@ethlete/components 1.0.0-next.23 → 1.0.0-next.24

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": "@ethlete/components",
3
- "version": "1.0.0-next.23",
3
+ "version": "1.0.0-next.24",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -5241,20 +5241,20 @@ declare class SelectDirective implements FormValueControl<unknown>, FormFieldCon
5241
5241
  commitCustomValueOnClose: _angular_core.InputSignal<boolean>;
5242
5242
  /** Maximum number of selected values (multi select) — further adds are ignored. */
5243
5243
  maxSelection: _angular_core.InputSignal<number | undefined>;
5244
- /** Renders an "Add new" row in `et-select`'s panel — clicking it emits `addNewRequested`. */
5244
+ /** Renders an "Add new" row in `et-select`'s panel — clicking it emits `addNew`. */
5245
5245
  allowAddNew: _angular_core.InputSignal<boolean>;
5246
5246
  /** Async option state — rendered by `et-select` as a loading row inside the panel. */
5247
5247
  loading: _angular_core.InputSignal<boolean>;
5248
5248
  /** Async option state — rendered by `et-select` as an error row inside the panel. */
5249
5249
  error: _angular_core.InputSignal<string | null>;
5250
- /** Async option state — `et-select` renders a load-more control emitting `loadMoreRequested`. */
5250
+ /** Async option state — `et-select` renders a load-more control emitting `loadMore`. */
5251
5251
  hasMoreItems: _angular_core.InputSignal<boolean>;
5252
5252
  /** Whether the panel mirrors the anchor's width. Off for compact triggers (e.g. a country picker). */
5253
5253
  mirrorPanelWidth: _angular_core.InputSignal<boolean>;
5254
5254
  queryChange: _angular_core.OutputEmitterRef<string>;
5255
- loadMoreRequested: _angular_core.OutputEmitterRef<void>;
5255
+ loadMore: _angular_core.OutputEmitterRef<void>;
5256
5256
  /** The user picked the "Add new" row (`allowAddNew`). Emits the current search query for prefilling. */
5257
- addNewRequested: _angular_core.OutputEmitterRef<string>;
5257
+ addNew: _angular_core.OutputEmitterRef<string>;
5258
5258
  shouldDisplayError: _angular_core.Signal<boolean>;
5259
5259
  hasValue: _angular_core.Signal<boolean>;
5260
5260
  describedBy: WritableSignal<string | null>;
@@ -5363,10 +5363,10 @@ declare class SelectDirective implements FormValueControl<unknown>, FormFieldCon
5363
5363
  activate(): void;
5364
5364
  /** @internal Commits an option as the (or a) selected value. Single select closes afterwards. */
5365
5365
  commitOption(item: SelectItem): void;
5366
- /** @internal Emits `loadMoreRequested` — wired to the panel's load-more control. */
5366
+ /** @internal Emits `loadMore` — wired to the panel's load-more control. */
5367
5367
  requestLoadMore(): void;
5368
5368
  /**
5369
- * Emits `addNewRequested` with the current search query and closes the panel — wired to
5369
+ * Emits `addNew` with the current search query and closes the panel — wired to
5370
5370
  * the panel's "Add new" row (`allowAddNew`). The consumer reacts by e.g. opening a
5371
5371
  * creation dialog and, once the new option exists, setting it as the value.
5372
5372
  */
@@ -5408,7 +5408,7 @@ declare class SelectDirective implements FormValueControl<unknown>, FormFieldCon
5408
5408
  private handlePanelBeforeClosed;
5409
5409
  private handlePanelKeydown;
