@14ch/svelte-ui 0.0.68 → 0.0.70

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.
@@ -139,10 +139,13 @@
139
139
  * ==================================== */
140
140
  /* 基本テキスト色の定義 */
141
141
  --svelte-ui-text-color: var(--base-800-transparent);
142
- --svelte-ui-text-subtle-color: var(--base-500-transparent);
142
+ --svelte-ui-text-weak-color: var(--base-500-transparent);
143
+ /* weak のエイリアス。weak から派生させることでどちらを上書きしても効く */
144
+ --svelte-ui-text-subtle-color: var(--svelte-ui-text-weak-color);
143
145
  --svelte-ui-text-on-filled-color: #ffffff;
144
146
  --svelte-ui-text-inverse-color: var(--white-800-transparent);
145
- --svelte-ui-text-inverse-subtle-color: var(--white-500-transparent);
147
+ --svelte-ui-text-inverse-weak-color: var(--white-500-transparent);
148
+ --svelte-ui-text-inverse-subtle-color: var(--svelte-ui-text-inverse-weak-color);
146
149
  --svelte-ui-text-placeholder-color: var(--base-500-transparent);
147
150
  /* ボーダーカラー */
148
151
  --svelte-ui-border-color: var(--base-200-transparent);
@@ -179,10 +182,12 @@
179
182
  [data-theme=dark] {
180
183
  /* 基本テキスト色の定義 */
181
184
  --svelte-ui-text-color: var(--white-800-transparent);
182
- --svelte-ui-text-subtle-color: var(--white-500-transparent);
185
+ --svelte-ui-text-weak-color: var(--white-500-transparent);
186
+ --svelte-ui-text-subtle-color: var(--svelte-ui-text-weak-color);
183
187
  --svelte-ui-text-on-filled-color: #ffffff;
184
188
  --svelte-ui-text-inverse-color: var(--base-800-transparent);
185
- --svelte-ui-text-inverse-subtle-color: var(--base-500-transparent);
189
+ --svelte-ui-text-inverse-weak-color: var(--base-500-transparent);
190
+ --svelte-ui-text-inverse-subtle-color: var(--svelte-ui-text-inverse-weak-color);
186
191
  --svelte-ui-text-placeholder-color: var(--white-500-transparent);
187
192
  /* ボーダーカラー */
188
193
  --svelte-ui-border-color: var(--white-200-transparent);
@@ -460,6 +465,15 @@
460
465
  --svelte-ui-select-border-color: var(--svelte-ui-border-weak-color);
461
466
  --svelte-ui-select-dropdown-icon-color: var(--svelte-ui-dropdown-icon-color);
462
467
  --svelte-ui-select-placeholder-color: var(--svelte-ui-text-placeholder-color);
468
+ --svelte-ui-select-options-min-width: 160px;
469
+ --svelte-ui-select-options-max-height: 280px;
470
+ --svelte-ui-select-option-padding: 8px 12px;
471
+ --svelte-ui-select-option-gap: 4px;
472
+ --svelte-ui-select-option-check-size: 18px;
473
+ --svelte-ui-select-option-hover-bg: var(--svelte-ui-hover-overlay);
474
+ --svelte-ui-select-option-selected-bg: var(--svelte-ui-select-overlay);
475
+ --svelte-ui-select-separator-margin: 4px 0;
476
+ --svelte-ui-select-separator-color: var(--svelte-ui-border-color);
463
477
  /* Checkbox */
464
478
  --svelte-ui-checkbox-size: 16px;
465
479
  --svelte-ui-checkbox-size-sm: 14px;
@@ -789,7 +803,7 @@
789
803
  [data-theme=dark] {
790
804
  /* ===== 基本色の上書き ===== */
791
805
  --svelte-ui-text-color: CanvasText;
792
- --svelte-ui-text-subtle-color: CanvasText;
806
+ --svelte-ui-text-weak-color: CanvasText;
793
807
  --svelte-ui-surface-accent-color: CanvasText;
794
808
  --svelte-ui-text-on-filled-color: HighlightText;
795
809
  --svelte-ui-text-placeholder-color: CanvasText;
@@ -827,6 +841,7 @@
827
841
  --svelte-ui-select-border-color: CanvasText;
828
842
  --svelte-ui-select-text-color: CanvasText;
829
843
  --svelte-ui-select-dropdown-icon-color: CanvasText;
844
+ --svelte-ui-select-separator-color: CanvasText;
830
845
  --svelte-ui-colorpicker-border-color: CanvasText;
831
846
  --svelte-ui-colorpicker-trigger-border-color: CanvasText;
832
847
  --svelte-ui-colorpicker-bg: Canvas;
@@ -875,6 +890,8 @@
875
890
  /* ===== オーバーレイ・インタラクション色の上書き ===== */
876
891
  --svelte-ui-hover-overlay: Highlight;
877
892
  --svelte-ui-select-overlay: Highlight;
893
+ --svelte-ui-select-option-hover-bg: Highlight;
894
+ --svelte-ui-select-option-selected-bg: Highlight;
878
895
  --svelte-ui-combobox-option-hover-bg: Highlight;
879
896
  --svelte-ui-combobox-option-selected-bg: Highlight;
880
897
  /* ===== アイコンボタンの上書き ===== */
@@ -141,10 +141,13 @@
141
141
 
142
142
  /* 基本テキスト色の定義 */
143
143
  --svelte-ui-text-color: var(--base-800-transparent);
144
- --svelte-ui-text-subtle-color: var(--base-500-transparent);
144
+ --svelte-ui-text-weak-color: var(--base-500-transparent);
145
+ /* weak のエイリアス。weak から派生させることでどちらを上書きしても効く */
146
+ --svelte-ui-text-subtle-color: var(--svelte-ui-text-weak-color);
145
147
  --svelte-ui-text-on-filled-color: #ffffff;
146
148
  --svelte-ui-text-inverse-color: var(--white-800-transparent);
147
- --svelte-ui-text-inverse-subtle-color: var(--white-500-transparent);
149
+ --svelte-ui-text-inverse-weak-color: var(--white-500-transparent);
150
+ --svelte-ui-text-inverse-subtle-color: var(--svelte-ui-text-inverse-weak-color);
148
151
  --svelte-ui-text-placeholder-color: var(--base-500-transparent);
149
152
 
150
153
  /* ボーダーカラー */
@@ -193,10 +196,12 @@
193
196
  [data-theme='dark'] {
194
197
  /* 基本テキスト色の定義 */
195
198
  --svelte-ui-text-color: var(--white-800-transparent);
196
- --svelte-ui-text-subtle-color: var(--white-500-transparent);
199
+ --svelte-ui-text-weak-color: var(--white-500-transparent);
200
+ --svelte-ui-text-subtle-color: var(--svelte-ui-text-weak-color);
197
201
  --svelte-ui-text-on-filled-color: #ffffff;
198
202
  --svelte-ui-text-inverse-color: var(--base-800-transparent);
199
- --svelte-ui-text-inverse-subtle-color: var(--base-500-transparent);
203
+ --svelte-ui-text-inverse-weak-color: var(--base-500-transparent);
204
+ --svelte-ui-text-inverse-subtle-color: var(--svelte-ui-text-inverse-weak-color);
200
205
  --svelte-ui-text-placeholder-color: var(--white-500-transparent);
201
206
 
202
207
  /* ボーダーカラー */
@@ -502,6 +507,15 @@
502
507
  --svelte-ui-select-border-color: var(--svelte-ui-border-weak-color);
503
508
  --svelte-ui-select-dropdown-icon-color: var(--svelte-ui-dropdown-icon-color);
504
509
  --svelte-ui-select-placeholder-color: var(--svelte-ui-text-placeholder-color);
510
+ --svelte-ui-select-options-min-width: 160px;
511
+ --svelte-ui-select-options-max-height: 280px;
512
+ --svelte-ui-select-option-padding: 8px 12px;
513
+ --svelte-ui-select-option-gap: 4px;
514
+ --svelte-ui-select-option-check-size: 18px;
515
+ --svelte-ui-select-option-hover-bg: var(--svelte-ui-hover-overlay);
516
+ --svelte-ui-select-option-selected-bg: var(--svelte-ui-select-overlay);
517
+ --svelte-ui-select-separator-margin: 4px 0;
518
+ --svelte-ui-select-separator-color: var(--svelte-ui-border-color);
505
519
 
506
520
  /* Checkbox */
507
521
  --svelte-ui-checkbox-size: 16px;
@@ -860,7 +874,7 @@
860
874
  [data-theme='dark'] {
861
875
  /* ===== 基本色の上書き ===== */
862
876
  --svelte-ui-text-color: CanvasText;
863
- --svelte-ui-text-subtle-color: CanvasText;
877
+ --svelte-ui-text-weak-color: CanvasText;
864
878
  --svelte-ui-surface-accent-color: CanvasText;
865
879
  --svelte-ui-text-on-filled-color: HighlightText;
866
880
  --svelte-ui-text-placeholder-color: CanvasText;
@@ -905,6 +919,7 @@
905
919
  --svelte-ui-select-border-color: CanvasText;
906
920
  --svelte-ui-select-text-color: CanvasText;
907
921
  --svelte-ui-select-dropdown-icon-color: CanvasText;
922
+ --svelte-ui-select-separator-color: CanvasText;
908
923
  --svelte-ui-colorpicker-border-color: CanvasText;
909
924
  --svelte-ui-colorpicker-trigger-border-color: CanvasText;
910
925
  --svelte-ui-colorpicker-bg: Canvas;
@@ -960,6 +975,8 @@
960
975
  /* ===== オーバーレイ・インタラクション色の上書き ===== */
961
976
  --svelte-ui-hover-overlay: Highlight;
962
977
  --svelte-ui-select-overlay: Highlight;
978
+ --svelte-ui-select-option-hover-bg: Highlight;
979
+ --svelte-ui-select-option-selected-bg: Highlight;
963
980
  --svelte-ui-combobox-option-hover-bg: Highlight;
964
981
  --svelte-ui-combobox-option-selected-bg: Highlight;
965
982
 
@@ -402,7 +402,7 @@
402
402
  {minWidth}
403
403
  {maxWidth}
404
404
  {rounded}
405
- customStyle={`padding-left: var(--svelte-ui-colorpicker-text-padding-left); ${customStyle}`}
405
+ customStyle={`${customStyle}; padding-left: var(--svelte-ui-colorpicker-text-padding-left)`}
406
406
  onchange={handleChange}
407
407
  oninput={handleInput}
408
408
  onfocus={handleFocus}
@@ -704,9 +704,37 @@
704
704
  // --------------------------------
705
705
  // style from number
706
706
  // --------------------------------
707
+ // アイコンの領域は customStyle で消されないよう、customStyle より後ろに指定する
708
+ const iconSpaceSuffix = $derived(inline ? '-inline' : '');
709
+ const iconPaddingStyle = $derived(
710
+ [
711
+ hasLeftIcon ? `padding-left: var(--svelte-ui-input-icon-space${iconSpaceSuffix})` : '',
712
+ clearable && hasRightIcon
713
+ ? `padding-right: var(--svelte-ui-input-icon-space-double${iconSpaceSuffix})`
714
+ : clearable || hasRightIcon
715
+ ? `padding-right: var(--svelte-ui-input-icon-space${iconSpaceSuffix})`
716
+ : ''
717
+ ]
718
+ .filter(Boolean)
719
+ .join('; ')
720
+ );
707
721
  const widthStyle = $derived(getStyleFromNumber(width));
708
722
  const maxWidthStyle = $derived(getStyleFromNumber(maxWidth));
709
723
  const minWidthStyle = $derived(getStyleFromNumber(minWidth));
724
+
725
+ // style: ディレクティブは style 属性に勝つため、幅の指定も customStyle と同じ文字列に混ぜる。
726
+ // 専用プロップが指定されたときだけ customStyle より後ろに置いてプロップを優先させる
727
+ const boxStyle = $derived(
728
+ [
729
+ customStyle,
730
+ iconPaddingStyle,
731
+ widthStyle ? `width: ${widthStyle}` : '',
732
+ minWidthStyle ? `min-width: ${minWidthStyle}` : '',
733
+ maxWidthStyle ? `max-width: ${maxWidthStyle}` : ''
734
+ ]
735
+ .filter(Boolean)
736
+ .join('; ')
737
+ );
710
738
  </script>
711
739
 
712
740
  <div
@@ -727,12 +755,10 @@
727
755
  class:input--readonly={readonly}
728
756
  class:input--focused={isFocused}
729
757
  data-testid="input"
730
- style:width={widthStyle}
731
- style:max-width={maxWidthStyle}
732
- style:min-width={minWidthStyle}
758
+ style={boxStyle}
733
759
  >
734
760
  <!-- 表示用テキスト -->
735
- <div class="input__display-text" style={customStyle}>
761
+ <div class="input__display-text">
736
762
  <div
737
763
  class="input__display-text-content"
738
764
  class:input__display-text-content--placeholder={!hasDisplayValue}
@@ -753,7 +779,6 @@
753
779
  bind:value
754
780
  bind:this={ref}
755
781
  type={resolvedType}
756
- style={customStyle}
757
782
  {placeholder}
758
783
  {autocomplete}
759
784
  {min}
@@ -798,7 +823,7 @@
798
823
  />
799
824
  </div>
800
825
  {#if isLinkifyActive}
801
- <div class="input__link-text" style={customStyle}>
826
+ <div class="input__link-text">
802
827
  <div class="input__link-text-content">
803
828
  {@html linkHtmlValue}
804
829
  </div>
@@ -905,6 +930,11 @@
905
930
  width: auto;
906
931
  max-width: 100%;
907
932
  height: inherit;
933
+ min-height: var(--svelte-ui-input-height);
934
+ padding: var(--svelte-ui-input-padding);
935
+ background-color: var(--svelte-ui-input-bg);
936
+ box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-input-border-color);
937
+ border-radius: var(--svelte-ui-input-border-radius);
908
938
  }
909
939
 
910
940
  .input__wrapper {
@@ -915,9 +945,8 @@
915
945
  height: 100%;
916
946
  padding: inherit;
917
947
  border: none;
918
- border-radius: var(--svelte-ui-input-border-radius);
919
- background-color: var(--svelte-ui-input-bg);
920
- box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-input-border-color);
948
+ border-radius: inherit;
949
+ background-color: transparent;
921
950
  font-size: inherit;
922
951
  font-weight: inherit;
923
952
  color: inherit;
@@ -935,10 +964,10 @@
935
964
  width: 100%;
936
965
  min-width: 1em;
937
966
  min-height: var(--svelte-ui-input-height);
938
- padding: var(--svelte-ui-input-padding);
967
+ padding: 0;
939
968
  background-color: transparent;
940
969
  border: none;
941
- border-radius: var(--svelte-ui-input-border-radius);
970
+ border-radius: inherit;
942
971
  font-family: inherit;
943
972
  font-size: inherit;
944
973
  font-weight: inherit;
@@ -962,7 +991,7 @@
962
991
  width: 100%;
963
992
  min-width: 1em;
964
993
  height: var(--svelte-ui-input-height);
965
- padding: var(--svelte-ui-input-padding);
994
+ padding: 0;
966
995
  font-size: inherit;
967
996
  font-weight: inherit;
968
997
  color: inherit;
@@ -990,6 +1019,7 @@
990
1019
  left: 0;
991
1020
  width: 100%;
992
1021
  height: 100%;
1022
+ padding: inherit;
993
1023
  pointer-events: none;
994
1024
  z-index: 1;
995
1025
  }
@@ -1005,7 +1035,7 @@
1005
1035
  /* =============================================
1006
1036
  * 表示制御
1007
1037
  * ============================================= */
1008
- /* 非フォーカス時: input要素自体を不可視化(枠線・背景はラッパーにあるため display-text のみ表示) */
1038
+ /* 非フォーカス時: input要素自体を不可視化(枠線・背景はルートにあるため display-text のみ表示) */
1009
1039
  .input:not(.input--focused) input {
1010
1040
  opacity: 0;
1011
1041
  }
@@ -1027,7 +1057,11 @@
1027
1057
  /* =============================================
1028
1058
  * フォーカス効果バリエーション
1029
1059
  * ============================================= */
1030
- .input--focus-outline input:focus {
1060
+ input:focus {
1061
+ outline: none;
1062
+ }
1063
+
1064
+ .input--focus-outline.input--focused .input__wrapper {
1031
1065
  outline: var(--svelte-ui-focus-outline-inner);
1032
1066
  outline-offset: var(--svelte-ui-focus-outline-offset-inner);
1033
1067
  }
@@ -1036,14 +1070,6 @@
1036
1070
  background: var(--svelte-ui-hover-overlay);
1037
1071
  }
1038
1072
 
1039
- .input--focus-background input:focus {
1040
- outline: none;
1041
- }
1042
-
1043
- .input--focus-none input:focus {
1044
- outline: none;
1045
- }
1046
-
1047
1073
  /* =============================================
1048
1074
  * 状態管理(disabled, readonly等)
1049
1075
  * ============================================= */
@@ -1089,22 +1115,6 @@
1089
1115
  transition: var(--svelte-ui-transition-duration);
1090
1116
  }
1091
1117
 
1092
- .input--clearable {
1093
- input,
1094
- .input__display-text,
1095
- .input__link-text {
1096
- padding-right: var(--svelte-ui-input-icon-space);
1097
- }
1098
- }
1099
-
1100
- .input--clearable.input--has-right-icon {
1101
- input,
1102
- .input__display-text,
1103
- .input__link-text {
1104
- padding-right: var(--svelte-ui-input-icon-space-double);
1105
- }
1106
- }
1107
-
1108
1118
  .input--has-right-icon .input__clear-button {
1109
1119
  right: var(--svelte-ui-input-icon-space);
1110
1120
  }
@@ -1122,22 +1132,6 @@
1122
1132
  }
