@placeholderco/placeholder-ui 1.0.11 → 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 +270 -137
- package/dist/form/Autocomplete.svelte.d.ts +58 -10
- package/dist/form/AutocompleteMulti.svelte +385 -227
- package/dist/form/AutocompleteMulti.svelte.d.ts +59 -10
- package/dist/form/Checkbox.svelte +124 -43
- package/dist/form/Checkbox.svelte.d.ts +26 -2
- package/dist/form/Chips.svelte +47 -17
- package/dist/form/Chips.svelte.d.ts +24 -3
- 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 +177 -191
- package/dist/form/DatePicker.svelte.d.ts +17 -2
- package/dist/form/DateRangePicker.svelte +775 -0
- package/dist/form/DateRangePicker.svelte.d.ts +23 -0
- package/dist/form/DateTimePicker.svelte +168 -209
- 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 +71 -29
- package/dist/form/Number.svelte.d.ts +39 -6
- package/dist/form/Radio.svelte +174 -0
- package/dist/form/Radio.svelte.d.ts +21 -0
- package/dist/form/RadioGroup.svelte +52 -138
- package/dist/form/RadioGroup.svelte.d.ts +19 -2
- package/dist/form/SegmentedControl.svelte +103 -57
- package/dist/form/SegmentedControl.svelte.d.ts +12 -2
- package/dist/form/Select.svelte +160 -229
- package/dist/form/Select.svelte.d.ts +35 -6
- package/dist/form/SelectMulti.svelte +166 -277
- package/dist/form/SelectMulti.svelte.d.ts +37 -6
- package/dist/form/Slider.svelte +185 -268
- package/dist/form/Slider.svelte.d.ts +33 -16
- 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 +80 -45
- package/dist/form/TextArea.svelte.d.ts +35 -10
- package/dist/form/Textbox.svelte +80 -47
- package/dist/form/Textbox.svelte.d.ts +41 -8
- 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/cube-send.svg +1 -0
- 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 -145
- package/dist/icon/index.js +166 -146
- package/dist/icon/layout-sidebar-left-collapse.svg +1 -0
- package/dist/icon/layout-sidebar-left-expand.svg +1 -0
- package/dist/icon/logo-placeholder.svg +6 -0
- package/dist/icon/paperclip.svg +1 -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/icon/thumb-down.svg +1 -0
- package/dist/icon/thumb-up.svg +1 -0
- package/dist/index.d.ts +93 -22
- package/dist/index.js +28 -27
- 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 +158 -110
- package/dist/layout/Navbar.svelte.d.ts +26 -12
- 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 +170 -161
- package/dist/ui/Badge.svelte.d.ts +16 -4
- 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 -104
- package/dist/ui/Dialog.svelte.d.ts +21 -2
- 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 +12 -6
- 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 +169 -0
- package/dist/ui/ProgressBar.svelte.d.ts +30 -0
- package/dist/ui/ProgressBarVariant.d.ts +7 -0
- package/dist/ui/ProgressBarVariant.js +1 -0
- 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 +497 -56
- package/dist/ui/Table.svelte.d.ts +64 -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/dist/util/interceptLinkClick.d.ts +13 -0
- package/dist/util/interceptLinkClick.js +33 -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 -252
- package/dist/form/PasswordInput.svelte.d.ts +0 -33
- 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
|
@@ -1,22 +1,41 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ComboBoxItem } from '../models/ComboBoxItem.js';
|
|
3
3
|
import FormGroup from './FormGroup.svelte';
|
|
4
|
+
import Radio from './Radio.svelte';
|
|
4
5
|
|
|
5
|
-
interface
|
|
6
|
+
export interface RadioGroupProps {
|
|
7
|
+
/** HTML name attribute for the radio group (falls back to label, then auto-generated) */
|
|
8
|
+
name?: string;
|
|
9
|
+
/** Label text displayed above the radio group */
|
|
6
10
|
label: string;
|
|
11
|
+
/** Available radio options */
|
|
7
12
|
options: ComboBoxItem[];
|
|
13
|
+
/** Mark field as required (shows asterisk) */
|
|
8
14
|
required?: boolean;
|
|
15
|
+
/** Show error state styling */
|
|
9
16
|
showError?: boolean;
|
|
17
|
+
/** Error message to display */
|
|
10
18
|
errorText?: string;
|
|
19
|
+
/** Additional CSS classes */
|
|
11
20
|
class?: string;
|
|
21
|
+
/** CSS classes for the container element */
|
|
12
22
|
containerClass?: string;
|
|
23
|
+
/** Disable all radio options */
|
|
13
24
|
disabled?: boolean;
|
|
25
|
+
/** When true, the radio state is controlled externally only. Clicking will call onchange but won't change the value. */
|
|
26
|
+
controlled?: boolean;
|
|
27
|
+
/** Display options vertically instead of horizontally */
|
|
28
|
+
vertical?: boolean;
|
|
29
|
+
/** Currently selected value (bindable) */
|
|
14
30
|
value?: string;
|
|
31
|
+
/** Position of the tooltip */
|
|
15
32
|
tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
|
|
33
|
+
/** Callback when selection changes */
|
|
16
34
|
onchange?: (e: string | undefined) => void;
|
|
17
35
|
}
|
|
18
36
|
|
|
19
37
|
let {
|
|
38
|
+
name,
|
|
20
39
|
label,
|
|
21
40
|
options,
|
|
22
41
|
required = false,
|
|
@@ -24,20 +43,26 @@
|
|
|
24
43
|
errorText = '',
|
|
25
44
|
class: classes = '',
|
|
26
45
|
containerClass = '',
|
|
46
|
+
vertical = false,
|
|
27
47
|
disabled = false,
|
|
48
|
+
controlled = false,
|
|
28
49
|
tooltipLocation = 'top',
|
|
29
50
|
value = $bindable(),
|
|
30
51
|
onchange = undefined
|
|
31
|
-
}:
|
|
52
|
+
}: RadioGroupProps = $props();
|
|
32
53
|
|
|
33
|
-
const
|
|
34
|
-
const
|
|
54
|
+
const autoName = `radio-${crypto.randomUUID()}`;
|
|
55
|
+
const resolvedName = $derived(
|
|
56
|
+
(name || label || autoName).replace(/[^a-zA-Z0-9_\-:.]/g, '_')
|
|
57
|
+
);
|
|
35
58
|
|
|
36
59
|
function handleChange(option: ComboBoxItem) {
|
|
37
60
|
if (option.value === value) return;
|
|
38
61
|
|
|
39
|
-
|
|
40
|
-
|
|
62
|
+
if (!controlled) {
|
|
63
|
+
value = option.value;
|
|
64
|
+
}
|
|
65
|
+
onchange?.(option.value);
|
|
41
66
|
}
|
|
42
67
|
</script>
|
|
43
68
|
|
|
@@ -46,26 +71,21 @@
|
|
|
46
71
|
<div
|
|
47
72
|
class="
|
|
48
73
|
radio-options
|
|
74
|
+
{vertical ? 'radio-vertical' : ''}
|
|
49
75
|
{required ? 'radio-required' : ''}
|
|
50
76
|
{showError ? 'error' : ''}
|
|
51
77
|
{disabled ? 'disabled' : ''}"
|
|
52
78
|
>
|
|
53
79
|
{#each options as option, i}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
checked={option.value === value}
|
|
64
|
-
onchange={() => handleChange(option)}
|
|
65
|
-
/>
|
|
66
|
-
{option.label}
|
|
67
|
-
</label>
|
|
68
|
-
</div>
|
|
80
|
+
<Radio
|
|
81
|
+
id={resolvedName + i}
|
|
82
|
+
name={resolvedName}
|
|
83
|
+
label={option.label}
|
|
84
|
+
{disabled}
|
|
85
|
+
checked={option.value === value}
|
|
86
|
+
controlled={true}
|
|
87
|
+
onchange={() => handleChange(option)}
|
|
88
|
+
/>
|
|
69
89
|
{/each}
|
|
70
90
|
</div>
|
|
71
91
|
{#if showError && errorText}
|
|
@@ -75,136 +95,30 @@
|
|
|
75
95
|
</div>
|
|
76
96
|
|
|
77
97
|
<style>
|
|
78
|
-
label {
|
|
79
|
-
display: flex;
|
|
80
|
-
flex-direction: row;
|
|
81
|
-
align-items: center;
|
|
82
|
-
user-select: none;
|
|
83
|
-
cursor: pointer;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.disabled label,
|
|
87
|
-
.disabled input {
|
|
88
|
-
cursor: not-allowed;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
input {
|
|
92
|
-
position: relative !important;
|
|
93
|
-
-webkit-appearance: none;
|
|
94
|
-
-moz-appearance: none;
|
|
95
|
-
appearance: none;
|
|
96
|
-
margin: var(--pui-spacing-2);
|
|
97
|
-
box-sizing: content-box;
|
|
98
|
-
overflow: hidden;
|
|
99
|
-
cursor: pointer;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
input:before {
|
|
103
|
-
content: '';
|
|
104
|
-
display: block;
|
|
105
|
-
box-sizing: content-box;
|
|
106
|
-
width: 16px;
|
|
107
|
-
height: 16px;
|
|
108
|
-
border: 2px solid var(--pui-border-disabled);
|
|
109
|
-
transition: var(--pui-transition-fast) border-color var(--pui-ease-out);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
98
|
.radio-options {
|
|
113
99
|
display: flex;
|
|
114
|
-
gap:
|
|
115
|
-
border-radius:
|
|
100
|
+
gap: 0.5rem;
|
|
101
|
+
border-radius: 6px;
|
|
116
102
|
}
|
|
117
103
|
|
|
118
|
-
.radio-
|
|
119
|
-
|
|
104
|
+
.radio-vertical.radio-options {
|
|
105
|
+
gap: 0.25rem;
|
|
120
106
|
}
|
|
121
107
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
input:checked:before {
|
|
126
|
-
border-color: var(--pui-color-primary);
|
|
127
|
-
transition: var(--pui-transition-slow) border-color var(--pui-ease-out);
|
|
128
|
-
}
|
|
129
|
-
:global(.dark) input:checked:before {
|
|
130
|
-
border-color: var(--pui-color-primary);
|
|
108
|
+
.radio-vertical {
|
|
109
|
+
flex-direction: column;
|
|
131
110
|
}
|
|
132
111
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
background-color: var(--pui-border-disabled);
|
|
136
|
-
opacity: 0.5;
|
|
137
|
-
}
|
|
138
|
-
:global(.dark) input:disabled:before {
|
|
139
|
-
border-color: var(--pui-color-gray-600);
|
|
140
|
-
background-color: var(--pui-color-gray-600);
|
|
141
|
-
}
|
|
142
|
-
input:after {
|
|
143
|
-
content: '';
|
|
144
|
-
display: block;
|
|
145
|
-
position: absolute;
|
|
146
|
-
box-sizing: content-box;
|
|
147
|
-
top: 50%;
|
|
148
|
-
left: 50%;
|
|
149
|
-
transform-origin: 50% 50%;
|
|
150
|
-
background-color: var(--pui-color-primary);
|
|
151
|
-
width: 16px;
|
|
152
|
-
height: 16px;
|
|
153
|
-
border-radius: var(--pui-radius-full);
|
|
154
|
-
transform: translate(-50%, -50%) scale(0);
|
|
155
|
-
}
|
|
156
|
-
input:disabled:after {
|
|
157
|
-
opacity: 0.5;
|
|
158
|
-
}
|
|
159
|
-
:global(.dark) input:after {
|
|
160
|
-
background-color: var(--pui-color-primary);
|
|
161
|
-
}
|
|
162
|
-
input[type='radio']:before {
|
|
163
|
-
border-radius: var(--pui-radius-full);
|
|
164
|
-
}
|
|
165
|
-
input[type='radio']:after {
|
|
166
|
-
width: 16px;
|
|
167
|
-
height: 16px;
|
|
168
|
-
border-radius: var(--pui-radius-full);
|
|
169
|
-
transform: translate(-50%, -50%) scale(0);
|
|
170
|
-
}
|
|
171
|
-
input[type='radio']:checked:after {
|
|
172
|
-
-webkit-animation: toggleOnRadio var(--pui-transition-fast) ease forwards;
|
|
173
|
-
animation: toggleOnRadio var(--pui-transition-fast) ease forwards;
|
|
174
|
-
}
|
|
175
|
-
@-webkit-keyframes toggleOnRadio {
|
|
176
|
-
0% {
|
|
177
|
-
opacity: 0;
|
|
178
|
-
transform: translate(-50%, -50%) scale(0);
|
|
179
|
-
}
|
|
180
|
-
70% {
|
|
181
|
-
opacity: 1;
|
|
182
|
-
transform: translate(-50%, -50%) scale(0.9);
|
|
183
|
-
}
|
|
184
|
-
100% {
|
|
185
|
-
transform: translate(-50%, -50%) scale(0.8);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
@keyframes toggleOnRadio {
|
|
189
|
-
0% {
|
|
190
|
-
opacity: 0;
|
|
191
|
-
transform: translate(-50%, -50%) scale(0);
|
|
192
|
-
}
|
|
193
|
-
70% {
|
|
194
|
-
opacity: 1;
|
|
195
|
-
transform: translate(-50%, -50%) scale(0.9);
|
|
196
|
-
}
|
|
197
|
-
100% {
|
|
198
|
-
transform: translate(-50%, -50%) scale(0.8);
|
|
199
|
-
}
|
|
112
|
+
.radio-required {
|
|
113
|
+
padding: 0.25rem;
|
|
200
114
|
}
|
|
201
115
|
|
|
202
116
|
.error {
|
|
203
|
-
border: 1px solid var(--
|
|
117
|
+
border: 1px solid var(--danger-text);
|
|
204
118
|
}
|
|
205
119
|
|
|
206
120
|
.error-text {
|
|
207
|
-
margin-top:
|
|
208
|
-
color: var(--
|
|
121
|
+
margin-top: 0.25rem;
|
|
122
|
+
color: var(--danger-text);
|
|
209
123
|
}
|
|
210
124
|
</style>
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
import type { ComboBoxItem } from '../models/ComboBoxItem.js';
|
|
2
|
-
interface
|
|
2
|
+
export interface RadioGroupProps {
|
|
3
|
+
/** HTML name attribute for the radio group (falls back to label, then auto-generated) */
|
|
4
|
+
name?: string;
|
|
5
|
+
/** Label text displayed above the radio group */
|
|
3
6
|
label: string;
|
|
7
|
+
/** Available radio options */
|
|
4
8
|
options: ComboBoxItem[];
|
|
9
|
+
/** Mark field as required (shows asterisk) */
|
|
5
10
|
required?: boolean;
|
|
11
|
+
/** Show error state styling */
|
|
6
12
|
showError?: boolean;
|
|
13
|
+
/** Error message to display */
|
|
7
14
|
errorText?: string;
|
|
15
|
+
/** Additional CSS classes */
|
|
8
16
|
class?: string;
|
|
17
|
+
/** CSS classes for the container element */
|
|
9
18
|
containerClass?: string;
|
|
19
|
+
/** Disable all radio options */
|
|
10
20
|
disabled?: boolean;
|
|
21
|
+
/** When true, the radio state is controlled externally only. Clicking will call onchange but won't change the value. */
|
|
22
|
+
controlled?: boolean;
|
|
23
|
+
/** Display options vertically instead of horizontally */
|
|
24
|
+
vertical?: boolean;
|
|
25
|
+
/** Currently selected value (bindable) */
|
|
11
26
|
value?: string;
|
|
27
|
+
/** Position of the tooltip */
|
|
12
28
|
tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
|
|
29
|
+
/** Callback when selection changes */
|
|
13
30
|
onchange?: (e: string | undefined) => void;
|
|
14
31
|
}
|
|
15
|
-
declare const RadioGroup: import("svelte").Component<
|
|
32
|
+
declare const RadioGroup: import("svelte").Component<RadioGroupProps, {}, "value">;
|
|
16
33
|
type RadioGroup = ReturnType<typeof RadioGroup>;
|
|
17
34
|
export default RadioGroup;
|
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ComboBoxItem } from '../models/ComboBoxItem.js';
|
|
3
|
-
import
|
|
3
|
+
import FormGroup from './FormGroup.svelte';
|
|
4
|
+
import { onMount } from 'svelte';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
export type SegmentedControlSize = 'default' | 'lg';
|
|
7
|
+
|
|
8
|
+
export interface SegmentedControlProps {
|
|
9
|
+
/** Available segment options */
|
|
6
10
|
options: ComboBoxItem[];
|
|
11
|
+
/** Currently selected value (bindable) */
|
|
7
12
|
value?: any;
|
|
13
|
+
/** Label text displayed above the control */
|
|
14
|
+
label?: string;
|
|
15
|
+
/** Visual size: 'default' (sized to match Textbox/Select) or 'lg' */
|
|
16
|
+
size?: SegmentedControlSize;
|
|
17
|
+
/** Callback when selection changes */
|
|
8
18
|
onchange?: (value: string) => void;
|
|
9
19
|
}
|
|
10
20
|
|
|
11
|
-
let {
|
|
21
|
+
let {
|
|
22
|
+
options,
|
|
23
|
+
value = $bindable(),
|
|
24
|
+
label,
|
|
25
|
+
size = 'default',
|
|
26
|
+
onchange
|
|
27
|
+
}: SegmentedControlProps = $props();
|
|
12
28
|
|
|
13
29
|
let containerRef: HTMLDivElement;
|
|
14
30
|
let buttonElements = $state<HTMLButtonElement[]>([]);
|
|
@@ -18,25 +34,13 @@
|
|
|
18
34
|
const selectedIndex = $derived(options.findIndex((option) => option.value === value));
|
|
19
35
|
|
|
20
36
|
onMount(() => {
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
// Use ResizeObserver to handle layout shifts (e.g. font loading, container resize)
|
|
29
|
-
const observer = new ResizeObserver(() => {
|
|
30
|
-
if (selectedIndex >= 0 && buttonElements[selectedIndex]) {
|
|
31
|
-
recalculateBackground();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
observer.observe(containerRef);
|
|
35
|
-
|
|
36
|
-
return () => observer.disconnect();
|
|
37
|
+
// recalculate 10 times on startup to ensure background is positioned correctly
|
|
38
|
+
for (let i = 0; i < 10; i++) {
|
|
39
|
+
setTimeout(() => recalculateBackground(), 100 * i);
|
|
40
|
+
}
|
|
37
41
|
});
|
|
38
42
|
|
|
39
|
-
// Update background position and size
|
|
43
|
+
// Update background position and size based on selected element
|
|
40
44
|
$effect(() => {
|
|
41
45
|
if (selectedIndex >= 0 && buttonElements[selectedIndex] && containerRef) {
|
|
42
46
|
recalculateBackground();
|
|
@@ -50,16 +54,30 @@
|
|
|
50
54
|
}
|
|
51
55
|
});
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Recalculate the selected item background position/size (e.g. after a layout change).
|
|
59
|
+
* @param delay Optional delay in milliseconds before measuring (e.g. to let a transition finish)
|
|
60
|
+
*/
|
|
61
|
+
export function recalculateBackground(delay?: number) {
|
|
62
|
+
if (delay) {
|
|
63
|
+
setTimeout(() => recalculateBackground(), delay);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
const selectedButton = buttonElements[selectedIndex];
|
|
68
|
+
if (!selectedButton || !containerRef) return;
|
|
69
|
+
|
|
55
70
|
const containerRect = containerRef.getBoundingClientRect();
|
|
56
71
|
const buttonRect = selectedButton.getBoundingClientRect();
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
// Absolute positioning is relative to the padding box, but getBoundingClientRect
|
|
74
|
+
// measures from the border's outer edge — subtract the border (clientLeft/clientTop)
|
|
75
|
+
const offsetLeft = buttonRect.left - containerRect.left - containerRef.clientLeft;
|
|
76
|
+
const offsetTop = buttonRect.top - containerRect.top - containerRef.clientTop;
|
|
59
77
|
const width = buttonRect.width;
|
|
60
78
|
const height = buttonRect.height;
|
|
61
79
|
|
|
62
|
-
backgroundStyle = `left: ${offsetLeft}px; width: ${width}px; height: ${height}px; top: ${
|
|
80
|
+
backgroundStyle = `left: ${offsetLeft}px; width: ${width}px; height: ${height}px; top: ${offsetTop}px;`;
|
|
63
81
|
}
|
|
64
82
|
|
|
65
83
|
function setValue(newValue: any) {
|
|
@@ -68,82 +86,110 @@
|
|
|
68
86
|
}
|
|
69
87
|
</script>
|
|
70
88
|
|
|
71
|
-
|
|
72
|
-
<div class="segmented-control
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
{#snippet control()}
|
|
90
|
+
<div class="segmented-control {size === 'lg' ? 'large' : ''}" bind:this={containerRef}>
|
|
91
|
+
<div class="segmented-control-background" style={backgroundStyle}></div>
|
|
92
|
+
{#each options as option, index}
|
|
93
|
+
{@const isSelected = option.value === value}
|
|
94
|
+
|
|
95
|
+
<button
|
|
96
|
+
bind:this={buttonElements[index]}
|
|
97
|
+
class="segmented-control-item {isSelected ? 'selected' : ''}"
|
|
98
|
+
onclick={() => setValue(option.value)}
|
|
99
|
+
>
|
|
100
|
+
{option.label}
|
|
101
|
+
</button>
|
|
102
|
+
{/each}
|
|
103
|
+
</div>
|
|
104
|
+
{/snippet}
|
|
105
|
+
|
|
106
|
+
{#if label}
|
|
107
|
+
<FormGroup {label}>
|
|
108
|
+
<div class="segmented-control-container">
|
|
109
|
+
{@render control()}
|
|
110
|
+
</div>
|
|
111
|
+
</FormGroup>
|
|
112
|
+
{:else}
|
|
113
|
+
{@render control()}
|
|
114
|
+
{/if}
|
|
85
115
|
|
|
86
116
|
<style>
|
|
87
117
|
.segmented-control {
|
|
88
118
|
position: relative;
|
|
89
119
|
display: inline-flex;
|
|
90
|
-
background-color:
|
|
91
|
-
border-radius:
|
|
92
|
-
|
|
120
|
+
background-color: #e5e7eb;
|
|
121
|
+
border-radius: 0.5rem;
|
|
122
|
+
border: 1px solid var(--border-color);
|
|
123
|
+
padding: 0.125rem;
|
|
93
124
|
user-select: none;
|
|
94
125
|
}
|
|
95
126
|
|
|
96
127
|
.segmented-control-background {
|
|
97
128
|
position: absolute;
|
|
98
|
-
background-color:
|
|
99
|
-
border-radius:
|
|
100
|
-
transition: all
|
|
101
|
-
box-shadow:
|
|
129
|
+
background-color: white;
|
|
130
|
+
border-radius: 0.375rem;
|
|
131
|
+
transition: all 0.2s ease-in-out;
|
|
132
|
+
box-shadow:
|
|
133
|
+
0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
|
134
|
+
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
102
135
|
}
|
|
103
136
|
|
|
104
137
|
.segmented-control-item {
|
|
105
138
|
position: relative;
|
|
106
139
|
align-items: center;
|
|
107
140
|
justify-content: center;
|
|
108
|
-
padding: var(--pui-spacing-2) var(--pui-spacing-4);
|
|
109
141
|
cursor: pointer;
|
|
110
142
|
user-select: none;
|
|
111
143
|
border: none;
|
|
112
144
|
background: transparent;
|
|
113
|
-
border-radius:
|
|
114
|
-
|
|
115
|
-
font-
|
|
116
|
-
|
|
117
|
-
|
|
145
|
+
border-radius: 0.375rem;
|
|
146
|
+
padding: 0.125rem 0.75rem;
|
|
147
|
+
font-size: 0.875rem;
|
|
148
|
+
line-height: 1.5rem;
|
|
149
|
+
font-weight: 500;
|
|
150
|
+
color: #6b7280;
|
|
151
|
+
transition: color 0.2s ease-in-out;
|
|
118
152
|
z-index: 1;
|
|
119
153
|
}
|
|
120
154
|
|
|
121
155
|
.segmented-control-item:hover {
|
|
122
|
-
color:
|
|
156
|
+
color: #374151;
|
|
123
157
|
}
|
|
124
158
|
|
|
125
159
|
.segmented-control-item.selected {
|
|
126
|
-
color:
|
|
160
|
+
color: #111827;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Large size */
|
|
164
|
+
.segmented-control.large {
|
|
165
|
+
border: none;
|
|
166
|
+
padding: 0.25rem;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.segmented-control.large .segmented-control-item {
|
|
170
|
+
padding: 0.5rem 1rem;
|
|
171
|
+
line-height: inherit;
|
|
127
172
|
}
|
|
128
173
|
|
|
129
174
|
/* Dark mode styles */
|
|
130
175
|
:global(.dark) .segmented-control {
|
|
131
|
-
background-color: var(--
|
|
176
|
+
background-color: var(--input-bg-color);
|
|
177
|
+
border-color: var(--border-color);
|
|
132
178
|
}
|
|
133
179
|
|
|
134
180
|
:global(.dark) .segmented-control-background {
|
|
135
|
-
background-color: var(--
|
|
181
|
+
background-color: var(--ui-primary);
|
|
136
182
|
}
|
|
137
183
|
|
|
138
184
|
:global(.dark) .segmented-control-item {
|
|
139
|
-
color:
|
|
185
|
+
color: #9ca3af;
|
|
140
186
|
}
|
|
141
187
|
|
|
142
188
|
:global(.dark) .segmented-control-item:hover {
|
|
143
|
-
color:
|
|
189
|
+
color: #d1d5db;
|
|
144
190
|
}
|
|
145
191
|
|
|
146
192
|
:global(.dark) .segmented-control-item.selected {
|
|
147
|
-
color:
|
|
193
|
+
color: #f9fafb;
|
|
148
194
|
}
|
|
149
195
|
</style>
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import type { ComboBoxItem } from '../models/ComboBoxItem.js';
|
|
2
|
-
|
|
2
|
+
export type SegmentedControlSize = 'default' | 'lg';
|
|
3
|
+
export interface SegmentedControlProps {
|
|
4
|
+
/** Available segment options */
|
|
3
5
|
options: ComboBoxItem[];
|
|
6
|
+
/** Currently selected value (bindable) */
|
|
4
7
|
value?: any;
|
|
8
|
+
/** Label text displayed above the control */
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Visual size: 'default' (sized to match Textbox/Select) or 'lg' */
|
|
11
|
+
size?: SegmentedControlSize;
|
|
12
|
+
/** Callback when selection changes */
|
|
5
13
|
onchange?: (value: string) => void;
|
|
6
14
|
}
|
|
7
|
-
declare const SegmentedControl: import("svelte").Component<
|
|
15
|
+
declare const SegmentedControl: import("svelte").Component<SegmentedControlProps, {
|
|
16
|
+
recalculateBackground: (delay?: number) => void;
|
|
17
|
+
}, "value">;
|
|
8
18
|
type SegmentedControl = ReturnType<typeof SegmentedControl>;
|
|
9
19
|
export default SegmentedControl;
|