@pythia-software/query-table-ui 0.4.2 → 0.6.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/README.md CHANGED
@@ -10,6 +10,48 @@ and selection toolbar.
10
10
  npm install @pythia-software/query-table-core @pythia-software/query-table-react @pythia-software/query-table-ui react react-dom
11
11
  ```
12
12
 
13
+ ## Column widths
14
+
15
+ Drag a header edge to resize one column (arrow keys nudge, Enter auto-fits).
16
+ Click a header and open **Column Widths** to resize in one step:
17
+
18
+ - **Fit This Column** sizes the clicked column to its widest rendered value.
19
+ - **Fit All to Content** does the same for every column.
20
+ - **Fit All to Screen** fills the viewport; when content overflows, narrow
21
+ columns keep their content width and only the widest ones are trimmed.
22
+ - **Equal Widths** splits the viewport evenly.
23
+ - **Reset Widths** drops explicit widths back to schema defaults.
24
+
25
+ Widths live in `query.select`, so presets are shareable and undoable.
26
+
27
+ ## Tag/set filters
28
+
29
+ Set `filter.editor: "set"` on a `textarray` field to use the native WHERE
30
+ multi-select editor, with ANY / ALL / NONE / EMPTY modes, badge presentation,
31
+ removable tags, keyboard controls, and a mobile bottom sheet. For stable tag
32
+ keys, also set `arrayCaseSensitive: true` and provide static `{ value, label }`
33
+ options. NONE includes empty/missing arrays while excluding every selected key.
34
+ Other fields and existing predicates keep their current editors.
35
+
36
+ ```ts
37
+ filter: {
38
+ editor: "set",
39
+ arrayCaseSensitive: true,
40
+ values: {
41
+ source: "static",
42
+ options: [{ value: "bug", label: "Bug" }, { value: "feature", label: "Feature" }],
43
+ },
44
+ }
45
+ ```
46
+
47
+ `FilterValueProvider` renders both selected chips and choices. Unknown selected
48
+ keys remain removable rather than being silently discarded. The editor honors
49
+ `filter.ops` and the query's predicate budget; a restrictive operator allowlist
50
+ can disable modes. `classNames.setEditor` and `classNames.setBackdrop` customize
51
+ the overlay alongside the existing input/select/button slots. See
52
+ [`docs/set-filters.md`](../../docs/set-filters.md) for serialization, alias
53
+ canonicalization, backend requirements, and compatibility details.
54
+
13
55
  ## Use
14
56
 
15
57
  ```tsx
@@ -60,27 +102,90 @@ consumer-owned bulk actions can call `selection.replace(ids)` or
60
102
  `selection.retain(ids)` atomically. Existing callbacks that use only the first
61
103
  argument remain compatible.
62
104
 
105
+ ## Icons
106
+
107
+ `Icon` is the shared, hand-drawn SVG set used throughout the UI and demo. Its
108
+ 24px grid, rounded 1.8px strokes, and `currentColor` styling keep controls
109
+ cohesive without forcing every shape into the same silhouette. Drag handles
110
+ use solid dots; saved and priority stars can use a filled active state.
111
+
112
+ ```tsx
113
+ import { Icon } from "@pythia-software/query-table-ui";
114
+
115
+ <button aria-label="Copy value"><Icon name="copy" /></button>
116
+ <Icon name="star" size={20} filled />
117
+ ```
118
+
119
+ Icons default to 16px; use `size` and `className` for larger carets or scoped
120
+ styling. SVGs are decorative and excluded from keyboard focus. Keep a visible
121
+ text label or an `aria-label` on the surrounding control; give standalone
122
+ status indicators an accessible label on their wrapper.
123
+
63
124
  ## Mobile behavior
64
125
 
65
126
  The bundled theme keeps the table as a horizontally scrollable grid on narrow
