From d49c5eef033fe179bf3d2a512debcb117b293290 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Mon, 23 Oct 2023 13:10:00 +0200 Subject: [PATCH] - Add new ContentMenuButton, which is MenuButton with only custom content, such as Checkbox. - Add new FilterCheckbox component, which is a row with checkbox designed for the filter. - Add common focus outline CSS property to theme. - Add common focus outline to checkbox. This should be applied to all focusable elements, but we are starting with checkbox. --- packages/core/src/types/ElementProps.tsx | 2 + .../ui/action-menu/ActionMenuItemContent.tsx | 2 +- .../menu-button/ContentMenuButton.module.css | 25 ++++++++ .../buttons/menu-button/ContentMenuButton.tsx | 21 +++++++ .../ui/buttons/menu-button/IconMenuButton.tsx | 58 +++++++++---------- .../ui/buttons/menu-button/MenuButton.tsx | 2 +- .../ui/buttons/menu-button/MenuButtonLink.tsx | 2 +- .../{ => internal}/MenuButtonContent.tsx | 4 +- packages/elements/src/index.ts | 1 + .../filter-checkbox/FilterCheckbox.tsx | 22 +++++++ .../filter-checkbox/FilterCheckboxList.tsx | 23 ++++++++ .../components/SimpleCheckboxListSection.tsx | 36 +++++------- packages/filter/src/index.ts | 2 + .../ui/checkbox/Checkbox.module.css | 7 +-- packages/theme/src/styles/default-theme.css | 3 + 15 files changed, 149 insertions(+), 61 deletions(-) create mode 100644 packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.module.css create mode 100644 packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.tsx rename packages/elements/src/components/ui/buttons/menu-button/{ => internal}/MenuButtonContent.tsx (91%) create mode 100644 packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckbox.tsx create mode 100644 packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckboxList.tsx diff --git a/packages/core/src/types/ElementProps.tsx b/packages/core/src/types/ElementProps.tsx index c1a0136e1..861c6071d 100644 --- a/packages/core/src/types/ElementProps.tsx +++ b/packages/core/src/types/ElementProps.tsx @@ -21,6 +21,8 @@ export type H1Props = ComponentPropsWithoutRef<"h1">; export type ButtonElementProps = ComponentPropsWithoutRef<"button">; +export type LabelElementProps = ComponentPropsWithoutRef<"label">; + export type InputElementProps = ComponentPropsWithoutRef<"input">; export type AnchorElementProps = ComponentPropsWithoutRef<"a">; diff --git a/packages/elements/src/components/ui/action-menu/ActionMenuItemContent.tsx b/packages/elements/src/components/ui/action-menu/ActionMenuItemContent.tsx index 6d5e460e3..bf736ff40 100644 --- a/packages/elements/src/components/ui/action-menu/ActionMenuItemContent.tsx +++ b/packages/elements/src/components/ui/action-menu/ActionMenuItemContent.tsx @@ -7,7 +7,7 @@ import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { MenuButtonContent, MenuButtonContentProps, -} from "../buttons/menu-button/MenuButtonContent"; +} from "../buttons/menu-button/internal/MenuButtonContent"; export interface ActionMenuItemContentProps extends DivProps, diff --git a/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.module.css b/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.module.css new file mode 100644 index 000000000..4215b70db --- /dev/null +++ b/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.module.css @@ -0,0 +1,25 @@ +.contentMenuButton { + --current-outline: none; + + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + border-radius: var(--swui-max-border-radius); + min-height: 40px; + padding: 4px 0; + outline: none; + + &:hover { + background: var(--lhds-color-ui-400); + } + + &:focus { + background: var(--lhds-color-ui-500); + } + + &:active { + background: var(--lhds-color-ui-500); + } +} diff --git a/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.tsx b/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.tsx new file mode 100644 index 000000000..22bd7a7ef --- /dev/null +++ b/packages/elements/src/components/ui/buttons/menu-button/ContentMenuButton.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; +import { forwardRef, ReactNode } from "react"; +import { LabelElementProps, Row } from "@stenajs-webui/core"; +import styles from "./ContentMenuButton.module.css"; + +export interface ContentMenuButtonProps extends LabelElementProps { + children?: ReactNode; +} + +export const ContentMenuButton = forwardRef< + HTMLLabelElement, + ContentMenuButtonProps +>(({ children, ...labelProps }, ref) => { + return ( + + ); +}); diff --git a/packages/elements/src/components/ui/buttons/menu-button/IconMenuButton.tsx b/packages/elements/src/components/ui/buttons/menu-button/IconMenuButton.tsx index 8a1516bb3..aa09eb262 100644 --- a/packages/elements/src/components/ui/buttons/menu-button/IconMenuButton.tsx +++ b/packages/elements/src/components/ui/buttons/menu-button/IconMenuButton.tsx @@ -21,37 +21,35 @@ export const IconMenuButton = forwardRef< ref ) { return ( - - + - + + + + + + ); }); diff --git a/packages/elements/src/components/ui/buttons/menu-button/MenuButton.tsx b/packages/elements/src/components/ui/buttons/menu-button/MenuButton.tsx index 71d5e8096..45e72c1c9 100644 --- a/packages/elements/src/components/ui/buttons/menu-button/MenuButton.tsx +++ b/packages/elements/src/components/ui/buttons/menu-button/MenuButton.tsx @@ -13,7 +13,7 @@ import { cssColor } from "@stenajs-webui/theme"; import { MenuButtonGroupBox } from "./MenuButtonGroupBox"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { Icon } from "../../icon/Icon"; -import { MenuButtonContent } from "./MenuButtonContent"; +import { MenuButtonContent } from "./internal/MenuButtonContent"; import { stenaAngleDown, stenaAngleUp, diff --git a/packages/elements/src/components/ui/buttons/menu-button/MenuButtonLink.tsx b/packages/elements/src/components/ui/buttons/menu-button/MenuButtonLink.tsx index c25f86c9d..df020258e 100644 --- a/packages/elements/src/components/ui/buttons/menu-button/MenuButtonLink.tsx +++ b/packages/elements/src/components/ui/buttons/menu-button/MenuButtonLink.tsx @@ -4,7 +4,7 @@ import { AnchorElementProps, Box, Row } from "@stenajs-webui/core"; import cx from "classnames"; import styles from "./MenuButton.module.css"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; -import { MenuButtonContent } from "./MenuButtonContent"; +import { MenuButtonContent } from "./internal/MenuButtonContent"; import { MenuButtonVariant } from "./MenuButton"; export type MenuButtonLinkRenderer = ( diff --git a/packages/elements/src/components/ui/buttons/menu-button/MenuButtonContent.tsx b/packages/elements/src/components/ui/buttons/menu-button/internal/MenuButtonContent.tsx similarity index 91% rename from packages/elements/src/components/ui/buttons/menu-button/MenuButtonContent.tsx rename to packages/elements/src/components/ui/buttons/menu-button/internal/MenuButtonContent.tsx index 34b92f757..ad90c9e24 100644 --- a/packages/elements/src/components/ui/buttons/menu-button/MenuButtonContent.tsx +++ b/packages/elements/src/components/ui/buttons/menu-button/internal/MenuButtonContent.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Box, Row, Text } from "@stenajs-webui/core"; -import { Icon } from "../../icon/Icon"; -import styles from "./MenuButton.module.css"; +import { Icon } from "../../../icon/Icon"; +import styles from "../MenuButton.module.css"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { ReactNode } from "react"; diff --git a/packages/elements/src/index.ts b/packages/elements/src/index.ts index 8d6f77f4f..956e3e8d0 100644 --- a/packages/elements/src/index.ts +++ b/packages/elements/src/index.ts @@ -19,6 +19,7 @@ export * from "./components/ui/buttons/SecondaryButton"; export * from "./components/ui/buttons/common/ButtonCommon"; export * from "./components/ui/buttons/common/ButtonContent"; export * from "./components/ui/buttons/menu-button/MenuButton"; +export * from "./components/ui/buttons/menu-button/ContentMenuButton"; export * from "./components/ui/buttons/menu-button/IconMenuButton"; export * from "./components/ui/buttons/menu-button/MenuButtonLink"; export * from "./components/ui/buttons/menu-button/IconMenuButtonLink"; diff --git a/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckbox.tsx b/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckbox.tsx new file mode 100644 index 000000000..72356a5f1 --- /dev/null +++ b/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckbox.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; +import { Row, Text } from "@stenajs-webui/core"; +import { ContentMenuButton } from "@stenajs-webui/elements"; +import { Checkbox, CheckboxProps } from "@stenajs-webui/forms"; + +export interface FilterCheckboxProps extends CheckboxProps { + label: string; +} + +export const FilterCheckbox: React.FC = ({ + label, + ...checkboxProps +}) => { + return ( + + + + {label} + + + ); +}; diff --git a/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckboxList.tsx b/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckboxList.tsx new file mode 100644 index 000000000..09e57d871 --- /dev/null +++ b/packages/filter/src/features/search-filter/features/filter-checkbox/FilterCheckboxList.tsx @@ -0,0 +1,23 @@ +import * as React from "react"; +import { PropsWithChildren } from "react"; +import { Column } from "@stenajs-webui/core"; + +export interface FilterCheckboxListProps extends PropsWithChildren { + maxHeight?: string; +} + +export const FilterCheckboxList: React.FC = ({ + children, + maxHeight, +}) => { + return ( + + {children} + + ); +}; diff --git a/packages/filter/src/features/search-filter/section-factories/boolean-record/components/SimpleCheckboxListSection.tsx b/packages/filter/src/features/search-filter/section-factories/boolean-record/components/SimpleCheckboxListSection.tsx index 04c5cdf3e..953828265 100644 --- a/packages/filter/src/features/search-filter/section-factories/boolean-record/components/SimpleCheckboxListSection.tsx +++ b/packages/filter/src/features/search-filter/section-factories/boolean-record/components/SimpleCheckboxListSection.tsx @@ -3,12 +3,10 @@ import { SearchFilterSection, SearchFilterSectionProps, } from "../../../components/SearchFilterSection"; -import { Column, Row } from "@stenajs-webui/core"; -import { - CheckboxWithLabel, - ValueAndOnValueChangeProps, -} from "@stenajs-webui/forms"; +import { ValueAndOnValueChangeProps } from "@stenajs-webui/forms"; import { BooleanRecord, BooleanRecordOptions } from "../BooleanRecordTypes"; +import { FilterCheckbox } from "../../../features/filter-checkbox/FilterCheckbox"; +import { FilterCheckboxList } from "../../../features/filter-checkbox/FilterCheckboxList"; export interface SimpleCheckboxSectionProps extends SearchFilterSectionProps, @@ -23,22 +21,20 @@ export const SimpleCheckboxListSection = ({ ...sectionProps }: SimpleCheckboxSectionProps): React.ReactElement => ( - + {options?.map((d) => ( - - - onValueChange?.({ - ...value, - [d.value]: v, - }) - } - /> - + + onValueChange?.({ + ...value, + [d.value]: v, + }) + } + /> ))} - + ); diff --git a/packages/filter/src/index.ts b/packages/filter/src/index.ts index 7ceaeb7f2..a66c08929 100644 --- a/packages/filter/src/index.ts +++ b/packages/filter/src/index.ts @@ -17,6 +17,8 @@ export * from "./features/search-filter/context/SearchFilterDispatchContext"; export * from "./features/search-filter/hooks/UseLocalSearchFilterState"; export * from "./features/search-filter/redux/SearchFilterRedux"; export * from "./features/search-filter/types/FilterEntity"; +export * from "./features/search-filter/features/filter-checkbox/FilterCheckbox"; +export * from "./features/search-filter/features/filter-checkbox/FilterCheckboxList"; export * from "./features/search-filter/features/chips/SearchFilterChips"; export * from "./features/search-filter/features/chips/SectionChips"; export * from "./features/search-filter/features/chips/SearchFilterChip"; diff --git a/packages/forms/src/components/ui/checkbox/Checkbox.module.css b/packages/forms/src/components/ui/checkbox/Checkbox.module.css index 4a624c1b3..cdc5f0497 100644 --- a/packages/forms/src/components/ui/checkbox/Checkbox.module.css +++ b/packages/forms/src/components/ui/checkbox/Checkbox.module.css @@ -163,12 +163,7 @@ } &:focus-visible { - &:checked { - box-shadow: var(--swui-checkbox-checked-focus-shadow); - } - &:not(:checked) { - box-shadow: var(--swui-checkbox-unchecked-focus-shadow); - } + outline: var(--swui-focus-outline); } & + label { diff --git a/packages/theme/src/styles/default-theme.css b/packages/theme/src/styles/default-theme.css index 6d79ef541..046933f43 100644 --- a/packages/theme/src/styles/default-theme.css +++ b/packages/theme/src/styles/default-theme.css @@ -109,4 +109,7 @@ --swui-metrics-space: 8px; --swui-default-item-height: 40px; + + /* Focus outline */ + --swui-focus-outline: 2px solid var(--modern-blue); }