@the-portland-company/shell 0.89.0 → 0.91.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/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## 0.91.0
2
+
3
+ Reverts the 0.88.0 and 0.89.0 shared form set (Ben 2026-10-24: restore the look from before the 10-22/23 shell wave; keep the 0.90.0 PageHeader, which matches the Spec). No live app uses 0.88 or newer.
4
+
5
+ - **Removed** `Button`, `Input`, `Select`, `Textarea`, `Checkbox`, `FileInput`, `FormField` and their types, from the root and `/native`.
6
+ - **Card** is back to its 0.87 form (plain padded box, `title` as an h3); the `--app-card-*` tokens are gone from chrome.css.
7
+ - **Theme.** The native-field border rule applies to every text-like control again (no `data-shell-field` exemption).
8
+ - **ESLint guard removed** (`@the-portland-company/shell/eslint`, its peer and dev dependency): its rules required the removed primitives.
9
+ - **Kept:** the 0.90.0 PageHeader, the router-agnostic PageHeader / BreadcrumbBar split and their `/native` exports (with `Card`, `HeaderTabBar`), and the `shell-version-check` bin.
10
+
11
+ ## 0.90.0
12
+
13
+ `PageHeader` matches the Spec (Reference/UI-Platform "Page header" and "Page header and width").
14
+
15
+ - **Surface and color.** The filled `--app-tab-header-bg` bar, white title, `text-slate-100` and bottom border are gone: the header sits on the page background and the title is Graphite (`--color-text`, fallback `#2F3136`). The title is now an `h1`.
16
+ - **Breadcrumbs.** The `breadcrumbs` prop is deprecated: accepted, renders nothing, `console.warn` once in dev.
17
+ - **Eyebrow.** Reads the mode color through `--color-accent-fg`, which follows the Mode's stamped primary (`--mode-accent`, the same token the tab strip uses for `modes.<mode>.primary`) and is pinned AA-safe for Petition. Never the white `modes.<mode>.accent`.
18
+ - **Spacing.** 22px above the header; 24px desktop gutter, 16px below `md`. `md:ml-60` sidebar offset unchanged.
19
+ - **Width.** `maxW` is deprecated and ignored (warns once in dev); the header spans its container.
20
+ - **Email guard.** A string `title` / `subtitle` containing an email address warns once in dev.
21
+ - Unchanged: 30px bold title, 11px uppercase eyebrow, 15px G4 subtitle, actions right, tabBar beneath.
22
+ - Tests: `__tests__/pageHeaderEyebrow.test.tsx`.
23
+
1
24
  ## 0.89.0
2
25
 
3
26
  Card follows the theme, and the form set gains Checkbox and FileInput. Follow-up to the 0.88.0 migrations.
package/README.md CHANGED
@@ -139,7 +139,8 @@ All `<ShellChrome>` props are optional — only supply what your app has. The ch
139
139
  | `<BrandLogo>` | `<img>` wrapper for the branded mode logo. |
140
140
  | `<BrandIcon name="...">` | Renders `/brand/icons/<name>.svg` from your `public/`. |
141
141
  | `<CommitCopyButton>` | Footer commit/version display with copy-to-clipboard. |
142
- | `<Card>`, `<PageHeader>` | Page-level layout primitives. |
142
+ | `<Card>` | Page-level layout primitive. |
143
+ | `<PageHeader>` | The page header (Reference/UI-Platform → "Page header"): no filled surface, 22px below the top bar, 24px gutter (16px below `md`), spans its container. Eyebrow in the mode color, 30px bold Graphite `h1` title, 15px G4 subtitle, `actions` right, `tabBar` beneath. `breadcrumbs` and `maxW` are **deprecated** (accepted, ignored, warn once in dev); width comes from `FormColumn` (960px) or the fluid frame. Warns in dev if `title` / `subtitle` is a string holding an email address. |
143
144
  | `<FormColumn>` | The one constrained layout inside the frame's fluid `<main>`: a left-aligned column, `max-width: 960px`, for form and settings pages. Also exported from `./native`. |
144
145
  | `<NavTabStrip>` (from `./native`) | The canonical page tab strip: underlined text tabs with a 2px underline in the mode color. Render it in the page body, below the page header. |
145
146
  | `<PageContainer>`, `<BreadcrumbBar>`, `<HeaderTabBar>` | **Deprecated for apps** (each warns in dev). The frame owns a fluid `<main>` (24px gutter, 16px below `md`, no max-width); there are no breadcrumbs; the tab strip is `NavTabStrip`. |
@@ -171,56 +172,13 @@ All `<ShellChrome>` props are optional — only supply what your app has. The ch
171
172
 
172
173
  ---
173
174
 
174
- ## Form primitives
175
+ ## Page primitives on `native`
175
176
 
176
- Shared `Button`, `Input`, `Select`, `Textarea`, `Checkbox`, `FileInput` and `Card`, styled from the shell's tokens (`--app-btn-*`, `--app-field-*`, `--color-*`). 5px radius, 12px horizontal padding.
177
+ `PageHeader`, `Card`, `FormColumn`, and the deprecated `BreadcrumbBar` and `HeaderTabBar` are also exported from `@the-portland-company/shell/native`, which needs no Chakra or react-router peer.
177
178
 
