@dryui/ui 1.5.0 → 1.6.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/app-frame/app-frame.svelte +10 -3
- package/dist/button-group/context.svelte.js +4 -7
- package/dist/calendar/calendar-root.svelte +15 -32
- package/dist/chip-group/context.svelte.d.ts +2 -4
- package/dist/chip-group/context.svelte.js +2 -9
- package/dist/context-menu/context-menu-content.svelte +24 -12
- package/dist/context-menu/context-menu-group.svelte +3 -2
- package/dist/context-menu/context-menu-item.svelte +8 -61
- package/dist/context-menu/context-menu-label.svelte +3 -11
- package/dist/context-menu/context-menu-root.svelte +10 -29
- package/dist/context-menu/context-menu-separator.svelte +2 -9
- package/dist/context-menu/context.svelte.d.ts +2 -12
- package/dist/date-picker/datepicker-content.svelte +11 -81
- package/dist/date-picker/datepicker-content.svelte.d.ts +1 -1
- package/dist/date-picker/datepicker-input-root.svelte +39 -47
- package/dist/date-range-picker/date-range-picker-content.svelte +11 -75
- package/dist/date-range-picker/date-range-picker-content.svelte.d.ts +1 -1
- package/dist/date-range-picker/date-range-picker-root.svelte +44 -49
- package/dist/drag-and-drop/group-context.svelte.d.ts +1 -1
- package/dist/drag-and-drop/group-context.svelte.js +4 -4
- package/dist/dropdown-menu/context.svelte.d.ts +2 -8
- package/dist/dropdown-menu/dropdown-menu-content.svelte +15 -3
- package/dist/dropdown-menu/dropdown-menu-group.svelte +3 -2
- package/dist/dropdown-menu/dropdown-menu-item.svelte +8 -61
- package/dist/dropdown-menu/dropdown-menu-label.svelte +3 -11
- package/dist/dropdown-menu/dropdown-menu-root.svelte +10 -21
- package/dist/dropdown-menu/dropdown-menu-separator.svelte +2 -9
- package/dist/flip-card/context.svelte.d.ts +5 -0
- package/dist/flip-card/context.svelte.js +2 -0
- package/dist/flip-card/flip-card-back.svelte +2 -2
- package/dist/flip-card/flip-card-root.svelte +42 -15
- package/dist/heading/heading.svelte +10 -1
- package/dist/heading/heading.svelte.d.ts +1 -0
- package/dist/heading/index.d.ts +1 -0
- package/dist/hover-card/hover-card-content.svelte +9 -21
- package/dist/hover-card/hover-card-root.svelte +2 -2
- package/dist/hover-card/hover-card-root.svelte.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/internal/anchored-overlay-content.svelte.d.ts +20 -0
- package/dist/internal/anchored-overlay-content.svelte.js +28 -0
- package/dist/internal/date-family-controller.svelte.d.ts +45 -0
- package/dist/internal/date-family-controller.svelte.js +99 -0
- package/dist/internal/menu-group.svelte +15 -0
- package/dist/internal/menu-group.svelte.d.ts +9 -0
- package/dist/internal/menu-item.svelte +82 -0
- package/dist/internal/menu-item.svelte.d.ts +11 -0
- package/dist/internal/menu-label.svelte +24 -0
- package/dist/internal/menu-label.svelte.d.ts +9 -0
- package/dist/internal/menu-root-state.svelte.d.ts +24 -0
- package/dist/internal/menu-root-state.svelte.js +42 -0
- package/dist/internal/menu-separator.svelte +19 -0
- package/dist/internal/menu-separator.svelte.d.ts +7 -0
- package/dist/internal/motion.js +12 -1
- package/dist/internal/picker-popover-content.svelte +112 -0
- package/dist/internal/picker-popover-content.svelte.d.ts +16 -0
- package/dist/link-preview/link-preview-content.svelte +7 -10
- package/dist/list/list-item-icon.svelte +3 -3
- package/dist/list/list-item-icon.svelte.d.ts +1 -1
- package/dist/list/list-item-text.svelte +3 -3
- package/dist/list/list-item-text.svelte.d.ts +1 -1
- package/dist/list/list-item.svelte +58 -35
- package/dist/list/list-item.svelte.d.ts +8 -2
- package/dist/popover/popover-content.svelte +9 -11
- package/dist/range-calendar/range-calendar-root.svelte +13 -19
- package/dist/text/index.d.ts +1 -0
- package/dist/text/text.svelte +3 -1
- package/dist/text/text.svelte.d.ts +1 -0
- package/dist/theme-toggle/index.d.ts +18 -0
- package/dist/theme-toggle/index.js +3 -0
- package/dist/theme-toggle/theme-controller.svelte.d.ts +54 -0
- package/dist/theme-toggle/theme-controller.svelte.js +121 -0
- package/dist/theme-toggle/theme-flash.d.ts +16 -0
- package/dist/theme-toggle/theme-flash.js +38 -0
- package/dist/theme-toggle/theme-toggle.svelte +189 -0
- package/dist/theme-toggle/theme-toggle.svelte.d.ts +40 -0
- package/dist/tooltip/tooltip-content.svelte +8 -10
- package/dist/typography/heading.svelte +13 -89
- package/dist/typography/heading.svelte.d.ts +3 -8
- package/dist/typography/index.d.ts +8 -7
- package/dist/typography/text.svelte +12 -84
- package/dist/typography/text.svelte.d.ts +3 -10
- package/package.json +7 -2
- package/skills/dryui/SKILL.md +18 -5
- package/skills/dryui/rules/composition.md +1 -1
- package/skills/dryui/rules/theming.md +1 -2
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { generateFormId } from '@dryui/primitives';
|
|
2
|
+
function createBaseMenuRootState(options) {
|
|
3
|
+
const triggerId = generateFormId(`${options.idBase}-trigger`);
|
|
4
|
+
const contentId = generateFormId(`${options.idBase}-content`);
|
|
5
|
+
return {
|
|
6
|
+
triggerId,
|
|
7
|
+
contentId,
|
|
8
|
+
triggerEl: null,
|
|
9
|
+
show() {
|
|
10
|
+
options.setOpen(true);
|
|
11
|
+
},
|
|
12
|
+
close() {
|
|
13
|
+
options.setOpen(false);
|
|
14
|
+
},
|
|
15
|
+
toggle() {
|
|
16
|
+
options.setOpen(!options.getOpen());
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createMenuRootState(options) {
|
|
21
|
+
return {
|
|
22
|
+
get open() {
|
|
23
|
+
return options.getOpen();
|
|
24
|
+
},
|
|
25
|
+
...createBaseMenuRootState(options)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function createPositionedMenuRootState(options) {
|
|
29
|
+
let position = $state({ x: 0, y: 0 });
|
|
30
|
+
return {
|
|
31
|
+
get open() {
|
|
32
|
+
return options.getOpen();
|
|
33
|
+
},
|
|
34
|
+
...createBaseMenuRootState(options),
|
|
35
|
+
get position() {
|
|
36
|
+
return position;
|
|
37
|
+
},
|
|
38
|
+
set position(value) {
|
|
39
|
+
position = value;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
className?: HTMLAttributes<HTMLDivElement>['class'];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let { className, ...rest }: Props = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div role="separator" class={className} {...rest}></div>
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
div {
|
|
15
|
+
height: 1px;
|
|
16
|
+
background: var(--dry-color-stroke-weak);
|
|
17
|
+
margin: var(--dry-space-1) 0;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
className?: HTMLAttributes<HTMLDivElement>['class'];
|
|
4
|
+
}
|
|
5
|
+
declare const MenuSeparator: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type MenuSeparator = ReturnType<typeof MenuSeparator>;
|
|
7
|
+
export default MenuSeparator;
|
package/dist/internal/motion.js
CHANGED
|
@@ -11,8 +11,19 @@ export function supportsScrollTimelines() {
|
|
|
11
11
|
return (CSS.supports('animation-timeline: view()') || CSS.supports('scroll-timeline-name: --dry-scroll'));
|
|
12
12
|
}
|
|
13
13
|
export function extractThemeColor(property, element) {
|
|
14
|
+
if (typeof document === 'undefined') {
|
|
15
|
+
return [0, 0, 0];
|
|
16
|
+
}
|
|
17
|
+
const readComputedStyle = typeof getComputedStyle === 'function'
|
|
18
|
+
? getComputedStyle
|
|
19
|
+
: typeof window !== 'undefined' && typeof window.getComputedStyle === 'function'
|
|
20
|
+
? window.getComputedStyle.bind(window)
|
|
21
|
+
: null;
|
|
22
|
+
if (!readComputedStyle) {
|
|
23
|
+
return [0, 0, 0];
|
|
24
|
+
}
|
|
14
25
|
const el = element ?? document.documentElement;
|
|
15
|
-
const value =
|
|
26
|
+
const value = readComputedStyle(el).getPropertyValue(property).trim();
|
|
16
27
|
// Parse hex (#rgb, #rrggbb)
|
|
17
28
|
const hexMatch = value.match(/^#([0-9a-f]{3,8})$/i);
|
|
18
29
|
if (hexMatch) {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fromAction } from 'svelte/attachments';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
import { createAnchoredPopover, type Placement } from '@dryui/primitives';
|
|
6
|
+
import type { PickerPopoverController } from './date-family-controller.svelte.js';
|
|
7
|
+
|
|
8
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
controller: PickerPopoverController;
|
|
10
|
+
dataAttribute: 'data-dp-content' | 'data-drp-content';
|
|
11
|
+
placement?: Placement;
|
|
12
|
+
offset?: number;
|
|
13
|
+
contentClass?: HTMLAttributes<HTMLDivElement>['class'];
|
|
14
|
+
contentStyle?: HTMLAttributes<HTMLDivElement>['style'];
|
|
15
|
+
children: Snippet;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
controller,
|
|
20
|
+
dataAttribute,
|
|
21
|
+
placement = 'bottom-start',
|
|
22
|
+
offset = 8,
|
|
23
|
+
contentClass,
|
|
24
|
+
contentStyle,
|
|
25
|
+
children,
|
|
26
|
+
...rest
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
let el = $state<HTMLDivElement | null>(null);
|
|
30
|
+
|
|
31
|
+
const markerAttrs = $derived.by<Record<string, string>>(() => ({
|
|
32
|
+
'data-picker-popover-content': '',
|
|
33
|
+
[dataAttribute]: ''
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
function attachContent(node: HTMLDivElement) {
|
|
37
|
+
el = node;
|
|
38
|
+
|
|
39
|
+
return () => {
|
|
40
|
+
if (el === node) {
|
|
41
|
+
el = null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const popover = createAnchoredPopover({
|
|
47
|
+
triggerEl: () => controller.triggerEl,
|
|
48
|
+
contentEl: () => el ?? null,
|
|
49
|
+
open: () => controller.open,
|
|
50
|
+
placement: () => placement,
|
|
51
|
+
offset: () => offset
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<div
|
|
56
|
+
{@attach attachContent}
|
|
57
|
+
{@attach fromAction(popover.applyPosition, () => contentStyle)}
|
|
58
|
+
popover="auto"
|
|
59
|
+
role="dialog"
|
|
60
|
+
id={controller.contentId}
|
|
61
|
+
aria-labelledby={controller.triggerId}
|
|
62
|
+
data-state={controller.open ? 'open' : 'closed'}
|
|
63
|
+
class={contentClass}
|
|
64
|
+
{...markerAttrs}
|
|
65
|
+
ontoggle={(e) => {
|
|
66
|
+
const newState = (e as ToggleEvent).newState === 'open';
|
|
67
|
+
|
|
68
|
+
if (newState && !controller.open) {
|
|
69
|
+
controller.show();
|
|
70
|
+
} else if (!newState && controller.open) {
|
|
71
|
+
controller.close();
|
|
72
|
+
}
|
|
73
|
+
}}
|
|
74
|
+
{...rest}
|
|
75
|
+
>
|
|
76
|
+
{@render children()}
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
[data-picker-popover-content] {
|
|
81
|
+
inset: unset;
|
|
82
|
+
margin: 0;
|
|
83
|
+
display: inline-grid;
|
|
84
|
+
padding: var(--dry-space-3);
|
|
85
|
+
border: 1px solid var(--dry-color-stroke-weak);
|
|
86
|
+
border-radius: var(--dry-radius-lg);
|
|
87
|
+
background: var(--dry-color-bg-overlay);
|
|
88
|
+
box-shadow: var(--dry-shadow-lg);
|
|
89
|
+
color: var(--dry-color-text-strong);
|
|
90
|
+
transition:
|
|
91
|
+
opacity var(--dry-duration-fast) var(--dry-ease-emphasized),
|
|
92
|
+
transform var(--dry-duration-fast) var(--dry-ease-emphasized);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
[data-picker-popover-content]:not(:popover-open) {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[data-picker-popover-content]:popover-open {
|
|
100
|
+
display: inline-grid;
|
|
101
|
+
opacity: 1;
|
|
102
|
+
transform: translateY(0) scale(1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@starting-style {
|
|
106
|
+
[data-picker-popover-content]:popover-open {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
transform: translateY(calc(var(--dry-motion-distance-xs) * -1))
|
|
109
|
+
scale(var(--dry-motion-scale-enter));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type Placement } from '@dryui/primitives';
|
|
4
|
+
import type { PickerPopoverController } from './date-family-controller.svelte.js';
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
|
+
controller: PickerPopoverController;
|
|
7
|
+
dataAttribute: 'data-dp-content' | 'data-drp-content';
|
|
8
|
+
placement?: Placement;
|
|
9
|
+
offset?: number;
|
|
10
|
+
contentClass?: HTMLAttributes<HTMLDivElement>['class'];
|
|
11
|
+
contentStyle?: HTMLAttributes<HTMLDivElement>['style'];
|
|
12
|
+
children: Snippet;
|
|
13
|
+
}
|
|
14
|
+
declare const PickerPopoverContent: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type PickerPopoverContent = ReturnType<typeof PickerPopoverContent>;
|
|
16
|
+
export default PickerPopoverContent;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import { createAnchoredPopover } from '@dryui/primitives';
|
|
5
4
|
import type { Placement } from '@dryui/primitives';
|
|
5
|
+
import { createAnchoredOverlayContent } from '../internal/anchored-overlay-content.svelte.js';
|
|
6
6
|
import { getLinkPreviewCtx } from './context.svelte.js';
|
|
7
7
|
|
|
8
8
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -22,25 +22,22 @@
|
|
|
22
22
|
|
|
23
23
|
const ctx = getLinkPreviewCtx();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const popover = createAnchoredPopover({
|
|
28
|
-
triggerEl: () => ctx.triggerEl,
|
|
29
|
-
contentEl: () => contentEl ?? null,
|
|
30
|
-
open: () => ctx.open,
|
|
25
|
+
const overlay = createAnchoredOverlayContent({
|
|
26
|
+
ctx,
|
|
31
27
|
placement: () => placement,
|
|
32
|
-
offset: () => offset
|
|
28
|
+
offset: () => offset,
|
|
29
|
+
style: () => style
|
|
33
30
|
});
|
|
34
31
|
</script>
|
|
35
32
|
|
|
36
33
|
<div
|
|
37
|
-
|
|
34
|
+
{@attach overlay.bindContent}
|
|
35
|
+
{@attach overlay.position}
|
|
38
36
|
id={ctx.contentId}
|
|
39
37
|
role="tooltip"
|
|
40
38
|
popover="manual"
|
|
41
39
|
data-link-preview-content
|
|
42
40
|
data-state={ctx.open ? 'open' : 'closed'}
|
|
43
|
-
use:popover.applyPosition={style}
|
|
44
41
|
onmouseenter={() => ctx.showImmediate()}
|
|
45
42
|
onmouseleave={() => ctx.close()}
|
|
46
43
|
class={className}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
|
|
5
|
-
interface Props extends HTMLAttributes<
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
6
|
children: Snippet;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
let { class: className, children, ...rest }: Props = $props();
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
|
-
<
|
|
12
|
+
<span data-list-item-icon class={className} {...rest}>
|
|
13
13
|
{@render children()}
|
|
14
|
-
</
|
|
14
|
+
</span>
|
|
15
15
|
|
|
16
16
|
<style>
|
|
17
17
|
[data-list-item-icon] {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
4
|
children: Snippet;
|
|
5
5
|
}
|
|
6
6
|
declare const ListItemIcon: import("svelte").Component<Props, {}, "">;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
|
|
5
|
-
interface Props extends HTMLAttributes<
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
6
|
primary?: Snippet;
|
|
7
7
|
secondary?: Snippet;
|
|
8
8
|
children?: Snippet;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
let { class: className, primary, secondary, children, ...rest }: Props = $props();
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
|
-
<
|
|
14
|
+
<span data-list-item-text class={className} {...rest}>
|
|
15
15
|
{#if primary}
|
|
16
16
|
<span data-list-item-primary>{@render primary()}</span>
|
|
17
17
|
{:else if children}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
{#if secondary}
|
|
21
21
|
<span data-list-item-secondary>{@render secondary()}</span>
|
|
22
22
|
{/if}
|
|
23
|
-
</
|
|
23
|
+
</span>
|
|
24
24
|
|
|
25
25
|
<style>
|
|
26
26
|
[data-list-item-text] {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
4
|
primary?: Snippet;
|
|
5
5
|
secondary?: Snippet;
|
|
6
6
|
children?: Snippet;
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ClassValue, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
4
|
+
import Button from '../button/button.svelte';
|
|
4
5
|
import { getListCtx } from './context.svelte.js';
|
|
5
6
|
|
|
6
|
-
interface Props extends
|
|
7
|
+
interface Props extends Omit<
|
|
8
|
+
HTMLAttributes<HTMLLIElement>,
|
|
9
|
+
'children' | 'class' | 'onclick' | 'onkeydown' | 'aria-label' | 'aria-labelledby' | 'title'
|
|
10
|
+
> {
|
|
7
11
|
interactive?: boolean;
|
|
8
12
|
disabled?: boolean;
|
|
13
|
+
class?: ClassValue;
|
|
9
14
|
children: Snippet;
|
|
15
|
+
onclick?: HTMLButtonAttributes['onclick'];
|
|
16
|
+
onkeydown?: HTMLButtonAttributes['onkeydown'];
|
|
17
|
+
'aria-label'?: HTMLButtonAttributes['aria-label'];
|
|
18
|
+
'aria-labelledby'?: HTMLButtonAttributes['aria-labelledby'];
|
|
19
|
+
title?: string;
|
|
10
20
|
}
|
|
11
21
|
|
|
12
22
|
let {
|
|
@@ -15,74 +25,87 @@
|
|
|
15
25
|
class: className,
|
|
16
26
|
children,
|
|
17
27
|
onclick,
|
|
28
|
+
onkeydown,
|
|
29
|
+
'aria-label': ariaLabel,
|
|
30
|
+
'aria-labelledby': ariaLabelledBy,
|
|
31
|
+
title,
|
|
18
32
|
...rest
|
|
19
33
|
}: Props = $props();
|
|
20
34
|
|
|
21
35
|
const ctx = getListCtx();
|
|
22
|
-
|
|
23
|
-
function handleKeydown(e: KeyboardEvent) {
|
|
24
|
-
if (!interactive || disabled) return;
|
|
25
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
26
|
-
e.preventDefault();
|
|
27
|
-
if (onclick) {
|
|
28
|
-
(onclick as (e: Event) => void)(e);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
36
|
</script>
|
|
33
37
|
|
|
34
|
-
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
35
38
|
<li
|
|
36
39
|
data-list-item
|
|
37
40
|
data-interactive={interactive || undefined}
|
|
38
41
|
data-disabled={disabled || undefined}
|
|
39
42
|
data-dense={ctx.dense || undefined}
|
|
40
|
-
role={interactive ? 'button' : undefined}
|
|
41
|
-
tabindex={interactive && !disabled ? 0 : undefined}
|
|
42
|
-
aria-disabled={disabled || undefined}
|
|
43
43
|
class={className}
|
|
44
|
-
{onclick}
|
|
45
|
-
onkeydown={interactive ? handleKeydown : undefined}
|
|
46
44
|
{...rest}
|
|
47
45
|
>
|
|
48
|
-
{
|
|
46
|
+
{#if interactive}
|
|
47
|
+
<Button
|
|
48
|
+
variant="secondary"
|
|
49
|
+
{disabled}
|
|
50
|
+
aria-label={ariaLabel}
|
|
51
|
+
aria-labelledby={ariaLabelledBy}
|
|
52
|
+
{title}
|
|
53
|
+
{onclick}
|
|
54
|
+
{onkeydown}
|
|
55
|
+
>
|
|
56
|
+
<span data-list-item-surface>
|
|
57
|
+
{@render children()}
|
|
58
|
+
</span>
|
|
59
|
+
</Button>
|
|
60
|
+
{:else}
|
|
61
|
+
<div data-list-item-surface>
|
|
62
|
+
{@render children()}
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
49
65
|
</li>
|
|
50
66
|
|
|
51
67
|
<style>
|
|
52
68
|
[data-list-item] {
|
|
69
|
+
display: grid;
|
|
70
|
+
list-style: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[data-list-item-surface] {
|
|
53
74
|
display: grid;
|
|
54
75
|
grid-template-columns: auto minmax(0, 1fr);
|
|
55
76
|
align-items: start;
|
|
56
77
|
gap: var(--dry-list-item-gap);
|
|
57
78
|
padding: var(--dry-list-item-padding);
|
|
79
|
+
border: 0;
|
|
58
80
|
border-radius: var(--dry-list-item-radius);
|
|
81
|
+
background: transparent;
|
|
82
|
+
color: inherit;
|
|
83
|
+
font: inherit;
|
|
84
|
+
text-align: left;
|
|
59
85
|
transition:
|
|
60
86
|
background var(--dry-duration-fast) var(--dry-ease-default),
|
|
61
87
|
color var(--dry-duration-fast) var(--dry-ease-default);
|
|
62
88
|
}
|
|
63
89
|
|
|
64
90
|
[data-list-item][data-interactive='true'] {
|
|
91
|
+
--dry-btn-bg: transparent;
|
|
92
|
+
--dry-btn-border: transparent;
|
|
93
|
+
--dry-btn-color: inherit;
|
|
94
|
+
--dry-btn-padding-x: 0;
|
|
95
|
+
--dry-btn-padding-y: 0;
|
|
96
|
+
--dry-btn-min-height: 0;
|
|
97
|
+
--dry-btn-accent: var(--dry-list-item-active-bg);
|
|
98
|
+
--dry-btn-accent-fg: inherit;
|
|
99
|
+
--dry-btn-accent-stroke: transparent;
|
|
100
|
+
--dry-btn-accent-weak: var(--dry-list-item-hover-bg);
|
|
101
|
+
--dry-btn-on-accent: inherit;
|
|
102
|
+
--dry-btn-radius: var(--dry-list-item-radius);
|
|
103
|
+
box-shadow: none;
|
|
65
104
|
cursor: pointer;
|
|
66
105
|
}
|
|
67
106
|
|
|
68
|
-
[data-list-item][data-interactive='true']:hover,
|
|
69
|
-
[data-list-item][data-interactive='true']:focus-visible {
|
|
70
|
-
background: var(--dry-list-item-hover-bg);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
[data-list-item][data-interactive='true']:active {
|
|
74
|
-
background: var(--dry-list-item-active-bg);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
[data-list-item][data-interactive='true']:focus-visible {
|
|
78
|
-
outline: var(--dry-focus-ring);
|
|
79
|
-
outline-offset: -2px;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
107
|
[data-list-item][data-disabled='true'] {
|
|
83
108
|
opacity: var(--dry-state-disabled-opacity);
|
|
84
|
-
cursor: not-allowed;
|
|
85
|
-
pointer-events: none;
|
|
86
109
|
}
|
|
87
110
|
|
|
88
111
|
[data-list-item][data-dense='true'] {
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLLIElement> {
|
|
2
|
+
import type { ClassValue, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends Omit<HTMLAttributes<HTMLLIElement>, 'children' | 'class' | 'onclick' | 'onkeydown' | 'aria-label' | 'aria-labelledby' | 'title'> {
|
|
4
4
|
interactive?: boolean;
|
|
5
5
|
disabled?: boolean;
|
|
6
|
+
class?: ClassValue;
|
|
6
7
|
children: Snippet;
|
|
8
|
+
onclick?: HTMLButtonAttributes['onclick'];
|
|
9
|
+
onkeydown?: HTMLButtonAttributes['onkeydown'];
|
|
10
|
+
'aria-label'?: HTMLButtonAttributes['aria-label'];
|
|
11
|
+
'aria-labelledby'?: HTMLButtonAttributes['aria-labelledby'];
|
|
12
|
+
title?: string;
|
|
7
13
|
}
|
|
8
14
|
declare const ListItem: import("svelte").Component<Props, {}, "">;
|
|
9
15
|
type ListItem = ReturnType<typeof ListItem>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import {
|
|
4
|
+
import { createDismiss } from '@dryui/primitives';
|
|
5
5
|
import type { Placement } from '@dryui/primitives';
|
|
6
|
+
import { createAnchoredOverlayContent } from '../internal/anchored-overlay-content.svelte.js';
|
|
6
7
|
import { getPopoverCtx } from './context.svelte.js';
|
|
7
8
|
|
|
8
9
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -22,20 +23,17 @@
|
|
|
22
23
|
|
|
23
24
|
const ctx = getPopoverCtx();
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const popover = createAnchoredPopover({
|
|
28
|
-
triggerEl: () => ctx.triggerEl,
|
|
29
|
-
contentEl: () => contentEl ?? null,
|
|
30
|
-
open: () => ctx.open,
|
|
26
|
+
const overlay = createAnchoredOverlayContent({
|
|
27
|
+
ctx,
|
|
31
28
|
placement: () => placement,
|
|
32
|
-
offset: () => offset
|
|
29
|
+
offset: () => offset,
|
|
30
|
+
style: () => style
|
|
33
31
|
});
|
|
34
32
|
|
|
35
33
|
createDismiss({
|
|
36
34
|
enabled: () => ctx.open,
|
|
37
35
|
onDismiss: () => ctx.close(),
|
|
38
|
-
contentEl:
|
|
36
|
+
contentEl: overlay.contentEl,
|
|
39
37
|
triggerEl: () => ctx.triggerEl,
|
|
40
38
|
preventDefaultOnEscape: true,
|
|
41
39
|
returnFocusTo: () => ctx.triggerEl
|
|
@@ -43,12 +41,12 @@
|
|
|
43
41
|
</script>
|
|
44
42
|
|
|
45
43
|
<div
|
|
46
|
-
|
|
44
|
+
{@attach overlay.bindContent}
|
|
45
|
+
{@attach overlay.position}
|
|
47
46
|
id={ctx.contentId}
|
|
48
47
|
popover="manual"
|
|
49
48
|
data-popover-content
|
|
50
49
|
data-state={ctx.open ? 'open' : 'closed'}
|
|
51
|
-
use:popover.applyPosition={style}
|
|
52
50
|
class={className}
|
|
53
51
|
{...rest}
|
|
54
52
|
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import {
|
|
4
|
+
import { createDateViewController } from '../internal/date-family-controller.svelte.js';
|
|
5
5
|
import { setRangeCalendarCtx } from './context.svelte.js';
|
|
6
6
|
|
|
7
7
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
...rest
|
|
27
27
|
}: Props = $props();
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const view = createDateViewController({
|
|
30
|
+
initialDate: startDate,
|
|
31
|
+
locale: () => locale
|
|
32
|
+
});
|
|
30
33
|
|
|
31
|
-
let viewMonth = $state(startDate ? startDate.getMonth() : new Date().getMonth());
|
|
32
|
-
let viewYear = $state(startDate ? startDate.getFullYear() : new Date().getFullYear());
|
|
33
|
-
let focusedDate = $state<Date>(startDate ?? new Date());
|
|
34
34
|
let hoveredDate = $state<Date | null>(null);
|
|
35
35
|
|
|
36
36
|
let selecting = $state(false);
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
return hoveredDate;
|
|
47
47
|
},
|
|
48
48
|
get focusedDate() {
|
|
49
|
-
return focusedDate;
|
|
49
|
+
return view.focusedDate;
|
|
50
50
|
},
|
|
51
51
|
get viewMonth() {
|
|
52
|
-
return viewMonth;
|
|
52
|
+
return view.viewMonth;
|
|
53
53
|
},
|
|
54
54
|
get viewYear() {
|
|
55
|
-
return viewYear;
|
|
55
|
+
return view.viewYear;
|
|
56
56
|
},
|
|
57
57
|
get locale() {
|
|
58
58
|
return locale;
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
return disabled;
|
|
68
68
|
},
|
|
69
69
|
get weekStartDay() {
|
|
70
|
-
return weekStartDay;
|
|
70
|
+
return view.weekStartDay;
|
|
71
71
|
},
|
|
72
72
|
selectDate(date: Date) {
|
|
73
73
|
if (!selecting) {
|
|
@@ -83,25 +83,19 @@
|
|
|
83
83
|
}
|
|
84
84
|
selecting = false;
|
|
85
85
|
}
|
|
86
|
-
|
|
86
|
+
view.focusDate(date);
|
|
87
87
|
},
|
|
88
88
|
setHoveredDate(date: Date | null) {
|
|
89
89
|
hoveredDate = date;
|
|
90
90
|
},
|
|
91
91
|
nextMonth() {
|
|
92
|
-
|
|
93
|
-
viewMonth = next.getMonth();
|
|
94
|
-
viewYear = next.getFullYear();
|
|
92
|
+
view.nextMonth();
|
|
95
93
|
},
|
|
96
94
|
prevMonth() {
|
|
97
|
-
|
|
98
|
-
viewMonth = prev.getMonth();
|
|
99
|
-
viewYear = prev.getFullYear();
|
|
95
|
+
view.prevMonth();
|
|
100
96
|
},
|
|
101
97
|
setFocusedDate(date: Date) {
|
|
102
|
-
|
|
103
|
-
viewMonth = date.getMonth();
|
|
104
|
-
viewYear = date.getFullYear();
|
|
98
|
+
view.setFocusedDate(date);
|
|
105
99
|
}
|
|
106
100
|
});
|
|
107
101
|
</script>
|
package/dist/text/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface TextProps extends HTMLAttributes<HTMLElement> {
|
|
|
7
7
|
font?: 'sans' | 'mono';
|
|
8
8
|
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
|
|
9
9
|
variant?: 'default' | 'label';
|
|
10
|
+
className?: HTMLAttributes<HTMLElement>['class'];
|
|
10
11
|
children: Snippet;
|
|
11
12
|
}
|
|
12
13
|
export { default as Text } from './text.svelte';
|
package/dist/text/text.svelte
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
font?: 'sans' | 'mono';
|
|
11
11
|
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
|
|
12
12
|
variant?: 'default' | 'label';
|
|
13
|
+
className?: HTMLAttributes<HTMLElement>['class'];
|
|
13
14
|
children: Snippet;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -20,7 +21,8 @@
|
|
|
20
21
|
font = 'sans',
|
|
21
22
|
weight,
|
|
22
23
|
variant = 'default',
|
|
23
|
-
class:
|
|
24
|
+
class: classAttr,
|
|
25
|
+
className = classAttr,
|
|
24
26
|
children,
|
|
25
27
|
...rest
|
|
26
28
|
}: Props = $props();
|
|
@@ -7,6 +7,7 @@ interface Props extends HTMLAttributes<HTMLElement> {
|
|
|
7
7
|
font?: 'sans' | 'mono';
|
|
8
8
|
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
|
|
9
9
|
variant?: 'default' | 'label';
|
|
10
|
+
className?: HTMLAttributes<HTMLElement>['class'];
|
|
10
11
|
children: Snippet;
|
|
11
12
|
}
|
|
12
13
|
declare const Text: import("svelte").Component<Props, {}, "">;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ClassValue, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
export { createThemeController } from './theme-controller.svelte.js';
|
|
4
|
+
export type { ThemeMode, ThemeController, ThemeControllerOptions } from './theme-controller.svelte.js';
|
|
5
|
+
export { themeFlashScript } from './theme-flash.js';
|
|
6
|
+
import type { ThemeController, ThemeMode } from './theme-controller.svelte.js';
|
|
7
|
+
export interface ThemeToggleProps extends Omit<HTMLButtonAttributes, 'onclick' | 'onkeydown' | 'disabled' | 'class'> {
|
|
8
|
+
storageKey?: string;
|
|
9
|
+
size?: 'sm' | 'md' | 'lg';
|
|
10
|
+
controller?: ThemeController;
|
|
11
|
+
'aria-label'?: string;
|
|
12
|
+
sunIcon?: Snippet;
|
|
13
|
+
moonIcon?: Snippet;
|
|
14
|
+
onModeChange?: (mode: ThemeMode) => void;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
class?: ClassValue;
|
|
17
|
+
}
|
|
18
|
+
export { default as ThemeToggle } from './theme-toggle.svelte';
|