@classic-homes/theme-svelte 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/AlertDialog.svelte +1 -1
- package/dist/lib/components/OTPInput.svelte +4 -4
- package/dist/lib/components/Tabs.svelte +73 -28
- package/dist/lib/components/layout/AuthLayout.svelte +1 -1
- package/dist/lib/components/layout/DashboardLayout.svelte +4 -1
- package/dist/lib/components/notifications/NotificationBulkActions.svelte +6 -3
- package/dist/lib/components/notifications/NotificationDialog.svelte +1 -1
- package/dist/lib/components/notifications/NotificationFilters.svelte +1 -1
- package/package.json +1 -1
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
/>
|
|
98
98
|
<AlertDialogPrimitive.Content
|
|
99
99
|
class={cn(
|
|
100
|
-
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-black bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]
|
|
100
|
+
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-[calc(100vw-2rem)] sm:max-w-lg max-h-[calc(100dvh-2rem)] overflow-y-auto translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-black bg-background p-4 sm:p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
|
|
101
101
|
className
|
|
102
102
|
)}
|
|
103
103
|
>
|
|
@@ -224,7 +224,7 @@
|
|
|
224
224
|
{/if}
|
|
225
225
|
|
|
226
226
|
<div
|
|
227
|
-
class={cn('flex gap-2', className)}
|
|
227
|
+
class={cn('flex gap-1.5 sm:gap-2', className)}
|
|
228
228
|
role="group"
|
|
229
229
|
aria-label={label || 'One-time password input'}
|
|
230
230
|
aria-describedby={describedBy}
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
onpaste={handlePaste}
|
|
245
245
|
onfocus={handleFocus}
|
|
246
246
|
class={cn(
|
|
247
|
-
'h-12 w-12 text-
|
|
247
|
+
'h-10 w-10 text-base sm:h-12 sm:w-12 sm:text-lg text-center font-semibold rounded-md border border-input bg-background ring-offset-background transition-colors',
|
|
248
248
|
'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
|
249
249
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
250
250
|
error && 'border-destructive focus:ring-destructive'
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
</div>
|
|
276
276
|
{:else}
|
|
277
277
|
<div
|
|
278
|
-
class={cn('flex gap-2', className)}
|
|
278
|
+
class={cn('flex gap-1.5 sm:gap-2', className)}
|
|
279
279
|
role="group"
|
|
280
280
|
aria-label="One-time password input"
|
|
281
281
|
aria-describedby={describedBy}
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
onpaste={handlePaste}
|
|
296
296
|
onfocus={handleFocus}
|
|
297
297
|
class={cn(
|
|
298
|
-
'h-12 w-12 text-
|
|
298
|
+
'h-10 w-10 text-base sm:h-12 sm:w-12 sm:text-lg text-center font-semibold rounded-md border border-input bg-background ring-offset-background transition-colors',
|
|
299
299
|
'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
|
300
300
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
301
301
|
error && 'border-destructive focus:ring-destructive'
|
|
@@ -50,6 +50,35 @@
|
|
|
50
50
|
// Store references to tab button elements for direct focus management
|
|
51
51
|
let tabRefs: Record<string, HTMLButtonElement | undefined> = $state({});
|
|
52
52
|
|
|
53
|
+
// Horizontal-scroll handling for tab lists wider than their container
|
|
54
|
+
let tabList: HTMLDivElement | undefined = $state();
|
|
55
|
+
let canScrollLeft = $state(false);
|
|
56
|
+
let canScrollRight = $state(false);
|
|
57
|
+
|
|
58
|
+
function updateScrollShadows() {
|
|
59
|
+
if (!tabList) return;
|
|
60
|
+
canScrollLeft = tabList.scrollLeft > 1;
|
|
61
|
+
canScrollRight = tabList.scrollLeft + tabList.clientWidth < tabList.scrollWidth - 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Scroll only the tab list (never the page) so deep-linked tabs are visible
|
|
65
|
+
function scrollTabIntoView(el: HTMLButtonElement) {
|
|
66
|
+
if (!tabList) return;
|
|
67
|
+
const listRect = tabList.getBoundingClientRect();
|
|
68
|
+
const rect = el.getBoundingClientRect();
|
|
69
|
+
if (rect.left < listRect.left) {
|
|
70
|
+
tabList.scrollLeft += rect.left - listRect.left - 8;
|
|
71
|
+
} else if (rect.right > listRect.right) {
|
|
72
|
+
tabList.scrollLeft += rect.right - listRect.right + 8;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
$effect(() => {
|
|
77
|
+
const el = tabRefs[value];
|
|
78
|
+
if (el) scrollTabIntoView(el);
|
|
79
|
+
updateScrollShadows();
|
|
80
|
+
});
|
|
81
|
+
|
|
53
82
|
// Create a reactive object for context
|
|
54
83
|
// Initialize with empty values - the effect will set them immediately
|
|
55
84
|
const tabsState = $state({ activeTab: '', tabsId: '' });
|
|
@@ -108,34 +137,50 @@
|
|
|
108
137
|
|
|
109
138
|
<div class={cn('w-full', className)}>
|
|
110
139
|
<!-- Tab List -->
|
|
111
|
-
<div
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
<div class="relative inline-flex max-w-full">
|
|
141
|
+
{#if canScrollLeft}
|
|
142
|
+
<div
|
|
143
|
+
class="pointer-events-none absolute inset-y-0 left-0 z-10 w-6 rounded-l-md bg-gradient-to-r from-muted to-transparent"
|
|
144
|
+
aria-hidden="true"
|
|
145
|
+
></div>
|
|
146
|
+
{/if}
|
|
147
|
+
{#if canScrollRight}
|
|
148
|
+
<div
|
|
149
|
+
class="pointer-events-none absolute inset-y-0 right-0 z-10 w-6 rounded-r-md bg-gradient-to-l from-muted to-transparent"
|
|
150
|
+
aria-hidden="true"
|
|
151
|
+
></div>
|
|
152
|
+
{/if}
|
|
153
|
+
<div
|
|
154
|
+
bind:this={tabList}
|
|
155
|
+
onscroll={updateScrollShadows}
|
|
156
|
+
role="tablist"
|
|
157
|
+
aria-label={label}
|
|
158
|
+
class="inline-flex h-10 max-w-full items-center justify-center overflow-x-auto rounded-md bg-muted p-1 text-muted-foreground [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
159
|
+
>
|
|
160
|
+
{#each tabs as tab, index (tab.id)}
|
|
161
|
+
<button
|
|
162
|
+
bind:this={tabRefs[tab.id]}
|
|
163
|
+
id={`${id}-tab-${tab.id}`}
|
|
164
|
+
role="tab"
|
|
165
|
+
type="button"
|
|
166
|
+
aria-selected={value === tab.id}
|
|
167
|
+
aria-controls={children && value === tab.id ? `${id}-panel-${tab.id}` : undefined}
|
|
168
|
+
tabindex={value === tab.id ? 0 : -1}
|
|
169
|
+
disabled={tab.disabled}
|
|
170
|
+
class={cn(
|
|
171
|
+
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
172
|
+
value === tab.id
|
|
173
|
+
? 'bg-background text-foreground shadow-sm'
|
|
174
|
+
: 'hover:bg-background-hover hover:text-foreground',
|
|
175
|
+
tab.disabled && 'opacity-50 pointer-events-none cursor-not-allowed'
|
|
176
|
+
)}
|
|
177
|
+
onclick={() => selectTab(tab.id)}
|
|
178
|
+
onkeydown={(e) => handleKeyDown(e, index)}
|
|
179
|
+
>
|
|
180
|
+
{tab.label}
|
|
181
|
+
</button>
|
|
182
|
+
{/each}
|
|
183
|
+
</div>
|
|
139
184
|
</div>
|
|
140
185
|
|
|
141
186
|
<!-- Tab Panels Container -->
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
<AppShell>
|
|
81
81
|
<div
|
|
82
82
|
class={cn(
|
|
83
|
-
'flex h-
|
|
83
|
+
'flex min-h-[100dvh] flex-col items-center justify-center bg-content-bg px-4 py-8 sm:px-6 lg:px-8',
|
|
84
84
|
showBackground && backgroundClasses[backgroundVariant],
|
|
85
85
|
className
|
|
86
86
|
)}
|
|
@@ -323,7 +323,10 @@
|
|
|
323
323
|
{/if}
|
|
324
324
|
|
|
325
325
|
<!-- Main Content -->
|
|
326
|
-
<main
|
|
326
|
+
<main
|
|
327
|
+
id="main-content"
|
|
328
|
+
class="min-w-0 flex-1 overflow-x-clip bg-content-bg {contentPaddingClass}"
|
|
329
|
+
>
|
|
327
330
|
{@render children()}
|
|
328
331
|
</main>
|
|
329
332
|
</div>
|
|
@@ -51,10 +51,13 @@
|
|
|
51
51
|
</script>
|
|
52
52
|
|
|
53
53
|
<div
|
|
54
|
-
class={cn(
|
|
54
|
+
class={cn(
|
|
55
|
+
'flex flex-wrap items-center justify-between gap-x-4 gap-y-2 rounded-lg border bg-muted/50 p-3',
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
55
58
|
>
|
|
56
59
|
<!-- Selection controls -->
|
|
57
|
-
<div class="flex items-center gap-3">
|
|
60
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
58
61
|
<Checkbox checked={allSelected} onCheckedChange={handleSelectAllChange}>
|
|
59
62
|
{#snippet children()}
|
|
60
63
|
<span class="text-sm">
|
|
@@ -80,7 +83,7 @@
|
|
|
80
83
|
|
|
81
84
|
<!-- Bulk actions -->
|
|
82
85
|
{#if hasSelection}
|
|
83
|
-
<div class="flex items-center gap-2">
|
|
86
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
84
87
|
{#if onMarkRead}
|
|
85
88
|
<Button variant="outline" size="sm" onclick={onMarkRead}>
|
|
86
89
|
{#snippet children()}
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
|
|
150
150
|
<!-- Metadata -->
|
|
151
151
|
<div class="border-t pt-4 mt-4">
|
|
152
|
-
<dl class="grid grid-cols-
|
|
152
|
+
<dl class="grid grid-cols-1 gap-4 text-sm sm:grid-cols-2">
|
|
153
153
|
<div>
|
|
154
154
|
<dt class="text-muted-foreground">Category</dt>
|
|
155
155
|
<dd class="font-medium capitalize">{notification.category}</dd>
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
role="tablist"
|
|
70
70
|
aria-label="Filter notifications"
|
|
71
71
|
class={cn(
|
|
72
|
-
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
|
|
72
|
+
'inline-flex h-10 max-w-full items-center justify-center overflow-x-auto rounded-md bg-muted p-1 text-muted-foreground [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
|
|
73
73
|
className
|
|
74
74
|
)}
|
|
75
75
|
>
|