@trebired/frontend 0.4.2 → 1.0.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 (223) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +112 -80
  3. package/dist/config/index.d.ts +6 -45
  4. package/dist/config/index.d.ts.map +1 -1
  5. package/dist/config/index.js +19 -252
  6. package/dist/config/index.js.map +1 -1
  7. package/dist/config/module.d.ts +5 -0
  8. package/dist/config/module.d.ts.map +1 -0
  9. package/dist/config/module.js +124 -0
  10. package/dist/config/module.js.map +1 -0
  11. package/dist/config/normalize.d.ts +9 -0
  12. package/dist/config/normalize.d.ts.map +1 -0
  13. package/dist/config/normalize.js +116 -0
  14. package/dist/config/normalize.js.map +1 -0
  15. package/dist/config/palette.d.ts +8 -0
  16. package/dist/config/palette.d.ts.map +1 -0
  17. package/dist/config/palette.js +104 -0
  18. package/dist/config/palette.js.map +1 -0
  19. package/dist/config/scales-css.d.ts +8 -0
  20. package/dist/config/scales-css.d.ts.map +1 -0
  21. package/dist/config/scales-css.js +99 -0
  22. package/dist/config/scales-css.js.map +1 -0
  23. package/dist/config/scales.d.ts +4 -0
  24. package/dist/config/scales.d.ts.map +1 -0
  25. package/dist/config/scales.js +55 -0
  26. package/dist/config/scales.js.map +1 -0
  27. package/dist/config/scss.d.ts +4 -0
  28. package/dist/config/scss.d.ts.map +1 -0
  29. package/dist/config/scss.js +134 -0
  30. package/dist/config/scss.js.map +1 -0
  31. package/dist/config/shared.d.ts +9 -0
  32. package/dist/config/shared.d.ts.map +1 -0
  33. package/dist/config/shared.js +27 -0
  34. package/dist/config/shared.js.map +1 -0
  35. package/dist/config/theme.d.ts +6 -0
  36. package/dist/config/theme.d.ts.map +1 -0
  37. package/dist/config/theme.js +133 -0
  38. package/dist/config/theme.js.map +1 -0
  39. package/dist/config/types.d.ts +127 -0
  40. package/dist/config/types.d.ts.map +1 -0
  41. package/dist/config/types.js +2 -0
  42. package/dist/config/types.js.map +1 -0
  43. package/dist/fullscreen/components/index.d.ts +20 -0
  44. package/dist/fullscreen/components/index.d.ts.map +1 -0
  45. package/dist/fullscreen/components/index.js +19 -0
  46. package/dist/fullscreen/components/index.js.map +1 -0
  47. package/dist/fullscreen/index.d.ts +24 -3
  48. package/dist/fullscreen/index.d.ts.map +1 -1
  49. package/dist/fullscreen/index.js +268 -7
  50. package/dist/fullscreen/index.js.map +1 -1
  51. package/dist/fullscreen/styles/index.scss +71 -0
  52. package/dist/index.d.ts +7 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +9 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/layout/components/index.d.ts +43 -0
  57. package/dist/layout/components/index.d.ts.map +1 -0
  58. package/dist/layout/components/index.js +53 -0
  59. package/dist/layout/components/index.js.map +1 -0
  60. package/dist/layout/index.d.ts +27 -0
  61. package/dist/layout/index.d.ts.map +1 -0
  62. package/dist/layout/index.js +80 -0
  63. package/dist/layout/index.js.map +1 -0
  64. package/dist/layout/styles/index.scss +137 -0
  65. package/dist/react/index.d.ts +14 -0
  66. package/dist/react/index.d.ts.map +1 -1
  67. package/dist/react/index.js +14 -0
  68. package/dist/react/index.js.map +1 -1
  69. package/dist/server/index.d.ts +5 -0
  70. package/dist/server/index.d.ts.map +1 -0
  71. package/dist/server/index.js +5 -0
  72. package/dist/server/index.js.map +1 -0
  73. package/dist/sidebar/components/index.d.ts +35 -0
  74. package/dist/sidebar/components/index.d.ts.map +1 -0
  75. package/dist/sidebar/components/index.js +49 -0
  76. package/dist/sidebar/components/index.js.map +1 -0
  77. package/dist/sidebar/index.d.ts +62 -0
  78. package/dist/sidebar/index.d.ts.map +1 -0
  79. package/dist/sidebar/index.js +247 -0
  80. package/dist/sidebar/index.js.map +1 -0
  81. package/dist/sidebar/styles/index.scss +205 -0
  82. package/dist/src/config/index.d.ts +6 -45
  83. package/dist/src/config/index.d.ts.map +1 -1
  84. package/dist/src/config/index.js +19 -252
  85. package/dist/src/config/index.js.map +1 -1
  86. package/dist/src/config/module.d.ts +5 -0
  87. package/dist/src/config/module.d.ts.map +1 -0
  88. package/dist/src/config/module.js +124 -0
  89. package/dist/src/config/module.js.map +1 -0
  90. package/dist/src/config/normalize.d.ts +9 -0
  91. package/dist/src/config/normalize.d.ts.map +1 -0
  92. package/dist/src/config/normalize.js +116 -0
  93. package/dist/src/config/normalize.js.map +1 -0
  94. package/dist/src/config/palette.d.ts +8 -0
  95. package/dist/src/config/palette.d.ts.map +1 -0
  96. package/dist/src/config/palette.js +104 -0
  97. package/dist/src/config/palette.js.map +1 -0
  98. package/dist/src/config/scales-css.d.ts +8 -0
  99. package/dist/src/config/scales-css.d.ts.map +1 -0
  100. package/dist/src/config/scales-css.js +99 -0
  101. package/dist/src/config/scales-css.js.map +1 -0
  102. package/dist/src/config/scales.d.ts +4 -0
  103. package/dist/src/config/scales.d.ts.map +1 -0
  104. package/dist/src/config/scales.js +55 -0
  105. package/dist/src/config/scales.js.map +1 -0
  106. package/dist/src/config/scss.d.ts +4 -0
  107. package/dist/src/config/scss.d.ts.map +1 -0
  108. package/dist/src/config/scss.js +134 -0
  109. package/dist/src/config/scss.js.map +1 -0
  110. package/dist/src/config/shared.d.ts +9 -0
  111. package/dist/src/config/shared.d.ts.map +1 -0
  112. package/dist/src/config/shared.js +27 -0
  113. package/dist/src/config/shared.js.map +1 -0
  114. package/dist/src/config/theme.d.ts +6 -0
  115. package/dist/src/config/theme.d.ts.map +1 -0
  116. package/dist/src/config/theme.js +133 -0
  117. package/dist/src/config/theme.js.map +1 -0
  118. package/dist/src/config/types.d.ts +127 -0
  119. package/dist/src/config/types.d.ts.map +1 -0
  120. package/dist/src/config/types.js +2 -0
  121. package/dist/src/config/types.js.map +1 -0
  122. package/dist/src/fullscreen/components/index.d.ts +20 -0
  123. package/dist/src/fullscreen/components/index.d.ts.map +1 -0
  124. package/dist/src/fullscreen/components/index.js +19 -0
  125. package/dist/src/fullscreen/components/index.js.map +1 -0
  126. package/dist/src/fullscreen/index.d.ts +24 -3
  127. package/dist/src/fullscreen/index.d.ts.map +1 -1
  128. package/dist/src/fullscreen/index.js +268 -7
  129. package/dist/src/fullscreen/index.js.map +1 -1
  130. package/dist/src/index.d.ts +7 -1
  131. package/dist/src/index.d.ts.map +1 -1
  132. package/dist/src/index.js +9 -1
  133. package/dist/src/index.js.map +1 -1
  134. package/dist/src/layout/components/index.d.ts +43 -0
  135. package/dist/src/layout/components/index.d.ts.map +1 -0
  136. package/dist/src/layout/components/index.js +53 -0
  137. package/dist/src/layout/components/index.js.map +1 -0
  138. package/dist/src/layout/index.d.ts +27 -0
  139. package/dist/src/layout/index.d.ts.map +1 -0
  140. package/dist/src/layout/index.js +80 -0
  141. package/dist/src/layout/index.js.map +1 -0
  142. package/dist/src/react/index.d.ts +14 -0
  143. package/dist/src/react/index.d.ts.map +1 -1
  144. package/dist/src/react/index.js +14 -0
  145. package/dist/src/react/index.js.map +1 -1
  146. package/dist/src/server/index.d.ts +5 -0
  147. package/dist/src/server/index.d.ts.map +1 -0
  148. package/dist/src/server/index.js +5 -0
  149. package/dist/src/server/index.js.map +1 -0
  150. package/dist/src/sidebar/components/index.d.ts +35 -0
  151. package/dist/src/sidebar/components/index.d.ts.map +1 -0
  152. package/dist/src/sidebar/components/index.js +49 -0
  153. package/dist/src/sidebar/components/index.js.map +1 -0
  154. package/dist/src/sidebar/index.d.ts +62 -0
  155. package/dist/src/sidebar/index.d.ts.map +1 -0
  156. package/dist/src/sidebar/index.js +247 -0
  157. package/dist/src/sidebar/index.js.map +1 -0
  158. package/dist/src/theme/apply.d.ts +26 -0
  159. package/dist/src/theme/apply.d.ts.map +1 -0
  160. package/dist/src/theme/apply.js +85 -0
  161. package/dist/src/theme/apply.js.map +1 -0
  162. package/dist/src/theme/boot.d.ts +4 -0
  163. package/dist/src/theme/boot.d.ts.map +1 -0
  164. package/dist/src/theme/boot.js +23 -0
  165. package/dist/src/theme/boot.js.map +1 -0
  166. package/dist/src/theme/components/index.d.ts +13 -5
  167. package/dist/src/theme/components/index.d.ts.map +1 -1
  168. package/dist/src/theme/components/index.js +22 -6
  169. package/dist/src/theme/components/index.js.map +1 -1
  170. package/dist/src/theme/constants.d.ts +12 -0
  171. package/dist/src/theme/constants.d.ts.map +1 -0
  172. package/dist/src/theme/constants.js +12 -0
  173. package/dist/src/theme/constants.js.map +1 -0
  174. package/dist/src/theme/controls.d.ts +15 -0
  175. package/dist/src/theme/controls.d.ts.map +1 -0
  176. package/dist/src/theme/controls.js +128 -0
  177. package/dist/src/theme/controls.js.map +1 -0
  178. package/dist/src/theme/index.d.ts +10 -24
  179. package/dist/src/theme/index.d.ts.map +1 -1
  180. package/dist/src/theme/index.js +15 -117
  181. package/dist/src/theme/index.js.map +1 -1
  182. package/dist/src/theme/modes.d.ts +36 -0
  183. package/dist/src/theme/modes.d.ts.map +1 -0
  184. package/dist/src/theme/modes.js +107 -0
  185. package/dist/src/theme/modes.js.map +1 -0
  186. package/dist/styles/utils.scss +193 -0
  187. package/dist/theme/apply.d.ts +26 -0
  188. package/dist/theme/apply.d.ts.map +1 -0
  189. package/dist/theme/apply.js +85 -0
  190. package/dist/theme/apply.js.map +1 -0
  191. package/dist/theme/boot.d.ts +4 -0
  192. package/dist/theme/boot.d.ts.map +1 -0
  193. package/dist/theme/boot.js +23 -0
  194. package/dist/theme/boot.js.map +1 -0
  195. package/dist/theme/components/index.d.ts +13 -5
  196. package/dist/theme/components/index.d.ts.map +1 -1
  197. package/dist/theme/components/index.js +22 -6
  198. package/dist/theme/components/index.js.map +1 -1
  199. package/dist/theme/constants.d.ts +12 -0
  200. package/dist/theme/constants.d.ts.map +1 -0
  201. package/dist/theme/constants.js +12 -0
  202. package/dist/theme/constants.js.map +1 -0
  203. package/dist/theme/controls.d.ts +15 -0
  204. package/dist/theme/controls.d.ts.map +1 -0
  205. package/dist/theme/controls.js +128 -0
  206. package/dist/theme/controls.js.map +1 -0
  207. package/dist/theme/index.d.ts +10 -24
  208. package/dist/theme/index.d.ts.map +1 -1
  209. package/dist/theme/index.js +15 -117
  210. package/dist/theme/index.js.map +1 -1
  211. package/dist/theme/modes.d.ts +36 -0
  212. package/dist/theme/modes.d.ts.map +1 -0
  213. package/dist/theme/modes.js +107 -0
  214. package/dist/theme/modes.js.map +1 -0
  215. package/package.json +4 -167
  216. package/dist/src/styles/index.d.ts +0 -3
  217. package/dist/src/styles/index.d.ts.map +0 -1
  218. package/dist/src/styles/index.js +0 -15
  219. package/dist/src/styles/index.js.map +0 -1
  220. package/dist/styles/index.d.ts +0 -3
  221. package/dist/styles/index.d.ts.map +0 -1
  222. package/dist/styles/index.js +0 -15
  223. package/dist/styles/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to `@trebired/frontend` will be documented here.
