@14ch/svelte-ui 0.0.6 → 0.0.8
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 +20 -1
- package/dist/components/Button.svelte +1 -1
- package/dist/components/ColorPicker.svelte +5 -6
- package/dist/components/Combobox.svelte +2 -3
- package/dist/components/Dialog.svelte +20 -9
- package/dist/components/Drawer.svelte +1 -3
- package/dist/components/Input.svelte +23 -23
- package/dist/components/Input.svelte.d.ts +0 -3
- package/dist/components/SegmentedControl.svelte +626 -0
- package/dist/components/SegmentedControl.svelte.d.ts +49 -0
- package/dist/components/SnackbarItem.svelte +146 -37
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/types/segmentedControlItem.d.ts +13 -0
- package/dist/types/segmentedControlItem.js +1 -0
- package/package.json +1 -1
|
@@ -341,6 +341,25 @@
|
|
|
341
341
|
--svelte-ui-iconbutton-hover-overlay: var(--svelte-ui-hover-overlay);
|
|
342
342
|
--svelte-ui-iconbutton-focus-color: var(--svelte-ui-focus-color);
|
|
343
343
|
|
|
344
|
+
/* SegmentedControl */
|
|
345
|
+
--svelte-ui-segmented-control-base-padding: 4px;
|
|
346
|
+
--svelte-ui-segmented-control-base-border-radius: var(--svelte-ui-border-radius);
|
|
347
|
+
--svelte-ui-segmented-control-gap: 4px;
|
|
348
|
+
--svelte-ui-segmented-control-button-radius: calc(var(--svelte-ui-border-radius) - 1px);
|
|
349
|
+
--svelte-ui-segmented-control-button-height-sm: 24px;
|
|
350
|
+
--svelte-ui-segmented-control-button-height: 32px;
|
|
351
|
+
--svelte-ui-segmented-control-button-height-lg: 40px;
|
|
352
|
+
--svelte-ui-segmented-control-font-size-sm: 12px;
|
|
353
|
+
--svelte-ui-segmented-control-font-size: 14px;
|
|
354
|
+
--svelte-ui-segmented-control-font-size-lg: 16px;
|
|
355
|
+
--svelte-ui-segmented-control-button-padding-sm: 4px 8px;
|
|
356
|
+
--svelte-ui-segmented-control-button-padding: 6px 12px;
|
|
357
|
+
--svelte-ui-segmented-control-button-padding-lg: 8px 16px;
|
|
358
|
+
--svelte-ui-segmented-control-base-bg: var(--svelte-ui-surface-accent-color);
|
|
359
|
+
--svelte-ui-segmented-control-selected-bg: var(--svelte-ui-primary-color);
|
|
360
|
+
--svelte-ui-segmented-control-selected-text-color: var(--svelte-ui-text-on-filled-color);
|
|
361
|
+
--svelte-ui-segmented-control-hover-overlay: var(--svelte-ui-hover-overlay);
|
|
362
|
+
|
|
344
363
|
/* Input */
|
|
345
364
|
--svelte-ui-input-height: var(--svelte-ui-form-height);
|
|
346
365
|
--svelte-ui-input-padding: var(--svelte-ui-form-padding);
|
|
@@ -490,7 +509,7 @@
|
|
|
490
509
|
/* ColorPicker */
|
|
491
510
|
--svelte-ui-colorpicker-trigger-size: 28px;
|
|
492
511
|
--svelte-ui-colorpicker-text-padding-left: 40px;
|
|
493
|
-
--svelte-ui-colorpicker-trigger-border-radius: calc(var(--svelte-ui-border-radius) -
|
|
512
|
+
--svelte-ui-colorpicker-trigger-border-radius: calc(var(--svelte-ui-border-radius) - 1px);
|
|
494
513
|
--svelte-ui-colorpicker-trigger-border-style: dashed;
|
|
495
514
|
--svelte-ui-colorpicker-trigger-border-width: 1px;
|
|
496
515
|
--svelte-ui-colorpicker-trigger-offset: 4px;
|
|
@@ -167,11 +167,6 @@
|
|
|
167
167
|
// Methods
|
|
168
168
|
// =========================================================================
|
|
169
169
|
|
|
170
|
-
const handleSubmit = (event: SubmitEvent) => {
|
|
171
|
-
event?.preventDefault?.();
|
|
172
|
-
handleChange();
|
|
173
|
-
};
|
|
174
|
-
|
|
175
170
|
const handleChange = (event?: Event): void => {
|
|
176
171
|
// 空文字列の場合はそのまま処理
|
|
177
172
|
if (localValue && !localValue.startsWith('#')) {
|
|
@@ -207,6 +202,11 @@
|
|
|
207
202
|
onclick?.(event);
|
|
208
203
|
};
|
|
209
204
|
const handleKeydown = (event: KeyboardEvent) => {
|
|
205
|
+
// Enterキーで色の変更を確定
|
|
206
|
+
if (event.key === 'Enter' && !disabled && !readonly) {
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
handleChange();
|
|
209
|
+
}
|
|
210
210
|
if (disabled) return;
|
|
211
211
|
onkeydown(event);
|
|
212
212
|
};
|
|
@@ -361,7 +361,6 @@
|
|
|
361
361
|
onpointerleave={handlePointerLeave}
|
|
362
362
|
onpointermove={handlePointerMove}
|
|
363
363
|
onpointercancel={handlePointerCancel}
|
|
364
|
-
onsubmit={handleSubmit}
|
|
365
364
|
{...restProps}
|
|
366
365
|
/>
|
|
367
366
|
|
|
@@ -155,7 +155,6 @@
|
|
|
155
155
|
let popupRef = $state<any>();
|
|
156
156
|
let highlightedIndex = $state(-1);
|
|
157
157
|
let isFocused = $state(false);
|
|
158
|
-
let comboboxRef = $state<HTMLDivElement>();
|
|
159
158
|
|
|
160
159
|
// 各要素のIDを生成
|
|
161
160
|
const inputId = `${id}-input`;
|
|
@@ -479,9 +478,9 @@
|
|
|
479
478
|
type="button"
|
|
480
479
|
class="combobox__option"
|
|
481
480
|
class:combobox__option--highlighted={index === highlightedIndex}
|
|
482
|
-
class:combobox__option--selected={option ===
|
|
481
|
+
class:combobox__option--selected={option === inputValue}
|
|
483
482
|
role="option"
|
|
484
|
-
aria-selected={option ===
|
|
483
|
+
aria-selected={option === inputValue}
|
|
485
484
|
onmousedown={(event) => {
|
|
486
485
|
event?.preventDefault?.();
|
|
487
486
|
event?.stopPropagation?.();
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
return styles.join('; ');
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
const dialogClasses = $derived(
|
|
118
|
+
const dialogClasses = $derived('');
|
|
119
119
|
|
|
120
120
|
const ariaLabelledby = $derived(title ? 'dialog-title' : undefined);
|
|
121
121
|
const ariaDescribedbyValue = $derived(
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
customStyles={dialogStyles}
|
|
137
137
|
id={id ? `${id}-modal` : undefined}
|
|
138
138
|
>
|
|
139
|
-
<div class="dialog {scrollable ? 'scrollable' : ''}">
|
|
139
|
+
<div class="dialog {scrollable ? 'dialog--scrollable' : ''}">
|
|
140
140
|
{#if header || title}
|
|
141
141
|
<div class="dialog__header">
|
|
142
142
|
{#if header}
|
|
@@ -166,14 +166,15 @@
|
|
|
166
166
|
</div>
|
|
167
167
|
</Modal>
|
|
168
168
|
|
|
169
|
-
<style
|
|
169
|
+
<style>@charset "UTF-8";
|
|
170
|
+
.dialog {
|
|
170
171
|
display: flex;
|
|
171
172
|
flex-direction: column;
|
|
172
173
|
justify-content: stretch;
|
|
173
|
-
max-height: calc(100dvh - 2em - 6px);
|
|
174
174
|
border: var(--svelte-ui-dialog-border);
|
|
175
175
|
border-radius: var(--svelte-ui-dialog-border-radius);
|
|
176
|
-
|
|
176
|
+
max-height: calc(100dvh - 2em - 6px);
|
|
177
|
+
overflow: auto;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
.dialog__header {
|
|
@@ -183,7 +184,6 @@
|
|
|
183
184
|
justify-content: stretch;
|
|
184
185
|
min-height: var(--svelte-ui-dialog-header-height);
|
|
185
186
|
padding: var(--svelte-ui-dialog-padding);
|
|
186
|
-
margin-bottom: calc(0px - var(--svelte-ui-dialog-body-padding));
|
|
187
187
|
}
|
|
188
188
|
.dialog__header .dialog__title {
|
|
189
189
|
flex-grow: 1;
|
|
@@ -214,15 +214,26 @@
|
|
|
214
214
|
border-bottom: 1px solid var(--svelte-ui-border-weak-color);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
/* scrollable=true 時: ヘッダー/フッター固定 + bodyのみスクロール */
|
|
218
|
+
.dialog--scrollable {
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.dialog--scrollable .dialog__header {
|
|
218
223
|
margin-bottom: 0;
|
|
219
224
|
border-bottom: solid var(--svelte-ui-border-width, 1px) var(--svelte-ui-border-weak-color);
|
|
220
225
|
}
|
|
221
|
-
|
|
226
|
+
|
|
227
|
+
.dialog--scrollable .dialog__body {
|
|
222
228
|
flex-shrink: 1;
|
|
223
229
|
padding: var(--svelte-ui-dialog-body-padding);
|
|
224
230
|
overflow: auto;
|
|
225
231
|
}
|
|
226
|
-
|
|
232
|
+
|
|
233
|
+
.dialog:not(.dialog--scrollable) .dialog__body {
|
|
234
|
+
padding-top: 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.dialog--scrollable .dialog__footer {
|
|
227
238
|
border-top: solid var(--svelte-ui-border-width, 1px) var(--svelte-ui-border-weak-color);
|
|
228
239
|
}</style>
|
|
@@ -123,9 +123,7 @@
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
const drawerClasses = $derived(
|
|
126
|
-
['drawer-wrapper', `drawer-wrapper--${position}
|
|
127
|
-
.filter(Boolean)
|
|
128
|
-
.join(' ')
|
|
126
|
+
['drawer-wrapper', `drawer-wrapper--${position}`].filter(Boolean).join(' ')
|
|
129
127
|
);
|
|
130
128
|
|
|
131
129
|
const ariaLabelledby = $derived(title ? 'drawer-title' : undefined);
|
|
@@ -95,11 +95,6 @@
|
|
|
95
95
|
// 入力イベント
|
|
96
96
|
onchange = () => {}, // No params for type inference
|
|
97
97
|
oninput = () => {}, // No params for type inference
|
|
98
|
-
onsubmit = () => {}, // No params for type inference
|
|
99
|
-
|
|
100
|
-
// IMEイベント
|
|
101
|
-
oncompositionstart = () => {}, // No params for type inference
|
|
102
|
-
oncompositionend = () => {}, // No params for type inference
|
|
103
98
|
|
|
104
99
|
// アイコンイベント
|
|
105
100
|
onRightIconClick,
|
|
@@ -190,11 +185,6 @@
|
|
|
190
185
|
// 入力イベント
|
|
191
186
|
onchange?: (value: any) => void;
|
|
192
187
|
oninput?: (value: any) => void;
|
|
193
|
-
onsubmit?: (value: any) => void;
|
|
194
|
-
|
|
195
|
-
// IMEイベント
|
|
196
|
-
oncompositionstart?: Function; // No params for type inference
|
|
197
|
-
oncompositionend?: Function; // No params for type inference
|
|
198
188
|
|
|
199
189
|
// アイコンイベント
|
|
200
190
|
onRightIconClick?: Function; // No params for type inference
|
|
@@ -206,6 +196,7 @@
|
|
|
206
196
|
|
|
207
197
|
let ref: HTMLInputElement | undefined = $state();
|
|
208
198
|
let isFocused: boolean = $state(false);
|
|
199
|
+
let isComposing: boolean = $state(false);
|
|
209
200
|
|
|
210
201
|
// =========================================================================
|
|
211
202
|
// Methods
|
|
@@ -243,6 +234,10 @@
|
|
|
243
234
|
|
|
244
235
|
// キーボードイベント
|
|
245
236
|
const handleKeydown = (event: KeyboardEvent) => {
|
|
237
|
+
// Enterキーで入力確定(blur)する(IME変換中は除く)
|
|
238
|
+
if (event.key === 'Enter' && !disabled && !readonly && !isComposing) {
|
|
239
|
+
ref?.blur();
|
|
240
|
+
}
|
|
246
241
|
onkeydown?.(event);
|
|
247
242
|
};
|
|
248
243
|
|
|
@@ -251,12 +246,6 @@
|
|
|
251
246
|
};
|
|
252
247
|
|
|
253
248
|
// 入力イベント
|
|
254
|
-
const handleSubmit = (event: SubmitEvent) => {
|
|
255
|
-
if (disabled || readonly) return;
|
|
256
|
-
event?.preventDefault?.();
|
|
257
|
-
ref?.blur();
|
|
258
|
-
onsubmit?.(value);
|
|
259
|
-
};
|
|
260
249
|
|
|
261
250
|
const handleChange = () => {
|
|
262
251
|
if (disabled || readonly) return;
|
|
@@ -366,6 +355,15 @@
|
|
|
366
355
|
onpointercancel?.(event);
|
|
367
356
|
};
|
|
368
357
|
|
|
358
|
+
// IMEイベント
|
|
359
|
+
const handleCompositionStart = () => {
|
|
360
|
+
isComposing = true;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const handleCompositionEnd = () => {
|
|
364
|
+
isComposing = false;
|
|
365
|
+
};
|
|
366
|
+
|
|
369
367
|
// =========================================================================
|
|
370
368
|
// $derived
|
|
371
369
|
// =========================================================================
|
|
@@ -405,8 +403,8 @@
|
|
|
405
403
|
{getDisplayValue()}
|
|
406
404
|
</div>
|
|
407
405
|
{/if}
|
|
408
|
-
<!--
|
|
409
|
-
<
|
|
406
|
+
<!-- 入力用要素 -->
|
|
407
|
+
<div class="input__wrapper">
|
|
410
408
|
<input
|
|
411
409
|
{id}
|
|
412
410
|
{name}
|
|
@@ -452,10 +450,12 @@
|
|
|
452
450
|
onpointerleave={handlePointerLeave}
|
|
453
451
|
onpointermove={handlePointerMove}
|
|
454
452
|
onpointercancel={handlePointerCancel}
|
|
453
|
+
oncompositionstart={handleCompositionStart}
|
|
454
|
+
oncompositionend={handleCompositionEnd}
|
|
455
455
|
{...inputAttributes}
|
|
456
456
|
{...restProps}
|
|
457
457
|
/>
|
|
458
|
-
</
|
|
458
|
+
</div>
|
|
459
459
|
<!-- クリアボタン -->
|
|
460
460
|
{#if clearable && !disabled && !readonly}
|
|
461
461
|
<div class="input__clear-button">
|
|
@@ -546,7 +546,7 @@
|
|
|
546
546
|
height: inherit;
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
|
|
549
|
+
.input__wrapper {
|
|
550
550
|
padding: inherit;
|
|
551
551
|
border: none;
|
|
552
552
|
font-size: inherit;
|
|
@@ -688,7 +688,7 @@
|
|
|
688
688
|
* デザインバリアント:default
|
|
689
689
|
* ============================================= */
|
|
690
690
|
.input:not(.input--inline) {
|
|
691
|
-
|
|
691
|
+
.input__wrapper {
|
|
692
692
|
position: static;
|
|
693
693
|
opacity: 1;
|
|
694
694
|
}
|
|
@@ -749,7 +749,7 @@
|
|
|
749
749
|
text-align: right;
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
-
|
|
752
|
+
.input__wrapper {
|
|
753
753
|
position: absolute;
|
|
754
754
|
top: 0;
|
|
755
755
|
left: 0;
|
|
@@ -790,7 +790,7 @@
|
|
|
790
790
|
opacity: 0;
|
|
791
791
|
}
|
|
792
792
|
|
|
793
|
-
|
|
793
|
+
.input__wrapper {
|
|
794
794
|
opacity: 1;
|
|
795
795
|
}
|
|
796
796
|
}
|
|
@@ -62,9 +62,6 @@ type $$ComponentProps = {
|
|
|
62
62
|
onpointercancel?: Function;
|
|
63
63
|
onchange?: (value: any) => void;
|
|
64
64
|
oninput?: (value: any) => void;
|
|
65
|
-
onsubmit?: (value: any) => void;
|
|
66
|
-
oncompositionstart?: Function;
|
|
67
|
-
oncompositionend?: Function;
|
|
68
65
|
onRightIconClick?: Function;
|
|
69
66
|
onLeftIconClick?: Function;
|
|
70
67
|
[key: string]: any;
|
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
<!-- SegmentedControl.svelte -->
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import Icon from './Icon.svelte';
|
|
5
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
6
|
+
import type { SegmentedControlItem } from '../types/segmentedControlItem';
|
|
7
|
+
|
|
8
|
+
// =========================================================================
|
|
9
|
+
// Props, States & Constants
|
|
10
|
+
// =========================================================================
|
|
11
|
+
let {
|
|
12
|
+
// 基本プロパティ
|
|
13
|
+
items = [],
|
|
14
|
+
value = $bindable(''),
|
|
15
|
+
|
|
16
|
+
// HTML属性系
|
|
17
|
+
id,
|
|
18
|
+
name = `segmented-control-${Math.random().toString(36).substring(2, 15)}`,
|
|
19
|
+
|
|
20
|
+
// スタイル/レイアウト
|
|
21
|
+
size = 'medium',
|
|
22
|
+
fullWidth = false,
|
|
23
|
+
color,
|
|
24
|
+
rounded = false,
|
|
25
|
+
|
|
26
|
+
// アイコン関連
|
|
27
|
+
iconFilled = false,
|
|
28
|
+
iconWeight = 300,
|
|
29
|
+
iconGrade = 0,
|
|
30
|
+
iconOpticalSize,
|
|
31
|
+
iconVariant = 'outlined',
|
|
32
|
+
|
|
33
|
+
// 状態/動作
|
|
34
|
+
disabled = false,
|
|
35
|
+
|
|
36
|
+
// ARIA/アクセシビリティ
|
|
37
|
+
ariaLabel,
|
|
38
|
+
ariaLabelledby,
|
|
39
|
+
reducedMotion = false,
|
|
40
|
+
|
|
41
|
+
// 入力イベント
|
|
42
|
+
onchange = () => {}, // No params for type inference
|
|
43
|
+
|
|
44
|
+
// フォーカスイベント
|
|
45
|
+
onfocus = () => {}, // No params for type inference
|
|
46
|
+
onblur = () => {}, // No params for type inference
|
|
47
|
+
|
|
48
|
+
// キーボードイベント
|
|
49
|
+
onkeydown = () => {}, // No params for type inference
|
|
50
|
+
onkeyup = () => {}, // No params for type inference
|
|
51
|
+
|
|
52
|
+
// マウスイベント
|
|
53
|
+
onclick = () => {}, // No params for type inference
|
|
54
|
+
onmousedown = () => {}, // No params for type inference
|
|
55
|
+
onmouseup = () => {}, // No params for type inference
|
|
56
|
+
onmouseenter = () => {}, // No params for type inference
|
|
57
|
+
onmouseleave = () => {}, // No params for type inference
|
|
58
|
+
onmouseover = () => {}, // No params for type inference
|
|
59
|
+
onmouseout = () => {}, // No params for type inference
|
|
60
|
+
oncontextmenu = () => {}, // No params for type inference
|
|
61
|
+
onauxclick = () => {}, // No params for type inference
|
|
62
|
+
|
|
63
|
+
// タッチイベント
|
|
64
|
+
ontouchstart = () => {}, // No params for type inference
|
|
65
|
+
ontouchend = () => {}, // No params for type inference
|
|
66
|
+
ontouchmove = () => {}, // No params for type inference
|
|
67
|
+
ontouchcancel = () => {}, // No params for type inference
|
|
68
|
+
|
|
69
|
+
// ポインターイベント
|
|
70
|
+
onpointerdown = () => {}, // No params for type inference
|
|
71
|
+
onpointerup = () => {}, // No params for type inference
|
|
72
|
+
onpointerenter = () => {}, // No params for type inference
|
|
73
|
+
onpointerleave = () => {}, // No params for type inference
|
|
74
|
+
onpointermove = () => {}, // No params for type inference
|
|
75
|
+
onpointercancel = () => {}, // No params for type inference
|
|
76
|
+
|
|
77
|
+
// その他
|
|
78
|
+
...restProps
|
|
79
|
+
}: {
|
|
80
|
+
// 基本プロパティ
|
|
81
|
+
items: SegmentedControlItem[];
|
|
82
|
+
value: string;
|
|
83
|
+
|
|
84
|
+
// HTML属性系
|
|
85
|
+
id?: string;
|
|
86
|
+
name?: string;
|
|
87
|
+
|
|
88
|
+
// スタイル/レイアウト
|
|
89
|
+
size?: 'small' | 'medium' | 'large';
|
|
90
|
+
fullWidth?: boolean;
|
|
91
|
+
color?: string;
|
|
92
|
+
rounded?: boolean;
|
|
93
|
+
|
|
94
|
+
// アイコン関連
|
|
95
|
+
iconFilled?: boolean;
|
|
96
|
+
iconWeight?: IconWeight;
|
|
97
|
+
iconGrade?: IconGrade;
|
|
98
|
+
iconOpticalSize?: IconOpticalSize;
|
|
99
|
+
iconVariant?: IconVariant;
|
|
100
|
+
|
|
101
|
+
// 状態/動作
|
|
102
|
+
disabled?: boolean;
|
|
103
|
+
|
|
104
|
+
// ARIA/アクセシビリティ
|
|
105
|
+
ariaLabel?: string;
|
|
106
|
+
ariaLabelledby?: string;
|
|
107
|
+
reducedMotion?: boolean;
|
|
108
|
+
|
|
109
|
+
// 入力イベント
|
|
110
|
+
onchange?: (value: string) => void;
|
|
111
|
+
|
|
112
|
+
// フォーカスイベント
|
|
113
|
+
onfocus?: Function; // No params for type inference
|
|
114
|
+
onblur?: Function; // No params for type inference
|
|
115
|
+
|
|
116
|
+
// キーボードイベント
|
|
117
|
+
onkeydown?: Function; // No params for type inference
|
|
118
|
+
onkeyup?: Function; // No params for type inference
|
|
119
|
+
|
|
120
|
+
// マウスイベント
|
|
121
|
+
onclick?: Function; // No params for type inference
|
|
122
|
+
onmousedown?: Function; // No params for type inference
|
|
123
|
+
onmouseup?: Function; // No params for type inference
|
|
124
|
+
onmouseenter?: Function; // No params for type inference
|
|
125
|
+
onmouseleave?: Function; // No params for type inference
|
|
126
|
+
onmouseover?: Function; // No params for type inference
|
|
127
|
+
onmouseout?: Function; // No params for type inference
|
|
128
|
+
oncontextmenu?: Function; // No params for type inference
|
|
129
|
+
onauxclick?: Function; // No params for type inference
|
|
130
|
+
|
|
131
|
+
// タッチイベント
|
|
132
|
+
ontouchstart?: Function; // No params for type inference
|
|
133
|
+
ontouchend?: Function; // No params for type inference
|
|
134
|
+
ontouchmove?: Function; // No params for type inference
|
|
135
|
+
ontouchcancel?: Function; // No params for type inference
|
|
136
|
+
|
|
137
|
+
// ポインターイベント
|
|
138
|
+
onpointerdown?: Function; // No params for type inference
|
|
139
|
+
onpointerup?: Function; // No params for type inference
|
|
140
|
+
onpointerenter?: Function; // No params for type inference
|
|
141
|
+
onpointerleave?: Function; // No params for type inference
|
|
142
|
+
onpointermove?: Function; // No params for type inference
|
|
143
|
+
onpointercancel?: Function; // No params for type inference
|
|
144
|
+
|
|
145
|
+
// その他
|
|
146
|
+
[key: string]: any;
|
|
147
|
+
} = $props();
|
|
148
|
+
|
|
149
|
+
// =========================================================================
|
|
150
|
+
// Methods
|
|
151
|
+
// =========================================================================
|
|
152
|
+
const handleChange = (item: SegmentedControlItem, event: Event) => {
|
|
153
|
+
if (disabled || item.disabled) return;
|
|
154
|
+
|
|
155
|
+
const target = event.target as HTMLInputElement;
|
|
156
|
+
if (target.checked) {
|
|
157
|
+
value = item.value;
|
|
158
|
+
onchange(item.value);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const handleFocus = (event: FocusEvent) => {
|
|
163
|
+
onfocus(event);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const handleBlur = (event: FocusEvent) => {
|
|
167
|
+
onblur(event);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleKeydown = (event: KeyboardEvent) => {
|
|
171
|
+
if (disabled || items.length === 0) {
|
|
172
|
+
onkeydown(event);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Radioコンポーネントと同じキーボードナビゲーション
|
|
177
|
+
if (
|
|
178
|
+
event.key === 'ArrowUp' ||
|
|
179
|
+
event.key === 'ArrowDown' ||
|
|
180
|
+
event.key === 'ArrowLeft' ||
|
|
181
|
+
event.key === 'ArrowRight'
|
|
182
|
+
) {
|
|
183
|
+
const radioInputs = document.querySelectorAll(
|
|
184
|
+
`input[type="radio"][name="${name}"]`
|
|
185
|
+
) as NodeListOf<HTMLInputElement>;
|
|
186
|
+
const currentIndex = Array.from(radioInputs).findIndex((input) => input === event.target);
|
|
187
|
+
|
|
188
|
+
if (currentIndex !== -1) {
|
|
189
|
+
event.preventDefault();
|
|
190
|
+
let nextIndex;
|
|
191
|
+
|
|
192
|
+
if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
|
|
193
|
+
// 前の有効なアイテムを探す
|
|
194
|
+
for (let i = currentIndex - 1; i >= 0; i--) {
|
|
195
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
196
|
+
nextIndex = i;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// 見つからなければ最後の有効なアイテムへ
|
|
201
|
+
if (nextIndex === undefined) {
|
|
202
|
+
for (let i = items.length - 1; i > currentIndex; i--) {
|
|
203
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
204
|
+
nextIndex = i;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
// 次の有効なアイテムを探す
|
|
211
|
+
for (let i = currentIndex + 1; i < items.length; i++) {
|
|
212
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
213
|
+
nextIndex = i;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// 見つからなければ最初の有効なアイテムへ
|
|
218
|
+
if (nextIndex === undefined) {
|
|
219
|
+
for (let i = 0; i < currentIndex; i++) {
|
|
220
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
221
|
+
nextIndex = i;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (nextIndex !== undefined) {
|
|
229
|
+
const nextInput = radioInputs[nextIndex];
|
|
230
|
+
if (nextInput && !nextInput.disabled) {
|
|
231
|
+
nextInput.focus();
|
|
232
|
+
nextInput.click();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} else if (event.key === 'Home') {
|
|
237
|
+
event.preventDefault();
|
|
238
|
+
const radioInputs = document.querySelectorAll(
|
|
239
|
+
`input[type="radio"][name="${name}"]`
|
|
240
|
+
) as NodeListOf<HTMLInputElement>;
|
|
241
|
+
for (let i = 0; i < items.length; i++) {
|
|
242
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
243
|
+
radioInputs[i].focus();
|
|
244
|
+
radioInputs[i].click();
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else if (event.key === 'End') {
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
const radioInputs = document.querySelectorAll(
|
|
251
|
+
`input[type="radio"][name="${name}"]`
|
|
252
|
+
) as NodeListOf<HTMLInputElement>;
|
|
253
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
254
|
+
if (!items[i]?.disabled && !radioInputs[i].disabled) {
|
|
255
|
+
radioInputs[i].focus();
|
|
256
|
+
radioInputs[i].click();
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
onkeydown(event);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const handleKeyup = (event: KeyboardEvent) => {
|
|
266
|
+
onkeyup(event);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// マウスイベント
|
|
270
|
+
const handleClick = (event: MouseEvent) => {
|
|
271
|
+
if (disabled) return;
|
|
272
|
+
onclick(event);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const handleMouseDown = (event: MouseEvent) => {
|
|
276
|
+
if (disabled) return;
|
|
277
|
+
onmousedown(event);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const handleMouseUp = (event: MouseEvent) => {
|
|
281
|
+
if (disabled) return;
|
|
282
|
+
onmouseup(event);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const handleMouseEnter = (event: MouseEvent) => {
|
|
286
|
+
if (disabled) return;
|
|
287
|
+
onmouseenter(event);
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const handleMouseLeave = (event: MouseEvent) => {
|
|
291
|
+
if (disabled) return;
|
|
292
|
+
onmouseleave(event);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const handleMouseOver = (event: MouseEvent) => {
|
|
296
|
+
if (disabled) return;
|
|
297
|
+
onmouseover(event);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const handleMouseOut = (event: MouseEvent) => {
|
|
301
|
+
if (disabled) return;
|
|
302
|
+
onmouseout(event);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const handleContextMenu = (event: MouseEvent) => {
|
|
306
|
+
if (disabled) return;
|
|
307
|
+
oncontextmenu(event);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const handleAuxClick = (event: MouseEvent) => {
|
|
311
|
+
if (disabled) return;
|
|
312
|
+
onauxclick(event);
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// タッチイベント
|
|
316
|
+
const handleTouchStart = (event: TouchEvent) => {
|
|
317
|
+
if (disabled) return;
|
|
318
|
+
ontouchstart(event);
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const handleTouchEnd = (event: TouchEvent) => {
|
|
322
|
+
if (disabled) return;
|
|
323
|
+
ontouchend(event);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const handleTouchMove = (event: TouchEvent) => {
|
|
327
|
+
if (disabled) return;
|
|
328
|
+
ontouchmove(event);
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const handleTouchCancel = (event: TouchEvent) => {
|
|
332
|
+
if (disabled) return;
|
|
333
|
+
ontouchcancel(event);
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// ポインターイベント
|
|
337
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
338
|
+
if (disabled) return;
|
|
339
|
+
onpointerdown(event);
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const handlePointerUp = (event: PointerEvent) => {
|
|
343
|
+
if (disabled) return;
|
|
344
|
+
onpointerup(event);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const handlePointerEnter = (event: PointerEvent) => {
|
|
348
|
+
if (disabled) return;
|
|
349
|
+
onpointerenter(event);
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const handlePointerLeave = (event: PointerEvent) => {
|
|
353
|
+
if (disabled) return;
|
|
354
|
+
onpointerleave(event);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const handlePointerMove = (event: PointerEvent) => {
|
|
358
|
+
if (disabled) return;
|
|
359
|
+
onpointermove(event);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const handlePointerCancel = (event: PointerEvent) => {
|
|
363
|
+
if (disabled) return;
|
|
364
|
+
onpointercancel(event);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// =========================================================================
|
|
368
|
+
// $derived
|
|
369
|
+
// =========================================================================
|
|
370
|
+
const effectiveIconSize = $derived(
|
|
371
|
+
iconOpticalSize || (size === 'small' ? 16 : size === 'large' ? 24 : 20)
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
const containerClasses = $derived(
|
|
375
|
+
[
|
|
376
|
+
'segmented-control',
|
|
377
|
+
`segmented-control--${size}`,
|
|
378
|
+
fullWidth && 'segmented-control--full-width',
|
|
379
|
+
rounded && 'segmented-control--rounded',
|
|
380
|
+
disabled && 'segmented-control--disabled',
|
|
381
|
+
reducedMotion && 'segmented-control--no-motion'
|
|
382
|
+
]
|
|
383
|
+
.filter(Boolean)
|
|
384
|
+
.join(' ')
|
|
385
|
+
);
|
|
386
|
+
</script>
|
|
387
|
+
|
|
388
|
+
<div
|
|
389
|
+
class={containerClasses}
|
|
390
|
+
role="radiogroup"
|
|
391
|
+
aria-label={ariaLabelledby ? undefined : ariaLabel}
|
|
392
|
+
aria-labelledby={ariaLabelledby}
|
|
393
|
+
style="--svelte-ui-segmented-control-selected-bg: {color || 'var(--svelte-ui-primary-color)'};"
|
|
394
|
+
{id}
|
|
395
|
+
data-testid="segmented-control"
|
|
396
|
+
{...restProps}
|
|
397
|
+
>
|
|
398
|
+
{#each items as item, index}
|
|
399
|
+
{@const isSelected = value === item.value}
|
|
400
|
+
{@const isDisabled = disabled || item.disabled}
|
|
401
|
+
{@const inputId = `${name}-${index}`}
|
|
402
|
+
<div class="segmented-control__item">
|
|
403
|
+
<input
|
|
404
|
+
type="radio"
|
|
405
|
+
id={inputId}
|
|
406
|
+
{name}
|
|
407
|
+
value={item.value}
|
|
408
|
+
checked={isSelected}
|
|
409
|
+
disabled={isDisabled}
|
|
410
|
+
class="segmented-control__input"
|
|
411
|
+
onchange={(e) => handleChange(item, e)}
|
|
412
|
+
onfocus={handleFocus}
|
|
413
|
+
onblur={handleBlur}
|
|
414
|
+
onkeydown={handleKeydown}
|
|
415
|
+
onkeyup={handleKeyup}
|
|
416
|
+
onclick={handleClick}
|
|
417
|
+
onmousedown={handleMouseDown}
|
|
418
|
+
onmouseup={handleMouseUp}
|
|
419
|
+
onmouseenter={handleMouseEnter}
|
|
420
|
+
onmouseleave={handleMouseLeave}
|
|
421
|
+
onmouseover={handleMouseOver}
|
|
422
|
+
onmouseout={handleMouseOut}
|
|
423
|
+
oncontextmenu={handleContextMenu}
|
|
424
|
+
onauxclick={handleAuxClick}
|
|
425
|
+
ontouchstart={handleTouchStart}
|
|
426
|
+
ontouchend={handleTouchEnd}
|
|
427
|
+
ontouchmove={handleTouchMove}
|
|
428
|
+
ontouchcancel={handleTouchCancel}
|
|
429
|
+
onpointerdown={handlePointerDown}
|
|
430
|
+
onpointerup={handlePointerUp}
|
|
431
|
+
onpointerenter={handlePointerEnter}
|
|
432
|
+
onpointerleave={handlePointerLeave}
|
|
433
|
+
onpointermove={handlePointerMove}
|
|
434
|
+
onpointercancel={handlePointerCancel}
|
|
435
|
+
data-testid="segmented-control-input"
|
|
436
|
+
data-value={item.value}
|
|
437
|
+
/>
|
|
438
|
+
<label
|
|
439
|
+
for={inputId}
|
|
440
|
+
class="segmented-control__label"
|
|
441
|
+
class:segmented-control__label--selected={isSelected}
|
|
442
|
+
class:segmented-control__label--first={index === 0}
|
|
443
|
+
class:segmented-control__label--last={index === items.length - 1}
|
|
444
|
+
aria-label={item.ariaLabel || item.label || undefined}
|
|
445
|
+
>
|
|
446
|
+
{#if item.icon}
|
|
447
|
+
<span class="segmented-control__icon">
|
|
448
|
+
<Icon
|
|
449
|
+
filled={iconFilled || isSelected}
|
|
450
|
+
weight={iconWeight}
|
|
451
|
+
grade={iconGrade}
|
|
452
|
+
opticalSize={effectiveIconSize}
|
|
453
|
+
variant={iconVariant}
|
|
454
|
+
>
|
|
455
|
+
{item.icon}
|
|
456
|
+
</Icon>
|
|
457
|
+
</span>
|
|
458
|
+
{/if}
|
|
459
|
+
{#if item.label}
|
|
460
|
+
<span class="segmented-control__label-text">{item.label}</span>
|
|
461
|
+
{/if}
|
|
462
|
+
</label>
|
|
463
|
+
</div>
|
|
464
|
+
{/each}
|
|
465
|
+
</div>
|
|
466
|
+
|
|
467
|
+
<style>.segmented-control {
|
|
468
|
+
display: inline-flex;
|
|
469
|
+
position: relative;
|
|
470
|
+
padding: var(--svelte-ui-segmented-control-base-padding);
|
|
471
|
+
background-color: var(--svelte-ui-segmented-control-base-bg);
|
|
472
|
+
border-radius: var(--svelte-ui-segmented-control-base-border-radius);
|
|
473
|
+
gap: var(--svelte-ui-segmented-control-gap);
|
|
474
|
+
box-sizing: border-box;
|
|
475
|
+
width: fit-content;
|
|
476
|
+
max-width: 100%;
|
|
477
|
+
overflow-x: auto;
|
|
478
|
+
overflow-y: visible;
|
|
479
|
+
-ms-overflow-style: none;
|
|
480
|
+
overscroll-behavior: contain;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.segmented-control::-webkit-scrollbar {
|
|
484
|
+
display: none;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.segmented-control--full-width {
|
|
488
|
+
width: 100%;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.segmented-control--full-width .segmented-control__item {
|
|
492
|
+
flex: 1;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.segmented-control--rounded {
|
|
496
|
+
border-radius: var(--svelte-ui-border-radius-rounded, 9999px);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.segmented-control--disabled {
|
|
500
|
+
opacity: var(--svelte-ui-button-disabled-opacity);
|
|
501
|
+
pointer-events: none;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.segmented-control__item {
|
|
505
|
+
position: relative;
|
|
506
|
+
flex: 0 1 auto;
|
|
507
|
+
display: flex;
|
|
508
|
+
align-items: stretch;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.segmented-control__input {
|
|
512
|
+
position: absolute;
|
|
513
|
+
width: 0;
|
|
514
|
+
height: 0;
|
|
515
|
+
margin: 0;
|
|
516
|
+
opacity: 0;
|
|
517
|
+
pointer-events: none;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.segmented-control__label {
|
|
521
|
+
display: flex;
|
|
522
|
+
align-items: center;
|
|
523
|
+
justify-content: center;
|
|
524
|
+
gap: 6px;
|
|
525
|
+
position: relative;
|
|
526
|
+
border: none;
|
|
527
|
+
background-color: transparent;
|
|
528
|
+
color: var(--svelte-ui-text-subtle-color, var(--svelte-ui-text-color));
|
|
529
|
+
white-space: nowrap;
|
|
530
|
+
cursor: pointer;
|
|
531
|
+
user-select: none;
|
|
532
|
+
-webkit-user-select: none;
|
|
533
|
+
-moz-user-select: none;
|
|
534
|
+
-ms-user-select: none;
|
|
535
|
+
transition-property: background-color, color;
|
|
536
|
+
transition-duration: var(--svelte-ui-transition-duration, 0.2s);
|
|
537
|
+
transition-timing-function: ease;
|
|
538
|
+
outline: none;
|
|
539
|
+
font-family: inherit;
|
|
540
|
+
font-weight: 500;
|
|
541
|
+
line-height: 1;
|
|
542
|
+
box-sizing: border-box;
|
|
543
|
+
width: 100%;
|
|
544
|
+
text-align: center;
|
|
545
|
+
border-radius: var(--svelte-ui-segmented-control-button-radius);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
.segmented-control--small .segmented-control__label {
|
|
549
|
+
height: var(--svelte-ui-segmented-control-button-height-sm);
|
|
550
|
+
font-size: var(--svelte-ui-segmented-control-font-size-sm);
|
|
551
|
+
padding: var(--svelte-ui-segmented-control-button-padding-sm);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.segmented-control--small .segmented-control__label:not(:has(.segmented-control__label-text)) {
|
|
555
|
+
width: var(--svelte-ui-segmented-control-button-height-sm);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.segmented-control--medium .segmented-control__label {
|
|
559
|
+
height: var(--svelte-ui-segmented-control-button-height);
|
|
560
|
+
font-size: var(--svelte-ui-segmented-control-font-size);
|
|
561
|
+
padding: var(--svelte-ui-segmented-control-button-padding);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.segmented-control--medium .segmented-control__label:not(:has(.segmented-control__label-text)) {
|
|
565
|
+
width: var(--svelte-ui-segmented-control-button-height);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.segmented-control--large .segmented-control__label {
|
|
569
|
+
height: var(--svelte-ui-segmented-control-button-height-lg);
|
|
570
|
+
font-size: var(--svelte-ui-segmented-control-font-size-lg);
|
|
571
|
+
padding: var(--svelte-ui-segmented-control-button-padding-lg);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.segmented-control--large .segmented-control__label:not(:has(.segmented-control__label-text)) {
|
|
575
|
+
width: var(--svelte-ui-segmented-control-button-height-lg);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.segmented-control--rounded .segmented-control__label {
|
|
579
|
+
border-radius: calc(var(--svelte-ui-border-radius-rounded, 9999px) - 2px);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
@media (hover: hover) {
|
|
583
|
+
.segmented-control__input:not(:disabled) + .segmented-control__label:hover:not(.segmented-control__label--selected) {
|
|
584
|
+
background-color: var(--svelte-ui-segmented-control-hover-overlay);
|
|
585
|
+
color: var(--svelte-ui-text-color);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
.segmented-control__input:focus-visible + .segmented-control__label {
|
|
589
|
+
outline: var(--svelte-ui-focus-outline-inner, 2px solid currentColor);
|
|
590
|
+
outline-offset: var(--svelte-ui-focus-outline-offset-inner, 2px);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.segmented-control__input:checked + .segmented-control__label,
|
|
594
|
+
.segmented-control__label--selected {
|
|
595
|
+
background-color: var(--svelte-ui-segmented-control-selected-bg);
|
|
596
|
+
color: var(--svelte-ui-segmented-control-selected-text-color, white);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
.segmented-control:not(.segmented-control--disabled) .segmented-control__input:disabled + .segmented-control__label {
|
|
600
|
+
opacity: var(--svelte-ui-button-disabled-opacity);
|
|
601
|
+
cursor: not-allowed;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.segmented-control__icon {
|
|
605
|
+
display: flex;
|
|
606
|
+
align-items: center;
|
|
607
|
+
justify-content: center;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.segmented-control__label-text {
|
|
611
|
+
text-box-trim: trim-both;
|
|
612
|
+
text-box-edge: cap alphabetic;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* Reduced motion */
|
|
616
|
+
.segmented-control--no-motion,
|
|
617
|
+
.segmented-control--no-motion .segmented-control__label {
|
|
618
|
+
transition-duration: 0.01s;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
@media (prefers-reduced-motion: reduce) {
|
|
622
|
+
.segmented-control,
|
|
623
|
+
.segmented-control__label {
|
|
624
|
+
transition-duration: 0.01s;
|
|
625
|
+
}
|
|
626
|
+
}</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
2
|
+
import type { SegmentedControlItem } from '../types/segmentedControlItem';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
items: SegmentedControlItem[];
|
|
5
|
+
value: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
size?: 'small' | 'medium' | 'large';
|
|
9
|
+
fullWidth?: boolean;
|
|
10
|
+
color?: string;
|
|
11
|
+
rounded?: boolean;
|
|
12
|
+
iconFilled?: boolean;
|
|
13
|
+
iconWeight?: IconWeight;
|
|
14
|
+
iconGrade?: IconGrade;
|
|
15
|
+
iconOpticalSize?: IconOpticalSize;
|
|
16
|
+
iconVariant?: IconVariant;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
ariaLabel?: string;
|
|
19
|
+
ariaLabelledby?: string;
|
|
20
|
+
reducedMotion?: boolean;
|
|
21
|
+
onchange?: (value: string) => void;
|
|
22
|
+
onfocus?: Function;
|
|
23
|
+
onblur?: Function;
|
|
24
|
+
onkeydown?: Function;
|
|
25
|
+
onkeyup?: Function;
|
|
26
|
+
onclick?: Function;
|
|
27
|
+
onmousedown?: Function;
|
|
28
|
+
onmouseup?: Function;
|
|
29
|
+
onmouseenter?: Function;
|
|
30
|
+
onmouseleave?: Function;
|
|
31
|
+
onmouseover?: Function;
|
|
32
|
+
onmouseout?: Function;
|
|
33
|
+
oncontextmenu?: Function;
|
|
34
|
+
onauxclick?: Function;
|
|
35
|
+
ontouchstart?: Function;
|
|
36
|
+
ontouchend?: Function;
|
|
37
|
+
ontouchmove?: Function;
|
|
38
|
+
ontouchcancel?: Function;
|
|
39
|
+
onpointerdown?: Function;
|
|
40
|
+
onpointerup?: Function;
|
|
41
|
+
onpointerenter?: Function;
|
|
42
|
+
onpointerleave?: Function;
|
|
43
|
+
onpointermove?: Function;
|
|
44
|
+
onpointercancel?: Function;
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
};
|
|
47
|
+
declare const SegmentedControl: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
48
|
+
type SegmentedControl = ReturnType<typeof SegmentedControl>;
|
|
49
|
+
export default SegmentedControl;
|
|
@@ -112,7 +112,10 @@
|
|
|
112
112
|
);
|
|
113
113
|
const requiredMargin = -containerHeight;
|
|
114
114
|
|
|
115
|
-
snackbarRef.style.setProperty(
|
|
115
|
+
snackbarRef.style.setProperty(
|
|
116
|
+
'--svelte-ui-snackbar-item-collapse-margin',
|
|
117
|
+
`${requiredMargin}px`
|
|
118
|
+
);
|
|
116
119
|
|
|
117
120
|
// CSSカスタムプロパティが確実に設定されるまで少し待つ
|
|
118
121
|
requestAnimationFrame(() => {
|
|
@@ -149,7 +152,8 @@
|
|
|
149
152
|
class="snackbar-item__content snackbar-item__content--{type} snackbar-item__content--{variant} snackbar-item__content--{position} {visible
|
|
150
153
|
? 'snackbar-item__content--visible'
|
|
151
154
|
: ''}"
|
|
152
|
-
style="--svelte-ui-snackbar-item-custom-color: {color ??
|
|
155
|
+
style="--svelte-ui-snackbar-item-custom-color: {color ??
|
|
156
|
+
'unset'}; --svelte-ui-snackbar-item-custom-text-color: {textColor ?? 'unset'};"
|
|
153
157
|
role={type === 'error' || type === 'warning' ? 'alert' : 'status'}
|
|
154
158
|
aria-live={type === 'error' || type === 'warning' ? 'assertive' : 'polite'}
|
|
155
159
|
aria-atomic="true"
|
|
@@ -321,103 +325,208 @@
|
|
|
321
325
|
|
|
322
326
|
/* Type variants - filled */
|
|
323
327
|
.snackbar-item__content--filled.snackbar-item__content--info {
|
|
324
|
-
background-color: var(
|
|
325
|
-
|
|
328
|
+
background-color: var(
|
|
329
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
330
|
+
var(--svelte-ui-snackbar-info-filled-bg)
|
|
331
|
+
);
|
|
332
|
+
color: var(
|
|
333
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
334
|
+
var(--svelte-ui-snackbar-info-filled-text-color)
|
|
335
|
+
);
|
|
326
336
|
}
|
|
327
337
|
|
|
328
338
|
.snackbar-item__content--filled.snackbar-item__content--info .snackbar-item__icon {
|
|
329
|
-
color: var(
|
|
339
|
+
color: var(
|
|
340
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
341
|
+
var(--svelte-ui-snackbar-info-filled-text-color)
|
|
342
|
+
);
|
|
330
343
|
}
|
|
331
344
|
|
|
332
345
|
.snackbar-item__content--filled.snackbar-item__content--success {
|
|
333
|
-
background-color: var(
|
|
334
|
-
|
|
346
|
+
background-color: var(
|
|
347
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
348
|
+
var(--svelte-ui-snackbar-success-filled-bg)
|
|
349
|
+
);
|
|
350
|
+
color: var(
|
|
351
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
352
|
+
var(--svelte-ui-snackbar-success-filled-text-color)
|
|
353
|
+
);
|
|
335
354
|
}
|
|
336
355
|
|
|
337
356
|
.snackbar-item__content--filled.snackbar-item__content--success .snackbar-item__icon {
|
|
338
|
-
color: var(
|
|
357
|
+
color: var(
|
|
358
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
359
|
+
var(--svelte-ui-snackbar-success-filled-text-color)
|
|
360
|
+
);
|
|
339
361
|
}
|
|
340
362
|
|
|
341
363
|
.snackbar-item__content--filled.snackbar-item__content--warning {
|
|
342
|
-
background-color: var(
|
|
343
|
-
|
|
364
|
+
background-color: var(
|
|
365
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
366
|
+
var(--svelte-ui-snackbar-warning-filled-bg)
|
|
367
|
+
);
|
|
368
|
+
color: var(
|
|
369
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
370
|
+
var(--svelte-ui-snackbar-warning-filled-text-color)
|
|
371
|
+
);
|
|
344
372
|
}
|
|
345
373
|
|
|
346
374
|
.snackbar-item__content--filled.snackbar-item__content--warning .snackbar-item__icon {
|
|
347
|
-
color: var(
|
|
375
|
+
color: var(
|
|
376
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
377
|
+
var(--svelte-ui-snackbar-warning-filled-text-color)
|
|
378
|
+
);
|
|
348
379
|
}
|
|
349
380
|
|
|
350
381
|
.snackbar-item__content--filled.snackbar-item__content--error {
|
|
351
|
-
background-color: var(
|
|
352
|
-
|
|
382
|
+
background-color: var(
|
|
383
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
384
|
+
var(--svelte-ui-snackbar-error-filled-bg)
|
|
385
|
+
);
|
|
386
|
+
color: var(
|
|
387
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
388
|
+
var(--svelte-ui-snackbar-error-filled-text-color)
|
|
389
|
+
);
|
|
353
390
|
}
|
|
354
391
|
|
|
355
392
|
.snackbar-item__content--filled.snackbar-item__content--error .snackbar-item__icon {
|
|
356
|
-
color: var(
|
|
393
|
+
color: var(
|
|
394
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
395
|
+
var(--svelte-ui-snackbar-error-filled-text-color)
|
|
396
|
+
);
|
|
357
397
|
}
|
|
358
398
|
|
|
359
399
|
.snackbar-item__content--filled.snackbar-item__content--default {
|
|
360
|
-
background-color: var(
|
|
361
|
-
|
|
400
|
+
background-color: var(
|
|
401
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
402
|
+
var(--svelte-ui-snackbar-default-filled-bg)
|
|
403
|
+
);
|
|
404
|
+
color: var(
|
|
405
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
406
|
+
var(--svelte-ui-snackbar-default-filled-text-color)
|
|
407
|
+
);
|
|
362
408
|
}
|
|
363
409
|
|
|
364
410
|
.snackbar-item__content--filled.snackbar-item__content--default .snackbar-item__icon {
|
|
365
|
-
color: var(
|
|
411
|
+
color: var(
|
|
412
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
413
|
+
var(--svelte-ui-snackbar-default-filled-text-color)
|
|
414
|
+
);
|
|
366
415
|
}
|
|
367
416
|
|
|
368
417
|
/* Type variants - outlined */
|
|
369
418
|
.snackbar-item__content--outlined.snackbar-item__content--info {
|
|
370
|
-
background-color: var(
|
|
371
|
-
|
|
419
|
+
background-color: var(
|
|
420
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
421
|
+
var(--svelte-ui-snackbar-info-outlined-bg)
|
|
422
|
+
);
|
|
423
|
+
color: var(
|
|
424
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
425
|
+
var(--svelte-ui-snackbar-info-outlined-text-color)
|
|
426
|
+
);
|
|
372
427
|
box-shadow: inset 0 0 0 1px
|
|
373
|
-
var(
|
|
428
|
+
var(
|
|
429
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
430
|
+
var(--svelte-ui-snackbar-info-outlined-border-color)
|
|
431
|
+
);
|
|
374
432
|
}
|
|
375
433
|
|
|
376
434
|
.snackbar-item__content--outlined.snackbar-item__content--info .snackbar-item__icon {
|
|
377
|
-
color: var(
|
|
435
|
+
color: var(
|
|
436
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
437
|
+
var(--svelte-ui-snackbar-info-outlined-text-color)
|
|
438
|
+
);
|
|
378
439
|
}
|
|
379
440
|
|
|
380
441
|
.snackbar-item__content--outlined.snackbar-item__content--success {
|
|
381
|
-
background-color: var(
|
|
382
|
-
|
|
442
|
+
background-color: var(
|
|
443
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
444
|
+
var(--svelte-ui-snackbar-success-outlined-bg)
|
|
445
|
+
);
|
|
446
|
+
color: var(
|
|
447
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
448
|
+
var(--svelte-ui-snackbar-success-outlined-text-color)
|
|
449
|
+
);
|
|
383
450
|
box-shadow: inset 0 0 0 1px
|
|
384
|
-
var(
|
|
451
|
+
var(
|
|
452
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
453
|
+
var(--svelte-ui-snackbar-success-outlined-border-color)
|
|
454
|
+
);
|
|
385
455
|
}
|
|
386
456
|
|
|
387
457
|
.snackbar-item__content--outlined.snackbar-item__content--success .snackbar-item__icon {
|
|
388
|
-
color: var(
|
|
458
|
+
color: var(
|
|
459
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
460
|
+
var(--svelte-ui-snackbar-success-outlined-text-color)
|
|
461
|
+
);
|
|
389
462
|
}
|
|
390
463
|
|
|
391
464
|
.snackbar-item__content--outlined.snackbar-item__content--warning {
|
|
392
|
-
background-color: var(
|
|
393
|
-
|
|
465
|
+
background-color: var(
|
|
466
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
467
|
+
var(--svelte-ui-snackbar-warning-outlined-bg)
|
|
468
|
+
);
|
|
469
|
+
color: var(
|
|
470
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
471
|
+
var(--svelte-ui-snackbar-warning-outlined-text-color)
|
|
472
|
+
);
|
|
394
473
|
box-shadow: inset 0 0 0 1px
|
|
395
|
-
var(
|
|
474
|
+
var(
|
|
475
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
476
|
+
var(--svelte-ui-snackbar-warning-outlined-border-color)
|
|
477
|
+
);
|
|
396
478
|
}
|
|
397
479
|
|
|
398
480
|
.snackbar-item__content--outlined.snackbar-item__content--warning .snackbar-item__icon {
|
|
399
|
-
color: var(
|
|
481
|
+
color: var(
|
|
482
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
483
|
+
var(--svelte-ui-snackbar-warning-outlined-text-color)
|
|
484
|
+
);
|
|
400
485
|
}
|
|
401
486
|
|
|
402
487
|
.snackbar-item__content--outlined.snackbar-item__content--error {
|
|
403
|
-
background-color: var(
|
|
404
|
-
|
|
488
|
+
background-color: var(
|
|
489
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
490
|
+
var(--svelte-ui-snackbar-error-outlined-bg)
|
|
491
|
+
);
|
|
492
|
+
color: var(
|
|
493
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
494
|
+
var(--svelte-ui-snackbar-error-outlined-text-color)
|
|
495
|
+
);
|
|
405
496
|
box-shadow: inset 0 0 0 1px
|
|
406
|
-
var(
|
|
497
|
+
var(
|
|
498
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
499
|
+
var(--svelte-ui-snackbar-error-outlined-border-color)
|
|
500
|
+
);
|
|
407
501
|
}
|
|
408
502
|
|
|
409
503
|
.snackbar-item__content--outlined.snackbar-item__content--error .snackbar-item__icon {
|
|
410
|
-
color: var(
|
|
504
|
+
color: var(
|
|
505
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
506
|
+
var(--svelte-ui-snackbar-error-outlined-text-color)
|
|
507
|
+
);
|
|
411
508
|
}
|
|
412
509
|
|
|
413
510
|
.snackbar-item__content--outlined.snackbar-item__content--default {
|
|
414
|
-
background-color: var(
|
|
415
|
-
|
|
511
|
+
background-color: var(
|
|
512
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
513
|
+
var(--svelte-ui-snackbar-default-outlined-bg)
|
|
514
|
+
);
|
|
515
|
+
color: var(
|
|
516
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
517
|
+
var(--svelte-ui-snackbar-default-outlined-text-color)
|
|
518
|
+
);
|
|
416
519
|
box-shadow: inset 0 0 0 1px
|
|
417
|
-
var(
|
|
520
|
+
var(
|
|
521
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
522
|
+
var(--svelte-ui-snackbar-default-outlined-border-color)
|
|
523
|
+
);
|
|
418
524
|
}
|
|
419
525
|
|
|
420
526
|
.snackbar-item__content--outlined.snackbar-item__content--default .snackbar-item__icon {
|
|
421
|
-
color: var(
|
|
527
|
+
color: var(
|
|
528
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
529
|
+
var(--svelte-ui-snackbar-default-outlined-text-color)
|
|
530
|
+
);
|
|
422
531
|
}
|
|
423
532
|
</style>
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export { default as PopupMenuButton } from './components/PopupMenuButton.svelte'
|
|
|
23
23
|
export { default as Radio } from './components/Radio.svelte';
|
|
24
24
|
export { default as RadioGroup } from './components/RadioGroup.svelte';
|
|
25
25
|
export { default as Select } from './components/Select.svelte';
|
|
26
|
+
export { default as SegmentedControl } from './components/SegmentedControl.svelte';
|
|
26
27
|
export { default as Slider } from './components/Slider.svelte';
|
|
27
28
|
export { default as Snackbar } from './components/Snackbar.svelte';
|
|
28
29
|
export { default as SnackbarItem } from './components/SnackbarItem.svelte';
|
|
@@ -40,3 +41,4 @@ export * from './utils/mobile';
|
|
|
40
41
|
export * from './utils/snackbar.svelte';
|
|
41
42
|
export * from './utils/style';
|
|
42
43
|
export type { MenuItem } from './types/menuItem';
|
|
44
|
+
export type { SegmentedControlItem } from './types/segmentedControlItem';
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ export { default as PopupMenuButton } from './components/PopupMenuButton.svelte'
|
|
|
24
24
|
export { default as Radio } from './components/Radio.svelte';
|
|
25
25
|
export { default as RadioGroup } from './components/RadioGroup.svelte';
|
|
26
26
|
export { default as Select } from './components/Select.svelte';
|
|
27
|
+
export { default as SegmentedControl } from './components/SegmentedControl.svelte';
|
|
27
28
|
export { default as Slider } from './components/Slider.svelte';
|
|
28
29
|
export { default as Snackbar } from './components/Snackbar.svelte';
|
|
29
30
|
export { default as SnackbarItem } from './components/SnackbarItem.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|