@rivet-health/design-system 40.8.0 → 40.9.0

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.
@@ -5474,12 +5474,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5474
5474
  * "commit" framing over "change" is deliberate: consumers that persist on
5475
5475
  * commit (analytics, PATCH) treat the gesture itself as the event; those
5476
5476
  * that only care about diffs can compare `next === current` in the handler.
5477
- * There is no cancel path.
5478
5477
  *
5479
- * Outside-click commits (rather than cancels) to match the established DS
5480
- * interaction pattern in `riv-date` and `riv-select`. If a future consumer
5481
- * needs an abandon path, the soft first step is Escape-to-cancel rather
5482
- * than changing outside-click's meaning.
5478
+ * Escape cancels: reverts the draft back to the current value and drops out
5479
+ * of edit mode WITHOUT emitting a change. Outside-click still commits (to
5480
+ * match `riv-date` / `riv-select`); Escape is the deliberate abandon path.
5483
5481
  *
5484
5482
  * Value handling follows the same convention as `riv-text-field`: `[title]`
5485
5483
  * and `[description]` are treated as suggestions, not authoritative state.
@@ -5488,6 +5486,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5488
5486
  * a different value. That lets the component demo out of the box (e.g. in
5489
5487
  * Storybook) without requiring a round trip through the parent.
5490
5488
  *
5489
+ * Programmatic entry into edit mode is available via `startEditingTitle()`
5490
+ * and `startEditingDescription()` — obtain a reference with
5491
+ * `@ViewChild(EditableHeadingComponent)`. Use these for secondary entry
5492
+ * points like a kebab-menu "Rename" item, or to auto-open rename after
5493
+ * creating a new entity.
5494
+ *
5491
5495
  * The component owns no border, background, or card chrome — consumers who
5492
5496
  * want a bordered container should wrap it.
5493
5497
  *
