@svelte-atoms/core 1.0.0-alpha.31 → 1.0.0-alpha.33
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 +21 -0
- package/README.md +289 -853
- package/dist/attachments/index.d.ts +1 -0
- package/dist/attachments/index.js +1 -0
- package/dist/components/accordion/accordion-root.svelte +65 -65
- package/dist/components/accordion/accordion.stories.svelte +70 -70
- package/dist/components/accordion/item/accordion-item-body.svelte +44 -44
- package/dist/components/accordion/item/accordion-item-header.svelte +51 -51
- package/dist/components/accordion/item/accordion-item-indicator.svelte +51 -51
- package/dist/components/accordion/item/accordion-item-root.svelte +66 -66
- package/dist/components/alert/alert-close-button.svelte +66 -66
- package/dist/components/alert/alert-description.svelte +42 -42
- package/dist/components/alert/alert-root.svelte +68 -68
- package/dist/components/atom/html-atom.svelte +26 -194
- package/dist/components/atom/types.d.ts +3 -2
- package/dist/components/atom/utils.d.ts +37 -0
- package/dist/components/atom/utils.js +208 -0
- package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
- package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
- package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
- package/dist/components/calendar/calendar-day.svelte +101 -101
- package/dist/components/checkbox/checkbox.svelte +159 -159
- package/dist/components/collapsible/bond.svelte.js +2 -1
- package/dist/components/collapsible/collapsible-body.svelte +3 -2
- package/dist/components/collapsible/motion.svelte.d.ts +6 -0
- package/dist/components/collapsible/motion.svelte.js +15 -0
- package/dist/components/combobox/atoms.d.ts +3 -3
- package/dist/components/combobox/atoms.js +3 -3
- package/dist/components/combobox/bond.svelte.d.ts +6 -6
- package/dist/components/combobox/bond.svelte.js +3 -26
- package/dist/components/combobox/combobox-control.svelte +52 -52
- package/dist/components/combobox/{compobox-item.svelte → combobox-item.svelte} +62 -68
- package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
- package/dist/components/combobox/combobox.stories.svelte +50 -0
- package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
- package/dist/components/datagrid/tr/datagrid-tr.svelte +90 -90
- package/dist/components/date-picker/bond.svelte.d.ts +15 -5
- package/dist/components/date-picker/bond.svelte.js +6 -11
- package/dist/components/date-picker/date-picker-calendar.svelte +1 -8
- package/dist/components/dialog/bond.svelte.js +5 -20
- package/dist/components/dialog/dialog-content.svelte +44 -44
- package/dist/components/dialog/dialog-root.svelte +91 -91
- package/dist/components/drawer/bond.svelte.d.ts +18 -16
- package/dist/components/drawer/bond.svelte.js +8 -18
- package/dist/components/drawer/drawer-content.svelte +49 -49
- package/dist/components/drawer/drawer-root.svelte +5 -4
- package/dist/components/drawer/drawer.stories.svelte +141 -144
- package/dist/components/drawer/motion.js +1 -1
- package/dist/components/dropdown/atoms.d.ts +1 -1
- package/dist/components/dropdown/atoms.js +1 -1
- package/dist/components/dropdown/bond.svelte.d.ts +21 -22
- package/dist/components/dropdown/bond.svelte.js +29 -53
- package/dist/components/dropdown/dropdown-root.svelte +65 -59
- package/dist/components/dropdown/dropdown-values.svelte +17 -17
- package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
- package/dist/components/dropdown/dropdown.stories.svelte +83 -80
- package/dist/components/dropdown/index.d.ts +1 -0
- package/dist/components/dropdown/index.js +1 -0
- package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
- package/dist/components/dropdown/item/attachments.svelte.js +2 -2
- package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
- package/dist/components/dropdown/item/controller.svelte.js +82 -0
- package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
- package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
- package/dist/components/dropdown/item/index.d.ts +3 -0
- package/dist/components/dropdown/item/index.js +3 -0
- package/dist/components/dropdown/item/types.d.ts +29 -0
- package/dist/components/dropdown/item/types.js +1 -0
- package/dist/components/list/list-item.svelte +20 -20
- package/dist/components/menu/atoms.d.ts +8 -3
- package/dist/components/menu/atoms.js +8 -3
- package/dist/components/menu/bond.svelte.d.ts +54 -0
- package/dist/components/menu/bond.svelte.js +132 -0
- package/dist/components/menu/index.d.ts +1 -0
- package/dist/components/menu/index.js +1 -0
- package/dist/components/menu/item/controller.svelte.d.ts +26 -0
- package/dist/components/menu/item/controller.svelte.js +69 -0
- package/dist/components/menu/item/index.d.ts +2 -0
- package/dist/components/menu/item/index.js +2 -0
- package/dist/components/menu/item/menu-item.svelte +103 -0
- package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
- package/dist/components/menu/item/types.d.ts +62 -0
- package/dist/components/menu/item/types.js +1 -0
- package/dist/components/menu/{menu-list.svelte → menu-content.svelte} +40 -40
- package/dist/components/menu/{menu-list.svelte.d.ts → menu-content.svelte.d.ts} +3 -3
- package/dist/components/menu/menu-root.svelte +15 -0
- package/dist/components/menu/menu-root.svelte.d.ts +8 -0
- package/dist/components/menu/menu.stories.svelte +33 -33
- package/dist/components/menu/types.d.ts +0 -7
- package/dist/components/popover/bond.svelte.d.ts +11 -14
- package/dist/components/popover/bond.svelte.js +27 -44
- package/dist/components/popover/popover-content.svelte +137 -137
- package/dist/components/popover/popover.stories.svelte +37 -49
- package/dist/components/portal/active-portal.svelte +29 -29
- package/dist/components/portal/portal-root.svelte +76 -76
- package/dist/components/portal/teleport.svelte +49 -49
- package/dist/components/radio/radio.svelte +109 -109
- package/dist/components/root/index.d.ts +1 -0
- package/dist/components/root/index.js +1 -0
- package/dist/components/root/l0-portal.svelte +8 -0
- package/dist/components/root/l0-portal.svelte.d.ts +26 -0
- package/dist/components/root/l1-portal.svelte +7 -0
- package/dist/components/root/l1-portal.svelte.d.ts +26 -0
- package/dist/components/root/root.css +119 -119
- package/dist/components/root/root.svelte +17 -18
- package/dist/components/root/root.svelte.d.ts +2 -6
- package/dist/components/root/toasts-portal.svelte +7 -0
- package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
- package/dist/components/root/types.d.ts +17 -0
- package/dist/components/sidebar/motion.svelte.js +3 -3
- package/dist/components/sidebar/sidebar-content.svelte +40 -40
- package/dist/components/textarea/textarea-input.svelte +9 -9
- package/dist/components/textarea/textarea-root.svelte +9 -9
- package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
- package/dist/components/tree/index.d.ts +1 -0
- package/dist/components/tree/index.js +1 -0
- package/dist/components/tree/motion.svelte.d.ts +6 -0
- package/dist/components/tree/motion.svelte.js +14 -0
- package/dist/components/tree/tree-body.svelte +4 -3
- package/dist/context/preset.svelte.d.ts +3 -1
- package/dist/icons/icon-copy.svelte +6 -6
- package/dist/utils/dom.svelte.d.ts +2 -0
- package/dist/utils/dom.svelte.js +21 -0
- package/dist/utils/function.d.ts +1 -1
- package/dist/utils/promise.svelte.d.ts +5 -0
- package/dist/utils/promise.svelte.js +20 -0
- package/package.json +4 -2
- package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
- package/dist/components/combobox/compobox.stories.svelte +0 -51
- package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
- package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
- package/dist/components/dropdown/item/bond.svelte.js +0 -99
- package/dist/components/menu/menu-item.svelte +0 -69
- package/dist/components/menu/menu-item.svelte.d.ts +0 -37
- package/dist/utils/markdown-to-llm.d.ts +0 -28
- package/dist/utils/markdown-to-llm.js +0 -76
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { isBefore, isSameDay, isWithinInterval } from 'date-fns';
|
|
3
|
-
import { CalendarBond } from './bond.svelte';
|
|
4
|
-
import type { CalendarDayProps } from './types';
|
|
5
|
-
import { HtmlAtom } from '../atom';
|
|
6
|
-
|
|
7
|
-
const calendarBond = CalendarBond.get();
|
|
8
|
-
|
|
9
|
-
const selectedDateStart = $derived(calendarBond?.state.props.start);
|
|
10
|
-
const selectedDateEnd = $derived(calendarBond?.state.props.end);
|
|
11
|
-
const isRange = $derived(Array.isArray(calendarBond?.state.props.type === 'range'));
|
|
12
|
-
|
|
13
|
-
let {
|
|
14
|
-
class: klass = '',
|
|
15
|
-
preset = 'calendar.day',
|
|
16
|
-
day,
|
|
17
|
-
as = 'button',
|
|
18
|
-
children = undefined,
|
|
19
|
-
onclick = handleClick,
|
|
20
|
-
...restProps
|
|
21
|
-
}: CalendarDayProps = $props();
|
|
22
|
-
|
|
23
|
-
const dayProps = $derived({
|
|
24
|
-
...calendarBond?.day(day),
|
|
25
|
-
...restProps
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const isSelected = $derived.by(() => {
|
|
29
|
-
if (selectedDateEnd && selectedDateStart) {
|
|
30
|
-
return isWithinInterval(day.date, { end: selectedDateEnd, start: selectedDateStart });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return selectedDateStart && isSameDay(day.date, selectedDateStart);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
function handleClick() {
|
|
37
|
-
if (day.disabled) return;
|
|
38
|
-
|
|
39
|
-
if (isRange) {
|
|
40
|
-
const start = calendarBond?.state.props.start;
|
|
41
|
-
if (!start) {
|
|
42
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (isBefore(new Date(day.date), new Date(start))) {
|
|
47
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
calendarBond?.state.selectEnd(new Date(day.date));
|
|
52
|
-
} else {
|
|
53
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
</script>
|
|
57
|
-
|
|
58
|
-
<HtmlAtom
|
|
59
|
-
{as}
|
|
60
|
-
{preset}
|
|
61
|
-
class={[
|
|
62
|
-
'calendar-day text-foreground border-border hover:bg-accent hover:text-accent-foreground h-12 cursor-pointer border-b border-l p-1 transition-colors',
|
|
63
|
-
day.offmonth && !day.disabled && 'text-muted-foreground/50 bg-muted/50',
|
|
64
|
-
day.weekend && 'bg-accent',
|
|
65
|
-
isSelected &&
|
|
66
|
-
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground',
|
|
67
|
-
isSelected && day.offmonth && 'bg-primary/70',
|
|
68
|
-
day.today &&
|
|
69
|
-
!day.disabled &&
|
|
70
|
-
!isSelected &&
|
|
71
|
-
'border-primary bg-primary/5 border-2 font-semibold',
|
|
72
|
-
day.disabled && 'pointer-events-none opacity-25',
|
|
73
|
-
klass
|
|
74
|
-
]}
|
|
75
|
-
data-disabled={day.disabled}
|
|
76
|
-
data-prec={day.fromPreviousMonth}
|
|
77
|
-
data-next={day.fromNextMonth}
|
|
78
|
-
data-offmonth={day.offmonth}
|
|
79
|
-
data-weekend={day.weekend}
|
|
80
|
-
data-today={day.today}
|
|
81
|
-
data-selected={isSelected}
|
|
82
|
-
{onclick}
|
|
83
|
-
{...dayProps}
|
|
84
|
-
>
|
|
85
|
-
{#if children}
|
|
86
|
-
{@render children({
|
|
87
|
-
calendar: calendarBond!
|
|
88
|
-
})}
|
|
89
|
-
{:else}
|
|
90
|
-
<span class="value">{day.dayOfMonth}</span>
|
|
91
|
-
{/if}
|
|
92
|
-
</HtmlAtom>
|
|
93
|
-
|
|
94
|
-
<style>
|
|
95
|
-
:global(.calendar-day):nth-child(7n + 1) {
|
|
96
|
-
border-left: none;
|
|
97
|
-
}
|
|
98
|
-
:global(.calendar-day):nth-last-child(-n + 7) {
|
|
99
|
-
border-bottom: none;
|
|
100
|
-
}
|
|
101
|
-
</style>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { isBefore, isSameDay, isWithinInterval } from 'date-fns';
|
|
3
|
+
import { CalendarBond } from './bond.svelte';
|
|
4
|
+
import type { CalendarDayProps } from './types';
|
|
5
|
+
import { HtmlAtom } from '../atom';
|
|
6
|
+
|
|
7
|
+
const calendarBond = CalendarBond.get();
|
|
8
|
+
|
|
9
|
+
const selectedDateStart = $derived(calendarBond?.state.props.start);
|
|
10
|
+
const selectedDateEnd = $derived(calendarBond?.state.props.end);
|
|
11
|
+
const isRange = $derived(Array.isArray(calendarBond?.state.props.type === 'range'));
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
class: klass = '',
|
|
15
|
+
preset = 'calendar.day',
|
|
16
|
+
day,
|
|
17
|
+
as = 'button',
|
|
18
|
+
children = undefined,
|
|
19
|
+
onclick = handleClick,
|
|
20
|
+
...restProps
|
|
21
|
+
}: CalendarDayProps = $props();
|
|
22
|
+
|
|
23
|
+
const dayProps = $derived({
|
|
24
|
+
...calendarBond?.day(day),
|
|
25
|
+
...restProps
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const isSelected = $derived.by(() => {
|
|
29
|
+
if (selectedDateEnd && selectedDateStart) {
|
|
30
|
+
return isWithinInterval(day.date, { end: selectedDateEnd, start: selectedDateStart });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return selectedDateStart && isSameDay(day.date, selectedDateStart);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
function handleClick() {
|
|
37
|
+
if (day.disabled) return;
|
|
38
|
+
|
|
39
|
+
if (isRange) {
|
|
40
|
+
const start = calendarBond?.state.props.start;
|
|
41
|
+
if (!start) {
|
|
42
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (isBefore(new Date(day.date), new Date(start))) {
|
|
47
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
calendarBond?.state.selectEnd(new Date(day.date));
|
|
52
|
+
} else {
|
|
53
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<HtmlAtom
|
|
59
|
+
{as}
|
|
60
|
+
{preset}
|
|
61
|
+
class={[
|
|
62
|
+
'calendar-day text-foreground border-border hover:bg-accent hover:text-accent-foreground h-12 cursor-pointer border-b border-l p-1 transition-colors',
|
|
63
|
+
day.offmonth && !day.disabled && 'text-muted-foreground/50 bg-muted/50',
|
|
64
|
+
day.weekend && 'bg-accent',
|
|
65
|
+
isSelected &&
|
|
66
|
+
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground',
|
|
67
|
+
isSelected && day.offmonth && 'bg-primary/70',
|
|
68
|
+
day.today &&
|
|
69
|
+
!day.disabled &&
|
|
70
|
+
!isSelected &&
|
|
71
|
+
'border-primary bg-primary/5 border-2 font-semibold',
|
|
72
|
+
day.disabled && 'pointer-events-none opacity-25',
|
|
73
|
+
klass
|
|
74
|
+
]}
|
|
75
|
+
data-disabled={day.disabled}
|
|
76
|
+
data-prec={day.fromPreviousMonth}
|
|
77
|
+
data-next={day.fromNextMonth}
|
|
78
|
+
data-offmonth={day.offmonth}
|
|
79
|
+
data-weekend={day.weekend}
|
|
80
|
+
data-today={day.today}
|
|
81
|
+
data-selected={isSelected}
|
|
82
|
+
{onclick}
|
|
83
|
+
{...dayProps}
|
|
84
|
+
>
|
|
85
|
+
{#if children}
|
|
86
|
+
{@render children({
|
|
87
|
+
calendar: calendarBond!
|
|
88
|
+
})}
|
|
89
|
+
{:else}
|
|
90
|
+
<span class="value">{day.dayOfMonth}</span>
|
|
91
|
+
{/if}
|
|
92
|
+
</HtmlAtom>
|
|
93
|
+
|
|
94
|
+
<style>
|
|
95
|
+
:global(.calendar-day):nth-child(7n + 1) {
|
|
96
|
+
border-left: none;
|
|
97
|
+
}
|
|
98
|
+
:global(.calendar-day):nth-last-child(-n + 7) {
|
|
99
|
+
border-bottom: none;
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { circOut } from 'svelte/easing';
|
|
3
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
-
import { scale } from 'svelte/transition';
|
|
5
|
-
import { Icon } from '../icon';
|
|
6
|
-
import { HtmlAtom } from '../atom';
|
|
7
|
-
import CheckmarkRegularIcon from '../../icons/icon-checkmark.svelte';
|
|
8
|
-
import { DURATION } from '../../shared';
|
|
9
|
-
import type { CheckboxProps } from './types';
|
|
10
|
-
import './checkbox.css';
|
|
11
|
-
|
|
12
|
-
let {
|
|
13
|
-
class: klass = '',
|
|
14
|
-
checked = $bindable(false),
|
|
15
|
-
indeterminate = $bindable(false),
|
|
16
|
-
value = $bindable(undefined),
|
|
17
|
-
group = $bindable([]),
|
|
18
|
-
disabled = false,
|
|
19
|
-
id,
|
|
20
|
-
name,
|
|
21
|
-
checkedContent,
|
|
22
|
-
indeterminateContent,
|
|
23
|
-
enter,
|
|
24
|
-
exit,
|
|
25
|
-
initial,
|
|
26
|
-
onchange,
|
|
27
|
-
oninput,
|
|
28
|
-
onblur,
|
|
29
|
-
onfocus,
|
|
30
|
-
onclick = undefined,
|
|
31
|
-
...restProps
|
|
32
|
-
}: CheckboxProps & Exclude<HTMLInputAttributes, 'type'> = $props();
|
|
33
|
-
|
|
34
|
-
let checkboxElement: HTMLInputElement | undefined = $state();
|
|
35
|
-
|
|
36
|
-
// Computed state for visual representation
|
|
37
|
-
const isChecked = $derived(checked === true);
|
|
38
|
-
const isIndeterminate = $derived(indeterminate === true);
|
|
39
|
-
const showCheckmark = $derived(isChecked && !isIndeterminate);
|
|
40
|
-
|
|
41
|
-
function handleChange(ev: Event) {
|
|
42
|
-
onchange?.(ev, {
|
|
43
|
-
checked: checked,
|
|
44
|
-
value: checked,
|
|
45
|
-
type: 'boolean'
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function handleInput(ev: Event) {
|
|
50
|
-
oninput?.(ev, {
|
|
51
|
-
checked: checked,
|
|
52
|
-
value: checked,
|
|
53
|
-
type: 'boolean'
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function handleClick(ev: MouseEvent) {
|
|
58
|
-
if (disabled) return;
|
|
59
|
-
|
|
60
|
-
onclick?.(ev);
|
|
61
|
-
|
|
62
|
-
if (ev.defaultPrevented) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Handle indeterminate → checked → unchecked cycle
|
|
67
|
-
if (indeterminate) {
|
|
68
|
-
// Indeterminate → checked
|
|
69
|
-
indeterminate = false;
|
|
70
|
-
checked = true;
|
|
71
|
-
} else {
|
|
72
|
-
// Toggle checked state
|
|
73
|
-
checked = !checked;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Trigger input event manually if needed
|
|
77
|
-
handleInput(ev);
|
|
78
|
-
}
|
|
79
|
-
</script>
|
|
80
|
-
|
|
81
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
82
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
83
|
-
<HtmlAtom
|
|
84
|
-
preset="checkbox"
|
|
85
|
-
as="div"
|
|
86
|
-
class={[
|
|
87
|
-
'checkbox-root border-border outline-primary bg-input text-foreground aspect-square h-5 w-fit cursor-pointer rounded-sm border outline-0 outline-offset-2 transition-colors duration-100',
|
|
88
|
-
isChecked && 'bg-foreground',
|
|
89
|
-
'$preset',
|
|
90
|
-
klass,
|
|
91
|
-
'relative'
|
|
92
|
-
]}
|
|
93
|
-
role="checkbox"
|
|
94
|
-
aria-checked={isIndeterminate ? 'mixed' : isChecked}
|
|
95
|
-
{enter}
|
|
96
|
-
{exit}
|
|
97
|
-
{initial}
|
|
98
|
-
onclick={handleClick}
|
|
99
|
-
{...restProps}
|
|
100
|
-
>
|
|
101
|
-
<input
|
|
102
|
-
bind:this={checkboxElement}
|
|
103
|
-
bind:checked
|
|
104
|
-
bind:group
|
|
105
|
-
bind:indeterminate
|
|
106
|
-
{value}
|
|
107
|
-
{id}
|
|
108
|
-
{name}
|
|
109
|
-
{disabled}
|
|
110
|
-
type="checkbox"
|
|
111
|
-
class="checkbox-input pointer-events-none"
|
|
112
|
-
onchange={handleChange}
|
|
113
|
-
oninput={handleInput}
|
|
114
|
-
{onblur}
|
|
115
|
-
{onfocus}
|
|
116
|
-
hidden
|
|
117
|
-
tabindex="-1"
|
|
118
|
-
/>
|
|
119
|
-
|
|
120
|
-
{#if isIndeterminate}
|
|
121
|
-
{#if indeterminateContent}
|
|
122
|
-
<HtmlAtom
|
|
123
|
-
preset="checkbox.indeterminate"
|
|
124
|
-
class={[
|
|
125
|
-
'checkbox-indeterminate pointer-events-none flex size-full scale-50 items-center justify-center rounded-[inherit] bg-current'
|
|
126
|
-
]}
|
|
127
|
-
base={indeterminateContent}
|
|
128
|
-
/>
|
|
129
|
-
{:else}
|
|
130
|
-
<HtmlAtom
|
|
131
|
-
preset="checkbox.indeterminate"
|
|
132
|
-
class={[
|
|
133
|
-
'checkbox-indeterminate pointer-events-none flex size-full scale-50 items-center justify-center rounded-[inherit] bg-current'
|
|
134
|
-
]}
|
|
135
|
-
/>
|
|
136
|
-
{/if}
|
|
137
|
-
{:else if showCheckmark}
|
|
138
|
-
{#if checkedContent}
|
|
139
|
-
<HtmlAtom
|
|
140
|
-
preset="checkbox.checkmark"
|
|
141
|
-
class={[
|
|
142
|
-
'checkbox-indicator text-accent pointer-events-none flex h-full content-center items-center justify-center overflow-hidden p-0.5'
|
|
143
|
-
]}
|
|
144
|
-
base={checkedContent}
|
|
145
|
-
/>
|
|
146
|
-
{:else}
|
|
147
|
-
<HtmlAtom
|
|
148
|
-
preset="checkbox.checkmark"
|
|
149
|
-
class={[
|
|
150
|
-
'checkbox-indicator text-accent pointer-events-none flex h-full content-center items-center justify-center overflow-hidden p-0.5'
|
|
151
|
-
]}
|
|
152
|
-
enter={(node) => scale(node, { duration: DURATION.fast, easing: circOut, start: 0.6 })}
|
|
153
|
-
exit={(node) => scale(node, { duration: DURATION.fast, easing: circOut, start: 0.6 })}
|
|
154
|
-
>
|
|
155
|
-
<Icon class="h-full p-0" src={CheckmarkRegularIcon} />
|
|
156
|
-
</HtmlAtom>
|
|
157
|
-
{/if}
|
|
158
|
-
{/if}
|
|
159
|
-
</HtmlAtom>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { circOut } from 'svelte/easing';
|
|
3
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
+
import { scale } from 'svelte/transition';
|
|
5
|
+
import { Icon } from '../icon';
|
|
6
|
+
import { HtmlAtom } from '../atom';
|
|
7
|
+
import CheckmarkRegularIcon from '../../icons/icon-checkmark.svelte';
|
|
8
|
+
import { DURATION } from '../../shared';
|
|
9
|
+
import type { CheckboxProps } from './types';
|
|
10
|
+
import './checkbox.css';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
class: klass = '',
|
|
14
|
+
checked = $bindable(false),
|
|
15
|
+
indeterminate = $bindable(false),
|
|
16
|
+
value = $bindable(undefined),
|
|
17
|
+
group = $bindable([]),
|
|
18
|
+
disabled = false,
|
|
19
|
+
id,
|
|
20
|
+
name,
|
|
21
|
+
checkedContent,
|
|
22
|
+
indeterminateContent,
|
|
23
|
+
enter,
|
|
24
|
+
exit,
|
|
25
|
+
initial,
|
|
26
|
+
onchange,
|
|
27
|
+
oninput,
|
|
28
|
+
onblur,
|
|
29
|
+
onfocus,
|
|
30
|
+
onclick = undefined,
|
|
31
|
+
...restProps
|
|
32
|
+
}: CheckboxProps & Exclude<HTMLInputAttributes, 'type'> = $props();
|
|
33
|
+
|
|
34
|
+
let checkboxElement: HTMLInputElement | undefined = $state();
|
|
35
|
+
|
|
36
|
+
// Computed state for visual representation
|
|
37
|
+
const isChecked = $derived(checked === true);
|
|
38
|
+
const isIndeterminate = $derived(indeterminate === true);
|
|
39
|
+
const showCheckmark = $derived(isChecked && !isIndeterminate);
|
|
40
|
+
|
|
41
|
+
function handleChange(ev: Event) {
|
|
42
|
+
onchange?.(ev, {
|
|
43
|
+
checked: checked,
|
|
44
|
+
value: checked,
|
|
45
|
+
type: 'boolean'
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function handleInput(ev: Event) {
|
|
50
|
+
oninput?.(ev, {
|
|
51
|
+
checked: checked,
|
|
52
|
+
value: checked,
|
|
53
|
+
type: 'boolean'
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function handleClick(ev: MouseEvent) {
|
|
58
|
+
if (disabled) return;
|
|
59
|
+
|
|
60
|
+
onclick?.(ev);
|
|
61
|
+
|
|
62
|
+
if (ev.defaultPrevented) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Handle indeterminate → checked → unchecked cycle
|
|
67
|
+
if (indeterminate) {
|
|
68
|
+
// Indeterminate → checked
|
|
69
|
+
indeterminate = false;
|
|
70
|
+
checked = true;
|
|
71
|
+
} else {
|
|
72
|
+
// Toggle checked state
|
|
73
|
+
checked = !checked;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Trigger input event manually if needed
|
|
77
|
+
handleInput(ev);
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
82
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
83
|
+
<HtmlAtom
|
|
84
|
+
preset="checkbox"
|
|
85
|
+
as="div"
|
|
86
|
+
class={[
|
|
87
|
+
'checkbox-root border-border outline-primary bg-input text-foreground aspect-square h-5 w-fit cursor-pointer rounded-sm border outline-0 outline-offset-2 transition-colors duration-100',
|
|
88
|
+
isChecked && 'bg-foreground',
|
|
89
|
+
'$preset',
|
|
90
|
+
klass,
|
|
91
|
+
'relative'
|
|
92
|
+
]}
|
|
93
|
+
role="checkbox"
|
|
94
|
+
aria-checked={isIndeterminate ? 'mixed' : isChecked}
|
|
95
|
+
{enter}
|
|
96
|
+
{exit}
|
|
97
|
+
{initial}
|
|
98
|
+
onclick={handleClick}
|
|
99
|
+
{...restProps}
|
|
100
|
+
>
|
|
101
|
+
<input
|
|
102
|
+
bind:this={checkboxElement}
|
|
103
|
+
bind:checked
|
|
104
|
+
bind:group
|
|
105
|
+
bind:indeterminate
|
|
106
|
+
{value}
|
|
107
|
+
{id}
|
|
108
|
+
{name}
|
|
109
|
+
{disabled}
|
|
110
|
+
type="checkbox"
|
|
111
|
+
class="checkbox-input pointer-events-none"
|
|
112
|
+
onchange={handleChange}
|
|
113
|
+
oninput={handleInput}
|
|
114
|
+
{onblur}
|
|
115
|
+
{onfocus}
|
|
116
|
+
hidden
|
|
117
|
+
tabindex="-1"
|
|
118
|
+
/>
|
|
119
|
+
|
|
120
|
+
{#if isIndeterminate}
|
|
121
|
+
{#if indeterminateContent}
|
|
122
|
+
<HtmlAtom
|
|
123
|
+
preset="checkbox.indeterminate"
|
|
124
|
+
class={[
|
|
125
|
+
'checkbox-indeterminate pointer-events-none flex size-full scale-50 items-center justify-center rounded-[inherit] bg-current'
|
|
126
|
+
]}
|
|
127
|
+
base={indeterminateContent}
|
|
128
|
+
/>
|
|
129
|
+
{:else}
|
|
130
|
+
<HtmlAtom
|
|
131
|
+
preset="checkbox.indeterminate"
|
|
132
|
+
class={[
|
|
133
|
+
'checkbox-indeterminate pointer-events-none flex size-full scale-50 items-center justify-center rounded-[inherit] bg-current'
|
|
134
|
+
]}
|
|
135
|
+
/>
|
|
136
|
+
{/if}
|
|
137
|
+
{:else if showCheckmark}
|
|
138
|
+
{#if checkedContent}
|
|
139
|
+
<HtmlAtom
|
|
140
|
+
preset="checkbox.checkmark"
|
|
141
|
+
class={[
|
|
142
|
+
'checkbox-indicator text-accent pointer-events-none flex h-full content-center items-center justify-center overflow-hidden p-0.5'
|
|
143
|
+
]}
|
|
144
|
+
base={checkedContent}
|
|
145
|
+
/>
|
|
146
|
+
{:else}
|
|
147
|
+
<HtmlAtom
|
|
148
|
+
preset="checkbox.checkmark"
|
|
149
|
+
class={[
|
|
150
|
+
'checkbox-indicator text-accent pointer-events-none flex h-full content-center items-center justify-center overflow-hidden p-0.5'
|
|
151
|
+
]}
|
|
152
|
+
enter={(node) => scale(node, { duration: DURATION.fast, easing: circOut, start: 0.6 })}
|
|
153
|
+
exit={(node) => scale(node, { duration: DURATION.fast, easing: circOut, start: 0.6 })}
|
|
154
|
+
>
|
|
155
|
+
<Icon class="h-full p-0" src={CheckmarkRegularIcon} />
|
|
156
|
+
</HtmlAtom>
|
|
157
|
+
{/if}
|
|
158
|
+
{/if}
|
|
159
|
+
</HtmlAtom>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createAttachmentKey } from 'svelte/attachments';
|
|
2
2
|
import { getContext, setContext } from 'svelte';
|
|
3
3
|
import { Bond, BondState } from '../../shared/bond.svelte';
|
|
4
|
+
import { isBrowser } from '../../utils/dom.svelte.js';
|
|
4
5
|
export class CollapsibleBond extends Bond {
|
|
5
6
|
static CONTEXT_KEY = '@atoms/context/collapsible';
|
|
6
7
|
#parent;
|
|
@@ -28,7 +29,7 @@ export class CollapsibleBond extends Bond {
|
|
|
28
29
|
header(props = {}) {
|
|
29
30
|
const isDisabled = this.state?.props?.disabled ?? false;
|
|
30
31
|
const isOpen = this.state?.props?.open ?? false;
|
|
31
|
-
const isButton = this.elements.header instanceof HTMLButtonElement;
|
|
32
|
+
const isButton = isBrowser() && this.elements.header instanceof HTMLButtonElement;
|
|
32
33
|
return {
|
|
33
34
|
'aria-disabled': isDisabled ? 'true' : 'false',
|
|
34
35
|
'aria-expanded': isOpen ? 'true' : 'false',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
|
|
2
2
|
import { HtmlAtom, type Base } from '../atom';
|
|
3
3
|
import { CollapsibleBond } from './bond.svelte';
|
|
4
|
+
import { animateCollapsibleBody } from './motion.svelte';
|
|
4
5
|
import type { CollapsibleBodyProps } from './types';
|
|
5
6
|
|
|
6
7
|
const bond = CollapsibleBond.get();
|
|
@@ -10,10 +11,10 @@
|
|
|
10
11
|
children = undefined,
|
|
11
12
|
onmount = undefined,
|
|
12
13
|
ondestroy = undefined,
|
|
13
|
-
animate =
|
|
14
|
+
animate = animateCollapsibleBody(),
|
|
14
15
|
enter = undefined,
|
|
15
16
|
exit = undefined,
|
|
16
|
-
initial =
|
|
17
|
+
initial = animateCollapsibleBody({ duration: 0 }),
|
|
17
18
|
...restProps
|
|
18
19
|
}: CollapsibleBodyProps<E, B> = $props();
|
|
19
20
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { animate } from 'motion';
|
|
2
|
+
import { CollapsibleBond } from '.';
|
|
3
|
+
import { DURATION } from '../../shared';
|
|
4
|
+
export function animateCollapsibleBody(params = {}) {
|
|
5
|
+
const bond = CollapsibleBond.get();
|
|
6
|
+
return (node) => {
|
|
7
|
+
const { duration = DURATION.fast / 1000, delay = 0, ease } = params;
|
|
8
|
+
const isOpen = bond?.state.props.open ?? false;
|
|
9
|
+
// animate(node, { opacity: +isOpen }, { duration, ease, delay });
|
|
10
|
+
animate(node, {
|
|
11
|
+
opacity: +isOpen,
|
|
12
|
+
height: isOpen ? 'auto' : 0
|
|
13
|
+
}, { duration, delay, ease });
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { default as Root } from './combobox-root.svelte';
|
|
2
2
|
export { default as Trigger } from './combobox-trigger.svelte';
|
|
3
|
-
export { default as Item } from './
|
|
3
|
+
export { default as Item } from './combobox-item.svelte';
|
|
4
4
|
/**
|
|
5
|
-
* @deprecated
|
|
5
|
+
* @deprecated Use Combobox.Control instead
|
|
6
6
|
*/
|
|
7
7
|
export { default as Input } from './combobox-control.svelte';
|
|
8
8
|
export { default as Control } from './combobox-control.svelte';
|
|
9
|
-
export { Arrow, Indicator, List, Group, Divider, Title } from '../dropdown/atoms';
|
|
9
|
+
export { Arrow, Indicator, Content, List, Group, Divider, Title } from '../dropdown/atoms';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { default as Root } from './combobox-root.svelte';
|
|
2
2
|
export { default as Trigger } from './combobox-trigger.svelte';
|
|
3
|
-
export { default as Item } from './
|
|
3
|
+
export { default as Item } from './combobox-item.svelte';
|
|
4
4
|
/**
|
|
5
|
-
* @deprecated
|
|
5
|
+
* @deprecated Use Combobox.Control instead
|
|
6
6
|
*/
|
|
7
7
|
export { default as Input } from './combobox-control.svelte';
|
|
8
8
|
export { default as Control } from './combobox-control.svelte';
|
|
9
|
-
export { Arrow, Indicator, List, Group, Divider, Title } from '../dropdown/atoms';
|
|
9
|
+
export { Arrow, Indicator, Content, List, Group, Divider, Title } from '../dropdown/atoms';
|
|
@@ -10,9 +10,8 @@ export type ComboboxBondElements = PopoverDomElements & {
|
|
|
10
10
|
};
|
|
11
11
|
export declare class ComboboxBond<T = unknown> extends DropdownBond<ComboboxBondProps, ComboboxBondState<T>, ComboboxBondElements> {
|
|
12
12
|
constructor(s: ComboboxBondState<T>);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
onkeydown: (ev: KeyboardEvent) => void;
|
|
13
|
+
control(): {
|
|
14
|
+
[x: symbol]: (node: HTMLInputElement) => void;
|
|
16
15
|
'data-atom': string;
|
|
17
16
|
'data-kind': string;
|
|
18
17
|
role: string;
|
|
@@ -21,11 +20,12 @@ export declare class ComboboxBond<T = unknown> extends DropdownBond<ComboboxBond
|
|
|
21
20
|
'aria-controls': string;
|
|
22
21
|
'aria-activedescendant': string | undefined;
|
|
23
22
|
'aria-disabled': boolean;
|
|
24
|
-
'aria-label': {};
|
|
25
23
|
tabindex: number;
|
|
24
|
+
oninput: (ev: Event) => void;
|
|
25
|
+
onkeydown: (ev: KeyboardEvent) => void;
|
|
26
26
|
};
|
|
27
|
-
static get: typeof DropdownBond.
|
|
28
|
-
static set: typeof DropdownBond.
|
|
27
|
+
static get: typeof DropdownBond.get;
|
|
28
|
+
static set: typeof DropdownBond.set;
|
|
29
29
|
}
|
|
30
30
|
export declare class ComboboxBondState<T> extends DropdownBondState<ComboboxBondProps> {
|
|
31
31
|
constructor(props: () => ComboboxBondProps);
|