@estiva-app/ui 0.25.0 → 0.27.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 (69) hide show
  1. package/dist/AttachmentCard.d.ts +48 -6
  2. package/dist/AttachmentCard.d.ts.map +1 -1
  3. package/dist/Lightbox.d.ts +30 -0
  4. package/dist/Lightbox.d.ts.map +1 -0
  5. package/dist/eslint/index.js +4 -4
  6. package/dist/eslint/index.js.map +2 -2
  7. package/dist/gates/app-checks.d.ts.map +1 -1
  8. package/dist/gates/{chunk-GTQZEHPC.js → chunk-I7CJLUPM.js} +13 -1
  9. package/dist/gates/chunk-I7CJLUPM.js.map +7 -0
  10. package/dist/gates/cli.js +1 -1
  11. package/dist/gates/index.js +7 -3
  12. package/dist/gates/index.js.map +2 -2
  13. package/dist/gates/status.d.ts +2 -0
  14. package/dist/gates/status.d.ts.map +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +594 -464
  18. package/dist/index.js.map +4 -4
  19. package/dist/registry/{app-DQI6WLHR.js → app-FXN4EI34.js} +2 -2
  20. package/dist/registry/app.d.ts.map +1 -1
  21. package/dist/registry/{chunk-W2B2G7OE.js → chunk-6OH3TWGF.js} +59 -1
  22. package/dist/registry/chunk-6OH3TWGF.js.map +7 -0
  23. package/dist/registry/{chunk-WMFF3MPP.js → chunk-XCBN2EKW.js} +3 -2
  24. package/dist/registry/{chunk-WMFF3MPP.js.map → chunk-XCBN2EKW.js.map} +2 -2
  25. package/dist/registry/cli.js +69 -8
  26. package/dist/registry/cli.js.map +3 -3
  27. package/dist/registry/contract.d.ts +29 -0
  28. package/dist/registry/contract.d.ts.map +1 -0
  29. package/dist/registry/gated-5CPIUQAW.js +230 -0
  30. package/dist/registry/gated-5CPIUQAW.js.map +7 -0
  31. package/dist/registry/gated.d.ts +31 -0
  32. package/dist/registry/gated.d.ts.map +1 -0
  33. package/dist/registry/index.d.ts +1 -0
  34. package/dist/registry/index.d.ts.map +1 -1
  35. package/dist/registry/index.js +15 -3
  36. package/package.json +1 -1
  37. package/registry.json +94 -4
  38. package/src/AttachmentCard.mdx +32 -8
  39. package/src/AttachmentCard.stories.tsx +54 -0
  40. package/src/AttachmentCard.test.tsx +115 -0
  41. package/src/AttachmentCard.tsx +212 -37
  42. package/src/CollapsibleSection.stories.tsx +6 -0
  43. package/src/Lightbox.mdx +71 -0
  44. package/src/Lightbox.stories.tsx +72 -0
  45. package/src/Lightbox.test.tsx +65 -0
  46. package/src/Lightbox.tsx +87 -0
  47. package/src/ListColumn.stories.tsx +6 -0
  48. package/src/MenuItem.stories.tsx +151 -135
  49. package/src/Person.stories.tsx +7 -0
  50. package/src/PersonTrigger.stories.tsx +7 -0
  51. package/src/SectionHeader.stories.tsx +5 -0
  52. package/src/eslint/no-rebuilt-behaviour.ts +4 -4
  53. package/src/gates/app-checks.ts +6 -2
  54. package/src/gates/status.ts +15 -0
  55. package/src/index.ts +1 -0
  56. package/src/registry/app.test.ts +14 -1
  57. package/src/registry/app.ts +5 -1
  58. package/src/registry/cli.ts +79 -7
  59. package/src/registry/contract.test.ts +158 -0
  60. package/src/registry/contract.ts +108 -0
  61. package/src/registry/gated.test.ts +98 -0
  62. package/src/registry/gated.ts +308 -0
  63. package/src/registry/index.ts +1 -0
  64. package/src/registry/registry.test.ts +4 -4
  65. package/tailwind-preset.js +3 -0
  66. package/tokens.css +4 -0
  67. package/dist/gates/chunk-GTQZEHPC.js.map +0 -7
  68. package/dist/registry/chunk-W2B2G7OE.js.map +0 -7
  69. /package/dist/registry/{app-DQI6WLHR.js.map → app-FXN4EI34.js.map} +0 -0
@@ -5,10 +5,17 @@ import { type ComponentPropsWithRef } from 'react';
5
5
  * Peek's two attachment components, class for class (UIG-27, Katerina's ruling
6
6
  * of 14 September that both apps draw one): `FileAttachmentCard`, the card on
7
7
  * something already posted, and `PendingAttachmentChip`, the card in a composer
