slate/components/core/FontFrame/Settings/Controls.js
2021-07-07 14:10:31 -07:00

270 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import * as React from "react";
import * as SVG from "~/common/svg";
import * as Constants from "~/common/constants";
import { P1 } from "~/components/system/components/Typography";
import { Slider } from "~/components/system/components/Slider";
import { css } from "@emotion/react";
import Select from "~/components/core/FontFrame/Settings/Select";
const STYLES_LABEL = (theme) => css`
font-size: 0.875rem;
color: ${theme.fontPreviewDarkMode ? theme.system.grayDark3 : theme.semantic.textGrayLight};
margin-bottom: 4px;
`;
export const Controller = ({
value,
options,
onChange,
selectSuffix = "",
//NOTE(Amine): minWidth will remove junk when Select value change
selectMinWidth,
label,
min,
max,
step,
disabled,
}) => {
return (
<div
css={
disabled &&
css`
opacity: 0.3;
pointer-events: none;
`
}
>
<P1 css={STYLES_LABEL}>{label}</P1>
<div css={css({ display: "flex", alignItems: "center" })}>
<Select
options={options}
value={value}
onChange={onChange}
placeholderSuffix={selectSuffix}
minWidth={selectMinWidth}
/>
<div style={{ width: "100%" }}>
<Slider
discrete
min={min}
max={max}
step={step}
value={value}
onChange={onChange}
containerStyle={{ height: "auto", marginLeft: "18px" }}
sliderBarStyle={(theme) => css`
height: 2px;
background-color: ${theme.fontPreviewDarkMode
? theme.system.grayDark3
: theme.system.grayLight4};
`}
activeBarStyle={(theme) => css`
height: 2px;
bottom: 2px;
background-color: ${theme.fontPreviewDarkMode
? theme.system.white
: theme.system.grayDark4};
`}
handleStyle={(theme) => css`
width: 15px;
height: 15px;
bottom: 11px;
background-color: ${theme.fontPreviewDarkMode
? theme.system.white
: theme.system.grayDark4};
:hover {
box-shadow: 0 0 0 4px
${theme.fontPreviewDarkMode
? "rgba(255, 255, 255, 0.1)"
: "rgba(75, 74, 77, 0.1)"};
}
:active {
box-shadow: 0 0 0 8px
${theme.fontPreviewDarkMode
? "rgba(255, 255, 255, 0.2)"
: "rgba(75, 74, 77, 0.2)"};
}
`}
/>
</div>
</div>
</div>
);
};
const STYLES_CONTENT_SELECT = (theme) => css`
display: flex;
justify-content: space-between;
width: 100%;
border: 1px solid
${theme.fontPreviewDarkMode ? Constants.system.grayDark4 : Constants.system.grayLight5};
padding: 8px 12px;
border-radius: 4px;
`;
export const ContentControl = ({ options, value, onChange, showLabel = true }) => {
return (
<div
css={css`
width: 100%;
`}
>
{showLabel && <P1 css={STYLES_LABEL}>Content</P1>}
<Select
inputStyle={STYLES_CONTENT_SELECT}
options={options}
value={value}
onChange={onChange}
/>
</div>
);
};
const STYLES_ALIGNEMENT_BUTTON = (theme) => css`
display: flex;
border-radius: 4px;
border: 1px solid
${theme.fontPreviewDarkMode ? theme.semantic.textGrayDark : theme.system.grayLight5};
margin-left: 16px;
button {
display: block;
box-sizing: border-box;
cursor: pointer;
padding: 8px 12px;
margin: 0;
border: none;
}
button:focus {
outline: none;
}
svg {
display: block;
}
`;
const getIconColor = (isActive, theme) => {
const darkMode = isActive ? theme.system.white : theme.semantic.textGray;
const lightMode = isActive ? theme.system.grayDark4 : theme.semantic.textGray;
return theme.fontPreviewDarkMode ? darkMode : lightMode;
};
const getBackgroundColor = (isActive, theme) => {
if (!isActive) return "transparent";
return theme.fontPreviewDarkMode ? theme.system.grayDark4 : theme.system.grayLight5;
};
const STYLES_ALIGN_BUTTON = (isActive) => (theme) => css`
background-color: ${getBackgroundColor(isActive, theme)};
path {
stroke: ${getIconColor(isActive, theme)};
}
`;
export const AlignmentControl = ({
vAlign,
textAlign,
options,
onChange,
updateTextAlign,
disabled,
}) => {
return (
<div
css={
disabled &&
css`
opacity: 0.3;
pointer-events: none;
`
}
>
<P1 css={STYLES_LABEL}>Alignment</P1>
<div css={css({ display: "flex", alignItems: "center" })}>
<Select options={options} value={vAlign} onChange={onChange} />
<div css={STYLES_ALIGNEMENT_BUTTON}>
<button
onClick={() => updateTextAlign("left")}
css={STYLES_ALIGN_BUTTON(textAlign === "left")}
>
<SVG.AlignLeft height={16} width={16} />
</button>
<button
onClick={() => updateTextAlign("center")}
css={STYLES_ALIGN_BUTTON(textAlign === "center")}
>
<SVG.AlignCenter height={16} width={16} />
</button>
<button
onClick={() => updateTextAlign("right")}
css={STYLES_ALIGN_BUTTON(textAlign === "right")}
>
<SVG.AlignRight height={16} width={16} />
</button>
</div>
</div>
</div>
);
};
const STYLES_SETTINGS_WRAPPER = (theme) => css`
box-sizing: border-box;
display: flex;
border-radius: 4px;
border: 1px solid
${theme.fontPreviewDarkMode ? theme.semantic.textGrayDark : theme.system.grayLight5};
justify-content: space-between;
overflow: hidden;
button {
display: block;
box-sizing: border-box;
cursor: pointer;
padding: 8px 12px;
margin: 0;
border: none;
background: none;
color: ${theme.fontPreviewDarkMode ? theme.system.white : theme.semantic.textGrayDark};
}
button:focus {
outline: none;
}
svg {
display: block;
path {
stroke: ${theme.fontPreviewDarkMode ? theme.system.white : theme.semantic.textGrayDark};
}
}
.reset_button {
border-left: 1px solid
${theme.fontPreviewDarkMode ? theme.semantic.textGrayDark : theme.system.grayLight5};
}
`;
const STYLES_FEELING_LUCKY = css`
width: 100%;
text-align: left;
`;
export const SettingsControl = ({ getRandomLayout, resetLayout }) => (
<div>
<P1 css={STYLES_LABEL}>Settings</P1>
<div css={STYLES_SETTINGS_WRAPPER}>
<button css={STYLES_FEELING_LUCKY} onClick={getRandomLayout}>
<P1
css={css`
font-size: 14px;
white-space: pre;
`}
>
Im feeling lucky
</P1>
</button>
<button className="reset_button" onClick={resetLayout}>
<SVG.RotateCcw height={16} width={16} />
</button>
</div>
</div>
);