# Styling SvSeeds components provide a flexible styling system. This document explains the two primary styling methods and their implementation details. ## Overview ### String-based Styling Used when a string is specified for the `styling` prop, or when no value is provided. The specified class name is automatically applied to each part of the component. When no value is provided, the default component name is used. ### Object-based Styling Used when an object of a specific type is specified for the `styling` prop. This allows you to specify classes individually for each part of the component. Use this approach when working with TailwindCSS. ## String-based Styling In String-based Styling, the specified class name is applied in combination with each component part and variant. ### Example **Basic Usage** ```svelte ``` Generated HTML (class attribute excerpt): ```html ``` **Conditional Styling Based on Variant** ```svelte Hello ``` Generated HTML (class attribute excerpt): ```html ``` ## Object-based Styling In Object-based Styling, you can specify classes individually for each part of the component. For detailed object specifications, see [Object for Styling](#object-for-styling). ### Example **Basic Usage** ```svelte ``` Generated HTML (class attribute excerpt): ```html ``` **Conditional Styling Based on Variant** ```svelte Hello ``` Generated HTML (class attribute excerpt): ```html ``` ## Part Name System To ensure styling flexibility, all elements within components are assigned part names. ### Standard Part Names The following part names are defined by default: - `whole` - Overall component wrapper - `top` - Top region - `middle` - Middle region - `bottom` - Bottom region - `left` - Left area - `main` - Main content area - `right` - Right area - `label` - Label part - `aux` - Auxiliary part - `extra` - Additional part Since part names are defined as `string` type, custom components can also define custom part names. For the specific part names used by each component, refer to the individual component documentation. ## Variant System Component styling adapts based on its current appearance variant. ### Standard Variants The following variant names are defined by default: - `neutral` - Default variant - `active` - Active variant (such as selected state) - `inactive` - Inactive variant (also used for invalid/error states) Since variants are defined as `string` type, custom variants can also be used. ### Variant Behavior Components fall into two categories: those that automatically manage their variant based on user interaction, and those that maintain a fixed variant. For detailed variant behavior of each component, refer to the individual component documentation. #### Auto-Managing Components Components like `Toggle` and `TextField` automatically update their variant in response to user interactions. For these components, the `variant` prop serves as an override for the default neutral variant. #### Non-Auto-Managing Components For these components, the `variant` prop directly sets the component's variant without any automatic changes. ## Theme-based Style Switching Use CSS `prefers-color-scheme` to configure theme switching. For theme toggle functionality, refer to the [feature details](/docs/dark-toggle#feature-details) of the `DarkToggle` component. ## Animation & CSS Custom Properties SvSeeds uses a shared convention for motion values and component-owned CSS custom properties. These props are set directly on the component, or on the child component that owns the motion, and CSS-expressible animation remains in caller CSS keyed off the existing part and variant classes. `cssvar` maps a component-defined key to the CSS custom property name that component reads or writes. This lets you wire component internals to your own design tokens without changing the component's styling classes. ```svelte ``` `duration` sets time-based motion in milliseconds. Components that expose CSS-driven timing publish the reduced-motion-aware value through the canonical `--svs-duration` custom property. ```svelte Content ``` `transition` is an escape hatch for JS-measured motion that CSS cannot express, such as auto-height or directional transitions. It accepts a `{ fn, params }` object; for example, Disclosure defaults to `slide` but can be swapped. ```svelte Content ``` ## Object for Styling ### Object Type The object used in object-based styling is defined as the `SVSClass` type. ```svelte ``` ### Advanced Class Value Specification Property values can use clsx library-compatible values that are valid for [Svelte's class attribute](https://svelte.dev/docs/svelte/class) specification, as well as strings. ```ts const styling = { whole: ["whole-class", "class1", "class2"], main: { base: "main-class", neutral: { foo, bar: !foo }, }, }; ``` Do not confuse the two object shapes. A clsx condition object such as `{ foo, bar: !foo }` has boolean values and is one class value, used as the value of a single variant. The variant map, the object keyed by `base`, `neutral`, `active`, and so on, takes a `ClassValue` at each key; its values are never booleans. ### Fallback Variant Style If the current variant is not found in the object, the style defined for `neutral` will be used as a fallback. ```svelte Hello ``` Generated HTML (class attribute excerpt): ```html ``` ### Shorthand Notation You can omit the variant and specify class attribute values directly for part names: ```ts const styling = { whole: "whole-class", main: "main-class", }; ``` This is interpreted as: ```ts const styling = { whole: { base: "whole-class", }, main: { base: "main-class", }, }; ``` #### Important Note Shorthand notation also accepts clsx condition objects directly. An object whose values are booleans, such as `{ foo, bar: !foo }`, is recognized as a class value and used as-is; no array wrapping is required: ```ts const styling = { whole: { foo, bar: !foo }, }; ``` This is interpreted as: ```ts const styling = { whole: { base: { foo, bar: !foo }, }, }; ``` An object is treated as a variant map only when none of its values are booleans, for example `{ base: "base-class", active: "active-class" }`. Wrapping the object in an array still works and is an explicit way to force a plain class value: ```ts const styling = { whole: [{ foo, bar: !foo }], }; ```