Skip to content

Commit

Permalink
Merge pull request #82 from ynput/develop
Browse files Browse the repository at this point in the history
release 1.0.2
  • Loading branch information
martastain authored May 2, 2024
2 parents 4033f5f + 6ef4791 commit 9fe706e
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 128 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ynput/ayon-react-components",
"private": false,
"version": "1.0.1",
"version": "0.0.0-dev",
"type": "module",
"repository": {
"type": "git",
Expand Down
10 changes: 10 additions & 0 deletions src/Dropdowns/Dropdown/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ export const Basic: Story = {
render: Template,
}

// Portal that creates dropdown outside of standard DOM instead inside parent
export const PortalSwitch: Story = {
args: {
isPortal: true
},
render: Template,
}


// simple dropdown with three items
export const Tags: Story = {
render: Template,
Expand Down Expand Up @@ -211,6 +220,7 @@ export const InvalidValue: Story = {
render: Template,
}


// outside state synced to dropdown state
export const SyncedState: Story = {
args: {},
Expand Down
194 changes: 99 additions & 95 deletions src/Dropdowns/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface DropdownProps extends Omit<React.HTMLAttributes<HTMLDivElement>
disabledValues?: (string | number)[]
listInline?: boolean
disableOpen?: boolean
isPortal?: boolean
}

export interface DropdownRef {
Expand Down Expand Up @@ -151,6 +152,7 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(
disabledValues = [],
listInline = false,
disableOpen = false,
isPortal = true,
...props
},
ref,
Expand Down Expand Up @@ -659,8 +661,103 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(
close: () => setIsOpen(false),
}),
[elementRef, valueRef, optionsRef, searchRef],

)
const StyledContainer = () => (
<Styled.Container
style={{
opacity: isShowOptions ? 1 : 0,
left: pos?.left || 'unset',
right: pos?.right || 'unset',
top: pos?.y || 'unset',
translate: offScreen ? '0 -100%' : 'none',
transformOrigin: offScreen ? 'center bottom' : 'center top',
...itemStyle,
}}
$message={message || ''}
$isOpen={true}
$hidden={!isShowOptions}
onSubmit={handleSearchSubmit}
ref={formRef}
>
{(search || editable) && (
<Styled.Search className="search">
<Icon icon={'search'} />
<InputText
value={searchForm}
onChange={(e) => setSearchForm(e.target.value)}
autoFocus
tabIndex={0}
ref={searchRef}
onKeyDown={(e) => e.code === 'Enter' && e.preventDefault()}
/>
</Styled.Search>
)}
<Styled.Scrollable
style={{ maxHeight }}
$message={message || ''}
$search={!!search || !!editable}
defer
>
<Styled.Options
style={{ minWidth, ...listStyle }}
className={'options'}
ref={optionsRef}
>
{showOptions.map((option, i) => (
<Styled.ListItem
key={`${option[dataKey]}-${i}`}
onClick={(e) =>
!disabledValues.includes(option[dataKey]) &&
handleChange(option[dataKey], i, e)
}
$focused={usingKeyboard && activeIndex === i}
$usingKeyboard={usingKeyboard}
tabIndex={0}
className={`option ${listClassName}`}
$disabled={disabledValues.includes(option[dataKey])}
>
{itemTemplate ? (
itemTemplate(
option,
!!value && value.includes(option[dataKey]),
!!selected?.includes(option[dataKey]),
i,
)
) : (
<Styled.DefaultItem
$isSelected={!!selected?.includes(option[dataKey])}
className={`option-child ${
value && value.includes(option[dataKey]) ? 'selected' : ''
} ${
value && value.includes(option[dataKey]) ? 'active' : ''
} ${itemClassName}`}
style={itemStyle}
>
{option.icon && <Icon icon={option.icon} />}
<span>{option[labelKey] || option[dataKey]}</span>
</Styled.DefaultItem>
)}
</Styled.ListItem>
))}
{!!hiddenLength && (
<Styled.ListItem
onClick={handleShowMore}
$focused={false}
$usingKeyboard={false}
className="option"
>
<Styled.DefaultItem $isSelected={false} className="option-child hidden">
<span>{`Show ${50} more...`}</span>
</Styled.DefaultItem>
</Styled.ListItem>
)}
</Styled.Options>
</Styled.Scrollable>
</Styled.Container>
)


const isShowOptions = isOpen && options && (pos.y || pos.y === 0) && (!widthExpand || minWidth)
return (
<Styled.Dropdown
Expand Down Expand Up @@ -693,101 +790,8 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(
)}
</Styled.Button>

{isOpen &&
createPortal(
<Styled.Container
style={{
opacity: isShowOptions ? 1 : 0,
left: pos?.left || 'unset',
right: pos?.right || 'unset',
top: pos?.y || 'unset',
translate: offScreen ? '0 -100%' : 'none',
transformOrigin: offScreen ? 'center bottom' : 'center top',
...itemStyle,
}}
$message={message || ''}
$isOpen={true}
$hidden={!isShowOptions}
onSubmit={handleSearchSubmit}
ref={formRef}
>
{(search || editable) && (
<Styled.Search className="search">
<Icon icon={'search'} />
<InputText
value={searchForm}
onChange={(e) => setSearchForm(e.target.value)}
autoFocus
tabIndex={0}
ref={searchRef}
onKeyDown={(e) => e.code === 'Enter' && e.preventDefault()}
/>
</Styled.Search>
)}
<Styled.Scrollable
style={{ maxHeight }}
$message={message || ''}
$search={!!search || !!editable}
defer
>
<Styled.Options
style={{ minWidth, ...listStyle }}
className={'options'}
ref={optionsRef}
>
{showOptions.map((option, i) => (
<Styled.ListItem
key={`${option[dataKey]}-${i}`}
onClick={(e) =>
!disabledValues.includes(option[dataKey]) &&
handleChange(option[dataKey], i, e)
}
$focused={usingKeyboard && activeIndex === i}
$usingKeyboard={usingKeyboard}
tabIndex={0}
className={`option ${listClassName}`}
$disabled={disabledValues.includes(option[dataKey])}
>
{itemTemplate ? (
itemTemplate(
option,
!!value && value.includes(option[dataKey]),
!!selected?.includes(option[dataKey]),
i,
)
) : (
<Styled.DefaultItem
$isSelected={!!selected?.includes(option[dataKey])}
className={`option-child ${
value && value.includes(option[dataKey]) ? 'selected' : ''
} ${
value && value.includes(option[dataKey]) ? 'active' : ''
} ${itemClassName}`}
style={itemStyle}
>
{option.icon && <Icon icon={option.icon} />}
<span>{option[labelKey] || option[dataKey]}</span>
</Styled.DefaultItem>
)}
</Styled.ListItem>
))}
{!!hiddenLength && (
<Styled.ListItem
onClick={handleShowMore}
$focused={false}
$usingKeyboard={false}
className="option"
>
<Styled.DefaultItem $isSelected={false} className="option-child hidden">
<span>{`Show ${50} more...`}</span>
</Styled.DefaultItem>
</Styled.ListItem>
)}
</Styled.Options>
</Styled.Scrollable>
</Styled.Container>,
document.body,
)}
{ isOpen && isPortal && createPortal(<StyledContainer />, document.body, )}
{ isOpen && !isPortal && <StyledContainer />}
</Styled.Dropdown>
)
},
Expand Down
5 changes: 1 addition & 4 deletions src/Overlay/Dialog/Dialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const closeProps = {
label: 'Close'
}



