@swiftbrowser/web 0.18.2 → 0.19.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/package.json +1 -1
- package/src/audioEngine.ts +1443 -0
- package/src/chartDom.ts +1 -1
- package/src/hostRequests.ts +10 -0
- package/src/languageModel.ts +309 -0
- package/src/layout/engine.ts +126 -48
- package/src/layoutDom.ts +43 -3
- package/src/protocol.ts +29 -4
- package/src/renderer.ts +167 -43
- package/src/styles.css +207 -35
- package/src/styles.ts +4 -9
- package/src/symbols.ts +6 -0
package/src/styles.css
CHANGED
|
@@ -67,6 +67,9 @@
|
|
|
67
67
|
--sb-color-tertiary-system-background: #ffffff;
|
|
68
68
|
--sb-color-tertiary-system-grouped-background: #f2f2f7;
|
|
69
69
|
--sb-color-opaque-separator: #c6c6c8;
|
|
70
|
+
/* The stepper's capsule and the line between its halves. */
|
|
71
|
+
--sb-stepper-fill: var(--sb-color-tertiary-fill);
|
|
72
|
+
--sb-stepper-divider: var(--sb-color-opaque-separator);
|
|
70
73
|
--sb-color-system-gray2: #aeaeb2;
|
|
71
74
|
--sb-color-system-gray3: #c7c7cc;
|
|
72
75
|
--sb-color-system-gray4: #d1d1d6;
|
|
@@ -115,7 +118,7 @@
|
|
|
115
118
|
--sb-color-segment-selected: #ffffff;
|
|
116
119
|
/* Menus, floating sheets and alerts are Liquid Glass too: translucent
|
|
117
120
|
over a heavier backdrop blur, with the glass rim. */
|
|
118
|
-
--sb-color-menu-background: rgba(250, 250, 250, 0.
|
|
121
|
+
--sb-color-menu-background: rgba(250, 250, 250, 0.97);
|
|
119
122
|
--sb-sheet-glass: rgba(255, 255, 255, 0.55);
|
|
120
123
|
}
|
|
121
124
|
|
|
@@ -141,6 +144,11 @@
|
|
|
141
144
|
--sb-color-tertiary-system-background: #2c2c2e;
|
|
142
145
|
--sb-color-tertiary-system-grouped-background: #2c2c2e;
|
|
143
146
|
--sb-color-opaque-separator: #38383a;
|
|
147
|
+
/* iOS 26 in dark mode, measured: a fainter capsule than the tertiary fill
|
|
148
|
+
(rgba(120,120,128,.15) reads (18,18,19) over black) and a divider in the
|
|
149
|
+
tertiary label color ((83,83,86) over it). */
|
|
150
|
+
--sb-stepper-fill: rgba(120, 120, 128, 0.15);
|
|
151
|
+
--sb-stepper-divider: rgba(235, 235, 245, 0.3);
|
|
144
152
|
--sb-color-system-gray2: #636366;
|
|
145
153
|
--sb-color-system-gray3: #48484a;
|
|
146
154
|
--sb-color-system-gray4: #3a3a3c;
|
|
@@ -177,7 +185,7 @@
|
|
|
177
185
|
--sb-color-tabbar-background: rgba(29, 29, 29, 0.94);
|
|
178
186
|
--sb-color-segment-track: rgba(118, 118, 128, 0.24);
|
|
179
187
|
--sb-color-segment-selected: #5a5a5f;
|
|
180
|
-
--sb-color-menu-background: rgba(
|
|
188
|
+
--sb-color-menu-background: rgba(44, 44, 46, 0.97);
|
|
181
189
|
/* The iPhone's dark floating sheet reads 42 over black: dark gray glass. */
|
|
182
190
|
--sb-sheet-glass: rgba(60, 60, 60, 0.7);
|
|
183
191
|
}
|
|
@@ -417,6 +425,16 @@ html[data-sb-mode="device"] .device {
|
|
|
417
425
|
}
|
|
418
426
|
|
|
419
427
|
html[data-sb-mode="device"] .device::before,
|
|
428
|
+
/* `.statusBarHidden` on the screen showing: the drawn status bar fades, as
|
|
429
|
+
iOS fades the real one (the safe area stays, as it does under a notch). */
|
|
430
|
+
.status-bar {
|
|
431
|
+
transition: opacity 0.25s ease;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
html[data-sb-status-hidden] .status-bar {
|
|
435
|
+
opacity: 0;
|
|
436
|
+
}
|
|
437
|
+
|
|
420
438
|
html[data-sb-mode="device"] .device::after,
|
|
421
439
|
html[data-sb-mode="device"] .dynamic-island,
|
|
422
440
|
html[data-sb-mode="device"] .status-bar,
|
|
@@ -585,6 +603,21 @@ html[data-sb-mode="device"] .device-screen {
|
|
|
585
603
|
user-select: none;
|
|
586
604
|
}
|
|
587
605
|
|
|
606
|
+
/* Text is not selectable, as on iOS, unless `.textSelection(.enabled)` is
|
|
607
|
+
on it or above it (the renderer marks that box). Fields and editors are
|
|
608
|
+
inputs, selectable as ever. */
|
|
609
|
+
.sb-text {
|
|
610
|
+
user-select: none;
|
|
611
|
+
-webkit-user-select: none;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
[data-sb-text-selection] .sb-text,
|
|
615
|
+
.sb-text[data-sb-text-selection] {
|
|
616
|
+
user-select: text;
|
|
617
|
+
-webkit-user-select: text;
|
|
618
|
+
-webkit-touch-callout: default;
|
|
619
|
+
}
|
|
620
|
+
|
|
588
621
|
/* Image(systemName:): a 1em glyph centered in its line-height square; the
|
|
589
622
|
renderer sets font-size from the resolved font. */
|
|
590
623
|
.sb-image {
|
|
@@ -1010,6 +1043,13 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1010
1043
|
background: transparent;
|
|
1011
1044
|
}
|
|
1012
1045
|
|
|
1046
|
+
/* A card of clear rows alone paints nothing, so it clips nothing either: a
|
|
1047
|
+
search field drawn in such a row (Notes', Reminders', Files') keeps its own
|
|
1048
|
+
corners instead of the card's larger ones cutting them. */
|
|
1049
|
+
.sb-section-rows:not(:has(> [data-sb-id]:not([data-sb-row-background='clear']))) {
|
|
1050
|
+
overflow: visible;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1013
1053
|
.sb-list-content > :not(.sb-section):first-child,
|
|
1014
1054
|
.sb-list-content > .sb-section + :not(.sb-section) {
|
|
1015
1055
|
border-top-left-radius: 26px;
|
|
@@ -1127,6 +1167,12 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1127
1167
|
background: var(--sb-color-grouped-background);
|
|
1128
1168
|
}
|
|
1129
1169
|
|
|
1170
|
+
/* So does a tab with a list as its content: the list is inset from the
|
|
1171
|
+
horizontal safe area (a phone on its side), the tab fills it. */
|
|
1172
|
+
.sb-tab:has(> .sb-list:not([data-sb-background="hidden"])) {
|
|
1173
|
+
background: var(--sb-color-grouped-background);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1130
1176
|
/* Screens below the top one slide partially left and are hidden once the
|
|
1131
1177
|
transition has finished. */
|
|
1132
1178
|
.sb-navscreen[data-sb-nav-position="below"] {
|
|
@@ -1220,6 +1266,19 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1220
1266
|
pointer-events: auto;
|
|
1221
1267
|
}
|
|
1222
1268
|
|
|
1269
|
+
/* `.toolbar(.hidden, for: .navigationBar)`: the bar fades where it was (its
|
|
1270
|
+
items are gone from the layout; the capsules play their exit). */
|
|
1271
|
+
.sb-navbar {
|
|
1272
|
+
transition:
|
|
1273
|
+
opacity 0.25s ease,
|
|
1274
|
+
visibility 0.25s;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
.sb-navscreen[data-sb-bar-hidden] > .sb-navbar {
|
|
1278
|
+
opacity: 0;
|
|
1279
|
+
visibility: hidden;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1223
1282
|
.sb-navbar-trailing:empty {
|
|
1224
1283
|
pointer-events: none;
|
|
1225
1284
|
}
|
|
@@ -1810,24 +1869,26 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
1810
1869
|
background: var(--sb-color-system-background);
|
|
1811
1870
|
}
|
|
1812
1871
|
|
|
1813
|
-
/* `sidebar` (iPadOS; a NavigationSplitView's sidebar list)
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
`insetGrouped` with
|
|
1817
|
-
.
|
|
1818
|
-
|
|
1819
|
-
.sb-list[data-sb-list-
|
|
1820
|
-
.sb-list[data-sb-list-
|
|
1872
|
+
/* `sidebar` (iPadOS; a NavigationSplitView's sidebar list) in a regular
|
|
1873
|
+
width (layoutDom's `data-sb-list-look`): the rows sit on the list's
|
|
1874
|
+
background, without cards or hairlines, and only a selected row is filled
|
|
1875
|
+
(its rounded fill, below). The engine lays it out like `insetGrouped` with
|
|
1876
|
+
44pt rows. In a compact width the list looks like `insetGrouped`; its
|
|
1877
|
+
sections still fold (above). */
|
|
1878
|
+
.sb-list[data-sb-list-look="sidebar"] .sb-section-rows,
|
|
1879
|
+
.sb-list[data-sb-list-look="sidebar"] .sb-section-rows > [data-sb-id],
|
|
1880
|
+
.sb-list[data-sb-list-look="sidebar"] .sb-section-rows > [data-sb-ghost],
|
|
1881
|
+
.sb-list[data-sb-list-look="sidebar"] > .sb-list-content > :not(.sb-section) {
|
|
1821
1882
|
background: transparent;
|
|
1822
1883
|
border-radius: 0;
|
|
1823
1884
|
}
|
|
1824
1885
|
|
|
1825
|
-
.sb-list[data-sb-list-
|
|
1826
|
-
.sb-list[data-sb-list-
|
|
1886
|
+
.sb-list[data-sb-list-look="sidebar"] .sb-section-rows > *::after,
|
|
1887
|
+
.sb-list[data-sb-list-look="sidebar"] > .sb-list-content > :not(.sb-section)::after {
|
|
1827
1888
|
display: none;
|
|
1828
1889
|
}
|
|
1829
1890
|
|
|
1830
|
-
.sb-list[data-sb-list-
|
|
1891
|
+
.sb-list[data-sb-list-look="sidebar"] :is(.sb-section-rows, .sb-list-content) > :is(input, textarea) {
|
|
1831
1892
|
background-image: none;
|
|
1832
1893
|
}
|
|
1833
1894
|
|
|
@@ -2118,13 +2179,17 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2118
2179
|
stroke-width: 2.5;
|
|
2119
2180
|
}
|
|
2120
2181
|
|
|
2121
|
-
/* The option menu
|
|
2182
|
+
/* The option menu, as iOS 26 draws one: an inset panel (10px above and
|
|
2183
|
+
below the rows, 12px beside them) with large rounded corners, anchored
|
|
2184
|
+
under (or above) the control by the renderer, over a toolbar button.
|
|
2122
2185
|
Closed, it fades out where it was (`.sb-picker-menu-exit`) and leaves. */
|
|
2123
2186
|
.sb-picker-menu,
|
|
2124
2187
|
.sb-picker-menu-exit {
|
|
2125
2188
|
position: absolute;
|
|
2126
2189
|
z-index: 6;
|
|
2127
|
-
|
|
2190
|
+
box-sizing: border-box;
|
|
2191
|
+
padding: 10px 12px;
|
|
2192
|
+
border-radius: 26px;
|
|
2128
2193
|
background: var(--sb-color-menu-background);
|
|
2129
2194
|
backdrop-filter: blur(40px) saturate(180%);
|
|
2130
2195
|
-webkit-backdrop-filter: blur(40px) saturate(180%);
|
|
@@ -2154,12 +2219,13 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2154
2219
|
appearance: none;
|
|
2155
2220
|
display: flex;
|
|
2156
2221
|
align-items: center;
|
|
2157
|
-
gap:
|
|
2222
|
+
gap: 13px;
|
|
2158
2223
|
width: 100%;
|
|
2159
2224
|
height: 44px;
|
|
2160
2225
|
margin: 0;
|
|
2161
2226
|
padding: 0 16px;
|
|
2162
2227
|
border: 0;
|
|
2228
|
+
border-radius: 14px;
|
|
2163
2229
|
background: none;
|
|
2164
2230
|
color: var(--sb-color-primary);
|
|
2165
2231
|
font: 400 var(--sb-font-size-body) / 1.3 var(--sb-font-family);
|
|
@@ -2169,19 +2235,19 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2169
2235
|
-webkit-tap-highlight-color: transparent;
|
|
2170
2236
|
}
|
|
2171
2237
|
|
|
2172
|
-
:is(.sb-picker-menu-item, .sb-picker-menu-static) + :is(.sb-picker-menu-item, .sb-picker-menu-static) {
|
|
2173
|
-
box-shadow: inset 0 1px 0 var(--sb-color-separator);
|
|
2174
|
-
}
|
|
2175
|
-
|
|
2176
2238
|
.sb-picker-menu-item:active {
|
|
2177
2239
|
background: var(--sb-color-fill);
|
|
2178
2240
|
}
|
|
2179
2241
|
|
|
2242
|
+
/* The checkmark's column (iOS 26): in a menu with checkable rows every item
|
|
2243
|
+
keeps it, empty unless checked, so titles and symbols line up; it sits
|
|
2244
|
+
closer to what follows than a symbol does. */
|
|
2180
2245
|
.sb-picker-menu-check {
|
|
2181
2246
|
display: inline-flex;
|
|
2182
2247
|
align-items: center;
|
|
2183
2248
|
justify-content: center;
|
|
2184
|
-
width:
|
|
2249
|
+
width: 16px;
|
|
2250
|
+
margin-right: -4px;
|
|
2185
2251
|
flex-shrink: 0;
|
|
2186
2252
|
visibility: hidden;
|
|
2187
2253
|
}
|
|
@@ -2191,8 +2257,8 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2191
2257
|
}
|
|
2192
2258
|
|
|
2193
2259
|
.sb-picker-menu-check > svg {
|
|
2194
|
-
width:
|
|
2195
|
-
height:
|
|
2260
|
+
width: 0.95em;
|
|
2261
|
+
height: 0.95em;
|
|
2196
2262
|
stroke: currentColor;
|
|
2197
2263
|
stroke-width: 2.5;
|
|
2198
2264
|
}
|
|
@@ -2204,6 +2270,47 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2204
2270
|
white-space: nowrap;
|
|
2205
2271
|
}
|
|
2206
2272
|
|
|
2273
|
+
/* A menu with a check column (iOS 26): the check sits 24px in from the
|
|
2274
|
+
panel's edge, plain titles and section titles start together after it, and
|
|
2275
|
+
a symbol's column starts a little past them, its title further in. */
|
|
2276
|
+
.sb-picker-menu[data-sb-checks] .sb-picker-menu-item {
|
|
2277
|
+
padding-left: 12px;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
.sb-picker-menu[data-sb-checks] .sb-picker-menu-check {
|
|
2281
|
+
margin-right: -5px;
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
.sb-picker-menu[data-sb-checks] .sb-picker-menu-symbol {
|
|
2285
|
+
width: 28px;
|
|
2286
|
+
margin: 0 4px 0 2px;
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
.sb-picker-menu[data-sb-checks] .sb-picker-menu-caption {
|
|
2290
|
+
padding-left: 36px;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
/* A title with a subtitle under it, in a taller row. */
|
|
2294
|
+
.sb-picker-menu-item[data-sb-subtitled] {
|
|
2295
|
+
height: 58px;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
.sb-picker-menu-titles {
|
|
2299
|
+
display: flex;
|
|
2300
|
+
flex: 1 1 auto;
|
|
2301
|
+
flex-direction: column;
|
|
2302
|
+
min-width: 0;
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
.sb-picker-menu-subtitle {
|
|
2306
|
+
overflow: hidden;
|
|
2307
|
+
color: var(--sb-color-secondary);
|
|
2308
|
+
font-size: 15px;
|
|
2309
|
+
line-height: 20px;
|
|
2310
|
+
text-overflow: ellipsis;
|
|
2311
|
+
white-space: nowrap;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2207
2314
|
@keyframes sb-menu-in {
|
|
2208
2315
|
from {
|
|
2209
2316
|
opacity: 0;
|
|
@@ -2342,15 +2449,15 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2342
2449
|
border-radius: 6px;
|
|
2343
2450
|
}
|
|
2344
2451
|
|
|
2345
|
-
/* Popover rows for menu items: a tap row
|
|
2346
|
-
destructive role is red; a disabled item dims; section headers are
|
|
2347
|
-
captions; `text` items are static 44px rows; groups are split by
|
|
2452
|
+
/* Popover rows for menu items (iOS 26): a tap row's symbol leads its title;
|
|
2453
|
+
a destructive role is red; a disabled item dims; section headers are 30px
|
|
2454
|
+
captions; `text` items are static 44px rows; groups are split by a hairline
|
|
2455
|
+
with 9px above and below, inset from the panel's edges. No lines between items. */
|
|
2348
2456
|
.sb-picker-menu-symbol {
|
|
2349
2457
|
display: inline-flex;
|
|
2350
2458
|
align-items: center;
|
|
2351
2459
|
justify-content: center;
|
|
2352
|
-
width:
|
|
2353
|
-
margin-left: auto;
|
|
2460
|
+
width: 24px;
|
|
2354
2461
|
flex-shrink: 0;
|
|
2355
2462
|
}
|
|
2356
2463
|
|
|
@@ -2372,10 +2479,10 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2372
2479
|
.sb-picker-menu-caption {
|
|
2373
2480
|
display: flex;
|
|
2374
2481
|
align-items: center;
|
|
2375
|
-
height:
|
|
2482
|
+
height: 30px;
|
|
2376
2483
|
padding: 0 16px;
|
|
2377
2484
|
color: var(--sb-color-secondary);
|
|
2378
|
-
font: 400
|
|
2485
|
+
font: 400 15px/20px var(--sb-font-family);
|
|
2379
2486
|
white-space: nowrap;
|
|
2380
2487
|
overflow: hidden;
|
|
2381
2488
|
text-overflow: ellipsis;
|
|
@@ -2394,8 +2501,9 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
2394
2501
|
}
|
|
2395
2502
|
|
|
2396
2503
|
.sb-picker-menu-separator {
|
|
2397
|
-
height:
|
|
2398
|
-
|
|
2504
|
+
height: 1px;
|
|
2505
|
+
margin: 9px 12px;
|
|
2506
|
+
background: var(--sb-color-separator);
|
|
2399
2507
|
}
|
|
2400
2508
|
|
|
2401
2509
|
/* Inline picker: a dim label row (when the label is non-empty) and 44px
|
|
@@ -3656,7 +3764,8 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
3656
3764
|
.sb-alert-layer > [hidden],
|
|
3657
3765
|
.sb-datepicker > [hidden],
|
|
3658
3766
|
.sb-stepper > [hidden],
|
|
3659
|
-
.sb-slider > [hidden]
|
|
3767
|
+
.sb-slider > [hidden],
|
|
3768
|
+
.sb-slider-labels > [hidden] {
|
|
3660
3769
|
display: none;
|
|
3661
3770
|
}
|
|
3662
3771
|
|
|
@@ -3897,7 +4006,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
3897
4006
|
display: flex;
|
|
3898
4007
|
box-sizing: border-box;
|
|
3899
4008
|
border-radius: 16px;
|
|
3900
|
-
background: var(--sb-
|
|
4009
|
+
background: var(--sb-stepper-fill);
|
|
3901
4010
|
overflow: hidden;
|
|
3902
4011
|
}
|
|
3903
4012
|
|
|
@@ -3930,7 +4039,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
|
|
|
3930
4039
|
top: 7px;
|
|
3931
4040
|
bottom: 7px;
|
|
3932
4041
|
width: 1px;
|
|
3933
|
-
background: var(--sb-
|
|
4042
|
+
background: var(--sb-stepper-divider);
|
|
3934
4043
|
}
|
|
3935
4044
|
|
|
3936
4045
|
.sb-stepper-button > svg {
|
|
@@ -4213,3 +4322,66 @@ svg.sb-path {
|
|
|
4213
4322
|
.sb-styled[data-sb-hover] {
|
|
4214
4323
|
pointer-events: auto;
|
|
4215
4324
|
}
|
|
4325
|
+
|
|
4326
|
+
/* ---------------------------------------------------------------------------
|
|
4327
|
+
`disclosuregroup`: the label (the first child) with a chevron at its
|
|
4328
|
+
trailing edge that turns down as the content opens below it; a button
|
|
4329
|
+
over the label takes the tap (layoutDom places both from the label's
|
|
4330
|
+
frame). `section` headers of `Section(isExpanded:)` get the chevron too,
|
|
4331
|
+
in a sidebar-style list, where the section collapses as on iOS.
|
|
4332
|
+
--------------------------------------------------------------------------- */
|
|
4333
|
+
.sb-disclosure-toggle {
|
|
4334
|
+
position: absolute;
|
|
4335
|
+
margin: 0;
|
|
4336
|
+
padding: 0;
|
|
4337
|
+
border: 0;
|
|
4338
|
+
background: transparent;
|
|
4339
|
+
cursor: pointer;
|
|
4340
|
+
-webkit-tap-highlight-color: transparent;
|
|
4341
|
+
}
|
|
4342
|
+
|
|
4343
|
+
.sb-disclosure-chevron {
|
|
4344
|
+
position: absolute;
|
|
4345
|
+
stroke-width: 2.5;
|
|
4346
|
+
color: var(--sb-color-accent);
|
|
4347
|
+
pointer-events: none;
|
|
4348
|
+
transition: transform 0.25s ease-in-out;
|
|
4349
|
+
}
|
|
4350
|
+
|
|
4351
|
+
.sb-disclosuregroup[data-sb-expanded] > .sb-disclosure-chevron {
|
|
4352
|
+
transform: rotate(90deg);
|
|
4353
|
+
}
|
|
4354
|
+
|
|
4355
|
+
/* Collapsed: the content (a disclosure group's, a sidebar section's rows) is hidden by the engine, without a frame. */
|
|
4356
|
+
.sb-disclosuregroup > .sb-slot > [data-sb-id][hidden],
|
|
4357
|
+
.sb-disclosuregroup > .sb-slot > [data-sb-ghost][hidden],
|
|
4358
|
+
.sb-section[data-sb-collapsible] .sb-section-rows > [data-sb-id][hidden],
|
|
4359
|
+
.sb-section[data-sb-collapsible] .sb-section-rows > [data-sb-ghost][hidden] {
|
|
4360
|
+
display: none;
|
|
4361
|
+
}
|
|
4362
|
+
|
|
4363
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] > .sb-section-header,
|
|
4364
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] .sb-sectionheader {
|
|
4365
|
+
cursor: pointer;
|
|
4366
|
+
}
|
|
4367
|
+
|
|
4368
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] > .sb-section-header::after,
|
|
4369
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] .sb-sectionheader::after {
|
|
4370
|
+
/* Centered 10 in from the content's trailing edge, over the rows' own chevrons (the engine's 20pt chevron box). */
|
|
4371
|
+
content: '';
|
|
4372
|
+
position: absolute;
|
|
4373
|
+
right: 6.5px;
|
|
4374
|
+
top: 50%;
|
|
4375
|
+
width: 7px;
|
|
4376
|
+
height: 7px;
|
|
4377
|
+
margin-top: -5px;
|
|
4378
|
+
border-right: 2px solid var(--sb-color-accent);
|
|
4379
|
+
border-bottom: 2px solid var(--sb-color-accent);
|
|
4380
|
+
transform: rotate(-45deg);
|
|
4381
|
+
transition: transform 0.25s ease-in-out;
|
|
4382
|
+
}
|
|
4383
|
+
|
|
4384
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible][data-sb-expanded] > .sb-section-header::after,
|
|
4385
|
+
.sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible][data-sb-expanded] .sb-sectionheader::after {
|
|
4386
|
+
transform: rotate(45deg);
|
|
4387
|
+
}
|
package/src/styles.ts
CHANGED
|
@@ -147,13 +147,6 @@ const HIERARCHICAL_TEXT: Record<1 | 2 | 3 | 4, string> = {
|
|
|
147
147
|
* colors' ratio has it).
|
|
148
148
|
*/
|
|
149
149
|
export const HIERARCHY_OPACITY: Record<1 | 2 | 3 | 4, number> = { 1: 1, 2: 0.5, 3: 0.25, 4: 0.18 };
|
|
150
|
-
const HIERARCHICAL_PAINT: Record<1 | 2 | 3 | 4, string> = {
|
|
151
|
-
1: 'var(--sb-color-fill)',
|
|
152
|
-
2: 'var(--sb-color-secondary-fill)',
|
|
153
|
-
3: 'var(--sb-color-tertiary-fill)',
|
|
154
|
-
4: 'var(--sb-color-quaternary-fill)',
|
|
155
|
-
};
|
|
156
|
-
|
|
157
150
|
/** Opacity of the system background each material shows over the blurred backdrop. */
|
|
158
151
|
export const MATERIAL_ALPHA: Record<Exclude<MaterialName, 'glass' | 'glassClear'>, number> = {
|
|
159
152
|
ultraThin: 0.55,
|
|
@@ -178,7 +171,7 @@ export function materialAlpha(name: MaterialName): number {
|
|
|
178
171
|
* stand out. A non-color style's top-level `opacity` multiplies the result
|
|
179
172
|
* (each stop of a gradient, the material's alpha) like a semantic color's `a`.
|
|
180
173
|
*/
|
|
181
|
-
export function styleToCSS(style: ShapeStyle,
|
|
174
|
+
export function styleToCSS(style: ShapeStyle, _role: PaintRole): PaintCSS {
|
|
182
175
|
if (isColor(style)) {
|
|
183
176
|
const value = colorToCSS(style);
|
|
184
177
|
return { kind: 'color', value, solid: value };
|
|
@@ -186,7 +179,9 @@ export function styleToCSS(style: ShapeStyle, role: PaintRole): PaintCSS {
|
|
|
186
179
|
const opacity = style.opacity;
|
|
187
180
|
if (isHierarchicalStyle(style)) {
|
|
188
181
|
const level = hierarchicalLevel(style.hierarchical);
|
|
189
|
-
|
|
182
|
+
// The levels of the foreground, as SwiftUI paints them in any role: a
|
|
183
|
+
// shape filled or stroked with `.primary` is the label color, not a fill gray.
|
|
184
|
+
const value = withOpacity(HIERARCHICAL_TEXT[level], opacity);
|
|
190
185
|
return { kind: 'color', value, solid: value };
|
|
191
186
|
}
|
|
192
187
|
if (isLinearGradientStyle(style)) {
|
package/src/symbols.ts
CHANGED
|
@@ -294,6 +294,7 @@ import {
|
|
|
294
294
|
Puzzle,
|
|
295
295
|
QrCode,
|
|
296
296
|
Rabbit,
|
|
297
|
+
Rainbow,
|
|
297
298
|
Radio,
|
|
298
299
|
RectangleHorizontal,
|
|
299
300
|
RectangleVertical,
|
|
@@ -748,6 +749,9 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
748
749
|
bolt: outline(Zap),
|
|
749
750
|
'bolt.fill': solid(Zap),
|
|
750
751
|
sparkles: outline(Sparkles),
|
|
752
|
+
// Apple Intelligence's mark: the sparkles stand in for it.
|
|
753
|
+
'apple.intelligence': outline(Sparkles),
|
|
754
|
+
rainbow: outline(Rainbow),
|
|
751
755
|
|
|
752
756
|
// Chevrons and arrows
|
|
753
757
|
'chevron.left': outline(ChevronLeft),
|
|
@@ -773,6 +777,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
773
777
|
'arrow.left.circle': outline(CircleArrowLeft),
|
|
774
778
|
'arrow.right.circle': outline(CircleArrowRight),
|
|
775
779
|
'arrow.up.circle': outline(CircleArrowUp),
|
|
780
|
+
'arrow.up.circle.fill': knockout(CircleArrowUp),
|
|
776
781
|
'arrow.down.circle': outline(CircleArrowDown),
|
|
777
782
|
'arrow.down.to.line': outline(ArrowDownToLine),
|
|
778
783
|
'arrow.up.to.line': outline(ArrowUpFromLine),
|
|
@@ -898,6 +903,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
898
903
|
'pause.circle': outline(CirclePause),
|
|
899
904
|
'pause.circle.fill': knockout(CirclePause),
|
|
900
905
|
'stop.circle': outline(CircleStop),
|
|
906
|
+
'stop.circle.fill': knockout(CircleStop),
|
|
901
907
|
pause: outline(Pause),
|
|
902
908
|
'pause.fill': solid(Pause),
|
|
903
909
|
stop: outline(Square),
|