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

chore: use radix to improve modal component #854

Open
wants to merge 9 commits into
base: next
Choose a base branch
from
9 changes: 8 additions & 1 deletion widget/embedded/src/utils/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,20 @@ export function expandToGenerateThemeColors(
*/
const isSingleColor = ['background', 'foreground'].includes(colorKey);

const expandedHexColor = expandShortHexColor(expandColor);
if (!isSingleColor && !isOverridingColor(colorKey)) {
const expandedHexColor = expandShortHexColor(expandColor);
Object.assign(
output,
createTintsAndShades(expandedHexColor, colorKey, isNeutralReversed)
);
}

if (colorKey === 'neutral') {
// add alpha to have 70 percent opacity
Object.assign(output, {
overlay: expandedHexColor + 'b3',
});
}
}

return { ...output, ...expandColors };
Expand Down
8 changes: 5 additions & 3 deletions widget/storybook/src/components/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ModalPropTypes } from '@rango-dev/ui';
import type { Meta } from '@storybook/react';

import { MessageBox, Modal } from '@rango-dev/ui';
import React, { useState } from 'react';
import React, { useRef, useState } from 'react';

export default {
name: 'Modal',
Expand Down Expand Up @@ -51,12 +51,14 @@ export default {

export const Main = (args: ModalPropTypes) => {
const [open, setOpen] = useState<boolean>(false);
const modalContainerRef = useRef<HTMLDivElement | null>(null);

return (
<div>
<div ref={modalContainerRef}>
<button onClick={() => setOpen(true)}>Open Modal</button>
<Modal
{...args}
container={document.getElementById('storybook-root')}
container={modalContainerRef.current as HTMLElement}
open={open}
onClose={() => setOpen(false)}>
<MessageBox
Expand Down
2 changes: 2 additions & 0 deletions widget/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@
"dependencies": {
"@radix-ui/react-checkbox": "^1.0.1",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-popover": "^1.0.6",
"@radix-ui/react-radio-group": "^1.1.1",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-switch": "^1.0.1",
"@radix-ui/react-tooltip": "^1.0.2",
"@radix-ui/react-visually-hidden": "^1.1.0",
"@rango-dev/wallets-shared": "^0.37.1-next.1",
"@stitches/react": "^1.2.8",
"copy-to-clipboard": "^3.3.3",
Expand Down
4 changes: 0 additions & 4 deletions widget/ui/src/components/Modal/Modal.helpers.ts

This file was deleted.

159 changes: 114 additions & 45 deletions widget/ui/src/components/Modal/Modal.styles.ts
Original file line number Diff line number Diff line change
@@ -1,83 +1,148 @@
import { styled } from '../../theme.js';
import * as Dialog from '@radix-ui/react-dialog';

import { keyframes, styled } from '../../theme.js';
import { IconButton } from '../IconButton/index.js';

export const BackDrop = styled('div', {
const DialogOverlayAnimateIn = keyframes({
'0%': {
backgroundColor: 'transparent',
},
'100%': {
backgroundColor: '$overlay',
},
});

const DialogOverlayAnimateOut = keyframes({
'0%': {
backgroundColor: '$overlay',
},
'100%': {
backgroundColor: 'transparent',
},
});

export const DialogOverlay = styled(Dialog.Overlay, {
position: 'absolute',
top: '0',
left: '0',
right: '0',
bottom: '0',
width: '100%',
height: '100%',
backgroundColor: 'transparent',
zIndex: 10,
borderRadius: '$primary',
overflow: 'hidden',
transition: 'background .35s',
backgroundColor: 'transparent',

variants: {
active: {
true: {
backgroundColor: 'color-mix(in srgb, $neutral500 70%, transparent)',
},
},
"&[data-state='open']": {
backgroundColor: '$overlay',
animation: `${DialogOverlayAnimateIn} .45s ease-in-out`,
},
"&[data-state='closed']": {
backgroundColor: 'transparent',
animation: `${DialogOverlayAnimateOut} .45s ease-in-out`,
},
});

const DialogContentRightAnimateIn = keyframes({
'0%': {
transform: 'translateX(100%)',
},
'100%': {
transform: 'translateX(0%)',
},
});

const DialogContentRightAnimateOut = keyframes({
'0%': {
transform: 'translateX(0%)',
},
'100%': {
transform: 'translateX(100%)',
},
});
const DialogContentCenterAnimateIn = keyframes({
'0%': {
top: '100%',
transform: 'translate(-50%, 100%)',
},
'100%': {
top: '50%',
transform: 'translate(-50%, -50%)',
},
});

const DialogContentCenterAnimateOut = keyframes({
'0%': {
top: '50%',
transform: 'translate(-50%, -50%)',
},
'100%': {
top: '100%',
transform: 'translate(-50%, 100%)',
},
});
const DialogContentBottomAnimateIn = keyframes({
'0%': {
transform: 'translateY(100%)',
},
'100%': {
transform: 'translateY(0%)',
},
});

const DialogContentBottomAnimateOut = keyframes({
'0%': {
transform: 'translateY(0%)',
},
'100%': {
transform: 'translateY(100%)',
},
});

export const ModalContainer = styled('div', {
export const DialogContent = styled(Dialog.Content, {
backgroundColor: '$background',
width: '100%',
borderRadius: '$primary',
display: 'flex',
flexDirection: 'column',
zIndex: 9999999,
position: 'absolute',
transition:
'transform .45s ease-in-out, top .45s ease-in-out, left .45s ease-in-out',

variants: {
anchor: {
right: {
left: '100%',
right: '0%',
"&[data-state='open']": {
animation: `${DialogContentRightAnimateIn} .45s ease-in-out`,
},
"&[data-state='closed']": {
animation: `${DialogContentRightAnimateOut} .45s ease-in-out`,
},
},
center: {
top: '100%',
left: '50%',
transform: 'translateX(-50%)',
transform: 'translate(-50%, -50%)',
"&[data-state='open']": {
top: '50%',
animation: `${DialogContentCenterAnimateIn} .45s ease-in-out`,
},
"&[data-state='closed']": {
top: '100%',
animation: `${DialogContentCenterAnimateOut} .45s ease-in-out`,
},
},
bottom: {
top: '100%',
bottom: 0,
"&[data-state='open']": {
animation: `${DialogContentBottomAnimateIn} .45s ease-in-out`,
},
"&[data-state='closed']": {
animation: `${DialogContentBottomAnimateOut} .45s ease-in-out`,
},
},
},
active: {
true: {},
},
},
compoundVariants: [
{
active: true,
anchor: 'right',
css: {
transform: 'translateX(-100%)',
},
},
{
active: true,
anchor: 'center',
css: {
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
},
{
active: true,
anchor: 'bottom',
css: {
transform: 'translateY(-100%)',
},
},
],
});

export const Flex = styled('div', {
Expand Down Expand Up @@ -114,6 +179,10 @@ export const Content = styled('div', {
overflowX: 'hidden',
});

export const DialogTitle = styled(Dialog.DialogTitle, {
margin: 0,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this will affect a11y and they did the trick for that. We can ignore 1px difference.

Copy link
Collaborator Author

@RyukTheCoder RyukTheCoder Sep 30, 2024

Choose a reason for hiding this comment

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

This was not added to handle 1px difference. Actually with position set to absolute, there is no 1px difference. When we wrap title with Dialog.DialogTitle it will be wrapped in a h2 element which have a default margin so I added this to remove the unwanted margin.

});

export const Footer = styled('div', {
padding: '0 $20 $10',
'& .footer__logo': {
Expand Down
Loading