@scalewing/react 1.59.4 → 1.60.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 +12 -0
- package/README.md +3 -0
- package/dist/components/ScreenPreview.d.ts +3 -2
- package/dist/components/ScreenPreview.js +2 -1
- package/dist/components/screen-preview/PreviewImage.d.ts +13 -0
- package/dist/components/screen-preview/PreviewImage.js +18 -0
- package/dist/css/css-filter-chips.js +2 -1
- package/dist/css/css-fixture-action.js +6 -3
- package/dist/css/css-screen-preview.js +12 -1
- package/dist/css/css-segmented.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/styles.css +13 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @scalewing/react
|
|
2
2
|
|
|
3
|
+
## 1.60.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 69e52f9: `PreviewImage`: a real screenshot inside a `ScreenPreview`, at the screen's width with its height following. Decorative, as the preview's `label` names the image (Teisoro F-017 task 2730).
|
|
8
|
+
|
|
9
|
+
## 1.59.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- e06c1e2: Forced colours show every choice. The chosen `FilterChips` chip sets `forced-color-adjust: none` on its Highlight face, so Chromium's Canvas backplate no longer hides its HighlightText words, and every `SegmentedControl` variant (plain and filled, not only the icon and raised tracks) outlines its selected item in Highlight. No API change.
|
|
14
|
+
|
|
3
15
|
## 1.59.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
Hero,
|
|
40
40
|
ScreenPreview,
|
|
41
41
|
PreviewGroup,
|
|
42
|
+
PreviewImage,
|
|
42
43
|
PreviewRow,
|
|
43
44
|
PreviewTiles,
|
|
44
45
|
SiteFooter,
|
|
@@ -1176,6 +1177,8 @@ const { headings, omissions } = inspectMarkdown(page.body, {
|
|
|
1176
1177
|
|
|
1177
1178
|
`ScreenPreview` is a drawn stand-in for an app's screen on a public page, until a real screenshot replaces it: a `figure` whose screen is one image (`role="img"`) named by `label`, its alternative text, so a screen reader hears that sentence instead of the rows; an optional `caption` shows under it as the `figcaption`. An optional `eyebrow` and `title` head the screen. Its content is `PreviewGroup`s of `PreviewRow`s (`label` at the start, `value` at the end in tabular numerals; `kind` `plain`, `total` in bold past a hairline, `note` a small label over its words, `filled` on the quiet fill, or `alert` on the danger tint) and `PreviewTiles` (`items` of `{ id, label, value }`, three to a row on a phone, six from `md`). `frame="card"` (default) is a surface card whose groups are parted by hairlines; `frame="device"` draws a 20rem phone from `md` (a bezel in the text colour round a quiet screen with a surface header and each group a card) and the card below `md`. A blank `label`, an unknown `frame` or `kind`, no tiles, or a blank or repeated tile id throws a `RangeError`.
|
|
1178
1179
|
|
|
1180
|
+
When the real screenshot exists, a `PreviewImage` (`src`, `width`, `height`) holds it in the same frame, filling the screen's body with its height following. It is decorative: `label` stays the alternative text.
|
|
1181
|
+
|
|
1179
1182
|
```tsx
|
|
1180
1183
|
<ScreenPreview
|
|
1181
1184
|
frame="device"
|
|
@@ -12,14 +12,15 @@ export type ScreenPreviewProps = Omit<HTMLAttributes<HTMLElement>, 'children' |
|
|
|
12
12
|
title?: ReactNode;
|
|
13
13
|
/** A visible caption under the screen, such as what will replace it. */
|
|
14
14
|
caption?: ReactNode;
|
|
15
|
-
/** `PreviewGroup`s, `PreviewRow`s
|
|
15
|
+
/** `PreviewGroup`s, `PreviewRow`s, `PreviewTiles` or a `PreviewImage`. */
|
|
16
16
|
children: ReactNode;
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
19
|
* A drawn stand-in for an app's screen on a public page: a `figure` whose
|
|
20
20
|
* screen is one image (`role="img"`) named by `label`, so its rows are
|
|
21
21
|
* read as that one sentence, with an optional visible `caption`. Its
|
|
22
|
-
* content is `PreviewGroup`s of `PreviewRow`s
|
|
22
|
+
* content is `PreviewGroup`s of `PreviewRow`s, `PreviewTiles` or a
|
|
23
|
+
* `PreviewImage` holding a real screenshot. A blank
|
|
23
24
|
* label or an unknown frame throws a `RangeError`.
|
|
24
25
|
*/
|
|
25
26
|
export declare function ScreenPreview({ caption, children, className, eyebrow, frame, label, title, ...rest }: ScreenPreviewProps): import("react").JSX.Element;
|
|
@@ -7,7 +7,8 @@ export { screenPreviewFrames };
|
|
|
7
7
|
* A drawn stand-in for an app's screen on a public page: a `figure` whose
|
|
8
8
|
* screen is one image (`role="img"`) named by `label`, so its rows are
|
|
9
9
|
* read as that one sentence, with an optional visible `caption`. Its
|
|
10
|
-
* content is `PreviewGroup`s of `PreviewRow`s
|
|
10
|
+
* content is `PreviewGroup`s of `PreviewRow`s, `PreviewTiles` or a
|
|
11
|
+
* `PreviewImage` holding a real screenshot. A blank
|
|
11
12
|
* label or an unknown frame throws a `RangeError`.
|
|
12
13
|
*/
|
|
13
14
|
export function ScreenPreview({ caption, children, className, eyebrow, frame = 'card', label, title, ...rest }) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The file and its natural size in pixels, so the page keeps its place while it loads. */
|
|
2
|
+
export type PreviewImageProps = {
|
|
3
|
+
src: string;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A real screenshot inside a `ScreenPreview`, drawn at the width of the
|
|
9
|
+
* screen with its height following. It is decorative (`alt=""`): the
|
|
10
|
+
* preview's `label` already says what it shows. A blank `src` or a size
|
|
11
|
+
* that is not a positive whole number throws a `RangeError`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function PreviewImage({ height, src, width }: PreviewImageProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A real screenshot inside a `ScreenPreview`, drawn at the width of the
|
|
4
|
+
* screen with its height following. It is decorative (`alt=""`): the
|
|
5
|
+
* preview's `label` already says what it shows. A blank `src` or a size
|
|
6
|
+
* that is not a positive whole number throws a `RangeError`.
|
|
7
|
+
*/
|
|
8
|
+
export function PreviewImage({ height, src, width }) {
|
|
9
|
+
if (!src.trim())
|
|
10
|
+
throw new RangeError('A PreviewImage needs a src');
|
|
11
|
+
for (const [name, side] of [
|
|
12
|
+
['width', width],
|
|
13
|
+
['height', height],
|
|
14
|
+
])
|
|
15
|
+
if (!Number.isInteger(side) || side <= 0)
|
|
16
|
+
throw new RangeError(`A PreviewImage's ${name} must be a positive whole number, not ${side}`);
|
|
17
|
+
return (_jsx("img", { alt: "", className: "sw-preview-image", height: height, loading: "lazy", src: src, width: width }));
|
|
18
|
+
}
|
|
@@ -135,7 +135,8 @@ ${cssFilterChipsRowClasses()}
|
|
|
135
135
|
@media (forced-colors: active) {
|
|
136
136
|
.sw-filter-chip-face { background: Canvas; border-color: CanvasText; color: CanvasText; }
|
|
137
137
|
.sw-filter-chips-error { color: Mark; }
|
|
138
|
-
|
|
138
|
+
/* Chromium paints a Canvas backplate behind text in forced colours; HighlightText on it vanishes. */
|
|
139
|
+
.sw-filter-chip-input:checked + .sw-filter-chip-face { background: Highlight; border-color: Highlight; color: HighlightText; forced-color-adjust: none; }
|
|
139
140
|
.sw-filter-chip-input:focus-visible + .sw-filter-chip-face { outline-color: Highlight; }
|
|
140
141
|
.sw-filter-chip-count { color: inherit; }
|
|
141
142
|
/* After the checked rule, so every chip, the chosen one too, takes the edge. */
|
|
@@ -2,9 +2,11 @@ import { mutedReadsAsText, quietFill } from './quiet-fill.js';
|
|
|
2
2
|
/*
|
|
3
3
|
* The action sits after the row in its own column, centred on the row's
|
|
4
4
|
* height, outside the row's press area, keeping the row's end padding
|
|
5
|
-
* after it.
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
5
|
+
* after it. It ends at the column's end, so a short action on one row and
|
|
6
|
+
* a long one on the next finish on the same line. Where :has() is supported
|
|
7
|
+
* the hover fill spans the whole item, so the row, its select and its action
|
|
8
|
+
* read as one line; a detail under the row is on that fill too, so its muted
|
|
9
|
+
* words take the text colour.
|
|
8
10
|
*/
|
|
9
11
|
function actionRules() {
|
|
10
12
|
return `.sw-fixture-action {
|
|
@@ -13,6 +15,7 @@ function actionRules() {
|
|
|
13
15
|
display: inline-flex;
|
|
14
16
|
grid-column: -2 / -1;
|
|
15
17
|
grid-row: 1;
|
|
18
|
+
justify-content: flex-end;
|
|
16
19
|
padding-inline-end: var(--sw-space-2);
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -87,6 +87,16 @@ function cardRules() {
|
|
|
87
87
|
line-height: ${caption.lineHeight}px;
|
|
88
88
|
}`;
|
|
89
89
|
}
|
|
90
|
+
/* A screenshot fills the screen's width; its height follows. */
|
|
91
|
+
function imageRules() {
|
|
92
|
+
return `.sw-preview-image {
|
|
93
|
+
border-radius: var(--sw-radius-sm);
|
|
94
|
+
display: block;
|
|
95
|
+
height: auto;
|
|
96
|
+
max-width: 100%;
|
|
97
|
+
width: 100%;
|
|
98
|
+
}`;
|
|
99
|
+
}
|
|
90
100
|
function rowRules() {
|
|
91
101
|
return `.sw-preview-row {
|
|
92
102
|
display: flex;
|
|
@@ -206,7 +216,7 @@ function wideRules() {
|
|
|
206
216
|
}`;
|
|
207
217
|
}
|
|
208
218
|
export function cssScreenPreviewClasses() {
|
|
209
|
-
return [cardRules(), rowRules(), wideRules()].join('\n\n');
|
|
219
|
+
return [cardRules(), imageRules(), rowRules(), wideRules()].join('\n\n');
|
|
210
220
|
}
|
|
211
221
|
export function screenPreviewClassCatalog() {
|
|
212
222
|
return [
|
|
@@ -224,6 +234,7 @@ export function screenPreviewClassCatalog() {
|
|
|
224
234
|
...previewRowKinds.map(previewRowKindClass),
|
|
225
235
|
'sw-preview-row-label',
|
|
226
236
|
'sw-preview-row-value',
|
|
237
|
+
'sw-preview-image',
|
|
227
238
|
'sw-preview-tiles',
|
|
228
239
|
'sw-preview-tile',
|
|
229
240
|
'sw-preview-tile-label',
|
|
@@ -99,6 +99,8 @@ function fieldRules() {
|
|
|
99
99
|
|
|
100
100
|
@media (forced-colors: active) {
|
|
101
101
|
.sw-segmented[aria-invalid='true'] { border-color: Mark; }
|
|
102
|
+
/* Every variant's chosen item: its surface or accent fill is dropped. */
|
|
103
|
+
.sw-segmented-item-selected { outline: 2px solid Highlight; }
|
|
102
104
|
}`;
|
|
103
105
|
}
|
|
104
106
|
export function cssSegmentedClasses() {
|
package/dist/index.d.ts
CHANGED
|
@@ -90,6 +90,8 @@ export type { SiteHeaderItem, SiteHeaderLabels, SiteHeaderProps, SiteHeaderSkipL
|
|
|
90
90
|
export { ScreenPreview, screenPreviewFrames, } from './components/ScreenPreview.js';
|
|
91
91
|
export type { ScreenPreviewFrame, ScreenPreviewProps, } from './components/ScreenPreview.js';
|
|
92
92
|
export { PreviewGroup } from './components/screen-preview/PreviewGroup.js';
|
|
93
|
+
export { PreviewImage } from './components/screen-preview/PreviewImage.js';
|
|
94
|
+
export type { PreviewImageProps } from './components/screen-preview/PreviewImage.js';
|
|
93
95
|
export { PreviewRow, previewRowKinds, } from './components/screen-preview/PreviewRow.js';
|
|
94
96
|
export type { PreviewRowKind, PreviewRowProps, } from './components/screen-preview/PreviewRow.js';
|
|
95
97
|
export { PreviewTiles } from './components/screen-preview/PreviewTiles.js';
|
package/dist/index.js
CHANGED
|
@@ -81,6 +81,7 @@ export { Band, bandElements, bandTones, bandWidths, } from './components/Band.js
|
|
|
81
81
|
export { SiteHeader } from './components/SiteHeader.js';
|
|
82
82
|
export { ScreenPreview, screenPreviewFrames, } from './components/ScreenPreview.js';
|
|
83
83
|
export { PreviewGroup } from './components/screen-preview/PreviewGroup.js';
|
|
84
|
+
export { PreviewImage } from './components/screen-preview/PreviewImage.js';
|
|
84
85
|
export { PreviewRow, previewRowKinds, } from './components/screen-preview/PreviewRow.js';
|
|
85
86
|
export { PreviewTiles } from './components/screen-preview/PreviewTiles.js';
|
|
86
87
|
export { Hero } from './components/Hero.js';
|
package/dist/styles.css
CHANGED
|
@@ -1546,6 +1546,8 @@ body {
|
|
|
1546
1546
|
|
|
1547
1547
|
@media (forced-colors: active) {
|
|
1548
1548
|
.sw-segmented[aria-invalid='true'] { border-color: Mark; }
|
|
1549
|
+
/* Every variant's chosen item: its surface or accent fill is dropped. */
|
|
1550
|
+
.sw-segmented-item-selected { outline: 2px solid Highlight; }
|
|
1549
1551
|
}
|
|
1550
1552
|
|
|
1551
1553
|
.sw-segmented {
|
|
@@ -3616,6 +3618,7 @@ button.sw-date-toggle-day[aria-disabled='true'] {
|
|
|
3616
3618
|
display: inline-flex;
|
|
3617
3619
|
grid-column: -2 / -1;
|
|
3618
3620
|
grid-row: 1;
|
|
3621
|
+
justify-content: flex-end;
|
|
3619
3622
|
padding-inline-end: var(--sw-space-2);
|
|
3620
3623
|
}
|
|
3621
3624
|
|
|
@@ -5297,6 +5300,14 @@ button.sw-date-toggle-day[aria-disabled='true'] {
|
|
|
5297
5300
|
line-height: 18px;
|
|
5298
5301
|
}
|
|
5299
5302
|
|
|
5303
|
+
.sw-preview-image {
|
|
5304
|
+
border-radius: var(--sw-radius-sm);
|
|
5305
|
+
display: block;
|
|
5306
|
+
height: auto;
|
|
5307
|
+
max-width: 100%;
|
|
5308
|
+
width: 100%;
|
|
5309
|
+
}
|
|
5310
|
+
|
|
5300
5311
|
.sw-preview-row {
|
|
5301
5312
|
display: flex;
|
|
5302
5313
|
gap: var(--sw-space-3);
|
|
@@ -8953,7 +8964,8 @@ html:has(.sw-site-header-sticky) {
|
|
|
8953
8964
|
@media (forced-colors: active) {
|
|
8954
8965
|
.sw-filter-chip-face { background: Canvas; border-color: CanvasText; color: CanvasText; }
|
|
8955
8966
|
.sw-filter-chips-error { color: Mark; }
|
|
8956
|
-
|
|
8967
|
+
/* Chromium paints a Canvas backplate behind text in forced colours; HighlightText on it vanishes. */
|
|
8968
|
+
.sw-filter-chip-input:checked + .sw-filter-chip-face { background: Highlight; border-color: Highlight; color: HighlightText; forced-color-adjust: none; }
|
|
8957
8969
|
.sw-filter-chip-input:focus-visible + .sw-filter-chip-face { outline-color: Highlight; }
|
|
8958
8970
|
.sw-filter-chip-count { color: inherit; }
|
|
8959
8971
|
/* After the checked rule, so every chip, the chosen one too, takes the edge. */
|