eidos-ui 2.1.0 → 3.1.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 (56) hide show
  1. package/README.md +66 -16
  2. package/dist/ThemeProvider.types-DgXN0gEH.d.cts +88 -0
  3. package/dist/ThemeProvider.types-DgXN0gEH.d.ts +88 -0
  4. package/dist/chunk-2ZY7M72Q.js +521 -0
  5. package/dist/chunk-2ZY7M72Q.js.map +1 -0
  6. package/dist/{chunk-W6IKHJ76.cjs → chunk-5BX4Q76D.cjs} +134 -126
  7. package/dist/chunk-5BX4Q76D.cjs.map +1 -0
  8. package/dist/{chunk-RAZRQ57B.js → chunk-74MBKLYI.js} +97 -16
  9. package/dist/chunk-74MBKLYI.js.map +1 -0
  10. package/dist/chunk-H5HWFOWZ.js +390 -0
  11. package/dist/chunk-H5HWFOWZ.js.map +1 -0
  12. package/dist/{chunk-VHQTDITV.cjs → chunk-KQD7CQ4Z.cjs} +96 -15
  13. package/dist/chunk-KQD7CQ4Z.cjs.map +1 -0
  14. package/dist/{chunk-JV7Z3D3U.js → chunk-LEMCJW57.js} +134 -126
  15. package/dist/chunk-LEMCJW57.js.map +1 -0
  16. package/dist/chunk-SE7MWOC7.cjs +390 -0
  17. package/dist/chunk-SE7MWOC7.cjs.map +1 -0
  18. package/dist/chunk-U5FHQ73U.cjs +521 -0
  19. package/dist/chunk-U5FHQ73U.cjs.map +1 -0
  20. package/dist/color-picker/index.cjs +2 -2
  21. package/dist/color-picker/index.js +1 -1
  22. package/dist/fonts/JetBrains-Mono-OFL.txt +93 -0
  23. package/dist/fonts/Plus-Jakarta-Sans-OFL.txt +93 -0
  24. package/dist/fonts/jetbrains-mono-latin-ext-wght-normal.woff2 +0 -0
  25. package/dist/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
  26. package/dist/fonts/plus-jakarta-sans-latin-ext-wght-normal.woff2 +0 -0
  27. package/dist/fonts/plus-jakarta-sans-latin-wght-normal.woff2 +0 -0
  28. package/dist/fonts.css +32 -0
  29. package/dist/fonts.css.d.ts +2 -0
  30. package/dist/index.cjs +32 -6
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.css +467 -123
  33. package/dist/index.d.cts +3 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.js +35 -9
  36. package/dist/tabs/index.cjs +2 -2
  37. package/dist/tabs/index.d.cts +11 -0
  38. package/dist/tabs/index.d.ts +11 -0
  39. package/dist/tabs/index.js +1 -1
  40. package/dist/theme-editor/index.cjs +22 -0
  41. package/dist/theme-editor/index.cjs.map +1 -0
  42. package/dist/theme-editor/index.d.cts +65 -0
  43. package/dist/theme-editor/index.d.ts +65 -0
  44. package/dist/theme-editor/index.js +22 -0
  45. package/dist/theme-editor/index.js.map +1 -0
  46. package/dist/theme-provider/index.cjs +27 -0
  47. package/dist/theme-provider/index.cjs.map +1 -0
  48. package/dist/theme-provider/index.d.cts +123 -0
  49. package/dist/theme-provider/index.d.ts +123 -0
  50. package/dist/theme-provider/index.js +27 -0
  51. package/dist/theme-provider/index.js.map +1 -0
  52. package/package.json +13 -3
  53. package/dist/chunk-JV7Z3D3U.js.map +0 -1
  54. package/dist/chunk-RAZRQ57B.js.map +0 -1
  55. package/dist/chunk-VHQTDITV.cjs.map +0 -1
  56. package/dist/chunk-W6IKHJ76.cjs.map +0 -1
