@placeholderco/placeholder-ui 2.6.6 → 2.7.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.
Files changed (36) hide show
  1. package/README.md +58 -10
  2. package/dist/app.css +70 -37
  3. package/dist/cards/GitCard.svelte +1 -1
  4. package/dist/display/Avatar.svelte +2 -2
  5. package/dist/display/LinkCollection.svelte +1 -1
  6. package/dist/display/Paper.svelte +8 -0
  7. package/dist/display/alert/Alert.svelte +1 -1
  8. package/dist/display/filetree/FileTreeItem.svelte +1 -1
  9. package/dist/editors/tiptap/LinkActionMenu.svelte +11 -6
  10. package/dist/editors/tiptap/TipTap.svelte +3 -3
  11. package/dist/editors/tiptap/TipTapBubble.svelte +5 -5
  12. package/dist/editors/tiptap/buttonLink.d.ts +1 -1
  13. package/dist/editors/tiptap/buttonLink.js +3 -1
  14. package/dist/editors/tiptap/toolbar/AlertButton.svelte +2 -2
  15. package/dist/editors/tiptap/toolbar/ButtonLinkButton.svelte +5 -3
  16. package/dist/editors/tiptap/toolbar/ColorButton.svelte +6 -6
  17. package/dist/editors/tiptap/toolbar/LinkButton.svelte +9 -9
  18. package/dist/editors/tiptap/toolbar/TableButton.svelte +2 -2
  19. package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +3 -3
  20. package/dist/form/CronBuilder.svelte +3 -3
  21. package/dist/form/DatePicker.svelte +8 -8
  22. package/dist/form/DateRangePicker.svelte +9 -9
  23. package/dist/form/DateTimePicker.svelte +8 -8
  24. package/dist/layout/Navbar.svelte +5 -5
  25. package/dist/layout/NavbarItemView.svelte +4 -4
  26. package/dist/ui/AccordionItem.svelte +20 -14
  27. package/dist/ui/Badge.svelte +69 -41
  28. package/dist/ui/Button.svelte +69 -52
  29. package/dist/ui/ButtonVariant.d.ts +1 -1
  30. package/dist/ui/Dropdown.svelte +1 -1
  31. package/dist/ui/Loader.svelte +1 -1
  32. package/dist/ui/ProgressBar.svelte +3 -3
  33. package/dist/ui/Tabs.svelte +1 -1
  34. package/dist/uiTheme.svelte.d.ts +39 -25
  35. package/dist/uiTheme.svelte.js +39 -45
  36. package/package.json +7 -7
@@ -145,12 +145,14 @@
145
145
  }
146
146
 
147
147
  .white {
148
- --button-text-color: var(--ui-primary);
148
+ --button-text-color: var(--ui-primary-text-color);
149
149
  --button-bg-color: white;
150
150
  --button-border: 0;
151
- --button-hover-bg-color: var(--ui-tertiary);
152
- --button-active-bg-color: var(--ui-tertiary-light);
153
- --button-outline-color: var(--ui-tertiary);
151
+ --button-hover-bg-color: var(--ui-accent-hover-color);
152
+ --button-hover-text-color: var(--ui-accent-contrast-color);
153
+ --button-active-bg-color: var(--ui-tertiary-pressed-color);
154
+ --button-active-text-color: var(--ui-tertiary-contrast-color);
155
+ --button-outline-color: var(--ui-focus-color);
154
156
  }
155
157
 
156
158
  .secondary {
@@ -180,13 +182,13 @@
180
182
  }
181
183
 
182
184
  .auto-subtle {
183
- --button-text-color: var(--ui-primary);
185
+ --button-text-color: var(--ui-primary-text-color);
184
186
  --button-bg-color: initial;
185
187
  --button-hover-bg-color: var(--ui-accent);
186
- --button-hover-text-color: var(--ui-primary);
188
+ --button-hover-text-color: var(--ui-accent-contrast-color);
187
189
  --button-active-bg-color: var(--ui-primary);
188
- --button-active-text-color: var(--ui-accent);
189
- --button-outline-color: var(--ui-tertiary);
190
+ --button-active-text-color: var(--ui-primary-contrast-color);
191
+ --button-outline-color: var(--ui-focus-color);
190
192
  }
