@rokkit/ui 1.0.0-next.124 → 1.0.0-next.127
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 +198 -101
- package/package.json +52 -34
- package/src/components/BreadCrumbs.svelte +82 -0
- package/src/components/Button.svelte +87 -0
- package/src/components/ButtonGroup.svelte +18 -0
- package/src/components/Card.svelte +61 -0
- package/src/components/Carousel.svelte +169 -0
- package/src/components/Code.svelte +185 -0
- package/src/components/Connector.svelte +46 -0
- package/src/components/FloatingAction.svelte +331 -0
- package/src/components/FloatingNavigation.svelte +228 -0
- package/src/components/ItemContent.svelte +24 -0
- package/src/components/List.svelte +476 -0
- package/src/components/Menu.svelte +421 -0
- package/src/components/MultiSelect.svelte +521 -0
- package/src/components/PaletteManager.svelte +354 -0
- package/src/components/Pill.svelte +78 -0
- package/src/components/ProgressBar.svelte +31 -0
- package/src/components/Range.svelte +325 -0
- package/src/components/Rating.svelte +91 -0
- package/src/components/Reveal.svelte +58 -0
- package/src/components/SearchFilter.svelte +80 -0
- package/src/components/Select.svelte +585 -0
- package/src/{Shine.svelte → components/Shine.svelte} +29 -21
- package/src/components/Stepper.svelte +169 -0
- package/src/components/Switch.svelte +75 -0
- package/src/components/Table.svelte +243 -0
- package/src/components/Tabs.svelte +268 -0
- package/src/components/Tilt.svelte +68 -0
- package/src/components/Timeline.svelte +61 -0
- package/src/components/Toggle.svelte +157 -0
- package/src/components/Toolbar.svelte +307 -0
- package/src/components/ToolbarGroup.svelte +17 -0
- package/src/components/Tree.svelte +613 -0
- package/src/components/index.ts +33 -0
- package/src/index.ts +41 -0
- package/src/types/button.ts +83 -0
- package/src/types/code.ts +46 -0
- package/src/types/floating-action.ts +118 -0
- package/src/types/floating-navigation.ts +68 -0
- package/src/types/index.ts +53 -0
- package/src/types/item-proxy.ts +358 -0
- package/src/types/list.ts +196 -0
- package/src/types/menu.ts +195 -0
- package/src/types/palette.ts +143 -0
- package/src/types/range.ts +51 -0
- package/src/types/search-filter.ts +67 -0
- package/src/types/select.ts +206 -0
- package/src/types/switch.ts +64 -0
- package/src/types/table.ts +210 -0
- package/src/types/tabs.ts +124 -0
- package/src/types/timeline.ts +51 -0
- package/src/types/toggle.ts +109 -0
- package/src/types/toolbar.ts +164 -0
- package/src/types/tree.ts +259 -0
- package/src/utils/palette.ts +582 -0
- package/src/utils/shiki.ts +122 -0
- package/dist/constants.d.ts +0 -2
- package/dist/index.d.ts +0 -41
- package/dist/lib/fields.d.ts +0 -16
- package/dist/lib/form.d.ts +0 -95
- package/dist/lib/index.d.ts +0 -6
- package/dist/lib/layout.d.ts +0 -7
- package/dist/lib/nested.d.ts +0 -48
- package/dist/lib/schema.d.ts +0 -7
- package/dist/lib/select.d.ts +0 -8
- package/dist/lib/tree.d.ts +0 -9
- package/dist/tree/List.spec.svelte.d.ts +0 -1
- package/dist/tree/Node.spec.svelte.d.ts +0 -1
- package/dist/tree/Root.spec.svelte.d.ts +0 -1
- package/dist/types.d.ts +0 -5
- package/dist/wrappers/index.d.ts +0 -3
- package/src/Accordion.svelte +0 -118
- package/src/BreadCrumbs.svelte +0 -32
- package/src/Button.svelte +0 -57
- package/src/Calendar.svelte +0 -93
- package/src/Card.svelte +0 -45
- package/src/Carousel.svelte +0 -49
- package/src/CheckBox.svelte +0 -56
- package/src/Connector.svelte +0 -40
- package/src/DropDown.svelte +0 -68
- package/src/DropSearch.svelte +0 -37
- package/src/Fillable.svelte +0 -19
- package/src/GraphPaper.svelte +0 -43
- package/src/Icon.svelte +0 -81
- package/src/Item.svelte +0 -25
- package/src/Link.svelte +0 -21
- package/src/List.svelte +0 -89
- package/src/ListBody.svelte +0 -43
- package/src/Message.svelte +0 -11
- package/src/MultiSelect.svelte +0 -48
- package/src/NestedList.svelte +0 -78
- package/src/NestedPaginator.svelte +0 -63
- package/src/Node.svelte +0 -76
- package/src/Overlay.svelte +0 -21
- package/src/PageNavigator.svelte +0 -94
- package/src/PickOne.svelte +0 -60
- package/src/Pill.svelte +0 -41
- package/src/ProgressBar.svelte +0 -21
- package/src/ProgressDots.svelte +0 -53
- package/src/RadioGroup.svelte +0 -52
- package/src/Range.svelte +0 -45
- package/src/RangeMinMax.svelte +0 -124
- package/src/RangeSlider.svelte +0 -79
- package/src/RangeTick.svelte +0 -28
- package/src/Rating.svelte +0 -95
- package/src/ResponsiveGrid.svelte +0 -88
- package/src/Scrollable.svelte +0 -7
- package/src/Select.svelte +0 -114
- package/src/Separator.svelte +0 -1
- package/src/Slider.svelte +0 -14
- package/src/SlidingColumns.svelte +0 -50
- package/src/Stage.svelte +0 -41
- package/src/Stepper.svelte +0 -66
- package/src/Summary.svelte +0 -22
- package/src/Switch.svelte +0 -106
- package/src/TableCell.svelte +0 -51
- package/src/TableHeaderCell.svelte +0 -54
- package/src/Tabs.svelte +0 -176
- package/src/Tilt.svelte +0 -66
- package/src/Toggle.svelte +0 -58
- package/src/ToggleThemeMode.svelte +0 -23
- package/src/Tree.svelte +0 -80
- package/src/TreeTable.svelte +0 -171
- package/src/ValidationReport.svelte +0 -23
- package/src/constants.js +0 -4
- package/src/index.js +0 -48
- package/src/lib/fields.js +0 -118
- package/src/lib/form.js +0 -72
- package/src/lib/index.js +0 -13
- package/src/lib/layout.js +0 -63
- package/src/lib/nested.js +0 -192
- package/src/lib/schema.js +0 -32
- package/src/lib/select.js +0 -38
- package/src/lib/tree.js +0 -22
- package/src/tree/List.spec.svelte.js +0 -84
- package/src/tree/List.svelte +0 -78
- package/src/tree/Node.spec.svelte.js +0 -104
- package/src/tree/Node.svelte +0 -80
- package/src/tree/Root.spec.svelte.js +0 -63
- package/src/tree/Root.svelte +0 -81
- package/src/types.js +0 -9
- package/src/wrappers/Category.svelte +0 -27
- package/src/wrappers/Section.svelte +0 -16
- package/src/wrappers/Wrapper.svelte +0 -12
- package/src/wrappers/index.js +0 -3
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Palette Utilities
|
|
3
|
+
*
|
|
4
|
+
* Functions for color manipulation, shade generation, and runtime palette application.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Types
|
|
9
|
+
// =============================================================================
|
|
10
|
+
|
|
11
|
+
export interface RGB {
|
|
12
|
+
r: number
|
|
13
|
+
g: number
|
|
14
|
+
b: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface HSL {
|
|
18
|
+
h: number
|
|
19
|
+
s: number
|
|
20
|
+
l: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ShadeKey = '50' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | '950'
|
|
24
|
+
|
|
25
|
+
export type Shades = Record<ShadeKey, string>
|
|
26
|
+
|
|
27
|
+
export type ColorRole =
|
|
28
|
+
| 'primary'
|
|
29
|
+
| 'secondary'
|
|
30
|
+
| 'accent'
|
|
31
|
+
| 'surface'
|
|
32
|
+
| 'success'
|
|
33
|
+
| 'warning'
|
|
34
|
+
| 'danger'
|
|
35
|
+
| 'info'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Mapping of color roles to Tailwind color names or hex values
|
|
39
|
+
*/
|
|
40
|
+
export type ColorMapping = Partial<Record<ColorRole, string>>
|
|
41
|
+
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Color Conversion Utilities
|
|
44
|
+
// =============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert hex color to RGB
|
|
48
|
+
*/
|
|
49
|
+
export function hexToRgb(hex: string): RGB {
|
|
50
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
|
51
|
+
if (!result) {
|
|
52
|
+
throw new Error(`Invalid hex color: ${hex}`)
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
r: parseInt(result[1], 16),
|
|
56
|
+
g: parseInt(result[2], 16),
|
|
57
|
+
b: parseInt(result[3], 16)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert RGB to hex color
|
|
63
|
+
*/
|
|
64
|
+
export function rgbToHex(rgb: RGB): string {
|
|
65
|
+
const toHex = (n: number) => {
|
|
66
|
+
const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)
|
|
67
|
+
return hex.length === 1 ? `0${ hex}` : hex
|
|
68
|
+
}
|
|
69
|
+
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Convert RGB to HSL
|
|
74
|
+
*/
|
|
75
|
+
export function rgbToHsl(rgb: RGB): HSL {
|
|
76
|
+
const r = rgb.r / 255
|
|
77
|
+
const g = rgb.g / 255
|
|
78
|
+
const b = rgb.b / 255
|
|
79
|
+
|
|
80
|
+
const max = Math.max(r, g, b)
|
|
81
|
+
const min = Math.min(r, g, b)
|
|
82
|
+
const l = (max + min) / 2
|
|
83
|
+
|
|
84
|
+
if (max === min) {
|
|
85
|
+
return { h: 0, s: 0, l: l * 100 }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const d = max - min
|
|
89
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
|
|
90
|
+
|
|
91
|
+
let h = 0
|
|
92
|
+
switch (max) {
|
|
93
|
+
case r:
|
|
94
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6
|
|
95
|
+
break
|
|
96
|
+
case g:
|
|
97
|
+
h = ((b - r) / d + 2) / 6
|
|
98
|
+
break
|
|
99
|
+
case b:
|
|
100
|
+
h = ((r - g) / d + 4) / 6
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { h: h * 360, s: s * 100, l: l * 100 }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Convert HSL to RGB
|
|
109
|
+
*/
|
|
110
|
+
export function hslToRgb(hsl: HSL): RGB {
|
|
111
|
+
const h = hsl.h / 360
|
|
112
|
+
const s = hsl.s / 100
|
|
113
|
+
const l = hsl.l / 100
|
|
114
|
+
|
|
115
|
+
if (s === 0) {
|
|
116
|
+
const val = Math.round(l * 255)
|
|
117
|
+
return { r: val, g: val, b: val }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const hue2rgb = (p: number, q: number, t: number) => {
|
|
121
|
+
if (t < 0) t += 1
|
|
122
|
+
if (t > 1) t -= 1
|
|
123
|
+
if (t < 1 / 6) return p + (q - p) * 6 * t
|
|
124
|
+
if (t < 1 / 2) return q
|
|
125
|
+
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6
|
|
126
|
+
return p
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s
|
|
130
|
+
const p = 2 * l - q
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),
|
|
134
|
+
g: Math.round(hue2rgb(p, q, h) * 255),
|
|
135
|
+
b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Convert hex to HSL
|
|
141
|
+
*/
|
|
142
|
+
export function hexToHsl(hex: string): HSL {
|
|
143
|
+
return rgbToHsl(hexToRgb(hex))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Convert HSL to hex
|
|
148
|
+
*/
|
|
149
|
+
export function hslToHex(hsl: HSL): string {
|
|
150
|
+
return rgbToHex(hslToRgb(hsl))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// =============================================================================
|
|
154
|
+
// Shade Generation
|
|
155
|
+
// =============================================================================
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Generate Tailwind-like shades from a base hex color
|
|
159
|
+
* The input color is used as the 500 shade
|
|
160
|
+
*/
|
|
161
|
+
export function generateShades(hex: string): Shades {
|
|
162
|
+
const hsl = hexToHsl(hex)
|
|
163
|
+
|
|
164
|
+
// Shade configuration: [saturation multiplier, target lightness]
|
|
165
|
+
// Lighter shades have higher lightness, lower saturation
|
|
166
|
+
// Darker shades have lower lightness, slightly higher saturation
|
|
167
|
+
const shadeConfig: Record<ShadeKey, [number, number]> = {
|
|
168
|
+
'50': [0.9, 97],
|
|
169
|
+
'100': [0.92, 94],
|
|
170
|
+
'200': [0.94, 86],
|
|
171
|
+
'300': [0.96, 75],
|
|
172
|
+
'400': [0.98, 60],
|
|
173
|
+
'500': [1.0, hsl.l], // Keep original lightness
|
|
174
|
+
'600': [1.02, Math.max(hsl.l * 0.82, 25)],
|
|
175
|
+
'700': [1.04, Math.max(hsl.l * 0.65, 20)],
|
|
176
|
+
'800': [1.06, Math.max(hsl.l * 0.50, 15)],
|
|
177
|
+
'900': [1.08, Math.max(hsl.l * 0.35, 12)],
|
|
178
|
+
'950': [1.12, Math.max(hsl.l * 0.22, 8)]
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const shades: Partial<Shades> = {}
|
|
182
|
+
|
|
183
|
+
for (const [shade, [satMult, lightness]] of Object.entries(shadeConfig)) {
|
|
184
|
+
const newHsl: HSL = {
|
|
185
|
+
h: hsl.h,
|
|
186
|
+
s: Math.min(100, hsl.s * satMult),
|
|
187
|
+
l: lightness
|
|
188
|
+
}
|
|
189
|
+
shades[shade as ShadeKey] = hslToHex(newHsl)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return shades as Shades
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Check if a string is a valid hex color
|
|
197
|
+
*/
|
|
198
|
+
export function isHexColor(value: string): boolean {
|
|
199
|
+
return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// =============================================================================
|
|
203
|
+
// Tailwind Colors (Built-in Presets)
|
|
204
|
+
// =============================================================================
|
|
205
|
+
|
|
206
|
+
export const tailwindColors: Record<string, Shades> = {
|
|
207
|
+
slate: {
|
|
208
|
+
'50': '#f8fafc',
|
|
209
|
+
'100': '#f1f5f9',
|
|
210
|
+
'200': '#e2e8f0',
|
|
211
|
+
'300': '#cbd5e1',
|
|
212
|
+
'400': '#94a3b8',
|
|
213
|
+
'500': '#64748b',
|
|
214
|
+
'600': '#475569',
|
|
215
|
+
'700': '#334155',
|
|
216
|
+
'800': '#1e293b',
|
|
217
|
+
'900': '#0f172a',
|
|
218
|
+
'950': '#020617'
|
|
219
|
+
},
|
|
220
|
+
gray: {
|
|
221
|
+
'50': '#f9fafb',
|
|
222
|
+
'100': '#f3f4f6',
|
|
223
|
+
'200': '#e5e7eb',
|
|
224
|
+
'300': '#d1d5db',
|
|
225
|
+
'400': '#9ca3af',
|
|
226
|
+
'500': '#6b7280',
|
|
227
|
+
'600': '#4b5563',
|
|
228
|
+
'700': '#374151',
|
|
229
|
+
'800': '#1f2937',
|
|
230
|
+
'900': '#111827',
|
|
231
|
+
'950': '#030712'
|
|
232
|
+
},
|
|
233
|
+
zinc: {
|
|
234
|
+
'50': '#fafafa',
|
|
235
|
+
'100': '#f4f4f5',
|
|
236
|
+
'200': '#e4e4e7',
|
|
237
|
+
'300': '#d4d4d8',
|
|
238
|
+
'400': '#a1a1aa',
|
|
239
|
+
'500': '#71717a',
|
|
240
|
+
'600': '#52525b',
|
|
241
|
+
'700': '#3f3f46',
|
|
242
|
+
'800': '#27272a',
|
|
243
|
+
'900': '#18181b',
|
|
244
|
+
'950': '#09090b'
|
|
245
|
+
},
|
|
246
|
+
neutral: {
|
|
247
|
+
'50': '#fafafa',
|
|
248
|
+
'100': '#f5f5f5',
|
|
249
|
+
'200': '#e5e5e5',
|
|
250
|
+
'300': '#d4d4d4',
|
|
251
|
+
'400': '#a3a3a3',
|
|
252
|
+
'500': '#737373',
|
|
253
|
+
'600': '#525252',
|
|
254
|
+
'700': '#404040',
|
|
255
|
+
'800': '#262626',
|
|
256
|
+
'900': '#171717',
|
|
257
|
+
'950': '#0a0a0a'
|
|
258
|
+
},
|
|
259
|
+
stone: {
|
|
260
|
+
'50': '#fafaf9',
|
|
261
|
+
'100': '#f5f5f4',
|
|
262
|
+
'200': '#e7e5e4',
|
|
263
|
+
'300': '#d6d3d1',
|
|
264
|
+
'400': '#a8a29e',
|
|
265
|
+
'500': '#78716c',
|
|
266
|
+
'600': '#57534e',
|
|
267
|
+
'700': '#44403c',
|
|
268
|
+
'800': '#292524',
|
|
269
|
+
'900': '#1c1917',
|
|
270
|
+
'950': '#0c0a09'
|
|
271
|
+
},
|
|
272
|
+
red: {
|
|
273
|
+
'50': '#fef2f2',
|
|
274
|
+
'100': '#fee2e2',
|
|
275
|
+
'200': '#fecaca',
|
|
276
|
+
'300': '#fca5a5',
|
|
277
|
+
'400': '#f87171',
|
|
278
|
+
'500': '#ef4444',
|
|
279
|
+
'600': '#dc2626',
|
|
280
|
+
'700': '#b91c1c',
|
|
281
|
+
'800': '#991b1b',
|
|
282
|
+
'900': '#7f1d1d',
|
|
283
|
+
'950': '#450a0a'
|
|
284
|
+
},
|
|
285
|
+
orange: {
|
|
286
|
+
'50': '#fff7ed',
|
|
287
|
+
'100': '#ffedd5',
|
|
288
|
+
'200': '#fed7aa',
|
|
289
|
+
'300': '#fdba74',
|
|
290
|
+
'400': '#fb923c',
|
|
291
|
+
'500': '#f97316',
|
|
292
|
+
'600': '#ea580c',
|
|
293
|
+
'700': '#c2410c',
|
|
294
|
+
'800': '#9a3412',
|
|
295
|
+
'900': '#7c2d12',
|
|
296
|
+
'950': '#431407'
|
|
297
|
+
},
|
|
298
|
+
amber: {
|
|
299
|
+
'50': '#fffbeb',
|
|
300
|
+
'100': '#fef3c7',
|
|
301
|
+
'200': '#fde68a',
|
|
302
|
+
'300': '#fcd34d',
|
|
303
|
+
'400': '#fbbf24',
|
|
304
|
+
'500': '#f59e0b',
|
|
305
|
+
'600': '#d97706',
|
|
306
|
+
'700': '#b45309',
|
|
307
|
+
'800': '#92400e',
|
|
308
|
+
'900': '#78350f',
|
|
309
|
+
'950': '#451a03'
|
|
310
|
+
},
|
|
311
|
+
yellow: {
|
|
312
|
+
'50': '#fefce8',
|
|
313
|
+
'100': '#fef9c3',
|
|
314
|
+
'200': '#fef08a',
|
|
315
|
+
'300': '#fde047',
|
|
316
|
+
'400': '#facc15',
|
|
317
|
+
'500': '#eab308',
|
|
318
|
+
'600': '#ca8a04',
|
|
319
|
+
'700': '#a16207',
|
|
320
|
+
'800': '#854d0e',
|
|
321
|
+
'900': '#713f12',
|
|
322
|
+
'950': '#422006'
|
|
323
|
+
},
|
|
324
|
+
lime: {
|
|
325
|
+
'50': '#f7fee7',
|
|
326
|
+
'100': '#ecfccb',
|
|
327
|
+
'200': '#d9f99d',
|
|
328
|
+
'300': '#bef264',
|
|
329
|
+
'400': '#a3e635',
|
|
330
|
+
'500': '#84cc16',
|
|
331
|
+
'600': '#65a30d',
|
|
332
|
+
'700': '#4d7c0f',
|
|
333
|
+
'800': '#3f6212',
|
|
334
|
+
'900': '#365314',
|
|
335
|
+
'950': '#1a2e05'
|
|
336
|
+
},
|
|
337
|
+
green: {
|
|
338
|
+
'50': '#f0fdf4',
|
|
339
|
+
'100': '#dcfce7',
|
|
340
|
+
'200': '#bbf7d0',
|
|
341
|
+
'300': '#86efac',
|
|
342
|
+
'400': '#4ade80',
|
|
343
|
+
'500': '#22c55e',
|
|
344
|
+
'600': '#16a34a',
|
|
345
|
+
'700': '#15803d',
|
|
346
|
+
'800': '#166534',
|
|
347
|
+
'900': '#14532d',
|
|
348
|
+
'950': '#052e16'
|
|
349
|
+
},
|
|
350
|
+
emerald: {
|
|
351
|
+
'50': '#ecfdf5',
|
|
352
|
+
'100': '#d1fae5',
|
|
353
|
+
'200': '#a7f3d0',
|
|
354
|
+
'300': '#6ee7b7',
|
|
355
|
+
'400': '#34d399',
|
|
356
|
+
'500': '#10b981',
|
|
357
|
+
'600': '#059669',
|
|
358
|
+
'700': '#047857',
|
|
359
|
+
'800': '#065f46',
|
|
360
|
+
'900': '#064e3b',
|
|
361
|
+
'950': '#022c22'
|
|
362
|
+
},
|
|
363
|
+
teal: {
|
|
364
|
+
'50': '#f0fdfa',
|
|
365
|
+
'100': '#ccfbf1',
|
|
366
|
+
'200': '#99f6e4',
|
|
367
|
+
'300': '#5eead4',
|
|
368
|
+
'400': '#2dd4bf',
|
|
369
|
+
'500': '#14b8a6',
|
|
370
|
+
'600': '#0d9488',
|
|
371
|
+
'700': '#0f766e',
|
|
372
|
+
'800': '#115e59',
|
|
373
|
+
'900': '#134e4a',
|
|
374
|
+
'950': '#042f2e'
|
|
375
|
+
},
|
|
376
|
+
cyan: {
|
|
377
|
+
'50': '#ecfeff',
|
|
378
|
+
'100': '#cffafe',
|
|
379
|
+
'200': '#a5f3fc',
|
|
380
|
+
'300': '#67e8f9',
|
|
381
|
+
'400': '#22d3ee',
|
|
382
|
+
'500': '#06b6d4',
|
|
383
|
+
'600': '#0891b2',
|
|
384
|
+
'700': '#0e7490',
|
|
385
|
+
'800': '#155e75',
|
|
386
|
+
'900': '#164e63',
|
|
387
|
+
'950': '#083344'
|
|
388
|
+
},
|
|
389
|
+
sky: {
|
|
390
|
+
'50': '#f0f9ff',
|
|
391
|
+
'100': '#e0f2fe',
|
|
392
|
+
'200': '#bae6fd',
|
|
393
|
+
'300': '#7dd3fc',
|
|
394
|
+
'400': '#38bdf8',
|
|
395
|
+
'500': '#0ea5e9',
|
|
396
|
+
'600': '#0284c7',
|
|
397
|
+
'700': '#0369a1',
|
|
398
|
+
'800': '#075985',
|
|
399
|
+
'900': '#0c4a6e',
|
|
400
|
+
'950': '#082f49'
|
|
401
|
+
},
|
|
402
|
+
blue: {
|
|
403
|
+
'50': '#eff6ff',
|
|
404
|
+
'100': '#dbeafe',
|
|
405
|
+
'200': '#bfdbfe',
|
|
406
|
+
'300': '#93c5fd',
|
|
407
|
+
'400': '#60a5fa',
|
|
408
|
+
'500': '#3b82f6',
|
|
409
|
+
'600': '#2563eb',
|
|
410
|
+
'700': '#1d4ed8',
|
|
411
|
+
'800': '#1e40af',
|
|
412
|
+
'900': '#1e3a8a',
|
|
413
|
+
'950': '#172554'
|
|
414
|
+
},
|
|
415
|
+
indigo: {
|
|
416
|
+
'50': '#eef2ff',
|
|
417
|
+
'100': '#e0e7ff',
|
|
418
|
+
'200': '#c7d2fe',
|
|
419
|
+
'300': '#a5b4fc',
|
|
420
|
+
'400': '#818cf8',
|
|
421
|
+
'500': '#6366f1',
|
|
422
|
+
'600': '#4f46e5',
|
|
423
|
+
'700': '#4338ca',
|
|
424
|
+
'800': '#3730a3',
|
|
425
|
+
'900': '#312e81',
|
|
426
|
+
'950': '#1e1b4b'
|
|
427
|
+
},
|
|
428
|
+
violet: {
|
|
429
|
+
'50': '#f5f3ff',
|
|
430
|
+
'100': '#ede9fe',
|
|
431
|
+
'200': '#ddd6fe',
|
|
432
|
+
'300': '#c4b5fd',
|
|
433
|
+
'400': '#a78bfa',
|
|
434
|
+
'500': '#8b5cf6',
|
|
435
|
+
'600': '#7c3aed',
|
|
436
|
+
'700': '#6d28d9',
|
|
437
|
+
'800': '#5b21b6',
|
|
438
|
+
'900': '#4c1d95',
|
|
439
|
+
'950': '#2e1065'
|
|
440
|
+
},
|
|
441
|
+
purple: {
|
|
442
|
+
'50': '#faf5ff',
|
|
443
|
+
'100': '#f3e8ff',
|
|
444
|
+
'200': '#e9d5ff',
|
|
445
|
+
'300': '#d8b4fe',
|
|
446
|
+
'400': '#c084fc',
|
|
447
|
+
'500': '#a855f7',
|
|
448
|
+
'600': '#9333ea',
|
|
449
|
+
'700': '#7e22ce',
|
|
450
|
+
'800': '#6b21a8',
|
|
451
|
+
'900': '#581c87',
|
|
452
|
+
'950': '#3b0764'
|
|
453
|
+
},
|
|
454
|
+
fuchsia: {
|
|
455
|
+
'50': '#fdf4ff',
|
|
456
|
+
'100': '#fae8ff',
|
|
457
|
+
'200': '#f5d0fe',
|
|
458
|
+
'300': '#f0abfc',
|
|
459
|
+
'400': '#e879f9',
|
|
460
|
+
'500': '#d946ef',
|
|
461
|
+
'600': '#c026d3',
|
|
462
|
+
'700': '#a21caf',
|
|
463
|
+
'800': '#86198f',
|
|
464
|
+
'900': '#701a75',
|
|
465
|
+
'950': '#4a044e'
|
|
466
|
+
},
|
|
467
|
+
pink: {
|
|
468
|
+
'50': '#fdf2f8',
|
|
469
|
+
'100': '#fce7f3',
|
|
470
|
+
'200': '#fbcfe8',
|
|
471
|
+
'300': '#f9a8d4',
|
|
472
|
+
'400': '#f472b6',
|
|
473
|
+
'500': '#ec4899',
|
|
474
|
+
'600': '#db2777',
|
|
475
|
+
'700': '#be185d',
|
|
476
|
+
'800': '#9d174d',
|
|
477
|
+
'900': '#831843',
|
|
478
|
+
'950': '#500724'
|
|
479
|
+
},
|
|
480
|
+
rose: {
|
|
481
|
+
'50': '#fff1f2',
|
|
482
|
+
'100': '#ffe4e6',
|
|
483
|
+
'200': '#fecdd3',
|
|
484
|
+
'300': '#fda4af',
|
|
485
|
+
'400': '#fb7185',
|
|
486
|
+
'500': '#f43f5e',
|
|
487
|
+
'600': '#e11d48',
|
|
488
|
+
'700': '#be123c',
|
|
489
|
+
'800': '#9f1239',
|
|
490
|
+
'900': '#881337',
|
|
491
|
+
'950': '#4c0519'
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Get shades for a color (either Tailwind preset or custom hex)
|
|
497
|
+
*/
|
|
498
|
+
export function getShades(color: string): Shades {
|
|
499
|
+
if (isHexColor(color)) {
|
|
500
|
+
return generateShades(color)
|
|
501
|
+
}
|
|
502
|
+
const preset = tailwindColors[color.toLowerCase()]
|
|
503
|
+
if (preset) {
|
|
504
|
+
return preset
|
|
505
|
+
}
|
|
506
|
+
throw new Error(`Unknown color: ${color}. Must be a hex color or Tailwind color name.`)
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// =============================================================================
|
|
510
|
+
// Runtime Palette Application
|
|
511
|
+
// =============================================================================
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Apply a color palette to the document root
|
|
515
|
+
* Sets CSS variables for each color role and shade
|
|
516
|
+
*/
|
|
517
|
+
export function applyPalette(
|
|
518
|
+
mapping: Partial<Record<ColorRole, string>>,
|
|
519
|
+
element: HTMLElement = document.documentElement
|
|
520
|
+
): void {
|
|
521
|
+
for (const [role, color] of Object.entries(mapping)) {
|
|
522
|
+
if (!color) continue
|
|
523
|
+
|
|
524
|
+
const shades = getShades(color)
|
|
525
|
+
|
|
526
|
+
for (const [shade, hex] of Object.entries(shades)) {
|
|
527
|
+
const rgb = hexToRgb(hex)
|
|
528
|
+
// Store as RGB values (comma-separated) for rgba() compatibility
|
|
529
|
+
element.style.setProperty(`--color-${role}-${shade}`, `${rgb.r},${rgb.g},${rgb.b}`)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Also set the default (500) as the base color variable
|
|
533
|
+
const baseRgb = hexToRgb(shades['500'])
|
|
534
|
+
element.style.setProperty(`--color-${role}`, `${baseRgb.r},${baseRgb.g},${baseRgb.b}`)
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Remove custom palette CSS variables (reset to theme defaults)
|
|
540
|
+
*/
|
|
541
|
+
export function resetPalette(
|
|
542
|
+
roles: ColorRole[] = ['primary', 'secondary', 'accent', 'surface', 'success', 'warning', 'danger', 'info'],
|
|
543
|
+
element: HTMLElement = document.documentElement
|
|
544
|
+
): void {
|
|
545
|
+
const shadeKeys: ShadeKey[] = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', '950']
|
|
546
|
+
|
|
547
|
+
for (const role of roles) {
|
|
548
|
+
element.style.removeProperty(`--color-${role}`)
|
|
549
|
+
for (const shade of shadeKeys) {
|
|
550
|
+
element.style.removeProperty(`--color-${role}-${shade}`)
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Save palette to localStorage
|
|
557
|
+
*/
|
|
558
|
+
export function savePalette(key: string, mapping: Partial<Record<ColorRole, string>>): void {
|
|
559
|
+
localStorage.setItem(key, JSON.stringify(mapping))
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Load palette from localStorage
|
|
564
|
+
*/
|
|
565
|
+
export function loadPalette(key: string): Partial<Record<ColorRole, string>> | null {
|
|
566
|
+
const stored = localStorage.getItem(key)
|
|
567
|
+
if (stored) {
|
|
568
|
+
try {
|
|
569
|
+
return JSON.parse(stored)
|
|
570
|
+
} catch {
|
|
571
|
+
return null
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return null
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Get list of available Tailwind color names
|
|
579
|
+
*/
|
|
580
|
+
export function getTailwindColorNames(): string[] {
|
|
581
|
+
return Object.keys(tailwindColors)
|
|
582
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shiki syntax highlighting utility
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createHighlighter, type Highlighter, type BundledLanguage, type BundledTheme } from 'shiki'
|
|
6
|
+
|
|
7
|
+
let highlighter: Highlighter | null = null
|
|
8
|
+
let isInitializing = false
|
|
9
|
+
let initPromise: Promise<Highlighter> | null = null
|
|
10
|
+
|
|
11
|
+
// Supported languages for the application
|
|
12
|
+
const SUPPORTED_LANGUAGES: BundledLanguage[] = [
|
|
13
|
+
'svelte',
|
|
14
|
+
'javascript',
|
|
15
|
+
'typescript',
|
|
16
|
+
'css',
|
|
17
|
+
'html',
|
|
18
|
+
'json',
|
|
19
|
+
'bash',
|
|
20
|
+
'shell',
|
|
21
|
+
'markdown',
|
|
22
|
+
'yaml',
|
|
23
|
+
'sql'
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
// Available themes
|
|
27
|
+
const THEMES: BundledTheme[] = ['github-light', 'github-dark']
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Initialize Shiki highlighter (singleton)
|
|
31
|
+
*/
|
|
32
|
+
function initializeHighlighter(): Promise<Highlighter> {
|
|
33
|
+
if (highlighter) return Promise.resolve(highlighter)
|
|
34
|
+
|
|
35
|
+
if (isInitializing && initPromise) {
|
|
36
|
+
return initPromise
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
isInitializing = true
|
|
40
|
+
|
|
41
|
+
initPromise = createHighlighter({
|
|
42
|
+
themes: THEMES,
|
|
43
|
+
langs: SUPPORTED_LANGUAGES
|
|
44
|
+
})
|
|
45
|
+
.then((hl: Highlighter) => {
|
|
46
|
+
highlighter = hl
|
|
47
|
+
isInitializing = false
|
|
48
|
+
return hl
|
|
49
|
+
})
|
|
50
|
+
.catch((error: Error) => {
|
|
51
|
+
isInitializing = false
|
|
52
|
+
initPromise = null
|
|
53
|
+
throw error
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
return initPromise
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface HighlightOptions {
|
|
60
|
+
/** Language for syntax highlighting */
|
|
61
|
+
lang?: BundledLanguage | string
|
|
62
|
+
/** Theme to use (defaults based on user preference) */
|
|
63
|
+
theme?: BundledTheme | 'light' | 'dark'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Highlight code using Shiki
|
|
68
|
+
*
|
|
69
|
+
* @param code - The code to highlight
|
|
70
|
+
* @param options - Highlighting options
|
|
71
|
+
* @returns The highlighted code as HTML
|
|
72
|
+
*/
|
|
73
|
+
export async function highlightCode(code: string, options: HighlightOptions = {}): Promise<string> {
|
|
74
|
+
if (!code || typeof code !== 'string') {
|
|
75
|
+
throw new Error('Invalid code provided for highlighting')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const hl = await initializeHighlighter()
|
|
79
|
+
const lang = (options.lang || 'text') as BundledLanguage
|
|
80
|
+
let theme: BundledTheme = 'github-dark'
|
|
81
|
+
|
|
82
|
+
if (options.theme === 'light') {
|
|
83
|
+
theme = 'github-light'
|
|
84
|
+
} else if (options.theme === 'dark') {
|
|
85
|
+
theme = 'github-dark'
|
|
86
|
+
} else if (options.theme) {
|
|
87
|
+
theme = options.theme
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Check if language is supported, fallback to text
|
|
91
|
+
const loadedLangs = hl.getLoadedLanguages()
|
|
92
|
+
const effectiveLang = loadedLangs.includes(lang) ? lang : 'text'
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
hl
|
|
96
|
+
.codeToHtml(code, {
|
|
97
|
+
lang: effectiveLang,
|
|
98
|
+
theme
|
|
99
|
+
})
|
|
100
|
+
// Remove inline styles from pre tag to allow CSS theming
|
|
101
|
+
.replace(/(<pre[^>]+) style="[^"]*"/, '$1')
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Preload the syntax highlighter for faster initial rendering
|
|
107
|
+
* Errors are silently ignored since preloading is optional
|
|
108
|
+
*/
|
|
109
|
+
export async function preloadHighlighter(): Promise<void> {
|
|
110
|
+
try {
|
|
111
|
+
await initializeHighlighter()
|
|
112
|
+
} catch {
|
|
113
|
+
// Preload failures are non-critical - highlighting will still work on demand
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get list of supported languages
|
|
119
|
+
*/
|
|
120
|
+
export function getSupportedLanguages(): readonly string[] {
|
|
121
|
+
return SUPPORTED_LANGUAGES
|
|
122
|
+
}
|
package/dist/constants.d.ts
DELETED