@truenas/ui-components 0.2.1 → 0.2.2

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.2.1",
3
+ "version": "0.2.2",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public"
@@ -1288,6 +1288,14 @@ declare class TnInputComponent implements AfterViewInit, OnDestroy, ControlValue
1288
1288
  * (e.g. `1.5 GiB`). Ignored unless `inputType` is `Size`.
1289
1289
  */
1290
1290
  sizeRound: _angular_core.InputSignal<number>;
1291
+ /**
1292
+ * Whether a `Password` field renders the built-in visibility toggle — the eye
1293
+ * button that switches the field between masked and plain-text display.
1294
+ * Defaults to true; set false for secrets that must never be revealed.
1295
+ * Setting `suffixIcon` suppresses the toggle automatically (a custom suffix
1296
+ * control replaces it). Ignored unless `inputType` is `Password`.
1297
+ */
1298
+ showPasswordToggle: _angular_core.InputSignal<boolean>;
1291
1299
  prefixIcon: _angular_core.InputSignal<string | undefined>;
1292
1300
  prefixIconLibrary: _angular_core.InputSignal<IconLibraryType | undefined>;
1293
1301
  suffixIcon: _angular_core.InputSignal<string | undefined>;
@@ -1308,12 +1316,44 @@ declare class TnInputComponent implements AfterViewInit, OnDestroy, ControlValue
1308
1316
  isSize: _angular_core.Signal<boolean>;
1309
1317
  /** True when the field only accepts whole numbers (i.e. `allowDecimals` is false). */
1310
1318
  integerOnly: _angular_core.Signal<boolean>;
1311
- /** The `type` attribute actually rendered. Number and size modes use a text input: number avoids the native type="number" footguns, size must accept unit letters. */
1319
+ /** True when the field is a password field. */
1320
+ isPassword: _angular_core.Signal<boolean>;
1321
+ /**
1322
+ * Whether the password is currently revealed. Not exposed as an input so a
1323
+ * reveal is always an explicit user gesture, and linked to the toggle's own
1324
+ * availability so a revealed value never outlives the control that revealed
1325
+ * it: whenever the toggle goes away (the field leaves password mode,
1326
+ * `showPasswordToggle` flips off, a `suffixIcon` replaces it) or the field
1327
+ * is disabled, the field snaps back to masked.
1328
+ */
1329
+ protected passwordVisible: _angular_core.WritableSignal<boolean>;
1330
+ /** The `type` attribute actually rendered. Number and size modes use a text input: number avoids the native type="number" footguns, size must accept unit letters. A revealed password renders as text — flipping the type attribute is the standard reveal mechanism and preserves value and caret. */
1312
1331
  resolvedType: _angular_core.Signal<InputType>;
1313
1332
  /** `inputmode` hint: numeric keypad for integers, decimal keypad otherwise. Null (omitted) outside number mode — size fields accept unit letters, so they keep the full keyboard. */
1314
1333
  numericInputMode: _angular_core.Signal<"numeric" | "decimal" | null>;
1315
1334
  /** Number and size modes are always single-line; they win over `multiline` if both are set. */
1316
1335
  showTextarea: _angular_core.Signal<boolean>;
1336
+ /**
1337
+ * The visibility toggle renders only on single-line password fields (a
1338
+ * password+multiline combo renders a textarea, which has no `type` to flip),
1339
+ * and yields to a consumer-provided `suffixIcon` — a custom suffix control
1340
+ * replaces the built-in toggle rather than stacking a second button.
1341
+ */
1342
+ protected hasPasswordToggle: _angular_core.Signal<boolean>;
1343
+ /**
1344
+ * Icon for the visibility toggle, mirroring the field's current state: a
1345
+ * slashed eye while masked, an open eye while revealed. The literal
1346
+ * `tnIconMarker` calls double as build-time markers that pull both icons
1347
+ * into the sprite.
1348
+ */
1349
+ protected passwordToggleIcon: _angular_core.Signal<string>;
1350
+ /**
1351
+ * Role-first test-id segments for the visibility toggle:
1352
+ * `button-toggle-password[-<testId>]`. The toggle is fixed field chrome, so
1353
+ * the role leads (matching the dialog-shell close/fullscreen convention) and
1354
+ * automation can target every password toggle with one prefix selector.
1355
+ */
1356
+ protected passwordToggleTestId: _angular_core.Signal<(string | number | null | undefined)[]>;
1317
1357
  id: string;
1318
1358
  protected value: string;
1319
1359
  private formDisabled;
@@ -1330,12 +1370,13 @@ declare class TnInputComponent implements AfterViewInit, OnDestroy, ControlValue
1330
1370
  setDisabledState(isDisabled: boolean): void;
