@adea-ai/ui 0.130.4 → 0.131.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 +15 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts +7 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js +39 -13
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-choices.js +222 -116
- package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.js +6 -1
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-types.d.ts +22 -3
- package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -1
- package/dist/lib/accent-presets.d.ts +7 -0
- package/dist/lib/accent-presets.d.ts.map +1 -1
- package/dist/lib/accent-presets.js +2 -2
- package/dist/lib/accent-presets.js.map +1 -1
- package/dist/lib/theme-projection.d.ts +23 -0
- package/dist/lib/theme-projection.d.ts.map +1 -0
- package/dist/lib/theme-projection.js +48 -0
- package/dist/lib/theme-projection.js.map +1 -0
- package/dist/lib/theme-records.d.ts +2 -0
- package/dist/lib/theme-records.d.ts.map +1 -1
- package/dist/lib/theme-records.js.map +1 -1
- package/dist/r/lib.json +5 -0
- package/dist/r/registry.json +5 -0
- package/dist/r/src/components/composites/appearance-editor/accent-swatch-groups.tsx +44 -10
- package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +158 -80
- package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +7 -2
- package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +22 -3
- package/dist/r/src/lib/accent-presets.ts +8 -0
- package/dist/r/src/lib/theme-projection.ts +52 -0
- package/dist/r/src/lib/theme-records.ts +3 -0
- package/package.json +1 -1
- package/registry.json +5 -0
- package/src/components/composites/appearance-editor/accent-swatch-groups.tsx +44 -10
- package/src/components/composites/appearance-editor/appearance-choices.tsx +158 -80
- package/src/components/composites/appearance-editor/appearance-editor.tsx +7 -2
- package/src/components/composites/appearance-editor/appearance-types.ts +22 -3
- package/src/lib/accent-presets.ts +8 -0
- package/src/lib/theme-projection.ts +52 -0
- package/src/lib/theme-records.ts +3 -0
package/README.md
CHANGED
|
@@ -762,6 +762,21 @@ capability stays visibly unavailable. App-specific persisted versions and the
|
|
|
762
762
|
legacy `translucent` value need an app-owned adapter to the editor's `theme`
|
|
763
763
|
surface selection. The library does not silently migrate stored preferences.
|
|
764
764
|
|
|
765
|
+
A host recomposes the editor through props, never by forking it. Every option keeps
|
|
766
|
+
the default below, so an existing consumer renders as before:
|
|
767
|
+
|
|
768
|
+
| Prop | Default | What it changes |
|
|
769
|
+
| -------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
770
|
+
| `fontSettingsPlacement` | `inline` | `end` closes the option list with the typefaces, after Glass, Reduce transparency and Theme library. |
|
|
771
|
+
| `accentEntryStyle` | `swatches` | `labels` renders every choice as a named chip. `row` draws the presets as circles in one equally spaced line (it holds at 320px, where the grid wraps) and turns Custom into a button that opens the native colour selector: only a chosen colour changes the draft. |
|
|
772
|
+
| `showThemeDefaultAccent` | `true` | `false` drops the leading "Theme default" entry, for a host whose default accent already is a preset. |
|
|
773
|
+
| `showCustomAccentCaption` | `true` | `false` drops the "Custom" caption over the `swatches` style's custom chip. No effect on `labels` or `row`. |
|
|
774
|
+
| `showModeIcons` | `false` | A sun, moon or monitor glyph beside each mode card's label. |
|
|
775
|
+
| `triggerVariant` (popover) | `ghost` | `toolbar` holds the pressed rung while the sheet is open and repeats the palette glyph in the tooltip, like the other toolbar actions. |
|
|
776
|
+
|
|
777
|
+
`customAccentValue` seeds the native selector (`row`) and the draft the `swatches`
|
|
778
|
+
Custom chip commits; hand it your starting colour.
|
|
779
|
+
|
|
765
780
|
The component browser lane uses a real Vite/Solid/Tailwind build in headless
|
|
766
781
|
Chromium without an app server. It checks keyboard mode selection, nested menu
|
|
767
782
|
accessibility, focus and pointer dismissal, Escape, live-preview rollback,
|
|
@@ -23,6 +23,13 @@ type AccentSwatchGroupsProps = {
|
|
|
23
23
|
* colour reads as a duplicate choice.
|
|
24
24
|
*/
|
|
25
25
|
showThemeDefault?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* `grid` — the default — wraps at four to a line. `row` keeps every swatch on
|
|
28
|
+
* one line at a smaller size, the columns sharing the width equally, so a
|
|
29
|
+
* narrow panel does not wrap them; each colour is then the fill of an SVG
|
|
30
|
+
* circle, which is where a host that asserts on swatch colours reads it.
|
|
31
|
+
*/
|
|
32
|
+
layout?: 'grid' | 'row';
|
|
26
33
|
};
|
|
27
34
|
/**
|
|
28
35
|
* The accent choices, as ONE group: the theme's own primary first, then every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accent-swatch-groups.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/accent-swatch-groups.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accent-swatch-groups.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/accent-swatch-groups.tsx"],"names":[],"mappings":"AA2BA,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAC,CAAA;AAEF,KAAK,uBAAuB,GAAG;IAC7B,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAC5C,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACxB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,kCA6BhE"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { className, createComponent, effect, insert, setAttribute, setStyleProperty, template } from "solid-js/web";
|
|
2
3
|
import { For, Show } from "solid-js";
|
|
3
4
|
import { RadioGroup } from "@kobalte/core/radio-group";
|
|
4
5
|
//#region src/components/composites/appearance-editor/accent-swatch-groups.tsx
|
|
5
|
-
var _tmpl$ = /*#__PURE__*/ template(`<div
|
|
6
|
-
var _tmpl$2 = /*#__PURE__*/ template(`<
|
|
6
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div data-accent-grid>`);
|
|
7
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<svg class=size-full viewBox="0 0 16 16"aria-hidden=true><circle cx=8 cy=8 r=8>`);
|
|
7
8
|
var _tmpl$3 = /*#__PURE__*/ template(`<span class=sr-only>`);
|
|
9
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<span class="block size-full rounded-full"aria-hidden=true>`);
|
|
8
10
|
/**
|
|
9
11
|
* The accent choices, as ONE group: the theme's own primary first, then every
|
|
10
12
|
* preset the host feeds, each painted with its value for the resolved
|
|
@@ -15,6 +17,7 @@ var _tmpl$3 = /*#__PURE__*/ template(`<span class=sr-only>`);
|
|
|
15
17
|
*/
|
|
16
18
|
function AccentSwatchGroups(props) {
|
|
17
19
|
const presets = () => props.accentOptions.filter((option) => option.id !== "theme");
|
|
20
|
+
const row = () => props.layout === "row";
|
|
18
21
|
return (() => {
|
|
19
22
|
var _el$ = _tmpl$();
|
|
20
23
|
insert(_el$, createComponent(Show, {
|
|
@@ -27,6 +30,9 @@ function AccentSwatchGroups(props) {
|
|
|
27
30
|
label: "Theme default",
|
|
28
31
|
get color() {
|
|
29
32
|
return props.themeDefaultColor;
|
|
33
|
+
},
|
|
34
|
+
get row() {
|
|
35
|
+
return row();
|
|
30
36
|
}
|
|
31
37
|
});
|
|
32
38
|
}
|
|
@@ -44,9 +50,13 @@ function AccentSwatchGroups(props) {
|
|
|
44
50
|
},
|
|
45
51
|
get color() {
|
|
46
52
|
return (props.resolvedAppearance === "light" ? option.light : option.dark) ?? "";
|
|
53
|
+
},
|
|
54
|
+
get row() {
|
|
55
|
+
return row();
|
|
47
56
|
}
|
|
48
57
|
})
|
|
49
58
|
}), null);
|
|
59
|
+
effect(() => className(_el$, row() ? "grid auto-cols-fr grid-flow-col" : "grid grid-cols-4 gap-2"));
|
|
50
60
|
return _el$;
|
|
51
61
|
})();
|
|
52
62
|
}
|
|
@@ -58,19 +68,35 @@ function AccentSwatch(props) {
|
|
|
58
68
|
get ["data-accent-option"]() {
|
|
59
69
|
return props.id;
|
|
60
70
|
},
|
|
61
|
-
"class"
|
|
71
|
+
get ["class"]() {
|
|
72
|
+
return cn("rounded-full focus-within:ring-3 focus-within:ring-ring/50", { "flex justify-center": props.row });
|
|
73
|
+
},
|
|
62
74
|
get children() {
|
|
63
75
|
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
64
|
-
"class"
|
|
76
|
+
get ["class"]() {
|
|
77
|
+
return cn("block cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary", props.row ? "size-6" : "size-7");
|
|
78
|
+
},
|
|
65
79
|
get children() {
|
|
66
|
-
return [(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
return [createComponent(Show, {
|
|
81
|
+
get when() {
|
|
82
|
+
return props.row;
|
|
83
|
+
},
|
|
84
|
+
get fallback() {
|
|
85
|
+
return (() => {
|
|
86
|
+
var _el$5 = _tmpl$4();
|
|
87
|
+
effect((_$p) => setStyleProperty(_el$5, "background-color", props.color));
|
|
88
|
+
return _el$5;
|
|
89
|
+
})();
|
|
90
|
+
},
|
|
91
|
+
get children() {
|
|
92
|
+
var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild;
|
|
93
|
+
effect(() => setAttribute(_el$3, "fill", props.color));
|
|
94
|
+
return _el$2;
|
|
95
|
+
}
|
|
96
|
+
}), (() => {
|
|
97
|
+
var _el$4 = _tmpl$3();
|
|
98
|
+
insert(_el$4, () => props.label);
|
|
99
|
+
return _el$4;
|
|
74
100
|
})()];
|
|
75
101
|
}
|
|
76
102
|
})];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accent-swatch-groups.js","names":["RadioGroup","Radio","For","Show","AccentOption","Readonly","id","label","light","dark","AccentSwatchGroupsProps","accentOptions","themeAccentOptions","resolvedAppearance","themeDefaultColor","showThemeDefault","AccentSwatchGroups","props","presets","filter","option","_el$","_tmpl$","_$insert","_$createComponent","when","children","AccentSwatch","color","each","Item","value","data-accent-option","ItemInput","ItemLabel","_el$
|
|
1
|
+
{"version":3,"file":"accent-swatch-groups.js","names":["RadioGroup","Radio","For","Show","cn","AccentOption","Readonly","id","label","light","dark","AccentSwatchGroupsProps","accentOptions","themeAccentOptions","resolvedAppearance","themeDefaultColor","showThemeDefault","layout","AccentSwatchGroups","props","presets","filter","option","row","_el$","_tmpl$","_$insert","_$createComponent","when","children","AccentSwatch","color","each","_$effect","_$className","Item","value","data-accent-option","class","ItemInput","ItemLabel","fallback","_el$5","_tmpl$4","_$p","_$setStyleProperty","_el$2","_tmpl$2","_el$3","firstChild","_$setAttribute","_el$4","_tmpl$3","_$createComponent","_$className","Radio","_$setStyleProperty","_$setAttribute"],"sources":["../../../../src/components/composites/appearance-editor/accent-swatch-groups.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { RadioGroup as Radio } from '@kobalte/core/radio-group'\nimport { For, Show } from 'solid-js'\nimport { cn } from '#lib/utils'\n\ntype AccentOption = Readonly<{\n id: string\n label: string\n light?: string\n dark?: string\n}>\n\ntype AccentSwatchGroupsProps = {\n accentOptions: readonly AccentOption[]\n /**\n * Accepted for host compatibility and no longer rendered. The picker offers\n * one theme-scoped group — the theme's own primary followed by the presets —\n * instead of splitting additional presets and the theme pair's accent slots\n * into labelled groups of their own. A stored theme-accent id still resolves\n * (`resolveAccentPreset`) and is still described by the row; it is just no\n * longer offered as a swatch, and a host can stop feeding this list.\n */\n themeAccentOptions?: readonly AccentOption[]\n resolvedAppearance: 'light' | 'dark'\n themeDefaultColor: string\n /**\n * Whether the group leads with the \"Theme default\" swatch. Hosts whose\n * default accent already is a preset omit it — a second entry for the same\n * colour reads as a duplicate choice.\n */\n showThemeDefault?: boolean\n /**\n * `grid` — the default — wraps at four to a line. `row` keeps every swatch on\n * one line at a smaller size, the columns sharing the width equally, so a\n * narrow panel does not wrap them; each colour is then the fill of an SVG\n * circle, which is where a host that asserts on swatch colours reads it.\n */\n layout?: 'grid' | 'row'\n}\n\n/**\n * The accent choices, as ONE group: the theme's own primary first, then every\n * preset the host feeds, each painted with its value for the resolved\n * appearance — which is what makes the group theme-scoped rather than a\n * catalogue table. The custom-color entry is the host's (`AccentChoices`\n * renders it beside this grid), because whether a free-form colour is accepted\n * is the host's validation to own.\n */\nexport function AccentSwatchGroups(props: AccentSwatchGroupsProps) {\n const presets = () => props.accentOptions.filter((option) => option.id !== 'theme')\n const row = () => props.layout === 'row'\n\n return (\n <div\n class={row() ? 'grid auto-cols-fr grid-flow-col' : 'grid grid-cols-4 gap-2'}\n data-accent-grid\n >\n <Show when={props.showThemeDefault ?? true}>\n <AccentSwatch\n id=\"theme\"\n label=\"Theme default\"\n color={props.themeDefaultColor}\n row={row()}\n />\n </Show>\n <For each={presets()}>\n {(option) => (\n <AccentSwatch\n id={option.id}\n label={option.label}\n color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}\n row={row()}\n />\n )}\n </For>\n </div>\n )\n}\n\nfunction AccentSwatch(props: { id: string; label: string; color: string; row: boolean }) {\n return (\n <Radio.Item\n value={props.id}\n data-accent-option={props.id}\n class={cn('rounded-full focus-within:ring-3 focus-within:ring-ring/50', {\n 'flex justify-center': props.row,\n })}\n >\n <Radio.ItemInput />\n <Radio.ItemLabel\n class={cn(\n 'block cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary',\n props.row ? 'size-6' : 'size-7'\n )}\n >\n <Show\n when={props.row}\n fallback={\n <span\n class=\"block size-full rounded-full\"\n aria-hidden=\"true\"\n style={{ 'background-color': props.color }}\n />\n }\n >\n <svg class=\"size-full\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill={props.color} />\n </svg>\n </Show>\n <span class=\"sr-only\">{props.label}</span>\n </Radio.ItemLabel>\n </Radio.Item>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsEA,SAAgBkB,mBAAmBC,OAAgC;CACjE,MAAMC,gBAAgBD,MAAMP,cAAcS,QAAQC,WAAWA,OAAOf,OAAO,OAAO;CAClF,MAAMgB,YAAYJ,MAAMF,WAAW;CAEnC,cAAA;EAAA,IAAAO,OAAAC,OAAA;EAAAC,OAAAF,MAAAG,gBAKKxB,MAAI;GAAA,IAACyB,OAAI;IAAA,OAAET,MAAMH,oBAAoB;GAAI;GAAA,IAAAa,WAAA;IAAA,OAAAF,gBACvCG,cAAY;KACXvB,IAAE;KACFC,OAAK;KAAA,IACLuB,QAAK;MAAA,OAAEZ,MAAMJ;KAAiB;KAAA,IAC9BQ,MAAG;MAAA,OAAEA,IAAI;KAAC;IAAA,CAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAAG,OAAAF,MAAAG,gBAGbzB,KAAG;GAAA,IAAC8B,OAAI;IAAA,OAAEZ,QAAQ;GAAC;GAAAS,WAChBP,WAAMK,gBACLG,cAAY;IAAA,IACXvB,KAAE;KAAA,OAAEe,OAAOf;IAAE;IAAA,IACbC,QAAK;KAAA,OAAEc,OAAOd;IAAK;IAAA,IACnBuB,QAAK;KAAA,QAAGZ,MAAML,uBAAuB,UAAUQ,OAAOb,QAAQa,OAAOZ,SAAS;IAAE;IAAA,IAChFa,MAAG;KAAA,OAAEA,IAAI;IAAC;GAAA,CAAA;EAEb,CAAA,GAAA,IAAA;EAAAU,aAAAC,UAAAV,MAnBID,IAAI,IAAI,oCAAoC,wBAAwB,CAAA;EAAA,OAAAC;CAAA,EAAA,CAAA;AAuBjF;AAEA,SAASM,aAAaX,OAAmE;CACvF,OAAAQ,gBACG1B,WAAMkC,MAAI;EAAA,IACTC,QAAK;GAAA,OAAEjB,MAAMZ;EAAE;EAAA,KAAA,wBAAA;GAAA,OACKY,MAAMZ;EAAE;EAAA,KAAA,WAAA;GAAA,OACrBH,GAAG,8DAA8D,EACtE,uBAAuBe,MAAMI,IAC/B,CAAC;EAAC;EAAA,IAAAM,WAAA;GAAA,OAAA,CAAAF,gBAED1B,WAAMsC,WAAS,CAAA,CAAA,GAAAZ,gBACf1B,WAAMuC,WAAS;IAAA,KAAA,WAAA;KAAA,OACPpC,GACL,kIACAe,MAAMI,MAAM,WAAW,QACzB;IAAC;IAAA,IAAAM,WAAA;KAAA,OAAA,CAAAF,gBAEAxB,MAAI;MAAA,IACHyB,OAAI;OAAA,OAAET,MAAMI;MAAG;MAAA,IACfkB,WAAQ;OAAA,cAAA;QAAA,IAAAC,QAAAC,QAAA;QAAAV,QAAAW,QAAAC,iBAAAH,OAAA,oBAIyBvB,MAAMY,KAAK,CAAA;QAAA,OAAAW;OAAA,EAAA,CAAA;MAAA;MAAA,IAAAb,WAAA;OAAA,IAAAiB,QAAAC,QAAA,GAAAC,QAAAF,MAAAG;OAAAhB,aAAAiB,aAAAF,OAAA,QAKR7B,MAAMY,KAAK,CAAA;OAAA,OAAAe;MAAA;KAAA,CAAA,UAAA;MAAA,IAAAK,QAAAC,QAAA;MAAA1B,OAAAyB,aAG1BhC,MAAMX,KAAK;MAAA,OAAA2C;KAAA,EAAA,CAAA,CAAA;IAAA;GAAA,CAAA,CAAA;EAAA;CAAA,CAAA;AAI1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appearance-choices.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-choices.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"appearance-choices.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-choices.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAe/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,qBAAqB,kCAmDvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAOpE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,kCA6IzD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,qBAAqB,kCA6BxD"}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import { Button } from "../../ui/button/button.js";
|
|
2
|
+
import { Input } from "../../ui/input/input.js";
|
|
1
3
|
import { isThemeAccentId } from "../../../lib/theme-accents.js";
|
|
2
4
|
import { AccentSwatchGroups } from "./accent-swatch-groups.js";
|
|
3
5
|
import { ThemeMiniature, ThemeMiniatureSplit } from "./theme-preview.js";
|
|
4
6
|
import { createComponent, insert, memo, template } from "solid-js/web";
|
|
7
|
+
import { Monitor, Moon, Sun } from "lucide-solid";
|
|
5
8
|
import { For, Show } from "solid-js";
|
|
6
9
|
import { RadioGroup } from "@kobalte/core/radio-group";
|
|
7
10
|
//#region src/components/composites/appearance-editor/appearance-choices.tsx
|
|
8
11
|
var _tmpl$ = /*#__PURE__*/ template(`<span class="block h-20 w-full">`);
|
|
9
|
-
var _tmpl$2 = /*#__PURE__*/ template(`<span>`);
|
|
10
|
-
var _tmpl$3 = /*#__PURE__*/ template(`<
|
|
11
|
-
var _tmpl$4 = /*#__PURE__*/ template(`<
|
|
12
|
-
var _tmpl$5 = /*#__PURE__*/ template(`<div class="
|
|
12
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<span class="flex items-center justify-center gap-1.5">`);
|
|
13
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<span>`);
|
|
14
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<div class="flex w-full min-w-0 items-center gap-2"data-accent-choices>`);
|
|
15
|
+
var _tmpl$5 = /*#__PURE__*/ template(`<div class="grid grid-cols-2 gap-2 sm:grid-cols-3"data-accent-grid>`);
|
|
16
|
+
var _tmpl$6 = /*#__PURE__*/ template(`<span class="text-xs font-medium text-muted-foreground">Custom`);
|
|
17
|
+
var _tmpl$7 = /*#__PURE__*/ template(`<div class="flex flex-col gap-1">`);
|
|
13
18
|
var MODES = [
|
|
14
19
|
{
|
|
15
20
|
value: "system",
|
|
@@ -38,6 +43,11 @@ var SURFACES = [
|
|
|
38
43
|
label: "Opaque"
|
|
39
44
|
}
|
|
40
45
|
];
|
|
46
|
+
var MODE_ICONS = {
|
|
47
|
+
system: Monitor,
|
|
48
|
+
light: Sun,
|
|
49
|
+
dark: Moon
|
|
50
|
+
};
|
|
41
51
|
function ModeChoices(props) {
|
|
42
52
|
return createComponent(RadioGroup, {
|
|
43
53
|
get value() {
|
|
@@ -56,50 +66,69 @@ function ModeChoices(props) {
|
|
|
56
66
|
get children() {
|
|
57
67
|
return createComponent(For, {
|
|
58
68
|
each: MODES,
|
|
59
|
-
children: (option) =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
children: (option) => {
|
|
70
|
+
const Icon = MODE_ICONS[option.value];
|
|
71
|
+
return createComponent(RadioGroup.Item, {
|
|
72
|
+
get value() {
|
|
73
|
+
return option.value;
|
|
74
|
+
},
|
|
75
|
+
get ["data-mode"]() {
|
|
76
|
+
return option.value;
|
|
77
|
+
},
|
|
78
|
+
"class": "min-w-0 rounded-lg focus-within:ring-3 focus-within:ring-ring/50",
|
|
79
|
+
get children() {
|
|
80
|
+
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
81
|
+
"class": "flex cursor-pointer flex-col gap-2 rounded-lg border p-2 text-center text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
|
|
82
|
+
get children() {
|
|
83
|
+
return [(() => {
|
|
84
|
+
var _el$ = _tmpl$();
|
|
85
|
+
insert(_el$, createComponent(Show, {
|
|
86
|
+
get when() {
|
|
87
|
+
return option.value === "system";
|
|
88
|
+
},
|
|
89
|
+
get fallback() {
|
|
90
|
+
return createComponent(ThemeMiniature, { get theme() {
|
|
91
|
+
return memo(() => option.value === "light")() ? props.lightTheme : props.darkTheme;
|
|
92
|
+
} });
|
|
93
|
+
},
|
|
94
|
+
get children() {
|
|
95
|
+
return createComponent(ThemeMiniatureSplit, {
|
|
96
|
+
get light() {
|
|
97
|
+
return props.lightTheme;
|
|
98
|
+
},
|
|
99
|
+
get dark() {
|
|
100
|
+
return props.darkTheme;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}));
|
|
105
|
+
return _el$;
|
|
106
|
+
})(), createComponent(Show, {
|
|
74
107
|
get when() {
|
|
75
|
-
return
|
|
108
|
+
return props.showModeIcons;
|
|
76
109
|
},
|
|
77
110
|
get fallback() {
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
return (() => {
|
|
112
|
+
var _el$3 = _tmpl$3();
|
|
113
|
+
insert(_el$3, () => option.label);
|
|
114
|
+
return _el$3;
|
|
115
|
+
})();
|
|
81
116
|
},
|
|
82
117
|
get children() {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
118
|
+
var _el$2 = _tmpl$2();
|
|
119
|
+
insert(_el$2, createComponent(Icon, {
|
|
120
|
+
"aria-hidden": "true",
|
|
121
|
+
"class": "size-3.5"
|
|
122
|
+
}), null);
|
|
123
|
+
insert(_el$2, () => option.label, null);
|
|
124
|
+
return _el$2;
|
|
91
125
|
}
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})()];
|
|
99
|
-
}
|
|
100
|
-
})];
|
|
101
|
-
}
|
|
102
|
-
})
|
|
126
|
+
})];
|
|
127
|
+
}
|
|
128
|
+
})];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
103
132
|
});
|
|
104
133
|
}
|
|
105
134
|
});
|
|
@@ -118,6 +147,8 @@ function AccentChoices(props) {
|
|
|
118
147
|
const resolvedAppearance = () => props.draft.mode === "system" ? props.resolvedAppearance : props.draft.mode;
|
|
119
148
|
const accentSelection = () => isCustomAccent(props) ? "custom" : props.draft.accent;
|
|
120
149
|
const showThemeDefault = () => props.showThemeDefaultAccent ?? true;
|
|
150
|
+
const entryStyle = () => props.accentEntryStyle ?? "swatches";
|
|
151
|
+
const themeDefaultColor = () => resolvedAppearance() === "light" ? props.lightTheme.colors.accent : props.darkTheme.colors.accent;
|
|
121
152
|
const labelEntries = () => {
|
|
122
153
|
const presets = props.accentOptions.filter((option) => option.id !== "theme");
|
|
123
154
|
return showThemeDefault() ? [{
|
|
@@ -125,24 +156,124 @@ function AccentChoices(props) {
|
|
|
125
156
|
label: "Theme default"
|
|
126
157
|
}, ...presets] : presets;
|
|
127
158
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
159
|
+
let colorPicker;
|
|
160
|
+
const openCustomColor = () => {
|
|
161
|
+
if (!colorPicker || props.saving) return;
|
|
162
|
+
if (typeof colorPicker.showPicker === "function") colorPicker.showPicker();
|
|
163
|
+
else colorPicker.click();
|
|
164
|
+
};
|
|
165
|
+
return createComponent(Show, {
|
|
166
|
+
get when() {
|
|
167
|
+
return entryStyle() === "row";
|
|
131
168
|
},
|
|
132
|
-
get
|
|
133
|
-
return
|
|
169
|
+
get fallback() {
|
|
170
|
+
return createComponent(RadioGroup, {
|
|
171
|
+
get value() {
|
|
172
|
+
return accentSelection();
|
|
173
|
+
},
|
|
174
|
+
get disabled() {
|
|
175
|
+
return props.saving;
|
|
176
|
+
},
|
|
177
|
+
orientation: "horizontal",
|
|
178
|
+
"aria-label": "Accent",
|
|
179
|
+
"class": "flex flex-col items-start gap-3",
|
|
180
|
+
onChange: (accent) => props.onChange({ accent: accent === "custom" ? props.customAccentValue ?? "" : accent }),
|
|
181
|
+
get children() {
|
|
182
|
+
return createComponent(Show, {
|
|
183
|
+
get when() {
|
|
184
|
+
return entryStyle() === "labels";
|
|
185
|
+
},
|
|
186
|
+
get fallback() {
|
|
187
|
+
return [createComponent(AccentSwatchGroups, {
|
|
188
|
+
get accentOptions() {
|
|
189
|
+
return props.accentOptions;
|
|
190
|
+
},
|
|
191
|
+
get resolvedAppearance() {
|
|
192
|
+
return resolvedAppearance();
|
|
193
|
+
},
|
|
194
|
+
get showThemeDefault() {
|
|
195
|
+
return showThemeDefault();
|
|
196
|
+
},
|
|
197
|
+
get themeDefaultColor() {
|
|
198
|
+
return themeDefaultColor();
|
|
199
|
+
}
|
|
200
|
+
}), (() => {
|
|
201
|
+
var _el$6 = _tmpl$7();
|
|
202
|
+
insert(_el$6, createComponent(Show, {
|
|
203
|
+
get when() {
|
|
204
|
+
return props.showCustomAccentCaption ?? true;
|
|
205
|
+
},
|
|
206
|
+
get children() {
|
|
207
|
+
return _tmpl$6();
|
|
208
|
+
}
|
|
209
|
+
}), null);
|
|
210
|
+
insert(_el$6, createComponent(RadioGroup.Item, {
|
|
211
|
+
value: "custom",
|
|
212
|
+
get children() {
|
|
213
|
+
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
214
|
+
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
215
|
+
children: "Custom"
|
|
216
|
+
})];
|
|
217
|
+
}
|
|
218
|
+
}), null);
|
|
219
|
+
return _el$6;
|
|
220
|
+
})()];
|
|
221
|
+
},
|
|
222
|
+
get children() {
|
|
223
|
+
var _el$5 = _tmpl$5();
|
|
224
|
+
insert(_el$5, createComponent(For, {
|
|
225
|
+
get each() {
|
|
226
|
+
return labelEntries();
|
|
227
|
+
},
|
|
228
|
+
children: (option) => createComponent(RadioGroup.Item, {
|
|
229
|
+
get value() {
|
|
230
|
+
return option.id;
|
|
231
|
+
},
|
|
232
|
+
"class": "min-w-0",
|
|
233
|
+
get ["data-accent-option"]() {
|
|
234
|
+
return option.id;
|
|
235
|
+
},
|
|
236
|
+
get children() {
|
|
237
|
+
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
238
|
+
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
239
|
+
get children() {
|
|
240
|
+
return option.label;
|
|
241
|
+
}
|
|
242
|
+
})];
|
|
243
|
+
}
|
|
244
|
+
})
|
|
245
|
+
}), null);
|
|
246
|
+
insert(_el$5, createComponent(RadioGroup.Item, {
|
|
247
|
+
value: "custom",
|
|
248
|
+
"class": "min-w-0",
|
|
249
|
+
get children() {
|
|
250
|
+
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
251
|
+
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
252
|
+
children: "Custom"
|
|
253
|
+
})];
|
|
254
|
+
}
|
|
255
|
+
}), null);
|
|
256
|
+
return _el$5;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
});
|
|
134
261
|
},
|
|
135
|
-
orientation: "horizontal",
|
|
136
|
-
"aria-label": "Accent",
|
|
137
|
-
"class": "flex flex-col items-start gap-3",
|
|
138
|
-
onChange: (accent) => props.onChange({ accent: accent === "custom" ? props.customAccentValue ?? "" : accent }),
|
|
139
262
|
get children() {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
263
|
+
var _el$4 = _tmpl$4();
|
|
264
|
+
insert(_el$4, createComponent(RadioGroup, {
|
|
265
|
+
get value() {
|
|
266
|
+
return accentSelection();
|
|
267
|
+
},
|
|
268
|
+
get disabled() {
|
|
269
|
+
return props.saving;
|
|
143
270
|
},
|
|
144
|
-
|
|
145
|
-
|
|
271
|
+
orientation: "horizontal",
|
|
272
|
+
"aria-label": "Accent",
|
|
273
|
+
"class": "min-w-0 flex-1",
|
|
274
|
+
onChange: (accent) => props.onChange({ accent }),
|
|
275
|
+
get children() {
|
|
276
|
+
return createComponent(AccentSwatchGroups, {
|
|
146
277
|
get accentOptions() {
|
|
147
278
|
return props.accentOptions;
|
|
148
279
|
},
|
|
@@ -153,67 +284,42 @@ function AccentChoices(props) {
|
|
|
153
284
|
return showThemeDefault();
|
|
154
285
|
},
|
|
155
286
|
get themeDefaultColor() {
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
}), (() => {
|
|
159
|
-
var _el$4 = _tmpl$5();
|
|
160
|
-
insert(_el$4, createComponent(Show, {
|
|
161
|
-
get when() {
|
|
162
|
-
return props.showCustomAccentCaption ?? true;
|
|
163
|
-
},
|
|
164
|
-
get children() {
|
|
165
|
-
return _tmpl$4();
|
|
166
|
-
}
|
|
167
|
-
}), null);
|
|
168
|
-
insert(_el$4, createComponent(RadioGroup.Item, {
|
|
169
|
-
value: "custom",
|
|
170
|
-
get children() {
|
|
171
|
-
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
172
|
-
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
173
|
-
children: "Custom"
|
|
174
|
-
})];
|
|
175
|
-
}
|
|
176
|
-
}), null);
|
|
177
|
-
return _el$4;
|
|
178
|
-
})()];
|
|
179
|
-
},
|
|
180
|
-
get children() {
|
|
181
|
-
var _el$3 = _tmpl$3();
|
|
182
|
-
insert(_el$3, createComponent(For, {
|
|
183
|
-
get each() {
|
|
184
|
-
return labelEntries();
|
|
287
|
+
return themeDefaultColor();
|
|
185
288
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return option.id;
|
|
189
|
-
},
|
|
190
|
-
"class": "min-w-0",
|
|
191
|
-
get ["data-accent-option"]() {
|
|
192
|
-
return option.id;
|
|
193
|
-
},
|
|
194
|
-
get children() {
|
|
195
|
-
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
196
|
-
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
197
|
-
get children() {
|
|
198
|
-
return option.label;
|
|
199
|
-
}
|
|
200
|
-
})];
|
|
201
|
-
}
|
|
202
|
-
})
|
|
203
|
-
}), null);
|
|
204
|
-
insert(_el$3, createComponent(RadioGroup.Item, {
|
|
205
|
-
value: "custom",
|
|
206
|
-
"class": "min-w-0",
|
|
207
|
-
get children() {
|
|
208
|
-
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
209
|
-
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary",
|
|
210
|
-
children: "Custom"
|
|
211
|
-
})];
|
|
212
|
-
}
|
|
213
|
-
}), null);
|
|
214
|
-
return _el$3;
|
|
289
|
+
layout: "row"
|
|
290
|
+
});
|
|
215
291
|
}
|
|
216
|
-
});
|
|
292
|
+
}), null);
|
|
293
|
+
insert(_el$4, createComponent(Button, {
|
|
294
|
+
type: "button",
|
|
295
|
+
variant: "outline",
|
|
296
|
+
size: "sm",
|
|
297
|
+
get disabled() {
|
|
298
|
+
return props.saving;
|
|
299
|
+
},
|
|
300
|
+
get ["aria-pressed"]() {
|
|
301
|
+
return isCustomAccent(props);
|
|
302
|
+
},
|
|
303
|
+
onClick: openCustomColor,
|
|
304
|
+
children: "Custom"
|
|
305
|
+
}), null);
|
|
306
|
+
insert(_el$4, createComponent(Input, {
|
|
307
|
+
ref: (element) => {
|
|
308
|
+
colorPicker = element;
|
|
309
|
+
},
|
|
310
|
+
type: "color",
|
|
311
|
+
"class": "sr-only w-px",
|
|
312
|
+
tabIndex: -1,
|
|
313
|
+
"aria-label": "Custom accent color",
|
|
314
|
+
get value() {
|
|
315
|
+
return memo(() => !!/^#[0-9a-f]{6}$/i.test(props.draft.accent))() ? props.draft.accent : props.customAccentValue ?? "#000000";
|
|
316
|
+
},
|
|
317
|
+
get disabled() {
|
|
318
|
+
return props.saving;
|
|
319
|
+
},
|
|
320
|
+
onChange: (event) => props.onChange({ accent: event.currentTarget.value })
|
|
321
|
+
}), null);
|
|
322
|
+
return _el$4;
|
|
217
323
|
}
|
|
218
324
|
});
|
|
219
325
|
}
|
|
@@ -245,7 +351,7 @@ function GlassChoices(props) {
|
|
|
245
351
|
"class": "rounded-md focus-within:ring-3 focus-within:ring-ring/50",
|
|
246
352
|
get children() {
|
|
247
353
|
return [createComponent(RadioGroup.ItemInput, {}), createComponent(RadioGroup.ItemLabel, {
|
|
248
|
-
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
|
|
354
|
+
"class": "flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs whitespace-nowrap data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
|
|
249
355
|
get children() {
|
|
250
356
|
return option.label;
|
|
251
357
|
}
|