Skip to content

Commit ac72475

Browse files
nicolas-cusanclaude
andcommitted
add support for Tailwind v4.2 block-start/end logical properties
Adds pbs, pbe, mbs, mbe, scroll-mbs, scroll-mbe, scroll-pbs, scroll-pbe utilities matching the new padding/margin/scroll block-start and block-end classes introduced in Tailwind CSS v4.2. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 34aba2e commit ac72475

4 files changed

Lines changed: 152 additions & 0 deletions

File tree

packages/tailwind-clamp-merge/lib/__tests__/index.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,30 @@ describe('hyphenated prop distinction', () => {
175175
).toBe('clamp-[scroll-p,1rem,2rem] clamp-[scroll-ps,0.5rem,1rem]');
176176
});
177177

178+
it('pbs and pbe do not interfere', () => {
179+
expect(
180+
twMerge('clamp-[pbs,1rem,2rem] clamp-[pbe,0.5rem,1rem]')
181+
).toBe('clamp-[pbs,1rem,2rem] clamp-[pbe,0.5rem,1rem]');
182+
});
183+
184+
it('mbs and mbe do not interfere', () => {
185+
expect(
186+
twMerge('clamp-[mbs,1rem,2rem] clamp-[mbe,0.5rem,1rem]')
187+
).toBe('clamp-[mbs,1rem,2rem] clamp-[mbe,0.5rem,1rem]');
188+
});
189+
190+
it('scroll-mbs and scroll-mbe do not interfere', () => {
191+
expect(
192+
twMerge('clamp-[scroll-mbs,1rem,2rem] clamp-[scroll-mbe,0.5rem,1rem]')
193+
).toBe('clamp-[scroll-mbs,1rem,2rem] clamp-[scroll-mbe,0.5rem,1rem]');
194+
});
195+
196+
it('scroll-pbs and scroll-pbe do not interfere', () => {
197+
expect(
198+
twMerge('clamp-[scroll-pbs,1rem,2rem] clamp-[scroll-pbe,0.5rem,1rem]')
199+
).toBe('clamp-[scroll-pbs,1rem,2rem] clamp-[scroll-pbe,0.5rem,1rem]');
200+
});
201+
178202
it('gap-x and gap-y do not interfere', () => {
179203
expect(
180204
twMerge('clamp-[gap-x,1rem,2rem] clamp-[gap-y,0.5rem,1rem]')

packages/tailwind-clamp-merge/lib/mapping.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const PROP_TO_GROUP = {
1818
pe: 'pe',
1919
px: 'px',
2020
py: 'py',
21+
pbs: 'pbs',
22+
pbe: 'pbe',
2123

2224
// Margin
2325
m: 'm',
@@ -29,6 +31,8 @@ export const PROP_TO_GROUP = {
2931
me: 'me',
3032
mx: 'mx',
3133
my: 'my',
34+
mbs: 'mbs',
35+
mbe: 'mbe',
3236

3337
// Inset
3438
inset: 'inset',
@@ -67,6 +71,8 @@ export const PROP_TO_GROUP = {
6771
'scroll-mb': 'scroll-mb',
6872
'scroll-ml': 'scroll-ml',
6973
'scroll-mr': 'scroll-mr',
74+
'scroll-mbs': 'scroll-mbs',
75+
'scroll-mbe': 'scroll-mbe',
7076

7177
// Scroll Padding
7278
'scroll-p': 'scroll-p',
@@ -78,6 +84,8 @@ export const PROP_TO_GROUP = {
7884
'scroll-pb': 'scroll-pb',
7985
'scroll-pl': 'scroll-pl',
8086
'scroll-pr': 'scroll-pr',
87+
'scroll-pbs': 'scroll-pbs',
88+
'scroll-pbe': 'scroll-pbe',
8189

8290
// Translate
8391
translate: 'translate',

packages/tailwind-clamp/lib/__tests__/index.test.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,70 @@ describe('resolveProperty', () => {
605605
props: ['inset'],
606606
});
607607
});
608+
609+
it('resolves "pbs" to paddingBlockStart', () => {
610+
expect(resolveProperty('pbs')).toEqual({
611+
type: 'spacing',
612+
key: 'padding',
613+
props: ['paddingBlockStart'],
614+
});
615+
});
616+
617+
it('resolves "pbe" to paddingBlockEnd', () => {
618+
expect(resolveProperty('pbe')).toEqual({
619+
type: 'spacing',
620+
key: 'padding',
621+
props: ['paddingBlockEnd'],
622+
});
623+
});
624+
625+
it('resolves "mbs" to marginBlockStart', () => {
626+
expect(resolveProperty('mbs')).toEqual({
627+
type: 'spacing',
628+
key: 'margin',
629+
props: ['marginBlockStart'],
630+
});
631+
});
632+
633+
it('resolves "mbe" to marginBlockEnd', () => {
634+
expect(resolveProperty('mbe')).toEqual({
635+
type: 'spacing',
636+
key: 'margin',
637+
props: ['marginBlockEnd'],
638+
});
639+
});
640+
641+
it('resolves "scroll-mbs" to scrollMarginBlockStart', () => {
642+
expect(resolveProperty('scroll-mbs')).toEqual({
643+
type: 'spacing',
644+
key: 'scrollMargin',
645+
props: ['scrollMarginBlockStart'],
646+
});
647+
});
648+
649+
it('resolves "scroll-mbe" to scrollMarginBlockEnd', () => {
650+
expect(resolveProperty('scroll-mbe')).toEqual({
651+
type: 'spacing',
652+
key: 'scrollMargin',
653+
props: ['scrollMarginBlockEnd'],
654+
});
655+
});
656+
657+
it('resolves "scroll-pbs" to scrollPaddingBlockStart', () => {
658+
expect(resolveProperty('scroll-pbs')).toEqual({
659+
type: 'spacing',
660+
key: 'scrollPadding',
661+
props: ['scrollPaddingBlockStart'],
662+
});
663+
});
664+
665+
it('resolves "scroll-pbe" to scrollPaddingBlockEnd', () => {
666+
expect(resolveProperty('scroll-pbe')).toEqual({
667+
type: 'spacing',
668+
key: 'scrollPadding',
669+
props: ['scrollPaddingBlockEnd'],
670+
});
671+
});
608672
});
609673

610674
describe('multi-prop outputs', () => {

packages/tailwind-clamp/lib/resolve-property.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ export const resolveProperty = (name) => {
7373
props: ['paddingBlock'],
7474
};
7575

76+
case 'pbs':
77+
return {
78+
type: 'spacing',
79+
key: 'padding',
80+
props: ['paddingBlockStart'],
81+
};
82+
83+
case 'pbe':
84+
return {
85+
type: 'spacing',
86+
key: 'padding',
87+
props: ['paddingBlockEnd'],
88+
};
89+
7690
case 'm':
7791
return {
7892
type: 'spacing',
@@ -136,6 +150,20 @@ export const resolveProperty = (name) => {
136150
props: ['marginBlock'],
137151
};
138152

153+
case 'mbs':
154+
return {
155+
type: 'spacing',
156+
key: 'margin',
157+
props: ['marginBlockStart'],
158+
};
159+
160+
case 'mbe':
161+
return {
162+
type: 'spacing',
163+
key: 'margin',
164+
props: ['marginBlockEnd'],
165+
};
166+
139167
case 'inset':
140168
return {
141169
type: 'spacing',
@@ -331,6 +359,20 @@ export const resolveProperty = (name) => {
331359
props: ['scrollMarginRight'],
332360
};
333361

362+
case 'scroll-mbs':
363+
return {
364+
type: 'spacing',
365+
key: 'scrollMargin',
366+
props: ['scrollMarginBlockStart'],
367+
};
368+
369+
case 'scroll-mbe':
370+
return {
371+
type: 'spacing',
372+
key: 'scrollMargin',
373+
props: ['scrollMarginBlockEnd'],
374+
};
375+
334376
case 'scroll-p':
335377
return {
336378
type: 'spacing',
@@ -394,6 +436,20 @@ export const resolveProperty = (name) => {
394436
props: ['scrollPaddingRight'],
395437
};
396438

439+
case 'scroll-pbs':
440+
return {
441+
type: 'spacing',
442+
key: 'scrollPadding',
443+
props: ['scrollPaddingBlockStart'],
444+
};
445+
446+
case 'scroll-pbe':
447+
return {
448+
type: 'spacing',
449+
key: 'scrollPadding',
450+
props: ['scrollPaddingBlockEnd'],
451+
};
452+
397453
case 'translate':
398454
return {
399455
type: 'spacing',

0 commit comments

Comments
 (0)