@truenas/ui-components 0.1.77 → 0.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truenas/ui-components",
3
- "version": "0.1.77",
3
+ "version": "0.2.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public"
@@ -3571,6 +3571,17 @@ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor, On
3571
3571
  * with i18n requirements can pass a translated string.
3572
3572
  */
3573
3573
  noOptionsLabel: _angular_core.InputSignal<string>;
3574
+ /**
3575
+ * When `true` (single-select mode only), prepends a synthetic "empty"
3576
+ * option to the dropdown so users can unset a chosen value: picking it
3577
+ * resets the selection to `null`, shows the placeholder again, and emits
3578
+ * `null` via `selectionChange` (and to any bound form control). Mirrors
3579
+ * webui ix-select's `--` option. Ignored when `multiple` is set — there,
3580
+ * values are cleared by toggling them off individually.
3581
+ */
3582
+ allowEmpty: _angular_core.InputSignal<boolean>;
3583
+ /** Label of the empty option rendered when `allowEmpty` is set. */
3584
+ emptyLabel: _angular_core.InputSignal<string>;
3574
3585
  disabled: _angular_core.InputSignal<boolean>;
3575
3586
  testId: _angular_core.InputSignal<TnTestIdValue>;
3576
3587
  multiple: _angular_core.InputSignal<boolean>;
@@ -3600,7 +3611,11 @@ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor, On
3600
3611
  * ```
3601
3612
  */
3602
3613
  compareWith: _angular_core.InputSignal<((a: T | null, b: T | null) => boolean) | undefined>;
3603
- selectionChange: _angular_core.OutputEmitterRef<T>;
3614
+ /**
3615
+ * Emits the picked value on each selection in single mode. Emits `null`
3616
+ * when the user picks the `allowEmpty` empty option to clear the field.
3617
+ */
3618
+ selectionChange: _angular_core.OutputEmitterRef<T | null>;
3604
3619
  /** Emits the full array of selected values after each toggle in multiple mode. */
3605
3620
  multiSelectionChange: _angular_core.OutputEmitterRef<T[]>;
3606
3621
  protected isOpen: _angular_core.WritableSignal<boolean>;
@@ -3620,6 +3635,17 @@ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor, On
3620
3635
  */
3621
3636
  protected idNamespace: _angular_core.Signal<string>;
3622
3637
  isDisabled: _angular_core.Signal<boolean>;
3638
+ /**
3639
+ * The synthetic clear-selection option (`allowEmpty`, single mode only).
3640
+ * Its value is `null` cast to `T` so it flows through the same selection
3641
+ * path as real options — `selectedValue`/`writeValue` already model "no
3642
+ * selection" as `null`, so picking it clears the field for free.
3643
+ */
3644
+ protected emptyOption: _angular_core.Signal<TnSelectOption<T> | null>;
3645
+ /** Ungrouped options as rendered: the empty option (when enabled) first. */
3646
+ protected displayOptions: _angular_core.Signal<TnSelectOption<T>[]>;
3647
+ /** Whether `option` is the synthetic `allowEmpty` clear option. */
3648
+ protected isEmptyOption(option: TnSelectOption<T>): boolean;
3623
3649
  /**
3624
3650
  * Selectable, non-disabled options in display order (regular options first,
3625
3651
  * then groups). Used by keyboard navigation so we can skip disabled
@@ -3730,7 +3756,7 @@ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor, On
3730
3756
  private activateFocusedOption;
3731
3757
  private scrollFocusedIntoView;
3732
3758
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSelectComponent<any>, never>;
3733
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSelectComponent<any>, "tn-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionGroups": { "alias": "optionGroups"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "noOptionsLabel": { "alias": "noOptionsLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "optionTestIdKey": { "alias": "optionTestIdKey"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "multiSelectionChange": "multiSelectionChange"; }, never, never, true, never>;
3759
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSelectComponent<any>, "tn-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionGroups": { "alias": "optionGroups"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "noOptionsLabel": { "alias": "noOptionsLabel"; "required": false; "isSignal": true; }; "allowEmpty": { "alias": "allowEmpty"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "optionTestIdKey": { "alias": "optionTestIdKey"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "multiSelectionChange": "multiSelectionChange"; }, never, never, true, never>;
3734
3760
  }
3735
3761
 
3736
3762
  /**
@@ -3864,6 +3890,22 @@ declare class TnSelectHarness extends ComponentHarness {
3864
3890
  * ```
3865
3891
  */
3866
3892
  selectOption(filter: string | RegExp): Promise<void>;
3893
+ /**
3894
+ * Clears the selection by picking the empty option. Only available when
3895
+ * the select has `allowEmpty` set (single mode); throws otherwise.
3896
+ * Opens the dropdown if needed.
3897
+ *
3898
+ * @returns Promise that resolves when the selection has been cleared.
3899
+ *
3900
+ * @example
3901
+ * ```typescript
3902
+ * const select = await loader.getHarness(TnSelectHarness);
3903
+ * await select.selectOption('Banana');
3904
+ * await select.clear();
3905
+ * expect(await select.getDisplayText()).toBe('Select a fruit'); // placeholder
3906
+ * ```
3907
+ */
3908
+ clear(): Promise<void>;
3867
3909
  /**
3868
3910
  * Gets the labels of all available options. Opens the dropdown if needed.
3869
3911
  *
@@ -5898,7 +5940,7 @@ declare class TnTimeInputComponent implements ControlValueAccessor {
5898
5940
  registerOnChange(fn: (value: string) => void): void;
5899
5941
  registerOnTouched(fn: () => void): void;
5900
5942
  setDisabledState(isDisabled: boolean): void;
5901
- onSelectionChange(value: string): void;
5943
+ onSelectionChange(value: string | null): void;
5902
5944
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTimeInputComponent, never>;
5903
5945
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTimeInputComponent, "tn-time-input", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "granularity": { "alias": "granularity"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5904
5946
  }