@zeyos/zx 4.4.0 → 5.0.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/CHANGELOG.md +283 -0
- package/README.md +42 -10
- package/dist/types/components/activity-list/activity-list.d.ts +22 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +5 -3
- package/dist/types/components/avatar/avatar.d.ts +46 -7
- package/dist/types/components/badge/badge.d.ts +21 -1
- package/dist/types/components/button/button.d.ts +15 -0
- package/dist/types/components/chart/chart.d.ts +10 -0
- package/dist/types/components/checklist/checklist.d.ts +9 -0
- package/dist/types/components/code-editor/code-editor.d.ts +6 -17
- package/dist/types/components/datebox/date-range-box.d.ts +5 -1
- package/dist/types/components/datebox/datebox.d.ts +7 -2
- package/dist/types/components/dialog/dialog.d.ts +46 -6
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +24 -2
- package/dist/types/components/fieldset/fieldset.d.ts +19 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
- package/dist/types/components/launcher/launcher.d.ts +260 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +1 -1
- package/dist/types/components/menu-button/menu-button.d.ts +33 -5
- package/dist/types/components/message/message.d.ts +119 -17
- package/dist/types/components/modal/modal.d.ts +13 -2
- package/dist/types/components/select/color.d.ts +12 -0
- package/dist/types/components/select/glyphs.d.ts +124 -0
- package/dist/types/components/select/select.d.ts +11 -3
- package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
- package/dist/types/components/tabbox/tabbox.d.ts +9 -0
- package/dist/types/components/table/table.d.ts +46 -1
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +15 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/types/zeyos/connect.d.ts +6 -0
- package/dist/types/zeyos/form.d.ts +50 -9
- package/dist/types/zeyos/index.d.ts +1 -1
- package/dist/types/zeyos/query.d.ts +79 -0
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +100 -14
- package/dist/types/zeyos/view.d.ts +10 -0
- package/dist/zx-zeyos.esm.js +1621 -443
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +1411 -660
- package/dist/zx.esm.js +1976 -703
- package/dist/zx.esm.min.js +56 -8
- package/dist/zx.global.js +1978 -705
- package/dist/zx.global.min.js +56 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +219 -34
- package/docs/llms.md +472 -110
- package/docs/llms.txt +3 -3
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/activity-item/activity-item.css +1 -1
- package/src/components/activity-item/activity-item.js +3 -0
- package/src/components/activity-list/activity-list.css +38 -3
- package/src/components/activity-list/activity-list.js +34 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +40 -79
- package/src/components/app-sidebar/app-sidebar.css +109 -174
- package/src/components/app-sidebar/app-sidebar.js +21 -6
- package/src/components/aurora/aurora.css +5 -3
- package/src/components/avatar/avatar.css +32 -7
- package/src/components/avatar/avatar.js +72 -8
- package/src/components/badge/badge.css +54 -2
- package/src/components/badge/badge.js +29 -2
- package/src/components/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +9 -7
- package/src/components/chart/chart.css +4 -1
- package/src/components/chart/chart.js +12 -0
- package/src/components/check-button/check-button.css +10 -2
- package/src/components/checklist/checklist.css +9 -2
- package/src/components/checklist/checklist.js +11 -5
- package/src/components/checklist/field-adapter.js +3 -1
- package/src/components/code-editor/code-editor.css +6 -5
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +8 -3
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- package/src/components/datebox/date-range-box.css +79 -2
- package/src/components/datebox/date-range-box.js +13 -2
- package/src/components/datebox/datebox.css +79 -2
- package/src/components/datebox/datebox.js +13 -2
- package/src/components/dialog/dialog.css +26 -0
- package/src/components/dialog/dialog.js +99 -17
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +5 -3
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +1 -1
- package/src/components/entity-ref/entity-ref.js +1 -1
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +68 -26
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +28 -5
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/filter/filter.js +7 -3
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/finder/finder.css +15 -13
- package/src/components/form/form.css +5 -4
- package/src/components/form/form.js +11 -2
- package/src/components/grid/grid.css +1 -1
- package/src/components/groupbox/groupbox.css +1 -1
- package/src/components/kanban-view/kanban-card.js +11 -3
- package/src/components/kanban-view/kanban-view.css +39 -15
- package/src/components/kanban-view/kanban-view.js +4 -4
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +503 -41
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +1 -1
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +9 -4
- package/src/components/menu-button/menu-button.js +65 -9
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +217 -15
- package/src/components/modal/modal.js +18 -3
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +1 -0
- package/src/components/number-field/number-field.css +70 -0
- package/src/components/number-field/number-field.js +2 -0
- package/src/components/pagination/pagination.css +8 -6
- package/src/components/panel/panel.css +1 -1
- package/src/components/rating/rating.css +7 -0
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +2 -0
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +83 -47
- package/src/components/sheet/sheet.css +11 -8
- package/src/components/slider/slider.css +16 -2
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/stat-tile/stat-tile.css +41 -46
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +104 -29
- package/src/components/table/table.js +90 -16
- package/src/components/tag-picker/tag-picker.css +83 -5
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/toggle/toggle.css +12 -1
- package/src/components/toolbar/toolbar.js +2 -2
- package/src/components/tooltip/tooltip.css +4 -0
- package/src/components/tooltip/tooltip.js +10 -3
- package/src/components/tree/tree.css +25 -16
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.js +1 -1
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +193 -60
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +5 -3
- package/src/internal/app-rail.js +1 -2
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +67 -27
- package/src/zeyos/index.js +1 -1
- package/src/zeyos/query.js +153 -0
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +68 -5
- package/src/zeyos/view.js +6 -0
- package/styles/base.css +56 -0
- package/styles/icons.css +11 -1
- package/styles/tokens/dark.css +113 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +100 -31
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +0 -1
- package/styles/tokens/density.css +0 -9
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/* Positioned so the hidden status line below is placed inside the button. Without a positioned
|
|
2
|
+
ancestor it would hang off the page instead, adding scrollable overflow that focus() can scroll
|
|
3
|
+
into view. */
|
|
1
4
|
.zx-copy-button {
|
|
5
|
+
position: relative;
|
|
2
6
|
display: inline-flex;
|
|
3
7
|
align-items: center;
|
|
4
8
|
gap: var(--zx-space-2);
|
|
@@ -19,6 +23,8 @@
|
|
|
19
23
|
*/
|
|
20
24
|
.zx-copy-button__status {
|
|
21
25
|
position: absolute;
|
|
26
|
+
inset-block-start: 0;
|
|
27
|
+
inset-inline-start: 0;
|
|
22
28
|
clip-path: inset(50%);
|
|
23
29
|
inline-size: 1px;
|
|
24
30
|
block-size: 1px;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
.zx-copy-input {
|
|
2
|
+
/* Holds the visually hidden label below, which would otherwise hang off the page. */
|
|
3
|
+
position: relative;
|
|
2
4
|
display: flex;
|
|
3
5
|
flex-direction: column;
|
|
4
6
|
gap: var(--zx-space-1);
|
|
5
7
|
inline-size: 100%;
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
/* The same quiet label a Field draws, so a copy field sits in a form without standing out. */
|
|
8
11
|
.zx-copy-input__label {
|
|
9
|
-
color: var(--zx-color-text);
|
|
10
|
-
font-size: var(--zx-
|
|
11
|
-
font-weight:
|
|
12
|
+
color: var(--zx-color-text-muted);
|
|
13
|
+
font-size: var(--zx-text-sm);
|
|
14
|
+
font-weight: var(--zx-weight-medium);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
.zx-copy-input[data-hide-label] .zx-copy-input__label {
|
|
15
18
|
position: absolute;
|
|
19
|
+
inset-block-start: 0;
|
|
20
|
+
inset-inline-start: 0;
|
|
16
21
|
clip-path: inset(50%);
|
|
17
22
|
inline-size: 1px;
|
|
18
23
|
block-size: 1px;
|
|
@@ -28,18 +28,19 @@
|
|
|
28
28
|
.zx-data-filter__label {
|
|
29
29
|
color: var(--zx-color-text-muted);
|
|
30
30
|
font-size: var(--zx-text-sm);
|
|
31
|
-
font-weight:
|
|
31
|
+
font-weight: var(--zx-weight-medium);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.zx-data-filter__badge {
|
|
35
35
|
align-self: center;
|
|
36
36
|
min-inline-size: var(--zx-control-height);
|
|
37
37
|
border-radius: var(--zx-radius-full);
|
|
38
|
-
background: var(--zx-color-bg-
|
|
39
|
-
color: var(--zx-color-
|
|
38
|
+
background: var(--zx-color-bg-current);
|
|
39
|
+
color: var(--zx-color-text);
|
|
40
40
|
padding: var(--zx-space-1) var(--zx-space-2);
|
|
41
41
|
font-size: var(--zx-text-sm);
|
|
42
|
-
font-
|
|
42
|
+
font-variant-numeric: tabular-nums;
|
|
43
|
+
font-weight: var(--zx-weight-medium);
|
|
43
44
|
text-align: center;
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
overflow: hidden;
|
|
40
40
|
border-color: transparent;
|
|
41
41
|
background: transparent;
|
|
42
|
-
font-weight:
|
|
42
|
+
font-weight: var(--zx-weight-semibold);
|
|
43
43
|
text-overflow: ellipsis;
|
|
44
44
|
text-wrap: nowrap;
|
|
45
45
|
}
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
.zx-month-picker__year,
|
|
48
48
|
.zx-date-picker__quick-year {
|
|
49
49
|
text-align: center;
|
|
50
|
-
font-weight:
|
|
50
|
+
font-weight: var(--zx-weight-semibold);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.zx-date-picker__grid {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
padding: 0;
|
|
63
63
|
color: var(--zx-color-text-muted);
|
|
64
64
|
font-size: var(--zx-text-xs);
|
|
65
|
-
font-weight:
|
|
65
|
+
font-weight: var(--zx-weight-medium);
|
|
66
66
|
text-align: center;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
border-color: var(--zx-color-accent);
|
|
95
95
|
background: var(--zx-color-accent);
|
|
96
96
|
color: var(--zx-color-on-accent);
|
|
97
|
-
font-weight:
|
|
97
|
+
font-weight: var(--zx-weight-semibold);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
.zx-date-picker__day[aria-disabled="true"] {
|
|
@@ -166,13 +166,13 @@
|
|
|
166
166
|
.zx-date-picker__quick-month[aria-selected="true"] {
|
|
167
167
|
background: var(--zx-color-overlay-selected);
|
|
168
168
|
color: var(--zx-color-accent);
|
|
169
|
-
font-weight:
|
|
169
|
+
font-weight: var(--zx-weight-semibold);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
.zx-month-picker__month[aria-selected="true"] {
|
|
173
173
|
background: var(--zx-color-bg-selected);
|
|
174
174
|
color: var(--zx-color-accent);
|
|
175
|
-
font-weight:
|
|
175
|
+
font-weight: var(--zx-weight-semibold);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
.zx-month-picker__month[aria-disabled="true"] {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
|
|
84
84
|
.zx-date-range-picker__caption {
|
|
85
85
|
overflow: hidden;
|
|
86
|
-
font-weight:
|
|
86
|
+
font-weight: var(--zx-weight-semibold);
|
|
87
87
|
text-align: center;
|
|
88
88
|
text-overflow: ellipsis;
|
|
89
89
|
text-wrap: nowrap;
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
padding: 0;
|
|
148
148
|
color: var(--zx-color-text-muted);
|
|
149
149
|
font-size: var(--zx-text-xs);
|
|
150
|
-
font-weight:
|
|
150
|
+
font-weight: var(--zx-weight-medium);
|
|
151
151
|
text-align: center;
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
border-radius: var(--zx-radius-full);
|
|
224
224
|
background: var(--zx-color-accent);
|
|
225
225
|
color: var(--zx-color-on-accent);
|
|
226
|
-
font-weight:
|
|
226
|
+
font-weight: var(--zx-weight-semibold);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
.zx-date-range-picker__grid td[data-range="middle"] > .zx-date-range-picker__day,
|
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
align-items: stretch;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/* The box draws the frame, so the input and buttons inside it are one border shorter on each side:
|
|
14
|
+
the control as a whole is one control height, like a text input beside it. */
|
|
15
|
+
.zx-date-range-box__control > :is(input, button) {
|
|
16
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
.zx-date-range-box__control {
|
|
14
20
|
position: relative;
|
|
15
21
|
border: 1px solid var(--zx-color-border-control);
|
|
@@ -26,16 +32,40 @@
|
|
|
26
32
|
background: var(--zx-color-danger-bg);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
/*
|
|
30
|
-
showing or hiding the button must not change the control's total width.
|
|
35
|
+
/* A clearable input always reserves room for the clear button, which floats over its trailing
|
|
36
|
+
edge — showing or hiding the button must not change the control's total width. Without
|
|
37
|
+
`clearable` there is no button, and no room is kept for one. */
|
|
31
38
|
.zx-date-range-box__input {
|
|
32
39
|
min-inline-size: 16em;
|
|
33
40
|
border: 0;
|
|
34
41
|
border-radius: var(--zx-control-radius) 0 0 var(--zx-control-radius);
|
|
35
42
|
background: inherit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.zx-date-range-box[data-clearable] .zx-date-range-box__input {
|
|
36
46
|
padding-inline-end: var(--zx-control-height);
|
|
37
47
|
}
|
|
38
48
|
|
|
49
|
+
/* In a Field the control fills its column, as a text input does, and gives way in a narrow one
|
|
50
|
+
instead of holding a minimum width that overflows a two-column row. */
|
|
51
|
+
.zx-field__control > .zx-date-range-box {
|
|
52
|
+
display: block;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.zx-field__control > .zx-date-range-box :is(.zx-date-range-box__content, .zx-date-range-box__control) {
|
|
56
|
+
display: flex;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.zx-field__control > .zx-date-range-box .zx-date-range-box__control {
|
|
60
|
+
flex: 1 1 auto;
|
|
61
|
+
min-inline-size: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.zx-field__control > .zx-date-range-box .zx-date-range-box__input {
|
|
65
|
+
flex: 1 1 auto;
|
|
66
|
+
min-inline-size: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
39
69
|
/* Focused controls lift above their siblings so the ring is never clipped. */
|
|
40
70
|
.zx-date-range-box__input:focus-visible,
|
|
41
71
|
.zx-date-range-box__toggle:focus-visible {
|
|
@@ -141,3 +171,50 @@
|
|
|
141
171
|
box-shadow: var(--zx-overlay-shadow);
|
|
142
172
|
}
|
|
143
173
|
}
|
|
174
|
+
|
|
175
|
+
/*
|
|
176
|
+
* Quiet fields. Inside `[data-zx-fields="quiet"]` the date reads as text: no border, no fill, and
|
|
177
|
+
* the calendar button and its divider hidden. Hover brings the hover fill and the button back;
|
|
178
|
+
* focus brings back the border, the control fill and the focus ring. An invalid value keeps its
|
|
179
|
+
* danger border, quiet or not. A disabled control never lights up.
|
|
180
|
+
*/
|
|
181
|
+
[data-zx-fields="quiet"] .zx-date-range-box:not([data-state="invalid"]) .zx-date-range-box__control {
|
|
182
|
+
border-color: transparent;
|
|
183
|
+
background: transparent;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
[data-zx-fields="quiet"] .zx-date-range-box__toggle {
|
|
187
|
+
border-inline-start-color: transparent;
|
|
188
|
+
opacity: 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
[data-zx-fields="quiet"] .zx-date-range-box__clear {
|
|
192
|
+
opacity: 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
[data-zx-fields="quiet"] .zx-date-range-box:not([aria-disabled="true"], [data-state="invalid"]):hover .zx-date-range-box__control {
|
|
196
|
+
background: var(--zx-color-bg-hover);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
[data-zx-fields="quiet"] .zx-date-range-box:not([aria-disabled="true"]):is(:hover, :focus-within) :is(.zx-date-range-box__toggle, .zx-date-range-box__clear) {
|
|
200
|
+
opacity: 1;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
[data-zx-fields="quiet"] .zx-date-range-box:not([aria-disabled="true"]):focus-within .zx-date-range-box__toggle {
|
|
204
|
+
border-inline-start-color: var(--zx-color-border-control);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
[data-zx-fields="quiet"] .zx-date-range-box:not([aria-disabled="true"], [data-state="invalid"]):focus-within .zx-date-range-box__control {
|
|
208
|
+
border-color: var(--zx-color-border-control);
|
|
209
|
+
background: var(--zx-color-bg-control);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
213
|
+
[data-zx-fields="quiet"] .zx-date-range-box__control {
|
|
214
|
+
transition: background-color var(--zx-dur-fast) var(--zx-ease), border-color var(--zx-dur-fast) var(--zx-ease);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
[data-zx-fields="quiet"] :is(.zx-date-range-box__toggle, .zx-date-range-box__clear) {
|
|
218
|
+
transition: opacity var(--zx-dur-fast) var(--zx-ease), border-color var(--zx-dur-fast) var(--zx-ease);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -19,7 +19,8 @@ import { DateRangePicker, clampRange, normalizeRange } from '../date-picker/date
|
|
|
19
19
|
* @property {string} [format='%d.%m.%Y'] Kernel date format used for both endpoints.
|
|
20
20
|
* @property {string} [separator=' – '] Text placed between the two formatted dates.
|
|
21
21
|
* @property {string|null} [placeholder=null] Input placeholder; null derives one from the format.
|
|
22
|
-
* @property {boolean} [clearable=true] Show a clear button while a range is present
|
|
22
|
+
* @property {boolean} [clearable=true] Show a clear button while a range is present and the box is
|
|
23
|
+
* enabled; without it the input keeps no room for one.
|
|
23
24
|
* @property {Date|null} [min=null] Earliest selectable local calendar day.
|
|
24
25
|
* @property {Date|null} [max=null] Latest selectable local calendar day.
|
|
25
26
|
* @property {number} [months=2] Month panels in the popover; narrow ones show only the first.
|
|
@@ -132,6 +133,8 @@ export class DateRangeBox extends Component {
|
|
|
132
133
|
this.el = root;
|
|
133
134
|
this._originalState = root.getAttribute('data-state');
|
|
134
135
|
this._originalAriaDisabled = root.getAttribute('aria-disabled');
|
|
136
|
+
this._originalClearable = root.getAttribute('data-clearable');
|
|
137
|
+
root.toggleAttribute('data-clearable', Boolean(this.options.clearable));
|
|
135
138
|
this._format = String(this.options.format || '%d.%m.%Y');
|
|
136
139
|
this._separator = String(this.options.separator ?? ' – ');
|
|
137
140
|
this._disabled = Boolean(this.options.disabled);
|
|
@@ -336,6 +339,7 @@ export class DateRangeBox extends Component {
|
|
|
336
339
|
this._content?.remove();
|
|
337
340
|
restoreAttribute(this.el, 'data-state', this._originalState);
|
|
338
341
|
restoreAttribute(this.el, 'aria-disabled', this._originalAriaDisabled);
|
|
342
|
+
restoreAttribute(this.el, 'data-clearable', this._originalClearable);
|
|
339
343
|
super.destroy();
|
|
340
344
|
}
|
|
341
345
|
|
|
@@ -435,7 +439,13 @@ export class DateRangeBox extends Component {
|
|
|
435
439
|
/** @returns {void} */
|
|
436
440
|
_syncDisplay() {
|
|
437
441
|
this.refs.input.value = formatRangeText(this._range, this._format, this._separator);
|
|
438
|
-
this.
|
|
442
|
+
this._syncClear();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** A disabled box offers no clear button: there is nothing it could do. @returns {void} */
|
|
446
|
+
_syncClear() {
|
|
447
|
+
this.refs.clear.hidden = !this.options.clearable || !(this._range.start || this._range.end)
|
|
448
|
+
|| this._disabled;
|
|
439
449
|
}
|
|
440
450
|
|
|
441
451
|
/** @returns {void} */
|
|
@@ -444,6 +454,7 @@ export class DateRangeBox extends Component {
|
|
|
444
454
|
this.refs.toggle.disabled = this._disabled;
|
|
445
455
|
this.refs.clear.disabled = this._disabled;
|
|
446
456
|
this.el.setAttribute('aria-disabled', String(this._disabled));
|
|
457
|
+
this._syncClear();
|
|
447
458
|
if (this._disabled) this._picker?.disable();
|
|
448
459
|
else this._picker?.enable();
|
|
449
460
|
}
|
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
align-items: stretch;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/* The box draws the frame, so the input and buttons inside it are one border shorter on each side:
|
|
14
|
+
the control as a whole is one control height, like a text input beside it. */
|
|
15
|
+
.zx-datebox__control > :is(input, button) {
|
|
16
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
.zx-datebox__control {
|
|
14
20
|
position: relative;
|
|
15
21
|
border: 1px solid var(--zx-color-border-control);
|
|
@@ -26,16 +32,40 @@
|
|
|
26
32
|
background: var(--zx-color-danger-bg);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
/*
|
|
30
|
-
showing or hiding the button must not change the control's total width.
|
|
35
|
+
/* A clearable input always reserves room for the clear button, which floats over its trailing
|
|
36
|
+
edge — showing or hiding the button must not change the control's total width. Without
|
|
37
|
+
`clearable` there is no button, and no room is kept for one. */
|
|
31
38
|
.zx-datebox__input {
|
|
32
39
|
min-inline-size: 10em;
|
|
33
40
|
border: 0;
|
|
34
41
|
border-radius: var(--zx-control-radius) 0 0 var(--zx-control-radius);
|
|
35
42
|
background: inherit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.zx-datebox[data-clearable] .zx-datebox__input {
|
|
36
46
|
padding-inline-end: var(--zx-control-height);
|
|
37
47
|
}
|
|
38
48
|
|
|
49
|
+
/* In a Field the control fills its column, as a text input does, and gives way in a narrow one
|
|
50
|
+
instead of holding a minimum width that overflows a two-column row. */
|
|
51
|
+
.zx-field__control > .zx-datebox {
|
|
52
|
+
display: block;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.zx-field__control > .zx-datebox :is(.zx-datebox__content, .zx-datebox__control) {
|
|
56
|
+
display: flex;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.zx-field__control > .zx-datebox .zx-datebox__control {
|
|
60
|
+
flex: 1 1 auto;
|
|
61
|
+
min-inline-size: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.zx-field__control > .zx-datebox .zx-datebox__input {
|
|
65
|
+
flex: 1 1 auto;
|
|
66
|
+
min-inline-size: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
39
69
|
/* Focused controls lift above their siblings so the ring is never clipped. */
|
|
40
70
|
.zx-datebox__input:focus-visible,
|
|
41
71
|
.zx-datebox__toggle:focus-visible {
|
|
@@ -121,3 +151,50 @@
|
|
|
121
151
|
box-shadow: var(--zx-overlay-shadow);
|
|
122
152
|
}
|
|
123
153
|
}
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
* Quiet fields. Inside `[data-zx-fields="quiet"]` the date reads as text: no border, no fill, and
|
|
157
|
+
* the calendar button and its divider hidden. Hover brings the hover fill and the button back;
|
|
158
|
+
* focus brings back the border, the control fill and the focus ring. An invalid value keeps its
|
|
159
|
+
* danger border, quiet or not. A disabled control never lights up.
|
|
160
|
+
*/
|
|
161
|
+
[data-zx-fields="quiet"] .zx-datebox:not([data-state="invalid"]) .zx-datebox__control {
|
|
162
|
+
border-color: transparent;
|
|
163
|
+
background: transparent;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
[data-zx-fields="quiet"] .zx-datebox__toggle {
|
|
167
|
+
border-inline-start-color: transparent;
|
|
168
|
+
opacity: 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
[data-zx-fields="quiet"] .zx-datebox__clear {
|
|
172
|
+
opacity: 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
[data-zx-fields="quiet"] .zx-datebox:not([aria-disabled="true"], [data-state="invalid"]):hover .zx-datebox__control {
|
|
176
|
+
background: var(--zx-color-bg-hover);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
[data-zx-fields="quiet"] .zx-datebox:not([aria-disabled="true"]):is(:hover, :focus-within) :is(.zx-datebox__toggle, .zx-datebox__clear) {
|
|
180
|
+
opacity: 1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
[data-zx-fields="quiet"] .zx-datebox:not([aria-disabled="true"]):focus-within .zx-datebox__toggle {
|
|
184
|
+
border-inline-start-color: var(--zx-color-border-control);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
[data-zx-fields="quiet"] .zx-datebox:not([aria-disabled="true"], [data-state="invalid"]):focus-within .zx-datebox__control {
|
|
188
|
+
border-color: var(--zx-color-border-control);
|
|
189
|
+
background: var(--zx-color-bg-control);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
193
|
+
[data-zx-fields="quiet"] .zx-datebox__control {
|
|
194
|
+
transition: background-color var(--zx-dur-fast) var(--zx-ease), border-color var(--zx-dur-fast) var(--zx-ease);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
[data-zx-fields="quiet"] :is(.zx-datebox__toggle, .zx-datebox__clear) {
|
|
198
|
+
transition: opacity var(--zx-dur-fast) var(--zx-ease), border-color var(--zx-dur-fast) var(--zx-ease);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -14,7 +14,8 @@ import { DatePicker } from '../date-picker/date-picker.js';
|
|
|
14
14
|
* @property {Date|null} [min=null] Earliest selectable date.
|
|
15
15
|
* @property {Date|null} [max=null] Latest selectable date.
|
|
16
16
|
* @property {string|null} [placeholder=null] Input placeholder; null derives one from the format.
|
|
17
|
-
* @property {boolean} [clearable=true] Show a clear button
|
|
17
|
+
* @property {boolean} [clearable=true] Show a clear button while a value is present and the box is
|
|
18
|
+
* enabled; without it the input keeps no room for one.
|
|
18
19
|
* @property {boolean} [disabled=false] Disable all controls.
|
|
19
20
|
* @property {(event: CustomEvent<{date: Date|null}>) => void} [onchange] Change listener.
|
|
20
21
|
* @property {(event: CustomEvent<{text: string}>) => void} [oninvalid] Invalid-input listener.
|
|
@@ -53,6 +54,8 @@ export class Datebox extends Component {
|
|
|
53
54
|
this.el = root;
|
|
54
55
|
this._originalState = root.getAttribute('data-state');
|
|
55
56
|
this._originalAriaDisabled = root.getAttribute('aria-disabled');
|
|
57
|
+
this._originalClearable = root.getAttribute('data-clearable');
|
|
58
|
+
root.toggleAttribute('data-clearable', Boolean(this.options.clearable));
|
|
56
59
|
this._format = effectiveFormat(this.options.format, this.options.time);
|
|
57
60
|
this._disabled = Boolean(this.options.disabled);
|
|
58
61
|
this._open = false;
|
|
@@ -230,6 +233,8 @@ export class Datebox extends Component {
|
|
|
230
233
|
else this.el.setAttribute('data-state', this._originalState);
|
|
231
234
|
if (this._originalAriaDisabled === null) this.el.removeAttribute('aria-disabled');
|
|
232
235
|
else this.el.setAttribute('aria-disabled', this._originalAriaDisabled);
|
|
236
|
+
if (this._originalClearable === null) this.el.removeAttribute('data-clearable');
|
|
237
|
+
else this.el.setAttribute('data-clearable', this._originalClearable);
|
|
233
238
|
super.destroy();
|
|
234
239
|
}
|
|
235
240
|
|
|
@@ -278,7 +283,12 @@ export class Datebox extends Component {
|
|
|
278
283
|
/** @returns {void} */
|
|
279
284
|
_syncDisplay() {
|
|
280
285
|
this.refs.input.value = this._value ? formatDate(this._value, this._format) : '';
|
|
281
|
-
this.
|
|
286
|
+
this._syncClear();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** A disabled box offers no clear button: there is nothing it could do. @returns {void} */
|
|
290
|
+
_syncClear() {
|
|
291
|
+
this.refs.clear.hidden = !this.options.clearable || !this._value || this._disabled;
|
|
282
292
|
}
|
|
283
293
|
|
|
284
294
|
/** @returns {void} */
|
|
@@ -287,6 +297,7 @@ export class Datebox extends Component {
|
|
|
287
297
|
this.refs.toggle.disabled = this._disabled;
|
|
288
298
|
this.refs.clear.disabled = this._disabled;
|
|
289
299
|
this.el.setAttribute('aria-disabled', String(this._disabled));
|
|
300
|
+
this._syncClear();
|
|
290
301
|
}
|
|
291
302
|
|
|
292
303
|
/** @returns {void} */
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
.zx-dialog__title {
|
|
25
25
|
margin: 0;
|
|
26
26
|
font-size: var(--zx-text-xl);
|
|
27
|
+
font-weight: 650;
|
|
28
|
+
letter-spacing: var(--zx-tracking-title);
|
|
27
29
|
line-height: 1.3;
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -61,6 +63,30 @@
|
|
|
61
63
|
inline-size: 100%;
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
/* Type-to-confirm: the message, then the label naming the text to type, then the input. */
|
|
67
|
+
.zx-dialog__confirm {
|
|
68
|
+
display: grid;
|
|
69
|
+
gap: var(--zx-space-2);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.zx-dialog__confirm > .zx-dialog__prompt-message {
|
|
73
|
+
margin-block-end: var(--zx-space-2);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.zx-dialog__confirm-label {
|
|
77
|
+
color: var(--zx-color-text-muted);
|
|
78
|
+
font-size: var(--zx-text-sm);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.zx-dialog__confirm-label > b {
|
|
82
|
+
color: var(--zx-color-text);
|
|
83
|
+
font-weight: var(--zx-weight-semibold);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.zx-dialog__confirm-input {
|
|
87
|
+
inline-size: 100%;
|
|
88
|
+
}
|
|
89
|
+
|
|
64
90
|
@media (prefers-reduced-motion: no-preference) {
|
|
65
91
|
.zx-dialog__view[aria-hidden="false"] {
|
|
66
92
|
animation: zx-dialog-view-enter var(--zx-dur-fast) var(--zx-ease);
|