178
- | Export | Props |
179
- |---|---|
180
- | `<Button>` | `variant`: `primary` (default) \| `secondary` \| `ghost` \| `danger`; `size`: `md` (44px, default) \| `sm` (36px); `loading` (spinner, `aria-busy`, blocks clicks); `disabled`; `href` or `as` for a link-button (e.g. `as={Link} to="/x"`); `type` defaults to `button`; forwards its ref. |
181
- | `<Input>` | All native input props plus `label`, `helperText`, `error`, `invalid`, `wrapperClassName`. 44px tall. Forwards its ref to the `<input>`. |
182
- | `<Select>` | Same as `Input`, with `<option>` children. 44px tall. Forwards its ref to the `<select>`. |
183
- | `<Textarea>` | Same as `Input`, 88px minimum height. Forwards its ref to the `<textarea>`. |
184
- | `<Checkbox>` | All native checkbox props plus `label`, `description`, `indeterminate`, `invalid`, `wrapperClassName`. The whole row is a 44px touch target; accent fill; `data-shell-field`. Forwards its ref to the `<input>`. |
185
- | `<FileInput>` | The `type="file"` control: `label`, `helperText`, `error`, `invalid`, `accept`, `multiple`, `wrapperClassName`. 44px tall. Forwards its ref. `Input` does not accept `type="file"` or `"checkbox"`. |
186
- | `<Card>` | `title`, `subtitle`, `aside`, `actions`, `footer`, `bodyClassName`, `padding` (`none \| sm \| md \| lg`, default `md`), `minH`, plus any div props. Plain `<Card title>` is a padded box with an h3; any of `subtitle`, `aside`, `actions`, `footer`, `bodyClassName` gives a bordered header / body / footer. |
187
-
188
- **Card and dark mode.** Card and Checkbox read `--app-card-bg`, `--app-card-border`, `--app-card-fg` and `--app-card-fg-muted` from `chrome.css`: light on `:root`, dark under `.dark`. Do not paint a card white in app CSS; override these tokens if an app needs a different surface.
189
-
190
- An `error` message marks the control invalid (`aria-invalid`, red border) and replaces the helper text; the label, helper and error are wired with `htmlFor` and `aria-describedby`.
191
-
192
- These primitives (and `Card`, `PageHeader`, `FormColumn`) are also exported from `@the-portland-company/shell/native`, which needs no Chakra or react-router peer. Apps without those peers should import from `native`.
193
-
194
- **Rule:** apps must use these instead of a local `Button`, `Input`, `Select` or `Textarea`. Do not hand-roll form controls or button styles in an app; if a control needs a new variant or state, add it here so every app gets it.
195
-
196
- ## Enforcement
197
-
198
- Spec: Components — shared primitives are mandatory. Apps must not hand-roll Button/Card/Input/Select/Textarea, and must not fall behind the shell version. Both are checked mechanically.
199
-
200
- Adopt in three lines:
201
-
202
- ```js
203
- // eslint.config.js (ESLint 9+ flat config)
204
- import shell from '@the-portland-company/shell/eslint'
205
- export default [...shell.configs.recommended /* , your other configs */]
206
- ```
207
-
208
- ```json
209
- // package.json
210
- { "scripts": { "lint": "eslint . && shell-version-check" } }
211
- ```
212
-
213
- Run `shell-version-check` in CI too (it is a package `bin`, so `npx shell-version-check` works after install).
214
-
215
- | Rule (`politogy-shell/…`) | Fails on |
216
- |---|---|
217
- | `no-local-primitives` | Declaring or exporting a local `Button`, `Card`, `Input`, `Select`, `Textarea`, `Checkbox`, `FileInput`, `PageHeader` or `FormColumn` (re-exports from the shell are fine). |
218
- | `no-raw-control-styling` | JSX `<button>`, `<input>`, `<select>`, `<textarea>` with `className` or `style`. Allowed in a file that imports the shell primitive of the same kind (wrapping). `<input type="checkbox">` needs `Checkbox` and `<input type="file">` needs `FileInput`; importing `Input` does not excuse them. |
219
- | `no-global-control-classes` | `className` strings matching `\b(btn\|input)(-[a-z]+)?\b`, including inside `clsx(...)`, ternaries and template literals. |
220
-
221
- Escape hatch: put `// shell-primitive-exempt: <reason>` on the line above (or the same line as) the offending code. A reason is required. Prefer adding the missing variant to the shell instead.
179
+ ## shell-version-check
222
180
 
223
- `shell-version-check` exits 1 when the app's declared shell range cannot install the latest published version (`npm view`, 10s timeout; exit 2 if that lookup fails). `--offline` compares against the installed shell version instead; `--cwd=<dir>` checks another package. The shell package itself does not enable these rules.
181
+ `shell-version-check` (a package `bin`, so `npx shell-version-check` works after install) exits 1 when the app's declared shell range cannot install the latest published version (`npm view`, 10s timeout; exit 2 if that lookup fails). `--offline` compares against the installed shell version instead; `--cwd=<dir>` checks another package.
224
182
 
225
183
  ## CSS imports
226
184