@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,127 @@
1
+ # コンポーネント設計ガイドライン
2
+
3
+ ## ID命名ルール
4
+
5
+ ### コンポーネント内包時のID受け渡しルール
6
+
7
+ #### 基本ルール
8
+
9
+ - **親コンポーネント**: `id`プロパティを受け取る
10
+ - **子コンポーネント**: 受け取った`id`にsuffixを付けて自身のIDを生成
11
+ - **内部要素**: 受け取った`id`にsuffixを付けてIDを生成
12
+
13
+ #### 命名パターン
14
+
15
+ ```typescript
16
+ // 親 → 子コンポーネント
17
+ <ChildComponent id={id ? `${id}-child-suffix` : undefined} />
18
+
19
+ // 内部要素
20
+ <div id={id ? `${id}-element-suffix` : undefined}>
21
+ ```
22
+
23
+ #### 具体例
24
+
25
+ ```typescript
26
+ // ConfirmDialog → Dialog → Modal
27
+ <Dialog id={id ? `${id}-dialog` : undefined} />
28
+ <Modal id={id ? `${id}-modal` : undefined} />
29
+
30
+ // 内部要素
31
+ <div id={id ? `${id}-dialog-title` : undefined}>
32
+ <div id={id ? `${id}-modal-description` : undefined}>
33
+
34
+ // 他の例
35
+ <Input id={id ? `${id}-input` : undefined} />
36
+ <Popup id={id ? `${id}-popup` : undefined} />
37
+ <DatepickerCalendar id={id ? `${id}-calendar` : undefined} />
38
+ ```
39
+
40
+ #### 判断基準
41
+
42
+ - **✅ IDを渡すべき**: 1対1の親子関係、アクセシビリティ上重要な要素、テストで個別特定が必要
43
+ - **❌ IDを渡さない**: 同じコンポーネントが複数存在、内部実装の詳細、動的生成要素
44
+
45
+ ### 理由
46
+
47
+ - **階層構造の明確化**: `${id}-suffix`パターンにより、コンポーネントの階層関係が分かりやすい
48
+ - **グローバル一意性**: 親のIDをベースにすることで、DOM全体で一意なIDを保証
49
+ - **アクセシビリティ**: ARIA属性との連携で、スクリーンリーダーなどの支援技術に対応
50
+ - **テストの安定性**: 一意なIDにより、テストでの要素特定が確実
51
+
52
+ ## コンポーネント設計原則
53
+
54
+ ### プロパティ設計
55
+
56
+ - **基本プロパティ**: 必須の機能に関わるプロパティ
57
+ - **HTML属性**: 標準的なHTML属性(id, class, style等)
58
+ - **スタイル/レイアウト**: 見た目やレイアウトに関わるプロパティ
59
+ - **状態/動作**: コンポーネントの動作状態に関わるプロパティ
60
+ - **ARIA/アクセシビリティ**: アクセシビリティに関わるプロパティ
61
+ - **イベントハンドラー**: イベント処理に関わるプロパティ
62
+
63
+ ### イベントハンドラー設計
64
+
65
+ ```typescript
66
+ // Svelte 5の推奨パターン
67
+ onclick = () => {}, // パラメータなしで型推論を可能にする
68
+ onchange = () => {}, // パラメータなしで型推論を可能にする
69
+ ```
70
+
71
+ ### データテストID
72
+
73
+ - 最上位のDOM要素に`data-testid`を設定
74
+ - テストでの要素特定を容易にする
75
+ - コンポーネント名をベースに命名(例: `data-testid="dialog"`)
76
+
77
+ ## 実装例
78
+
79
+ ### 基本的なコンポーネント構造
80
+
81
+ ```svelte
82
+ <script lang="ts">
83
+ // Props, States & Constants
84
+ let {
85
+ // 基本プロパティ
86
+ title = 'Default Title',
87
+
88
+ // HTML属性
89
+ id,
90
+
91
+ // スタイル/レイアウト
92
+ variant = 'default',
93
+
94
+ // 状態/動作
95
+ isOpen = $bindable(false),
96
+
97
+ // イベントハンドラー
98
+ onclick = () => {}
99
+ }: {
100
+ // 型定義
101
+ title?: string;
102
+ id?: string;
103
+ variant?: 'default' | 'primary';
104
+ isOpen?: boolean;
105
+ onclick?: () => void;
106
+ } = $props();
107
+ </script>
108
+
109
+ <div class="component" {id} data-testid="component">
110
+ <!-- コンテンツ -->
111
+ </div>
112
+ ```
113
+
114
+ ### 内包コンポーネントの例
115
+
116
+ ```svelte
117
+ <script lang="ts">
118
+ let { id }: { id?: string } = $props();
119
+ </script>
120
+
121
+ <div class="parent" {id} data-testid="parent">
122
+ <ChildComponent id={id ? `${id}-child` : undefined} />
123
+ <div id={id ? `${id}-element` : undefined}>
124
+ <!-- 内部要素 -->
125
+ </div>
126
+ </div>
127
+ ```
@@ -0,0 +1,523 @@
1
+ <!-- Checkbox.svelte -->
2
+
3
+ <script lang="ts">
4
+ import { type Snippet } from 'svelte';
5
+ import type { HTMLInputAttributes } from 'svelte/elements';
6
+
7
+ // =========================================================================
8
+ // Props, States & Constants
9
+ // =========================================================================
10
+ let {
11
+ // Snippet
12
+ children,
13
+
14
+ // 基本プロパティ
15
+ name = '',
16
+ value = $bindable(false),
17
+ indeterminate = $bindable(false),
18
+
19
+ // HTML属性系
20
+ id = `checkbox-${Math.random().toString(36).substring(2, 15)}`,
21
+ inputAttributes,
22
+
23
+ // スタイル/レイアウト
24
+ size = 'medium',
25
+
26
+ // 状態/動作
27
+ disabled = false,
28
+ required = false,
29
+ reducedMotion = false,
30
+
31
+ // 入力イベント
32
+ onchange = () => {}, // No params for type inference
33
+
34
+ // フォーカスイベント
35
+ onfocus = () => {}, // No params for type inference
36
+ onblur = () => {}, // No params for type inference
37
+
38
+ // キーボードイベント
39
+ onkeydown = () => {}, // No params for type inference
40
+ onkeyup = () => {}, // No params for type inference
41
+
42
+ // マウスイベント
43
+ onclick = () => {}, // No params for type inference
44
+ onmousedown = () => {}, // No params for type inference
45
+ onmouseup = () => {}, // No params for type inference
46
+ onmouseenter = () => {}, // No params for type inference
47
+ onmouseleave = () => {}, // No params for type inference
48
+ onmouseover = () => {}, // No params for type inference
49
+ onmouseout = () => {}, // No params for type inference
50
+ oncontextmenu = () => {}, // No params for type inference
51
+ onauxclick = () => {}, // No params for type inference
52
+
53
+ // タッチイベント
54
+ ontouchstart = () => {}, // No params for type inference
55
+ ontouchend = () => {}, // No params for type inference
56
+ ontouchmove = () => {}, // No params for type inference
57
+ ontouchcancel = () => {}, // No params for type inference
58
+
59
+ // ポインターイベント
60
+ onpointerdown = () => {}, // No params for type inference
61
+ onpointerup = () => {}, // No params for type inference
62
+ onpointerenter = () => {}, // No params for type inference
63
+ onpointerleave = () => {}, // No params for type inference
64
+ onpointermove = () => {}, // No params for type inference
65
+ onpointercancel = () => {}, // No params for type inference
66
+
67
+ // その他
68
+ ...restProps
69
+ }: {
70
+ // Snippet
71
+ children?: Snippet;
72
+
73
+ // 基本プロパティ
74
+ name?: string;
75
+ value: boolean;
76
+ indeterminate?: boolean;
77
+
78
+ // HTML属性系
79
+ id?: string;
80
+ inputAttributes?: HTMLInputAttributes | undefined;
81
+
82
+ // スタイル/レイアウト
83
+ size?: 'small' | 'medium' | 'large';
84
+
85
+ // 状態/動作
86
+ disabled?: boolean;
87
+ required?: boolean;
88
+ reducedMotion?: boolean;
89
+
90
+ // 入力イベント
91
+ onchange?: (value: boolean) => void;
92
+
93
+ // フォーカスイベント
94
+ onfocus?: Function; // No params for type inference
95
+ onblur?: Function; // No params for type inference
96
+
97
+ // キーボードイベント
98
+ onkeydown?: Function; // No params for type inference
99
+ onkeyup?: Function; // No params for type inference
100
+
101
+ // マウスイベント
102
+ onclick?: Function; // No params for type inference
103
+ onmousedown?: Function; // No params for type inference
104
+ onmouseup?: Function; // No params for type inference
105
+ onmouseenter?: Function; // No params for type inference
106
+ onmouseleave?: Function; // No params for type inference
107
+ onmouseover?: Function; // No params for type inference
108
+ onmouseout?: Function; // No params for type inference
109
+ oncontextmenu?: Function; // No params for type inference
110
+ onauxclick?: Function; // No params for type inference
111
+
112
+ // タッチイベント
113
+ ontouchstart?: Function; // No params for type inference
114
+ ontouchend?: Function; // No params for type inference
115
+ ontouchmove?: Function; // No params for type inference
116
+ ontouchcancel?: Function; // No params for type inference
117
+
118
+ // ポインターイベント
119
+ onpointerdown?: Function; // No params for type inference
120
+ onpointerup?: Function; // No params for type inference
121
+ onpointerenter?: Function; // No params for type inference
122
+ onpointerleave?: Function; // No params for type inference
123
+ onpointermove?: Function; // No params for type inference
124
+ onpointercancel?: Function; // No params for type inference
125
+
126
+ // その他
127
+ [key: string]: any;
128
+ } = $props();
129
+
130
+ // =========================================================================
131
+ // $derived
132
+ // =========================================================================
133
+ const containerClasses = $derived(
134
+ [
135
+ 'checkbox',
136
+ `checkbox--${size}`,
137
+ disabled && 'checkbox--disabled',
138
+ reducedMotion && 'checkbox--no-motion'
139
+ ]
140
+ .filter(Boolean)
141
+ .join(' ')
142
+ );
143
+
144
+ // =========================================================================
145
+
146
+ // Methods
147
+ // =========================================================================
148
+ const handleFocus = (event: FocusEvent) => {
149
+ if (disabled) return;
150
+ onfocus(event);
151
+ };
152
+
153
+ const handleBlur = (event: FocusEvent) => {
154
+ if (disabled) return;
155
+ onblur(event);
156
+ };
157
+
158
+ const handleKeydown = (event: KeyboardEvent) => {
159
+ if (disabled) return;
160
+ if (event.key === ' ' || event.key === 'Enter') {
161
+ event.preventDefault();
162
+ value = !value;
163
+ onchange(value);
164
+ }
165
+ onkeydown(event);
166
+ };
167
+
168
+ const handleKeyup = (event: KeyboardEvent) => {
169
+ onkeyup(event);
170
+ };
171
+
172
+ // マウスイベント
173
+ const handleClick = (event: MouseEvent) => {
174
+ if (disabled) return;
175
+ onclick?.(event);
176
+ };
177
+
178
+ const handleMouseDown = (event: MouseEvent) => {
179
+ if (disabled) return;
180
+ onmousedown?.(event);
181
+ };
182
+
183
+ const handleMouseUp = (event: MouseEvent) => {
184
+ if (disabled) return;
185
+ onmouseup?.(event);
186
+ };
187
+
188
+ const handleMouseEnter = (event: MouseEvent) => {
189
+ if (disabled) return;
190
+ onmouseenter?.(event);
191
+ };
192
+
193
+ const handleMouseLeave = (event: MouseEvent) => {
194
+ if (disabled) return;
195
+ onmouseleave?.(event);
196
+ };
197
+
198
+ const handleMouseOver = (event: MouseEvent) => {
199
+ if (disabled) return;
200
+ onmouseover?.(event);
201
+ };
202
+
203
+ const handleMouseOut = (event: MouseEvent) => {
204
+ if (disabled) return;
205
+ onmouseout?.(event);
206
+ };
207
+
208
+ const handleContextMenu = (event: MouseEvent) => {
209
+ if (disabled) return;
210
+ oncontextmenu?.(event);
211
+ };
212
+
213
+ const handleAuxClick = (event: MouseEvent) => {
214
+ if (disabled) return;
215
+ onauxclick?.(event);
216
+ };
217
+
218
+ // タッチイベント
219
+ const handleTouchStart = (event: TouchEvent) => {
220
+ if (disabled) return;
221
+ ontouchstart?.(event);
222
+ };
223
+
224
+ const handleTouchEnd = (event: TouchEvent) => {
225
+ if (disabled) return;
226
+ ontouchend?.(event);
227
+ };
228
+
229
+ const handleTouchMove = (event: TouchEvent) => {
230
+ if (disabled) return;
231
+ ontouchmove?.(event);
232
+ };
233
+
234
+ const handleTouchCancel = (event: TouchEvent) => {
235
+ if (disabled) return;
236
+ ontouchcancel?.(event);
237
+ };
238
+
239
+ // ポインターイベント
240
+ const handlePointerDown = (event: PointerEvent) => {
241
+ if (disabled) return;
242
+ onpointerdown?.(event);
243
+ };
244
+
245
+ const handlePointerUp = (event: PointerEvent) => {
246
+ if (disabled) return;
247
+ onpointerup?.(event);
248
+ };
249
+
250
+ const handlePointerEnter = (event: PointerEvent) => {
251
+ if (disabled) return;
252
+ onpointerenter?.(event);
253
+ };
254
+
255
+ const handlePointerLeave = (event: PointerEvent) => {
256
+ if (disabled) return;
257
+ onpointerleave?.(event);
258
+ };
259
+
260
+ const handlePointerMove = (event: PointerEvent) => {
261
+ if (disabled) return;
262
+ onpointermove?.(event);
263
+ };
264
+
265
+ const handlePointerCancel = (event: PointerEvent) => {
266
+ if (disabled) return;
267
+ onpointercancel?.(event);
268
+ };
269
+
270
+ // 変更イベント
271
+ const handleChange = (event: Event) => {
272
+ onchange(value);
273
+ };
274
+ </script>
275
+
276
+ <div class={containerClasses} data-testid="checkbox">
277
+ <input
278
+ type="checkbox"
279
+ bind:checked={value}
280
+ bind:indeterminate
281
+ {id}
282
+ {name}
283
+ {disabled}
284
+ {required}
285
+ aria-invalid={false}
286
+ aria-required={required ? 'true' : 'false'}
287
+ aria-describedby={undefined}
288
+ onfocus={handleFocus}
289
+ onblur={handleBlur}
290
+ onkeydown={handleKeydown}
291
+ onkeyup={handleKeyup}
292
+ onclick={handleClick}
293
+ onmousedown={handleMouseDown}
294
+ onmouseup={handleMouseUp}
295
+ onmouseenter={handleMouseEnter}
296
+ onmouseleave={handleMouseLeave}
297
+ onmouseover={handleMouseOver}
298
+ onmouseout={handleMouseOut}
299
+ oncontextmenu={handleContextMenu}
300
+ onauxclick={handleAuxClick}
301
+ ontouchstart={handleTouchStart}
302
+ ontouchend={handleTouchEnd}
303
+ ontouchmove={handleTouchMove}
304
+ ontouchcancel={handleTouchCancel}
305
+ onpointerdown={handlePointerDown}
306
+ onpointerup={handlePointerUp}
307
+ onpointerenter={handlePointerEnter}
308
+ onpointerleave={handlePointerLeave}
309
+ onpointermove={handlePointerMove}
310
+ onpointercancel={handlePointerCancel}
311
+ onchange={handleChange}
312
+ {...inputAttributes}
313
+ {...restProps}
314
+ />
315
+ <label for={id} class="checkbox__icon"></label>
316
+
317
+ {#if children}
318
+ <label for={id} class="checkbox__label">
319
+ {@render children()}
320
+ </label>
321
+ {/if}
322
+ </div>
323
+
324
+ <style>
325
+ /* =========================================================================
326
+ * Base Styles
327
+ * ========================================================================= */
328
+
329
+ .checkbox {
330
+ display: flex;
331
+ align-items: center;
332
+ width: fit-content;
333
+ contain: layout;
334
+ }
335
+
336
+ .checkbox input[type='checkbox'] {
337
+ position: absolute;
338
+ width: 16px;
339
+ height: 16px;
340
+ margin: 0;
341
+ opacity: 0;
342
+ cursor: pointer;
343
+ }
344
+
345
+ /* Label */
346
+ .checkbox__label {
347
+ display: flex;
348
+ align-items: center;
349
+ min-height: var(--svelte-ui-checkbox-min-height);
350
+ padding-left: var(--svelte-ui-checkbox-gap);
351
+ white-space: nowrap;
352
+ font-size: inherit;
353
+ color: inherit;
354
+ cursor: pointer;
355
+ }
356
+
357
+ /* Checkbox box */
358
+ .checkbox__icon {
359
+ position: relative;
360
+ width: var(--svelte-ui-checkbox-size);
361
+ height: var(--svelte-ui-checkbox-size);
362
+ border: var(--svelte-ui-checkbox-border-width) solid var(--svelte-ui-checkbox-border-color);
363
+ border-radius: var(--svelte-ui-checkbox-border-radius);
364
+ background-color: transparent;
365
+ transition-property: background-color, border-color, opacity;
366
+ transition-duration: var(--svelte-ui-transition-duration);
367
+ flex-shrink: 0;
368
+ cursor: pointer;
369
+ }
370
+
371
+ /* Check mark */
372
+ .checkbox__icon::after {
373
+ content: 'check';
374
+ position: absolute;
375
+ top: 50%;
376
+ left: 50%;
377
+ transform: translate(-50%, -50%);
378
+ width: fit-content;
379
+ clip-path: inset(0 100% 0 0);
380
+ font-size: var(--svelte-ui-checkbox-icon-size);
381
+ font-family: 'Material Symbols Outlined';
382
+ font-weight: bold;
383
+ font-style: normal;
384
+ color: var(--svelte-ui-checkbox-icon-color);
385
+ text-align: center;
386
+ line-height: 1;
387
+ letter-spacing: normal;
388
+ text-transform: none;
389
+ display: inline-block;
390
+ white-space: nowrap;
391
+ word-wrap: normal;
392
+ direction: ltr;
393
+ font-feature-settings: 'liga';
394
+ -webkit-font-smoothing: antialiased;
395
+ opacity: 0;
396
+ transition-property: clip-path, opacity;
397
+ transition-delay: 0s, 0s;
398
+ transition-duration: var(--svelte-ui-transition-duration), var(--svelte-ui-transition-duration);
399
+ }
400
+
401
+ /* =========================================================================
402
+ State Modifiers
403
+ ========================================================================= */
404
+
405
+ /* Disabled state */
406
+ .checkbox--disabled input[type='checkbox'] {
407
+ cursor: not-allowed;
408
+ }
409
+
410
+ .checkbox--disabled .checkbox__label {
411
+ opacity: var(--svelte-ui-button-disabled-opacity);
412
+ cursor: not-allowed;
413
+ }
414
+
415
+ /* Checked state */
416
+ input[type='checkbox']:checked + .checkbox__icon::after {
417
+ width: var(--svelte-ui-checkbox-icon-width);
418
+ clip-path: inset(0 0 0 0);
419
+ opacity: 1;
420
+ transition-delay:
421
+ var(--svelte-ui-transition-duration-fast), var(--svelte-ui-transition-duration-fast);
422
+ }
423
+
424
+ /* Indeterminate state */
425
+ input[type='checkbox']:indeterminate + .checkbox__icon::after {
426
+ content: 'remove';
427
+ width: var(--svelte-ui-checkbox-icon-width);
428
+ opacity: 1;
429
+ transition-delay:
430
+ var(--svelte-ui-transition-duration-fast), var(--svelte-ui-transition-duration-fast);
431
+ }
432
+
433
+ /* Hover states */
434
+ @media (hover: hover) {
435
+ .checkbox:not(.checkbox--disabled):hover .checkbox__icon {
436
+ border-color: var(--svelte-ui-checkbox-hover-color);
437
+ }
438
+ }
439
+
440
+ /* Focus states */
441
+ input[type='checkbox']:focus-visible + .checkbox__icon {
442
+ outline: var(--svelte-ui-focus-outline-outer);
443
+ outline-offset: var(--svelte-ui-focus-outline-offset-outer);
444
+ }
445
+
446
+ /* Checked/Indeterminate background */
447
+ input[type='checkbox']:checked + .checkbox__icon,
448
+ input[type='checkbox']:indeterminate + .checkbox__icon {
449
+ background-color: var(--svelte-ui-checkbox-bg-checked);
450
+ border-color: transparent;
451
+ }
452
+
453
+ /* =========================================================================
454
+ * Size Variants
455
+ * ========================================================================= */
456
+
457
+ .checkbox--small {
458
+ font-size: inherit;
459
+ }
460
+
461
+ .checkbox--small .checkbox__label {
462
+ min-height: var(--svelte-ui-checkbox-min-height-sm);
463
+ }
464
+
465
+ .checkbox--small .checkbox__icon {
466
+ width: var(--svelte-ui-checkbox-size-sm);
467
+ height: var(--svelte-ui-checkbox-size-sm);
468
+ }
469
+
470
+ .checkbox--small .checkbox__icon::after {
471
+ font-size: var(--svelte-ui-checkbox-icon-size-sm);
472
+ }
473
+
474
+ .checkbox--large {
475
+ font-size: inherit;
476
+ }
477
+
478
+ .checkbox--large .checkbox__label {
479
+ min-height: var(--svelte-ui-checkbox-min-height-lg);
480
+ }
481
+
482
+ .checkbox--large .checkbox__icon {
483
+ width: var(--svelte-ui-checkbox-size-lg);
484
+ height: var(--svelte-ui-checkbox-size-lg);
485
+ }
486
+
487
+ .checkbox--large .checkbox__icon::after {
488
+ font-size: var(--svelte-ui-checkbox-icon-size-lg);
489
+ }
490
+
491
+ /* =========================================================================
492
+ * Motion & Media Queries
493
+ * ========================================================================= */
494
+
495
+ /* Mobile touch targets */
496
+ @media (hover: none) and (pointer: coarse) {
497
+ .checkbox__label {
498
+ min-height: var(--svelte-ui-touch-target);
499
+ }
500
+
501
+ .checkbox--small .checkbox__label {
502
+ min-height: var(--svelte-ui-touch-target-sm);
503
+ }
504
+
505
+ .checkbox--large .checkbox__label {
506
+ min-height: var(--svelte-ui-touch-target-lg);
507
+ }
508
+ }
509
+
510
+ /* Reduced motion */
511
+ .checkbox--no-motion .checkbox__icon,
512
+ .checkbox--no-motion .checkbox__icon::after {
513
+ transition-duration: 0.01s;
514
+ }
515
+
516
+ /* Prefers reduced motion */
517
+ @media (prefers-reduced-motion: reduce) {
518
+ .checkbox__icon,
519
+ .checkbox__icon::after {
520
+ transition-duration: 0.01s;
521
+ }
522
+ }
523
+ </style>
@@ -0,0 +1,42 @@
1
+ import { type Snippet } from 'svelte';
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ type $$ComponentProps = {
4
+ children?: Snippet;
5
+ name?: string;
6
+ value: boolean;
7
+ indeterminate?: boolean;
8
+ id?: string;
9
+ inputAttributes?: HTMLInputAttributes | undefined;
10
+ size?: 'small' | 'medium' | 'large';
11
+ disabled?: boolean;
12
+ required?: boolean;
13
+ reducedMotion?: boolean;
14
+ onchange?: (value: boolean) => void;
15
+ onfocus?: Function;
16
+ onblur?: Function;
17
+ onkeydown?: Function;
18
+ onkeyup?: Function;
19
+ onclick?: Function;
20
+ onmousedown?: Function;
21
+ onmouseup?: Function;
22
+ onmouseenter?: Function;
23
+ onmouseleave?: Function;
24
+ onmouseover?: Function;
25
+ onmouseout?: Function;
26
+ oncontextmenu?: Function;
27
+ onauxclick?: Function;
28
+ ontouchstart?: Function;
29
+ ontouchend?: Function;
30
+ ontouchmove?: Function;
31
+ ontouchcancel?: Function;
32
+ onpointerdown?: Function;
33
+ onpointerup?: Function;
34
+ onpointerenter?: Function;
35
+ onpointerleave?: Function;
36
+ onpointermove?: Function;
37
+ onpointercancel?: Function;
38
+ [key: string]: any;
39
+ };
40
+ declare const Checkbox: import("svelte").Component<$$ComponentProps, {}, "value" | "indeterminate">;
41
+ type Checkbox = ReturnType<typeof Checkbox>;
42
+ export default Checkbox;