4
4
 
5
5
  This project follows semantic versioning once published.
6
6
 
7
+ ## Unreleased
8
+
9
+ ## 1.0.0
10
+
11
+ - Consolidated the public package API to structured entrypoints only: `@trebired/frontend`, `@trebired/frontend/config`, `@trebired/frontend/react`, and `@trebired/frontend/server`. Public Sass/component subpath exports are no longer part of the app contract.
12
+ - Added config-driven palette and scale CSS generation so ecosystem apps declare theme values in `.trebired/frontend/config.ts` and `@trebired/bundler` compiles package CSS in memory.
13
+ - Added package-owned generic utility CSS coverage for layout, spacing, sizing, text, border, alignment, and scroll helpers through the config-selected package CSS path.
14
+ - Added the package-owned sidebar system with runtime binding, persisted minimize state, mobile open/close state, React markup components, boot script, and internal CSS.
15
+ - Added the package-owned layout system with stable document/layout/main/content/header/bottom-bar/portal markup components, body-state boot script, runtime body-state syncing, and internal CSS so Trebired ecosystem apps share the same HTML structure.
16
+ - Expanded fullscreen into a package-owned panel fullscreen system with registered targets, open/close/toggle controls, overlay/placeholder restoration, persisted target ids, React components, and internal CSS while keeping native browser fullscreen helpers.
17
+ - Added the `@trebired/frontend/server` entrypoint for server-side icon helpers and middleware, and moved React component consumption behind `@trebired/frontend/react`.
18
+ - Updated verification to enforce structured exports, absence of public Sass/component subpaths, config-bundled package CSS, and package-owned layout/sidebar/fullscreen behavior.
19
+
20
+ ## 0.5.0
21
+
22
+ - Generalized the `./theme` runtime to an open, caller-supplied registry of named modes: `configureThemeModes()`, `getThemeModes()`, `themeModeKeys()`, `findThemeMode()`, `isThemeMode()`, mode-aware `setTheme()`/`normalizeTheme()`/`systemThemeKey()`, and `nextTheme()` as a cycler over the registry. `ThemeValue` is now `string`; `data-tbf-theme` accepts any registered key and `color-scheme` follows each mode's declared scheme.
23
+ - Added `[data-tbf-theme-select]` control binding (`bindThemeControls()`, `bindThemeSelect()`, `bindThemeSelects()`, `syncThemeControls()`, `syncThemeSelect()`, `syncThemeSelects()`) for `<select>` pickers and `[data-tbf-theme-value]` option groups.
24
+ - Added the `<ThemeSelect>` multi-choice component with `select` and `buttons` variants, a `labels` prop on `<ThemeToggle>`, and mode registry props on `<ThemeBootScript>`, whose boot script now publishes the registry for the client runtime.
25
+ - Added `theme.modes`, `theme.defaultMode`, `theme.dark`, and `theme.light` to `.trebired/frontend/config.ts`. `generateTrebiredFrontendScss()` emits one `[data-tbf-theme="<mode>"] {}` block per declared mode plus `prefers-color-scheme` fallbacks, alongside the existing shared `:root {}` block.
26
+ - Added `dependencies` to the `loadTrebiredFrontendConfig()` result and keyed the config compile cache on the whole relative import graph, so a design-tokens module imported by the config file drives generated CSS without stale output.
27
+ - Added `collectConfigDependencies()` and `THEME_MODE_ATTRIBUTE` to `@trebired/frontend/config`.
28
+
7
29
  ## 0.4.2
