@@ -260,87 +260,127 @@ export function parseLayout(cls: string, customSpacing?: Record<string, number>)
260260 }
261261 }
262262
263- // Top positioning: top-0, top-4, top-[10px], top-[50%], etc.
264- if ( cls . startsWith ( "top-" ) ) {
265- const topKey = cls . substring ( 4 ) ;
263+ // Top positioning: top-0, top-4, top-[10px], top-[50%], -top-4, etc.
264+ const topMatch = cls . match ( / ^ ( - ? ) t o p - ( .+ ) $ / ) ;
265+ if ( topMatch ) {
266+ const [ , negPrefix , topKey ] = topMatch ;
267+ const isNegative = negPrefix === "-" ;
266268
267269 // Auto value - return empty object (no-op, removes the property)
268270 if ( topKey === "auto" ) {
269271 return { } ;
270272 }
271273
272- // Arbitrary values: top-[123px], top-[50%], top-[- 10px]
274+ // Arbitrary values: top-[123px], top-[50%], - top-[10px]
273275 const arbitraryTop = parseArbitraryInset ( topKey ) ;
274276 if ( arbitraryTop !== null ) {
277+ if ( typeof arbitraryTop === "number" ) {
278+ return { top : isNegative ? - arbitraryTop : arbitraryTop } ;
279+ }
280+ // Percentage values with negative prefix
281+ if ( isNegative && arbitraryTop . endsWith ( "%" ) ) {
282+ const numValue = parseFloat ( arbitraryTop ) ;
283+ return { top : `${ - numValue } %` } ;
284+ }
275285 return { top : arbitraryTop } ;
276286 }
277287
278288 const topValue = insetMap [ topKey ] ;
279289 if ( topValue !== undefined ) {
280- return { top : topValue } ;
290+ return { top : isNegative ? - topValue : topValue } ;
281291 }
282292 }
283293
284- // Right positioning: right-0, right-4, right-[10px], right-[50%], etc.
285- if ( cls . startsWith ( "right-" ) ) {
286- const rightKey = cls . substring ( 6 ) ;
294+ // Right positioning: right-0, right-4, right-[10px], right-[50%], -right-4, etc.
295+ const rightMatch = cls . match ( / ^ ( - ? ) r i g h t - ( .+ ) $ / ) ;
296+ if ( rightMatch ) {
297+ const [ , negPrefix , rightKey ] = rightMatch ;
298+ const isNegative = negPrefix === "-" ;
287299
288300 // Auto value - return empty object (no-op, removes the property)
289301 if ( rightKey === "auto" ) {
290302 return { } ;
291303 }
292304
293- // Arbitrary values: right-[123px], right-[50%], right-[- 10px]
305+ // Arbitrary values: right-[123px], right-[50%], - right-[10px]
294306 const arbitraryRight = parseArbitraryInset ( rightKey ) ;
295307 if ( arbitraryRight !== null ) {
308+ if ( typeof arbitraryRight === "number" ) {
309+ return { right : isNegative ? - arbitraryRight : arbitraryRight } ;
310+ }
311+ // Percentage values with negative prefix
312+ if ( isNegative && arbitraryRight . endsWith ( "%" ) ) {
313+ const numValue = parseFloat ( arbitraryRight ) ;
314+ return { right : `${ - numValue } %` } ;
315+ }
296316 return { right : arbitraryRight } ;
297317 }
298318
299319 const rightValue = insetMap [ rightKey ] ;
300320 if ( rightValue !== undefined ) {
301- return { right : rightValue } ;
321+ return { right : isNegative ? - rightValue : rightValue } ;
302322 }
303323 }
304324
305- // Bottom positioning: bottom-0, bottom-4, bottom-[10px], bottom-[50%], etc.
306- if ( cls . startsWith ( "bottom-" ) ) {
307- const bottomKey = cls . substring ( 7 ) ;
325+ // Bottom positioning: bottom-0, bottom-4, bottom-[10px], bottom-[50%], -bottom-4, etc.
326+ const bottomMatch = cls . match ( / ^ ( - ? ) b o t t o m - ( .+ ) $ / ) ;
327+ if ( bottomMatch ) {
328+ const [ , negPrefix , bottomKey ] = bottomMatch ;
329+ const isNegative = negPrefix === "-" ;
308330
309331 // Auto value - return empty object (no-op, removes the property)
310332 if ( bottomKey === "auto" ) {
311333 return { } ;
312334 }
313335
314- // Arbitrary values: bottom-[123px], bottom-[50%], bottom-[- 10px]
336+ // Arbitrary values: bottom-[123px], bottom-[50%], - bottom-[10px]
315337 const arbitraryBottom = parseArbitraryInset ( bottomKey ) ;
316338 if ( arbitraryBottom !== null ) {
339+ if ( typeof arbitraryBottom === "number" ) {
340+ return { bottom : isNegative ? - arbitraryBottom : arbitraryBottom } ;
341+ }
342+ // Percentage values with negative prefix
343+ if ( isNegative && arbitraryBottom . endsWith ( "%" ) ) {
344+ const numValue = parseFloat ( arbitraryBottom ) ;
345+ return { bottom : `${ - numValue } %` } ;
346+ }
317347 return { bottom : arbitraryBottom } ;
318348 }
319349
320350 const bottomValue = insetMap [ bottomKey ] ;
321351 if ( bottomValue !== undefined ) {
322- return { bottom : bottomValue } ;
352+ return { bottom : isNegative ? - bottomValue : bottomValue } ;
323353 }
324354 }
325355
326- // Left positioning: left-0, left-4, left-[10px], left-[50%], etc.
327- if ( cls . startsWith ( "left-" ) ) {
328- const leftKey = cls . substring ( 5 ) ;
356+ // Left positioning: left-0, left-4, left-[10px], left-[50%], -left-4, etc.
357+ const leftMatch = cls . match ( / ^ ( - ? ) l e f t - ( .+ ) $ / ) ;
358+ if ( leftMatch ) {
359+ const [ , negPrefix , leftKey ] = leftMatch ;
360+ const isNegative = negPrefix === "-" ;
329361
330362 // Auto value - return empty object (no-op, removes the property)
331363 if ( leftKey === "auto" ) {
332364 return { } ;
333365 }
334366
335- // Arbitrary values: left-[123px], left-[50%], left-[- 10px]
367+ // Arbitrary values: left-[123px], left-[50%], - left-[10px]
336368 const arbitraryLeft = parseArbitraryInset ( leftKey ) ;
337369 if ( arbitraryLeft !== null ) {
370+ if ( typeof arbitraryLeft === "number" ) {
371+ return { left : isNegative ? - arbitraryLeft : arbitraryLeft } ;
372+ }
373+ // Percentage values with negative prefix
374+ if ( isNegative && arbitraryLeft . endsWith ( "%" ) ) {
375+ const numValue = parseFloat ( arbitraryLeft ) ;
376+ return { left : `${ - numValue } %` } ;
377+ }
338378 return { left : arbitraryLeft } ;
339379 }
340380
341381 const leftValue = insetMap [ leftKey ] ;
342382 if ( leftValue !== undefined ) {
343- return { left : leftValue } ;
383+ return { left : isNegative ? - leftValue : leftValue } ;
344384 }
345385 }
346386
0 commit comments