- Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis nam minima non modi consequuntur corporis est
- itaque, exercitationem amet, fugiat optio, facilis repellendus inventore vero perferendis. Possimus porro eaque
- facere.
-
-
-
-
Grid content
-
- Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis nam minima non modi consequuntur corporis est
- itaque, exercitationem amet, fugiat optio, facilis repellendus inventore vero perferendis. Possimus porro eaque
- facere.
-
-
-
-);
diff --git a/packages/components/src/Grid/Grid.style.tsx b/packages/components/src/Grid/Grid.style.tsx
deleted file mode 100644
index b4775fb27..000000000
--- a/packages/components/src/Grid/Grid.style.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import styled from 'styled-components';
-import { theme } from '@interlay/theme';
-
-export const GridContainer = styled.div`
- display: grid;
- gap: ${theme.spacing.spacing5};
- grid-template-columns: repeat(4, 1fr);
-
- @media screen and (min-width: 48em) {
- grid-template-columns: repeat(12, 1fr);
- }
-`;
diff --git a/packages/components/src/Grid/Grid.tsx b/packages/components/src/Grid/Grid.tsx
deleted file mode 100644
index c3ab5371e..000000000
--- a/packages/components/src/Grid/Grid.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { GridContainer } from './Grid.style';
-
-interface GridProps {
- children: React.ReactNode;
- className?: string;
-}
-
-const Grid = ({ className, children }: GridProps): JSX.Element => (
- {children}
-);
-
-export { Grid };
-export type { GridProps };
diff --git a/packages/components/src/Grid/GridItem.style.tsx b/packages/components/src/Grid/GridItem.style.tsx
deleted file mode 100644
index 44e438bf5..000000000
--- a/packages/components/src/Grid/GridItem.style.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import styled from 'styled-components';
-
-import { GridItemProps } from './GridItem';
-
-export const GridItemContainer = styled.div`
- grid-column: ${(props) =>
- props.mobile.start ? `${props.mobile.start} / span ${props.mobile.span}` : `span ${props.mobile.span}`};
- grid-row: ${(props) => props.mobile.row || 'auto'};
- justify-self: ${(props) => props.mobile.justify || 'auto'};
-
- @media (min-width: 48em) {
- grid-column: ${(props) =>
- props.desktop.start ? `${props.desktop.start} / span ${props.desktop.span}` : `span ${props.desktop.span}`};
- grid-row: ${(props) => props.desktop.row || 'auto'};
- justify-self: ${(props) => props.desktop.justify || 'auto'};
- }
-`;
diff --git a/packages/components/src/Grid/GridItem.tsx b/packages/components/src/Grid/GridItem.tsx
deleted file mode 100644
index 3ecdfe568..000000000
--- a/packages/components/src/Grid/GridItem.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { GridItemContainer } from './GridItem.style';
-
-type Justify = 'start' | 'center' | 'end';
-
-type GridColumnsWide = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
-type GridColumnsNarrow = 1 | 2 | 3 | 4;
-
-interface GridItemProps extends React.HTMLAttributes {
- mobile: {
- span: GridColumnsNarrow;
- start?: GridColumnsNarrow;
- row?: number;
- justify?: Justify;
- };
- desktop: {
- span: GridColumnsWide;
- start?: GridColumnsWide;
- row?: number;
- justify?: Justify;
- };
-}
-
-const GridItem = ({ mobile, desktop, className, children }: GridItemProps): JSX.Element => (
-
- {children}
-
-);
-
-export { GridItem };
-export type { GridItemProps };
diff --git a/packages/components/src/Grid/__tests__/Grid.test.tsx b/packages/components/src/Grid/__tests__/Grid.test.tsx
deleted file mode 100644
index ae83a76f5..000000000
--- a/packages/components/src/Grid/__tests__/Grid.test.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { render } from '@testing-library/react';
-
-import { Grid, GridItem } from '..';
-
-describe('Grid', () => {
- it('should render correctly', () => {
- const wrapper = render(
-
-
- item
-
-
- );
-
- expect(() => wrapper.unmount()).not.toThrow();
- });
-});
diff --git a/packages/components/src/Grid/index.ts b/packages/components/src/Grid/index.ts
deleted file mode 100644
index 4de7077e0..000000000
--- a/packages/components/src/Grid/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export type { GridProps } from './Grid';
-export { Grid } from './Grid';
-export type { GridItemProps } from './GridItem';
-export { GridItem } from './GridItem';
diff --git a/packages/components/src/HelperText/HelperText.style.tsx b/packages/components/src/HelperText/HelperText.style.tsx
index bf979bbe1..d9e733c6f 100644
--- a/packages/components/src/HelperText/HelperText.style.tsx
+++ b/packages/components/src/HelperText/HelperText.style.tsx
@@ -1,5 +1,4 @@
import styled from 'styled-components';
-import { theme } from '@interlay/theme';
import { visuallyHidden } from '../utils/visually-hidden';
@@ -9,16 +8,15 @@ type StyledHelperTextProps = {
};
const StyledHelperText = styled.div`
- font-weight: ${theme.fontWeight.medium};
- line-height: ${theme.lineHeight.lg};
- font-size: ${theme.text.xs};
- color: ${(props) => (props.$hasError ? theme.input.helperText.error.color : theme.colors.textTertiary)};
- padding: ${theme.spacing.spacing1} 0;
+ font-weight: ${({ theme }) => theme.fontWeight('medium')};
+ ${({ theme }) => theme.typography('xs')}
+ color: ${({ $hasError, theme }) => ($hasError ? theme.color('red-500') : theme.color('grey-100'))};
+ padding: ${({ theme }) => theme.spacing('xs')} 0;
${({ $isHidden }) => $isHidden && visuallyHidden()}
`;
const StyledSubHelperText = styled.p`
- line-height: ${theme.lineHeight.s};
+ line-height: ${({ theme }) => theme.lineHeight('s')};
`;
export { StyledHelperText, StyledSubHelperText };
diff --git a/packages/components/src/HelperText/__tests__/HelperText.test.tsx b/packages/components/src/HelperText/__tests__/HelperText.test.tsx
index f684d9582..347f3ba24 100644
--- a/packages/components/src/HelperText/__tests__/HelperText.test.tsx
+++ b/packages/components/src/HelperText/__tests__/HelperText.test.tsx
@@ -1,6 +1,5 @@
-import { render } from '@testing-library/react';
import { createRef } from 'react';
-import { testA11y } from '@interlay/test-utils';
+import { testA11y, render } from '@interlay/test-utils';
import { HelperText } from '..';
diff --git a/packages/components/src/Input/BaseInput.tsx b/packages/components/src/Input/BaseInput.tsx
index d81825f9d..f4370a9e7 100644
--- a/packages/components/src/Input/BaseInput.tsx
+++ b/packages/components/src/Input/BaseInput.tsx
@@ -1,22 +1,13 @@
-import { Sizes, Spacing } from '@interlay/theme';
-import {
- FocusEvent,
- forwardRef,
- InputHTMLAttributes,
- ReactNode,
- TextareaHTMLAttributes,
- useEffect,
- useRef,
- useState
-} from 'react';
+import { Spacing, InputSizes } from '@interlay/theme';
+import { FocusEvent, forwardRef, InputHTMLAttributes, ReactNode, TextareaHTMLAttributes } from 'react';
-import { ElementTypeProp } from '../utils/types';
import { Field, FieldProps, useFieldProps } from '../Field';
import { HelperTextProps } from '../HelperText';
import { LabelProps } from '../Label';
import { hasError } from '../utils/input';
+import { ElementTypeProp } from '../utils/types';
-import { Adornment, StyledBaseInput } from './Input.style';
+import { StyledAdornmentLeft, StyledAdornmentRight, StyledBaseInput } from './Input.style';
// TODO: might need to consolidate this later
interface HTMLInputProps extends ElementTypeProp {
@@ -36,10 +27,9 @@ type Props = {
labelProps?: LabelProps;
startAdornment?: ReactNode;
endAdornment?: ReactNode;
- bottomAdornment?: ReactNode;
value?: string | ReadonlyArray | number;
defaultValue?: string | ReadonlyArray | number;
- size?: Sizes;
+ size?: InputSizes;
isInvalid?: boolean;
minHeight?: Spacing;
onFocus?: (e: FocusEvent) => void;
@@ -51,57 +41,33 @@ type InheritAttrs = Omit<
Pick,
keyof Props
>;
+
type BaseInputProps = Props & InheritAttrs;
const BaseInput = forwardRef(
(
- {
- startAdornment,
- endAdornment,
- bottomAdornment,
- size = 'medium',
- isInvalid,
- inputProps,
- minHeight,
- elementType = 'input',
- ...props
- },
+ { startAdornment, endAdornment, size = 'md', isInvalid, inputProps, minHeight, elementType = 'input', ...props },
ref
): JSX.Element => {
- const endAdornmentRef = useRef(null);
- const [endAdornmentWidth, setEndAdornmentWidth] = useState(0);
-
// FIXME: move this into Field
const { fieldProps } = useFieldProps(props);
- useEffect(() => {
- if (!endAdornmentRef.current || !endAdornment) return;
-
- setEndAdornmentWidth(endAdornmentRef.current.getBoundingClientRect().width);
- }, [endAdornment]);
-
const error = hasError({ isInvalid, errorMessage: props.errorMessage });
return (
- {startAdornment && {startAdornment}}
+ {startAdornment && {startAdornment}}
- {bottomAdornment && {bottomAdornment}}
- {endAdornment && (
-
- {endAdornment}
-
- )}
+ {endAdornment && {endAdornment}}
);
}
diff --git a/packages/components/src/Input/Input.stories.tsx b/packages/components/src/Input/Input.stories.tsx
index 0ac6c7be4..c871d8bf8 100644
--- a/packages/components/src/Input/Input.stories.tsx
+++ b/packages/components/src/Input/Input.stories.tsx
@@ -1,8 +1,7 @@
import { Meta, StoryFn, StoryObj } from '@storybook/react';
-import { useState } from 'react';
import { InformationCircle } from '@interlay/icons';
-import { Flex, Span } from '..';
+import { Flex } from '../Flex';
import { Input, InputProps } from '.';
@@ -19,17 +18,17 @@ export default {
export const Default: StoryObj = {};
-export const Controlled: StoryFn = (args) => {
- const [state, setState] = useState();
+// export const Controlled: StoryFn = (args) => {
+// const [state, setState] = useState();
- return setState(e.target.value)} />;
-};
+// return setState(e.target.value)} />;
+// };
-export const DefaultValue: StoryObj = {
- args: {
- defaultValue: 'Sesame Street'
- }
-};
+// export const DefaultValue: StoryObj = {
+// args: {
+// defaultValue: 'Sesame Street'
+// }
+// };
export const WithDescription: StoryObj = {
args: {
@@ -43,47 +42,44 @@ export const WithErrorMessage: StoryObj = {
}
};
-export const WithMultipleErrorMessage: StoryObj = {
- args: {
- errorMessage: ['Please enter your street address', 'Please enter your street address']
- }
-};
+// export const WithMultipleErrorMessage: StoryObj = {
+// args: {
+// errorMessage: ['Please enter your street address', 'Please enter your street address']
+// }
+// };
-export const SideLabel: StoryObj = {
- args: {
- labelPosition: 'side'
- }
-};
+// export const SideLabel: StoryObj = {
+// args: {
+// labelPosition: 'side'
+// }
+// };
-export const MaxWidth: StoryObj = {
- args: {
- maxWidth: 'spacing28'
- }
-};
+// export const MaxWidth: StoryObj = {
+// args: {
+// maxWidth: 'spacing28'
+// }
+// };
export const Adornments: StoryFn = (args) => (
} />
} label='End Adornment' />
-
- $0.00
-
- }
- label='Bottom Adornment'
- />
);
-export const Sizes: StoryFn = (args) => (
-
-
-
-
-
-);
+// export const Sizes: StoryFn = (args) => (
+//
+//
+//
+//
+//
+// );
+
+export const Placeholder: StoryObj = {
+ args: {
+ placeholder: 'Enter address'
+ }
+};
export const Disabled: StoryObj = {
args: {
diff --git a/packages/components/src/Input/Input.style.tsx b/packages/components/src/Input/Input.style.tsx
index 6976bfcfc..200d7e5b8 100644
--- a/packages/components/src/Input/Input.style.tsx
+++ b/packages/components/src/Input/Input.style.tsx
@@ -1,20 +1,14 @@
-import styled from 'styled-components';
-import { Spacing, theme } from '@interlay/theme';
-import { Placement, Sizes } from '@interlay/theme';
+import { InputSizes, Spacing } from '@interlay/theme';
+import styled, { css } from 'styled-components';
type BaseInputProps = {
- $size: Sizes;
- $adornments: { bottom: boolean; left: boolean; right: boolean };
+ $size: InputSizes;
+ $adornments: { left: boolean; right: boolean };
$isDisabled: boolean;
$hasError: boolean;
- $endAdornmentWidth: number;
$minHeight?: Spacing;
};
-type AdornmentProps = {
- $position: Placement;
-};
-
const StyledBaseInput = styled.input`
display: block;
width: 100%;
@@ -25,58 +19,49 @@ const StyledBaseInput = styled.input`
letter-spacing: inherit;
background: none;
- color: ${(props) => (props.disabled ? theme.input.disabled.color : theme.input.color)};
- font-size: ${({ $size, $adornments }) =>
- $adornments.bottom ? theme.input.overflow.large.text : theme.input[$size].text};
- line-height: ${theme.lineHeight.base};
- font-weight: ${({ $size }) => theme.input[$size].weight};
text-overflow: ellipsis;
- background-color: ${({ $isDisabled }) => ($isDisabled ? theme.input.disabled.bg : theme.input.background)};
- overflow: hidden;
-
- border: ${(props) =>
- props.$isDisabled
- ? theme.input.disabled.border
- : props.$hasError
- ? theme.input.error.border
- : theme.border.default};
- border-radius: ${theme.rounded.lg};
- transition:
- border-color ${theme.transition.duration.duration150}ms ease-in-out,
- box-shadow ${theme.transition.duration.duration150}ms ease-in-out;
-
- padding-top: ${theme.spacing.spacing2};
- padding-left: ${({ $adornments }) => ($adornments.left ? theme.input.paddingX.md : theme.spacing.spacing2)};
+ // Properties for textarea
+ min-height: ${({ $minHeight, theme, as }) =>
+ $minHeight ? theme.spacing($minHeight) : as === 'textarea' && theme.spacing('7xl')};
+ resize: ${({ as }) => as === 'textarea' && 'vertical'};
- padding-right: ${({ $adornments, $endAdornmentWidth }) => {
- if (!$adornments.right) theme.spacing.spacing2;
+ ${({ theme, $size, $adornments, $hasError }) => {
+ const { paddingRight, paddingTop, paddingBottom, paddingLeft, ...sizeCss } = theme.input.size[$size];
// MEMO: adding `spacing6` is a hacky solution because
// the `endAdornmentWidth` does not update width correctly
// after fonts are loaded. Instead of falling back to a more
// complex solution, an extra offset does the job of not allowing
// the input overlap the adornment.
- return `calc(${$endAdornmentWidth}px + ${theme.spacing.spacing6})`;
- }};
- padding-bottom: ${({ $adornments }) => ($adornments.bottom ? theme.spacing.spacing6 : theme.spacing.spacing2)};
+ return css`
+ padding-top: ${paddingTop};
+ padding-bottom: ${paddingBottom};
+ padding-left: ${$adornments.left ? theme.spacing('5xl') : paddingLeft};
+ padding-right: ${$adornments.right ? theme.spacing('5xl') : paddingRight};
- min-height: ${({ $minHeight, as }) =>
- $minHeight ? theme.spacing[$minHeight] : as === 'textarea' && theme.spacing.spacing16};
- resize: ${({ as }) => as === 'textarea' && 'vertical'};
+ ${sizeCss}
+ ${theme.input.base}
+ ${$hasError && theme.input.error.base}
- &:hover:not(:disabled):not(:focus) {
- border: ${(props) => !props.$isDisabled && !props.$hasError && theme.border.focus};
- }
- &:focus {
- border: ${(props) => !props.$isDisabled && theme.border.focus};
- box-shadow: ${(props) => !props.$isDisabled && theme.boxShadow.focus};
- }
+ &:hover:not(:disabled):not(:focus) {
+ ${$hasError ? theme.input.error.hover : theme.input.hover}
+ }
- &::placeholder {
- color: ${(props) => (props.disabled ? theme.input.disabled.color : theme.colors.textTertiary)};
- }
+ &:focus:not(:disabled) {
+ ${$hasError ? theme.input.error.focus : theme.input.focus}
+ }
+
+ &::placeholder {
+ ${theme.input.placeholder}
+ }
+
+ &:disabled {
+ ${theme.input.disabled}
+ }
+ `;
+ }}
/* MEMO: inspired by https://www.w3schools.com/howto/howto_css_hide_arrow_number.asp */
/* Chrome, Safari, Edge, Opera */
@@ -91,26 +76,36 @@ const StyledBaseInput = styled.input`
}
`;
-const BaseInputWrapper = styled.div`
+const StyledWrapper = styled.div`
position: relative;
- color: ${theme.colors.textPrimary};
box-sizing: border-box;
display: flex;
align-items: center;
`;
-// TODO: simplify this (put into theme)
-const Adornment = styled.div`
+type StyledAdornmentProps = {
+ $size: InputSizes;
+};
+
+const StyledAdornment = styled.div`
display: inline-flex;
align-items: center;
position: absolute;
- top: ${({ $position }) => ($position === 'left' || $position === 'right') && '50%'};
- left: ${({ $position }) => ($position === 'left' || $position === 'bottom') && theme.spacing.spacing2};
- right: ${({ $position }) => $position === 'right' && theme.spacing.spacing2};
- transform: ${({ $position }) => ($position === 'left' || $position === 'right') && 'translateY(-50%)'};
- bottom: ${({ $position }) => $position === 'bottom' && theme.spacing.spacing1};
// to not allow adornment to take more than 50% of the input. We might want to reduce this in the future.
max-width: 50%;
+ ${({ theme }) => theme.input.adornment};
+`;
+
+const StyledAdornmentRight = styled(StyledAdornment)`
+ top: 50%;
+ right: ${({ theme }) => theme.spacing('md')};
+ transform: translateY(-50%);
+`;
+
+const StyledAdornmentLeft = styled(StyledAdornment)`
+ top: 50%;
+ left: ${({ theme }) => theme.spacing('md')};
+ transform: translateY(-50%);
`;
const Wrapper = styled.div`
@@ -118,4 +113,4 @@ const Wrapper = styled.div`
flex-direction: column;
`;
-export { Adornment, BaseInputWrapper, StyledBaseInput, Wrapper };
+export { StyledAdornmentLeft, StyledAdornmentRight, StyledBaseInput, StyledWrapper, Wrapper };
diff --git a/packages/components/src/Input/__tests__/Input.test.tsx b/packages/components/src/Input/__tests__/Input.test.tsx
index ed5c601f2..b6b1edbca 100644
--- a/packages/components/src/Input/__tests__/Input.test.tsx
+++ b/packages/components/src/Input/__tests__/Input.test.tsx
@@ -1,5 +1,5 @@
-import { blur, focus, testA11y } from '@interlay/test-utils';
-import { render, screen, waitFor } from '@testing-library/react';
+import { blur, focus, testA11y, render } from '@interlay/test-utils';
+import { screen, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { createRef, useState } from 'react';
diff --git a/packages/components/src/Label/Label.style.tsx b/packages/components/src/Label/Label.style.tsx
index 706ae80dd..6e49e342d 100644
--- a/packages/components/src/Label/Label.style.tsx
+++ b/packages/components/src/Label/Label.style.tsx
@@ -1,19 +1,18 @@
import styled from 'styled-components';
-import { LabelPosition, theme } from '@interlay/theme';
+import { LabelPosition } from '@interlay/theme';
type StyledLabelProps = {
$position: LabelPosition;
};
const StyledLabel = styled.label`
- font-weight: ${theme.fontWeight.medium};
- line-height: ${theme.lineHeight.lg};
- font-size: ${theme.text.xs};
- color: ${theme.label.text};
- padding: ${({ $position }) =>
- $position === 'top'
- ? `${theme.spacing.spacing1} 0`
- : `${theme.spacing.spacing2} ${theme.spacing.spacing1} 0.438rem 0`};
+ ${({ theme }) => theme.typography('xs')}
+ color: ${({ theme }) => theme.color('light')};
+ font-weight: ${({ theme }) => theme.fontWeight('medium')};
+
+ // FIXME: padding bottom when position is on side
+ padding: ${({ theme, $position }) =>
+ $position === 'top' ? `${theme.spacing('xs')} 0` : `${theme.spacing('s')} ${theme.spacing('xs')} 0.625rem 0`};
align-self: flex-start;
`;
diff --git a/packages/components/src/Label/Label.tsx b/packages/components/src/Label/Label.tsx
index d7bf4e9a0..a2c0cbdfa 100644
--- a/packages/components/src/Label/Label.tsx
+++ b/packages/components/src/Label/Label.tsx
@@ -13,7 +13,7 @@ type LabelProps = Props & NativeAttrs;
const Label = forwardRef(
({ children, position = 'top', ...props }, ref): JSX.Element => (
-
+
{children}
)
diff --git a/packages/components/src/Label/__tests__/Label.test.tsx b/packages/components/src/Label/__tests__/Label.test.tsx
index 9ea9db6eb..5605fd4dc 100644
--- a/packages/components/src/Label/__tests__/Label.test.tsx
+++ b/packages/components/src/Label/__tests__/Label.test.tsx
@@ -1,6 +1,5 @@
-import { render } from '@testing-library/react';
import { createRef } from 'react';
-import { testA11y } from '@interlay/test-utils';
+import { testA11y, render } from '@interlay/test-utils';
import { Label } from '..';
diff --git a/packages/components/src/List/List.stories.tsx b/packages/components/src/List/List.stories.tsx
index 127893a25..f71effb3f 100644
--- a/packages/components/src/List/List.stories.tsx
+++ b/packages/components/src/List/List.stories.tsx
@@ -28,18 +28,6 @@ export default {
export const Default: StoryObj = {};
-export const Secondary: StoryObj = {
- args: {
- variant: 'secondary'
- }
-};
-
-export const Card: StoryObj = {
- args: {
- variant: 'card'
- }
-};
-
export const Horizontal: StoryObj = {
args: {
direction: 'row'
diff --git a/packages/components/src/List/List.style.tsx b/packages/components/src/List/List.style.tsx
index 49e6892a5..b0381a6ac 100644
--- a/packages/components/src/List/List.style.tsx
+++ b/packages/components/src/List/List.style.tsx
@@ -1,22 +1,16 @@
-import styled, { css } from 'styled-components';
-import { theme } from '@interlay/theme';
-import { ListVariants } from '@interlay/theme';
+import styled, { CSSProperties, css } from 'styled-components';
import { Flex } from '../Flex';
type StyledListProps = {
- $variant: ListVariants;
+ $maxHeight?: CSSProperties['maxHeight'];
};
const StyledList = styled(Flex)`
- background-color: ${({ $variant }) => theme.list?.[$variant]?.bg};
- border-radius: ${({ $variant }) => theme.list[$variant].rounded};
- border: ${({ $variant }) => theme.list[$variant].border};
- overflow: hidden;
+ max-height: ${({ $maxHeight }) => $maxHeight};
`;
type StyledListItemProps = {
- $variant: ListVariants;
$isDisabled: boolean;
$isHovered: boolean;
$isInteractable: boolean;
@@ -26,31 +20,18 @@ type StyledListItemProps = {
const StyledListItem = styled.div`
flex: 1;
align-self: stretch;
- padding: ${theme.spacing.spacing3};
- border-radius: ${({ $variant }) => theme.list.item[$variant].rounded};
- background-color: ${({ $variant, $isHovered, $isFocusVisible }) =>
- $isHovered || $isFocusVisible ? theme.list.item[$variant].hover.bg : theme.list.item[$variant].bg};
- border: ${({ $variant }) => $variant !== 'card' && theme.list.item[$variant].border};
- color: ${theme.colors.textPrimary};
cursor: ${({ $isInteractable }) => $isInteractable && 'pointer'};
outline: ${({ $isFocusVisible }) => !$isFocusVisible && 'none'};
opacity: ${({ $isDisabled }) => $isDisabled && 0.5};
white-space: nowrap;
- ${({ $variant }) => {
- if ($variant === 'card') {
- return css`
- &:not(:first-of-type) {
- border-top: ${theme.list.item.card.border};
- }
- `;
- }
-
+ ${({ theme, $isHovered }) => {
return css`
+ ${theme.list.item.base}
+ ${$isHovered && theme.list.item.hover}
+
&[aria-selected='true'] {
- background-color: ${theme.list.item[$variant].selected.bg};
- color: ${theme.list.text};
- border-color: ${theme.list.item[$variant].selected.bg};
+ ${theme.list.item.selected};
}
`;
}}
diff --git a/packages/components/src/List/List.tsx b/packages/components/src/List/List.tsx
index be30d5d3e..c471d6d82 100644
--- a/packages/components/src/List/List.tsx
+++ b/packages/components/src/List/List.tsx
@@ -2,9 +2,9 @@ import { AriaGridListOptions, useGridList } from '@react-aria/gridlist';
import { mergeProps } from '@react-aria/utils';
import { ListProps as StatelyListProps, useListState } from '@react-stately/list';
import { forwardRef } from 'react';
-import { ListVariants } from '@interlay/theme';
import { Selection } from '@react-types/shared';
import { useDOMRef } from '@interlay/hooks';
+import { CSSProperties } from 'styled-components';
import { FlexProps } from '../Flex';
@@ -12,7 +12,7 @@ import { StyledList } from './List.style';
import { ListItem } from './ListItem';
type Props = {
- variant?: ListVariants;
+ maxHeight?: CSSProperties['maxHeight'];
};
type InheritAttrs = Omit<
@@ -27,7 +27,19 @@ type ListProps = Props & NativeAttrs & InheritAttrs;
// FIXME: use keyboardDelegate for horizontal list (see TagGroup from spectrum)
const List = forwardRef(
(
- { variant = 'primary', direction = 'column', onSelectionChange, selectionMode, selectedKeys, ...props },
+ {
+ maxHeight,
+ direction = 'column',
+ onSelectionChange,
+ selectionMode,
+ selectedKeys,
+ disabledBehavior,
+ disabledKeys,
+ disallowEmptySelection,
+ defaultSelectedKeys,
+ selectionBehavior,
+ ...props
+ },
ref
): JSX.Element => {
const listRef = useDOMRef(ref);
@@ -36,22 +48,20 @@ const List = forwardRef(
onSelectionChange,
selectionMode,
selectedKeys,
+ disabledBehavior,
+ defaultSelectedKeys,
+ disabledKeys,
+ disallowEmptySelection,
...props
};
- const state = useListState(ariaProps);
+ const state = useListState({ selectionBehavior, ...ariaProps });
const { gridProps } = useGridList(ariaProps, state, listRef);
return (
-
+
{[...state.collection].map((item) => (
-
+
))}
);
diff --git a/packages/components/src/List/ListItem.tsx b/packages/components/src/List/ListItem.tsx
index 46cd298d7..d7931ade3 100644
--- a/packages/components/src/List/ListItem.tsx
+++ b/packages/components/src/List/ListItem.tsx
@@ -6,15 +6,12 @@ import { mergeProps } from '@react-aria/utils';
import { ListState } from '@react-stately/list';
import { Node } from '@react-types/shared';
import { useMemo, useRef } from 'react';
-import { ListVariants } from '@interlay/theme';
import { Flex, FlexProps } from '../Flex';
import { StyledListItem } from './List.style';
-type Props = {
- variant?: ListVariants;
-};
+type Props = {};
type InheritAttrs = Omit;
@@ -22,7 +19,7 @@ type ListItemProps = Props & InheritAttrs;
type InternalProps = ListItemProps & { item: Node; state: ListState };
-const ListItem = ({ item, state, variant = 'primary' }: InternalProps): JSX.Element => {
+const ListItem = ({ item, state }: InternalProps): JSX.Element => {
const ref = useRef(null);
const { rowProps, gridCellProps, isDisabled } = useGridListItem({ node: item }, state, ref);
@@ -44,7 +41,6 @@ const ListItem = ({ item, state, variant = 'primary' }: Intern
$isFocusVisible={isFocusVisible}
$isHovered={isHovered}
$isInteractable={isInteractable}
- $variant={variant}
>
{item.rendered}
diff --git a/packages/components/src/List/__tests__/List.test.tsx b/packages/components/src/List/__tests__/List.test.tsx
index e1b553297..3eb79047b 100644
--- a/packages/components/src/List/__tests__/List.test.tsx
+++ b/packages/components/src/List/__tests__/List.test.tsx
@@ -1,6 +1,5 @@
-import { render } from '@testing-library/react';
import { createRef } from 'react';
-import { testA11y } from '@interlay/test-utils';
+import { testA11y, render } from '@interlay/test-utils';
import { List, ListItem } from '..';
diff --git a/packages/components/src/Meter/Meter.stories.tsx b/packages/components/src/Meter/Meter.stories.tsx
index 9e81dc520..75bc8ef69 100644
--- a/packages/components/src/Meter/Meter.stories.tsx
+++ b/packages/components/src/Meter/Meter.stories.tsx
@@ -10,8 +10,8 @@ const Render = (args: MeterProps) => {
const [error, setError] = useState(80);
return (
-
-
+
+
diff --git a/packages/components/src/Meter/__tests__/Meter.test.tsx b/packages/components/src/Meter/__tests__/Meter.test.tsx
index 9d211f3ed..ee83fdb23 100644
--- a/packages/components/src/Meter/__tests__/Meter.test.tsx
+++ b/packages/components/src/Meter/__tests__/Meter.test.tsx
@@ -1,5 +1,4 @@
-import { render } from '@testing-library/react';
-import { testA11y } from '@interlay/test-utils';
+import { testA11y, render } from '@interlay/test-utils';
import { Meter } from '..';
diff --git a/packages/components/src/Modal/Modal.stories.tsx b/packages/components/src/Modal/Modal.stories.tsx
index 758b77220..b29b55501 100644
--- a/packages/components/src/Modal/Modal.stories.tsx
+++ b/packages/components/src/Modal/Modal.stories.tsx
@@ -1,7 +1,7 @@
import { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react';
-import { CTA } from '../CTA';
+import { Button } from '../Button';
import { Modal, ModalProps } from './Modal';
import { ModalHeader } from './ModalHeader';
@@ -15,19 +15,17 @@ const Render = ({ title, footer, children, ...args }: StoryProps) => {
return (
<>
- setState(true)}>Open Modal
+
setState(false)}>
{title && (
<>
-
- {title}
-
+ {title}
>
)}
{children}
{footer && (
- Procced
+
)}
@@ -85,11 +83,132 @@ export const BodyWithFooter: StoryObj = {
}
};
-export const LargeContent: StoryObj = {
+export const ScrollBehaviour: StoryObj = {
args: {
title: 'Title',
footer: true,
- hasMaxHeight: true,
+ children: (
+ <>
+ Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam.
+ Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque
+ nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras
+ mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi
+ leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
+ consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
+ egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna,
+ vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
+ ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent
+ commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum.
+ Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
+ vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur
+ purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
+ consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
+ >
+ )
+ }
+};
+
+export const MaxHeight: StoryObj = {
+ args: {
+ title: 'Title',
+ footer: true,
+ maxHeight: '400px',
children: (
<>
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam.
diff --git a/packages/components/src/Modal/Modal.style.tsx b/packages/components/src/Modal/Modal.style.tsx
index 4ee89c6e3..86e658221 100644
--- a/packages/components/src/Modal/Modal.style.tsx
+++ b/packages/components/src/Modal/Modal.style.tsx
@@ -1,46 +1,44 @@
-import styled from 'styled-components';
+import styled, { CSSProperties } from 'styled-components';
+import { DialogSize } from '@interlay/theme';
-import { theme } from '../../../core/theme/src';
-import { Overflow } from '../../../core/theme/src';
import { overlayCSS } from '../utils/overlay';
import { Dialog, DialogBody } from '../Dialog';
+type StyledWrapperProps = {
+ $placement: 'top' | 'center';
+};
+
type StyledModalProps = {
$isOpen?: boolean;
- $isCentered?: boolean;
+ $size: DialogSize;
+ $maxHeight?: CSSProperties['maxHeight'];
};
type StyledDialogProps = {
- $isCentered?: boolean;
- $hasMaxHeight?: boolean;
$isOpen?: boolean;
};
type StyledModalBodyProps = {
- $overflow?: Overflow;
$noPadding?: boolean;
};
-const StyledWrapper = styled.div`
+const StyledWrapper = styled.div`
position: fixed;
top: 0;
left: 0;
- z-index: ${theme.modal.zIndex};
+ z-index: 2;
width: 100vw;
- height: 100vh;
+ height: 100dvh;
visibility: visible;
display: flex;
justify-content: center;
- align-items: ${({ $isCentered }) => ($isCentered ? 'center' : 'flex-start')};
- overflow: ${({ $isCentered }) => !$isCentered && 'auto'};
+ align-items: ${({ $placement }) => ($placement === 'center' ? 'center' : 'flex-start')};
`;
+//FIXME: on very small screen (height) the modal could overflow when max-heigh is set
+// might not need the max-heigh property
const StyledModal = styled.div`
- max-width: calc(100% - ${theme.spacing.spacing12});
- max-height: ${({ $isCentered }) => $isCentered && theme.modal.maxHeight};
- margin: ${({ $isCentered }) => ($isCentered ? 0 : theme.spacing.spacing16)} ${theme.spacing.spacing6};
-
transform: ${({ $isOpen }) => ($isOpen ? 'translateY(0)' : `translateY(20px)`)};
${({ $isOpen }) => overlayCSS(!!$isOpen)}
// Overrides overlayCSS properties, because react-aria Overlay
@@ -49,19 +47,25 @@ const StyledModal = styled.div`
visibility: visible;
// Allows scroll on the modal
pointer-events: auto;
- transition: ${({ $isOpen }) => ($isOpen ? theme.modal.transition.entering : theme.modal.transition.exiting)};
+ transition: ${({ $isOpen }) =>
+ $isOpen
+ ? 'transform .15s cubic-bezier(0,0,0.4,1) .1s, opacity .15s cubic-bezier(0,0,0.4,1)'
+ : 'opacity .1s cubic-bezier(0.5,0,1,1), visibility 0s linear, transform 0s linear .1s'};
outline: none;
+ margin: ${({ theme }) => `${theme.spacing('7xl')} ${theme.spacing('xl')}`};
+ max-width: ${({ theme, $size }) => theme.dialog.size[$size].maxWidth};
+ width: 100%;
+ max-height: ${({ theme, $maxHeight }) => $maxHeight || `calc(100dvh - ${theme.spacing('10xl')})`};
`;
const StyledDialog = styled(Dialog)`
- max-height: ${({ $hasMaxHeight }) => $hasMaxHeight && '560px'};
- overflow: ${({ $isCentered }) => $isCentered && 'hidden'};
pointer-events: ${({ $isOpen }) => !$isOpen && 'none'};
+ max-height: inherit;
`;
const StyledDialogBody = styled(DialogBody)`
- overflow-y: ${({ $overflow }) => $overflow};
+ overflow-y: auto;
position: relative;
padding: ${({ $noPadding }) => $noPadding && 0};
`;
diff --git a/packages/components/src/Modal/Modal.tsx b/packages/components/src/Modal/Modal.tsx
index a38cc1f6f..375e1b77c 100644
--- a/packages/components/src/Modal/Modal.tsx
+++ b/packages/components/src/Modal/Modal.tsx
@@ -1,11 +1,12 @@
import { forwardRef, useRef } from 'react';
import { useDOMRef } from '@interlay/hooks';
+import { DialogSize } from '@interlay/theme';
+import { CSSProperties } from 'styled-components';
import { DialogProps } from '../Dialog';
import { Overlay } from '../Overlay';
import { StyledDialog } from './Modal.style';
-import { ModalContext } from './ModalContext';
import { ModalWrapper, ModalWrapperProps } from './ModalWrapper';
const isInteractingWithToasts = (element: Element) => {
@@ -16,13 +17,16 @@ const isInteractingWithToasts = (element: Element) => {
return toastsContainer.contains(element);
};
+type ModalSizes = DialogSize;
+
type Props = {
container?: Element;
- hasMaxHeight?: boolean;
- align?: 'top' | 'center';
+ placement?: 'top' | 'center';
+ size?: ModalSizes;
+ maxHeight?: CSSProperties['maxHeight'];
};
-type InheritAttrs = Omit;
+type InheritAttrs = Omit;
type ModalProps = Props & InheritAttrs;
@@ -31,13 +35,14 @@ const Modal = forwardRef(
{
children,
isDismissable = true,
- align = 'center',
- hasMaxHeight,
+ placement = 'center',
isKeyboardDismissDisabled,
shouldCloseOnBlur,
shouldCloseOnInteractOutside,
container,
isOpen,
+ size = 'md',
+ maxHeight,
...props
},
ref
@@ -46,8 +51,6 @@ const Modal = forwardRef(
const { onClose } = props;
const wrapperRef = useRef(null);
- const isCentered = align === 'center';
-
// Does not allow the modal to close when clicking on toasts
const handleShouldCloseOnInteractOutside = (element: Element) =>
shouldCloseOnInteractOutside
@@ -55,25 +58,25 @@ const Modal = forwardRef(
: !isInteractingWithToasts(element);
return (
-
-
-
-
- {children}
-
-
-
-
+
+
+
+ {children}
+
+
+
);
}
);
diff --git a/packages/components/src/Modal/ModalBody.tsx b/packages/components/src/Modal/ModalBody.tsx
index 17ce166e8..895539df5 100644
--- a/packages/components/src/Modal/ModalBody.tsx
+++ b/packages/components/src/Modal/ModalBody.tsx
@@ -1,11 +1,8 @@
-import { Overflow } from '../../../core/theme/src';
import { DialogBodyProps } from '../Dialog';
import { StyledDialogBody } from './Modal.style';
-import { useModalContext } from './ModalContext';
type Props = {
- overflow?: Overflow;
noPadding?: boolean;
};
@@ -13,11 +10,9 @@ type InheritAttrs = Omit;
type ModalBodyProps = Props & InheritAttrs;
-const ModalBody = ({ overflow, noPadding, ...props }: ModalBodyProps): JSX.Element => {
- const { bodyProps } = useModalContext();
-
- return ;
-};
+const ModalBody = ({ noPadding, ...props }: ModalBodyProps): JSX.Element => (
+
+);
export { ModalBody };
export type { ModalBodyProps };
diff --git a/packages/components/src/Modal/ModalContext.tsx b/packages/components/src/Modal/ModalContext.tsx
deleted file mode 100644
index 42353cbe0..000000000
--- a/packages/components/src/Modal/ModalContext.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react';
-
-import { ModalBodyProps } from './ModalBody';
-
-interface ModalConfig {
- bodyProps?: ModalBodyProps;
-}
-
-const defaultContext = {};
-
-const ModalContext = React.createContext(defaultContext);
-
-const useModalContext = (): ModalConfig => React.useContext(ModalContext);
-
-export { ModalContext, useModalContext };
-export type { ModalConfig };
diff --git a/packages/components/src/Modal/ModalDivider.tsx b/packages/components/src/Modal/ModalDivider.tsx
deleted file mode 100644
index 1e9630a48..000000000
--- a/packages/components/src/Modal/ModalDivider.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { DialogDivider, DialogDividerProps } from '../Dialog';
-
-type ModalDividerProps = DialogDividerProps;
-
-const ModalDivider = (props: ModalDividerProps): JSX.Element => ;
-
-export { ModalDivider };
-export type { ModalDividerProps };
diff --git a/packages/components/src/Modal/ModalFooter.tsx b/packages/components/src/Modal/ModalFooter.tsx
index 655a8d5d2..0564102ad 100644
--- a/packages/components/src/Modal/ModalFooter.tsx
+++ b/packages/components/src/Modal/ModalFooter.tsx
@@ -2,7 +2,7 @@ import { DialogFooter, DialogFooterProps } from '../Dialog';
type ModalFooterProps = DialogFooterProps;
-const ModalFooter = ({ direction = 'column', gap = 'spacing4', ...props }: ModalFooterProps): JSX.Element => (
+const ModalFooter = ({ direction = 'column', gap = 's', ...props }: ModalFooterProps): JSX.Element => (
);
diff --git a/packages/components/src/Modal/ModalHeader.tsx b/packages/components/src/Modal/ModalHeader.tsx
index decf2059e..abb4bce5e 100644
--- a/packages/components/src/Modal/ModalHeader.tsx
+++ b/packages/components/src/Modal/ModalHeader.tsx
@@ -2,8 +2,8 @@ import { DialogHeader, DialogHeaderProps } from '../Dialog';
type ModalHeaderProps = DialogHeaderProps;
-const ModalHeader = ({ align = 'center', children, ...props }: ModalHeaderProps): JSX.Element => (
-
+const ModalHeader = ({ align = 'start', weight = 'semibold', children, ...props }: ModalHeaderProps): JSX.Element => (
+
{children}
);
diff --git a/packages/components/src/Modal/ModalWrapper.tsx b/packages/components/src/Modal/ModalWrapper.tsx
index 578e93fc2..90a97c3fc 100644
--- a/packages/components/src/Modal/ModalWrapper.tsx
+++ b/packages/components/src/Modal/ModalWrapper.tsx
@@ -2,6 +2,8 @@ import { AriaModalOverlayProps, AriaOverlayProps, useModalOverlay } from '@react
import { mergeProps } from '@react-aria/utils';
import { OverlayTriggerState } from '@react-stately/overlays';
import { forwardRef, ReactNode, RefObject } from 'react';
+import { DialogSize } from '@interlay/theme';
+import { CSSProperties } from 'styled-components';
import { Underlay } from '../Overlay/Underlay';
@@ -9,10 +11,12 @@ import { StyledModal, StyledWrapper } from './Modal.style';
type Props = {
children: ReactNode;
- align?: 'top' | 'center';
+ placement?: 'top' | 'center';
isOpen?: boolean;
onClose: () => void;
wrapperRef: RefObject;
+ size: DialogSize;
+ maxHeight?: CSSProperties['maxHeight'];
};
type InheritAttrs = Omit;
@@ -24,13 +28,15 @@ const ModalWrapper = forwardRef(
{
children,
isDismissable = true,
- align = 'center',
+ placement = 'center',
onClose,
isKeyboardDismissDisabled,
isOpen,
shouldCloseOnInteractOutside,
shouldCloseOnBlur,
wrapperRef,
+ size,
+ maxHeight,
...props
},
ref
@@ -50,13 +56,17 @@ const ModalWrapper = forwardRef(
ref as RefObject
);
- const isCentered = align === 'center';
-
return (