@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,276 @@
1
+ <!-- Pagination.svelte -->
2
+
3
+ <script lang="ts">
4
+ import Icon from './Icon.svelte';
5
+ import { announceToScreenReader } from '../utils/accessibility';
6
+ import { t } from '../i18n';
7
+
8
+ // =========================================================================
9
+ // Props, States & Constants
10
+ // =========================================================================
11
+ let {
12
+ // 基本プロパティ
13
+ total,
14
+ limit = 100,
15
+ currentPageNum = 1,
16
+ visiblePages = 5,
17
+
18
+ // HTML属性
19
+ id,
20
+
21
+ // 状態/動作
22
+ showCount = true,
23
+ showRange = true,
24
+ showTotal = true,
25
+
26
+ // イベントハンドラー
27
+ onchange = () => {}
28
+ }: {
29
+ // 基本プロパティ
30
+ total: number;
31
+ limit: number;
32
+ currentPageNum: number;
33
+ visiblePages?: number;
34
+
35
+ // HTML属性
36
+ id?: string;
37
+
38
+ // 状態/動作
39
+ showCount?: boolean;
40
+ showRange?: boolean;
41
+ showTotal?: boolean;
42
+
43
+ // イベントハンドラー
44
+ onchange: (pageNum: number) => void;
45
+ } = $props();
46
+
47
+ // =========================================================================
48
+ // Methods
49
+ // =========================================================================
50
+ const handleClick = (pageNum: number) => {
51
+ onchange(pageNum);
52
+ announceToScreenReader(`Page ${pageNum} of ${totalPages}`);
53
+ };
54
+
55
+ const goFirstPage = () => {
56
+ onchange(1);
57
+ announceToScreenReader(`First page, page 1 of ${totalPages}`);
58
+ };
59
+
60
+ const goLastPage = () => {
61
+ onchange(totalPages);
62
+ announceToScreenReader(`Last page, page ${totalPages} of ${totalPages}`);
63
+ };
64
+
65
+ const goPrevPage = () => {
66
+ const newPage = currentPageNum - 1;
67
+ onchange(newPage);
68
+ announceToScreenReader(`Previous page, page ${newPage} of ${totalPages}`);
69
+ };
70
+
71
+ const goNextPage = () => {
72
+ const newPage = currentPageNum + 1;
73
+ onchange(newPage);
74
+ announceToScreenReader(`Next page, page ${newPage} of ${totalPages}`);
75
+ };
76
+
77
+ // =========================================================================
78
+ // $derived
79
+ // =========================================================================
80
+ const totalPages = $derived(Math.ceil(total / limit));
81
+
82
+ // ページリストとエリプシスを含む表示アイテムを生成
83
+ const pageItems = $derived.by(() => {
84
+ const items: Array<{ type: 'page' | 'ellipsis'; value: number | null }> = [];
85
+
86
+ if (totalPages <= visiblePages + 2) {
87
+ // 総ページ数が少ない場合は全て表示
88
+ return Array.from({ length: totalPages }, (_, i) => ({ type: 'page', value: i + 1 }));
89
+ }
90
+
91
+ // 現在のページを中心とした連続するページ範囲を計算
92
+ const half = Math.floor(visiblePages / 2);
93
+ let start = Math.max(1, currentPageNum - half);
94
+ let end = Math.min(totalPages, start + visiblePages - 1);
95
+
96
+ // 右端に寄りすぎた場合の調整
97
+ if (end === totalPages && end - start + 1 < visiblePages) {
98
+ start = Math.max(1, totalPages - visiblePages + 1);
99
+ }
100
+
101
+ // 1ページ目を追加(範囲に含まれていない場合)
102
+ if (start > 1) {
103
+ items.push({ type: 'page', value: 1 });
104
+
105
+ // ギャップがある場合はエリプシスを追加
106
+ if (start > 2) {
107
+ items.push({ type: 'ellipsis', value: null });
108
+ }
109
+ }
110
+
111
+ // メインの連続ページ範囲を追加
112
+ for (let i = start; i <= end; i++) {
113
+ items.push({ type: 'page', value: i });
114
+ }
115
+
116
+ // 最終ページを追加(範囲に含まれていない場合)
117
+ if (end < totalPages) {
118
+ // ギャップがある場合はエリプシスを追加
119
+ if (end < totalPages - 1) {
120
+ items.push({ type: 'ellipsis', value: null });
121
+ }
122
+
123
+ items.push({ type: 'page', value: totalPages });
124
+ }
125
+
126
+ return items;
127
+ });
128
+
129
+ // 現在のページのアイテム範囲を計算
130
+ const currentPageRange = $derived.by(() => {
131
+ const startItem = (currentPageNum - 1) * limit + 1;
132
+ const endItem = Math.min(currentPageNum * limit, total);
133
+ return { start: startItem, end: endItem };
134
+ });
135
+
136
+ // 表示用のテキストを生成
137
+ const rangeText = $derived.by(() => {
138
+ if (!showCount) return '';
139
+
140
+ const { start, end } = currentPageRange;
141
+ const parts: string[] = [];
142
+
143
+ if (showRange) {
144
+ parts.push(`${start.toLocaleString()} - ${end.toLocaleString()}`);
145
+ }
146
+
147
+ if (showTotal) {
148
+ parts.push(total.toLocaleString());
149
+ }
150
+
151
+ return parts.join(' / ');
152
+ });
153
+ </script>
154
+
155
+ <div class="pagination" {id}>
156
+ {#if showCount && rangeText}
157
+ <div class="pagination__count">{rangeText}</div>
158
+ {/if}
159
+ <ul class="pagination__list">
160
+ <li>
161
+ <button
162
+ class="pagination__button"
163
+ disabled={currentPageNum === 1}
164
+ aria-label={t('pagination.prevPage')}
165
+ onclick={goPrevPage}
166
+ >
167
+ <Icon>chevron_left</Icon>
168
+ </button>
169
+ </li>
170
+ {#each pageItems as item, index (item.type === 'page' ? `page-${item.value}` : `ellipsis-${index}`)}
171
+ <li>
172
+ {#if item.type === 'page'}
173
+ <button
174
+ class="pagination__button"
175
+ class:pagination__button--selected={item.value === currentPageNum}
176
+ aria-label={t('pagination.goToPage', { page: item.value })}
177
+ onclick={() => handleClick(item.value!)}
178
+ >
179
+ {item.value}
180
+ </button>
181
+ {:else}
182
+ <span class="pagination__ellipsis" aria-label={t('pagination.ellipsis')}>...</span>
183
+ {/if}
184
+ </li>
185
+ {/each}
186
+ <li>
187
+ <button
188
+ class="pagination__button"
189
+ disabled={currentPageNum === totalPages || totalPages === 0}
190
+ aria-label={t('pagination.nextPage')}
191
+ onclick={goNextPage}
192
+ >
193
+ <Icon>chevron_right</Icon>
194
+ </button>
195
+ </li>
196
+ </ul>
197
+ </div>
198
+
199
+ <style>
200
+ .pagination {
201
+ display: flex;
202
+ align-items: center;
203
+ gap: var(--svelte-ui-pagination-gap);
204
+ }
205
+ .pagination__count {
206
+ color: var(--svelte-ui-pagination-count-text-color);
207
+ white-space: nowrap;
208
+ }
209
+ .pagination__list {
210
+ display: flex;
211
+ gap: var(--svelte-ui-pagination-page-list-gap);
212
+ }
213
+ .pagination__button {
214
+ display: flex;
215
+ justify-content: center;
216
+ align-items: center;
217
+ position: relative;
218
+ min-width: var(--svelte-ui-pagination-button-size);
219
+ height: var(--svelte-ui-pagination-button-size);
220
+ padding: 0 4px;
221
+ background-color: transparent;
222
+ border: none;
223
+ border-radius: var(--svelte-ui-pagination-button-border-radius);
224
+ box-shadow: var(--svelte-ui-pagination-button-box-shadow);
225
+ line-height: 1px;
226
+ overflow: hidden;
227
+ color: var(--svelte-ui-pagination-button-text-color);
228
+ transition-duration: 0s;
229
+ }
230
+ .pagination__button:before {
231
+ content: '';
232
+ display: block;
233
+ position: absolute;
234
+ top: 0;
235
+ left: 0;
236
+ width: 100%;
237
+ height: 100%;
238
+ background-color: var(--svelte-ui-hover-overlay);
239
+ opacity: 0;
240
+ transition-property: opacity;
241
+ transition-duration: var(--svelte-ui-transition-duration);
242
+ z-index: 0;
243
+ }
244
+
245
+ @media (hover: hover) {
246
+ .pagination__button:hover:before {
247
+ opacity: 1;
248
+ }
249
+ }
250
+
251
+ .pagination__button--selected {
252
+ background-color: var(--svelte-ui-pagination-selected-button-bg);
253
+ box-shadow: var(--svelte-ui-pagination-selected-button-box-shadow);
254
+ color: var(--svelte-ui-pagination-selected-button-text-color);
255
+ }
256
+
257
+ .pagination__button:disabled {
258
+ opacity: 0.5;
259
+ cursor: not-allowed;
260
+ pointer-events: none;
261
+ }
262
+
263
+ .pagination__button:disabled:before {
264
+ opacity: 0;
265
+ }
266
+
267
+ .pagination__ellipsis {
268
+ display: flex;
269
+ justify-content: center;
270
+ align-items: center;
271
+ width: var(--svelte-ui-pagination-button-size);
272
+ height: var(--svelte-ui-pagination-button-size);
273
+ color: var(--svelte-ui-pagination-ellipsis-text-color);
274
+ user-select: none;
275
+ }
276
+ </style>
@@ -0,0 +1,14 @@
1
+ type $$ComponentProps = {
2
+ total: number;
3
+ limit: number;
4
+ currentPageNum: number;
5
+ visiblePages?: number;
6
+ id?: string;
7
+ showCount?: boolean;
8
+ showRange?: boolean;
9
+ showTotal?: boolean;
10
+ onchange: (pageNum: number) => void;
11
+ };
12
+ declare const Pagination: import("svelte").Component<$$ComponentProps, {}, "">;
13
+ type Pagination = ReturnType<typeof Pagination>;
14
+ export default Pagination;