@apliteni/apliteni-ui 0.77.0 → 0.79.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/guidelines/file-drop.md +87 -0
- package/package.json +1 -1
- package/react/README.md +114 -0
- package/react/dist/index.css +309 -2
- package/react/dist/index.d.ts +105 -1
- package/react/dist/index.js +920 -297
- package/src/index.css +1 -0
- package/src/inline.js +2 -0
- package/src/styles/file-drop.css +83 -0
- package/src/styles/tap-zone.css +42 -2
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# File drop
|
|
2
|
+
|
|
3
|
+
## Spend one row at rest
|
|
4
|
+
|
|
5
|
+
<!-- rule: one-row -->
|
|
6
|
+
|
|
7
|
+
**Rule:** At rest, a file drop is one row: the button that opens the picker and the accepted types beside it.
|
|
8
|
+
|
|
9
|
+
**Why:** A tall box holds the page's best space open for a file that arrives once a month.
|
|
10
|
+
|
|
11
|
+
**Do:** Put an Upload button and “PDF or CSV, up to 10 MB” on one line above the list they feed.
|
|
12
|
+
|
|
13
|
+
**Don't:** Draw a tall dashed box with a glyph, an invitation and a button stacked inside it.
|
|
14
|
+
|
|
15
|
+
**Except:** A page whose whole purpose is receiving one file may use the field-sized picker, which carries a label of its own.
|
|
16
|
+
|
|
17
|
+
## Paint the target only while a file is over it
|
|
18
|
+
|
|
19
|
+
<!-- rule: on-drag -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Show the drop target while a file is over the region that accepts it, and nowhere else.
|
|
22
|
+
|
|
23
|
+
**Why:** A target drawn before there is a file to catch covers content the reader still needs.
|
|
24
|
+
|
|
25
|
+
**Do:** Cover the panel that accepts the file the moment the file crosses it.
|
|
26
|
+
|
|
27
|
+
**Don't:** Cover the whole window when one panel accepts the file.
|
|
28
|
+
|
|
29
|
+
## Keep the file in the row it arrived in
|
|
30
|
+
|
|
31
|
+
<!-- rule: in-the-row -->
|
|
32
|
+
|
|
33
|
+
**Rule:** After the drop, the file's name, size and progress take the place the button was in, with remove on the name's line.
|
|
34
|
+
|
|
35
|
+
**Why:** A row that changes in place keeps the page still while the file uploads.
|
|
36
|
+
|
|
37
|
+
**Do:** Give the name a line with remove at its end, put the size under it, and run the progress track the full width below both.
|
|
38
|
+
|
|
39
|
+
**Don't:** Push the list down with a progress card, or open a dialog over the page.
|
|
40
|
+
|
|
41
|
+
## Fail in place
|
|
42
|
+
|
|
43
|
+
<!-- rule: failure -->
|
|
44
|
+
|
|
45
|
+
**Rule:** A refused file keeps its place, says what it did wrong under its name, and offers Retry beside Remove.
|
|
46
|
+
|
|
47
|
+
**Why:** A row that drops the file sends the reader back to choosing one. The reason is the one string here that has to be read in full, so it gets a line rather than a share of one.
|
|
48
|
+
|
|
49
|
+
**Do:** Keep the name on its line and say “Larger than 10 MB” under it, with Retry.
|
|
50
|
+
|
|
51
|
+
**Don't:** Replace the row with “Upload failed”, losing both the file and the retry.
|
|
52
|
+
|
|
53
|
+
## Offer a button, not only a drag
|
|
54
|
+
|
|
55
|
+
<!-- rule: button-path -->
|
|
56
|
+
|
|
57
|
+
**Rule:** Give the reader a button that opens the picker, and let dragging be the shortcut.
|
|
58
|
+
|
|
59
|
+
**Why:** A keyboard cannot drag a file.
|
|
60
|
+
|
|
61
|
+
**Do:** Make the Upload button the control, reachable by keyboard and showing the focus ring.
|
|
62
|
+
|
|
63
|
+
**Don't:** Write “Drag a file here” with nothing to press.
|
|
64
|
+
|
|
65
|
+
## State the limits once
|
|
66
|
+
|
|
67
|
+
<!-- rule: limits-once -->
|
|
68
|
+
|
|
69
|
+
**Rule:** Name the accepted types and the size limit once, beside the button, in the product's own words.
|
|
70
|
+
|
|
71
|
+
**Why:** Repeated limits teach the reader to skip them.
|
|
72
|
+
|
|
73
|
+
**Do:** Write “PDF or CSV, up to 10 MB” beside the button, and let a failure say what this file did wrong.
|
|
74
|
+
|
|
75
|
+
**Don't:** Repeat the limits under the button, in a tooltip and again in the error.
|
|
76
|
+
|
|
77
|
+
## Choose the row, the region or the dialog
|
|
78
|
+
|
|
79
|
+
<!-- rule: which-shape -->
|
|
80
|
+
|
|
81
|
+
**Rule:** Use a row where the file joins a list on the page, a region when one panel owns the file, and a dialog only when the upload needs answers of its own.
|
|
82
|
+
|
|
83
|
+
**Why:** A dialog that asks nothing is one more thing to dismiss. The rule picks between three containers, so a drawing would show one of them and not the choice.
|
|
84
|
+
|
|
85
|
+
**Do:** Take a statement into the row under the statements it joins, and a replacement logo into the panel that shows it.
|
|
86
|
+
|
|
87
|
+
**Don't:** Open a dialog for one file that the row behind it could have taken.
|
package/package.json
CHANGED
package/react/README.md
CHANGED
|
@@ -493,6 +493,34 @@ places a decorative kit glyph with `icon` — the same glyph names `Button` and
|
|
|
493
493
|
`onFileChange`. Use `accept` and `hint` to describe allowed file types and size.
|
|
494
494
|
Your application must validate files before upload.
|
|
495
495
|
|
|
496
|
+
## File drop
|
|
497
|
+
|
|
498
|
+
`FileDrop` is the compact drop: one row with the button that opens the picker and
|
|
499
|
+
the accepted types beside it, and a drop target painted only while a file is over
|
|
500
|
+
the region. Use it where a file joins a list on the page; use `FileField` where a
|
|
501
|
+
labelled, field-sized picker belongs. The guideline page states when to use a row,
|
|
502
|
+
a region or a dialog.
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
<FileDrop note="PDF or CSV, up to 10 MB" accept=".pdf,.csv"
|
|
506
|
+
file={upload} onFile={send} onRemove={clear} onRetry={send} />
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Your application owns the upload and supplies the `file` it is holding: the
|
|
510
|
+
name, the `size` already written for a reader, `progress` while it uploads, and
|
|
511
|
+
the `error` when it failed. A file with no `status` is uploading, so a file
|
|
512
|
+
handed over before the request starts never reads as uploaded. A status the row
|
|
513
|
+
draws shows a mark and a word; where you give `progress` the track says it
|
|
514
|
+
instead, and the word goes to the track's accessible name. The file reads as a
|
|
515
|
+
stack: the name on top with the actions at its end, the size — or the failure
|
|
516
|
+
message — under it, and the track the full width below. No tier takes a second
|
|
517
|
+
line. The name truncates its stem and keeps its extension, with the whole name in
|
|
518
|
+
a `title`, and nothing is hidden or moved at any width. `Remove` is the icon-only
|
|
519
|
+
`x`, named by `removeLabel`; `Retry` keeps its word. Both appear only when you
|
|
520
|
+
handle them. Children render above the row, inside the region the target covers;
|
|
521
|
+
pass `dragging` to drive that target from a parent. `accept` filters the system
|
|
522
|
+
picker only — validate type and size yourself.
|
|
523
|
+
|
|
496
524
|
Use `Field` when an existing labelled control needs the kit frame. Spread its
|
|
497
525
|
render-prop attributes onto one labelable control, and apply the existing control
|
|
498
526
|
class and invalid styling as appropriate:
|
|
@@ -672,3 +700,89 @@ the accent from a checked box.
|
|
|
672
700
|
<Checkbox label="Full access" type="radio" name="scope" value="full" />
|
|
673
701
|
<Switch label="Email notifications" checked={email} onChange={event => setEmail(event.currentTarget.checked)} />
|
|
674
702
|
```
|
|
703
|
+
|
|
704
|
+
## DatePicker
|
|
705
|
+
|
|
706
|
+
`DatePicker` picks one month (`mode="month"`, the default), a range of months
|
|
707
|
+
(`mode="range"`), one date (`mode="day"`) or a range of dates (`mode="day-range"`). It
|
|
708
|
+
uses the dropdown's own trigger and panel, so it sits beside a `Dropdown` as the same
|
|
709
|
+
control. Periods are ISO strings in the mode's grain: `'2026-08'` for months,
|
|
710
|
+
`'2026-08-14'` for dates. Pass `value`/`onChange` for the single-period modes and
|
|
711
|
+
`range`/`onRangeChange` for the two range modes, or `defaultValue`/`defaultRange` to
|
|
712
|
+
leave the state to the component. Import both the kit CSS and the React CSS.
|
|
713
|
+
|
|
714
|
+
```tsx
|
|
715
|
+
<DatePicker value={month} onChange={setMonth}
|
|
716
|
+
min="2025-01" max="2026-12" disabledPeriods={['2026-07']} />
|
|
717
|
+
|
|
718
|
+
<DatePicker mode="range" range={span} onRangeChange={setSpan}
|
|
719
|
+
presets={[{ label: 'This year', range: { start: '2026-01', end: '2026-12' } }]} />
|
|
720
|
+
|
|
721
|
+
<DatePicker mode="day-range" range={span} onRangeChange={setSpan}
|
|
722
|
+
presets={[{ label: 'This week', range: { start: '2026-09-14', end: '2026-09-20' } }]} />
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
**The trigger shows the value and nothing else.** There is no field name in front of it:
|
|
726
|
+
"Period: Apr 2026 – Aug 2026" says "period" twice, and the picker has no word to add that
|
|
727
|
+
the value does not already carry. Where the surrounding screen leaves the control
|
|
728
|
+
unexplained, name it with `ariaLabel`, which names the trigger and the panel without
|
|
729
|
+
drawing anything.
|
|
730
|
+
|
|
731
|
+
**The grid has one tab stop.** The arrows move one period and one row, Home and End go to
|
|
732
|
+
the ends of the row — they never leave the month, so the blank slots a day grid pads its
|
|
733
|
+
first and last weeks with are not somewhere they can take you — Page Up and Page Down
|
|
734
|
+
move a year in the month modes and a month in day mode, Enter and Space pick, and Escape
|
|
735
|
+
closes and returns focus to the trigger. A move past the edge of the shown year or month
|
|
736
|
+
turns the page and keeps the reader on the period they moved to. Each cell's accessible
|
|
737
|
+
name says what the cell is: `selected` for the pick in every mode, plus `range start`,
|
|
738
|
+
`range end` and `in range` in range mode, and `this month` or `today`.
|
|
739
|
+
|
|
740
|
+
**Bounds hold against your code as well as the reader's.** `min`, `max` and
|
|
741
|
+
`disabledPeriods` are `string`, so a period in the other grain is converted rather than
|
|
742
|
+
dropped: in day mode `min="2026-09"` is 1 September and `max="2026-09"` is the 30th, and
|
|
743
|
+
`disabledPeriods={['2026-09']}` blocks the whole month; in month mode a date means the
|
|
744
|
+
month it falls in. Blocked cells get `aria-disabled` and refuse the press while staying
|
|
745
|
+
focusable. A page step with nowhere to go is disabled.
|
|
746
|
+
|
|
747
|
+
**A range mode takes a start, then an end**, staying open in between; a second pick above
|
|
748
|
+
or below the first always reads as the same range, so the ends swap rather than
|
|
749
|
+
restarting. `range` and `day-range` differ only in grain — a range may run past the page
|
|
750
|
+
it started on, and the span is painted on both pages.
|
|
751
|
+
`onRangeChange` fires on each end, so `{ start, end: null }` reaches you too. `presets`
|
|
752
|
+
set both ends at once and are held to the same bounds the grid is: a preset that overruns
|
|
753
|
+
them is clamped, one with no overlap at all is disabled, and one whose end lands on a
|
|
754
|
+
blocked period is disabled too rather than quietly moved inwards. A blocked period between
|
|
755
|
+
the two ends is still inside the range you are handed — `{ start, end }` is a pair and
|
|
756
|
+
spans it — and says so in its accessible name; only the tint is withheld, because the
|
|
757
|
+
disabled ink over it cannot be read. To exclude a period, split the range and show two
|
|
758
|
+
pickers.
|
|
759
|
+
|
|
760
|
+
**Blocked beats every other state in the paint, and the label is struck through.** Block
|
|
761
|
+
the period your own `value` names and the cell goes bare, keeping its place by weight
|
|
762
|
+
rather than wearing the accent fill under disabled ink; the strike is what says
|
|
763
|
+
unavailable before the pointer is anywhere near it. A cell under the pointer takes the
|
|
764
|
+
kit's neutral row hover, so the accent stays on the pick and the span. Its name still
|
|
765
|
+
says `selected` and the gridcell still carries `aria-selected`: it is still your value,
|
|
766
|
+
it just cannot be pressed.
|
|
767
|
+
|
|
768
|
+
**The period you are in now wears a ring** — hollow for the period you are in, filled for
|
|
769
|
+
the one you chose — and the cell's own name says "this month" or "today". Nothing is drawn
|
|
770
|
+
under the grid to explain it: a key is a second place to read, and these marks are the
|
|
771
|
+
ones a calendar has always drawn. There is no slot for a consumer's own note on a period
|
|
772
|
+
either; a 5px dot can only be read against a key, and a note about a period belongs on the
|
|
773
|
+
surface that shows that period's numbers. The month grid draws its twelve names at one
|
|
774
|
+
length — "Sep", not en-GB's "Sept" — so no cell reads as emphasised; a locale that numbers
|
|
775
|
+
its months keeps its own names.
|
|
776
|
+
|
|
777
|
+
**Below 560px the panel is a bottom `Drawer`**, so the sheet has the kit's scrim, close
|
|
778
|
+
control and focus trap and the page behind it is inert. Pass `sheet` to force that at any
|
|
779
|
+
width — a host that already knows it is on a phone, or one rendering where no viewport
|
|
780
|
+
can be read, should, because the picker reads the viewport with `matchMedia` and starts
|
|
781
|
+
as the popover until it has.
|
|
782
|
+
|
|
783
|
+
Pass `today` (a `'YYYY-MM-DD'` date) to fix what the grid calls today — stories and tests
|
|
784
|
+
use it to stay the same whenever they run. `locale` names the months and weekdays,
|
|
785
|
+
`weekStartsOn` sets the first column in day mode, and `align="end"` hangs the panel off
|
|
786
|
+
the trigger's trailing edge. Without `ariaLabel` the trigger's own text is its accessible
|
|
787
|
+
name, so a control reading "17 September 2026" is heard as that rather than as its
|
|
788
|
+
placeholder. The popover stays mounted while closed, and is `inert` while it is.
|
package/react/dist/index.css
CHANGED
|
@@ -31,14 +31,15 @@
|
|
|
31
31
|
--tap-min: 44px;
|
|
32
32
|
--tap-aa: 24px;
|
|
33
33
|
--tap-gap: var(--space-5, 20px);
|
|
34
|
+
--tap-gap-bordered: calc(var(--tap-min) - var(--tap-aa) + 2px);
|
|
34
35
|
--tap-clear-x: 0px;
|
|
35
36
|
--tap-clear-y: 0px;
|
|
36
37
|
}
|
|
37
38
|
@media (max-width: 560px) and (pointer: coarse) {
|
|
38
|
-
:where(.ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social) {
|
|
39
|
+
:where(.ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-datepicker__opt) {
|
|
39
40
|
position: relative;
|
|
40
41
|
}
|
|
41
|
-
:where(.ui-btn, .ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-switch)::after {
|
|
42
|
+
:where(.ui-btn, .ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-switch, .ui-datepicker__opt)::after {
|
|
42
43
|
content: "";
|
|
43
44
|
position: absolute;
|
|
44
45
|
left: 50%;
|
|
@@ -82,6 +83,14 @@
|
|
|
82
83
|
.ui-table__act .ui-btn + .ui-btn {
|
|
83
84
|
margin-inline-start: var(--tap-gap) !important;
|
|
84
85
|
}
|
|
86
|
+
.ui-drop__row {
|
|
87
|
+
--tap-clear-y: var(--tap-gap);
|
|
88
|
+
}
|
|
89
|
+
.ui-drop__actions {
|
|
90
|
+
gap: var(--tap-gap) !important;
|
|
91
|
+
--tap-clear-x: var(--tap-gap);
|
|
92
|
+
--tap-clear-y: var(--tap-gap);
|
|
93
|
+
}
|
|
85
94
|
.ui-table__act {
|
|
86
95
|
--tap-clear-x: var(--tap-gap);
|
|
87
96
|
--tap-clear-y: 0px;
|
|
@@ -101,6 +110,19 @@
|
|
|
101
110
|
row-gap: var(--tap-gap) !important;
|
|
102
111
|
--tap-clear-y: var(--tap-gap);
|
|
103
112
|
}
|
|
113
|
+
.ui-datepicker__grid {
|
|
114
|
+
row-gap: var(--tap-gap) !important;
|
|
115
|
+
--tap-clear-x: var(--space-1, 4px);
|
|
116
|
+
--tap-clear-y: var(--tap-gap);
|
|
117
|
+
}
|
|
118
|
+
.ui-datepicker__head {
|
|
119
|
+
--tap-clear-x: var(--tap-gap-bordered);
|
|
120
|
+
--tap-clear-y: var(--tap-gap-bordered);
|
|
121
|
+
}
|
|
122
|
+
.ui-datepicker__presets {
|
|
123
|
+
--tap-clear-x: var(--space-1, 4px);
|
|
124
|
+
--tap-clear-y: var(--tap-gap-bordered);
|
|
125
|
+
}
|
|
104
126
|
.ui-footer__socials,
|
|
105
127
|
.ui-drawer__header {
|
|
106
128
|
gap: var(--tap-gap) !important;
|
|
@@ -276,6 +298,168 @@
|
|
|
276
298
|
}
|
|
277
299
|
}
|
|
278
300
|
|
|
301
|
+
/* src/DatePicker.css */
|
|
302
|
+
.ui-datepicker__panel {
|
|
303
|
+
--ui-dropdown-pad: var(--space-3);
|
|
304
|
+
width: max-content;
|
|
305
|
+
min-width: 0;
|
|
306
|
+
max-width: 92vw;
|
|
307
|
+
}
|
|
308
|
+
.ui-datepicker__body {
|
|
309
|
+
display: flex;
|
|
310
|
+
align-items: flex-start;
|
|
311
|
+
gap: var(--space-4);
|
|
312
|
+
}
|
|
313
|
+
.ui-datepicker__calendar {
|
|
314
|
+
display: grid;
|
|
315
|
+
gap: var(--space-3);
|
|
316
|
+
}
|
|
317
|
+
.ui-datepicker__head {
|
|
318
|
+
display: flex;
|
|
319
|
+
align-items: center;
|
|
320
|
+
justify-content: space-between;
|
|
321
|
+
gap: var(--space-2);
|
|
322
|
+
}
|
|
323
|
+
.ui-datepicker__caption {
|
|
324
|
+
font-size: var(--text-sm);
|
|
325
|
+
font-weight: var(--weight-semibold);
|
|
326
|
+
color: var(--strong);
|
|
327
|
+
}
|
|
328
|
+
.ui-datepicker__grid {
|
|
329
|
+
display: grid;
|
|
330
|
+
gap: var(--space-1);
|
|
331
|
+
}
|
|
332
|
+
.ui-datepicker__row {
|
|
333
|
+
display: grid;
|
|
334
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
335
|
+
gap: var(--space-1);
|
|
336
|
+
}
|
|
337
|
+
.ui-datepicker__grid.is-days .ui-datepicker__row {
|
|
338
|
+
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
339
|
+
}
|
|
340
|
+
.ui-datepicker__weekday {
|
|
341
|
+
display: flex;
|
|
342
|
+
align-items: center;
|
|
343
|
+
justify-content: center;
|
|
344
|
+
font-size: var(--text-xs);
|
|
345
|
+
font-weight: var(--weight-semibold);
|
|
346
|
+
color: var(--text);
|
|
347
|
+
}
|
|
348
|
+
.ui-datepicker__cell {
|
|
349
|
+
display: flex;
|
|
350
|
+
}
|
|
351
|
+
.ui-datepicker__opt {
|
|
352
|
+
position: relative;
|
|
353
|
+
flex: 1;
|
|
354
|
+
display: inline-flex;
|
|
355
|
+
align-items: center;
|
|
356
|
+
justify-content: center;
|
|
357
|
+
min-width: 34px;
|
|
358
|
+
min-height: 34px;
|
|
359
|
+
padding: var(--space-2);
|
|
360
|
+
font-size: var(--text-sm);
|
|
361
|
+
font-weight: var(--weight-medium);
|
|
362
|
+
font-variant-numeric: tabular-nums;
|
|
363
|
+
color: var(--text);
|
|
364
|
+
background: transparent;
|
|
365
|
+
border: 1px solid transparent;
|
|
366
|
+
border-radius: var(--radius-xs);
|
|
367
|
+
cursor: pointer;
|
|
368
|
+
transition:
|
|
369
|
+
background var(--dur-fast) var(--ease),
|
|
370
|
+
border-color var(--dur-fast) var(--ease),
|
|
371
|
+
color var(--dur-fast) var(--ease);
|
|
372
|
+
}
|
|
373
|
+
.ui-datepicker__grid.is-days .ui-datepicker__opt {
|
|
374
|
+
min-width: 30px;
|
|
375
|
+
}
|
|
376
|
+
.ui-datepicker__opt:hover {
|
|
377
|
+
outline: 1px solid var(--control-edge);
|
|
378
|
+
outline-offset: -1px;
|
|
379
|
+
background: var(--surface);
|
|
380
|
+
color: var(--strong);
|
|
381
|
+
}
|
|
382
|
+
.ui-datepicker__opt:focus-visible {
|
|
383
|
+
outline: 2px solid transparent;
|
|
384
|
+
}
|
|
385
|
+
.ui-datepicker__opt.is-inside {
|
|
386
|
+
background: color-mix(in srgb, var(--accent) 14%, var(--bg-elevated));
|
|
387
|
+
}
|
|
388
|
+
.ui-datepicker__opt.is-selected {
|
|
389
|
+
background: var(--accent-strong);
|
|
390
|
+
border-color: var(--accent-strong);
|
|
391
|
+
color: var(--accent-contrast);
|
|
392
|
+
}
|
|
393
|
+
.ui-datepicker__opt.is-selected:hover {
|
|
394
|
+
outline-color: transparent;
|
|
395
|
+
background: var(--accent-strong);
|
|
396
|
+
color: var(--accent-contrast);
|
|
397
|
+
}
|
|
398
|
+
.ui-datepicker__opt.is-today {
|
|
399
|
+
border-color: var(--accent);
|
|
400
|
+
}
|
|
401
|
+
.ui-datepicker__opt.is-today:hover {
|
|
402
|
+
outline-color: transparent;
|
|
403
|
+
}
|
|
404
|
+
.ui-datepicker__opt.is-selected.is-today {
|
|
405
|
+
border-color: var(--accent-contrast);
|
|
406
|
+
}
|
|
407
|
+
.ui-datepicker__opt.is-disabled {
|
|
408
|
+
color: var(--disabled-ink-bare);
|
|
409
|
+
cursor: not-allowed;
|
|
410
|
+
}
|
|
411
|
+
.ui-datepicker__opt.is-disabled .ui-datepicker__num {
|
|
412
|
+
text-decoration: line-through;
|
|
413
|
+
}
|
|
414
|
+
.ui-datepicker__opt.is-disabled:hover {
|
|
415
|
+
outline-color: transparent;
|
|
416
|
+
background: transparent;
|
|
417
|
+
border-color: transparent;
|
|
418
|
+
color: var(--disabled-ink-bare);
|
|
419
|
+
}
|
|
420
|
+
.ui-datepicker__opt.is-disabled.is-selected,
|
|
421
|
+
.ui-datepicker__opt.is-disabled.is-selected:hover,
|
|
422
|
+
.ui-datepicker__opt.is-disabled.is-inside,
|
|
423
|
+
.ui-datepicker__opt.is-disabled.is-inside:hover {
|
|
424
|
+
background: transparent;
|
|
425
|
+
border-color: transparent;
|
|
426
|
+
color: var(--disabled-ink-bare);
|
|
427
|
+
}
|
|
428
|
+
.ui-datepicker__opt.is-disabled.is-selected {
|
|
429
|
+
font-weight: var(--weight-bold);
|
|
430
|
+
}
|
|
431
|
+
.ui-datepicker__opt.is-disabled.is-today,
|
|
432
|
+
.ui-datepicker__opt.is-disabled.is-today:hover {
|
|
433
|
+
border-color: var(--accent);
|
|
434
|
+
}
|
|
435
|
+
.ui-datepicker__presets {
|
|
436
|
+
display: grid;
|
|
437
|
+
align-content: start;
|
|
438
|
+
gap: var(--space-1);
|
|
439
|
+
padding: 0 var(--space-3) 0 0;
|
|
440
|
+
border-inline-end: 1px solid var(--border);
|
|
441
|
+
}
|
|
442
|
+
.ui-datepicker__preset {
|
|
443
|
+
justify-content: flex-start;
|
|
444
|
+
}
|
|
445
|
+
.ui-datepicker__body.is-sheet {
|
|
446
|
+
flex-direction: column;
|
|
447
|
+
align-items: stretch;
|
|
448
|
+
}
|
|
449
|
+
.ui-datepicker__body.is-sheet .ui-datepicker__presets {
|
|
450
|
+
grid-auto-flow: column;
|
|
451
|
+
grid-auto-columns: max-content;
|
|
452
|
+
overflow-x: auto;
|
|
453
|
+
scroll-padding-inline: var(--space-1);
|
|
454
|
+
padding: var(--space-3) var(--space-1);
|
|
455
|
+
border-inline-end: 0;
|
|
456
|
+
border-block-end: 1px solid var(--border);
|
|
457
|
+
}
|
|
458
|
+
.ui-datepicker__body.is-sheet .ui-datepicker__presets:focus-visible {
|
|
459
|
+
outline: var(--ring-scroll);
|
|
460
|
+
outline-offset: var(--ring-scroll-offset);
|
|
461
|
+
}
|
|
462
|
+
|
|
279
463
|
/* src/KeyValueList.css */
|
|
280
464
|
.ui-kv {
|
|
281
465
|
display: grid;
|
|
@@ -498,6 +682,129 @@
|
|
|
498
682
|
cursor: not-allowed;
|
|
499
683
|
}
|
|
500
684
|
|
|
685
|
+
/* ../src/styles/file-drop.css */
|
|
686
|
+
.ui-drop {
|
|
687
|
+
position: relative;
|
|
688
|
+
}
|
|
689
|
+
.ui-drop > * + .ui-drop__row {
|
|
690
|
+
margin-top: var(--space-3);
|
|
691
|
+
}
|
|
692
|
+
.ui-drop__row {
|
|
693
|
+
display: flex;
|
|
694
|
+
flex-wrap: wrap;
|
|
695
|
+
align-items: center;
|
|
696
|
+
min-height: var(--space-8);
|
|
697
|
+
gap: var(--space-2) var(--space-3);
|
|
698
|
+
font-size: var(--text-sm);
|
|
699
|
+
color: var(--text);
|
|
700
|
+
overflow-wrap: anywhere;
|
|
701
|
+
}
|
|
702
|
+
.ui-drop__note {
|
|
703
|
+
margin: 0;
|
|
704
|
+
}
|
|
705
|
+
.ui-drop__file {
|
|
706
|
+
display: grid;
|
|
707
|
+
flex: 1 1 auto;
|
|
708
|
+
gap: var(--space-2);
|
|
709
|
+
min-width: 0;
|
|
710
|
+
}
|
|
711
|
+
.ui-drop__line {
|
|
712
|
+
display: flex;
|
|
713
|
+
flex-wrap: nowrap;
|
|
714
|
+
align-items: center;
|
|
715
|
+
gap: var(--space-3);
|
|
716
|
+
min-width: 0;
|
|
717
|
+
}
|
|
718
|
+
.ui-drop__name {
|
|
719
|
+
display: flex;
|
|
720
|
+
flex: 1 1 auto;
|
|
721
|
+
min-width: var(--space-10);
|
|
722
|
+
color: var(--strong);
|
|
723
|
+
font-weight: var(--weight-medium);
|
|
724
|
+
}
|
|
725
|
+
.ui-drop__stem {
|
|
726
|
+
overflow: hidden;
|
|
727
|
+
text-overflow: ellipsis;
|
|
728
|
+
white-space: nowrap;
|
|
729
|
+
}
|
|
730
|
+
.ui-drop__ext {
|
|
731
|
+
flex: none;
|
|
732
|
+
}
|
|
733
|
+
.ui-drop__facts {
|
|
734
|
+
display: flex;
|
|
735
|
+
flex-wrap: nowrap;
|
|
736
|
+
align-items: center;
|
|
737
|
+
gap: var(--space-3);
|
|
738
|
+
min-width: 0;
|
|
739
|
+
}
|
|
740
|
+
.ui-drop__size {
|
|
741
|
+
flex: none;
|
|
742
|
+
white-space: nowrap;
|
|
743
|
+
}
|
|
744
|
+
.ui-drop__word {
|
|
745
|
+
overflow: hidden;
|
|
746
|
+
text-overflow: ellipsis;
|
|
747
|
+
white-space: nowrap;
|
|
748
|
+
flex: 0 1 auto;
|
|
749
|
+
min-width: 0;
|
|
750
|
+
}
|
|
751
|
+
.ui-drop__state {
|
|
752
|
+
display: inline-flex;
|
|
753
|
+
flex: 0 1 auto;
|
|
754
|
+
align-items: center;
|
|
755
|
+
gap: var(--space-2);
|
|
756
|
+
min-width: 0;
|
|
757
|
+
}
|
|
758
|
+
.ui-drop__state svg {
|
|
759
|
+
width: 16px;
|
|
760
|
+
height: 16px;
|
|
761
|
+
flex: none;
|
|
762
|
+
stroke-width: 2.4;
|
|
763
|
+
}
|
|
764
|
+
.ui-drop__error {
|
|
765
|
+
color: var(--pink);
|
|
766
|
+
}
|
|
767
|
+
.ui-drop__actions {
|
|
768
|
+
display: flex;
|
|
769
|
+
flex: none;
|
|
770
|
+
align-items: center;
|
|
771
|
+
gap: var(--space-2);
|
|
772
|
+
margin-left: auto;
|
|
773
|
+
}
|
|
774
|
+
.ui-drop__bar {
|
|
775
|
+
display: block;
|
|
776
|
+
width: 100%;
|
|
777
|
+
height: 6px;
|
|
778
|
+
border-radius: var(--radius-pill);
|
|
779
|
+
background: var(--surface-2);
|
|
780
|
+
overflow: hidden;
|
|
781
|
+
}
|
|
782
|
+
.ui-drop__bar span {
|
|
783
|
+
display: block;
|
|
784
|
+
height: 100%;
|
|
785
|
+
background: var(--accent);
|
|
786
|
+
}
|
|
787
|
+
.ui-drop__target {
|
|
788
|
+
position: absolute;
|
|
789
|
+
inset: 0;
|
|
790
|
+
display: flex;
|
|
791
|
+
align-items: center;
|
|
792
|
+
justify-content: center;
|
|
793
|
+
padding: var(--space-3);
|
|
794
|
+
border: 1px dashed var(--accent);
|
|
795
|
+
border-radius: var(--radius-md);
|
|
796
|
+
background: var(--surface);
|
|
797
|
+
color: var(--strong);
|
|
798
|
+
font-size: var(--text-sm);
|
|
799
|
+
text-align: center;
|
|
800
|
+
}
|
|
801
|
+
.ui-drop.is-disabled .ui-drop__row {
|
|
802
|
+
color: var(--disabled-ink);
|
|
803
|
+
}
|
|
804
|
+
.ui-drop.is-disabled .ui-drop__name {
|
|
805
|
+
color: var(--disabled-ink);
|
|
806
|
+
}
|
|
807
|
+
|
|
501
808
|
/* src/Toast.css */
|
|
502
809
|
.rx-toast-stack {
|
|
503
810
|
position: fixed;
|