--- title: "Components Configuration" description: "Configure static and dynamic component classes in Shilp CSS. Learn generation patterns and usage." keywords: [ "component configuration", "static components", "dynamic generation", "config setup", ] --- # Components Components are **ready-to-use classes** generated by Shilp CSS. Unlike utilities (which are written inside `.css` files), components **expose predefined class names** that you can directly use in HTML. Example: ```html title="Component classes usage"
...
...

...

``` Components can be **static** or **generated dynamically**. ---
## Why Components Exist Intents and Mixins are great for writing styles inside CSS. But, sometimes you need classes that should exist automatically. Example: `.container` A container usually depends on breakpoints. If a user changes breakpoints inside `shilpConfig.theme.screens`, the container component should update automatically. Instead of manually writing media queries, Shilp CSS generates the component. This keeps components **in sync with the theme configuration**. These are reusable patterns that are easier to expose as classes.
## What Is a Component? A component is simply a **regular CSS class**. It is a named collection of CSS properties that can be used directly in HTML. Example: ```css title="Base container class" .container { width: 100%; margin-left: auto; margin-right: auto; padding-left: 1rem; padding-right: 1rem; } ``` Shilp CSS provides: - **Static components**: written in CSS - **Dynamic components**: generated with JavaScript `!important` flag (with `!` at end) is **not supported** at the component level. If needed, add it per property. You can also generate components using SCSS, but **JavaScript is recommended** for dynamic generation.
## Location There are two types of components. ### 1. Static Components Defined in `shilpcss/styles/components.css`. These are normal CSS classes. Example: ```css title="shilpcss/styles/components.css" /* @import "./components/screen-reader.css"; */ .screen-reader { ... } .screen-reader--none { ... } /* @import "./components/limit-lines.css"; */ .limit-lines { ... } ``` To know more, read [Components](/docs/default-styles/components) ### 2. Dynamic Components Defined in `shilpConfig.components`. Each root-level key is a **component name** and value is a **component config**. Example: ```js tilte="Component config example" const shilpConfig = { source: "react", components: { container: { ... }, }, }; export default shilpConfig; ``` This generates container component classes. Component name and actual generated class name can be different. There are no coupling. #### Where Dynamic Components Are Inserted During processing, generated components are appended to `shilpcss/styles/components.css`. Example file structure: ```css title="shilpcss/styles/components.css" /* static components */ .screen-reader { ... } .limit-lines { ... } /* import("shilpcss-dynamic-components"); */ ``` Shilp CSS detects this **exact comment string** `/* import("shilpcss-dynamic-components"); */` and replaces it with generated component classes during processing. In other words, static and dynamic components **lives in a single file**. Dynamic components may override static component properties if they share the same selector (same or lower specificity).
## Basic Shape of Components Config ```js title="Componet config" const componentConfig = { disable: boolean, // optional // EITHER resolve: function, // optional if generateTree exists // OR generateTree: function, // optional if resolve exists mergeTree: function, // optional if resolve exists } ``` You can use either `resolve` (`function`) or `generateTree + mergeTree` (both are functions). ### resolve The `resolve` function generates component classes as a **CSS string**. ```js title="Dynamically generated component string" const shilpConfig = { source: "react", extend: { components: { ipsum: { resolve: (options) => { // custom component classes generation logic return ` .any-component { @layout is-flex; max-width: theme(screens-lg); } `; }, }, }, }, }; export default shilpConfig; ``` You can write normal CSS, intents, mixins and inline theme functions inside the returned string. #### Available Options Custom component resolver `componentConfig.resolve` receives a single argument (`object`) with following options: | Option | Type | Description | | ------------------------- | -------- | -------------------------- | | `options.content` | `string` | Raw CSS string | | `options.config` | `object` | Full shilp config object | | `options.componentName` | `string` | Mostly for error reporting | | `options.componentConfig` | `object` | Full component config | DO NOT MUTATE THESE OPTIONS. #### Expected Output The resolver must return **a string containing generated CSS classes**. ### generateTree Instead of returning CSS as a string, you can generate a **structured tree object**. Unlike `resolve`, `generateTree` will let you modify the component tree structure before it generates classes string. This is useful when integrating third-party components. Know more at [Merge Tree](#mergetree). ```js title="Dynamically generated component tree" const shilpConfig = { source: "react", extend: { components: { ipsum: { generateTree: (options) => { // Custom component generator logic return { ".ipsum": { width: "100%", "@space": "mx-auto;", "padding-left": "theme(spacing|spacing-4)", "padding-right": "theme(spacing|spacing-4)", }, }; }, }, }, }, }; export default shilpConfig; ``` Rules: - Keys must be unique at the same level - CSS properties name must use **kebab-case** - Values must be `string` or `object` #### Writing Intents Inside tree structure: - Key → intent name starts with `@` - Value → utility string ending with `;` Example: ```js { "@layout": "is-flex overflow-hidden shadow-lg;" } ``` #### Writing Mixins Inside tree structure: - Key → mixin name starts with `@` - Value → object containing styles Example: ```js { "@state hover": { "@layout": "is-flex;" } } ``` #### Writing Inline Theme Function Inline theme works normally. Example: ```js { "max-width": "theme(screens-lg);" } ``` #### Available Options `componentConfig.generateTree` receives a single argument (`object`) with following options (same as `resolve`): | Option | Type | Description | | ------------------------- | -------- | -------------------------- | | `options.content` | `string` | Raw CSS string | | `options.config` | `object` | Full shilp config object | | `options.componentName` | `string` | Mostly for error reporting | | `options.componentConfig` | `object` | Full component config | DO NOT MUTATE THESE OPTIONS. #### Expected Output Must return a **tree object representing CSS structure**. Shilp CSS will convert it into CSS. ### mergeTree **Used together with `generateTree` ONLY**. It allows modifying generated component trees before converted to string. Useful for **overriding third-party component trees**. Example: ```js title="Modify dynamically generated component tree" const shilpConfig = { source: "react", extend: { components: { ipsum: { mergeTree: (options) => { // modify generated component tree // add changes only as it will be deep merged return changesOnGeneratedTree; }, }, }, }, }; export default shilpConfig; ``` Rules: - Works like `shilpConfig.extend` (deep merge) - Set value to `null` or `undefined` to remove it from tree Example to remove horizontal padding: ```js title="Modify dynamically generated tree before converting to string" const componentConfig = { generateTree: () => { ... }, mergeTree: (options) => { return { ".container": { "padding-left": null, "padding-right": null, }, }; } } ``` #### Available Options `componentConfig.mergeTree` receives a single argument (`object`) with following options (almost same as `generateTree`): | Option | Type | Description | | ------------------------- | -------- | ----------------------------------- | | `options.content` | `string` | Raw CSS string | | `options.config` | `object` | Full shilp config object | | `options.componentName` | `string` | Mostly for error reporting | | `options.componentConfig` | `object` | Full component config | | `options.generatedTree` | `object` | Generated components tree structure | DO NOT MUTATE THESE OPTIONS. #### Expected Output Must return a **tree object representing CSS structure**. Return only what you want to modify, as it will be deep merged and not require full `generatedTree`. Shilp CSS now generates actual classes string. ### disable You can disable any dynamic component. This **does not affect static components or any other css classes**. For example, to disable `container` component: ```js title="Disable container component" const shilpConfig = { source: "react", extend: { components: { container: { disable: true, }, }, }, }; export default shilpConfig; ``` This prevents Shilp CSS from generating the component entirely, and any styles defined inside it. This can be useful when: - Integrating third-party component classes - Reducing bundle size - Restricting allowed styling patterns
## High-Level Components Processing At the beginning of processing: - Internal default mixins are created from `shilpConfig.components` and loaded - Root-level components `shilpConfig.components` override them completely (if provided) - This is not recommended. Avoid this. - `shilpConfig.extend.components` is deep merged with `shilpConfig.components` This defines which **components** are available. Component processing happens during build generation. There is no runtime evaluation. See: [Where Dynamic Components Are Inserted](#where-dynamic-components-are-inserted) At this stage, component processing is done.
## Available Built-in Components Dataset All built-in components datasets are documented separately. You can explore the [full list](/docs/components) in the **COMPONENTS** section of the documentation. Each dataset has its own page: `/docs/components/` Examples: - `/docs/components/container` - `/docs/components/screen-reader` - `/docs/components/limit-lines` Those pages show exact components dataset structure with usage example.