@adea-ai/ui 0.105.0 → 0.106.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -8
- package/dist/components/composites/action-button/action-button.d.ts.map +1 -1
- package/dist/components/composites/action-button/action-button.js +6 -8
- package/dist/components/composites/action-button/action-button.js.map +1 -1
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts +16 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js +151 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-choices.js +24 -84
- package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts +2 -2
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.js +25 -7
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-types.d.ts +9 -0
- package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/font-settings-group.d.ts +10 -0
- package/dist/components/composites/appearance-editor/font-settings-group.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/font-settings-group.js +310 -0
- package/dist/components/composites/appearance-editor/font-settings-group.js.map +1 -0
- package/dist/components/composites/appearance-editor/index.d.ts +2 -0
- package/dist/components/composites/appearance-editor/index.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/index.js +3 -1
- package/dist/components/composites/update-dialog/update-dialog.js +2 -2
- package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
- package/dist/components/conversation/message-row.d.ts.map +1 -1
- package/dist/components/conversation/message-row.js +3 -3
- package/dist/components/conversation/message-row.js.map +1 -1
- package/dist/components/conversation/paste-token-editor.js +1 -1
- package/dist/components/conversation/paste-token-editor.js.map +1 -1
- package/dist/components/layout/side-rail/side-rail.js +2 -2
- package/dist/components/layout/side-rail/side-rail.js.map +1 -1
- package/dist/components/layout/top-bar/top-bar.js +1 -1
- package/dist/components/layout/top-bar/top-bar.js.map +1 -1
- package/dist/components/theme/appearance-panel.d.ts +1 -1
- package/dist/components/theme/appearance-panel.d.ts.map +1 -1
- package/dist/components/theme/appearance-panel.js +45 -105
- package/dist/components/theme/appearance-panel.js.map +1 -1
- package/dist/components/theme/theme-provider.d.ts +5 -2
- package/dist/components/theme/theme-provider.d.ts.map +1 -1
- package/dist/components/theme/theme-provider.js +38 -19
- package/dist/components/theme/theme-provider.js.map +1 -1
- package/dist/components/ui/code-block/code-block.d.ts +3 -3
- package/dist/components/ui/code-block/code-block.js +6 -6
- package/dist/components/ui/code-block/code-block.js.map +1 -1
- package/dist/components/ui/command/command.js +1 -1
- package/dist/components/ui/command/command.js.map +1 -1
- package/dist/components/ui/context-menu/context-menu.js +1 -1
- package/dist/components/ui/context-menu/context-menu.js.map +1 -1
- package/dist/components/ui/diff-block/diff-block.js +5 -5
- package/dist/components/ui/diff-block/diff-block.js.map +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.js +101 -8
- package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/ui/kbd/kbd.js +1 -1
- package/dist/components/ui/kbd/kbd.js.map +1 -1
- package/dist/components/ui/menubar/menubar.js +1 -1
- package/dist/components/ui/menubar/menubar.js.map +1 -1
- package/dist/components/ui/typography/typography.d.ts +3 -5
- package/dist/components/ui/typography/typography.d.ts.map +1 -1
- package/dist/components/ui/typography/typography.js +6 -8
- package/dist/components/ui/typography/typography.js.map +1 -1
- package/dist/index.js +6 -3
- package/dist/lib/appearance-font-settings.d.ts +53 -0
- package/dist/lib/appearance-font-settings.d.ts.map +1 -0
- package/dist/lib/appearance-font-settings.js +160 -0
- package/dist/lib/appearance-font-settings.js.map +1 -0
- package/dist/lib/font-catalog.d.ts +72 -0
- package/dist/lib/font-catalog.d.ts.map +1 -0
- package/dist/lib/font-catalog.js +71 -0
- package/dist/lib/font-catalog.js.map +1 -0
- package/dist/lib/safe-script.d.ts +3 -0
- package/dist/lib/safe-script.d.ts.map +1 -0
- package/dist/lib/safe-script.js +9 -0
- package/dist/lib/safe-script.js.map +1 -0
- package/dist/lib/tokens.d.ts +2 -19
- package/dist/lib/tokens.d.ts.map +1 -1
- package/dist/lib/tokens.js +63 -39
- package/dist/lib/tokens.js.map +1 -1
- package/dist/r/appearance-editor.json +12 -1
- package/dist/r/lib.json +16 -1
- package/dist/r/registry.json +36 -3
- package/dist/r/src/components/composites/action-button/action-button.tsx +2 -1
- package/dist/r/src/components/composites/appearance-editor/accent-swatch-groups.tsx +147 -0
- package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +17 -74
- package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +19 -6
- package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +9 -0
- package/dist/r/src/components/composites/appearance-editor/font-settings-group.tsx +350 -0
- package/dist/r/src/components/composites/appearance-editor/index.ts +19 -0
- package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +2 -2
- package/dist/r/src/components/conversation/message-row.tsx +7 -3
- package/dist/r/src/components/conversation/paste-token-editor.tsx +1 -1
- package/dist/r/src/components/layout/side-rail/side-rail.tsx +3 -3
- package/dist/r/src/components/layout/top-bar/top-bar.tsx +1 -1
- package/dist/r/src/components/theme/appearance-panel.tsx +34 -83
- package/dist/r/src/components/theme/theme-provider.tsx +50 -20
- package/dist/r/src/components/ui/code-block/code-block.tsx +6 -6
- package/dist/r/src/components/ui/command/command.tsx +1 -1
- package/dist/r/src/components/ui/context-menu/context-menu.tsx +1 -1
- package/dist/r/src/components/ui/diff-block/diff-block.tsx +7 -7
- package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +145 -7
- package/dist/r/src/components/ui/kbd/kbd.tsx +1 -1
- package/dist/r/src/components/ui/menubar/menubar.tsx +1 -1
- package/dist/r/src/components/ui/typography/typography.tsx +6 -8
- package/dist/r/src/lib/appearance-font-settings.ts +233 -0
- package/dist/r/src/lib/font-catalog.ts +80 -0
- package/dist/r/src/lib/safe-script.ts +7 -0
- package/dist/r/src/lib/tokens.ts +64 -59
- package/dist/r/src/styles/appearance-font-settings.css +110 -0
- package/dist/r/src/styles/fonts.css +4 -5
- package/dist/r/src/styles/globals.css +4 -1
- package/dist/r/src/styles/theme.css +14 -0
- package/dist/r/theme.json +5 -0
- package/dist/r/theming.json +3 -1
- package/package.json +3 -2
- package/registry.json +36 -3
- package/src/components/composites/action-button/action-button.tsx +2 -1
- package/src/components/composites/appearance-editor/accent-swatch-groups.tsx +147 -0
- package/src/components/composites/appearance-editor/appearance-choices.tsx +17 -74
- package/src/components/composites/appearance-editor/appearance-editor.tsx +19 -6
- package/src/components/composites/appearance-editor/appearance-types.ts +9 -0
- package/src/components/composites/appearance-editor/font-settings-group.tsx +350 -0
- package/src/components/composites/appearance-editor/index.ts +19 -0
- package/src/components/composites/update-dialog/update-dialog.tsx +2 -2
- package/src/components/conversation/message-row.tsx +7 -3
- package/src/components/conversation/paste-token-editor.tsx +1 -1
- package/src/components/layout/side-rail/side-rail.tsx +3 -3
- package/src/components/layout/top-bar/top-bar.tsx +1 -1
- package/src/components/theme/appearance-panel.tsx +34 -83
- package/src/components/theme/theme-provider.tsx +50 -20
- package/src/components/ui/code-block/code-block.tsx +6 -6
- package/src/components/ui/command/command.tsx +1 -1
- package/src/components/ui/context-menu/context-menu.tsx +1 -1
- package/src/components/ui/diff-block/diff-block.tsx +7 -7
- package/src/components/ui/dropdown-menu/dropdown-menu.tsx +145 -7
- package/src/components/ui/kbd/kbd.tsx +1 -1
- package/src/components/ui/menubar/menubar.tsx +1 -1
- package/src/components/ui/typography/typography.tsx +6 -8
- package/src/lib/appearance-font-settings.ts +233 -0
- package/src/lib/font-catalog.ts +80 -0
- package/src/lib/safe-script.ts +7 -0
- package/src/lib/tokens.ts +64 -59
- package/src/styles/appearance-font-settings.css +110 -0
- package/src/styles/fonts.css +4 -5
- package/src/styles/globals.css +4 -1
- package/src/styles/theme.css +14 -0
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* @shadcn/lint discover, so it must stay the file that imports Tailwind.
|
|
6
6
|
*
|
|
7
7
|
* @import '@adea-ai/ui/globals.css';
|
|
8
|
+
* @import '@adea-ai/ui/appearance-font-settings.css'; <- optional role preferences
|
|
8
9
|
* @import '@adea-ai/ui/fonts.css'; <- optional, self-hosted typefaces
|
|
9
10
|
*
|
|
10
11
|
* A consumer that already imports Tailwind itself should import `theme.css`
|
|
11
|
-
* and `base.css` directly instead, and must not import this file.
|
|
12
|
+
* and `base.css` directly instead, and must not import this file. The font role
|
|
13
|
+
* stylesheet stays opt-in so applications that use only the base theme keep
|
|
14
|
+
* the existing CSS footprint.
|
|
12
15
|
*
|
|
13
16
|
* Tokens live in `theme.css` only. This file must never duplicate them.
|
|
14
17
|
*/
|
|
@@ -525,6 +525,14 @@
|
|
|
525
525
|
--font-family-geist-mono: 'Geist Mono Variable', 'Geist Mono', monospace;
|
|
526
526
|
--font-family-system: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
527
527
|
--font-family-system-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
|
528
|
+
/* Lightweight role defaults keep conversation and code components useful for
|
|
529
|
+
consumers that have not opted into independent Appearance font settings. */
|
|
530
|
+
--font-content: var(--font-sans);
|
|
531
|
+
--font-code: var(--font-mono);
|
|
532
|
+
--text-content: var(--text-sm);
|
|
533
|
+
--text-content--line-height: var(--text-sm--line-height);
|
|
534
|
+
--text-code: 0.75rem;
|
|
535
|
+
--text-code--line-height: 1.5;
|
|
528
536
|
|
|
529
537
|
/* Width compensation for the mono UI fonts. `normal` on the proportional face,
|
|
530
538
|
tightened by the `[data-font]` blocks above when the UI font is monospace. */
|
|
@@ -776,6 +784,8 @@
|
|
|
776
784
|
|
|
777
785
|
--font-sans: var(--font-sans);
|
|
778
786
|
--font-mono: var(--font-mono);
|
|
787
|
+
--font-content: var(--font-content);
|
|
788
|
+
--font-code: var(--font-code);
|
|
779
789
|
--font-family-space-grotesk: var(--font-family-space-grotesk);
|
|
780
790
|
--font-family-jetbrains-mono: var(--font-family-jetbrains-mono);
|
|
781
791
|
--font-family-geist: var(--font-family-geist);
|
|
@@ -799,6 +809,10 @@
|
|
|
799
809
|
--text-2xl--line-height: var(--text-2xl--line-height);
|
|
800
810
|
--text-3xl: var(--text-3xl);
|
|
801
811
|
--text-3xl--line-height: var(--text-3xl--line-height);
|
|
812
|
+
--text-content: var(--text-content);
|
|
813
|
+
--text-content--line-height: var(--text-content--line-height);
|
|
814
|
+
--text-code: var(--text-code);
|
|
815
|
+
--text-code--line-height: var(--text-code--line-height);
|
|
802
816
|
|
|
803
817
|
--radius-sm: var(--radius-sm);
|
|
804
818
|
--radius-md: var(--radius-md);
|
package/dist/r/theme.json
CHANGED
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"type": "registry:style",
|
|
28
28
|
"target": "styles/base.css"
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
"path": "src/styles/appearance-font-settings.css",
|
|
32
|
+
"type": "registry:style",
|
|
33
|
+
"target": "styles/appearance-font-settings.css"
|
|
34
|
+
},
|
|
30
35
|
{
|
|
31
36
|
"path": "src/styles/fonts.css",
|
|
32
37
|
"type": "registry:style",
|
package/dist/r/theming.json
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
"title": "Theming",
|
|
5
5
|
"description": "",
|
|
6
6
|
"dependencies": [
|
|
7
|
-
"@adea-ai/themes@^0.9.
|
|
7
|
+
"@adea-ai/themes@^0.9.7",
|
|
8
|
+
"@kobalte/core@^0.13.14",
|
|
8
9
|
"lucide-solid@^1.51.0"
|
|
9
10
|
],
|
|
10
11
|
"registryDependencies": [
|
|
12
|
+
"@adea-ai/ui/appearance-editor",
|
|
11
13
|
"@adea-ai/ui/button",
|
|
12
14
|
"@adea-ai/ui/radio-group",
|
|
13
15
|
"@adea-ai/ui/toggle-group",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adea-ai/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.106.1",
|
|
4
4
|
"description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adea",
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"./globals.css": "./src/styles/globals.css",
|
|
68
68
|
"./theme.css": "./src/styles/theme.css",
|
|
69
69
|
"./base.css": "./src/styles/base.css",
|
|
70
|
+
"./appearance-font-settings.css": "./src/styles/appearance-font-settings.css",
|
|
70
71
|
"./fonts.css": "./src/styles/fonts.css",
|
|
71
72
|
"./registry.json": "./registry.json",
|
|
72
73
|
"./package.json": "./package.json",
|
|
@@ -125,7 +126,7 @@
|
|
|
125
126
|
"check:packed-paste-model": "node scripts/check-packed-paste-model.mjs"
|
|
126
127
|
},
|
|
127
128
|
"dependencies": {
|
|
128
|
-
"@adea-ai/themes": "^0.9.
|
|
129
|
+
"@adea-ai/themes": "^0.9.7",
|
|
129
130
|
"@corvu/calendar": "^0.1.2",
|
|
130
131
|
"@corvu/drawer": "^0.2.4",
|
|
131
132
|
"@corvu/otp-field": "^0.1.4",
|
package/registry.json
CHANGED
|
@@ -1910,7 +1910,7 @@
|
|
|
1910
1910
|
"title": "Appearance Editor",
|
|
1911
1911
|
"description": "",
|
|
1912
1912
|
"dependencies": [
|
|
1913
|
-
"@adea-ai/themes@^0.9.
|
|
1913
|
+
"@adea-ai/themes@^0.9.7",
|
|
1914
1914
|
"@kobalte/core@^0.13.14",
|
|
1915
1915
|
"lucide-solid@^1.51.0"
|
|
1916
1916
|
],
|
|
@@ -1920,9 +1920,15 @@
|
|
|
1920
1920
|
"@adea-ai/ui/input",
|
|
1921
1921
|
"@adea-ai/ui/popover",
|
|
1922
1922
|
"@adea-ai/ui/switch",
|
|
1923
|
+
"@adea-ai/ui/theme",
|
|
1923
1924
|
"lib"
|
|
1924
1925
|
],
|
|
1925
1926
|
"files": [
|
|
1927
|
+
{
|
|
1928
|
+
"path": "src/components/composites/appearance-editor/accent-swatch-groups.tsx",
|
|
1929
|
+
"type": "registry:ui",
|
|
1930
|
+
"target": "components/composites/appearance-editor/accent-swatch-groups.tsx"
|
|
1931
|
+
},
|
|
1926
1932
|
{
|
|
1927
1933
|
"path": "src/components/composites/appearance-editor/appearance-choices.tsx",
|
|
1928
1934
|
"type": "registry:ui",
|
|
@@ -1943,6 +1949,11 @@
|
|
|
1943
1949
|
"type": "registry:ui",
|
|
1944
1950
|
"target": "components/composites/appearance-editor/appearance-types.ts"
|
|
1945
1951
|
},
|
|
1952
|
+
{
|
|
1953
|
+
"path": "src/components/composites/appearance-editor/font-settings-group.tsx",
|
|
1954
|
+
"type": "registry:ui",
|
|
1955
|
+
"target": "components/composites/appearance-editor/font-settings-group.tsx"
|
|
1956
|
+
},
|
|
1946
1957
|
{
|
|
1947
1958
|
"path": "src/components/composites/appearance-editor/index.ts",
|
|
1948
1959
|
"type": "registry:ui",
|
|
@@ -2357,10 +2368,12 @@
|
|
|
2357
2368
|
"title": "Theming",
|
|
2358
2369
|
"description": "",
|
|
2359
2370
|
"dependencies": [
|
|
2360
|
-
"@adea-ai/themes@^0.9.
|
|
2371
|
+
"@adea-ai/themes@^0.9.7",
|
|
2372
|
+
"@kobalte/core@^0.13.14",
|
|
2361
2373
|
"lucide-solid@^1.51.0"
|
|
2362
2374
|
],
|
|
2363
2375
|
"registryDependencies": [
|
|
2376
|
+
"@adea-ai/ui/appearance-editor",
|
|
2364
2377
|
"@adea-ai/ui/button",
|
|
2365
2378
|
"@adea-ai/ui/radio-group",
|
|
2366
2379
|
"@adea-ai/ui/toggle-group",
|
|
@@ -2452,6 +2465,11 @@
|
|
|
2452
2465
|
"type": "registry:style",
|
|
2453
2466
|
"target": "styles/base.css"
|
|
2454
2467
|
},
|
|
2468
|
+
{
|
|
2469
|
+
"path": "src/styles/appearance-font-settings.css",
|
|
2470
|
+
"type": "registry:style",
|
|
2471
|
+
"target": "styles/appearance-font-settings.css"
|
|
2472
|
+
},
|
|
2455
2473
|
{
|
|
2456
2474
|
"path": "src/styles/fonts.css",
|
|
2457
2475
|
"type": "registry:style",
|
|
@@ -2465,12 +2483,17 @@
|
|
|
2465
2483
|
"title": "Class-name and token helpers",
|
|
2466
2484
|
"description": "The private helpers the components import: the class-name merge, the variant recipes, the token manifest and the theme bridge. Installed automatically as a peer of any component that needs it.",
|
|
2467
2485
|
"dependencies": [
|
|
2468
|
-
"@adea-ai/themes@^0.9.
|
|
2486
|
+
"@adea-ai/themes@^0.9.7",
|
|
2469
2487
|
"class-variance-authority@^0.7.1",
|
|
2470
2488
|
"cn@^0.4.0"
|
|
2471
2489
|
],
|
|
2472
2490
|
"registryDependencies": [],
|
|
2473
2491
|
"files": [
|
|
2492
|
+
{
|
|
2493
|
+
"path": "src/lib/appearance-font-settings.ts",
|
|
2494
|
+
"type": "registry:lib",
|
|
2495
|
+
"target": "lib/appearance-font-settings.ts"
|
|
2496
|
+
},
|
|
2474
2497
|
{
|
|
2475
2498
|
"path": "src/lib/clipboard.ts",
|
|
2476
2499
|
"type": "registry:lib",
|
|
@@ -2486,6 +2509,11 @@
|
|
|
2486
2509
|
"type": "registry:lib",
|
|
2487
2510
|
"target": "lib/download.ts"
|
|
2488
2511
|
},
|
|
2512
|
+
{
|
|
2513
|
+
"path": "src/lib/font-catalog.ts",
|
|
2514
|
+
"type": "registry:lib",
|
|
2515
|
+
"target": "lib/font-catalog.ts"
|
|
2516
|
+
},
|
|
2489
2517
|
{
|
|
2490
2518
|
"path": "src/lib/form-field.ts",
|
|
2491
2519
|
"type": "registry:lib",
|
|
@@ -2501,6 +2529,11 @@
|
|
|
2501
2529
|
"type": "registry:lib",
|
|
2502
2530
|
"target": "lib/overlay.ts"
|
|
2503
2531
|
},
|
|
2532
|
+
{
|
|
2533
|
+
"path": "src/lib/safe-script.ts",
|
|
2534
|
+
"type": "registry:lib",
|
|
2535
|
+
"target": "lib/safe-script.ts"
|
|
2536
|
+
},
|
|
2504
2537
|
{
|
|
2505
2538
|
"path": "src/lib/theme-accents.ts",
|
|
2506
2539
|
"type": "registry:lib",
|
|
@@ -161,6 +161,7 @@ export function ActionButton<T extends ValidComponent = 'button'>(props: ActionB
|
|
|
161
161
|
}
|
|
162
162
|
>
|
|
163
163
|
<Tooltip
|
|
164
|
+
placement={local.tooltipSide ?? 'bottom'}
|
|
164
165
|
open={tooltipOpen()}
|
|
165
166
|
onOpenChange={(open) => {
|
|
166
167
|
if (open && tooltipSuppression()) return
|
|
@@ -174,7 +175,7 @@ export function ActionButton<T extends ValidComponent = 'button'>(props: ActionB
|
|
|
174
175
|
>
|
|
175
176
|
{contents()}
|
|
176
177
|
</TooltipTrigger>
|
|
177
|
-
<TooltipContent
|
|
178
|
+
<TooltipContent>{local.tooltip}</TooltipContent>
|
|
178
179
|
</Tooltip>
|
|
179
180
|
</Show>
|
|
180
181
|
<Show when={busy()}>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MIT License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2026 Wing
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
import { RadioGroup as Radio } from '@kobalte/core/radio-group'
|
|
25
|
+
import { For, Show } from 'solid-js'
|
|
26
|
+
import { cn } from '#lib/utils'
|
|
27
|
+
|
|
28
|
+
export const PRIMARY_ACCENT_IDS = ['blue', 'green', 'amber', 'cyan', 'pink'] as const
|
|
29
|
+
const primaryAccentIds: ReadonlySet<string> = new Set(PRIMARY_ACCENT_IDS)
|
|
30
|
+
|
|
31
|
+
type AccentOption = Readonly<{
|
|
32
|
+
id: string
|
|
33
|
+
label: string
|
|
34
|
+
light?: string
|
|
35
|
+
dark?: string
|
|
36
|
+
}>
|
|
37
|
+
|
|
38
|
+
type AccentSwatchGroupsProps = {
|
|
39
|
+
accentOptions: readonly AccentOption[]
|
|
40
|
+
themeAccentOptions: readonly AccentOption[]
|
|
41
|
+
resolvedAppearance: 'light' | 'dark'
|
|
42
|
+
themeDefaultColor: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function AccentSwatchGroups(props: AccentSwatchGroupsProps) {
|
|
46
|
+
const primaryAccents = () =>
|
|
47
|
+
PRIMARY_ACCENT_IDS.flatMap((id) => {
|
|
48
|
+
const option = props.accentOptions.find((candidate) => candidate.id === id)
|
|
49
|
+
return option ? [option] : []
|
|
50
|
+
})
|
|
51
|
+
const additionalAccents = () =>
|
|
52
|
+
props.accentOptions.filter(
|
|
53
|
+
(option) => option.id !== 'theme' && !primaryAccentIds.has(option.id)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<>
|
|
58
|
+
<div class="grid grid-cols-3 gap-2" data-primary-accent-grid>
|
|
59
|
+
<AccentSwatch
|
|
60
|
+
id="theme"
|
|
61
|
+
label="Theme default"
|
|
62
|
+
color={props.themeDefaultColor}
|
|
63
|
+
group="primary"
|
|
64
|
+
/>
|
|
65
|
+
<For each={primaryAccents()}>
|
|
66
|
+
{(option) => (
|
|
67
|
+
<AccentSwatch
|
|
68
|
+
id={option.id}
|
|
69
|
+
label={option.label}
|
|
70
|
+
color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
|
|
71
|
+
group="primary"
|
|
72
|
+
/>
|
|
73
|
+
)}
|
|
74
|
+
</For>
|
|
75
|
+
</div>
|
|
76
|
+
<Show when={additionalAccents().length > 0}>
|
|
77
|
+
<div class="flex flex-col gap-1">
|
|
78
|
+
<span class="text-xs font-medium text-muted-foreground">Additional colors</span>
|
|
79
|
+
<div class="flex flex-wrap gap-2">
|
|
80
|
+
<For each={additionalAccents()}>
|
|
81
|
+
{(option) => (
|
|
82
|
+
<AccentSwatch
|
|
83
|
+
id={option.id}
|
|
84
|
+
label={option.label}
|
|
85
|
+
color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
|
|
86
|
+
group="additional"
|
|
87
|
+
/>
|
|
88
|
+
)}
|
|
89
|
+
</For>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</Show>
|
|
93
|
+
<Show when={props.themeAccentOptions.length > 0}>
|
|
94
|
+
<div class="flex flex-col gap-1">
|
|
95
|
+
<span class="text-xs font-medium text-muted-foreground">Theme accents</span>
|
|
96
|
+
<div class="grid grid-cols-3 gap-2">
|
|
97
|
+
<For each={props.themeAccentOptions}>
|
|
98
|
+
{(option) => (
|
|
99
|
+
<AccentSwatch
|
|
100
|
+
id={option.id}
|
|
101
|
+
label={'Theme ' + option.label.toLowerCase()}
|
|
102
|
+
color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
|
|
103
|
+
group="theme"
|
|
104
|
+
dashed
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
</For>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</Show>
|
|
111
|
+
</>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function AccentSwatch(props: {
|
|
116
|
+
id: string
|
|
117
|
+
label: string
|
|
118
|
+
color: string
|
|
119
|
+
group: 'primary' | 'additional' | 'theme'
|
|
120
|
+
dashed?: boolean
|
|
121
|
+
}) {
|
|
122
|
+
return (
|
|
123
|
+
<Radio.Item
|
|
124
|
+
value={props.id}
|
|
125
|
+
data-accent-option={props.id}
|
|
126
|
+
data-primary-accent={props.group === 'primary' ? props.id : undefined}
|
|
127
|
+
data-additional-accent={props.group === 'additional' ? props.id : undefined}
|
|
128
|
+
data-theme-accent={props.group === 'theme' ? props.id : undefined}
|
|
129
|
+
class="rounded-full focus-within:ring-3 focus-within:ring-ring/50"
|
|
130
|
+
>
|
|
131
|
+
<Radio.ItemInput />
|
|
132
|
+
<Radio.ItemLabel
|
|
133
|
+
class={cn(
|
|
134
|
+
'block size-7 cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary',
|
|
135
|
+
{ 'border-dashed data-[checked]:border-solid': props.dashed }
|
|
136
|
+
)}
|
|
137
|
+
>
|
|
138
|
+
<span
|
|
139
|
+
class="block size-full rounded-full"
|
|
140
|
+
aria-hidden="true"
|
|
141
|
+
style={{ 'background-color': props.color }}
|
|
142
|
+
/>
|
|
143
|
+
<span class="sr-only">{props.label}</span>
|
|
144
|
+
</Radio.ItemLabel>
|
|
145
|
+
</Radio.Item>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
import { RadioGroup as Radio } from '@kobalte/core/radio-group'
|
|
27
27
|
import { For, Show } from 'solid-js'
|
|
28
28
|
import { isThemeAccentId } from '#lib/theme-accents'
|
|
29
|
+
import { AccentSwatchGroups } from './accent-swatch-groups'
|
|
29
30
|
import type { AppearanceEditorProps } from './appearance-types'
|
|
30
31
|
import { ThemeMiniature, ThemeMiniatureSplit } from './theme-preview'
|
|
31
32
|
|
|
@@ -39,7 +40,6 @@ const SURFACES = [
|
|
|
39
40
|
{ value: 'frosted', label: 'Frosted' },
|
|
40
41
|
{ value: 'opaque', label: 'Opaque' },
|
|
41
42
|
] as const
|
|
42
|
-
|
|
43
43
|
export function ModeChoices(props: AppearanceEditorProps) {
|
|
44
44
|
return (
|
|
45
45
|
<Radio
|
|
@@ -113,89 +113,32 @@ export function AccentChoices(props: AppearanceEditorProps) {
|
|
|
113
113
|
disabled={props.saving}
|
|
114
114
|
orientation="horizontal"
|
|
115
115
|
aria-label="Accent"
|
|
116
|
-
|
|
117
|
-
// beside a full-width swatch line overflowed the settings sidebar's
|
|
118
|
-
// control column, so the pair stays a narrow chip plus a wrapped grid.
|
|
119
|
-
class="flex items-center gap-3"
|
|
116
|
+
class="flex flex-col items-start gap-3"
|
|
120
117
|
onChange={(accent) =>
|
|
121
118
|
props.onChange({
|
|
122
119
|
accent: accent === 'custom' ? (props.customAccentValue ?? '') : accent,
|
|
123
120
|
})
|
|
124
121
|
}
|
|
125
122
|
>
|
|
126
|
-
<
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
123
|
+
<AccentSwatchGroups
|
|
124
|
+
accentOptions={props.accentOptions}
|
|
125
|
+
themeAccentOptions={themeAccents()}
|
|
126
|
+
resolvedAppearance={resolvedAppearance()}
|
|
127
|
+
themeDefaultColor={
|
|
128
|
+
resolvedAppearance() === 'light'
|
|
129
|
+
? props.lightTheme.colors.accent
|
|
130
|
+
: props.darkTheme.colors.accent
|
|
131
|
+
}
|
|
132
|
+
/>
|
|
133
|
+
<div class="flex flex-col gap-1">
|
|
134
|
+
<span class="text-xs font-medium text-muted-foreground">Custom</span>
|
|
135
|
+
<Radio.Item value="custom">
|
|
134
136
|
<Radio.ItemInput />
|
|
135
|
-
<Radio.ItemLabel class="
|
|
136
|
-
|
|
137
|
-
class="block size-full rounded-full"
|
|
138
|
-
aria-hidden="true"
|
|
139
|
-
style={{
|
|
140
|
-
'background-color':
|
|
141
|
-
resolvedAppearance() === 'light'
|
|
142
|
-
? props.lightTheme.colors.accent
|
|
143
|
-
: props.darkTheme.colors.accent,
|
|
144
|
-
}}
|
|
145
|
-
/>
|
|
146
|
-
<span class="sr-only">Theme default</span>
|
|
137
|
+
<Radio.ItemLabel 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">
|
|
138
|
+
Custom
|
|
147
139
|
</Radio.ItemLabel>
|
|
148
140
|
</Radio.Item>
|
|
149
|
-
<For each={props.accentOptions}>
|
|
150
|
-
{(option) => (
|
|
151
|
-
<Radio.Item
|
|
152
|
-
value={option.id}
|
|
153
|
-
class="rounded-full focus-within:ring-3 focus-within:ring-ring/50"
|
|
154
|
-
>
|
|
155
|
-
<Radio.ItemInput />
|
|
156
|
-
<Radio.ItemLabel class="block size-7 cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary">
|
|
157
|
-
<span
|
|
158
|
-
class="block size-full rounded-full"
|
|
159
|
-
aria-hidden="true"
|
|
160
|
-
style={{
|
|
161
|
-
'background-color':
|
|
162
|
-
resolvedAppearance() === 'light' ? option.light : option.dark,
|
|
163
|
-
}}
|
|
164
|
-
/>
|
|
165
|
-
<span class="sr-only">{option.label}</span>
|
|
166
|
-
</Radio.ItemLabel>
|
|
167
|
-
</Radio.Item>
|
|
168
|
-
)}
|
|
169
|
-
</For>
|
|
170
|
-
<For each={themeAccents()}>
|
|
171
|
-
{(option) => (
|
|
172
|
-
<Radio.Item
|
|
173
|
-
value={option.id}
|
|
174
|
-
data-theme-accent={option.id}
|
|
175
|
-
class="rounded-full focus-within:ring-3 focus-within:ring-ring/50"
|
|
176
|
-
>
|
|
177
|
-
<Radio.ItemInput />
|
|
178
|
-
<Radio.ItemLabel class="block size-7 cursor-pointer rounded-full border border-dashed p-0.5 data-[checked]:border-solid data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary">
|
|
179
|
-
<span
|
|
180
|
-
class="block size-full rounded-full"
|
|
181
|
-
aria-hidden="true"
|
|
182
|
-
style={{
|
|
183
|
-
'background-color':
|
|
184
|
-
resolvedAppearance() === 'light' ? option.light : option.dark,
|
|
185
|
-
}}
|
|
186
|
-
/>
|
|
187
|
-
<span class="sr-only">{`Theme ${option.label.toLowerCase()}`}</span>
|
|
188
|
-
</Radio.ItemLabel>
|
|
189
|
-
</Radio.Item>
|
|
190
|
-
)}
|
|
191
|
-
</For>
|
|
192
141
|
</div>
|
|
193
|
-
<Radio.Item value="custom">
|
|
194
|
-
<Radio.ItemInput />
|
|
195
|
-
<Radio.ItemLabel 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">
|
|
196
|
-
Custom
|
|
197
|
-
</Radio.ItemLabel>
|
|
198
|
-
</Radio.Item>
|
|
199
142
|
</Radio>
|
|
200
143
|
)
|
|
201
144
|
}
|
|
@@ -32,10 +32,12 @@
|
|
|
32
32
|
* custom accent/reduced-transparency are accepted Adea divergences (#425).
|
|
33
33
|
*/
|
|
34
34
|
import { EyeOff, Palette, PanelsTopLeft, SlidersHorizontal } from 'lucide-solid'
|
|
35
|
-
import { Show, createUniqueId } from 'solid-js'
|
|
35
|
+
import { Show, createSignal, createUniqueId } from 'solid-js'
|
|
36
36
|
import { cn } from '#lib/utils'
|
|
37
37
|
import { Button } from '../../ui/button/button'
|
|
38
38
|
import { Input } from '../../ui/input/input'
|
|
39
|
+
import { AppearanceFontSettingsGroup } from './font-settings-group'
|
|
40
|
+
import { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS } from '#lib/appearance-font-settings'
|
|
39
41
|
|
|
40
42
|
import { Switch } from '../../ui/switch/switch'
|
|
41
43
|
import {
|
|
@@ -54,8 +56,8 @@ import { SettingsRow, TerminalRow, ThemeRow } from './appearance-rows'
|
|
|
54
56
|
* No ThemeProvider is required, and no catalogue, renderer engine or storage is
|
|
55
57
|
* imported. Hosts normalize unknown IDs and custom colors, report recovery,
|
|
56
58
|
* snapshot on open, preview on changes, commit on Save, and restore on dismissal.
|
|
57
|
-
* Both theme rows remain mounted when mode changes.
|
|
58
|
-
*
|
|
59
|
+
* Both theme rows remain mounted when mode changes. Density remains outside the
|
|
60
|
+
* accepted appearance surface; typeface settings are shared and host-persisted.
|
|
59
61
|
*/
|
|
60
62
|
export function AppearanceEditor(props: AppearanceEditorProps) {
|
|
61
63
|
const errorId = createUniqueId()
|
|
@@ -140,6 +142,12 @@ export function AppearanceEditor(props: AppearanceEditorProps) {
|
|
|
140
142
|
</Show>
|
|
141
143
|
</div>
|
|
142
144
|
</Show>
|
|
145
|
+
<AppearanceFontSettingsGroup
|
|
146
|
+
settings={props.draft.fonts ?? DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS}
|
|
147
|
+
menuPortalMount={props.menuPortalMount}
|
|
148
|
+
disabled={props.saving}
|
|
149
|
+
onChange={(fonts) => props.onChange({ fonts })}
|
|
150
|
+
/>
|
|
143
151
|
<SettingsRow title="Glass" icon={<PanelsTopLeft />} description={glassDescription()}>
|
|
144
152
|
<GlassChoices {...props} />
|
|
145
153
|
</SettingsRow>
|
|
@@ -188,7 +196,7 @@ export function AppearanceEditor(props: AppearanceEditorProps) {
|
|
|
188
196
|
{/* Sticky so Save/Cancel stay reachable in a tall scroll container: the
|
|
189
197
|
editor scrolls with its host panel, and actions parked at the bottom
|
|
190
198
|
of a long form were unreachable without scrolling past every row. */}
|
|
191
|
-
<div class="sticky bottom-0 z-10 mt-2 flex flex-wrap items-center gap-2 border-t bg-background px-4 py-3">
|
|
199
|
+
<div class="global-appearance-editor-actions sticky bottom-0 z-10 mt-2 flex flex-wrap items-center gap-2 border-t bg-background px-4 py-3">
|
|
192
200
|
<Button
|
|
193
201
|
type="button"
|
|
194
202
|
size="sm"
|
|
@@ -228,6 +236,8 @@ export function AppearanceEditor(props: AppearanceEditorProps) {
|
|
|
228
236
|
* Its measured available height also bounds scrolling, keeping footer actions
|
|
229
237
|
* reachable when a narrow popup begins below its trigger. */
|
|
230
238
|
export function AppearancePopover(props: AppearancePopoverProps) {
|
|
239
|
+
const [menuPortalMount, setMenuPortalMount] = createSignal<HTMLElement>()
|
|
240
|
+
|
|
231
241
|
return (
|
|
232
242
|
<Popover
|
|
233
243
|
open={props.open}
|
|
@@ -243,12 +253,15 @@ export function AppearancePopover(props: AppearancePopoverProps) {
|
|
|
243
253
|
>
|
|
244
254
|
<Palette />
|
|
245
255
|
</PopoverTrigger>
|
|
246
|
-
<PopoverContent
|
|
256
|
+
<PopoverContent
|
|
257
|
+
ref={setMenuPortalMount}
|
|
258
|
+
class="w-lg max-w-[calc(100vw-2rem)] max-h-(--kb-popper-content-available-height) overflow-y-auto"
|
|
259
|
+
>
|
|
247
260
|
<PopoverTitle>Appearance</PopoverTitle>
|
|
248
261
|
<PopoverDescription>
|
|
249
262
|
Changes preview immediately. Save keeps them; Cancel restores the previous appearance.
|
|
250
263
|
</PopoverDescription>
|
|
251
|
-
<AppearanceEditor {...props} />
|
|
264
|
+
<AppearanceEditor {...props} menuPortalMount={menuPortalMount()} />
|
|
252
265
|
</PopoverContent>
|
|
253
266
|
</Popover>
|
|
254
267
|
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AccentPreset, AdeaTheme, AdeaThemeRecord } from '@adea-ai/themes'
|
|
2
|
+
import type { AppearanceEditorFontSettings } from '#lib/appearance-font-settings'
|
|
2
3
|
|
|
3
4
|
export type AppearanceDraft = Readonly<{
|
|
4
5
|
mode: 'system' | 'light' | 'dark'
|
|
@@ -13,6 +14,12 @@ export type AppearanceDraft = Readonly<{
|
|
|
13
14
|
terminalThemeId?: string
|
|
14
15
|
/** Theme default, a canonical preset id, or the host's custom accent draft. */
|
|
15
16
|
accent: string
|
|
17
|
+
/**
|
|
18
|
+
* The UI, content and code typeface axes. Optional for compatibility with
|
|
19
|
+
* hosts upgrading from the earlier appearance contract; omitted means the
|
|
20
|
+
* shared System defaults.
|
|
21
|
+
*/
|
|
22
|
+
fonts?: AppearanceEditorFontSettings
|
|
16
23
|
surface: 'theme' | 'frosted' | 'opaque'
|
|
17
24
|
reduceTransparency: boolean
|
|
18
25
|
}>
|
|
@@ -45,6 +52,8 @@ export type AppearanceEditorProps = {
|
|
|
45
52
|
surfaceCapability: { frosted: boolean; reason?: string; themeDefaultDescription?: string }
|
|
46
53
|
/** Undefined means theme import is unavailable, never a working-looking action. */
|
|
47
54
|
onManageThemes?: () => void
|
|
55
|
+
/** Mount nested font menus inside the containing overlay when one exists. */
|
|
56
|
+
menuPortalMount?: HTMLElement
|
|
48
57
|
class?: string
|
|
49
58
|
}
|
|
50
59
|
|