-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from UrbanInstitute/button-component
Add Button component
- Loading branch information
Showing
6 changed files
with
356 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,26 @@ | ||
/** @type { import('@storybook/sveltekit').StorybookConfig } */ | ||
const config = { | ||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx|svelte)"], | ||
addons: [ | ||
"@storybook/addon-links", | ||
"@storybook/addon-essentials", | ||
"@storybook/addon-interactions", | ||
"@storybook/addon-svelte-csf", | ||
"@storybook/addon-a11y" | ||
], | ||
framework: { | ||
name: "@storybook/sveltekit", | ||
options: {} | ||
}, | ||
core: { disableTelemetry: true }, | ||
docs: { | ||
autodocs: "tag" | ||
}, | ||
staticDirs: ["../static/"] | ||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx|svelte)"], | ||
addons: [ | ||
"@storybook/addon-links", | ||
"@storybook/addon-essentials", | ||
"@storybook/addon-interactions", | ||
"@storybook/addon-svelte-csf", | ||
"@storybook/addon-a11y" | ||
], | ||
framework: { | ||
name: "@storybook/sveltekit", | ||
options: {} | ||
}, | ||
core: { disableTelemetry: true }, | ||
docs: { | ||
autodocs: "tag" | ||
}, | ||
staticDirs: ["../static/"], | ||
build: { | ||
test: { | ||
disableAutoDocs: false | ||
} | ||
} | ||
}; | ||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# @UrbanInstitute/dataviz-components Changelog | ||
|
||
## Next | ||
- Add Button component | ||
|
||
## 0.4.0 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<script context="module"> | ||
import Button from "./Button.svelte"; | ||
import IconDownload from "./IconDownload.svelte"; | ||
export const meta = { | ||
title: "Components/Button", | ||
description: "A basic button component.", | ||
component: Button, | ||
tags: ["autodocs"], | ||
argTypes: { | ||
variant: { | ||
default: "primary", | ||
options: ["primary", "primary-black", "secondary", "secondary-black", "tertiary"], | ||
control: "select" | ||
}, | ||
size: { | ||
default: "standard", | ||
options: ["standard", "small"], | ||
control: "select" | ||
} | ||
}, | ||
parameters: { | ||
docs: { | ||
description: { | ||
component: "Basic HTML Button adhering to Urban styles." | ||
} | ||
} | ||
} | ||
}; | ||
</script> | ||
|
||
<script> | ||
import { Story, Template } from "@storybook/addon-svelte-csf"; | ||
import { within, userEvent, expect, fn } from "@storybook/test"; | ||
</script> | ||
|
||
<Template let:args> | ||
<Button {...args} on:click on:mouseenter on:mouseleave>Button text</Button> | ||
</Template> | ||
|
||
<Story name="primary" args={{}} /> | ||
|
||
<Story | ||
name="primary with event listeners" | ||
args={{ | ||
event_click: fn(), | ||
event_mouseenter: fn(), | ||
event_mouseleave: fn() | ||
}} | ||
play={async ({ canvasElement, args }) => { | ||
const canvas = within(canvasElement); | ||
const button = canvas.getByRole("button"); | ||
await userEvent.click(button); | ||
await expect(args.event_click).toHaveBeenCalled(); | ||
await userEvent.hover(button); | ||
await expect(args.event_mouseenter).toHaveBeenCalled(); | ||
await userEvent.unhover(button); | ||
await expect(args.event_mouseleave).toHaveBeenCalled(); | ||
}} | ||
/> | ||
|
||
<Story name="primary with icon"> | ||
<Button | ||
>Button text <svelte:fragment slot="icon" let:iconColor | ||
><IconDownload size={16} fill={iconColor} /></svelte:fragment | ||
></Button | ||
> | ||
</Story> | ||
|
||
<Story | ||
name="primary small" | ||
args={{ | ||
size: "small" | ||
}} | ||
/> | ||
|
||
<Story | ||
name="primary-black" | ||
args={{ | ||
variant: "primary-black" | ||
}} | ||
/> | ||
|
||
<Story name="primary-black with icon"> | ||
<Button variant="primary-black" | ||
>Button text <svelte:fragment slot="icon" let:iconColor | ||
><IconDownload size={16} fill={iconColor} /></svelte:fragment | ||
></Button | ||
> | ||
</Story> | ||
|
||
<Story | ||
name="primary-black-small" | ||
args={{ | ||
variant: "primary-black", | ||
size: "small" | ||
}} | ||
/> | ||
|
||
<Story | ||
name="secondary" | ||
args={{ | ||
variant: "secondary" | ||
}} | ||
/> | ||
<Story name="secondary with icon"> | ||
<Button variant="secondary" | ||
>Button text <svelte:fragment slot="icon" let:iconColor | ||
><IconDownload size={16} fill={iconColor} /></svelte:fragment | ||
></Button | ||
> | ||
</Story> | ||
|
||
<Story | ||
name="secondary-small" | ||
args={{ | ||
variant: "secondary", | ||
size: "small" | ||
}} | ||
/> | ||
|
||
<Story | ||
name="secondary-black" | ||
args={{ | ||
variant: "secondary-black" | ||
}} | ||
/> | ||
|
||
<Story name="secondary-black with icon"> | ||
<Button variant="secondary-black" | ||
>Button text <svelte:fragment slot="icon" let:iconColor | ||
><IconDownload size={16} fill={iconColor} /></svelte:fragment | ||
></Button | ||
> | ||
</Story> | ||
<Story | ||
name="secondary-black-small" | ||
args={{ | ||
variant: "secondary-black", | ||
size: "small" | ||
}} | ||
/> | ||
|
||
<Story | ||
name="tertiary" | ||
args={{ | ||
variant: "tertiary" | ||
}} | ||
/> | ||
|
||
<Story name="tertiary with icon"> | ||
<Button variant="tertiary" | ||
>Button text <svelte:fragment slot="icon" let:iconColor | ||
><IconDownload size={16} fill={iconColor} /></svelte:fragment | ||
></Button | ||
> | ||
</Story> | ||
<Story | ||
name="tertiary-small" | ||
args={{ | ||
variant: "tertiary", | ||
size: "small" | ||
}} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<!-- @component Button a basic HTML button with Urban styling--> | ||
<script> | ||
import "../style/app.css"; | ||
import { urbanColors } from "../utils"; | ||
import { createEventDispatcher } from "svelte"; | ||
/** | ||
* Which variant of button to use | ||
* @type {"primary" | "primary-black" | "secondary" | "secondary-black" | "tertiary"} | ||
*/ | ||
export let variant = "primary"; | ||
/** | ||
* Which size of button to use | ||
* @type {"standard" | "small" } | ||
*/ | ||
export let size = "standard" | ||
/** | ||
* Is the button disabled? | ||
* @type { boolean } | ||
*/ | ||
export let disabled = false; | ||
let hovered = false; | ||
let dispatch = createEventDispatcher(); | ||
function getIconColor(_variant, _hovered) { | ||
// hovered colors | ||
if (!_hovered) { | ||
if (_variant === "primary" || _variant === "primary-black") { | ||
return urbanColors.white; | ||
} | ||
if (_variant === "secondary") { | ||
return urbanColors.blue; | ||
} | ||
if (_variant === "secondary-black" || _variant === "tertiary") { | ||
return urbanColors.black; | ||
} | ||
} | ||
if (_variant === "primary") { | ||
return urbanColors.white; | ||
} | ||
if (_variant === "primary-black") { | ||
return urbanColors.black; | ||
} | ||
// not hovered colors | ||
if (_variant === "secondary" || _variant == "secondary-black" || _variant === "tertiary") { | ||
return urbanColors.white; | ||
} | ||
return urbanColors.black; | ||
} | ||
function onMouseEnter(e) { | ||
hovered = true; | ||
dispatch("mouseenter", e); | ||
} | ||
function onMouseLeave(e) { | ||
hovered = false; | ||
dispatch("mouseleave", e); | ||
} | ||
$: iconColor = getIconColor(variant, hovered); | ||
</script> | ||
<button class="variant-{variant} size-{size}" on:click {disabled} on:mouseenter={onMouseEnter} on:mouseleave={onMouseLeave}> | ||
<slot>Default button text</slot> | ||
{#if $$slots.icon} | ||
<span class="button-icon"><slot name="icon" {iconColor}></slot></span> | ||
{/if} | ||
</button> | ||
<style> | ||
button { | ||
appearance: none; | ||
border: none; | ||
cursor: pointer; | ||
font-family: var(--font-family-sans); | ||
font-size: var(--font-size-large); | ||
font-weight: var(--font-weight-bold); | ||
text-transform: uppercase; | ||
--border-size: 2px; | ||
} | ||
.button-icon { | ||
display: inline-block; | ||
margin-left: 0.5rem; | ||
} | ||
/* sizes */ | ||
button.size-standard { | ||
padding: calc(1rem - var(--border-size) * 2); | ||
} | ||
button.size-small { | ||
padding: calc(0.75rem - var(--border-size) * 2); | ||
} | ||
/* primary variant */ | ||
button.variant-primary { | ||
background-color: var(--color-blue); | ||
border: solid var(--border-size) var(--color-blue); | ||
color: var(--color-white); | ||
} | ||
button.variant-primary:hover { | ||
background-color: var(--color-blue-shade-dark); | ||
border: solid var(--border-size) var(--color-blue-shade-dark); | ||
} | ||
/* primary-black variant */ | ||
button.variant-primary-black { | ||
background-color: var(--color-black); | ||
border: solid var(--border-size) var(--color-black); | ||
color: var(--color-white); | ||
} | ||
button.variant-primary-black:hover { | ||
background-color: var(--color-white); | ||
color: var(--color-black); | ||
border: solid var(--border-size) var(--color-black); | ||
} | ||
/* secondary variant */ | ||
button.variant-secondary { | ||
background-color: var(--color-white); | ||
border: solid var(--border-size) var(--color-blue); | ||
color: var(--color-blue); | ||
} | ||
button.variant-secondary:hover { | ||
background-color: var(--color-blue); | ||
color: var(--color-white); | ||
border: solid var(--border-size) var(--color-blue); | ||
} | ||
/* secondary-black variant */ | ||
button.variant-secondary-black { | ||
background-color: var(--color-white); | ||
border: solid var(--border-size) var(--color-black); | ||
color: var(--color-black); | ||
} | ||
button.variant-secondary-black:hover { | ||
background-color: var(--color-black); | ||
color: var(--color-white); | ||
border: solid var(--border-size) var(--color-black); | ||
} | ||
/* tertiary variant */ | ||
button.variant-tertiary { | ||
background-color: var(--color-yellow); | ||
border: solid var(--border-size) var(--color-yellow); | ||
color: var(--color-black); | ||
} | ||
button.variant-tertiary:hover { | ||
background-color: var(--color-black); | ||
border: solid var(--border-size) var(--color-black); | ||
color: var(--color-white); | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<script> | ||
export let fill = "#FFFFFF"; | ||
export let size = 48; | ||
</script> | ||
|
||
<svg width={size} height={size} viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"> | ||
<path | ||
d="M43.6933 42.4229C44.0667 42.4229 44.3467 42.56 44.6267 42.7886C44.9067 43.0171 45 43.3371 45 43.7029V46.72C45 47.0857 44.86 47.36 44.6267 47.6343C44.3933 47.9086 44.0667 48 43.6933 48H4.30667C3.93333 48 3.65333 47.8629 3.37333 47.6343C3.09333 47.4057 3 47.0857 3 46.72V43.7029C3 43.3371 3.14 43.0629 3.37333 42.7886C3.60667 42.5143 3.93333 42.4229 4.30667 42.4229H43.6933ZM41.1733 21.44C41.4067 21.2114 41.5 20.9371 41.5 20.5714C41.5 20.2057 41.36 19.8857 41.08 19.6114L38.98 17.4629C38.7 17.2343 38.3733 17.1429 38 17.1429C37.6267 17.1429 37.3467 17.28 37.1133 17.5543L26.8467 27.9314V1.28C26.8467 0.914286 26.7067 0.64 26.4733 0.365714C26.24 0.0914286 25.9133 0 25.54 0H22.46C22.0867 0 21.8067 0.137143 21.5267 0.365714C21.2467 0.594286 21.1533 0.914286 21.1533 1.28V27.9771L10.8867 17.6C10.6533 17.28 10.3733 17.1429 10 17.1429C9.62667 17.1429 9.3 17.2343 9.02 17.4629L6.82667 19.6114C6.59333 19.8857 6.5 20.2057 6.5 20.5714C6.5 20.9371 6.64 21.2114 6.92 21.44L23.02 37.3029C23.3 37.5771 23.6267 37.7143 24 37.7143C24.3733 37.7143 24.7 37.5771 24.98 37.3029L41.1733 21.44Z" | ||
{fill} | ||
/> | ||
</svg> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters