@lobehub/ui 6.0.0 → 6.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.
Files changed (54) hide show
  1. package/es/Drawer/atoms.mjs +2 -1
  2. package/es/Drawer/atoms.mjs.map +1 -1
  3. package/es/DropdownMenu/atoms.mjs +2 -1
  4. package/es/DropdownMenu/atoms.mjs.map +1 -1
  5. package/es/Input/InputPassword.mjs +4 -2
  6. package/es/Input/InputPassword.mjs.map +1 -1
  7. package/es/Input/index.d.mts +2 -2
  8. package/es/Input/type.d.mts +15 -0
  9. package/es/Modal/atoms.mjs +2 -1
  10. package/es/Modal/atoms.mjs.map +1 -1
  11. package/es/Popover/PopoverInGroup.mjs +2 -1
  12. package/es/Popover/PopoverInGroup.mjs.map +1 -1
  13. package/es/Popover/atoms.mjs +2 -1
  14. package/es/Popover/atoms.mjs.map +1 -1
  15. package/es/Segmented/Segmented.mjs +2 -1
  16. package/es/Segmented/Segmented.mjs.map +1 -1
  17. package/es/Segmented/type.d.mts +7 -0
  18. package/es/Select/atoms.mjs +2 -1
  19. package/es/Select/atoms.mjs.map +1 -1
  20. package/es/Switch/Switch.mjs +2 -1
  21. package/es/Switch/Switch.mjs.map +1 -1
  22. package/es/Switch/type.d.mts +6 -2
  23. package/es/Text/style.d.mts +2 -2
  24. package/es/Tooltip/TooltipInGroup.mjs +2 -1
  25. package/es/Tooltip/TooltipInGroup.mjs.map +1 -1
  26. package/es/Tooltip/TooltipStandalone.mjs +2 -1
  27. package/es/Tooltip/TooltipStandalone.mjs.map +1 -1
  28. package/es/hooks/useNativeButton.mjs +1 -0
  29. package/es/hooks/useNativeButton.mjs.map +1 -1
  30. package/es/index.d.mts +4 -3
  31. package/es/index.mjs +3 -2
  32. package/es/styles/index.d.mts +3 -2
  33. package/es/styles/index.mjs +3 -2
  34. package/es/styles/theme/createLobeToken.d.mts +2 -2
  35. package/es/styles/theme/createLobeToken.mjs.map +1 -1
  36. package/es/styles/theme/customNeutral.d.mts +28 -0
  37. package/es/styles/theme/customNeutral.mjs +84 -0
  38. package/es/styles/theme/customNeutral.mjs.map +1 -0
  39. package/es/styles/theme/customPalette.mjs +5 -1
  40. package/es/styles/theme/customPalette.mjs.map +1 -1
  41. package/es/styles/theme/customStylishStatic.mjs +155 -145
  42. package/es/styles/theme/customStylishStatic.mjs.map +1 -1
  43. package/es/styles/theme/scope.d.mts +3 -3
  44. package/es/styles/theme/scope.mjs +55 -5
  45. package/es/styles/theme/scope.mjs.map +1 -1
  46. package/es/styles/theme/themeCss.d.mts +2 -0
  47. package/es/styles/theme/themeCss.mjs +31 -1
  48. package/es/styles/theme/themeCss.mjs.map +1 -1
  49. package/es/styles/theme/token/neutral.mjs +3 -5
  50. package/es/styles/theme/token/neutral.mjs.map +1 -1
  51. package/es/styles/theme/token/neutralText.d.mts +4 -0
  52. package/es/utils/getElementRef.mjs +17 -0
  53. package/es/utils/getElementRef.mjs.map +1 -0
  54. package/package.json +1 -1
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { getPaletteRevision, isRegisteredPalette, subscribePalettes } from "./customPalette.mjs";
3
+ import { isCustomNeutral } from "./customNeutral.mjs";
3
4
  import { isCustomPrimaryColor } from "./customPrimary.mjs";
4
5
  import { staticToken } from "./token/static.mjs";
5
6
  import { createLobeToken } from "./createLobeToken.mjs";
6
- import { getCustomPaletteCss, getCustomPrimaryCss } from "./themeCss.mjs";
7
+ import { getCustomNeutralCss, getCustomPaletteCss, getCustomPrimaryCss, getPaletteNeutralCss } from "./themeCss.mjs";
7
8
  import { createContext, use, useMemo, useSyncExternalStore } from "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region src/styles/theme/scope.tsx
@@ -29,6 +30,22 @@ const ensureCustomPrimaryStyle = (color, doc) => {
29
30
  style.textContent = getCustomPrimaryCss(color);
30
31
  doc.head.append(style);
31
32
  };
33
+ const normalizeNeutral = (color) => color?.startsWith("#") ? color.toLowerCase() : color;
34
+ /** Encodes hex vs registered name so `#0e1010` and a neutral named `0e1010` never collide. */
35
+ const neutralKey = (value) => value.startsWith("#") ? `hex-${value.slice(1)}` : `name-${value}`;
36
+ const neutralStyleId = (value) => `lobe-neutral-${neutralKey(value)}`;
37
+ /** Written every time (a re-registered neutral must replace its old rules). */
38
+ const ensureNeutralStyle = (value, doc) => {
39
+ const id = neutralStyleId(value);
40
+ let style = doc.getElementById(id);
41
+ if (!style) {
42
+ style = doc.createElement("style");
43
+ style.id = id;
44
+ doc.head.append(style);
45
+ }
46
+ const css = getCustomNeutralCss(value);
47
+ if (style.textContent !== css) style.textContent = css;
48
+ };
32
49
  const paletteStyleId = (name) => `lobe-palette-${name}`;
