diff --git a/.changeset/async-fetch-error-state.md b/.changeset/async-fetch-error-state.md deleted file mode 100644 index 47bad86f..00000000 --- a/.changeset/async-fetch-error-state.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@tailor-platform/app-shell": minor ---- - -Add a built-in error state to `Combobox.Async`, `Autocomplete.Async`, and `Select.Async` - -When an async fetcher throws or rejects, the components now render an inline error state in the popover — a "Couldn't load results." message plus a **Retry** button that re-runs the last fetch — instead of silently falling back to the misleading "No results." empty state. This makes failed fetches distinguishable from genuinely-empty results without any consumer code. - -The debounce/abort lifecycle is handled centrally: aborted/superseded requests are ignored, and outages are de-duped so typing during an outage doesn't stack repeated announcements. - -Three new props on each `.Async` component: - -| Prop | Type | Default | Description | -| -------------- | -------------------------- | -------------------------- | ------------------------------------------------------------------ | -| `errorText` | `string` | `"Couldn't load results."` | Message shown in the popover when the fetcher fails | -| `retryText` | `string` | `"Retry"` | Label for the retry button | -| `onFetchError` | `(error: unknown) => void` | - | Called once per outage when a fetch fails (logging/error tracking) | - -The `Combobox.useAsync` / `Autocomplete.useAsync` / `Select.useAsync` hooks now also expose `error` and a `retry()` function and accept an `onFetchError` option, for consumers building custom compositions with `Parts`. diff --git a/.changeset/cool-badgers-type.md b/.changeset/cool-badgers-type.md deleted file mode 100644 index 366e12b2..00000000 --- a/.changeset/cool-badgers-type.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@tailor-platform/app-shell": minor ---- - -Add a built-in `/__appinfo` page to `AppShell` for exposing app metadata and the current AppShell version. - -```tsx - -``` - -The page stays out of AppShell's built-in auto-generated sidebar navigation, appears in the Command Palette as a page entry, and includes a copy button for the rendered app information. diff --git a/.changeset/data-table-columns-and-row-nav.md b/.changeset/data-table-columns-and-row-nav.md deleted file mode 100644 index 4394da0f..00000000 --- a/.changeset/data-table-columns-and-row-nav.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@tailor-platform/app-shell": minor ---- - -DataTable: sticky/pinned columns and user column settings - -- **Pinned columns** — add `pin: "left" | "right"` to a `Column` to freeze it during horizontal scroll (sticky offsets are measured from the rendered layout; `width` is optional but recommended for stable sizing). The selection column auto-pins left and the row-actions column auto-pins right, with a subtle freeze shadow at the frozen edge once content scrolls under it. -- **Column settings** — pass `columnSettings` to `DataTable.Toolbar` to render a built-in "Columns" control (top-right) that lets users show/hide columns, reorder them (drag), and change pinning by dragging a column between the Fixed left / Scrollable / Fixed right zones. -- **Persisted column layout** — pass a stable `tableId` to `useDataTable` to persist each user's column visibility, order, and pinning to `localStorage` (per-user preference; not stored in the URL). Omit for in-memory-only layout. -- `Table.Root` now accepts an optional `containerRef` for its scroll container. diff --git a/.changeset/data-table-filter-redesign.md b/.changeset/data-table-filter-redesign.md deleted file mode 100644 index f8332ad0..00000000 --- a/.changeset/data-table-filter-redesign.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@tailor-platform/app-shell": minor ---- - -Redesign `DataTable.Filters` for a faster, more direct filtering experience. - -- **Add-filter panel**: replaces the old popover + nested selects with a single popover laid out in up to three columns — **field ▸ condition ▸ value**. The condition column appears for fields with more than one operator; single-operator fields (enum, uuid) go straight to the value. Values are drafted and committed with an **Apply**/**Update** button, and the panel stays open so several filters can be added in a row. A per-field **Clear** and a sticky **Clear all filters** are built in. -- **Segmented filter chips**: each active filter renders as `field │ operator │ value │ ✕`. The operator segment opens a searchable dropdown to switch the condition; the value segment opens the type-specific editor. Long values are truncated. -- **Date & time use app-shell's own components**: single date → inline `Calendar`; single datetime → inline calendar + a "Choose time" picker; `date`/`datetime` **between** → one inline calendar with **From / To** tabs; `time` → native time input. (Swaps to the dedicated date-range / datetime pickers 1:1 once those land.) -- Friendlier operator labels (`is`, `is not`, `is between`, `is any of`, …), multi-select enum values summarized as "N items" (localized), an inline error for reversed `between` ranges, and a consistent primary-colored checkbox across every filter surface. -- **New `slot` prop** on `DataTable.Filters` (`"all"` | `"chips"` | `"add"`) to render the chips and the **Add filter** trigger separately for custom toolbar layouts (e.g. trigger in a header row, chips on the row below). diff --git a/.changeset/fix-datatable-row-selection-highlight.md b/.changeset/fix-datatable-row-selection-highlight.md deleted file mode 100644 index d66a069d..00000000 --- a/.changeset/fix-datatable-row-selection-highlight.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@tailor-platform/app-shell": patch ---- - -Fix DataTable row-selection highlight. Selecting a row now tints the **whole** row, not just the pinned selection/actions cells. The row sets `data-state="selected"` (which `Table.Row` keys its selected background off of) in addition to the existing `aria-selected`; previously only the pinned cells — which carry their own `group-aria-selected:bg-muted` — were highlighted. diff --git a/.changeset/standalone-checkbox.md b/.changeset/standalone-checkbox.md deleted file mode 100644 index 1f80223c..00000000 --- a/.changeset/standalone-checkbox.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@tailor-platform/app-shell": minor ---- - -Add standalone `Checkbox` component - -- New `Checkbox` — a styled boolean control wrapping Base UI's checkbox. Supports controlled (`checked`) and uncontrolled (`defaultChecked`) use, an `indeterminate` state, and an optional inline `label`. Integrates with `Field` and React Hook Form for label association, `disabled`, and invalid/error state exactly like `Input`/`Select` (no bespoke `error` prop) — drive it via `Controller` with `onCheckedChange`/`inputRef`. The invalid state is styled off both `data-invalid` (AppShell `Field.Root`) and `aria-invalid` (shadcn-style `FormControl`), so it fits either form stack. -- DataTable now uses `Checkbox` internally for row selection, the header select-all (indeterminate), the enum and case-sensitive filter controls, and the column-settings visibility toggles — replacing the previously hand-rolled, slightly inconsistent checkbox styling with one shared control. diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index d856e5ef..d3e2d676 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,65 @@ # @tailor-platform/app-shell +## 1.10.0 + +### Minor Changes + +- 73d0c0a: Add a built-in error state to `Combobox.Async`, `Autocomplete.Async`, and `Select.Async` + + When an async fetcher throws or rejects, the components now render an inline error state in the popover — a "Couldn't load results." message plus a **Retry** button that re-runs the last fetch — instead of silently falling back to the misleading "No results." empty state. This makes failed fetches distinguishable from genuinely-empty results without any consumer code. + + The debounce/abort lifecycle is handled centrally: aborted/superseded requests are ignored, and outages are de-duped so typing during an outage doesn't stack repeated announcements. + + Three new props on each `.Async` component: + + | Prop | Type | Default | Description | + | -------------- | -------------------------- | -------------------------- | ------------------------------------------------------------------ | + | `errorText` | `string` | `"Couldn't load results."` | Message shown in the popover when the fetcher fails | + | `retryText` | `string` | `"Retry"` | Label for the retry button | + | `onFetchError` | `(error: unknown) => void` | - | Called once per outage when a fetch fails (logging/error tracking) | + + The `Combobox.useAsync` / `Autocomplete.useAsync` / `Select.useAsync` hooks now also expose `error` and a `retry()` function and accept an `onFetchError` option, for consumers building custom compositions with `Parts`. + +- 16c1046: Add a built-in `/__appinfo` page to `AppShell` for exposing app metadata and the current AppShell version. + + ```tsx + + ``` + + The page stays out of AppShell's built-in auto-generated sidebar navigation, appears in the Command Palette as a page entry, and includes a copy button for the rendered app information. + +- 35ab98a: DataTable: sticky/pinned columns and user column settings + + - **Pinned columns** — add `pin: "left" | "right"` to a `Column` to freeze it during horizontal scroll (sticky offsets are measured from the rendered layout; `width` is optional but recommended for stable sizing). The selection column auto-pins left and the row-actions column auto-pins right, with a subtle freeze shadow at the frozen edge once content scrolls under it. + - **Column settings** — pass `columnSettings` to `DataTable.Toolbar` to render a built-in "Columns" control (top-right) that lets users show/hide columns, reorder them (drag), and change pinning by dragging a column between the Fixed left / Scrollable / Fixed right zones. + - **Persisted column layout** — pass a stable `tableId` to `useDataTable` to persist each user's column visibility, order, and pinning to `localStorage` (per-user preference; not stored in the URL). Omit for in-memory-only layout. + - `Table.Root` now accepts an optional `containerRef` for its scroll container. + +- b32f003: Redesign `DataTable.Filters` for a faster, more direct filtering experience. + + - **Add-filter panel**: replaces the old popover + nested selects with a single popover laid out in up to three columns — **field ▸ condition ▸ value**. The condition column appears for fields with more than one operator; single-operator fields (enum, uuid) go straight to the value. Values are drafted and committed with an **Apply**/**Update** button, and the panel stays open so several filters can be added in a row. A per-field **Clear** and a sticky **Clear all filters** are built in. + - **Segmented filter chips**: each active filter renders as `field │ operator │ value │ ✕`. The operator segment opens a searchable dropdown to switch the condition; the value segment opens the type-specific editor. Long values are truncated. + - **Date & time use app-shell's own components**: single date → inline `Calendar`; single datetime → inline calendar + a "Choose time" picker; `date`/`datetime` **between** → one inline calendar with **From / To** tabs; `time` → native time input. (Swaps to the dedicated date-range / datetime pickers 1:1 once those land.) + - Friendlier operator labels (`is`, `is not`, `is between`, `is any of`, …), multi-select enum values summarized as "N items" (localized), an inline error for reversed `between` ranges, and a consistent primary-colored checkbox across every filter surface. + - **New `slot` prop** on `DataTable.Filters` (`"all"` | `"chips"` | `"add"`) to render the chips and the **Add filter** trigger separately for custom toolbar layouts (e.g. trigger in a header row, chips on the row below). + +- 7832718: Add standalone `Checkbox` component + + - New `Checkbox` — a styled boolean control wrapping Base UI's checkbox. Supports controlled (`checked`) and uncontrolled (`defaultChecked`) use, an `indeterminate` state, and an optional inline `label`. Integrates with `Field` and React Hook Form for label association, `disabled`, and invalid/error state exactly like `Input`/`Select` (no bespoke `error` prop) — drive it via `Controller` with `onCheckedChange`/`inputRef`. The invalid state is styled off both `data-invalid` (AppShell `Field.Root`) and `aria-invalid` (shadcn-style `FormControl`), so it fits either form stack. + - DataTable now uses `Checkbox` internally for row selection, the header select-all (indeterminate), the enum and case-sensitive filter controls, and the column-settings visibility toggles — replacing the previously hand-rolled, slightly inconsistent checkbox styling with one shared control. + +### Patch Changes + +- 7a9e958: Fix DataTable row-selection highlight. Selecting a row now tints the **whole** row, not just the pinned selection/actions cells. The row sets `data-state="selected"` (which `Table.Row` keys its selected background off of) in addition to the existing `aria-selected`; previously only the pinned cells — which carry their own `group-aria-selected:bg-muted` — were highlighted. + ## 1.9.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index d6945923..6f278a3e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@tailor-platform/app-shell", - "version": "1.9.0", + "version": "1.10.0", "description": "An opinionated React application framework for building ERP applications on Tailor Platform", "keywords": [ "app-shell",