PettyUI/.firecrawl/corvu-state.md
Mats Bosson db906fd85a Fix linting config and package fields
- Replace .eslintrc.cjs with eslint.config.mjs (ESLint 9 flat config)
  using direct eslint-plugin-solid + @typescript-eslint/parser approach
- Add @typescript-eslint/parser to root devDependencies
- Add main/module/types top-level fields to packages/core/package.json
- Add resolve.conditions to packages/core/vite.config.ts
- Create packages/core/tsconfig.test.json for test type-checking
- Remove empty paths:{} from packages/core/tsconfig.json
2026-03-29 02:35:57 +07:00

125 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# State
By default, all corvu primitives manage their state internally. This means that they handle their state themselves and you dont need to pass any props/state to them.
corvu aims to be very customizable and provides various ways to control a primitive or access internal state. Lets take a look at them. Well use the [Dialog](https://corvu.dev/docs/primitives/dialog/) primitive as an example, but the same applies to all other primitives.
## Controlled State [Section titled Controlled State](https://corvu.dev/docs/state/\#controlled-state)
The easiest way to control a primitives state is by passing your own defined state to its `Root` component. Most of the time, this consists of a getter and setter property like in this example, where we control the open state of a dialog:
```
import Dialog from '@corvu/dialog'
import { createSignal } from 'solid-js'
const MyDialog = () => {
const [open, setOpen] = createSignal(false)
return (
<Dialog open={open()} onOpenChange={setOpen}>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Dialog.Content>
<Dialog.Label>Label</Dialog.Label>
</Dialog.Content>
</Dialog>
)
}
```
This allows you to use the open state anywhere in your code and alter it freely. The dialog will open and close accordingly.
## Context [Section titled Context](https://corvu.dev/docs/state/\#context)
Its also possible to access the context of every primitive. This allows you to get the internal state of a primitive from anywhere in your code, as long as its under the `Root` component, where the context gets provided. Accessing the context of a dialog looks like this:
```
import Dialog from '@corvu/dialog'
import { createSignal } from 'solid-js'
const DialogRoot = () => {
return (
<Dialog>
<DialogContent />
</Dialog>
)
}
const DialogContent = () => {
const { open, setOpen } = Dialog.useContext()
return (
<>
<p>The dialog is {open() ? 'open' : 'closed'}</p>
<button onClick={() => setOpen(open => !open)}>
My own, custom trigger button
</button>
<Dialog.Content>
<Dialog.Label>Label</Dialog.Label>
</Dialog.Content>
</>
)
}
```
Every primitive provides different properties in its context, have a look at the API section of each primitive to see whats available.
## Children callbacks [Section titled Children callbacks](https://corvu.dev/docs/state/\#children-callbacks)
The `Root` component of every primitive (and in a few cases others) also accepts a function as its children. By doing this, we can pass the internal state to the children for you to access. An example of this looks like this:
```
import Dialog from '@corvu/dialog'
import { createSignal } from 'solid-js'
const MyDialog = () => {
return (
<Dialog>
{(props) => (
<>
<p>The dialog is {props.open() ? 'open' : 'closed'}</p>
<button onClick={() => props.setOpen(open => !open)}>
My own, custom trigger button
</button>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Dialog.Content>
<Dialog.Label>Label</Dialog.Label>
</Dialog.Content>
</>
)}
</Dialog>
)
}
```
Note that the props passed from the `Root` component include reactive getters. Make sure to access them in a reactive scope, like you would in any other Solid component.
## Keyed context [Section titled Keyed context](https://corvu.dev/docs/state/\#keyed-context)
There may be situations where you want to use nested instances of the same primitive. For example, multiple dialogs with multiple trigger buttons that are hard to separate in the template. For this case, corvu allows you to pass a `contextId` to every primitive component to tell which context to use.
Heres how two nested dialogs would look like:
```
<Dialog contextId="dialog-1">
<Dialog contextId="dialog-2">
<Dialog.Trigger contextId="dialog-1">Open Dialog 1</Dialog.Trigger>
<Dialog.Trigger contextId="dialog-2">Open Dialog 2</Dialog.Trigger>
<Dialog.Content contextId="dialog-1">
<Dialog.Label contextId="dialog-1">Dialog 1</Dialog.Label>
</Dialog.Content>
<Dialog.Content contextId="dialog-2">
<Dialog.Label contextId="dialog-2">Dialog 2</Dialog.Label>
</Dialog.Content>
</Dialog>
</Dialog>
```
When using keyed contexts, you can pass the same key to the `useContext()` function to access the context of the respective primitive.
```
const { open, setOpen } = Dialog.useContext('dialog-1')
```
Developed and designed by [Jasmin](https://github.com/GiyoMoon/)