noph-ui 0.51.2 → 0.52.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/dist/animation.d.ts +26 -1
- package/dist/animation.js +50 -2
- package/dist/app-bar/AppBar.svelte +71 -7
- package/dist/app-bar/types.d.ts +6 -0
- package/dist/autocomplete/AutoComplete.svelte +6 -31
- package/dist/autocomplete/AutoComplete.svelte.d.ts +1 -1
- package/dist/badge/Badge.svelte +12 -4
- package/dist/badge/description.d.ts +4 -0
- package/dist/badge/description.js +4 -0
- package/dist/button/Button.svelte +55 -20
- package/dist/button/ButtonGroup.svelte +139 -19
- package/dist/button/ButtonGroup.svelte.d.ts +1 -1
- package/dist/button/IconButton.svelte +49 -18
- package/dist/button/SegmentedButton.svelte +44 -4
- package/dist/button/SplitButton.svelte +77 -3
- package/dist/button/SplitButton.svelte.d.ts +1 -1
- package/dist/button/buttonGroup.d.ts +0 -4
- package/dist/button/buttonGroup.js +0 -9
- package/dist/button/groupContext.d.ts +10 -0
- package/dist/button/groupContext.js +4 -0
- package/dist/button/types.d.ts +19 -0
- package/dist/checkbox/Checkbox.svelte +5 -0
- package/dist/chip/ChipSet.svelte +28 -2
- package/dist/chip/FilterChip.svelte +32 -4
- package/dist/chip/InputChip.svelte +127 -26
- package/dist/chip/SuggestionChip.svelte +6 -22
- package/dist/chip/SuggestionChip.svelte.d.ts +1 -2
- package/dist/chip/types.d.ts +8 -1
- package/dist/date-picker/Calendar.svelte +4 -2
- package/dist/date-picker/DatePickerDialog.svelte +1 -0
- package/dist/date-picker/DatePickerDialog.svelte.d.ts +1 -1
- package/dist/date-picker/DateRangePicker.svelte +1 -0
- package/dist/date-picker/DateRangePicker.svelte.d.ts +1 -1
- package/dist/date-picker/DockedDatePicker.svelte +12 -5
- package/dist/date-picker/DockedDatePicker.svelte.d.ts +1 -1
- package/dist/date-picker/DockedDateTimePicker.svelte +12 -5
- package/dist/date-picker/DockedDateTimePicker.svelte.d.ts +1 -1
- package/dist/date-picker/YearGrid.svelte +4 -2
- package/dist/dialog/Dialog.svelte +171 -33
- package/dist/dialog/Dialog.svelte.d.ts +2 -1
- package/dist/dialog/types.d.ts +6 -0
- package/dist/divider/Divider.svelte +36 -10
- package/dist/divider/types.d.ts +1 -0
- package/dist/fab/ExtendedFab.svelte +26 -60
- package/dist/fab/Fab.svelte +13 -48
- package/dist/fab/FabMenu.svelte +102 -44
- package/dist/fab/FabMenu.svelte.d.ts +2 -1
- package/dist/fab/FabMenuItem.svelte +8 -0
- package/dist/fab/FabMenuItem.svelte.d.ts +4 -0
- package/dist/fab/index.d.ts +1 -0
- package/dist/fab/index.js +1 -0
- package/dist/fab/types.d.ts +6 -4
- package/dist/icons/MenuIcon.svelte +13 -0
- package/dist/icons/MenuIcon.svelte.d.ts +7 -0
- package/dist/icons/MenuOpenIcon.svelte +15 -0
- package/dist/icons/MenuOpenIcon.svelte.d.ts +7 -0
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/index.js +2 -0
- package/dist/internal/exit.css +47 -0
- package/dist/internal/fieldTypes.d.ts +6 -0
- package/dist/internal/focus-ring.css +4 -0
- package/dist/internal/interest.css +3 -1
- package/dist/keyboard-nav.d.ts +12 -1
- package/dist/keyboard-nav.js +104 -14
- package/dist/list/Item.svelte +52 -6
- package/dist/list/List.svelte +35 -2
- package/dist/list/ListItem.svelte +16 -2
- package/dist/list/context.d.ts +6 -0
- package/dist/list/context.js +4 -0
- package/dist/list/types.d.ts +7 -0
- package/dist/media.d.ts +1 -0
- package/dist/media.js +1 -0
- package/dist/menu/Menu.svelte +70 -18
- package/dist/menu/Menu.svelte.d.ts +2 -1
- package/dist/menu/MenuItem.svelte +9 -3
- package/dist/menu/types.d.ts +7 -1
- package/dist/navigation-bar/NavigationBar.svelte +9 -3
- package/dist/navigation-bar/NavigationBarItem.svelte +29 -13
- package/dist/navigation-drawer/NavigationDrawer.svelte +96 -20
- package/dist/navigation-drawer/NavigationDrawer.svelte.d.ts +2 -1
- package/dist/navigation-drawer/NavigationDrawerItem.svelte +8 -3
- package/dist/navigation-drawer/NavigationDrawerSection.svelte +49 -0
- package/dist/navigation-drawer/NavigationDrawerSection.svelte.d.ts +4 -0
- package/dist/navigation-drawer/index.d.ts +1 -0
- package/dist/navigation-drawer/index.js +1 -0
- package/dist/navigation-drawer/types.d.ts +12 -0
- package/dist/navigation-rail/NavigationRail.svelte +367 -7
- package/dist/navigation-rail/NavigationRail.svelte.d.ts +1 -1
- package/dist/navigation-rail/NavigationRailItem.svelte +190 -53
- package/dist/navigation-rail/NavigationRailSection.svelte +57 -0
- package/dist/navigation-rail/NavigationRailSection.svelte.d.ts +4 -0
- package/dist/navigation-rail/context.d.ts +6 -0
- package/dist/navigation-rail/context.js +5 -0
- package/dist/navigation-rail/index.d.ts +1 -0
- package/dist/navigation-rail/index.js +1 -0
- package/dist/navigation-rail/morph.d.ts +14 -0
- package/dist/navigation-rail/morph.js +78 -0
- package/dist/navigation-rail/types.d.ts +21 -0
- package/dist/progress/CircularProgress.svelte +2 -1
- package/dist/progress/LinearProgress.svelte +48 -20
- package/dist/progress/types.d.ts +1 -0
- package/dist/radio/Radio.svelte +7 -1
- package/dist/search/Search.svelte +245 -58
- package/dist/search/types.d.ts +4 -0
- package/dist/select/NativeSelect.svelte +20 -12
- package/dist/select/Option.svelte +1 -2
- package/dist/select/Select.svelte +59 -140
- package/dist/select/VirtualList.svelte +16 -1
- package/dist/select/VirtualList.svelte.d.ts +6 -2
- package/dist/sheet/Sheet.svelte +223 -5
- package/dist/sheet/Sheet.svelte.d.ts +3 -1
- package/dist/sheet/types.d.ts +10 -0
- package/dist/slider/Slider.svelte +1 -27
- package/dist/snackbar/Snackbar.svelte +3 -0
- package/dist/snackbar/Snackbar.svelte.d.ts +2 -1
- package/dist/switch/Switch.svelte +51 -11
- package/dist/tabs/Tab.svelte +28 -14
- package/dist/tabs/Tabs.svelte +28 -4
- package/dist/tabs/types.d.ts +3 -0
- package/dist/text-field/TextField.svelte +49 -13
- package/dist/time-picker/DockedTimePicker.svelte +6 -1
- package/dist/time-picker/DockedTimePicker.svelte.d.ts +1 -1
- package/dist/time-picker/TimePickerDialog.svelte +1 -0
- package/dist/time-picker/TimePickerDialog.svelte.d.ts +1 -1
- package/dist/toolbar/Toolbar.svelte +21 -11
- package/dist/toolbar/types.d.ts +1 -0
- package/dist/tooltip/RichTooltip.svelte.d.ts +1 -1
- package/dist/tooltip/Tooltip.svelte +3 -1
- package/dist/tooltip/Tooltip.svelte.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import '../internal/focus-ring.css'
|
|
3
3
|
import Badge from '../badge/Badge.svelte'
|
|
4
|
+
import { badgeDescription } from '../badge/description.js'
|
|
4
5
|
import Ripple from '../ripple/Ripple.svelte'
|
|
5
6
|
import type { HTMLButtonAttributes } from 'svelte/elements'
|
|
6
7
|
import type { NavigationBarItemProps } from './types.js'
|
|
@@ -18,7 +19,11 @@
|
|
|
18
19
|
...attributes
|
|
19
20
|
}: NavigationBarItemProps = $props()
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
const uid = $props.id()
|
|
23
|
+
let badgeId = $derived(badge ? `${uid}-badge` : undefined)
|
|
24
|
+
let describedBy = $derived(
|
|
25
|
+
[attributes['aria-describedby'], badgeId].filter(Boolean).join(' ') || undefined,
|
|
26
|
+
)
|
|
22
27
|
|
|
23
28
|
let isLink = $derived(attributes.href != null)
|
|
24
29
|
let classes = $derived([
|
|
@@ -32,21 +37,24 @@
|
|
|
32
37
|
|
|
33
38
|
{#snippet content()}
|
|
34
39
|
{#if orientation === 'horizontal'}
|
|
35
|
-
<Ripple forElement={
|
|
40
|
+
<Ripple forElement={element} />
|
|
36
41
|
{/if}
|
|
37
42
|
<span class="np-navigation-bar-item-icon">
|
|
38
43
|
{#if orientation === 'vertical'}
|
|
39
|
-
<Ripple forElement={
|
|
44
|
+
<Ripple forElement={element} />
|
|
40
45
|
{/if}
|
|
41
46
|
{@render icon()}
|
|
42
47
|
{#if badge}
|
|
43
48
|
<span class="np-navigation-bar-item-badge">
|
|
44
|
-
<Badge label={badgeLabel}
|
|
49
|
+
<Badge label={badgeLabel} />
|
|
45
50
|
</span>
|
|
46
51
|
{/if}
|
|
47
52
|
</span>
|
|
48
53
|
<span class="np-navigation-bar-item-label">{label}</span>
|
|
49
|
-
|
|
54
|
+
{#if badgeId}
|
|
55
|
+
<span id={badgeId} hidden>{badgeDescription(badgeLabel, badgeAriaLabel)}</span>
|
|
56
|
+
{/if}
|
|
57
|
+
<span class="np-touch"></span>
|
|
50
58
|
{/snippet}
|
|
51
59
|
|
|
52
60
|
{#if isLink}
|
|
@@ -54,6 +62,7 @@
|
|
|
54
62
|
{...attributes}
|
|
55
63
|
bind:this={element}
|
|
56
64
|
href={attributes.href}
|
|
65
|
+
aria-describedby={describedBy}
|
|
57
66
|
class={classes}
|
|
58
67
|
aria-current={selected ? 'page' : undefined}
|
|
59
68
|
tabindex={selected ? 0 : -1}
|
|
@@ -64,6 +73,7 @@
|
|
|
64
73
|
<button
|
|
65
74
|
{...attributes as HTMLButtonAttributes}
|
|
66
75
|
bind:this={element}
|
|
76
|
+
aria-describedby={describedBy}
|
|
67
77
|
class={classes}
|
|
68
78
|
aria-current={selected ? 'page' : undefined}
|
|
69
79
|
tabindex={selected ? 0 : -1}
|
|
@@ -80,6 +90,8 @@
|
|
|
80
90
|
cursor: pointer;
|
|
81
91
|
font: inherit;
|
|
82
92
|
border-width: 0;
|
|
93
|
+
padding-block: 0;
|
|
94
|
+
padding-inline: 0.375rem;
|
|
83
95
|
background: none;
|
|
84
96
|
display: flex;
|
|
85
97
|
flex-direction: column;
|
|
@@ -150,6 +162,7 @@
|
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
.np-navigation-bar-item-horizontal {
|
|
165
|
+
flex: 0 0 auto;
|
|
153
166
|
flex-direction: row;
|
|
154
167
|
justify-content: center;
|
|
155
168
|
gap: 0.25rem;
|
|
@@ -182,14 +195,12 @@
|
|
|
182
195
|
.np-navigation-bar-item-horizontal .np-navigation-bar-item-icon::before {
|
|
183
196
|
content: none;
|
|
184
197
|
}
|
|
185
|
-
.np-navigation-bar-item-horizontal .np-navigation-bar-item-badge {
|
|
186
|
-
--np-badge-top: -0.25rem;
|
|
187
|
-
--np-badge-end: -0.25rem;
|
|
188
|
-
}
|
|
189
198
|
.np-navigation-bar-item-horizontal .np-touch {
|
|
190
|
-
inset: 0;
|
|
199
|
+
inset-inline: 0;
|
|
200
|
+
inset-block-start: 50%;
|
|
201
|
+
translate: 0 -50%;
|
|
191
202
|
width: 100%;
|
|
192
|
-
height: 100
|
|
203
|
+
height: max(3rem, 100%);
|
|
193
204
|
}
|
|
194
205
|
@media (prefers-reduced-motion: no-preference) {
|
|
195
206
|
.np-navigation-bar-item-horizontal::before {
|
|
@@ -200,10 +211,11 @@
|
|
|
200
211
|
}
|
|
201
212
|
|
|
202
213
|
.np-navigation-bar-item-badge {
|
|
203
|
-
--np-badge-top: 0;
|
|
204
|
-
--np-badge-end: 1rem;
|
|
205
214
|
position: absolute;
|
|
206
215
|
inset: 0;
|
|
216
|
+
width: 1.5rem;
|
|
217
|
+
height: 1.5rem;
|
|
218
|
+
margin: auto;
|
|
207
219
|
pointer-events: none;
|
|
208
220
|
}
|
|
209
221
|
|
|
@@ -221,6 +233,10 @@
|
|
|
221
233
|
outline-offset: 2px;
|
|
222
234
|
border-radius: 1rem;
|
|
223
235
|
}
|
|
236
|
+
/* The focused state layer, on top of the ring. */
|
|
237
|
+
.np-navigation-bar-item:focus-visible :global(.np-ripple-surface)::before {
|
|
238
|
+
opacity: var(--np-ripple-focus-opacity, 0.1);
|
|
239
|
+
}
|
|
224
240
|
|
|
225
241
|
@media (prefers-reduced-motion: no-preference) {
|
|
226
242
|
.np-navigation-bar-item-icon::before {
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import '../internal/exit.css'
|
|
3
|
+
import { exitAnimation } from '../animation.js'
|
|
4
|
+
import { arrowKeyNav, focusableItems, rovingTabindex } from '../keyboard-nav.js'
|
|
3
5
|
import { syncOpenEffect } from '../popover.svelte.js'
|
|
4
6
|
import type { NavigationDrawerProps } from './types.js'
|
|
5
7
|
|
|
6
8
|
let {
|
|
7
9
|
modal = false,
|
|
8
|
-
backdrop =
|
|
9
|
-
open = $bindable(
|
|
10
|
+
backdrop = true,
|
|
11
|
+
open = $bindable(),
|
|
12
|
+
headline,
|
|
10
13
|
element = $bindable(),
|
|
11
14
|
direction,
|
|
12
15
|
children,
|
|
@@ -15,8 +18,10 @@
|
|
|
15
18
|
...attributes
|
|
16
19
|
}: NavigationDrawerProps = $props()
|
|
17
20
|
|
|
18
|
-
const
|
|
19
|
-
const
|
|
21
|
+
const uid = $props.id()
|
|
22
|
+
const ITEMS = '.np-navigation-drawer-item'
|
|
23
|
+
const attach = rovingTabindex(ITEMS)
|
|
24
|
+
const arrowHandler = arrowKeyNav(ITEMS)
|
|
20
25
|
|
|
21
26
|
const handleKeydown = (event: KeyboardEvent & { currentTarget: EventTarget & HTMLElement }) => {
|
|
22
27
|
userKeydown?.(event)
|
|
@@ -40,8 +45,23 @@
|
|
|
40
45
|
show,
|
|
41
46
|
close,
|
|
42
47
|
)
|
|
48
|
+
|
|
49
|
+
// The headline names the navigation unless the drawer is named otherwise.
|
|
50
|
+
let headlineId = $derived(headline ? `${uid}-headline` : undefined)
|
|
51
|
+
let labelledBy = $derived(
|
|
52
|
+
attributes['aria-labelledby'] ?? (attributes['aria-label'] ? undefined : headlineId),
|
|
53
|
+
)
|
|
43
54
|
</script>
|
|
44
55
|
|
|
56
|
+
{#snippet content()}
|
|
57
|
+
<div class="np-navigation-drawer">
|
|
58
|
+
{#if headline}
|
|
59
|
+
<div id={headlineId} class="np-navigation-drawer-headline">{headline}</div>
|
|
60
|
+
{/if}
|
|
61
|
+
{@render children?.()}
|
|
62
|
+
</div>
|
|
63
|
+
{/snippet}
|
|
64
|
+
|
|
45
65
|
{#if modal}
|
|
46
66
|
<dialog
|
|
47
67
|
{...attributes}
|
|
@@ -55,13 +75,15 @@
|
|
|
55
75
|
class={[
|
|
56
76
|
'np-navigation-drawer-container',
|
|
57
77
|
'np-navigation-drawer-container-modal',
|
|
58
|
-
backdrop && 'np-navigation-drawer-backdrop',
|
|
78
|
+
backdrop && 'np-navigation-drawer-backdrop np-exit-scrim',
|
|
59
79
|
attributes.class,
|
|
60
80
|
]}
|
|
81
|
+
{@attach exitAnimation}
|
|
61
82
|
onkeydown={handleKeydown}
|
|
62
83
|
ontoggle={(event) => {
|
|
63
84
|
open = event.newState === 'open'
|
|
64
|
-
|
|
85
|
+
// Focus lands on the first destination, the first interactive element.
|
|
86
|
+
if (open && element) focusableItems(element, ITEMS)[0]?.focus()
|
|
65
87
|
ontoggle?.(event)
|
|
66
88
|
}}
|
|
67
89
|
onclick={(event) => {
|
|
@@ -71,12 +93,10 @@
|
|
|
71
93
|
>
|
|
72
94
|
<nav
|
|
73
95
|
aria-label={attributes['aria-label']}
|
|
74
|
-
aria-labelledby={
|
|
96
|
+
aria-labelledby={labelledBy}
|
|
75
97
|
class="np-navigation-wrapper np-navigation-drawer-shade"
|
|
76
98
|
>
|
|
77
|
-
|
|
78
|
-
{@render children?.()}
|
|
79
|
-
</div>
|
|
99
|
+
{@render content()}
|
|
80
100
|
</nav>
|
|
81
101
|
</dialog>
|
|
82
102
|
{:else}
|
|
@@ -84,13 +104,16 @@
|
|
|
84
104
|
{...attributes}
|
|
85
105
|
{@attach attach}
|
|
86
106
|
bind:this={element}
|
|
87
|
-
|
|
107
|
+
aria-labelledby={labelledBy}
|
|
108
|
+
class={[
|
|
109
|
+
'np-navigation-drawer-container',
|
|
110
|
+
open === false && 'np-navigation-drawer-closed',
|
|
111
|
+
attributes.class,
|
|
112
|
+
]}
|
|
88
113
|
onkeydown={handleKeydown}
|
|
89
114
|
>
|
|
90
115
|
<div class="np-navigation-wrapper">
|
|
91
|
-
|
|
92
|
-
{@render children?.()}
|
|
93
|
-
</div>
|
|
116
|
+
{@render content()}
|
|
94
117
|
</div>
|
|
95
118
|
</nav>
|
|
96
119
|
{/if}
|
|
@@ -98,7 +121,7 @@
|
|
|
98
121
|
<style>
|
|
99
122
|
.np-navigation-drawer-container {
|
|
100
123
|
color: var(--np-color-on-surface-variant);
|
|
101
|
-
width:
|
|
124
|
+
width: var(--np-navigation-drawer-width, 22.5rem);
|
|
102
125
|
border: 0;
|
|
103
126
|
outline: none;
|
|
104
127
|
margin: 0;
|
|
@@ -140,16 +163,28 @@
|
|
|
140
163
|
transform: translateX(0);
|
|
141
164
|
}
|
|
142
165
|
|
|
166
|
+
/* It moves like the modal navigation rail: it springs open and slides back without the spring. */
|
|
143
167
|
@media (prefers-reduced-motion: no-preference) {
|
|
144
168
|
.np-navigation-drawer-container-modal .np-navigation-wrapper {
|
|
145
|
-
|
|
169
|
+
--_motion: var(--np-motion-standard-fast-spatial);
|
|
170
|
+
transition: transform var(--_motion);
|
|
171
|
+
/* Its colour carries on past the window's edge, so the spring shows no gap there. */
|
|
172
|
+
box-shadow:
|
|
173
|
+
var(--_bleed) 0 0 0
|
|
174
|
+
var(--np-navigation-drawer-background, var(--np-color-surface-container-low)),
|
|
175
|
+
var(--np-elevation-1);
|
|
146
176
|
}
|
|
147
177
|
.np-navigation-drawer-container-modal {
|
|
178
|
+
--_bleed: -2rem;
|
|
148
179
|
transition:
|
|
149
|
-
overlay var(--np-motion-standard-
|
|
150
|
-
display var(--np-motion-standard-
|
|
180
|
+
overlay var(--np-motion-standard-fast-spatial) allow-discrete,
|
|
181
|
+
display var(--np-motion-standard-fast-spatial) allow-discrete;
|
|
182
|
+
}
|
|
183
|
+
.np-navigation-drawer-container-modal:dir(rtl) {
|
|
184
|
+
--_bleed: 2rem;
|
|
151
185
|
}
|
|
152
186
|
.np-navigation-drawer-container-modal[open] .np-navigation-wrapper {
|
|
187
|
+
--_motion: var(--np-motion-expressive-default-spatial);
|
|
153
188
|
@starting-style {
|
|
154
189
|
transform: var(--_hidden);
|
|
155
190
|
}
|
|
@@ -158,9 +193,50 @@
|
|
|
158
193
|
|
|
159
194
|
.np-navigation-drawer {
|
|
160
195
|
display: flex;
|
|
161
|
-
padding: var(--np-navigation-drawer-padding,
|
|
196
|
+
padding: var(--np-navigation-drawer-padding, 0.75rem);
|
|
162
197
|
flex-direction: column;
|
|
163
198
|
}
|
|
199
|
+
/* The headline sits like a 56dp row, its text in line with the labels below. */
|
|
200
|
+
.np-navigation-drawer-headline {
|
|
201
|
+
display: flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
min-height: 3.5rem;
|
|
204
|
+
padding-inline: 1rem;
|
|
205
|
+
font-size: 0.875rem;
|
|
206
|
+
line-height: 1.25rem;
|
|
207
|
+
font-weight: 500;
|
|
208
|
+
letter-spacing: 0.006rem;
|
|
209
|
+
color: var(--np-color-on-surface-variant);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* A dismissible standard drawer slides out to the start and gives its space back. */
|
|
213
|
+
.np-navigation-drawer-container:not(.np-navigation-drawer-container-modal) {
|
|
214
|
+
--_hidden: translateX(-100%);
|
|
215
|
+
overflow: hidden;
|
|
216
|
+
}
|
|
217
|
+
.np-navigation-drawer-container:not(.np-navigation-drawer-container-modal):dir(rtl) {
|
|
218
|
+
--_hidden: translateX(100%);
|
|
219
|
+
}
|
|
220
|
+
.np-navigation-drawer-closed {
|
|
221
|
+
width: 0;
|
|
222
|
+
visibility: hidden;
|
|
223
|
+
}
|
|
224
|
+
.np-navigation-drawer-closed .np-navigation-wrapper {
|
|
225
|
+
transform: var(--_hidden);
|
|
226
|
+
}
|
|
227
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
228
|
+
/* visibility stays visible for as long as either end is, so it hides only once the drawer
|
|
229
|
+
has slid out. */
|
|
230
|
+
.np-navigation-drawer-container:not(.np-navigation-drawer-container-modal) {
|
|
231
|
+
transition:
|
|
232
|
+
width var(--np-motion-standard-slow-spatial),
|
|
233
|
+
visibility var(--np-motion-standard-slow-spatial);
|
|
234
|
+
}
|
|
235
|
+
.np-navigation-drawer-container:not(.np-navigation-drawer-container-modal)
|
|
236
|
+
.np-navigation-wrapper {
|
|
237
|
+
transition: transform var(--np-motion-standard-slow-spatial);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
164
240
|
.np-navigation-drawer-shade {
|
|
165
241
|
box-shadow: var(--np-elevation-1);
|
|
166
242
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import '../internal/exit.css';
|
|
1
2
|
import type { NavigationDrawerProps } from './types.js';
|
|
2
3
|
declare const NavigationDrawer: import("svelte").Component<NavigationDrawerProps, {
|
|
3
4
|
show: () => void;
|
|
4
5
|
close: () => void;
|
|
5
|
-
}, "
|
|
6
|
+
}, "open" | "element">;
|
|
6
7
|
type NavigationDrawer = ReturnType<typeof NavigationDrawer>;
|
|
7
8
|
export default NavigationDrawer;
|
|
@@ -95,9 +95,6 @@
|
|
|
95
95
|
height: 100%;
|
|
96
96
|
opacity: 0;
|
|
97
97
|
transform: scaleX(0.32);
|
|
98
|
-
transition-duration: 0.2s;
|
|
99
|
-
transition-property: transform, opacity;
|
|
100
|
-
transition-timing-function: linear;
|
|
101
98
|
background-color: var(--np-color-secondary-container);
|
|
102
99
|
border-radius: var(--np-navigation-drawer-item-container-shape, var(--np-shape-corner-full));
|
|
103
100
|
z-index: -1;
|
|
@@ -107,6 +104,14 @@
|
|
|
107
104
|
opacity: 1;
|
|
108
105
|
transform: scaleX(1);
|
|
109
106
|
}
|
|
107
|
+
/* Like the active indicator in the navigation bar and rail. */
|
|
108
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
109
|
+
.np-navigation-drawer-item::before {
|
|
110
|
+
transition:
|
|
111
|
+
transform var(--np-motion-expressive-default-spatial),
|
|
112
|
+
opacity var(--np-motion-expressive-fast-effects);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
110
115
|
|
|
111
116
|
.np-navigation-drawer-item:focus-visible {
|
|
112
117
|
outline-style: solid;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { NavigationDrawerSectionProps } from './types.js'
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
label,
|
|
6
|
+
children,
|
|
7
|
+
element = $bindable(),
|
|
8
|
+
...attributes
|
|
9
|
+
}: NavigationDrawerSectionProps = $props()
|
|
10
|
+
|
|
11
|
+
const uid = $props.id()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<!-- A group of related destinations, set off by a divider and named by its label. -->
|
|
15
|
+
<div
|
|
16
|
+
{...attributes}
|
|
17
|
+
bind:this={element}
|
|
18
|
+
role="group"
|
|
19
|
+
aria-labelledby="{uid}-label"
|
|
20
|
+
class={['np-navigation-drawer-section', attributes.class]}
|
|
21
|
+
>
|
|
22
|
+
<div class="np-navigation-drawer-section-divider"></div>
|
|
23
|
+
<div id="{uid}-label" class="np-navigation-drawer-section-label">{label}</div>
|
|
24
|
+
{@render children?.()}
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<style>
|
|
28
|
+
.np-navigation-drawer-section {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
}
|
|
32
|
+
/* 16dp above, and 28dp in from both edges of the drawer, like the labels. */
|
|
33
|
+
.np-navigation-drawer-section-divider {
|
|
34
|
+
height: 1px;
|
|
35
|
+
margin: 1rem 1rem 0;
|
|
36
|
+
background-color: var(--np-divider-color, var(--np-color-outline-variant));
|
|
37
|
+
}
|
|
38
|
+
.np-navigation-drawer-section-label {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
min-height: 3.5rem;
|
|
42
|
+
padding-inline: 1rem;
|
|
43
|
+
font-size: 0.875rem;
|
|
44
|
+
line-height: 1.25rem;
|
|
45
|
+
font-weight: 500;
|
|
46
|
+
letter-spacing: 0.006rem;
|
|
47
|
+
color: var(--np-color-on-surface-variant);
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NavigationDrawerSectionProps } from './types.js';
|
|
2
|
+
declare const NavigationDrawerSection: import("svelte").Component<NavigationDrawerSectionProps, {}, "element">;
|
|
3
|
+
type NavigationDrawerSection = ReturnType<typeof NavigationDrawerSection>;
|
|
4
|
+
export default NavigationDrawerSection;
|
|
@@ -2,8 +2,15 @@ import type { Snippet } from 'svelte';
|
|
|
2
2
|
import type { HTMLAnchorAttributes, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
export interface NavigationDrawerProps extends HTMLAttributes<HTMLElement> {
|
|
4
4
|
modal?: boolean;
|
|
5
|
+
/** The scrim behind a modal drawer. On by default, as Material 3 asks. */
|
|
5
6
|
backdrop?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Modal: whether the drawer is open. Standard: leave it out for a drawer that is always there,
|
|
9
|
+
* or set it to make the drawer dismissible, sliding in and out.
|
|
10
|
+
*/
|
|
6
11
|
open?: boolean;
|
|
12
|
+
/** A headline above the destinations. It names the navigation unless `aria-label` does. */
|
|
13
|
+
headline?: string;
|
|
7
14
|
element?: HTMLElement;
|
|
8
15
|
/**
|
|
9
16
|
* The edge the modal drawer slides in from: `ltr` from the left, `rtl` from the right. Leave it
|
|
@@ -21,3 +28,8 @@ export interface NavigationDrawerItemProps extends HTMLAttributes<NavigationDraw
|
|
|
21
28
|
type?: 'submit' | 'reset' | 'button' | (string & {}) | null;
|
|
22
29
|
element?: NavigationDrawerItemElement;
|
|
23
30
|
}
|
|
31
|
+
export interface NavigationDrawerSectionProps extends HTMLAttributes<HTMLDivElement> {
|
|
32
|
+
/** The section label, shown above the destinations and naming the group. */
|
|
33
|
+
label: string;
|
|
34
|
+
element?: HTMLDivElement;
|
|
35
|
+
}
|