diff --git a/TODO.md b/TODO.md
index 4913bde..e8c73b8 100644
--- a/TODO.md
+++ b/TODO.md
@@ -66,3 +66,4 @@
# Others
- [X] Add `select-none` to input labels, etc.
+- [ ] Test all components!
diff --git a/categories/action/react/.eslintrc b/categories/action/react/.eslintrc
index 8a6172f..8cd8ffc 100644
--- a/categories/action/react/.eslintrc
+++ b/categories/action/react/.eslintrc
@@ -3,7 +3,10 @@
"rules": {
"quote-props": "off",
"react/jsx-props-no-spreading": "off",
- "react/button-has-type": "off"
+ "react/button-has-type": "off",
+ "@typescript-eslint/no-unsafe-call": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+ "import/no-extraneous-dependencies": "off"
},
"extends": [
"lxsmnsyc/typescript/react"
diff --git a/categories/action/react/package.json b/categories/action/react/package.json
index ed95c06..98bde3e 100644
--- a/categories/action/react/package.json
+++ b/categories/action/react/package.json
@@ -18,6 +18,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/node": "^18.14.1",
"@types/react": "^18.0.27",
+ "@types/testing-library__jest-dom": "^5.14.7",
"eslint": "^8.35.0",
"eslint-config-lxsmnsyc": "^0.5.0",
"jsdom": "^21.1.0",
diff --git a/categories/action/react/setupTests.ts b/categories/action/react/setupTests.ts
deleted file mode 100644
index b210af5..0000000
--- a/categories/action/react/setupTests.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import matchers from '@testing-library/jest-dom/matchers';
-import { expect } from 'vitest';
-
-expect.extend(matchers);
diff --git a/categories/action/react/src/components/ActionButton/ActionButton.test.tsx b/categories/action/react/src/components/ActionButton/ActionButton.test.tsx
index 7498c15..eb81840 100644
--- a/categories/action/react/src/components/ActionButton/ActionButton.test.tsx
+++ b/categories/action/react/src/components/ActionButton/ActionButton.test.tsx
@@ -12,13 +12,12 @@ import {
it,
expect, afterEach,
} from 'vitest';
+import matchers from '@testing-library/jest-dom/matchers';
import {
ActionButton,
} from '.';
-import matchers from '@testing-library/jest-dom/matchers';
-expect.extend(matchers);
-vi.mock('@tesseract-design/web-base-button');
+expect.extend(matchers);
describe('ActionButton', () => {
afterEach(() => {
@@ -65,7 +64,7 @@ describe('ActionButton', () => {
});
it('handles click events', async () => {
- const onClick = vi.fn().mockImplementationOnce((e) => { e.preventDefault() });
+ const onClick = vi.fn().mockImplementationOnce((e) => { e.preventDefault(); });
render(
{
${'small'} | ${'h-10'}
${'medium'} | ${'h-12'}
${'large'} | ${'h-16'}
- `('on %s size', ({
+ `('on $size size', ({
size,
className,
}: { size: Button.Size, className: string }) => {
@@ -127,7 +126,7 @@ describe('ActionButton', () => {
${'bare'} | ${'bg-negative'}
${'outline'} | ${'border-2'}
${'filled'} | ${'bg-primary'}
- `('renders a button with variant %s', ({
+ `('renders a button with $variant variant', ({
variant,
className,
}: { variant: Button.Variant, className: string }) => {
@@ -157,7 +156,7 @@ describe('ActionButton', () => {
render(
Foo
-
+ ,
);
const children: HTMLElement = screen.getByTestId('children');
@@ -168,7 +167,7 @@ describe('ActionButton', () => {
render(
+ />,
);
const button: HTMLButtonElement = screen.getByRole('button');
expect(button).toHaveProperty('type', buttonType);
@@ -178,7 +177,7 @@ describe('ActionButton', () => {
render(
+ />,
);
const button: HTMLButtonElement = screen.getByTestId('button');
expect(button).toBeDisabled();
diff --git a/categories/choice/react/package.json b/categories/choice/react/package.json
index 8763864..e3b842d 100644
--- a/categories/choice/react/package.json
+++ b/categories/choice/react/package.json
@@ -15,8 +15,10 @@
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
+ "@testing-library/user-event": "^14.4.3",
"@types/node": "^18.14.1",
"@types/react": "^18.0.27",
+ "@types/testing-library__jest-dom": "^5.14.7",
"eslint": "^8.35.0",
"eslint-config-lxsmnsyc": "^0.5.0",
"jsdom": "^21.1.0",
@@ -83,4 +85,4 @@
"typesVersions": {
"*": {}
}
-}
\ No newline at end of file
+}
diff --git a/categories/choice/react/pridepack.json b/categories/choice/react/pridepack.json
index f07dd67..0bc7a8f 100644
--- a/categories/choice/react/pridepack.json
+++ b/categories/choice/react/pridepack.json
@@ -1,9 +1,3 @@
{
- "target": "es2018",
- "entryPoints": {
- ".": "src/index.ts",
- "./dist/DropdownSelect.css": "src/components/DropdownSelect/DropdownSelect.css",
- "./dist/RadioButton.css": "src/components/RadioButton/RadioButton.css",
- "./dist/RadioTickBox.css": "src/components/RadioTickBox/RadioTickBox.css"
- }
+ "target": "es2018"
}
diff --git a/categories/choice/react/src/components/ComboBox/index.tsx b/categories/choice/react/src/components/ComboBox/index.tsx
index 5460f70..b23a6c5 100644
--- a/categories/choice/react/src/components/ComboBox/index.tsx
+++ b/categories/choice/react/src/components/ComboBox/index.tsx
@@ -10,7 +10,7 @@ export type ComboBoxDerivedElement = HTMLInputElement;
/**
* Props of the {@link ComboBox} component.
*/
-export interface ComboBoxProps extends Omit, 'size' | 'type' | 'style' | 'label' | 'list' | 'inputMode'> {
+export interface ComboBoxProps extends Omit, 'size' | 'type' | 'label' | 'list' | 'inputMode'> {
/**
* Short textual description indicating the nature of the component's value.
*/
@@ -73,6 +73,7 @@ export const ComboBox = React.forwardRef(
children,
inputMode = 'text' as const,
id: idProp,
+ style,
...etcProps
}: ComboBoxProps,
forwardedRef,
@@ -106,6 +107,7 @@ export const ComboBox = React.forwardRef(
},
className,
)}
+ style={style}
>
{
+ afterEach(() => {
+ cleanup();
+ });
+
+ it('renders a combobox', () => {
+ render();
+ const combobox = screen.getByRole('combobox');
+ expect(combobox).toBeInTheDocument();
+ });
+
+ it('renders a border', () => {
+ render(
+ ,
+ );
+ const border = screen.getByTestId('border');
+ expect(border).toBeInTheDocument();
+ });
+
+ it('renders a label', () => {
+ render(
+ ,
+ );
+ const combobox = screen.getByLabelText('foo');
+ expect(combobox).toBeInTheDocument();
+ const label = screen.getByTestId('label');
+ expect(label).toHaveTextContent('foo');
+ });
+
+ it('renders a hidden label', () => {
+ render(
+ ,
+ );
+ const combobox = screen.getByLabelText('foo');
+ expect(combobox).toBeInTheDocument();
+ const label = screen.getByTestId('label');
+ expect(label).toHaveClass('sr-only');
+ });
+
+ it('renders a hint', () => {
+ render(
+ ,
+ );
+ const hint = screen.getByTestId('hint');
+ expect(hint).toBeInTheDocument();
+ });
+
+ it('render options with implicit values', () => {
+ render(
+
+
+
+ ,
+ );
+ const combobox = screen.getByRole('combobox');
+ expect(combobox.children).toHaveLength(2);
+ });
+
+ it('renders valid options', () => {
+ render(
+
+
+
+ ,
+ );
+ const combobox = screen.getByRole('combobox');
+ expect(combobox.children).toHaveLength(2);
+ });
+
+ it('renders option groups', () => {
+ render(
+
+
+
+ ,
+ );
+ const combobox = screen.getByRole('combobox');
+ expect(combobox.children).toHaveLength(2);
+ expect(combobox.children[0].children).toHaveLength(1);
+ expect(combobox.children[1].children).toHaveLength(2);
+ });
+
+ describe.each`
+ size | inputClassNames | hintClassNames | indicatorClassNames
+ ${'small'} | ${['h-10']} | ${['pr-10']} | ${['w-10']}
+ ${'medium'} | ${['h-12']} | ${['pr-12']} | ${['w-12']}
+ ${'large'} | ${['h-16']} | ${['pr-16']} | ${['w-16']}
+ `('on $size size', ({
+ size,
+ inputClassNames,
+ hintClassNames,
+ indicatorClassNames,
+ }: {
+ size: TextControl.Size,
+ inputClassNames: string[],
+ hintClassNames: string[],
+ indicatorClassNames: string[],
+ }) => {
+ it('renders input styles', () => {
+ render(
+ ,
+ );
+
+ const combobox = screen.getByRole('combobox');
+ expect(combobox).toHaveClass(...inputClassNames);
+ });
+
+ it('renders hint styles', () => {
+ render(
+ ,
+ );
+
+ const hint = screen.getByTestId('hint');
+ expect(hint).toHaveClass(...hintClassNames);
+ });
+
+ it('renders indicator styles', () => {
+ render(
+ ,
+ );
+
+ const indicator = screen.getByTestId('indicator');
+ expect(indicator).toHaveClass(...indicatorClassNames);
+ });
+ });
+
+ it('renders a block input', () => {
+ render(
+ ,
+ );
+
+ const base = screen.getByTestId('base');
+ expect(base).toHaveClass('block');
+ });
+
+ describe.each`
+ variant | inputClassNames | hintClassNames
+ ${'default'} | ${['pl-4']} | ${['bottom-0', 'pl-4', 'pb-1']}
+ ${'alternate'} | ${['pl-1.5', 'pt-4']} | ${['top-0.5']}
+ `('on $variant variant', ({
+ variant,
+ inputClassNames,
+ hintClassNames,
+ }: {
+ variant: TextControl.Variant,
+ inputClassNames: string[],
+ hintClassNames: string[],
+ }) => {
+ it('renders input styles', () => {
+ render(
+ ,
+ );
+
+ const combobox = screen.getByRole('combobox');
+ expect(combobox).toHaveClass(...inputClassNames);
+ });
+
+ it('renders hint styles', () => {
+ render(
+ ,
+ );
+
+ const hint = screen.getByTestId('hint');
+ expect(hint).toHaveClass(...hintClassNames);
+ });
+ });
+
+ it('handles change events', async () => {
+ const onChange = vi.fn().mockImplementationOnce((e) => { e.preventDefault(); })
+ render(
+
+
+
+ ,
+ );
+ const combobox: HTMLSelectElement = screen.getByRole('combobox');
+ const [, secondOption] = screen.getAllByRole('option');
+ await userEvent.selectOptions(combobox, secondOption);
+ expect(onChange).toBeCalled();
+ });
+});
diff --git a/categories/choice/react/src/components/DropdownSelect/index.tsx b/categories/choice/react/src/components/DropdownSelect/index.tsx
index 7c83fc9..9c10e41 100644
--- a/categories/choice/react/src/components/DropdownSelect/index.tsx
+++ b/categories/choice/react/src/components/DropdownSelect/index.tsx
@@ -10,7 +10,7 @@ export type DropdownSelectDerivedElement = HTMLSelectElement;
/**
* Props of the {@link DropdownSelect} component.
*/
-export interface DropdownSelectProps extends Omit, 'size' | 'type' | 'style' | 'label' | 'list' | 'multiple'> {
+export interface DropdownSelectProps extends Omit, 'size' | 'type' | 'label' | 'list' | 'multiple'> {
/**
* Short textual description indicating the nature of the component's value.
*/
@@ -61,6 +61,7 @@ export const DropdownSelect = React.forwardRef