mirror of
https://github.com/docmost/docmost.git
synced 2026-08-28 17:27:06 +08:00
fix(base): close view popovers on Escape regardless of focus; drop redundant property switch tab stop
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
|||||||
} from "@/ee/base/property-types/property-type.registry";
|
} from "@/ee/base/property-types/property-type.registry";
|
||||||
import { FilterPersonInput } from "./filter-person-input";
|
import { FilterPersonInput } from "./filter-person-input";
|
||||||
import { FilterDateInput } from "./filter-date-input";
|
import { FilterDateInput } from "./filter-date-input";
|
||||||
|
import { useEscapeClose } from "@/ee/base/hooks/use-escape-close";
|
||||||
import viewClasses from "@/ee/base/styles/views.module.css";
|
import viewClasses from "@/ee/base/styles/views.module.css";
|
||||||
|
|
||||||
const OPERATORS: { value: FilterOperator; labelKey: string }[] = [
|
const OPERATORS: { value: FilterOperator; labelKey: string }[] = [
|
||||||
@@ -191,6 +192,7 @@ export function ViewFilterConfigPopover({
|
|||||||
children,
|
children,
|
||||||
}: ViewFilterConfigProps) {
|
}: ViewFilterConfigProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
useEscapeClose(opened, onClose);
|
||||||
|
|
||||||
const propertyOptions = properties.map((p) => ({
|
const propertyOptions = properties.map((p) => ({
|
||||||
value: p.id,
|
value: p.id,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Table } from "@tanstack/react-table";
|
|||||||
import { IBaseRow, IBaseProperty } from "@/ee/base/types/base.types";
|
import { IBaseRow, IBaseProperty } from "@/ee/base/types/base.types";
|
||||||
import { propertyTypes } from "@/ee/base/property-types/property-type.registry";
|
import { propertyTypes } from "@/ee/base/property-types/property-type.registry";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useEscapeClose } from "@/ee/base/hooks/use-escape-close";
|
||||||
import cellClasses from "@/ee/base/styles/cells.module.css";
|
import cellClasses from "@/ee/base/styles/cells.module.css";
|
||||||
import viewClasses from "@/ee/base/styles/views.module.css";
|
import viewClasses from "@/ee/base/styles/views.module.css";
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ export function ViewPropertyVisibility({
|
|||||||
children,
|
children,
|
||||||
}: ViewPropertyVisibilityProps) {
|
}: ViewPropertyVisibilityProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
useEscapeClose(opened, onClose);
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
return table
|
return table
|
||||||
@@ -122,6 +124,9 @@ export function ViewPropertyVisibility({
|
|||||||
return (
|
return (
|
||||||
<UnstyledButton
|
<UnstyledButton
|
||||||
key={col.id}
|
key={col.id}
|
||||||
|
role="switch"
|
||||||
|
aria-checked={isVisible}
|
||||||
|
aria-disabled={!canHide || undefined}
|
||||||
className={cellClasses.menuItem}
|
className={cellClasses.menuItem}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (canHide) {
|
if (canHide) {
|
||||||
@@ -140,6 +145,8 @@ export function ViewPropertyVisibility({
|
|||||||
size="xs"
|
size="xs"
|
||||||
checked={isVisible}
|
checked={isVisible}
|
||||||
disabled={!canHide}
|
disabled={!canHide}
|
||||||
|
tabIndex={-1}
|
||||||
|
aria-hidden
|
||||||
onChange={() => {}}
|
onChange={() => {}}
|
||||||
// Clicking the track synthesizes a second click on the hidden input which bubbles
|
// Clicking the track synthesizes a second click on the hidden input which bubbles
|
||||||
// to UnstyledButton, firing handleToggle twice. stopPropagation blocks only that
|
// to UnstyledButton, firing handleToggle twice. stopPropagation blocks only that
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
ViewSortConfig,
|
ViewSortConfig,
|
||||||
} from "@/ee/base/types/base.types";
|
} from "@/ee/base/types/base.types";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useEscapeClose } from "@/ee/base/hooks/use-escape-close";
|
||||||
import viewClasses from "@/ee/base/styles/views.module.css";
|
import viewClasses from "@/ee/base/styles/views.module.css";
|
||||||
|
|
||||||
type ViewSortConfigProps = {
|
type ViewSortConfigProps = {
|
||||||
@@ -35,6 +36,7 @@ export function ViewSortConfigPopover({
|
|||||||
children,
|
children,
|
||||||
}: ViewSortConfigProps) {
|
}: ViewSortConfigProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
useEscapeClose(opened, onClose);
|
||||||
const [draft, setDraft] = useState<ViewSortConfig | null>(null);
|
const [draft, setDraft] = useState<ViewSortConfig | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
export function useEscapeClose(opened: boolean, onClose: () => void) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!opened) return;
|
||||||
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === "Escape" && !e.defaultPrevented) onClose();
|
||||||
|
};
|
||||||
|
document.addEventListener("keydown", onKeyDown);
|
||||||
|
return () => document.removeEventListener("keydown", onKeyDown);
|
||||||
|
}, [opened, onClose]);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user