@14ch/svelte-ui 0.0.28 → 0.0.29
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/assets/styles/variables.scss +28 -24
- package/dist/components/Nav.svelte +168 -46
- package/dist/components/Nav.svelte.d.ts +7 -3
- package/dist/components/NavItem.svelte +438 -59
- package/dist/components/NavItem.svelte.d.ts +19 -2
- package/dist/components/Tab.svelte +44 -118
- package/dist/components/Tab.svelte.d.ts +8 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +0 -1
- package/dist/types/menuItem.d.ts +1 -0
- package/dist/types/propOptions.d.ts +10 -1
- package/package.json +1 -1
- package/dist/components/TabItem.svelte +0 -219
- package/dist/components/TabItem.svelte.d.ts +0 -19
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<!-- Tab.svelte -->
|
|
2
2
|
|
|
3
3
|
<script lang="ts">
|
|
4
|
-
import
|
|
4
|
+
import Nav from './Nav.svelte';
|
|
5
5
|
import type { MenuItem } from '../types/menuItem';
|
|
6
|
-
import {
|
|
7
|
-
import { getCurrentPath as resolveCurrentPath, matchPath as doMatchPath } from '../utils/navPath';
|
|
6
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
8
7
|
|
|
9
8
|
// =========================================================================
|
|
10
9
|
// Props, States & Constants
|
|
@@ -12,7 +11,7 @@
|
|
|
12
11
|
export type TabProps = {
|
|
13
12
|
// 基本プロパティ
|
|
14
13
|
/** `{ label, href, icon?, disabled? }[]` */
|
|
15
|
-
tabItems
|
|
14
|
+
tabItems?: MenuItem[];
|
|
16
15
|
/** Prepended to each item's href for active-state matching. */
|
|
17
16
|
pathPrefix?: string;
|
|
18
17
|
/** Custom function to determine if an item is active. */
|
|
@@ -20,6 +19,16 @@
|
|
|
20
19
|
/** Overrides the auto-detected current path. */
|
|
21
20
|
currentPath?: string;
|
|
22
21
|
|
|
22
|
+
// HTML属性
|
|
23
|
+
id?: string;
|
|
24
|
+
|
|
25
|
+
// アイコン関連
|
|
26
|
+
iconFilled?: boolean;
|
|
27
|
+
iconWeight?: IconWeight;
|
|
28
|
+
iconGrade?: IconGrade;
|
|
29
|
+
iconOpticalSize?: IconOpticalSize;
|
|
30
|
+
iconVariant?: IconVariant;
|
|
31
|
+
|
|
23
32
|
// スタイル/レイアウト
|
|
24
33
|
/** Custom CSS color for tab labels. */
|
|
25
34
|
textColor?: string;
|
|
@@ -40,7 +49,17 @@
|
|
|
40
49
|
customPathMatcher,
|
|
41
50
|
currentPath,
|
|
42
51
|
|
|
43
|
-
//
|
|
52
|
+
// HTML属性
|
|
53
|
+
id,
|
|
54
|
+
|
|
55
|
+
// アイコン関連
|
|
56
|
+
iconFilled = false,
|
|
57
|
+
iconWeight = 300,
|
|
58
|
+
iconGrade = 0,
|
|
59
|
+
iconOpticalSize = 24,
|
|
60
|
+
iconVariant = 'outlined',
|
|
61
|
+
|
|
62
|
+
// スタイル/レイアウト
|
|
44
63
|
textColor,
|
|
45
64
|
selectedTextColor,
|
|
46
65
|
selectedBarColor,
|
|
@@ -49,128 +68,35 @@
|
|
|
49
68
|
ariaLabel = 'Tabs',
|
|
50
69
|
ariaLabelledby
|
|
51
70
|
}: TabProps = $props();
|
|
52
|
-
|
|
53
|
-
let resolvedCurrentPath = $state('');
|
|
54
|
-
|
|
55
|
-
// =========================================================================
|
|
56
|
-
// Effects
|
|
57
|
-
// =========================================================================
|
|
58
|
-
$effect(() => {
|
|
59
|
-
// props の currentPath が変更されたとき
|
|
60
|
-
resolvedCurrentPath = resolveCurrentPath(currentPath);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
$effect(() => {
|
|
64
|
-
// URL の変更を subscribe
|
|
65
|
-
return subscribeUrlChange(() => {
|
|
66
|
-
resolvedCurrentPath = resolveCurrentPath(currentPath);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// =========================================================================
|
|
71
|
-
// Methods
|
|
72
|
-
// =========================================================================
|
|
73
|
-
|
|
74
|
-
// シンプルなキーボードナビゲーション(disabled タブはスキップ)
|
|
75
|
-
const handleKeyDown = (event: KeyboardEvent) => {
|
|
76
|
-
if (tabItems.length === 0 || enabledIndices.length === 0) return;
|
|
77
|
-
|
|
78
|
-
const tabList = event.currentTarget as HTMLElement;
|
|
79
|
-
const tabs = Array.from(tabList.querySelectorAll('[role="tab"]')) as HTMLElement[];
|
|
80
|
-
const currentTab = event.target as HTMLElement;
|
|
81
|
-
const currentIndex = tabs.indexOf(currentTab);
|
|
82
|
-
|
|
83
|
-
if (currentIndex === -1) return;
|
|
84
|
-
|
|
85
|
-
const currentEnabledPosition = enabledIndices.indexOf(currentIndex);
|
|
86
|
-
let nextEnabledPosition = currentEnabledPosition;
|
|
87
|
-
|
|
88
|
-
switch (event.key) {
|
|
89
|
-
case 'ArrowLeft':
|
|
90
|
-
event.preventDefault();
|
|
91
|
-
nextEnabledPosition =
|
|
92
|
-
currentEnabledPosition > 0 ? currentEnabledPosition - 1 : enabledIndices.length - 1;
|
|
93
|
-
break;
|
|
94
|
-
case 'ArrowRight':
|
|
95
|
-
event.preventDefault();
|
|
96
|
-
nextEnabledPosition =
|
|
97
|
-
currentEnabledPosition < enabledIndices.length - 1 ? currentEnabledPosition + 1 : 0;
|
|
98
|
-
break;
|
|
99
|
-
case 'Home':
|
|
100
|
-
event.preventDefault();
|
|
101
|
-
nextEnabledPosition = 0;
|
|
102
|
-
break;
|
|
103
|
-
case 'End':
|
|
104
|
-
event.preventDefault();
|
|
105
|
-
nextEnabledPosition = enabledIndices.length - 1;
|
|
106
|
-
break;
|
|
107
|
-
default:
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const nextIndex = enabledIndices[nextEnabledPosition];
|
|
112
|
-
tabs[nextIndex]?.focus();
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// =========================================================================
|
|
116
|
-
// $derived
|
|
117
|
-
// =========================================================================
|
|
118
|
-
|
|
119
|
-
// アクティブなタブのインデックスを現在のパスに基づいて計算
|
|
120
|
-
const selectedTabIndex = $derived.by(() => {
|
|
121
|
-
for (let i = 0; i < tabItems.length; i++) {
|
|
122
|
-
const item = tabItems[i];
|
|
123
|
-
if (!item.href) continue;
|
|
124
|
-
|
|
125
|
-
if (doMatchPath(resolvedCurrentPath, item.href, item, pathPrefix, customPathMatcher)) {
|
|
126
|
-
return i;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return -1;
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// 有効なタブのインデックス一覧(disabled を除く)
|
|
133
|
-
const enabledIndices = $derived(
|
|
134
|
-
tabItems.map((item, i) => (item.disabled ? -1 : i)).filter((i) => i >= 0)
|
|
135
|
-
);
|
|
136
71
|
</script>
|
|
137
72
|
|
|
138
73
|
<div
|
|
139
74
|
class="tab"
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
tabindex="-1"
|
|
144
|
-
onkeydown={handleKeyDown}
|
|
75
|
+
style:--svelte-ui-nav-item-underline-text-color={textColor}
|
|
76
|
+
style:--svelte-ui-nav-item-underline-selected-text-color={selectedTextColor}
|
|
77
|
+
style:--svelte-ui-nav-item-underline-bar-color={selectedBarColor}
|
|
145
78
|
data-testid="tab"
|
|
146
79
|
>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
80
|
+
<Nav
|
|
81
|
+
navItems={tabItems}
|
|
82
|
+
variant="horizontal"
|
|
83
|
+
selectedStyle="underline"
|
|
84
|
+
{pathPrefix}
|
|
85
|
+
{customPathMatcher}
|
|
86
|
+
{currentPath}
|
|
87
|
+
{id}
|
|
88
|
+
{iconFilled}
|
|
89
|
+
{iconWeight}
|
|
90
|
+
{iconGrade}
|
|
91
|
+
{iconOpticalSize}
|
|
92
|
+
{iconVariant}
|
|
93
|
+
{ariaLabel}
|
|
94
|
+
{ariaLabelledby}
|
|
95
|
+
/>
|
|
158
96
|
</div>
|
|
159
97
|
|
|
160
98
|
<style>.tab {
|
|
161
|
-
display: flex;
|
|
162
|
-
justify-content: start;
|
|
163
|
-
position: relative;
|
|
164
|
-
width: 100%;
|
|
165
|
-
height: 100%;
|
|
166
99
|
min-height: var(--svelte-ui-tab-min-height);
|
|
167
|
-
|
|
168
|
-
overflow-y: visible;
|
|
169
|
-
-ms-overflow-style: none;
|
|
170
|
-
overscroll-behavior: contain;
|
|
100
|
+
width: 100%;
|
|
171
101
|
box-sizing: border-box;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.tab::-webkit-scrollbar {
|
|
175
|
-
display: none;
|
|
176
102
|
}</style>
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import type { MenuItem } from '../types/menuItem';
|
|
2
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
2
3
|
export type TabProps = {
|
|
3
4
|
/** `{ label, href, icon?, disabled? }[]` */
|
|
4
|
-
tabItems
|
|
5
|
+
tabItems?: MenuItem[];
|
|
5
6
|
/** Prepended to each item's href for active-state matching. */
|
|
6
7
|
pathPrefix?: string;
|
|
7
8
|
/** Custom function to determine if an item is active. */
|
|
8
9
|
customPathMatcher?: (currentPath: string, itemHref: string, item: MenuItem) => boolean;
|
|
9
10
|
/** Overrides the auto-detected current path. */
|
|
10
11
|
currentPath?: string;
|
|
12
|
+
id?: string;
|
|
13
|
+
iconFilled?: boolean;
|
|
14
|
+
iconWeight?: IconWeight;
|
|
15
|
+
iconGrade?: IconGrade;
|
|
16
|
+
iconOpticalSize?: IconOpticalSize;
|
|
17
|
+
iconVariant?: IconVariant;
|
|
11
18
|
/** Custom CSS color for tab labels. */
|
|
12
19
|
textColor?: string;
|
|
13
20
|
/** Custom CSS color for the active tab label. */
|
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,6 @@ export { default as Switch } from './components/Switch.svelte';
|
|
|
35
35
|
export { default as Nav } from './components/Nav.svelte';
|
|
36
36
|
export { default as NavItem } from './components/NavItem.svelte';
|
|
37
37
|
export { default as Tab } from './components/Tab.svelte';
|
|
38
|
-
export { default as TabItem } from './components/TabItem.svelte';
|
|
39
38
|
export { default as Textarea } from './components/Textarea.svelte';
|
|
40
39
|
export type { ButtonProps } from './components/Button.svelte';
|
|
41
40
|
export type { CheckboxProps } from './components/Checkbox.svelte';
|
|
@@ -78,9 +77,8 @@ export type { SwitchProps } from './components/Switch.svelte';
|
|
|
78
77
|
export type { NavProps } from './components/Nav.svelte';
|
|
79
78
|
export type { NavItemProps, NavItemSelectedStyle } from './components/NavItem.svelte';
|
|
80
79
|
export type { TabProps } from './components/Tab.svelte';
|
|
81
|
-
export type { TabItemProps } from './components/TabItem.svelte';
|
|
82
80
|
export type { TextareaProps } from './components/Textarea.svelte';
|
|
83
|
-
export type { PopupPosition, SnackbarPosition, FabPosition, ButtonVariant, ButtonSize, SnackbarType, SnackbarVariant, BadgeVariant, DatepickerMode, FocusStyle, NavVariant } from './types/propOptions';
|
|
81
|
+
export type { PopupPosition, SnackbarPosition, FabPosition, ButtonVariant, ButtonSize, SnackbarType, SnackbarVariant, BadgeVariant, DatepickerMode, FocusStyle, NavVariant, SubMenuMode } from './types/propOptions';
|
|
84
82
|
export type { MenuItem } from './types/menuItem';
|
|
85
83
|
export type { SegmentedControlItem } from './types/segmentedControlItem';
|
|
86
84
|
export type { Option, OptionValue } from './types/options';
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,6 @@ export { default as Switch } from './components/Switch.svelte';
|
|
|
36
36
|
export { default as Nav } from './components/Nav.svelte';
|
|
37
37
|
export { default as NavItem } from './components/NavItem.svelte';
|
|
38
38
|
export { default as Tab } from './components/Tab.svelte';
|
|
39
|
-
export { default as TabItem } from './components/TabItem.svelte';
|
|
40
39
|
export { default as Textarea } from './components/Textarea.svelte';
|
|
41
40
|
// Utils
|
|
42
41
|
export * from './utils/accessibility';
|
package/dist/types/menuItem.d.ts
CHANGED
|
@@ -56,4 +56,13 @@ export type FocusStyle = 'background' | 'outline' | 'none';
|
|
|
56
56
|
* Nav variant type
|
|
57
57
|
* Used by Nav component
|
|
58
58
|
*/
|
|
59
|
-
export type NavVariant = 'vertical' | 'horizontal' | 'mobile'
|
|
59
|
+
export type NavVariant = 'vertical' | 'horizontal' | 'mobile';
|
|
60
|
+
/**
|
|
61
|
+
* Sub-menu display mode for Nav hierarchical menus.
|
|
62
|
+
* - `popup`: child items appear in a floating panel (all variants)
|
|
63
|
+
* - `accordion`: child items expand/collapse inline (vertical only)
|
|
64
|
+
* - `expanded`: child items are always visible inline (vertical only)
|
|
65
|
+
* - `bar`: child items appear in a secondary bar below the nav (horizontal only)
|
|
66
|
+
* - `bottom-sheet`: child items appear in a fixed bottom sheet overlay (mobile only)
|
|
67
|
+
*/
|
|
68
|
+
export type SubMenuMode = 'popup' | 'accordion' | 'expanded' | 'bar' | 'bottom-sheet';
|
package/package.json
CHANGED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
<!-- TabItem.svelte -->
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
import Icon from './Icon.svelte';
|
|
5
|
-
import type { MenuItem } from '../types/menuItem';
|
|
6
|
-
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
7
|
-
|
|
8
|
-
// =========================================================================
|
|
9
|
-
// Props, States & Constants
|
|
10
|
-
// =========================================================================
|
|
11
|
-
export type TabItemProps = {
|
|
12
|
-
// 基本プロパティ
|
|
13
|
-
tabItem: MenuItem;
|
|
14
|
-
pathPrefix?: string;
|
|
15
|
-
|
|
16
|
-
// スタイル/レイアウト(未指定時は variables の tab 用変数を参照)
|
|
17
|
-
textColor?: string;
|
|
18
|
-
selectedTextColor?: string;
|
|
19
|
-
selectedBarColor?: string;
|
|
20
|
-
|
|
21
|
-
// アイコン関連
|
|
22
|
-
iconFilled?: boolean;
|
|
23
|
-
iconWeight?: IconWeight;
|
|
24
|
-
iconGrade?: IconGrade;
|
|
25
|
-
iconOpticalSize?: IconOpticalSize;
|
|
26
|
-
iconVariant?: IconVariant;
|
|
27
|
-
|
|
28
|
-
// 状態/動作
|
|
29
|
-
isSelected?: boolean;
|
|
30
|
-
isDisabled?: boolean;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
let {
|
|
34
|
-
// 基本プロパティ
|
|
35
|
-
tabItem,
|
|
36
|
-
pathPrefix = '',
|
|
37
|
-
|
|
38
|
-
// スタイル/レイアウト
|
|
39
|
-
textColor,
|
|
40
|
-
selectedTextColor,
|
|
41
|
-
selectedBarColor,
|
|
42
|
-
|
|
43
|
-
// アイコン関連
|
|
44
|
-
iconFilled = false,
|
|
45
|
-
iconWeight = 300,
|
|
46
|
-
iconGrade = 0,
|
|
47
|
-
iconOpticalSize = 24,
|
|
48
|
-
iconVariant = 'outlined',
|
|
49
|
-
|
|
50
|
-
// 状態/動作
|
|
51
|
-
isSelected = false,
|
|
52
|
-
isDisabled = false
|
|
53
|
-
}: TabItemProps = $props();
|
|
54
|
-
|
|
55
|
-
// =========================================================================
|
|
56
|
-
// $derived
|
|
57
|
-
// =========================================================================
|
|
58
|
-
|
|
59
|
-
// pathPrefixを付与したhrefを計算
|
|
60
|
-
const hrefWithPrefix = $derived.by(() => {
|
|
61
|
-
if (!tabItem.href) return undefined;
|
|
62
|
-
if (!pathPrefix) return tabItem.href;
|
|
63
|
-
|
|
64
|
-
// 既にpathPrefixが含まれている場合はそのまま
|
|
65
|
-
// pathPrefixが完全一致、またはpathPrefix + '/'で始まる場合
|
|
66
|
-
if (tabItem.href === pathPrefix || tabItem.href.startsWith(`${pathPrefix}/`)) {
|
|
67
|
-
return tabItem.href;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// pathPrefixを付与
|
|
71
|
-
return `${pathPrefix}${tabItem.href.startsWith('/') ? '' : '/'}${tabItem.href}`;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// 明示的に渡されたときだけ内部CSS変数で上書き。未渡しなら variables の tab 用変数をそのまま参照
|
|
75
|
-
const internalTextColor = $derived(textColor);
|
|
76
|
-
const internalSelectedTextColor = $derived(selectedTextColor);
|
|
77
|
-
const internalSelectedBarColor = $derived(selectedBarColor);
|
|
78
|
-
</script>
|
|
79
|
-
|
|
80
|
-
{#if isDisabled}
|
|
81
|
-
<span
|
|
82
|
-
class="tab-item tab-item--disabled"
|
|
83
|
-
class:tab-item--selected={isSelected}
|
|
84
|
-
style:--internal-tab-item-text-color={internalTextColor}
|
|
85
|
-
style:--internal-tab-item-selected-text-color={internalSelectedTextColor}
|
|
86
|
-
style:--internal-tab-item-selected-bar-color={internalSelectedBarColor}
|
|
87
|
-
role="tab"
|
|
88
|
-
aria-selected={isSelected}
|
|
89
|
-
aria-disabled="true"
|
|
90
|
-
tabindex="-1"
|
|
91
|
-
data-testid="tab-item"
|
|
92
|
-
>
|
|
93
|
-
{#if tabItem.icon}
|
|
94
|
-
<div class="tab-item__icon">
|
|
95
|
-
<Icon
|
|
96
|
-
filled={iconFilled || isSelected}
|
|
97
|
-
weight={iconWeight}
|
|
98
|
-
grade={iconGrade}
|
|
99
|
-
opticalSize={iconOpticalSize}
|
|
100
|
-
variant={iconVariant}>{tabItem.icon}</Icon
|
|
101
|
-
>
|
|
102
|
-
</div>
|
|
103
|
-
{/if}
|
|
104
|
-
{#if tabItem.label}
|
|
105
|
-
<div class="tab-item__label">
|
|
106
|
-
{tabItem.label}
|
|
107
|
-
</div>
|
|
108
|
-
{/if}
|
|
109
|
-
</span>
|
|
110
|
-
{:else}
|
|
111
|
-
<a
|
|
112
|
-
href={hrefWithPrefix}
|
|
113
|
-
class="tab-item"
|
|
114
|
-
class:tab-item--selected={isSelected}
|
|
115
|
-
style:--internal-tab-item-text-color={internalTextColor}
|
|
116
|
-
style:--internal-tab-item-selected-text-color={internalSelectedTextColor}
|
|
117
|
-
style:--internal-tab-item-selected-bar-color={internalSelectedBarColor}
|
|
118
|
-
role="tab"
|
|
119
|
-
aria-selected={isSelected}
|
|
120
|
-
tabindex={0}
|
|
121
|
-
data-testid="tab-item"
|
|
122
|
-
>
|
|
123
|
-
{#if tabItem.icon}
|
|
124
|
-
<div class="tab-item__icon">
|
|
125
|
-
<Icon
|
|
126
|
-
filled={iconFilled || isSelected}
|
|
127
|
-
weight={iconWeight}
|
|
128
|
-
grade={iconGrade}
|
|
129
|
-
opticalSize={iconOpticalSize}
|
|
130
|
-
variant={iconVariant}>{tabItem.icon}</Icon
|
|
131
|
-
>
|
|
132
|
-
</div>
|
|
133
|
-
{/if}
|
|
134
|
-
{#if tabItem.label}
|
|
135
|
-
<div class="tab-item__label">
|
|
136
|
-
{tabItem.label}
|
|
137
|
-
</div>
|
|
138
|
-
{/if}
|
|
139
|
-
</a>
|
|
140
|
-
{/if}
|
|
141
|
-
|
|
142
|
-
<style>@charset "UTF-8";
|
|
143
|
-
.tab-item {
|
|
144
|
-
display: flex;
|
|
145
|
-
justify-content: center;
|
|
146
|
-
align-items: center;
|
|
147
|
-
gap: var(--svelte-ui-tab-item-icon-gap);
|
|
148
|
-
position: relative;
|
|
149
|
-
padding: var(--svelte-ui-tab-item-padding);
|
|
150
|
-
color: var(--internal-tab-item-text-color, var(--svelte-ui-tab-item-text-color));
|
|
151
|
-
white-space: nowrap;
|
|
152
|
-
text-decoration: none;
|
|
153
|
-
transition-property: background-color, color, outline;
|
|
154
|
-
transition-duration: var(--svelte-ui-transition-duration);
|
|
155
|
-
outline: none;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
@media (hover: hover) {
|
|
159
|
-
.tab-item:hover:not(.tab-item--selected) {
|
|
160
|
-
color: var(--internal-tab-item-selected-text-color, var(--svelte-ui-tab-item-selected-text-color));
|
|
161
|
-
}
|
|
162
|
-
.tab-item:hover:not(.tab-item--selected)::before {
|
|
163
|
-
opacity: 1;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
/* キーボードフォーカス時のみ枠線を表示 */
|
|
167
|
-
.tab-item:focus-visible {
|
|
168
|
-
outline: var(--svelte-ui-focus-outline-inner);
|
|
169
|
-
outline-offset: var(--svelte-ui-focus-outline-offset-inner);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/* フォールバック: :focus-visible未対応ブラウザ用 */
|
|
173
|
-
@supports not selector(:focus-visible) {
|
|
174
|
-
.tab-item:focus {
|
|
175
|
-
outline: var(--svelte-ui-focus-outline-inner);
|
|
176
|
-
outline-offset: var(--svelte-ui-focus-outline-offset-inner);
|
|
177
|
-
}
|
|
178
|
-
.tab-item:focus:not(.tab-item--selected) {
|
|
179
|
-
color: var(--internal-tab-item-selected-text-color, var(--svelte-ui-tab-item-selected-text-color));
|
|
180
|
-
}
|
|
181
|
-
.tab-item:focus:not(.tab-item--selected)::before {
|
|
182
|
-
opacity: 1;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/* 選択状態のインジケーター */
|
|
186
|
-
.tab-item::before {
|
|
187
|
-
content: "";
|
|
188
|
-
display: block;
|
|
189
|
-
position: absolute;
|
|
190
|
-
left: calc(var(--svelte-ui-tab-item-padding-x) - var(--svelte-ui-tab-item-selected-bar-offset));
|
|
191
|
-
bottom: 0;
|
|
192
|
-
width: calc(100% - 2 * var(--svelte-ui-tab-item-padding-x) + 2 * var(--svelte-ui-tab-item-selected-bar-offset));
|
|
193
|
-
height: var(--svelte-ui-tab-item-selected-bar-height);
|
|
194
|
-
background-color: var(--internal-tab-item-selected-bar-color, var(--svelte-ui-tab-item-selected-bar-color));
|
|
195
|
-
border-radius: var(--svelte-ui-tab-item-selected-bar-radius);
|
|
196
|
-
opacity: 0;
|
|
197
|
-
transition-property: opacity;
|
|
198
|
-
transition-duration: var(--svelte-ui-transition-duration);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.tab-item--selected {
|
|
202
|
-
color: var(--internal-tab-item-selected-text-color, var(--svelte-ui-tab-item-selected-text-color));
|
|
203
|
-
background-color: transparent;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.tab-item--selected::before {
|
|
207
|
-
opacity: 1;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.tab-item--disabled {
|
|
211
|
-
opacity: var(--svelte-ui-tab-item-disabled-opacity);
|
|
212
|
-
pointer-events: none;
|
|
213
|
-
cursor: default;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.tab-item__label {
|
|
217
|
-
text-box-trim: trim-both;
|
|
218
|
-
text-box-edge: cap alphabetic;
|
|
219
|
-
}</style>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { MenuItem } from '../types/menuItem';
|
|
2
|
-
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
3
|
-
export type TabItemProps = {
|
|
4
|
-
tabItem: MenuItem;
|
|
5
|
-
pathPrefix?: string;
|
|
6
|
-
textColor?: string;
|
|
7
|
-
selectedTextColor?: string;
|
|
8
|
-
selectedBarColor?: string;
|
|
9
|
-
iconFilled?: boolean;
|
|
10
|
-
iconWeight?: IconWeight;
|
|
11
|
-
iconGrade?: IconGrade;
|
|
12
|
-
iconOpticalSize?: IconOpticalSize;
|
|
13
|
-
iconVariant?: IconVariant;
|
|
14
|
-
isSelected?: boolean;
|
|
15
|
-
isDisabled?: boolean;
|
|
16
|
-
};
|
|
17
|
-
declare const TabItem: import("svelte").Component<TabItemProps, {}, "">;
|
|
18
|
-
type TabItem = ReturnType<typeof TabItem>;
|
|
19
|
-
export default TabItem;
|