@lotics/ui 47.12.1 → 47.12.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/docs/catalog.md CHANGED
@@ -1815,7 +1815,10 @@ source (`src/<module>.tsx`/`.ts`) is the API reference.
1815
1815
  control cannot do itself — see [composition.md](./composition.md) §register.
1816
1816
  - **`column_filter`** — `ColumnFilter` + `columnFilterToConditions` +
1817
1817
  `isColumnFilterActive` + `columnFilterSummary`: the typed per-column filter pill; for a
1818
- register filtering on several columns.
1818
+ register filtering on several columns. `FilterableColumn<C>` / `FilterConditionNode<C>` carry
1819
+ the column key's type — pass the app SDK's `ColumnKeyOf<alias>` so the nodes this helper builds
1820
+ stay assignable to a `useQuery` filter typed against its query; the default `C = string` is
1821
+ for an alias whose projection codegen could not read.
1819
1822
  - **`filter_band`** — `FilterBand`: the toolbar ROW above a list — search, the `FilterChip`s,
1820
1823
  and the screen's primary action. **On a small screen the chips collapse into one `Filters (n)`
1821
1824
  button** that opens a sheet where the same chips render as full-width disclosure rows, one
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/ui",
3
- "version": "47.12.1",
3
+ "version": "47.12.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./accordion": "./src/accordion.tsx",
@@ -7,9 +7,17 @@ import { FilterChip } from "./filter_chip";
7
7
  import type { PickerOption } from "./picker";
8
8
  import { useLoticsLocale } from "./locale";
9
9
 
10
- /** A column the picker can filter on. `type` selects the control + operators. */
11
- export interface FilterableColumn {
12
- key: string;
10
+ /**
11
+ * A column the picker can filter on. `type` selects the control + operators.
12
+ *
13
+ * `C` is the key's type — `string` by default, or the literal union of a
14
+ * query's projected outputs (`AppQueryColumns[alias]` from the app SDK) when
15
+ * the caller has one. It exists so a condition built here stays assignable to
16
+ * a `useQuery` filter typed against its query; with a plain `string` key the
17
+ * SDK's typed filter would refuse every node this helper produced.
18
+ */
19
+ export interface FilterableColumn<C extends string = string> {
20
+ key: C;
13
21
  label: string;
14
22
  type: "text" | "number" | "select";
15
23
  /** Options for `type: "select"`. */
@@ -22,10 +30,11 @@ export type ColumnFilterValue =
22
30
  | { kind: "number"; min: number | null; max: number | null }
23
31
  | { kind: "select"; selected: string[] };
24
32
 
25
- /** A `TableRecordFilters` condition node (the shape the app query RPC accepts). */
26
- export interface FilterConditionNode {
33
+ /** A `TableRecordFilters` condition node (the shape the app query RPC accepts).
34
+ * `C` follows the column it was built from — see `FilterableColumn`. */
35
+ export interface FilterConditionNode<C extends string = string> {
27
36
  node_type: "condition";
28
- field_key: string;
37
+ field_key: C;
29
38
  type: "text" | "number" | "select";
30
39
  operator: string;
31
40
  value: unknown;
@@ -36,10 +45,10 @@ export interface FilterConditionNode {
36
45
  * column filter must become a `TableRecordFilters` predicate). Returns 0+ nodes
37
46
  * — a number range yields two, an empty filter yields none.
38
47
  */
39
- export function columnFilterToConditions(
40
- column: FilterableColumn,
48
+ export function columnFilterToConditions<C extends string = string>(
49
+ column: FilterableColumn<C>,
41
50
  value: ColumnFilterValue | undefined,
42
- ): FilterConditionNode[] {
51
+ ): FilterConditionNode<C>[] {
43
52
  if (!value) return [];
44
53
  if (value.kind === "text") {
45
54
  const q = value.query.trim();
@@ -48,7 +57,7 @@ export function columnFilterToConditions(
48
57
  : [];
49
58
  }
50
59
  if (value.kind === "number") {
51
- const nodes: FilterConditionNode[] = [];
60
+ const nodes: FilterConditionNode<C>[] = [];
52
61
  if (value.min != null) {
53
62
  nodes.push({ node_type: "condition", field_key: column.key, type: "number", operator: "greater_than_or_equal_to", value: value.min });
54
63
  }