8
- * waiting to go. What stays in each app is what only the app can do: fetch the
9
- * bytes with the reader's own permission, open an image full screen, save a
10
- * file. The card is told the result — a `src`, an `href`, a `state` — and hands
11
- * a click back through `onOpen`, `onDownload` and `onRemove`.
8
+ * waiting to go. The card is told the result — a `src`, an `href`, a `state` —
9
+ * and hands a click back through `onOpen`, `onDownload` and `onRemove`.
10
+ *
11
+ * **It now does the rest of the job too** (UIG-35, Katerina 20 September):
12
+ * given a `remoteSrc` and the app's `fetchImage`, it fetches a file the reader
13
+ * needs permission for and draws the wait and the refusal; it opens a picture
14
+ * full screen in the package's `Lightbox`; and with `download` it saves the
15
+ * file. Peek and Ship had each written those three around it, 174 and 181 lines
16
+ * that did the same things differently — Ship's pictures never opened at all.
17
+ * What stays an app's is the one thing only it knows: how to fetch with its own
18
+ * authorization.
12
19
  *
13
20
  * Two shapes, decided by the file: an **image** with a picture is a 180px
14
21
  * thumbnail you can open; anything else is a 240px **row** — a type tile, the
@@ -30,10 +37,45 @@ export interface AttachmentCardProps extends Omit<ComponentPropsWithRef<'div'>,
30
37
  href?: string;
31
38
  /** The picture an image card draws. Without it an image is drawn as a row. */
32
39
  src?: string;
33
- /** What a click on an image's picture does — the app's full-screen view. */
40
+ /**
41
+ * What the picture shows, where the sender said — Ship carries one on every
42
+ * `imeta`. It is what a screen reader reads and what the viewer is named
43
+ * with; `name` is still the file's name, under the thumbnail. Without it the
44
+ * name does both jobs.
45
+ */
46
+ alt?: string;
47
+ /**
48
+ * A file the app has to *fetch* before it can be used — one on a relay, where
49
+ * reading it needs the reader's own authorization (UIG-35). Give `fetchImage`
50
+ * with it. For a picture the card waits, draws it, and says so if it cannot
51
+ * be read, so no app writes that state machine again; for a document the
52
+ * result is where the row opens, and until it lands the row is dimmed rather
53
+ * than pretending to open. Ignored when `src` is set.
54
+ */
55
+ remoteSrc?: string;
56
+ /**
57
+ * The full-size picture, fetched only when someone opens it. A thread of
58
+ * screenshots would otherwise pull every original at full size to draw them
59
+ * at 112px. Until it arrives the viewer shows the thumbnail.
60
+ */
61
+ remoteFullSrc?: string;
62
+ /** How this app fetches a picture it is allowed to read: a URL in, a URL the
63
+ * browser can draw out (an object URL, usually). */
64
+ fetchImage?: (url: string) => Promise<string>;
65
+ /**
66
+ * What a click on an image's picture does. Without it the card **opens the
67
+ * picture itself**, full screen, in the package's `Lightbox` — which is what
68
+ * both apps wanted and one of them had written by hand.
69
+ */
34
70
  onOpen?: () => void;
35
71
  /** Shows a download control on hover or focus, and calls this. */
36
72
  onDownload?: () => void;
73
+ /**
74
+ * Shows the download control and **saves the file itself**, under `name`:
75
+ * the original where there is one (`remoteFullSrc`), otherwise what the card
76
+ * is drawing. Use `onDownload` instead when the app must do it another way.
77
+ */
78
+ download?: boolean;
37
79
  /** Waiting to be sent: the composer's 200px row, with a remove control on its corner. */
38
80
  pending?: boolean;
39
81
  /** Removes a pending card. */
@@ -48,5 +90,5 @@ export interface AttachmentCardProps extends Omit<ComponentPropsWithRef<'div'>,
48
90
  /** The note's full words, on hover, where the line is short. */
49
91
  noteHint?: string;
50
92
  }
51
- export declare function AttachmentCard({ name, size, contentType, href, src, onOpen, onDownload, pending, onRemove, state, note, noteHint, className, ...props }: AttachmentCardProps): import("react").JSX.Element;
93
+ export declare function AttachmentCard({ name, size, contentType, href, src, alt, remoteSrc, remoteFullSrc, fetchImage, onOpen, onDownload, download, pending, onRemove, state, note, noteHint, className, ...props }: AttachmentCardProps): import("react").JSX.Element;
52
94
  //# sourceMappingURL=AttachmentCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentCard.d.ts","sourceRoot":"","sources":["../src/AttachmentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,qBAAqB,EAAW,MAAM,OAAO,CAAA;AAyB9F;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AA2FzG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzF,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,yFAAyF;IACzF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAC3B,sGAAsG;IACtG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,GAAG,EACH,MAAM,EACN,UAAU,EACV,OAAe,EACf,QAAQ,EACR,KAAe,EACf,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,mBAAmB,+BAuJrB"}
