sv5ui 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Calendar/Calendar.svelte +48 -6
- package/dist/Calendar/calendar.types.d.ts +19 -0
- package/dist/Calendar/calendar.variants.js +2 -1
- package/dist/Carousel/Carousel.svelte +279 -0
- package/dist/Carousel/Carousel.svelte.d.ts +26 -0
- package/dist/Carousel/carousel.types.d.ts +242 -0
- package/dist/Carousel/carousel.types.js +1 -0
- package/dist/Carousel/carousel.variants.d.ts +408 -0
- package/dist/Carousel/carousel.variants.js +88 -0
- package/dist/Carousel/index.d.ts +2 -0
- package/dist/Carousel/index.js +1 -0
- package/dist/FileUpload/FileUpload.svelte +81 -10
- package/dist/FileUpload/file-upload.types.d.ts +39 -0
- package/dist/FileUpload/index.d.ts +1 -1
- package/dist/Modal/Modal.svelte +14 -3
- package/dist/Modal/modal.types.d.ts +15 -4
- package/dist/Modal/modal.variants.d.ts +110 -20
- package/dist/Modal/modal.variants.js +27 -9
- package/dist/PinInput/PinInput.svelte +18 -4
- package/dist/PinInput/pin-input.types.d.ts +11 -0
- package/dist/Select/Select.svelte +98 -28
- package/dist/Select/select.types.d.ts +44 -2
- package/dist/SelectMenu/SelectMenu.svelte +210 -25
- package/dist/SelectMenu/select-menu.types.d.ts +62 -1
- package/dist/SelectMenu/select-menu.variants.d.ts +26 -0
- package/dist/SelectMenu/select-menu.variants.js +34 -6
- package/dist/Slideover/Slideover.svelte +13 -2
- package/dist/Slideover/slideover.types.d.ts +14 -3
- package/dist/Slideover/slideover.variants.d.ts +85 -5
- package/dist/Slideover/slideover.variants.js +42 -12
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const carouselVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
root: 'relative',
|
|
5
|
+
viewport: 'overflow-hidden',
|
|
6
|
+
container: 'flex',
|
|
7
|
+
slide: 'shrink-0 grow-0 basis-[calc(100%/var(--sv-slides))]',
|
|
8
|
+
arrow: 'absolute z-10 shadow-md',
|
|
9
|
+
arrowPrev: '',
|
|
10
|
+
arrowNext: '',
|
|
11
|
+
dots: 'flex items-center justify-center gap-2',
|
|
12
|
+
dot: [
|
|
13
|
+
'rounded-full bg-on-surface/30 transition-all',
|
|
14
|
+
'hover:bg-on-surface/50',
|
|
15
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
|
|
16
|
+
'data-[selected]:bg-primary'
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
variants: {
|
|
20
|
+
orientation: {
|
|
21
|
+
horizontal: {
|
|
22
|
+
viewport: 'w-full',
|
|
23
|
+
container: 'flex-row touch-pan-y',
|
|
24
|
+
slide: 'min-w-0 h-auto',
|
|
25
|
+
dots: 'flex-row mt-4',
|
|
26
|
+
arrowPrev: 'left-2 top-1/2 -translate-y-1/2',
|
|
27
|
+
arrowNext: 'right-2 top-1/2 -translate-y-1/2'
|
|
28
|
+
},
|
|
29
|
+
vertical: {
|
|
30
|
+
root: 'h-full',
|
|
31
|
+
viewport: 'h-full w-full',
|
|
32
|
+
container: 'flex-col h-full touch-pan-x',
|
|
33
|
+
slide: 'min-h-0 w-auto',
|
|
34
|
+
dots: 'flex-col absolute right-2 top-1/2 -translate-y-1/2',
|
|
35
|
+
arrowPrev: 'top-2 left-1/2 -translate-x-1/2',
|
|
36
|
+
arrowNext: 'bottom-2 left-1/2 -translate-x-1/2'
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
size: {
|
|
40
|
+
xs: { dot: 'size-1.5' },
|
|
41
|
+
sm: { dot: 'size-2' },
|
|
42
|
+
md: { dot: 'size-2.5' },
|
|
43
|
+
lg: { dot: 'size-3' },
|
|
44
|
+
xl: { dot: 'size-3.5' }
|
|
45
|
+
},
|
|
46
|
+
color: {
|
|
47
|
+
primary: { dot: 'data-[selected]:bg-primary focus-visible:outline-primary' },
|
|
48
|
+
secondary: { dot: 'data-[selected]:bg-secondary focus-visible:outline-secondary' },
|
|
49
|
+
tertiary: { dot: 'data-[selected]:bg-tertiary focus-visible:outline-tertiary' },
|
|
50
|
+
success: { dot: 'data-[selected]:bg-success focus-visible:outline-success' },
|
|
51
|
+
warning: { dot: 'data-[selected]:bg-warning focus-visible:outline-warning' },
|
|
52
|
+
error: { dot: 'data-[selected]:bg-error focus-visible:outline-error' },
|
|
53
|
+
info: { dot: 'data-[selected]:bg-info focus-visible:outline-info' },
|
|
54
|
+
surface: {
|
|
55
|
+
dot: 'data-[selected]:bg-on-surface focus-visible:outline-on-surface'
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
variant: {
|
|
59
|
+
solid: '',
|
|
60
|
+
outline: '',
|
|
61
|
+
soft: '',
|
|
62
|
+
subtle: '',
|
|
63
|
+
ghost: ''
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
compoundVariants: [
|
|
67
|
+
{ orientation: 'horizontal', size: 'xs', class: { dot: 'data-[selected]:w-4' } },
|
|
68
|
+
{ orientation: 'horizontal', size: 'sm', class: { dot: 'data-[selected]:w-5' } },
|
|
69
|
+
{ orientation: 'horizontal', size: 'md', class: { dot: 'data-[selected]:w-6' } },
|
|
70
|
+
{ orientation: 'horizontal', size: 'lg', class: { dot: 'data-[selected]:w-7' } },
|
|
71
|
+
{ orientation: 'horizontal', size: 'xl', class: { dot: 'data-[selected]:w-8' } },
|
|
72
|
+
{ orientation: 'vertical', size: 'xs', class: { dot: 'data-[selected]:h-4' } },
|
|
73
|
+
{ orientation: 'vertical', size: 'sm', class: { dot: 'data-[selected]:h-5' } },
|
|
74
|
+
{ orientation: 'vertical', size: 'md', class: { dot: 'data-[selected]:h-6' } },
|
|
75
|
+
{ orientation: 'vertical', size: 'lg', class: { dot: 'data-[selected]:h-7' } },
|
|
76
|
+
{ orientation: 'vertical', size: 'xl', class: { dot: 'data-[selected]:h-8' } }
|
|
77
|
+
],
|
|
78
|
+
defaultVariants: {
|
|
79
|
+
orientation: 'horizontal',
|
|
80
|
+
size: 'md',
|
|
81
|
+
color: 'primary',
|
|
82
|
+
variant: 'soft'
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
export const carouselDefaults = {
|
|
86
|
+
defaultVariants: carouselVariants.defaultVariants,
|
|
87
|
+
slots: {}
|
|
88
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Carousel } from './Carousel.svelte';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import type { FileUploadProps } from './file-upload.types.js'
|
|
2
|
+
import type { FileUploadProps, FileUploadRejection } from './file-upload.types.js'
|
|
3
3
|
|
|
4
4
|
export type Props = FileUploadProps
|
|
5
5
|
</script>
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import Icon from '../Icon/Icon.svelte'
|
|
13
13
|
import Button from '../Button/Button.svelte'
|
|
14
14
|
import Modal from '../Modal/Modal.svelte'
|
|
15
|
+
import { useFormField, useFormFieldEmit } from '../hooks/useFormField.svelte.js'
|
|
15
16
|
|
|
16
17
|
const config = getComponentConfig('fileUpload', fileUploadDefaults)
|
|
17
18
|
const icons = getComponentConfig('icons', iconsDefaults)
|
|
@@ -22,6 +23,9 @@
|
|
|
22
23
|
onValueChange,
|
|
23
24
|
multiple = false,
|
|
24
25
|
accept,
|
|
26
|
+
maxSize,
|
|
27
|
+
maxFiles,
|
|
28
|
+
onReject,
|
|
25
29
|
dropzone = true,
|
|
26
30
|
interactive = true,
|
|
27
31
|
label = 'Drop files here or click to upload',
|
|
@@ -39,6 +43,7 @@
|
|
|
39
43
|
required = false,
|
|
40
44
|
fileIcon = icons.file,
|
|
41
45
|
imagePreview = true,
|
|
46
|
+
id,
|
|
42
47
|
name,
|
|
43
48
|
leadingSlot,
|
|
44
49
|
labelSlot,
|
|
@@ -59,6 +64,9 @@
|
|
|
59
64
|
let previewOpen = $state(false)
|
|
60
65
|
let previewFile = $state<File | null>(null)
|
|
61
66
|
|
|
67
|
+
const formFieldContext = useFormField()
|
|
68
|
+
const emit = useFormFieldEmit()
|
|
69
|
+
|
|
62
70
|
// Stable file identity key with separator to avoid collisions
|
|
63
71
|
const fileKey = (f: File) => `${f.name}:${f.size}:${f.lastModified}`
|
|
64
72
|
|
|
@@ -67,8 +75,23 @@
|
|
|
67
75
|
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
68
76
|
const urlCache = new Map<string, string>()
|
|
69
77
|
|
|
78
|
+
const hasError = $derived(
|
|
79
|
+
formFieldContext?.error !== undefined && formFieldContext?.error !== false
|
|
80
|
+
)
|
|
81
|
+
const resolvedHighlight = $derived(highlight || hasError)
|
|
82
|
+
const resolvedId = $derived(id ?? formFieldContext?.ariaId)
|
|
83
|
+
const resolvedName = $derived(name ?? formFieldContext?.name)
|
|
84
|
+
const ariaDescribedBy = $derived(
|
|
85
|
+
!formFieldContext
|
|
86
|
+
? undefined
|
|
87
|
+
: hasError
|
|
88
|
+
? `${formFieldContext.ariaId}-error`
|
|
89
|
+
: `${formFieldContext.ariaId}-description ${formFieldContext.ariaId}-help`
|
|
90
|
+
)
|
|
91
|
+
|
|
70
92
|
const isDisabled = $derived(disabled || loading)
|
|
71
93
|
const isDragging = $derived(dragCounter > 0)
|
|
94
|
+
const isFull = $derived(maxFiles !== undefined && value.length >= maxFiles)
|
|
72
95
|
const showFilesInside = $derived(
|
|
73
96
|
layout === 'grid' && !multiple && value.length > 0 && preview && variant === 'area'
|
|
74
97
|
)
|
|
@@ -76,13 +99,13 @@
|
|
|
76
99
|
// Pass booleans directly so compound variants with `false` values match correctly
|
|
77
100
|
const slots = $derived(
|
|
78
101
|
fileUploadVariants({
|
|
79
|
-
color,
|
|
102
|
+
color: hasError ? 'error' : color,
|
|
80
103
|
size,
|
|
81
104
|
variant,
|
|
82
105
|
layout,
|
|
83
106
|
dropzone,
|
|
84
107
|
interactive: interactive && !isDisabled,
|
|
85
|
-
highlight,
|
|
108
|
+
highlight: resolvedHighlight,
|
|
86
109
|
multiple,
|
|
87
110
|
disabled: isDisabled
|
|
88
111
|
})
|
|
@@ -150,17 +173,53 @@
|
|
|
150
173
|
})
|
|
151
174
|
}
|
|
152
175
|
|
|
176
|
+
function validateIngress(file: File): FileUploadRejection['reason'] | null {
|
|
177
|
+
if (accept && !isFileAccepted(file)) return 'accept'
|
|
178
|
+
if (maxSize !== undefined && file.size > maxSize) return 'maxSize'
|
|
179
|
+
return null
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function applyMaxFiles(candidates: File[]): {
|
|
183
|
+
accepted: File[]
|
|
184
|
+
rejected: FileUploadRejection[]
|
|
185
|
+
} {
|
|
186
|
+
if (maxFiles === undefined) return { accepted: candidates, rejected: [] }
|
|
187
|
+
const remaining = Math.max(0, maxFiles - value.length)
|
|
188
|
+
if (candidates.length <= remaining) return { accepted: candidates, rejected: [] }
|
|
189
|
+
return {
|
|
190
|
+
accepted: candidates.slice(0, remaining),
|
|
191
|
+
rejected: candidates.slice(remaining).map((file) => ({ file, reason: 'maxFiles' }))
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
153
195
|
function addFiles(newFiles: File[]) {
|
|
154
196
|
if (isDisabled) return
|
|
155
|
-
|
|
156
|
-
|
|
197
|
+
|
|
198
|
+
const rejected: FileUploadRejection[] = []
|
|
199
|
+
const passed: File[] = []
|
|
200
|
+
for (const file of newFiles) {
|
|
201
|
+
const reason = validateIngress(file)
|
|
202
|
+
if (reason) rejected.push({ file, reason })
|
|
203
|
+
else passed.push(file)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let accepted: File[]
|
|
157
207
|
if (!multiple) {
|
|
158
|
-
|
|
208
|
+
accepted = passed.slice(0, 1)
|
|
159
209
|
} else {
|
|
160
210
|
const existing = new Set(value.map(fileKey))
|
|
161
|
-
|
|
211
|
+
const deduped = passed.filter((f) => !existing.has(fileKey(f)))
|
|
212
|
+
const result = applyMaxFiles(deduped)
|
|
213
|
+
accepted = result.accepted
|
|
214
|
+
rejected.push(...result.rejected)
|
|
162
215
|
}
|
|
163
|
-
|
|
216
|
+
|
|
217
|
+
if (accepted.length) {
|
|
218
|
+
value = multiple ? [...value, ...accepted] : accepted
|
|
219
|
+
onValueChange?.(value)
|
|
220
|
+
emit.onChange()
|
|
221
|
+
}
|
|
222
|
+
if (rejected.length) onReject?.(rejected)
|
|
164
223
|
}
|
|
165
224
|
|
|
166
225
|
function removeFile(index: number) {
|
|
@@ -176,6 +235,7 @@
|
|
|
176
235
|
}
|
|
177
236
|
value = value.filter((_, i) => i !== index)
|
|
178
237
|
onValueChange?.(value)
|
|
238
|
+
emit.onChange()
|
|
179
239
|
}
|
|
180
240
|
|
|
181
241
|
export function clearAll() {
|
|
@@ -185,6 +245,7 @@
|
|
|
185
245
|
urlCache.clear()
|
|
186
246
|
value = []
|
|
187
247
|
onValueChange?.(value)
|
|
248
|
+
emit.onChange()
|
|
188
249
|
}
|
|
189
250
|
|
|
190
251
|
function handleInputChange(e: Event) {
|
|
@@ -254,13 +315,13 @@
|
|
|
254
315
|
}
|
|
255
316
|
</script>
|
|
256
317
|
|
|
257
|
-
<div {...restProps} bind:this={ref} class={classes.root}>
|
|
318
|
+
<div {...restProps} bind:this={ref} class={classes.root} data-full={isFull ? '' : undefined}>
|
|
258
319
|
<!-- Hidden file input — uses auto-generated id internally -->
|
|
259
320
|
<input
|
|
260
321
|
bind:this={inputRef}
|
|
261
322
|
type="file"
|
|
262
323
|
id={autoId}
|
|
263
|
-
{
|
|
324
|
+
name={resolvedName}
|
|
264
325
|
{accept}
|
|
265
326
|
{multiple}
|
|
266
327
|
{required}
|
|
@@ -275,18 +336,23 @@
|
|
|
275
336
|
<!-- Area / Dropzone -->
|
|
276
337
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
277
338
|
<div
|
|
339
|
+
id={resolvedId}
|
|
278
340
|
class={classes.base}
|
|
279
341
|
data-dragging={isDragging ? '' : undefined}
|
|
280
342
|
role={interactive ? 'button' : undefined}
|
|
281
343
|
tabindex={interactive && !isDisabled ? 0 : undefined}
|
|
282
344
|
aria-disabled={isDisabled || undefined}
|
|
283
345
|
aria-label={interactive ? label : undefined}
|
|
346
|
+
aria-invalid={resolvedHighlight ? true : undefined}
|
|
347
|
+
aria-describedby={ariaDescribedBy}
|
|
284
348
|
onclick={handleAreaClick}
|
|
285
349
|
ondragenter={handleDragEnter}
|
|
286
350
|
ondragover={handleDragOver}
|
|
287
351
|
ondragleave={handleDragLeave}
|
|
288
352
|
ondrop={handleDrop}
|
|
289
353
|
onkeydown={handleKeydown}
|
|
354
|
+
onfocus={() => emit.onFocus()}
|
|
355
|
+
onblur={() => emit.onBlur()}
|
|
290
356
|
>
|
|
291
357
|
{#if showFilesInside}
|
|
292
358
|
<!-- Grid single: file fills the area as overlay -->
|
|
@@ -390,6 +456,7 @@
|
|
|
390
456
|
{:else}
|
|
391
457
|
<!-- Button variant -->
|
|
392
458
|
<Button
|
|
459
|
+
id={resolvedId}
|
|
393
460
|
{color}
|
|
394
461
|
{size}
|
|
395
462
|
disabled={isDisabled}
|
|
@@ -397,7 +464,11 @@
|
|
|
397
464
|
{loadingIcon}
|
|
398
465
|
leadingIcon={loading ? undefined : icon}
|
|
399
466
|
{label}
|
|
467
|
+
aria-invalid={resolvedHighlight ? true : undefined}
|
|
468
|
+
aria-describedby={ariaDescribedBy}
|
|
400
469
|
onclick={handleAreaClick}
|
|
470
|
+
onfocus={() => emit.onFocus()}
|
|
471
|
+
onblur={() => emit.onBlur()}
|
|
401
472
|
/>
|
|
402
473
|
{/if}
|
|
403
474
|
|
|
@@ -2,6 +2,21 @@ import type { Snippet } from 'svelte';
|
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import type { ClassNameValue } from 'tailwind-merge';
|
|
4
4
|
import type { FileUploadVariantProps, FileUploadSlots } from './file-upload.variants.js';
|
|
5
|
+
/**
|
|
6
|
+
* Reason a file was rejected by FileUpload.
|
|
7
|
+
*
|
|
8
|
+
* - `accept`: file did not match the `accept` MIME/extension filter
|
|
9
|
+
* - `maxSize`: file exceeded the `maxSize` byte limit
|
|
10
|
+
* - `maxFiles`: file would have pushed the selection past `maxFiles`
|
|
11
|
+
*/
|
|
12
|
+
export type FileUploadRejectionReason = 'accept' | 'maxSize' | 'maxFiles';
|
|
13
|
+
/**
|
|
14
|
+
* A single rejected file along with the reason it was rejected.
|
|
15
|
+
*/
|
|
16
|
+
export interface FileUploadRejection {
|
|
17
|
+
file: File;
|
|
18
|
+
reason: FileUploadRejectionReason;
|
|
19
|
+
}
|
|
5
20
|
export type FileUploadProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'children'> & {
|
|
6
21
|
/**
|
|
7
22
|
* Bindable reference to the root DOM element.
|
|
@@ -25,6 +40,30 @@ export type FileUploadProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'child
|
|
|
25
40
|
* Accepted file types as MIME types or extensions (e.g. "image/*,.pdf").
|
|
26
41
|
*/
|
|
27
42
|
accept?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Maximum allowed size per file, in bytes. Files exceeding this are
|
|
45
|
+
* rejected and reported through `onReject`.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```svelte
|
|
49
|
+
* <FileUpload maxSize={5 * 1024 * 1024} /> <!-- 5 MB -->
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
maxSize?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Maximum number of files that can be selected. When the current
|
|
55
|
+
* selection plus the incoming files would exceed this, the excess
|
|
56
|
+
* files are rejected and reported through `onReject`. The root element
|
|
57
|
+
* exposes a `data-full` attribute when the limit is reached, so the
|
|
58
|
+
* upload area can be styled accordingly.
|
|
59
|
+
*/
|
|
60
|
+
maxFiles?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Called when one or more incoming files are rejected by `accept`,
|
|
63
|
+
* `maxSize`, or `maxFiles`. Receives the full rejection list for a
|
|
64
|
+
* single user action (one drop or one input change).
|
|
65
|
+
*/
|
|
66
|
+
onReject?: (rejected: FileUploadRejection[]) => void;
|
|
28
67
|
/**
|
|
29
68
|
* Enable drag-and-drop file upload.
|
|
30
69
|
* @default true
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as FileUpload } from './FileUpload.svelte';
|
|
2
|
-
export type { FileUploadProps } from './file-upload.types.js';
|
|
2
|
+
export type { FileUploadProps, FileUploadRejection, FileUploadRejectionReason } from './file-upload.types.js';
|
package/dist/Modal/Modal.svelte
CHANGED
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
description,
|
|
29
29
|
overlay: showOverlay = config.defaultVariants.overlay ?? true,
|
|
30
30
|
scrollable = config.defaultVariants.scrollable ?? false,
|
|
31
|
-
transition = config.defaultVariants.transition ??
|
|
32
|
-
|
|
31
|
+
transition = config.defaultVariants.transition ?? 'scale',
|
|
32
|
+
size = config.defaultVariants.size ?? 'md',
|
|
33
|
+
fullscreen = false,
|
|
33
34
|
portal = true,
|
|
34
35
|
close: closeProp = true,
|
|
35
36
|
dismissible = true,
|
|
@@ -46,6 +47,11 @@
|
|
|
46
47
|
closeSlot
|
|
47
48
|
}: Props = $props()
|
|
48
49
|
|
|
50
|
+
const resolvedSize = $derived(fullscreen ? 'full' : size)
|
|
51
|
+
const resolvedTransition = $derived(
|
|
52
|
+
transition === false ? 'none' : transition === true ? 'scale' : transition
|
|
53
|
+
)
|
|
54
|
+
|
|
49
55
|
const showClose = $derived(!!closeProp)
|
|
50
56
|
const closeProps = $derived(typeof closeProp === 'object' ? closeProp : {})
|
|
51
57
|
|
|
@@ -57,7 +63,12 @@
|
|
|
57
63
|
)
|
|
58
64
|
|
|
59
65
|
const variantSlots = $derived(
|
|
60
|
-
modalVariants({
|
|
66
|
+
modalVariants({
|
|
67
|
+
transition: resolvedTransition,
|
|
68
|
+
size: resolvedSize,
|
|
69
|
+
overlay: showOverlay,
|
|
70
|
+
scrollable
|
|
71
|
+
})
|
|
61
72
|
)
|
|
62
73
|
|
|
63
74
|
const classes = $derived({
|
|
@@ -43,15 +43,26 @@ export interface ModalProps extends RootProps, ContentProps {
|
|
|
43
43
|
*/
|
|
44
44
|
scrollable?: ModalVariantProps['scrollable'];
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Controls the entrance/exit animation.
|
|
47
|
+
* - `'none'` / `false`: no animation
|
|
48
|
+
* - `'fade'`: overlay + content fade
|
|
49
|
+
* - `'slide'`: overlay fade + content slide-in from top
|
|
50
|
+
* - `'scale'` / `true`: overlay fade + content scale-in (default)
|
|
51
|
+
* @default 'scale'
|
|
52
|
+
*/
|
|
53
|
+
transition?: ModalVariantProps['transition'] | boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Controls the modal width. The `'full'` value expands to fill the
|
|
56
|
+
* entire viewport (replaces the deprecated `fullscreen` prop).
|
|
57
|
+
* @default 'md'
|
|
48
58
|
*/
|
|
49
|
-
|
|
59
|
+
size?: ModalVariantProps['size'];
|
|
50
60
|
/**
|
|
51
61
|
* Expand the modal to fill the entire viewport.
|
|
62
|
+
* @deprecated Use `size="full"` instead. Retained as an alias for backward compatibility.
|
|
52
63
|
* @default false
|
|
53
64
|
*/
|
|
54
|
-
fullscreen?:
|
|
65
|
+
fullscreen?: boolean;
|
|
55
66
|
/**
|
|
56
67
|
* Render the modal content in a portal appended to `<body>`.
|
|
57
68
|
* @default true
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
import { type VariantProps } from 'tailwind-variants';
|
|
2
2
|
export declare const modalVariants: import("tailwind-variants").TVReturnType<{
|
|
3
3
|
transition: {
|
|
4
|
-
|
|
4
|
+
none: {};
|
|
5
|
+
fade: {
|
|
6
|
+
overlay: string;
|
|
7
|
+
content: string;
|
|
8
|
+
};
|
|
9
|
+
slide: {
|
|
10
|
+
overlay: string;
|
|
11
|
+
content: string;
|
|
12
|
+
};
|
|
13
|
+
scale: {
|
|
5
14
|
overlay: string;
|
|
6
15
|
content: string;
|
|
7
16
|
};
|
|
8
17
|
};
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
size: {
|
|
19
|
+
sm: {
|
|
11
20
|
content: string;
|
|
12
21
|
};
|
|
13
|
-
|
|
22
|
+
md: {
|
|
23
|
+
content: string;
|
|
24
|
+
};
|
|
25
|
+
lg: {
|
|
26
|
+
content: string;
|
|
27
|
+
};
|
|
28
|
+
xl: {
|
|
29
|
+
content: string;
|
|
30
|
+
};
|
|
31
|
+
full: {
|
|
14
32
|
content: string;
|
|
15
33
|
};
|
|
16
34
|
};
|
|
@@ -42,16 +60,34 @@ export declare const modalVariants: import("tailwind-variants").TVReturnType<{
|
|
|
42
60
|
close: string;
|
|
43
61
|
}, undefined, {
|
|
44
62
|
transition: {
|
|
45
|
-
|
|
63
|
+
none: {};
|
|
64
|
+
fade: {
|
|
65
|
+
overlay: string;
|
|
66
|
+
content: string;
|
|
67
|
+
};
|
|
68
|
+
slide: {
|
|
69
|
+
overlay: string;
|
|
70
|
+
content: string;
|
|
71
|
+
};
|
|
72
|
+
scale: {
|
|
46
73
|
overlay: string;
|
|
47
74
|
content: string;
|
|
48
75
|
};
|
|
49
76
|
};
|
|
50
|
-
|
|
51
|
-
|
|
77
|
+
size: {
|
|
78
|
+
sm: {
|
|
52
79
|
content: string;
|
|
53
80
|
};
|
|
54
|
-
|
|
81
|
+
md: {
|
|
82
|
+
content: string;
|
|
83
|
+
};
|
|
84
|
+
lg: {
|
|
85
|
+
content: string;
|
|
86
|
+
};
|
|
87
|
+
xl: {
|
|
88
|
+
content: string;
|
|
89
|
+
};
|
|
90
|
+
full: {
|
|
55
91
|
content: string;
|
|
56
92
|
};
|
|
57
93
|
};
|
|
@@ -83,16 +119,34 @@ export declare const modalVariants: import("tailwind-variants").TVReturnType<{
|
|
|
83
119
|
close: string;
|
|
84
120
|
}, import("tailwind-variants").TVReturnType<{
|
|
85
121
|
transition: {
|
|
86
|
-
|
|
122
|
+
none: {};
|
|
123
|
+
fade: {
|
|
124
|
+
overlay: string;
|
|
125
|
+
content: string;
|
|
126
|
+
};
|
|
127
|
+
slide: {
|
|
128
|
+
overlay: string;
|
|
129
|
+
content: string;
|
|
130
|
+
};
|
|
131
|
+
scale: {
|
|
87
132
|
overlay: string;
|
|
88
133
|
content: string;
|
|
89
134
|
};
|
|
90
135
|
};
|
|
91
|
-
|
|
92
|
-
|
|
136
|
+
size: {
|
|
137
|
+
sm: {
|
|
93
138
|
content: string;
|
|
94
139
|
};
|
|
95
|
-
|
|
140
|
+
md: {
|
|
141
|
+
content: string;
|
|
142
|
+
};
|
|
143
|
+
lg: {
|
|
144
|
+
content: string;
|
|
145
|
+
};
|
|
146
|
+
xl: {
|
|
147
|
+
content: string;
|
|
148
|
+
};
|
|
149
|
+
full: {
|
|
96
150
|
content: string;
|
|
97
151
|
};
|
|
98
152
|
};
|
|
@@ -128,16 +182,34 @@ export type ModalSlots = keyof ReturnType<typeof modalVariants>;
|
|
|
128
182
|
export declare const modalDefaults: {
|
|
129
183
|
defaultVariants: import("tailwind-variants").TVDefaultVariants<{
|
|
130
184
|
transition: {
|
|
131
|
-
|
|
185
|
+
none: {};
|
|
186
|
+
fade: {
|
|
187
|
+
overlay: string;
|
|
188
|
+
content: string;
|
|
189
|
+
};
|
|
190
|
+
slide: {
|
|
191
|
+
overlay: string;
|
|
192
|
+
content: string;
|
|
193
|
+
};
|
|
194
|
+
scale: {
|
|
132
195
|
overlay: string;
|
|
133
196
|
content: string;
|
|
134
197
|
};
|
|
135
198
|
};
|
|
136
|
-
|
|
137
|
-
|
|
199
|
+
size: {
|
|
200
|
+
sm: {
|
|
138
201
|
content: string;
|
|
139
202
|
};
|
|
140
|
-
|
|
203
|
+
md: {
|
|
204
|
+
content: string;
|
|
205
|
+
};
|
|
206
|
+
lg: {
|
|
207
|
+
content: string;
|
|
208
|
+
};
|
|
209
|
+
xl: {
|
|
210
|
+
content: string;
|
|
211
|
+
};
|
|
212
|
+
full: {
|
|
141
213
|
content: string;
|
|
142
214
|
};
|
|
143
215
|
};
|
|
@@ -169,16 +241,34 @@ export declare const modalDefaults: {
|
|
|
169
241
|
close: string;
|
|
170
242
|
}, {
|
|
171
243
|
transition: {
|
|
172
|
-
|
|
244
|
+
none: {};
|
|
245
|
+
fade: {
|
|
246
|
+
overlay: string;
|
|
247
|
+
content: string;
|
|
248
|
+
};
|
|
249
|
+
slide: {
|
|
250
|
+
overlay: string;
|
|
251
|
+
content: string;
|
|
252
|
+
};
|
|
253
|
+
scale: {
|
|
173
254
|
overlay: string;
|
|
174
255
|
content: string;
|
|
175
256
|
};
|
|
176
257
|
};
|
|
177
|
-
|
|
178
|
-
|
|
258
|
+
size: {
|
|
259
|
+
sm: {
|
|
179
260
|
content: string;
|
|
180
261
|
};
|
|
181
|
-
|
|
262
|
+
md: {
|
|
263
|
+
content: string;
|
|
264
|
+
};
|
|
265
|
+
lg: {
|
|
266
|
+
content: string;
|
|
267
|
+
};
|
|
268
|
+
xl: {
|
|
269
|
+
content: string;
|
|
270
|
+
};
|
|
271
|
+
full: {
|
|
182
272
|
content: string;
|
|
183
273
|
};
|
|
184
274
|
};
|