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.
- package/README.md +107 -0
- package/package.json +71 -0
- package/src/css.ts +140 -0
- package/src/cx.ts +105 -0
- package/src/dcx.ts +79 -0
- package/src/dynamic.ts +117 -0
- package/src/hash.ts +54 -0
- package/src/index.ts +137 -0
- package/src/inject.ts +86 -0
- package/src/layer.ts +81 -0
- package/src/modifiers/aria.ts +15 -0
- package/src/modifiers/colorScheme.ts +32 -0
- package/src/modifiers/data.ts +6 -0
- package/src/modifiers/direction.ts +5 -0
- package/src/modifiers/group.ts +21 -0
- package/src/modifiers/index.ts +17 -0
- package/src/modifiers/media.ts +11 -0
- package/src/modifiers/peer.ts +24 -0
- package/src/modifiers/pseudo.ts +183 -0
- package/src/modifiers/pseudoElements.ts +26 -0
- package/src/modifiers/responsive.ts +110 -0
- package/src/modifiers/supports.ts +6 -0
- package/src/registry.ts +171 -0
- package/src/rule.ts +202 -0
- package/src/runtime.ts +36 -0
- package/src/theme/animations.ts +11 -0
- package/src/theme/borders.ts +9 -0
- package/src/theme/colors.ts +326 -0
- package/src/theme/createTheme.ts +238 -0
- package/src/theme/filters.ts +20 -0
- package/src/theme/index.ts +9 -0
- package/src/theme/inject-theme.ts +81 -0
- package/src/theme/shadows.ts +8 -0
- package/src/theme/sizes.ts +37 -0
- package/src/theme/spacing.ts +44 -0
- package/src/theme/typography.ts +72 -0
- package/src/types.ts +273 -0
- package/src/utilities/accessibility.ts +33 -0
- package/src/utilities/backgrounds.ts +86 -0
- package/src/utilities/borders.ts +610 -0
- package/src/utilities/colors.ts +127 -0
- package/src/utilities/effects.ts +169 -0
- package/src/utilities/filters.ts +96 -0
- package/src/utilities/index.ts +57 -0
- package/src/utilities/interactivity.ts +253 -0
- package/src/utilities/layout.ts +1149 -0
- package/src/utilities/spacing.ts +681 -0
- package/src/utilities/svg.ts +34 -0
- package/src/utilities/tables.ts +54 -0
- package/src/utilities/transforms.ts +85 -0
- package/src/utilities/transitions.ts +98 -0
- package/src/utilities/typography.ts +380 -0
- package/src/when.ts +63 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { StyleRule } from '../types.ts'
|
|
2
|
+
import type { DynamicValue } from '../dynamic.ts'
|
|
3
|
+
import { createRule, createDynamicRule } from '../rule.ts'
|
|
4
|
+
import { resolveSpacing } from '../theme/spacing.ts'
|
|
5
|
+
import { isDynamic } from '../dynamic.ts'
|
|
6
|
+
|
|
7
|
+
export function borderCollapse(): StyleRule {
|
|
8
|
+
return createRule({ 'border-collapse': 'collapse' })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function borderSeparate(): StyleRule {
|
|
12
|
+
return createRule({ 'border-collapse': 'separate' })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function borderSpacing(value: number | string | DynamicValue): StyleRule {
|
|
16
|
+
if (isDynamic(value)) {
|
|
17
|
+
return createDynamicRule(
|
|
18
|
+
{ 'border-spacing': `var(${value.__id})` },
|
|
19
|
+
{ [value.__id]: String(value.__value) },
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
const v = typeof value === 'number' ? resolveSpacing(value) : value
|
|
23
|
+
return createRule({ 'border-spacing': v })
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function borderSpacingX(value: number | string | DynamicValue): StyleRule {
|
|
27
|
+
if (isDynamic(value)) {
|
|
28
|
+
return createDynamicRule(
|
|
29
|
+
{ 'border-spacing': `var(${value.__id}) 0` },
|
|
30
|
+
{ [value.__id]: String(value.__value) },
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
const v = typeof value === 'number' ? resolveSpacing(value) : value
|
|
34
|
+
return createRule({ 'border-spacing': `${v} 0` })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function borderSpacingY(value: number | string | DynamicValue): StyleRule {
|
|
38
|
+
if (isDynamic(value)) {
|
|
39
|
+
return createDynamicRule(
|
|
40
|
+
{ 'border-spacing': `0 var(${value.__id})` },
|
|
41
|
+
{ [value.__id]: String(value.__value) },
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
const v = typeof value === 'number' ? resolveSpacing(value) : value
|
|
45
|
+
return createRule({ 'border-spacing': `0 ${v}` })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function tableLayout(value: string): StyleRule {
|
|
49
|
+
return createRule({ 'table-layout': value })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function captionSide(value: string): StyleRule {
|
|
53
|
+
return createRule({ 'caption-side': value })
|
|
54
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { StyleRule } from '../types.ts'
|
|
2
|
+
import type { DynamicValue } from '../dynamic.ts'
|
|
3
|
+
import { createRule, createDynamicRule } from '../rule.ts'
|
|
4
|
+
import { isDynamic } from '../dynamic.ts'
|
|
5
|
+
|
|
6
|
+
function transformRule(fn: string, value: string | number | DynamicValue): StyleRule {
|
|
7
|
+
if (isDynamic(value)) {
|
|
8
|
+
return createDynamicRule(
|
|
9
|
+
{ transform: `${fn}(var(${value.__id}))` },
|
|
10
|
+
{ [value.__id]: String(value.__value) },
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
return createRule({ transform: `${fn}(${value})` })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function scale(value: string | number | DynamicValue): StyleRule {
|
|
17
|
+
if (isDynamic(value)) {
|
|
18
|
+
return createDynamicRule(
|
|
19
|
+
{ transform: `scale(var(${value.__id}))` },
|
|
20
|
+
{ [value.__id]: String(value.__value) },
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
const v = typeof value === 'number' ? String(value / 100) : value
|
|
24
|
+
return createRule({ transform: `scale(${v})` })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function scaleX(value: string | number | DynamicValue): StyleRule {
|
|
28
|
+
if (isDynamic(value)) {
|
|
29
|
+
return createDynamicRule(
|
|
30
|
+
{ transform: `scaleX(var(${value.__id}))` },
|
|
31
|
+
{ [value.__id]: String(value.__value) },
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
const v = typeof value === 'number' ? String(value / 100) : value
|
|
35
|
+
return createRule({ transform: `scaleX(${v})` })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function scaleY(value: string | number | DynamicValue): StyleRule {
|
|
39
|
+
if (isDynamic(value)) {
|
|
40
|
+
return createDynamicRule(
|
|
41
|
+
{ transform: `scaleY(var(${value.__id}))` },
|
|
42
|
+
{ [value.__id]: String(value.__value) },
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
const v = typeof value === 'number' ? String(value / 100) : value
|
|
46
|
+
return createRule({ transform: `scaleY(${v})` })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function rotate(value: string | DynamicValue): StyleRule {
|
|
50
|
+
return transformRule('rotate', value)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function translateX(value: string | DynamicValue): StyleRule {
|
|
54
|
+
return transformRule('translateX', value)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function translateY(value: string | DynamicValue): StyleRule {
|
|
58
|
+
return transformRule('translateY', value)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function skewX(value: string | DynamicValue): StyleRule {
|
|
62
|
+
return transformRule('skewX', value)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function skewY(value: string | DynamicValue): StyleRule {
|
|
66
|
+
return transformRule('skewY', value)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function transformOrigin(value: string | DynamicValue): StyleRule {
|
|
70
|
+
if (isDynamic(value)) {
|
|
71
|
+
return createDynamicRule(
|
|
72
|
+
{ 'transform-origin': `var(${value.__id})` },
|
|
73
|
+
{ [value.__id]: String(value.__value) },
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
return createRule({ 'transform-origin': value })
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function transformGpu(): StyleRule {
|
|
80
|
+
return createRule({ transform: 'translate3d(0, 0, 0)' })
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function transformNone(): StyleRule {
|
|
84
|
+
return createRule({ transform: 'none' })
|
|
85
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { StyleRule } from '../types.ts'
|
|
2
|
+
import type { DynamicValue } from '../dynamic.ts'
|
|
3
|
+
import { createRule, createDynamicRule } from '../rule.ts'
|
|
4
|
+
import { isDynamic } from '../dynamic.ts'
|
|
5
|
+
|
|
6
|
+
export function transition(): StyleRule {
|
|
7
|
+
return createRule({
|
|
8
|
+
'transition-property': 'color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter',
|
|
9
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
10
|
+
'transition-duration': '150ms',
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function transitionAll(): StyleRule {
|
|
15
|
+
return createRule({
|
|
16
|
+
'transition-property': 'all',
|
|
17
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
18
|
+
'transition-duration': '150ms',
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function transitionColors(): StyleRule {
|
|
23
|
+
return createRule({
|
|
24
|
+
'transition-property': 'color, background-color, border-color, text-decoration-color, fill, stroke',
|
|
25
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
26
|
+
'transition-duration': '150ms',
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function transitionOpacity(): StyleRule {
|
|
31
|
+
return createRule({
|
|
32
|
+
'transition-property': 'opacity',
|
|
33
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
34
|
+
'transition-duration': '150ms',
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function transitionShadow(): StyleRule {
|
|
39
|
+
return createRule({
|
|
40
|
+
'transition-property': 'box-shadow',
|
|
41
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
42
|
+
'transition-duration': '150ms',
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function transitionTransform(): StyleRule {
|
|
47
|
+
return createRule({
|
|
48
|
+
'transition-property': 'transform',
|
|
49
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
50
|
+
'transition-duration': '150ms',
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function transitionNone(): StyleRule {
|
|
55
|
+
return createRule({ 'transition-property': 'none' })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function duration(value: string | number | DynamicValue): StyleRule {
|
|
59
|
+
if (isDynamic(value)) {
|
|
60
|
+
return createDynamicRule(
|
|
61
|
+
{ 'transition-duration': `var(${value.__id})` },
|
|
62
|
+
{ [value.__id]: String(value.__value) },
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
const v = typeof value === 'number' ? `${value}ms` : value
|
|
66
|
+
return createRule({ 'transition-duration': v })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function ease(value: string | DynamicValue): StyleRule {
|
|
70
|
+
if (isDynamic(value)) {
|
|
71
|
+
return createDynamicRule(
|
|
72
|
+
{ 'transition-timing-function': `var(${value.__id})` },
|
|
73
|
+
{ [value.__id]: String(value.__value) },
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
return createRule({ 'transition-timing-function': value })
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function delay(value: string | number | DynamicValue): StyleRule {
|
|
80
|
+
if (isDynamic(value)) {
|
|
81
|
+
return createDynamicRule(
|
|
82
|
+
{ 'transition-delay': `var(${value.__id})` },
|
|
83
|
+
{ [value.__id]: String(value.__value) },
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
const v = typeof value === 'number' ? `${value}ms` : value
|
|
87
|
+
return createRule({ 'transition-delay': v })
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function animate(value: string | DynamicValue): StyleRule {
|
|
91
|
+
if (isDynamic(value)) {
|
|
92
|
+
return createDynamicRule(
|
|
93
|
+
{ animation: `var(${value.__id})` },
|
|
94
|
+
{ [value.__id]: String(value.__value) },
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
return createRule({ animation: value })
|
|
98
|
+
}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import type { StyleRule } from '../types.ts'
|
|
2
|
+
import type { TextSize } from '../theme/typography.ts'
|
|
3
|
+
import type { DynamicValue } from '../dynamic.ts'
|
|
4
|
+
import { createRule, createDynamicRule } from '../rule.ts'
|
|
5
|
+
import { isDynamic } from '../dynamic.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sets the font size (and optionally line height) of an element.
|
|
9
|
+
*
|
|
10
|
+
* Accepts a {@link TextSize} object from the typography theme (which sets both
|
|
11
|
+
* `font-size` and `line-height`), a raw CSS string for `font-size` only,
|
|
12
|
+
* or a {@link DynamicValue} for runtime values.
|
|
13
|
+
*
|
|
14
|
+
* @param size - A {@link TextSize} preset (e.g. `typography.base`), a raw CSS string (`'1.5rem'`), or `dynamic()` value.
|
|
15
|
+
* @returns A {@link StyleRule} that sets `font-size` and optionally `line-height`.
|
|
16
|
+
*
|
|
17
|
+
* @example TextSize preset
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { cx, text } from 'typewritingclass'
|
|
20
|
+
* import * as typography from 'typewritingclass/theme/typography'
|
|
21
|
+
*
|
|
22
|
+
* cx(text(typography.lg))
|
|
23
|
+
* // CSS: font-size: 1.125rem; line-height: 1.75rem;
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example Raw value
|
|
27
|
+
* ```ts
|
|
28
|
+
* cx(text('2rem'))
|
|
29
|
+
* // CSS: font-size: 2rem;
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example Dynamic value
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { dcx, text, dynamic } from 'typewritingclass'
|
|
35
|
+
*
|
|
36
|
+
* const { className, style } = dcx(text(dynamic(fontSize)))
|
|
37
|
+
* // CSS: font-size: var(--twc-d0);
|
|
38
|
+
* // style: { '--twc-d0': fontSize }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function text(size: TextSize | string | DynamicValue): StyleRule {
|
|
42
|
+
if (isDynamic(size)) {
|
|
43
|
+
return createDynamicRule(
|
|
44
|
+
{ 'font-size': `var(${size.__id})` },
|
|
45
|
+
{ [size.__id]: String(size.__value) },
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
if (typeof size === 'string') {
|
|
49
|
+
return createRule({ 'font-size': size })
|
|
50
|
+
}
|
|
51
|
+
return createRule({ 'font-size': size.fontSize, 'line-height': size.lineHeight })
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sets the font weight of an element.
|
|
56
|
+
*
|
|
57
|
+
* Accepts a raw CSS font-weight string or a {@link DynamicValue} for runtime values.
|
|
58
|
+
* Use the typography theme exports (e.g. `typography.bold`) for standard weights.
|
|
59
|
+
*
|
|
60
|
+
* @param weight - A font-weight string (`'700'`, `'bold'`) or `dynamic()` value.
|
|
61
|
+
* @returns A {@link StyleRule} that sets `font-weight`.
|
|
62
|
+
*
|
|
63
|
+
* @example Typography theme weight
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { cx, font } from 'typewritingclass'
|
|
66
|
+
* import * as typography from 'typewritingclass/theme/typography'
|
|
67
|
+
*
|
|
68
|
+
* cx(font(typography.bold))
|
|
69
|
+
* // CSS: font-weight: 700;
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @example Raw value
|
|
73
|
+
* ```ts
|
|
74
|
+
* cx(font('600'))
|
|
75
|
+
* // CSS: font-weight: 600;
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example Dynamic value
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { dcx, font, dynamic } from 'typewritingclass'
|
|
81
|
+
*
|
|
82
|
+
* const { className, style } = dcx(font(dynamic(weight)))
|
|
83
|
+
* // CSS: font-weight: var(--twc-d0);
|
|
84
|
+
* // style: { '--twc-d0': weight }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function font(weight: string | DynamicValue): StyleRule {
|
|
88
|
+
if (isDynamic(weight)) {
|
|
89
|
+
return createDynamicRule(
|
|
90
|
+
{ 'font-weight': `var(${weight.__id})` },
|
|
91
|
+
{ [weight.__id]: String(weight.__value) },
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
return createRule({ 'font-weight': weight })
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sets the letter spacing (tracking) of an element.
|
|
99
|
+
*
|
|
100
|
+
* Accepts a raw CSS letter-spacing string or a {@link DynamicValue} for runtime values.
|
|
101
|
+
*
|
|
102
|
+
* @param value - A CSS letter-spacing string (`'-0.025em'`, `'0.05em'`) or `dynamic()` value.
|
|
103
|
+
* @returns A {@link StyleRule} that sets `letter-spacing`.
|
|
104
|
+
*
|
|
105
|
+
* @example Raw value
|
|
106
|
+
* ```ts
|
|
107
|
+
* import { cx, tracking } from 'typewritingclass'
|
|
108
|
+
*
|
|
109
|
+
* cx(tracking('-0.025em'))
|
|
110
|
+
* // CSS: letter-spacing: -0.025em;
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @example Wide tracking
|
|
114
|
+
* ```ts
|
|
115
|
+
* cx(tracking('0.1em'))
|
|
116
|
+
* // CSS: letter-spacing: 0.1em;
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @example Dynamic value
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { dcx, tracking, dynamic } from 'typewritingclass'
|
|
122
|
+
*
|
|
123
|
+
* const { className, style } = dcx(tracking(dynamic(letterSpacing)))
|
|
124
|
+
* // CSS: letter-spacing: var(--twc-d0);
|
|
125
|
+
* // style: { '--twc-d0': letterSpacing }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export function tracking(value: string | DynamicValue): StyleRule {
|
|
129
|
+
if (isDynamic(value)) {
|
|
130
|
+
return createDynamicRule(
|
|
131
|
+
{ 'letter-spacing': `var(${value.__id})` },
|
|
132
|
+
{ [value.__id]: String(value.__value) },
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
return createRule({ 'letter-spacing': value })
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Sets the line height (leading) of an element.
|
|
140
|
+
*
|
|
141
|
+
* Accepts a raw CSS line-height string or a {@link DynamicValue} for runtime values.
|
|
142
|
+
*
|
|
143
|
+
* @param value - A CSS line-height string (`'1.5'`, `'2rem'`) or `dynamic()` value.
|
|
144
|
+
* @returns A {@link StyleRule} that sets `line-height`.
|
|
145
|
+
*
|
|
146
|
+
* @example Unitless ratio
|
|
147
|
+
* ```ts
|
|
148
|
+
* import { cx, leading } from 'typewritingclass'
|
|
149
|
+
*
|
|
150
|
+
* cx(leading('1.5'))
|
|
151
|
+
* // CSS: line-height: 1.5;
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example Fixed value
|
|
155
|
+
* ```ts
|
|
156
|
+
* cx(leading('2rem'))
|
|
157
|
+
* // CSS: line-height: 2rem;
|
|
158
|
+
* ```
|
|
159
|
+
*
|
|
160
|
+
* @example Dynamic value
|
|
161
|
+
* ```ts
|
|
162
|
+
* import { dcx, leading, dynamic } from 'typewritingclass'
|
|
163
|
+
*
|
|
164
|
+
* const { className, style } = dcx(leading(dynamic(lineHeight)))
|
|
165
|
+
* // CSS: line-height: var(--twc-d0);
|
|
166
|
+
* // style: { '--twc-d0': lineHeight }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export function leading(value: string | DynamicValue): StyleRule {
|
|
170
|
+
if (isDynamic(value)) {
|
|
171
|
+
return createDynamicRule(
|
|
172
|
+
{ 'line-height': `var(${value.__id})` },
|
|
173
|
+
{ [value.__id]: String(value.__value) },
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
return createRule({ 'line-height': value })
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Sets the text alignment of an element.
|
|
181
|
+
*
|
|
182
|
+
* Accepts a raw CSS text-align string.
|
|
183
|
+
*
|
|
184
|
+
* @param value - A CSS text-align value (`'left'`, `'center'`, `'right'`, `'justify'`).
|
|
185
|
+
* @returns A {@link StyleRule} that sets `text-align`.
|
|
186
|
+
*
|
|
187
|
+
* @example Center alignment
|
|
188
|
+
* ```ts
|
|
189
|
+
* import { cx, textAlign } from 'typewritingclass'
|
|
190
|
+
*
|
|
191
|
+
* cx(textAlign('center'))
|
|
192
|
+
* // CSS: text-align: center;
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @example Right alignment
|
|
196
|
+
* ```ts
|
|
197
|
+
* cx(textAlign('right'))
|
|
198
|
+
* // CSS: text-align: right;
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export function textAlign(value: string): StyleRule {
|
|
202
|
+
return createRule({ 'text-align': value })
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function fontFamily(value: string | DynamicValue): StyleRule {
|
|
206
|
+
if (isDynamic(value)) {
|
|
207
|
+
return createDynamicRule(
|
|
208
|
+
{ 'font-family': `var(${value.__id})` },
|
|
209
|
+
{ [value.__id]: String(value.__value) },
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
return createRule({ 'font-family': value })
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function antialiased(): StyleRule {
|
|
216
|
+
return createRule({
|
|
217
|
+
'-webkit-font-smoothing': 'antialiased',
|
|
218
|
+
'-moz-osx-font-smoothing': 'grayscale',
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function subpixelAntialiased(): StyleRule {
|
|
223
|
+
return createRule({
|
|
224
|
+
'-webkit-font-smoothing': 'auto',
|
|
225
|
+
'-moz-osx-font-smoothing': 'auto',
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function italic(): StyleRule {
|
|
230
|
+
return createRule({ 'font-style': 'italic' })
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function notItalic(): StyleRule {
|
|
234
|
+
return createRule({ 'font-style': 'normal' })
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function normalNums(): StyleRule {
|
|
238
|
+
return createRule({ 'font-variant-numeric': 'normal' })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export function ordinal(): StyleRule {
|
|
242
|
+
return createRule({ 'font-variant-numeric': 'ordinal' })
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function slashedZero(): StyleRule {
|
|
246
|
+
return createRule({ 'font-variant-numeric': 'slashed-zero' })
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function liningNums(): StyleRule {
|
|
250
|
+
return createRule({ 'font-variant-numeric': 'lining-nums' })
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export function oldstyleNums(): StyleRule {
|
|
254
|
+
return createRule({ 'font-variant-numeric': 'oldstyle-nums' })
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function proportionalNums(): StyleRule {
|
|
258
|
+
return createRule({ 'font-variant-numeric': 'proportional-nums' })
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function tabularNums(): StyleRule {
|
|
262
|
+
return createRule({ 'font-variant-numeric': 'tabular-nums' })
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function diagonalFractions(): StyleRule {
|
|
266
|
+
return createRule({ 'font-variant-numeric': 'diagonal-fractions' })
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export function stackedFractions(): StyleRule {
|
|
270
|
+
return createRule({ 'font-variant-numeric': 'stacked-fractions' })
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function lineClamp(value: number): StyleRule {
|
|
274
|
+
return createRule({
|
|
275
|
+
overflow: 'hidden',
|
|
276
|
+
display: '-webkit-box',
|
|
277
|
+
'-webkit-box-orient': 'vertical',
|
|
278
|
+
'-webkit-line-clamp': String(value),
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function listStyleImage(value: string): StyleRule {
|
|
283
|
+
return createRule({ 'list-style-image': value })
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function listStylePosition(value: string): StyleRule {
|
|
287
|
+
return createRule({ 'list-style-position': value })
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function listStyleType(value: string): StyleRule {
|
|
291
|
+
return createRule({ 'list-style-type': value })
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export function textDecoration(value: string): StyleRule {
|
|
295
|
+
return createRule({ 'text-decoration-line': value })
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export function textDecorationColor(value: string | DynamicValue): StyleRule {
|
|
299
|
+
if (isDynamic(value)) {
|
|
300
|
+
return createDynamicRule(
|
|
301
|
+
{ 'text-decoration-color': `var(${value.__id})` },
|
|
302
|
+
{ [value.__id]: String(value.__value) },
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
return createRule({ 'text-decoration-color': value })
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function textDecorationStyle(value: string): StyleRule {
|
|
309
|
+
return createRule({ 'text-decoration-style': value })
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function textDecorationThickness(value: string | DynamicValue): StyleRule {
|
|
313
|
+
if (isDynamic(value)) {
|
|
314
|
+
return createDynamicRule(
|
|
315
|
+
{ 'text-decoration-thickness': `var(${value.__id})` },
|
|
316
|
+
{ [value.__id]: String(value.__value) },
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
return createRule({ 'text-decoration-thickness': value })
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function textUnderlineOffset(value: string | DynamicValue): StyleRule {
|
|
323
|
+
if (isDynamic(value)) {
|
|
324
|
+
return createDynamicRule(
|
|
325
|
+
{ 'text-underline-offset': `var(${value.__id})` },
|
|
326
|
+
{ [value.__id]: String(value.__value) },
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
return createRule({ 'text-underline-offset': value })
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function textTransform(value: string): StyleRule {
|
|
333
|
+
return createRule({ 'text-transform': value })
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function textOverflow(value: string): StyleRule {
|
|
337
|
+
return createRule({ 'text-overflow': value })
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function textWrap(value: string): StyleRule {
|
|
341
|
+
return createRule({ 'text-wrap': value })
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export function textIndent(value: string | DynamicValue): StyleRule {
|
|
345
|
+
if (isDynamic(value)) {
|
|
346
|
+
return createDynamicRule(
|
|
347
|
+
{ 'text-indent': `var(${value.__id})` },
|
|
348
|
+
{ [value.__id]: String(value.__value) },
|
|
349
|
+
)
|
|
350
|
+
}
|
|
351
|
+
return createRule({ 'text-indent': value })
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export function verticalAlign(value: string): StyleRule {
|
|
355
|
+
return createRule({ 'vertical-align': value })
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export function whitespace(value: string): StyleRule {
|
|
359
|
+
return createRule({ 'white-space': value })
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export function wordBreak(value: string): StyleRule {
|
|
363
|
+
return createRule({ 'word-break': value })
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export function hyphens(value: string): StyleRule {
|
|
367
|
+
return createRule({ hyphens: value })
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function content_(value: string): StyleRule {
|
|
371
|
+
return createRule({ content: value })
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export function truncate(): StyleRule {
|
|
375
|
+
return createRule({
|
|
376
|
+
overflow: 'hidden',
|
|
377
|
+
'text-overflow': 'ellipsis',
|
|
378
|
+
'white-space': 'nowrap',
|
|
379
|
+
})
|
|
380
|
+
}
|
package/src/when.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { StyleRule, Modifier } from './types.ts'
|
|
2
|
+
import { combineRules } from './rule.ts'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a conditional style applicator by composing one or more modifiers.
|
|
6
|
+
*
|
|
7
|
+
* Returns a function that accepts style rules and wraps them with the given
|
|
8
|
+
* modifiers applied right-to-left (innermost modifier listed first). This
|
|
9
|
+
* lets you express multi-condition rules like "on hover at the `md` breakpoint"
|
|
10
|
+
* in a readable, composable way.
|
|
11
|
+
*
|
|
12
|
+
* Multiple style rules passed to the returned function are merged into a single
|
|
13
|
+
* combined rule before modifiers are applied, so selectors and media queries
|
|
14
|
+
* are shared across all declarations.
|
|
15
|
+
*
|
|
16
|
+
* @param modifiers - One or more {@link Modifier} functions (e.g. `hover`, `md`, `dark`)
|
|
17
|
+
* applied right-to-left around the inner rules.
|
|
18
|
+
* @returns A function that accepts {@link StyleRule}s and returns a single
|
|
19
|
+
* modifier-wrapped `StyleRule`.
|
|
20
|
+
*
|
|
21
|
+
* @example Single modifier -- hover state
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { cx, bg, when, hover } from 'typewritingclass'
|
|
24
|
+
* import { blue } from 'typewritingclass/theme/colors'
|
|
25
|
+
*
|
|
26
|
+
* cx(when(hover)(bg(blue[600])))
|
|
27
|
+
* // CSS: .cls:hover { background-color: #2563eb; }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Stacked modifiers -- hover at medium breakpoint
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { cx, bg, p, when, hover, md } from 'typewritingclass'
|
|
33
|
+
* import { blue } from 'typewritingclass/theme/colors'
|
|
34
|
+
*
|
|
35
|
+
* cx(when(hover, md)(bg(blue[700]), p(8)))
|
|
36
|
+
* // CSS:
|
|
37
|
+
* // @media (min-width: 768px) {
|
|
38
|
+
* // .cls:hover { background-color: #1d4ed8; padding: 2rem; }
|
|
39
|
+
* // }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Dark mode styling
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { cx, bg, textColor, when, dark } from 'typewritingclass'
|
|
45
|
+
* import { slate, white } from 'typewritingclass/theme/colors'
|
|
46
|
+
*
|
|
47
|
+
* cx(
|
|
48
|
+
* bg(white),
|
|
49
|
+
* textColor(slate[900]),
|
|
50
|
+
* when(dark)(bg(slate[900]), textColor(white)),
|
|
51
|
+
* )
|
|
52
|
+
* // CSS:
|
|
53
|
+
* // .cls1 { background-color: #ffffff; }
|
|
54
|
+
* // .cls2 { color: #0f172a; }
|
|
55
|
+
* // .dark .cls3 { background-color: #0f172a; color: #ffffff; }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function when(...modifiers: Modifier[]) {
|
|
59
|
+
return (...rules: StyleRule[]): StyleRule => {
|
|
60
|
+
const combined = combineRules(rules)
|
|
61
|
+
return modifiers.reduceRight((acc, mod) => mod(acc), combined)
|
|
62
|
+
}
|
|
63
|
+
}
|