8
30
 
9
31
  - Removed the project-local `.trebired/frontend/generated/styles.scss` writer contract; frontend config now exposes deterministic SCSS for bundlers to consume in memory.
package/README.md CHANGED
@@ -30,21 +30,7 @@ bindFrontendRuntime(document, {
30
30
  });
31
31
  ```
32
32
 
33
- Load only the SCSS systems your product uses:
34
-
35
- ```scss
36
- @use "@trebired/frontend/styles/tokens" as *;
37
- @use "@trebired/frontend/styles/utils" as *;
38
- @use "@trebired/frontend/icons/styles" as *;
39
- @use "@trebired/frontend/actions/styles" as *;
40
- @use "@trebired/frontend/flash/styles" as *;
41
- @use "@trebired/frontend/progress/styles" as *;
42
- @use "@trebired/frontend/layer/styles" as *;
43
- @use "@trebired/frontend/tooltip/styles" as *;
44
- @use "@trebired/frontend/popover/styles" as *;
45
- @use "@trebired/frontend/modal/styles" as *;
46
- @use "@trebired/frontend/inputs/styles" as *;
47
- ```
33
+ Configure the generic systems in `.trebired/frontend/config.ts`. `@trebired/bundler` reads that structured config and includes package-owned CSS through an internal virtual entry; products do not import package Sass paths directly.
48
34
 
49
35
  Markup stays normal HTML:
50
36
 
@@ -64,10 +50,10 @@ Markup stays normal HTML:
64
50
  </div>
65
51
  ```
