themes
This commit is contained in:
parent
855112ac82
commit
dafbce762b
105
README.md
105
README.md
|
|
@ -30,6 +30,24 @@ self-contained TSX components out of discrete parts.
|
||||||
|
|
||||||
## examples
|
## examples
|
||||||
|
|
||||||
|
### styles
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { define } from "forge"
|
||||||
|
|
||||||
|
export const Button = define("button", {
|
||||||
|
base: "button",
|
||||||
|
|
||||||
|
padding: 20,
|
||||||
|
background: "blue",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
<Button>Click me</Button>
|
||||||
|
```
|
||||||
|
|
||||||
|
### variants
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { define } from "forge"
|
import { define } from "forge"
|
||||||
|
|
||||||
|
|
@ -51,23 +69,27 @@ export const Button = define("button", {
|
||||||
<Button>Click me</Button>
|
<Button>Click me</Button>
|
||||||
<Button status="danger">Click me carefully</Button>
|
<Button status="danger">Click me carefully</Button>
|
||||||
<Button status="warning">Click me?</Button>
|
<Button status="warning">Click me?</Button>
|
||||||
|
```
|
||||||
|
|
||||||
|
### parts + `render()`
|
||||||
|
|
||||||
|
```typescript
|
||||||
export const Profile = define("div", {
|
export const Profile = define("div", {
|
||||||
padding: 50,
|
padding: 50,
|
||||||
background: "red",
|
background: "red",
|
||||||
|
|
||||||
parts: {
|
parts: {
|
||||||
Header: { display: "flex" },
|
Header: { display: "flex" },
|
||||||
Avatar: { base: 'img', width: 50 },
|
Avatar: { base: "img", width: 50 },
|
||||||
Bio: { color: "gray" },
|
Bio: { color: "gray" },
|
||||||
},
|
},
|
||||||
|
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
small: {
|
small: {
|
||||||
parts: { Avatar: { width: 20 }}
|
parts: { Avatar: { width: 20 } },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
render({ props, parts: { Root, Header, Avatar, Bio } }) {
|
render({ props, parts: { Root, Header, Avatar, Bio } }) {
|
||||||
|
|
@ -83,9 +105,80 @@ export const Profile = define("div", {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Usage:
|
// Usage:
|
||||||
import { Profile } from './whatever'
|
import { Profile } from "./whatever"
|
||||||
|
|
||||||
<Profile pic={user.pic} bio={user.bio} />
|
console.log(<Profile pic={user.pic} bio={user.bio} />)
|
||||||
|
console.log(<Profile size="small" pic={user.pic} bio={user.bio} />)
|
||||||
|
```
|
||||||
|
|
||||||
|
## themes
|
||||||
|
|
||||||
|
built-in support for CSS variables with full type safety:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// themes.tsx - Define your themes
|
||||||
|
import { createThemes } from "forge"
|
||||||
|
|
||||||
|
export const theme = createThemes({
|
||||||
|
dark: {
|
||||||
|
bgColor: "#0a0a0a",
|
||||||
|
fgColor: "#00ff00",
|
||||||
|
sm: 12,
|
||||||
|
lg: 24,
|
||||||
|
},
|
||||||
|
light: {
|
||||||
|
bgColor: "#f5f5f0",
|
||||||
|
fgColor: "#0a0a0a",
|
||||||
|
sm: 12,
|
||||||
|
lg: 24,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Use theme() in your components
|
||||||
|
import { define } from "forge"
|
||||||
|
import { theme } from "./themes"
|
||||||
|
|
||||||
|
const Button = define("Button", {
|
||||||
|
padding: theme("spacing-sm"),
|
||||||
|
background: theme("colors-bg"),
|
||||||
|
color: theme("colors-fg"),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Theme switching is done via the `data-theme` attribute:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// Toggle between themes
|
||||||
|
document.body.setAttribute("data-theme", "dark")
|
||||||
|
document.body.setAttribute("data-theme", "light")
|
||||||
|
```
|
||||||
|
|
||||||
|
The `theme()` function is fully typed based on your theme keys, giving
|
||||||
|
you autocomplete and type checking throughout your codebase.
|
||||||
|
|
||||||
|
## scopes
|
||||||
|
|
||||||
|
Sometimes you want your parts named things like ButtonRow, ButtonCell,
|
||||||
|
ButtonTable, etc, but all those Button's are repetitive:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const { define } = createScope("Button")
|
||||||
|
|
||||||
|
// css class becomes "Button"
|
||||||
|
const Button = define("Root", {
|
||||||
|
// becomes "Button"
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
|
||||||
|
// css class becomes "ButtonRow"
|
||||||
|
const ButtonRow = define("Row", {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
|
||||||
|
// css class becomes "ButtonContainer"
|
||||||
|
const ButtonContainer = define("Container", {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## see it
|
## see it
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { createTheme, createThemedVar } from '../../src'
|
import { createThemes } from '../../src'
|
||||||
import darkTheme from './darkTheme'
|
import darkTheme from './darkTheme'
|
||||||
import lightTheme from './lightTheme'
|
import lightTheme from './lightTheme'
|
||||||
|
|
||||||
// Register themes and get typed keys back
|
// Register themes and get a typed theme function in one step
|
||||||
const dark = createTheme('dark', darkTheme)
|
export const theme = createThemes({
|
||||||
const light = createTheme('light', lightTheme)
|
dark: darkTheme,
|
||||||
|
light: lightTheme
|
||||||
// Create a typed themeVar function
|
})
|
||||||
export const theme = createThemedVar({ dark, light })
|
|
||||||
|
|
@ -50,6 +50,19 @@ export function createThemedVar<T extends Record<string, any>>(_themes: T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplified API: register multiple themes and get typed themeVar in one call
|
||||||
|
export function createThemes<
|
||||||
|
T extends Record<string, Record<string, string | number>>
|
||||||
|
>(themes: T) {
|
||||||
|
const registeredThemes: Record<string, Record<string, string>> = {}
|
||||||
|
|
||||||
|
for (const [name, values] of Object.entries(themes)) {
|
||||||
|
registeredThemes[name] = createTheme(name, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
return createThemedVar(registeredThemes)
|
||||||
|
}
|
||||||
|
|
||||||
// Generic themeVar (untyped fallback)
|
// Generic themeVar (untyped fallback)
|
||||||
export function themeVar(name: string): string {
|
export function themeVar(name: string): string {
|
||||||
return `var(--theme-${name as string})`
|
return `var(--theme-${name as string})`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user