Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AerDropdownMenu #24

Open
wants to merge 56 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3f3acab
feat:
S-unya Nov 18, 2022
4e259a9
feat: update packages & use vite/vitest
S-unya Nov 18, 2022
7ef6349
feat: use vite with sotrybook
S-unya Nov 18, 2022
2c24cf3
feat:
S-unya Nov 18, 2022
991ee40
feat: Add AlertDialog & Button
S-unya Nov 18, 2022
8338ff7
docs: readme
S-unya Nov 18, 2022
87646d2
chore: fix Button story title & add z-index tokens
S-unya Nov 18, 2022
0fdafb0
feat: AlertDialog, rename with Aer prefix
S-unya Nov 21, 2022
90a4c2f
style: AlertDialog, fix animation behaviour
S-unya Nov 21, 2022
da3e8be
fix: add visuallyHidden style
S-unya Nov 21, 2022
ed92b50
chore: rm unnecessary templates
S-unya Nov 21, 2022
d32f1a8
chore: update component story to include local theme docs
S-unya Nov 21, 2022
dcab2b8
docs: add local theme docs to stories
S-unya Nov 21, 2022
93866f9
chore: comment out favicon
S-unya Nov 21, 2022
18b53be
test: fix AerButton tests
S-unya Nov 21, 2022
75a40c9
test: update tests
S-unya Nov 21, 2022
000e9af
feat: Accodion added to package
S-unya Nov 21, 2022
93125ff
chore: more templating
S-unya Nov 21, 2022
67c4d32
feat: AerAccordion added to lib (unfinished)
S-unya Nov 21, 2022
054d3cf
fix: updated repo refs
S-unya Nov 24, 2022
b41ee6c
fix: updated repo refs
S-unya Nov 24, 2022
5f6a560
chore: accordion: add template for local theme docs
S-unya Nov 25, 2022
ea1b4ba
feat: accordion add local theme
S-unya Nov 25, 2022
98543ba
docs: alert update readme
S-unya Nov 25, 2022
71c526f
Merge branch 'update-packaging' of github.com:aerian-studios/aerian-c…
S-unya Nov 25, 2022
492b8c3
chore: alert respond to pr comments
S-unya Nov 25, 2022
f934ec3
feat: alert change API, respond to PR comments
S-unya Nov 25, 2022
abb6c17
Merge branch 'update-packaging' into accordion
S-unya Nov 26, 2022
d3c2dbb
style: accordion update animation styles
S-unya Nov 26, 2022
402486c
docs: readme updated to reflect current state
S-unya Nov 26, 2022
082b34c
style: checkbox + new util & box-sizing & rm Theme
S-unya Nov 27, 2022
e90b9a3
feat: checkbox new component
S-unya Nov 27, 2022
5c787dd
chore: checkbox update packages
S-unya Nov 27, 2022
41a6383
feat: checkbox slight API change
S-unya Nov 27, 2022
a9250d8
chore: checkbox update template
S-unya Nov 27, 2022
b009951
feat: checkbox enforce `value` & + label for status
S-unya Nov 27, 2022
7e29744
docs: checkbox Add local theme
S-unya Nov 27, 2022
2d94da4
test: checkbox tests
S-unya Nov 27, 2022
f47d69e
feat: checkbox update accordion to change heading levels
S-unya Nov 27, 2022
b385a15
docs: checkbox document theme usage
S-unya Nov 28, 2022
0ecef64
style: checkbox use scss vars for local vars
S-unya Nov 28, 2022
af01545
chore: checkbox clean up
S-unya Nov 28, 2022
2bf9f8f
style: checkbox update local themes for consistency
S-unya Nov 28, 2022
e574732
Update src/components/AerButton/AerButton.tsx
S-unya Nov 28, 2022
3f12873
test: checkbox update accordion test
S-unya Nov 28, 2022
1385501
Merge branch 'update-packaging' into checkbox
S-unya Nov 28, 2022
bedf89e
chore: dropdown add package & update template
S-unya Nov 29, 2022
41ca72d
feat: dropdown start component work
S-unya Nov 29, 2022
71a02db
feat: dropdown all the subcomponents, not working yet
S-unya Dec 2, 2022
17ac739
style: dropdown add a couple of theme vars
S-unya Dec 5, 2022
9d5aabe
feat: dropdown working & styled dropdown
S-unya Dec 5, 2022
9b9af7b
docs: dropdown remove floder from button story
S-unya Dec 5, 2022
1d24546
feat: dropdown add utils/dataStructures.ts/removeEmptyObjectKVs
S-unya Dec 5, 2022
b22cc86
chore: dropdown refactor container el to be ref
S-unya Dec 5, 2022
da6a2d1
chore: checkbox address PR comments
S-unya Dec 5, 2022
9a7b196
Merge branch 'checkbox' into AerDropdownMenu
S-unya Dec 5, 2022
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
Prev Previous commit
Next Next commit
feat: Add AlertDialog & Button
S-unya committed Nov 18, 2022
commit 991ee401237975eee27fecd5939698df838b42d2
85 changes: 85 additions & 0 deletions src/components/AlertDialog/AlertDialog.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Implements the following theme:
* animation-duration: var(--ease-duration-short, 150ms);
* animation-transition: var(--ease-1, 0.16, 1, 0.3, 1);
* overlay animation: overlayShow
* overlay: background-color: var(--c-overlay-bg-color, var(--c-black));
* overlay: opacity: var(--c-overlay-opacity);
*
* content animation: contentShow
* content: background-color: var(--c-dialog-content-bg, var(--c-white));
* content: border-radius: var(--s-border-radius-xs);
* content: box-shadow: var(--sh-dialog-content-shadow, var(--sh-box-xs));
* content: padding: var(--s-content-padding, var(--s-2));
* content: var(--s-content-border-radius, var(--s-border-radius-xs));
*
* title: font-size: var(--t-dialog-title);
* title: font-weight: var(--fw-dialog-title);
*/

