diff --git a/__fixtures__/arbitraryValues/arbitraryValues.js b/__fixtures__/arbitraryValues/arbitraryValues.js index 00a68910..b883d10f 100644 --- a/__fixtures__/arbitraryValues/arbitraryValues.js +++ b/__fixtures__/arbitraryValues/arbitraryValues.js @@ -8,6 +8,8 @@ tw`bg-opacity-[0.11]` tw`bg-opacity-[var(--value)]` tw`border-[#f00]` tw`border-[2.5px]` +tw`border-t-[#f00]` +tw`border-t-[2.5px]` tw`w-[3.23rem]` tw`w-[calc(100%+1rem)]` tw`w-[calc(var(--10-10px,calc(-20px-(-30px--40px)))-50px)]` diff --git a/__fixtures__/directionalBorders/directionalBorders.js b/__fixtures__/directionalBorders/directionalBorders.js new file mode 100644 index 00000000..38c17cae --- /dev/null +++ b/__fixtures__/directionalBorders/directionalBorders.js @@ -0,0 +1,29 @@ +import tw from './macro' // twinImport + +tw`border-t` +tw`border-r` +tw`border-b` +tw`border-l` + +tw`border-t-transparent` +tw`border-t-current` +tw`border-t-gray-50` + +tw`border-r-transparent` +tw`border-r-current` +tw`border-r-gray-50` + +tw`border-b-transparent` +tw`border-b-current` +tw`border-b-gray-50` + +tw`border-l-transparent` +tw`border-l-current` +tw`border-l-gray-50` + +tw`border-l-gray-50/20` + +tw`border-t-4` +tw`border-r-4` +tw`border-b-4` +tw`border-l-4` diff --git a/__snapshots__/plugin.test.js.snap b/__snapshots__/plugin.test.js.snap index e7e5dec3..e6b47e97 100644 --- a/__snapshots__/plugin.test.js.snap +++ b/__snapshots__/plugin.test.js.snap @@ -2245,6 +2245,8 @@ tw\`bg-opacity-[0.11]\` tw\`bg-opacity-[var(--value)]\` tw\`border-[#f00]\` tw\`border-[2.5px]\` +tw\`border-t-[#f00]\` +tw\`border-t-[2.5px]\` tw\`w-[3.23rem]\` tw\`w-[calc(100%+1rem)]\` tw\`w-[calc(var(--10-10px,calc(-20px-(-30px--40px)))-50px)]\` @@ -2379,6 +2381,13 @@ tw\`md:text-[red]\` ;({ borderWidth: '2.5px', }) +;({ + '--tw-border-opacity': '1', + borderTopColor: 'rgba(255, 0, 0, var(--tw-border-opacity))', +}) +;({ + borderTopWidth: '2.5px', +}) ;({ width: '3.23rem', }) @@ -8452,6 +8461,112 @@ tw\`bg-blue-gray-green-pink\` }) +`; + +exports[`twin.macro directionalBorders.js: directionalBorders.js 1`] = ` + +import tw from './macro' // twinImport + +tw\`border-t\` +tw\`border-r\` +tw\`border-b\` +tw\`border-l\` + +tw\`border-t-transparent\` +tw\`border-t-current\` +tw\`border-t-gray-50\` + +tw\`border-r-transparent\` +tw\`border-r-current\` +tw\`border-r-gray-50\` + +tw\`border-b-transparent\` +tw\`border-b-current\` +tw\`border-b-gray-50\` + +tw\`border-l-transparent\` +tw\`border-l-current\` +tw\`border-l-gray-50\` + +tw\`border-l-gray-50/20\` + +tw\`border-t-4\` +tw\`border-r-4\` +tw\`border-b-4\` +tw\`border-l-4\` + + ↓ ↓ ↓ ↓ ↓ ↓ + +// twinImport +;({ + borderTopWidth: '1px', +}) +;({ + borderRightWidth: '1px', +}) +;({ + borderBottomWidth: '1px', +}) +;({ + borderLeftWidth: '1px', +}) +;({ + borderTopColor: 'rgba(0, 0, 0, 0)', +}) +;({ + borderTopColor: 'currentColor', +}) +;({ + '--tw-border-opacity': '1', + borderTopColor: 'rgba(249, 250, 251, var(--tw-border-opacity))', +}) +;({ + borderRightColor: 'rgba(0, 0, 0, 0)', +}) +;({ + borderRightColor: 'currentColor', +}) +;({ + '--tw-border-opacity': '1', + borderRightColor: 'rgba(249, 250, 251, var(--tw-border-opacity))', +}) +;({ + borderBottomColor: 'rgba(0, 0, 0, 0)', +}) +;({ + borderBottomColor: 'currentColor', +}) +;({ + '--tw-border-opacity': '1', + borderBottomColor: 'rgba(249, 250, 251, var(--tw-border-opacity))', +}) +;({ + borderLeftColor: 'rgba(0, 0, 0, 0)', +}) +;({ + borderLeftColor: 'currentColor', +}) +;({ + '--tw-border-opacity': '1', + borderLeftColor: 'rgba(249, 250, 251, var(--tw-border-opacity))', +}) +;({ + borderLeftColor: 'rgba(249, 250, 251, 0.2)', +}) +;({ + borderTopWidth: '4px', +}) +;({ + borderRightWidth: '4px', +}) +;({ + borderBottomWidth: '4px', +}) +;({ + borderLeftWidth: '4px', +}) + + `; exports[`twin.macro disableColorVariables.js: disableColorVariables.js 1`] = ` diff --git a/src/config/dynamicStyles.js b/src/config/dynamicStyles.js index 21c9d41b..207f2f79 100644 --- a/src/config/dynamicStyles.js +++ b/src/config/dynamicStyles.js @@ -341,49 +341,43 @@ export default { // https://tailwindcss.com/docs/border-width 'border-t': { - prop: 'borderTopWidth', value: ['color', 'length'], - config: 'borderWidth', + plugin: 'border', coerced: { color: { property: 'borderTopColor', variable: '--tw-border-opacity' }, length: { property: 'borderTopWidth' }, }, }, 'border-b': { - prop: 'borderBottomWidth', value: ['color', 'length'], - config: 'borderWidth', + plugin: 'border', coerced: { color: { property: 'borderBottomColor', variable: '--tw-border-opacity' }, length: { property: 'borderBottomWidth' }, }, }, 'border-l': { - prop: 'borderLeftWidth', value: ['color', 'length'], - config: 'borderWidth', + plugin: 'border', coerced: { color: { property: 'borderLeftColor', variable: '--tw-border-opacity' }, length: { property: 'borderLeftWidth' }, }, }, 'border-r': { - prop: 'borderRightWidth', value: ['color', 'length'], - config: 'borderWidth', + plugin: 'border', coerced: { color: { property: 'borderRightColor', variable: '--tw-border-opacity' }, length: { property: 'borderRightWidth' }, }, }, - 'border-opacity': { prop: '--tw-border-opacity', config: 'borderOpacity', configFallback: 'opacity', }, border: { - prop: 'borderWidth', value: ['color', 'length'], plugin: 'border', coerced: { diff --git a/src/handlers/corePlugins.js b/src/handlers/corePlugins.js index a4fdda23..4299499c 100644 --- a/src/handlers/corePlugins.js +++ b/src/handlers/corePlugins.js @@ -58,7 +58,7 @@ const getMatchConfigValue = ({ match, theme, getConfigValue }) => ( regexMatch ) => { const matcher = match(regexMatch) - if (!matcher) return + if (matcher === undefined) return return getConfigValue(theme(config), matcher) } @@ -73,7 +73,11 @@ export default ({ ...rest }) => { const errors = getErrors({ state, pieces, dynamicKey }) - const match = regex => get(pieces.className.match(regex), [0]) || null + const match = regex => { + const result = get(pieces.className.match(regex), [0]) + if (result === undefined) return + return result + } const matchConfigValue = getMatchConfigValue({ match, theme, getConfigValue }) const toColor = getColor({ diff --git a/src/plugins/border.js b/src/plugins/border.js index 130e1ae4..1a3159f3 100644 --- a/src/plugins/border.js +++ b/src/plugins/border.js @@ -1,43 +1,62 @@ -const handleWidth = ({ configValue, important }) => { - const value = configValue('borderWidth') - if (!value) return +const borderWidthConfig = [ + { + property: 'borderTopWidth', + value: regex => regex(/(?<=(border-t(-|$)))([^]*)/), + }, + { + property: 'borderRightWidth', + value: regex => regex(/(?<=(border-r(-|$)))([^]*)/), + }, + { + property: 'borderBottomWidth', + value: regex => regex(/(?<=(border-b(-|$)))([^]*)/), + }, + { + property: 'borderLeftWidth', + value: regex => regex(/(?<=(border-l(-|$)))([^]*)/), + }, + { + property: 'borderWidth', + value: regex => regex(/(?<=(border(-|$)))([^]*)/), + }, +] - return { - borderWidth: `${value}${important}`, - } -} +const borderColorConfig = [ + { matchStart: 'border-t', property: 'borderTopColor' }, + { matchStart: 'border-r', property: 'borderRightColor' }, + { matchStart: 'border-b', property: 'borderBottomColor' }, + { matchStart: 'border-l', property: 'borderLeftColor' }, + { matchStart: 'border', property: 'borderColor' }, +] -const handleColor = ({ toColor }) => { - const common = { - matchStart: 'border', - property: 'borderColor', - configSearch: 'borderColor', - } - return toColor([ - { ...common, opacityVariable: '--tw-border-opacity' }, - common, - ]) -} +const getCommonColorConfig = ({ matchStart, property }) => ({ + matchStart, + property, + configSearch: 'borderColor', +}) export default properties => { const { - match, - theme, - getConfigValue, + matchConfigValue, toColor, pieces: { important }, errors: { errorSuggestions }, } = properties - const width = handleWidth({ - configValue: config => - getConfigValue(theme(config), match(/(?<=(border-))([^]*)/)), - important, - }) - if (width) return width + const getBorderWidthByRegex = regex => matchConfigValue('borderWidth', regex) + for (const task of borderWidthConfig) { + const value = task.value(getBorderWidthByRegex) + if (value) return { [task.property]: `${value}${important}` } + } - const color = handleColor({ toColor }) - if (color) return color + for (const task of borderColorConfig) { + const common = getCommonColorConfig(task) + const value = toColor([ + { ...common, opacityVariable: '--tw-border-opacity' }, + common, + ]) + if (value) return value + } errorSuggestions({ config: ['borderColor', 'borderWidth'] }) }