@14ch/svelte-ui 0.0.7 → 0.0.9
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/components/ColorPicker.svelte +0 -1
- package/dist/components/Combobox.svelte +2 -3
- package/dist/components/DatepickerCalendar.svelte +26 -11
- package/dist/components/Dialog.svelte +20 -9
- package/dist/components/Drawer.svelte +1 -3
- package/dist/components/Input.svelte +93 -12
- package/dist/components/Input.svelte.d.ts +1 -0
- package/dist/components/SegmentedControl.svelte +4 -0
- package/dist/components/SnackbarItem.svelte +146 -37
- package/dist/components/Textarea.svelte +73 -11
- package/dist/components/Textarea.svelte.d.ts +1 -0
- package/package.json +1 -1
|
@@ -155,7 +155,6 @@
|
|
|
155
155
|
let popupRef = $state<any>();
|
|
156
156
|
let highlightedIndex = $state(-1);
|
|
157
157
|
let isFocused = $state(false);
|
|
158
|
-
let comboboxRef = $state<HTMLDivElement>();
|
|
159
158
|
|
|
160
159
|
// 各要素のIDを生成
|
|
161
160
|
const inputId = `${id}-input`;
|
|
@@ -479,9 +478,9 @@
|
|
|
479
478
|
type="button"
|
|
480
479
|
class="combobox__option"
|
|
481
480
|
class:combobox__option--highlighted={index === highlightedIndex}
|
|
482
|
-
class:combobox__option--selected={option ===
|
|
481
|
+
class:combobox__option--selected={option === inputValue}
|
|
483
482
|
role="option"
|
|
484
|
-
aria-selected={option ===
|
|
483
|
+
aria-selected={option === inputValue}
|
|
485
484
|
onmousedown={(event) => {
|
|
486
485
|
event?.preventDefault?.();
|
|
487
486
|
event?.stopPropagation?.();
|
|
@@ -366,12 +366,23 @@
|
|
|
366
366
|
}
|
|
367
367
|
};
|
|
368
368
|
|
|
369
|
+
const getNormalizedRange = () => {
|
|
370
|
+
if (mode !== 'range' || !value || !('start' in value && 'end' in value)) return null;
|
|
371
|
+
|
|
372
|
+
const startDate = dayjs(value.start).startOf('day');
|
|
373
|
+
const endDate = dayjs(value.end).startOf('day');
|
|
374
|
+
|
|
375
|
+
if (startDate.isSameOrBefore(endDate)) {
|
|
376
|
+
return { start: startDate, end: endDate };
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return { start: endDate, end: startDate };
|
|
380
|
+
};
|
|
381
|
+
|
|
369
382
|
const isSelected = (date: dayjs.Dayjs) => {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
dayjs(date).isSameOrBefore(dayjs(value.end).startOf('day'))
|
|
374
|
-
);
|
|
383
|
+
const range = getNormalizedRange();
|
|
384
|
+
if (range) {
|
|
385
|
+
return dayjs(date).isSameOrAfter(range.start) && dayjs(date).isSameOrBefore(range.end);
|
|
375
386
|
} else if (mode === 'single' && value && value instanceof Date) {
|
|
376
387
|
return dayjs(date).isSame(dayjs(value).startOf('day'));
|
|
377
388
|
}
|
|
@@ -379,25 +390,29 @@
|
|
|
379
390
|
};
|
|
380
391
|
|
|
381
392
|
const isRangeStart = (date: dayjs.Dayjs) => {
|
|
382
|
-
|
|
393
|
+
const range = getNormalizedRange();
|
|
394
|
+
if (!range) return false;
|
|
383
395
|
if (isRangePreviewActive) return false;
|
|
384
|
-
return dayjs(date).isSame(
|
|
396
|
+
return dayjs(date).isSame(range.start);
|
|
385
397
|
};
|
|
386
398
|
|
|
387
399
|
const isRangeEnd = (date: dayjs.Dayjs) => {
|
|
388
|
-
|
|
400
|
+
const range = getNormalizedRange();
|
|
401
|
+
if (!range) return false;
|
|
389
402
|
if (isRangePreviewActive) return false;
|
|
390
|
-
return dayjs(date).isSame(
|
|
403
|
+
return dayjs(date).isSame(range.end);
|
|
391
404
|
};
|
|
392
405
|
|
|
393
406
|
const isRangeMiddle = (date: dayjs.Dayjs) => {
|
|
394
|
-
|
|
407
|
+
const range = getNormalizedRange();
|
|
408
|
+
if (!range) return false;
|
|
395
409
|
if (isRangePreviewActive) return false;
|
|
396
410
|
return isSelected(date) && !isRangeStart(date) && !isRangeEnd(date);
|
|
397
411
|
};
|
|
398
412
|
|
|
399
413
|
const isRangeSingle = (date: dayjs.Dayjs) => {
|
|
400
|
-
|
|
414
|
+
const range = getNormalizedRange();
|
|
415
|
+
if (!range) return false;
|
|
401
416
|
if (isRangePreviewActive) return false;
|
|
402
417
|
return isRangeStart(date) && isRangeEnd(date);
|
|
403
418
|
};
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
return styles.join('; ');
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
const dialogClasses = $derived(
|
|
118
|
+
const dialogClasses = $derived('');
|
|
119
119
|
|
|
120
120
|
const ariaLabelledby = $derived(title ? 'dialog-title' : undefined);
|
|
121
121
|
const ariaDescribedbyValue = $derived(
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
customStyles={dialogStyles}
|
|
137
137
|
id={id ? `${id}-modal` : undefined}
|
|
138
138
|
>
|
|
139
|
-
<div class="dialog {scrollable ? 'scrollable' : ''}">
|
|
139
|
+
<div class="dialog {scrollable ? 'dialog--scrollable' : ''}">
|
|
140
140
|
{#if header || title}
|
|
141
141
|
<div class="dialog__header">
|
|
142
142
|
{#if header}
|
|
@@ -166,14 +166,15 @@
|
|
|
166
166
|
</div>
|
|
167
167
|
</Modal>
|
|
168
168
|
|
|
169
|
-
<style
|
|
169
|
+
<style>@charset "UTF-8";
|
|
170
|
+
.dialog {
|
|
170
171
|
display: flex;
|
|
171
172
|
flex-direction: column;
|
|
172
173
|
justify-content: stretch;
|
|
173
|
-
max-height: calc(100dvh - 2em - 6px);
|
|
174
174
|
border: var(--svelte-ui-dialog-border);
|
|
175
175
|
border-radius: var(--svelte-ui-dialog-border-radius);
|
|
176
|
-
|
|
176
|
+
max-height: calc(100dvh - 2em - 6px);
|
|
177
|
+
overflow: auto;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
.dialog__header {
|
|
@@ -183,7 +184,6 @@
|
|
|
183
184
|
justify-content: stretch;
|
|
184
185
|
min-height: var(--svelte-ui-dialog-header-height);
|
|
185
186
|
padding: var(--svelte-ui-dialog-padding);
|
|
186
|
-
margin-bottom: calc(0px - var(--svelte-ui-dialog-body-padding));
|
|
187
187
|
}
|
|
188
188
|
.dialog__header .dialog__title {
|
|
189
189
|
flex-grow: 1;
|
|
@@ -214,15 +214,26 @@
|
|
|
214
214
|
border-bottom: 1px solid var(--svelte-ui-border-weak-color);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
/* scrollable=true 時: ヘッダー/フッター固定 + bodyのみスクロール */
|
|
218
|
+
.dialog--scrollable {
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.dialog--scrollable .dialog__header {
|
|
218
223
|
margin-bottom: 0;
|
|
219
224
|
border-bottom: solid var(--svelte-ui-border-width, 1px) var(--svelte-ui-border-weak-color);
|
|
220
225
|
}
|
|
221
|
-
|
|
226
|
+
|
|
227
|
+
.dialog--scrollable .dialog__body {
|
|
222
228
|
flex-shrink: 1;
|
|
223
229
|
padding: var(--svelte-ui-dialog-body-padding);
|
|
224
230
|
overflow: auto;
|
|
225
231
|
}
|
|
226
|
-
|
|
232
|
+
|
|
233
|
+
.dialog:not(.dialog--scrollable) .dialog__body {
|
|
234
|
+
padding-top: 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.dialog--scrollable .dialog__footer {
|
|
227
238
|
border-top: solid var(--svelte-ui-border-width, 1px) var(--svelte-ui-border-weak-color);
|
|
228
239
|
}</style>
|
|
@@ -123,9 +123,7 @@
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
const drawerClasses = $derived(
|
|
126
|
-
['drawer-wrapper', `drawer-wrapper--${position}
|
|
127
|
-
.filter(Boolean)
|
|
128
|
-
.join(' ')
|
|
126
|
+
['drawer-wrapper', `drawer-wrapper--${position}`].filter(Boolean).join(' ')
|
|
129
127
|
);
|
|
130
128
|
|
|
131
129
|
const ariaLabelledby = $derived(title ? 'drawer-title' : undefined);
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
8
8
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
9
9
|
import { t } from '../i18n';
|
|
10
|
+
import { convertToHtmlWithLink } from '../utils/formatText';
|
|
10
11
|
|
|
11
12
|
// =========================================================================
|
|
12
13
|
// Props, States & Constants
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
required = false,
|
|
59
60
|
clearable = false,
|
|
60
61
|
clearButtonAriaLabel = t('input.clear'),
|
|
62
|
+
linkify = false,
|
|
61
63
|
|
|
62
64
|
// フォーカスイベント
|
|
63
65
|
onfocus = () => {}, // No params for type inference
|
|
@@ -148,6 +150,7 @@
|
|
|
148
150
|
readonly?: boolean;
|
|
149
151
|
required?: boolean;
|
|
150
152
|
clearable?: boolean;
|
|
153
|
+
linkify?: boolean;
|
|
151
154
|
|
|
152
155
|
// フォーカスイベント
|
|
153
156
|
onfocus?: Function; // No params for type inference
|
|
@@ -374,6 +377,12 @@
|
|
|
374
377
|
return String(value);
|
|
375
378
|
};
|
|
376
379
|
|
|
380
|
+
const linkHtmlValue = $derived.by(() => {
|
|
381
|
+
if (!linkify) return '';
|
|
382
|
+
const result = convertToHtmlWithLink(getDisplayValue());
|
|
383
|
+
return typeof result === 'string' ? result : String(result ?? '');
|
|
384
|
+
});
|
|
385
|
+
|
|
377
386
|
const widthStyle = $derived(getStyleFromNumber(width));
|
|
378
387
|
const maxWidthStyle = $derived(getStyleFromNumber(maxWidth));
|
|
379
388
|
const minWidthStyle = $derived(getStyleFromNumber(minWidth));
|
|
@@ -384,6 +393,7 @@
|
|
|
384
393
|
input--focus-{focusStyle}
|
|
385
394
|
input--type-{type}"
|
|
386
395
|
class:input--inline={inline}
|
|
396
|
+
class:input--linkify={linkify}
|
|
387
397
|
class:input--auto-resize={inline}
|
|
388
398
|
class:input--full-width={fullWidth}
|
|
389
399
|
class:input--clearable={clearable}
|
|
@@ -456,6 +466,11 @@
|
|
|
456
466
|
{...restProps}
|
|
457
467
|
/>
|
|
458
468
|
</div>
|
|
469
|
+
{#if linkify}
|
|
470
|
+
<div class="input__link-text" style={customStyle}>
|
|
471
|
+
{@html linkHtmlValue}
|
|
472
|
+
</div>
|
|
473
|
+
{/if}
|
|
459
474
|
<!-- クリアボタン -->
|
|
460
475
|
{#if clearable && !disabled && !readonly}
|
|
461
476
|
<div class="input__clear-button">
|
|
@@ -613,6 +628,35 @@
|
|
|
613
628
|
}
|
|
614
629
|
}
|
|
615
630
|
|
|
631
|
+
/* リンク表示用オーバーレイ */
|
|
632
|
+
.input__link-text {
|
|
633
|
+
position: absolute;
|
|
634
|
+
top: 0;
|
|
635
|
+
left: 0;
|
|
636
|
+
width: 100%;
|
|
637
|
+
height: 100%;
|
|
638
|
+
display: flex;
|
|
639
|
+
align-items: center;
|
|
640
|
+
padding: inherit;
|
|
641
|
+
background: transparent;
|
|
642
|
+
border-radius: inherit;
|
|
643
|
+
font-size: inherit;
|
|
644
|
+
font-weight: inherit;
|
|
645
|
+
color: inherit;
|
|
646
|
+
line-height: inherit;
|
|
647
|
+
text-align: inherit;
|
|
648
|
+
white-space: nowrap;
|
|
649
|
+
overflow: hidden;
|
|
650
|
+
text-overflow: ellipsis;
|
|
651
|
+
pointer-events: none;
|
|
652
|
+
z-index: 1;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.input__link-text :global(a) {
|
|
656
|
+
pointer-events: auto;
|
|
657
|
+
text-decoration: underline;
|
|
658
|
+
}
|
|
659
|
+
|
|
616
660
|
.input__clear-button {
|
|
617
661
|
position: absolute;
|
|
618
662
|
top: 50%;
|
|
@@ -695,7 +739,6 @@
|
|
|
695
739
|
|
|
696
740
|
input {
|
|
697
741
|
min-height: var(--svelte-ui-input-height);
|
|
698
|
-
padding: var(--svelte-ui-input-padding);
|
|
699
742
|
background-color: var(--svelte-ui-input-bg);
|
|
700
743
|
box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-input-border-color);
|
|
701
744
|
border: none;
|
|
@@ -703,30 +746,40 @@
|
|
|
703
746
|
color: var(--svelte-ui-input-text-color);
|
|
704
747
|
}
|
|
705
748
|
|
|
749
|
+
input,
|
|
750
|
+
.input__display-text,
|
|
751
|
+
.input__link-text {
|
|
752
|
+
padding: var(--svelte-ui-input-padding);
|
|
753
|
+
}
|
|
754
|
+
|
|
706
755
|
&.input--has-left-icon {
|
|
707
756
|
input,
|
|
708
|
-
.input__display-text
|
|
757
|
+
.input__display-text,
|
|
758
|
+
.input__link-text {
|
|
709
759
|
padding-left: var(--svelte-ui-input-icon-space);
|
|
710
760
|
}
|
|
711
761
|
}
|
|
712
762
|
|
|
713
763
|
&.input--has-right-icon {
|
|
714
764
|
input,
|
|
715
|
-
.input__display-text
|
|
765
|
+
.input__display-text,
|
|
766
|
+
.input__link-text {
|
|
716
767
|
padding-right: var(--svelte-ui-input-icon-space);
|
|
717
768
|
}
|
|
718
769
|
}
|
|
719
770
|
|
|
720
771
|
&.input--clearable {
|
|
721
772
|
input,
|
|
722
|
-
.input__display-text
|
|
773
|
+
.input__display-text,
|
|
774
|
+
.input__link-text {
|
|
723
775
|
padding-right: var(--svelte-ui-input-icon-space);
|
|
724
776
|
}
|
|
725
777
|
}
|
|
726
778
|
|
|
727
779
|
&.input--clearable.input--has-right-icon {
|
|
728
780
|
input,
|
|
729
|
-
.input__display-text
|
|
781
|
+
.input__display-text,
|
|
782
|
+
.input__link-text {
|
|
730
783
|
padding-right: var(--svelte-ui-input-icon-space-double);
|
|
731
784
|
}
|
|
732
785
|
}
|
|
@@ -741,6 +794,18 @@
|
|
|
741
794
|
}
|
|
742
795
|
}
|
|
743
796
|
|
|
797
|
+
/* linkify=true かつフォーカスがないときは、input のテキストカラーだけ透明にして二重描画を防ぐ */
|
|
798
|
+
.input--linkify:not(.input--focused) input {
|
|
799
|
+
color: transparent;
|
|
800
|
+
caret-color: transparent;
|
|
801
|
+
text-shadow: none;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/* フォーカス時はリンク用オーバーレイも非表示にして(display:none)、リンクが反応しないようにする */
|
|
805
|
+
.input--focused .input__link-text {
|
|
806
|
+
display: none;
|
|
807
|
+
}
|
|
808
|
+
|
|
744
809
|
/* =============================================
|
|
745
810
|
* デザインバリアント:inline
|
|
746
811
|
* ============================================= */
|
|
@@ -759,28 +824,32 @@
|
|
|
759
824
|
|
|
760
825
|
&.input--has-left-icon {
|
|
761
826
|
input,
|
|
762
|
-
.input__display-text
|
|
827
|
+
.input__display-text,
|
|
828
|
+
.input__link-text {
|
|
763
829
|
padding-left: var(--svelte-ui-input-icon-space-inline);
|
|
764
830
|
}
|
|
765
831
|
}
|
|
766
832
|
|
|
767
833
|
&.input--has-right-icon {
|
|
768
834
|
input,
|
|
769
|
-
.input__display-text
|
|
835
|
+
.input__display-text,
|
|
836
|
+
.input__link-text {
|
|
770
837
|
padding-right: var(--svelte-ui-input-icon-space-inline);
|
|
771
838
|
}
|
|
772
839
|
}
|
|
773
840
|
|
|
774
841
|
&.input--clearable {
|
|
775
842
|
input,
|
|
776
|
-
.input__display-text
|
|
843
|
+
.input__display-text,
|
|
844
|
+
.input__link-text {
|
|
777
845
|
padding-right: var(--svelte-ui-input-icon-space-inline);
|
|
778
846
|
}
|
|
779
847
|
}
|
|
780
848
|
|
|
781
849
|
&.input--clearable.input--has-right-icon {
|
|
782
850
|
input,
|
|
783
|
-
.input__display-text
|
|
851
|
+
.input__display-text,
|
|
852
|
+
.input__link-text {
|
|
784
853
|
padding-right: var(--svelte-ui-input-icon-space-double-inline);
|
|
785
854
|
}
|
|
786
855
|
}
|
|
@@ -796,6 +865,15 @@
|
|
|
796
865
|
}
|
|
797
866
|
}
|
|
798
867
|
|
|
868
|
+
/* inline + linkify のときは、display-text を常に隠し、wrapper を常に表示 */
|
|
869
|
+
.input--inline.input--linkify .input__display-text {
|
|
870
|
+
opacity: 0;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.input--inline.input--linkify .input__wrapper {
|
|
874
|
+
opacity: 1;
|
|
875
|
+
}
|
|
876
|
+
|
|
799
877
|
/* =============================================
|
|
800
878
|
* レイアウトバリエーション
|
|
801
879
|
* ============================================= */
|
|
@@ -812,21 +890,24 @@
|
|
|
812
890
|
* ============================================= */
|
|
813
891
|
.input--clearable {
|
|
814
892
|
input,
|
|
815
|
-
.input__display-text
|
|
893
|
+
.input__display-text,
|
|
894
|
+
.input__link-text {
|
|
816
895
|
padding-right: var(--svelte-ui-input-icon-space);
|
|
817
896
|
}
|
|
818
897
|
}
|
|
819
898
|
|
|
820
899
|
.input.input--has-right-icon {
|
|
821
900
|
input,
|
|
822
|
-
.input__display-text
|
|
901
|
+
.input__display-text,
|
|
902
|
+
.input__link-text {
|
|
823
903
|
padding-right: var(--svelte-ui-input-icon-space);
|
|
824
904
|
}
|
|
825
905
|
}
|
|
826
906
|
|
|
827
907
|
.input.input--has-left-icon {
|
|
828
908
|
input,
|
|
829
|
-
.input__display-text
|
|
909
|
+
.input__display-text,
|
|
910
|
+
.input__link-text {
|
|
830
911
|
padding-left: var(--svelte-ui-input-icon-space);
|
|
831
912
|
}
|
|
832
913
|
}
|
|
@@ -528,6 +528,10 @@
|
|
|
528
528
|
color: var(--svelte-ui-text-subtle-color, var(--svelte-ui-text-color));
|
|
529
529
|
white-space: nowrap;
|
|
530
530
|
cursor: pointer;
|
|
531
|
+
user-select: none;
|
|
532
|
+
-webkit-user-select: none;
|
|
533
|
+
-moz-user-select: none;
|
|
534
|
+
-ms-user-select: none;
|
|
531
535
|
transition-property: background-color, color;
|
|
532
536
|
transition-duration: var(--svelte-ui-transition-duration, 0.2s);
|
|
533
537
|
transition-timing-function: ease;
|
|
@@ -112,7 +112,10 @@
|
|
|
112
112
|
);
|
|
113
113
|
const requiredMargin = -containerHeight;
|
|
114
114
|
|
|
115
|
-
snackbarRef.style.setProperty(
|
|
115
|
+
snackbarRef.style.setProperty(
|
|
116
|
+
'--svelte-ui-snackbar-item-collapse-margin',
|
|
117
|
+
`${requiredMargin}px`
|
|
118
|
+
);
|
|
116
119
|
|
|
117
120
|
// CSSカスタムプロパティが確実に設定されるまで少し待つ
|
|
118
121
|
requestAnimationFrame(() => {
|
|
@@ -149,7 +152,8 @@
|
|
|
149
152
|
class="snackbar-item__content snackbar-item__content--{type} snackbar-item__content--{variant} snackbar-item__content--{position} {visible
|
|
150
153
|
? 'snackbar-item__content--visible'
|
|
151
154
|
: ''}"
|
|
152
|
-
style="--svelte-ui-snackbar-item-custom-color: {color ??
|
|
155
|
+
style="--svelte-ui-snackbar-item-custom-color: {color ??
|
|
156
|
+
'unset'}; --svelte-ui-snackbar-item-custom-text-color: {textColor ?? 'unset'};"
|
|
153
157
|
role={type === 'error' || type === 'warning' ? 'alert' : 'status'}
|
|
154
158
|
aria-live={type === 'error' || type === 'warning' ? 'assertive' : 'polite'}
|
|
155
159
|
aria-atomic="true"
|
|
@@ -321,103 +325,208 @@
|
|
|
321
325
|
|
|
322
326
|
/* Type variants - filled */
|
|
323
327
|
.snackbar-item__content--filled.snackbar-item__content--info {
|
|
324
|
-
background-color: var(
|
|
325
|
-
|
|
328
|
+
background-color: var(
|
|
329
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
330
|
+
var(--svelte-ui-snackbar-info-filled-bg)
|
|
331
|
+
);
|
|
332
|
+
color: var(
|
|
333
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
334
|
+
var(--svelte-ui-snackbar-info-filled-text-color)
|
|
335
|
+
);
|
|
326
336
|
}
|
|
327
337
|
|
|
328
338
|
.snackbar-item__content--filled.snackbar-item__content--info .snackbar-item__icon {
|
|
329
|
-
color: var(
|
|
339
|
+
color: var(
|
|
340
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
341
|
+
var(--svelte-ui-snackbar-info-filled-text-color)
|
|
342
|
+
);
|
|
330
343
|
}
|
|
331
344
|
|
|
332
345
|
.snackbar-item__content--filled.snackbar-item__content--success {
|
|
333
|
-
background-color: var(
|
|
334
|
-
|
|
346
|
+
background-color: var(
|
|
347
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
348
|
+
var(--svelte-ui-snackbar-success-filled-bg)
|
|
349
|
+
);
|
|
350
|
+
color: var(
|
|
351
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
352
|
+
var(--svelte-ui-snackbar-success-filled-text-color)
|
|
353
|
+
);
|
|
335
354
|
}
|
|
336
355
|
|
|
337
356
|
.snackbar-item__content--filled.snackbar-item__content--success .snackbar-item__icon {
|
|
338
|
-
color: var(
|
|
357
|
+
color: var(
|
|
358
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
359
|
+
var(--svelte-ui-snackbar-success-filled-text-color)
|
|
360
|
+
);
|
|
339
361
|
}
|
|
340
362
|
|
|
341
363
|
.snackbar-item__content--filled.snackbar-item__content--warning {
|
|
342
|
-
background-color: var(
|
|
343
|
-
|
|
364
|
+
background-color: var(
|
|
365
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
366
|
+
var(--svelte-ui-snackbar-warning-filled-bg)
|
|
367
|
+
);
|
|
368
|
+
color: var(
|
|
369
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
370
|
+
var(--svelte-ui-snackbar-warning-filled-text-color)
|
|
371
|
+
);
|
|
344
372
|
}
|
|
345
373
|
|
|
346
374
|
.snackbar-item__content--filled.snackbar-item__content--warning .snackbar-item__icon {
|
|
347
|
-
color: var(
|
|
375
|
+
color: var(
|
|
376
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
377
|
+
var(--svelte-ui-snackbar-warning-filled-text-color)
|
|
378
|
+
);
|
|
348
379
|
}
|
|
349
380
|
|
|
350
381
|
.snackbar-item__content--filled.snackbar-item__content--error {
|
|
351
|
-
background-color: var(
|
|
352
|
-
|
|
382
|
+
background-color: var(
|
|
383
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
384
|
+
var(--svelte-ui-snackbar-error-filled-bg)
|
|
385
|
+
);
|
|
386
|
+
color: var(
|
|
387
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
388
|
+
var(--svelte-ui-snackbar-error-filled-text-color)
|
|
389
|
+
);
|
|
353
390
|
}
|
|
354
391
|
|
|
355
392
|
.snackbar-item__content--filled.snackbar-item__content--error .snackbar-item__icon {
|
|
356
|
-
color: var(
|
|
393
|
+
color: var(
|
|
394
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
395
|
+
var(--svelte-ui-snackbar-error-filled-text-color)
|
|
396
|
+
);
|
|
357
397
|
}
|
|
358
398
|
|
|
359
399
|
.snackbar-item__content--filled.snackbar-item__content--default {
|
|
360
|
-
background-color: var(
|
|
361
|
-
|
|
400
|
+
background-color: var(
|
|
401
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
402
|
+
var(--svelte-ui-snackbar-default-filled-bg)
|
|
403
|
+
);
|
|
404
|
+
color: var(
|
|
405
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
406
|
+
var(--svelte-ui-snackbar-default-filled-text-color)
|
|
407
|
+
);
|
|
362
408
|
}
|
|
363
409
|
|
|
364
410
|
.snackbar-item__content--filled.snackbar-item__content--default .snackbar-item__icon {
|
|
365
|
-
color: var(
|
|
411
|
+
color: var(
|
|
412
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
413
|
+
var(--svelte-ui-snackbar-default-filled-text-color)
|
|
414
|
+
);
|
|
366
415
|
}
|
|
367
416
|
|
|
368
417
|
/* Type variants - outlined */
|
|
369
418
|
.snackbar-item__content--outlined.snackbar-item__content--info {
|
|
370
|
-
background-color: var(
|
|
371
|
-
|
|
419
|
+
background-color: var(
|
|
420
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
421
|
+
var(--svelte-ui-snackbar-info-outlined-bg)
|
|
422
|
+
);
|
|
423
|
+
color: var(
|
|
424
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
425
|
+
var(--svelte-ui-snackbar-info-outlined-text-color)
|
|
426
|
+
);
|
|
372
427
|
box-shadow: inset 0 0 0 1px
|
|
373
|
-
var(
|
|
428
|
+
var(
|
|
429
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
430
|
+
var(--svelte-ui-snackbar-info-outlined-border-color)
|
|
431
|
+
);
|
|
374
432
|
}
|
|
375
433
|
|
|
376
434
|
.snackbar-item__content--outlined.snackbar-item__content--info .snackbar-item__icon {
|
|
377
|
-
color: var(
|
|
435
|
+
color: var(
|
|
436
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
437
|
+
var(--svelte-ui-snackbar-info-outlined-text-color)
|
|
438
|
+
);
|
|
378
439
|
}
|
|
379
440
|
|
|
380
441
|
.snackbar-item__content--outlined.snackbar-item__content--success {
|
|
381
|
-
background-color: var(
|
|
382
|
-
|
|
442
|
+
background-color: var(
|
|
443
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
444
|
+
var(--svelte-ui-snackbar-success-outlined-bg)
|
|
445
|
+
);
|
|
446
|
+
color: var(
|
|
447
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
448
|
+
var(--svelte-ui-snackbar-success-outlined-text-color)
|
|
449
|
+
);
|
|
383
450
|
box-shadow: inset 0 0 0 1px
|
|
384
|
-
var(
|
|
451
|
+
var(
|
|
452
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
453
|
+
var(--svelte-ui-snackbar-success-outlined-border-color)
|
|
454
|
+
);
|
|
385
455
|
}
|
|
386
456
|
|
|
387
457
|
.snackbar-item__content--outlined.snackbar-item__content--success .snackbar-item__icon {
|
|
388
|
-
color: var(
|
|
458
|
+
color: var(
|
|
459
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
460
|
+
var(--svelte-ui-snackbar-success-outlined-text-color)
|
|
461
|
+
);
|
|
389
462
|
}
|
|
390
463
|
|
|
391
464
|
.snackbar-item__content--outlined.snackbar-item__content--warning {
|
|
392
|
-
background-color: var(
|
|
393
|
-
|
|
465
|
+
background-color: var(
|
|
466
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
467
|
+
var(--svelte-ui-snackbar-warning-outlined-bg)
|
|
468
|
+
);
|
|
469
|
+
color: var(
|
|
470
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
471
|
+
var(--svelte-ui-snackbar-warning-outlined-text-color)
|
|
472
|
+
);
|
|
394
473
|
box-shadow: inset 0 0 0 1px
|
|
395
|
-
var(
|
|
474
|
+
var(
|
|
475
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
476
|
+
var(--svelte-ui-snackbar-warning-outlined-border-color)
|
|
477
|
+
);
|
|
396
478
|
}
|
|
397
479
|
|
|
398
480
|
.snackbar-item__content--outlined.snackbar-item__content--warning .snackbar-item__icon {
|
|
399
|
-
color: var(
|
|
481
|
+
color: var(
|
|
482
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
483
|
+
var(--svelte-ui-snackbar-warning-outlined-text-color)
|
|
484
|
+
);
|
|
400
485
|
}
|
|
401
486
|
|
|
402
487
|
.snackbar-item__content--outlined.snackbar-item__content--error {
|
|
403
|
-
background-color: var(
|
|
404
|
-
|
|
488
|
+
background-color: var(
|
|
489
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
490
|
+
var(--svelte-ui-snackbar-error-outlined-bg)
|
|
491
|
+
);
|
|
492
|
+
color: var(
|
|
493
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
494
|
+
var(--svelte-ui-snackbar-error-outlined-text-color)
|
|
495
|
+
);
|
|
405
496
|
box-shadow: inset 0 0 0 1px
|
|
406
|
-
var(
|
|
497
|
+
var(
|
|
498
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
499
|
+
var(--svelte-ui-snackbar-error-outlined-border-color)
|
|
500
|
+
);
|
|
407
501
|
}
|
|
408
502
|
|
|
409
503
|
.snackbar-item__content--outlined.snackbar-item__content--error .snackbar-item__icon {
|
|
410
|
-
color: var(
|
|
504
|
+
color: var(
|
|
505
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
506
|
+
var(--svelte-ui-snackbar-error-outlined-text-color)
|
|
507
|
+
);
|
|
411
508
|
}
|
|
412
509
|
|
|
413
510
|
.snackbar-item__content--outlined.snackbar-item__content--default {
|
|
414
|
-
background-color: var(
|
|
415
|
-
|
|
511
|
+
background-color: var(
|
|
512
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
513
|
+
var(--svelte-ui-snackbar-default-outlined-bg)
|
|
514
|
+
);
|
|
515
|
+
color: var(
|
|
516
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
517
|
+
var(--svelte-ui-snackbar-default-outlined-text-color)
|
|
518
|
+
);
|
|
416
519
|
box-shadow: inset 0 0 0 1px
|
|
417
|
-
var(
|
|
520
|
+
var(
|
|
521
|
+
--svelte-ui-snackbar-item-custom-color,
|
|
522
|
+
var(--svelte-ui-snackbar-default-outlined-border-color)
|
|
523
|
+
);
|
|
418
524
|
}
|
|
419
525
|
|
|
420
526
|
.snackbar-item__content--outlined.snackbar-item__content--default .snackbar-item__icon {
|
|
421
|
-
color: var(
|
|
527
|
+
color: var(
|
|
528
|
+
--svelte-ui-snackbar-item-custom-text-color,
|
|
529
|
+
var(--svelte-ui-snackbar-default-outlined-text-color)
|
|
530
|
+
);
|
|
422
531
|
}
|
|
423
532
|
</style>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import IconButton from './IconButton.svelte';
|
|
5
5
|
import { getStyleFromNumber } from '../utils/style';
|
|
6
6
|
import { t } from '../i18n';
|
|
7
|
+
import { convertToHtml, convertToHtmlWithLink } from '../utils/formatText';
|
|
7
8
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
8
9
|
import type { IconVariant } from '../types/icon';
|
|
9
10
|
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
readonly = false,
|
|
49
50
|
required = false,
|
|
50
51
|
iconVariant = 'outlined',
|
|
52
|
+
linkify = false,
|
|
51
53
|
|
|
52
54
|
// フォーカスイベント
|
|
53
55
|
onfocus = () => {}, // No params for type inference
|
|
@@ -125,6 +127,7 @@
|
|
|
125
127
|
readonly?: boolean;
|
|
126
128
|
required?: boolean;
|
|
127
129
|
iconVariant?: IconVariant;
|
|
130
|
+
linkify?: boolean;
|
|
128
131
|
|
|
129
132
|
// フォーカスイベント
|
|
130
133
|
onfocus?: Function; // No params for type inference
|
|
@@ -335,9 +338,7 @@
|
|
|
335
338
|
// HTML表示用の値(autoResize時の高さ調整用)
|
|
336
339
|
const htmlValue = $derived.by(() => {
|
|
337
340
|
if (value !== '') {
|
|
338
|
-
let html = value
|
|
339
|
-
.replace(/ +/g, (match) => ' '.repeat(match.length))
|
|
340
|
-
.replace(/\n/g, '<br />');
|
|
341
|
+
let html = convertToHtml(value) as string;
|
|
341
342
|
// 最後の行が空だったら空白を追加(高さ調整のため)
|
|
342
343
|
const lines = html.split('<br />');
|
|
343
344
|
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
@@ -348,12 +349,22 @@
|
|
|
348
349
|
return '';
|
|
349
350
|
}
|
|
350
351
|
});
|
|
352
|
+
|
|
353
|
+
// URLをリンク化した表示用HTML(クリック検出用オーバーレイで使用)
|
|
354
|
+
const linkHtmlValue = $derived.by(() => {
|
|
355
|
+
if (!linkify || value === '') {
|
|
356
|
+
return '';
|
|
357
|
+
}
|
|
358
|
+
const result = convertToHtmlWithLink(value);
|
|
359
|
+
return typeof result === 'string' ? result : String(result ?? '');
|
|
360
|
+
});
|
|
351
361
|
</script>
|
|
352
362
|
|
|
353
363
|
<div
|
|
354
364
|
class="textarea
|
|
355
365
|
textarea--focus-{focusStyle}"
|
|
356
366
|
class:textarea--inline={inline}
|
|
367
|
+
class:textarea--linkify={linkify}
|
|
357
368
|
class:textarea--full-width={fullWidth}
|
|
358
369
|
class:textarea--full-height={fullHeight}
|
|
359
370
|
class:textarea--auto-resize={autoResize}
|
|
@@ -438,6 +449,11 @@
|
|
|
438
449
|
</div>
|
|
439
450
|
{/if}
|
|
440
451
|
</div>
|
|
452
|
+
{#if linkify}
|
|
453
|
+
<div class="textarea__link-text" style="{minHeightStyle} {customStyle}">
|
|
454
|
+
{@html linkHtmlValue}
|
|
455
|
+
</div>
|
|
456
|
+
{/if}
|
|
441
457
|
</div>
|
|
442
458
|
|
|
443
459
|
<style>
|
|
@@ -471,11 +487,11 @@
|
|
|
471
487
|
}
|
|
472
488
|
|
|
473
489
|
/* =============================================
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
.textarea__display-text
|
|
477
|
-
|
|
478
|
-
|
|
490
|
+
* 基本コンポーネント
|
|
491
|
+
* ============================================= */
|
|
492
|
+
.textarea__display-text,
|
|
493
|
+
.textarea__link-text {
|
|
494
|
+
display: block;
|
|
479
495
|
width: 100%;
|
|
480
496
|
background: inherit;
|
|
481
497
|
border: inherit;
|
|
@@ -498,6 +514,23 @@
|
|
|
498
514
|
}
|
|
499
515
|
}
|
|
500
516
|
|
|
517
|
+
/* クリック可能なリンク用オーバーレイ */
|
|
518
|
+
.textarea__link-text {
|
|
519
|
+
position: absolute;
|
|
520
|
+
top: 0;
|
|
521
|
+
left: 0;
|
|
522
|
+
width: 100%;
|
|
523
|
+
height: 100%;
|
|
524
|
+
padding: inherit;
|
|
525
|
+
pointer-events: none;
|
|
526
|
+
z-index: 1;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.textarea__link-text :global(a) {
|
|
530
|
+
pointer-events: auto;
|
|
531
|
+
text-decoration: underline;
|
|
532
|
+
}
|
|
533
|
+
|
|
501
534
|
textarea {
|
|
502
535
|
position: absolute;
|
|
503
536
|
top: 0;
|
|
@@ -626,8 +659,8 @@
|
|
|
626
659
|
}
|
|
627
660
|
|
|
628
661
|
/* =============================================
|
|
629
|
-
|
|
630
|
-
|
|
662
|
+
* 表示切り替え(フォーカス時・非inline)
|
|
663
|
+
* ============================================= */
|
|
631
664
|
.textarea--focused,
|
|
632
665
|
.textarea:not(.textarea--inline) {
|
|
633
666
|
.textarea__display-text {
|
|
@@ -639,11 +672,22 @@
|
|
|
639
672
|
}
|
|
640
673
|
}
|
|
641
674
|
|
|
675
|
+
/* linkify=true かつ非 inline のときは、display-text は常に非表示(レイアウトだけ保持) */
|
|
676
|
+
.textarea--linkify:not(.textarea--inline) .textarea__display-text {
|
|
677
|
+
opacity: 0;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/* フォーカス時はリンク用オーバーレイも非表示にして(display:none)、リンクが反応しないようにする */
|
|
681
|
+
.textarea--focused .textarea__link-text {
|
|
682
|
+
display: none;
|
|
683
|
+
}
|
|
684
|
+
|
|
642
685
|
/* =============================================
|
|
643
686
|
* デザインバリアント:default
|
|
644
687
|
* ============================================= */
|
|
645
688
|
.textarea:not(.textarea--inline) {
|
|
646
|
-
.textarea__display-text
|
|
689
|
+
.textarea__display-text,
|
|
690
|
+
.textarea__link-text {
|
|
647
691
|
padding: var(--svelte-ui-textarea-padding);
|
|
648
692
|
}
|
|
649
693
|
|
|
@@ -664,6 +708,15 @@
|
|
|
664
708
|
}
|
|
665
709
|
}
|
|
666
710
|
|
|
711
|
+
/* linkify=true かつフォーカスがないときは、textarea のテキストカラーだけ透明にして二重描画を防ぐ
|
|
712
|
+
* placeholder の色は textarea::placeholder 側で指定しているため、この指定の影響を受けない
|
|
713
|
+
*/
|
|
714
|
+
.textarea--linkify:not(.textarea--focused) textarea {
|
|
715
|
+
color: transparent;
|
|
716
|
+
caret-color: transparent;
|
|
717
|
+
text-shadow: none;
|
|
718
|
+
}
|
|
719
|
+
|
|
667
720
|
/* =============================================
|
|
668
721
|
* デザインバリアント:rounded
|
|
669
722
|
* ============================================= */
|
|
@@ -699,4 +752,13 @@
|
|
|
699
752
|
top: var(--svelte-ui-textarea-icon-top-inline);
|
|
700
753
|
}
|
|
701
754
|
}
|
|
755
|
+
|
|
756
|
+
/* inline + linkify のときは、display-text を常に隠し、textarea を常に表示 */
|
|
757
|
+
.textarea--inline.textarea--linkify .textarea__display-text {
|
|
758
|
+
opacity: 0;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.textarea--inline.textarea--linkify textarea {
|
|
762
|
+
opacity: 1;
|
|
763
|
+
}
|
|
702
764
|
</style>
|