@marwes-ui/svelte 1.3.0 → 1.4.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/CHANGELOG.md +30 -0
- package/README.md +43 -11
- package/dist/components/README.md +31 -0
- package/dist/components/accordion/AccordionField.svelte +20 -6
- package/dist/components/accordion/index.d.ts +5 -2
- package/dist/components/accordion/index.js +7 -1
- package/dist/components/accordion/types.d.ts +3 -0
- package/dist/components/avatar/AvatarGroup.svelte +5 -2
- package/dist/components/avatar/AvatarGroup.svelte.d.ts +1 -0
- package/dist/components/avatar/TeamAvatarGroup.svelte +1 -0
- package/dist/components/avatar/TeamAvatarGroup.svelte.d.ts +1 -0
- package/dist/components/avatar/index.d.ts +7 -1
- package/dist/components/avatar/index.js +6 -0
- package/dist/components/avatar/types.d.ts +28 -0
- package/dist/components/badge/BadgeGroup.svelte +2 -1
- package/dist/components/badge/index.d.ts +5 -1
- package/dist/components/badge/index.js +4 -0
- package/dist/components/badge/types.d.ts +3 -0
- package/dist/components/banner/Banner.svelte +67 -0
- package/dist/components/banner/Banner.svelte.d.ts +4 -0
- package/dist/components/banner/ErrorBanner.svelte +9 -0
- package/dist/components/banner/ErrorBanner.svelte.d.ts +4 -0
- package/dist/components/banner/InfoBanner.svelte +9 -0
- package/dist/components/banner/InfoBanner.svelte.d.ts +4 -0
- package/dist/components/banner/SuccessBanner.svelte +9 -0
- package/dist/components/banner/SuccessBanner.svelte.d.ts +4 -0
- package/dist/components/banner/WarningBanner.svelte +9 -0
- package/dist/components/banner/WarningBanner.svelte.d.ts +4 -0
- package/dist/components/banner/index.d.ts +7 -0
- package/dist/components/banner/index.js +6 -0
- package/dist/components/banner/types.d.ts +14 -0
- package/dist/components/banner/types.js +1 -0
- package/dist/components/breadcrumb/Breadcrumb.svelte +115 -0
- package/dist/components/breadcrumb/Breadcrumb.svelte.d.ts +4 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/breadcrumb/types.d.ts +8 -0
- package/dist/components/breadcrumb/types.js +1 -0
- package/dist/components/button/Button.svelte +8 -4
- package/dist/components/button/DestructiveButton.svelte +1 -1
- package/dist/components/button/IconButton.svelte +9 -0
- package/dist/components/button/IconButton.svelte.d.ts +4 -0
- package/dist/components/button/index.d.ts +24 -1
- package/dist/components/button/index.js +23 -0
- package/dist/components/button/types.d.ts +30 -1
- package/dist/components/card/Card.svelte +2 -1
- package/dist/components/card/index.d.ts +4 -1
- package/dist/components/card/index.js +3 -0
- package/dist/components/card/types.d.ts +4 -0
- package/dist/components/checkbox/CheckboxField.svelte +4 -3
- package/dist/components/checkbox/CheckboxGroupField.svelte +21 -9
- package/dist/components/checkbox/index.d.ts +2 -2
- package/dist/components/checkbox/index.js +4 -1
- package/dist/components/checkbox/types.d.ts +7 -0
- package/dist/components/context-menu/ContextMenu.svelte +56 -0
- package/dist/components/context-menu/ContextMenu.svelte.d.ts +4 -0
- package/dist/components/context-menu/index.d.ts +2 -0
- package/dist/components/context-menu/index.js +1 -0
- package/dist/components/context-menu/types.d.ts +7 -0
- package/dist/components/context-menu/types.js +1 -0
- package/dist/components/date-picker/DatePicker.svelte +14 -2
- package/dist/components/date-picker/DatePickerField.svelte +72 -0
- package/dist/components/date-picker/DatePickerField.svelte.d.ts +4 -0
- package/dist/components/date-picker/index.d.ts +2 -2
- package/dist/components/date-picker/index.js +3 -1
- package/dist/components/date-picker/types.d.ts +15 -0
- package/dist/components/dialog/Dialog.svelte +1 -0
- package/dist/components/dialog/DialogModal.svelte +12 -0
- package/dist/components/dialog/index.d.ts +1 -1
- package/dist/components/dialog/types.d.ts +7 -3
- package/dist/components/drawer/Drawer.svelte +132 -0
- package/dist/components/drawer/Drawer.svelte.d.ts +4 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/drawer/types.d.ts +16 -0
- package/dist/components/drawer/types.js +1 -0
- package/dist/components/heading/H1.svelte +10 -0
- package/dist/components/heading/H2.svelte +6 -0
- package/dist/components/heading/H3.svelte +7 -0
- package/dist/components/input/CurrencyField.svelte +1 -1
- package/dist/components/input/Input.svelte +1 -0
- package/dist/components/input/InputField.svelte +4 -3
- package/dist/components/input/InputOtp.svelte +21 -44
- package/dist/components/input/InputOtpField.svelte +81 -0
- package/dist/components/input/InputOtpField.svelte.d.ts +4 -0
- package/dist/components/input/RichText.svelte +7 -6
- package/dist/components/input/RichTextField.svelte +4 -3
- package/dist/components/input/Select.svelte +7 -31
- package/dist/components/input/SelectField.svelte +6 -3
- package/dist/components/input/Textarea.svelte +1 -0
- package/dist/components/input/TextareaField.svelte +20 -5
- package/dist/components/input/index.d.ts +12 -4
- package/dist/components/input/index.js +19 -3
- package/dist/components/input/types.d.ts +59 -5
- package/dist/components/pagination/Pagination.svelte +399 -0
- package/dist/components/pagination/Pagination.svelte.d.ts +4 -0
- package/dist/components/pagination/PaginationField.svelte +72 -0
- package/dist/components/pagination/PaginationField.svelte.d.ts +4 -0
- package/dist/components/pagination/index.d.ts +2 -0
- package/dist/components/pagination/index.js +2 -0
- package/dist/components/pagination/types.d.ts +40 -0
- package/dist/components/pagination/types.js +1 -0
- package/dist/components/progress-bar/ProgressBar.svelte +50 -0
- package/dist/components/progress-bar/ProgressBar.svelte.d.ts +4 -0
- package/dist/components/progress-bar/index.d.ts +2 -0
- package/dist/components/progress-bar/index.js +1 -0
- package/dist/components/progress-bar/types.d.ts +6 -0
- package/dist/components/progress-bar/types.js +1 -0
- package/dist/components/radio/OptionRadioGroup.svelte +39 -5
- package/dist/components/radio/OptionRadioGroup.svelte.d.ts +2 -5
- package/dist/components/radio/Radio.svelte +1 -0
- package/dist/components/radio/RadioGroupField.svelte +4 -3
- package/dist/components/radio/RatingRadioGroup.svelte +18 -3
- package/dist/components/radio/YesNoRadioGroup.svelte +18 -3
- package/dist/components/radio/index.d.ts +4 -2
- package/dist/components/radio/index.js +6 -1
- package/dist/components/radio/types.d.ts +47 -0
- package/dist/components/segmented-control/SegmentedControl.svelte +125 -0
- package/dist/components/segmented-control/SegmentedControl.svelte.d.ts +25 -0
- package/dist/components/segmented-control/SegmentedControlField.svelte +76 -0
- package/dist/components/segmented-control/SegmentedControlField.svelte.d.ts +25 -0
- package/dist/components/segmented-control/index.d.ts +2 -0
- package/dist/components/segmented-control/index.js +2 -0
- package/dist/components/segmented-control/types.d.ts +41 -0
- package/dist/components/segmented-control/types.js +1 -0
- package/dist/components/skip-link/SkipLink.svelte +12 -0
- package/dist/components/skip-link/SkipLink.svelte.d.ts +4 -0
- package/dist/components/skip-link/index.d.ts +2 -0
- package/dist/components/skip-link/index.js +1 -0
- package/dist/components/skip-link/types.d.ts +7 -0
- package/dist/components/skip-link/types.js +1 -0
- package/dist/components/slider/SliderField.svelte +9 -8
- package/dist/components/slider/index.d.ts +5 -2
- package/dist/components/slider/index.js +7 -1
- package/dist/components/slider/types.d.ts +21 -0
- package/dist/components/spinner/EmptyStateSpinner.svelte +2 -3
- package/dist/components/spinner/EmptyStateSpinner.svelte.d.ts +1 -2
- package/dist/components/spinner/Spinner.svelte +2 -0
- package/dist/components/spinner/index.d.ts +2 -1
- package/dist/components/spinner/index.js +1 -0
- package/dist/components/spinner/types.d.ts +1 -0
- package/dist/components/switch/Switch.svelte +1 -1
- package/dist/components/switch/SwitchField.svelte +6 -4
- package/dist/components/switch/index.d.ts +4 -2
- package/dist/components/switch/index.js +6 -1
- package/dist/components/switch/types.d.ts +3 -0
- package/dist/components/tab/TabGroup.svelte +7 -4
- package/dist/components/text/Text.svelte +23 -0
- package/dist/components/text/Text.svelte.d.ts +4 -0
- package/dist/components/text/index.d.ts +4 -0
- package/dist/components/text/index.js +2 -0
- package/dist/components/text/types.d.ts +15 -0
- package/dist/components/text/types.js +1 -0
- package/dist/components/tooltip/TooltipGroup.svelte +10 -2
- package/dist/index.d.ts +47 -29
- package/dist/index.js +51 -13
- package/dist/provider/MarwesProvider.svelte +26 -14
- package/dist/provider/types.d.ts +5 -2
- package/package.json +6 -5
- package/dist/components/accordion/README.md +0 -19
- package/dist/components/avatar/README.md +0 -19
- package/dist/components/badge/README.md +0 -16
- package/dist/components/button/README.md +0 -21
- package/dist/components/card/README.md +0 -15
- package/dist/components/checkbox/README.md +0 -17
- package/dist/components/date-picker/README.md +0 -17
- package/dist/components/dialog/README.md +0 -23
- package/dist/components/divider/README.md +0 -15
- package/dist/components/heading/README.md +0 -13
- package/dist/components/icon/README.md +0 -18
- package/dist/components/input/README.md +0 -24
- package/dist/components/paragraph/README.md +0 -13
- package/dist/components/radio/README.md +0 -16
- package/dist/components/skeleton/README.md +0 -16
- package/dist/components/slider/README.md +0 -20
- package/dist/components/spacing/README.md +0 -15
- package/dist/components/spinner/README.md +0 -19
- package/dist/components/stat-tile/README.md +0 -15
- package/dist/components/switch/README.md +0 -17
- package/dist/components/tab/README.md +0 -26
- package/dist/components/toast/README.md +0 -35
- package/dist/components/tooltip/README.md +0 -22
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export type {
|
|
1
|
+
export { default as DatePickerField } from "./DatePickerField.svelte";
|
|
2
|
+
export type { DatePickerFieldProps } from "./types.js";
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
// `DatePicker` atom intentionally NOT re-exported — use `DatePickerField`.
|
|
2
|
+
// Internal consumers can deep-import "./DatePicker.svelte" directly.
|
|
3
|
+
export { default as DatePickerField } from "./DatePickerField.svelte";
|
|
@@ -11,3 +11,18 @@ export interface DatePickerProps extends DatePickerOptions {
|
|
|
11
11
|
onapply?: () => void;
|
|
12
12
|
class?: string;
|
|
13
13
|
}
|
|
14
|
+
export interface DatePickerFieldProps {
|
|
15
|
+
/** Optional: if omitted, a stable id is generated. */
|
|
16
|
+
id?: string;
|
|
17
|
+
/** Field label (required for accessibility). */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Optional helper text shown below the calendar. */
|
|
20
|
+
helperText?: string;
|
|
21
|
+
/** Optional error message. */
|
|
22
|
+
error?: string;
|
|
23
|
+
/** Props forwarded to the DatePicker atom. */
|
|
24
|
+
datePicker?: Omit<DatePickerProps, "ariaLabel" | "ariaLabelledBy" | "calendarLabel">;
|
|
25
|
+
/** Additional aria-describedby IDs to merge with internal helper/error IDs. */
|
|
26
|
+
ariaDescribedBy?: string;
|
|
27
|
+
class?: string;
|
|
28
|
+
}
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
closeOnEscape = true,
|
|
9
9
|
closeOnScrimClick = true,
|
|
10
10
|
restoreFocus = true,
|
|
11
|
+
surfaceWidth,
|
|
12
|
+
tone = "default",
|
|
13
|
+
divider = "visible",
|
|
11
14
|
onopenchange,
|
|
12
15
|
overlayClass,
|
|
13
16
|
footer,
|
|
@@ -19,6 +22,11 @@
|
|
|
19
22
|
let previouslyFocused: HTMLElement | null = $state(null);
|
|
20
23
|
|
|
21
24
|
const mergedOverlayClass = $derived(mergeClass("mw-dialog-modal", overlayClass));
|
|
25
|
+
const surfaceWidthStyle = $derived(
|
|
26
|
+
surfaceWidth === undefined
|
|
27
|
+
? undefined
|
|
28
|
+
: `--mw-dialog-surface-width: ${typeof surfaceWidth === "number" ? `${surfaceWidth}px` : surfaceWidth}`
|
|
29
|
+
);
|
|
22
30
|
|
|
23
31
|
function close(): void {
|
|
24
32
|
if (!open) return;
|
|
@@ -108,6 +116,10 @@
|
|
|
108
116
|
<div
|
|
109
117
|
bind:this={overlayElement}
|
|
110
118
|
class={mergedOverlayClass}
|
|
119
|
+
style={surfaceWidthStyle}
|
|
120
|
+
data-surface-width={surfaceWidth === undefined ? undefined : "custom"}
|
|
121
|
+
data-tone={tone}
|
|
122
|
+
data-divider={divider}
|
|
111
123
|
onclick={handleScrimClick}
|
|
112
124
|
onkeydown={handleKeyDown}
|
|
113
125
|
role="presentation"
|
|
@@ -3,4 +3,4 @@ export { default as DialogModal } from "./DialogModal.svelte";
|
|
|
3
3
|
export { default as ConfirmDialog } from "./ConfirmDialog.svelte";
|
|
4
4
|
export { default as DestructiveDialog } from "./DestructiveDialog.svelte";
|
|
5
5
|
export { default as InfoDialog } from "./InfoDialog.svelte";
|
|
6
|
-
export type { ConfirmDialogProps, DestructiveDialogProps, DialogModalProps, DialogProps, InfoDialogProps, } from "./types.js";
|
|
6
|
+
export type { ConfirmDialogProps, DestructiveDialogProps, DialogFooterControls, DialogModalProps, DialogProps, InfoDialogProps, } from "./types.js";
|
|
@@ -12,14 +12,18 @@ export interface DialogProps extends DialogOptions {
|
|
|
12
12
|
class?: string;
|
|
13
13
|
dataAttributes?: Record<string, string>;
|
|
14
14
|
}
|
|
15
|
+
export interface DialogFooterControls {
|
|
16
|
+
close: () => void;
|
|
17
|
+
}
|
|
15
18
|
export interface DialogModalProps extends Omit<DialogProps, "footer" | "onclose"> {
|
|
16
19
|
open?: boolean;
|
|
17
20
|
closeOnEscape?: boolean;
|
|
18
21
|
closeOnScrimClick?: boolean;
|
|
19
22
|
restoreFocus?: boolean;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
surfaceWidth?: string | number;
|
|
24
|
+
tone?: "default" | "calm";
|
|
25
|
+
divider?: "visible" | "hidden";
|
|
26
|
+
footer?: Snippet<[DialogFooterControls]>;
|
|
23
27
|
onopenchange?: (open: boolean) => void;
|
|
24
28
|
class?: string;
|
|
25
29
|
overlayClass?: string;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { IconName, createDrawerRecipe } from "@marwes-ui/core";
|
|
3
|
+
import type { DrawerOptions } from "@marwes-ui/core";
|
|
4
|
+
import { mergeClass } from "../../internal/merge-class.js";
|
|
5
|
+
import Icon from "../icon/Icon.svelte";
|
|
6
|
+
import type { DrawerProps } from "./types.js";
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
id: userProvidedId,
|
|
10
|
+
title,
|
|
11
|
+
description,
|
|
12
|
+
children,
|
|
13
|
+
footer,
|
|
14
|
+
onclose,
|
|
15
|
+
class: className,
|
|
16
|
+
panelClass,
|
|
17
|
+
dataAttributes,
|
|
18
|
+
size,
|
|
19
|
+
placement,
|
|
20
|
+
showFooter,
|
|
21
|
+
dismissible,
|
|
22
|
+
modal,
|
|
23
|
+
showScrim,
|
|
24
|
+
ariaLabel,
|
|
25
|
+
ariaLabelledBy,
|
|
26
|
+
ariaDescribedBy,
|
|
27
|
+
}: DrawerProps = $props();
|
|
28
|
+
|
|
29
|
+
const uniqueId = $props.id();
|
|
30
|
+
const drawerId = $derived(userProvidedId ?? `mw-drawer-${uniqueId}`);
|
|
31
|
+
const titleId = $derived(`${drawerId}-title`);
|
|
32
|
+
const descriptionId = $derived(`${drawerId}-description`);
|
|
33
|
+
|
|
34
|
+
const hasTitle = $derived(title !== undefined && title.trim().length > 0);
|
|
35
|
+
const hasDescription = $derived(description !== undefined && description.trim().length > 0);
|
|
36
|
+
const hasFooter = $derived((showFooter ?? true) && footer !== undefined);
|
|
37
|
+
const isDismissible = $derived((dismissible ?? true) && onclose !== undefined);
|
|
38
|
+
|
|
39
|
+
const drawerOptions = $derived.by((): DrawerOptions => {
|
|
40
|
+
const opts: DrawerOptions = {
|
|
41
|
+
showFooter: hasFooter,
|
|
42
|
+
dismissible: isDismissible,
|
|
43
|
+
};
|
|
44
|
+
if (modal !== undefined) opts.modal = modal;
|
|
45
|
+
if (showScrim !== undefined) opts.showScrim = showScrim;
|
|
46
|
+
if (dataAttributes !== undefined) opts.dataAttributes = dataAttributes;
|
|
47
|
+
if (size !== undefined) opts.size = size;
|
|
48
|
+
if (placement !== undefined) opts.placement = placement;
|
|
49
|
+
if (ariaLabel !== undefined) opts.ariaLabel = ariaLabel;
|
|
50
|
+
if (ariaLabelledBy !== undefined) {
|
|
51
|
+
opts.ariaLabelledBy = ariaLabelledBy;
|
|
52
|
+
} else if (ariaLabel === undefined && hasTitle) {
|
|
53
|
+
opts.ariaLabelledBy = titleId;
|
|
54
|
+
}
|
|
55
|
+
if (ariaDescribedBy !== undefined) {
|
|
56
|
+
opts.ariaDescribedBy = ariaDescribedBy;
|
|
57
|
+
} else if (hasDescription) {
|
|
58
|
+
opts.ariaDescribedBy = descriptionId;
|
|
59
|
+
}
|
|
60
|
+
return opts;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const kit = $derived(createDrawerRecipe(drawerOptions));
|
|
64
|
+
const mergedClass = $derived(mergeClass(kit.className, className));
|
|
65
|
+
const mergedPanelClass = $derived(mergeClass(kit.panel.className, panelClass));
|
|
66
|
+
|
|
67
|
+
function handleClose(): void {
|
|
68
|
+
onclose?.();
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<div class={mergedClass} {...kit.dataAttributes}>
|
|
73
|
+
{#if kit.showScrim}
|
|
74
|
+
<div
|
|
75
|
+
class={kit.scrim.className}
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
onclick={isDismissible ? handleClose : undefined}
|
|
78
|
+
{...kit.scrim.dataAttributes}
|
|
79
|
+
></div>
|
|
80
|
+
{/if}
|
|
81
|
+
|
|
82
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
83
|
+
<div
|
|
84
|
+
id={drawerId}
|
|
85
|
+
class={mergedPanelClass}
|
|
86
|
+
role={kit.panel.a11y.role}
|
|
87
|
+
aria-modal={kit.panel.a11y.ariaModal ? "true" : undefined}
|
|
88
|
+
aria-label={kit.panel.a11y.ariaLabel}
|
|
89
|
+
aria-labelledby={kit.panel.a11y.ariaLabelledBy}
|
|
90
|
+
aria-describedby={kit.panel.a11y.ariaDescribedBy}
|
|
91
|
+
tabindex={-1}
|
|
92
|
+
{...kit.panel.dataAttributes}
|
|
93
|
+
>
|
|
94
|
+
{#if hasTitle || kit.showCloseButton}
|
|
95
|
+
<div class="mw-drawer__header">
|
|
96
|
+
{#if hasTitle}
|
|
97
|
+
<div class="mw-drawer__heading-group">
|
|
98
|
+
<h2 class="mw-drawer__title" id={titleId}>{title}</h2>
|
|
99
|
+
</div>
|
|
100
|
+
{:else}
|
|
101
|
+
<span class="mw-drawer__spacer" aria-hidden="true"></span>
|
|
102
|
+
{/if}
|
|
103
|
+
|
|
104
|
+
{#if kit.showCloseButton && onclose}
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
class="mw-drawer__close"
|
|
108
|
+
aria-label="Close drawer"
|
|
109
|
+
onclick={handleClose}
|
|
110
|
+
>
|
|
111
|
+
<Icon name={IconName.X} decorative />
|
|
112
|
+
</button>
|
|
113
|
+
{/if}
|
|
114
|
+
</div>
|
|
115
|
+
<div class="mw-drawer__header-divider" aria-hidden="true"></div>
|
|
116
|
+
{/if}
|
|
117
|
+
|
|
118
|
+
<div class="mw-drawer__content">
|
|
119
|
+
{#if hasDescription}
|
|
120
|
+
<p class="mw-drawer__description" id={descriptionId}>{description}</p>
|
|
121
|
+
{/if}
|
|
122
|
+
{@render children?.()}
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
{#if hasFooter}
|
|
126
|
+
<div class="mw-drawer__footer-divider" aria-hidden="true"></div>
|
|
127
|
+
<div class="mw-drawer__footer">
|
|
128
|
+
{@render footer?.({ close: handleClose })}
|
|
129
|
+
</div>
|
|
130
|
+
{/if}
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Drawer } from "./Drawer.svelte";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DrawerOptions, DrawerPlacement, DrawerSize } from "@marwes-ui/core";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
export interface DrawerProps extends DrawerOptions {
|
|
4
|
+
id?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
footer?: Snippet<[{
|
|
9
|
+
close: () => void;
|
|
10
|
+
}]>;
|
|
11
|
+
onclose?: () => void;
|
|
12
|
+
class?: string;
|
|
13
|
+
panelClass?: string;
|
|
14
|
+
dataAttributes?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
export type { DrawerPlacement, DrawerSize };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
H1 (Heading Level 1) — semantic top-level heading rendered as `<h1>`.
|
|
3
|
+
|
|
4
|
+
@remarks
|
|
5
|
+
Marwes officially styles H1-H3 only. For semantic H4-H6 (deep section
|
|
6
|
+
nesting, accessibility outlines), render
|
|
7
|
+
`<Text headingLevel={4} variant="..." />` — it produces the correct
|
|
8
|
+
heading tag while letting the consumer pick the visual variant.
|
|
9
|
+
Type your wrappers against `SemanticHeadingLevel` from `@marwes-ui/core`.
|
|
10
|
+
-->
|
|
1
11
|
<script lang="ts">
|
|
2
12
|
import { headingRecipe } from "@marwes-ui/core";
|
|
3
13
|
import { cssVarsToStyle, mergeStyle } from "../../internal/css-vars.js";
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
H2 (Heading Level 2) — semantic section heading rendered as `<h2>`.
|
|
3
|
+
|
|
4
|
+
@remarks
|
|
5
|
+
For semantic H4-H6, use `<Text headingLevel={4..6} variant="..." />`.
|
|
6
|
+
-->
|
|
1
7
|
<script lang="ts">
|
|
2
8
|
import { headingRecipe } from "@marwes-ui/core";
|
|
3
9
|
import { cssVarsToStyle, mergeStyle } from "../../internal/css-vars.js";
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
H3 (Heading Level 3) — semantic subsection heading rendered as `<h3>`.
|
|
3
|
+
|
|
4
|
+
@remarks
|
|
5
|
+
H3 is the deepest blessed rung. For H4-H6, use
|
|
6
|
+
`<Text headingLevel={4..6} variant="..." />`.
|
|
7
|
+
-->
|
|
1
8
|
<script lang="ts">
|
|
2
9
|
import { headingRecipe } from "@marwes-ui/core";
|
|
3
10
|
import { cssVarsToStyle, mergeStyle } from "../../internal/css-vars.js";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
let { currency, input = {}, ...props }: Props = $props();
|
|
6
6
|
|
|
7
7
|
const symbols: Record<string, string> = { USD: "$", EUR: "€", GBP: "£", JPY: "¥", SEK: "kr", NOK: "kr", DKK: "kr", CHF: "CHF", BTC: "₿" };
|
|
8
|
-
const leadingSymbol = currency ? symbols[currency] : undefined;
|
|
8
|
+
const leadingSymbol = $derived(currency ? symbols[currency] : undefined);
|
|
9
9
|
</script>
|
|
10
10
|
<div data-purpose="currency" data-currency={currency}>
|
|
11
11
|
<InputField {...props} input={{ ...input, type: "text", inputMode: "decimal" }} {...(leadingSymbol ? { leadingSymbol } : {})} />
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { buildInputFieldA11yIds } from "@marwes-ui/core";
|
|
3
3
|
import { mergeClass } from "../../internal/merge-class.js";
|
|
4
4
|
import Icon from "../icon/Icon.svelte";
|
|
5
|
+
import Text from "../text/Text.svelte";
|
|
5
6
|
import Input from "./Input.svelte";
|
|
6
7
|
import type { InputFieldProps } from "./types.js";
|
|
7
8
|
|
|
@@ -76,7 +77,7 @@
|
|
|
76
77
|
|
|
77
78
|
<div class={wrapperClass}>
|
|
78
79
|
<label class="mw-input-field__label" for={fieldId}>
|
|
79
|
-
<
|
|
80
|
+
<Text variant="label">{label}</Text>
|
|
80
81
|
</label>
|
|
81
82
|
|
|
82
83
|
<div class="mw-input-field__input-wrapper">
|
|
@@ -127,13 +128,13 @@
|
|
|
127
128
|
|
|
128
129
|
{#if hasHelperText && !hasError}
|
|
129
130
|
<div class="mw-input-field__helper" id={a11yIds.helperTextId}>
|
|
130
|
-
<
|
|
131
|
+
<Text variant="caption">{helperText}</Text>
|
|
131
132
|
</div>
|
|
132
133
|
{/if}
|
|
133
134
|
|
|
134
135
|
{#if hasError}
|
|
135
136
|
<div class="mw-input-field__error" id={a11yIds.errorId} aria-live="polite">
|
|
136
|
-
<
|
|
137
|
+
<Text variant="caption">{error}</Text>
|
|
137
138
|
</div>
|
|
138
139
|
{/if}
|
|
139
140
|
</div>
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
buildInputFieldA11yIds,
|
|
4
|
-
createInputOtpRecipe,
|
|
5
|
-
sanitizeInputOtpValue,
|
|
6
|
-
} from "@marwes-ui/core";
|
|
2
|
+
import { createInputOtpRecipe, sanitizeInputOtpValue } from "@marwes-ui/core";
|
|
7
3
|
import type { InputOtpOptions } from "@marwes-ui/core";
|
|
8
4
|
import { cssVarsToStyle } from "../../internal/css-vars.js";
|
|
9
5
|
import { mergeClass } from "../../internal/merge-class.js";
|
|
10
6
|
import type { InputOtpProps } from "./types.js";
|
|
11
7
|
|
|
8
|
+
/**
|
|
9
|
+
* InputOtp (Atom) — bare OTP cells. Renders the visual cells and a hidden
|
|
10
|
+
* native `<input>` that captures keyboard entry. Pair with `InputOtpField`
|
|
11
|
+
* for label + helper/error wiring.
|
|
12
|
+
*/
|
|
12
13
|
let {
|
|
13
14
|
id: userProvidedId,
|
|
14
15
|
name,
|
|
15
|
-
label,
|
|
16
|
-
helperText,
|
|
17
|
-
error,
|
|
18
|
-
ariaDescribedBy,
|
|
19
16
|
value: controlledValue,
|
|
20
17
|
defaultValue,
|
|
21
18
|
length: lengthProp,
|
|
@@ -23,8 +20,11 @@
|
|
|
23
20
|
disabled,
|
|
24
21
|
readOnly,
|
|
25
22
|
required,
|
|
26
|
-
invalid
|
|
23
|
+
invalid,
|
|
27
24
|
ariaLabel,
|
|
25
|
+
label,
|
|
26
|
+
ariaLabelledBy,
|
|
27
|
+
describedBy,
|
|
28
28
|
onvaluechange,
|
|
29
29
|
class: className,
|
|
30
30
|
}: InputOtpProps = $props();
|
|
@@ -33,44 +33,34 @@
|
|
|
33
33
|
const fieldId = $derived(userProvidedId ?? `mw-input-otp-${uniqueId}`);
|
|
34
34
|
const otpLength = $derived(Math.max(1, lengthProp ?? 6));
|
|
35
35
|
|
|
36
|
-
function hasTextContent(text: string | undefined): boolean {
|
|
37
|
-
return text !== undefined && text.trim().length > 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const hasHelperText = $derived(hasTextContent(helperText));
|
|
41
|
-
const hasError = $derived(hasTextContent(error));
|
|
42
|
-
const isInvalid = $derived(hasError || invalidProp === true);
|
|
43
36
|
const isControlled = $derived(controlledValue !== undefined);
|
|
44
37
|
|
|
45
|
-
|
|
38
|
+
function getInitialUncontrolledValue(): string {
|
|
39
|
+
return sanitizeInputOtpValue(defaultValue, lengthProp ?? 6);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let uncontrolledValue = $state(getInitialUncontrolledValue());
|
|
46
43
|
|
|
47
44
|
const currentValue = $derived(
|
|
48
45
|
sanitizeInputOtpValue(isControlled ? controlledValue : uncontrolledValue, otpLength)
|
|
49
46
|
);
|
|
50
47
|
|
|
51
|
-
const a11yIds = $derived(
|
|
52
|
-
buildInputFieldA11yIds({
|
|
53
|
-
id: fieldId,
|
|
54
|
-
hasHelperText,
|
|
55
|
-
hasError,
|
|
56
|
-
externalDescribedBy: ariaDescribedBy,
|
|
57
|
-
})
|
|
58
|
-
);
|
|
59
|
-
|
|
60
48
|
const recipeOptions = $derived.by((): InputOtpOptions => {
|
|
61
49
|
const opts: InputOtpOptions = {
|
|
62
50
|
id: fieldId,
|
|
63
51
|
value: currentValue,
|
|
64
52
|
length: otpLength,
|
|
65
|
-
invalid: isInvalid,
|
|
66
53
|
};
|
|
67
54
|
if (name) opts.name = name;
|
|
68
55
|
if (placeholderCharacter) opts.placeholderCharacter = placeholderCharacter;
|
|
69
56
|
if (disabled) opts.disabled = true;
|
|
70
57
|
if (readOnly) opts.readOnly = true;
|
|
71
58
|
if (required) opts.required = true;
|
|
72
|
-
if (
|
|
59
|
+
if (invalid) opts.invalid = true;
|
|
60
|
+
if (describedBy) opts.describedBy = describedBy;
|
|
73
61
|
if (ariaLabel) opts.ariaLabel = ariaLabel;
|
|
62
|
+
if (label) opts.label = label;
|
|
63
|
+
if (ariaLabelledBy) opts.ariaLabelledBy = ariaLabelledBy;
|
|
74
64
|
return opts;
|
|
75
65
|
});
|
|
76
66
|
|
|
@@ -91,13 +81,9 @@
|
|
|
91
81
|
class={mergedClass}
|
|
92
82
|
style={mergedStyle}
|
|
93
83
|
data-component="input-otp"
|
|
94
|
-
data-invalid={
|
|
84
|
+
data-invalid={invalid ? "true" : undefined}
|
|
95
85
|
data-disabled={disabled ? "true" : undefined}
|
|
96
86
|
>
|
|
97
|
-
<label class="mw-input-otp__label" for={fieldId}>
|
|
98
|
-
<p class="mw-p mw-p--md">{label}</p>
|
|
99
|
-
</label>
|
|
100
|
-
|
|
101
87
|
<div class="mw-input-otp__cells">
|
|
102
88
|
{#each kit.displayCells as cell (cell.key)}
|
|
103
89
|
<span
|
|
@@ -121,20 +107,11 @@
|
|
|
121
107
|
readonly={kit.a11y.readOnly}
|
|
122
108
|
required={kit.a11y.required}
|
|
123
109
|
aria-label={kit.a11y.ariaLabel}
|
|
110
|
+
aria-labelledby={kit.a11y.ariaLabelledBy}
|
|
124
111
|
aria-invalid={kit.a11y.ariaInvalid}
|
|
125
112
|
aria-describedby={kit.a11y.ariaDescribedBy}
|
|
126
113
|
value={kit.displayValue}
|
|
127
114
|
oninput={handleChange}
|
|
128
115
|
/>
|
|
129
116
|
</div>
|
|
130
|
-
|
|
131
|
-
{#if hasError}
|
|
132
|
-
<div class="mw-input-otp__error" id={a11yIds.errorId} aria-live="polite">
|
|
133
|
-
<p class="mw-p mw-p--sm">{error}</p>
|
|
134
|
-
</div>
|
|
135
|
-
{:else if hasHelperText}
|
|
136
|
-
<div class="mw-input-otp__helper" id={a11yIds.helperTextId}>
|
|
137
|
-
<p class="mw-p mw-p--sm">{helperText}</p>
|
|
138
|
-
</div>
|
|
139
|
-
{/if}
|
|
140
117
|
</div>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { buildInputFieldA11yIds } from "@marwes-ui/core";
|
|
3
|
+
import { mergeClass } from "../../internal/merge-class.js";
|
|
4
|
+
import Text from "../text/Text.svelte";
|
|
5
|
+
import InputOtp from "./InputOtp.svelte";
|
|
6
|
+
import type { InputOtpFieldProps, InputOtpProps } from "./types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* InputOtpField (Molecule) — labeled wrapper around `InputOtp`.
|
|
10
|
+
*/
|
|
11
|
+
let {
|
|
12
|
+
id: userProvidedId,
|
|
13
|
+
label,
|
|
14
|
+
helperText,
|
|
15
|
+
error,
|
|
16
|
+
inputOtp = {},
|
|
17
|
+
ariaDescribedBy,
|
|
18
|
+
class: className,
|
|
19
|
+
}: InputOtpFieldProps = $props();
|
|
20
|
+
|
|
21
|
+
const uniqueId = $props.id();
|
|
22
|
+
const fieldId = $derived(userProvidedId ?? `mw-input-otp-${uniqueId}`);
|
|
23
|
+
const labelId = $derived(`${fieldId}-label`);
|
|
24
|
+
|
|
25
|
+
function hasTextContent(text: string | undefined): boolean {
|
|
26
|
+
return text !== undefined && text.trim().length > 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const hasHelperText = $derived(hasTextContent(helperText));
|
|
30
|
+
const hasError = $derived(hasTextContent(error));
|
|
31
|
+
const isInvalid = $derived(hasError || inputOtp.invalid === true);
|
|
32
|
+
|
|
33
|
+
const a11yIds = $derived(
|
|
34
|
+
buildInputFieldA11yIds({
|
|
35
|
+
id: fieldId,
|
|
36
|
+
hasHelperText,
|
|
37
|
+
hasError,
|
|
38
|
+
externalDescribedBy: ariaDescribedBy,
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const wrapperClass = $derived(
|
|
43
|
+
mergeClass(
|
|
44
|
+
"mw-input-otp-field",
|
|
45
|
+
hasError && "mw-input-otp-field--invalid",
|
|
46
|
+
inputOtp.disabled && "mw-input-otp-field--disabled",
|
|
47
|
+
className
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const otpProps = $derived.by((): InputOtpProps => {
|
|
52
|
+
const props: InputOtpProps = {
|
|
53
|
+
...inputOtp,
|
|
54
|
+
id: fieldId,
|
|
55
|
+
invalid: isInvalid,
|
|
56
|
+
ariaLabelledBy: labelId,
|
|
57
|
+
};
|
|
58
|
+
if (a11yIds.describedBy) {
|
|
59
|
+
props.describedBy = a11yIds.describedBy;
|
|
60
|
+
}
|
|
61
|
+
return props;
|
|
62
|
+
});
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div class={wrapperClass}>
|
|
66
|
+
<label class="mw-input-otp-field__label" for={fieldId} id={labelId}>
|
|
67
|
+
<Text variant="label">{label}</Text>
|
|
68
|
+
</label>
|
|
69
|
+
|
|
70
|
+
<InputOtp {...otpProps} />
|
|
71
|
+
|
|
72
|
+
{#if hasError}
|
|
73
|
+
<div class="mw-input-otp-field__error" id={a11yIds.errorId} aria-live="polite">
|
|
74
|
+
<Text variant="caption">{error}</Text>
|
|
75
|
+
</div>
|
|
76
|
+
{:else if hasHelperText}
|
|
77
|
+
<div class="mw-input-otp-field__helper" id={a11yIds.helperTextId}>
|
|
78
|
+
<Text variant="caption">{helperText}</Text>
|
|
79
|
+
</div>
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
|
@@ -32,11 +32,15 @@
|
|
|
32
32
|
const showToolbar = $derived(!options.readOnly);
|
|
33
33
|
|
|
34
34
|
let editorElement: HTMLDivElement | undefined = $state(undefined);
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
function getInitialUncontrolledHtml(): string {
|
|
36
|
+
return normalizeRichTextHtml(defaultValue);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let uncontrolledHtml = $state(getInitialUncontrolledHtml());
|
|
37
40
|
let activeFormats = $state<RichTextFormat[]>([]);
|
|
38
41
|
|
|
39
42
|
const editorHtml = $derived(isControlled ? normalizeRichTextHtml(controlledValue) : uncontrolledHtml);
|
|
43
|
+
const isEditorEmpty = $derived(isRichTextHtmlEmpty(editorHtml));
|
|
40
44
|
|
|
41
45
|
const formatLabels: Record<RichTextFormat, string> = {
|
|
42
46
|
bold: "Bold",
|
|
@@ -46,9 +50,7 @@
|
|
|
46
50
|
|
|
47
51
|
function syncEditorState(nextHtml: string): string {
|
|
48
52
|
const normalized = normalizeRichTextHtml(nextHtml);
|
|
49
|
-
const empty = isRichTextHtmlEmpty(normalized);
|
|
50
53
|
if (!isControlled) uncontrolledHtml = normalized;
|
|
51
|
-
isEditorEmpty = empty;
|
|
52
54
|
onvaluechange?.(normalized);
|
|
53
55
|
return normalized;
|
|
54
56
|
}
|
|
@@ -113,7 +115,6 @@
|
|
|
113
115
|
if (!editorElement) return;
|
|
114
116
|
const normalizedDom = normalizeRichTextHtml(editorElement.innerHTML);
|
|
115
117
|
if (normalizedDom !== editorHtml) editorElement.innerHTML = editorHtml;
|
|
116
|
-
isEditorEmpty = isRichTextHtmlEmpty(editorHtml);
|
|
117
118
|
});
|
|
118
119
|
|
|
119
120
|
$effect(() => {
|
|
@@ -154,7 +155,7 @@
|
|
|
154
155
|
data-empty={isEditorEmpty ? "true" : undefined}
|
|
155
156
|
data-placeholder={options.placeholder}
|
|
156
157
|
id={kit.a11y.id}
|
|
157
|
-
role=
|
|
158
|
+
role="textbox"
|
|
158
159
|
tabindex={kit.a11y.tabIndex}
|
|
159
160
|
aria-label={kit.a11y.ariaLabel}
|
|
160
161
|
aria-labelledby={kit.a11y.ariaLabelledBy}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { buildRichTextFieldA11yIds } from "@marwes-ui/core";
|
|
3
3
|
import type { RichTextOptions } from "@marwes-ui/core";
|
|
4
4
|
import { mergeClass } from "../../internal/merge-class.js";
|
|
5
|
+
import Text from "../text/Text.svelte";
|
|
5
6
|
import RichText from "./RichText.svelte";
|
|
6
7
|
import type { RichTextFieldProps } from "./types.js";
|
|
7
8
|
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
el?.focus();
|
|
58
59
|
}}
|
|
59
60
|
>
|
|
60
|
-
<
|
|
61
|
+
<Text variant="label">{label}</Text>
|
|
61
62
|
</button>
|
|
62
63
|
|
|
63
64
|
<div class="mw-input-field__input-wrapper">
|
|
@@ -72,13 +73,13 @@
|
|
|
72
73
|
|
|
73
74
|
{#if hasHelperText && !hasError}
|
|
74
75
|
<div class="mw-input-field__helper" id={a11yIds.helperTextId}>
|
|
75
|
-
<
|
|
76
|
+
<Text variant="caption">{helperText}</Text>
|
|
76
77
|
</div>
|
|
77
78
|
{/if}
|
|
78
79
|
|
|
79
80
|
{#if hasError}
|
|
80
81
|
<div class="mw-input-field__error" id={a11yIds.errorId} aria-live="polite">
|
|
81
|
-
<
|
|
82
|
+
<Text variant="caption">{error}</Text>
|
|
82
83
|
</div>
|
|
83
84
|
{/if}
|
|
84
85
|
</div>
|