@getmicdrop/svelte-components 5.12.0 → 5.13.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/index.spec.js +0 -1
- package/dist/patterns/navigation/Header.svelte +23 -27
- package/dist/patterns/navigation/Header.svelte.d.ts.map +1 -1
- package/dist/primitives/AvatarButton/AvatarButton.svelte +57 -0
- package/dist/primitives/AvatarButton/AvatarButton.svelte.d.ts +18 -0
- package/dist/primitives/AvatarButton/AvatarButton.svelte.d.ts.map +1 -0
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +19 -19
- package/dist/primitives/BottomSheet/BottomSheet.svelte +5 -5
- package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts +2 -2
- package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts.map +1 -1
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte +3 -3
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts +1 -1
- package/dist/primitives/Button/Button.spec.js +8 -8
- package/dist/primitives/Button/Button.svelte +9 -45
- package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
- package/dist/primitives/CardAction/CardAction.svelte +68 -0
- package/dist/primitives/CardAction/CardAction.svelte.d.ts +20 -0
- package/dist/primitives/CardAction/CardAction.svelte.d.ts.map +1 -0
- package/dist/primitives/Drawer/Drawer.spec.js +33 -33
- package/dist/primitives/Drawer/Drawer.svelte +5 -9
- package/dist/primitives/Drawer/Drawer.svelte.d.ts +2 -3
- package/dist/primitives/Drawer/Drawer.svelte.d.ts.map +1 -1
- package/dist/primitives/LandingButton/LandingButton.svelte +92 -0
- package/dist/primitives/LandingButton/LandingButton.svelte.d.ts +22 -0
- package/dist/primitives/LandingButton/LandingButton.svelte.d.ts.map +1 -0
- package/dist/primitives/MenuItem/MenuItem.svelte +85 -0
- package/dist/primitives/MenuItem/MenuItem.svelte.d.ts +24 -0
- package/dist/primitives/MenuItem/MenuItem.svelte.d.ts.map +1 -0
- package/dist/primitives/Modal/Modal.spec.js +7 -7
- package/dist/primitives/Modal/Modal.stories.svelte +3 -3
- package/dist/primitives/Modal/Modal.svelte +25 -18
- package/dist/primitives/Modal/Modal.svelte.d.ts +5 -5
- package/dist/primitives/Modal/Modal.svelte.d.ts.map +1 -1
- package/dist/primitives/Modal/ModalTestWrapper.svelte +3 -3
- package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts +2 -2
- package/dist/primitives/NavItem/NavItem.svelte +75 -0
- package/dist/primitives/NavItem/NavItem.svelte.d.ts +20 -0
- package/dist/primitives/NavItem/NavItem.svelte.d.ts.map +1 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.svelte +109 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.svelte.d.ts +26 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.svelte.d.ts.map +1 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.svelte +55 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.svelte.d.ts +18 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.svelte.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +7 -0
- package/dist/primitives/index.js +21 -0
- package/dist/recipes/SuperLogin/SuperLogin.svelte +3 -3
- package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/index.d.ts +0 -1
- package/dist/recipes/inputs/index.js +0 -1
- package/dist/recipes/modals/AlertModal.spec.js +2 -2
- package/dist/recipes/modals/AlertModal.svelte +6 -6
- package/dist/recipes/modals/AlertModal.svelte.d.ts +3 -3
- package/dist/recipes/modals/ConfirmationModal.spec.js +2 -2
- package/dist/recipes/modals/ConfirmationModal.svelte +5 -5
- package/dist/recipes/modals/ConfirmationModal.svelte.d.ts +3 -3
- package/dist/recipes/modals/InputModal.spec.js +2 -2
- package/dist/recipes/modals/InputModal.svelte +4 -4
- package/dist/recipes/modals/InputModal.svelte.d.ts +3 -3
- package/dist/recipes/modals/ModalTestWrapper.spec.js +49 -49
- package/dist/recipes/modals/ModalTestWrapper.svelte +3 -3
- package/dist/recipes/modals/ModalTestWrapper.svelte.d.ts +2 -2
- package/dist/recipes/modals/StatusModal.spec.js +2 -2
- package/dist/recipes/modals/StatusModal.svelte +4 -4
- package/dist/recipes/modals/StatusModal.svelte.d.ts +3 -3
- package/dist/stories/ComponentConsolidation.stories.svelte +10 -10
- package/dist/stories/PrimitivesGallery.svelte +25 -21
- package/dist/stories/PrimitivesGallery.svelte.d.ts.map +1 -1
- package/dist/stories/RecipesGallery.spec.js +9 -18
- package/dist/stories/RecipesGallery.svelte +5 -22
- package/dist/stories/RecipesGallery.svelte.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts +0 -2
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts.map +0 -1
- package/dist/recipes/inputs/SelectDropdown.spec.js +0 -518
- package/dist/recipes/inputs/SelectDropdown.svelte +0 -171
- package/dist/recipes/inputs/SelectDropdown.svelte.d.ts +0 -16
- package/dist/recipes/inputs/SelectDropdown.svelte.d.ts.map +0 -1
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
import { triggerHaptic } from "../../utils/haptic.js";
|
|
14
14
|
|
|
15
15
|
/** @type {{
|
|
16
|
-
|
|
16
|
+
open?: boolean,
|
|
17
17
|
isProcessing?: boolean,
|
|
18
18
|
isSuccess?: boolean,
|
|
19
|
-
size?: '
|
|
19
|
+
size?: 'sm' | 'md' | 'lg' | 'xl',
|
|
20
20
|
persistent?: boolean,
|
|
21
21
|
haptic?: boolean,
|
|
22
22
|
oncancel?: () => void,
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
class?: string,
|
|
27
27
|
}} */
|
|
28
28
|
let {
|
|
29
|
-
|
|
29
|
+
open = $bindable(false),
|
|
30
30
|
isProcessing = false,
|
|
31
31
|
isSuccess = false,
|
|
32
|
-
size = "
|
|
32
|
+
size = "md",
|
|
33
33
|
persistent = false,
|
|
34
34
|
haptic = true,
|
|
35
35
|
oncancel,
|
|
@@ -43,55 +43,61 @@
|
|
|
43
43
|
// Store scroll position for iOS scroll lock
|
|
44
44
|
let scrollY = $state(0);
|
|
45
45
|
|
|
46
|
-
// Track previous
|
|
47
|
-
let
|
|
46
|
+
// Track previous open state to detect open transitions
|
|
47
|
+
let prevOpen = $state(false);
|
|
48
48
|
|
|
49
49
|
// Trigger haptic on modal open (QOL Bible)
|
|
50
50
|
$effect(() => {
|
|
51
|
-
if (
|
|
51
|
+
if (open && !prevOpen && haptic) {
|
|
52
52
|
triggerHaptic('light');
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
prevOpen = open;
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
// Handle escape key
|
|
58
58
|
function handleKeydown(event) {
|
|
59
|
-
if (event.key === "Escape" &&
|
|
59
|
+
if (event.key === "Escape" && open && !persistent) {
|
|
60
60
|
resetModal();
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const resetModal = () => {
|
|
65
65
|
oncancel?.();
|
|
66
|
-
|
|
66
|
+
open = false;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
// Size classes for desktop modal (
|
|
69
|
+
// Size classes for desktop modal (xs/sm/md/lg/xl scale)
|
|
70
70
|
const sizeClasses = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
sm: "max-w-sm",
|
|
72
|
+
md: "max-w-md",
|
|
73
|
+
lg: "max-w-xl",
|
|
74
|
+
xl: "max-w-2xl"
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
let modalSizeClass = $derived(sizeClasses[size] || sizeClasses.
|
|
77
|
+
let modalSizeClass = $derived(sizeClasses[size] || sizeClasses.md);
|
|
78
78
|
|
|
79
79
|
// iOS-compatible scroll lock using position:fixed approach
|
|
80
|
+
// Also compensates for scrollbar width to prevent layout shift
|
|
80
81
|
$effect(() => {
|
|
81
82
|
if (typeof document !== "undefined") {
|
|
82
|
-
if (
|
|
83
|
+
if (open) {
|
|
83
84
|
scrollY = window.scrollY;
|
|
85
|
+
// Calculate scrollbar width before hiding it
|
|
86
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
84
87
|
document.body.style.position = "fixed";
|
|
85
88
|
document.body.style.top = `-${scrollY}px`;
|
|
86
89
|
document.body.style.left = "0";
|
|
87
90
|
document.body.style.right = "0";
|
|
88
91
|
document.body.style.overflow = "hidden";
|
|
92
|
+
// Add padding to compensate for scrollbar disappearing
|
|
93
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
89
94
|
} else {
|
|
90
95
|
document.body.style.position = "";
|
|
91
96
|
document.body.style.top = "";
|
|
92
97
|
document.body.style.left = "";
|
|
93
98
|
document.body.style.right = "";
|
|
94
99
|
document.body.style.overflow = "";
|
|
100
|
+
document.body.style.paddingRight = "";
|
|
95
101
|
window.scrollTo(0, scrollY);
|
|
96
102
|
}
|
|
97
103
|
}
|
|
@@ -104,13 +110,14 @@
|
|
|
104
110
|
document.body.style.left = "";
|
|
105
111
|
document.body.style.right = "";
|
|
106
112
|
document.body.style.overflow = "";
|
|
113
|
+
document.body.style.paddingRight = "";
|
|
107
114
|
}
|
|
108
115
|
});
|
|
109
116
|
</script>
|
|
110
117
|
|
|
111
118
|
<svelte:window onkeydown={handleKeydown} />
|
|
112
119
|
|
|
113
|
-
{#if
|
|
120
|
+
{#if open}
|
|
114
121
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
115
122
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
116
123
|
<div
|
|
@@ -2,10 +2,10 @@ export default Modal;
|
|
|
2
2
|
type Modal = {
|
|
3
3
|
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
4
|
$set?(props: Partial<{
|
|
5
|
-
|
|
5
|
+
open?: boolean | undefined;
|
|
6
6
|
isProcessing?: boolean | undefined;
|
|
7
7
|
isSuccess?: boolean | undefined;
|
|
8
|
-
size?: "
|
|
8
|
+
size?: "sm" | "md" | "lg" | "xl" | undefined;
|
|
9
9
|
persistent?: boolean | undefined;
|
|
10
10
|
haptic?: boolean | undefined;
|
|
11
11
|
oncancel?: (() => void) | undefined;
|
|
@@ -16,10 +16,10 @@ type Modal = {
|
|
|
16
16
|
}>): void;
|
|
17
17
|
};
|
|
18
18
|
declare const Modal: import("svelte").Component<{
|
|
19
|
-
|
|
19
|
+
open?: boolean;
|
|
20
20
|
isProcessing?: boolean;
|
|
21
21
|
isSuccess?: boolean;
|
|
22
|
-
size?: "
|
|
22
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
23
23
|
persistent?: boolean;
|
|
24
24
|
haptic?: boolean;
|
|
25
25
|
oncancel?: () => void;
|
|
@@ -27,5 +27,5 @@ declare const Modal: import("svelte").Component<{
|
|
|
27
27
|
body?: import("svelte").Snippet;
|
|
28
28
|
footer?: import("svelte").Snippet;
|
|
29
29
|
class?: string;
|
|
30
|
-
}, {}, "
|
|
30
|
+
}, {}, "open">;
|
|
31
31
|
//# sourceMappingURL=Modal.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Modal/Modal.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Modal/Modal.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA6LA;WAZW,OAAO;mBACC,OAAO;gBACV,OAAO;WACZ,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;iBACnB,OAAO;aACX,OAAO;eACL,MAAM,IAAI;aACZ,OAAO,QAAQ,EAAE,OAAO;WAC1B,OAAO,QAAQ,EAAE,OAAO;aACtB,OAAO,QAAQ,EAAE,OAAO;YACzB,MAAM;eAEkC"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
/** Whether the modal is visible */
|
|
8
|
-
|
|
8
|
+
open?: boolean;
|
|
9
9
|
/** Modal title */
|
|
10
10
|
title?: string;
|
|
11
11
|
/** Modal description */
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
let {
|
|
26
|
-
|
|
26
|
+
open = $bindable(false),
|
|
27
27
|
title = '',
|
|
28
28
|
description = '',
|
|
29
29
|
warningText = '',
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
}: Props = $props();
|
|
35
35
|
</script>
|
|
36
36
|
|
|
37
|
-
<Modal bind:
|
|
37
|
+
<Modal bind:open {oncancel}>
|
|
38
38
|
{#snippet header()}
|
|
39
39
|
{#if customHeader}
|
|
40
40
|
{@render customHeader()}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
interface Props {
|
|
3
3
|
/** Whether the modal is visible */
|
|
4
|
-
|
|
4
|
+
open?: boolean;
|
|
5
5
|
/** Modal title */
|
|
6
6
|
title?: string;
|
|
7
7
|
/** Modal description */
|
|
@@ -17,7 +17,7 @@ interface Props {
|
|
|
17
17
|
/** Custom footer snippet */
|
|
18
18
|
customFooter?: Snippet;
|
|
19
19
|
}
|
|
20
|
-
declare const ModalTestWrapper: import("svelte").Component<Props, {}, "
|
|
20
|
+
declare const ModalTestWrapper: import("svelte").Component<Props, {}, "open">;
|
|
21
21
|
type ModalTestWrapper = ReturnType<typeof ModalTestWrapper>;
|
|
22
22
|
export default ModalTestWrapper;
|
|
23
23
|
//# sourceMappingURL=ModalTestWrapper.svelte.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* NavItem Component
|
|
4
|
+
* Bottom navigation item with vertical layout.
|
|
5
|
+
*
|
|
6
|
+
* Replaces: Button variant="nav"
|
|
7
|
+
*/
|
|
8
|
+
import { twMerge } from 'tailwind-merge';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Active/selected state */
|
|
13
|
+
active?: boolean;
|
|
14
|
+
/** Disabled state */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Link href (renders as <a> if provided) */
|
|
17
|
+
href?: string | null;
|
|
18
|
+
/** Content (icon + label) */
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
/** Additional classes */
|
|
21
|
+
class?: string;
|
|
22
|
+
/** Click handler */
|
|
23
|
+
onclick?: (e: MouseEvent) => void;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
active = false,
|
|
29
|
+
disabled = false,
|
|
30
|
+
href = null,
|
|
31
|
+
children,
|
|
32
|
+
class: className = '',
|
|
33
|
+
onclick,
|
|
34
|
+
...restProps
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
const baseClasses = 'flex flex-col items-center justify-center h-full py-2 bg-transparent border-transparent rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
|
|
38
|
+
const defaultClasses = 'text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-500';
|
|
39
|
+
const activeClasses = 'text-blue-600 dark:text-blue-500';
|
|
40
|
+
const disabledClasses = 'text-gray-400 cursor-not-allowed dark:text-gray-500';
|
|
41
|
+
|
|
42
|
+
let variantClass = $derived(() => {
|
|
43
|
+
if (disabled) return disabledClasses;
|
|
44
|
+
if (active) return activeClasses;
|
|
45
|
+
return defaultClasses;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let classes = $derived(twMerge(
|
|
49
|
+
baseClasses,
|
|
50
|
+
variantClass(),
|
|
51
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
52
|
+
className
|
|
53
|
+
));
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
{#if href}
|
|
57
|
+
<a
|
|
58
|
+
{href}
|
|
59
|
+
class={classes}
|
|
60
|
+
{onclick}
|
|
61
|
+
{...restProps}
|
|
62
|
+
>
|
|
63
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
64
|
+
</a>
|
|
65
|
+
{:else}
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
class={classes}
|
|
69
|
+
{disabled}
|
|
70
|
+
{onclick}
|
|
71
|
+
{...restProps}
|
|
72
|
+
>
|
|
73
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
74
|
+
</button>
|
|
75
|
+
{/if}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Active/selected state */
|
|
4
|
+
active?: boolean;
|
|
5
|
+
/** Disabled state */
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** Link href (renders as <a> if provided) */
|
|
8
|
+
href?: string | null;
|
|
9
|
+
/** Content (icon + label) */
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
/** Additional classes */
|
|
12
|
+
class?: string;
|
|
13
|
+
/** Click handler */
|
|
14
|
+
onclick?: (e: MouseEvent) => void;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
declare const NavItem: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type NavItem = ReturnType<typeof NavItem>;
|
|
19
|
+
export default NavItem;
|
|
20
|
+
//# sourceMappingURL=NavItem.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavItem.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/NavItem/NavItem.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,4BAA4B;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgDH,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SearchResultItem Component
|
|
4
|
+
* Search dropdown result item with blue hover.
|
|
5
|
+
*
|
|
6
|
+
* Two modes:
|
|
7
|
+
* - Simple (no type): Blue hover, no border - for basic dropdowns
|
|
8
|
+
* - Typed (with type): Colored left border by entity type - matches global search styling
|
|
9
|
+
*
|
|
10
|
+
* Replaces: Button variant="search-result"
|
|
11
|
+
*/
|
|
12
|
+
import { twMerge } from 'tailwind-merge';
|
|
13
|
+
import type { Snippet } from 'svelte';
|
|
14
|
+
import { buttonMenuItemSizes } from '../../tokens/sizing.js';
|
|
15
|
+
|
|
16
|
+
/** Entity type for colored border mode */
|
|
17
|
+
export type SearchResultType = 'event' | 'order' | 'performer' | 'venue' | 'collection' | 'series';
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
/** Size variant */
|
|
21
|
+
size?: 'sm' | 'md' | 'lg';
|
|
22
|
+
/** Entity type - when provided, shows colored left border instead of blue hover */
|
|
23
|
+
type?: SearchResultType;
|
|
24
|
+
/** Disabled state */
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/** Selected/highlighted state (alias: isActive) */
|
|
27
|
+
selected?: boolean;
|
|
28
|
+
/** Content */
|
|
29
|
+
children?: Snippet;
|
|
30
|
+
/** Trailing content (icons, badges) */
|
|
31
|
+
trailing?: Snippet;
|
|
32
|
+
/** Additional classes */
|
|
33
|
+
class?: string;
|
|
34
|
+
/** Click handler */
|
|
35
|
+
onclick?: (e: MouseEvent) => void;
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let {
|
|
40
|
+
size = 'md',
|
|
41
|
+
type,
|
|
42
|
+
disabled = false,
|
|
43
|
+
selected = false,
|
|
44
|
+
children,
|
|
45
|
+
trailing,
|
|
46
|
+
class: className = '',
|
|
47
|
+
onclick,
|
|
48
|
+
...restProps
|
|
49
|
+
}: Props = $props();
|
|
50
|
+
|
|
51
|
+
// Border colors by entity type - matches micdrop-frontend SearchResultItem
|
|
52
|
+
const borderColors: Record<SearchResultType, string> = {
|
|
53
|
+
event: 'border-l-blue-500',
|
|
54
|
+
order: 'border-l-yellow-500',
|
|
55
|
+
performer: 'border-l-pink-500',
|
|
56
|
+
venue: 'border-l-indigo-500',
|
|
57
|
+
collection: 'border-l-purple-500',
|
|
58
|
+
series: 'border-l-blue-500',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Simple mode (no type): rounded with blue hover
|
|
62
|
+
const simpleBaseClasses = 'w-full text-left rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
|
|
63
|
+
const simpleDefaultClasses = 'text-gray-900 bg-transparent border-transparent hover:bg-blue-50 focus:bg-blue-50 dark:text-white dark:hover:bg-blue-900/20 dark:focus:bg-blue-900/20';
|
|
64
|
+
const simpleSelectedClasses = 'text-gray-900 bg-blue-50 dark:text-white dark:bg-blue-900/20';
|
|
65
|
+
|
|
66
|
+
// Typed mode (with type): colored left border, gray hover
|
|
67
|
+
const typedBaseClasses = 'w-full text-left font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none border-l-3';
|
|
68
|
+
const typedDefaultClasses = 'text-gray-900 bg-transparent hover:bg-gray-50 hover:border-l-4 dark:text-white dark:hover:bg-gray-700';
|
|
69
|
+
const typedSelectedClasses = 'text-gray-900 bg-primary-100 border-l-primary-600 border-l-4 dark:text-white dark:bg-gray-700';
|
|
70
|
+
|
|
71
|
+
const disabledClasses = 'text-gray-400 cursor-not-allowed dark:text-gray-500';
|
|
72
|
+
|
|
73
|
+
let sizeClass = $derived(buttonMenuItemSizes[size] || buttonMenuItemSizes.md);
|
|
74
|
+
let hasTrailing = $derived(typeof trailing === 'function' || trailing);
|
|
75
|
+
let isTypedMode = $derived(!!type);
|
|
76
|
+
|
|
77
|
+
let variantClass = $derived(() => {
|
|
78
|
+
if (disabled) return disabledClasses;
|
|
79
|
+
if (isTypedMode) {
|
|
80
|
+
return selected ? typedSelectedClasses : typedDefaultClasses;
|
|
81
|
+
}
|
|
82
|
+
return selected ? simpleSelectedClasses : simpleDefaultClasses;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
let borderClass = $derived(isTypedMode && type ? borderColors[type] : '');
|
|
86
|
+
|
|
87
|
+
let classes = $derived(twMerge(
|
|
88
|
+
isTypedMode ? typedBaseClasses : simpleBaseClasses,
|
|
89
|
+
hasTrailing ? 'flex items-center justify-between' : 'flex items-center justify-start',
|
|
90
|
+
sizeClass,
|
|
91
|
+
borderClass,
|
|
92
|
+
variantClass(),
|
|
93
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer active:scale-[0.97] active:opacity-90',
|
|
94
|
+
className
|
|
95
|
+
));
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
class={classes}
|
|
101
|
+
{disabled}
|
|
102
|
+
{onclick}
|
|
103
|
+
{...restProps}
|
|
104
|
+
>
|
|
105
|
+
<span class="inline-flex items-center gap-1.5">
|
|
106
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
107
|
+
</span>
|
|
108
|
+
{#if typeof trailing === 'function'}{@render trailing()}{:else if trailing}{trailing}{/if}
|
|
109
|
+
</button>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
/** Entity type for colored border mode */
|
|
3
|
+
export type SearchResultType = 'event' | 'order' | 'performer' | 'venue' | 'collection' | 'series';
|
|
4
|
+
interface Props {
|
|
5
|
+
/** Size variant */
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
/** Entity type - when provided, shows colored left border instead of blue hover */
|
|
8
|
+
type?: SearchResultType;
|
|
9
|
+
/** Disabled state */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
/** Selected/highlighted state (alias: isActive) */
|
|
12
|
+
selected?: boolean;
|
|
13
|
+
/** Content */
|
|
14
|
+
children?: Snippet;
|
|
15
|
+
/** Trailing content (icons, badges) */
|
|
16
|
+
trailing?: Snippet;
|
|
17
|
+
/** Additional classes */
|
|
18
|
+
class?: string;
|
|
19
|
+
/** Click handler */
|
|
20
|
+
onclick?: (e: MouseEvent) => void;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
declare const SearchResultItem: import("svelte").Component<Props, {}, "">;
|
|
24
|
+
type SearchResultItem = ReturnType<typeof SearchResultItem>;
|
|
25
|
+
export default SearchResultItem;
|
|
26
|
+
//# sourceMappingURL=SearchResultItem.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchResultItem.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/SearchResultItem/SearchResultItem.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEnG,UAAU,KAAK;IACb,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,mFAAmF;IACnF,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA6EH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SidebarToggle Component
|
|
4
|
+
* Compact pill button for sidebar expand/collapse.
|
|
5
|
+
*
|
|
6
|
+
* Replaces: Button variant="sidebar-toggle"
|
|
7
|
+
*/
|
|
8
|
+
import { twMerge } from 'tailwind-merge';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Expanded state (affects icon direction if using chevron) */
|
|
13
|
+
expanded?: boolean;
|
|
14
|
+
/** Disabled state */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Content (typically a chevron icon) */
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
/** Additional classes */
|
|
19
|
+
class?: string;
|
|
20
|
+
/** Click handler */
|
|
21
|
+
onclick?: (e: MouseEvent) => void;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
expanded = false,
|
|
27
|
+
disabled = false,
|
|
28
|
+
children,
|
|
29
|
+
class: className = '',
|
|
30
|
+
onclick,
|
|
31
|
+
...restProps
|
|
32
|
+
}: Props = $props();
|
|
33
|
+
|
|
34
|
+
const baseClasses = 'w-6 h-7 inline-flex items-center justify-center rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
|
|
35
|
+
const defaultClasses = 'text-gray-900 bg-blue-100 border border-blue-200 hover:bg-blue-200 shadow-lg dark:text-white dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700';
|
|
36
|
+
const disabledClasses = 'bg-gray-200 border-gray-200 text-gray-400 cursor-not-allowed dark:bg-gray-700 dark:border-gray-700 dark:text-gray-500';
|
|
37
|
+
|
|
38
|
+
let classes = $derived(twMerge(
|
|
39
|
+
baseClasses,
|
|
40
|
+
disabled ? disabledClasses : defaultClasses,
|
|
41
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer active:scale-[0.95] active:opacity-90',
|
|
42
|
+
className
|
|
43
|
+
));
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<button
|
|
47
|
+
type="button"
|
|
48
|
+
class={classes}
|
|
49
|
+
{disabled}
|
|
50
|
+
aria-expanded={expanded}
|
|
51
|
+
{onclick}
|
|
52
|
+
{...restProps}
|
|
53
|
+
>
|
|
54
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
55
|
+
</button>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Expanded state (affects icon direction if using chevron) */
|
|
4
|
+
expanded?: boolean;
|
|
5
|
+
/** Disabled state */
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** Content (typically a chevron icon) */
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
/** Additional classes */
|
|
10
|
+
class?: string;
|
|
11
|
+
/** Click handler */
|
|
12
|
+
onclick?: (e: MouseEvent) => void;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
declare const SidebarToggle: import("svelte").Component<Props, {}, "">;
|
|
16
|
+
type SidebarToggle = ReturnType<typeof SidebarToggle>;
|
|
17
|
+
export default SidebarToggle;
|
|
18
|
+
//# sourceMappingURL=SidebarToggle.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarToggle.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/SidebarToggle/SidebarToggle.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAkCH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -33,4 +33,11 @@ export { default as Toggle } from "./Toggle.svelte";
|
|
|
33
33
|
export { default as Tooltip } from "./Tooltip/Tooltip.svelte";
|
|
34
34
|
export { default as Typography } from "./Typography/Typography.svelte";
|
|
35
35
|
export { default as ValidationError } from "./ValidationError.svelte";
|
|
36
|
+
export { default as MenuItem } from "./MenuItem/MenuItem.svelte";
|
|
37
|
+
export { default as AvatarButton } from "./AvatarButton/AvatarButton.svelte";
|
|
38
|
+
export { default as NavItem } from "./NavItem/NavItem.svelte";
|
|
39
|
+
export { default as CardAction } from "./CardAction/CardAction.svelte";
|
|
40
|
+
export { default as SearchResultItem } from "./SearchResultItem/SearchResultItem.svelte";
|
|
41
|
+
export { default as LandingButton } from "./LandingButton/LandingButton.svelte";
|
|
42
|
+
export { default as SidebarToggle } from "./SidebarToggle/SidebarToggle.svelte";
|
|
36
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/primitives/index.js
CHANGED
|
@@ -90,3 +90,24 @@ export { default as Typography } from './Typography/Typography.svelte';
|
|
|
90
90
|
|
|
91
91
|
// ValidationError
|
|
92
92
|
export { default as ValidationError } from './ValidationError.svelte';
|
|
93
|
+
|
|
94
|
+
// MenuItem
|
|
95
|
+
export { default as MenuItem } from './MenuItem/MenuItem.svelte';
|
|
96
|
+
|
|
97
|
+
// AvatarButton
|
|
98
|
+
export { default as AvatarButton } from './AvatarButton/AvatarButton.svelte';
|
|
99
|
+
|
|
100
|
+
// NavItem
|
|
101
|
+
export { default as NavItem } from './NavItem/NavItem.svelte';
|
|
102
|
+
|
|
103
|
+
// CardAction
|
|
104
|
+
export { default as CardAction } from './CardAction/CardAction.svelte';
|
|
105
|
+
|
|
106
|
+
// SearchResultItem
|
|
107
|
+
export { default as SearchResultItem } from './SearchResultItem/SearchResultItem.svelte';
|
|
108
|
+
|
|
109
|
+
// LandingButton
|
|
110
|
+
export { default as LandingButton } from './LandingButton/LandingButton.svelte';
|
|
111
|
+
|
|
112
|
+
// SidebarToggle
|
|
113
|
+
export { default as SidebarToggle } from './SidebarToggle/SidebarToggle.svelte';
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import PasswordStrengthIndicator from "../inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte";
|
|
9
9
|
import Input from "../../primitives/Input/Input.svelte";
|
|
10
10
|
import Button from "../../primitives/Button/Button.svelte";
|
|
11
|
+
import CardAction from "../../primitives/CardAction/CardAction.svelte";
|
|
11
12
|
import Checkbox from "../../primitives/Checkbox/Checkbox.svelte";
|
|
12
13
|
import { typography } from '../../tokens/typography';
|
|
13
14
|
|
|
@@ -795,8 +796,7 @@
|
|
|
795
796
|
|
|
796
797
|
<div class="space-y-3">
|
|
797
798
|
{#each accounts as account}
|
|
798
|
-
<
|
|
799
|
-
variant="card"
|
|
799
|
+
<CardAction
|
|
800
800
|
size="md"
|
|
801
801
|
class="group"
|
|
802
802
|
onclick={() => handleAccountSelectInternal(account)}
|
|
@@ -844,7 +844,7 @@
|
|
|
844
844
|
/>
|
|
845
845
|
</svg>
|
|
846
846
|
</div>
|
|
847
|
-
</
|
|
847
|
+
</CardAction>
|
|
848
848
|
{/each}
|
|
849
849
|
</div>
|
|
850
850
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuperLogin.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/SuperLogin/SuperLogin.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"SuperLogin.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/SuperLogin/SuperLogin.svelte.js"],"names":[],"mappings":";;;;;AAs+BA;iBAp7BkC,MAAM;cAAY,MAAM;cAAY,MAAM;kBAAgB,MAAM;kBAAgB,OAAO;gBAAc,MAAM;gBAAc,MAAM;iBAAe,MAAM;0BAAwB,MAAM;wBAAsB,MAAM;aAAW,MAAM;;;;;yBAAoI,OAAO;mBAAiB,MAAM;WAo7B1W;wBAp7BtC;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,WAAW;IAAC,eAAe,CAAC,WAAW;IAAC,UAAU,CAAC,WAAW;IAAC,kBAAkB,CAAC,WAAW;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -4,5 +4,4 @@ export { default as PasswordInput } from "./PasswordInput.svelte";
|
|
|
4
4
|
export { default as PasswordStrengthIndicator } from "./PasswordStrengthIndicator/PasswordStrengthIndicator.svelte";
|
|
5
5
|
export { default as PlaceAutocomplete } from "./PlaceAutocomplete/PlaceAutocomplete.svelte";
|
|
6
6
|
export { default as Search } from "./Search.svelte";
|
|
7
|
-
export { default as SelectDropdown } from "./SelectDropdown.svelte";
|
|
8
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -5,4 +5,3 @@ export { default as PasswordInput } from './PasswordInput.svelte';
|
|
|
5
5
|
export { default as PasswordStrengthIndicator } from './PasswordStrengthIndicator/PasswordStrengthIndicator.svelte';
|
|
6
6
|
export { default as PlaceAutocomplete } from './PlaceAutocomplete/PlaceAutocomplete.svelte';
|
|
7
7
|
export { default as Search } from './Search.svelte';
|
|
8
|
-
export { default as SelectDropdown } from './SelectDropdown.svelte';
|
|
@@ -7,7 +7,7 @@ function setupTest(args = {}) {
|
|
|
7
7
|
const user = userEvent.setup();
|
|
8
8
|
const { component } = render(AlertModal, {
|
|
9
9
|
props: {
|
|
10
|
-
|
|
10
|
+
open: true,
|
|
11
11
|
title: "Test Alert",
|
|
12
12
|
message: "This is a test message",
|
|
13
13
|
...args,
|
|
@@ -26,7 +26,7 @@ describe("AlertModal Component Tests", () => {
|
|
|
26
26
|
// Use getAllByText/queryAllByText and check length or first element
|
|
27
27
|
|
|
28
28
|
test("Does not render when show is false", () => {
|
|
29
|
-
render(AlertModal, { props: {
|
|
29
|
+
render(AlertModal, { props: { open: false } });
|
|
30
30
|
expect(screen.queryByText("Test Alert")).not.toBeInTheDocument();
|
|
31
31
|
});
|
|
32
32
|
|