diff --git a/src/components/Actions.tsx b/src/components/Actions.tsx index e7ced60c87..63d2ce03d2 100644 --- a/src/components/Actions.tsx +++ b/src/components/Actions.tsx @@ -151,23 +151,14 @@ export const SelectedShapeActions = ({ ); }; -const LIBRARY_ICON = ( - // fa-th-large - <svg viewBox="0 0 512 512"> - <path d="M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z" /> - </svg> -); - export const ShapesSwitcher = ({ canvas, elementType, setAppState, - isLibraryOpen, }: { canvas: HTMLCanvasElement | null; elementType: ExcalidrawElement["type"]; setAppState: React.Component<any, AppState>["setState"]; - isLibraryOpen: boolean; }) => ( <> {SHAPES.map(({ value, icon, key }, index) => { @@ -201,19 +192,6 @@ export const ShapesSwitcher = ({ /> ); })} - <ToolButton - className="Shape ToolIcon_type_button__library" - type="button" - icon={LIBRARY_ICON} - name="editor-library" - keyBindingLabel="9" - aria-keyshortcuts="9" - title={`${capitalizeString(t("toolBar.library"))} — 9`} - aria-label={capitalizeString(t("toolBar.library"))} - onClick={() => { - setAppState({ isLibraryOpen: !isLibraryOpen }); - }} - /> </> ); diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index dc245fc248..2fe0789683 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -36,7 +36,7 @@ import { Island } from "./Island"; import "./LayerUI.scss"; import { LibraryUnit } from "./LibraryUnit"; import { LoadingMessage } from "./LoadingMessage"; -import { LockIcon } from "./LockIcon"; +import { LockButton } from "./LockButton"; import { MobileMenu } from "./MobileMenu"; import { PasteChartDialog } from "./PasteChartDialog"; import { Section } from "./Section"; @@ -47,6 +47,7 @@ import { Tooltip } from "./Tooltip"; import { UserList } from "./UserList"; import Library from "../data/library"; import { JSONExportDialog } from "./JSONExportDialog"; +import { LibraryButton } from "./LibraryButton"; interface LayerUIProps { actionManager: ActionManager; @@ -570,6 +571,12 @@ const LayerUI = ({ {(heading) => ( <Stack.Col gap={4} align="start"> <Stack.Row gap={1}> + <LockButton + zenModeEnabled={zenModeEnabled} + checked={appState.elementLocked} + onChange={onLockToggle} + title={t("toolBar.lock")} + /> <Island padding={1} className={clsx({ "zen-mode": zenModeEnabled })} @@ -581,15 +588,12 @@ const LayerUI = ({ canvas={canvas} elementType={appState.elementType} setAppState={setAppState} - isLibraryOpen={appState.isLibraryOpen} /> </Stack.Row> </Island> - <LockIcon - zenModeEnabled={zenModeEnabled} - checked={appState.elementLocked} - onChange={onLockToggle} - title={t("toolBar.lock")} + <LibraryButton + appState={appState} + setAppState={setAppState} /> </Stack.Row> {libraryMenu} diff --git a/src/components/LibraryButton.tsx b/src/components/LibraryButton.tsx new file mode 100644 index 0000000000..570f61a943 --- /dev/null +++ b/src/components/LibraryButton.tsx @@ -0,0 +1,45 @@ +import clsx from "clsx"; +import { t } from "../i18n"; +import { AppState } from "../types"; +import { capitalizeString } from "../utils"; + +const LIBRARY_ICON = ( + <svg viewBox="0 0 576 512"> + <path + fill="currentColor" + d="M542.22 32.05c-54.8 3.11-163.72 14.43-230.96 55.59-4.64 2.84-7.27 7.89-7.27 13.17v363.87c0 11.55 12.63 18.85 23.28 13.49 69.18-34.82 169.23-44.32 218.7-46.92 16.89-.89 30.02-14.43 30.02-30.66V62.75c.01-17.71-15.35-31.74-33.77-30.7zM264.73 87.64C197.5 46.48 88.58 35.17 33.78 32.05 15.36 31.01 0 45.04 0 62.75V400.6c0 16.24 13.13 29.78 30.02 30.66 49.49 2.6 149.59 12.11 218.77 46.95 10.62 5.35 23.21-1.94 23.21-13.46V100.63c0-5.29-2.62-10.14-7.27-12.99z" + ></path> + </svg> +); + +export const LibraryButton: React.FC<{ + appState: AppState; + setAppState: React.Component<any, AppState>["setState"]; +}> = ({ appState, setAppState }) => { + return ( + <label + className={clsx( + "ToolIcon ToolIcon_type_floating ToolIcon__library zen-mode-visibility", + `ToolIcon_size_m`, + { + "zen-mode-visibility--hidden": appState.zenModeEnabled, + }, + )} + title={`${capitalizeString(t("toolBar.library"))} — 9`} + style={{ marginInlineStart: "var(--space-factor)" }} + > + <input + className="ToolIcon_type_checkbox" + type="checkbox" + name="editor-library" + onChange={(event) => { + setAppState({ isLibraryOpen: event.target.checked }); + }} + checked={appState.isLibraryOpen} + aria-label={capitalizeString(t("toolBar.library"))} + aria-keyshortcuts="9" + /> + <div className="ToolIcon__icon">{LIBRARY_ICON}</div> + </label> + ); +}; diff --git a/src/components/LockIcon.tsx b/src/components/LockButton.tsx similarity index 93% rename from src/components/LockIcon.tsx rename to src/components/LockButton.tsx index eaae9aa91f..e4691fad33 100644 --- a/src/components/LockIcon.tsx +++ b/src/components/LockButton.tsx @@ -10,7 +10,6 @@ type LockIconProps = { name?: string; checked: boolean; onChange?(): void; - size?: LockIconSize; zenModeEnabled?: boolean; }; @@ -40,12 +39,12 @@ const ICONS = { ), }; -export const LockIcon = (props: LockIconProps) => { +export const LockButton = (props: LockIconProps) => { return ( <label className={clsx( "ToolIcon ToolIcon__lock ToolIcon_type_floating zen-mode-visibility", - `ToolIcon_size_${props.size || DEFAULT_SIZE}`, + `ToolIcon_size_${DEFAULT_SIZE}`, { "zen-mode-visibility--hidden": props.zenModeEnabled, }, diff --git a/src/components/MobileMenu.tsx b/src/components/MobileMenu.tsx index 6c62f68dab..a8e0e88935 100644 --- a/src/components/MobileMenu.tsx +++ b/src/components/MobileMenu.tsx @@ -13,9 +13,10 @@ import { SelectedShapeActions, ShapesSwitcher } from "./Actions"; import { Section } from "./Section"; import CollabButton from "./CollabButton"; import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars"; -import { LockIcon } from "./LockIcon"; +import { LockButton } from "./LockButton"; import { UserList } from "./UserList"; import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle"; +import { LibraryButton } from "./LibraryButton"; type MobileMenuProps = { appState: AppState; @@ -64,15 +65,15 @@ export const MobileMenu = ({ canvas={canvas} elementType={appState.elementType} setAppState={setAppState} - isLibraryOpen={appState.isLibraryOpen} /> </Stack.Row> </Island> - <LockIcon + <LockButton checked={appState.elementLocked} onChange={onLockToggle} title={t("toolBar.lock")} /> + <LibraryButton appState={appState} setAppState={setAppState} /> </Stack.Row> {libraryMenu} </Stack.Col> diff --git a/src/components/ToolIcon.scss b/src/components/ToolIcon.scss index faecf65f0f..5aa90395c6 100644 --- a/src/components/ToolIcon.scss +++ b/src/components/ToolIcon.scss @@ -8,10 +8,18 @@ position: relative; font-family: Cascadia; cursor: pointer; - background-color: var(--button-gray-1); -webkit-tap-highlight-color: transparent; border-radius: var(--space-factor); user-select: none; + + background-color: var(--button-gray-1); + + &:hover { + background-color: var(--button-gray-2); + } + &:active { + background-color: var(--button-gray-3); + } } .ToolIcon--plain { @@ -66,14 +74,6 @@ margin: 0; font-size: inherit; - &:hover { - background-color: var(--button-gray-1); - } - - &:active { - background-color: var(--button-gray-2); - } - &:focus { box-shadow: 0 0 0 2px var(--focus-highlight-color); } @@ -86,6 +86,14 @@ } } + &:hover { + background-color: var(--button-gray-2); + } + + &:active { + background-color: var(--button-gray-3); + } + &--show { visibility: visible; } @@ -103,6 +111,9 @@ &:not(.ToolIcon_toggle_opaque):checked + .ToolIcon__icon { background-color: var(--button-gray-2); + &:active { + background-color: var(--button-gray-3); + } } &:focus + .ToolIcon__icon { @@ -130,12 +141,21 @@ } .ToolIcon__icon { + background-color: var(--button-gray-1); + &:hover { + background-color: var(--button-gray-2); + } + &:active { + background-color: var(--button-gray-3); + } + width: 2rem; height: 2em; } } .ToolIcon.ToolIcon__lock { + margin-inline-end: var(--space-factor); &.ToolIcon_type_floating { margin-left: 0.1rem; } @@ -166,10 +186,9 @@ // move the lock button out of the way on small viewports // it begins to collide with the GitHub icon before we switch to mobile mode @media (max-width: 760px) { - .ToolIcon.ToolIcon__lock { + .ToolIcon.ToolIcon_type_floating { display: inline-block; position: absolute; - top: 60px; right: -8px; margin-left: 0; @@ -194,6 +213,14 @@ position: static; } } + .ToolIcon.ToolIcon__library { + top: 100px; + } + + .ToolIcon.ToolIcon__lock { + margin-inline-end: 0; + top: 60px; + } } .unlocked-icon {