@dryui/ui 1.1.0 → 1.1.2
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-button-trigger.svelte +2 -0
- package/dist/calendar/calendar-button-grid.svelte +40 -140
- package/dist/date-picker/datepicker-button-calendar.svelte +46 -202
- package/dist/date-range-picker/date-range-picker-button-calendar.svelte +64 -239
- package/dist/image/image.svelte +4 -1
- package/dist/internal/calendar-grid-button.svelte +260 -0
- package/dist/internal/calendar-grid-button.svelte.d.ts +27 -0
- package/dist/internal/calendar-grid-utils.js +1 -1
- package/dist/number-input/number-input-button.svelte +2 -3
- package/dist/range-calendar/range-calendar-grid-button.svelte +41 -243
- package/dist/video-embed/video-embed-button.svelte +6 -0
- package/package.json +2 -2
|
@@ -1,151 +1,51 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import
|
|
3
|
+
import { isSameDay } from '@dryui/primitives';
|
|
4
4
|
import { getCalendarCtx } from './context.svelte.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isToday,
|
|
9
|
-
isDateInRange,
|
|
10
|
-
formatDate
|
|
11
|
-
} from '@dryui/primitives';
|
|
12
|
-
import {
|
|
13
|
-
generateWeekdayLabels,
|
|
14
|
-
splitIntoWeeks,
|
|
15
|
-
getDayISOString,
|
|
16
|
-
handleCalendarKeydown,
|
|
17
|
-
focusCalendarDay
|
|
18
|
-
} from '../internal/calendar-grid-utils.js';
|
|
5
|
+
import CalendarGridButton, {
|
|
6
|
+
type CalendarGridAdapter
|
|
7
|
+
} from '../internal/calendar-grid-button.svelte';
|
|
19
8
|
|
|
20
9
|
interface Props extends HTMLAttributes<HTMLDivElement> {}
|
|
21
10
|
|
|
22
|
-
let
|
|
11
|
+
let props: Props = $props();
|
|
23
12
|
|
|
24
13
|
const ctx = getCalendarCtx();
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
requestAnimationFrame(() => focusCalendarDay(containerEl, result.newDate));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isDayDisabled(day: Date): boolean {
|
|
65
|
-
return !isDateInRange(day, ctx.min, ctx.max);
|
|
66
|
-
}
|
|
15
|
+
const adapter: CalendarGridAdapter = {
|
|
16
|
+
get viewYear() {
|
|
17
|
+
return ctx.viewYear;
|
|
18
|
+
},
|
|
19
|
+
get viewMonth() {
|
|
20
|
+
return ctx.viewMonth;
|
|
21
|
+
},
|
|
22
|
+
get locale() {
|
|
23
|
+
return ctx.locale;
|
|
24
|
+
},
|
|
25
|
+
get weekStartDay() {
|
|
26
|
+
return ctx.weekStartDay;
|
|
27
|
+
},
|
|
28
|
+
get focusedDate() {
|
|
29
|
+
return ctx.focusedDate;
|
|
30
|
+
},
|
|
31
|
+
get min() {
|
|
32
|
+
return ctx.min;
|
|
33
|
+
},
|
|
34
|
+
get max() {
|
|
35
|
+
return ctx.max;
|
|
36
|
+
},
|
|
37
|
+
get disabled() {
|
|
38
|
+
return ctx.disabled;
|
|
39
|
+
},
|
|
40
|
+
isSelected: (day) => (ctx.value ? isSameDay(day, ctx.value) : false),
|
|
41
|
+
isInRange: () => false,
|
|
42
|
+
isRangeStart: () => false,
|
|
43
|
+
isRangeEnd: () => false,
|
|
44
|
+
selectDate: (day) => ctx.select(day),
|
|
45
|
+
setFocusedDate: (day) => ctx.setFocusedDate(day),
|
|
46
|
+
prevMonth: () => ctx.prevMonth(),
|
|
47
|
+
nextMonth: () => ctx.nextMonth()
|
|
48
|
+
};
|
|
67
49
|
</script>
|
|
68
50
|
|
|
69
|
-
<
|
|
70
|
-
<div role="grid" aria-label={monthYearLabel}>
|
|
71
|
-
<div data-calendar-row role="row">
|
|
72
|
-
{#each weekdayLabels as label (label)}
|
|
73
|
-
<div data-calendar-columnheader role="columnheader" aria-label={label}>
|
|
74
|
-
<span aria-hidden="true">{label}</span>
|
|
75
|
-
</div>
|
|
76
|
-
{/each}
|
|
77
|
-
</div>
|
|
78
|
-
|
|
79
|
-
{#each weeks as week, wi (wi)}
|
|
80
|
-
<div data-calendar-row role="row">
|
|
81
|
-
{#each week as day (day.getTime())}
|
|
82
|
-
{@const isCurrent = day.getMonth() === ctx.viewMonth}
|
|
83
|
-
{@const selected = ctx.value ? isSameDay(day, ctx.value) : false}
|
|
84
|
-
{@const today = isToday(day)}
|
|
85
|
-
{@const disabled = isDayDisabled(day)}
|
|
86
|
-
{@const focused = isSameDay(day, ctx.focusedDate)}
|
|
87
|
-
{@const isoStr = getDayISOString(day)}
|
|
88
|
-
<div data-calendar-cell>
|
|
89
|
-
<Button
|
|
90
|
-
variant="trigger"
|
|
91
|
-
size="icon-sm"
|
|
92
|
-
type="button"
|
|
93
|
-
role="gridcell"
|
|
94
|
-
tabindex={focused ? 0 : -1}
|
|
95
|
-
aria-label={formatDate(day, ctx.locale, {
|
|
96
|
-
year: 'numeric',
|
|
97
|
-
month: 'long',
|
|
98
|
-
day: 'numeric'
|
|
99
|
-
})}
|
|
100
|
-
aria-selected={selected}
|
|
101
|
-
aria-disabled={disabled}
|
|
102
|
-
data-calendar-day={isoStr}
|
|
103
|
-
data-today={today ? '' : undefined}
|
|
104
|
-
data-selected={selected ? '' : undefined}
|
|
105
|
-
data-outside-month={!isCurrent ? '' : undefined}
|
|
106
|
-
{disabled}
|
|
107
|
-
onclick={() => handleDayClick(day)}
|
|
108
|
-
onkeydown={(e) => handleDayKeydown(e, day)}
|
|
109
|
-
>
|
|
110
|
-
{day.getDate()}
|
|
111
|
-
</Button>
|
|
112
|
-
</div>
|
|
113
|
-
{/each}
|
|
114
|
-
</div>
|
|
115
|
-
{/each}
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
<style>
|
|
120
|
-
[data-calendar-grid] {
|
|
121
|
-
--dry-calendar-grid-gap: 1px;
|
|
122
|
-
display: grid;
|
|
123
|
-
gap: var(--dry-space-2);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
[role='grid'] {
|
|
127
|
-
display: grid;
|
|
128
|
-
gap: var(--dry-calendar-grid-gap);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
[data-calendar-row] {
|
|
132
|
-
display: grid;
|
|
133
|
-
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
134
|
-
gap: var(--dry-calendar-grid-gap);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
[data-calendar-columnheader] {
|
|
138
|
-
display: grid;
|
|
139
|
-
place-items: center;
|
|
140
|
-
min-height: var(--dry-space-8);
|
|
141
|
-
font-size: var(--dry-type-tiny-size);
|
|
142
|
-
color: var(--dry-calendar-muted-color, var(--dry-color-text-weak));
|
|
143
|
-
text-transform: uppercase;
|
|
144
|
-
letter-spacing: 0.04em;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
[data-calendar-cell] {
|
|
148
|
-
display: grid;
|
|
149
|
-
place-items: center;
|
|
150
|
-
}
|
|
151
|
-
</style>
|
|
51
|
+
<CalendarGridButton {adapter} {...props} />
|
|
@@ -1,214 +1,58 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import
|
|
3
|
+
import { isSameDay } from '@dryui/primitives';
|
|
4
4
|
import { getDatePickerCtx } from './context.svelte.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isToday,
|
|
9
|
-
isDateInRange,
|
|
10
|
-
formatDate
|
|
11
|
-
} from '@dryui/primitives';
|
|
12
|
-
import {
|
|
13
|
-
generateWeekdayLabels,
|
|
14
|
-
splitIntoWeeks,
|
|
15
|
-
getDayISOString,
|
|
16
|
-
handleCalendarKeydown,
|
|
17
|
-
focusCalendarDay
|
|
18
|
-
} from '../internal/calendar-grid-utils.js';
|
|
5
|
+
import CalendarGridButton, {
|
|
6
|
+
type CalendarGridAdapter
|
|
7
|
+
} from '../internal/calendar-grid-button.svelte';
|
|
19
8
|
|
|
20
9
|
interface Props extends HTMLAttributes<HTMLDivElement> {}
|
|
21
10
|
|
|
22
|
-
let
|
|
11
|
+
let props: Props = $props();
|
|
23
12
|
|
|
24
13
|
const ctx = getDatePickerCtx();
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
onEscape: () => {
|
|
66
|
-
ctx.close();
|
|
67
|
-
ctx.triggerEl?.focus();
|
|
68
|
-
},
|
|
69
|
-
setFocusedDate: (d) => ctx.setFocusedDate(d),
|
|
70
|
-
weekStartDay: ctx.weekStartDay,
|
|
71
|
-
min: ctx.min,
|
|
72
|
-
max: ctx.max
|
|
73
|
-
});
|
|
74
|
-
if (result?.type === 'navigate') {
|
|
75
|
-
requestAnimationFrame(() => focusCalendarDay(containerEl, result.newDate));
|
|
15
|
+
const adapter: CalendarGridAdapter = {
|
|
16
|
+
get viewYear() {
|
|
17
|
+
return ctx.viewYear;
|
|
18
|
+
},
|
|
19
|
+
get viewMonth() {
|
|
20
|
+
return ctx.viewMonth;
|
|
21
|
+
},
|
|
22
|
+
get locale() {
|
|
23
|
+
return ctx.locale;
|
|
24
|
+
},
|
|
25
|
+
get weekStartDay() {
|
|
26
|
+
return ctx.weekStartDay;
|
|
27
|
+
},
|
|
28
|
+
get focusedDate() {
|
|
29
|
+
return ctx.focusedDate;
|
|
30
|
+
},
|
|
31
|
+
get min() {
|
|
32
|
+
return ctx.min;
|
|
33
|
+
},
|
|
34
|
+
get max() {
|
|
35
|
+
return ctx.max;
|
|
36
|
+
},
|
|
37
|
+
get disabled() {
|
|
38
|
+
return ctx.disabled;
|
|
39
|
+
},
|
|
40
|
+
isSelected: (day) => (ctx.value ? isSameDay(day, ctx.value) : false),
|
|
41
|
+
isInRange: () => false,
|
|
42
|
+
isRangeStart: () => false,
|
|
43
|
+
isRangeEnd: () => false,
|
|
44
|
+
selectDate: (day) => {
|
|
45
|
+
ctx.select(day);
|
|
46
|
+
ctx.triggerEl?.focus();
|
|
47
|
+
},
|
|
48
|
+
setFocusedDate: (day) => ctx.setFocusedDate(day),
|
|
49
|
+
prevMonth: () => ctx.prevMonth(),
|
|
50
|
+
nextMonth: () => ctx.nextMonth(),
|
|
51
|
+
onEscape: () => {
|
|
52
|
+
ctx.close();
|
|
53
|
+
ctx.triggerEl?.focus();
|
|
76
54
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function isDayDisabled(day: Date): boolean {
|
|
80
|
-
return !isDateInRange(day, ctx.min, ctx.max);
|
|
81
|
-
}
|
|
55
|
+
};
|
|
82
56
|
</script>
|
|
83
57
|
|
|
84
|
-
<
|
|
85
|
-
<div role="group" aria-label={monthYearLabel} data-calendar-panel>
|
|
86
|
-
<div class="dp-header" data-calendar-header>
|
|
87
|
-
<Button
|
|
88
|
-
variant="trigger"
|
|
89
|
-
size="icon-sm"
|
|
90
|
-
type="button"
|
|
91
|
-
aria-label="Previous month"
|
|
92
|
-
disabled={ctx.disabled}
|
|
93
|
-
onclick={() => ctx.prevMonth()}
|
|
94
|
-
>
|
|
95
|
-
‹
|
|
96
|
-
</Button>
|
|
97
|
-
<span aria-live="polite" aria-atomic="true" data-calendar-heading>
|
|
98
|
-
{monthYearLabel}
|
|
99
|
-
</span>
|
|
100
|
-
<Button
|
|
101
|
-
variant="trigger"
|
|
102
|
-
size="icon-sm"
|
|
103
|
-
type="button"
|
|
104
|
-
aria-label="Next month"
|
|
105
|
-
disabled={ctx.disabled}
|
|
106
|
-
onclick={() => ctx.nextMonth()}
|
|
107
|
-
>
|
|
108
|
-
›
|
|
109
|
-
</Button>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div role="grid" aria-label={monthYearLabel}>
|
|
113
|
-
<div role="row" data-calendar-row>
|
|
114
|
-
{#each weekdayLabels as label (label)}
|
|
115
|
-
<div role="columnheader" aria-label={label} data-calendar-columnheader>
|
|
116
|
-
<span aria-hidden="true">{label}</span>
|
|
117
|
-
</div>
|
|
118
|
-
{/each}
|
|
119
|
-
</div>
|
|
120
|
-
|
|
121
|
-
{#each weeks as week, weekIndex (weekIndex)}
|
|
122
|
-
<div role="row" data-calendar-row>
|
|
123
|
-
{#each week as day (getDayISOString(day))}
|
|
124
|
-
{@const isCurrent = day.getMonth() === ctx.viewMonth}
|
|
125
|
-
{@const selected = ctx.value ? isSameDay(day, ctx.value) : false}
|
|
126
|
-
{@const today = isToday(day)}
|
|
127
|
-
{@const disabled = isDayDisabled(day)}
|
|
128
|
-
{@const focused = isSameDay(day, ctx.focusedDate)}
|
|
129
|
-
{@const isoStr = getDayISOString(day)}
|
|
130
|
-
<div role="gridcell" data-calendar-cell>
|
|
131
|
-
<Button
|
|
132
|
-
variant="trigger"
|
|
133
|
-
size="icon-sm"
|
|
134
|
-
type="button"
|
|
135
|
-
tabindex={focused ? 0 : -1}
|
|
136
|
-
aria-label={formatDate(day, ctx.locale, {
|
|
137
|
-
year: 'numeric',
|
|
138
|
-
month: 'long',
|
|
139
|
-
day: 'numeric'
|
|
140
|
-
})}
|
|
141
|
-
aria-pressed={selected}
|
|
142
|
-
aria-disabled={disabled}
|
|
143
|
-
data-calendar-day={isoStr}
|
|
144
|
-
data-today={today ? '' : undefined}
|
|
145
|
-
data-selected={selected ? '' : undefined}
|
|
146
|
-
data-outside-month={!isCurrent ? '' : undefined}
|
|
147
|
-
{disabled}
|
|
148
|
-
onclick={() => handleDayClick(day)}
|
|
149
|
-
onkeydown={(e) => handleDayKeydown(e, day)}
|
|
150
|
-
>
|
|
151
|
-
{day.getDate()}
|
|
152
|
-
</Button>
|
|
153
|
-
</div>
|
|
154
|
-
{/each}
|
|
155
|
-
</div>
|
|
156
|
-
{/each}
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
|
|
161
|
-
<style>
|
|
162
|
-
[data-dp-calendar] {
|
|
163
|
-
display: grid;
|
|
164
|
-
gap: var(--dry-space-2);
|
|
165
|
-
user-select: none;
|
|
166
|
-
color: var(--dry-calendar-header-color, var(--dry-color-text-strong));
|
|
167
|
-
font-family: var(--dry-font-sans);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
[data-dp-calendar] [data-calendar-panel] {
|
|
171
|
-
display: grid;
|
|
172
|
-
gap: var(--dry-space-2);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
[data-dp-calendar] [data-calendar-header] {
|
|
176
|
-
display: grid;
|
|
177
|
-
grid-template-columns: auto 1fr auto;
|
|
178
|
-
align-items: center;
|
|
179
|
-
gap: var(--dry-space-2);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
[data-dp-calendar] [data-calendar-heading] {
|
|
183
|
-
font-size: var(--dry-type-small-size);
|
|
184
|
-
font-weight: 600;
|
|
185
|
-
letter-spacing: -0.01em;
|
|
186
|
-
text-align: center;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
[data-dp-calendar] [role='grid'] {
|
|
190
|
-
display: grid;
|
|
191
|
-
gap: 1px;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
[data-dp-calendar] [data-calendar-row] {
|
|
195
|
-
display: grid;
|
|
196
|
-
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
197
|
-
gap: 1px;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
[data-dp-calendar] [data-calendar-columnheader] {
|
|
201
|
-
display: grid;
|
|
202
|
-
place-items: center;
|
|
203
|
-
min-height: var(--dry-space-8);
|
|
204
|
-
font-size: var(--dry-type-tiny-size);
|
|
205
|
-
color: var(--dry-calendar-muted-color, var(--dry-color-text-weak));
|
|
206
|
-
text-transform: uppercase;
|
|
207
|
-
letter-spacing: 0.04em;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
[data-dp-calendar] [data-calendar-cell] {
|
|
211
|
-
display: grid;
|
|
212
|
-
place-items: center;
|
|
213
|
-
}
|
|
214
|
-
</style>
|
|
58
|
+
<CalendarGridButton {adapter} {...props} />
|