66
- screens so columns remain comparable. It adds a scroll cue, touch-sized query
67
- controls, button-based reordering alongside desktop drag-and-drop, sticky row
68
- selection, single-column metric cards, and bottom-sheet menus and dialogs. Keep
69
- the standard viewport meta tag in the host page:
127
+ screens so columns remain comparable. Narrow screens (up to 760px) and short,
128
+ touch-based landscape viewports use a mobile interaction model:
129
+
130
+ - **Tap to edit or delete:** filters, sorts, and metrics become readable summaries
131
+ with pencil buttons. Remove actions live inside the editor, including removal
132
+ of an entire OR group, and support Undo. There are no inline trash buttons.
133
+ Adding a filter, sort, or metric immediately
134
+ opens its editor. Filters can be combined with OR without relying on drag-and-drop.
135
+ - **Direct ordering:** columns, sorts, and metrics have leading drag handles
136
+ directly in the query builder, with no Order buttons. Column chips stay
137
+ wrapped and can move horizontally or between rows. Keyboard arrow keys reorder
138
+ a focused handle. A drop commits the new order; cancelled gestures leave the
139
+ query unchanged. Filters have no ordering controls because their order does
140
+ not affect results. Ordinary scrolling outside a handle does not start a drag.
141
+ - **Consistent sheets:** field and value pickers, conditions, cell/header actions,
142
+ saved queries, auto-update settings, and the column editor use bottom sheets
143
+ with a scrim, a visible close action, and pull-down dismissal from the handle.
144
+ Sheets trap and restore focus, lock background scrolling, respect safe areas
145
+ and reduced motion, and fit the visible viewport when the keyboard opens.
146
+ Mobile portals preserve inherited `--qt-*` theme variables.
147
+ - **Focused column workbench:** Selected, Catalogue, and Preview sections replace
148
+ stacked desktop panels. Selected columns reorder directly using their leading
149
+ handles; draft changes still require Apply.
150
+ Layout actions remain visible in the footer.
151
+ - **Compact spacing:** mobile sheets, lists, query sections, and editors reduce
152
+ padding and redundant headings. Query chips, their buttons, and inline handles
153
+ use a 32px minimum height with zero vertical padding; long summaries can wrap.
154
+ Filter, sort, and metric inputs use 36px controls. Keyword sections have extra breathing room
155
+ and solid horizontal rules on desktop and mobile.
156
+ - **Dense query setup:** filter, sort, and metric actions share a section header.
157
+ Summaries use one line when space allows and wrap without truncating values.
158
+ Labeled condition/value and function/measure pairs replace wrapping desktop
159
+ chips. Sort direction and null-value placement use native selects; regex
160
+ extraction stays optional. Its configuration opens a dialog (a bottom sheet on small screens) with a live, worker-isolated preview of up to 100 matching rows. The preview shows original values, extracted sort values, and no-match/null states; Apply commits any syntactically valid pattern even when the preview is unavailable or still loading, while Cancel leaves the sort unchanged. Grouping uses removable tags and a field picker.
161
+ Simple metric results share two-column rows; grouped results use the full width.
162
+ - **Touch-first controls:** dedicated drag handles, 16px text inputs,
163
+ sticky bulk actions, a horizontal table scroll cue, and the device's native
164
+ share sheet when available (clipboard fallback otherwise).
165
+
166
+ Filter and sort edits update the query immediately; **Done** dismisses the sheet. The column and metric workbenches retain explicit **Apply** draft workflows. Desktop chips, popovers, and drag-and-drop remain available.
167
+
168
+ Keep the standard viewport meta tag in the host page:
70
169
 
71
170
  ```html
72
171
  <meta name="viewport" content="width=device-width, initial-scale=1" />
73
172
  ```
74
173
 
75
174
  Applications that omit `theme.css` and use only `classNames` are responsible for
76
- providing their own responsive and touch-target styles.
175
+ providing their own responsive and touch-target styles, including styles for
176
+ the mobile summary, sheet, and reorder-list structural classes.
177
+
178
+ To run browser interaction checks, start `npm run demo`, install Playwright's
179
+ Chromium and WebKit browsers, and run `npm run test:mobile` from the repository
180
+ root. The suite covers narrow phones, small tablets, and phone landscape; it
181
+ also exercises real Chromium touch events and saves previews in `.context/`.
77
182
 
