@lynx-js/luna-reactlynx 0.0.1

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +201 -0
  3. package/README.md +255 -0
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.jsx +2 -0
  7. package/dist/runtime/global-props.d.ts +9 -0
  8. package/dist/runtime/global-props.d.ts.map +1 -0
  9. package/dist/runtime/global-props.jsx +0 -0
  10. package/dist/runtime/index.d.ts +2 -0
  11. package/dist/runtime/index.d.ts.map +1 -0
  12. package/dist/runtime/index.jsx +2 -0
  13. package/dist/runtime/luna-theme.d.ts +14 -0
  14. package/dist/runtime/luna-theme.d.ts.map +1 -0
  15. package/dist/runtime/luna-theme.jsx +51 -0
  16. package/dist/theming/consumption.d.ts +22 -0
  17. package/dist/theming/consumption.d.ts.map +1 -0
  18. package/dist/theming/consumption.jsx +31 -0
  19. package/dist/theming/create-theme.d.ts +16 -0
  20. package/dist/theming/create-theme.d.ts.map +1 -0
  21. package/dist/theming/create-theme.jsx +109 -0
  22. package/dist/theming/identity.d.ts +3 -0
  23. package/dist/theming/identity.d.ts.map +1 -0
  24. package/dist/theming/identity.jsx +2 -0
  25. package/dist/theming/index.d.ts +7 -0
  26. package/dist/theming/index.d.ts.map +1 -0
  27. package/dist/theming/index.jsx +7 -0
  28. package/dist/theming/theme-context.d.ts +5 -0
  29. package/dist/theming/theme-context.d.ts.map +1 -0
  30. package/dist/theming/theme-context.jsx +5 -0
  31. package/dist/theming/theme-provider.d.ts +4 -0
  32. package/dist/theming/theme-provider.d.ts.map +1 -0
  33. package/dist/theming/theme-provider.helpers.d.ts +21 -0
  34. package/dist/theming/theme-provider.helpers.d.ts.map +1 -0
  35. package/dist/theming/theme-provider.helpers.jsx +35 -0
  36. package/dist/theming/theme-provider.jsx +84 -0
  37. package/dist/theming/types.d.ts +175 -0
  38. package/dist/theming/types.d.ts.map +1 -0
  39. package/dist/theming/types.jsx +0 -0
  40. package/dist/theming/use-color.d.ts +3 -0
  41. package/dist/theming/use-color.d.ts.map +1 -0
  42. package/dist/theming/use-color.jsx +55 -0
  43. package/dist/theming/use-colors.d.ts +11 -0
  44. package/dist/theming/use-colors.d.ts.map +1 -0
  45. package/dist/theming/use-colors.jsx +45 -0
  46. package/dist/theming/use-theme-context.d.ts +7 -0
  47. package/dist/theming/use-theme-context.d.ts.map +1 -0
  48. package/dist/theming/use-theme-context.jsx +8 -0
  49. package/package.json +72 -0