@keyframes overlayShow {
0% {
opacity: 0;
}
90% {
opacity: 1;
}
}

@keyframes contentShow {
0% {
opacity: 0;
scale: 0.5;
}
50% {
scale: 1;
}
100% {
opacity: 1;
}
}

.content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90vw;
max-width: 500px;
max-height: 85vh;
padding: var(--s-content-padding, var(--s-2));
animation: contentShow var(--ease-duration-short, 150ms)
var(--ease-1, 0.16, 1, 0.3, 1);
background-color: var(--c-dialog-content-bg, var(--c-white));
border-radius: var(--s-content-border-radius, var(--s-border-radius-xs));
box-shadow: var(--sh-dialog-content-shadow, var(--sh-box-xs));

&:focus {
outline: none;
}
}

.overlay {
position: fixed;
inset: 0;
// todo, potentially move this variable to global
background-color: var(--c-overlay-bg-color, var(--c-black));
opacity: var(--c-overlay-opacity);
animation: overlayShow var(--ease-duration-short, 150ms)
var(--ease-1, 0.16, 1, 0.3, 1);
}

.title {
font-size: var(--t-dialog-title, var(--t-heading-m));
font-weight: var(--fw-dialog-title, var(--fw-medium));
}

.description {
position: relative;
}

.footer {
display: flex;
justify-content: flex-end;
align-items: center;
}
36 changes: 36 additions & 0 deletions src/components/AlertDialog/AlertDialog.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { AlertDialog, AlertDialogFooter, AlertDialogTrigger } from "./index";

describe("AlertDialog", () => {
it("should render correctly", async () => {
const { container } = render(
<AlertDialog
trigger={
<AlertDialogTrigger>
<button>Open the dialog</button>
</AlertDialogTrigger>
}
dialogTitle={<>This is important!</>}
dialogFooter={
<AlertDialogFooter
dialogCancel={<button>Cancel</button>}
dialogAction={<button>Yes, do it!</button>}
/>
}
dialogContent={<p>Are you sure about all of that stuff?</p>}
/>
);

await userEvent.click(
screen.getByRole("button", { name: "Open the dialog" })
);

expect(screen.getByRole("alertdialog", { name: "This is important!" }));
expect(screen.getByText("Are you sure about all of that stuff?"));

expect(container).toMatchSnapshot();
});
});
32 changes: 32 additions & 0 deletions src/components/AlertDialog/AlertDialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";
import { AlertDialog, AlertDialogTrigger, AlertDialogFooter } from "./index";

