jaci-ui 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +75 -0
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/components/alert-dialog/alert-dialog.cjs +4 -1
- package/dist/components/alert-dialog/alert-dialog.cjs.map +1 -1
- package/dist/components/alert-dialog/alert-dialog.d.cts +2 -2
- package/dist/components/alert-dialog/alert-dialog.d.ts +2 -2
- package/dist/components/alert-dialog/alert-dialog.js +4 -1
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/carousel/carousel.cjs +342 -0
- package/dist/components/carousel/carousel.cjs.map +1 -0
- package/dist/components/carousel/carousel.d.cts +44 -0
- package/dist/components/carousel/carousel.d.ts +44 -0
- package/dist/components/carousel/carousel.js +330 -0
- package/dist/components/carousel/carousel.js.map +1 -0
- package/dist/components/carousel/index.d.cts +2 -0
- package/dist/components/carousel/index.d.ts +2 -0
- package/dist/components/code/code.cjs +32 -5
- package/dist/components/code/code.cjs.map +1 -1
- package/dist/components/code/code.d.cts +1 -0
- package/dist/components/code/code.d.ts +1 -0
- package/dist/components/code/code.js +34 -7
- package/dist/components/code/code.js.map +1 -1
- package/dist/components/color-picker/color-picker.cjs +4 -1
- package/dist/components/color-picker/color-picker.cjs.map +1 -1
- package/dist/components/color-picker/color-picker.d.cts +2 -2
- package/dist/components/color-picker/color-picker.d.ts +2 -2
- package/dist/components/color-picker/color-picker.js +4 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-swatch/color-swatch.cjs +33 -0
- package/dist/components/color-swatch/color-swatch.cjs.map +1 -0
- package/dist/components/color-swatch/color-swatch.d.cts +13 -0
- package/dist/components/color-swatch/color-swatch.d.ts +13 -0
- package/dist/components/color-swatch/color-swatch.js +33 -0
- package/dist/components/color-swatch/color-swatch.js.map +1 -0
- package/dist/components/color-swatch/index.d.cts +2 -0
- package/dist/components/color-swatch/index.d.ts +2 -0
- package/dist/components/combobox/combobox.cjs +4 -1
- package/dist/components/combobox/combobox.cjs.map +1 -1
- package/dist/components/combobox/combobox.d.cts +2 -2
- package/dist/components/combobox/combobox.d.ts +2 -2
- package/dist/components/combobox/combobox.js +4 -1
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.cjs +76 -13
- package/dist/components/command/command.cjs.map +1 -1
- package/dist/components/command/command.d.cts +7 -1
- package/dist/components/command/command.d.ts +7 -1
- package/dist/components/command/command.js +76 -13
- package/dist/components/command/command.js.map +1 -1
- package/dist/components/command/index.d.cts +2 -2
- package/dist/components/command/index.d.ts +2 -2
- package/dist/components/context-menu/context-menu.cjs +4 -1
- package/dist/components/context-menu/context-menu.cjs.map +1 -1
- package/dist/components/context-menu/context-menu.d.cts +2 -2
- package/dist/components/context-menu/context-menu.d.ts +2 -2
- package/dist/components/context-menu/context-menu.js +4 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +4 -1
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.d.cts +2 -2
- package/dist/components/date-picker/date-picker.d.ts +2 -2
- package/dist/components/date-picker/date-picker.js +4 -1
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.cjs +4 -1
- package/dist/components/date-range-picker/date-range-picker.cjs.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.d.cts +2 -2
- package/dist/components/date-range-picker/date-range-picker.d.ts +2 -2
- package/dist/components/date-range-picker/date-range-picker.js +4 -1
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/dialog/dialog.cjs +4 -1
- package/dist/components/dialog/dialog.cjs.map +1 -1
- package/dist/components/dialog/dialog.d.cts +2 -2
- package/dist/components/dialog/dialog.d.ts +2 -2
- package/dist/components/dialog/dialog.js +4 -1
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/download-trigger/download-trigger.cjs +25 -0
- package/dist/components/download-trigger/download-trigger.cjs.map +1 -0
- package/dist/components/download-trigger/download-trigger.d.cts +12 -0
- package/dist/components/download-trigger/download-trigger.d.ts +12 -0
- package/dist/components/download-trigger/download-trigger.js +25 -0
- package/dist/components/download-trigger/download-trigger.js.map +1 -0
- package/dist/components/download-trigger/index.d.cts +2 -0
- package/dist/components/download-trigger/index.d.ts +2 -0
- package/dist/components/drawer/drawer.cjs +4 -1
- package/dist/components/drawer/drawer.cjs.map +1 -1
- package/dist/components/drawer/drawer.d.cts +2 -2
- package/dist/components/drawer/drawer.d.ts +2 -2
- package/dist/components/drawer/drawer.js +4 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/figure/figure.cjs +45 -36
- package/dist/components/figure/figure.cjs.map +1 -1
- package/dist/components/figure/figure.js +45 -36
- package/dist/components/figure/figure.js.map +1 -1
- package/dist/components/image/image.cjs +41 -32
- package/dist/components/image/image.cjs.map +1 -1
- package/dist/components/image/image.js +41 -32
- package/dist/components/image/image.js.map +1 -1
- package/dist/components/menu/menu.cjs +4 -1
- package/dist/components/menu/menu.cjs.map +1 -1
- package/dist/components/menu/menu.d.cts +2 -2
- package/dist/components/menu/menu.d.ts +2 -2
- package/dist/components/menu/menu.js +4 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menubar/menubar.cjs +4 -1
- package/dist/components/menubar/menubar.cjs.map +1 -1
- package/dist/components/menubar/menubar.d.cts +2 -2
- package/dist/components/menubar/menubar.d.ts +2 -2
- package/dist/components/menubar/menubar.js +4 -1
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/navigation/navigation.cjs +3 -1
- package/dist/components/navigation/navigation.cjs.map +1 -1
- package/dist/components/navigation/navigation.js +3 -1
- package/dist/components/navigation/navigation.js.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.cjs +4 -1
- package/dist/components/navigation-menu/navigation-menu.cjs.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.d.cts +2 -2
- package/dist/components/navigation-menu/navigation-menu.d.ts +2 -2
- package/dist/components/navigation-menu/navigation-menu.js +4 -1
- package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
- package/dist/components/popover/popover.cjs +4 -1
- package/dist/components/popover/popover.cjs.map +1 -1
- package/dist/components/popover/popover.d.cts +2 -2
- package/dist/components/popover/popover.d.ts +2 -2
- package/dist/components/popover/popover.js +4 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/qr-code/index.d.cts +2 -0
- package/dist/components/qr-code/index.d.ts +2 -0
- package/dist/components/qr-code/qr-code.cjs +118 -0
- package/dist/components/qr-code/qr-code.cjs.map +1 -0
- package/dist/components/qr-code/qr-code.d.cts +17 -0
- package/dist/components/qr-code/qr-code.d.ts +17 -0
- package/dist/components/qr-code/qr-code.js +116 -0
- package/dist/components/qr-code/qr-code.js.map +1 -0
- package/dist/components/select/select.cjs +4 -1
- package/dist/components/select/select.cjs.map +1 -1
- package/dist/components/select/select.d.cts +2 -2
- package/dist/components/select/select.d.ts +2 -2
- package/dist/components/select/select.js +4 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/sidebar/sidebar.cjs +24 -17
- package/dist/components/sidebar/sidebar.cjs.map +1 -1
- package/dist/components/sidebar/sidebar.d.cts +4 -2
- package/dist/components/sidebar/sidebar.d.ts +4 -2
- package/dist/components/sidebar/sidebar.js +24 -17
- package/dist/components/sidebar/sidebar.js.map +1 -1
- package/dist/components/spacer/index.d.cts +2 -0
- package/dist/components/spacer/index.d.ts +2 -0
- package/dist/components/spacer/spacer.cjs +24 -0
- package/dist/components/spacer/spacer.cjs.map +1 -0
- package/dist/components/spacer/spacer.d.cts +10 -0
- package/dist/components/spacer/spacer.d.ts +10 -0
- package/dist/components/spacer/spacer.js +24 -0
- package/dist/components/spacer/spacer.js.map +1 -0
- package/dist/components/toast/toast.cjs +4 -1
- package/dist/components/toast/toast.cjs.map +1 -1
- package/dist/components/toast/toast.d.cts +1 -1
- package/dist/components/toast/toast.d.ts +1 -1
- package/dist/components/toast/toast.js +4 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/tooltip/tooltip.cjs +4 -1
- package/dist/components/tooltip/tooltip.cjs.map +1 -1
- package/dist/components/tooltip/tooltip.d.cts +2 -2
- package/dist/components/tooltip/tooltip.d.ts +2 -2
- package/dist/components/tooltip/tooltip.js +4 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -0
- package/dist/styled-system/recipes/carousel.cjs +48 -0
- package/dist/styled-system/recipes/carousel.cjs.map +1 -0
- package/dist/styled-system/recipes/carousel.js +48 -0
- package/dist/styled-system/recipes/carousel.js.map +1 -0
- package/dist/styled-system/recipes/code.cjs +4 -2
- package/dist/styled-system/recipes/code.cjs.map +1 -1
- package/dist/styled-system/recipes/code.js +4 -2
- package/dist/styled-system/recipes/code.js.map +1 -1
- package/dist/styled-system/recipes/color-swatch.cjs +37 -0
- package/dist/styled-system/recipes/color-swatch.cjs.map +1 -0
- package/dist/styled-system/recipes/color-swatch.js +37 -0
- package/dist/styled-system/recipes/color-swatch.js.map +1 -0
- package/dist/styled-system/recipes/command.cjs +3 -3
- package/dist/styled-system/recipes/command.cjs.map +1 -1
- package/dist/styled-system/recipes/command.js +3 -3
- package/dist/styled-system/recipes/command.js.map +1 -1
- package/dist/styled-system/recipes/download-trigger.cjs +39 -0
- package/dist/styled-system/recipes/download-trigger.cjs.map +1 -0
- package/dist/styled-system/recipes/download-trigger.js +39 -0
- package/dist/styled-system/recipes/download-trigger.js.map +1 -0
- package/dist/styled-system/recipes/figure.cjs +1 -0
- package/dist/styled-system/recipes/figure.cjs.map +1 -1
- package/dist/styled-system/recipes/figure.js +1 -0
- package/dist/styled-system/recipes/figure.js.map +1 -1
- package/dist/styled-system/recipes/image.cjs +1 -0
- package/dist/styled-system/recipes/image.cjs.map +1 -1
- package/dist/styled-system/recipes/image.js +1 -0
- package/dist/styled-system/recipes/image.js.map +1 -1
- package/dist/styled-system/recipes/layout-spacer.cjs +88 -0
- package/dist/styled-system/recipes/layout-spacer.cjs.map +1 -0
- package/dist/styled-system/recipes/layout-spacer.js +88 -0
- package/dist/styled-system/recipes/layout-spacer.js.map +1 -0
- package/dist/styled-system/recipes/qr-code.cjs +25 -0
- package/dist/styled-system/recipes/qr-code.cjs.map +1 -0
- package/dist/styled-system/recipes/qr-code.js +25 -0
- package/dist/styled-system/recipes/qr-code.js.map +1 -0
- package/dist/styles.css +662 -106
- package/dist/theme/theme-provider.cjs +46 -8
- package/dist/theme/theme-provider.cjs.map +1 -1
- package/dist/theme/theme-provider.js +46 -8
- package/dist/theme/theme-provider.js.map +1 -1
- package/dist/theme/theme-scope.cjs +21 -0
- package/dist/theme/theme-scope.cjs.map +1 -0
- package/dist/theme/theme-scope.js +19 -0
- package/dist/theme/theme-scope.js.map +1 -0
- package/package.json +10 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
const require_theme_scope = require("./theme-scope.cjs");
|
|
2
3
|
let react = require("react");
|
|
3
4
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
5
|
//#region src/theme/theme-provider.tsx
|
|
@@ -31,6 +32,8 @@ function initialSystemTheme(ssrTheme) {
|
|
|
31
32
|
const ThemeProvider = (0, react.forwardRef)(function ThemeProvider({ as = "div", children, defaultTheme = "light", onThemeChange, ssrTheme, style, theme, tokens, ...props }, ref) {
|
|
32
33
|
const [uncontrolledTheme, setUncontrolledTheme] = (0, react.useState)(defaultTheme);
|
|
33
34
|
const [systemTheme, setSystemTheme] = (0, react.useState)(() => initialSystemTheme(ssrTheme));
|
|
35
|
+
const [scopeElement, setScopeElement] = (0, react.useState)(null);
|
|
36
|
+
const [portalContainer, setPortalContainer] = (0, react.useState)(null);
|
|
34
37
|
const currentTheme = theme ?? uncontrolledTheme;
|
|
35
38
|
(0, react.useEffect)(() => {
|
|
36
39
|
if (currentTheme !== "system") return;
|
|
@@ -63,17 +66,52 @@ const ThemeProvider = (0, react.forwardRef)(function ThemeProvider({ as = "div",
|
|
|
63
66
|
...style,
|
|
64
67
|
...tokenStyles(tokens)
|
|
65
68
|
}), [style, tokens]);
|
|
69
|
+
const scopedTokenStyles = (0, react.useMemo)(() => tokenStyles(tokens), [tokens]);
|
|
66
70
|
const Root = as;
|
|
71
|
+
const setRootRef = (0, react.useCallback)((element) => {
|
|
72
|
+
setScopeElement((current) => current === element ? current : element);
|
|
73
|
+
if (typeof ref === "function") ref(element);
|
|
74
|
+
else if (ref) ref.current = element;
|
|
75
|
+
}, [ref]);
|
|
76
|
+
(0, react.useEffect)(() => {
|
|
77
|
+
if (!scopeElement || typeof document === "undefined") return;
|
|
78
|
+
const host = document.createElement("div");
|
|
79
|
+
host.dataset.jaciThemePortal = "true";
|
|
80
|
+
host.dataset.jaciComponent = "theme-portal";
|
|
81
|
+
host.dataset.slot = "theme-portal";
|
|
82
|
+
host.style.display = "contents";
|
|
83
|
+
document.body.append(host);
|
|
84
|
+
setPortalContainer(host);
|
|
85
|
+
return () => {
|
|
86
|
+
setPortalContainer((current) => current === host ? null : current);
|
|
87
|
+
host.remove();
|
|
88
|
+
};
|
|
89
|
+
}, [scopeElement]);
|
|
90
|
+
(0, react.useEffect)(() => {
|
|
91
|
+
if (!portalContainer) return;
|
|
92
|
+
portalContainer.dataset.jaciTheme = resolvedTheme;
|
|
93
|
+
for (const [property, value] of Object.entries(scopedTokenStyles)) portalContainer.style.setProperty(property, value);
|
|
94
|
+
return () => {
|
|
95
|
+
for (const property of Object.keys(scopedTokenStyles)) portalContainer.style.removeProperty(property);
|
|
96
|
+
};
|
|
97
|
+
}, [
|
|
98
|
+
portalContainer,
|
|
99
|
+
resolvedTheme,
|
|
100
|
+
scopedTokenStyles
|
|
101
|
+
]);
|
|
67
102
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeContext.Provider, {
|
|
68
103
|
value: contextValue,
|
|
69
|
-
children: (0,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_theme_scope.ThemeScopeContext.Provider, {
|
|
105
|
+
value: { container: portalContainer },
|
|
106
|
+
children: (0, react.createElement)(Root, {
|
|
107
|
+
...props,
|
|
108
|
+
"data-jaci-theme": resolvedTheme,
|
|
109
|
+
"data-jaci-component": "theme-provider",
|
|
110
|
+
"data-slot": "theme-provider",
|
|
111
|
+
ref: setRootRef,
|
|
112
|
+
style: mergedStyle
|
|
113
|
+
}, children)
|
|
114
|
+
})
|
|
77
115
|
});
|
|
78
116
|
});
|
|
79
117
|
function useTheme() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-provider.cjs","names":[],"sources":["../../src/theme/theme-provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n createElement,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, CSSProperties, ElementType, ReactNode, Ref } from \"react\";\n\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\n\n/** A leaf value accepted by the theme variable mapper. */\nexport type JaciThemeTokenValue = string | number;\n\n/**\n * Semantic theme values. The groups intentionally accept additional keys so\n * applications can extend the token vocabulary without waiting for a package\n * release. Known semantic groups are documented in the public README.\n */\nexport type JaciThemeTokenGroup = {\n readonly [key: string]: JaciThemeTokenValue | JaciThemeTokenGroup | undefined;\n};\n\nexport interface JaciThemeColorTokens extends JaciThemeTokenGroup {\n surface?: JaciThemeTokenGroup;\n fg?: JaciThemeTokenGroup;\n border?: JaciThemeTokenGroup;\n accent?: JaciThemeTokenGroup;\n success?: JaciThemeTokenValue;\n warning?: JaciThemeTokenValue;\n danger?: JaciThemeTokenValue;\n info?: JaciThemeTokenValue;\n link?: JaciThemeTokenGroup;\n focus?: JaciThemeTokenValue;\n disabled?: JaciThemeTokenValue;\n selected?: JaciThemeTokenValue;\n}\n\nexport interface JaciThemeTokens {\n colors?: JaciThemeColorTokens;\n radii?: JaciThemeTokenGroup;\n shadows?: JaciThemeTokenGroup;\n durations?: JaciThemeTokenGroup;\n easings?: JaciThemeTokenGroup;\n transitions?: JaciThemeTokenGroup;\n spacing?: JaciThemeTokenGroup;\n fontSizes?: JaciThemeTokenGroup;\n lineHeights?: JaciThemeTokenGroup;\n typography?: JaciThemeTokenGroup;\n textStyles?: JaciThemeTokenGroup;\n fonts?: JaciThemeTokenGroup;\n}\n\nexport interface ThemeProviderProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** The controlled color mode. */\n theme?: ThemeMode;\n /** The initial color mode for an uncontrolled provider. */\n defaultTheme?: ThemeMode;\n /** The deterministic mode used for `system` while rendering on the server. */\n ssrTheme?: \"light\" | \"dark\";\n /** Scoped semantic token overrides. */\n tokens?: JaciThemeTokens;\n /** Called when a controlled provider requests a mode change. */\n onThemeChange?: (theme: ThemeMode) => void;\n /** The element that owns the theme scope. */\n as?: ElementType;\n children?: ReactNode;\n}\n\nexport interface ThemeContextValue {\n theme: ThemeMode;\n resolvedTheme: \"light\" | \"dark\";\n setTheme: (theme: ThemeMode) => void;\n}\n\nconst defaultThemeContext: ThemeContextValue = {\n theme: \"light\",\n resolvedTheme: \"light\",\n setTheme: () => undefined,\n};\n\nconst ThemeContext = createContext<ThemeContextValue>(defaultThemeContext);\n\nfunction kebabCase(value: string) {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction flattenTokens(\n group: JaciThemeTokenGroup | undefined,\n path: string[],\n output: Record<string, string>,\n) {\n if (!group) return;\n\n for (const [key, value] of Object.entries(group)) {\n if (value === undefined) continue;\n const nextPath = [...path, kebabCase(key)];\n\n if (typeof value === \"object\") {\n flattenTokens(value, nextPath, output);\n } else {\n output[`--jaci-${nextPath.join(\"-\")}`] = String(value);\n }\n }\n}\n\nfunction tokenStyles(tokens: JaciThemeTokens | undefined): CSSProperties {\n if (!tokens) return {};\n\n const variables: Record<string, string> = {};\n for (const [group, values] of Object.entries(tokens)) {\n flattenTokens(values, [kebabCase(group)], variables);\n }\n\n return variables as CSSProperties;\n}\n\nfunction initialSystemTheme(ssrTheme: \"light\" | \"dark\" | undefined) {\n return ssrTheme ?? \"light\";\n}\n\nexport const ThemeProvider = forwardRef<HTMLElement, ThemeProviderProps>(function ThemeProvider(\n {\n as = \"div\",\n children,\n defaultTheme = \"light\",\n onThemeChange,\n ssrTheme,\n style,\n theme,\n tokens,\n ...props\n },\n ref,\n) {\n const [uncontrolledTheme, setUncontrolledTheme] = useState<ThemeMode>(defaultTheme);\n const [systemTheme, setSystemTheme] = useState<\"light\" | \"dark\">(() =>\n initialSystemTheme(ssrTheme),\n );\n const currentTheme = theme ?? uncontrolledTheme;\n\n useEffect(() => {\n if (currentTheme !== \"system\") return;\n\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n\n const media = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const update = () => setSystemTheme(media.matches ? \"dark\" : \"light\");\n update();\n if (typeof media.addEventListener === \"function\") media.addEventListener(\"change\", update);\n else media.addListener?.(update);\n\n return () => {\n if (typeof media.removeEventListener === \"function\")\n media.removeEventListener(\"change\", update);\n else media.removeListener?.(update);\n };\n }, [currentTheme]);\n\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n const setTheme = useCallback(\n (nextTheme: ThemeMode) => {\n if (theme === undefined) setUncontrolledTheme(nextTheme);\n onThemeChange?.(nextTheme);\n },\n [onThemeChange, theme],\n );\n const contextValue = useMemo(\n () => ({ theme: currentTheme, resolvedTheme, setTheme }),\n [currentTheme, resolvedTheme, setTheme],\n );\n const mergedStyle = useMemo(() => ({ ...style, ...tokenStyles(tokens) }), [style, tokens]);\n const Root = as;\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {createElement(\n Root,\n {\n ...props,\n \"data-jaci-theme\": resolvedTheme,\n \"data-jaci-component\": \"theme-provider\",\n \"data-slot\": \"theme-provider\",\n ref: ref as Ref<HTMLElement>,\n style: mergedStyle,\n },\n children,\n )}\n </ThemeContext.Provider>\n );\n});\n\nexport function useTheme() {\n return useContext(ThemeContext);\n}\n"],"mappings":";;;;AAsFA,MAAM,gBAAA,GAAA,MAAA,cAAA,CAAgD;CALpD,OAAO;CACP,eAAe;CACf,gBAAgB,KAAA;AAGsD,CAAC;AAEzE,SAAS,UAAU,OAAe;CAChC,OAAO,MACJ,QAAQ,sBAAsB,OAAO,CAAC,CACtC,QAAQ,WAAW,GAAG,CAAC,CACvB,YAAY;AACjB;AAEA,SAAS,cACP,OACA,MACA,QACA;CACA,IAAI,CAAC,OAAO;CAEZ,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,UAAU,KAAA,GAAW;EACzB,MAAM,WAAW,CAAC,GAAG,MAAM,UAAU,GAAG,CAAC;EAEzC,IAAI,OAAO,UAAU,UACnB,cAAc,OAAO,UAAU,MAAM;OAErC,OAAO,UAAU,SAAS,KAAK,GAAG,OAAO,OAAO,KAAK;CAEzD;AACF;AAEA,SAAS,YAAY,QAAoD;CACvE,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,MAAM,YAAoC,CAAC;CAC3C,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,MAAM,GACjD,cAAc,QAAQ,CAAC,UAAU,KAAK,CAAC,GAAG,SAAS;CAGrD,OAAO;AACT;AAEA,SAAS,mBAAmB,UAAwC;CAClE,OAAO,YAAY;AACrB;AAEA,MAAa,iBAAA,GAAA,MAAA,WAAA,CAA4D,SAAS,cAChF,EACE,KAAK,OACL,UACA,eAAe,SACf,eACA,UACA,OACA,OACA,QACA,GAAG,SAEL,KACA;CACA,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAA4C,YAAY;CAClF,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,OAClB,mBAAmB,QAAQ,CAC7B;CACA,MAAM,eAAe,SAAS;CAE9B,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,iBAAiB,UAAU;EAE/B,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;EAE9E,MAAM,QAAQ,OAAO,WAAW,8BAA8B;EAC9D,MAAM,eAAe,eAAe,MAAM,UAAU,SAAS,OAAO;EACpE,OAAO;EACP,IAAI,OAAO,MAAM,qBAAqB,YAAY,MAAM,iBAAiB,UAAU,MAAM;OACpF,MAAM,cAAc,MAAM;EAE/B,aAAa;GACX,IAAI,OAAO,MAAM,wBAAwB,YACvC,MAAM,oBAAoB,UAAU,MAAM;QACvC,MAAM,iBAAiB,MAAM;EACpC;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,gBAAgB,iBAAiB,WAAW,cAAc;CAChE,MAAM,YAAA,GAAA,MAAA,YAAA,EACH,cAAyB;EACxB,IAAI,UAAU,KAAA,GAAW,qBAAqB,SAAS;EACvD,gBAAgB,SAAS;CAC3B,GACA,CAAC,eAAe,KAAK,CACvB;CACA,MAAM,gBAAA,GAAA,MAAA,QAAA,QACG;EAAE,OAAO;EAAc;EAAe;CAAS,IACtD;EAAC;EAAc;EAAe;CAAQ,CACxC;CACA,MAAM,eAAA,GAAA,MAAA,QAAA,QAA6B;EAAE,GAAG;EAAO,GAAG,YAAY,MAAM;CAAE,IAAI,CAAC,OAAO,MAAM,CAAC;CACzF,MAAM,OAAO;CAEb,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAa,UAAd;EAAuB,OAAO;qCAE1B,MACA;GACE,GAAG;GACH,mBAAmB;GACnB,uBAAuB;GACvB,aAAa;GACR;GACL,OAAO;EACT,GACA,QACF;CACqB,CAAA;AAE3B,CAAC;AAED,SAAgB,WAAW;CACzB,QAAA,GAAA,MAAA,WAAA,CAAkB,YAAY;AAChC"}
|
|
1
|
+
{"version":3,"file":"theme-provider.cjs","names":["ThemeScopeContext"],"sources":["../../src/theme/theme-provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n createElement,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, CSSProperties, ElementType, ReactNode, Ref } from \"react\";\n\nimport { ThemeScopeContext } from \"./theme-scope\";\n\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\n\n/** A leaf value accepted by the theme variable mapper. */\nexport type JaciThemeTokenValue = string | number;\n\n/**\n * Semantic theme values. The groups intentionally accept additional keys so\n * applications can extend the token vocabulary without waiting for a package\n * release. Known semantic groups are documented in the public README.\n */\nexport type JaciThemeTokenGroup = {\n readonly [key: string]: JaciThemeTokenValue | JaciThemeTokenGroup | undefined;\n};\n\nexport interface JaciThemeColorTokens extends JaciThemeTokenGroup {\n surface?: JaciThemeTokenGroup;\n fg?: JaciThemeTokenGroup;\n border?: JaciThemeTokenGroup;\n accent?: JaciThemeTokenGroup;\n success?: JaciThemeTokenValue;\n warning?: JaciThemeTokenValue;\n danger?: JaciThemeTokenValue;\n info?: JaciThemeTokenValue;\n link?: JaciThemeTokenGroup;\n focus?: JaciThemeTokenValue;\n disabled?: JaciThemeTokenValue;\n selected?: JaciThemeTokenValue;\n}\n\nexport interface JaciThemeTokens {\n colors?: JaciThemeColorTokens;\n radii?: JaciThemeTokenGroup;\n shadows?: JaciThemeTokenGroup;\n durations?: JaciThemeTokenGroup;\n easings?: JaciThemeTokenGroup;\n transitions?: JaciThemeTokenGroup;\n spacing?: JaciThemeTokenGroup;\n fontSizes?: JaciThemeTokenGroup;\n lineHeights?: JaciThemeTokenGroup;\n typography?: JaciThemeTokenGroup;\n textStyles?: JaciThemeTokenGroup;\n fonts?: JaciThemeTokenGroup;\n}\n\nexport interface ThemeProviderProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** The controlled color mode. */\n theme?: ThemeMode;\n /** The initial color mode for an uncontrolled provider. */\n defaultTheme?: ThemeMode;\n /** The deterministic mode used for `system` while rendering on the server. */\n ssrTheme?: \"light\" | \"dark\";\n /** Scoped semantic token overrides. */\n tokens?: JaciThemeTokens;\n /** Called when a controlled provider requests a mode change. */\n onThemeChange?: (theme: ThemeMode) => void;\n /** The element that owns the theme scope. */\n as?: ElementType;\n children?: ReactNode;\n}\n\nexport interface ThemeContextValue {\n theme: ThemeMode;\n resolvedTheme: \"light\" | \"dark\";\n setTheme: (theme: ThemeMode) => void;\n}\n\nconst defaultThemeContext: ThemeContextValue = {\n theme: \"light\",\n resolvedTheme: \"light\",\n setTheme: () => undefined,\n};\n\nconst ThemeContext = createContext<ThemeContextValue>(defaultThemeContext);\n\nfunction kebabCase(value: string) {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction flattenTokens(\n group: JaciThemeTokenGroup | undefined,\n path: string[],\n output: Record<string, string>,\n) {\n if (!group) return;\n\n for (const [key, value] of Object.entries(group)) {\n if (value === undefined) continue;\n const nextPath = [...path, kebabCase(key)];\n\n if (typeof value === \"object\") {\n flattenTokens(value, nextPath, output);\n } else {\n output[`--jaci-${nextPath.join(\"-\")}`] = String(value);\n }\n }\n}\n\nfunction tokenStyles(tokens: JaciThemeTokens | undefined): CSSProperties {\n if (!tokens) return {};\n\n const variables: Record<string, string> = {};\n for (const [group, values] of Object.entries(tokens)) {\n flattenTokens(values, [kebabCase(group)], variables);\n }\n\n return variables as CSSProperties;\n}\n\nfunction initialSystemTheme(ssrTheme: \"light\" | \"dark\" | undefined) {\n return ssrTheme ?? \"light\";\n}\n\nexport const ThemeProvider = forwardRef<HTMLElement, ThemeProviderProps>(function ThemeProvider(\n {\n as = \"div\",\n children,\n defaultTheme = \"light\",\n onThemeChange,\n ssrTheme,\n style,\n theme,\n tokens,\n ...props\n },\n ref,\n) {\n const [uncontrolledTheme, setUncontrolledTheme] = useState<ThemeMode>(defaultTheme);\n const [systemTheme, setSystemTheme] = useState<\"light\" | \"dark\">(() =>\n initialSystemTheme(ssrTheme),\n );\n const [scopeElement, setScopeElement] = useState<HTMLElement | null>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const currentTheme = theme ?? uncontrolledTheme;\n\n useEffect(() => {\n if (currentTheme !== \"system\") return;\n\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n\n const media = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const update = () => setSystemTheme(media.matches ? \"dark\" : \"light\");\n update();\n if (typeof media.addEventListener === \"function\") media.addEventListener(\"change\", update);\n else media.addListener?.(update);\n\n return () => {\n if (typeof media.removeEventListener === \"function\")\n media.removeEventListener(\"change\", update);\n else media.removeListener?.(update);\n };\n }, [currentTheme]);\n\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n const setTheme = useCallback(\n (nextTheme: ThemeMode) => {\n if (theme === undefined) setUncontrolledTheme(nextTheme);\n onThemeChange?.(nextTheme);\n },\n [onThemeChange, theme],\n );\n const contextValue = useMemo(\n () => ({ theme: currentTheme, resolvedTheme, setTheme }),\n [currentTheme, resolvedTheme, setTheme],\n );\n const mergedStyle = useMemo(() => ({ ...style, ...tokenStyles(tokens) }), [style, tokens]);\n const scopedTokenStyles = useMemo(() => tokenStyles(tokens), [tokens]);\n const Root = as;\n const setRootRef = useCallback(\n (element: HTMLElement | null) => {\n setScopeElement((current) => (current === element ? current : element));\n if (typeof ref === \"function\") ref(element);\n else if (ref) (ref as { current: HTMLElement | null }).current = element;\n },\n [ref],\n );\n\n useEffect(() => {\n if (!scopeElement || typeof document === \"undefined\") return;\n\n const host = document.createElement(\"div\");\n host.dataset.jaciThemePortal = \"true\";\n host.dataset.jaciComponent = \"theme-portal\";\n host.dataset.slot = \"theme-portal\";\n // Keep the host out of the Storybook/app layout. Its descendants still\n // inherit the theme attribute and scoped custom properties.\n host.style.display = \"contents\";\n document.body.append(host);\n setPortalContainer(host);\n\n return () => {\n setPortalContainer((current) => (current === host ? null : current));\n host.remove();\n };\n }, [scopeElement]);\n\n useEffect(() => {\n if (!portalContainer) return;\n\n portalContainer.dataset.jaciTheme = resolvedTheme;\n for (const [property, value] of Object.entries(scopedTokenStyles)) {\n portalContainer.style.setProperty(property, value);\n }\n\n return () => {\n for (const property of Object.keys(scopedTokenStyles)) {\n portalContainer.style.removeProperty(property);\n }\n };\n }, [portalContainer, resolvedTheme, scopedTokenStyles]);\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <ThemeScopeContext.Provider value={{ container: portalContainer }}>\n {createElement(\n Root,\n {\n ...props,\n \"data-jaci-theme\": resolvedTheme,\n \"data-jaci-component\": \"theme-provider\",\n \"data-slot\": \"theme-provider\",\n ref: setRootRef as Ref<HTMLElement>,\n style: mergedStyle,\n },\n children,\n )}\n </ThemeScopeContext.Provider>\n </ThemeContext.Provider>\n );\n});\n\nexport function useTheme() {\n return useContext(ThemeContext);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { ThemeScopeContext } from "./theme-scope.js";
|
|
2
3
|
import { createContext, createElement, forwardRef, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
//#region src/theme/theme-provider.tsx
|
|
@@ -31,6 +32,8 @@ function initialSystemTheme(ssrTheme) {
|
|
|
31
32
|
const ThemeProvider = forwardRef(function ThemeProvider({ as = "div", children, defaultTheme = "light", onThemeChange, ssrTheme, style, theme, tokens, ...props }, ref) {
|
|
32
33
|
const [uncontrolledTheme, setUncontrolledTheme] = useState(defaultTheme);
|
|
33
34
|
const [systemTheme, setSystemTheme] = useState(() => initialSystemTheme(ssrTheme));
|
|
35
|
+
const [scopeElement, setScopeElement] = useState(null);
|
|
36
|
+
const [portalContainer, setPortalContainer] = useState(null);
|
|
34
37
|
const currentTheme = theme ?? uncontrolledTheme;
|
|
35
38
|
useEffect(() => {
|
|
36
39
|
if (currentTheme !== "system") return;
|
|
@@ -63,17 +66,52 @@ const ThemeProvider = forwardRef(function ThemeProvider({ as = "div", children,
|
|
|
63
66
|
...style,
|
|
64
67
|
...tokenStyles(tokens)
|
|
65
68
|
}), [style, tokens]);
|
|
69
|
+
const scopedTokenStyles = useMemo(() => tokenStyles(tokens), [tokens]);
|
|
66
70
|
const Root = as;
|
|
71
|
+
const setRootRef = useCallback((element) => {
|
|
72
|
+
setScopeElement((current) => current === element ? current : element);
|
|
73
|
+
if (typeof ref === "function") ref(element);
|
|
74
|
+
else if (ref) ref.current = element;
|
|
75
|
+
}, [ref]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!scopeElement || typeof document === "undefined") return;
|
|
78
|
+
const host = document.createElement("div");
|
|
79
|
+
host.dataset.jaciThemePortal = "true";
|
|
80
|
+
host.dataset.jaciComponent = "theme-portal";
|
|
81
|
+
host.dataset.slot = "theme-portal";
|
|
82
|
+
host.style.display = "contents";
|
|
83
|
+
document.body.append(host);
|
|
84
|
+
setPortalContainer(host);
|
|
85
|
+
return () => {
|
|
86
|
+
setPortalContainer((current) => current === host ? null : current);
|
|
87
|
+
host.remove();
|
|
88
|
+
};
|
|
89
|
+
}, [scopeElement]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!portalContainer) return;
|
|
92
|
+
portalContainer.dataset.jaciTheme = resolvedTheme;
|
|
93
|
+
for (const [property, value] of Object.entries(scopedTokenStyles)) portalContainer.style.setProperty(property, value);
|
|
94
|
+
return () => {
|
|
95
|
+
for (const property of Object.keys(scopedTokenStyles)) portalContainer.style.removeProperty(property);
|
|
96
|
+
};
|
|
97
|
+
}, [
|
|
98
|
+
portalContainer,
|
|
99
|
+
resolvedTheme,
|
|
100
|
+
scopedTokenStyles
|
|
101
|
+
]);
|
|
67
102
|
return /* @__PURE__ */ jsx(ThemeContext.Provider, {
|
|
68
103
|
value: contextValue,
|
|
69
|
-
children:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
children: /* @__PURE__ */ jsx(ThemeScopeContext.Provider, {
|
|
105
|
+
value: { container: portalContainer },
|
|
106
|
+
children: createElement(Root, {
|
|
107
|
+
...props,
|
|
108
|
+
"data-jaci-theme": resolvedTheme,
|
|
109
|
+
"data-jaci-component": "theme-provider",
|
|
110
|
+
"data-slot": "theme-provider",
|
|
111
|
+
ref: setRootRef,
|
|
112
|
+
style: mergedStyle
|
|
113
|
+
}, children)
|
|
114
|
+
})
|
|
77
115
|
});
|
|
78
116
|
});
|
|
79
117
|
function useTheme() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-provider.js","names":[],"sources":["../../src/theme/theme-provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n createElement,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, CSSProperties, ElementType, ReactNode, Ref } from \"react\";\n\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\n\n/** A leaf value accepted by the theme variable mapper. */\nexport type JaciThemeTokenValue = string | number;\n\n/**\n * Semantic theme values. The groups intentionally accept additional keys so\n * applications can extend the token vocabulary without waiting for a package\n * release. Known semantic groups are documented in the public README.\n */\nexport type JaciThemeTokenGroup = {\n readonly [key: string]: JaciThemeTokenValue | JaciThemeTokenGroup | undefined;\n};\n\nexport interface JaciThemeColorTokens extends JaciThemeTokenGroup {\n surface?: JaciThemeTokenGroup;\n fg?: JaciThemeTokenGroup;\n border?: JaciThemeTokenGroup;\n accent?: JaciThemeTokenGroup;\n success?: JaciThemeTokenValue;\n warning?: JaciThemeTokenValue;\n danger?: JaciThemeTokenValue;\n info?: JaciThemeTokenValue;\n link?: JaciThemeTokenGroup;\n focus?: JaciThemeTokenValue;\n disabled?: JaciThemeTokenValue;\n selected?: JaciThemeTokenValue;\n}\n\nexport interface JaciThemeTokens {\n colors?: JaciThemeColorTokens;\n radii?: JaciThemeTokenGroup;\n shadows?: JaciThemeTokenGroup;\n durations?: JaciThemeTokenGroup;\n easings?: JaciThemeTokenGroup;\n transitions?: JaciThemeTokenGroup;\n spacing?: JaciThemeTokenGroup;\n fontSizes?: JaciThemeTokenGroup;\n lineHeights?: JaciThemeTokenGroup;\n typography?: JaciThemeTokenGroup;\n textStyles?: JaciThemeTokenGroup;\n fonts?: JaciThemeTokenGroup;\n}\n\nexport interface ThemeProviderProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** The controlled color mode. */\n theme?: ThemeMode;\n /** The initial color mode for an uncontrolled provider. */\n defaultTheme?: ThemeMode;\n /** The deterministic mode used for `system` while rendering on the server. */\n ssrTheme?: \"light\" | \"dark\";\n /** Scoped semantic token overrides. */\n tokens?: JaciThemeTokens;\n /** Called when a controlled provider requests a mode change. */\n onThemeChange?: (theme: ThemeMode) => void;\n /** The element that owns the theme scope. */\n as?: ElementType;\n children?: ReactNode;\n}\n\nexport interface ThemeContextValue {\n theme: ThemeMode;\n resolvedTheme: \"light\" | \"dark\";\n setTheme: (theme: ThemeMode) => void;\n}\n\nconst defaultThemeContext: ThemeContextValue = {\n theme: \"light\",\n resolvedTheme: \"light\",\n setTheme: () => undefined,\n};\n\nconst ThemeContext = createContext<ThemeContextValue>(defaultThemeContext);\n\nfunction kebabCase(value: string) {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction flattenTokens(\n group: JaciThemeTokenGroup | undefined,\n path: string[],\n output: Record<string, string>,\n) {\n if (!group) return;\n\n for (const [key, value] of Object.entries(group)) {\n if (value === undefined) continue;\n const nextPath = [...path, kebabCase(key)];\n\n if (typeof value === \"object\") {\n flattenTokens(value, nextPath, output);\n } else {\n output[`--jaci-${nextPath.join(\"-\")}`] = String(value);\n }\n }\n}\n\nfunction tokenStyles(tokens: JaciThemeTokens | undefined): CSSProperties {\n if (!tokens) return {};\n\n const variables: Record<string, string> = {};\n for (const [group, values] of Object.entries(tokens)) {\n flattenTokens(values, [kebabCase(group)], variables);\n }\n\n return variables as CSSProperties;\n}\n\nfunction initialSystemTheme(ssrTheme: \"light\" | \"dark\" | undefined) {\n return ssrTheme ?? \"light\";\n}\n\nexport const ThemeProvider = forwardRef<HTMLElement, ThemeProviderProps>(function ThemeProvider(\n {\n as = \"div\",\n children,\n defaultTheme = \"light\",\n onThemeChange,\n ssrTheme,\n style,\n theme,\n tokens,\n ...props\n },\n ref,\n) {\n const [uncontrolledTheme, setUncontrolledTheme] = useState<ThemeMode>(defaultTheme);\n const [systemTheme, setSystemTheme] = useState<\"light\" | \"dark\">(() =>\n initialSystemTheme(ssrTheme),\n );\n const currentTheme = theme ?? uncontrolledTheme;\n\n useEffect(() => {\n if (currentTheme !== \"system\") return;\n\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n\n const media = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const update = () => setSystemTheme(media.matches ? \"dark\" : \"light\");\n update();\n if (typeof media.addEventListener === \"function\") media.addEventListener(\"change\", update);\n else media.addListener?.(update);\n\n return () => {\n if (typeof media.removeEventListener === \"function\")\n media.removeEventListener(\"change\", update);\n else media.removeListener?.(update);\n };\n }, [currentTheme]);\n\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n const setTheme = useCallback(\n (nextTheme: ThemeMode) => {\n if (theme === undefined) setUncontrolledTheme(nextTheme);\n onThemeChange?.(nextTheme);\n },\n [onThemeChange, theme],\n );\n const contextValue = useMemo(\n () => ({ theme: currentTheme, resolvedTheme, setTheme }),\n [currentTheme, resolvedTheme, setTheme],\n );\n const mergedStyle = useMemo(() => ({ ...style, ...tokenStyles(tokens) }), [style, tokens]);\n const Root = as;\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {createElement(\n Root,\n {\n ...props,\n \"data-jaci-theme\": resolvedTheme,\n \"data-jaci-component\": \"theme-provider\",\n \"data-slot\": \"theme-provider\",\n ref: ref as Ref<HTMLElement>,\n style: mergedStyle,\n },\n children,\n )}\n </ThemeContext.Provider>\n );\n});\n\nexport function useTheme() {\n return useContext(ThemeContext);\n}\n"],"mappings":";;;;AAsFA,MAAM,eAAe,cAAiC;CALpD,OAAO;CACP,eAAe;CACf,gBAAgB,KAAA;AAGsD,CAAC;AAEzE,SAAS,UAAU,OAAe;CAChC,OAAO,MACJ,QAAQ,sBAAsB,OAAO,CAAC,CACtC,QAAQ,WAAW,GAAG,CAAC,CACvB,YAAY;AACjB;AAEA,SAAS,cACP,OACA,MACA,QACA;CACA,IAAI,CAAC,OAAO;CAEZ,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,UAAU,KAAA,GAAW;EACzB,MAAM,WAAW,CAAC,GAAG,MAAM,UAAU,GAAG,CAAC;EAEzC,IAAI,OAAO,UAAU,UACnB,cAAc,OAAO,UAAU,MAAM;OAErC,OAAO,UAAU,SAAS,KAAK,GAAG,OAAO,OAAO,KAAK;CAEzD;AACF;AAEA,SAAS,YAAY,QAAoD;CACvE,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,MAAM,YAAoC,CAAC;CAC3C,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,MAAM,GACjD,cAAc,QAAQ,CAAC,UAAU,KAAK,CAAC,GAAG,SAAS;CAGrD,OAAO;AACT;AAEA,SAAS,mBAAmB,UAAwC;CAClE,OAAO,YAAY;AACrB;AAEA,MAAa,gBAAgB,WAA4C,SAAS,cAChF,EACE,KAAK,OACL,UACA,eAAe,SACf,eACA,UACA,OACA,OACA,QACA,GAAG,SAEL,KACA;CACA,MAAM,CAAC,mBAAmB,wBAAwB,SAAoB,YAAY;CAClF,MAAM,CAAC,aAAa,kBAAkB,eACpC,mBAAmB,QAAQ,CAC7B;CACA,MAAM,eAAe,SAAS;CAE9B,gBAAgB;EACd,IAAI,iBAAiB,UAAU;EAE/B,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;EAE9E,MAAM,QAAQ,OAAO,WAAW,8BAA8B;EAC9D,MAAM,eAAe,eAAe,MAAM,UAAU,SAAS,OAAO;EACpE,OAAO;EACP,IAAI,OAAO,MAAM,qBAAqB,YAAY,MAAM,iBAAiB,UAAU,MAAM;OACpF,MAAM,cAAc,MAAM;EAE/B,aAAa;GACX,IAAI,OAAO,MAAM,wBAAwB,YACvC,MAAM,oBAAoB,UAAU,MAAM;QACvC,MAAM,iBAAiB,MAAM;EACpC;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,gBAAgB,iBAAiB,WAAW,cAAc;CAChE,MAAM,WAAW,aACd,cAAyB;EACxB,IAAI,UAAU,KAAA,GAAW,qBAAqB,SAAS;EACvD,gBAAgB,SAAS;CAC3B,GACA,CAAC,eAAe,KAAK,CACvB;CACA,MAAM,eAAe,eACZ;EAAE,OAAO;EAAc;EAAe;CAAS,IACtD;EAAC;EAAc;EAAe;CAAQ,CACxC;CACA,MAAM,cAAc,eAAe;EAAE,GAAG;EAAO,GAAG,YAAY,MAAM;CAAE,IAAI,CAAC,OAAO,MAAM,CAAC;CACzF,MAAM,OAAO;CAEb,OACE,oBAAC,aAAa,UAAd;EAAuB,OAAO;YAC3B,cACC,MACA;GACE,GAAG;GACH,mBAAmB;GACnB,uBAAuB;GACvB,aAAa;GACR;GACL,OAAO;EACT,GACA,QACF;CACqB,CAAA;AAE3B,CAAC;AAED,SAAgB,WAAW;CACzB,OAAO,WAAW,YAAY;AAChC"}
|
|
1
|
+
{"version":3,"file":"theme-provider.js","names":[],"sources":["../../src/theme/theme-provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n createElement,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, CSSProperties, ElementType, ReactNode, Ref } from \"react\";\n\nimport { ThemeScopeContext } from \"./theme-scope\";\n\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\n\n/** A leaf value accepted by the theme variable mapper. */\nexport type JaciThemeTokenValue = string | number;\n\n/**\n * Semantic theme values. The groups intentionally accept additional keys so\n * applications can extend the token vocabulary without waiting for a package\n * release. Known semantic groups are documented in the public README.\n */\nexport type JaciThemeTokenGroup = {\n readonly [key: string]: JaciThemeTokenValue | JaciThemeTokenGroup | undefined;\n};\n\nexport interface JaciThemeColorTokens extends JaciThemeTokenGroup {\n surface?: JaciThemeTokenGroup;\n fg?: JaciThemeTokenGroup;\n border?: JaciThemeTokenGroup;\n accent?: JaciThemeTokenGroup;\n success?: JaciThemeTokenValue;\n warning?: JaciThemeTokenValue;\n danger?: JaciThemeTokenValue;\n info?: JaciThemeTokenValue;\n link?: JaciThemeTokenGroup;\n focus?: JaciThemeTokenValue;\n disabled?: JaciThemeTokenValue;\n selected?: JaciThemeTokenValue;\n}\n\nexport interface JaciThemeTokens {\n colors?: JaciThemeColorTokens;\n radii?: JaciThemeTokenGroup;\n shadows?: JaciThemeTokenGroup;\n durations?: JaciThemeTokenGroup;\n easings?: JaciThemeTokenGroup;\n transitions?: JaciThemeTokenGroup;\n spacing?: JaciThemeTokenGroup;\n fontSizes?: JaciThemeTokenGroup;\n lineHeights?: JaciThemeTokenGroup;\n typography?: JaciThemeTokenGroup;\n textStyles?: JaciThemeTokenGroup;\n fonts?: JaciThemeTokenGroup;\n}\n\nexport interface ThemeProviderProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** The controlled color mode. */\n theme?: ThemeMode;\n /** The initial color mode for an uncontrolled provider. */\n defaultTheme?: ThemeMode;\n /** The deterministic mode used for `system` while rendering on the server. */\n ssrTheme?: \"light\" | \"dark\";\n /** Scoped semantic token overrides. */\n tokens?: JaciThemeTokens;\n /** Called when a controlled provider requests a mode change. */\n onThemeChange?: (theme: ThemeMode) => void;\n /** The element that owns the theme scope. */\n as?: ElementType;\n children?: ReactNode;\n}\n\nexport interface ThemeContextValue {\n theme: ThemeMode;\n resolvedTheme: \"light\" | \"dark\";\n setTheme: (theme: ThemeMode) => void;\n}\n\nconst defaultThemeContext: ThemeContextValue = {\n theme: \"light\",\n resolvedTheme: \"light\",\n setTheme: () => undefined,\n};\n\nconst ThemeContext = createContext<ThemeContextValue>(defaultThemeContext);\n\nfunction kebabCase(value: string) {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction flattenTokens(\n group: JaciThemeTokenGroup | undefined,\n path: string[],\n output: Record<string, string>,\n) {\n if (!group) return;\n\n for (const [key, value] of Object.entries(group)) {\n if (value === undefined) continue;\n const nextPath = [...path, kebabCase(key)];\n\n if (typeof value === \"object\") {\n flattenTokens(value, nextPath, output);\n } else {\n output[`--jaci-${nextPath.join(\"-\")}`] = String(value);\n }\n }\n}\n\nfunction tokenStyles(tokens: JaciThemeTokens | undefined): CSSProperties {\n if (!tokens) return {};\n\n const variables: Record<string, string> = {};\n for (const [group, values] of Object.entries(tokens)) {\n flattenTokens(values, [kebabCase(group)], variables);\n }\n\n return variables as CSSProperties;\n}\n\nfunction initialSystemTheme(ssrTheme: \"light\" | \"dark\" | undefined) {\n return ssrTheme ?? \"light\";\n}\n\nexport const ThemeProvider = forwardRef<HTMLElement, ThemeProviderProps>(function ThemeProvider(\n {\n as = \"div\",\n children,\n defaultTheme = \"light\",\n onThemeChange,\n ssrTheme,\n style,\n theme,\n tokens,\n ...props\n },\n ref,\n) {\n const [uncontrolledTheme, setUncontrolledTheme] = useState<ThemeMode>(defaultTheme);\n const [systemTheme, setSystemTheme] = useState<\"light\" | \"dark\">(() =>\n initialSystemTheme(ssrTheme),\n );\n const [scopeElement, setScopeElement] = useState<HTMLElement | null>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const currentTheme = theme ?? uncontrolledTheme;\n\n useEffect(() => {\n if (currentTheme !== \"system\") return;\n\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n\n const media = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const update = () => setSystemTheme(media.matches ? \"dark\" : \"light\");\n update();\n if (typeof media.addEventListener === \"function\") media.addEventListener(\"change\", update);\n else media.addListener?.(update);\n\n return () => {\n if (typeof media.removeEventListener === \"function\")\n media.removeEventListener(\"change\", update);\n else media.removeListener?.(update);\n };\n }, [currentTheme]);\n\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n const setTheme = useCallback(\n (nextTheme: ThemeMode) => {\n if (theme === undefined) setUncontrolledTheme(nextTheme);\n onThemeChange?.(nextTheme);\n },\n [onThemeChange, theme],\n );\n const contextValue = useMemo(\n () => ({ theme: currentTheme, resolvedTheme, setTheme }),\n [currentTheme, resolvedTheme, setTheme],\n );\n const mergedStyle = useMemo(() => ({ ...style, ...tokenStyles(tokens) }), [style, tokens]);\n const scopedTokenStyles = useMemo(() => tokenStyles(tokens), [tokens]);\n const Root = as;\n const setRootRef = useCallback(\n (element: HTMLElement | null) => {\n setScopeElement((current) => (current === element ? current : element));\n if (typeof ref === \"function\") ref(element);\n else if (ref) (ref as { current: HTMLElement | null }).current = element;\n },\n [ref],\n );\n\n useEffect(() => {\n if (!scopeElement || typeof document === \"undefined\") return;\n\n const host = document.createElement(\"div\");\n host.dataset.jaciThemePortal = \"true\";\n host.dataset.jaciComponent = \"theme-portal\";\n host.dataset.slot = \"theme-portal\";\n // Keep the host out of the Storybook/app layout. Its descendants still\n // inherit the theme attribute and scoped custom properties.\n host.style.display = \"contents\";\n document.body.append(host);\n setPortalContainer(host);\n\n return () => {\n setPortalContainer((current) => (current === host ? null : current));\n host.remove();\n };\n }, [scopeElement]);\n\n useEffect(() => {\n if (!portalContainer) return;\n\n portalContainer.dataset.jaciTheme = resolvedTheme;\n for (const [property, value] of Object.entries(scopedTokenStyles)) {\n portalContainer.style.setProperty(property, value);\n }\n\n return () => {\n for (const property of Object.keys(scopedTokenStyles)) {\n portalContainer.style.removeProperty(property);\n }\n };\n }, [portalContainer, resolvedTheme, scopedTokenStyles]);\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <ThemeScopeContext.Provider value={{ container: portalContainer }}>\n {createElement(\n Root,\n {\n ...props,\n \"data-jaci-theme\": resolvedTheme,\n \"data-jaci-component\": \"theme-provider\",\n \"data-slot\": \"theme-provider\",\n ref: setRootRef as Ref<HTMLElement>,\n style: mergedStyle,\n },\n children,\n )}\n </ThemeScopeContext.Provider>\n </ThemeContext.Provider>\n );\n});\n\nexport function useTheme() {\n return useContext(ThemeContext);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
let react = require("react");
|
|
3
|
+
//#region src/theme/theme-scope.ts
|
|
4
|
+
const ThemeScopeContext = (0, react.createContext)({ container: null });
|
|
5
|
+
function useThemePortalContainer() {
|
|
6
|
+
return (0, react.useContext)(ThemeScopeContext).container;
|
|
7
|
+
}
|
|
8
|
+
function useThemePortalProps(props) {
|
|
9
|
+
const scopedContainer = useThemePortalContainer();
|
|
10
|
+
if (props.container !== void 0 || scopedContainer === null) return props;
|
|
11
|
+
return {
|
|
12
|
+
...props,
|
|
13
|
+
container: scopedContainer
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.ThemeScopeContext = ThemeScopeContext;
|
|
18
|
+
exports.useThemePortalContainer = useThemePortalContainer;
|
|
19
|
+
exports.useThemePortalProps = useThemePortalProps;
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=theme-scope.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-scope.cjs","names":[],"sources":["../../src/theme/theme-scope.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type { RefObject } from \"react\";\n\nexport type ThemePortalContainer =\n | HTMLElement\n | ShadowRoot\n | null\n | RefObject<HTMLElement | ShadowRoot | null>;\n\nexport interface ThemeScopeValue {\n container: HTMLElement | null;\n}\n\nexport const ThemeScopeContext = createContext<ThemeScopeValue>({ container: null });\n\nexport function useThemePortalContainer() {\n return useContext(ThemeScopeContext).container;\n}\n\nexport function useThemePortalProps<T extends { container?: ThemePortalContainer | undefined }>(\n props: T,\n): T {\n const scopedContainer = useThemePortalContainer();\n\n if (props.container !== undefined || scopedContainer === null) return props;\n\n return { ...props, container: scopedContainer };\n}\n"],"mappings":";;;AAeA,MAAa,qBAAA,GAAA,MAAA,cAAA,CAAmD,EAAE,WAAW,KAAK,CAAC;AAEnF,SAAgB,0BAA0B;CACxC,QAAA,GAAA,MAAA,WAAA,CAAkB,iBAAiB,CAAC,CAAC;AACvC;AAEA,SAAgB,oBACd,OACG;CACH,MAAM,kBAAkB,wBAAwB;CAEhD,IAAI,MAAM,cAAc,KAAA,KAAa,oBAAoB,MAAM,OAAO;CAEtE,OAAO;EAAE,GAAG;EAAO,WAAW;CAAgB;AAChD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
//#region src/theme/theme-scope.ts
|
|
4
|
+
const ThemeScopeContext = createContext({ container: null });
|
|
5
|
+
function useThemePortalContainer() {
|
|
6
|
+
return useContext(ThemeScopeContext).container;
|
|
7
|
+
}
|
|
8
|
+
function useThemePortalProps(props) {
|
|
9
|
+
const scopedContainer = useThemePortalContainer();
|
|
10
|
+
if (props.container !== void 0 || scopedContainer === null) return props;
|
|
11
|
+
return {
|
|
12
|
+
...props,
|
|
13
|
+
container: scopedContainer
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { ThemeScopeContext, useThemePortalContainer, useThemePortalProps };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=theme-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-scope.js","names":[],"sources":["../../src/theme/theme-scope.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type { RefObject } from \"react\";\n\nexport type ThemePortalContainer =\n | HTMLElement\n | ShadowRoot\n | null\n | RefObject<HTMLElement | ShadowRoot | null>;\n\nexport interface ThemeScopeValue {\n container: HTMLElement | null;\n}\n\nexport const ThemeScopeContext = createContext<ThemeScopeValue>({ container: null });\n\nexport function useThemePortalContainer() {\n return useContext(ThemeScopeContext).container;\n}\n\nexport function useThemePortalProps<T extends { container?: ThemePortalContainer | undefined }>(\n props: T,\n): T {\n const scopedContainer = useThemePortalContainer();\n\n if (props.container !== undefined || scopedContainer === null) return props;\n\n return { ...props, container: scopedContainer };\n}\n"],"mappings":";;;AAeA,MAAa,oBAAoB,cAA+B,EAAE,WAAW,KAAK,CAAC;AAEnF,SAAgB,0BAA0B;CACxC,OAAO,WAAW,iBAAiB,CAAC,CAAC;AACvC;AAEA,SAAgB,oBACd,OACG;CACH,MAAM,kBAAkB,wBAAwB;CAEhD,IAAI,MAAM,cAAc,KAAA,KAAa,oBAAoB,MAAM,OAAO;CAEtE,OAAO;EAAE,GAAG;EAAO,WAAW;CAAgB;AAChD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaci-ui",
|
|
3
3
|
"description": "Accessible, themeable React components by Jaci UI",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Richard Borges",
|
|
@@ -79,13 +79,15 @@
|
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
81
|
"@base-ui/react": "^1.6.0",
|
|
82
|
-
"date-fns": "^4.1.0"
|
|
82
|
+
"date-fns": "^4.1.0",
|
|
83
|
+
"qrcode": "^1.5.4"
|
|
83
84
|
},
|
|
84
85
|
"publishConfig": {
|
|
85
86
|
"access": "public"
|
|
86
87
|
},
|
|
87
88
|
"devDependencies": {
|
|
88
89
|
"@pandacss/dev": "^1.11.4",
|
|
90
|
+
"@types/qrcode": "^1.5.6",
|
|
89
91
|
"@types/react": "^19.2.17",
|
|
90
92
|
"@types/react-dom": "^19.2.3",
|
|
91
93
|
"jsdom": "^27.4.0",
|
|
@@ -97,15 +99,18 @@
|
|
|
97
99
|
"clean": "rimraf dist src/styled-system",
|
|
98
100
|
"panda:codegen": "panda codegen --clean --config panda.config.ts",
|
|
99
101
|
"panda:css": "panda cssgen --config panda.config.ts --outfile dist/styles.css",
|
|
100
|
-
"
|
|
102
|
+
"ensure:sourcemaps": "node scripts/ensure-entry-sourcemaps.mjs",
|
|
103
|
+
"build": "pnpm panda:codegen && tsdown && pnpm ensure:sourcemaps && pnpm panda:css && pnpm verify:client-boundaries",
|
|
101
104
|
"dev": "pnpm panda:codegen && tsdown --watch",
|
|
102
|
-
"lint": "biome
|
|
105
|
+
"lint": "biome check --assist-enabled=false src scripts panda.config.ts tsdown.config.ts",
|
|
103
106
|
"format": "biome format --write src panda.config.ts tsdown.config.ts",
|
|
104
107
|
"format:check": "biome format src panda.config.ts tsdown.config.ts",
|
|
105
108
|
"typecheck": "pnpm panda:codegen && tsc --noEmit",
|
|
106
109
|
"test": "pnpm panda:codegen && vitest run",
|
|
107
110
|
"test:watch": "pnpm panda:codegen && vitest",
|
|
108
111
|
"verify:client-boundaries": "node scripts/verify-client-boundaries.mjs",
|
|
109
|
-
"package:check": "pnpm build &&
|
|
112
|
+
"package:check": "pnpm build && pnpm performance:check && pnpm package:contract",
|
|
113
|
+
"package:contract": "node scripts/package-check.mjs",
|
|
114
|
+
"performance:check": "node scripts/performance-check.mjs"
|
|
110
115
|
}
|
|
111
116
|
}
|