@@ -9,9 +9,11 @@ import {
99 toStyleVal ,
1010} from '../helpers' ;
1111
12+ const originPositions = [ `left` , `center` , `right` , `top` , `bottom` ] ;
13+
1214type Axis = `x` | `y` | `z` | ``;
1315type Property = `scale` | `rotate` | `skew` | `translate`;
14- type Position = `left` | `center` | `right` | `top` | `bottom` ;
16+ type OriginPosition = ( typeof originPositions ) [ number ] ;
1517
1618export 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
210212function createStyle (
@@ -237,21 +239,21 @@ function isArbitraryValue(value: string): boolean {
237239
238240function 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}
0 commit comments