1
0
Fork 0
mirror of synced 2024-09-14 08:18:31 +12:00
budibase/packages/builder/src/builderStore/generate_css.js
2020-02-20 17:07:25 +00:00

129 lines
2.8 KiB
JavaScript

import { filter, map, reduce, toPairs } from "lodash/fp"
import { pipe } from "../common/core"
const self = n => n
const join_with = delimiter => a => a.join(delimiter)
const empty_string_to_unset = s => (s.length ? s : "0")
const add_suffix_if_number = suffix => s => {
try {
if (isNaN(s) || isNaN(parseFloat(s))) return s
} catch (_) {
return s
}
return s + suffix
}
export const make_margin = values =>
pipe(values, [
map(empty_string_to_unset),
map(add_suffix_if_number("px")),
join_with(" "),
])
const css_map = {
templaterows: {
name: "grid-template-rows",
generate: self,
},
templatecolumns: {
name: "grid-template-columns",
generate: self,
},
gridarea: {
name: "grid-area",
generate: make_margin,
},
gap: {
name: "grid-gap",
generate: n => `${n}px`,
},
columnstart: {
name: "grid-column-start",
generate: self,
},
columnend: {
name: "grid-column-end",
generate: self,
},
rowstart: {
name: "grid-row-start",
generate: self,
},
rowend: {
name: "grid-row-end",
generate: self,
},
padding: {
name: "padding",
generate: make_margin,
},
margin: {
name: "margin",
generate: make_margin,
},
zindex: {
name: "z-index",
generate: self,
},
height: {
name: "height",
generate: self,
},
width: {
name: "width",
generate: self,
},
}
export const generate_rule = ([name, values]) =>
`${css_map[name].name}: ${css_map[name].generate(values)};`
const handle_grid = (acc, [name, value]) => {
let tmp = []
if (name === "row" || name === "column") {
if (value[0]) tmp.push([`${name}start`, value[0]])
if (value[1]) tmp.push([`${name}end`, value[1]])
return acc.concat(tmp)
}
return acc.concat([[name, value]])
}
const object_to_css_string = [
toPairs,
reduce(handle_grid, []),
filter(v => (Array.isArray(v[1]) ? v[1].some(s => s.length) : v[1].length)),
map(generate_rule),
join_with("\n"),
]
export const generate_css = ({ layout, position }) => {
let _layout = pipe(layout, object_to_css_string)
_layout = _layout.length ? _layout + "\ndisplay: grid;" : _layout
return {
layout: _layout,
position: pipe(position, object_to_css_string),
}
}
const apply_class = (id, name, styles) => `.${name}-${id} {\n${styles}\n}`
export const generate_screen_css = component_array => {
let styles = ""
let emptyStyles = { layout: {}, position: {} }
for (let i = 0; i < component_array.length; i += 1) {
const { _styles, _id, _children } = component_array[i]
const { layout, position } = generate_css(_styles || emptyStyles)
styles += apply_class(_id, "pos", position) + "\n"
styles += apply_class(_id, "lay", layout) + "\n"
if (_children && _children.length) {
styles += generate_screen_css(_children) + "\n"
}
}
return styles.trim()
}