66
52
 
67
- TSX components are available from system component subpaths when a product wants package-owned default markup:
53
+ TSX components are available from the React entrypoint when a product wants package-owned default markup:
68
54
 
69
55
  ```tsx
70
- import { UploadField } from "@trebired/frontend/inputs/components";
56
+ import { UploadField } from "@trebired/frontend/react";
71
57
 
72
58
  export function AvatarUpload() {
73
59
  return (
@@ -99,7 +85,7 @@ The package-owned selectors use `data-tbf-*` attributes. They never require cust
99
85
 
100
86
  ### Markup Components
101
87
 
102
- Component subpaths render real HTML with `data-tbf-*` attributes and `tbf-*` classes. They are not exported from `@trebired/frontend`, so the root runtime stays browser-behavior only.
88
+ React components render real HTML with `data-tbf-*` attributes and `tbf-*` classes. They are exported from `@trebired/frontend/react`, so the root runtime stays browser-behavior only.
103
89
 
104
90
  Upload markup includes hidden file and directory inputs, mixed file/folder buttons, multiple-file support, drag/drop slots, accepted-format metadata, preview slots, list output, clear-current-preview state, crop config, a crop hidden field, and an empty-toggle hidden field.
105
91
 
@@ -125,9 +111,11 @@ export default defineTrebiredFrontendConfig({
125
111
  icons: true,
126
112
  inputs: true,
127
113
  layer: true,
114
+ layout: true,
128
115
  modal: true,
129
116
  popover: true,
130
117
  progress: true,
118
+ sidebar: true,
131
119
  theme: true,
132
120
  tooltip: true,
133
121
  },
@@ -138,7 +126,41 @@ export default defineTrebiredFrontendConfig({
138
126
  });
139
127
  ```
140
128
 
