@classic-homes/theme-svelte 1.1.1 → 1.1.2

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.
@@ -235,58 +235,62 @@
235
235
  />
236
236
  </div>
237
237
 
238
- <ComboboxPrimitive.Content
239
- class="isolate relative z-50 min-w-[var(--bits-floating-anchor-width)] overflow-hidden rounded-md border border-black 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"
240
- sideOffset={-1}
241
- collisionPadding={8}
242
- avoidCollisions={true}
243
- >
244
- <div class="p-1 max-h-[300px] overflow-y-auto">
245
- {#if loading}
246
- <div class="flex items-center justify-center py-6">
247
- <Spinner size="sm" />
248
- <span class="ml-2 text-sm text-muted-foreground">Loading...</span>
249
- </div>
250
- {:else if filteredOptions.length === 0}
251
- <div class="py-6 text-center text-sm text-muted-foreground">
252
- {emptyMessage}
253
- </div>
254
- {:else}
255
- {#each filteredOptions as option}
256
- {@const isSelected = value.includes(option.value)}
257
- {@const isDisabledByMax = maxReached && !isSelected}
258
- <ComboboxPrimitive.Item
259
- value={option.value}
260
- label={option.label}
261
- disabled={option.disabled || isDisabledByMax}
262
- class="relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:cursor-default"
263
- >
264
- <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
265
- {#if isSelected}
266
- <svg
267
- xmlns="http://www.w3.org/2000/svg"
268
- width="16"
269
- height="16"
270
- viewBox="0 0 24 24"
271
- fill="none"
272
- stroke="currentColor"
273
- stroke-width="2"
274
- stroke-linecap="round"
275
- stroke-linejoin="round"
276
- class="h-4 w-4"
277
- >
278
- <polyline points="20 6 9 17 4 12" />
279
- </svg>
280
- {:else}
281
- <span class="h-3.5 w-3.5 rounded-sm border border-primary"></span>
282
- {/if}
283
- </span>
284
- {option.label}
285
- </ComboboxPrimitive.Item>
286
- {/each}
287
- {/if}
288
- </div>
289
- </ComboboxPrimitive.Content>
238
+ <!-- Portal to <body>: escapes transformed/overflow-hidden ancestors
239
+ (e.g. Dialog panels) that would clip the dropdown. -->
240
+ <ComboboxPrimitive.Portal>
241
+ <ComboboxPrimitive.Content
242
+ class="isolate relative z-50 min-w-[var(--bits-floating-anchor-width)] overflow-hidden rounded-md border border-black 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"
243
+ sideOffset={-1}
244
+ collisionPadding={8}
245
+ avoidCollisions={true}
246
+ >
247
+ <div class="p-1 max-h-[300px] overflow-y-auto">
248
+ {#if loading}
249
+ <div class="flex items-center justify-center py-6">
250
+ <Spinner size="sm" />
251
+ <span class="ml-2 text-sm text-muted-foreground">Loading...</span>
252
+ </div>
253
+ {:else if filteredOptions.length === 0}
254
+ <div class="py-6 text-center text-sm text-muted-foreground">
255
+ {emptyMessage}
256
+ </div>
257
+ {:else}
258
+ {#each filteredOptions as option}
259
+ {@const isSelected = value.includes(option.value)}
260
+ {@const isDisabledByMax = maxReached && !isSelected}
261
+ <ComboboxPrimitive.Item
262
+ value={option.value}
263
+ label={option.label}
264
+ disabled={option.disabled || isDisabledByMax}
265
+ class="relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:cursor-default"
266
+ >
267
+ <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
268
+ {#if isSelected}
269
+ <svg
270
+ xmlns="http://www.w3.org/2000/svg"
271
+ width="16"
272
+ height="16"
273
+ viewBox="0 0 24 24"
274
+ fill="none"
275
+ stroke="currentColor"
276
+ stroke-width="2"
277
+ stroke-linecap="round"
278
+ stroke-linejoin="round"
279
+ class="h-4 w-4"
280
+ >
281
+ <polyline points="20 6 9 17 4 12" />
282
+ </svg>
283
+ {:else}
284
+ <span class="h-3.5 w-3.5 rounded-sm border border-primary"></span>
285
+ {/if}
286
+ </span>
287
+ {option.label}
288
+ </ComboboxPrimitive.Item>
289
+ {/each}
290
+ {/if}
291
+ </div>
292
+ </ComboboxPrimitive.Content>
293
+ </ComboboxPrimitive.Portal>
290
294
  </ComboboxPrimitive.Root>
291
295
  </div>
292
296
 
@@ -368,58 +372,62 @@
368
372
  />
369
373
  </div>
370
374
 
371
- <ComboboxPrimitive.Content
372
- class="isolate relative z-50 min-w-[var(--bits-floating-anchor-width)] overflow-hidden rounded-md border border-black 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"
373
- sideOffset={-1}
374
- collisionPadding={8}
375
- avoidCollisions={true}
376
- >
377
- <div class="p-1 max-h-[300px] overflow-y-auto">
378
- {#if loading}
379
- <div class="flex items-center justify-center py-6">
380
- <Spinner size="sm" />
381
- <span class="ml-2 text-sm text-muted-foreground">Loading...</span>
382
- </div>
383
- {:else if filteredOptions.length === 0}
384
- <div class="py-6 text-center text-sm text-muted-foreground">
385
- {emptyMessage}
386
- </div>
387
- {:else}
388
- {#each filteredOptions as option}
389
- {@const isSelected = value.includes(option.value)}
390
- {@const isDisabledByMax = maxReached && !isSelected}
391
- <ComboboxPrimitive.Item
392
- value={option.value}
393
- label={option.label}
394
- disabled={option.disabled || isDisabledByMax}
395
- class="relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:cursor-default"
396
- >
397
- <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
398
- {#if isSelected}
399
- <svg
400
- xmlns="http://www.w3.org/2000/svg"
401
- width="16"
402
- height="16"
403
- viewBox="0 0 24 24"
404
- fill="none"
405
- stroke="currentColor"
406
- stroke-width="2"
407
- stroke-linecap="round"
408
- stroke-linejoin="round"
409
- class="h-4 w-4"
410
- >
411
- <polyline points="20 6 9 17 4 12" />
412
- </svg>
413
- {:else}
414
- <span class="h-3.5 w-3.5 rounded-sm border border-primary"></span>
415
- {/if}
416
- </span>
417
- {option.label}
418
- </ComboboxPrimitive.Item>
419
- {/each}
420
- {/if}
421
- </div>
422
- </ComboboxPrimitive.Content>
375
+ <!-- Portal to <body>: escapes transformed/overflow-hidden ancestors
376
+ (e.g. Dialog panels) that would clip the dropdown. -->
377
+ <ComboboxPrimitive.Portal>
378
+ <ComboboxPrimitive.Content
379
+ class="isolate relative z-50 min-w-[var(--bits-floating-anchor-width)] overflow-hidden rounded-md border border-black 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"
380
+ sideOffset={-1}
381
+ collisionPadding={8}
382
+ avoidCollisions={true}
383
+ >
384
+ <div class="p-1 max-h-[300px] overflow-y-auto">
385
+ {#if loading}
386
+ <div class="flex items-center justify-center py-6">
387
+ <Spinner size="sm" />
388
+ <span class="ml-2 text-sm text-muted-foreground">Loading...</span>
389
+ </div>
390
+ {:else if filteredOptions.length === 0}
391
+ <div class="py-6 text-center text-sm text-muted-foreground">
392
+ {emptyMessage}
393
+ </div>
394
+ {:else}
395
+ {#each filteredOptions as option}
396
+ {@const isSelected = value.includes(option.value)}
397
+ {@const isDisabledByMax = maxReached && !isSelected}
398
+ <ComboboxPrimitive.Item
399
+ value={option.value}
400
+ label={option.label}
401
+ disabled={option.disabled || isDisabledByMax}
402
+ class="relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:cursor-default"
403
+ >
404
+ <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
405
+ {#if isSelected}
406
+ <svg
407
+ xmlns="http://www.w3.org/2000/svg"
408
+ width="16"
409
+ height="16"
410
+ viewBox="0 0 24 24"
411
+ fill="none"
412
+ stroke="currentColor"
413
+ stroke-width="2"
414
+ stroke-linecap="round"
415
+ stroke-linejoin="round"
416
+ class="h-4 w-4"
417
+ >
418
+ <polyline points="20 6 9 17 4 12" />
419
+ </svg>
420
+ {:else}
421
+ <span class="h-3.5 w-3.5 rounded-sm border border-primary"></span>
422
+ {/if}
423
+ </span>
424
+ {option.label}
425
+ </ComboboxPrimitive.Item>
426
+ {/each}
427
+ {/if}
428
+ </div>
429
+ </ComboboxPrimitive.Content>
430
+ </ComboboxPrimitive.Portal>
423
431
  </ComboboxPrimitive.Root>
424
432
  </div>
425
433
  {/if}
@@ -198,29 +198,35 @@
198
198
  {/snippet}
199
199
 
200
200
  {#snippet selectContent()}
201
- <SelectPrimitive.Content
202
- class={contentClasses}
203
- sideOffset={-1}
204
- collisionPadding={8}
205
- avoidCollisions={true}
206
- >
207
- <div class="p-1 max-h-[300px] overflow-y-auto">
208
- {#each options as item}
209
- {#if isGroup(item)}
210
- <SelectPrimitive.Group>
211
- <div class="py-1.5 pl-8 pr-2 text-sm font-semibold">
212
- {item.label}
213
- </div>
214
- {#each item.options as option}
215
- {@render selectItem(option)}
216
- {/each}
217
- </SelectPrimitive.Group>
218
- {:else}
219
- {@render selectItem(item)}
220
- {/if}
221
- {/each}
222
- </div>
223
- </SelectPrimitive.Content>
201
+ <!-- Portal to <body>: inside a Dialog the content would otherwise be clipped —
202
+ the dialog panel is transformed (translate centering), which makes it the
203
+ containing block for the floating content, and its overflow-hidden cuts
204
+ the dropdown off at the panel edge. -->
205
+ <SelectPrimitive.Portal>
206
+ <SelectPrimitive.Content
207
+ class={contentClasses}
208
+ sideOffset={-1}
209
+ collisionPadding={8}
210
+ avoidCollisions={true}
211
+ >
212
+ <div class="p-1 max-h-[300px] overflow-y-auto">
213
+ {#each options as item}
214
+ {#if isGroup(item)}
215
+ <SelectPrimitive.Group>
216
+ <div class="py-1.5 pl-8 pr-2 text-sm font-semibold">
217
+ {item.label}
218
+ </div>
219
+ {#each item.options as option}
220
+ {@render selectItem(option)}
221
+ {/each}
222
+ </SelectPrimitive.Group>
223
+ {:else}
224
+ {@render selectItem(item)}
225
+ {/if}
226
+ {/each}
227
+ </div>
228
+ </SelectPrimitive.Content>
229
+ </SelectPrimitive.Portal>
224
230
  {/snippet}
225
231
 
226
232
  {#snippet selectRoot(ariaLabel: string | undefined)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/theme-svelte",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Svelte components for the Classic theme system",
5
5
  "type": "module",
6
6
  "svelte": "./dist/lib/index.js",