5410
5410
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SelectDirective, never>;
5411
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SelectDirective, "[etSelect]", ["etSelect"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "filterMode": { "alias": "filterMode"; "required": false; "isSignal": true; }; "allowCustomValues": { "alias": "allowCustomValues"; "required": false; "isSignal": true; }; "customValueSeparators": { "alias": "customValueSeparators"; "required": false; "isSignal": true; }; "normalizeCustomValue": { "alias": "normalizeCustomValue"; "required": false; "isSignal": true; }; "commitCustomValueOnClose": { "alias": "commitCustomValueOnClose"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "allowAddNew": { "alias": "allowAddNew"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "hasMoreItems": { "alias": "hasMoreItems"; "required": false; "isSignal": true; }; "mirrorPanelWidth": { "alias": "mirrorPanelWidth"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "open": "openChange"; "queryChange": "queryChange"; "loadMoreRequested": "loadMoreRequested"; "addNewRequested": "addNewRequested"; }, never, never, true, never>;
5411
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SelectDirective, "[etSelect]", ["etSelect"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "filterMode": { "alias": "filterMode"; "required": false; "isSignal": true; }; "allowCustomValues": { "alias": "allowCustomValues"; "required": false; "isSignal": true; }; "customValueSeparators": { "alias": "customValueSeparators"; "required": false; "isSignal": true; }; "normalizeCustomValue": { "alias": "normalizeCustomValue"; "required": false; "isSignal": true; }; "commitCustomValueOnClose": { "alias": "commitCustomValueOnClose"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "allowAddNew": { "alias": "allowAddNew"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "hasMoreItems": { "alias": "hasMoreItems"; "required": false; "isSignal": true; }; "mirrorPanelWidth": { "alias": "mirrorPanelWidth"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "open": "openChange"; "queryChange": "queryChange"; "loadMore": "loadMore"; "addNew": "addNew"; }, never, never, true, never>;
5412
5412
  }
5413
5413
 
5414
5414
  declare class SelectListboxDirective {
@@ -5553,14 +5553,22 @@ type SelectOptionsFromQueryConfig<TCreator extends AnyQueryCreator, TOption> = {
5553
5553
  */
5554
5554
  queryCreator: TCreator;
5555
5555
  /**
5556
- * Builds the request args from the debounced search query. Runs reactively (like `withArgs`):
5557
- * reading `query()` re-executes as the user types. Return `null` to skip a request (e.g. for an
5558
- * empty query) — `options` is empty while skipped.
5556
+ * Builds the request args from the debounced search query and the current `page`. Runs
5557
+ * reactively (like `withArgs`): reading `query()` re-executes as the user types, and reading
5558
+ * `page()` re-executes when `loadMore()` advances the page. Return `null` to skip a request
5559
+ * (e.g. for an empty query) — `options` is empty while skipped.
5560
+ *
5561
+ * `page` starts at `initialPage` and resets there whenever the query changes; `loadMore()`
5562
+ * increments it. Return only that page's slice from `toOptions` — the factory appends each
5563
+ * page to the accumulated `options`.
5564
+ */
5565
+ args: (query: Signal<string>, page: Signal<number>) => RequestArgs<QueryArgsOf<TCreator>> | null;
5566
+ /**
5567
+ * Maps a successful response to the option slice for the **current page**. The factory appends
5568
+ * each page's slice to the accumulated `options` (and resets when the query changes).
5559
5569
  */
5560
- args: (query: Signal<string>) => RequestArgs<QueryArgsOf<TCreator>> | null;
5561
- /** Maps a successful response to the option data your `@for` renders. */
5562
5570
  toOptions: (response: ResponseType<QueryArgsOf<TCreator>>) => TOption[];
5563
- /** Derives whether more pages exist from the response — drives the select's `hasMoreItems`. */
5571
+ /** Derives whether more pages exist from the latest page's response — drives `hasMoreItems` and gates `loadMore()`. */
5564
5572
  toHasMore?: (response: ResponseType<QueryArgsOf<TCreator>>) => boolean;
5565
5573
  /** Turns a query failure into the select's error text. Defaults to the first error message. */
5566
5574
  toErrorMessage?: (error: QueryErrorResponse) => string;
@@ -5568,6 +5576,8 @@ type SelectOptionsFromQueryConfig<TCreator extends AnyQueryCreator, TOption> = {
5568
5576
  minQueryLength?: number;
5569
5577
  /** Debounce applied to the query before it reaches `args`, in ms. @default 300 */
5570
5578
  debounceTime?: number;
5579
+ /** The page `args` receives on first load and after each query change. @default 1 */
5580
+ initialPage?: number;
5571
5581
  };
5572
5582
  type SelectOptionsFromQuery<TOption> = {
5573
5583
  /** The mapped options — render them with an `@for` of `et-select-option`s (`filterMode="external"`). */
@@ -5582,6 +5592,11 @@ type SelectOptionsFromQuery<TOption> = {
5582
5592
  query: Signal<string>;
5583
5593
  /** Wire to the select's `(queryChange)` output. */
5584
5594
  setQuery: (query: string) => void;
5595
+ /**
5596
+ * Wire to the select's `(loadMore)` output — advances to the next page and appends it
5597
+ * to `options`. A no-op while loading, when skipped, or once `hasMore` is false.
5598
+ */
5599
+ loadMore: () => void;
5585
5600
  };
5586
5601
  /**
5587
5602
  * Feeds a select's options from an `@ethlete/query` query as the user searches. Mirroring
@@ -5592,8 +5607,9 @@ type SelectOptionsFromQuery<TOption> = {
5592
5607
  * ```ts
5593
5608
  * users = selectOptionsFromQuery({
5594
5609
  * queryCreator: searchUsers,
5595
- * args: (query) => (query() ? { queryParams: { q: query() } } : null),
5610
+ * args: (query, page) => (query() ? { queryParams: { q: query(), page: page() } } : null),
5596
5611
  * toOptions: (res) => res.items,
5612
+ * toHasMore: (res) => res.page < res.totalPages,
5597
5613
  * });
5598
5614
  * ```
5599
5615
  *
@@ -5602,7 +5618,9 @@ type SelectOptionsFromQuery<TOption> = {
5602
5618
  * [formField]="form.assignee"
5603
5619
  * [loading]="users.loading()"
5604
5620
  * [error]="users.error()"
5621
+ * [hasMoreItems]="users.hasMore()"
5605
5622
  * (queryChange)="users.setQuery($event)"
5623
+ * (loadMore)="users.loadMore()"
5606
5624
  * filterMode="external"
5607
5625
  * >
5608
5626
  * <input etSelectSearch placeholder="Search users" />
@@ -5612,8 +5630,18 @@ type SelectOptionsFromQuery<TOption> = {
5612
5630
  * </et-select>
5613
5631
  * ```
5614
5632
  *
5633
+ * Pagination is built in: `loadMore()` advances `page` and appends the next page's slice to
5634
+ * `options`; the accumulator resets whenever the query changes. Derive `hasMore` from the latest
5635
+ * response via `toHasMore` — it also gates `loadMore()`.
5636
+ *
5615
5637
  * Call it from a field initializer / constructor (injection context), the same place you'd create
5616
5638
  * a query or a query stack.
5639
+ *
5640
+ * Pagination is built in: `args` receives a `page` signal (starting at `initialPage`, default `1`)
5641
+ * that resets on every query change and advances on `loadMore()`. Return only the current page's
5642
+ * slice from `toOptions` — the factory appends each page to the accumulated `options`. Wire
5643
+ * `hasMore` (via `toHasMore`) to `hasMoreItems` and `loadMore` to `(loadMore)`; `loadMore`
5644
+ * is a no-op while loading, when skipped, or once `hasMore` is false.
5617
5645
  */
5618
5646
  declare const selectOptionsFromQuery: <TCreator extends AnyQueryCreator, TOption>(config: SelectOptionsFromQueryConfig<TCreator, TOption>) => SelectOptionsFromQuery<TOption>;
5619
5647
 
@@ -5628,14 +5656,22 @@ type SelectOptionsFromV2QueryConfig<TCreator extends AnyV2QueryCreator | AnyLega
5628
5656
  */
5629
5657
  queryCreator: TCreator;
5630
5658
  /**
5631
- * Builds the `prepare()` args from the debounced search query. Runs reactively (like
5632
- * `queryComputed`): reading `query()` re-executes as the user types. Return `null` to skip a
5633
- * request (e.g. for an empty query) — `options` is empty while skipped.
5659
+ * Builds the `prepare()` args from the debounced search query and the current `page`. Runs
5660
+ * reactively (like `queryComputed`): reading `query()` re-executes as the user types, and reading
5661
+ * `page()` re-executes when `loadMore()` advances the page. Return `null` to skip a request
5662
+ * (e.g. for an empty query) — `options` is empty while skipped.
5663
+ *
5664
+ * `page` starts at `initialPage` and resets there whenever the query changes; `loadMore()`
5665
+ * increments it. Return only that page's slice from `toOptions` — the factory appends each
5666
+ * page to the accumulated `options`.
5667
+ */
5668
+ args: (query: Signal<string>, page: Signal<number>) => V2PrepareArgsOf<TCreator> | null;
5669
+ /**
5670
+ * Maps a successful response to the option slice for the **current page**. The factory appends
5671
+ * each page's slice to the accumulated `options` (and resets when the query changes).
5634
5672
  */
5635
- args: (query: Signal<string>) => V2PrepareArgsOf<TCreator> | null;
5636
- /** Maps a successful response to the option data your `@for` renders. */
5637
5673
  toOptions: (response: QueryDataOf<TCreator>) => TOption[];
5638
- /** Derives whether more pages exist from the response — drives the select's `hasMoreItems`. */
5674
+ /** Derives whether more pages exist from the latest page's response — drives `hasMoreItems` and gates `loadMore()`. */
5639
5675
  toHasMore?: (response: QueryDataOf<TCreator>) => boolean;
5640
5676
  /** Turns a query failure into the select's error text. Defaults to the first error message. */
5641
5677
  toErrorMessage?: (error: RequestError) => string;
@@ -5643,6 +5679,8 @@ type SelectOptionsFromV2QueryConfig<TCreator extends AnyV2QueryCreator | AnyLega
5643
5679
  minQueryLength?: number;
5644
5680
  /** Debounce applied to the query before it reaches `args`, in ms. @default 300 */
5645
5681
  debounceTime?: number;
5682
+ /** The page `args` receives on first load and after each query change. @default 1 */
5683
+ initialPage?: number;
5646
5684
  };
5647
5685
  /**
5648
5686
  * Feeds a select's options from a **legacy v2** query as the user searches — the
@@ -5653,8 +5691,9 @@ type SelectOptionsFromV2QueryConfig<TCreator extends AnyV2QueryCreator | AnyLega
5653
5691
  * ```ts
5654
5692
  * users = selectOptionsFromV2Query({
5655
5693
  * queryCreator: searchUsers, // client.get({ route: '/users', types: { … } })
5656
- * args: (query) => (query() ? { queryParams: { q: query() } } : null),
5694
+ * args: (query, page) => (query() ? { queryParams: { q: query(), page: page() } } : null),
5657
5695
  * toOptions: (res) => res.items,
5696
+ * toHasMore: (res) => res.page < res.totalPages,
5658
5697
  * });
5659
5698
  * ```
5660
5699
  *
@@ -5663,7 +5702,9 @@ type SelectOptionsFromV2QueryConfig<TCreator extends AnyV2QueryCreator | AnyLega
5663
5702
  * [formField]="form.assignee"
5664
5703
  * [loading]="users.loading()"
5665
5704
  * [error]="users.error()"
5705
+ * [hasMoreItems]="users.hasMore()"
5666
5706
  * (queryChange)="users.setQuery($event)"
5707
+ * (loadMore)="users.loadMore()"
5667
5708
  * filterMode="external"
5668
5709
  * >
5669
5710
  * <input etSelectSearch placeholder="Search users" />
@@ -5675,6 +5716,12 @@ type SelectOptionsFromV2QueryConfig<TCreator extends AnyV2QueryCreator | AnyLega
5675
5716
  *
5676
5717
  * Call it from a field initializer / constructor (injection context), the same place you'd use
5677
5718
  * `queryComputed` or a query container.
5719
+ *
5720
+ * Pagination is built in: `args` receives a `page` signal (starting at `initialPage`, default `1`)
5721
+ * that resets on every query change and advances on `loadMore()`. Return only the current page's
5722
+ * slice from `toOptions` — the factory appends each page to the accumulated `options`. Wire
5723
+ * `hasMore` (via `toHasMore`) to `hasMoreItems` and `loadMore` to `(loadMore)`; `loadMore`
5724
+ * is a no-op while loading, when skipped, or once `hasMore` is false.
5678
5725
  */
5679
5726
  declare const selectOptionsFromV2Query: <TCreator extends AnyV2QueryCreator | AnyLegacyQueryCreator, TOption>(config: SelectOptionsFromV2QueryConfig<TCreator, TOption>) => SelectOptionsFromQuery<TOption>;
5680
5727
 
@@ -5717,7 +5764,7 @@ declare class SelectComponent {
5717
5764
  protected handleClearClick(event: Event): void;
5718
5765
  protected handleArrowClick(event: Event): void;
5719
5766
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SelectComponent, never>;
5720
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SelectComponent, "et-select", never, { "loadMoreLabel": { "alias": "loadMoreLabel"; "required": false; "isSignal": true; }; "addNewLabel": { "alias": "addNewLabel"; "required": false; "isSignal": true; }; "createLabel": { "alias": "createLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, {}, never, ["input[etSelectSearch]", "*"], true, [{ directive: typeof SelectDirective; inputs: { "value": "value"; "touched": "touched"; "open": "open"; "multiple": "multiple"; "placeholder": "placeholder"; "disabled": "disabled"; "readonly": "readonly"; "invalid": "invalid"; "errors": "errors"; "required": "required"; "name": "name"; "options": "options"; "filterMode": "filterMode"; "allowCustomValues": "allowCustomValues"; "customValueSeparators": "customValueSeparators"; "normalizeCustomValue": "normalizeCustomValue"; "commitCustomValueOnClose": "commitCustomValueOnClose"; "maxSelection": "maxSelection"; "allowAddNew": "allowAddNew"; "loading": "loading"; "error": "error"; "hasMoreItems": "hasMoreItems"; }; outputs: { "valueChange": "valueChange"; "touchedChange": "touchedChange"; "openChange": "openChange"; "queryChange": "queryChange"; "loadMoreRequested": "loadMoreRequested"; "addNewRequested": "addNewRequested"; }; }, { directive: typeof _ethlete_core.ColorInteractiveDirective; inputs: {}; outputs: {}; }]>;
5767
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SelectComponent, "et-select", never, { "loadMoreLabel": { "alias": "loadMoreLabel"; "required": false; "isSignal": true; }; "addNewLabel": { "alias": "addNewLabel"; "required": false; "isSignal": true; }; "createLabel": { "alias": "createLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, {}, never, ["input[etSelectSearch]", "*"], true, [{ directive: typeof SelectDirective; inputs: { "value": "value"; "touched": "touched"; "open": "open"; "multiple": "multiple"; "placeholder": "placeholder"; "disabled": "disabled"; "readonly": "readonly"; "invalid": "invalid"; "errors": "errors"; "required": "required"; "name": "name"; "options": "options"; "filterMode": "filterMode"; "allowCustomValues": "allowCustomValues"; "customValueSeparators": "customValueSeparators"; "normalizeCustomValue": "normalizeCustomValue"; "commitCustomValueOnClose": "commitCustomValueOnClose"; "maxSelection": "maxSelection"; "allowAddNew": "allowAddNew"; "loading": "loading"; "error": "error"; "hasMoreItems": "hasMoreItems"; }; outputs: { "valueChange": "valueChange"; "touchedChange": "touchedChange"; "openChange": "openChange"; "queryChange": "queryChange"; "loadMore": "loadMore"; "addNew": "addNew"; }; }, { directive: typeof _ethlete_core.ColorInteractiveDirective; inputs: {}; outputs: {}; }]>;
5721
5768
  }
5722
5769
 
5723
5770
  declare const SELECT_IMPORTS: readonly [typeof SelectComponent, typeof SelectOptionComponent, typeof SelectOptionGroupComponent, typeof SelectPanelComponent, typeof SelectVirtualOptionComponent, typeof SelectDirective, typeof SelectTriggerDirective, typeof SelectSurfaceDirective, typeof SelectListboxDirective, typeof SelectOptionDirective, typeof SelectOptionGroupDirective, typeof SelectOptionTemplateDirective, typeof SelectValueDirective, typeof SelectSearchDirective, typeof SelectViewportDirective, typeof SelectVirtualOptionDirective, typeof SelectLoadingDirective, typeof SelectErrorDirective, typeof SelectEmptyDirective];