@weasel-js/theme 1.11.1 → 1.12.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/dist/react.d.ts +8 -1
- package/dist/react.js +11 -2
- package/dist/react.js.map +1 -1
- package/package.json +4 -4
package/dist/react.d.ts
CHANGED
|
@@ -98,5 +98,12 @@ declare function useTones(): ThemeContextValue;
|
|
|
98
98
|
* answers.
|
|
99
99
|
*/
|
|
100
100
|
declare function useColorCss(): (source: ColorSource | null | undefined) => string | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Turns a `ColorSource` into a hex color under the theme, tones, and palette in force, for a
|
|
103
|
+
* surface drawn without the cascade, such as a scene's paint. `useColorCss` may answer
|
|
104
|
+
* `var(--wzl-…)`, which only the DOM resolves; this answers the value. `undefined` for no
|
|
105
|
+
* source, and for one nothing answers.
|
|
106
|
+
*/
|
|
107
|
+
declare function useColorHex(): (source: ColorSource | null | undefined) => string | undefined;
|
|
101
108
|
|
|
102
|
-
export { ColorMode, ColorModePreference, type ColorModePreferenceOptions, type ColorModePreferenceState, type ColorModeStorage, ThemeContext, type ThemeContextValue, ThemeProvider, type ThemeProviderProps, useColorCss, useColorModePreference, useResolvedColorMode, useTheme, useThemeOptional, useTones };
|
|
109
|
+
export { ColorMode, ColorModePreference, type ColorModePreferenceOptions, type ColorModePreferenceState, type ColorModeStorage, ThemeContext, type ThemeContextValue, ThemeProvider, type ThemeProviderProps, useColorCss, useColorHex, useColorModePreference, useResolvedColorMode, useTheme, useThemeOptional, useTones };
|
package/dist/react.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { isColorModePreference, themeTones, applyTheme, colorSourceCss } from './chunk-QGOGBCYW.js';
|
|
1
|
+
import { isColorModePreference, themeTones, applyTheme, colorSourceCss, colorSourceLiteral } from './chunk-QGOGBCYW.js';
|
|
2
2
|
export { isColorModePreference } from './chunk-QGOGBCYW.js';
|
|
3
3
|
import './chunk-S7MJPFDP.js';
|
|
4
4
|
import './chunk-M3R5MV7Q.js';
|
|
5
5
|
import { themeAxes, resolveTheme } from './chunk-32JKTYS2.js';
|
|
6
6
|
import { weaselTheme } from './chunk-JX2OC444.js';
|
|
7
7
|
import { fullSelection, selectionKey } from './chunk-P5F3GZV6.js';
|
|
8
|
+
import { colorLiteralToHex } from '@weasel-js/paint';
|
|
8
9
|
import { createContext, useState, useEffect, useCallback, useRef, useMemo, useLayoutEffect, useContext } from 'react';
|
|
9
10
|
import { isDev } from '@weasel-js/registry';
|
|
10
11
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -128,7 +129,15 @@ function useColorCss() {
|
|
|
128
129
|
const ctx = useTones();
|
|
129
130
|
return useCallback((source) => source == null ? void 0 : colorSourceCss(source, ctx) ?? void 0, [ctx]);
|
|
130
131
|
}
|
|
132
|
+
function useColorHex() {
|
|
133
|
+
const ctx = useTones();
|
|
134
|
+
return useCallback((source) => {
|
|
135
|
+
if (source == null) return void 0;
|
|
136
|
+
const literal = colorSourceLiteral(source, ctx);
|
|
137
|
+
return (literal && colorLiteralToHex(literal)) ?? void 0;
|
|
138
|
+
}, [ctx]);
|
|
139
|
+
}
|
|
131
140
|
|
|
132
|
-
export { ThemeContext, ThemeProvider, useColorCss, useColorModePreference, useResolvedColorMode, useTheme, useThemeOptional, useTones };
|
|
141
|
+
export { ThemeContext, ThemeProvider, useColorCss, useColorHex, useColorModePreference, useResolvedColorMode, useTheme, useThemeOptional, useTones };
|
|
133
142
|
//# sourceMappingURL=react.js.map
|
|
134
143
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useColorMode.ts","../src/react.tsx"],"names":["systemMode","useCallback"],"mappings":"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","file":"react.js","sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { isColorModePreference, type ColorMode, type ColorModePreference } from './colorMode';\n\nfunction systemQuery(): MediaQueryList | null {\n if (typeof globalThis.matchMedia !== 'function') return null;\n return globalThis.matchMedia('(prefers-color-scheme: light)');\n}\n\nconst systemMode = (): ColorMode => (systemQuery()?.matches ? 'light' : 'dark');\n\n/**\n * Resolves a preference to the mode a `ThemeProvider` selection takes.\n * `'auto'` subscribes to the OS setting and follows it live; an explicit\n * choice opts out of the subscription entirely.\n */\nexport function useResolvedColorMode(preference: ColorModePreference): ColorMode {\n const [system, setSystem] = useState<ColorMode>(systemMode);\n\n useEffect(() => {\n if (preference !== 'auto') return;\n const mq = systemQuery();\n if (!mq) return;\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncs to the OS color-scheme query\n setSystem(mq.matches ? 'light' : 'dark');\n const onChange = (e: { matches: boolean }) => setSystem(e.matches ? 'light' : 'dark');\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [preference]);\n\n return preference === 'auto' ? system : preference;\n}\n\n/** The part of `Storage` {@link useColorModePreference} reads and writes. */\nexport type ColorModeStorage = Pick<Storage, 'getItem' | 'setItem'>;\n\n/** Options for {@link useColorModePreference}. */\nexport interface ColorModePreferenceOptions {\n /** Where the choice is remembered. Unset, it lasts as long as the component. */\n readonly storageKey?: string;\n /** The store `storageKey` names a slot in. Defaults to `localStorage`. */\n readonly storage?: ColorModeStorage;\n /** The preference before the user has chosen one. Defaults to `'auto'`. */\n readonly defaultPreference?: ColorModePreference;\n}\n\n/** What {@link useColorModePreference} returns. */\nexport interface ColorModePreferenceState {\n readonly preference: ColorModePreference;\n readonly setPreference: (next: ColorModePreference) => void;\n /** `preference` resolved against the OS — what to put in the theme's `mode` axis. */\n readonly mode: ColorMode;\n}\n\nfunction defaultStorage(): ColorModeStorage | undefined {\n try {\n return globalThis.localStorage ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * A user's color-mode choice, optionally remembered across loads, and the mode\n * it resolves to. Storage that is missing or throws (a private window, blocked\n * site data) degrades to an unremembered choice rather than an error.\n */\nexport function useColorModePreference(\n options: ColorModePreferenceOptions = {},\n): ColorModePreferenceState {\n const { storageKey, storage, defaultPreference = 'auto' } = options;\n\n const [preference, setState] = useState<ColorModePreference>(() => {\n if (storageKey === undefined) return defaultPreference;\n try {\n const stored = (storage ?? defaultStorage())?.getItem(storageKey);\n return isColorModePreference(stored) ? stored : defaultPreference;\n } catch {\n return defaultPreference;\n }\n });\n\n const setPreference = useCallback(\n (next: ColorModePreference) => {\n setState(next);\n if (storageKey === undefined) return;\n try {\n (storage ?? defaultStorage())?.setItem(storageKey, next);\n } catch {\n // Unremembered, but still applied.\n }\n },\n [storageKey, storage],\n );\n\n return { preference, setPreference, mode: useResolvedColorMode(preference) };\n}\n","import type { ColorSource, Palette } from '@weasel-js/paint';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useLayoutEffect } from 'react';\nimport { isDev } from '@weasel-js/registry';\nimport { applyTheme } from './applyTheme';\nimport { themeTones, type ColorList } from './colorList';\nimport { colorSourceCss } from './colorSource';\nimport { fullSelection, selectionKey, type Selection } from './axes';\nimport { resolveTheme, themeAxes, type ResolvedTheme } from './resolveTheme';\nimport { weaselTheme, type Theme } from './theme';\nimport { useResolvedColorMode } from './useColorMode';\n\nexport {\n useColorModePreference,\n useResolvedColorMode,\n type ColorModePreferenceOptions,\n type ColorModePreferenceState,\n type ColorModeStorage,\n} from './useColorMode';\nexport { isColorModePreference, type ColorMode, type ColorModePreference } from './colorMode';\n\n/** What `<ThemeProvider>` publishes: the theme, the full selection in force, the\n * fully resolved token record for that pair, and the tone list and palette in force. */\nexport interface ThemeContextValue {\n readonly theme: Theme;\n readonly selection: Selection;\n readonly resolved: ResolvedTheme;\n readonly tones: ColorList;\n readonly palette: Palette;\n}\n\n/** What `<ThemeProvider>` publishes. Provide `null` to hide an outer theme from a subtree, as a\n * boundary that renders its children the way a page with no provider would. */\nexport const ThemeContext = createContext<ThemeContextValue | null>(null);\n\nconst NO_PALETTE: Palette = { entries: [] };\n\n/** Props for `<ThemeProvider>`. */\nexport interface ThemeProviderProps {\n readonly theme?: Theme;\n /** Axis values, e.g. `{ mode: 'light' }`. A missing axis takes its default. `mode: 'auto'`\n * follows the OS setting, live; any other value the theme lacks takes the default, with a\n * warning in development. */\n readonly selection?: Selection;\n /** The colors a `tone` index picks from in this subtree. Absent: the theme's own. */\n readonly tones?: ColorList;\n /** Colors a `ColorRef` names in this subtree, answered before the theme's own names. Absent: none. */\n readonly palette?: Palette;\n /** Applied to the wrapper element, so it can be the layout element too. */\n readonly className?: string;\n readonly style?: React.CSSProperties;\n readonly children: React.ReactNode;\n}\n\n/**\n * Applies a theme to a wrapper element and publishes the resolved record.\n *\n * Consumers that draw outside the DOM (the WebGL HUD) read `resolved` and\n * never touch `getComputedStyle`.\n *\n * The wrapper is a real element in the layout. Pass `className` rather than\n * nesting your own div inside — an anonymous div between a flex parent and\n * its child breaks percentage heights.\n */\nexport function ThemeProvider({\n theme = weaselTheme,\n selection,\n tones,\n palette = NO_PALETTE,\n className,\n style,\n children,\n}: ThemeProviderProps): React.ReactElement {\n const ref = useRef<HTMLDivElement>(null);\n const axes = themeAxes(theme);\n const autoMode = selection?.mode === 'auto' && !('auto' in (axes.mode?.values ?? {}));\n const systemMode = useResolvedColorMode(autoMode ? 'auto' : 'dark');\n const given = autoMode ? { ...selection, mode: systemMode } : selection;\n const full = fullSelection(axes, given);\n warnUnknownAxisValues(theme, axes, given);\n // Keyed on the selection's content: callers pass a fresh object every render.\n const key = selectionKey(axes, full);\n\n const value = useMemo<ThemeContextValue>(\n () => ({ theme, selection: full, resolved: resolveTheme(theme, full), tones: tones ?? themeTones(theme), palette }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [theme, key, tones, palette],\n );\n\n // Applying again replaces what the element held, so only the unmount releases.\n const release = useRef<(() => void) | null>(null);\n useLayoutEffect(() => {\n if (ref.current) release.current = applyTheme(ref.current, theme, value.selection);\n }, [theme, value]);\n useLayoutEffect(() => () => release.current?.(), []);\n\n const attrs = Object.fromEntries(Object.keys(axes).map((a) => [`data-wzl-${a}`, full[a]]));\n return (\n <ThemeContext.Provider value={value}>\n <div ref={ref} className={className} style={style} data-wzl-theme={theme.name} {...attrs}>\n {children}\n </div>\n </ThemeContext.Provider>\n );\n}\n\nconst warned = new Set<string>();\n\nfunction warnUnknownAxisValues(theme: Theme, axes: ReturnType<typeof themeAxes>, selection: Selection | undefined): void {\n if (!selection || !isDev()) return;\n for (const [axis, value] of Object.entries(selection)) {\n const def = axes[axis];\n if (!def || value in def.values) continue;\n const key = `${theme.name}\\0${axis}\\0${value}`;\n if (warned.has(key)) continue;\n warned.add(key);\n console.warn(\n `[weasel theme] ThemeProvider: theme \"${theme.name}\" has no ${axis} \"${value}\"; using \"${def.default}\". Its ${axis} values: ${Object.keys(def.values).join(', ')}.`,\n );\n }\n}\n\n/** The theme in force. Throws outside a `<ThemeProvider>`; use\n * `useThemeOptional` where the provider is not guaranteed. */\nexport function useTheme(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error('useTheme must be used inside a <ThemeProvider>');\n return ctx;\n}\n\n/**\n * The theme if one is provided, `null` otherwise.\n *\n * For kit internals that should follow a theme when the app supplies one but\n * must still work in an app that never mounted a provider — `useHud` is the\n * motivating case.\n */\nexport function useThemeOptional(): ThemeContextValue | null {\n return useContext(ThemeContext);\n}\n\nlet defaultTones: ThemeContextValue | undefined;\n\n/**\n * The tone list in force and what it resolves against — the nearest\n * `<ThemeProvider>`'s, else the built-in theme's at its defaults. Pass the\n * result as `colorAt`'s context.\n */\nexport function useTones(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (ctx) return ctx;\n return (defaultTones ??= {\n theme: weaselTheme,\n selection: fullSelection(themeAxes(weaselTheme)),\n resolved: resolveTheme(weaselTheme),\n tones: themeTones(weaselTheme),\n palette: NO_PALETTE,\n });\n}\n\n/**\n * Turns a `ColorSource` into a CSS color under the theme, tones, and palette in\n * force: `colorSourceCss` against `useTones()`. Every component that takes a\n * color writes it through this. `undefined` for no source, and for one nothing\n * answers.\n */\nexport function useColorCss(): (source: ColorSource | null | undefined) => string | undefined {\n const ctx = useTones();\n return useCallback((source) => (source == null ? undefined : (colorSourceCss(source, ctx) ?? undefined)), [ctx]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/useColorMode.ts","../src/react.tsx"],"names":["systemMode","useCallback"],"mappings":"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","file":"react.js","sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { isColorModePreference, type ColorMode, type ColorModePreference } from './colorMode';\n\nfunction systemQuery(): MediaQueryList | null {\n if (typeof globalThis.matchMedia !== 'function') return null;\n return globalThis.matchMedia('(prefers-color-scheme: light)');\n}\n\nconst systemMode = (): ColorMode => (systemQuery()?.matches ? 'light' : 'dark');\n\n/**\n * Resolves a preference to the mode a `ThemeProvider` selection takes.\n * `'auto'` subscribes to the OS setting and follows it live; an explicit\n * choice opts out of the subscription entirely.\n */\nexport function useResolvedColorMode(preference: ColorModePreference): ColorMode {\n const [system, setSystem] = useState<ColorMode>(systemMode);\n\n useEffect(() => {\n if (preference !== 'auto') return;\n const mq = systemQuery();\n if (!mq) return;\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncs to the OS color-scheme query\n setSystem(mq.matches ? 'light' : 'dark');\n const onChange = (e: { matches: boolean }) => setSystem(e.matches ? 'light' : 'dark');\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [preference]);\n\n return preference === 'auto' ? system : preference;\n}\n\n/** The part of `Storage` {@link useColorModePreference} reads and writes. */\nexport type ColorModeStorage = Pick<Storage, 'getItem' | 'setItem'>;\n\n/** Options for {@link useColorModePreference}. */\nexport interface ColorModePreferenceOptions {\n /** Where the choice is remembered. Unset, it lasts as long as the component. */\n readonly storageKey?: string;\n /** The store `storageKey` names a slot in. Defaults to `localStorage`. */\n readonly storage?: ColorModeStorage;\n /** The preference before the user has chosen one. Defaults to `'auto'`. */\n readonly defaultPreference?: ColorModePreference;\n}\n\n/** What {@link useColorModePreference} returns. */\nexport interface ColorModePreferenceState {\n readonly preference: ColorModePreference;\n readonly setPreference: (next: ColorModePreference) => void;\n /** `preference` resolved against the OS — what to put in the theme's `mode` axis. */\n readonly mode: ColorMode;\n}\n\nfunction defaultStorage(): ColorModeStorage | undefined {\n try {\n return globalThis.localStorage ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * A user's color-mode choice, optionally remembered across loads, and the mode\n * it resolves to. Storage that is missing or throws (a private window, blocked\n * site data) degrades to an unremembered choice rather than an error.\n */\nexport function useColorModePreference(\n options: ColorModePreferenceOptions = {},\n): ColorModePreferenceState {\n const { storageKey, storage, defaultPreference = 'auto' } = options;\n\n const [preference, setState] = useState<ColorModePreference>(() => {\n if (storageKey === undefined) return defaultPreference;\n try {\n const stored = (storage ?? defaultStorage())?.getItem(storageKey);\n return isColorModePreference(stored) ? stored : defaultPreference;\n } catch {\n return defaultPreference;\n }\n });\n\n const setPreference = useCallback(\n (next: ColorModePreference) => {\n setState(next);\n if (storageKey === undefined) return;\n try {\n (storage ?? defaultStorage())?.setItem(storageKey, next);\n } catch {\n // Unremembered, but still applied.\n }\n },\n [storageKey, storage],\n );\n\n return { preference, setPreference, mode: useResolvedColorMode(preference) };\n}\n","import { colorLiteralToHex, type ColorSource, type Palette } from '@weasel-js/paint';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useLayoutEffect } from 'react';\nimport { isDev } from '@weasel-js/registry';\nimport { applyTheme } from './applyTheme';\nimport { themeTones, type ColorList } from './colorList';\nimport { colorSourceCss, colorSourceLiteral } from './colorSource';\nimport { fullSelection, selectionKey, type Selection } from './axes';\nimport { resolveTheme, themeAxes, type ResolvedTheme } from './resolveTheme';\nimport { weaselTheme, type Theme } from './theme';\nimport { useResolvedColorMode } from './useColorMode';\n\nexport {\n useColorModePreference,\n useResolvedColorMode,\n type ColorModePreferenceOptions,\n type ColorModePreferenceState,\n type ColorModeStorage,\n} from './useColorMode';\nexport { isColorModePreference, type ColorMode, type ColorModePreference } from './colorMode';\n\n/** What `<ThemeProvider>` publishes: the theme, the full selection in force, the\n * fully resolved token record for that pair, and the tone list and palette in force. */\nexport interface ThemeContextValue {\n readonly theme: Theme;\n readonly selection: Selection;\n readonly resolved: ResolvedTheme;\n readonly tones: ColorList;\n readonly palette: Palette;\n}\n\n/** What `<ThemeProvider>` publishes. Provide `null` to hide an outer theme from a subtree, as a\n * boundary that renders its children the way a page with no provider would. */\nexport const ThemeContext = createContext<ThemeContextValue | null>(null);\n\nconst NO_PALETTE: Palette = { entries: [] };\n\n/** Props for `<ThemeProvider>`. */\nexport interface ThemeProviderProps {\n readonly theme?: Theme;\n /** Axis values, e.g. `{ mode: 'light' }`. A missing axis takes its default. `mode: 'auto'`\n * follows the OS setting, live; any other value the theme lacks takes the default, with a\n * warning in development. */\n readonly selection?: Selection;\n /** The colors a `tone` index picks from in this subtree. Absent: the theme's own. */\n readonly tones?: ColorList;\n /** Colors a `ColorRef` names in this subtree, answered before the theme's own names. Absent: none. */\n readonly palette?: Palette;\n /** Applied to the wrapper element, so it can be the layout element too. */\n readonly className?: string;\n readonly style?: React.CSSProperties;\n readonly children: React.ReactNode;\n}\n\n/**\n * Applies a theme to a wrapper element and publishes the resolved record.\n *\n * Consumers that draw outside the DOM (the WebGL HUD) read `resolved` and\n * never touch `getComputedStyle`.\n *\n * The wrapper is a real element in the layout. Pass `className` rather than\n * nesting your own div inside — an anonymous div between a flex parent and\n * its child breaks percentage heights.\n */\nexport function ThemeProvider({\n theme = weaselTheme,\n selection,\n tones,\n palette = NO_PALETTE,\n className,\n style,\n children,\n}: ThemeProviderProps): React.ReactElement {\n const ref = useRef<HTMLDivElement>(null);\n const axes = themeAxes(theme);\n const autoMode = selection?.mode === 'auto' && !('auto' in (axes.mode?.values ?? {}));\n const systemMode = useResolvedColorMode(autoMode ? 'auto' : 'dark');\n const given = autoMode ? { ...selection, mode: systemMode } : selection;\n const full = fullSelection(axes, given);\n warnUnknownAxisValues(theme, axes, given);\n // Keyed on the selection's content: callers pass a fresh object every render.\n const key = selectionKey(axes, full);\n\n const value = useMemo<ThemeContextValue>(\n () => ({ theme, selection: full, resolved: resolveTheme(theme, full), tones: tones ?? themeTones(theme), palette }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [theme, key, tones, palette],\n );\n\n // Applying again replaces what the element held, so only the unmount releases.\n const release = useRef<(() => void) | null>(null);\n useLayoutEffect(() => {\n if (ref.current) release.current = applyTheme(ref.current, theme, value.selection);\n }, [theme, value]);\n useLayoutEffect(() => () => release.current?.(), []);\n\n const attrs = Object.fromEntries(Object.keys(axes).map((a) => [`data-wzl-${a}`, full[a]]));\n return (\n <ThemeContext.Provider value={value}>\n <div ref={ref} className={className} style={style} data-wzl-theme={theme.name} {...attrs}>\n {children}\n </div>\n </ThemeContext.Provider>\n );\n}\n\nconst warned = new Set<string>();\n\nfunction warnUnknownAxisValues(theme: Theme, axes: ReturnType<typeof themeAxes>, selection: Selection | undefined): void {\n if (!selection || !isDev()) return;\n for (const [axis, value] of Object.entries(selection)) {\n const def = axes[axis];\n if (!def || value in def.values) continue;\n const key = `${theme.name}\\0${axis}\\0${value}`;\n if (warned.has(key)) continue;\n warned.add(key);\n console.warn(\n `[weasel theme] ThemeProvider: theme \"${theme.name}\" has no ${axis} \"${value}\"; using \"${def.default}\". Its ${axis} values: ${Object.keys(def.values).join(', ')}.`,\n );\n }\n}\n\n/** The theme in force. Throws outside a `<ThemeProvider>`; use\n * `useThemeOptional` where the provider is not guaranteed. */\nexport function useTheme(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error('useTheme must be used inside a <ThemeProvider>');\n return ctx;\n}\n\n/**\n * The theme if one is provided, `null` otherwise.\n *\n * For kit internals that should follow a theme when the app supplies one but\n * must still work in an app that never mounted a provider — `useHud` is the\n * motivating case.\n */\nexport function useThemeOptional(): ThemeContextValue | null {\n return useContext(ThemeContext);\n}\n\nlet defaultTones: ThemeContextValue | undefined;\n\n/**\n * The tone list in force and what it resolves against — the nearest\n * `<ThemeProvider>`'s, else the built-in theme's at its defaults. Pass the\n * result as `colorAt`'s context.\n */\nexport function useTones(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (ctx) return ctx;\n return (defaultTones ??= {\n theme: weaselTheme,\n selection: fullSelection(themeAxes(weaselTheme)),\n resolved: resolveTheme(weaselTheme),\n tones: themeTones(weaselTheme),\n palette: NO_PALETTE,\n });\n}\n\n/**\n * Turns a `ColorSource` into a CSS color under the theme, tones, and palette in\n * force: `colorSourceCss` against `useTones()`. Every component that takes a\n * color writes it through this. `undefined` for no source, and for one nothing\n * answers.\n */\nexport function useColorCss(): (source: ColorSource | null | undefined) => string | undefined {\n const ctx = useTones();\n return useCallback((source) => (source == null ? undefined : (colorSourceCss(source, ctx) ?? undefined)), [ctx]);\n}\n\n/**\n * Turns a `ColorSource` into a hex color under the theme, tones, and palette in force, for a\n * surface drawn without the cascade, such as a scene's paint. `useColorCss` may answer\n * `var(--wzl-…)`, which only the DOM resolves; this answers the value. `undefined` for no\n * source, and for one nothing answers.\n */\nexport function useColorHex(): (source: ColorSource | null | undefined) => string | undefined {\n const ctx = useTones();\n return useCallback((source) => {\n if (source == null) return undefined;\n const literal = colorSourceLiteral(source, ctx);\n return (literal && colorLiteralToHex(literal)) ?? undefined;\n }, [ctx]);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/theme",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Design tokens shared by weasel-ui and weasel-hud — CSS variables + a parallel TS export.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"./package.json": "./package.json"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@weasel-js/paint": "1.
|
|
47
|
-
"@weasel-js/prefs": "1.
|
|
48
|
-
"@weasel-js/registry": "1.
|
|
46
|
+
"@weasel-js/paint": "1.12.0",
|
|
47
|
+
"@weasel-js/prefs": "1.12.0",
|
|
48
|
+
"@weasel-js/registry": "1.12.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"react": ">=18"
|