const Meta: ComponentMeta<typeof AlertDialog> = {
title: "Components/AlertDialog",
component: AlertDialog,
subcomponents: { AlertDialogTrigger, AlertDialogFooter },
};

export default Meta;

const Template: ComponentStory<typeof AlertDialog> = (args) => (
<AlertDialog {...args} />
);
export const Default = Template.bind({});

Default.args = {
trigger: (
<AlertDialogTrigger>
<button>Open the dialog</button>
</AlertDialogTrigger>
),
dialogTitle: <>This is important!</>,
dialogContent: <p>Are you sure about all of that stuff?</p>,
dialogFooter: (
<AlertDialogFooter
dialogCancel={<button>Cancel</button>}
dialogAction={<button>Yes, do it!</button>}
/>
),
};
84 changes: 84 additions & 0 deletions src/components/AlertDialog/AlertDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { ReactElement } from "react";
import cx from "classnames";
import * as Dialog from "@radix-ui/react-alert-dialog";
import styles from "./AlertDialog.module.scss";
import { DefaultProps } from "../../types/types";

export const AlertDialogTrigger = ({ children }: DefaultProps<"button">) => (
<Dialog.Trigger asChild>{children}</Dialog.Trigger>
);

export interface AlertDialogFooterProps extends DefaultProps<"footer"> {
// An element (ideally a button) to cancel the alert dialog
dialogCancel?: ReactElement;
// An element (ideally a button) to trigger the alert dialog action
dialogAction: ReactElement;
}

export const AlertDialogFooter = ({
dialogCancel,
dialogAction,
...rest
}: AlertDialogFooterProps) => (
<footer {...rest}>
{dialogCancel ? (
<Dialog.Cancel asChild>{dialogCancel}</Dialog.Cancel>
) : null}
<Dialog.Action asChild>{dialogAction}</Dialog.Action>
</footer>
);

const elementIsReactElement = (element: any): element is ReactElement => {
return "props" in element;
};

export interface AlertDialogProps extends DefaultProps<"div"> {
// The trigger should be an `AlertDialogTrigger`
trigger: ReactElement;
// `dialogTitle` is an object of the title and whether to hide the title (this defaults to true). NOTE: This is placed in an `<h2>`.
dialogTitle: ReactElement | { title: ReactElement; hideTitle?: boolean };
// The body content of the alert. NOTE: This will take the form of the element that you pass in.
dialogContent: ReactElement;
// An element that displays in the dialog footer that contains an action and an optional cancel button
dialogFooter: ReactElement;
}
/**
* The AlertDialog interrupts a user's workflow to communicate an important message that requires a response. *NOTE:* This is different from the Dialog component
*/
export const AlertDialog = ({
className,
trigger,
dialogTitle,
dialogFooter,
dialogContent,
}: AlertDialogProps) => {
return (
<Dialog.Root>
{trigger}
<Dialog.Portal>
<div className={className}>
<Dialog.Overlay className={styles.overlay} />
<Dialog.Content className={cx(styles.content)}>
{elementIsReactElement(dialogTitle) ? (
<Dialog.Title className={cx(styles.title)}>
{dialogTitle}
</Dialog.Title>
) : (
<Dialog.Title
className={cx(styles.title, {
[styles.visuallyHidden]: dialogTitle.hideTitle === false,
})}
>
{dialogTitle.title}
</Dialog.Title>
)}
<Dialog.Description className={styles.description} asChild>
{dialogContent}
</Dialog.Description>
{dialogFooter}
</Dialog.Content>
</div>
</Dialog.Portal>
</Dialog.Root>
);
};
18 changes: 18 additions & 0 deletions src/components/AlertDialog/__snapshots__/AlertDialog.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Vitest Snapshot v1

