@crewlethq/ui 0.3.0 → 0.4.1
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/Card/Card.d.ts +23 -1
- package/dist/Card/index.js +1 -1
- package/dist/{Card-AHX3Q2JD.css → Card-RLR254LD.css} +22 -0
- package/dist/CodeBlock/CodeBlock.d.ts +68 -9
- package/dist/CodeBlock/index.js +3 -3
- package/dist/{CodeBlock-U2W6NNVC.css → CodeBlock-GYNJ2HI6.css} +50 -15
- package/dist/Copyable/CopyButton.d.ts +11 -1
- package/dist/Copyable/Copyable.d.ts +9 -1
- package/dist/Copyable/index.js +2 -2
- package/dist/DataTable/index.js +2 -2
- package/dist/DataView/index.js +3 -3
- package/dist/FilterChip/FilterChip.d.ts +37 -5
- package/dist/FilterChip/index.d.ts +1 -1
- package/dist/FilterChip/index.js +1 -1
- package/dist/Meter/Meter.d.ts +79 -2
- package/dist/Meter/index.d.ts +2 -2
- package/dist/Meter/index.js +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts +36 -3
- package/dist/SegmentedControl/index.d.ts +1 -1
- package/dist/SegmentedControl/index.js +2 -2
- package/dist/Select/Select.d.ts +16 -1
- package/dist/Select/index.js +1 -1
- package/dist/Tabs/index.js +1 -1
- package/dist/Tabs/roving.d.ts +32 -1
- package/dist/ThemeSwitcher/index.js +3 -3
- package/dist/TimeWindowPicker/index.js +2 -2
- package/dist/{chunk-GUIF6Q6N.js → chunk-2HQR4U4D.js} +1 -1
- package/dist/{chunk-GHYY2WPF.js → chunk-34VGEDVV.js} +1 -1
- package/dist/{chunk-D3OADIM6.js → chunk-3QRYCPXQ.js} +7 -3
- package/dist/{chunk-V663QU4R.js → chunk-5VNUYO76.js} +16 -5
- package/dist/chunk-6ZFVFA56.js +108 -0
- package/dist/{chunk-HTDFCRJZ.js → chunk-D35VTV2Z.js} +20 -6
- package/dist/{chunk-T7FKOJKW.js → chunk-NDCATSW7.js} +11 -3
- package/dist/{chunk-5IMACPJS.js → chunk-OFHBK7RI.js} +5 -2
- package/dist/{chunk-YMWONFSI.js → chunk-QEUY3A5P.js} +19 -3
- package/dist/{chunk-G2QFRTJ2.js → chunk-WOYYD2YR.js} +1 -1
- package/dist/{chunk-EHMQQHYR.js → chunk-WQX73TWF.js} +1 -1
- package/dist/{chunk-LGCPQIOZ.js → chunk-YODNNSZL.js} +23 -9
- package/dist/{chunk-EPOOQZYA.js → chunk-ZFATEERP.js} +32 -6
- package/dist/generated/index.js +16 -16
- package/dist/index.js +16 -16
- package/dist/styles.css +74 -17
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/useClipboard.d.ts +56 -4
- package/package.json +3 -3
- package/dist/chunk-ARMRX2YV.js +0 -96
package/dist/Card/Card.d.ts
CHANGED
|
@@ -131,12 +131,34 @@ export interface CardTitleProps extends HTMLAttributes<HTMLHeadingElement> {
|
|
|
131
131
|
* heading and an `h2` at the top of a page.
|
|
132
132
|
*/
|
|
133
133
|
as?: `h${HeadingLevel}` | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* A title with nowhere left to go ENDS in an ellipsis rather than being cut.
|
|
136
|
+
*
|
|
137
|
+
* The head is one line and the name block clips, so a title longer than the
|
|
138
|
+
* row is stopped at the header's edge — mid-word, with nothing to say a word
|
|
139
|
+
* was lost. `text-overflow` is the answer to that and it applies to a BLOCK
|
|
140
|
+
* container only, never to a flex one, and the title is flex: the text
|
|
141
|
+
* inside it is an anonymous flex item that no rule in this stylesheet can
|
|
142
|
+
* reach. So the ellipsis is a change of the title's own display, which is a
|
|
143
|
+
* change to what a caller's own children do inside it, which is why it is
|
|
144
|
+
* asked for rather than assumed.
|
|
145
|
+
*
|
|
146
|
+
* OFF BY DEFAULT, because it is not free: a truncating title lays its
|
|
147
|
+
* children out as one line of inline content instead of as centred,
|
|
148
|
+
* gap-separated flex items, so a caller who put a glyph or a tag inside the
|
|
149
|
+
* title gets it on the text baseline with no gap. `Card.Header`'s own `icon`
|
|
150
|
+
* slot is where a glyph belongs, and it is outside the title and unaffected.
|
|
151
|
+
* A title of plain text — which is every title in this package and every one
|
|
152
|
+
* in the engine dashboard — reads identically either way, and is exactly the
|
|
153
|
+
* case that was being cut.
|
|
154
|
+
*/
|
|
155
|
+
truncate?: boolean | undefined;
|
|
134
156
|
}
|
|
135
157
|
export declare const Card: (({ variant, padding, interactive, rail, selected, as, href, asChild, className, children, ...rest }: CardProps) => import("react/jsx-runtime").JSX.Element) & {
|
|
136
158
|
Header: ({ divided, icon, count, subtitle, actions, className, children, ...rest }: CardHeaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
137
159
|
Body: ({ padding, className, children, ...rest }: CardSectionProps) => import("react/jsx-runtime").JSX.Element;
|
|
138
160
|
Footer: ({ variant, padding, className, children, ...rest }: CardFooterProps) => import("react/jsx-runtime").JSX.Element;
|
|
139
|
-
Title: ({ as, className, children, ...rest }: CardTitleProps) => import("react/jsx-runtime").JSX.Element;
|
|
161
|
+
Title: ({ as, truncate, className, children, ...rest }: CardTitleProps) => import("react/jsx-runtime").JSX.Element;
|
|
140
162
|
Description: ({ className, children, ...rest }: HTMLAttributes<HTMLParagraphElement>) => import("react/jsx-runtime").JSX.Element;
|
|
141
163
|
};
|
|
142
164
|
export {};
|
package/dist/Card/index.js
CHANGED
|
@@ -394,6 +394,28 @@
|
|
|
394
394
|
color: var(--color-text-primary);
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
+
/*
|
|
398
|
+
* A TITLE THAT ENDS RATHER THAN STOPS, where a caller has asked for it.
|
|
399
|
+
*
|
|
400
|
+
* The name block clips, which is what keeps the head one line, so a title
|
|
401
|
+
* wider than the row is cut at the header's edge — mid-word, with nothing to
|
|
402
|
+
* say a word was lost. `text-overflow` is the rule that says it, and it
|
|
403
|
+
* applies to a BLOCK container only: on the flex title above it does nothing
|
|
404
|
+
* at all, and the text it would act on is an anonymous flex item that no
|
|
405
|
+
* selector here can reach. So the modifier makes the title a block. Its
|
|
406
|
+
* children are then one line of inline content rather than centred flex items
|
|
407
|
+
* with a gap between them, which is the whole of what a caller opts into, and
|
|
408
|
+
* why this is a modifier rather than the base rule.
|
|
409
|
+
*
|
|
410
|
+
* `white-space: nowrap` is already the title's own, and `min-width: 0` is what
|
|
411
|
+
* lets the block shrink below its content inside the name block; both stand.
|
|
412
|
+
*/
|
|
413
|
+
.crewlet-card__title--truncate {
|
|
414
|
+
display: block;
|
|
415
|
+
overflow: hidden;
|
|
416
|
+
text-overflow: ellipsis;
|
|
417
|
+
}
|
|
418
|
+
|
|
397
419
|
/*
|
|
398
420
|
* The subtitle gives up its tail and the title does not: a title is the
|
|
399
421
|
* record's identity and has to be read in full, while a subtitle is context.
|
|
@@ -19,31 +19,90 @@ interface CodeBlockLook extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>
|
|
|
19
19
|
* trace, and a sideways scrollbar on one of those is a line nobody finds the
|
|
20
20
|
* end of. Turn it off for a block whose columns are the point: a diff, a
|
|
21
21
|
* table of output, a log that is aligned on purpose.
|
|
22
|
+
*
|
|
23
|
+
* THIS IS THE WRAPPING PROP, and the only one. `plain` is about the header;
|
|
24
|
+
* see its note.
|
|
22
25
|
*/
|
|
23
26
|
wrap?: boolean | undefined;
|
|
24
27
|
/**
|
|
25
|
-
* A ceiling, after which
|
|
26
|
-
* of px. Without one a 900-line record pushes everything under it
|
|
27
|
-
* screen.
|
|
28
|
+
* A ceiling for THIS block, after which it scrolls itself: a CSS length, or
|
|
29
|
+
* a number of px. Without one a 900-line record pushes everything under it
|
|
30
|
+
* off the screen.
|
|
31
|
+
*
|
|
32
|
+
* There is no default, and a ceiling every caller has to remember is a
|
|
33
|
+
* ceiling somebody forgets — so the value is also readable from the CASCADE.
|
|
34
|
+
* An application that wants one ceiling for every block it renders declares
|
|
35
|
+
* `--crewlet-codeblock-max-height` on an ancestor (`:root`, a route's own
|
|
36
|
+
* wrapper) and passes nothing here; this prop then OVERRIDES that ancestor
|
|
37
|
+
* for one block, `maxHeight="none"` escapes it, and with neither set the
|
|
38
|
+
* block is unbounded exactly as it has always been.
|
|
28
39
|
*/
|
|
29
40
|
maxHeight?: string | number | undefined;
|
|
30
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* No HEADER at all, for a block inside a row that already has one: no
|
|
43
|
+
* filename strip, no language, no copy control.
|
|
44
|
+
*
|
|
45
|
+
* IT IS ABOUT THE CHROME, NEVER THE TEXT. A `plain` block still wraps, and a
|
|
46
|
+
* block with a header wraps too — wrapping is `wrap` and nothing else. The
|
|
47
|
+
* name is worth reading twice when porting, because it is a word other code
|
|
48
|
+
* blocks spend on the opposite meaning: a `plain` that turned WRAPPING off
|
|
49
|
+
* is `wrap={false}` here.
|
|
50
|
+
*/
|
|
31
51
|
plain?: boolean | undefined;
|
|
32
52
|
}
|
|
33
53
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
54
|
+
* WHAT MAKES A BLOCK FOCUSABLE IS TWO DECISIONS, AND A NAME IS WHAT BOTH OWE.
|
|
55
|
+
*
|
|
56
|
+
* `selectable` is an INTENT only the caller has: this block is the record the
|
|
57
|
+
* screen is about, so while it has focus Command or Control plus A means this
|
|
58
|
+
* record rather than the document.
|
|
59
|
+
*
|
|
60
|
+
* `focusWhenScrollable` is an OBLIGATION the component discharges for itself.
|
|
61
|
+
* The `pre` is `overflow: auto`, so a ceiling or `wrap={false}` can turn any
|
|
62
|
+
* block into a scroll container, and a scroll container no keyboard can reach
|
|
63
|
+
* is content no keyboard can read. Whether a given block is one is a fact
|
|
64
|
+
* about the RENDERED BOX, not about any prop — the same code overflows at one
|
|
65
|
+
* viewport and not at the next — so the component measures it. A card carrying
|
|
66
|
+
* dozens of tool-argument blocks then gets a tab stop in front of the two that
|
|
67
|
+
* scroll rather than in front of all of them.
|
|
68
|
+
*
|
|
69
|
+
* They are separate because they answer different questions, and welding them
|
|
70
|
+
* gets both cases wrong: a block promoted for its scrollbar would start
|
|
71
|
+
* swallowing a chord nobody pressed for it, and a block that owns the chord
|
|
72
|
+
* would have to scroll to be named.
|
|
73
|
+
*
|
|
74
|
+
* `label` is the part they SHARE, and the type is what says so: a focusable
|
|
75
|
+
* `role="region"` with no accessible name is a tab stop a screen reader
|
|
76
|
+
* announces as nothing, which is worse than the plain block it replaced. So
|
|
77
|
+
* every arm that can take focus demands one, from either door, and the arm
|
|
78
|
+
* that cannot take focus refuses one — an optional label beside an optional
|
|
79
|
+
* flag is a label somebody forgets, and a label on a block that can never be
|
|
80
|
+
* named is a prop that silently does nothing.
|
|
39
81
|
*/
|
|
40
82
|
export type CodeBlockProps = CodeBlockLook & ({
|
|
41
83
|
/** Take Command or Control plus A while focused, and take focus. */
|
|
42
84
|
selectable: true;
|
|
85
|
+
/** Also take focus when the rendered box turns out to scroll. */
|
|
86
|
+
focusWhenScrollable?: boolean | undefined;
|
|
43
87
|
/** What this block is: "The turn record, as JSON". */
|
|
44
88
|
label: string;
|
|
45
89
|
} | {
|
|
46
90
|
selectable?: false | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Take focus when, and only when, the rendered box scrolls — on
|
|
93
|
+
* either axis. The block is a named region then and nothing more: the
|
|
94
|
+
* select-all chord stays with the browser.
|
|
95
|
+
*/
|
|
96
|
+
focusWhenScrollable: true;
|
|
97
|
+
/**
|
|
98
|
+
* What this block is. Required although the block may never take
|
|
99
|
+
* focus, because whether it does is a property of the box at one
|
|
100
|
+
* viewport and not of this call.
|
|
101
|
+
*/
|
|
102
|
+
label: string;
|
|
103
|
+
} | {
|
|
104
|
+
selectable?: false | undefined;
|
|
105
|
+
focusWhenScrollable?: false | undefined;
|
|
47
106
|
label?: never;
|
|
48
107
|
});
|
|
49
108
|
/**
|
package/dist/CodeBlock/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { CodeBlock } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { CodeBlock } from '../chunk-D35VTV2Z.js';
|
|
2
|
+
import '../chunk-3QRYCPXQ.js';
|
|
3
|
+
import '../chunk-5VNUYO76.js';
|
|
4
4
|
import '../chunk-F27EPQ7D.js';
|
|
5
5
|
import '../chunk-BZYDZBAN.js';
|
|
6
6
|
import '../chunk-BZFWDIV6.js';
|
|
@@ -66,6 +66,42 @@
|
|
|
66
66
|
white-space: pre-wrap;
|
|
67
67
|
overflow-wrap: anywhere;
|
|
68
68
|
tab-size: 2;
|
|
69
|
+
/*
|
|
70
|
+
* THE CEILING IS A CASCADING ONE, read here and declared nowhere, so the
|
|
71
|
+
* fallback IS the default: with nothing set the block is unbounded, as it
|
|
72
|
+
* has always been. `maxHeight` writes the property inline on the block, and
|
|
73
|
+
* an application that wants one ceiling for every block it renders writes it
|
|
74
|
+
* once on an ancestor instead — because a ceiling every call site has to
|
|
75
|
+
* remember is a ceiling somebody forgets, and the right height is a fact
|
|
76
|
+
* about the SURFACE the block sits on rather than about the component.
|
|
77
|
+
*
|
|
78
|
+
* Declared with a fallback rather than seeded on `.crewlet-codeblock`: a
|
|
79
|
+
* name a component declares on itself stops inheriting, so seeding it would
|
|
80
|
+
* be the one shape in which an ancestor's value can never arrive.
|
|
81
|
+
*
|
|
82
|
+
* ONE DECLARATION, in the rule below. `.crewlet-codeblock--bounded` is still
|
|
83
|
+
* emitted as the marker that this block set a ceiling of its own — the hook
|
|
84
|
+
* an application stylesheet and a reader of the DOM key on — but it draws
|
|
85
|
+
* nothing, because a second rule restating this height is how the two come
|
|
86
|
+
* to disagree.
|
|
87
|
+
*/
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
* The ceiling, at the specificity the rule it replaces already had.
|
|
92
|
+
*
|
|
93
|
+
* `.crewlet-codeblock .crewlet-codeblock__pre` rather than
|
|
94
|
+
* `.crewlet-codeblock__pre`, and the extra class earns its place: the rule
|
|
95
|
+
* that used to set this was `.crewlet-codeblock--bounded .crewlet-codeblock__pre`
|
|
96
|
+
* at (0,2,0), and an application overriding it wrote `.crewlet-codeblock__pre
|
|
97
|
+
* { max-height: … }` at (0,1,0) and expected to LOSE. Declaring it on the
|
|
98
|
+
* single class drops this to (0,1,0), which turns every one of those
|
|
99
|
+
* overrides into a tie decided by sheet order — so a consumer who wrote a
|
|
100
|
+
* losing rule on purpose silently starts winning. Same two-class weight,
|
|
101
|
+
* same outcome for anybody who already had an opinion.
|
|
102
|
+
*/
|
|
103
|
+
.crewlet-codeblock .crewlet-codeblock__pre {
|
|
104
|
+
max-height: var(--crewlet-codeblock-max-height, none);
|
|
69
105
|
}
|
|
70
106
|
|
|
71
107
|
/*
|
|
@@ -78,21 +114,20 @@
|
|
|
78
114
|
}
|
|
79
115
|
|
|
80
116
|
/*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* a secret.
|
|
117
|
+
* A BLOCK A READER CAN REACH. Two things put the block in the tab order and
|
|
118
|
+
* the role follows both: `selectable`, and `focusWhenScrollable` on a box that
|
|
119
|
+
* turned out to scroll.
|
|
120
|
+
*
|
|
121
|
+
* On the first, select-all is a document verb, so on a screen that is mostly
|
|
122
|
+
* one record it took the nav, the stat row and every card with it. While this
|
|
123
|
+
* block has focus the verb means "this record", which is the only thing
|
|
124
|
+
* anybody was reaching for, and the ring is what says so: a keyboard verb that
|
|
125
|
+
* changes meaning on focus, with no visible focus state, is a secret. On the
|
|
126
|
+
* second the block keeps no keys at all; the ring is there because a scroll
|
|
127
|
+
* container a reader arrows through has to say where they are.
|
|
128
|
+
*
|
|
129
|
+
* The text cursor is right for both, and it is what the caret-shape of a
|
|
130
|
+
* `pre` full of selectable text should always have been.
|
|
96
131
|
*/
|
|
97
132
|
.crewlet-codeblock__pre[role='region'] {
|
|
98
133
|
cursor: text;
|
|
@@ -41,6 +41,16 @@ export interface CopyButtonProps {
|
|
|
41
41
|
size?: ButtonSize | undefined;
|
|
42
42
|
variant?: ButtonVariant | undefined;
|
|
43
43
|
title?: string | undefined;
|
|
44
|
+
/** How long `copiedLabel` stands before the control offers its action again. */
|
|
45
|
+
resetMs?: number | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* How long `failedLabel` stands. Unset it is `resetMs`; `null` holds it
|
|
48
|
+
* until the next press. See [ClipboardOptions.failedResetMs] for why a
|
|
49
|
+
* refusal wants a clock of its own — and note the cost of `null`, which is
|
|
50
|
+
* that the control's accessible name stays "Copy failed" and so names a
|
|
51
|
+
* status rather than the action it still performs.
|
|
52
|
+
*/
|
|
53
|
+
failedResetMs?: number | null | undefined;
|
|
44
54
|
className?: string | undefined;
|
|
45
55
|
}
|
|
46
56
|
/**
|
|
@@ -51,4 +61,4 @@ export interface CopyButtonProps {
|
|
|
51
61
|
* sighted reader gets and the status region is the only evidence anybody else
|
|
52
62
|
* gets. Both are part of the control, not decoration on it.
|
|
53
63
|
*/
|
|
54
|
-
export declare function CopyButton({ text, label, copiedLabel, failedLabel, copiedMessage, failedMessage, size, variant, title, className, }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
export declare function CopyButton({ text, label, copiedLabel, failedLabel, copiedMessage, failedMessage, size, variant, title, resetMs, failedResetMs, className, }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,6 +16,14 @@ export interface CopyableProps {
|
|
|
16
16
|
copiedMessage?: string | undefined;
|
|
17
17
|
/** Read out on failure. */
|
|
18
18
|
failedMessage?: string | undefined;
|
|
19
|
+
/** How long the tick stands before the control settles back. */
|
|
20
|
+
resetMs?: number | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* How long the refusal glyph stands. Unset it is `resetMs`; `null` holds it
|
|
23
|
+
* until the next press. See [ClipboardOptions.failedResetMs] for why a
|
|
24
|
+
* refusal wants a clock of its own.
|
|
25
|
+
*/
|
|
26
|
+
failedResetMs?: number | null | undefined;
|
|
19
27
|
className?: string | undefined;
|
|
20
28
|
}
|
|
21
29
|
/**
|
|
@@ -31,4 +39,4 @@ export interface CopyableProps {
|
|
|
31
39
|
* plain http origin anybody reads a remote dashboard at, the tick appeared and
|
|
32
40
|
* the clipboard was empty.
|
|
33
41
|
*/
|
|
34
|
-
export declare const Copyable: ({ value, display, variant, monospace, truncate, truncateLength, ariaLabel, title, copiedMessage, failedMessage, className, }: CopyableProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
42
|
+
export declare const Copyable: ({ value, display, variant, monospace, truncate, truncateLength, ariaLabel, title, copiedMessage, failedMessage, resetMs, failedResetMs, className, }: CopyableProps) => import("react/jsx-runtime").JSX.Element | null;
|
package/dist/Copyable/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { CopyButton, Copyable } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { CopyButton, Copyable } from '../chunk-3QRYCPXQ.js';
|
|
2
|
+
import '../chunk-5VNUYO76.js';
|
|
3
3
|
import '../chunk-F27EPQ7D.js';
|
|
4
4
|
import '../chunk-BZYDZBAN.js';
|
|
5
5
|
import '../chunk-BZFWDIV6.js';
|
package/dist/DataTable/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-
|
|
1
|
+
export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-WQX73TWF.js';
|
|
2
2
|
import '../chunk-FBZAKNSX.js';
|
|
3
3
|
import '../chunk-EUCC37WY.js';
|
|
4
4
|
import '../chunk-2EOKFKHX.js';
|
|
5
5
|
import '../chunk-AV2DXAEL.js';
|
|
6
6
|
import '../chunk-2PRH365R.js';
|
|
7
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-5VNUYO76.js';
|
|
8
8
|
import '../chunk-PQADV6P6.js';
|
|
9
9
|
import '../chunk-7RPGY3JE.js';
|
|
10
10
|
import '../chunk-ITHXJHBB.js';
|
package/dist/DataView/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { DATA_VIEW_TOOLBAR_LABELS, DataView, DataViewToolbar, FILTER_AXIS_LABELS, FilterAxisBar, FilterAxisChip, applyColumnFilters, applyFilters, blankFilterValue, defaultOperator, filterDefsFromColumns, filterHasValue, filterPredicate, formatFilterValue, operatorOf, tableColumns } from '../chunk-
|
|
1
|
+
export { DATA_VIEW_TOOLBAR_LABELS, DataView, DataViewToolbar, FILTER_AXIS_LABELS, FilterAxisBar, FilterAxisChip, applyColumnFilters, applyFilters, blankFilterValue, defaultOperator, filterDefsFromColumns, filterHasValue, filterPredicate, formatFilterValue, operatorOf, tableColumns } from '../chunk-34VGEDVV.js';
|
|
2
2
|
import '../chunk-5EKIWVOR.js';
|
|
3
3
|
import '../chunk-HOXGBLEY.js';
|
|
4
4
|
import '../chunk-3CZ7XAVY.js';
|
|
5
5
|
import '../chunk-SFZOKW2G.js';
|
|
6
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-WQX73TWF.js';
|
|
7
7
|
import '../chunk-FBZAKNSX.js';
|
|
8
8
|
import '../chunk-EUCC37WY.js';
|
|
9
9
|
import '../chunk-2EOKFKHX.js';
|
|
@@ -12,7 +12,7 @@ import '../chunk-DD5BBGBE.js';
|
|
|
12
12
|
import '../chunk-GXQ3B46I.js';
|
|
13
13
|
import '../chunk-AV2DXAEL.js';
|
|
14
14
|
import '../chunk-2PRH365R.js';
|
|
15
|
-
import '../chunk-
|
|
15
|
+
import '../chunk-5VNUYO76.js';
|
|
16
16
|
import '../chunk-GTOUGQQK.js';
|
|
17
17
|
import '../chunk-O6232G37.js';
|
|
18
18
|
import '../chunk-BHHIIK3M.js';
|
|
@@ -9,6 +9,23 @@ import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
|
9
9
|
* at, so this is a prop rather than a styling flag.
|
|
10
10
|
*/
|
|
11
11
|
export type FilterChipSemantics = 'toggle' | 'radio';
|
|
12
|
+
/**
|
|
13
|
+
* Whether an arrow key APPLIES the filter it lands on, or only moves to it.
|
|
14
|
+
*
|
|
15
|
+
* `automatic` is the platform's own radio group and the default: the choice
|
|
16
|
+
* changes as focus moves, which costs nothing where the choice costs nothing.
|
|
17
|
+
*
|
|
18
|
+
* `manual` moves focus alone, and Enter or Space applies — which a real
|
|
19
|
+
* button already turns into its own click. A filter row is the one place that
|
|
20
|
+
* is routinely wrong: a chip row that drives a URL parameter re-runs the
|
|
21
|
+
* screen's query on every change, so arrowing across five chips under
|
|
22
|
+
* `automatic` fires five queries nobody asked for and redraws the list under
|
|
23
|
+
* the reader four times on the way past.
|
|
24
|
+
*
|
|
25
|
+
* It says nothing about a `toggle` row, which has no arrow keys to qualify:
|
|
26
|
+
* every chip there is its own tab stop and its own switch.
|
|
27
|
+
*/
|
|
28
|
+
export type FilterChipActivation = 'automatic' | 'manual';
|
|
12
29
|
/** The attribute the group finds its own chips by, without a registry to keep. */
|
|
13
30
|
export declare const FILTER_CHIP_ATTRIBUTE = "data-crewlet-filter-chip";
|
|
14
31
|
export interface FilterChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'value' | 'onChange'> {
|
|
@@ -43,6 +60,15 @@ export interface FilterChipGroupProps {
|
|
|
43
60
|
*/
|
|
44
61
|
label: string;
|
|
45
62
|
semantics?: FilterChipSemantics | undefined;
|
|
63
|
+
/** Whether the arrows apply the filter they land on. Radio rows only. */
|
|
64
|
+
activate?: FilterChipActivation | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* The sentence a manual row is described by, or `null` for none where the
|
|
67
|
+
* screen already says it elsewhere. Defaults to naming the key that
|
|
68
|
+
* applies, because a radio group that does not select as it moves is the
|
|
69
|
+
* unusual one and nothing else on the row says so.
|
|
70
|
+
*/
|
|
71
|
+
activateHint?: string | null | undefined;
|
|
46
72
|
/** The chosen value in radio mode. `null` is a deliberate none. */
|
|
47
73
|
value?: string | null | undefined;
|
|
48
74
|
onValueChange?: ((value: string | null) => void) | undefined;
|
|
@@ -60,9 +86,15 @@ export interface FilterChipGroupProps {
|
|
|
60
86
|
/**
|
|
61
87
|
* A named row of filters.
|
|
62
88
|
*
|
|
63
|
-
* In radio mode the arrows move AND choose, which is what the
|
|
64
|
-
* radio group does: a reader arrowing through a set of choices
|
|
65
|
-
* and a group where focus and selection come apart makes them
|
|
66
|
-
* after every move for a reason they could not name.
|
|
89
|
+
* In radio mode the arrows move AND choose by default, which is what the
|
|
90
|
+
* platform's own radio group does: a reader arrowing through a set of choices
|
|
91
|
+
* is choosing, and a group where focus and selection come apart makes them
|
|
92
|
+
* press Space after every move for a reason they could not name.
|
|
93
|
+
*
|
|
94
|
+
* `activate="manual"` is where the reason CAN be named: a row driving a URL
|
|
95
|
+
* parameter runs the screen's query again on every change, and there the
|
|
96
|
+
* moves a reader makes on the way to the chip they want are queries nobody
|
|
97
|
+
* asked for. Then the row says which key applies, because a radio group that
|
|
98
|
+
* does not select as it moves is the unusual one.
|
|
67
99
|
*/
|
|
68
|
-
export declare function FilterChipGroup({ label, semantics, value, onValueChange, allowNone, hideLabel, className, children, }: FilterChipGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
100
|
+
export declare function FilterChipGroup({ label, semantics, activate, activateHint, value, onValueChange, allowNone, hideLabel, className, children, }: FilterChipGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './FilterChip.css';
|
|
2
2
|
export { FILTER_CHIP_ATTRIBUTE, FilterChip, FilterChipGroup } from './FilterChip.js';
|
|
3
|
-
export type { FilterChipGroupProps, FilterChipProps, FilterChipSemantics } from './FilterChip.js';
|
|
3
|
+
export type { FilterChipActivation, FilterChipGroupProps, FilterChipProps, FilterChipSemantics, } from './FilterChip.js';
|
package/dist/FilterChip/index.js
CHANGED
package/dist/Meter/Meter.d.ts
CHANGED
|
@@ -8,8 +8,31 @@ import { type HTMLAttributes, type ReactNode } from 'react';
|
|
|
8
8
|
* so without every call site remembering to.
|
|
9
9
|
*/
|
|
10
10
|
export type MeterTone = 'brand' | 'success' | 'warning' | 'danger' | 'neutral';
|
|
11
|
+
/**
|
|
12
|
+
* WHICH DIRECTION A FULL BAR POINTS, which is the one thing the fill itself
|
|
13
|
+
* cannot say. A budget at 100 percent is a fault; a goal at 100 percent is the
|
|
14
|
+
* whole point of the goal. The same arithmetic, the opposite conclusion — so
|
|
15
|
+
* the polarity is a property of what is being measured and belongs to the call
|
|
16
|
+
* site, not to the ramp.
|
|
17
|
+
*
|
|
18
|
+
* `spent` is the default and is what every existing caller already gets.
|
|
19
|
+
*
|
|
20
|
+
* IT MOVES THE TONE RAMP AND NOTHING ELSE — in particular it does not reach
|
|
21
|
+
* for `role="progressbar"`. That role is for an operation the application is
|
|
22
|
+
* running while the user waits on it, which is why the meter role says authors
|
|
23
|
+
* "SHOULD NOT use the meter role to indicate progress". A goal that is eight
|
|
24
|
+
* tenths achieved is not an operation anybody is waiting on; it is a scalar
|
|
25
|
+
* measurement within a known range, which is a meter. A file upload is the
|
|
26
|
+
* other thing, and it is not this component.
|
|
27
|
+
*/
|
|
28
|
+
export type MeterPolarity = 'spent' | 'progress';
|
|
11
29
|
export interface MeterProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
12
30
|
value: number;
|
|
31
|
+
/**
|
|
32
|
+
* The ceiling. NON-POSITIVE MEANS THERE IS NO CEILING, and the bar is then
|
|
33
|
+
* drawn as decoration rather than as a reading — see the note on the
|
|
34
|
+
* component.
|
|
35
|
+
*/
|
|
13
36
|
max: number;
|
|
14
37
|
/**
|
|
15
38
|
* What is being measured. REQUIRED, and LINKED to the bar: the meter this
|
|
@@ -28,6 +51,12 @@ export interface MeterProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'
|
|
|
28
51
|
hint?: ReactNode;
|
|
29
52
|
/** Overrides the tone derived from the fill. */
|
|
30
53
|
tone?: MeterTone | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Which ramp the derived tone comes from. `spent` (the default) reads a full
|
|
56
|
+
* bar as a fault; `progress` reads it as an achievement. Ignored when `tone`
|
|
57
|
+
* is given, which overrides the ramp entirely.
|
|
58
|
+
*/
|
|
59
|
+
polarity?: MeterPolarity | undefined;
|
|
31
60
|
/**
|
|
32
61
|
* `compact` is the bar inside a table cell. Its legend drops a type step;
|
|
33
62
|
* the track does not, because the track is already the engine's 4px and
|
|
@@ -37,13 +66,61 @@ export interface MeterProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'
|
|
|
37
66
|
/** Keep the label out of the picture. It stays in the accessibility tree. */
|
|
38
67
|
hideLabel?: boolean | undefined;
|
|
39
68
|
}
|
|
40
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* The `spent` ramp: at the top it is a fault, near the top it wants a person,
|
|
71
|
+
* below that it is just a number.
|
|
72
|
+
*
|
|
73
|
+
* Keeps its plain name because renaming an export is breaking, and it is still
|
|
74
|
+
* the ramp a `Meter` uses when nobody says otherwise.
|
|
75
|
+
*/
|
|
41
76
|
export declare function meterTone(percent: number): MeterTone;
|
|
77
|
+
/**
|
|
78
|
+
* The `progress` ramp: finished is finished, and everything short of it is
|
|
79
|
+
* just a number.
|
|
80
|
+
*
|
|
81
|
+
* TWO STEPS RATHER THAN THREE, deliberately. The spent ramp has a middle step
|
|
82
|
+
* because a budget carries two escalating facts a reader has to act on — near
|
|
83
|
+
* the limit somebody should look, past it something is already wrong. A goal
|
|
84
|
+
* carries one: it is done or it is not. "Nearly done" is not a warning and
|
|
85
|
+
* "barely started" is only a fault against a DEADLINE, which is not one of
|
|
86
|
+
* this component's inputs — so a middle step here would be an alarm invented
|
|
87
|
+
* out of a number the meter cannot interpret.
|
|
88
|
+
*/
|
|
89
|
+
export declare function progressTone(percent: number): MeterTone;
|
|
42
90
|
/**
|
|
43
91
|
* A budget, a share, a fill.
|
|
44
92
|
*
|
|
45
93
|
* THE TRACK IS ALWAYS DRAWN. A bar with no track is a bar whose maximum the
|
|
46
94
|
* reader has to guess, and at 8 percent it is indistinguishable from a bar
|
|
47
95
|
* that is simply short.
|
|
96
|
+
*
|
|
97
|
+
* A NON-POSITIVE MAXIMUM IS NOT A METER, because ARIA gives the meter role no
|
|
98
|
+
* way at all to say "there is no ceiling" and both attempts are a false claim.
|
|
99
|
+
* `max={0}` renders `aria-valuemax="0"` against an `aria-valuemin` of 0: a
|
|
100
|
+
* range of zero width, in which the fraction a reader is offered is 0/0 and
|
|
101
|
+
* every value but 0 breaks the role's own "the value of aria-valuenow MUST NOT
|
|
102
|
+
* fall below or exceed the computed values of aria-valuemin and aria-valuemax"
|
|
103
|
+
* — and a negative maximum additionally breaks "authors MUST ensure the value
|
|
104
|
+
* of aria-valuemax is greater than or equal to the value of aria-valuemin".
|
|
105
|
+
* Leaving the attribute off instead is WORSE rather than better, because
|
|
106
|
+
* missing is precisely when the role's implicit value takes over — "if
|
|
107
|
+
* aria-valuemax is missing or not a number, it defaults to 100" — so the bar
|
|
108
|
+
* stops saying nothing and starts announcing a confident fraction of a ceiling
|
|
109
|
+
* that nobody set.
|
|
110
|
+
*
|
|
111
|
+
* So the only honest move is to stop being a meter. The bar drops the role and
|
|
112
|
+
* every value attribute and is hidden from the accessibility tree as the
|
|
113
|
+
* decoration it is; the legend still names it and still carries the figure.
|
|
114
|
+
* (`DataTable`'s column resizer reaches the same conclusion from the same
|
|
115
|
+
* place: a maximum invented to fill the attribute is a number a reader is told
|
|
116
|
+
* they cannot pass.)
|
|
117
|
+
*
|
|
118
|
+
* THE REPORTED VALUE IS CLAMPED INTO THE SCALE. A budget lowered under a
|
|
119
|
+
* counter that has already passed it is an ordinary event, and it used to
|
|
120
|
+
* publish `aria-valuenow` outside `[min,max]` — the same normative MUST NOT as
|
|
121
|
+
* above, which assistive technology is therefore free to resolve however it
|
|
122
|
+
* likes. The clamp makes the pair valid and `aria-valuetext` keeps the true
|
|
123
|
+
* figures, so nothing is lost: what a reader hears is "140 of 100", not a bar
|
|
124
|
+
* that quietly rounds itself down to exactly the limit it has overrun.
|
|
48
125
|
*/
|
|
49
|
-
export declare function Meter({ value, max, label, valueText, hint, tone, size, hideLabel, className, ...rest }: MeterProps): import("react/jsx-runtime").JSX.Element;
|
|
126
|
+
export declare function Meter({ value, max, label, valueText, hint, tone, polarity, size, hideLabel, className, ...rest }: MeterProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Meter/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './Meter.css';
|
|
2
|
-
export { Meter, meterTone } from './Meter.js';
|
|
3
|
-
export type { MeterProps, MeterTone } from './Meter.js';
|
|
2
|
+
export { Meter, meterTone, progressTone } from './Meter.js';
|
|
3
|
+
export type { MeterPolarity, MeterProps, MeterTone } from './Meter.js';
|
package/dist/Meter/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
2
|
export type SegmentedSize = 'sm' | 'md';
|
|
3
3
|
export interface SegmentedOption<T extends string = string> {
|
|
4
4
|
value: T;
|
|
@@ -35,7 +35,8 @@ interface SegmentedShared<T extends string> {
|
|
|
35
35
|
* `radio` is a SETTING or a filter (the theme, the density, a lens with no
|
|
36
36
|
* panel): announced as a radio group, and the arrows select as they move,
|
|
37
37
|
* because a choice that is not in the URL costs nothing to change on every
|
|
38
|
-
* keypress.
|
|
38
|
+
* keypress. A choice that IS in the URL costs a query per keypress, and
|
|
39
|
+
* `activate` is where that row says so (see [SegmentedActivation]).
|
|
39
40
|
*
|
|
40
41
|
* `tabs` is a row of SECTIONS, and in this product a section pushes a history
|
|
41
42
|
* entry: the arrows move focus and Enter or Space selects, so walking the row
|
|
@@ -45,10 +46,42 @@ interface SegmentedShared<T extends string> {
|
|
|
45
46
|
type SegmentedSemantics = {
|
|
46
47
|
semantics: 'tabs';
|
|
47
48
|
panelId: string;
|
|
49
|
+
activate?: undefined;
|
|
50
|
+
activateHint?: undefined;
|
|
48
51
|
} | {
|
|
49
52
|
semantics: 'radio';
|
|
50
53
|
panelId?: undefined;
|
|
54
|
+
/** Whether the arrows choose the option they land on. Radio rows only. */
|
|
55
|
+
activate?: SegmentedActivation | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* The sentence a manual row is described by, or `null` for none where
|
|
58
|
+
* the screen already says it elsewhere. Defaults to naming the key that
|
|
59
|
+
* chooses, because a radio group that does not select as it moves is the
|
|
60
|
+
* unusual one and nothing else on the row says so.
|
|
61
|
+
*/
|
|
62
|
+
activateHint?: string | null | undefined;
|
|
51
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Whether an arrow key CHOOSES the option it lands on, or only moves to it.
|
|
66
|
+
*
|
|
67
|
+
* `automatic` is the platform's own radio group and the default: the choice
|
|
68
|
+
* changes as focus moves, which costs nothing where the choice costs nothing.
|
|
69
|
+
*
|
|
70
|
+
* `manual` moves focus alone, and Enter or Space chooses — which a real
|
|
71
|
+
* button already turns into its own click. It is for the row whose choice is
|
|
72
|
+
* NOT free: a single-choice filter that drives a URL parameter re-runs the
|
|
73
|
+
* screen's query on every change, so arrowing across five options under
|
|
74
|
+
* `automatic` fires five queries nobody asked for and re-renders the screen
|
|
75
|
+
* under the reader four times on the way past. Those rows are not tabs
|
|
76
|
+
* either — they open no panel and `semantics="tabs"` would have a screen
|
|
77
|
+
* reader hunting for one — so the choice between the two semantics was never
|
|
78
|
+
* the choice this answers.
|
|
79
|
+
*
|
|
80
|
+
* It is offered on a radio row only. A `tabs` row is manual already, for the
|
|
81
|
+
* history entry its own doc describes, and an automatic one would be that
|
|
82
|
+
* bug on request.
|
|
83
|
+
*/
|
|
84
|
+
export type SegmentedActivation = 'automatic' | 'manual';
|
|
52
85
|
export type SegmentedControlProps<T extends string = string> = SegmentedShared<T> & SegmentedSemantics;
|
|
53
86
|
/**
|
|
54
87
|
* A row of mutually exclusive choices.
|
|
@@ -64,5 +97,5 @@ export type SegmentedControlProps<T extends string = string> = SegmentedShared<T
|
|
|
64
97
|
* look like two different controls depending on which component a screen
|
|
65
98
|
* reached for.
|
|
66
99
|
*/
|
|
67
|
-
export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, className, semantics, panelId, }: SegmentedControlProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
100
|
+
export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, className, semantics, panelId, activate, activateHint, }: SegmentedControlProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
68
101
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '../Tabs/Tabs.css';
|
|
2
2
|
import './SegmentedControl.css';
|
|
3
3
|
export { SegmentedControl } from './SegmentedControl.js';
|
|
4
|
-
export type { SegmentedControlProps, SegmentedOption, SegmentedSize } from './SegmentedControl.js';
|
|
4
|
+
export type { SegmentedActivation, SegmentedControlProps, SegmentedOption, SegmentedSize, } from './SegmentedControl.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { SegmentedControl } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { SegmentedControl } from '../chunk-6ZFVFA56.js';
|
|
2
|
+
import '../chunk-QEUY3A5P.js';
|
|
3
3
|
import '../chunk-BHHIIK3M.js';
|
|
4
4
|
import '../chunk-BZFWDIV6.js';
|
|
5
5
|
import '../chunk-ODEQTPFM.js';
|