@scalewing/react 1.25.0 → 1.27.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 +45 -0
- package/README.md +110 -1
- package/dist/components/ActionBar.d.ts +14 -0
- package/dist/components/ActionBar.js +5 -2
- package/dist/components/DenominationGrid.d.ts +1 -1
- package/dist/components/DenominationGrid.js +3 -0
- package/dist/components/DescriptionList.d.ts +28 -0
- package/dist/components/DescriptionList.js +15 -0
- package/dist/components/Stepper.d.ts +44 -0
- package/dist/components/Stepper.js +77 -0
- package/dist/components/Steps.d.ts +18 -0
- package/dist/components/Steps.js +34 -0
- package/dist/components/action-bar/ActionBarSummary.d.ts +22 -0
- package/dist/components/action-bar/ActionBarSummary.js +23 -0
- package/dist/components/denomination-grid/ColumnHeadText.d.ts +7 -0
- package/dist/components/denomination-grid/ColumnHeadText.js +13 -0
- package/dist/components/denomination-grid/DenominationStrip.js +3 -7
- package/dist/components/denomination-grid/DenominationTiles.js +2 -1
- package/dist/components/denomination-grid/EntryCell.d.ts +15 -0
- package/dist/components/denomination-grid/EntryCell.js +16 -0
- package/dist/components/denomination-grid/RowLabelLine.d.ts +3 -2
- package/dist/components/denomination-grid/RowLabelLine.js +5 -3
- package/dist/components/denomination-grid/StripRow.d.ts +13 -0
- package/dist/components/denomination-grid/StripRow.js +19 -0
- package/dist/components/denomination-grid/types.d.ts +44 -1
- package/dist/components/denomination-grid/validate-entry.d.ts +15 -0
- package/dist/components/denomination-grid/validate-entry.js +78 -0
- package/dist/components/steps/Step.d.ts +24 -0
- package/dist/components/steps/Step.js +62 -0
- package/dist/components/steps/step-status.d.ts +26 -0
- package/dist/components/steps/step-status.js +37 -0
- package/dist/components/steps/steps-context.d.ts +16 -0
- package/dist/components/steps/steps-context.js +3 -0
- package/dist/css/css-action-bar-summary.d.ts +2 -0
- package/dist/css/css-action-bar-summary.js +48 -0
- package/dist/css/css-action-bar.js +4 -0
- package/dist/css/css-components.js +10 -0
- package/dist/css/css-denomination-entry.d.ts +2 -0
- package/dist/css/css-denomination-entry.js +78 -0
- package/dist/css/css-denomination-grid.js +4 -0
- package/dist/css/css-description-list.d.ts +12 -0
- package/dist/css/css-description-list.js +63 -0
- package/dist/css/css-stepper.d.ts +10 -0
- package/dist/css/css-stepper.js +126 -0
- package/dist/css/css-steps.d.ts +9 -0
- package/dist/css/css-steps.js +203 -0
- package/dist/css/stylesheet.js +6 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -1
- package/dist/stepper-count.d.ts +37 -0
- package/dist/stepper-count.js +50 -0
- package/dist/styles.css +367 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
const caption = typographyVariants.caption;
|
|
3
|
+
/** An enabled entry count, unless its Stepper shows an error (whose danger border wins). */
|
|
4
|
+
const tonedEntryInput = '[data-theme] .sw-denomination-cell-toned .sw-stepper:not(.sw-stepper-invalid) input.sw-stepper-input:not(:disabled)';
|
|
5
|
+
/*
|
|
6
|
+
* Count entry and the labels around it. An entry cell holds a full-width
|
|
7
|
+
* Stepper; its count keeps spacing step 8 (room for three digits), so a narrow strip scrolls
|
|
8
|
+
* in its region instead of crushing the counts. A cell tone draws the
|
|
9
|
+
* count's border in the tone, a hairline thicker through an inset shadow so
|
|
10
|
+
* nothing moves. A caption is a muted caption-size line: under a row label,
|
|
11
|
+
* or after a column label. A quiet row sits on the subtle fill, its pinned
|
|
12
|
+
* label too. A disabled row fades its label, counts and total (its entry is
|
|
13
|
+
* disabled by its Stepper); a pinned label fades its contents, not its
|
|
14
|
+
* fill, so counts never show through it.
|
|
15
|
+
*/
|
|
16
|
+
export function cssDenominationEntryClasses() {
|
|
17
|
+
return `.sw-denomination-strip td.sw-denomination-entry {
|
|
18
|
+
padding: var(--sw-space-1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sw-denomination-entry .sw-stepper-full .sw-stepper-track {
|
|
22
|
+
grid-template-columns: var(--sw-space-6) minmax(var(--sw-space-8), 1fr) var(--sw-space-6);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* A strip with entry rows centres its heads and read-only counts over the steppers. */
|
|
26
|
+
.sw-denomination-strip-entry .sw-denomination-head:not(.sw-denomination-total-head),
|
|
27
|
+
.sw-denomination-strip-entry .sw-denomination-cell {
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
${tonedEntryInput} {
|
|
32
|
+
border-color: var(--sw-denomination-cell-tone);
|
|
33
|
+
box-shadow: inset 0 0 0 1px var(--sw-denomination-cell-tone);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sw-denomination-label-words {
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
min-width: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sw-denomination-label-caption,
|
|
43
|
+
.sw-denomination-head-caption {
|
|
44
|
+
color: var(--sw-color-muted);
|
|
45
|
+
font-size: ${caption.fontSize}px;
|
|
46
|
+
font-weight: ${caption.fontWeight};
|
|
47
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
48
|
+
line-height: ${caption.lineHeight}px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.sw-denomination-row-quiet,
|
|
52
|
+
.sw-denomination-strip .sw-denomination-row-quiet .sw-denomination-label {
|
|
53
|
+
background: var(--sw-color-subtle);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sw-denomination-strip .sw-denomination-row-disabled .sw-denomination-label-body,
|
|
57
|
+
.sw-denomination-strip .sw-denomination-row-disabled .sw-denomination-cell,
|
|
58
|
+
.sw-denomination-strip .sw-denomination-row-disabled .sw-denomination-total {
|
|
59
|
+
opacity: var(--sw-disabled-opacity);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (forced-colors: active) {
|
|
63
|
+
${tonedEntryInput} { border-color: Highlight; box-shadow: inset 0 0 0 1px Highlight; }
|
|
64
|
+
.sw-denomination-label-caption,
|
|
65
|
+
.sw-denomination-head-caption { color: CanvasText; }
|
|
66
|
+
}`;
|
|
67
|
+
}
|
|
68
|
+
export function denominationEntryClassCatalog() {
|
|
69
|
+
return [
|
|
70
|
+
'sw-denomination-entry',
|
|
71
|
+
'sw-denomination-strip-entry',
|
|
72
|
+
'sw-denomination-label-words',
|
|
73
|
+
'sw-denomination-label-caption',
|
|
74
|
+
'sw-denomination-head-caption',
|
|
75
|
+
'sw-denomination-row-quiet',
|
|
76
|
+
'sw-denomination-row-disabled',
|
|
77
|
+
];
|
|
78
|
+
}
|
|
@@ -2,6 +2,7 @@ import { typographyVariants } from '@scalewing/tokens';
|
|
|
2
2
|
import { breakpointQuery } from './breakpoints.js';
|
|
3
3
|
import { badgeTones } from './css-data.js';
|
|
4
4
|
import { cssDenominationAlignedClasses, denominationAlignedClassCatalog, } from './css-denomination-aligned.js';
|
|
5
|
+
import { cssDenominationEntryClasses, denominationEntryClassCatalog, } from './css-denomination-entry.js';
|
|
5
6
|
import { cssDenominationCellToneClasses, denominationCellToneClassCatalog, } from './css-denomination-cell-tones.js';
|
|
6
7
|
import { pinnedStartShadeRules, scrollRegionRules, } from './css-scroll-region.js';
|
|
7
8
|
import { visuallyHiddenDeclarations } from './css-utilities.js';
|
|
@@ -249,6 +250,8 @@ ${pinnedStartShadeRules('.sw-denomination-scroll', [
|
|
|
249
250
|
|
|
250
251
|
${cssDenominationCellToneClasses()}
|
|
251
252
|
|
|
253
|
+
${cssDenominationEntryClasses()}
|
|
254
|
+
|
|
252
255
|
${cssDenominationAlignedClasses()}
|
|
253
256
|
|
|
254
257
|
@media (forced-colors: active) {
|
|
@@ -290,6 +293,7 @@ export function denominationGridClassCatalog() {
|
|
|
290
293
|
'sw-denomination-tile',
|
|
291
294
|
'sw-denomination-subtotal',
|
|
292
295
|
...denominationCellToneClassCatalog(),
|
|
296
|
+
...denominationEntryClassCatalog(),
|
|
293
297
|
...denominationAlignedClassCatalog(),
|
|
294
298
|
];
|
|
295
299
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The description list: a two-column grid whose items share its columns
|
|
3
|
+
* (`subgrid`), so every term starts the same column and every detail the
|
|
4
|
+
* next. The term column fits the widest term up to 40% of the list. A
|
|
5
|
+
* hairline divides the rows, the list sits flush with no space above the
|
|
6
|
+
* first row or below the last, and each row aligns to its top. Below `md`
|
|
7
|
+
* a term sits over its detail. A term and a detail are columns of lines:
|
|
8
|
+
* each child is its own line with its own line height, so a caption term
|
|
9
|
+
* starts level with a caption detail instead of on the list's taller line.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cssDescriptionListClasses(): string;
|
|
12
|
+
export declare function descriptionListClassCatalog(): string[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { breakpointQuery } from './breakpoints.js';
|
|
2
|
+
/**
|
|
3
|
+
* The description list: a two-column grid whose items share its columns
|
|
4
|
+
* (`subgrid`), so every term starts the same column and every detail the
|
|
5
|
+
* next. The term column fits the widest term up to 40% of the list. A
|
|
6
|
+
* hairline divides the rows, the list sits flush with no space above the
|
|
7
|
+
* first row or below the last, and each row aligns to its top. Below `md`
|
|
8
|
+
* a term sits over its detail. A term and a detail are columns of lines:
|
|
9
|
+
* each child is its own line with its own line height, so a caption term
|
|
10
|
+
* starts level with a caption detail instead of on the list's taller line.
|
|
11
|
+
*/
|
|
12
|
+
export function cssDescriptionListClasses() {
|
|
13
|
+
return `.sw-description-list {
|
|
14
|
+
column-gap: var(--sw-space-4);
|
|
15
|
+
display: grid;
|
|
16
|
+
grid-template-columns: fit-content(40%) minmax(0, 1fr);
|
|
17
|
+
margin: 0;
|
|
18
|
+
min-width: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sw-description-item {
|
|
22
|
+
align-items: start;
|
|
23
|
+
display: grid;
|
|
24
|
+
grid-column: 1 / -1;
|
|
25
|
+
grid-template-columns: subgrid;
|
|
26
|
+
padding-block: var(--sw-space-2);
|
|
27
|
+
row-gap: var(--sw-space-1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sw-description-item:first-child { padding-top: 0; }
|
|
31
|
+
|
|
32
|
+
.sw-description-item:last-child { padding-bottom: 0; }
|
|
33
|
+
|
|
34
|
+
.sw-description-item + .sw-description-item {
|
|
35
|
+
border-top: 1px solid var(--sw-color-border);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.sw-description-term,
|
|
39
|
+
.sw-description-detail {
|
|
40
|
+
align-items: flex-start;
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
margin: 0;
|
|
44
|
+
min-width: 0;
|
|
45
|
+
overflow-wrap: anywhere;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media ${breakpointQuery('below', 'md')} {
|
|
49
|
+
.sw-description-list { grid-template-columns: minmax(0, 1fr); }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@media (forced-colors: active) {
|
|
53
|
+
.sw-description-item + .sw-description-item { border-top-color: CanvasText; }
|
|
54
|
+
}`;
|
|
55
|
+
}
|
|
56
|
+
export function descriptionListClassCatalog() {
|
|
57
|
+
return [
|
|
58
|
+
'sw-description-list',
|
|
59
|
+
'sw-description-item',
|
|
60
|
+
'sw-description-term',
|
|
61
|
+
'sw-description-detail',
|
|
62
|
+
];
|
|
63
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The web Stepper: a label over a track of − count +. The count is a few
|
|
3
|
+
* digits wide by default, the track at its own width even under a wider label
|
|
4
|
+
* or message (`5ch` plus its padding, so its width never follows
|
|
5
|
+
* its value), or fills its container with `sw-stepper-full`. The buttons are
|
|
6
|
+
* spacing step 6 wide on the subtle fill and every part is the `md` control
|
|
7
|
+
* height.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cssStepperClasses(): string;
|
|
10
|
+
export declare function stepperClassCatalog(): string[];
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { changedTintLayer } from './css-field-changed.js';
|
|
3
|
+
const body = typographyVariants.body;
|
|
4
|
+
const label = typographyVariants.label;
|
|
5
|
+
const title = typographyVariants.title;
|
|
6
|
+
/*
|
|
7
|
+
* The count is a text input, so the canvas already draws it as a control
|
|
8
|
+
* (`[data-theme] :is(input[type='text'], …)`). `input.sw-stepper-input`
|
|
9
|
+
* matches that rule's specificity and comes later in the sheet, so the
|
|
10
|
+
* stepper's own centering and type win while the canvas keeps the surface,
|
|
11
|
+
* the focus ring and the disabled look.
|
|
12
|
+
*/
|
|
13
|
+
const input = '[data-theme] input.sw-stepper-input';
|
|
14
|
+
function stateRules() {
|
|
15
|
+
return `[data-theme] .sw-stepper-invalid input.sw-stepper-input {
|
|
16
|
+
border-color: var(--sw-color-danger);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
[data-theme] .sw-stepper-changed input.sw-stepper-input {
|
|
20
|
+
border-color: var(--sw-color-accent);
|
|
21
|
+
box-shadow: inset 0 0 0 1px var(--sw-color-accent);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-theme] .sw-stepper-changed input.sw-stepper-input:not(:placeholder-shown) {
|
|
25
|
+
background-image: ${changedTintLayer};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Read-only: the buttons keep their room, so the count lines up with an editable one. */
|
|
29
|
+
.sw-stepper-readonly .sw-stepper-button { visibility: hidden; }
|
|
30
|
+
|
|
31
|
+
@media (forced-colors: active) {
|
|
32
|
+
.sw-stepper-button { border-color: ButtonText; }
|
|
33
|
+
.sw-stepper-button:disabled { border-color: GrayText; color: GrayText; opacity: 1; }
|
|
34
|
+
[data-theme] .sw-stepper-invalid input.sw-stepper-input { border-color: Mark; }
|
|
35
|
+
[data-theme] .sw-stepper-changed input.sw-stepper-input { border-color: Highlight; box-shadow: inset 0 0 0 1px Highlight; background-image: none; }
|
|
36
|
+
}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The web Stepper: a label over a track of − count +. The count is a few
|
|
40
|
+
* digits wide by default, the track at its own width even under a wider label
|
|
41
|
+
* or message (`5ch` plus its padding, so its width never follows
|
|
42
|
+
* its value), or fills its container with `sw-stepper-full`. The buttons are
|
|
43
|
+
* spacing step 6 wide on the subtle fill and every part is the `md` control
|
|
44
|
+
* height.
|
|
45
|
+
*/
|
|
46
|
+
export function cssStepperClasses() {
|
|
47
|
+
return `.sw-stepper {
|
|
48
|
+
align-items: flex-start;
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
gap: var(--sw-space-1);
|
|
52
|
+
min-width: 0;
|
|
53
|
+
/* Holds its hidden label and empty error region, which leave the flow,
|
|
54
|
+
so inside a scroll region they never widen the page. */
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sw-stepper-full { align-items: stretch; display: flex; }
|
|
59
|
+
|
|
60
|
+
.sw-stepper-track {
|
|
61
|
+
display: inline-grid;
|
|
62
|
+
gap: var(--sw-space-1);
|
|
63
|
+
grid-template-columns: var(--sw-space-6) auto var(--sw-space-6);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sw-stepper-full .sw-stepper-track {
|
|
67
|
+
display: grid;
|
|
68
|
+
grid-template-columns: var(--sw-space-6) minmax(0, 1fr) var(--sw-space-6);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.sw-stepper-button {
|
|
72
|
+
align-items: center;
|
|
73
|
+
appearance: none;
|
|
74
|
+
background: var(--sw-color-subtle);
|
|
75
|
+
border: 1px solid transparent;
|
|
76
|
+
border-radius: var(--sw-radius-sm);
|
|
77
|
+
color: var(--sw-color-text);
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
font-family: var(--sw-font-sans);
|
|
81
|
+
font-size: ${title.fontSize}px;
|
|
82
|
+
font-weight: ${title.fontWeight};
|
|
83
|
+
justify-content: center;
|
|
84
|
+
line-height: ${title.lineHeight}px;
|
|
85
|
+
margin: 0;
|
|
86
|
+
min-height: var(--sw-control-md-min-height);
|
|
87
|
+
padding: 0;
|
|
88
|
+
touch-action: manipulation;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.sw-stepper-button:hover:not(:disabled) {
|
|
92
|
+
background: var(--sw-color-border);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sw-stepper-button:disabled {
|
|
96
|
+
cursor: not-allowed;
|
|
97
|
+
opacity: var(--sw-disabled-opacity);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
${input} {
|
|
101
|
+
font-size: ${body.fontSize}px;
|
|
102
|
+
font-variant-numeric: tabular-nums;
|
|
103
|
+
font-weight: ${label.fontWeight};
|
|
104
|
+
inline-size: calc(5ch + 2 * var(--sw-space-1));
|
|
105
|
+
line-height: ${body.lineHeight}px;
|
|
106
|
+
min-width: 0;
|
|
107
|
+
padding-inline: var(--sw-space-1);
|
|
108
|
+
text-align: center;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.sw-stepper-full input.sw-stepper-input { inline-size: 100%; }
|
|
112
|
+
|
|
113
|
+
${stateRules()}`;
|
|
114
|
+
}
|
|
115
|
+
export function stepperClassCatalog() {
|
|
116
|
+
return [
|
|
117
|
+
'sw-stepper',
|
|
118
|
+
'sw-stepper-full',
|
|
119
|
+
'sw-stepper-track',
|
|
120
|
+
'sw-stepper-button',
|
|
121
|
+
'sw-stepper-input',
|
|
122
|
+
'sw-stepper-invalid',
|
|
123
|
+
'sw-stepper-changed',
|
|
124
|
+
'sw-stepper-readonly',
|
|
125
|
+
];
|
|
126
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one-page vertical stepper: an ordered list of glass panels a small
|
|
3
|
+
* gap apart. Each has a header line (marker, title, and on a done step its
|
|
4
|
+
* summary and Edit) and, while open (current or error), a body indented to
|
|
5
|
+
* the title. An open step's title is the title variant; a folded one's is
|
|
6
|
+
* body size at label weight, muted ahead of the form or skipped.
|
|
7
|
+
*/
|
|
8
|
+
export declare function cssStepsClasses(): string;
|
|
9
|
+
export declare function stepsClassCatalog(): string[];
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
const body = typographyVariants.body;
|
|
3
|
+
const caption = typographyVariants.caption;
|
|
4
|
+
const label = typographyVariants.label;
|
|
5
|
+
const title = typographyVariants.title;
|
|
6
|
+
/** The marker's size: the xs control height. */
|
|
7
|
+
const marker = 'var(--sw-control-xs-min-height)';
|
|
8
|
+
/** The marker's look per status: its fill, ring and number color. */
|
|
9
|
+
function markerRules() {
|
|
10
|
+
return `.sw-steps-item-upcoming .sw-steps-marker,
|
|
11
|
+
.sw-steps-item-skipped .sw-steps-marker {
|
|
12
|
+
box-shadow: inset 0 0 0 2px var(--sw-color-border);
|
|
13
|
+
color: var(--sw-color-muted);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.sw-steps-item-current .sw-steps-marker {
|
|
17
|
+
background: var(--sw-color-accent);
|
|
18
|
+
color: var(--sw-color-onAccent);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sw-steps-item-error .sw-steps-marker {
|
|
22
|
+
background: var(--sw-color-danger);
|
|
23
|
+
color: var(--sw-color-onDanger);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.sw-steps-item-done .sw-steps-marker {
|
|
27
|
+
background: var(--sw-color-success);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Private chrome: a check drawn with two borders, as Checkbox's. */
|
|
31
|
+
.sw-steps-item-done .sw-steps-marker::after {
|
|
32
|
+
border-bottom: 2px solid var(--sw-color-surface);
|
|
33
|
+
border-right: 2px solid var(--sw-color-surface);
|
|
34
|
+
content: '';
|
|
35
|
+
height: var(--sw-space-3);
|
|
36
|
+
margin-top: calc(-1 * var(--sw-space-1) / 2);
|
|
37
|
+
transform: rotate(45deg);
|
|
38
|
+
width: calc(var(--sw-space-3) / 2);
|
|
39
|
+
}`;
|
|
40
|
+
}
|
|
41
|
+
/*
|
|
42
|
+
* A line from each marker down to the next step's, through the gap between
|
|
43
|
+
* the panels: the success color below a done step, the hairline otherwise.
|
|
44
|
+
*/
|
|
45
|
+
function connectorRules() {
|
|
46
|
+
return `.sw-steps-item:not(:last-child)::after {
|
|
47
|
+
background: var(--sw-color-border);
|
|
48
|
+
bottom: calc(-1 * var(--sw-space-2) - 1px);
|
|
49
|
+
content: '';
|
|
50
|
+
inset-inline-start: calc(var(--sw-space-4) + ${marker} / 2 - 1px);
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: calc(var(--sw-steps-padding) + ${marker} + var(--sw-space-1));
|
|
53
|
+
width: 2px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sw-steps-item-done:not(:last-child)::after {
|
|
57
|
+
background: var(--sw-color-success);
|
|
58
|
+
}`;
|
|
59
|
+
}
|
|
60
|
+
function forcedColorRules() {
|
|
61
|
+
return `@media (forced-colors: active) {
|
|
62
|
+
.sw-steps-marker { border: 2px solid CanvasText; box-shadow: none; }
|
|
63
|
+
.sw-steps-item-current .sw-steps-marker { border-color: Highlight; }
|
|
64
|
+
.sw-steps-item-done .sw-steps-marker::after { border-color: CanvasText; }
|
|
65
|
+
.sw-steps-item:not(:last-child)::after { background: CanvasText; }
|
|
66
|
+
.sw-steps-item-upcoming .sw-steps-title,
|
|
67
|
+
.sw-steps-item-skipped .sw-steps-title { color: GrayText; }
|
|
68
|
+
}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The one-page vertical stepper: an ordered list of glass panels a small
|
|
72
|
+
* gap apart. Each has a header line (marker, title, and on a done step its
|
|
73
|
+
* summary and Edit) and, while open (current or error), a body indented to
|
|
74
|
+
* the title. An open step's title is the title variant; a folded one's is
|
|
75
|
+
* body size at label weight, muted ahead of the form or skipped.
|
|
76
|
+
*/
|
|
77
|
+
export function cssStepsClasses() {
|
|
78
|
+
return `.sw-steps {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
gap: var(--sw-space-2);
|
|
82
|
+
list-style: none;
|
|
83
|
+
margin: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.sw-steps-item {
|
|
88
|
+
--sw-steps-padding: var(--sw-space-3);
|
|
89
|
+
background: var(--sw-glass-fill);
|
|
90
|
+
border: 1px solid var(--sw-glass-border);
|
|
91
|
+
border-radius: var(--sw-radius-md);
|
|
92
|
+
box-shadow: inset 0 1px 0 var(--sw-glass-specular);
|
|
93
|
+
color: var(--sw-color-text);
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
gap: var(--sw-space-4);
|
|
97
|
+
padding: var(--sw-steps-padding) var(--sw-space-4);
|
|
98
|
+
position: relative;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.sw-steps-item-current,
|
|
102
|
+
.sw-steps-item-error {
|
|
103
|
+
--sw-steps-padding: var(--sw-space-4);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* The marker sits at the top of the header, so the connector always starts
|
|
107
|
+
under it; each line of the header is centred on the marker's height. */
|
|
108
|
+
.sw-steps-header {
|
|
109
|
+
align-items: flex-start;
|
|
110
|
+
display: flex;
|
|
111
|
+
gap: var(--sw-space-3);
|
|
112
|
+
min-height: ${marker};
|
|
113
|
+
min-width: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.sw-steps-marker {
|
|
117
|
+
align-items: center;
|
|
118
|
+
border-radius: var(--sw-radius-pill);
|
|
119
|
+
box-sizing: border-box;
|
|
120
|
+
display: inline-flex;
|
|
121
|
+
flex: none;
|
|
122
|
+
font-family: var(--sw-font-sans);
|
|
123
|
+
font-size: ${caption.fontSize}px;
|
|
124
|
+
font-variant-numeric: tabular-nums;
|
|
125
|
+
font-weight: 700;
|
|
126
|
+
height: ${marker};
|
|
127
|
+
justify-content: center;
|
|
128
|
+
line-height: ${caption.lineHeight}px;
|
|
129
|
+
width: ${marker};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.sw-steps-title {
|
|
133
|
+
font-family: var(--sw-font-sans);
|
|
134
|
+
font-size: ${body.fontSize}px;
|
|
135
|
+
font-weight: ${label.fontWeight};
|
|
136
|
+
letter-spacing: ${body.letterSpacing}px;
|
|
137
|
+
line-height: ${body.lineHeight}px;
|
|
138
|
+
margin: 0;
|
|
139
|
+
min-width: 0;
|
|
140
|
+
padding-block: calc((${marker} - ${body.lineHeight}px) / 2);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.sw-steps-item-current .sw-steps-title,
|
|
144
|
+
.sw-steps-item-error .sw-steps-title {
|
|
145
|
+
font-size: ${title.fontSize}px;
|
|
146
|
+
letter-spacing: ${title.letterSpacing}px;
|
|
147
|
+
line-height: ${title.lineHeight}px;
|
|
148
|
+
padding-block: calc((${marker} - ${title.lineHeight}px) / 2);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.sw-steps-item-upcoming .sw-steps-title,
|
|
152
|
+
.sw-steps-item-skipped .sw-steps-title,
|
|
153
|
+
.sw-steps-reason {
|
|
154
|
+
color: var(--sw-color-muted);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.sw-steps-summary {
|
|
158
|
+
flex: 1 1 0;
|
|
159
|
+
font-size: ${label.fontSize}px;
|
|
160
|
+
letter-spacing: ${label.letterSpacing}px;
|
|
161
|
+
line-height: ${label.lineHeight}px;
|
|
162
|
+
min-width: 25%;
|
|
163
|
+
overflow: hidden;
|
|
164
|
+
padding-block: calc((${marker} - ${label.lineHeight}px) / 2);
|
|
165
|
+
text-overflow: ellipsis;
|
|
166
|
+
white-space: nowrap;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.sw-button.sw-steps-edit {
|
|
170
|
+
flex: none;
|
|
171
|
+
margin-block: calc((${marker} - var(--sw-control-sm-min-height)) / 2);
|
|
172
|
+
margin-inline-start: auto;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.sw-steps-body {
|
|
176
|
+
margin-inline-start: calc(${marker} + var(--sw-space-3));
|
|
177
|
+
min-width: 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
${markerRules()}
|
|
181
|
+
|
|
182
|
+
${connectorRules()}
|
|
183
|
+
|
|
184
|
+
${forcedColorRules()}`;
|
|
185
|
+
}
|
|
186
|
+
export function stepsClassCatalog() {
|
|
187
|
+
return [
|
|
188
|
+
'sw-steps',
|
|
189
|
+
'sw-steps-item',
|
|
190
|
+
'sw-steps-item-upcoming',
|
|
191
|
+
'sw-steps-item-current',
|
|
192
|
+
'sw-steps-item-done',
|
|
193
|
+
'sw-steps-item-error',
|
|
194
|
+
'sw-steps-item-skipped',
|
|
195
|
+
'sw-steps-header',
|
|
196
|
+
'sw-steps-marker',
|
|
197
|
+
'sw-steps-title',
|
|
198
|
+
'sw-steps-reason',
|
|
199
|
+
'sw-steps-summary',
|
|
200
|
+
'sw-steps-edit',
|
|
201
|
+
'sw-steps-body',
|
|
202
|
+
];
|
|
203
|
+
}
|
package/dist/css/stylesheet.js
CHANGED
|
@@ -13,6 +13,7 @@ import { tooltipClassCatalog } from './css-tooltip.js';
|
|
|
13
13
|
import { infoTipClassCatalog } from './css-info-tip.js';
|
|
14
14
|
import { separatorClassCatalog } from './css-separator.js';
|
|
15
15
|
import { statTileClassCatalog } from './css-stat-tile.js';
|
|
16
|
+
import { descriptionListClassCatalog } from './css-description-list.js';
|
|
16
17
|
import { tabsClassCatalog } from './css-tabs.js';
|
|
17
18
|
import { responsiveClassCatalog } from './css-responsive.js';
|
|
18
19
|
import { filterChipsClassCatalog } from './css-filter-chips.js';
|
|
@@ -21,6 +22,8 @@ import { gridSpanClassCatalog } from './css-grid-span.js';
|
|
|
21
22
|
import { denominationGridClassCatalog } from './css-denomination-grid.js';
|
|
22
23
|
import { scrollRegionClassCatalog } from './css-scroll-region.js';
|
|
23
24
|
import { fieldClassCatalog } from './css-field.js';
|
|
25
|
+
import { stepperClassCatalog } from './css-stepper.js';
|
|
26
|
+
import { stepsClassCatalog } from './css-steps.js';
|
|
24
27
|
import { boxBorderClassCatalog } from './css-box-border.js';
|
|
25
28
|
import { cssComponentClasses } from './css-components.js';
|
|
26
29
|
import { buttonClassCatalog } from './css-button.js';
|
|
@@ -76,12 +79,15 @@ export function utilityClassCatalog() {
|
|
|
76
79
|
...infoTipClassCatalog(),
|
|
77
80
|
...separatorClassCatalog(),
|
|
78
81
|
...statTileClassCatalog(),
|
|
82
|
+
...descriptionListClassCatalog(),
|
|
79
83
|
...tabsClassCatalog(),
|
|
80
84
|
...filterChipsClassCatalog(),
|
|
81
85
|
...gridClassCatalog(),
|
|
82
86
|
...gridSpanClassCatalog(),
|
|
83
87
|
...denominationGridClassCatalog(),
|
|
84
88
|
...fieldClassCatalog(),
|
|
89
|
+
...stepperClassCatalog(),
|
|
90
|
+
...stepsClassCatalog(),
|
|
85
91
|
...splitClassCatalog(),
|
|
86
92
|
...toastClassCatalog(),
|
|
87
93
|
...responsiveClassCatalog(),
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ActionMenu, type ActionMenuAlign, type ActionMenuItem, type ActionMenuProps, } from './components/ActionMenu.js';
|
|
2
|
-
export { ActionBar, type ActionBarProps } from './components/ActionBar.js';
|
|
2
|
+
export { ActionBar, type ActionBarProps, type ActionBarSummary, type ActionBarSummaryTone, } from './components/ActionBar.js';
|
|
3
3
|
export { Accordion } from './components/Accordion.js';
|
|
4
4
|
export type { AccordionProps, AccordionSize } from './components/Accordion.js';
|
|
5
5
|
export { Switch, type SwitchProps } from './components/Switch.js';
|
|
@@ -24,6 +24,8 @@ export { TabPanel, type TabItem, type TabPanelProps, Tabs, type TabsProps, tabId
|
|
|
24
24
|
export { Toast, toastTones } from './components/Toast.js';
|
|
25
25
|
export type { ToastProps, ToastTone } from './components/Toast.js';
|
|
26
26
|
export { Field, type FieldProps, type FieldSize } from './components/Field.js';
|
|
27
|
+
export { Step, type StepHeadingLevel, type StepProps, Steps, type StepsLabels, type StepsProps, type StepStatus, } from './components/Steps.js';
|
|
28
|
+
export { Stepper, type StepperProps, type StepperWidth, } from './components/Stepper.js';
|
|
27
29
|
export { Inline, type InlineProps } from './components/Inline.js';
|
|
28
30
|
export { Split } from './components/Split.js';
|
|
29
31
|
export type { SplitProps } from './components/Split.js';
|
|
@@ -42,11 +44,13 @@ export type { Breakpoint, BreakpointDirection, VisibilityBreakpoint, } from './c
|
|
|
42
44
|
export { breakpointQuery } from './css/breakpoints.js';
|
|
43
45
|
export { Separator } from './components/Separator.js';
|
|
44
46
|
export type { SeparatorOrientation, SeparatorProps, } from './components/Separator.js';
|
|
47
|
+
export { DescriptionItem, DescriptionList, } from './components/DescriptionList.js';
|
|
48
|
+
export type { DescriptionItemProps, DescriptionListProps, } from './components/DescriptionList.js';
|
|
45
49
|
export { Grid } from './components/Grid.js';
|
|
46
50
|
export type { GridColumns, GridProps } from './components/Grid.js';
|
|
47
51
|
export type { GridColumnSpan } from './css/css-grid-span.js';
|
|
48
52
|
export type { ColumnSpanProps } from './column-span-classes.js';
|
|
49
53
|
export { DenominationGrid } from './components/DenominationGrid.js';
|
|
50
|
-
export type { DenominationGridColumn, DenominationGridLayout, DenominationGridProps, DenominationGridRow, DenominationGridRowRole, DenominationGridTone, DenominationLabelWidth, } from './components/DenominationGrid.js';
|
|
54
|
+
export type { DenominationGridColumn, DenominationGridEntry, DenominationGridLayout, DenominationGridProps, DenominationGridRow, DenominationGridRowEmphasis, DenominationGridRowRole, DenominationGridTone, DenominationLabelWidth, } from './components/DenominationGrid.js';
|
|
51
55
|
export { FilterChips } from './components/FilterChips.js';
|
|
52
56
|
export type { FilterChipOption, FilterChipsProps, } from './components/FilterChips.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ActionMenu, } from './components/ActionMenu.js';
|
|
2
|
-
export { ActionBar } from './components/ActionBar.js';
|
|
2
|
+
export { ActionBar, } from './components/ActionBar.js';
|
|
3
3
|
export { Accordion } from './components/Accordion.js';
|
|
4
4
|
export { Switch } from './components/Switch.js';
|
|
5
5
|
export { DateField, } from './components/DateField.js';
|
|
@@ -22,6 +22,8 @@ export { StatTile, statTileTones, } from './components/StatTile.js';
|
|
|
22
22
|
export { TabPanel, Tabs, tabId, tabPanelId, } from './components/Tabs.js';
|
|
23
23
|
export { Toast, toastTones } from './components/Toast.js';
|
|
24
24
|
export { Field } from './components/Field.js';
|
|
25
|
+
export { Step, Steps, } from './components/Steps.js';
|
|
26
|
+
export { Stepper, } from './components/Stepper.js';
|
|
25
27
|
export { Inline } from './components/Inline.js';
|
|
26
28
|
export { Split } from './components/Split.js';
|
|
27
29
|
export { Nav } from './components/Nav.js';
|
|
@@ -35,6 +37,7 @@ export { ThemeProvider, useTheme, } from './theme/ThemeProvider.js';
|
|
|
35
37
|
export { utilityClassCatalog } from './css/stylesheet.js';
|
|
36
38
|
export { breakpointQuery } from './css/breakpoints.js';
|
|
37
39
|
export { Separator } from './components/Separator.js';
|
|
40
|
+
export { DescriptionItem, DescriptionList, } from './components/DescriptionList.js';
|
|
38
41
|
export { Grid } from './components/Grid.js';
|
|
39
42
|
export { DenominationGrid } from './components/DenominationGrid.js';
|
|
40
43
|
export { FilterChips } from './components/FilterChips.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** A web `Stepper`'s bounds: whole numbers, `min <= max`, `step > 0`. */
|
|
2
|
+
export type StepperBounds = {
|
|
3
|
+
min: number;
|
|
4
|
+
max: number;
|
|
5
|
+
step: number;
|
|
6
|
+
};
|
|
7
|
+
/** Where one press of − and of + lands, or null where that button is stopped. */
|
|
8
|
+
export type StepperMoves = {
|
|
9
|
+
down: number | null;
|
|
10
|
+
up: number | null;
|
|
11
|
+
};
|
|
12
|
+
/** A typed text: no count (empty), a whole count, or text the box refuses. */
|
|
13
|
+
export type StepperEntry = {
|
|
14
|
+
kind: 'empty';
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'count';
|
|
17
|
+
value: number;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'refused';
|
|
20
|
+
};
|
|
21
|
+
/** A consumer bug, not a runtime state: the bounds must describe a range. */
|
|
22
|
+
export declare function assertStepperBounds(bounds: StepperBounds): void;
|
|
23
|
+
/**
|
|
24
|
+
* The counts − and + would move to. An empty box counts as `min`. A count
|
|
25
|
+
* outside the bounds (typed) moves back inside them; a bound stops its own
|
|
26
|
+
* direction, and a locked (disabled or read-only) stepper stops both.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stepperMoves(value: number | null, bounds: StepperBounds, locked: boolean): StepperMoves;
|
|
29
|
+
/**
|
|
30
|
+
* Reads what the person typed. Digits make a count, with a leading minus
|
|
31
|
+
* only when the range goes below zero; an empty box, or a lone minus on its
|
|
32
|
+
* way to a negative count, is no count. Anything else, or a count too large
|
|
33
|
+
* to be exact, is refused and the box keeps its last text.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readStepperEntry(text: string, allowsNegative: boolean): StepperEntry;
|
|
36
|
+
/** The box's text for a count: the plain number, or empty for none. */
|
|
37
|
+
export declare function stepperText(value: number | null): string;
|