typewritingclass 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +107 -0
  2. package/package.json +71 -0
  3. package/src/css.ts +140 -0
  4. package/src/cx.ts +105 -0
  5. package/src/dcx.ts +79 -0
  6. package/src/dynamic.ts +117 -0
  7. package/src/hash.ts +54 -0
  8. package/src/index.ts +137 -0
  9. package/src/inject.ts +86 -0
  10. package/src/layer.ts +81 -0
  11. package/src/modifiers/aria.ts +15 -0
  12. package/src/modifiers/colorScheme.ts +32 -0
  13. package/src/modifiers/data.ts +6 -0
  14. package/src/modifiers/direction.ts +5 -0
  15. package/src/modifiers/group.ts +21 -0
  16. package/src/modifiers/index.ts +17 -0
  17. package/src/modifiers/media.ts +11 -0
  18. package/src/modifiers/peer.ts +24 -0
  19. package/src/modifiers/pseudo.ts +183 -0
  20. package/src/modifiers/pseudoElements.ts +26 -0
  21. package/src/modifiers/responsive.ts +110 -0
  22. package/src/modifiers/supports.ts +6 -0
  23. package/src/registry.ts +171 -0
  24. package/src/rule.ts +202 -0
  25. package/src/runtime.ts +36 -0
  26. package/src/theme/animations.ts +11 -0
  27. package/src/theme/borders.ts +9 -0
  28. package/src/theme/colors.ts +326 -0
  29. package/src/theme/createTheme.ts +238 -0
  30. package/src/theme/filters.ts +20 -0
  31. package/src/theme/index.ts +9 -0
  32. package/src/theme/inject-theme.ts +81 -0
  33. package/src/theme/shadows.ts +8 -0
  34. package/src/theme/sizes.ts +37 -0
  35. package/src/theme/spacing.ts +44 -0
  36. package/src/theme/typography.ts +72 -0
  37. package/src/types.ts +273 -0
  38. package/src/utilities/accessibility.ts +33 -0
  39. package/src/utilities/backgrounds.ts +86 -0
  40. package/src/utilities/borders.ts +610 -0
  41. package/src/utilities/colors.ts +127 -0
  42. package/src/utilities/effects.ts +169 -0
  43. package/src/utilities/filters.ts +96 -0
  44. package/src/utilities/index.ts +57 -0
  45. package/src/utilities/interactivity.ts +253 -0
  46. package/src/utilities/layout.ts +1149 -0
  47. package/src/utilities/spacing.ts +681 -0
  48. package/src/utilities/svg.ts +34 -0
  49. package/src/utilities/tables.ts +54 -0
  50. package/src/utilities/transforms.ts +85 -0
  51. package/src/utilities/transitions.ts +98 -0
  52. package/src/utilities/typography.ts +380 -0
  53. package/src/when.ts +63 -0
