@scalewing/react 1.44.0 → 1.46.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 +21 -0
- package/README.md +51 -2
- package/dist/components/Article.d.ts +19 -2
- package/dist/components/Article.js +9 -5
- package/dist/components/Button.d.ts +14 -1
- package/dist/components/Button.js +5 -2
- package/dist/components/FileField.d.ts +18 -2
- package/dist/components/FileField.js +26 -22
- package/dist/components/ListGroup.d.ts +8 -3
- package/dist/components/ListGroup.js +13 -5
- package/dist/components/ListRow.d.ts +11 -3
- package/dist/components/ListRow.js +6 -4
- package/dist/components/Select.d.ts +8 -5
- package/dist/components/Select.js +7 -4
- package/dist/components/file-field/ChosenFile.d.ts +45 -0
- package/dist/components/file-field/ChosenFile.js +48 -0
- package/dist/components/file-field/file-field-checks.d.ts +5 -2
- package/dist/components/file-field/file-field-checks.js +7 -2
- package/dist/components/list/ListRowContent.d.ts +5 -1
- package/dist/components/list/ListRowContent.js +4 -2
- package/dist/components/select/select-naming.d.ts +34 -0
- package/dist/components/select/select-naming.js +22 -0
- package/dist/components/steps/Step.d.ts +10 -1
- package/dist/components/steps/Step.js +15 -19
- package/dist/components/steps/StepTitleLine.d.ts +19 -0
- package/dist/components/steps/StepTitleLine.js +13 -0
- package/dist/components/steps/StepTitleWords.d.ts +27 -0
- package/dist/components/steps/StepTitleWords.js +21 -0
- package/dist/components/steps/assert-step.d.ts +7 -0
- package/dist/components/steps/assert-step.js +19 -0
- package/dist/css/css-button-width.d.ts +11 -0
- package/dist/css/css-button-width.js +36 -0
- package/dist/css/css-button.js +3 -0
- package/dist/css/css-file-field-compact.d.ts +2 -0
- package/dist/css/css-file-field-compact.js +106 -0
- package/dist/css/css-file-field.js +4 -0
- package/dist/css/css-list-tiles.d.ts +6 -0
- package/dist/css/css-list-tiles.js +50 -0
- package/dist/css/css-list.js +5 -1
- package/dist/css/css-steps-title-detail.d.ts +2 -0
- package/dist/css/css-steps-title-detail.js +36 -0
- package/dist/css/css-steps.d.ts +2 -2
- package/dist/css/css-steps.js +6 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/list-options.d.ts +19 -11
- package/dist/list-options.js +27 -11
- package/dist/styles.css +134 -0
- package/package.json +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { touchTarget } from './touch-target.js';
|
|
3
|
+
const body = typographyVariants.body;
|
|
4
|
+
/*
|
|
5
|
+
* Remove beside a chosen file in the full field: the change button and
|
|
6
|
+
* Remove together at the row's end, a space-2 apart.
|
|
7
|
+
*/
|
|
8
|
+
function actionsRules() {
|
|
9
|
+
return `.sw-file-field-actions {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex: none;
|
|
12
|
+
flex-wrap: wrap;
|
|
13
|
+
gap: var(--sw-space-2);
|
|
14
|
+
margin-inline-start: auto;
|
|
15
|
+
}`;
|
|
16
|
+
}
|
|
17
|
+
/*
|
|
18
|
+
* A compact field is a text field's height (the md control, 44 px), on
|
|
19
|
+
* one line. Empty, its zone holds the choose words at its start. Chosen,
|
|
20
|
+
* the row is the change button (the thumbnail or mark a space-1 from the
|
|
21
|
+
* frame's start, then the name in the body weight cut to one line) and a
|
|
22
|
+
* quiet Remove at its end. The button's focus ring sits inside the frame.
|
|
23
|
+
*/
|
|
24
|
+
function compactRules() {
|
|
25
|
+
return `.sw-file-field-compact.sw-file-field-chosen {
|
|
26
|
+
flex-wrap: nowrap;
|
|
27
|
+
gap: var(--sw-space-1);
|
|
28
|
+
min-height: ${touchTarget};
|
|
29
|
+
padding-block: 0;
|
|
30
|
+
padding-inline: 0 var(--sw-space-1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.sw-file-field-compact .sw-file-field-zone {
|
|
34
|
+
justify-content: flex-start;
|
|
35
|
+
padding: var(--sw-space-2) var(--sw-space-4);
|
|
36
|
+
text-align: start;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.sw-file-field-pick {
|
|
40
|
+
align-items: center;
|
|
41
|
+
appearance: none;
|
|
42
|
+
background: transparent;
|
|
43
|
+
border: 0;
|
|
44
|
+
border-radius: inherit;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
color: var(--sw-color-text);
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
display: flex;
|
|
49
|
+
flex: 1 1 auto;
|
|
50
|
+
font-family: var(--sw-font-sans);
|
|
51
|
+
gap: var(--sw-space-3);
|
|
52
|
+
margin: 0;
|
|
53
|
+
min-height: ${touchTarget};
|
|
54
|
+
min-width: 0;
|
|
55
|
+
padding-block: var(--sw-space-1);
|
|
56
|
+
padding-inline: var(--sw-space-1) var(--sw-space-2);
|
|
57
|
+
text-align: start;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sw-file-field-pick:focus { outline: none; }
|
|
61
|
+
|
|
62
|
+
.sw-file-field-pick:focus-visible {
|
|
63
|
+
outline: var(--sw-focus-ring-width) solid var(--sw-color-accent);
|
|
64
|
+
outline-offset: calc(-1 * var(--sw-focus-ring-width));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.sw-file-field-pick:disabled { cursor: not-allowed; }
|
|
68
|
+
|
|
69
|
+
.sw-file-field-pick .sw-file-field-name {
|
|
70
|
+
font-weight: ${body.fontWeight};
|
|
71
|
+
min-width: 0;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
overflow-wrap: normal;
|
|
74
|
+
text-overflow: ellipsis;
|
|
75
|
+
white-space: nowrap;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* With no thumbnail or mark, the name starts where a text field's words do. */
|
|
79
|
+
.sw-file-field-pick > .sw-file-field-name:first-child { margin-inline-start: var(--sw-space-3); }
|
|
80
|
+
|
|
81
|
+
.sw-file-field-compact .sw-file-field-preview,
|
|
82
|
+
.sw-file-field-compact .sw-file-field-icon { margin-inline-start: var(--sw-space-1); }
|
|
83
|
+
|
|
84
|
+
.sw-file-field-remove { flex: none; }
|
|
85
|
+
|
|
86
|
+
@media (forced-colors: active) {
|
|
87
|
+
.sw-file-field-pick { color: ButtonText; }
|
|
88
|
+
.sw-file-field-pick:disabled { color: GrayText; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Disabled, the row fades as its Remove does. */
|
|
92
|
+
.sw-file-field-pick:disabled { opacity: var(--sw-disabled-opacity); }`;
|
|
93
|
+
}
|
|
94
|
+
export function cssFileFieldCompactClasses() {
|
|
95
|
+
return `${actionsRules()}
|
|
96
|
+
|
|
97
|
+
${compactRules()}`;
|
|
98
|
+
}
|
|
99
|
+
export function fileFieldCompactClassCatalog() {
|
|
100
|
+
return [
|
|
101
|
+
'sw-file-field-actions',
|
|
102
|
+
'sw-file-field-compact',
|
|
103
|
+
'sw-file-field-pick',
|
|
104
|
+
'sw-file-field-remove',
|
|
105
|
+
];
|
|
106
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { typographyVariants } from '@scalewing/tokens';
|
|
2
2
|
import { disabledControlSurface } from './css-document.js';
|
|
3
|
+
import { cssFileFieldCompactClasses, fileFieldCompactClassCatalog, } from './css-file-field-compact.js';
|
|
3
4
|
import { coarsePointerQuery, touchTarget } from './touch-target.js';
|
|
4
5
|
const label = typographyVariants.label;
|
|
5
6
|
const caption = typographyVariants.caption;
|
|
@@ -172,6 +173,8 @@ ${zoneRules()}
|
|
|
172
173
|
|
|
173
174
|
${fileRules()}
|
|
174
175
|
|
|
176
|
+
${cssFileFieldCompactClasses()}
|
|
177
|
+
|
|
175
178
|
${forcedColorRules()}`;
|
|
176
179
|
}
|
|
177
180
|
export function fileFieldClassCatalog() {
|
|
@@ -190,5 +193,6 @@ export function fileFieldClassCatalog() {
|
|
|
190
193
|
'sw-file-field-file',
|
|
191
194
|
'sw-file-field-name',
|
|
192
195
|
'sw-file-field-detail',
|
|
196
|
+
...fileFieldCompactClassCatalog(),
|
|
193
197
|
];
|
|
194
198
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** How many tiles share a row from `md` up; one a row below it. */
|
|
2
|
+
export declare const listTileColumnCounts: readonly [2, 3, 4];
|
|
3
|
+
export type ListGroupTileColumns = (typeof listTileColumnCounts)[number];
|
|
4
|
+
export declare function listTileColumnsClass(columns: ListGroupTileColumns): string;
|
|
5
|
+
export declare function cssListTilesClasses(): string;
|
|
6
|
+
export declare function listTilesClassCatalog(): string[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { breakpointQuery } from './breakpoints.js';
|
|
2
|
+
/** How many tiles share a row from `md` up; one a row below it. */
|
|
3
|
+
export const listTileColumnCounts = [2, 3, 4];
|
|
4
|
+
export function listTileColumnsClass(columns) {
|
|
5
|
+
return `sw-list-group-tiles-${columns}`;
|
|
6
|
+
}
|
|
7
|
+
const tiles = '.sw-list-group-tiles';
|
|
8
|
+
/*
|
|
9
|
+
* A tiled ListGroup is still one list (`sw-list`), its rows laid out as
|
|
10
|
+
* tiles: equal columns a space-3 apart from `md` up, one column below it,
|
|
11
|
+
* each row its own bordered panel on the surface (the panel variant's
|
|
12
|
+
* look, per row), with no hairlines between them. A row's press fill and
|
|
13
|
+
* its inset focus ring stay inside its tile.
|
|
14
|
+
*
|
|
15
|
+
* Generated after the list's hairline rules (css-list.ts), whose
|
|
16
|
+
* `.sw-list > .sw-list-item + .sw-list-item` has the same specificity as
|
|
17
|
+
* the tile rule: being later is what lets a tile's own border replace the
|
|
18
|
+
* hairline. `list-group-tiles.test.tsx` holds that order.
|
|
19
|
+
*/
|
|
20
|
+
export function cssListTilesClasses() {
|
|
21
|
+
const columns = listTileColumnCounts.map((count) => `.${listTileColumnsClass(count)} > .sw-list { grid-template-columns: repeat(${count}, minmax(0, 1fr)); }`);
|
|
22
|
+
return `${tiles} > .sw-list {
|
|
23
|
+
display: grid;
|
|
24
|
+
gap: var(--sw-space-3);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
${columns.join('\n')}
|
|
28
|
+
|
|
29
|
+
${tiles} > .sw-list > .sw-list-item {
|
|
30
|
+
background: var(--sw-color-surface);
|
|
31
|
+
border: 1px solid var(--sw-color-border);
|
|
32
|
+
border-radius: var(--sw-radius-md);
|
|
33
|
+
min-width: 0;
|
|
34
|
+
overflow: clip;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media ${breakpointQuery('below', 'md')} {
|
|
38
|
+
${tiles} > .sw-list { grid-template-columns: minmax(0, 1fr); }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@media (forced-colors: active) {
|
|
42
|
+
${tiles} > .sw-list > .sw-list-item { border-color: CanvasText; }
|
|
43
|
+
}`;
|
|
44
|
+
}
|
|
45
|
+
export function listTilesClassCatalog() {
|
|
46
|
+
return [
|
|
47
|
+
'sw-list-group-tiles',
|
|
48
|
+
...listTileColumnCounts.map((count) => listTileColumnsClass(count)),
|
|
49
|
+
];
|
|
50
|
+
}
|
package/dist/css/css-list.js
CHANGED
|
@@ -2,6 +2,7 @@ import { typographyVariants } from '@scalewing/tokens';
|
|
|
2
2
|
import { cssListRowClasses, listRowClassCatalog } from './css-list-row.js';
|
|
3
3
|
import { cssListRowTrailingClasses, listRowTrailingClassCatalog, } from './css-list-row-trailing.js';
|
|
4
4
|
import { cssListRowTruncateClasses, listRowTruncateClassCatalog, } from './css-list-row-truncate.js';
|
|
5
|
+
import { cssListTilesClasses, listTilesClassCatalog, } from './css-list-tiles.js';
|
|
5
6
|
import { blockEdgeShadeRules, scrollRegionRules } from './css-scroll-region.js';
|
|
6
7
|
const label = typographyVariants.label;
|
|
7
8
|
const caption = typographyVariants.caption;
|
|
@@ -75,7 +76,9 @@ ${cssListRowClasses()}
|
|
|
75
76
|
|
|
76
77
|
${cssListRowTrailingClasses()}
|
|
77
78
|
|
|
78
|
-
${cssListRowTruncateClasses()}
|
|
79
|
+
${cssListRowTruncateClasses()}
|
|
80
|
+
|
|
81
|
+
${cssListTilesClasses()}`;
|
|
79
82
|
}
|
|
80
83
|
export function listClassCatalog() {
|
|
81
84
|
return [
|
|
@@ -86,6 +89,7 @@ export function listClassCatalog() {
|
|
|
86
89
|
'sw-list-group-plain',
|
|
87
90
|
'sw-list-group-scroll',
|
|
88
91
|
'sw-list-group-footer',
|
|
92
|
+
...listTilesClassCatalog(),
|
|
89
93
|
...listRowClassCatalog(),
|
|
90
94
|
...listRowTrailingClassCatalog(),
|
|
91
95
|
...listRowTruncateClassCatalog(),
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
const body = typographyVariants.body;
|
|
3
|
+
const label = typographyVariants.label;
|
|
4
|
+
/*
|
|
5
|
+
* An open step's muted words after its title ("Optional", "Wetlands done ·
|
|
6
|
+
* Woodlands empty"): the title and the words share one line that wraps, the
|
|
7
|
+
* words on the title's baseline a space-2 after it, or on a line of their
|
|
8
|
+
* own under the title when they do not fit beside it. The line gives way
|
|
9
|
+
* to a done step's summary and Edit in an open list, as the title does.
|
|
10
|
+
* The words are the label size at the body's weight in the muted colour,
|
|
11
|
+
* a skipped step's reason's colour beside its title; a long word breaks
|
|
12
|
+
* rather than pass the panel.
|
|
13
|
+
*/
|
|
14
|
+
export function cssStepsTitleDetailClasses() {
|
|
15
|
+
return `.sw-steps-title-line {
|
|
16
|
+
align-items: baseline;
|
|
17
|
+
column-gap: var(--sw-space-2);
|
|
18
|
+
display: flex;
|
|
19
|
+
flex: 0 1 auto;
|
|
20
|
+
flex-wrap: wrap;
|
|
21
|
+
min-width: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sw-steps-title-detail {
|
|
25
|
+
color: var(--sw-color-muted);
|
|
26
|
+
font-size: ${label.fontSize}px;
|
|
27
|
+
font-weight: ${body.fontWeight};
|
|
28
|
+
letter-spacing: ${label.letterSpacing}px;
|
|
29
|
+
line-height: ${label.lineHeight}px;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
overflow-wrap: anywhere;
|
|
32
|
+
}`;
|
|
33
|
+
}
|
|
34
|
+
export function stepsTitleDetailClassCatalog() {
|
|
35
|
+
return ['sw-steps-title-line', 'sw-steps-title-detail'];
|
|
36
|
+
}
|
package/dist/css/css-steps.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one-page vertical stepper: an ordered list of glass panels a small
|
|
3
|
-
* gap apart. Each has a header line (marker, title,
|
|
4
|
-
* summary and Edit) and, while open (current or error), a body indented to
|
|
3
|
+
* gap apart. Each has a header line (marker, title, an open step's muted
|
|
4
|
+
* words beside it, and on a done step its summary and Edit) and, while open (current or error), a body indented to
|
|
5
5
|
* the title. An open step's title is the title variant; a folded one's is
|
|
6
6
|
* body size at label weight, muted ahead of the form or skipped. In an
|
|
7
7
|
* open list (`sw-steps-open`) every step is open: each panel takes the open
|
package/dist/css/css-steps.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { typographyVariants } from '@scalewing/tokens';
|
|
2
2
|
import { checkStrokeIn } from './chevron.js';
|
|
3
|
+
import { cssStepsTitleDetailClasses, stepsTitleDetailClassCatalog, } from './css-steps-title-detail.js';
|
|
3
4
|
const body = typographyVariants.body;
|
|
4
5
|
const caption = typographyVariants.caption;
|
|
5
6
|
const label = typographyVariants.label;
|
|
@@ -69,8 +70,8 @@ function forcedColorRules() {
|
|
|
69
70
|
}
|
|
70
71
|
/**
|
|
71
72
|
* The one-page vertical stepper: an ordered list of glass panels a small
|
|
72
|
-
* gap apart. Each has a header line (marker, title,
|
|
73
|
-
* summary and Edit) and, while open (current or error), a body indented to
|
|
73
|
+
* gap apart. Each has a header line (marker, title, an open step's muted
|
|
74
|
+
* words beside it, and on a done step its summary and Edit) and, while open (current or error), a body indented to
|
|
74
75
|
* the title. An open step's title is the title variant; a folded one's is
|
|
75
76
|
* body size at label weight, muted ahead of the form or skipped. In an
|
|
76
77
|
* open list (`sw-steps-open`) every step is open: each panel takes the open
|
|
@@ -190,6 +191,8 @@ export function cssStepsClasses() {
|
|
|
190
191
|
min-width: 0;
|
|
191
192
|
}
|
|
192
193
|
|
|
194
|
+
${cssStepsTitleDetailClasses()}
|
|
195
|
+
|
|
193
196
|
${markerRules()}
|
|
194
197
|
|
|
195
198
|
${connectorRules()}
|
|
@@ -214,5 +217,6 @@ export function stepsClassCatalog() {
|
|
|
214
217
|
'sw-steps-edit',
|
|
215
218
|
'sw-steps-body',
|
|
216
219
|
'sw-steps-region',
|
|
220
|
+
...stepsTitleDetailClassCatalog(),
|
|
217
221
|
];
|
|
218
222
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { ListGroup, type ListGroupProps } from './components/ListGroup.js';
|
|
|
13
13
|
export { inspectMarkdown, markdownOmissionKinds, MarkdownView, type MarkdownHeading, type MarkdownInspection, type MarkdownImage, type MarkdownImageResolver, type MarkdownOmission, type MarkdownOmissionCounts, type MarkdownOmissionKind, type MarkdownOptions, type MarkdownViewProps, } from './components/MarkdownView.js';
|
|
14
14
|
export { ListRow, type ListRowProps } from './components/ListRow.js';
|
|
15
15
|
export { listGroupVariants, listRowTitleAppearances, listRowTones, listRowValueTones, type ListGroupMaxHeight, type ListGroupVariant, type ListRowTitleAppearance, type ListRowTone, type ListRowValueTone, } from './list-options.js';
|
|
16
|
+
export { listTileColumnCounts, type ListGroupTileColumns, } from './css/css-list-tiles.js';
|
|
16
17
|
export { Checkbox, type CheckboxProps } from './components/Checkbox.js';
|
|
17
18
|
export { Spinner, type SpinnerProps, type SpinnerSize, } from './components/Spinner.js';
|
|
18
19
|
export { GlyphTile, glyphTileSizes, type GlyphTileHue, type GlyphTileProps, type GlyphTileSize, } from './components/GlyphTile.js';
|
|
@@ -29,7 +30,8 @@ export { ColumnChart, type ColumnChartCallout, type ColumnChartLine, type Column
|
|
|
29
30
|
export { LineChart, type LineChartCurve, type LineChartMarker, type LineChartPeriod, type LineChartPoint, type LineChartProps, lineChartCurves, } from './components/LineChart.js';
|
|
30
31
|
export { DataBar, type DataBarProps, type DataBarTone, dataBarTones, } from './components/DataBar.js';
|
|
31
32
|
export { Pagination, type PaginationLabels, type PaginationProps, } from './components/Pagination.js';
|
|
32
|
-
export { Button, type ButtonDisabledAppearance, type ButtonProps, type ButtonSize, type ButtonVariant, } from './components/Button.js';
|
|
33
|
+
export { Button, type ButtonDisabledAppearance, type ButtonProps, type ButtonSize, type ButtonVariant, type ButtonWidth, } from './components/Button.js';
|
|
34
|
+
export { buttonWidths } from './css/css-button-width.js';
|
|
33
35
|
export { buttonDisabledAppearances, webButtonVariants, } from './css/css-button.js';
|
|
34
36
|
export { Box, type BoxBorder, type BoxElement, type BoxLink, type BoxProps, } from './components/Box.js';
|
|
35
37
|
export { boxLinkAppearances } from './css/css-box-link.js';
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { ListGroup } from './components/ListGroup.js';
|
|
|
12
12
|
export { inspectMarkdown, markdownOmissionKinds, MarkdownView, } from './components/MarkdownView.js';
|
|
13
13
|
export { ListRow } from './components/ListRow.js';
|
|
14
14
|
export { listGroupVariants, listRowTitleAppearances, listRowTones, listRowValueTones, } from './list-options.js';
|
|
15
|
+
export { listTileColumnCounts, } from './css/css-list-tiles.js';
|
|
15
16
|
export { Checkbox } from './components/Checkbox.js';
|
|
16
17
|
export { Spinner, } from './components/Spinner.js';
|
|
17
18
|
export { GlyphTile, glyphTileSizes, } from './components/GlyphTile.js';
|
|
@@ -29,6 +30,7 @@ export { LineChart, lineChartCurves, } from './components/LineChart.js';
|
|
|
29
30
|
export { DataBar, dataBarTones, } from './components/DataBar.js';
|
|
30
31
|
export { Pagination, } from './components/Pagination.js';
|
|
31
32
|
export { Button, } from './components/Button.js';
|
|
33
|
+
export { buttonWidths } from './css/css-button-width.js';
|
|
32
34
|
export { buttonDisabledAppearances, webButtonVariants, } from './css/css-button.js';
|
|
33
35
|
export { Box, } from './components/Box.js';
|
|
34
36
|
export { boxLinkAppearances } from './css/css-box-link.js';
|
package/dist/list-options.d.ts
CHANGED
|
@@ -4,9 +4,11 @@ import { listRowValueTones, type ListRowValueTone } from './css/css-list-row.js'
|
|
|
4
4
|
/**
|
|
5
5
|
* `panel` (the default) is one bordered panel on the surface; `plain`
|
|
6
6
|
* draws no panel and a hairline above the first row too, for rows inside
|
|
7
|
-
* a surface that already has one, such as a Card
|
|
7
|
+
* a surface that already has one, such as a Card; `tiles` lays the rows
|
|
8
|
+
* out as tiles, each its own panel, in equal columns (one a row below
|
|
9
|
+
* `md`).
|
|
8
10
|
*/
|
|
9
|
-
export declare const listGroupVariants: readonly ["panel", "plain"];
|
|
11
|
+
export declare const listGroupVariants: readonly ["panel", "plain", "tiles"];
|
|
10
12
|
export type ListGroupVariant = (typeof listGroupVariants)[number];
|
|
11
13
|
/**
|
|
12
14
|
* A list's bounded height, counted in rows: as tall as `rows` rows of a
|
|
@@ -30,17 +32,23 @@ export type ListGroupInput = {
|
|
|
30
32
|
labelledBy: string | undefined;
|
|
31
33
|
variant: unknown;
|
|
32
34
|
maxHeight: ListGroupMaxHeight | undefined;
|
|
35
|
+
tileColumns: unknown;
|
|
36
|
+
hasFooter: boolean;
|
|
33
37
|
};
|
|
34
38
|
/**
|
|
35
39
|
* Fails closed on a ListGroup it cannot draw: an unknown variant, a
|
|
36
|
-
* `maxHeight` that is not a whole row count from 1,
|
|
37
|
-
* no name (its scroll region is a keyboard stop and must say what it
|
|
40
|
+
* `maxHeight` that is not a whole row count from 1, a bounded list with
|
|
41
|
+
* no name (its scroll region is a keyboard stop and must say what it
|
|
42
|
+
* holds), `tileColumns` other than 2, 3 or 4 or on a list that is not
|
|
43
|
+
* tiles, or tiles with `maxHeight` or a `footer` (tiles neither scroll as
|
|
44
|
+
* rows nor add up to a total).
|
|
38
45
|
*/
|
|
39
|
-
export declare function assertListGroup({ label, labelledBy, variant, maxHeight, }: ListGroupInput): void;
|
|
46
|
+
export declare function assertListGroup({ label, labelledBy, variant, maxHeight, tileColumns, hasFooter, }: ListGroupInput): void;
|
|
40
47
|
/** The row count the generated `sw-list-group-scroll` height reads. */
|
|
41
48
|
export declare function listMaxHeightStyle(maxHeight: ListGroupMaxHeight): CSSProperties;
|
|
42
49
|
export type ListRowInput = {
|
|
43
50
|
title: string;
|
|
51
|
+
titleLang: string | undefined;
|
|
44
52
|
tone: unknown;
|
|
45
53
|
titleAppearance: unknown;
|
|
46
54
|
valueTone: unknown;
|
|
@@ -54,12 +62,12 @@ export type ListRowInput = {
|
|
|
54
62
|
unreadLabel: string | undefined;
|
|
55
63
|
};
|
|
56
64
|
/**
|
|
57
|
-
* Fails closed on a ListRow it cannot draw: an empty title or
|
|
58
|
-
* unknown tone, title appearance, value tone, badge tone or
|
|
59
|
-
* `valueDetail`, `valueTone` or `valueBadge` with no value, a
|
|
60
|
-
* toned and a badge, `selected` on a row that is not a button or
|
|
61
|
-
* (its check would be a state nothing can read), or an unread row with
|
|
62
|
-
* words for its dot (a colour alone says nothing).
|
|
65
|
+
* Fails closed on a ListRow it cannot draw: an empty title, titleLang or
|
|
66
|
+
* value, an unknown tone, title appearance, value tone, badge tone or
|
|
67
|
+
* accessory, a `valueDetail`, `valueTone` or `valueBadge` with no value, a
|
|
68
|
+
* value both toned and a badge, `selected` on a row that is not a button or
|
|
69
|
+
* link (its check would be a state nothing can read), or an unread row with
|
|
70
|
+
* no words for its dot (a colour alone says nothing).
|
|
63
71
|
*/
|
|
64
72
|
export declare function assertListRow(input: ListRowInput): void;
|
|
65
73
|
/**
|
package/dist/list-options.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { badgeTones } from './css/css-data.js';
|
|
2
2
|
import { listRowValueTones, } from './css/css-list-row.js';
|
|
3
|
+
import { listTileColumnCounts } from './css/css-list-tiles.js';
|
|
3
4
|
import { isOneOf } from './is-one-of.js';
|
|
4
5
|
/**
|
|
5
6
|
* `panel` (the default) is one bordered panel on the surface; `plain`
|
|
6
7
|
* draws no panel and a hairline above the first row too, for rows inside
|
|
7
|
-
* a surface that already has one, such as a Card
|
|
8
|
+
* a surface that already has one, such as a Card; `tiles` lays the rows
|
|
9
|
+
* out as tiles, each its own panel, in equal columns (one a row below
|
|
10
|
+
* `md`).
|
|
8
11
|
*/
|
|
9
|
-
export const listGroupVariants = ['panel', 'plain'];
|
|
12
|
+
export const listGroupVariants = ['panel', 'plain', 'tiles'];
|
|
10
13
|
/** `danger` draws the title in the danger colour, for a row that ends something. */
|
|
11
14
|
export const listRowTones = ['default', 'danger'];
|
|
12
15
|
/** `strong` (the default) sets the title at the label weight; `plain` at the body's. */
|
|
@@ -17,12 +20,23 @@ function isBlank(text) {
|
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* Fails closed on a ListGroup it cannot draw: an unknown variant, a
|
|
20
|
-
* `maxHeight` that is not a whole row count from 1,
|
|
21
|
-
* no name (its scroll region is a keyboard stop and must say what it
|
|
23
|
+
* `maxHeight` that is not a whole row count from 1, a bounded list with
|
|
24
|
+
* no name (its scroll region is a keyboard stop and must say what it
|
|
25
|
+
* holds), `tileColumns` other than 2, 3 or 4 or on a list that is not
|
|
26
|
+
* tiles, or tiles with `maxHeight` or a `footer` (tiles neither scroll as
|
|
27
|
+
* rows nor add up to a total).
|
|
22
28
|
*/
|
|
23
|
-
export function assertListGroup({ label, labelledBy, variant, maxHeight, }) {
|
|
29
|
+
export function assertListGroup({ label, labelledBy, variant, maxHeight, tileColumns, hasFooter, }) {
|
|
24
30
|
if (!isOneOf(listGroupVariants, variant))
|
|
25
31
|
throw new RangeError(`Unknown ListGroup variant: ${String(variant)}`);
|
|
32
|
+
if (tileColumns !== undefined) {
|
|
33
|
+
if (variant !== 'tiles')
|
|
34
|
+
throw new RangeError('ListGroup tileColumns needs variant="tiles"');
|
|
35
|
+
if (!listTileColumnCounts.includes(tileColumns))
|
|
36
|
+
throw new RangeError(`ListGroup tileColumns must be 2, 3 or 4: ${String(tileColumns)}`);
|
|
37
|
+
}
|
|
38
|
+
if (variant === 'tiles' && (maxHeight !== undefined || hasFooter))
|
|
39
|
+
throw new RangeError('A ListGroup of tiles takes no maxHeight or footer');
|
|
26
40
|
if (maxHeight === undefined)
|
|
27
41
|
return;
|
|
28
42
|
const rows = typeof maxHeight === 'object' && maxHeight !== null
|
|
@@ -38,16 +52,18 @@ export function listMaxHeightStyle(maxHeight) {
|
|
|
38
52
|
return { '--sw-list-max-rows': maxHeight.rows };
|
|
39
53
|
}
|
|
40
54
|
/**
|
|
41
|
-
* Fails closed on a ListRow it cannot draw: an empty title or
|
|
42
|
-
* unknown tone, title appearance, value tone, badge tone or
|
|
43
|
-
* `valueDetail`, `valueTone` or `valueBadge` with no value, a
|
|
44
|
-
* toned and a badge, `selected` on a row that is not a button or
|
|
45
|
-
* (its check would be a state nothing can read), or an unread row with
|
|
46
|
-
* words for its dot (a colour alone says nothing).
|
|
55
|
+
* Fails closed on a ListRow it cannot draw: an empty title, titleLang or
|
|
56
|
+
* value, an unknown tone, title appearance, value tone, badge tone or
|
|
57
|
+
* accessory, a `valueDetail`, `valueTone` or `valueBadge` with no value, a
|
|
58
|
+
* value both toned and a badge, `selected` on a row that is not a button or
|
|
59
|
+
* link (its check would be a state nothing can read), or an unread row with
|
|
60
|
+
* no words for its dot (a colour alone says nothing).
|
|
47
61
|
*/
|
|
48
62
|
export function assertListRow(input) {
|
|
49
63
|
if (isBlank(input.title))
|
|
50
64
|
throw new RangeError('ListRow title must be non-empty text');
|
|
65
|
+
if (input.titleLang !== undefined && isBlank(input.titleLang))
|
|
66
|
+
throw new RangeError('ListRow titleLang must be a non-empty language tag');
|
|
51
67
|
if (!isOneOf(listRowTones, input.tone))
|
|
52
68
|
throw new RangeError(`Unknown ListRow tone: ${String(input.tone)}`);
|
|
53
69
|
if (!isOneOf(listRowTitleAppearances, input.titleAppearance))
|
package/dist/styles.css
CHANGED
|
@@ -967,6 +967,19 @@ body {
|
|
|
967
967
|
.sw-button-xs { min-height: 28px; padding-inline: 10px; }
|
|
968
968
|
.sw-button-sm { min-height: 32px; padding-inline: 12px; }
|
|
969
969
|
.sw-button-md { min-height: 44px; padding-inline: 16px; }
|
|
970
|
+
.sw-button-full {
|
|
971
|
+
width: 100%;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
.sw-inline > .sw-button-full {
|
|
975
|
+
flex: 1 1 0;
|
|
976
|
+
min-width: 0;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.sw-inline.sw-wrap > .sw-button-full {
|
|
980
|
+
flex: 1 1 auto;
|
|
981
|
+
width: auto;
|
|
982
|
+
}
|
|
970
983
|
.sw-button-group { align-items: center; display: flex; flex-wrap: wrap; gap: var(--sw-space-2); min-width: 0; }
|
|
971
984
|
.sw-button-group-start { justify-content: flex-start; }
|
|
972
985
|
.sw-button-group-end { justify-content: flex-end; }
|
|
@@ -3018,6 +3031,31 @@ body {
|
|
|
3018
3031
|
white-space: nowrap;
|
|
3019
3032
|
}
|
|
3020
3033
|
|
|
3034
|
+
.sw-list-group-tiles > .sw-list {
|
|
3035
|
+
display: grid;
|
|
3036
|
+
gap: var(--sw-space-3);
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
.sw-list-group-tiles-2 > .sw-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
3040
|
+
.sw-list-group-tiles-3 > .sw-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
3041
|
+
.sw-list-group-tiles-4 > .sw-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
|
3042
|
+
|
|
3043
|
+
.sw-list-group-tiles > .sw-list > .sw-list-item {
|
|
3044
|
+
background: var(--sw-color-surface);
|
|
3045
|
+
border: 1px solid var(--sw-color-border);
|
|
3046
|
+
border-radius: var(--sw-radius-md);
|
|
3047
|
+
min-width: 0;
|
|
3048
|
+
overflow: clip;
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
@media not all and (min-width: 48rem) {
|
|
3052
|
+
.sw-list-group-tiles > .sw-list { grid-template-columns: minmax(0, 1fr); }
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
@media (forced-colors: active) {
|
|
3056
|
+
.sw-list-group-tiles > .sw-list > .sw-list-item { border-color: CanvasText; }
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3021
3059
|
.sw-file-field-frame {
|
|
3022
3060
|
border: 1px solid var(--sw-color-border);
|
|
3023
3061
|
border-radius: var(--sw-radius-md);
|
|
@@ -3147,6 +3185,83 @@ body {
|
|
|
3147
3185
|
margin-inline-start: auto;
|
|
3148
3186
|
}
|
|
3149
3187
|
|
|
3188
|
+
.sw-file-field-actions {
|
|
3189
|
+
display: flex;
|
|
3190
|
+
flex: none;
|
|
3191
|
+
flex-wrap: wrap;
|
|
3192
|
+
gap: var(--sw-space-2);
|
|
3193
|
+
margin-inline-start: auto;
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
.sw-file-field-compact.sw-file-field-chosen {
|
|
3197
|
+
flex-wrap: nowrap;
|
|
3198
|
+
gap: var(--sw-space-1);
|
|
3199
|
+
min-height: var(--sw-control-md-min-height);
|
|
3200
|
+
padding-block: 0;
|
|
3201
|
+
padding-inline: 0 var(--sw-space-1);
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
.sw-file-field-compact .sw-file-field-zone {
|
|
3205
|
+
justify-content: flex-start;
|
|
3206
|
+
padding: var(--sw-space-2) var(--sw-space-4);
|
|
3207
|
+
text-align: start;
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
.sw-file-field-pick {
|
|
3211
|
+
align-items: center;
|
|
3212
|
+
appearance: none;
|
|
3213
|
+
background: transparent;
|
|
3214
|
+
border: 0;
|
|
3215
|
+
border-radius: inherit;
|
|
3216
|
+
box-sizing: border-box;
|
|
3217
|
+
color: var(--sw-color-text);
|
|
3218
|
+
cursor: pointer;
|
|
3219
|
+
display: flex;
|
|
3220
|
+
flex: 1 1 auto;
|
|
3221
|
+
font-family: var(--sw-font-sans);
|
|
3222
|
+
gap: var(--sw-space-3);
|
|
3223
|
+
margin: 0;
|
|
3224
|
+
min-height: var(--sw-control-md-min-height);
|
|
3225
|
+
min-width: 0;
|
|
3226
|
+
padding-block: var(--sw-space-1);
|
|
3227
|
+
padding-inline: var(--sw-space-1) var(--sw-space-2);
|
|
3228
|
+
text-align: start;
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
.sw-file-field-pick:focus { outline: none; }
|
|
3232
|
+
|
|
3233
|
+
.sw-file-field-pick:focus-visible {
|
|
3234
|
+
outline: var(--sw-focus-ring-width) solid var(--sw-color-accent);
|
|
3235
|
+
outline-offset: calc(-1 * var(--sw-focus-ring-width));
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3238
|
+
.sw-file-field-pick:disabled { cursor: not-allowed; }
|
|
3239
|
+
|
|
3240
|
+
.sw-file-field-pick .sw-file-field-name {
|
|
3241
|
+
font-weight: 400;
|
|
3242
|
+
min-width: 0;
|
|
3243
|
+
overflow: hidden;
|
|
3244
|
+
overflow-wrap: normal;
|
|
3245
|
+
text-overflow: ellipsis;
|
|
3246
|
+
white-space: nowrap;
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
/* With no thumbnail or mark, the name starts where a text field's words do. */
|
|
3250
|
+
.sw-file-field-pick > .sw-file-field-name:first-child { margin-inline-start: var(--sw-space-3); }
|
|
3251
|
+
|
|
3252
|
+
.sw-file-field-compact .sw-file-field-preview,
|
|
3253
|
+
.sw-file-field-compact .sw-file-field-icon { margin-inline-start: var(--sw-space-1); }
|
|
3254
|
+
|
|
3255
|
+
.sw-file-field-remove { flex: none; }
|
|
3256
|
+
|
|
3257
|
+
@media (forced-colors: active) {
|
|
3258
|
+
.sw-file-field-pick { color: ButtonText; }
|
|
3259
|
+
.sw-file-field-pick:disabled { color: GrayText; }
|
|
3260
|
+
}
|
|
3261
|
+
|
|
3262
|
+
/* Disabled, the row fades as its Remove does. */
|
|
3263
|
+
.sw-file-field-pick:disabled { opacity: var(--sw-disabled-opacity); }
|
|
3264
|
+
|
|
3150
3265
|
@media (forced-colors: active) {
|
|
3151
3266
|
.sw-file-field-frame { border-color: CanvasText; }
|
|
3152
3267
|
.sw-field-invalid .sw-file-field-frame { border-color: Mark; }
|
|
@@ -7303,6 +7418,25 @@ body {
|
|
|
7303
7418
|
min-width: 0;
|
|
7304
7419
|
}
|
|
7305
7420
|
|
|
7421
|
+
.sw-steps-title-line {
|
|
7422
|
+
align-items: baseline;
|
|
7423
|
+
column-gap: var(--sw-space-2);
|
|
7424
|
+
display: flex;
|
|
7425
|
+
flex: 0 1 auto;
|
|
7426
|
+
flex-wrap: wrap;
|
|
7427
|
+
min-width: 0;
|
|
7428
|
+
}
|
|
7429
|
+
|
|
7430
|
+
.sw-steps-title-detail {
|
|
7431
|
+
color: var(--sw-color-muted);
|
|
7432
|
+
font-size: 15px;
|
|
7433
|
+
font-weight: 400;
|
|
7434
|
+
letter-spacing: -0.2px;
|
|
7435
|
+
line-height: 20px;
|
|
7436
|
+
min-width: 0;
|
|
7437
|
+
overflow-wrap: anywhere;
|
|
7438
|
+
}
|
|
7439
|
+
|
|
7306
7440
|
.sw-steps-item-upcoming .sw-steps-marker,
|
|
7307
7441
|
.sw-steps-item-skipped .sw-steps-marker {
|
|
7308
7442
|
box-shadow: inset 0 0 0 2px var(--sw-color-border);
|