Skip to content

Commit 9e6be53

Browse files
committed
refactor: overhaul CSS architecture — consumers own Tailwind setup
- Remove DatumProvider; consumers use ThemeProvider directly from @datum-cloud/datum-ui/theme for light/dark/system switching - Remove .theme-alpha class scoping; theme tokens now on :root/.dark - Remove tw-animate-css and tailwind-scrollbar-hide from package deps; consumers add these to their own CSS if needed - Keep @import 'tailwindcss' in root.css for build-time @theme/@apply processing; consumers also import tailwindcss so their custom utilities (e.g. h-14) are generated by their own build - Add ./styles export with "style" condition for PostCSS compatibility - Add CSS-only entry to tsdown config; rename plugin to stableCssName - Update storybook and docs apps to own their Tailwind setup - Update docs content (installation, theming, providers) and README
1 parent 17c117b commit 9e6be53

25 files changed

Lines changed: 359 additions & 463 deletions

File tree

README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,27 @@ pnpm add @datum-cloud/datum-ui
106106
bun add @datum-cloud/datum-ui
107107
```
108108

109-
Wrap your app with `DatumProvider` and import styles:
109+
Add datum-ui styles to your CSS file, after Tailwind:
110+
111+
```css
112+
@import 'tailwindcss';
113+
@import '@datum-cloud/datum-ui/styles';
114+
```
115+
116+
Wrap your app with `ThemeProvider` for light/dark/system switching:
110117

111118
```tsx
112-
import { DatumProvider, Button, Input } from '@datum-cloud/datum-ui'
113-
import '@datum-cloud/datum-ui/styles'
119+
import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
120+
import { Button, Input } from '@datum-cloud/datum-ui'
114121

115122
function App() {
116123
return (
117-
<DatumProvider>
124+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
118125
<Input placeholder="Enter your name" />
119126
<Button type="primary" theme="solid">
120127
Submit
121128
</Button>
122-
</DatumProvider>
129+
</ThemeProvider>
123130
)
124131
}
125132
```
@@ -128,13 +135,12 @@ function App() {
128135

129136
| Import Path | Description |
130137
|---|---|
131-
| `@datum-cloud/datum-ui` | All components, hooks, providers, and utilities |
132-
| `@datum-cloud/datum-ui/components` | Components only (base + features) |
133-
| `@datum-cloud/datum-ui/providers` | `DatumProvider` |
138+
| `@datum-cloud/datum-ui` | All components, hooks, and utilities |
139+
| `@datum-cloud/datum-ui/styles` | CSS (fonts, tokens, theme variables, component styles) |
140+
| `@datum-cloud/datum-ui/theme` | `ThemeProvider`, `useTheme` |
134141
| `@datum-cloud/datum-ui/hooks` | `useCopyToClipboard`, `useDebounce` |
135142
| `@datum-cloud/datum-ui/icons` | `CloseIcon`, `IconWrapper`, `SpinnerIcon` |
136143
| `@datum-cloud/datum-ui/utils` | `cn` (className merge utility) |
137-
| `@datum-cloud/datum-ui/styles` | Global CSS (fonts, tokens, component styles) |
138144

139145
### Peer Dependencies
140146

apps/docs/app/globals.css

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
2-
3-
/*
4-
* Explicit datum-ui CSS import required because Next.js `transpilePackages`
5-
* re-processes the package through its bundler, which strips the CSS
6-
* side-effect import from DatumProvider's built output.
7-
*
8-
* In normal consumer apps (without transpilePackages), DatumProvider
9-
* automatically loads all styles — no explicit import needed.
10-
*/
1+
@import 'tailwindcss';
112
@import '@datum-cloud/datum-ui/styles';
12-
133
@import 'fumadocs-ui/style.css';

apps/docs/components/providers.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
import type { ReactNode } from 'react'
44

5-
import { DatumProvider } from '@datum-cloud/datum-ui/provider'
5+
import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
66

77
export function Providers({ children }: { children: ReactNode }) {
8-
return <DatumProvider>{children}</DatumProvider>
8+
return (
9+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
10+
{children}
11+
</ThemeProvider>
12+
)
913
}

apps/docs/content/docs/components/themes.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
1919
export default function RootLayout({ children }) {
2020
return (
2121
<html>
22-
<body className="theme-alpha">
22+
<body>
2323
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
2424
{children}
2525
</ThemeProvider>

apps/docs/content/docs/index.mdx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,23 @@ Install the package:
1515
@datum-cloud/datum-ui
1616
```
1717

18-
Wrap your app with `DatumProvider`:
18+
Add styles to your CSS file and wrap your app with `ThemeProvider`:
19+
20+
```css
21+
/* app.css */
22+
@import 'tailwindcss';
23+
@import '@datum-cloud/datum-ui/styles';
24+
```
1925

2026
```tsx
21-
import { DatumProvider } from '@datum-cloud/datum-ui/provider'
27+
import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
2228

2329
export default function App({ children }) {
24-
return <DatumProvider>{children}</DatumProvider>
30+
return (
31+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
32+
{children}
33+
</ThemeProvider>
34+
)
2535
}
2636
```
2737

apps/docs/content/docs/installation.mdx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,31 @@ react react-dom tailwindcss lucide-react
1919

2020
Each component may have additional peer dependencies — check the component's doc page for the specific install command.
2121

22-
## Provider Setup
22+
## Styles Setup
2323

