@marianmeres/stuic 3.128.0 → 3.129.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/API.md +32 -31
- package/README.md +38 -0
- package/dist/components/Header/Header.svelte +11 -0
- package/dist/components/Header/Header.svelte.d.ts +9 -0
- package/dist/components/Header/README.md +28 -0
- package/dist/components/Header/index.css +19 -0
- package/dist/components/Notifications/index.css +18 -0
- package/dist/index.css +45 -0
- package/package.json +1 -1
package/API.md
CHANGED
|
@@ -134,37 +134,38 @@ Navigation wrapper component.
|
|
|
134
134
|
|
|
135
135
|
Responsive navigation header with leading slot, logo, nav items, locale switcher, action icon buttons, avatar, and configurable responsive collapse (`"hamburger"` fold or `"hide"` for app-like shells). Renders as `<header>`.
|
|
136
136
|
|
|
137
|
-
| Prop | Type | Default | Description
|
|
138
|
-
| ----------------------- | ------------------------------------------------ | --------------------- |
|
|
139
|
-
| `leading` | `Snippet<[{ isCollapsed }]>` | — | Leading (left-side) slot. Overrides `leadingHamburger`.
|
|
140
|
-
| `leadingHamburger` | `boolean \| "collapsed"` | `false` | Built-in hamburger in the leading slot (`"collapsed"` = only below threshold). Ignored when `leading` is provided.
|
|
141
|
-
| `onLeadingHamburger` | `() => void` | — | Click handler for the built-in leading hamburger (typically opens a drawer).
|
|
142
|
-
| `leadingHamburgerIcon` | `THC` | menu icon | Icon override for the built-in leading hamburger.
|
|
143
|
-
| `leadingHamburgerLabel` | `string` | `"Open menu"` | Aria-label for the leading hamburger.
|
|
144
|
-
| `logo` | `Snippet` | — | Logo/brand snippet.
|
|
145
|
-
| `projectName` | `string` | — | Simple text logo alternative.
|
|
146
|
-
| `navVariant` | `ButtonVariant` | `"ghost"` | Button variant for nav items and the locale switcher trigger.
|
|
147
|
-
| `items` | `HeaderNavItem[]` | `[]` | Navigation items — inline when expanded, dropdown when collapsed (hamburger mode).
|
|
148
|
-
| `actions` | `HeaderActionItem[]` | `[]` | Action icon buttons between the locale switcher and the avatar. Always visible — never fold into the dropdown.
|
|
149
|
-
| `onActionSelect` | `(action) => void` | — | Called after the per-item `onclick`.
|
|
150
|
-
| `avatar` | `Snippet` | — | Avatar snippet (far right).
|
|
151
|
-
| `avatarOnClick` | `() => void` | — | Makes the avatar interactive. In `"hamburger"` collapse mode it moves into the dropdown.
|
|
152
|
-
| `avatarLabel` | `THC` | `"Account"` | Label for the avatar entry inside the collapsed dropdown.
|
|
153
|
-
| `locales` | `HeaderLocaleItem[]` | `[]` | Locale items. Switcher only renders when 2+.
|
|
154
|
-
| `activeLocale` | `string` | — | Current locale id.
|
|
155
|
-
| `onLocaleChange` | `(localeId) => void` | — | Locale selection callback.
|
|
156
|
-
| `localeLabel` | `THC` | `"Language"` | Section header inside the collapsed dropdown.
|
|
157
|
-
| `contentMaxWidth` | `string \| number` | — | Max-width of the inner content row (outer header stays 100%). Accepts any CSS length. Maps to `--stuic-header-content-max-width`.
|
|
158
|
-
| `collapseThreshold` | `number` | `768` | Width (px) to collapse; 0 disables.
|
|
159
|
-
| `collapseMode` | `"hamburger" \| "hide"` | `"hamburger"` | Collapse behavior. `"hide"` keeps avatar/actions visible and renders no trailing hamburger (app-shell pattern).
|
|
160
|
-
| `keepLocaleOnCollapse` | `boolean` | `false` | Keep the locale switcher visible in collapsed mode (only `collapseMode === "hide"`).
|
|
161
|
-
| `fixed` | `boolean` | `false` | Fixed positioning at the top.
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
137
|
+
| Prop | Type | Default | Description |
|
|
138
|
+
| ----------------------- | ------------------------------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
139
|
+
| `leading` | `Snippet<[{ isCollapsed }]>` | — | Leading (left-side) slot. Overrides `leadingHamburger`. |
|
|
140
|
+
| `leadingHamburger` | `boolean \| "collapsed"` | `false` | Built-in hamburger in the leading slot (`"collapsed"` = only below threshold). Ignored when `leading` is provided. |
|
|
141
|
+
| `onLeadingHamburger` | `() => void` | — | Click handler for the built-in leading hamburger (typically opens a drawer). |
|
|
142
|
+
| `leadingHamburgerIcon` | `THC` | menu icon | Icon override for the built-in leading hamburger. |
|
|
143
|
+
| `leadingHamburgerLabel` | `string` | `"Open menu"` | Aria-label for the leading hamburger. |
|
|
144
|
+
| `logo` | `Snippet` | — | Logo/brand snippet. |
|
|
145
|
+
| `projectName` | `string` | — | Simple text logo alternative. |
|
|
146
|
+
| `navVariant` | `ButtonVariant` | `"ghost"` | Button variant for nav items and the locale switcher trigger. |
|
|
147
|
+
| `items` | `HeaderNavItem[]` | `[]` | Navigation items — inline when expanded, dropdown when collapsed (hamburger mode). |
|
|
148
|
+
| `actions` | `HeaderActionItem[]` | `[]` | Action icon buttons between the locale switcher and the avatar. Always visible — never fold into the dropdown. |
|
|
149
|
+
| `onActionSelect` | `(action) => void` | — | Called after the per-item `onclick`. |
|
|
150
|
+
| `avatar` | `Snippet` | — | Avatar snippet (far right). |
|
|
151
|
+
| `avatarOnClick` | `() => void` | — | Makes the avatar interactive. In `"hamburger"` collapse mode it moves into the dropdown. |
|
|
152
|
+
| `avatarLabel` | `THC` | `"Account"` | Label for the avatar entry inside the collapsed dropdown. |
|
|
153
|
+
| `locales` | `HeaderLocaleItem[]` | `[]` | Locale items. Switcher only renders when 2+. |
|
|
154
|
+
| `activeLocale` | `string` | — | Current locale id. |
|
|
155
|
+
| `onLocaleChange` | `(localeId) => void` | — | Locale selection callback. |
|
|
156
|
+
| `localeLabel` | `THC` | `"Language"` | Section header inside the collapsed dropdown. |
|
|
157
|
+
| `contentMaxWidth` | `string \| number` | — | Max-width of the inner content row (outer header stays 100%). Accepts any CSS length. Maps to `--stuic-header-content-max-width`. |
|
|
158
|
+
| `collapseThreshold` | `number` | `768` | Width (px) to collapse; 0 disables. |
|
|
159
|
+
| `collapseMode` | `"hamburger" \| "hide"` | `"hamburger"` | Collapse behavior. `"hide"` keeps avatar/actions visible and renders no trailing hamburger (app-shell pattern). |
|
|
160
|
+
| `keepLocaleOnCollapse` | `boolean` | `false` | Keep the locale switcher visible in collapsed mode (only `collapseMode === "hide"`). |
|
|
161
|
+
| `fixed` | `boolean` | `false` | Fixed positioning at the top. |
|
|
162
|
+
| `safeArea` | `boolean` | `false` | PWA: when installed/standalone, offset the **top app bar** below the device safe-area insets (top + side notch). No-op in a browser tab. Set only on the top bar — not in-page/detail/drawer headers. See Header README. |
|
|
163
|
+
| `isCollapsed` | `boolean` | — | Bindable: collapsed state. |
|
|
164
|
+
| `isMenuOpen` | `boolean` | — | Bindable: hamburger menu open. |
|
|
165
|
+
| `dropdownPosition` | `DropdownMenuPosition` | `"bottom-span-right"` | Position of the collapsed dropdown. |
|
|
166
|
+
| `iconSize` | `number` | `24` | Hamburger/X icon size in px. |
|
|
167
|
+
| `onSelect` | `(item) => void` | — | Item selection callback (both modes). |
|
|
168
|
+
| `children` | `Snippet<[{ isCollapsed, items, offsetWidth }]>` | — | Escape hatch: override the entire inner layout. |
|
|
168
169
|
|
|
169
170
|
Class slots: `class`, `classContent`, `classLeading`, `classLeadingHamburger`, `classLogo`, `classNav`, `classNavItem`, `classNavItemActive`, `classActions`, `classAction`, `classActionActive`, `classEnd`, `classAvatar`, `classLocale`, `classHamburger`, `classDropdown`.
|
|
170
171
|
|
package/README.md
CHANGED
|
@@ -183,6 +183,44 @@ Cart, Checkout (CheckoutProgress, CheckoutOrderSummary, CheckoutCartReview, Chec
|
|
|
183
183
|
|
|
184
184
|
`autogrow` · `validate` · `focusTrap` · `autoscroll` · `dimBehind` · `fileDropzone` · `highlightDragover` · `resizableWidth` · `spotlight` · `trim` · `typeahead` · `onSubmitValidityCheck` · `popover` · `tooltip` · `createTour` / `tourStep` (onboarding)
|
|
185
185
|
|
|
186
|
+
## PWA safe-area insets
|
|
187
|
+
|
|
188
|
+
When a stuic app is installed and launched standalone (iOS Home Screen, Android/desktop PWA), the web view fills the entire screen, so edge-anchored chrome can render under the status bar / notch / home indicator. stuic ships an **opt-in** safe-area layer that is **inert in a normal browser tab** (`env()` → `0`) and only engages under `@media (display-mode: standalone), (display-mode: fullscreen)`.
|
|
189
|
+
|
|
190
|
+
> The insets are only non-zero when your app sets `<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">` (your responsibility) **and** the device has an inset.
|
|
191
|
+
|
|
192
|
+
**Component props (opt-in):**
|
|
193
|
+
|
|
194
|
+
- `Header` — `safeArea` offsets the top app bar below the top + side insets. See the [Header README](src/lib/components/Header/README.md). Set it only on the **top** app bar, never on in-page / detail / drawer-internal headers.
|
|
195
|
+
|
|
196
|
+
**Automatic:**
|
|
197
|
+
|
|
198
|
+
- `Notifications` — the toast stack always keeps clear of the insets in standalone (you never want a toast under the home indicator). No prop needed; no-op in a browser tab.
|
|
199
|
+
|
|
200
|
+
**Utility classes** — offset any edge-anchored element without writing your own `env()` rule. They are active in standalone only:
|
|
201
|
+
|
|
202
|
+
```html
|
|
203
|
+
<header class="my-top-bar stuic-safe-area-top">…</header>
|
|
204
|
+
<footer class="my-bottom-bar stuic-safe-area-bottom">…</footer>
|
|
205
|
+
<!-- also: stuic-safe-area-left / stuic-safe-area-right -->
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> ⚠️ These **set** the padding on their axis (they replace, not add). Apply them only to an element that doesn't already pad that side. To **add** inset on top of existing padding, compose the variables below instead.
|
|
209
|
+
|
|
210
|
+
**CSS variables** — composable insets (`0px` everywhere, real device insets in standalone):
|
|
211
|
+
|
|
212
|
+
```css
|
|
213
|
+
.my-bottom-bar {
|
|
214
|
+
/* keep my own 1rem and add the home-indicator inset on top */
|
|
215
|
+
padding-bottom: calc(1rem + var(--stuic-safe-area-bottom));
|
|
216
|
+
}
|
|
217
|
+
/* also: --stuic-safe-area-top / --stuic-safe-area-left / --stuic-safe-area-right */
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Pick ONE layer.** Don't pad the same edge twice in a nesting chain. E.g. a nav `Drawer` whose content is its own stuic `Header`: put `safeArea` on the inner `Header`, not also on the drawer panel/wrapper.
|
|
221
|
+
|
|
222
|
+
**Not covered:** other fixed/edge-anchored components (`Modal`/`ModalDialog` full-bleed on mobile, `Float`) do not auto-handle insets — apply a `stuic-safe-area-*` class or the variables to their content as needed.
|
|
223
|
+
|
|
186
224
|
## TypeScript
|
|
187
225
|
|
|
188
226
|
All components export their Props types:
|
|
@@ -158,6 +158,15 @@
|
|
|
158
158
|
keepLocaleOnCollapse?: boolean;
|
|
159
159
|
/** Fixed positioning (top of viewport) */
|
|
160
160
|
fixed?: boolean;
|
|
161
|
+
/** When the app runs installed/standalone (display-mode standalone or
|
|
162
|
+
* fullscreen), offset the header below the device safe-area insets so its
|
|
163
|
+
* content (logo, hamburger) clears the status bar / notch / Dynamic Island.
|
|
164
|
+
* Pads the top plus the left/right insets (the latter only matter for a
|
|
165
|
+
* side notch in landscape — both 0 in portrait). The header's own
|
|
166
|
+
* background fills the inset strip. No-op in a browser tab / on devices
|
|
167
|
+
* without an inset. Only set this on the TOP app bar — never on in-page,
|
|
168
|
+
* detail, or drawer-internal headers (they'd get wrongly padded). */
|
|
169
|
+
safeArea?: boolean;
|
|
161
170
|
/** Bindable: whether the header is currently in collapsed (hamburger) mode */
|
|
162
171
|
isCollapsed?: boolean;
|
|
163
172
|
/** Bindable: whether the hamburger dropdown is currently open */
|
|
@@ -256,6 +265,7 @@
|
|
|
256
265
|
collapseMode = "hamburger",
|
|
257
266
|
keepLocaleOnCollapse = false,
|
|
258
267
|
fixed = false,
|
|
268
|
+
safeArea = false,
|
|
259
269
|
isCollapsed = $bindable(false),
|
|
260
270
|
isMenuOpen = $bindable(false),
|
|
261
271
|
dropdownPosition = "bottom-span-right",
|
|
@@ -462,6 +472,7 @@
|
|
|
462
472
|
class={_class}
|
|
463
473
|
data-fixed={!unstyled && fixed ? "" : undefined}
|
|
464
474
|
data-collapsed={!unstyled && _isCollapsed ? "" : undefined}
|
|
475
|
+
data-safe-area={!unstyled && safeArea ? "" : undefined}
|
|
465
476
|
{...rest}
|
|
466
477
|
>
|
|
467
478
|
{#if children}
|
|
@@ -147,6 +147,15 @@ export interface Props extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
|
147
147
|
keepLocaleOnCollapse?: boolean;
|
|
148
148
|
/** Fixed positioning (top of viewport) */
|
|
149
149
|
fixed?: boolean;
|
|
150
|
+
/** When the app runs installed/standalone (display-mode standalone or
|
|
151
|
+
* fullscreen), offset the header below the device safe-area insets so its
|
|
152
|
+
* content (logo, hamburger) clears the status bar / notch / Dynamic Island.
|
|
153
|
+
* Pads the top plus the left/right insets (the latter only matter for a
|
|
154
|
+
* side notch in landscape — both 0 in portrait). The header's own
|
|
155
|
+
* background fills the inset strip. No-op in a browser tab / on devices
|
|
156
|
+
* without an inset. Only set this on the TOP app bar — never on in-page,
|
|
157
|
+
* detail, or drawer-internal headers (they'd get wrongly padded). */
|
|
158
|
+
safeArea?: boolean;
|
|
150
159
|
/** Bindable: whether the header is currently in collapsed (hamburger) mode */
|
|
151
160
|
isCollapsed?: boolean;
|
|
152
161
|
/** Bindable: whether the hamburger dropdown is currently open */
|
|
@@ -33,3 +33,31 @@ Minimal config:
|
|
|
33
33
|
{#snippet avatar()}<Avatar initials="MM" autoColor />{/snippet}
|
|
34
34
|
</Header>
|
|
35
35
|
```
|
|
36
|
+
|
|
37
|
+
## PWA safe area (`safeArea`)
|
|
38
|
+
|
|
39
|
+
When your app is installed and launched standalone (iOS Home Screen, Android/desktop PWA), the web view fills the **entire** screen, so a top app bar renders _under_ the status bar / notch / Dynamic Island, where the system swallows touches — the logo and hamburger become untappable.
|
|
40
|
+
|
|
41
|
+
Set `safeArea` on the **top app bar** to offset its content below the device safe-area insets. It pads the **top** (status bar / notch in portrait) plus the **left/right** insets (a side notch in landscape — both `0` in portrait). The padding lands on the **outer** `<header>` (the background-bearing, full-width element), so the brand color fills the inset strip and the inner content row keeps its own padding.
|
|
42
|
+
|
|
43
|
+
```svelte
|
|
44
|
+
<Header
|
|
45
|
+
projectName="App"
|
|
46
|
+
fixed
|
|
47
|
+
safeArea
|
|
48
|
+
leadingHamburger
|
|
49
|
+
onLeadingHamburger={openDrawer}
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **Default `false`.** No change to any existing render path. It's a **no-op in a browser tab** and on devices without an inset (`env()` → `0`).
|
|
54
|
+
- The insets are only non-zero when the consuming app sets `<meta name="viewport" content="..., viewport-fit=cover">` (the app's responsibility) **and** the device has an inset.
|
|
55
|
+
- **Only set it on the TOP app bar.** `Header` is reused as in-page, detail, and drawer-internal headers — those must NOT get `safeArea`, or they'd be wrongly padded.
|
|
56
|
+
- **Respects `unstyled`** (skipped, like every other `data-*` toggle).
|
|
57
|
+
- It is **independent of `fixed`** — you typically want both on a top app bar, but neither implies the other.
|
|
58
|
+
|
|
59
|
+
### Pick ONE layer (avoid double padding)
|
|
60
|
+
|
|
61
|
+
A nav **drawer** that contains its own stuic `Header` (logo + close button) is common. In that case set `safeArea` on the **inner `Header`** (so the header color fills the strip) and do **not** also offset the drawer panel — otherwise the top inset is applied twice. Each safe-area edge should be padded on exactly **one** element in any nesting chain.
|
|
62
|
+
|
|
63
|
+
> The underlying mechanism (and the reusable `.stuic-safe-area-*` utility classes / `--stuic-safe-area-*` CSS variables for any other edge-anchored element) is documented in the root README under "PWA safe-area insets".
|
|
@@ -250,3 +250,22 @@
|
|
|
250
250
|
margin-inline-end: var(--stuic-header-trailing-hamburger-offset-inline-end);
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
|
+
|
|
254
|
+
/* ============================================================================
|
|
255
|
+
SAFE AREA (PWA installed / standalone) — opt-in via the `safeArea` prop.
|
|
256
|
+
Deliberately UNLAYERED (not in @layer components, unlike [data-fixed] above)
|
|
257
|
+
so it reliably beats a consumer's Tailwind `utilities` layer — the whole
|
|
258
|
+
point is a safe-area offset that a stray `pt-*` can't silently override.
|
|
259
|
+
Pads the OUTER .stuic-header (full-width, background-bearing) so the brand
|
|
260
|
+
color fills the inset strip. Top covers the status bar/notch in portrait;
|
|
261
|
+
left/right cover a side notch in landscape (both 0 without an inset). The
|
|
262
|
+
inner .stuic-header-content keeps its own padding, so the inset stacks above
|
|
263
|
+
the content row rather than replacing it. No-op in a browser tab (env → 0).
|
|
264
|
+
============================================================================ */
|
|
265
|
+
@media (display-mode: standalone), (display-mode: fullscreen) {
|
|
266
|
+
.stuic-header[data-safe-area] {
|
|
267
|
+
padding-top: env(safe-area-inset-top);
|
|
268
|
+
padding-left: env(safe-area-inset-left);
|
|
269
|
+
padding-right: env(safe-area-inset-right);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -230,3 +230,21 @@
|
|
|
230
230
|
);
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
/* ============================================================================
|
|
235
|
+
SAFE AREA (PWA installed / standalone) — automatic, not opt-in.
|
|
236
|
+
The .stuic-notifs wrap is `fixed inset-0` and carries no padding of its own
|
|
237
|
+
(the visual spacing lives on the inner `p-4` wrap), so padding it here insets
|
|
238
|
+
the whole toast region by the device safe area. This keeps toasts clear of
|
|
239
|
+
the status bar / notch / home indicator regardless of corner placement, and
|
|
240
|
+
composes with the inner p-4. Toasts should never sit under system UI, so this
|
|
241
|
+
needs no prop. No-op in a browser tab (env → 0).
|
|
242
|
+
============================================================================ */
|
|
243
|
+
@media (display-mode: standalone), (display-mode: fullscreen) {
|
|
244
|
+
.stuic-notifs {
|
|
245
|
+
padding-top: env(safe-area-inset-top);
|
|
246
|
+
padding-right: env(safe-area-inset-right);
|
|
247
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
248
|
+
padding-left: env(safe-area-inset-left);
|
|
249
|
+
}
|
|
250
|
+
}
|
package/dist/index.css
CHANGED
|
@@ -130,3 +130,48 @@ In practice:
|
|
|
130
130
|
.scrollbar-thin {
|
|
131
131
|
scrollbar-width: thin;
|
|
132
132
|
}
|
|
133
|
+
|
|
134
|
+
/* ============================================================================
|
|
135
|
+
PWA SAFE-AREA INSETS (installed / standalone)
|
|
136
|
+
Unlayered (like .scrollbar-thin above) so they reliably beat a consumer's
|
|
137
|
+
Tailwind `utilities` layer — a deliberate `pt-*` elsewhere must not silently
|
|
138
|
+
win over a safe-area offset. The raw env() values self-zero in a normal
|
|
139
|
+
browser tab; they only become non-zero on a device with an inset when the
|
|
140
|
+
app declares `viewport-fit=cover` (the consuming app's responsibility).
|
|
141
|
+
============================================================================ */
|
|
142
|
+
|
|
143
|
+
/* Composable inset variables: 0px everywhere, real device insets only when the
|
|
144
|
+
app runs installed/standalone. Use these to ADD inset without clobbering an
|
|
145
|
+
element's existing padding, e.g.:
|
|
146
|
+
padding-block-start: calc(1rem + var(--stuic-safe-area-top)); */
|
|
147
|
+
:root {
|
|
148
|
+
--stuic-safe-area-top: 0px;
|
|
149
|
+
--stuic-safe-area-right: 0px;
|
|
150
|
+
--stuic-safe-area-bottom: 0px;
|
|
151
|
+
--stuic-safe-area-left: 0px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@media (display-mode: standalone), (display-mode: fullscreen) {
|
|
155
|
+
:root {
|
|
156
|
+
--stuic-safe-area-top: env(safe-area-inset-top);
|
|
157
|
+
--stuic-safe-area-right: env(safe-area-inset-right);
|
|
158
|
+
--stuic-safe-area-bottom: env(safe-area-inset-bottom);
|
|
159
|
+
--stuic-safe-area-left: env(safe-area-inset-left);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Utility classes. NB these SET the padding on their axis (they replace,
|
|
163
|
+
not add) — apply them only to an element that does not otherwise pad that
|
|
164
|
+
side. To ADD inset to existing padding, compose the var above instead. */
|
|
165
|
+
.stuic-safe-area-top {
|
|
166
|
+
padding-top: env(safe-area-inset-top);
|
|
167
|
+
}
|
|
168
|
+
.stuic-safe-area-right {
|
|
169
|
+
padding-right: env(safe-area-inset-right);
|
|
170
|
+
}
|
|
171
|
+
.stuic-safe-area-bottom {
|
|
172
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
173
|
+
}
|
|
174
|
+
.stuic-safe-area-left {
|
|
175
|
+
padding-left: env(safe-area-inset-left);
|
|
176
|
+
}
|
|
177
|
+
}
|