@dryui/ui 1.5.1 → 1.7.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/accordion/accordion-item.svelte +9 -0
- package/dist/accordion/accordion-root.svelte +1 -1
- package/dist/alert/alert.svelte +1 -0
- package/dist/avatar/avatar.svelte +1 -1
- package/dist/button/button.svelte +3 -2
- package/dist/button-group/context.svelte.js +4 -7
- package/dist/calendar/calendar-root.svelte +15 -32
- package/dist/card/card-root.svelte +1 -0
- package/dist/chart/chart-y-axis.svelte +5 -0
- package/dist/checkbox/checkbox-input.svelte +30 -31
- package/dist/chip-group/context.svelte.d.ts +2 -4
- package/dist/chip-group/context.svelte.js +2 -9
- package/dist/combobox/combobox-content.svelte +1 -0
- package/dist/combobox/combobox-item.svelte +9 -0
- package/dist/command-palette/command-palette-item.svelte +9 -0
- package/dist/command-palette/command-palette-list.svelte +1 -0
- package/dist/context-menu/context-menu-content.svelte +25 -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/data-grid/data-grid-cell.svelte +5 -0
- 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 +22 -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/image/image.svelte +5 -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 +91 -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/modal-content.svelte +18 -0
- package/dist/internal/motion.js +12 -1
- package/dist/internal/nav-arrow-button.svelte +21 -5
- 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/menubar/menubar-content.svelte +1 -0
- package/dist/menubar/menubar-item.svelte +10 -1
- package/dist/number-input/number-input-button.svelte +1 -0
- package/dist/pin-input/pin-input-cell.svelte +1 -0
- package/dist/popover/popover-content.svelte +15 -11
- package/dist/progress/progress.svelte +1 -0
- package/dist/radio-group/radio-group-item-input.svelte +17 -2
- package/dist/range-calendar/range-calendar-root.svelte +13 -19
- package/dist/reveal/reveal.svelte +1 -1
- package/dist/select/select-content.svelte +1 -0
- package/dist/select/select-item.svelte +9 -0
- package/dist/select/select-trigger-button.svelte +18 -1
- package/dist/skeleton/skeleton.svelte +2 -0
- package/dist/slider/slider-input.svelte +1 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text/text.svelte +4 -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 +199 -0
- package/dist/theme-toggle/theme-toggle.svelte.d.ts +40 -0
- package/dist/themes/dark.css +6 -0
- package/dist/themes/default.css +92 -0
- package/dist/toast/toast-provider.svelte +1 -0
- package/dist/toast/toast-root.svelte +1 -0
- package/dist/tooltip/tooltip-content.svelte +13 -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/dist/video-embed/video-embed-button.svelte +2 -1
- 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
|
@@ -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>;
|
|
@@ -69,7 +69,16 @@
|
|
|
69
69
|
outline: none;
|
|
70
70
|
color: var(--dry-color-text-strong);
|
|
71
71
|
min-height: var(--dry-space-11);
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
transition:
|
|
74
|
+
background var(--dry-duration-fast) var(--dry-ease-default),
|
|
75
|
+
opacity var(--dry-duration-fast) var(--dry-ease-out),
|
|
76
|
+
transform var(--dry-duration-fast) var(--dry-ease-out);
|
|
77
|
+
|
|
78
|
+
@starting-style {
|
|
79
|
+
opacity: 0;
|
|
80
|
+
transform: translateY(4px);
|
|
81
|
+
}
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
[data-menubar-item]:hover:not([data-disabled]),
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
font-size: var(--dry-input-font-size);
|
|
83
83
|
line-height: var(--dry-type-small-leading);
|
|
84
84
|
font-family: var(--dry-font-sans);
|
|
85
|
+
font-variant-numeric: tabular-nums;
|
|
85
86
|
color: var(--dry-input-color);
|
|
86
87
|
background: var(--dry-input-bg);
|
|
87
88
|
border: 1px solid var(--dry-input-border);
|
|
@@ -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
|
>
|
|
@@ -63,6 +61,7 @@
|
|
|
63
61
|
--dry-popover-shadow: var(--dry-overlay-shadow, var(--dry-shadow-lg));
|
|
64
62
|
--dry-popover-padding: var(--dry-space-4);
|
|
65
63
|
--dry-radius-nested: max(0px, calc(var(--dry-popover-radius) - var(--dry-popover-padding)));
|
|
64
|
+
--dry-btn-radius: var(--dry-radius-nested);
|
|
66
65
|
|
|
67
66
|
inset: unset;
|
|
68
67
|
margin: 0;
|
|
@@ -81,6 +80,11 @@
|
|
|
81
80
|
transform var(--dry-duration-fast) var(--dry-ease-emphasized);
|
|
82
81
|
}
|
|
83
82
|
|
|
83
|
+
[data-popover-content][data-state='closed'] {
|
|
84
|
+
transition-duration: calc(var(--dry-duration-fast) / 2);
|
|
85
|
+
transition-timing-function: var(--dry-ease-out);
|
|
86
|
+
}
|
|
87
|
+
|
|
84
88
|
[data-popover-content]:not(:popover-open) {
|
|
85
89
|
display: none;
|
|
86
90
|
}
|
|
@@ -275,6 +275,7 @@
|
|
|
275
275
|
font-size: var(--dry-type-ui-caption-size, var(--dry-text-xs-size, 0.75rem));
|
|
276
276
|
color: var(--dry-color-text-weak, #64748b);
|
|
277
277
|
white-space: nowrap;
|
|
278
|
+
font-variant-numeric: tabular-nums;
|
|
278
279
|
}
|
|
279
280
|
|
|
280
281
|
[data-part='label'][data-position='inside'] {
|
|
@@ -91,12 +91,18 @@
|
|
|
91
91
|
position: absolute;
|
|
92
92
|
top: 50%;
|
|
93
93
|
left: 50%;
|
|
94
|
-
transform: translate(-50%, -50%) scale(0);
|
|
94
|
+
transform: translate(-50%, -50%) scale(0.25);
|
|
95
|
+
opacity: 0;
|
|
96
|
+
filter: blur(4px);
|
|
95
97
|
height: 8px;
|
|
96
98
|
aspect-ratio: 1;
|
|
97
99
|
border-radius: var(--dry-radius-full);
|
|
98
100
|
background: var(--dry-color-on-brand);
|
|
99
|
-
|
|
101
|
+
transform-origin: center;
|
|
102
|
+
transition:
|
|
103
|
+
opacity var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
104
|
+
transform var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
105
|
+
filter var(--dry-duration-fast) var(--dry-ease-spring-snappy);
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
[data-radio-group-item] input[type='radio']:hover:not(:disabled) {
|
|
@@ -120,6 +126,15 @@
|
|
|
120
126
|
|
|
121
127
|
[data-radio-group-item] input[type='radio']:checked::after {
|
|
122
128
|
transform: translate(-50%, -50%) scale(1);
|
|
129
|
+
opacity: 1;
|
|
130
|
+
filter: blur(0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@media (prefers-reduced-motion: reduce) {
|
|
134
|
+
[data-radio-group-item] input[type='radio']::after {
|
|
135
|
+
transition: none;
|
|
136
|
+
filter: none;
|
|
137
|
+
}
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
[data-radio-group-item] input[type='radio']:checked:hover:not(:disabled) {
|
|
@@ -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>
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
<style>
|
|
129
129
|
[data-reveal] {
|
|
130
130
|
--dry-reveal-distance: var(--dry-motion-distance-sm, 0.75rem);
|
|
131
|
-
--dry-reveal-delay: 0ms;
|
|
131
|
+
--dry-reveal-delay: var(--dry-stagger-delay, 0ms);
|
|
132
132
|
--dry-reveal-duration: var(--dry-duration-entrance, 480ms);
|
|
133
133
|
--dry-reveal-ease: cubic-bezier(0.16, 1, 0.3, 1);
|
|
134
134
|
--dry-reveal-hidden-opacity: var(--dry-motion-opacity-enter, 0);
|
|
@@ -81,6 +81,15 @@
|
|
|
81
81
|
outline: none;
|
|
82
82
|
color: var(--dry-color-text-strong);
|
|
83
83
|
min-height: var(--dry-space-10);
|
|
84
|
+
|
|
85
|
+
transition:
|
|
86
|
+
opacity var(--dry-duration-fast) var(--dry-ease-out),
|
|
87
|
+
transform var(--dry-duration-fast) var(--dry-ease-out);
|
|
88
|
+
|
|
89
|
+
@starting-style {
|
|
90
|
+
opacity: 0;
|
|
91
|
+
transform: translateY(4px);
|
|
92
|
+
}
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
[data-select-item]:hover:not([data-disabled]),
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
{@render children()}
|
|
34
34
|
<svg
|
|
35
35
|
data-indicator
|
|
36
|
+
data-state={ctx.open ? 'open' : 'closed'}
|
|
36
37
|
xmlns="http://www.w3.org/2000/svg"
|
|
37
38
|
viewBox="0 0 24 24"
|
|
38
39
|
fill="none"
|
|
@@ -55,6 +56,22 @@
|
|
|
55
56
|
aspect-ratio: 1;
|
|
56
57
|
place-self: center;
|
|
57
58
|
opacity: 0.5;
|
|
58
|
-
|
|
59
|
+
transform-origin: center;
|
|
60
|
+
transition:
|
|
61
|
+
opacity var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
62
|
+
transform var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
63
|
+
filter var(--dry-duration-fast) var(--dry-ease-spring-snappy);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
svg[data-indicator][data-state='open'] {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
transform: scale(1.05);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-reduced-motion: reduce) {
|
|
72
|
+
svg[data-indicator] {
|
|
73
|
+
transition: none;
|
|
74
|
+
filter: none;
|
|
75
|
+
}
|
|
59
76
|
}
|
|
60
77
|
</style>
|
|
@@ -91,10 +91,12 @@
|
|
|
91
91
|
--dry-skeleton-radius: var(--dry-radius-full);
|
|
92
92
|
aspect-ratio: 1;
|
|
93
93
|
height: var(--_h, var(--dry-space-10));
|
|
94
|
+
box-shadow: inset 0 0 0 1px var(--dry-image-edge);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
div[data-variant='rectangular'] {
|
|
97
98
|
--dry-skeleton-radius: var(--dry-radius-sm);
|
|
98
99
|
height: var(--_h, var(--dry-space-16));
|
|
100
|
+
box-shadow: inset 0 0 0 1px var(--dry-image-edge);
|
|
99
101
|
}
|
|
100
102
|
</style>
|
|
@@ -249,6 +249,7 @@
|
|
|
249
249
|
padding-inline: var(--dry-space-4);
|
|
250
250
|
font-size: var(--dry-text-sm-size, 0.875rem);
|
|
251
251
|
font-weight: 600;
|
|
252
|
+
font-variant-numeric: tabular-nums;
|
|
252
253
|
color: var(--dry-color-text);
|
|
253
254
|
clip-path: inset(
|
|
254
255
|
0 calc(100% - var(--dry-slider-progress, 50%)) 0 0 round var(--dry-radius-full)
|
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();
|
|
@@ -58,6 +60,7 @@
|
|
|
58
60
|
color: var(--dry-typography-text-color, var(--dry-color-text-strong));
|
|
59
61
|
font-family: var(--dry-font-sans);
|
|
60
62
|
line-height: 1.7;
|
|
63
|
+
text-wrap: pretty;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
[data-color='muted'] {
|
|
@@ -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';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type ThemeMode = 'system' | 'light' | 'dark';
|
|
2
|
+
export interface ThemeControllerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Storage key used to persist the explicit theme preference.
|
|
5
|
+
* When the user selects system mode the key is removed.
|
|
6
|
+
* Defaults to `'dryui-theme'`.
|
|
7
|
+
*/
|
|
8
|
+
storageKey?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ThemeController {
|
|
11
|
+
/** Current stored preference: `'system'`, `'light'`, or `'dark'`. */
|
|
12
|
+
readonly mode: ThemeMode;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the active rendered theme is dark. Tracks `prefers-color-scheme`
|
|
15
|
+
* when the mode is `'system'`.
|
|
16
|
+
*/
|
|
17
|
+
readonly isDark: boolean;
|
|
18
|
+
/** Whether the system color-scheme preference is currently dark. */
|
|
19
|
+
readonly systemPrefersDark: boolean;
|
|
20
|
+
/** Apply an explicit mode and persist it (or clear persistence for `'system'`). */
|
|
21
|
+
setMode(mode: ThemeMode): void;
|
|
22
|
+
/** Toggle between the two rendered themes, writing an explicit preference. */
|
|
23
|
+
cycle(): void;
|
|
24
|
+
/** Return to system mode and clear any persisted preference. */
|
|
25
|
+
reset(): void;
|
|
26
|
+
/** Stop watching `matchMedia` changes. Called automatically on HMR disposal. */
|
|
27
|
+
destroy(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare const DARK_MEDIA_QUERY = "(prefers-color-scheme: dark)";
|
|
30
|
+
export declare const DEFAULT_STORAGE_KEY = "dryui-theme";
|
|
31
|
+
/**
|
|
32
|
+
* Read the stored theme mode. Exported for testing; production callers
|
|
33
|
+
* should go through `createThemeController`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readStoredMode(storageKey: string): ThemeMode;
|
|
36
|
+
/**
|
|
37
|
+
* Persist the theme mode. When `mode === 'system'`, removes the key.
|
|
38
|
+
* Exported for testing.
|
|
39
|
+
*/
|
|
40
|
+
export declare function writeStoredMode(storageKey: string, mode: ThemeMode): void;
|
|
41
|
+
/**
|
|
42
|
+
* Apply the mode to `<html>` via `classList.theme-auto` and `dataset.theme`.
|
|
43
|
+
* Exported for testing.
|
|
44
|
+
*/
|
|
45
|
+
export declare function applyModeToDom(mode: ThemeMode): void;
|
|
46
|
+
/**
|
|
47
|
+
* Create a theme controller that reads the current preference from storage,
|
|
48
|
+
* applies it to `<html>`, and watches the system color-scheme for changes.
|
|
49
|
+
*
|
|
50
|
+
* The returned object exposes reactive `mode`, `isDark`, and `systemPrefersDark`
|
|
51
|
+
* properties backed by Svelte 5 `$state`, plus imperative methods for changing
|
|
52
|
+
* or resetting the mode.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createThemeController(options?: ThemeControllerOptions): ThemeController;
|