@@ -0,0 +1,109 @@
1
+ import { isNonEmptyString } from "./consumption.jsx";
2
+ import { LUNA_COLOR_IDS, colorIdToColorKey, createEmptyLunaColors } from "./identity.jsx";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
9
+ });
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
13
+ function _object_spread(target) {
14
+ for(var i = 1; i < arguments.length; i++){
15
+ var source = null != arguments[i] ? arguments[i] : {};
16
+ var ownKeys = Object.keys(source);
17
+ if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
18
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
19
+ }));
20
+ ownKeys.forEach(function(key) {
21
+ _define_property(target, key, source[key]);
22
+ });
23
+ }
24
+ return target;
25
+ }
26
+ function createLunaTheme(input, options = {}) {
27
+ const { consumptionFormat = 'value', cssVarPrefix } = options;
28
+ const colors = createEmptyLunaColors();
29
+ if (!hasColors(input)) {
30
+ if ('var-ref' !== consumptionFormat) throw new Error(formatInvalidInputError({
31
+ sourceType: 'meta-only',
32
+ consumptionFormat: `'${consumptionFormat}'`
33
+ }));
34
+ return _object_spread({
35
+ key: input.key,
36
+ variant: input.variant,
37
+ mode: input.mode,
38
+ colors,
39
+ sourceType: 'meta-only',
40
+ consumptionFormat: 'var-ref'
41
+ }, void 0 !== cssVarPrefix ? {
42
+ cssVarPrefix
43
+ } : {});
44
+ }
45
+ const missingIds = collectMissingColorIds(input.colors);
46
+ if (missingIds.length > 0) throw new Error(formatMissingColorValuesError(_object_spread({
47
+ consumptionFormat,
48
+ sourceType: 'values',
49
+ missingIds
50
+ }, void 0 !== cssVarPrefix ? {
51
+ cssVarPrefix
52
+ } : {})));
53
+ for (const id of LUNA_COLOR_IDS){
54
+ const key = colorIdToColorKey(id);
55
+ colors[key] = input.colors[id];
56
+ }
57
+ Object.freeze(colors);
58
+ return _object_spread({
59
+ key: input.key,
60
+ variant: input.variant,
61
+ mode: input.mode,
62
+ colors,
63
+ sourceType: 'values',
64
+ consumptionFormat
65
+ }, void 0 !== cssVarPrefix ? {
66
+ cssVarPrefix
67
+ } : {});
68
+ }
69
+ function hasColors(input) {
70
+ return 'colors' in input && 'object' == typeof input.colors && null !== input.colors;
71
+ }
72
+ function formatInvalidInputError(args) {
73
+ const { sourceType, consumptionFormat } = args;
74
+ return [
75
+ '[createLunaTheme] Invalid theme input for the requested consumption format.',
76
+ `- sourceType: '${sourceType}'`,
77
+ `- consumptionFormat: ${consumptionFormat}`,
78
+ '',
79
+ 'A meta-only theme input cannot produce raw values.',
80
+ 'If you want to use CSS variables, pass `consumptionFormat: \'var-ref\'`.'
81
+ ].join('\n');
82
+ }
83
+ function formatMissingColorValuesError(args) {
84
+ const { consumptionFormat, sourceType, missingIds, cssVarPrefix } = args;
85
+ const preview = missingIds.slice(0, 12).join(', ');
86
+ const more = missingIds.length > 12 ? ` (+${missingIds.length - 12} more)` : '';
87
+ const prefixHint = void 0 !== cssVarPrefix ? `- cssVarPrefix: ${cssVarPrefix}\n` : '';
88
+ return [
89
+ '[createLunaTheme] Missing required color values.',
90
+ `- sourceType: \`${sourceType}\``,
91
+ `- consumptionFormat: \`${consumptionFormat}\``,
92
+ prefixHint.trimEnd(),
93
+ `- missing color ids: ${missingIds.length}`,
94
+ `- missing (preview): ${preview}${more}`,
95
+ '',
96
+ 'Note: token values must be complete, even if `consumptionFormat` is `\'var-ref\'`.'
97
+ ].filter(Boolean).join('\n');
98
+ }
99
+ function collectMissingColorIds(colors) {
100
+ const missing = [];
101
+ for (const id of LUNA_COLOR_IDS){
102
+ const value = colors[id];
103
+ if (!isNonEmptyString(value)) missing.push(id);
104
+ }
105
+ return missing;
106
+ }
107
+ export { createLunaTheme };
108
+
109
+ //# sourceMappingURL=create-theme.jsx.map
@@ -0,0 +1,3 @@
1
+ import { LUNA_COLOR_IDS, LUNA_COLOR_KEYS, colorIdToColorKey, colorKeyToColorId, createEmptyLunaColors } from '@lynx-js/luna-core';
2
+ export { LUNA_COLOR_IDS, LUNA_COLOR_KEYS, colorIdToColorKey, colorKeyToColorId, createEmptyLunaColors, };
3
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/theming/identity.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { LUNA_COLOR_IDS, LUNA_COLOR_KEYS, colorIdToColorKey, colorKeyToColorId, createEmptyLunaColors } from "@lynx-js/luna-core";
2
+ export { LUNA_COLOR_IDS, LUNA_COLOR_KEYS, colorIdToColorKey, colorKeyToColorId, createEmptyLunaColors };
@@ -0,0 +1,7 @@
1
+ export { LunaThemeContext } from './theme-context.jsx';
2
+ export { LunaThemeProvider } from './theme-provider.jsx';
3
+ export { createLunaTheme } from './create-theme.js';
4
+ export { useLunaThemeContext } from './use-theme-context.js';
5
+ export { useLunaColor } from './use-color.js';
6
+ export { useLunaColors } from './use-colors.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theming/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { LunaThemeContext } from "./theme-context.jsx";
2
+ import { LunaThemeProvider } from "./theme-provider.jsx";
3
+ import { createLunaTheme } from "./create-theme.jsx";
4
+ import { useLunaThemeContext } from "./use-theme-context.jsx";
5
+ import { useLunaColor } from "./use-color.jsx";
6
+ import { useLunaColors } from "./use-colors.jsx";
7
+ export { LunaThemeContext, LunaThemeProvider, createLunaTheme, useLunaColor, useLunaColors, useLunaThemeContext };
@@ -0,0 +1,5 @@
1
+ import type { Context } from '@lynx-js/react';
2
+ import type { LunaThemeContextValue } from './types.js';
3
+ declare const LunaThemeContext: Context<LunaThemeContextValue | null>;
4
+ export { LunaThemeContext };
5
+ //# sourceMappingURL=theme-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-context.d.ts","sourceRoot":"","sources":["../../src/theming/theme-context.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,QAAA,MAAM,gBAAgB,EAAE,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAErD,CAAC;AAER,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { createContext } from "@lynx-js/react";
2
+ const LunaThemeContext = createContext(null);
3
+ export { LunaThemeContext };
4
+
5
+ //# sourceMappingURL=theme-context.jsx.map
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from '@lynx-js/react';
2
+ import type { LunaThemeProviderProps } from './types.js';
3
+ export declare function LunaThemeProvider(props: LunaThemeProviderProps): ReactNode;
4
+ //# sourceMappingURL=theme-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/theming/theme-provider.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAOhD,OAAO,KAAK,EAAyB,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEhF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,SAAS,CA2GX"}
@@ -0,0 +1,21 @@
1
+ import type { LunaThemeResolveRuleSpec } from '@lynx-js/luna-core';
2
+ /**
3
+ * Generate a stable string key for resolver rules.
4
+ *
5
+ * WHY THIS EXISTS:
6
+ * - `resolve.rules` may be passed inline by callers (new array/object every render)
7
+ * - React `useMemo` compares dependencies by reference
8
+ * - We need a *semantic* equality check, not reference equality
9
+ *
10
+ * This function produces a stable, ordered, domain-aware key so that:
11
+ * - rules with the same meaning => same key
12
+ * - rules with different order / options => different key
13
+ *
14
+ * NOTE:
15
+ * - This is NOT a general-purpose serializer
16
+ * - This is intentionally shallow (rules options are config, not data)
17
+ *
18
+ * @internal
19
+ */
20
+ export declare function stableRulesKey(rules: readonly LunaThemeResolveRuleSpec[] | undefined): string;
21
+ //# sourceMappingURL=theme-provider.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-provider.helpers.d.ts","sourceRoot":"","sources":["../../src/theming/theme-provider.helpers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,wBAAwB,EAAE,GAAG,SAAS,GACrD,MAAM,CAkBR"}
@@ -0,0 +1,35 @@
1
+ function stableRulesKey(rules) {
2
+ if (!rules || 0 === rules.length) return '';
3
+ return rules.map((rule)=>{
4
+ if ('string' == typeof rule) return rule;
5
+ const { id, options } = rule;
6
+ if (!options || 0 === Object.keys(options).length) return id;
7
+ const optionPairs = Object.entries(options).sort(([a], [b])=>a.localeCompare(b)).map(([k, v])=>`${k}:${stableAtom(v)}`).join(',');
8
+ return `${id}(${optionPairs})`;
9
+ }).join('|');
10
+ }
11
+ function stableAtom(v) {
12
+ if (null === v) return 'null';
13
+ if (void 0 === v) return 'undefined';
14
+ switch(typeof v){
15
+ case 'string':
16
+ return JSON.stringify(v);
17
+ case 'number':
18
+ case 'boolean':
19
+ case 'bigint':
20
+ return String(v);
21
+ case 'symbol':
22
+ return v.toString();
23
+ case 'function':
24
+ return '[fn]';
25
+ default:
26
+ try {
27
+ return JSON.stringify(v);
28
+ } catch (e) {
29
+ return '[unserializable]';
30
+ }
31
+ }
32
+ }
33
+ export { stableRulesKey };
34
+
35
+ //# sourceMappingURL=theme-provider.helpers.jsx.map
@@ -0,0 +1,84 @@
1
+ import { useMemo } from "@lynx-js/react";
2
+ import { resolveThemeObjectFromList } from "@lynx-js/luna-core";
3
+ import { LunaThemeContext } from "./theme-context.jsx";
4
+ import { stableRulesKey } from "./theme-provider.helpers.jsx";
5
+ function _define_property(obj, key, value) {
6
+ if (key in obj) Object.defineProperty(obj, key, {
7
+ value: value,
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true
11
+ });
12
+ else obj[key] = value;
13
+ return obj;
14
+ }
15
+ function _object_spread(target) {
16
+ for(var i = 1; i < arguments.length; i++){
17
+ var source = null != arguments[i] ? arguments[i] : {};
18
+ var ownKeys = Object.keys(source);
19
+ if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
20
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
21
+ }));
22
+ ownKeys.forEach(function(key) {
23
+ _define_property(target, key, source[key]);
24
+ });
25
+ }
26
+ return target;
27
+ }
28
+ function LunaThemeProvider(props) {
29
+ var _props_resolve, _props_resolve1, _props_resolve2, _props_resolve3;
30
+ const rulesKey = stableRulesKey(null == (_props_resolve = props.resolve) ? void 0 : _props_resolve.rules);
31
+ const resolveStable = useMemo(()=>{
32
+ var _props_resolve, _props_resolve1, _props_resolve2;
33
+ return omitUndefined({
34
+ defaultKey: null == (_props_resolve = props.resolve) ? void 0 : _props_resolve.defaultKey,
35
+ fallback: null == (_props_resolve1 = props.resolve) ? void 0 : _props_resolve1.fallback,
36
+ onEmpty: null == (_props_resolve2 = props.resolve) ? void 0 : _props_resolve2.onEmpty
37
+ });
38
+ }, [
39
+ null == (_props_resolve1 = props.resolve) ? void 0 : _props_resolve1.defaultKey,
40
+ null == (_props_resolve2 = props.resolve) ? void 0 : _props_resolve2.fallback,
41
+ null == (_props_resolve3 = props.resolve) ? void 0 : _props_resolve3.onEmpty
42
+ ]);
43
+ const singleTheme = 'theme' in props ? props.theme : void 0;
44
+ const themeList = 'themes' in props ? props.themes : void 0;
45
+ const resolvedThemeKey = 'themes' in props ? props.themeKey : void 0;
46
+ const value = useMemo(()=>{
47
+ var _props_resolve;
48
+ if ('theme' in props) {
49
+ const theme = props.theme;
50
+ return {
51
+ themeKey: theme.key,
52
+ theme
53
+ };
54
+ }
55
+ const themes = props.themes;
56
+ if (!themes || 0 === themes.length) throw new Error('[LunaThemeProvider] "themes" must be a non-empty array.');
57
+ const resolvedKey = props.themeKey;
58
+ const theme = resolveThemeObjectFromList(themes, resolvedKey, _object_spread({}, resolveStable, (null == (_props_resolve = props.resolve) ? void 0 : _props_resolve.rules) !== void 0 ? {
59
+ rules: props.resolve.rules
60
+ } : {}));
61
+ if (!theme) throw new Error('[LunaThemeProvider] Failed to resolve theme.');
62
+ return {
63
+ themeKey: theme.key,
64
+ theme
65
+ };
66
+ }, [
67
+ singleTheme,
68
+ themeList,
69
+ resolvedThemeKey,
70
+ resolveStable,
71
+ rulesKey
72
+ ]);
73
+ return <LunaThemeContext.Provider value={value}>
74
+ {props.children}
75
+ </LunaThemeContext.Provider>;
76
+ }
77
+ function omitUndefined(obj) {
78
+ const out = {};
79
+ for (const [k, v] of Object.entries(obj))if (void 0 !== v) out[k] = v;
80
+ return out;
81
+ }
82
+ export { LunaThemeProvider };
83
+
84
+ //# sourceMappingURL=theme-provider.jsx.map
@@ -0,0 +1,175 @@
1
+ import type { ReactNode } from '@lynx-js/react';
2
+ import type { LunaColorId, LunaColorKey, LunaCustomThemeKey, LunaCustomThemeMeta, LunaCustomThemeMode, LunaCustomThemeTokens, LunaCustomThemeVariant, LunaThemeResolverOptions, LunaThemeTokens } from '@lynx-js/luna-core';
3
+ export type { LunaColorId, LunaColorKey };
4
+ /**
5
+ * Values-backed theme input that provides concrete token values.
6
+ *
7
+ * Contract:
8
+ * - Provide concrete raw values (canonical truth).
9
+ * - Token values must be complete (all required ids must be present).
10
+ *
11
+ * Notes:
12
+ * - This type describes the semantic contract ("values-backed"),
13
+ * not the source mechanism (tokens).
14
+ */
15
+ export type LunaThemeValueInput = LunaThemeTokens | LunaCustomThemeTokens;
16
+ /**
17
+ * Public-friendly alias: token-driven input.
18
+ *
19
+ * @remarks
20
+ * Today values-backed inputs are provided via tokens,
21
+ * hence the name. Internally we keep "ValueInput"
22
+ * to avoid coupling the contract to a specific mechanism.
23
+ */
24
+ export type LunaThemeTokenInput = LunaThemeValueInput;
25
+ /**
26
+ * Public-friendly alias for meta-only theme input.
27
+ *
28
+ * @remarks
29
+ * Meta-only inputs do not provide concrete token values.
30
+ * They are intended for CSS-variable–only or metadata-driven
31
+ * theme definitions.
32
+ *
33
+ * Internally this maps to `LunaCustomThemeMeta`.
34
+ */
35
+ export type LunaThemeMetaInput = LunaCustomThemeMeta;
36
+ /**
37
+ * Theme inputs accepted by createLunaTheme.
38
+ *
39
+ * - `LunaThemeTokenInput` (values-backed): provides concrete token values
40
+ * - `LunaCustomThemeMeta` (meta-only): no token values
41
+ */
42
+ export type LunaThemeInput = LunaThemeValueInput | LunaThemeMetaInput;
43
+ export type LunaRuntimeThemeSourceType =
44
+ /** Values-backed input that provides concrete token values */
45
+ 'values'
46
+ /** Meta-only input without token values */
47
+ | 'meta-only';
48
+ export type LunaRuntimeThemeConsumptionFormat =
49
+ /** raw values */
50
+ 'value'
51
+ /** `var(--prefix-id)` references */
52
+ | 'var-ref';
53
+ /**
54
+ * Runtime theme object consumed by LunaThemeProvider and hooks.
55
+ *
56
+ * Key points:
57
+ * - `colors` and future surfaces like `typography` and `radii`
58
+ * store canonical raw values when `sourceType: 'values'`.
59
+ * - CSS variable references are computed on demand (from token ids),
60
+ * and should not be stored into `colors` or other value surfaces.
61
+ */
62
+ export type LunaRuntimeTheme = {
63
+ key: LunaCustomThemeKey;
64
+ variant: LunaCustomThemeVariant;
65
+ mode: LunaCustomThemeMode;
66
+ /**
67
+ * Canonical color values.
68
+ *
69
+ * - When `sourceType: 'values'`, this must be a complete raw value surface.
70
+ * - When `sourceType: 'meta-only'`, values are not available; this stays as
71
+ * the empty template for shape stability.
72
+ */
73
+ colors: Readonly<Record<LunaColorKey, string>>;
74
+ /**
75
+ * Where this runtime theme comes from.
76
+ */
77
+ sourceType: LunaRuntimeThemeSourceType;
78
+ /**
79
+ * Describe how theme values should be consumed by default.
80
+ *
81
+ * This applies to all runtime theme surfaces (e.g. `colors`,
82
+ * and future surfaces like typography, radius, or spacing).
83
+ *
84
+ * - `'value'`: consumers read raw values from runtime surfaces
85
+ * - `'var-ref'`: consumers read css-var references generated from token ids
86
+ */
87
+ consumptionFormat: LunaRuntimeThemeConsumptionFormat;
88
+ /**
89
+ * Optional metadata for css-var pipeline.
90
+ *
91
+ * If omitted, variables are generated without a prefix:
92
+ * - `'var-name'`: `--neutral`
93
+ * - `'var-ref'`: `var(--neutral)`
94
+ */
95
+ cssVarPrefix?: string;
96
+ };
97
+ export type LunaThemeContextValue = {
98
+ themeKey: LunaCustomThemeKey;
99
+ theme: LunaRuntimeTheme;
100
+ };
101
+ export type CreateLunaThemeOptions = {
102
+ /**
103
+ * Decide how theme values should be consumed by default in the runtime theme.
104
+ *
105
+ * Notes:
106
+ * - This does NOT change what is stored in `runtimeTheme.colors` or other value surfaces.
107
+ * - For values-backed inputs, `colors` always stores raw values.
108
+ * - For meta-only inputs, `'value'` is invalid.
109
+ *
110
+ * - `'value'`: default consumption uses raw values
111
+ * - `'var-ref'`: default consumption uses css-var references
112
+ *
113
+ * @defaultValue `'value'`
114
+ */
115
+ consumptionFormat?: LunaRuntimeThemeConsumptionFormat;
116
+ /**
117
+ * CSS var prefix used when consuming `'var-ref'` / generating `'var-name'`.
118
+ */
119
+ cssVarPrefix?: string;
120
+ };
121
+ type LunaThemeProviderCommonProps = {
122
+ /**
123
+ * Theme resolver options controlling resolution behavior
124
+ *
125
+ * @remarks
126
+ * Only takes effect in list mode (when `themes` is provided).
127
+ * Ignored in single-theme mode.
128
+ */
129
+ resolve?: LunaThemeResolverOptions;
130
+ children?: ReactNode;
131
+ };
132
+ export type LunaThemeProviderSingleThemeProps = {
133
+ /** Single theme entry (MUI-style) */
134
+ theme: LunaRuntimeTheme;
135
+ /** Must not be provided in single-theme mode */
136
+ themes?: never;
137
+ themeKey?: never;
138
+ } & LunaThemeProviderCommonProps;
139
+ export type LunaThemeProviderThemeListProps = {
140
+ /** Theme list for routing */
141
+ themes: LunaRuntimeTheme[];
142
+ /** Optional requested theme key */
143
+ themeKey?: LunaCustomThemeKey;
144
+ /** Must not be provided in list mode */
145
+ theme?: never;
146
+ } & LunaThemeProviderCommonProps;
147
+ export type LunaThemeProviderProps = LunaThemeProviderSingleThemeProps | LunaThemeProviderThemeListProps;
148
+ export type LunaConsumptionOptions = {
149
+ /**
150
+ * - `'result'`: return the resolved consumption result based on `format` (`'value'` or `'var-ref'`)
151
+ * - `'var-name'`: return a CSS custom property name (e.g. `--neutral`)
152
+ *
153
+ * Notes:
154
+ * - `format` only applies when `as: 'result'`.
155
+ *
156
+ * @defaultValue `'result'`
157
+ */
158
+ as?: 'result' | 'var-name';
159
+ /**
160
+ * Override how the result is produced for consumption.
161
+ *
162
+ * - `'value'`: return raw values
163
+ * - `'var-ref'`: return a CSS variable reference (e.g. `var(--neutral)`)
164
+ */
165
+ format?: LunaRuntimeThemeConsumptionFormat;
166
+ /**
167
+ * Optional override for css var prefix.
168
+ *
169
+ * If omitted, uses `theme.cssVarPrefix`.
170
+ */
171
+ cssVarPrefix?: string;
172
+ };
173
+ export type UseLunaColorOptions = LunaConsumptionOptions;
174
+ export type UseLunaColorsOptions = LunaConsumptionOptions;
175
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/theming/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAM1C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,qBAAqB,CAAC;AAE1B;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,kBAAkB,CAAC;AAMvB,MAAM,MAAM,0BAA0B;AACpC,8DAA8D;AAC5D,QAAQ;AACV,2CAA2C;GACzC,WAAW,CAAC;AAEhB,MAAM,MAAM,iCAAiC;AAC3C,iBAAiB;AACf,OAAO;AACT,oCAAoC;GAClC,SAAS,CAAC;AAEd;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,kBAAkB,CAAC;IACxB,OAAO,EAAE,sBAAsB,CAAC;IAChC,IAAI,EAAE,mBAAmB,CAAC;IAE1B;;;;;;OAMG;IACH,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAE/C;;OAEG;IACH,UAAU,EAAE,0BAA0B,CAAC;IAEvC;;;;;;;;OAQG;IACH,iBAAiB,EAAE,iCAAiC,CAAC;IAErD;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAMF,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,iCAAiC,CAAC;IAEtD;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAMF,KAAK,4BAA4B,GAAG;IAClC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,qCAAqC;IACrC,KAAK,EAAE,gBAAgB,CAAC;IAExB,gDAAgD;IAChD,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,GAAG,4BAA4B,CAAC;AAEjC,MAAM,MAAM,+BAA+B,GAAG;IAC5C,6BAA6B;IAC7B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAE3B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B,wCAAwC;IACxC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GAAG,4BAA4B,CAAC;AAEjC,MAAM,MAAM,sBAAsB,GAC9B,iCAAiC,GACjC,+BAA+B,CAAC;AAMpC,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;;;;OAQG;IACH,EAAE,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAE3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,iCAAiC,CAAC;IAE3C;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,CAAC"}
File without changes
@@ -0,0 +1,3 @@
1
+ import type { LunaColorKey, UseLunaColorOptions } from './types.js';
2
+ export declare function useLunaColor(options?: UseLunaColorOptions): (key: LunaColorKey) => string;
3
+ //# sourceMappingURL=use-color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-color.d.ts","sourceRoot":"","sources":["../../src/theming/use-color.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGpE,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAmD/B"}
@@ -0,0 +1,55 @@
1
+ import { useCallback, useMemo } from "@lynx-js/react";
2
+ import { formatMetaOnlyValueError, resolveConsumptionFormat, toVarName } from "./consumption.jsx";
3
+ import { colorKeyToColorId } from "./identity.jsx";
4
+ import { useLunaThemeContext } from "./use-theme-context.jsx";
5
+ function useLunaColor(options = {}) {
6
+ const ctx = useLunaThemeContext();
7
+ if (!ctx) throw new Error('[useLunaColor] must be used within <LunaThemeProvider>.');
8
+ const { theme } = ctx;
9
+ const { as = 'result', format, cssVarPrefix } = options;
10
+ const resolved = useMemo(()=>resolveConsumptionFormat({
11
+ as,
12
+ format,
13
+ themeFormat: theme.consumptionFormat
14
+ }), [
15
+ as,
16
+ format,
17
+ theme.consumptionFormat
18
+ ]);
19
+ const prefix = useMemo(()=>null != cssVarPrefix ? cssVarPrefix : theme.cssVarPrefix, [
20
+ cssVarPrefix,
21
+ theme.cssVarPrefix
22
+ ]);
23
+ const getColor = useCallback((key)=>{
24
+ const id = colorKeyToColorId(key);
25
+ const varName = toVarName({
26
+ id,
27
+ cssVarPrefix: prefix
28
+ });
29
+ switch(resolved.kind){
30
+ case 'var-name':
31
+ return varName;
32
+ case 'var-ref':
33
+ return `var(${varName})`;
34
+ case 'value':
35
+ if ('values' !== theme.sourceType) throw new Error(formatMetaOnlyValueError({
36
+ hook: 'useLunaColor'
37
+ }));
38
+ return theme.colors[key];
39
+ default:
40
+ return assertNever(resolved);
41
+ }
42
+ }, [
43
+ resolved,
44
+ prefix,
45
+ theme.sourceType,
46
+ theme.colors
47
+ ]);
48
+ return getColor;
49
+ }
50
+ function assertNever(x) {
51
+ throw new Error(`[useLunaColor] Unexpected resolved.kind: ${String(x)}`);
52
+ }
53
+ export { useLunaColor };
54
+
55
+ //# sourceMappingURL=use-color.jsx.map
@@ -0,0 +1,11 @@
1
+ import type { LunaColorKey, UseLunaColorsOptions } from './types.js';
2
+ /**
3
+ * Batch version of `useLunaColor`.
4
+ *
5
+ * Contract:
6
+ * - Returns an immutable snapshot.
7
+ * - In "value" mode, returns the theme's canonical colors surface.
8
+ * - In var modes, returns a derived surface (also immutable).
9
+ */
10
+ export declare function useLunaColors(options?: UseLunaColorsOptions): Readonly<Record<LunaColorKey, string>>;
11
+ //# sourceMappingURL=use-colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-colors.d.ts","sourceRoot":"","sources":["../../src/theming/use-colors.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGrE;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,GAAE,oBAAyB,GACjC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAiDxC"}
@@ -0,0 +1,45 @@
1
+ import { useMemo } from "@lynx-js/react";
2
+ import { formatMetaOnlyValueError, resolveConsumptionFormat, toVarName } from "./consumption.jsx";
3
+ import { LUNA_COLOR_KEYS, colorKeyToColorId } from "./identity.jsx";
4
+ import { useLunaThemeContext } from "./use-theme-context.jsx";
5
+ function useLunaColors(options = {}) {
6
+ const ctx = useLunaThemeContext();
7
+ if (!ctx) throw new Error('[useLunaColors] must be used within <LunaThemeProvider>.');
8
+ const { theme } = ctx;
9
+ const { as = 'result', format, cssVarPrefix } = options;
10
+ return useMemo(()=>{
11
+ const resolved = resolveConsumptionFormat({
12
+ as,
13
+ format,
14
+ themeFormat: theme.consumptionFormat
15
+ });
16
+ if ('value' === resolved.kind) {
17
+ if ('values' !== theme.sourceType) throw new Error(formatMetaOnlyValueError({
18
+ hook: 'useLunaColors'
19
+ }));
20
+ return theme.colors;
21
+ }
22
+ const prefix = null != cssVarPrefix ? cssVarPrefix : theme.cssVarPrefix;
23
+ const out = {};
24
+ for (const key of LUNA_COLOR_KEYS){
25
+ const id = colorKeyToColorId(key);
26
+ const varName = toVarName({
27
+ id,
28
+ cssVarPrefix: prefix
29
+ });
30
+ out[key] = 'var-name' === resolved.kind ? varName : `var(${varName})`;
31
+ }
32
+ return Object.freeze(out);
33
+ }, [
34
+ as,
35
+ cssVarPrefix,
36
+ format,
37
+ theme.consumptionFormat,
38
+ theme.sourceType,
39
+ theme.colors,
40
+ theme.cssVarPrefix
41
+ ]);
42
+ }
43
+ export { useLunaColors };
44
+
45
+ //# sourceMappingURL=use-colors.jsx.map
@@ -0,0 +1,7 @@
1
+ import type { LunaThemeContextValue } from './types.js';
2
+ /**
3
+ * Internal hook.
4
+ * Returns theme context or null if no provider is found.
5
+ */
6
+ export declare function useLunaThemeContext(): LunaThemeContextValue | null;
7
+ //# sourceMappingURL=use-theme-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-theme-context.d.ts","sourceRoot":"","sources":["../../src/theming/use-theme-context.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,GAAG,IAAI,CAElE"}
@@ -0,0 +1,8 @@
1
+ import { useContext } from "@lynx-js/react";
2
+ import { LunaThemeContext } from "./theme-context.jsx";
3
+ function useLunaThemeContext() {
4
+ return useContext(LunaThemeContext);
5
+ }
6
+ export { useLunaThemeContext };
7
+
8
+ //# sourceMappingURL=use-theme-context.jsx.map