191
193
 
192
194
  .danger {
@@ -197,7 +199,7 @@
197
199
 
198
200
  --button-active-bg-color: #b02a37;
199
201
 
200
- --button-outline-color: var(--ui-tertiary);
202
+ --button-outline-color: var(--ui-focus-color);
201
203
 
202
204
  :global(.loader) {
203
205
  color: white;
@@ -218,82 +220,97 @@
218
220
  }
219
221
 
220
222
  .accent {
221
- --button-text-color: var(--ui-primary);
223
+ --button-text-color: var(--ui-accent-contrast-color);
222
224
  --button-bg-color: var(--ui-accent);
223
- --button-hover-bg-color: var(--ui-tertiary);
224
- --button-active-bg-color: var(--ui-tertiary-light);
225
- --button-outline-color: var(--ui-tertiary);
225
+ --button-hover-bg-color: var(--ui-accent-hover-color);
226
+ --button-active-bg-color: var(--ui-accent-pressed-color);
227
+ --button-outline-color: var(--ui-focus-color);
226
228
  }
227
229
 
228
230
  .accent-outline {
229
- --button-text-color: var(--ui-accent);
231
+ --button-text-color: var(--ui-accent-text-color);
230
232
  --button-bg-color: initial;
231
- --button-border: 1px solid var(--ui-accent);
232
- --button-hover-text-color: var(--ui-tertiary);
233
- --button-hover-border: 1px solid var(--ui-tertiary);
234
- --button-active-text-color: var(--ui-tertiary-light);
235
- --button-active-border: 1px solid var(--ui-tertiary-light);
236
- --button-outline-color: var(--ui-tertiary);
233
+ --button-border: 1px solid var(--ui-accent-text-color);
234
+ --button-hover-text-color: var(--ui-accent-hover-color);
235
+ --button-hover-border: 1px solid var(--ui-accent-hover-color);
236
+ --button-active-text-color: var(--ui-accent-pressed-color);
237
+ --button-active-border: 1px solid var(--ui-accent-pressed-color);
238
+ --button-outline-color: var(--ui-focus-color);
237
239
  }
238
240
 
239
241
  .accent-subtle {
240
- --button-text-color: var(--ui-accent);
242
+ --button-text-color: var(--ui-accent-text-color);
241
243
  --button-bg-color: initial;
242
- --button-hover-text-color: var(--ui-primary);
243
- --button-hover-bg-color: var(--ui-accent);
244
- --button-active-text-color: white;
245
- --button-active-bg-color: var(--ui-accent-dark);
246
- --button-outline-color: var(--ui-tertiary);
244
+ --button-hover-text-color: var(--ui-accent-contrast-color);
245
+ --button-hover-bg-color: var(--ui-accent-hover-color);
246
+ --button-active-text-color: var(--ui-accent-contrast-color);
247
+ --button-active-bg-color: var(--ui-accent-pressed-color);
248
+ --button-outline-color: var(--ui-focus-color);
247
249
  }
248
250
 
249
251
  .primary {
250
252
  --button-bg-color: var(--ui-primary);
251
- --button-text-color: white;
252
- --button-hover-bg-color: var(--ui-accent-dark);
253
- --button-active-bg-color: var(--ui-primary-dark);
253
+ --button-text-color: var(--ui-primary-contrast-color);
254
+ --button-hover-bg-color: var(--ui-primary-hover-color);
255
+ --button-active-bg-color: var(--ui-primary-pressed-color);
254
256
  }
255
257
 
256
258
  .primary-outline {
257
- --button-text-color: var(--ui-primary);
259
+ --button-text-color: var(--ui-primary-text-color);
258
260
  --button-bg-color: initial;
259
- --button-border: 1px solid var(--ui-primary);
260
- --button-hover-text-color: var(--ui-accent-dark);
261
- --button-hover-border: 1px solid var(--ui-accent-dark);
262
- --button-active-text-color: var(--ui-primary-dark);
263
- --button-active-border: 1px solid var(--ui-primary-dark);
261
+ --button-border: 1px solid var(--ui-primary-text-color);
262
+ --button-hover-text-color: var(--ui-primary-hover-color);
263
+ --button-hover-border: 1px solid var(--ui-primary-hover-color);
264
+ --button-active-text-color: var(--ui-primary-pressed-color);
265
+ --button-active-border: 1px solid var(--ui-primary-pressed-color);
264
266
  }
265
267
 
266
268
  .primary-subtle {
267
- --button-text-color: var(--ui-primary);
269
+ --button-text-color: var(--ui-primary-text-color);
268
270
  --button-bg-color: initial;
269
- --button-hover-text-color: white;
270
- --button-hover-bg-color: var(--ui-primary);
271
- --button-active-text-color: white;
272
- --button-active-bg-color: var(--ui-primary-dark);
271
+ --button-hover-text-color: var(--ui-primary-contrast-color);
272
+ --button-hover-bg-color: var(--ui-primary-hover-color);
273
+ --button-active-text-color: var(--ui-primary-contrast-color);
274
+ --button-active-bg-color: var(--ui-primary-pressed-color);
273
275
  }
274
276
 
275
277
  .tertiary {
276
- --button-text-color: var(--ui-primary);
278
+ --button-text-color: var(--ui-tertiary-contrast-color);
277
279
  --button-bg-color: var(--ui-tertiary);
278
- --button-hover-bg-color: var(--ui-accent);
279
- --button-active-bg-color: var(--ui-tertiary-light);
280
- --button-outline-color: var(--ui-accent);
280
+ --button-hover-bg-color: var(--ui-tertiary-hover-color);
281
+ --button-active-bg-color: var(--ui-tertiary-pressed-color);
282
+ --button-outline-color: var(--ui-focus-color);
283
+ }
284
+
285
+ .tertiary-outline {
286
+ --button-text-color: var(--ui-tertiary-text-color);
287
+ --button-bg-color: transparent;
288
+ --button-border: 1px solid var(--ui-tertiary-text-color);
289
+ --button-hover-text-color: var(--ui-tertiary-contrast-color);
290
+ --button-hover-bg-color: var(--ui-tertiary-hover-color);
291
+ --button-active-text-color: var(--ui-tertiary-contrast-color);
292
+ --button-active-bg-color: var(--ui-tertiary-pressed-color);
293
+ --button-outline-color: var(--ui-focus-color);
281
294
  }
282
295
 
283
296
  .tertiary-subtle {
284
297
  background-color: initial;
285
- color: var(--ui-tertiary-dark);
298
+ color: var(--ui-tertiary-text-color);
286
299
 
287
300
  &:hover:not(:disabled) {
288
- background-color: rgba(var(--ui-tertiary-dark-rgbc), 0.25);
301
+ background-color: color-mix(in srgb, var(--ui-tertiary-hover-color) 25%, transparent);
302
+ }
303
+
304
+ &:active:not(:disabled, .effects-disabled) {
305
+ background-color: color-mix(in srgb, var(--ui-tertiary-pressed-color) 25%, transparent);
289
306
  }
290
307
 
291
308
  &:focus-visible {
292
- outline-color: var(--ui-tertiary);
309
+ outline-color: var(--ui-focus-color);
293
310
  }
294
311
 
295
312
  :global(.loader) {
296
- color: var(--ui-tertiary-dark);
313
+ color: var(--ui-tertiary-text-color);
297
314
  }
298
315
  }
299
316
 
@@ -327,7 +344,7 @@
327
344
  }
