105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
import { css, Elevation, FontSizeUnit, MeasureUnit, Theme } from "@emotion/react";
|
|
import chroma from "chroma-js";
|
|
import type { Property } from "csstype";
|
|
|
|
export function generatePalette(lightest: string, darkest: string): ColorPalette {
|
|
return chroma.scale([lightest, darkest]).mode("lch").colors(10, "hex");
|
|
}
|
|
|
|
export const mq = {
|
|
dark: `@media (prefers-color-scheme: dark)`,
|
|
[576]: `@media (min-width: 576px)`,
|
|
[768]: `@media (min-width: 768px)`,
|
|
[992]: `@media (min-width: 992px)`,
|
|
[1200]: `@media (min-width: 1200px)`,
|
|
};
|
|
|
|
function transformShadowDefine(
|
|
shadow: Elevation,
|
|
shadowColor?: chroma.Color = chroma.hsl(0, 0, 0)
|
|
): string[] {
|
|
return [
|
|
`${shadow.offset.width}px`,
|
|
`${shadow.offset.height}px`,
|
|
`${shadow.blur}px`,
|
|
shadowColor.alpha(shadow.opacity).hex(),
|
|
];
|
|
}
|
|
|
|
export function elevation(theme: Theme, level: MeasureUnit) {
|
|
return css({ boxShadow: transformShadowDefine(theme.elevations[level]) });
|
|
}
|
|
|
|
export function flex(
|
|
theme: Theme,
|
|
direction: Property.FlexDirection = "row",
|
|
justify: Property.JustifyContent = "flex-start",
|
|
align: Property.AlignItems = "start",
|
|
gap: MeasureUnit = "none",
|
|
wrap: Property.FlexWrap = "nowrap"
|
|
) {
|
|
return css({
|
|
display: "flex",
|
|
flexDirection: direction,
|
|
justifyContent: justify,
|
|
alignItems: align,
|
|
flexWrap: wrap,
|
|
gap: `${theme.spacings[gap]}px`,
|
|
});
|
|
}
|
|
|
|
export function paddingHorizontal(theme: Theme, padding: MeasureUnit | number = "none") {
|
|
switch (typeof padding) {
|
|
case "number":
|
|
return css({ paddingLeft: padding, paddingRight: padding });
|
|
case "string":
|
|
return css({
|
|
paddingLeft: theme.spacings[padding],
|
|
paddingRight: theme.spacings[padding],
|
|
});
|
|
}
|
|
}
|
|
|
|
export function paddingVertical(theme: Theme, padding: MeasureUnit | number = "none") {
|
|
switch (typeof padding) {
|
|
case "number":
|
|
return css({ paddingTop: padding, paddingBottom: padding });
|
|
case "string":
|
|
return css({
|
|
paddingTop: theme.spacings[padding],
|
|
paddingBottom: theme.spacings[padding],
|
|
});
|
|
}
|
|
}
|
|
|
|
export function marginHorizontal(theme: Theme, margin: MeasureUnit | number = "none") {
|
|
switch (typeof margin) {
|
|
case "number":
|
|
return css({ marginLeft: margin, marginRight: margin });
|
|
case "string":
|
|
return css({
|
|
marginLeft: theme.spacings[margin],
|
|
marginRight: theme.spacings[margin],
|
|
});
|
|
}
|
|
}
|
|
|
|
export function marginVertical(theme: Theme, margin: MeasureUnit | number = "none") {
|
|
switch (typeof margin) {
|
|
case "number":
|
|
return css({ marginTop: margin, marginBottom: margin });
|
|
case "string":
|
|
return css({
|
|
marginTop: theme.spacings[margin],
|
|
marginBottom: theme.spacings[margin],
|
|
});
|
|
}
|
|
}
|
|
|
|
export function Typography(theme: Theme, fontSize: FontSizeUnit, lineHeightRatio: number = 1.3) {
|
|
return css({
|
|
fontSize: theme.fontSizes[fontSize],
|
|
lineHeight: theme.fontSizes[fontSize] * lineHeightRatio,
|
|
});
|
|
}
|