33
50
  const ensurePaletteStyle = (name, doc) => {
34
51
  const id = paletteStyleId(name);
@@ -41,6 +58,18 @@ const ensurePaletteStyle = (name, doc) => {
41
58
  const css = getCustomPaletteCss(name);
42
59
  if (style.textContent !== css) style.textContent = css;
43
60
  };
61
+ const paletteNeutralStyleId = (name, neutral) => `lobe-palette-${name}--neutral-${neutralKey(neutral)}`;
62
+ const ensurePaletteNeutralStyle = (name, neutral, doc) => {
63
+ const id = paletteNeutralStyleId(name, neutral);
64
+ let style = doc.getElementById(id);
65
+ if (!style) {
66
+ style = doc.createElement("style");
67
+ style.id = id;
68
+ doc.head.append(style);
69
+ }
70
+ const css = getPaletteNeutralCss(name, neutral);
71
+ if (style.textContent !== css) style.textContent = css;
72
+ };
44
73
  const setLobeTheme = (state, root = document.documentElement) => {
45
74
  const next = {
46
75
  ...readThemeState(root),
@@ -48,7 +77,12 @@ const setLobeTheme = (state, root = document.documentElement) => {
48
77
  };
49
78
  next.primaryColor = normalizePrimary(next.primaryColor);
50
79
  if (isCustomPrimaryColor(next.primaryColor)) ensureCustomPrimaryStyle(next.primaryColor, root.ownerDocument);
51
- if (isRegisteredPalette(next.palette)) ensurePaletteStyle(next.palette, root.ownerDocument);
80
+ next.neutralColor = normalizeNeutral(next.neutralColor);
81
+ if (isCustomNeutral(next.neutralColor)) ensureNeutralStyle(next.neutralColor, root.ownerDocument);
82
+ if (isRegisteredPalette(next.palette)) {
83
+ ensurePaletteStyle(next.palette, root.ownerDocument);
84
+ if (next.neutralColor) ensurePaletteNeutralStyle(next.palette, next.neutralColor, root.ownerDocument);
85
+ }
52
86
  for (const [name, value] of Object.entries(toAttributes(next))) if (value) root.setAttribute(name, value);
53
87
  else root.removeAttribute(name);
54
88
  };
@@ -85,7 +119,7 @@ const ThemeScope = ({ appearance, children, className, neutralColor, palette, pr
85
119
  const parent = useThemeState();
86
120
  const state = useMemo(() => ({
87
121
  appearance: appearance ?? parent.appearance,
88
- neutralColor: neutralColor ?? parent.neutralColor,
122
+ neutralColor: normalizeNeutral(neutralColor) ?? parent.neutralColor,
89
123
  palette: palette ?? parent.palette,
90
124
  primaryColor: normalizePrimary(primaryColor) ?? parent.primaryColor
91
125
  }), [
@@ -98,6 +132,7 @@ const ThemeScope = ({ appearance, children, className, neutralColor, palette, pr
98
132
  const customPrimary = isCustomPrimaryColor(state.primaryColor) ? state.primaryColor : void 0;
99
133
  const paletteRevision = usePaletteRevision();
100
134
  const customPalette = isRegisteredPalette(state.palette) ? state.palette : void 0;
135
+ const customNeutral = isCustomNeutral(state.neutralColor) ? state.neutralColor : void 0;
101
136
  return /* @__PURE__ */ jsxs(ThemeScopeContext, {
102
137
  value: state,
103
138
  children: [
@@ -106,11 +141,21 @@ const ThemeScope = ({ appearance, children, className, neutralColor, palette, pr
106
141
  precedence: "lobe-theme",
107
142
  children: getCustomPrimaryCss(customPrimary)
108
143
  }),
144
+ customNeutral && /* @__PURE__ */ jsx("style", {
145
+ href: `${neutralStyleId(customNeutral)}-${paletteRevision}`,
146
+ precedence: "lobe-theme",
147
+ children: getCustomNeutralCss(customNeutral)
148
+ }),
109
149
  customPalette && /* @__PURE__ */ jsx("style", {
110
150
  href: `${paletteStyleId(customPalette)}-${paletteRevision}`,
111
151
  precedence: "lobe-theme",
112
152
  children: getCustomPaletteCss(customPalette)
113
153
  }),
154
+ customPalette && state.neutralColor && /* @__PURE__ */ jsx("style", {
155
+ href: `${paletteNeutralStyleId(customPalette, state.neutralColor)}-${paletteRevision}`,
156
+ precedence: "lobe-theme",
157
+ children: getPaletteNeutralCss(customPalette, state.neutralColor)
158
+ }),
114
159
  /* @__PURE__ */ jsx("div", {
115
160
  className,
116
161
  style,
@@ -185,11 +230,16 @@ const LobeThemeScript = ({ appearance, neutralColor, nonce, palette, primaryColo
185
230
  const primary = normalizePrimary(primaryColor);
186
231
  const styles = [];
187
232
  if (isCustomPrimaryColor(primary)) styles.push([customPrimaryStyleId(primary), getCustomPrimaryCss(primary)]);
188
- if (isRegisteredPalette(palette)) styles.push([paletteStyleId(palette), getCustomPaletteCss(palette)]);
233
+ const neutral = normalizeNeutral(neutralColor);
234
+ if (isCustomNeutral(neutral)) styles.push([neutralStyleId(neutral), getCustomNeutralCss(neutral)]);
235
+ if (isRegisteredPalette(palette)) {
236
+ styles.push([paletteStyleId(palette), getCustomPaletteCss(palette)]);
237
+ if (neutral) styles.push([paletteNeutralStyleId(palette, neutral), getPaletteNeutralCss(palette, neutral)]);
238
+ }
189
239
  const script = `(function(a,p,n,q,t){var d=document.documentElement;if(a==='system')a=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';if(a)d.setAttribute('data-theme',a);else if(!d.hasAttribute('data-theme'))d.setAttribute('data-theme','light');if(p)d.setAttribute('data-primary-color',p);if(n)d.setAttribute('data-neutral-color',n);if(q)d.setAttribute('data-palette',q);t.forEach(function(x){if(document.getElementById(x[0]))return;var s=document.createElement('style');s.id=x[0];s.textContent=x[1];document.head.appendChild(s);});}).apply(null,${JSON.stringify([
190
240
  appearance ?? null,
191
241
  primary ?? null,
192
- neutralColor ?? null,
242
+ neutral ?? null,
193
243
  palette ?? null,
194
244
  styles
195
245
  ])})`;
@@ -1 +1 @@
1
- {"version":3,"file":"scope.mjs","names":[],"sources":["../../../src/styles/theme/scope.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type CSSProperties,\n type ReactNode,\n use,\n useMemo,\n useSyncExternalStore,\n} from 'react';\n\nimport type { NeutralColors } from '../customTheme';\nimport { createLobeToken, type LobeToken } from './createLobeToken';\nimport { getPaletteRevision, isRegisteredPalette, subscribePalettes } from './customPalette';\nimport {\n type CustomPrimaryColor,\n isCustomPrimaryColor,\n type LobePrimaryColor,\n} from './customPrimary';\nimport { getCustomPaletteCss, getCustomPrimaryCss } from './themeCss';\nimport { staticToken } from './token/static';\n\nexport type LobeAppearance = 'light' | 'dark';\n\nexport interface LobeThemeState {\n appearance: LobeAppearance;\n neutralColor?: NeutralColors;\n palette?: string;\n primaryColor?: LobePrimaryColor;\n}\n\nconst ATTRIBUTES = ['data-theme', 'data-primary-color', 'data-neutral-color', 'data-palette'];\n\nconst toAttributes = ({ appearance, neutralColor, palette, primaryColor }: LobeThemeState) => ({\n 'data-neutral-color': neutralColor,\n 'data-palette': palette,\n 'data-primary-color': primaryColor,\n 'data-theme': appearance,\n});\n\nconst normalizePrimary = (color?: LobePrimaryColor) =>\n isCustomPrimaryColor(color) ? (color.toLowerCase() as CustomPrimaryColor) : color;\n\nconst customPrimaryStyleId = (color: CustomPrimaryColor) => `lobe-primary-${color.slice(1)}`;\n\nconst ensureCustomPrimaryStyle = (color: CustomPrimaryColor, doc: Document) => {\n const id = customPrimaryStyleId(color);\n if (doc.getElementById(id)) return;\n const style = doc.createElement('style');\n style.id = id;\n style.textContent = getCustomPrimaryCss(color);\n doc.head.append(style);\n};\n\nconst paletteStyleId = (name: string) => `lobe-palette-${name}`;\n\nconst ensurePaletteStyle = (name: string, doc: Document) => {\n const id = paletteStyleId(name);\n let style = doc.getElementById(id);\n if (!style) {\n style = doc.createElement('style');\n style.id = id;\n doc.head.append(style);\n }\n const css = getCustomPaletteCss(name);\n if (style.textContent !== css) style.textContent = css;\n};\n\nexport const setLobeTheme = (\n state: Partial<LobeThemeState>,\n root: HTMLElement = document.documentElement,\n) => {\n const next = { ...readThemeState(root), ...state };\n next.primaryColor = normalizePrimary(next.primaryColor);\n if (isCustomPrimaryColor(next.primaryColor))\n ensureCustomPrimaryStyle(next.primaryColor, root.ownerDocument);\n if (isRegisteredPalette(next.palette)) ensurePaletteStyle(next.palette, root.ownerDocument);\n for (const [name, value] of Object.entries(toAttributes(next))) {\n if (value) root.setAttribute(name, value);\n else root.removeAttribute(name);\n }\n};\n\nconst readThemeState = (el: HTMLElement): LobeThemeState => ({\n appearance: el.dataset.theme === 'dark' ? 'dark' : 'light',\n neutralColor: (el.dataset.neutralColor as NeutralColors) || undefined,\n palette: el.dataset.palette || undefined,\n primaryColor: (el.dataset.primaryColor as LobePrimaryColor) || undefined,\n});\n\nconst stateKey = (state: LobeThemeState) =>\n `${state.appearance}|${state.primaryColor ?? ''}|${state.neutralColor ?? ''}|${state.palette ?? ''}`;\n\nconst usePaletteRevision = () =>\n useSyncExternalStore(subscribePalettes, getPaletteRevision, getPaletteRevision);\n\nconst SERVER_STATE: LobeThemeState = { appearance: 'light' };\nlet rootSnapshot: LobeThemeState = SERVER_STATE;\n\nconst getRootSnapshot = () => {\n const next = readThemeState(document.documentElement);\n if (stateKey(next) !== stateKey(rootSnapshot)) rootSnapshot = next;\n return rootSnapshot;\n};\n\nconst subscribeRoot = (onChange: () => void) => {\n const observer = new MutationObserver(onChange);\n observer.observe(document.documentElement, { attributeFilter: ATTRIBUTES, attributes: true });\n return () => observer.disconnect();\n};\n\nconst ThemeScopeContext = createContext<LobeThemeState | null>(null);\n\nconst useThemeState = () => {\n const scoped = use(ThemeScopeContext);\n const root = useSyncExternalStore(subscribeRoot, getRootSnapshot, () => SERVER_STATE);\n return scoped ?? root;\n};\n\nexport interface ThemeScopeProps extends Partial<LobeThemeState> {\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nexport const ThemeScope = ({\n appearance,\n children,\n className,\n neutralColor,\n palette,\n primaryColor,\n style,\n}: ThemeScopeProps) => {\n const parent = useThemeState();\n const state = useMemo<LobeThemeState>(\n () => ({\n appearance: appearance ?? parent.appearance,\n neutralColor: neutralColor ?? parent.neutralColor,\n palette: palette ?? parent.palette,\n primaryColor: normalizePrimary(primaryColor) ?? parent.primaryColor,\n }),\n [appearance, neutralColor, palette, primaryColor, parent],\n );\n const customPrimary = isCustomPrimaryColor(state.primaryColor) ? state.primaryColor : undefined;\n const paletteRevision = usePaletteRevision();\n const customPalette = isRegisteredPalette(state.palette) ? state.palette : undefined;\n\n return (\n <ThemeScopeContext value={state}>\n {customPrimary && (\n <style href={customPrimaryStyleId(customPrimary)} precedence=\"lobe-theme\">\n {getCustomPrimaryCss(customPrimary)}\n </style>\n )}\n {customPalette && (\n <style href={`${paletteStyleId(customPalette)}-${paletteRevision}`} precedence=\"lobe-theme\">\n {getCustomPaletteCss(customPalette)}\n </style>\n )}\n <div className={className} style={style} {...toAttributes(state)}>\n {children}\n </div>\n </ThemeScopeContext>\n );\n};\n\nexport const useThemeMode = () => {\n const { appearance } = useThemeState();\n return useMemo(() => ({ appearance, isDarkMode: appearance === 'dark' }), [appearance]);\n};\n\nexport type LobeTheme = LobeToken & { appearance: LobeAppearance; isDarkMode: boolean };\n\nconst themeCache = new Map<string, LobeTheme>();\n\nexport const useTheme = (): LobeTheme => {\n const state = useThemeState();\n const key = `${stateKey(state)}@${usePaletteRevision()}`;\n let theme = themeCache.get(key);\n if (!theme) {\n theme = {\n ...createLobeToken(state),\n appearance: state.appearance,\n isDarkMode: state.appearance === 'dark',\n };\n themeCache.set(key, theme);\n }\n return theme;\n};\n\nconst breakpointQueries = {\n lg: `(min-width: ${staticToken.screenLG}px)`,\n md: `(min-width: ${staticToken.screenMD}px)`,\n sm: `(min-width: ${staticToken.screenSM}px)`,\n xl: `(min-width: ${staticToken.screenXL}px)`,\n xs: `(max-width: ${staticToken.screenXSMax}px)`,\n xxl: `(min-width: ${staticToken.screenXXL}px)`,\n xxxl: `(min-width: ${staticToken.screenXXXL}px)`,\n};\n\ntype Breakpoint = keyof typeof breakpointQueries;\nexport type ResponsiveState = Record<\n Breakpoint | 'mobile' | 'tablet' | 'laptop' | 'desktop',\n boolean\n>;\n\nconst toResponsive = (matches: Record<Breakpoint, boolean>): ResponsiveState => ({\n ...matches,\n desktop: matches.xxl,\n laptop: matches.lg,\n mobile: matches.xs,\n tablet: matches.md,\n});\n\nconst SERVER_RESPONSIVE = toResponsive({\n lg: false,\n md: false,\n sm: false,\n xl: false,\n xs: false,\n xxl: false,\n xxxl: false,\n});\nlet responsiveSnapshot = SERVER_RESPONSIVE;\n\nconst getResponsiveSnapshot = () => {\n const matches = Object.fromEntries(\n Object.entries(breakpointQueries).map(([key, query]) => [key, matchMedia(query).matches]),\n ) as Record<Breakpoint, boolean>;\n const changed = (Object.keys(matches) as Breakpoint[]).some(\n (key) => matches[key] !== responsiveSnapshot[key],\n );\n if (changed) responsiveSnapshot = toResponsive(matches);\n return responsiveSnapshot;\n};\n\nconst subscribeResponsive = (onChange: () => void) => {\n const lists = Object.values(breakpointQueries).map((query) => matchMedia(query));\n for (const list of lists) list.addEventListener('change', onChange);\n return () => {\n for (const list of lists) list.removeEventListener('change', onChange);\n };\n};\n\nexport const useResponsive = () =>\n useSyncExternalStore(subscribeResponsive, getResponsiveSnapshot, () => SERVER_RESPONSIVE);\n\nexport interface LobeThemeScriptProps {\n appearance?: LobeAppearance | 'system';\n neutralColor?: NeutralColors;\n nonce?: string;\n palette?: string;\n primaryColor?: LobePrimaryColor;\n}\n\nexport const LobeThemeScript = ({\n appearance,\n neutralColor,\n nonce,\n palette,\n primaryColor,\n}: LobeThemeScriptProps) => {\n const primary = normalizePrimary(primaryColor);\n const styles: [string, string][] = [];\n if (isCustomPrimaryColor(primary))\n styles.push([customPrimaryStyleId(primary), getCustomPrimaryCss(primary)]);\n if (isRegisteredPalette(palette))\n styles.push([paletteStyleId(palette), getCustomPaletteCss(palette)]);\n const args = JSON.stringify([\n appearance ?? null,\n primary ?? null,\n neutralColor ?? null,\n palette ?? null,\n styles,\n ]);\n const script = `(function(a,p,n,q,t){var d=document.documentElement;if(a==='system')a=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';if(a)d.setAttribute('data-theme',a);else if(!d.hasAttribute('data-theme'))d.setAttribute('data-theme','light');if(p)d.setAttribute('data-primary-color',p);if(n)d.setAttribute('data-neutral-color',n);if(q)d.setAttribute('data-palette',q);t.forEach(function(x){if(document.getElementById(x[0]))return;var s=document.createElement('style');s.id=x[0];s.textContent=x[1];document.head.appendChild(s);});}).apply(null,${args})`;\n\n return (\n <script suppressHydrationWarning dangerouslySetInnerHTML={{ __html: script }} nonce={nonce} />\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"scope.mjs","names":[],"sources":["../../../src/styles/theme/scope.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type CSSProperties,\n type ReactNode,\n use,\n useMemo,\n useSyncExternalStore,\n} from 'react';\n\nimport { createLobeToken, type LobeToken } from './createLobeToken';\nimport { isCustomNeutral, type LobeNeutralColor } from './customNeutral';\nimport { getPaletteRevision, isRegisteredPalette, subscribePalettes } from './customPalette';\nimport {\n type CustomPrimaryColor,\n isCustomPrimaryColor,\n type LobePrimaryColor,\n} from './customPrimary';\nimport {\n getCustomNeutralCss,\n getCustomPaletteCss,\n getCustomPrimaryCss,\n getPaletteNeutralCss,\n} from './themeCss';\nimport { staticToken } from './token/static';\n\nexport type LobeAppearance = 'light' | 'dark';\n\nexport interface LobeThemeState {\n appearance: LobeAppearance;\n neutralColor?: LobeNeutralColor;\n palette?: string;\n primaryColor?: LobePrimaryColor;\n}\n\nconst ATTRIBUTES = ['data-theme', 'data-primary-color', 'data-neutral-color', 'data-palette'];\n\nconst toAttributes = ({ appearance, neutralColor, palette, primaryColor }: LobeThemeState) => ({\n 'data-neutral-color': neutralColor,\n 'data-palette': palette,\n 'data-primary-color': primaryColor,\n 'data-theme': appearance,\n});\n\nconst normalizePrimary = (color?: LobePrimaryColor) =>\n isCustomPrimaryColor(color) ? (color.toLowerCase() as CustomPrimaryColor) : color;\n\nconst customPrimaryStyleId = (color: CustomPrimaryColor) => `lobe-primary-${color.slice(1)}`;\n\nconst ensureCustomPrimaryStyle = (color: CustomPrimaryColor, doc: Document) => {\n const id = customPrimaryStyleId(color);\n if (doc.getElementById(id)) return;\n const style = doc.createElement('style');\n style.id = id;\n style.textContent = getCustomPrimaryCss(color);\n doc.head.append(style);\n};\n\nconst normalizeNeutral = (color?: LobeNeutralColor) =>\n color?.startsWith('#') ? color.toLowerCase() : color;\n\n/** Encodes hex vs registered name so `#0e1010` and a neutral named `0e1010` never collide. */\nconst neutralKey = (value: string) =>\n value.startsWith('#') ? `hex-${value.slice(1)}` : `name-${value}`;\n\nconst neutralStyleId = (value: string) => `lobe-neutral-${neutralKey(value)}`;\n\n/** Written every time (a re-registered neutral must replace its old rules). */\nconst ensureNeutralStyle = (value: string, doc: Document) => {\n const id = neutralStyleId(value);\n let style = doc.getElementById(id);\n if (!style) {\n style = doc.createElement('style');\n style.id = id;\n doc.head.append(style);\n }\n const css = getCustomNeutralCss(value);\n if (style.textContent !== css) style.textContent = css;\n};\n\nconst paletteStyleId = (name: string) => `lobe-palette-${name}`;\n\nconst ensurePaletteStyle = (name: string, doc: Document) => {\n const id = paletteStyleId(name);\n let style = doc.getElementById(id);\n if (!style) {\n style = doc.createElement('style');\n style.id = id;\n doc.head.append(style);\n }\n const css = getCustomPaletteCss(name);\n if (style.textContent !== css) style.textContent = css;\n};\n\nconst paletteNeutralStyleId = (name: string, neutral: string) =>\n `lobe-palette-${name}--neutral-${neutralKey(neutral)}`;\n\nconst ensurePaletteNeutralStyle = (name: string, neutral: string, doc: Document) => {\n const id = paletteNeutralStyleId(name, neutral);\n let style = doc.getElementById(id);\n if (!style) {\n style = doc.createElement('style');\n style.id = id;\n doc.head.append(style);\n }\n const css = getPaletteNeutralCss(name, neutral);\n if (style.textContent !== css) style.textContent = css;\n};\n\nexport const setLobeTheme = (\n state: Partial<LobeThemeState>,\n root: HTMLElement = document.documentElement,\n) => {\n const next = { ...readThemeState(root), ...state };\n next.primaryColor = normalizePrimary(next.primaryColor);\n if (isCustomPrimaryColor(next.primaryColor))\n ensureCustomPrimaryStyle(next.primaryColor, root.ownerDocument);\n next.neutralColor = normalizeNeutral(next.neutralColor);\n if (isCustomNeutral(next.neutralColor)) ensureNeutralStyle(next.neutralColor, root.ownerDocument);\n if (isRegisteredPalette(next.palette)) {\n ensurePaletteStyle(next.palette, root.ownerDocument);\n if (next.neutralColor)\n ensurePaletteNeutralStyle(next.palette, next.neutralColor, root.ownerDocument);\n }\n for (const [name, value] of Object.entries(toAttributes(next))) {\n if (value) root.setAttribute(name, value);\n else root.removeAttribute(name);\n }\n};\n\nconst readThemeState = (el: HTMLElement): LobeThemeState => ({\n appearance: el.dataset.theme === 'dark' ? 'dark' : 'light',\n neutralColor: el.dataset.neutralColor || undefined,\n palette: el.dataset.palette || undefined,\n primaryColor: (el.dataset.primaryColor as LobePrimaryColor) || undefined,\n});\n\nconst stateKey = (state: LobeThemeState) =>\n `${state.appearance}|${state.primaryColor ?? ''}|${state.neutralColor ?? ''}|${state.palette ?? ''}`;\n\nconst usePaletteRevision = () =>\n useSyncExternalStore(subscribePalettes, getPaletteRevision, getPaletteRevision);\n\nconst SERVER_STATE: LobeThemeState = { appearance: 'light' };\nlet rootSnapshot: LobeThemeState = SERVER_STATE;\n\nconst getRootSnapshot = () => {\n const next = readThemeState(document.documentElement);\n if (stateKey(next) !== stateKey(rootSnapshot)) rootSnapshot = next;\n return rootSnapshot;\n};\n\nconst subscribeRoot = (onChange: () => void) => {\n const observer = new MutationObserver(onChange);\n observer.observe(document.documentElement, { attributeFilter: ATTRIBUTES, attributes: true });\n return () => observer.disconnect();\n};\n\nconst ThemeScopeContext = createContext<LobeThemeState | null>(null);\n\nconst useThemeState = () => {\n const scoped = use(ThemeScopeContext);\n const root = useSyncExternalStore(subscribeRoot, getRootSnapshot, () => SERVER_STATE);\n return scoped ?? root;\n};\n\nexport interface ThemeScopeProps extends Partial<LobeThemeState> {\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nexport const ThemeScope = ({\n appearance,\n children,\n className,\n neutralColor,\n palette,\n primaryColor,\n style,\n}: ThemeScopeProps) => {\n const parent = useThemeState();\n const state = useMemo<LobeThemeState>(\n () => ({\n appearance: appearance ?? parent.appearance,\n neutralColor: normalizeNeutral(neutralColor) ?? parent.neutralColor,\n palette: palette ?? parent.palette,\n primaryColor: normalizePrimary(primaryColor) ?? parent.primaryColor,\n }),\n [appearance, neutralColor, palette, primaryColor, parent],\n );\n const customPrimary = isCustomPrimaryColor(state.primaryColor) ? state.primaryColor : undefined;\n const paletteRevision = usePaletteRevision();\n const customPalette = isRegisteredPalette(state.palette) ? state.palette : undefined;\n const customNeutral = isCustomNeutral(state.neutralColor) ? state.neutralColor : undefined;\n\n return (\n <ThemeScopeContext value={state}>\n {customPrimary && (\n <style href={customPrimaryStyleId(customPrimary)} precedence=\"lobe-theme\">\n {getCustomPrimaryCss(customPrimary)}\n </style>\n )}\n {customNeutral && (\n <style href={`${neutralStyleId(customNeutral)}-${paletteRevision}`} precedence=\"lobe-theme\">\n {getCustomNeutralCss(customNeutral)}\n </style>\n )}\n {customPalette && (\n <style href={`${paletteStyleId(customPalette)}-${paletteRevision}`} precedence=\"lobe-theme\">\n {getCustomPaletteCss(customPalette)}\n </style>\n )}\n {customPalette && state.neutralColor && (\n <style\n href={`${paletteNeutralStyleId(customPalette, state.neutralColor)}-${paletteRevision}`}\n precedence=\"lobe-theme\"\n >\n {getPaletteNeutralCss(customPalette, state.neutralColor)}\n </style>\n )}\n <div className={className} style={style} {...toAttributes(state)}>\n {children}\n </div>\n </ThemeScopeContext>\n );\n};\n\nexport const useThemeMode = () => {\n const { appearance } = useThemeState();\n return useMemo(() => ({ appearance, isDarkMode: appearance === 'dark' }), [appearance]);\n};\n\nexport type LobeTheme = LobeToken & { appearance: LobeAppearance; isDarkMode: boolean };\n\nconst themeCache = new Map<string, LobeTheme>();\n\nexport const useTheme = (): LobeTheme => {\n const state = useThemeState();\n const key = `${stateKey(state)}@${usePaletteRevision()}`;\n let theme = themeCache.get(key);\n if (!theme) {\n theme = {\n ...createLobeToken(state),\n appearance: state.appearance,\n isDarkMode: state.appearance === 'dark',\n };\n themeCache.set(key, theme);\n }\n return theme;\n};\n\nconst breakpointQueries = {\n lg: `(min-width: ${staticToken.screenLG}px)`,\n md: `(min-width: ${staticToken.screenMD}px)`,\n sm: `(min-width: ${staticToken.screenSM}px)`,\n xl: `(min-width: ${staticToken.screenXL}px)`,\n xs: `(max-width: ${staticToken.screenXSMax}px)`,\n xxl: `(min-width: ${staticToken.screenXXL}px)`,\n xxxl: `(min-width: ${staticToken.screenXXXL}px)`,\n};\n\ntype Breakpoint = keyof typeof breakpointQueries;\nexport type ResponsiveState = Record<\n Breakpoint | 'mobile' | 'tablet' | 'laptop' | 'desktop',\n boolean\n>;\n\nconst toResponsive = (matches: Record<Breakpoint, boolean>): ResponsiveState => ({\n ...matches,\n desktop: matches.xxl,\n laptop: matches.lg,\n mobile: matches.xs,\n tablet: matches.md,\n});\n\nconst SERVER_RESPONSIVE = toResponsive({\n lg: false,\n md: false,\n sm: false,\n xl: false,\n xs: false,\n xxl: false,\n xxxl: false,\n});\nlet responsiveSnapshot = SERVER_RESPONSIVE;\n\nconst getResponsiveSnapshot = () => {\n const matches = Object.fromEntries(\n Object.entries(breakpointQueries).map(([key, query]) => [key, matchMedia(query).matches]),\n ) as Record<Breakpoint, boolean>;\n const changed = (Object.keys(matches) as Breakpoint[]).some(\n (key) => matches[key] !== responsiveSnapshot[key],\n );\n if (changed) responsiveSnapshot = toResponsive(matches);\n return responsiveSnapshot;\n};\n\nconst subscribeResponsive = (onChange: () => void) => {\n const lists = Object.values(breakpointQueries).map((query) => matchMedia(query));\n for (const list of lists) list.addEventListener('change', onChange);\n return () => {\n for (const list of lists) list.removeEventListener('change', onChange);\n };\n};\n\nexport const useResponsive = () =>\n useSyncExternalStore(subscribeResponsive, getResponsiveSnapshot, () => SERVER_RESPONSIVE);\n\nexport interface LobeThemeScriptProps {\n appearance?: LobeAppearance | 'system';\n neutralColor?: LobeNeutralColor;\n nonce?: string;\n palette?: string;\n primaryColor?: LobePrimaryColor;\n}\n\nexport const LobeThemeScript = ({\n appearance,\n neutralColor,\n nonce,\n palette,\n primaryColor,\n}: LobeThemeScriptProps) => {\n const primary = normalizePrimary(primaryColor);\n const styles: [string, string][] = [];\n if (isCustomPrimaryColor(primary))\n styles.push([customPrimaryStyleId(primary), getCustomPrimaryCss(primary)]);\n const neutral = normalizeNeutral(neutralColor);\n if (isCustomNeutral(neutral))\n styles.push([neutralStyleId(neutral), getCustomNeutralCss(neutral)]);\n if (isRegisteredPalette(palette)) {\n styles.push([paletteStyleId(palette), getCustomPaletteCss(palette)]);\n if (neutral)\n styles.push([\n paletteNeutralStyleId(palette, neutral),\n getPaletteNeutralCss(palette, neutral),\n ]);\n }\n const args = JSON.stringify([\n appearance ?? null,\n primary ?? null,\n neutral ?? null,\n palette ?? null,\n styles,\n ]);\n const script = `(function(a,p,n,q,t){var d=document.documentElement;if(a==='system')a=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';if(a)d.setAttribute('data-theme',a);else if(!d.hasAttribute('data-theme'))d.setAttribute('data-theme','light');if(p)d.setAttribute('data-primary-color',p);if(n)d.setAttribute('data-neutral-color',n);if(q)d.setAttribute('data-palette',q);t.forEach(function(x){if(document.getElementById(x[0]))return;var s=document.createElement('style');s.id=x[0];s.textContent=x[1];document.head.appendChild(s);});}).apply(null,${args})`;\n\n return (\n <script suppressHydrationWarning dangerouslySetInnerHTML={{ __html: script }} nonce={nonce} />\n );\n};\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { CustomPrimaryColor } from "./customPrimary.mjs";
2
2
  //#region src/styles/theme/themeCss.d.ts
3
3
  export declare const getCustomPrimaryCss: (color: CustomPrimaryColor) => string;
4
+ /** CSS for a custom neutral (6-digit hex or a `registerLobeNeutral` name); '' for presets. */
5
+ export declare const getCustomNeutralCss: (value: string) => string;
4
6
  export declare const getCustomPaletteCss: (name: string) => string;
5
7
  export declare const getThemeCss: () => string;
6
8
  export declare const getGlobalCss: () => string;
@@ -1,4 +1,5 @@
1
1
  import { isRegisteredPalette } from "./customPalette.mjs";
2
+ import { isCustomNeutral } from "./customNeutral.mjs";
2
3
  import { neutralColors, primaryColors } from "../customTheme.mjs";
3
4
  import { createLobeTokenGroups } from "./createLobeToken.mjs";
4
5
  import { toCssVarName, toCssVariables } from "../css.mjs";
@@ -57,6 +58,15 @@ const getCustomPrimaryCss = (color) => {
57
58
  primaryColor: hex
58
59
  }).primary))).join("\n\n");
59
60
  };
61
+ /** CSS for a custom neutral (6-digit hex or a `registerLobeNeutral` name); '' for presets. */
62
+ const getCustomNeutralCss = (value) => {
63
+ const key = value.startsWith("#") ? value.toLowerCase() : value;
64
+ if (!isCustomNeutral(key)) return "";
65
+ return ["light", "dark"].map((appearance) => rule(`[data-neutral-color='${key}']${appearanceSelector(appearance)}`, toCssVariables(createLobeTokenGroups({
66
+ appearance,
67
+ neutralColor: key
68
+ }).neutral))).join("\n\n");
69
+ };
60
70
  const getCustomPaletteCss = (name) => {
61
71
  if (!isRegisteredPalette(name)) return "";
62
72
  return ["light", "dark"].map((appearance) => {
@@ -71,6 +81,26 @@ const getCustomPaletteCss = (name) => {
71
81
  }));
72
82
  }).join("\n\n");
73
83
  };
84
+ /**
85
+ * The outline tokens depend on both the neutral and the status palette, so the standalone
86
+ * neutral / palette stylesheets each compute them against the other's default. This rule
87
+ * (higher specificity) recomputes them for the actual combination.
88
+ */
89
+ const getPaletteNeutralCss = (name, neutralColor) => {
90
+ if (!isRegisteredPalette(name) || !neutralColor) return "";
91
+ const key = neutralColor.startsWith("#") ? neutralColor.toLowerCase() : neutralColor;
92
+ return ["light", "dark"].map((appearance) => {
93
+ const { neutral } = createLobeTokenGroups({
94
+ appearance,
95
+ neutralColor: key,
96
+ palette: name
97
+ });
98
+ return rule(`[data-palette='${name}'][data-neutral-color='${key}']${appearanceSelector(appearance)}`, toCssVariables({
99
+ colorErrorOutline: neutral.colorErrorOutline,
100
+ colorWarningOutline: neutral.colorWarningOutline
101
+ }));
102
+ }).join("\n\n");
103
+ };
74
104
  const essentialCss = `@layer lobe-ui {
75
105
  .lobe-brand-loading path {
76
106
  fill: currentcolor;
@@ -350,6 +380,6 @@ const getThemeCss = () => cached ??= [
350
380
  ].join("\n\n");
351
381
  const getGlobalCss = () => `${layerOrder}\n\n${globalCss}`;
352
382
  //#endregion
353
- export { getCustomPaletteCss, getCustomPrimaryCss, getGlobalCss, getThemeCss };
383
+ export { getCustomNeutralCss, getCustomPaletteCss, getCustomPrimaryCss, getGlobalCss, getPaletteNeutralCss, getThemeCss };
354
384
 
355
385
  //# sourceMappingURL=themeCss.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"themeCss.mjs","names":[],"sources":["../../../src/styles/theme/themeCss.ts"],"sourcesContent":["import { toCssVariables, toCssVarName } from '../css';\nimport { neutralColors, primaryColors } from '../customTheme';\nimport { createLobeTokenGroups } from './createLobeToken';\nimport { isRegisteredPalette } from './customPalette';\nimport type { CustomPrimaryColor } from './customPrimary';\nimport type { LobeAppearance } from './scope';\n\nconst v = (key: string) => `var(${toCssVarName(key)})`;\n\nconst ring: Record<LobeAppearance, string> = {\n dark: '0 0 0 1px rgb(255 255 255 / 18%)',\n light: '0 0 0 1px rgb(0 0 0 / 5%)',\n};\n\n/* `initial` makes a light scope nested in a dark one fall back to each variant's own fill\n instead of inheriting the dark table surface. */\nconst surface: Record<LobeAppearance, Record<string, string>> = {\n dark: {\n '--lobe-fill-border': v('colorFillSecondary'),\n '--lobe-fill-border-strong': v('colorFill'),\n '--lobe-table-cell-bg': 'transparent',\n '--lobe-table-surface': v('colorFillQuaternary'),\n },\n light: {\n '--lobe-fill-border': v('colorFill'),\n '--lobe-fill-border-strong': `color-mix(in srgb, ${v('colorFill')}, ${v('colorText')} 15%)`,\n '--lobe-table-cell-bg': 'initial',\n '--lobe-table-surface': 'initial',\n },\n};\n\nconst rule = (selector: string, declarations: Record<string, number | string>) =>\n `${selector} {\\n${Object.entries(declarations)\n .map(([name, value]) => ` ${name}: ${value};`)\n .join('\\n')}\\n}`;\n\nconst appearanceRule = (selector: string, appearance: LobeAppearance) => {\n const { neutral, palette, primary, static: base } = createLobeTokenGroups({ appearance });\n const token =\n appearance === 'light'\n ? { ...base, ...palette, ...primary, ...neutral }\n : { ...palette, ...primary, ...neutral };\n\n return rule(selector, {\n ...toCssVariables(token),\n '--lobe-ring': ring[appearance],\n ...surface[appearance],\n 'color-scheme': appearance,\n });\n};\n\nconst appearanceSelector = (appearance: LobeAppearance) =>\n appearance === 'dark' ? \"[data-theme='dark']\" : \":not([data-theme='dark'])\";\n\nconst colorRules = (appearance: LobeAppearance) => [\n ...(Object.keys(primaryColors) as (keyof typeof primaryColors)[]).map((primaryColor) =>\n rule(\n `[data-primary-color='${primaryColor}']${appearanceSelector(appearance)}`,\n toCssVariables(createLobeTokenGroups({ appearance, primaryColor }).primary),\n ),\n ),\n ...(Object.keys(neutralColors) as (keyof typeof neutralColors)[]).map((neutralColor) =>\n rule(\n `[data-neutral-color='${neutralColor}']${appearanceSelector(appearance)}`,\n toCssVariables(createLobeTokenGroups({ appearance, neutralColor }).neutral),\n ),\n ),\n];\n\nexport const getCustomPrimaryCss = (color: CustomPrimaryColor) => {\n const hex = color.toLowerCase();\n return (['light', 'dark'] as const)\n .map((appearance) =>\n rule(\n `[data-primary-color='${hex}']${appearanceSelector(appearance)}`,\n toCssVariables(\n createLobeTokenGroups({ appearance, primaryColor: hex as CustomPrimaryColor }).primary,\n ),\n ),\n )\n .join('\\n\\n');\n};\n\nexport const getCustomPaletteCss = (name: string) => {\n if (!isRegisteredPalette(name)) return '';\n return (['light', 'dark'] as const)\n .map((appearance) => {\n const { neutral, palette } = createLobeTokenGroups({ appearance, palette: name });\n return rule(\n `[data-palette='${name}']${appearanceSelector(appearance)}`,\n toCssVariables({\n ...palette,\n colorErrorOutline: neutral.colorErrorOutline,\n colorWarningOutline: neutral.colorWarningOutline,\n }),\n );\n })\n .join('\\n\\n');\n};\n\nconst essentialCss = `@layer lobe-ui {\n .lobe-brand-loading path {\n fill: currentcolor;\n fill-opacity: 0;\n stroke: currentcolor;\n stroke-dasharray: 1000;\n stroke-dashoffset: 1000;\n stroke-width: 0.25em;\n\n animation:\n draw 2s cubic-bezier(0.4, 0, 0.2, 1) infinite,\n fill 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;\n }\n}\n\n@layer lobe-popup {\n .lobe-context-trigger[data-popup-open],\n .lobe-dropdown-menu-trigger[data-popup-open] {\n background: ${v('colorFillTertiary')};\n }\n}\n\n@layer lobe-base {\n :where(body, body [data-theme]) {\n color: ${v('colorText')};\n font-family: ${v('fontFamily')};\n font-size: ${v('fontSize')};\n line-height: ${v('lineHeight')};\n }\n\n :where(body) :where(a) {\n cursor: pointer;\n\n color: ${v('colorLink')};\n text-decoration: none;\n\n background-color: transparent;\n outline: none;\n\n transition: color ${v('motionDurationSlow')};\n }\n\n :where(body) :where(a):hover {\n color: ${v('colorLinkHover')};\n }\n\n :where(body) :where(a):active {\n color: ${v('colorLinkActive')};\n }\n\n :where(body) :where(a):focus-visible {\n outline: ${v('lineWidthFocus')} solid ${v('colorPrimaryBorder')};\n outline-offset: 1px;\n }\n\n :where(body) :where(a)[disabled] {\n cursor: not-allowed;\n color: ${v('colorTextDisabled')};\n }\n\n :where(.lobe-flex) {\n --lobe-flex: 0 1 auto;\n --lobe-flex-direction: column;\n --lobe-flex-wrap: nowrap;\n --lobe-flex-justify: flex-start;\n --lobe-flex-align: stretch;\n --lobe-flex-width: auto;\n --lobe-flex-height: auto;\n --lobe-flex-padding: 0;\n --lobe-flex-padding-inline: var(--lobe-flex-padding);\n --lobe-flex-padding-block: var(--lobe-flex-padding);\n --lobe-flex-gap: 0;\n\n display: flex;\n flex: var(--lobe-flex);\n flex-flow: var(--lobe-flex-direction) var(--lobe-flex-wrap);\n gap: var(--lobe-flex-gap);\n align-items: var(--lobe-flex-align);\n justify-content: var(--lobe-flex-justify);\n\n width: var(--lobe-flex-width);\n height: var(--lobe-flex-height);\n padding: var(--lobe-flex-padding);\n padding-block: var(--lobe-flex-padding-block);\n padding-inline: var(--lobe-flex-padding-inline);\n }\n\n .lobe-flex-hidden {\n display: none;\n }\n}\n\n@keyframes draw {\n 0% {\n stroke-dashoffset: 1000;\n }\n\n 100% {\n stroke-dashoffset: 0;\n }\n}\n\n@keyframes fill {\n 30% {\n fill-opacity: 0.05;\n }\n\n 100% {\n fill-opacity: 1;\n }\n}`;\n\nconst globalCss = `@layer lobe-base {\n :root {\n --font-settings: 'cv01', 'tnum', 'kern';\n --font-variations: 'opsz' auto, tabular-nums;\n\n font-synthesis: style;\n text-autospace: normal;\n }\n\n html {\n overscroll-behavior: none;\n }\n\n body {\n overflow: hidden auto;\n\n min-height: 100vh;\n margin: 0;\n padding: 0;\n\n font-feature-settings: var(--font-settings);\n font-variation-settings: var(--font-variations);\n font-optical-sizing: auto;\n font-kerning: normal;\n font-variant-ligatures: common-ligatures contextual;\n font-variant-numeric: tabular-nums;\n font-size-adjust: from-font;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-wrap: pretty;\n text-size-adjust: 100%;\n text-rendering: optimizelegibility;\n overflow-wrap: anywhere;\n vertical-align: baseline;\n\n background-color: ${v('colorBgLayout')};\n\n font-synthesis: style;\n\n -webkit-overflow-scrolling: touch;\n -webkit-tap-highlight-color: transparent;\n }\n\n html,\n body {\n width: 100%;\n height: 100%;\n }\n\n [tabindex='-1']:focus {\n outline: none;\n }\n\n [hidden] {\n display: none !important;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: 0 0.5em;\n font-weight: 500;\n }\n\n p,\n ol,\n ul,\n dl,\n pre {\n margin-block: 0 1em;\n }\n\n ol ol,\n ul ul,\n ol ul,\n ul ol {\n margin-block-end: 0;\n }\n\n dd {\n margin-block-end: 0.5em;\n margin-inline-start: 0;\n }\n\n blockquote,\n figure {\n margin-block: 0 1em;\n margin-inline: 0;\n }\n\n img {\n border-style: none;\n vertical-align: middle;\n }\n\n table {\n border-collapse: collapse;\n }\n\n input,\n button,\n select,\n optgroup,\n textarea {\n margin: 0;\n\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n color: inherit;\n }\n\n textarea {\n resize: vertical;\n overflow: auto;\n }\n\n fieldset {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n }\n\n code,\n kbd,\n samp,\n pre {\n font-family: ${v('fontFamilyCode')} !important;\n font-feature-settings:\n 'liga' 0,\n 'calt' 0;\n font-variant-ligatures: none;\n\n span {\n font-family: ${v('fontFamilyCode')} !important;\n }\n }\n\n ::selection {\n color: #000;\n background: ${v('yellow9')};\n\n -webkit-text-fill-color: unset !important;\n }\n\n * {\n scrollbar-color: ${v('colorFill')} transparent;\n scrollbar-width: thin;\n box-sizing: border-box;\n vertical-align: baseline;\n }\n}`;\n\nconst layerOrder = '@layer lobe-base, lobe-popup, lobe-ui;';\n\nlet cached: string | undefined;\n\nexport const getThemeCss = () =>\n (cached ??= [\n layerOrder,\n appearanceRule(\":root, [data-theme='light']\", 'light'),\n appearanceRule(\"[data-theme='dark']\", 'dark'),\n ...colorRules('light'),\n ...colorRules('dark'),\n essentialCss,\n ].join('\\n\\n'));\n\nexport const getGlobalCss = () => `${layerOrder}\\n\\n${globalCss}`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"themeCss.mjs","names":[],"sources":["../../../src/styles/theme/themeCss.ts"],"sourcesContent":["import { toCssVariables, toCssVarName } from '../css';\nimport { neutralColors, primaryColors } from '../customTheme';\nimport { createLobeTokenGroups } from './createLobeToken';\nimport { isCustomNeutral } from './customNeutral';\nimport { isRegisteredPalette } from './customPalette';\nimport type { CustomPrimaryColor } from './customPrimary';\nimport type { LobeAppearance } from './scope';\n\nconst v = (key: string) => `var(${toCssVarName(key)})`;\n\nconst ring: Record<LobeAppearance, string> = {\n dark: '0 0 0 1px rgb(255 255 255 / 18%)',\n light: '0 0 0 1px rgb(0 0 0 / 5%)',\n};\n\n/* `initial` makes a light scope nested in a dark one fall back to each variant's own fill\n instead of inheriting the dark table surface. */\nconst surface: Record<LobeAppearance, Record<string, string>> = {\n dark: {\n '--lobe-fill-border': v('colorFillSecondary'),\n '--lobe-fill-border-strong': v('colorFill'),\n '--lobe-table-cell-bg': 'transparent',\n '--lobe-table-surface': v('colorFillQuaternary'),\n },\n light: {\n '--lobe-fill-border': v('colorFill'),\n '--lobe-fill-border-strong': `color-mix(in srgb, ${v('colorFill')}, ${v('colorText')} 15%)`,\n '--lobe-table-cell-bg': 'initial',\n '--lobe-table-surface': 'initial',\n },\n};\n\nconst rule = (selector: string, declarations: Record<string, number | string>) =>\n `${selector} {\\n${Object.entries(declarations)\n .map(([name, value]) => ` ${name}: ${value};`)\n .join('\\n')}\\n}`;\n\nconst appearanceRule = (selector: string, appearance: LobeAppearance) => {\n const { neutral, palette, primary, static: base } = createLobeTokenGroups({ appearance });\n const token =\n appearance === 'light'\n ? { ...base, ...palette, ...primary, ...neutral }\n : { ...palette, ...primary, ...neutral };\n\n return rule(selector, {\n ...toCssVariables(token),\n '--lobe-ring': ring[appearance],\n ...surface[appearance],\n 'color-scheme': appearance,\n });\n};\n\nconst appearanceSelector = (appearance: LobeAppearance) =>\n appearance === 'dark' ? \"[data-theme='dark']\" : \":not([data-theme='dark'])\";\n\nconst colorRules = (appearance: LobeAppearance) => [\n ...(Object.keys(primaryColors) as (keyof typeof primaryColors)[]).map((primaryColor) =>\n rule(\n `[data-primary-color='${primaryColor}']${appearanceSelector(appearance)}`,\n toCssVariables(createLobeTokenGroups({ appearance, primaryColor }).primary),\n ),\n ),\n ...(Object.keys(neutralColors) as (keyof typeof neutralColors)[]).map((neutralColor) =>\n rule(\n `[data-neutral-color='${neutralColor}']${appearanceSelector(appearance)}`,\n toCssVariables(createLobeTokenGroups({ appearance, neutralColor }).neutral),\n ),\n ),\n];\n\nexport const getCustomPrimaryCss = (color: CustomPrimaryColor) => {\n const hex = color.toLowerCase();\n return (['light', 'dark'] as const)\n .map((appearance) =>\n rule(\n `[data-primary-color='${hex}']${appearanceSelector(appearance)}`,\n toCssVariables(\n createLobeTokenGroups({ appearance, primaryColor: hex as CustomPrimaryColor }).primary,\n ),\n ),\n )\n .join('\\n\\n');\n};\n\n/** CSS for a custom neutral (6-digit hex or a `registerLobeNeutral` name); '' for presets. */\nexport const getCustomNeutralCss = (value: string) => {\n const key = value.startsWith('#') ? value.toLowerCase() : value;\n if (!isCustomNeutral(key)) return '';\n return (['light', 'dark'] as const)\n .map((appearance) =>\n rule(\n `[data-neutral-color='${key}']${appearanceSelector(appearance)}`,\n toCssVariables(createLobeTokenGroups({ appearance, neutralColor: key }).neutral),\n ),\n )\n .join('\\n\\n');\n};\n\nexport const getCustomPaletteCss = (name: string) => {\n if (!isRegisteredPalette(name)) return '';\n return (['light', 'dark'] as const)\n .map((appearance) => {\n const { neutral, palette } = createLobeTokenGroups({ appearance, palette: name });\n return rule(\n `[data-palette='${name}']${appearanceSelector(appearance)}`,\n toCssVariables({\n ...palette,\n colorErrorOutline: neutral.colorErrorOutline,\n colorWarningOutline: neutral.colorWarningOutline,\n }),\n );\n })\n .join('\\n\\n');\n};\n\n/**\n * The outline tokens depend on both the neutral and the status palette, so the standalone\n * neutral / palette stylesheets each compute them against the other's default. This rule\n * (higher specificity) recomputes them for the actual combination.\n */\nexport const getPaletteNeutralCss = (name: string, neutralColor: string) => {\n if (!isRegisteredPalette(name) || !neutralColor) return '';\n const key = neutralColor.startsWith('#') ? neutralColor.toLowerCase() : neutralColor;\n return (['light', 'dark'] as const)\n .map((appearance) => {\n const { neutral } = createLobeTokenGroups({ appearance, neutralColor: key, palette: name });\n return rule(\n `[data-palette='${name}'][data-neutral-color='${key}']${appearanceSelector(appearance)}`,\n toCssVariables({\n colorErrorOutline: neutral.colorErrorOutline,\n colorWarningOutline: neutral.colorWarningOutline,\n }),\n );\n })\n .join('\\n\\n');\n};\n\nconst essentialCss = `@layer lobe-ui {\n .lobe-brand-loading path {\n fill: currentcolor;\n fill-opacity: 0;\n stroke: currentcolor;\n stroke-dasharray: 1000;\n stroke-dashoffset: 1000;\n stroke-width: 0.25em;\n\n animation:\n draw 2s cubic-bezier(0.4, 0, 0.2, 1) infinite,\n fill 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;\n }\n}\n\n@layer lobe-popup {\n .lobe-context-trigger[data-popup-open],\n .lobe-dropdown-menu-trigger[data-popup-open] {\n background: ${v('colorFillTertiary')};\n }\n}\n\n@layer lobe-base {\n :where(body, body [data-theme]) {\n color: ${v('colorText')};\n font-family: ${v('fontFamily')};\n font-size: ${v('fontSize')};\n line-height: ${v('lineHeight')};\n }\n\n :where(body) :where(a) {\n cursor: pointer;\n\n color: ${v('colorLink')};\n text-decoration: none;\n\n background-color: transparent;\n outline: none;\n\n transition: color ${v('motionDurationSlow')};\n }\n\n :where(body) :where(a):hover {\n color: ${v('colorLinkHover')};\n }\n\n :where(body) :where(a):active {\n color: ${v('colorLinkActive')};\n }\n\n :where(body) :where(a):focus-visible {\n outline: ${v('lineWidthFocus')} solid ${v('colorPrimaryBorder')};\n outline-offset: 1px;\n }\n\n :where(body) :where(a)[disabled] {\n cursor: not-allowed;\n color: ${v('colorTextDisabled')};\n }\n\n :where(.lobe-flex) {\n --lobe-flex: 0 1 auto;\n --lobe-flex-direction: column;\n --lobe-flex-wrap: nowrap;\n --lobe-flex-justify: flex-start;\n --lobe-flex-align: stretch;\n --lobe-flex-width: auto;\n --lobe-flex-height: auto;\n --lobe-flex-padding: 0;\n --lobe-flex-padding-inline: var(--lobe-flex-padding);\n --lobe-flex-padding-block: var(--lobe-flex-padding);\n --lobe-flex-gap: 0;\n\n display: flex;\n flex: var(--lobe-flex);\n flex-flow: var(--lobe-flex-direction) var(--lobe-flex-wrap);\n gap: var(--lobe-flex-gap);\n align-items: var(--lobe-flex-align);\n justify-content: var(--lobe-flex-justify);\n\n width: var(--lobe-flex-width);\n height: var(--lobe-flex-height);\n padding: var(--lobe-flex-padding);\n padding-block: var(--lobe-flex-padding-block);\n padding-inline: var(--lobe-flex-padding-inline);\n }\n\n .lobe-flex-hidden {\n display: none;\n }\n}\n\n@keyframes draw {\n 0% {\n stroke-dashoffset: 1000;\n }\n\n 100% {\n stroke-dashoffset: 0;\n }\n}\n\n@keyframes fill {\n 30% {\n fill-opacity: 0.05;\n }\n\n 100% {\n fill-opacity: 1;\n }\n}`;\n\nconst globalCss = `@layer lobe-base {\n :root {\n --font-settings: 'cv01', 'tnum', 'kern';\n --font-variations: 'opsz' auto, tabular-nums;\n\n font-synthesis: style;\n text-autospace: normal;\n }\n\n html {\n overscroll-behavior: none;\n }\n\n body {\n overflow: hidden auto;\n\n min-height: 100vh;\n margin: 0;\n padding: 0;\n\n font-feature-settings: var(--font-settings);\n font-variation-settings: var(--font-variations);\n font-optical-sizing: auto;\n font-kerning: normal;\n font-variant-ligatures: common-ligatures contextual;\n font-variant-numeric: tabular-nums;\n font-size-adjust: from-font;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-wrap: pretty;\n text-size-adjust: 100%;\n text-rendering: optimizelegibility;\n overflow-wrap: anywhere;\n vertical-align: baseline;\n\n background-color: ${v('colorBgLayout')};\n\n font-synthesis: style;\n\n -webkit-overflow-scrolling: touch;\n -webkit-tap-highlight-color: transparent;\n }\n\n html,\n body {\n width: 100%;\n height: 100%;\n }\n\n [tabindex='-1']:focus {\n outline: none;\n }\n\n [hidden] {\n display: none !important;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: 0 0.5em;\n font-weight: 500;\n }\n\n p,\n ol,\n ul,\n dl,\n pre {\n margin-block: 0 1em;\n }\n\n ol ol,\n ul ul,\n ol ul,\n ul ol {\n margin-block-end: 0;\n }\n\n dd {\n margin-block-end: 0.5em;\n margin-inline-start: 0;\n }\n\n blockquote,\n figure {\n margin-block: 0 1em;\n margin-inline: 0;\n }\n\n img {\n border-style: none;\n vertical-align: middle;\n }\n\n table {\n border-collapse: collapse;\n }\n\n input,\n button,\n select,\n optgroup,\n textarea {\n margin: 0;\n\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n color: inherit;\n }\n\n textarea {\n resize: vertical;\n overflow: auto;\n }\n\n fieldset {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n }\n\n code,\n kbd,\n samp,\n pre {\n font-family: ${v('fontFamilyCode')} !important;\n font-feature-settings:\n 'liga' 0,\n 'calt' 0;\n font-variant-ligatures: none;\n\n span {\n font-family: ${v('fontFamilyCode')} !important;\n }\n }\n\n ::selection {\n color: #000;\n background: ${v('yellow9')};\n\n -webkit-text-fill-color: unset !important;\n }\n\n * {\n scrollbar-color: ${v('colorFill')} transparent;\n scrollbar-width: thin;\n box-sizing: border-box;\n vertical-align: baseline;\n }\n}`;\n\nconst layerOrder = '@layer lobe-base, lobe-popup, lobe-ui;';\n\nlet cached: string | undefined;\n\nexport const getThemeCss = () =>\n (cached ??= [\n layerOrder,\n appearanceRule(\":root, [data-theme='light']\", 'light'),\n appearanceRule(\"[data-theme='dark']\", 'dark'),\n ...colorRules('light'),\n ...colorRules('dark'),\n essentialCss,\n ].join('\\n\\n'));\n\nexport const getGlobalCss = () => `${layerOrder}\\n\\n${globalCss}`;\n"],"mappings":"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"}
@@ -1,8 +1,6 @@
1
- import gray from "../../../color/colors/gray.mjs";
2
- import { neutralColorScales } from "../../../color/neutrals/index.mjs";
3
1
  import { mixColors, parseRgb } from "../../../utils/colorMath.mjs";
2
+ import { resolveNeutral } from "../customNeutral.mjs";
4
3
  import { generateColorNeutralPalette } from "../generateColorPalette.mjs";
5
- import { neutralText } from "./neutralText.mjs";
6
4
  //#region src/styles/theme/token/neutral.ts
7
5
  const isChannel = (value) => value >= 0 && value <= 255;
8
6
  const getAlphaColor = (front, back) => {
@@ -21,8 +19,8 @@ const getAlphaColor = (front, back) => {
21
19
  return `rgb(${f.red},${f.green},${f.blue})`;
22
20
  };
23
21
  const createNeutralToken = (appearance, neutralColor, status) => {
24
- const scale = neutralColor && neutralColorScales[neutralColor] || gray;
25
- const [colorText, colorTextSecondary, colorTextTertiary, colorTextQuaternary] = neutralText[neutralColor && neutralColorScales[neutralColor] && neutralColor || "gray"][appearance];
22
+ const { scale, text } = resolveNeutral(neutralColor);
23
+ const [colorText, colorTextSecondary, colorTextTertiary, colorTextQuaternary] = text[appearance];
26
24
  const token = {
27
25
  ...generateColorNeutralPalette({
28
26
  appearance,
@@ -1 +1 @@
1
- {"version":3,"file":"neutral.mjs","names":[],"sources":["../../../../src/styles/theme/token/neutral.ts"],"sourcesContent":["import { gray } from '@/color/colors';\nimport { neutralColorScales } from '@/color/neutrals';\nimport { mixColors, parseRgb } from '@/utils/colorMath';\n\nimport type { NeutralColors } from '../../customTheme';\nimport { generateColorNeutralPalette } from '../generateColorPalette';\nimport { neutralText } from './neutralText';\n\nconst isChannel = (value: number) => value >= 0 && value <= 255;\n\n// port of antd's getAlphaColor: the most transparent rgba that renders `front` over `back`\nconst getAlphaColor = (front: string, back: string) => {\n const f = parseRgb(front);\n if (f.alpha !== undefined) return front;\n const b = parseRgb(back);\n\n for (let alpha = 0.01; alpha <= 1; alpha += 0.01) {\n const r = Math.round((f.red - b.red * (1 - alpha)) / alpha);\n const g = Math.round((f.green - b.green * (1 - alpha)) / alpha);\n const bl = Math.round((f.blue - b.blue * (1 - alpha)) / alpha);\n if (isChannel(r) && isChannel(g) && isChannel(bl)) {\n const a = Math.round(alpha * 100) / 100;\n return a === 1 ? `rgb(${r},${g},${bl})` : `rgba(${r},${g},${bl},${a})`;\n }\n }\n\n return `rgb(${f.red},${f.green},${f.blue})`;\n};\n\nexport const createNeutralToken = (\n appearance: 'light' | 'dark',\n neutralColor: NeutralColors | undefined,\n status: { colorErrorBg: string; colorWarningBg: string },\n) => {\n const scale = (neutralColor && neutralColorScales[neutralColor]) || gray;\n const [colorText, colorTextSecondary, colorTextTertiary, colorTextQuaternary] =\n neutralText[(neutralColor && neutralColorScales[neutralColor] && neutralColor) || 'gray'][\n appearance\n ];\n const token = {\n ...generateColorNeutralPalette({ appearance, scale }),\n colorText,\n colorTextQuaternary,\n colorTextSecondary,\n colorTextTertiary,\n };\n\n return {\n ...token,\n colorBgContainerDisabled: token.colorFillTertiary,\n colorBgContainerSecondary: mixColors(0.5, token.colorBgLayout, token.colorBgContainer),\n colorBgTextActive: token.colorFill,\n colorBgTextHover: token.colorFillSecondary,\n colorBorderBg: token.colorBgContainer,\n colorErrorOutline: getAlphaColor(status.colorErrorBg, token.colorBgContainer),\n colorFillAlter: token.colorFillQuaternary,\n colorFillContent: token.colorFillSecondary,\n colorFillContentHover: token.colorFill,\n colorIcon: token.colorTextTertiary,\n colorIconHover: token.colorText,\n colorSplit: getAlphaColor(token.colorBorderSecondary, token.colorBgContainer),\n colorTextDescription: token.colorTextTertiary,\n colorTextDisabled: token.colorTextQuaternary,\n colorTextHeading: token.colorText,\n colorTextLabel: token.colorTextSecondary,\n colorTextPlaceholder: token.colorTextQuaternary,\n colorWarningOutline: getAlphaColor(status.colorWarningBg, token.colorBgContainer),\n controlItemBgActiveDisabled: token.colorFill,\n controlItemBgHover: token.colorFillTertiary,\n controlTmpOutline: token.colorFillQuaternary,\n };\n};\n"],"mappings":";;;;;;AAQA,MAAM,aAAa,UAAkB,SAAS,KAAK,SAAS;AAG5D,MAAM,iBAAiB,OAAe,SAAiB;CACrD,MAAM,IAAI,SAAS,KAAK;CACxB,IAAI,EAAE,UAAU,KAAA,GAAW,OAAO;CAClC,MAAM,IAAI,SAAS,IAAI;CAEvB,KAAK,IAAI,QAAQ,KAAM,SAAS,GAAG,SAAS,KAAM;EAChD,MAAM,IAAI,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,UAAU,KAAK;EAC1D,MAAM,IAAI,KAAK,OAAO,EAAE,QAAQ,EAAE,SAAS,IAAI,UAAU,KAAK;EAC9D,MAAM,KAAK,KAAK,OAAO,EAAE,OAAO,EAAE,QAAQ,IAAI,UAAU,KAAK;EAC7D,IAAI,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,EAAE,GAAG;GACjD,MAAM,IAAI,KAAK,MAAM,QAAQ,GAAG,IAAI;GACpC,OAAO,MAAM,IAAI,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,KAAK,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE;EACtE;CACF;CAEA,OAAO,OAAO,EAAE,IAAI,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK;AAC3C;AAEA,MAAa,sBACX,YACA,cACA,WACG;CACH,MAAM,QAAS,gBAAgB,mBAAmB,iBAAkB;CACpE,MAAM,CAAC,WAAW,oBAAoB,mBAAmB,uBACvD,YAAa,gBAAgB,mBAAmB,iBAAiB,gBAAiB,OAAO,CACvF;CAEJ,MAAM,QAAQ;EACZ,GAAG,4BAA4B;GAAE;GAAY;EAAM,CAAC;EACpD;EACA;EACA;EACA;CACF;CAEA,OAAO;EACL,GAAG;EACH,0BAA0B,MAAM;EAChC,2BAA2B,UAAU,IAAK,MAAM,eAAe,MAAM,gBAAgB;EACrF,mBAAmB,MAAM;EACzB,kBAAkB,MAAM;EACxB,eAAe,MAAM;EACrB,mBAAmB,cAAc,OAAO,cAAc,MAAM,gBAAgB;EAC5E,gBAAgB,MAAM;EACtB,kBAAkB,MAAM;EACxB,uBAAuB,MAAM;EAC7B,WAAW,MAAM;EACjB,gBAAgB,MAAM;EACtB,YAAY,cAAc,MAAM,sBAAsB,MAAM,gBAAgB;EAC5E,sBAAsB,MAAM;EAC5B,mBAAmB,MAAM;EACzB,kBAAkB,MAAM;EACxB,gBAAgB,MAAM;EACtB,sBAAsB,MAAM;EAC5B,qBAAqB,cAAc,OAAO,gBAAgB,MAAM,gBAAgB;EAChF,6BAA6B,MAAM;EACnC,oBAAoB,MAAM;EAC1B,mBAAmB,MAAM;CAC3B;AACF"}
1
+ {"version":3,"file":"neutral.mjs","names":[],"sources":["../../../../src/styles/theme/token/neutral.ts"],"sourcesContent":["import { mixColors, parseRgb } from '@/utils/colorMath';\n\nimport { type LobeNeutralColor, resolveNeutral } from '../customNeutral';\nimport { generateColorNeutralPalette } from '../generateColorPalette';\n\nconst isChannel = (value: number) => value >= 0 && value <= 255;\n\n// port of antd's getAlphaColor: the most transparent rgba that renders `front` over `back`\nconst getAlphaColor = (front: string, back: string) => {\n const f = parseRgb(front);\n if (f.alpha !== undefined) return front;\n const b = parseRgb(back);\n\n for (let alpha = 0.01; alpha <= 1; alpha += 0.01) {\n const r = Math.round((f.red - b.red * (1 - alpha)) / alpha);\n const g = Math.round((f.green - b.green * (1 - alpha)) / alpha);\n const bl = Math.round((f.blue - b.blue * (1 - alpha)) / alpha);\n if (isChannel(r) && isChannel(g) && isChannel(bl)) {\n const a = Math.round(alpha * 100) / 100;\n return a === 1 ? `rgb(${r},${g},${bl})` : `rgba(${r},${g},${bl},${a})`;\n }\n }\n\n return `rgb(${f.red},${f.green},${f.blue})`;\n};\n\nexport const createNeutralToken = (\n appearance: 'light' | 'dark',\n neutralColor: LobeNeutralColor | undefined,\n status: { colorErrorBg: string; colorWarningBg: string },\n) => {\n const { scale, text } = resolveNeutral(neutralColor);\n const [colorText, colorTextSecondary, colorTextTertiary, colorTextQuaternary] = text[appearance];\n const token = {\n ...generateColorNeutralPalette({ appearance, scale }),\n colorText,\n colorTextQuaternary,\n colorTextSecondary,\n colorTextTertiary,\n };\n\n return {\n ...token,\n colorBgContainerDisabled: token.colorFillTertiary,\n colorBgContainerSecondary: mixColors(0.5, token.colorBgLayout, token.colorBgContainer),\n colorBgTextActive: token.colorFill,\n colorBgTextHover: token.colorFillSecondary,\n colorBorderBg: token.colorBgContainer,\n colorErrorOutline: getAlphaColor(status.colorErrorBg, token.colorBgContainer),\n colorFillAlter: token.colorFillQuaternary,\n colorFillContent: token.colorFillSecondary,\n colorFillContentHover: token.colorFill,\n colorIcon: token.colorTextTertiary,\n colorIconHover: token.colorText,\n colorSplit: getAlphaColor(token.colorBorderSecondary, token.colorBgContainer),\n colorTextDescription: token.colorTextTertiary,\n colorTextDisabled: token.colorTextQuaternary,\n colorTextHeading: token.colorText,\n colorTextLabel: token.colorTextSecondary,\n colorTextPlaceholder: token.colorTextQuaternary,\n colorWarningOutline: getAlphaColor(status.colorWarningBg, token.colorBgContainer),\n controlItemBgActiveDisabled: token.colorFill,\n controlItemBgHover: token.colorFillTertiary,\n controlTmpOutline: token.colorFillQuaternary,\n };\n};\n"],"mappings":";;;;AAKA,MAAM,aAAa,UAAkB,SAAS,KAAK,SAAS;AAG5D,MAAM,iBAAiB,OAAe,SAAiB;CACrD,MAAM,IAAI,SAAS,KAAK;CACxB,IAAI,EAAE,UAAU,KAAA,GAAW,OAAO;CAClC,MAAM,IAAI,SAAS,IAAI;CAEvB,KAAK,IAAI,QAAQ,KAAM,SAAS,GAAG,SAAS,KAAM;EAChD,MAAM,IAAI,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,UAAU,KAAK;EAC1D,MAAM,IAAI,KAAK,OAAO,EAAE,QAAQ,EAAE,SAAS,IAAI,UAAU,KAAK;EAC9D,MAAM,KAAK,KAAK,OAAO,EAAE,OAAO,EAAE,QAAQ,IAAI,UAAU,KAAK;EAC7D,IAAI,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,EAAE,GAAG;GACjD,MAAM,IAAI,KAAK,MAAM,QAAQ,GAAG,IAAI;GACpC,OAAO,MAAM,IAAI,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,KAAK,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE;EACtE;CACF;CAEA,OAAO,OAAO,EAAE,IAAI,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK;AAC3C;AAEA,MAAa,sBACX,YACA,cACA,WACG;CACH,MAAM,EAAE,OAAO,SAAS,eAAe,YAAY;CACnD,MAAM,CAAC,WAAW,oBAAoB,mBAAmB,uBAAuB,KAAK;CACrF,MAAM,QAAQ;EACZ,GAAG,4BAA4B;GAAE;GAAY;EAAM,CAAC;EACpD;EACA;EACA;EACA;CACF;CAEA,OAAO;EACL,GAAG;EACH,0BAA0B,MAAM;EAChC,2BAA2B,UAAU,IAAK,MAAM,eAAe,MAAM,gBAAgB;EACrF,mBAAmB,MAAM;EACzB,kBAAkB,MAAM;EACxB,eAAe,MAAM;EACrB,mBAAmB,cAAc,OAAO,cAAc,MAAM,gBAAgB;EAC5E,gBAAgB,MAAM;EACtB,kBAAkB,MAAM;EACxB,uBAAuB,MAAM;EAC7B,WAAW,MAAM;EACjB,gBAAgB,MAAM;EACtB,YAAY,cAAc,MAAM,sBAAsB,MAAM,gBAAgB;EAC5E,sBAAsB,MAAM;EAC5B,mBAAmB,MAAM;EACzB,kBAAkB,MAAM;EACxB,gBAAgB,MAAM;EACtB,sBAAsB,MAAM;EAC5B,qBAAqB,cAAc,OAAO,gBAAgB,MAAM,gBAAgB;EAChF,6BAA6B,MAAM;EACnC,oBAAoB,MAAM;EAC1B,mBAAmB,MAAM;CAC3B;AACF"}
@@ -0,0 +1,4 @@
1
+ //#region src/styles/theme/token/neutralText.d.ts
2
+ export type NeutralTextLadder = Record<'dark' | 'light', [string, string, string, string]>;
3
+ //#endregion
4
+ //# sourceMappingURL=neutralText.d.mts.map
@@ -0,0 +1,17 @@
1
+ import { isValidElement, version } from "react";
2
+ //#region src/utils/getElementRef.ts
3
+ const IS_REACT_19 = Number.parseInt(version, 10) >= 19;
4
+ /**
5
+ * The ref attached to a React element. React 19 moved it to `props.ref` and warns
6
+ * ("Accessing element.ref was removed in React 19") when `element.ref` is read; React 18
7
+ * keeps it on the element.
8
+ */
9
+ const getElementRef = (element) => {
10
+ if (!isValidElement(element)) return void 0;
11
+ if (IS_REACT_19) return element.props?.ref;
12
+ return element.ref;
13
+ };
14
+ //#endregion
15
+ export { getElementRef };
16
+
17
+ //# sourceMappingURL=getElementRef.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getElementRef.mjs","names":[],"sources":["../../src/utils/getElementRef.ts"],"sourcesContent":["import { isValidElement, type Ref, version } from 'react';\n\nconst IS_REACT_19 = Number.parseInt(version, 10) >= 19;\n\n/**\n * The ref attached to a React element. React 19 moved it to `props.ref` and warns\n * (\"Accessing element.ref was removed in React 19\") when `element.ref` is read; React 18\n * keeps it on the element.\n */\nexport const getElementRef = <T = unknown>(element: unknown): Ref<T> | undefined => {\n if (!isValidElement(element)) return undefined;\n if (IS_REACT_19) return (element.props as { ref?: Ref<T> } | null)?.ref;\n return (element as unknown as { ref?: Ref<T> }).ref;\n};\n"],"mappings":";;AAEA,MAAM,cAAc,OAAO,SAAS,SAAS,EAAE,KAAK;;;;;;AAOpD,MAAa,iBAA8B,YAAyC;CAClF,IAAI,CAAC,eAAe,OAAO,GAAG,OAAO,KAAA;CACrC,IAAI,aAAa,OAAQ,QAAQ,OAAmC;CACpE,OAAQ,QAAwC;AAClD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",