@arbor-education/design-system.components 0.25.5 → 0.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/components/grid/Grid.d.ts +14 -0
- package/dist/components/grid/Grid.d.ts.map +1 -0
- package/dist/components/grid/Grid.js +11 -0
- package/dist/components/grid/Grid.js.map +1 -0
- package/dist/components/grid/Grid.stories.d.ts +52 -0
- package/dist/components/grid/Grid.stories.d.ts.map +1 -0
- package/dist/components/grid/Grid.stories.js +675 -0
- package/dist/components/grid/Grid.stories.js.map +1 -0
- package/dist/components/grid/Grid.test.d.ts +2 -0
- package/dist/components/grid/Grid.test.d.ts.map +1 -0
- package/dist/components/grid/Grid.test.js +59 -0
- package/dist/components/grid/Grid.test.js.map +1 -0
- package/dist/components/grid/GridColumn.d.ts +11 -0
- package/dist/components/grid/GridColumn.d.ts.map +1 -0
- package/dist/components/grid/GridColumn.js +7 -0
- package/dist/components/grid/GridColumn.js.map +1 -0
- package/dist/components/grid/GridRow.d.ts +10 -0
- package/dist/components/grid/GridRow.d.ts.map +1 -0
- package/dist/components/grid/GridRow.js +7 -0
- package/dist/components/grid/GridRow.js.map +1 -0
- package/dist/index.css +186 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/components/grid/Grid.stories.tsx +1130 -0
- package/src/components/grid/Grid.test.tsx +67 -0
- package/src/components/grid/Grid.tsx +34 -0
- package/src/components/grid/GridColumn.tsx +31 -0
- package/src/components/grid/GridRow.tsx +29 -0
- package/src/docs/Contributing.mdx +16 -0
- package/src/index.scss +1 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { expect, test, describe } from 'vitest';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom/vitest';
|
|
4
|
+
import { Grid } from './Grid.js';
|
|
5
|
+
|
|
6
|
+
describe('Grid', () => {
|
|
7
|
+
test('renders govuk-main-wrapper class', () => {
|
|
8
|
+
const { container } = render(<Grid />);
|
|
9
|
+
expect(container.firstChild).toHaveClass('govuk-main-wrapper');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('renders children', () => {
|
|
13
|
+
render(<Grid><span>School report</span></Grid>);
|
|
14
|
+
expect(screen.getByText('School report')).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('merges custom className with govuk-main-wrapper', () => {
|
|
18
|
+
const { container } = render(<Grid className="my-layout" />);
|
|
19
|
+
expect(container.firstChild).toHaveClass('govuk-main-wrapper', 'my-layout');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('Grid.Row', () => {
|
|
24
|
+
test('renders govuk-grid-row class', () => {
|
|
25
|
+
const { container } = render(<Grid.Row />);
|
|
26
|
+
expect(container.firstChild).toHaveClass('govuk-grid-row');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('renders children', () => {
|
|
30
|
+
render(<Grid.Row><span>Attendance data</span></Grid.Row>);
|
|
31
|
+
expect(screen.getByText('Attendance data')).toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('merges custom className with govuk-grid-row', () => {
|
|
35
|
+
const { container } = render(<Grid.Row className="my-row" />);
|
|
36
|
+
expect(container.firstChild).toHaveClass('govuk-grid-row', 'my-row');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('Grid.Column', () => {
|
|
41
|
+
test('defaults to govuk-grid-column-full when columnWidth is omitted', () => {
|
|
42
|
+
const { container } = render(<Grid.Column />);
|
|
43
|
+
expect(container.firstChild).toHaveClass('govuk-grid-column-full');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('renders children', () => {
|
|
47
|
+
render(<Grid.Column columnWidth="full"><span>Student profile</span></Grid.Column>);
|
|
48
|
+
expect(screen.getByText('Student profile')).toBeInTheDocument();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('merges custom className', () => {
|
|
52
|
+
const { container } = render(<Grid.Column columnWidth="full" className="my-col" />);
|
|
53
|
+
expect(container.firstChild).toHaveClass('govuk-grid-column-full', 'my-col');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test.each([
|
|
57
|
+
['full', 'govuk-grid-column-full'],
|
|
58
|
+
['one-half', 'govuk-grid-column-one-half'],
|
|
59
|
+
['one-third', 'govuk-grid-column-one-third'],
|
|
60
|
+
['two-thirds', 'govuk-grid-column-two-thirds'],
|
|
61
|
+
['one-quarter', 'govuk-grid-column-one-quarter'],
|
|
62
|
+
['three-quarters', 'govuk-grid-column-three-quarters'],
|
|
63
|
+
] as const)('applies %s class for columnWidth="%s"', (width, expectedClass) => {
|
|
64
|
+
const { container } = render(<Grid.Column columnWidth={width} />);
|
|
65
|
+
expect(container.firstChild).toHaveClass(expectedClass);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { GridRow } from './GridRow.js';
|
|
4
|
+
import { GridColumn } from './GridColumn.js';
|
|
5
|
+
|
|
6
|
+
export type GridProps = {
|
|
7
|
+
className?: string;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const Grid = (props: GridProps) => {
|
|
12
|
+
const {
|
|
13
|
+
className,
|
|
14
|
+
children,
|
|
15
|
+
} = props;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className={classNames(
|
|
20
|
+
'govuk-main-wrapper',
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
>
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Grid.Row = GridRow;
|
|
30
|
+
Grid.Column = GridColumn;
|
|
31
|
+
|
|
32
|
+
export namespace Grid {
|
|
33
|
+
export type Props = GridProps;
|
|
34
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
export type GridColumnProps = {
|
|
5
|
+
className?: string;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
columnWidth?: 'one-quarter' | 'three-quarters' | 'one-third' | 'two-thirds' | 'one-half' | 'full';
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const GridColumn = (props: GridColumnProps) => {
|
|
11
|
+
const {
|
|
12
|
+
className,
|
|
13
|
+
children,
|
|
14
|
+
columnWidth = 'full',
|
|
15
|
+
} = props;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className={classNames(
|
|
20
|
+
`govuk-grid-column-${columnWidth}`,
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
>
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export namespace GridColumn {
|
|
30
|
+
export type Props = GridColumnProps;
|
|
31
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
export type GridRowProps = {
|
|
5
|
+
className?: string;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const GridRow = (props: GridRowProps) => {
|
|
10
|
+
const {
|
|
11
|
+
className,
|
|
12
|
+
children,
|
|
13
|
+
} = props;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div
|
|
17
|
+
className={classNames(
|
|
18
|
+
'govuk-grid-row',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export namespace GridRow {
|
|
28
|
+
export type Props = GridRowProps;
|
|
29
|
+
}
|
|
@@ -52,6 +52,8 @@ It also automatically adds the component's exports to `src/index.ts` and `src/in
|
|
|
52
52
|
|
|
53
53
|
## Key conventions
|
|
54
54
|
|
|
55
|
+
Most of these are enforced automatically by ESLint — run `yarn eslint --fix` and let it guide you. A few the linter can't catch are worth knowing.
|
|
56
|
+
|
|
55
57
|
### File and directory naming
|
|
56
58
|
|
|
57
59
|
<table>
|
|
@@ -97,6 +99,20 @@ import { Button } from '../../components/button/Button'; // ✗
|
|
|
97
99
|
</tbody>
|
|
98
100
|
</table>
|
|
99
101
|
|
|
102
|
+
### Prefer team hooks
|
|
103
|
+
|
|
104
|
+
Before writing your own hook, check `Utils/hooks` — reuse one that already exists, and reach for one that encapsulates a common pattern rather than hand-rolling it. For example, use `useComponentDidMount` for run-once-on-mount effects rather than `useEffect(fn, [])`. Always give `useEffect` a dependency array, even an empty one.
|
|
105
|
+
|
|
106
|
+
### One component per file
|
|
107
|
+
|
|
108
|
+
Keep one component per file. This applies to compound components too: define each part in its own file and assemble the public API in the root component's file by importing the parts. `Table` is a good example — it pulls in `TableHeader`, `TableFooter`, and its cell renderers from their own files. See the **Compound components** design principle below for the API pattern itself.
|
|
109
|
+
|
|
110
|
+
### Keep comments rare and meaningful
|
|
111
|
+
|
|
112
|
+
Good code is self-documenting, so comments should be the exception rather than the rule. Before writing one, make the code explain itself instead: choose descriptive names, and lift complex expressions or conditions into well-named constants. A clear name is worth more than a sentence describing it.
|
|
113
|
+
|
|
114
|
+
Reserve comments for the _why_ behind something unusual — a constraint, a workaround, a non-obvious decision — never the _what_ the code already says plainly. If you feel the need to explain a piece of code, that's often a sign the code itself should be clearer. This matters especially for agent-assisted changes, which tend to over-narrate — strip the running commentary before opening a PR.
|
|
115
|
+
|
|
100
116
|
---
|
|
101
117
|
|
|
102
118
|
## Design principles
|
package/src/index.scss
CHANGED
package/src/index.ts
CHANGED
|
@@ -89,3 +89,4 @@ export { SlideoverUtils } from 'Utils/SlideoverUtils';
|
|
|
89
89
|
export { ArborLogo, type ArborLogoProps } from 'Components/arborLogo/ArborLogo';
|
|
90
90
|
export { DataViewCard, type DataViewCardProps } from 'Components/dataViewCard/DataViewCard';
|
|
91
91
|
export { FileUpload, type FileUploadProps } from 'Components/fileUpload/FileUpload';
|
|
92
|
+
export { Grid, type GridProps } from 'Components/grid/Grid';
|