@databiosphere/findable-ui 50.3.0 → 50.4.0

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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "50.3.0"
2
+ ".": "50.4.0"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [50.4.0](https://github.com/DataBiosphere/findable-ui/compare/v50.3.0...v50.4.0) (2026-03-30)
4
+
5
+
6
+ ### Features
7
+
8
+ * refactor exportmethod to card-based layout ([#848](https://github.com/DataBiosphere/findable-ui/issues/848)) ([bfc09d3](https://github.com/DataBiosphere/findable-ui/commit/bfc09d35c4e3d5fa55a7ab6f9e50eb88b23f31f0))
9
+ * update export/download ui ([#848](https://github.com/DataBiosphere/findable-ui/issues/848)) ([#853](https://github.com/DataBiosphere/findable-ui/issues/853)) ([bfc09d3](https://github.com/DataBiosphere/findable-ui/commit/bfc09d35c4e3d5fa55a7ab6f9e50eb88b23f31f0))
10
+
3
11
  ## [50.3.0](https://github.com/DataBiosphere/findable-ui/compare/v50.2.1...v50.3.0) (2026-03-27)
4
12
 
5
13
 
@@ -1,11 +1,10 @@
1
1
  import { JSX, ReactNode } from "react";
2
2
  import { TrackingProps } from "../../../types";
3
3
  export interface ExportMethodProps extends TrackingProps {
4
- buttonLabel: string;
5
4
  description: ReactNode;
6
5
  footnote?: ReactNode;
7
6
  isAccessible?: boolean;
8
7
  route: string;
9
8
  title: string;
10
9
  }
11
- export declare const ExportMethod: ({ buttonLabel, description, footnote, isAccessible, route, title, trackingId, }: ExportMethodProps) => JSX.Element;
10
+ export declare const ExportMethod: ({ description, footnote, isAccessible, route, title, trackingId, }: ExportMethodProps) => JSX.Element;
@@ -1,13 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Tooltip, Typography } from "@mui/material";
2
+ import { ChevronRightRounded } from "@mui/icons-material";
3
+ import { CardActionArea, CardActions, CardContent, Tooltip, Typography, } from "@mui/material";
3
4
  import Link from "next/link";
4
5
  import { useDownloadStatus } from "../../../../hooks/useDownloadStatus";
6
+ import { SVG_ICON_PROPS } from "../../../../styles/common/mui/svgIcon";
5
7
  import { TYPOGRAPHY_PROPS } from "../../../../styles/common/mui/typography";
6
- import { FluidPaper } from "../../../common/Paper/paper.styles";
7
- import { SectionTitle } from "../../../common/Section/components/SectionTitle/sectionTitle";
8
- import { Section, SectionActions, SectionContent, } from "../../../common/Section/section.styles";
9
- import { ExportButton } from "./exportMethod.styles";
10
- export const ExportMethod = ({ buttonLabel, description, footnote, isAccessible = true, route, title, trackingId, }) => {
8
+ import { FluidPaper } from "../../../common/Paper/components/FluidPaper/fluidPaper";
9
+ import { StyledCard } from "./exportMethod.styles";
10
+ export const ExportMethod = ({ description, footnote, isAccessible = true, route, title, trackingId, }) => {
11
11
  const { disabled, message } = useDownloadStatus();
12
- return (_jsx(FluidPaper, { children: _jsxs(Section, { children: [_jsxs(SectionContent, { children: [_jsx(SectionTitle, { title: title }), _jsx(Typography, { variant: TYPOGRAPHY_PROPS.VARIANT.BODY_400_2_LINES, children: description })] }), _jsx(SectionActions, { children: _jsx(Tooltip, { arrow: true, title: message, children: _jsx("span", { children: _jsx(ExportButton, { component: Link, disabled: disabled || !isAccessible, href: route, id: trackingId, children: buttonLabel }) }) }) }), footnote && (_jsx(Typography, { color: TYPOGRAPHY_PROPS.COLOR.INK_LIGHT, component: "div", variant: TYPOGRAPHY_PROPS.VARIANT.BODY_SMALL_400_2_LINES, children: footnote }))] }) }));
12
+ return (_jsx(Tooltip, { arrow: true, title: message, children: _jsx(StyledCard, { component: FluidPaper, elevation: 1, children: _jsxs(CardActionArea, { component: Link, disabled: disabled || !isAccessible, href: route, id: trackingId, children: [_jsxs(CardContent, { children: [_jsx(Typography, { component: "h3", variant: TYPOGRAPHY_PROPS.VARIANT.HEADING_XSMALL, children: title }), _jsx(Typography, { component: "div", variant: TYPOGRAPHY_PROPS.VARIANT.BODY_400_2_LINES, children: description }), footnote && (_jsx(Typography, { color: TYPOGRAPHY_PROPS.COLOR.INK_LIGHT, component: "div", variant: TYPOGRAPHY_PROPS.VARIANT.BODY_SMALL_400_2_LINES, children: footnote }))] }), _jsx(CardActions, { children: _jsx(ChevronRightRounded, { color: SVG_ICON_PROPS.COLOR.INK_LIGHT }) })] }) }) }));
13
13
  };
@@ -1,3 +1,2 @@
1
- export declare const ExportButton: import("@emotion/styled").StyledComponent<Omit<import("../../../common/Button/button").ButtonProps, "ref"> & import("react").RefAttributes<HTMLButtonElement> & {
2
- theme?: import("@emotion/react").Theme;
3
- }, {}, {}>;
1
+ import { Card } from "@mui/material";
2
+ export declare const StyledCard: typeof Card;
@@ -1,5 +1,28 @@
1
1
  import styled from "@emotion/styled";
2
- import { ButtonPrimary } from "../../../common/Button/components/ButtonPrimary/buttonPrimary";
3
- export const ExportButton = styled(ButtonPrimary) `
4
- text-transform: none; // overrides MuiButton theme text-transform "capitalize".
2
+ import { Card } from "@mui/material";
3
+ import { sectionPadding } from "../../../common/Section/section.styles";
4
+ export const StyledCard = styled(Card) `
5
+ .MuiCardActionArea-root {
6
+ display: grid;
7
+ gap: 16px;
8
+ grid-template-columns: 1fr auto;
9
+ ${sectionPadding};
10
+ text-decoration: none;
11
+
12
+ &.Mui-disabled {
13
+ opacity: 0.6;
14
+ }
15
+
16
+ .MuiCardContent-root {
17
+ padding: 0;
18
+
19
+ h3 {
20
+ margin-bottom: 4px;
21
+ }
22
+ }
23
+
24
+ .MuiCardActions-root {
25
+ padding: 0;
26
+ }
27
+ }
5
28
  `;
@@ -0,0 +1,6 @@
1
+ import { Meta, StoryObj } from "@storybook/nextjs-vite";
2
+ import { ExportMethod } from "../exportMethod";
3
+ declare const meta: Meta<typeof ExportMethod>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const ExportMethodStory: Story;
@@ -1,18 +1,15 @@
1
- import { ExportMethod } from "./exportMethod";
1
+ import { ExportMethod } from "../exportMethod";
2
2
  const meta = {
3
3
  argTypes: {
4
- buttonLabel: { control: "text" },
5
4
  description: { control: "text" },
6
5
  route: { control: "text" },
7
6
  title: { control: "text" },
8
7
  },
9
8
  component: ExportMethod,
10
- title: "Components/Section/Export/ExportMethod",
11
9
  };
12
10
  export default meta;
13
11
  export const ExportMethodStory = {
14
12
  args: {
15
- buttonLabel: "Request curl Command",
16
13
  description: "Obtain a curl command for downloading the selected data.",
17
14
  route: "/request-curl-command",
18
15
  title: "Download Study Data and Metadata (Curl Command)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "50.3.0",
3
+ "version": "50.4.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
@@ -1,6 +1,29 @@
1
1
  import styled from "@emotion/styled";
2
- import { ButtonPrimary } from "../../../common/Button/components/ButtonPrimary/buttonPrimary";
2
+ import { Card } from "@mui/material";
3
+ import { sectionPadding } from "../../../common/Section/section.styles";
3
4
 
4
- export const ExportButton = styled(ButtonPrimary)`
5
- text-transform: none; // overrides MuiButton theme text-transform "capitalize".
6
- `;
5
+ export const StyledCard = styled(Card)`
6
+ .MuiCardActionArea-root {
7
+ display: grid;
8
+ gap: 16px;
9
+ grid-template-columns: 1fr auto;
10
+ ${sectionPadding};
11
+ text-decoration: none;
12
+
13
+ &.Mui-disabled {
14
+ opacity: 0.6;
15
+ }
16
+
17
+ .MuiCardContent-root {
18
+ padding: 0;
19
+
20
+ h3 {
21
+ margin-bottom: 4px;
22
+ }
23
+ }
24
+
25
+ .MuiCardActions-root {
26
+ padding: 0;
27
+ }
28
+ }
29
+ ` as typeof Card;
@@ -1,20 +1,21 @@
1
- import { Tooltip, Typography } from "@mui/material";
1
+ import { ChevronRightRounded } from "@mui/icons-material";
2
+ import {
3
+ CardActionArea,
4
+ CardActions,
5
+ CardContent,
6
+ Tooltip,
7
+ Typography,
8
+ } from "@mui/material";
2
9
  import Link from "next/link";
3
10
  import { JSX, ReactNode } from "react";
4
11
  import { useDownloadStatus } from "../../../../hooks/useDownloadStatus";
12
+ import { SVG_ICON_PROPS } from "../../../../styles/common/mui/svgIcon";
5
13
  import { TYPOGRAPHY_PROPS } from "../../../../styles/common/mui/typography";
6
- import { FluidPaper } from "../../../common/Paper/paper.styles";
7
- import { SectionTitle } from "../../../common/Section/components/SectionTitle/sectionTitle";
8
- import {
9
- Section,
10
- SectionActions,
11
- SectionContent,
12
- } from "../../../common/Section/section.styles";
14
+ import { FluidPaper } from "../../../common/Paper/components/FluidPaper/fluidPaper";
13
15
  import { TrackingProps } from "../../../types";
14
- import { ExportButton } from "./exportMethod.styles";
16
+ import { StyledCard } from "./exportMethod.styles";
15
17
 
16
18
  export interface ExportMethodProps extends TrackingProps {
17
- buttonLabel: string;
18
19
  description: ReactNode;
19
20
  footnote?: ReactNode;
20
21
  isAccessible?: boolean;
@@ -23,7 +24,6 @@ export interface ExportMethodProps extends TrackingProps {
23
24
  }
24
25
 
25
26
  export const ExportMethod = ({
26
- buttonLabel,
27
27
  description,
28
28
  footnote,
29
29
  isAccessible = true,
@@ -33,38 +33,42 @@ export const ExportMethod = ({
33
33
  }: ExportMethodProps): JSX.Element => {
34
34
  const { disabled, message } = useDownloadStatus();
35
35
  return (
36
- <FluidPaper>
37
- <Section>
38
- <SectionContent>
39
- <SectionTitle title={title} />
40
- <Typography variant={TYPOGRAPHY_PROPS.VARIANT.BODY_400_2_LINES}>
41
- {description}
42
- </Typography>
43
- </SectionContent>
44
- <SectionActions>
45
- <Tooltip arrow title={message}>
46
- <span>
47
- <ExportButton
48
- component={Link}
49
- disabled={disabled || !isAccessible}
50
- href={route}
51
- id={trackingId}
36
+ <Tooltip arrow title={message}>
37
+ <StyledCard component={FluidPaper} elevation={1}>
38
+ <CardActionArea
39
+ component={Link}
40
+ disabled={disabled || !isAccessible}
41
+ href={route}
42
+ id={trackingId}
43
+ >
44
+ <CardContent>
45
+ <Typography
46
+ component="h3"
47
+ variant={TYPOGRAPHY_PROPS.VARIANT.HEADING_XSMALL}
48
+ >
49
+ {title}
50
+ </Typography>
51
+ <Typography
52
+ component="div"
53
+ variant={TYPOGRAPHY_PROPS.VARIANT.BODY_400_2_LINES}
54
+ >
55
+ {description}
56
+ </Typography>
57
+ {footnote && (
58
+ <Typography
59
+ color={TYPOGRAPHY_PROPS.COLOR.INK_LIGHT}
60
+ component="div"
61
+ variant={TYPOGRAPHY_PROPS.VARIANT.BODY_SMALL_400_2_LINES}
52
62
  >
53
- {buttonLabel}
54
- </ExportButton>
55
- </span>
56
- </Tooltip>
57
- </SectionActions>
58
- {footnote && (
59
- <Typography
60
- color={TYPOGRAPHY_PROPS.COLOR.INK_LIGHT}
61
- component="div"
62
- variant={TYPOGRAPHY_PROPS.VARIANT.BODY_SMALL_400_2_LINES}
63
- >
64
- {footnote}
65
- </Typography>
66
- )}
67
- </Section>
68
- </FluidPaper>
63
+ {footnote}
64
+ </Typography>
65
+ )}
66
+ </CardContent>
67
+ <CardActions>
68
+ <ChevronRightRounded color={SVG_ICON_PROPS.COLOR.INK_LIGHT} />
69
+ </CardActions>
70
+ </CardActionArea>
71
+ </StyledCard>
72
+ </Tooltip>
69
73
  );
70
74
  };
@@ -1,16 +1,14 @@
1
- import type { Meta, StoryObj } from "@storybook/nextjs-vite";
2
- import { ExportMethod } from "./exportMethod";
1
+ import { Meta, StoryObj } from "@storybook/nextjs-vite";
2
+ import { ExportMethod } from "../exportMethod";
3
3
 
4
- const meta = {
4
+ const meta: Meta<typeof ExportMethod> = {
5
5
  argTypes: {
6
- buttonLabel: { control: "text" },
7
6
  description: { control: "text" },
8
7
  route: { control: "text" },
9
8
  title: { control: "text" },
10
9
  },
11
10
  component: ExportMethod,
12
- title: "Components/Section/Export/ExportMethod",
13
- } satisfies Meta<typeof ExportMethod>;
11
+ };
14
12
 
15
13
  export default meta;
16
14
 
@@ -18,7 +16,6 @@ type Story = StoryObj<typeof meta>;
18
16
 
19
17
  export const ExportMethodStory: Story = {
20
18
  args: {
21
- buttonLabel: "Request curl Command",
22
19
  description: "Obtain a curl command for downloading the selected data.",
23
20
  route: "/request-curl-command",
24
21
  title: "Download Study Data and Metadata (Curl Command)",
@@ -1,22 +0,0 @@
1
- import type { StoryObj } from "@storybook/nextjs-vite";
2
- declare const meta: {
3
- argTypes: {
4
- buttonLabel: {
5
- control: "text";
6
- };
7
- description: {
8
- control: "text";
9
- };
10
- route: {
11
- control: "text";
12
- };
13
- title: {
14
- control: "text";
15
- };
16
- };
17
- component: ({ buttonLabel, description, footnote, isAccessible, route, title, trackingId, }: import("./exportMethod").ExportMethodProps) => import("react").JSX.Element;
18
- title: string;
19
- };
20
- export default meta;
21
- type Story = StoryObj<typeof meta>;
22
- export declare const ExportMethodStory: Story;