@14ch/svelte-ui 0.0.25 → 0.0.26
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.
|
@@ -376,7 +376,6 @@
|
|
|
376
376
|
/* Nav */
|
|
377
377
|
--svelte-ui-nav-item-text-color: var(--svelte-ui-text-color);
|
|
378
378
|
--svelte-ui-nav-item-selected-text-color: var(--svelte-ui-primary-color);
|
|
379
|
-
--svelte-ui-nav-item-selected-bg-color: var(--svelte-ui-hover-overlay);
|
|
380
379
|
--svelte-ui-nav-item-filled-text-color: #ffffff;
|
|
381
380
|
--svelte-ui-nav-item-tonal-bg-color: color-mix(
|
|
382
381
|
in srgb,
|
|
@@ -394,11 +393,9 @@
|
|
|
394
393
|
--svelte-ui-nav-mobile-item-padding: 8px;
|
|
395
394
|
--svelte-ui-nav-mobile-item-icon-gap: 8px;
|
|
396
395
|
--svelte-ui-nav-mobile-item-font-size: 0.75rem;
|
|
397
|
-
--svelte-ui-nav-mobile-item-bar-width: 40px;
|
|
398
396
|
--svelte-ui-nav-item-padding: 8px 12px;
|
|
399
397
|
--svelte-ui-nav-item-border-radius: var(--svelte-ui-border-radius);
|
|
400
398
|
/* Nav: vertical */
|
|
401
|
-
--svelte-ui-nav-vertical-padding: 8px;
|
|
402
399
|
--svelte-ui-nav-vertical-item-gap: 8px;
|
|
403
400
|
/* Nav: horizontal */
|
|
404
401
|
--svelte-ui-nav-horizontal-item-gap: 8px;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// =========================================================================
|
|
15
15
|
export type NavProps = {
|
|
16
16
|
// 基本プロパティ
|
|
17
|
-
|
|
17
|
+
navItems?: MenuItem[];
|
|
18
18
|
variant?: NavVariant;
|
|
19
19
|
pathPrefix?: string;
|
|
20
20
|
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
// スタイル/レイアウト
|
|
34
34
|
selectedStyle?: NavItemSelectedStyle;
|
|
35
|
+
gap?: number | string;
|
|
35
36
|
|
|
36
37
|
// ARIA/アクセシビリティ
|
|
37
38
|
ariaLabel?: string;
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
|
|
41
42
|
let {
|
|
42
43
|
// 基本プロパティ
|
|
43
|
-
|
|
44
|
+
navItems = [],
|
|
44
45
|
variant = 'tab',
|
|
45
46
|
pathPrefix = '',
|
|
46
47
|
customPathMatcher,
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
|
|
59
60
|
// スタイル/レイアウト
|
|
60
61
|
selectedStyle,
|
|
62
|
+
gap,
|
|
61
63
|
|
|
62
64
|
// ARIA/アクセシビリティ
|
|
63
65
|
ariaLabel,
|
|
@@ -83,12 +85,13 @@
|
|
|
83
85
|
// Methods
|
|
84
86
|
// =========================================================================
|
|
85
87
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
86
|
-
if (
|
|
88
|
+
if (navItems.length === 0 || enabledIndices.length === 0) return;
|
|
87
89
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
+
const navItemEls = Array.from(
|
|
91
|
+
(event.currentTarget as HTMLElement).querySelectorAll('[data-nav-item]')
|
|
92
|
+
) as HTMLElement[];
|
|
90
93
|
const currentItem = event.target as HTMLElement;
|
|
91
|
-
const currentIndex =
|
|
94
|
+
const currentIndex = navItemEls.indexOf(currentItem);
|
|
92
95
|
|
|
93
96
|
if (currentIndex === -1) return;
|
|
94
97
|
|
|
@@ -123,15 +126,15 @@
|
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
const nextIndex = enabledIndices[nextEnabledPosition];
|
|
126
|
-
|
|
129
|
+
navItemEls[nextIndex]?.focus();
|
|
127
130
|
};
|
|
128
131
|
|
|
129
132
|
// =========================================================================
|
|
130
133
|
// $derived
|
|
131
134
|
// =========================================================================
|
|
132
135
|
const selectedIndex = $derived.by(() => {
|
|
133
|
-
for (let i = 0; i <
|
|
134
|
-
const item =
|
|
136
|
+
for (let i = 0; i < navItems.length; i++) {
|
|
137
|
+
const item = navItems[i];
|
|
135
138
|
if (!item.href) continue;
|
|
136
139
|
if (matchPath(resolvedCurrentPath, item.href, item, pathPrefix, customPathMatcher)) {
|
|
137
140
|
return i;
|
|
@@ -141,7 +144,7 @@
|
|
|
141
144
|
});
|
|
142
145
|
|
|
143
146
|
const enabledIndices = $derived(
|
|
144
|
-
|
|
147
|
+
navItems.map((item, i) => (item.disabled ? -1 : i)).filter((i) => i >= 0)
|
|
145
148
|
);
|
|
146
149
|
|
|
147
150
|
const isTabVariant = $derived(variant === 'tab');
|
|
@@ -153,12 +156,13 @@
|
|
|
153
156
|
aria-label={ariaLabelledby ? undefined : ariaLabel}
|
|
154
157
|
aria-labelledby={ariaLabelledby}
|
|
155
158
|
aria-orientation={variant === 'vertical' ? 'vertical' : 'horizontal'}
|
|
159
|
+
style:--internal-nav-gap={gap != null ? (typeof gap === 'number' ? `${gap}px` : gap) : undefined}
|
|
156
160
|
tabindex="-1"
|
|
157
161
|
{id}
|
|
158
162
|
onkeydown={handleKeyDown}
|
|
159
163
|
data-testid="nav"
|
|
160
164
|
>
|
|
161
|
-
{#each
|
|
165
|
+
{#each navItems as item, index}
|
|
162
166
|
<NavItem
|
|
163
167
|
{item}
|
|
164
168
|
{variant}
|
|
@@ -206,13 +210,12 @@
|
|
|
206
210
|
|
|
207
211
|
.nav--vertical {
|
|
208
212
|
flex-direction: column;
|
|
209
|
-
gap: var(--svelte-ui-nav-vertical-item-gap);
|
|
210
|
-
padding: var(--svelte-ui-nav-vertical-padding);
|
|
213
|
+
gap: var(--internal-nav-gap, var(--svelte-ui-nav-vertical-item-gap));
|
|
211
214
|
width: 100%;
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
.nav--horizontal {
|
|
215
218
|
flex-direction: row;
|
|
216
|
-
gap: var(--svelte-ui-nav-horizontal-item-gap);
|
|
219
|
+
gap: var(--internal-nav-gap, var(--svelte-ui-nav-horizontal-item-gap));
|
|
217
220
|
align-items: center;
|
|
218
221
|
}</style>
|
|
@@ -3,7 +3,7 @@ import type { MenuItem } from '../types/menuItem';
|
|
|
3
3
|
import type { NavVariant } from '../types/propOptions';
|
|
4
4
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
5
5
|
export type NavProps = {
|
|
6
|
-
|
|
6
|
+
navItems?: MenuItem[];
|
|
7
7
|
variant?: NavVariant;
|
|
8
8
|
pathPrefix?: string;
|
|
9
9
|
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
@@ -15,6 +15,7 @@ export type NavProps = {
|
|
|
15
15
|
iconOpticalSize?: IconOpticalSize;
|
|
16
16
|
iconVariant?: IconVariant;
|
|
17
17
|
selectedStyle?: NavItemSelectedStyle;
|
|
18
|
+
gap?: number | string;
|
|
18
19
|
ariaLabel?: string;
|
|
19
20
|
ariaLabelledby?: string;
|
|
20
21
|
};
|
|
@@ -210,23 +210,16 @@
|
|
|
210
210
|
justify-content: center;
|
|
211
211
|
flex: 1;
|
|
212
212
|
padding: var(--svelte-ui-nav-mobile-item-padding);
|
|
213
|
-
|
|
214
|
-
color: var(--svelte-ui-nav-item-text-color);
|
|
213
|
+
height: var(--svelte-ui-nav-mobile-min-height);
|
|
215
214
|
font-size: var(--svelte-ui-nav-mobile-item-font-size);
|
|
216
215
|
gap: var(--svelte-ui-nav-mobile-item-icon-gap);
|
|
217
216
|
}
|
|
218
217
|
|
|
219
|
-
@media (hover: hover) {
|
|
220
|
-
.nav-item--mobile:hover {
|
|
221
|
-
color: var(--svelte-ui-nav-item-selected-text-color);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
218
|
.nav-item--vertical {
|
|
225
219
|
width: 100%;
|
|
226
220
|
padding: var(--svelte-ui-nav-item-padding);
|
|
227
221
|
min-height: var(--svelte-ui-nav-item-min-height);
|
|
228
222
|
border-radius: var(--svelte-ui-nav-item-border-radius);
|
|
229
|
-
color: var(--svelte-ui-nav-item-text-color);
|
|
230
223
|
}
|
|
231
224
|
|
|
232
225
|
.nav-item--vertical::after {
|
|
@@ -234,9 +227,6 @@
|
|
|
234
227
|
}
|
|
235
228
|
|
|
236
229
|
@media (hover: hover) {
|
|
237
|
-
.nav-item--vertical:hover {
|
|
238
|
-
color: var(--svelte-ui-nav-item-selected-text-color);
|
|
239
|
-
}
|
|
240
230
|
.nav-item--vertical:hover::after {
|
|
241
231
|
opacity: 1;
|
|
242
232
|
}
|
|
@@ -245,7 +235,6 @@
|
|
|
245
235
|
padding: var(--svelte-ui-nav-item-padding);
|
|
246
236
|
min-height: var(--svelte-ui-nav-item-min-height);
|
|
247
237
|
border-radius: var(--svelte-ui-nav-item-border-radius);
|
|
248
|
-
color: var(--svelte-ui-nav-item-text-color);
|
|
249
238
|
}
|
|
250
239
|
|
|
251
240
|
.nav-item--horizontal::after {
|
|
@@ -253,9 +242,6 @@
|
|
|
253
242
|
}
|
|
254
243
|
|
|
255
244
|
@media (hover: hover) {
|
|
256
|
-
.nav-item--horizontal:hover {
|
|
257
|
-
color: var(--svelte-ui-nav-item-selected-text-color);
|
|
258
|
-
}
|
|
259
245
|
.nav-item--horizontal:hover::after {
|
|
260
246
|
opacity: 1;
|
|
261
247
|
}
|