@14ch/svelte-ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +359 -0
  2. package/dist/assets/styles/README.md +144 -0
  3. package/dist/assets/styles/core.scss +61 -0
  4. package/dist/assets/styles/import.scss +11 -0
  5. package/dist/assets/styles/optional/fonts.scss +23 -0
  6. package/dist/assets/styles/optional/reset.scss +230 -0
  7. package/dist/assets/styles/variables.scss +805 -0
  8. package/dist/components/Button.svelte +574 -0
  9. package/dist/components/Button.svelte.d.ts +56 -0
  10. package/dist/components/COMPONENT_DESIGN_GUIDELINES.md +127 -0
  11. package/dist/components/Checkbox.svelte +523 -0
  12. package/dist/components/Checkbox.svelte.d.ts +42 -0
  13. package/dist/components/CheckboxGroup.svelte +82 -0
  14. package/dist/components/CheckboxGroup.svelte.d.ts +13 -0
  15. package/dist/components/ColorPicker.svelte +496 -0
  16. package/dist/components/ColorPicker.svelte.d.ts +45 -0
  17. package/dist/components/Combobox.svelte +576 -0
  18. package/dist/components/Combobox.svelte.d.ts +52 -0
  19. package/dist/components/ConfirmDialog.svelte +116 -0
  20. package/dist/components/ConfirmDialog.svelte.d.ts +20 -0
  21. package/dist/components/Datepicker.svelte +578 -0
  22. package/dist/components/Datepicker.svelte.d.ts +72 -0
  23. package/dist/components/DatepickerCalendar.svelte +925 -0
  24. package/dist/components/DatepickerCalendar.svelte.d.ts +31 -0
  25. package/dist/components/Dialog.svelte +245 -0
  26. package/dist/components/Dialog.svelte.d.ts +38 -0
  27. package/dist/components/Drawer.svelte +383 -0
  28. package/dist/components/Drawer.svelte.d.ts +39 -0
  29. package/dist/components/Fab.svelte +486 -0
  30. package/dist/components/Fab.svelte.d.ts +51 -0
  31. package/dist/components/FileUploader.svelte +456 -0
  32. package/dist/components/FileUploader.svelte.d.ts +36 -0
  33. package/dist/components/Icon.svelte +167 -0
  34. package/dist/components/Icon.svelte.d.ts +21 -0
  35. package/dist/components/IconButton.svelte +557 -0
  36. package/dist/components/IconButton.svelte.d.ts +60 -0
  37. package/dist/components/ImageUploader.svelte +516 -0
  38. package/dist/components/ImageUploader.svelte.d.ts +37 -0
  39. package/dist/components/ImageUploaderPreview.svelte +157 -0
  40. package/dist/components/ImageUploaderPreview.svelte.d.ts +13 -0
  41. package/dist/components/Input.svelte +885 -0
  42. package/dist/components/Input.svelte.d.ts +75 -0
  43. package/dist/components/LoadingSpinner.svelte +116 -0
  44. package/dist/components/LoadingSpinner.svelte.d.ts +10 -0
  45. package/dist/components/Modal.svelte +313 -0
  46. package/dist/components/Modal.svelte.d.ts +34 -0
  47. package/dist/components/Pagination.svelte +276 -0
  48. package/dist/components/Pagination.svelte.d.ts +14 -0
  49. package/dist/components/Popup.svelte +676 -0
  50. package/dist/components/Popup.svelte.d.ts +40 -0
  51. package/dist/components/PopupMenu.svelte +421 -0
  52. package/dist/components/PopupMenu.svelte.d.ts +24 -0
  53. package/dist/components/PopupMenuButton.svelte +365 -0
  54. package/dist/components/PopupMenuButton.svelte.d.ts +42 -0
  55. package/dist/components/Radio.svelte +548 -0
  56. package/dist/components/Radio.svelte.d.ts +42 -0
  57. package/dist/components/RadioGroup.svelte +74 -0
  58. package/dist/components/RadioGroup.svelte.d.ts +14 -0
  59. package/dist/components/Select.svelte +479 -0
  60. package/dist/components/Select.svelte.d.ts +47 -0
  61. package/dist/components/Slider.svelte +473 -0
  62. package/dist/components/Slider.svelte.d.ts +46 -0
  63. package/dist/components/Snackbar.svelte +124 -0
  64. package/dist/components/Snackbar.svelte.d.ts +9 -0
  65. package/dist/components/SnackbarItem.svelte +423 -0
  66. package/dist/components/SnackbarItem.svelte.d.ts +21 -0
  67. package/dist/components/Switch.svelte +454 -0
  68. package/dist/components/Switch.svelte.d.ts +40 -0
  69. package/dist/components/Tab.svelte +193 -0
  70. package/dist/components/Tab.svelte.d.ts +14 -0
  71. package/dist/components/TabItem.svelte +140 -0
  72. package/dist/components/TabItem.svelte.d.ts +17 -0
  73. package/dist/components/Textarea.svelte +702 -0
  74. package/dist/components/Textarea.svelte.d.ts +64 -0
  75. package/dist/components/skeleton/Skeleton.svelte +235 -0
  76. package/dist/components/skeleton/Skeleton.svelte.d.ts +13 -0
  77. package/dist/components/skeleton/SkeletonAvatar.svelte +97 -0
  78. package/dist/components/skeleton/SkeletonAvatar.svelte.d.ts +8 -0
  79. package/dist/components/skeleton/SkeletonBox.svelte +105 -0
  80. package/dist/components/skeleton/SkeletonBox.svelte.d.ts +12 -0
  81. package/dist/components/skeleton/SkeletonButton.svelte +71 -0
  82. package/dist/components/skeleton/SkeletonButton.svelte.d.ts +8 -0
  83. package/dist/components/skeleton/SkeletonHeading.svelte +49 -0
  84. package/dist/components/skeleton/SkeletonHeading.svelte.d.ts +8 -0
  85. package/dist/components/skeleton/SkeletonMedia.svelte +115 -0
  86. package/dist/components/skeleton/SkeletonMedia.svelte.d.ts +9 -0
  87. package/dist/components/skeleton/SkeletonText.svelte +75 -0
  88. package/dist/components/skeleton/SkeletonText.svelte.d.ts +8 -0
  89. package/dist/index.d.ts +42 -0
  90. package/dist/index.js +43 -0
  91. package/dist/types/icon.d.ts +4 -0
  92. package/dist/types/icon.js +2 -0
  93. package/dist/types/menuItem.d.ts +8 -0
  94. package/dist/types/menuItem.js +1 -0
  95. package/dist/types/options.d.ts +6 -0
  96. package/dist/types/options.js +4 -0
  97. package/dist/types/skeleton.d.ts +77 -0
  98. package/dist/types/skeleton.js +19 -0
  99. package/dist/utils/accessibility.d.ts +48 -0
  100. package/dist/utils/accessibility.js +87 -0
  101. package/dist/utils/formatText.d.ts +4 -0
  102. package/dist/utils/formatText.js +44 -0
  103. package/dist/utils/mobile.d.ts +9 -0
  104. package/dist/utils/mobile.js +47 -0
  105. package/dist/utils/snackbar.svelte.d.ts +51 -0
  106. package/dist/utils/snackbar.svelte.js +107 -0
  107. package/dist/utils/style.d.ts +17 -0
  108. package/dist/utils/style.js +22 -0
  109. package/package.json +102 -0