exports[`AlertDialog > should render correctly 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<button
aria-controls="radix-:r0:"
aria-expanded="true"
aria-haspopup="dialog"
data-state="open"
type="button"
>
Open the dialog
</button>
</div>
`;
3 changes: 3 additions & 0 deletions src/components/AlertDialog/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { AlertDialog, AlertDialogTrigger, AlertDialogFooter } from "./AlertDialog";

export { AlertDialog, AlertDialogTrigger, AlertDialogFooter };
135 changes: 135 additions & 0 deletions src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
Implements the globally available theme::after// Button
--c-button: var(--c-cobalt);
--c-button-bg: var(--c-white);
--c-button-border: var(--c-cobalt);
--c-button-hover: var(--c-luminous-vivid-amber);
--c-button-hover-bg: var(--c-white);
--c-button-hover-border: var(--c-luminous-vivid-amber);
--c-button-disabled: var(--c-gray-600);
--c-button-disabled-bg: var(--c-gray-200);
// Primary
--c-button-primary: var(--c-cobalt);
--c-button-primary-bg: var(--c-vivid-green-cyan);
--c-button-primary-border: var(--c-cobalt);
--c-button-primary-hover: var(--c-cobalt);
--c-button-primary-hover-bg: var(--c-luminous-vivid-amber);
--c-button-primary-hover-border: var(--c-cobalt);
--c-button-primary-disabled: var(--c-gray-600);
--c-button-primary-disabled-bg: var(--c-gray-200);
// Important/negative
--c-button-important: var(--c-white);
--c-button-important-bg: var(--c-negative);
--c-button-important-border: var(--c-negative);
--c-button-important-hover: var(--c-cobalt);
--c-button-important-hover-bg: var(--c-luminous-vivid-amber);
--c-button-important-hover-border: var(--c-cobalt);
--c-button-important-disabled: var(--c-gray-600);
--c-button-important-disabled-bg: var(--c-gray-200);
// (buttons that look like links)
--c-button-tertiary: var(--c-link);
--c-button-tertiary-bg: transparent;
--c-button-tertiary-border: transparent;
--c-button-tertiary-hover: var(--c-link-hover);
--c-button-tertiary-hover-border: transparent;
--c-button-tertiary-hover-bg: transparent;
--c-button-tertiary-disabled: var(--c-link-disabled);
--c-button-tertiary-disabled-bg: transparent;
*/

.default {
all: unset;
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--s-button-padding, var(--s-1) var(--s-2));
border: 1px solid;
background-color: var(--c-button-bg);
border-color: var(--c-button);
border-radius: var(--s-btn-radius, var(-s-border-radius-s));
font-size: var(--t-body-m);
color: var(--c-button);

&:active:enabled,
&:focus-visible:enabled,
&:hover:enabled {
color: var(--c-button-hover);
background: var(--c-button-hover-bg);
border-color: var(--c-button-hover-border);
}

&:disabled {
cursor: not-allowed;
color: var(--c-button-disabled);
border-color: var(--c-button-disabled-border);
background-color: var(--c-button-disabled-bg);
}
}

.primary {
composes: default;
background-color: var(--c-button-primary-bg);
border-color: var(--c-button-primary);
border-radius: var(--s-btn-radius, var(-s-border-radius-s));
font-size: var(--t-body-m);
color: var(--c-button-primary);

&:active:enabled,
&:focus-visible:enabled,
&:hover:enabled {
color: var(--c-button-primary-hover);
background: var(--c-button-primary-hover-bg);
border-color: var(--c-button-primary-hover-border);
}

&:disabled {
color: var(--c-button-primary-disabled);
border-color: var(--c-button-primary-disabled-border);
background-color: var(--c-button-primary-disabled-bg);
}
}

// looks like link
.tertiary {
composes: default;
background-color: var(--c-button-tertiary-bg);
color: var(--c-button-tertiary);
border: solid 1px var(--c-button-tertiary-border);
padding: 0;

&:focus-visible:enabled,
&:hover:enabled,
&:active:enabled {
color: var(--c-button-tertiary-hover);
background-color: var(--c-button-tertiary-bg);
border: solid 1px var(--c-button-tertiary-border);
text-decoration: underline;
}

&:disabled {
color: var(--c-button-tertiary-disabled);
border-color: var(--c-button-tertiary-disabled-border);
background-color: var(--c-button-tertiary-disabled-bg);
}
}

.important {
composes: default;
background-color: var(--c-button-important-bg);
color: var(--c-button-important);
border: 1px solid var(--c-button-important-border);

&:active:enabled,
&:focus-visible:enabled,
&:hover:enabled {
color: var(--c-button-important-hover);
background: var(--c-button-important-hover-bg);
border-color: var(--c-button-important-hover-border);
}

&:disabled {
color: var(--c-button-important-disabled);
border-color: var(--c-button-important-disabled-border);
background-color: var(--c-button-important-disabled-bg);
}
}
Loading