@classic-homes/theme-svelte 0.1.13 → 0.1.15

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.
@@ -133,7 +133,7 @@
133
133
  </div>
134
134
 
135
135
  <ComboboxPrimitive.Content
136
- class="relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
136
+ class="isolate relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
137
137
  sideOffset={-1}
138
138
  collisionPadding={8}
139
139
  avoidCollisions={true}
@@ -71,7 +71,7 @@
71
71
  collisionPadding={8}
72
72
  avoidCollisions={true}
73
73
  class={cn(
74
- 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
74
+ 'isolate z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
75
75
  className
76
76
  )}
77
77
  >
@@ -185,7 +185,7 @@
185
185
  </div>
186
186
 
187
187
  <ComboboxPrimitive.Content
188
- class="relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
188
+ class="isolate relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
189
189
  sideOffset={-1}
190
190
  collisionPadding={8}
191
191
  avoidCollisions={true}
@@ -146,7 +146,7 @@
146
146
  </SelectPrimitive.Trigger>
147
147
 
148
148
  <SelectPrimitive.Content
149
- class="relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
149
+ class="isolate relative z-50 w-[var(--bits-floating-anchor-width)] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:border-t-0 data-[side=bottom]:rounded-t-none data-[side=top]:border-b-0 data-[side=top]:rounded-b-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
150
150
  sideOffset={-1}
151
151
  collisionPadding={8}
152
152
  avoidCollisions={true}
@@ -149,7 +149,8 @@
149
149
 
150
150
  // Variant-based styling
151
151
  const isLight = $derived(variant === 'light');
152
- const sidebarWidth = $derived(collapsed ? 'w-16' : 'w-64');
152
+ // Use the actual width props instead of hardcoded Tailwind classes
153
+ const currentWidth = $derived(collapsed ? collapsedWidth : expandedWidth);
153
154
 
154
155
  // Track previous search to avoid redundant updates
155
156
  let prevSearchQuery = '';
@@ -365,12 +366,22 @@
365
366
  // Variant-based background and text colors
366
367
  isLight ? 'bg-background text-foreground' : 'bg-sidebar text-sidebar-foreground',
367
368
  strongBorder ? 'border-r-2 border-black' : 'border-r border-black',
368
- isMobile ? (mobileOpen ? 'translate-x-0 w-64' : '-translate-x-full w-64') : sidebarWidth,
369
+ isMobile && !mobileOpen && '-translate-x-full',
369
370
  // Disable transition during swipe for smooth following
370
371
  isSwiping && 'transition-none',
371
372
  className
372
373
  )}
373
- style={isSwiping && swipeOffset < 0 ? `transform: translateX(${swipeOffset}px)` : undefined}
374
+ style={(() => {
375
+ const styles: string[] = [];
376
+ // Apply width - use expandedWidth for mobile, respect collapsed state for desktop
377
+ const width = isMobile ? expandedWidth : currentWidth;
378
+ styles.push(`width: ${width}px`);
379
+ // Apply swipe transform if swiping
380
+ if (isSwiping && swipeOffset < 0) {
381
+ styles.push(`transform: translateX(${swipeOffset}px)`);
382
+ }
383
+ return styles.join('; ');
384
+ })()}
374
385
  aria-label="Main navigation"
375
386
  ontouchstart={handleTouchStart}
376
387
  ontouchmove={handleTouchMove}
@@ -495,6 +506,7 @@
495
506
  <SidebarFlyout
496
507
  item={hoveredFlyoutItem}
497
508
  top={flyoutTop}
509
+ left={collapsedWidth}
498
510
  {isLight}
499
511
  onNavigate={handleNavigate}
500
512
  onMouseEnter={handleFlyoutMouseEnter}
@@ -13,6 +13,8 @@
13
13
  item: NavItem;
14
14
  /** Top position in pixels */
15
15
  top: number;
16
+ /** Left position in pixels (sidebar width) */
17
+ left?: number;
16
18
  /** Whether using light variant */
17
19
  isLight?: boolean;
18
20
  /** Callback when a navigation item is clicked */
@@ -23,7 +25,15 @@
23
25
  onMouseLeave?: () => void;
24
26
  }
25
27
 
