@ekkolyth/ui 0.1.16 → 0.1.18
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 +21 -0
- package/README.md +153 -97
- package/dist/base.css +263 -0
- package/dist/blocks.d.ts +4 -0
- package/dist/blocks.js +4 -0
- package/dist/container-BBg21poC.js +10 -0
- package/dist/convex.d.ts +2 -0
- package/dist/convex.js +2 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +2 -0
- package/dist/icon-picker-ByfHyJ7i.js +4078 -0
- package/dist/index-Bwp0YMmG.d.ts +5 -0
- package/dist/index-BxcqwZNT.d.ts +30 -0
- package/dist/index-DHF8OR1R.d.ts +60 -0
- package/dist/index-DsLGf2HX.d.ts +9 -0
- package/dist/index-qji4ohJZ.d.ts +24 -0
- package/dist/index.d.ts +793 -533
- package/dist/index.js +3236 -5578
- package/dist/layout.d.ts +2 -0
- package/dist/layout.js +2 -0
- package/dist/loading-screen-DB3youyT.js +63 -0
- package/dist/shiki-code-Bg__Vnt1.js +29 -0
- package/dist/text.d.ts +17 -0
- package/dist/text.js +177 -0
- package/dist/themes/catpuccin/frappe.css +33 -33
- package/dist/themes/catpuccin/latte.css +33 -33
- package/dist/themes/catpuccin/macchiato.css +33 -33
- package/dist/themes/catpuccin/mocha.css +33 -33
- package/dist/themes/ekko-os.css +92 -37
- package/dist/themes/ekkolyth.css +2 -2
- package/dist/themes/index.css +7 -66
- package/dist/themes/provider.d.ts +62 -0
- package/dist/themes/provider.js +271 -0
- package/dist/themes/tokyo-night.css +33 -33
- package/dist/themes.css +7 -0
- package/dist/toggle-B2PFPImC.js +182 -0
- package/dist/use-mobile-BVGje-2e.d.ts +4 -0
- package/dist/use-mobile-CqHXB_Nc.js +18 -0
- package/dist/utils-C_uf36nf.js +8 -0
- package/dist/widget-C2vjxQms.js +94 -0
- package/dist/widget.d.ts +6 -0
- package/dist/widget.js +19 -0
- package/package.json +125 -170
- package/dist/index-C3ceanPz.d.ts +0 -18
- package/dist/index-C7t_lwpi.d.ts +0 -13
- package/dist/next.d.ts +0 -13
- package/dist/next.js +0 -271
- package/dist/providers/next.d.ts +0 -25
- package/dist/providers/next.js +0 -216
- package/dist/providers/tanstack.d.ts +0 -24
- package/dist/providers/tanstack.js +0 -120
- package/dist/tanstack.d.ts +0 -12
- package/dist/tanstack.js +0 -203
- package/dist/themes/ekko-playlist.css +0 -71
- package/dist/themes/theme-select.d.ts +0 -12
- package/dist/themes/theme-select.js +0 -357
- package/dist/themes/theme-toggle.d.ts +0 -15
- package/dist/themes/theme-toggle.js +0 -179
- package/dist/types-fUfvw1Mz.d.ts +0 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ekkolyth
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,111 +1,164 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ekkolyth/ui
|
|
2
2
|
|
|
3
|
-
Shared UI component library
|
|
3
|
+
Shared UI component library, published as `@ekkolyth/ui`.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
7
|
+
```sh
|
|
8
|
+
bun add @ekkolyth/ui
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Peer Dependencies
|
|
12
12
|
|
|
13
|
-
- `react` ^19.2.
|
|
14
|
-
- `react-dom` ^19.2.
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
- `react` ^19.2.0
|
|
14
|
+
- `react-dom` ^19.2.0
|
|
15
|
+
|
|
16
|
+
`next` is only reachable through the `/widget` compatibility entry
|
|
17
|
+
(`Widget`). It ships as an ordinary workspace dependency here; the
|
|
18
|
+
published package declares it as an **optional** peer so an app that never
|
|
19
|
+
imports `/widget` never installs it.
|
|
17
20
|
|
|
18
21
|
## Exports
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
| Subpath | What it is |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `.` | All UI components, hooks, and utilities. Theme runtime is not here — see `/themes/provider`. |
|
|
26
|
+
| `./text` | `RichText` — renders Tiptap `JSONContent` through a node registry. |
|
|
27
|
+
| `./layout` | `Container`. |
|
|
28
|
+
| `./blocks` | `ColorPicker`, `Field`, `IconPicker`, `LoadingScreen`, `Widget`. |
|
|
29
|
+
| `./hooks` | `useIsMobile`. |
|
|
30
|
+
| `./themes/provider` | The framework-neutral theme runtime — see below. |
|
|
31
|
+
| `./themes` | Stylesheet: all seven palettes, `@import`ed. |
|
|
32
|
+
| `./themes/catpuccin/latte`, `./themes/catpuccin/frappe`, `./themes/catpuccin/macchiato`, `./themes/catpuccin/mocha`, `./themes/tokyo-night`, `./themes/ekko-os`, `./themes/ekkolyth` | Individual palette stylesheets — seven subpaths, one per palette. |
|
|
33
|
+
| `./base.css` | The base theme layer — see "Base CSS" below. |
|
|
34
|
+
|
|
35
|
+
`./widget` and `./convex` are **compatibility entries, not documented API.**
|
|
36
|
+
They exist because specific `apps/web` call sites import from them and sit
|
|
37
|
+
outside this package's edit surface; don't build new code against them.
|
|
21
38
|
|
|
22
|
-
|
|
39
|
+
**Components:**
|
|
40
|
+
Built on top of shadcn@latest.
|
|
23
41
|
|
|
24
42
|
```tsx
|
|
25
43
|
import { Button, Card, Dialog, useIsMobile, cn } from '@ekkolyth/ui'
|
|
26
44
|
```
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
Built on top of shadcn@latest.
|
|
30
|
-
|
|
31
|
-
### Next.js Theme Provider (`@ekkolyth/ui/next`)
|
|
46
|
+
## Theme Provider
|
|
32
47
|
|
|
33
|
-
|
|
48
|
+
One framework-neutral provider, at `@ekkolyth/ui/themes/provider`. No
|
|
49
|
+
`next-themes` — a vitest guard (`src/index.test.ts`) fails the build if
|
|
50
|
+
anything reachable from the root barrel imports it. The subpath exports:
|
|
34
51
|
|
|
35
52
|
```tsx
|
|
36
|
-
import {
|
|
37
|
-
|
|
53
|
+
import {
|
|
54
|
+
ThemeProvider,
|
|
55
|
+
ThemeScript,
|
|
56
|
+
ThemeSelect,
|
|
57
|
+
ThemeToggle,
|
|
58
|
+
Toaster,
|
|
59
|
+
useTheme,
|
|
60
|
+
} from '@ekkolyth/ui/themes/provider'
|
|
61
|
+
import type {
|
|
62
|
+
Appearance,
|
|
63
|
+
DarkThemes,
|
|
64
|
+
LightThemes,
|
|
65
|
+
ThemeContextState,
|
|
66
|
+
ThemeName,
|
|
67
|
+
ThemeProviderProps,
|
|
68
|
+
ThemeScriptProps,
|
|
69
|
+
} from '@ekkolyth/ui/themes/provider'
|
|
38
70
|
```
|
|
39
71
|
|
|
40
|
-
|
|
41
|
-
- `
|
|
42
|
-
- `lightTheme?:
|
|
43
|
-
- `darkTheme?:
|
|
44
|
-
- `storageKey?: string`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- `
|
|
49
|
-
- `resolvedTheme: ThemeName`
|
|
50
|
-
- `availableThemes: { light:
|
|
51
|
-
- `
|
|
52
|
-
- `setSpecificTheme: (mode:
|
|
72
|
+
**`ThemeProviderProps`:**
|
|
73
|
+
- `defaultAppearance?: Appearance` — `"light" | "dark" | "system" | "normal"`, default `"system"`. `"normal"` is a legacy alias for `"light"`.
|
|
74
|
+
- `lightTheme?: LightThemes | LightThemes[]` — light palette(s) to make available, default `"ekkolyth-light"`.
|
|
75
|
+
- `darkTheme?: DarkThemes | DarkThemes[]` — dark palette(s) to make available, default `"ekkolyth-dark"`.
|
|
76
|
+
- `storageKey?: string` — localStorage key prefix, default `"ekko-ui"`. Most apps won't need this; it matters if several frontends share a domain and need independent theme state.
|
|
77
|
+
|
|
78
|
+
**`useTheme()` returns `ThemeContextState`:**
|
|
79
|
+
- `appearance: Appearance` — the mode the user picked, before resolving `"system"`.
|
|
80
|
+
- `resolvedMode: 'light' | 'dark'` — `appearance` resolved against `matchMedia` when it's `"system"`.
|
|
81
|
+
- `resolvedTheme: ThemeName` — the palette currently applied for `resolvedMode`.
|
|
82
|
+
- `availableThemes: { light: LightThemes[], dark: DarkThemes[] }`
|
|
83
|
+
- `setAppearance: (appearance: Appearance) => void`
|
|
84
|
+
- `setSpecificTheme: (mode: 'light' | 'dark', theme: LightThemes | DarkThemes) => void`
|
|
85
|
+
|
|
86
|
+
`ThemeName` is the union of every palette (`LightThemes | DarkThemes`) —
|
|
87
|
+
which palette is showing. `Appearance` is a separate concept — light/dark/system
|
|
88
|
+
preference — deliberately a different word so the two don't get conflated at a
|
|
89
|
+
call site.
|
|
90
|
+
|
|
91
|
+
**`ThemeName` values:**
|
|
92
|
+
- `"latte" | "ekkoos-light" | "ekkolyth-light"` — light palettes
|
|
93
|
+
- `"mocha" | "frappe" | "macchiato" | "tokyo-night" | "ekkoos-dark" | "ekkolyth-dark"` — dark palettes
|
|
94
|
+
|
|
95
|
+
### `ThemeScript`
|
|
96
|
+
|
|
97
|
+
Renders a `<script>` that reads the stored appearance/palette from
|
|
98
|
+
`localStorage` and sets `data-theme` + the `.dark` class on `<html>` before
|
|
99
|
+
React hydrates. Put it in `<head>` — `app/layout.tsx` on Next.js,
|
|
100
|
+
`__root.tsx` on TanStack Start — with the same `defaultAppearance`,
|
|
101
|
+
`lightTheme`, `darkTheme`, and `storageKey` as the `<ThemeProvider>` it pairs
|
|
102
|
+
with. Skipping it doesn't break anything, it just costs one painted frame of
|
|
103
|
+
the wrong palette before the provider's own mount effect catches up.
|
|
53
104
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- `"tokyo-night"` - Tokyo Night theme
|
|
57
|
-
- `"ekkoos-light" | "ekkoos-dark"` - Ekko OS themes
|
|
58
|
-
- `"ekkolyth-light" | "ekkolyth-dark"` - Ekkolyth themes
|
|
59
|
-
- `"ekko-playlist-light" | "ekko-playlist-dark"` - Ekko Playlist themes
|
|
105
|
+
```tsx
|
|
106
|
+
import { ThemeScript } from '@ekkolyth/ui/themes/provider'
|
|
60
107
|
|
|
61
|
-
|
|
108
|
+
<head>
|
|
109
|
+
<ThemeScript defaultAppearance='system' />
|
|
110
|
+
</head>
|
|
111
|
+
```
|
|
62
112
|
|
|
63
|
-
Theme
|
|
113
|
+
### Theme Toggle / Theme Select
|
|
64
114
|
|
|
65
115
|
```tsx
|
|
66
|
-
import {
|
|
67
|
-
import type { SystemTheme, ThemeName } from '@ekkolyth/ui/tanstack'
|
|
116
|
+
import { ThemeToggle, ThemeSelect } from '@ekkolyth/ui/themes/provider'
|
|
68
117
|
```
|
|
69
118
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
**Note:** The `Toaster` component is exported from the theme provider entries (`/next` and `/tanstack`) and is automatically theme-aware. If you import `Toaster` from the main entry point (`@ekkolyth/ui`), it will be theme-agnostic and you'll need to pass a `theme` prop manually.
|
|
119
|
+
## Base CSS
|
|
73
120
|
|
|
74
|
-
|
|
121
|
+
`@ekkolyth/ui/base.css` is the base theme layer — 34 color tokens with
|
|
122
|
+
colourless (grayscale) defaults, the `@theme inline` mapping from those
|
|
123
|
+
tokens into Tailwind utilities, `@custom-variant dark`, and an `@layer base`
|
|
124
|
+
reset (`* { border-border outline-ring/50 }`, `body { bg-background
|
|
125
|
+
text-foreground }`). Import it after the consuming app's own
|
|
126
|
+
`@import 'tailwindcss'` and before its palette overrides:
|
|
75
127
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
import type { ThemeToggleProps } from '@ekkolyth/ui/themes/theme-toggle'
|
|
128
|
+
```css
|
|
129
|
+
@import 'tailwindcss';
|
|
130
|
+
@import '@ekkolyth/ui/base.css';
|
|
131
|
+
/* app-specific palette overrides go here */
|
|
81
132
|
```
|
|
82
133
|
|
|
83
|
-
|
|
134
|
+
The export resolves to `./src/base.css`, not `./dist/base.css`, deliberately:
|
|
135
|
+
`dist/` is gitignored, so a `dist` path would leave fresh clones and git
|
|
136
|
+
worktrees unstyled until someone ran the UI package's build.
|
|
84
137
|
|
|
85
|
-
|
|
86
|
-
import { ThemeSelect } from '@ekkolyth/ui/themes/theme-select'
|
|
87
|
-
import type { ThemeSelectProps } from '@ekkolyth/ui/themes/theme-select'
|
|
88
|
-
```
|
|
138
|
+
## Theme Styles
|
|
89
139
|
|
|
90
|
-
|
|
140
|
+
`@ekkolyth/ui/themes` is a **stylesheet entry** (a CSS `@import`, not a JS
|
|
141
|
+
module) that pulls in all seven palettes. It stands in for the app's own
|
|
142
|
+
Tailwind preamble, not the other way around — a theme picker that lets the
|
|
143
|
+
user switch palettes needs every palette present, so import it alongside the
|
|
144
|
+
three lines every consumer already writes:
|
|
91
145
|
|
|
92
|
-
|
|
146
|
+
```css
|
|
147
|
+
@import 'tailwindcss';
|
|
148
|
+
@import 'tw-animate-css';
|
|
149
|
+
@import '@ekkolyth/ui/base.css';
|
|
150
|
+
@import '@ekkolyth/ui/themes';
|
|
151
|
+
```
|
|
93
152
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
import
|
|
153
|
+
Each palette is scoped to `html[data-theme='<name>']`; the provider and
|
|
154
|
+
`ThemeScript` switch palettes by setting that attribute, so nothing here is a
|
|
155
|
+
runtime import. Pull a single palette instead of the aggregate when an app
|
|
156
|
+
only ever shows one:
|
|
97
157
|
|
|
98
|
-
|
|
99
|
-
import '@ekkolyth/ui/catpuccin/latte'
|
|
100
|
-
import '@ekkolyth/ui/
|
|
101
|
-
import '@ekkolyth/ui/
|
|
102
|
-
import '@ekkolyth/ui/catpuccin/mocha'
|
|
103
|
-
|
|
104
|
-
// Other themes
|
|
105
|
-
import '@ekkolyth/ui/tokyo-night'
|
|
106
|
-
import '@ekkolyth/ui/ekko-os'
|
|
107
|
-
import '@ekkolyth/ui/ekkolyth'
|
|
108
|
-
import '@ekkolyth/ui/ekko-playlist'
|
|
158
|
+
```css
|
|
159
|
+
@import '@ekkolyth/ui/themes/catpuccin/latte';
|
|
160
|
+
@import '@ekkolyth/ui/themes/tokyo-night';
|
|
161
|
+
@import '@ekkolyth/ui/themes/ekkolyth';
|
|
109
162
|
```
|
|
110
163
|
|
|
111
164
|
## Usage Example
|
|
@@ -114,17 +167,20 @@ import '@ekkolyth/ui/ekko-playlist'
|
|
|
114
167
|
|
|
115
168
|
```tsx
|
|
116
169
|
// app/layout.tsx
|
|
117
|
-
import { ThemeProvider, Toaster } from '@ekkolyth/ui/
|
|
170
|
+
import { ThemeProvider, ThemeScript, Toaster } from '@ekkolyth/ui/themes/provider'
|
|
118
171
|
import '@ekkolyth/ui/themes'
|
|
119
172
|
|
|
120
173
|
export default function RootLayout({ children }) {
|
|
121
174
|
return (
|
|
122
175
|
<html>
|
|
176
|
+
<head>
|
|
177
|
+
<ThemeScript defaultAppearance='system' />
|
|
178
|
+
</head>
|
|
123
179
|
<body>
|
|
124
180
|
<ThemeProvider
|
|
125
|
-
|
|
126
|
-
lightTheme={[
|
|
127
|
-
darkTheme={[
|
|
181
|
+
defaultAppearance='system'
|
|
182
|
+
lightTheme={['latte', 'ekkolyth-light']}
|
|
183
|
+
darkTheme={['mocha', 'ekkolyth-dark']}
|
|
128
184
|
>
|
|
129
185
|
{children}
|
|
130
186
|
<Toaster />
|
|
@@ -137,16 +193,15 @@ export default function RootLayout({ children }) {
|
|
|
137
193
|
// app/page.tsx
|
|
138
194
|
'use client'
|
|
139
195
|
import { Button } from '@ekkolyth/ui'
|
|
140
|
-
import { ThemeToggle } from '@ekkolyth/ui/themes/
|
|
141
|
-
import { useTheme } from '@ekkolyth/ui/next'
|
|
196
|
+
import { ThemeToggle, useTheme } from '@ekkolyth/ui/themes/provider'
|
|
142
197
|
|
|
143
198
|
export default function Page() {
|
|
144
|
-
const {
|
|
145
|
-
|
|
199
|
+
const { appearance, setAppearance } = useTheme()
|
|
200
|
+
|
|
146
201
|
return (
|
|
147
202
|
<div>
|
|
148
203
|
<ThemeToggle />
|
|
149
|
-
<Button onClick={() =>
|
|
204
|
+
<Button onClick={() => setAppearance('dark')}>
|
|
150
205
|
Set Dark Mode
|
|
151
206
|
</Button>
|
|
152
207
|
</div>
|
|
@@ -154,23 +209,24 @@ export default function Page() {
|
|
|
154
209
|
}
|
|
155
210
|
```
|
|
156
211
|
|
|
157
|
-
|
|
212
|
+
## Release
|
|
158
213
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
214
|
+
1. On the feature branch, describe the change: `bun run changeset`.
|
|
215
|
+
2. Merge to `main`. `.github/workflows/release-packages.yml` consumes the
|
|
216
|
+
Changesets plan, bumps the manifest and changelog, builds the package, and
|
|
217
|
+
runs `scripts/stage-public.ts` to produce the `@ekkolyth/ui` artifact with its
|
|
218
|
+
curated `dist/` exports.
|
|
219
|
+
3. `scripts/validate-package.ts` checks the staged tarball before anything
|
|
220
|
+
ships.
|
|
221
|
+
4. The workflow publishes the validated tarball, commits the release state,
|
|
222
|
+
and tags the release `ui-v<version>`.
|
|
163
223
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
</ThemeProvider>
|
|
174
|
-
)
|
|
175
|
-
}
|
|
176
|
-
```
|
|
224
|
+
A push to `main` with no pending changeset is a no-op — `changeset version`
|
|
225
|
+
has nothing to consume, and the commit/publish steps detect the unchanged
|
|
226
|
+
manifest and stop.
|
|
227
|
+
|
|
228
|
+
### Storybook + vitest
|
|
229
|
+
|
|
230
|
+
The package's storybook (`.storybook/main.ts`) and vitest (`vitest.config.ts`)
|
|
231
|
+
configs include `@ekkolyth/ui` in their alias maps so stories and unit tests resolve
|
|
232
|
+
internal imports the same way the dev/prod bundler does.
|
package/dist/base.css
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/* Base theme layer for every app consuming this package.
|
|
2
|
+
*
|
|
3
|
+
* Deliberately colourless: an app that forgets to override a token renders
|
|
4
|
+
* unthemed rather than plausibly designed. An undefined CSS variable resolves
|
|
5
|
+
* to nothing silently, which is the failure this file exists to remove.
|
|
6
|
+
*
|
|
7
|
+
* Does not import tailwindcss — the consuming app owns that import and must
|
|
8
|
+
* place it before this one, so the @apply rules below resolve. */
|
|
9
|
+
|
|
10
|
+
@plugin '@tailwindcss/typography';
|
|
11
|
+
|
|
12
|
+
@custom-variant dark (&:is(.dark *));
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--radius: 0.625rem;
|
|
16
|
+
|
|
17
|
+
--background: oklch(1 0 0);
|
|
18
|
+
--foreground: oklch(0.145 0 0);
|
|
19
|
+
--card: oklch(1 0 0);
|
|
20
|
+
--card-foreground: oklch(0.145 0 0);
|
|
21
|
+
--popover: oklch(1 0 0);
|
|
22
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
23
|
+
--primary: oklch(0.205 0 0);
|
|
24
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
25
|
+
--secondary: oklch(0.97 0 0);
|
|
26
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
27
|
+
--muted: oklch(0.97 0 0);
|
|
28
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
29
|
+
--accent: oklch(0.97 0 0);
|
|
30
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
31
|
+
--destructive: oklch(0.45 0 0);
|
|
32
|
+
--destructive-foreground: oklch(0.985 0 0);
|
|
33
|
+
--success: oklch(0.55 0 0);
|
|
34
|
+
--warning: oklch(0.65 0 0);
|
|
35
|
+
--info: oklch(0.6 0 0);
|
|
36
|
+
--border: oklch(0.922 0 0);
|
|
37
|
+
--input: oklch(0.922 0 0);
|
|
38
|
+
--ring: oklch(0.708 0 0);
|
|
39
|
+
--chart-1: oklch(0.35 0 0);
|
|
40
|
+
--chart-2: oklch(0.45 0 0);
|
|
41
|
+
--chart-3: oklch(0.55 0 0);
|
|
42
|
+
--chart-4: oklch(0.65 0 0);
|
|
43
|
+
--chart-5: oklch(0.75 0 0);
|
|
44
|
+
--sidebar: oklch(0.985 0 0);
|
|
45
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
46
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
47
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
48
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
49
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
50
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
51
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.dark {
|
|
55
|
+
--background: oklch(0.145 0 0);
|
|
56
|
+
--foreground: oklch(0.985 0 0);
|
|
57
|
+
--card: oklch(0.205 0 0);
|
|
58
|
+
--card-foreground: oklch(0.985 0 0);
|
|
59
|
+
--popover: oklch(0.205 0 0);
|
|
60
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
61
|
+
--primary: oklch(0.922 0 0);
|
|
62
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
63
|
+
--secondary: oklch(0.269 0 0);
|
|
64
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
65
|
+
--muted: oklch(0.269 0 0);
|
|
66
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
67
|
+
--accent: oklch(0.269 0 0);
|
|
68
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
69
|
+
--destructive: oklch(0.6 0 0);
|
|
70
|
+
--destructive-foreground: oklch(0.985 0 0);
|
|
71
|
+
--success: oklch(0.65 0 0);
|
|
72
|
+
--warning: oklch(0.75 0 0);
|
|
73
|
+
--info: oklch(0.7 0 0);
|
|
74
|
+
--border: oklch(0.269 0 0);
|
|
75
|
+
--input: oklch(0.269 0 0);
|
|
76
|
+
--ring: oklch(0.556 0 0);
|
|
77
|
+
--chart-1: oklch(0.45 0 0);
|
|
78
|
+
--chart-2: oklch(0.55 0 0);
|
|
79
|
+
--chart-3: oklch(0.65 0 0);
|
|
80
|
+
--chart-4: oklch(0.75 0 0);
|
|
81
|
+
--chart-5: oklch(0.85 0 0);
|
|
82
|
+
--sidebar: oklch(0.205 0 0);
|
|
83
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
84
|
+
--sidebar-primary: oklch(0.922 0 0);
|
|
85
|
+
--sidebar-primary-foreground: oklch(0.205 0 0);
|
|
86
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
87
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
88
|
+
--sidebar-border: oklch(0.269 0 0);
|
|
89
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
90
|
+
color-scheme: dark;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@theme inline {
|
|
94
|
+
--color-background: var(--background);
|
|
95
|
+
--color-foreground: var(--foreground);
|
|
96
|
+
--color-card: var(--card);
|
|
97
|
+
--color-card-foreground: var(--card-foreground);
|
|
98
|
+
--color-popover: var(--popover);
|
|
99
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
100
|
+
--color-primary: var(--primary);
|
|
101
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
102
|
+
--color-secondary: var(--secondary);
|
|
103
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
104
|
+
--color-muted: var(--muted);
|
|
105
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
106
|
+
--color-accent: var(--accent);
|
|
107
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
108
|
+
--color-destructive: var(--destructive);
|
|
109
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
110
|
+
--color-success: var(--success);
|
|
111
|
+
--color-warning: var(--warning);
|
|
112
|
+
--color-info: var(--info);
|
|
113
|
+
--color-border: var(--border);
|
|
114
|
+
--color-input: var(--input);
|
|
115
|
+
--color-ring: var(--ring);
|
|
116
|
+
--color-chart-1: var(--chart-1);
|
|
117
|
+
--color-chart-2: var(--chart-2);
|
|
118
|
+
--color-chart-3: var(--chart-3);
|
|
119
|
+
--color-chart-4: var(--chart-4);
|
|
120
|
+
--color-chart-5: var(--chart-5);
|
|
121
|
+
--color-sidebar: var(--sidebar);
|
|
122
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
123
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
124
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
125
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
126
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
127
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
128
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
129
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
130
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
131
|
+
--radius-lg: var(--radius);
|
|
132
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
133
|
+
--radius-2xl: calc(var(--radius) + 8px);
|
|
134
|
+
--radius-3xl: calc(var(--radius) + 12px);
|
|
135
|
+
--radius-4xl: calc(var(--radius) + 16px);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Plain @theme, not @theme inline: `inline` bakes the value straight into
|
|
139
|
+
* .font-sans, which makes a per-palette override impossible. Emitting the
|
|
140
|
+
* variable to :root is what lets html[data-theme='…'] swap the face.
|
|
141
|
+
*
|
|
142
|
+
* Atkinson Hyperlegible Next and its Mono sibling are the package's default
|
|
143
|
+
* pair — designed together, and picked for legibility. The chain degrades to
|
|
144
|
+
* a real system font for a consumer who hasn't loaded the webfont. */
|
|
145
|
+
@theme {
|
|
146
|
+
--font-sans:
|
|
147
|
+
'Atkinson Hyperlegible Next Variable', ui-sans-serif, system-ui,
|
|
148
|
+
sans-serif;
|
|
149
|
+
--font-mono:
|
|
150
|
+
'Atkinson Hyperlegible Mono Variable', ui-monospace, SFMono-Regular,
|
|
151
|
+
Menlo, monospace;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* The sidebar is a dark panel inside a light theme, so a child reading the
|
|
155
|
+
* page-level tokens disappears: --muted-foreground is a mid grey tuned for
|
|
156
|
+
* white, --border a pale hairline that reads as a white outline. Rebinding
|
|
157
|
+
* them here means an ordinary component — and text-muted-foreground in
|
|
158
|
+
* particular — works in a sidebar without knowing it is in one. */
|
|
159
|
+
[data-slot='sidebar'][data-slot],
|
|
160
|
+
[data-slot='sidebar-container'][data-slot] {
|
|
161
|
+
--foreground: var(--sidebar-foreground);
|
|
162
|
+
--muted-foreground: color-mix(
|
|
163
|
+
in oklab,
|
|
164
|
+
var(--sidebar-foreground) 65%,
|
|
165
|
+
var(--sidebar)
|
|
166
|
+
);
|
|
167
|
+
--border: var(--sidebar-border);
|
|
168
|
+
--accent: var(--sidebar-accent);
|
|
169
|
+
--accent-foreground: var(--sidebar-accent-foreground);
|
|
170
|
+
--ring: var(--sidebar-ring);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@layer base {
|
|
174
|
+
* {
|
|
175
|
+
@apply border-border outline-ring/50;
|
|
176
|
+
}
|
|
177
|
+
body {
|
|
178
|
+
@apply bg-background text-foreground;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.prose h1,
|
|
183
|
+
.prose h2,
|
|
184
|
+
.prose h3 {
|
|
185
|
+
margin-top: 2.5rem;
|
|
186
|
+
margin-bottom: 0.5rem;
|
|
187
|
+
}
|
|
188
|
+
.prose h1 {
|
|
189
|
+
font-size: 1.5em;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
}
|
|
192
|
+
.prose h2 {
|
|
193
|
+
font-size: 1.25em;
|
|
194
|
+
font-weight: 600;
|
|
195
|
+
}
|
|
196
|
+
.prose h3 {
|
|
197
|
+
font-size: 1.125em;
|
|
198
|
+
font-weight: 600;
|
|
199
|
+
}
|
|
200
|
+
.prose h1:first-child,
|
|
201
|
+
.prose h2:first-child,
|
|
202
|
+
.prose h3:first-child {
|
|
203
|
+
margin-top: 0;
|
|
204
|
+
}
|
|
205
|
+
.prose h1 + * {
|
|
206
|
+
margin-top: 1.5rem;
|
|
207
|
+
}
|
|
208
|
+
.prose h2 + * {
|
|
209
|
+
margin-top: 1rem;
|
|
210
|
+
}
|
|
211
|
+
.prose h3 + * {
|
|
212
|
+
margin-top: 0.75rem;
|
|
213
|
+
}
|
|
214
|
+
/* @tailwindcss/typography wraps inline <code> in literal backticks via
|
|
215
|
+
* ::before/::after pseudo-content and leaves it otherwise unstyled. Strip
|
|
216
|
+
* the backticks and render inline code as a rounded muted pill. */
|
|
217
|
+
.prose :not(pre) > code::before,
|
|
218
|
+
.prose :not(pre) > code::after {
|
|
219
|
+
content: none;
|
|
220
|
+
}
|
|
221
|
+
.prose :not(pre) > code {
|
|
222
|
+
padding: 0.125rem 0.375rem;
|
|
223
|
+
font-family: var(--font-mono);
|
|
224
|
+
font-size: 0.875em;
|
|
225
|
+
font-weight: 500;
|
|
226
|
+
color: var(--foreground);
|
|
227
|
+
background-color: var(--muted);
|
|
228
|
+
border: 1px solid var(--border);
|
|
229
|
+
border-radius: 0.25rem;
|
|
230
|
+
}
|
|
231
|
+
.prose thead th,
|
|
232
|
+
.prose tbody td,
|
|
233
|
+
.prose tfoot td {
|
|
234
|
+
padding-top: 0.375rem !important;
|
|
235
|
+
padding-bottom: 0.375rem !important;
|
|
236
|
+
border-right: 1px solid color-mix(in oklab, var(--border) 40%, transparent);
|
|
237
|
+
}
|
|
238
|
+
.prose thead th:last-child,
|
|
239
|
+
.prose tbody td:last-child,
|
|
240
|
+
.prose tfoot td:last-child {
|
|
241
|
+
border-right: 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* Shiki renders with `defaultColor: false`, so every token carries its colours
|
|
245
|
+
as --shiki-light / --shiki-dark variables and nothing else. These rules pick
|
|
246
|
+
the pair for the active theme. Without them the block has no colour at all,
|
|
247
|
+
and with shiki's default the light theme wins in dark mode — the variables
|
|
248
|
+
would be inert either way, because inline styles can only be beaten by
|
|
249
|
+
!important, which the biome config rejects. */
|
|
250
|
+
.shiki {
|
|
251
|
+
background-color: var(--shiki-light-bg);
|
|
252
|
+
}
|
|
253
|
+
.shiki,
|
|
254
|
+
.shiki span {
|
|
255
|
+
color: var(--shiki-light);
|
|
256
|
+
}
|
|
257
|
+
.dark .shiki {
|
|
258
|
+
background-color: var(--shiki-dark-bg);
|
|
259
|
+
}
|
|
260
|
+
.dark .shiki,
|
|
261
|
+
.dark .shiki span {
|
|
262
|
+
color: var(--shiki-dark);
|
|
263
|
+
}
|
package/dist/blocks.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { i as ColorPicker, n as Field, r as validate, t as IconPicker } from "./index-DHF8OR1R.js";
|
|
2
|
+
import { n as LoadingScreenProps, t as LoadingScreen } from "./index-DsLGf2HX.js";
|
|
3
|
+
import { n as WidgetLinkProps, r as WidgetProps, t as Widget } from "./index-qji4ohJZ.js";
|
|
4
|
+
export { ColorPicker, Field, IconPicker, LoadingScreen, type LoadingScreenProps, Widget, type WidgetLinkProps, type WidgetProps, validate };
|
package/dist/blocks.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { R as validate, d as Field, t as IconPicker, z as ColorPicker } from "./icon-picker-ByfHyJ7i.js";
|
|
2
|
+
import { t as LoadingScreen } from "./loading-screen-DB3youyT.js";
|
|
3
|
+
import { t as Widget } from "./widget-C2vjxQms.js";
|
|
4
|
+
export { ColorPicker, Field, IconPicker, LoadingScreen, Widget, validate };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/components/layout/container/index.tsx
|
|
3
|
+
function Container({ className, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5
|
+
className: ["mx-auto flex w-full max-w-7xl flex-1 flex-col p-3 md:p-6", className].filter(Boolean).join(" "),
|
|
6
|
+
...props
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { Container as t };
|
package/dist/convex.d.ts
ADDED
package/dist/convex.js
ADDED
package/dist/hooks.d.ts
ADDED
package/dist/hooks.js
ADDED