Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Biome linter errors + TS errors + accessibility violations #113

Merged
merged 6 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/storybook_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ name: Storybook Tests

on:
push:
branches: [ "**" ]
branches:
- "master"

jobs:
build:

runs-on: ubuntu-latest

strategy:
Expand Down
3 changes: 3 additions & 0 deletions .storybook/test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const config: TestRunnerConfig = {
await injectAxe(page);
},
async postVisit(page, context) {
// Workaround for https://github.com/dequelabs/axe-core/issues/3426
await new Promise(resolve => setTimeout(resolve, 200));

// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);

Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@
"files.eol": "\n",
"javascript.preferences.quoteStyle": "single",
"typescript.tsdk": "node_modules/typescript/lib", // Use the TypeScript SDK from the current project
"typescript.preferences.autoImportFileExcludePatterns": [
"storybook/internal/**/*"
],
}
13 changes: 9 additions & 4 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,24 @@
},
"linter": {
"enabled": true,
"include": ["app/**/*", "src/**/*", "tests/**/*"],
"include": ["app", "src", "tests"],

"ignore": [
"node_modules",
"dist",
"src/components/tables/MultiSearch/MultiSearch.tsx", // Ignore for now (need to focus on type errors first)
"tests/installation/**/*"
],
"tests/installation"
],
"rules": {
"recommended": true,
"correctness": {
//"useExhaustiveDependencies": "off"
},
"complexity": {
"noBannedTypes": "off",
"noForEach": "off",
"useOptionalChain": "off"
"useOptionalChain": "off",
"useLiteralKeys": "off"
},
"style": {
"useImportType": "off",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"test": "npm run check:types && npm run lint:style",
"test-ui": "vitest --ui",
"coverage": "vitest run --coverage",
"test:storybook": "test-storybook --failOnConsole --browsers chromium",
"test:storybook": "test-storybook --failOnConsole --browsers chromium --maxWorkers=1",
"test:storybook-ci": "\n npx playwright install --with-deps chromium && npx concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"npm run storybook:build --quiet && npx http-server storybook-static --port 6006 --silent\" \"npx wait-on tcp:6006 && npm run test:storybook\"\n ",
"start": "npm run storybook:serve",
"prepare": "npm run build"
Expand Down
3 changes: 2 additions & 1 deletion package.json.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ const packageConfig = {

// Browser automation tests
// https://github.com/storybookjs/test-runner?tab=readme-ov-file#2-running-against-locally-built-storybooks-in-ci
'test:storybook': 'test-storybook --failOnConsole --browsers chromium', // For text only: FORCE_COLOR=false
'test:storybook': 'test-storybook --failOnConsole --browsers chromium --maxWorkers=1', // For text only: FORCE_COLOR=false
// Note: the following assumes `localhost:6006` is free, so don't run it if a dev server is already running
'test:storybook-ci': `
npx playwright install --with-deps chromium\
&& npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue"\
Expand Down
2 changes: 1 addition & 1 deletion src/components/actions/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
align-items: center;
gap: 0.3ch;

@include bk.font(bk.$font-family-display, bk.$font-weight-medium);
@include bk.font(bk.$font-family-display, bk.$font-weight-semibold);
/* letter-spacing: 0.1ch; */
text-transform: uppercase;

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
16 changes: 6 additions & 10 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 Expand Up @@ -153,7 +149,7 @@ export const Banner = Object.assign(
)}
>
{/* Apply `bk-theme--light` on all children (but not the box itself). */}
<header className={cx('bk-theme--light', cl['bk-banner__header'])}>
<div className={cx('bk-theme--light', cl['bk-banner__header'])}>
<div className={cx(cl['bk-banner__header__text'])}>
<strong className={cx(cl['bk-banner__title'])}>
<BannerVariantIcon variant={variant} className={cx(cl['bk-banner__title__icon'])}/>
Expand All @@ -178,7 +174,7 @@ export const Banner = Object.assign(
</ActionIcon>
}
</div>
</header>
</div>

{!compact && children &&
<article className={cx('bk-body-text', 'bk-theme--light', cl['bk-banner__message'])}>{children}</article>
Expand Down
4 changes: 3 additions & 1 deletion src/components/forms/controls/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export default {
tags: ['autodocs'],
argTypes: {
},
args: {},
args: {
'aria-label': 'Test checkbox',
},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ export const DateTimePicker = (props: DateTimePickerProps) => {
)}
>
<DatePicker
aria-label="Date input"
selected={date}
onChange={onChange}
dateFormat={dateFormat}
placeholderText={placeholderText}
/>
<TimePicker
aria-label="Time input"
time={time}
onUpdate={onTimeUpdate}
className={cx(cl['bk-date-time-picker--time-picker'])}
Expand Down
7 changes: 5 additions & 2 deletions src/components/forms/controls/Input/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ export const InvalidInput: Story = {
async play({ canvasElement }) {
const canvas = within(canvasElement);
const input = canvas.getByPlaceholderText('Example');
const form = input.closest('form');
if (!form) { throw new Error(`Missing <form> element`); }

await delay(100);
await userEvent.type(input, 'invalid');
await delay(100);
await userEvent.keyboard('{Enter}');
await fireEvent.submit(input.closest('form')!);
await userEvent.click(input.closest('form')!);
await fireEvent.submit(form);
await userEvent.click(form);
},
};
4 changes: 3 additions & 1 deletion src/components/forms/controls/Radio/Radio.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export default {
tags: ['autodocs'],
argTypes: {
},
args: {},
args: {
'aria-label': 'Test radio button',
},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
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
1 change: 1 addition & 0 deletions src/components/forms/controls/Switch/Switch.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default {
tags: ['autodocs'],
argTypes: {},
args: {
'aria-label': 'Test switch',
defaultChecked: true,
},
decorators: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const TimePickerStory: Story = {

return (
<div>
<TimePicker time={time} onUpdate={setTime}/>
<TimePicker aria-label="Example time picker" time={time} onUpdate={setTime}/>
<p>
The selected time is: {time.hours}:{time.minutes}
</p>
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
Loading
Loading