Skip to content

Commit

Permalink
chore(widgets): components update (#4852)
Browse files Browse the repository at this point in the history
### Description

- Added new icons
- Updated Modal with new props
- Fixed an issue where the close icon button was not absolute positioned
to the correct container in the Modal

### Drive-by changes

No

### Backward compatibility

Yes

### Testing

Tested in warp UI
  • Loading branch information
Xaroz authored Nov 13, 2024
1 parent 3e72ef7 commit 1866635
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .changeset/rare-llamas-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@hyperlane-xyz/widgets': minor
---

New Icons
Updated modal with new props
Updated storybook for modal and icon list
38 changes: 38 additions & 0 deletions typescript/widgets/src/icons/Ellipsis.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { memo } from 'react';

import { ColorPalette } from '../color.js';

import { DefaultIconProps } from './types.js';

type Props = DefaultIconProps & {
direction?: 'horizontal' | 'vertical';
};

function _EllipsisIcon({
color = ColorPalette.Black,
width = 24,
height = 6,
direction = 'horizontal',
className,
...rest
}: Props) {
return (
<svg
width={width}
height={height}
viewBox="0 0 24 6"
xmlns="http://www.w3.org/2000/svg"
className={`${
direction === 'vertical' ? 'htw-rotate-90' : ''
} ${className}`}
{...rest}
>
<path
d="M3.42836 5.25C2.74638 5.25 2.09232 5.01295 1.61009 4.59099C1.12785 4.16903 0.856934 3.59674 0.856934 3C0.856934 2.40326 1.12785 1.83097 1.61009 1.40901C2.09232 0.987053 2.74638 0.75 3.42836 0.75C4.11035 0.75 4.7644 0.987053 5.24664 1.40901C5.72887 1.83097 5.99979 2.40326 5.99979 3C5.99979 3.59674 5.72887 4.16903 5.24664 4.59099C4.7644 5.01295 4.11035 5.25 3.42836 5.25ZM11.9998 5.25C11.3178 5.25 10.6638 5.01295 10.1815 4.59099C9.69928 4.16903 9.42836 3.59674 9.42836 3C9.42836 2.40326 9.69928 1.83097 10.1815 1.40901C10.6638 0.987053 11.3178 0.75 11.9998 0.75C12.6818 0.75 13.3358 0.987053 13.8181 1.40901C14.3003 1.83097 14.5712 2.40326 14.5712 3C14.5712 3.59674 14.3003 4.16903 13.8181 4.59099C13.3358 5.01295 12.6818 5.25 11.9998 5.25ZM20.5712 5.25C19.8892 5.25 19.2352 5.01295 18.7529 4.59099C18.2707 4.16903 17.9998 3.59674 17.9998 3C17.9998 2.40326 18.2707 1.83097 18.7529 1.40901C19.2352 0.987053 19.8892 0.75 20.5712 0.75C21.2532 0.75 21.9073 0.987053 22.3895 1.40901C22.8717 1.83097 23.1426 2.40326 23.1426 3C23.1426 3.59674 22.8717 4.16903 22.3895 4.59099C21.9073 5.01295 21.2532 5.25 20.5712 5.25Z"
fill={color}
/>
</svg>
);
}

export const EllipsisIcon = memo(_EllipsisIcon);
29 changes: 29 additions & 0 deletions typescript/widgets/src/icons/Logout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { memo } from 'react';

import { ColorPalette } from '../color.js';

import { DefaultIconProps } from './types.js';

function _LogoutIcon({
color = ColorPalette.Black,
width = 48,
height = 48,
...rest
}: DefaultIconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
height={height}
width={width}
{...rest}
>
<path
fill={color}
d="M9 42q-1.2 0-2.1-.9Q6 40.2 6 39V9q0-1.2.9-2.1Q7.8 6 9 6h14.55v3H9v30h14.55v3Zm24.3-9.25-2.15-2.15 5.1-5.1h-17.5v-3h17.4l-5.1-5.1 2.15-2.15 8.8 8.8Z"
/>
</svg>
);
}

export const LogoutIcon = memo(_LogoutIcon);
30 changes: 30 additions & 0 deletions typescript/widgets/src/icons/Warning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { memo } from 'react';

import { ColorPalette } from '../color.js';

import { DefaultIconProps } from './types.js';

