@placeholderco/placeholder-ui 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.css CHANGED
@@ -46,16 +46,6 @@
46
46
  --ui-link-color: var(--ui-tertiary-dark);
47
47
  --ui-link-hover-color: var(--ui-accent-dark);
48
48
 
49
- /* ---- Legacy aliases (deprecated, kept for backwards compatibility) ---- */
50
- --midnight-rgb: var(--ui-primary-rgb);
51
- --midnight-rgbc: var(--ui-primary-rgbc);
52
- --midnight: var(--ui-primary);
53
- --pistachio-rgb: var(--ui-accent-rgb);
54
- --pistachio-rgbc: var(--ui-accent-rgbc);
55
- --pistachio: var(--ui-accent);
56
- --pistachio-dark: var(--ui-accent-dark);
57
- --turquoise: var(--ui-tertiary);
58
- --turquoise-dark: var(--ui-tertiary-dark);
59
49
 
60
50
  /* ---- Surfaces and text (light mode) ---- */
61
51
  --off-white: rgb(221, 221, 221);
@@ -748,7 +748,7 @@
748
748
  line-height: 1.5;
749
749
  }
750
750
 
751
- /* Default variant - use pistachio theme */
751
+ /* Default variant - accent tint */
752
752
  .editor-content :global(.ProseMirror .alert-default) {
753
753
  background: rgba(var(--ui-accent-rgbc), 0.3);
754
754
  border: 1px solid var(--ui-accent);
@@ -72,7 +72,7 @@
72
72
  cursor: not-allowed;
73
73
  }
74
74
 
75
- .toolbar-button :global(.cu-icon) {
75
+ .toolbar-button :global(.pui-icon) {
76
76
  height: 19px;
77
77
  }
78
78
  </style>
@@ -316,22 +316,6 @@
316
316
  }}>{value.label}</Badge
317
317
  >
318
318
  {/if}
319
- <!-- <span class="inline-flex items-center bg-midnight text-white rounded-md px-2">
320
- {value.label}
321
- <button
322
- class="leading-0 ml-1 size-4 rounded hover:bg-neutral-400/25"
323
- {disabled}
324
- onclick={(e) => {
325
- if (disabled) return;
326
-
327
- value.selected = !value.selected;
328
- onSelection(value);
329
- open = false;
330
- e.stopPropagation();
331
- }}
332
-
333
- </button>
334
- </span> -->
335
319
  {/each}
336
320
  </div>
337
321
  {/if}
@@ -29,24 +29,24 @@
29
29
  <span
30
30
  style="--svg-stroke: {stroke}; --svg-fill: {fill}; {sizeStyle}"
31
31
  class:flip
32
- class="cu-icon {classes}"
32
+ class="pui-icon {classes}"
33
33
  >
34
34
  {@html svg}
35
35
  </span>
36
36
 
37
37
  <style>
