@@ -215,9 +215,10 @@ WebUI follows a compositional pattern for creating HTML elements. When adding a
215
215
216
216
## Adding New Style Modifiers
217
217
218
- Style modifiers in WebUI follow an extension pattern on the ` Element ` class . Here's how to add a new style modifier:
218
+ Style modifiers in WebUI follow the unified style system pattern . Here's how to add a new style modifier:
219
219
220
220
1 . ** File Location** : Add the new style modifier to the appropriate file in ` Sources/WebUI/Styles/ ` :
221
+ - Core style operations go in the ` Core/ ` directory
221
222
- Appearance-related modifiers go in the ` Appearance/ ` directory
222
223
- Layout-related modifiers go in the ` Base/ ` or ` Positioning/ ` directories
223
224
- Create a new file if the modifier doesn't fit an existing category
@@ -238,7 +239,33 @@ Style modifiers in WebUI follow an extension pattern on the `Element` class. Her
238
239
}
239
240
```
240
241
241
- b. ** Implement the Extension Method** :
242
+ b. ** Implement the Style Operation** :
243
+ ``` swift
244
+ /// Style operation for the custom style
245
+ public struct StyleModifierOperation : StyleOperation {
246
+ /// Parameters for this style operation
247
+ public struct Parameters {
248
+ public let option: StyleOption
249
+
250
+ public init (option : StyleOption) {
251
+ self .option = option
252
+ }
253
+ }
254
+
255
+ /// Applies the style operation and returns CSS classes
256
+ public func applyClasses (params : Parameters) -> [String ] {
257
+ return [" style-\( params.option .rawValue ) " ]
258
+ }
259
+
260
+ /// Shared instance
261
+ public static let shared = StyleModifierOperation ()
262
+
263
+ /// Private initializer
264
+ private init () {}
265
+ }
266
+ ```
267
+
268
+ c. ** Implement the Element Extension Method** :
242
269
``` swift
243
270
extension Element {
244
271
/// Applies a style modifier to the element.
@@ -260,43 +287,45 @@ Style modifiers in WebUI follow an extension pattern on the `Element` class. Her
260
287
option : StyleOption,
261
288
on modifiers : Modifier...
262
289
) -> Element {
263
- let baseClass = " style-\( option.rawValue ) "
264
- let newClasses = combineClasses ([baseClass], withModifiers : modifiers)
265
-
266
- return Element (
267
- tag : self .tag ,
268
- id : self .id ,
269
- classes : (self .classes ?? []) + newClasses,
270
- role : self .role ,
271
- label : self .label ,
272
- data : self .data ,
273
- isSelfClosing : self .isSelfClosing ,
274
- customAttributes : self .customAttributes ,
275
- content : self .contentBuilder
290
+ let params = StyleModifierOperation.Parameters (option : option)
291
+
292
+ return StyleModifierOperation.shared .applyToElement (
293
+ self ,
294
+ params : params,
295
+ modifiers : modifiers
276
296
)
277
297
}
278
298
}
279
299
```
280
300
281
- c . ** Update Responsive Support ** (if applicable) :
301
+ d . ** Implement the Global Function for Declarative DSL ** :
282
302
``` swift
283
- extension Element {
284
- /// Responsive version for use within the .responsive block
285
- @discardableResult
286
- public func styleModifier (option : StyleOption) -> Element {
287
- return self .styleModifier (option : option, on : []).proxy ()
288
- }
303
+ /// Applies the style modifier in the responsive context with Declarative syntax.
304
+ ///
305
+ /// - Parameters:
306
+ /// - option: The style option to apply.
307
+ /// - Returns: A responsive modification for the style.
308
+ public func styleModifier (option : StyleOption) -> ResponsiveModification {
309
+ let params = StyleModifierOperation.Parameters (option : option)
310
+
311
+ return StyleModifierOperation.shared .asModification (params : params)
289
312
}
290
313
```
291
314
315
+ f. ** Register in StyleRegistry** (optional but recommended):
316
+ ``` swift
317
+ // In StyleRegistry.swift
318
+ public static let styleModifier = StyleModifierOperation.shared
319
+ ```
320
+
292
321
3 . ** Testing** : Add unit tests for the new style modifier in the ` Tests ` directory.
293
322
294
323
4 . ** Documentation** : Include comprehensive DocC documentation with:
295
324
- Method-level documentation explaining the modifier's purpose
296
325
- Parameter documentation for all method parameters
297
326
- Usage examples showing common implementations
298
327
- Visual examples if the style has a significant impact on appearance
299
- - Examples of using the modifier within responsive blocks
328
+ - Examples of using the modifier with all three interfaces (direct, on, and Declarative)
300
329
301
330
### Adding Extensions to Existing Elements
302
331
@@ -332,30 +361,62 @@ You can extend existing elements with specialized methods to improve developer e
332
361
333
362
3 . ** Documentation** : As with other additions, include comprehensive DocC documentation.
334
363
335
- ### Using Responsive Styling
336
-
337
- WebUI provides a block-based responsive API for cleaner responsive designs.
338
-
339
- ### Basic Usage
340
-
341
- The ` .responsive ` modifier allows applying multiple style changes across different breakpoints in a single block:
342
-
343
- ``` swift
344
- Text { " Responsive Content" }
345
- .font (size : .sm )
346
- .background (color : .neutral (._500 ))
347
- .responsive {
348
- $0 .md {
349
- $0 .font (size : .lg )
350
- $0 .background (color : .neutral (._700 ))
351
- $0 .padding (of : 4 )
352
- }
353
- $0 .lg {
354
- $0 .font (size : .xl )
355
- $0 .background (color : .neutral (._900 ))
356
- }
357
- }
358
- ```
364
+ ## Responsive Styling System
365
+
366
+ WebUI provides a powerful responsive styling system with multiple syntaxes for flexibility and developer experience.
367
+
368
+ ### Responsive Styling Options
369
+
370
+ WebUI supports two different ways to apply responsive styles:
371
+
372
+ 1 . ** Declarative Block Syntax** - Create responsive styles in a clean, concise way:
373
+ 1 . ** Declaritive** (using the result builder pattern):
374
+ ``` swift
375
+ Text { " Responsive Content" }
376
+ .font (size : .sm )
377
+ .responsive {
378
+ md {
379
+ font (size : .lg )
380
+ background (color : .neutral (._700 ))
381
+ }
382
+ lg {
383
+ font (size : .xl )
384
+ padding (of : 6 )
385
+ }
386
+ }
387
+ ```
388
+
389
+ 2 . ** Direct Breakpoint Modifiers** (for single property changes):
390
+ ``` swift
391
+ Text { " Responsive Content" }
392
+ .font (size : .sm , on : .xs )
393
+ .font (size : .lg , on : .md )
394
+ .font (size : .xl , on : .lg )
395
+ ```
396
+
397
+ ### Implementing Responsive Support
398
+
399
+ When adding new style modifiers, you must implement both interfaces to ensure full responsive support:
400
+
401
+ 1 . ** Element Extension** - For direct styling and breakpoint modifiers
402
+ 2 . ** Global Function** - For Declaritive syntax with result builders
403
+
404
+ The unified style system makes this process simple by deriving both interfaces from a single style operation.
405
+
406
+ ### Unified Style System
407
+
408
+ WebUI uses a unified style system that defines each style operation once and derives multiple interfaces from it:
409
+
410
+ 1 . ** Core Style Operations** - Define the core logic for generating CSS classes
411
+ 2 . ** Interface Adapters** - Adapt the core operations to different contexts (Element extensions and global functions)
412
+ 3 . ** StyleRegistry** - Provides centralized access to all style operations
413
+
414
+ This approach provides several benefits:
415
+ - Single point of definition for each style
416
+ - Consistency across different interfaces
417
+ - Reduced code duplication
418
+ - Easier maintenance and extension
419
+ - Clean, Declarative syntax for responsive styling
359
420
360
421
### File Organization Principles
361
422
@@ -367,18 +428,21 @@ When organizing code in the WebUI library, follow these principles:
367
428
4 . ** Manageable Size** : Keep files under on the smaller side where possible
368
429
5 . ** Clear Dependencies** : Make dependencies between components explicit and avoid circularity
369
430
370
- When refactoring or adding new code, consider if you should:
371
- - Add to an existing file (for small, closely related additions)
372
- - Create a new file in an existing directory (for new components in an established category)
373
- - Create a new directory (for entirely new subsystems or categories)
431
+ When adding new style operations:
432
+ - Create the style operation in ` Styles/Core/ `
433
+ - Register it in ` StyleRegistry `
434
+ - Implement the three interface adapters (Element, ResponsiveBuilder, global function)
435
+ - Add comprehensive documentation and tests
436
+
437
+ ### Style Operation File Structure
374
438
375
- ### Adding Support to Custom Style Methods
439
+ Each style operation file should follow this structure:
376
440
377
- When creating custom style modifiers, ensure they work within responsive blocks by:
441
+ 1 . ** Style Operation Implementation** - The core logic for generating CSS classes
442
+ 2 . ** Element Extension** - For direct styling with the ` on: modifiers ` parameter
443
+ 3 . ** Global Function** - For Declarative syntax within responsive blocks
378
444
379
- 1 . Adding a version without the ` on modifiers ` parameter
380
- 2 . Using the ` .proxy() ` method to maintain the proper element chain
381
- 3 . Adding examples showing how to use the style in responsive contexts
445
+ This structure ensures full support across both interfaces and maintains consistency across the codebase.
382
446
383
447
## Styleguides
384
448
0 commit comments