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,37 @@
|
|
|
1
|
+
export const full = '100%'
|
|
2
|
+
export const screen = '100vw'
|
|
3
|
+
export const screenH = '100vh'
|
|
4
|
+
export const min = 'min-content'
|
|
5
|
+
export const max = 'max-content'
|
|
6
|
+
export const fit = 'fit-content'
|
|
7
|
+
export const auto = 'auto'
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Max-width scale (Tailwind v3 defaults)
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
export const maxWidths = {
|
|
14
|
+
none: 'none',
|
|
15
|
+
0: '0rem',
|
|
16
|
+
xs: '20rem',
|
|
17
|
+
sm: '24rem',
|
|
18
|
+
md: '28rem',
|
|
19
|
+
lg: '32rem',
|
|
20
|
+
xl: '36rem',
|
|
21
|
+
'2xl': '42rem',
|
|
22
|
+
'3xl': '48rem',
|
|
23
|
+
'4xl': '56rem',
|
|
24
|
+
'5xl': '64rem',
|
|
25
|
+
'6xl': '72rem',
|
|
26
|
+
'7xl': '80rem',
|
|
27
|
+
full: '100%',
|
|
28
|
+
min: 'min-content',
|
|
29
|
+
max: 'max-content',
|
|
30
|
+
fit: 'fit-content',
|
|
31
|
+
prose: '65ch',
|
|
32
|
+
screenSm: '640px',
|
|
33
|
+
screenMd: '768px',
|
|
34
|
+
screenLg: '1024px',
|
|
35
|
+
screenXl: '1280px',
|
|
36
|
+
screen2xl: '1536px',
|
|
37
|
+
} as const
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const spacingScale: Record<number, string> = {
|
|
2
|
+
0: '0px',
|
|
3
|
+
0.5: '0.125rem',
|
|
4
|
+
1: '0.25rem',
|
|
5
|
+
1.5: '0.375rem',
|
|
6
|
+
2: '0.5rem',
|
|
7
|
+
2.5: '0.625rem',
|
|
8
|
+
3: '0.75rem',
|
|
9
|
+
3.5: '0.875rem',
|
|
10
|
+
4: '1rem',
|
|
11
|
+
5: '1.25rem',
|
|
12
|
+
6: '1.5rem',
|
|
13
|
+
7: '1.75rem',
|
|
14
|
+
8: '2rem',
|
|
15
|
+
9: '2.25rem',
|
|
16
|
+
10: '2.5rem',
|
|
17
|
+
11: '2.75rem',
|
|
18
|
+
12: '3rem',
|
|
19
|
+
14: '3.5rem',
|
|
20
|
+
16: '4rem',
|
|
21
|
+
20: '5rem',
|
|
22
|
+
24: '6rem',
|
|
23
|
+
28: '7rem',
|
|
24
|
+
32: '8rem',
|
|
25
|
+
36: '9rem',
|
|
26
|
+
40: '10rem',
|
|
27
|
+
44: '11rem',
|
|
28
|
+
48: '12rem',
|
|
29
|
+
52: '13rem',
|
|
30
|
+
56: '14rem',
|
|
31
|
+
60: '15rem',
|
|
32
|
+
64: '16rem',
|
|
33
|
+
72: '18rem',
|
|
34
|
+
80: '20rem',
|
|
35
|
+
96: '24rem',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function resolveSpacing(value: number | string): string {
|
|
39
|
+
if (typeof value === 'string') return value
|
|
40
|
+
if (value in spacingScale) return spacingScale[value]
|
|
41
|
+
return `${value * 0.25}rem`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { spacingScale }
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface TextSize {
|
|
2
|
+
fontSize: string
|
|
3
|
+
lineHeight: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export const xs: TextSize = { fontSize: '0.75rem', lineHeight: '1rem' }
|
|
7
|
+
export const sm: TextSize = { fontSize: '0.875rem', lineHeight: '1.25rem' }
|
|
8
|
+
export const base: TextSize = { fontSize: '1rem', lineHeight: '1.5rem' }
|
|
9
|
+
export const lg: TextSize = { fontSize: '1.125rem', lineHeight: '1.75rem' }
|
|
10
|
+
export const xl: TextSize = { fontSize: '1.25rem', lineHeight: '1.75rem' }
|
|
11
|
+
export const _2xl: TextSize = { fontSize: '1.5rem', lineHeight: '2rem' }
|
|
12
|
+
export const _3xl: TextSize = { fontSize: '1.875rem', lineHeight: '2.25rem' }
|
|
13
|
+
export const _4xl: TextSize = { fontSize: '2.25rem', lineHeight: '2.5rem' }
|
|
14
|
+
export const _5xl: TextSize = { fontSize: '3rem', lineHeight: '1' }
|
|
15
|
+
export const _6xl: TextSize = { fontSize: '3.75rem', lineHeight: '1' }
|
|
16
|
+
export const _7xl: TextSize = { fontSize: '4.5rem', lineHeight: '1' }
|
|
17
|
+
export const _8xl: TextSize = { fontSize: '6rem', lineHeight: '1' }
|
|
18
|
+
export const _9xl: TextSize = { fontSize: '8rem', lineHeight: '1' }
|
|
19
|
+
|
|
20
|
+
export const thin = '100'
|
|
21
|
+
export const extralight = '200'
|
|
22
|
+
export const light = '300'
|
|
23
|
+
export const normal = '400'
|
|
24
|
+
export const medium = '500'
|
|
25
|
+
export const semibold = '600'
|
|
26
|
+
export const bold = '700'
|
|
27
|
+
export const extrabold = '800'
|
|
28
|
+
export const black_ = '900'
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Font families (Tailwind v3 defaults)
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
export const fontFamilies = {
|
|
35
|
+
sans: 'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
|
36
|
+
serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
|
|
37
|
+
mono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
38
|
+
} as const
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Letter spacing / tracking (Tailwind v3 defaults)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
export const letterSpacings = {
|
|
45
|
+
tighter: '-0.05em',
|
|
46
|
+
tight: '-0.025em',
|
|
47
|
+
normal: '0em',
|
|
48
|
+
wide: '0.025em',
|
|
49
|
+
wider: '0.05em',
|
|
50
|
+
widest: '0.1em',
|
|
51
|
+
} as const
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Line height / leading (Tailwind v3 defaults)
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
export const lineHeights = {
|
|
58
|
+
none: '1',
|
|
59
|
+
tight: '1.25',
|
|
60
|
+
snug: '1.375',
|
|
61
|
+
normal: '1.5',
|
|
62
|
+
relaxed: '1.625',
|
|
63
|
+
loose: '2',
|
|
64
|
+
'3': '.75rem',
|
|
65
|
+
'4': '1rem',
|
|
66
|
+
'5': '1.25rem',
|
|
67
|
+
'6': '1.5rem',
|
|
68
|
+
'7': '1.75rem',
|
|
69
|
+
'8': '2rem',
|
|
70
|
+
'9': '2.25rem',
|
|
71
|
+
'10': '2.5rem',
|
|
72
|
+
} as const
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Brand infrastructure
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
declare const __brand: unique symbol
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates a nominal/branded type from a base type.
|
|
9
|
+
*
|
|
10
|
+
* Branded types look like their base type at runtime but are distinct at the
|
|
11
|
+
* type level, preventing accidental misuse (e.g. passing a color where a
|
|
12
|
+
* spacing value is expected).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* type Meters = Brand<number, 'meters'>
|
|
17
|
+
* type Seconds = Brand<number, 'seconds'>
|
|
18
|
+
*
|
|
19
|
+
* const d: Meters = 5 as Meters
|
|
20
|
+
* const t: Seconds = d // Type error — distinct brands!
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type Brand<T, B extends string> = T & { readonly [__brand]: B }
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// CSS value brands
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A branded CSS color value — hex, `rgb()`, `hsl()`, CSS variable, etc.
|
|
31
|
+
*
|
|
32
|
+
* Theme color tokens (e.g. `blue[500]`) carry this brand. Raw color strings
|
|
33
|
+
* are also accepted alongside `CSSColor` since utility functions accept both.
|
|
34
|
+
*/
|
|
35
|
+
export type CSSColor = Brand<string, 'css-color'>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A branded CSS length value — `rem`, `px`, `em`, `%`, `vh`, `vw`, etc.
|
|
39
|
+
*
|
|
40
|
+
* Theme spacing, size, and border-radius tokens carry this brand.
|
|
41
|
+
*/
|
|
42
|
+
export type CSSLength = Brand<string, 'css-length'>
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A branded CSS shadow value — `box-shadow` definition string.
|
|
46
|
+
*
|
|
47
|
+
* Theme shadow tokens (e.g. `lg` from `theme/shadows`) carry this brand.
|
|
48
|
+
*/
|
|
49
|
+
export type CSSShadow = Brand<string, 'css-shadow'>
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A branded CSS font-weight value — numeric string like `'400'` or `'700'`.
|
|
53
|
+
*
|
|
54
|
+
* Theme font weight tokens (e.g. `bold`, `semibold`) carry this brand.
|
|
55
|
+
*/
|
|
56
|
+
export type CSSFontWeight = Brand<string, 'css-font-weight'>
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Utility input types
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
/** Shorthand for any DynamicValue — used in utility input types. */
|
|
63
|
+
type DynamicValueAny = import('./dynamic.ts').DynamicValue
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Input type for color utilities ({@link bg}, {@link textColor}, {@link borderColor}).
|
|
67
|
+
*
|
|
68
|
+
* Accepts theme color tokens (`CSSColor`), raw CSS color strings, or dynamic values.
|
|
69
|
+
*/
|
|
70
|
+
export type ColorInput = CSSColor | string | DynamicValueAny
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Input type for spacing utilities ({@link p}, {@link m}, {@link gap}).
|
|
74
|
+
*
|
|
75
|
+
* Accepts a theme scale number (`4` → `1rem`), a raw CSS length string
|
|
76
|
+
* (`'1.5rem'`), a theme length token, or a dynamic value.
|
|
77
|
+
*/
|
|
78
|
+
export type SpacingInput = number | CSSLength | string | DynamicValueAny
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Input type for size utilities ({@link w}, {@link h}, {@link minW}).
|
|
82
|
+
*
|
|
83
|
+
* Accepts a theme scale number, a raw CSS string (`'100%'`), a theme size
|
|
84
|
+
* token (`full`, `screen`), or a dynamic value.
|
|
85
|
+
*/
|
|
86
|
+
export type SizeInput = number | CSSLength | string | DynamicValueAny
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Input type for border-radius utilities ({@link rounded}).
|
|
90
|
+
*
|
|
91
|
+
* Accepts a theme radius token (`lg`), a raw CSS string, or a dynamic value.
|
|
92
|
+
*/
|
|
93
|
+
export type RadiusInput = CSSLength | string | DynamicValueAny
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Input type for shadow utilities ({@link shadow}).
|
|
97
|
+
*
|
|
98
|
+
* Accepts a theme shadow token (`lg`), a raw CSS string, or a dynamic value.
|
|
99
|
+
*/
|
|
100
|
+
export type ShadowInput = CSSShadow | string | DynamicValueAny
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Core types
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A self-contained CSS rule produced by utility functions, the {@link css}
|
|
108
|
+
* helper, or modifier composition.
|
|
109
|
+
*
|
|
110
|
+
* `StyleRule` is the fundamental unit of the typewritingclass system. Every
|
|
111
|
+
* utility (`p`, `bg`, `rounded`, ...) returns a `StyleRule`, and composing
|
|
112
|
+
* functions like `cx` and `dcx` consume them to generate class names and
|
|
113
|
+
* register CSS in the global stylesheet.
|
|
114
|
+
*
|
|
115
|
+
* You rarely need to construct a `StyleRule` by hand -- use the provided
|
|
116
|
+
* utilities or the `css` tagged-template helper instead.
|
|
117
|
+
*
|
|
118
|
+
* @example Inspecting a rule returned by a utility
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { p } from 'typewritingclass'
|
|
121
|
+
*
|
|
122
|
+
* const rule = p(4)
|
|
123
|
+
* // rule.declarations => { padding: '1rem' }
|
|
124
|
+
* // rule.selectors => []
|
|
125
|
+
* // rule.mediaQueries => []
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @example A rule wrapped with a modifier
|
|
129
|
+
* ```ts
|
|
130
|
+
* import { p, hover } from 'typewritingclass'
|
|
131
|
+
*
|
|
132
|
+
* const rule = hover(p(4))
|
|
133
|
+
* // rule.selectors => [':hover']
|
|
134
|
+
* // CSS: .className:hover { padding: 1rem; }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export interface StyleRule {
|
|
138
|
+
/** Discriminant tag used for runtime type narrowing. Always `'StyleRule'`. */
|
|
139
|
+
_tag: 'StyleRule'
|
|
140
|
+
/**
|
|
141
|
+
* A map of CSS property-value pairs that this rule will emit.
|
|
142
|
+
*
|
|
143
|
+
* Keys are CSS property names (e.g. `'padding'`, `'background-color'`),
|
|
144
|
+
* and values are their corresponding CSS values (e.g. `'1rem'`, `'#3b82f6'`).
|
|
145
|
+
*/
|
|
146
|
+
declarations: Record<string, string>
|
|
147
|
+
/**
|
|
148
|
+
* Pseudo-class or pseudo-element selectors appended to the generated
|
|
149
|
+
* class name (e.g. `[':hover']`, `[':focus', ':active']`).
|
|
150
|
+
*
|
|
151
|
+
* An empty array means the rule applies unconditionally.
|
|
152
|
+
*/
|
|
153
|
+
selectors: string[]
|
|
154
|
+
/**
|
|
155
|
+
* Media query strings that wrap the generated rule
|
|
156
|
+
* (e.g. `['(min-width: 768px)']`).
|
|
157
|
+
*
|
|
158
|
+
* An empty array means no `@media` wrapper is emitted.
|
|
159
|
+
*/
|
|
160
|
+
mediaQueries: string[]
|
|
161
|
+
/**
|
|
162
|
+
* CSS custom property bindings for dynamic (runtime-changeable) values.
|
|
163
|
+
*
|
|
164
|
+
* When present, the generated CSS references `var(--twc-dN)` and these
|
|
165
|
+
* bindings must be applied as inline `style` on the element (via `dcx`).
|
|
166
|
+
* Keys are CSS custom property names (e.g. `'--twc-d0'`), values are
|
|
167
|
+
* the current runtime values (e.g. `'#ff0000'`).
|
|
168
|
+
*/
|
|
169
|
+
dynamicBindings?: Record<string, string>
|
|
170
|
+
/**
|
|
171
|
+
* `@supports` query strings that wrap the generated rule
|
|
172
|
+
* (e.g. `['(display: grid)']`).
|
|
173
|
+
*
|
|
174
|
+
* An empty array means no `@supports` wrapper is emitted.
|
|
175
|
+
*/
|
|
176
|
+
supportsQueries: string[]
|
|
177
|
+
/**
|
|
178
|
+
* Optional selector template that wraps the generated class name in a
|
|
179
|
+
* more complex selector pattern. The `&` character is replaced with the
|
|
180
|
+
* generated `.className` at render time.
|
|
181
|
+
*
|
|
182
|
+
* Used for utilities like `spaceX`/`spaceY` (child combinator selectors),
|
|
183
|
+
* `group-*` / `peer-*` modifiers, and `rtl`/`ltr` direction modifiers.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* // spaceX uses: '& > :not([hidden]) ~ :not([hidden])'
|
|
188
|
+
* // group-hover uses: '.group:hover &'
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
selectorTemplate?: string
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* A function that accepts a design-token value and returns a {@link StyleRule}.
|
|
196
|
+
*
|
|
197
|
+
* Every spacing, color, typography, and layout helper (`p`, `bg`, `text`, ...)
|
|
198
|
+
* satisfies this signature. The `value` parameter is intentionally `any` so
|
|
199
|
+
* that individual utilities can narrow it to their own accepted types
|
|
200
|
+
* (e.g. `number | string | DynamicValue`).
|
|
201
|
+
*
|
|
202
|
+
* @param value - The design-token or raw CSS value to apply.
|
|
203
|
+
* @returns A {@link StyleRule} containing the appropriate CSS declarations.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* import type { Utility } from 'typewritingclass'
|
|
208
|
+
* import { p } from 'typewritingclass'
|
|
209
|
+
*
|
|
210
|
+
* // `p` satisfies the Utility signature:
|
|
211
|
+
* const myUtility: Utility = p
|
|
212
|
+
* const rule = myUtility(4)
|
|
213
|
+
* // CSS: padding: 1rem;
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export type Utility = (value: any) => StyleRule
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* A function that transforms a {@link StyleRule} by wrapping it with a
|
|
220
|
+
* pseudo-class selector or a media query.
|
|
221
|
+
*
|
|
222
|
+
* Modifiers are composable -- you can chain them via {@link when} to build
|
|
223
|
+
* multi-condition rules (e.g. "on hover, at medium breakpoint").
|
|
224
|
+
*
|
|
225
|
+
* @param rule - The source {@link StyleRule} to transform.
|
|
226
|
+
* @returns A new {@link StyleRule} with additional selectors or media queries.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* import type { Modifier } from 'typewritingclass'
|
|
231
|
+
* import { hover, md } from 'typewritingclass'
|
|
232
|
+
*
|
|
233
|
+
* // `hover` and `md` are both Modifiers:
|
|
234
|
+
* const hoverMod: Modifier = hover
|
|
235
|
+
* const mdMod: Modifier = md
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export type Modifier = (rule: StyleRule) => StyleRule
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The return value of {@link dcx}, containing both a class string and an
|
|
242
|
+
* inline `style` object for dynamic CSS custom-property bindings.
|
|
243
|
+
*
|
|
244
|
+
* Use this when your styles include runtime-changeable values created with
|
|
245
|
+
* {@link dynamic}. The `className` goes on the element's class attribute, and
|
|
246
|
+
* `style` must be spread onto the element's inline style so the CSS custom
|
|
247
|
+
* properties are set.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* import { dcx, bg, dynamic } from 'typewritingclass'
|
|
252
|
+
*
|
|
253
|
+
* const color = dynamic('#ff0000')
|
|
254
|
+
* const result = dcx(bg(color))
|
|
255
|
+
* // result.className => "_a1b2c"
|
|
256
|
+
* // result.style => { '--twc-d0': '#ff0000' }
|
|
257
|
+
*
|
|
258
|
+
* // In JSX:
|
|
259
|
+
* // <div className={result.className} style={result.style} />
|
|
260
|
+
* // CSS: .\_a1b2c { background-color: var(--twc-d0); }
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export interface DynamicResult {
|
|
264
|
+
/** A space-separated string of generated CSS class names, ready for `className` or `class`. */
|
|
265
|
+
className: string
|
|
266
|
+
/**
|
|
267
|
+
* An object of CSS custom property assignments to apply as inline styles.
|
|
268
|
+
*
|
|
269
|
+
* Keys are custom property names (e.g. `'--twc-d0'`), values are the
|
|
270
|
+
* current runtime values (e.g. `'#ff0000'`, `'1.5rem'`).
|
|
271
|
+
*/
|
|
272
|
+
style: Record<string, string>
|
|
273
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { StyleRule } from '../types.ts'
|
|
2
|
+
import { createRule } from '../rule.ts'
|
|
3
|
+
|
|
4
|
+
export function srOnly(): StyleRule {
|
|
5
|
+
return createRule({
|
|
6
|
+
position: 'absolute',
|
|
7
|
+
width: '1px',
|
|
8
|
+
height: '1px',
|
|
9
|
+
padding: '0',
|
|
10
|
+
margin: '-1px',
|
|
11
|
+
overflow: 'hidden',
|
|
12
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
13
|
+
'white-space': 'nowrap',
|
|
14
|
+
'border-width': '0',
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function notSrOnly(): StyleRule {
|
|
19
|
+
return createRule({
|
|
20
|
+
position: 'static',
|
|
21
|
+
width: 'auto',
|
|
22
|
+
height: 'auto',
|
|
23
|
+
padding: '0',
|
|
24
|
+
margin: '0',
|
|
25
|
+
overflow: 'visible',
|
|
26
|
+
clip: 'auto',
|
|
27
|
+
'white-space': 'normal',
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function forcedColorAdjust(value: string): StyleRule {
|
|
32
|
+
return createRule({ 'forced-color-adjust': value })
|
|
33
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
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 bgAttachment(value: string): StyleRule {
|
|
7
|
+
return createRule({ 'background-attachment': value })
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function bgClip(value: string): StyleRule {
|
|
11
|
+
return createRule({ 'background-clip': value })
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function bgOrigin(value: string): StyleRule {
|
|
15
|
+
return createRule({ 'background-origin': value })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function bgPosition(value: string | DynamicValue): StyleRule {
|
|
19
|
+
if (isDynamic(value)) {
|
|
20
|
+
return createDynamicRule(
|
|
21
|
+
{ 'background-position': `var(${value.__id})` },
|
|
22
|
+
{ [value.__id]: String(value.__value) },
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
return createRule({ 'background-position': value })
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function bgRepeat(value: string): StyleRule {
|
|
29
|
+
return createRule({ 'background-repeat': value })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function bgSize(value: string | DynamicValue): StyleRule {
|
|
33
|
+
if (isDynamic(value)) {
|
|
34
|
+
return createDynamicRule(
|
|
35
|
+
{ 'background-size': `var(${value.__id})` },
|
|
36
|
+
{ [value.__id]: String(value.__value) },
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
return createRule({ 'background-size': value })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function bgImage(value: string | DynamicValue): StyleRule {
|
|
43
|
+
if (isDynamic(value)) {
|
|
44
|
+
return createDynamicRule(
|
|
45
|
+
{ 'background-image': `var(${value.__id})` },
|
|
46
|
+
{ [value.__id]: String(value.__value) },
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
return createRule({ 'background-image': value })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function bgGradient(direction: string = 'to right'): StyleRule {
|
|
53
|
+
return createRule({
|
|
54
|
+
'background-image': `linear-gradient(${direction}, var(--twc-gradient-from, transparent), var(--twc-gradient-via, transparent), var(--twc-gradient-to, transparent))`,
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function gradientFrom(color: string | DynamicValue): StyleRule {
|
|
59
|
+
if (isDynamic(color)) {
|
|
60
|
+
return createDynamicRule(
|
|
61
|
+
{ '--twc-gradient-from': `var(${color.__id})` },
|
|
62
|
+
{ [color.__id]: String(color.__value) },
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
return createRule({ '--twc-gradient-from': color })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function gradientVia(color: string | DynamicValue): StyleRule {
|
|
69
|
+
if (isDynamic(color)) {
|
|
70
|
+
return createDynamicRule(
|
|
71
|
+
{ '--twc-gradient-via': `var(${color.__id})` },
|
|
72
|
+
{ [color.__id]: String(color.__value) },
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
return createRule({ '--twc-gradient-via': color })
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function gradientTo(color: string | DynamicValue): StyleRule {
|
|
79
|
+
if (isDynamic(color)) {
|
|
80
|
+
return createDynamicRule(
|
|
81
|
+
{ '--twc-gradient-to': `var(${color.__id})` },
|
|
82
|
+
{ [color.__id]: String(color.__value) },
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
return createRule({ '--twc-gradient-to': color })
|
|
86
|
+
}
|