@14ch/svelte-ui 0.0.29 → 0.0.30
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.
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import NavItem from './NavItem.svelte';
|
|
5
5
|
import type { NavItemSelectedStyle } from './NavItem.svelte';
|
|
6
6
|
import type { MenuItem } from '../types/menuItem';
|
|
7
|
-
import type { NavVariant,
|
|
7
|
+
import type { NavVariant, ChildrenVariant } from '../types/propOptions';
|
|
8
8
|
import { subscribeUrlChange } from '../utils/urlChange';
|
|
9
9
|
import { getCurrentPath, matchPath } from '../utils/navPath';
|
|
10
10
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
/** Visual style for the selected item. */
|
|
40
40
|
selectedStyle?: NavItemSelectedStyle;
|
|
41
41
|
gap?: number | string;
|
|
42
|
-
/**
|
|
43
|
-
|
|
42
|
+
/** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
|
|
43
|
+
childrenVariant?: ChildrenVariant;
|
|
44
44
|
/** Show chevron icon on parent items. @default true */
|
|
45
45
|
chevron?: boolean;
|
|
46
46
|
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
// スタイル/レイアウト
|
|
71
71
|
selectedStyle,
|
|
72
72
|
gap,
|
|
73
|
-
|
|
73
|
+
childrenVariant = variant === 'mobile' ? 'bottom-sheet' : variant === 'vertical' ? 'accordion' : 'bar',
|
|
74
74
|
chevron,
|
|
75
75
|
|
|
76
76
|
// ARIA/アクセシビリティ
|
|
@@ -95,13 +95,13 @@
|
|
|
95
95
|
$effect(() => {
|
|
96
96
|
return subscribeUrlChange(() => {
|
|
97
97
|
resolvedCurrentPath = getCurrentPath(currentPath);
|
|
98
|
-
if (
|
|
98
|
+
if (childrenVariant !== 'accordion') expandedParent = null;
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
// accordion モード: アクティブな子を持つ親を自動展開
|
|
103
103
|
$effect(() => {
|
|
104
|
-
if (
|
|
104
|
+
if (childrenVariant !== 'accordion' || !resolvedCurrentPath) return;
|
|
105
105
|
const activeParent = navItems.find((item) =>
|
|
106
106
|
item.children?.some(
|
|
107
107
|
(child) =>
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
|
|
125
125
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
126
126
|
// accordion/expanded は子アイテムも DOM 順で含める
|
|
127
|
-
const includeChildren =
|
|
127
|
+
const includeChildren = childrenVariant === 'accordion' || childrenVariant === 'expanded';
|
|
128
128
|
const selector = includeChildren ? '[data-nav-item], [data-nav-item-child]' : '[data-nav-item]';
|
|
129
129
|
const navItemEls = Array.from(
|
|
130
130
|
(event.currentTarget as HTMLElement).querySelectorAll<HTMLElement>(selector)
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
if (currentIndex === -1) return;
|
|
137
137
|
|
|
138
138
|
// bar モード: 展開中の親で ArrowDown → サブバーの最初の子へ
|
|
139
|
-
if (
|
|
139
|
+
if (childrenVariant === 'bar' && event.key === 'ArrowDown' && showSubBar) {
|
|
140
140
|
const allNavItemEls = Array.from(
|
|
141
141
|
(event.currentTarget as HTMLElement).querySelectorAll<HTMLElement>('[data-nav-item]')
|
|
142
142
|
);
|
|
@@ -211,8 +211,8 @@
|
|
|
211
211
|
}
|
|
212
212
|
};
|
|
213
213
|
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
214
|
+
const handleToggle = (item: MenuItem) => {
|
|
215
|
+
if (childrenVariant === 'accordion') {
|
|
216
216
|
// accordion: 開くのみ(再クリックで閉じない、他は自動的に閉じる)
|
|
217
217
|
expandedParent = item;
|
|
218
218
|
} else {
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
return i;
|
|
232
232
|
}
|
|
233
233
|
// bar モード: 子が選択されていれば親も選択とみなす
|
|
234
|
-
if (
|
|
234
|
+
if (childrenVariant === 'bar' && item.children?.some(
|
|
235
235
|
(child) => child.href && matchPath(resolvedCurrentPath, child.href, child, pathPrefix, customPathMatcher)
|
|
236
236
|
)) {
|
|
237
237
|
return i;
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
});
|
|
242
242
|
|
|
243
243
|
const showSubBar = $derived(
|
|
244
|
-
variant === 'horizontal' &&
|
|
244
|
+
variant === 'horizontal' && childrenVariant === 'bar' && expandedParent != null
|
|
245
245
|
);
|
|
246
246
|
|
|
247
247
|
const isChildSelected = (child: MenuItem) =>
|
|
@@ -271,13 +271,13 @@
|
|
|
271
271
|
{iconOpticalSize}
|
|
272
272
|
{iconVariant}
|
|
273
273
|
{selectedStyle}
|
|
274
|
-
{
|
|
274
|
+
{childrenVariant}
|
|
275
275
|
{chevron}
|
|
276
276
|
{resolvedCurrentPath}
|
|
277
277
|
{customPathMatcher}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
isChildrenExpanded={(childrenVariant === 'bar' || childrenVariant === 'accordion') && expandedParent === item}
|
|
279
|
+
onChildrenToggle={handleToggle}
|
|
280
|
+
onChildrenClose={() => { expandedParent = null; }}
|
|
281
281
|
/>
|
|
282
282
|
{/each}
|
|
283
283
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { NavItemSelectedStyle } from './NavItem.svelte';
|
|
2
2
|
import type { MenuItem } from '../types/menuItem';
|
|
3
|
-
import type { NavVariant,
|
|
3
|
+
import type { NavVariant, ChildrenVariant } from '../types/propOptions';
|
|
4
4
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
5
5
|
export type NavProps = {
|
|
6
6
|
/** `{ label, href, icon?, children?, disabled? }[]` */
|
|
@@ -22,8 +22,8 @@ export type NavProps = {
|
|
|
22
22
|
/** Visual style for the selected item. */
|
|
23
23
|
selectedStyle?: NavItemSelectedStyle;
|
|
24
24
|
gap?: number | string;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
|
|
26
|
+
childrenVariant?: ChildrenVariant;
|
|
27
27
|
/** Show chevron icon on parent items. @default true */
|
|
28
28
|
chevron?: boolean;
|
|
29
29
|
ariaLabel?: string;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { fade, fly, slide } from 'svelte/transition';
|
|
8
8
|
import type { PopupPosition } from '../types/propOptions';
|
|
9
9
|
import type { MenuItem } from '../types/menuItem';
|
|
10
|
-
import type { NavVariant,
|
|
10
|
+
import type { NavVariant, ChildrenVariant } from '../types/propOptions';
|
|
11
11
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
12
12
|
import { tick } from 'svelte';
|
|
13
13
|
import { matchPath } from '../utils/navPath';
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
item: MenuItem;
|
|
23
23
|
variant?: NavVariant;
|
|
24
24
|
pathPrefix?: string;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
|
|
25
|
+
/** Current URL path passed from Nav for computing child selected state. */
|
|
26
|
+
resolvedCurrentPath?: string;
|
|
27
|
+
/** Custom function to determine if a child item is active. */
|
|
28
|
+
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
29
29
|
|
|
30
30
|
// アイコン関連
|
|
31
31
|
iconFilled?: boolean;
|
|
@@ -34,26 +34,26 @@
|
|
|
34
34
|
iconOpticalSize?: IconOpticalSize;
|
|
35
35
|
iconVariant?: IconVariant;
|
|
36
36
|
|
|
37
|
+
// スタイル/レイアウト
|
|
38
|
+
/** Show chevron icon on parent items. @default true */
|
|
39
|
+
chevron?: boolean;
|
|
40
|
+
selectedStyle?: NavItemSelectedStyle;
|
|
41
|
+
/** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
|
|
42
|
+
childrenVariant?: ChildrenVariant;
|
|
43
|
+
|
|
37
44
|
// 状態/動作
|
|
38
45
|
isSelected?: boolean;
|
|
39
46
|
isDisabled?: boolean;
|
|
40
|
-
selectedStyle?: NavItemSelectedStyle;
|
|
41
|
-
|
|
42
|
-
// サブメニュー関連
|
|
43
|
-
/** Sub-menu display mode. @default 'popup' */
|
|
44
|
-
subMenuMode?: SubMenuMode;
|
|
45
47
|
/** When true, this item does not render its own children (prevents infinite recursion). */
|
|
46
48
|
isChild?: boolean;
|
|
47
|
-
/** Current URL path passed from Nav for computing child selected state. */
|
|
48
|
-
resolvedCurrentPath?: string;
|
|
49
|
-
/** Custom function to determine if a child item is active. */
|
|
50
|
-
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
51
49
|
/** For bar/accordion mode: whether this item's sub-menu is currently expanded. */
|
|
52
|
-
|
|
50
|
+
isChildrenExpanded?: boolean;
|
|
51
|
+
|
|
52
|
+
// イベントハンドラ
|
|
53
53
|
/** For bar/accordion mode: called when this parent is clicked. */
|
|
54
|
-
|
|
54
|
+
onChildrenToggle?: (item: MenuItem) => void;
|
|
55
55
|
/** Called when a leaf item (no children) is clicked — used to close any open sub-menu. */
|
|
56
|
-
|
|
56
|
+
onChildrenClose?: () => void;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
let {
|
|
@@ -61,6 +61,8 @@
|
|
|
61
61
|
item,
|
|
62
62
|
variant = 'horizontal',
|
|
63
63
|
pathPrefix = '',
|
|
64
|
+
resolvedCurrentPath = '',
|
|
65
|
+
customPathMatcher,
|
|
64
66
|
|
|
65
67
|
// アイコン関連
|
|
66
68
|
iconFilled = false,
|
|
@@ -71,20 +73,18 @@
|
|
|
71
73
|
|
|
72
74
|
// スタイル/レイアウト
|
|
73
75
|
chevron = true,
|
|
76
|
+
selectedStyle,
|
|
77
|
+
childrenVariant = variant === 'mobile' ? 'bottom-sheet' : variant === 'vertical' ? 'accordion' : 'bar',
|
|
74
78
|
|
|
75
79
|
// 状態/動作
|
|
76
80
|
isSelected = false,
|
|
77
81
|
isDisabled = false,
|
|
78
|
-
selectedStyle,
|
|
79
|
-
|
|
80
|
-
// サブメニュー関連
|
|
81
|
-
subMenuMode = 'popup',
|
|
82
82
|
isChild = false,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
isChildrenExpanded = false,
|
|
84
|
+
|
|
85
|
+
// イベントハンドラ
|
|
86
|
+
onChildrenToggle,
|
|
87
|
+
onChildrenClose
|
|
88
88
|
}: NavItemProps = $props();
|
|
89
89
|
|
|
90
90
|
// =========================================================================
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
// =========================================================================
|
|
122
122
|
// States
|
|
123
123
|
// =========================================================================
|
|
124
|
-
let
|
|
124
|
+
let isChildrenOpen = $state(false);
|
|
125
125
|
let anchorEl: HTMLElement | undefined = $state();
|
|
126
126
|
let popupMenuRef: PopupMenu | undefined = $state();
|
|
127
127
|
let isPopupOpen = $state(false);
|
|
@@ -131,60 +131,60 @@
|
|
|
131
131
|
container?.querySelector<HTMLElement>('[data-nav-item-child]:not([tabindex="-1"])')?.focus();
|
|
132
132
|
|
|
133
133
|
$effect(() => {
|
|
134
|
-
if (
|
|
134
|
+
if (isChildrenOpen) tick().then(() => focusFirstChild(bottomSheetEl));
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
const popupPosition = $derived<PopupPosition>(
|
|
138
138
|
variant === 'vertical' ? 'right-top' : variant === 'mobile' ? 'top-center' : 'bottom-left'
|
|
139
139
|
);
|
|
140
140
|
|
|
141
|
-
const
|
|
141
|
+
const isChildrenVisible = $derived(
|
|
142
142
|
!hasChildren
|
|
143
143
|
? false
|
|
144
|
-
:
|
|
144
|
+
: childrenVariant === 'expanded'
|
|
145
145
|
? true
|
|
146
|
-
:
|
|
147
|
-
?
|
|
148
|
-
:
|
|
146
|
+
: childrenVariant === 'bottom-sheet'
|
|
147
|
+
? isChildrenOpen
|
|
148
|
+
: childrenVariant === 'popup'
|
|
149
149
|
? isPopupOpen
|
|
150
|
-
:
|
|
150
|
+
: isChildrenExpanded
|
|
151
151
|
);
|
|
152
152
|
|
|
153
153
|
const showChevron = $derived(hasChildren && chevron && variant !== 'mobile');
|
|
154
154
|
|
|
155
155
|
// popup の方向に合わせたアイコン。それ以外は expand_more
|
|
156
156
|
const chevronIcon = $derived(
|
|
157
|
-
|
|
157
|
+
childrenVariant === 'popup' && variant === 'vertical'
|
|
158
158
|
? 'arrow_right'
|
|
159
|
-
:
|
|
159
|
+
: childrenVariant === 'popup' && variant === 'horizontal'
|
|
160
160
|
? 'arrow_drop_down'
|
|
161
161
|
: 'expand_more'
|
|
162
162
|
);
|
|
163
163
|
|
|
164
164
|
// popup 専用アイコンは方向固定なので展開時も回転しない
|
|
165
|
-
const chevronRotates = $derived(
|
|
165
|
+
const chevronRotates = $derived(childrenVariant !== 'popup');
|
|
166
166
|
|
|
167
167
|
// =========================================================================
|
|
168
168
|
// Methods
|
|
169
169
|
// =========================================================================
|
|
170
|
-
const
|
|
171
|
-
|
|
170
|
+
const toggleOpen = () => {
|
|
171
|
+
isChildrenOpen = !isChildrenOpen;
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
-
const
|
|
175
|
-
|
|
174
|
+
const closeOpen = () => {
|
|
175
|
+
isChildrenOpen = false;
|
|
176
176
|
};
|
|
177
177
|
|
|
178
178
|
// popup の ArrowRight(vertical) / ArrowDown(horizontal) でサブメニューを開く
|
|
179
179
|
const handleTriggerKeyDown = (event: KeyboardEvent) => {
|
|
180
|
-
if (!hasChildren ||
|
|
180
|
+
if (!hasChildren || childrenVariant !== 'popup' || isPopupOpen) return;
|
|
181
181
|
const openKey = variant === 'vertical' ? 'ArrowRight' : 'ArrowDown';
|
|
182
182
|
if (event.key !== openKey) return;
|
|
183
183
|
event.preventDefault();
|
|
184
184
|
popupMenuRef?.toggle();
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
-
const
|
|
187
|
+
const handleChildKeyDown = (event: KeyboardEvent, horizontal = false) => {
|
|
188
188
|
const container = event.currentTarget as HTMLElement;
|
|
189
189
|
const items = Array.from(
|
|
190
190
|
container.querySelectorAll<HTMLElement>('[data-nav-item-child]:not([tabindex="-1"])')
|
|
@@ -213,9 +213,9 @@
|
|
|
213
213
|
items[items.length - 1]?.focus();
|
|
214
214
|
break;
|
|
215
215
|
case 'Escape':
|
|
216
|
-
if (
|
|
216
|
+
if (childrenVariant === 'bottom-sheet') {
|
|
217
217
|
event.preventDefault();
|
|
218
|
-
|
|
218
|
+
closeOpen();
|
|
219
219
|
anchorEl?.focus();
|
|
220
220
|
}
|
|
221
221
|
break;
|
|
@@ -223,12 +223,12 @@
|
|
|
223
223
|
};
|
|
224
224
|
|
|
225
225
|
const handleLinkClick = () => {
|
|
226
|
-
if (
|
|
226
|
+
if (childrenVariant === 'popup') {
|
|
227
227
|
popupMenuRef?.toggle();
|
|
228
|
-
} else if (
|
|
229
|
-
|
|
228
|
+
} else if (childrenVariant === 'bottom-sheet') {
|
|
229
|
+
toggleOpen();
|
|
230
230
|
} else {
|
|
231
|
-
|
|
231
|
+
onChildrenToggle?.(item);
|
|
232
232
|
}
|
|
233
233
|
};
|
|
234
234
|
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
=================================================================== -->
|
|
274
274
|
<div
|
|
275
275
|
class="nav-item__group nav-item__group--{variant}"
|
|
276
|
-
class:nav-item__group--open={
|
|
276
|
+
class:nav-item__group--open={isChildrenVisible}
|
|
277
277
|
>
|
|
278
278
|
<a
|
|
279
279
|
href={resolvedParentHref}
|
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
class:nav-item--style-tonal={isSelected && resolvedSelectedStyle === 'tonal'}
|
|
286
286
|
class:nav-item--style-underline={resolvedSelectedStyle === 'underline'}
|
|
287
287
|
aria-current={isSelected ? 'page' : undefined}
|
|
288
|
-
aria-expanded={
|
|
288
|
+
aria-expanded={childrenVariant === 'popup' ? isPopupOpen : isChildrenExpanded}
|
|
289
289
|
tabindex={0}
|
|
290
290
|
data-nav-item
|
|
291
291
|
data-testid="nav-item"
|
|
@@ -309,7 +309,7 @@
|
|
|
309
309
|
{#if showChevron}
|
|
310
310
|
<div
|
|
311
311
|
class="nav-item__chevron"
|
|
312
|
-
class:nav-item__chevron--expanded={chevronRotates &&
|
|
312
|
+
class:nav-item__chevron--expanded={chevronRotates && isChildrenVisible}
|
|
313
313
|
>
|
|
314
314
|
<Icon
|
|
315
315
|
weight={iconWeight}
|
|
@@ -322,7 +322,7 @@
|
|
|
322
322
|
</a>
|
|
323
323
|
|
|
324
324
|
<!-- popup サブメニュー -->
|
|
325
|
-
{#if
|
|
325
|
+
{#if childrenVariant === 'popup'}
|
|
326
326
|
<PopupMenu
|
|
327
327
|
bind:this={popupMenuRef}
|
|
328
328
|
bind:isOpen={isPopupOpen}
|
|
@@ -339,7 +339,7 @@
|
|
|
339
339
|
{/if}
|
|
340
340
|
|
|
341
341
|
<!-- accordion / expanded サブメニュー -->
|
|
342
|
-
{#if (
|
|
342
|
+
{#if (childrenVariant === 'accordion' || childrenVariant === 'expanded') && isChildrenVisible}
|
|
343
343
|
<div class="nav-item__children" role="presentation" transition:slide={{ duration: 200 }}>
|
|
344
344
|
{#each item.children! as child}
|
|
345
345
|
<NavItem
|
|
@@ -363,11 +363,11 @@
|
|
|
363
363
|
{/if}
|
|
364
364
|
|
|
365
365
|
<!-- bottom-sheet オーバーレイ -->
|
|
366
|
-
{#if
|
|
366
|
+
{#if childrenVariant === 'bottom-sheet' && isChildrenOpen}
|
|
367
367
|
<div
|
|
368
368
|
class="nav-item__bottom-sheet-backdrop"
|
|
369
369
|
role="presentation"
|
|
370
|
-
onclick={
|
|
370
|
+
onclick={closeOpen}
|
|
371
371
|
transition:fade={{ duration: 200 }}
|
|
372
372
|
></div>
|
|
373
373
|
<div
|
|
@@ -375,7 +375,7 @@
|
|
|
375
375
|
role="menu"
|
|
376
376
|
tabindex="-1"
|
|
377
377
|
transition:fly={{ y: 100, duration: 250 }}
|
|
378
|
-
onkeydown={(e) =>
|
|
378
|
+
onkeydown={(e) => handleChildKeyDown(e, true)}
|
|
379
379
|
bind:this={bottomSheetEl}
|
|
380
380
|
>
|
|
381
381
|
{#each item.children! as child}
|
|
@@ -394,7 +394,7 @@
|
|
|
394
394
|
{customPathMatcher}
|
|
395
395
|
isSelected={isChildSelected(child)}
|
|
396
396
|
isDisabled={child.disabled ?? false}
|
|
397
|
-
|
|
397
|
+
onChildrenClose={closeOpen}
|
|
398
398
|
/>
|
|
399
399
|
{/each}
|
|
400
400
|
</div>
|
|
@@ -418,7 +418,7 @@
|
|
|
418
418
|
data-nav-item={!isChild ? '' : undefined}
|
|
419
419
|
data-nav-item-child={isChild ? '' : undefined}
|
|
420
420
|
data-testid="nav-item"
|
|
421
|
-
onclick={
|
|
421
|
+
onclick={onChildrenClose}
|
|
422
422
|
>
|
|
423
423
|
{#if item.icon}
|
|
424
424
|
<div class="nav-item__icon">
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import NavItem from './NavItem.svelte';
|
|
2
2
|
import type { MenuItem } from '../types/menuItem';
|
|
3
|
-
import type { NavVariant,
|
|
3
|
+
import type { NavVariant, ChildrenVariant } from '../types/propOptions';
|
|
4
4
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
5
5
|
export type NavItemSelectedStyle = 'color' | 'filled' | 'tonal' | 'underline';
|
|
6
6
|
export type NavItemProps = {
|
|
7
7
|
item: MenuItem;
|
|
8
8
|
variant?: NavVariant;
|
|
9
9
|
pathPrefix?: string;
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/** Current URL path passed from Nav for computing child selected state. */
|
|
11
|
+
resolvedCurrentPath?: string;
|
|
12
|
+
/** Custom function to determine if a child item is active. */
|
|
13
|
+
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
12
14
|
iconFilled?: boolean;
|
|
13
15
|
iconWeight?: IconWeight;
|
|
14
16
|
iconGrade?: IconGrade;
|
|
15
17
|
iconOpticalSize?: IconOpticalSize;
|
|
16
18
|
iconVariant?: IconVariant;
|
|
19
|
+
/** Show chevron icon on parent items. @default true */
|
|
20
|
+
chevron?: boolean;
|
|
21
|
+
selectedStyle?: NavItemSelectedStyle;
|
|
22
|
+
/** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
|
|
23
|
+
childrenVariant?: ChildrenVariant;
|
|
17
24
|
isSelected?: boolean;
|
|
18
25
|
isDisabled?: boolean;
|
|
19
|
-
selectedStyle?: NavItemSelectedStyle;
|
|
20
|
-
/** Sub-menu display mode. @default 'popup' */
|
|
21
|
-
subMenuMode?: SubMenuMode;
|
|
22
26
|
/** When true, this item does not render its own children (prevents infinite recursion). */
|
|
23
27
|
isChild?: boolean;
|
|
24
|
-
/** Current URL path passed from Nav for computing child selected state. */
|
|
25
|
-
resolvedCurrentPath?: string;
|
|
26
|
-
/** Custom function to determine if a child item is active. */
|
|
27
|
-
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
28
28
|
/** For bar/accordion mode: whether this item's sub-menu is currently expanded. */
|
|
29
|
-
|
|
29
|
+
isChildrenExpanded?: boolean;
|
|
30
30
|
/** For bar/accordion mode: called when this parent is clicked. */
|
|
31
|
-
|
|
31
|
+
onChildrenToggle?: (item: MenuItem) => void;
|
|
32
32
|
/** Called when a leaf item (no children) is clicked — used to close any open sub-menu. */
|
|
33
|
-
|
|
33
|
+
onChildrenClose?: () => void;
|
|
34
34
|
};
|
|
35
35
|
declare const NavItem: import("svelte").Component<NavItemProps, {}, "">;
|
|
36
36
|
type NavItem = ReturnType<typeof NavItem>;
|
package/dist/index.d.ts
CHANGED
|
@@ -78,7 +78,7 @@ export type { NavProps } from './components/Nav.svelte';
|
|
|
78
78
|
export type { NavItemProps, NavItemSelectedStyle } from './components/NavItem.svelte';
|
|
79
79
|
export type { TabProps } from './components/Tab.svelte';
|
|
80
80
|
export type { TextareaProps } from './components/Textarea.svelte';
|
|
81
|
-
export type { PopupPosition, SnackbarPosition, FabPosition, ButtonVariant, ButtonSize, SnackbarType, SnackbarVariant, BadgeVariant, DatepickerMode, FocusStyle, NavVariant,
|
|
81
|
+
export type { PopupPosition, SnackbarPosition, FabPosition, ButtonVariant, ButtonSize, SnackbarType, SnackbarVariant, BadgeVariant, DatepickerMode, FocusStyle, NavVariant, ChildrenVariant } from './types/propOptions';
|
|
82
82
|
export type { MenuItem } from './types/menuItem';
|
|
83
83
|
export type { SegmentedControlItem } from './types/segmentedControlItem';
|
|
84
84
|
export type { Option, OptionValue } from './types/options';
|
|
@@ -58,11 +58,11 @@ export type FocusStyle = 'background' | 'outline' | 'none';
|
|
|
58
58
|
*/
|
|
59
59
|
export type NavVariant = 'vertical' | 'horizontal' | 'mobile';
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Display variant for Nav hierarchical (children) menus.
|
|
62
62
|
* - `popup`: child items appear in a floating panel (all variants)
|
|
63
63
|
* - `accordion`: child items expand/collapse inline (vertical only)
|
|
64
64
|
* - `expanded`: child items are always visible inline (vertical only)
|
|
65
65
|
* - `bar`: child items appear in a secondary bar below the nav (horizontal only)
|
|
66
66
|
* - `bottom-sheet`: child items appear in a fixed bottom sheet overlay (mobile only)
|
|
67
67
|
*/
|
|
68
|
-
export type
|
|
68
|
+
export type ChildrenVariant = 'popup' | 'accordion' | 'expanded' | 'bar' | 'bottom-sheet';
|