@@ -0,0 +1,610 @@
1
+ import type { StyleRule } from '../types.ts'
2
+ import type { DynamicValue } from '../dynamic.ts'
3
+ import { createRule, createDynamicRule, wrapWithSelectorTemplate } from '../rule.ts'
4
+ import { DEFAULT as defaultRadius } from '../theme/borders.ts'
5
+ import { isDynamic } from '../dynamic.ts'
6
+
7
+ /**
8
+ * Sets the `border-radius` on all corners of an element.
9
+ *
10
+ * When called without arguments, uses the default border radius (`0.25rem`).
11
+ * Accepts an optional raw CSS string or a {@link DynamicValue} for runtime values.
12
+ *
13
+ * @param value - Optional CSS border-radius string (`'0.5rem'`, `'9999px'`) or `dynamic()` value. Defaults to `'0.25rem'`.
14
+ * @returns A {@link StyleRule} that sets `border-radius`.
15
+ *
16
+ * @example Default radius
17
+ * ```ts
18
+ * import { cx, rounded } from 'typewritingclass'
19
+ *
20
+ * cx(rounded())
21
+ * // CSS: border-radius: 0.25rem;
22
+ * ```
23
+ *
24
+ * @example Custom radius
25
+ * ```ts
26
+ * cx(rounded('0.5rem'))
27
+ * // CSS: border-radius: 0.5rem;
28
+ * ```
29
+ *
30
+ * @example Full rounding (pill shape)
31
+ * ```ts
32
+ * cx(rounded('9999px'))
33
+ * // CSS: border-radius: 9999px;
34
+ * ```
35
+ *
36
+ * @example Dynamic value
37
+ * ```ts
38
+ * import { dcx, rounded, dynamic } from 'typewritingclass'
39
+ *
40
+ * const { className, style } = dcx(rounded(dynamic(radius)))
41
+ * // CSS: border-radius: var(--twc-d0);
42
+ * // style: { '--twc-d0': radius }
43
+ * ```
44
+ */
45
+ export function rounded(value?: string | DynamicValue): StyleRule {
46
+ if (isDynamic(value)) {
47
+ return createDynamicRule(
48
+ { 'border-radius': `var(${value.__id})` },
49
+ { [value.__id]: String(value.__value) },
50
+ )
51
+ }
52
+ return createRule({ 'border-radius': (value as string | undefined) ?? defaultRadius })
53
+ }
54
+
55
+ /**
56
+ * Sets the `border-radius` on the top-left and top-right corners of an element.
57
+ *
58
+ * When called without arguments, uses the default border radius (`0.25rem`).
59
+ * Accepts an optional raw CSS string or a {@link DynamicValue} for runtime values.
60
+ *
61
+ * @param value - Optional CSS border-radius string (`'0.5rem'`) or `dynamic()` value. Defaults to `'0.25rem'`.
62
+ * @returns A {@link StyleRule} that sets `border-top-left-radius` and `border-top-right-radius`.
63
+ *
64
+ * @example Default radius
65
+ * ```ts
66
+ * import { cx, roundedT } from 'typewritingclass'
67
+ *
68
+ * cx(roundedT())
69
+ * // CSS: border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem;
70
+ * ```
71
+ *
72
+ * @example Custom radius
73
+ * ```ts
74
+ * cx(roundedT('1rem'))
75
+ * // CSS: border-top-left-radius: 1rem; border-top-right-radius: 1rem;
76
+ * ```
77
+ *
78
+ * @example Dynamic value
79
+ * ```ts
80
+ * import { dcx, roundedT, dynamic } from 'typewritingclass'
81
+ *
82
+ * const { className, style } = dcx(roundedT(dynamic(radius)))
83
+ * // CSS: border-top-left-radius: var(--twc-d0); border-top-right-radius: var(--twc-d0);
84
+ * // style: { '--twc-d0': radius }
85
+ * ```
86
+ */
87
+ export function roundedT(value?: string | DynamicValue): StyleRule {
88
+ if (isDynamic(value)) {
89
+ return createDynamicRule(
90
+ { 'border-top-left-radius': `var(${value.__id})`, 'border-top-right-radius': `var(${value.__id})` },
91
+ { [value.__id]: String(value.__value) },
92
+ )
93
+ }
94
+ const v = (value as string | undefined) ?? defaultRadius
95
+ return createRule({ 'border-top-left-radius': v, 'border-top-right-radius': v })
96
+ }
97
+
98
+ /**
99
+ * Sets the `border-radius` on the bottom-left and bottom-right corners of an element.
100
+ *
101
+ * When called without arguments, uses the default border radius (`0.25rem`).
102
+ * Accepts an optional raw CSS string or a {@link DynamicValue} for runtime values.
103
+ *
104
+ * @param value - Optional CSS border-radius string (`'0.5rem'`) or `dynamic()` value. Defaults to `'0.25rem'`.
105
+ * @returns A {@link StyleRule} that sets `border-bottom-left-radius` and `border-bottom-right-radius`.
106
+ *
107
+ * @example Default radius
108
+ * ```ts
109
+ * import { cx, roundedB } from 'typewritingclass'
110
+ *
111
+ * cx(roundedB())
112
+ * // CSS: border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem;
113
+ * ```
114
+ *
115
+ * @example Custom radius
116
+ * ```ts
117
+ * cx(roundedB('1rem'))
118
+ * // CSS: border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem;
119
+ * ```
120
+ *
121
+ * @example Dynamic value
122
+ * ```ts
123
+ * import { dcx, roundedB, dynamic } from 'typewritingclass'
124
+ *
125
+ * const { className, style } = dcx(roundedB(dynamic(radius)))
126
+ * // CSS: border-bottom-left-radius: var(--twc-d0); border-bottom-right-radius: var(--twc-d0);
127
+ * // style: { '--twc-d0': radius }
128
+ * ```
129
+ */
130
+ export function roundedB(value?: string | DynamicValue): StyleRule {
131
+ if (isDynamic(value)) {
132
+ return createDynamicRule(
133
+ { 'border-bottom-left-radius': `var(${value.__id})`, 'border-bottom-right-radius': `var(${value.__id})` },
134
+ { [value.__id]: String(value.__value) },
135
+ )
136
+ }
137
+ const v = (value as string | undefined) ?? defaultRadius
138
+ return createRule({ 'border-bottom-left-radius': v, 'border-bottom-right-radius': v })
139
+ }
140
+
141
+ /**
142
+ * Sets the `border-radius` on the top-left and bottom-left corners of an element.
143
+ *
144
+ * When called without arguments, uses the default border radius (`0.25rem`).
145
+ * Accepts an optional raw CSS string or a {@link DynamicValue} for runtime values.
146
+ *
147
+ * @param value - Optional CSS border-radius string (`'0.5rem'`) or `dynamic()` value. Defaults to `'0.25rem'`.
148
+ * @returns A {@link StyleRule} that sets `border-top-left-radius` and `border-bottom-left-radius`.
149
+ *
150
+ * @example Default radius
151
+ * ```ts
152
+ * import { cx, roundedL } from 'typewritingclass'
153
+ *
154
+ * cx(roundedL())
155
+ * // CSS: border-top-left-radius: 0.25rem; border-bottom-left-radius: 0.25rem;
156
+ * ```
157
+ *
158
+ * @example Custom radius
159
+ * ```ts
160
+ * cx(roundedL('0.75rem'))
161
+ * // CSS: border-top-left-radius: 0.75rem; border-bottom-left-radius: 0.75rem;
162
+ * ```
163
+ *
164
+ * @example Dynamic value
165
+ * ```ts
166
+ * import { dcx, roundedL, dynamic } from 'typewritingclass'
167
+ *
168
+ * const { className, style } = dcx(roundedL(dynamic(radius)))
169
+ * // CSS: border-top-left-radius: var(--twc-d0); border-bottom-left-radius: var(--twc-d0);
170
+ * // style: { '--twc-d0': radius }
171
+ * ```
172
+ */
173
+ export function roundedL(value?: string | DynamicValue): StyleRule {
174
+ if (isDynamic(value)) {
175
+ return createDynamicRule(
176
+ { 'border-top-left-radius': `var(${value.__id})`, 'border-bottom-left-radius': `var(${value.__id})` },
177
+ { [value.__id]: String(value.__value) },
178
+ )
179
+ }
180
+ const v = (value as string | undefined) ?? defaultRadius
181
+ return createRule({ 'border-top-left-radius': v, 'border-bottom-left-radius': v })
182
+ }
183
+
184
+ /**
185
+ * Sets the `border-radius` on the top-right and bottom-right corners of an element.
186
+ *
187
+ * When called without arguments, uses the default border radius (`0.25rem`).
188
+ * Accepts an optional raw CSS string or a {@link DynamicValue} for runtime values.
189
+ *
190
+ * @param value - Optional CSS border-radius string (`'0.5rem'`) or `dynamic()` value. Defaults to `'0.25rem'`.
191
+ * @returns A {@link StyleRule} that sets `border-top-right-radius` and `border-bottom-right-radius`.
192
+ *
193
+ * @example Default radius
194
+ * ```ts
195
+ * import { cx, roundedR } from 'typewritingclass'
196
+ *
197
+ * cx(roundedR())
198
+ * // CSS: border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem;
199
+ * ```
200
+ *
201
+ * @example Custom radius
202
+ * ```ts
203
+ * cx(roundedR('0.75rem'))
204
+ * // CSS: border-top-right-radius: 0.75rem; border-bottom-right-radius: 0.75rem;
205
+ * ```
206
+ *
207
+ * @example Dynamic value
208
+ * ```ts
209
+ * import { dcx, roundedR, dynamic } from 'typewritingclass'
210
+ *
211
+ * const { className, style } = dcx(roundedR(dynamic(radius)))
212
+ * // CSS: border-top-right-radius: var(--twc-d0); border-bottom-right-radius: var(--twc-d0);
213
+ * // style: { '--twc-d0': radius }
214
+ * ```
215
+ */
216
+ export function roundedR(value?: string | DynamicValue): StyleRule {
217
+ if (isDynamic(value)) {
218
+ return createDynamicRule(
219
+ { 'border-top-right-radius': `var(${value.__id})`, 'border-bottom-right-radius': `var(${value.__id})` },
220
+ { [value.__id]: String(value.__value) },
221
+ )
222
+ }
223
+ const v = (value as string | undefined) ?? defaultRadius
224
+ return createRule({ 'border-top-right-radius': v, 'border-bottom-right-radius': v })
225
+ }
226
+
227
+ /**
228
+ * Sets a solid border on all sides of an element.
229
+ *
230
+ * When called without arguments, defaults to `1px` width. Sets both
231
+ * `border-width` and `border-style: solid`.
232
+ *
233
+ * @param width - Optional CSS border-width string (`'2px'`). Defaults to `'1px'`.
234
+ * @returns A {@link StyleRule} that sets `border-width` and `border-style`.
235
+ *
236
+ * @example Default width
237
+ * ```ts
238
+ * import { cx, border } from 'typewritingclass'
239
+ *
240
+ * cx(border())
241
+ * // CSS: border-width: 1px; border-style: solid;
242
+ * ```
243
+ *
244
+ * @example Custom width
245
+ * ```ts
246
+ * cx(border('2px'))
247
+ * // CSS: border-width: 2px; border-style: solid;
248
+ * ```
249
+ */
250
+ export function border(width?: string): StyleRule {
251
+ return createRule({ 'border-width': width ?? '1px', 'border-style': 'solid' })
252
+ }
253
+
254
+ /**
255
+ * Sets a solid border on the top side of an element.
256
+ *
257
+ * When called without arguments, defaults to `1px` width. Sets both
258
+ * `border-top-width` and `border-style: solid`.
259
+ *
260
+ * @param width - Optional CSS border-width string (`'2px'`). Defaults to `'1px'`.
261
+ * @returns A {@link StyleRule} that sets `border-top-width` and `border-style`.
262
+ *
263
+ * @example Default width
264
+ * ```ts
265
+ * import { cx, borderT } from 'typewritingclass'
266
+ *
267
+ * cx(borderT())
268
+ * // CSS: border-top-width: 1px; border-style: solid;
269
+ * ```
270
+ *
271
+ * @example Custom width
272
+ * ```ts
273
+ * cx(borderT('2px'))
274
+ * // CSS: border-top-width: 2px; border-style: solid;
275
+ * ```
276
+ */
277
+ export function borderT(width?: string): StyleRule {
278
+ return createRule({ 'border-top-width': width ?? '1px', 'border-style': 'solid' })
279
+ }
280
+
281
+ /**
282
+ * Sets a solid border on the right side of an element.
283
+ *
284
+ * When called without arguments, defaults to `1px` width. Sets both
285
+ * `border-right-width` and `border-style: solid`.
286
+ *
287
+ * @param width - Optional CSS border-width string (`'2px'`). Defaults to `'1px'`.
288
+ * @returns A {@link StyleRule} that sets `border-right-width` and `border-style`.
289
+ *
290
+ * @example Default width
291
+ * ```ts
292
+ * import { cx, borderR } from 'typewritingclass'
293
+ *
294
+ * cx(borderR())
295
+ * // CSS: border-right-width: 1px; border-style: solid;
296
+ * ```
297
+ *
298
+ * @example Custom width
299
+ * ```ts
300
+ * cx(borderR('3px'))
301
+ * // CSS: border-right-width: 3px; border-style: solid;
302
+ * ```
303
+ */
304
+ export function borderR(width?: string): StyleRule {
305
+ return createRule({ 'border-right-width': width ?? '1px', 'border-style': 'solid' })
306
+ }
307
+
308
+ /**
309
+ * Sets a solid border on the bottom side of an element.
310
+ *
311
+ * When called without arguments, defaults to `1px` width. Sets both
312
+ * `border-bottom-width` and `border-style: solid`.
313
+ *
314
+ * @param width - Optional CSS border-width string (`'2px'`). Defaults to `'1px'`.
315
+ * @returns A {@link StyleRule} that sets `border-bottom-width` and `border-style`.
316
+ *
317
+ * @example Default width
318
+ * ```ts
319
+ * import { cx, borderB } from 'typewritingclass'
320
+ *
321
+ * cx(borderB())
322
+ * // CSS: border-bottom-width: 1px; border-style: solid;
323
+ * ```
324
+ *
325
+ * @example Custom width
326
+ * ```ts
327
+ * cx(borderB('2px'))
328
+ * // CSS: border-bottom-width: 2px; border-style: solid;
329
+ * ```
330
+ */
331
+ export function borderB(width?: string): StyleRule {
332
+ return createRule({ 'border-bottom-width': width ?? '1px', 'border-style': 'solid' })
333
+ }
334
+
335
+ /**
336
+ * Sets a solid border on the left side of an element.
337
+ *
338
+ * When called without arguments, defaults to `1px` width. Sets both
339
+ * `border-left-width` and `border-style: solid`.
340
+ *
341
+ * @param width - Optional CSS border-width string (`'2px'`). Defaults to `'1px'`.
342
+ * @returns A {@link StyleRule} that sets `border-left-width` and `border-style`.
343
+ *
344
+ * @example Default width
345
+ * ```ts
346
+ * import { cx, borderL } from 'typewritingclass'
347
+ *
348
+ * cx(borderL())
349
+ * // CSS: border-left-width: 1px; border-style: solid;
350
+ * ```
351
+ *
352
+ * @example Custom width
353
+ * ```ts
354
+ * cx(borderL('4px'))
355
+ * // CSS: border-left-width: 4px; border-style: solid;
356
+ * ```
357
+ */
358
+ export function borderL(width?: string): StyleRule {
359
+ return createRule({ 'border-left-width': width ?? '1px', 'border-style': 'solid' })
360
+ }
361
+
362
+ /**
363
+ * Creates a focus-ring-style `box-shadow` around an element.
364
+ *
365
+ * When called without arguments, defaults to `3px` width and `#3b82f6` (blue) color.
366
+ * Produces a `box-shadow` with zero offset and zero blur, acting as an outline alternative.
367
+ *
368
+ * @param width - Optional ring width string (`'2px'`). Defaults to `'3px'`.
369
+ * @param color - Optional ring color string (`'#ef4444'`). Defaults to `'#3b82f6'`.
370
+ * @returns A {@link StyleRule} that sets `box-shadow`.
371
+ *
372
+ * @example Default ring
373
+ * ```ts
374
+ * import { cx, ring } from 'typewritingclass'
375
+ *
376
+ * cx(ring())
377
+ * // CSS: box-shadow: 0 0 0 3px #3b82f6;
378
+ * ```
379
+ *
380
+ * @example Custom width and color
381
+ * ```ts
382
+ * cx(ring('2px', '#ef4444'))
383
+ * // CSS: box-shadow: 0 0 0 2px #ef4444;
384
+ * ```
385
+ *
386
+ * @example Custom width only
387
+ * ```ts
388
+ * cx(ring('1px'))
389
+ * // CSS: box-shadow: 0 0 0 1px #3b82f6;
390
+ * ```
391
+ */
392
+ export function ring(width?: string, color?: string): StyleRule {
393
+ const w = width ?? '3px'
394
+ const c = color ?? '#3b82f6'
395
+ return createRule({ 'box-shadow': `0 0 0 ${w} ${c}` })
396
+ }
397
+
398
+ // --- Individual corner radius utilities ---
399
+
400
+ export function roundedTL(value?: string | DynamicValue): StyleRule {
401
+ if (isDynamic(value)) {
402
+ return createDynamicRule(
403
+ { 'border-top-left-radius': `var(${value.__id})` },
404
+ { [value.__id]: String(value.__value) },
405
+ )
406
+ }
407
+ return createRule({ 'border-top-left-radius': (value as string | undefined) ?? defaultRadius })
408
+ }
409
+
410
+ export function roundedTR(value?: string | DynamicValue): StyleRule {
411
+ if (isDynamic(value)) {
412
+ return createDynamicRule(
413
+ { 'border-top-right-radius': `var(${value.__id})` },
414
+ { [value.__id]: String(value.__value) },
415
+ )
416
+ }
417
+ return createRule({ 'border-top-right-radius': (value as string | undefined) ?? defaultRadius })
418
+ }
419
+
420
+ export function roundedBR(value?: string | DynamicValue): StyleRule {
421
+ if (isDynamic(value)) {
422
+ return createDynamicRule(
423
+ { 'border-bottom-right-radius': `var(${value.__id})` },
424
+ { [value.__id]: String(value.__value) },
425
+ )
426
+ }
427
+ return createRule({ 'border-bottom-right-radius': (value as string | undefined) ?? defaultRadius })
428
+ }
429
+
430
+ export function roundedBL(value?: string | DynamicValue): StyleRule {
431
+ if (isDynamic(value)) {
432
+ return createDynamicRule(
433
+ { 'border-bottom-left-radius': `var(${value.__id})` },
434
+ { [value.__id]: String(value.__value) },
435
+ )
436
+ }
437
+ return createRule({ 'border-bottom-left-radius': (value as string | undefined) ?? defaultRadius })
438
+ }
439
+
440
+ export function roundedSS(value?: string | DynamicValue): StyleRule {
441
+ if (isDynamic(value)) {
442
+ return createDynamicRule(
443
+ { 'border-start-start-radius': `var(${value.__id})`, 'border-end-start-radius': `var(${value.__id})` },
444
+ { [value.__id]: String(value.__value) },
445
+ )
446
+ }
447
+ const v = (value as string | undefined) ?? defaultRadius
448
+ return createRule({ 'border-start-start-radius': v, 'border-end-start-radius': v })
449
+ }
450
+
451
+ export function roundedSE(value?: string | DynamicValue): StyleRule {
452
+ if (isDynamic(value)) {
453
+ return createDynamicRule(
454
+ { 'border-start-end-radius': `var(${value.__id})`, 'border-end-end-radius': `var(${value.__id})` },
455
+ { [value.__id]: String(value.__value) },
456
+ )
457
+ }
458
+ const v = (value as string | undefined) ?? defaultRadius
459
+ return createRule({ 'border-start-end-radius': v, 'border-end-end-radius': v })
460
+ }
461
+
462
+ export function roundedEE(value?: string | DynamicValue): StyleRule {
463
+ if (isDynamic(value)) {
464
+ return createDynamicRule(
465
+ { 'border-start-end-radius': `var(${value.__id})`, 'border-end-end-radius': `var(${value.__id})` },
466
+ { [value.__id]: String(value.__value) },
467
+ )
468
+ }
469
+ const v = (value as string | undefined) ?? defaultRadius
470
+ return createRule({ 'border-start-end-radius': v, 'border-end-end-radius': v })
471
+ }
472
+
473
+ export function roundedES(value?: string | DynamicValue): StyleRule {
474
+ if (isDynamic(value)) {
475
+ return createDynamicRule(
476
+ { 'border-end-start-radius': `var(${value.__id})`, 'border-start-start-radius': `var(${value.__id})` },
477
+ { [value.__id]: String(value.__value) },
478
+ )
479
+ }
480
+ const v = (value as string | undefined) ?? defaultRadius
481
+ return createRule({ 'border-end-start-radius': v, 'border-start-start-radius': v })
482
+ }
483
+
484
+ // --- Directional border width utilities ---
485
+
486
+ export function borderX(width?: string): StyleRule {
487
+ return createRule({ 'border-left-width': width ?? '1px', 'border-right-width': width ?? '1px', 'border-style': 'solid' })
488
+ }
489
+
490
+ export function borderY(width?: string): StyleRule {
491
+ return createRule({ 'border-top-width': width ?? '1px', 'border-bottom-width': width ?? '1px', 'border-style': 'solid' })
492
+ }
493
+
494
+ export function borderS(width?: string): StyleRule {
495
+ return createRule({ 'border-inline-start-width': width ?? '1px', 'border-style': 'solid' })
496
+ }
497
+
498
+ export function borderE(width?: string): StyleRule {
499
+ return createRule({ 'border-inline-end-width': width ?? '1px', 'border-style': 'solid' })
500
+ }
501
+
502
+ export function borderStyle(value: string): StyleRule {
503
+ return createRule({ 'border-style': value })
504
+ }
505
+
506
+ // --- Outline utilities ---
507
+
508
+ export function outlineWidth(value: string): StyleRule {
509
+ return createRule({ 'outline-width': value })
510
+ }
511
+
512
+ export function outlineColor(value: string | DynamicValue): StyleRule {
513
+ if (isDynamic(value)) {
514
+ return createDynamicRule(
515
+ { 'outline-color': `var(${value.__id})` },
516
+ { [value.__id]: String(value.__value) },
517
+ )
518
+ }
519
+ return createRule({ 'outline-color': value })
520
+ }
521
+
522
+ export function outlineStyle(value: string): StyleRule {
523
+ return createRule({ 'outline-style': value })
524
+ }
525
+
526
+ export function outlineOffset(value: string): StyleRule {
527
+ return createRule({ 'outline-offset': value })
528
+ }
529
+
530
+ export function outline(width?: string, style?: string, color?: string): StyleRule {
531
+ const decls: Record<string, string> = {}
532
+ decls['outline-width'] = width ?? '1px'
533
+ decls['outline-style'] = style ?? 'solid'
534
+ if (color) decls['outline-color'] = color
535
+ return createRule(decls)
536
+ }
537
+
538
+ export function outlineNone(): StyleRule {
539
+ return createRule({ outline: '2px solid transparent', 'outline-offset': '2px' })
540
+ }
541
+
542
+ // --- Ring utilities ---
543
+
544
+ export function ringInset(): StyleRule {
545
+ return createRule({ '--twc-ring-inset': 'inset' })
546
+ }
547
+
548
+ export function ringColor(value: string | DynamicValue): StyleRule {
549
+ if (isDynamic(value)) {
550
+ return createDynamicRule(
551
+ { '--twc-ring-color': `var(${value.__id})` },
552
+ { [value.__id]: String(value.__value) },
553
+ )
554
+ }
555
+ return createRule({ '--twc-ring-color': value })
556
+ }
557
+
558
+ export function ringOffsetWidth(value: string): StyleRule {
559
+ return createRule({ '--twc-ring-offset-width': value })
560
+ }
561
+
562
+ export function ringOffsetColor(value: string | DynamicValue): StyleRule {
563
+ if (isDynamic(value)) {
564
+ return createDynamicRule(
565
+ { '--twc-ring-offset-color': `var(${value.__id})` },
566
+ { [value.__id]: String(value.__value) },
567
+ )
568
+ }
569
+ return createRule({ '--twc-ring-offset-color': value })
570
+ }
571
+
572
+ // --- Divide utilities (selector-template-based) ---
573
+
574
+ export function divideX(width?: string): StyleRule {
575
+ const rule = createRule({ 'border-left-width': width ?? '1px', 'border-style': 'solid' })
576
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
577
+ }
578
+
579
+ export function divideY(width?: string): StyleRule {
580
+ const rule = createRule({ 'border-top-width': width ?? '1px', 'border-style': 'solid' })
581
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
582
+ }
583
+
584
+ export function divideColor(value: string | DynamicValue): StyleRule {
585
+ let rule: StyleRule
586
+ if (isDynamic(value)) {
587
+ rule = createDynamicRule(
588
+ { 'border-color': `var(${value.__id})` },
589
+ { [value.__id]: String(value.__value) },
590
+ )
591
+ } else {
592
+ rule = createRule({ 'border-color': value })
593
+ }
594
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
595
+ }
596
+
597
+ export function divideStyle(value: string): StyleRule {
598
+ const rule = createRule({ 'border-style': value })
599
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
600
+ }
601
+
602
+ export function divideXReverse(): StyleRule {
603
+ const rule = createRule({ '--twc-divide-x-reverse': '1' })
604
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
605
+ }
606
+
607
+ export function divideYReverse(): StyleRule {
608
+ const rule = createRule({ '--twc-divide-y-reverse': '1' })
609
+ return wrapWithSelectorTemplate(rule, '& > :not([hidden]) ~ :not([hidden])')
610
+ }