@swiftbrowser/web 0.4.0 → 0.5.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/README.md +1 -0
- package/app/index.html +1 -0
- package/package.json +2 -1
- package/src/largeTitle.ts +4 -1
- package/src/layout/engine.ts +250 -48
- package/src/layout/index.ts +3 -3
- package/src/layoutDom.ts +23 -0
- package/src/page.css +234 -0
- package/src/protocol.ts +32 -1
- package/src/renderer.ts +79 -5
- package/src/scrollEdge.ts +26 -4
- package/src/styles.css +103 -252
- package/src/symbols.ts +3 -1
package/src/styles.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
iOS design tokens. Light values live on the device frame; dark ones switch
|
|
3
|
-
with the frame's data-theme so the page
|
|
4
|
-
independent.
|
|
3
|
+
with the frame's data-theme so the page around it (page.css) and the
|
|
4
|
+
"phone" are independent.
|
|
5
5
|
------------------------------------------------------------------------- */
|
|
6
6
|
|
|
7
7
|
:root {
|
|
@@ -15,15 +15,6 @@
|
|
|
15
15
|
overrides this with the current size (see .device below). */
|
|
16
16
|
--sb-font-size-body: 17px;
|
|
17
17
|
|
|
18
|
-
/* Page chrome (not iOS) */
|
|
19
|
-
--page-bg: #e9e9ee;
|
|
20
|
-
--page-fg: #1c1c1e;
|
|
21
|
-
--page-muted: #6e6e73;
|
|
22
|
-
--page-border: rgba(0, 0, 0, 0.08);
|
|
23
|
-
--page-surface: rgba(255, 255, 255, 0.8);
|
|
24
|
-
--page-error-bg: #ffe5e5;
|
|
25
|
-
--page-error-fg: #a1000d;
|
|
26
|
-
|
|
27
18
|
/* Device dimensions (iPhone 15 Pro logical points) */
|
|
28
19
|
--device-screen-width: 393px;
|
|
29
20
|
--device-screen-height: 852px;
|
|
@@ -41,18 +32,6 @@
|
|
|
41
32
|
--sb-inset-left: env(safe-area-inset-left, 0px);
|
|
42
33
|
}
|
|
43
34
|
|
|
44
|
-
@media (prefers-color-scheme: dark) {
|
|
45
|
-
:root {
|
|
46
|
-
--page-bg: #111114;
|
|
47
|
-
--page-fg: #f2f2f7;
|
|
48
|
-
--page-muted: #98989f;
|
|
49
|
-
--page-border: rgba(255, 255, 255, 0.1);
|
|
50
|
-
--page-surface: rgba(28, 28, 30, 0.85);
|
|
51
|
-
--page-error-bg: #3a0b10;
|
|
52
|
-
--page-error-fg: #ff8a8a;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
35
|
.device {
|
|
57
36
|
/* Dynamic Type: main.ts writes --sb-ts-<style>-size / -lh / -scale on the
|
|
58
37
|
device frame for the selected size (typography.ts); the fallbacks are the
|
|
@@ -164,159 +143,28 @@
|
|
|
164
143
|
}
|
|
165
144
|
|
|
166
145
|
/* ---------------------------------------------------------------------------
|
|
167
|
-
|
|
146
|
+
The renderer's boxes size by their borders. Only its own DOM: a page that
|
|
147
|
+
draws an island (@swiftbrowser/react) keeps its own box model.
|
|
168
148
|
------------------------------------------------------------------------- */
|
|
169
149
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
*::
|
|
150
|
+
.device,
|
|
151
|
+
.device *,
|
|
152
|
+
.device *::before,
|
|
153
|
+
.device *::after {
|
|
173
154
|
box-sizing: border-box;
|
|
174
155
|
}
|
|
175
156
|
|
|
176
|
-
html,
|
|
177
|
-
body {
|
|
178
|
-
margin: 0;
|
|
179
|
-
min-height: 100%;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
body {
|
|
183
|
-
display: flex;
|
|
184
|
-
flex-direction: column;
|
|
185
|
-
min-height: 100vh;
|
|
186
|
-
background: var(--page-bg);
|
|
187
|
-
color: var(--page-fg);
|
|
188
|
-
font-family: var(--sb-font-family);
|
|
189
|
-
font-size: 14px;
|
|
190
|
-
-webkit-font-smoothing: antialiased;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.toolbar {
|
|
194
|
-
position: sticky;
|
|
195
|
-
top: 0;
|
|
196
|
-
z-index: 10;
|
|
197
|
-
display: flex;
|
|
198
|
-
align-items: center;
|
|
199
|
-
gap: 10px;
|
|
200
|
-
padding: 10px 16px;
|
|
201
|
-
background: var(--page-surface);
|
|
202
|
-
border-bottom: 1px solid var(--page-border);
|
|
203
|
-
backdrop-filter: blur(16px);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.toolbar-brand {
|
|
207
|
-
font-weight: 600;
|
|
208
|
-
letter-spacing: -0.01em;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.toolbar-sep {
|
|
212
|
-
width: 1px;
|
|
213
|
-
height: 18px;
|
|
214
|
-
background: var(--page-border);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.toolbar-label {
|
|
218
|
-
color: var(--page-muted);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
.toolbar-value {
|
|
222
|
-
font-variant-numeric: tabular-nums;
|
|
223
|
-
padding: 2px 8px;
|
|
224
|
-
border-radius: 6px;
|
|
225
|
-
background: var(--page-border);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
.toolbar-spacer {
|
|
229
|
-
flex: 1 1 0;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/* Hot-reload indicator, driven by the dev server's sb:build-* events. */
|
|
233
|
-
.toolbar-build {
|
|
234
|
-
display: inline-flex;
|
|
235
|
-
align-items: center;
|
|
236
|
-
gap: 6px;
|
|
237
|
-
color: var(--page-muted);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
.toolbar-build[hidden] {
|
|
241
|
-
display: none;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
.toolbar-build::before {
|
|
245
|
-
content: "";
|
|
246
|
-
width: 10px;
|
|
247
|
-
height: 10px;
|
|
248
|
-
border-radius: 50%;
|
|
249
|
-
border: 1.5px solid currentColor;
|
|
250
|
-
border-top-color: transparent;
|
|
251
|
-
animation: sb-spin 0.9s linear infinite;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.toolbar-build[data-state="error"] {
|
|
255
|
-
color: var(--page-error-fg);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.toolbar-build[data-state="error"]::before {
|
|
259
|
-
animation: none;
|
|
260
|
-
border-color: currentColor;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.toolbar-button {
|
|
264
|
-
font: inherit;
|
|
265
|
-
padding: 6px 12px;
|
|
266
|
-
border: 1px solid var(--page-border);
|
|
267
|
-
border-radius: 8px;
|
|
268
|
-
background: transparent;
|
|
269
|
-
color: var(--page-fg);
|
|
270
|
-
cursor: pointer;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.toolbar-button:hover {
|
|
274
|
-
background: var(--page-border);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.toolbar-button[aria-pressed="true"] {
|
|
278
|
-
background: var(--page-fg);
|
|
279
|
-
color: var(--page-bg);
|
|
280
|
-
border-color: transparent;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.toolbar-select {
|
|
284
|
-
font: inherit;
|
|
285
|
-
padding: 5px 8px;
|
|
286
|
-
border: 1px solid var(--page-border);
|
|
287
|
-
border-radius: 8px;
|
|
288
|
-
background: transparent;
|
|
289
|
-
color: var(--page-fg);
|
|
290
|
-
cursor: pointer;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
.stage {
|
|
294
|
-
display: flex;
|
|
295
|
-
flex-direction: column;
|
|
296
|
-
align-items: center;
|
|
297
|
-
gap: 16px;
|
|
298
|
-
padding: 32px 16px 48px;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
.status {
|
|
302
|
-
max-width: 560px;
|
|
303
|
-
margin: 0;
|
|
304
|
-
padding: 10px 14px;
|
|
305
|
-
border-radius: 10px;
|
|
306
|
-
background: var(--page-error-bg);
|
|
307
|
-
color: var(--page-error-fg);
|
|
308
|
-
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
309
|
-
font-size: 12px;
|
|
310
|
-
white-space: pre-wrap;
|
|
311
|
-
word-break: break-word;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
157
|
/* ---------------------------------------------------------------------------
|
|
315
158
|
Device frame
|
|
316
159
|
------------------------------------------------------------------------- */
|
|
317
160
|
|
|
318
161
|
.device {
|
|
319
162
|
position: relative;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* The iPhone's size and bezel: the frame's only. An island (`.sb-island`,
|
|
166
|
+
below) is the page's box, sized by the page's own CSS. */
|
|
167
|
+
.device:not(.sb-island) {
|
|
320
168
|
flex: 0 0 auto;
|
|
321
169
|
width: calc(var(--device-screen-width) + 2 * var(--device-bezel));
|
|
322
170
|
height: calc(var(--device-screen-height) + 2 * var(--device-bezel));
|
|
@@ -485,53 +333,13 @@ body {
|
|
|
485
333
|
/* ---------------------------------------------------------------------------
|
|
486
334
|
Device mode (html[data-sb-mode="device"], see src/deviceMode.ts)
|
|
487
335
|
|
|
488
|
-
On a real phone there is no
|
|
489
|
-
|
|
490
|
-
status-bar / home-indicator
|
|
491
|
-
(via --sb-inset-*), so it is
|
|
336
|
+
On a real phone there is no fake bezel: the OS draws the status bar and
|
|
337
|
+
#screen fills the viewport (the page's part, its toolbar and background,
|
|
338
|
+
is page.css). The layout engine still gets a status-bar / home-indicator
|
|
339
|
+
safe area, but from env(safe-area-inset-*) (via --sb-inset-*), so it is
|
|
340
|
+
only non-zero in standalone mode / landscape.
|
|
492
341
|
------------------------------------------------------------------------- */
|
|
493
342
|
|
|
494
|
-
html[data-sb-mode="device"] {
|
|
495
|
-
height: 100%;
|
|
496
|
-
overflow: hidden;
|
|
497
|
-
overscroll-behavior: none;
|
|
498
|
-
/* No double-tap zoom, no text inflation in landscape. */
|
|
499
|
-
touch-action: manipulation;
|
|
500
|
-
-webkit-text-size-adjust: 100%;
|
|
501
|
-
text-size-adjust: 100%;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
html[data-sb-mode="device"] body {
|
|
505
|
-
min-height: 100dvh;
|
|
506
|
-
overflow: hidden;
|
|
507
|
-
overscroll-behavior: none;
|
|
508
|
-
touch-action: manipulation;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/* The page behind the app is the OS appearance's system background from the
|
|
512
|
-
first paint (Safari tints its status bar strip from it); chromeColor.ts
|
|
513
|
-
then keeps it at the color the app draws at its top edge. */
|
|
514
|
-
html[data-sb-mode="device"],
|
|
515
|
-
html[data-sb-mode="device"] body {
|
|
516
|
-
background: #ffffff;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
@media (prefers-color-scheme: dark) {
|
|
520
|
-
html[data-sb-mode="device"],
|
|
521
|
-
html[data-sb-mode="device"] body {
|
|
522
|
-
background: #000000;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
html[data-sb-mode="device"] .toolbar {
|
|
527
|
-
display: none;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
html[data-sb-mode="device"] .stage {
|
|
531
|
-
padding: 0;
|
|
532
|
-
gap: 0;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
343
|
html[data-sb-mode="device"] .device {
|
|
536
344
|
position: fixed;
|
|
537
345
|
top: 0;
|
|
@@ -558,18 +366,6 @@ html[data-sb-mode="device"] .device-screen {
|
|
|
558
366
|
border-radius: 0;
|
|
559
367
|
}
|
|
560
368
|
|
|
561
|
-
/* The error banner floats over the app, clear of the home indicator. */
|
|
562
|
-
html[data-sb-mode="device"] .status {
|
|
563
|
-
position: fixed;
|
|
564
|
-
left: 16px;
|
|
565
|
-
right: 16px;
|
|
566
|
-
bottom: calc(16px + var(--sb-inset-bottom));
|
|
567
|
-
z-index: 10;
|
|
568
|
-
max-width: none;
|
|
569
|
-
max-height: 40dvh;
|
|
570
|
-
overflow: auto;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
369
|
/* ---------------------------------------------------------------------------
|
|
574
370
|
Rendered elements
|
|
575
371
|
|
|
@@ -1205,6 +1001,41 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1205
1001
|
display: none;
|
|
1206
1002
|
}
|
|
1207
1003
|
|
|
1004
|
+
/* The More button of the collapsed `.secondaryAction` items: the ellipsis
|
|
1005
|
+
in a 44pt glass circle at the engine's `more` rect (iOS 26). */
|
|
1006
|
+
.sb-navbar-more {
|
|
1007
|
+
appearance: none;
|
|
1008
|
+
display: inline-flex;
|
|
1009
|
+
align-items: center;
|
|
1010
|
+
justify-content: center;
|
|
1011
|
+
margin: 0;
|
|
1012
|
+
padding: 0;
|
|
1013
|
+
border: 0;
|
|
1014
|
+
border-radius: 22px;
|
|
1015
|
+
background: var(--sb-glass-background);
|
|
1016
|
+
box-shadow: var(--sb-glass-shadow);
|
|
1017
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
1018
|
+
-webkit-backdrop-filter: blur(12px) saturate(180%);
|
|
1019
|
+
color: var(--sb-color-primary);
|
|
1020
|
+
font-size: var(--sb-font-size-body);
|
|
1021
|
+
cursor: pointer;
|
|
1022
|
+
touch-action: manipulation;
|
|
1023
|
+
-webkit-tap-highlight-color: transparent;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
.sb-navbar-more[hidden] {
|
|
1027
|
+
display: none;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
.sb-navbar-more:active {
|
|
1031
|
+
opacity: 0.3;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
.sb-navbar-more > svg {
|
|
1035
|
+
width: 1.2em;
|
|
1036
|
+
height: 1.2em;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1208
1039
|
.sb-navbar-back:active {
|
|
1209
1040
|
opacity: 0.3;
|
|
1210
1041
|
}
|
|
@@ -1337,8 +1168,12 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1337
1168
|
mask-image: linear-gradient(to bottom, #000 60%, transparent);
|
|
1338
1169
|
}
|
|
1339
1170
|
|
|
1171
|
+
/* Its strength follows the content under the bar, ramping up over the
|
|
1172
|
+
first 40px scrolled (`--sb-edge-top`, src/scrollEdge.ts); the transition
|
|
1173
|
+
smooths a scroll that jumps. */
|
|
1340
1174
|
.sb-navscreen[data-sb-scrolled] > .sb-navbar::before {
|
|
1341
|
-
opacity: 1;
|
|
1175
|
+
opacity: var(--sb-edge-top, 1);
|
|
1176
|
+
transition: opacity 0.12s linear;
|
|
1342
1177
|
}
|
|
1343
1178
|
|
|
1344
1179
|
/* At the bottom: a list or scroll view runs under the tab bar, or its
|
|
@@ -1369,21 +1204,24 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1369
1204
|
pointer-events: none;
|
|
1370
1205
|
opacity: 0;
|
|
1371
1206
|
transition: opacity 0.2s ease;
|
|
1207
|
+
/* iOS 26 mostly fades the content here (it stays faintly legible under
|
|
1208
|
+
the bar) and barely blurs it. */
|
|
1372
1209
|
background: linear-gradient(
|
|
1373
1210
|
to top,
|
|
1374
|
-
var(--sb-edge-color) 0%,
|
|
1375
|
-
color-mix(in srgb, var(--sb-edge-color)
|
|
1211
|
+
color-mix(in srgb, var(--sb-edge-color) 70%, transparent) 0%,
|
|
1212
|
+
color-mix(in srgb, var(--sb-edge-color) 55%, transparent) 45%,
|
|
1376
1213
|
transparent 100%
|
|
1377
1214
|
);
|
|
1378
|
-
-webkit-backdrop-filter: blur(
|
|
1379
|
-
backdrop-filter: blur(
|
|
1215
|
+
-webkit-backdrop-filter: blur(1.5px);
|
|
1216
|
+
backdrop-filter: blur(1.5px);
|
|
1380
1217
|
-webkit-mask-image: linear-gradient(to top, #000 60%, transparent);
|
|
1381
1218
|
mask-image: linear-gradient(to top, #000 60%, transparent);
|
|
1382
1219
|
}
|
|
1383
1220
|
|
|
1384
1221
|
.sb-navscreen[data-sb-scrolled-bottom] > .sb-navscreen-body::after,
|
|
1385
1222
|
.sb-tab[data-sb-scrolled-bottom]::after {
|
|
1386
|
-
opacity: 1;
|
|
1223
|
+
opacity: var(--sb-edge-bottom, 1);
|
|
1224
|
+
transition: opacity 0.12s linear;
|
|
1387
1225
|
}
|
|
1388
1226
|
|
|
1389
1227
|
/* `.scrollEdgeEffectStyle(.hard, for:)`: an opaque backing exactly behind
|
|
@@ -2039,6 +1877,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2039
1877
|
.sb-grid,
|
|
2040
1878
|
.sb-gridrow,
|
|
2041
1879
|
.sb-lazyvgrid,
|
|
1880
|
+
.sb-lazyhgrid,
|
|
2042
1881
|
.sb-decorated {
|
|
2043
1882
|
display: block;
|
|
2044
1883
|
}
|
|
@@ -2293,6 +2132,13 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2293
2132
|
display: block;
|
|
2294
2133
|
}
|
|
2295
2134
|
|
|
2135
|
+
/* A toolbar the engine hid (a spacer, `secondary` items collapsed into the
|
|
2136
|
+
More menu), and its items collapsed one by one, draw nothing. */
|
|
2137
|
+
.sb-toolbar[hidden],
|
|
2138
|
+
.sb-toolbar > [data-sb-id][hidden] {
|
|
2139
|
+
display: none;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2296
2142
|
/* iOS 26: a bar's leading and trailing items share a glass capsule (the
|
|
2297
2143
|
engine sizes the group: 44 tall, each item in a slot at least 44 wide),
|
|
2298
2144
|
drawn in the label color unless tinted. */
|
|
@@ -2315,30 +2161,41 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2315
2161
|
|
|
2316
2162
|
/* Their symbols are drawn a little larger and heavier (semibold), as iOS 26
|
|
2317
2163
|
draws bar buttons: a plus is 17.7 pt with 2.33 pt bars there. */
|
|
2318
|
-
.sb-toolbar:is([data-sb-placement="leading"], [data-sb-placement="trailing"]) .sb-image > svg {
|
|
2164
|
+
.sb-toolbar:is([data-sb-placement="leading"], [data-sb-placement="trailing"], [data-sb-placement="bottom"]) .sb-image > svg {
|
|
2319
2165
|
width: 1.57em;
|
|
2320
2166
|
height: 1.57em;
|
|
2321
2167
|
stroke-width: 1.85;
|
|
2322
2168
|
}
|
|
2323
2169
|
|
|
2170
|
+
/* A bottom toolbar's symbols are as large but regular weight. */
|
|
2171
|
+
.sb-toolbar[data-sb-placement="bottom"] .sb-image > svg {
|
|
2172
|
+
stroke-width: 1.5;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
/* iOS 26: a bottom toolbar's items float over the content on Liquid Glass
|
|
2176
|
+
capsules (engine `bottomGlass0` …, src/layoutDom.ts), drawn in the label
|
|
2177
|
+
color unless tinted, above the scroll edge effect. */
|
|
2324
2178
|
.sb-toolbar[data-sb-placement="bottom"] {
|
|
2325
2179
|
z-index: 3;
|
|
2326
|
-
|
|
2327
|
-
backdrop-filter: blur(20px) saturate(180%);
|
|
2328
|
-
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
2180
|
+
--sb-color-accent: var(--sb-color-primary);
|
|
2329
2181
|
}
|
|
2330
2182
|
|
|
2331
|
-
.sb-
|
|
2332
|
-
content: "";
|
|
2183
|
+
.sb-bottom-glass {
|
|
2333
2184
|
position: absolute;
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2185
|
+
z-index: 2;
|
|
2186
|
+
border-radius: 24px;
|
|
2187
|
+
background: var(--sb-glass-background);
|
|
2188
|
+
box-shadow: var(--sb-glass-shadow);
|
|
2189
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
2190
|
+
-webkit-backdrop-filter: blur(12px) saturate(180%);
|
|
2339
2191
|
pointer-events: none;
|
|
2340
2192
|
}
|
|
2341
2193
|
|
|
2194
|
+
/* A ToolbarSpacer draws nothing (the engine also hides it). */
|
|
2195
|
+
.sb-toolbar[data-sb-spacer] {
|
|
2196
|
+
display: none;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2342
2199
|
/* Search field: a capsule (engine `searchField` rect) with a
|
|
2343
2200
|
magnifier leading; the input sends `text` events like a textfield. */
|
|
2344
2201
|
.sb-searchfield {
|
|
@@ -2641,6 +2498,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2641
2498
|
.sb-grid,
|
|
2642
2499
|
.sb-gridrow,
|
|
2643
2500
|
.sb-lazyvgrid,
|
|
2501
|
+
.sb-lazyhgrid,
|
|
2644
2502
|
.sb-viewthatfits,
|
|
2645
2503
|
.sb-decorated,
|
|
2646
2504
|
.sb-gesture,
|
|
@@ -2648,8 +2506,8 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2648
2506
|
pointer-events: none;
|
|
2649
2507
|
}
|
|
2650
2508
|
|
|
2651
|
-
:is(.sb-vstack, .sb-hstack, .sb-zstack, .sb-styled, .sb-geometry, .sb-layout, .sb-grid, .sb-gridrow, .sb-lazyvgrid, .sb-viewthatfits, .sb-decorated, .sb-gesture, .sb-tapgesture)
|
|
2652
|
-
> [data-sb-kind]:not(.sb-vstack, .sb-hstack, .sb-zstack, .sb-spacer, .sb-styled, .sb-geometry, .sb-layout, .sb-grid, .sb-gridrow, .sb-lazyvgrid, .sb-viewthatfits, .sb-decorated, .sb-gesture, .sb-tapgesture) {
|
|
2509
|
+
:is(.sb-vstack, .sb-hstack, .sb-zstack, .sb-styled, .sb-geometry, .sb-layout, .sb-grid, .sb-gridrow, .sb-lazyvgrid, .sb-lazyhgrid, .sb-viewthatfits, .sb-decorated, .sb-gesture, .sb-tapgesture)
|
|
2510
|
+
> [data-sb-kind]:not(.sb-vstack, .sb-hstack, .sb-zstack, .sb-spacer, .sb-styled, .sb-geometry, .sb-layout, .sb-grid, .sb-gridrow, .sb-lazyvgrid, .sb-lazyhgrid, .sb-viewthatfits, .sb-decorated, .sb-gesture, .sb-tapgesture) {
|
|
2653
2511
|
pointer-events: auto;
|
|
2654
2512
|
}
|
|
2655
2513
|
|
|
@@ -3629,19 +3487,12 @@ svg.sb-path {
|
|
|
3629
3487
|
|
|
3630
3488
|
/* ---------------------------------------------------------------------------
|
|
3631
3489
|
Islands (@swiftbrowser/react's `SwiftUIView`): a SwiftUI root inside a
|
|
3632
|
-
page's own layout, with the device's tokens and none of its frame
|
|
3633
|
-
|
|
3490
|
+
page's own layout, with the device's tokens and none of its frame: the
|
|
3491
|
+
frame's size, bezel and shadow are `.device:not(.sb-island)`'s above, so
|
|
3492
|
+
the page's own CSS, however specific, gives the island its width and
|
|
3493
|
+
height. In `content` fit the renderer sets the root's height
|
|
3634
3494
|
from the layout.
|
|
3635
3495
|
------------------------------------------------------------------------- */
|
|
3636
|
-
.device.sb-island {
|
|
3637
|
-
width: auto;
|
|
3638
|
-
padding: 0;
|
|
3639
|
-
border-radius: 0;
|
|
3640
|
-
background: none;
|
|
3641
|
-
box-shadow: none;
|
|
3642
|
-
flex: initial;
|
|
3643
|
-
}
|
|
3644
|
-
|
|
3645
3496
|
.device.sb-island::before,
|
|
3646
3497
|
.device.sb-island::after {
|
|
3647
3498
|
display: none;
|
package/src/symbols.ts
CHANGED
|
@@ -215,6 +215,7 @@ import {
|
|
|
215
215
|
Link2,
|
|
216
216
|
List,
|
|
217
217
|
ListChecks,
|
|
218
|
+
ListFilter,
|
|
218
219
|
ListIndentIncrease,
|
|
219
220
|
ListMusic,
|
|
220
221
|
ListOrdered,
|
|
@@ -571,7 +572,8 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
571
572
|
'tag.fill': solid(Tag),
|
|
572
573
|
textformat: outline(CaseSensitive),
|
|
573
574
|
'line.3.horizontal': outline(Menu),
|
|
574
|
-
|
|
575
|
+
// Three lines, each shorter than the one above.
|
|
576
|
+
'line.3.horizontal.decrease': outline(ListFilter),
|
|
575
577
|
'line.3.horizontal.decrease.circle': outline(Funnel),
|
|
576
578
|
'slider.horizontal.3': outline(SlidersHorizontal),
|
|
577
579
|
'list.bullet': outline(List),
|