Skip to content

Commit

Permalink
Merge pull request #103 from fortanix/feature/component-data-table
Browse files Browse the repository at this point in the history
New components: DataTable + variants
  • Loading branch information
mkrause authored Jan 17, 2025
2 parents 000b384 + 62c04f4 commit 1913efc
Show file tree
Hide file tree
Showing 56 changed files with 6,812 additions and 34 deletions.
9 changes: 7 additions & 2 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
"linter": {
"enabled": true,
"include": ["app/**/*", "src/**/*", "tests/**/*"],
"ignore": ["tests/installation/**/*"],

"ignore": [
"src/components/tables/MultiSearch/MultiSearch.tsx", // Ignore for now (need to focus on type errors first)
"tests/installation/**/*"
],
"rules": {
"recommended": true,
"complexity": {
Expand All @@ -33,7 +37,8 @@
},
"style": {
"useImportType": "off",
"noUnusedTemplateLiteral": "off"
"noUnusedTemplateLiteral": "off",
"noUselessElse": "off"
}
}
}
Expand Down
53 changes: 53 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"check:types": "tsc -b",
"lint:style": "stylelint 'src/**/*.scss'",
"lint:script": "biome lint",
"lint": "npm run lint:style && npm run lint:script",
"lint": "npm run lint:style; npm run lint:script",
"test": "npm run check:types && npm run lint:style",
"test-ui": "vitest --ui",
"coverage": "vitest run --coverage",
Expand Down Expand Up @@ -101,7 +101,9 @@
"sass-embedded": "^1.83.1",
"lightningcss": "^1.29.1",
"@types/react": "^19.0.4",
"@types/react-dom": "^19.0.2"
"@types/react-dom": "^19.0.2",
"@types/react-table": "^7.7.20",
"@ngneat/falso": "^6.4.0"
},
"dependencies": {
"date-fns": "^4.1.0",
Expand All @@ -112,6 +114,7 @@
"react-error-boundary": "^5.0.0",
"@floating-ui/react": "^0.26.28",
"react-toastify": "^10.0.6",
"react-table": "^7.8.0",
"react-datepicker": "^7.6.0",
"effect": "^3.12.1",
"react-hook-form": "^7.54.2",
Expand All @@ -134,6 +137,10 @@
"react-datepicker": {
"react": "$react",
"react-dom": "$react-dom"
},
"react-table": {
"react": "$react",
"react-dom": "$react-dom"
}
}
}
15 changes: 13 additions & 2 deletions package.json.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const packageConfig = {
'check:types': 'tsc -b',
'lint:style': `stylelint 'src/**/*.scss'`,
'lint:script': 'biome lint',
'lint': 'npm run lint:style && npm run lint:script',
'lint': 'npm run lint:style; npm run lint:script',

// Test
// Note: use `vitest run --root=. src/...` to run a single test file
Expand Down Expand Up @@ -155,6 +155,11 @@ const packageConfig = {
// React
'@types/react': '^19.0.4',
'@types/react-dom': '^19.0.2',

// Data table
'@types/react-table': '^7.7.20',
// Fake data
"@ngneat/falso": "^6.4.0",
},

// Dependencies needed when running the generated build
Expand All @@ -172,6 +177,7 @@ const packageConfig = {

'@floating-ui/react': '^0.26.28',
'react-toastify': '^10.0.6',
'react-table': '^7.8.0',
'react-datepicker': '^7.6.0',

'effect': '^3.12.1',
Expand Down Expand Up @@ -200,6 +206,11 @@ const packageConfig = {
'react': '$react',
'react-dom': '$react-dom',
},
// TODO: Revisit after updating react-table to v8
'react-table': {
'react': '$react',
'react-dom': '$react-dom',
},
},
};

Expand Down Expand Up @@ -229,4 +240,4 @@ const makePackageJson = () => {
};

// Write to `package.json`
fs.writeFileSync('./package.json', JSON.stringify(makePackageJson(), null, 2) + '\n');
fs.writeFileSync('./package.json', `${JSON.stringify(makePackageJson(), null, 2)}\n`);
14 changes: 7 additions & 7 deletions src/components/actions/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@

--bk-button-color-accent: #{bk.$theme-button-primary-background-default};
--bk-button-color-contrast: #{bk.$theme-button-primary-text-default};

align-self: flex-start;


cursor: pointer;
user-select: none;

margin: 0;
padding: 0;
&:not(.bk-button--trimmed) {
padding: calc(bk.$spacing-2 - 0.125lh) bk.$spacing-3; /* Note: compensate for line-height difference with Figma */
}
padding: calc(bk.$spacing-2 - 0.125lh) bk.$spacing-3; /* Note: compensate for line-height difference with Figma */

/* Transparent border for consistency with other variants that have a border */
border: bk.$size-1 solid transparent;
border-radius: bk.$radius-s;
background: transparent;

&.bk-button--trimmed {
padding: 0;
border: none;
}

