@hearthscale/app-ui 0.0.0-stage → 0.2.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/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Simon Wagenfuehrer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ The fonts in `dist/fonts` are licensed under the SIL Open Font License 1.1
24
+ (`dist/fonts/OFL.txt`). The Remix Icon font in `dist/remixicon` is licensed
25
+ under the Apache License 2.0 (`dist/remixicon/License`).
package/README.md CHANGED
@@ -1,3 +1,168 @@
1
- # Temporary Holding Version
1
+ # @hearthscale/app-ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The UI kit of a Hearthscale app's view: the tokens and `hs-*` classes of the
4
+ Hearthscale design system, React parts built from it, and the whole Remix Icon
5
+ set. A view drawn with it looks like the rest of Hearthscale and follows the
6
+ person's theme, colourway and colour scheme.
7
+
8
+ ## In a view
9
+
10
+ Hearthscale loads the kit into every view an app packages: `ui.css`, with the
11
+ tokens and the `hs-*` classes, and `remixicon.css`, with the Remix Icon font
12
+ and its `ri-*` classes. The view's document is the theme root
13
+ (`<html class="hs-shell hs-view" data-theme="dark">`, `light` in the light
14
+ scheme), so you bundle no stylesheet of the kit. Write the classes:
15
+
16
+ ```html
17
+ <button class="hs-button" data-variant="secondary" data-size="sm">
18
+ <i class="hs-icon ri-add-line"></i>New note
19
+ </button>
20
+ ```
21
+
22
+ or, in a React view, import the parts:
23
+
24
+ ```tsx
25
+ import { Button, Card, Icon } from '@hearthscale/app-ui';
26
+
27
+ export function Notes() {
28
+ return (
29
+ <Card>
30
+ <Button icon={<Icon name="add-line" size={14} />}>New note</Button>
31
+ </Card>
32
+ );
33
+ }
34
+ ```
35
+
36
+ The parts are one ES module that leaves React 19 and `@floating-ui/dom` to
37
+ your bundle. Bundle them into your view: the host gives a packaged view the
38
+ stylesheets and maps `@modelcontextprotocol/ext-apps` to its own copy
39
+ (`/ui/mcp-apps.js`), so leave that one import out of the bundle.
40
+
41
+ A label names its action. Where a reason is needed, give it in a tooltip
42
+ (`useFloatingTips`), not in a line under the action.
43
+
44
+ ## The parts
45
+
46
+ | Kind | Parts |
47
+ | -------------- | ------------------------------------------------------------------------------------------ |
48
+ | Actions | `Button`, `IconButton` |
49
+ | Surfaces | `Card`, `SettingsCard`, `SettingsSection`, `EmptyState`, `Notice` |
50
+ | Scrolling | `OverlayScroll` |
51
+ | Rows | `ListRow`, `InfoRow`, `LinkRow`, `FactRow`, `ToggleRow` |
52
+ | Fields | `TextField`, `TextInput`, `Toggle`, `SegmentedControl`, `SettingsSearch`, `SettingsSelect` |
53
+ | Tabs | `SettingsTabs` |
54
+ | Status | `Chip`, `StatusWord` |
55
+ | Text | `PageTitle`, `Label`, `Mono` |
56
+ | Menus and tips | `MenuSurface`, `MItem`, `MSub`, `MDivider`, `MSection`, `anchorFrom`, `useFloatingTips` |
57
+ | Dialogs | `ShellConfirm` |
58
+ | Icons | `Icon` |
59
+
60
+ Each part draws the same `hs-*` classes as the same part in Hearthscale, so a
61
+ theme reaches it as it reaches the shell.
62
+
63
+ ## Icons
64
+
65
+ Every Remix Icon, by its name on [remixicon.com](https://remixicon.com/):
66
+
67
+ ```html
68
+ <i class="hs-icon ri-mail-line"></i>
69
+ ```
70
+
71
+ ```tsx
72
+ <Icon name="mail-line" size={16} />
73
+ ```
74
+
75
+ The mark takes the colour of the text around it, and the font size around it
76
+ or `size`. `hs-icon` gives it the box of its size and the states of the
77
+ design system's drawn marks: the dim ink in a picker or a search field, and
78
+ the press of the control it sits in. `IconName` names every icon, so your
79
+ editor completes the names. Draw no icon by hand.
80
+
81
+ Two marks are Hearthscale's own, drawn the same way: the sidebar open wide
82
+ and folded narrow, which Hearthscale's own sidebars show on the press that
83
+ opens and folds them. A press shows the shape the sidebar takes:
84
+
85
+ ```html
86
+ <i class="hs-icon hs-glyph-side-narrow"></i>
87
+ ```
88
+
89
+ ```tsx
90
+ <Icon name="side-narrow" size={16} />
91
+ ```
92
+
93
+ ## Tokens and classes
94
+
95
+ `dist/TOKENS.md` lists every token with its dark and light value, and
96
+ `dist/CLASSES.md` every public `hs-*` class, as do the
97
+ [tokens](https://hearthscale.com/docs/developers/themes/tokens) and
98
+ [classes](https://hearthscale.com/docs/developers/themes/classes) pages of
99
+ the documentation. A view may use every class there. Give your own rules tokens for every colour,
100
+ corner, size and duration, such as `color: var(--mut)` or
101
+ `border-radius: var(--r-card)`, so a theme and a colourway reach your view as
102
+ they reach the shell.
103
+
104
+ ## Previews and docs
105
+
106
+ Outside Hearthscale, import the two sheets and give the page the root the host
107
+ gives a view, on the plate a view sits on:
108
+
109
+ ```js
110
+ import '@hearthscale/app-ui/ui.css';
111
+ import '@hearthscale/app-ui/remixicon.css';
112
+ ```
113
+
114
+ ```html
115
+ <html class="hs-shell hs-view" data-theme="dark" style="background: var(--win)"></html>
116
+ ```
117
+
118
+ ## The rail icon
119
+
120
+ The rail shows the `icon` of your `app.json` 18 pixels square, beside
121
+ Hearthscale's own marks. Draw it to sit among them:
122
+
123
+ - **A 20 px grid.** A square `viewBox="0 0 24 24"` with the shape inside the
124
+ central 20 × 20, 2 units clear on every side.
125
+ - **Monochrome.** One colour, in the weight of Remix Icon's line marks: no
126
+ gradient, no shadow, no text.
127
+ - **`currentColor`.** Draw every shape in `currentColor` and set the ink once,
128
+ on the root. The rail shows the icon as a picture, which takes no colour from
129
+ the page, so give one file per scheme, the two differing in that one colour:
130
+ `#111111` in the light file, `#ffffff` in the dark file.
131
+
132
+ ```json
133
+ "icon": { "light": "assets/icon-light.svg", "dark": "assets/icon-dark.svg" }
134
+ ```
135
+
136
+ ```svg
137
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" color="#111111">
138
+ <path fill="currentColor" d="M5 4h14v2H5zM5 9h14v2H5zM5 14h9v2H5z" />
139
+ </svg>
140
+ ```
141
+
142
+ ## Licences
143
+
144
+ The code is MIT. Inter and JetBrains Mono are under the SIL Open Font License
145
+ 1.1 (`dist/fonts/OFL.txt`). The Remix Icon font, from `remixicon` 4.8.0, is
146
+ under the Apache License 2.0 (`dist/remixicon/License`).
147
+
148
+ ## Building, in the Hearthscale repository
149
+
150
+ `pnpm --filter @hearthscale/app-ui build` writes `dist/` from the design
151
+ system's build and the `remixicon` package, and writes `src/icon-names.ts`
152
+ from the font's sheet. It does not build `@hearthscale/ui`:
153
+ `pnpm --filter @hearthscale/app-ui... build` builds both, the design system
154
+ first. The parts come from the design system's `kit` entry
155
+ (`packages/ui/src/kit.ts`): a part is added there, never copied here. The
156
+ platform's build stages the sheets and fonts of this `dist/` beside the
157
+ daemon, with the MCP Apps SDK's browser build as `mcp-apps.js`, which the
158
+ build writes to `dist/host/` without the SDK's `console.debug` of every
159
+ message and the package does not publish, and the
160
+ daemon serves them to every view as `/ui/*`, so the kit a view gets and the
161
+ files this package publishes are one build.
162
+ `npm pack --dry-run` lists what a publish ships. `remixicon` stays at 4.8.0
163
+ here and in `@hearthscale/ui`: its later releases carry the Remix Icon License
164
+ v1.0 in place of the Apache License 2.0. Every Tiptap package takes one exact
165
+ version, here and in `@hearthscale/ui`, and they move together: a Tiptap
166
+ package of one release reads the internals of another, so a range lets an
167
+ app's install mix two releases, and `RichTextEditor` then breaks on Markdown
168
+ headings.