package/README.md CHANGED
@@ -19,14 +19,14 @@
19
19
 
20
20
  ## Features
21
21
 
22
- | | |
23
- | ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
24
- | **Themeable** | Every design token is a CSS custom property, so palette, spacing, and radii can be overridden without touching source. |
25
- | **Type-safe** | Written in TypeScript with full prop typings exported for every component. |
26
- | **Tree-shakeable** | Per-component entry points (`eidos-ui/button`, `eidos-ui/table`, ...) keep bundles lean. |
27
- | **Icon-agnostic** | Works with any icon library - Lucide, MUI Icons, Font Awesome, Remix Icons, or your own. |
28
- | **Accessible** | Built with keyboard navigation and ARIA semantics in mind. |
29
- | **Optimized build** | Bundled with tsup, shipping both ESM and CJS with source maps and `.d.ts` files. |
22
+ | | |
23
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
24
+ | **Themeable** | Every design token is a CSS custom property. Override them statically, or let users change the palette and typography at runtime with `ThemeProvider`. |
25
+ | **Type-safe** | Written in TypeScript with full prop typings exported for every component. |
26
+ | **Tree-shakeable** | Per-component entry points (`eidos-ui/button`, `eidos-ui/table`, ...) keep bundles lean. |
27
+ | **Icon-agnostic** | Works with any icon library - Lucide, MUI Icons, Font Awesome, Remix Icons, or your own. |
28
+ | **Accessible** | Built with keyboard navigation and ARIA semantics in mind. |
29
+ | **Optimized build** | Bundled with tsup, shipping both ESM and CJS with source maps and `.d.ts` files. |
30
30
 
31
31
  ## Installation
32
32
 
@@ -45,6 +45,7 @@ npm install lucide-react
45
45
  ```tsx
46
46
  import { Button, Tooltip } from 'eidos-ui';
47
47
  import 'eidos-ui/styles';
48
+ import 'eidos-ui/fonts'; // optional - bundled Plus Jakarta Sans + JetBrains Mono
48
49
 
49
50
  function App() {
50
51
  return (
@@ -91,6 +92,11 @@ These are the same groups used in Storybook, so the README and the docs sidebar
91
92
  - Toolbar
92
93
  - Breadcrumb
93
94
 
95
+ **Theming**
96
+
97
+ - ThemeProvider
98
+ - ThemeEditor
99
+
94
100
  **Elements**
95
101
 
96
102
  - Button
@@ -120,7 +126,6 @@ These are the same groups used in Storybook, so the README and the docs sidebar
120
126
  - Switch
121
127
  - Slider
122
128
  - ColorPicker
123
- - DatePicker
124
129
  - OTPInput
125
130
  - TagInput
126
131
  - FileUpload
@@ -139,7 +144,9 @@ These are the same groups used in Storybook, so the README and the docs sidebar
139
144
  **Data**
140
145
 
141
146
  - Table
147
+ - TableFiltersDropdown
142
148
  - DataGrid
149
+ - DatePicker
143
150
  - Timeline
144
151
  - VirtualList
145
152
 
@@ -180,15 +187,19 @@ npm run storybook
180
187
 
181
188
  ## Theming
182
189
 
183
- All design tokens are exposed as CSS custom properties, so themes can be overridden globally without touching component source.
190
+ Every design token is a CSS custom property. There are two ways to change them, depending on whether the theme is fixed at build time or chosen by the user.
191
+
192
+ ### Static overrides
193
+
194
+ Redeclare any token in your own stylesheet:
184
195
 
185
196
  ```css
