@truenas/ui-components 0.3.8 → 0.3.10

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.3.8",
3
+ "version": "0.3.10",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public"
@@ -1054,6 +1054,17 @@ declare class TnButtonComponent implements AfterViewInit {
1054
1054
  variant: _angular_core.InputSignal<"filled" | "outline">;
1055
1055
  backgroundColor: _angular_core.InputSignal<string | undefined>;
1056
1056
  label: _angular_core.InputSignal<string>;
1057
+ /**
1058
+ * Optional icon rendered alongside the label. Accepts any name resolvable by
1059
+ * `tn-icon` (sprite/registry/library). Use `iconPosition` to place it before
1060
+ * or after the label.
1061
+ */
1062
+ icon: _angular_core.InputSignal<string | undefined>;
1063
+ /**
1064
+ * Side of the label the `icon` sits on. `left` (default) renders the icon
1065
+ * before the label; `right` renders it after. No effect when `icon` is unset.
1066
+ */
1067
+ iconPosition: _angular_core.InputSignal<"left" | "right">;
1057
1068
  disabled: _angular_core.InputSignal<boolean>;
1058
1069
  /**
1059
1070
  * Native `type` of the rendered `<button>`. Defaults to `button` so stray
@@ -1099,7 +1110,7 @@ declare class TnButtonComponent implements AfterViewInit {
1099
1110
  private innerRef;
1100
1111
  ngAfterViewInit(): void;
1101
1112
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnButtonComponent, never>;
1102
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnButtonComponent, "tn-button", never, { "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "backgroundColor": { "alias": "backgroundColor"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "queryParams": { "alias": "queryParams"; "required": false; "isSignal": true; }; "fragment": { "alias": "fragment"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; "rel": { "alias": "rel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, never, true, never>;
1113
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnButtonComponent, "tn-button", never, { "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "backgroundColor": { "alias": "backgroundColor"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "queryParams": { "alias": "queryParams"; "required": false; "isSignal": true; }; "fragment": { "alias": "fragment"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; "rel": { "alias": "rel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, never, true, never>;
1103
1114
  }
1104
1115
 
1105
1116
  /**
@@ -1126,6 +1137,8 @@ declare class TnButtonHarness extends ComponentHarness {
1126
1137
  */
1127
1138
  static hostSelector: string;
1128
1139
  private _button;
1140
+ private _label;
1141
+ private _icon;
1129
1142
  /**
1130
1143
  * Gets a `HarnessPredicate` that can be used to search for a button
1131
1144
  * with specific attributes.
@@ -1156,6 +1169,27 @@ declare class TnButtonHarness extends ComponentHarness {
1156
1169
  * ```
1157
1170
  */
1158
1171
  getLabel(): Promise<string>;
1172
+ /**
1173
+ * Gets the `name` of the icon rendered inside the button, or `null` when the
1174
+ * button has no icon.
1175
+ *
1176
+ * @example
1177
+ * ```typescript
1178
+ * const saveBtn = await loader.getHarness(TnButtonHarness.with({ label: 'Save' }));
1179
+ * expect(await saveBtn.getIconName()).toBe('check');
1180
+ * ```
1181
+ */
1182
+ getIconName(): Promise<string | null>;
1183
+ /**
1184
+ * Reports whether the button renders an icon.
1185
+ *
1186
+ * @example
1187
+ * ```typescript
1188
+ * const saveBtn = await loader.getHarness(TnButtonHarness.with({ label: 'Save' }));
1189
+ * expect(await saveBtn.hasIcon()).toBe(true);
1190
+ * ```
1191
+ */
1192
+ hasIcon(): Promise<boolean>;
1159
1193
  /**
1160
1194
  * Checks whether the button is disabled.
1161
1195
  *
@@ -6823,21 +6857,46 @@ declare class TnSliderThumbDirective implements ControlValueAccessor, OnInit, On
6823
6857
  max: () => number;
6824
6858
  step: () => number;
6825
6859
  value: () => number;
6860
+ labelPrefix: () => string;
6861
+ labelSuffix: () => string;
6862
+ ariaLabel: () => string | undefined;
6863
+ ariaLabelledby: () => string | undefined;
6826
6864
  updateValue: (value: number) => void;
6865
+ markTouched: () => void;
6827
6866
  getSliderRect: () => DOMRect;
6828
6867
  };
6829
6868
  onTouched: () => void;
6830
6869
  private onChangeCallback;
6870
+ private isPointerDown;
6831
6871
  private isDragging;
6872
+ private currentValue;
6873
+ private hasWrittenValue;
6832
6874
  private elementRef;
6875
+ private fallbackAriaLabel;
6876
+ private fallbackAriaLabelledby;
6833
6877
  ngOnInit(): void;
6834
6878
  ngOnDestroy(): void;
6879
+ /** Value last written by the form, for the slider to read once linked. */
6880
+ getValue(): number;
6881
+ /**
6882
+ * Whether the form has written a value to this thumb. The slider checks this
6883
+ * before adopting getValue() so an unbound thumb's default 0 never overwrites
6884
+ * a value bound directly on the slider.
6885
+ */
6886
+ hasFormValue(): boolean;
6835
6887
  writeValue(value: number): void;
6836
6888
  registerOnChange(fn: (value: number) => void): void;
6837
6889
  registerOnTouched(fn: () => void): void;
6838
6890
  setDisabledState(isDisabled: boolean): void;
6839
6891
  onInput(event: Event): void;
6840
6892
  onChange(_event: Event): void;
6893
+ /**
6894
+ * Marks the bound control touched. Calls the thumb's own `onTouched` (for a
6895
+ * thumb-bound control) and forwards to the linked slider (for a
6896
+ * slider-host-bound control) — the thumb is the only interactive element, so
6897
+ * the slider relies on it to ever become touched.
6898
+ */
6899
+ notifyTouched(): void;
6841
6900
  onMouseDown(event: MouseEvent): void;
6842
6901
  onTouchStart(event: TouchEvent): void;
6843
6902
  private addGlobalListeners;
@@ -6847,13 +6906,35 @@ declare class TnSliderThumbDirective implements ControlValueAccessor, OnInit, On
6847
6906
  private onGlobalTouchMove;
6848
6907
  private onGlobalTouchEnd;
6849
6908
  private updateValueFromPosition;
6909
+ /**
6910
+ * Resolve the accessible name for the range input: the parent slider's
6911
+ * `aria-label`/`aria-labelledby` input when set, otherwise a value placed
6912
+ * directly on the `<input tnSliderThumb>`. Returning the fallback keeps the
6913
+ * host binding from wiping a directly-set label. Null removes the attribute.
6914
+ */
6915
+ ariaLabel(): string | null;
6916
+ ariaLabelledby(): string | null;
6917
+ /**
6918
+ * Commit a value that originated outside the native input (a thumb drag).
6919
+ * Syncs `currentValue`, the native input, and emits to the form. The slider's
6920
+ * own `onChange` only reaches a slider-bound control, so a thumb-bound control
6921
+ * relies on this to stay in sync. Expects an already clamped/stepped value
6922
+ * (slider.value()).
6923
+ */
6924
+ commit(value: number): void;
6925
+ /**
6926
+ * Builds an aria-valuetext when the slider has a label prefix/suffix so screen
6927
+ * readers announce "50 km/h" rather than the bare number. Returns null when
6928
+ * neither is set, letting the native range's valuenow announcement stand.
6929
+ */
6930
+ ariaValueText(): string | null;
6850
6931
  private cleanup;
6851
6932
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSliderThumbDirective, never>;
6852
6933
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnSliderThumbDirective, "input[tnSliderThumb]", never, {}, {}, never, never, true, never>;
6853
6934
  }
