@ixfx/components 0.14.0 → 0.14.1

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.
package/dist/index.js CHANGED
@@ -9449,6 +9449,28 @@ __decorate([state()], IcicleTreeListElement.prototype, "_zoomKey", void 0);
9449
9449
  __decorate([query(`#icicle-tooltip`)], IcicleTreeListElement.prototype, "_tooltipEl", void 0);
9450
9450
  IcicleTreeListElement = __decorate([safeCustomElement(`ixfx-icicletree-list`)], IcicleTreeListElement);
9451
9451
  //#endregion
9452
+ //#region src/multicol-list/categories.ts
9453
+ /** A group node only organises the picker menu; it is not a selectable category. */
9454
+ function isGroup(category) {
9455
+ return category.children !== void 0 && category.children.length > 0;
9456
+ }
9457
+ /** All selectable categories (leaves) of a category tree, depth-first. */
9458
+ function flattenCategories(categories) {
9459
+ return categories.flatMap((c) => isGroup(c) ? flattenCategories(c.children) : [c]);
9460
+ }
9461
+ /** Finds any node (group or leaf) by key, searching the whole tree depth-first. */
9462
+ function findCategory(categories, key) {
9463
+ for (const category of categories) {
9464
+ if (category.key === key) return category;
9465
+ const nested = category.children ? findCategory(category.children, key) : void 0;
9466
+ if (nested) return nested;
9467
+ }
9468
+ }
9469
+ /** Like `findCategory`, but only resolves selectable leaves (never a group node). */
9470
+ function findLeafCategory(categories, key) {
9471
+ return flattenCategories(categories).find((c) => c.key === key);
9472
+ }
9473
+ //#endregion
9452
9474
  //#region src/multicol-list/types.ts
9453
9475
  const ALL_KEY = `__all__`;
9454
9476
  //#endregion
@@ -10010,7 +10032,7 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10010
10032
  const existing = existingMap.get(colState.id);
10011
10033
  if (existing) {
10012
10034
  if (existing.categoryKey !== colState.categoryKey) {
10013
- const newCategory = this.categories.find((c) => c.key === colState.categoryKey);
10035
+ const newCategory = findLeafCategory(this.categories, colState.categoryKey);
10014
10036
  if (newCategory) existing.setCategory(newCategory);
10015
10037
  }
10016
10038
  existing.updateState(colState);
@@ -10018,7 +10040,7 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10018
10040
  existingMap.delete(colState.id);
10019
10041
  continue;
10020
10042
  }
10021
- const category = this.categories.find((c) => c.key === colState.categoryKey);
10043
+ const category = findLeafCategory(this.categories, colState.categoryKey);
10022
10044
  if (!category) continue;
10023
10045
  const controller = this.#createController(colState.id, category);
10024
10046
  controller.updateState(colState);
@@ -10033,7 +10055,7 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10033
10055
  }
10034
10056
  addColumn(categoryKey, position) {
10035
10057
  if (this.maxColumns > 0 && this._columns.length >= this.maxColumns) return;
10036
- const category = this.categories.find((c) => c.key === categoryKey);
10058
+ const category = findLeafCategory(this.categories, categoryKey);
10037
10059
  if (!category) return;
10038
10060
  const id = `col-${++this._idCounter}`;
10039
10061
  const controller = this.#createController(id, category);
@@ -10075,9 +10097,10 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10075
10097
  `;
10076
10098
  }
10077
10099
  updated(changedProperties) {
10078
- if (!this._autoSeeded && this._columns.length === 0 && this.categories.length > 0) {
10100
+ const seedCategory = flattenCategories(this.categories)[0];
10101
+ if (!this._autoSeeded && this._columns.length === 0 && seedCategory) {
10079
10102
  this._autoSeeded = true;
10080
- this.addColumn(this.categories[0].key);
10103
+ this.addColumn(seedCategory.key);
10081
10104
  }
10082
10105
  if (changedProperties.has(`selectionMode`)) for (const col of this._columns) col.setSelectionMode(this.selectionMode);
10083
10106
  if (changedProperties.has(`dataProvider`)) for (const col of this._columns) col.setDataProvider(this.dataProvider);
@@ -10138,11 +10161,11 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10138
10161
  `;
10139
10162
  }
10140
10163
  _getCategoryLabel(key) {
10141
- return this.categories.find((c) => c.key === key)?.label ?? key;
10164
+ return findCategory(this.categories, key)?.label ?? key;
10142
10165
  }