186
197
  :root {
187
- /* Colors */
188
- --primary-color: #6366f1;
189
- --secondary-color: #ec4899;
198
+ /* Colours - each family also has -dark, -light, -rgb and -contrast */
199
+ --primary-color: #5c5de8;
200
+ --secondary-color: #617087;
190
201
 
191
- /* Spacing */
202
+ /* Spacing (em-based, so it scales with font size) */
192
203
  --spacing-md: 1em;
193
204
  --spacing-lg: 1.5em;
194
205
 
@@ -197,15 +208,54 @@ All design tokens are exposed as CSS custom properties, so themes can be overrid
197
208
  }
198
209
  ```
199
210
 
200
- Individual component styles can also be targeted directly, following each component's `eidos-<name>` BEM-style class names:
211
+ Individual components can also be targeted directly, following each component's `eidos-<name>` BEM-style class names:
201
212
 
202
213
  ```css
203
214
  .eidos-button--filled.eidos-button--primary {
204
215
  border-radius: 20px;
205
- background: linear-gradient(to right, #6366f1, #8b5cf6);
216
+ background: linear-gradient(to right, #5c5de8, #8b5cf6);
206
217
  }
207
218
  ```
208
219
 
220
+ ### Runtime theming
221
+
222
+ `ThemeProvider` applies a theme at runtime — for a settings screen, a per-tenant palette, or a colour a user picks. Supply one base colour per family and the shades, tints, ramp steps and accessible foregrounds are derived from it:
223
+
224
+ ```tsx
225
+ import { ThemeProvider, ThemeEditor } from 'eidos-ui';
226
+
227
+ <ThemeProvider defaultTheme={{ colors: { primary: '#0ea5e9' } }}>
228
+ <App />
229
+ </ThemeProvider>;
230
+ ```
231
+
232
+ `ThemeEditor` is a ready-made panel for editing the active theme, with live WCAG contrast readouts per colour:
233
+
234
+ ```tsx
235
+ <ThemeProvider theme={theme} onThemeChange={saveThemeForUser}>
236
+ <ThemeEditor />
237
+ <App />
238
+ </ThemeProvider>
239
+ ```
240
+
241
+ Ten things are editable — seven colour bases, two font stacks, and a font scale. Tokens are written through the CSSOM to `document.documentElement`, which needs **no Content Security Policy allowance** and covers portaled overlays too. A theme equal to the preset writes nothing at all.
242
+
243
+ Use `useTheme()` to read or change it from your own UI, and `toCss()` to export the resolved tokens as a `:root` block you can paste into a stylesheet — useful for baking a theme in at build time.
244
+
245
+ ### Fonts
246
+
247
+ The theme names Plus Jakarta Sans and JetBrains Mono, but a font stack only _names_ families — it cannot install them. Import the bundled copies to actually use them:
248
+
249
+ ```ts
250
+ import 'eidos-ui/fonts';
251
+ ```
252
+
253
+ This is a separate entry point because these are the only rules in the library that fetch a subresource; importing it means allowing `font-src 'self'` (already covered by `default-src 'self'`). Skip it and the stylesheet fetches nothing, falling back to system fonts.
254
+
255
+ For a font of your own, `registerFontFace(family, arrayBuffer)` registers one at runtime with no CSP allowance at all.
256
+
257
+ See the **Theming** and **Content Security Policy** pages in Storybook for the full reference.
258
+
209
259
  ## TypeScript
210
260
 
211
261
  Every component ships with exported prop types:
@@ -0,0 +1,88 @@
1
+ import React__default from 'react';
2
+
3
+ /** The seven themeable colour families. */
4
+ type ThemeColorKey = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'hyperlink';
5
+ /**
6
+ * A themeable colour: either a bare hex string, or an object that also pins the
7
+ * foreground to place on it.
8
+ *
9
+ * `contrast` exists because the provider writes tokens inline on
10
+ * `document.documentElement`, and inline styles beat author stylesheets - a
11
+ * consumer who must have a specific foreground could otherwise only override it
12
+ * with `!important`. Leave it unset to have it computed (see `pickContrast`).
13
+ */
14
+ type ThemeColorValue = string | {
15
+ base: string;
16
+ contrast?: string;
17
+ };
18
+ type ThemeColors = Partial<Record<ThemeColorKey, ThemeColorValue>>;
19
+ /** A selectable font stack, as offered by `ThemeEditor`. */
20
+ interface ThemeFontOption {
21
+ /** Display name, e.g. "Plus Jakarta Sans". */
22
+ label: string;
23
+ /** The full CSS font stack written to the token. */
24
+ value: string;
25
+ }
26
+ interface ThemeTypography {
27
+ /** Replaces `--font-family-primary`. A full CSS font stack. */
28
+ fontFamily?: string;
29
+ /** Replaces `--font-family-mono`. A full CSS font stack. */
30
+ monoFamily?: string;
31
+ /**
32
+ * Multiplier applied to all eight `--font-size-*` tokens. 1 is the preset.
33
+ *
34
+ * Note that `--spacing-*` is declared in `em`, so this scales most padding
35
+ * and gaps along with the text rather than only the glyphs.
36
+ */
37
+ fontScale?: number;
38
+ }
39
+ /**
40
+ * A theme. Every field is optional and anything omitted falls back to
41
+ * `defaultTheme`, so a theme may be as small as one colour.
42
+ *
43
+ * Named `ThemeConfig` rather than `Theme` to avoid colliding with the `Theme`
44
+ * exported by MUI, styled-components and others in a consumer's namespace.
45
+ */
46
+ interface ThemeConfig {
47
+ colors?: ThemeColors;
48
+ typography?: ThemeTypography;
49
+ }
50
+ /** A theme with every field populated - what the provider actually applies. */
51
+ interface ResolvedTheme {
52
+ colors: Record<ThemeColorKey, {
53
+ base: string;
54
+ contrast?: string;
55
+ }>;
56
+ typography: Required<ThemeTypography>;
57
+ }
58
+ interface ThemeContextValue {
59
+ /** The theme as supplied, with omitted fields left absent. */
60
+ theme: ThemeConfig;
61
+ /** The same theme with every field filled in from the preset. */
62
+ resolvedTheme: ResolvedTheme;
63
+ /** Replaces the whole theme. */
64
+ setTheme: (theme: ThemeConfig) => void;
65
+ /** Deep-merges a partial theme into the current one. */
66
+ updateTheme: (patch: ThemeConfig) => void;
67
+ /** Returns to the preset. */
68
+ resetTheme: () => void;
69
+ /** True when nothing differs from the preset, so no tokens are being written. */
70
+ isDefault: boolean;
71
+ /** The resolved theme as a `:root { … }` CSS block. */
72
+ toCss: () => string;
73
+ }
74
+ interface ThemeProviderProps {
75
+ children: React__default.ReactNode;
76
+ /**
77
+ * Controlled theme. Pair with `onThemeChange` and own persistence yourself -
78
+ * this is the mode to use when the theme comes from a user record on your
79
+ * server.
80
+ */
81
+ theme?: ThemeConfig;
82
+ /** Initial theme for uncontrolled usage. Ignored when `theme` is supplied. */
83
+ defaultTheme?: ThemeConfig;
84
+ /** Fires whenever the theme changes, in both controlled and uncontrolled mode. */
85
+ onThemeChange?: (theme: ThemeConfig) => void;
86
+ }
87
+
88
+ export type { ResolvedTheme as R, ThemeColorKey as T, ThemeColorValue as a, ThemeColors as b, ThemeConfig as c, ThemeContextValue as d, ThemeFontOption as e, ThemeProviderProps as f, ThemeTypography as g };
@@ -0,0 +1,88 @@
1
+ import React__default from 'react';
2
+
3
+ /** The seven themeable colour families. */
4
+ type ThemeColorKey = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'hyperlink';
5
+ /**
6
+ * A themeable colour: either a bare hex string, or an object that also pins the
7
+ * foreground to place on it.
8
+ *
9
+ * `contrast` exists because the provider writes tokens inline on
10
+ * `document.documentElement`, and inline styles beat author stylesheets - a
11
+ * consumer who must have a specific foreground could otherwise only override it
12
+ * with `!important`. Leave it unset to have it computed (see `pickContrast`).
13
+ */
14
+ type ThemeColorValue = string | {
15
+ base: string;
16
+ contrast?: string;
17
+ };
18
+ type ThemeColors = Partial<Record<ThemeColorKey, ThemeColorValue>>;
19
+ /** A selectable font stack, as offered by `ThemeEditor`. */
20
+ interface ThemeFontOption {
21
+ /** Display name, e.g. "Plus Jakarta Sans". */
22
+ label: string;
23
+ /** The full CSS font stack written to the token. */
24
+ value: string;
25
+ }
26
+ interface ThemeTypography {
27
+ /** Replaces `--font-family-primary`. A full CSS font stack. */
28
+ fontFamily?: string;
29
+ /** Replaces `--font-family-mono`. A full CSS font stack. */
30
+ monoFamily?: string;
31
+ /**
32
+ * Multiplier applied to all eight `--font-size-*` tokens. 1 is the preset.
33
+ *
34
+ * Note that `--spacing-*` is declared in `em`, so this scales most padding
35
+ * and gaps along with the text rather than only the glyphs.
36
+ */
37
+ fontScale?: number;
38
+ }
39
+ /**
40
+ * A theme. Every field is optional and anything omitted falls back to
41
+ * `defaultTheme`, so a theme may be as small as one colour.
42
+ *
43
+ * Named `ThemeConfig` rather than `Theme` to avoid colliding with the `Theme`
44
+ * exported by MUI, styled-components and others in a consumer's namespace.
45
+ */
46
+ interface ThemeConfig {
47
+ colors?: ThemeColors;
48
+ typography?: ThemeTypography;
49
+ }
50
+ /** A theme with every field populated - what the provider actually applies. */
51
+ interface ResolvedTheme {
52
+ colors: Record<ThemeColorKey, {
53
+ base: string;
54
+ contrast?: string;
55
+ }>;
56
+ typography: Required<ThemeTypography>;
57
+ }
58
+ interface ThemeContextValue {
59
+ /** The theme as supplied, with omitted fields left absent. */
60
+ theme: ThemeConfig;
61
+ /** The same theme with every field filled in from the preset. */
62
+ resolvedTheme: ResolvedTheme;
63
+ /** Replaces the whole theme. */
64
+ setTheme: (theme: ThemeConfig) => void;
65
+ /** Deep-merges a partial theme into the current one. */
66
+ updateTheme: (patch: ThemeConfig) => void;
67
+ /** Returns to the preset. */
68
+ resetTheme: () => void;
69
+ /** True when nothing differs from the preset, so no tokens are being written. */
70
+ isDefault: boolean;
71
+ /** The resolved theme as a `:root { … }` CSS block. */
72
+ toCss: () => string;
73
+ }
74
+ interface ThemeProviderProps {
75
+ children: React__default.ReactNode;
76
+ /**
77
+ * Controlled theme. Pair with `onThemeChange` and own persistence yourself -
78
+ * this is the mode to use when the theme comes from a user record on your
79
+ * server.
80
+ */
81
+ theme?: ThemeConfig;
82
+ /** Initial theme for uncontrolled usage. Ignored when `theme` is supplied. */
83
+ defaultTheme?: ThemeConfig;
84
+ /** Fires whenever the theme changes, in both controlled and uncontrolled mode. */
85
+ onThemeChange?: (theme: ThemeConfig) => void;
86
+ }
87
+
88
+ export type { ResolvedTheme as R, ThemeColorKey as T, ThemeColorValue as a, ThemeColors as b, ThemeConfig as c, ThemeContextValue as d, ThemeFontOption as e, ThemeProviderProps as f, ThemeTypography as g };