1331
1371
  protected onValueChange(event: Event): void;
1332
1372
  protected onBlur(): void;
1373
+ protected togglePasswordVisibility(): void;
1333
1374
  /** Strips any character that can't appear in the current numeric mode (single leading '-', single '.' for decimals). */
1334
1375
  private sanitizeNumeric;
1335
1376
  /** Parses a sanitized string to a number, mapping empty/partial input to null (never 0). */
1336
1377
  private parseNumeric;
1337
1378
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnInputComponent, never>;
1338
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnInputComponent, "tn-input", never, { "inputType": { "alias": "inputType"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "allowDecimals": { "alias": "allowDecimals"; "required": false; "isSignal": true; }; "sizeStandard": { "alias": "sizeStandard"; "required": false; "isSignal": true; }; "sizeDefaultUnit": { "alias": "sizeDefaultUnit"; "required": false; "isSignal": true; }; "sizeRound": { "alias": "sizeRound"; "required": false; "isSignal": true; }; "prefixIcon": { "alias": "prefixIcon"; "required": false; "isSignal": true; }; "prefixIconLibrary": { "alias": "prefixIconLibrary"; "required": false; "isSignal": true; }; "suffixIcon": { "alias": "suffixIcon"; "required": false; "isSignal": true; }; "suffixIconLibrary": { "alias": "suffixIconLibrary"; "required": false; "isSignal": true; }; "suffixIconAriaLabel": { "alias": "suffixIconAriaLabel"; "required": false; "isSignal": true; }; "suffixActionTestId": { "alias": "suffixActionTestId"; "required": false; "isSignal": true; }; }, { "onSuffixAction": "onSuffixAction"; }, never, never, true, never>;
1379
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnInputComponent, "tn-input", never, { "inputType": { "alias": "inputType"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "allowDecimals": { "alias": "allowDecimals"; "required": false; "isSignal": true; }; "sizeStandard": { "alias": "sizeStandard"; "required": false; "isSignal": true; }; "sizeDefaultUnit": { "alias": "sizeDefaultUnit"; "required": false; "isSignal": true; }; "sizeRound": { "alias": "sizeRound"; "required": false; "isSignal": true; }; "showPasswordToggle": { "alias": "showPasswordToggle"; "required": false; "isSignal": true; }; "prefixIcon": { "alias": "prefixIcon"; "required": false; "isSignal": true; }; "prefixIconLibrary": { "alias": "prefixIconLibrary"; "required": false; "isSignal": true; }; "suffixIcon": { "alias": "suffixIcon"; "required": false; "isSignal": true; }; "suffixIconLibrary": { "alias": "suffixIconLibrary"; "required": false; "isSignal": true; }; "suffixIconAriaLabel": { "alias": "suffixIconAriaLabel"; "required": false; "isSignal": true; }; "suffixActionTestId": { "alias": "suffixActionTestId"; "required": false; "isSignal": true; }; }, { "onSuffixAction": "onSuffixAction"; }, never, never, true, never>;
1339
1380
  }
1340
1381
 
1341
1382
  /**
@@ -1565,6 +1606,7 @@ declare class TnInputHarness extends ComponentHarness {
1565
1606
  private prefixIconEl;
1566
1607
  private suffixButton;
1567
1608
  private suffixIconEl;
1609
+ private visibilityToggle;
1568
1610
  /**
1569
1611
  * Gets a `HarnessPredicate` that can be used to search for an input
1570
1612
  * with specific attributes.
@@ -1699,6 +1741,27 @@ declare class TnInputHarness extends ComponentHarness {
1699
1741
  * @returns Promise that resolves when the click action is complete.
1700
1742
  */
1701
1743
  clickSuffixAction(): Promise<void>;
1744
+ /**
1745
+ * Checks whether the password visibility toggle is present.
1746
+ *
1747
+ * @returns Promise resolving to true if the toggle button exists.
1748
+ */
1749
+ hasPasswordToggle(): Promise<boolean>;
1750
+ /**
1751
+ * Whether the password is currently revealed (the field renders as plain text).
1752
+ *
1753
+ * Only meaningful on password-type inputs; resolves false while masked.
1754
+ *
1755
+ * @returns Promise resolving to true when the value is shown in plain text.
1756
+ */
1757
+ isPasswordRevealed(): Promise<boolean>;
1758
+ /**
1759
+ * Clicks the password visibility toggle, switching between masked and
1760
+ * plain-text display.
1761
+ *
1762
+ * @returns Promise that resolves when the click action is complete.
1763
+ */
1764
+ togglePasswordVisibility(): Promise<void>;
1702
1765
  /**
1703
1766
  * Focuses the input element.
1704
1767
  *