328
345
 
329
346
  &:focus-visible {
330
- outline: solid 0.125rem var(--button-outline-color, var(--ui-accent-dark));
347
+ outline: solid 0.125rem var(--button-outline-color, var(--ui-focus-color));
331
348
  outline-offset: 0.125rem;
332
349
  }
333
350
 
@@ -352,11 +369,11 @@
352
369
 
353
370
  .auto-subtle {
354
371
  --button-text-color: white;
355
- --button-hover-text-color: white;
372
+ --button-hover-text-color: var(--ui-primary-contrast-color);
356
373
  --button-hover-bg-color: var(--ui-primary);
357
- --button-active-text-color: var(--ui-accent);
374
+ --button-active-text-color: var(--ui-primary-contrast-color);
358
375
  --button-active-bg-color: var(--ui-primary);
359
- --button-outline-color: var(--ui-accent);
376
+ --button-outline-color: var(--ui-focus-color);
360
377
  }
361
378
  }
362
379
 
@@ -6,4 +6,4 @@
6
6
  * - `accent` → `--ui-accent` (light brand colour)
7
7
  * - `tertiary` → `--ui-tertiary` (supporting colour)
8
8
  */
9
- export type ButtonVariant = 'white' | 'secondary' | 'secondary-subtle' | 'secondary-selected' | 'danger' | 'danger-subtle' | 'auto-subtle' | 'auto-outline' | 'primary' | 'primary-outline' | 'primary-subtle' | 'accent' | 'accent-outline' | 'accent-subtle' | 'tertiary' | 'tertiary-subtle' | 'shaded';
9
+ export type ButtonVariant = 'white' | 'secondary' | 'secondary-subtle' | 'secondary-selected' | 'danger' | 'danger-subtle' | 'auto-subtle' | 'auto-outline' | 'primary' | 'primary-outline' | 'primary-subtle' | 'accent' | 'accent-outline' | 'accent-subtle' | 'tertiary' | 'tertiary-outline' | 'tertiary-subtle' | 'shaded';
@@ -102,7 +102,7 @@
102
102
  display: block;
