Skip to content

Commit

Permalink
feat(components): add balloon components (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kohei Asai authored Apr 10, 2021
1 parent 7eb3f09 commit 15374c0
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
14 changes: 14 additions & 0 deletions components/balloon.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from "react";
import { Story, Meta } from "@storybook/react";
import { Balloon, BalloonProps } from "./balloon";

export default {
title: "Components/Balloon",
component: Balloon,
argTypes: {},
args: {
children: <div style={{ width: 200, height: 200 }}>200x200</div>,
},
} as Meta;

export const Example: Story<BalloonProps> = (props) => <Balloon {...props} />;
48 changes: 48 additions & 0 deletions components/balloon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { css, cx } from "@linaria/core";
import * as React from "react";

export interface BalloonProps extends React.Attributes {
className?: string;
style?: React.CSSProperties;
}

export const Balloon: React.FC<BalloonProps> = ({
children,
className,
...props
}) => {
return (
<div
className={cx(
css`
position: relative;
padding-block-end: 8px;
`,
className
)}
{...props}
>
<div
className={css`
position: absolute;
top: calc(100% - 8px);
left: var(--space-md);
border-width: 8px;
border-style: solid;
border-color: var(--color-bg-gray-weak) transparent transparent
transparent;
`}
/>

<div
className={css`
background-color: var(--color-bg-gray-weak);
backdrop-filter: blur(8px);
border-radius: 8px;
`}
>
{children}
</div>
</div>
);
};
26 changes: 26 additions & 0 deletions components/button-list-balloon.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Story, Meta } from "@storybook/react";
import * as React from "react";
import { Facebook, Twitter } from "react-feather";
import {
ButtonListBalloon,
ButtonListBalloonProps,
ButtonListBaloonItem,
} from "./button-list-balloon";

export default {
title: "Components/ButtonListBalloon",
component: ButtonListBalloon,
subcomponents: { ButtonListBaloonItem },
argTypes: {},
args: {},
} as Meta;

export const Example: Story<ButtonListBalloonProps> = (props) => (
<ButtonListBalloon {...props}>
<ButtonListBaloonItem>Click me</ButtonListBaloonItem>

<ButtonListBaloonItem icon={<Facebook />} />

<ButtonListBaloonItem icon={<Twitter />}>Click me</ButtonListBaloonItem>
</ButtonListBalloon>
);
110 changes: 110 additions & 0 deletions components/button-list-balloon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { css, cx } from "@linaria/core";
import * as React from "react";
import { IconProps } from "react-feather";
import { Balloon } from "./balloon";

export interface ButtonListBalloonProps extends React.Attributes {
className?: string;
style?: React.CSSProperties;
children?:
| React.ReactElement<ButtonListBaloonItemProps>
| React.ReactElement<ButtonListBaloonItemProps>[];
}

export const ButtonListBalloon: React.VFC<ButtonListBalloonProps> = ({
children,
...props
}) => {
return (
<Balloon {...props}>
<ul
className={css`
display: flex;
list-style: none;
margin-block-start: 0;
margin-block-end: 0;
padding-inline-start: 0;
`}
>
{React.Children.map(children, (child) => (
<li>{child}</li>
))}
</ul>
</Balloon>
);
};

export interface ButtonListBaloonItemProps
extends React.HTMLAttributes<HTMLButtonElement> {
icon?: React.ReactElement<IconProps>;
}

export const ButtonListBaloonItem: React.FC<ButtonListBaloonItemProps> = ({
icon,
className,
children,
...props
}) => {
return (
<button
className={cx(
css`
appearance: none;
display: flex;
align-items: center;
justify-content: center;
min-width: 48px;
max-width: 256px;
height: 48px;
background-color: inherit;
border: none;
border-radius: 8px;
cursor: pointer;
:hover {
background-color: var(--color-bg-gray);
}
`,
children
? css`
padding-inline-start: var(--space-md);
padding-inline-end: var(--space-md);
`
: null,
className
)}
{...props}
>
{icon
? React.cloneElement(icon, {
...icon.props,
className: cx(
css`
width: 20px;
height: 20px;
color: var(--color-fg-strong);
`,
children
? css`
margin-inline-end: var(--space-sm);
`
: null,
icon.props.className
),
})
: null}

<span
className={css`
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
color: var(--color-fg-strong);
overflow: hidden;
`}
>
{children}
</span>
</button>
);
};

1 comment on commit 15374c0

@vercel
Copy link

@vercel vercel bot commented on 15374c0 Apr 10, 2021

Choose a reason for hiding this comment

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

Please sign in to comment.