@marcoschwartz/lite-ui 0.24.12 → 0.24.14

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 CHANGED
@@ -19,23 +19,21 @@ A lightweight, modern UI component library built with React, TypeScript, and Tai
19
19
  npm install @marcoschwartz/lite-ui
20
20
  ```
21
21
 
22
- ### Setup
22
+ ### Setup for Next.js (Required)
23
23
 
24
- 1. **Import the CSS** in your app's entry point:
24
+ > ⚠️ **Important:** You must include `ColorSchemeScript` in your layout to prevent dark mode flashing (FOUC).
25
25
 
26
26
  ```tsx
27
- // app/layout.tsx (Next.js) or main.tsx (Vite)
27
+ // app/layout.tsx
28
+ import { ThemeProvider, ColorSchemeScript } from '@marcoschwartz/lite-ui';
28
29
  import '@marcoschwartz/lite-ui/styles.css';
29
- ```
30
-
31
- 2. **Wrap your app with ThemeProvider** (recommended):
32
-
33
- ```tsx
34
- import { ThemeProvider } from '@marcoschwartz/lite-ui';
35
30
 
36
31
  export default function RootLayout({ children }) {
37
32
  return (
38
- <html lang="en">
33
+ <html lang="en" suppressHydrationWarning>
34
+ <head>
35
+ <ColorSchemeScript defaultColorMode="system" />
36
+ </head>
39
37
  <body>
40
38
  <ThemeProvider defaultTheme="default" defaultColorMode="system">
41
39
  {children}
@@ -46,7 +44,36 @@ export default function RootLayout({ children }) {
46
44
  }
47
45
  ```
48
46
 
49
- 3. **Start using components:**
47
+ **Key points:**
48
+ - `ColorSchemeScript` must be in `<head>` - it prevents flash by setting colors before React hydrates
49
+ - `suppressHydrationWarning` on `<html>` is required to avoid React warnings
50
+ - `defaultColorMode` should match between `ColorSchemeScript` and `ThemeProvider`
51
+
52
+ ### Setup for Vite/Other React Apps
53
+
54
+ ```tsx
55
+ // main.tsx
56
+ import '@marcoschwartz/lite-ui/styles.css';
57
+ import { ThemeProvider } from '@marcoschwartz/lite-ui';
58
+
59
+ ReactDOM.createRoot(document.getElementById('root')!).render(
60
+ <ThemeProvider defaultTheme="default" defaultColorMode="system">
61
+ <App />
62
+ </ThemeProvider>
63
+ );
64
+ ```
65
+
66
+ For Vite apps, add the theme script to your `index.html`:
67
+
68
+ ```html
69
+ <head>
70
+ <script>
71
+ (function(){try{var d=document.documentElement,c=localStorage.getItem('lite-ui-color-mode')||'system',r=c;if(c==='system'||!c)r=matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light';d.setAttribute('data-color-mode',r);d.style.colorScheme=r;if(r==='dark'){d.classList.add('dark');d.style.backgroundColor='hsl(0,0%,3.9%)';d.style.color='hsl(0,0%,98%)'}else{d.classList.remove('dark');d.style.backgroundColor='hsl(0,0%,100%)';d.style.color='hsl(0,0%,3.9%)'}}catch(e){}})();
72
+ </script>
73
+ </head>
74
+ ```
75
+
76
+ ### Start using components:
50
77
 
51
78
  ```tsx
52
79
  import { Button, Card, TextInput } from '@marcoschwartz/lite-ui';
@@ -99,7 +126,29 @@ export default function Page() {
99
126
 
100
127
  ## 🌙 Dark Mode
101
128
 
102
- Lite UI includes built-in dark mode support with three color modes:
129
+ Lite UI includes built-in dark mode support with three color modes.
130
+
131
+ ### Preventing Flash (FOUC)
132
+
133
+ To prevent the flash of wrong colors on page load, you **must** use `ColorSchemeScript`:
134
+
135
+ ```tsx
136
+ // app/layout.tsx
137
+ import { ColorSchemeScript, ThemeProvider } from '@marcoschwartz/lite-ui';
138
+
139
+ <html lang="en" suppressHydrationWarning>
140
+ <head>
141
+ <ColorSchemeScript defaultColorMode="system" />
142
+ </head>
143
+ <body>
144
+ <ThemeProvider defaultColorMode="system">
145
+ {children}
146
+ </ThemeProvider>
147
+ </body>
148
+ </html>
149
+ ```
150
+
151
+ ### Toggling Dark Mode
103
152
 
104
153
  ```tsx
105
154
  import { useTheme } from '@marcoschwartz/lite-ui';
@@ -117,6 +166,29 @@ function ThemeToggle() {
117
166
  }
118
167
  ```
119
168
 
169
+ ## ⬆️ Upgrading from v0.24.7 or earlier
170
+
171
+ If you're upgrading from an earlier version, update your `layout.tsx`:
172
+
173
+ ```diff
174
+ - import { ThemeProvider, themeScript } from '@marcoschwartz/lite-ui';
175
+ + import { ThemeProvider, ColorSchemeScript } from '@marcoschwartz/lite-ui';
176
+
177
+ <html lang="en" suppressHydrationWarning>
178
+ <head>
179
+ - <script
180
+ - dangerouslySetInnerHTML={{ __html: themeScript }}
181
+ - suppressHydrationWarning
182
+ - />
183
+ + <ColorSchemeScript defaultColorMode="system" />
184
+ </head>
185
+ ```
186
+
187
+ The new `ColorSchemeScript` component:
188
+ - Sets CSS custom properties inline (prevents flash even if CSS loads slowly)
189
+ - Cleaner API than the old `themeScript` string
190
+ - Supports `nonce` prop for Content Security Policy
191
+
120
192
  ## 🎭 Theming
121
193
 
122
194
  Switch between built-in themes or create your own:
package/dist/index.d.mts CHANGED
@@ -288,8 +288,9 @@ interface TableProps<T = any> {
288
288
  hoverable?: boolean;
289
289
  className?: string;
290
290
  responsive?: boolean;
291
+ onRowClick?: (row: T, index: number) => void;
291
292
  }
292
- declare function Table<T extends Record<string, any>>({ columns, data, keyField, striped, hoverable, className, responsive, }: TableProps<T>): react_jsx_runtime.JSX.Element;
293
+ declare function Table<T extends Record<string, any>>({ columns, data, keyField, striped, hoverable, className, responsive, onRowClick, }: TableProps<T>): react_jsx_runtime.JSX.Element;
293
294
 
294
295
  interface PaginationProps {
295
296
  currentPage: number;
package/dist/index.d.ts CHANGED
@@ -288,8 +288,9 @@ interface TableProps<T = any> {
288
288
  hoverable?: boolean;
289
289
  className?: string;
290
290
  responsive?: boolean;
291
+ onRowClick?: (row: T, index: number) => void;
291
292
  }
292
- declare function Table<T extends Record<string, any>>({ columns, data, keyField, striped, hoverable, className, responsive, }: TableProps<T>): react_jsx_runtime.JSX.Element;
293
+ declare function Table<T extends Record<string, any>>({ columns, data, keyField, striped, hoverable, className, responsive, onRowClick, }: TableProps<T>): react_jsx_runtime.JSX.Element;
293
294
 
294
295
  interface PaginationProps {
295
296
  currentPage: number;
package/dist/index.js CHANGED
@@ -2343,7 +2343,8 @@ function Table({
2343
2343
  striped = false,
2344
2344
  hoverable = true,
2345
2345
  className = "",
2346
- responsive = true
2346
+ responsive = true,
2347
+ onRowClick
2347
2348
  }) {
2348
2349
  return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className, children: [
2349
2350
  /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: `${responsive ? "hidden md:block" : ""} overflow-x-auto`, children: [
@@ -2363,12 +2364,14 @@ function Table({
2363
2364
  /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("tbody", { className: "bg-[hsl(var(--card))] divide-y divide-[hsl(var(--border))]", children: data.map((row, rowIndex) => {
2364
2365
  const rowClasses = [
2365
2366
  striped && rowIndex % 2 === 1 ? "bg-[hsl(var(--muted))]/50" : "",
2366
- hoverable ? "hover:bg-[hsl(var(--muted))] transition-colors" : ""
2367
+ hoverable ? "hover:bg-[hsl(var(--muted))] transition-colors" : "",
2368
+ onRowClick ? "cursor-pointer" : ""
2367
2369
  ].filter(Boolean).join(" ");
2368
2370
  return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
2369
2371
  "tr",
2370
2372
  {
2371
2373
  className: rowClasses,
2374
+ onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
2372
2375
  children: columns.map((column, colIndex) => {
2373
2376
  const isLast = colIndex === columns.length - 1;
2374
2377
  return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
@@ -2392,6 +2395,7 @@ function Table({
2392
2395
  const cardClasses = [
2393
2396
  "bg-[hsl(var(--card))] border border-[hsl(var(--border))] rounded-[--radius] p-4 shadow-sm",
2394
2397
  hoverable ? "hover:shadow-md transition-shadow" : "",
2398
+ onRowClick ? "cursor-pointer" : "",
2395
2399
  "relative isolate"
2396
2400
  // Ensure cards are isolated layers
2397
2401
  ].filter(Boolean).join(" ");
@@ -2399,6 +2403,7 @@ function Table({
2399
2403
  "div",
2400
2404
  {
2401
2405
  className: cardClasses,
2406
+ onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
2402
2407
  children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
2403
2408
  "div",
2404
2409
  {