6854
6935
 
6855
6936
  type LabelType = 'none' | 'handle' | 'track' | 'both';
6856
- declare class TnSliderComponent implements ControlValueAccessor, OnDestroy, AfterViewInit {
6937
+ declare class TnSliderComponent implements ControlValueAccessor, OnDestroy, AfterContentInit, AfterViewInit {
6857
6938
  min: _angular_core.InputSignal<number>;
6858
6939
  max: _angular_core.InputSignal<number>;
6859
6940
  step: _angular_core.InputSignal<number>;
@@ -6866,9 +6947,18 @@ declare class TnSliderComponent implements ControlValueAccessor, OnDestroy, Afte
6866
6947
  * is configured via `TN_TEST_ATTR` (default `data-testid`).
6867
6948
  */
6868
6949
  testId: _angular_core.InputSignal<TnTestIdValue>;
6950
+ /**
6951
+ * Accessible name forwarded to the inner range input — the focusable element
6952
+ * screen readers actually announce. Set this (or `aria-labelledby`) when the
6953
+ * slider isn't already labelled by a `tn-form-field`/`<label>`, otherwise a
6954
+ * standalone `<tn-slider><input tnSliderThumb></tn-slider>` announces only
6955
+ * "slider". A label set directly on the `input[tnSliderThumb]` is used as a
6956
+ * fallback when neither is provided here.
6957
+ */
6958
+ ariaLabel: _angular_core.InputSignal<string | undefined>;
6959
+ ariaLabelledby: _angular_core.InputSignal<string | undefined>;
6869
6960
  thumbDirective: _angular_core.Signal<TnSliderThumbDirective>;
6870
6961
  sliderContainer: _angular_core.Signal<ElementRef<HTMLDivElement>>;
6871
- thumbVisual: _angular_core.Signal<ElementRef<HTMLDivElement>>;
6872
6962
  private onChange;
6873
6963
  private onTouched;
6874
6964
  value: _angular_core.WritableSignal<number>;
@@ -6878,30 +6968,35 @@ declare class TnSliderComponent implements ControlValueAccessor, OnDestroy, Afte
6878
6968
  isDisabled: _angular_core.Signal<boolean>;
6879
6969
  fillPercentage: _angular_core.Signal<number>;
6880
6970
  fillScale: _angular_core.Signal<number>;
6881
- thumbPosition: _angular_core.Signal<number>;
6882
6971
  showLabel: _angular_core.Signal<boolean>;
6883
6972
  labelVisible: _angular_core.Signal<boolean>;
6884
6973
  constructor();
6974
+ ngAfterContentInit(): void;
6885
6975
  ngAfterViewInit(): void;
6886
6976
  ngOnDestroy(): void;
6887
6977
  writeValue(value: number): void;
6888
6978
  registerOnChange(fn: (value: number) => void): void;
6889
6979
  registerOnTouched(fn: () => void): void;
6980
+ /**
6981
+ * Marks a slider-host-bound control as touched. The inner thumb is the only
6982
+ * interactive element, so it forwards its touch events here (on blur / pointer
6983
+ * release) — otherwise a control bound to the `tn-slider` host would never
6984
+ * transition to touched and touched-gated validation would never show.
6985
+ */
6986
+ markTouched(): void;
6890
6987
  setDisabledState(isDisabled: boolean): void;
6891
6988
  updateValue(newValue: number): void;
6892
6989
  enableLabel(): void;
6893
6990
  showThumbLabel(): void;
6894
6991
  hideThumbLabel(): void;
6895
6992
  getSliderRect(): DOMRect;
6896
- onTrackClick(event: MouseEvent | TouchEvent): void;
6897
- private updateThumbPosition;
6898
6993
  private clampValue;
6899
6994
  private setupHandleInteractionListeners;
6900
6995
  private cleanupHandleInteractionListeners;
6901
6996
  private onInteractionStart;
6902
6997
  private onInteractionEnd;
6903
6998
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSliderComponent, never>;
6904
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSliderComponent, "tn-slider", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "labelPrefix": { "alias": "labelPrefix"; "required": false; "isSignal": true; }; "labelSuffix": { "alias": "labelSuffix"; "required": false; "isSignal": true; }; "labelType": { "alias": "labelType"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, {}, ["thumbDirective"], ["*"], true, never>;
6999
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSliderComponent, "tn-slider", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "labelPrefix": { "alias": "labelPrefix"; "required": false; "isSignal": true; }; "labelSuffix": { "alias": "labelSuffix"; "required": false; "isSignal": true; }; "labelType": { "alias": "labelType"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, {}, ["thumbDirective"], ["*"], true, never>;
6905
7000
  }
6906
7001
 
6907
7002
  declare class TnSliderWithLabelDirective implements OnInit, OnDestroy {