@@ -0,0 +1,115 @@
1
+ <!-- SkeletonMedia.svelte -->
2
+
3
+ <script lang="ts">
4
+ import SkeletonBox from './SkeletonBox.svelte';
5
+ import SkeletonText from './SkeletonText.svelte';
6
+ import { getStyleFromNumber } from '../../utils/style';
7
+ import type {
8
+ SkeletonMediaConfig,
9
+ SkeletonThumbnailConfig,
10
+ SkeletonTextConfig
11
+ } from '../../types/skeleton';
12
+
13
+ let {
14
+ width = '100%',
15
+ mediaConfig = {},
16
+ animated = true
17
+ }: {
18
+ width?: string | number;
19
+ mediaConfig?: Partial<SkeletonMediaConfig>;
20
+ animated?: boolean;
21
+ } = $props();
22
+
23
+ // デフォルト設定
24
+ const DEFAULT_MEDIA_CONFIG: Partial<SkeletonMediaConfig> = {
25
+ type: 'media',
26
+ layout: 'horizontal',
27
+ thumbnailConfig: { width: '160px', aspectRatio: '16/9' },
28
+ textConfig: { width: '100%', lines: 2 }
29
+ };
30
+
31
+ // マージされた設定
32
+ const mergedMediaConfig = $derived({
33
+ ...DEFAULT_MEDIA_CONFIG,
34
+ ...mediaConfig
35
+ });
36
+
37
+ // レイアウト方向を取得
38
+ const layoutDirection = $derived(mergedMediaConfig.layout || 'horizontal');
39
+
40
+ // デフォルト設定
41
+ const DEFAULT_THUMBNAIL_CONFIG: SkeletonThumbnailConfig = {
42
+ type: 'thumbnail',
43
+ width: '120px',
44
+ radius: 'var(--svelte-ui-skeleton-button-border-radius)',
45
+ customStyle: ''
46
+ };
47
+ const DEFAULT_TEXT_CONFIG: SkeletonTextConfig = {
48
+ type: 'text',
49
+ width: '100%',
50
+ lines: 2,
51
+ customStyle: ''
52
+ };
53
+
54
+ // マージされた設定
55
+ const mergedThumbnailConfig = $derived({
56
+ ...DEFAULT_THUMBNAIL_CONFIG,
57
+ ...(mergedMediaConfig.thumbnailConfig || {})
58
+ });
59
+
60
+ const mergedTextConfig = $derived({
61
+ ...DEFAULT_TEXT_CONFIG,
62
+ ...(mergedMediaConfig.textConfig || {})
63
+ });
64
+
65
+ const widthStyle = $derived(getStyleFromNumber(width));
66
+ const thumbnailWidthStyle = $derived(getStyleFromNumber(mergedThumbnailConfig.width));
67
+ const thumbnailHeightStyle = $derived(
68
+ mergedThumbnailConfig.height ? getStyleFromNumber(mergedThumbnailConfig.height) : ''
69
+ );
70
+ const textWidthStyle = $derived(getStyleFromNumber(mergedTextConfig.width));
71
+
72
+ // heightとaspectRatioの優先順位を制御
73
+ const finalThumbnailHeight = $derived(mergedThumbnailConfig.height ? thumbnailHeightStyle : '');
74
+ const finalThumbnailAspectRatio = $derived(
75
+ mergedThumbnailConfig.height ? undefined : mergedThumbnailConfig.aspectRatio
76
+ );
77
+ </script>
78
+
79
+ <div
80
+ class="skeleton-media"
81
+ class:skeleton-media--vertical={layoutDirection === 'vertical'}
82
+ style="width: {widthStyle}"
83
+ >
84
+ <SkeletonBox
85
+ width={thumbnailWidthStyle}
86
+ {...finalThumbnailHeight && { height: finalThumbnailHeight }}
87
+ aspectRatio={finalThumbnailAspectRatio}
88
+ radius={mergedThumbnailConfig.radius}
89
+ {animated}
90
+ customStyle={mergedThumbnailConfig.customStyle}
91
+ />
92
+ <SkeletonText
93
+ textConfig={{
94
+ width: textWidthStyle,
95
+ lines: mergedTextConfig.lines,
96
+ fontSize: mergedTextConfig.fontSize
97
+ }}
98
+ {animated}
99
+ />
100
+ </div>
101
+
102
+ <style>
103
+ .skeleton-media {
104
+ display: grid;
105
+ grid-template-columns: auto 1fr;
106
+ gap: 16px;
107
+ }
108
+
109
+ .skeleton-media--vertical {
110
+ grid-template-columns: 1fr;
111
+ grid-template-rows: auto 1fr;
112
+ justify-items: center;
113
+ gap: 8px;
114
+ }
115
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { SkeletonMediaConfig } from '../../types/skeleton';
2
+ type $$ComponentProps = {
3
+ width?: string | number;
4
+ mediaConfig?: Partial<SkeletonMediaConfig>;
5
+ animated?: boolean;
6
+ };
7
+ declare const SkeletonMedia: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type SkeletonMedia = ReturnType<typeof SkeletonMedia>;
9
+ export default SkeletonMedia;
@@ -0,0 +1,75 @@
1
+ <!-- SkeletonText.svelte -->
2
+
3
+ <script lang="ts">
4
+ import SkeletonBox from './SkeletonBox.svelte';
5
+ import { getStyleFromNumber } from '../../utils/style';
6
+ import type { SkeletonTextConfig } from '../../types/skeleton';
7
+
8
+ // =========================================================================
9
+ // Props
10
+ // =========================================================================
11
+
12
+ let {
13
+ // 基本プロパティ
14
+ textConfig = {},
15
+ animated = true
16
+ }: {
17
+ textConfig?: Partial<SkeletonTextConfig>;
18
+ animated?: boolean;
19
+ } = $props();
20
+
21
+ // デフォルト設定
22
+ const DEFAULT_TEXT_CONFIG: SkeletonTextConfig = {
23
+ type: 'text',
24
+ width: '100%',
25
+ lines: 1,
26
+ customStyle: ''
27
+ };
28
+
29
+ // マージされた設定
30
+ const mergedTextConfig = $derived({
31
+ ...DEFAULT_TEXT_CONFIG,
32
+ ...textConfig
33
+ });
34
+
35
+ // =========================================================================
36
+ // State
37
+ // =========================================================================
38
+
39
+ let containerRef: HTMLDivElement;
40
+
41
+ // =========================================================================
42
+ // $derived
43
+ // =========================================================================
44
+
45
+ const widthStyle = $derived(getStyleFromNumber(mergedTextConfig.width));
46
+ const fontSizeStyle = $derived(getStyleFromNumber(mergedTextConfig.fontSize));
47
+ </script>
48
+
49
+ <div
50
+ bind:this={containerRef}
51
+ class="skeleton-text"
52
+ style="font-size: {fontSizeStyle}; {mergedTextConfig.customStyle}"
53
+ >
54
+ {#each Array(mergedTextConfig.lines) as _, index}
55
+ <div class="skeleton-text__line" style="width: {widthStyle}">
56
+ <SkeletonBox
57
+ width="100%"
58
+ height="1em"
59
+ radius="var(--svelte-ui-skeleton-text-border-radius)"
60
+ {animated}
61
+ />
62
+ </div>
63
+ {/each}
64
+ </div>
65
+
66
+ <style>.skeleton-text {
67
+ display: block;
68
+ width: 100%;
69
+ }
70
+
71
+ .skeleton-text__line {
72
+ display: inline-block;
73
+ position: relative;
74
+ width: 100%;
75
+ }</style>
@@ -0,0 +1,8 @@
1
+ import type { SkeletonTextConfig } from '../../types/skeleton';
2
+ type $$ComponentProps = {
3
+ textConfig?: Partial<SkeletonTextConfig>;
4
+ animated?: boolean;
5
+ };
6
+ declare const SkeletonText: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type SkeletonText = ReturnType<typeof SkeletonText>;
8
+ export default SkeletonText;
@@ -0,0 +1,42 @@
1
+ export { default as Button } from './components/Button.svelte';
2
+ export { default as Checkbox } from './components/Checkbox.svelte';
3
+ export { default as CheckboxGroup } from './components/CheckboxGroup.svelte';
4
+ export { default as ColorPicker } from './components/ColorPicker.svelte';
5
+ export { default as Combobox } from './components/Combobox.svelte';
6
+ export { default as ConfirmDialog } from './components/ConfirmDialog.svelte';
7
+ export { default as Datepicker } from './components/Datepicker.svelte';
8
+ export { default as DatepickerCalendar } from './components/DatepickerCalendar.svelte';
9
+ export { default as Dialog } from './components/Dialog.svelte';
10
+ export { default as Drawer } from './components/Drawer.svelte';
11
+ export { default as Fab } from './components/Fab.svelte';
12
+ export { default as FileUploader } from './components/FileUploader.svelte';
13
+ export { default as Icon } from './components/Icon.svelte';
14
+ export { default as IconButton } from './components/IconButton.svelte';
15
+ export { default as ImageUploader } from './components/ImageUploader.svelte';
16
+ export { default as Input } from './components/Input.svelte';
17
+ export { default as LoadingSpinner } from './components/LoadingSpinner.svelte';
18
+ export { default as Modal } from './components/Modal.svelte';
19
+ export { default as Pagination } from './components/Pagination.svelte';
20
+ export { default as Popup } from './components/Popup.svelte';
21
+ export { default as PopupMenu } from './components/PopupMenu.svelte';
22
+ export { default as PopupMenuButton } from './components/PopupMenuButton.svelte';
23
+ export { default as Radio } from './components/Radio.svelte';
24
+ export { default as RadioGroup } from './components/RadioGroup.svelte';
25
+ export { default as Select } from './components/Select.svelte';
26
+ export { default as Slider } from './components/Slider.svelte';
27
+ export { default as Snackbar } from './components/Snackbar.svelte';
28
+ export { default as SnackbarItem } from './components/SnackbarItem.svelte';
29
+ export { default as Skeleton } from './components/skeleton/Skeleton.svelte';
30
+ export { default as SkeletonText } from './components/skeleton/SkeletonText.svelte';
31
+ export { default as SkeletonBox } from './components/skeleton/SkeletonBox.svelte';
32
+ export { default as SkeletonAvatar } from './components/skeleton/SkeletonAvatar.svelte';
33
+ export { default as Switch } from './components/Switch.svelte';
34
+ export { default as Tab } from './components/Tab.svelte';
35
+ export { default as TabItem } from './components/TabItem.svelte';
36
+ export { default as Textarea } from './components/Textarea.svelte';
37
+ export * from './utils/accessibility';
38
+ export * from './utils/formatText';
39
+ export * from './utils/mobile';
40
+ export * from './utils/snackbar.svelte';
41
+ export * from './utils/style';
42
+ export type { MenuItem } from './types/menuItem';
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ // Components
2
+ export { default as Button } from './components/Button.svelte';
3
+ export { default as Checkbox } from './components/Checkbox.svelte';
4
+ export { default as CheckboxGroup } from './components/CheckboxGroup.svelte';
5
+ export { default as ColorPicker } from './components/ColorPicker.svelte';
6
+ export { default as Combobox } from './components/Combobox.svelte';
7
+ export { default as ConfirmDialog } from './components/ConfirmDialog.svelte';
8
+ export { default as Datepicker } from './components/Datepicker.svelte';
9
+ export { default as DatepickerCalendar } from './components/DatepickerCalendar.svelte';
10
+ export { default as Dialog } from './components/Dialog.svelte';
11
+ export { default as Drawer } from './components/Drawer.svelte';
12
+ export { default as Fab } from './components/Fab.svelte';
13
+ export { default as FileUploader } from './components/FileUploader.svelte';
14
+ export { default as Icon } from './components/Icon.svelte';
15
+ export { default as IconButton } from './components/IconButton.svelte';
16
+ export { default as ImageUploader } from './components/ImageUploader.svelte';
17
+ export { default as Input } from './components/Input.svelte';
18
+ export { default as LoadingSpinner } from './components/LoadingSpinner.svelte';
19
+ export { default as Modal } from './components/Modal.svelte';
20
+ export { default as Pagination } from './components/Pagination.svelte';
21
+ export { default as Popup } from './components/Popup.svelte';
22
+ export { default as PopupMenu } from './components/PopupMenu.svelte';
23
+ export { default as PopupMenuButton } from './components/PopupMenuButton.svelte';
24
+ export { default as Radio } from './components/Radio.svelte';
25
+ export { default as RadioGroup } from './components/RadioGroup.svelte';
26
+ export { default as Select } from './components/Select.svelte';
27
+ export { default as Slider } from './components/Slider.svelte';
28
+ export { default as Snackbar } from './components/Snackbar.svelte';
29
+ export { default as SnackbarItem } from './components/SnackbarItem.svelte';
30
+ export { default as Skeleton } from './components/skeleton/Skeleton.svelte';
31
+ export { default as SkeletonText } from './components/skeleton/SkeletonText.svelte';
32
+ export { default as SkeletonBox } from './components/skeleton/SkeletonBox.svelte';
33
+ export { default as SkeletonAvatar } from './components/skeleton/SkeletonAvatar.svelte';
34
+ export { default as Switch } from './components/Switch.svelte';
35
+ export { default as Tab } from './components/Tab.svelte';
36
+ export { default as TabItem } from './components/TabItem.svelte';
37
+ export { default as Textarea } from './components/Textarea.svelte';
38
+ // Utils
39
+ export * from './utils/accessibility';
40
+ export * from './utils/formatText';
41
+ export * from './utils/mobile';
42
+ export * from './utils/snackbar.svelte';
43
+ export * from './utils/style';
@@ -0,0 +1,4 @@
1
+ export type IconVariant = 'outlined' | 'rounded' | 'sharp';
2
+ export type IconWeight = 100 | 200 | 300 | 400 | 500 | 600 | 700;
3
+ export type IconGrade = number;
4
+ export type IconOpticalSize = number;
@@ -0,0 +1,2 @@
1
+ // Icon関連の型定義
2
+ export {};
@@ -0,0 +1,8 @@
1
+ export type MenuItem = {
2
+ title: string;
3
+ href?: string;
4
+ callback?: () => void;
5
+ icon?: string;
6
+ matchingPath?: string[];
7
+ strictMatch?: boolean;
8
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export type Option = {
2
+ value: OptionValue;
3
+ label: string;
4
+ disabled?: boolean;
5
+ };
6
+ export type OptionValue = string | number | null;
@@ -0,0 +1,4 @@
1
+ // =========================================================================
2
+ // Common Option Types
3
+ // =========================================================================
4
+ export {};
@@ -0,0 +1,77 @@
1
+ export type SkeletonPatternConfig = SkeletonBoxConfig | SkeletonTextConfig | SkeletonAvatarConfig | SkeletonMediaConfig | SkeletonButtonConfig | SkeletonHeadingConfig | SkeletonPresetConfig;
2
+ type SkeletonPatternCommonConfig = {
3
+ customStyle?: string;
4
+ repeat?: number;
5
+ repeatDirection?: 'horizontal' | 'vertical';
6
+ repeatGap?: string | number;
7
+ };
8
+ export type SkeletonBoxConfig = SkeletonPatternCommonConfig & {
9
+ type: 'box';
10
+ width?: string | number;
11
+ height?: string | number;
12
+ radius?: string | number;
13
+ };
14
+ export type SkeletonTextConfig = SkeletonPatternCommonConfig & {
15
+ type: 'text';
16
+ width?: string | number;
17
+ lines?: number;
18
+ fontSize?: string | number;
19
+ radius?: string | number;
20
+ };
21
+ export type SkeletonAvatarConfig = SkeletonPatternCommonConfig & {
22
+ type: 'avatar';
23
+ avatarImageConfig?: SkeletonAvatarImageConfig;
24
+ textConfig?: Partial<SkeletonTextConfig>;
25
+ showName?: boolean;
26
+ };
27
+ export type SkeletonAvatarImageConfig = SkeletonPatternCommonConfig & {
28
+ type: 'avatar-image';
29
+ size?: string | number;
30
+ radius?: string | number;
31
+ };
32
+ export type SkeletonMediaConfig = SkeletonPatternCommonConfig & {
33
+ type: 'media';
34
+ width?: string | number;
35
+ layout?: 'horizontal' | 'vertical';
36
+ thumbnailConfig?: Partial<SkeletonThumbnailConfig>;
37
+ textConfig?: Partial<SkeletonTextConfig>;
38
+ };
39
+ export type SkeletonThumbnailConfig = SkeletonPatternCommonConfig & {
40
+ type: 'thumbnail';
41
+ width?: string | number;
42
+ height?: string | number;
43
+ aspectRatio?: string | number;
44
+ radius?: string | number;
45
+ };
46
+ export type SkeletonButtonConfig = SkeletonPatternCommonConfig & {
47
+ type: 'button';
48
+ width?: string | number;
49
+ height?: string | number;
50
+ radius?: string | number;
51
+ align?: 'left' | 'center' | 'right';
52
+ };
53
+ export type SkeletonHeadingConfig = SkeletonPatternCommonConfig & {
54
+ type: 'heading';
55
+ width?: string | number;
56
+ fontSize?: string | number;
57
+ radius?: string | number;
58
+ };
59
+ export type SkeletonPresetConfig = SkeletonPatternCommonConfig & {
60
+ type: 'article-detail' | 'article-list' | 'product-list' | 'video-list' | 'user-list' | 'button-group';
61
+ layout?: 'horizontal' | 'vertical';
62
+ width?: string | number;
63
+ height?: string | number;
64
+ aspectRatio?: string | number;
65
+ radius?: string | number;
66
+ lines?: number;
67
+ fontSize?: string | number;
68
+ showName?: boolean;
69
+ align?: 'left' | 'center' | 'right';
70
+ thumbnailConfig?: Partial<SkeletonThumbnailConfig>;
71
+ textConfig?: Partial<SkeletonTextConfig>;
72
+ avatarImageConfig?: SkeletonAvatarImageConfig;
73
+ };
74
+ export declare const isPresetPattern: (pattern: SkeletonPatternConfig) => pattern is SkeletonPresetConfig;
75
+ export declare const isMediaPattern: (pattern: SkeletonPatternConfig) => pattern is SkeletonMediaConfig;
76
+ export declare const isAvatarPattern: (pattern: SkeletonPatternConfig) => pattern is SkeletonAvatarConfig;
77
+ export {};
@@ -0,0 +1,19 @@
1
+ // =========================================================================
2
+ // Type Guards
3
+ // =========================================================================
4
+ export const isPresetPattern = (pattern) => {
5
+ return [
6
+ 'article-detail',
7
+ 'article-list',
8
+ 'product-list',
9
+ 'video-list',
10
+ 'user-list',
11
+ 'button-group'
12
+ ].includes(pattern.type);
13
+ };
14
+ export const isMediaPattern = (pattern) => {
15
+ return pattern.type === 'media';
16
+ };
17
+ export const isAvatarPattern = (pattern) => {
18
+ return pattern.type === 'avatar';
19
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * スクリーンリーダー向けアナウンス機能
3
+ * アクセシビリティを向上させるために、UIの状態変化をスクリーンリーダーに通知する
4
+ */
5
+ /**
6
+ * スクリーンリーダーにメッセージをアナウンスする
7
+ * @param message - アナウンスするメッセージ
8
+ * @param priority - アナウンスの優先度('polite' | 'assertive')
9
+ * @param delay - 要素を削除するまでの時間(ミリ秒)
10
+ */
11
+ export declare const announceToScreenReader: (message: string, priority?: "polite" | "assertive", delay?: number) => void;
12
+ /**
13
+ * コンポーネントの開閉状態をアナウンスする
14
+ * @param componentName - コンポーネント名
15
+ * @param isOpen - 開閉状態
16
+ * @param title - タイトル(任意)
17
+ */
18
+ export declare const announceOpenClose: (componentName: string, isOpen: boolean, title?: string) => void;
19
+ /**
20
+ * 値の変更をアナウンスする
21
+ * @param field - フィールド名
22
+ * @param value - 新しい値
23
+ * @param unit - 単位(任意)
24
+ */
25
+ export declare const announceValueChange: (field: string, value: string | number, unit?: string) => void;
26
+ /**
27
+ * エラーメッセージをアナウンスする
28
+ * @param message - エラーメッセージ
29
+ */
30
+ export declare const announceError: (message: string) => void;
31
+ /**
32
+ * 成功メッセージをアナウンスする
33
+ * @param message - 成功メッセージ
34
+ */
35
+ export declare const announceSuccess: (message: string) => void;
36
+ /**
37
+ * 読み込み状態をアナウンスする
38
+ * @param isLoading - 読み込み状態
39
+ * @param message - カスタムメッセージ(任意)
40
+ */
41
+ export declare const announceLoading: (isLoading: boolean, message?: string) => void;
42
+ /**
43
+ * 選択状態をアナウンスする
44
+ * @param item - 選択されたアイテム
45
+ * @param total - 全体数(任意)
46
+ * @param index - インデックス(任意)
47
+ */
48
+ export declare const announceSelection: (item: string, total?: number, index?: number) => void;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * スクリーンリーダー向けアナウンス機能
3
+ * アクセシビリティを向上させるために、UIの状態変化をスクリーンリーダーに通知する
4
+ */
5
+ /**
6
+ * スクリーンリーダーにメッセージをアナウンスする
7
+ * @param message - アナウンスするメッセージ
8
+ * @param priority - アナウンスの優先度('polite' | 'assertive')
9
+ * @param delay - 要素を削除するまでの時間(ミリ秒)
10
+ */
11
+ export const announceToScreenReader = (message, priority = 'polite', delay = 1000) => {
12
+ if (!message.trim())
13
+ return;
14
+ const announcement = document.createElement('div');
15
+ announcement.setAttribute('aria-live', priority);
16
+ announcement.setAttribute('aria-atomic', 'true');
17
+ announcement.className = 'sr-only';
18
+ announcement.textContent = message;
19
+ document.body.appendChild(announcement);
20
+ // アナウンス後に削除
21
+ setTimeout(() => {
22
+ if (document.body.contains(announcement)) {
23
+ document.body.removeChild(announcement);
24
+ }
25
+ }, delay);
26
+ };
27
+ /**
28
+ * コンポーネントの開閉状態をアナウンスする
29
+ * @param componentName - コンポーネント名
30
+ * @param isOpen - 開閉状態
31
+ * @param title - タイトル(任意)
32
+ */
33
+ export const announceOpenClose = (componentName, isOpen, title) => {
34
+ const displayName = title || componentName;
35
+ const status = isOpen ? 'opened' : 'closed';
36
+ announceToScreenReader(`${displayName} ${status}`);
37
+ };
38
+ /**
39
+ * 値の変更をアナウンスする
40
+ * @param field - フィールド名
41
+ * @param value - 新しい値
42
+ * @param unit - 単位(任意)
43
+ */
44
+ export const announceValueChange = (field, value, unit) => {
45
+ const unitText = unit ? ` ${unit}` : '';
46
+ announceToScreenReader(`${field} changed to ${value}${unitText}`);
47
+ };
48
+ /**
49
+ * エラーメッセージをアナウンスする
50
+ * @param message - エラーメッセージ
51
+ */
52
+ export const announceError = (message) => {
53
+ announceToScreenReader(`Error: ${message}`, 'assertive');
54
+ };
55
+ /**
56
+ * 成功メッセージをアナウンスする
57
+ * @param message - 成功メッセージ
58
+ */
59
+ export const announceSuccess = (message) => {
60
+ announceToScreenReader(`Success: ${message}`, 'polite');
61
+ };
62
+ /**
63
+ * 読み込み状態をアナウンスする
64
+ * @param isLoading - 読み込み状態
65
+ * @param message - カスタムメッセージ(任意)
66
+ */
67
+ export const announceLoading = (isLoading, message) => {
68
+ if (isLoading) {
69
+ announceToScreenReader(message || 'Loading started', 'polite');
70
+ }
71
+ else {
72
+ announceToScreenReader(message || 'Loading completed', 'polite');
73
+ }
74
+ };
75
+ /**
76
+ * 選択状態をアナウンスする
77
+ * @param item - 選択されたアイテム
78
+ * @param total - 全体数(任意)
79
+ * @param index - インデックス(任意)
80
+ */
81
+ export const announceSelection = (item, total, index) => {
82
+ let message = `${item} selected`;
83
+ if (typeof index === 'number' && typeof total === 'number') {
84
+ message += `, ${index + 1} of ${total}`;
85
+ }
86
+ announceToScreenReader(message);
87
+ };
@@ -0,0 +1,4 @@
1
+ export declare const convertToHtml: (value: string | number | null) => string | number | null;
2
+ export declare const convertToLink: (str: string) => string;
3
+ export declare const escapeHtml: (value: string) => string;
4
+ export declare const convertToHtmlWithLink: (value: string | number | null) => string | number | null;
@@ -0,0 +1,44 @@
1
+ import DOMPurify from 'dompurify';
2
+ export const convertToHtml = (value) => {
3
+ if (typeof value === 'string') {
4
+ const escapedValue = escapeHtml(value);
5
+ let html = escapedValue
6
+ .replace(/ +/g, (match) => '&nbsp;'.repeat(match.length))
7
+ .replace(/\n/g, '<br />');
8
+ // 最後の行が空だったら空白を追加
9
+ const lines = html.split('<br />');
10
+ if (lines.length > 0 && lines[lines.length - 1] === '') {
11
+ html += '&nbsp;';
12
+ }
13
+ return html;
14
+ }
15
+ else {
16
+ return value;
17
+ }
18
+ };
19
+ export const convertToLink = (str) => {
20
+ let text = str;
21
+ text = text.replace(/((http|https|ftp):\/\/[\w?=&./#~%-;,*!$'():@+]+(?![\w\s?&./#~%";,=*'()-]*>))/g, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a> ');
22
+ return text;
23
+ };
24
+ export const escapeHtml = (value) => {
25
+ const map = {
26
+ '&': '&amp;',
27
+ '<': '&lt;',
28
+ '>': '&gt;',
29
+ '"': '&quot;',
30
+ "'": '&#039;'
31
+ };
32
+ const escapedValue = value.replace(/[&<>"']/g, (m) => map[m]);
33
+ return DOMPurify.sanitize(escapedValue);
34
+ };
35
+ export const convertToHtmlWithLink = (value) => {
36
+ if (typeof value === 'string') {
37
+ const html = convertToHtml(value);
38
+ const htmlWithLink = convertToLink(html);
39
+ return htmlWithLink;
40
+ }
41
+ else {
42
+ return value;
43
+ }
44
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Mobile detection and utilities
3
+ */
4
+ export declare const isMobileDevice: () => boolean;
5
+ export declare const getViewportSize: () => {
6
+ width: number;
7
+ height: number;
8
+ };
9
+ export declare const disableBodyScroll: () => () => void;