boxwood 2.1.0 → 2.2.1
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/index.js +22 -8
- package/package.json +3 -2
- package/ui/Group/index.js +50 -0
- package/ui/Stack/index.js +43 -0
- package/ui/index.js +7 -0
- package/ui/normalize.js +86 -0
- package/.claude/settings.local.json +0 -11
package/index.js
CHANGED
|
@@ -509,6 +509,27 @@ function decamelize(string) {
|
|
|
509
509
|
|
|
510
510
|
function stylesheet(input) {
|
|
511
511
|
const object = { ...input }
|
|
512
|
+
function render(object, selector = "") {
|
|
513
|
+
let result = []
|
|
514
|
+
for (const key in object) {
|
|
515
|
+
const value = object[key]
|
|
516
|
+
if (value && typeof value === "object") {
|
|
517
|
+
if (key.startsWith("@")) {
|
|
518
|
+
result.push(`${key}{${render(value, selector)}}`)
|
|
519
|
+
} else {
|
|
520
|
+
const nextSelector = selector ? `${selector} ${key}` : key
|
|
521
|
+
result.push(render(value, nextSelector))
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
if (selector) {
|
|
525
|
+
result.push(`${selector}{${decamelize(key)}:${value};}`)
|
|
526
|
+
} else {
|
|
527
|
+
result.push(`${decamelize(key)}:${value};`)
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return result.join("")
|
|
532
|
+
}
|
|
512
533
|
return {
|
|
513
534
|
add(item) {
|
|
514
535
|
for (const key in item) {
|
|
@@ -519,14 +540,7 @@ function stylesheet(input) {
|
|
|
519
540
|
object[key] = value
|
|
520
541
|
},
|
|
521
542
|
toString() {
|
|
522
|
-
|
|
523
|
-
for (const key in object) {
|
|
524
|
-
const value = object[key]
|
|
525
|
-
if (value) {
|
|
526
|
-
result.push(`${decamelize(key)}:${value}`)
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return result.join(";")
|
|
543
|
+
return render(object)
|
|
530
544
|
},
|
|
531
545
|
}
|
|
532
546
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "boxwood",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Compile HTML templates into JS",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./index.js",
|
|
9
|
-
"./adapters/express": "./adapters/express/index.js"
|
|
9
|
+
"./adapters/express": "./adapters/express/index.js",
|
|
10
|
+
"./ui": "./ui/index.js"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
13
|
"test": "node --test --test-reporter=dot \"test/**/*.test.js\" \"test/**/*.spec.js\"",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const { css, component, Div } = require("../..")
|
|
2
|
+
const {
|
|
3
|
+
normalizeGap,
|
|
4
|
+
normalizeFlex,
|
|
5
|
+
normalizeBreakpoint,
|
|
6
|
+
normalizeWidth,
|
|
7
|
+
normalizeSpacing,
|
|
8
|
+
} = require("../normalize")
|
|
9
|
+
|
|
10
|
+
function Group(
|
|
11
|
+
{ align, className, breakpoint, justify, gap, width, margin, padding, style },
|
|
12
|
+
children
|
|
13
|
+
) {
|
|
14
|
+
gap = normalizeGap(gap)
|
|
15
|
+
align = normalizeFlex(align)
|
|
16
|
+
justify = normalizeFlex(justify)
|
|
17
|
+
breakpoint = normalizeBreakpoint(breakpoint)
|
|
18
|
+
width = normalizeWidth(width)
|
|
19
|
+
margin = normalizeSpacing(margin)
|
|
20
|
+
padding = normalizeSpacing(padding)
|
|
21
|
+
|
|
22
|
+
const styleObject = {
|
|
23
|
+
display: "flex",
|
|
24
|
+
"flex-direction": "row",
|
|
25
|
+
...(gap && { gap }),
|
|
26
|
+
...(align && { "align-items": align }),
|
|
27
|
+
...(justify && { "justify-content": justify }),
|
|
28
|
+
...(width && { width }),
|
|
29
|
+
...(margin && { margin }),
|
|
30
|
+
...(padding && { padding }),
|
|
31
|
+
...(breakpoint && {
|
|
32
|
+
[`@media (max-width: ${breakpoint})`]: {
|
|
33
|
+
"flex-direction": "column",
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const styles = css`
|
|
39
|
+
.group {
|
|
40
|
+
${css.create(styleObject).toString()}
|
|
41
|
+
}
|
|
42
|
+
`
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
Div({ className: [styles.group, className], style }, children),
|
|
46
|
+
styles.css,
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = component(Group)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { css, component, Div } = require("../..")
|
|
2
|
+
const {
|
|
3
|
+
normalizeGap,
|
|
4
|
+
normalizeFlex,
|
|
5
|
+
normalizeWidth,
|
|
6
|
+
normalizeSpacing,
|
|
7
|
+
} = require("../normalize")
|
|
8
|
+
|
|
9
|
+
function Stack(
|
|
10
|
+
{ align, className, justify, gap, width, margin, padding, style },
|
|
11
|
+
children
|
|
12
|
+
) {
|
|
13
|
+
gap = normalizeGap(gap)
|
|
14
|
+
align = normalizeFlex(align)
|
|
15
|
+
justify = normalizeFlex(justify)
|
|
16
|
+
width = normalizeWidth(width)
|
|
17
|
+
margin = normalizeSpacing(margin)
|
|
18
|
+
padding = normalizeSpacing(padding)
|
|
19
|
+
|
|
20
|
+
const styleObject = {
|
|
21
|
+
display: "flex",
|
|
22
|
+
"flex-direction": "column",
|
|
23
|
+
...(gap && { gap }),
|
|
24
|
+
...(align && { "align-items": align }),
|
|
25
|
+
...(justify && { "justify-content": justify }),
|
|
26
|
+
...(width && { width }),
|
|
27
|
+
...(margin && { margin }),
|
|
28
|
+
...(padding && { padding }),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const styles = css`
|
|
32
|
+
.stack {
|
|
33
|
+
${css.create(styleObject).toString()}
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
|
|
37
|
+
return [
|
|
38
|
+
Div({ className: [styles.stack, className], style }, children),
|
|
39
|
+
styles.css,
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = component(Stack)
|
package/ui/index.js
ADDED
package/ui/normalize.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
function normalizeFlex(align) {
|
|
2
|
+
switch (align) {
|
|
3
|
+
case "start":
|
|
4
|
+
return "flex-start"
|
|
5
|
+
case "end":
|
|
6
|
+
return "flex-end"
|
|
7
|
+
default:
|
|
8
|
+
return align
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const GAP_MAP = {
|
|
13
|
+
xs: "0.25rem",
|
|
14
|
+
sm: "0.5rem",
|
|
15
|
+
md: "1rem",
|
|
16
|
+
lg: "2rem",
|
|
17
|
+
xl: "4rem",
|
|
18
|
+
none: null,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function normalizeGap(gap) {
|
|
22
|
+
if (!gap) {
|
|
23
|
+
return "1rem"
|
|
24
|
+
}
|
|
25
|
+
if (typeof gap === "number") {
|
|
26
|
+
return `${gap}px`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (GAP_MAP.hasOwnProperty(gap)) {
|
|
30
|
+
return GAP_MAP[gap]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return gap
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const BREAKPOINT_MAP = {
|
|
37
|
+
xs: "575px",
|
|
38
|
+
sm: "767px",
|
|
39
|
+
md: "991px",
|
|
40
|
+
lg: "1199px",
|
|
41
|
+
xl: "1399px",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function normalizeBreakpoint(breakpoint) {
|
|
45
|
+
if (typeof breakpoint === "number") {
|
|
46
|
+
return `${breakpoint}px`
|
|
47
|
+
}
|
|
48
|
+
if (BREAKPOINT_MAP.hasOwnProperty(breakpoint)) {
|
|
49
|
+
return BREAKPOINT_MAP[breakpoint]
|
|
50
|
+
}
|
|
51
|
+
return breakpoint
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizeWidth(width) {
|
|
55
|
+
if (typeof width === "number") {
|
|
56
|
+
return `${width}px`
|
|
57
|
+
}
|
|
58
|
+
return width
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const SPACING_MAP = {
|
|
62
|
+
xs: "0.25rem",
|
|
63
|
+
sm: "0.5rem",
|
|
64
|
+
md: "1rem",
|
|
65
|
+
lg: "2rem",
|
|
66
|
+
xl: "4rem",
|
|
67
|
+
none: null,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function normalizeSpacing(spacing) {
|
|
71
|
+
if (typeof spacing === "number") {
|
|
72
|
+
return `${spacing}px`
|
|
73
|
+
}
|
|
74
|
+
if (SPACING_MAP.hasOwnProperty(spacing)) {
|
|
75
|
+
return SPACING_MAP[spacing]
|
|
76
|
+
}
|
|
77
|
+
return spacing
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
normalizeFlex,
|
|
82
|
+
normalizeGap,
|
|
83
|
+
normalizeBreakpoint,
|
|
84
|
+
normalizeWidth,
|
|
85
|
+
normalizeSpacing,
|
|
86
|
+
}
|