@svelte-atoms/core 1.0.0-alpha.44 → 1.0.0-alpha.46
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/README.md +13 -0
- package/dist/components/accordion/item/accordion-item-body.svelte +5 -8
- package/dist/components/accordion/item/accordion-item-header.svelte +0 -13
- package/dist/components/accordion/item/accordion-item-indicator.svelte +0 -12
- package/dist/components/accordion/item/accordion-item-root.svelte +0 -12
- package/dist/components/alert/alert-actions.svelte +0 -12
- package/dist/components/alert/alert-close-button.svelte +0 -12
- package/dist/components/alert/alert-content.svelte +0 -12
- package/dist/components/alert/alert-description.svelte +0 -12
- package/dist/components/alert/alert-icon.svelte +0 -12
- package/dist/components/alert/alert-root.svelte +1 -13
- package/dist/components/alert/alert-title.svelte +0 -12
- package/dist/components/atom/html-atom.svelte +31 -17
- package/dist/components/atom/types.d.ts +9 -0
- package/dist/components/atom/utils/base.d.ts +6 -0
- package/dist/components/atom/utils/base.js +8 -0
- package/dist/components/atom/utils/cache.d.ts +17 -0
- package/dist/components/atom/utils/cache.js +134 -0
- package/dist/components/atom/utils/classes.d.ts +14 -0
- package/dist/components/atom/utils/classes.js +42 -0
- package/dist/components/atom/utils/constants.d.ts +9 -0
- package/dist/components/atom/utils/constants.js +9 -0
- package/dist/components/atom/utils/index.d.ts +6 -0
- package/dist/components/atom/utils/index.js +5 -0
- package/dist/components/atom/utils/preset.d.ts +22 -0
- package/dist/components/atom/utils/preset.js +94 -0
- package/dist/components/atom/utils/props.d.ts +13 -0
- package/dist/components/atom/utils/props.js +60 -0
- package/dist/components/atom/utils/variants.d.ts +31 -0
- package/dist/components/atom/utils/variants.js +270 -0
- package/dist/components/card/card-body.svelte +0 -12
- package/dist/components/card/card-description.svelte +0 -12
- package/dist/components/card/card-footer.svelte +0 -12
- package/dist/components/card/card-header.svelte +0 -12
- package/dist/components/card/card-media.svelte +0 -12
- package/dist/components/card/card-root.svelte +0 -12
- package/dist/components/card/card-subtitle.svelte +0 -12
- package/dist/components/card/card-title.svelte +0 -12
- package/dist/components/collapsible/collapsible-body.svelte +5 -12
- package/dist/components/collapsible/collapsible-header.svelte +0 -12
- package/dist/components/collapsible/collapsible-indicator.svelte +0 -12
- package/dist/components/collapsible/collapsible-root.svelte +0 -12
- package/dist/components/combobox/combobox-control.svelte +0 -12
- package/dist/components/combobox/combobox-item.svelte +0 -12
- package/dist/components/combobox/combobox-item.svelte.d.ts +0 -6
- package/dist/components/combobox/index.d.ts +1 -1
- package/dist/components/container/container.svelte +0 -12
- package/dist/components/datagrid/column/datagrid-column-sort-icon.svelte +3 -12
- package/dist/components/datagrid/column/datagrid-column-sort-icon.svelte.d.ts +0 -6
- package/dist/components/datagrid/datagrid-body.svelte +17 -1
- package/dist/components/dialog/dialog-body.svelte +0 -12
- package/dist/components/dialog/dialog-close-button.svelte +0 -12
- package/dist/components/dialog/dialog-close.svelte +0 -12
- package/dist/components/dialog/dialog-content.svelte +4 -12
- package/dist/components/dialog/dialog-description.svelte +0 -12
- package/dist/components/dialog/dialog-footer.svelte +0 -12
- package/dist/components/dialog/dialog-header.svelte +0 -12
- package/dist/components/dialog/dialog-title.svelte +0 -12
- package/dist/components/dialog/index.d.ts +3 -0
- package/dist/components/dialog/index.js +3 -0
- package/dist/components/drawer/drawer-backdrop.svelte +0 -12
- package/dist/components/drawer/drawer-body.svelte +0 -12
- package/dist/components/drawer/drawer-content.svelte +5 -12
- package/dist/components/drawer/drawer-description.svelte +0 -12
- package/dist/components/drawer/drawer-footer.svelte +0 -12
- package/dist/components/drawer/drawer-header.svelte +0 -12
- package/dist/components/drawer/drawer-root.svelte +5 -4
- package/dist/components/drawer/drawer-title.svelte +0 -12
- package/dist/components/dropdown/dropdown-placeholder.svelte +0 -6
- package/dist/components/dropdown/dropdown-placeholder.svelte.d.ts +0 -6
- package/dist/components/dropdown/dropdown-query.svelte +0 -12
- package/dist/components/dropdown-menu/bond.svelte.d.ts +0 -4
- package/dist/components/dropdown-menu/dropdown-menu-content.svelte +0 -12
- package/dist/components/dropdown-menu/dropdown-menu-content.svelte.d.ts +0 -6
- package/dist/components/dropdown-menu/index.d.ts +1 -1
- package/dist/components/form/field/bond.svelte.d.ts +29 -17
- package/dist/components/form/field/bond.svelte.js +73 -49
- package/dist/components/form/field/field-control.svelte +21 -18
- package/dist/components/form/field/field-label.svelte +2 -2
- package/dist/components/form/field/field-root.svelte +2 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/input/input-file-control.svelte +0 -12
- package/dist/components/input/input-icon.svelte +3 -3
- package/dist/components/input/input-number-control.svelte +28 -35
- package/dist/components/input/input-text-control.svelte +8 -3
- package/dist/components/input/input-url-control.svelte +2 -2
- package/dist/components/input/types.d.ts +4 -4
- package/dist/components/kbd/index.d.ts +3 -0
- package/dist/components/kbd/index.js +3 -0
- package/dist/components/kbd/kbd.svelte +19 -0
- package/dist/components/kbd/kbd.svelte.d.ts +4 -0
- package/dist/components/kbd/shortcut.svelte +38 -0
- package/dist/components/kbd/shortcut.svelte.d.ts +4 -0
- package/dist/components/kbd/types.d.ts +20 -0
- package/dist/components/kbd/types.js +1 -0
- package/dist/components/layer/layer-inner.svelte +0 -12
- package/dist/components/layer/layer-root.svelte +0 -12
- package/dist/components/menu/menu-content.svelte +0 -12
- package/dist/components/menu/menu-content.svelte.d.ts +0 -6
- package/dist/components/popover/bond.svelte.d.ts +29 -1
- package/dist/components/popover/bond.svelte.js +55 -2
- package/dist/components/popover/index.d.ts +1 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/popover/popover-arrow.svelte +4 -2
- package/dist/components/popover/popover-content.svelte +17 -90
- package/dist/components/popover/popover-overlay.svelte +98 -0
- package/dist/components/popover/popover-overlay.svelte.d.ts +4 -0
- package/dist/components/popover/popover-trigger.svelte +9 -0
- package/dist/components/popover/strategies/floating.svelte +10 -10
- package/dist/components/popover/types.d.ts +7 -2
- package/dist/components/portal/portal-inner.svelte +0 -12
- package/dist/components/portal/portal-root.svelte +0 -12
- package/dist/components/portal/types.d.ts +1 -1
- package/dist/components/progress/index.d.ts +3 -0
- package/dist/components/progress/index.js +3 -0
- package/dist/components/progress/progress-circular.svelte +99 -0
- package/dist/components/progress/progress-circular.svelte.d.ts +6 -0
- package/dist/components/progress/progress-linear.svelte +66 -0
- package/dist/components/progress/progress-linear.svelte.d.ts +6 -0
- package/dist/components/progress/types.d.ts +18 -0
- package/dist/components/progress/types.js +1 -0
- package/dist/components/scrollable/scrollable-container.svelte +0 -12
- package/dist/components/scrollable/scrollable-content.svelte +0 -12
- package/dist/components/scrollable/scrollable-root.svelte +0 -12
- package/dist/components/scrollable/scrollable-thumb.svelte +1 -12
- package/dist/components/scrollable/scrollable-track.svelte +0 -12
- package/dist/components/select/bond.svelte.d.ts +0 -4
- package/dist/components/select/index.d.ts +1 -1
- package/dist/components/select/select-placeholder.svelte +0 -6
- package/dist/components/select/select-placeholder.svelte.d.ts +0 -6
- package/dist/components/sidebar/sidebar-content.svelte +5 -12
- package/dist/components/stack/bond.svelte.js +6 -0
- package/dist/components/stack/stack-item.svelte +4 -0
- package/dist/components/switch/switch.svelte +2 -0
- package/dist/components/tabs/tab/tab-header.svelte +4 -4
- package/dist/components/tabs/tabs-body.svelte +0 -2
- package/dist/components/tabs/tabs-root.svelte +11 -3
- package/dist/components/toast/atoms.d.ts +1 -1
- package/dist/components/toast/atoms.js +1 -1
- package/dist/components/toast/attachments.svelte.d.ts +10 -2
- package/dist/components/toast/attachments.svelte.js +9 -1
- package/dist/components/toast/bond.svelte.d.ts +73 -0
- package/dist/components/toast/bond.svelte.js +132 -0
- package/dist/components/toast/index.d.ts +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/toast/toast-close.svelte +47 -0
- package/dist/components/toast/toast-close.svelte.d.ts +26 -0
- package/dist/components/toast/toast-description.svelte +16 -24
- package/dist/components/toast/toast-description.svelte.d.ts +15 -19
- package/dist/components/toast/toast-root.svelte +36 -26
- package/dist/components/toast/toast-root.svelte.d.ts +16 -15
- package/dist/components/toast/toast-title.svelte +17 -22
- package/dist/components/toast/toast-title.svelte.d.ts +13 -13
- package/dist/components/toast/toaster.svelte.d.ts +38 -0
- package/dist/components/toast/toaster.svelte.js +107 -0
- package/dist/components/toast/types.d.ts +13 -21
- package/dist/components/tree/tree-body.svelte +5 -12
- package/dist/components/tree/tree-header.svelte +0 -12
- package/dist/components/tree/tree-indicator.svelte +0 -12
- package/dist/components/tree/tree-root.svelte +0 -12
- package/dist/context/preset.svelte.d.ts +53 -37
- package/dist/context/preset.svelte.js +29 -3
- package/package.json +1 -1
- package/dist/components/atom/utils.d.ts +0 -44
- package/dist/components/atom/utils.js +0 -275
- package/dist/components/popover/popover-engine.svelte +0 -118
- package/dist/components/popover/popover-engine.svelte.d.ts +0 -3
- package/dist/components/toast/bond.d.ts +0 -35
- package/dist/components/toast/bond.js +0 -59
- package/dist/components/toast/manager.svelte.d.ts +0 -38
- package/dist/components/toast/manager.svelte.js +0 -82
- package/dist/components/toast/toast-root-managed.svelte +0 -64
- package/dist/components/toast/toast-root-managed.svelte.d.ts +0 -7
- package/dist/components/toast/toast-toaster.svelte +0 -42
- package/dist/components/toast/toast-toaster.svelte.d.ts +0 -4
- /package/dist/components/popover/{motion.d.ts → motion.svelte.d.ts} +0 -0
- /package/dist/components/popover/{motion.js → motion.svelte.js} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts" generics="E extends HtmlElementTagName, B extends Base = Base">
|
|
2
|
-
import { PortalBond, PortalsBond
|
|
2
|
+
import { PortalBond, PortalsBond } from '../portal';
|
|
3
3
|
import { HtmlAtom, type Base } from '../atom';
|
|
4
4
|
import type { HtmlElementTagName } from '../element';
|
|
5
|
+
import { clickout } from '../../attachments';
|
|
5
6
|
import { PopoverBond } from './bond.svelte';
|
|
6
|
-
import { animatePopoverContent } from './motion';
|
|
7
|
-
import { ZLayer } from '../portal/zlayer.svelte';
|
|
7
|
+
import { animatePopoverContent } from './motion.svelte';
|
|
8
8
|
import type { PopoverContentProps } from './types';
|
|
9
9
|
import Floating from './strategies/floating.svelte';
|
|
10
|
-
import
|
|
10
|
+
import PopoverOverlay from './popover-overlay.svelte';
|
|
11
11
|
|
|
12
12
|
const bond = PopoverBond.get();
|
|
13
13
|
|
|
@@ -15,18 +15,6 @@
|
|
|
15
15
|
throw new Error('<PopoverOverlay /> must be used within a <Popover />');
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const positionStrategy = $derived(bond?.state.props.positionStrategy ?? 'absolute');
|
|
19
|
-
|
|
20
|
-
const parentLayer = (() => {
|
|
21
|
-
try {
|
|
22
|
-
return ZLayer.get();
|
|
23
|
-
} catch {
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
})();
|
|
27
|
-
|
|
28
|
-
const layer = new ZLayer('popover', () => parentLayer?.get() ?? 0).share();
|
|
29
|
-
|
|
30
18
|
const activePortalBond = $derived.by(() => {
|
|
31
19
|
const key = bond.state.props.portal;
|
|
32
20
|
if (key instanceof PortalBond) {
|
|
@@ -42,73 +30,21 @@
|
|
|
42
30
|
|
|
43
31
|
let {
|
|
44
32
|
class: klass = '',
|
|
33
|
+
overlay: Overlay = PopoverOverlay,
|
|
45
34
|
children = undefined,
|
|
46
|
-
animate = animatePopoverContent(),
|
|
47
35
|
onclickoutside = undefined,
|
|
36
|
+
fallback = {
|
|
37
|
+
animate: animatePopoverContent()
|
|
38
|
+
},
|
|
48
39
|
...restProps
|
|
49
40
|
}: PopoverContentProps<E, B> = $props();
|
|
50
41
|
|
|
51
|
-
const isOpen = $derived(bond.state.isOpen && !!bond.elements.trigger);
|
|
52
42
|
const portalId = $derived(activePortalBond?.id);
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const position = bond.state.position;
|
|
59
|
-
|
|
60
|
-
if (!position) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const { placement, x = 0, y = 0, middlewareData } = position;
|
|
65
|
-
const offset = bond.state.props.offset;
|
|
66
|
-
const openState = +isOpen;
|
|
67
|
-
|
|
68
|
-
// Calculate direction multipliers based on placement
|
|
69
|
-
const directionY = placement?.startsWith('top') ? -1 : placement?.startsWith('bottom') ? 1 : 0;
|
|
70
|
-
const directionX = placement?.startsWith('left') ? -1 : placement?.startsWith('right') ? 1 : 0;
|
|
71
|
-
|
|
72
|
-
// Calculate arrow dimensions and delta
|
|
73
|
-
const arrowWidth = bond?.elements.arrow?.clientWidth ?? 0;
|
|
74
|
-
const arrowHeight = bond?.elements.arrow?.clientHeight ?? 0;
|
|
75
|
-
const arrowDelta = middlewareData?.arrow ? 1 : 0;
|
|
76
|
-
|
|
77
|
-
// Calculate final position with offset and arrow adjustment
|
|
78
|
-
const finalX = x + directionX * offset * openState + arrowDelta * directionX * arrowWidth;
|
|
79
|
-
const finalY = y + directionY * offset * openState + arrowDelta * directionY * arrowHeight;
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
transform: `translate3d(${finalX}px, ${finalY}px, 1px)`,
|
|
83
|
-
opacity: openState.toString()
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function containerInitial(this: typeof bond.state, node: HTMLElement) {
|
|
88
|
-
const styles = calculatePosition();
|
|
89
|
-
|
|
90
|
-
// Hide content until position is calculated to avoid ghosting
|
|
91
|
-
if (!styles) {
|
|
92
|
-
node.style.opacity = '0';
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
node.style.transform = styles.transform;
|
|
97
|
-
node.style.opacity = styles.opacity;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function containerAnimate(this: typeof bond.state, node: HTMLElement) {
|
|
101
|
-
void bond.state.props.open; // Ensure reactivity to open state changes
|
|
102
|
-
|
|
103
|
-
const styles = calculatePosition();
|
|
104
|
-
|
|
105
|
-
if (!styles) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
node.style.transform = styles.transform;
|
|
110
|
-
node.style.opacity = '1';
|
|
111
|
-
}
|
|
44
|
+
const contentProps = $derived({
|
|
45
|
+
...bond?.content().spread,
|
|
46
|
+
...restProps
|
|
47
|
+
});
|
|
112
48
|
|
|
113
49
|
function clickoutAttachement(node: HTMLElement) {
|
|
114
50
|
const cleanup = clickout((ev) => {
|
|
@@ -119,7 +55,7 @@
|
|
|
119
55
|
|
|
120
56
|
const trigger = bond.element('trigger');
|
|
121
57
|
|
|
122
|
-
if (trigger && (trigger.contains(ev.target as Node) || trigger === ev.target)) {
|
|
58
|
+
if (trigger instanceof Element && (trigger.contains(ev.target as Node) || trigger === ev.target)) {
|
|
123
59
|
return;
|
|
124
60
|
}
|
|
125
61
|
|
|
@@ -132,28 +68,19 @@
|
|
|
132
68
|
|
|
133
69
|
<Floating />
|
|
134
70
|
|
|
135
|
-
<
|
|
136
|
-
portal={portalId ?? 'root.l0'}
|
|
137
|
-
as="div"
|
|
138
|
-
class="top-0 left-0 h-min w-fit outline-none pointer-events-none"
|
|
139
|
-
style="z-index: {layer.get()}; position: {positionStrategy};"
|
|
140
|
-
initial={containerInitial?.bind(bond.state)}
|
|
141
|
-
animate={containerAnimate?.bind(bond.state)}
|
|
142
|
-
{...bond.content().spread}
|
|
143
|
-
>
|
|
71
|
+
<Overlay portal={portalId ?? 'root.l0'} as="div">
|
|
144
72
|
<HtmlAtom
|
|
145
73
|
{@attach clickoutAttachement}
|
|
146
74
|
{bond}
|
|
75
|
+
{fallback}
|
|
147
76
|
preset="popover.content"
|
|
148
77
|
class={[
|
|
149
78
|
'popover-content bg-popover text-popover-foreground border-border rounded-md border p-2 opacity-0 shadow-lg outline-none',
|
|
150
|
-
// isOpen && 'pointer-events-auto',
|
|
151
79
|
'$preset',
|
|
152
80
|
klass
|
|
153
81
|
]}
|
|
154
|
-
|
|
155
|
-
{...restProps}
|
|
82
|
+
{...contentProps}
|
|
156
83
|
>
|
|
157
84
|
{@render children?.({ popover: bond })}
|
|
158
85
|
</HtmlAtom>
|
|
159
|
-
</
|
|
86
|
+
</Overlay>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Teleport, ZLayer } from "../portal";
|
|
3
|
+
import { PopoverBond } from "./bond.svelte";
|
|
4
|
+
import type { PopoverOverlayProps } from "./types";
|
|
5
|
+
|
|
6
|
+
const bond = PopoverBond.get();
|
|
7
|
+
const isOpen = $derived(bond?.state.isOpen ?? false);
|
|
8
|
+
const positionStrategy = $derived(bond?.state.props.positionStrategy ?? 'absolute');
|
|
9
|
+
|
|
10
|
+
const parentLayer = (() => {
|
|
11
|
+
try {
|
|
12
|
+
return ZLayer.get();
|
|
13
|
+
} catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
17
|
+
|
|
18
|
+
const layer = new ZLayer('popover', () => parentLayer?.get() ?? 0).share();
|
|
19
|
+
|
|
20
|
+
let { portal, children = undefined, ...restProps}: PopoverOverlayProps = $props();
|
|
21
|
+
|
|
22
|
+
const overlayProps = $derived({
|
|
23
|
+
...bond?.overlay().spread,
|
|
24
|
+
...restProps
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Calculate the final position and opacity for the popover content
|
|
29
|
+
*/
|
|
30
|
+
function calculatePosition() {
|
|
31
|
+
const position = bond.state.position;
|
|
32
|
+
|
|
33
|
+
if (!position) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const { placement, x = 0, y = 0, middlewareData } = position;
|
|
38
|
+
const offset = bond.state.props.offset;
|
|
39
|
+
const openState = +isOpen;
|
|
40
|
+
|
|
41
|
+
// Calculate direction multipliers based on placement
|
|
42
|
+
const directionY = placement?.startsWith('top') ? -1 : placement?.startsWith('bottom') ? 1 : 0;
|
|
43
|
+
const directionX = placement?.startsWith('left') ? -1 : placement?.startsWith('right') ? 1 : 0;
|
|
44
|
+
|
|
45
|
+
const arrow = bond.element('arrow');
|
|
46
|
+
// Calculate arrow dimensions and delta
|
|
47
|
+
const arrowWidth = arrow?.clientWidth ?? 0;
|
|
48
|
+
const arrowHeight = arrow?.clientHeight ?? 0;
|
|
49
|
+
const arrowDelta = middlewareData?.arrow ? 1 : 0;
|
|
50
|
+
|
|
51
|
+
// Calculate final position with offset and arrow adjustment
|
|
52
|
+
const finalX = x + directionX * offset * openState + arrowDelta * directionX * arrowWidth;
|
|
53
|
+
const finalY = y + directionY * offset * openState + arrowDelta * directionY * arrowHeight;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
transform: `translate3d(${finalX}px, ${finalY}px, 1px)`,
|
|
57
|
+
opacity: openState.toString()
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function initial(this: typeof bond.state, node: HTMLElement) {
|
|
62
|
+
const styles = calculatePosition();
|
|
63
|
+
|
|
64
|
+
// Hide content until position is calculated to avoid ghosting
|
|
65
|
+
if (!styles) {
|
|
66
|
+
node.style.opacity = '0';
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
node.style.transform = styles.transform;
|
|
71
|
+
node.style.opacity = styles.opacity;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function animate(this: typeof bond.state, node: HTMLElement) {
|
|
75
|
+
void bond.state.props.open; // Ensure reactivity to open state changes
|
|
76
|
+
|
|
77
|
+
const styles = calculatePosition();
|
|
78
|
+
|
|
79
|
+
if (!styles) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
node.style.transform = styles.transform;
|
|
84
|
+
node.style.opacity = '1';
|
|
85
|
+
}
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<Teleport
|
|
89
|
+
{portal}
|
|
90
|
+
as="div"
|
|
91
|
+
class="top-0 left-0 h-min w-fit outline-none pointer-events-none"
|
|
92
|
+
style="z-index: {layer.get()}; position: {positionStrategy};"
|
|
93
|
+
initial={initial}
|
|
94
|
+
animate={animate}
|
|
95
|
+
{...overlayProps}
|
|
96
|
+
>
|
|
97
|
+
{@render children?.({ popover: bond })}
|
|
98
|
+
</Teleport>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
as = 'button' as E,
|
|
15
15
|
preset = 'popover.trigger',
|
|
16
16
|
children = undefined,
|
|
17
|
+
onpointerenter = undefined,
|
|
17
18
|
...restProps
|
|
18
19
|
}: PopoverTriggerProps<E, B> = $props();
|
|
19
20
|
|
|
@@ -21,6 +22,13 @@
|
|
|
21
22
|
...bond.trigger().spread,
|
|
22
23
|
...restProps
|
|
23
24
|
});
|
|
25
|
+
|
|
26
|
+
function handlePointerEnter(event: PointerEvent) {
|
|
27
|
+
onpointerenter?.(event);
|
|
28
|
+
if(event.defaultPrevented) return;
|
|
29
|
+
|
|
30
|
+
bond.state.tracking = true;
|
|
31
|
+
}
|
|
24
32
|
</script>
|
|
25
33
|
|
|
26
34
|
<HtmlAtom
|
|
@@ -29,6 +37,7 @@
|
|
|
29
37
|
{preset}
|
|
30
38
|
class={['border-border flex w-fit cursor-pointer rounded-md p-2', '$preset', klass]}
|
|
31
39
|
type={as === 'button' ? 'button' : undefined}
|
|
40
|
+
onpointerenter={handlePointerEnter}
|
|
32
41
|
{...triggerProps}
|
|
33
42
|
>
|
|
34
43
|
{@render children?.({ popover: bond })}
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
const bond = PopoverBond.get();
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const tracking = $derived(bond?.state.shouldTrackPosition ?? false);
|
|
17
17
|
const reference = $derived(bond?.element<BondVirtualElement>('virtual-trigger') ?? bond?.element<Element>('trigger'));
|
|
18
|
-
const
|
|
18
|
+
const overlay = $derived(bond?.element<HTMLElement>('overlay'));
|
|
19
19
|
|
|
20
20
|
$effect.pre(() => {
|
|
21
|
-
if (!
|
|
21
|
+
if (!reference || !overlay || !tracking) return;
|
|
22
22
|
|
|
23
23
|
// Use the existing positioning behavior
|
|
24
24
|
const cleanup = compute(bond)({}, autoUpdate);
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
const arrowElement = bond.element<HTMLElement>('arrow');
|
|
34
34
|
|
|
35
35
|
// Guard: ensure required elements exist
|
|
36
|
-
if (!reference || !
|
|
36
|
+
if (!reference || !overlay) {
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
// Double rAF ensures browser has completed layout + paint
|
|
70
70
|
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
|
71
71
|
|
|
72
|
-
const position = await computePosition(reference,
|
|
72
|
+
const position = await computePosition(reference, overlay, {
|
|
73
73
|
placement: placement ?? 'bottom',
|
|
74
74
|
middleware,
|
|
75
75
|
strategy: bond.state.props.positionStrategy
|
|
@@ -79,26 +79,26 @@
|
|
|
79
79
|
const x = Math.round((position.x ?? 0) * 100) / 100;
|
|
80
80
|
const y = Math.round((position.y ?? 0) * 100) / 100;
|
|
81
81
|
|
|
82
|
-
bond.state.
|
|
82
|
+
bond.state.notifyComputed({
|
|
83
83
|
middlewareData: position.middlewareData,
|
|
84
84
|
placement: position.placement,
|
|
85
85
|
strategy: position.strategy,
|
|
86
86
|
x,
|
|
87
87
|
y
|
|
88
|
-
};
|
|
89
|
-
onchangeCallback?.(
|
|
88
|
+
});
|
|
89
|
+
onchangeCallback?.(overlay, position);
|
|
90
90
|
|
|
91
91
|
// Set minimum width to match trigger
|
|
92
92
|
if (reference && (reference instanceof Element)) {
|
|
93
93
|
requestAnimationFrame(() => {
|
|
94
|
-
|
|
94
|
+
overlay.style.minWidth = `${reference.clientWidth}px`;
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
// Use auto-update if provided, otherwise compute once
|
|
100
100
|
if (updater) {
|
|
101
|
-
return updater(reference,
|
|
101
|
+
return updater(reference, overlay, compute, {
|
|
102
102
|
ancestorScroll: false
|
|
103
103
|
});
|
|
104
104
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
2
|
import type { Placement } from '@floating-ui/dom';
|
|
3
3
|
import type { Factory } from '../../types';
|
|
4
4
|
import type { PopoverBond } from './bond.svelte';
|
|
5
5
|
import type { Base, HtmlAtomProps } from '../atom';
|
|
6
6
|
import type { HtmlElementTagName } from '../element';
|
|
7
|
-
import type { PortalBond } from '../portal';
|
|
7
|
+
import type { PortalBond, TeleportProps } from '../portal';
|
|
8
8
|
export type PopoverChildren = Snippet<[{
|
|
9
9
|
popover: PopoverBond;
|
|
10
10
|
}]>;
|
|
@@ -26,7 +26,12 @@ export interface AnimateParams {
|
|
|
26
26
|
yOffset: number;
|
|
27
27
|
open: boolean;
|
|
28
28
|
}
|
|
29
|
+
export interface PopoverOverlayProps<E extends HtmlElementTagName = 'div', B extends Base = Base> extends TeleportProps<E, B, PopoverChildren> {
|
|
30
|
+
portal: string | PortalBond;
|
|
31
|
+
children?: PopoverChildren;
|
|
32
|
+
}
|
|
29
33
|
export interface PopoverContentProps<T extends HtmlElementTagName, B extends Base = Base> extends HtmlAtomProps<T, B, PopoverChildren> {
|
|
34
|
+
overlay?: Component<PopoverOverlayProps>;
|
|
30
35
|
onclickoutside?: (ev: PointerEvent, atom: PopoverBond) => void;
|
|
31
36
|
}
|
|
32
37
|
export interface PopoverIndicatorProps<E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base> extends HtmlAtomProps<E, B, PopoverChildren> {
|
|
@@ -15,12 +15,6 @@
|
|
|
15
15
|
let {
|
|
16
16
|
class: klass = '',
|
|
17
17
|
children = undefined,
|
|
18
|
-
onmount = undefined,
|
|
19
|
-
ondestroy = undefined,
|
|
20
|
-
animate = undefined,
|
|
21
|
-
enter = undefined,
|
|
22
|
-
exit = undefined,
|
|
23
|
-
initial = undefined,
|
|
24
18
|
...restProps
|
|
25
19
|
}: HtmlAtomProps<E, B> & HTMLAttributes<Element> = $props();
|
|
26
20
|
|
|
@@ -34,12 +28,6 @@
|
|
|
34
28
|
{bond}
|
|
35
29
|
preset="portal.inner"
|
|
36
30
|
class={['border-border relative size-full', '$preset', klass]}
|
|
37
|
-
enter={enter?.bind(bond.state)}
|
|
38
|
-
exit={exit?.bind(bond.state)}
|
|
39
|
-
initial={initial?.bind(bond.state)}
|
|
40
|
-
animate={animate?.bind(bond.state)}
|
|
41
|
-
onmount={onmount?.bind(bond.state)}
|
|
42
|
-
ondestroy={ondestroy?.bind(bond.state)}
|
|
43
31
|
{...bondProps}
|
|
44
32
|
>
|
|
45
33
|
{@render children?.()}
|
|
@@ -17,12 +17,6 @@
|
|
|
17
17
|
id,
|
|
18
18
|
factory = _factory,
|
|
19
19
|
children = undefined,
|
|
20
|
-
onmount = undefined,
|
|
21
|
-
ondestroy = undefined,
|
|
22
|
-
animate = undefined,
|
|
23
|
-
enter = undefined,
|
|
24
|
-
exit = undefined,
|
|
25
|
-
initial = undefined,
|
|
26
20
|
...restProps
|
|
27
21
|
}: PortalOuterProps<E, B> & HTMLAttributes<Element> = $props();
|
|
28
22
|
|
|
@@ -64,12 +58,6 @@
|
|
|
64
58
|
{bond}
|
|
65
59
|
preset="portal"
|
|
66
60
|
class={['border-border pointer-events-none', '$preset', klass]}
|
|
67
|
-
enter={enter?.bind(bond.state)}
|
|
68
|
-
exit={exit?.bind(bond.state)}
|
|
69
|
-
initial={initial?.bind(bond.state)}
|
|
70
|
-
animate={animate?.bind(bond.state)}
|
|
71
|
-
onmount={onmount?.bind(bond.state)}
|
|
72
|
-
ondestroy={ondestroy?.bind(bond.state)}
|
|
73
61
|
{...rootProps}
|
|
74
62
|
>
|
|
75
63
|
{@render children?.()}
|
|
@@ -16,6 +16,6 @@ export type PortalOuterProps<E extends keyof HTMLElementTagNameMap = 'div', B ex
|
|
|
16
16
|
id: RootPortals | (string & {});
|
|
17
17
|
children?: Snippet;
|
|
18
18
|
};
|
|
19
|
-
export type TeleportProps<E extends HtmlElementTagName = 'div', B extends Base = Base> = HtmlAtomProps<E, B,
|
|
19
|
+
export type TeleportProps<E extends HtmlElementTagName = 'div', B extends Base = Base, Children extends Snippet<unknown[]> = PortalChildren> = HtmlAtomProps<E, B, Children> & {
|
|
20
20
|
portal?: string | PortalBond;
|
|
21
21
|
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { HtmlAtom } from '../atom';
|
|
4
|
+
import type { ProgressCircularProps } from './types';
|
|
5
|
+
import { SvgElement } from '../element'
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
class: klass = '',
|
|
9
|
+
value = null,
|
|
10
|
+
max = 100,
|
|
11
|
+
preset = 'progress.circular',
|
|
12
|
+
...restProps
|
|
13
|
+
}: ProgressCircularProps & HTMLAttributes<HTMLDivElement> = $props();
|
|
14
|
+
|
|
15
|
+
const isIndeterminate = $derived(value === null || value === undefined);
|
|
16
|
+
const percent = $derived(isIndeterminate ? null : Math.min(100, Math.max(0, (value! / max) * 100)));
|
|
17
|
+
|
|
18
|
+
const radius = 20;
|
|
19
|
+
const circumference = 2 * Math.PI * radius;
|
|
20
|
+
const strokeDashoffset = $derived(
|
|
21
|
+
isIndeterminate ? circumference : circumference - (percent! / 100) * circumference
|
|
22
|
+
);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{#snippet defaultCircularFill()}
|
|
26
|
+
<SvgElement
|
|
27
|
+
as="circle"
|
|
28
|
+
preset="progress.circular.fill"
|
|
29
|
+
cx="24"
|
|
30
|
+
cy="24"
|
|
31
|
+
r={radius}
|
|
32
|
+
fill="none"
|
|
33
|
+
stroke-width="4"
|
|
34
|
+
stroke-linecap="round"
|
|
35
|
+
stroke-dasharray={circumference}
|
|
36
|
+
stroke-dashoffset={strokeDashoffset}
|
|
37
|
+
class={[
|
|
38
|
+
'stroke-foreground origin-center duration-300',
|
|
39
|
+
!isIndeterminate && 'transition-[stroke-dashoffset]',
|
|
40
|
+
isIndeterminate && 'animate-progress-circular-indeterminate'
|
|
41
|
+
]
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.join(' ')}
|
|
44
|
+
/>
|
|
45
|
+
{/snippet}
|
|
46
|
+
|
|
47
|
+
<HtmlAtom
|
|
48
|
+
{preset}
|
|
49
|
+
as="div"
|
|
50
|
+
class={[
|
|
51
|
+
'progress-root progress-root--circular relative inline-flex items-center justify-center',
|
|
52
|
+
'$preset',
|
|
53
|
+
klass
|
|
54
|
+
]}
|
|
55
|
+
role="progressbar"
|
|
56
|
+
aria-valuemin={0}
|
|
57
|
+
aria-valuemax={max}
|
|
58
|
+
aria-valuenow={isIndeterminate ? undefined : value ?? undefined}
|
|
59
|
+
aria-valuetext={isIndeterminate ? undefined : `${Math.round(percent!)}%`}
|
|
60
|
+
data-indeterminate={isIndeterminate}
|
|
61
|
+
data-value={isIndeterminate ? undefined : value ?? undefined}
|
|
62
|
+
data-max={max}
|
|
63
|
+
data-completed={!isIndeterminate && percent === 100}
|
|
64
|
+
{...restProps}
|
|
65
|
+
>
|
|
66
|
+
<svg viewBox="0 0 48 48" class="h-full w-full -rotate-90" aria-hidden="true">
|
|
67
|
+
<SvgElement
|
|
68
|
+
as="circle"
|
|
69
|
+
preset="progress.circular.track"
|
|
70
|
+
cx="24"
|
|
71
|
+
cy="24"
|
|
72
|
+
r={radius}
|
|
73
|
+
fill="none"
|
|
74
|
+
stroke-width="4"
|
|
75
|
+
class="stroke-input"
|
|
76
|
+
/>
|
|
77
|
+
{@render defaultCircularFill()}
|
|
78
|
+
</svg>
|
|
79
|
+
</HtmlAtom>
|
|
80
|
+
|
|
81
|
+
<style>
|
|
82
|
+
@keyframes progress-circular-spin {
|
|
83
|
+
0% { transform: rotate(0deg); }
|
|
84
|
+
100% { transform: rotate(360deg); }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@keyframes progress-circular-dash {
|
|
88
|
+
0% { stroke-dashoffset: 119; }
|
|
89
|
+
50% { stroke-dashoffset: 30; }
|
|
90
|
+
100% { stroke-dashoffset: 119; }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:global(.animate-progress-circular-indeterminate) {
|
|
94
|
+
animation:
|
|
95
|
+
progress-circular-spin 1.4s linear infinite,
|
|
96
|
+
progress-circular-dash 1.4s ease-in-out infinite;
|
|
97
|
+
transform-origin: center;
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ProgressCircularProps } from './types';
|
|
3
|
+
type $$ComponentProps = ProgressCircularProps & HTMLAttributes<HTMLDivElement>;
|
|
4
|
+
declare const ProgressCircular: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ProgressCircular = ReturnType<typeof ProgressCircular>;
|
|
6
|
+
export default ProgressCircular;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { HtmlAtom } from '../atom';
|
|
4
|
+
import type { ProgressLinearProps } from './types';
|
|
5
|
+
import { HtmlElement } from '../element';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
class: klass = '',
|
|
9
|
+
value = null,
|
|
10
|
+
max = 100,
|
|
11
|
+
preset = 'progress.linear',
|
|
12
|
+
...restProps
|
|
13
|
+
}: ProgressLinearProps & HTMLAttributes<HTMLDivElement> = $props();
|
|
14
|
+
|
|
15
|
+
const isIndeterminate = $derived(value === null || value === undefined);
|
|
16
|
+
const percent = $derived(isIndeterminate ? null : Math.min(100, Math.max(0, (value! / max) * 100)));
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
{#snippet defaultLinearFill({ percent: p }: { percent: number | null })}
|
|
20
|
+
<HtmlElement
|
|
21
|
+
preset="progress.linear.fill"
|
|
22
|
+
as="div"
|
|
23
|
+
class={[
|
|
24
|
+
'progress-fill bg-foreground h-full rounded-full transition-[width] duration-300',
|
|
25
|
+
isIndeterminate && 'animate-progress-indeterminate w-1/3',
|
|
26
|
+
'$preset'
|
|
27
|
+
]}
|
|
28
|
+
style={p !== null ? `width: ${p}%` : undefined}
|
|
29
|
+
/>
|
|
30
|
+
{/snippet}
|
|
31
|
+
|
|
32
|
+
<HtmlAtom
|
|
33
|
+
{preset}
|
|
34
|
+
as="div"
|
|
35
|
+
class={['progress-root flex flex-col gap-1', '$preset', klass]}
|
|
36
|
+
role="progressbar"
|
|
37
|
+
aria-valuemin={0}
|
|
38
|
+
aria-valuemax={max}
|
|
39
|
+
aria-valuenow={isIndeterminate ? undefined : value ?? undefined}
|
|
40
|
+
aria-valuetext={isIndeterminate ? undefined : `${Math.round(percent!)}%`}
|
|
41
|
+
data-indeterminate={isIndeterminate}
|
|
42
|
+
data-value={isIndeterminate ? undefined : value ?? undefined}
|
|
43
|
+
data-max={max}
|
|
44
|
+
data-completed={!isIndeterminate && percent === 100}
|
|
45
|
+
{...restProps}
|
|
46
|
+
>
|
|
47
|
+
<HtmlElement
|
|
48
|
+
preset="progress.linear.track"
|
|
49
|
+
as="div"
|
|
50
|
+
class="progress-track bg-input border-none p-0.5 h-2 w-full overflow-hidden rounded-full border $preset"
|
|
51
|
+
>
|
|
52
|
+
{@render defaultLinearFill({ percent })}
|
|
53
|
+
</HtmlElement>
|
|
54
|
+
</HtmlAtom>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
@keyframes progress-indeterminate {
|
|
58
|
+
0% { transform: translateX(-100%); }
|
|
59
|
+
50% { transform: translateX(300%); }
|
|
60
|
+
100% { transform: translateX(-100%); }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:global(.animate-progress-indeterminate) {
|
|
64
|
+
animation: progress-indeterminate 1.8s ease-in-out infinite;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ProgressLinearProps } from './types';
|
|
3
|
+
type $$ComponentProps = ProgressLinearProps & HTMLAttributes<HTMLDivElement>;
|
|
4
|
+
declare const ProgressLinear: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ProgressLinear = ReturnType<typeof ProgressLinear>;
|
|
6
|
+
export default ProgressLinear;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HtmlAtomProps } from '../atom';
|
|
2
|
+
interface ProgressSharedProps {
|
|
3
|
+
/**
|
|
4
|
+
* Current value (0–max). Set to `null` for indeterminate state.
|
|
5
|
+
* @default null
|
|
6
|
+
*/
|
|
7
|
+
value?: number | null;
|
|
8
|
+
/**
|
|
9
|
+
* Maximum value
|
|
10
|
+
* @default 100
|
|
11
|
+
*/
|
|
12
|
+
max?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ProgressLinearProps extends HtmlAtomProps<'div'>, ProgressSharedProps {
|
|
15
|
+
}
|
|
16
|
+
export interface ProgressCircularProps extends HtmlAtomProps<'div'>, ProgressSharedProps {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -12,12 +12,6 @@
|
|
|
12
12
|
let {
|
|
13
13
|
class: klass = '',
|
|
14
14
|
children,
|
|
15
|
-
onmount,
|
|
16
|
-
ondestroy,
|
|
17
|
-
animate,
|
|
18
|
-
enter,
|
|
19
|
-
exit,
|
|
20
|
-
initial,
|
|
21
15
|
...restProps
|
|
22
16
|
}: ScrollableContainerProps<E, B> = $props();
|
|
23
17
|
|
|
@@ -52,12 +46,6 @@
|
|
|
52
46
|
'$preset',
|
|
53
47
|
klass
|
|
54
48
|
]}
|
|
55
|
-
{enter}
|
|
56
|
-
{exit}
|
|
57
|
-
{initial}
|
|
58
|
-
{animate}
|
|
59
|
-
{onmount}
|
|
60
|
-
{ondestroy}
|
|
61
49
|
{...containerProps}
|
|
62
50
|
>
|
|
63
51
|
{#if children}
|