@spaethtech/svelte-ui 0.17.1-dev.82.2748ef4 → 0.17.1-dev.84.05ecf9b

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.
@@ -222,10 +222,8 @@
222
222
  class="cursor-pointer px-3 py-1.5 {i === highlight
223
223
  ? '[background-color:var(--ui-color-hover)]'
224
224
  : ''} hover:[background-color:var(--ui-color-hover)]"
225
- onpointerdown={(e) => {
226
- e.preventDefault(); // keep input focused so the click lands before blur closes the list
227
- choose(opt);
228
- }}
225
+ onpointerdown={(e) => e.preventDefault()}
226
+ onclick={() => choose(opt)}
229
227
  onpointerenter={() => (highlight = i)}
230
228
  >
231
229
  {opt}
@@ -60,7 +60,9 @@
60
60
  * reorders WITHIN the visible page only. */
61
61
  reorderable?: boolean;
62
62
  expanded?: Snippet<[T]>;
63
- rowActions?: (row: T) => MenuItem[];
63
+ /** Per-row kebab menu. Return `null`/`undefined`/`[]` for a row with no actions — the kebab still
64
+ * renders (columns stay aligned) but is disabled, rather than opening an empty/all-disabled menu. */
65
+ rowActions?: (row: T) => MenuItem[] | null | undefined;
64
66
  bulkActions?: (selected: ReadonlySet<string>) => MenuItem[];
65
67
  onReorder?: (row: T, direction: "up" | "down") => void;
66
68
  /** Overall density tier. Scales the whole table uniformly:
@@ -444,12 +446,17 @@
444
446
  {#if hasTail}
445
447
  <div class="flex shrink-0 items-center justify-end" style="width: {heightVar}">
446
448
  {#if rowActions}
449
+ <!-- The kebab renders on EVERY row (keeps the tail column aligned); it's DISABLED
450
+ when this row has no actions (`rowActions` returned null/undefined/[]) — a
451
+ disabled button reads as "nothing to do here", vs a menu of greyed-out items. -->
452
+ {@const actions = rowActions(row)}
447
453
  <Button
448
454
  variant="ghost"
449
455
  {size}
456
+ disabled={!actions || actions.length === 0}
450
457
  aria-label="Row actions"
451
458
  title="Row actions"
452
- onclick={(e) => openMenu(e, rowActions(row))}
459
+ onclick={(e) => openMenu(e, actions ?? [])}
453
460
  >
454
461
  {#snippet icon()}<IconDots />{/snippet}
455
462
  </Button>
@@ -16,7 +16,9 @@ declare function $$render<T>(): {
16
16
  * reorders WITHIN the visible page only. */
17
17
  reorderable?: boolean;
18
18
  expanded?: Snippet<[T]>;
19
- rowActions?: (row: T) => MenuItem[];
19
+ /** Per-row kebab menu. Return `null`/`undefined`/`[]` for a row with no actions — the kebab still
20
+ * renders (columns stay aligned) but is disabled, rather than opening an empty/all-disabled menu. */
21
+ rowActions?: (row: T) => MenuItem[] | null | undefined;
20
22
  bulkActions?: (selected: ReadonlySet<string>) => MenuItem[];
21
23
  onReorder?: (row: T, direction: "up" | "down") => void;
22
24
  /** Overall density tier. Scales the whole table uniformly:
@@ -535,6 +535,11 @@
535
535
  </div>
536
536
  {:else}
537
537
  {#each allOptions() as option, index (option.value)}
538
+ <!-- Select on the full CLICK, not mousedown: if selection closes a hosting Popup (a Select in
539
+ a Dialog), doing it on mousedown tears the popover out of the top layer before mouseup,
540
+ so the mouseup + click land on whatever's underneath (e.g. a CardFooter button) — a
541
+ silent click-through. `mousedown` still `preventDefault`s to keep focus off the option
542
+ (the reason it lived on mousedown), but selection waits for the completed gesture. -->
538
543
  <button
539
544
  bind:this={itemElements[index]}
540
545
  type="button"
@@ -552,7 +557,8 @@
552
557
  style="border: none; border-radius: 0; justify-content: flex-start; {itemSnippet
553
558
  ? ''
554
559
  : `height: ${itemHeight}px;`}"
555
- onmousedown={(event) => selectOption(option.value, event)}
560
+ onmousedown={(event) => event.preventDefault()}
561
+ onclick={(event) => selectOption(option.value, event)}
556
562
  tabindex="-1"
557
563
  role="option"
558
564
  aria-selected={isSelected(option.value)}
@@ -211,10 +211,8 @@
211
211
  ? '[background-color:color-mix(in_srgb,var(--ui-color-text)_10%,transparent)]'
212
212
  : ''}"
213
213
  onmouseenter={() => (active = i)}
214
- onmousedown={(e) => {
215
- e.preventDefault();
216
- accept(s);
217
- }}
214
+ onmousedown={(e) => e.preventDefault()}
215
+ onclick={() => accept(s)}
218
216
  >
219
217
  <span class="font-mono">{ctx.type === "column" ? "$" : ""}{s.value}</span>
220
218
  {#if s.label !== s.value}<span
@@ -377,10 +377,17 @@ Config-driven, responsive 12-column data table over a `DataGrid`.
377
377
 
378
378
  - **Location**: `src/lib/components/DataTable.svelte`
379
379
  - **Props**: `grid` (`DataGrid<T>` from `@spaethtech/svelte-ui/data`), `selectable`, `expandable`, `expanded`
380
- (snippet), `rowActions` (`(row) => MenuItem[]`), `bulkActions`
380
+ (snippet), `rowActions` (`(row) => MenuItem[] | null`), `bulkActions`
381
381
  - **Features**: selectable + expandable rows, sortable headers, per-row & bulk action menus
382
382
  (via `Menu`/`Popup`), paginated footer. A **compound component** — all controls are
383
383
  `<Button variant="plain" size="sm">` / `<Select size="sm">` / `<Checkbox>`.
384
+ - **`rowActions` per row**: return `null`/`undefined`/`[]` for a row with no actions — the kebab still
385
+ renders (the tail column stays aligned across rows) but is **disabled**, rather than opening an empty
386
+ or all-greyed menu. Return items to enable it.
387
+ - **Links in an expandable table**: wrap only the **text** in `<a>` inside your `cell` snippet (not the
388
+ whole cell). The cell is a flex box, so a plain inline `<a>text</a>` is text-width — the rest of the
389
+ cell stays an expand/collapse target. Row-click already ignores clicks on `a`/`button`/`input`/…, so
390
+ a link navigates without toggling expand; don't stretch the anchor with `block`/`w-full`.
384
391
 
385
392
  ### Query
386
393
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaethtech/svelte-ui",
3
- "version": "0.17.1-dev.82.2748ef4",
3
+ "version": "0.17.1-dev.84.05ecf9b",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/spaethtech/svelte-ui.git"