@14ch/svelte-ui 0.0.42 → 0.0.44

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.
Files changed (52) hide show
  1. package/dist/assets/styles/import.css +900 -0
  2. package/dist/assets/styles/variables.scss +5 -0
  3. package/dist/components/Checkbox.svelte +12 -8
  4. package/dist/components/Checkbox.svelte.d.ts +8 -5
  5. package/dist/components/CheckboxGroup.svelte +5 -6
  6. package/dist/components/CheckboxGroup.svelte.d.ts +2 -1
  7. package/dist/components/ColorPicker.svelte +4 -3
  8. package/dist/components/ColorPicker.svelte.d.ts +3 -3
  9. package/dist/components/Combobox.svelte +4 -3
  10. package/dist/components/Datepicker.svelte +2 -1
  11. package/dist/components/Dialog.svelte +1 -1
  12. package/dist/components/Drawer.svelte +1 -1
  13. package/dist/components/FileUploader.svelte +2 -8
  14. package/dist/components/ImageUploader.svelte +2 -8
  15. package/dist/components/ImageUploaderPreview.svelte +1 -0
  16. package/dist/components/Input.svelte +8 -2
  17. package/dist/components/Input.svelte.d.ts +2 -0
  18. package/dist/components/LoadingSpinner.svelte +3 -3
  19. package/dist/components/Modal.svelte +7 -7
  20. package/dist/components/Modal.svelte.d.ts +1 -1
  21. package/dist/components/MultiSelect.svelte +2 -2
  22. package/dist/components/Nav.svelte +15 -0
  23. package/dist/components/Nav.svelte.d.ts +6 -0
  24. package/dist/components/NavItem.svelte +22 -4
  25. package/dist/components/NavItem.svelte.d.ts +6 -0
  26. package/dist/components/Pagination.svelte +3 -2
  27. package/dist/components/Pagination.svelte.d.ts +2 -1
  28. package/dist/components/Popup.svelte +1 -0
  29. package/dist/components/PopupMenu.svelte +1 -0
  30. package/dist/components/PopupMenuButton.svelte +6 -6
  31. package/dist/components/PopupMenuButton.svelte.d.ts +1 -1
  32. package/dist/components/Radio.svelte +9 -4
  33. package/dist/components/Radio.svelte.d.ts +6 -3
  34. package/dist/components/RadioGroup.svelte +5 -6
  35. package/dist/components/RadioGroup.svelte.d.ts +2 -1
  36. package/dist/components/SegmentedControl.svelte +5 -3
  37. package/dist/components/SegmentedControl.svelte.d.ts +4 -3
  38. package/dist/components/Select.svelte +0 -1
  39. package/dist/components/Slider.svelte +4 -3
  40. package/dist/components/Slider.svelte.d.ts +3 -3
  41. package/dist/components/SnackbarItem.svelte +3 -3
  42. package/dist/components/Switch.svelte +12 -6
  43. package/dist/components/Switch.svelte.d.ts +7 -4
  44. package/dist/components/Tab.svelte +4 -7
  45. package/dist/components/Textarea.svelte +12 -3
  46. package/dist/components/Textarea.svelte.d.ts +5 -3
  47. package/dist/components/skeleton/Skeleton.svelte +1 -9
  48. package/dist/components/skeleton/SkeletonBox.svelte +5 -15
  49. package/dist/index.d.ts +4 -1
  50. package/dist/index.js +3 -0
  51. package/dist/types/propOptions.d.ts +7 -2
  52. package/package.json +3 -3
@@ -127,6 +127,7 @@
127
127
  /* State Colors */
128
128
  --svelte-ui-success-color: #12b073;
129
129
  --svelte-ui-error-color: #f54d4d;
130
+ --svelte-ui-error-container-color: transparent;
130
131
  --svelte-ui-danger-color: #f54d4d;
131
132
  --svelte-ui-warning-color: #f57c00;
132
133
  --svelte-ui-info-color: #13a3b4;
@@ -277,6 +278,7 @@
277
278
  --svelte-ui-form-height-lg: 44px;
278
279
  --svelte-ui-form-padding: 0 12px;
279
280
  --svelte-ui-form-padding-left: 12px;
281
+ --svelte-ui-form-padding-inline: 12px;
280
282
  --svelte-ui-form-icon-offset: 4px;
