mirror of
https://github.com/filecoin-project/slate.git
synced 2024-11-23 14:07:20 +03:00
added controls
This commit is contained in:
parent
fc685affdd
commit
c2f92ffd8a
@ -1,9 +1,14 @@
|
||||
import * as React from "react";
|
||||
import * as SVG from "~/common/svg";
|
||||
import * as Constants from "~/common/constants";
|
||||
|
||||
import { P } from "~/components/system/components/Typography";
|
||||
import { Slider } from "~/components/system/components/Slider";
|
||||
import { css } from "@emotion/react";
|
||||
|
||||
const CONTROLS_STYLES_WRAPPER = (dark) => (theme) => css`
|
||||
import Select from "./Select";
|
||||
|
||||
const CONTROLS_STYLES_WRAPPER = (theme) => css`
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
@ -11,15 +16,16 @@ const CONTROLS_STYLES_WRAPPER = (dark) => (theme) => css`
|
||||
margin-left: 8px;
|
||||
}
|
||||
path {
|
||||
stroke: ${dark ? theme.system.white : theme.system.black};
|
||||
stroke: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.black};
|
||||
}
|
||||
`;
|
||||
|
||||
const CONTROLS_DARKMODE_WRAPPER = (dark) => (theme) => css`
|
||||
display: inline-block;
|
||||
const CONTROLS_DARKMODE_WRAPPER = (theme) => css`
|
||||
display: flex;
|
||||
border-radius: 4px;
|
||||
border: 1px solid ${dark ? theme.system.textGrayDark : theme.system.gray20};
|
||||
border: 1px solid ${theme.fontPreviewDarkMode ? theme.system.textGrayDark : theme.system.gray20};
|
||||
button {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
padding: 8px 12px;
|
||||
@ -27,60 +33,57 @@ const CONTROLS_DARKMODE_WRAPPER = (dark) => (theme) => css`
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
.lightmode_btn {
|
||||
path {
|
||||
stroke: ${dark ? theme.system.gray50 : theme.system.black};
|
||||
stroke: ${theme.fontPreviewDarkMode ? theme.system.gray50 : theme.system.black};
|
||||
}
|
||||
background-color: ${!dark ? theme.system.gray20 : "none"};
|
||||
background-color: ${!theme.fontPreviewDarkMode ? theme.system.gray20 : "none"};
|
||||
}
|
||||
.darkmode_btn {
|
||||
path {
|
||||
stroke: ${dark ? theme.system.white : theme.system.textGray};
|
||||
stroke: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.textGray};
|
||||
}
|
||||
background-color: ${dark ? theme.system.gray80 : "none"};
|
||||
background-color: ${theme.fontPreviewDarkMode ? theme.system.gray80 : "none"};
|
||||
}
|
||||
`;
|
||||
|
||||
const CONTROLS_SETTINGS_BUTTON = (dark, isActive) => (theme) => css`
|
||||
const CONTROLS_SETTINGS_BUTTON = (isActive) => (theme) => css`
|
||||
padding: 8px 12px;
|
||||
margin: 0;
|
||||
border-radius: 4px;
|
||||
background: none;
|
||||
border: 1px solid ${dark ? theme.system.textGrayDark : theme.system.gray20};
|
||||
border: 1px solid ${theme.fontPreviewDarkMode ? theme.system.textGrayDark : theme.system.gray20};
|
||||
cursor: pointer;
|
||||
${isActive &&
|
||||
css`
|
||||
background-color: ${dark ? theme.system.gray80 : theme.system.gray20};
|
||||
background-color: ${theme.fontPreviewDarkMode ? theme.system.gray80 : theme.system.gray20};
|
||||
`};
|
||||
path {
|
||||
${isActive
|
||||
? css`
|
||||
stroke: ${dark ? theme.system.white : theme.system.black};
|
||||
stroke: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.black};
|
||||
`
|
||||
: css`
|
||||
stroke: ${dark ? theme.system.gray50 : theme.system.textGray};
|
||||
stroke: ${theme.fontPreviewDarkMode ? theme.system.gray50 : theme.system.textGray};
|
||||
`}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function Controls({
|
||||
onDarkMode,
|
||||
onLightMode,
|
||||
onToggleSettings,
|
||||
isDarkMode,
|
||||
isSettingsVisible,
|
||||
}) {
|
||||
export const FixedControls = ({ onDarkMode, onLightMode, onToggleSettings, isSettingsVisible }) => {
|
||||
return (
|
||||
<div css={CONTROLS_STYLES_WRAPPER(isDarkMode)}>
|
||||
<div css={CONTROLS_STYLES_WRAPPER}>
|
||||
<div>
|
||||
<button
|
||||
css={CONTROLS_SETTINGS_BUTTON(isDarkMode, isSettingsVisible)}
|
||||
onClick={onToggleSettings}
|
||||
>
|
||||
<button css={CONTROLS_SETTINGS_BUTTON(isSettingsVisible)} onClick={onToggleSettings}>
|
||||
<SVG.Sliders />
|
||||
</button>
|
||||
</div>
|
||||
<div css={CONTROLS_DARKMODE_WRAPPER(isDarkMode)}>
|
||||
<div css={CONTROLS_DARKMODE_WRAPPER}>
|
||||
<button onClick={onLightMode} className="lightmode_btn">
|
||||
<SVG.Sun />
|
||||
</button>
|
||||
@ -90,4 +93,235 @@ export default function Controls({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const STYLES_CONTROLLER_WRAPPER = (theme) =>
|
||||
css`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
grid-column-gap: 48px;
|
||||
grid-row-gap: 32px;
|
||||
background-color: ${theme.fontPreviewDarkMode ? "#212124" : "#fbfbfb"};
|
||||
width: 100%;
|
||||
padding: 25px 32px 32px;
|
||||
flex-wrap: wrap;
|
||||
`;
|
||||
|
||||
const STYLES_CONTENT_SELECT = (theme) => css`
|
||||
width: 100%;
|
||||
border: 1px solid ${theme.fontPreviewDarkMode ? Constants.system.gray80 : Constants.system.gray20};
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
`;
|
||||
export const Controls = ({
|
||||
settings,
|
||||
updateFontSize,
|
||||
updateLineHeight,
|
||||
updateTracking,
|
||||
updateColumn,
|
||||
updateTextAlign,
|
||||
updateVerticalAlign,
|
||||
}) => {
|
||||
const VerticalOptions = [
|
||||
{ value: "top", name: "Top" },
|
||||
{ value: "center", name: "Center" },
|
||||
{ value: "bottom", name: "Bottom" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div css={STYLES_CONTROLLER_WRAPPER}>
|
||||
<div>
|
||||
<p css={STYLES_LABEL}>Content</p>
|
||||
<Select
|
||||
inputStyle={STYLES_CONTENT_SELECT}
|
||||
options={[{ value: "custom", name: "Custom" }]}
|
||||
value={"Custom"}
|
||||
/>
|
||||
</div>
|
||||
<AlignmentControl
|
||||
options={VerticalOptions}
|
||||
vAlign={settings.valign}
|
||||
textAlign={settings.textAlign}
|
||||
onChange={(e) => updateVerticalAlign(e.target.value)}
|
||||
updateTextAlign={updateTextAlign}
|
||||
/>
|
||||
<Controller
|
||||
selectSuffix="px"
|
||||
label="Size"
|
||||
min={12}
|
||||
max={72}
|
||||
step={2}
|
||||
options={[
|
||||
{ value: 12, name: "12px" },
|
||||
{ value: 14, name: "14px" },
|
||||
]}
|
||||
value={settings.fontSize}
|
||||
onChange={(e) => {
|
||||
updateFontSize(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
label="Line Height"
|
||||
selectSuffix="%"
|
||||
min={40}
|
||||
max={400}
|
||||
step={20}
|
||||
options={[
|
||||
{ value: 100, name: "100%" },
|
||||
{ value: 200, name: "200%" },
|
||||
{ value: 300, name: "300%" },
|
||||
{ value: 400, name: "400%" },
|
||||
]}
|
||||
value={settings.lineHeight}
|
||||
onChange={(e) => updateLineHeight(e.target.value)}
|
||||
/>
|
||||
<Controller
|
||||
label="Tracking"
|
||||
selectSuffix="em"
|
||||
min={-1}
|
||||
max={1.5}
|
||||
step={0.05}
|
||||
options={[
|
||||
{ value: -1, name: "-1em" },
|
||||
{ value: 0, name: "0em" },
|
||||
{ value: 1, name: "1em" },
|
||||
{ value: 2, name: "2em" },
|
||||
]}
|
||||
value={settings.tracking}
|
||||
onChange={(e) => updateTracking(e.target.value)}
|
||||
/>
|
||||
<Controller
|
||||
label="Column"
|
||||
min={1}
|
||||
max={6}
|
||||
step={1}
|
||||
options={[
|
||||
{ value: 1, name: "1" },
|
||||
{ value: 2, name: "2" },
|
||||
{ value: 3, name: "3" },
|
||||
{ value: 4, name: "4" },
|
||||
]}
|
||||
value={settings.column}
|
||||
onChange={(e) => updateColumn(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const STYLES_ALIGNEMENT_BUTTON = (theme) => css`
|
||||
display: flex;
|
||||
border-radius: 4px;
|
||||
border: 1px solid ${theme.fontPreviewDarkMode ? theme.system.textGrayDark : theme.system.gray20};
|
||||
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;
|
||||
}
|
||||
/* .left_btn {
|
||||
path {
|
||||
stroke: ${dark ? theme.system.gray50 : theme.system.black};
|
||||
}
|
||||
background-color: ${dark ? theme.system.gray20 : "none"};
|
||||
}
|
||||
.center_btn {
|
||||
path {
|
||||
stroke: ${dark ? theme.system.white : theme.system.textGray};
|
||||
}
|
||||
background-color: ${dark ? theme.system.gray80 : "none"};
|
||||
}
|
||||
.right_btn {
|
||||
path {
|
||||
stroke: ${dark ? theme.system.white : theme.system.textGray};
|
||||
}
|
||||
background-color: ${dark ? theme.system.gray80 : "none"};
|
||||
} */
|
||||
`;
|
||||
const getIconColor = (isActive, theme) => {
|
||||
const darkMode = isActive ? theme.system.white : theme.system.textGray;
|
||||
const lightMode = isActive ? theme.system.gray80 : theme.system.textGray;
|
||||
return theme.fontPreviewDarkMode ? darkMode : lightMode;
|
||||
};
|
||||
const getBackgroundColor = (isActive, theme) => {
|
||||
if (!isActive) return "transparent";
|
||||
return theme.fontPreviewDarkMode ? theme.system.gray80 : theme.system.gray20;
|
||||
};
|
||||
const STYLES_ALIGN_BUTTON = (isActive) => (theme) => css`
|
||||
background-color: ${getBackgroundColor(isActive, theme)};
|
||||
path {
|
||||
stroke: ${getIconColor(isActive, theme)};
|
||||
}
|
||||
`;
|
||||
|
||||
const AlignmentControl = ({ vAlign, textAlign, options, onChange, updateTextAlign }) => {
|
||||
return (
|
||||
<div>
|
||||
<p css={STYLES_LABEL}>Alignment</p>
|
||||
<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_LABEL = (theme) => css`
|
||||
font-size: 0.875rem;
|
||||
color: ${theme.fontPreviewDarkMode ? theme.system.gray70 : theme.system.textGrayLight};
|
||||
margin-bottom: 4px;
|
||||
`;
|
||||
|
||||
const Controller = ({ value, options, onChange, selectSuffix = "", label, min, max, step }) => {
|
||||
return (
|
||||
<div>
|
||||
<P css={STYLES_LABEL}>{label}</P>
|
||||
<div css={css({ display: "flex", alignItems: "center" })}>
|
||||
<Select
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
placeholderSuffix={selectSuffix}
|
||||
/>
|
||||
<div style={{ width: "100%" }}>
|
||||
<Slider
|
||||
min={min}
|
||||
max={max}
|
||||
step={step}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
containerStyle={{ height: "auto", marginLeft: "18px" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
64
components/core/FontFrame/Select.js
Normal file
64
components/core/FontFrame/Select.js
Normal file
@ -0,0 +1,64 @@
|
||||
import * as React from "react";
|
||||
import * as SVG from "~/common/svg";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import { P } from "~/components/system/components/Typography";
|
||||
|
||||
export default function Select({
|
||||
options = [],
|
||||
value,
|
||||
placeholderSuffix = "",
|
||||
inputStyle,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
css={css`
|
||||
position: relative;
|
||||
`}
|
||||
>
|
||||
<div
|
||||
css={[
|
||||
(theme) => css`
|
||||
display: flex;
|
||||
padding: 4px 0px;
|
||||
color: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.textGrayDark};
|
||||
align-items: center;
|
||||
& > * + * {
|
||||
margin-left: 8px;
|
||||
}
|
||||
`,
|
||||
inputStyle,
|
||||
]}
|
||||
>
|
||||
<P
|
||||
dark
|
||||
css={css`
|
||||
font-size: 14px;
|
||||
`}
|
||||
>
|
||||
{value}
|
||||
{placeholderSuffix}
|
||||
</P>
|
||||
<SVG.ChevronDown height="16px" display="block" />
|
||||
</div>
|
||||
<select
|
||||
css={css`
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`}
|
||||
value={value}
|
||||
name="fontSize"
|
||||
{...props}
|
||||
>
|
||||
{options.map((item) => (
|
||||
<option value={item.value}>{item.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import * as React from "react";
|
||||
import * as Events from "~/common/custom-events";
|
||||
|
||||
export const useFont = ({ url, name }, deps) => {
|
||||
const [loading, setLoading] = React.useState(false);
|
||||
@ -14,11 +15,14 @@ export const useFont = ({ url, name }, deps) => {
|
||||
const customFonts = new FontFace(name, `url(${url})`);
|
||||
customFonts.load().then((loadedFont) => {
|
||||
document.fonts.add(loadedFont);
|
||||
prevName.current = name;
|
||||
setLoading(false);
|
||||
|
||||
window.$SLATES_LOADED_FONTS.push(name);
|
||||
});
|
||||
}, deps);
|
||||
return { isFontLoading: loading, fontName: alreadyLoaded || !loading ? name : prevName.current };
|
||||
|
||||
return { isFontLoading: loading, fontName: alreadyLoaded ? name : prevName.current };
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
@ -30,15 +34,21 @@ const initialState = {
|
||||
textAlign: "left",
|
||||
fontSize: 24,
|
||||
column: 1,
|
||||
lineHeight: 1,
|
||||
lineHeight: 100,
|
||||
tracking: 0,
|
||||
leading: 0,
|
||||
},
|
||||
},
|
||||
view: "paragraph",
|
||||
};
|
||||
|
||||
const reducer = (state, action) => {
|
||||
const updateSettingsField = (field, newValue) => ({
|
||||
...state,
|
||||
context: {
|
||||
...state.context,
|
||||
settings: { ...state.context.settings, [field]: newValue },
|
||||
},
|
||||
});
|
||||
switch (action.type) {
|
||||
case "SET_DARK_MODE":
|
||||
return { ...state, context: { ...state.context, darkmode: true } };
|
||||
@ -46,6 +56,18 @@ const reducer = (state, action) => {
|
||||
return { ...state, context: { ...state.context, darkmode: false } };
|
||||
case "TOGGLE_SETTINGS_VISIBILITY":
|
||||
return { ...state, context: { ...state.context, showSettings: !state.context.showSettings } };
|
||||
case "UPDATE_FONT_SIZE":
|
||||
return updateSettingsField("fontSize", action.value);
|
||||
case "UPDATE_LINE_HEIGHT":
|
||||
return updateSettingsField("lineHeight", action.value);
|
||||
case "UPDATE_TRACKING":
|
||||
return updateSettingsField("tracking", action.value);
|
||||
case "UPDATE_COLUMN":
|
||||
return updateSettingsField("column", action.value);
|
||||
case "UPDATE_TEXT_ALIGN":
|
||||
return updateSettingsField("textAlign", action.value);
|
||||
case "UPDATE_VERTICAL_ALIGN":
|
||||
return updateSettingsField("valign", action.value);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
@ -53,13 +75,21 @@ const reducer = (state, action) => {
|
||||
|
||||
export const useFontControls = () => {
|
||||
const [current, send] = React.useReducer(reducer, initialState);
|
||||
const handlers = React.useMemo(
|
||||
() => ({
|
||||
setDarkMode: () => send({ type: "SET_DARK_MODE" }),
|
||||
setLightMode: () => send({ type: "SET_LIGHT_MODE" }),
|
||||
toggleSettings: () => send({ type: "TOGGLE_SETTINGS_VISIBILITY" }),
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const handleDarkMode = (state) =>
|
||||
Events.dispatchCustomEvent({
|
||||
name: "set-slate-theme",
|
||||
detail: { fontPreviewDarkMode: state },
|
||||
});
|
||||
const handlers = React.useMemo(() => ({
|
||||
setDarkMode: () => handleDarkMode(true),
|
||||
setLightMode: () => handleDarkMode(false),
|
||||
toggleSettings: () => send({ type: "TOGGLE_SETTINGS_VISIBILITY" }),
|
||||
updateFontSize: (v) => send({ type: "UPDATE_FONT_SIZE", value: v }),
|
||||
updateLineHeight: (v) => send({ type: "UPDATE_LINE_HEIGHT", value: v }),
|
||||
updateTracking: (v) => send({ type: "UPDATE_TRACKING", value: v }),
|
||||
updateColumn: (v) => send({ type: "UPDATE_COLUMN", value: v }),
|
||||
updateTextAlign: (v) => send({ type: "UPDATE_TEXT_ALIGN", value: v }),
|
||||
updateVerticalAlign: (v) => send({ type: "UPDATE_VERTICAL_ALIGN", value: v }),
|
||||
}));
|
||||
return [current, handlers];
|
||||
};
|
||||
|
@ -1,9 +1,10 @@
|
||||
import * as React from "react";
|
||||
import * as SVG from "~/common/svg";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
|
||||
import Controls from "./Controls";
|
||||
import { useFont, useFontControls } from "./hooks";
|
||||
import { FixedControls, Controls } from "./Controls";
|
||||
|
||||
const Glyphs = ({ dark }) => (
|
||||
<div>
|
||||
@ -14,88 +15,114 @@ const Glyphs = ({ dark }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const GET_STYLES_CONTAINER = (dark) => (theme) => css`
|
||||
const GET_STYLES_CONTAINER = (theme) => css`
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: ${dark ? theme.system.pitchBlack : theme.system.white};
|
||||
padding: 14px 32px 28px;
|
||||
background-color: ${theme.fontPreviewDarkMode ? theme.system.pitchBlack : theme.system.white};
|
||||
padding-top: 14px;
|
||||
`;
|
||||
|
||||
export default function FontFrame({ cid, url, ...props }) {
|
||||
const { isFontLoading, fontName } = useFont({ url, name: cid }, [cid]);
|
||||
const [currentState, { setLightMode, setDarkMode, toggleSettings }] = useFontControls();
|
||||
const [
|
||||
currentState,
|
||||
{
|
||||
setLightMode,
|
||||
setDarkMode,
|
||||
toggleSettings,
|
||||
updateFontSize,
|
||||
updateLineHeight,
|
||||
updateTracking,
|
||||
updateColumn,
|
||||
updateTextAlign,
|
||||
updateVerticalAlign,
|
||||
},
|
||||
] = useFontControls();
|
||||
|
||||
return (
|
||||
<div
|
||||
css={GET_STYLES_CONTAINER(currentState.context.darkmode)}
|
||||
style={{ fontFamily: fontName }}
|
||||
{...props}
|
||||
>
|
||||
<Controls
|
||||
<div css={GET_STYLES_CONTAINER} style={{ fontFamily: fontName }} {...props}>
|
||||
<FixedControls
|
||||
onDarkMode={setDarkMode}
|
||||
onLightMode={setLightMode}
|
||||
onToggleSettings={toggleSettings}
|
||||
isDarkMode={currentState.context.darkmode}
|
||||
isSettingsVisible={currentState.context.showSettings}
|
||||
/>
|
||||
{isFontLoading && (
|
||||
<div
|
||||
css={css({
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: "rgba(0,0,0,0.4)",
|
||||
})}
|
||||
>
|
||||
<p>loading...</p>
|
||||
</div>
|
||||
)}
|
||||
<Sentence
|
||||
content="The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy"
|
||||
valign={currentState.context.settings.valign}
|
||||
textAlign={currentState.context.settings.textAlign}
|
||||
fontSize={currentState.context.settings.fontSize}
|
||||
lineHeight={currentState.context.settings.lineHeight}
|
||||
letterSpacing={currentState.context.settings.tracking}
|
||||
<div style={{ position: "relative", flexGrow: 1 }}>
|
||||
{isFontLoading && (
|
||||
<div
|
||||
css={css({
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: "rgba(0,0,0,0.4)",
|
||||
})}
|
||||
>
|
||||
<p>loading...</p>
|
||||
</div>
|
||||
)}
|
||||
<Sentence
|
||||
content="The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy"
|
||||
valign={currentState.context.settings.valign}
|
||||
textAlign={currentState.context.settings.textAlign}
|
||||
fontSize={currentState.context.settings.fontSize}
|
||||
lineHeight={currentState.context.settings.lineHeight}
|
||||
tracking={currentState.context.settings.tracking}
|
||||
/>
|
||||
</div>
|
||||
<Controls
|
||||
dark={currentState.context.darkmode}
|
||||
settings={currentState.context.settings}
|
||||
updateFontSize={updateFontSize}
|
||||
updateLineHeight={updateLineHeight}
|
||||
updateTracking={updateTracking}
|
||||
updateColumn={updateColumn}
|
||||
updateTextAlign={updateTextAlign}
|
||||
updateVerticalAlign={updateVerticalAlign}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Sentence = ({ content, valign, textAlign, fontSize, lineHeight, tracking, dark }) => {
|
||||
const STYLES_SENTENCE = (theme) => css`
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
overflow-y: scroll;
|
||||
color: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.pitchBlack};
|
||||
padding: 0px 32px 28px;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
`;
|
||||
const Sentence = ({ content, valign, textAlign, fontSize, lineHeight, tracking }) => {
|
||||
const [value, setValue] = React.useState(`<p>${content}</p>`);
|
||||
const mapAlignToFlex = { center: "center", top: "flex-start", bottom: "flex-end" };
|
||||
return (
|
||||
<div
|
||||
contentEditable="true"
|
||||
suppressContentEditableWarning={true}
|
||||
dangerouslySetInnerHTML={{ __html: value }}
|
||||
onInput={(e) => setValue(e.target.innerText)}
|
||||
css={(theme) =>
|
||||
css({
|
||||
display: "flex",
|
||||
flexGrow: 1,
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
marginTop: "12px",
|
||||
overflowY: "scroll",
|
||||
color: dark ? theme.system.white : theme.system.pitchBlack,
|
||||
justifyContent: valign,
|
||||
textAlign,
|
||||
fontSize,
|
||||
lineHeight,
|
||||
letterSpacing: tracking,
|
||||
})
|
||||
}
|
||||
style={{
|
||||
fontSize: `${fontSize}px`,
|
||||
lineHeight: `${lineHeight}%`,
|
||||
letterSpacing: `${tracking}em`,
|
||||
justifyContent: mapAlignToFlex[valign],
|
||||
textAlign,
|
||||
}}
|
||||
css={STYLES_SENTENCE}
|
||||
onKeyDown={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
></div>
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -17,9 +17,8 @@ const STYLES_CONTAINER = css`
|
||||
|
||||
const STYLES_BAR_CONTAINER = css`
|
||||
height: 24px;
|
||||
width: calc(100% - 12px);
|
||||
width: calc(100%);
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
`;
|
||||
|
||||
const STYLES_SLIDER_BAR = css`
|
||||
@ -63,7 +62,7 @@ const STYLES_SLIDER_HANDLE = css`
|
||||
background-color: ${Constants.system.brand};
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
bottom: 16px;
|
||||
bottom: 18px;
|
||||
right: 12px;
|
||||
|
||||
:hover {
|
||||
|
Loading…
Reference in New Issue
Block a user