@truenas/ui-components 0.7.8 → 0.7.9

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.
@@ -16477,6 +16477,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
16477
16477
  * The primary-text slot is the deliberate exception — it has no gate, so
16478
16478
  * `[tnListItemTitle]` and `[tnListItemPrimary]` render either way. See the
16479
16479
  * comment in `list-item.component.html` for why the asymmetry is there.
16480
+ *
16481
+ * `[testId]` names the row for automation. It lands on the host, which is both
16482
+ * the click target (`(click)` is a host binding) and the `listitem` — so one id
16483
+ * addresses the row whether a suite clicks it or reads what it renders. The
16484
+ * value is written verbatim, with no element-type prefix, matching the other
16485
+ * components whose host *is* the target (`tn-tree-node`, `tn-table`): a row of
16486
+ * a list is not a control whose type the library can name, and its meaning
16487
+ * comes from the list it sits in, which only the consumer knows.
16480
16488
  */
16481
16489
  class TnListItemComponent {
16482
16490
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
@@ -16522,11 +16530,11 @@ class TnListItemComponent {
16522
16530
  }
16523
16531
  }
16524
16532
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16525
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnListItemComponent, isStandalone: true, selector: "tn-list-item", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { attributes: { "role": "listitem" }, listeners: { "click": "onClick($event)" }, properties: { "class.tn-list-item--disabled": "disabled()", "class.tn-list-item--clickable": "clickable()", "class.tn-list-item--dense": "dense()", "class.tn-list-item--wrap": "wrap()", "class.tn-list-item--two-line": "hasSecondaryText()", "class.tn-list-item--three-line": "hasThirdText()" }, classAttribute: "tn-list-item" }, queries: [{ propertyName: "leadingIcons", predicate: TnListIconDirective, descendants: true, isSignal: true }, { propertyName: "leadingAvatars", predicate: TnListAvatarDirective, descendants: true, isSignal: true }, { propertyName: "secondaryLines", predicate: TnListItemLineDirective, descendants: true, isSignal: true }, { propertyName: "secondaryTexts", predicate: TnListItemSecondaryDirective, descendants: true, isSignal: true }, { propertyName: "trailing", predicate: TnListItemTrailingDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tn-list-item__content\">\n <!-- Leading icon/avatar slot -->\n @if (hasLeadingContent()) {\n <div class=\"tn-list-item__leading\">\n <ng-content select=\"[tnListIcon], [tnListAvatar]\" />\n </div>\n }\n\n <!-- Text content -->\n <div class=\"tn-list-item__text\">\n <!--\n Primary text. The catch-all slot needs no guard: a projected node is\n assigned to exactly one slot, so anything carrying [tnListItemTitle] or\n [tnListItemPrimary] lands in the slot above and can never reach the\n catch-all. Gating this on a directive query would instead key projection\n and rendering off two different things \u2014 the slot matches the attribute,\n a contentChildren query matches the directive instance \u2014 so an attribute\n written without its directive imported would toggle the guard while\n projecting exactly as before.\n\n The leading, secondary and trailing slots below are still gated that way,\n deliberately: their wrappers carry gutters that would space out every row\n if rendered empty. The cost is that they require the directive to be\n imported, which is documented on the component and on each directive.\n -->\n <div class=\"tn-list-item__primary-text\">\n <ng-content select=\"[tnListItemTitle], [tnListItemPrimary]\" />\n <ng-content />\n </div>\n\n <!-- Secondary text -->\n @if (hasSecondaryText()) {\n <div class=\"tn-list-item__secondary-text\">\n <ng-content select=\"[tnListItemLine], [tnListItemSecondary]\" />\n </div>\n }\n </div>\n\n <!-- Trailing content slot -->\n @if (hasTrailingContent()) {\n <div class=\"tn-list-item__trailing\">\n <ng-content select=\"[tnListItemTrailing]\" />\n </div>\n }\n</div>", styles: [".tn-list-item{display:block;position:relative;min-height:48px;padding:0;cursor:default;text-decoration:none;color:var(--tn-fg1);transition:background-color .2s ease}.tn-list-item__content{display:flex;align-items:center;padding:8px 16px;min-height:inherit;box-sizing:border-box}.tn-list-item__leading{flex-shrink:0;margin-right:16px;display:flex;align-items:center;justify-content:center}.tn-list-item__text{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.tn-list-item__primary-text{font-size:1rem;font-weight:400;line-height:1.5;color:var(--tn-fg1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-list-item__secondary-text{font-size:14px;font-weight:400;line-height:1.4;color:var(--tn-fg2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-list-item__trailing{flex-shrink:0;margin-left:16px;display:flex;align-items:center}.tn-list-item--clickable{cursor:pointer}.tn-list-item--clickable:hover:not(.tn-list-item--disabled){background-color:var(--tn-alt-bg1)}.tn-list-item--clickable:focus{outline:none;background-color:var(--tn-alt-bg1)}.tn-list-item--clickable:active:not(.tn-list-item--disabled){background-color:var(--tn-alt-bg2)}.tn-list-item--two-line{min-height:64px}.tn-list-item--two-line .tn-list-item__primary-text{white-space:normal;line-height:1.4}.tn-list-item--two-line .tn-list-item__secondary-text{white-space:normal;line-height:1.3}.tn-list-item--three-line{min-height:88px}.tn-list-item--three-line .tn-list-item__text{align-items:flex-start;padding:8px 0}.tn-list-item--three-line .tn-list-item__primary-text{white-space:normal;line-height:1.4}.tn-list-item--three-line .tn-list-item__secondary-text{white-space:normal;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.tn-list-item--dense{min-height:32px}.tn-list-item--dense .tn-list-item__content{padding:4px 16px}.tn-list-item--dense .tn-list-item__leading{margin-right:8px}.tn-list-item--dense .tn-list-item__trailing{margin-left:8px}.tn-list-item--wrap .tn-list-item__primary-text,.tn-list-item--wrap .tn-list-item__secondary-text{overflow:visible;text-overflow:clip;white-space:normal}.tn-list-item--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}::ng-deep [tnListIcon]{width:24px;height:24px;font-size:24px;color:var(--tn-fg2);display:flex;align-items:center;justify-content:center}::ng-deep [tnListAvatar]{width:40px;height:40px;border-radius:50%;object-fit:cover;background-color:var(--tn-alt-bg1);color:var(--tn-fg1);display:flex;align-items:center;justify-content:center;font-weight:500}::ng-deep [tnListItemTitle]{font-weight:400}::ng-deep [tnListItemLine]{display:block;margin-top:4px;font-size:14px;color:var(--tn-fg2);line-height:1.4}::ng-deep [tnListItemTrailing]{color:var(--tn-fg2);font-size:14px}\n"] });
16533
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnListItemComponent, isStandalone: true, selector: "tn-list-item", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { attributes: { "role": "listitem" }, listeners: { "click": "onClick($event)" }, properties: { "class.tn-list-item--disabled": "disabled()", "class.tn-list-item--clickable": "clickable()", "class.tn-list-item--dense": "dense()", "class.tn-list-item--wrap": "wrap()", "class.tn-list-item--two-line": "hasSecondaryText()", "class.tn-list-item--three-line": "hasThirdText()" }, classAttribute: "tn-list-item" }, queries: [{ propertyName: "leadingIcons", predicate: TnListIconDirective, descendants: true, isSignal: true }, { propertyName: "leadingAvatars", predicate: TnListAvatarDirective, descendants: true, isSignal: true }, { propertyName: "secondaryLines", predicate: TnListItemLineDirective, descendants: true, isSignal: true }, { propertyName: "secondaryTexts", predicate: TnListItemSecondaryDirective, descendants: true, isSignal: true }, { propertyName: "trailing", predicate: TnListItemTrailingDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: TnTestIdDirective, inputs: ["tnTestId", "testId"] }], ngImport: i0, template: "<div class=\"tn-list-item__content\">\n <!-- Leading icon/avatar slot -->\n @if (hasLeadingContent()) {\n <div class=\"tn-list-item__leading\">\n <ng-content select=\"[tnListIcon], [tnListAvatar]\" />\n </div>\n }\n\n <!-- Text content -->\n <div class=\"tn-list-item__text\">\n <!--\n Primary text. The catch-all slot needs no guard: a projected node is\n assigned to exactly one slot, so anything carrying [tnListItemTitle] or\n [tnListItemPrimary] lands in the slot above and can never reach the\n catch-all. Gating this on a directive query would instead key projection\n and rendering off two different things \u2014 the slot matches the attribute,\n a contentChildren query matches the directive instance \u2014 so an attribute\n written without its directive imported would toggle the guard while\n projecting exactly as before.\n\n The leading, secondary and trailing slots below are still gated that way,\n deliberately: their wrappers carry gutters that would space out every row\n if rendered empty. The cost is that they require the directive to be\n imported, which is documented on the component and on each directive.\n -->\n <div class=\"tn-list-item__primary-text\">\n <ng-content select=\"[tnListItemTitle], [tnListItemPrimary]\" />\n <ng-content />\n </div>\n\n <!-- Secondary text -->\n @if (hasSecondaryText()) {\n <div class=\"tn-list-item__secondary-text\">\n <ng-content select=\"[tnListItemLine], [tnListItemSecondary]\" />\n </div>\n }\n </div>\n\n <!-- Trailing content slot -->\n @if (hasTrailingContent()) {\n <div class=\"tn-list-item__trailing\">\n <ng-content select=\"[tnListItemTrailing]\" />\n </div>\n }\n</div>", styles: [".tn-list-item{display:block;position:relative;min-height:48px;padding:0;cursor:default;text-decoration:none;color:var(--tn-fg1);transition:background-color .2s ease}.tn-list-item__content{display:flex;align-items:center;padding:8px 16px;min-height:inherit;box-sizing:border-box}.tn-list-item__leading{flex-shrink:0;margin-right:16px;display:flex;align-items:center;justify-content:center}.tn-list-item__text{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.tn-list-item__primary-text{font-size:1rem;font-weight:400;line-height:1.5;color:var(--tn-fg1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-list-item__secondary-text{font-size:14px;font-weight:400;line-height:1.4;color:var(--tn-fg2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-list-item__trailing{flex-shrink:0;margin-left:16px;display:flex;align-items:center}.tn-list-item--clickable{cursor:pointer}.tn-list-item--clickable:hover:not(.tn-list-item--disabled){background-color:var(--tn-alt-bg1)}.tn-list-item--clickable:focus{outline:none;background-color:var(--tn-alt-bg1)}.tn-list-item--clickable:active:not(.tn-list-item--disabled){background-color:var(--tn-alt-bg2)}.tn-list-item--two-line{min-height:64px}.tn-list-item--two-line .tn-list-item__primary-text{white-space:normal;line-height:1.4}.tn-list-item--two-line .tn-list-item__secondary-text{white-space:normal;line-height:1.3}.tn-list-item--three-line{min-height:88px}.tn-list-item--three-line .tn-list-item__text{align-items:flex-start;padding:8px 0}.tn-list-item--three-line .tn-list-item__primary-text{white-space:normal;line-height:1.4}.tn-list-item--three-line .tn-list-item__secondary-text{white-space:normal;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.tn-list-item--dense{min-height:32px}.tn-list-item--dense .tn-list-item__content{padding:4px 16px}.tn-list-item--dense .tn-list-item__leading{margin-right:8px}.tn-list-item--dense .tn-list-item__trailing{margin-left:8px}.tn-list-item--wrap .tn-list-item__primary-text,.tn-list-item--wrap .tn-list-item__secondary-text{overflow:visible;text-overflow:clip;white-space:normal}.tn-list-item--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}::ng-deep [tnListIcon]{width:24px;height:24px;font-size:24px;color:var(--tn-fg2);display:flex;align-items:center;justify-content:center}::ng-deep [tnListAvatar]{width:40px;height:40px;border-radius:50%;object-fit:cover;background-color:var(--tn-alt-bg1);color:var(--tn-fg1);display:flex;align-items:center;justify-content:center;font-weight:500}::ng-deep [tnListItemTitle]{font-weight:400}::ng-deep [tnListItemLine]{display:block;margin-top:4px;font-size:14px;color:var(--tn-fg2);line-height:1.4}::ng-deep [tnListItemTrailing]{color:var(--tn-fg2);font-size:14px}\n"] });
16526
16534
  }
16527
16535
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnListItemComponent, decorators: [{
16528
16536
  type: Component,
16529
- args: [{ selector: 'tn-list-item', standalone: true, imports: [], host: {
16537
+ args: [{ selector: 'tn-list-item', standalone: true, imports: [], hostDirectives: [{ directive: TnTestIdDirective, inputs: ['tnTestId: testId'] }], host: {
16530
16538
  'class': 'tn-list-item',
16531
16539
  '[class.tn-list-item--disabled]': 'disabled()',
16532
16540
  '[class.tn-list-item--clickable]': 'clickable()',