function _WarningIcon({
color = ColorPalette.Black,
width = 18,
height = 16,
...rest
}: DefaultIconProps) {
return (
<svg
width={width}
height={height}
viewBox="0 0 18 16"
xmlns="http://www.w3.org/2000/svg"
{...rest}
>
<path
d="M17.7385 12.8424L10.3944 1.37207C10.0899 0.896794 9.56445 0.609344 9.00031 0.609344C8.43613 0.609344 7.9106 0.896794 7.60622 1.37207L0.261512 12.8424C-0.0648531 13.3519 -0.0874155 13.999 0.203235 14.5299C0.493345 15.0604 1.05035 15.3907 1.65552 15.3907H16.3444C16.9496 15.3907 17.5066 15.0607 17.7967 14.5299C18.0875 13.999 18.0649 13.3519 17.7385 12.8424ZM8.07826 5.27148C8.07826 4.76708 8.48727 4.35837 8.99136 4.35837C9.49553 4.35837 9.9045 4.76708 9.9045 5.27148V9.18939C9.9045 9.69379 9.49553 10.1025 8.99136 10.1025C8.48727 10.1025 8.07826 9.69379 8.07826 9.18939V5.27148ZM8.97416 13.4096C8.34403 13.4096 7.83277 12.8986 7.83277 12.2682C7.83277 11.6377 8.34403 11.1268 8.97416 11.1268C9.60433 11.1268 10.1156 11.6377 10.1156 12.2682C10.1155 12.8986 9.60433 13.4096 8.97416 13.4096Z"
fill={color}
fillOpacity="0.8"
/>
</svg>
);
}

export const WarningIcon = memo(_WarningIcon);
3 changes: 3 additions & 0 deletions typescript/widgets/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export { Circle } from './icons/Circle.js';
export { CopyIcon } from './icons/Copy.js';
export { DiscordIcon } from './icons/Discord.js';
export { DocsIcon } from './icons/Docs.js';
export { EllipsisIcon } from './icons/Ellipsis.js';
export { EnvelopeIcon } from './icons/Envelope.js';
export { FilterIcon } from './icons/Filter.js';
export { FunnelIcon } from './icons/Funnel.js';
Expand All @@ -36,6 +37,7 @@ export { GithubIcon } from './icons/Github.js';
export { HistoryIcon } from './icons/History.js';
export { LinkedInIcon } from './icons/LinkedIn.js';
export { LockIcon } from './icons/Lock.js';
export { LogoutIcon } from './icons/Logout.js';
export { MediumIcon } from './icons/Medium.js';
export { PencilIcon } from './icons/Pencil.js';
export { PlusIcon } from './icons/Plus.js';
Expand All @@ -48,6 +50,7 @@ export { SwapIcon } from './icons/Swap.js';
export { TwitterIcon } from './icons/Twitter.js';
export { UpDownArrowsIcon } from './icons/UpDownArrows.js';
export { WalletIcon } from './icons/Wallet.js';
export { WarningIcon } from './icons/Warning.js';
export { WebIcon } from './icons/Web.js';
export { WideChevronIcon } from './icons/WideChevron.js';
export { XCircleIcon } from './icons/XCircle.js';
Expand Down
27 changes: 18 additions & 9 deletions typescript/widgets/src/layout/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react';
import {
Dialog,
DialogBackdrop,
DialogPanel,
DialogTitle,
} from '@headlessui/react';
import clsx from 'clsx';
import React, { ComponentProps, PropsWithChildren, useState } from 'react';

import { IconButton } from '../components/IconButton.js';
import { XIcon } from '../icons/X.js';
import { XCircleIcon } from '../icons/XCircle.js';