281
283
  --svelte-ui-form-icon-space: 32px;
282
284
  --svelte-ui-form-icon-space-inline: 32px;
@@ -528,9 +530,11 @@
528
530
 
529
531
  /* CheckboxGroup */
530
532
  --svelte-ui-checkbox-group-gap: 8px 24px;
533
+ --svelte-ui-checkbox-group-min-option-width: auto;
531
534
 
532
535
  /* RadioGroup */
533
536
  --svelte-ui-radio-group-gap: 8px 24px;
537
+ --svelte-ui-radio-group-min-option-width: auto;
534
538
  --svelte-ui-radio-disabled-opacity: var(--svelte-ui-disabled-opacity);
535
539
  --svelte-ui-radio-border-color: var(--svelte-ui-border-color);
536
540
  --svelte-ui-radio-bg-checked: var(--svelte-ui-radio-checked-color);
@@ -581,6 +585,7 @@
581
585
  /* FileUploader */
582
586
  --svelte-ui-file-uploader-border-width: 1px;
583
587
  --svelte-ui-file-uploader-border-style: dashed;
588
+ --svelte-ui-file-uploader-height: auto;
584
589
  --svelte-ui-file-uploader-bg: var(--svelte-ui-form-bg);
585
590
  --svelte-ui-file-uploader-border-color: var(--svelte-ui-border-color);
586
591
  --svelte-ui-file-uploader-hover-bg: var(--svelte-ui-hover-overlay);
@@ -7,8 +7,10 @@
7
7
  KeyboardHandler,
8
8
  MouseHandler,
9
9
  TouchHandler,
10
- PointerHandler
10
+ PointerHandler,
11
+ BivariantValueHandler
11
12
  } from '../types/callbackHandlers';
13
+ import type { ComponentSize } from '../types/propOptions';
12
14
 
13
15
  // =========================================================================
14
16
  // Props, States & Constants
@@ -31,17 +33,19 @@
31
33
 
32
34
  // スタイル/レイアウト
33
35
  /** Checkbox size. @default 'medium' */
34
- size?: 'small' | 'medium' | 'large';
36
+ size?: ComponentSize;
35
37
  customStyle?: string;
38
+ /** Stretches the checkbox to fill its container width. @default false */
39
+ fullWidth?: boolean;
36
40
 
37
41
  // 状態/動作
38
42
  /** Disables the checkbox. @default false */
39
43
  disabled?: boolean;
40
- /** Stretches the checkbox to fill its container width. @default false */
41
- fullWidth?: boolean;
42
44
  required?: boolean;
43
45
 
44
46
  // ARIA/アクセシビリティ
47
+ /** Accessible label, used when no visible label (children) is provided. */
48
+ ariaLabel?: string;
45
49
  /** Disables animations for users who prefer reduced motion. @default false */
46
50
  reducedMotion?: boolean;
47
51
 
@@ -79,7 +83,7 @@
79
83
  onpointercancel?: PointerHandler;
80
84
 
81
85
  // 入力イベント
82
- onchange?: (value: boolean) => void;
86
+ onchange?: BivariantValueHandler<boolean>;
83
87
 
84
88
  // その他
85
89
  [key: string]: any;
@@ -100,13 +104,14 @@
100
104
  // スタイル/レイアウト
101
105
  size = 'medium',
102
106
  customStyle = '',
107
+ fullWidth = false,
103
108
 
104
109
  // 状態/動作
105
110
  disabled = false,
106
- fullWidth = false,
107
111
  required = false,
108
112
 
109
113
  // ARIA/アクセシビリティ
114
+ ariaLabel,
110
115
  reducedMotion = false,
111
116
 
112
117
  // フォーカスイベント
@@ -304,6 +309,7 @@
304
309
  {name}
305
310
  {disabled}
306
311
  {required}
312
+ aria-label={ariaLabel}
307
313
  aria-invalid={false}
308
314
  aria-required={required ? 'true' : 'false'}
309
315
  aria-describedby={undefined}
@@ -444,7 +450,6 @@
444
450
 
445
451
  /* Checked state */