103
103
  padding: 8px 12px;
104
104
  text-decoration: none;
105
- color: var(--ui-primary);
105
+ color: var(--ui-primary-text-color);
106
106
  transition: background-color 0.2s ease;
107
107
  }
108
108
 
@@ -59,7 +59,7 @@
59
59
  justify-content: center;
60
60
  background-color: rgba(255, 255, 255, 0.75);
61
61
  border-radius: 0.25rem;
62
- color: var(--ui-primary);
62
+ color: var(--ui-primary-text-color);
63
63
  }
64
64
 
65
65
  :global(.dark) .full-screen {
@@ -134,17 +134,17 @@
134
134
  /* Variant colors */
135
135
  .primary {
136
136
  background-color: var(--ui-primary);
137
- color: #fff;
137
+ color: var(--ui-primary-contrast-color);
138
138
  }
139
139
 
140
140
  .accent {
141
141
  background-color: var(--ui-accent);
142
- color: var(--ui-primary);
142
+ color: var(--ui-accent-contrast-color);
143
143
  }
144
144
 
145
145
  .tertiary {
146
146
  background-color: var(--ui-tertiary);
147
- color: var(--ui-primary);
147
+ color: var(--ui-tertiary-contrast-color);
148
148
  }
149
149
 
150
150
  .danger {
@@ -112,7 +112,7 @@
112
112
  }
113
113
 
114
114
  .tab-item.selected {
115
- color: var(--ui-primary);
115
+ color: var(--ui-primary-text-color);
116
116
  }
117
117
 
118
118
  .tab-underline {
@@ -1,34 +1,48 @@
1
- /** Brand colours. Accepts `#rgb`, `#rrggbb` or `rgb(r, g, b)` strings. */
1
+ /** Brand colors. Accepts `#rgb`, `#rrggbb` or `rgb(r, g, b)` strings. */
2
2
  export interface ThemeColors {
3
- /** Dark brand colour. Used for solid buttons, headings and active states. */
3
+ /** Primary fill color for solid controls and active backgrounds. */
4
4
  primary: string;
5
- /** Darker shade of `primary` for pressed states. Derived from `primary` when omitted. */
6
- primaryDark?: string;
7
- /** Text colour on top of `primary`. Defaults to white. */
8
- primaryContrast?: string;
9
- /** Light brand colour. Used for highlights, hovers and as the dark-mode accent. */
5
+ /** Hover color for primary controls. Defaults to the accent text color. */
6
+ primaryHoverColor?: string;
7
+ /** Pressed color for primary controls. Darkened from `primary` when omitted. */
8
+ primaryPressedColor?: string;
9
+ /** Primary-colored text on page/paper surfaces and unfilled controls. Defaults to `primary`. */
10
+ primaryTextColor?: string;
11
+ /** Foreground on primary-filled controls, including hover/pressed fills. Defaults to white. */
12
+ primaryContrastColor?: string;
13
+ /** Accent fill color for solid controls and highlights. */
10
14
  accent: string;
11
- /** Darker shade of `accent`, used for hover text on light surfaces. Derived when omitted. */
12
- accentDark?: string;
13
- /** Text colour on top of `accent`. Defaults to `primary`. */
14
- accentContrast?: string;
15
- /** Light supporting colour. Defaults to `accent` when omitted. */
15
+ /** Hover color for accent controls. Defaults to `tertiary`. */
16
+ accentHoverColor?: string;
17
+ /** Pressed color for accent controls. Lightened from `tertiary` (or `accent`) when omitted. */
18
+ accentPressedColor?: string;
19
+ /** Accent-colored text on page/paper surfaces and unfilled controls. Darkened from `accent` by default. */
20
+ accentTextColor?: string;
21
+ /** Foreground on accent-filled controls, including hover/pressed fills. Defaults to `primary`. */
22
+ accentContrastColor?: string;
23
+ /** Tertiary fill color for solid controls. Defaults to `accent` when omitted. */
16
24
  tertiary?: string;
17
- /** Darker shade of `tertiary`, used for links and subtle text. Derived when omitted. */
18
- tertiaryDark?: string;
19
- /** Lighter shade of `tertiary`, used for pressed states on light buttons. Derived when omitted. */
20
- tertiaryLight?: string;
21
- /** Link colour. Defaults to `tertiaryDark`. */
25
+ /** Hover color for tertiary controls. Defaults to `accent`. */
26
+ tertiaryHoverColor?: string;
27
+ /** Pressed color for tertiary and white controls. Lightened from `tertiary` when omitted. */
28
+ tertiaryPressedColor?: string;
29
+ /** Tertiary-colored text on page/paper surfaces and unfilled controls. Darkened from `tertiary` by default. */
30
+ tertiaryTextColor?: string;
31
+ /** Foreground on tertiary-filled controls, including hover/pressed fills. Defaults to `primary`. */
32
+ tertiaryContrastColor?: string;
33
+ /** Keyboard focus ring color. Defaults to the accent text color. */
34
+ focusColor?: string;
35
+ /** Link color. Defaults to `tertiaryTextColor`. */
22
36
  link?: string;
23
- /** Link hover colour. Defaults to `accentDark`. */
37
+ /** Link hover color. Defaults to `accentTextColor`. */
24
38
  linkHover?: string;
25
39
  }
26
40
  /**
27
- * Settings that can be given per colour mode. Used as the base (light) config and,
41
+ * Settings that can be given per color mode. Used as the base (light) config and,
28
42
  * with every field optional, as the `dark` override block.
29
43
  */
30
44
  export interface ThemeModeConfig {
31
- /** Brand colours. In the `dark` block any subset may be given; shades are derived per colour. */
45
+ /** Brand colors. In the `dark` block any subset may be given; shades are derived per color. */
32
46
  colors?: Partial<ThemeColors>;
33
47
  /**
34
48
  * CSS `font-family` value applied to the whole UI, e.g. `"'Inter', system-ui, sans-serif"`.
@@ -44,7 +58,7 @@ export interface ThemeModeConfig {
44
58
  variables?: Record<string, string>;
45
59
  }
46
60
  export interface ThemeConfig extends ThemeModeConfig {
47
- /** Brand colours for light mode (and dark mode unless overridden in `dark`). */
61
+ /** Brand colors for light mode (and dark mode unless overridden in `dark`). */
48
62
  colors?: ThemeColors;
49
63
  /**
50
64
  * Overrides applied while dark mode is active (`.dark` on `<html>`). Anything not
@@ -54,7 +68,7 @@ export interface ThemeConfig extends ThemeModeConfig {
54
68
  }
55
69
  /** Reactive brand state consumed by components such as `Logo`. */
56
70
  export declare const brandState: {
57
- /** Logo for the active colour mode: the dark logo when set and dark mode is on, else the light one. */
71
+ /** Logo for the active color mode: the dark logo when set and dark mode is on, else the light one. */
58
72
  readonly logo: string | undefined;
59
73
  };
60
74
  /**
@@ -63,9 +77,9 @@ export declare const brandState: {
63
77
  */
64
78
  export declare function setLogo(svg: string | undefined, darkSvg?: string): void;
65
79
  /**
66
- * Build the `--ui-*` custom property map for one colour mode. Only the groups whose
67
- * base colour is present are emitted, so a partial `dark` block overrides just what
68
- * it names. Unknown colour formats are passed through unchanged (their `-rgb`
80
+ * Build the `--ui-*` custom property map for one color mode. Only the groups whose
81
+ * base color is present are emitted, so a partial `dark` block overrides just what
82
+ * it names. Unknown color formats are passed through unchanged (their `-rgb`
69
83
  * variants are skipped).
70
84
  */
71
85
  export declare function themeToVariables(config: ThemeModeConfig): Record<string, string>;
@@ -29,7 +29,7 @@ let lightLogo = $state(undefined);
29
29
  let darkLogo = $state(undefined);
30
30
  /** Reactive brand state consumed by components such as `Logo`. */
31
31
  export const brandState = {
32
- /** Logo for the active colour mode: the dark logo when set and dark mode is on, else the light one. */
32
+ /** Logo for the active color mode: the dark logo when set and dark mode is on, else the light one. */
33
33
  get logo() {
34
34
  return themeState.isDarkMode ? (darkLogo ?? lightLogo) : lightLogo;
35
35
  }
@@ -66,11 +66,11 @@ function toHex([r, g, b]) {
66
66
  function clamp(n) {
67
67
  return Math.min(255, Math.max(0, n));
68
68
  }
69
- /** Mix a colour towards black (`amount` 0..1). */
69
+ /** Mix a color towards black (`amount` 0..1). */
70
70
  function darken(rgb, amount) {
71
71
  return rgb.map((c) => c * (1 - amount));
72
72
  }
73
- /** Mix a colour towards white (`amount` 0..1). */
73
+ /** Mix a color towards white (`amount` 0..1). */
74
74
  function lighten(rgb, amount) {
75
75
  return rgb.map((c) => c + (255 - c) * amount);
76
76
  }
@@ -78,9 +78,9 @@ function lighten(rgb, amount) {
78
78
  // Config -> CSS variables
79
79
  // ============================================
80
80
  /**
81
- * Build the `--ui-*` custom property map for one colour mode. Only the groups whose
82
- * base colour is present are emitted, so a partial `dark` block overrides just what
83
- * it names. Unknown colour formats are passed through unchanged (their `-rgb`
81
+ * Build the `--ui-*` custom property map for one color mode. Only the groups whose
82
+ * base color is present are emitted, so a partial `dark` block overrides just what
83
+ * it names. Unknown color formats are passed through unchanged (their `-rgb`
84
84
  * variants are skipped).
85
85
  */
86
86
  export function themeToVariables(config) {
@@ -90,46 +90,50 @@ export function themeToVariables(config) {
90
90
  if (c.primary) {
91
91
  const primary = parseColor(c.primary);
92
92
  setColor(vars, 'primary', c.primary, primary);
93
- vars['--ui-primary-dark'] =
94
- c.primaryDark ?? (primary ? toHex(darken(primary, 0.35)) : c.primary);
95
- vars['--ui-primary-contrast'] = c.primaryContrast ?? '#ffffff';
96
- }
97
- else {
98
- if (c.primaryDark)
99
- vars['--ui-primary-dark'] = c.primaryDark;
100
- if (c.primaryContrast)
101
- vars['--ui-primary-contrast'] = c.primaryContrast;
93
+ vars['--ui-primary-pressed-color'] = primary ? toHex(darken(primary, 0.35)) : c.primary;
94
+ vars['--ui-primary-text-color'] = 'var(--ui-primary)';
95
+ vars['--ui-primary-contrast-color'] = '#ffffff';
102
96
  }
103
97
  if (c.accent) {
104
98
  const accent = parseColor(c.accent);
105
99
  setColor(vars, 'accent', c.accent, accent);
106
- vars['--ui-accent-dark'] = c.accentDark ?? (accent ? toHex(darken(accent, 0.5)) : c.accent);
107
- vars['--ui-accent-contrast'] = c.accentContrast ?? 'var(--ui-primary)';
108
- }
109
- else {
110
- if (c.accentDark)
111
- vars['--ui-accent-dark'] = c.accentDark;
112
- if (c.accentContrast)
113
- vars['--ui-accent-contrast'] = c.accentContrast;
100
+ vars['--ui-accent-text-color'] = accent ? toHex(darken(accent, 0.5)) : c.accent;
101
+ vars['--ui-accent-contrast-color'] = 'var(--ui-primary)';
114
102
  }
115
103
  const tertiarySource = c.tertiary ?? c.accent;
116
104
  if (tertiarySource) {
117
105
  const tertiary = parseColor(tertiarySource);
118
106
  setColor(vars, 'tertiary', tertiarySource, tertiary);
119
- setTertiaryDark(vars, c.tertiaryDark ?? (tertiary ? toHex(darken(tertiary, 0.45)) : tertiarySource));
120
- vars['--ui-tertiary-light'] =
121
- c.tertiaryLight ?? (tertiary ? toHex(lighten(tertiary, 0.5)) : tertiarySource);
107
+ vars['--ui-tertiary-text-color'] = tertiary ? toHex(darken(tertiary, 0.45)) : tertiarySource;
108
+ vars['--ui-tertiary-contrast-color'] = 'var(--ui-primary)';
109
+ const pressedColor = tertiary ? toHex(lighten(tertiary, 0.5)) : tertiarySource;
110
+ vars['--ui-accent-pressed-color'] = pressedColor;
111
+ vars['--ui-tertiary-pressed-color'] = pressedColor;
122
112
  }
123
- else {
124
- if (c.tertiaryDark)
125
- setTertiaryDark(vars, c.tertiaryDark);
126
- if (c.tertiaryLight)
127
- vars['--ui-tertiary-light'] = c.tertiaryLight;
113
+ // Explicit role overrides work independently, including in partial dark-mode configs.
114
+ // Hover defaults live in app.css so they follow the current palette without
115
+ // coupling text, borders, links or focus rings to a custom hover color.
116
+ const overrides = {
117
+ primaryHoverColor: '--ui-primary-hover-color',
118
+ primaryPressedColor: '--ui-primary-pressed-color',
119
+ primaryTextColor: '--ui-primary-text-color',
120
+ primaryContrastColor: '--ui-primary-contrast-color',
121
+ accentHoverColor: '--ui-accent-hover-color',
122
+ accentPressedColor: '--ui-accent-pressed-color',
123
+ accentTextColor: '--ui-accent-text-color',
124
+ accentContrastColor: '--ui-accent-contrast-color',
125
+ tertiaryHoverColor: '--ui-tertiary-hover-color',
126
+ tertiaryPressedColor: '--ui-tertiary-pressed-color',
127
+ tertiaryTextColor: '--ui-tertiary-text-color',
128
+ tertiaryContrastColor: '--ui-tertiary-contrast-color',
129
+ focusColor: '--ui-focus-color',
130
+ link: '--ui-link-color',
131
+ linkHover: '--ui-link-hover-color'
132
+ };
133
+ for (const key of Object.keys(overrides)) {
134
+ if (c[key])
135
+ vars[overrides[key]] = c[key];
128
136
  }
129
- if (c.link)
130
- vars['--ui-link-color'] = c.link;
131
- if (c.linkHover)
132
- vars['--ui-link-hover-color'] = c.linkHover;
133
137
  }
134
138
  if (config.fontFamily)
135
139
  vars['--ui-font-family'] = config.fontFamily;
@@ -147,16 +151,6 @@ function setColor(vars, name, raw, rgb) {
147
151
  vars[`--ui-${name}`] = raw;
148
152
  }
149
153
  }
150
- function setTertiaryDark(vars, value) {
151
- const rgb = parseColor(value);
152
- if (rgb) {
153
- vars['--ui-tertiary-dark-rgbc'] = rgb.join(', ');
154
- vars['--ui-tertiary-dark'] = 'rgb(var(--ui-tertiary-dark-rgbc))';
155
- }
156
- else {
157
- vars['--ui-tertiary-dark'] = value;
158
- }
159
- }
160
154
  function toRule(selector, vars) {
161
155
  const body = Object.entries(vars)
162
156
  .map(([k, v]) => `\t${k}: ${v};`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@placeholderco/placeholder-ui",
3
- "version": "2.6.6",
3
+ "version": "2.7.0",
4
4
  "description": "A modern, customizable Svelte 5 UI component library with comprehensive theming support. Re-brand it with a single config object.",
5
5
  "license": "MIT",
6
6
  "author": "Placeholderco",
@@ -56,20 +56,20 @@
56
56
  "@sveltejs/kit": "^2.70.3",
57
57
  "@sveltejs/package": "^2.5.8",
58
58
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
59
- "@types/node": "^26.5.1",
59
+ "@types/node": "^26.6.2",
60
60
  "globals": "^17.12.0",
61
- "prettier": "^3.9.6",
61
+ "prettier": "^3.9.8",
62
62
  "prettier-plugin-svelte": "^4.1.1",
63
63
  "publint": "^0.3.24",
64
64
  "rimraf": "^6.1.3",
65
- "svelte": "^5.57.0",
65
+ "svelte": "^5.57.1",
66
66
  "svelte-check": "^4.7.6",
67
67
  "typescript": "^6.0.3",
68
68
  "vite": "^8.3.0"
69
69
  },
70
70
  "dependencies": {
71
71
  "@codemirror/autocomplete": "^6.20.3",
72
- "@codemirror/commands": "^6.11.0",
72
+ "@codemirror/commands": "^6.11.1",
73
73
  "@codemirror/lang-css": "^6.3.1",
74
74
  "@codemirror/lang-html": "^6.4.12",
75
75
  "@codemirror/lang-javascript": "^6.2.5",
@@ -80,9 +80,9 @@
80
80
  "@codemirror/legacy-modes": "^6.5.4",
81
81
  "@codemirror/lint": "^6.9.7",
82
82
  "@codemirror/search": "^6.7.2",
83
- "@codemirror/state": "^6.7.4",
83
+ "@codemirror/state": "^6.7.5",
84
84
  "@codemirror/theme-one-dark": "^6.1.3",
85
- "@codemirror/view": "^6.43.11",
85
+ "@codemirror/view": "^6.43.12",
86
86
  "@lezer/highlight": "^1.2.3",
87
87
  "@tiptap/core": "^3.31.3",
88
88
  "@tiptap/extension-bubble-menu": "^3.31.3",