24-
Wrap your app with `DatumProvider` — it automatically loads all design tokens, theme variables, and component styles:
24+
Add the datum-ui styles import to your CSS file, after Tailwind:
25+
26+
```css
27+
/* app.css */
28+
@import 'tailwindcss';
29+
@import '@datum-cloud/datum-ui/styles';
30+
```
31+
32+
This loads all design tokens, theme variables, fonts, and component styles. datum-ui's tokens are registered with Tailwind via `@theme inline`, so utilities like `bg-primary` and `text-foreground` work automatically in your code.
33+
34+
## Theme Provider
35+
36+
Wrap your app with `ThemeProvider` for light/dark/system theme switching:
2537

2638
```tsx
27-
import { DatumProvider } from '@datum-cloud/datum-ui/provider'
39+
import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
2840

2941
export default function RootLayout({ children }) {
30-
return <DatumProvider>{children}</DatumProvider>
42+
return (
43+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
44+
{children}
45+
</ThemeProvider>
46+
)
3147
}
3248
```
3349

apps/docs/content/docs/providers.mdx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,47 @@
11
---
22
title: Providers
3-
description: Configure DatumProvider for theming, tooltips, and global context.
3+
description: Configure ThemeProvider for light/dark/system theme switching.
44
---
55

6-
## DatumProvider
6+
## ThemeProvider
77

8-
All datum-ui components must be wrapped in `DatumProvider`. It provides:
8+
Wrap your app with `ThemeProvider` for theme management:
99

10-
- **Theme management** with built-in theme provider (light/dark/system)
11-
- **Design tokens and styles** loaded automatically via CSS import
10+
- **Light/dark/system** mode switching
11+
- **System preference** detection
12+
- **localStorage** persistence
13+
- **CSS transition** control during theme switches
1214

1315
## Basic Usage
1416

1517
```tsx
16-
import { DatumProvider } from '@datum-cloud/datum-ui/provider'
18+
import { ThemeProvider } from '@datum-cloud/datum-ui/theme'
1719

1820
export default function RootLayout({ children }: { children: React.ReactNode }) {
1921
return (
2022
<html lang="en" suppressHydrationWarning>
2123
<body>
22-
<DatumProvider>{children}</DatumProvider>
24+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
25+
{children}
26+
</ThemeProvider>
2327
</body>
2428
</html>
2529
)
2630
}
2731
```
2832

33+
## Props
34+
35+
| Prop | Type | Default | Description |
36+
|------|------|---------|-------------|
37+
| `defaultTheme` | `'light' \| 'dark' \| 'system'` | `'system'` | Initial theme |
38+
| `storageKey` | `string` | `'theme'` | localStorage key for persistence |
39+
| `enableSystem` | `boolean` | `false` | Enable system preference detection |
40+
| `forcedTheme` | `Theme` || Force a specific theme |
41+
| `disableTransitionOnChange` | `boolean` | `false` | Disable CSS transitions during switches |
42+
| `attribute` | `'class' \| 'data-*'` | `'data-theme'` | HTML attribute for theme |
43+
| `nonce` | `string` || CSP nonce for inline script |
44+
2945
## Theme Hook
3046

3147
Access and control the current theme:

apps/docs/content/docs/theming.mdx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
---
22
title: Theming
3-
description: Customize datum-ui's visual appearance with design tokens and themes.
3+
description: Understand datum-ui's design token architecture and dark mode support.
44
---
55

66
## Design Token Architecture
77

8-
datum-ui uses a three-layer token system:
8+
datum-ui uses a two-layer token system:
99

1010
1. **Figma tokens** — raw color values exported from Figma (e.g., `--glacier-mist-700`, `--midnight-fjord`)
1111
2. **Purpose tokens** — semantic aliases used by components (e.g., `--background`, `--primary`, `--border`)
12-
3. **Theme classes** — map Figma tokens to purpose tokens (e.g., `.theme-alpha`)
1312

14-
## Applying a Theme
15-
16-
`DatumProvider` applies the theme class automatically on `<html>`. By default it uses the `alpha` theme style. You can change it via the `themeStyle` prop:
17-
18-
```tsx
19-
<DatumProvider themeStyle="alpha">{children}</DatumProvider>
20-
```
13+
Purpose tokens are defined on `:root` for light mode and overridden in `.dark` for dark mode. They are registered with Tailwind via `@theme inline`, so you can use utilities like `bg-primary`, `text-foreground`, `border-border` in your own code.
2114

2215
## Available Tokens
2316

@@ -43,7 +36,7 @@ datum-ui uses a three-layer token system:
4336

4437
## Dark Mode
4538

46-
datum-ui supports dark mode via the `.dark` class. `DatumProvider` handles theme switching with a built-in theme provider that supports system preference detection, localStorage persistence, and CSS transition control.
39+
datum-ui supports dark mode via the `.dark` class on `<html>`. Use `ThemeProvider` for automatic switching:
4740

4841
```tsx
4942
import { useTheme } from '@datum-cloud/datum-ui/theme'

apps/docs/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
},
4040
"devDependencies": {
4141
"@repo/config": "workspace:*",
42+
"@tailwindcss/postcss": "^4.2.1",
4243
"@types/leaflet": "^1.9.21",
4344
"@types/leaflet-draw": "^1.0.13",
4445
"@types/leaflet.fullscreen": "^5.2.0",
@@ -52,6 +53,7 @@
5253
"leaflet.markercluster": "^1.5.3",
5354
"react-leaflet": "^5.0.0",
5455
"react-leaflet-markercluster": "5.0.0-rc.0",
56+
"tailwindcss": "^4.2.1",
5557
"typescript": "^5.9",
5658
"zod": "^4.3.6"
5759
}

apps/docs/postcss.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
plugins: {
3+
'@tailwindcss/postcss': {},
4+
},
5+
}

0 commit comments

Comments
 (0)