jaci-ui 0.9.4 → 1.0.2
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 +25 -0
- package/README.md +11 -1
- package/dist/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/components/accordion/accordion.cjs.map +1 -1
- package/dist/components/accordion/accordion.js.map +1 -1
- package/dist/components/alert/alert.cjs.map +1 -1
- package/dist/components/alert/alert.js.map +1 -1
- package/dist/components/alert-dialog/alert-dialog.cjs.map +1 -1
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/aspect-ratio/aspect-ratio.cjs.map +1 -1
- package/dist/components/avatar/avatar.cjs.map +1 -1
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/breadcrumbs/breadcrumbs.cjs.map +1 -1
- package/dist/components/button/button.cjs +1 -0
- package/dist/components/button/button.cjs.map +1 -1
- package/dist/components/button/button.d.cts +2 -1
- package/dist/components/button/button.d.ts +2 -1
- package/dist/components/button/button.js +1 -0
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button-group/button-group.cjs.map +1 -1
- package/dist/components/calendar/calendar.cjs +4 -6
- package/dist/components/calendar/calendar.cjs.map +1 -1
- package/dist/components/calendar/calendar.js +4 -6
- package/dist/components/calendar/calendar.js.map +1 -1
- package/dist/components/card/card.cjs.map +1 -1
- package/dist/components/carousel/carousel.cjs.map +1 -1
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.cjs +7 -3
- package/dist/components/checkbox-group/checkbox-group.cjs.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.js +7 -3
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/code/code.cjs.map +1 -1
- package/dist/components/code/code.js.map +1 -1
- package/dist/components/collapsible/collapsible.cjs.map +1 -1
- package/dist/components/collapsible/collapsible.js.map +1 -1
- package/dist/components/color-picker/color-picker.cjs.map +1 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-picker/color-utils.cjs +5 -3
- package/dist/components/color-picker/color-utils.cjs.map +1 -1
- package/dist/components/color-picker/color-utils.js +5 -3
- package/dist/components/color-picker/color-utils.js.map +1 -1
- package/dist/components/color-swatch/color-swatch.cjs.map +1 -1
- package/dist/components/combobox/combobox.cjs +2 -1
- package/dist/components/combobox/combobox.cjs.map +1 -1
- package/dist/components/combobox/combobox.js +2 -1
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.cjs.map +1 -1
- package/dist/components/command/command.js.map +1 -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/controls/checkbox.cjs.map +1 -1
- package/dist/components/controls/checkbox.js.map +1 -1
- package/dist/components/controls/input.cjs.map +1 -1
- package/dist/components/controls/input.js.map +1 -1
- package/dist/components/controls/radio.cjs.map +1 -1
- package/dist/components/controls/switch.cjs.map +1 -1
- package/dist/components/controls/switch.js.map +1 -1
- package/dist/components/controls/textarea.cjs.map +1 -1
- package/dist/components/controls/textarea.js.map +1 -1
- package/dist/components/copyable/copyable.cjs.map +1 -1
- package/dist/components/copyable/copyable.js.map +1 -1
- package/dist/components/data-toolbar/data-toolbar.cjs.map +1 -1
- package/dist/components/data-toolbar/data-toolbar.js.map +1 -1
- package/dist/components/data-view/data-view.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +4 -7
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.js +4 -7
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.cjs +4 -6
- package/dist/components/date-range-picker/date-range-picker.cjs.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +4 -6
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/dialog/dialog.cjs.map +1 -1
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/download-trigger/download-trigger.cjs.map +1 -1
- package/dist/components/drawer/drawer.cjs.map +1 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/empty-state/empty-state.cjs.map +1 -1
- package/dist/components/feedback/badge.cjs.map +1 -1
- package/dist/components/field/field.cjs.map +1 -1
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/fieldset/fieldset.cjs.map +1 -1
- package/dist/components/figure/figure.cjs.map +1 -1
- package/dist/components/figure/figure.js.map +1 -1
- package/dist/components/form/form.cjs.map +1 -1
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/icon-button/icon-button.cjs.map +1 -1
- package/dist/components/icon-button/icon-button.js.map +1 -1
- package/dist/components/image/image.cjs.map +1 -1
- package/dist/components/image/image.js.map +1 -1
- package/dist/components/input-group/input-group.cjs.map +1 -1
- package/dist/components/kbd/kbd.cjs.map +1 -1
- package/dist/components/layout/index.cjs.map +1 -1
- package/dist/components/list/list.cjs.map +1 -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/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.map +1 -1
- package/dist/components/meter/meter.cjs.map +1 -1
- package/dist/components/meter/meter.js.map +1 -1
- package/dist/components/navigation/navigation.cjs.map +1 -1
- package/dist/components/navigation/navigation.js.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.cjs.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
- package/dist/components/number-field/number-field.cjs +2 -1
- package/dist/components/number-field/number-field.cjs.map +1 -1
- package/dist/components/number-field/number-field.js +2 -1
- package/dist/components/number-field/number-field.js.map +1 -1
- package/dist/components/option-selector/option-selector.cjs.map +1 -1
- package/dist/components/option-selector/option-selector.js.map +1 -1
- package/dist/components/pagination/pagination.cjs.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pin-input/pin-input.cjs.map +1 -1
- package/dist/components/pin-input/pin-input.js.map +1 -1
- package/dist/components/popover/popover.cjs.map +1 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/progress/progress.cjs.map +1 -1
- package/dist/components/progress/progress.js.map +1 -1
- package/dist/components/qr-code/qr-code.cjs.map +1 -1
- package/dist/components/qr-code/qr-code.js.map +1 -1
- package/dist/components/quote/quote.cjs.map +1 -1
- package/dist/components/quote/quote.js.map +1 -1
- package/dist/components/radio-group/radio-group.cjs +7 -3
- package/dist/components/radio-group/radio-group.cjs.map +1 -1
- package/dist/components/radio-group/radio-group.js +7 -3
- package/dist/components/radio-group/radio-group.js.map +1 -1
- package/dist/components/range-slider/range-slider.cjs.map +1 -1
- package/dist/components/range-slider/range-slider.js.map +1 -1
- package/dist/components/scroll-area/scroll-area.cjs.map +1 -1
- package/dist/components/select/select.cjs.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/sidebar/sidebar.cjs.map +1 -1
- package/dist/components/sidebar/sidebar.js.map +1 -1
- package/dist/components/skeleton/skeleton.cjs.map +1 -1
- package/dist/components/slider/slider.cjs.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/spacer/spacer.cjs.map +1 -1
- package/dist/components/stat/stat.cjs.map +1 -1
- package/dist/components/stat/stat.js.map +1 -1
- package/dist/components/stepper/stepper.cjs +2 -1
- package/dist/components/stepper/stepper.cjs.map +1 -1
- package/dist/components/stepper/stepper.js +2 -1
- package/dist/components/stepper/stepper.js.map +1 -1
- package/dist/components/table/table.cjs.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/tabs/tabs.cjs.map +1 -1
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tags-input/tags-input.cjs +10 -9
- package/dist/components/tags-input/tags-input.cjs.map +1 -1
- package/dist/components/tags-input/tags-input.js +10 -9
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/toast/toast.cjs.map +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toggle/toggle.cjs.map +1 -1
- package/dist/components/toggle-group/toggle-group.cjs.map +1 -1
- package/dist/components/toolbar/toolbar.cjs.map +1 -1
- package/dist/components/tooltip/tooltip.cjs.map +1 -1
- package/dist/components/tree-view/tree-view.cjs.map +1 -1
- package/dist/components/tree-view/tree-view.js.map +1 -1
- package/dist/components/typography/heading.cjs.map +1 -1
- package/dist/components/typography/link.cjs.map +1 -1
- package/dist/components/typography/paragraph.cjs.map +1 -1
- package/dist/components/typography/text.cjs.map +1 -1
- package/dist/components/upload/upload.cjs +2 -2
- package/dist/components/upload/upload.cjs.map +1 -1
- package/dist/components/upload/upload.js +2 -2
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/components/visually-hidden/visually-hidden.cjs.map +1 -1
- package/dist/panda-preset.cjs.map +1 -1
- package/dist/styles/theme.cjs +18 -18
- package/dist/styles/theme.cjs.map +1 -1
- package/dist/styles/theme.js +18 -18
- package/dist/styles/theme.js.map +1 -1
- package/dist/styles.css +12 -21
- package/dist/theme/theme-provider.cjs.map +1 -1
- package/dist/theme/theme-provider.js.map +1 -1
- package/dist/theme/theme-scope.cjs.map +1 -1
- package/package.json +9 -9
|
@@ -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\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":";;;;;AAwFA,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,CAAC,cAAc,mBAAmB,SAA6B,IAAI;CACzE,MAAM,CAAC,iBAAiB,sBAAsB,SAA6B,IAAI;CAC/E,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,oBAAoB,cAAc,YAAY,MAAM,GAAG,CAAC,MAAM,CAAC;CACrE,MAAM,OAAO;CACb,MAAM,aAAa,aAChB,YAAgC;EAC/B,iBAAiB,YAAa,YAAY,UAAU,UAAU,OAAQ;EACtE,IAAI,OAAO,QAAQ,YAAY,IAAI,OAAO;OACrC,IAAI,KAAK,IAAyC,UAAU;CACnE,GACA,CAAC,GAAG,CACN;CAEA,gBAAgB;EACd,IAAI,CAAC,gBAAgB,OAAO,aAAa,aAAa;EAEtD,MAAM,OAAO,SAAS,cAAc,KAAK;EACzC,KAAK,QAAQ,kBAAkB;EAC/B,KAAK,QAAQ,gBAAgB;EAC7B,KAAK,QAAQ,OAAO;EAGpB,KAAK,MAAM,UAAU;EACrB,SAAS,KAAK,OAAO,IAAI;EACzB,mBAAmB,IAAI;EAEvB,aAAa;GACX,oBAAoB,YAAa,YAAY,OAAO,OAAO,OAAQ;GACnE,KAAK,OAAO;EACd;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,gBAAgB;EACd,IAAI,CAAC,iBAAiB;EAEtB,gBAAgB,QAAQ,YAAY;EACpC,KAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,iBAAiB,GAC9D,gBAAgB,MAAM,YAAY,UAAU,KAAK;EAGnD,aAAa;GACX,KAAK,MAAM,YAAY,OAAO,KAAK,iBAAiB,GAClD,gBAAgB,MAAM,eAAe,QAAQ;EAEjD;CACF,GAAG;EAAC;EAAiB;EAAe;CAAiB,CAAC;CAEtD,OACE,oBAAC,aAAa,UAAd;EAAuB,OAAO;YAC5B,oBAAC,kBAAkB,UAAnB;GAA4B,OAAO,EAAE,WAAW,gBAAgB;aAC7D,cACC,MACA;IACE,GAAG;IACH,mBAAmB;IACnB,uBAAuB;IACvB,aAAa;IACb,KAAK;IACL,OAAO;GACT,GACA,QACF;EAC0B,CAAA;CACP,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":";;;;;AAwFA,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,CAAC,cAAc,mBAAmB,SAA6B,IAAI;CACzE,MAAM,CAAC,iBAAiB,sBAAsB,SAA6B,IAAI;CAC/E,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,oBAAoB,cAAc,YAAY,MAAM,GAAG,CAAC,MAAM,CAAC;CACrE,MAAM,OAAO;CACb,MAAM,aAAa,aAChB,YAAgC;EAC/B,iBAAiB,YAAa,YAAY,UAAU,UAAU,OAAQ;EACtE,IAAI,OAAO,QAAQ,YAAY,IAAI,OAAO;OACrC,IAAI,KAAK,IAAyC,UAAU;CACnE,GACA,CAAC,GAAG,CACN;CAEA,gBAAgB;EACd,IAAI,CAAC,gBAAgB,OAAO,aAAa,aAAa;EAEtD,MAAM,OAAO,SAAS,cAAc,KAAK;EACzC,KAAK,QAAQ,kBAAkB;EAC/B,KAAK,QAAQ,gBAAgB;EAC7B,KAAK,QAAQ,OAAO;EAGpB,KAAK,MAAM,UAAU;EACrB,SAAS,KAAK,OAAO,IAAI;EACzB,mBAAmB,IAAI;EAEvB,aAAa;GACX,oBAAoB,YAAa,YAAY,OAAO,OAAO,OAAQ;GACnE,KAAK,OAAO;EACd;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,gBAAgB;EACd,IAAI,CAAC,iBAAiB;EAEtB,gBAAgB,QAAQ,YAAY;EACpC,KAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,iBAAiB,GAC9D,gBAAgB,MAAM,YAAY,UAAU,KAAK;EAGnD,aAAa;GACX,KAAK,MAAM,YAAY,OAAO,KAAK,iBAAiB,GAClD,gBAAgB,MAAM,eAAe,QAAQ;EAEjD;CACF,GAAG;EAAC;EAAiB;EAAe;CAAiB,CAAC;CAEtD,OACE,oBAAC,aAAa,UAAd;EAAuB,OAAO;EAC5B,UAAA,oBAAC,kBAAkB,UAAnB;GAA4B,OAAO,EAAE,WAAW,gBAAgB;GAC7D,UAAA,cACC,MACA;IACE,GAAG;IACH,mBAAmB;IACnB,uBAAuB;IACvB,aAAa;IACb,KAAK;IACL,OAAO;GACT,GACA,QACF;EAC0B,CAAA;CACP,CAAA;AAE3B,CAAC;AAED,SAAgB,WAAW;CACzB,OAAO,WAAW,YAAY;AAChC"}
|
|
@@ -1 +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,
|
|
1
|
+
{"version":3,"file":"theme-scope.cjs","names":["createContext","useContext"],"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,GAAoBA,MAAAA,cAAAA,CAA+B,EAAE,WAAW,KAAK,CAAC;AAEnF,SAAgB,0BAA0B;CACxC,QAAA,GAAOC,MAAAA,WAAAA,CAAW,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": "1.0.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Richard Borges",
|
|
@@ -78,22 +78,22 @@
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"@base-ui/react": "^1.
|
|
82
|
-
"date-fns": "^4.
|
|
81
|
+
"@base-ui/react": "^1.8.0",
|
|
82
|
+
"date-fns": "^4.4.0",
|
|
83
83
|
"qrcode": "^1.5.4"
|
|
84
84
|
},
|
|
85
85
|
"publishConfig": {
|
|
86
86
|
"access": "public"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@pandacss/dev": "^1.
|
|
89
|
+
"@pandacss/dev": "^1.12.1",
|
|
90
90
|
"@types/qrcode": "^1.5.6",
|
|
91
|
-
"@types/react": "^19.
|
|
92
|
-
"@types/react-dom": "^19.
|
|
91
|
+
"@types/react": "^19.3.0",
|
|
92
|
+
"@types/react-dom": "^19.3.0",
|
|
93
93
|
"jsdom": "^27.4.0",
|
|
94
|
-
"react": "^19.
|
|
95
|
-
"react-dom": "^19.
|
|
96
|
-
"tsdown": "^0.22.
|
|
94
|
+
"react": "^19.3.0",
|
|
95
|
+
"react-dom": "^19.3.0",
|
|
96
|
+
"tsdown": "^0.22.14"
|
|
97
97
|
},
|
|
98
98
|
"scripts": {
|
|
99
99
|
"clean": "rimraf dist src/styled-system",
|