From cc282392fee5fd1c775c49db39b8f7acb3d137c0 Mon Sep 17 00:00:00 2001 From: mkrause Date: Tue, 21 Jan 2025 18:43:40 +0100 Subject: [PATCH] Fix biome errors. --- .vscode/settings.json | 5 +- biome.jsonc | 2 +- src/components/actions/Link/Link.stories.tsx | 5 +- src/components/containers/Banner/Banner.tsx | 12 +- .../forms/controls/Select/Select.tsx | 5 +- .../navigations/Stepper/Stepper.module.scss | 101 +++++++++-------- .../navigations/Stepper/Stepper.stories.tsx | 4 +- .../navigations/Stepper/Stepper.tsx | 103 +++++++++--------- src/components/navigations/Tabs/Tabs.tsx | 15 +-- .../overlays/DropdownMenu/DropdownMenu.tsx | 4 +- .../overlays/ToastProvider/ToastProvider.tsx | 7 +- .../overlays/Tooltip/Tooltip.stories.tsx | 13 ++- .../tables/DataTable/table/DataTable.tsx | 2 +- src/typography/BodyText/BodyText.stories.tsx | 6 +- src/util/storybook/StorybookLink.tsx | 9 ++ tsconfig.app.json | 1 - 16 files changed, 161 insertions(+), 133 deletions(-) create mode 100644 src/util/storybook/StorybookLink.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index ad440a7a..eab5d4e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,5 +19,8 @@ "editor.trimAutoWhitespace": false, "files.eol": "\n", "javascript.preferences.quoteStyle": "single", - "typescript.tsdk": "node_modules/typescript/lib", // Use the TypeScript SDK from the current project + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.preferences.autoImportFileExcludePatterns": [ + "storybook/internal/**/*" + ], // Use the TypeScript SDK from the current project } diff --git a/biome.jsonc b/biome.jsonc index 14ee060a..277998ae 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -34,7 +34,7 @@ "rules": { "recommended": true, "correctness": { - //"useExhaustiveDependencies": "off" + "useExhaustiveDependencies": "off" }, "complexity": { "noBannedTypes": "off", diff --git a/src/components/actions/Link/Link.stories.tsx b/src/components/actions/Link/Link.stories.tsx index 85ce6452..bb6db4f2 100644 --- a/src/components/actions/Link/Link.stories.tsx +++ b/src/components/actions/Link/Link.stories.tsx @@ -5,9 +5,10 @@ import * as React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; +import { DummyLink } from '../../../util/storybook/StorybookLink.tsx'; +import { OverflowTester } from '../../../util/storybook/OverflowTester.tsx'; import { Link } from './Link.tsx'; -import { OverflowTester } from '../../../util/storybook/OverflowTester.tsx'; type LinkArgs = React.ComponentProps; @@ -45,7 +46,7 @@ export const Descenders: Story = { export const Scroll: Story = { render: (args) => ( <> - { evt.preventDefault(); }}>Anchor + Anchor diff --git a/src/components/containers/Banner/Banner.tsx b/src/components/containers/Banner/Banner.tsx index 37eb60ff..c3151f3f 100644 --- a/src/components/containers/Banner/Banner.tsx +++ b/src/components/containers/Banner/Banner.tsx @@ -45,10 +45,8 @@ const ActionButton = (props: ActionButtonProps) => { diff --git a/src/components/navigations/Stepper/Stepper.module.scss b/src/components/navigations/Stepper/Stepper.module.scss index e9e82101..15aa9b25 100644 --- a/src/components/navigations/Stepper/Stepper.module.scss +++ b/src/components/navigations/Stepper/Stepper.module.scss @@ -8,53 +8,62 @@ .bk-stepper { @include bk.component-base(bk-stepper); + --bk-stepper-indicator-size: #{bk.rem-from-px(28)}; + display: flex; + + > ol { + display: contents; + } + &.bk-stepper--horizontal { - display: flex; - gap: bk.$spacing-9; + flex-direction: row; + column-gap: bk.$spacing-9; } &.bk-stepper--vertical { - .bk-stepper__item { - &:not(:first-child) { - margin-top: bk.$spacing-9; + flex-direction: column; + row-gap: bk.$spacing-9; - .bk-stepper__item__circle { - &::before { - position: absolute; - content: ''; - width: 0; - height: bk.$spacing-9; - top: -42px; - left: 50%; - border: 0.5px solid #{bk.$theme-stepper-border-disabled}; - } - } + // Draw a line between subsequent items + li + li .bk-stepper__item__indicator { + &::before { + content: ''; + position: absolute; + top: calc(-1 * bk.$spacing-9 - bk.$size-2); + left: calc(50% - bk.$size-2 / 2); + width: 0; + height: bk.$spacing-9; + border-left: bk.$size-2 solid bk.$theme-stepper-border-disabled; } } } .bk-stepper__item { + cursor: pointer; + display: flex; align-items: center; - color: #{bk.$theme-stepper-text-disabled}; - cursor: pointer; + color: bk.$theme-stepper-text-disabled; - .bk-stepper__item__circle { - display: flex; - align-items: center; - justify-content: center; - position: relative; + .bk-stepper__item__indicator { + position: relative; // Needed for the vertical line `position: absolute` + flex-shrink: 0; + margin-right: bk.$spacing-3; - border: 2px solid #{bk.$theme-stepper-border-disabled}; + aspect-ratio: 1; + width: var(--bk-stepper-indicator-size); + + border: bk.$size-2 solid #{bk.$theme-stepper-border-disabled}; border-radius: 50%; - width: 28px; - height: 28px; font-weight: bk.$font-weight-bold; font-size: bk.$font-size-m; - } - - .bk-stepper__item__circle__icon { - font-size: bk.$font-size-xs; + + display: grid; + place-content: center; + + .bk-stepper__item__indicator__icon { + font-size: bk.$font-size-xs; + } } .bk-stepper__item__title { @@ -65,22 +74,26 @@ margin-left: bk.$spacing-2; font-size: bk.$font-size-xs; } - - &[aria-selected="true"] { - color: #{bk.$theme-stepper-text-selected}; - - .bk-stepper__item__circle { - border-color: #{bk.$theme-stepper-border-default}; - background-color: #{bk.$theme-stepper-background-default}; - color: #{bk.$theme-stepper-text-selected-number}; - } - } + } + + // Any steps we've already visited + .bk-stepper__item--checked { + color: bk.$theme-stepper-text-selected; - &.bk-stepper__item--checked { - color: #{bk.$theme-stepper-text-selected}; + .bk-stepper__item__indicator { + border-color: bk.$theme-stepper-border-default; + } + } + + // The currently active step + [aria-current="true"] { + .bk-stepper__item { + color: bk.$theme-stepper-text-selected; - .bk-stepper__item__circle { - border-color: #{bk.$theme-stepper-border-default}; + .bk-stepper__item__indicator { + border-color: bk.$theme-stepper-border-default; + background-color: bk.$theme-stepper-background-default; + color: bk.$theme-stepper-text-selected-number; } } } diff --git a/src/components/navigations/Stepper/Stepper.stories.tsx b/src/components/navigations/Stepper/Stepper.stories.tsx index 8bea4946..1bb25695 100644 --- a/src/components/navigations/Stepper/Stepper.stories.tsx +++ b/src/components/navigations/Stepper/Stepper.stories.tsx @@ -6,7 +6,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import * as React from 'react'; -import { Stepper, Step } from './Stepper.tsx'; +import { type Step, Stepper } from './Stepper.tsx'; type StepperArgs = React.ComponentProps; @@ -27,7 +27,7 @@ export default { const defaultSteps: Step[] = [1,2,3,4].map(index => { return { stepKey: `${index}`, - title: `Step${index}`, + title: `Step ${index}`, isOptional: index === 4, }; }); diff --git a/src/components/navigations/Stepper/Stepper.tsx b/src/components/navigations/Stepper/Stepper.tsx index 7700790e..8f1a5aa3 100644 --- a/src/components/navigations/Stepper/Stepper.tsx +++ b/src/components/navigations/Stepper/Stepper.tsx @@ -6,9 +6,18 @@ import * as React from 'react'; import { type ClassNameArgument, type ComponentProps, classNames as cx } from '../../../util/componentUtil.ts'; import { Icon } from '../../graphics/Icon/Icon.tsx'; +import { Button } from '../../actions/Button/Button.tsx'; import cl from './Stepper.module.scss'; + +/* +References: +- https://stackoverflow.com/questions/52932018/making-a-step-progress-indicator-accessible-for-screen-readers +- https://www.telerik.com/design-system/docs/components/stepper/accessibility +- https://cauldron.dequelabs.com/components/Stepper +*/ + export { cl as SteppersClassNames }; export type Step = { @@ -18,23 +27,21 @@ export type Step = { hide?: boolean, isOptional?: boolean, }; - export type StepperKey = Step['stepKey']; - export type StepperDirection = 'vertical' | 'horizontal'; -export type StepperProps = React.PropsWithChildren & { +export type StepperProps = React.PropsWithChildren & { /** Whether this component should be unstyled. */ unstyled?: undefined | boolean, /** Step items. */ - steps: Step[], + steps: Array, /** Active key of step. */ - activeKey?: string, + activeKey?: undefined | string, /** Whether this component should be displayed vertically or horizontally. */ - direction?: StepperDirection, + direction?: undefined | StepperDirection, /** Callback executed when active step is changed. */ onSwitch: (stepKey: StepperKey) => void, @@ -45,51 +52,49 @@ export type StepperProps = React.PropsWithChildren & { export const Stepper = (props: StepperProps) => { const { unstyled = false, steps = [], activeKey, direction = 'vertical', onSwitch, ...propsRest } = props; - const handleKeyDown = (event: React.KeyboardEvent, stepKey: Step['stepKey']) => { - if (event.key === 'Enter') { - onSwitch(stepKey); - } - }; - return ( -
    - {steps.map((step, index) => { - if (step.hide) return null; - const isActive = step.stepKey === activeKey; - const isChecked = index < steps.findIndex(step => step.stepKey === activeKey); - return ( -
  • { onSwitch(step.stepKey); }} - onKeyDown={(event) => { handleKeyDown(event, step.stepKey); }} - > - - {isChecked - ? - : index + 1 - } - - {step.title} - {step.isOptional && (Optional)} -
  • - ) - })} -
