@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.
- package/README.md +359 -0
- package/dist/assets/styles/README.md +144 -0
- package/dist/assets/styles/core.scss +61 -0
- package/dist/assets/styles/import.scss +11 -0
- package/dist/assets/styles/optional/fonts.scss +23 -0
- package/dist/assets/styles/optional/reset.scss +230 -0
- package/dist/assets/styles/variables.scss +805 -0
- package/dist/components/Button.svelte +574 -0
- package/dist/components/Button.svelte.d.ts +56 -0
- package/dist/components/COMPONENT_DESIGN_GUIDELINES.md +127 -0
- package/dist/components/Checkbox.svelte +523 -0
- package/dist/components/Checkbox.svelte.d.ts +42 -0
- package/dist/components/CheckboxGroup.svelte +82 -0
- package/dist/components/CheckboxGroup.svelte.d.ts +13 -0
- package/dist/components/ColorPicker.svelte +496 -0
- package/dist/components/ColorPicker.svelte.d.ts +45 -0
- package/dist/components/Combobox.svelte +576 -0
- package/dist/components/Combobox.svelte.d.ts +52 -0
- package/dist/components/ConfirmDialog.svelte +116 -0
- package/dist/components/ConfirmDialog.svelte.d.ts +20 -0
- package/dist/components/Datepicker.svelte +578 -0
- package/dist/components/Datepicker.svelte.d.ts +72 -0
- package/dist/components/DatepickerCalendar.svelte +925 -0
- package/dist/components/DatepickerCalendar.svelte.d.ts +31 -0
- package/dist/components/Dialog.svelte +245 -0
- package/dist/components/Dialog.svelte.d.ts +38 -0
- package/dist/components/Drawer.svelte +383 -0
- package/dist/components/Drawer.svelte.d.ts +39 -0
- package/dist/components/Fab.svelte +486 -0
- package/dist/components/Fab.svelte.d.ts +51 -0
- package/dist/components/FileUploader.svelte +456 -0
- package/dist/components/FileUploader.svelte.d.ts +36 -0
- package/dist/components/Icon.svelte +167 -0
- package/dist/components/Icon.svelte.d.ts +21 -0
- package/dist/components/IconButton.svelte +557 -0
- package/dist/components/IconButton.svelte.d.ts +60 -0
- package/dist/components/ImageUploader.svelte +516 -0
- package/dist/components/ImageUploader.svelte.d.ts +37 -0
- package/dist/components/ImageUploaderPreview.svelte +157 -0
- package/dist/components/ImageUploaderPreview.svelte.d.ts +13 -0
- package/dist/components/Input.svelte +885 -0
- package/dist/components/Input.svelte.d.ts +75 -0
- package/dist/components/LoadingSpinner.svelte +116 -0
- package/dist/components/LoadingSpinner.svelte.d.ts +10 -0
- package/dist/components/Modal.svelte +313 -0
- package/dist/components/Modal.svelte.d.ts +34 -0
- package/dist/components/Pagination.svelte +276 -0
- package/dist/components/Pagination.svelte.d.ts +14 -0
- package/dist/components/Popup.svelte +676 -0
- package/dist/components/Popup.svelte.d.ts +40 -0
- package/dist/components/PopupMenu.svelte +421 -0
- package/dist/components/PopupMenu.svelte.d.ts +24 -0
- package/dist/components/PopupMenuButton.svelte +365 -0
- package/dist/components/PopupMenuButton.svelte.d.ts +42 -0
- package/dist/components/Radio.svelte +548 -0
- package/dist/components/Radio.svelte.d.ts +42 -0
- package/dist/components/RadioGroup.svelte +74 -0
- package/dist/components/RadioGroup.svelte.d.ts +14 -0
- package/dist/components/Select.svelte +479 -0
- package/dist/components/Select.svelte.d.ts +47 -0
- package/dist/components/Slider.svelte +473 -0
- package/dist/components/Slider.svelte.d.ts +46 -0
- package/dist/components/Snackbar.svelte +124 -0
- package/dist/components/Snackbar.svelte.d.ts +9 -0
- package/dist/components/SnackbarItem.svelte +423 -0
- package/dist/components/SnackbarItem.svelte.d.ts +21 -0
- package/dist/components/Switch.svelte +454 -0
- package/dist/components/Switch.svelte.d.ts +40 -0
- package/dist/components/Tab.svelte +193 -0
- package/dist/components/Tab.svelte.d.ts +14 -0
- package/dist/components/TabItem.svelte +140 -0
- package/dist/components/TabItem.svelte.d.ts +17 -0
- package/dist/components/Textarea.svelte +702 -0
- package/dist/components/Textarea.svelte.d.ts +64 -0
- package/dist/components/skeleton/Skeleton.svelte +235 -0
- package/dist/components/skeleton/Skeleton.svelte.d.ts +13 -0
- package/dist/components/skeleton/SkeletonAvatar.svelte +97 -0
- package/dist/components/skeleton/SkeletonAvatar.svelte.d.ts +8 -0
- package/dist/components/skeleton/SkeletonBox.svelte +105 -0
- package/dist/components/skeleton/SkeletonBox.svelte.d.ts +12 -0
- package/dist/components/skeleton/SkeletonButton.svelte +71 -0
- package/dist/components/skeleton/SkeletonButton.svelte.d.ts +8 -0
- package/dist/components/skeleton/SkeletonHeading.svelte +49 -0
- package/dist/components/skeleton/SkeletonHeading.svelte.d.ts +8 -0
- package/dist/components/skeleton/SkeletonMedia.svelte +115 -0
- package/dist/components/skeleton/SkeletonMedia.svelte.d.ts +9 -0
- package/dist/components/skeleton/SkeletonText.svelte +75 -0
- package/dist/components/skeleton/SkeletonText.svelte.d.ts +8 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +43 -0
- package/dist/types/icon.d.ts +4 -0
- package/dist/types/icon.js +2 -0
- package/dist/types/menuItem.d.ts +8 -0
- package/dist/types/menuItem.js +1 -0
- package/dist/types/options.d.ts +6 -0
- package/dist/types/options.js +4 -0
- package/dist/types/skeleton.d.ts +77 -0
- package/dist/types/skeleton.js +19 -0
- package/dist/utils/accessibility.d.ts +48 -0
- package/dist/utils/accessibility.js +87 -0
- package/dist/utils/formatText.d.ts +4 -0
- package/dist/utils/formatText.js +44 -0
- package/dist/utils/mobile.d.ts +9 -0
- package/dist/utils/mobile.js +47 -0
- package/dist/utils/snackbar.svelte.d.ts +51 -0
- package/dist/utils/snackbar.svelte.js +107 -0
- package/dist/utils/style.d.ts +17 -0
- package/dist/utils/style.js +22 -0
- package/package.json +102 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🚨 CRITICAL: DO NOT MANAGE DRAWER STATE FROM PARENT COMPONENTS
|
|
3
|
+
*
|
|
4
|
+
* This Drawer component manages its own open/closed state internally.
|
|
5
|
+
* Parent components must NEVER create their own Drawer state variables.
|
|
6
|
+
*
|
|
7
|
+
* ❌ WRONG: let isDrawerOpen = $state(false)
|
|
8
|
+
* ✅ RIGHT: Use drawerRef.open(), drawerRef.close(), drawerRef.toggle()
|
|
9
|
+
* ✅ RIGHT: Use onOpen/onClose callbacks for side effects
|
|
10
|
+
*
|
|
11
|
+
* This prevents state synchronization bugs and ensures consistent behavior.
|
|
12
|
+
*/
|
|
13
|
+
import type { Snippet } from 'svelte';
|
|
14
|
+
type $$ComponentProps = {
|
|
15
|
+
header?: Snippet;
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
footer?: Snippet;
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
id?: string;
|
|
21
|
+
width?: string | number;
|
|
22
|
+
position?: 'left' | 'right';
|
|
23
|
+
bodyStyle?: string;
|
|
24
|
+
noPadding?: boolean;
|
|
25
|
+
isOpen?: boolean;
|
|
26
|
+
scrollable?: boolean;
|
|
27
|
+
closeIfClickOutside?: boolean;
|
|
28
|
+
restoreFocus?: boolean;
|
|
29
|
+
ariaLabel?: string;
|
|
30
|
+
ariaDescribedby?: string;
|
|
31
|
+
};
|
|
32
|
+
declare const Drawer: import("svelte").Component<$$ComponentProps, {
|
|
33
|
+
open: () => void;
|
|
34
|
+
close: () => void;
|
|
35
|
+
toggle: () => void;
|
|
36
|
+
closeEnd: () => void;
|
|
37
|
+
}, "isOpen">;
|
|
38
|
+
type Drawer = ReturnType<typeof Drawer>;
|
|
39
|
+
export default Drawer;
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
<!-- Fab.svelte -->
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
6
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
7
|
+
import Icon from './Icon.svelte';
|
|
8
|
+
import LoadingSpinner from './LoadingSpinner.svelte';
|
|
9
|
+
|
|
10
|
+
// =========================================================================
|
|
11
|
+
// Props, States & Constants
|
|
12
|
+
// =========================================================================
|
|
13
|
+
let {
|
|
14
|
+
// Snippet
|
|
15
|
+
children,
|
|
16
|
+
|
|
17
|
+
// HTML属性系
|
|
18
|
+
type = 'button',
|
|
19
|
+
buttonAttributes,
|
|
20
|
+
|
|
21
|
+
// スタイル/レイアウト
|
|
22
|
+
customStyle,
|
|
23
|
+
color,
|
|
24
|
+
variant = 'filled',
|
|
25
|
+
position = 'right',
|
|
26
|
+
hasShadow = false,
|
|
27
|
+
|
|
28
|
+
// アイコン関連
|
|
29
|
+
icon = '',
|
|
30
|
+
iconFilled = false,
|
|
31
|
+
iconWeight = 300,
|
|
32
|
+
iconGrade = 0,
|
|
33
|
+
iconOpticalSize = null,
|
|
34
|
+
iconVariant = 'outlined',
|
|
35
|
+
|
|
36
|
+
// 状態/動作
|
|
37
|
+
disabled = false,
|
|
38
|
+
loading = false,
|
|
39
|
+
|
|
40
|
+
// ARIA/アクセシビリティ
|
|
41
|
+
ariaLabel,
|
|
42
|
+
ariaDescribedby,
|
|
43
|
+
reducedMotion = false,
|
|
44
|
+
|
|
45
|
+
// フォーカスイベント
|
|
46
|
+
onfocus = () => {}, // No params for type inference
|
|
47
|
+
onblur = () => {}, // No params for type inference
|
|
48
|
+
|
|
49
|
+
// キーボードイベント
|
|
50
|
+
onkeydown = () => {}, // No params for type inference
|
|
51
|
+
onkeyup = () => {}, // No params for type inference
|
|
52
|
+
|
|
53
|
+
// マウスイベント
|
|
54
|
+
onclick,
|
|
55
|
+
onmousedown = () => {}, // No params for type inference
|
|
56
|
+
onmouseup = () => {}, // No params for type inference
|
|
57
|
+
onmouseenter = () => {}, // No params for type inference
|
|
58
|
+
onmouseleave = () => {}, // No params for type inference
|
|
59
|
+
onmouseover = () => {}, // No params for type inference
|
|
60
|
+
onmouseout = () => {}, // No params for type inference
|
|
61
|
+
oncontextmenu = () => {}, // No params for type inference
|
|
62
|
+
onauxclick = () => {}, // No params for type inference
|
|
63
|
+
|
|
64
|
+
// タッチイベント
|
|
65
|
+
ontouchstart = () => {}, // No params for type inference
|
|
66
|
+
ontouchend = () => {}, // No params for type inference
|
|
67
|
+
ontouchmove = () => {}, // No params for type inference
|
|
68
|
+
ontouchcancel = () => {}, // No params for type inference
|
|
69
|
+
|
|
70
|
+
// ポインターイベント
|
|
71
|
+
onpointerdown = () => {}, // No params for type inference
|
|
72
|
+
onpointerup = () => {}, // No params for type inference
|
|
73
|
+
onpointerenter = () => {}, // No params for type inference
|
|
74
|
+
onpointerleave = () => {}, // No params for type inference
|
|
75
|
+
onpointermove = () => {}, // No params for type inference
|
|
76
|
+
onpointercancel = () => {}, // No params for type inference
|
|
77
|
+
|
|
78
|
+
// その他
|
|
79
|
+
...restProps
|
|
80
|
+
}: {
|
|
81
|
+
children?: Snippet;
|
|
82
|
+
buttonAttributes?: HTMLButtonAttributes | undefined;
|
|
83
|
+
type?: HTMLButtonAttributes['type'];
|
|
84
|
+
customStyle?: HTMLButtonAttributes['style'];
|
|
85
|
+
disabled?: boolean;
|
|
86
|
+
loading?: boolean;
|
|
87
|
+
icon?: string;
|
|
88
|
+
iconFilled?: boolean;
|
|
89
|
+
iconWeight?: IconWeight;
|
|
90
|
+
iconGrade?: IconGrade;
|
|
91
|
+
iconOpticalSize?: IconOpticalSize;
|
|
92
|
+
iconVariant?: IconVariant;
|
|
93
|
+
color?: string;
|
|
94
|
+
variant?: 'ghost' | 'filled' | 'outlined' | 'glass';
|
|
95
|
+
position?: 'left' | 'center' | 'right';
|
|
96
|
+
hasShadow?: boolean;
|
|
97
|
+
reducedMotion?: boolean;
|
|
98
|
+
ariaLabel?: string;
|
|
99
|
+
ariaDescribedby?: string;
|
|
100
|
+
// フォーカスイベント
|
|
101
|
+
onfocus?: Function; // No params for type inference
|
|
102
|
+
onblur?: Function; // No params for type inference
|
|
103
|
+
|
|
104
|
+
// キーボードイベント
|
|
105
|
+
onkeydown?: Function; // No params for type inference
|
|
106
|
+
onkeyup?: Function; // No params for type inference
|
|
107
|
+
|
|
108
|
+
// マウスイベント
|
|
109
|
+
onclick?: Function; // No params for type inference
|
|
110
|
+
onmousedown?: Function; // No params for type inference
|
|
111
|
+
onmouseup?: Function; // No params for type inference
|
|
112
|
+
onmouseenter?: Function; // No params for type inference
|
|
113
|
+
onmouseleave?: Function; // No params for type inference
|
|
114
|
+
onmouseover?: Function; // No params for type inference
|
|
115
|
+
onmouseout?: Function; // No params for type inference
|
|
116
|
+
oncontextmenu?: Function; // No params for type inference
|
|
117
|
+
onauxclick?: Function; // No params for type inference
|
|
118
|
+
|
|
119
|
+
// タッチイベント
|
|
120
|
+
ontouchstart?: Function; // No params for type inference
|
|
121
|
+
ontouchend?: Function; // No params for type inference
|
|
122
|
+
ontouchmove?: Function; // No params for type inference
|
|
123
|
+
ontouchcancel?: Function; // No params for type inference
|
|
124
|
+
|
|
125
|
+
// ポインターイベント
|
|
126
|
+
onpointerdown?: Function; // No params for type inference
|
|
127
|
+
onpointerup?: Function; // No params for type inference
|
|
128
|
+
onpointerenter?: Function; // No params for type inference
|
|
129
|
+
onpointerleave?: Function; // No params for type inference
|
|
130
|
+
onpointermove?: Function; // No params for type inference
|
|
131
|
+
onpointercancel?: Function; // No params for type inference
|
|
132
|
+
[key: string]: any;
|
|
133
|
+
} = $props();
|
|
134
|
+
|
|
135
|
+
// =========================================================================
|
|
136
|
+
// Methods
|
|
137
|
+
// =========================================================================
|
|
138
|
+
const handleClick = (event: MouseEvent) => {
|
|
139
|
+
if (disabled || loading) return;
|
|
140
|
+
if (onclick) onclick(event);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const handleFocus = (event: FocusEvent) => {
|
|
144
|
+
onfocus(event);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const handleBlur = (event: FocusEvent) => {
|
|
148
|
+
onblur(event);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const handleKeydown = (event: KeyboardEvent) => {
|
|
152
|
+
onkeydown(event);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const handleKeyup = (event: KeyboardEvent) => {
|
|
156
|
+
onkeyup(event);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// マウスイベント
|
|
160
|
+
const handleMouseDown = (event: MouseEvent) => {
|
|
161
|
+
if (disabled || loading) return;
|
|
162
|
+
onmousedown(event);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const handleMouseUp = (event: MouseEvent) => {
|
|
166
|
+
if (disabled || loading) return;
|
|
167
|
+
onmouseup(event);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleMouseEnter = (event: MouseEvent) => {
|
|
171
|
+
if (disabled || loading) return;
|
|
172
|
+
onmouseenter(event);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const handleMouseLeave = (event: MouseEvent) => {
|
|
176
|
+
if (disabled || loading) return;
|
|
177
|
+
onmouseleave(event);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const handleMouseOver = (event: MouseEvent) => {
|
|
181
|
+
if (disabled || loading) return;
|
|
182
|
+
onmouseover(event);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const handleMouseOut = (event: MouseEvent) => {
|
|
186
|
+
if (disabled || loading) return;
|
|
187
|
+
onmouseout(event);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const handleContextMenu = (event: MouseEvent) => {
|
|
191
|
+
if (disabled || loading) return;
|
|
192
|
+
oncontextmenu(event);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const handleAuxClick = (event: MouseEvent) => {
|
|
196
|
+
if (disabled || loading) return;
|
|
197
|
+
onauxclick(event);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// タッチイベント
|
|
201
|
+
const handleTouchStart = (event: TouchEvent) => {
|
|
202
|
+
if (disabled || loading) return;
|
|
203
|
+
ontouchstart(event);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const handleTouchEnd = (event: TouchEvent) => {
|
|
207
|
+
if (disabled || loading) return;
|
|
208
|
+
ontouchend(event);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const handleTouchMove = (event: TouchEvent) => {
|
|
212
|
+
if (disabled || loading) return;
|
|
213
|
+
ontouchmove(event);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const handleTouchCancel = (event: TouchEvent) => {
|
|
217
|
+
if (disabled || loading) return;
|
|
218
|
+
ontouchcancel(event);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// ポインターイベント
|
|
222
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
223
|
+
if (disabled || loading) return;
|
|
224
|
+
onpointerdown(event);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const handlePointerUp = (event: PointerEvent) => {
|
|
228
|
+
if (disabled || loading) return;
|
|
229
|
+
onpointerup(event);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const handlePointerEnter = (event: PointerEvent) => {
|
|
233
|
+
if (disabled || loading) return;
|
|
234
|
+
onpointerenter(event);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const handlePointerLeave = (event: PointerEvent) => {
|
|
238
|
+
if (disabled || loading) return;
|
|
239
|
+
onpointerleave(event);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const handlePointerMove = (event: PointerEvent) => {
|
|
243
|
+
if (disabled || loading) return;
|
|
244
|
+
onpointermove(event);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const handlePointerCancel = (event: PointerEvent) => {
|
|
248
|
+
if (disabled || loading) return;
|
|
249
|
+
onpointercancel(event);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// =========================================================================
|
|
253
|
+
// $derived
|
|
254
|
+
// =========================================================================
|
|
255
|
+
|
|
256
|
+
const backgroundColors = $derived({
|
|
257
|
+
ghost: 'transparent',
|
|
258
|
+
filled: color ?? 'var(--svelte-ui-fab-bg-filled)',
|
|
259
|
+
outlined: 'transparent',
|
|
260
|
+
glass: 'var(--svelte-ui-fab-bg-glass)'
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const textColors = $derived({
|
|
264
|
+
ghost: color ?? 'var(--svelte-ui-fab-text-ghost)',
|
|
265
|
+
filled: 'var(--svelte-ui-fab-text-filled)',
|
|
266
|
+
outlined: color ?? 'var(--svelte-ui-fab-text-outlined)',
|
|
267
|
+
glass: color ?? 'var(--svelte-ui-fab-text-glass)'
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const hasLabel = $derived(children !== undefined);
|
|
271
|
+
</script>
|
|
272
|
+
|
|
273
|
+
<button
|
|
274
|
+
{type}
|
|
275
|
+
disabled={disabled || loading}
|
|
276
|
+
{...buttonAttributes}
|
|
277
|
+
{...restProps}
|
|
278
|
+
class="fab"
|
|
279
|
+
class:fab--outlined={variant === 'outlined'}
|
|
280
|
+
class:fab--filled={variant === 'filled'}
|
|
281
|
+
class:fab--glass={variant === 'glass'}
|
|
282
|
+
class:fab--without-label={!hasLabel}
|
|
283
|
+
class:fab--left={position === 'left'}
|
|
284
|
+
class:fab--center={position === 'center'}
|
|
285
|
+
class:fab--right={position === 'right'}
|
|
286
|
+
class:fab--shadow={hasShadow}
|
|
287
|
+
class:fab--loading={loading}
|
|
288
|
+
class:fab--no-motion={reducedMotion}
|
|
289
|
+
style="color: {textColors[variant]}; background-color: {backgroundColors[variant]};
|
|
290
|
+
{customStyle ?? ''};"
|
|
291
|
+
onclick={handleClick}
|
|
292
|
+
onfocus={handleFocus}
|
|
293
|
+
onblur={handleBlur}
|
|
294
|
+
onkeydown={handleKeydown}
|
|
295
|
+
onkeyup={handleKeyup}
|
|
296
|
+
onmousedown={handleMouseDown}
|
|
297
|
+
onmouseup={handleMouseUp}
|
|
298
|
+
onmouseenter={handleMouseEnter}
|
|
299
|
+
onmouseleave={handleMouseLeave}
|
|
300
|
+
onmouseover={handleMouseOver}
|
|
301
|
+
onmouseout={handleMouseOut}
|
|
302
|
+
oncontextmenu={handleContextMenu}
|
|
303
|
+
onauxclick={handleAuxClick}
|
|
304
|
+
ontouchstart={handleTouchStart}
|
|
305
|
+
ontouchend={handleTouchEnd}
|
|
306
|
+
ontouchmove={handleTouchMove}
|
|
307
|
+
ontouchcancel={handleTouchCancel}
|
|
308
|
+
onpointerdown={handlePointerDown}
|
|
309
|
+
onpointerup={handlePointerUp}
|
|
310
|
+
onpointerenter={handlePointerEnter}
|
|
311
|
+
onpointerleave={handlePointerLeave}
|
|
312
|
+
onpointermove={handlePointerMove}
|
|
313
|
+
onpointercancel={handlePointerCancel}
|
|
314
|
+
aria-label={ariaLabel || (hasLabel ? undefined : 'Floating Action Button')}
|
|
315
|
+
aria-describedby={ariaDescribedby}
|
|
316
|
+
aria-busy={loading ? 'true' : undefined}
|
|
317
|
+
data-testid="fab"
|
|
318
|
+
>
|
|
319
|
+
{#if loading}
|
|
320
|
+
<div class="fab__loading">
|
|
321
|
+
<LoadingSpinner size={24} strokeWidth={2} color="currentColor" />
|
|
322
|
+
</div>
|
|
323
|
+
{:else if icon}
|
|
324
|
+
<div class="fab__icon">
|
|
325
|
+
<Icon
|
|
326
|
+
filled={iconFilled}
|
|
327
|
+
weight={iconWeight}
|
|
328
|
+
grade={iconGrade}
|
|
329
|
+
opticalSize={iconOpticalSize}
|
|
330
|
+
variant={iconVariant}
|
|
331
|
+
size={24}>{icon}</Icon
|
|
332
|
+
>
|
|
333
|
+
</div>
|
|
334
|
+
{/if}
|
|
335
|
+
|
|
336
|
+
{#if children}
|
|
337
|
+
<div class="fab__label" class:fab__label--hidden={loading}>
|
|
338
|
+
{@render children()}
|
|
339
|
+
</div>
|
|
340
|
+
{/if}
|
|
341
|
+
</button>
|
|
342
|
+
|
|
343
|
+
<style>.fab {
|
|
344
|
+
display: flex;
|
|
345
|
+
justify-content: center;
|
|
346
|
+
align-items: center;
|
|
347
|
+
position: fixed;
|
|
348
|
+
bottom: calc(24px + env(safe-area-inset-bottom));
|
|
349
|
+
height: 56px;
|
|
350
|
+
padding: 0 20px;
|
|
351
|
+
background-color: transparent;
|
|
352
|
+
border: none;
|
|
353
|
+
border-radius: var(--svelte-ui-button-border-radius-rounded);
|
|
354
|
+
font-size: inherit;
|
|
355
|
+
font-family: inherit;
|
|
356
|
+
line-height: normal;
|
|
357
|
+
text-align: center;
|
|
358
|
+
overflow: hidden;
|
|
359
|
+
z-index: 1000;
|
|
360
|
+
cursor: pointer;
|
|
361
|
+
transition-property: background-color, box-shadow, color, opacity, transform;
|
|
362
|
+
transition-duration: var(--svelte-ui-transition-duration);
|
|
363
|
+
}
|
|
364
|
+
.fab.fab--left {
|
|
365
|
+
left: 24px;
|
|
366
|
+
}
|
|
367
|
+
.fab.fab--center {
|
|
368
|
+
left: 50%;
|
|
369
|
+
transform: translateX(-50%);
|
|
370
|
+
}
|
|
371
|
+
.fab.fab--right {
|
|
372
|
+
right: 24px;
|
|
373
|
+
}
|
|
374
|
+
.fab > * {
|
|
375
|
+
z-index: 1;
|
|
376
|
+
}
|
|
377
|
+
.fab:before {
|
|
378
|
+
content: "";
|
|
379
|
+
display: block;
|
|
380
|
+
position: absolute;
|
|
381
|
+
top: 0;
|
|
382
|
+
left: 0;
|
|
383
|
+
width: 100%;
|
|
384
|
+
height: 100%;
|
|
385
|
+
background-color: var(--svelte-ui-fab-hover-overlay);
|
|
386
|
+
opacity: 0;
|
|
387
|
+
transition-property: opacity;
|
|
388
|
+
transition-duration: var(--svelte-ui-transition-duration);
|
|
389
|
+
z-index: 0;
|
|
390
|
+
}
|
|
391
|
+
@media (hover: hover) {
|
|
392
|
+
.fab:hover:before {
|
|
393
|
+
opacity: 1;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
.fab:focus-visible {
|
|
397
|
+
outline: 2px solid var(--svelte-ui-fab-focus-color);
|
|
398
|
+
outline-offset: 2px;
|
|
399
|
+
}
|
|
400
|
+
.fab:disabled {
|
|
401
|
+
opacity: var(--svelte-ui-button-disabled-opacity);
|
|
402
|
+
cursor: not-allowed;
|
|
403
|
+
pointer-events: none;
|
|
404
|
+
}
|
|
405
|
+
.fab.fab--outlined {
|
|
406
|
+
box-shadow: inset 0 0 0 var(--svelte-ui-border-width) currentColor;
|
|
407
|
+
}
|
|
408
|
+
.fab.fab--glass {
|
|
409
|
+
backdrop-filter: var(--svelte-ui-glass-blur);
|
|
410
|
+
-webkit-backdrop-filter: var(--svelte-ui-glass-blur);
|
|
411
|
+
}
|
|
412
|
+
.fab.fab--shadow {
|
|
413
|
+
box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
|
|
414
|
+
}
|
|
415
|
+
.fab.fab--outlined.fab--shadow {
|
|
416
|
+
box-shadow: inset 0 0 0 var(--svelte-ui-border-width) currentColor, 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
|
|
417
|
+
}
|
|
418
|
+
@media (hover: hover) {
|
|
419
|
+
.fab.fab--shadow:hover {
|
|
420
|
+
box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
421
|
+
}
|
|
422
|
+
.fab.fab--outlined.fab--shadow:hover {
|
|
423
|
+
box-shadow: inset 0 0 0 var(--svelte-ui-border-width) currentColor, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
.fab.fab--shadow:active {
|
|
427
|
+
box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 12px 17px 2px rgba(0, 0, 0, 0.14), 0px 5px 22px 4px rgba(0, 0, 0, 0.12);
|
|
428
|
+
}
|
|
429
|
+
.fab.fab--outlined.fab--shadow:active {
|
|
430
|
+
box-shadow: inset 0 0 0 var(--svelte-ui-border-width) currentColor, 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 12px 17px 2px rgba(0, 0, 0, 0.14), 0px 5px 22px 4px rgba(0, 0, 0, 0.12);
|
|
431
|
+
}
|
|
432
|
+
.fab.fab--loading {
|
|
433
|
+
cursor: wait;
|
|
434
|
+
}
|
|
435
|
+
.fab.fab--no-motion, .fab.fab--no-motion:before {
|
|
436
|
+
transition-duration: 0.01s;
|
|
437
|
+
}
|
|
438
|
+
.fab .fab__icon {
|
|
439
|
+
margin: 0 8px 0 -8px;
|
|
440
|
+
user-select: none;
|
|
441
|
+
display: flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
justify-content: center;
|
|
444
|
+
}
|
|
445
|
+
.fab .fab__loading {
|
|
446
|
+
position: absolute;
|
|
447
|
+
top: 50%;
|
|
448
|
+
left: 50%;
|
|
449
|
+
transform: translate(-50%, -50%);
|
|
450
|
+
display: flex;
|
|
451
|
+
align-items: center;
|
|
452
|
+
justify-content: center;
|
|
453
|
+
}
|
|
454
|
+
.fab .fab__label {
|
|
455
|
+
white-space: nowrap;
|
|
456
|
+
user-select: none;
|
|
457
|
+
transition-property: opacity;
|
|
458
|
+
transition-duration: var(--svelte-ui-transition-duration);
|
|
459
|
+
}
|
|
460
|
+
.fab .fab__label--hidden {
|
|
461
|
+
opacity: 0;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.fab.fab--without-label {
|
|
465
|
+
width: 56px;
|
|
466
|
+
height: 56px;
|
|
467
|
+
padding: 0;
|
|
468
|
+
border-radius: 28px;
|
|
469
|
+
}
|
|
470
|
+
.fab.fab--without-label .fab__icon {
|
|
471
|
+
margin: 0;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* Reduced motion */
|
|
475
|
+
@media (prefers-reduced-motion: reduce) {
|
|
476
|
+
.fab,
|
|
477
|
+
.fab:before {
|
|
478
|
+
transition-duration: 0.01s;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/* Print styles */
|
|
482
|
+
@media print {
|
|
483
|
+
.fab {
|
|
484
|
+
display: none;
|
|
485
|
+
}
|
|
486
|
+
}</style>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
import type { IconVariant, IconWeight, IconGrade, IconOpticalSize } from '../types/icon';
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
buttonAttributes?: HTMLButtonAttributes | undefined;
|
|
7
|
+
type?: HTMLButtonAttributes['type'];
|
|
8
|
+
customStyle?: HTMLButtonAttributes['style'];
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
loading?: boolean;
|
|
11
|
+
icon?: string;
|
|
12
|
+
iconFilled?: boolean;
|
|
13
|
+
iconWeight?: IconWeight;
|
|
14
|
+
iconGrade?: IconGrade;
|
|
15
|
+
iconOpticalSize?: IconOpticalSize;
|
|
16
|
+
iconVariant?: IconVariant;
|
|
17
|
+
color?: string;
|
|
18
|
+
variant?: 'ghost' | 'filled' | 'outlined' | 'glass';
|
|
19
|
+
position?: 'left' | 'center' | 'right';
|
|
20
|
+
hasShadow?: boolean;
|
|
21
|
+
reducedMotion?: boolean;
|
|
22
|
+
ariaLabel?: string;
|
|
23
|
+
ariaDescribedby?: string;
|
|
24
|
+
onfocus?: Function;
|
|
25
|
+
onblur?: Function;
|
|
26
|
+
onkeydown?: Function;
|
|
27
|
+
onkeyup?: Function;
|
|
28
|
+
onclick?: Function;
|
|
29
|
+
onmousedown?: Function;
|
|
30
|
+
onmouseup?: Function;
|
|
31
|
+
onmouseenter?: Function;
|
|
32
|
+
onmouseleave?: Function;
|
|
33
|
+
onmouseover?: Function;
|
|
34
|
+
onmouseout?: Function;
|
|
35
|
+
oncontextmenu?: Function;
|
|
36
|
+
onauxclick?: Function;
|
|
37
|
+
ontouchstart?: Function;
|
|
38
|
+
ontouchend?: Function;
|
|
39
|
+
ontouchmove?: Function;
|
|
40
|
+
ontouchcancel?: Function;
|
|
41
|
+
onpointerdown?: Function;
|
|
42
|
+
onpointerup?: Function;
|
|
43
|
+
onpointerenter?: Function;
|
|
44
|
+
onpointerleave?: Function;
|
|
45
|
+
onpointermove?: Function;
|
|
46
|
+
onpointercancel?: Function;
|
|
47
|
+
[key: string]: any;
|
|
48
|
+
};
|
|
49
|
+
declare const Fab: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
50
|
+
type Fab = ReturnType<typeof Fab>;
|
|
51
|
+
export default Fab;
|