@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
|
@@ -46,6 +46,15 @@
|
|
|
46
46
|
display: grid;
|
|
47
47
|
border-bottom: 1px solid var(--dry-color-stroke-weak);
|
|
48
48
|
|
|
49
|
+
transition:
|
|
50
|
+
opacity var(--dry-duration-fast) var(--dry-ease-out),
|
|
51
|
+
transform var(--dry-duration-fast) var(--dry-ease-out);
|
|
52
|
+
|
|
53
|
+
@starting-style {
|
|
54
|
+
opacity: 0;
|
|
55
|
+
transform: translateY(4px);
|
|
56
|
+
}
|
|
57
|
+
|
|
49
58
|
&:last-child {
|
|
50
59
|
border-bottom: none;
|
|
51
60
|
}
|
package/dist/alert/alert.svelte
CHANGED
|
@@ -177,6 +177,7 @@
|
|
|
177
177
|
text-decoration: none;
|
|
178
178
|
white-space: nowrap;
|
|
179
179
|
user-select: none;
|
|
180
|
+
transform-origin: center;
|
|
180
181
|
transition:
|
|
181
182
|
background var(--dry-duration-fast) var(--dry-ease-default),
|
|
182
183
|
border-color var(--dry-duration-fast) var(--dry-ease-default),
|
|
@@ -191,7 +192,7 @@
|
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
&:active:not([data-disabled]) {
|
|
194
|
-
transform:
|
|
195
|
+
transform: scale(0.98);
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
&[data-disabled] {
|
|
@@ -499,7 +500,7 @@
|
|
|
499
500
|
--_dry-btn-padding-x: var(--dry-btn-padding-x, 0);
|
|
500
501
|
--_dry-btn-padding-y: var(--dry-btn-padding-y, 0);
|
|
501
502
|
aspect-ratio: 1;
|
|
502
|
-
height: var(--dry-space-
|
|
503
|
+
height: var(--dry-space-10);
|
|
503
504
|
--_dry-btn-radius: var(--dry-btn-radius, var(--dry-radius-sm));
|
|
504
505
|
--_dry-btn-font-size: var(
|
|
505
506
|
--dry-btn-font-size,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const
|
|
1
|
+
import { createContext } from '@dryui/primitives';
|
|
2
|
+
const [_setButtonGroupCtx, _getButtonGroupCtx] = createContext('button-group');
|
|
3
3
|
export function setButtonGroupCtx(ctx) {
|
|
4
|
-
|
|
5
|
-
return ctx;
|
|
4
|
+
return _setButtonGroupCtx(ctx);
|
|
6
5
|
}
|
|
7
6
|
export function getButtonGroupCtx() {
|
|
8
|
-
|
|
9
|
-
return undefined;
|
|
10
|
-
return getContext(KEY);
|
|
7
|
+
return _getButtonGroupCtx();
|
|
11
8
|
}
|
|
@@ -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 { createDateViewController } from '../internal/date-family-controller.svelte.js';
|
|
4
5
|
import { setCalendarCtx } from './context.svelte.js';
|
|
5
|
-
import { getWeekStartDay, addMonths } from '@dryui/primitives';
|
|
6
6
|
|
|
7
7
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
8
8
|
value?: Date | null;
|
|
@@ -24,24 +24,23 @@
|
|
|
24
24
|
...rest
|
|
25
25
|
}: Props = $props();
|
|
26
26
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
let focusedDate = $state<Date>(value ?? new Date());
|
|
27
|
+
const view = createDateViewController({
|
|
28
|
+
initialDate: value,
|
|
29
|
+
locale: () => locale
|
|
30
|
+
});
|
|
32
31
|
|
|
33
32
|
setCalendarCtx({
|
|
34
33
|
get value() {
|
|
35
34
|
return value;
|
|
36
35
|
},
|
|
37
36
|
get focusedDate() {
|
|
38
|
-
return focusedDate;
|
|
37
|
+
return view.focusedDate;
|
|
39
38
|
},
|
|
40
39
|
get viewMonth() {
|
|
41
|
-
return viewMonth;
|
|
40
|
+
return view.viewMonth;
|
|
42
41
|
},
|
|
43
42
|
get viewYear() {
|
|
44
|
-
return viewYear;
|
|
43
|
+
return view.viewYear;
|
|
45
44
|
},
|
|
46
45
|
get locale() {
|
|
47
46
|
return locale;
|
|
@@ -56,7 +55,7 @@
|
|
|
56
55
|
return disabled;
|
|
57
56
|
},
|
|
58
57
|
get weekStartDay() {
|
|
59
|
-
return weekStartDay;
|
|
58
|
+
return view.weekStartDay;
|
|
60
59
|
},
|
|
61
60
|
get multiple() {
|
|
62
61
|
return false;
|
|
@@ -66,38 +65,22 @@
|
|
|
66
65
|
},
|
|
67
66
|
select(date: Date) {
|
|
68
67
|
value = date;
|
|
69
|
-
|
|
70
|
-
viewMonth = date.getMonth();
|
|
71
|
-
viewYear = date.getFullYear();
|
|
68
|
+
view.setFocusedDate(date);
|
|
72
69
|
},
|
|
73
70
|
goToMonth(month: number) {
|
|
74
|
-
|
|
75
|
-
viewMonth = 11;
|
|
76
|
-
viewYear = viewYear - 1;
|
|
77
|
-
} else if (month > 11) {
|
|
78
|
-
viewMonth = 0;
|
|
79
|
-
viewYear = viewYear + 1;
|
|
80
|
-
} else {
|
|
81
|
-
viewMonth = month;
|
|
82
|
-
}
|
|
71
|
+
view.goToMonth(month);
|
|
83
72
|
},
|
|
84
73
|
goToYear(year: number) {
|
|
85
|
-
|
|
74
|
+
view.goToYear(year);
|
|
86
75
|
},
|
|
87
76
|
nextMonth() {
|
|
88
|
-
|
|
89
|
-
viewMonth = next.getMonth();
|
|
90
|
-
viewYear = next.getFullYear();
|
|
77
|
+
view.nextMonth();
|
|
91
78
|
},
|
|
92
79
|
prevMonth() {
|
|
93
|
-
|
|
94
|
-
viewMonth = prev.getMonth();
|
|
95
|
-
viewYear = prev.getFullYear();
|
|
80
|
+
view.prevMonth();
|
|
96
81
|
},
|
|
97
82
|
setFocusedDate(date: Date) {
|
|
98
|
-
|
|
99
|
-
viewMonth = date.getMonth();
|
|
100
|
-
viewYear = date.getFullYear();
|
|
83
|
+
view.setFocusedDate(date);
|
|
101
84
|
}
|
|
102
85
|
});
|
|
103
86
|
</script>
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
font-size="11"
|
|
46
46
|
fill="currentColor"
|
|
47
47
|
opacity="0.6"
|
|
48
|
+
data-chart-tick-label
|
|
48
49
|
>
|
|
49
50
|
{Math.round(tick.value)}
|
|
50
51
|
</text>
|
|
@@ -63,4 +64,8 @@
|
|
|
63
64
|
[data-chart-axis] {
|
|
64
65
|
color: var(--dry-chart-axis-color);
|
|
65
66
|
}
|
|
67
|
+
|
|
68
|
+
[data-chart-tick-label] {
|
|
69
|
+
font-variant-numeric: tabular-nums;
|
|
70
|
+
}
|
|
66
71
|
</style>
|
|
@@ -133,8 +133,21 @@
|
|
|
133
133
|
|
|
134
134
|
&::after {
|
|
135
135
|
content: '';
|
|
136
|
-
display:
|
|
137
|
-
|
|
136
|
+
display: block;
|
|
137
|
+
height: 60%;
|
|
138
|
+
aspect-ratio: 35 / 60;
|
|
139
|
+
border: solid transparent;
|
|
140
|
+
border-width: 0 2px 2px 0;
|
|
141
|
+
margin-left: calc(var(--dry-checkbox-size) * 0.52);
|
|
142
|
+
margin-top: calc(var(--dry-checkbox-size) * -0.18);
|
|
143
|
+
transform-origin: center;
|
|
144
|
+
opacity: 0;
|
|
145
|
+
transform: rotate(45deg) scale(0.25);
|
|
146
|
+
filter: blur(4px);
|
|
147
|
+
transition:
|
|
148
|
+
opacity var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
149
|
+
transform var(--dry-duration-fast) var(--dry-ease-spring-snappy),
|
|
150
|
+
filter var(--dry-duration-fast) var(--dry-ease-spring-snappy);
|
|
138
151
|
}
|
|
139
152
|
|
|
140
153
|
&[data-state='checked'] {
|
|
@@ -143,16 +156,10 @@
|
|
|
143
156
|
box-shadow: inset 0 0 0 1px var(--dry-color-stroke-selected);
|
|
144
157
|
|
|
145
158
|
&::after {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
aspect-ratio: 35 / 60;
|
|
149
|
-
border: solid var(--dry-checkbox-check-color);
|
|
150
|
-
border-width: 0 2px 2px 0;
|
|
151
|
-
margin-left: calc(var(--dry-checkbox-size) * 0.52);
|
|
152
|
-
margin-top: calc(var(--dry-checkbox-size) * -0.18);
|
|
159
|
+
border-color: var(--dry-checkbox-check-color);
|
|
160
|
+
opacity: 1;
|
|
153
161
|
transform: rotate(45deg) scale(1);
|
|
154
|
-
|
|
155
|
-
animation: checkScale var(--dry-duration-fast) var(--dry-ease-spring);
|
|
162
|
+
filter: blur(0);
|
|
156
163
|
}
|
|
157
164
|
}
|
|
158
165
|
|
|
@@ -163,11 +170,15 @@
|
|
|
163
170
|
box-shadow: inset 0 0 0 1px var(--dry-color-stroke-selected);
|
|
164
171
|
|
|
165
172
|
&::after {
|
|
166
|
-
display: block;
|
|
167
173
|
height: 2px;
|
|
174
|
+
aspect-ratio: auto;
|
|
175
|
+
border: none;
|
|
168
176
|
background: var(--dry-checkbox-check-color);
|
|
177
|
+
margin-left: 0;
|
|
178
|
+
margin-top: 0;
|
|
179
|
+
opacity: 1;
|
|
169
180
|
transform: scale(1);
|
|
170
|
-
|
|
181
|
+
filter: blur(0);
|
|
171
182
|
}
|
|
172
183
|
}
|
|
173
184
|
|
|
@@ -226,28 +237,16 @@
|
|
|
226
237
|
--dry-checkbox-radius: var(--dry-radius-md);
|
|
227
238
|
}
|
|
228
239
|
|
|
229
|
-
@
|
|
230
|
-
|
|
231
|
-
|
|
240
|
+
@media (prefers-reduced-motion: reduce) {
|
|
241
|
+
input::after {
|
|
242
|
+
transition: none;
|
|
243
|
+
filter: none;
|
|
232
244
|
}
|
|
233
|
-
|
|
245
|
+
input[data-state='checked']::after {
|
|
234
246
|
transform: rotate(45deg) scale(1);
|
|
235
247
|
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
@keyframes dashScale {
|
|
239
|
-
from {
|
|
240
|
-
transform: scale(0);
|
|
241
|
-
}
|
|
242
|
-
to {
|
|
243
|
-
transform: scale(1);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
@media (prefers-reduced-motion: reduce) {
|
|
248
|
-
input[data-state='checked']::after,
|
|
249
248
|
input[data-state='indeterminate']::after {
|
|
250
|
-
|
|
249
|
+
transform: scale(1);
|
|
251
250
|
}
|
|
252
251
|
}
|
|
253
252
|
</style>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
interface ChipGroupContext {
|
|
1
|
+
export interface ChipGroupContext {
|
|
2
2
|
readonly type: 'single' | 'multiple';
|
|
3
3
|
readonly disabled: boolean;
|
|
4
4
|
readonly value: string[];
|
|
5
5
|
toggle: (itemValue: string) => void;
|
|
6
6
|
isSelected: (itemValue: string) => boolean;
|
|
7
7
|
}
|
|
8
|
-
export declare
|
|
9
|
-
export declare function getChipGroupCtx(): ChipGroupContext;
|
|
10
|
-
export {};
|
|
8
|
+
export declare const setChipGroupCtx: (ctx: ChipGroupContext) => ChipGroupContext, getChipGroupCtx: () => ChipGroupContext;
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const
|
|
3
|
-
export function setChipGroupCtx(ctx) {
|
|
4
|
-
setContext(CHIP_GROUP_KEY, ctx);
|
|
5
|
-
return ctx;
|
|
6
|
-
}
|
|
7
|
-
export function getChipGroupCtx() {
|
|
8
|
-
return getContext(CHIP_GROUP_KEY);
|
|
9
|
-
}
|
|
1
|
+
import { createContext } from '@dryui/primitives';
|
|
2
|
+
export const [setChipGroupCtx, getChipGroupCtx] = createContext('chip-group');
|
|
@@ -97,6 +97,15 @@
|
|
|
97
97
|
outline: none;
|
|
98
98
|
color: var(--dry-color-text-strong);
|
|
99
99
|
min-height: var(--dry-space-10);
|
|
100
|
+
|
|
101
|
+
transition:
|
|
102
|
+
opacity var(--dry-duration-fast) var(--dry-ease-out),
|
|
103
|
+
transform var(--dry-duration-fast) var(--dry-ease-out);
|
|
104
|
+
|
|
105
|
+
@starting-style {
|
|
106
|
+
opacity: 0;
|
|
107
|
+
transform: translateY(4px);
|
|
108
|
+
}
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
[data-combobox-item][data-has-icon] {
|
|
@@ -71,6 +71,15 @@
|
|
|
71
71
|
cursor: pointer;
|
|
72
72
|
color: var(--dry-color-text-strong);
|
|
73
73
|
min-height: var(--dry-space-11);
|
|
74
|
+
|
|
75
|
+
transition:
|
|
76
|
+
opacity var(--dry-duration-fast) var(--dry-ease-out),
|
|
77
|
+
transform var(--dry-duration-fast) var(--dry-ease-out);
|
|
78
|
+
|
|
79
|
+
@starting-style {
|
|
80
|
+
opacity: 0;
|
|
81
|
+
transform: translateY(4px);
|
|
82
|
+
}
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
[data-command-palette-item]:hover:not([data-disabled]) {
|
|
@@ -12,26 +12,36 @@
|
|
|
12
12
|
|
|
13
13
|
const ctx = getContextMenuCtx();
|
|
14
14
|
|
|
15
|
-
let el = $state<HTMLDivElement>();
|
|
15
|
+
let el = $state<HTMLDivElement | null>(null);
|
|
16
|
+
|
|
17
|
+
function attachContent(node: HTMLDivElement) {
|
|
18
|
+
el = node;
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
if (el === node) {
|
|
22
|
+
el = null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
16
26
|
|
|
17
27
|
const menu = createMenuNavigation({
|
|
18
28
|
container: () => el ?? null,
|
|
19
29
|
orientation: 'vertical'
|
|
20
30
|
});
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
if (ctx.open
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!
|
|
28
|
-
|
|
32
|
+
function syncPopover(node: HTMLDivElement) {
|
|
33
|
+
if (ctx.open) {
|
|
34
|
+
node.style.position = 'fixed';
|
|
35
|
+
node.style.left = `${ctx.position.x}px`;
|
|
36
|
+
node.style.top = `${ctx.position.y}px`;
|
|
37
|
+
if (!node.matches(':popover-open')) {
|
|
38
|
+
node.showPopover();
|
|
29
39
|
menu.focusFirst();
|
|
30
40
|
}
|
|
31
|
-
} else if (
|
|
32
|
-
|
|
41
|
+
} else if (node.matches(':popover-open')) {
|
|
42
|
+
node.hidePopover();
|
|
33
43
|
}
|
|
34
|
-
}
|
|
44
|
+
}
|
|
35
45
|
|
|
36
46
|
createDismiss({
|
|
37
47
|
enabled: () => ctx.open,
|
|
@@ -42,13 +52,15 @@
|
|
|
42
52
|
</script>
|
|
43
53
|
|
|
44
54
|
<div
|
|
45
|
-
|
|
55
|
+
{@attach attachContent}
|
|
56
|
+
{@attach syncPopover}
|
|
46
57
|
popover="manual"
|
|
47
58
|
role="menu"
|
|
48
59
|
tabindex="-1"
|
|
49
60
|
id={ctx.contentId}
|
|
50
61
|
aria-labelledby={ctx.triggerId}
|
|
51
62
|
data-context-menu-content
|
|
63
|
+
data-dry-stagger
|
|
52
64
|
data-state={ctx.open ? 'open' : 'closed'}
|
|
53
65
|
class={className}
|
|
54
66
|
{style}
|
|
@@ -69,6 +81,7 @@
|
|
|
69
81
|
--dry-menu-radius: var(--dry-radius-lg);
|
|
70
82
|
--dry-menu-shadow: var(--dry-shadow-lg);
|
|
71
83
|
--dry-menu-padding: var(--dry-space-1);
|
|
84
|
+
--dry-menu-item-padding: var(--dry-space-2_5) var(--dry-space-2);
|
|
72
85
|
|
|
73
86
|
display: grid;
|
|
74
87
|
grid-template-columns: minmax(12rem, max-content);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import MenuGroup from '../internal/menu-group.svelte';
|
|
4
5
|
|
|
5
6
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
7
|
children: Snippet;
|
|
@@ -9,6 +10,6 @@
|
|
|
9
10
|
let { class: className, children, ...rest }: Props = $props();
|
|
10
11
|
</script>
|
|
11
12
|
|
|
12
|
-
<
|
|
13
|
+
<MenuGroup {className} {...rest}>
|
|
13
14
|
{@render children()}
|
|
14
|
-
</
|
|
15
|
+
</MenuGroup>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import { getContextMenuCtx } from './context.svelte.js';
|
|
5
|
+
import MenuItem from '../internal/menu-item.svelte';
|
|
5
6
|
|
|
6
7
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
7
8
|
disabled?: boolean;
|
|
@@ -11,70 +12,16 @@
|
|
|
11
12
|
let { class: className, disabled, children, onclick, onkeydown, ...rest }: Props = $props();
|
|
12
13
|
|
|
13
14
|
const ctx = getContextMenuCtx();
|
|
14
|
-
|
|
15
|
-
function handleClick(e: MouseEvent & { currentTarget: HTMLDivElement }) {
|
|
16
|
-
if (disabled) return;
|
|
17
|
-
if (onclick) (onclick as (e: MouseEvent & { currentTarget: HTMLDivElement }) => void)(e);
|
|
18
|
-
ctx.close();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function handleKeydown(e: KeyboardEvent & { currentTarget: HTMLDivElement }) {
|
|
22
|
-
if (disabled) return;
|
|
23
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
24
|
-
e.preventDefault();
|
|
25
|
-
(e.currentTarget as HTMLElement).click();
|
|
26
|
-
}
|
|
27
|
-
if (onkeydown) (onkeydown as (e: KeyboardEvent & { currentTarget: HTMLDivElement }) => void)(e);
|
|
28
|
-
}
|
|
29
15
|
</script>
|
|
30
16
|
|
|
31
|
-
<
|
|
32
|
-
role="menuitem"
|
|
33
|
-
tabindex={disabled ? undefined : -1}
|
|
34
|
-
aria-disabled={disabled || undefined}
|
|
17
|
+
<MenuItem
|
|
35
18
|
data-context-menu-item
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
19
|
+
{className}
|
|
20
|
+
close={ctx.close}
|
|
21
|
+
{disabled}
|
|
22
|
+
{onclick}
|
|
23
|
+
{onkeydown}
|
|
40
24
|
{...rest}
|
|
41
25
|
>
|
|
42
26
|
{@render children()}
|
|
43
|
-
</
|
|
44
|
-
|
|
45
|
-
<style>
|
|
46
|
-
[data-context-menu-item] {
|
|
47
|
-
display: grid;
|
|
48
|
-
grid-auto-flow: column;
|
|
49
|
-
grid-auto-columns: max-content;
|
|
50
|
-
align-items: center;
|
|
51
|
-
gap: var(--dry-space-2);
|
|
52
|
-
padding: var(--dry-menu-item-padding, var(--dry-space-2_5) var(--dry-space-2));
|
|
53
|
-
border-radius: var(
|
|
54
|
-
--dry-menu-item-radius,
|
|
55
|
-
min(var(--dry-control-radius, var(--dry-radius-sm)), var(--dry-space-4))
|
|
56
|
-
);
|
|
57
|
-
font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
|
|
58
|
-
cursor: pointer;
|
|
59
|
-
user-select: none;
|
|
60
|
-
outline: none;
|
|
61
|
-
color: var(--dry-color-text-strong);
|
|
62
|
-
min-height: var(--dry-space-11);
|
|
63
|
-
transition: background var(--dry-duration-fast) var(--dry-ease-default);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
[data-context-menu-item]:hover:not([data-disabled]),
|
|
67
|
-
[data-context-menu-item]:focus-visible {
|
|
68
|
-
background: var(--dry-color-fill);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
[data-context-menu-item]:active:not([data-disabled]) {
|
|
72
|
-
background: var(--dry-color-fill-hover);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
[data-context-menu-item][data-disabled] {
|
|
76
|
-
color: var(--dry-color-text-disabled);
|
|
77
|
-
cursor: not-allowed;
|
|
78
|
-
pointer-events: none;
|
|
79
|
-
}
|
|
80
|
-
</style>
|
|
27
|
+
</MenuItem>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import MenuLabel from '../internal/menu-label.svelte';
|
|
4
5
|
|
|
5
6
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
7
|
children: Snippet;
|
|
@@ -9,15 +10,6 @@
|
|
|
9
10
|
let { class: className, children, ...rest }: Props = $props();
|
|
10
11
|
</script>
|
|
11
12
|
|
|
12
|
-
<
|
|
13
|
+
<MenuLabel data-context-menu-label {className} {...rest}>
|
|
13
14
|
{@render children()}
|
|
14
|
-
</
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
[data-context-menu-label] {
|
|
18
|
-
padding: var(--dry-space-1_5) var(--dry-space-2);
|
|
19
|
-
font-size: var(--dry-type-tiny-size, var(--dry-text-xs-size));
|
|
20
|
-
color: var(--dry-color-text-weak);
|
|
21
|
-
font-weight: 500;
|
|
22
|
-
}
|
|
23
|
-
</style>
|
|
15
|
+
</MenuLabel>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import { generateFormId } from '@dryui/primitives';
|
|
4
3
|
import { setContextMenuCtx } from './context.svelte.js';
|
|
4
|
+
import { createPositionedMenuRootState } from '../internal/menu-root-state.svelte.js';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
open?: boolean;
|
|
@@ -10,34 +10,15 @@
|
|
|
10
10
|
|
|
11
11
|
let { open = $bindable(false), children }: Props = $props();
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
triggerId,
|
|
23
|
-
contentId,
|
|
24
|
-
triggerEl: null,
|
|
25
|
-
get position() {
|
|
26
|
-
return position;
|
|
27
|
-
},
|
|
28
|
-
set position(value: { x: number; y: number }) {
|
|
29
|
-
position = value;
|
|
30
|
-
},
|
|
31
|
-
show() {
|
|
32
|
-
open = true;
|
|
33
|
-
},
|
|
34
|
-
close() {
|
|
35
|
-
open = false;
|
|
36
|
-
},
|
|
37
|
-
toggle() {
|
|
38
|
-
open = !open;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
13
|
+
setContextMenuCtx(
|
|
14
|
+
createPositionedMenuRootState({
|
|
15
|
+
idBase: 'context-menu',
|
|
16
|
+
getOpen: () => open,
|
|
17
|
+
setOpen: (value) => {
|
|
18
|
+
open = value;
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
);
|
|
41
22
|
</script>
|
|
42
23
|
|
|
43
24
|
{@render children()}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import MenuSeparator from '../internal/menu-separator.svelte';
|
|
3
4
|
|
|
4
5
|
interface Props extends HTMLAttributes<HTMLDivElement> {}
|
|
5
6
|
|
|
6
7
|
let { class: className, ...rest }: Props = $props();
|
|
7
8
|
</script>
|
|
8
9
|
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
<style>
|
|
12
|
-
[data-context-menu-separator] {
|
|
13
|
-
height: 1px;
|
|
14
|
-
background: var(--dry-color-stroke-weak);
|
|
15
|
-
margin: var(--dry-space-1) 0;
|
|
16
|
-
}
|
|
17
|
-
</style>
|
|
10
|
+
<MenuSeparator data-context-menu-separator {className} {...rest}></MenuSeparator>
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
readonly triggerId: string;
|
|
4
|
-
readonly contentId: string;
|
|
5
|
-
triggerEl: HTMLElement | null;
|
|
6
|
-
position: {
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
};
|
|
10
|
-
show: () => void;
|
|
11
|
-
close: () => void;
|
|
12
|
-
toggle: () => void;
|
|
1
|
+
import type { PositionedMenuRootState } from '../internal/menu-root-state.svelte.js';
|
|
2
|
+
export interface ContextMenuContext extends PositionedMenuRootState {
|
|
13
3
|
}
|
|
14
4
|
export declare const setContextMenuCtx: (ctx: ContextMenuContext) => ContextMenuContext, getContextMenuCtx: () => ContextMenuContext;
|