+
    + {steps.map((step, index) => { + if (step.hide) return null; + const isActive = step.stepKey === activeKey; + const stepNumber = index + 1; + const isChecked = index < steps.findIndex(step => step.stepKey === activeKey); + return ( +
  1. + +
  2. + ) + })} +
+ ); }; diff --git a/src/components/navigations/Tabs/Tabs.tsx b/src/components/navigations/Tabs/Tabs.tsx index 9ac275c4..b7f56fa3 100644 --- a/src/components/navigations/Tabs/Tabs.tsx +++ b/src/components/navigations/Tabs/Tabs.tsx @@ -83,10 +83,11 @@ export const Tabs = (props: TabsProps) => {
    {tabs.map(tab => { @@ -94,13 +95,13 @@ export const Tabs = (props: TabsProps) => { const isActive = tab.props.tabKey === activeKey; return (
  • { onSwitch(tab.props.tabKey); }} + onClick={() => { onSwitch(tab.props.tabKey); }} // FIXME: add a Button and use that instead > {tab.props.title}
  • diff --git a/src/components/overlays/DropdownMenu/DropdownMenu.tsx b/src/components/overlays/DropdownMenu/DropdownMenu.tsx index 3280c611..1bd93813 100644 --- a/src/components/overlays/DropdownMenu/DropdownMenu.tsx +++ b/src/components/overlays/DropdownMenu/DropdownMenu.tsx @@ -76,7 +76,7 @@ export const Action = (props: ActionProps) => { cl['bk-dropdown-menu__item--action'], propsRest.className, )} - onClick={() => { onActivate(context); }} + onPress={() => { onActivate(context); }} > {icon && } {label ?? propsRest.children} @@ -121,7 +121,7 @@ export const Option = (props: OptionProps) => { cl['bk-dropdown-menu__item--option'], propsRest.className, )} - onClick={() => { selectOption(option); }} + onPress={() => { selectOption(option); }} > {icon && } {label ?? propsRest.children} diff --git a/src/components/overlays/ToastProvider/ToastProvider.tsx b/src/components/overlays/ToastProvider/ToastProvider.tsx index 937a4151..0c349745 100644 --- a/src/components/overlays/ToastProvider/ToastProvider.tsx +++ b/src/components/overlays/ToastProvider/ToastProvider.tsx @@ -190,10 +190,9 @@ export const Toaster = (props: ToasterProps) => { onClose={() => { toastStore.dismissToast(toastId); }} - onClick={event => { - event.stopPropagation(); - toastStore.dismissToast(toastId); - }} + // Handle dismiss signals (e.g. clicking or tapping on the toast) + onClick={event => { event.stopPropagation(); toastStore.dismissToast(toastId); }} + // Handle interest signals (e.g. hovering over the toast) onMouseEnter={event => { event.stopPropagation(); toastStore.pauseAutoClose(toastId); }} onTouchStart={event => { event.stopPropagation(); toastStore.pauseAutoClose(toastId); }} onMouseLeave={event => { event.stopPropagation(); toastStore.resumeAutoClose(toastId); }} diff --git a/src/components/overlays/Tooltip/Tooltip.stories.tsx b/src/components/overlays/Tooltip/Tooltip.stories.tsx index 06722000..55f3ec2d 100644 --- a/src/components/overlays/Tooltip/Tooltip.stories.tsx +++ b/src/components/overlays/Tooltip/Tooltip.stories.tsx @@ -2,14 +2,15 @@ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import type { Meta, StoryObj } from '@storybook/react'; - -import { classNames as cx } from '../../../util/componentUtil.ts'; import * as React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { DummyLink } from '../../../util/storybook/StorybookLink.tsx'; import { OverflowTester } from '../../../util/storybook/OverflowTester.tsx'; + import { Button } from '../../actions/Button/Button.tsx'; -import { TooltipClassNames, Tooltip } from './Tooltip.tsx'; + +import { Tooltip } from './Tooltip.tsx'; type TooltipArgs = React.ComponentProps; @@ -75,7 +76,7 @@ export const TooltipScroll: StoryObj = { render: () => (

    - Lorem ipsum dolor sit amet, { event.preventDefault(); }}>consectetur adipiscing elit. Pellentesque eget sem ut neque lobortis pharetra nec vel quam. Etiam sem neque, gravida sed pharetra ut, vehicula quis lectus. Donec ac rhoncus purus. Proin ultricies augue vitae purus feugiat, in ultrices lorem aliquet. Donec eleifend ac dolor a auctor. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget sem ut neque lobortis pharetra nec vel quam. Etiam sem neque, gravida sed pharetra ut, vehicula quis lectus. Donec ac rhoncus purus. Proin ultricies augue vitae purus feugiat, in ultrices lorem aliquet. Donec eleifend ac dolor a auctor.

    Cras ac suscipit nibh. Fusce tincidunt iaculis dapibus. Vivamus sit amet neque eu velit tincidunt semper. Donec at magna aliquam mi consectetur imperdiet. Donec pretium placerat quam, in sodales purus porta vitae. Phasellus nisl justo, luctus vel mi vel, sollicitudin. @@ -103,7 +104,7 @@ const TooltipNativeAnchoringControlled = () => { This is a tooltip with a lot of text that gives more information about the element. - It has a { event.preventDefault(); }}>link you can focus. + It has a link you can focus.