1
+ {"version":3,"file":"AttachmentCard.d.ts","sourceRoot":"","sources":["../src/AttachmentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,qBAAqB,EAAW,MAAM,OAAO,CAAA;AA0BzG;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AA2FzG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzF,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;yDACqD;IACrD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7C;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yFAAyF;IACzF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAC3B,sGAAsG;IACtG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAwED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,GAAG,EACH,GAAG,EACH,SAAS,EACT,aAAa,EACb,UAAU,EACV,MAAM,EACN,UAAU,EACV,QAAgB,EAChB,OAAe,EACf,QAAQ,EACR,KAAe,EACf,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,mBAAmB,+BAgNrB"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A picture, full screen, on a scrim — the thing a thumbnail opens into.
3
+ *
4
+ * Both apps had written this by hand and neither had got it right: Peek's
5
+ * `ImageLightbox` and the `FrameLightbox` before it were `createPortal` plus a
6
+ * fixed `<div>`, with no Escape, no focus trap and nothing to return focus to
7
+ * (Peek scan F5, P4; migration B22, Katerina 10 September). Ship never had one
8
+ * at all, so a screenshot in an issue could not be looked at.
9
+ *
10
+ * On Base UI's `Dialog`, like `DialogShell`: the portal, the backdrop, Escape,
11
+ * the outside press and the focus trap are its, and what is written here is the
12
+ * picture, the scrim and the close button.
13
+ *
14
+ * **The close button is this component's own**, not an `IconButton`: a 26px
15
+ * square with no fill is hard to find on top of a photograph, which is why Peek
16
+ * had written an escape note beside its own. A 32px round button on an elevated
17
+ * fill with a hairline reads on any picture.
18
+ */
19
+ export interface LightboxProps {
20
+ /** The picture to show. Swapping it — a thumbnail for the original, once it
21
+ * arrives — swaps what is on screen, with no flash of nothing. */
22
+ src: string;
23
+ /** What the picture is. Names the viewer for assistive tech too. */
24
+ alt: string;
25
+ onClose: () => void;
26
+ /** Extra classes on the picture itself. */
27
+ className?: string;
28
+ }
29
+ export declare function Lightbox({ src, alt, onClose, className }: LightboxProps): import("react").JSX.Element;
30
+ //# sourceMappingURL=Lightbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lightbox.d.ts","sourceRoot":"","sources":["../src/Lightbox.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,aAAa;IAC5B;uEACmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,aAAa,+BAoDvE"}
@@ -369,7 +369,7 @@ var OWNED_BEHAVIOURS = [
369
369
  id: "portal",
370
370
  behaviour: "Floats on top of the page",
371
371
  baseUi: ["Dialog", "AlertDialog", "Popover", "Menu", "Select", "Combobox", "Autocomplete", "Tooltip", "PreviewCard", "Toast"],
372
- owners: ["DialogShell", "ConfirmDialog", "CommandPalette", "Popover", "Menu", "Select", "ChipInput", "Tooltip", "PreviewCard", "Toast"],
372
+ owners: ["DialogShell", "ConfirmDialog", "CommandPalette", "Lightbox", "Popover", "Menu", "Select", "ChipInput", "Tooltip", "PreviewCard", "Toast"],
373
373
  reads: "createPortal, called, or imported and never called"
374
374
  },
375
375
  {
@@ -383,21 +383,21 @@ var OWNED_BEHAVIOURS = [
383
383
  id: "page-keys",
384
384
  behaviour: "Takes its keys by itself",
385
385
  baseUi: ["Dialog", "AlertDialog", "Popover", "Menu", "Select", "Combobox", "Tooltip", "PreviewCard", "Toast"],
386
- owners: ["DialogShell", "Popover", "Menu", "Select", "Tabs", "Toolbar"],
386
+ owners: ["DialogShell", "Lightbox", "Popover", "Menu", "Select", "Tabs", "Toolbar"],
387
387
  reads: "a keydown, keyup or keypress listener on window or document"
388
388
  },
389
389
  {
390
390
  id: "focus",
391
391
  behaviour: "Holds focus inside while open, and gives it back",
392
392
  baseUi: ["Dialog", "AlertDialog", "Popover", "Menu", "Select", "Combobox"],
393
- owners: ["DialogShell", "CommandPalette"],
393
+ owners: ["DialogShell", "CommandPalette", "Lightbox"],
394
394
  reads: "a focusin or focusout listener on window or document; the Tab key compared by hand"
395
395
  },
396
396
  {
397
397
  id: "scroll-lock",
398
398
  behaviour: "Stops the page behind it scrolling",
399
399
  baseUi: ["Dialog", "AlertDialog"],
400
- owners: ["DialogShell"],
400
+ owners: ["DialogShell", "Lightbox"],
401
401
  reads: "overflow written into the style of document.body or document.documentElement"
402
402
  },
403
403
  {