446
452
  input[type='checkbox']:checked + .checkbox__icon::after {
447
- width: var(--svelte-ui-checkbox-icon-width);
448
453
  clip-path: inset(0 0 0 0);
449
454
  opacity: 1;
450
455
  transition-delay:
@@ -454,7 +459,6 @@
454
459
  /* Indeterminate state */
455
460
  input[type='checkbox']:indeterminate + .checkbox__icon::after {
456
461
  content: 'remove';
457
- width: var(--svelte-ui-checkbox-icon-width);
458
462
  clip-path: inset(0 0 0 0);
459
463
  opacity: 1;
460
464
  transition-delay:
@@ -1,5 +1,6 @@
1
1
  import { type Snippet } from 'svelte';
2
- import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
2
+ import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler, BivariantValueHandler } from '../types/callbackHandlers';
3
+ import type { ComponentSize } from '../types/propOptions';
3
4
  export type CheckboxProps = {
4
5
  /** Label content displayed next to the checkbox. */
5
6
  children?: Snippet;
@@ -11,13 +12,15 @@ export type CheckboxProps = {
11
12
  indeterminate?: boolean;
12
13
  id?: string;
13
14
  /** Checkbox size. @default 'medium' */
14
- size?: 'small' | 'medium' | 'large';
15
+ size?: ComponentSize;
15
16
  customStyle?: string;
16
- /** Disables the checkbox. @default false */
17
- disabled?: boolean;
18
17
  /** Stretches the checkbox to fill its container width. @default false */
19
18
  fullWidth?: boolean;
19
+ /** Disables the checkbox. @default false */
20
+ disabled?: boolean;
20
21
  required?: boolean;
22
+ /** Accessible label, used when no visible label (children) is provided. */
23
+ ariaLabel?: string;
21
24
  /** Disables animations for users who prefer reduced motion. @default false */
22
25
  reducedMotion?: boolean;
23
26
  onfocus?: FocusHandler;
@@ -43,7 +46,7 @@ export type CheckboxProps = {
43
46
  onpointerleave?: PointerHandler;
44
47
  onpointermove?: PointerHandler;
45
48
  onpointercancel?: PointerHandler;
46
- onchange?: (value: boolean) => void;
49
+ onchange?: BivariantValueHandler<boolean>;
47
50
  [key: string]: any;
48
51
  };
49
52
  declare const Checkbox: import("svelte").Component<CheckboxProps, {}, "value" | "indeterminate">;
@@ -5,6 +5,7 @@
5
5
  import Checkbox from './Checkbox.svelte';
6
6
  import { getStyleFromNumber } from '../utils/style';
7
7
  import type { BivariantValueHandler } from '../types/callbackHandlers';
8
+ import type { ComponentSize } from '../types/propOptions';
8
9
 
9
10
  // =========================================================================
10
11
  // Props, States & Constants
@@ -24,7 +25,7 @@
24
25
  wrap?: boolean;
25
26
  minOptionWidth?: string | number;
26
27
  /** @default 'medium' */
27
- size?: 'small' | 'medium' | 'large';
28
+ size?: ComponentSize;
28
29
 
29
30
  // 状態/動作
30
31
  disabled?: boolean;
@@ -84,6 +85,7 @@
84
85
  style:--internal-checkbox-group-gap={gapStyle}
85
86
  style:--internal-checkbox-group-wrap={wrap ? 'wrap' : 'none'}
86
87
  style:--internal-checkbox-group-min-option-width={minOptionWidthStyle}
88
+ data-testid="checkbox-group"
87
89
  >
88
90
  {#each options as option (option.value)}
89
91
  <li class="checkbox-group__option">
@@ -104,12 +106,9 @@
104
106
  <style>
105
107
  .checkbox-group {
106
108
  display: flex;
107
- flex-direction: var(
108
- --internal-checkbox-group-flex-direction,
109
- var(--svelte-ui-checkbox-group-flex-direction)
110
- );
109
+ flex-direction: var(--internal-checkbox-group-flex-direction);
111
110
  gap: var(--internal-checkbox-group-gap, var(--svelte-ui-checkbox-group-gap));
112
- flex-wrap: var(--internal-checkbox-group-wrap, var(--svelte-ui-checkbox-group-wrap));
111
+ flex-wrap: var(--internal-checkbox-group-wrap);
113
112
  }
114
113
 
115
114
  .checkbox-group__option {
@@ -1,5 +1,6 @@
1
1
  import type { Option, OptionValue } from '../types/options';
2
2
  import type { BivariantValueHandler } from '../types/callbackHandlers';
3
+ import type { ComponentSize } from '../types/propOptions';
3
4
  export type CheckboxGroupProps = {
4
5
  /** `{ label, value, disabled? }[]` */
5
6
  options: Option[];
@@ -11,7 +12,7 @@ export type CheckboxGroupProps = {
11
12
  wrap?: boolean;
12
13
  minOptionWidth?: string | number;
13
14
  /** @default 'medium' */
14
- size?: 'small' | 'medium' | 'large';
15
+ size?: ComponentSize;
15
16
  disabled?: boolean;
16
17
  required?: boolean;
17
18
  /** Disables animations for accessibility. @default false */
@@ -10,7 +10,8 @@
10
10
  KeyboardHandler,
11
11
  MouseHandler,
12
12
  TouchHandler,
13
- PointerHandler
13
+ PointerHandler,
14
+ BivariantValueHandler
14
15
  } from '../types/callbackHandlers';
15
16
 
16
17
  // =========================================================================
@@ -43,8 +44,8 @@
43
44
  iconVariant?: IconVariant;
44
45
 
45
46
  // 入力イベント
46
- onchange?: (value: string) => void;
47
- oninput?: (value: string) => void;
47
+ onchange?: BivariantValueHandler<string>;
48
+ oninput?: BivariantValueHandler<string>;
48
49
 
49
50
  // フォーカスイベント
50
51
  onfocus?: FocusHandler;
@@ -1,5 +1,5 @@
1
1
  import type { IconVariant } from '../types/icon';
2
- import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
2
+ import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler, BivariantValueHandler } from '../types/callbackHandlers';
3
3
  export type ColorPickerProps = {
4
4
  /** Hex color string (e.g. `"#ff0000"`). Supports `bind:value`. */
5
5
  value: string | null | undefined;
@@ -19,8 +19,8 @@ export type ColorPickerProps = {
19
19
  clearable?: boolean;
20
20
  clearButtonAriaLabel?: string;
21
21
  iconVariant?: IconVariant;
22
- onchange?: (value: string) => void;
23
- oninput?: (value: string) => void;
22
+ onchange?: BivariantValueHandler<string>;
23
+ oninput?: BivariantValueHandler<string>;
24
24
  onfocus?: FocusHandler;
25
25
  onblur?: FocusHandler;
26
26
  onkeydown?: KeyboardHandler;
@@ -416,9 +416,10 @@
416
416
  // =========================================================================
417
417
  // $derived
418
418
  // =========================================================================
419
- // 各要素のIDを生成
420
- const inputId = $derived(`${id}-input`);
421
- const listboxId = $derived(`${id}-listbox`);
419
+ // 各要素のIDを生成(id 未指定時は安定した一意のフォールバックを使用)
420
+ const fallbackId = `combobox-${Math.random().toString(36).substring(2, 15)}`;
421
+ const inputId = $derived(`${id ?? fallbackId}-input`);
422
+ const listboxId = $derived(`${id ?? fallbackId}-listbox`);
422
423
 
423
424
  // フィルタリングされたオプション
424
425
  const filteredOptions = $derived.by(() => {
@@ -599,7 +599,8 @@
599
599
  // =========================================================================
600
600
  // $derived
601
601
  // =========================================================================
602
- const calendarId = $derived(`${id}-calendar`);
602
+ const fallbackId = `datepicker-${Math.random().toString(36).substring(2, 15)}`;
603
+ const calendarId = $derived(`${id ?? fallbackId}-calendar`);
603
604
  const currentLocaleConfig = $derived(localeConfig[resolvedLocale]);
604
605
  const finalFormat = $derived(
605
606
  format ||
@@ -153,7 +153,7 @@
153
153
  customStyles={dialogStyles}
154
154
  id={id ? `${id}-modal` : undefined}
155
155
  >
156
- <div class="dialog {scrollable ? 'dialog--scrollable' : ''}">
156
+ <div class="dialog {scrollable ? 'dialog--scrollable' : ''}" data-testid="dialog">
157
157
  {#if header || title}
158
158
  <div class="dialog__header">
159
159
  {#if header}
@@ -167,7 +167,7 @@
167
167
  customStyles={drawerStyles()}
168
168
  id={id ? `${id}-modal` : undefined}
169
169
  >
170
- <div class="drawer drawer--{position} {scrollable ? 'drawer--scrollable' : ''}">
170
+ <div class="drawer drawer--{position} {scrollable ? 'drawer--scrollable' : ''}" data-testid="drawer">
171
171
  {#if header || title}
172
172
  <div class="drawer__header">
173
173
  {#if header}
@@ -383,14 +383,8 @@
383
383
  align-items: center;
384
384
  gap: 16px;
385
385
  position: relative;
386
- width: var(
387
- --internal-file-uploader-width,
388
- var(--svelte-ui-file-uploader-width, 100%)
389
- );
390
- height: var(
391
- --internal-file-uploader-height,
392
- var(--svelte-ui-file-uploader-height, auto)
393
- );
386
+ width: var(--internal-file-uploader-width);
387
+ height: var(--internal-file-uploader-height, var(--svelte-ui-file-uploader-height));
394
388
  min-height: 100px;
395
389
  padding: 16px;
396
390
  background-color: var(--svelte-ui-file-uploader-bg);
@@ -450,14 +450,8 @@
450
450
  align-items: center;
451
451
  position: relative;
452
452
  max-width: 100%;
453
- min-width: var(
454
- --internal-image-uploader-button-width,
455
- var(--svelte-ui-image-uploader-button-width)
456
- );
457
- min-height: var(
458
- --internal-image-uploader-button-height,
459
- var(--svelte-ui-image-uploader-button-height)
460
- );
453
+ min-width: var(--internal-image-uploader-button-width);
454
+ min-height: var(--internal-image-uploader-button-height);
461
455
  padding: 16px;
462
456
  background-color: var(--svelte-ui-form-bg);
463
457
  border-radius: var(--svelte-ui-border-radius);
@@ -110,6 +110,7 @@
110
110
  class:image-uploader-preview--adaptive={previewAdaptive}
111
111
  class:image-uploader-preview--plain={previewStyle === 'plain'}
112
112
  style={imageSizeStyle}
113
+ data-testid="image-uploader-preview"
113
114
  >
114
115
  <img
115
116
  src={getImageUrl(file)}
@@ -83,6 +83,10 @@
83
83
  /** Adds increment/decrement stepper buttons. Only for `type="number"`. @default false */
84
84
  enableNumberStepper?: boolean;
85
85
 
86
+ // ARIA/アクセシビリティ
87
+ /** Accessible label for the input, used when no associated visible label exists. */
88
+ ariaLabel?: string;
89
+
86
90
  // フォーカスイベント
87
91
  onfocus?: FocusHandler;
88
92
  onblur?: FocusHandler;
@@ -192,6 +196,9 @@
192
196
  clearButtonAriaLabel = t('input.clear'),
193
197
  linkify = false,
194
198
 
199
+ // ARIA/アクセシビリティ
200
+ ariaLabel,
201
+
195
202
  // フォーカスイベント
196
203
  onfocus = () => {}, // No params for type inference
197
204
  onblur = () => {}, // No params for type inference
@@ -718,6 +725,7 @@
718
725
  {disabled}
719
726
  {readonly}
720
727
  {required}
728
+ aria-label={ariaLabel}
721
729
  {tabindex}
722
730
  {spellcheck}
723
731
  onchange={handleChange}
@@ -1099,7 +1107,6 @@
1099
1107
  width: 32px;
1100
1108
  height: 32px;
1101
1109
  transform: translateY(-50%);
1102
- font-size: var(--svelte-ui-select-dropdown-icon-size);
1103
1110
  color: var(--svelte-ui-input-icon-color);
1104
1111
  pointer-events: none;
1105
1112
  z-index: 1;
@@ -1115,7 +1122,6 @@
1115
1122
  width: 32px;
1116
1123
  height: 32px;
1117
1124
  transform: translateY(-50%);
1118
- font-size: var(--svelte-ui-select-dropdown-icon-size);
1119
1125
  color: var(--svelte-ui-input-icon-color);
1120
1126
  pointer-events: none;
1121
1127
  z-index: 2;
@@ -55,6 +55,8 @@ export type InputProps = {
55
55
  enablePasswordVisibilityToggle?: boolean;
56
56
  /** Adds increment/decrement stepper buttons. Only for `type="number"`. @default false */
57
57
  enableNumberStepper?: boolean;
58
+ /** Accessible label for the input, used when no associated visible label exists. */
59
+ ariaLabel?: string;
58
60
  onfocus?: FocusHandler;
59
61
  onblur?: FocusHandler;
60
62
  onkeydown?: KeyboardHandler;
@@ -47,7 +47,7 @@
47
47
 
48
48
  <div
49
49
  class="loading-spinner"
50
- class:spinner--no-motion={reducedMotion}
50
+ class:loading-spinner--no-motion={reducedMotion}
51
51
  style:--internal-loading-spinner-grow-duration="{growDuration}s"
52
52
  style:--internal-loading-spinner-rotate-duration="{rotateDuration}s"
53
53
  style:--internal-loading-spinner-size="{size}px"
@@ -114,8 +114,8 @@
114
114
  }
115
115
 
116
116
  /* Reduced motion */
117
- .spinner--no-motion svg,
118
- .spinner--no-motion circle {
117
+ .loading-spinner--no-motion svg,
118
+ .loading-spinner--no-motion circle {
119
119
  animation-duration: 0.01s;
120
120
  }
121
121
 
@@ -26,6 +26,9 @@
26
26
  /** Internal label used for accessibility announcements. @default 'Modal' */
27
27
  componentType?: string;
28
28
 
29
+ // HTML属性
30
+ id?: string;
31
+
29
32
  // スタイル/レイアウト
30
33
  customClass?: string;
31
34
  customStyles?: string;
@@ -44,9 +47,6 @@
44
47
  ariaLabel?: string;
45
48
  ariaLabelledby?: string;
46
49
  ariaDescribedby?: string;
47
-
48
- // HTML属性
49
- id?: string;
50
50
  };
51
51
 
52
52
  let {
@@ -56,6 +56,9 @@
56
56
  // 基本プロパティ
57
57
  componentType = 'Modal',
58
58
 
59
+ // HTML属性
60
+ id,
61
+
59
62
  // スタイル/レイアウト
60
63
  customClass = '',
61
64
  customStyles = '',
@@ -69,10 +72,7 @@
69
72
  // ARIA/アクセシビリティ
70
73
  ariaLabel,
71
74
  ariaLabelledby,
72
- ariaDescribedby,
73
-
74
- // HTML属性
75
- id
75
+ ariaDescribedby
76
76
  }: ModalProps = $props();
77
77
 
78
78
  let dialogRef: HTMLDialogElement;
@@ -15,6 +15,7 @@ export type ModalProps = {
15
15
  children?: Snippet;
16
16
  /** Internal label used for accessibility announcements. @default 'Modal' */
17
17
  componentType?: string;
18
+ id?: string;
18
19
  customClass?: string;
19
20
  customStyles?: string;
20
21
  /** Use `modalRef.open()` / `.close()` instead of binding this directly. */
@@ -28,7 +29,6 @@ export type ModalProps = {
28
29
  ariaLabel?: string;
29
30
  ariaLabelledby?: string;
30
31
  ariaDescribedby?: string;
31
- id?: string;
32
32
  };
33
33
  declare const Modal: import("svelte").Component<ModalProps, {
34
34
  /** Opens the modal. */ open: (title?: string) => void;
@@ -82,7 +82,8 @@
82
82
  // =========================================================================
83
83
  // $derived
84
84
  // =========================================================================
85
- const listboxId = $derived(`${id}-listbox`);
85
+ const fallbackId = `multi-select-${Math.random().toString(36).substring(2, 15)}`;
86
+ const listboxId = $derived(`${id ?? fallbackId}-listbox`);
86
87
 
87
88
  const selectedLabels = $derived(
88
89
  options.filter((o) => value.includes(o.value)).map((o) => o.label)
@@ -291,7 +292,6 @@
291
292
  margin-right: calc(0px - var(--svelte-ui-select-icon-space));
292
293
  width: 32px;
293
294
  height: 32px;
294
- font-size: var(--svelte-ui-select-dropdown-icon-size);
295
295
  color: var(--svelte-ui-select-dropdown-icon-color);
296
296
  pointer-events: none;
297
297
  }
@@ -38,6 +38,12 @@
38
38
  // スタイル/レイアウト
39
39
  /** Visual style for the selected item. */
40
40
  selectedVariant?: NavItemSelectedVariant;
41
+ /** Custom CSS color for item labels (underline variant). */
42
+ textColor?: string;
43
+ /** Custom CSS color for the selected item label (underline variant). */
44
+ selectedTextColor?: string;
45
+ /** Custom CSS color for the selected underline bar (underline variant). */
46
+ selectedBarColor?: string;
41
47
  gap?: number | string;
42
48
  /** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
43
49
  childrenVariant?: ChildrenVariant;
@@ -77,6 +83,9 @@
77
83
 
78
84
  // スタイル/レイアウト
79
85
  selectedVariant,
86
+ textColor,
87
+ selectedTextColor,
88
+ selectedBarColor,
80
89
  gap,
81
90
  childrenVariant = variant === 'mobile'
82
91
  ? 'bottom-sheet'
@@ -290,6 +299,9 @@
290
299
  {iconOpticalSize}
291
300
  {iconVariant}
292
301
  {selectedVariant}
302
+ {textColor}
303
+ {selectedTextColor}
304
+ {selectedBarColor}
293
305
  {childrenVariant}
294
306
  {chevron}
295
307
  customStyle={customItemStyle}
@@ -325,6 +337,9 @@
325
337
  {iconOpticalSize}
326
338
  {iconVariant}
327
339
  {selectedVariant}
340
+ {textColor}
341
+ {selectedTextColor}
342
+ {selectedBarColor}
328
343
  customStyle={customChildrenItemStyle}
329
344
  isChild={true}
330
345
  {resolvedCurrentPath}
@@ -21,6 +21,12 @@ export type NavProps = {
21
21
  iconVariant?: IconVariant;
22
22
  /** Visual style for the selected item. */
23
23
  selectedVariant?: NavItemSelectedVariant;
24
+ /** Custom CSS color for item labels (underline variant). */
25
+ textColor?: string;
26
+ /** Custom CSS color for the selected item label (underline variant). */
27
+ selectedTextColor?: string;
28
+ /** Custom CSS color for the selected underline bar (underline variant). */
29
+ selectedBarColor?: string;
24
30
  gap?: number | string;
25
31
  /** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
26
32
  childrenVariant?: ChildrenVariant;
@@ -38,6 +38,12 @@
38
38
  /** Show chevron icon on parent items. @default true */
39
39
  chevron?: boolean;
40
40
  selectedVariant?: NavItemSelectedVariant;
41
+ /** Custom CSS color for the item label (underline variant). */
42
+ textColor?: string;
43
+ /** Custom CSS color for the selected item label (underline variant). */
44
+ selectedTextColor?: string;
45
+ /** Custom CSS color for the selected underline bar (underline variant). */
46
+ selectedBarColor?: string;
41
47
  /** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
42
48
  childrenVariant?: ChildrenVariant;
43
49
  /** Inline style applied to this nav item element. */
@@ -75,6 +81,9 @@
75
81
  // スタイル/レイアウト
76
82
  chevron = true,
77
83
  selectedVariant,
84
+ textColor,
85
+ selectedTextColor,
86
+ selectedBarColor,
78
87
  childrenVariant = variant === 'mobile' ? 'bottom-sheet' : variant === 'vertical' ? 'accordion' : 'bar',
79
88
  customStyle,
80
89
  customChildrenStyle,
@@ -231,6 +240,9 @@
231
240
  class:nav-item--style-filled={isSelected && resolvedSelectedStyle === 'filled'}
232
241
  class:nav-item--style-tonal={isSelected && resolvedSelectedStyle === 'tonal'}
233
242
  class:nav-item--style-underline={resolvedSelectedStyle === 'underline'}
243
+ style:--internal-nav-item-underline-text-color={textColor}
244
+ style:--internal-nav-item-underline-selected-text-color={selectedTextColor}
245
+ style:--internal-nav-item-underline-bar-color={selectedBarColor}
234
246
  style={customStyle}
235
247
  aria-disabled="true"
236
248
  tabindex="-1"
@@ -260,6 +272,9 @@
260
272
  <div
261
273
  class="nav-item__group nav-item__group--{variant}"
262
274
  class:nav-item__group--open={childrenVariant === 'expanded' || isChildrenVisible}
275
+ style:--internal-nav-item-underline-text-color={textColor}
276
+ style:--internal-nav-item-underline-selected-text-color={selectedTextColor}
277
+ style:--internal-nav-item-underline-bar-color={selectedBarColor}
263
278
  >
264
279
  <a
265
280
  href={resolvedParentHref}
@@ -402,6 +417,9 @@
402
417
  class:nav-item--style-filled={isSelected && resolvedSelectedStyle === 'filled'}
403
418
  class:nav-item--style-tonal={isSelected && resolvedSelectedStyle === 'tonal'}
404
419
  class:nav-item--style-underline={resolvedSelectedStyle === 'underline'}
420
+ style:--internal-nav-item-underline-text-color={textColor}
421
+ style:--internal-nav-item-underline-selected-text-color={selectedTextColor}
422
+ style:--internal-nav-item-underline-bar-color={selectedBarColor}
405
423
  style={customStyle}
406
424
  aria-current={isSelected ? 'page' : undefined}
407
425
  tabindex={0}
@@ -508,7 +526,7 @@
508
526
  padding: var(--svelte-ui-nav-item-padding-y) var(--svelte-ui-nav-item-padding-x);
509
527
  justify-content: center;
510
528
  border-radius: 0;
511
- color: var(--svelte-ui-nav-item-underline-text-color);
529
+ color: var(--internal-nav-item-underline-text-color, var(--svelte-ui-nav-item-underline-text-color));
512
530
  }
513
531
 
514
532
  .nav-item--horizontal::after {
@@ -524,7 +542,7 @@
524
542
  opacity: 1;
525
543
  }
526
544
  .nav-item--horizontal.nav-item--style-underline:hover {
527
- color: var(--svelte-ui-nav-item-underline-selected-text-color);
545
+ color: var(--internal-nav-item-underline-selected-text-color, var(--svelte-ui-nav-item-underline-selected-text-color));
528
546
  }
529
547
  .nav-item--horizontal.nav-item--style-underline:hover::before {
530
548
  opacity: 1;
@@ -545,7 +563,7 @@
545
563
  }
546
564
 
547
565
  .nav-item--horizontal.nav-item--style-underline.nav-item--selected {
548
- color: var(--svelte-ui-nav-item-underline-selected-text-color);
566
+ color: var(--internal-nav-item-underline-selected-text-color, var(--svelte-ui-nav-item-underline-selected-text-color));
549
567
  }
550
568
 
551
569
  .nav-item--horizontal.nav-item--style-underline::before {
@@ -556,7 +574,7 @@
556
574
  left: calc(var(--svelte-ui-nav-item-padding-x) - var(--svelte-ui-nav-item-underline-bar-offset));
557
575
  width: calc(100% - 2 * var(--svelte-ui-nav-item-padding-x) + 2 * var(--svelte-ui-nav-item-underline-bar-offset));
558
576
  height: var(--svelte-ui-nav-item-underline-bar-height);
559
- background-color: var(--svelte-ui-nav-item-underline-bar-color);
577
+ background-color: var(--internal-nav-item-underline-bar-color, var(--svelte-ui-nav-item-underline-bar-color));
560
578
  border-radius: var(--svelte-ui-nav-item-underline-bar-radius);
561
579
  opacity: 0;
562
580
  transition-property: opacity;
@@ -19,6 +19,12 @@ export type NavItemProps = {
19
19
  /** Show chevron icon on parent items. @default true */
20
20
  chevron?: boolean;
21
21
  selectedVariant?: NavItemSelectedVariant;
22
+ /** Custom CSS color for the item label (underline variant). */
23
+ textColor?: string;
24
+ /** Custom CSS color for the selected item label (underline variant). */
25
+ selectedTextColor?: string;
26
+ /** Custom CSS color for the selected underline bar (underline variant). */
27
+ selectedBarColor?: string;
22
28
  /** How child items are displayed. Defaults to `accordion` (vertical), `bar` (horizontal), `bottom-sheet` (mobile). */
23
29
  childrenVariant?: ChildrenVariant;
24
30
  /** Inline style applied to this nav item element. */