141
- `@trebired/frontend/config` exports `defineTrebiredFrontendConfig()`, `normalizeTrebiredFrontendConfig()`, `loadTrebiredFrontendConfig()`, `findTrebiredFrontendConfig()`, and `generateTrebiredFrontendScss()`. Missing config files use package defaults. Bundlers should consume the generated SCSS string in memory and emit normal bundled CSS; projects do not need a `.trebired/frontend/generated/styles.scss` file.
129
+ `@trebired/frontend/config` exports `defineTrebiredFrontendConfig()`, `normalizeTrebiredFrontendConfig()`, `loadTrebiredFrontendConfig()`, `findTrebiredFrontendConfig()`, `generateTrebiredFrontendScss()`, `collectConfigDependencies()`, and `THEME_MODE_ATTRIBUTE`. Missing config files use package defaults. Bundlers should consume the generated SCSS string in memory and emit normal bundled CSS; projects do not need a `.trebired/frontend/generated/styles.scss` file.
130
+
131
+ `loadTrebiredFrontendConfig()` resolves the config file's relative import graph, returns it as `dependencies`, and keys its compile cache on the contents of every file in that graph. A project can therefore keep design tokens in a sibling module and edit them without stale output:
132
+
133
+ ```ts
134
+ // .trebired/frontend/tokens.ts
135
+ export const surface = { dark: "#101014", light: "#ffffff", sepia: "#f4ecd8" };
136
+ ```
137
+
138
+ ### Theme Modes
139
+
140
+ `theme.modes` declares an open set of named modes. Each mode owns a token block and, optionally, a `label` and a `scheme` (`"dark"` or `"light"`). Anything other than `label`, `scheme`, and `tokens` inside a mode is rejected, so custom properties always live under `tokens`.
141
+
142
+ ```ts
143
+ import { defineTrebiredFrontendConfig } from "@trebired/frontend/config";
144
+ import { surface } from "./tokens.js";
145
+
146
+ export default defineTrebiredFrontendConfig({
147
+ prefix: "app",
148
+ theme: {
149
+ cssVariables: true,
150
+ defaultMode: "sepia",
151
+ tokens: { radius: { md: "6px" } },
152
+ modes: {
153
+ dark: { tokens: { color: { surface: surface.dark } } },
154
+ light: { tokens: { color: { surface: surface.light } } },
155
+ sepia: { label: "Paper", scheme: "light", tokens: { color: { surface: surface.sepia } } },
156
+ },
157
+ },
158
+ });
159
+ ```
160
+
161
+ `generateTrebiredFrontendScss()` emits shared tokens in `:root {}` and one `[data-tbf-theme="<mode>"] {}` block per declared mode, each carrying its own `color-scheme`. It also emits `--<prefix>-theme-modes`, `--<prefix>-theme-default`, and `prefers-color-scheme` fallbacks scoped to `:root:not([data-tbf-theme])` so unbooted documents still resolve.
162
+
163
+ `theme.dark` and `theme.light` name which registered modes answer `prefers-color-scheme`. When omitted, the first mode of each scheme wins. Declaring no `theme.modes` keeps the previous single `:root {}` output.
142
164
 
143
165
  ### Runtime Options
144
166
 
