@lotics/ui 47.12.1 → 47.13.0

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
@@ -637,6 +637,9 @@ source (`src/<module>.tsx`/`.ts`) is the API reference.
637
637
  the scale (h1→h4, h2→h5, h3+→h6): sizing alone leaves a model's `##` announcing as a PEER of
638
638
  your own sections in heading navigation, which no visual check can see.
639
639
  - **`markdown_types`** — `MarkdownProps`; types only.
640
+ - **`remark_gfm_safe`** — `remarkGfmSafe`: the GFM plugin `Markdown` uses, for a
641
+ `react-markdown` instance the kit's renderer cannot serve. Never `remark-gfm`: it ships a
642
+ regex-lookbehind literal, which WebKit older than Safari 16.4 rejects while parsing the bundle.
640
643
  - **`markdown.css`** — import once for the web markdown styling.
641
644
  - **`format_date`** — `formatDate` / `parseDate` / `toISODate` + `DateFormatStyle`.
642
645
  - **`format_money`** — `formatMoney` / `formatCompactNumber`.
@@ -1815,7 +1818,10 @@ source (`src/<module>.tsx`/`.ts`) is the API reference.
1815
1818
  control cannot do itself — see [composition.md](./composition.md) §register.
1816
1819
  - **`column_filter`** — `ColumnFilter` + `columnFilterToConditions` +
1817
1820
  `isColumnFilterActive` + `columnFilterSummary`: the typed per-column filter pill; for a
1818
- register filtering on several columns.
1821
+ register filtering on several columns. `FilterableColumn<C>` / `FilterConditionNode<C>` carry
1822
+ the column key's type — pass the app SDK's `ColumnKeyOf<alias>` so the nodes this helper builds
1823
+ stay assignable to a `useQuery` filter typed against its query; the default `C = string` is
1824
+ for an alias whose projection codegen could not read.
1819
1825
  - **`filter_band`** — `FilterBand`: the toolbar ROW above a list — search, the `FilterChip`s,
1820
1826
  and the screen's primary action. **On a small screen the chips collapse into one `Filters (n)`
1821
1827
  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.13.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./accordion": "./src/accordion.tsx",
@@ -187,6 +187,7 @@
187
187
  "./markdown_editor.css": "./src/markdown_editor.css",
188
188
  "./markdown_editor_props": "./src/markdown_editor_props.ts",
189
189
  "./markdown_types": "./src/markdown_types.ts",
190
+ "./remark_gfm_safe": "./src/remark_gfm_safe.ts",
190
191
  "./matrix": "./src/matrix.tsx",
191
192
  "./matrix_totals": "./src/matrix_totals.ts",
192
193
  "./media_player": {
@@ -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
  }