Skip to content

Commit

Permalink
fix(declaration-converters-mapping): correct arbitrary values for bor…
Browse files Browse the repository at this point in the history
…der shorthand

Now arbitrary values for border shorthand works correctly. Previously, everything was using
border-[] prefix, but that is only correct for border-color arbitrary values.

fix Jackardios#25
  • Loading branch information
guivr committed Sep 16, 2024
1 parent 43b8e1a commit bd1ed12
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 23 deletions.
132 changes: 111 additions & 21 deletions src/mappings/declaration-converters-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,26 @@ function convertBorderDeclarationValue(
if (!config.tailwindConfig.corePlugins.borderWidth) {
return [];
}
const widthClasses = convertSizeDeclarationValue(
width,
config.mapping.borderWidth,
classPrefix,
config.remInPx,
false,
'length'
);

// Handle arbitrary values for border width
classes = classes.concat(
convertSizeDeclarationValue(
width,
config.mapping.borderWidth,
classPrefix,
config.remInPx,
false,
'length'
)
widthClasses.map(cls => {
if (cls.includes('[') && cls.includes(']')) {
// Only add 'w-' for the general 'border' case
return classPrefix === 'border'
? cls.replace(`${classPrefix}-[`, `${classPrefix}-w-[`)
: cls;
}
return cls;
})
);
}

Expand All @@ -174,12 +185,16 @@ function convertBorderDeclarationValue(
if (!config.tailwindConfig.corePlugins.borderColor) {
return [];
}
const colorClasses = convertColorDeclarationValue(
color,
config.mapping.borderColor,
classPrefix,
'color'
);
// Remove extra hyphen for color classes
classes = classes.concat(
convertColorDeclarationValue(
color,
config.mapping.borderColor,
classPrefix,
'color'
colorClasses.map(cls =>
cls.replace(`${classPrefix}--`, `${classPrefix}-`)
)
);
}
Expand Down Expand Up @@ -244,6 +259,88 @@ interface DeclarationConvertersMapping {
[property: string]: DeclarationConverter;
}

function convertBorderWidthDeclaration(
value: string,
config: ResolvedTailwindConverterConfig
) {
const values = value.trim().split(/\s+/);
const borderWidthMap = config.mapping.borderWidth;
const remInPx = config.remInPx;

let classes: string[] = [];

if (values.length === 1) {
// Applies to all sides
classes = classes.concat(
convertSizeDeclarationValue(values[0], borderWidthMap, 'border', remInPx)
);
} else if (values.length === 2) {
// [vertical, horizontal]
const [vertical, horizontal] = values;

classes = classes.concat(
convertSizeDeclarationValue(vertical, borderWidthMap, 'border-y', remInPx)
);
if (horizontal !== '0' && horizontal !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(
horizontal,
borderWidthMap,
'border-x',
remInPx
)
);
}
} else if (values.length === 3) {
// [top, horizontal, bottom]
const [top, horizontal, bottom] = values;

classes = classes.concat(
convertSizeDeclarationValue(top, borderWidthMap, 'border-t', remInPx),
convertSizeDeclarationValue(bottom, borderWidthMap, 'border-b', remInPx)
);
if (horizontal !== '0' && horizontal !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(
horizontal,
borderWidthMap,
'border-x',
remInPx
)
);
}
} else if (values.length === 4) {
// [top, right, bottom, left]
const [top, right, bottom, left] = values;

if (top !== '0' && top !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(top, borderWidthMap, 'border-t', remInPx)
);
}
if (right !== '0' && right !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(right, borderWidthMap, 'border-r', remInPx)
);
}
if (bottom !== '0' && bottom !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(bottom, borderWidthMap, 'border-b', remInPx)
);
}
if (left !== '0' && left !== '0px') {
classes = classes.concat(
convertSizeDeclarationValue(left, borderWidthMap, 'border-l', remInPx)
);
}
} else {
// Invalid number of values
return [];
}

return classes;
}

