Styling
Destyler are unstyled and compatible with any styling solution giving you complete control over styling.
Styling overview
Functional styles
You are in control of all aspects of styling, including functional styles. For example, by default, a Dialog Overlay won’t cover the entire viewport. You’re responsible for adding those styles, plus any presentation styles.
Classes
All components accept class
attributes, just like normal component.
This class will be passed through to the DOM element. You can use it in CSS as expected.
Data attributes
When components are stateful, their state will be exposed in a data-state
attribute.
For example, when an Collapse Item is opened, it includes a data-state="open"
attribute.
Styling with CSS
Styling a part
You can style a component part by targeting the class that you provide.
<script setup lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/vue'import { computed, useId } from 'vue'
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = computed(() => collapse.connect(state.value, send, normalizeProps),)</script>
<template> <div v-bind="api.getRootProps()" > <div class="collapse-item" v-bind="api.getItemProps({ value: 'item-1' })" /> <!-- ... --> </div></template>
<style scoped>.collapse-item { /* ... */}</style>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/react'import { useId } from 'react'import './App.css'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = collapse.connect(state, send, normalizeProps)
return ( <> <div {...api.getRootProps()} > <div className="collapse-item" {...api.getItemProps({ value: item.title })} > </div> {/* ... */} </div> </> )}
.collapse-item { /* ... */}
<script lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/svelte'
const id = $props.id()
const [state, send] = useMachine(collapse.machine({ id }))
const api = $derived(collapse.connect(state, send, normalizeProps))</script>
<div {...api.getRootProps()}> <div class="collapse-item" {...api.getItemProps({ value: item.title })} > </div> <!-- ... --></div>
<style> .collapse-item { /* ... */ }</style>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/solid'import { createMemo, createUniqueId } from 'solid-js'import './App.css'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: createUniqueId() }))
const api = createMemo(() => collapse.connect(state, send, normalizeProps))
return ( <> <div {...api().getRootProps()} > <div class="collapse-item" {...api().getItemProps({ value: item.title })} > </div> {/* ... */} </div> </> )}
.collapse-item { /* ... */}
Styling a state
You can style a component state by targeting its data-state
attribute.
.collapse-item { border-bottom: 1px solid gainsboro;}
.collapse-item[data-state="open"] { border-bottom-width: 2px;}
Styling with Atomic CSS
Styling a part
You can style a component part by targeting the class
.
<script setup lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/vue'import { computed, useId } from 'vue'
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = computed(() => collapse.connect(state.value, send, normalizeProps),)</script>
<template> <div v-bind="api.getRootProps()" > <div class="border border-gray-400 rounded-2xl" v-bind="api.getItemProps({ value: 'item-1' })" /> <!-- ... --> </div></template>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/react'import { useId } from 'react'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = collapse.connect(state, send, normalizeProps)
return ( <> <div {...api.getRootProps()} > <div class="border border-gray-400 rounded-2xl" {...api.getItemProps({ value: item.title })} > </div> {/* ... */} </div> </> )}
<script lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/svelte'
const id = $props.id()
const [state, send] = useMachine(collapse.machine({ id }))
const api = $derived(collapse.connect(state, send, normalizeProps))</script>
<div {...api.getRootProps()}> <div class="border border-gray-400 rounded-2xl" {...api.getItemProps({ value: item.title })} > </div> <!-- ... --></div>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/solid'import { createMemo, createUniqueId } from 'solid-js'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: createUniqueId() }))
const api = createMemo(() => collapse.connect(state, send, normalizeProps))
return ( <> <div {...api().getRootProps()} > <div class="border border-gray-400 rounded-2xl" {...api().getItemProps({ value: item.title })} > </div> {/* ... */} </div> </> )}
Styling a state
With Tailwind CSS’s powerful variant selector, you can style a component state by targeting its data-state
attribute.
<script setup lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/vue'import { computed, useId } from 'vue'
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = computed(() => collapse.connect(state.value, send, normalizeProps),)</script>
<template> <div v-bind="api.getRootProps()" > <div class="border border-gray-400 rounded-2xl data-[state=open]:border-b-2 data-[state=open]:border-gray-800" v-bind="api.getItemProps({ value: 'item-1' })" /> <!-- ... --> </div></template>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/react'import { useId } from 'react'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = collapse.connect(state, send, normalizeProps)
return ( <> <div {...api.getRootProps()} > <div class="border border-gray-400 rounded-2xl data-[state=open]:border-b-2 data-[state=open]:border-gray-800" {...api.getItemProps({ value: item.title })} > </div> </div> </> )}
<script lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/svelte'
const id = $props.id()
const [state, send] = useMachine(collapse.machine({ id }))
const api = $derived(collapse.connect(state, send, normalizeProps))</script>
<div {...api.getRootProps()}> <div class="border border-gray-400 rounded-2xl data-[state=open]:border-b-2 data-[state=open]:border-gray-800" {...api.getItemProps({ value: item.title })} > </div> <!-- ... --></div>
import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/solid'import { createMemo, createUniqueId } from 'solid-js'
export default function CollapsePage() {
const [state, send] = useMachine(collapse.machine({ id: createUniqueId() }))
const api = createMemo(() => collapse.connect(state, send, normalizeProps))
return ( <> <div {...api().getRootProps()} > <div class="border border-gray-400 rounded-2xl data-[state=open]:border-b-2 data-[state=open]:border-gray-800" {...api().getItemProps({ value: item.title })} > </div> {/* ... */} </div> </> )}
Summary
Destyler were designed to encapsulate accessibility concerns and other complex functionalities, while ensuring you retain complete control over styling.
For convenience, stateful components include a data-state attribute.