@@ -152,8 +174,10 @@ export default defineTrebiredFrontendConfig({
152
174
  - `adapters.reload`
153
175
  - `adapters.progress`
154
176
  - `adapters.flash`
177
+ - `adapters.sidebarPersistence`
155
178
  - `adapters.themePersistence`
156
179
  - `adapters.live`
180
+ - `sidebar`
157
181
  - `theme`
158
182
  - `live`
159
183
  - `observe`
@@ -166,34 +190,81 @@ Set `frontend_quiet: true`, `quiet: true`, `globalThis.frontend_quiet = true`, o
166
190
 
167
191
  ### Binding Order
168
192
 
169
- The canonical runtime binds theme, layer roots, icons, progress, flash, inputs, uploads, tooltips, popovers, modals, actions, fullscreen controls, and live refresh in that order.
193
+ The canonical runtime binds theme, layout, layer roots, icons, progress, flash, inputs, uploads, tooltips, popovers, modals, sidebars, actions, fullscreen controls, and live refresh in that order.
170
194
 
171
- ### CSS
195
+ ### Layout
172
196
 
173
- There is no aggregate CSS file. Each style-owning system exposes SCSS through package exports so `@trebired/bundler` can resolve package `sass` and `style` conditions from `node_modules`.
197
+ Ecosystem apps should use the package layout components for the document shell shape instead of owning separate layout HTML. The app still supplies product-specific header, sidebar link content, page body, and bottom-bar children.
198
+
199
+ ```tsx
200
+ import {
201
+ Layout,
202
+ LayoutBootScript,
203
+ LayoutContent,
204
+ LayoutDocument,
205
+ Sidebar,
206
+ SidebarLink,
207
+ SidebarList,
208
+ SidebarShell,
209
+ } from "@trebired/frontend/react";
210
+
211
+ export function Document({ body, header }: { body: React.ReactNode; header: React.ReactNode }) {
212
+ return (
213
+ <LayoutDocument title="App" scripts={<LayoutBootScript hasLeftSidebar />}>
214
+ <Layout
215
+ header={header}
216
+ leftSidebar={
217
+ <SidebarShell id="main_sidebar" side="left">
218
+ <Sidebar aria-label="Navigation">
219
+ <SidebarList>
220
+ <SidebarLink href="/dashboard">Dashboard</SidebarLink>
221
+ </SidebarList>
222
+ </Sidebar>
223
+ </SidebarShell>
224
+ }
225
+ >
226
+ <LayoutContent>{body}</LayoutContent>
227
+ </Layout>
228
+ </LayoutDocument>
229
+ );
230
+ }
231
+ ```
174
232
 
175
- Default SCSS is intentionally plain: `tbf-*` classes, CSS variables, black/white fallback colors, and square radius fallbacks. Products own visual polish by overriding variables.
233
+ ### Theme
176
234
 
177
- Base exports:
235
+ Theme runtime works against a caller-supplied mode registry rather than a fixed light/dark pair. The registry defaults to `["dark", "light"]`, so existing callers keep their behavior.
178
236
 
179
- - `@trebired/frontend/styles/tokens`
180
- - `@trebired/frontend/styles/utils`
237
+ ```ts
238
+ import { bindThemeRuntime } from "@trebired/frontend";
239
+
240
+ await bindThemeRuntime(document, {
241
+ modes: ["dark", "light", { key: "sepia", label: "Paper", scheme: "light" }],
242
+ dark: "dark",
243
+ light: "light",
244
+ defaultTheme: "sepia",
245
+ persistence,
246
+ });
247
+ ```
248
+
249
+ Passing `modes`, `dark`, or `light` to `bindThemeRuntime()` registers them process-wide, so `setTheme()`, `nextTheme()`, and control syncing can be called later without repeating the list. `configureThemeModes(registry)` registers them directly; `configureThemeModes(null)` restores the default pair. `<ThemeBootScript>` publishes the registry it renders with, so a server-rendered page hands its modes to the client before first paint.
250
+
251
+ - `setTheme(key, options)` validates `key` against the registry and falls back to system preference when it is not registered.
252
+ - `nextTheme(options)` cycles through the registry in declaration order.
253
+ - `data-tbf-theme` accepts any registered key; `color-scheme` is set from the mode's `scheme`, not from its name.
254
+ - `systemThemeKey(options)` maps `prefers-color-scheme` onto the registry's `dark` / `light` members.
255
+ - `bindThemeControls(root, options)` binds both `[data-tbf-theme-button]` cyclers and `[data-tbf-theme-select]` pickers; `bindThemeToggles()` and `bindThemeSelects()` bind one kind each.
256
+
257
+ A `[data-tbf-theme-select]` element is either a `<select>` whose option values are mode keys, or a container of `[data-tbf-theme-value]` options. Both stay in sync with the active mode. `<ThemeToggle>` remains the two-mode control and now accepts a `labels` record for registries larger than two; `<ThemeSelect>` renders the multi-choice picker in either `select` or `buttons` form.
258
+
259
+ ### CSS
181
260
 
182
- System exports:
261
+ There is no aggregate CSS file and no public Sass subpath API. Package-owned CSS is selected by `.trebired/frontend/config.ts`, then emitted by `@trebired/frontend/config` as SCSS for `@trebired/bundler` to compile in memory.
183
262
 
184
- - `@trebired/frontend/actions/styles`
185
- - `@trebired/frontend/icons/styles`
186
- - `@trebired/frontend/flash/styles`
187
- - `@trebired/frontend/progress/styles`
188
- - `@trebired/frontend/layer/styles`
189
- - `@trebired/frontend/tooltip/styles`
190
- - `@trebired/frontend/popover/styles`
191
- - `@trebired/frontend/modal/styles`
192
- - `@trebired/frontend/inputs/styles`
263
+ Default CSS is intentionally plain: `tbf-*` classes, generic utility classes, CSS variables, black/white fallback colors, and square radius fallbacks. Products own visual polish by declaring config tokens or writing component-specific CSS.
193
264
 
194
265
  ### Upload Crop
195
266
 
196
- Upload crop uses `cropperjs` only through the upload crop path. The root runtime import and the normal `@trebired/frontend/inputs` import do not load cropper or TSX component modules until a crop session opens.
267
+ Upload crop uses `cropperjs` only through the upload crop path. The root runtime import does not load cropper or TSX component modules until a crop session opens.
197
268
 
198
269
  ### Icons
199
270
 
@@ -207,7 +278,7 @@ Canonical icon specs use `pack:name`:
207
278
  Browser runtime:
208
279
 
209
280
  ```ts
210
- import { bindIcons, renderIconElement } from "@trebired/frontend/icons";
281
+ import { bindIcons, renderIconElement } from "@trebired/frontend";
211
282
 
212
283
  bindIcons(document);
213
284
  await renderIconElement(document.querySelector("[data-tbf-icon]")!, "remixicon:add-line");
@@ -216,7 +287,7 @@ await renderIconElement(document.querySelector("[data-tbf-icon]")!, "remixicon:a
216
287
  React:
217
288
 
218
289
  ```tsx
219
- import { Icon } from "@trebired/frontend/icons/react";
290
+ import { Icon } from "@trebired/frontend/react";
220
291
 
221
292
  export function SaveIcon() {
222
293
  return <Icon spec="remixicon:save-3-line" label="Save" />;
@@ -226,8 +297,7 @@ export function SaveIcon() {
226
297
  Server:
227
298
 
228
299
  ```ts
229
- import { renderIconHtml } from "@trebired/frontend/icons/server";
230
- import { createIconMiddleware } from "@trebired/frontend/icons/middleware";
300
+ import { createIconMiddleware, renderIconHtml } from "@trebired/frontend/server";
231
301
 
232
302
  const html = renderIconHtml("simple-icons:github", { label: "GitHub" });
233
303
  const middleware = createIconMiddleware();
@@ -240,47 +310,9 @@ The icon system supports explicit colors, simple-icons brand colors, source-colo
240
310
  Entrypoints:
241
311
 
242
312
  - `@trebired/frontend`
243
- - `@trebired/frontend/dom`
244
- - `@trebired/frontend/http`
245
313
  - `@trebired/frontend/config`
246
- - `@trebired/frontend/fullscreen`
247
- - `@trebired/frontend/icons`
248
- - `@trebired/frontend/icons/react`
249
- - `@trebired/frontend/icons/server`
250
- - `@trebired/frontend/icons/middleware`
251
- - `@trebired/frontend/actions`
252
- - `@trebired/frontend/actions/components`
253
- - `@trebired/frontend/flash`
254
- - `@trebired/frontend/flash/components`
255
- - `@trebired/frontend/progress`
256
- - `@trebired/frontend/progress/components`
257
- - `@trebired/frontend/layer`
258
- - `@trebired/frontend/layer/components`
259
- - `@trebired/frontend/tooltip`
260
- - `@trebired/frontend/tooltip/components`
261
- - `@trebired/frontend/popover`
262
- - `@trebired/frontend/popover/components`
263
- - `@trebired/frontend/modal`
264
- - `@trebired/frontend/modal/components`
265
- - `@trebired/frontend/inputs`
266
- - `@trebired/frontend/inputs/components`
267
- - `@trebired/frontend/theme`
268
- - `@trebired/frontend/theme/components`
269
- - `@trebired/frontend/live`
270
- - `@trebired/frontend/live/components`
271
314
  - `@trebired/frontend/react`
272
- - `@trebired/frontend/styles`
273
- - `@trebired/frontend/styles/tokens`
274
- - `@trebired/frontend/styles/utils`
275
- - `@trebired/frontend/icons/styles`
276
- - `@trebired/frontend/actions/styles`
277
- - `@trebired/frontend/flash/styles`
278
- - `@trebired/frontend/progress/styles`
279
- - `@trebired/frontend/layer/styles`
280
- - `@trebired/frontend/tooltip/styles`
281
- - `@trebired/frontend/popover/styles`
282
- - `@trebired/frontend/modal/styles`
283
- - `@trebired/frontend/inputs/styles`
315
+ - `@trebired/frontend/server`
284
316
 
285
317
  ## What It Does Not Do
286
318
 
@@ -1,49 +1,10 @@
1
- type TrebiredFrontendIconPack = "remixicon" | "simple-icons";
2
- type TrebiredFrontendSystemKey = "actions" | "flash" | "fullscreen" | "icons" | "inputs" | "layer" | "modal" | "popover" | "progress" | "theme" | "tooltip";
3
- type TrebiredFrontendThemeTokens = Record<string, unknown>;
4
- type TrebiredFrontendConfig = {
5
- prefix?: string;
6
- icons?: {
7
- endpoint?: string;
8
- packs?: readonly TrebiredFrontendIconPack[];
9
- };
10
- systems?: Partial<Record<TrebiredFrontendSystemKey, boolean>>;
11
- theme?: {
12
- cssVariables?: boolean;
13
- tokens?: TrebiredFrontendThemeTokens;
14
- };
15
- };
16
- type NormalizedTrebiredFrontendConfig = {
17
- prefix: string;
18
- icons: {
19
- endpoint: string;
20
- packs: TrebiredFrontendIconPack[];
21
- };
22
- systems: Record<TrebiredFrontendSystemKey, boolean>;
23
- theme: {
24
- cssVariables: boolean;
25
- tokens: TrebiredFrontendThemeTokens;
26
- };
27
- };
28
- type LoadedTrebiredFrontendConfig = {
29
- config: NormalizedTrebiredFrontendConfig;
30
- configPath: string | null;
31
- generatedScss: string;
32
- };
33
- type LoadTrebiredFrontendConfigOptions = {
34
- configPath?: string;
35
- defaultIfMissing?: boolean;
36
- searchFrom?: string;
37
- };
38
- declare const TREBIRED_FRONTEND_CONFIG_PATH = ".trebired/frontend/config.ts";
39
- declare const SUPPORTED_ICON_PACKS: TrebiredFrontendIconPack[];
40
- declare const SYSTEM_ORDER: TrebiredFrontendSystemKey[];
41
- declare const DEFAULT_TREBIRED_FRONTEND_CONFIG: NormalizedTrebiredFrontendConfig;
1
+ import type { LoadTrebiredFrontendConfigOptions, LoadedTrebiredFrontendConfig, TrebiredFrontendConfig } from "./types.js";
42
2
  declare function defineTrebiredFrontendConfig<T extends TrebiredFrontendConfig>(config: T): T;
43
- declare function normalizeTrebiredFrontendConfig(config?: unknown): NormalizedTrebiredFrontendConfig;
44
- declare function generateTrebiredFrontendScss(configInput: TrebiredFrontendConfig | NormalizedTrebiredFrontendConfig): string;
45
3
  declare function findTrebiredFrontendConfig(startDir?: string, boundaryDir?: string): Promise<string | null>;
46
4
  declare function loadTrebiredFrontendConfig(projectRoot?: string, options?: LoadTrebiredFrontendConfigOptions): Promise<LoadedTrebiredFrontendConfig>;
47
- export { DEFAULT_TREBIRED_FRONTEND_CONFIG, SUPPORTED_ICON_PACKS, SYSTEM_ORDER, TREBIRED_FRONTEND_CONFIG_PATH, defineTrebiredFrontendConfig, findTrebiredFrontendConfig, generateTrebiredFrontendScss, loadTrebiredFrontendConfig, normalizeTrebiredFrontendConfig, };
48
- export type { LoadedTrebiredFrontendConfig, LoadTrebiredFrontendConfigOptions, NormalizedTrebiredFrontendConfig, TrebiredFrontendConfig, TrebiredFrontendIconPack, TrebiredFrontendSystemKey, TrebiredFrontendThemeTokens, };
5
+ export { DEFAULT_TREBIRED_FRONTEND_CONFIG, SUPPORTED_ICON_PACKS, SYSTEM_ORDER, THEME_MODE_ATTRIBUTE, TREBIRED_FRONTEND_CONFIG_PATH, normalizeTrebiredFrontendConfig, } from "./normalize.js";
6
+ export { generateTrebiredFrontendScss } from "./scss.js";
7
+ export { collectConfigDependencies } from "./module.js";
8
+ export { defineTrebiredFrontendConfig, findTrebiredFrontendConfig, loadTrebiredFrontendConfig };
9
+ export type { LoadTrebiredFrontendConfigOptions, LoadedTrebiredFrontendConfig, NormalizedTrebiredFrontendConfig, NormalizedTrebiredFrontendPaletteConfig, NormalizedTrebiredFrontendPaletteMode, NormalizedTrebiredFrontendPaletteSemantic, NormalizedTrebiredFrontendScalesConfig, NormalizedTrebiredFrontendThemeConfig, NormalizedTrebiredFrontendThemeMode, NormalizedTrebiredFrontendZIndexScaleConfig, TrebiredFrontendConfig, TrebiredFrontendIconPack, TrebiredFrontendPaletteConfig, TrebiredFrontendPaletteFamilies, TrebiredFrontendPaletteMode, TrebiredFrontendPaletteScale, TrebiredFrontendPaletteSemanticRef, TrebiredFrontendScaleSteps, TrebiredFrontendScalesConfig, TrebiredFrontendSystemKey, TrebiredFrontendThemeConfig, TrebiredFrontendThemeMode, TrebiredFrontendThemeModeScheme, TrebiredFrontendThemeTokens, TrebiredFrontendZIndexScaleConfig, } from "./types.js";
49
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAKA,KAAK,wBAAwB,GAAG,WAAW,GAAG,cAAc,CAAC;AAE7D,KAAK,yBAAyB,GAC1B,SAAS,GACT,OAAO,GACP,YAAY,GACZ,OAAO,GACP,QAAQ,GACR,OAAO,GACP,OAAO,GACP,SAAS,GACT,UAAU,GACV,OAAO,GACP,SAAS,CAAC;AAEd,KAAK,2BAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D,KAAK,sBAAsB,GAAG;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;KAC7C,CAAC;IACF,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,MAAM,CAAC,EAAE,2BAA2B,CAAC;KACtC,CAAC;CACH,CAAC;AAEF,KAAK,gCAAgC,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,wBAAwB,EAAE,CAAC;KACnC,CAAC;IACF,OAAO,EAAE,MAAM,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC;IACpD,KAAK,EAAE;QACL,YAAY,EAAE,OAAO,CAAC;QACtB,MAAM,EAAE,2BAA2B,CAAC;KACrC,CAAC;CACH,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,MAAM,EAAE,gCAAgC,CAAC;IACzC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,iCAAiC,GAAG;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,6BAA6B,iCAAiC,CAAC;AAErE,QAAA,MAAM,oBAAoB,EAAE,wBAAwB,EAAkC,CAAC;AAEvF,QAAA,MAAM,YAAY,EAAE,yBAAyB,EAY5C,CAAC;AAcF,QAAA,MAAM,gCAAgC,EAAE,gCAWtC,CAAC;AAEH,iBAAS,4BAA4B,CAAC,CAAC,SAAS,sBAAsB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEpF;AAwFD,iBAAS,+BAA+B,CAAC,MAAM,GAAE,OAAY,GAAG,gCAAgC,CAgB/F;AA2CD,iBAAS,4BAA4B,CAAC,WAAW,EAAE,sBAAsB,GAAG,gCAAgC,GAAG,MAAM,CAsBpH;AAWD,iBAAe,0BAA0B,CACvC,QAAQ,GAAE,MAAsB,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAkDD,iBAAe,0BAA0B,CACvC,WAAW,GAAE,MAAsB,EACnC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,4BAA4B,CAAC,CA4BvC;AAED,OAAO,EACL,gCAAgC,EAChC,oBAAoB,EACpB,YAAY,EACZ,6BAA6B,EAC7B,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,+BAA+B,GAChC,CAAC;AACF,YAAY,EACV,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,GAC5B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iCAAiC,EACjC,4BAA4B,EAC5B,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,iBAAS,4BAA4B,CAAC,CAAC,SAAS,sBAAsB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEpF;AAED,iBAAe,0BAA0B,CACvC,QAAQ,GAAE,MAAsB,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAYD,iBAAe,0BAA0B,CACvC,WAAW,GAAE,MAAsB,EACnC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,4BAA4B,CAAC,CAyBvC;AAED,OAAO,EACL,gCAAgC,EAChC,oBAAoB,EACpB,YAAY,EACZ,oBAAoB,EACpB,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,CAAC;AAChG,YAAY,EACV,iCAAiC,EACjC,4BAA4B,EAC5B,gCAAgC,EAChC,uCAAuC,EACvC,qCAAqC,EACrC,yCAAyC,EACzC,sCAAsC,EACtC,qCAAqC,EACrC,mCAAmC,EACnC,2CAA2C,EAC3C,sBAAsB,EACtB,wBAAwB,EACxB,6BAA6B,EAC7B,+BAA+B,EAC/B,2BAA2B,EAC3B,4BAA4B,EAC5B,kCAAkC,EAClC,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,+BAA+B,EAC/B,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,YAAY,CAAC"}