From a4ab511a6e3681c0937da7f2fe07b4beeb89d639 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Sat, 26 Apr 2025 23:59:52 +0200 Subject: [PATCH 1/5] Try to fix tailwind hijacking issues --- src/index.css | 124 +++++++++++++++++++++++---------------------- tailwind.config.js | 3 +- 2 files changed, 65 insertions(+), 62 deletions(-) diff --git a/src/index.css b/src/index.css index a349e17..f013422 100644 --- a/src/index.css +++ b/src/index.css @@ -2,80 +2,82 @@ @tailwind components; @tailwind utilities; -:root { - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -@layer base { +.sui-layout { :root { - --rfs-background: 0 0% 100%; - --rfs-foreground: 0 0% 3.9%; - --rfs-card: 0 0% 100%; - --rfs-card-foreground: 0 0% 3.9%; - --rfs-popover: 0 0% 100%; - --rfs-popover-foreground: 0 0% 3.9%; - --rfs-primary: 215 100% 50%; - --rfs-primary-foreground: 0 0% 98%; - --rfs-secondary: 0 0% 96.1%; - --rfs-secondary-foreground: 0 0% 9%; - --rfs-muted: 0 0% 96.1%; - --rfs-muted-foreground: 0 0% 45.1%; - --rfs-accent: 0 0% 96.1%; - --rfs-accent-foreground: 0 0% 9%; - --rfs-destructive: 0 84.2% 60.2%; - --rfs-destructive-foreground: 0 0% 98%; - --rfs-border: 0 0% 89.8%; - --rfs-input: 0 0% 89.8%; - --rfs-ring: 0 0% 3.9%; - --rfs-chart-1: 12 76% 61%; - --rfs-chart-2: 173 58% 39%; - --rfs-chart-3: 197 37% 24%; - --rfs-chart-4: 43 74% 66%; - --rfs-chart-5: 27 87% 67%; - --rfs-radius: 0.5rem; + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } - .dark { - --rfs-background: 0 0% 3.9%; - --rfs-foreground: 0 0% 98%; - --rfs-card: 0 0% 3.9%; - --rfs-card-foreground: 0 0% 98%; - --rfs-popover: 0 0% 3.9%; - --rfs-popover-foreground: 0 0% 98%; - --rfs-primary: 215 100% 40%; - --rfs-primary-foreground: 0 0% 98%; - --rfs-secondary: 0 0% 14.9%; - --rfs-secondary-foreground: 0 0% 98%; - --rfs-muted: 0 0% 14.9%; - --rfs-muted-foreground: 0 0% 63.9%; - --rfs-accent: 0 0% 14.9%; - --rfs-accent-foreground: 0 0% 98%; - --rfs-destructive: 0 62.8% 30.6%; - --rfs-destructive-foreground: 0 0% 98%; - --rfs-border: 0 0% 14.9%; - --rfs-input: 0 0% 14.9%; - --rfs-ring: 0 0% 83.1%; - --rfs-chart-1: 220 70% 50%; - --rfs-chart-2: 160 60% 45%; - --rfs-chart-3: 30 80% 55%; - --rfs-chart-4: 280 65% 60%; - --rfs-chart-5: 340 75% 55%; + @layer base { + :root { + --rfs-background: 0 0% 100%; + --rfs-foreground: 0 0% 3.9%; + --rfs-card: 0 0% 100%; + --rfs-card-foreground: 0 0% 3.9%; + --rfs-popover: 0 0% 100%; + --rfs-popover-foreground: 0 0% 3.9%; + --rfs-primary: 215 100% 50%; + --rfs-primary-foreground: 0 0% 98%; + --rfs-secondary: 0 0% 96.1%; + --rfs-secondary-foreground: 0 0% 9%; + --rfs-muted: 0 0% 96.1%; + --rfs-muted-foreground: 0 0% 45.1%; + --rfs-accent: 0 0% 96.1%; + --rfs-accent-foreground: 0 0% 9%; + --rfs-destructive: 0 84.2% 60.2%; + --rfs-destructive-foreground: 0 0% 98%; + --rfs-border: 0 0% 89.8%; + --rfs-input: 0 0% 89.8%; + --rfs-ring: 0 0% 3.9%; + --rfs-chart-1: 12 76% 61%; + --rfs-chart-2: 173 58% 39%; + --rfs-chart-3: 197 37% 24%; + --rfs-chart-4: 43 74% 66%; + --rfs-chart-5: 27 87% 67%; + --rfs-radius: 0.5rem; + } + + .dark { + --rfs-background: 0 0% 3.9%; + --rfs-foreground: 0 0% 98%; + --rfs-card: 0 0% 3.9%; + --rfs-card-foreground: 0 0% 98%; + --rfs-popover: 0 0% 3.9%; + --rfs-popover-foreground: 0 0% 98%; + --rfs-primary: 215 100% 40%; + --rfs-primary-foreground: 0 0% 98%; + --rfs-secondary: 0 0% 14.9%; + --rfs-secondary-foreground: 0 0% 98%; + --rfs-muted: 0 0% 14.9%; + --rfs-muted-foreground: 0 0% 63.9%; + --rfs-accent: 0 0% 14.9%; + --rfs-accent-foreground: 0 0% 98%; + --rfs-destructive: 0 62.8% 30.6%; + --rfs-destructive-foreground: 0 0% 98%; + --rfs-border: 0 0% 14.9%; + --rfs-input: 0 0% 14.9%; + --rfs-ring: 0 0% 83.1%; + --rfs-chart-1: 220 70% 50%; + --rfs-chart-2: 160 60% 45%; + --rfs-chart-3: 30 80% 55%; + --rfs-chart-4: 280 65% 60%; + --rfs-chart-5: 340 75% 55%; + } } } @layer base { - * { + .sui-layout * { @apply rfs-border-border; } - body { + .sui-layout { @apply rfs-bg-background rfs-text-foreground; } - ul, ol { + .sui-layout ul, .sui-layout ol { list-style: revert; margin: revert; padding: revert; diff --git a/tailwind.config.js b/tailwind.config.js index 6f3fca3..718c766 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,7 @@ /** @type {import('tailwindcss').Config} */ import animatePlugin from "tailwindcss-animate" +import nestingPlugin from "tailwindcss/nesting" export default { darkMode: ["class", `[class="dark"]`], @@ -70,5 +71,5 @@ export default { } } }, - plugins: [animatePlugin] + plugins: [animatePlugin, nestingPlugin] } From e1bbc2ceba64bfa01b479e4778738e9771b6eea5 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Sun, 27 Apr 2025 00:31:21 +0200 Subject: [PATCH 2/5] Fully isolate tailwind styles to only this component --- .storybook/decorators/RootClass.tsx | 9 + .storybook/preview.ts | 4 +- package-lock.json | 12 ++ package.json | 1 + src/components/ReactSearchComponent.tsx | 1 + src/components/ui/carousel.tsx | 2 +- src/components/ui/dialog.tsx | 2 +- src/components/ui/dropdown-menu.tsx | 257 +++++++++++------------- src/components/ui/popover.tsx | 28 +-- src/components/ui/select.tsx | 212 +++++++++---------- src/components/ui/tooltip.tsx | 22 +- tailwind.config.js | 9 +- tsconfig.app.json | 2 +- tsconfig.node.json | 2 +- 14 files changed, 278 insertions(+), 285 deletions(-) create mode 100644 .storybook/decorators/RootClass.tsx diff --git a/.storybook/decorators/RootClass.tsx b/.storybook/decorators/RootClass.tsx new file mode 100644 index 0000000..5a9290e --- /dev/null +++ b/.storybook/decorators/RootClass.tsx @@ -0,0 +1,9 @@ +import { Decorator } from "@storybook/react" + +export const withRootClass: Decorator = (Story) => { + return ( +
+ +
+ ) +} diff --git a/.storybook/preview.ts b/.storybook/preview.ts index e5106c4..999dcd0 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -2,6 +2,7 @@ import type { Preview } from "@storybook/react" import { withThemeByClassName } from "@storybook/addon-themes" import "../src/index.css" +import { withRootClass } from "./decorators/RootClass" const preview: Preview = { parameters: { @@ -24,7 +25,8 @@ const preview: Preview = { dark: "dark" }, defaultTheme: "light" - }) + }), + withRootClass ] } diff --git a/package-lock.json b/package-lock.json index ddd3d6c..4578102 100644 --- a/package-lock.json +++ b/package-lock.json @@ -77,6 +77,7 @@ "style-loader": "^4.0.0", "tailwindcss": "^3.4.16", "tailwindcss-animate": "^1.0.7", + "tailwindcss-scoped-preflight": "^3.4.12", "ts-loader": "^9.5.2", "tsc-alias": "^1.8.10", "typescript": "^5.7.3", @@ -17800,6 +17801,17 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tailwindcss-scoped-preflight": { + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/tailwindcss-scoped-preflight/-/tailwindcss-scoped-preflight-3.4.12.tgz", + "integrity": "sha512-iEk5Hk4N1C3TZpUlRHc1TiPY9+A/X+Ia21/i/hO0yjMy3A5tGDCZZJdREK8tWPzybgBYRBNpUxTWbL0Yj0zoSw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "postcss": "^8", + "tailwindcss": "^3" + } + }, "node_modules/tailwindcss/node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", diff --git a/package.json b/package.json index 1c9e48f..5c31e01 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "style-loader": "^4.0.0", "tailwindcss": "^3.4.16", "tailwindcss-animate": "^1.0.7", + "tailwindcss-scoped-preflight": "^3.4.12", "ts-loader": "^9.5.2", "tsc-alias": "^1.8.10", "typescript": "^5.7.3", diff --git a/src/components/ReactSearchComponent.tsx b/src/components/ReactSearchComponent.tsx index cf3fd1a..80095da 100644 --- a/src/components/ReactSearchComponent.tsx +++ b/src/components/ReactSearchComponent.tsx @@ -128,6 +128,7 @@ export function ReactSearchComponent({ return ( +
) diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 0d271ff..683f7c6 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -38,7 +38,7 @@ const DialogContent = React.forwardRef< , - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } >(({ className, inset, children, ...props }, ref) => ( - - {children} - - + + {children} + + )) -DropdownMenuSubTrigger.displayName = - DropdownMenuPrimitive.SubTrigger.displayName +DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName const DropdownMenuSubContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) -DropdownMenuSubContent.displayName = - DropdownMenuPrimitive.SubContent.displayName +DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName const DropdownMenuContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( - - - + + + )) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const DropdownMenuItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } >(({ className, inset, ...props }, ref) => ( - + )) DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName const DropdownMenuCheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - + + + + + + + {children} + )) -DropdownMenuCheckboxItem.displayName = - DropdownMenuPrimitive.CheckboxItem.displayName +DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName const DropdownMenuRadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - - - - - - {children} - + + + + + + + {children} + )) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const DropdownMenuLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } >(({ className, inset, ...props }, ref) => ( - + )) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName const DropdownMenuSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName -const DropdownMenuShortcut = ({ - className, - ...props -}: React.HTMLAttributes) => { - return ( - - ) +const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { + return } DropdownMenuShortcut.displayName = "DropdownMenuShortcut" export { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuCheckboxItem, - DropdownMenuRadioItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuRadioGroup, + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup } diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx index 0b8288c..ff600b8 100644 --- a/src/components/ui/popover.tsx +++ b/src/components/ui/popover.tsx @@ -10,21 +10,21 @@ const Popover = PopoverPrimitive.Root const PopoverTrigger = PopoverPrimitive.Trigger const PopoverContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( - - - + + + )) PopoverContent.displayName = PopoverPrimitive.Content.displayName diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index 3b7777b..5897ad5 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -11,148 +11,130 @@ const SelectGroup = SelectPrimitive.Group const SelectValue = SelectPrimitive.Value const SelectTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - span]:rfs-line-clamp-1", - className - )} - {...props} - > - {children} - - - - + span]:rfs-line-clamp-1", + className + )} + {...props} + > + {children} + + + + )) SelectTrigger.displayName = SelectPrimitive.Trigger.displayName const SelectScrollUpButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - + + + )) SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName const SelectScrollDownButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - + + + )) -SelectScrollDownButton.displayName = - SelectPrimitive.ScrollDownButton.displayName +SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName const SelectContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, position = "popper", ...props }, ref) => ( - - - - - {children} - - - - + + + + + {children} + + + + )) SelectContent.displayName = SelectPrimitive.Content.displayName -const SelectLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) +const SelectLabel = React.forwardRef, React.ComponentPropsWithoutRef>( + ({ className, ...props }, ref) => ( + + ) +) SelectLabel.displayName = SelectPrimitive.Label.displayName -const SelectItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - - - +const SelectItem = React.forwardRef, React.ComponentPropsWithoutRef>( + ({ className, children, ...props }, ref) => ( + + + + + + - {children} - -)) + {children} + + ) +) SelectItem.displayName = SelectPrimitive.Item.displayName const SelectSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) SelectSeparator.displayName = SelectPrimitive.Separator.displayName export { - Select, - SelectGroup, - SelectValue, - SelectTrigger, - SelectContent, - SelectLabel, - SelectItem, - SelectSeparator, - SelectScrollUpButton, - SelectScrollDownButton, + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton } diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index 8ac513f..d302bde 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -10,18 +10,18 @@ const Tooltip = TooltipPrimitive.Root const TooltipTrigger = TooltipPrimitive.Trigger const TooltipContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( - + )) TooltipContent.displayName = TooltipPrimitive.Content.displayName diff --git a/tailwind.config.js b/tailwind.config.js index 718c766..4bfcf1d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,7 @@ /** @type {import('tailwindcss').Config} */ import animatePlugin from "tailwindcss-animate" -import nestingPlugin from "tailwindcss/nesting" +import { isolateInsideOfContainer, scopedPreflightStyles } from "tailwindcss-scoped-preflight" export default { darkMode: ["class", `[class="dark"]`], @@ -71,5 +71,10 @@ export default { } } }, - plugins: [animatePlugin, nestingPlugin] + plugins: [ + animatePlugin, + scopedPreflightStyles({ + isolationStrategy: isolateInsideOfContainer(".rfs-root", {}) + }) + ] } diff --git a/tsconfig.app.json b/tsconfig.app.json index a285f83..453b836 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -24,5 +24,5 @@ }, "baseUrl": "./" }, - "include": ["src"] + "include": ["src", ".storybook/*"] } diff --git a/tsconfig.node.json b/tsconfig.node.json index db0becc..54bb9c2 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -18,7 +18,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedSideEffectImports": true, }, "include": ["vite.config.ts"] } From b1aede6c3409b3983fb3258b4bf6c22a964321ce Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Sun, 27 Apr 2025 14:17:25 +0200 Subject: [PATCH 3/5] Potentially fully isolate tailwind rules --- package-lock.json | 51 +++++++++++++++++++++++++++++----------------- package.json | 3 ++- postcss-scoped.cjs | 19 +++++++++++++++++ postcss.config.cjs | 5 +---- src/index.css | 9 ++++---- tailwind.config.js | 3 +++ 6 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 postcss-scoped.cjs diff --git a/package-lock.json b/package-lock.json index 4578102..da13c0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,7 @@ "globals": "^16.0.0", "postcss": "^8.4.49", "postcss-loader": "^8.1.1", + "postcss-nested": "^7.0.2", "prettier": "^3.4.2", "storybook": "^8.4.7", "style-loader": "^4.0.0", @@ -15626,9 +15627,9 @@ } }, "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-7.0.2.tgz", + "integrity": "sha512-5osppouFc0VR9/VYzYxO03VaDa3e8F23Kfd6/9qcZTUI8P58GIYlArOET2Wq0ywSl2o2PjELhYOFI4W7l5QHKw==", "dev": true, "funding": [ { @@ -15642,29 +15643,15 @@ ], "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.1.1" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": ">=12.0" + "node": ">=18.0" }, "peerDependencies": { "postcss": "^8.2.14" } }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-selector-parser": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", @@ -17812,6 +17799,32 @@ "tailwindcss": "^3" } }, + "node_modules/tailwindcss/node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, "node_modules/tailwindcss/node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", diff --git a/package.json b/package.json index 5c31e01..4301f35 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "storybook:dev": "storybook dev -p 6006", "storybook:build": "storybook build", "storybook:test": "test-storybook", - "build": "rm -rf ./dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.app.json && tailwind build -i src/index.css -o dist/index.css && cp ./src/elastic-ui.css ./dist", + "build": "rm -rf ./dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.app.json && tailwind build -i src/index.css -o dist/index.css --postcss && cp ./src/elastic-ui.css ./dist", "test": "" }, "dependencies": { @@ -98,6 +98,7 @@ "globals": "^16.0.0", "postcss": "^8.4.49", "postcss-loader": "^8.1.1", + "postcss-nested": "^7.0.2", "prettier": "^3.4.2", "storybook": "^8.4.7", "style-loader": "^4.0.0", diff --git a/postcss-scoped.cjs b/postcss-scoped.cjs new file mode 100644 index 0000000..bd7e9c2 --- /dev/null +++ b/postcss-scoped.cjs @@ -0,0 +1,19 @@ +/** + * @type {import('postcss').PluginCreator} + */ +module.exports = (opts = {}) => ({ + postcssPlugin: "postcss-scoped", + Once(root) { + root.walkRules((rule) => { + if (rule.selector === "*, ::before, ::after") { + rule.selectors = rule.selectors.map((s) => (s === "*" ? "*:where(.rfs-root,.rfs-root *)" : ":where(.rfs-root,.rfs-root *)" + s)) + } + + if (rule.selector === "::backdrop") { + rule.selectors = rule.selectors.map((s) => ":where(.rfs-root,.rfs-root *)" + s) + } + }) + } +}) + +module.exports.postcss = true diff --git a/postcss.config.cjs b/postcss.config.cjs index 33ad091..e62e68e 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -1,6 +1,3 @@ module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, + plugins: [require("tailwindcss"), require("autoprefixer"), require("postcss-nested"), require("./postcss-scoped.cjs")] } diff --git a/src/index.css b/src/index.css index f013422..ad9cfcc 100644 --- a/src/index.css +++ b/src/index.css @@ -2,7 +2,7 @@ @tailwind components; @tailwind utilities; -.sui-layout { +.rfs-root { :root { font-synthesis: none; text-rendering: optimizeLegibility; @@ -70,11 +70,12 @@ @layer base { .sui-layout * { - @apply rfs-border-border; + border-color: hsl(var(--rfs-border)); } - .sui-layout { - @apply rfs-bg-background rfs-text-foreground; + #storybook-root { + background-color: hsl(var(--rfs-background)); + color: hsl(var(--rfs-foreground)); } .sui-layout ul, .sui-layout ol { diff --git a/tailwind.config.js b/tailwind.config.js index 4bfcf1d..729d5eb 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -2,6 +2,8 @@ import animatePlugin from "tailwindcss-animate" import { isolateInsideOfContainer, scopedPreflightStyles } from "tailwindcss-scoped-preflight" +import nestingPlugin from "tailwindcss/nesting" +import postcssNesting from "postcss-nested" export default { darkMode: ["class", `[class="dark"]`], @@ -73,6 +75,7 @@ export default { }, plugins: [ animatePlugin, + nestingPlugin(postcssNesting), scopedPreflightStyles({ isolationStrategy: isolateInsideOfContainer(".rfs-root", {}) }) From 10fa3e6feccf8a5f214d02e2c330e6a890162494 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Mon, 28 Apr 2025 09:26:31 +0200 Subject: [PATCH 4/5] Fix borders and text color in dark mode popups --- postcss-scoped.cjs | 7 +++++++ src/components/ui/dialog.tsx | 2 +- src/elastic-ui.css | 7 ------- src/index.css | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/postcss-scoped.cjs b/postcss-scoped.cjs index bd7e9c2..0f920be 100644 --- a/postcss-scoped.cjs +++ b/postcss-scoped.cjs @@ -1,3 +1,8 @@ +/** + * PostCSS plugin for rewriting some selectors in tailwindcss to prevent overspill of tailwind variables into the + * surrounding application. There are more isolation mechanics in tailwind.config.js + */ + /** * @type {import('postcss').PluginCreator} */ @@ -5,10 +10,12 @@ module.exports = (opts = {}) => ({ postcssPlugin: "postcss-scoped", Once(root) { root.walkRules((rule) => { + // Rewrite global variable declaration to be only present on elements inside .rfs-root if (rule.selector === "*, ::before, ::after") { rule.selectors = rule.selectors.map((s) => (s === "*" ? "*:where(.rfs-root,.rfs-root *)" : ":where(.rfs-root,.rfs-root *)" + s)) } + // Rewrite backdrop variable declaration to be only present on backdrops inside .rfs-root if (rule.selector === "::backdrop") { rule.selectors = rule.selectors.map((s) => ":where(.rfs-root,.rfs-root *)" + s) } diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 683f7c6..dd960e5 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef< Date: Mon, 28 Apr 2025 09:44:04 +0200 Subject: [PATCH 5/5] Add some documentation on styling --- README.md | 2 +- src/stories/3 Styling.mdx | 80 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/stories/3 Styling.mdx diff --git a/README.md b/README.md index b5d58d3..c1c8842 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Then simply pass your custom component to the search component. ### Styling Styling is done using tailwind and css variables. Feel free to override these variables in your own CSS. - +More information can be found in the Storybook. ## Contributing diff --git a/src/stories/3 Styling.mdx b/src/stories/3 Styling.mdx new file mode 100644 index 0000000..fd204ee --- /dev/null +++ b/src/stories/3 Styling.mdx @@ -0,0 +1,80 @@ +import { Meta, Source } from "@storybook/blocks" + + + +# Styling + +This component uses Tailwind and shadcn/ui for styling and structuring the component. You can customize many aspects of +the theme, like colors and edge radius. You can also switch between dark and light mode by using the `dark` prop on +`` + +## CSS Variables + +The following CSS variables can be overwritten to match your needs. Shown are the default values. Make sure to also +**supply your color values in HSL**. + +> **Note:** Some variables might currently not be in use + + + +## CSS classes + +CSS classes with prefix `sui-` are specified in the `elastic-ui.css` file, these classes can be directly overwritten in your CSS. + +Tailwind classes start with `rfs-`. Colors should be overwritten by using the color variables above. \ No newline at end of file