@ekanos/ui 0.1.1 → 0.1.3
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/README.md +184 -26
- package/dist/ai-prompt-input.js +122 -816
- package/dist/base.css +116 -0
- package/dist/card.d.ts +1 -1
- package/dist/dialog.js +16 -716
- package/dist/dropdown-menu.js +26 -719
- package/dist/form.d.ts +2 -2
- package/dist/icon.js +27 -0
- package/dist/select.js +22 -722
- package/dist/styles.css +2159 -0
- package/dist/switch.d.ts +8 -0
- package/dist/switch.js +44 -0
- package/dist/textarea.d.ts +5 -0
- package/dist/textarea.js +25 -0
- package/dist/theme.css +221 -0
- package/dist/tokens.css +414 -0
- package/package.json +28 -15
package/README.md
CHANGED
|
@@ -21,6 +21,8 @@ One subpath per component, mirroring the `@kit/ui` names:
|
|
|
21
21
|
| `@ekanos/ui/select` | `Select`, `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, … |
|
|
22
22
|
| `@ekanos/ui/form` | `Form`, `FormField`, `FormItem`, `FormLabel`, `FormControl`, `FormDescription`, `FormMessage`, `useFormField` |
|
|
23
23
|
| `@ekanos/ui/input` | `Input` |
|
|
24
|
+
| `@ekanos/ui/textarea` | `Textarea` |
|
|
25
|
+
| `@ekanos/ui/switch` | `Switch` |
|
|
24
26
|
| `@ekanos/ui/dropdown-menu` | `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem`, … |
|
|
25
27
|
| `@ekanos/ui/label` | `Label` |
|
|
26
28
|
| `@ekanos/ui/skeleton` | `Skeleton` |
|
|
@@ -31,37 +33,170 @@ One subpath per component, mirroring the `@kit/ui` names:
|
|
|
31
33
|
| `@ekanos/ui/spinner` | `Spinner` |
|
|
32
34
|
| `@ekanos/ui/ai-prompt-input` | `PromptInput` compound components for AI ask surfaces |
|
|
33
35
|
|
|
34
|
-
Most source files are a thin
|
|
35
|
-
`@kit/ui` stays the single source of truth. At build time
|
|
36
|
-
inlined into `dist/` so the published artifact has no workspace dependencies
|
|
37
|
-
|
|
36
|
+
Most source files are a thin re-export of the internal `@kit/ui` library — for
|
|
37
|
+
those, `@kit/ui` stays the single source of truth. At build time that code is
|
|
38
|
+
inlined into `dist/` so the published artifact has no workspace dependencies;
|
|
39
|
+
`pnpm --filter @ekanos/ui pack:test` fails the build if any `@kit/` specifier
|
|
40
|
+
leaks into the tarball.
|
|
38
41
|
|
|
39
42
|
Three subpaths — `if`, `trans`, and `spinner` — are instead implemented
|
|
40
|
-
natively
|
|
41
|
-
|
|
42
|
-
commercial Turbo starter this monorepo was built on; publishing it under this
|
|
43
|
+
natively here. Their internal counterparts are Makerkit-authored code from the
|
|
44
|
+
commercial Turbo starter this monorepo was built on; publishing that under this
|
|
43
45
|
package's MIT license would purport to grant reuse rights we do not hold. The
|
|
44
|
-
implementations here are original, and `pack:test` fails the build if
|
|
45
|
-
|
|
46
|
-
monorepo, first-party code keeps using `@kit/ui` as before.
|
|
46
|
+
implementations shipped here are original, and `pack:test` fails the build if
|
|
47
|
+
any Makerkit-authored source is ever inlined into `dist/`.
|
|
47
48
|
|
|
48
|
-
## Styling
|
|
49
|
+
## Styling
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
tokens
|
|
52
|
-
|
|
53
|
-
integration dev harness. Nothing here reads or requires the host's
|
|
54
|
-
`theme-tokens.ts` runtime; the contract is purely "the host page loads
|
|
55
|
-
Fusion's stylesheet".
|
|
51
|
+
Every component emits Tailwind class strings bound to Fusion's semantic design
|
|
52
|
+
tokens (`bg-primary`, `text-muted-foreground`, `border-border`, `shadow-card`,
|
|
53
|
+
…), so something has to define those. This package ships that CSS.
|
|
56
54
|
|
|
57
|
-
|
|
55
|
+
Pick **one** of the two paths. Loading both means two copies of every utility.
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
### You do NOT use Tailwind — import the compiled stylesheet
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import '@ekanos/ui/styles.css';
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Self-contained: Tailwind's Preflight, the design tokens, light and dark, and
|
|
64
|
+
every utility class the components in this package emit — all pre-compiled.
|
|
65
|
+
Nothing else to install, no build step, no config. Works in Next.js, Vite, CRA,
|
|
66
|
+
a plain `<link rel="stylesheet">`, anything.
|
|
67
|
+
|
|
68
|
+
### You DO use Tailwind v4 — import the preset
|
|
69
|
+
|
|
70
|
+
```css
|
|
71
|
+
@import 'tailwindcss';
|
|
72
|
+
@import '@ekanos/ui/theme.css';
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
That registers the token map (`--color-primary` → `--primary`, the `--radius-*`
|
|
76
|
+
scale, `shadow-card`), the token values for both themes, the base rules, the
|
|
77
|
+
`dark:` variant, and an `@source` pointing at this package's bundles so your
|
|
78
|
+
Tailwind build generates the components' utilities itself. You then get the
|
|
79
|
+
Fusion tokens in **your own** class strings too.
|
|
80
|
+
|
|
81
|
+
Also published, if you want the pieces separately: `@ekanos/ui/tokens.css`
|
|
82
|
+
(just the custom properties, no Tailwind at-rules) and `@ekanos/ui/base.css`
|
|
83
|
+
(the base rules).
|
|
84
|
+
|
|
85
|
+
### What `styles.css` does and does not contain
|
|
86
|
+
|
|
87
|
+
It contains the utilities **this package's components** emit — derived by
|
|
88
|
+
compiling every class string found in the built bundles. It is not a copy of
|
|
89
|
+
Tailwind.
|
|
90
|
+
|
|
91
|
+
So `<Button>` and `<Card>` render correctly, but a Tailwind class *you* write in
|
|
92
|
+
*your* component (`p-8`, `grid-cols-3`, `h-5 w-5`) has no rule in it and will do
|
|
93
|
+
nothing. That is inherent: a pre-compiled stylesheet cannot know class names
|
|
94
|
+
that don't exist yet. Two options, both fine:
|
|
95
|
+
|
|
96
|
+
- style your own markup with plain CSS or inline styles, or
|
|
97
|
+
- take the Tailwind path above, which is how Fusion itself works.
|
|
98
|
+
|
|
99
|
+
`styles.css` includes Tailwind's Preflight, which is a global reset — it will
|
|
100
|
+
normalise margins, headings and form controls across your whole page. If that
|
|
101
|
+
is unwelcome, use the Tailwind path and control layering yourself.
|
|
102
|
+
|
|
103
|
+
### Page background and dark mode
|
|
104
|
+
|
|
105
|
+
The stylesheet will not repaint your page uninvited. To adopt Fusion's page
|
|
106
|
+
surface — which is what makes dark mode look right rather than dark cards
|
|
107
|
+
floating on a white page — add the opt-in class:
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<body class="ekanos-root">
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Dark mode resolves in three states, in this order:
|
|
114
|
+
|
|
115
|
+
| State | Result |
|
|
116
|
+
| ----------------------------------------- | ---------------------------- |
|
|
117
|
+
| nothing set | light |
|
|
118
|
+
| `@media (prefers-color-scheme: dark)` | dark |
|
|
119
|
+
| `.dark` or `[data-theme='dark']` ancestor | dark, beating the media query |
|
|
120
|
+
| `.light` or `[data-theme='light']` on `:root` | light, beating the media query |
|
|
121
|
+
|
|
122
|
+
So a partner app with no theme toggle at all still follows the OS, and one with
|
|
123
|
+
a toggle (next-themes, or your own) works by setting the class. Fusion itself is
|
|
124
|
+
class-only; the media query is added here for apps that have no switcher.
|
|
125
|
+
|
|
126
|
+
### Tokens: exactly the ones the components use
|
|
127
|
+
|
|
128
|
+
`tokens.css` is not a copy of Fusion's `shadcn-ui.css`. It carries the 25
|
|
129
|
+
semantic colour tokens the published components actually reference, plus their
|
|
130
|
+
paired foregrounds, `--radius`, and the one elevation level any of them uses
|
|
131
|
+
(`--el-card`, behind `shadow-card`). Fusion's chart, sidebar and assistant
|
|
132
|
+
tokens, and nine of its ten elevation levels, are deliberately absent.
|
|
133
|
+
|
|
134
|
+
The build enforces this in both directions: it re-compiles the same class
|
|
135
|
+
strings against Fusion's **full** token map and fails if a component has started
|
|
136
|
+
using a token this package doesn't ship (which would otherwise emit no CSS at
|
|
137
|
+
all, silently). The CSS build enforces it.
|
|
138
|
+
|
|
139
|
+
### Fonts
|
|
140
|
+
|
|
141
|
+
Fusion pairs **Figtree** (body) with **Bricolage Grotesque** (headings) and
|
|
142
|
+
loads them via `next/font`. This package only names them in `--font-sans` /
|
|
143
|
+
`--font-heading`, followed by a system fallback stack — no webfont is bundled or
|
|
144
|
+
fetched. For exact typographic parity, load them yourself:
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<link
|
|
148
|
+
rel="stylesheet"
|
|
149
|
+
href="https://fonts.googleapis.com/css2?family=Figtree:wght@300..700&family=Bricolage+Grotesque:wght@200..800&display=swap"
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Without them, everything still renders — in your platform's UI font.
|
|
154
|
+
|
|
155
|
+
### Icons: you must supply Font Awesome
|
|
156
|
+
|
|
157
|
+
`Icon` renders Font Awesome markup (`<i class="fa-solid fa-house">`) and this
|
|
158
|
+
package ships **no icon font**, because Fusion uses **Font Awesome Pro** (7.2.0,
|
|
159
|
+
© Fonticons, Inc.) under a commercial licence. Redistributing it inside an MIT
|
|
160
|
+
package would hand reuse rights we do not hold to everyone who installs this;
|
|
161
|
+
`pack:test` fails the build if any font data ever reaches `dist/`.
|
|
162
|
+
|
|
163
|
+
**If you hold a Font Awesome Pro licence**, load your own Pro CSS (or kit) and
|
|
164
|
+
every icon renders exactly as it does in Fusion.
|
|
165
|
+
|
|
166
|
+
**If you do not**, use Font Awesome Free — but read this, because the fit is
|
|
167
|
+
imperfect:
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
npm install @fortawesome/fontawesome-free
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import '@fortawesome/fontawesome-free/css/all.min.css';
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Free ships `fa-solid`, `fa-regular` and `fa-brands`. It has **no `fa-light` or
|
|
178
|
+
`fa-duotone` family**, and it is missing many Pro glyphs — and `fa-light` is
|
|
179
|
+
exactly what `@kit/ui`'s resolver falls back to for an icon name it doesn't
|
|
180
|
+
recognise. Force everything into a family Free actually has:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { IconStyleOverrideProvider } from '@ekanos/ui/icon';
|
|
184
|
+
|
|
185
|
+
<IconStyleOverrideProvider value="solid">{children}</IconStyleOverrideProvider>;
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Any glyph Free still doesn't have falls back to a question mark rather than
|
|
189
|
+
vanishing (`--ekanos-icon-fa-fallback`, default `'\f059'`).
|
|
190
|
+
|
|
191
|
+
**If you load no Font Awesome at all**, icons do not disappear silently: this
|
|
192
|
+
package's CSS draws a placeholder box (`□`) in their place, so "I forgot the
|
|
193
|
+
icon font" is visibly different from "my code is broken". Change or disable it
|
|
194
|
+
with `--ekanos-icon-fallback`.
|
|
195
|
+
|
|
196
|
+
Note that FA glyphs are sized by `font-size`, not box dimensions, and `Icon`
|
|
197
|
+
derives that from the first `h-*` / `w-*` / `size-*` token in `className` in JS
|
|
198
|
+
— so `<Icon className="h-5 w-5" />` is the right *visual* size even on the
|
|
199
|
+
no-Tailwind path where those utilities have no CSS rule.
|
|
65
200
|
|
|
66
201
|
## Runtime notes
|
|
67
202
|
|
|
@@ -110,14 +245,37 @@ runtime is a declared dependency of this package.
|
|
|
110
245
|
## Building / verifying
|
|
111
246
|
|
|
112
247
|
```bash
|
|
113
|
-
pnpm --filter @ekanos/ui build # tsup → dist
|
|
114
|
-
pnpm --filter @ekanos/ui pack:test # clean-room publish gate
|
|
248
|
+
pnpm --filter @ekanos/ui build # tsup → dist/, then the CSS build → the stylesheets
|
|
249
|
+
pnpm --filter @ekanos/ui pack:test # clean-room publish gate
|
|
115
250
|
```
|
|
116
251
|
|
|
252
|
+
The build runs in two stages, in this order for a reason: `tsup` bundles the
|
|
253
|
+
components, then the CSS build scans the *built* `dist/*.js` for class
|
|
254
|
+
strings and compiles exactly those through Tailwind. Deriving the utility set
|
|
255
|
+
from the build output rather than a hand-kept list is what makes it impossible
|
|
256
|
+
to add a component whose classes have no CSS.
|
|
257
|
+
|
|
258
|
+
That script carries three fatal gates:
|
|
259
|
+
|
|
260
|
+
- **dangling** — every `var(--x)` the token map reaches for must be defined.
|
|
261
|
+
- **coverage** — the same class strings are re-compiled against Fusion's full
|
|
262
|
+
token map, and the build fails if a component has begun using a token this
|
|
263
|
+
package doesn't ship. Without this, such a utility would just silently emit
|
|
264
|
+
nothing.
|
|
265
|
+
- **lockstep** — `tokens.css` spells its dark values out twice (a media query
|
|
266
|
+
and an explicit selector, because CSS can't share a block between them); both
|
|
267
|
+
must stay in agreement.
|
|
268
|
+
|
|
117
269
|
`pack:test` packs the tarball, asserts dist-only contents, fails on any
|
|
118
270
|
`@kit/` leak, asserts `'use client'` preservation, then installs the tarball
|
|
119
271
|
into a temp project outside the workspace and typechecks
|
|
120
272
|
(`skipLibCheck: false`) + esbuild-bundles a consumer importing every subpath.
|
|
121
273
|
|
|
274
|
+
It also gates the stylesheets: all four must ship, clear a size floor, still
|
|
275
|
+
contain known utilities and both theme states, resolve through esbuild as
|
|
276
|
+
`@ekanos/ui/styles.css`, and carry **no** icon-font data — `@font-face`, a
|
|
277
|
+
webfont reference or a glyph table in `dist/` fails the build, for the same
|
|
278
|
+
licensing reason the Makerkit lineage check exists.
|
|
279
|
+
|
|
122
280
|
`prepack` runs the build, so a publish can never ship a stale or missing
|
|
123
281
|
`dist/`.
|