38
- .cu-icon {
38
+ .pui-icon {
39
39
  display: inline-flex;
40
40
  align-items: center;
41
41
  justify-content: center;
42
42
  }
43
43
 
44
- .cu-icon :global(svg) {
44
+ .pui-icon :global(svg) {
45
45
  width: 100%;
46
46
  height: 100%;
47
47
  }
48
48
 
49
- .cu-icon :global(svg:not(.icons-tabler-filled)) {
49
+ .pui-icon :global(svg:not(.icons-tabler-filled)) {
50
50
  stroke: var(--svg-stroke);
51
51
  fill: var(--svg-fill);
52
52
  }
package/dist/index.d.ts CHANGED
@@ -30,7 +30,7 @@ export { default as ContextMenu } from './ui/ContextMenu.svelte';
30
30
  export type { ContextMenuProps, ContextMenuItem } from './ui/ContextMenu.svelte';
31
31
  export { default as ProgressBar } from './ui/ProgressBar.svelte';
32
32
  export type { ProgressBarProps, ProgressBarSegment } from './ui/ProgressBar.svelte';
33
- export type { ProgressBarVariant, LegacyProgressBarVariant } from './ui/ProgressBarVariant.js';
33
+ export type { ProgressBarVariant } from './ui/ProgressBarVariant.js';
34
34
  export { default as Tabs } from './ui/Tabs.svelte';
35
35
  export type { TabsProps } from './ui/Tabs.svelte';
36
36
  export { default as Table } from './ui/Table.svelte';
@@ -123,7 +123,7 @@ export { default as GitCard } from './cards/GitCard.svelte';
123
123
  export type { GitCardProps } from './cards/GitCard.svelte';
124
124
  export * from './icon/index.js';
125
125
  export type { IconProps } from './icon/Icon.svelte';
126
- export type { ButtonVariant, LegacyButtonVariant } from './ui/ButtonVariant.js';
126
+ export type { ButtonVariant } from './ui/ButtonVariant.js';
127
127
  export type { ButtonSize } from './ui/ButtonSize.js';
128
128
  export type { Hyperlink } from './models/Hyperlink.js';
129
129
  export type { LinkCollectionItem } from './models/LinkCollectionItem.js';
@@ -12,8 +12,7 @@
12
12
  import Logo from '../ui/Logo.svelte';
13
13
  import type { Snippet } from 'svelte';
14
14
 
15
- /** `midnight` is a legacy alias for `primary`. */
16
- export type NavbarVariant = 'default' | 'primary' | 'midnight';
15
+ export type NavbarVariant = 'default' | 'primary';
17
16
 
18
17
  export interface NavbarProps {
19
18
  /** Visual variant. `primary` uses the primary brand colour as the background across all themes */
@@ -67,7 +66,7 @@
67
66
  onDrawerButtonClick = undefined
68
67
  }: NavbarProps = $props();
69
68
 
70
- const isPrimary = $derived(variant === 'primary' || variant === 'midnight');
69
+ const isPrimary = $derived(variant === 'primary');
71
70
  </script>
72
71
 
73
72
  <header class={isPrimary ? 'primary' : ''}>
@@ -254,7 +253,7 @@
254
253
  height: 1.5rem;
255
254
  }
256
255
 
257
- .inner-navbar :global(.cu-icon) {
256
+ .inner-navbar :global(.pui-icon) {
258
257
  display: flex;
259
258
  }
260
259
 
@@ -1,8 +1,7 @@
1
1
  import type { NavbarItem } from '../models/NavbarItem.js';
2
2
  import { type Hyperlink } from '../index.js';
3
3
  import type { Snippet } from 'svelte';
4
- /** `midnight` is a legacy alias for `primary`. */
5
- export type NavbarVariant = 'default' | 'primary' | 'midnight';
4
+ export type NavbarVariant = 'default' | 'primary';
6
5
  export interface NavbarProps {
7
6
  /** Visual variant. `primary` uses the primary brand colour as the background across all themes */
8
7
  variant?: NavbarVariant;
@@ -219,52 +219,44 @@
219
219
  --accordion-open-color: var(--danger-text);
220
220
  }
221
221
 
222
- .variant-accent,
223
- .variant-pistachio {
222
+ .variant-accent {
224
223
  --accordion-open-bg: var(--ui-accent);
225
224
  --accordion-open-color: var(--ui-primary);
226
225
  }
227
226
 
228
- .variant-accent-subtle,
229
- .variant-pistachio-subtle {
227
+ .variant-accent-subtle {
230
228
  --accordion-open-bg: rgba(var(--ui-accent-rgbc), 0.15);
231
229
  --accordion-open-color: var(--text-color);
232
230
  }
233
231
 
234
- .variant-accent-outline,
235
- .variant-pistachio-outline {
232
+ .variant-accent-outline {
236
233
  --accordion-open-bg: transparent;
237
234
  --accordion-open-color: var(--ui-accent);
238
235
  --accordion-open-border-color: var(--ui-accent);
239
236
  }
240
237
 
241
- .variant-primary,
242
- .variant-midnight {
238
+ .variant-primary {
243
239
  --accordion-open-bg: var(--ui-primary);
244
240
  --accordion-open-color: white;
245
241
  }
246
242
 
247
- .variant-primary-subtle,
248
- .variant-midnight-subtle {
243
+ .variant-primary-subtle {
249
244
  --accordion-open-bg: rgba(var(--ui-primary-rgbc), 0.1);
250
245
  --accordion-open-color: var(--text-color);
251
246
  }
252
247
 
253
- .variant-primary-outline,
254
- .variant-midnight-outline {
248
+ .variant-primary-outline {
255
249
  --accordion-open-bg: transparent;
256
250
  --accordion-open-color: var(--ui-primary);
257
251
  --accordion-open-border-color: var(--ui-primary);
258
252
  }
259
253
 
260
- .variant-tertiary,
261
- .variant-turquoise {
254
+ .variant-tertiary {
262
255
  --accordion-open-bg: var(--ui-tertiary);
263
256
  --accordion-open-color: var(--ui-primary);
264
257
  }
265
258
 
266
- .variant-tertiary-subtle,
267
- .variant-turquoise-subtle {
259
+ .variant-tertiary-subtle {
268
260
  --accordion-open-bg: rgba(var(--ui-tertiary-dark-rgbc), 0.25);
269
261
  --accordion-open-color: var(--ui-tertiary-dark);
270
262
  }
@@ -122,8 +122,7 @@
122
122
  color: var(--badge-text-color) !important;
123
123
  }
124
124
 
125
- .accent,
126
- .pistachio {
125
+ .accent {
127
126
  --badge-bg-color: var(--ui-accent);
128
127
  --badge-text-color: var(--ui-primary);
129
128
  --badge-hover-bg-color: var(--ui-tertiary);
@@ -131,13 +130,11 @@
131
130
  --badge-outline-color: var(--ui-tertiary);
132
131
  }
133
132
 
134
- .accent :global(.loader),
135
- .pistachio :global(.loader) {
133
+ .accent :global(.loader) {
136
134
  color: var(--ui-primary);
137
135
  }
138
136
 
139
- .primary,
140
- .midnight {
137
+ .primary {
141
138
  --badge-bg-color: var(--ui-primary);
142
139
  --badge-text-color: #fff;
143
140
  --badge-hover-bg-color: var(--ui-accent-dark);
@@ -145,8 +142,7 @@
145
142
  --badge-outline-color: var(--ui-accent-dark);
146
143
  }
147
144
 
148
- .primary :global(.loader),
149
- .midnight :global(.loader) {
145
+ .primary :global(.loader) {
150
146
  color: var(--ui-accent);
151
147
  }
152
148
 
@@ -213,8 +209,7 @@
213
209
  --badge-outline-color: var(--ui-tertiary);
214
210
  }
215
211
 
216
- .accent-outline,
217
- .pistachio-outline {
212
+ .accent-outline {
218
213
  --badge-text-color: var(--ui-accent);
219
214
  --badge-bg-color: initial;
220
215
  --badge-border: 1px solid var(--ui-accent);
@@ -224,8 +219,7 @@
224
219
  --badge-outline-color: var(--ui-tertiary);
225
220
  }
226
221
 
227
- .primary-outline,
228
- .midnight-outline {
222
+ .primary-outline {
229
223
  --badge-text-color: var(--ui-primary);
230
224
  --badge-bg-color: initial;
231
225
  --badge-border: 1px solid var(--ui-primary);
@@ -235,8 +229,7 @@
235
229
  --badge-outline-color: var(--ui-accent-dark);
236
230
  }
237
231
 
238
- .tertiary,
239
- .turquoise {
232
+ .tertiary {
240
233
  --badge-text-color: black;
241
234
  --badge-bg-color: var(--ui-tertiary);
242
235
  --badge-hover-bg-color: var(--ui-tertiary-dark);
@@ -217,8 +217,7 @@
217
217
  }
218
218
  }
219
219
 
220
- .accent,
221
- .pistachio {
220
+ .accent {
222
221
  --button-text-color: var(--ui-primary);
223
222
  --button-bg-color: var(--ui-accent);
224
223
  --button-hover-bg-color: var(--ui-tertiary);
@@ -226,8 +225,7 @@
226
225
  --button-outline-color: var(--ui-tertiary);
227
226
  }
228
227
 
229
- .accent-outline,
230
- .pistachio-outline {
228
+ .accent-outline {
231
229
  --button-text-color: var(--ui-accent);
232
230
  --button-bg-color: initial;
233
231
  --button-border: 1px solid var(--ui-accent);
@@ -238,8 +236,7 @@
238
236
  --button-outline-color: var(--ui-tertiary);
239
237
  }
240
238
 
241
- .accent-subtle,
242
- .pistachio-subtle {
239
+ .accent-subtle {
243
240
  --button-text-color: var(--ui-accent);
244
241
  --button-bg-color: initial;
245
242
  --button-hover-text-color: var(--ui-primary);
@@ -249,16 +246,14 @@
249
246
  --button-outline-color: var(--ui-tertiary);
250
247
  }
251
248
 
252
- .primary,
253
- .midnight {
249
+ .primary {
254
250
  --button-bg-color: var(--ui-primary);
255
251
  --button-text-color: white;
256
252
  --button-hover-bg-color: var(--ui-accent-dark);
257
253
  --button-active-bg-color: var(--ui-primary-dark);
258
254
  }
259
255
 
260
- .primary-outline,
261
- .midnight-outline {
256
+ .primary-outline {
262
257
  --button-text-color: var(--ui-primary);
263
258
  --button-bg-color: initial;
264
259
  --button-border: 1px solid var(--ui-primary);
@@ -268,8 +263,7 @@
268
263
  --button-active-border: 1px solid var(--ui-primary-dark);
269
264
  }
270
265
 
271
- .primary-subtle,
272
- .midnight-subtle {
266
+ .primary-subtle {
273
267
  --button-text-color: var(--ui-primary);
274
268
  --button-bg-color: initial;
275
269
  --button-hover-text-color: white;
@@ -278,8 +272,7 @@
278
272
  --button-active-bg-color: var(--ui-primary-dark);
279
273
  }
280
274
 
281
- .tertiary,
282
- .turquoise {
275
+ .tertiary {
283
276
  --button-text-color: var(--ui-primary);
284
277
  --button-bg-color: var(--ui-tertiary);
285
278
  --button-hover-bg-color: var(--ui-accent);
@@ -287,8 +280,7 @@
287
280
  --button-outline-color: var(--ui-accent);
288
281
  }
289
282
 
290
- .tertiary-subtle,
291
- .turquoise-subtle {
283
+ .tertiary-subtle {
292
284
  background-color: initial;
293
285
  color: var(--ui-tertiary-dark);
294
286
 
@@ -5,11 +5,5 @@
5
5
  * - `primary` → `--ui-primary` (dark brand colour)
6
6
  * - `accent` → `--ui-accent` (light brand colour)
7
7
  * - `tertiary` → `--ui-tertiary` (supporting colour)
8
- *
9
- * The `midnight`, `pistachio` and `turquoise` names are legacy aliases for
10
- * `primary`, `accent` and `tertiary` respectively. They keep working but new code
11
- * should use the semantic names.
12
8
  */
13
- 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' | LegacyButtonVariant;
14
- /** @deprecated Use `primary`, `accent` and `tertiary` instead. */
15
- export type LegacyButtonVariant = 'pistachio' | 'pistachio-outline' | 'pistachio-subtle' | 'midnight' | 'midnight-outline' | 'midnight-subtle' | 'turquoise' | 'turquoise-subtle';
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';
@@ -34,7 +34,7 @@
34
34
  /** @deprecated Scrolling is now the default; use `allowOverflow` to opt out. */
35
35
  preventOverflow?: boolean;
36
36
  /** Size preset for the dialog width */
37
- size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
37
+ size?: 'md' | 'lg' | 'xl' | 'full';
38
38
  /** Additional CSS classes */
39
39
  class?: string;
40
40
  /** Footer content (typically action buttons) */
@@ -142,12 +142,12 @@
142
142
  {#snippet DialogInner()}
143
143
  {#if title}
144
144
  <div class="dialog-title">
145
- <span id={titleId} class="font-bold">{title}</span>
145
+ <span id={titleId} class="dialog-title-text">{title}</span>
146
146
  {#if allowImplicitClose}
147
147
  <ActionIcon
148
148
  onclick={() => (show = false)}
149
149
  variant="secondary-subtle"
150
- class="flex !p-[0.3rem] mr-1 !leading-0"
150
+ class="dialog-close"
151
151
  svg={iconX}
152
152
  size="1rem"
153
153
  ariaLabel="Close dialog"
@@ -182,8 +182,9 @@
182
182
  {#if noPaper}
183
183
  {@render DialogInner()}
184
184
  {:else}
185
- <div class="dialog-paper {overflowClass}">
186
- <Paper containerClass={classes}>
185
+ <div class="dialog-paper">
186
+ <!-- Dialog owns the section padding so header and footer dividers span the card -->
187
+ <Paper containerClass={classes} noPadding noGap>
187
188
  {@render DialogInner()}
188
189
  </Paper>
189
190
  </div>
@@ -260,7 +261,7 @@
260
261
  background-color: transparent;
261
262
  overflow: visible;
262
263
  margin: auto;
263
- max-width: min(calc(100vw - 2rem), calc(100% - 6px));
264
+ max-width: calc(100% - 2rem);
264
265
  /* Cap to the visible viewport with equal margins; the flex chain below
265
266
  (dialog > inner > paper > body, each min-height: 0) passes this limit
266
267
  down so the body shrinks instead of spilling past the bottom edge.
@@ -294,36 +295,77 @@
294
295
  min-height: 0;
295
296
  }
296
297
 
297
- /* Paper sits inside the height chain; .paper-body already has an inline
298
- min-height: 0, so only .paper needs the shrink link */
299
- .dialog :global(.paper) {
298
+ /* Paper sits inside the height chain. Without a gap its body is a plain
299
+ block, so make it a shrinkable flex column here; the sections below rely
300
+ on that to give the body the leftover height */
301
+ .dialog :global(.paper),
302
+ .dialog :global(.paper-body) {
303
+ display: flex;
304
+ flex-direction: column;
300
305
  min-height: 0;
301
306
  }
302
307
 
308
+ /* Section padding: 1rem inset, 0.75rem vertical for the header and footer,
309
+ 1rem for the body. Dividers run edge to edge */
303
310
  .dialog-title {
304
311
  display: flex;
312
+ align-items: center;
305
313
  justify-content: space-between;
306
- margin-bottom: 0.5rem;
307
- padding-bottom: 0.25rem;
314
+ gap: 0.75rem;
315
+ padding: 0.75rem 1rem;
308
316
  border-bottom: 1px solid var(--border-color);
317
+ flex-shrink: 0;
318
+ }
319
+
320
+ .dialog-title-text {
321
+ font-size: 1.0625rem;
309
322
  font-weight: 600;
323
+ line-height: 1.4;
324
+ min-width: 0;
325
+ overflow-wrap: anywhere;
326
+ }
327
+
328
+ /* Keep the close button from setting the header height: its hit area
329
+ overhangs the text line and the right inset instead */
330
+ .dialog-title :global(button.dialog-close) {
310
331
  flex-shrink: 0;
332
+ padding: 0.25rem;
333
+ margin: -0.25rem -0.5rem -0.25rem 0;
334
+ line-height: 0;
311
335
  }
312
336
 
337
+ /* The only scroll container. Padding lives inside it so focus rings and
338
+ negative-margin rows are not clipped, and the scrollbar hugs the edge */
313
339
  .dialog-body {
314
340
  display: flex;
315
341
  flex-direction: column;
316
342
  min-width: 0;
317
343
  min-height: 0;
318
344
  flex-shrink: 1;
345
+ padding: 1rem;
346
+ }
347
+
348
+ /* The body padding is the spacing; don't let the first and last elements
349
+ (or a wrapper's first and last) add their own margins on top of it */
350
+ .dialog-body > :global(:first-child),
351
+ .dialog-body > :global(:first-child > :first-child) {
352
+ margin-top: 0;
353
+ }
354
+
355
+ .dialog-body > :global(:last-child),
356
+ .dialog-body > :global(:last-child > :last-child) {
357
+ margin-bottom: 0;
319
358
  }
320
359
 
360
+ /* Actions align right. A secondary action can sit on the left with
361
+ `margin-right: auto` */
321
362
  .dialog-footer {
322
363
  display: flex;
323
- justify-content: space-between;
324
- padding-top: 0.5rem;
325
- border-top: 1px solid var(--border-color);
364
+ align-items: center;
365
+ justify-content: flex-end;
326
366
  gap: 0.5rem;
367
+ padding: 0.75rem 1rem;
368
+ border-top: 1px solid var(--border-color);
327
369
  flex-shrink: 0;
328
370
  }
329
371
 
@@ -335,33 +377,22 @@
335
377
  overflow-y: auto;
336
378
  }
337
379
 
338
- .dialog-no-paper {
339
- padding: 1rem;
340
- }
341
-
342
380
  .dialog-paper,
343
381
  .dialog-no-paper {
344
382
  display: flex;
345
383
  flex-direction: column;
346
- box-sizing: border-box;
347
- border-radius: 0.25rem;
348
- background: #f1f3f5;
349
384
  min-height: 0;
350
385
  }
351
386
 
352
- :global(.dark .dialog-paper),
353
- :global(.dark .dialog-no-paper) {
354
- background-color: rgb(33, 34, 38);
387
+ .dialog-no-paper {
388
+ border-radius: 0.25rem;
389
+ background-color: var(--paper-body-bg);
355
390
  }
356
391
 
357
392
  dialog::backdrop {
358
393
  background-color: #0008;
359
394
  }
360
395
 
361
- .dialog.sm {
362
- width: 20rem;
363
- }
364
-
365
396
  .dialog.md {
366
397
  width: 30rem;
367
398
  }
@@ -27,7 +27,7 @@ export interface DialogProps {
27
27
  /** @deprecated Scrolling is now the default; use `allowOverflow` to opt out. */
28
28
  preventOverflow?: boolean;
29
29
  /** Size preset for the dialog width */
30
- size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
30
+ size?: 'md' | 'lg' | 'xl' | 'full';
31
31
  /** Additional CSS classes */
32
32
  class?: string;
33
33
  /** Footer content (typically action buttons) */
@@ -132,20 +132,17 @@
132
132
  }
133
133
 
134
134
  /* Variant colors */
135
- .primary,
136
- .midnight {
135
+ .primary {
137
136
  background-color: var(--ui-primary);
138
137
  color: #fff;
139
138
  }
140
139
 
141
- .accent,
142
- .pistachio {
140
+ .accent {
143
141
  background-color: var(--ui-accent);
144
142
  color: var(--ui-primary);
145
143
  }
146
144
 
147
- .tertiary,
148
- .turquoise {
145
+ .tertiary {
149
146
  background-color: var(--ui-tertiary);
150
147
  color: var(--ui-primary);
151
148
  }
@@ -1,7 +1,2 @@
1
- /**
2
- * Colour variants for ProgressBar. `midnight`, `pistachio` and `turquoise` are
3
- * legacy aliases for `primary`, `accent` and `tertiary`.
4
- */
5
- export type ProgressBarVariant = 'primary' | 'accent' | 'tertiary' | 'danger' | 'secondary' | LegacyProgressBarVariant;
6
- /** @deprecated Use `primary`, `accent` and `tertiary` instead. */
7
- export type LegacyProgressBarVariant = 'midnight' | 'pistachio' | 'turquoise';
1
+ /** Colour variants for ProgressBar, named after the `--ui-*` tokens. */
2
+ export type ProgressBarVariant = 'primary' | 'accent' | 'tertiary' | 'danger' | 'secondary';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@placeholderco/placeholder-ui",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
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",