export const DECLARATION_CONVERTERS_MAPPING: DeclarationConvertersMapping = {
'accent-color': (declaration, config) =>
config.tailwindConfig.corePlugins.accentColor
Expand Down Expand Up @@ -662,14 +759,7 @@ export const DECLARATION_CONVERTERS_MAPPING: DeclarationConvertersMapping = {

'border-width': (declaration, config) =>
config.tailwindConfig.corePlugins.borderWidth
? convertSizeDeclarationValue(
declaration.value,
config.mapping.borderWidth,
'border',
config.remInPx,
false,
'length'
)
? convertBorderWidthDeclaration(declaration.value, config)
: [],

bottom: (declaration, config) =>
Expand Down
88 changes: 87 additions & 1 deletion test/TailwindConverter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ describe('TailwindConverter', () => {
]);
});

it('should convert border with color function correctly even if width is missing', async () => {
it('should convert border with color correctly even if width is missing', async () => {
const converter = createTailwindConverter();
const css = `
td {
Expand Down Expand Up @@ -615,4 +615,90 @@ describe('TailwindConverter', () => {
},
]);
});

it('should convert border width on shorthand correctly', async () => {
const converter = createTailwindConverter();
const css = `
td {
border: 1px solid rgba(148, 163, 184, 0.1);
}
.a {
border-color: rgba(148, 163, 184, 0.1);
border-width: 1px 2px;
}
.b {
border-color: rgba(148, 163, 184, 0.1);
border-width: 2px;
}
.c {
border-color: rgba(148, 163, 184, 0.1);
border-width: 1px 0px 3px;
}
.d {
border-color: rgba(148, 163, 184, 0.1);
border-width: 1px 0px 2px;
}
.f {
border-color: rgba(148, 163, 184, 0.1);
border-width: 1px 3px 2px 4.5em;
}
.g {
border: 4.5em solid;
}`;
const converted = await converter.convertCSS(css);

expect(converted.convertedRoot.toString()).toMatchSnapshot();
expect(converted.nodes).toEqual([
{
rule: expect.objectContaining({ selector: 'td' }),
tailwindClasses: [
'border',
'border-solid',
'border-[rgba(148,163,184,0.1)]',
],
},
{
rule: expect.objectContaining({ selector: '.a' }),
tailwindClasses: [
'border-x-2',
'border-[rgba(148,163,184,0.1)]',
'border-y',
],
},
{
rule: expect.objectContaining({ selector: '.b' }),
tailwindClasses: ['border-[rgba(148,163,184,0.1)]', 'border-2'],
},
{
rule: expect.objectContaining({ selector: '.c' }),
tailwindClasses: [
'border-b-[3px]',
'border-[rgba(148,163,184,0.1)]',
'border-t',
],
},
{
rule: expect.objectContaining({ selector: '.d' }),
tailwindClasses: [
'border-b-2',
'border-[rgba(148,163,184,0.1)]',
'border-t',
],
},
{
rule: expect.objectContaining({ selector: '.f' }),
tailwindClasses: [
'border-l-[4.5em]',
'border-r-[3px]',
'border-b-2',
'border-[rgba(148,163,184,0.1)]',
'border-t',
],
},
{
rule: expect.objectContaining({ selector: '.g' }),
tailwindClasses: ['border-w-[4.5em]', 'border-solid'],
},
]);
});
});
26 changes: 25 additions & 1 deletion test/__snapshots__/TailwindConverter.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,31 @@ exports[`TailwindConverter should consider \`prefix\`, \`separator\` and \`coreP
"
`;

exports[`TailwindConverter should convert border with color function correctly even if width is missing 1`] = `
exports[`TailwindConverter should convert border width on shorthand correctly 1`] = `
"td {
@apply border border-solid border-[rgba(148,163,184,0.1)];
}
.a {
@apply border-x-2 border-[rgba(148,163,184,0.1)] border-y;
}
.b {
@apply border-[rgba(148,163,184,0.1)] border-2;
}
.c {
@apply border-b-[3px] border-[rgba(148,163,184,0.1)] border-t;
}
.d {
@apply border-b-2 border-[rgba(148,163,184,0.1)] border-t;
}
.f {
@apply border-l-[4.5em] border-r-[3px] border-b-2 border-[rgba(148,163,184,0.1)] border-t;
}
.g {
@apply border-w-[4.5em] border-solid;
}"
`;

exports[`TailwindConverter should convert border with color correctly even if width is missing 1`] = `
"td {
@apply border-solid border-[rgba(148,163,184,0.1)];
}
Expand Down

0 comments on commit bd1ed12

Please sign in to comment.