@placeholderco/placeholder-ui 1.0.12 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +134 -130
- package/dist/app.css +178 -0
- package/dist/bootstrap.min.css +3600 -0
- package/dist/cards/GitCard.svelte +115 -0
- package/dist/cards/GitCard.svelte.d.ts +22 -0
- package/dist/display/Avatar.svelte +29 -17
- package/dist/display/Avatar.svelte.d.ts +12 -2
- package/dist/display/LinkCollection.svelte +40 -18
- package/dist/display/LinkCollection.svelte.d.ts +9 -2
- package/dist/display/Paper.svelte +31 -19
- package/dist/display/Paper.svelte.d.ts +12 -3
- package/dist/display/alert/Alert.svelte +129 -0
- package/dist/display/alert/Alert.svelte.d.ts +15 -0
- package/dist/display/alert/AlertVariant.d.ts +1 -0
- package/dist/display/alert/AlertVariant.js +1 -0
- package/dist/display/filetree/FileTree.svelte +259 -0
- package/dist/display/filetree/FileTree.svelte.d.ts +76 -0
- package/dist/display/filetree/FileTreeItem.svelte +396 -0
- package/dist/display/filetree/FileTreeItem.svelte.d.ts +40 -0
- package/dist/display/filetree/FileTreeNode.d.ts +46 -0
- package/dist/display/filetree/FileTreeNode.js +115 -0
- package/dist/display/filetree/index.d.ts +5 -0
- package/dist/display/filetree/index.js +3 -0
- package/dist/editors/CodeMirror.svelte +306 -0
- package/dist/editors/CodeMirror.svelte.d.ts +31 -0
- package/dist/editors/tiptap/LinkActionMenu.svelte +307 -0
- package/dist/editors/tiptap/LinkActionMenu.svelte.d.ts +8 -0
- package/dist/editors/tiptap/TipTap.svelte +856 -0
- package/dist/editors/tiptap/TipTap.svelte.d.ts +54 -0
- package/dist/editors/tiptap/TipTapBubble.svelte +790 -0
- package/dist/editors/tiptap/TipTapBubble.svelte.d.ts +44 -0
- package/dist/editors/tiptap/collaboration.d.ts +55 -0
- package/dist/editors/tiptap/collaboration.js +1 -0
- package/dist/editors/tiptap/extensions/Alert.d.ts +18 -0
- package/dist/editors/tiptap/extensions/Alert.js +72 -0
- package/dist/editors/tiptap/extensions/CodeBlockEditor.d.ts +21 -0
- package/dist/editors/tiptap/extensions/CodeBlockEditor.js +326 -0
- package/dist/editors/tiptap/extensions/Div.d.ts +19 -0
- package/dist/editors/tiptap/extensions/Div.js +89 -0
- package/dist/editors/tiptap/extensions/Span.d.ts +5 -0
- package/dist/editors/tiptap/extensions/Span.js +56 -0
- package/dist/editors/tiptap/extensions/codeBlockEditor.css +236 -0
- package/dist/editors/tiptap/extensions/codeBlockLanguages.d.ts +17 -0
- package/dist/editors/tiptap/extensions/codeBlockLanguages.js +124 -0
- package/dist/editors/tiptap/extensions/index.d.ts +7 -0
- package/dist/editors/tiptap/extensions/index.js +5 -0
- package/dist/editors/tiptap/toolbar/AlertButton.svelte +261 -0
- package/dist/editors/tiptap/toolbar/AlertButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/AlignRightButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/AlignRightButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/BoldButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/BoldButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/BulletListButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/BulletListButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/CodeButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/CodeButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/ColorButton.svelte +299 -0
- package/dist/editors/tiptap/toolbar/ColorButton.svelte.d.ts +20 -0
- package/dist/editors/tiptap/toolbar/DocumentButton.svelte +58 -0
- package/dist/editors/tiptap/toolbar/DocumentButton.svelte.d.ts +9 -0
- package/dist/editors/tiptap/toolbar/HeadingButton.svelte +30 -0
- package/dist/editors/tiptap/toolbar/HeadingButton.svelte.d.ts +8 -0
- package/dist/editors/tiptap/toolbar/HtmlButton.svelte +68 -0
- package/dist/editors/tiptap/toolbar/HtmlButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/ImageButton.svelte +54 -0
- package/dist/editors/tiptap/toolbar/ImageButton.svelte.d.ts +8 -0
- package/dist/editors/tiptap/toolbar/ItalicButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/ItalicButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/LinkButton.svelte +257 -0
- package/dist/editors/tiptap/toolbar/LinkButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/OrderedListButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/OrderedListButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/RedoButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/RedoButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/SubscriptButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/SubscriptButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/TableButton.svelte +258 -0
- package/dist/editors/tiptap/toolbar/TableButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +84 -0
- package/dist/editors/tiptap/toolbar/ToolbarButton.svelte.d.ts +10 -0
- package/dist/editors/tiptap/toolbar/UnderlineButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/UnderlineButton.svelte.d.ts +7 -0
- package/dist/editors/tiptap/toolbar/UndoButton.svelte +18 -0
- package/dist/editors/tiptap/toolbar/UndoButton.svelte.d.ts +7 -0
- package/dist/form/Autocomplete.svelte +86 -135
- package/dist/form/Autocomplete.svelte.d.ts +6 -8
- package/dist/form/AutocompleteMulti.svelte +385 -227
- package/dist/form/AutocompleteMulti.svelte.d.ts +59 -10
- package/dist/form/Checkbox.svelte +59 -54
- package/dist/form/Checkbox.svelte.d.ts +14 -5
- package/dist/form/Chips.svelte +29 -13
- package/dist/form/Chips.svelte.d.ts +16 -2
- package/dist/form/ColorPicker.svelte +957 -0
- package/dist/form/ColorPicker.svelte.d.ts +78 -0
- package/dist/form/ComboBox.svelte +30 -20
- package/dist/form/ComboBox.svelte.d.ts +1 -1
- package/dist/form/ComboBoxItemBuilder.svelte +161 -188
- package/dist/form/ComboBoxItemBuilder.svelte.d.ts +19 -2
- package/dist/form/ComboBoxMulti.svelte +38 -24
- package/dist/form/ComboBoxMulti.svelte.d.ts +1 -1
- package/dist/form/CronBuilder.svelte +84 -67
- package/dist/form/CronBuilder.svelte.d.ts +16 -3
- package/dist/form/DatePicker.svelte +148 -195
- package/dist/form/DateRangePicker.svelte +101 -98
- package/dist/form/DateTimePicker.svelte +167 -208
- package/dist/form/DateTimePicker.svelte.d.ts +10 -2
- package/dist/form/FormGroup.svelte +33 -10
- package/dist/form/FormGroup.svelte.d.ts +12 -2
- package/dist/form/Number.svelte +70 -47
- package/dist/form/Number.svelte.d.ts +36 -6
- package/dist/form/Radio.svelte +18 -18
- package/dist/form/RadioGroup.svelte +23 -12
- package/dist/form/RadioGroup.svelte.d.ts +13 -2
- package/dist/form/SegmentedControl.svelte +76 -56
- package/dist/form/SegmentedControl.svelte.d.ts +9 -4
- package/dist/form/Select.svelte +150 -233
- package/dist/form/Select.svelte.d.ts +29 -5
- package/dist/form/SelectMulti.svelte +163 -277
- package/dist/form/SelectMulti.svelte.d.ts +36 -7
- package/dist/form/Slider.svelte +183 -269
- package/dist/form/Slider.svelte.d.ts +32 -17
- package/dist/form/StringArrayBuilder.svelte +249 -0
- package/dist/form/StringArrayBuilder.svelte.d.ts +15 -0
- package/dist/form/Switch.svelte +164 -106
- package/dist/form/Switch.svelte.d.ts +22 -3
- package/dist/form/TextArea.svelte +49 -29
- package/dist/form/TextArea.svelte.d.ts +23 -3
- package/dist/form/Textbox.svelte +69 -68
- package/dist/form/Textbox.svelte.d.ts +32 -4
- package/dist/form/TimePicker.svelte +42 -47
- package/dist/form/TimePicker.svelte.d.ts +12 -2
- package/dist/form/comboBoxCore.svelte.d.ts +99 -0
- package/dist/form/comboBoxCore.svelte.js +243 -0
- package/dist/icon/Icon.svelte +8 -3
- package/dist/icon/Icon.svelte.d.ts +8 -3
- package/dist/icon/file-type-bmp.svg +1 -0
- package/dist/icon/file-type-csv.svg +1 -0
- package/dist/icon/file-type-doc.svg +1 -0
- package/dist/icon/file-type-docx.svg +1 -0
- package/dist/icon/file-type-jpg.svg +1 -0
- package/dist/icon/file-type-pdf.svg +1 -0
- package/dist/icon/file-type-png.svg +1 -0
- package/dist/icon/file-type-ppt.svg +1 -0
- package/dist/icon/file-type-svg.svg +1 -0
- package/dist/icon/file-type-txt.svg +1 -0
- package/dist/icon/file-type-xls.svg +1 -0
- package/dist/icon/file-type-zip.svg +1 -0
- package/dist/icon/index.d.ts +166 -151
- package/dist/icon/index.js +166 -152
- package/dist/icon/logo-placeholder.svg +6 -0
- package/dist/icon/source-code.svg +1 -0
- package/dist/icon/sun-moon.svg +1 -0
- package/dist/icon/table.svg +6 -0
- package/dist/index.d.ts +146 -82
- package/dist/index.js +77 -78
- package/dist/layout/AppShell.svelte +12 -162
- package/dist/layout/AppShell.svelte.d.ts +6 -27
- package/dist/layout/CustomNavbar.svelte +9 -7
- package/dist/layout/CustomNavbar.svelte.d.ts +4 -2
- package/dist/layout/Navbar.svelte +161 -129
- package/dist/layout/Navbar.svelte.d.ts +29 -15
- package/dist/layout/NavbarItemDisplay.svelte +2 -2
- package/dist/layout/NavbarItemView.svelte +182 -0
- package/dist/layout/NavbarItemView.svelte.d.ts +10 -0
- package/dist/layout/Sidenav.svelte +280 -341
- package/dist/layout/Sidenav.svelte.d.ts +36 -4
- package/dist/models/ComboBoxItem.d.ts +2 -0
- package/dist/models/Employee.d.ts +53 -0
- package/dist/models/Employee.js +23 -0
- package/dist/models/Hyperlink.d.ts +3 -1
- package/dist/models/LinkCollectionItem.d.ts +3 -1
- package/dist/models/NavbarItem.d.ts +6 -2
- package/dist/theme.svelte.d.ts +0 -1
- package/dist/theme.svelte.js +46 -58
- package/dist/ui/Accordion.svelte +81 -242
- package/dist/ui/Accordion.svelte.d.ts +37 -14
- package/dist/ui/AccordionItem.svelte +303 -0
- package/dist/ui/AccordionItem.svelte.d.ts +21 -0
- package/dist/ui/ActionIcon.svelte +25 -21
- package/dist/ui/ActionIcon.svelte.d.ts +15 -2
- package/dist/ui/Badge.svelte +163 -171
- package/dist/ui/Badge.svelte.d.ts +13 -5
- package/dist/ui/Button.svelte +178 -205
- package/dist/ui/Button.svelte.d.ts +19 -2
- package/dist/ui/ButtonVariant.d.ts +15 -1
- package/dist/ui/ContextMenu.svelte +146 -0
- package/dist/ui/ContextMenu.svelte.d.ts +37 -0
- package/dist/ui/ContextMenuList.svelte +188 -0
- package/dist/ui/ContextMenuList.svelte.d.ts +12 -0
- package/dist/ui/Dialog.svelte +183 -111
- package/dist/ui/Dialog.svelte.d.ts +21 -4
- package/dist/ui/Drawer.svelte +237 -184
- package/dist/ui/Drawer.svelte.d.ts +20 -2
- package/dist/ui/Dropdown.svelte +24 -14
- package/dist/ui/Dropdown.svelte.d.ts +11 -2
- package/dist/ui/Dropzone.svelte +159 -57
- package/dist/ui/Dropzone.svelte.d.ts +29 -2
- package/dist/ui/Link.svelte +12 -4
- package/dist/ui/Link.svelte.d.ts +8 -2
- package/dist/ui/Loader.svelte +23 -18
- package/dist/ui/Loader.svelte.d.ts +5 -2
- package/dist/ui/Logo.svelte +37 -0
- package/dist/ui/Logo.svelte.d.ts +16 -0
- package/dist/ui/MultiSortable.svelte +287 -0
- package/dist/ui/MultiSortable.svelte.d.ts +50 -0
- package/dist/ui/Pagination.svelte +15 -9
- package/dist/ui/Pagination.svelte.d.ts +6 -2
- package/dist/ui/Popover.svelte +43 -65
- package/dist/ui/Popover.svelte.d.ts +14 -5
- package/dist/ui/ProgressBar.svelte +28 -30
- package/dist/ui/ProgressBarVariant.d.ts +7 -1
- package/dist/ui/SegmentedControl.svelte +0 -0
- package/dist/ui/SegmentedControl.svelte.d.ts +26 -0
- package/dist/ui/Sortable.svelte +163 -0
- package/dist/ui/Sortable.svelte.d.ts +47 -0
- package/dist/ui/Table.svelte +383 -80
- package/dist/ui/Table.svelte.d.ts +43 -2
- package/dist/ui/Tabs.svelte +22 -18
- package/dist/ui/Tabs.svelte.d.ts +6 -2
- package/dist/ui/ThemeSwitcher.svelte +26 -7
- package/dist/ui/ThemeSwitcher.svelte.d.ts +4 -2
- package/dist/ui/Tooltip.svelte +312 -180
- package/dist/ui/Tooltip.svelte.d.ts +4 -3
- package/dist/uiTheme.svelte.d.ts +86 -0
- package/dist/uiTheme.svelte.js +214 -0
- package/dist/util/DateFunctions.js +1 -1
- package/dist/util/DragDrop.d.ts +50 -0
- package/dist/util/DragDrop.js +154 -0
- package/dist/util/NavigateTo.js +2 -2
- package/dist/util/dayjs.d.ts +4 -0
- package/dist/util/dayjs.js +15 -0
- package/package.json +66 -26
- package/dist/display/Alert.svelte +0 -179
- package/dist/display/Alert.svelte.d.ts +0 -13
- package/dist/form/FileInput.svelte +0 -235
- package/dist/form/FileInput.svelte.d.ts +0 -23
- package/dist/form/PasswordInput.svelte +0 -253
- package/dist/form/PasswordInput.svelte.d.ts +0 -34
- package/dist/form/Rating.svelte +0 -235
- package/dist/form/Rating.svelte.d.ts +0 -21
- package/dist/styles/components.css +0 -199
- package/dist/styles/dark.css +0 -146
- package/dist/styles/index.css +0 -116
- package/dist/styles/reset.css +0 -110
- package/dist/styles/semantic.css +0 -86
- package/dist/styles/tokens.css +0 -203
- package/dist/styles/utilities.css +0 -523
- package/dist/ui/Breadcrumbs.svelte +0 -131
- package/dist/ui/Breadcrumbs.svelte.d.ts +0 -16
- package/dist/ui/LoadingOverlay.svelte +0 -53
- package/dist/ui/LoadingOverlay.svelte.d.ts +0 -11
- package/dist/ui/Progress.svelte +0 -191
- package/dist/ui/Progress.svelte.d.ts +0 -15
- package/dist/ui/RingProgress.svelte +0 -141
- package/dist/ui/RingProgress.svelte.d.ts +0 -18
- package/dist/ui/Skeleton.svelte +0 -85
- package/dist/ui/Skeleton.svelte.d.ts +0 -12
- package/dist/ui/Stepper.svelte +0 -355
- package/dist/ui/Stepper.svelte.d.ts +0 -24
- package/dist/ui/Timeline.svelte +0 -225
- package/dist/ui/Timeline.svelte.d.ts +0 -23
- /package/dist/{actions → util}/ClickOutside.d.ts +0 -0
- /package/dist/{actions → util}/ClickOutside.js +0 -0
- /package/dist/{transitions → util}/Transitions.d.ts +0 -0
- /package/dist/{transitions → util}/Transitions.js +0 -0
package/dist/ui/Dialog.svelte
CHANGED
|
@@ -3,19 +3,37 @@
|
|
|
3
3
|
import { iconX } from '../icon/index.js';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import ActionIcon from './ActionIcon.svelte';
|
|
6
|
-
import { setContext } from 'svelte';
|
|
6
|
+
import { setContext, untrack } from 'svelte';
|
|
7
|
+
|
|
8
|
+
export interface DialogContext {
|
|
9
|
+
/** Whether the dialog is currently open (reactive) */
|
|
10
|
+
readonly isOpen: boolean;
|
|
11
|
+
/** Register a callback invoked each time the dialog opens */
|
|
12
|
+
onOpen: (callback: () => void) => void;
|
|
13
|
+
/** Register a callback invoked each time the dialog closes */
|
|
14
|
+
onClose: (callback: () => void) => void;
|
|
15
|
+
/** Register a callback invoked only the first time the dialog opens */
|
|
16
|
+
onFirstOpen: (callback: () => void) => void;
|
|
17
|
+
}
|
|
7
18
|
|
|
8
|
-
interface
|
|
19
|
+
export interface DialogProps {
|
|
20
|
+
/** Whether the dialog is visible (bindable) */
|
|
9
21
|
show: boolean;
|
|
22
|
+
/** Allow closing by clicking backdrop or pressing Escape */
|
|
10
23
|
allowImplicitClose?: boolean;
|
|
24
|
+
/** Dialog title displayed in the header */
|
|
11
25
|
title?: string | undefined;
|
|
26
|
+
/** Render without the Paper wrapper component */
|
|
12
27
|
noPaper?: boolean;
|
|
28
|
+
/** Prevent content from overflowing the dialog bounds */
|
|
13
29
|
preventOverflow?: boolean;
|
|
30
|
+
/** Size preset for the dialog width */
|
|
14
31
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
32
|
+
/** Additional CSS classes */
|
|
15
33
|
class?: string;
|
|
16
|
-
/**
|
|
17
|
-
footerBetween?: boolean;
|
|
34
|
+
/** Footer content (typically action buttons) */
|
|
18
35
|
footer?: Snippet;
|
|
36
|
+
/** Main dialog content */
|
|
19
37
|
children?: Snippet;
|
|
20
38
|
}
|
|
21
39
|
|
|
@@ -27,153 +45,178 @@
|
|
|
27
45
|
preventOverflow = false,
|
|
28
46
|
size = 'md',
|
|
29
47
|
class: classes = '',
|
|
30
|
-
footerBetween = false,
|
|
31
48
|
footer,
|
|
32
49
|
children
|
|
33
|
-
}:
|
|
50
|
+
}: DialogProps = $props();
|
|
51
|
+
|
|
52
|
+
const uid = $props.id();
|
|
53
|
+
const titleId = `${uid}-title`;
|
|
34
54
|
|
|
35
55
|
let dialogElement: HTMLDialogElement | undefined = $state(undefined);
|
|
36
|
-
|
|
37
|
-
// Create context for dialog events
|
|
38
|
-
let hasOpenedBefore = $state(false);
|
|
39
|
-
let dialogContext = $state({
|
|
40
|
-
isOpen: show,
|
|
41
|
-
onOpen: () => {},
|
|
42
|
-
onClose: () => {},
|
|
43
|
-
onFirstOpen: () => {}
|
|
44
|
-
});
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
// Context so child components can react to dialog state
|
|
58
|
+
const openCallbacks: (() => void)[] = [];
|
|
59
|
+
const closeCallbacks: (() => void)[] = [];
|
|
60
|
+
const firstOpenCallbacks: (() => void)[] = [];
|
|
61
|
+
|
|
62
|
+
setContext<DialogContext>('dialog', {
|
|
63
|
+
get isOpen() {
|
|
64
|
+
return show;
|
|
65
|
+
},
|
|
66
|
+
onOpen: (callback) => openCallbacks.push(callback),
|
|
67
|
+
onClose: (callback) => closeCallbacks.push(callback),
|
|
68
|
+
onFirstOpen: (callback) => firstOpenCallbacks.push(callback)
|
|
48
69
|
});
|
|
49
70
|
|
|
50
|
-
//
|
|
51
|
-
|
|
71
|
+
// Plain (untracked) flags — only the `show` transition should re-run the effect
|
|
72
|
+
let wasOpen = false;
|
|
73
|
+
let hasOpenedBefore = false;
|
|
52
74
|
|
|
53
75
|
$effect(() => {
|
|
54
|
-
if (dialogElement)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
if (!dialogElement) return;
|
|
77
|
+
|
|
78
|
+
if (show && !wasOpen) {
|
|
79
|
+
wasOpen = true;
|
|
80
|
+
dialogElement.showModal();
|
|
81
|
+
untrack(() => {
|
|
82
|
+
for (const callback of openCallbacks) callback();
|
|
58
83
|
if (!hasOpenedBefore) {
|
|
59
84
|
hasOpenedBefore = true;
|
|
60
|
-
|
|
85
|
+
for (const callback of firstOpenCallbacks) callback();
|
|
61
86
|
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
});
|
|
88
|
+
} else if (!show && wasOpen) {
|
|
89
|
+
wasOpen = false;
|
|
90
|
+
dialogElement.close();
|
|
91
|
+
untrack(() => {
|
|
92
|
+
for (const callback of closeCallbacks) callback();
|
|
93
|
+
});
|
|
66
94
|
}
|
|
67
95
|
});
|
|
68
96
|
|
|
97
|
+
// Lock body scroll while open; effects only run in the browser, so this is SSR-safe
|
|
69
98
|
$effect(() => {
|
|
70
|
-
if (!body) return;
|
|
71
|
-
|
|
72
99
|
if (show) {
|
|
73
|
-
body.style.overflow = 'hidden';
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
document.body.style.overflow = 'hidden';
|
|
101
|
+
return () => {
|
|
102
|
+
document.body.style.overflow = '';
|
|
103
|
+
};
|
|
76
104
|
}
|
|
77
105
|
});
|
|
78
106
|
|
|
79
|
-
|
|
107
|
+
function onCancel(e: Event) {
|
|
108
|
+
// Escape closes the native dialog before `close` fires; block it here,
|
|
109
|
+
// otherwise the dialog closes while `show` stays true
|
|
110
|
+
if (!allowImplicitClose) e.preventDefault();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function onNativeClose() {
|
|
114
|
+
// The dialog has already closed natively (Escape, form method="dialog");
|
|
115
|
+
// sync `show` unconditionally so it can be reopened
|
|
116
|
+
show = false;
|
|
117
|
+
}
|
|
80
118
|
|
|
81
|
-
function
|
|
119
|
+
function onBackdropMousedown() {
|
|
82
120
|
if (allowImplicitClose) show = false;
|
|
83
121
|
}
|
|
84
122
|
|
|
85
|
-
function
|
|
86
|
-
|
|
123
|
+
function stopMousedown(e: Event) {
|
|
124
|
+
// Keep mousedowns inside the dialog from reaching the backdrop handler
|
|
125
|
+
e.stopPropagation();
|
|
87
126
|
}
|
|
88
127
|
</script>
|
|
89
128
|
|
|
90
129
|
{#snippet DialogInner()}
|
|
91
130
|
{#if title}
|
|
92
131
|
<div class="dialog-title">
|
|
93
|
-
<span class="font-bold">{title}</span>
|
|
132
|
+
<span id={titleId} class="font-bold">{title}</span>
|
|
94
133
|
{#if allowImplicitClose}
|
|
95
134
|
<ActionIcon
|
|
96
|
-
onclick={
|
|
135
|
+
onclick={() => (show = false)}
|
|
97
136
|
variant="secondary-subtle"
|
|
98
137
|
class="flex !p-[0.3rem] mr-1 !leading-0"
|
|
99
138
|
svg={iconX}
|
|
100
139
|
size="1rem"
|
|
140
|
+
ariaLabel="Close dialog"
|
|
101
141
|
/>
|
|
102
142
|
{/if}
|
|
103
143
|
</div>
|
|
104
144
|
{/if}
|
|
105
|
-
<div
|
|
106
|
-
class="dialog-body
|
|
107
|
-
{preventOverflow ? 'overflow-y-auto' : 'overflow-visible'}
|
|
108
|
-
{!footer && 'no-footer'}"
|
|
109
|
-
>
|
|
145
|
+
<div class="dialog-body {preventOverflow ? 'overflow-y-auto' : 'overflow-visible'}">
|
|
110
146
|
{@render children?.()}
|
|
111
147
|
</div>
|
|
112
148
|
{#if footer}
|
|
113
|
-
<div class="dialog-footer"
|
|
149
|
+
<div class="dialog-footer">
|
|
114
150
|
{@render footer?.()}
|
|
115
151
|
</div>
|
|
116
152
|
{/if}
|
|
117
153
|
{/snippet}
|
|
118
154
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
155
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
156
|
+
<dialog
|
|
157
|
+
bind:this={dialogElement}
|
|
158
|
+
oncancel={onCancel}
|
|
159
|
+
onclose={onNativeClose}
|
|
160
|
+
onmousedown={onBackdropMousedown}
|
|
161
|
+
class={`dialog ${size}`}
|
|
162
|
+
aria-labelledby={title ? titleId : undefined}
|
|
163
|
+
>
|
|
164
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
165
|
+
<div
|
|
166
|
+
class="dialog-inner {noPaper ? `${classes} dialog-no-paper` : ''}"
|
|
167
|
+
onmousedown={stopMousedown}
|
|
126
168
|
>
|
|
127
|
-
|
|
128
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
129
|
-
<div
|
|
130
|
-
class="dialog-inner {classes} dialog-no-paper"
|
|
131
|
-
onclick={cancel}
|
|
132
|
-
onmousedown={cancel}
|
|
133
|
-
onmouseup={cancel}
|
|
134
|
-
>
|
|
169
|
+
{#if noPaper}
|
|
135
170
|
{@render DialogInner()}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{:else}
|
|
139
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
140
|
-
<dialog
|
|
141
|
-
bind:this={dialogElement}
|
|
142
|
-
onclose={onClose}
|
|
143
|
-
onmousedown={onClose}
|
|
144
|
-
class={`dialog ${size}`}
|
|
145
|
-
>
|
|
146
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
147
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
148
|
-
<div class="dialog-inner" onclick={cancel} onmousedown={cancel} onmouseup={cancel}>
|
|
149
|
-
<div class="dialog-paper {preventOverflow ? 'overflow-y-auto' : 'overflow-visible'} ">
|
|
171
|
+
{:else}
|
|
172
|
+
<div class="dialog-paper {preventOverflow ? 'overflow-y-auto' : 'overflow-visible'}">
|
|
150
173
|
<Paper containerClass={classes}>
|
|
151
174
|
{@render DialogInner()}
|
|
152
175
|
</Paper>
|
|
153
176
|
</div>
|
|
154
|
-
|
|
155
|
-
</
|
|
156
|
-
|
|
177
|
+
{/if}
|
|
178
|
+
</div>
|
|
179
|
+
</dialog>
|
|
157
180
|
|
|
158
181
|
<style>
|
|
182
|
+
/* Animate transform, not margin — the native dialog centers itself via
|
|
183
|
+
`margin: auto`, and a margin animation with `forwards` fill would
|
|
184
|
+
permanently override it and pin the dialog to the top of the viewport */
|
|
159
185
|
@keyframes fadeIn {
|
|
160
186
|
from {
|
|
161
187
|
opacity: 0;
|
|
162
|
-
transform: translateY(-
|
|
188
|
+
transform: translateY(-0.5rem);
|
|
163
189
|
}
|
|
164
190
|
to {
|
|
165
191
|
opacity: 1;
|
|
166
|
-
transform: translateY(
|
|
192
|
+
transform: translateY(0);
|
|
167
193
|
}
|
|
168
194
|
}
|
|
169
195
|
@keyframes fadeOut {
|
|
170
196
|
from {
|
|
171
197
|
opacity: 1;
|
|
172
|
-
transform: translateY(
|
|
198
|
+
transform: translateY(0);
|
|
199
|
+
}
|
|
200
|
+
to {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
transform: translateY(-0.5rem);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@keyframes fadeInFull {
|
|
207
|
+
from {
|
|
208
|
+
opacity: 0;
|
|
209
|
+
}
|
|
210
|
+
to {
|
|
211
|
+
opacity: 1;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
@keyframes fadeOutFull {
|
|
215
|
+
from {
|
|
216
|
+
opacity: 1;
|
|
173
217
|
}
|
|
174
218
|
to {
|
|
175
219
|
opacity: 0;
|
|
176
|
-
transform: translateY(-1em);
|
|
177
220
|
}
|
|
178
221
|
}
|
|
179
222
|
|
|
@@ -196,58 +239,79 @@
|
|
|
196
239
|
}
|
|
197
240
|
|
|
198
241
|
dialog {
|
|
199
|
-
color: var(--
|
|
242
|
+
color: var(--text-color);
|
|
200
243
|
border: none;
|
|
244
|
+
/* The dialog element itself is focused by showModal(); don't draw a
|
|
245
|
+
focus ring around the whole dialog */
|
|
246
|
+
outline: none;
|
|
201
247
|
background-color: transparent;
|
|
202
248
|
overflow: visible;
|
|
203
249
|
margin: auto;
|
|
204
|
-
|
|
205
|
-
|
|
250
|
+
max-width: min(calc(100vw - 2rem), calc(100% - 6px));
|
|
251
|
+
/* Cap to the visible viewport with equal margins; the flex chain below
|
|
252
|
+
(dialog > inner > paper > body, each min-height: 0) passes this limit
|
|
253
|
+
down so the body shrinks instead of spilling past the bottom edge.
|
|
254
|
+
dvh tracks the visible viewport on iOS Safari (100vh includes the
|
|
255
|
+
area behind the collapsible URL bar); vh is the older-browser fallback */
|
|
256
|
+
max-height: calc(100vh - 2rem);
|
|
257
|
+
max-height: calc(100dvh - 2rem);
|
|
258
|
+
|
|
259
|
+
animation: fadeOut 0.2s forwards;
|
|
206
260
|
transition:
|
|
207
|
-
display
|
|
208
|
-
overlay
|
|
261
|
+
display 0.2s allow-discrete,
|
|
262
|
+
overlay 0.2s allow-discrete;
|
|
209
263
|
&::backdrop {
|
|
210
|
-
animation: backdropFadeOut
|
|
264
|
+
animation: backdropFadeOut 0.2s forwards;
|
|
211
265
|
}
|
|
212
266
|
&[open] {
|
|
213
|
-
|
|
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
|
+
flex-direction: column;
|
|
271
|
+
animation: fadeIn 0.2s forwards;
|
|
214
272
|
&::backdrop {
|
|
215
|
-
animation: backdropFadeIn
|
|
273
|
+
animation: backdropFadeIn 0.2s forwards;
|
|
216
274
|
}
|
|
217
275
|
}
|
|
218
276
|
}
|
|
219
277
|
|
|
278
|
+
.dialog-inner {
|
|
279
|
+
display: flex;
|
|
280
|
+
flex-direction: column;
|
|
281
|
+
min-height: 0;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* Paper sits inside the height chain; .paper-body already has an inline
|
|
285
|
+
min-height: 0, so only .paper needs the shrink link */
|
|
286
|
+
.dialog :global(.paper) {
|
|
287
|
+
min-height: 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
220
290
|
.dialog-title {
|
|
221
291
|
display: flex;
|
|
222
292
|
justify-content: space-between;
|
|
223
|
-
margin-bottom:
|
|
224
|
-
padding-bottom:
|
|
225
|
-
border-bottom: 1px solid var(--
|
|
226
|
-
font-weight:
|
|
293
|
+
margin-bottom: 0.5rem;
|
|
294
|
+
padding-bottom: 0.25rem;
|
|
295
|
+
border-bottom: 1px solid var(--border-color);
|
|
296
|
+
font-weight: 600;
|
|
297
|
+
flex-shrink: 0;
|
|
227
298
|
}
|
|
228
299
|
|
|
229
300
|
.dialog-body {
|
|
230
301
|
display: flex;
|
|
231
302
|
flex-direction: column;
|
|
232
303
|
min-width: 0;
|
|
304
|
+
min-height: 0;
|
|
233
305
|
flex-shrink: 1;
|
|
234
|
-
max-height: calc(100vh - 167px);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.dialog-body.no-footer {
|
|
238
|
-
max-height: calc(100vh - 107px);
|
|
239
306
|
}
|
|
240
307
|
|
|
241
308
|
.dialog-footer {
|
|
242
309
|
display: flex;
|
|
243
|
-
justify-content: flex-end;
|
|
244
|
-
padding: var(--pui-spacing-2) 0;
|
|
245
|
-
border-top: 1px solid var(--pui-border-default);
|
|
246
|
-
gap: var(--pui-spacing-2);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
.dialog-footer.footer-between {
|
|
250
310
|
justify-content: space-between;
|
|
311
|
+
padding-top: 0.5rem;
|
|
312
|
+
border-top: 1px solid var(--border-color);
|
|
313
|
+
gap: 0.5rem;
|
|
314
|
+
flex-shrink: 0;
|
|
251
315
|
}
|
|
252
316
|
|
|
253
317
|
.overflow-visible {
|
|
@@ -259,7 +323,7 @@
|
|
|
259
323
|
}
|
|
260
324
|
|
|
261
325
|
.dialog-no-paper {
|
|
262
|
-
padding:
|
|
326
|
+
padding: 1rem;
|
|
263
327
|
}
|
|
264
328
|
|
|
265
329
|
.dialog-paper,
|
|
@@ -267,17 +331,18 @@
|
|
|
267
331
|
display: flex;
|
|
268
332
|
flex-direction: column;
|
|
269
333
|
box-sizing: border-box;
|
|
270
|
-
border-radius:
|
|
271
|
-
background:
|
|
334
|
+
border-radius: 0.25rem;
|
|
335
|
+
background: #f1f3f5;
|
|
336
|
+
min-height: 0;
|
|
272
337
|
}
|
|
273
338
|
|
|
274
339
|
:global(.dark .dialog-paper),
|
|
275
340
|
:global(.dark .dialog-no-paper) {
|
|
276
|
-
background-color:
|
|
341
|
+
background-color: rgb(33, 34, 38);
|
|
277
342
|
}
|
|
278
343
|
|
|
279
344
|
dialog::backdrop {
|
|
280
|
-
background-color:
|
|
345
|
+
background-color: #0008;
|
|
281
346
|
}
|
|
282
347
|
|
|
283
348
|
.dialog.sm {
|
|
@@ -298,13 +363,20 @@
|
|
|
298
363
|
|
|
299
364
|
.dialog.full {
|
|
300
365
|
width: 100%;
|
|
366
|
+
max-width: 100%;
|
|
367
|
+
max-height: 100%;
|
|
301
368
|
margin-top: auto;
|
|
369
|
+
animation: fadeOutFull 0.2s forwards;
|
|
370
|
+
|
|
371
|
+
&[open] {
|
|
372
|
+
animation: fadeInFull 0.2s forwards;
|
|
373
|
+
}
|
|
302
374
|
}
|
|
303
375
|
|
|
304
376
|
.dialog.full,
|
|
305
377
|
.dialog.full .dialog-inner,
|
|
306
378
|
.dialog.full :global(.paper),
|
|
307
|
-
.dialog.full
|
|
379
|
+
.dialog.full .dialog-paper {
|
|
308
380
|
height: 100%;
|
|
309
381
|
}
|
|
310
382
|
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
interface
|
|
2
|
+
export interface DialogContext {
|
|
3
|
+
/** Whether the dialog is currently open (reactive) */
|
|
4
|
+
readonly isOpen: boolean;
|
|
5
|
+
/** Register a callback invoked each time the dialog opens */
|
|
6
|
+
onOpen: (callback: () => void) => void;
|
|
7
|
+
/** Register a callback invoked each time the dialog closes */
|
|
8
|
+
onClose: (callback: () => void) => void;
|
|
9
|
+
/** Register a callback invoked only the first time the dialog opens */
|
|
10
|
+
onFirstOpen: (callback: () => void) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface DialogProps {
|
|
13
|
+
/** Whether the dialog is visible (bindable) */
|
|
3
14
|
show: boolean;
|
|
15
|
+
/** Allow closing by clicking backdrop or pressing Escape */
|
|
4
16
|
allowImplicitClose?: boolean;
|
|
17
|
+
/** Dialog title displayed in the header */
|
|
5
18
|
title?: string | undefined;
|
|
19
|
+
/** Render without the Paper wrapper component */
|
|
6
20
|
noPaper?: boolean;
|
|
21
|
+
/** Prevent content from overflowing the dialog bounds */
|
|
7
22
|
preventOverflow?: boolean;
|
|
23
|
+
/** Size preset for the dialog width */
|
|
8
24
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
25
|
+
/** Additional CSS classes */
|
|
9
26
|
class?: string;
|
|
10
|
-
/**
|
|
11
|
-
footerBetween?: boolean;
|
|
27
|
+
/** Footer content (typically action buttons) */
|
|
12
28
|
footer?: Snippet;
|
|
29
|
+
/** Main dialog content */
|
|
13
30
|
children?: Snippet;
|
|
14
31
|
}
|
|
15
|
-
declare const Dialog: import("svelte").Component<
|
|
32
|
+
declare const Dialog: import("svelte").Component<DialogProps, {}, "show">;
|
|
16
33
|
type Dialog = ReturnType<typeof Dialog>;
|
|
17
34
|
export default Dialog;
|