Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import terser from "@rollup/plugin-terser";
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import analyze from 'rollup-plugin-analyzer';

const limitBytes = 8.5e6;
const limitBytes = 9.0e6;

const onAnalysis = ({ bundleSize }) => {
if (bundleSize < limitBytes) return;
Expand Down
8 changes: 8 additions & 0 deletions src/components/container/Goal/Goal.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,12 @@
border: 2px solid #555;
border-radius: 8px;
transform: translate(-50%, 0);
}

.mdhui-goal .recharts-wrapper {
cursor: inherit !important;
}

.mdhui-goal .recharts-sector {
outline: none;
}
17 changes: 13 additions & 4 deletions src/components/container/Goal/Goal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default meta;
type GoalDefaultStoryArgs = React.ComponentProps<typeof Goal> & {
colorScheme: 'auto' | 'light' | 'dark';
iconType: 'default' | 'custom';
parentCursor: 'default' | 'pointer' | 'crosshair';
};

export const Default: StoryObj<GoalDefaultStoryArgs> = {
Expand All @@ -31,6 +32,7 @@ export const Default: StoryObj<GoalDefaultStoryArgs> = {
maxValue: 7,
maxSegments: 10,
iconType: 'default',
parentCursor: 'default',
notStartedColor: '',
inProgressColor: '',
completedColor: '',
Expand Down Expand Up @@ -80,6 +82,11 @@ export const Default: StoryObj<GoalDefaultStoryArgs> = {
control: 'radio',
options: ['default', 'custom']
},
parentCursor: {
name: 'parent cursor',
control: 'radio',
options: ['default', 'pointer', 'crosshair']
},
notStartedColor: {
name: 'not started color',
control: 'color'
Expand Down Expand Up @@ -110,10 +117,12 @@ export const Default: StoryObj<GoalDefaultStoryArgs> = {
},
render: args => {
return <Layout colorScheme={args.colorScheme}>
<Goal
{...args}
icon={args.iconType === 'custom' ? faHeartbeat : undefined}
/>
<div style={{ cursor: args.parentCursor }}>
<Goal
{...args}
icon={args.iconType === 'custom' ? faHeartbeat : undefined}
/>
</div>
</Layout>;
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/presentational/Action/Action.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
align-items: center;
gap: 16px;
box-sizing: border-box;
cursor: default;
cursor: inherit;
}

.mdhui-action.mdhui-action-clickable,
Expand Down
187 changes: 145 additions & 42 deletions src/components/presentational/Action/Action.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,152 @@
import React from "react";
import Action, { ActionProps } from "./Action";
import Layout from "../Layout";
import React from 'react';
import Action, { ActionProps } from './Action';
import Layout from '../Layout';
import './Action.stories.css';
import { FontAwesomeSvgIcon } from "react-fontawesome-svg-icon";
import { faFile } from "@fortawesome/free-solid-svg-icons";
import { Meta, StoryObj } from "@storybook/react";
import { FontAwesomeSvgIcon } from 'react-fontawesome-svg-icon';
import { faArrowRight, faFile, faHeart } from '@fortawesome/free-solid-svg-icons';
import { Meta, StoryObj } from '@storybook/react';
import { argTypesToHide } from '../../../../.storybook/helpers';

const meta: Meta<typeof Action> = {
title: "Presentational/Action",
component: Action,
parameters: {
layout: 'fullscreen'
}
type ActionStoryArgs = React.ComponentProps<typeof Action> & {
colorScheme: 'auto' | 'light' | 'dark';
withClass: boolean;
withIcon: boolean;
withTitleIcon: boolean;
withIndicator: boolean;
withIndicatorIcon: boolean;
withIndicatorValue: boolean;
withClickHandler: boolean;
parentCursor: 'not set' | 'pointer' | 'crosshair';
};

export default meta;
type Story = StoryObj<typeof Action>;

const render = (args: ActionProps) =>
<Layout colorScheme="auto">
<Action {...args} />
</Layout>;
const meta: Meta<ActionStoryArgs> = {
title: 'Presentational/Action',
component: Action,
parameters: {
layout: 'fullscreen'
},
render: (storyArgs: ActionStoryArgs) => {
const componentArgs: ActionProps = {
...storyArgs,
...(storyArgs.withClass && { className: 'action-story-primary', renderAs: 'div' }),
...(storyArgs.withIcon && { icon: <FontAwesomeSvgIcon icon={faFile} color="#2e6e9e" /> }),
...(storyArgs.withTitleIcon && { titleIcon: <FontAwesomeSvgIcon icon={faHeart} color="#df4747" style={{ marginRight: '4px' }} /> }),
...(storyArgs.withIndicator && { indicator: <FontAwesomeSvgIcon icon={faArrowRight} color="#2e6e9e" /> }),
...(storyArgs.withIndicatorIcon && { indicatorIcon: faArrowRight }),
...(storyArgs.withIndicatorValue && { indicatorValue: '3' }),
...(storyArgs.withClickHandler && { onClick: () => alert('Clicked') })
};

const baseArgs : ActionProps = {
title: "Baseline Survey",
subtitle: "Tap here to start your baseline survey",
onClick: () => alert("Clicked")
return <Layout colorScheme={storyArgs.colorScheme}>
<div style={{ cursor: storyArgs.parentCursor }}>
<Action {...componentArgs} />
{componentArgs.bottomBorder && <div style={{ padding: '16px', fontSize: '0.75em', color: '#888' }}>
Note: Adding this here because the bottom border seen above only renders when the action is not the last child of its parent.
</div>}
</div>
</Layout>;
}
};
export default meta;

export const WithClickEvent: Story = {
args: {...baseArgs},
render: render
}

export const WithClass: Story = {
args: {...baseArgs, className: "action-story-primary", renderAs: "div"},
render: render
}

export const WithIcon: Story = {
args: {...baseArgs, icon: <FontAwesomeSvgIcon icon={faFile} color="#2e6e9e" />},
render: render
}

export const WithTitleIcon: Story = {
args: {...baseArgs, titleIcon: <FontAwesomeSvgIcon icon={faFile} color="#2e6e9e" />},
render: render
}
export const Default: StoryObj<ActionStoryArgs> = {
args: {
colorScheme: 'auto',
title: 'Baseline Survey',
subtitle: 'Tap here to start your baseline survey',
withClass: false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, but the story args here seem a little inconsistent compared to other stories. I'm used to seeing the actual component properties reflected in the story arguments. For example, on BasicPointsForBadges you can control the BasicPointsForBadgesProps like pointsPerBadge and progressBarColor. Here the story args seem to be activating specific scenarios, but I thought that was more normally done with separate stories?

withIcon: false,
withTitleIcon: false,
withIndicator: false,
withIndicatorIcon: false,
withIndicatorValue: false,
indicatorPosition: 'default',
bottomBorder: false,
withClickHandler: false,
titleColor: '',
subtitleColor: '',
parentCursor: 'not set',
renderAs: 'default' as any
},
argTypes: {
colorScheme: {
name: 'color scheme',
control: 'radio',
options: ['auto', 'light', 'dark']
},
title: {
name: 'title',
control: 'text'
},
subtitle: {
name: 'subtitle',
control: 'text'
},
withClass: {
name: 'with class',
control: 'boolean'
},
withIcon: {
name: 'with icon',
control: 'boolean'
},
withTitleIcon: {
name: 'with title icon',
control: 'boolean'
},
withIndicator: {
name: 'with indicator',
control: 'boolean'
},
withIndicatorIcon: {
name: 'with indicator icon',
control: 'boolean'
},
withIndicatorValue: {
name: 'with indicator value',
control: 'boolean'
},
indicatorPosition: {
name: 'indicator position',
control: 'radio',
options: ['default', 'topRight']
},
bottomBorder: {
name: 'with bottom border',
control: 'boolean'
},
withClickHandler: {
name: 'with click handler',
control: 'boolean'
},
titleColor: {
name: 'title color',
control: 'color'
},
subtitleColor: {
name: 'subtitle color',
control: 'color'
},
parentCursor: {
name: 'parent cursor',
control: 'radio',
options: ['not set', 'pointer', 'crosshair'],
mapping: {
['not set']: undefined
}
},
renderAs: {
name: 'render as',
control: 'radio',
options: ['default', 'button', 'div'],
mapping: {
default: undefined
}
},
...argTypesToHide([
'titleIcon', 'icon', 'onClick', 'className',
'indicator', 'indicatorIcon', 'indicatorValue',
'innerRef'
])
}
};
15 changes: 15 additions & 0 deletions src/components/presentational/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Action from "../Action/Action";
import Layout from "../Layout"
import Card, { CardProps } from "./Card"
import "./Card.stories.css";
import { Goal } from '../../container';

export default {
title: "Presentational/Card",
Expand Down Expand Up @@ -43,4 +44,18 @@ export const HighlightVariant = {
children: <Action onClick={() => {}} title="Baseline Survey" subtitle="Tap here to start your baseline survey" />
},
render: render
};

export const ClickableCard = {
args: {
children: <>
<Action title="See more details" bottomBorder />
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Goal variant="compact" label="Goal 1" targetValue={5} maxValue={10} valueProvider={{ type: 'static integer', getValue: async () => 7 }} />
<Goal variant="compact" label="Goal 2" targetValue={5} maxValue={10} valueProvider={{ type: 'static integer', getValue: async () => 3 }} />
</div>
</>,
onClick: () => console.log("Card Clicked!")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"See more details" made me expect to see more details, not a console statement. I think it would be better if the click event actually did something visible (even if it was as simple as changing a color or something) with a prompt to match.

},
render: render
};
3 changes: 2 additions & 1 deletion src/components/presentational/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface CardProps {
innerRef?: React.Ref<HTMLDivElement>;
variant?: "default" | "subtle" | "highlight";
backgroundColor?: ColorDefinition;
onClick?: () => void;
style?: React.CSSProperties;
}

Expand All @@ -36,7 +37,7 @@ export default function (props: CardProps) {
let backgroundColor = resolveColor(layoutContext?.colorScheme, props.backgroundColor);

return (
<div style={{...props.style, backgroundColor:backgroundColor}} ref={props.innerRef} className={classes.join(" ")}>
<div style={{ ...props.style, backgroundColor: backgroundColor, ...(props.onClick && { cursor: "pointer" }) }} ref={props.innerRef} className={classes.join(" ")} onClick={props.onClick}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Chrome and Safari on Mac, I don't see any visible difference between the pointer on a clickable card vs a non-clickable card.

{props.children}
{props.children && variant === "highlight" && <ShinyOverlay />}
</div>
Expand Down
Loading