@ixfx/components 0.9.6 → 0.9.8

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.
Files changed (84) hide show
  1. package/bundle/index.d.ts +100 -64
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +382 -253
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +2 -2
  6. package/dist/ac-text.js +2 -2
  7. package/dist/ac-token.js +2 -2
  8. package/dist/checkbox.js +1 -1
  9. package/dist/{colour-picker-CSxwUmtE.js → colour-picker-R73i0QTP.js} +2 -2
  10. package/dist/{colour-picker-CSxwUmtE.js.map → colour-picker-R73i0QTP.js.map} +1 -1
  11. package/dist/colour-picker.js +1 -1
  12. package/dist/crumbs.js +2 -2
  13. package/dist/data-display.js +1 -1
  14. package/dist/{data-grid-DIHhfsqS.d.ts → data-grid-BUeZjnvj.d.ts} +38 -1
  15. package/dist/data-grid-BUeZjnvj.d.ts.map +1 -0
  16. package/dist/data-grid.d.ts +1 -1
  17. package/dist/data-grid.js +156 -26
  18. package/dist/data-grid.js.map +1 -1
  19. package/dist/detail-list.js +2 -2
  20. package/dist/editable-label.js +1 -1
  21. package/dist/{fallbacks-BcKGq-2F.js → fallbacks-DQ_5OsmR.js} +2 -2
  22. package/dist/{fallbacks-BcKGq-2F.js.map → fallbacks-DQ_5OsmR.js.map} +1 -1
  23. package/dist/{grid-list-mL0GJTQR.js → grid-list-40blkeza.js} +5 -232
  24. package/dist/grid-list-40blkeza.js.map +1 -0
  25. package/dist/{grid-list-CSw1VMXT.d.ts → grid-list-lTwg4lp7.d.ts} +3 -66
  26. package/dist/grid-list-lTwg4lp7.d.ts.map +1 -0
  27. package/dist/grid-list.d.ts +1 -1
  28. package/dist/grid-list.js +1 -1
  29. package/dist/{icon-Dy33gu4Z.js → icon-BCJJYEpm.js} +2 -2
  30. package/dist/{icon-Dy33gu4Z.js.map → icon-BCJJYEpm.js.map} +1 -1
  31. package/dist/icons.js +1 -1
  32. package/dist/index.d.ts +3 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +13 -12
  35. package/dist/index.js.map +1 -1
  36. package/dist/labelled-radial-input.js +2 -2
  37. package/dist/{labelled-slider-input-aEYDvW2S.js → labelled-slider-input-CF2RtzgG.js} +3 -3
  38. package/dist/{labelled-slider-input-aEYDvW2S.js.map → labelled-slider-input-CF2RtzgG.js.map} +1 -1
  39. package/dist/labelled-slider-input.js +1 -1
  40. package/dist/{menu-CMXhIaNZ.js → menu-C8a-84S5.js} +4 -4
  41. package/dist/{menu-CMXhIaNZ.js.map → menu-C8a-84S5.js.map} +1 -1
  42. package/dist/{menu-item-BYGQzyCe.js → menu-item-DzizkMH-.js} +3 -3
  43. package/dist/{menu-item-BYGQzyCe.js.map → menu-item-DzizkMH-.js.map} +1 -1
  44. package/dist/menu.js +2 -2
  45. package/dist/miller.js +1 -1
  46. package/dist/narrowed-text.js +1 -1
  47. package/dist/notifier.js +1 -1
  48. package/dist/pan-text-CoYmt2qd.d.ts +67 -0
  49. package/dist/pan-text-CoYmt2qd.d.ts.map +1 -0
  50. package/dist/pan-text-CqtvjPyK.js +235 -0
  51. package/dist/pan-text-CqtvjPyK.js.map +1 -0
  52. package/dist/panel.js +1 -1
  53. package/dist/polar-pad.js +1 -1
  54. package/dist/{radial-input-DyxfbNzD.js → radial-input-KMVltQfe.js} +2 -2
  55. package/dist/{radial-input-DyxfbNzD.js.map → radial-input-KMVltQfe.js.map} +1 -1
  56. package/dist/radial-input.js +1 -1
  57. package/dist/range-input.js +1 -1
  58. package/dist/range.js +1 -1
  59. package/dist/select-horiz.js +1 -1
  60. package/dist/{slider-input-Cb5uSV42.js → slider-input-ByHdotzp.js} +2 -2
  61. package/dist/{slider-input-Cb5uSV42.js.map → slider-input-ByHdotzp.js.map} +1 -1
  62. package/dist/slider-input.js +1 -1
  63. package/dist/snackbar.js +1 -1
  64. package/dist/{split-layout-Bx0g8k8-.js → split-layout-3yBOEVZW.js} +2 -2
  65. package/dist/{split-layout-Bx0g8k8-.js.map → split-layout-3yBOEVZW.js.map} +1 -1
  66. package/dist/split-layout.js +1 -1
  67. package/dist/style.css +2 -2
  68. package/dist/swipe.js +1 -1
  69. package/dist/tabs.js +1 -1
  70. package/dist/{timeline-THyvH8xy.js → timeline-CFlBFFGZ.js} +2 -2
  71. package/dist/{timeline-THyvH8xy.js.map → timeline-CFlBFFGZ.js.map} +1 -1
  72. package/dist/timeline.js +1 -1
  73. package/dist/titlebar.js +2 -2
  74. package/dist/{tree-DAFBO_MF.js → tree-CVj7TIk2.js} +2 -2
  75. package/dist/{tree-DAFBO_MF.js.map → tree-CVj7TIk2.js.map} +1 -1
  76. package/dist/tree.js +1 -1
  77. package/dist/vertical-list.js +1 -1
  78. package/dist/xy-pad.js +1 -1
  79. package/docs-user/data-grid.md +59 -0
  80. package/docs-user/index.json +2 -2
  81. package/package.json +1 -1
  82. package/dist/data-grid-DIHhfsqS.d.ts.map +0 -1
  83. package/dist/grid-list-CSw1VMXT.d.ts.map +0 -1
  84. package/dist/grid-list-mL0GJTQR.js.map +0 -1
