@adea-ai/ui 0.33.0 → 0.35.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.
@@ -0,0 +1,40 @@
1
+ import type { JSX } from 'solid-js';
2
+ import type { ThemeVariant } from './appearance';
3
+ /** Which corners of the miniature round themselves (donor `Corners`). */
4
+ export type MiniatureCorners = 'all' | 'left' | 'right';
5
+ /**
6
+ * The sidebar-plus-pane miniature of the app chrome, painted from one
7
+ * variant: a sidebar of text bars beside a bordered content pane. (Zeron
8
+ * `miniature`; bar rhythm and opacities preserved.)
9
+ */
10
+ export declare function ThemeMiniature(props: {
11
+ variant: ThemeVariant;
12
+ corners?: MiniatureCorners;
13
+ class?: string;
14
+ }): JSX.Element;
15
+ /**
16
+ * The System-mode card: the light and dark miniatures side by side, each
17
+ * rounding only its outer corners. (Zeron `miniature_split`.)
18
+ */
19
+ export declare function ThemeMiniatureSplit(props: {
20
+ light: ThemeVariant;
21
+ dark: ThemeVariant;
22
+ class?: string;
23
+ }): JSX.Element;
24
+ /**
25
+ * The compact palette strip in a theme picker row: surface, background, and
26
+ * accent thirds behind the variant's border. (Zeron `palette_preview`.)
27
+ */
28
+ export declare function PalettePreview(props: {
29
+ variant: ThemeVariant;
30
+ class?: string;
31
+ }): JSX.Element;
32
+ /**
33
+ * The "Theme default" accent sample: the derived accent wash with a ramp of
34
+ * foreground glyph bars. (Zeron's accent-wash swatch; Adea derives the wash
35
+ * from the accent roles and paints the glyph ramp with foreground opacities.)
36
+ */
37
+ export declare function AccentDefaultSample(props: {
38
+ variant: ThemeVariant;
39
+ class?: string;
40
+ }): JSX.Element;
@@ -0,0 +1,210 @@
1
+ import { className, createComponent, effect, insert, setStyleProperty, template } from "solid-js/web";
2
+ //#region src/components/theme-preview.tsx
3
+ var _tmpl$ = /*#__PURE__*/ template(`<span class="h-[5px] rounded-[3px]">`);
4
+ var _tmpl$2 = /*#__PURE__*/ template(`<span data-theme-miniature aria-hidden=true><span class="flex h-full w-11 shrink-0 flex-col gap-[7px] px-2 pt-3.5"></span><span class="theme-preview-border my-2 mr-2 flex min-w-0 flex-1 flex-col gap-[7px] rounded-md border p-2.5">`);
5
+ var _tmpl$3 = /*#__PURE__*/ template(`<span aria-hidden=true><span class="h-full w-1/2 overflow-hidden"></span><span class="h-full w-1/2 overflow-hidden">`);
6
+ var _tmpl$4 = /*#__PURE__*/ template(`<span class="theme-preview-border flex h-[18px] w-[30px] shrink-0 overflow-hidden rounded-[5px] border"aria-hidden=true>`);
7
+ var _tmpl$5 = /*#__PURE__*/ template(`<span class="h-full w-1/3">`);
8
+ var _tmpl$6 = /*#__PURE__*/ template(`<span aria-hidden=true>`);
9
+ var _tmpl$7 = /*#__PURE__*/ template(`<span class="w-1 rounded-[2px]">`);
10
+ var cornerClass = {
11
+ all: "rounded-md",
12
+ left: "rounded-l-md",
13
+ right: "rounded-r-md"
14
+ };
15
+ /** The glyph-bar ramp in the accent default sample (donor bar heights). */
16
+ var accentRamp = Object.freeze([
17
+ {
18
+ height: "13px",
19
+ opacity: "0.4"
20
+ },
21
+ {
22
+ height: "16px",
23
+ opacity: "0.7"
24
+ },
25
+ {
26
+ height: "11px",
27
+ opacity: "1"
28
+ }
29
+ ]);
30
+ function Bar(props) {
31
+ return (() => {
32
+ var _el$ = _tmpl$();
33
+ effect((_p$) => {
34
+ var _v$ = `${Math.round(props.fraction * 100)}%`, _v$2 = props.color, _v$3 = props.opacity;
35
+ _v$ !== _p$.e && setStyleProperty(_el$, "width", _p$.e = _v$);
36
+ _v$2 !== _p$.t && setStyleProperty(_el$, "background-color", _p$.t = _v$2);
37
+ _v$3 !== _p$.a && setStyleProperty(_el$, "opacity", _p$.a = _v$3);
38
+ return _p$;
39
+ }, {
40
+ e: void 0,
41
+ t: void 0,
42
+ a: void 0
43
+ });
44
+ return _el$;
45
+ })();
46
+ }
47
+ /**
48
+ * The sidebar-plus-pane miniature of the app chrome, painted from one
49
+ * variant: a sidebar of text bars beside a bordered content pane. (Zeron
50
+ * `miniature`; bar rhythm and opacities preserved.)
51
+ */
52
+ function ThemeMiniature(props) {
53
+ const colors = () => props.variant.colors;
54
+ return (() => {
55
+ var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
56
+ insert(_el$3, createComponent(Bar, {
57
+ fraction: .7,
58
+ opacity: .34,
59
+ get color() {
60
+ return colors().foreground;
61
+ }
62
+ }), null);
63
+ insert(_el$3, createComponent(Bar, {
64
+ fraction: 1,
65
+ opacity: .22,
66
+ get color() {
67
+ return colors().foreground;
68
+ }
69
+ }), null);
70
+ insert(_el$3, createComponent(Bar, {
71
+ fraction: .85,
72
+ opacity: .22,
73
+ get color() {
74
+ return colors().foreground;
75
+ }
76
+ }), null);
77
+ insert(_el$3, createComponent(Bar, {
78
+ fraction: 1,
79
+ opacity: .22,
80
+ get color() {
81
+ return colors().foreground;
82
+ }
83
+ }), null);
84
+ insert(_el$4, createComponent(Bar, {
85
+ fraction: .62,
86
+ opacity: .34,
87
+ get color() {
88
+ return colors().foreground;
89
+ }
90
+ }), null);
91
+ insert(_el$4, createComponent(Bar, {
92
+ fraction: .88,
93
+ opacity: .22,
94
+ get color() {
95
+ return colors().foreground;
96
+ }
97
+ }), null);
98
+ insert(_el$4, createComponent(Bar, {
99
+ fraction: .76,
100
+ opacity: .22,
101
+ get color() {
102
+ return colors().foreground;
103
+ }
104
+ }), null);
105
+ insert(_el$4, createComponent(Bar, {
106
+ fraction: .52,
107
+ opacity: .22,
108
+ get color() {
109
+ return colors().foreground;
110
+ }
111
+ }), null);
112
+ effect((_p$) => {
113
+ var _v$4 = `flex h-full w-full overflow-hidden ${cornerClass[props.corners ?? "all"]} ${props.class ?? ""}`, _v$5 = colors().card, _v$6 = colors().background, _v$7 = colors().border;
114
+ _v$4 !== _p$.e && className(_el$2, _p$.e = _v$4);
115
+ _v$5 !== _p$.t && setStyleProperty(_el$2, "background-color", _p$.t = _v$5);
116
+ _v$6 !== _p$.a && setStyleProperty(_el$4, "background-color", _p$.a = _v$6);
117
+ _v$7 !== _p$.o && setStyleProperty(_el$4, "--preview-border", _p$.o = _v$7);
118
+ return _p$;
119
+ }, {
120
+ e: void 0,
121
+ t: void 0,
122
+ a: void 0,
123
+ o: void 0
124
+ });
125
+ return _el$2;
126
+ })();
127
+ }
128
+ /**
129
+ * The System-mode card: the light and dark miniatures side by side, each
130
+ * rounding only its outer corners. (Zeron `miniature_split`.)
131
+ */
132
+ function ThemeMiniatureSplit(props) {
133
+ return (() => {
134
+ var _el$5 = _tmpl$3(), _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling;
135
+ insert(_el$6, createComponent(ThemeMiniature, {
136
+ get variant() {
137
+ return props.light;
138
+ },
139
+ corners: "left"
140
+ }));
141
+ insert(_el$7, createComponent(ThemeMiniature, {
142
+ get variant() {
143
+ return props.dark;
144
+ },
145
+ corners: "right"
146
+ }));
147
+ effect(() => className(_el$5, `flex h-full w-full ${props.class ?? ""}`));
148
+ return _el$5;
149
+ })();
150
+ }
151
+ /**
152
+ * The compact palette strip in a theme picker row: surface, background, and
153
+ * accent thirds behind the variant's border. (Zeron `palette_preview`.)
154
+ */
155
+ function PalettePreview(props) {
156
+ const bands = () => [
157
+ props.variant.colors.card,
158
+ props.variant.colors.background,
159
+ props.variant.colors.primary
160
+ ];
161
+ return (() => {
162
+ var _el$8 = _tmpl$4();
163
+ insert(_el$8, () => bands().map((band) => (() => {
164
+ var _el$9 = _tmpl$5();
165
+ setStyleProperty(_el$9, "background-color", band);
166
+ return _el$9;
167
+ })()));
168
+ effect((_$p) => setStyleProperty(_el$8, "--preview-border", props.variant.colors.border));
169
+ return _el$8;
170
+ })();
171
+ }
172
+ /**
173
+ * The "Theme default" accent sample: the derived accent wash with a ramp of
174
+ * foreground glyph bars. (Zeron's accent-wash swatch; Adea derives the wash
175
+ * from the accent roles and paints the glyph ramp with foreground opacities.)
176
+ */
177
+ function AccentDefaultSample(props) {
178
+ const accent = () => props.variant.colors.primary;
179
+ const foreground = () => props.variant.colors.foreground;
180
+ return (() => {
181
+ var _el$0 = _tmpl$6();
182
+ insert(_el$0, () => accentRamp.map((bar) => (() => {
183
+ var _el$1 = _tmpl$7();
184
+ effect((_p$) => {
185
+ var _v$0 = bar.height, _v$1 = foreground(), _v$10 = bar.opacity;
186
+ _v$0 !== _p$.e && setStyleProperty(_el$1, "height", _p$.e = _v$0);
187
+ _v$1 !== _p$.t && setStyleProperty(_el$1, "background-color", _p$.t = _v$1);
188
+ _v$10 !== _p$.a && setStyleProperty(_el$1, "opacity", _p$.a = _v$10);
189
+ return _p$;
190
+ }, {
191
+ e: void 0,
192
+ t: void 0,
193
+ a: void 0
194
+ });
195
+ return _el$1;
196
+ })()));
197
+ effect((_p$) => {
198
+ var _v$8 = `flex h-full w-full items-center justify-center gap-[2px] rounded-[6px] ${props.class ?? ""}`, _v$9 = `color-mix(in srgb, ${accent()} 16%, transparent)`;
199
+ _v$8 !== _p$.e && className(_el$0, _p$.e = _v$8);
200
+ _v$9 !== _p$.t && setStyleProperty(_el$0, "background-color", _p$.t = _v$9);
201
+ return _p$;
202
+ }, {
203
+ e: void 0,
204
+ t: void 0
205
+ });
206
+ return _el$0;
207
+ })();
208
+ }
209
+ //#endregion
210
+ export { AccentDefaultSample, PalettePreview, ThemeMiniature, ThemeMiniatureSplit };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "Shared UI kit for Adea: Kobalte/corvu-backed Solid primitives, workspace shells, and theme styles.",
5
5
  "keywords": [
6
6
  "components",
@@ -0,0 +1,170 @@
1
+ /*
2
+ * Copyright (c) 2026 Wing
3
+ * Licensed under the MIT License.
4
+ *
5
+ * Appearance miniatures substantially translated from Zeron
6
+ * crates/ui/src/settings/appearance.rs (the `miniature`, `miniature_split`,
7
+ * and `palette_preview` builders) with the option-card frame rhythm of
8
+ * crates/ui/src/settings/widgets.rs (`option_card`), revision
9
+ * 30a9a9537c5ec96226c87f4bf349b6f77c5dfb59: a sidebar-plus-pane miniature of
10
+ * the real chrome painted from a variant's own colors, the split light/dark
11
+ * half for System mode, and the three-band palette strip. Modified for
12
+ * Adea's token roles (card/background/border/foreground/primary stand in for
13
+ * the donor's surface/bg/border/text/accent) and for the accent default
14
+ * sample, which shows the derived accent wash over foreground glyph bars.
15
+ * See NOTICE and docs/research/dev-view-donor-audit.md.
16
+ *
17
+ * Like theme-swatch.tsx, these components are the sanctioned bridge between
18
+ * runtime token data and the DOM: the colors they paint arrive as theme
19
+ * manifest values, so painting them must inline them (token data may never
20
+ * become a component color literal). The previewed variant's border color
21
+ * travels through the `--preview-border` custom property consumed by the
22
+ * `.theme-preview-border` hook in styles/theme.css.
23
+ */
24
+ import type { JSX } from 'solid-js'
25
+
26
+ import type { ThemeVariant } from './appearance'
27
+
28
+ /** Which corners of the miniature round themselves (donor `Corners`). */
29
+ export type MiniatureCorners = 'all' | 'left' | 'right'
30
+
31
+ const cornerClass: Record<MiniatureCorners, string> = {
32
+ all: 'rounded-md',
33
+ left: 'rounded-l-md',
34
+ right: 'rounded-r-md',
35
+ }
36
+
37
+ /** The glyph-bar ramp in the accent default sample (donor bar heights). */
38
+ const accentRamp: readonly { height: string; opacity: string }[] = Object.freeze([
39
+ { height: '13px', opacity: '0.4' },
40
+ { height: '16px', opacity: '0.7' },
41
+ { height: '11px', opacity: '1' },
42
+ ])
43
+
44
+ function Bar(props: { fraction: number; opacity: number; color: string }) {
45
+ return (
46
+ <span
47
+ class="h-[5px] rounded-[3px]"
48
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
49
+ style={{
50
+ width: `${Math.round(props.fraction * 100)}%`,
51
+ 'background-color': props.color,
52
+ opacity: props.opacity,
53
+ }}
54
+ />
55
+ )
56
+ }
57
+
58
+ /**
59
+ * The sidebar-plus-pane miniature of the app chrome, painted from one
60
+ * variant: a sidebar of text bars beside a bordered content pane. (Zeron
61
+ * `miniature`; bar rhythm and opacities preserved.)
62
+ */
63
+ export function ThemeMiniature(props: {
64
+ variant: ThemeVariant
65
+ corners?: MiniatureCorners
66
+ class?: string
67
+ }) {
68
+ const colors = () => props.variant.colors
69
+ return (
70
+ <span
71
+ data-theme-miniature
72
+ class={`flex h-full w-full overflow-hidden ${cornerClass[props.corners ?? 'all']} ${props.class ?? ''}`}
73
+ aria-hidden="true"
74
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
75
+ style={{ 'background-color': colors().card }}
76
+ >
77
+ <span class="flex h-full w-11 shrink-0 flex-col gap-[7px] px-2 pt-3.5">
78
+ <Bar fraction={0.7} opacity={0.34} color={colors().foreground} />
79
+ <Bar fraction={1} opacity={0.22} color={colors().foreground} />
80
+ <Bar fraction={0.85} opacity={0.22} color={colors().foreground} />
81
+ <Bar fraction={1} opacity={0.22} color={colors().foreground} />
82
+ </span>
83
+ <span
84
+ class="theme-preview-border my-2 mr-2 flex min-w-0 flex-1 flex-col gap-[7px] rounded-md border p-2.5"
85
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
86
+ style={{ 'background-color': colors().background, '--preview-border': colors().border }}
87
+ >
88
+ <Bar fraction={0.62} opacity={0.34} color={colors().foreground} />
89
+ <Bar fraction={0.88} opacity={0.22} color={colors().foreground} />
90
+ <Bar fraction={0.76} opacity={0.22} color={colors().foreground} />
91
+ <Bar fraction={0.52} opacity={0.22} color={colors().foreground} />
92
+ </span>
93
+ </span>
94
+ )
95
+ }
96
+
97
+ /**
98
+ * The System-mode card: the light and dark miniatures side by side, each
99
+ * rounding only its outer corners. (Zeron `miniature_split`.)
100
+ */
101
+ export function ThemeMiniatureSplit(props: {
102
+ light: ThemeVariant
103
+ dark: ThemeVariant
104
+ class?: string
105
+ }) {
106
+ return (
107
+ <span class={`flex h-full w-full ${props.class ?? ''}`} aria-hidden="true">
108
+ <span class="h-full w-1/2 overflow-hidden">
109
+ <ThemeMiniature variant={props.light} corners="left" />
110
+ </span>
111
+ <span class="h-full w-1/2 overflow-hidden">
112
+ <ThemeMiniature variant={props.dark} corners="right" />
113
+ </span>
114
+ </span>
115
+ )
116
+ }
117
+
118
+ /**
119
+ * The compact palette strip in a theme picker row: surface, background, and
120
+ * accent thirds behind the variant's border. (Zeron `palette_preview`.)
121
+ */
122
+ export function PalettePreview(props: { variant: ThemeVariant; class?: string }) {
123
+ const bands = () => [
124
+ props.variant.colors.card,
125
+ props.variant.colors.background,
126
+ props.variant.colors.primary,
127
+ ]
128
+ return (
129
+ <span
130
+ class="theme-preview-border flex h-[18px] w-[30px] shrink-0 overflow-hidden rounded-[5px] border"
131
+ aria-hidden="true"
132
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
133
+ style={{ '--preview-border': props.variant.colors.border }}
134
+ >
135
+ {bands().map((band) => (
136
+ <span
137
+ class="h-full w-1/3"
138
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
139
+ style={{ 'background-color': band }}
140
+ />
141
+ ))}
142
+ </span>
143
+ )
144
+ }
145
+
146
+ /**
147
+ * The "Theme default" accent sample: the derived accent wash with a ramp of
148
+ * foreground glyph bars. (Zeron's accent-wash swatch; Adea derives the wash
149
+ * from the accent roles and paints the glyph ramp with foreground opacities.)
150
+ */
151
+ export function AccentDefaultSample(props: { variant: ThemeVariant; class?: string }): JSX.Element {
152
+ const accent = () => props.variant.colors.primary
153
+ const foreground = () => props.variant.colors.foreground
154
+ return (
155
+ <span
156
+ class={`flex h-full w-full items-center justify-center gap-[2px] rounded-[6px] ${props.class ?? ''}`}
157
+ aria-hidden="true"
158
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
159
+ style={{ 'background-color': `color-mix(in srgb, ${accent()} 16%, transparent)` }}
160
+ >
161
+ {accentRamp.map((bar) => (
162
+ <span
163
+ class="w-1 rounded-[2px]"
164
+ // oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
165
+ style={{ height: bar.height, 'background-color': foreground(), opacity: bar.opacity }}
166
+ />
167
+ ))}
168
+ </span>
169
+ )
170
+ }
@@ -218,6 +218,13 @@
218
218
  border: 1px solid var(--border);
219
219
  }
220
220
 
221
+ /* Appearance preview painters (see components/theme-preview.tsx). The
222
+ previewed variant's own border color is runtime token data, passed
223
+ through this hook's custom property instead of the live theme border. */
224
+ .theme-preview-border {
225
+ border-color: var(--preview-border, var(--border));
226
+ }
227
+
221
228
  @layer base {
222
229
  *,
223
230
  *::before,