Skip to content

Commit 3c2776c

Browse files
committed
changed how origin is parsed
1 parent 0e2fad4 commit 3c2776c

File tree

3 files changed

+66
-60
lines changed

3 files changed

+66
-60
lines changed

src/__tests__/transform.spec.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ describe(`transform utilities`, () => {
281281

282282
describe(`origin`, () => {
283283
const cases: Array<
284-
[string, Record<'transformOrigin', string | (string | number)[]>]
284+
[string, Record<'transformOrigin', string> | Record<string, never>]
285285
> = [
286286
[`origin-center`, { transformOrigin: `center` }],
287287
[`origin-top`, { transformOrigin: `top` }],
@@ -294,12 +294,23 @@ describe(`transform utilities`, () => {
294294
[`origin-top-left`, { transformOrigin: `top left` }],
295295

296296
// arbitrary
297-
[`origin-[top]`, { transformOrigin: [`top`] }],
298-
[`origin-[10%]`, { transformOrigin: [`10%`] }],
299-
[`origin-[10px]`, { transformOrigin: [10] }],
300-
[`origin-[left_top]`, { transformOrigin: [`left`, `top`] }],
301-
[`origin-[-10%_20%_10px]`, { transformOrigin: [`-10%`, `20%`, 10] }],
302-
[`origin-[-10px_-10px_-10px]`, { transformOrigin: [-10, -10, -10] }],
297+
[`origin-[top]`, { transformOrigin: `top` }],
298+
[`origin-[10%]`, { transformOrigin: `10%` }],
299+
[`origin-[10px]`, { transformOrigin: `10px` }],
300+
[`origin-[left_top]`, { transformOrigin: `left top` }],
301+
[`origin-[bottom_right]`, { transformOrigin: `bottom right` }],
302+
[`origin-[center_center]`, { transformOrigin: `center center` }],
303+
[`origin-[center_10%]`, { transformOrigin: `center 10%` }],
304+
[`origin-[10px_center]`, { transformOrigin: `10px center` }],
305+
[`origin-[10px_10%]`, { transformOrigin: `10px 10%` }],
306+
[`origin-[-10%_20%_10px]`, { transformOrigin: `-10% 20% 10px` }],
307+
[`origin-[-10px_-10px_-10px]`, { transformOrigin: `-10px -10px -10px` }],
308+
[`origin-[left_top_10px]`, { transformOrigin: `left top 10px` }],
309+
310+
// invalid
311+
[`origin-[left_left]`, {}],
312+
[`origin-[top_top]`, {}],
313+
[`origin-[top_left_10%]`, {}],
303314
];
304315

305316
test.each(cases)(`tw\`%s\` -> %s`, (utility, expected) => {
@@ -311,13 +322,13 @@ describe(`transform utilities`, () => {
311322
theme: {
312323
extend: {
313324
transformOrigin: {
314-
'top-left-1/3-3/4-10': `33% 75% 10px`,
325+
custom: `33% 75% 10px`,
315326
},
316327
},
317328
},
318329
});
319330

320-
expect(tw.style(`origin-top-left-1/3-3/4-10`)).toMatchObject({
331+
expect(tw.style(`origin-custom`)).toMatchObject({
321332
transformOrigin: `33% 75% 10px`,
322333
});
323334
});

src/resolve/transform.ts

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import {
99
toStyleVal,
1010
} from '../helpers';
1111

12+
const originPositions = [`left`, `center`, `right`, `top`, `bottom`];
13+
1214
type Axis = `x` | `y` | `z` | ``;
1315
type Property = `scale` | `rotate` | `skew` | `translate`;
14-
type Position = `left` | `center` | `right` | `top` | `bottom`;
16+
type OriginPosition = (typeof originPositions)[number];
1517

1618
export function scale(
1719
value: string,
@@ -149,62 +151,62 @@ export function origin(
149151
return complete({ transformOrigin: configValue });
150152
}
151153

152-
if (isArbitraryValue(value)) {
153-
const values = value.slice(1, -1).split(`_`);
154+
if (!isArbitraryValue(value)) {
155+
return null;
156+
}
154157

155-
if (values.length === 0 || values.length > 3) {
156-
return null;
157-
}
158+
const values = value.slice(1, -1).split(`_`);
158159

159-
// with a single value, the value must be one of the positions, a percentage or a pixel value
160-
if (values.length === 1) {
161-
const parsedValue = parseOriginValue(
162-
values[0],
163-
[`left`, `center`, `right`, `top`, `bottom`],
164-
[Unit.percent, Unit.px],
165-
context,
166-
);
167-
return parsedValue === null ? null : complete({ transformOrigin: [parsedValue] });
168-
}
160+
if (values.length === 0 || values.length > 3) {
161+
return null;
162+
}
169163

170-
// with two or three values, the first value must be 'left' / 'center' / 'right', a percentage or a pixel value
171-
const xOffset = parseOriginValue(
172-
values[0],
173-
[`left`, `center`, `right`],
174-
[Unit.percent, Unit.px],
175-
context,
176-
);
164+
// the first value must be one of the positions, a percentage or a pixel value
165+
const firstOriginValue = parseOriginValue(
166+
values[0],
167+
originPositions,
168+
[Unit.px, Unit.percent],
169+
context,
170+
);
177171

178-
if (xOffset === null) {
179-
return null;
180-
}
172+
if (firstOriginValue === null) {
173+
return null;
174+
}
181175

182-
// with two or three values, the second value must be 'top' / 'center' / 'bottom', a percentage or a pixel value
183-
const yOffset = parseOriginValue(
176+
const origin = [firstOriginValue];
177+
178+
if (values.length >= 2) {
179+
// the second value must a position different from the first or `center`, a percentage or a pixel value
180+
const secondOriginValue = parseOriginValue(
184181
values[1],
185-
[`top`, `center`, `bottom`],
186-
[Unit.percent, Unit.px],
182+
originPositions.filter(
183+
(position) => position === `center` || position !== firstOriginValue,
184+
),
185+
[Unit.px, Unit.percent],
187186
context,
188187
);
189188

190-
if (yOffset === null) {
189+
if (secondOriginValue === null) {
191190
return null;
192191
}
193192

194-
// with three values, the third value must be a pixel value
195-
const zOffset = parseOriginValue(values[2], [], [Unit.px], context);
193+
origin.push(secondOriginValue);
194+
}
195+
196+
if (values.length === 3) {
197+
// the third value must be a pixel value
198+
const thirdOriginValue = parseOriginValue(values[2], [], [Unit.px], context);
196199

197-
if (zOffset === null && values.length === 3) {
200+
if (thirdOriginValue === null) {
198201
return null;
199202
}
200203

201-
return complete({
202-
transformOrigin:
203-
zOffset === null ? [xOffset, yOffset] : [xOffset, yOffset, zOffset],
204-
});
204+
origin.push(thirdOriginValue);
205205
}
206206

207-
return null;
207+
return complete({
208+
transformOrigin: origin.join(` `),
209+
});
208210
}
209211

210212
function createStyle(
@@ -237,21 +239,21 @@ function isArbitraryValue(value: string): boolean {
237239

238240
function parseOriginValue(
239241
value: string | undefined,
240-
allowedPositions: Position[],
242+
allowedPositions: OriginPosition[],
241243
allowedUnits: Unit[],
242244
context: ParseContext = {},
243-
): string | number | null {
245+
): string | null {
244246
if (!value) {
245247
return null;
246248
}
247249

248-
if (allowedPositions.includes(value as any)) {
250+
if (allowedPositions.includes(value)) {
249251
return value;
250252
}
251253

252254
const parsedValue = parseNumericValue(value, context);
253255

254256
return parsedValue === null || !allowedUnits.includes(parsedValue[1])
255257
? null
256-
: toStyleVal(parsedValue[0], parsedValue[1], context);
258+
: `${parsedValue[0] * (context.isNegative ? -1 : 1)}${parsedValue[1]}`;
257259
}

src/types.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,7 @@ export type Direction =
108108
| 'BottomRight';
109109

110110
export type Style = {
111-
[key: string]:
112-
| string[]
113-
| (string | number)[]
114-
| string
115-
| number
116-
| boolean
117-
| Style
118-
| Style[];
111+
[key: string]: string[] | string | number | boolean | Style | Style[];
119112
};
120113

121114
export enum ConfigType {

0 commit comments

Comments
 (0)