78
183
  See the [repository README](https://github.com/Pythia-Software/query-table#readme)
79
184
  for customization and backend integration details.
80
185
 
81
186
  ## SELECT editor
82
187
 
83
- `QueryBuilder` includes an **Edit columns** action. The exported `SelectColumnEditor` also accepts `{ api, onClose }` for standalone use. It supports draft column ordering, a searchable catalogue, sampled value frequencies, and a lazy-loaded CodeMirror formula editor with grouped live previews and regex inspection. Shared-definition saves and query-layout application are separate actions.
188
+ `QueryBuilder` includes a split **Add** button and **Reset** action for Columns: Add opens the field picker, while its caret opens the column customizer. Actions follow the selected chips on desktop and sit in the section header on small screens. The exported `SelectColumnEditor` also accepts `{ api, onClose }` for standalone use. It supports draft column ordering, a searchable catalogue, sampled value frequencies, and a lazy-loaded, dependency-free textarea formula editor with field/function suggestions, signature help, and compiler diagnostics with grouped live previews and regex inspection. A Function library beside the editor supports search by name or intent, browsing by concept and return type, and insertion at the cursor or around selected text; it stacks below the editor on narrow screens. Shared-definition saves and query-layout application are separate actions.
84
189
 
85
190
  ### Filter value presentation
86
191
 
@@ -103,3 +208,19 @@ The searchable static picker matches both labels and keys. Selection emits the
103
208
  canonical `value` only; presentation is never serialized into queries. A resolver
104
209
  can present a current value even when it is absent from the options. Strings without
105
210
  a presentation provider retain the existing select control.
211
+
212
+ ## Metric workbench and dashboards
213
+
214
+ QueryBuilder's **Edit metrics** opens the resizable four-pane `MetricsEditor`. Apply commits drafts together; Cancel discards them. Dashboard layout provides draggable canvas widths, whole-rem card sizing through corner handles or inputs, canvas presets, pointer/keyboard reordering, and inline names. Metrics use their own workbench on desktop and compact viewports; their changes commit on Apply.
215
+
216
+ Use the icon buttons beside **Panels** to show or hide the metric list, definition, references, and preview. At least one panel stays visible; the metric picker and Previous/Next controls remain available when the list is hidden. **See in dashboard** reveals the selected card in the same draft; **Back to metric**, the card’s pencil action, or a double-click returns to editing. Open settings and panel preferences survive these transitions.
217
+
218
+ Drag the dashboard canvas’s right edge to test responsive wrapping. Card corner handles adjust preferred width and height in whole rems; arrow keys resize and Shift increases the step. Escape or a cancelled pointer gesture restores the dimensions at drag start. Canvas and panel geometry are temporary preferences; card geometry commits on Apply. Removal offers **Undo remove**, and **Review issues** opens the metric needing attention while valid metrics continue to preview.
219
+
220
+ Use **Dialog size** for keyboard-editable pixel width/height controls; the native resize corner remains available. **Reset layout** restores the modal and all pane widths without changing metric drafts. Card minimum widths apply equally in the layout canvas and saved dashboard; narrower containers scroll horizontally.
221
+
222
+ **Value** requires no grouping. Incompatible drafts show an actionable diagnostic and block Apply; standalone `MetricCard` also rejects grouped or multiple scalar buckets. Lists suppress magnitude bars for signed results. Charts visibly disclose missing/error points and drawing limits while keeping ordinary captions compact. Malformed remote box/histogram summaries produce a card-local diagnostic instead of throwing during rendering.
223
+
224
+ `MetricsPanel` renders values, lists, pivots/flat tables, bars, lines, pie/ring, scatter, box, and histogram cards through native SVG and accessible data tables/tooltips. Pass a `MetricTheme` as `metricTheme` to QueryBuilder and `theme` to MetricsPanel for consistent typed-category palette assignments. Labels, temporal units/patterns, legends, list styling, axis labels, and card dimensions are query-local. `MetricCard` and `MetricsEditor` are also exported for standalone integration.
225
+
226
+ See [the production metrics guide](../../docs/metrics.md). Run `npm run test:metrics` against the demo for authoring/layout/persistence and chart interactions.