@truenas/ui-components 0.1.40 → 0.1.41

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.
@@ -8106,6 +8106,59 @@ async function setInputValue(el, value) {
8106
8106
  }
8107
8107
  await el.blur();
8108
8108
  }
8109
+ const MONTHS = [
8110
+ 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN',
8111
+ 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC',
8112
+ ];
8113
+ /**
8114
+ * Navigates the calendar overlay to the target month/year, then clicks the day cell.
8115
+ * Assumes the calendar popup is already open.
8116
+ *
8117
+ * @param rootLocator The document root locator factory (for finding overlay elements).
8118
+ * @param date The target date to select.
8119
+ */
8120
+ async function selectCalendarDate(rootLocator, date) {
8121
+ await navigateCalendarTo(rootLocator, date);
8122
+ const dayStr = date.getDate().toString();
8123
+ const cells = await rootLocator.locatorForAll('.tn-calendar-body-cell:not([disabled])')();
8124
+ for (const cell of cells) {
8125
+ if ((await cell.text()).trim() === dayStr) {
8126
+ await cell.click();
8127
+ return;
8128
+ }
8129
+ }
8130
+ throw new Error(`Could not find enabled calendar cell for day ${dayStr}`);
8131
+ }
8132
+ /**
8133
+ * Navigates the calendar to show the month/year of the target date by
8134
+ * clicking previous/next buttons as needed.
8135
+ */
8136
+ async function navigateCalendarTo(rootLocator, date) {
8137
+ const targetLabel = `${MONTHS[date.getMonth()]} ${date.getFullYear()}`;
8138
+ // Safety limit to prevent infinite loops
8139
+ for (let i = 0; i < 120; i++) {
8140
+ const periodButton = await rootLocator.locatorFor('.tn-calendar-period-button')();
8141
+ const currentLabel = (await periodButton.text()).trim();
8142
+ if (currentLabel === targetLabel) {
8143
+ return;
8144
+ }
8145
+ const currentDate = parseCalendarLabel(currentLabel);
8146
+ const targetTime = date.getFullYear() * 12 + date.getMonth();
8147
+ const currentTime = currentDate.year * 12 + currentDate.month;
8148
+ const navSelector = targetTime > currentTime
8149
+ ? '.tn-calendar-next-button'
8150
+ : '.tn-calendar-previous-button';
8151
+ const navButton = await rootLocator.locatorFor(navSelector)();
8152
+ await navButton.click();
8153
+ }
8154
+ throw new Error(`Could not navigate calendar to ${targetLabel}`);
8155
+ }
8156
+ function parseCalendarLabel(label) {
8157
+ const parts = label.split(' ');
8158
+ const monthIndex = MONTHS.indexOf(parts[0]);
8159
+ const year = parseInt(parts[1], 10);
8160
+ return { year, month: monthIndex >= 0 ? monthIndex : 0 };
8161
+ }
8109
8162
 
8110
8163
  /**
8111
8164
  * Harness for interacting with `tn-date-input` in tests.
@@ -8198,6 +8251,25 @@ class TnDateInputHarness extends ComponentHarness {
8198
8251
  const overlay = await this.documentRootLocatorFactory().locatorForOptional('.tn-datepicker-overlay')();
8199
8252
  return overlay !== null;
8200
8253
  }
8254
+ /**
8255
+ * Selects a date via the calendar popup. Opens the calendar if not already
8256
+ * open, navigates to the target month, and clicks the day cell.
8257
+ *
8258
+ * @param date The date to select.
8259
+ *
8260
+ * @example
8261
+ * ```typescript
8262
+ * const dateInput = await loader.getHarness(TnDateInputHarness);
8263
+ * await dateInput.selectDate(new Date(2026, 3, 15));
8264
+ * expect(await dateInput.getDisplayText()).toBe('04/15/2026');
8265
+ * ```
8266
+ */
8267
+ async selectDate(date) {
8268
+ if (!(await this.isCalendarOpen())) {
8269
+ await this.openCalendar();
8270
+ }
8271
+ await selectCalendarDate(this.documentRootLocatorFactory(), date);
8272
+ }
8201
8273
  }
8202
8274
 
8203
8275
  class TnDateRangeInputComponent {
@@ -8676,6 +8748,31 @@ class TnDateRangeInputHarness extends ComponentHarness {
8676
8748
  const overlay = await this.documentRootLocatorFactory().locatorForOptional('.tn-datepicker-overlay')();
8677
8749
  return overlay !== null;
8678
8750
  }
8751
+ /**
8752
+ * Selects a date range via the calendar popup. Opens the calendar if not
8753
+ * already open, navigates to each target month, and clicks the day cells.
8754
+ *
8755
+ * @param range An object with `start` and `end` dates.
8756
+ *
8757
+ * @example
8758
+ * ```typescript
8759
+ * const rangeInput = await loader.getHarness(TnDateRangeInputHarness);
8760
+ * await rangeInput.selectRange({
8761
+ * start: new Date(2026, 0, 1),
8762
+ * end: new Date(2026, 0, 31),
8763
+ * });
8764
+ * expect(await rangeInput.getStartText()).toBe('01/01/2026');
8765
+ * expect(await rangeInput.getEndText()).toBe('01/31/2026');
8766
+ * ```
8767
+ */
8768
+ async selectRange(range) {
8769
+ if (!(await this.isCalendarOpen())) {
8770
+ await this.openCalendar();
8771
+ }
8772
+ const rootLocator = this.documentRootLocatorFactory();
8773
+ await selectCalendarDate(rootLocator, range.start);
8774
+ await selectCalendarDate(rootLocator, range.end);
8775
+ }
8679
8776
  }
8680
8777
 
8681
8778
  class TnTimeInputComponent {