@tailor-platform/app-shell 1.7.0 → 1.8.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/app-shell",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "An opinionated React application framework for building ERP applications on Tailor Platform",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app-shell",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@base-ui/react": "^1.5.0",
|
|
47
|
+
"@internationalized/date": "3.12.2",
|
|
47
48
|
"@standard-schema/spec": "^1.1.0",
|
|
48
49
|
"@tailor-platform/auth-public-client": "^0.5.0",
|
|
49
50
|
"change-case": "^5.4.4",
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
"clsx": "^2.1.1",
|
|
52
53
|
"encoding-japanese": "^2.2.0",
|
|
53
54
|
"lucide-react": "^1.8.0",
|
|
55
|
+
"openai": "6.45.0",
|
|
54
56
|
"papaparse": "^5.5.3",
|
|
55
57
|
"react-router": "^7.14.1",
|
|
56
58
|
"sonner": "^2.0.7",
|
|
@@ -47,7 +47,9 @@ For the full upstream API of any component, follow the link to the published ref
|
|
|
47
47
|
|
|
48
48
|
**Import:** `import { Layout } from '@tailor-platform/app-shell'`
|
|
49
49
|
**Purpose:** Standard page container with header + 1–N column body. The most-used component — every page wraps content in `<Layout>`.
|
|
50
|
-
**API:** `Layout` (root) + `Layout.Column` + `Layout.Header`. `LayoutProps`: `columns` (number, default auto-detected from children), `gap`, `title`, `actions`, `className`, `style`.
|
|
50
|
+
**API:** `Layout` (root) + `Layout.Column` + `Layout.Header`. `LayoutProps`: `fill` (boolean), `columns` (number, default auto-detected from children), `gap`, `title`, `actions`, `className`, `style`.
|
|
51
|
+
|
|
52
|
+
**`fill`** — stretches the layout to the available height and bounds the column row so children can scroll internally instead of growing the page. Use on table-first pages (`<Layout fill>` + `DataTable`): the title, table toolbar, sticky column headers, and pagination footer stay pinned while only the rows scroll — see **`patterns/list-dense-scan.md`**. Omit on pages that should flow and scroll naturally (forms, dashboards).
|
|
51
53
|
|
|
52
54
|
**Column-count → width rules** (column count is auto-detected from `Layout.Column` children):
|
|
53
55
|
|
|
@@ -111,15 +113,29 @@ import { Button, Layout, Tabs } from "@tailor-platform/app-shell";
|
|
|
111
113
|
|
|
112
114
|
**Import:** `import { SidebarLayout } from '@tailor-platform/app-shell'`
|
|
113
115
|
**Purpose:** Top-level layout that mounts the sidebar and renders the page outlet.
|
|
114
|
-
**API:** `SidebarLayoutProps` — sidebar
|
|
116
|
+
**API:** `SidebarLayoutProps` — `sidebar`, `header`, and `children` are full-region slots (each defaults to a built-in). `sidebar` defaults to `SidebarLayout.DefaultSidebar`; `header` defaults to `SidebarLayout.DefaultHeader`. Used in `App.tsx`.
|
|
115
117
|
**Used in patterns:** consumed by AppShell init, not directly by page patterns. See `project-setup.md`.
|
|
116
118
|
|
|
117
|
-
### `
|
|
119
|
+
### `SidebarLayout.DefaultHeader` (`DefaultHeader`)
|
|
120
|
+
|
|
121
|
+
**Import:** `import { SidebarLayout } from '@tailor-platform/app-shell'` → `SidebarLayout.DefaultHeader` (also top-level `DefaultHeader`)
|
|
122
|
+
**Purpose:** The built-in top bar (trigger + breadcrumb, plus an `actions` cluster). Drop into `SidebarLayout`'s `header` slot to extend the header without rebuilding it.
|
|
123
|
+
**API:** `actions?: ReactNode | ReactNode[]` — the right-hand cluster (opinionated flex row). **Defaults to `[<AppearanceSwitcher />]`, and passing `actions` REPLACES the switcher** — include `<AppearanceSwitcher />` in the array to keep it. `actions={[]}` = empty right side.
|
|
124
|
+
**Used in patterns:** project-level header customization (notification bell, user menu). See `project-setup.md`.
|
|
125
|
+
|
|
126
|
+
### `SidebarLayout.DefaultSidebar` (`DefaultSidebar`), `SidebarGroup`, `SidebarItem`, `SidebarSeparator`
|
|
118
127
|
|
|
119
|
-
**Import:** `import {
|
|
128
|
+
**Import:** `import { SidebarLayout, SidebarGroup, SidebarItem, SidebarSeparator } from '@tailor-platform/app-shell'` → `SidebarLayout.DefaultSidebar` (also top-level `DefaultSidebar`)
|
|
120
129
|
**Purpose:** Sidebar composition. `DefaultSidebar` auto-resolves nav items from `appShellPageProps.meta` on each page; the others let you customize manually.
|
|
121
130
|
**Used in patterns:** sidebar is a project-level concern. See `project-setup.md`.
|
|
122
131
|
|
|
132
|
+
### `AppearanceSwitcher`
|
|
133
|
+
|
|
134
|
+
**Import:** `import { AppearanceSwitcher } from '@tailor-platform/app-shell'`
|
|
135
|
+
**Purpose:** Palette-icon dropdown for Light/Dark/System color mode. The default `SidebarLayout.DefaultHeader` action; also usable standalone (e.g. a sidebar footer). Include it in `DefaultHeader`'s `actions` array when customizing the header to keep it visible.
|
|
136
|
+
**API:** No props — reads/writes theme via `useTheme`.
|
|
137
|
+
**Used in patterns:** project-level. See `project-setup.md`.
|
|
138
|
+
|
|
123
139
|
### `CommandPalette`
|
|
124
140
|
|
|
125
141
|
**Import:** `import { CommandPalette } from '@tailor-platform/app-shell'`
|
|
@@ -78,7 +78,7 @@ export const columns: Column<Order>[] = [
|
|
|
78
78
|
|
|
79
79
|
```tsx
|
|
80
80
|
/* pattern: list/dense-scan */
|
|
81
|
-
import { DataTable, useDataTable, Button, Input } from "@tailor-platform/app-shell";
|
|
81
|
+
import { DataTable, Layout, useDataTable, Button, Input } from "@tailor-platform/app-shell";
|
|
82
82
|
import type { Order } from "./columns";
|
|
83
83
|
import { columns } from "./columns";
|
|
84
84
|
import type { DataTableData } from "@tailor-platform/app-shell";
|
|
@@ -92,19 +92,46 @@ export default function DenseScanList({ data, onCreateClick }: Props) {
|
|
|
92
92
|
const table = useDataTable({ data, columns });
|
|
93
93
|
|
|
94
94
|
return (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
// `fill` pins the page chrome for table-first pages: the title, toolbar,
|
|
96
|
+
// column header row, and pagination footer stay visible at every viewport
|
|
97
|
+
// height — only the table's rows region scrolls. Omit `fill` on pages
|
|
98
|
+
// that should flow and scroll naturally (forms, dashboards, articles).
|
|
99
|
+
<Layout fill>
|
|
100
|
+
<Layout.Header
|
|
101
|
+
title="Orders"
|
|
102
|
+
actions={[
|
|
103
|
+
<Button key="create" onClick={onCreateClick}>
|
|
104
|
+
Create Order
|
|
105
|
+
</Button>,
|
|
106
|
+
]}
|
|
107
|
+
/>
|
|
108
|
+
<Layout.Column>
|
|
109
|
+
<DataTable.Root value={table}>
|
|
110
|
+
<DataTable.Toolbar>
|
|
111
|
+
<Input placeholder="Search orders..." className="max-w-sm" />
|
|
112
|
+
</DataTable.Toolbar>
|
|
113
|
+
<DataTable.Table />
|
|
114
|
+
<DataTable.Footer>
|
|
115
|
+
<DataTable.Pagination />
|
|
116
|
+
</DataTable.Footer>
|
|
117
|
+
</DataTable.Root>
|
|
118
|
+
</Layout.Column>
|
|
119
|
+
</Layout>
|
|
104
120
|
);
|
|
105
121
|
}
|
|
106
122
|
```
|
|
107
123
|
|
|
124
|
+
## Page Layout & Internal Scrolling
|
|
125
|
+
|
|
126
|
+
Table-first pages should pin their chrome and scroll only the rows region. Wrap the page in `<Layout fill>`:
|
|
127
|
+
|
|
128
|
+
- `fill` stretches the layout to the available height and bounds the column row, so the `DataTable` shrinks to fit instead of growing past the viewport
|
|
129
|
+
- The `Layout.Header` (title/actions), `DataTable.Toolbar`, the column header row (sticky), and `DataTable.Footer` (pagination) stay visible at every viewport height — only the rows scroll vertically
|
|
130
|
+
- When the current page of rows fits, nothing stretches and no scrollbar appears — short tables render identically with or without `fill`
|
|
131
|
+
- Requires no extra styling on the page: the height chain (`AppShell` content area → `Layout fill` → `Layout.Column` → `DataTable.Root`) is wired by the components
|
|
132
|
+
|
|
133
|
+
Omit `fill` on pages that should flow and scroll naturally (forms, dashboards, articles) — the AppShell content area scrolls those.
|
|
134
|
+
|
|
108
135
|
## Variants
|
|
109
136
|
|
|
110
137
|
- **Toolbar chips only (`DataTable.Filters`)** — best when filters map cleanly to typed column metadata / enum facets
|
|
@@ -117,6 +144,7 @@ export default function DenseScanList({ data, onCreateClick }: Props) {
|
|
|
117
144
|
|
|
118
145
|
- Column count: 4-8 recommended
|
|
119
146
|
- Must include pagination — never render unbounded lists
|
|
147
|
+
- Table-first pages use `<Layout fill>` so title/toolbar/header/footer stay pinned and only rows scroll
|
|
120
148
|
- Status Badge colors must use design system tokens (variant prop)
|
|
121
149
|
- Bulk actions toolbar appears only when ≥1 row is selected
|
|
122
150
|
- Whole row is clickable via `onClickRow`; no per-row "View" / "Open" buttons
|
|
@@ -125,6 +153,7 @@ export default function DenseScanList({ data, onCreateClick }: Props) {
|
|
|
125
153
|
## Anti-patterns
|
|
126
154
|
|
|
127
155
|
- Building a bespoke table + custom pagination instead of `DataTable` + `useCollectionVariables`
|
|
156
|
+
- Hand-rolled `max-height`/`overflow` wrappers around `DataTable` to contain scrolling — use `<Layout fill>` instead
|
|
128
157
|
- Tabs that mutate only local UI state while pagination/filters assume the full server set
|
|
129
158
|
- Using `<table>` directly instead of `<DataTable>` for live collections
|
|
130
159
|
- Client-side filtering on 1000+ records without server-side support
|