* feat: allow the hiding of top picks * feat: allow the hiding of default fonts * refactor: rename to compactMode * feat: introduce layout (incomplete) * tweak icons * do not show border * lint * add isTouchMobile to device * add isTouchMobile to device * refactor to use showCompactSidebar instead * hide library label in compact * fix icon color in dark theme * fix library and share btns getting hidden in smaller tablet widths * update tests * use a smaller gap between shapes * proper fix of range * quicker switching between different popovers * to not show properties panel at all when editing text * fix switching between different popovers for texts * fix popover not closable and font search auto focus * change properties for a new or editing text * change icon for more style settings * use bolt icon for extra actions * fix breakpoints * use rem for icon sizes * fix tests * improve switching between triggers (incomplete) * improve trigger switching (complete) * clean up code * put compact into app state * fix button size * remove redundant PanelComponentProps["compactMode"] * move fontSize UI on top * mobile detection (breakpoints incomplete) * tweak compact mode detection * rename appState prop & values * update snapshots --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
130 lines
3.4 KiB
TypeScript
130 lines
3.4 KiB
TypeScript
import * as Popover from "@radix-ui/react-popover";
|
|
import clsx from "clsx";
|
|
import React, { useCallback, useMemo } from "react";
|
|
|
|
import { FONT_FAMILY } from "@excalidraw/common";
|
|
|
|
import type { FontFamilyValues } from "@excalidraw/element/types";
|
|
|
|
import { t } from "../../i18n";
|
|
import { RadioSelection } from "../RadioSelection";
|
|
import { ButtonSeparator } from "../ButtonSeparator";
|
|
import {
|
|
FontFamilyCodeIcon,
|
|
FontFamilyNormalIcon,
|
|
FreedrawIcon,
|
|
} from "../icons";
|
|
|
|
import { FontPickerList } from "./FontPickerList";
|
|
import { FontPickerTrigger } from "./FontPickerTrigger";
|
|
|
|
import "./FontPicker.scss";
|
|
|
|
export const DEFAULT_FONTS = [
|
|
{
|
|
value: FONT_FAMILY.Excalifont,
|
|
icon: FreedrawIcon,
|
|
text: t("labels.handDrawn"),
|
|
testId: "font-family-hand-drawn",
|
|
},
|
|
{
|
|
value: FONT_FAMILY.Nunito,
|
|
icon: FontFamilyNormalIcon,
|
|
text: t("labels.normal"),
|
|
testId: "font-family-normal",
|
|
},
|
|
{
|
|
value: FONT_FAMILY["Comic Shanns"],
|
|
icon: FontFamilyCodeIcon,
|
|
text: t("labels.code"),
|
|
testId: "font-family-code",
|
|
},
|
|
];
|
|
|
|
const defaultFontFamilies = new Set(DEFAULT_FONTS.map((x) => x.value));
|
|
|
|
export const isDefaultFont = (fontFamily: number | null) => {
|
|
if (!fontFamily) {
|
|
return false;
|
|
}
|
|
|
|
return defaultFontFamilies.has(fontFamily);
|
|
};
|
|
|
|
interface FontPickerProps {
|
|
isOpened: boolean;
|
|
selectedFontFamily: FontFamilyValues | null;
|
|
hoveredFontFamily: FontFamilyValues | null;
|
|
onSelect: (fontFamily: FontFamilyValues) => void;
|
|
onHover: (fontFamily: FontFamilyValues) => void;
|
|
onLeave: () => void;
|
|
onPopupChange: (open: boolean) => void;
|
|
compactMode?: boolean;
|
|
}
|
|
|
|
export const FontPicker = React.memo(
|
|
({
|
|
isOpened,
|
|
selectedFontFamily,
|
|
hoveredFontFamily,
|
|
onSelect,
|
|
onHover,
|
|
onLeave,
|
|
onPopupChange,
|
|
compactMode = false,
|
|
}: FontPickerProps) => {
|
|
const defaultFonts = useMemo(() => DEFAULT_FONTS, []);
|
|
const onSelectCallback = useCallback(
|
|
(value: number | false) => {
|
|
if (value) {
|
|
onSelect(value);
|
|
}
|
|
},
|
|
[onSelect],
|
|
);
|
|
|
|
return (
|
|
<div
|
|
role="dialog"
|
|
aria-modal="true"
|
|
className={clsx("FontPicker__container", {
|
|
"FontPicker__container--compact": compactMode,
|
|
})}
|
|
>
|
|
{!compactMode && (
|
|
<div className="buttonList">
|
|
<RadioSelection<FontFamilyValues | false>
|
|
type="button"
|
|
options={defaultFonts}
|
|
value={selectedFontFamily}
|
|
onClick={onSelectCallback}
|
|
/>
|
|
</div>
|
|
)}
|
|
{!compactMode && <ButtonSeparator />}
|
|
<Popover.Root open={isOpened} onOpenChange={onPopupChange}>
|
|
<FontPickerTrigger
|
|
selectedFontFamily={selectedFontFamily}
|
|
isOpened={isOpened}
|
|
/>
|
|
{isOpened && (
|
|
<FontPickerList
|
|
selectedFontFamily={selectedFontFamily}
|
|
hoveredFontFamily={hoveredFontFamily}
|
|
onSelect={onSelectCallback}
|
|
onHover={onHover}
|
|
onLeave={onLeave}
|
|
onOpen={() => onPopupChange(true)}
|
|
onClose={() => onPopupChange(false)}
|
|
/>
|
|
)}
|
|
</Popover.Root>
|
|
</div>
|
|
);
|
|
},
|
|
(prev, next) =>
|
|
prev.isOpened === next.isOpened &&
|
|
prev.selectedFontFamily === next.selectedFontFamily &&
|
|
prev.hoveredFontFamily === next.hoveredFontFamily,
|
|
);
|