diff --git a/src/index.ts b/src/index.ts index a1e6509..1c8b9e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,9 +11,11 @@ const DEFAULT_BORDER_WIDTH = "1px"; const DEFAULT_OFFSET = "0px"; const DEFAULT_COLOR = "currentColor"; const DEFAULT_RADIUS = "0px"; -const svgRadius = "max(0px, calc(var(--tw-dashed-border-radius) - (var(--tw-dashed-border-width) / 2)))"; +const DEFAULT_ALIGN = "calc(var(--tw-dashed-border-width) / 2)"; +const dashedBorderAlign = "var(--tw-dashed-border-align)"; +const svgRadius = `max(0px, calc(var(--tw-dashed-border-radius) - (${dashedBorderAlign})))`; const dashedBorderTransitionProperties = - "stroke-dasharray, stroke-dashoffset, stroke-width, stroke, rx"; + "stroke-dasharray, stroke-dashoffset, stroke-width, stroke, rx, x, y, width, height"; const flattenThemeMap = ( input: ThemeValueMap, @@ -38,6 +40,11 @@ const flattenThemeMap = ( const roundedSelector = (name: string): string => name === "DEFAULT" ? ".rounded" : `.rounded-${name}`; +const resolveAlignValue = (value: string): string => + /^-?(?:\d+|\d*\.\d+)$/.test(value) + ? `calc((0.5 - ${value}) * var(--tw-dashed-border-width))` + : `calc((var(--tw-dashed-border-width) / 2) - (${value}))`; + const dashedBorderPlugin: ReturnType = plugin( ({ addBase, addUtilities, matchUtilities, theme }) => { addBase({ @@ -61,6 +68,11 @@ const dashedBorderPlugin: ReturnType = plugin( inherits: "true", "initial-value": DEFAULT_BORDER_WIDTH, }, + "@property --tw-dashed-border-align": { + syntax: "", + inherits: "true", + "initial-value": DEFAULT_ALIGN, + }, "@property --tw-dashed-border-radius": { syntax: "", inherits: "true", @@ -75,6 +87,7 @@ const dashedBorderPlugin: ReturnType = plugin( "--tw-dashed-border-offset": DEFAULT_OFFSET, "--tw-dashed-border-width": DEFAULT_BORDER_WIDTH, "--tw-dashed-border-color": DEFAULT_COLOR, + "--tw-dashed-border-align": DEFAULT_ALIGN, "--tw-dashed-border-radius": DEFAULT_RADIUS, position: "relative", }, @@ -96,10 +109,10 @@ const dashedBorderPlugin: ReturnType = plugin( strokeDashoffset: "var(--tw-dashed-border-offset)", shapeRendering: "geometricPrecision", vectorEffect: "non-scaling-stroke", - x: "calc(var(--tw-dashed-border-width) / 2)", - y: "calc(var(--tw-dashed-border-width) / 2)", - width: "calc(100% - var(--tw-dashed-border-width))", - height: "calc(100% - var(--tw-dashed-border-width))", + x: dashedBorderAlign, + y: dashedBorderAlign, + width: `calc(100% - (${dashedBorderAlign} * 2))`, + height: `calc(100% - (${dashedBorderAlign} * 2))`, rx: svgRadius, }, ".dashed-border-transition, .dashed-border.transition, .dashed-border.transition-all": @@ -121,13 +134,11 @@ const dashedBorderPlugin: ReturnType = plugin( }, ".dashed-border.transition-colors .dashed-border-rect": { transitionProperty: "stroke", - transitionTimingFunction: - "inherit", + transitionTimingFunction: "inherit", transitionDuration: "inherit", }, }); - const spacing = theme("spacing", {}) as Record; const borderWidths = theme("borderWidth", { DEFAULT: DEFAULT_BORDER_WIDTH, }) as Record; @@ -147,12 +158,19 @@ const dashedBorderPlugin: ReturnType = plugin( "dashed-border-offset": (value: string) => ({ "--tw-dashed-border-offset": value, }), + "dashed-border-align": (value: string) => ({ + "--tw-dashed-border-align": resolveAlignValue(value), + }), "dashed-border-radius": (value: string) => ({ "--tw-dashed-border-radius": value, }), }, { - values: spacing, + values: { + inside: DEFAULT_ALIGN, + edge: "0px", + outside: "calc(var(--tw-dashed-border-width) / -2)", + }, }, );