@14ch/svelte-ui 0.0.13 → 0.0.15
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 +3 -7
- package/dist/components/Button.svelte +31 -5
- package/dist/components/Button.svelte.d.ts +5 -3
- package/dist/components/Checkbox.svelte +4 -4
- package/dist/components/Checkbox.svelte.d.ts +1 -1
- package/dist/components/CheckboxGroup.svelte +6 -3
- package/dist/components/CheckboxGroup.svelte.d.ts +1 -1
- package/dist/components/ColorPicker.svelte +18 -10
- package/dist/components/ColorPicker.svelte.d.ts +4 -4
- package/dist/components/Combobox.svelte +28 -8
- package/dist/components/Combobox.svelte.d.ts +1 -1
- package/dist/components/ConfirmDialog.svelte +3 -7
- package/dist/components/ConfirmDialog.svelte.d.ts +1 -1
- package/dist/components/Datepicker.svelte +88 -24
- package/dist/components/Datepicker.svelte.d.ts +4 -3
- package/dist/components/DatepickerCalendar.svelte +1 -1
- package/dist/components/DatepickerCalendar.svelte.d.ts +1 -1
- package/dist/components/Drawer.svelte +8 -4
- package/dist/components/Drawer.svelte.d.ts +1 -1
- package/dist/components/Fab.svelte +28 -11
- package/dist/components/Fab.svelte.d.ts +8 -4
- package/dist/components/FileUploader.svelte +1 -1
- package/dist/components/FileUploader.svelte.d.ts +1 -1
- package/dist/components/Icon.svelte +20 -24
- package/dist/components/Icon.svelte.d.ts +1 -1
- package/dist/components/IconButton.svelte +4 -3
- package/dist/components/IconButton.svelte.d.ts +4 -3
- package/dist/components/ImageUploader.svelte +1 -1
- package/dist/components/ImageUploader.svelte.d.ts +1 -1
- package/dist/components/Input.svelte +110 -99
- package/dist/components/Input.svelte.d.ts +5 -3
- package/dist/components/Popup.svelte +69 -82
- package/dist/components/Popup.svelte.d.ts +3 -3
- package/dist/components/PopupMenu.svelte +40 -56
- package/dist/components/PopupMenu.svelte.d.ts +3 -3
- package/dist/components/PopupMenuButton.svelte +10 -23
- package/dist/components/PopupMenuButton.svelte.d.ts +5 -4
- package/dist/components/Radio.svelte +3 -2
- package/dist/components/Radio.svelte.d.ts +1 -1
- package/dist/components/RadioGroup.svelte +1 -1
- package/dist/components/RadioGroup.svelte.d.ts +1 -1
- package/dist/components/SegmentedControl.svelte +4 -5
- package/dist/components/SegmentedControl.svelte.d.ts +1 -1
- package/dist/components/Select.svelte +2 -2
- package/dist/components/Select.svelte.d.ts +1 -1
- package/dist/components/Slider.svelte +2 -3
- package/dist/components/Slider.svelte.d.ts +1 -1
- package/dist/components/Snackbar.svelte +3 -2
- package/dist/components/Snackbar.svelte.d.ts +3 -2
- package/dist/components/SnackbarItem.svelte +4 -3
- package/dist/components/SnackbarItem.svelte.d.ts +4 -3
- package/dist/components/Switch.svelte +2 -4
- package/dist/components/Switch.svelte.d.ts +1 -1
- package/dist/components/Tab.svelte +1 -0
- package/dist/components/TabItem.svelte +24 -3
- package/dist/components/TabItem.svelte.d.ts +1 -0
- package/dist/components/Textarea.svelte +74 -38
- package/dist/components/Textarea.svelte.d.ts +4 -3
- package/dist/components/skeleton/SkeletonAvatar.svelte +22 -32
- package/dist/components/skeleton/SkeletonAvatar.svelte.d.ts +6 -2
- package/dist/components/skeleton/SkeletonButton.svelte +18 -16
- package/dist/components/skeleton/SkeletonButton.svelte.d.ts +5 -2
- package/dist/components/skeleton/SkeletonHeading.svelte +15 -18
- package/dist/components/skeleton/SkeletonHeading.svelte.d.ts +3 -2
- package/dist/components/skeleton/SkeletonMedia.svelte +29 -41
- package/dist/components/skeleton/SkeletonMedia.svelte.d.ts +8 -2
- package/dist/components/skeleton/SkeletonText.svelte +12 -14
- package/dist/components/skeleton/SkeletonText.svelte.d.ts +4 -2
- package/dist/i18n/index.d.ts +143 -6
- package/dist/i18n/index.js +18 -40
- package/dist/i18n/locales/de.d.ts +35 -0
- package/dist/i18n/locales/de.js +35 -0
- package/dist/i18n/locales/es.d.ts +35 -0
- package/dist/i18n/locales/es.js +35 -0
- package/dist/i18n/locales/fr.d.ts +35 -0
- package/dist/i18n/locales/fr.js +35 -0
- package/dist/i18n/locales/zh-cn.d.ts +35 -0
- package/dist/i18n/locales/zh-cn.js +35 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +1 -0
- package/dist/types/menuItem.d.ts +1 -1
- package/dist/types/propOptions.d.ts +54 -0
- package/dist/types/propOptions.js +5 -0
- package/dist/utils/formatText.d.ts +2 -2
- package/dist/utils/formatText.js +2 -2
- package/dist/utils/popupManager.d.ts +26 -0
- package/dist/utils/popupManager.js +34 -0
- package/package.json +1 -1
- /package/dist/types/{eventHandlers.d.ts → callbackHandlers.d.ts} +0 -0
- /package/dist/types/{eventHandlers.js → callbackHandlers.js} +0 -0
|
@@ -376,7 +376,7 @@
|
|
|
376
376
|
--svelte-ui-input-icon-space-double-inline: calc(var(--svelte-ui-form-icon-space) * 2);
|
|
377
377
|
--svelte-ui-input-bg: var(--svelte-ui-form-bg);
|
|
378
378
|
--svelte-ui-input-border-color: var(--svelte-ui-border-weak-color);
|
|
379
|
-
--svelte-ui-input-
|
|
379
|
+
--svelte-ui-input-unit-font-size: max(0.5em, var(--svelte-ui-font-size-sm));
|
|
380
380
|
--svelte-ui-input-placeholder-color: var(--svelte-ui-text-placeholder-color);
|
|
381
381
|
--svelte-ui-input-icon-color: var(--svelte-ui-text-subtle-color);
|
|
382
382
|
|
|
@@ -387,7 +387,6 @@
|
|
|
387
387
|
--svelte-ui-textarea-border-radius-rounded: calc(var(--svelte-ui-textarea-min-height) / 2);
|
|
388
388
|
--svelte-ui-textarea-bg: var(--svelte-ui-form-bg);
|
|
389
389
|
--svelte-ui-textarea-border-color: var(--svelte-ui-border-weak-color);
|
|
390
|
-
--svelte-ui-textarea-text-color: var(--svelte-ui-text-color);
|
|
391
390
|
--svelte-ui-textarea-placeholder-color: var(--svelte-ui-text-placeholder-color);
|
|
392
391
|
--svelte-ui-textarea-icon-space: calc(
|
|
393
392
|
var(--svelte-ui-form-icon-space) + var(--svelte-ui-form-icon-offset)
|
|
@@ -409,7 +408,6 @@
|
|
|
409
408
|
--svelte-ui-select-border-radius-rounded: var(--svelte-ui-form-border-radius-rounded);
|
|
410
409
|
--svelte-ui-select-bg: var(--svelte-ui-form-bg);
|
|
411
410
|
--svelte-ui-select-border-color: var(--svelte-ui-border-weak-color);
|
|
412
|
-
--svelte-ui-select-text-color: var(--svelte-ui-text-color);
|
|
413
411
|
--svelte-ui-select-dropdown-icon-color: var(--svelte-ui-dropdown-icon-color);
|
|
414
412
|
--svelte-ui-select-placeholder-color: var(--svelte-ui-text-placeholder-color);
|
|
415
413
|
|
|
@@ -510,7 +508,6 @@
|
|
|
510
508
|
--svelte-ui-colorpicker-border-color: var(--svelte-ui-border-weak-color);
|
|
511
509
|
--svelte-ui-colorpicker-trigger-border-color: var(--svelte-ui-border-color);
|
|
512
510
|
--svelte-ui-colorpicker-bg: var(--svelte-ui-form-bg);
|
|
513
|
-
--svelte-ui-colorpicker-text-color: var(--svelte-ui-text-color);
|
|
514
511
|
--svelte-ui-colorpicker-placeholder-color: var(--svelte-ui-text-placeholder-color);
|
|
515
512
|
|
|
516
513
|
/* Combobox */
|
|
@@ -524,7 +521,6 @@
|
|
|
524
521
|
--svelte-ui-combobox-border-radius-rounded: var(--svelte-ui-form-border-radius-rounded);
|
|
525
522
|
--svelte-ui-combobox-border-color: var(--svelte-ui-border-weak-color);
|
|
526
523
|
--svelte-ui-combobox-bg: var(--svelte-ui-surface-color);
|
|
527
|
-
--svelte-ui-combobox-text-color: var(--svelte-ui-text-color);
|
|
528
524
|
--svelte-ui-combobox-dropdown-icon-color: var(--svelte-ui-dropdown-icon-color);
|
|
529
525
|
--svelte-ui-combobox-option-hover-bg: var(--svelte-ui-hover-overlay);
|
|
530
526
|
--svelte-ui-combobox-option-selected-bg: var(--svelte-ui-select-overlay);
|
|
@@ -610,8 +606,8 @@
|
|
|
610
606
|
/* Drawer */
|
|
611
607
|
--svelte-ui-drawer-gap: 16px;
|
|
612
608
|
--svelte-ui-drawer-gap-sm: 8px;
|
|
613
|
-
--svelte-ui-drawer-padding: 16px 24px;
|
|
614
|
-
--svelte-ui-drawer-body-padding:
|
|
609
|
+
--svelte-ui-drawer-header-padding: 16px 24px;
|
|
610
|
+
--svelte-ui-drawer-body-padding: 0;
|
|
615
611
|
--svelte-ui-drawer-header-height: 56px;
|
|
616
612
|
--svelte-ui-drawer-title-font-size: 1.4rem;
|
|
617
613
|
--svelte-ui-drawer-description-font-size: 0.875rem;
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
MouseHandler,
|
|
11
11
|
TouchHandler,
|
|
12
12
|
PointerHandler
|
|
13
|
-
} from '../types/
|
|
13
|
+
} from '../types/callbackHandlers';
|
|
14
|
+
import type { ButtonVariant, ButtonSize } from '../types/propOptions';
|
|
14
15
|
import Icon from './Icon.svelte';
|
|
15
16
|
import LoadingSpinner from './LoadingSpinner.svelte';
|
|
16
17
|
import { getStyleFromNumber } from '../utils/style';
|
|
@@ -29,10 +30,11 @@
|
|
|
29
30
|
|
|
30
31
|
// スタイル/レイアウト
|
|
31
32
|
customStyle?: HTMLButtonAttributes['style'];
|
|
32
|
-
variant?:
|
|
33
|
-
size?:
|
|
33
|
+
variant?: ButtonVariant;
|
|
34
|
+
size?: ButtonSize;
|
|
34
35
|
color?: string;
|
|
35
36
|
fullWidth?: boolean;
|
|
37
|
+
align?: 'left' | 'center' | 'right';
|
|
36
38
|
minWidth?: string | number;
|
|
37
39
|
rounded?: boolean;
|
|
38
40
|
popup?: boolean;
|
|
@@ -107,6 +109,7 @@
|
|
|
107
109
|
size = 'medium',
|
|
108
110
|
color,
|
|
109
111
|
fullWidth = false,
|
|
112
|
+
align = 'center',
|
|
110
113
|
minWidth = 0,
|
|
111
114
|
rounded = false,
|
|
112
115
|
popup = false,
|
|
@@ -310,6 +313,7 @@
|
|
|
310
313
|
popup && 'button--popup',
|
|
311
314
|
rounded && 'button--rounded',
|
|
312
315
|
fullWidth && 'button--full-width',
|
|
316
|
+
`button--align-${align}`,
|
|
313
317
|
loading && 'button--loading',
|
|
314
318
|
reducedMotion && 'button--no-motion'
|
|
315
319
|
]
|
|
@@ -453,6 +457,14 @@
|
|
|
453
457
|
width: 100%;
|
|
454
458
|
}
|
|
455
459
|
|
|
460
|
+
.button--align-left {
|
|
461
|
+
justify-content: flex-start;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.button--align-right {
|
|
465
|
+
justify-content: flex-end;
|
|
466
|
+
}
|
|
467
|
+
|
|
456
468
|
.button--rounded {
|
|
457
469
|
border-radius: var(--svelte-ui-button-border-radius-rounded);
|
|
458
470
|
}
|
|
@@ -510,9 +522,8 @@
|
|
|
510
522
|
}
|
|
511
523
|
|
|
512
524
|
.button__label {
|
|
513
|
-
width: 100%;
|
|
514
525
|
display: block;
|
|
515
|
-
|
|
526
|
+
width: auto;
|
|
516
527
|
line-height: var(--svelte-ui-button-line-height);
|
|
517
528
|
text-box-trim: trim-both;
|
|
518
529
|
text-box-edge: cap alphabetic;
|
|
@@ -531,6 +542,11 @@
|
|
|
531
542
|
justify-content: center;
|
|
532
543
|
}
|
|
533
544
|
|
|
545
|
+
.button--align-left .button__popup-icon {
|
|
546
|
+
margin-left: auto;
|
|
547
|
+
margin-right: -4px;
|
|
548
|
+
}
|
|
549
|
+
|
|
534
550
|
.button__loading {
|
|
535
551
|
position: absolute;
|
|
536
552
|
top: 50%;
|
|
@@ -550,6 +566,11 @@
|
|
|
550
566
|
margin-right: -2px;
|
|
551
567
|
}
|
|
552
568
|
|
|
569
|
+
.button--align-left.button--small .button__popup-icon {
|
|
570
|
+
margin-left: auto;
|
|
571
|
+
margin-right: -2px;
|
|
572
|
+
}
|
|
573
|
+
|
|
553
574
|
.button--large .button__icon {
|
|
554
575
|
margin-left: -6px;
|
|
555
576
|
}
|
|
@@ -558,6 +579,11 @@
|
|
|
558
579
|
margin-right: -6px;
|
|
559
580
|
}
|
|
560
581
|
|
|
582
|
+
.button--align-left.button--large .button__popup-icon {
|
|
583
|
+
margin-left: auto;
|
|
584
|
+
margin-right: -6px;
|
|
585
|
+
}
|
|
586
|
+
|
|
561
587
|
/* Reduced motion */
|
|
562
588
|
.button--no-motion,
|
|
563
589
|
.button--no-motion:before,
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
4
|
-
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/
|
|
4
|
+
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
|
|
5
|
+
import type { ButtonVariant, ButtonSize } from '../types/propOptions';
|
|
5
6
|
export type ButtonProps = {
|
|
6
7
|
children: Snippet;
|
|
7
8
|
buttonAttributes?: HTMLButtonAttributes | undefined;
|
|
8
9
|
type?: HTMLButtonAttributes['type'];
|
|
9
10
|
tabindex?: number | null;
|
|
10
11
|
customStyle?: HTMLButtonAttributes['style'];
|
|
11
|
-
variant?:
|
|
12
|
-
size?:
|
|
12
|
+
variant?: ButtonVariant;
|
|
13
|
+
size?: ButtonSize;
|
|
13
14
|
color?: string;
|
|
14
15
|
fullWidth?: boolean;
|
|
16
|
+
align?: 'left' | 'center' | 'right';
|
|
15
17
|
minWidth?: string | number;
|
|
16
18
|
rounded?: boolean;
|
|
17
19
|
popup?: boolean;
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
KeyboardHandler,
|
|
9
9
|
MouseHandler,
|
|
10
10
|
TouchHandler,
|
|
11
|
-
PointerHandler
|
|
12
|
-
|
|
13
|
-
} from '../types/eventHandlers';
|
|
11
|
+
PointerHandler
|
|
12
|
+
} from '../types/callbackHandlers';
|
|
14
13
|
|
|
15
14
|
// =========================================================================
|
|
16
15
|
// Props, States & Constants
|
|
@@ -340,10 +339,11 @@
|
|
|
340
339
|
* ========================================================================= */
|
|
341
340
|
|
|
342
341
|
.checkbox {
|
|
343
|
-
display: flex;
|
|
342
|
+
display: inline-flex;
|
|
344
343
|
align-items: center;
|
|
345
344
|
width: fit-content;
|
|
346
345
|
min-height: var(--svelte-ui-checkbox-min-height);
|
|
346
|
+
vertical-align: top;
|
|
347
347
|
contain: layout;
|
|
348
348
|
}
|
|
349
349
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/
|
|
3
|
+
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
|
|
4
4
|
export type CheckboxProps = {
|
|
5
5
|
children?: Snippet;
|
|
6
6
|
name?: string;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import Checkbox from './Checkbox.svelte';
|
|
6
6
|
import { onMount } from 'svelte';
|
|
7
7
|
import { getStyleFromNumber } from '../utils/style';
|
|
8
|
-
import type { BivariantValueHandler } from '../types/
|
|
8
|
+
import type { BivariantValueHandler } from '../types/callbackHandlers';
|
|
9
9
|
|
|
10
10
|
// =========================================================================
|
|
11
11
|
// Props, States & Constants
|
|
@@ -78,8 +78,11 @@
|
|
|
78
78
|
onchange(value);
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
// =========================================================================
|
|
82
|
+
// $defived
|
|
83
|
+
// =========================================================================
|
|
84
|
+
const gapStyle = $derived(gap !== undefined ? getStyleFromNumber(gap) : undefined);
|
|
85
|
+
const minOptionWidthStyle = $derived(getStyleFromNumber(minOptionWidth));
|
|
83
86
|
</script>
|
|
84
87
|
|
|
85
88
|
<ul
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Option, OptionValue } from '../types/options';
|
|
2
|
-
import type { BivariantValueHandler } from '../types/
|
|
2
|
+
import type { BivariantValueHandler } from '../types/callbackHandlers';
|
|
3
3
|
export type CheckboxGroupProps = {
|
|
4
4
|
options: Option[];
|
|
5
5
|
value: OptionValue[];
|
|
@@ -11,16 +11,15 @@
|
|
|
11
11
|
KeyboardHandler,
|
|
12
12
|
MouseHandler,
|
|
13
13
|
TouchHandler,
|
|
14
|
-
PointerHandler
|
|
15
|
-
|
|
16
|
-
} from '../types/eventHandlers';
|
|
14
|
+
PointerHandler
|
|
15
|
+
} from '../types/callbackHandlers';
|
|
17
16
|
|
|
18
17
|
// =========================================================================
|
|
19
18
|
// Props, States & Constants
|
|
20
19
|
// =========================================================================
|
|
21
20
|
export type ColorPickerProps = {
|
|
22
21
|
// 基本プロパティ
|
|
23
|
-
value: string;
|
|
22
|
+
value: string | null | undefined;
|
|
24
23
|
|
|
25
24
|
// HTML属性系
|
|
26
25
|
id?: string;
|
|
@@ -40,8 +39,8 @@
|
|
|
40
39
|
iconVariant?: IconVariant;
|
|
41
40
|
|
|
42
41
|
// 入力イベント
|
|
43
|
-
onchange?:
|
|
44
|
-
oninput?:
|
|
42
|
+
onchange?: (value: string) => void;
|
|
43
|
+
oninput?: (value: string) => void;
|
|
45
44
|
|
|
46
45
|
// フォーカスイベント
|
|
47
46
|
onfocus?: FocusHandler;
|
|
@@ -142,7 +141,12 @@
|
|
|
142
141
|
...restProps
|
|
143
142
|
}: ColorPickerProps = $props();
|
|
144
143
|
|
|
145
|
-
|
|
144
|
+
const getNormalizedValue = (val: string | null | undefined): string => {
|
|
145
|
+
if (val === null || val === undefined) return '';
|
|
146
|
+
return val;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
let localValue: string = $state(getNormalizedValue(value));
|
|
146
150
|
let prevValue: string = $state('');
|
|
147
151
|
let isFocused: boolean = $state(false);
|
|
148
152
|
|
|
@@ -155,7 +159,7 @@
|
|
|
155
159
|
value;
|
|
156
160
|
untrack(() => {
|
|
157
161
|
/* value を localValue に反映 */
|
|
158
|
-
localValue = value;
|
|
162
|
+
localValue = getNormalizedValue(value);
|
|
159
163
|
|
|
160
164
|
/* value が更新されたらonchangeを実行 */
|
|
161
165
|
handleValueChange();
|
|
@@ -166,7 +170,7 @@
|
|
|
166
170
|
localValue;
|
|
167
171
|
untrack(() => {
|
|
168
172
|
/* localValue がクリアされた時に value もクリア */
|
|
169
|
-
if (localValue === ''
|
|
173
|
+
if (localValue === '') {
|
|
170
174
|
value = '';
|
|
171
175
|
prevValue = '';
|
|
172
176
|
}
|
|
@@ -393,7 +397,10 @@
|
|
|
393
397
|
{...inputAttributes}
|
|
394
398
|
{...restProps}
|
|
395
399
|
/>
|
|
396
|
-
<div
|
|
400
|
+
<div
|
|
401
|
+
class="color-picker__color-display"
|
|
402
|
+
style="background-color: {getNormalizedValue(value)};"
|
|
403
|
+
></div>
|
|
397
404
|
</div>
|
|
398
405
|
</div>
|
|
399
406
|
|
|
@@ -408,6 +415,7 @@
|
|
|
408
415
|
position: relative;
|
|
409
416
|
width: auto;
|
|
410
417
|
max-width: 100%;
|
|
418
|
+
vertical-align: top;
|
|
411
419
|
}
|
|
412
420
|
|
|
413
421
|
/* =============================================
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
2
|
import type { IconVariant } from '../types/icon';
|
|
3
|
-
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler
|
|
3
|
+
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
|
|
4
4
|
export type ColorPickerProps = {
|
|
5
|
-
value: string;
|
|
5
|
+
value: string | null | undefined;
|
|
6
6
|
id?: string;
|
|
7
7
|
inputAttributes?: HTMLInputAttributes | undefined;
|
|
8
8
|
customStyle?: string;
|
|
@@ -14,8 +14,8 @@ export type ColorPickerProps = {
|
|
|
14
14
|
clearable?: boolean;
|
|
15
15
|
clearButtonAriaLabel?: string;
|
|
16
16
|
iconVariant?: IconVariant;
|
|
17
|
-
onchange?:
|
|
18
|
-
oninput?:
|
|
17
|
+
onchange?: (value: string) => void;
|
|
18
|
+
oninput?: (value: string) => void;
|
|
19
19
|
onfocus?: FocusHandler;
|
|
20
20
|
onblur?: FocusHandler;
|
|
21
21
|
onkeydown?: KeyboardHandler;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
TouchHandler,
|
|
14
14
|
PointerHandler,
|
|
15
15
|
BivariantValueHandler
|
|
16
|
-
} from '../types/
|
|
16
|
+
} from '../types/callbackHandlers';
|
|
17
17
|
|
|
18
18
|
// =========================================================================
|
|
19
19
|
// Props, States & Constants
|
|
@@ -165,10 +165,7 @@
|
|
|
165
165
|
let popupRef = $state<any>();
|
|
166
166
|
let highlightedIndex = $state(-1);
|
|
167
167
|
let isFocused = $state(false);
|
|
168
|
-
|
|
169
|
-
// 各要素のIDを生成
|
|
170
|
-
const inputId = `${id}-input`;
|
|
171
|
-
const listboxId = `${id}-listbox`;
|
|
168
|
+
let isKeyboardNavigation = $state(false);
|
|
172
169
|
|
|
173
170
|
// =========================================================================
|
|
174
171
|
// Methods
|
|
@@ -180,6 +177,7 @@
|
|
|
180
177
|
popupRef?.close();
|
|
181
178
|
highlightedIndex = -1;
|
|
182
179
|
isFocused = false;
|
|
180
|
+
isKeyboardNavigation = false;
|
|
183
181
|
|
|
184
182
|
// スクリーンリーダーアナウンス
|
|
185
183
|
if (option !== null && option !== undefined) {
|
|
@@ -239,6 +237,7 @@
|
|
|
239
237
|
switch (event.key) {
|
|
240
238
|
case 'ArrowDown':
|
|
241
239
|
event?.preventDefault?.();
|
|
240
|
+
isKeyboardNavigation = true;
|
|
242
241
|
if (!isFocused) {
|
|
243
242
|
isFocused = true;
|
|
244
243
|
popupRef?.open();
|
|
@@ -247,6 +246,7 @@
|
|
|
247
246
|
break;
|
|
248
247
|
case 'ArrowUp':
|
|
249
248
|
event?.preventDefault?.();
|
|
249
|
+
isKeyboardNavigation = true;
|
|
250
250
|
if (!isFocused) {
|
|
251
251
|
isFocused = true;
|
|
252
252
|
popupRef?.open();
|
|
@@ -263,6 +263,7 @@
|
|
|
263
263
|
event?.preventDefault?.();
|
|
264
264
|
inputValue = '';
|
|
265
265
|
highlightedIndex = -1;
|
|
266
|
+
isKeyboardNavigation = false;
|
|
266
267
|
popupRef?.close();
|
|
267
268
|
isFocused = false;
|
|
268
269
|
break;
|
|
@@ -387,6 +388,9 @@
|
|
|
387
388
|
// =========================================================================
|
|
388
389
|
// $derived
|
|
389
390
|
// =========================================================================
|
|
391
|
+
// 各要素のIDを生成
|
|
392
|
+
const inputId = $derived(`${id}-input`);
|
|
393
|
+
const listboxId = $derived(`${id}-listbox`);
|
|
390
394
|
|
|
391
395
|
// フィルタリングされたオプション
|
|
392
396
|
const filteredOptions = $derived.by(() => {
|
|
@@ -463,7 +467,7 @@
|
|
|
463
467
|
bind:this={popupRef}
|
|
464
468
|
anchorElement={comboboxElement}
|
|
465
469
|
position="bottom-left"
|
|
466
|
-
|
|
470
|
+
mobileFullscreen={false}
|
|
467
471
|
onClose={handlePopupClose}
|
|
468
472
|
margin={4}
|
|
469
473
|
>
|
|
@@ -481,6 +485,7 @@
|
|
|
481
485
|
type="button"
|
|
482
486
|
class="combobox__option"
|
|
483
487
|
class:combobox__option--highlighted={index === highlightedIndex}
|
|
488
|
+
class:combobox__option--keyboard={isKeyboardNavigation && index === highlightedIndex}
|
|
484
489
|
class:combobox__option--selected={option === inputValue}
|
|
485
490
|
role="option"
|
|
486
491
|
aria-selected={option === inputValue}
|
|
@@ -489,7 +494,10 @@
|
|
|
489
494
|
event?.stopPropagation?.();
|
|
490
495
|
selectOption(option);
|
|
491
496
|
}}
|
|
492
|
-
onmouseenter={() =>
|
|
497
|
+
onmouseenter={() => {
|
|
498
|
+
highlightedIndex = index;
|
|
499
|
+
isKeyboardNavigation = false; // マウス操作時はキーボード操作フラグをリセット
|
|
500
|
+
}}
|
|
493
501
|
>
|
|
494
502
|
{option}
|
|
495
503
|
</button>
|
|
@@ -510,6 +518,7 @@
|
|
|
510
518
|
position: relative;
|
|
511
519
|
width: auto;
|
|
512
520
|
max-width: 100%;
|
|
521
|
+
vertical-align: top;
|
|
513
522
|
}
|
|
514
523
|
|
|
515
524
|
.combobox--full-width {
|
|
@@ -539,7 +548,7 @@
|
|
|
539
548
|
text-align: left;
|
|
540
549
|
cursor: pointer;
|
|
541
550
|
font-size: inherit;
|
|
542
|
-
color: var(--svelte-ui-
|
|
551
|
+
color: var(--svelte-ui-text-color);
|
|
543
552
|
transition: background-color var(--svelte-ui-transition-duration) ease;
|
|
544
553
|
|
|
545
554
|
@media (hover: hover) {
|
|
@@ -553,6 +562,12 @@
|
|
|
553
562
|
background-color: var(--svelte-ui-combobox-option-hover-bg);
|
|
554
563
|
}
|
|
555
564
|
|
|
565
|
+
/* キーボード操作時のみ枠線を表示 */
|
|
566
|
+
&.combobox__option--keyboard {
|
|
567
|
+
outline: var(--svelte-ui-focus-outline-inner);
|
|
568
|
+
outline-offset: var(--svelte-ui-focus-outline-offset-inner);
|
|
569
|
+
}
|
|
570
|
+
|
|
556
571
|
&.combobox__option--selected {
|
|
557
572
|
background-color: var(--svelte-ui-combobox-option-selected-bg);
|
|
558
573
|
}
|
|
@@ -561,6 +576,11 @@
|
|
|
561
576
|
background-color: var(--svelte-ui-combobox-option-selected-bg);
|
|
562
577
|
}
|
|
563
578
|
|
|
579
|
+
&.combobox__option--selected.combobox__option--keyboard {
|
|
580
|
+
outline: var(--svelte-ui-focus-outline-inner);
|
|
581
|
+
outline-offset: var(--svelte-ui-focus-outline-offset-inner);
|
|
582
|
+
}
|
|
583
|
+
|
|
564
584
|
&:focus,
|
|
565
585
|
&:focus-visible {
|
|
566
586
|
outline: var(--svelte-ui-focus-outline-inner);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler, BivariantValueHandler } from '../types/
|
|
2
|
+
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler, BivariantValueHandler } from '../types/callbackHandlers';
|
|
3
3
|
export type ComboboxProps = {
|
|
4
4
|
name?: string;
|
|
5
5
|
value: string | number | null | undefined;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
id?: string;
|
|
21
21
|
|
|
22
22
|
// スタイル/レイアウト
|
|
23
|
-
|
|
23
|
+
danger?: boolean;
|
|
24
24
|
width?: string | number;
|
|
25
25
|
|
|
26
26
|
// 状態/動作
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
id,
|
|
44
44
|
|
|
45
45
|
// スタイル/レイアウト
|
|
46
|
-
|
|
46
|
+
danger = false,
|
|
47
47
|
width = 400,
|
|
48
48
|
|
|
49
49
|
// 状態/動作
|
|
@@ -101,11 +101,7 @@
|
|
|
101
101
|
</Button>
|
|
102
102
|
<Button
|
|
103
103
|
variant="filled"
|
|
104
|
-
color={
|
|
105
|
-
? 'var(--svelte-ui-danger-color)'
|
|
106
|
-
: variant === 'warning'
|
|
107
|
-
? 'var(--svelte-ui-warning-color)'
|
|
108
|
-
: undefined}
|
|
104
|
+
color={danger ? 'var(--svelte-ui-danger-color)' : undefined}
|
|
109
105
|
onclick={handleSubmit}
|
|
110
106
|
>
|
|
111
107
|
{submitLabel}
|