@madie/madie-design-system 1.2.101 → 1.2.103
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/.babelrc +0 -1
- package/.storybook/main.mjs +38 -0
- package/README.md +18 -0
- package/components/Breadcrumb/Breadcrumb.stories.js +9 -8
- package/components/Button/Button.stories.js +0 -2
- package/components/CalloutBox/CalloutBox.stories.js +0 -2
- package/components/Card/Card.stories.js +0 -2
- package/components/DateField/DateField.stories.jsx +0 -2
- package/components/DateTimeField/DateTimeField.stories.jsx +0 -2
- package/components/Dropdown/Dropdown.stories.js +0 -2
- package/components/Footer/Footer.stories.js +11 -7
- package/components/HowItWorks/HowItWorks.stories.js +0 -2
- package/components/Infotip/Infotip.stories.js +3 -4
- package/components/Instant/Instant.stories.js +0 -2
- package/components/Link/Link.stories.js +0 -2
- package/components/MadieAlert/MadieAlert.stories.js +0 -2
- package/components/MadieConfirmDialog/MadieConfirmDialog.stories.js +0 -2
- package/components/MadieDeleteDialog/MadieDeleteDialog.stories.js +0 -2
- package/components/MadieDialog/MadieDialog.stories.js +0 -2
- package/components/MadieDiscardDialog/MadieDiscardDialog.stories.js +0 -2
- package/components/MadieSpinner/MadieSpinner.stories.js +0 -2
- package/components/MadieTable/MadieTable.stories.js +93 -0
- package/components/MadieTable/index.jsx +34 -8
- package/components/Modal/Modal.stories.js +19 -25
- package/components/NotificationBanner/NotificationBanner.stories.js +5 -4
- package/components/NumberInput/NumberInput.stories.js +0 -2
- package/components/Pagination/index.jsx +3 -8
- package/components/Popover/Popover.stories.js +0 -2
- package/components/ReadOnlyTextField/ReadOnlyTextField.stories.js +0 -2
- package/components/RichTextEditor/RichTextEditor.stories.js +0 -2
- package/components/SearchAndFilter/index.jsx +1 -1
- package/components/Select/Select.stories.js +0 -2
- package/components/Tabs/Tabs.stories.js +0 -2
- package/components/TextArea/TextArea.stories.js +0 -2
- package/components/TextField/TextField.stories.js +0 -2
- package/components/TextInput/TextInput.stories.js +0 -2
- package/components/TimeField/TimeField.jsx +1 -1
- package/components/TimeField/TimeField.stories.js +0 -2
- package/components/Toast/Toast.stories.js +0 -2
- package/components/TruncateText/TruncateText.stories.js +0 -2
- package/components/TruncateText/index.js +12 -1
- package/components/index.js +0 -2
- package/dist/browser.js +1 -1
- package/dist/index.js +1 -1
- package/dist/react/index.js +5 -5
- package/dist/react/index.js.LICENSE.txt +3 -1
- package/dist/react/index.js.map +1 -1
- package/jest.config.js +0 -4
- package/package.json +15 -25
- package/styles/_main.scss +0 -6
- package/test/components/MadieTable.test.js +38 -0
- package/test/components/Pagination.test.js +56 -0
- package/test/components/TruncateText.test.js +38 -0
- package/.storybook/main.js +0 -61
- package/components/Spinner/index.js +0 -9
- package/components/UnwrappedSpinner/index.js +0 -8
- package/storybook-static/favicon.svg +0 -1
- package/storybook-static/index.html +0 -169
- package/storybook-static/index.json +0 -1
- package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/project.json +0 -1
- package/storybook-static/sb-addons/a11y-5/manager-bundle.js +0 -220
- package/storybook-static/sb-addons/actions-1/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/backgrounds-7/manager-bundle.js +0 -12
- package/storybook-static/sb-addons/docs-6/manager-bundle.js +0 -245
- package/storybook-static/sb-addons/knobs-4/register-bundle.js +0 -23
- package/storybook-static/sb-addons/knobs-4/register-bundle.js.LEGAL.txt +0 -11
- package/storybook-static/sb-addons/links-2/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +0 -3
- package/storybook-static/sb-addons/storysource-3/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/viewport-8/manager-bundle.js +0 -3
- package/storybook-static/sb-common-assets/favicon.svg +0 -1
- package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/sb-manager/globals-module-info.js +0 -1052
- package/storybook-static/sb-manager/globals-runtime.js +0 -41775
- package/storybook-static/sb-manager/globals.js +0 -48
- package/storybook-static/sb-manager/runtime.js +0 -12048
- package/storybook-static/sb-preview/globals.js +0 -33
- package/storybook-static/sb-preview/runtime.js +0 -7745
- package/test/__mocks__/styled-components-macro.js +0 -2
- package/test/__mocks__/twin.macro.js +0 -24
package/.babelrc
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
stories: ["../components/**/*.@(mdx|stories.@(js|jsx))"],
|
|
3
|
+
|
|
4
|
+
addons: [
|
|
5
|
+
"@storybook/addon-links",
|
|
6
|
+
"@storybook/addon-a11y",
|
|
7
|
+
"@storybook/addon-docs"
|
|
8
|
+
],
|
|
9
|
+
|
|
10
|
+
framework: {
|
|
11
|
+
name: "@storybook/react-vite",
|
|
12
|
+
options: {}
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
docs: {},
|
|
16
|
+
|
|
17
|
+
typescript: {
|
|
18
|
+
reactDocgen: "react-docgen"
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// stories and components are .js files that contain JSX
|
|
22
|
+
viteFinal: async (config) => {
|
|
23
|
+
config.esbuild = {
|
|
24
|
+
...config.esbuild,
|
|
25
|
+
loader: "jsx",
|
|
26
|
+
include: /(components|lib|\.storybook)\/.*\.jsx?$/,
|
|
27
|
+
exclude: [],
|
|
28
|
+
};
|
|
29
|
+
config.optimizeDeps = {
|
|
30
|
+
...config.optimizeDeps,
|
|
31
|
+
esbuildOptions: {
|
|
32
|
+
...(config.optimizeDeps && config.optimizeDeps.esbuildOptions),
|
|
33
|
+
loader: { ".js": "jsx" },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
return config;
|
|
37
|
+
},
|
|
38
|
+
};
|
package/README.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
# Madie/madie-design-system React
|
|
2
2
|
|
|
3
3
|
This directory contains react implementations of the components for Madie.
|
|
4
|
+
|
|
5
|
+
## Testing
|
|
6
|
+
|
|
7
|
+
Use Node 20 to match CI. The test suite uses Jest 30, `babel-jest` 30, and
|
|
8
|
+
`jest-environment-jsdom` 30 (JSDOM 26).
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm ci
|
|
12
|
+
npm test
|
|
13
|
+
npm run coverage
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
To run selected suites, use `npm test -- --runTestsByPath test/components/Button.test.js`
|
|
17
|
+
or `npm test -- --testPathPatterns=Button`.
|
|
18
|
+
|
|
19
|
+
When updating tests, follow the [Jest 30 migration guide](https://jestjs.io/docs/upgrading-to-jest30).
|
|
20
|
+
Use canonical matcher names such as `toHaveBeenCalled` rather than the removed
|
|
21
|
+
`toBeCalled` aliases.
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import Breadcrumb from "./index";
|
|
3
|
-
import { withKnobs, boolean } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "Breadcrumb",
|
|
7
6
|
component: Breadcrumb,
|
|
8
|
-
|
|
7
|
+
args: {
|
|
8
|
+
newBreadcrumb: true,
|
|
9
|
+
},
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
export const ExampleLightBreadcrumb = () => (
|
|
12
|
+
export const ExampleLightBreadcrumb = (args) => (
|
|
12
13
|
<div className="qppds qpp-u-padding--16 qpp-u-fill--blue-80">
|
|
13
14
|
<Breadcrumb
|
|
14
|
-
newBreadcrumb={
|
|
15
|
+
newBreadcrumb={args.newBreadcrumb}
|
|
15
16
|
crumbs={[
|
|
16
17
|
{
|
|
17
18
|
url: "/",
|
|
@@ -32,10 +33,10 @@ export const ExampleLightBreadcrumb = () => (
|
|
|
32
33
|
|
|
33
34
|
ExampleLightBreadcrumb.storyName = "Light";
|
|
34
35
|
|
|
35
|
-
export const ExampleScreenreaderOnlyBreadcrumb = () => (
|
|
36
|
+
export const ExampleScreenreaderOnlyBreadcrumb = (args) => (
|
|
36
37
|
<div className="qppds qpp-u-padding--16 qpp-u-fill--blue-80">
|
|
37
38
|
<Breadcrumb
|
|
38
|
-
newBreadcrumb={
|
|
39
|
+
newBreadcrumb={args.newBreadcrumb}
|
|
39
40
|
crumbs={[
|
|
40
41
|
{
|
|
41
42
|
url: "/",
|
|
@@ -50,10 +51,10 @@ export const ExampleScreenreaderOnlyBreadcrumb = () => (
|
|
|
50
51
|
);
|
|
51
52
|
ExampleScreenreaderOnlyBreadcrumb.storyName = "SR Only Breadcrumb";
|
|
52
53
|
|
|
53
|
-
export const ExampleDarkBreadcrumb = () => (
|
|
54
|
+
export const ExampleDarkBreadcrumb = (args) => (
|
|
54
55
|
<div className="qppds qpp-u-padding--16">
|
|
55
56
|
<Breadcrumb
|
|
56
|
-
newBreadcrumb={
|
|
57
|
+
newBreadcrumb={args.newBreadcrumb}
|
|
57
58
|
dark
|
|
58
59
|
crumbs={[
|
|
59
60
|
{
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import FeatherIcon from "feather-icons-react";
|
|
5
4
|
|
|
6
5
|
import Button, { TextButton } from "./index";
|
|
@@ -8,7 +7,6 @@ import Button, { TextButton } from "./index";
|
|
|
8
7
|
export default {
|
|
9
8
|
title: "Button",
|
|
10
9
|
component: Button,
|
|
11
|
-
decorators: [withKnobs],
|
|
12
10
|
};
|
|
13
11
|
|
|
14
12
|
const Container = ({ className = "", children }) => (
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
3
2
|
|
|
4
3
|
import CalloutBox from "./index";
|
|
5
4
|
|
|
6
5
|
export default {
|
|
7
6
|
title: "CalloutBox",
|
|
8
7
|
component: CalloutBox,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
export const Default = () => {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import DateField from "./DateField";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "DateField",
|
|
7
6
|
component: DateField,
|
|
8
|
-
decorators: [withKnobs],
|
|
9
7
|
};
|
|
10
8
|
export const DateFieldComponent = (args) => {
|
|
11
9
|
const [value, setValue] = useState("");
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import DateTimeField from "./DateTimeField";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "DateTimeField",
|
|
7
6
|
component: DateTimeField,
|
|
8
|
-
decorators: [withKnobs],
|
|
9
7
|
};
|
|
10
8
|
|
|
11
9
|
export const TimeDateFieldComponent = (args) => {
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import Footer from "./FooterUI";
|
|
3
|
-
import { withKnobs, boolean, text } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "Footer",
|
|
7
6
|
component: Footer,
|
|
8
|
-
|
|
7
|
+
args: {
|
|
8
|
+
isFullWidth: false,
|
|
9
|
+
buildVersion: "BUILD VERSION",
|
|
10
|
+
isNewFooter: false,
|
|
11
|
+
showHcdResearch: false,
|
|
12
|
+
},
|
|
9
13
|
};
|
|
10
14
|
|
|
11
|
-
export const ExampleFooter = () => (
|
|
15
|
+
export const ExampleFooter = (args) => (
|
|
12
16
|
<Footer
|
|
13
|
-
isFullWidth={
|
|
14
|
-
buildVersion={
|
|
15
|
-
isNewFooter={
|
|
16
|
-
showHcdResearch={
|
|
17
|
+
isFullWidth={args.isFullWidth}
|
|
18
|
+
buildVersion={args.buildVersion}
|
|
19
|
+
isNewFooter={args.isNewFooter}
|
|
20
|
+
showHcdResearch={args.showHcdResearch}
|
|
17
21
|
/>
|
|
18
22
|
);
|
|
19
23
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import HowItWorks from "./index";
|
|
5
4
|
|
|
6
5
|
export default {
|
|
7
6
|
title: "HowItWorks",
|
|
8
7
|
component: HowItWorks,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
const Wrapper = ({ children }) => (
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import Infotip from "./index";
|
|
3
|
-
import { withKnobs, boolean } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "Infotip",
|
|
7
6
|
component: Infotip,
|
|
7
|
+
args: { lightIcon: false },
|
|
8
8
|
decorators: [
|
|
9
|
-
withKnobs,
|
|
10
9
|
(storyFn) => (
|
|
11
10
|
<div style={{ marginTop: "120px", marginLeft: "100px" }}>
|
|
12
11
|
{storyFn()}
|
|
@@ -15,8 +14,8 @@ export default {
|
|
|
15
14
|
],
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
export const ExampleInfoTip = () => (
|
|
19
|
-
<Infotip label="Tooltip Content!" lightIcon={
|
|
17
|
+
export const ExampleInfoTip = (args) => (
|
|
18
|
+
<Infotip label="Tooltip Content!" lightIcon={args.lightIcon} />
|
|
20
19
|
);
|
|
21
20
|
|
|
22
21
|
ExampleInfoTip.storyName = "qpp themed Infotip";
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import Instant from "./index";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "Instant",
|
|
7
6
|
component: Instant,
|
|
8
|
-
decorators: [withKnobs],
|
|
9
7
|
};
|
|
10
8
|
|
|
11
9
|
export const InstantComponent = (args) => {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import DSLink from "./index";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
|
|
5
4
|
|
|
6
5
|
export default {
|
|
7
6
|
title: "Link",
|
|
8
7
|
component: DSLink,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
export const LinkLabel = () => <DSLink href="#">Link Label</DSLink>;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import MadieAlert from "./index";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
title: "Madie Alert",
|
|
7
6
|
component: MadieAlert,
|
|
8
7
|
decorators: [
|
|
9
|
-
withKnobs,
|
|
10
8
|
(storyFn) => (
|
|
11
9
|
<div style={{ padding: "120px", backgroundColor: "gray" }}>
|
|
12
10
|
{storyFn()}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import MadieConfirmDialog from "./index";
|
|
5
4
|
import Button from "../Button";
|
|
6
5
|
export default {
|
|
7
6
|
title: "MadieConfirmDialog",
|
|
8
7
|
component: MadieConfirmDialog,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
const Wrapper = ({ children }) => (
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import MadieDeleteDialog from "./index";
|
|
5
4
|
import Button from "../Button";
|
|
6
5
|
export default {
|
|
7
6
|
title: "MadieDeleteDialog",
|
|
8
7
|
component: MadieDeleteDialog,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
const Wrapper = ({ children }) => (
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import MadieDialog from "./index";
|
|
5
4
|
import TextArea from "../TextArea/index";
|
|
6
5
|
import Select from "../Select/index";
|
|
@@ -11,7 +10,6 @@ import { DialogContent, Typography } from "@mui/material";
|
|
|
11
10
|
export default {
|
|
12
11
|
title: "MadieDialog",
|
|
13
12
|
component: MadieDialog,
|
|
14
|
-
decorators: [withKnobs],
|
|
15
13
|
};
|
|
16
14
|
|
|
17
15
|
const Wrapper = ({ children }) => (
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import MadieDiscardDialog from "./index";
|
|
5
4
|
import Button from "../Button";
|
|
6
5
|
export default {
|
|
7
6
|
title: "MadieDiscardDialog",
|
|
8
7
|
component: MadieDiscardDialog,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
const Wrapper = ({ children }) => (
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { withKnobs } from "@storybook/addon-knobs";
|
|
4
3
|
import MadieSpinner from "./index";
|
|
5
4
|
|
|
6
5
|
export default {
|
|
7
6
|
title: "MadieSpinner",
|
|
8
7
|
component: MadieSpinner,
|
|
9
|
-
decorators: [withKnobs],
|
|
10
8
|
};
|
|
11
9
|
|
|
12
10
|
const Wrapper = ({ children }) => (
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { useMemo, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
createColumnHelper,
|
|
4
|
+
getCoreRowModel,
|
|
5
|
+
getSortedRowModel,
|
|
6
|
+
useReactTable,
|
|
7
|
+
} from "@tanstack/react-table";
|
|
8
|
+
import MadieTable from "./index";
|
|
9
|
+
import TruncateText from "../TruncateText";
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
title: "Madie Table",
|
|
13
|
+
component: MadieTable,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const longDescription =
|
|
17
|
+
"Addressing Social Needs in the Inpatient Setting Part 4 of 4 Housing Domain. This description is intentionally long so that it is truncated and exposes a keyboard focusable Show more button.";
|
|
18
|
+
|
|
19
|
+
const rows = [
|
|
20
|
+
{ id: "1", name: "Measure A", version: "1.0.000", description: longDescription },
|
|
21
|
+
{ id: "2", name: "Measure B", version: "0.0.001", description: "Short description" },
|
|
22
|
+
{ id: "3", name: "Measure C", version: "2.1.000", description: longDescription },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const columnHelper = createColumnHelper();
|
|
26
|
+
|
|
27
|
+
const useStoryTable = (data) => {
|
|
28
|
+
const [sorting, setSorting] = useState([]);
|
|
29
|
+
const columns = useMemo(
|
|
30
|
+
() => [
|
|
31
|
+
columnHelper.accessor("name", { header: "Name" }),
|
|
32
|
+
columnHelper.accessor("version", { header: "Version" }),
|
|
33
|
+
columnHelper.accessor("description", {
|
|
34
|
+
header: "Description",
|
|
35
|
+
enableSorting: false,
|
|
36
|
+
cell: (info) => (
|
|
37
|
+
<TruncateText
|
|
38
|
+
text={info.getValue()}
|
|
39
|
+
maxLength={60}
|
|
40
|
+
dataTestId={`description-${info.row.original.id}`}
|
|
41
|
+
/>
|
|
42
|
+
),
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
[]
|
|
46
|
+
);
|
|
47
|
+
const table = useReactTable({
|
|
48
|
+
data,
|
|
49
|
+
columns,
|
|
50
|
+
state: { sorting },
|
|
51
|
+
onSortingChange: setSorting,
|
|
52
|
+
getCoreRowModel: getCoreRowModel(),
|
|
53
|
+
getSortedRowModel: getSortedRowModel(),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// asc -> desc -> cleared, matching how the consuming apps drive MadieTable
|
|
57
|
+
const handleSort = (columnId) => {
|
|
58
|
+
const current = sorting[0];
|
|
59
|
+
if (!current || current.id !== columnId) {
|
|
60
|
+
setSorting([{ id: columnId, desc: false }]);
|
|
61
|
+
} else if (!current.desc) {
|
|
62
|
+
setSorting([{ id: columnId, desc: true }]);
|
|
63
|
+
} else {
|
|
64
|
+
setSorting([]);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
table,
|
|
70
|
+
handleSort,
|
|
71
|
+
currentSort: sorting[0]?.id,
|
|
72
|
+
currentDirection: sorting[0] ? (sorting[0].desc ? "DESC" : "ASC") : undefined,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const WithTruncatedText = () => {
|
|
77
|
+
const tableProps = useStoryTable(rows);
|
|
78
|
+
return (
|
|
79
|
+
<div className="measure-table" style={{ padding: 24 }}>
|
|
80
|
+
<MadieTable {...tableProps} ariaLabel="Measures" />
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
WithTruncatedText.storyName = "With TruncateText cells";
|
|
85
|
+
|
|
86
|
+
export const Empty = () => {
|
|
87
|
+
const tableProps = useStoryTable([]);
|
|
88
|
+
return (
|
|
89
|
+
<div className="measure-table" style={{ padding: 24 }}>
|
|
90
|
+
<MadieTable {...tableProps} ariaLabel="Measures" />
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
@@ -4,8 +4,20 @@ import { flexRender } from "@tanstack/react-table";
|
|
|
4
4
|
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
|
|
5
5
|
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
|
6
6
|
import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
|
|
7
|
-
import
|
|
8
|
-
|
|
7
|
+
import styled from "@emotion/styled";
|
|
8
|
+
|
|
9
|
+
const StyledTable = styled.table`
|
|
10
|
+
min-width: 100%;
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const TH = styled.th`
|
|
14
|
+
padding: 0.75rem;
|
|
15
|
+
text-align: left;
|
|
16
|
+
font-size: 0.875rem;
|
|
17
|
+
line-height: 1.25rem;
|
|
18
|
+
font-weight: 700;
|
|
19
|
+
text-transform: capitalize;
|
|
20
|
+
`;
|
|
9
21
|
|
|
10
22
|
const MadieTable = ({
|
|
11
23
|
table,
|
|
@@ -15,16 +27,15 @@ const MadieTable = ({
|
|
|
15
27
|
renderExpandedRow,
|
|
16
28
|
emptyMessage = "No results were found",
|
|
17
29
|
id="measureListTable",
|
|
18
|
-
dataTestId = "measure-list-tbl"
|
|
30
|
+
dataTestId = "measure-list-tbl",
|
|
31
|
+
ariaLabel,
|
|
19
32
|
}) => {
|
|
20
|
-
const TH = tw.th`p-3 text-left text-sm font-bold capitalize`;
|
|
21
33
|
const [hoveredHeader, setHoveredHeader] = useState(null);
|
|
22
34
|
|
|
23
35
|
return (
|
|
24
|
-
<
|
|
25
|
-
/* eslint-disable-next-line react/no-unknown-property */
|
|
26
|
-
tw="min-w-full"
|
|
36
|
+
<StyledTable
|
|
27
37
|
id={id}
|
|
38
|
+
aria-label={ariaLabel}
|
|
28
39
|
data-testid={dataTestId}
|
|
29
40
|
className="tcl-table"
|
|
30
41
|
style={{
|
|
@@ -39,11 +50,23 @@ const MadieTable = ({
|
|
|
39
50
|
<tr key={headerGroup.id}>
|
|
40
51
|
{headerGroup.headers.map((header) => {
|
|
41
52
|
const isHovered = hoveredHeader?.includes(header.id);
|
|
53
|
+
const isSorted =
|
|
54
|
+
currentSort === header.column.id.replace("_", ".");
|
|
55
|
+
const ariaSort = header.column.getCanSort()
|
|
56
|
+
? isSorted
|
|
57
|
+
? currentDirection === "ASC"
|
|
58
|
+
? "ascending"
|
|
59
|
+
: currentDirection === "DESC"
|
|
60
|
+
? "descending"
|
|
61
|
+
: "none"
|
|
62
|
+
: "none"
|
|
63
|
+
: undefined;
|
|
42
64
|
|
|
43
65
|
return (
|
|
44
66
|
<TH
|
|
45
67
|
key={header.id}
|
|
46
68
|
scope="col"
|
|
69
|
+
aria-sort={ariaSort}
|
|
47
70
|
onMouseEnter={() => setHoveredHeader(header.id)}
|
|
48
71
|
onMouseLeave={() => setHoveredHeader(null)}
|
|
49
72
|
className="header-cell"
|
|
@@ -59,6 +82,8 @@ const MadieTable = ({
|
|
|
59
82
|
onClick={() =>
|
|
60
83
|
handleSort(header.id.replace("_", "."))
|
|
61
84
|
}
|
|
85
|
+
onFocus={() => setHoveredHeader(header.id)}
|
|
86
|
+
onBlur={() => setHoveredHeader(null)}
|
|
62
87
|
data-testid={`header-${header.id.replace("_", ".")}`}
|
|
63
88
|
title={
|
|
64
89
|
header.column.getCanSort()
|
|
@@ -139,7 +164,7 @@ const MadieTable = ({
|
|
|
139
164
|
</React.Fragment>
|
|
140
165
|
))}
|
|
141
166
|
</tbody>
|
|
142
|
-
</
|
|
167
|
+
</StyledTable>
|
|
143
168
|
);
|
|
144
169
|
};
|
|
145
170
|
|
|
@@ -157,6 +182,7 @@ MadieTable.propTypes = {
|
|
|
157
182
|
emptyMessage: PropTypes.node,
|
|
158
183
|
|
|
159
184
|
id: PropTypes.string,
|
|
185
|
+
ariaLabel: PropTypes.string,
|
|
160
186
|
dataTestId: PropTypes.string,
|
|
161
187
|
};
|
|
162
188
|
|