Values
At the lowest level, everything is just a value.
16px: absolute spacing0.25rem: relative spacing64.6% 0.222 41.116: raw OKLCH color (L% C H)1.5: fraction (number)200ms: time
These are primitive values and finally becomes:
property: value <optional !important flag>;
Shilp CSS simply organizes them.
if intent decides where, utility decides what, property decides how, then values decides what the actual data is.
Property Config And Values
From the Properties Config Page, we know:
- What a property config is
- How property and value tokens are resolved
- How
global values,propertyConfig.themeKey, andpropertyConfig.valuesare merged - What
special: truechanges
Values are resolved after property config is found and each property decides how
its values are resolved using propertyConfig.resolve.
Value Resolver Methods
You can define how value is resolved (per property) by using
propertyConfig.resolve: <resolver-name>.
All the built-in value resolvers are defined at shilpConfig.valueResolvers.
| Resolver | Description |
|---|---|
"rawColor" | Returns only raw value L% C H as it is defined without processing |
"color" | Return full color oklch(L% C H) with optional opacity support |
"rawSpacing" | Return only raw value px as it is defined without processing |
"spacing" | Returns numeric values px processed to rem values |
"default" | Returns raw value as it is defined without processing |
How Resolver Is Selected
For every property:
- If
propertyConfig.resolveis defined → use resolver fromshilpConfig.valueResolvers - If nothing provided → use
shilpConfig.valueResolvers.defaultresolver - If invalid resolver provided → error will be thrown
How Value Is Found (Core Logic)
Algorithm:
- Start at
propertyConfig.valuesobject - Take first value
token - Try
values[token] - If not found → try
values.DEFAULT - If result is another object → go one level deeper
- With sub-sequent value tokens, continue until final non-object value is found
- If nothing found → throw error
In simple words, Value resolver finds a value from propertyConfig.values using
value tokens and thows error if not found a correct path.
That’s it. Everything else in resolvers builds on top of this logic.
Built-in Resolvers
All the built-in resolvers are explained below:
Default Resolver
Property config with 'default' resovlerconst propertyConfig = { property: "...", resolve: "default", values: { ... } }
If nothing is specified, this is used.
It:
- Uses the standard value-finding logic
- Does not support variant
- Supports inline
theme(...)values
Special Case
For Inline Theme Function with
color value, If value not found by core logic, it will try values[500]
once for current nesting level.
Raw Color Resolver
Property config with 'rawColor' resolverconst propertyConfig = { property: "...", resolve: "rawColor", values: { ... } }
It uses the standard value-finding logic, but with slightly different fallback.
Instead of only checking values[token] and then values.DEFAULT, it also
checks values[500] at current nesting level.
In simple words, if token not found and no DEFAULT at current nesting level,
it will check 500 key.
It returns raw color value as-is (not wrapped in oklch()).
Raw Spacing Resolver
Property config with 'rawSpacing' resolverconst propertyConfig = { property: "...", resolve: "rawSpacing", values: { ... } }
It uses standard value-finding logic. No extra transformation.
Returns raw spacing value as-is.
Color Resolver
Property config with 'color' resolverconst propertyConfig = { property: "...", resolve: "color", values: { ... } }
Steps:
- First uses
rawColorresolver to get raw color - If value:
- Starts with
var(...)→ return as-is. - Is not in
L% C Hformat → return as-is.L% C Hformat pattern is/(\d*\.?\d+)%\s+(\d*\.?\d+)\s+(\d*\.?\d+)/g- NOTE:
Lmust be in%(0-100%)
- Starts with
- If valid OKLCH raw value:
- If no variant → return
oklch(rawColor) - If variant exists:
- Must be between
0–100 - Converted to opacity (
variant / 100) - Return
oklch(rawColor / opacity)
- Must be between
- If no variant → return
For example, @text color-orange-600/80; will becomes
color: oklch(64.6% 0.222 41.116 / 0.8);.
Spacing Resolver
Property config with 'spacing' resolverconst propertyConfig = { property: "...", resolve: "spacing", values: { ... } }
Steps:
- Use
rawSpacingto get raw value - If value:
- contains
calckeyword → return as-is - does not ends with
pxunit → return as-is
- contains
- If valid raw spacing value:
- Parse float
- Divide by
16 - Keep up to 4 decimal precision
- Remove
.0000if exist
Custom Resolver
You can also use custom value resolvers by defining it inside
shilpConfig.extend.valueResolvers object.
Use this for advanced use-cases.
Custom value resolver 'ipsum'const shilpConfig = { source: "react", extend: { properties: { space: { // margin m: { resolve: "ipsum", }, }, }, valueResolvers: { ipsum: (options) => { // custom value resolver logic return resolvedValue; }, }, }, }; export default shilpConfig;
Available Options
Custom resolver function receives a single argument (object) with following
options:
| Option | Type | Description |
|---|---|---|
options.config | object | full shilp config object |
options.intentName | string | mostly for error reporting |
options.utility | object | utility object |
options.tokens | array | values tokens array |
options.values | object | values object from property config |
options.propertyConfig | object | full property config object |
options.inlineThemeConfig | object | full inline theme config object |
Expected Output
In return, it expects a string containing valid CSS value.
High-Level Values Processing
values is the first config that is resolved in config.
At the beginning of processing:
- Internal defaults are created and loaded
- values loaded at
shilpConfig.values - value resolvers loaded at
shilpConfig.valueResolvers
- values loaded at
- Root-level objects override them completely (if provided)
- values at
shilpConfig.values - value resolvers at
shilpConfig.valueResolvers - This is not recommended. Avoid this
- values at
- Extend configs are deep merged
shilpConfig.extend.valuesdeep merged withshilpConfig.valuesshilpConfig.extend.valueResolversdeep merged withshilpConfig.valueResolves
Now full values dataset and value resovlers are available.
When properties processing reaches at resolver stage:
- Resolver runs
- Value is resolved
- Value returned to property config to generates final CSS
At this stage, value resolution is done.
Further processing is handled by the Properties Config – High Level Processing.
Available Built-in Values Dataset
All built-in values datasets are documented separately.
You can explore the full list in the VALUES section of the documentation.
Each dataset has its own page: /docs/values/<dataset-name>
Examples:
/docs/values/colors/docs/values/border/docs/values/time
Those pages show exact values dataset structure with usage example.