@hypen-space/web 0.4.946 → 0.4.948
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/dist/canvas/paint.js +23 -33
- package/dist/canvas/paint.js.map +1 -1
- package/dist/canvas/utils.js +6 -1
- package/dist/canvas/utils.js.map +1 -1
- package/dist/dom/applicators/advanced-layout.js +9 -8
- package/dist/dom/applicators/advanced-layout.js.map +1 -1
- package/dist/dom/applicators/border.js +10 -17
- package/dist/dom/applicators/border.js.map +1 -1
- package/dist/dom/applicators/effects.js +9 -8
- package/dist/dom/applicators/effects.js.map +1 -1
- package/dist/dom/applicators/font.js +2 -1
- package/dist/dom/applicators/font.js.map +1 -1
- package/dist/dom/applicators/layout.js +2 -1
- package/dist/dom/applicators/layout.js.map +1 -1
- package/dist/dom/applicators/margin.js +6 -7
- package/dist/dom/applicators/margin.js.map +1 -1
- package/dist/dom/applicators/padding.js +9 -10
- package/dist/dom/applicators/padding.js.map +1 -1
- package/dist/dom/applicators/size.d.ts +19 -0
- package/dist/dom/applicators/size.js +35 -9
- package/dist/dom/applicators/size.js.map +1 -1
- package/dist/dom/applicators/transform.js +5 -4
- package/dist/dom/applicators/transform.js.map +1 -1
- package/dist/dom/applicators/typography.js +14 -5
- package/dist/dom/applicators/typography.js.map +1 -1
- package/package.json +2 -2
- package/src/canvas/QUICKSTART.md +0 -2
- package/src/canvas/paint.ts +21 -32
- package/src/canvas/utils.ts +6 -1
- package/src/dom/applicators/advanced-layout.ts +9 -8
- package/src/dom/applicators/border.ts +10 -17
- package/src/dom/applicators/effects.ts +9 -8
- package/src/dom/applicators/font.ts +2 -1
- package/src/dom/applicators/layout.ts +2 -1
- package/src/dom/applicators/margin.ts +6 -6
- package/src/dom/applicators/padding.ts +9 -9
- package/src/dom/applicators/size.ts +34 -9
- package/src/dom/applicators/transform.ts +5 -4
- package/src/dom/applicators/typography.ts +13 -5
- package/src/canvas/PARITY.md +0 -254
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./index.js";
|
|
6
6
|
import { mapAlignmentValue } from "./layout.js";
|
|
7
|
+
import { toCssLength } from "./size.js";
|
|
7
8
|
|
|
8
9
|
export const advancedLayoutHandlers: Record<string, ApplicatorHandler> = {
|
|
9
10
|
// Flexbox properties
|
|
@@ -12,7 +13,7 @@ export const advancedLayoutHandlers: Record<string, ApplicatorHandler> = {
|
|
|
12
13
|
},
|
|
13
14
|
|
|
14
15
|
flexBasis: (el, value) => {
|
|
15
|
-
el.style.flexBasis =
|
|
16
|
+
el.style.flexBasis = toCssLength(value);
|
|
16
17
|
},
|
|
17
18
|
|
|
18
19
|
alignContent: (el, value) => {
|
|
@@ -80,11 +81,11 @@ export const advancedLayoutHandlers: Record<string, ApplicatorHandler> = {
|
|
|
80
81
|
},
|
|
81
82
|
|
|
82
83
|
rowGap: (el, value) => {
|
|
83
|
-
el.style.rowGap =
|
|
84
|
+
el.style.rowGap = toCssLength(value);
|
|
84
85
|
},
|
|
85
86
|
|
|
86
87
|
columnGap: (el, value) => {
|
|
87
|
-
el.style.columnGap =
|
|
88
|
+
el.style.columnGap = toCssLength(value);
|
|
88
89
|
},
|
|
89
90
|
|
|
90
91
|
placeItems: (el, value) => {
|
|
@@ -105,23 +106,23 @@ export const advancedLayoutHandlers: Record<string, ApplicatorHandler> = {
|
|
|
105
106
|
},
|
|
106
107
|
|
|
107
108
|
top: (el, value) => {
|
|
108
|
-
el.style.top =
|
|
109
|
+
el.style.top = toCssLength(value);
|
|
109
110
|
},
|
|
110
111
|
|
|
111
112
|
right: (el, value) => {
|
|
112
|
-
el.style.right =
|
|
113
|
+
el.style.right = toCssLength(value);
|
|
113
114
|
},
|
|
114
115
|
|
|
115
116
|
bottom: (el, value) => {
|
|
116
|
-
el.style.bottom =
|
|
117
|
+
el.style.bottom = toCssLength(value);
|
|
117
118
|
},
|
|
118
119
|
|
|
119
120
|
left: (el, value) => {
|
|
120
|
-
el.style.left =
|
|
121
|
+
el.style.left = toCssLength(value);
|
|
121
122
|
},
|
|
122
123
|
|
|
123
124
|
inset: (el, value) => {
|
|
124
|
-
el.style.inset =
|
|
125
|
+
el.style.inset = toCssLength(value);
|
|
125
126
|
},
|
|
126
127
|
|
|
127
128
|
zIndex: (el, value) => {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
export const borderHandlers: Record<string, ApplicatorHandler> = {
|
|
8
9
|
// Compound border applicator - can take width, color, style, radius
|
|
@@ -16,7 +17,7 @@ export const borderHandlers: Record<string, ApplicatorHandler> = {
|
|
|
16
17
|
|
|
17
18
|
// Width
|
|
18
19
|
if (obj.width !== undefined) {
|
|
19
|
-
el.style.borderWidth =
|
|
20
|
+
el.style.borderWidth = toCssLength(obj.width);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
// Color
|
|
@@ -34,7 +35,7 @@ export const borderHandlers: Record<string, ApplicatorHandler> = {
|
|
|
34
35
|
|
|
35
36
|
// Radius
|
|
36
37
|
if (obj.radius !== undefined) {
|
|
37
|
-
el.style.borderRadius =
|
|
38
|
+
el.style.borderRadius = toCssLength(obj.radius);
|
|
38
39
|
}
|
|
39
40
|
} else if (typeof value === "string") {
|
|
40
41
|
// CSS shorthand like "1px solid black"
|
|
@@ -43,7 +44,7 @@ export const borderHandlers: Record<string, ApplicatorHandler> = {
|
|
|
43
44
|
},
|
|
44
45
|
|
|
45
46
|
borderWidth: (el, value) => {
|
|
46
|
-
el.style.borderWidth =
|
|
47
|
+
el.style.borderWidth = toCssLength(value);
|
|
47
48
|
// CSS `border-style` default is `none`, so a width-only border draws
|
|
48
49
|
// nothing. The Hypen DSL writes `.borderWidth(2).borderColor(...)`
|
|
49
50
|
// expecting a visible stroke (the social Stories ring + the Profile
|
|
@@ -60,38 +61,30 @@ export const borderHandlers: Record<string, ApplicatorHandler> = {
|
|
|
60
61
|
},
|
|
61
62
|
|
|
62
63
|
borderRadius: (el, value) => {
|
|
63
|
-
if (typeof value === "
|
|
64
|
-
el.style.borderRadius = `${value}px`;
|
|
65
|
-
} else if (typeof value === "object" && value !== null) {
|
|
64
|
+
if (typeof value === "object" && value !== null) {
|
|
66
65
|
// Support for individual corners
|
|
67
66
|
const obj = value as Record<string, any>;
|
|
68
67
|
const topLeft = obj.topLeft ?? obj.topStart ?? 0;
|
|
69
68
|
const topRight = obj.topRight ?? obj.topEnd ?? 0;
|
|
70
69
|
const bottomRight = obj.bottomRight ?? obj.bottomEnd ?? 0;
|
|
71
70
|
const bottomLeft = obj.bottomLeft ?? obj.bottomStart ?? 0;
|
|
72
|
-
|
|
73
|
-
const formatValue = (v: any) => typeof v === "number" ? `${v}px` : String(v);
|
|
74
|
-
el.style.borderRadius = `${formatValue(topLeft)} ${formatValue(topRight)} ${formatValue(bottomRight)} ${formatValue(bottomLeft)}`;
|
|
71
|
+
el.style.borderRadius = `${toCssLength(topLeft)} ${toCssLength(topRight)} ${toCssLength(bottomRight)} ${toCssLength(bottomLeft)}`;
|
|
75
72
|
} else {
|
|
76
|
-
el.style.borderRadius =
|
|
73
|
+
el.style.borderRadius = toCssLength(value);
|
|
77
74
|
}
|
|
78
75
|
},
|
|
79
76
|
|
|
80
77
|
// Alias for borderRadius (Compose naming)
|
|
81
78
|
cornerRadius: (el, value) => {
|
|
82
|
-
if (typeof value === "
|
|
83
|
-
el.style.borderRadius = `${value}px`;
|
|
84
|
-
} else if (typeof value === "object" && value !== null) {
|
|
79
|
+
if (typeof value === "object" && value !== null) {
|
|
85
80
|
const obj = value as Record<string, any>;
|
|
86
81
|
const topLeft = obj.topLeft ?? obj.topStart ?? 0;
|
|
87
82
|
const topRight = obj.topRight ?? obj.topEnd ?? 0;
|
|
88
83
|
const bottomRight = obj.bottomRight ?? obj.bottomEnd ?? 0;
|
|
89
84
|
const bottomLeft = obj.bottomLeft ?? obj.bottomStart ?? 0;
|
|
90
|
-
|
|
91
|
-
const formatValue = (v: any) => typeof v === "number" ? `${v}px` : String(v);
|
|
92
|
-
el.style.borderRadius = `${formatValue(topLeft)} ${formatValue(topRight)} ${formatValue(bottomRight)} ${formatValue(bottomLeft)}`;
|
|
85
|
+
el.style.borderRadius = `${toCssLength(topLeft)} ${toCssLength(topRight)} ${toCssLength(bottomRight)} ${toCssLength(bottomLeft)}`;
|
|
93
86
|
} else {
|
|
94
|
-
el.style.borderRadius =
|
|
87
|
+
el.style.borderRadius = toCssLength(value);
|
|
95
88
|
}
|
|
96
89
|
},
|
|
97
90
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
export const effectsHandlers: Record<string, ApplicatorHandler> = {
|
|
8
9
|
// Shadow effects
|
|
@@ -12,10 +13,10 @@ export const effectsHandlers: Record<string, ApplicatorHandler> = {
|
|
|
12
13
|
} else if (typeof value === "object" && value !== null) {
|
|
13
14
|
// Object format: { x, y, blur, spread, color, inset }
|
|
14
15
|
const obj = value as Record<string, any>;
|
|
15
|
-
const x =
|
|
16
|
-
const y =
|
|
17
|
-
const blur =
|
|
18
|
-
const spread =
|
|
16
|
+
const x = toCssLength(obj.x ?? obj.offsetX ?? 0);
|
|
17
|
+
const y = toCssLength(obj.y ?? obj.offsetY ?? 0);
|
|
18
|
+
const blur = toCssLength(obj.blur ?? obj.radius ?? 0);
|
|
19
|
+
const spread = toCssLength(obj.spread ?? 0);
|
|
19
20
|
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
20
21
|
const inset = obj.inset ? "inset " : "";
|
|
21
22
|
el.style.boxShadow = `${inset}${x} ${y} ${blur} ${spread} ${color}`;
|
|
@@ -29,9 +30,9 @@ export const effectsHandlers: Record<string, ApplicatorHandler> = {
|
|
|
29
30
|
shadow: (el, value) => {
|
|
30
31
|
if (typeof value === "object" && value !== null) {
|
|
31
32
|
const obj = value as Record<string, any>;
|
|
32
|
-
const x =
|
|
33
|
-
const y =
|
|
34
|
-
const blur =
|
|
33
|
+
const x = toCssLength(obj.x ?? obj.offsetX ?? 0);
|
|
34
|
+
const y = toCssLength(obj.y ?? obj.offsetY ?? 0);
|
|
35
|
+
const blur = toCssLength(obj.blur ?? obj.radius ?? 4);
|
|
35
36
|
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
36
37
|
el.style.boxShadow = `${x} ${y} ${blur} ${color}`;
|
|
37
38
|
} else if (typeof value === "number") {
|
|
@@ -69,7 +70,7 @@ export const effectsHandlers: Record<string, ApplicatorHandler> = {
|
|
|
69
70
|
|
|
70
71
|
// Individual filter functions
|
|
71
72
|
blur: (el, value) => {
|
|
72
|
-
const val =
|
|
73
|
+
const val = toCssLength(value);
|
|
73
74
|
const current = el.style.filter || "";
|
|
74
75
|
el.style.filter = current ? `${current} blur(${val})` : `blur(${val})`;
|
|
75
76
|
},
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
// Track loaded Google Fonts to avoid duplicate link tags
|
|
8
9
|
const loadedGoogleFonts = new Set<string>();
|
|
@@ -75,7 +76,7 @@ function processFontFamily(value: string): string {
|
|
|
75
76
|
|
|
76
77
|
export const fontHandlers: Record<string, ApplicatorHandler> = {
|
|
77
78
|
fontSize: (el, value) => {
|
|
78
|
-
el.style.fontSize =
|
|
79
|
+
el.style.fontSize = toCssLength(value);
|
|
79
80
|
},
|
|
80
81
|
|
|
81
82
|
fontWeight: (el, value) => {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Maps Hypen alignment values to CSS flexbox values.
|
|
@@ -97,7 +98,7 @@ export const layoutHandlers: Record<string, ApplicatorHandler> = {
|
|
|
97
98
|
},
|
|
98
99
|
|
|
99
100
|
gap: (el, value) => {
|
|
100
|
-
el.style.gap =
|
|
101
|
+
el.style.gap = toCssLength(value);
|
|
101
102
|
},
|
|
102
103
|
|
|
103
104
|
// weight: unified cross-platform API (same as flex)
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength as toCssLengthShared } from "./size.js";
|
|
6
7
|
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
8
|
+
// See `padding.ts#toCssLength` — shared helper normalises `dp` / `sp` / `pt`
|
|
9
|
+
// (which CSS doesn't understand) to `px`, and passes `rem` / `em` / `%`
|
|
10
|
+
// through unchanged.
|
|
10
11
|
const toCssLength = (v: any): string => {
|
|
11
12
|
if (v == null) return "";
|
|
12
|
-
if (typeof v === "number") return `${v}px`;
|
|
13
13
|
if (typeof v === "object" && v["0"] !== undefined) return toCssLength(v["0"]);
|
|
14
|
-
return
|
|
14
|
+
return toCssLengthShared(v);
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// Collect positional args ("0", "1", "2", "3") in order, stopping at the first gap.
|
|
@@ -30,7 +30,7 @@ export const marginHandler: ApplicatorHandler = (el, value) => {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (typeof value !== "object" || value === null) {
|
|
33
|
-
el.style.margin =
|
|
33
|
+
el.style.margin = toCssLength(value);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength as toCssLengthShared } from "./size.js";
|
|
6
7
|
|
|
7
|
-
// Format a value as a CSS length
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
8
|
+
// Format a value as a CSS length. Delegates to the shared helper in
|
|
9
|
+
// `size.ts` so `dp` / `sp` / `pt` normalise to `px` (CSS doesn't understand
|
|
10
|
+
// those suffixes). Numbers become `${n}px`; anything CSS already knows
|
|
11
|
+
// (`rem`, `em`, `%`, `calc(...)`, …) passes through unchanged. The object
|
|
12
|
+
// form (`v["0"]`) is carried over from the legacy applicator-argument
|
|
13
|
+
// shape that sometimes reaches this handler.
|
|
13
14
|
const toCssLength = (v: any): string => {
|
|
14
15
|
if (v == null) return "";
|
|
15
|
-
if (typeof v === "number") return `${v}px`;
|
|
16
16
|
if (typeof v === "object" && v["0"] !== undefined) return toCssLength(v["0"]);
|
|
17
|
-
return
|
|
17
|
+
return toCssLengthShared(v);
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
// Collect positional args ("0", "1", "2", "3") in order, stopping at the first
|
|
@@ -34,7 +34,7 @@ export const paddingHandler: ApplicatorHandler = (el, value) => {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
if (typeof value !== "object" || value === null) {
|
|
37
|
-
el.style.padding =
|
|
37
|
+
el.style.padding = toCssLength(value);
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -16,8 +16,14 @@ import type { ApplicatorHandler } from "./types.js";
|
|
|
16
16
|
/**
|
|
17
17
|
* Parse a size value and return CSS-compatible string.
|
|
18
18
|
* Ensures cross-platform compatibility with Android/iOS.
|
|
19
|
+
*
|
|
20
|
+
* Exported for reuse by other DOM applicators (padding, margin, font,
|
|
21
|
+
* typography, border, …) that historically passed strings through
|
|
22
|
+
* untouched. CSS doesn't understand `dp` / `sp`, so `fontSize("24dp")`
|
|
23
|
+
* or `padding("16sp")` would otherwise be silently dropped by the
|
|
24
|
+
* browser even though the Android / iOS renderers accept them.
|
|
19
25
|
*/
|
|
20
|
-
function parseSizeValue(value: any): string | null {
|
|
26
|
+
export function parseSizeValue(value: any): string | null {
|
|
21
27
|
if (value === null || value === undefined) return null;
|
|
22
28
|
|
|
23
29
|
// Numbers default to px
|
|
@@ -42,8 +48,10 @@ function parseSizeValue(value: any): string | null {
|
|
|
42
48
|
return "100%";
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
// Parse value with unit
|
|
46
|
-
|
|
51
|
+
// Parse value with unit. `sp` is accepted as an alias for `dp` — on web,
|
|
52
|
+
// density-independent and scale-independent units all collapse to CSS
|
|
53
|
+
// `px` at 96dpi (there's no separate text-scaling knob on the DOM side).
|
|
54
|
+
const match = str.match(/^(-?[\d.]+)\s*(px|dp|pt|sp|%|vw|vh|vmin|vmax|em|rem)?$/);
|
|
47
55
|
if (!match) {
|
|
48
56
|
// Pass through other CSS values as-is (e.g., "calc(...)", "fit-content")
|
|
49
57
|
return str;
|
|
@@ -57,13 +65,17 @@ function parseSizeValue(value: any): string | null {
|
|
|
57
65
|
// Absolute pixels - use as-is
|
|
58
66
|
return `${num}px`;
|
|
59
67
|
case "dp":
|
|
60
|
-
case "
|
|
61
|
-
// Density-independent
|
|
62
|
-
// On web, 1dp/
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// but CSS px is already defined as 1/96th of an inch
|
|
68
|
+
case "sp":
|
|
69
|
+
// Density/scale-independent logical pixels.
|
|
70
|
+
// On web, 1dp/1sp = 1 CSS px at standard density (96dpi).
|
|
71
|
+
// (`sp` does not yet scale with the user's text-size preference
|
|
72
|
+
// — that's a separate cross-renderer change.)
|
|
66
73
|
return `${num}px`;
|
|
74
|
+
case "pt":
|
|
75
|
+
// Typographic point = 1/72 inch. Emit native CSS `pt` so the
|
|
76
|
+
// browser's own length resolution runs (1pt = 1.333… CSS px at
|
|
77
|
+
// 96dpi). Matches the 96/72 multiplier used on iOS and Android.
|
|
78
|
+
return `${num}pt`;
|
|
67
79
|
case "%":
|
|
68
80
|
return `${num}%`;
|
|
69
81
|
case "vw":
|
|
@@ -83,6 +95,19 @@ function parseSizeValue(value: any): string | null {
|
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Coerce a Hypen length value to a CSS length string for applicators that
|
|
100
|
+
* feed directly into `el.style.*`. Numbers become `${n}px`; strings with
|
|
101
|
+
* platform-agnostic units (`dp`, `sp`, `pt`) are normalised; anything the
|
|
102
|
+
* browser already understands (`em`, `rem`, `%`, `calc(...)`, …) passes
|
|
103
|
+
* through.
|
|
104
|
+
*/
|
|
105
|
+
export function toCssLength(value: any): string {
|
|
106
|
+
if (value === null || value === undefined) return "";
|
|
107
|
+
if (typeof value === "number") return `${value}px`;
|
|
108
|
+
return parseSizeValue(value) ?? String(value);
|
|
109
|
+
}
|
|
110
|
+
|
|
86
111
|
export const sizeHandlers: Record<string, ApplicatorHandler> = {
|
|
87
112
|
width: (el, value) => {
|
|
88
113
|
const size = parseSizeValue(value);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
export const transformHandlers: Record<string, ApplicatorHandler> = {
|
|
8
9
|
transform: (el, value) => {
|
|
@@ -15,19 +16,19 @@ export const transformHandlers: Record<string, ApplicatorHandler> = {
|
|
|
15
16
|
|
|
16
17
|
translateX: (el, value) => {
|
|
17
18
|
const current = el.style.transform || "";
|
|
18
|
-
const val =
|
|
19
|
+
const val = toCssLength(value);
|
|
19
20
|
el.style.transform = current ? `${current} translateX(${val})` : `translateX(${val})`;
|
|
20
21
|
},
|
|
21
22
|
|
|
22
23
|
translateY: (el, value) => {
|
|
23
24
|
const current = el.style.transform || "";
|
|
24
|
-
const val =
|
|
25
|
+
const val = toCssLength(value);
|
|
25
26
|
el.style.transform = current ? `${current} translateY(${val})` : `translateY(${val})`;
|
|
26
27
|
},
|
|
27
28
|
|
|
28
29
|
translateZ: (el, value) => {
|
|
29
30
|
const current = el.style.transform || "";
|
|
30
|
-
const val =
|
|
31
|
+
const val = toCssLength(value);
|
|
31
32
|
el.style.transform = current ? `${current} translateZ(${val})` : `translateZ(${val})`;
|
|
32
33
|
},
|
|
33
34
|
|
|
@@ -86,7 +87,7 @@ export const transformHandlers: Record<string, ApplicatorHandler> = {
|
|
|
86
87
|
},
|
|
87
88
|
|
|
88
89
|
perspective: (el, value) => {
|
|
89
|
-
el.style.perspective =
|
|
90
|
+
el.style.perspective = toCssLength(value);
|
|
90
91
|
},
|
|
91
92
|
};
|
|
92
93
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ApplicatorHandler } from "./types.js";
|
|
6
|
+
import { toCssLength } from "./size.js";
|
|
6
7
|
|
|
7
8
|
export const typographyHandlers: Record<string, ApplicatorHandler> = {
|
|
8
9
|
textAlign: (el, value) => {
|
|
@@ -36,23 +37,30 @@ export const typographyHandlers: Record<string, ApplicatorHandler> = {
|
|
|
36
37
|
},
|
|
37
38
|
|
|
38
39
|
textDecorationThickness: (el, value) => {
|
|
39
|
-
el.style.textDecorationThickness =
|
|
40
|
+
el.style.textDecorationThickness = toCssLength(value);
|
|
40
41
|
},
|
|
41
42
|
|
|
42
43
|
letterSpacing: (el, value) => {
|
|
43
|
-
el.style.letterSpacing =
|
|
44
|
+
el.style.letterSpacing = toCssLength(value);
|
|
44
45
|
},
|
|
45
46
|
|
|
46
47
|
wordSpacing: (el, value) => {
|
|
47
|
-
el.style.wordSpacing =
|
|
48
|
+
el.style.wordSpacing = toCssLength(value);
|
|
48
49
|
},
|
|
49
50
|
|
|
50
51
|
lineHeight: (el, value) => {
|
|
51
|
-
|
|
52
|
+
// `line-height` is unitless by convention when the value is a bare
|
|
53
|
+
// number (CSS multiplier on the element's font-size); only normalise
|
|
54
|
+
// when the value carries a length unit like `dp` / `sp`.
|
|
55
|
+
if (typeof value === "string" && /^-?[\d.]+\s*(dp|sp)$/i.test(value.trim())) {
|
|
56
|
+
el.style.lineHeight = toCssLength(value);
|
|
57
|
+
} else {
|
|
58
|
+
el.style.lineHeight = String(value);
|
|
59
|
+
}
|
|
52
60
|
},
|
|
53
61
|
|
|
54
62
|
textIndent: (el, value) => {
|
|
55
|
-
el.style.textIndent =
|
|
63
|
+
el.style.textIndent = toCssLength(value);
|
|
56
64
|
},
|
|
57
65
|
|
|
58
66
|
textOverflow: (el, value) => {
|