@@ -5524,6 +5528,15 @@ class EditableHeadingComponent {
5524
5528
  get description() {
5525
5529
  return this._description;
5526
5530
  }
5531
+ set disabled(v) {
5532
+ this._disabled = v;
5533
+ if (v && this.mode !== 'view')
5534
+ this.cancel();
5535
+ this.cdr.markForCheck();
5536
+ }
5537
+ get disabled() {
5538
+ return this._disabled;
5539
+ }
5527
5540
  constructor(cdr, host) {
5528
5541
  this.cdr = cdr;
5529
5542
  this.host = host;
@@ -5532,6 +5545,13 @@ class EditableHeadingComponent {
5532
5545
  this._description = '';
5533
5546
  this.titleMaxLength = 100;
5534
5547
  this.descriptionMaxLength = 300;
5548
+ /**
5549
+ * When true, the title and description are not clickable and cannot be
5550
+ * edited. Any in-progress edit is dropped without emitting. Imperative
5551
+ * `startEditing*` calls no-op. Useful for consumers that need to gate
5552
+ * editing on a permission or a broader "actions disabled" state.
5553
+ */
5554
+ this._disabled = false;
5535
5555
  this.titleChange = new EventEmitter();
5536
5556
  this.descriptionChange = new EventEmitter();
5537
5557
  this.mode = 'view';
@@ -5541,15 +5561,38 @@ class EditableHeadingComponent {
5541
5561
  get isEditing() {
5542
5562
  return this.mode !== 'view';
5543
5563
  }
5564
+ /**
5565
+ * Enter title-edit mode programmatically. Same behavior as clicking the
5566
+ * title — populates the edit buffer from the current value, focuses the
5567
+ * input with the caret at the end, and hides the actions slot. No-op if
5568
+ * already in an editing mode or when the component is disabled.
5569
+ *
5570
+ * Intended for consumers that offer a secondary entry point to renaming
5571
+ * (e.g. a kebab menu item), or that want to auto-open rename after
5572
+ * creating a new entity. Bind via `@ViewChild(EditableHeadingComponent)`.
5573
+ */
5544
5574
  startEditingTitle() {
5575
+ if (this.disabled || this.mode !== 'view')
5576
+ return;
5545
5577
  this.draftTitle = this.title;
5546
5578
  this.mode = 'editingTitle';
5579
+ // `markForCheck` so consumers can call this from outside Angular's zone
5580
+ // (e.g. an async callback) without having to trigger CD themselves.
5581
+ this.cdr.markForCheck();
5547
5582
  // Defer focus until Angular has rendered the input into the DOM.
5548
5583
  setTimeout(() => this.focusEnd(this.titleInputRef), 0);
5549
5584
  }
5585
+ /**
5586
+ * Enter description-edit mode programmatically. Same behavior as clicking
5587
+ * the description (or the "+ Add description" button). No-op if already
5588
+ * in an editing mode or when the component is disabled.
5589
+ */
5550
5590
  startEditingDescription() {
5591
+ if (this.disabled || this.mode !== 'view')
5592
+ return;
5551
5593
  this.draftDescription = this.description;
5552
5594
  this.mode = 'editingDescription';
5595
+ this.cdr.markForCheck();
5553
5596
  setTimeout(() => this.focusEnd(this.descriptionInputRef), 0);
5554
5597
  }
5555
5598
  commitTitle() {
@@ -5575,6 +5618,18 @@ class EditableHeadingComponent {
5575
5618
  this.mode = 'view';
5576
5619
  this.descriptionChange.emit(value);
5577
5620
  }
5621
+ /**
5622
+ * Abandon the current edit and return to view mode. No change is emitted.
5623
+ * Wired to the Escape key on both edit inputs; also called internally
5624
+ * when `disabled` flips to true mid-edit.
5625
+ */
5626
+ cancel() {
5627
+ if (this.mode === 'view')
5628
+ return;
5629
+ this.draftTitle = this._title;
5630
+ this.draftDescription = this._description;
5631
+ this.mode = 'view';
5632
+ }
5578
5633
  // Listens on `mousedown` (not `click`) so the check runs before Angular
5579
5634
  // re-renders the trigger element out of the DOM — otherwise
5580
5635
  // `host.contains(target)` returns false for a click that landed on the
@@ -5592,23 +5647,24 @@ class EditableHeadingComponent {
5592
5647
  this.commitDescription();
5593
5648
  }
5594
5649
  }
5595
- // Focus with caret at end (rather than selecting all) so the user can
5596
- // continue typing where the previous value left off.
5650
+ // Position caret at end (rather than selecting all) so the user can continue
5651
+ // typing where the previous value left off. `riv-text-field` handles the
5652
+ // focus itself via `[autoFocus]`; we just fix up the selection range on the
5653
+ // descendant `<input>`.
5597
5654
  focusEnd(ref) {
5598
- const el = ref?.nativeElement;
5599
- if (!el)
5655
+ const input = ref?.nativeElement.querySelector('input');
5656
+ if (!input)
5600
5657
  return;
5601
- el.focus();
5602
- const len = el.value.length;
5603
- el.setSelectionRange(len, len);
5658
+ const len = input.value.length;
5659
+ input.setSelectionRange(len, len);
5604
5660
  this.cdr.markForCheck();
5605
5661
  }
5606
5662
  }
5607
5663
  EditableHeadingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EditableHeadingComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
5608
- EditableHeadingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: EditableHeadingComponent, selector: "riv-editable-heading", inputs: { title: "title", description: "description", titleMaxLength: "titleMaxLength", descriptionMaxLength: "descriptionMaxLength" }, outputs: { titleChange: "titleChange", descriptionChange: "descriptionChange" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event.target)" }, properties: { "class.editing": "this.isEditing" } }, viewQueries: [{ propertyName: "titleInputRef", first: true, predicate: ["titleInput"], descendants: true }, { propertyName: "descriptionInputRef", first: true, predicate: ["descriptionInput"], descendants: true }], ngImport: i0, template: "<div class=\"leading\">\n <ng-container [ngSwitch]=\"mode\">\n <!-- View mode -->\n <ng-container *ngSwitchDefault>\n <button\n type=\"button\"\n class=\"title\"\n [class.has-description]=\"description\"\n rivTruncate\n aria-label=\"Rename\"\n (click)=\"startEditingTitle()\"\n >\n {{ title || 'Untitled' }}\n </button>\n\n <div class=\"divider\"></div>\n\n <button\n *ngIf=\"description; else addDescription\"\n type=\"button\"\n class=\"description\"\n rivTruncate\n aria-label=\"Edit description\"\n (click)=\"startEditingDescription()\"\n >\n {{ description }}\n </button>\n\n <ng-template #addDescription>\n <div class=\"add-description-wrap\">\n <button\n rivButton\n [variant]=\"'ghost'\"\n [size]=\"'xsmall'\"\n [icon]=\"'Plus'\"\n [iconPosition]=\"'first'\"\n type=\"button\"\n (click)=\"startEditingDescription()\"\n >\n Add description\n </button>\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Editing title -->\n <ng-container *ngSwitchCase=\"'editingTitle'\">\n <input\n #titleInput\n class=\"title-input\"\n type=\"text\"\n aria-label=\"Title\"\n [value]=\"draftTitle\"\n [attr.maxlength]=\"titleMaxLength\"\n (input)=\"draftTitle = titleInput.value\"\n (keydown.enter)=\"commitTitle()\"\n />\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n [disabled]=\"!draftTitle\"\n (click)=\"commitTitle()\"\n aria-label=\"Save title\"\n ></button>\n </ng-container>\n\n <!-- Editing description -->\n <ng-container *ngSwitchCase=\"'editingDescription'\">\n <input\n #descriptionInput\n class=\"description-input\"\n type=\"text\"\n aria-label=\"Description\"\n [value]=\"draftDescription\"\n [attr.maxlength]=\"descriptionMaxLength\"\n placeholder=\"Add a description\"\n (input)=\"draftDescription = descriptionInput.value\"\n (keydown.enter)=\"commitDescription()\"\n />\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n (click)=\"commitDescription()\"\n aria-label=\"Save description\"\n ></button>\n </ng-container>\n </ng-container>\n</div>\n\n<div class=\"actions\" *ngIf=\"!isEditing\">\n <ng-content select=\"[actions]\"></ng-content>\n</div>\n", styles: [":host{display:flex;align-items:stretch;gap:var(--size-large);min-height:calc(var(--base-grid-size) * 8);font:var(--body-medium)}.leading{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:var(--size-small)}.title,.description{padding:0;border:none;background:none;text-align:left;cursor:pointer;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.title{font:var(--stat-xsmall);line-height:calc(var(--base-grid-size) * 4.5);color:var(--type-light-high-contrast);max-width:100%}.title.has-description{width:-moz-fit-content;width:fit-content;max-width:50%;flex-shrink:0}.description{font:var(--input-small);line-height:calc(var(--base-grid-size) * 3.5);color:var(--type-light-low-contrast);flex:1 1 auto}.divider{align-self:stretch;border-right:var(--border-width) solid var(--border-light);margin:0 var(--base-grid-size) 0 0;flex-shrink:0}.add-description-wrap{flex-shrink:0}.title-input,.description-input{border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);padding:var(--size-small) var(--size-medium);color:var(--type-light-high-contrast);outline:none;min-width:0}.title-input{font:var(--stat-xsmall);flex:1 1 auto}.description-input{font:var(--input-small);flex:1 1 auto}.title-input:focus,.description-input:focus{border-color:var(--purp-60)}.commit{flex-shrink:0}.actions{display:flex;align-items:center;gap:var(--size-small);flex-shrink:0}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition", "current"] }, { kind: "component", type: TruncateComponent, selector: "[rivTruncate]", inputs: ["maxTooltipWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5664
+ EditableHeadingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: EditableHeadingComponent, selector: "riv-editable-heading", inputs: { title: "title", description: "description", titleMaxLength: "titleMaxLength", descriptionMaxLength: "descriptionMaxLength", disabled: "disabled" }, outputs: { titleChange: "titleChange", descriptionChange: "descriptionChange" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event.target)" }, properties: { "class.editing": "this.isEditing" } }, viewQueries: [{ propertyName: "titleInputRef", first: true, predicate: ["titleInput"], descendants: true, read: ElementRef }, { propertyName: "descriptionInputRef", first: true, predicate: ["descriptionInput"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"leading\">\n <ng-container [ngSwitch]=\"mode\">\n <!-- View mode -->\n <ng-container *ngSwitchDefault>\n <button\n type=\"button\"\n class=\"title\"\n [class.has-description]=\"description\"\n [disabled]=\"disabled\"\n rivTruncate\n aria-label=\"Rename\"\n (click)=\"startEditingTitle()\"\n >\n {{ title || 'Untitled' }}\n </button>\n\n <div class=\"divider\"></div>\n\n <button\n *ngIf=\"description; else addDescription\"\n type=\"button\"\n class=\"description\"\n [disabled]=\"disabled\"\n rivTruncate\n aria-label=\"Edit description\"\n (click)=\"startEditingDescription()\"\n >\n {{ description }}\n </button>\n\n <ng-template #addDescription>\n <div class=\"add-description-wrap\" *ngIf=\"!disabled\">\n <button\n rivButton\n [variant]=\"'ghost'\"\n [size]=\"'xsmall'\"\n [icon]=\"'Plus'\"\n [iconPosition]=\"'first'\"\n type=\"button\"\n (click)=\"startEditingDescription()\"\n >\n Add description\n </button>\n </div>\n </ng-template>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'editingTitle'\">\n <riv-text-field\n #titleInput\n class=\"title-input\"\n [value]=\"draftTitle\"\n [maxLength]=\"titleMaxLength\"\n [autoFocus]=\"true\"\n (valueChange)=\"draftTitle = $event\"\n (keydown.enter)=\"commitTitle()\"\n (keydown.escape)=\"cancel()\"\n ></riv-text-field>\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n [disabled]=\"!draftTitle\"\n (click)=\"commitTitle()\"\n aria-label=\"Save title\"\n ></button>\n </ng-container>\n\n <!-- Editing description -->\n <ng-container *ngSwitchCase=\"'editingDescription'\">\n <riv-text-field\n #descriptionInput\n class=\"description-input\"\n placeholder=\"Add a description\"\n [value]=\"draftDescription\"\n [maxLength]=\"descriptionMaxLength\"\n [autoFocus]=\"true\"\n (valueChange)=\"draftDescription = $event\"\n (keydown.enter)=\"commitDescription()\"\n (keydown.escape)=\"cancel()\"\n ></riv-text-field>\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n (click)=\"commitDescription()\"\n aria-label=\"Save description\"\n ></button>\n </ng-container>\n </ng-container>\n</div>\n\n<div class=\"actions\" *ngIf=\"!isEditing\">\n <ng-content select=\"[actions]\"></ng-content>\n</div>\n", styles: [":host{display:flex;align-items:stretch;gap:var(--size-large);min-height:calc(var(--base-grid-size) * 8);font:var(--body-medium)}.leading{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:var(--size-small)}.title,.description{padding:0;border:none;background:none;text-align:left;cursor:pointer;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.title:disabled,.description:disabled{cursor:default}.title{font:var(--stat-xsmall);line-height:calc(var(--base-grid-size) * 4.5);color:var(--type-light-high-contrast);max-width:100%}.title.has-description{width:-moz-fit-content;width:fit-content;max-width:50%;flex-shrink:0}.description{font:var(--input-small);line-height:calc(var(--base-grid-size) * 3.5);color:var(--type-light-low-contrast);flex:1 1 auto}.divider{align-self:stretch;border-right:var(--border-width) solid var(--border-light);margin:0 var(--base-grid-size) 0 0;flex-shrink:0}.add-description-wrap{flex-shrink:0}.title-input,.description-input{flex:1 1 auto;min-width:0}.commit{flex-shrink:0}.actions{display:flex;align-items:center;gap:var(--size-small);flex-shrink:0}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition", "current"] }, { kind: "component", type: TextFieldComponent, selector: "riv-text-field", inputs: ["disabled", "readonly", "placeholder", "casing", "type", "size", "autoFocus", "name", "minLength", "maxLength", "value"], outputs: ["valueChange", "blur"] }, { kind: "component", type: TruncateComponent, selector: "[rivTruncate]", inputs: ["maxTooltipWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5609
5665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EditableHeadingComponent, decorators: [{
5610
5666
  type: Component,
5611
- args: [{ selector: 'riv-editable-heading', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"leading\">\n <ng-container [ngSwitch]=\"mode\">\n <!-- View mode -->\n <ng-container *ngSwitchDefault>\n <button\n type=\"button\"\n class=\"title\"\n [class.has-description]=\"description\"\n rivTruncate\n aria-label=\"Rename\"\n (click)=\"startEditingTitle()\"\n >\n {{ title || 'Untitled' }}\n </button>\n\n <div class=\"divider\"></div>\n\n <button\n *ngIf=\"description; else addDescription\"\n type=\"button\"\n class=\"description\"\n rivTruncate\n aria-label=\"Edit description\"\n (click)=\"startEditingDescription()\"\n >\n {{ description }}\n </button>\n\n <ng-template #addDescription>\n <div class=\"add-description-wrap\">\n <button\n rivButton\n [variant]=\"'ghost'\"\n [size]=\"'xsmall'\"\n [icon]=\"'Plus'\"\n [iconPosition]=\"'first'\"\n type=\"button\"\n (click)=\"startEditingDescription()\"\n >\n Add description\n </button>\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Editing title -->\n <ng-container *ngSwitchCase=\"'editingTitle'\">\n <input\n #titleInput\n class=\"title-input\"\n type=\"text\"\n aria-label=\"Title\"\n [value]=\"draftTitle\"\n [attr.maxlength]=\"titleMaxLength\"\n (input)=\"draftTitle = titleInput.value\"\n (keydown.enter)=\"commitTitle()\"\n />\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n [disabled]=\"!draftTitle\"\n (click)=\"commitTitle()\"\n aria-label=\"Save title\"\n ></button>\n </ng-container>\n\n <!-- Editing description -->\n <ng-container *ngSwitchCase=\"'editingDescription'\">\n <input\n #descriptionInput\n class=\"description-input\"\n type=\"text\"\n aria-label=\"Description\"\n [value]=\"draftDescription\"\n [attr.maxlength]=\"descriptionMaxLength\"\n placeholder=\"Add a description\"\n (input)=\"draftDescription = descriptionInput.value\"\n (keydown.enter)=\"commitDescription()\"\n />\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n (click)=\"commitDescription()\"\n aria-label=\"Save description\"\n ></button>\n </ng-container>\n </ng-container>\n</div>\n\n<div class=\"actions\" *ngIf=\"!isEditing\">\n <ng-content select=\"[actions]\"></ng-content>\n</div>\n", styles: [":host{display:flex;align-items:stretch;gap:var(--size-large);min-height:calc(var(--base-grid-size) * 8);font:var(--body-medium)}.leading{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:var(--size-small)}.title,.description{padding:0;border:none;background:none;text-align:left;cursor:pointer;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.title{font:var(--stat-xsmall);line-height:calc(var(--base-grid-size) * 4.5);color:var(--type-light-high-contrast);max-width:100%}.title.has-description{width:-moz-fit-content;width:fit-content;max-width:50%;flex-shrink:0}.description{font:var(--input-small);line-height:calc(var(--base-grid-size) * 3.5);color:var(--type-light-low-contrast);flex:1 1 auto}.divider{align-self:stretch;border-right:var(--border-width) solid var(--border-light);margin:0 var(--base-grid-size) 0 0;flex-shrink:0}.add-description-wrap{flex-shrink:0}.title-input,.description-input{border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);padding:var(--size-small) var(--size-medium);color:var(--type-light-high-contrast);outline:none;min-width:0}.title-input{font:var(--stat-xsmall);flex:1 1 auto}.description-input{font:var(--input-small);flex:1 1 auto}.title-input:focus,.description-input:focus{border-color:var(--purp-60)}.commit{flex-shrink:0}.actions{display:flex;align-items:center;gap:var(--size-small);flex-shrink:0}\n"] }]
5667
+ args: [{ selector: 'riv-editable-heading', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"leading\">\n <ng-container [ngSwitch]=\"mode\">\n <!-- View mode -->\n <ng-container *ngSwitchDefault>\n <button\n type=\"button\"\n class=\"title\"\n [class.has-description]=\"description\"\n [disabled]=\"disabled\"\n rivTruncate\n aria-label=\"Rename\"\n (click)=\"startEditingTitle()\"\n >\n {{ title || 'Untitled' }}\n </button>\n\n <div class=\"divider\"></div>\n\n <button\n *ngIf=\"description; else addDescription\"\n type=\"button\"\n class=\"description\"\n [disabled]=\"disabled\"\n rivTruncate\n aria-label=\"Edit description\"\n (click)=\"startEditingDescription()\"\n >\n {{ description }}\n </button>\n\n <ng-template #addDescription>\n <div class=\"add-description-wrap\" *ngIf=\"!disabled\">\n <button\n rivButton\n [variant]=\"'ghost'\"\n [size]=\"'xsmall'\"\n [icon]=\"'Plus'\"\n [iconPosition]=\"'first'\"\n type=\"button\"\n (click)=\"startEditingDescription()\"\n >\n Add description\n </button>\n </div>\n </ng-template>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'editingTitle'\">\n <riv-text-field\n #titleInput\n class=\"title-input\"\n [value]=\"draftTitle\"\n [maxLength]=\"titleMaxLength\"\n [autoFocus]=\"true\"\n (valueChange)=\"draftTitle = $event\"\n (keydown.enter)=\"commitTitle()\"\n (keydown.escape)=\"cancel()\"\n ></riv-text-field>\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n [disabled]=\"!draftTitle\"\n (click)=\"commitTitle()\"\n aria-label=\"Save title\"\n ></button>\n </ng-container>\n\n <!-- Editing description -->\n <ng-container *ngSwitchCase=\"'editingDescription'\">\n <riv-text-field\n #descriptionInput\n class=\"description-input\"\n placeholder=\"Add a description\"\n [value]=\"draftDescription\"\n [maxLength]=\"descriptionMaxLength\"\n [autoFocus]=\"true\"\n (valueChange)=\"draftDescription = $event\"\n (keydown.enter)=\"commitDescription()\"\n (keydown.escape)=\"cancel()\"\n ></riv-text-field>\n <button\n rivButton\n type=\"button\"\n class=\"commit\"\n [variant]=\"'primary'\"\n [icon]=\"'Check'\"\n (click)=\"commitDescription()\"\n aria-label=\"Save description\"\n ></button>\n </ng-container>\n </ng-container>\n</div>\n\n<div class=\"actions\" *ngIf=\"!isEditing\">\n <ng-content select=\"[actions]\"></ng-content>\n</div>\n", styles: [":host{display:flex;align-items:stretch;gap:var(--size-large);min-height:calc(var(--base-grid-size) * 8);font:var(--body-medium)}.leading{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:var(--size-small)}.title,.description{padding:0;border:none;background:none;text-align:left;cursor:pointer;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.title:disabled,.description:disabled{cursor:default}.title{font:var(--stat-xsmall);line-height:calc(var(--base-grid-size) * 4.5);color:var(--type-light-high-contrast);max-width:100%}.title.has-description{width:-moz-fit-content;width:fit-content;max-width:50%;flex-shrink:0}.description{font:var(--input-small);line-height:calc(var(--base-grid-size) * 3.5);color:var(--type-light-low-contrast);flex:1 1 auto}.divider{align-self:stretch;border-right:var(--border-width) solid var(--border-light);margin:0 var(--base-grid-size) 0 0;flex-shrink:0}.add-description-wrap{flex-shrink:0}.title-input,.description-input{flex:1 1 auto;min-width:0}.commit{flex-shrink:0}.actions{display:flex;align-items:center;gap:var(--size-small);flex-shrink:0}\n"] }]
5612
5668
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { title: [{
5613
5669
  type: Input
5614
5670
  }], description: [{
@@ -5617,16 +5673,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5617
5673
  type: Input
5618
5674
  }], descriptionMaxLength: [{
5619
5675
  type: Input
5676
+ }], disabled: [{
5677
+ type: Input
5620
5678
  }], titleChange: [{
5621
5679
  type: Output
5622
5680
  }], descriptionChange: [{
5623
5681
  type: Output
5624
5682
  }], titleInputRef: [{
5625
5683
  type: ViewChild,
5626
- args: ['titleInput']
5684
+ args: ['titleInput', { read: ElementRef }]
5627
5685
  }], descriptionInputRef: [{
5628
5686
  type: ViewChild,
5629
- args: ['descriptionInput']
5687
+ args: ['descriptionInput', { read: ElementRef }]
5630
5688
  }], isEditing: [{
5631
5689
  type: HostBinding,
5632
5690
  args: ['class.editing']