1 Commits

Author SHA1 Message Date
Mira bd83d28400 Just experiment with line bottom 2026-06-19 02:01:05 +03:00
10 changed files with 7066 additions and 95 deletions
View File
-82
View File
@@ -1,82 +0,0 @@
# Tailwind Dashed Border SVG
A plugin for addressing issue with customizable and animatable dashed border via tailwind interface (mostly).
It uses real svg under the hood what provide the maximum flexibility.
# Setup
for the tailwind v4 use this in your css file:
```css
@import "tailwindcss";
@plugin "tailwind-dashed-border";
```
then prepare a component for svg in case you don't want repeat yourself everywhere. I will show it as it would look in React, but similar approach should work in any framework.
```tsx
export function BorderSVG() {
return (
<svg className="dashed-border-svg" aria-hidden="true">
<rect className="dashed-border-rect" />
</svg>
);
}
```
and now you are ready to make your borders
```tsx
<div className="dashed-border">
<BorderSVG/>
</div>
```
# Usage Example
```tsx
<div
className="
px-14 py-10 bg-purple-900 rounded-2xl text-2xl
dashed-border dashed-border-width-5 dashed-border-color-orange-600
dashed-border-align-edge
duration-300 ease-in-out transition-all
dashed-border-gap-0 dashed-border-length-9
hover:dashed-border-gap-3 hover:dashed-border-length-6
dashed-border-offset-2.5 hover:dashed-border-offset-1
"
>
<DashedBorderSvg />
<div>Content</div>
</div>
```
![output](./assets/example.webp)
# Plugin Properties
## Setup
- `dashed-border`
- `dashed-border-svg`
- `dashed-border-rect`
## Configuration
- `dashed-border-color-[color]`
- `dashed-border-width-[px]`
- `dashed-border-length-[spacing]`
- `dashed-border-gap-[spacing]`
- `dashed-border-offset-[spacing]`
- `dashed-border-align-["inside"/"edge"/"outside"]`
- `dashed-border-align-[[number]]` - example `dashed-border-align-[0.4]` (0 - inside, 0.5 - edge, 1 - outside, etc.)
## Vanilla extended
- `duration-[ms]`
- `[timing function]` (`easing-linear`, `ease-in-out`, etc.)
- `transition` - allow transition for all border properties.
- `transition-all` - allow transition for all border properties.
- `transition-dashed-border` - to target only dashed border transitions.
# P.S. Repos
- [github repo](https://github.com/ArsenijSerjogin/tailwind-dashed-border) - mirror for releases, community issues, forks, etc.
- [main repo](https://gitea.gluhih.dev/mira/tailwind-dashed-border) - where I originally developing it.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

+6509
View File
File diff suppressed because it is too large Load Diff
+1 -11
View File
@@ -2,8 +2,6 @@
"name": "tailwind-dashed-border", "name": "tailwind-dashed-border",
"version": "0.1.0", "version": "0.1.0",
"description": "Configurable dashed border utility for Tailwind CSS v4", "description": "Configurable dashed border utility for Tailwind CSS v4",
"author": "Mira Gluhih",
"contributors": [],
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -21,10 +19,6 @@
"build": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"check": "tsc -p tsconfig.json --noEmit" "check": "tsc -p tsconfig.json --noEmit"
}, },
"repository": {
"type": "git",
"url": "https://github.com/ArsenijSerjogin/tailwind-dashed-border.git"
},
"keywords": [ "keywords": [
"tailwindcss", "tailwindcss",
"tailwind", "tailwind",
@@ -42,9 +36,5 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"license": "MIT", "license": "MIT"
"bugs": {
"url": "https://github.com/ArsenijSerjogin/tailwind-dashed-border/issues"
},
"homepage": "https://github.com/ArsenijSerjogin/tailwind-dashed-border"
} }
+63
View File
@@ -0,0 +1,63 @@
# Tailwind Dashed Border SVG
A plugin for adressing issue with custamable and animatable dashed border via tailwind interface (mostly).
It uses real svg under the hood what provide the maximum flexibility. Non animated border coming soon.
# Setup
prepare a component for svg
```tsx
export function BorderSVG() {
return (
<svg className="dashed-border-svg" aria-hidden="true">
<rect className="dashed-border-rect" />
</svg>
);
}
export function BorderBottomLineSVG() {
return (
<svg className="dashed-border-svg" aria-hidden="true">
<line
className="dashed-border-bottom-line"
x1="0"
x2="100%"
y1="100%"
y2="100%"
/>
</svg>
);
}
```
and now you are ready to make your borders
```tsx
<div className="dashed-border">
<BorderSVG/>
</div>
```
# Properties
## Setup
- dashed-border
- dashed-border-svg
- dashed-border-rect
- dashed-border-bottom-line
## Configuration
- dashed-border-color-[color]
- dashed-border-width-[spacing]
- dashed-border-length-[spacing]
- dashed-border-gap-[spacing]
- dashed-border-offset-[spacing]
- dashed-border-align-["inside"/"edge"/"outside"]
- dashed-border-align-[spacing] (0 - inside, toward the outside)
## Vanilla extended
- duration-[time]
- [timing function] (easing-linear, ease-in-out, etc.)
- transition-all
+33 -2
View File
@@ -163,9 +163,15 @@ function toCssVariable(
const dashedBorderPlugin: ReturnType<typeof plugin> = plugin( const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
({ addBase, addUtilities, theme, ...pluginApi }) => { ({ addBase, addUtilities, theme, ...pluginApi }) => {
// const matchUtilities = pluginApi.matchUtilities;
const matchUtilities = betterMatchUtility(pluginApi.matchUtilities); const matchUtilities = betterMatchUtility(pluginApi.matchUtilities);
const DEFAULT_GAP = "0.5rem";
const DEFAULT_LENGTH = "0.75rem";
const DEFAULT_OFFSET = "0px";
const DEFAULT_WIDTH = "1px";
const DEFAULT_COLOR = "currentColor"; const DEFAULT_COLOR = "currentColor";
const DEFAULT_RADIUS = "0px";
addBase({ addBase({
"@property --tw-dashed-border-gap": { "@property --tw-dashed-border-gap": {
@@ -210,13 +216,17 @@ const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
}, },
".dashed-border": { ".dashed-border": {
position: "relative", position: "relative",
// "--tw-dashed-border-gap": DEFAULT_GAP,
// "--tw-dashed-border-length": DEFAULT_LENGTH,
// "--tw-dashed-border-offset": DEFAULT_OFFSET,
// "--tw-dashed-border-width": DEFAULT_WIDTH,
"--tw-dashed-border-color": DEFAULT_COLOR, "--tw-dashed-border-color": DEFAULT_COLOR,
"--tw-dashed-border-ease": "var(--tw-ease)", "--tw-dashed-border-ease": "var(--tw-ease)",
"--tw-dashed-border-duration": "var(--tw-duration)", "--tw-dashed-border-duration": "var(--tw-duration)",
// "--tw-dashed-border-radius": DEFAULT_RADIUS,
}, },
".dashed-border-svg": { ".dashed-border-svg": {
position: "absolute", position: "absolute",
overflow: "visible",
inset: "0", inset: "0",
width: "100%", width: "100%",
height: "100%", height: "100%",
@@ -238,7 +248,7 @@ const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
"stroke-width": "var(--tw-dashed-border-width)", "stroke-width": "var(--tw-dashed-border-width)",
"stroke-dasharray": "stroke-dasharray":
"var(--tw-dashed-border-length) var(--tw-dashed-border-gap)", "var(--tw-dashed-border-length) var(--tw-dashed-border-gap)",
"stroke-dashoffset": "calc(-1 * var(--tw-dashed-border-offset))", "stroke-dashoffset": "var(--tw-dashed-border-offset)",
"vector-effect": "non-scaling-stroke", "vector-effect": "non-scaling-stroke",
x: INSET, x: INSET,
y: INSET, y: INSET,
@@ -246,6 +256,17 @@ const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
height: INNER_SIZE, height: INNER_SIZE,
rx: ADJUSTED_RADIUS, rx: ADJUSTED_RADIUS,
}, },
".dashed-border-bottom-line": {
fill: "none",
stroke: "var(--tw-dashed-border-color)",
"stroke-width": "var(--tw-dashed-border-width)",
"stroke-dasharray":
"var(--tw-dashed-border-length) var(--tw-dashed-border-gap)",
"stroke-dashoffset": "var(--tw-dashed-border-offset)",
// "stroke-linecap": "butt",
"vector-effect": "non-scaling-stroke",
transform: `translateY(${INSET})`,
},
}); });
const spacingRawValues = theme("spacing") as const spacingRawValues = theme("spacing") as
@@ -329,17 +350,27 @@ const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
} }
const ALL_TRANSITION_PROPERTIES = const ALL_TRANSITION_PROPERTIES =
"stroke-dasharray, stroke-dashoffset, stroke-width, stroke, rx, x, y, width, height"; "stroke-dasharray, stroke-dashoffset, stroke-width, stroke, rx, x, y, width, height";
const ALL_LINE_TRANSITION_PROPERTIES =
"stroke-dasharray, stroke-dashoffset, stroke-width, stroke, transform";
addUtilities({ addUtilities({
".dashed-border.transition .dashed-border-rect": createTransitionStyles( ".dashed-border.transition .dashed-border-rect": createTransitionStyles(
ALL_TRANSITION_PROPERTIES, ALL_TRANSITION_PROPERTIES,
), ),
".dashed-border.transition .dashed-border-bottom-line":
createTransitionStyles(ALL_LINE_TRANSITION_PROPERTIES),
".dashed-border.transition-all .dashed-border-rect": ".dashed-border.transition-all .dashed-border-rect":
createTransitionStyles(ALL_TRANSITION_PROPERTIES), createTransitionStyles(ALL_TRANSITION_PROPERTIES),
".dashed-border.transition-all .dashed-border-bottom-line":
createTransitionStyles(ALL_LINE_TRANSITION_PROPERTIES),
".dashed-border.transition-colors .dashed-border-rect": ".dashed-border.transition-colors .dashed-border-rect":
createTransitionStyles("stroke"), createTransitionStyles("stroke"),
".dashed-border.transition-colors .dashed-border-bottom-line":
createTransitionStyles("stroke"),
".dashed-border.transition-dashed-border .dashed-border-rect": ".dashed-border.transition-dashed-border .dashed-border-rect":
createTransitionStyles(ALL_TRANSITION_PROPERTIES), createTransitionStyles(ALL_TRANSITION_PROPERTIES),
".dashed-border.transition-dashed-border .dashed-border-bottom-line":
createTransitionStyles(ALL_LINE_TRANSITION_PROPERTIES),
}); });
}, },
); );
+217
View File
@@ -0,0 +1,217 @@
import plugin from "tailwindcss/plugin";
interface ThemeValueMap {
[key: string]: string | ThemeValueMap;
}
const DEFAULT_SPACING_VALUE = "0.25rem";
const DEFAULT_GAP = `calc(var(--spacing, ${DEFAULT_SPACING_VALUE}) * 2)`;
const DEFAULT_LENGTH = `calc(var(--spacing, ${DEFAULT_SPACING_VALUE}) * 3)`;
const DEFAULT_BORDER_WIDTH = "1px";
const DEFAULT_OFFSET = "0px";
const DEFAULT_COLOR = "currentColor";
const DEFAULT_RADIUS = "0px";
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, x, y, width, height";
const flattenThemeMap = (
input: ThemeValueMap,
path: string[] = [],
): Record<string, string> => {
const output: Record<string, string> = {};
for (const [key, value] of Object.entries(input)) {
const nextPath = key === "DEFAULT" ? path : [...path, key];
if (typeof value === "string") {
output[nextPath.join("-")] = value;
continue;
}
Object.assign(output, flattenThemeMap(value, nextPath));
}
return output;
};
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<typeof plugin> = plugin(
({ addBase, addUtilities, matchUtilities, theme }) => {
addBase({
"@property --tw-dashed-border-gap": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": "0.5rem",
},
"@property --tw-dashed-border-length": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": "0.75rem",
},
"@property --tw-dashed-border-offset": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": DEFAULT_OFFSET,
},
"@property --tw-dashed-border-width": {
syntax: "<length>",
inherits: "true",
"initial-value": DEFAULT_BORDER_WIDTH,
},
"@property --tw-dashed-border-align": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": DEFAULT_ALIGN,
},
"@property --tw-dashed-border-radius": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": DEFAULT_RADIUS,
},
});
addUtilities({
".dashed-border": {
"--tw-dashed-border-gap": DEFAULT_GAP,
"--tw-dashed-border-length": DEFAULT_LENGTH,
"--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",
},
".dashed-border-svg": {
display: "block",
position: "absolute",
inset: "0",
width: "100%",
height: "100%",
overflow: "hidden",
pointerEvents: "none",
},
".dashed-border-rect": {
fill: "none",
stroke: "var(--tw-dashed-border-color)",
strokeWidth: "var(--tw-dashed-border-width)",
strokeDasharray:
"var(--tw-dashed-border-length) var(--tw-dashed-border-gap)",
strokeDashoffset: "var(--tw-dashed-border-offset)",
shapeRendering: "geometricPrecision",
vectorEffect: "non-scaling-stroke",
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":
{
transitionTimingFunction:
"var(--default-transition-timing-function, cubic-bezier(0.4, 0, 0.2, 1))",
transitionDuration: "var(--default-transition-duration, 150ms)",
},
".dashed-border.transition-colors": {
transitionTimingFunction:
"var(--default-transition-timing-function, cubic-bezier(0.4, 0, 0.2, 1))",
transitionDuration: "var(--default-transition-duration, 150ms)",
},
".dashed-border-transition .dashed-border-rect, .dashed-border.transition .dashed-border-rect, .dashed-border.transition-all .dashed-border-rect":
{
transitionProperty: dashedBorderTransitionProperties,
transitionTimingFunction: "inherit",
transitionDuration: "inherit",
},
".dashed-border.transition-colors .dashed-border-rect": {
transitionProperty: "stroke",
transitionTimingFunction: "inherit",
transitionDuration: "inherit",
},
});
const borderWidths = theme("borderWidth", {
DEFAULT: DEFAULT_BORDER_WIDTH,
}) as Record<string, string>;
const colors = flattenThemeMap(theme("colors", {}) as ThemeValueMap);
const radii = theme("borderRadius", {
DEFAULT: DEFAULT_RADIUS,
}) as Record<string, string>;
matchUtilities(
{
"dashed-border-gap": (value: string) => ({
"--tw-dashed-border-gap": value,
}),
"dashed-border-length": (value: string) => ({
"--tw-dashed-border-length": value,
}),
"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: {
inside: DEFAULT_ALIGN,
edge: "0px",
outside: "calc(var(--tw-dashed-border-width) / -2)",
},
},
);
matchUtilities(
{
"dashed-border-width": (value: string) => ({
"--tw-dashed-border-width": value,
}),
},
{
values: borderWidths,
},
);
matchUtilities(
{
"dashed-border-color": (value: string) => ({
"--tw-dashed-border-color": value,
}),
},
{
values: {
...colors,
current: "currentColor",
inherit: "inherit",
transparent: "transparent",
},
},
);
addUtilities(
Object.fromEntries(
Object.entries(radii).map(([name, value]) => [
`.dashed-border${roundedSelector(name)}`,
{
"--tw-dashed-border-radius": value,
},
]),
),
);
},
);
export default dashedBorderPlugin;
+210
View File
@@ -0,0 +1,210 @@
import plugin from "tailwindcss/plugin";
interface ThemeValueMap {
[key: string]: string | ThemeValueMap;
}
const DEFAULT_SPACING_VALUE = "0.25rem";
const DEFAULT_GAP = `calc(var(--spacing, ${DEFAULT_SPACING_VALUE}) * 2)`;
const DEFAULT_LENGTH = `calc(var(--spacing, ${DEFAULT_SPACING_VALUE}) * 3)`;
const DEFAULT_BORDER_WIDTH = "1px";
const DEFAULT_OFFSET = "0px";
const DEFAULT_COLOR = "currentColor";
const DEFAULT_RADIUS = "0px";
const DEFAULT_ALIGNMENT = "0%";
const dashedBorderInset =
"calc((0.5 - (var(--tw-dashed-border-alignment) / 100%)) * var(--tw-dashed-border-width))";
const svgRadius = `max(0px, calc(var(--tw-dashed-border-radius) - (${dashedBorderInset})))`;
const dashedBorderTransitionProperties =
"stroke-dasharray, stroke-dashoffset, stroke-width, stroke, rx, x, y, width, height";
const flattenThemeMap = (
input: ThemeValueMap,
path: string[] = [],
): Record<string, string> => {
const output: Record<string, string> = {};
for (const [key, value] of Object.entries(input)) {
const nextPath = key === "DEFAULT" ? path : [...path, key];
if (typeof value === "string") {
output[nextPath.join("-")] = value;
continue;
}
Object.assign(output, flattenThemeMap(value, nextPath));
}
return output;
};
const roundedSelector = (name: string): string =>
name === "DEFAULT" ? ".rounded" : `.rounded-${name}`;
const dashedBorderPlugin: ReturnType<typeof plugin> = plugin(
({ addBase, addUtilities, matchUtilities, theme }) => {
addBase({
"@property --tw-dashed-border-gap": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": "0.5rem",
},
"@property --tw-dashed-border-length": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": "0.75rem",
},
"@property --tw-dashed-border-offset": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": DEFAULT_OFFSET,
},
"@property --tw-dashed-border-width": {
syntax: "<length>",
inherits: "true",
"initial-value": DEFAULT_BORDER_WIDTH,
},
"@property --tw-dashed-border-alignment": {
syntax: "<percentage>",
inherits: "true",
"initial-value": DEFAULT_ALIGNMENT,
},
"@property --tw-dashed-border-radius": {
syntax: "<length-percentage>",
inherits: "true",
"initial-value": DEFAULT_RADIUS,
},
});
addUtilities({
".dashed-border": {
"--tw-dashed-border-gap": DEFAULT_GAP,
"--tw-dashed-border-length": DEFAULT_LENGTH,
"--tw-dashed-border-offset": DEFAULT_OFFSET,
"--tw-dashed-border-width": DEFAULT_BORDER_WIDTH,
"--tw-dashed-border-color": DEFAULT_COLOR,
"--tw-dashed-border-alignment": DEFAULT_ALIGNMENT,
"--tw-dashed-border-radius": DEFAULT_RADIUS,
position: "relative",
},
".dashed-border-svg": {
display: "block",
position: "absolute",
inset: "0",
width: "100%",
height: "100%",
overflow: "hidden",
pointerEvents: "none",
},
".dashed-border-rect": {
fill: "none",
stroke: "var(--tw-dashed-border-color)",
strokeWidth: "var(--tw-dashed-border-width)",
strokeDasharray:
"var(--tw-dashed-border-length) var(--tw-dashed-border-gap)",
strokeDashoffset: "var(--tw-dashed-border-offset)",
shapeRendering: "geometricPrecision",
vectorEffect: "non-scaling-stroke",
x: dashedBorderInset,
y: dashedBorderInset,
width: `calc(100% - (${dashedBorderInset} * 2))`,
height: `calc(100% - (${dashedBorderInset} * 2))`,
rx: svgRadius,
},
".dashed-border-transition, .dashed-border.transition, .dashed-border.transition-all":
{
transitionTimingFunction:
"var(--default-transition-timing-function, cubic-bezier(0.4, 0, 0.2, 1))",
transitionDuration: "var(--default-transition-duration, 150ms)",
},
".dashed-border.transition-colors": {
transitionTimingFunction:
"var(--default-transition-timing-function, cubic-bezier(0.4, 0, 0.2, 1))",
transitionDuration: "var(--default-transition-duration, 150ms)",
},
".dashed-border-transition .dashed-border-rect, .dashed-border.transition .dashed-border-rect, .dashed-border.transition-all .dashed-border-rect":
{
transitionProperty: dashedBorderTransitionProperties,
transitionTimingFunction: "inherit",
transitionDuration: "inherit",
},
".dashed-border.transition-colors .dashed-border-rect": {
transitionProperty: "stroke",
transitionTimingFunction: "inherit",
transitionDuration: "inherit",
},
});
const spacing = theme("spacing", {}) as Record<string, string>;
const borderWidths = theme("borderWidth", {
DEFAULT: DEFAULT_BORDER_WIDTH,
}) as Record<string, string>;
const colors = flattenThemeMap(theme("colors", {}) as ThemeValueMap);
const radii = theme("borderRadius", {
DEFAULT: DEFAULT_RADIUS,
}) as Record<string, string>;
matchUtilities(
{
"dashed-border-gap": (value: string) => ({
"--tw-dashed-border-gap": value,
}),
"dashed-border-length": (value: string) => ({
"--tw-dashed-border-length": value,
}),
"dashed-border-offset": (value: string) => ({
"--tw-dashed-border-offset": value,
}),
"dashed-border-align": (value: string) => ({
"--tw-dashed-border-alignment": value,
}),
"dashed-border-radius": (value: string) => ({
"--tw-dashed-border-radius": value,
}),
},
{
values: spacing,
},
);
matchUtilities(
{
"dashed-border-width": (value: string) => ({
"--tw-dashed-border-width": value,
}),
},
{
values: borderWidths,
},
);
matchUtilities(
{
"dashed-border-color": (value: string) => ({
"--tw-dashed-border-color": value,
}),
},
{
values: {
...colors,
current: "currentColor",
inherit: "inherit",
transparent: "transparent",
},
},
);
addUtilities(
Object.fromEntries(
Object.entries(radii).map(([name, value]) => [
`.dashed-border${roundedSelector(name)}`,
{
"--tw-dashed-border-radius": value,
},
]),
),
);
},
);
export default dashedBorderPlugin;
+33
View File
@@ -0,0 +1,33 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import { createRequire } from 'node:module'
import plugin from 'tailwindcss/plugin'
import { compile } from 'tailwindcss'
import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette'
const require = createRequire(import.meta.url)
const pluginTest = plugin(({ theme, config }) => {
const raw = theme('colors')
const flat = flattenColorPalette(raw ?? {})
const random_fn = theme("backgroundOpacity.__BARE_VALUE__")
const random_fn = theme("backgroundOpacity.__BARE_VALUE__")
console.log('default bare function at 80', random_fn, random_fn({value: 80, fraction: null}));
})
await compile('@import "tailwindcss"; @plugin "inspect-plugin";', {
base: process.cwd(),
async loadModule(id, base) {
if (id === 'inspect-plugin') {
return { path: 'inspect-plugin', base, module: pluginTest }
}
},
async loadStylesheet(id, base) {
if (id === 'tailwindcss') {
const pkg = path.dirname(require.resolve('tailwindcss/package.json'))
const file = path.join(pkg, 'index.css')
return { path: file, base: path.dirname(file), content: await fs.readFile(file, 'utf8') }
}
const resolved = path.resolve(base, id)
return { path: resolved, base: path.dirname(resolved), content: await fs.readFile(resolved, 'utf8') }
},
})