@lobehub/ui 6.0.0-beta.8 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/es/Accordion/style.d.mts +1 -1
- package/es/CodeDiff/DiffPanel.mjs +2 -2
- package/es/CodeDiff/DiffPanel.mjs.map +1 -1
- package/es/DatePicker/DatePicker.d.mts +5 -3
- package/es/DatePicker/DatePicker.mjs +7 -5
- package/es/DatePicker/DatePicker.mjs.map +1 -1
- package/es/DatePicker/DateRangePicker.d.mts +1 -1
- package/es/DatePicker/DayjsDatePicker.d.mts +12 -0
- package/es/DatePicker/DayjsDatePicker.mjs +19 -0
- package/es/DatePicker/DayjsDatePicker.mjs.map +1 -0
- package/es/DatePicker/DayjsDateRangePicker.d.mts +7 -0
- package/es/DatePicker/DayjsDateRangePicker.mjs +8 -0
- package/es/DatePicker/DayjsDateRangePicker.mjs.map +1 -0
- package/es/DatePicker/RangePicker.mjs +7 -1
- package/es/DatePicker/RangePicker.mjs.map +1 -1
- package/es/DatePicker/SinglePicker.mjs +3 -1
- package/es/DatePicker/SinglePicker.mjs.map +1 -1
- package/es/DatePicker/dateGenerateConfig.mjs +52 -0
- package/es/DatePicker/dateGenerateConfig.mjs.map +1 -0
- package/es/DatePicker/index.d.mts +4 -2
- package/es/DatePicker/index.mjs +3 -1
- package/es/DatePicker/legacyDate.mjs +58 -0
- package/es/DatePicker/legacyDate.mjs.map +1 -0
- package/es/DatePicker/type.d.mts +60 -34
- package/es/DatePicker/usePresetActive.mjs +1 -0
- package/es/DatePicker/usePresetActive.mjs.map +1 -1
- package/es/Drawer/style.mjs.map +1 -1
- package/es/FloatingPanel/style.mjs +3 -2
- package/es/FloatingPanel/style.mjs.map +1 -1
- package/es/Form/Form.mjs +6 -2
- package/es/Form/Form.mjs.map +1 -1
- package/es/Form/style.mjs +3 -3
- package/es/Form/style.mjs.map +1 -1
- package/es/Form/type.d.mts +7 -0
- package/es/Popover/style.mjs +1 -1
- package/es/Popover/style.mjs.map +1 -1
- package/es/ProTable/hooks/useFetchData.mjs +1 -1
- package/es/ProTable/hooks/useFetchData.mjs.map +1 -1
- package/es/ProTable/parts/FieldControl.mjs +32 -15
- package/es/ProTable/parts/FieldControl.mjs.map +1 -1
- package/es/ProTable/style.mjs +9 -0
- package/es/ProTable/style.mjs.map +1 -1
- package/es/ProTable/type.d.mts +5 -2
- package/es/Switch/Switch.mjs +8 -1
- package/es/Switch/Switch.mjs.map +1 -1
- package/es/Switch/atoms.d.mts +7 -1
- package/es/Switch/atoms.mjs +20 -4
- package/es/Switch/atoms.mjs.map +1 -1
- package/es/Switch/style.mjs +33 -2
- package/es/Switch/style.mjs.map +1 -1
- package/es/Table/Table.mjs +14 -5
- package/es/Table/Table.mjs.map +1 -1
- package/es/Table/render/FixedFrost.mjs +11 -2
- package/es/Table/render/FixedFrost.mjs.map +1 -1
- package/es/Table/style.mjs +4 -0
- package/es/Table/style.mjs.map +1 -1
- package/es/Tabs/style.d.mts +1 -1
- package/es/Text/style.d.mts +3 -3
- package/es/Toast/dodge.mjs +0 -1
- package/es/Toast/dodge.mjs.map +1 -1
- package/es/Toast/dodge.stylex.mjs +1 -4
- package/es/Toast/dodge.stylex.mjs.map +1 -1
- package/es/Toast/style.mjs +1 -1
- package/es/Toast/style.mjs.map +1 -1
- package/es/Tooltip/style.mjs +2 -2
- package/es/Tooltip/style.mjs.map +1 -1
- package/es/color/index.d.mts +2 -1
- package/es/color/index.mjs +2 -1
- package/es/color/status/error.mjs +67 -0
- package/es/color/status/error.mjs.map +1 -0
- package/es/color/status/index.d.mts +11 -0
- package/es/color/status/index.mjs +15 -0
- package/es/color/status/index.mjs.map +1 -0
- package/es/color/status/info.mjs +67 -0
- package/es/color/status/info.mjs.map +1 -0
- package/es/color/status/success.mjs +67 -0
- package/es/color/status/success.mjs.map +1 -0
- package/es/color/status/warning.mjs +67 -0
- package/es/color/status/warning.mjs.map +1 -0
- package/es/index.d.mts +6 -3
- package/es/index.mjs +5 -2
- package/es/style.css +114 -23
- package/es/styles/index.d.mts +3 -2
- package/es/styles/index.mjs +3 -2
- package/es/styles/stylex/cssVar.stylex.mjs +3 -0
- package/es/styles/stylex/cssVar.stylex.mjs.map +1 -1
- package/es/styles/theme/createLobeToken.d.mts +9 -5
- package/es/styles/theme/createLobeToken.mjs +3 -2
- package/es/styles/theme/createLobeToken.mjs.map +1 -1
- package/es/styles/theme/customPalette.d.mts +6 -0
- package/es/styles/theme/customPalette.mjs +28 -0
- package/es/styles/theme/customPalette.mjs.map +1 -0
- package/es/styles/theme/customPrimary.mjs +52 -17
- package/es/styles/theme/customPrimary.mjs.map +1 -1
- package/es/styles/theme/scope.d.mts +4 -2
- package/es/styles/theme/scope.mjs +53 -20
- package/es/styles/theme/scope.mjs.map +1 -1
- package/es/styles/theme/themeCss.d.mts +1 -0
- package/es/styles/theme/themeCss.mjs +16 -1
- package/es/styles/theme/themeCss.mjs.map +1 -1
- package/es/styles/theme/token/legacy.mjs +12 -12
- package/es/styles/theme/token/legacy.mjs.map +1 -1
- package/es/styles/theme/token/neutral.mjs +12 -4
- package/es/styles/theme/token/neutral.mjs.map +1 -1
- package/es/styles/theme/token/neutralText.mjs +91 -0
- package/es/styles/theme/token/neutralText.mjs.map +1 -0
- package/es/styles/theme/token/palette.mjs +16 -41
- package/es/styles/theme/token/palette.mjs.map +1 -1
- package/es/styles/theme/token/static.mjs +3 -0
- package/es/styles/theme/token/static.mjs.map +1 -1
- package/es/theme.css +293 -290
- package/package.json +1 -1
|
@@ -4,9 +4,10 @@ import { LobePrimaryColor } from "./customPrimary.mjs";
|
|
|
4
4
|
export interface CreateLobeTokenParams {
|
|
5
5
|
appearance: 'light' | 'dark';
|
|
6
6
|
neutralColor?: NeutralColors;
|
|
7
|
+
palette?: string;
|
|
7
8
|
primaryColor?: LobePrimaryColor;
|
|
8
9
|
}
|
|
9
|
-
export declare const createLobeTokenGroups: ({ appearance, neutralColor, primaryColor }: CreateLobeTokenParams) => {
|
|
10
|
+
export declare const createLobeTokenGroups: ({ appearance, neutralColor, palette: paletteName, primaryColor }: CreateLobeTokenParams) => {
|
|
10
11
|
neutral: {
|
|
11
12
|
colorBgContainerDisabled: string;
|
|
12
13
|
colorBgContainerSecondary: string;
|
|
@@ -29,6 +30,10 @@ export declare const createLobeTokenGroups: ({ appearance, neutralColor, primary
|
|
|
29
30
|
controlItemBgActiveDisabled: string;
|
|
30
31
|
controlItemBgHover: string;
|
|
31
32
|
controlTmpOutline: string;
|
|
33
|
+
colorText: string;
|
|
34
|
+
colorTextQuaternary: string;
|
|
35
|
+
colorTextSecondary: string;
|
|
36
|
+
colorTextTertiary: string;
|
|
32
37
|
colorBgContainer: string;
|
|
33
38
|
colorBgElevated: string;
|
|
34
39
|
colorBgLayout: string;
|
|
@@ -40,10 +45,6 @@ export declare const createLobeTokenGroups: ({ appearance, neutralColor, primary
|
|
|
40
45
|
colorFillQuaternary: string;
|
|
41
46
|
colorFillSecondary: string;
|
|
42
47
|
colorFillTertiary: string;
|
|
43
|
-
colorText: string;
|
|
44
|
-
colorTextQuaternary: string;
|
|
45
|
-
colorTextSecondary: string;
|
|
46
|
-
colorTextTertiary: string;
|
|
47
48
|
};
|
|
48
49
|
palette: {
|
|
49
50
|
colorErrorAffix: string;
|
|
@@ -1291,6 +1292,9 @@ export declare const createLobeTokenGroups: ({ appearance, neutralColor, primary
|
|
|
1291
1292
|
motionEaseOutBack: string;
|
|
1292
1293
|
motionEaseOutCirc: string;
|
|
1293
1294
|
motionEaseOutQuint: string;
|
|
1295
|
+
motionSpringBouncy: string;
|
|
1296
|
+
motionSpringSmooth: string;
|
|
1297
|
+
motionSpringSnappy: string;
|
|
1294
1298
|
motionUnit: number;
|
|
1295
1299
|
opacityImage: number;
|
|
1296
1300
|
opacityLoading: number;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { resolveStatusScales } from "./customPalette.mjs";
|
|
1
2
|
import { createNeutralToken } from "./token/neutral.mjs";
|
|
2
3
|
import { createPaletteToken } from "./token/palette.mjs";
|
|
3
4
|
import { createPrimaryToken } from "./token/primary.mjs";
|
|
4
5
|
import { staticToken } from "./token/static.mjs";
|
|
5
6
|
//#region src/styles/theme/createLobeToken.ts
|
|
6
|
-
const createLobeTokenGroups = ({ appearance, neutralColor, primaryColor }) => {
|
|
7
|
-
const palette = createPaletteToken(appearance);
|
|
7
|
+
const createLobeTokenGroups = ({ appearance, neutralColor, palette: paletteName, primaryColor }) => {
|
|
8
|
+
const palette = createPaletteToken(appearance, resolveStatusScales(paletteName));
|
|
8
9
|
return {
|
|
9
10
|
neutral: createNeutralToken(appearance, neutralColor, palette),
|
|
10
11
|
palette,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLobeToken.mjs","names":[],"sources":["../../../src/styles/theme/createLobeToken.ts"],"sourcesContent":["import type { NeutralColors } from '../customTheme';\nimport type { LobePrimaryColor } from './customPrimary';\nimport { createNeutralToken } from './token/neutral';\nimport { createPaletteToken } from './token/palette';\nimport { createPrimaryToken } from './token/primary';\nimport { staticToken } from './token/static';\n\nexport interface CreateLobeTokenParams {\n appearance: 'light' | 'dark';\n neutralColor?: NeutralColors;\n primaryColor?: LobePrimaryColor;\n}\n\nexport const createLobeTokenGroups = ({\n appearance,\n neutralColor,\n primaryColor,\n}: CreateLobeTokenParams) => {\n const palette = createPaletteToken(appearance);\n\n return {\n neutral: createNeutralToken(appearance, neutralColor, palette),\n palette,\n primary: createPrimaryToken(appearance, primaryColor),\n static: staticToken,\n };\n};\n\nexport type LobeTokenGroups = ReturnType<typeof createLobeTokenGroups>;\n\nexport type LobeToken = LobeTokenGroups['static'] &\n LobeTokenGroups['palette'] &\n LobeTokenGroups['primary'] &\n LobeTokenGroups['neutral'];\n\nexport const createLobeToken = (params: CreateLobeTokenParams): LobeToken => {\n const groups = createLobeTokenGroups(params);\n\n return { ...groups.static, ...groups.palette, ...groups.primary, ...groups.neutral };\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"createLobeToken.mjs","names":[],"sources":["../../../src/styles/theme/createLobeToken.ts"],"sourcesContent":["import type { NeutralColors } from '../customTheme';\nimport { resolveStatusScales } from './customPalette';\nimport type { LobePrimaryColor } from './customPrimary';\nimport { createNeutralToken } from './token/neutral';\nimport { createPaletteToken } from './token/palette';\nimport { createPrimaryToken } from './token/primary';\nimport { staticToken } from './token/static';\n\nexport interface CreateLobeTokenParams {\n appearance: 'light' | 'dark';\n neutralColor?: NeutralColors;\n palette?: string;\n primaryColor?: LobePrimaryColor;\n}\n\nexport const createLobeTokenGroups = ({\n appearance,\n neutralColor,\n palette: paletteName,\n primaryColor,\n}: CreateLobeTokenParams) => {\n const palette = createPaletteToken(appearance, resolveStatusScales(paletteName));\n\n return {\n neutral: createNeutralToken(appearance, neutralColor, palette),\n palette,\n primary: createPrimaryToken(appearance, primaryColor),\n static: staticToken,\n };\n};\n\nexport type LobeTokenGroups = ReturnType<typeof createLobeTokenGroups>;\n\nexport type LobeToken = LobeTokenGroups['static'] &\n LobeTokenGroups['palette'] &\n LobeTokenGroups['primary'] &\n LobeTokenGroups['neutral'];\n\nexport const createLobeToken = (params: CreateLobeTokenParams): LobeToken => {\n const groups = createLobeTokenGroups(params);\n\n return { ...groups.static, ...groups.palette, ...groups.primary, ...groups.neutral };\n};\n"],"mappings":";;;;;;AAeA,MAAa,yBAAyB,EACpC,YACA,cACA,SAAS,aACT,mBAC2B;CAC3B,MAAM,UAAU,mBAAmB,YAAY,oBAAoB,WAAW,CAAC;CAE/E,OAAO;EACL,SAAS,mBAAmB,YAAY,cAAc,OAAO;EAC7D;EACA,SAAS,mBAAmB,YAAY,YAAY;EACpD,QAAQ;CACV;AACF;AASA,MAAa,mBAAmB,WAA6C;CAC3E,MAAM,SAAS,sBAAsB,MAAM;CAE3C,OAAO;EAAE,GAAG,OAAO;EAAQ,GAAG,OAAO;EAAS,GAAG,OAAO;EAAS,GAAG,OAAO;CAAQ;AACrF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { StatusColorScales } from "../../color/status/index.mjs";
|
|
2
|
+
//#region src/styles/theme/customPalette.d.ts
|
|
3
|
+
export type LobeStatusPalette = Partial<StatusColorScales>;
|
|
4
|
+
export declare const registerLobePalette: (name: string, palette: LobeStatusPalette) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
//# sourceMappingURL=customPalette.d.mts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { statusColorScales } from "../../color/status/index.mjs";
|
|
2
|
+
//#region src/styles/theme/customPalette.ts
|
|
3
|
+
const NAME = /^[\w-]+$/;
|
|
4
|
+
const registry = /* @__PURE__ */ new Map();
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
let revision = 0;
|
|
7
|
+
const registerLobePalette = (name, palette) => {
|
|
8
|
+
if (!NAME.test(name)) throw new Error(`Invalid palette name "${name}": use letters, digits, _ or -`);
|
|
9
|
+
registry.set(name, palette);
|
|
10
|
+
revision++;
|
|
11
|
+
for (const listener of listeners) listener();
|
|
12
|
+
};
|
|
13
|
+
const getPaletteRevision = () => revision;
|
|
14
|
+
const subscribePalettes = (listener) => {
|
|
15
|
+
listeners.add(listener);
|
|
16
|
+
return () => {
|
|
17
|
+
listeners.delete(listener);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const isRegisteredPalette = (name) => !!name && registry.has(name);
|
|
21
|
+
const resolveStatusScales = (name) => isRegisteredPalette(name) ? {
|
|
22
|
+
...statusColorScales,
|
|
23
|
+
...registry.get(name)
|
|
24
|
+
} : statusColorScales;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { getPaletteRevision, isRegisteredPalette, registerLobePalette, resolveStatusScales, subscribePalettes };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=customPalette.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customPalette.mjs","names":[],"sources":["../../../src/styles/theme/customPalette.ts"],"sourcesContent":["import { type StatusColorScales, statusColorScales } from '@/color/status';\n\nexport type LobeStatusPalette = Partial<StatusColorScales>;\n\nconst NAME = /^[\\w-]+$/;\n\nconst registry = new Map<string, LobeStatusPalette>();\nconst listeners = new Set<() => void>();\nlet revision = 0;\n\nexport const registerLobePalette = (name: string, palette: LobeStatusPalette) => {\n if (!NAME.test(name))\n throw new Error(`Invalid palette name \"${name}\": use letters, digits, _ or -`);\n registry.set(name, palette);\n revision++;\n for (const listener of listeners) listener();\n};\n\nexport const getPaletteRevision = () => revision;\n\nexport const subscribePalettes = (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n};\n\nexport const isRegisteredPalette = (name?: string): name is string => !!name && registry.has(name);\n\nexport const resolveStatusScales = (name?: string): StatusColorScales =>\n isRegisteredPalette(name) ? { ...statusColorScales, ...registry.get(name) } : statusColorScales;\n"],"mappings":";;AAIA,MAAM,OAAO;AAEb,MAAM,2BAAW,IAAI,IAA+B;AACpD,MAAM,4BAAY,IAAI,IAAgB;AACtC,IAAI,WAAW;AAEf,MAAa,uBAAuB,MAAc,YAA+B;CAC/E,IAAI,CAAC,KAAK,KAAK,IAAI,GACjB,MAAM,IAAI,MAAM,yBAAyB,KAAK,+BAA+B;CAC/E,SAAS,IAAI,MAAM,OAAO;CAC1B;CACA,KAAK,MAAM,YAAY,WAAW,SAAS;AAC7C;AAEA,MAAa,2BAA2B;AAExC,MAAa,qBAAqB,aAAyB;CACzD,UAAU,IAAI,QAAQ;CACtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;AAEA,MAAa,uBAAuB,SAAkC,CAAC,CAAC,QAAQ,SAAS,IAAI,IAAI;AAEjG,MAAa,uBAAuB,SAClC,oBAAoB,IAAI,IAAI;CAAE,GAAG;CAAmB,GAAG,SAAS,IAAI,IAAI;AAAE,IAAI"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import gray from "../../color/colors/gray.mjs";
|
|
1
2
|
import { colorScales } from "../../color/colors/index.mjs";
|
|
2
3
|
import { primaryColors } from "../customTheme.mjs";
|
|
3
4
|
import chroma from "chroma-js";
|
|
@@ -5,12 +6,26 @@ import chroma from "chroma-js";
|
|
|
5
6
|
const HEX = /^#[\da-f]{6}$/i;
|
|
6
7
|
const isCustomPrimaryColor = (value) => !!value && HEX.test(value);
|
|
7
8
|
const ANCHOR = 9;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const SHIFT_WEIGHT = [
|
|
10
|
+
0,
|
|
11
|
+
0,
|
|
12
|
+
0,
|
|
13
|
+
0,
|
|
14
|
+
0,
|
|
15
|
+
.25,
|
|
16
|
+
.5,
|
|
17
|
+
.75,
|
|
18
|
+
1,
|
|
19
|
+
1,
|
|
20
|
+
1,
|
|
21
|
+
.5,
|
|
22
|
+
0
|
|
23
|
+
];
|
|
24
|
+
const MIN_STEP_GAP = .015;
|
|
25
|
+
const LIGHTNESS_WEIGHT = 100;
|
|
13
26
|
const MAX_CHROMA_RATIO = 2;
|
|
27
|
+
const DARK_SURFACE = gray.dark[1];
|
|
28
|
+
const MIN_DARK_CONTRAST = 4.5;
|
|
14
29
|
const oklch = (color) => {
|
|
15
30
|
const [l, c, h] = chroma(color).oklch();
|
|
16
31
|
return {
|
|
@@ -23,17 +38,35 @@ const hueDistance = (a, b) => {
|
|
|
23
38
|
const d = Math.abs(a - b) % 360;
|
|
24
39
|
return d > 180 ? 360 - d : d;
|
|
25
40
|
};
|
|
26
|
-
const
|
|
41
|
+
const presetDistance = (name, target) => {
|
|
42
|
+
const preset = oklch(primaryColors[name]);
|
|
43
|
+
return hueDistance(preset.h, target.h) + LIGHTNESS_WEIGHT * Math.abs(preset.l - target.l);
|
|
44
|
+
};
|
|
45
|
+
const nearestPreset = (target) => Object.keys(primaryColors).reduce((best, name) => presetDistance(name, target) < presetDistance(best, target) ? name : best);
|
|
27
46
|
const clamp = (value) => Math.min(1, Math.max(0, value));
|
|
28
|
-
const
|
|
47
|
+
const readableOnDark = (hex) => {
|
|
48
|
+
const { c, h, l } = oklch(hex);
|
|
49
|
+
let lightness = l;
|
|
50
|
+
let color = hex;
|
|
51
|
+
while (chroma.contrast(color, DARK_SURFACE) < MIN_DARK_CONTRAST && lightness < 1) {
|
|
52
|
+
lightness = Math.min(1, lightness + .005);
|
|
53
|
+
color = chroma.oklch(lightness, c, h).hex();
|
|
54
|
+
}
|
|
55
|
+
return color;
|
|
56
|
+
};
|
|
57
|
+
const orderLightness = (lightness, direction) => {
|
|
58
|
+
const ordered = [...lightness];
|
|
59
|
+
for (let i = 10; i < ordered.length; i++) ordered[i] = direction > 0 ? Math.max(ordered[i], ordered[i - 1] + MIN_STEP_GAP) : Math.min(ordered[i], ordered[i - 1] - MIN_STEP_GAP);
|
|
60
|
+
for (let i = 8; i >= 0; i--) ordered[i] = direction > 0 ? Math.min(ordered[i], ordered[i + 1] - MIN_STEP_GAP) : Math.max(ordered[i], ordered[i + 1] + MIN_STEP_GAP);
|
|
61
|
+
return ordered.map(clamp);
|
|
62
|
+
};
|
|
63
|
+
const retintSolid = (steps, target, hex, direction) => {
|
|
29
64
|
const anchor = oklch(steps[ANCHOR]);
|
|
30
65
|
const ratio = anchor.c > 0 ? Math.min(target.c / anchor.c, MAX_CHROMA_RATIO) : 0;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return chroma.oklch(lightness, c * ratio, target.h).hex();
|
|
36
|
-
});
|
|
66
|
+
const shift = target.l - anchor.l;
|
|
67
|
+
const source = steps.map(oklch);
|
|
68
|
+
const lightness = orderLightness(source.map(({ l }, i) => i === ANCHOR ? target.l : l + SHIFT_WEIGHT[i] * shift), direction);
|
|
69
|
+
return source.map(({ c }, i) => i === ANCHOR ? hex : chroma.oklch(lightness[i], c * ratio, target.h).hex());
|
|
37
70
|
};
|
|
38
71
|
const retintAlpha = (steps, solid, target) => {
|
|
39
72
|
const anchor = oklch(solid[ANCHOR]);
|
|
@@ -50,11 +83,13 @@ const generatePrimaryScale = (color) => {
|
|
|
50
83
|
const cached = cache.get(hex);
|
|
51
84
|
if (cached) return cached;
|
|
52
85
|
const target = oklch(hex);
|
|
53
|
-
const preset = colorScales[nearestPreset(target
|
|
86
|
+
const preset = colorScales[nearestPreset(target)];
|
|
87
|
+
const darkHex = readableOnDark(hex);
|
|
88
|
+
const darkTarget = oklch(darkHex);
|
|
54
89
|
const scale = {
|
|
55
|
-
dark: retintSolid(preset.dark,
|
|
56
|
-
darkA: retintAlpha(preset.darkA, preset.dark,
|
|
57
|
-
light: retintSolid(preset.light, target, hex),
|
|
90
|
+
dark: retintSolid(preset.dark, darkTarget, darkHex, 1),
|
|
91
|
+
darkA: retintAlpha(preset.darkA, preset.dark, darkTarget),
|
|
92
|
+
light: retintSolid(preset.light, target, hex, -1),
|
|
58
93
|
lightA: retintAlpha(preset.lightA, preset.light, target)
|
|
59
94
|
};
|
|
60
95
|
cache.set(hex, scale);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customPrimary.mjs","names":[],"sources":["../../../src/styles/theme/customPrimary.ts"],"sourcesContent":["import chroma from 'chroma-js';\n\nimport { colorScales } from '@/color/colors';\nimport type { ColorScaleItem } from '@/color/types';\n\nimport { type PrimaryColors, primaryColors } from '../customTheme';\n\nexport type CustomPrimaryColor = `#${string}`;\nexport type LobePrimaryColor = PrimaryColors | CustomPrimaryColor;\n\nconst HEX = /^#[\\da-f]{6}$/i;\n\nexport const isCustomPrimaryColor = (value?: string): value is CustomPrimaryColor =>\n !!value && HEX.test(value);\n\nconst ANCHOR = 9;\nconst
|
|
1
|
+
{"version":3,"file":"customPrimary.mjs","names":[],"sources":["../../../src/styles/theme/customPrimary.ts"],"sourcesContent":["import chroma from 'chroma-js';\n\nimport { colorScales, gray } from '@/color/colors';\nimport type { ColorScaleItem } from '@/color/types';\n\nimport { type PrimaryColors, primaryColors } from '../customTheme';\n\nexport type CustomPrimaryColor = `#${string}`;\nexport type LobePrimaryColor = PrimaryColors | CustomPrimaryColor;\n\nconst HEX = /^#[\\da-f]{6}$/i;\n\nexport const isCustomPrimaryColor = (value?: string): value is CustomPrimaryColor =>\n !!value && HEX.test(value);\n\nconst ANCHOR = 9;\nconst SHIFT_WEIGHT = [0, 0, 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1, 0.5, 0];\nconst MIN_STEP_GAP = 0.015;\nconst LIGHTNESS_WEIGHT = 100;\nconst MAX_CHROMA_RATIO = 2;\nconst DARK_SURFACE = gray.dark[1];\nconst MIN_DARK_CONTRAST = 4.5;\n\nconst oklch = (color: string) => {\n const [l, c, h] = chroma(color).oklch();\n return { c, h: Number.isNaN(h) ? 0 : h, l };\n};\n\nconst hueDistance = (a: number, b: number) => {\n const d = Math.abs(a - b) % 360;\n return d > 180 ? 360 - d : d;\n};\n\nconst presetDistance = (name: PrimaryColors, target: ReturnType<typeof oklch>) => {\n const preset = oklch(primaryColors[name]);\n return hueDistance(preset.h, target.h) + LIGHTNESS_WEIGHT * Math.abs(preset.l - target.l);\n};\n\nconst nearestPreset = (target: ReturnType<typeof oklch>) =>\n (Object.keys(primaryColors) as PrimaryColors[]).reduce((best, name) =>\n presetDistance(name, target) < presetDistance(best, target) ? name : best,\n );\n\nconst clamp = (value: number) => Math.min(1, Math.max(0, value));\n\nconst readableOnDark = (hex: string) => {\n const { c, h, l } = oklch(hex);\n let lightness = l;\n let color = hex;\n while (chroma.contrast(color, DARK_SURFACE) < MIN_DARK_CONTRAST && lightness < 1) {\n lightness = Math.min(1, lightness + 0.005);\n color = chroma.oklch(lightness, c, h).hex();\n }\n return color;\n};\n\nconst orderLightness = (lightness: number[], direction: 1 | -1) => {\n const ordered = [...lightness];\n for (let i = ANCHOR + 1; i < ordered.length; i++)\n ordered[i] =\n direction > 0\n ? Math.max(ordered[i], ordered[i - 1] + MIN_STEP_GAP)\n : Math.min(ordered[i], ordered[i - 1] - MIN_STEP_GAP);\n for (let i = ANCHOR - 1; i >= 0; i--)\n ordered[i] =\n direction > 0\n ? Math.min(ordered[i], ordered[i + 1] - MIN_STEP_GAP)\n : Math.max(ordered[i], ordered[i + 1] + MIN_STEP_GAP);\n return ordered.map(clamp);\n};\n\ntype Steps = ColorScaleItem['light'];\n\nconst retintSolid = (\n steps: Steps,\n target: ReturnType<typeof oklch>,\n hex: string,\n direction: 1 | -1,\n): Steps => {\n const anchor = oklch(steps[ANCHOR]);\n const ratio = anchor.c > 0 ? Math.min(target.c / anchor.c, MAX_CHROMA_RATIO) : 0;\n const shift = target.l - anchor.l;\n const source = steps.map(oklch);\n const lightness = orderLightness(\n source.map(({ l }, i) => (i === ANCHOR ? target.l : l + SHIFT_WEIGHT[i] * shift)),\n direction,\n );\n\n return source.map(({ c }, i) =>\n i === ANCHOR ? hex : chroma.oklch(lightness[i], c * ratio, target.h).hex(),\n ) as Steps;\n};\n\nconst retintAlpha = (steps: Steps, solid: Steps, target: ReturnType<typeof oklch>): Steps => {\n const anchor = oklch(solid[ANCHOR]);\n const ratio = anchor.c > 0 ? Math.min(target.c / anchor.c, MAX_CHROMA_RATIO) : 0;\n\n return steps.map((step) => {\n const color = chroma(step);\n const { c, l } = oklch(step);\n return chroma\n .oklch(l, c * ratio, target.h)\n .alpha(color.alpha())\n .css();\n }) as Steps;\n};\n\nconst cache = new Map<string, ColorScaleItem>();\n\nexport const generatePrimaryScale = (color: CustomPrimaryColor): ColorScaleItem => {\n const hex = color.toLowerCase();\n const cached = cache.get(hex);\n if (cached) return cached;\n\n const target = oklch(hex);\n const preset = colorScales[nearestPreset(target)];\n const darkHex = readableOnDark(hex);\n const darkTarget = oklch(darkHex);\n const scale: ColorScaleItem = {\n dark: retintSolid(preset.dark, darkTarget, darkHex, 1),\n darkA: retintAlpha(preset.darkA, preset.dark, darkTarget),\n light: retintSolid(preset.light, target, hex, -1),\n lightA: retintAlpha(preset.lightA, preset.light, target),\n };\n\n cache.set(hex, scale);\n return scale;\n};\n"],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export type LobeAppearance = 'light' | 'dark';
|
|
|
7
7
|
export interface LobeThemeState {
|
|
8
8
|
appearance: LobeAppearance;
|
|
9
9
|
neutralColor?: NeutralColors;
|
|
10
|
+
palette?: string;
|
|
10
11
|
primaryColor?: LobePrimaryColor;
|
|
11
12
|
}
|
|
12
13
|
export declare const setLobeTheme: (state: Partial<LobeThemeState>, root?: HTMLElement) => void;
|
|
@@ -15,7 +16,7 @@ export interface ThemeScopeProps extends Partial<LobeThemeState> {
|
|
|
15
16
|
className?: string;
|
|
16
17
|
style?: CSSProperties;
|
|
17
18
|
}
|
|
18
|
-
export declare const ThemeScope: ({ appearance, children, className, neutralColor, primaryColor, style }: ThemeScopeProps) => import("react").JSX.Element;
|
|
19
|
+
export declare const ThemeScope: ({ appearance, children, className, neutralColor, palette, primaryColor, style }: ThemeScopeProps) => import("react").JSX.Element;
|
|
19
20
|
export declare const useThemeMode: () => {
|
|
20
21
|
appearance: LobeAppearance;
|
|
21
22
|
isDarkMode: boolean;
|
|
@@ -41,9 +42,10 @@ export interface LobeThemeScriptProps {
|
|
|
41
42
|
appearance?: LobeAppearance | 'system';
|
|
42
43
|
neutralColor?: NeutralColors;
|
|
43
44
|
nonce?: string;
|
|
45
|
+
palette?: string;
|
|
44
46
|
primaryColor?: LobePrimaryColor;
|
|
45
47
|
}
|
|
46
|
-
export declare const LobeThemeScript: ({ appearance, neutralColor, nonce, primaryColor }: LobeThemeScriptProps) => import("react").JSX.Element;
|
|
48
|
+
export declare const LobeThemeScript: ({ appearance, neutralColor, nonce, palette, primaryColor }: LobeThemeScriptProps) => import("react").JSX.Element;
|
|
47
49
|
//#endregion
|
|
48
50
|
export {};
|
|
49
51
|
//# sourceMappingURL=scope.d.mts.map
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { getPaletteRevision, isRegisteredPalette, subscribePalettes } from "./customPalette.mjs";
|
|
2
3
|
import { isCustomPrimaryColor } from "./customPrimary.mjs";
|
|
3
4
|
import { staticToken } from "./token/static.mjs";
|
|
4
5
|
import { createLobeToken } from "./createLobeToken.mjs";
|
|
5
|
-
import { getCustomPrimaryCss } from "./themeCss.mjs";
|
|
6
|
+
import { getCustomPaletteCss, getCustomPrimaryCss } from "./themeCss.mjs";
|
|
6
7
|
import { createContext, use, useMemo, useSyncExternalStore } from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
//#region src/styles/theme/scope.tsx
|
|
9
10
|
const ATTRIBUTES = [
|
|
10
11
|
"data-theme",
|
|
11
12
|
"data-primary-color",
|
|
12
|
-
"data-neutral-color"
|
|
13
|
+
"data-neutral-color",
|
|
14
|
+
"data-palette"
|
|
13
15
|
];
|
|
14
|
-
const toAttributes = ({ appearance, neutralColor, primaryColor }) => ({
|
|
16
|
+
const toAttributes = ({ appearance, neutralColor, palette, primaryColor }) => ({
|
|
15
17
|
"data-neutral-color": neutralColor,
|
|
18
|
+
"data-palette": palette,
|
|
16
19
|
"data-primary-color": primaryColor,
|
|
17
20
|
"data-theme": appearance
|
|
18
21
|
});
|
|
@@ -26,6 +29,18 @@ const ensureCustomPrimaryStyle = (color, doc) => {
|
|
|
26
29
|
style.textContent = getCustomPrimaryCss(color);
|
|
27
30
|
doc.head.append(style);
|
|
28
31
|
};
|
|
32
|
+
const paletteStyleId = (name) => `lobe-palette-${name}`;
|
|
33
|
+
const ensurePaletteStyle = (name, doc) => {
|
|
34
|
+
const id = paletteStyleId(name);
|
|
35
|
+
let style = doc.getElementById(id);
|
|
36
|
+
if (!style) {
|
|
37
|
+
style = doc.createElement("style");
|
|
38
|
+
style.id = id;
|
|
39
|
+
doc.head.append(style);
|
|
40
|
+
}
|
|
41
|
+
const css = getCustomPaletteCss(name);
|
|
42
|
+
if (style.textContent !== css) style.textContent = css;
|
|
43
|
+
};
|
|
29
44
|
const setLobeTheme = (state, root = document.documentElement) => {
|
|
30
45
|
const next = {
|
|
31
46
|
...readThemeState(root),
|
|
@@ -33,15 +48,18 @@ const setLobeTheme = (state, root = document.documentElement) => {
|
|
|
33
48
|
};
|
|
34
49
|
next.primaryColor = normalizePrimary(next.primaryColor);
|
|
35
50
|
if (isCustomPrimaryColor(next.primaryColor)) ensureCustomPrimaryStyle(next.primaryColor, root.ownerDocument);
|
|
51
|
+
if (isRegisteredPalette(next.palette)) ensurePaletteStyle(next.palette, root.ownerDocument);
|
|
36
52
|
for (const [name, value] of Object.entries(toAttributes(next))) if (value) root.setAttribute(name, value);
|
|
37
53
|
else root.removeAttribute(name);
|
|
38
54
|
};
|
|
39
55
|
const readThemeState = (el) => ({
|
|
40
56
|
appearance: el.dataset.theme === "dark" ? "dark" : "light",
|
|
41
57
|
neutralColor: el.dataset.neutralColor || void 0,
|
|
58
|
+
palette: el.dataset.palette || void 0,
|
|
42
59
|
primaryColor: el.dataset.primaryColor || void 0
|
|
43
60
|
});
|
|
44
|
-
const stateKey = (state) => `${state.appearance}|${state.primaryColor ?? ""}|${state.neutralColor ?? ""}`;
|
|
61
|
+
const stateKey = (state) => `${state.appearance}|${state.primaryColor ?? ""}|${state.neutralColor ?? ""}|${state.palette ?? ""}`;
|
|
62
|
+
const usePaletteRevision = () => useSyncExternalStore(subscribePalettes, getPaletteRevision, getPaletteRevision);
|
|
45
63
|
const SERVER_STATE = { appearance: "light" };
|
|
46
64
|
let rootSnapshot = SERVER_STATE;
|
|
47
65
|
const getRootSnapshot = () => {
|
|
@@ -63,31 +81,43 @@ const useThemeState = () => {
|
|
|
63
81
|
const root = useSyncExternalStore(subscribeRoot, getRootSnapshot, () => SERVER_STATE);
|
|
64
82
|
return scoped ?? root;
|
|
65
83
|
};
|
|
66
|
-
const ThemeScope = ({ appearance, children, className, neutralColor, primaryColor, style }) => {
|
|
84
|
+
const ThemeScope = ({ appearance, children, className, neutralColor, palette, primaryColor, style }) => {
|
|
67
85
|
const parent = useThemeState();
|
|
68
86
|
const state = useMemo(() => ({
|
|
69
87
|
appearance: appearance ?? parent.appearance,
|
|
70
88
|
neutralColor: neutralColor ?? parent.neutralColor,
|
|
89
|
+
palette: palette ?? parent.palette,
|
|
71
90
|
primaryColor: normalizePrimary(primaryColor) ?? parent.primaryColor
|
|
72
91
|
}), [
|
|
73
92
|
appearance,
|
|
74
93
|
neutralColor,
|
|
94
|
+
palette,
|
|
75
95
|
primaryColor,
|
|
76
96
|
parent
|
|
77
97
|
]);
|
|
78
98
|
const customPrimary = isCustomPrimaryColor(state.primaryColor) ? state.primaryColor : void 0;
|
|
99
|
+
const paletteRevision = usePaletteRevision();
|
|
100
|
+
const customPalette = isRegisteredPalette(state.palette) ? state.palette : void 0;
|
|
79
101
|
return /* @__PURE__ */ jsxs(ThemeScopeContext, {
|
|
80
102
|
value: state,
|
|
81
|
-
children: [
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
style,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
103
|
+
children: [
|
|
104
|
+
customPrimary && /* @__PURE__ */ jsx("style", {
|
|
105
|
+
href: customPrimaryStyleId(customPrimary),
|
|
106
|
+
precedence: "lobe-theme",
|
|
107
|
+
children: getCustomPrimaryCss(customPrimary)
|
|
108
|
+
}),
|
|
109
|
+
customPalette && /* @__PURE__ */ jsx("style", {
|
|
110
|
+
href: `${paletteStyleId(customPalette)}-${paletteRevision}`,
|
|
111
|
+
precedence: "lobe-theme",
|
|
112
|
+
children: getCustomPaletteCss(customPalette)
|
|
113
|
+
}),
|
|
114
|
+
/* @__PURE__ */ jsx("div", {
|
|
115
|
+
className,
|
|
116
|
+
style,
|
|
117
|
+
...toAttributes(state),
|
|
118
|
+
children
|
|
119
|
+
})
|
|
120
|
+
]
|
|
91
121
|
});
|
|
92
122
|
};
|
|
93
123
|
const useThemeMode = () => {
|
|
@@ -100,7 +130,7 @@ const useThemeMode = () => {
|
|
|
100
130
|
const themeCache = /* @__PURE__ */ new Map();
|
|
101
131
|
const useTheme = () => {
|
|
102
132
|
const state = useThemeState();
|
|
103
|
-
const key = stateKey(state)
|
|
133
|
+
const key = `${stateKey(state)}@${usePaletteRevision()}`;
|
|
104
134
|
let theme = themeCache.get(key);
|
|
105
135
|
if (!theme) {
|
|
106
136
|
theme = {
|
|
@@ -151,14 +181,17 @@ const subscribeResponsive = (onChange) => {
|
|
|
151
181
|
};
|
|
152
182
|
};
|
|
153
183
|
const useResponsive = () => useSyncExternalStore(subscribeResponsive, getResponsiveSnapshot, () => SERVER_RESPONSIVE);
|
|
154
|
-
const LobeThemeScript = ({ appearance, neutralColor, nonce, primaryColor }) => {
|
|
184
|
+
const LobeThemeScript = ({ appearance, neutralColor, nonce, palette, primaryColor }) => {
|
|
155
185
|
const primary = normalizePrimary(primaryColor);
|
|
156
|
-
const
|
|
157
|
-
|
|
186
|
+
const styles = [];
|
|
187
|
+
if (isCustomPrimaryColor(primary)) styles.push([customPrimaryStyleId(primary), getCustomPrimaryCss(primary)]);
|
|
188
|
+
if (isRegisteredPalette(palette)) styles.push([paletteStyleId(palette), getCustomPaletteCss(palette)]);
|
|
189
|
+
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([
|
|
158
190
|
appearance ?? null,
|
|
159
191
|
primary ?? null,
|
|
160
192
|
neutralColor ?? null,
|
|
161
|
-
|
|
193
|
+
palette ?? null,
|
|
194
|
+
styles
|
|
162
195
|
])})`;
|
|
163
196
|
return /* @__PURE__ */ jsx("script", {
|
|
164
197
|
suppressHydrationWarning: true,
|
|
@@ -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 {\n type CustomPrimaryColor,\n isCustomPrimaryColor,\n type LobePrimaryColor,\n} from './customPrimary';\nimport { 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 primaryColor?: LobePrimaryColor;\n}\n\nconst ATTRIBUTES = ['data-theme', 'data-primary-color', 'data-neutral-color'];\n\nconst toAttributes = ({ appearance, neutralColor, primaryColor }: LobeThemeState) => ({\n 'data-neutral-color': neutralColor,\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\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 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 primaryColor: (el.dataset.primaryColor as LobePrimaryColor) || undefined,\n});\n\nconst stateKey = (state: LobeThemeState) =>\n `${state.appearance}|${state.primaryColor ?? ''}|${state.neutralColor ?? ''}`;\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 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 primaryColor: normalizePrimary(primaryColor) ?? parent.primaryColor,\n }),\n [appearance, neutralColor, primaryColor, parent],\n );\n const customPrimary = isCustomPrimaryColor(state.primaryColor) ? state.primaryColor : 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 <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);\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 primaryColor?: LobePrimaryColor;\n}\n\nexport const LobeThemeScript = ({\n appearance,\n neutralColor,\n nonce,\n primaryColor,\n}: LobeThemeScriptProps) => {\n const primary = normalizePrimary(primaryColor);\n const custom = isCustomPrimaryColor(primary)\n ? [customPrimaryStyleId(primary), getCustomPrimaryCss(primary)]\n : [null, null];\n const args = JSON.stringify([\n appearance ?? null,\n primary ?? null,\n neutralColor ?? null,\n ...custom,\n ]);\n const script = `(function(a,p,n,i,c){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(c&&!document.getElementById(i)){var s=document.createElement('style');s.id=i;s.textContent=c;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 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":";;;;;;;;;AA+BA,MAAM,aAAa;CAAC;CAAc;CAAsB;CAAsB;AAAc;AAE5F,MAAM,gBAAgB,EAAE,YAAY,cAAc,SAAS,oBAAoC;CAC7F,sBAAsB;CACtB,gBAAgB;CAChB,sBAAsB;CACtB,cAAc;AAChB;AAEA,MAAM,oBAAoB,UACxB,qBAAqB,KAAK,IAAK,MAAM,YAAY,IAA2B;AAE9E,MAAM,wBAAwB,UAA8B,gBAAgB,MAAM,MAAM,CAAC;AAEzF,MAAM,4BAA4B,OAA2B,QAAkB;CAC7E,MAAM,KAAK,qBAAqB,KAAK;CACrC,IAAI,IAAI,eAAe,EAAE,GAAG;CAC5B,MAAM,QAAQ,IAAI,cAAc,OAAO;CACvC,MAAM,KAAK;CACX,MAAM,cAAc,oBAAoB,KAAK;CAC7C,IAAI,KAAK,OAAO,KAAK;AACvB;AAEA,MAAM,kBAAkB,SAAiB,gBAAgB;AAEzD,MAAM,sBAAsB,MAAc,QAAkB;CAC1D,MAAM,KAAK,eAAe,IAAI;CAC9B,IAAI,QAAQ,IAAI,eAAe,EAAE;CACjC,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,cAAc,OAAO;EACjC,MAAM,KAAK;EACX,IAAI,KAAK,OAAO,KAAK;CACvB;CACA,MAAM,MAAM,oBAAoB,IAAI;CACpC,IAAI,MAAM,gBAAgB,KAAK,MAAM,cAAc;AACrD;AAEA,MAAa,gBACX,OACA,OAAoB,SAAS,oBAC1B;CACH,MAAM,OAAO;EAAE,GAAG,eAAe,IAAI;EAAG,GAAG;CAAM;CACjD,KAAK,eAAe,iBAAiB,KAAK,YAAY;CACtD,IAAI,qBAAqB,KAAK,YAAY,GACxC,yBAAyB,KAAK,cAAc,KAAK,aAAa;CAChE,IAAI,oBAAoB,KAAK,OAAO,GAAG,mBAAmB,KAAK,SAAS,KAAK,aAAa;CAC1F,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,aAAa,IAAI,CAAC,GAC3D,IAAI,OAAO,KAAK,aAAa,MAAM,KAAK;MACnC,KAAK,gBAAgB,IAAI;AAElC;AAEA,MAAM,kBAAkB,QAAqC;CAC3D,YAAY,GAAG,QAAQ,UAAU,SAAS,SAAS;CACnD,cAAe,GAAG,QAAQ,gBAAkC,KAAA;CAC5D,SAAS,GAAG,QAAQ,WAAW,KAAA;CAC/B,cAAe,GAAG,QAAQ,gBAAqC,KAAA;AACjE;AAEA,MAAM,YAAY,UAChB,GAAG,MAAM,WAAW,GAAG,MAAM,gBAAgB,GAAG,GAAG,MAAM,gBAAgB,GAAG,GAAG,MAAM,WAAW;AAElG,MAAM,2BACJ,qBAAqB,mBAAmB,oBAAoB,kBAAkB;AAEhF,MAAM,eAA+B,EAAE,YAAY,QAAQ;AAC3D,IAAI,eAA+B;AAEnC,MAAM,wBAAwB;CAC5B,MAAM,OAAO,eAAe,SAAS,eAAe;CACpD,IAAI,SAAS,IAAI,MAAM,SAAS,YAAY,GAAG,eAAe;CAC9D,OAAO;AACT;AAEA,MAAM,iBAAiB,aAAyB;CAC9C,MAAM,WAAW,IAAI,iBAAiB,QAAQ;CAC9C,SAAS,QAAQ,SAAS,iBAAiB;EAAE,iBAAiB;EAAY,YAAY;CAAK,CAAC;CAC5F,aAAa,SAAS,WAAW;AACnC;AAEA,MAAM,oBAAoB,cAAqC,IAAI;AAEnE,MAAM,sBAAsB;CAC1B,MAAM,SAAS,IAAI,iBAAiB;CACpC,MAAM,OAAO,qBAAqB,eAAe,uBAAuB,YAAY;CACpF,OAAO,UAAU;AACnB;AAQA,MAAa,cAAc,EACzB,YACA,UACA,WACA,cACA,SACA,cACA,YACqB;CACrB,MAAM,SAAS,cAAc;CAC7B,MAAM,QAAQ,eACL;EACL,YAAY,cAAc,OAAO;EACjC,cAAc,gBAAgB,OAAO;EACrC,SAAS,WAAW,OAAO;EAC3B,cAAc,iBAAiB,YAAY,KAAK,OAAO;CACzD,IACA;EAAC;EAAY;EAAc;EAAS;EAAc;CAAM,CAC1D;CACA,MAAM,gBAAgB,qBAAqB,MAAM,YAAY,IAAI,MAAM,eAAe,KAAA;CACtF,MAAM,kBAAkB,mBAAmB;CAC3C,MAAM,gBAAgB,oBAAoB,MAAM,OAAO,IAAI,MAAM,UAAU,KAAA;CAE3E,OACE,qBAAC,mBAAD;EAAmB,OAAO;EAA1B,UAAA;GACG,iBACC,oBAAC,SAAD;IAAO,MAAM,qBAAqB,aAAa;IAAG,YAAW;IAC1D,UAAA,oBAAoB,aAAa;GAC7B,CAAA;GAER,iBACC,oBAAC,SAAD;IAAO,MAAM,GAAG,eAAe,aAAa,EAAE,GAAG;IAAmB,YAAW;IAC5E,UAAA,oBAAoB,aAAa;GAC7B,CAAA;GAET,oBAAC,OAAD;IAAgB;IAAkB;IAAO,GAAI,aAAa,KAAK;IAC5D;GACE,CAAA;EACY;;AAEvB;AAEA,MAAa,qBAAqB;CAChC,MAAM,EAAE,eAAe,cAAc;CACrC,OAAO,eAAe;EAAE;EAAY,YAAY,eAAe;CAAO,IAAI,CAAC,UAAU,CAAC;AACxF;AAIA,MAAM,6BAAa,IAAI,IAAuB;AAE9C,MAAa,iBAA4B;CACvC,MAAM,QAAQ,cAAc;CAC5B,MAAM,MAAM,GAAG,SAAS,KAAK,EAAE,GAAG,mBAAmB;CACrD,IAAI,QAAQ,WAAW,IAAI,GAAG;CAC9B,IAAI,CAAC,OAAO;EACV,QAAQ;GACN,GAAG,gBAAgB,KAAK;GACxB,YAAY,MAAM;GAClB,YAAY,MAAM,eAAe;EACnC;EACA,WAAW,IAAI,KAAK,KAAK;CAC3B;CACA,OAAO;AACT;AAEA,MAAM,oBAAoB;CACxB,IAAI,eAAe,YAAY,SAAS;CACxC,IAAI,eAAe,YAAY,SAAS;CACxC,IAAI,eAAe,YAAY,SAAS;CACxC,IAAI,eAAe,YAAY,SAAS;CACxC,IAAI,eAAe,YAAY,YAAY;CAC3C,KAAK,eAAe,YAAY,UAAU;CAC1C,MAAM,eAAe,YAAY,WAAW;AAC9C;AAQA,MAAM,gBAAgB,aAA2D;CAC/E,GAAG;CACH,SAAS,QAAQ;CACjB,QAAQ,QAAQ;CAChB,QAAQ,QAAQ;CAChB,QAAQ,QAAQ;AAClB;AAEA,MAAM,oBAAoB,aAAa;CACrC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,MAAM;AACR,CAAC;AACD,IAAI,qBAAqB;AAEzB,MAAM,8BAA8B;CAClC,MAAM,UAAU,OAAO,YACrB,OAAO,QAAQ,iBAAiB,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,WAAW,KAAK,CAAC,CAAC,OAAO,CAAC,CAC1F;CAIA,IAHiB,OAAO,KAAK,OAAO,CAAC,CAAkB,MACpD,QAAQ,QAAQ,SAAS,mBAAmB,IAErC,GAAG,qBAAqB,aAAa,OAAO;CACtD,OAAO;AACT;AAEA,MAAM,uBAAuB,aAAyB;CACpD,MAAM,QAAQ,OAAO,OAAO,iBAAiB,CAAC,CAAC,KAAK,UAAU,WAAW,KAAK,CAAC;CAC/E,KAAK,MAAM,QAAQ,OAAO,KAAK,iBAAiB,UAAU,QAAQ;CAClE,aAAa;EACX,KAAK,MAAM,QAAQ,OAAO,KAAK,oBAAoB,UAAU,QAAQ;CACvE;AACF;AAEA,MAAa,sBACX,qBAAqB,qBAAqB,6BAA6B,iBAAiB;AAU1F,MAAa,mBAAmB,EAC9B,YACA,cACA,OACA,SACA,mBAC0B;CAC1B,MAAM,UAAU,iBAAiB,YAAY;CAC7C,MAAM,SAA6B,CAAC;CACpC,IAAI,qBAAqB,OAAO,GAC9B,OAAO,KAAK,CAAC,qBAAqB,OAAO,GAAG,oBAAoB,OAAO,CAAC,CAAC;CAC3E,IAAI,oBAAoB,OAAO,GAC7B,OAAO,KAAK,CAAC,eAAe,OAAO,GAAG,oBAAoB,OAAO,CAAC,CAAC;CAQrE,MAAM,SAAS,uiBAPF,KAAK,UAAU;EAC1B,cAAc;EACd,WAAW;EACX,gBAAgB;EAChB,WAAW;EACX;CACF,CACyjB,EAAE;CAE3jB,OACE,oBAAC,UAAD;EAAQ,0BAAA;EAAyB,yBAAyB,EAAE,QAAQ,OAAO;EAAU;CAAQ,CAAA;AAEjG"}
|
|
@@ -1,6 +1,7 @@
|
|
|
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
|
+
export declare const getCustomPaletteCss: (name: string) => string;
|
|
4
5
|
export declare const getThemeCss: () => string;
|
|
5
6
|
export declare const getGlobalCss: () => string;
|
|
6
7
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRegisteredPalette } from "./customPalette.mjs";
|
|
1
2
|
import { neutralColors, primaryColors } from "../customTheme.mjs";
|
|
2
3
|
import { createLobeTokenGroups } from "./createLobeToken.mjs";
|
|
3
4
|
import { toCssVarName, toCssVariables } from "../css.mjs";
|
|
@@ -56,6 +57,20 @@ const getCustomPrimaryCss = (color) => {
|
|
|
56
57
|
primaryColor: hex
|
|
57
58
|
}).primary))).join("\n\n");
|
|
58
59
|
};
|
|
60
|
+
const getCustomPaletteCss = (name) => {
|
|
61
|
+
if (!isRegisteredPalette(name)) return "";
|
|
62
|
+
return ["light", "dark"].map((appearance) => {
|
|
63
|
+
const { neutral, palette } = createLobeTokenGroups({
|
|
64
|
+
appearance,
|
|
65
|
+
palette: name
|
|
66
|
+
});
|
|
67
|
+
return rule(`[data-palette='${name}']${appearanceSelector(appearance)}`, toCssVariables({
|
|
68
|
+
...palette,
|
|
69
|
+
colorErrorOutline: neutral.colorErrorOutline,
|
|
70
|
+
colorWarningOutline: neutral.colorWarningOutline
|
|
71
|
+
}));
|
|
72
|
+
}).join("\n\n");
|
|
73
|
+
};
|
|
59
74
|
const essentialCss = `@layer lobe-ui {
|
|
60
75
|
.lobe-brand-loading path {
|
|
61
76
|
fill: currentcolor;
|
|
@@ -335,6 +350,6 @@ const getThemeCss = () => cached ??= [
|
|
|
335
350
|
].join("\n\n");
|
|
336
351
|
const getGlobalCss = () => `${layerOrder}\n\n${globalCss}`;
|
|
337
352
|
//#endregion
|
|
338
|
-
export { getCustomPrimaryCss, getGlobalCss, getThemeCss };
|
|
353
|
+
export { getCustomPaletteCss, getCustomPrimaryCss, getGlobalCss, getThemeCss };
|
|
339
354
|
|
|
340
355
|
//# 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 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\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 { 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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"}
|