Skip to content

Commit

Permalink
fix(input): Closing UI no longer blocked by input focus
Browse files Browse the repository at this point in the history
- Users can now close UI with 'Escape' key no regardless of if an input has focus trapped
  • Loading branch information
jag3dagster committed Jan 14, 2024
1 parent a679e17 commit ab0b4fa
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 16 deletions.
44 changes: 43 additions & 1 deletion web/src/layouts/shared/Inputs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Checkbox, Group, InputVariant, MantineSize, NumberInput, TextInput, ThemeIcon, Tooltip, createStyles } from "@mantine/core";
import { Checkbox, Group, InputVariant, MantineSize, NumberInput, Switch, TextInput, ThemeIcon, Tooltip, createStyles } from "@mantine/core";
import { getHotkeyHandler } from "@mantine/hooks";
import React from "react";
import { BsQuestionCircle } from "react-icons/bs";
import { useLocale } from "../../providers/LocaleProvider";
import { useVisibility } from "../../providers/VisibilityProvider";

interface InputProps {
label?: string;
Expand Down Expand Up @@ -56,6 +58,7 @@ const useInputStyles = createStyles((theme) => ({
}));

const NumInput: React.FC<NumberInputProps> = (props) => {
const exitUi = useVisibility((state) => state.exitUI);
const { classes } = useInputStyles();
const variant = props.inputVariant ?? props.disabled ? "filled" : "default";
const arrowSize = props.icArrow !== false ? (props.icArrowSize ?? 10) : undefined;
Expand Down Expand Up @@ -88,12 +91,14 @@ const NumInput: React.FC<NumberInputProps> = (props) => {
</Tooltip>
)
}
onKeyDown={getHotkeyHandler([["Escape", exitUi]])}
/>
);
}

const StringInput: React.FC<StringInputProps> = (props) => {
const locale = useLocale((state) => state.locale);
const exitUi = useVisibility((state) => state.exitUI);
const { classes } = useInputStyles();
const variant = props.inputVariant ?? props.disabled ? "filled" : "default";
const arrowSize = props.icArrow !== false ? (props.icArrowSize ?? 10) : undefined;
Expand Down Expand Up @@ -129,12 +134,14 @@ const StringInput: React.FC<StringInputProps> = (props) => {
</Tooltip>
)
}
onKeyDown={getHotkeyHandler([["Escape", exitUi]])}
/>
</Tooltip>
);
};

