@estiva-app/ui 0.24.1 → 0.26.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.
Files changed (47) hide show
  1. package/dist/AttachmentCard.d.ts +48 -6
  2. package/dist/AttachmentCard.d.ts.map +1 -1
  3. package/dist/ErrorBoundary.d.ts +32 -0
  4. package/dist/ErrorBoundary.d.ts.map +1 -0
  5. package/dist/Lightbox.d.ts +30 -0
  6. package/dist/Lightbox.d.ts.map +1 -0
  7. package/dist/ListColumn.d.ts +9 -8
  8. package/dist/ListColumn.d.ts.map +1 -1
  9. package/dist/Menu.d.ts +7 -0
  10. package/dist/Menu.d.ts.map +1 -1
  11. package/dist/eslint/index.js +4 -4
  12. package/dist/eslint/index.js.map +2 -2
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +634 -456
  16. package/dist/index.js.map +4 -4
  17. package/package.json +1 -1
  18. package/registry.json +157 -20
  19. package/src/AttachmentCard.mdx +32 -8
  20. package/src/AttachmentCard.stories.tsx +54 -0
  21. package/src/AttachmentCard.test.tsx +115 -0
  22. package/src/AttachmentCard.tsx +212 -37
  23. package/src/CollapsibleSection.mdx +1 -1
  24. package/src/Divider.mdx +3 -3
  25. package/src/ErrorBoundary.mdx +66 -0
  26. package/src/ErrorBoundary.stories.tsx +64 -0
  27. package/src/ErrorBoundary.test.tsx +79 -0
  28. package/src/ErrorBoundary.tsx +54 -0
  29. package/src/Lightbox.mdx +71 -0
  30. package/src/Lightbox.stories.tsx +72 -0
  31. package/src/Lightbox.test.tsx +65 -0
  32. package/src/Lightbox.tsx +87 -0
  33. package/src/ListColumn.mdx +11 -3
  34. package/src/ListColumn.stories.tsx +34 -10
  35. package/src/ListColumn.test.tsx +20 -7
  36. package/src/ListColumn.tsx +34 -11
  37. package/src/Menu.mdx +5 -2
  38. package/src/Menu.stories.tsx +6 -7
  39. package/src/Menu.test.tsx +19 -1
  40. package/src/Menu.tsx +11 -1
  41. package/src/SectionHeader.mdx +5 -1
  42. package/src/SectionLabel.mdx +4 -2
  43. package/src/eslint/no-rebuilt-behaviour.ts +4 -4
  44. package/src/index.ts +3 -1
  45. package/src/registry/registry.test.ts +6 -6
  46. package/tailwind-preset.js +3 -0
  47. package/tokens.css +4 -0
@@ -16,6 +16,9 @@ title the toggle — that is where a section folds.
16
16
 
17
17
  - A sidebar or panel section that carries its own actions — add, sort,
18
18
  filter.
19
+ - **A heading over a group of rows, even with nothing to act on**: no
20
+ `actions`, and `hover="none"` so the row stays still under the pointer.
21
+ Never a row drawn by hand with a SectionLabel in it.
19
22
  - `showActions="always"` keeps the actions visible — for touch, or for a
20
23
  section whose actions are the point.
21
24
 
@@ -25,7 +28,8 @@ title the toggle — that is where a section folds.
25
28
 
26
29
  - A section that opens and closes → **CollapsibleSection**: the header,
27
30
  the rows, the slide, and a `storageKey` that remembers.
28
- - A title with no chevron and no actions → **SectionLabel** alone.
31
+ - A label inside a row of another shape — a dialog's section, a panel's
32
+ title, a card's line → **SectionLabel**.
29
33
  - A heading inside a menu → **MenuSection**.
30
34
  - Page-level headings → the `h*` type tokens.
31
35
 
@@ -15,13 +15,15 @@ how).
15
15
  ## When
16
16
 
17
17
  - **It is a bare label**: the row it sits in, and the room around it, are yours.
18
- - Titling a group of rows in a sidebar, a panel, a rail.
18
+ - A label inside a row of another shape: a dialog's section, a panel's
19
+ title, a card's line.
19
20
  - Inside a menu it arrives via **MenuSection** — don't place it there by
20
21
  hand.
21
22
 
22
23
  ## When not
23
24
 
24
- - A heading that also collapses or carries actions → **SectionHeader**.
25
+ - A heading over a group of rows → **SectionHeader**, even with nothing to
26
+ act on; a group that folds → **CollapsibleSection**.
25
27
  - The label above a stacked control → **Property** `stacked` — a field
26
28
  label is a different voice, at a different size, on purpose.
