@adea-ai/ui 0.142.4 → 0.144.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/dist/components/composites/accent-picker/accent-picker.d.ts +28 -0
- package/dist/components/composites/accent-picker/accent-picker.d.ts.map +1 -0
- package/dist/components/composites/accent-picker/accent-picker.js +107 -0
- package/dist/components/composites/accent-picker/accent-picker.js.map +1 -0
- package/dist/components/composites/accent-picker/index.d.ts +2 -0
- package/dist/components/composites/accent-picker/index.d.ts.map +1 -0
- package/dist/components/composites/accent-picker/index.js +2 -0
- package/dist/components/composites/icon-picker/icon-picker.d.ts +52 -0
- package/dist/components/composites/icon-picker/icon-picker.d.ts.map +1 -0
- package/dist/components/composites/icon-picker/icon-picker.js +265 -0
- package/dist/components/composites/icon-picker/icon-picker.js.map +1 -0
- package/dist/components/composites/icon-picker/image-data-url.d.ts +42 -0
- package/dist/components/composites/icon-picker/image-data-url.d.ts.map +1 -0
- package/dist/components/composites/icon-picker/image-data-url.js +90 -0
- package/dist/components/composites/icon-picker/image-data-url.js.map +1 -0
- package/dist/components/composites/icon-picker/index.d.ts +4 -0
- package/dist/components/composites/icon-picker/index.d.ts.map +1 -0
- package/dist/components/composites/icon-picker/index.js +4 -0
- package/dist/components/composites/icon-picker/shell-icons.d.ts +264 -0
- package/dist/components/composites/icon-picker/shell-icons.d.ts.map +1 -0
- package/dist/components/composites/icon-picker/shell-icons.js +334 -0
- package/dist/components/composites/icon-picker/shell-icons.js.map +1 -0
- package/dist/components/composites/settings/settings-navigation.js +1 -1
- package/dist/components/composites/settings/settings-navigation.js.map +1 -1
- package/dist/components/composites/settings/settings.d.ts +8 -14
- package/dist/components/composites/settings/settings.d.ts.map +1 -1
- package/dist/components/composites/settings/settings.js +88 -37
- package/dist/components/composites/settings/settings.js.map +1 -1
- package/dist/components/composites/terminal/terminal.js +2 -2
- package/dist/components/composites/terminal/terminal.js.map +1 -1
- package/dist/components/composites/tree/tree.d.ts +6 -0
- package/dist/components/composites/tree/tree.d.ts.map +1 -1
- package/dist/components/composites/tree/tree.js +35 -14
- package/dist/components/composites/tree/tree.js.map +1 -1
- package/dist/components/composites/workspace-switcher/index.d.ts +2 -0
- package/dist/components/composites/workspace-switcher/index.d.ts.map +1 -0
- package/dist/components/composites/workspace-switcher/index.js +2 -0
- package/dist/components/composites/workspace-switcher/workspace-switcher.d.ts +44 -0
- package/dist/components/composites/workspace-switcher/workspace-switcher.d.ts.map +1 -0
- package/dist/components/composites/workspace-switcher/workspace-switcher.js +157 -0
- package/dist/components/composites/workspace-switcher/workspace-switcher.js.map +1 -0
- package/dist/components/layout/shell-rail/index.d.ts +2 -0
- package/dist/components/layout/shell-rail/index.d.ts.map +1 -0
- package/dist/components/layout/shell-rail/index.js +2 -0
- package/dist/components/layout/shell-rail/shell-rail.d.ts +36 -0
- package/dist/components/layout/shell-rail/shell-rail.d.ts.map +1 -0
- package/dist/components/layout/shell-rail/shell-rail.js +124 -0
- package/dist/components/layout/shell-rail/shell-rail.js.map +1 -0
- package/dist/components/layout/shell-top-bar/index.d.ts +2 -0
- package/dist/components/layout/shell-top-bar/index.d.ts.map +1 -0
- package/dist/components/layout/shell-top-bar/index.js +2 -0
- package/dist/components/layout/shell-top-bar/shell-top-bar.d.ts +68 -0
- package/dist/components/layout/shell-top-bar/shell-top-bar.d.ts.map +1 -0
- package/dist/components/layout/shell-top-bar/shell-top-bar.js +135 -0
- package/dist/components/layout/shell-top-bar/shell-top-bar.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/r/accent-picker.json +25 -0
- package/dist/r/icon-picker.json +37 -0
- package/dist/r/registry.json +141 -1
- package/dist/r/settings.json +3 -1
- package/dist/r/shell-rail.json +27 -0
- package/dist/r/shell-top-bar.json +23 -0
- package/dist/r/src/components/composites/accent-picker/accent-picker.tsx +106 -0
- package/dist/r/src/components/composites/accent-picker/index.ts +1 -0
- package/dist/r/src/components/composites/icon-picker/icon-picker.tsx +246 -0
- package/dist/r/src/components/composites/icon-picker/image-data-url.ts +107 -0
- package/dist/r/src/components/composites/icon-picker/index.ts +25 -0
- package/dist/r/src/components/composites/icon-picker/shell-icons.ts +166 -0
- package/dist/r/src/components/composites/settings/settings-navigation.tsx +1 -1
- package/dist/r/src/components/composites/settings/settings.tsx +40 -5
- package/dist/r/src/components/composites/tree/tree.tsx +25 -0
- package/dist/r/src/components/composites/workspace-switcher/index.ts +5 -0
- package/dist/r/src/components/composites/workspace-switcher/workspace-switcher.tsx +128 -0
- package/dist/r/src/components/layout/shell-rail/index.ts +1 -0
- package/dist/r/src/components/layout/shell-rail/shell-rail.tsx +120 -0
- package/dist/r/src/components/layout/shell-top-bar/index.ts +1 -0
- package/dist/r/src/components/layout/shell-top-bar/shell-top-bar.tsx +185 -0
- package/dist/r/workspace-switcher.json +26 -0
- package/package.json +1 -1
- package/registry.json +141 -1
- package/src/components/composites/accent-picker/accent-picker.tsx +106 -0
- package/src/components/composites/accent-picker/index.ts +1 -0
- package/src/components/composites/icon-picker/icon-picker.tsx +246 -0
- package/src/components/composites/icon-picker/image-data-url.ts +107 -0
- package/src/components/composites/icon-picker/index.ts +25 -0
- package/src/components/composites/icon-picker/shell-icons.ts +166 -0
- package/src/components/composites/settings/settings-navigation.tsx +1 -1
- package/src/components/composites/settings/settings.tsx +40 -5
- package/src/components/composites/tree/tree.tsx +25 -0
- package/src/components/composites/workspace-switcher/index.ts +5 -0
- package/src/components/composites/workspace-switcher/workspace-switcher.tsx +128 -0
- package/src/components/layout/shell-rail/index.ts +1 -0
- package/src/components/layout/shell-rail/shell-rail.tsx +120 -0
- package/src/components/layout/shell-top-bar/index.ts +1 -0
- package/src/components/layout/shell-top-bar/shell-top-bar.tsx +185 -0
- package/src/index.ts +5 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { Anchor, BookOpen, Bot, Box, Brain, Briefcase, Building2, Camera, ChartColumn, Cloud, Code, Coffee, Compass, Cpu, Database, Dumbbell, Flag, Flame, FlaskConical, Folder, FolderGit2, Gamepad2, Gem, Globe, GraduationCap, Hammer, Heart, House, Key, Layers, Leaf, Lightbulb, Map as Map$1, Megaphone, MessagesSquare, Moon, Mountain, Music, Newspaper, Package, Palette, Plane, Puzzle, Rocket, Server, Shapes, Shield, ShoppingCart, Sparkles, Star, Sun, Target, Terminal, Trophy, Users, Utensils, Wallet, Wrench, Zap } from "lucide-solid";
|
|
2
|
+
//#region src/components/composites/icon-picker/shell-icons.ts
|
|
3
|
+
/**
|
|
4
|
+
* The icons a workspace or a project may choose for itself.
|
|
5
|
+
*
|
|
6
|
+
* A curated set rather than the whole Lucide catalogue, for two reasons the
|
|
7
|
+
* picker depends on: the keys are persisted, so each one is a promise that the
|
|
8
|
+
* glyph keeps existing, and every icon here is imported by name so a consumer's
|
|
9
|
+
* bundle pays for these few dozen glyphs and not for the library.
|
|
10
|
+
*
|
|
11
|
+
* `home`, `box` and `folder` lead the list because they are the defaults the
|
|
12
|
+
* apps already use: Home workspaces carry `home`, other workspaces `box` and
|
|
13
|
+
* projects `folder`. Keys are lowercase kebab-case so they are valid project
|
|
14
|
+
* `iconKey`s as well as workspace logo values.
|
|
15
|
+
*/
|
|
16
|
+
var shellIconEntries = [
|
|
17
|
+
{
|
|
18
|
+
key: "home",
|
|
19
|
+
label: "Home",
|
|
20
|
+
icon: House
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
key: "box",
|
|
24
|
+
label: "Box",
|
|
25
|
+
icon: Box
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: "folder",
|
|
29
|
+
label: "Folder",
|
|
30
|
+
icon: Folder
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
key: "git-folder",
|
|
34
|
+
label: "Repository",
|
|
35
|
+
icon: FolderGit2
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: "briefcase",
|
|
39
|
+
label: "Briefcase",
|
|
40
|
+
icon: Briefcase
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
key: "building",
|
|
44
|
+
label: "Building",
|
|
45
|
+
icon: Building2
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: "users",
|
|
49
|
+
label: "Team",
|
|
50
|
+
icon: Users
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: "rocket",
|
|
54
|
+
label: "Rocket",
|
|
55
|
+
icon: Rocket
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: "star",
|
|
59
|
+
label: "Star",
|
|
60
|
+
icon: Star
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
key: "heart",
|
|
64
|
+
label: "Heart",
|
|
65
|
+
icon: Heart
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: "code",
|
|
69
|
+
label: "Code",
|
|
70
|
+
icon: Code
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: "terminal",
|
|
74
|
+
label: "Terminal",
|
|
75
|
+
icon: Terminal
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: "cpu",
|
|
79
|
+
label: "Chip",
|
|
80
|
+
icon: Cpu
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
key: "server",
|
|
84
|
+
label: "Server",
|
|
85
|
+
icon: Server
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: "database",
|
|
89
|
+
label: "Database",
|
|
90
|
+
icon: Database
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
key: "cloud",
|
|
94
|
+
label: "Cloud",
|
|
95
|
+
icon: Cloud
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
key: "globe",
|
|
99
|
+
label: "Globe",
|
|
100
|
+
icon: Globe
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
key: "bot",
|
|
104
|
+
label: "Agent",
|
|
105
|
+
icon: Bot
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
key: "brain",
|
|
109
|
+
label: "Brain",
|
|
110
|
+
icon: Brain
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: "sparkles",
|
|
114
|
+
label: "Sparkles",
|
|
115
|
+
icon: Sparkles
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
key: "lightbulb",
|
|
119
|
+
label: "Idea",
|
|
120
|
+
icon: Lightbulb
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
key: "flask",
|
|
124
|
+
label: "Lab",
|
|
125
|
+
icon: FlaskConical
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: "book",
|
|
129
|
+
label: "Book",
|
|
130
|
+
icon: BookOpen
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: "graduation",
|
|
134
|
+
label: "Study",
|
|
135
|
+
icon: GraduationCap
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
key: "newspaper",
|
|
139
|
+
label: "News",
|
|
140
|
+
icon: Newspaper
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
key: "megaphone",
|
|
144
|
+
label: "Marketing",
|
|
145
|
+
icon: Megaphone
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
key: "chart",
|
|
149
|
+
label: "Chart",
|
|
150
|
+
icon: ChartColumn
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
key: "wallet",
|
|
154
|
+
label: "Finance",
|
|
155
|
+
icon: Wallet
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
key: "cart",
|
|
159
|
+
label: "Shop",
|
|
160
|
+
icon: ShoppingCart
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
key: "package",
|
|
164
|
+
label: "Package",
|
|
165
|
+
icon: Package
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
key: "layers",
|
|
169
|
+
label: "Layers",
|
|
170
|
+
icon: Layers
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: "puzzle",
|
|
174
|
+
label: "Puzzle",
|
|
175
|
+
icon: Puzzle
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
key: "shield",
|
|
179
|
+
label: "Security",
|
|
180
|
+
icon: Shield
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
key: "key",
|
|
184
|
+
label: "Key",
|
|
185
|
+
icon: Key
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
key: "wrench",
|
|
189
|
+
label: "Tools",
|
|
190
|
+
icon: Wrench
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
key: "hammer",
|
|
194
|
+
label: "Build",
|
|
195
|
+
icon: Hammer
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
key: "zap",
|
|
199
|
+
label: "Bolt",
|
|
200
|
+
icon: Zap
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
key: "flame",
|
|
204
|
+
label: "Flame",
|
|
205
|
+
icon: Flame
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: "target",
|
|
209
|
+
label: "Target",
|
|
210
|
+
icon: Target
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
key: "trophy",
|
|
214
|
+
label: "Trophy",
|
|
215
|
+
icon: Trophy
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: "flag",
|
|
219
|
+
label: "Flag",
|
|
220
|
+
icon: Flag
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
key: "compass",
|
|
224
|
+
label: "Compass",
|
|
225
|
+
icon: Compass
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
key: "map",
|
|
229
|
+
label: "Map",
|
|
230
|
+
icon: Map$1
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
key: "plane",
|
|
234
|
+
label: "Travel",
|
|
235
|
+
icon: Plane
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
key: "anchor",
|
|
239
|
+
label: "Anchor",
|
|
240
|
+
icon: Anchor
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
key: "mountain",
|
|
244
|
+
label: "Mountain",
|
|
245
|
+
icon: Mountain
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
key: "leaf",
|
|
249
|
+
label: "Garden",
|
|
250
|
+
icon: Leaf
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
key: "sun",
|
|
254
|
+
label: "Sun",
|
|
255
|
+
icon: Sun
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
key: "moon",
|
|
259
|
+
label: "Moon",
|
|
260
|
+
icon: Moon
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
key: "palette",
|
|
264
|
+
label: "Design",
|
|
265
|
+
icon: Palette
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
key: "camera",
|
|
269
|
+
label: "Camera",
|
|
270
|
+
icon: Camera
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
key: "music",
|
|
274
|
+
label: "Music",
|
|
275
|
+
icon: Music
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
key: "gamepad",
|
|
279
|
+
label: "Games",
|
|
280
|
+
icon: Gamepad2
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
key: "coffee",
|
|
284
|
+
label: "Coffee",
|
|
285
|
+
icon: Coffee
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
key: "utensils",
|
|
289
|
+
label: "Kitchen",
|
|
290
|
+
icon: Utensils
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
key: "dumbbell",
|
|
294
|
+
label: "Gym",
|
|
295
|
+
icon: Dumbbell
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
key: "gem",
|
|
299
|
+
label: "Gem",
|
|
300
|
+
icon: Gem
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
key: "messages",
|
|
304
|
+
label: "Chat",
|
|
305
|
+
icon: MessagesSquare
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: "shapes",
|
|
309
|
+
label: "Shapes",
|
|
310
|
+
icon: Shapes
|
|
311
|
+
}
|
|
312
|
+
];
|
|
313
|
+
var shellIconByKey = new Map(shellIconEntries.map((entry) => [entry.key, entry.icon]));
|
|
314
|
+
/** Whether a stored string names an icon in the curated set. */
|
|
315
|
+
function isShellIconKey(value) {
|
|
316
|
+
return shellIconByKey.has(value);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* The glyph for a stored key, or `fallback` when the key is not in the set.
|
|
320
|
+
* Callers pass the fallback their surface wants (a workspace falls back to
|
|
321
|
+
* `box`, a project to `folder`), so an unknown key degrades to the default
|
|
322
|
+
* rather than to an empty tile.
|
|
323
|
+
*/
|
|
324
|
+
function resolveShellIcon(key, fallback = "folder") {
|
|
325
|
+
return (key ? shellIconByKey.get(key) : void 0) ?? shellIconByKey.get(fallback);
|
|
326
|
+
}
|
|
327
|
+
/** The picker's accessible name for a key. */
|
|
328
|
+
function shellIconLabel(key) {
|
|
329
|
+
return shellIconEntries.find((entry) => entry.key === key)?.label ?? key;
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
export { isShellIconKey, resolveShellIcon, shellIconEntries, shellIconLabel };
|
|
333
|
+
|
|
334
|
+
//# sourceMappingURL=shell-icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-icons.js","names":["MapIcon"],"sources":["../../../../src/components/composites/icon-picker/shell-icons.ts"],"sourcesContent":["import {\n Anchor,\n Bot,\n Box,\n BookOpen,\n Brain,\n Briefcase,\n Building2,\n Camera,\n ChartColumn,\n Cloud,\n Code,\n Coffee,\n Compass,\n Cpu,\n Database,\n Dumbbell,\n Flag,\n Flame,\n FlaskConical,\n Folder,\n FolderGit2,\n Gamepad2,\n Gem,\n Globe,\n GraduationCap,\n Hammer,\n Heart,\n House,\n Key,\n Layers,\n Leaf,\n Lightbulb,\n type LucideIcon,\n Map as MapIcon,\n Megaphone,\n MessagesSquare,\n Moon,\n Mountain,\n Music,\n Newspaper,\n Package,\n Palette,\n Plane,\n Puzzle,\n Rocket,\n Server,\n Shapes,\n Shield,\n ShoppingCart,\n Sparkles,\n Star,\n Sun,\n Target,\n Terminal,\n Trophy,\n Users,\n Utensils,\n Wallet,\n Wrench,\n Zap,\n} from 'lucide-solid'\n\n/**\n * The icons a workspace or a project may choose for itself.\n *\n * A curated set rather than the whole Lucide catalogue, for two reasons the\n * picker depends on: the keys are persisted, so each one is a promise that the\n * glyph keeps existing, and every icon here is imported by name so a consumer's\n * bundle pays for these few dozen glyphs and not for the library.\n *\n * `home`, `box` and `folder` lead the list because they are the defaults the\n * apps already use: Home workspaces carry `home`, other workspaces `box` and\n * projects `folder`. Keys are lowercase kebab-case so they are valid project\n * `iconKey`s as well as workspace logo values.\n */\nexport const shellIconEntries = [\n { key: 'home', label: 'Home', icon: House },\n { key: 'box', label: 'Box', icon: Box },\n { key: 'folder', label: 'Folder', icon: Folder },\n { key: 'git-folder', label: 'Repository', icon: FolderGit2 },\n { key: 'briefcase', label: 'Briefcase', icon: Briefcase },\n { key: 'building', label: 'Building', icon: Building2 },\n { key: 'users', label: 'Team', icon: Users },\n { key: 'rocket', label: 'Rocket', icon: Rocket },\n { key: 'star', label: 'Star', icon: Star },\n { key: 'heart', label: 'Heart', icon: Heart },\n { key: 'code', label: 'Code', icon: Code },\n { key: 'terminal', label: 'Terminal', icon: Terminal },\n { key: 'cpu', label: 'Chip', icon: Cpu },\n { key: 'server', label: 'Server', icon: Server },\n { key: 'database', label: 'Database', icon: Database },\n { key: 'cloud', label: 'Cloud', icon: Cloud },\n { key: 'globe', label: 'Globe', icon: Globe },\n { key: 'bot', label: 'Agent', icon: Bot },\n { key: 'brain', label: 'Brain', icon: Brain },\n { key: 'sparkles', label: 'Sparkles', icon: Sparkles },\n { key: 'lightbulb', label: 'Idea', icon: Lightbulb },\n { key: 'flask', label: 'Lab', icon: FlaskConical },\n { key: 'book', label: 'Book', icon: BookOpen },\n { key: 'graduation', label: 'Study', icon: GraduationCap },\n { key: 'newspaper', label: 'News', icon: Newspaper },\n { key: 'megaphone', label: 'Marketing', icon: Megaphone },\n { key: 'chart', label: 'Chart', icon: ChartColumn },\n { key: 'wallet', label: 'Finance', icon: Wallet },\n { key: 'cart', label: 'Shop', icon: ShoppingCart },\n { key: 'package', label: 'Package', icon: Package },\n { key: 'layers', label: 'Layers', icon: Layers },\n { key: 'puzzle', label: 'Puzzle', icon: Puzzle },\n { key: 'shield', label: 'Security', icon: Shield },\n { key: 'key', label: 'Key', icon: Key },\n { key: 'wrench', label: 'Tools', icon: Wrench },\n { key: 'hammer', label: 'Build', icon: Hammer },\n { key: 'zap', label: 'Bolt', icon: Zap },\n { key: 'flame', label: 'Flame', icon: Flame },\n { key: 'target', label: 'Target', icon: Target },\n { key: 'trophy', label: 'Trophy', icon: Trophy },\n { key: 'flag', label: 'Flag', icon: Flag },\n { key: 'compass', label: 'Compass', icon: Compass },\n { key: 'map', label: 'Map', icon: MapIcon },\n { key: 'plane', label: 'Travel', icon: Plane },\n { key: 'anchor', label: 'Anchor', icon: Anchor },\n { key: 'mountain', label: 'Mountain', icon: Mountain },\n { key: 'leaf', label: 'Garden', icon: Leaf },\n { key: 'sun', label: 'Sun', icon: Sun },\n { key: 'moon', label: 'Moon', icon: Moon },\n { key: 'palette', label: 'Design', icon: Palette },\n { key: 'camera', label: 'Camera', icon: Camera },\n { key: 'music', label: 'Music', icon: Music },\n { key: 'gamepad', label: 'Games', icon: Gamepad2 },\n { key: 'coffee', label: 'Coffee', icon: Coffee },\n { key: 'utensils', label: 'Kitchen', icon: Utensils },\n { key: 'dumbbell', label: 'Gym', icon: Dumbbell },\n { key: 'gem', label: 'Gem', icon: Gem },\n { key: 'messages', label: 'Chat', icon: MessagesSquare },\n { key: 'shapes', label: 'Shapes', icon: Shapes },\n] as const satisfies readonly Readonly<{ key: string; label: string; icon: LucideIcon }>[]\n\nexport type ShellIconKey = (typeof shellIconEntries)[number]['key']\n\nconst shellIconByKey: ReadonlyMap<string, LucideIcon> = new Map(\n shellIconEntries.map((entry) => [entry.key, entry.icon])\n)\n\n/** Whether a stored string names an icon in the curated set. */\nexport function isShellIconKey(value: string): value is ShellIconKey {\n return shellIconByKey.has(value)\n}\n\n/**\n * The glyph for a stored key, or `fallback` when the key is not in the set.\n * Callers pass the fallback their surface wants (a workspace falls back to\n * `box`, a project to `folder`), so an unknown key degrades to the default\n * rather than to an empty tile.\n */\nexport function resolveShellIcon(\n key: string | null | undefined,\n fallback: ShellIconKey = 'folder'\n): LucideIcon {\n return (key ? shellIconByKey.get(key) : undefined) ?? shellIconByKey.get(fallback)!\n}\n\n/** The picker's accessible name for a key. */\nexport function shellIconLabel(key: string): string {\n return shellIconEntries.find((entry) => entry.key === key)?.label ?? key\n}\n"],"mappings":"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"}
|
|
@@ -130,7 +130,7 @@ function SettingsNavigation(props) {
|
|
|
130
130
|
if (local.value === item.value) local.onReselect?.(item.value);
|
|
131
131
|
},
|
|
132
132
|
get ["class"]() {
|
|
133
|
-
return cn(sidebarNavItemClass, sidebarNavItemStateClass.idle, "h-row-lg justify-start border-0 px-3 py-2 text-left data-[selected]:bg-primary-subtle
|
|
133
|
+
return cn(sidebarNavItemClass, sidebarNavItemStateClass.idle, "h-row-lg justify-start border-0 px-3 py-2 text-left text-foreground data-[selected]:bg-primary-subtle", strip() ? "w-auto shrink-0" : "w-full");
|
|
134
134
|
},
|
|
135
135
|
get children() {
|
|
136
136
|
return [memo(() => item.icon), (() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-navigation.js","names":["useTabsContext","JSX","createEffect","createUniqueId","onCleanup","Show","splitProps","cn","sidebarNavItemClass","sidebarNavItemStateClass","TabsList","TabsTrigger","TabsListProps","Text","SettingsNavigationItem","value","label","icon","Element","disabled","SettingsNavigationGroup","items","SettingsNavigationProps","Omit","groups","onReselect","revealSelected","trigger","HTMLButtonElement","scrollContainerNearest","container","HTMLElement","row","style","window","getComputedStyle","box","getBoundingClientRect","rowBox","overflowX","left","scrollLeft","right","overflowY","top","scrollTop","bottom","revealNearest","parentElement","SettingsNavigation","props","local","rest","tabs","strip","orientation","triggers","Map","groupIdPrefix","reveal","revealCurrent","get","addEventListener","removeEventListener","_$createComponent","_$mergeProps","aria-label","class","children","map","group","groupIndex","groupId","_el$","_tmpl$","_el$2","firstChild","_$setAttribute","_$insert","when","variant","tone","item","ref","element","set","delete","onClick","idle","_$memo","_el$3","_tmpl$2","_$effect","_$className","truncate","_$createComponent","_$mergeProps","_$memo","_$className"],"sources":["../../../../src/components/composites/settings/settings-navigation.tsx"],"sourcesContent":["import { useTabsContext } from '@kobalte/core/tabs'\nimport type { JSX } from 'solid-js'\nimport { createEffect, createUniqueId, onCleanup, Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { sidebarNavItemClass, sidebarNavItemStateClass } from '../../layout/sidebar-nav/sidebar-nav'\nimport { TabsList, TabsTrigger, type TabsListProps } from '../../ui/tabs'\nimport { Text } from '../../ui/typography'\n\n/** One host-owned destination in a settings tab list. Values must be unique. */\nexport type SettingsNavigationItem = {\n value: string\n label: string\n icon?: JSX.Element\n disabled?: boolean\n}\n\n/** A visible, accessibly named group of settings destinations. */\nexport type SettingsNavigationGroup = {\n label: string\n items: readonly SettingsNavigationItem[]\n}\n\nexport type SettingsNavigationProps = Omit<\n TabsListProps,\n 'appearance' | 'children' | 'orientation'\n> & {\n /** Groups are presentation only; the host owns the tab values and panels. */\n groups: readonly SettingsNavigationGroup[]\n /** The same controlled value supplied to the enclosing `Tabs`. */\n value: string\n /** Called when the already-selected destination is activated again. */\n onReselect?: (value: string) => void\n /** Reveal the selected row on value changes and window resizes. Defaults to nearest scrolling\n * of the ancestors that expose a scroll affordance; hidden-overflow ancestors never move. */\n revealSelected?:\n | boolean\n | ((\n trigger: HTMLButtonElement | undefined\n ) => void) /** Every tab list needs a label independent of its visible group headings. */\n 'aria-label': string\n}\n\n/**\n * SettingsNavigation.\n *\n * A grouped vertical tab list for sibling settings panels. It composes the\n * shared Tabs behaviour with the shared sidebar row recipe; the host supplies\n * the controlled value, panel content, icons and any persistence or routing.\n * Use ordinary tabs for a short, ungrouped row of view choices.\n *\n * The shape follows the enclosing `Tabs` orientation rather than a prop of its\n * own, so the visual axis can never disagree with the arrow keys Kobalte\n * binds: `vertical` is the grouped rail, `horizontal` is a single scrollable\n * strip of tabs (what `SettingsLayout` shows below 48rem). The strip keeps the\n * groups in order, separated by a rule; their visible headings drop out, since\n * an overline between tabs reads as another tab, but each tab still carries its\n * group as its accessible description.\n *\n * Kobalte owns roving focus, arrow keys, selection and tab/panel ARIA. This\n * component adds no URL, storage or host-specific state. Set\n * `revealSelected={false}` when the surrounding layout does not use an internal\n * scrolling viewport.\n */\n/**\n * Reveal by scrolling only the ancestors that expose a scroll affordance\n * (`auto` or `scroll`), by the exact nearest-edge delta. `scrollIntoView` also\n * pans `overflow: hidden` ancestors, which are programmatically scrollable but\n * give the user no way back, so one over-pan left earlier rows permanently\n * clipped outside the viewport with no scroll to recover them (#182).\n */\nfunction scrollContainerNearest(container: HTMLElement, row: HTMLElement): void {\n const style = window.getComputedStyle(container)\n const box = container.getBoundingClientRect()\n const rowBox = row.getBoundingClientRect()\n if (style.overflowX === 'auto' || style.overflowX === 'scroll') {\n if (rowBox.left < box.left) container.scrollLeft += rowBox.left - box.left\n else if (rowBox.right > box.right) container.scrollLeft += rowBox.right - box.right\n }\n if (style.overflowY === 'auto' || style.overflowY === 'scroll') {\n if (rowBox.top < box.top) container.scrollTop += rowBox.top - box.top\n else if (rowBox.bottom > box.bottom) container.scrollTop += rowBox.bottom - box.bottom\n }\n}\n\nfunction revealNearest(row: HTMLElement): void {\n for (let container = row.parentElement; container; container = container.parentElement) {\n scrollContainerNearest(container, row)\n }\n}\n\nexport function SettingsNavigation(props: SettingsNavigationProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'aria-label',\n 'groups',\n 'value',\n 'onReselect',\n 'revealSelected',\n ])\n const tabs = useTabsContext()\n const strip = () => tabs.orientation() === 'horizontal'\n const triggers = new Map<string, HTMLButtonElement>()\n const groupIdPrefix = `settings-navigation-${createUniqueId()}`\n\n createEffect(() => {\n const value = local.value\n const reveal = local.revealSelected\n // Tracked so a rail that becomes a strip (or back) re-reveals on the new axis.\n strip()\n if (reveal === false) return\n\n const revealCurrent = () => {\n const trigger = triggers.get(value)\n if (typeof reveal === 'function') reveal(trigger)\n else if (trigger) revealNearest(trigger)\n }\n\n revealCurrent()\n window.addEventListener('resize', revealCurrent)\n onCleanup(() => window.removeEventListener('resize', revealCurrent))\n })\n\n return (\n <TabsList\n data-slot=\"settings-navigation\"\n aria-label={local['aria-label']}\n orientation={tabs.orientation()}\n class={cn(\n // Positioned so the visually hidden group names are laid out (and\n // clipped) inside the list: unpositioned, their absolute boxes escape a\n // scrolled strip and widen the page by however far it has scrolled.\n 'relative flex min-w-0 shrink-0 justify-start',\n strip()\n ? // The block padding is the room the focus ring needs: a scroller\n // clips at its padding edge, and this one scrolls sideways only.\n 'scroll-fade w-full flex-row items-center gap-1 overflow-x-auto overflow-y-hidden border-b border-border px-2 py-1.5'\n : 'max-h-full min-h-0 flex-col items-stretch gap-2 overflow-x-hidden overflow-y-auto px-2 py-2',\n local.class\n )}\n {...rest}\n >\n {local.groups.map((group, groupIndex) => {\n const groupId = `${groupIdPrefix}-group-${groupIndex}`\n return (\n <div\n role=\"none\"\n data-slot=\"settings-navigation-group\"\n class={cn(\n 'flex gap-0.5',\n strip()\n ? 'shrink-0 flex-row items-center not-first:ms-1 not-first:border-s not-first:border-border not-first:ps-2'\n : 'min-w-0 flex-col'\n )}\n >\n <span id={groupId} class=\"sr-only\">\n {group.label}\n </span>\n <Show when={!strip()}>\n {/* The overline role on the sidebar's own muted foreground. */}\n <Text\n variant=\"overline\"\n tone=\"inherit\"\n aria-hidden=\"true\"\n class=\"px-2 py-1.5 text-sidebar-muted-foreground\"\n >\n {group.label}\n </Text>\n </Show>\n {group.items.map((item) => (\n <TabsTrigger\n data-slot=\"settings-navigation-trigger\"\n aria-describedby={groupId}\n value={item.value}\n disabled={item.disabled}\n ref={(element: HTMLButtonElement | undefined) => {\n if (element) triggers.set(item.value, element)\n else triggers.delete(item.value)\n }}\n onClick={() => {\n if (local.value === item.value) local.onReselect?.(item.value)\n }}\n class={cn(\n sidebarNavItemClass,\n sidebarNavItemStateClass.idle,\n 'h-row-lg justify-start border-0 px-3 py-2 text-left data-[selected]:bg-primary-subtle data-[selected]:text-foreground',\n strip() ? 'w-auto shrink-0' : 'w-full'\n )}\n >\n {item.icon}\n <span class={cn('min-w-0', { truncate: !strip() })}>{item.label}</span>\n </TabsTrigger>\n ))}\n </div>\n )\n })}\n </TabsList>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"settings-navigation.js","names":["useTabsContext","JSX","createEffect","createUniqueId","onCleanup","Show","splitProps","cn","sidebarNavItemClass","sidebarNavItemStateClass","TabsList","TabsTrigger","TabsListProps","Text","SettingsNavigationItem","value","label","icon","Element","disabled","SettingsNavigationGroup","items","SettingsNavigationProps","Omit","groups","onReselect","revealSelected","trigger","HTMLButtonElement","scrollContainerNearest","container","HTMLElement","row","style","window","getComputedStyle","box","getBoundingClientRect","rowBox","overflowX","left","scrollLeft","right","overflowY","top","scrollTop","bottom","revealNearest","parentElement","SettingsNavigation","props","local","rest","tabs","strip","orientation","triggers","Map","groupIdPrefix","reveal","revealCurrent","get","addEventListener","removeEventListener","_$createComponent","_$mergeProps","aria-label","class","children","map","group","groupIndex","groupId","_el$","_tmpl$","_el$2","firstChild","_$setAttribute","_$insert","when","variant","tone","item","ref","element","set","delete","onClick","idle","_$memo","_el$3","_tmpl$2","_$effect","_$className","truncate","_$createComponent","_$mergeProps","_$memo","_$className"],"sources":["../../../../src/components/composites/settings/settings-navigation.tsx"],"sourcesContent":["import { useTabsContext } from '@kobalte/core/tabs'\nimport type { JSX } from 'solid-js'\nimport { createEffect, createUniqueId, onCleanup, Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { sidebarNavItemClass, sidebarNavItemStateClass } from '../../layout/sidebar-nav/sidebar-nav'\nimport { TabsList, TabsTrigger, type TabsListProps } from '../../ui/tabs'\nimport { Text } from '../../ui/typography'\n\n/** One host-owned destination in a settings tab list. Values must be unique. */\nexport type SettingsNavigationItem = {\n value: string\n label: string\n icon?: JSX.Element\n disabled?: boolean\n}\n\n/** A visible, accessibly named group of settings destinations. */\nexport type SettingsNavigationGroup = {\n label: string\n items: readonly SettingsNavigationItem[]\n}\n\nexport type SettingsNavigationProps = Omit<\n TabsListProps,\n 'appearance' | 'children' | 'orientation'\n> & {\n /** Groups are presentation only; the host owns the tab values and panels. */\n groups: readonly SettingsNavigationGroup[]\n /** The same controlled value supplied to the enclosing `Tabs`. */\n value: string\n /** Called when the already-selected destination is activated again. */\n onReselect?: (value: string) => void\n /** Reveal the selected row on value changes and window resizes. Defaults to nearest scrolling\n * of the ancestors that expose a scroll affordance; hidden-overflow ancestors never move. */\n revealSelected?:\n | boolean\n | ((\n trigger: HTMLButtonElement | undefined\n ) => void) /** Every tab list needs a label independent of its visible group headings. */\n 'aria-label': string\n}\n\n/**\n * SettingsNavigation.\n *\n * A grouped vertical tab list for sibling settings panels. It composes the\n * shared Tabs behaviour with the shared sidebar row recipe; the host supplies\n * the controlled value, panel content, icons and any persistence or routing.\n * Use ordinary tabs for a short, ungrouped row of view choices.\n *\n * The shape follows the enclosing `Tabs` orientation rather than a prop of its\n * own, so the visual axis can never disagree with the arrow keys Kobalte\n * binds: `vertical` is the grouped rail, `horizontal` is a single scrollable\n * strip of tabs (what `SettingsLayout` shows below 48rem). The strip keeps the\n * groups in order, separated by a rule; their visible headings drop out, since\n * an overline between tabs reads as another tab, but each tab still carries its\n * group as its accessible description.\n *\n * Kobalte owns roving focus, arrow keys, selection and tab/panel ARIA. This\n * component adds no URL, storage or host-specific state. Set\n * `revealSelected={false}` when the surrounding layout does not use an internal\n * scrolling viewport.\n */\n/**\n * Reveal by scrolling only the ancestors that expose a scroll affordance\n * (`auto` or `scroll`), by the exact nearest-edge delta. `scrollIntoView` also\n * pans `overflow: hidden` ancestors, which are programmatically scrollable but\n * give the user no way back, so one over-pan left earlier rows permanently\n * clipped outside the viewport with no scroll to recover them (#182).\n */\nfunction scrollContainerNearest(container: HTMLElement, row: HTMLElement): void {\n const style = window.getComputedStyle(container)\n const box = container.getBoundingClientRect()\n const rowBox = row.getBoundingClientRect()\n if (style.overflowX === 'auto' || style.overflowX === 'scroll') {\n if (rowBox.left < box.left) container.scrollLeft += rowBox.left - box.left\n else if (rowBox.right > box.right) container.scrollLeft += rowBox.right - box.right\n }\n if (style.overflowY === 'auto' || style.overflowY === 'scroll') {\n if (rowBox.top < box.top) container.scrollTop += rowBox.top - box.top\n else if (rowBox.bottom > box.bottom) container.scrollTop += rowBox.bottom - box.bottom\n }\n}\n\nfunction revealNearest(row: HTMLElement): void {\n for (let container = row.parentElement; container; container = container.parentElement) {\n scrollContainerNearest(container, row)\n }\n}\n\nexport function SettingsNavigation(props: SettingsNavigationProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'aria-label',\n 'groups',\n 'value',\n 'onReselect',\n 'revealSelected',\n ])\n const tabs = useTabsContext()\n const strip = () => tabs.orientation() === 'horizontal'\n const triggers = new Map<string, HTMLButtonElement>()\n const groupIdPrefix = `settings-navigation-${createUniqueId()}`\n\n createEffect(() => {\n const value = local.value\n const reveal = local.revealSelected\n // Tracked so a rail that becomes a strip (or back) re-reveals on the new axis.\n strip()\n if (reveal === false) return\n\n const revealCurrent = () => {\n const trigger = triggers.get(value)\n if (typeof reveal === 'function') reveal(trigger)\n else if (trigger) revealNearest(trigger)\n }\n\n revealCurrent()\n window.addEventListener('resize', revealCurrent)\n onCleanup(() => window.removeEventListener('resize', revealCurrent))\n })\n\n return (\n <TabsList\n data-slot=\"settings-navigation\"\n aria-label={local['aria-label']}\n orientation={tabs.orientation()}\n class={cn(\n // Positioned so the visually hidden group names are laid out (and\n // clipped) inside the list: unpositioned, their absolute boxes escape a\n // scrolled strip and widen the page by however far it has scrolled.\n 'relative flex min-w-0 shrink-0 justify-start',\n strip()\n ? // The block padding is the room the focus ring needs: a scroller\n // clips at its padding edge, and this one scrolls sideways only.\n 'scroll-fade w-full flex-row items-center gap-1 overflow-x-auto overflow-y-hidden border-b border-border px-2 py-1.5'\n : 'max-h-full min-h-0 flex-col items-stretch gap-2 overflow-x-hidden overflow-y-auto px-2 py-2',\n local.class\n )}\n {...rest}\n >\n {local.groups.map((group, groupIndex) => {\n const groupId = `${groupIdPrefix}-group-${groupIndex}`\n return (\n <div\n role=\"none\"\n data-slot=\"settings-navigation-group\"\n class={cn(\n 'flex gap-0.5',\n strip()\n ? 'shrink-0 flex-row items-center not-first:ms-1 not-first:border-s not-first:border-border not-first:ps-2'\n : 'min-w-0 flex-col'\n )}\n >\n <span id={groupId} class=\"sr-only\">\n {group.label}\n </span>\n <Show when={!strip()}>\n {/* The overline role on the sidebar's own muted foreground. */}\n <Text\n variant=\"overline\"\n tone=\"inherit\"\n aria-hidden=\"true\"\n class=\"px-2 py-1.5 text-sidebar-muted-foreground\"\n >\n {group.label}\n </Text>\n </Show>\n {group.items.map((item) => (\n <TabsTrigger\n data-slot=\"settings-navigation-trigger\"\n aria-describedby={groupId}\n value={item.value}\n disabled={item.disabled}\n ref={(element: HTMLButtonElement | undefined) => {\n if (element) triggers.set(item.value, element)\n else triggers.delete(item.value)\n }}\n onClick={() => {\n if (local.value === item.value) local.onReselect?.(item.value)\n }}\n class={cn(\n sidebarNavItemClass,\n sidebarNavItemStateClass.idle,\n 'h-row-lg justify-start border-0 px-3 py-2 text-left text-foreground data-[selected]:bg-primary-subtle',\n strip() ? 'w-auto shrink-0' : 'w-full'\n )}\n >\n {item.icon}\n <span class={cn('min-w-0', { truncate: !strip() })}>{item.label}</span>\n </TabsTrigger>\n ))}\n </div>\n )\n })}\n </TabsList>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsEA,SAAS6B,uBAAuBC,WAAwBE,KAAwB;CAC9E,MAAMC,QAAQC,OAAOC,iBAAiBL,SAAS;CAC/C,MAAMM,MAAMN,UAAUO,sBAAsB;CAC5C,MAAMC,SAASN,IAAIK,sBAAsB;CACzC,IAAIJ,MAAMM,cAAc,UAAUN,MAAMM,cAAc,UAAU;EAC9D,IAAID,OAAOE,OAAOJ,IAAII,MAAMV,UAAUW,cAAcH,OAAOE,OAAOJ,IAAII;OACjE,IAAIF,OAAOI,QAAQN,IAAIM,OAAOZ,UAAUW,cAAcH,OAAOI,QAAQN,IAAIM;CAChF;CACA,IAAIT,MAAMU,cAAc,UAAUV,MAAMU,cAAc,UAAU;EAC9D,IAAIL,OAAOM,MAAMR,IAAIQ,KAAKd,UAAUe,aAAaP,OAAOM,MAAMR,IAAIQ;OAC7D,IAAIN,OAAOQ,SAASV,IAAIU,QAAQhB,UAAUe,aAAaP,OAAOQ,SAASV,IAAIU;CAClF;AACF;AAEA,SAASC,cAAcf,KAAwB;CAC7C,KAAK,IAAIF,YAAYE,IAAIgB,eAAelB,WAAWA,YAAYA,UAAUkB,eACvEnB,uBAAuBC,WAAWE,GAAG;AAEzC;AAEA,SAAgBiB,mBAAmBC,OAAgC;CACjE,MAAM,CAACC,OAAOC,QAAQ9C,WAAW4C,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;CAAgB,CACjB;CACD,MAAMG,OAAOrD,eAAe;CAC5B,MAAMsD,cAAcD,KAAKE,YAAY,MAAM;CAC3C,MAAMC,2BAAW,IAAIC,IAA+B;CACpD,MAAMC,gBAAgB,uBAAuBvD,eAAe;CAE5DD,mBAAmB;EACjB,MAAMa,QAAQoC,MAAMpC;EACpB,MAAM4C,SAASR,MAAMzB;EAErB4B,MAAM;EACN,IAAIK,WAAW,OAAO;EAEtB,MAAMC,sBAAsB;GAC1B,MAAMjC,UAAU6B,SAASK,IAAI9C,KAAK;GAClC,IAAI,OAAO4C,WAAW,YAAYA,OAAOhC,OAAO;QAC3C,IAAIA,SAASoB,cAAcpB,OAAO;EACzC;EAEAiC,cAAc;EACd1B,OAAO4B,iBAAiB,UAAUF,aAAa;EAC/CxD,gBAAgB8B,OAAO6B,oBAAoB,UAAUH,aAAa,CAAC;CACrE,CAAC;CAED,OAAAI,gBACGtD,UAAQuD,WAAA;EAAA,aAAA;EAAA,KAAA,gBAAA;GAAA,OAEKd,MAAM;EAAa;EAAA,IAC/BI,cAAW;GAAA,OAAEF,KAAKE,YAAY;EAAC;EAAA,KAAA,WAAA;GAAA,OACxBhD,GAIL,gDACA+C,MAAM,IAGF,wHACA,+FACJH,MAAMgB,KACR;EAAC;CAAA,GACGf,MAAI,EAAA,IAAAgB,WAAA;EAAA,OAEPjB,MAAM3B,OAAO6C,KAAKC,OAAOC,eAAe;GACvC,MAAMC,UAAU,GAAGd,cAAa,SAAUa;GAC1C,cAAA;IAAA,IAAAE,OAAAC,OAAA,GAAAC,QAAAF,KAAAG;IAAAC,aAAAF,OAAA,MAWcH,OAAO;IAAAM,OAAAH,aACdL,MAAMtD,KAAK;IAAA8D,OAAAL,MAAAT,gBAEb3D,MAAI;KAAA,IAAC0E,OAAI;MAAA,OAAE,CAACzB,MAAM;KAAC;KAAA,IAAAc,WAAA;MAAA,OAAAJ,gBAEjBnD,MAAI;OACHmE,SAAO;OACPC,MAAI;OAAA,eAAA;OAAA,SAAA;OAAA,IAAAb,WAAA;QAAA,OAIHE,MAAMtD;OAAK;MAAA,CAAA;KAAA;IAAA,CAAA,GAAA,IAAA;IAAA8D,OAAAL,YAGfH,MAAMjD,MAAMgD,KAAKa,SAAIlB,gBACnBrD,aAAW;KAAA,aAAA;KAAA,oBAEQ6D;KAAO,IACzBzD,QAAK;MAAA,OAAEmE,KAAKnE;KAAK;KAAA,IACjBI,WAAQ;MAAA,OAAE+D,KAAK/D;KAAQ;KAAAgE,MACjBC,YAA2C;MAC/C,IAAIA,SAAS5B,SAAS6B,IAAIH,KAAKnE,OAAOqE,OAAO;WACxC5B,SAAS8B,OAAOJ,KAAKnE,KAAK;KACjC;KACAwE,eAAe;MACb,IAAIpC,MAAMpC,UAAUmE,KAAKnE,OAAOoC,MAAM1B,aAAayD,KAAKnE,KAAK;KAC/D;KAAC,KAAA,WAAA;MAAA,OACMR,GACLC,qBACAC,yBAAyB+E,MACzB,yGACAlC,MAAM,IAAI,oBAAoB,QAChC;KAAC;KAAA,IAAAc,WAAA;MAAA,OAAA,CAAAqB,WAEAP,KAAKjE,IAAI,UAAA;OAAA,IAAAyE,QAAAC,QAAA;OAAAb,OAAAY,aAC2CR,KAAKlE,KAAK;OAAA4E,aAAAC,UAAAH,OAAlDnF,GAAG,WAAW,EAAEuF,UAAU,CAACxC,MAAM,EAAE,CAAC,CAAC,CAAA;OAAA,OAAAoC;MAAA,EAAA,CAAA,CAAA;KAAA;IAAA,CAAA,CAErD,GAAC,IAAA;IAAAE,aAAAC,UAAApB,MA5CKlE,GACL,gBACA+C,MAAM,IACF,4GACA,kBACN,CAAC,CAAA;IAAA,OAAAmB;GAAA,EAAA,CAAA;EA0CP,CAAC;CAAC,EAAA,CAAA,CAAA;AAGR"}
|
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
import type { ComponentProps, JSX } from 'solid-js';
|
|
2
|
-
/**
|
|
3
|
-
* SettingsSection and SettingsRow.
|
|
4
|
-
*
|
|
5
|
-
* A settings page is the most repetitive surface in any application, and the
|
|
6
|
-
* one where drift is most visible: label sizes, control widths and description
|
|
7
|
-
* placement all wander unless something fixes them.
|
|
8
|
-
*
|
|
9
|
-
* The row puts the label and description at the start and the control at the
|
|
10
|
-
* end (stacked on a narrow window), so controls line up down the page's end
|
|
11
|
-
* edge regardless of how long the labels are. `SettingsRow` also
|
|
12
|
-
* exposes its label and description through the shared form-field context to
|
|
13
|
-
* the first control inside it. `SettingsField` is the visual stacked layout;
|
|
14
|
-
* use `FormField` when the control needs label, help, or validation wiring.
|
|
15
|
-
*/
|
|
16
2
|
export declare function SettingsSection(props: ComponentProps<'section'> & {
|
|
17
3
|
title: string;
|
|
18
4
|
description?: string;
|
|
5
|
+
/** A short explanation behind a help icon beside the title; prefer it to a long description. */
|
|
6
|
+
help?: string;
|
|
19
7
|
/** A control for the section as a whole, e.g. a master toggle. */
|
|
20
8
|
action?: JSX.Element;
|
|
21
9
|
/** Use a spaced content stack for fields, alerts, and cards instead of divided rows. */
|
|
@@ -32,6 +20,12 @@ export declare function SettingsSection(props: ComponentProps<'section'> & {
|
|
|
32
20
|
export declare function SettingsRow(props: ComponentProps<'div'> & {
|
|
33
21
|
label: string;
|
|
34
22
|
description?: string;
|
|
23
|
+
/**
|
|
24
|
+
* A short explanation behind a help icon beside the label. Prefer it to a
|
|
25
|
+
* long description: the row stays quiet and the explanation is one hover or
|
|
26
|
+
* focus away.
|
|
27
|
+
*/
|
|
28
|
+
help?: string;
|
|
35
29
|
/** Render a vertical stack when the control needs the full width. */
|
|
36
30
|
orientation?: 'horizontal' | 'vertical';
|
|
37
31
|
/** Hide the divider this row would otherwise contribute. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/settings/settings.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/settings/settings.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAsCnD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACpB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAChC,eA8CF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,eA4DF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,eAiBzF;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASxD"}
|