const Template = () => {

const [openModal, setOpenModal] = useState(false)
Expand All @@ -48,12 +46,11 @@ const Template = () => {
<Dialog
header={<HeaderContent/>}
children={<BodyContent />}
// footer={<FooterContent />}
footer={<FooterContent />}
isOpen={openModal}
onClose={handleCloseModal}
closeProps={closeProps}
hideCancelButton={false}
// classNames={{header: 'alert'}}
size='full'
/>
</>
Expand Down
11 changes: 8 additions & 3 deletions src/Overlay/Dialog/Dialog.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ export const Dialog = styled.dialog<{ $size?: string }>`

export const Close = styled(Button)`
position: absolute;
top: 8px;
right: 8px;
top: 50%;
transform: translateY(-50%);
`

export const BaseDialogEdge = styled.div`
Expand All @@ -78,18 +79,22 @@ export const BaseDialogEdge = styled.div`
`


export const Header = styled(BaseDialogEdge)`
export const Header = styled(BaseDialogEdge)<{ hideCancelButton?: boolean }>`
position: relative;
display: flex;
flex-direction: column;
padding: 16px;
${({ hideCancelButton }) => !hideCancelButton && css`padding-right: 32px;`}
${titleLarge}
& > * {
${titleLarge}
}
`

export const Footer = styled(BaseDialogEdge)`
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
align-items: center;
padding: 16px;
`
export const Body = styled.div`
Expand Down
42 changes: 17 additions & 25 deletions src/Overlay/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,27 @@ export const Dialog = forwardRef<HTMLDialogElement, DialogProps>((props) => {
className={clsx('modal', className)}
{...props}
>
{hideCancelButton ? null : (
<Styled.Close
className={classNames ? 'cancelButton' + ' ' + classNames.cancelButton : 'cancelButton'}
icon="close"
variant="text"
autoFocus
onClick={handleCloseModal}
/>
)}
<Styled.Header className={classNames ? 'header' + ' ' + classNames.header : 'header'}>
{header ? header : ''}
<Styled.Header className={clsx('header', classNames?.header)}>
{header ? header : ''}
{hideCancelButton ? null : (
<Styled.Close
className={clsx('cancelButton', classNames?.cancelButton)}
icon="close"
variant="text"
autoFocus
onClick={handleCloseModal}
/> )}
</Styled.Header>
{children && (
<Styled.Body className={classNames ? 'body' + ' ' + classNames.body : 'body'}>
{children}
</Styled.Body>
)}
<Styled.Footer>
{footer ? (
footer
) : (
{children && <Styled.Body className={clsx('body', classNames?.body)}>{children}</Styled.Body>}
<Styled.Footer className={clsx('footer', classNames?.footer)}>
{ footer && footer }
<Button
className={classNames ? 'closeButton' + ' ' + classNames.closeButton : 'closeButton'}
{...closeProps}
label={!!closeProps?.label ? closeProps.label : 'Cancel'}
className={clsx('closeButton', classNames?.closeButton)}
variant="text"
onClick={handleCloseModal}
{...closeProps}
/>
)}
</Styled.Footer>
</Styled.Dialog>
)
})
)})

0 comments on commit 9fe706e

Please sign in to comment.