package/dist/data-grid.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as TickledController } from "./tickled-controller-Dh1Uh_vG.js";
2
2
  import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
3
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
3
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
4
4
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
5
5
  import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES } from "./incr-search-C05WjbZh.js";
6
6
  import { t as handleStyles } from "./handle-BPOxBOKf.js";
@@ -8,7 +8,8 @@ import { t as ListNativeDragController } from "./list-native-drag-controller-B0h
8
8
  import { i as listItemFadeKeyframes } from "./list-item-animation-BUoEKi5s.js";
9
9
  import "./interaction-BskmlA9t.js";
10
10
  import { t as createDragGhost } from "./drag-ghost-DtSDvjri.js";
11
- import "./menu-CMXhIaNZ.js";
11
+ import "./menu-C8a-84S5.js";
12
+ import "./pan-text-CqtvjPyK.js";
12
13
  import { LitElement, css, html, nothing } from "lit";
13
14
  import { property, query, state } from "lit/decorators.js";
14
15
  import { createCommandRegistry } from "@clinth/ui-commands";
@@ -26,12 +27,16 @@ let DataGridElement = class DataGridElement extends LitElement {
26
27
  this.getRowKey = (r, i) => r.key ?? r.id ?? String(i);
27
28
  this.editable = false;
28
29
  this.editability = `user`;
30
+ this.cellOverflow = `ellipsis`;
31
+ this.zebraStripes = false;
29
32
  this.groupBy = null;
30
33
  this.allowGrouping = false;
31
34
  this.crossGroupSelection = false;
32
35
  this.columnMenu = `auto`;
33
36
  this.itemsDraggable = false;
34
37
  this._columnFormatters = /* @__PURE__ */ new Map();
38
+ this._resizingColKey = void 0;
39
+ this._animatingColKeys = /* @__PURE__ */ new Set();
35
40
  this._selectedKeys = /* @__PURE__ */ new Set();
36
41
  this._scrollTop = 0;
37
42
  this._scrollLeft = 0;
@@ -312,6 +317,14 @@ let DataGridElement = class DataGridElement extends LitElement {
312
317
  --data-grid-header-bg: var(--surface-2);
313
318
  --data-grid-border: var(--border);
314
319
  --data-grid-header-text: var(--surface-3-text);
320
+ --data-grid-reorder-handle-width: 10px;
321
+ /* How strongly the alternate ("zebra") row stands out from the base row
322
+ background when [zebra-stripes] is set - a color-mix() percentage. */
323
+ --data-grid-zebra-intensity: 6%;
324
+ /* Duration of the width transition when a column is auto-sized via
325
+ autoSizeColumn(). Read back in JS (_columnResizeAnimationMs) to know
326
+ when the animation has finished, so keep it a plain time value. */
327
+ --data-grid-column-resize-duration: 180ms;
315
328
  position: relative;
316
329
  display: block;
317
330
  overflow: hidden;
@@ -340,11 +353,28 @@ let DataGridElement = class DataGridElement extends LitElement {
340
353
  box-sizing: border-box;
341
354
  }
342
355
  .header-cell[data-tickled] { background: var(--surface-5); }
356
+ /* Applied to a header-cell / cell while its column is animating towards
357
+ an autoSizeColumn() target width. */
358
+ .header-cell.width-animating, .cell.width-animating {
359
+ transition: width var(--data-grid-column-resize-duration, 180ms) ease-out;
360
+ }
361
+ @media (prefers-reduced-motion: reduce) {
362
+ .header-cell.width-animating, .cell.width-animating { transition: none; }
363
+ }
343
364
  .header-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
344
365
  .sort-icon { font-size: 10px; opacity: 0.7; }
345
- .resize-handle { position: absolute; right: 0; top: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 1; }
346
- .reorder-handle { cursor: grab; opacity: 0.5; padding: 0 2px; display: inline-flex; align-items: center; }
347
- .reorder-handle .ixfx-handle { --ixfx-handle-spot-size: 14px; --ixfx-handle-dot-size: 3px; }
366
+ .resize-handle {
367
+ position: absolute; right: -4px; top: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 1;
368
+ display: flex; align-items: stretch; justify-content: center;
369
+ }
370
+ .resize-handle::before {
371
+ content: ''; width: 2px; margin: 2px 0; border-radius: 1px; background: var(--split-gutter-color, transparent);
372
+ transition: background-color var(--transition, 0.15s ease-out);
373
+ }
374
+ .resize-handle:hover::before { background: var(--split-gutter-hover-color, var(--surface-6)); }
375
+ .resize-handle[data-active]::before { background: var(--split-gutter-active-color, var(--accent)); }
376
+ .reorder-handle { cursor: grab; opacity: 0.5; display: inline-flex; align-items: center; }
377
+ .reorder-handle .ixfx-handle { --ixfx-handle-length: 14px; --ixfx-handle-thickness: var(--data-grid-reorder-handle-width, 10px); --ixfx-handle-dot-size: 3px; }
348
378
  .flyout-trigger { flex-shrink: 0; width: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; border-left: var(--border-subtle); background: var(--data-grid-header-bg); }
349
379
  .viewport { flex: 1; overflow: auto; position: relative; }
350
380
  .spacer { position: relative; }
@@ -352,14 +382,28 @@ let DataGridElement = class DataGridElement extends LitElement {
352
382
  position: absolute; left: 0; right: 0; display: flex; align-items: stretch;
353
383
  gap: 0;
354
384
  height: var(--data-grid-row-height);
355
- border: none;
356
- box-shadow: inset 0 0 0 1px var(--item-border-color, transparent);
385
+ /* Border width is always 1px, even when not visually shown (transparent),
386
+ so hover/selection never changes the box size and shifts content. */
387
+ border: 1px solid transparent;
357
388
  background: var(--item-bg);
358
389
  border-radius: var(--item-border-radius);
359
390
  padding: 0;
360
391
  box-sizing: border-box;
392
+ /* Only background transitions - hover ("tickled") no longer changes
393
+ border, so there is nothing else to animate. */
394
+ transition: background var(--transition, 0.1s ease-out);
361
395
  }
362
- .row.item.tickled { background: var(--item-bg-tickled); border: var(--item-border-tickled); color: var(--item-text-tickled); }
396
+ /* Zebra striping: alternate rows tint towards the text colour, which
397
+ lightens in dark themes and darkens in light themes - so it reads as
398
+ "more contrast" either way. The zebra-odd class is only applied when
399
+ zebraStripes is set (see render()). Declared before .tickled /
400
+ .selected so those states (same specificity) still win when a striped
401
+ row is also hovered or selected. */
402
+ .row.item.zebra-odd {
403
+ background: color-mix(in oklch, transparent calc(100% - var(--data-grid-zebra-intensity, 6%)), var(--surface-3-text) var(--data-grid-zebra-intensity, 6%));
404
+ }
405
+ /* Hover: background only, no border change (avoids layout shift + colour flash). */
406
+ .row.item.tickled { background: var(--item-bg-tickled); color: var(--item-text-tickled); }
363
407
  .row.item.selected { background: var(--item-bg-selected); border: var(--item-border-selected); color: var(--item-text-selected); }
364
408
  .row.item.selected.tickled { background: var(--item-bg-selected-tickled); }
365
409
  .row.item.dragging-origin { opacity: 0.6; }
@@ -408,6 +452,7 @@ let DataGridElement = class DataGridElement extends LitElement {
408
452
  `
409
453
  ];
410
454
  }
455
+ #viewportResizeObserver;
411
456
  #nativeDragging;
412
457
  #dragOriginKey;
413
458
  #postDragSuppressTimer;
@@ -525,6 +570,8 @@ let DataGridElement = class DataGridElement extends LitElement {
525
570
  clearTimeout(this.#postDragSuppressTimer);
526
571
  this.#postDragSuppressTimer = 0;
527
572
  }
573
+ this.#viewportResizeObserver?.disconnect();
574
+ this.#viewportResizeObserver = void 0;
528
575
  }
529
576
  /**
530
577
  * Dispatch a command to this grid — routes through the command registry so
@@ -534,14 +581,35 @@ let DataGridElement = class DataGridElement extends LitElement {
534
581
  this.#searchRegistry?.invoke(commandId, args);
535
582
  }
536
583
  firstUpdated() {
537
- new ResizeObserver(() => {
538
- if (!this._viewportEl) return;
539
- this._viewportH = this._viewportEl.clientHeight;
540
- this._viewportW = this._viewportEl.clientWidth;
541
- this.requestUpdate();
542
- }).observe(this._viewportEl);
543
- this._viewportH = this._viewportEl.clientHeight;
544
- this._viewportW = this._viewportEl.clientWidth;
584
+ this.#viewportResizeObserver = new ResizeObserver(() => this.#measureViewport());
585
+ this.#viewportResizeObserver.observe(this._viewportEl);
586
+ this.#measureViewport();
587
+ }
588
+ /**
589
+ * Re-read the viewport's size and update `_viewportH`/`_viewportW` if it
590
+ * changed. A zero-sized read (e.g. while hosted in a hidden/inactive dock
591
+ * tab) is ignored so it never clobbers the last known-good geometry — the
592
+ * observer fires again with the real size once the host becomes visible.
593
+ */
594
+ #measureViewport() {
595
+ if (!this._viewportEl) return;
596
+ const w = this._viewportEl.clientWidth;
597
+ const h = this._viewportEl.clientHeight;
598
+ if (w <= 0 || h <= 0) return;
599
+ if (w === this._viewportW && h === this._viewportH) return;
600
+ this._viewportW = w;
601
+ this._viewportH = h;
602
+ }
603
+ /**
604
+ * Force a fresh re-measure of the viewport and re-render. Normally
605
+ * unnecessary — a `ResizeObserver` tracks the viewport automatically — but
606
+ * gives a consumer an escape hatch to recover if an ancestor's
607
+ * layout/visibility changes without the observer noticing (matches
608
+ * `ixfx-grid-list`'s `refreshLayout()`).
609
+ */
610
+ refreshLayout() {
611
+ this.#measureViewport();
612
+ this.requestUpdate();
545
613
  }
546
614
  updated(changed) {
547
615
  super.updated(changed);
@@ -1204,7 +1272,13 @@ let DataGridElement = class DataGridElement extends LitElement {
1204
1272
  composed: true
1205
1273
  }));
1206
1274
  }
1207
- _autoSizeColumn(col) {
1275
+ /**
1276
+ * Measure the width a column would need to show its header label and every
1277
+ * row's (formatted) value without truncation, clamped to `minWidth`/`maxWidth`.
1278
+ * Values are measured from their formatted string via canvas `measureText` -
1279
+ * accurate for plain text, an estimate for anything else.
1280
+ */
1281
+ _measureAutoWidth(col) {
1208
1282
  const cs = getComputedStyle(this);
1209
1283
  const font = `${cs.fontSize} ${cs.fontFamily}`;
1210
1284
  const ctx = document.createElement(`canvas`).getContext(`2d`);
@@ -1219,12 +1293,15 @@ let DataGridElement = class DataGridElement extends LitElement {
1219
1293
  for (const r of this.rows) {
1220
1294
  const v = r[col.key];
1221
1295
  if (v === null || v === void 0 || v === ``) continue;
1222
- const w = measure(String(v)) + cellPad;
1296
+ const w = measure(String(this._formatValue(v, col, r))) + cellPad;
1223
1297
  if (w > maxW) maxW = w;
1224
1298
  }
1225
1299
  const min = col.minWidth ?? 40;
1226
1300
  const max = col.maxWidth ?? 600;
1227
- const w = Math.max(min, Math.min(max, maxW));
1301
+ return Math.max(min, Math.min(max, maxW));
1302
+ }
1303
+ _autoSizeColumn(col) {
1304
+ const w = this._measureAutoWidth(col);
1228
1305
  col.width = w;
1229
1306
  this.requestUpdate();
1230
1307
  this.dispatchEvent(new CustomEvent(`datagrid-column-resize`, {
@@ -1236,11 +1313,50 @@ let DataGridElement = class DataGridElement extends LitElement {
1236
1313
  composed: true
1237
1314
  }));
1238
1315
  }
1316
+ /**
1317
+ * Resize a single column, by key, to fit its contents (header label + every
1318
+ * row's formatted value), animating the width change smoothly. Only works
1319
+ * for plain columns - one with a custom `renderer` can't be measured
1320
+ * reliably from its raw value, so it's left untouched. Returns `false` (and
1321
+ * does nothing) if the column doesn't exist, isn't resizable, or has a
1322
+ * `renderer`.
1323
+ */
1324
+ autoSizeColumn(key) {
1325
+ const col = this.columns.find((c) => c.key === key);
1326
+ if (!col || col.resizable === false || col.renderer) return false;
1327
+ const target = this._measureAutoWidth(col);
1328
+ if ((col.width ?? 150) === target) return true;
1329
+ this._animatingColKeys = new Set(this._animatingColKeys).add(key);
1330
+ requestAnimationFrame(() => {
1331
+ col.width = target;
1332
+ this.requestUpdate();
1333
+ this.dispatchEvent(new CustomEvent(`datagrid-column-resize`, {
1334
+ detail: {
1335
+ key,
1336
+ width: target
1337
+ },
1338
+ bubbles: true,
1339
+ composed: true
1340
+ }));
1341
+ window.setTimeout(() => {
1342
+ const next = new Set(this._animatingColKeys);
1343
+ next.delete(key);
1344
+ this._animatingColKeys = next;
1345
+ }, this._columnResizeAnimationMs());
1346
+ });
1347
+ return true;
1348
+ }
1349
+ _columnResizeAnimationMs() {
1350
+ const raw = getComputedStyle(this).getPropertyValue(`--data-grid-column-resize-duration`).trim();
1351
+ const ms = raw.endsWith(`ms`) ? Number.parseFloat(raw) : raw.endsWith(`s`) ? Number.parseFloat(raw) * 1e3 : Number.parseFloat(raw);
1352
+ return (Number.isFinite(ms) && ms > 0 ? ms : 180) + 30;
1353
+ }
1239
1354
  _onResizePointerDown(e, col) {
1240
1355
  e.preventDefault();
1241
1356
  e.stopPropagation();
1242
1357
  const startX = e.clientX;
1243
1358
  const startW = col.width ?? 150;
1359
+ this._resizingColKey = col.key;
1244
1360
  const onMove = (ev) => {
1245
1361
  col.width = Math.max(col.minWidth ?? 40, Math.min(col.maxWidth ?? 600, startW + ev.clientX - startX));
1246
1362
  this.requestUpdate();
@@ -1248,6 +1364,7 @@ let DataGridElement = class DataGridElement extends LitElement {
1248
1364
  const onUp = (ev) => {
1249
1365
  window.removeEventListener(`pointermove`, onMove);
1250
1366
  window.removeEventListener(`pointerup`, onUp);
1367
+ this._resizingColKey = void 0;
1251
1368
  const w = Math.max(col.minWidth ?? 40, Math.min(col.maxWidth ?? 600, startW + ev.clientX - startX));
1252
1369
  this.dispatchEvent(new CustomEvent(`datagrid-column-resize`, {
1253
1370
  detail: {
@@ -1299,20 +1416,20 @@ let DataGridElement = class DataGridElement extends LitElement {
1299
1416
  const visibleFlat = this._flat.slice(startRow, endRow);
1300
1417
  const showCheckbox = this.interactionMode === `checked`;
1301
1418
  return html`
1302
- <div class="grid" style="height:400px">
1419
+ <div class="grid">
1303
1420
  <div class="header-bar">
1304
1421
  <div class="header-scroll">
1305
1422
  ${showCheckbox ? html`<div class="header-cell checkbox-col"></div>` : nothing}
1306
1423
  ${repeat(this._visibleColumns, (c) => c.key, (col, idx) => html`
1307
- <div class="header-cell" style="width:${col.width ?? 150}px" ?drag-source=${this._drag?.active && this._drag.sourceCol.key === col.key}
1424
+ <div class="header-cell ${this._animatingColKeys.has(col.key) ? `width-animating` : ``}" style="width:${col.width ?? 150}px" ?drag-source=${this._drag?.active && this._drag.sourceCol.key === col.key}
1308
1425
  @click=${() => this._onHeaderClick(col)}
1309
1426
  @pointerenter=${() => this._tickled.handlePointerEnter(col.key)}>
1310
1427
  ${col.reorderable !== false ? html`<span class="reorder-handle" draggable="false"
1311
1428
  @pointerdown=${(e) => this._beginHeaderDrag(e, col, idx)}
1312
- ><span class="ixfx-handle" data-handle="dotted" data-shape="spot" part="reorder-handle"></span></span>` : nothing}
1429
+ ><span class="ixfx-handle" data-handle="dotted" data-shape="vertical" part="reorder-handle"></span></span>` : nothing}
1313
1430
  <span class="header-label">${col.label}</span>
1314
1431
  ${this.sortState?.key === col.key ? html`<span class="sort-icon">${this.sortState.direction === `asc` ? `▲` : `▼`}</span>` : nothing}
1315
- ${col.resizable !== false ? html`<span class="resize-handle" @pointerdown=${(e) => this._onResizePointerDown(e, col)} @click=${(e) => e.stopPropagation()} @dblclick=${(e) => {
1432
+ ${col.resizable !== false ? html`<span class="resize-handle" ?data-active=${this._resizingColKey === col.key} @pointerdown=${(e) => this._onResizePointerDown(e, col)} @click=${(e) => e.stopPropagation()} @dblclick=${(e) => {
1316
1433
  e.preventDefault();
1317
1434
  e.stopPropagation();
1318
1435
  this._autoSizeColumn(col);
@@ -1383,7 +1500,7 @@ let DataGridElement = class DataGridElement extends LitElement {
1383
1500
  const selected = this._selectedKeys.has(rowKey);
1384
1501
  const tickled = this._tickled.isTickled(rowKey);
1385
1502
  return html`
1386
- <div class="row item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${this.#enteringRowKeys.has(rowKey) ? `entering` : ``} ${this.#nativeDragging && rowKey === this.#dragOriginKey ? `dragging-origin` : ``}" style="top:${absIdx * rh}px; height:${rh}px"
1503
+ <div class="row item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${this.zebraStripes && absIdx2 % 2 === 1 ? `zebra-odd` : ``} ${this.#enteringRowKeys.has(rowKey) ? `entering` : ``} ${this.#nativeDragging && rowKey === this.#dragOriginKey ? `dragging-origin` : ``}" style="top:${absIdx * rh}px; height:${rh}px"
1387
1504
  data-key=${rowKey}
1388
1505
  draggable=${this.#nativeDrag.draggableAttr}
1389
1506
  @click=${(e) => {
@@ -1489,7 +1606,9 @@ let DataGridElement = class DataGridElement extends LitElement {
1489
1606
  const rendered = col.renderer ? col.renderer(row, col, absIdx2) : displayVal;
1490
1607
  const cellContent = col.renderer ? rendered : displayVal;
1491
1608
  const textEditable = this._isEditable(row, col) && this._isTextEditor(col);
1492
- return html`<div class="cell ${textEditable ? `editable-text` : ``}" data-col=${col.key} style="width:${col.width ?? 150}px; justify-content:${col.align === `right` ? `flex-end` : col.align === `center` ? `center` : `flex-start`}"
1609
+ const indent = col.align !== `right` && col.align !== `center` && col.reorderable !== false ? `padding-left:calc(var(--space-s) + var(--data-grid-reorder-handle-width, 10px) + var(--space-xs));` : ``;
1610
+ const canPan = this.cellOverflow === `pan-text` && !col.renderer && (selected || tickled);
1611
+ return html`<div class="cell ${textEditable ? `editable-text` : ``} ${this._animatingColKeys.has(col.key) ? `width-animating` : ``}" data-col=${col.key} style="width:${col.width ?? 150}px; justify-content:${col.align === `right` ? `flex-end` : col.align === `center` ? `center` : `flex-start`}; ${indent}"
1493
1612
  @click=${(e) => {
1494
1613
  this._lastClickedCell = {
1495
1614
  rowKey,
@@ -1511,7 +1630,7 @@ let DataGridElement = class DataGridElement extends LitElement {
1511
1630
  composed: true
1512
1631
  }));
1513
1632
  }}
1514
- >${cellContent}</div>`;
1633
+ >${canPan ? html`<ixfx-pan-text mode="loop">${cellContent}</ixfx-pan-text>` : cellContent}</div>`;
1515
1634
  })}
1516
1635
  </div>
1517
1636
  `;
@@ -1545,6 +1664,15 @@ __decorate([property({
1545
1664
  type: String,
1546
1665
  reflect: true
1547
1666
  })], DataGridElement.prototype, "editability", void 0);
1667
+ __decorate([property({
1668
+ type: String,
1669
+ attribute: `cell-overflow`
1670
+ })], DataGridElement.prototype, "cellOverflow", void 0);
1671
+ __decorate([property({
1672
+ type: Boolean,
1673
+ attribute: `zebra-stripes`,
1674
+ reflect: true
1675
+ })], DataGridElement.prototype, "zebraStripes", void 0);
1548
1676
  __decorate([property({ attribute: false })], DataGridElement.prototype, "groupBy", void 0);
1549
1677
  __decorate([property({
1550
1678
  type: Boolean,
@@ -1575,6 +1703,8 @@ __decorate([property({
1575
1703
  reflect: true
1576
1704
  })], DataGridElement.prototype, "itemsDraggable", void 0);
1577
1705
  __decorate([property({ attribute: false })], DataGridElement.prototype, "dragPreviewRenderer", void 0);
1706
+ __decorate([state()], DataGridElement.prototype, "_resizingColKey", void 0);
1707
+ __decorate([state()], DataGridElement.prototype, "_animatingColKeys", void 0);
1578
1708
  __decorate([state()], DataGridElement.prototype, "_selectedKeys", void 0);
1579
1709
  __decorate([state()], DataGridElement.prototype, "_scrollTop", void 0);
1580
1710
  __decorate([state()], DataGridElement.prototype, "_scrollLeft", void 0);