export function useModal() {
const [isOpen, setIsOpen] = useState(false);
Expand All @@ -20,6 +25,7 @@ export type ModalProps = PropsWithChildren<{
panelClassname?: string;
panelProps?: ComponentProps<typeof DialogPanel>;
showCloseButton?: boolean;
title?: string;
}>;

export function Modal({
Expand All @@ -30,30 +36,33 @@ export function Modal({
panelClassname,
panelProps,
showCloseButton,
title,
children,
}: ModalProps) {
return (
<Dialog
open={isOpen}
as="div"
className={clsx(
'htw-relative htw-z-20 htw-focus:outline-none',
dialogClassname,
)}
className={clsx('htw-z-20 htw-focus:outline-none', dialogClassname)}
onClose={close}
{...dialogProps}
>
<DialogBackdrop className="htw-fixed htw-inset-0 htw-bg-black/5 htw-transition-all htw-duration-200" />
<DialogBackdrop className="htw-fixed htw-inset-0 htw-bg-black/25 htw-transition-all htw-duration-200" />
<div className="htw-fixed htw-inset-0 htw-z-20 htw-w-screen htw-overflow-y-auto">
<div className="htw-flex htw-min-h-full htw-items-center htw-justify-center htw-p-4">
<DialogPanel
transition
className={clsx(
'htw-w-full htw-max-w-sm htw-max-h-[90vh] htw-rounded-lg htw-shadow htw-overflow-auto no-scrollbar htw-bg-white htw-duration-200 htw-ease-out data-[closed]:htw-transform-[scale(95%)] data-[closed]:htw-opacity-0 data-[closed]:htw--translate-y-1',
'htw-w-full htw-max-w-sm htw-max-h-[90vh] htw-relative htw-rounded-lg htw-shadow htw-overflow-auto no-scrollbar htw-bg-white htw-duration-200 htw-ease-out data-[closed]:htw-transform-[scale(95%)] data-[closed]:htw-opacity-0 data-[closed]:htw--translate-y-1',
panelClassname,
)}
{...panelProps}
>
{title && (
<DialogTitle as="h3" className="htw-text-gray-700">
{title}
</DialogTitle>
)}
{children}
{showCloseButton && (
<div className="htw-absolute htw-right-3 htw-top-3">
Expand All @@ -62,7 +71,7 @@ export function Modal({
title="Close"
className="hover:htw-rotate-90"
>
<XIcon height={10} width={10} />
<XCircleIcon height={16} width={16} />
</IconButton>
</div>
)}
Expand Down
22 changes: 21 additions & 1 deletion typescript/widgets/src/stories/IconList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ interface StoryIconProps {
rounded?: boolean;
}

const excludedComponents = ['IconButton', 'EllipsisIcon'];

const iconList = Object.entries(Hyperlane)
.filter(([name]) => name.includes('Icon') && !name.includes('IconButton'))
.filter(
([name]) => name.includes('Icon') && !excludedComponents.includes(name),
)
.map(([_, Component]) => Component as React.ComponentType<StoryIconProps>);

function IconList({
Expand All @@ -22,13 +26,15 @@ function IconList({
direction,
bgColorSeed,
roundedWideChevron,
ellipsisDirection,
}: {
width: number;
height: number;
color: string;
direction: 'n' | 'e' | 's' | 'w';
bgColorSeed: number | undefined;
roundedWideChevron: boolean;
ellipsisDirection: 'vertical' | 'horizontal';
}) {
return (
<>
Expand All @@ -52,6 +58,15 @@ function IconList({
/>
</IconContainer>
))}
<IconContainer>
<span>EllipsisIcon</span>
<Hyperlane.EllipsisIcon
width={width}
height={height}
direction={ellipsisDirection}
color={color}
/>
</IconContainer>
<IconContainer>
<span>Circle</span>
<Hyperlane.Circle size={width} bgColorSeed={bgColorSeed} />
Expand Down Expand Up @@ -85,6 +100,10 @@ const meta = {
options: ['n', 'e', 's', 'w'],
control: { type: 'select' },
},
ellipsisDirection: {
options: ['horizontal', 'vertical'],
control: { type: 'select' },
},
},
} satisfies Meta<typeof IconList>;
export default meta;
Expand All @@ -98,5 +117,6 @@ export const DefaultIconList = {
direction: 's',
bgColorSeed: 0,
roundedWideChevron: false,
ellipsisDirection: 'horizontal',
},
} satisfies Story;
15 changes: 11 additions & 4 deletions typescript/widgets/src/stories/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import React, { useState } from 'react';

import { Modal } from '../layout/Modal.js';

function MyModal() {
function MyModal({
title,
showCloseButton,
}: {
title?: string;
showCloseButton?: boolean;
}) {
const [isOpen, setIsOpen] = useState(false);
const open = () => setIsOpen(true);
const close = () => setIsOpen(false);
Expand All @@ -15,8 +21,9 @@ function MyModal() {
<Modal
isOpen={isOpen}
close={close}
showCloseButton
panelClassname="htw-bg-gray-100"
showCloseButton={showCloseButton}
title={title}
panelClassname="htw-bg-gray-100 htw-p-4"
>
<div>Hello Modal</div>
</Modal>
Expand All @@ -32,5 +39,5 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const BasicModal = {
args: {},
args: { title: '', showCloseButton: true },
} satisfies Story;

0 comments on commit 1866635

Please sign in to comment.