10143
10166
  /** Category description if present, else the default 'Change category' hint. */
10144
10167
  _getCategoryTooltip(key) {
10145
- return this.categories.find((c) => c.key === key)?.description ?? `Change category`;
10168
+ return findCategory(this.categories, key)?.description ?? `Change category`;
10146
10169
  }
10147
10170
  #createController(id, category) {
10148
10171
  return new MulticolColumnController({
@@ -10313,7 +10336,7 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10313
10336
  container.appendChild(separator);
10314
10337
  const atMax = this.maxColumns > 0 && this._columns.length >= this.maxColumns;
10315
10338
  const usedCats = new Set(this._columns.map((c) => c.categoryKey));
10316
- const unused = this.categories.filter((c) => !usedCats.has(c.key));
10339
+ const unused = flattenCategories(this.categories).filter((c) => !usedCats.has(c.key));
10317
10340
  const canAdd = !atMax && unused.length > 0;
10318
10341
  const addSub = document.createElement(`ixfx-menu-sub-trigger`);
10319
10342
  addSub.setAttribute(`label`, `Add column`);
@@ -10357,7 +10380,7 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10357
10380
  this.addColumn(categoryKey, position);
10358
10381
  }
10359
10382
  _changeColumnCategory(col, categoryKey) {
10360
- const category = this.categories.find((c) => c.key === categoryKey);
10383
+ const category = findLeafCategory(this.categories, categoryKey);
10361
10384
  if (!category) return;
10362
10385
  col.setCategory(category);
10363
10386
  this._emitColumnsChange(`category`);
@@ -10393,10 +10416,11 @@ let MulticolListElement = class MulticolListElement extends LitElement {
10393
10416
  }
10394
10417
  _syncColumnsWithCategories() {
10395
10418
  let changed = false;
10419
+ const leaves = flattenCategories(this.categories);
10396
10420
  for (const col of this._columns) {
10397
- if (this.categories.some((c) => c.key === col.categoryKey)) continue;
10398
- if (this.categories.length === 0) continue;
10399
- col.setCategory(this.categories[0]);
10421
+ if (leaves.some((c) => c.key === col.categoryKey)) continue;
10422
+ if (leaves.length === 0) continue;
10423
+ col.setCategory(leaves[0]);
10400
10424
  changed = true;
10401
10425
  }
10402
10426
  if (changed) this._emitColumnsChange(`category`);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
- "version": "0.14.0",
4
- "generated": "2026-10-09T22:14:37.194Z",
3
+ "version": "0.14.1",
4
+ "generated": "2026-10-09T22:40:55.145Z",
5
5
  "components": [
6
6
  {
7
7
  "name": "ac-text",
@@ -17,7 +17,7 @@ provider returns that column's choices; items may carry a `count` for display.
17
17
 
18
18
  | Property | Type | Default | Description |
19
19
  |----------|------|---------|-------------|
20
- | `categories` | `readonly MulticolCategory[]` | `[]` | Facet definitions (tree, shown in the header picker menu). Each may carry `description` (shown as a tooltip on the column header label) and `defaults`: `grouped`, `groupBy`, `allLabel`, `sort`. |
20
+ | `categories` | `readonly MulticolCategory[]` | `[]` | Facet definitions (tree, shown in the header picker menu). Only leaves are selectable as a column's category; a node with `children` is just a menu group. Keys are resolved across the whole tree. Each may carry `description` (shown as a tooltip on the column header label) and `defaults`: `grouped`, `groupBy`, `allLabel`, `sort`. |
21
21
  | `dataProvider` | `IDataProvider<MulticolQuery, MulticolItem>` \| `undefined` | — | Called per column whenever that column's inputs change. Sync arrays, Promises and async-iterables are supported; the `AbortSignal` is honoured. |
22
22
  | `selectionMode` | `ListSelectionMode` | `'multiple'` | `'none'`, `'single'` or `'multiple'` selection within a column. |
23
23
  | `minColumns` | `number` | `1` | Floor for column removal. |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
3
  "type": "module",
4
- "version": "0.14.0",
4
+ "version": "0.14.1",
5
5
  "packageManager": "pnpm@10.0.0",
6
6
  "description": "Web components for ixfx — Lit-based UI toolkit",
7
7
  "author": "Clint Heyer",