@espressif/dashboard-ui-components 1.5.0 → 1.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/.claude/rules/dashboard-ui-consumption.md +31 -0
- package/.cursor/rules/dashboard-ui-consumption.mdc +31 -0
- package/CHANGELOG.md +110 -0
- package/README.md +1 -0
- package/dist/{chunk-WR54R7J6.js → chunk-HYSNJBDF.js} +1 -1
- package/dist/{chunk-X7LDLZBT.js → chunk-IYMCZTJ5.js} +688 -40
- package/dist/common/index.js +2 -2
- package/dist/components/index.d.ts +109 -4
- package/dist/components/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/src/styles/colors.css +3 -2
|
@@ -110,6 +110,37 @@ Things agents get wrong about it:
|
|
|
110
110
|
full page reload.
|
|
111
111
|
- No `prose` wrapper or spacing utilities are needed; it owns its own vertical rhythm.
|
|
112
112
|
|
|
113
|
+
## Editing code and JSON
|
|
114
|
+
|
|
115
|
+
`CodeEditor` (from `/components`) is the editable counterpart of `Code`: a form field
|
|
116
|
+
with syntax highlighting. Use it instead of `Textarea` for JSON payloads, policies or
|
|
117
|
+
templates; use `Code` for read-only display.
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { CodeEditor } from '@espressif/dashboard-ui-components/components'
|
|
121
|
+
|
|
122
|
+
<CodeEditor
|
|
123
|
+
{...field} // react-hook-form: native onChange + ref to the <textarea>
|
|
124
|
+
lang="json" // "text" for base64 / opaque data
|
|
125
|
+
theme={dark ? 'dark' : 'light'}
|
|
126
|
+
label="Payload"
|
|
127
|
+
errorContent={fieldState.error?.message}
|
|
128
|
+
onFormatError={(e) => setFormatError(String(e))}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Things agents get wrong about it:
|
|
133
|
+
|
|
134
|
+
- `onChange` receives the native change event, like `Textarea` — there is no `onValueChange`.
|
|
135
|
+
- It does **not** validate. The built-in Format button (JSON only) pretty-prints and
|
|
136
|
+
reports invalid JSON to `onFormatError`; schema rules (zod etc.) stay in the app.
|
|
137
|
+
Pass `formatter` for other languages; do not reimplement Format in `headerActions`.
|
|
138
|
+
- Esc, then Tab, moves focus out (Tab otherwise indents). Inside a `Sheet` or `Dialog`,
|
|
139
|
+
Esc also reaches the overlay's own Escape handler and closes it; guard with
|
|
140
|
+
`onEscapeKeyDown={(e) => { if ((e.target as Element).closest('[data-slot="code-editor"]')) e.preventDefault() }}`
|
|
141
|
+
if that matters.
|
|
142
|
+
- `className` / `style` style the editor box, not the `<textarea>`.
|
|
143
|
+
|
|
113
144
|
## Bundle size and tooling (what agents should assume)
|
|
114
145
|
|
|
115
146
|
- The published library is **pre-bundled ESM** (tsup). Consumers receive **large `dist` chunks**, not one file per source component.
|
|
@@ -107,6 +107,37 @@ Things agents get wrong about it:
|
|
|
107
107
|
full page reload.
|
|
108
108
|
- No `prose` wrapper or spacing utilities are needed; it owns its own vertical rhythm.
|
|
109
109
|
|
|
110
|
+
## Editing code and JSON
|
|
111
|
+
|
|
112
|
+
`CodeEditor` (from `/components`) is the editable counterpart of `Code`: a form field
|
|
113
|
+
with syntax highlighting. Use it instead of `Textarea` for JSON payloads, policies or
|
|
114
|
+
templates; use `Code` for read-only display.
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { CodeEditor } from '@espressif/dashboard-ui-components/components'
|
|
118
|
+
|
|
119
|
+
<CodeEditor
|
|
120
|
+
{...field} // react-hook-form: native onChange + ref to the <textarea>
|
|
121
|
+
lang="json" // "text" for base64 / opaque data
|
|
122
|
+
theme={dark ? 'dark' : 'light'}
|
|
123
|
+
label="Payload"
|
|
124
|
+
errorContent={fieldState.error?.message}
|
|
125
|
+
onFormatError={(e) => setFormatError(String(e))}
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Things agents get wrong about it:
|
|
130
|
+
|
|
131
|
+
- `onChange` receives the native change event, like `Textarea` — there is no `onValueChange`.
|
|
132
|
+
- It does **not** validate. The built-in Format button (JSON only) pretty-prints and
|
|
133
|
+
reports invalid JSON to `onFormatError`; schema rules (zod etc.) stay in the app.
|
|
134
|
+
Pass `formatter` for other languages; do not reimplement Format in `headerActions`.
|
|
135
|
+
- Esc, then Tab, moves focus out (Tab otherwise indents). Inside a `Sheet` or `Dialog`,
|
|
136
|
+
Esc also reaches the overlay's own Escape handler and closes it; guard with
|
|
137
|
+
`onEscapeKeyDown={(e) => { if ((e.target as Element).closest('[data-slot="code-editor"]')) e.preventDefault() }}`
|
|
138
|
+
if that matters.
|
|
139
|
+
- `className` / `style` style the editor box, not the `<textarea>`.
|
|
140
|
+
|
|
110
141
|
## Bundle size and tooling (what agents should assume)
|
|
111
142
|
|
|
112
143
|
- The published library is **pre-bundled ESM** (tsup). Consumers receive **large `dist` chunks**, not one file per source component.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,116 @@ All notable changes to this project are documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres
|
|
5
5
|
to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [1.6.0] - 2026-09-25
|
|
8
|
+
|
|
9
|
+
A minor release adding an editable code field (`CodeEditor`), a warning
|
|
10
|
+
state to `StatusCardList`, fixed-value fields to `KeyValueManager`, and
|
|
11
|
+
rolling presets plus a clear action to `DateRangePicker`. Focus rings now
|
|
12
|
+
follow the primary colour, and a render loop in `DataTable` is fixed. No
|
|
13
|
+
breaking changes.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **`CodeEditor`** — an editable, syntax-highlighted code field. It has the
|
|
17
|
+
same header, file name, copy button and Shiki themes as `Code`, and works
|
|
18
|
+
in a form like `Textarea`: controlled or uncontrolled, native `onChange` /
|
|
19
|
+
`onBlur` / `name`, a ref to the `<textarea>`, so `{...field}` and
|
|
20
|
+
`{...register(name)}` from react-hook-form work unchanged (including
|
|
21
|
+
values written by `setValue` / `reset`). Carries `label`, `required`,
|
|
22
|
+
`hintContent`, `error`, `errorContent`, `disabled`, `readOnly` and
|
|
23
|
+
`placeholder`.
|
|
24
|
+
- Tab indents (every line of a multi-line selection), Shift+Tab outdents,
|
|
25
|
+
Enter keeps the current indentation, and all three are undoable with
|
|
26
|
+
Cmd/Ctrl+Z. Press Esc, then Tab, to move focus out of the editor. Keys
|
|
27
|
+
pressed during IME composition are left alone.
|
|
28
|
+
- For `lang="json"` the header has a Format button that pretty-prints with
|
|
29
|
+
`tabSize` spaces (undoable, fires `onChange`). Invalid JSON is left
|
|
30
|
+
unchanged and passed to `onFormatError`. `formatter` supplies a
|
|
31
|
+
formatter for any language; `formatButton={false}` hides the button;
|
|
32
|
+
`formatLabel` sets its accessible name, and `copyLabel` sets the copy
|
|
33
|
+
button's. `headerActions` adds further
|
|
34
|
+
header controls.
|
|
35
|
+
- `hideHeader` removes the header. It is also left out automatically when
|
|
36
|
+
there is no `fileName`, no `headerActions`, and neither a copy nor a
|
|
37
|
+
format button.
|
|
38
|
+
- Other props: `lang` (default `"json"`; `"text"` for base64 or other
|
|
39
|
+
opaque data), `theme` / `themes`, `fileName`, `icon`, `copyButton`,
|
|
40
|
+
`minHeight` / `maxHeight` of the editing area, `wrap` (soft-wrap long
|
|
41
|
+
lines; off by default) and `tabSize` (default 2).
|
|
42
|
+
- Above `maxHighlightLength` characters (default 10 000) the editor shows
|
|
43
|
+
plain text, so typing in a large document stays responsive. Highlighting
|
|
44
|
+
one keystroke of a 64 KB JSON document takes about 64 ms on an Apple M4,
|
|
45
|
+
and a 10 KB one about 13 ms. Languages or themes outside the curated
|
|
46
|
+
Shiki bundle also render as plain text, with one console warning per
|
|
47
|
+
language.
|
|
48
|
+
- Text renders at 16px below the `md` breakpoint so iOS Safari does not
|
|
49
|
+
zoom on focus, and at 13px (like `Code`) from `md` up.
|
|
50
|
+
- **`DateRangePicker`** — rolling presets and a clear action:
|
|
51
|
+
- New presets `last-1-hour`, `last-24-hours`, `past-7-days` and
|
|
52
|
+
`past-30-days`. They end at the moment they are selected instead of
|
|
53
|
+
snapping to day boundaries, so `past-7-days` and `past-30-days` include
|
|
54
|
+
today (the existing `last-7-days` and `last-30-days` end yesterday at
|
|
55
|
+
23:59 and are unchanged). `ROLLING_PRESET_IDS` lists them, so a consumer
|
|
56
|
+
can recompute the range with `computeDateRange` when it refreshes data.
|
|
57
|
+
- New `clearable` prop. While a preset or custom range is selected, the
|
|
58
|
+
menu shows a "Clear" item that calls the new `onClear` callback and
|
|
59
|
+
closes the menu. `clearLabel` overrides its text (default `"Clear"`).
|
|
60
|
+
- Code with an exhaustive `switch` over `DateRangePickerPresetId` must
|
|
61
|
+
handle the four new IDs.
|
|
62
|
+
- **`KeyValueManager`** — two new `KeyValueManagerFieldMeta` options:
|
|
63
|
+
- `options` renders the field in the add popover as a select limited to
|
|
64
|
+
those values, and rejects any other value. Use it when the allowed values
|
|
65
|
+
are known up front, for example the header columns of an uploaded CSV.
|
|
66
|
+
- `regexFlags` is passed to the `RegExp` built from `regex`, so a pattern
|
|
67
|
+
can use Unicode property escapes such as `\p{L}` with `"u"`. Patterns
|
|
68
|
+
without flags behave as before.
|
|
69
|
+
- New label `selectPlaceholder` (default `"Select"`) for fields with
|
|
70
|
+
`options`.
|
|
71
|
+
- **`StatusCardList`** — new `"warning"` value for `StatusCardState`, for a
|
|
72
|
+
step that finished but only partly succeeded (for example, a bulk job where
|
|
73
|
+
some items failed). It uses the `warning` colour token for the card, avatar
|
|
74
|
+
and text, and a `TriangleAlert` end icon. Code with an exhaustive `switch`
|
|
75
|
+
over `StatusCardState` must handle the new value.
|
|
76
|
+
- **AI agent rules** — `.claude/rules/dashboard-ui-consumption.md` and
|
|
77
|
+
`.cursor/rules/dashboard-ui-consumption.mdc` gain an "Editing code and JSON"
|
|
78
|
+
section on `CodeEditor`: when to use it instead of `Textarea` / `Code`, the
|
|
79
|
+
react-hook-form wiring, and the usual mistakes (there is no `onValueChange`,
|
|
80
|
+
it does not validate, Esc inside a `Sheet` / `Dialog`).
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
- **Focus ring colour** — `--color-ring` now defaults to `var(--color-primary)`
|
|
84
|
+
in light and dark mode instead of fixed blues (`#0053c2` / `#7cd9ff`).
|
|
85
|
+
Components that draw their focus ring with `ring-ring` (`Input`, `Select`,
|
|
86
|
+
`Textarea`, `SearchBox`, `AdvancedSearchBox`, `ToggleGroup`, `Tabs`,
|
|
87
|
+
`Switch`, `Checkbox`, `Dialog` and others) previously kept the blue ring in
|
|
88
|
+
apps that re-theme `primary`, while `Button` and the clickable cards already
|
|
89
|
+
used `ring-primary`, so focus rings in the same toolbar did not match.
|
|
90
|
+
- With the default theme, light mode's ring moves from `#0053c2` to the
|
|
91
|
+
primary `#0071e3`; dark mode is unchanged (both were `#7cd9ff`).
|
|
92
|
+
- Apps that want a ring distinct from primary can still set `--color-ring`.
|
|
93
|
+
- **`DateRangePicker`** — a picker without a `presets` prop shows every
|
|
94
|
+
preset, so its menu now also lists the four new rolling presets. They sit
|
|
95
|
+
among the trailing ranges, which run shortest to longest: "Last 1 hour" and
|
|
96
|
+
"Last 24 hours" come before "Last 1 day", and "Past 7 days" / "Past 30 days"
|
|
97
|
+
come just before "Last 7 days" / "Last 30 days". `PRESET_IDS` follows the
|
|
98
|
+
same order. Pass `presets` to keep the previous menu.
|
|
99
|
+
- **`Code`** — the header's copy button now has an accessible name and
|
|
100
|
+
tooltip (`aria-label` / `title` "Copy"); before, the icon-only button had
|
|
101
|
+
no name for screen readers. The header is now shared with `CodeEditor` and
|
|
102
|
+
is otherwise unchanged.
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
- **`DataTable`** — no longer triggers an extra internal re-render every time
|
|
106
|
+
`data` changes identity. TanStack Table resets the page index when `data`
|
|
107
|
+
changes unless pagination is manual, and each reset was a table-internal
|
|
108
|
+
state update. The page index here is always 0 (paging belongs to the
|
|
109
|
+
consumer through `pageIndex` / `onNextPage` / `onPrevPage`), so the reset
|
|
110
|
+
did nothing useful. With a consumer passing a fresh array on every render
|
|
111
|
+
(`data?.items ?? []`), those updates could pile up into React's "Maximum
|
|
112
|
+
update depth exceeded" under load, for example when switching to a
|
|
113
|
+
server-paginated table while the main thread was busy. The table now sets
|
|
114
|
+
`autoResetPageIndex: false` and memoizes its pagination state. Rows are
|
|
115
|
+
still capped at `pageSize`, so existing tables render the same.
|
|
116
|
+
|
|
7
117
|
## [1.5.0] - 2026-09-22
|
|
8
118
|
|
|
9
119
|
A minor release adding a combined date and time control.
|
package/README.md
CHANGED
|
@@ -455,6 +455,7 @@ version you have installed is the shipped type declarations:
|
|
|
455
455
|
| Alert | Alert banners (optionally dismissible) |
|
|
456
456
|
| Link | Styled anchor element — colour-tinted pill, or `variant="ghost"` for a bare inline link |
|
|
457
457
|
| Code | Syntax-highlighted code blocks |
|
|
458
|
+
| CodeEditor | Editable, syntax-highlighted code field (`Code` look, `Textarea` form behaviour), with Format (JSON) and Copy buttons |
|
|
458
459
|
| MarkdownContent | Renders a markdown string with library primitives (GFM, heading anchors; raw HTML is escaped, not parsed) |
|
|
459
460
|
| CopiableText / CopyButton | Copy-to-clipboard utilities |
|
|
460
461
|
| ProgressBar | Progress indicator |
|