Add nav buttons
This commit is contained in:
parent
0e9a3c37c5
commit
d9444e9aef
@ -38,6 +38,62 @@ Inline.args = {
|
|||||||
variant: 'inline',
|
variant: 'inline',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const NavAccent: Story = (args) => (
|
||||||
|
<>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button variant="accent" className="px-4">
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button
|
||||||
|
variant="accent"
|
||||||
|
className="pl-8 pr-4"
|
||||||
|
prependIconName="menu-open"
|
||||||
|
>
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button
|
||||||
|
variant="accent"
|
||||||
|
className="pl-4 pr-8"
|
||||||
|
appendIconName="menu-closed"
|
||||||
|
>
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const NavInline: Story = (args) => (
|
||||||
|
<>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button variant="inline" className="uppercase">
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button
|
||||||
|
variant="inline"
|
||||||
|
className="uppercase"
|
||||||
|
prependIconName="menu-open"
|
||||||
|
>
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mb-8">
|
||||||
|
<Button
|
||||||
|
variant="inline"
|
||||||
|
className="uppercase"
|
||||||
|
appendIconName="menu-closed"
|
||||||
|
>
|
||||||
|
Background
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
export const IconPrepend = Template.bind({});
|
export const IconPrepend = Template.bind({});
|
||||||
IconPrepend.args = {
|
IconPrepend.args = {
|
||||||
children: 'Icon prepend',
|
children: 'Icon prepend',
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Icon, IconName } from '../icon';
|
import { Icon, IconName } from '../icon';
|
||||||
|
|
||||||
/* eslint-disable-next-line */
|
|
||||||
export interface ButtonProps {
|
export interface ButtonProps {
|
||||||
tag?: 'a' | 'button';
|
tag?: 'a' | 'button';
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
@ -29,10 +27,9 @@ export function Button({
|
|||||||
[
|
[
|
||||||
'inline-flex',
|
'inline-flex',
|
||||||
'items-center',
|
'items-center',
|
||||||
|
'justify-center',
|
||||||
'box-border',
|
'box-border',
|
||||||
'h-28',
|
'h-28',
|
||||||
'pl-28',
|
|
||||||
'pr-28',
|
|
||||||
'border',
|
'border',
|
||||||
'text-ui',
|
'text-ui',
|
||||||
'no-underline',
|
'no-underline',
|
||||||
@ -43,6 +40,13 @@ export function Button({
|
|||||||
'disabled:bg-disabled/25',
|
'disabled:bg-disabled/25',
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
|
'pl-28': !(
|
||||||
|
className?.match(/(^| )p(l|x)-\d+( |$)/) || variant === 'inline'
|
||||||
|
),
|
||||||
|
'pr-28': !(
|
||||||
|
className?.match(/(^| )p(r|x)-\d+( |$)/) || variant === 'inline'
|
||||||
|
),
|
||||||
|
|
||||||
'bg-white': variant === 'primary',
|
'bg-white': variant === 'primary',
|
||||||
'border-light-gray-50': variant === 'primary' || variant === 'secondary',
|
'border-light-gray-50': variant === 'primary' || variant === 'secondary',
|
||||||
'text-black': variant === 'primary',
|
'text-black': variant === 'primary',
|
||||||
@ -51,7 +55,6 @@ export function Button({
|
|||||||
'active:text-white': variant === 'primary',
|
'active:text-white': variant === 'primary',
|
||||||
'disabled:text-gray-50': variant === 'primary' || variant === 'secondary',
|
'disabled:text-gray-50': variant === 'primary' || variant === 'secondary',
|
||||||
'disabled:border-neutral-593': variant === 'primary',
|
'disabled:border-neutral-593': variant === 'primary',
|
||||||
'disabled:gray-50': variant === 'primary',
|
|
||||||
|
|
||||||
'bg-black': variant === 'secondary',
|
'bg-black': variant === 'secondary',
|
||||||
'text-light-gray-50': variant === 'secondary' || variant === 'inline',
|
'text-light-gray-50': variant === 'secondary' || variant === 'inline',
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||||
|
|
||||||
import { Callout } from '.';
|
import { Callout } from './callout';
|
||||||
|
import { Button } from '../button';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Callout',
|
title: 'Callout',
|
||||||
@ -9,37 +10,61 @@ export default {
|
|||||||
} as ComponentMeta<typeof Callout>;
|
} as ComponentMeta<typeof Callout>;
|
||||||
|
|
||||||
const Template: ComponentStory<typeof Callout> = (args) => (
|
const Template: ComponentStory<typeof Callout> = (args) => (
|
||||||
<Callout {...args}>Content</Callout>
|
<Callout {...args} />
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Default = Template.bind({});
|
export const Default = Template.bind({});
|
||||||
|
Default.args = {
|
||||||
|
children: 'Content',
|
||||||
|
};
|
||||||
|
|
||||||
export const Danger = Template.bind({});
|
export const Danger = Template.bind({});
|
||||||
Danger.args = {
|
Danger.args = {
|
||||||
intent: 'danger',
|
intent: 'danger',
|
||||||
|
children: 'Content',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Warning = Template.bind({});
|
export const Warning = Template.bind({});
|
||||||
Warning.args = {
|
Warning.args = {
|
||||||
intent: 'warning',
|
intent: 'warning',
|
||||||
|
children: 'Content',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Prompt = Template.bind({});
|
export const Prompt = Template.bind({});
|
||||||
Prompt.args = {
|
Prompt.args = {
|
||||||
intent: 'prompt',
|
intent: 'prompt',
|
||||||
|
children: 'Content',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Progress = Template.bind({});
|
export const Progress = Template.bind({});
|
||||||
Progress.args = {
|
Progress.args = {
|
||||||
intent: 'progress',
|
intent: 'progress',
|
||||||
|
children: 'Content',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Success = Template.bind({});
|
export const Success = Template.bind({});
|
||||||
Success.args = {
|
Success.args = {
|
||||||
intent: 'success',
|
intent: 'success',
|
||||||
|
children: 'Content',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Help = Template.bind({});
|
export const Help = Template.bind({});
|
||||||
Help.args = {
|
Help.args = {
|
||||||
intent: 'help',
|
intent: 'help',
|
||||||
|
children: 'Content',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const IconAndContent = Template.bind({});
|
||||||
|
IconAndContent.args = {
|
||||||
|
intent: 'help',
|
||||||
|
title: 'This is what this thing does',
|
||||||
|
iconName: 'endorsed',
|
||||||
|
children: (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div>With a longer explaination</div>
|
||||||
|
<Button className="block mt-8" variant="secondary">
|
||||||
|
Action
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
@ -8,8 +8,10 @@ test('It renders content within callout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('It renders title and icon', () => {
|
test('It renders title and icon', () => {
|
||||||
render(<Callout icon={<div data-testid="icon" />} title="title" />);
|
render(<Callout iconName="endorsed" title="title" />);
|
||||||
expect(screen.getByTestId('icon')).toBeInTheDocument();
|
expect(
|
||||||
|
screen.getByTestId('callout').querySelector('svg')
|
||||||
|
).toBeInTheDocument();
|
||||||
expect(screen.getByText('title')).toBeInTheDocument();
|
expect(screen.getByText('title')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
import React from 'react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { Icon, IconName } from '../icon';
|
||||||
|
|
||||||
export const Callout = ({
|
export interface CalloutProps {
|
||||||
children,
|
|
||||||
title,
|
|
||||||
intent = 'help',
|
|
||||||
icon,
|
|
||||||
headingLevel,
|
|
||||||
}: {
|
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
title?: React.ReactElement | string;
|
title?: React.ReactElement | string;
|
||||||
intent?: 'danger' | 'warning' | 'prompt' | 'progress' | 'success' | 'help';
|
intent?: 'danger' | 'warning' | 'prompt' | 'progress' | 'success' | 'help';
|
||||||
icon?: React.ReactNode;
|
iconName?: IconName;
|
||||||
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
||||||
}) => {
|
}
|
||||||
|
|
||||||
|
export function Callout({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
intent = 'help',
|
||||||
|
iconName,
|
||||||
|
headingLevel,
|
||||||
|
}: CalloutProps) {
|
||||||
const className = classNames(
|
const className = classNames(
|
||||||
'shadow-callout',
|
'shadow-callout',
|
||||||
'border',
|
'border',
|
||||||
'border-black',
|
'border-black',
|
||||||
'dark:border-white',
|
'dark:border-white',
|
||||||
|
'text-body-large',
|
||||||
|
'dark:text-white',
|
||||||
'p-8',
|
'p-8',
|
||||||
{
|
{
|
||||||
'shadow-intent-danger': intent === 'danger',
|
'shadow-intent-danger': intent === 'danger',
|
||||||
@ -27,22 +31,25 @@ export const Callout = ({
|
|||||||
'shadow-intent-black dark:shadow-intent-progress': intent === 'progress',
|
'shadow-intent-black dark:shadow-intent-progress': intent === 'progress',
|
||||||
'shadow-intent-success': intent === 'success',
|
'shadow-intent-success': intent === 'success',
|
||||||
'shadow-intent-help': intent === 'help',
|
'shadow-intent-help': intent === 'help',
|
||||||
flex: icon,
|
flex: !!iconName,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const TitleTag: keyof JSX.IntrinsicElements = headingLevel
|
const TitleTag: keyof JSX.IntrinsicElements = headingLevel
|
||||||
? `h${headingLevel}`
|
? `h${headingLevel}`
|
||||||
: 'div';
|
: 'div';
|
||||||
|
const icon = iconName && (
|
||||||
|
<Icon name={iconName} className="fill-current ml-8 mr-16 mt-8" size={20} />
|
||||||
|
);
|
||||||
const body = (
|
const body = (
|
||||||
<div className="body-large dark:text-white">
|
<>
|
||||||
{title && <TitleTag className="text-h5">{title}</TitleTag>}
|
{title && <TitleTag className="text-h5">{title}</TitleTag>}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div data-testid="callout" className={className}>
|
<div data-testid="callout" className={className}>
|
||||||
{icon && <div className="">{icon}</div>}
|
{icon}
|
||||||
{icon ? <div className="grow">{body}</div> : body}
|
{icon ? <div className="grow">{body}</div> : body}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user