@classic-homes/theme-svelte 1.3.0 → 1.5.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.
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
DEFAULT_CARD_CONFIG,
|
|
20
20
|
DEFAULT_TAB_WIDTH,
|
|
21
21
|
CARD_HEADER_HEIGHT,
|
|
22
|
-
CARD_EXPANDED_RATIO,
|
|
23
22
|
CARD_MIN_WIDTH,
|
|
24
23
|
loadPanelState,
|
|
25
24
|
savePanelState,
|
|
@@ -116,6 +115,12 @@
|
|
|
116
115
|
snapThreshold?: number;
|
|
117
116
|
/** Distance in pixels to drag before detaching from pinned mode (0 to disable) */
|
|
118
117
|
detachThreshold?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Viewport width (px) below which the panel uses mobile behaviors
|
|
120
|
+
* (card scrim, focus trap, card drag). Default 640. Pass 768 for apps
|
|
121
|
+
* that switch layouts at md.
|
|
122
|
+
*/
|
|
123
|
+
mobileBreakpoint?: number;
|
|
119
124
|
/** Custom header content (replaces title/subtitle) */
|
|
120
125
|
header?: Snippet;
|
|
121
126
|
/** Custom header actions */
|
|
@@ -155,6 +160,7 @@
|
|
|
155
160
|
persistKey,
|
|
156
161
|
snapThreshold = 20,
|
|
157
162
|
detachThreshold = 40,
|
|
163
|
+
mobileBreakpoint = 640,
|
|
158
164
|
header,
|
|
159
165
|
headerActions,
|
|
160
166
|
footer,
|
|
@@ -166,6 +172,20 @@
|
|
|
166
172
|
const resolvedConstraints = $derived({ ...DEFAULT_CONSTRAINTS, ...constraints });
|
|
167
173
|
const resolvedCardConfig = $derived({ ...DEFAULT_CARD_CONFIG, ...cardConfig });
|
|
168
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Default left offset for the card sheet, honoring cardConfig.align.
|
|
177
|
+
* Drag/resize bounds derive from the same offset so existing
|
|
178
|
+
* interactions are unaffected by non-center alignment.
|
|
179
|
+
*/
|
|
180
|
+
function cardDefaultLeftOffset(width: number): number {
|
|
181
|
+
const margin = resolvedCardConfig.horizontalMargin;
|
|
182
|
+
if (resolvedCardConfig.align === 'left') return margin;
|
|
183
|
+
if (resolvedCardConfig.align === 'right') {
|
|
184
|
+
return Math.max(margin, viewportWidth - width - margin);
|
|
185
|
+
}
|
|
186
|
+
return Math.max(margin, (viewportWidth - width) / 2);
|
|
187
|
+
}
|
|
188
|
+
|
|
169
189
|
// Internal state - initialized from props or persistence
|
|
170
190
|
let internalMode = $state<PanelMode>(DEFAULT_PANEL_STATE.mode);
|
|
171
191
|
let internalVariant = $state<PanelVariant>(DEFAULT_PANEL_STATE.variant);
|
|
@@ -229,7 +249,7 @@
|
|
|
229
249
|
let viewportHeight = $state(typeof window !== 'undefined' ? window.innerHeight : 768);
|
|
230
250
|
|
|
231
251
|
// Detect mobile
|
|
232
|
-
let isMobile = $derived(viewportWidth <
|
|
252
|
+
let isMobile = $derived(viewportWidth < mobileBreakpoint);
|
|
233
253
|
|
|
234
254
|
// Derived state - use props if provided, otherwise internal state
|
|
235
255
|
const mode = $derived(propMode ?? internalMode);
|
|
@@ -295,13 +315,13 @@
|
|
|
295
315
|
viewportHeight = window.innerHeight;
|
|
296
316
|
|
|
297
317
|
// Initialize card expanded height
|
|
298
|
-
cardExpandedHeight = viewportHeight *
|
|
318
|
+
cardExpandedHeight = viewportHeight * resolvedCardConfig.expandedRatio;
|
|
299
319
|
|
|
300
320
|
// Listen for resize
|
|
301
321
|
const handleResize = () => {
|
|
302
322
|
viewportWidth = window.innerWidth;
|
|
303
323
|
viewportHeight = window.innerHeight;
|
|
304
|
-
cardExpandedHeight = viewportHeight *
|
|
324
|
+
cardExpandedHeight = viewportHeight * resolvedCardConfig.expandedRatio;
|
|
305
325
|
};
|
|
306
326
|
window.addEventListener('resize', handleResize);
|
|
307
327
|
|
|
@@ -583,10 +603,7 @@
|
|
|
583
603
|
viewportWidth - resolvedCardConfig.horizontalMargin * 2,
|
|
584
604
|
resolvedCardConfig.maxWidth
|
|
585
605
|
);
|
|
586
|
-
const defaultLeftOffset =
|
|
587
|
-
resolvedCardConfig.horizontalMargin,
|
|
588
|
-
(viewportWidth - cardWidth) / 2
|
|
589
|
-
);
|
|
606
|
+
const defaultLeftOffset = cardDefaultLeftOffset(cardWidth);
|
|
590
607
|
// Calculate bounds: can move from left margin to right margin
|
|
591
608
|
const minOffset = -(defaultLeftOffset - resolvedCardConfig.horizontalMargin);
|
|
592
609
|
const maxOffset =
|
|
@@ -898,10 +915,7 @@
|
|
|
898
915
|
cardWidthResizeStartWidth = currentWidth;
|
|
899
916
|
|
|
900
917
|
// Calculate current left position
|
|
901
|
-
const defaultLeftOffset =
|
|
902
|
-
resolvedCardConfig.horizontalMargin,
|
|
903
|
-
(viewportWidth - defaultCardWidth) / 2
|
|
904
|
-
);
|
|
918
|
+
const defaultLeftOffset = cardDefaultLeftOffset(defaultCardWidth);
|
|
905
919
|
cardWidthResizeStartLeft = defaultLeftOffset + cardHorizontalPosition;
|
|
906
920
|
|
|
907
921
|
document.body.style.cursor = 'ew-resize';
|
|
@@ -940,10 +954,7 @@
|
|
|
940
954
|
viewportWidth - resolvedCardConfig.horizontalMargin * 2,
|
|
941
955
|
resolvedCardConfig.maxWidth
|
|
942
956
|
);
|
|
943
|
-
const defaultLeftOffset =
|
|
944
|
-
resolvedCardConfig.horizontalMargin,
|
|
945
|
-
(viewportWidth - defaultCardWidth) / 2
|
|
946
|
-
);
|
|
957
|
+
const defaultLeftOffset = cardDefaultLeftOffset(defaultCardWidth);
|
|
947
958
|
cardHorizontalPosition = newLeft - defaultLeftOffset;
|
|
948
959
|
}
|
|
949
960
|
}
|
|
@@ -1087,10 +1098,7 @@
|
|
|
1087
1098
|
);
|
|
1088
1099
|
// Use custom cardWidth if set, otherwise use default
|
|
1089
1100
|
const actualCardWidth = cardWidth ?? defaultCardWidth;
|
|
1090
|
-
const defaultLeftOffset =
|
|
1091
|
-
resolvedCardConfig.horizontalMargin,
|
|
1092
|
-
(viewportWidth - defaultCardWidth) / 2
|
|
1093
|
-
);
|
|
1101
|
+
const defaultLeftOffset = cardDefaultLeftOffset(defaultCardWidth);
|
|
1094
1102
|
|
|
1095
1103
|
// Height based on expanded state or drag
|
|
1096
1104
|
let height: number;
|
|
@@ -64,6 +64,12 @@ interface Props {
|
|
|
64
64
|
snapThreshold?: number;
|
|
65
65
|
/** Distance in pixels to drag before detaching from pinned mode (0 to disable) */
|
|
66
66
|
detachThreshold?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Viewport width (px) below which the panel uses mobile behaviors
|
|
69
|
+
* (card scrim, focus trap, card drag). Default 640. Pass 768 for apps
|
|
70
|
+
* that switch layouts at md.
|
|
71
|
+
*/
|
|
72
|
+
mobileBreakpoint?: number;
|
|
67
73
|
/** Custom header content (replaces title/subtitle) */
|
|
68
74
|
header?: Snippet;
|
|
69
75
|
/** Custom header actions */
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
{/if}
|
|
118
118
|
{#if showClose}
|
|
119
119
|
<DialogPrimitive.Close
|
|
120
|
-
class="flex h-9 w-9 items-center justify-center rounded-md bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none"
|
|
120
|
+
class="flex h-9 w-9 items-center justify-center rounded-md bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none relative after:absolute after:-inset-1 after:content-['']"
|
|
121
121
|
aria-label="Close dialog"
|
|
122
122
|
>
|
|
123
123
|
<svg
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
root: 'relative flex w-full touch-none select-none items-center',
|
|
11
11
|
range: 'absolute h-full bg-primary rounded-full',
|
|
12
12
|
thumb:
|
|
13
|
-
|
|
13
|
+
"block rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 relative after:absolute after:left-1/2 after:top-1/2 after:h-11 after:w-11 after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:content-['']",
|
|
14
14
|
},
|
|
15
15
|
variants: {
|
|
16
16
|
size: {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
const positionLabel = $derived(`${index + 1} of ${items.length}`);
|
|
88
88
|
|
|
89
89
|
const buttonClass =
|
|
90
|
-
|
|
90
|
+
"inline-flex h-10 w-10 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm outline-none hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-40 relative after:absolute after:-inset-0.5 after:rounded-full after:content-['']";
|
|
91
91
|
|
|
92
92
|
function goTo(next: number, smooth = true) {
|
|
93
93
|
if (items.length === 0) return;
|