@redseed/redseed-ui-tailwindcss 7.53.0 → 7.55.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/components/form_field_date_range.css +177 -0
- package/components/stage_dial.css +60 -0
- package/components.css +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
.rsui-form-field-date-range {
|
|
2
|
+
@apply relative;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.rsui-form-field-date-range__group {
|
|
6
|
+
@apply relative flex flex-nowrap overflow-hidden;
|
|
7
|
+
@apply text-base transition;
|
|
8
|
+
@apply w-full border rounded-lg ring-0;
|
|
9
|
+
@apply bg-background-primary placeholder-text-secondary border-border-primary;
|
|
10
|
+
@apply has-[:focus]:border-border-primary;
|
|
11
|
+
@apply has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-border-primary has-[:focus-visible]:ring-offset-2;
|
|
12
|
+
@apply has-[:disabled]:text-text-disabled has-[:disabled]:bg-background-disabled has-[:disabled]:border-border-disabled has-[:disabled]:ring-0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* The trigger is a button, not an input, so `:user-invalid` — which the other
|
|
17
|
+
* fields lean on — never fires here. The error border is driven by the same
|
|
18
|
+
* `aria-invalid` the control already sets for assistive tech, so the visual and
|
|
19
|
+
* the announced state cannot drift apart.
|
|
20
|
+
*/
|
|
21
|
+
.rsui-form-field-date-range__group:has([aria-invalid='true']) {
|
|
22
|
+
@apply border-border-error ring-0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.rsui-form-field-date-range__trigger {
|
|
26
|
+
@apply flex-1 flex items-center text-left cursor-pointer;
|
|
27
|
+
@apply text-base text-text-primary transition py-3 px-3 xs:px-4 pr-12 outline-hidden focus:outline-hidden;
|
|
28
|
+
@apply bg-background-primary;
|
|
29
|
+
@apply disabled:text-text-disabled disabled:bg-background-disabled disabled:cursor-not-allowed;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.rsui-form-field-date-range__value {
|
|
33
|
+
@apply truncate;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.rsui-form-field-date-range__placeholder {
|
|
37
|
+
@apply truncate text-text-secondary select-none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rsui-form-field-date-range__icon {
|
|
41
|
+
@apply absolute top-0 right-3 bottom-0 flex items-center justify-center;
|
|
42
|
+
@apply text-text-primary h-full w-8 pointer-events-none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.rsui-form-field-date-range__icon svg {
|
|
46
|
+
@apply size-5;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.rsui-form-field-date-range__popover {
|
|
50
|
+
@apply hidden absolute top-0 z-50;
|
|
51
|
+
@apply bg-background-primary p-4 mt-2 rounded-lg shadow-full-light;
|
|
52
|
+
@apply flex flex-col sm:flex-row gap-4;
|
|
53
|
+
@apply max-h-[80vh] overflow-y-auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.rsui-form-field-date-range__popover--open {
|
|
57
|
+
@apply flex;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* The preset rail sits inside the popover (MUI's shortcuts placement) rather
|
|
61
|
+
than above the field, so the control stays one control. */
|
|
62
|
+
.rsui-form-field-date-range__presets {
|
|
63
|
+
@apply flex flex-row sm:flex-col flex-wrap gap-1 shrink-0;
|
|
64
|
+
@apply sm:border-r sm:border-border-secondary sm:pr-4;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.rsui-form-field-date-range__preset {
|
|
68
|
+
@apply text-left text-sm whitespace-nowrap px-3 py-2 rounded-lg cursor-pointer transition;
|
|
69
|
+
@apply text-text-primary hover:bg-background-secondary;
|
|
70
|
+
@apply focus-visible:ring-2 focus-visible:ring-border-primary focus-visible:ring-inset outline-hidden;
|
|
71
|
+
@apply disabled:text-text-disabled disabled:hover:bg-transparent disabled:cursor-not-allowed;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.rsui-form-field-date-range__preset--selected {
|
|
75
|
+
@apply bg-background-secondary font-semibold;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.rsui-form-field-date-range__calendars {
|
|
79
|
+
@apply relative flex flex-col gap-2;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.rsui-form-field-date-range__nav {
|
|
83
|
+
@apply absolute inset-x-0 top-0 flex items-center justify-between pointer-events-none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.rsui-form-field-date-range__nav-button {
|
|
87
|
+
@apply flex items-center justify-center size-8 rounded-lg cursor-pointer pointer-events-auto transition;
|
|
88
|
+
@apply text-text-primary hover:bg-background-secondary;
|
|
89
|
+
@apply focus-visible:ring-2 focus-visible:ring-border-primary focus-visible:ring-inset outline-hidden;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.rsui-form-field-date-range__nav-button svg {
|
|
93
|
+
@apply size-5;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.rsui-form-field-date-range__months {
|
|
97
|
+
@apply flex flex-col sm:flex-row gap-6;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.rsui-form-field-date-range__month {
|
|
101
|
+
@apply flex flex-col gap-2;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.rsui-form-field-date-range__caption {
|
|
105
|
+
@apply text-sm font-semibold text-center text-text-primary h-8 flex items-center justify-center;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.rsui-form-field-date-range__table {
|
|
109
|
+
@apply border-collapse;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.rsui-form-field-date-range__weekday {
|
|
113
|
+
@apply size-9 text-xs font-normal text-text-secondary;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.rsui-form-field-date-range__cell {
|
|
117
|
+
@apply p-0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.rsui-form-field-date-range__day {
|
|
121
|
+
@apply size-9 text-sm rounded-lg cursor-pointer transition;
|
|
122
|
+
@apply text-text-primary hover:bg-background-secondary;
|
|
123
|
+
@apply focus-visible:ring-2 focus-visible:ring-border-primary focus-visible:ring-inset outline-hidden;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Which days sit inside the window is this component's most important visual
|
|
128
|
+
* affordance, so the fill is Brand-200 — about 1.56:1 against the popover's
|
|
129
|
+
* white, against 1.14:1 for background-brand-invert (Brand-50) and 1.07:1 for
|
|
130
|
+
* background-brand (Brand-25), both of which read as no fill at all.
|
|
131
|
+
*
|
|
132
|
+
* Brand-200 is deliberately the stopping point. Nothing in the ramp reaches the
|
|
133
|
+
* 3:1 that WCAG 1.4.11 asks of a component state until Brand-400 (~3.47:1),
|
|
134
|
+
* which is dark enough to need light text and would make an in-range day look
|
|
135
|
+
* almost like an endpoint — losing the distinction the fill exists to draw. So
|
|
136
|
+
* this is a legibility improvement rather than a compliance fix, chosen with
|
|
137
|
+
* that trade-off understood.
|
|
138
|
+
*
|
|
139
|
+
* The ramp step rather than a semantic token because none of the three
|
|
140
|
+
* background-brand-* tokens maps to Brand-200; if in-range fills turn up in
|
|
141
|
+
* other components, this wants promoting to a token of its own.
|
|
142
|
+
*
|
|
143
|
+
* Day numerals stay text-text-primary (Grey-900, #171c26) and clear AA on this
|
|
144
|
+
* fill comfortably. The endpoints are unaffected: white on Brand-500 at 6.4:1.
|
|
145
|
+
*/
|
|
146
|
+
.rsui-form-field-date-range__day--in-range {
|
|
147
|
+
@apply bg-brand-200 rounded-none;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.rsui-form-field-date-range__day--range-start,
|
|
151
|
+
.rsui-form-field-date-range__day--range-end {
|
|
152
|
+
@apply bg-background-brand-contrast text-text-on-color font-semibold;
|
|
153
|
+
@apply hover:bg-background-brand-contrast;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
* The day the presets resolve against — "today" as the server sees it.
|
|
158
|
+
*
|
|
159
|
+
* Marked with an underline rather than a ring. It previously used ring-1 in the
|
|
160
|
+
* same colour as the focus ring's ring-2, so the only thing separating "this
|
|
161
|
+
* day has keyboard focus" from "this is the reference date" was one pixel of
|
|
162
|
+
* ring width — on a widget whose entire interaction model is a roving focus.
|
|
163
|
+
* A different SHAPE keeps the two readable at a glance, and readable at all for
|
|
164
|
+
* anyone who cannot compare two greys.
|
|
165
|
+
*/
|
|
166
|
+
.rsui-form-field-date-range__day--reference {
|
|
167
|
+
@apply font-semibold underline decoration-2 underline-offset-4;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.rsui-form-field-date-range__day--unavailable {
|
|
171
|
+
@apply text-text-disabled cursor-not-allowed;
|
|
172
|
+
@apply hover:bg-transparent;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.rsui-form-field-date-range__sr-only {
|
|
176
|
+
@apply sr-only;
|
|
177
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
.rsui-stage-dial {
|
|
2
|
+
/* Accent falls back to a neutral token when the consumer supplies no color. */
|
|
3
|
+
--rsui-stage-dial-accent: var(--color-background-secondary-contrast);
|
|
4
|
+
|
|
5
|
+
@apply relative m-0 p-0 shrink-0 before:hidden after:hidden;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/* Size ramp — mirrors ProgressCircle's sm/md/lg, scaled up because the dial
|
|
9
|
+
carries centre content inside the ring. The stroke is in viewBox units, so it
|
|
10
|
+
scales with the box and needs no per-size rule. */
|
|
11
|
+
.rsui-stage-dial--sm {
|
|
12
|
+
@apply size-16 text-xs;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.rsui-stage-dial--md {
|
|
16
|
+
@apply size-24 text-sm;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.rsui-stage-dial--lg {
|
|
20
|
+
@apply size-32 text-base;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.rsui-stage-dial__svg {
|
|
24
|
+
@apply w-full h-full;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* The unfilled ring behind every stage, so the full arc reads as the scale even
|
|
28
|
+
when only the first stage is reached. */
|
|
29
|
+
.rsui-stage-dial__track {
|
|
30
|
+
@apply fill-none stroke-border-primary;
|
|
31
|
+
|
|
32
|
+
stroke-width: 9;
|
|
33
|
+
stroke-linecap: round;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.rsui-stage-dial__fill {
|
|
37
|
+
@apply fill-none;
|
|
38
|
+
|
|
39
|
+
stroke: var(--rsui-stage-dial-accent);
|
|
40
|
+
stroke-width: 9;
|
|
41
|
+
stroke-linecap: round;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Opt-in draw-in. The per-segment delay is set inline by the component, which
|
|
45
|
+
is what staggers the segments. */
|
|
46
|
+
.rsui-stage-dial--animate .rsui-stage-dial__fill {
|
|
47
|
+
transition: stroke-dasharray 0.75s cubic-bezier(0.22, 1, 0.36, 1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* The ring's inner edge sits at 12.5% of the box (radius 42 less half the
|
|
51
|
+
9-unit stroke, of 50), so a 15% inset keeps centre content clear of it. */
|
|
52
|
+
.rsui-stage-dial__content {
|
|
53
|
+
@apply absolute inset-[15%] flex items-center justify-center text-center;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (prefers-reduced-motion: reduce) {
|
|
57
|
+
.rsui-stage-dial--animate .rsui-stage-dial__fill {
|
|
58
|
+
transition: none;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/components.css
CHANGED
|
@@ -37,6 +37,7 @@ Please be careful when adding new components and updating the order.
|
|
|
37
37
|
@import './components/form_field_slot.css';
|
|
38
38
|
@import './components/form_field_checkbox.css';
|
|
39
39
|
@import './components/form_field_combobox.css';
|
|
40
|
+
@import './components/form_field_date_range.css';
|
|
40
41
|
@import './components/form_field_password.css';
|
|
41
42
|
@import './components/form_field_radio_group.css';
|
|
42
43
|
@import './components/form_field_search.css';
|
|
@@ -97,6 +98,7 @@ Please be careful when adding new components and updating the order.
|
|
|
97
98
|
@import './components/skeleton.css';
|
|
98
99
|
@import './components/single_column_layout.css';
|
|
99
100
|
@import './components/sorting.css';
|
|
101
|
+
@import './components/stage_dial.css';
|
|
100
102
|
@import './components/switcher.css';
|
|
101
103
|
@import './components/switcher_item.css';
|
|
102
104
|
@import './components/tab_slider.css';
|