svelora 3.0.1 → 3.0.3
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/Accordion/Accordion.svelte +66 -97
- package/dist/Alert/Alert.svelte +39 -64
- package/dist/Alert/Alert.svelte.d.ts +1 -1
- package/dist/Avatar/Avatar.svelte +35 -75
- package/dist/AvatarGroup/AvatarGroup.svelte +38 -55
- package/dist/Badge/Badge.svelte +28 -50
- package/dist/Banner/Banner.svelte +46 -41
- package/dist/Banner/Banner.svelte.d.ts +1 -1
- package/dist/Breadcrumb/Breadcrumb.svelte +32 -26
- package/dist/Button/Button.svelte +70 -138
- package/dist/Calendar/Calendar.svelte +94 -157
- package/dist/Calendar/Calendar.svelte.d.ts +1 -1
- package/dist/Card/Card.svelte +18 -31
- package/dist/Carousel/Carousel.svelte +118 -173
- package/dist/Checkbox/Checkbox.svelte +52 -97
- package/dist/CheckboxGroup/CheckboxGroup.svelte +62 -107
- package/dist/CheckboxGroup/CheckboxGroup.svelte.d.ts +1 -1
- package/dist/Chip/Chip.svelte +22 -34
- package/dist/CodeBlock/CodeBlock.svelte +42 -59
- package/dist/Collapsible/Collapsible.svelte +22 -38
- package/dist/Collapsible/Collapsible.svelte.d.ts +1 -1
- package/dist/Collapsible/CollapsibleTestWrapper.svelte +2 -5
- package/dist/Collapsible/CollapsibleTestWrapper.svelte.d.ts +1 -1
- package/dist/Command/Command.svelte +40 -77
- package/dist/Command/Command.svelte.d.ts +1 -1
- package/dist/Command/CommandTestWrapper.svelte +2 -10
- package/dist/Command/CommandTestWrapper.svelte.d.ts +1 -1
- package/dist/Container/Container.svelte +11 -14
- package/dist/ContextMenu/ContextMenu.svelte +51 -114
- package/dist/ContextMenu/ContextMenu.svelte.d.ts +1 -1
- package/dist/Drawer/Drawer.svelte +72 -110
- package/dist/Drawer/DrawerTriggerTestWrapper.svelte +1 -2
- package/dist/DropdownMenu/DropdownMenu.svelte +63 -124
- package/dist/DropdownMenu/DropdownMenu.svelte.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuTriggerTestWrapper.svelte +2 -5
- package/dist/Editor/Editor.svelte +441 -576
- package/dist/Editor/Editor.svelte.d.ts +1 -1
- package/dist/Editor/EditorUrlPrompt.svelte +40 -53
- package/dist/Editor/SlashPopup.svelte +12 -24
- package/dist/Empty/Empty.svelte +32 -63
- package/dist/FieldGroup/FieldGroup.svelte +23 -38
- package/dist/FileUpload/FileUpload.svelte +242 -320
- package/dist/FileUpload/FileUpload.svelte.d.ts +1 -1
- package/dist/Fonts/Fonts.svelte +15 -37
- package/dist/Form/Form.svelte +112 -170
- package/dist/FormField/FormField.svelte +102 -135
- package/dist/Icon/Icon.svelte +7 -32
- package/dist/Input/Input.svelte +71 -141
- package/dist/Input/Input.svelte.d.ts +2 -2
- package/dist/Kbd/Kbd.svelte +18 -34
- package/dist/Link/Link.svelte +129 -196
- package/dist/LocaleButton/LocaleButton.svelte +165 -0
- package/dist/LocaleButton/LocaleButton.svelte.d.ts +5 -0
- package/dist/LocaleButton/index.d.ts +2 -0
- package/dist/LocaleButton/index.js +1 -0
- package/dist/LocaleButton/locale-button.types.d.ts +182 -0
- package/dist/LocaleButton/locale-button.types.js +1 -0
- package/dist/LocaleButton/locale-button.variants.d.ts +61 -0
- package/dist/LocaleButton/locale-button.variants.js +34 -0
- package/dist/Modal/Modal.svelte +52 -106
- package/dist/Modal/ModalTriggerTestWrapper.svelte +1 -2
- package/dist/Pagination/Pagination.svelte +48 -92
- package/dist/Pagination/pagination.variants.d.ts +1 -1
- package/dist/PinInput/PinInput.svelte +57 -111
- package/dist/PinInput/PinInput.svelte.d.ts +1 -1
- package/dist/Popover/Popover.svelte +28 -61
- package/dist/Popover/Popover.svelte.d.ts +1 -1
- package/dist/Progress/Progress.svelte +75 -94
- package/dist/RadioGroup/RadioGroup.svelte +54 -99
- package/dist/RadioGroup/RadioGroup.svelte.d.ts +1 -1
- package/dist/Select/Select.svelte +112 -269
- package/dist/Select/Select.svelte.d.ts +1 -1
- package/dist/SelectMenu/SelectMenu.svelte +211 -409
- package/dist/SelectMenu/SelectMenu.svelte.d.ts +1 -1
- package/dist/SelectMenu/SelectMenuFormFieldTestWrapper.svelte +3 -6
- package/dist/Separator/Separator.svelte +29 -44
- package/dist/Skeleton/Skeleton.svelte +11 -23
- package/dist/Slideover/Slideover.svelte +52 -106
- package/dist/Slideover/SlideoverTriggerTestWrapper.svelte +1 -2
- package/dist/Slider/Slider.svelte +48 -84
- package/dist/Slider/Slider.svelte.d.ts +1 -1
- package/dist/Stepper/Stepper.svelte +139 -132
- package/dist/Stepper/Stepper.svelte.d.ts +1 -1
- package/dist/Switch/Switch.svelte +62 -98
- package/dist/Table/Table.svelte +232 -283
- package/dist/Table/table.variants.d.ts +1 -1
- package/dist/Tabs/Tabs.svelte +96 -129
- package/dist/Tabs/Tabs.svelte.d.ts +1 -1
- package/dist/Textarea/Textarea.svelte +90 -173
- package/dist/Textarea/Textarea.svelte.d.ts +1 -1
- package/dist/ThemeModeButton/ThemeModeButton.svelte +16 -38
- package/dist/Timeline/Timeline.svelte +75 -54
- package/dist/Toast/Toaster.svelte +8 -25
- package/dist/Tooltip/Tooltip.svelte +34 -66
- package/dist/Tooltip/Tooltip.svelte.d.ts +1 -1
- package/dist/Tooltip/TooltipTestWrapper.svelte +2 -5
- package/dist/User/User.svelte +33 -49
- package/dist/docs/navigation.js +6 -0
- package/dist/hooks/HookContextProbe.svelte +2 -4
- package/dist/hooks/HookContextProvider.svelte +8 -6
- package/dist/hooks/HookEmitProbe.svelte +8 -11
- package/dist/i18n.d.ts +2 -0
- package/dist/i18n.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp/svelora-docs.data.json +4 -2
- package/dist/theme.css +2 -0
- package/package.json +16 -8
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<script lang="ts" module>export {};
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<script lang="ts">import Button from "../Button/Button.svelte";
|
|
5
|
+
import { getComponentConfig, iconsDefaults } from "../config.js";
|
|
6
|
+
import DropdownMenu from "../DropdownMenu/DropdownMenu.svelte";
|
|
7
|
+
import Icon from "../Icon/Icon.svelte";
|
|
8
|
+
import Link from "../Link/Link.svelte";
|
|
9
|
+
import { localeButtonDefaults, localeButtonVariants } from "./locale-button.variants.js";
|
|
10
|
+
const config = getComponentConfig("localeButton", localeButtonDefaults);
|
|
11
|
+
const icons = getComponentConfig("icons", iconsDefaults);
|
|
12
|
+
let { locales = [], locale, variant = config.defaultVariants.variant ?? "outline", color = config.defaultVariants.color ?? "surface", size = config.defaultVariants.size ?? "md", loading = false, disabled = false, block = false, square = false, placeholder = "Select language", ariaLabel = "Change language", menuLabel = "Language", icon = "lucide:languages", chevronIcon = icons.chevronDown, showIcon = true, showChevron = true, showCode = true, showIndicator = true, disableCurrentLocale = true, closeOnSelect = true, getLocaleHref, onLocaleChange, open = $bindable(false), onOpenChange, side = "bottom", sideOffset = 4, align = "start", alignOffset = 0, avoidCollisions = true, collisionBoundary, collisionPadding = 8, sticky = "partial", hideWhenDetached = false, onEscapeKeydown, onInteractOutside, onCloseAutoFocus, forceMount, loop = true, portal = true, arrow = false, ui, children: triggerContent, class: className, ...restProps } = $props();
|
|
13
|
+
const slots = localeButtonVariants();
|
|
14
|
+
const classes = $derived({
|
|
15
|
+
base: slots.base({ class: [
|
|
16
|
+
config.slots.base,
|
|
17
|
+
className,
|
|
18
|
+
ui?.base
|
|
19
|
+
] }),
|
|
20
|
+
triggerLabel: slots.triggerLabel({ class: [config.slots.triggerLabel, ui?.triggerLabel] }),
|
|
21
|
+
triggerIcon: slots.triggerIcon({ class: [config.slots.triggerIcon, ui?.triggerIcon] }),
|
|
22
|
+
triggerChevron: slots.triggerChevron({ class: [config.slots.triggerChevron, ui?.triggerChevron] }),
|
|
23
|
+
menu: slots.menu({ class: [config.slots.menu, ui?.menu] }),
|
|
24
|
+
menuLabel: slots.menuLabel({ class: [config.slots.menuLabel, ui?.menuLabel] }),
|
|
25
|
+
item: slots.item({ class: [config.slots.item, ui?.item] }),
|
|
26
|
+
itemIdle: slots.itemIdle({ class: [config.slots.itemIdle, ui?.itemIdle] }),
|
|
27
|
+
itemCurrent: slots.itemCurrent({ class: [config.slots.itemCurrent, ui?.itemCurrent] }),
|
|
28
|
+
itemLeading: slots.itemLeading({ class: [config.slots.itemLeading, ui?.itemLeading] }),
|
|
29
|
+
itemText: slots.itemText({ class: [config.slots.itemText, ui?.itemText] }),
|
|
30
|
+
itemLabel: slots.itemLabel({ class: [config.slots.itemLabel, ui?.itemLabel] }),
|
|
31
|
+
itemDescription: slots.itemDescription({ class: [config.slots.itemDescription, ui?.itemDescription] }),
|
|
32
|
+
itemCode: slots.itemCode({ class: [config.slots.itemCode, ui?.itemCode] }),
|
|
33
|
+
itemIndicator: slots.itemIndicator({ class: [config.slots.itemIndicator, ui?.itemIndicator] })
|
|
34
|
+
});
|
|
35
|
+
const currentLocale = $derived(locales.find((item) => item.code === locale) ?? locales[0]);
|
|
36
|
+
const triggerLabel = $derived(currentLocale?.shortLabel ?? currentLocale?.label ?? placeholder);
|
|
37
|
+
const triggerDisabled = $derived(disabled || loading || locales.length <= 1);
|
|
38
|
+
function isCurrentLocale(item) {
|
|
39
|
+
return item.code === currentLocale?.code;
|
|
40
|
+
}
|
|
41
|
+
function getResolvedHref(item) {
|
|
42
|
+
return item.href ?? getLocaleHref?.(item.code, item);
|
|
43
|
+
}
|
|
44
|
+
function isItemDisabled(item) {
|
|
45
|
+
return disabled || loading || item.disabled || disableCurrentLocale && isCurrentLocale(item);
|
|
46
|
+
}
|
|
47
|
+
async function handleItemClick(event, item, close) {
|
|
48
|
+
if (isItemDisabled(item)) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
event.stopPropagation();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (onLocaleChange) {
|
|
54
|
+
await onLocaleChange(item.code, item);
|
|
55
|
+
}
|
|
56
|
+
if (!getResolvedHref(item) && closeOnSelect) {
|
|
57
|
+
close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<DropdownMenu
|
|
63
|
+
bind:open
|
|
64
|
+
{onOpenChange}
|
|
65
|
+
{side}
|
|
66
|
+
{sideOffset}
|
|
67
|
+
{align}
|
|
68
|
+
{alignOffset}
|
|
69
|
+
{avoidCollisions}
|
|
70
|
+
{collisionBoundary}
|
|
71
|
+
{collisionPadding}
|
|
72
|
+
{sticky}
|
|
73
|
+
{hideWhenDetached}
|
|
74
|
+
{onEscapeKeydown}
|
|
75
|
+
{onInteractOutside}
|
|
76
|
+
{onCloseAutoFocus}
|
|
77
|
+
{forceMount}
|
|
78
|
+
{loop}
|
|
79
|
+
{portal}
|
|
80
|
+
{arrow}
|
|
81
|
+
>
|
|
82
|
+
{#snippet children({ open: isOpen, props })}
|
|
83
|
+
<Button
|
|
84
|
+
{...props}
|
|
85
|
+
{variant}
|
|
86
|
+
{color}
|
|
87
|
+
{size}
|
|
88
|
+
{loading}
|
|
89
|
+
disabled={triggerDisabled}
|
|
90
|
+
{block}
|
|
91
|
+
{square}
|
|
92
|
+
class={classes.base}
|
|
93
|
+
aria-label={ariaLabel}
|
|
94
|
+
{...restProps}
|
|
95
|
+
>
|
|
96
|
+
{#if triggerContent}
|
|
97
|
+
{@render triggerContent({ open: isOpen, currentLocale })}
|
|
98
|
+
{:else}
|
|
99
|
+
{#if showIcon}
|
|
100
|
+
<span class={classes.triggerIcon}>
|
|
101
|
+
<Icon name={icon} />
|
|
102
|
+
</span>
|
|
103
|
+
{/if}
|
|
104
|
+
<span class={classes.triggerLabel}>{triggerLabel}</span>
|
|
105
|
+
{#if showChevron}
|
|
106
|
+
<span class={classes.triggerChevron}>
|
|
107
|
+
<Icon name={chevronIcon} />
|
|
108
|
+
</span>
|
|
109
|
+
{/if}
|
|
110
|
+
{/if}
|
|
111
|
+
</Button>
|
|
112
|
+
{/snippet}
|
|
113
|
+
|
|
114
|
+
{#snippet content({ close })}
|
|
115
|
+
<div class={classes.menu}>
|
|
116
|
+
{#if menuLabel}
|
|
117
|
+
<p class={classes.menuLabel}>{menuLabel}</p>
|
|
118
|
+
{/if}
|
|
119
|
+
|
|
120
|
+
{#each locales as item (item.code)}
|
|
121
|
+
{@const current = isCurrentLocale(item)}
|
|
122
|
+
{@const href = getResolvedHref(item)}
|
|
123
|
+
{@const itemDisabled = isItemDisabled(item)}
|
|
124
|
+
|
|
125
|
+
<Link
|
|
126
|
+
href={href}
|
|
127
|
+
hreflang={item.hreflang ?? item.code}
|
|
128
|
+
raw
|
|
129
|
+
role="menuitemradio"
|
|
130
|
+
aria-checked={current}
|
|
131
|
+
disabled={itemDisabled}
|
|
132
|
+
class={[
|
|
133
|
+
classes.item,
|
|
134
|
+
current ? classes.itemCurrent : classes.itemIdle,
|
|
135
|
+
item.class
|
|
136
|
+
]}
|
|
137
|
+
onclick={(event) => handleItemClick(event, item, close)}
|
|
138
|
+
>
|
|
139
|
+
<span class={classes.itemLeading}>
|
|
140
|
+
{#if item.icon}
|
|
141
|
+
<Icon name={item.icon} />
|
|
142
|
+
{/if}
|
|
143
|
+
<span class={classes.itemText}>
|
|
144
|
+
<span class={classes.itemLabel}>{item.label}</span>
|
|
145
|
+
{#if item.description}
|
|
146
|
+
<span class={classes.itemDescription}>{item.description}</span>
|
|
147
|
+
{/if}
|
|
148
|
+
</span>
|
|
149
|
+
</span>
|
|
150
|
+
|
|
151
|
+
<span class="flex items-center gap-2">
|
|
152
|
+
{#if showCode}
|
|
153
|
+
<span class={classes.itemCode}>{item.shortLabel ?? item.code}</span>
|
|
154
|
+
{/if}
|
|
155
|
+
{#if showIndicator && current}
|
|
156
|
+
<span class={classes.itemIndicator}>
|
|
157
|
+
<Icon name={icons.check} />
|
|
158
|
+
</span>
|
|
159
|
+
{/if}
|
|
160
|
+
</span>
|
|
161
|
+
</Link>
|
|
162
|
+
{/each}
|
|
163
|
+
</div>
|
|
164
|
+
{/snippet}
|
|
165
|
+
</DropdownMenu>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LocaleButtonProps } from './locale-button.types.js';
|
|
2
|
+
export type Props = LocaleButtonProps;
|
|
3
|
+
declare const LocaleButton: import("svelte").Component<LocaleButtonProps, {}, "open">;
|
|
4
|
+
type LocaleButton = ReturnType<typeof LocaleButton>;
|
|
5
|
+
export default LocaleButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as LocaleButton } from './LocaleButton.svelte';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { DropdownMenuContentPropsWithoutHTML, DropdownMenuRootPropsWithoutHTML } from 'bits-ui';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
5
|
+
import type { ButtonVariantProps } from '../Button/button.variants.js';
|
|
6
|
+
import type { LocaleButtonSlots } from './locale-button.variants.js';
|
|
7
|
+
export type LocaleButtonLocale = {
|
|
8
|
+
/**
|
|
9
|
+
* Locale code used by your i18n layer, for example `en` or `th`.
|
|
10
|
+
*/
|
|
11
|
+
code: string;
|
|
12
|
+
/**
|
|
13
|
+
* Full label rendered in the dropdown menu.
|
|
14
|
+
*/
|
|
15
|
+
label: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional short label for the trigger, such as `EN` or `TH`.
|
|
18
|
+
*/
|
|
19
|
+
shortLabel?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Optional helper text shown below the label.
|
|
22
|
+
*/
|
|
23
|
+
description?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional static href for this locale.
|
|
26
|
+
*/
|
|
27
|
+
href?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Optional language tag forwarded to anchor items.
|
|
30
|
+
*/
|
|
31
|
+
hreflang?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Optional leading icon for the locale item.
|
|
34
|
+
*/
|
|
35
|
+
icon?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Disables this locale in the dropdown.
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Additional CSS classes for the locale item.
|
|
43
|
+
*/
|
|
44
|
+
class?: ClassNameValue;
|
|
45
|
+
};
|
|
46
|
+
type RootProps = Pick<DropdownMenuRootPropsWithoutHTML, 'open' | 'onOpenChange'>;
|
|
47
|
+
type ContentProps = Pick<DropdownMenuContentPropsWithoutHTML, 'side' | 'sideOffset' | 'align' | 'alignOffset' | 'avoidCollisions' | 'collisionBoundary' | 'collisionPadding' | 'sticky' | 'hideWhenDetached' | 'onEscapeKeydown' | 'onInteractOutside' | 'onCloseAutoFocus' | 'forceMount' | 'loop'>;
|
|
48
|
+
export type LocaleButtonProps = Omit<HTMLAttributes<HTMLElement>, 'children' | 'class' | 'color'> & RootProps & ContentProps & {
|
|
49
|
+
/**
|
|
50
|
+
* Available locales shown in the menu.
|
|
51
|
+
*/
|
|
52
|
+
locales: LocaleButtonLocale[];
|
|
53
|
+
/**
|
|
54
|
+
* Current active locale code.
|
|
55
|
+
*/
|
|
56
|
+
locale?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Controls the visual style of the trigger button.
|
|
59
|
+
* @default 'outline'
|
|
60
|
+
*/
|
|
61
|
+
variant?: NonNullable<ButtonVariantProps['variant']>;
|
|
62
|
+
/**
|
|
63
|
+
* Sets the color scheme of the trigger button.
|
|
64
|
+
* @default 'surface'
|
|
65
|
+
*/
|
|
66
|
+
color?: NonNullable<ButtonVariantProps['color']>;
|
|
67
|
+
/**
|
|
68
|
+
* Controls the trigger button size.
|
|
69
|
+
* @default 'md'
|
|
70
|
+
*/
|
|
71
|
+
size?: NonNullable<ButtonVariantProps['size']>;
|
|
72
|
+
/**
|
|
73
|
+
* Renders a loading spinner and disables interaction.
|
|
74
|
+
* @default false
|
|
75
|
+
*/
|
|
76
|
+
loading?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Disables the trigger and all locale actions.
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
disabled?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Stretches the trigger to fill the available width.
|
|
84
|
+
* @default false
|
|
85
|
+
*/
|
|
86
|
+
block?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Forces equal width and height for the trigger button.
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
square?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Fallback text shown when no current locale is matched.
|
|
94
|
+
* @default 'Select language'
|
|
95
|
+
*/
|
|
96
|
+
placeholder?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Accessible label for the trigger button.
|
|
99
|
+
* @default 'Change language'
|
|
100
|
+
*/
|
|
101
|
+
ariaLabel?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Optional heading rendered above the locale list.
|
|
104
|
+
* @default 'Language'
|
|
105
|
+
*/
|
|
106
|
+
menuLabel?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Leading icon displayed in the trigger.
|
|
109
|
+
* @default 'lucide:languages'
|
|
110
|
+
*/
|
|
111
|
+
icon?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Trailing chevron icon displayed in the trigger.
|
|
114
|
+
* @default Uses `icons.chevronDown` from app config
|
|
115
|
+
*/
|
|
116
|
+
chevronIcon?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Whether to render the leading trigger icon.
|
|
119
|
+
* @default true
|
|
120
|
+
*/
|
|
121
|
+
showIcon?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Whether to render the trailing chevron icon.
|
|
124
|
+
* @default true
|
|
125
|
+
*/
|
|
126
|
+
showChevron?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Whether to render the locale code badge inside the menu.
|
|
129
|
+
* @default true
|
|
130
|
+
*/
|
|
131
|
+
showCode?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Whether to render the selected locale check icon.
|
|
134
|
+
* @default true
|
|
135
|
+
*/
|
|
136
|
+
showIndicator?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Disables the currently active locale item.
|
|
139
|
+
* @default true
|
|
140
|
+
*/
|
|
141
|
+
disableCurrentLocale?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Closes the menu after selecting a locale without href navigation.
|
|
144
|
+
* @default true
|
|
145
|
+
*/
|
|
146
|
+
closeOnSelect?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Resolves a locale-specific href, useful for Paraglide URL strategies.
|
|
149
|
+
*/
|
|
150
|
+
getLocaleHref?: (locale: string, item: LocaleButtonLocale) => string | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* Called when a locale is selected.
|
|
153
|
+
* Use this for integrations like `setLocale(...)`.
|
|
154
|
+
*/
|
|
155
|
+
onLocaleChange?: (locale: string, item: LocaleButtonLocale) => void | Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Render custom trigger content.
|
|
158
|
+
*/
|
|
159
|
+
children?: Snippet<[{
|
|
160
|
+
open: boolean;
|
|
161
|
+
currentLocale: LocaleButtonLocale | undefined;
|
|
162
|
+
}]>;
|
|
163
|
+
/**
|
|
164
|
+
* Whether to render the menu in a portal.
|
|
165
|
+
* @default true
|
|
166
|
+
*/
|
|
167
|
+
portal?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Display an arrow alongside the dropdown.
|
|
170
|
+
* @default false
|
|
171
|
+
*/
|
|
172
|
+
arrow?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Additional CSS classes for the trigger element.
|
|
175
|
+
*/
|
|
176
|
+
class?: ClassNameValue;
|
|
177
|
+
/**
|
|
178
|
+
* Override classes for LocaleButton slots.
|
|
179
|
+
*/
|
|
180
|
+
ui?: Partial<Record<LocaleButtonSlots, ClassNameValue>>;
|
|
181
|
+
};
|
|
182
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type VariantProps } from 'tailwind-variants';
|
|
2
|
+
import type { ButtonVariantProps } from '../Button/button.variants.js';
|
|
3
|
+
export declare const localeButtonVariants: import("tailwind-variants").TVReturnType<{}, {
|
|
4
|
+
base: string;
|
|
5
|
+
triggerLabel: string;
|
|
6
|
+
triggerIcon: string;
|
|
7
|
+
triggerChevron: string;
|
|
8
|
+
menu: string;
|
|
9
|
+
menuLabel: string;
|
|
10
|
+
item: string[];
|
|
11
|
+
itemIdle: string;
|
|
12
|
+
itemCurrent: string;
|
|
13
|
+
itemLeading: string;
|
|
14
|
+
itemText: string;
|
|
15
|
+
itemLabel: string;
|
|
16
|
+
itemDescription: string;
|
|
17
|
+
itemCode: string;
|
|
18
|
+
itemIndicator: string;
|
|
19
|
+
}, undefined, {}, {
|
|
20
|
+
base: string;
|
|
21
|
+
triggerLabel: string;
|
|
22
|
+
triggerIcon: string;
|
|
23
|
+
triggerChevron: string;
|
|
24
|
+
menu: string;
|
|
25
|
+
menuLabel: string;
|
|
26
|
+
item: string[];
|
|
27
|
+
itemIdle: string;
|
|
28
|
+
itemCurrent: string;
|
|
29
|
+
itemLeading: string;
|
|
30
|
+
itemText: string;
|
|
31
|
+
itemLabel: string;
|
|
32
|
+
itemDescription: string;
|
|
33
|
+
itemCode: string;
|
|
34
|
+
itemIndicator: string;
|
|
35
|
+
}, import("tailwind-variants").TVReturnType<{}, {
|
|
36
|
+
base: string;
|
|
37
|
+
triggerLabel: string;
|
|
38
|
+
triggerIcon: string;
|
|
39
|
+
triggerChevron: string;
|
|
40
|
+
menu: string;
|
|
41
|
+
menuLabel: string;
|
|
42
|
+
item: string[];
|
|
43
|
+
itemIdle: string;
|
|
44
|
+
itemCurrent: string;
|
|
45
|
+
itemLeading: string;
|
|
46
|
+
itemText: string;
|
|
47
|
+
itemLabel: string;
|
|
48
|
+
itemDescription: string;
|
|
49
|
+
itemCode: string;
|
|
50
|
+
itemIndicator: string;
|
|
51
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
52
|
+
export type LocaleButtonVariantProps = VariantProps<typeof localeButtonVariants>;
|
|
53
|
+
export type LocaleButtonSlots = keyof ReturnType<typeof localeButtonVariants>;
|
|
54
|
+
export declare const localeButtonDefaults: {
|
|
55
|
+
defaultVariants: {
|
|
56
|
+
color: NonNullable<ButtonVariantProps["color"]>;
|
|
57
|
+
variant: NonNullable<ButtonVariantProps["variant"]>;
|
|
58
|
+
size: NonNullable<ButtonVariantProps["size"]>;
|
|
59
|
+
};
|
|
60
|
+
slots: Partial<Record<LocaleButtonSlots, string>>;
|
|
61
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const localeButtonVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
base: '',
|
|
5
|
+
triggerLabel: 'truncate',
|
|
6
|
+
triggerIcon: 'shrink-0',
|
|
7
|
+
triggerChevron: 'shrink-0 opacity-70',
|
|
8
|
+
menu: 'min-w-52 space-y-1 rounded-xl p-1',
|
|
9
|
+
menuLabel: 'px-3 pt-2 pb-1 text-xs font-semibold tracking-[0.14em] text-on-surface-variant uppercase',
|
|
10
|
+
item: [
|
|
11
|
+
'flex w-full items-center justify-between gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors',
|
|
12
|
+
'focus-visible:ring-primary/40 focus-visible:outline-none focus-visible:ring-2'
|
|
13
|
+
],
|
|
14
|
+
itemIdle: 'text-on-surface hover:bg-surface-container-high',
|
|
15
|
+
itemCurrent: 'bg-primary/10 text-primary',
|
|
16
|
+
itemLeading: 'flex min-w-0 items-start gap-2.5',
|
|
17
|
+
itemText: 'min-w-0 space-y-0.5',
|
|
18
|
+
itemLabel: 'truncate font-medium',
|
|
19
|
+
itemDescription: 'text-xs text-on-surface-variant',
|
|
20
|
+
itemCode: 'shrink-0 rounded-md bg-surface-container px-1.5 py-0.5 text-[11px] font-medium text-on-surface-variant uppercase',
|
|
21
|
+
itemIndicator: 'shrink-0 text-primary'
|
|
22
|
+
},
|
|
23
|
+
variants: {},
|
|
24
|
+
defaultVariants: {}
|
|
25
|
+
});
|
|
26
|
+
export const localeButtonDefaults = {
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
...localeButtonVariants.defaultVariants,
|
|
29
|
+
color: 'surface',
|
|
30
|
+
variant: 'outline',
|
|
31
|
+
size: 'md'
|
|
32
|
+
},
|
|
33
|
+
slots: {}
|
|
34
|
+
};
|
package/dist/Modal/Modal.svelte
CHANGED
|
@@ -1,111 +1,57 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import type { ModalProps } from './modal.types.js'
|
|
3
|
-
|
|
4
|
-
export type Props = ModalProps
|
|
1
|
+
<script lang="ts" module>export {};
|
|
5
2
|
</script>
|
|
6
3
|
|
|
7
|
-
<script lang="ts">
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const hasTitle = $derived(!!title || !!titleSlot)
|
|
59
|
-
const hasDescription = $derived(!!description || !!descriptionSlot)
|
|
60
|
-
const hasHeading = $derived(hasTitle || hasDescription)
|
|
61
|
-
const hasHeader = $derived(
|
|
62
|
-
!!headerSlot || hasHeading || !!actionsSlot || showClose || !!closeSlot
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
const variantSlots = $derived(
|
|
66
|
-
modalVariants({
|
|
67
|
-
transition: resolvedTransition,
|
|
68
|
-
size: resolvedSize,
|
|
69
|
-
overlay: showOverlay,
|
|
70
|
-
scrollable
|
|
71
|
-
})
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
const classes = $derived({
|
|
75
|
-
overlay: variantSlots.overlay({ class: [config.slots.overlay, ui?.overlay] }),
|
|
76
|
-
content: variantSlots.content({ class: [config.slots.content, ui?.content] }),
|
|
77
|
-
header: variantSlots.header({ class: [config.slots.header, ui?.header] }),
|
|
78
|
-
wrapper: variantSlots.wrapper({ class: [config.slots.wrapper, ui?.wrapper] }),
|
|
79
|
-
title: variantSlots.title({ class: [config.slots.title, ui?.title] }),
|
|
80
|
-
description: variantSlots.description({
|
|
81
|
-
class: [config.slots.description, ui?.description]
|
|
82
|
-
}),
|
|
83
|
-
actions: variantSlots.actions({ class: [config.slots.actions, ui?.actions] }),
|
|
84
|
-
body: variantSlots.body({ class: [config.slots.body, ui?.body] }),
|
|
85
|
-
footer: variantSlots.footer({ class: [config.slots.footer, ui?.footer] }),
|
|
86
|
-
close: variantSlots.close({ class: [config.slots.close, ui?.close] })
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
const contentProps = $derived.by(() => {
|
|
90
|
-
const behavior = dismissible ? ('close' as const) : ('ignore' as const)
|
|
91
|
-
return {
|
|
92
|
-
trapFocus,
|
|
93
|
-
preventScroll,
|
|
94
|
-
escapeKeydownBehavior: behavior,
|
|
95
|
-
interactOutsideBehavior: behavior,
|
|
96
|
-
onOpenAutoFocus,
|
|
97
|
-
onCloseAutoFocus,
|
|
98
|
-
onEscapeKeydown,
|
|
99
|
-
onInteractOutside,
|
|
100
|
-
forceMount,
|
|
101
|
-
restoreScrollDelay
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
function handleOpenChange(value: boolean) {
|
|
106
|
-
open = value
|
|
107
|
-
onOpenChange?.(value)
|
|
108
|
-
}
|
|
4
|
+
<script lang="ts">import { Dialog } from "bits-ui";
|
|
5
|
+
import Button from "../Button/Button.svelte";
|
|
6
|
+
import { getComponentConfig } from "../config.js";
|
|
7
|
+
import { modalDefaults, modalVariants } from "./modal.variants.js";
|
|
8
|
+
const config = getComponentConfig("modal", modalDefaults);
|
|
9
|
+
let { open = $bindable(false), onOpenChange, onOpenChangeComplete, trapFocus = true, preventScroll = true, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeydown, onInteractOutside, forceMount, restoreScrollDelay, title, description, overlay: showOverlay = config.defaultVariants.overlay ?? true, scrollable = config.defaultVariants.scrollable ?? false, transition = config.defaultVariants.transition ?? "scale", size = config.defaultVariants.size ?? "md", fullscreen = false, portal = true, close: closeProp = true, dismissible = true, ui, class: className, children, content: contentSlot, header: headerSlot, titleSlot, descriptionSlot, actions: actionsSlot, body: bodySlot, footer: footerSlot, closeSlot } = $props();
|
|
10
|
+
const resolvedSize = $derived(fullscreen ? "full" : size);
|
|
11
|
+
const resolvedTransition = $derived(transition === false ? "none" : transition === true ? "scale" : transition);
|
|
12
|
+
const showClose = $derived(!!closeProp);
|
|
13
|
+
const closeProps = $derived(typeof closeProp === "object" ? closeProp : {});
|
|
14
|
+
const hasTitle = $derived(!!title || !!titleSlot);
|
|
15
|
+
const hasDescription = $derived(!!description || !!descriptionSlot);
|
|
16
|
+
const hasHeading = $derived(hasTitle || hasDescription);
|
|
17
|
+
const hasHeader = $derived(!!headerSlot || hasHeading || !!actionsSlot || showClose || !!closeSlot);
|
|
18
|
+
const variantSlots = $derived(modalVariants({
|
|
19
|
+
transition: resolvedTransition,
|
|
20
|
+
size: resolvedSize,
|
|
21
|
+
overlay: showOverlay,
|
|
22
|
+
scrollable
|
|
23
|
+
}));
|
|
24
|
+
const classes = $derived({
|
|
25
|
+
overlay: variantSlots.overlay({ class: [config.slots.overlay, ui?.overlay] }),
|
|
26
|
+
content: variantSlots.content({ class: [config.slots.content, ui?.content] }),
|
|
27
|
+
header: variantSlots.header({ class: [config.slots.header, ui?.header] }),
|
|
28
|
+
wrapper: variantSlots.wrapper({ class: [config.slots.wrapper, ui?.wrapper] }),
|
|
29
|
+
title: variantSlots.title({ class: [config.slots.title, ui?.title] }),
|
|
30
|
+
description: variantSlots.description({ class: [config.slots.description, ui?.description] }),
|
|
31
|
+
actions: variantSlots.actions({ class: [config.slots.actions, ui?.actions] }),
|
|
32
|
+
body: variantSlots.body({ class: [config.slots.body, ui?.body] }),
|
|
33
|
+
footer: variantSlots.footer({ class: [config.slots.footer, ui?.footer] }),
|
|
34
|
+
close: variantSlots.close({ class: [config.slots.close, ui?.close] })
|
|
35
|
+
});
|
|
36
|
+
const contentProps = $derived.by(() => {
|
|
37
|
+
const behavior = dismissible ? "close" : "ignore";
|
|
38
|
+
return {
|
|
39
|
+
trapFocus,
|
|
40
|
+
preventScroll,
|
|
41
|
+
escapeKeydownBehavior: behavior,
|
|
42
|
+
interactOutsideBehavior: behavior,
|
|
43
|
+
onOpenAutoFocus,
|
|
44
|
+
onCloseAutoFocus,
|
|
45
|
+
onEscapeKeydown,
|
|
46
|
+
onInteractOutside,
|
|
47
|
+
forceMount,
|
|
48
|
+
restoreScrollDelay
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
function handleOpenChange(value) {
|
|
52
|
+
open = value;
|
|
53
|
+
onOpenChange?.(value);
|
|
54
|
+
}
|
|
109
55
|
</script>
|
|
110
56
|
|
|
111
57
|
{#snippet titleEl()}
|