27
29
  - Page-level headings → the `h*` type tokens.
@@ -190,7 +190,7 @@ export const OWNED_BEHAVIOURS: OwnedBehaviour[] = [
190
190
  id: 'portal',
191
191
  behaviour: 'Floats on top of the page',
192
192
  baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Autocomplete', 'Tooltip', 'PreviewCard', 'Toast'],
193
- owners: ['DialogShell', 'ConfirmDialog', 'CommandPalette', 'Popover', 'Menu', 'Select', 'ChipInput', 'Tooltip', 'PreviewCard', 'Toast'],
193
+ owners: ['DialogShell', 'ConfirmDialog', 'CommandPalette', 'Lightbox', 'Popover', 'Menu', 'Select', 'ChipInput', 'Tooltip', 'PreviewCard', 'Toast'],
194
194
  reads: 'createPortal, called, or imported and never called',
195
195
  },
196
196
  {
@@ -204,21 +204,21 @@ export const OWNED_BEHAVIOURS: OwnedBehaviour[] = [
204
204
  id: 'page-keys',
205
205
  behaviour: 'Takes its keys by itself',
206
206
  baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard', 'Toast'],
207
- owners: ['DialogShell', 'Popover', 'Menu', 'Select', 'Tabs', 'Toolbar'],
207
+ owners: ['DialogShell', 'Lightbox', 'Popover', 'Menu', 'Select', 'Tabs', 'Toolbar'],
208
208
  reads: 'a keydown, keyup or keypress listener on window or document',
209
209
  },
210
210
  {
211
211
  id: 'focus',
212
212
  behaviour: 'Holds focus inside while open, and gives it back',
213
213
  baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox'],
214
- owners: ['DialogShell', 'CommandPalette'],
214
+ owners: ['DialogShell', 'CommandPalette', 'Lightbox'],
215
215
  reads: 'a focusin or focusout listener on window or document; the Tab key compared by hand',
216
216
  },
217
217
  {
218
218
  id: 'scroll-lock',
219
219
  behaviour: 'Stops the page behind it scrolling',
220
220
  baseUi: ['Dialog', 'AlertDialog'],
221
- owners: ['DialogShell'],
221
+ owners: ['DialogShell', 'Lightbox'],
222
222
  reads: 'overflow written into the style of document.body or document.documentElement',
223
223
  },
224
224
  {
package/src/index.ts CHANGED
@@ -44,6 +44,7 @@ export {
44
44
  type InlineChipProps,
45
45
  type InlineChipTone,
46
46
  } from './InlineChip'
47
+ export { Lightbox, type LightboxProps } from './Lightbox'
47
48
  export { Link, type LinkProps, type LinkVariant } from './Link'
48
49
  export { IconButton, type IconButtonProps, type IconButtonVariant } from './IconButton'
49
50
  export { Kbd, type KbdProps } from './Kbd'
@@ -60,10 +61,11 @@ export { DialogShell, type DialogShellProps } from './DialogShell'
60
61
  export { Divider, type DividerProps } from './Divider'
61
62
  export { EditableText, type EditableTextProps } from './EditableText'
62
63
  export { EmptyState, type EmptyStateProps } from './EmptyState'
64
+ export { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary'
63
65
  export { ProgressBar, type ProgressBarProps, type ProgressBarVariant } from './ProgressBar'
64
66
  export { SkeletonBar, SkeletonList, SkeletonRow } from './Skeleton'
65
67
  export { Breadcrumb, type BreadcrumbProps, type Crumb } from './Breadcrumb'
66
- export { EnterHint, Menu, MenuItem, MenuPanel, MenuRow, MenuSection, MenuSub, type MenuItemProps, type MenuPanelProps, type MenuProps, type MenuSubProps } from './Menu'
68
+ export { EnterHint, Menu, MenuItem, MenuPanel, MenuRow, MenuSection, MenuSeparator, MenuSub, type MenuItemProps, type MenuPanelProps, type MenuProps, type MenuSubProps } from './Menu'
67
69
  export { NavItem, type NavItemProps } from './NavItem'
68
70
  export { Popover, type PopoverProps } from './Popover'
69
71
  export { ScrollArea, type ScrollAreaProps } from './ScrollArea'
@@ -45,17 +45,17 @@ describe('the registry builds', () => {
45
45
  expect(registry.entries.map((one) => one.name).sort()).toEqual(values.map((one) => one.name).sort())
46
46
  })
47
47
 
48
- it('counts 84 names over 55 files: 77 components, 6 helpers and 1 hook (ListColumn and ToolbarLink joined in UIG-14)', () => {
48
+ it('counts 87 names over 57 files: 80 components, 6 helpers and 1 hook (Lightbox joined in UIG-35)', () => {
49
49
  // The reconciliation GATES.md §24 explains. If this changes, that changes.
50
50
  const kinds = registry.entries.reduce<Record<string, number>>((all, one) => ({ ...all, [one.kind]: (all[one.kind] ?? 0) + 1 }), {})
51
- expect(kinds).toEqual({ component: 77, helper: 6, hook: 1 })
52
- expect(new Set(registry.entries.map((one) => one.sourceFile)).size).toBe(55)
51
+ expect(kinds).toEqual({ component: 80, helper: 6, hook: 1 })
52
+ expect(new Set(registry.entries.map((one) => one.sourceFile)).size).toBe(57)
53
53
  })
54
54
 
55
55
  it('gives every entry a purpose, from its own page or from the comment above it', () => {
56
56
  expect(registry.entries.filter((one) => one.purpose.trim() === '')).toEqual([])
57
- expect(registry.entries.filter((one) => one.purposeFrom === 'page').length).toBe(55)
58
- expect(registry.entries.filter((one) => one.purposeFrom === 'comment').length).toBe(29)
57
+ expect(registry.entries.filter((one) => one.purposeFrom === 'page').length).toBe(57)
58
+ expect(registry.entries.filter((one) => one.purposeFrom === 'comment').length).toBe(30)
59
59
  })
60
60
 
61
61
  it('takes a name with a page of its own from the page, and a name without one from the code', () => {
@@ -278,7 +278,7 @@ describe('the ids point at something', () => {
278
278
  describe('a second parser agrees', async () => {
279
279
  const docgen = await import('react-docgen').catch(() => null)
280
280
 
281
- it.skipIf(!docgen)('finds the same props on all 77 components', async () => {
281
+ it.skipIf(!docgen)('finds the same props on all 79 components', async () => {
282
282
  if (!docgen) return
283
283
  const resolver = new docgen.builtinResolvers.FindExportedDefinitionsResolver({ limit: 0 })
284
284
  const byName = new Map(registry.entries.map((one) => [one.name, one]))
@@ -188,6 +188,9 @@ export default {
188
188
  'accent-wash': 'var(--accent-wash)',
189
189
  'success-wash': 'var(--success-wash)',
190
190
  'scrim': 'var(--scrim)',
191
+ // A picture viewer dims harder than a dialog does: the page behind is
192
+ // not context there, it is glare beside the thing you opened (UIG-35).
193
+ 'scrim-strong': 'var(--scrim-strong)',
191
194
  },
192
195
  boxShadow: {
193
196
  'sm': 'var(--shadow-sm)',
package/tokens.css CHANGED
@@ -79,6 +79,7 @@
79
79
  --glow-accent: 0 0 5px rgba(139, 92, 246, 0.6);
80
80
  --highlight-inset: inset 0 1px 0 rgba(255, 255, 255, 0.035);
81
81
  --scrim: rgba(0, 0, 0, 0.5);
82
+ --scrim-strong: rgba(0, 0, 0, 0.8);
82
83
  }
83
84
 
84
85
  /* ─── dark ─── Peek's dark theme (peek/src/index.css .dark, 2026-08-28). */
@@ -142,6 +143,7 @@
142
143
  --glow-accent: 0 0 5px rgba(167, 139, 250, 0.6);
143
144
  --highlight-inset: inset 0 1px 0 rgba(255, 255, 255, 0.035);
144
145
  --scrim: rgba(0, 0, 0, 0.5);
146
+ --scrim-strong: rgba(0, 0, 0, 0.8);
145
147
  }
146
148
 
147
149
 
@@ -209,6 +211,7 @@
209
211
  --glow-accent: 0 0 5px rgba(86, 200, 255, 0.6);
210
212
  --highlight-inset: inset 0 1px 0 rgba(255, 255, 255, 0.035);
211
213
  --scrim: rgba(0, 0, 0, 0.5);
214
+ --scrim-strong: rgba(0, 0, 0, 0.8);
212
215
  }
213
216
 
214
217
  /* ─── ship ─── Ship's palette (Katerina's ruling, 2026-08-28; ship/web/src/index.css). */
@@ -282,4 +285,5 @@
282
285
  --glow-accent: 0 0 5px rgba(75, 88, 212, 0.6);
283
286
  --highlight-inset: inset 0 1px 0 rgba(255, 255, 255, 0.035);
284
287
  --scrim: rgba(0, 0, 0, 0.5);
288
+ --scrim-strong: rgba(0, 0, 0, 0.8);
285
289
  }