PettyUI/.firecrawl/corvu-dynamic.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

112 lines
5.4 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.

# Dynamic Components
All primitive components that render a DOM element are dynamic, which means that you can modify the element or the component they should render as.
## Native elements [Section titled Native elements](https://corvu.dev/docs/dynamic-components/\#native-elements)
In most cases, you shouldnt need to change the DOM element that the primitive component renders. corvu has sensible defaults for all components. But there are cases where it makes sense to change them. An example would be the `Tooltip` trigger which renders as a `button` element. You may want to render a tooltip on a link (`a` tag) instead. To do this, you have to specify the `as` property on the trigger component:
```
<Tooltip.Trigger as="a" href="https://corvu.dev">
corvu.dev
</Tooltip.Trigger>
```
## Solid components [Section titled Solid components](https://corvu.dev/docs/dynamic-components/\#solid-components)
A much more common use case is to render a primitive component as a custom Solid component. This is useful to apply default styling or to add additional functionality.
For example, you might have your own, custom-styled button component and want to use it as a trigger for a dialog:
```
import {
ComponentProps,
splitProps,
} from 'solid-js'
import Dialog from '@corvu/dialog'
const CustomButton = (
props: ComponentProps<'button'> & { variant: 'fill' | 'outline' },
) => {
const [local, rest] = splitProps(props, ['variant'])
// Apply your custom styling here
return <button class={local.variant} {...rest} />
}
const DialogTrigger = () => (
<Dialog.Trigger as={CustomButton} variant="outline">
Open
</Dialog.Trigger>
)
```
Props not belonging to the primitive component will be passed through to your custom component. In this case, the `variant` prop is passed to the `CustomButton` component.
> ❗ To ensure functionality and accessibility, your component needs to spread the received props onto your element. Otherwise, corvu cant define props on the element and things will break.
## Component types [Section titled Component types](https://corvu.dev/docs/dynamic-components/\#component-types)
corvus dynamic components have a flexible type system. This allows library developers or users who want to create their own components based on corvus primitives to have a great developer experience.
Every dynamic component exposes 4 types.
For example, the `<Dialog.Trigger>` component exports the types `DialogTriggerCorvuProps`, `DialogTriggerSharedElementProps<T>`, `DialogTriggerElementProps` and `DialogTriggerProps<T>`.
Lets have a look at the types:
### CorvuProps [Section titled CorvuProps](https://corvu.dev/docs/dynamic-components/\#corvuprops)
`CorvuProps` contains all props that are specific to the primitive component and are not passed through to the rendered element. They are consumed by corvu. For example, the [`<Resizable.Handle />`](https://corvu.dev/docs/primitives/resizable/#Panel) has props like `minSize` or `collapsible`.
### SharedElementProps<T extends ValidComponent> [Section titled SharedElementProps<T extends ValidComponent>](https://corvu.dev/docs/dynamic-components/\#sharedelementpropst-extends-validcomponent)
`SharedElementProps` includes all props that get defined by corvu on the rendered element **but** can be overridden by the user. This usually includes the `ref` or `style` properties. The generic is used to properly type `ref` and event listeners.
### ElementProps [Section titled ElementProps](https://corvu.dev/docs/dynamic-components/\#elementprops)
`ElementProps` element props inherits all `SharedElementProps` and additionally includes all props that are set by corvu and cant be overridden by the user. This includes for example accessibility props like `aria-*`, `role` and `data-*`.
### Props<T extends ValidComponent> [Section titled Props<T extends ValidComponent>](https://corvu.dev/docs/dynamic-components/\#propst-extends-validcomponent)
This is the type that defines what props that corvu expects from the user. Its equal to `CorvuProps & Partial<SharedElementProps>`.
### DynamicProps [Section titled DynamicProps](https://corvu.dev/docs/dynamic-components/\#dynamicprops)
`DynamicProps` is a helper type that allows you to expose the dynamic aspect of corvu components from your custom component. Lets look at an example:
```
import {
type ValidComponent,
ComponentProps,
splitProps,
} from 'solid-js'
import Dialog, { type TriggerProps, type DynamicProps } from '@corvu/dialog'
// Define your custom props, including `TriggerProps` from corvu
export type CustomDisclosureTriggerProps<T extends ValidComponent = 'button'> = TriggerProps<T> & {
variant: 'fill' | 'outline'
}
// The generic `T` allows the user to specify
// the element this component should render as
const CustomDialogTrigger = <T extends ValidComponent = 'button'>(
props: DynamicProps<T, CustomDisclosureTriggerProps<T>>,
) => {
const [local, rest] = splitProps(props as CustomDisclosureTriggerProps, [\
'variant',\
])
// Define the default dynamic type, in this case 'button'.
// This can be overridden by the user.
return <Dialog.Trigger as="button" class={local.variant} {...rest} />
}
```
If you dont want to expose the dynamic aspect of corvus components, you can define the generic explicitly:
```
const CustomDialogTrigger = (
props: DynamicProps<'button', CustomDisclosureTriggerProps<'button'>>,
) => {
```
Developed and designed by [Jasmin](https://github.com/GiyoMoon/)