@placeholderco/placeholder-ui 1.0.12 → 2.0.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/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 +87 -26
- package/dist/index.js +25 -28
- 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/Dropdown.svelte
CHANGED
|
@@ -1,31 +1,41 @@
|
|
|
1
1
|
<!-- drop down component that displays a button, when clicked on the children expand -->
|
|
2
2
|
<script lang="ts">
|
|
3
3
|
import Button from './Button.svelte';
|
|
4
|
+
import type { ButtonVariant } from './ButtonVariant.js';
|
|
4
5
|
import type { Hyperlink } from '../models/Hyperlink.js';
|
|
5
6
|
import LinkCollection from '../display/LinkCollection.svelte';
|
|
6
7
|
import { iconChevronDown } from '../icon/index.js';
|
|
7
8
|
|
|
8
|
-
interface
|
|
9
|
+
export interface DropdownProps {
|
|
10
|
+
/** Whether the dropdown is expanded (bindable) */
|
|
9
11
|
show?: boolean;
|
|
12
|
+
/** Text label for the trigger button */
|
|
10
13
|
label: string | undefined;
|
|
14
|
+
/** Visual style variant of the trigger button */
|
|
15
|
+
variant?: ButtonVariant;
|
|
16
|
+
/** SVG icon for the trigger button */
|
|
11
17
|
buttonSvg?: string | undefined;
|
|
18
|
+
/** Navigation links to display (flat array or grouped arrays) */
|
|
12
19
|
links?: Hyperlink[] | Hyperlink[][];
|
|
20
|
+
/** Additional CSS classes */
|
|
13
21
|
class?: string;
|
|
22
|
+
/** Horizontal alignment of dropdown content relative to button */
|
|
14
23
|
alignToButton?: 'left' | 'right';
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
let {
|
|
18
27
|
show = $bindable(false),
|
|
19
28
|
label,
|
|
29
|
+
variant = 'primary',
|
|
20
30
|
buttonSvg = iconChevronDown,
|
|
21
31
|
links = [],
|
|
22
32
|
class: classes = '',
|
|
23
33
|
alignToButton = 'left'
|
|
24
|
-
}:
|
|
34
|
+
}: DropdownProps = $props();
|
|
25
35
|
</script>
|
|
26
36
|
|
|
27
37
|
<div class="dropdown {classes} {alignToButton}">
|
|
28
|
-
<Button class="ps-2" svg={buttonSvg} onclick={() => (show = !show)}>
|
|
38
|
+
<Button class="ps-2" {variant} svg={buttonSvg} onclick={() => (show = !show)}>
|
|
29
39
|
{label}
|
|
30
40
|
</Button>
|
|
31
41
|
{#if show}
|
|
@@ -54,13 +64,13 @@
|
|
|
54
64
|
position: absolute;
|
|
55
65
|
top: 100%;
|
|
56
66
|
left: 0;
|
|
57
|
-
background-color: var(--
|
|
67
|
+
background-color: var(--paper-body-bg);
|
|
58
68
|
min-width: 160px;
|
|
59
|
-
box-shadow:
|
|
60
|
-
z-index:
|
|
61
|
-
border-radius:
|
|
69
|
+
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
|
|
70
|
+
z-index: 1000;
|
|
71
|
+
border-radius: 4px;
|
|
62
72
|
overflow: hidden;
|
|
63
|
-
border: 1px solid var(--
|
|
73
|
+
border: 1px solid var(--border-color);
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
.dropdown-group {
|
|
@@ -69,19 +79,19 @@
|
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
.dropdown-group:not(:last-child) {
|
|
72
|
-
border-bottom: 1px solid var(--
|
|
82
|
+
border-bottom: 1px solid var(--border-color);
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
.dropdown-content :global(a) {
|
|
76
86
|
display: block;
|
|
77
|
-
padding:
|
|
87
|
+
padding: 8px 12px;
|
|
78
88
|
text-decoration: none;
|
|
79
|
-
color: var(--
|
|
80
|
-
transition: background-color
|
|
89
|
+
color: var(--ui-primary);
|
|
90
|
+
transition: background-color 0.2s ease;
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
.dropdown-content :global(a:hover) {
|
|
84
|
-
background-color: var(--
|
|
94
|
+
background-color: var(--border-color);
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
.dropdown.right .dropdown-content {
|
|
@@ -91,7 +101,7 @@
|
|
|
91
101
|
|
|
92
102
|
:global(.dark) {
|
|
93
103
|
.dropdown-content :global(a) {
|
|
94
|
-
color: var(--
|
|
104
|
+
color: var(--ui-accent);
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
107
|
</style>
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
+
import type { ButtonVariant } from './ButtonVariant.js';
|
|
1
2
|
import type { Hyperlink } from '../models/Hyperlink.js';
|
|
2
|
-
interface
|
|
3
|
+
export interface DropdownProps {
|
|
4
|
+
/** Whether the dropdown is expanded (bindable) */
|
|
3
5
|
show?: boolean;
|
|
6
|
+
/** Text label for the trigger button */
|
|
4
7
|
label: string | undefined;
|
|
8
|
+
/** Visual style variant of the trigger button */
|
|
9
|
+
variant?: ButtonVariant;
|
|
10
|
+
/** SVG icon for the trigger button */
|
|
5
11
|
buttonSvg?: string | undefined;
|
|
12
|
+
/** Navigation links to display (flat array or grouped arrays) */
|
|
6
13
|
links?: Hyperlink[] | Hyperlink[][];
|
|
14
|
+
/** Additional CSS classes */
|
|
7
15
|
class?: string;
|
|
16
|
+
/** Horizontal alignment of dropdown content relative to button */
|
|
8
17
|
alignToButton?: 'left' | 'right';
|
|
9
18
|
}
|
|
10
|
-
declare const Dropdown: import("svelte").Component<
|
|
19
|
+
declare const Dropdown: import("svelte").Component<DropdownProps, {}, "show">;
|
|
11
20
|
type Dropdown = ReturnType<typeof Dropdown>;
|
|
12
21
|
export default Dropdown;
|
package/dist/ui/Dropzone.svelte
CHANGED
|
@@ -1,122 +1,224 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
3
|
import Loader from './Loader.svelte';
|
|
4
|
+
import Icon from '../icon/Icon.svelte';
|
|
5
|
+
import iconCloudUpload from '../icon/cloud-upload.svg?raw';
|
|
6
|
+
import iconDownload from '../icon/download.svg?raw';
|
|
4
7
|
|
|
5
|
-
interface
|
|
8
|
+
export interface DropzoneProps {
|
|
9
|
+
/** Show loading state */
|
|
6
10
|
loading?: boolean;
|
|
11
|
+
/** Disable the dropzone without showing the loading state */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Allow multiple file selection */
|
|
7
14
|
multiple?: boolean;
|
|
15
|
+
/** Callback when valid files are dropped or selected */
|
|
8
16
|
onFileSubmit: (files: File[]) => void;
|
|
17
|
+
/** Callback with files rejected by accept, maxSize or maxFiles validation */
|
|
18
|
+
onReject?: (files: File[]) => void;
|
|
19
|
+
/** Accepted file types (e.g., "image/*,.pdf") */
|
|
9
20
|
accept?: string;
|
|
21
|
+
/** Maximum file size in bytes */
|
|
22
|
+
maxSize?: number;
|
|
23
|
+
/** Maximum number of files per drop or selection (only applies when multiple) */
|
|
24
|
+
maxFiles?: number;
|
|
25
|
+
/** Icon shown above the label (raw SVG string, defaults to the cloud upload icon) */
|
|
26
|
+
icon?: string;
|
|
27
|
+
/** Icon shown while files are dragged over (raw SVG string, defaults to the download icon) */
|
|
28
|
+
dragOverIcon?: string;
|
|
29
|
+
/** Label text (defaults to "Click to upload or drag and drop") */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** Sublabel text under the label (defaults to a hint built from accept/maxSize) */
|
|
32
|
+
sublabel?: string;
|
|
33
|
+
/** Width override (any CSS width value, defaults to 100%) */
|
|
34
|
+
width?: string;
|
|
35
|
+
/** Height override (any CSS height value) */
|
|
36
|
+
height?: string;
|
|
37
|
+
/** Custom content rendered inside the dropzone instead of the label */
|
|
38
|
+
children?: Snippet;
|
|
10
39
|
}
|
|
11
40
|
|
|
12
|
-
let {
|
|
41
|
+
let {
|
|
42
|
+
loading = false,
|
|
43
|
+
disabled = false,
|
|
44
|
+
multiple = false,
|
|
45
|
+
onFileSubmit,
|
|
46
|
+
onReject,
|
|
47
|
+
accept,
|
|
48
|
+
maxSize,
|
|
49
|
+
maxFiles,
|
|
50
|
+
icon = iconCloudUpload,
|
|
51
|
+
dragOverIcon = iconDownload,
|
|
52
|
+
label,
|
|
53
|
+
sublabel,
|
|
54
|
+
width,
|
|
55
|
+
height,
|
|
56
|
+
children
|
|
57
|
+
}: DropzoneProps = $props();
|
|
13
58
|
|
|
14
|
-
let dragzoneElement: HTMLElement;
|
|
15
59
|
let fileInput: HTMLInputElement;
|
|
16
|
-
|
|
17
|
-
let
|
|
60
|
+
// Counter instead of a boolean: dragleave fires when crossing child elements
|
|
61
|
+
let dragDepth = $state(0);
|
|
62
|
+
let dragOver = $derived(dragDepth > 0);
|
|
63
|
+
let labelText = $derived(
|
|
64
|
+
dragOver ? 'Drop files here' : label || 'Click to upload or drag and drop'
|
|
65
|
+
);
|
|
66
|
+
let iconSvg = $derived(dragOver ? dragOverIcon : icon);
|
|
67
|
+
let sublabelText = $derived.by(() => {
|
|
68
|
+
if (sublabel !== undefined) return sublabel;
|
|
69
|
+
const hints = [];
|
|
70
|
+
if (accept) hints.push(accept);
|
|
71
|
+
if (maxSize) hints.push(`up to ${formatBytes(maxSize)}`);
|
|
72
|
+
return hints.length ? hints.join(' · ') : '';
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
function formatBytes(bytes: number): string {
|
|
76
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
77
|
+
const units = ['KB', 'MB', 'GB'];
|
|
78
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length);
|
|
79
|
+
return `${parseFloat((bytes / Math.pow(1024, i)).toFixed(1))} ${units[i - 1]}`;
|
|
80
|
+
}
|
|
18
81
|
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
|
|
82
|
+
function matchesAccept(file: File): boolean {
|
|
83
|
+
if (!accept) return true;
|
|
84
|
+
return accept.split(',').some((token) => {
|
|
85
|
+
const type = token.trim().toLowerCase();
|
|
86
|
+
if (!type) return false;
|
|
87
|
+
if (type === '*/*') return true;
|
|
88
|
+
if (type.startsWith('.')) return file.name.toLowerCase().endsWith(type);
|
|
89
|
+
if (type.endsWith('/*')) return file.type.toLowerCase().startsWith(type.slice(0, -1));
|
|
90
|
+
return file.type.toLowerCase() === type;
|
|
91
|
+
});
|
|
22
92
|
}
|
|
23
93
|
|
|
24
|
-
function
|
|
25
|
-
|
|
94
|
+
function submitFiles(files: File[]) {
|
|
95
|
+
let accepted = files.filter(
|
|
96
|
+
(file) => matchesAccept(file) && (!maxSize || file.size <= maxSize)
|
|
97
|
+
);
|
|
98
|
+
let rejected = files.filter((file) => !accepted.includes(file));
|
|
99
|
+
|
|
100
|
+
const limit = multiple ? maxFiles : 1;
|
|
101
|
+
if (limit && accepted.length > limit) {
|
|
102
|
+
rejected = [...rejected, ...accepted.slice(limit)];
|
|
103
|
+
accepted = accepted.slice(0, limit);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (accepted.length) onFileSubmit(accepted);
|
|
107
|
+
if (rejected.length) onReject?.(rejected);
|
|
26
108
|
}
|
|
27
109
|
|
|
28
|
-
function
|
|
110
|
+
function handleDrop(event: DragEvent) {
|
|
29
111
|
event.preventDefault();
|
|
112
|
+
dragDepth = 0;
|
|
113
|
+
if (loading || disabled) return;
|
|
30
114
|
const files = event.dataTransfer?.files;
|
|
31
|
-
if (files)
|
|
32
|
-
let array = Array.from(files);
|
|
33
|
-
|
|
34
|
-
if (!multiple && array.length > 1) array = [array[0]];
|
|
35
|
-
|
|
36
|
-
handleFileSubmission(array);
|
|
37
|
-
}
|
|
38
|
-
dragOver = false;
|
|
115
|
+
if (files?.length) submitFiles(Array.from(files));
|
|
39
116
|
}
|
|
40
117
|
|
|
41
|
-
function
|
|
118
|
+
function handleDragEnter(event: DragEvent) {
|
|
42
119
|
event.preventDefault();
|
|
43
|
-
|
|
120
|
+
dragDepth++;
|
|
44
121
|
}
|
|
45
122
|
|
|
46
123
|
function handleDragLeave(event: DragEvent) {
|
|
47
124
|
event.preventDefault();
|
|
48
|
-
|
|
125
|
+
dragDepth = Math.max(0, dragDepth - 1);
|
|
49
126
|
}
|
|
50
127
|
|
|
51
128
|
function handleInputChange(event: Event) {
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
toast.error('No file selected');
|
|
57
|
-
}
|
|
129
|
+
const input = event.currentTarget as HTMLInputElement;
|
|
130
|
+
if (input.files?.length) submitFiles(Array.from(input.files));
|
|
131
|
+
// Reset so selecting the same file again re-fires change
|
|
132
|
+
input.value = '';
|
|
58
133
|
}
|
|
59
134
|
</script>
|
|
60
135
|
|
|
61
136
|
<input
|
|
62
137
|
type="file"
|
|
63
|
-
|
|
64
|
-
|
|
138
|
+
{multiple}
|
|
139
|
+
{accept}
|
|
65
140
|
onchange={handleInputChange}
|
|
66
141
|
bind:this={fileInput}
|
|
67
142
|
class="hidden"
|
|
68
|
-
accept={accept ? accept : '*.*'}
|
|
69
143
|
/>
|
|
70
144
|
<button
|
|
71
|
-
|
|
145
|
+
type="button"
|
|
72
146
|
class="dropzone"
|
|
73
147
|
class:dragover={dragOver}
|
|
74
|
-
|
|
75
|
-
|
|
148
|
+
style:width
|
|
149
|
+
style:height
|
|
150
|
+
disabled={loading || disabled}
|
|
151
|
+
aria-busy={loading}
|
|
152
|
+
aria-label={labelText}
|
|
153
|
+
ondragenter={handleDragEnter}
|
|
76
154
|
ondragover={(ev) => ev.preventDefault()}
|
|
77
155
|
ondragleave={handleDragLeave}
|
|
78
|
-
ondrop={
|
|
79
|
-
onclick={(
|
|
156
|
+
ondrop={handleDrop}
|
|
157
|
+
onclick={() => fileInput.click()}
|
|
80
158
|
>
|
|
81
159
|
{#if loading}
|
|
82
160
|
<Loader fullScreen />
|
|
161
|
+
{:else if children}
|
|
162
|
+
{@render children()}
|
|
83
163
|
{:else}
|
|
84
|
-
|
|
164
|
+
<span class="dropzone-content">
|
|
165
|
+
<Icon svg={iconSvg} size="32px" class="dropzone-icon" />
|
|
166
|
+
<span class="dropzone-label">{labelText}</span>
|
|
167
|
+
{#if sublabelText}
|
|
168
|
+
<span class="dropzone-sublabel">{sublabelText}</span>
|
|
169
|
+
{/if}
|
|
170
|
+
</span>
|
|
85
171
|
{/if}
|
|
86
172
|
</button>
|
|
87
173
|
|
|
88
174
|
<style>
|
|
89
175
|
.dropzone {
|
|
90
|
-
|
|
91
|
-
|
|
176
|
+
width: 100%;
|
|
177
|
+
border: 1px dashed var(--border-color);
|
|
178
|
+
padding: 1rem;
|
|
92
179
|
text-align: center;
|
|
93
180
|
cursor: pointer;
|
|
94
|
-
transition: all
|
|
95
|
-
border-radius:
|
|
181
|
+
transition: all 0.2s ease-in-out;
|
|
182
|
+
border-radius: 6px;
|
|
96
183
|
flex-grow: 1;
|
|
97
|
-
background
|
|
98
|
-
color: var(--
|
|
184
|
+
background: var(--paper-body-bg);
|
|
185
|
+
color: var(--text-color);
|
|
99
186
|
}
|
|
100
187
|
|
|
101
|
-
.dropzone:hover,
|
|
188
|
+
.dropzone:hover:not(:disabled),
|
|
102
189
|
.dropzone.dragover {
|
|
103
|
-
background
|
|
104
|
-
border-color: var(--pui-color-primary);
|
|
190
|
+
background: var(--page-bg);
|
|
105
191
|
}
|
|
106
192
|
|
|
107
|
-
.
|
|
108
|
-
|
|
193
|
+
.dropzone:disabled {
|
|
194
|
+
cursor: not-allowed;
|
|
195
|
+
opacity: 0.65;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.dropzone-content {
|
|
199
|
+
display: flex;
|
|
200
|
+
flex-direction: column;
|
|
201
|
+
align-items: center;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
gap: 0.25rem;
|
|
204
|
+
height: 100%;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.dropzone-content :global(.dropzone-icon) {
|
|
208
|
+
opacity: 0.65;
|
|
209
|
+
margin-bottom: 0.25rem;
|
|
109
210
|
}
|
|
110
211
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
border-color: var(--pui-border-default);
|
|
114
|
-
color: var(--pui-text-primary);
|
|
212
|
+
.dropzone-label {
|
|
213
|
+
font-weight: 500;
|
|
115
214
|
}
|
|
116
215
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
216
|
+
.dropzone-sublabel {
|
|
217
|
+
font-size: 0.8125rem;
|
|
218
|
+
opacity: 0.65;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.hidden {
|
|
222
|
+
display: none;
|
|
121
223
|
}
|
|
122
224
|
</style>
|
|
@@ -1,9 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export interface DropzoneProps {
|
|
3
|
+
/** Show loading state */
|
|
2
4
|
loading?: boolean;
|
|
5
|
+
/** Disable the dropzone without showing the loading state */
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** Allow multiple file selection */
|
|
3
8
|
multiple?: boolean;
|
|
9
|
+
/** Callback when valid files are dropped or selected */
|
|
4
10
|
onFileSubmit: (files: File[]) => void;
|
|
11
|
+
/** Callback with files rejected by accept, maxSize or maxFiles validation */
|
|
12
|
+
onReject?: (files: File[]) => void;
|
|
13
|
+
/** Accepted file types (e.g., "image/*,.pdf") */
|
|
5
14
|
accept?: string;
|
|
15
|
+
/** Maximum file size in bytes */
|
|
16
|
+
maxSize?: number;
|
|
17
|
+
/** Maximum number of files per drop or selection (only applies when multiple) */
|
|
18
|
+
maxFiles?: number;
|
|
19
|
+
/** Icon shown above the label (raw SVG string, defaults to the cloud upload icon) */
|
|
20
|
+
icon?: string;
|
|
21
|
+
/** Icon shown while files are dragged over (raw SVG string, defaults to the download icon) */
|
|
22
|
+
dragOverIcon?: string;
|
|
23
|
+
/** Label text (defaults to "Click to upload or drag and drop") */
|
|
24
|
+
label?: string;
|
|
25
|
+
/** Sublabel text under the label (defaults to a hint built from accept/maxSize) */
|
|
26
|
+
sublabel?: string;
|
|
27
|
+
/** Width override (any CSS width value, defaults to 100%) */
|
|
28
|
+
width?: string;
|
|
29
|
+
/** Height override (any CSS height value) */
|
|
30
|
+
height?: string;
|
|
31
|
+
/** Custom content rendered inside the dropzone instead of the label */
|
|
32
|
+
children?: Snippet;
|
|
6
33
|
}
|
|
7
|
-
declare const Dropzone: import("svelte").Component<
|
|
34
|
+
declare const Dropzone: import("svelte").Component<DropzoneProps, {}, "">;
|
|
8
35
|
type Dropzone = ReturnType<typeof Dropzone>;
|
|
9
36
|
export default Dropzone;
|
package/dist/ui/Link.svelte
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { resolve } from '$app/paths';
|
|
3
|
+
import { interceptLinkClick } from '../util/interceptLinkClick.js';
|
|
2
4
|
import type { Snippet } from 'svelte';
|
|
3
5
|
|
|
4
|
-
interface
|
|
6
|
+
export interface LinkProps {
|
|
7
|
+
/** URL to navigate to */
|
|
5
8
|
href?: string;
|
|
9
|
+
/** Relationship attribute for the link */
|
|
6
10
|
rel?: string;
|
|
11
|
+
/** Link target attribute */
|
|
7
12
|
target?: '_self' | '_blank' | undefined;
|
|
13
|
+
/** Additional CSS classes */
|
|
8
14
|
class?: string;
|
|
15
|
+
/** Link content */
|
|
9
16
|
children?: Snippet;
|
|
17
|
+
/** Click event handler */
|
|
10
18
|
onclick?: (event: MouseEvent) => void;
|
|
11
19
|
}
|
|
12
20
|
|
|
@@ -17,15 +25,15 @@
|
|
|
17
25
|
class: classes = '',
|
|
18
26
|
children,
|
|
19
27
|
onclick
|
|
20
|
-
}:
|
|
28
|
+
}: LinkProps = $props();
|
|
21
29
|
</script>
|
|
22
30
|
|
|
23
31
|
<a
|
|
24
32
|
{target}
|
|
25
33
|
class={classes}
|
|
26
|
-
{href}
|
|
34
|
+
href={href?.startsWith('/') ? resolve(href as any) : href}
|
|
27
35
|
{rel}
|
|
28
|
-
{onclick}
|
|
36
|
+
onclick={(e) => interceptLinkClick(e, { href, target, onclick })}
|
|
29
37
|
data-sveltekit-preload-data="hover"
|
|
30
38
|
>
|
|
31
39
|
{@render children?.()}
|
package/dist/ui/Link.svelte.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
interface
|
|
2
|
+
export interface LinkProps {
|
|
3
|
+
/** URL to navigate to */
|
|
3
4
|
href?: string;
|
|
5
|
+
/** Relationship attribute for the link */
|
|
4
6
|
rel?: string;
|
|
7
|
+
/** Link target attribute */
|
|
5
8
|
target?: '_self' | '_blank' | undefined;
|
|
9
|
+
/** Additional CSS classes */
|
|
6
10
|
class?: string;
|
|
11
|
+
/** Link content */
|
|
7
12
|
children?: Snippet;
|
|
13
|
+
/** Click event handler */
|
|
8
14
|
onclick?: (event: MouseEvent) => void;
|
|
9
15
|
}
|
|
10
|
-
declare const Link: import("svelte").Component<
|
|
16
|
+
declare const Link: import("svelte").Component<LinkProps, {}, "">;
|
|
11
17
|
type Link = ReturnType<typeof Link>;
|
|
12
18
|
export default Link;
|
package/dist/ui/Loader.svelte
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
import Icon from '../icon/Icon.svelte';
|
|
3
3
|
import loaderSvg from '../icon/loader.svg?raw';
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
export interface LoaderProps {
|
|
6
|
+
/** Display as full-screen overlay */
|
|
6
7
|
fullScreen?: boolean;
|
|
8
|
+
/** Custom size for the loader icon */
|
|
7
9
|
sizeOverride?: string;
|
|
10
|
+
/** Additional CSS classes */
|
|
8
11
|
class?: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
let { fullScreen = false, sizeOverride = '50px', class: classes = '' }:
|
|
14
|
+
let { fullScreen = false, sizeOverride = '50px', class: classes = '' }: LoaderProps = $props();
|
|
12
15
|
|
|
13
16
|
// export let fullScreen: boolean = false;
|
|
14
17
|
// export let sizeOverride: string = '50px';
|
|
@@ -17,22 +20,11 @@
|
|
|
17
20
|
// export { classes as class };
|
|
18
21
|
</script>
|
|
19
22
|
|
|
20
|
-
<span class="loader {classes} {fullScreen && 'full-screen'}">
|
|
23
|
+
<span class="loader flex {classes} {fullScreen && 'full-screen'}">
|
|
21
24
|
<Icon size={sizeOverride} class="spin" svg={loaderSvg} />
|
|
22
25
|
</span>
|
|
23
26
|
|
|
24
27
|
<style>
|
|
25
|
-
.loader {
|
|
26
|
-
display: inline-flex;
|
|
27
|
-
align-items: center;
|
|
28
|
-
justify-content: center;
|
|
29
|
-
color: var(--pui-loader-color, var(--pui-color-primary));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
:global(.dark) .loader {
|
|
33
|
-
color: var(--pui-loader-color, var(--pui-color-secondary));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
28
|
@keyframes -global-ckw {
|
|
37
29
|
from {
|
|
38
30
|
transform: rotate(0deg);
|
|
@@ -42,24 +34,37 @@
|
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
36
|
|
|
37
|
+
/* loader
|
|
38
|
+
text-accent
|
|
39
|
+
absolute
|
|
40
|
+
top-0
|
|
41
|
+
z-30
|
|
42
|
+
left-0
|
|
43
|
+
w-full
|
|
44
|
+
h-full
|
|
45
|
+
flex
|
|
46
|
+
items-center
|
|
47
|
+
justify-center
|
|
48
|
+
bg-neutral-200/75
|
|
49
|
+
dark:bg-neutral-700/75 */
|
|
45
50
|
.full-screen {
|
|
46
51
|
position: absolute;
|
|
47
52
|
top: 0;
|
|
48
53
|
left: 0;
|
|
49
54
|
width: 100%;
|
|
50
55
|
height: 100%;
|
|
51
|
-
z-index:
|
|
56
|
+
z-index: 30;
|
|
52
57
|
display: flex;
|
|
53
58
|
align-items: center;
|
|
54
59
|
justify-content: center;
|
|
55
60
|
background-color: rgba(255, 255, 255, 0.75);
|
|
56
|
-
border-radius:
|
|
57
|
-
color: var(--
|
|
61
|
+
border-radius: 0.25rem;
|
|
62
|
+
color: var(--ui-primary);
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
:global(.dark) .full-screen {
|
|
61
66
|
background-color: rgba(0, 0, 0, 0.75);
|
|
62
|
-
color: var(--
|
|
67
|
+
color: var(--ui-accent);
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
:global(span.spin) {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
interface
|
|
1
|
+
export interface LoaderProps {
|
|
2
|
+
/** Display as full-screen overlay */
|
|
2
3
|
fullScreen?: boolean;
|
|
4
|
+
/** Custom size for the loader icon */
|
|
3
5
|
sizeOverride?: string;
|
|
6
|
+
/** Additional CSS classes */
|
|
4
7
|
class?: string;
|
|
5
8
|
}
|
|
6
|
-
declare const Loader: import("svelte").Component<
|
|
9
|
+
declare const Loader: import("svelte").Component<LoaderProps, {}, "">;
|
|
7
10
|
type Loader = ReturnType<typeof Loader>;
|
|
8
11
|
export default Loader;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { themeState } from '../theme.svelte.js';
|
|
3
|
+
import { brandState } from '../uiTheme.svelte.js';
|
|
4
|
+
import Icon from '../icon/Icon.svelte';
|
|
5
|
+
import Link from './Link.svelte';
|
|
6
|
+
import placeholderLogo from '../icon/logo-placeholder.svg?raw';
|
|
7
|
+
|
|
8
|
+
export interface LogoProps {
|
|
9
|
+
/** Additional CSS classes */
|
|
10
|
+
class?: string;
|
|
11
|
+
/** URL to navigate to when logo is clicked */
|
|
12
|
+
href?: string;
|
|
13
|
+
/** Override the logo fill colour (defaults to theme-aware primary/white) */
|
|
14
|
+
fill?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Raw SVG markup to render. Falls back to the logo registered via
|
|
17
|
+
* `applyTheme({ logo })` / `setLogo()`, then to a generic placeholder.
|
|
18
|
+
*/
|
|
19
|
+
svg?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
class: classes = '',
|
|
24
|
+
href = '/',
|
|
25
|
+
fill: fillOverride = undefined,
|
|
26
|
+
svg = undefined
|
|
27
|
+
}: LogoProps = $props();
|
|
28
|
+
|
|
29
|
+
const fill = $derived(fillOverride ?? (themeState.isDarkMode ? 'white' : 'var(--ui-primary)'));
|
|
30
|
+
const logoSvg = $derived(svg ?? brandState.logo ?? placeholderLogo);
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<Link {href}>
|
|
34
|
+
<span class="logo {classes}">
|
|
35
|
+
<Icon svg={logoSvg} {fill} stroke="none" />
|
|
36
|
+
</span>
|
|
37
|
+
</Link>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface LogoProps {
|
|
2
|
+
/** Additional CSS classes */
|
|
3
|
+
class?: string;
|
|
4
|
+
/** URL to navigate to when logo is clicked */
|
|
5
|
+
href?: string;
|
|
6
|
+
/** Override the logo fill colour (defaults to theme-aware primary/white) */
|
|
7
|
+
fill?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Raw SVG markup to render. Falls back to the logo registered via
|
|
10
|
+
* `applyTheme({ logo })` / `setLogo()`, then to a generic placeholder.
|
|
11
|
+
*/
|
|
12
|
+
svg?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const Logo: import("svelte").Component<LogoProps, {}, "">;
|
|
15
|
+
type Logo = ReturnType<typeof Logo>;
|
|
16
|
+
export default Logo;
|