26
- let { item, top, isLight = true, onNavigate, onMouseEnter, onMouseLeave }: Props = $props();
28
+ let {
29
+ item,
30
+ top,
31
+ left = 64,
32
+ isLight = true,
33
+ onNavigate,
34
+ onMouseEnter,
35
+ onMouseLeave,
36
+ }: Props = $props();
27
37
 
28
38
  let flyoutElement = $state<HTMLElement | null>(null);
29
39
 
@@ -99,11 +109,11 @@
99
109
  <div
100
110
  bind:this={flyoutElement}
101
111
  class={cn(
102
- 'fixed left-16 min-w-48 rounded-md border shadow-lg z-[calc(var(--z-sidebar,50)+10)]',
112
+ 'fixed min-w-48 rounded-md border shadow-lg z-[calc(var(--z-sidebar,50)+10)]',
103
113
  'motion-reduce:transition-none',
104
114
  isLight ? 'bg-background border-border' : 'bg-sidebar border-sidebar-foreground/20'
105
115
  )}
106
- style="top: {top}px;"
116
+ style="top: {top}px; left: {left}px;"
107
117
  role="menu"
108
118
  tabindex="0"
109
119
  onmouseenter={onMouseEnter}
@@ -112,20 +122,28 @@
112
122
  transition:fly={{ x: -10, duration: 150 }}
113
123
  >
114
124
  <div class="p-2">
115
- <!-- Item name as header -->
125
+ <!-- Item name as header - always clickable unless disabled -->
116
126
  <div
117
127
  class={cn(
118
128
  'px-3 py-2 text-sm font-medium',
119
129
  isLight ? 'text-foreground' : 'text-sidebar-foreground'
120
130
  )}
121
131
  >
122
- {#if item.href && !item.disabled}
132
+ {#if item.disabled}
133
+ <span class="opacity-50 cursor-not-allowed">
134
+ {item.name}
135
+ </span>
136
+ {:else if item.href}
123
137
  <a
124
138
  href={item.href}
125
- class="hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 rounded"
139
+ class={cn(
140
+ 'hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 rounded',
141
+ 'cursor-pointer'
142
+ )}
126
143
  target={item.external ? '_blank' : undefined}
127
144
  rel={item.external ? 'noopener noreferrer' : undefined}
128
145
  onclick={() => onNavigate?.(item)}
146
+ role="menuitem"
129
147
  >
130
148
  {item.name}
131
149
  {#if item.external}
@@ -133,9 +151,17 @@
133
151
  {/if}
134
152
  </a>
135
153
  {:else}
136
- <span class={item.disabled ? 'opacity-50' : ''}>
154
+ <button
155
+ type="button"
156
+ class={cn(
157
+ 'hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 rounded',
158
+ 'cursor-pointer text-left bg-transparent border-none p-0 font-medium text-inherit'
159
+ )}
160
+ onclick={() => onNavigate?.(item)}
161
+ role="menuitem"
162
+ >
137
163
  {item.name}
138
- </span>
164
+ </button>
139
165
  {/if}
140
166
  </div>
141
167
 
@@ -4,6 +4,8 @@ interface Props {
4
4
  item: NavItem;
5
5
  /** Top position in pixels */
6
6
  top: number;
7
+ /** Left position in pixels (sidebar width) */
8
+ left?: number;
7
9
  /** Whether using light variant */
8
10
  isLight?: boolean;
9
11
  /** Callback when a navigation item is clicked */
@@ -342,7 +342,7 @@
342
342
  {/if}
343
343
  </a>
344
344
  {:else}
345
- <!-- Item without href (parent with children only, or placeholder) - render as button -->
345
+ <!-- Item without href (parent with children only, or action button) - render as button -->
346
346
  <button
347
347
  type="button"
348
348
  class={cn(
@@ -355,6 +355,7 @@
355
355
  aria-haspopup={hasChildren ? 'menu' : undefined}
356
356
  aria-disabled={item.disabled || undefined}
357
357
  disabled={item.disabled}
358
+ onclick={handleClick}
358
359
  onmouseenter={handleMouseEnter}
359
360
  onmouseleave={onMouseLeave}
360
361
  >
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/theme-svelte",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Svelte components for the Classic theme system",
5
5
  "type": "module",
6
6
  "svelte": "./dist/lib/index.js",