@14ch/svelte-ui 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/styles/variables.scss +3 -7
- package/dist/components/Button.svelte +31 -5
- package/dist/components/Button.svelte.d.ts +5 -3
- package/dist/components/Checkbox.svelte +4 -4
- package/dist/components/Checkbox.svelte.d.ts +1 -1
- package/dist/components/CheckboxGroup.svelte +6 -3
- package/dist/components/CheckboxGroup.svelte.d.ts +1 -1
- package/dist/components/ColorPicker.svelte +18 -10
- package/dist/components/ColorPicker.svelte.d.ts +4 -4
- package/dist/components/Combobox.svelte +28 -8
- package/dist/components/Combobox.svelte.d.ts +1 -1
- package/dist/components/ConfirmDialog.svelte +3 -7
- package/dist/components/ConfirmDialog.svelte.d.ts +1 -1
- package/dist/components/Datepicker.svelte +88 -24
- package/dist/components/Datepicker.svelte.d.ts +4 -3
- package/dist/components/DatepickerCalendar.svelte +1 -1
- package/dist/components/DatepickerCalendar.svelte.d.ts +1 -1
- package/dist/components/Drawer.svelte +8 -4
- package/dist/components/Drawer.svelte.d.ts +1 -1
- package/dist/components/Fab.svelte +28 -11
- package/dist/components/Fab.svelte.d.ts +8 -4
- package/dist/components/FileUploader.svelte +1 -1
- package/dist/components/FileUploader.svelte.d.ts +1 -1
- package/dist/components/Icon.svelte +20 -24
- package/dist/components/Icon.svelte.d.ts +1 -1
- package/dist/components/IconButton.svelte +4 -3
- package/dist/components/IconButton.svelte.d.ts +4 -3
- package/dist/components/ImageUploader.svelte +1 -1
- package/dist/components/ImageUploader.svelte.d.ts +1 -1
- package/dist/components/Input.svelte +110 -99
- package/dist/components/Input.svelte.d.ts +5 -3
- package/dist/components/Popup.svelte +69 -82
- package/dist/components/Popup.svelte.d.ts +3 -3
- package/dist/components/PopupMenu.svelte +40 -56
- package/dist/components/PopupMenu.svelte.d.ts +3 -3
- package/dist/components/PopupMenuButton.svelte +10 -23
- package/dist/components/PopupMenuButton.svelte.d.ts +5 -4
- package/dist/components/Radio.svelte +3 -2
- package/dist/components/Radio.svelte.d.ts +1 -1
- package/dist/components/RadioGroup.svelte +1 -1
- package/dist/components/RadioGroup.svelte.d.ts +1 -1
- package/dist/components/SegmentedControl.svelte +4 -5
- package/dist/components/SegmentedControl.svelte.d.ts +1 -1
- package/dist/components/Select.svelte +2 -2
- package/dist/components/Select.svelte.d.ts +1 -1
- package/dist/components/Slider.svelte +2 -3
- package/dist/components/Slider.svelte.d.ts +1 -1
- package/dist/components/Snackbar.svelte +3 -2
- package/dist/components/Snackbar.svelte.d.ts +3 -2
- package/dist/components/SnackbarItem.svelte +4 -3
- package/dist/components/SnackbarItem.svelte.d.ts +4 -3
- package/dist/components/Switch.svelte +2 -4
- package/dist/components/Switch.svelte.d.ts +1 -1
- package/dist/components/Tab.svelte +1 -0
- package/dist/components/TabItem.svelte +24 -3
- package/dist/components/TabItem.svelte.d.ts +1 -0
- package/dist/components/Textarea.svelte +74 -38
- package/dist/components/Textarea.svelte.d.ts +4 -3
- package/dist/components/skeleton/SkeletonAvatar.svelte +22 -32
- package/dist/components/skeleton/SkeletonAvatar.svelte.d.ts +6 -2
- package/dist/components/skeleton/SkeletonButton.svelte +18 -16
- package/dist/components/skeleton/SkeletonButton.svelte.d.ts +5 -2
- package/dist/components/skeleton/SkeletonHeading.svelte +15 -18
- package/dist/components/skeleton/SkeletonHeading.svelte.d.ts +3 -2
- package/dist/components/skeleton/SkeletonMedia.svelte +29 -41
- package/dist/components/skeleton/SkeletonMedia.svelte.d.ts +8 -2
- package/dist/components/skeleton/SkeletonText.svelte +12 -14
- package/dist/components/skeleton/SkeletonText.svelte.d.ts +4 -2
- package/dist/i18n/index.d.ts +143 -6
- package/dist/i18n/index.js +18 -40
- package/dist/i18n/locales/de.d.ts +35 -0
- package/dist/i18n/locales/de.js +35 -0
- package/dist/i18n/locales/es.d.ts +35 -0
- package/dist/i18n/locales/es.js +35 -0
- package/dist/i18n/locales/fr.d.ts +35 -0
- package/dist/i18n/locales/fr.js +35 -0
- package/dist/i18n/locales/zh-cn.d.ts +35 -0
- package/dist/i18n/locales/zh-cn.js +35 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +1 -0
- package/dist/types/menuItem.d.ts +1 -1
- package/dist/types/propOptions.d.ts +54 -0
- package/dist/types/propOptions.js +5 -0
- package/dist/utils/formatText.d.ts +2 -2
- package/dist/utils/formatText.js +2 -2
- package/dist/utils/popupManager.d.ts +26 -0
- package/dist/utils/popupManager.js +34 -0
- package/package.json +1 -1
- /package/dist/types/{eventHandlers.d.ts → callbackHandlers.d.ts} +0 -0
- /package/dist/types/{eventHandlers.js → callbackHandlers.js} +0 -0
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
export type TabItemProps = {
|
|
12
12
|
// 基本プロパティ
|
|
13
13
|
tabItem: MenuItem;
|
|
14
|
+
pathPrefix?: string;
|
|
14
15
|
|
|
15
16
|
// スタイル/レイアウト
|
|
16
17
|
textColor: string;
|
|
@@ -31,6 +32,7 @@
|
|
|
31
32
|
let {
|
|
32
33
|
// 基本プロパティ
|
|
33
34
|
tabItem,
|
|
35
|
+
pathPrefix = '',
|
|
34
36
|
|
|
35
37
|
// スタイル/レイアウト
|
|
36
38
|
textColor,
|
|
@@ -47,10 +49,29 @@
|
|
|
47
49
|
// 状態/動作
|
|
48
50
|
isSelected = false
|
|
49
51
|
}: TabItemProps = $props();
|
|
52
|
+
|
|
53
|
+
// =========================================================================
|
|
54
|
+
// $derived
|
|
55
|
+
// =========================================================================
|
|
56
|
+
|
|
57
|
+
// pathPrefixを付与したhrefを計算
|
|
58
|
+
const hrefWithPrefix = $derived.by(() => {
|
|
59
|
+
if (!tabItem.href) return undefined;
|
|
60
|
+
if (!pathPrefix) return tabItem.href;
|
|
61
|
+
|
|
62
|
+
// 既にpathPrefixが含まれている場合はそのまま
|
|
63
|
+
// pathPrefixが完全一致、またはpathPrefix + '/'で始まる場合
|
|
64
|
+
if (tabItem.href === pathPrefix || tabItem.href.startsWith(`${pathPrefix}/`)) {
|
|
65
|
+
return tabItem.href;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// pathPrefixを付与
|
|
69
|
+
return `${pathPrefix}${tabItem.href.startsWith('/') ? '' : '/'}${tabItem.href}`;
|
|
70
|
+
});
|
|
50
71
|
</script>
|
|
51
72
|
|
|
52
73
|
<a
|
|
53
|
-
href={
|
|
74
|
+
href={hrefWithPrefix}
|
|
54
75
|
class="tab-item"
|
|
55
76
|
class:tab-item--selected={isSelected}
|
|
56
77
|
style="--svelte-ui-tab-item-text-color: {textColor}; --svelte-ui-tab-item-selected-text-color: {selectedTextColor}; --svelte-ui-tab-item-selected-bar-color: {selectedBarColor}"
|
|
@@ -70,9 +91,9 @@
|
|
|
70
91
|
>
|
|
71
92
|
</div>
|
|
72
93
|
{/if}
|
|
73
|
-
{#if tabItem.
|
|
94
|
+
{#if tabItem.label}
|
|
74
95
|
<div class="tab-item__label">
|
|
75
|
-
{tabItem.
|
|
96
|
+
{tabItem.label}
|
|
76
97
|
</div>
|
|
77
98
|
{/if}
|
|
78
99
|
</a>
|
|
@@ -2,6 +2,7 @@ import type { MenuItem } from '../types/menuItem';
|
|
|
2
2
|
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
3
3
|
export type TabItemProps = {
|
|
4
4
|
tabItem: MenuItem;
|
|
5
|
+
pathPrefix?: string;
|
|
5
6
|
textColor: string;
|
|
6
7
|
selectedTextColor: string;
|
|
7
8
|
selectedBarColor: string;
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
KeyboardHandler,
|
|
13
13
|
MouseHandler,
|
|
14
14
|
TouchHandler,
|
|
15
|
-
PointerHandler
|
|
16
|
-
|
|
17
|
-
} from '../types/
|
|
15
|
+
PointerHandler
|
|
16
|
+
} from '../types/callbackHandlers';
|
|
17
|
+
import type { FocusStyle } from '../types/propOptions';
|
|
18
18
|
|
|
19
19
|
// =========================================================================
|
|
20
20
|
// Props, States & Constants
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
export type TextareaProps = {
|
|
23
23
|
// 基本プロパティ
|
|
24
24
|
name?: string;
|
|
25
|
-
value: string;
|
|
25
|
+
value: string | null | undefined;
|
|
26
26
|
placeholder?: string;
|
|
27
27
|
|
|
28
28
|
// HTML属性系
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
minHeight?: string | number | null;
|
|
41
41
|
maxHeight?: string | number | null;
|
|
42
42
|
inline?: boolean;
|
|
43
|
-
focusStyle?:
|
|
43
|
+
focusStyle?: FocusStyle;
|
|
44
44
|
fullWidth?: boolean;
|
|
45
45
|
fullHeight?: boolean;
|
|
46
46
|
width?: string | number | null;
|
|
@@ -180,6 +180,8 @@
|
|
|
180
180
|
}: TextareaProps = $props();
|
|
181
181
|
|
|
182
182
|
let ref: HTMLTextAreaElement | null = null;
|
|
183
|
+
let displayTextRef: HTMLDivElement | null = $state(null);
|
|
184
|
+
let linkTextRef: HTMLDivElement | null = $state(null);
|
|
183
185
|
let isFocused: boolean = $state(false);
|
|
184
186
|
|
|
185
187
|
// =========================================================================
|
|
@@ -330,6 +332,18 @@
|
|
|
330
332
|
onpointercancel?.(event);
|
|
331
333
|
};
|
|
332
334
|
|
|
335
|
+
// スクロール同期
|
|
336
|
+
const handleScroll = () => {
|
|
337
|
+
if (!ref) return;
|
|
338
|
+
const scrollTop = ref.scrollTop;
|
|
339
|
+
if (displayTextRef) {
|
|
340
|
+
displayTextRef.scrollTop = scrollTop;
|
|
341
|
+
}
|
|
342
|
+
if (linkify && linkTextRef) {
|
|
343
|
+
linkTextRef.scrollTop = scrollTop;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
333
347
|
// =========================================================================
|
|
334
348
|
// $derived
|
|
335
349
|
// =========================================================================
|
|
@@ -339,13 +353,14 @@
|
|
|
339
353
|
|
|
340
354
|
// HTML表示用の値(autoResize時の高さ調整用)
|
|
341
355
|
const htmlValue = $derived.by(() => {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
356
|
+
const normalizedValue = value ?? '';
|
|
357
|
+
if (normalizedValue !== '') {
|
|
358
|
+
const converted = convertToHtml(normalizedValue);
|
|
359
|
+
const html = String(converted ?? '');
|
|
345
360
|
// 最後の行が空だったら空白を追加(高さ調整のため)
|
|
346
361
|
const lines = html.split('<br />');
|
|
347
362
|
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
348
|
-
html
|
|
363
|
+
return html + ' ';
|
|
349
364
|
}
|
|
350
365
|
return html;
|
|
351
366
|
} else {
|
|
@@ -360,11 +375,12 @@
|
|
|
360
375
|
|
|
361
376
|
// URLをリンク化した表示用HTML(クリック検出用オーバーレイで使用)
|
|
362
377
|
const linkHtmlValue = $derived.by(() => {
|
|
363
|
-
|
|
378
|
+
const normalizedValue = value ?? '';
|
|
379
|
+
if (!linkify || normalizedValue === '') {
|
|
364
380
|
return '';
|
|
365
381
|
}
|
|
366
|
-
const result = convertToHtmlWithLink(
|
|
367
|
-
return
|
|
382
|
+
const result = convertToHtmlWithLink(normalizedValue);
|
|
383
|
+
return String(result ?? '');
|
|
368
384
|
});
|
|
369
385
|
</script>
|
|
370
386
|
|
|
@@ -386,13 +402,14 @@
|
|
|
386
402
|
>
|
|
387
403
|
<!-- autoResize時の表示用要素(HTMLレンダリングで高さ調整) -->
|
|
388
404
|
<div
|
|
405
|
+
bind:this={displayTextRef}
|
|
389
406
|
class="textarea__display-text"
|
|
390
407
|
data-placeholder={placeholder}
|
|
391
|
-
style="min-height: {minHeightStyle}; {customStyle}"
|
|
408
|
+
style="min-height: {minHeightStyle}; max-height: {maxHeightStyle}; {customStyle}"
|
|
392
409
|
>
|
|
393
410
|
{@html htmlValue}
|
|
394
411
|
</div>
|
|
395
|
-
<div class="
|
|
412
|
+
<div class="textarea__wrapper">
|
|
396
413
|
<textarea
|
|
397
414
|
{id}
|
|
398
415
|
{name}
|
|
@@ -436,32 +453,37 @@
|
|
|
436
453
|
onpointerleave={handlePointerLeave}
|
|
437
454
|
onpointermove={handlePointerMove}
|
|
438
455
|
onpointercancel={handlePointerCancel}
|
|
456
|
+
onscroll={handleScroll}
|
|
439
457
|
{...textareaAttributes}
|
|
440
458
|
{...restProps}
|
|
441
459
|
></textarea>
|
|
442
|
-
<!-- クリアボタン -->
|
|
443
|
-
{#if clearable && !disabled && !readonly}
|
|
444
|
-
<div class="textarea__clear-button">
|
|
445
|
-
<IconButton
|
|
446
|
-
ariaLabel={clearButtonAriaLabel}
|
|
447
|
-
color="var(--svelte-ui-textarea-text-color)"
|
|
448
|
-
onclick={(event) => {
|
|
449
|
-
event.stopPropagation();
|
|
450
|
-
clear();
|
|
451
|
-
}}
|
|
452
|
-
tabindex={-1}
|
|
453
|
-
iconFilled={true}
|
|
454
|
-
{iconVariant}
|
|
455
|
-
fontSize={18}>cancel</IconButton
|
|
456
|
-
>
|
|
457
|
-
</div>
|
|
458
|
-
{/if}
|
|
459
460
|
</div>
|
|
460
461
|
{#if linkify}
|
|
461
|
-
<div
|
|
462
|
+
<div
|
|
463
|
+
bind:this={linkTextRef}
|
|
464
|
+
class="textarea__link-text"
|
|
465
|
+
style="min-height: {minHeightStyle}; max-height: {maxHeightStyle}; {customStyle}"
|
|
466
|
+
>
|
|
462
467
|
{@html linkHtmlValue}
|
|
463
468
|
</div>
|
|
464
469
|
{/if}
|
|
470
|
+
<!-- クリアボタン -->
|
|
471
|
+
{#if clearable && !disabled && !readonly}
|
|
472
|
+
<div class="textarea__clear-button">
|
|
473
|
+
<IconButton
|
|
474
|
+
ariaLabel={clearButtonAriaLabel}
|
|
475
|
+
color="var(--svelte-ui-text-color)"
|
|
476
|
+
onclick={(event) => {
|
|
477
|
+
event.stopPropagation();
|
|
478
|
+
clear();
|
|
479
|
+
}}
|
|
480
|
+
tabindex={-1}
|
|
481
|
+
iconFilled={true}
|
|
482
|
+
{iconVariant}
|
|
483
|
+
fontSize={18}>cancel</IconButton
|
|
484
|
+
>
|
|
485
|
+
</div>
|
|
486
|
+
{/if}
|
|
465
487
|
</div>
|
|
466
488
|
|
|
467
489
|
<style>
|
|
@@ -479,7 +501,7 @@
|
|
|
479
501
|
}
|
|
480
502
|
}
|
|
481
503
|
|
|
482
|
-
.
|
|
504
|
+
.textarea__wrapper {
|
|
483
505
|
position: absolute;
|
|
484
506
|
top: 0;
|
|
485
507
|
left: 0;
|
|
@@ -512,6 +534,14 @@
|
|
|
512
534
|
opacity: 1;
|
|
513
535
|
transition: none;
|
|
514
536
|
cursor: text !important;
|
|
537
|
+
overflow-y: auto;
|
|
538
|
+
overflow-x: hidden;
|
|
539
|
+
scrollbar-width: none; /* Firefox */
|
|
540
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
541
|
+
|
|
542
|
+
&::-webkit-scrollbar {
|
|
543
|
+
display: none; /* Chrome, Safari, Opera */
|
|
544
|
+
}
|
|
515
545
|
|
|
516
546
|
&::before {
|
|
517
547
|
content: '';
|
|
@@ -600,7 +630,8 @@
|
|
|
600
630
|
* ============================================= */
|
|
601
631
|
.textarea--clearable {
|
|
602
632
|
textarea,
|
|
603
|
-
.textarea__display-text
|
|
633
|
+
.textarea__display-text,
|
|
634
|
+
.textarea__link-text {
|
|
604
635
|
padding-right: var(--svelte-ui-textarea-icon-space);
|
|
605
636
|
}
|
|
606
637
|
}
|
|
@@ -686,9 +717,13 @@
|
|
|
686
717
|
opacity: 0;
|
|
687
718
|
}
|
|
688
719
|
|
|
689
|
-
/*
|
|
720
|
+
/* フォーカス時はリンク用オーバーレイも非表示(opacity: 0)にして、リンクが反応しないようにする */
|
|
690
721
|
.textarea--focused .textarea__link-text {
|
|
691
|
-
|
|
722
|
+
opacity: 0;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.textarea--focused .textarea__link-text :global(a) {
|
|
726
|
+
pointer-events: none;
|
|
692
727
|
}
|
|
693
728
|
|
|
694
729
|
/* =============================================
|
|
@@ -708,11 +743,12 @@
|
|
|
708
743
|
box-shadow: 0 0 0 var(--svelte-ui-border-width) inset var(--svelte-ui-textarea-border-color);
|
|
709
744
|
border: none;
|
|
710
745
|
border-radius: var(--svelte-ui-textarea-border-radius);
|
|
711
|
-
color: var(--svelte-ui-textarea-text-color);
|
|
712
746
|
}
|
|
713
747
|
|
|
714
748
|
&.textarea--clearable {
|
|
715
|
-
textarea
|
|
749
|
+
textarea,
|
|
750
|
+
.textarea__display-text,
|
|
751
|
+
.textarea__link-text {
|
|
716
752
|
padding-right: var(--svelte-ui-textarea-icon-space);
|
|
717
753
|
}
|
|
718
754
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
2
2
|
import type { IconVariant } from '../types/icon';
|
|
3
|
-
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/
|
|
3
|
+
import type { FocusHandler, KeyboardHandler, MouseHandler, TouchHandler, PointerHandler } from '../types/callbackHandlers';
|
|
4
|
+
import type { FocusStyle } from '../types/propOptions';
|
|
4
5
|
export type TextareaProps = {
|
|
5
6
|
name?: string;
|
|
6
|
-
value: string;
|
|
7
|
+
value: string | null | undefined;
|
|
7
8
|
placeholder?: string;
|
|
8
9
|
id?: string | null;
|
|
9
10
|
tabindex?: number | null;
|
|
@@ -17,7 +18,7 @@ export type TextareaProps = {
|
|
|
17
18
|
minHeight?: string | number | null;
|
|
18
19
|
maxHeight?: string | number | null;
|
|
19
20
|
inline?: boolean;
|
|
20
|
-
focusStyle?:
|
|
21
|
+
focusStyle?: FocusStyle;
|
|
21
22
|
fullWidth?: boolean;
|
|
22
23
|
fullHeight?: boolean;
|
|
23
24
|
width?: string | number | null;
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import SkeletonBox from './SkeletonBox.svelte';
|
|
5
5
|
import SkeletonText from './SkeletonText.svelte';
|
|
6
6
|
import { getStyleFromNumber } from '../../utils/style';
|
|
7
|
-
import type { SkeletonAvatarConfig } from '../../types/skeleton';
|
|
8
7
|
import {
|
|
9
8
|
DEFAULT_AVATAR_IMAGE_CONFIG,
|
|
10
9
|
DEFAULT_TEXT_CONFIG_AVATAR,
|
|
@@ -15,37 +14,35 @@
|
|
|
15
14
|
// Props, States & Constants
|
|
16
15
|
// =========================================================================
|
|
17
16
|
export type SkeletonAvatarProps = {
|
|
18
|
-
|
|
17
|
+
avatarImageSize?: string | number;
|
|
18
|
+
avatarImageRadius?: string | number;
|
|
19
|
+
textWidth?: string | number;
|
|
20
|
+
lines?: number;
|
|
21
|
+
fontSize?: string | number;
|
|
22
|
+
showName?: boolean;
|
|
19
23
|
animated?: boolean;
|
|
20
24
|
};
|
|
21
25
|
|
|
22
26
|
let {
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
avatarImageSize = DEFAULT_AVATAR_IMAGE_CONFIG.size,
|
|
28
|
+
avatarImageRadius = DEFAULT_AVATAR_IMAGE_CONFIG.radius,
|
|
29
|
+
textWidth = DEFAULT_TEXT_CONFIG_AVATAR.width,
|
|
30
|
+
lines = DEFAULT_TEXT_CONFIG_AVATAR.lines,
|
|
31
|
+
fontSize,
|
|
32
|
+
showName = DEFAULT_AVATAR_CONFIG.showName,
|
|
25
33
|
animated = true
|
|
26
34
|
}: SkeletonAvatarProps = $props();
|
|
27
35
|
|
|
28
36
|
// =========================================================================
|
|
29
37
|
// $derived
|
|
30
38
|
// =========================================================================
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
...DEFAULT_TEXT_CONFIG_AVATAR,
|
|
39
|
-
...(avatarConfig.textConfig || {})
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const mergedAvatarConfig = $derived({
|
|
43
|
-
...DEFAULT_AVATAR_CONFIG,
|
|
44
|
-
...avatarConfig
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const avatarImageSizeStyle = $derived(getStyleFromNumber(mergedAvatarImageConfig.size));
|
|
48
|
-
const nameWidthStyle = $derived(getStyleFromNumber(mergedTextConfig.width));
|
|
39
|
+
const avatarImageSizeStyle = $derived(getStyleFromNumber(avatarImageSize));
|
|
40
|
+
const avatarImageRadiusStyle = $derived(
|
|
41
|
+
avatarImageRadius
|
|
42
|
+
? getStyleFromNumber(avatarImageRadius)
|
|
43
|
+
: 'var(--svelte-ui-skeleton-avatar-image-border-radius)'
|
|
44
|
+
);
|
|
45
|
+
const textWidthStyle = $derived(getStyleFromNumber(textWidth));
|
|
49
46
|
</script>
|
|
50
47
|
|
|
51
48
|
<div class="skeleton-avatar">
|
|
@@ -53,20 +50,13 @@
|
|
|
53
50
|
<SkeletonBox
|
|
54
51
|
width={avatarImageSizeStyle}
|
|
55
52
|
height={avatarImageSizeStyle}
|
|
56
|
-
radius=
|
|
53
|
+
radius={avatarImageRadiusStyle}
|
|
57
54
|
{animated}
|
|
58
|
-
customStyle={mergedAvatarImageConfig.customStyle}
|
|
59
55
|
/>
|
|
60
56
|
</div>
|
|
61
|
-
{#if
|
|
57
|
+
{#if showName}
|
|
62
58
|
<div class="skeleton-avatar__text">
|
|
63
|
-
<SkeletonText
|
|
64
|
-
textConfig={{
|
|
65
|
-
width: nameWidthStyle,
|
|
66
|
-
lines: mergedTextConfig.lines
|
|
67
|
-
}}
|
|
68
|
-
{animated}
|
|
69
|
-
/>
|
|
59
|
+
<SkeletonText width={textWidthStyle} {lines} {fontSize} {animated} />
|
|
70
60
|
</div>
|
|
71
61
|
{/if}
|
|
72
62
|
</div>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type { SkeletonAvatarConfig } from '../../types/skeleton';
|
|
2
1
|
export type SkeletonAvatarProps = {
|
|
3
|
-
|
|
2
|
+
avatarImageSize?: string | number;
|
|
3
|
+
avatarImageRadius?: string | number;
|
|
4
|
+
textWidth?: string | number;
|
|
5
|
+
lines?: number;
|
|
6
|
+
fontSize?: string | number;
|
|
7
|
+
showName?: boolean;
|
|
4
8
|
animated?: boolean;
|
|
5
9
|
};
|
|
6
10
|
declare const SkeletonAvatar: import("svelte").Component<SkeletonAvatarProps, {}, "">;
|
|
@@ -3,38 +3,40 @@
|
|
|
3
3
|
<script lang="ts">
|
|
4
4
|
import SkeletonBox from './SkeletonBox.svelte';
|
|
5
5
|
import { getStyleFromNumber } from '../../utils/style';
|
|
6
|
-
import type { SkeletonButtonConfig } from '../../types/skeleton';
|
|
7
6
|
import { DEFAULT_BUTTON_CONFIG } from '../../constants/skeleton';
|
|
8
7
|
|
|
9
8
|
// =========================================================================
|
|
10
9
|
// Props, States & Constants
|
|
11
10
|
// =========================================================================
|
|
12
11
|
export type SkeletonButtonProps = {
|
|
13
|
-
|
|
12
|
+
width?: string | number;
|
|
13
|
+
height?: string | number;
|
|
14
|
+
radius?: string | number;
|
|
15
|
+
align?: 'left' | 'center' | 'right';
|
|
16
|
+
customStyle?: string;
|
|
14
17
|
animated?: boolean;
|
|
15
18
|
};
|
|
16
19
|
|
|
17
|
-
let {
|
|
20
|
+
let {
|
|
21
|
+
width = DEFAULT_BUTTON_CONFIG.width,
|
|
22
|
+
height = DEFAULT_BUTTON_CONFIG.height,
|
|
23
|
+
radius = DEFAULT_BUTTON_CONFIG.radius,
|
|
24
|
+
align = DEFAULT_BUTTON_CONFIG.align,
|
|
25
|
+
customStyle = DEFAULT_BUTTON_CONFIG.customStyle,
|
|
26
|
+
animated = true
|
|
27
|
+
}: SkeletonButtonProps = $props();
|
|
18
28
|
|
|
19
29
|
// =========================================================================
|
|
20
30
|
// $derived
|
|
21
31
|
// =========================================================================
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
...DEFAULT_BUTTON_CONFIG,
|
|
25
|
-
...buttonConfig
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const widthStyle = $derived(getStyleFromNumber(mergedButtonConfig.width));
|
|
29
|
-
const heightStyle = $derived(getStyleFromNumber(mergedButtonConfig.height));
|
|
32
|
+
const widthStyle = $derived(getStyleFromNumber(width));
|
|
33
|
+
const heightStyle = $derived(getStyleFromNumber(height));
|
|
30
34
|
const radiusStyle = $derived(
|
|
31
|
-
typeof
|
|
32
|
-
? `${mergedButtonConfig.radius}px`
|
|
33
|
-
: mergedButtonConfig.radius
|
|
35
|
+
typeof radius === 'number' ? `${radius}px` : radius
|
|
34
36
|
);
|
|
35
37
|
|
|
36
38
|
// alignに応じたCSSクラスを生成
|
|
37
|
-
const alignClass = $derived(`skeleton-button--align-${
|
|
39
|
+
const alignClass = $derived(`skeleton-button--align-${align}`);
|
|
38
40
|
</script>
|
|
39
41
|
|
|
40
42
|
<div class="skeleton-button {alignClass}">
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
height={heightStyle}
|
|
44
46
|
radius={radiusStyle}
|
|
45
47
|
{animated}
|
|
46
|
-
|
|
48
|
+
{customStyle}
|
|
47
49
|
/>
|
|
48
50
|
</div>
|
|
49
51
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { SkeletonButtonConfig } from '../../types/skeleton';
|
|
2
1
|
export type SkeletonButtonProps = {
|
|
3
|
-
|
|
2
|
+
width?: string | number;
|
|
3
|
+
height?: string | number;
|
|
4
|
+
radius?: string | number;
|
|
5
|
+
align?: 'left' | 'center' | 'right';
|
|
6
|
+
customStyle?: string;
|
|
4
7
|
animated?: boolean;
|
|
5
8
|
};
|
|
6
9
|
declare const SkeletonButton: import("svelte").Component<SkeletonButtonProps, {}, "">;
|
|
@@ -3,41 +3,38 @@
|
|
|
3
3
|
<script lang="ts">
|
|
4
4
|
import SkeletonText from './SkeletonText.svelte';
|
|
5
5
|
import { getStyleFromNumber } from '../../utils/style';
|
|
6
|
-
import type { SkeletonHeadingConfig } from '../../types/skeleton';
|
|
7
6
|
import { DEFAULT_HEADING_CONFIG } from '../../constants/skeleton';
|
|
8
7
|
|
|
9
8
|
// =========================================================================
|
|
10
9
|
// Props, States & Constants
|
|
11
10
|
// =========================================================================
|
|
12
11
|
export type SkeletonHeadingProps = {
|
|
13
|
-
|
|
12
|
+
width?: string | number;
|
|
13
|
+
fontSize?: string | number;
|
|
14
|
+
customStyle?: string;
|
|
14
15
|
animated?: boolean;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
let {
|
|
18
|
+
let {
|
|
19
|
+
width = DEFAULT_HEADING_CONFIG.width,
|
|
20
|
+
fontSize = DEFAULT_HEADING_CONFIG.fontSize,
|
|
21
|
+
customStyle = DEFAULT_HEADING_CONFIG.customStyle,
|
|
22
|
+
animated = true
|
|
23
|
+
}: SkeletonHeadingProps = $props();
|
|
18
24
|
|
|
19
25
|
// =========================================================================
|
|
20
26
|
// $derived
|
|
21
27
|
// =========================================================================
|
|
22
|
-
|
|
23
|
-
const mergedHeadingConfig = $derived({
|
|
24
|
-
...DEFAULT_HEADING_CONFIG,
|
|
25
|
-
...headingConfig
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const widthStyle = $derived(getStyleFromNumber(mergedHeadingConfig.width));
|
|
28
|
+
const widthStyle = $derived(getStyleFromNumber(width));
|
|
29
29
|
const fontSizeStyle = $derived(
|
|
30
|
-
|
|
31
|
-
?
|
|
32
|
-
|
|
33
|
-
? mergedHeadingConfig.fontSize
|
|
34
|
-
: getStyleFromNumber(mergedHeadingConfig.fontSize)
|
|
35
|
-
: DEFAULT_HEADING_CONFIG.fontSize
|
|
30
|
+
typeof fontSize === 'string' && fontSize.startsWith('var(')
|
|
31
|
+
? fontSize
|
|
32
|
+
: getStyleFromNumber(fontSize)
|
|
36
33
|
);
|
|
37
34
|
</script>
|
|
38
35
|
|
|
39
|
-
<div class="skeleton-heading" style="font-size: {fontSizeStyle}; {
|
|
40
|
-
<SkeletonText
|
|
36
|
+
<div class="skeleton-heading" style="font-size: {fontSizeStyle}; {customStyle}">
|
|
37
|
+
<SkeletonText width={widthStyle} {animated} />
|
|
41
38
|
</div>
|
|
42
39
|
|
|
43
40
|
<style>.skeleton-heading {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { SkeletonHeadingConfig } from '../../types/skeleton';
|
|
2
1
|
export type SkeletonHeadingProps = {
|
|
3
|
-
|
|
2
|
+
width?: string | number;
|
|
3
|
+
fontSize?: string | number;
|
|
4
|
+
customStyle?: string;
|
|
4
5
|
animated?: boolean;
|
|
5
6
|
};
|
|
6
7
|
declare const SkeletonHeading: import("svelte").Component<SkeletonHeadingProps, {}, "">;
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import SkeletonBox from './SkeletonBox.svelte';
|
|
5
5
|
import SkeletonText from './SkeletonText.svelte';
|
|
6
6
|
import { getStyleFromNumber } from '../../utils/style';
|
|
7
|
-
import type { SkeletonMediaConfig } from '../../types/skeleton';
|
|
8
7
|
import {
|
|
9
8
|
DEFAULT_MEDIA_CONFIG,
|
|
10
9
|
DEFAULT_THUMBNAIL_CONFIG,
|
|
@@ -16,47 +15,44 @@
|
|
|
16
15
|
// =========================================================================
|
|
17
16
|
export type SkeletonMediaProps = {
|
|
18
17
|
width?: string | number;
|
|
19
|
-
|
|
18
|
+
layout?: 'horizontal' | 'vertical';
|
|
19
|
+
textWidth?: string | number;
|
|
20
|
+
lines?: number;
|
|
21
|
+
fontSize?: string | number;
|
|
22
|
+
thumbnailWidth?: string | number;
|
|
23
|
+
thumbnailHeight?: string | number;
|
|
24
|
+
thumbnailAspectRatio?: string | number;
|
|
25
|
+
thumbnailRadius?: string | number;
|
|
20
26
|
animated?: boolean;
|
|
21
27
|
};
|
|
22
28
|
|
|
23
|
-
let {
|
|
29
|
+
let {
|
|
30
|
+
width = '100%',
|
|
31
|
+
layout = DEFAULT_MEDIA_CONFIG.layout,
|
|
32
|
+
textWidth = DEFAULT_TEXT_CONFIG_MEDIA.width,
|
|
33
|
+
lines = DEFAULT_TEXT_CONFIG_MEDIA.lines,
|
|
34
|
+
fontSize,
|
|
35
|
+
thumbnailWidth = DEFAULT_THUMBNAIL_CONFIG.width,
|
|
36
|
+
thumbnailHeight,
|
|
37
|
+
thumbnailAspectRatio,
|
|
38
|
+
thumbnailRadius = DEFAULT_THUMBNAIL_CONFIG.radius,
|
|
39
|
+
animated = true
|
|
40
|
+
}: SkeletonMediaProps = $props();
|
|
24
41
|
|
|
25
42
|
// =========================================================================
|
|
26
43
|
// $derived
|
|
27
44
|
// =========================================================================
|
|
28
|
-
|
|
29
|
-
const mergedMediaConfig = $derived({
|
|
30
|
-
...DEFAULT_MEDIA_CONFIG,
|
|
31
|
-
...mediaConfig
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// レイアウト方向を取得
|
|
35
|
-
const layoutDirection = $derived(mergedMediaConfig.layout || 'horizontal');
|
|
36
|
-
|
|
37
|
-
// マージされた設定
|
|
38
|
-
const mergedThumbnailConfig = $derived({
|
|
39
|
-
...DEFAULT_THUMBNAIL_CONFIG,
|
|
40
|
-
...(mergedMediaConfig.thumbnailConfig || {})
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const mergedTextConfig = $derived({
|
|
44
|
-
...DEFAULT_TEXT_CONFIG_MEDIA,
|
|
45
|
-
...(mergedMediaConfig.textConfig || {})
|
|
46
|
-
});
|
|
45
|
+
const layoutDirection = $derived(layout || 'horizontal');
|
|
47
46
|
|
|
48
47
|
const widthStyle = $derived(getStyleFromNumber(width));
|
|
49
|
-
const thumbnailWidthStyle = $derived(getStyleFromNumber(
|
|
50
|
-
const thumbnailHeightStyle = $derived(
|
|
51
|
-
|
|
52
|
-
);
|
|
53
|
-
const textWidthStyle = $derived(getStyleFromNumber(mergedTextConfig.width));
|
|
48
|
+
const thumbnailWidthStyle = $derived(getStyleFromNumber(thumbnailWidth));
|
|
49
|
+
const thumbnailHeightStyle = $derived(thumbnailHeight ? getStyleFromNumber(thumbnailHeight) : '');
|
|
50
|
+
const textWidthStyle = $derived(getStyleFromNumber(textWidth));
|
|
54
51
|
|
|
55
52
|
// heightとaspectRatioの優先順位を制御
|
|
56
|
-
const finalThumbnailHeight = $derived(
|
|
57
|
-
const finalThumbnailAspectRatio = $derived(
|
|
58
|
-
|
|
59
|
-
);
|
|
53
|
+
const finalThumbnailHeight = $derived(thumbnailHeight ? thumbnailHeightStyle : '');
|
|
54
|
+
const finalThumbnailAspectRatio = $derived(thumbnailHeight ? undefined : thumbnailAspectRatio);
|
|
55
|
+
const thumbnailRadiusStyle = $derived(thumbnailRadius ? getStyleFromNumber(thumbnailRadius) : '');
|
|
60
56
|
</script>
|
|
61
57
|
|
|
62
58
|
<div
|
|
@@ -68,18 +64,10 @@
|
|
|
68
64
|
width={thumbnailWidthStyle}
|
|
69
65
|
{...finalThumbnailHeight && { height: finalThumbnailHeight }}
|
|
70
66
|
aspectRatio={finalThumbnailAspectRatio}
|
|
71
|
-
radius={
|
|
72
|
-
{animated}
|
|
73
|
-
customStyle={mergedThumbnailConfig.customStyle}
|
|
74
|
-
/>
|
|
75
|
-
<SkeletonText
|
|
76
|
-
textConfig={{
|
|
77
|
-
width: textWidthStyle,
|
|
78
|
-
lines: mergedTextConfig.lines,
|
|
79
|
-
fontSize: mergedTextConfig.fontSize
|
|
80
|
-
}}
|
|
67
|
+
radius={thumbnailRadiusStyle}
|
|
81
68
|
{animated}
|
|
82
69
|
/>
|
|
70
|
+
<SkeletonText width={textWidthStyle} {lines} {fontSize} {animated} />
|
|
83
71
|
</div>
|
|
84
72
|
|
|
85
73
|
<style>
|