@14ch/svelte-ui 0.0.69 → 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.
@@ -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 */
@@ -82,6 +82,13 @@
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
 
@@ -161,7 +168,7 @@
161
168
  aria-required={required ? 'true' : undefined}
162
169
  {tabindex}
163
170
  {disabled}
164
- style={customStyle}
171
+ style={triggerStyle}
165
172
  onfocus={handleFocus}
166
173
  onblur={handleBlur}
167
174
  onclick={handleTriggerClick}
@@ -243,7 +250,6 @@
243
250
  width: 100%;
244
251
  min-height: var(--svelte-ui-select-height);
245
252
  padding: var(--svelte-ui-select-padding);
246
- padding-right: var(--svelte-ui-select-icon-space);
247
253
  background: transparent;
248
254
  border: none;
249
255
  font-family: inherit;
@@ -258,7 +264,6 @@
258
264
  }
259
265
 
260
266
  .multi-select__inner {
261
- position: relative;
262
267
  flex: 1;
263
268
  align-self: stretch;
264
269
  display: flex;
@@ -287,11 +292,9 @@
287
292
  justify-content: center;
288
293
  align-items: center;
289
294
  position: absolute;
290
- top: 0;
295
+ top: 50%;
291
296
  right: 4px;
292
- margin-top: calc((var(--svelte-ui-select-height) - 32px) / 2);
293
- margin-bottom: calc((var(--svelte-ui-select-height) - 32px) / 2);
294
- margin-right: calc(0px - var(--svelte-ui-select-icon-space));
297
+ transform: translateY(-50%);
295
298
  width: 32px;
296
299
  height: 32px;
297
300
  color: var(--svelte-ui-select-dropdown-icon-color);
@@ -352,7 +355,6 @@
352
355
  * ============================================= */
353
356
  .multi-select.multi-select--inline .multi-select__trigger {
354
357
  padding: inherit;
355
- padding-right: var(--svelte-ui-select-icon-space-inline);
356
358
  background: transparent;
357
359
  border: none;
358
360
  border-radius: 0;
@@ -368,9 +370,7 @@
368
370
  .multi-select.multi-select--inline .multi-select__dropdown-icon {
369
371
  top: calc((1lh - 32px) / 2);
370
372
  right: 0;
371
- margin-top: 0;
372
- margin-bottom: 0;
373
- margin-right: calc(0px - var(--svelte-ui-select-icon-space-inline));
373
+ transform: none;
374
374
  }
375
375
 
376
376
  /* =============================================
@@ -168,6 +168,13 @@
168
168
  // =========================================================================
169
169
  // $derived
170
170
  // =========================================================================
171
+ // アイコンの領域は customStyle で消されないよう、customStyle より後ろに指定する
172
+ const triggerStyle = $derived(
173
+ [customStyle, `padding-right: var(--svelte-ui-select-icon-space${inline ? '-inline' : ''})`]
174
+ .filter(Boolean)
175
+ .join('; ')
176
+ );
177
+
171
178
  const fallbackId = `select-${Math.random().toString(36).substring(2, 15)}`;
172
179
  const baseId = $derived(id ?? fallbackId);
173
180
  const listboxId = $derived(`${baseId}-listbox`);
@@ -367,7 +374,7 @@
367
374
  aria-required={required ? 'true' : undefined}
368
375
  {tabindex}
369
376
  {disabled}
370
- style={customStyle}
377
+ style={triggerStyle}
371
378
  onfocus={handleFocus}
372
379
  onblur={handleBlur}
373
380
  onclick={handleTriggerClick}
@@ -486,7 +493,6 @@
486
493
  width: 100%;
487
494
  min-height: var(--svelte-ui-select-height);
488
495
  padding: var(--svelte-ui-select-padding);
489
- padding-right: var(--svelte-ui-select-icon-space);
490
496
  background: transparent;
491
497
  border: none;
492
498
  font-family: inherit;
@@ -499,7 +505,6 @@
499
505
  }
500
506
 
501
507
  .select__inner {
502
- position: relative;
503
508
  flex: 1;
504
509
  align-self: stretch;
505
510
  display: flex;
@@ -525,11 +530,9 @@
525
530
  justify-content: center;
526
531
  align-items: center;
527
532
  position: absolute;
528
- top: 0;
533
+ top: 50%;
529
534
  right: 4px;
530
- margin-top: calc((var(--svelte-ui-select-height) - 32px) / 2);
531
- margin-bottom: calc((var(--svelte-ui-select-height) - 32px) / 2);
532
- margin-right: calc(0px - var(--svelte-ui-select-icon-space));
535
+ transform: translateY(-50%);
533
536
  width: 32px;
534
537
  height: 32px;
535
538
  color: var(--svelte-ui-select-dropdown-icon-color);
@@ -590,7 +593,6 @@
590
593
  * ============================================= */
591
594
  .select.select--inline .select__trigger {
592
595
  padding: inherit;
593
- padding-right: var(--svelte-ui-select-icon-space-inline);
594
596
  background: transparent;
595
597
  border: none;
596
598
  border-radius: 0;
@@ -606,9 +608,7 @@
606
608
  .select.select--inline .select__dropdown-icon {
607
609
  top: calc((1lh - 32px) / 2);
608
610
  right: 0;
609
- margin-top: 0;
610
- margin-bottom: 0;
611
- margin-right: calc(0px - var(--svelte-ui-select-icon-space-inline));
611
+ transform: none;
612
612
  }
613
613
 
614
614
  /* =============================================
@@ -12,6 +12,7 @@
12
12
  KeyboardHandler,
13
13
  BivariantValueHandler
14
14
  } from '../types/callbackHandlers';
15
+ import { getStyleFromNumber } from '../utils/style';
15
16
  import { getCurrentPath, matchPath } from '../utils/navPath';
16
17
  import { subscribeUrlChange } from '../utils/urlChange';
17
18
  import { t } from '../i18n';
@@ -52,6 +53,10 @@
52
53
  size?: ComponentSize;
53
54
  /** 現在/完了ステップの強調色。テーマ色より優先。 */
54
55
  color?: string;
56
+ /** 幅。数値は px として扱う。 */
57
+ width?: string | number | null;
58
+ minWidth?: string | number | null;
59
+ maxWidth?: string | number | null;
55
60
  /** 番号の代わりに各ステップの icon を表示。 @default false */
56
61
  showIcon?: boolean;
57
62
  /** 追加インラインスタイル。 */
@@ -103,6 +108,9 @@
103
108
  orientation = 'horizontal',
104
109
  size = 'medium',
105
110
  color,
111
+ width = null,
112
+ minWidth = null,
113
+ maxWidth = null,
106
114
  showIcon = false,
107
115
  customStyle = '',
108
116
 
@@ -204,12 +212,19 @@
204
212
  .join(' ')
205
213
  );
206
214
 
215
+ const widthStyle = $derived(getStyleFromNumber(width));
216
+ const minWidthStyle = $derived(getStyleFromNumber(minWidth));
217
+ const maxWidthStyle = $derived(getStyleFromNumber(maxWidth));
218
+
207
219
  const rootStyle = $derived(
208
220
  [
209
221
  // color 指定時は強調色を上書き。リングは半透明の色なので同率で合成した値も注入する。
210
222
  color ? `--internal-step-nav-accent:${color}` : '',
211
223
  color ? `--internal-step-nav-ring-color:color-mix(in srgb, ${color} 40%, transparent)` : '',
212
- customStyle
224
+ customStyle,
225
+ widthStyle ? `width: ${widthStyle}` : '',
226
+ minWidthStyle ? `min-width: ${minWidthStyle}` : '',
227
+ maxWidthStyle ? `max-width: ${maxWidthStyle}` : ''
213
228
  ]
214
229
  .filter(Boolean)
215
230
  .join('; ')
@@ -504,14 +519,12 @@ button.step-nav__step {
504
519
 
505
520
  /* upcoming: 淡いアウトライン + 番号 */
506
521
  .step-nav__step--upcoming .step-nav__marker {
507
- background: var(--svelte-ui-surface-color);
508
522
  color: var(--svelte-ui-step-nav-upcoming-text-color);
509
523
  border: var(--svelte-ui-step-nav-marker-border-width) solid var(--svelte-ui-step-nav-upcoming-marker-color);
510
524
  }
511
525
 
512
526
  /* in-progress: primary アウトライン + 番号 */
513
527
  .step-nav__step--in-progress .step-nav__marker {
514
- background: var(--svelte-ui-surface-color);
515
528
  color: var(--internal-step-nav-accent, var(--svelte-ui-step-nav-accent-color));
516
529
  border: var(--svelte-ui-step-nav-marker-border-width) solid var(--internal-step-nav-accent, var(--svelte-ui-step-nav-accent-color));
517
530
  }
@@ -525,14 +538,15 @@ button.step-nav__step {
525
538
 
526
539
  /* error: error 色 + error アイコン(進捗軸を上書き) */
527
540
  .step-nav__step--error .step-nav__marker {
528
- background: var(--svelte-ui-surface-color);
529
541
  color: var(--svelte-ui-step-nav-error-color);
530
542
  border: var(--svelte-ui-step-nav-marker-border-width) solid var(--svelte-ui-step-nav-error-color);
531
543
  }
532
544
 
533
- /* 表示中: 外周リング(フォーカス表示とは別レイヤー・別色) */
545
+ /* 表示中: 外周リング(フォーカス表示とは別レイヤー・別色)。
546
+ リングとマーカーの隙間に背景が透けるよう、box-shadow ではなく outline で描く */
534
547
  .step-nav__step--viewing .step-nav__marker {
535
- box-shadow: 0 0 0 var(--svelte-ui-step-nav-ring-offset) var(--svelte-ui-surface-color), 0 0 0 calc(var(--svelte-ui-step-nav-ring-offset) + var(--svelte-ui-step-nav-ring-width)) var(--internal-step-nav-ring-color, var(--svelte-ui-step-nav-ring-color));
548
+ outline: var(--svelte-ui-step-nav-ring-width) solid var(--internal-step-nav-ring-color, var(--svelte-ui-step-nav-ring-color));
549
+ outline-offset: var(--svelte-ui-step-nav-ring-offset);
536
550
  }
537
551
 
538
552
  /* ---- ラベル/説明 ---- */
@@ -31,6 +31,10 @@ export type StepNavProps = {
31
31
  size?: ComponentSize;
32
32
  /** 現在/完了ステップの強調色。テーマ色より優先。 */
33
33
  color?: string;
34
+ /** 幅。数値は px として扱う。 */
35
+ width?: string | number | null;
36
+ minWidth?: string | number | null;
37
+ maxWidth?: string | number | null;
34
38
  /** 番号の代わりに各ステップの icon を表示。 @default false */
35
39
  showIcon?: boolean;
36
40
  /** 追加インラインスタイル。 */
@@ -469,13 +469,18 @@
469
469
  const width = rect.width;
470
470
  if (!height || !width) return;
471
471
 
472
+ // 箱(ルート)は padding を持つため、textarea の実寸に padding 分を足す
473
+ const rootStyle = getComputedStyle(containerRef);
474
+ const paddingY = parseFloat(rootStyle.paddingTop) + parseFloat(rootStyle.paddingBottom);
475
+ const paddingX = parseFloat(rootStyle.paddingLeft) + parseFloat(rootStyle.paddingRight);
476
+
472
477
  // コンポーネント全体の高さは textarea に合わせる
473
- containerRef.style.height = `${height}px`;
478
+ containerRef.style.height = `${height + paddingY}px`;
474
479
 
475
480
  // 幅は、初期状態では width プロップを優先し、
476
481
  // ユーザーがリサイズ(ResizeObserver 経由)したあとは textarea の幅で上書きする
477
482
  if (forceWidth || !widthStyle) {
478
- containerRef.style.width = `${width}px`;
483
+ containerRef.style.width = `${width + paddingX}px`;
479
484
  }
480
485
 
481
486
  // display-text / link-text はコンテナにフィットさせる
@@ -549,6 +554,27 @@
549
554
  );
550
555
  const maxHeightStyle = $derived(getStyleFromNumber(maxHeight));
551
556
  const widthStyle = $derived(getStyleFromNumber(width));
557
+ // 箱(ルート)は border-box、内側のテキスト層は padding を持たないので縦 padding を差し引く
558
+ const innerMinHeightStyle = $derived(
559
+ `calc(${minHeightStyle} - var(--internal-textarea-vertical-padding))`
560
+ );
561
+ const innerMaxHeightStyle = $derived(
562
+ maxHeightStyle
563
+ ? `calc(${maxHeightStyle} - var(--internal-textarea-vertical-padding))`
564
+ : undefined
565
+ );
566
+ // アイコンの領域は customStyle で消されないよう、customStyle より後ろに指定する。
567
+ // style: ディレクティブは style 属性に勝つため、幅・最大高さも同じ文字列に混ぜる
568
+ const boxStyle = $derived(
569
+ [
570
+ customStyle,
571
+ clearable ? 'padding-right: var(--svelte-ui-textarea-icon-space)' : '',
572
+ widthStyle ? `width: ${widthStyle}` : '',
573
+ !inline && maxHeightStyle ? `max-height: ${maxHeightStyle}` : ''
574
+ ]
575
+ .filter(Boolean)
576
+ .join('; ')
577
+ );
552
578
  </script>
553
579
 
554
580
  <div
@@ -567,16 +593,14 @@
567
593
  class:textarea--readonly={readonly}
568
594
  class:textarea--focused={isFocused}
569
595
  data-testid="textarea"
570
- style:width={widthStyle}
571
- style:max-height={!inline ? maxHeightStyle : undefined}
596
+ style={boxStyle}
572
597
  >
573
598
  <div
574
599
  bind:this={displayTextRef}
575
600
  class="textarea__display-text"
576
601
  class:textarea__display-text--placeholder={!hasDisplayValue}
577
- style:min-height={minHeightStyle}
578
- style:max-height={maxHeightStyle}
579
- style={customStyle}
602
+ style:min-height={innerMinHeightStyle}
603
+ style:max-height={innerMaxHeightStyle}
580
604
  >
581
605
  {@html displayValue}
582
606
  </div>
@@ -599,8 +623,7 @@
599
623
  {spellcheck}
600
624
  {autocapitalize}
601
625
  class:resizable
602
- style:min-height={minHeightStyle}
603
- style={customStyle}
626
+ style:min-height={innerMinHeightStyle}
604
627
  onchange={handleChange}
605
628
  oninput={handleInput}
606
629
  onfocus={handleFocus}
@@ -634,9 +657,8 @@
634
657
  <div
635
658
  bind:this={linkTextRef}
636
659
  class="textarea__link-text"
637
- style:min-height={minHeightStyle}
638
- style:max-height={maxHeightStyle}
639
- style={customStyle}
660
+ style:min-height={innerMinHeightStyle}
661
+ style:max-height={innerMaxHeightStyle}
640
662
  >
641
663
  {@html linkHtmlValue}
642
664
  </div>
@@ -670,6 +692,13 @@
670
692
  width: auto;
671
693
  max-width: 100%;
672
694
  overflow: hidden;
695
+ --internal-textarea-vertical-padding: calc(
696
+ var(--svelte-ui-textarea-min-height) - var(--svelte-ui-textarea-line-height)
697
+ );
698
+ padding: var(--svelte-ui-textarea-padding);
699
+ background-color: var(--svelte-ui-textarea-bg);
700
+ box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-textarea-border-color);
701
+ border-radius: var(--svelte-ui-textarea-border-radius);
673
702
 
674
703
  &.textarea--full-height {
675
704
  height: 100%;
@@ -684,9 +713,8 @@
684
713
  height: 100%;
685
714
  padding: inherit;
686
715
  border: none;
687
- border-radius: var(--svelte-ui-textarea-border-radius);
688
- background-color: var(--svelte-ui-textarea-bg);
689
- box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-textarea-border-color);
716
+ border-radius: inherit;
717
+ background-color: transparent;
690
718
  font-size: inherit;
691
719
  font-weight: inherit;
692
720
  color: inherit;
@@ -700,11 +728,11 @@
700
728
  textarea {
701
729
  width: 100%;
702
730
  height: auto;
703
- min-height: var(--svelte-ui-textarea-min-height);
704
- padding: var(--svelte-ui-textarea-padding);
731
+ min-height: var(--svelte-ui-textarea-line-height);
732
+ padding: 0;
705
733
  background-color: transparent;
706
734
  border: none;
707
- border-radius: var(--svelte-ui-textarea-border-radius);
735
+ border-radius: inherit;
708
736
  font-family: inherit;
709
737
  font-size: inherit;
710
738
  font-weight: inherit;
@@ -724,10 +752,10 @@
724
752
  .textarea__link-text {
725
753
  display: block;
726
754
  width: 100%;
727
- min-height: var(--svelte-ui-textarea-min-height);
728
- padding: var(--svelte-ui-textarea-padding);
729
- background: inherit;
730
- border: inherit;
755
+ min-height: var(--svelte-ui-textarea-line-height);
756
+ padding: 0;
757
+ background: transparent;
758
+ border: none;
731
759
  font-size: inherit;
732
760
  font-weight: inherit;
733
761
  color: inherit;
@@ -774,6 +802,7 @@
774
802
  left: 0;
775
803
  width: 100%;
776
804
  height: 100%;
805
+ padding: inherit;
777
806
  pointer-events: none;
778
807
  z-index: 1;
779
808
  }
@@ -818,7 +847,11 @@
818
847
  /* =============================================
819
848
  * フォーカス効果バリエーション
820
849
  * ============================================= */
821
- .textarea--focus-outline textarea:focus {
850
+ textarea:focus {
851
+ outline: none;
852
+ }
853
+
854
+ .textarea--focus-outline.textarea--focused .textarea__wrapper {
822
855
  outline: var(--svelte-ui-focus-outline-inner);
823
856
  outline-offset: var(--svelte-ui-focus-outline-offset-inner);
824
857
  }
@@ -827,14 +860,6 @@
827
860
  background: var(--svelte-ui-hover-overlay);
828
861
  }
829
862
 
830
- .textarea--focus-background textarea:focus {
831
- outline: none;
832
- }
833
-
834
- .textarea--focus-none textarea:focus {
835
- outline: none;
836
- }
837
-
838
863
  /* =============================================
839
864
  * 状態管理(disabled, readonly等)
840
865
  * ============================================= */
@@ -853,7 +878,7 @@
853
878
  /* =============================================
854
879
  * 表示切り替え
855
880
  * ============================================= */
856
- /* 非フォーカス時: textarea要素自体を不可視化(枠線・背景はラッパーにあるため display-text のみ表示) */
881
+ /* 非フォーカス時: textarea要素自体を不可視化(枠線・背景はルートにあるため display-text のみ表示) */
857
882
  .textarea:not(.textarea--focused) textarea {
858
883
  opacity: 0;
859
884
  }
@@ -868,14 +893,6 @@
868
893
  * 機能バリエーション
869
894
  * ============================================= */
870
895
  /* clearable */
871
- .textarea--clearable {
872
- textarea,
873
- .textarea__display-text,
874
- .textarea__link-text {
875
- padding-right: var(--svelte-ui-textarea-icon-space);
876
- }
877
- }
878
-
879
896
  @media (hover: hover) {
880
897
  .textarea--clearable:hover .textarea__clear-button {
881
898
  opacity: 1;
@@ -913,29 +930,22 @@
913
930
  * デザインバリエーション
914
931
  * ============================================= */
915
932
  /* rounded */
916
- .textarea--rounded:not(.textarea--inline) .textarea__wrapper,
917
- .textarea--rounded:not(.textarea--inline) textarea {
933
+ .textarea--rounded:not(.textarea--inline) {
918
934
  border-radius: var(--svelte-ui-textarea-border-radius-rounded);
919
935
  }
920
936
 
921
937
  /* inline */
922
938
  .textarea--inline {
939
+ --internal-textarea-vertical-padding: 0px;
940
+ padding: 0;
941
+ background-color: transparent;
942
+ box-shadow: none;
943
+ border-radius: 0;
944
+
923
945
  .textarea__display-text,
924
946
  .textarea__link-text,
925
947
  textarea {
926
948
  min-height: auto;
927
- padding-top: inherit;
928
- padding-bottom: inherit;
929
- padding-left: inherit;
930
- padding-right: inherit;
931
- }
932
-
933
- .textarea__wrapper,
934
- textarea {
935
- padding: inherit;
936
- background: transparent;
937
- box-shadow: none;
938
- border-radius: 0;
939
949
  }
940
950
 
941
951
  textarea {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@14ch/svelte-ui",
3
3
  "description": "Modern Svelte UI components library with TypeScript support",
4
4
  "private": false,
5
- "version": "0.0.69",
5
+ "version": "0.0.70",
6
6
  "type": "module",
7
7
  "keywords": [
8
8
  "svelte",