@@ -6,12 +6,17 @@ A type-safe CSS style system for the Spark framework.
66
77## Features
88
9- - ** Type-Safe CSS Values** : Sealed classes for colors, lengths, spacing, display, position, flexbox, typography, borders, transitions, and more.
9+ - ** Type-Safe CSS Values** : Sealed classes for colors, lengths, spacing, display, position, flexbox, typography, borders, transitions, filters, transforms, shadows, cursors, backgrounds, and more.
1010- ** Stylesheet API** : ` Style.typed ` for individual rule sets and ` css() ` helper for multi-selector stylesheets.
11- - ** CSS Shorthand Support** : ` CssSpacing ` handles 1, 2, 3, or 4 value shorthand for margin and padding .
11+ - ** CSS Shorthand Support** : ` CssSpacing ` and ` CssBorderRadius ` handle 1– 4 value shorthand for margin, padding, and border-radius .
1212- ** CSS Functions** : Support for ` calc() ` , ` min() ` , ` max() ` , ` clamp() ` , and ` fit-content() ` .
1313- ** CSS Variables** : Every value type supports ` variable() ` for CSS custom properties.
14+ - ** Global Keywords** : Every value type supports ` global() ` for ` inherit ` , ` initial ` , ` unset ` , ` revert ` , and ` revert-layer ` .
15+ - ** Filters & Transforms** : Full ` CssFilter ` and ` CssTransform ` APIs with composition support.
16+ - ** Gradients & Backgrounds** : Linear and radial gradients, plus typed background-size, position, repeat, clip, origin, and attachment.
17+ - ** Shadows** : ` CssBoxShadow ` and ` CssTextShadow ` with multi-shadow support.
1418- ** Automatic Minification** : CSS output is minified in production builds via the ` dart.vm.product ` flag.
19+ - ** Component Style Registry** : Server-side style deduplication via ` componentStyles ` .
1520- ** Escape Hatches** : ` raw() ` factories and ` .add() ` method for properties not yet covered by typed constructors.
1621- ** Zero Dependencies** : Pure Dart package with no runtime dependencies.
1722
@@ -38,7 +43,7 @@ final style = Style.typed(
3843 display: CssDisplay.flex,
3944 padding: CssSpacing.all(CssLength.px(16)),
4045 backgroundColor: CssColor.hex('f5f5f5'),
41- borderRadius: CssLength.px(8),
46+ borderRadius: CssBorderRadius.all( CssLength.px(8) ),
4247);
4348
4449print(style.toCss());
@@ -85,6 +90,29 @@ margin: CssSpacing.trbl(
8590 CssLength.px(30),
8691 CssLength.px(40),
8792),
93+
94+ // Named parameters for specific sides
95+ margin: CssSpacing.sides(top: CssLength.px(10), left: CssLength.px(20)),
96+ ```
97+
98+ ### Border Radius Shorthand
99+
100+ ` CssBorderRadius ` follows the same shorthand pattern:
101+
102+ ``` dart
103+ // Single value (all corners)
104+ borderRadius: CssBorderRadius.all(CssLength.px(8)),
105+
106+ // Two values (topLeft+bottomRight | topRight+bottomLeft)
107+ borderRadius: CssBorderRadius.symmetric(CssLength.px(8), CssLength.px(4)),
108+
109+ // Four values (topLeft | topRight | bottomRight | bottomLeft)
110+ borderRadius: CssBorderRadius.trbl(
111+ CssLength.px(8),
112+ CssLength.px(4),
113+ CssLength.px(8),
114+ CssLength.px(4),
115+ ),
88116```
89117
90118### CSS Variables
@@ -98,6 +126,140 @@ Style.typed(
98126)
99127```
100128
129+ ### Global Keywords
130+
131+ Every value type supports CSS global keywords via ` CssGlobal ` :
132+
133+ ``` dart
134+ Style.typed(
135+ display: CssDisplay.global(CssGlobal.inherit),
136+ color: CssColor.global(CssGlobal.unset),
137+ )
138+ ```
139+
140+ Available globals: ` inherit ` , ` initial ` , ` unset ` , ` revert ` , ` revertLayer ` .
141+
142+ ### Filters
143+
144+ ` CssFilter ` supports all CSS filter functions:
145+
146+ ``` dart
147+ Style.typed(
148+ filter: CssFilter.blur(CssLength.px(4)),
149+ )
150+
151+ // Compose multiple filters
152+ Style.typed(
153+ filter: CssFilter.compose([
154+ CssFilter.grayscalePercent(50),
155+ CssFilter.blur(CssLength.px(2)),
156+ ]),
157+ )
158+
159+ // Backdrop filter
160+ Style.typed(
161+ backdropFilter: CssFilter.blur(CssLength.px(10)),
162+ )
163+ ```
164+
165+ Available filters: ` blur ` , ` brightness ` , ` contrast ` , ` dropShadow ` , ` grayscale ` , ` hueRotate ` , ` invert ` , ` opacity ` , ` saturate ` , ` sepia ` . Each has both unitless and percent variants (e.g. ` brightness ` / ` brightnessPercent ` ).
166+
167+ ### Transforms
168+
169+ ` CssTransform ` supports all 2D transform functions:
170+
171+ ``` dart
172+ Style.typed(
173+ transform: CssTransform.rotate(CssAngle.deg(45)),
174+ )
175+
176+ // Compose multiple transforms
177+ Style.typed(
178+ transform: CssTransform.list([
179+ CssTransform.translate(CssLength.px(10), CssLength.px(20)),
180+ CssTransform.scale(1.5),
181+ CssTransform.rotate(CssAngle.deg(45)),
182+ ]),
183+ )
184+ ```
185+
186+ Available transforms: ` translate ` , ` translateX ` , ` translateY ` , ` scale ` , ` scaleX ` , ` scaleY ` , ` rotate ` , ` skew ` , ` skewX ` , ` skewY ` , ` matrix ` .
187+
188+ ### Shadows
189+
190+ ` CssBoxShadow ` and ` CssTextShadow ` support single and multiple shadows:
191+
192+ ``` dart
193+ // Box shadow
194+ Style.typed(
195+ boxShadow: CssBoxShadow(
196+ x: CssLength.px(0),
197+ y: CssLength.px(4),
198+ blur: CssLength.px(8),
199+ color: CssColor.rgba(0, 0, 0, 0.1),
200+ ),
201+ )
202+
203+ // Multiple box shadows
204+ Style.typed(
205+ boxShadow: CssBoxShadow.multiple([
206+ CssBoxShadow(
207+ x: CssLength.px(0),
208+ y: CssLength.px(2),
209+ blur: CssLength.px(4),
210+ color: CssColor.rgba(0, 0, 0, 0.1),
211+ ),
212+ CssBoxShadow(
213+ x: CssLength.px(0),
214+ y: CssLength.px(8),
215+ blur: CssLength.px(16),
216+ color: CssColor.rgba(0, 0, 0, 0.1),
217+ inset: true,
218+ ),
219+ ]),
220+ )
221+
222+ // Text shadow
223+ Style.typed(
224+ textShadow: CssTextShadow(
225+ x: CssLength.px(1),
226+ y: CssLength.px(1),
227+ blur: CssLength.px(2),
228+ color: CssColor.rgba(0, 0, 0, 0.3),
229+ ),
230+ )
231+ ```
232+
233+ ### Gradients & Backgrounds
234+
235+ ` CssBackgroundImage ` supports linear and radial gradients:
236+
237+ ``` dart
238+ // Linear gradient
239+ Style.typed(
240+ backgroundImage: CssBackgroundImage.linearGradient(
241+ direction: CssGradientDirection.toRight,
242+ stops: [
243+ CssGradientStop(CssColor.hex('ff0000')),
244+ CssGradientStop(CssColor.hex('0000ff')),
245+ ],
246+ ),
247+ )
248+
249+ // Radial gradient with stop offsets
250+ Style.typed(
251+ backgroundImage: CssBackgroundImage.radialGradient(
252+ shape: CssRadialShape.circle,
253+ stops: [
254+ CssGradientStop(CssColor.hex('ff0000'), CssLength.percent(0)),
255+ CssGradientStop(CssColor.hex('0000ff'), CssLength.percent(100)),
256+ ],
257+ ),
258+ )
259+ ```
260+
261+ Typed background properties: ` backgroundSize ` , ` backgroundPosition ` , ` backgroundRepeat ` , ` backgroundClip ` , ` backgroundOrigin ` , ` backgroundAttachment ` .
262+
101263### Transitions
102264
103265` CssTransition ` uses typed parameters for property names, durations, and timing functions:
@@ -107,36 +269,112 @@ Style.typed(
107269 transition: CssTransition.simple(
108270 CssTransitionProperty.opacity,
109271 CssDuration.ms(200),
110- CssTimingFunction.ease ,
272+ CssTimingFunction.easeInOut ,
111273 ),
112274)
113- ```
114275
115- Use the named constructor for full control including delay:
116-
117- ``` dart
276+ // Full control with delay
118277CssTransition(
119278 property: CssTransitionProperty.transform,
120279 duration: CssDuration.s(0.3),
121280 timingFunction: CssTimingFunction.easeInOut,
122281 delay: CssDuration.ms(100),
123282)
283+
284+ // Multiple transitions
285+ Style.typed(
286+ transition: CssTransition.multiple([
287+ CssTransition.simple(CssTransitionProperty.opacity, CssDuration.ms(200)),
288+ CssTransition.simple(CssTransitionProperty.transform, CssDuration.ms(300)),
289+ ]),
290+ )
291+
292+ // Raw escape hatches for unsupported values
293+ CssTransitionProperty.raw('max-width')
294+ CssDuration.raw('200ms')
295+
296+ // Custom timing function
297+ CssTimingFunction.cubicBezier(0.4, 0, 0.2, 1)
124298```
125299
126- Combine multiple transitions:
300+ ### Flex Shorthand
301+
302+ ` CssFlexShorthand ` provides the ` flex ` shorthand with smart validation:
127303
128304``` dart
129- CssTransition.multiple([
130- CssTransition.simple(CssTransitionProperty.opacity, CssDuration.ms(200)),
131- CssTransition.simple(CssTransitionProperty.transform, CssDuration.ms(300)),
132- ])
305+ // flex: auto
306+ Style.typed(flex: CssFlexShorthand.auto)
307+
308+ // flex: 1 (grow only)
309+ Style.typed(flex: CssFlexShorthand(grow: 1))
310+
311+ // flex: 1 0 auto (grow, shrink, basis)
312+ Style.typed(flex: CssFlexShorthand(grow: 1, shrink: 0, basis: CssLength.auto))
133313```
134314
135- Use ` .raw() ` for values not covered by the typed constructors:
315+ ### Font Families
316+
317+ ` CssFontFamily ` supports named fonts, generic families, and font stacks:
136318
137319``` dart
138- CssTransitionProperty.raw('max-width')
139- CssDuration.raw('200ms')
320+ // Generic family
321+ Style.typed(fontFamily: CssFontFamily.sansSerif)
322+
323+ // Named font
324+ Style.typed(fontFamily: CssFontFamily.named('Inter'))
325+
326+ // Font stack with fallbacks
327+ Style.typed(
328+ fontFamily: CssFontFamily.stack([
329+ CssFontFamily.named('Inter'),
330+ CssFontFamily.named('Helvetica'),
331+ CssFontFamily.sansSerif,
332+ ]),
333+ )
334+ ```
335+
336+ ### Outline
337+
338+ ` CssOutline ` provides the outline shorthand:
339+
340+ ``` dart
341+ Style.typed(
342+ outline: CssOutline(
343+ width: CssLength.px(2),
344+ style: CssBorderStyle.solid,
345+ color: CssColor.hex('0066ff'),
346+ ),
347+ outlineOffset: CssLength.px(2),
348+ )
349+ ```
350+
351+ ### Cursors
352+
353+ ` CssCursor ` covers all standard CSS cursors plus custom URL cursors:
354+
355+ ``` dart
356+ Style.typed(cursor: CssCursor.pointer)
357+
358+ // Custom cursor with fallback
359+ Style.typed(
360+ cursor: CssCursor.url('custom.cur', fallback: CssCursor.pointer),
361+ )
362+ ```
363+
364+ ### Modern Viewport Units
365+
366+ ` CssLength ` supports modern viewport units alongside classic ones:
367+
368+ ``` dart
369+ // Dynamic viewport units
370+ height: CssLength.dvh(100),
371+ width: CssLength.dvw(100),
372+
373+ // Small viewport units
374+ height: CssLength.svh(100),
375+
376+ // Large viewport units
377+ height: CssLength.lvh(100),
140378```
141379
142380### Custom Properties
@@ -150,6 +388,17 @@ final style = Style.typed(
150388style.add('grid-template-columns', 'repeat(3, 1fr)');
151389```
152390
391+ ### Component Style Registry
392+
393+ For server-side rendering, ` componentStyles ` provides style deduplication:
394+
395+ ``` dart
396+ componentStyles.register('my-button', buttonStyles.toCss());
397+
398+ // Later, retrieve registered CSS
399+ final css = componentStyles.get('my-button');
400+ ```
401+
153402## Contributing
154403
155404This package is part of the Spark framework. Contributions are welcome at [ https://github.com/KLEAK-Development/spark ] ( https://github.com/KLEAK-Development/spark ) .
0 commit comments