const TooltipCheckbox: React.FC<TooltipCheckboxProps> = (props) => {
const exitUi = useVisibility((state) => state.exitUI);
const arrowSize = props.icArrow !== false ? (props.icArrowSize ?? 10) : undefined;

return (
Expand All @@ -143,6 +150,7 @@ const TooltipCheckbox: React.FC<TooltipCheckboxProps> = (props) => {
label={props.label}
checked={props.value}
onChange={(e) => { if (props.setValue !== undefined) props.setValue(e.currentTarget.checked) }}
onKeyDown={getHotkeyHandler([["Escape", exitUi]])}
/>
{
props.infoCircle && (
Expand All @@ -163,6 +171,40 @@ const TooltipCheckbox: React.FC<TooltipCheckboxProps> = (props) => {
);
};

const TooltipSwitch: React.FC<TooltipSwitchProps> = (props) => {
const exitUi = useVisibility((state) => state.exitUI);
const arrowSize = props.icArrow !== false ? (props.icArrowSize ?? 10) : undefined;

return (
<Group spacing={8} align="center" p={5}>
<Switch
label={props.label}
checked={props.value}
onChange={(e) => { if (props.setValue !== undefined) props.setValue(e.currentTarget.checked) }}
size={props.size}
labelPosition={props.labelPosition}
onKeyDown={getHotkeyHandler([["Escape", exitUi]])}
/>
{
props.infoCircle && (
<Tooltip
label={props.infoCircle}
withArrow={props.icArrow ?? true}
arrowSize={arrowSize}
multiline={props.icMultiline ?? true}
width={props.icWidth ?? 200}
>
<ThemeIcon radius="xl" variant="outline" size={16}>
<BsQuestionCircle size={props.iconSize ?? 14} />
</ThemeIcon>
</Tooltip>
)
}
</Group>
);
}

export const MemoNumberInput = React.memo(NumInput);
export const MemoStringInput = React.memo(StringInput);
export const MemoTooltipCheckbox = React.memo(TooltipCheckbox);
export const MemoTooltipSwitch = React.memo(TooltipSwitch);
5 changes: 4 additions & 1 deletion web/src/layouts/shared/RoomSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Select } from "@mantine/core";
import { getHotkeyHandler } from "@mantine/hooks";
import React from "react";
import { useLocale } from "../../providers/LocaleProvider";
import { useVisibility } from "../../providers/VisibilityProvider";
import { RoomsStoreState, useRoomsStore } from "../../store/rooms";

const RoomSelect: React.FC = () => {
const locale = useLocale((state) => state.locale);
const exitUi = useVisibility((state) => state.exitUI);
const [roomSelectList, selectedRoom, roomList] = useRoomsStore((state) => [state.roomSelectList, state.selectedRoom, state.roomList]);
const [setSelectedRoom, setActiveRoom] = useRoomsStore((state) => [state.setSelectedRoom, state.setActiveRoom]);

Expand All @@ -30,9 +33,9 @@ const RoomSelect: React.FC = () => {
nothingFound={locale("ui_room_select_nothing_found")}
data={roomSelectList}
maxDropdownHeight={200}
onKeyDown={getHotkeyHandler([["Escape", exitUi]])}
/>
)
};

export default RoomSelect;
export const MemoRoomSelect = React.memo(RoomSelect);
21 changes: 11 additions & 10 deletions web/src/layouts/views/portals/components/DebugMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ActionIcon, Menu, Switch } from "@mantine/core";
import { ActionIcon, Menu } from "@mantine/core";
import { useEffect } from "react";
import { FaGear } from "react-icons/fa6";
import { MemoTooltipSwitch } from "../../../shared/Inputs";
import { useLocale } from "../../../../providers/LocaleProvider";
import { usePortalsStore } from "../../../../store/portals";
import { fetchNui } from "../../../../utils/fetchNui";
Expand All @@ -25,25 +26,25 @@ const DebugMenu: React.FC = () => {
<Menu.Dropdown>
<Menu.Label>{locale("ui_portal_debug")}</Menu.Label>
<Menu.Item
component={Switch}
component={MemoTooltipSwitch}
closeMenuOnClick={false}
label={locale("ui_portal_debug_draw_info")}
checked={enableInfo ?? false}
onChange={() => toggleSwitch("enablePortalInfo")}
value={enableInfo ?? false}
setValue={() => toggleSwitch("enablePortalInfo")}
/>
<Menu.Item
component={Switch}
component={MemoTooltipSwitch}
closeMenuOnClick={false}
label={locale("ui_portal_debug_draw_outline")}
checked={enableOutline ?? false}
onChange={() => toggleSwitch("enablePortalOutline")}
value={enableOutline ?? false}
setValue={() => toggleSwitch("enablePortalOutline")}
/>
<Menu.Item
component={Switch}
component={MemoTooltipSwitch}
closeMenuOnClick={false}
label={locale("ui_portal_debug_draw_fill")}
checked={enableFill ?? false}
onChange={() => toggleSwitch("enablePortalFill")}
value={enableFill ?? false}
setValue={() => toggleSwitch("enablePortalFill")}
/>
</Menu.Dropdown>
</Menu>
Expand Down
9 changes: 5 additions & 4 deletions web/src/layouts/views/portals/components/PortalInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Alert, Center, Checkbox, Divider, Group, Paper, Space, Switch, Table, Text, Title } from "@mantine/core";
import { Alert, Center, Checkbox, Divider, Group, Paper, Space, Table, Title } from "@mantine/core";
import { useEffect, useState } from "react";
import EntitySettings from "./EntitySettings";
import { MemoTooltipSwitch } from "../../../shared/Inputs";
import { useLocale } from "../../../../providers/LocaleProvider";
import { useGeneralStore } from "../../../../store/general";
import { usePortalsStore } from "../../../../store/portals";
Expand Down Expand Up @@ -63,12 +64,12 @@ const PortalInfo: React.FC<Props> = (props) => {
<Title order={5}>
{`${props.portal.mloPortalIndex}. ${intRoom.displayName} [${intRoom.index}] ↔ ${extRoom.displayName} [${extRoom.index}]`}
</Title>
<Switch
<MemoTooltipSwitch
size={"xs"}
label={locale("ui_portal_debug_point")}
labelPosition={"left"}
checked={navigate}
onChange={() => setNavigate(!navigate)}
value={navigate}
setValue={() => setNavigate(!navigate)}
/>
</Group>
<Center py={10} px={15} >
Expand Down

0 comments on commit ab0b4fa

Please sign in to comment.