selectors
This commit is contained in:
parent
8a4408fe22
commit
718dc3b73d
49
README.md
49
README.md
|
|
@ -111,6 +111,55 @@ console.log(<Profile pic={user.pic} bio={user.bio} />)
|
||||||
console.log(<Profile size="small" pic={user.pic} bio={user.bio} />)
|
console.log(<Profile size="small" pic={user.pic} bio={user.bio} />)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### selectors
|
||||||
|
|
||||||
|
Use `selectors` to write custom CSS selectors. Reference the current
|
||||||
|
element with `&` and other parts with `@PartName`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const Checkbox = define("Checkbox", {
|
||||||
|
parts: {
|
||||||
|
Input: {
|
||||||
|
base: "input[type=checkbox]",
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
Label: {
|
||||||
|
base: "label",
|
||||||
|
padding: 10,
|
||||||
|
cursor: "pointer",
|
||||||
|
color: "gray",
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
// style Label when Input is checked
|
||||||
|
"@Input:checked + &": {
|
||||||
|
color: "green",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
// style Label when Input is disabled
|
||||||
|
"@Input:disabled + &": {
|
||||||
|
opacity: 0.5,
|
||||||
|
cursor: "not-allowed",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
render({ props, parts: { Root, Input, Label } }) {
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<Label>
|
||||||
|
<Input checked={props.checked} />
|
||||||
|
{props.label}
|
||||||
|
</Label>
|
||||||
|
</Root>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
<Checkbox label="Agree to terms" checked />
|
||||||
|
```
|
||||||
|
|
||||||
## themes
|
## themes
|
||||||
|
|
||||||
built-in support for CSS variables with full type safety:
|
built-in support for CSS variables with full type safety:
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ const UserProfile = define('UserProfile', {
|
||||||
maxWidth: 600,
|
maxWidth: 600,
|
||||||
margin: "0 auto",
|
margin: "0 auto",
|
||||||
background: theme('colors-bgElevated'),
|
background: theme('colors-bgElevated'),
|
||||||
border: `1px solid ${theme('colors-border')}`,
|
|
||||||
borderRadius: theme('radius-md'),
|
borderRadius: theme('radius-md'),
|
||||||
|
border: theme('colors-accent'),
|
||||||
|
|
||||||
parts: {
|
parts: {
|
||||||
Header: {
|
Header: {
|
||||||
|
|
|
||||||
|
|
@ -35,16 +35,9 @@ const ThemePicker = define('SpaThemePicker', {
|
||||||
},
|
},
|
||||||
|
|
||||||
render({ parts: { Root, Select } }) {
|
render({ parts: { Root, Select } }) {
|
||||||
const handleChange = (e: Event) => {
|
|
||||||
const target = e.target as HTMLSelectElement
|
|
||||||
const themeName = target.value
|
|
||||||
document.body.setAttribute('data-theme', themeName)
|
|
||||||
localStorage.setItem('theme', themeName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Root>
|
<Root>
|
||||||
<Select id="theme-select" onchange={handleChange}>
|
<Select id="theme-select" onChange={themeChanged}>
|
||||||
<option value="dark">Dark</option>
|
<option value="dark">Dark</option>
|
||||||
<option value="light">Light</option>
|
<option value="light">Light</option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
@ -53,6 +46,13 @@ const ThemePicker = define('SpaThemePicker', {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function themeChanged(e: Event) {
|
||||||
|
const target = e.target as HTMLSelectElement
|
||||||
|
const themeName = target.value
|
||||||
|
document.body.setAttribute('data-theme', themeName)
|
||||||
|
localStorage.setItem('theme', themeName)
|
||||||
|
}
|
||||||
|
|
||||||
export const Main = define('SpaMain', {
|
export const Main = define('SpaMain', {
|
||||||
base: 'div',
|
base: 'div',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,12 @@ export function createThemedVar<T extends Record<string, any>>(_themes: T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simplified API: register multiple themes and get typed themeVar in one call
|
// Simplified API: register multiple themes and get typed themeVar in one call
|
||||||
export function createThemes<
|
type Theme = Record<string, string | number>
|
||||||
T extends Record<string, Record<string, string | number>>
|
export function createThemes<T extends Record<string, Theme>>(themes: T) {
|
||||||
>(themes: T) {
|
const registeredThemes = {} as T
|
||||||
const registeredThemes: Record<string, Record<string, string>> = {}
|
|
||||||
|
|
||||||
for (const [name, values] of Object.entries(themes)) {
|
for (const [name, values] of Object.entries(themes)) {
|
||||||
registeredThemes[name] = createTheme(name, values)
|
(registeredThemes as any)[name] = createTheme(name, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
return createThemedVar(registeredThemes)
|
return createThemedVar(registeredThemes)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user