Skip to content

Commit

Permalink
Fix biome errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrause committed Jan 21, 2025
1 parent cb38b2d commit cc28239
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 133 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
2 changes: 1 addition & 1 deletion biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"rules": {
"recommended": true,
"correctness": {
//"useExhaustiveDependencies": "off"
"useExhaustiveDependencies": "off"
},
"complexity": {
"noBannedTypes": "off",
Expand Down
5 changes: 3 additions & 2 deletions src/components/actions/Link/Link.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof Link>;
Expand Down Expand Up @@ -45,7 +46,7 @@ export const Descenders: Story = {
export const Scroll: Story = {
render: (args) => (
<>
<a id="anchor" href="/" onClick={evt => { evt.preventDefault(); }}>Anchor</a>
<DummyLink id="anchor">Anchor</DummyLink>
<OverflowTester openDefault/>
<Link {...args} href="#anchor"/>
<OverflowTester openDefault/>
Expand Down
12 changes: 4 additions & 8 deletions src/components/containers/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ const ActionButton = (props: ActionButtonProps) => {
<Button trimmed
{...props}
className={cx(cl['bk-banner__action'], cl['bk-banner__action--button'], props.className)}
onClick={event => {
event.stopPropagation(); // Prevent this from triggering any click handlers on the Banner itself (e.g. toasts)
props.onClick?.(event);
}}
// Prevent clicks from triggering any click handlers on the Banner itself (e.g. to prevent toast dismissal)
onClick={event => { event.stopPropagation(); props.onClick?.(event); }}
/>
);
};
Expand All @@ -69,10 +67,8 @@ const ActionIcon = ({ tooltip, ...buttonProps }: ActionIconProps) => {
<Button trimmed
{...buttonProps}
className={cx(cl['bk-banner__action'], cl['bk-banner__action--icon'], buttonProps.className)}
onClick={event => {
event.stopPropagation(); // Prevent this from triggering any click handlers on the Banner itself (e.g. toasts)
buttonProps.onClick?.(event);
}}
// Prevent clicks from triggering any click handlers on the Banner itself (e.g. to prevent toast dismissal)
onClick={event => { event.stopPropagation(); buttonProps.onClick?.(event); }}
/>
</TooltipProvider>
);
Expand Down
5 changes: 2 additions & 3 deletions src/components/forms/controls/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ export const Option = (props: OptionProps) => {
cl['bk-select__option'],
propsRest.className,
)}
{...getItemProps({
onClick: () => { selectOption(option); },
})}
{...getItemProps()}
onPress={() => { selectOption(option); }}
>
{label ?? propsRest.children}
</Button>
Expand Down
101 changes: 57 additions & 44 deletions src/components/navigations/Stepper/Stepper.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/navigations/Stepper/Stepper.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof Stepper>;
Expand All @@ -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,
};
});
Expand Down
103 changes: 54 additions & 49 deletions src/components/navigations/Stepper/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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<ComponentProps<'ul'> & {
export type StepperProps = React.PropsWithChildren<ComponentProps<'nav'> & {
/** Whether this component should be unstyled. */
unstyled?: undefined | boolean,

/** Step items. */
steps: Step[],
steps: Array<Step>,

/** 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,
Expand All @@ -45,51 +52,49 @@ export type StepperProps = React.PropsWithChildren<ComponentProps<'ul'> & {
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 (
<ul
<nav
aria-label="Steps" // Recommendation is to override this per usage
{...propsRest}
className={cx({
bk: true,
[cl['bk-stepper']]: !unstyled,
[cl['bk-stepper--horizontal']]: direction === 'horizontal',
[cl['bk-stepper--vertical']]: direction === 'vertical',
}, propsRest.className)}
className={cx(
'bk',
{ [cl['bk-stepper']]: !unstyled },
{ [cl['bk-stepper--horizontal']]: direction === 'horizontal' },
{ [cl['bk-stepper--vertical']]: direction === 'vertical' },
propsRest.className,
)}
>
{steps.map((step, index) => {
if (step.hide) return null;
const isActive = step.stepKey === activeKey;
const isChecked = index < steps.findIndex(step => step.stepKey === activeKey);
return (
<li
role="tab"
tabIndex={0}
aria-selected={isActive ? 'true': 'false'}
data-tab={step.stepKey}
key={step.stepKey}
className={cx({
[cl['bk-stepper__item']]: true,
[cl['bk-stepper__item--checked']]: isChecked,
}, step.className)}
onClick={() => { onSwitch(step.stepKey); }}
onKeyDown={(event) => { handleKeyDown(event, step.stepKey); }}
>
<span className={cx(cl['bk-stepper__item__circle'])}>
{isChecked
? <Icon icon="check" className={cx(cl['bk-stepper__item__circle__icon'])}/>
: index + 1
}
</span>
<span className={cx(cl['bk-stepper__item__title'])}>{step.title}</span>
{step.isOptional && <span className={cx(cl['bk-stepper__item__optional'])}>(Optional)</span>}
</li>
)
})}
</ul>
<ol>
{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 (
<li key={step.stepKey} aria-current={isActive}>
<Button
unstyled
//nonactive={!isActive} // Note: the buttons *look* nonactive, but are actually clickable
className={cx(
cl['bk-stepper__item'],
{ [cl['bk-stepper__item--checked']]: isChecked },
step.className,
)}
onPress={() => { onSwitch(step.stepKey); }}
>
<span aria-label={`Step ${stepNumber}:`} className={cx(cl['bk-stepper__item__indicator'])}>
{isChecked
? <Icon icon="check" className={cx(cl['bk-stepper__item__indicator__icon'])}/>
: stepNumber
}
</span>
<span className={cx(cl['bk-stepper__item__title'])}>{step.title}</span>
{step.isOptional && <span className={cx(cl['bk-stepper__item__optional'])}>(Optional)</span>}
</Button>
</li>
)
})}
</ol>
</nav>
);
};
Loading

0 comments on commit cc28239

Please sign in to comment.