@nxgt/material 3.85.1 → 3.86.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/CHANGELOG.md +36 -0
- package/README.md +39 -5
- package/dist/{alert-dialog-1t6ULy5i.js → alert-dialog-DZnt8PYE.js} +1 -1
- package/dist/{async-slice-xyA9Uzct.js → async-slice-D3OdV2BS.js} +1 -1
- package/dist/{button-DhiNGrdT.js → button-MAL5an7L.js} +1 -1
- package/dist/{calculator-BcgxxScL.js → calculator-C3a8YMwl.js} +10 -10
- package/dist/calculator-field.js +6 -6
- package/dist/{calculator-segment-C4WQAHcN.js → calculator-segment-BigMpjhn.js} +1 -1
- package/dist/calculator.js +1 -1
- package/dist/charts.js +3 -3
- package/dist/{chip-m0_usuzd.js → chip-DKAKoNxq.js} +2 -2
- package/dist/{code-editor-BgKFrcld.js → code-editor-B6dFQSUJ.js} +4 -4
- package/dist/code-editor.js +4 -4
- package/dist/{code-language-items-BWw17W9s.js → code-language-items-CXEMiWoF.js} +2 -2
- package/dist/components/components.css +2 -0
- package/dist/components/theme-tokens.css +18 -0
- package/dist/components/ui/layout/app-bar/top-app-bar/top-app-bar-collapse.css +60 -0
- package/dist/components/ui/layout/app-bar/top-app-bar/top-app-bar.css +205 -0
- package/dist/components/ui/layout/app-shell/app-header.css +70 -63
- package/dist/{components-DfSE2F8d.js → components-C2MBVly0.js} +17327 -16929
- package/dist/components.js +24 -24
- package/dist/{conversion-variant-DultZZQm.js → conversion-variant-BT5n4-jm.js} +3 -3
- package/dist/{currency-field-CPbaM7ay.js → currency-field-t41sFYg_.js} +4 -4
- package/dist/{dialog-DmlG9opW.js → dialog-BjKiRXJg.js} +3 -3
- package/dist/dnd.js +1 -1
- package/dist/{dropdown-menu-CDKev8dk.js → dropdown-menu-IRFp4CH9.js} +1 -1
- package/dist/editor.js +7 -7
- package/dist/{empty-state-C56000TB.js → empty-state-C70prDDr.js} +1 -1
- package/dist/{financial-variant-BYjQ690K.js → financial-variant-BIpzs8IL.js} +5 -5
- package/dist/{hooks-BTwLAy_A.js → hooks-CjO11MS7.js} +2 -2
- package/dist/hooks.js +2 -2
- package/dist/{hover-card-CDtW6utN.js → hover-card-cU_aJa18.js} +1 -1
- package/dist/i18n.js +3 -3
- package/dist/{icon-badge-ec7MmUGA.js → icon-badge-D3KO6uEQ.js} +1 -1
- package/dist/{icon-button-CG4aO8Gh.js → icon-button-DrqNk1Ww.js} +1 -1
- package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
- package/dist/lib/components/ui/layout/app-bar/index.d.ts +1 -1
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/index.d.ts +1 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-actions.d.ts +15 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-headline.d.ts +4 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-link.d.ts +9 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-menu-section.d.ts +14 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-primary-action.d.ts +12 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-row.d.ts +23 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/partials/top-app-bar-title-block.d.ts +18 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar.actions.d.ts +43 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar.d.ts +9 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar.types.d.ts +120 -0
- package/dist/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar.utils.d.ts +43 -0
- package/dist/lib/components/ui/layout/app-shell/activity-app-bar.d.ts +6 -6
- package/dist/lib/components/ui/layout/app-shell/activity-chrome.d.ts +6 -3
- package/dist/lib/components/ui/layout/app-shell/activity-column-props.d.ts +1 -1
- package/dist/lib/components/ui/layout/app-shell/activity-column.d.ts +2 -2
- package/dist/lib/components/ui/layout/app-shell/activity-layout-navigation.types.d.ts +32 -4
- package/dist/lib/components/ui/layout/app-shell/activity-layout.types.d.ts +12 -2
- package/dist/lib/components/ui/layout/app-shell/app-header.d.ts +9 -3
- package/dist/lib/components/ui/layout/app-shell/header-look.d.ts +14 -0
- package/dist/lib/components/ui/layout/app-shell/header-title.d.ts +9 -36
- package/dist/lib/components/ui/layout/app-shell/header.utils.d.ts +13 -3
- package/dist/lib/components/ui/layout/app-shell/index.d.ts +1 -1
- package/dist/lib/components/ui/layout/app-shell/navigation.utils.d.ts +7 -2
- package/dist/lib/components/ui/layout/app-shell/shell-scroll.d.ts +23 -1
- package/dist/lib/components/ui/layout/app-shell/shell-top-app-bar.d.ts +10 -0
- package/dist/lib/components/ui/layout/app-shell/shell-top-app-bar.parts.d.ts +58 -0
- package/dist/lib/components/ui/layout/app-shell/shell-top-app-bar.types.d.ts +26 -0
- package/dist/lib/components/ui/layout/app-shell/use-header-scroll.d.ts +16 -9
- package/dist/lib/components/ui/layout/app-shell/use-shell-header.d.ts +1 -1
- package/dist/lib/components/ui/primitives/tabs/tabs-press.d.ts +11 -0
- package/dist/lib/i18n/resources/en/en.d.ts +4 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +4 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +4 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +4 -0
- package/dist/lib/i18n/resources/resources.d.ts +8 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +28 -28
- package/dist/map.js +7 -7
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/{percent-field-8_pILs15.js → percent-field-D47IlaPF.js} +1 -1
- package/dist/{picker-surface-pyGv-Qh9.js → picker-surface-Cg4V4-E0.js} +4 -4
- package/dist/{popover-3EF4q2CT.js → popover-Dzk4-l9U.js} +1 -1
- package/dist/{pos-types-Dv2UxKSN.js → pos-types-JOXMY4Y2.js} +1 -1
- package/dist/{pos-variant-DJvtN9N8.js → pos-variant-B2mS8bMB.js} +4 -4
- package/dist/print.js +1 -1
- package/dist/{programmer-variant-Bmcq2KzC.js → programmer-variant-C_Tl0P4_.js} +2 -2
- package/dist/{public-BNebh4z0.js → public-ByAsqBOf.js} +9 -9
- package/dist/{rich-code-block-DmX7d58S.js → rich-code-block-CJAfqk6b.js} +5 -5
- package/dist/{scientific-variant-DijUrpP8.js → scientific-variant-CskM4MLV.js} +2 -2
- package/dist/{sortable-provider-Cnmt_gWu.js → sortable-provider-ICS_vkLA.js} +2 -2
- package/dist/{spinner-C6LP2Rw8.js → spinner-CweqX5A9.js} +1 -1
- package/dist/styles.css +2 -0
- package/dist/{tabs-Bj1zOe7-.js → tabs-95Y2LmnV.js} +65 -43
- package/dist/theme-picker.js +2 -2
- package/dist/{theme-toggle-Cxku5iBP.js → theme-toggle-WAFkncYx.js} +1 -1
- package/dist/{toolbar-items-CEIuSxU_.js → toolbar-items-BsgzHSNf.js} +4 -4
- package/dist/{translate-material-DI3nmQ6I.js → translate-material-DTIAPmlU.js} +1 -1
- package/dist/{translator-BstxG_hN.js → translator-BRZNhsy5.js} +8 -0
- package/dist/{use-chat-composer-BqLkk_iH.js → use-chat-composer-CleSUh_y.js} +15 -15
- package/dist/{use-heading-spy-nFyb9_KE.js → use-heading-spy-D8WbHJuK.js} +4 -4
- package/dist/{use-material-translation-1kCHtB0p.js → use-material-translation-CCy1Me0h.js} +1 -1
- package/dist/{use-return-focus-Hv8rn55-.js → use-return-focus-BA8G1qVU.js} +1 -1
- package/docs/README.md +1 -0
- package/docs/components/navigation-and-layout.md +85 -32
- package/docs/guides/app-shell.md +158 -63
- package/docs/guides/drawing.md +2 -0
- package/docs/guides/layouts.md +3 -3
- package/docs/guides/migrating-to-top-app-bar.md +156 -0
- package/docs/guides/theming.md +5 -0
- package/docs/previews/navigation-layout-appshell-blue-moon.webp +0 -0
- package/docs/previews/navigation-layout-appshell-footer-icon.webp +0 -0
- package/docs/previews/navigation-layout-appshell-menu-badge.webp +0 -0
- package/docs/previews/navigation-layout-appshell-page-ground.webp +0 -0
- package/docs/previews/navigation-layout-appshell-themes.webp +0 -0
- package/docs/previews/navigation-layout-appshell.webp +0 -0
- package/docs/previews/navigation-layout-topappbar.webp +0 -0
- package/docs/roadmap.md +17 -6
- package/docs/troubleshooting.md +80 -0
- package/lib/components/components.css +2 -0
- package/lib/components/theme-tokens.css +18 -0
- package/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar-collapse.css +60 -0
- package/lib/components/ui/layout/app-bar/top-app-bar/top-app-bar.css +205 -0
- package/lib/components/ui/layout/app-shell/app-header.css +70 -63
- package/lib/styles.css +2 -0
- package/lib/themes/ambre.css +5 -1
- package/lib/themes/ardoise.css +5 -1
- package/lib/themes/bleumono.css +5 -1
- package/lib/themes/bluemoon.css +5 -1
- package/lib/themes/corail.css +5 -1
- package/lib/themes/foret.css +5 -1
- package/lib/themes/lavande.css +5 -1
- package/lib/themes/menthe.css +5 -1
- package/lib/themes/ocean.css +5 -1
- package/lib/themes/pink.css +5 -1
- package/lib/themes/prune.css +5 -1
- package/lib/themes/sable.css +5 -1
- package/lib/themes/slate.css +5 -1
- package/lib/themes/teal.css +5 -1
- package/package.json +2 -2
- package/dist/lib/components/ui/layout/app-bar/top-app-bar.d.ts +0 -18
- package/dist/lib/components/ui/layout/app-shell/app-header-row.d.ts +0 -3
- package/dist/lib/components/ui/layout/app-shell/header-context.d.ts +0 -10
- package/dist/lib/components/ui/layout/app-shell/page-title.d.ts +0 -27
- /package/dist/lib/components/ui/layout/{app-shell → app-bar/top-app-bar}/use-truncated-title.d.ts +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Moving to TopAppBar
|
|
2
|
+
|
|
3
|
+
`ActivityLayout` draws its app bar with `TopAppBar`, and `TopAppBar` has new
|
|
4
|
+
sizes, a title that is the page's `h1`, free icon actions and a main action. This
|
|
5
|
+
is a minor release: every old spelling keeps working, logs a one-time development
|
|
6
|
+
warning, and is removed no earlier than the next major. This page lists each one
|
|
7
|
+
with what replaces it, what looks different, and which slots the next major renames.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [`AppHeader` becomes `TopAppBar`](#appheader-becomes-topappbar)
|
|
12
|
+
- [`header` values and `handle.header`](#header-values-and-handleheader)
|
|
13
|
+
- [`TopAppBar` `variant` and `headline`](#topappbar-variant-and-headline)
|
|
14
|
+
- [Actions, the account menu and a main action](#actions-the-account-menu-and-a-main-action)
|
|
15
|
+
- [What looks different](#what-looks-different)
|
|
16
|
+
- [The `data-slot` rename in the next major](#the-data-slot-rename-in-the-next-major)
|
|
17
|
+
|
|
18
|
+
## `AppHeader` becomes `TopAppBar`
|
|
19
|
+
|
|
20
|
+
**Search**: `AppHeader`.
|
|
21
|
+
|
|
22
|
+
`AppHeader` is a thin wrapper over `TopAppBar` with the props it always had; it
|
|
23
|
+
logs `AppHeader: is deprecated, use TopAppBar` once in development. Inside
|
|
24
|
+
`ActivityLayout` there is nothing to do: the layout does not use the wrapper.
|
|
25
|
+
In a layout of your own, draw the bar with `TopAppBar`; the menu button and back
|
|
26
|
+
arrow go in `leading`, the avatar in `trailing`.
|
|
27
|
+
|
|
28
|
+
**Replace**:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// before
|
|
32
|
+
<AppHeader items={items} variant="large" headline={<h1>Orders</h1>} avatar={<Avatar />} />
|
|
33
|
+
|
|
34
|
+
// after
|
|
35
|
+
<TopAppBar
|
|
36
|
+
as="header"
|
|
37
|
+
size="large-flexible"
|
|
38
|
+
title="Orders"
|
|
39
|
+
leading={<MenuButton />}
|
|
40
|
+
trailing={<Avatar />}
|
|
41
|
+
/>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`TopAppBar` does not draw the phone's menu sheet or read the router: the shell
|
|
45
|
+
does. A bar of your own passes its own `leading` and `actions`. `AppHeader` also
|
|
46
|
+
renders a `div`, where `as="header"` makes the bar the page's banner.
|
|
47
|
+
|
|
48
|
+
## `header` values and `handle.header`
|
|
49
|
+
|
|
50
|
+
**Search**: `header="center"`, `header="medium"`, `header="large"`,
|
|
51
|
+
`header: 'center'` (and `'medium'`, `'large'`), `variant:` inside a `header` object
|
|
52
|
+
or a route's `handle.header`.
|
|
53
|
+
|
|
54
|
+
| Before | After |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `'small'` | `'small'` (unchanged) |
|
|
57
|
+
| `'center'` | `{ size: 'small', align: 'center' }` |
|
|
58
|
+
| `'medium'` | `'medium-flexible'` |
|
|
59
|
+
| `'large'` | `'large-flexible'` |
|
|
60
|
+
| `'none'` | `'none'` (unchanged) |
|
|
61
|
+
| `{ variant: 'large', hideOnScroll: true }` | `{ size: 'large-flexible', hideOnScroll: true }` |
|
|
62
|
+
| (none) | `'search'`: the search field is the bar's centre |
|
|
63
|
+
|
|
64
|
+
A string in the new spelling sets the size only, so the layout's `align` stays.
|
|
65
|
+
A route's header in one spelling overrides the layout's in the other. The warning
|
|
66
|
+
is `ActivityLayout: header `medium` is deprecated; use 'medium-flexible'.`
|
|
67
|
+
([troubleshooting](../troubleshooting.md#activitylayout-header-center-medium-or-large-is-deprecated)).
|
|
68
|
+
|
|
69
|
+
`resolveHeader` and `ResolvedHeader` gain `size` and `align`; `variant` stays
|
|
70
|
+
filled with the old equivalent. `ShellHeaderVariant` is widened with the new
|
|
71
|
+
values: an exhaustive `switch` over it needs them.
|
|
72
|
+
|
|
73
|
+
## `TopAppBar` `variant` and `headline`
|
|
74
|
+
|
|
75
|
+
**Search**: `<TopAppBar variant=`, `headline=`.
|
|
76
|
+
|
|
77
|
+
| Before | After |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `variant="center"` | `size="small" align="center"` |
|
|
80
|
+
| `variant="medium"` | `size="medium-flexible"` |
|
|
81
|
+
| `variant="large"` | `size="large-flexible"` |
|
|
82
|
+
| `headline={<h1>Projects</h1>}` | `title="Projects"` (the bar renders the `<h1>`) |
|
|
83
|
+
|
|
84
|
+
`headline` rendered in a non-heading element with display type; it still does, now
|
|
85
|
+
with the bar's title styling. `data-variant` is still set (`"search"` is new), and
|
|
86
|
+
`data-size` and `data-align` are added.
|
|
87
|
+
|
|
88
|
+
## Actions, the account menu and a main action
|
|
89
|
+
|
|
90
|
+
All additive. `headerActions` (and `TopAppBar`'s `actions`) takes a
|
|
91
|
+
`TopAppBarAction[]` as well as a node: free ghost icon buttons, with the rest in
|
|
92
|
+
the account menu on the avatar. `headerPrimaryAction` (`primaryAction`) is a
|
|
93
|
+
`Button` from 768 px and a floating button on a phone. `headerContext` is now the
|
|
94
|
+
bar's subtitle, under the title. An `actions` that is a node, an array of elements
|
|
95
|
+
included, and `trailing` draw as before. See
|
|
96
|
+
[Top app bar sizes](./app-shell.md#top-app-bar-sizes) and
|
|
97
|
+
[the `TopAppBar` props](../components/navigation-and-layout.md#topappbar).
|
|
98
|
+
|
|
99
|
+
An avatar used as `trailing` next to an `actions` array of data becomes the menu's
|
|
100
|
+
trigger (a `<button>`): it must hold no link or button.
|
|
101
|
+
|
|
102
|
+
## What looks different
|
|
103
|
+
|
|
104
|
+
No code change, but snapshots of an app that renders the bar change:
|
|
105
|
+
|
|
106
|
+
- **Heights.** The headline row of a medium bar is 3 rem and a large bar's 6.5 rem
|
|
107
|
+
before it is measured (it was 5 rem and 8 rem), then follows the title's real
|
|
108
|
+
height. Medium titles are 28 px, large ones 40 px (36 px on a phone).
|
|
109
|
+
- **A flat bar.** It sits on the page ground with no shadow, border or surface
|
|
110
|
+
background (it was a translucent card). Once scrolled it takes the
|
|
111
|
+
`--surface-container` tint and a 1 px `--border` hairline (the `data-scrolled`
|
|
112
|
+
attribute). A `className` background, radius or shadow wins at rest (the
|
|
113
|
+
bar's own look is in `@layer components`); once scrolled the tint replaces a
|
|
114
|
+
`className` background, as the scrolled state's look.
|
|
115
|
+
- **A ghost menu button on a phone**, leading the bar, with no logo or brand.
|
|
116
|
+
Desktop is unchanged.
|
|
117
|
+
- **Vertical padding** sits on the bar itself, so `className="py-1"` still works.
|
|
118
|
+
- **`position`.** A `TopAppBar` is no longer `position: relative` except
|
|
119
|
+
`size="search"`, so a `sticky` class works.
|
|
120
|
+
- **The root is a column.** A standalone `TopAppBar` used to be one flex row on
|
|
121
|
+
the root; the root is now `flex-col` and its children sit in a
|
|
122
|
+
`[data-slot="top-app-bar-row"]` (a headline row and the tabs follow it). A
|
|
123
|
+
layout utility in the root's `className` (`justify-between`, `gap-*`,
|
|
124
|
+
`items-*`, a horizontal `px-*`) no longer reaches the children; aim it at the
|
|
125
|
+
row, for example `className="[&_[data-slot=top-app-bar-row]]:justify-between"`.
|
|
126
|
+
A vertical `py-*` on the root still works.
|
|
127
|
+
- **`title` is the page's heading.** On the old `TopAppBar`, `title` was the HTML
|
|
128
|
+
`title` attribute (a native tooltip). It is now the bar's own title and renders
|
|
129
|
+
an `<h1>`. To keep a tooltip, put `title` on an element you pass as a child.
|
|
130
|
+
- **The shell's bar** is the page's `<header>` (a banner landmark) instead of a
|
|
131
|
+
`<div>`. It keeps its `data-slot` names; `app-header-page-title-row` is now the
|
|
132
|
+
title block, always present around the title and the context line. A small
|
|
133
|
+
bar with `hideOnScroll` or tabs still carries `data-variant="small"`. The
|
|
134
|
+
internal `--nxgt-header-h` custom property (never documented) is gone;
|
|
135
|
+
`--nxgt-header-height` still sets the bar's height, and the first-paint total
|
|
136
|
+
`--nxgt-header-total` follows it.
|
|
137
|
+
|
|
138
|
+
## The `data-slot` rename in the next major
|
|
139
|
+
|
|
140
|
+
The shell keeps its `app-header*` `data-slot` names in this minor, so selectors
|
|
141
|
+
and tests written against them keep working; `TopAppBar`'s CSS styles both
|
|
142
|
+
families. The next major renames the slots in the table below. Update selectors then, or now with the new
|
|
143
|
+
names on a `TopAppBar` of your own:
|
|
144
|
+
|
|
145
|
+
| Today (shell) | Next major |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `app-header` | `top-app-bar` |
|
|
148
|
+
| `app-header-page-title` | `top-app-bar-title` |
|
|
149
|
+
| `app-header-headline` | `top-app-bar-headline` |
|
|
150
|
+
| `app-header-collapsed-title` | `top-app-bar-collapsed-title` |
|
|
151
|
+
| `app-header-context` | `top-app-bar-subtitle` |
|
|
152
|
+
| `app-header-tabs` | `top-app-bar-tabs` |
|
|
153
|
+
|
|
154
|
+
The other `app-header*` slots (`app-header-title`, `-title-after`, `-back`, `-menu`) are not in this table: their next-major names are not decided yet, so do not rely on a `top-app-bar-*` equivalent.
|
|
155
|
+
|
|
156
|
+
**Search**: `app-header` in tests, CSS and `data-slot=` selectors.
|
package/docs/guides/theming.md
CHANGED
|
@@ -73,6 +73,7 @@ at the top are needed is in [getting started](../getting-started.md#styles).
|
|
|
73
73
|
| `--error-text` | `text-error-text` | error drawn as text: field messages, `HelperText` in its error state, form and dialog errors, `variant="error"` menu items |
|
|
74
74
|
| `--destructive` | `bg-destructive`, `text-destructive` | deprecated alias of `--error`: the light theme sets it to `var(--error)`, the dark theme keeps its own value; use `--error` |
|
|
75
75
|
| `--ground` | `bg-ground` | the page's ground under `ActivityLayout`: the tinted colour the cards stand on (see [Page ground](#page-ground)) |
|
|
76
|
+
| `--surface-container`, `--surface-container-high` | `bg-surface-container`, `bg-surface-container-high` | tinted chrome: `--surface-container` is the scrolled top app bar (draw it with a 1px `--border` hairline), the primary at 12 % over `--ground` in light (less for a very dark primary, solved per seed) and 26 % in dark; `--surface-container-high` is raised chrome such as a search field, the primary at 16 % over `--background` in light (+4 points over the solved share) and 34 % over `--ground` in dark. Foreground, muted foreground and primary text keep 4.5:1 or more on both, in every preset |
|
|
76
77
|
| `--card`, `--popover`, `--tooltip` (+ `-foreground`) | `bg-card`, `bg-popover`, `bg-tooltip` | surfaces |
|
|
77
78
|
| `--card-edge` | `border-card-edge` | the edge of a `Card`, a `Popover` and a `Dialog`: `var(--border)` in light, `color-mix(in oklab, white 8%, var(--card))` in dark, a hairline lighter than the surface so it lifts off `--ground` |
|
|
78
79
|
| `--border`, `--input`, `--ring` | `border-border`, `border-input`, `ring-ring` | outlines |
|
|
@@ -83,6 +84,10 @@ at the top are needed is in [getting started](../getting-started.md#styles).
|
|
|
83
84
|
| `--nxgt-cards-min`, `--nxgt-cards-gap` | set on the list or an ancestor | the narrowest a `DataTable`/`ServerTable` card is (default `15rem`) with `cardDensity="compact"`, and the gap between cards (`0.75rem`, `0.5rem` when compact): see [Cards and tiles](./cards-and-tiles.md#columns) |
|
|
84
85
|
| `--nxgt-field-radius`, `--nxgt-field-inner-radius` | `rounded-field` (and its sides, `rounded-s-field`…), `rounded-field-inner` | every field's corners, and the corner a field meets its open list with: see [The field box](#the-field-box) |
|
|
85
86
|
|
|
87
|
+
```tsx
|
|
88
|
+
<header className="bg-surface-container border-b border-border" />
|
|
89
|
+
```
|
|
90
|
+
|
|
86
91
|
Some colours are derived rather than tokens of their own:
|
|
87
92
|
`bg-background-paper` (5 % primary), `bg-paper` (0.5 % primary),
|
|
88
93
|
`bg-primary-container`, `bg-secondary-container`, `bg-tertiary-container`,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/roadmap.md
CHANGED
|
@@ -6,12 +6,6 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
6
6
|
|
|
7
7
|
## Now
|
|
8
8
|
|
|
9
|
-
- **App shell header refresh** — `AppHeader` and the look `TopAppBar`
|
|
10
|
-
shares sit flat on the page ground and tint when content scrolls under
|
|
11
|
-
them; the actions are grouped in a pill, the search is a pill field (an
|
|
12
|
-
icon on a phone), and the menu button is a ghost icon button. The new look
|
|
13
|
-
is the default in a minor, with no API change; an A/B preview comes first
|
|
14
|
-
([#2503](https://github.com/softistx/nxgt-material/issues/2503)).
|
|
15
9
|
- **Calculator** — `@nxgt/material/calculator` is an exact-decimal calculator
|
|
16
10
|
(Standard, Scientific, point of sale, Financial, Conversion, Programmer;
|
|
17
11
|
every variant but Standard loads on demand)
|
|
@@ -386,6 +380,23 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
386
380
|
|
|
387
381
|
## Shipped
|
|
388
382
|
|
|
383
|
+
- **App shell header refresh: the TopAppBar family (next minor)** — `TopAppBar`
|
|
384
|
+
takes four sizes (`small`, `medium-flexible`, `large-flexible`, `search`), an
|
|
385
|
+
`align`, a `title` that is the page's `h1` with a `subtitle`, and a collapse
|
|
386
|
+
from large to small on scroll with a morph (snapped under reduced motion).
|
|
387
|
+
It sits flat on the page ground and tints when content scrolls under it,
|
|
388
|
+
with new surface-container tokens. Actions are data (`TopAppBarAction`):
|
|
389
|
+
free icon buttons plus an account menu on the avatar, and a `primaryAction`
|
|
390
|
+
that is a floating button on a phone. `ActivityLayout` draws its bar with it
|
|
391
|
+
(`header` / `handle.header` take the new sizes, `headerActions` takes data,
|
|
392
|
+
`headerPrimaryAction` is new, `headerContext` is the subtitle) and the
|
|
393
|
+
phone's menu button is a ghost icon leading the bar. `AppHeader` and the old
|
|
394
|
+
`variant`, `headline` and `'center'` / `'medium'` / `'large'` values are
|
|
395
|
+
deprecated, and some `app-header*` slots are renamed in the next major (see the guide)
|
|
396
|
+
([#2503](https://github.com/softistx/nxgt-material/issues/2503),
|
|
397
|
+
[guide](guides/app-shell.md#top-app-bar-sizes),
|
|
398
|
+
[moving to `TopAppBar`](guides/migrating-to-top-app-bar.md)).
|
|
399
|
+
|
|
389
400
|
- **Seven more layout recipes (next minor)** — whole screens to start from under Guides/Recipes, each a tested Storybook story with its code in the plugin's `screen-recipes` skill: a team feed, a gallery of pictures by day, sign-in, sign-up and forgotten-password screens, a messages thread, settings with sections, an overview of rearrangeable widgets and a document editor, on the layouts the shell ships ([#2413](https://github.com/softistx/nxgt-material/issues/2413)).
|
|
390
401
|
|
|
391
402
|
- **Search dialog and results page recipe (next patch)** — a command dialog (Ctrl/Cmd+K and a header button), debounced grouped suggestions, type chips, a conditional filter and highlighted result cards, with its code in the plugin's `screen-recipes` skill ([#2333](https://github.com/softistx/nxgt-material/issues/2333)).
|
package/docs/troubleshooting.md
CHANGED
|
@@ -125,6 +125,10 @@ words in your error.
|
|
|
125
125
|
|
|
126
126
|
**Navigation**
|
|
127
127
|
|
|
128
|
+
- [`AppHeader is deprecated, use TopAppBar (ActivityLayout draws its own bar with it)`](#appheader-is-deprecated-use-topappbar-activitylayout-draws-its-own-bar-with-it)
|
|
129
|
+
- [`ActivityLayout: header "center", "medium" or "large" is deprecated`](#activitylayout-header-center-medium-or-large-is-deprecated)
|
|
130
|
+
- [`TopAppBar: variant="medium" is deprecated, use size="medium-flexible"`](#topappbar-variantmedium-is-deprecated-use-sizemedium-flexible)
|
|
131
|
+
- [`TopAppBar: headline is deprecated, use title`](#topappbar-headline-is-deprecated-use-title)
|
|
128
132
|
- [A `ListTile` link shows two chevrons](#a-listtile-link-shows-two-chevrons)
|
|
129
133
|
- [A `ListTile` link reloads the whole page](#a-listtile-link-reloads-the-whole-page)
|
|
130
134
|
- [A `Switcher` in link mode reloads the page](#a-switcher-in-link-mode-reloads-the-page)
|
|
@@ -2350,6 +2354,82 @@ workaround. A `DateField`'s tonal fill is deliberate and not a misalignment.
|
|
|
2350
2354
|
|
|
2351
2355
|
## Navigation
|
|
2352
2356
|
|
|
2357
|
+
### `AppHeader is deprecated, use TopAppBar (ActivityLayout draws its own bar with it)`
|
|
2358
|
+
|
|
2359
|
+
**When:** in development, the first time an `AppHeader` renders. The console
|
|
2360
|
+
line reads `[@nxgt/material] AppHeader: is deprecated, use TopAppBar
|
|
2361
|
+
(ActivityLayout draws its own bar with it)`.
|
|
2362
|
+
|
|
2363
|
+
**Why:** `ActivityLayout` now draws its app bar with `TopAppBar`, and `AppHeader`
|
|
2364
|
+
is a thin wrapper over it, kept so nothing breaks in a minor. It renders a
|
|
2365
|
+
`div`, not a `<header>`, and keeps its `app-header*` slot names.
|
|
2366
|
+
|
|
2367
|
+
**Fix:** inside `ActivityLayout`, nothing to do (the layout does not use the
|
|
2368
|
+
wrapper). In a layout of your own, draw the bar with `TopAppBar` and put the
|
|
2369
|
+
menu button, back arrow and avatar in `leading` and `trailing`:
|
|
2370
|
+
|
|
2371
|
+
```tsx
|
|
2372
|
+
import { TopAppBar } from '@nxgt/material/components';
|
|
2373
|
+
|
|
2374
|
+
<TopAppBar as="header" title="Orders" leading={<MenuButton />} trailing={<Avatar />} />
|
|
2375
|
+
```
|
|
2376
|
+
|
|
2377
|
+
### `ActivityLayout: header "center", "medium" or "large" is deprecated`
|
|
2378
|
+
|
|
2379
|
+
**When:** in development, the first time a `header` value of `'center'`, `'medium'`
|
|
2380
|
+
or `'large'` is read: on `ActivityLayout`, in a route's `handle.header`, or as
|
|
2381
|
+
`variant` in the options. The console line reads `[@nxgt/material] ActivityLayout:
|
|
2382
|
+
header `medium` is deprecated; use 'medium-flexible'.`; for `center` it ends
|
|
2383
|
+
`use { size: 'small', align: 'center' }.` and for `large` `use 'large-flexible'.`.
|
|
2384
|
+
|
|
2385
|
+
**Why:** the shell's bar is a `TopAppBar` now, with `size` and `align` instead of
|
|
2386
|
+
one `variant`. The old values still draw the same bars, so this is a warning,
|
|
2387
|
+
not an error, and it is silent in production.
|
|
2388
|
+
|
|
2389
|
+
**Fix:** spell the new value:
|
|
2390
|
+
|
|
2391
|
+
```tsx
|
|
2392
|
+
// before
|
|
2393
|
+
<ActivityLayout items={items} header="medium" />
|
|
2394
|
+
export const handle = { title: 'Orders', header: { variant: 'center' } };
|
|
2395
|
+
|
|
2396
|
+
// after
|
|
2397
|
+
<ActivityLayout items={items} header="medium-flexible" />
|
|
2398
|
+
export const handle = { title: 'Orders', header: { size: 'small', align: 'center' } };
|
|
2399
|
+
```
|
|
2400
|
+
|
|
2401
|
+
`'none'` stays valid. The full table is in [Moving to TopAppBar](./guides/migrating-to-top-app-bar.md).
|
|
2402
|
+
|
|
2403
|
+
### `TopAppBar: variant="medium" is deprecated, use size="medium-flexible"`
|
|
2404
|
+
|
|
2405
|
+
**When:** in development, the first time a `TopAppBar` renders with `variant="center"`,
|
|
2406
|
+
`"medium"` or `"large"` (`"small"` does not warn). The line names the replacement:
|
|
2407
|
+
`size="small" align="center"`, `size="medium-flexible"` or `size="large-flexible"`.
|
|
2408
|
+
|
|
2409
|
+
**Why:** `variant` is split into `size` and `align`; `size` and `align` win over
|
|
2410
|
+
it when both are given.
|
|
2411
|
+
|
|
2412
|
+
**Fix:** `<TopAppBar size="large-flexible" title="Projects" />`. See
|
|
2413
|
+
[Moving to TopAppBar](./guides/migrating-to-top-app-bar.md).
|
|
2414
|
+
|
|
2415
|
+
### `TopAppBar: headline is deprecated, use title`
|
|
2416
|
+
|
|
2417
|
+
**When:** in development, the first time a `TopAppBar` (or an `AppHeader`) renders
|
|
2418
|
+
a `headline` without a `title`. The line reads `[@nxgt/material] TopAppBar:
|
|
2419
|
+
headline is deprecated, use title (it renders the bar's own h1)`.
|
|
2420
|
+
|
|
2421
|
+
**Why:** `title` is rendered by the bar as the page's one `<h1>`; `headline`
|
|
2422
|
+
renders in a non-heading element, so you had to bring your own heading.
|
|
2423
|
+
|
|
2424
|
+
**Fix:** pass the text as `title` and drop your own `<h1>`:
|
|
2425
|
+
|
|
2426
|
+
```tsx
|
|
2427
|
+
// before
|
|
2428
|
+
<TopAppBar variant="large" headline={<h1>Projects</h1>} />
|
|
2429
|
+
// after
|
|
2430
|
+
<TopAppBar size="large-flexible" title="Projects" />
|
|
2431
|
+
```
|
|
2432
|
+
|
|
2353
2433
|
### A `ListTile` link shows two chevrons
|
|
2354
2434
|
|
|
2355
2435
|
**When:** a `ListTile` with an `href` and a `trailing={<ChevronRight />}` of
|
|
@@ -106,6 +106,8 @@
|
|
|
106
106
|
@import "./rich-chat-composer-expressive.css";
|
|
107
107
|
@import "./ui/actions/toolbar/toolbar-pair.css";
|
|
108
108
|
@import "./ui/layout/app-bar/bottom-app-bar.css";
|
|
109
|
+
@import "./ui/layout/app-bar/top-app-bar/top-app-bar.css";
|
|
110
|
+
@import "./ui/layout/app-bar/top-app-bar/top-app-bar-collapse.css";
|
|
109
111
|
@import "./ui/primitives/label/label.css";
|
|
110
112
|
/* The field box every text field and picker trigger draws: its
|
|
111
113
|
* --nxgt-field-* tokens, its states, its open shape and parts, then forced
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
`body`, so a zone that sets --primary or --background gets its own. A page
|
|
11
11
|
keeps the flat look with `--ground: var(--background)`. */
|
|
12
12
|
--ground: color-mix(in oklab, var(--primary) 7%, var(--background));
|
|
13
|
+
/* The scrolled top app bar (draw a 1px --border hairline with it): the primary at
|
|
14
|
+
12 % over the ground. --surface-container-high is raised chrome such as a search
|
|
15
|
+
field: the primary at 16 % over the page. The default seed solves to 12 and 16;
|
|
16
|
+
palette.test and ground.test guard it. */
|
|
17
|
+
--surface-container: color-mix(in oklab, var(--primary) 12%, var(--ground));
|
|
18
|
+
--surface-container-high: color-mix(
|
|
19
|
+
in oklab,
|
|
20
|
+
var(--primary) 16%,
|
|
21
|
+
var(--background)
|
|
22
|
+
);
|
|
13
23
|
--card: oklch(1 0 0);
|
|
14
24
|
/* The card's edge (Card, Popover, Dialog): the border in light; dark draws it a
|
|
15
25
|
hairline lighter than the card. */
|
|
@@ -114,6 +124,14 @@
|
|
|
114
124
|
var(--primary) 6%,
|
|
115
125
|
color-mix(in oklab, var(--background) 55%, black)
|
|
116
126
|
);
|
|
127
|
+
/* Dark: the primary at 26 % over the ground (the scrolled top app bar) and 34 % over
|
|
128
|
+
the ground (raised chrome such as a search field). */
|
|
129
|
+
--surface-container: color-mix(in oklab, var(--primary) 26%, var(--ground));
|
|
130
|
+
--surface-container-high: color-mix(
|
|
131
|
+
in oklab,
|
|
132
|
+
var(--primary) 34%,
|
|
133
|
+
var(--ground)
|
|
134
|
+
);
|
|
117
135
|
--card: oklch(0.22 0.019 289.4);
|
|
118
136
|
--card-edge: color-mix(in oklab, white 8%, var(--card));
|
|
119
137
|
--card-foreground: oklch(0.943 0.012 291.3);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* Collapse (data-collapse, medium and large): use-header-scroll.ts sets
|
|
2
|
+
* --nxgt-header-progress (0 expanded, 1 collapsed) on the bar as the shell
|
|
3
|
+
* scrolls, and --nxgt-header-extra, the headline row's measured height. The
|
|
4
|
+
* headline gives that height back through a negative margin (the bar clips
|
|
5
|
+
* it), fades, and its title shrinks to 90% from its start edge. The rem values
|
|
6
|
+
* are the height before it is measured (the server, first paint). A bar
|
|
7
|
+
* outside the shell has no progress: 0, the expanded bar. */
|
|
8
|
+
:is(
|
|
9
|
+
[data-slot="top-app-bar"],
|
|
10
|
+
[data-slot="app-header"]
|
|
11
|
+
)[data-collapse][data-size="medium-flexible"] {
|
|
12
|
+
--nxgt-header-extra: 3rem;
|
|
13
|
+
}
|
|
14
|
+
:is(
|
|
15
|
+
[data-slot="top-app-bar"],
|
|
16
|
+
[data-slot="app-header"]
|
|
17
|
+
)[data-collapse][data-size="large-flexible"] {
|
|
18
|
+
--nxgt-header-extra: 6.5rem;
|
|
19
|
+
}
|
|
20
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-collapse]:is(
|
|
21
|
+
[data-size="medium-flexible"],
|
|
22
|
+
[data-size="large-flexible"]
|
|
23
|
+
) {
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-collapse]
|
|
27
|
+
:is([data-slot="top-app-bar-headline"], [data-slot="app-header-headline"]) {
|
|
28
|
+
margin-bottom: calc(
|
|
29
|
+
var(--nxgt-header-extra) *
|
|
30
|
+
var(--nxgt-header-progress, 0) *
|
|
31
|
+
-1
|
|
32
|
+
);
|
|
33
|
+
opacity: clamp(0, calc(1 - var(--nxgt-header-progress, 0) * 1.6), 1);
|
|
34
|
+
transform-origin: left bottom;
|
|
35
|
+
transform: translateY(calc(var(--nxgt-header-progress, 0) * -0.75rem))
|
|
36
|
+
scale(calc(1 - var(--nxgt-header-progress, 0) * 0.1));
|
|
37
|
+
}
|
|
38
|
+
[dir="rtl"]
|
|
39
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-collapse]
|
|
40
|
+
:is([data-slot="top-app-bar-headline"], [data-slot="app-header-headline"]) {
|
|
41
|
+
transform-origin: right bottom;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* The title's copy in the small row (aria-hidden: the headline keeps the one
|
|
45
|
+
* h1, folded away but still in the accessibility tree). It fades in over the
|
|
46
|
+
* second half of the collapse; under reduced motion the progress snaps. */
|
|
47
|
+
:is(
|
|
48
|
+
[data-slot="top-app-bar-collapsed-title"],
|
|
49
|
+
[data-slot="app-header-collapsed-title"]
|
|
50
|
+
) {
|
|
51
|
+
flex: 1;
|
|
52
|
+
min-width: 0;
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
text-overflow: ellipsis;
|
|
55
|
+
white-space: nowrap;
|
|
56
|
+
font-size: 1.125rem;
|
|
57
|
+
line-height: 1.5rem;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
opacity: clamp(0, calc((var(--nxgt-header-progress, 0) - 0.5) * 2), 1);
|
|
60
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/* TopAppBar (issue #2510): flat on the page ground; the scroll tint and a
|
|
2
|
+
* hairline arrive with [data-scrolled]. --surface-container comes from the
|
|
3
|
+
* theme; the fallback keeps the bar right until a theme defines it.
|
|
4
|
+
*
|
|
5
|
+
* The at-rest look (ground, hairline slot, radius, transition) is in
|
|
6
|
+
* `@layer components`, so a `className` background, radius or shadow wins
|
|
7
|
+
* (Tailwind utilities are a later layer). The scrolled tint is not layered: it
|
|
8
|
+
* is the bar's state, and overrides a className background once scrolled. */
|
|
9
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"]) {
|
|
10
|
+
--top-app-bar-tint: var(
|
|
11
|
+
--surface-container,
|
|
12
|
+
color-mix(in oklab, var(--primary) 12%, var(--ground, var(--background)))
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
:is(.dark, [data-theme="dark"])
|
|
16
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"]),
|
|
17
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"]):is(
|
|
18
|
+
.dark,
|
|
19
|
+
[data-theme="dark"]
|
|
20
|
+
) {
|
|
21
|
+
--top-app-bar-tint: var(
|
|
22
|
+
--surface-container,
|
|
23
|
+
color-mix(in oklab, var(--primary) 26%, var(--ground, var(--background)))
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
@layer components {
|
|
27
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"]) {
|
|
28
|
+
background: var(--ground, var(--background));
|
|
29
|
+
box-shadow: inset 0 -1px 0 transparent;
|
|
30
|
+
border-radius: 0;
|
|
31
|
+
transition:
|
|
32
|
+
background-color 200ms ease,
|
|
33
|
+
box-shadow 200ms ease;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-scrolled] {
|
|
37
|
+
background: var(--top-app-bar-tint);
|
|
38
|
+
box-shadow: inset 0 -1px 0 var(--border);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-slot="top-app-bar-row"] {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 1rem;
|
|
45
|
+
padding-inline: 1rem;
|
|
46
|
+
min-height: 3rem;
|
|
47
|
+
}
|
|
48
|
+
[data-slot="top-app-bar-actions"] {
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 0.25rem;
|
|
52
|
+
margin-inline-start: auto;
|
|
53
|
+
}
|
|
54
|
+
:is([data-slot="top-app-bar-tabs"], [data-slot="app-header-tabs"]) {
|
|
55
|
+
padding-inline: 1rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Title block: the h1, and the subtitle after it, stacked. */
|
|
59
|
+
:is(
|
|
60
|
+
[data-slot="top-app-bar-title-block"],
|
|
61
|
+
[data-slot="app-header-page-title-row"]
|
|
62
|
+
) {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
justify-content: center;
|
|
66
|
+
min-width: 0;
|
|
67
|
+
flex: 1;
|
|
68
|
+
gap: 0.0625rem;
|
|
69
|
+
}
|
|
70
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
71
|
+
margin: 0;
|
|
72
|
+
font-size: 1.25rem;
|
|
73
|
+
line-height: 1.5rem;
|
|
74
|
+
font-weight: 700;
|
|
75
|
+
letter-spacing: -0.01em;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
text-overflow: ellipsis;
|
|
78
|
+
white-space: nowrap;
|
|
79
|
+
}
|
|
80
|
+
:is(
|
|
81
|
+
[data-slot="top-app-bar-title"],
|
|
82
|
+
[data-slot="app-header-page-title"]
|
|
83
|
+
):focus-visible {
|
|
84
|
+
outline: none;
|
|
85
|
+
border-radius: 0.25rem;
|
|
86
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent);
|
|
87
|
+
}
|
|
88
|
+
:is([data-slot="top-app-bar-subtitle"], [data-slot="app-header-context"]) {
|
|
89
|
+
margin: 0;
|
|
90
|
+
overflow: hidden;
|
|
91
|
+
text-overflow: ellipsis;
|
|
92
|
+
white-space: nowrap;
|
|
93
|
+
font-size: 0.875rem;
|
|
94
|
+
line-height: 1.25rem;
|
|
95
|
+
font-weight: 500;
|
|
96
|
+
color: var(--muted-foreground);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Medium and large: the title on its own row. */
|
|
100
|
+
:is([data-slot="top-app-bar-headline"], [data-slot="app-header-headline"]) {
|
|
101
|
+
padding: 0.25rem 1rem 0.75rem;
|
|
102
|
+
}
|
|
103
|
+
:is([data-slot="top-app-bar-headline"], [data-slot="app-header-headline"])
|
|
104
|
+
:is(
|
|
105
|
+
[data-slot="top-app-bar-title-block"],
|
|
106
|
+
[data-slot="app-header-page-title-row"]
|
|
107
|
+
) {
|
|
108
|
+
flex: none;
|
|
109
|
+
align-items: flex-start;
|
|
110
|
+
}
|
|
111
|
+
:is([data-slot="top-app-bar-headline"], [data-slot="app-header-headline"])
|
|
112
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
113
|
+
white-space: normal;
|
|
114
|
+
text-wrap: balance;
|
|
115
|
+
letter-spacing: -0.02em;
|
|
116
|
+
}
|
|
117
|
+
:is(
|
|
118
|
+
[data-slot="top-app-bar"],
|
|
119
|
+
[data-slot="app-header"]
|
|
120
|
+
)[data-size="medium-flexible"]
|
|
121
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
122
|
+
font-size: 1.75rem;
|
|
123
|
+
line-height: 2rem;
|
|
124
|
+
}
|
|
125
|
+
:is(
|
|
126
|
+
[data-slot="top-app-bar"],
|
|
127
|
+
[data-slot="app-header"]
|
|
128
|
+
)[data-size="large-flexible"]
|
|
129
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
130
|
+
font-size: 2.5rem;
|
|
131
|
+
line-height: 1.08;
|
|
132
|
+
display: -webkit-box;
|
|
133
|
+
-webkit-box-orient: vertical;
|
|
134
|
+
-webkit-line-clamp: 2;
|
|
135
|
+
line-clamp: 2;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Centre: the row's content and the title block are centred. */
|
|
139
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-align="center"]
|
|
140
|
+
[data-slot="top-app-bar-row"] {
|
|
141
|
+
justify-content: center;
|
|
142
|
+
text-align: center;
|
|
143
|
+
}
|
|
144
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-align="center"]
|
|
145
|
+
:is(
|
|
146
|
+
[data-slot="top-app-bar-title-block"],
|
|
147
|
+
[data-slot="app-header-page-title-row"]
|
|
148
|
+
) {
|
|
149
|
+
align-items: center;
|
|
150
|
+
text-align: center;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Search: the field is the bar's centre; the h1 stays for assistive tech.
|
|
154
|
+
* The bar is positioned only here (its sr-only title is absolute), so a bar
|
|
155
|
+
* can be made `sticky` with a class. */
|
|
156
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-size="search"] {
|
|
157
|
+
position: relative;
|
|
158
|
+
}
|
|
159
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"])[data-size="search"]
|
|
160
|
+
:is(
|
|
161
|
+
[data-slot="top-app-bar-title-block"],
|
|
162
|
+
[data-slot="app-header-page-title-row"]
|
|
163
|
+
) {
|
|
164
|
+
position: absolute;
|
|
165
|
+
width: 1px;
|
|
166
|
+
height: 1px;
|
|
167
|
+
overflow: hidden;
|
|
168
|
+
clip-path: inset(50%);
|
|
169
|
+
white-space: nowrap;
|
|
170
|
+
}
|
|
171
|
+
[data-slot="top-app-bar-search"] {
|
|
172
|
+
flex: 1;
|
|
173
|
+
min-width: 0;
|
|
174
|
+
max-width: 40rem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@media (max-width: 767px) {
|
|
178
|
+
[data-slot="top-app-bar-row"] {
|
|
179
|
+
gap: 0.25rem;
|
|
180
|
+
padding-inline: 0.5rem;
|
|
181
|
+
}
|
|
182
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
183
|
+
font-size: 1.125rem;
|
|
184
|
+
}
|
|
185
|
+
:is(
|
|
186
|
+
[data-slot="top-app-bar"],
|
|
187
|
+
[data-slot="app-header"]
|
|
188
|
+
)[data-size="medium-flexible"]
|
|
189
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
190
|
+
font-size: 1.75rem;
|
|
191
|
+
}
|
|
192
|
+
:is(
|
|
193
|
+
[data-slot="top-app-bar"],
|
|
194
|
+
[data-slot="app-header"]
|
|
195
|
+
)[data-size="large-flexible"]
|
|
196
|
+
:is([data-slot="top-app-bar-title"], [data-slot="app-header-page-title"]) {
|
|
197
|
+
font-size: 2.25rem;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@media (prefers-reduced-motion: reduce) {
|
|
202
|
+
:is([data-slot="top-app-bar"], [data-slot="app-header"]) {
|
|
203
|
+
transition: none;
|
|
204
|
+
}
|
|
205
|
+
}
|