@estiva-app/ui 0.38.0 → 0.40.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/dist/AppShell.d.ts +5 -2
- package/dist/AppShell.d.ts.map +1 -1
- package/dist/RichText.d.ts +78 -0
- package/dist/RichText.d.ts.map +1 -0
- package/dist/Sidebar.d.ts +7 -1
- package/dist/Sidebar.d.ts.map +1 -1
- package/dist/TopBar.d.ts +5 -2
- package/dist/TopBar.d.ts.map +1 -1
- package/dist/eslint/index.js +1 -0
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/gates/app-checks.d.ts.map +1 -1
- package/dist/gates/index.js +11 -1
- package/dist/gates/index.js.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +688 -542
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +97 -8
- package/src/AppShell.mdx +11 -3
- package/src/AppShell.stories.tsx +19 -0
- package/src/AppShell.test.tsx +20 -0
- package/src/AppShell.tsx +43 -24
- package/src/RichText.mdx +79 -0
- package/src/RichText.stories.tsx +91 -0
- package/src/RichText.test.tsx +149 -0
- package/src/RichText.tsx +294 -0
- package/src/Sidebar.tsx +10 -2
- package/src/TopBar.mdx +6 -4
- package/src/TopBar.tsx +6 -3
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/gates/app-checks.ts +7 -0
- package/src/index.ts +1 -0
- package/src/registry/registry.test.ts +5 -5
- package/stories/Choosing.mdx +1 -0
- package/tailwind-preset.js +1 -0
- package/tokens.css +15 -0
package/dist/AppShell.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* The frame of an app, in the
|
|
3
|
+
* The frame of an app, in the manners that pair with the TopBar's
|
|
4
4
|
* (Katerina, 2026-09-02: the two shells go together — the solid bar with
|
|
5
5
|
* the sidebar, the floating bar with the rail):
|
|
6
6
|
*
|
|
@@ -11,6 +11,9 @@ import type { ReactNode } from 'react';
|
|
|
11
11
|
* edge, the rail stands on the app background, and the content lives
|
|
12
12
|
* in the rounded card beside it (2026-09-02, the floating app's frame
|
|
13
13
|
* geometry; its collapse animation and launcher stay in the app).
|
|
14
|
+
* - `inset` — the structured frame, the other way round: the TopBar and
|
|
15
|
+
* the Sidebar stand on the ground, and the content is a lighter card
|
|
16
|
+
* beside them (Katerina, 28 September: Linear's layout, in any theme).
|
|
14
17
|
*
|
|
15
18
|
* The banner belongs to the content area (her ruling, 2026-09-02): it
|
|
16
19
|
* renders at the top of the main column — inside the card, in the
|
|
@@ -20,7 +23,7 @@ import type { ReactNode } from 'react';
|
|
|
20
23
|
* has no data and no routes.
|
|
21
24
|
*/
|
|
22
25
|
export interface AppShellProps {
|
|
23
|
-
variant?: 'solid' | 'floating';
|
|
26
|
+
variant?: 'solid' | 'floating' | 'inset';
|
|
24
27
|
/** The top bar's menu button, in an app whose navigation collapses. */
|
|
25
28
|
menu?: ReactNode;
|
|
26
29
|
/** The top bar's left: the app's logo mark, or its name as text. */
|
package/dist/AppShell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../src/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../src/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOtC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;IACxC,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,gEAAgE;IAChE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,qFAAqF;IACrF,GAAG,EAAE,SAAS,CAAA;IACd,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,aAAa,+BA8EjH"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Formatted text, drawn: headings, paragraphs, lists, a quote, code, a divider,
|
|
4
|
+
* a table and links.
|
|
5
|
+
*
|
|
6
|
+
* Both apps drew the same thing twice, from the same source — the text tree the
|
|
7
|
+
* protocol package builds (`toRenderTree` → `RenderBlock`, `RenderInline`) —
|
|
8
|
+
* and the two had drifted: headings, list markers, quotes and code differed,
|
|
9
|
+
* one app had tables and the other dropped them, one had links and the other
|
|
10
|
+
* printed the brackets (UIG-30). The look here is Katerina's picks of
|
|
11
|
+
* 28 September, one per difference, most of them Peek's.
|
|
12
|
+
*
|
|
13
|
+
* **It takes the tree, not the text.** The caller parses (the format comes from
|
|
14
|
+
* the item's tag, never from the body) and hands the blocks in. So this package
|
|
15
|
+
* does not depend on the protocol, and a caller can leave out a block it draws
|
|
16
|
+
* elsewhere before passing the rest. The types below are the tree's shape; the
|
|
17
|
+
* protocol's own types fit them.
|
|
18
|
+
*
|
|
19
|
+
* **Safe by construction.** The tree has nothing left to parse, and every
|
|
20
|
+
* string here reaches the page as a React child, so it is text. Nothing is set
|
|
21
|
+
* as HTML.
|
|
22
|
+
*
|
|
23
|
+
* **What a word points at stays the app's.** A person, an item from another
|
|
24
|
+
* app, a name the app recognises in plain text: `renderReference`,
|
|
25
|
+
* `renderText` and `renderBlock` are where each app draws its own.
|
|
26
|
+
*/
|
|
27
|
+
/** A run of text and the marks on it — the protocol's `RenderInline`. */
|
|
28
|
+
export interface RichTextRun {
|
|
29
|
+
text: string;
|
|
30
|
+
marks: readonly string[];
|
|
31
|
+
/** A `nostr:` address this run stands for. `text` is the address itself. */
|
|
32
|
+
reference?: string;
|
|
33
|
+
}
|
|
34
|
+
/** A block of the tree — the protocol's `RenderBlock`. */
|
|
35
|
+
export interface RichTextBlock {
|
|
36
|
+
type: string;
|
|
37
|
+
/** What the document called a block the tree does not know. */
|
|
38
|
+
typeName?: string;
|
|
39
|
+
/** The block's address, when it has one. Drawn as `data-block-id`. */
|
|
40
|
+
id?: string;
|
|
41
|
+
level?: 1 | 2 | 3;
|
|
42
|
+
language?: string;
|
|
43
|
+
/** A numbered list's first number. */
|
|
44
|
+
start?: number;
|
|
45
|
+
attrs?: Record<string, unknown>;
|
|
46
|
+
inline?: readonly RichTextRun[];
|
|
47
|
+
children?: readonly RichTextBlock[];
|
|
48
|
+
}
|
|
49
|
+
export type RichTextSize = 'default' | 'small';
|
|
50
|
+
export interface RichTextProps {
|
|
51
|
+
/** The tree, already parsed. */
|
|
52
|
+
blocks: readonly RichTextBlock[];
|
|
53
|
+
/**
|
|
54
|
+
* Default `default`, the size of text you read. `small` is the same text one
|
|
55
|
+
* step down, with every heading, list, quote and table kept: an item shown
|
|
56
|
+
* inside a card.
|
|
57
|
+
*/
|
|
58
|
+
size?: RichTextSize;
|
|
59
|
+
/**
|
|
60
|
+
* Draws plain text: what is left of a run once its links are drawn. Where an
|
|
61
|
+
* app turns words it recognises into chips. By default the text as it is.
|
|
62
|
+
*/
|
|
63
|
+
renderText?: (text: string) => ReactNode;
|
|
64
|
+
/** Draws a run that stands for an address. By default its text. */
|
|
65
|
+
renderReference?: (reference: string, run: RichTextRun) => ReactNode;
|
|
66
|
+
/**
|
|
67
|
+
* Draws a block this part has no design for (an attachment, a widget). Return
|
|
68
|
+
* `undefined` to leave it to the part, which draws its words.
|
|
69
|
+
*/
|
|
70
|
+
renderBlock?: (block: RichTextBlock) => ReactNode | undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* RichText's look, for a box you draw yourself: an editor's, so that what is
|
|
74
|
+
* being written looks the same as what is read. Put it on the editor's root.
|
|
75
|
+
*/
|
|
76
|
+
export declare function richTextClassName(size?: RichTextSize, className?: string): string;
|
|
77
|
+
export declare function RichText({ blocks, size, renderText, renderReference, renderBlock, }: RichTextProps): import("react").JSX.Element | null;
|
|
78
|
+
//# sourceMappingURL=RichText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichText.d.ts","sourceRoot":"","sources":["../src/RichText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAA;AAIlD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CACpC;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;IACxC,mEAAmE;IACnE,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,SAAS,CAAA;IACpE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,GAAG,SAAS,CAAA;CAC9D;AA0BD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,YAAwB,EAAE,SAAS,CAAC,EAAE,MAAM,UAGnF;AAyKD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,IAAgB,EAChB,UAA2B,EAC3B,eAA+C,EAC/C,WAAW,GACZ,EAAE,aAAa,sCAQf"}
|
package/dist/Sidebar.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* The navigation column: 240px, a hairline on its right, the surface
|
|
4
4
|
* behind it, scrolling independently of the content beside it (the shell
|
|
@@ -7,6 +7,10 @@ import type { ReactNode } from 'react';
|
|
|
7
7
|
* What goes inside is the caller's: NavItem rows, a SectionLabel heading
|
|
8
8
|
* in a 32px row over a group. Desktop only — there is no narrow-screen
|
|
9
9
|
* drawer.
|
|
10
|
+
*
|
|
11
|
+
* In AppShell's `inset` frame it stands on the ground instead: no hairline,
|
|
12
|
+
* no surface, the content's card beside it (Katerina, 28 September). The
|
|
13
|
+
* frame tells it so; the caller passes nothing.
|
|
10
14
|
*/
|
|
11
15
|
export interface SidebarProps {
|
|
12
16
|
/** Names the navigation region for assistive tech. */
|
|
@@ -14,5 +18,7 @@ export interface SidebarProps {
|
|
|
14
18
|
children: ReactNode;
|
|
15
19
|
className?: string;
|
|
16
20
|
}
|
|
21
|
+
/** Set by AppShell's `inset` frame: the sidebar stands on the ground, with no line or surface of its own. */
|
|
22
|
+
export declare const SidebarOnGround: import("react").Context<boolean>;
|
|
17
23
|
export declare function Sidebar({ 'aria-label': ariaLabel, children, className }: SidebarProps): import("react").JSX.Element;
|
|
18
24
|
//# sourceMappingURL=Sidebar.d.ts.map
|
package/dist/Sidebar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../src/Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../src/Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIjE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,6GAA6G;AAC7G,eAAO,MAAM,eAAe,kCAAuB,CAAA;AAEnD,wBAAgB,OAAO,CAAC,EAAE,YAAY,EAAE,SAAuB,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,YAAY,+BAenG"}
|
package/dist/TopBar.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* The 52px top bar, in
|
|
3
|
+
* The 52px top bar, in three manners:
|
|
4
4
|
*
|
|
5
5
|
* - `solid` — in flow: a hairline under it, the surface behind it, the
|
|
6
6
|
* frame's first row (2026-09-02, verbatim from the structured app; its
|
|
@@ -9,6 +9,9 @@ import type { ReactNode } from 'react';
|
|
|
9
9
|
* background, and the bar itself ignores the pointer — only its clusters
|
|
10
10
|
* catch clicks, so the content underneath stays reachable (2026-09-02,
|
|
11
11
|
* verbatim from the floating app).
|
|
12
|
+
* - `inset` — in flow like `solid`, but standing on the ground: no hairline
|
|
13
|
+
* and no surface, above a sidebar on the ground and the content's card
|
|
14
|
+
* (Katerina, 28 September).
|
|
12
15
|
*
|
|
13
16
|
* Geometry both apps agreed on before extraction: 52px tall, `pl-5
|
|
14
17
|
* pr-[26px]`, right cluster `gap-[6px]`. The left region is two slots
|
|
@@ -18,7 +21,7 @@ import type { ReactNode } from 'react';
|
|
|
18
21
|
* searched; it only knows where those go.
|
|
19
22
|
*/
|
|
20
23
|
export interface TopBarProps {
|
|
21
|
-
variant?: 'solid' | 'floating';
|
|
24
|
+
variant?: 'solid' | 'floating' | 'inset';
|
|
22
25
|
/** Far left: the menu button, in an app whose navigation collapses. Stays the caller's — the bar only places it. */
|
|
23
26
|
menu?: ReactNode;
|
|
24
27
|
/** Beside the menu button: the app's logo mark, or its name as text. */
|
package/dist/TopBar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopBar.d.ts","sourceRoot":"","sources":["../src/TopBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC
|
|
1
|
+
{"version":3,"file":"TopBar.d.ts","sourceRoot":"","sources":["../src/TopBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;IACxC,oHAAoH;IACpH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,wEAAwE;IACxE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,mGAAmG;IACnG,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,gEAAgE;IAChE,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,WAAW,+BAsB9F"}
|
package/dist/eslint/index.js
CHANGED