feat: compact layout for tablets (#9910)

* 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>
This commit is contained in:
Ryan Di
2025-09-12 10:18:31 +10:00
committed by GitHub
parent 414182f599
commit 204e06b77b
32 changed files with 1527 additions and 147 deletions

View File

@@ -1,4 +1,5 @@
import * as Popover from "@radix-ui/react-popover";
import clsx from "clsx";
import React, { useCallback, useMemo } from "react";
import { FONT_FAMILY } from "@excalidraw/common";
@@ -58,6 +59,7 @@ interface FontPickerProps {
onHover: (fontFamily: FontFamilyValues) => void;
onLeave: () => void;
onPopupChange: (open: boolean) => void;
compactMode?: boolean;
}
export const FontPicker = React.memo(
@@ -69,6 +71,7 @@ export const FontPicker = React.memo(
onHover,
onLeave,
onPopupChange,
compactMode = false,
}: FontPickerProps) => {
const defaultFonts = useMemo(() => DEFAULT_FONTS, []);
const onSelectCallback = useCallback(
@@ -81,18 +84,29 @@ export const FontPicker = React.memo(
);
return (
<div role="dialog" aria-modal="true" className="FontPicker__container">
<div className="buttonList">
<RadioSelection<FontFamilyValues | false>
type="button"
options={defaultFonts}
value={selectedFontFamily}
onClick={onSelectCallback}
/>
</div>
<ButtonSeparator />
<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} />
<FontPickerTrigger
selectedFontFamily={selectedFontFamily}
isOpened={isOpened}
/>
{isOpened && (
<FontPickerList
selectedFontFamily={selectedFontFamily}