display: inline-flex;
flex-flow: row wrap;
align-items: center;
Expand Down
3 changes: 2 additions & 1 deletion src/components/actions/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ export const Button = (props: ButtonProps) => {
[cl['bk-button--trimmed']]: trimmed,
[cl['bk-button--primary']]: variant === 'primary',
[cl['bk-button--secondary']]: variant === 'secondary',
[cl['bk-button--nonactive']]: isNonactive,
[cl['bk-button--disabled']]: !isInteractive,
[cl['bk-button--nonactive']]: isNonactive,
'nonactive': isNonactive, // Global class name so that consumers can style nonactive states
}, props.className)}
onClick={handleClick}
>
Expand Down
18 changes: 8 additions & 10 deletions src/components/forms/controls/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ export const Input = ({ unstyled = false, type = 'text', ...propsRest }: InputPr
}

return (
<div>
<input
{...propsRest}
type={type}
className={cx({
bk: true,
[cl['bk-input']]: !unstyled,
}, propsRest.className)}
/>
</div>
<input
{...propsRest}
type={type}
className={cx({
bk: true,
[cl['bk-input']]: !unstyled,
}, propsRest.className)}
/>
);
};
6 changes: 4 additions & 2 deletions src/components/forms/fields/CheckboxField/CheckboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const CheckboxFieldTitle = ({ className, children, titleOptional, titleTo
</h1>
);

export type CheckboxFieldProps = ComponentProps<'div'> & {
export type CheckboxFieldProps = ComponentProps<typeof Checkbox> & {
/** Whether this component should be unstyled. */
unstyled?: undefined | boolean,

Expand Down Expand Up @@ -71,7 +71,7 @@ export type CheckboxFieldProps = ComponentProps<'div'> & {
disabled?: undefined | boolean,

/** The onChange event for the checkbox. Passed down to Checkbox component. */
onChange?: (e: React.FormEvent) => void,
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void,
};

/**
Expand All @@ -86,6 +86,7 @@ export const CheckboxField = (props: CheckboxFieldProps) => {
titleOptional,
titleTooltip,
className,
...propsRest
} = props;

return (
Expand All @@ -109,6 +110,7 @@ export const CheckboxField = (props: CheckboxFieldProps) => {
defaultChecked={props.defaultChecked}
disabled={props.disabled}
onChange={props.onChange}
{...propsRest}
/>
<span className={cl['bk-checkbox-field__label__content']}>
{label}
Expand Down
8 changes: 4 additions & 4 deletions src/components/forms/fields/CheckboxGroup/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
|* 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 { classNames as cx } from '../../../../util/componentUtil.ts';
import { classNames as cx, type ComponentProps } from '../../../../util/componentUtil.ts';
import * as React from 'react';

import cl from './CheckboxGroup.module.scss';
Expand All @@ -12,9 +12,9 @@ import { CheckboxField } from '../CheckboxField/CheckboxField.tsx';

export { cl as CheckboxGroupClassNames };

export type CheckboxGroupProps = React.PropsWithChildren<{
direction?: undefined | "vertical" | "horizontal";
}>;
export type CheckboxGroupProps = ComponentProps<'div'> & {
direction?: undefined | 'vertical' | 'horizontal',
};

/**
* Checkbox group component, wrapping multiple CheckboxField components vertically or horizontally.
Expand Down
7 changes: 6 additions & 1 deletion src/components/graphics/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import { icons } from '../../../assets/icons/_icons.ts';
import cl from './Icon.module.scss';


export type IconName = keyof typeof icons;
export { cl as IconClassNames };

export type IconName = keyof typeof icons;
export const iconNames = new Set(Object.keys(icons) as Array<IconName>);
export const isIconName = (iconName: string): iconName is IconName => {
return (iconNames as Set<string>).has(iconName);
};

export type Decoration = (
| { type: 'background-circle' }
);
Expand Down
34 changes: 34 additions & 0 deletions src/components/tables/DataTable/DataTableContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* Copyright (c) Fortanix, Inc.
|* 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 * as React from 'react';
import type * as ReactTable from 'react-table';


export type DataTableStatus = {
ready: boolean, // Whether the data is ready to be used/shown in the UI
loading: boolean, // Whether we're (re)loading the data
error: null | Error, // Whether the last loading attempt resulted in an error
};

export type TableContextState<D extends object> = {
status: DataTableStatus,
setStatus: (status: DataTableStatus) => void,
reload: () => void,
table: ReactTable.TableInstance<D>,
};

const TableContext = React.createContext<null | TableContextState<object>>(null); // Memoized
export const createTableContext = <D extends object>() => TableContext as React.Context<null | TableContextState<D>>;


export const useTable = <D extends object>(): TableContextState<D> => {
const context = React.useContext(TableContext as React.Context<null | TableContextState<D>>);

if (context === null) {
throw new TypeError('TableContext not yet initialized');
}

return context;
};
Loading

0 comments on commit 1913efc

Please sign in to comment.