1123
1133
 
1124
1134
  /* アイコン */
1125
- .input--has-left-icon {
1126
- input,
1127
- .input__display-text,
1128
- .input__link-text {
1129
- padding-left: var(--svelte-ui-input-icon-space);
1130
- }
1131
- }
1132
-
1133
- .input--has-right-icon {
1134
- input,
1135
- .input__display-text,
1136
- .input__link-text {
1137
- padding-right: var(--svelte-ui-input-icon-space);
1138
- }
1139
- }
1140
-
1141
1135
  .input__icon-left {
1142
1136
  display: flex;
1143
1137
  justify-content: center;
@@ -1214,29 +1208,27 @@
1214
1208
  * デザインバリエーション
1215
1209
  * ============================================= */
1216
1210
  /* rounded */
1217
- .input--rounded .input__wrapper,
1218
- .input--rounded input {
1211
+ .input--rounded {
1219
1212
  border-radius: var(--svelte-ui-input-border-radius-rounded);
1220
1213
  }
1221
1214
 
1222
1215
  /* inline */
1223
- .input--inline .input__wrapper,
1224
- .input--inline input {
1225
- min-height: inherit;
1226
- line-height: inherit;
1216
+ .input--inline {
1217
+ min-height: 0;
1218
+ padding: 0;
1227
1219
  background-color: transparent;
1228
1220
  box-shadow: none;
1229
- border: inherit;
1230
1221
  border-radius: 0;
1231
- }
1232
1222
 
1233
- .input--inline {
1223
+ input {
1224
+ min-height: 0;
1225
+ }
1226
+
1234
1227
  input,
1235
1228
  .input__display-text,
1236
1229
  .input__link-text {
1237
1230
  height: inherit;
1238
1231
  line-height: inherit;
1239
- padding: inherit;
1240
1232
  }
1241
1233
 
1242
1234
  /*
@@ -1249,41 +1241,11 @@
1249
1241
  line-height: normal;
1250
1242
  }
1251
1243
 
1252
- &.input--has-left-icon {
1253
- input,
1254
- .input__display-text,
1255
- .input__link-text {
1256
- padding-left: var(--svelte-ui-input-icon-space-inline);
1257
- }
1258
- }
1259
-
1260
1244
  &.input--has-right-icon {
1261
- input,
1262
- .input__display-text,
1263
- .input__link-text {
1264
- padding-right: var(--svelte-ui-input-icon-space-inline);
1265
- }
1266
-
1267
1245
  .input__icon-right {
1268
1246
  right: 0;
1269
1247
  }
1270
1248
  }
1271
-
1272
- &.input--clearable {
1273
- input,
1274
- .input__display-text,
1275
- .input__link-text {
1276
- padding-right: var(--svelte-ui-input-icon-space-inline);
1277
- }
1278
- }
1279
-
1280
- &.input--clearable.input--has-right-icon {
1281
- input,
1282
- .input__display-text,
1283
- .input__link-text {
1284
- padding-right: var(--svelte-ui-input-icon-space-double-inline);
1285
- }
1286
- }
1287
1249
  }
1288
1250
 
1289
1251
  /* full-width */
@@ -16,8 +16,8 @@
16
16
  // 基本プロパティ
17
17
  /** Selected values array. Supports `bind:value`. */
18
18
  value: OptionValue[];
19
- /** `{ label, value, disabled? }[]` */
20
- options: Option[];
19
+ /** `{ label, value, disabled? }[]` or `'separator'` for dividers. */
20
+ options: (Option | 'separator')[];
21
21
 
22
22
  // HTML属性系
23
23
  id?: string | null;
@@ -82,11 +82,20 @@
82
82
  // =========================================================================
83
83
  // $derived
84
84
  // =========================================================================
85
+ // アイコンの領域は customStyle で消されないよう、customStyle より後ろに指定する
86
+ const triggerStyle = $derived(
87
+ [customStyle, `padding-right: var(--svelte-ui-select-icon-space${inline ? '-inline' : ''})`]
88
+ .filter(Boolean)
89
+ .join('; ')
90
+ );
91
+
85
92
  const fallbackId = `multi-select-${Math.random().toString(36).substring(2, 15)}`;
86
93
  const listboxId = $derived(`${id ?? fallbackId}-listbox`);
87
94
 
88
95
  const selectedLabels = $derived(
89
- options.filter((o) => value.includes(o.value)).map((o) => o.label)
96
+ options
97
+ .filter((option): option is Option => option !== 'separator' && value.includes(option.value))
98
+ .map((option) => option.label)
90
99
  );
91
100
 
92
101
  // =========================================================================
@@ -159,7 +168,7 @@
159
168
  aria-required={required ? 'true' : undefined}
160
169
  {tabindex}
161
170
  {disabled}
162
- style={customStyle}
171
+ style={triggerStyle}
163
172
  onfocus={handleFocus}
164
173
  onblur={handleBlur}
165
174
  onclick={handleTriggerClick}
@@ -199,20 +208,24 @@
199
208
  role="listbox"
200
209
  aria-multiselectable="true"
201
210
  aria-label={ariaLabel ?? t('multiSelect.accessibleName')}
202
- style:min-width="{triggerWidth}px"
211
+ style:--internal-multi-select-trigger-width="{triggerWidth}px"
203
212
  >
204
- {#each options as option (option.value)}
205
- <li role="presentation" class="multi-select__item">
206
- <Checkbox
207
- value={value.includes(option.value)}
208
- disabled={option.disabled}
209
- fullWidth
210
- customStyle="padding: 8px 12px"
211
- onchange={() => toggleOption(option.value)}
212
- >
213
- {option.label}
214
- </Checkbox>
215
- </li>
213
+ {#each options as option, index (option === 'separator' ? `separator-${index}` : option.value)}
214
+ {#if option === 'separator'}
215
+ <li class="multi-select__separator" role="separator"></li>
216
+ {:else}
217
+ <li role="presentation" class="multi-select__item">
218
+ <Checkbox
219
+ value={value.includes(option.value)}
220
+ disabled={option.disabled}
221
+ fullWidth
222
+ customStyle="padding: 8px 12px"
223
+ onchange={() => toggleOption(option.value)}
224
+ >
225
+ {option.label}
226
+ </Checkbox>
227
+ </li>
228
+ {/if}
216
229
  {/each}
217
230
  </ul>
218
231
  </Popup>
@@ -237,7 +250,6 @@
237
250
  width: 100%;
238
251
  min-height: var(--svelte-ui-select-height);
239
252
  padding: var(--svelte-ui-select-padding);
240
- padding-right: var(--svelte-ui-select-icon-space);
241
253
  background: transparent;
242
254
  border: none;
243
255
  font-family: inherit;
@@ -252,7 +264,6 @@
252
264
  }
253
265
 
254
266
  .multi-select__inner {
255
- position: relative;
256
267
  flex: 1;
257
268
  align-self: stretch;
258
269
  display: flex;
@@ -281,11 +292,9 @@
281
292
  justify-content: center;
282
293
  align-items: center;
283
294
  position: absolute;
284
- top: 0;
295
+ top: 50%;
285
296
  right: 4px;
286
- margin-top: calc((var(--svelte-ui-select-height) - 32px) / 2);
287
- margin-bottom: calc((var(--svelte-ui-select-height) - 32px) / 2);
288
- margin-right: calc(0px - var(--svelte-ui-select-icon-space));
297
+ transform: translateY(-50%);
289
298
  width: 32px;
290
299
  height: 32px;
291
300
  color: var(--svelte-ui-select-dropdown-icon-color);
@@ -346,7 +355,6 @@
346
355
  * ============================================= */
347
356
  .multi-select.multi-select--inline .multi-select__trigger {
348
357
  padding: inherit;
349
- padding-right: var(--svelte-ui-input-icon-space-inline);
350
358
  background: transparent;
351
359
  border: none;
352
360
  border-radius: 0;
@@ -362,9 +370,7 @@
362
370
  .multi-select.multi-select--inline .multi-select__dropdown-icon {
363
371
  top: calc((1lh - 32px) / 2);
364
372
  right: 0;
365
- margin-top: 0;
366
- margin-bottom: 0;
367
- margin-right: calc(0px - var(--svelte-ui-input-icon-space-inline));
373
+ transform: none;
368
374
  }
369
375
 
370
376
  /* =============================================
@@ -381,8 +387,9 @@
381
387
  list-style: none;
382
388
  margin: 0;
383
389
  padding: 0;
384
- min-width: 160px;
385
- max-height: var(--svelte-ui-combobox-options-max-height);
390
+ /* トリガー幅に合わせつつ、トリガーが狭いときはテーマの下限を保つ */
391
+ min-width: max(var(--internal-multi-select-trigger-width, 0px), var(--svelte-ui-select-options-min-width));
392
+ max-height: var(--svelte-ui-select-options-max-height);
386
393
  overflow-y: auto;
387
394
  }
388
395
 
@@ -397,11 +404,8 @@
397
404
  }
398
405
  }
399
406
 
400
- .multi-select__option-cover {
401
- position: absolute;
402
- inset: 0;
403
- cursor: pointer;
404
- }
405
- .multi-select__option-cover--disabled {
406
- cursor: not-allowed;
407
+ .multi-select__separator {
408
+ height: 0;
409
+ margin: var(--svelte-ui-select-separator-margin);
410
+ border-bottom: solid 1px var(--svelte-ui-select-separator-color);
407
411
  }</style>
@@ -4,8 +4,8 @@ import type { PopupPosition } from '../types/propOptions';
4
4
  export type MultiSelectProps = {
5
5
  /** Selected values array. Supports `bind:value`. */
6
6
  value: OptionValue[];
7
- /** `{ label, value, disabled? }[]` */
8
- options: Option[];
7
+ /** `{ label, value, disabled? }[]` or `'separator'` for dividers. */
8
+ options: (Option | 'separator')[];
9
9
  id?: string | null;
10
10
  ariaLabel?: string;
11
11
  tabindex?: number | null;