@placeholderco/placeholder-ui 2.1.1 → 2.2.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/dist/editors/CodeMirror.svelte +295 -297
- package/dist/editors/tiptap/LinkActionMenu.svelte +6 -1
- package/dist/editors/tiptap/extensions/Alert.js +17 -17
- package/dist/editors/tiptap/extensions/Div.js +19 -19
- package/dist/editors/tiptap/extensions/Span.js +14 -14
- package/dist/editors/tiptap/toolbar/AlertButton.svelte +254 -253
- package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/AlignRightButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/BoldButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/BulletListButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/CodeButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/ColorButton.svelte +265 -265
- package/dist/editors/tiptap/toolbar/DocumentButton.svelte +51 -51
- package/dist/editors/tiptap/toolbar/HeadingButton.svelte +21 -21
- package/dist/editors/tiptap/toolbar/HtmlButton.svelte +48 -52
- package/dist/editors/tiptap/toolbar/ImageButton.svelte +35 -39
- package/dist/editors/tiptap/toolbar/ItalicButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/LinkButton.svelte +249 -249
- package/dist/editors/tiptap/toolbar/OrderedListButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/RedoButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/SubscriptButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/TableButton.svelte +231 -224
- package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +59 -65
- package/dist/editors/tiptap/toolbar/UnderlineButton.svelte +11 -11
- package/dist/editors/tiptap/toolbar/UndoButton.svelte +11 -11
- package/dist/form/Autocomplete.svelte +24 -22
- package/dist/form/AutocompleteMulti.svelte +24 -22
- package/dist/form/Checkbox.svelte +4 -4
- package/dist/form/Chips.svelte +15 -7
- package/dist/form/ColorPicker.svelte +5 -20
- package/dist/form/ComboBox.svelte +4 -4
- package/dist/form/ComboBoxItemBuilder.svelte +14 -32
- package/dist/form/ComboBoxMulti.svelte +7 -3
- package/dist/form/CronBuilder.svelte +32 -110
- package/dist/form/DatePicker.svelte +9 -28
- package/dist/form/DateRangePicker.svelte +46 -36
- package/dist/form/DateTimePicker.svelte +11 -30
- package/dist/form/Number.svelte +1 -3
- package/dist/form/RadioGroup.svelte +1 -3
- package/dist/form/Select.svelte +25 -28
- package/dist/form/SelectMulti.svelte +36 -38
- package/dist/form/StringArrayBuilder.svelte +1 -3
- package/dist/form/TextArea.svelte +5 -6
- package/dist/form/Textbox.svelte +10 -4
- package/dist/form/TimePicker.svelte +10 -4
- package/dist/icon/Icon.svelte +5 -1
- package/dist/index.d.ts +147 -146
- package/dist/index.js +78 -77
- package/dist/layout/CustomNavbar.svelte +1 -1
- package/dist/layout/NavbarItemDisplay.svelte +1 -1
- package/dist/layout/NavbarItemView.svelte +3 -1
- package/dist/layout/Sidenav.svelte +1 -1
- package/dist/models/ComboBoxItem.d.ts +4 -4
- package/dist/models/NotifyModel.js +0 -1
- package/dist/theme.svelte.d.ts +1 -1
- package/dist/theme.svelte.js +46 -22
- package/dist/ui/Accordion.svelte +1 -3
- package/dist/ui/Badge.svelte +4 -5
- package/dist/ui/Button.svelte +7 -1
- package/dist/ui/ContextMenu.svelte +5 -11
- package/dist/ui/Dialog.svelte +16 -3
- package/dist/ui/Dialog.svelte.d.ts +7 -1
- package/dist/ui/Dropdown.svelte +21 -10
- package/dist/ui/MultiSortable.svelte +1 -3
- package/dist/ui/Pagination.svelte +2 -2
- package/dist/ui/Popover.svelte +16 -37
- package/dist/ui/ProgressBar.svelte +1 -4
- package/dist/ui/ThemeSwitcher.svelte +2 -1
- package/dist/ui/Tooltip.svelte +1 -37
- package/dist/util/DateFunctions.js +1 -1
- package/dist/util/Floating.d.ts +70 -0
- package/dist/util/Floating.js +321 -0
- package/dist/util/NavigateTo.js +2 -2
- package/dist/util/Transitions.d.ts +1 -1
- package/dist/util/Transitions.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
export { default as Accordion } from
|
|
2
|
-
export { default as AccordionItem } from
|
|
3
|
-
export { default as Button } from
|
|
4
|
-
export { default as ActionIcon } from
|
|
5
|
-
export { default as Badge } from
|
|
6
|
-
export { default as Dialog } from
|
|
7
|
-
export { default as Drawer } from
|
|
8
|
-
export { default as Dropdown } from
|
|
9
|
-
export { default as Dropzone } from
|
|
10
|
-
export { default as Link } from
|
|
11
|
-
export { default as Loader } from
|
|
12
|
-
export { default as Logo } from
|
|
13
|
-
export { default as Pagination } from
|
|
14
|
-
export { default as Popover } from
|
|
15
|
-
export { default as ContextMenu } from
|
|
16
|
-
export { default as ProgressBar } from
|
|
17
|
-
export { default as Tabs } from
|
|
18
|
-
export { default as Table } from
|
|
19
|
-
export { default as ThemeSwitcher } from
|
|
20
|
-
export { default as Sortable } from
|
|
21
|
-
export { default as MultiSortable } from
|
|
22
|
-
export { default as Toaster } from
|
|
23
|
-
export { default as Tooltip } from
|
|
24
|
-
export { default as Alert } from
|
|
25
|
-
export { default as LinkCollection } from
|
|
26
|
-
export { default as Navbar } from
|
|
27
|
-
export { default as NavbarItemView } from
|
|
28
|
-
export { default as CustomNavbar } from
|
|
29
|
-
export { default as AppShell } from
|
|
30
|
-
export { default as Sidenav } from
|
|
31
|
-
export { default as Paper } from
|
|
32
|
-
export { default as Avatar } from
|
|
33
|
-
export { default as Autocomplete } from
|
|
34
|
-
export { default as AutocompleteMulti } from
|
|
35
|
-
export { default as Checkbox } from
|
|
36
|
-
export { default as ComboBoxItemBuilder } from
|
|
37
|
-
export { default as StringArrayBuilder } from
|
|
38
|
-
export { default as CronBuilder } from
|
|
39
|
-
export { default as DatePicker } from
|
|
40
|
-
export { default as DateRangePicker } from
|
|
41
|
-
export { default as TimePicker } from
|
|
42
|
-
export { default as DateTimePicker } from
|
|
43
|
-
export { default as FormGroup } from
|
|
44
|
-
export { default as Number } from
|
|
45
|
-
export { default as Radio } from
|
|
46
|
-
export { default as RadioGroup } from
|
|
47
|
-
export { default as Select } from
|
|
48
|
-
export { default as SelectMulti } from
|
|
49
|
-
export { default as SegmentedControl } from
|
|
50
|
-
export { default as TextArea } from
|
|
51
|
-
export { default as Textbox } from
|
|
52
|
-
export { default as Slider } from
|
|
53
|
-
export { default as Switch } from
|
|
54
|
-
export { default as Chips } from
|
|
55
|
-
export { default as ColorPicker } from
|
|
56
|
-
export { parseColor, parseHex, toHex, formatColor, rgbToHsv, hsvToRgb, rgbToHsl
|
|
57
|
-
export { default as TipTap } from
|
|
58
|
-
export { default as TipTapBubble } from
|
|
59
|
-
export { CodeBlockEditor, codeBlockLanguages, resolveCodeBlockLanguage
|
|
60
|
-
export { default as CodeMirror } from
|
|
61
|
-
export { default as GitCard } from
|
|
62
|
-
export * from
|
|
63
|
-
export * from
|
|
64
|
-
export * from
|
|
65
|
-
export * from
|
|
66
|
-
export * from
|
|
67
|
-
export * from
|
|
68
|
-
export
|
|
69
|
-
export
|
|
70
|
-
export * from
|
|
71
|
-
export * from
|
|
72
|
-
export * from
|
|
73
|
-
export * from
|
|
74
|
-
export * from
|
|
75
|
-
export * from
|
|
76
|
-
export * from
|
|
77
|
-
export * from
|
|
1
|
+
export { default as Accordion } from './ui/Accordion.svelte';
|
|
2
|
+
export { default as AccordionItem } from './ui/AccordionItem.svelte';
|
|
3
|
+
export { default as Button } from './ui/Button.svelte';
|
|
4
|
+
export { default as ActionIcon } from './ui/ActionIcon.svelte';
|
|
5
|
+
export { default as Badge } from './ui/Badge.svelte';
|
|
6
|
+
export { default as Dialog } from './ui/Dialog.svelte';
|
|
7
|
+
export { default as Drawer } from './ui/Drawer.svelte';
|
|
8
|
+
export { default as Dropdown } from './ui/Dropdown.svelte';
|
|
9
|
+
export { default as Dropzone } from './ui/Dropzone.svelte';
|
|
10
|
+
export { default as Link } from './ui/Link.svelte';
|
|
11
|
+
export { default as Loader } from './ui/Loader.svelte';
|
|
12
|
+
export { default as Logo } from './ui/Logo.svelte';
|
|
13
|
+
export { default as Pagination } from './ui/Pagination.svelte';
|
|
14
|
+
export { default as Popover } from './ui/Popover.svelte';
|
|
15
|
+
export { default as ContextMenu } from './ui/ContextMenu.svelte';
|
|
16
|
+
export { default as ProgressBar } from './ui/ProgressBar.svelte';
|
|
17
|
+
export { default as Tabs } from './ui/Tabs.svelte';
|
|
18
|
+
export { default as Table } from './ui/Table.svelte';
|
|
19
|
+
export { default as ThemeSwitcher } from './ui/ThemeSwitcher.svelte';
|
|
20
|
+
export { default as Sortable } from './ui/Sortable.svelte';
|
|
21
|
+
export { default as MultiSortable } from './ui/MultiSortable.svelte';
|
|
22
|
+
export { default as Toaster } from './ui/Toaster.svelte';
|
|
23
|
+
export { default as Tooltip } from './ui/Tooltip.svelte';
|
|
24
|
+
export { default as Alert } from './display/alert/Alert.svelte';
|
|
25
|
+
export { default as LinkCollection } from './display/LinkCollection.svelte';
|
|
26
|
+
export { default as Navbar } from './layout/Navbar.svelte';
|
|
27
|
+
export { default as NavbarItemView } from './layout/NavbarItemView.svelte';
|
|
28
|
+
export { default as CustomNavbar } from './layout/CustomNavbar.svelte';
|
|
29
|
+
export { default as AppShell } from './layout/AppShell.svelte';
|
|
30
|
+
export { default as Sidenav } from './layout/Sidenav.svelte';
|
|
31
|
+
export { default as Paper } from './display/Paper.svelte';
|
|
32
|
+
export { default as Avatar } from './display/Avatar.svelte';
|
|
33
|
+
export { default as Autocomplete } from './form/Autocomplete.svelte';
|
|
34
|
+
export { default as AutocompleteMulti } from './form/AutocompleteMulti.svelte';
|
|
35
|
+
export { default as Checkbox } from './form/Checkbox.svelte';
|
|
36
|
+
export { default as ComboBoxItemBuilder } from './form/ComboBoxItemBuilder.svelte';
|
|
37
|
+
export { default as StringArrayBuilder } from './form/StringArrayBuilder.svelte';
|
|
38
|
+
export { default as CronBuilder } from './form/CronBuilder.svelte';
|
|
39
|
+
export { default as DatePicker } from './form/DatePicker.svelte';
|
|
40
|
+
export { default as DateRangePicker } from './form/DateRangePicker.svelte';
|
|
41
|
+
export { default as TimePicker } from './form/TimePicker.svelte';
|
|
42
|
+
export { default as DateTimePicker } from './form/DateTimePicker.svelte';
|
|
43
|
+
export { default as FormGroup } from './form/FormGroup.svelte';
|
|
44
|
+
export { default as Number } from './form/Number.svelte';
|
|
45
|
+
export { default as Radio } from './form/Radio.svelte';
|
|
46
|
+
export { default as RadioGroup } from './form/RadioGroup.svelte';
|
|
47
|
+
export { default as Select } from './form/Select.svelte';
|
|
48
|
+
export { default as SelectMulti } from './form/SelectMulti.svelte';
|
|
49
|
+
export { default as SegmentedControl } from './form/SegmentedControl.svelte';
|
|
50
|
+
export { default as TextArea } from './form/TextArea.svelte';
|
|
51
|
+
export { default as Textbox } from './form/Textbox.svelte';
|
|
52
|
+
export { default as Slider } from './form/Slider.svelte';
|
|
53
|
+
export { default as Switch } from './form/Switch.svelte';
|
|
54
|
+
export { default as Chips } from './form/Chips.svelte';
|
|
55
|
+
export { default as ColorPicker } from './form/ColorPicker.svelte';
|
|
56
|
+
export { parseColor, parseHex, toHex, formatColor, rgbToHsv, hsvToRgb, rgbToHsl } from './form/ColorPicker.svelte';
|
|
57
|
+
export { default as TipTap } from './editors/tiptap/TipTap.svelte';
|
|
58
|
+
export { default as TipTapBubble } from './editors/tiptap/TipTapBubble.svelte';
|
|
59
|
+
export { CodeBlockEditor, codeBlockLanguages, resolveCodeBlockLanguage } from './editors/tiptap/extensions/index.js';
|
|
60
|
+
export { default as CodeMirror } from './editors/CodeMirror.svelte';
|
|
61
|
+
export { default as GitCard } from './cards/GitCard.svelte';
|
|
62
|
+
export * from './icon/index.js';
|
|
63
|
+
export * from './models/ComboBoxItem.js';
|
|
64
|
+
export * from './models/NavbarItem.js';
|
|
65
|
+
export * from './models/NotifyModel.js';
|
|
66
|
+
export * from './util/ClickOutside.js';
|
|
67
|
+
export * from './util/Floating.js';
|
|
68
|
+
export * from './util/CronParser.js';
|
|
69
|
+
export { dayjs } from './util/dayjs.js';
|
|
70
|
+
export * from './util/DateFunctions.js';
|
|
71
|
+
export * from './util/DragDrop.js';
|
|
72
|
+
export * from './util/Transitions.js';
|
|
73
|
+
export * from './util/interceptLinkClick.js';
|
|
74
|
+
export * from './util/NavigateTo.js';
|
|
75
|
+
export * from './display/filetree/index.js';
|
|
76
|
+
export * from './theme.svelte.js';
|
|
77
|
+
export * from './uiTheme.svelte.js';
|
|
78
|
+
export * from './ui/Toast.svelte.js';
|
|
@@ -61,7 +61,9 @@
|
|
|
61
61
|
<div
|
|
62
62
|
class="navbar-submenu"
|
|
63
63
|
class:flyout={depth > 0}
|
|
64
|
-
style={item.submenuWidth
|
|
64
|
+
style={item.submenuWidth
|
|
65
|
+
? `width: ${item.submenuWidth}; min-width: ${item.submenuWidth};`
|
|
66
|
+
: ''}
|
|
65
67
|
onclick={(e) => {
|
|
66
68
|
// Close the fold-out once an actual link is chosen (but not when toggling a nested parent)
|
|
67
69
|
if ((e.target as HTMLElement).closest('a')) close();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NotifyModel } from
|
|
1
|
+
import type { NotifyModel } from './NotifyModel.js';
|
|
2
2
|
export interface ComboBoxGroup {
|
|
3
3
|
label: string;
|
|
4
4
|
items: ComboBoxItem[];
|
|
@@ -20,6 +20,6 @@ export interface ComboBoxItem {
|
|
|
20
20
|
/** Marks a synthetic "add new value" suggestion (see Autocomplete) */
|
|
21
21
|
isAddNew?: boolean;
|
|
22
22
|
}
|
|
23
|
-
export type FetchFunctionType = (
|
|
24
|
-
export type SearchFunctionType = (
|
|
25
|
-
export type RetrieveLabelFunctionType = (
|
|
23
|
+
export type FetchFunctionType = () => Promise<NotifyModel<ComboBoxItem[]>>;
|
|
24
|
+
export type SearchFunctionType = (query: string) => Promise<NotifyModel<ComboBoxItem[]>>;
|
|
25
|
+
export type RetrieveLabelFunctionType = (value: any) => Promise<NotifyModel<string | undefined>>;
|
package/dist/theme.svelte.d.ts
CHANGED
package/dist/theme.svelte.js
CHANGED
|
@@ -4,12 +4,12 @@ const browser = typeof window !== 'undefined' && typeof document !== 'undefined'
|
|
|
4
4
|
// Theme State
|
|
5
5
|
// ============================================
|
|
6
6
|
// Svelte 5 runes for reactive state
|
|
7
|
-
let theme = $state(
|
|
7
|
+
let theme = $state('system');
|
|
8
8
|
let systemDarkMode = $state(browser && isSystemDarkMode());
|
|
9
9
|
let isDarkMode = $derived.by(() => {
|
|
10
|
-
if (theme ===
|
|
10
|
+
if (theme === 'system')
|
|
11
11
|
return systemDarkMode;
|
|
12
|
-
return theme ===
|
|
12
|
+
return theme === 'dark';
|
|
13
13
|
});
|
|
14
14
|
// Initialize theme on module load (browser only - SSR has no localStorage/document)
|
|
15
15
|
if (browser)
|
|
@@ -18,8 +18,8 @@ if (browser)
|
|
|
18
18
|
if (browser && window.matchMedia) {
|
|
19
19
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
|
20
20
|
systemDarkMode = e.matches;
|
|
21
|
-
if (theme ===
|
|
22
|
-
applyThemeClass(e.matches ?
|
|
21
|
+
if (theme === 'system')
|
|
22
|
+
applyThemeClass(e.matches ? 'dark' : 'light');
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
// ============================================
|
|
@@ -55,20 +55,44 @@ if (typeof window !== 'undefined') {
|
|
|
55
55
|
}
|
|
56
56
|
// Export reactive viewport state object
|
|
57
57
|
export const viewportState = {
|
|
58
|
-
get width() {
|
|
59
|
-
|
|
58
|
+
get width() {
|
|
59
|
+
return windowWidth;
|
|
60
|
+
},
|
|
61
|
+
get height() {
|
|
62
|
+
return windowHeight;
|
|
63
|
+
},
|
|
60
64
|
// Boolean helpers
|
|
61
|
-
get isMobile() {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
get
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
get
|
|
68
|
-
|
|
65
|
+
get isMobile() {
|
|
66
|
+
return isMobile;
|
|
67
|
+
},
|
|
68
|
+
get isTablet() {
|
|
69
|
+
return isTablet;
|
|
70
|
+
},
|
|
71
|
+
get isDesktop() {
|
|
72
|
+
return isDesktop;
|
|
73
|
+
},
|
|
74
|
+
get isSmall() {
|
|
75
|
+
return isSmall;
|
|
76
|
+
},
|
|
77
|
+
get isMedium() {
|
|
78
|
+
return isMedium;
|
|
79
|
+
},
|
|
80
|
+
get isLarge() {
|
|
81
|
+
return isLarge;
|
|
82
|
+
},
|
|
83
|
+
get isExtraLarge() {
|
|
84
|
+
return isExtraLarge;
|
|
85
|
+
},
|
|
86
|
+
get isUltrawide() {
|
|
87
|
+
return isUltrawide;
|
|
88
|
+
},
|
|
69
89
|
// Utility function for custom breakpoints
|
|
70
|
-
isBelow(breakpoint) {
|
|
71
|
-
|
|
90
|
+
isBelow(breakpoint) {
|
|
91
|
+
return windowWidth < breakpoint;
|
|
92
|
+
},
|
|
93
|
+
isAbove(breakpoint) {
|
|
94
|
+
return windowWidth >= breakpoint;
|
|
95
|
+
}
|
|
72
96
|
};
|
|
73
97
|
// Export getter for the theme state
|
|
74
98
|
export function getTheme() {
|
|
@@ -86,7 +110,7 @@ export const themeState = {
|
|
|
86
110
|
export function loadTheme() {
|
|
87
111
|
if (!browser)
|
|
88
112
|
return;
|
|
89
|
-
const themeString = localStorage.getItem(
|
|
113
|
+
const themeString = localStorage.getItem('theme') || 'system';
|
|
90
114
|
if (themeString == 'light')
|
|
91
115
|
setTheme('light');
|
|
92
116
|
else if (themeString == 'dark')
|
|
@@ -96,9 +120,9 @@ export function loadTheme() {
|
|
|
96
120
|
}
|
|
97
121
|
export function setTheme(newTheme) {
|
|
98
122
|
let appliedTheme;
|
|
99
|
-
if (newTheme ===
|
|
123
|
+
if (newTheme === 'system') {
|
|
100
124
|
systemDarkMode = isSystemDarkMode();
|
|
101
|
-
appliedTheme = systemDarkMode ?
|
|
125
|
+
appliedTheme = systemDarkMode ? 'dark' : 'light';
|
|
102
126
|
}
|
|
103
127
|
else {
|
|
104
128
|
appliedTheme = newTheme;
|
|
@@ -108,13 +132,13 @@ export function setTheme(newTheme) {
|
|
|
108
132
|
if (!browser)
|
|
109
133
|
return;
|
|
110
134
|
applyThemeClass(appliedTheme);
|
|
111
|
-
localStorage.setItem(
|
|
135
|
+
localStorage.setItem('theme', newTheme);
|
|
112
136
|
}
|
|
113
137
|
function applyThemeClass(appliedTheme) {
|
|
114
138
|
if (!browser)
|
|
115
139
|
return;
|
|
116
140
|
const classList = document.documentElement.classList;
|
|
117
|
-
classList.remove(
|
|
141
|
+
classList.remove('light', 'dark');
|
|
118
142
|
classList.add(appliedTheme);
|
|
119
143
|
}
|
|
120
144
|
function isSystemDarkMode() {
|
package/dist/ui/Accordion.svelte
CHANGED
|
@@ -59,9 +59,7 @@
|
|
|
59
59
|
children
|
|
60
60
|
}: AccordionProps = $props();
|
|
61
61
|
|
|
62
|
-
const openValues = $derived(
|
|
63
|
-
Array.isArray(value) ? value : value ? [value] : []
|
|
64
|
-
);
|
|
62
|
+
const openValues = $derived(Array.isArray(value) ? value : value ? [value] : []);
|
|
65
63
|
|
|
66
64
|
function isOpen(itemValue: string): boolean {
|
|
67
65
|
return openValues.includes(itemValue);
|
package/dist/ui/Badge.svelte
CHANGED
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
let isDisabled: boolean = $derived(loading || disabled);
|
|
44
44
|
let type: 'a' | 'button' | 'div' = $derived(onClick ? 'button' : href ? 'a' : 'div');
|
|
45
45
|
|
|
46
|
-
const elClass = $derived(
|
|
47
|
-
`badge ${isDisabled ? 'disabled' : ''}`
|
|
48
|
-
);
|
|
46
|
+
const elClass = $derived(`badge ${isDisabled ? 'disabled' : ''}`);
|
|
49
47
|
</script>
|
|
50
48
|
|
|
51
|
-
<div
|
|
49
|
+
<div
|
|
50
|
+
class="badge-container {variant} shape-{shape} size-{size} {onDelete ? 'badge-with-button' : ''} "
|
|
51
|
+
>
|
|
52
52
|
{#if type == 'a' && !disabled}
|
|
53
53
|
<a class={elClass} {href} {target}> {@render children?.()}</a>
|
|
54
54
|
{:else if type == 'button'}
|
|
@@ -334,5 +334,4 @@
|
|
|
334
334
|
.size-lg .badge-button {
|
|
335
335
|
padding: 6px;
|
|
336
336
|
}
|
|
337
|
-
|
|
338
337
|
</style>
|
package/dist/ui/Button.svelte
CHANGED
|
@@ -87,7 +87,13 @@
|
|
|
87
87
|
{/snippet}
|
|
88
88
|
|
|
89
89
|
{#if isLink && href && !disabled}
|
|
90
|
-
<a
|
|
90
|
+
<a
|
|
91
|
+
{target}
|
|
92
|
+
class={elClass}
|
|
93
|
+
aria-label={ariaLabel}
|
|
94
|
+
href={href?.startsWith('/') ? resolve(href as any) : href}
|
|
95
|
+
onclick={(e) => interceptLinkClick(e, { href, target, onclick })}
|
|
96
|
+
>
|
|
91
97
|
{@render buttonContent?.()}
|
|
92
98
|
</a>
|
|
93
99
|
{:else}
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
<script lang="ts">
|
|
40
40
|
import ContextMenuList from './ContextMenuList.svelte';
|
|
41
|
+
import { topLayer } from '../util/Floating.js';
|
|
41
42
|
|
|
42
43
|
let {
|
|
43
44
|
open = $bindable(false),
|
|
@@ -54,16 +55,6 @@
|
|
|
54
55
|
let posY = $state(0);
|
|
55
56
|
let placed = $state(false);
|
|
56
57
|
|
|
57
|
-
/** Move the menu to <body> so it can't be clipped by overflow/transform ancestors. */
|
|
58
|
-
function portal(node: HTMLElement) {
|
|
59
|
-
document.body.appendChild(node);
|
|
60
|
-
return {
|
|
61
|
-
destroy() {
|
|
62
|
-
node.remove();
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
58
|
function close() {
|
|
68
59
|
if (!open) return;
|
|
69
60
|
open = false;
|
|
@@ -127,8 +118,11 @@
|
|
|
127
118
|
|
|
128
119
|
{#if open}
|
|
129
120
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
121
|
+
<!-- Promoted to the top layer so overflow/transform ancestors cannot clip it. Unlike a
|
|
122
|
+
body portal, the menu stays inside its subtree, so it remains usable inside a
|
|
123
|
+
modal Dialog (everything outside an open modal is inert). -->
|
|
130
124
|
<div
|
|
131
|
-
use:
|
|
125
|
+
use:topLayer
|
|
132
126
|
bind:this={menuEl}
|
|
133
127
|
class="pui-ctxmenu {classes}"
|
|
134
128
|
style="left: {posX}px; top: {posY}px; visibility: {placed ? 'visible' : 'hidden'};"
|
package/dist/ui/Dialog.svelte
CHANGED
|
@@ -25,7 +25,13 @@
|
|
|
25
25
|
title?: string | undefined;
|
|
26
26
|
/** Render without the Paper wrapper component */
|
|
27
27
|
noPaper?: boolean;
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Let content overflow the dialog bounds instead of scrolling inside it.
|
|
30
|
+
* The body scrolls by default; dropdowns, pickers and tooltips render in
|
|
31
|
+
* the browser's top layer, so they are never clipped by that scroll.
|
|
32
|
+
*/
|
|
33
|
+
allowOverflow?: boolean;
|
|
34
|
+
/** @deprecated Scrolling is now the default; use `allowOverflow` to opt out. */
|
|
29
35
|
preventOverflow?: boolean;
|
|
30
36
|
/** Size preset for the dialog width */
|
|
31
37
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
@@ -42,6 +48,7 @@
|
|
|
42
48
|
allowImplicitClose = true,
|
|
43
49
|
title = undefined,
|
|
44
50
|
noPaper = false,
|
|
51
|
+
allowOverflow = false,
|
|
45
52
|
preventOverflow = false,
|
|
46
53
|
size = 'md',
|
|
47
54
|
class: classes = '',
|
|
@@ -50,6 +57,12 @@
|
|
|
50
57
|
}: DialogProps = $props();
|
|
51
58
|
|
|
52
59
|
const uid = $props.id();
|
|
60
|
+
|
|
61
|
+
// preventOverflow is the legacy opt-in for the behaviour that is now default,
|
|
62
|
+
// so it wins over allowOverflow when both are set
|
|
63
|
+
const overflowClass = $derived(
|
|
64
|
+
allowOverflow && !preventOverflow ? 'overflow-visible' : 'overflow-y-auto'
|
|
65
|
+
);
|
|
53
66
|
const titleId = `${uid}-title`;
|
|
54
67
|
|
|
55
68
|
let dialogElement: HTMLDialogElement | undefined = $state(undefined);
|
|
@@ -142,7 +155,7 @@
|
|
|
142
155
|
{/if}
|
|
143
156
|
</div>
|
|
144
157
|
{/if}
|
|
145
|
-
<div class="dialog-body {
|
|
158
|
+
<div class="dialog-body {overflowClass}">
|
|
146
159
|
{@render children?.()}
|
|
147
160
|
</div>
|
|
148
161
|
{#if footer}
|
|
@@ -169,7 +182,7 @@
|
|
|
169
182
|
{#if noPaper}
|
|
170
183
|
{@render DialogInner()}
|
|
171
184
|
{:else}
|
|
172
|
-
<div class="dialog-paper {
|
|
185
|
+
<div class="dialog-paper {overflowClass}">
|
|
173
186
|
<Paper containerClass={classes}>
|
|
174
187
|
{@render DialogInner()}
|
|
175
188
|
</Paper>
|
|
@@ -18,7 +18,13 @@ export interface DialogProps {
|
|
|
18
18
|
title?: string | undefined;
|
|
19
19
|
/** Render without the Paper wrapper component */
|
|
20
20
|
noPaper?: boolean;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Let content overflow the dialog bounds instead of scrolling inside it.
|
|
23
|
+
* The body scrolls by default; dropdowns, pickers and tooltips render in
|
|
24
|
+
* the browser's top layer, so they are never clipped by that scroll.
|
|
25
|
+
*/
|
|
26
|
+
allowOverflow?: boolean;
|
|
27
|
+
/** @deprecated Scrolling is now the default; use `allowOverflow` to opt out. */
|
|
22
28
|
preventOverflow?: boolean;
|
|
23
29
|
/** Size preset for the dialog width */
|
|
24
30
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
package/dist/ui/Dropdown.svelte
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import type { Hyperlink } from '../models/Hyperlink.js';
|
|
6
6
|
import LinkCollection from '../display/LinkCollection.svelte';
|
|
7
7
|
import { iconChevronDown } from '../icon/index.js';
|
|
8
|
+
import { floating } from '../util/Floating.js';
|
|
9
|
+
import { clickOutside } from '../util/ClickOutside.js';
|
|
8
10
|
|
|
9
11
|
export interface DropdownProps {
|
|
10
12
|
/** Whether the dropdown is expanded (bindable) */
|
|
@@ -32,16 +34,32 @@
|
|
|
32
34
|
class: classes = '',
|
|
33
35
|
alignToButton = 'left'
|
|
34
36
|
}: DropdownProps = $props();
|
|
37
|
+
|
|
38
|
+
let triggerElement: HTMLElement | undefined = $state(undefined);
|
|
35
39
|
</script>
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
<!-- The floating content is still a DOM descendant of this wrapper (only its rendering
|
|
42
|
+
moves to the top layer), so a contains() check covers both the button and the menu -->
|
|
43
|
+
<div
|
|
44
|
+
class="dropdown {classes} {alignToButton}"
|
|
45
|
+
bind:this={triggerElement}
|
|
46
|
+
use:clickOutside={() => (show = false)}
|
|
47
|
+
>
|
|
38
48
|
<Button class="ps-2" {variant} svg={buttonSvg} onclick={() => (show = !show)}>
|
|
39
49
|
{label}
|
|
40
50
|
</Button>
|
|
41
51
|
{#if show}
|
|
52
|
+
<!-- Rendered in the top layer so a scrolling Dialog body cannot clip it -->
|
|
42
53
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
43
54
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
44
|
-
<div
|
|
55
|
+
<div
|
|
56
|
+
class="dropdown-content"
|
|
57
|
+
use:floating={{
|
|
58
|
+
anchor: () => triggerElement,
|
|
59
|
+
placement: alignToButton === 'right' ? 'bottom-end' : 'bottom-start'
|
|
60
|
+
}}
|
|
61
|
+
onclick={(e) => e.stopPropagation()}
|
|
62
|
+
>
|
|
45
63
|
{#if links.length > 0 && Array.isArray(links[0])}
|
|
46
64
|
{#each links as group}
|
|
47
65
|
<div class="dropdown-group">
|
|
@@ -60,10 +78,8 @@
|
|
|
60
78
|
position: relative;
|
|
61
79
|
}
|
|
62
80
|
|
|
81
|
+
/* Position and top-layer promotion come from use:floating */
|
|
63
82
|
.dropdown-content {
|
|
64
|
-
position: absolute;
|
|
65
|
-
top: 100%;
|
|
66
|
-
left: 0;
|
|
67
83
|
background-color: var(--paper-body-bg);
|
|
68
84
|
min-width: 160px;
|
|
69
85
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
|
|
@@ -94,11 +110,6 @@
|
|
|
94
110
|
background-color: var(--border-color);
|
|
95
111
|
}
|
|
96
112
|
|
|
97
|
-
.dropdown.right .dropdown-content {
|
|
98
|
-
left: auto;
|
|
99
|
-
right: 0;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
113
|
:global(.dark) {
|
|
103
114
|
.dropdown-content :global(a) {
|
|
104
115
|
color: var(--ui-accent);
|
|
@@ -114,9 +114,7 @@
|
|
|
114
114
|
if (!accepts(ctx)) return;
|
|
115
115
|
const host = container;
|
|
116
116
|
if (!host) return;
|
|
117
|
-
const itemEls = Array.from(
|
|
118
|
-
host.querySelectorAll<HTMLElement>(':scope > .pui-msortable-item')
|
|
119
|
-
);
|
|
117
|
+
const itemEls = Array.from(host.querySelectorAll<HTMLElement>(':scope > .pui-msortable-item'));
|
|
120
118
|
if (itemEls.length === 0) {
|
|
121
119
|
dropIndex = null;
|
|
122
120
|
return;
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
// For maxPageButtons, we need to fit: first, last, and some middle pages + ellipsis
|
|
49
49
|
// Reserve 2 slots for first and last pages, leaving maxPageButtons - 2 for middle + ellipsis
|
|
50
50
|
const middleSlots = maxPageButtons - 2;
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
// Calculate how many pages we can show around the selected page
|
|
53
53
|
const sidePages = Math.floor((middleSlots - 1) / 2); // -1 to account for potential ellipsis
|
|
54
54
|
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
display: flex;
|
|
135
135
|
justify-content: center;
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
|
|
138
138
|
:global(.dark) .pagination-container :global(.paginate-button.secondary-selected) {
|
|
139
139
|
color: black;
|
|
140
140
|
}
|