@placeholderco/placeholder-ui 2.2.0 → 2.2.2
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 +0 -10
- package/dist/editors/tiptap/TipTap.svelte +1 -1
- package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +1 -1
- package/dist/form/SelectMulti.svelte +0 -16
- package/dist/icon/Icon.svelte +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/layout/Navbar.svelte +3 -4
- package/dist/layout/Navbar.svelte.d.ts +1 -2
- package/dist/ui/AccordionItem.svelte +8 -16
- package/dist/ui/Badge.svelte +7 -14
- package/dist/ui/Button.svelte +8 -16
- package/dist/ui/ButtonVariant.d.ts +1 -7
- package/dist/ui/Dialog.svelte +153 -112
- package/dist/ui/Dialog.svelte.d.ts +1 -1
- package/dist/ui/ProgressBar.svelte +3 -6
- package/dist/ui/ProgressBarVariant.d.ts +2 -7
- package/package.json +1 -1
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 -
|
|
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);
|
|
@@ -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}
|
package/dist/icon/Icon.svelte
CHANGED
|
@@ -29,24 +29,24 @@
|
|
|
29
29
|
<span
|
|
30
30
|
style="--svg-stroke: {stroke}; --svg-fill: {fill}; {sizeStyle}"
|
|
31
31
|
class:flip
|
|
32
|
-
class="
|
|
32
|
+
class="pui-icon {classes}"
|
|
33
33
|
>
|
|
34
34
|
{@html svg}
|
|
35
35
|
</span>
|
|
36
36
|
|
|
37
37
|
<style>
|
|
38
|
-
.
|
|
38
|
+
.pui-icon {
|
|
39
39
|
display: inline-flex;
|
|
40
40
|
align-items: center;
|
|
41
41
|
justify-content: center;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
.
|
|
44
|
+
.pui-icon :global(svg) {
|
|
45
45
|
width: 100%;
|
|
46
46
|
height: 100%;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
.
|
|
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
|
|
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
|
|
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
|
-
|
|
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'
|
|
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(.
|
|
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
|
-
|
|
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
|
}
|
package/dist/ui/Badge.svelte
CHANGED
|
@@ -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);
|
package/dist/ui/Button.svelte
CHANGED
|
@@ -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'
|
|
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';
|
package/dist/ui/Dialog.svelte
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
// One lock shared by every instance so a nested dialog closing does not
|
|
3
|
+
// hand the page its scrollbar back while the parent is still open
|
|
4
|
+
let lockCount = 0;
|
|
5
|
+
let savedOverflow = '';
|
|
6
|
+
let savedPaddingRight = '';
|
|
7
|
+
|
|
8
|
+
function lockBodyScroll() {
|
|
9
|
+
if (lockCount++ > 0) return;
|
|
10
|
+
const body = document.body;
|
|
11
|
+
savedOverflow = body.style.overflow;
|
|
12
|
+
savedPaddingRight = body.style.paddingRight;
|
|
13
|
+
// Hiding the scrollbar widens the page and shifts everything sideways,
|
|
14
|
+
// which reads as a flicker behind the backdrop; pad by its width instead
|
|
15
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
16
|
+
if (scrollbarWidth > 0) {
|
|
17
|
+
const current = parseFloat(getComputedStyle(body).paddingRight) || 0;
|
|
18
|
+
body.style.paddingRight = `${current + scrollbarWidth}px`;
|
|
19
|
+
}
|
|
20
|
+
body.style.overflow = 'hidden';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function unlockBodyScroll() {
|
|
24
|
+
if (--lockCount > 0) return;
|
|
25
|
+
document.body.style.overflow = savedOverflow;
|
|
26
|
+
document.body.style.paddingRight = savedPaddingRight;
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
1
30
|
<script lang="ts">
|
|
2
31
|
import Paper from '../display/Paper.svelte';
|
|
3
32
|
import { iconX } from '../icon/index.js';
|
|
@@ -34,7 +63,7 @@
|
|
|
34
63
|
/** @deprecated Scrolling is now the default; use `allowOverflow` to opt out. */
|
|
35
64
|
preventOverflow?: boolean;
|
|
36
65
|
/** Size preset for the dialog width */
|
|
37
|
-
size?: '
|
|
66
|
+
size?: 'md' | 'lg' | 'xl' | 'full';
|
|
38
67
|
/** Additional CSS classes */
|
|
39
68
|
class?: string;
|
|
40
69
|
/** Footer content (typically action buttons) */
|
|
@@ -110,10 +139,8 @@
|
|
|
110
139
|
// Lock body scroll while open; effects only run in the browser, so this is SSR-safe
|
|
111
140
|
$effect(() => {
|
|
112
141
|
if (show) {
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
-
document.body.style.overflow = '';
|
|
116
|
-
};
|
|
142
|
+
lockBodyScroll();
|
|
143
|
+
return unlockBodyScroll;
|
|
117
144
|
}
|
|
118
145
|
});
|
|
119
146
|
|
|
@@ -142,12 +169,12 @@
|
|
|
142
169
|
{#snippet DialogInner()}
|
|
143
170
|
{#if title}
|
|
144
171
|
<div class="dialog-title">
|
|
145
|
-
<span id={titleId} class="
|
|
172
|
+
<span id={titleId} class="dialog-title-text">{title}</span>
|
|
146
173
|
{#if allowImplicitClose}
|
|
147
174
|
<ActionIcon
|
|
148
175
|
onclick={() => (show = false)}
|
|
149
176
|
variant="secondary-subtle"
|
|
150
|
-
class="
|
|
177
|
+
class="dialog-close"
|
|
151
178
|
svg={iconX}
|
|
152
179
|
size="1rem"
|
|
153
180
|
ariaLabel="Close dialog"
|
|
@@ -182,8 +209,9 @@
|
|
|
182
209
|
{#if noPaper}
|
|
183
210
|
{@render DialogInner()}
|
|
184
211
|
{:else}
|
|
185
|
-
<div class="dialog-paper
|
|
186
|
-
|
|
212
|
+
<div class="dialog-paper">
|
|
213
|
+
<!-- Dialog owns the section padding so header and footer dividers span the card -->
|
|
214
|
+
<Paper containerClass={classes} noPadding noGap>
|
|
187
215
|
{@render DialogInner()}
|
|
188
216
|
</Paper>
|
|
189
217
|
</div>
|
|
@@ -192,66 +220,21 @@
|
|
|
192
220
|
</dialog>
|
|
193
221
|
|
|
194
222
|
<style>
|
|
195
|
-
/*
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
to {
|
|
204
|
-
opacity: 1;
|
|
205
|
-
transform: translateY(0);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
@keyframes fadeOut {
|
|
209
|
-
from {
|
|
210
|
-
opacity: 1;
|
|
211
|
-
transform: translateY(0);
|
|
212
|
-
}
|
|
213
|
-
to {
|
|
214
|
-
opacity: 0;
|
|
215
|
-
transform: translateY(-0.5rem);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
@keyframes fadeInFull {
|
|
220
|
-
from {
|
|
221
|
-
opacity: 0;
|
|
222
|
-
}
|
|
223
|
-
to {
|
|
224
|
-
opacity: 1;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
@keyframes fadeOutFull {
|
|
228
|
-
from {
|
|
229
|
-
opacity: 1;
|
|
230
|
-
}
|
|
231
|
-
to {
|
|
232
|
-
opacity: 0;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/* Keyframes for the backdrop pseudo-element */
|
|
237
|
-
@keyframes backdropFadeIn {
|
|
238
|
-
from {
|
|
239
|
-
background: hsl(0 0% 0% / 0%);
|
|
240
|
-
}
|
|
241
|
-
to {
|
|
242
|
-
background: hsl(0 0% 0% / 65%);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
@keyframes backdropFadeOut {
|
|
246
|
-
from {
|
|
247
|
-
background: hsl(0 0% 0% / 65%);
|
|
248
|
-
}
|
|
249
|
-
to {
|
|
250
|
-
background: hsl(0 0% 0% / 0%);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
223
|
+
/* Open/close is a transition driven by [open] plus @starting-style, not a
|
|
224
|
+
keyframe animation. Keyframes with a `forwards` fill kept a transform
|
|
225
|
+
applied while open, and the backdrop's static colour could paint for a
|
|
226
|
+
frame before its animation took over, showing as a flash on open.
|
|
227
|
+
Transitions have no fill state: the closed values are the base rule, the
|
|
228
|
+
open values live on [open], and @starting-style supplies the from-values
|
|
229
|
+
for the first frame after display switches on */
|
|
254
230
|
dialog {
|
|
231
|
+
/* Everything that shapes the box lives here, not on [open]: the close
|
|
232
|
+
transition runs after [open] is removed, so rules scoped to it would
|
|
233
|
+
drop out while the dialog is still fading. That includes the browser's
|
|
234
|
+
own :modal positioning, which stops applying the moment close() runs */
|
|
235
|
+
position: fixed;
|
|
236
|
+
inset: 0;
|
|
237
|
+
flex-direction: column;
|
|
255
238
|
color: var(--text-color);
|
|
256
239
|
border: none;
|
|
257
240
|
/* The dialog element itself is focused by showModal(); don't draw a
|
|
@@ -260,7 +243,7 @@
|
|
|
260
243
|
background-color: transparent;
|
|
261
244
|
overflow: visible;
|
|
262
245
|
margin: auto;
|
|
263
|
-
max-width:
|
|
246
|
+
max-width: calc(100% - 2rem);
|
|
264
247
|
/* Cap to the visible viewport with equal margins; the flex chain below
|
|
265
248
|
(dialog > inner > paper > body, each min-height: 0) passes this limit
|
|
266
249
|
down so the body shrinks instead of spilling past the bottom edge.
|
|
@@ -269,22 +252,56 @@
|
|
|
269
252
|
max-height: calc(100vh - 2rem);
|
|
270
253
|
max-height: calc(100dvh - 2rem);
|
|
271
254
|
|
|
272
|
-
|
|
255
|
+
opacity: 0;
|
|
256
|
+
/* Animate transform, not margin: the native dialog centres itself via
|
|
257
|
+
`margin: auto` */
|
|
258
|
+
transform: translateY(-0.5rem);
|
|
259
|
+
transition:
|
|
260
|
+
opacity 0.2s ease,
|
|
261
|
+
transform 0.2s ease,
|
|
262
|
+
display 0.2s allow-discrete,
|
|
263
|
+
overlay 0.2s allow-discrete;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
dialog[open] {
|
|
267
|
+
/* Only when [open] — an unconditional author display would override
|
|
268
|
+
the UA's display: none on closed dialogs and make them visible */
|
|
269
|
+
display: flex;
|
|
270
|
+
opacity: 1;
|
|
271
|
+
/* `none`, not translateY(0): a transform of any value makes the dialog
|
|
272
|
+
the containing block for position: fixed descendants */
|
|
273
|
+
transform: none;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@starting-style {
|
|
277
|
+
dialog[open] {
|
|
278
|
+
opacity: 0;
|
|
279
|
+
transform: translateY(-0.5rem);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
dialog::backdrop {
|
|
284
|
+
background-color: rgb(0 0 0 / 0);
|
|
273
285
|
transition:
|
|
286
|
+
background-color 0.2s ease,
|
|
274
287
|
display 0.2s allow-discrete,
|
|
275
288
|
overlay 0.2s allow-discrete;
|
|
276
|
-
|
|
277
|
-
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
dialog[open]::backdrop {
|
|
292
|
+
background-color: rgb(0 0 0 / 0.65);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@starting-style {
|
|
296
|
+
dialog[open]::backdrop {
|
|
297
|
+
background-color: rgb(0 0 0 / 0);
|
|
278
298
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
&::backdrop {
|
|
286
|
-
animation: backdropFadeIn 0.2s forwards;
|
|
287
|
-
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@media (prefers-reduced-motion: reduce) {
|
|
302
|
+
dialog,
|
|
303
|
+
dialog::backdrop {
|
|
304
|
+
transition-duration: 0.01ms;
|
|
288
305
|
}
|
|
289
306
|
}
|
|
290
307
|
|
|
@@ -294,36 +311,77 @@
|
|
|
294
311
|
min-height: 0;
|
|
295
312
|
}
|
|
296
313
|
|
|
297
|
-
/* Paper sits inside the height chain
|
|
298
|
-
|
|
299
|
-
|
|
314
|
+
/* Paper sits inside the height chain. Without a gap its body is a plain
|
|
315
|
+
block, so make it a shrinkable flex column here; the sections below rely
|
|
316
|
+
on that to give the body the leftover height */
|
|
317
|
+
.dialog :global(.paper),
|
|
318
|
+
.dialog :global(.paper-body) {
|
|
319
|
+
display: flex;
|
|
320
|
+
flex-direction: column;
|
|
300
321
|
min-height: 0;
|
|
301
322
|
}
|
|
302
323
|
|
|
324
|
+
/* Section padding: 1rem inset, 0.75rem vertical for the header and footer,
|
|
325
|
+
1rem for the body. Dividers run edge to edge */
|
|
303
326
|
.dialog-title {
|
|
304
327
|
display: flex;
|
|
328
|
+
align-items: center;
|
|
305
329
|
justify-content: space-between;
|
|
306
|
-
|
|
307
|
-
padding
|
|
330
|
+
gap: 0.75rem;
|
|
331
|
+
padding: 0.75rem 1rem;
|
|
308
332
|
border-bottom: 1px solid var(--border-color);
|
|
333
|
+
flex-shrink: 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.dialog-title-text {
|
|
337
|
+
font-size: 1.0625rem;
|
|
309
338
|
font-weight: 600;
|
|
339
|
+
line-height: 1.4;
|
|
340
|
+
min-width: 0;
|
|
341
|
+
overflow-wrap: anywhere;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* Keep the close button from setting the header height: its hit area
|
|
345
|
+
overhangs the text line and the right inset instead */
|
|
346
|
+
.dialog-title :global(button.dialog-close) {
|
|
310
347
|
flex-shrink: 0;
|
|
348
|
+
padding: 0.25rem;
|
|
349
|
+
margin: -0.25rem -0.5rem -0.25rem 0;
|
|
350
|
+
line-height: 0;
|
|
311
351
|
}
|
|
312
352
|
|
|
353
|
+
/* The only scroll container. Padding lives inside it so focus rings and
|
|
354
|
+
negative-margin rows are not clipped, and the scrollbar hugs the edge */
|
|
313
355
|
.dialog-body {
|
|
314
356
|
display: flex;
|
|
315
357
|
flex-direction: column;
|
|
316
358
|
min-width: 0;
|
|
317
359
|
min-height: 0;
|
|
318
360
|
flex-shrink: 1;
|
|
361
|
+
padding: 1rem;
|
|
319
362
|
}
|
|
320
363
|
|
|
364
|
+
/* The body padding is the spacing; don't let the first and last elements
|
|
365
|
+
(or a wrapper's first and last) add their own margins on top of it */
|
|
366
|
+
.dialog-body > :global(:first-child),
|
|
367
|
+
.dialog-body > :global(:first-child > :first-child) {
|
|
368
|
+
margin-top: 0;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.dialog-body > :global(:last-child),
|
|
372
|
+
.dialog-body > :global(:last-child > :last-child) {
|
|
373
|
+
margin-bottom: 0;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* Actions align right. A secondary action can sit on the left with
|
|
377
|
+
`margin-right: auto` */
|
|
321
378
|
.dialog-footer {
|
|
322
379
|
display: flex;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
border-top: 1px solid var(--border-color);
|
|
380
|
+
align-items: center;
|
|
381
|
+
justify-content: flex-end;
|
|
326
382
|
gap: 0.5rem;
|
|
383
|
+
padding: 0.75rem 1rem;
|
|
384
|
+
border-top: 1px solid var(--border-color);
|
|
327
385
|
flex-shrink: 0;
|
|
328
386
|
}
|
|
329
387
|
|
|
@@ -335,31 +393,16 @@
|
|
|
335
393
|
overflow-y: auto;
|
|
336
394
|
}
|
|
337
395
|
|
|
338
|
-
.dialog-no-paper {
|
|
339
|
-
padding: 1rem;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
396
|
.dialog-paper,
|
|
343
397
|
.dialog-no-paper {
|
|
344
398
|
display: flex;
|
|
345
399
|
flex-direction: column;
|
|
346
|
-
box-sizing: border-box;
|
|
347
|
-
border-radius: 0.25rem;
|
|
348
|
-
background: #f1f3f5;
|
|
349
400
|
min-height: 0;
|
|
350
401
|
}
|
|
351
402
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
background-color:
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
dialog::backdrop {
|
|
358
|
-
background-color: #0008;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
.dialog.sm {
|
|
362
|
-
width: 20rem;
|
|
403
|
+
.dialog-no-paper {
|
|
404
|
+
border-radius: 0.25rem;
|
|
405
|
+
background-color: var(--paper-body-bg);
|
|
363
406
|
}
|
|
364
407
|
|
|
365
408
|
.dialog.md {
|
|
@@ -379,11 +422,9 @@
|
|
|
379
422
|
max-width: 100%;
|
|
380
423
|
max-height: 100%;
|
|
381
424
|
margin-top: auto;
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
animation: fadeInFull 0.2s forwards;
|
|
386
|
-
}
|
|
425
|
+
/* Full-screen fades in place; more specific than the @starting-style
|
|
426
|
+
rule above, so it wins for both the starting and the open state */
|
|
427
|
+
transform: none;
|
|
387
428
|
}
|
|
388
429
|
|
|
389
430
|
.dialog.full,
|
|
@@ -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?: '
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "2.2.2",
|
|
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",
|