mirror of https://github.com/acid-info/lsd.git
Merge branch 'batch-1' into topic-implement-tabs
This commit is contained in:
commit
58b3bbd89f
|
@ -20,7 +20,8 @@
|
|||
"clsx": "^1.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react-use": "^17.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-runtime": "^7.19.6",
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
import { Global, SerializedStyles } from '@emotion/react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { ButtonStyles } from '../Button/Button.styles'
|
||||
import { DropdownStyles } from '../Dropdown/Dropdown.styles'
|
||||
import { DropdownItemStyles } from '../DropdownItem/DropdownItem.styles'
|
||||
import { LsdIconStyles } from '../Icons/LsdIcon/LsdIcon.styles'
|
||||
import { ListBoxStyles } from '../ListBox/ListBox.styles'
|
||||
import { TabItemStyles } from '../TabItem/TabItem.styles'
|
||||
import { TabsStyles } from '../Tabs/Tabs.styles'
|
||||
import { defaultThemes, Theme, withTheme } from '../Theme'
|
||||
import { TypographyStyles } from '../Typography/Typography.styles'
|
||||
|
||||
const componentStyles: Array<ReturnType<typeof withTheme> | SerializedStyles> =
|
||||
[ButtonStyles, TypographyStyles, LsdIconStyles, TabItemStyles, TabsStyles]
|
||||
[
|
||||
ButtonStyles,
|
||||
TypographyStyles,
|
||||
LsdIconStyles,
|
||||
TabItemStyles,
|
||||
TabsStyles,
|
||||
ListBoxStyles,
|
||||
DropdownStyles,
|
||||
DropdownItemStyles,
|
||||
]
|
||||
|
||||
export const CSSBaseline: React.FC<{ theme?: Theme }> = ({
|
||||
theme = defaultThemes.light,
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
export const dropdownClasses = {
|
||||
root: `lsd-dropdown`,
|
||||
|
||||
trigger: `lsd-dropdown-trigger`,
|
||||
triggerLabel: `lsd-dropdown-trigger__label`,
|
||||
triggerIcons: `lsd-dropdown-trigger-icons`,
|
||||
triggerIcon: `lsd-dropdown-trigger-icons__icon`,
|
||||
triggerMenuIcon: `lsd-dropdown-trigger-icons__menu-icon`,
|
||||
|
||||
supportingText: 'lsd-dropdown__supporting-text',
|
||||
|
||||
listBox: 'lsd-dropdown-list-box',
|
||||
|
||||
open: 'lsd-dropdown--open',
|
||||
error: 'lsd-dropdown--error',
|
||||
disabled: 'lsd-dropdown--disabled',
|
||||
small: `lsd-dropdown--small`,
|
||||
medium: `lsd-dropdown--medium`,
|
||||
large: `lsd-dropdown--large`,
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { Meta, Story } from '@storybook/react'
|
||||
import { Dropdown, DropdownProps } from './Dropdown'
|
||||
|
||||
export default {
|
||||
title: 'Dropdown',
|
||||
component: Dropdown,
|
||||
} as Meta
|
||||
|
||||
export const Root: Story<DropdownProps> = (args) => (
|
||||
<div style={{ width: 300 }}>
|
||||
<Dropdown {...args}></Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
||||
Root.args = {
|
||||
size: 'large',
|
||||
label: 'Choose an option',
|
||||
supportingText: '',
|
||||
disabled: false,
|
||||
error: false,
|
||||
multi: false,
|
||||
onChange: undefined,
|
||||
options: new Array(16).fill(null).map((value, index) => ({
|
||||
value: `${index}`,
|
||||
name: `Option ${index + 1}`,
|
||||
})),
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
import { css } from '@emotion/react'
|
||||
import { dropdownItemClasses } from '../DropdownItem/DropdownItem.classes'
|
||||
import { dropdownClasses } from './Dropdown.classes'
|
||||
|
||||
export const DropdownStyles = css`
|
||||
.${dropdownClasses.root} {
|
||||
}
|
||||
|
||||
.${dropdownClasses.root}:not(.${dropdownClasses.disabled}):not(
|
||||
.${dropdownClasses.error}
|
||||
) {
|
||||
.${dropdownClasses.trigger} {
|
||||
&:hover,
|
||||
&:focus {
|
||||
.${dropdownClasses.triggerLabel} {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.trigger} {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 14px 10px 18px;
|
||||
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerLabel} {
|
||||
cursor: inherit;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerIcons} {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerIcon} {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerMenuIcon} {
|
||||
}
|
||||
|
||||
.${dropdownClasses.supportingText} {
|
||||
margin: 6px 14px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.error} {
|
||||
.${dropdownClasses.triggerLabel} {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.disabled} {
|
||||
.${dropdownClasses.trigger} {
|
||||
opacity: 0.34;
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.listBox} {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
border-top: 0;
|
||||
|
||||
& .${dropdownItemClasses.root} {
|
||||
border: 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid rgb(var(--lsd-border-primary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.small} {
|
||||
.${dropdownClasses.trigger} {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.medium} {
|
||||
.${dropdownClasses.trigger} {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
}
|
||||
`
|
|
@ -0,0 +1,147 @@
|
|||
import clsx from 'clsx'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { SelectOption, useSelect } from '../../utils/useSelect'
|
||||
import { DropdownItem } from '../DropdownItem'
|
||||
import { ArrowDownIcon, ArrowUpIcon, ErrorIcon } from '../Icons'
|
||||
import { ListBox } from '../ListBox'
|
||||
import { Portal } from '../PortalProvider/Portal'
|
||||
import { Typography } from '../Typography'
|
||||
import { dropdownClasses } from './Dropdown.classes'
|
||||
|
||||
export type DropdownOption = SelectOption
|
||||
|
||||
export type DropdownProps = Omit<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
'label' | 'disabled' | 'value' | 'onChange'
|
||||
> & {
|
||||
label: string
|
||||
error?: boolean
|
||||
disabled?: boolean
|
||||
supportingText?: string
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
|
||||
multi?: boolean
|
||||
options?: DropdownOption[]
|
||||
value?: string | string[]
|
||||
onChange?: (value: string | string[]) => void
|
||||
}
|
||||
|
||||
export const Dropdown: React.FC<DropdownProps> & {
|
||||
classes: typeof dropdownClasses
|
||||
} = ({
|
||||
label,
|
||||
size = 'large',
|
||||
error = false,
|
||||
disabled = false,
|
||||
supportingText,
|
||||
|
||||
value = [],
|
||||
onChange,
|
||||
options = [],
|
||||
multi = false,
|
||||
...props
|
||||
}) => {
|
||||
const ref = useRef<HTMLButtonElement>(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const { select, isSelected, selected } = useSelect(options, value, {
|
||||
multi,
|
||||
onChange,
|
||||
onDone: () => {
|
||||
setOpen(false)
|
||||
},
|
||||
})
|
||||
|
||||
const onTrigger = () => {
|
||||
!disabled && setOpen((value) => !value)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (disabled && open) setOpen(false)
|
||||
}, [open, disabled])
|
||||
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={clsx(
|
||||
props.className,
|
||||
dropdownClasses.root,
|
||||
dropdownClasses[size],
|
||||
error && dropdownClasses.error,
|
||||
disabled && dropdownClasses.disabled,
|
||||
open && dropdownClasses.open,
|
||||
)}
|
||||
>
|
||||
<button
|
||||
ref={ref}
|
||||
className={clsx(dropdownClasses.trigger)}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
<Typography
|
||||
color="primary"
|
||||
component="label"
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
className={dropdownClasses.triggerLabel}
|
||||
>
|
||||
{selected.length > 0
|
||||
? selected.map((opt) => opt.name).join(', ')
|
||||
: label}
|
||||
</Typography>
|
||||
<div className={dropdownClasses.triggerIcons}>
|
||||
{error && (
|
||||
<ErrorIcon
|
||||
color="primary"
|
||||
className={dropdownClasses.triggerIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{open ? (
|
||||
<ArrowUpIcon
|
||||
color="primary"
|
||||
className={dropdownClasses.triggerMenuIcon}
|
||||
/>
|
||||
) : (
|
||||
<ArrowDownIcon
|
||||
color="primary"
|
||||
className={dropdownClasses.triggerMenuIcon}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{supportingText && (
|
||||
<Typography
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
component="p"
|
||||
className={dropdownClasses.supportingText}
|
||||
>
|
||||
{supportingText}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Portal id="dropdown">
|
||||
<ListBox
|
||||
handleRef={ref}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
className={dropdownClasses.listBox}
|
||||
>
|
||||
{options.map((opt) => (
|
||||
<DropdownItem
|
||||
key={opt.value}
|
||||
size={size}
|
||||
tabIndex={0}
|
||||
onClick={select.bind(null, opt)}
|
||||
withIcon={multi}
|
||||
label={opt.name}
|
||||
selected={isSelected(opt)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && select(opt)}
|
||||
/>
|
||||
))}
|
||||
</ListBox>
|
||||
</Portal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Dropdown.classes = dropdownClasses
|
|
@ -0,0 +1 @@
|
|||
export * from './Dropdown'
|
|
@ -0,0 +1,13 @@
|
|||
export const dropdownItemClasses = {
|
||||
root: `lsd-dropdown-item`,
|
||||
icon: `lsd-dropdown-item__icon`,
|
||||
label: `lsd-dropdown-item__label`,
|
||||
|
||||
error: 'lsd-dropdown-item--error',
|
||||
disabled: 'lsd-dropdown-item--disabled',
|
||||
selected: 'lsd-dropdown-item--selected',
|
||||
withIcon: 'lsd-dropdown-item--with-icon',
|
||||
small: `lsd-dropdown-item--small`,
|
||||
medium: `lsd-dropdown-item--medium`,
|
||||
large: `lsd-dropdown-item--large`,
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import { Meta, Story } from '@storybook/react'
|
||||
import { DropdownItem, DropdownItemProps } from './DropdownItem'
|
||||
|
||||
export default {
|
||||
title: 'DropdownItem',
|
||||
component: DropdownItem,
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
name: 'enum',
|
||||
value: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
|
||||
export const Root: Story<DropdownItemProps> = (args) => (
|
||||
<div style={{ width: 400, overflow: 'hidden' }}>
|
||||
<DropdownItem {...args}></DropdownItem>
|
||||
</div>
|
||||
)
|
||||
|
||||
Root.args = {
|
||||
label: 'label',
|
||||
size: 'large',
|
||||
selected: false,
|
||||
withIcon: false,
|
||||
disabled: false,
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { css } from '@emotion/react'
|
||||
import { dropdownItemClasses } from './DropdownItem.classes'
|
||||
|
||||
export const DropdownItemStyles = css`
|
||||
.${dropdownItemClasses.root} {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
padding: 10px 14px;
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
|
||||
:not(.${dropdownItemClasses.disabled}) {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
outline: none;
|
||||
.${dropdownItemClasses.label} {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.label} {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.disabled} {
|
||||
opacity: 0.34;
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.icon} {
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.small} {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.medium} {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
.${dropdownItemClasses.large} {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
`
|
|
@ -0,0 +1,62 @@
|
|||
import clsx from 'clsx'
|
||||
import React from 'react'
|
||||
import { CheckboxFilledIcon, CheckboxIcon, LsdIconProps } from '../Icons'
|
||||
import { Typography } from '../Typography'
|
||||
import { dropdownItemClasses } from './DropdownItem.classes'
|
||||
|
||||
export type DropdownItemProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
label: string
|
||||
selected?: boolean
|
||||
withIcon?: boolean
|
||||
disabled?: boolean
|
||||
size: 'small' | 'medium' | 'large'
|
||||
}
|
||||
|
||||
export const DropdownItem: React.FC<DropdownItemProps> & {
|
||||
classes: typeof dropdownItemClasses
|
||||
} = ({
|
||||
label,
|
||||
size = 'large',
|
||||
withIcon,
|
||||
selected,
|
||||
disabled,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const iconProps: LsdIconProps = {
|
||||
color: 'primary',
|
||||
className: dropdownItemClasses.icon,
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="option"
|
||||
aria-selected={selected ? 'true' : 'false'}
|
||||
aria-label={label}
|
||||
className={clsx(
|
||||
className,
|
||||
dropdownItemClasses.root,
|
||||
dropdownItemClasses[size],
|
||||
withIcon && dropdownItemClasses.withIcon,
|
||||
disabled && dropdownItemClasses.disabled,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withIcon &&
|
||||
(selected ? (
|
||||
<CheckboxFilledIcon {...iconProps} />
|
||||
) : (
|
||||
<CheckboxIcon {...iconProps} />
|
||||
))}
|
||||
<Typography
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
component="span"
|
||||
className={dropdownItemClasses.label}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
DropdownItem.classes = dropdownItemClasses
|
|
@ -0,0 +1 @@
|
|||
export * from './DropdownItem'
|
|
@ -0,0 +1,6 @@
|
|||
export const listBoxClasses = {
|
||||
root: `lsd-list-box`,
|
||||
list: 'lsd-list-box-list',
|
||||
|
||||
open: 'lsd-list-box--open',
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { css } from '@emotion/react'
|
||||
import { listBoxClasses } from './ListBox.classes'
|
||||
|
||||
export const ListBoxStyles = css`
|
||||
.${listBoxClasses.root} {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
background: rgb(var(--lsd-surface-primary));
|
||||
}
|
||||
|
||||
.${listBoxClasses.open} {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
`
|
|
@ -0,0 +1,61 @@
|
|||
import clsx from 'clsx'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useClickAway } from 'react-use'
|
||||
import { listBoxClasses } from './ListBox.classes'
|
||||
|
||||
export type ListBoxProps = Omit<
|
||||
React.HTMLAttributes<HTMLUListElement>,
|
||||
'label'
|
||||
> & {
|
||||
open?: boolean
|
||||
label?: string
|
||||
onClose?: () => void
|
||||
handleRef: React.RefObject<HTMLElement>
|
||||
}
|
||||
|
||||
export const ListBox: React.FC<ListBoxProps> & {
|
||||
classes: typeof listBoxClasses
|
||||
} = ({ open, label, handleRef, onClose, children, ...props }) => {
|
||||
const ref = useRef<HTMLUListElement>(null)
|
||||
const [style, setStyle] = useState<React.CSSProperties>({})
|
||||
|
||||
useClickAway(ref, (event) => {
|
||||
if (!open || event.composedPath().includes(handleRef.current!)) return
|
||||
|
||||
onClose && onClose()
|
||||
})
|
||||
|
||||
const updateStyle = () => {
|
||||
const { width, height, top, left } =
|
||||
handleRef.current!.getBoundingClientRect()
|
||||
|
||||
setStyle({
|
||||
left,
|
||||
width,
|
||||
top: top + height,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateStyle()
|
||||
}, [open])
|
||||
|
||||
return (
|
||||
<ul
|
||||
{...props}
|
||||
ref={ref}
|
||||
role="listbox"
|
||||
aria-label={label}
|
||||
style={{ ...style, ...(props.style ?? {}) }}
|
||||
className={clsx(
|
||||
props.className,
|
||||
listBoxClasses.root,
|
||||
open && listBoxClasses.open,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
ListBox.classes = listBoxClasses
|
|
@ -0,0 +1 @@
|
|||
export * from './ListBox'
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { useCanUsePortal } from './PortalContext'
|
||||
import { usePortal } from './usePortal'
|
||||
|
||||
export type PortalProps = React.PropsWithChildren & {
|
||||
id: string
|
||||
}
|
||||
|
||||
export const Portal: React.FC<PortalProps> = ({ id, children }) => {
|
||||
const canUse = useCanUsePortal()
|
||||
if (!canUse) return <></>
|
||||
|
||||
return <PortalContent id={id}>{children}</PortalContent>
|
||||
}
|
||||
|
||||
const PortalContent: React.FC<PortalProps> = ({ id, children }) => {
|
||||
const element = usePortal({ parentId: 'lsd-presentation' })
|
||||
|
||||
if (!element) return <></>
|
||||
|
||||
return createPortal(children, element, id)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import React, { useContext } from 'react'
|
||||
|
||||
export type PortalContextType = {
|
||||
initialized?: boolean
|
||||
}
|
||||
|
||||
export const PortalContext = React.createContext<PortalContextType>({
|
||||
initialized: false,
|
||||
})
|
||||
|
||||
export const useCanUsePortal = (): boolean =>
|
||||
useContext(PortalContext)?.initialized ?? false
|
|
@ -0,0 +1,29 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { PortalContext } from './PortalContext'
|
||||
|
||||
export type PortalProviderProps = React.PropsWithChildren
|
||||
|
||||
export const PortalProvider: React.FC<PortalProviderProps> = ({ children }) => {
|
||||
const [initialized, setInitialized] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
const body = document.querySelector('body')!
|
||||
const container = document.createElement('div')
|
||||
container.id = 'lsd-presentation'
|
||||
body.appendChild(container)
|
||||
|
||||
setInitialized(true)
|
||||
|
||||
return () => {
|
||||
body.removeChild(container)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<PortalContext.Provider value={{ initialized }}>
|
||||
{children}
|
||||
</PortalContext.Provider>
|
||||
)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './PortalProvider'
|
|
@ -0,0 +1,28 @@
|
|||
import { useEffect, useRef } from 'react'
|
||||
|
||||
interface Props {
|
||||
parentId: string
|
||||
}
|
||||
|
||||
export const usePortal = ({ parentId }: Props) => {
|
||||
const elementRef = useRef<HTMLElement>()
|
||||
|
||||
if (typeof window !== 'undefined' && !elementRef.current) {
|
||||
elementRef.current = document.createElement('div')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || !elementRef.current) return
|
||||
document.getElementById(parentId)?.appendChild(elementRef.current)
|
||||
|
||||
return () => {
|
||||
try {
|
||||
document
|
||||
.getElementById(parentId)
|
||||
?.removeChild(elementRef.current as Node)
|
||||
} catch (error) {}
|
||||
}
|
||||
}, [parentId, elementRef.current])
|
||||
|
||||
return elementRef.current
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { Global, ThemeProvider as EmotionThemeProvider } from '@emotion/react'
|
||||
import React from 'react'
|
||||
import { CSSBaseline } from '../CSSBaseline'
|
||||
import { PortalProvider } from '../PortalProvider'
|
||||
import { ResizeObserverProvider } from '../ResizeObserver'
|
||||
import { Theme } from './types'
|
||||
|
||||
|
@ -14,11 +15,13 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|||
}) => {
|
||||
return (
|
||||
<ResizeObserverProvider>
|
||||
<ThemeContext.Provider value={{ theme }}>
|
||||
<EmotionThemeProvider theme={theme}>{children}</EmotionThemeProvider>
|
||||
<CSSBaseline theme={theme} />
|
||||
<Global styles={theme.globalStyles} />
|
||||
</ThemeContext.Provider>
|
||||
<PortalProvider>
|
||||
<ThemeContext.Provider value={{ theme }}>
|
||||
<EmotionThemeProvider theme={theme}>{children}</EmotionThemeProvider>
|
||||
<CSSBaseline theme={theme} />
|
||||
<Global styles={theme.globalStyles} />
|
||||
</ThemeContext.Provider>
|
||||
</PortalProvider>
|
||||
</ResizeObserverProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
export * from './components/Button'
|
||||
export * from './components/Dropdown'
|
||||
export * from './components/DropdownItem'
|
||||
export * from './components/Icons'
|
||||
export * from './components/ListBox'
|
||||
export * from './components/TabItem'
|
||||
export * from './components/Tabs'
|
||||
export * from './components/Theme'
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { pairs } from './object.utils'
|
||||
|
||||
export type SelectOption = {
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export const useSelect = (
|
||||
options: SelectOption[],
|
||||
value: string | string[],
|
||||
{
|
||||
onDone,
|
||||
onChange,
|
||||
multi = false,
|
||||
}: {
|
||||
multi?: boolean
|
||||
onDone?: (value: string | string[]) => void
|
||||
onChange?: (value: string | string[]) => void
|
||||
} = {},
|
||||
) => {
|
||||
const dict = useMemo(
|
||||
() => Object.fromEntries(options.map((opt) => [opt.value, opt])),
|
||||
[options],
|
||||
)
|
||||
|
||||
const [val, setVal] = useState<string[]>(
|
||||
Array.isArray(value) ? value : value ? [value] : [],
|
||||
)
|
||||
|
||||
const selection = useMemo(() => pairs(val, () => true), [val])
|
||||
const selected = useMemo(() => val.map((value) => dict[value]), [val, dict])
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) setVal(Array.isArray(value) ? value : value ? [value] : [])
|
||||
}, [value, onChange])
|
||||
|
||||
const getKey = (option: string | SelectOption) =>
|
||||
typeof option === 'string' ? option : option.value
|
||||
|
||||
const isSelected = (option: string | SelectOption) =>
|
||||
!!selection[getKey(option)]
|
||||
|
||||
const doSelect = (option: string | SelectOption) => {
|
||||
const key = getKey(option)
|
||||
const newVal = multi
|
||||
? selection[key]
|
||||
? val.filter((i) => i !== key)
|
||||
: [...val, key]
|
||||
: [key]
|
||||
onChange ? onChange(multi ? newVal : newVal[0]) : setVal(newVal)
|
||||
if (!multi && onDone) onDone(multi ? newVal : newVal[0])
|
||||
}
|
||||
|
||||
return {
|
||||
selected,
|
||||
isSelected,
|
||||
select: doSelect,
|
||||
}
|
||||
}
|
181
yarn.lock
181
yarn.lock
|
@ -1105,7 +1105,7 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4":
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4":
|
||||
version "7.20.13"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz"
|
||||
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
|
||||
|
@ -4257,6 +4257,11 @@
|
|||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/js-cookie@^2.2.6":
|
||||
version "2.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.7.tgz#226a9e31680835a6188e887f3988e60c04d3f6a3"
|
||||
integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8":
|
||||
version "7.0.11"
|
||||
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz"
|
||||
|
@ -4790,6 +4795,11 @@
|
|||
"@webassemblyjs/wast-parser" "1.9.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xobotyi/scrollbar-width@^1.9.5":
|
||||
version "1.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d"
|
||||
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
|
||||
|
@ -6715,6 +6725,13 @@ copy-descriptor@^0.1.0:
|
|||
resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
|
||||
integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==
|
||||
|
||||
copy-to-clipboard@^3.3.1:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0"
|
||||
integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==
|
||||
dependencies:
|
||||
toggle-selection "^1.0.6"
|
||||
|
||||
core-js-compat@^3.25.1, core-js-compat@^3.8.1:
|
||||
version "3.27.2"
|
||||
resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz"
|
||||
|
@ -6872,6 +6889,13 @@ crypto-browserify@^3.11.0:
|
|||
randombytes "^2.0.0"
|
||||
randomfill "^1.0.3"
|
||||
|
||||
css-in-js-utils@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz#640ae6a33646d401fc720c54fc61c42cd76ae2bb"
|
||||
integrity sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.3"
|
||||
|
||||
css-loader@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz"
|
||||
|
@ -6918,6 +6942,14 @@ css-select@^4.1.3:
|
|||
domutils "^2.8.0"
|
||||
nth-check "^2.0.1"
|
||||
|
||||
css-tree@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
||||
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
|
||||
dependencies:
|
||||
mdn-data "2.0.14"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-what@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz"
|
||||
|
@ -6928,7 +6960,7 @@ cssesc@^3.0.0:
|
|||
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
|
||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||
|
||||
csstype@^3.0.2:
|
||||
csstype@^3.0.2, csstype@^3.0.6:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz"
|
||||
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
||||
|
@ -8205,6 +8237,21 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
|||
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
|
||||
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
||||
|
||||
fast-loops@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-loops/-/fast-loops-1.1.3.tgz#ce96adb86d07e7bf9b4822ab9c6fac9964981f75"
|
||||
integrity sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==
|
||||
|
||||
fast-shallow-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b"
|
||||
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
|
||||
|
||||
fastest-stable-stringify@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76"
|
||||
integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
|
||||
|
@ -9417,6 +9464,11 @@ husky@^8.0.3:
|
|||
resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz"
|
||||
integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==
|
||||
|
||||
hyphenate-style-name@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
|
||||
|
@ -9564,6 +9616,14 @@ inline-style-parser@0.1.1:
|
|||
resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz"
|
||||
integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
|
||||
|
||||
inline-style-prefixer@^6.0.0:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz#4290ed453ab0e4441583284ad86e41ad88384f44"
|
||||
integrity sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==
|
||||
dependencies:
|
||||
css-in-js-utils "^3.1.0"
|
||||
fast-loops "^1.1.3"
|
||||
|
||||
inquirer@8.2.5, inquirer@^8.2.4:
|
||||
version "8.2.5"
|
||||
resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz"
|
||||
|
@ -10229,6 +10289,11 @@ jju@~1.4.0:
|
|||
resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz"
|
||||
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
|
||||
|
||||
js-cookie@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
|
||||
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
|
||||
|
||||
js-sdsl@^4.1.4:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz"
|
||||
|
@ -11033,6 +11098,11 @@ mdast-util-to-string@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz"
|
||||
integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==
|
||||
|
||||
mdn-data@2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
mdurl@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz"
|
||||
|
@ -11453,6 +11523,20 @@ nan@^2.12.1:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
|
||||
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
|
||||
|
||||
nano-css@^5.3.1:
|
||||
version "5.3.5"
|
||||
resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.5.tgz#3075ea29ffdeb0c7cb6d25edb21d8f7fa8e8fe8e"
|
||||
integrity sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==
|
||||
dependencies:
|
||||
css-tree "^1.1.2"
|
||||
csstype "^3.0.6"
|
||||
fastest-stable-stringify "^2.0.2"
|
||||
inline-style-prefixer "^6.0.0"
|
||||
rtl-css-js "^1.14.0"
|
||||
sourcemap-codec "^1.4.8"
|
||||
stacktrace-js "^2.0.2"
|
||||
stylis "^4.0.6"
|
||||
|
||||
nanoid@^3.3.1, nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
|
||||
|
@ -13130,6 +13214,31 @@ react-refresh@^0.14.0:
|
|||
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz"
|
||||
integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
|
||||
|
||||
react-universal-interface@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"
|
||||
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
|
||||
|
||||
react-use@^17.4.0:
|
||||
version "17.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.4.0.tgz#cefef258b0a6c534a5c8021c2528ac6e1a4cdc6d"
|
||||
integrity sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==
|
||||
dependencies:
|
||||
"@types/js-cookie" "^2.2.6"
|
||||
"@xobotyi/scrollbar-width" "^1.9.5"
|
||||
copy-to-clipboard "^3.3.1"
|
||||
fast-deep-equal "^3.1.3"
|
||||
fast-shallow-equal "^1.0.0"
|
||||
js-cookie "^2.2.1"
|
||||
nano-css "^5.3.1"
|
||||
react-universal-interface "^0.6.2"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
screenfull "^5.1.0"
|
||||
set-harmonic-interval "^1.0.1"
|
||||
throttle-debounce "^3.0.1"
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^2.1.0"
|
||||
|
||||
react@18.2.0, react@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
||||
|
@ -13481,6 +13590,11 @@ require-from-string@^2.0.2:
|
|||
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
|
||||
resolve-alpn@^1.0.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz"
|
||||
|
@ -13625,6 +13739,13 @@ rsvp@^4.8.4:
|
|||
resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz"
|
||||
integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==
|
||||
|
||||
rtl-css-js@^1.14.0:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.16.1.tgz#4b48b4354b0ff917a30488d95100fbf7219a3e80"
|
||||
integrity sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
run-async@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
|
||||
|
@ -13754,6 +13875,11 @@ schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1:
|
|||
ajv "^6.12.5"
|
||||
ajv-keywords "^3.5.2"
|
||||
|
||||
screenfull@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
|
||||
integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
||||
|
@ -13844,6 +13970,11 @@ set-blocking@^2.0.0:
|
|||
resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
|
||||
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
|
||||
|
||||
set-harmonic-interval@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249"
|
||||
integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==
|
||||
|
||||
set-value@^2.0.0, set-value@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz"
|
||||
|
@ -14093,6 +14224,11 @@ source-map-url@^0.4.0:
|
|||
resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz"
|
||||
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
|
||||
|
||||
source-map@0.5.6:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
|
||||
|
@ -14196,11 +14332,35 @@ stable@^0.1.8:
|
|||
resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz"
|
||||
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
|
||||
|
||||
stack-generator@^2.0.5:
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.10.tgz#8ae171e985ed62287d4f1ed55a1633b3fb53bb4d"
|
||||
integrity sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==
|
||||
dependencies:
|
||||
stackframe "^1.3.4"
|
||||
|
||||
stackframe@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz"
|
||||
integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
|
||||
|
||||
stacktrace-gps@^3.0.4:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz#0c40b24a9b119b20da4525c398795338966a2fb0"
|
||||
integrity sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==
|
||||
dependencies:
|
||||
source-map "0.5.6"
|
||||
stackframe "^1.3.4"
|
||||
|
||||
stacktrace-js@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
|
||||
integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
|
||||
dependencies:
|
||||
error-stack-parser "^2.0.6"
|
||||
stack-generator "^2.0.5"
|
||||
stacktrace-gps "^3.0.4"
|
||||
|
||||
state-toggle@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz"
|
||||
|
@ -14482,7 +14642,7 @@ styled-jsx@5.1.1:
|
|||
dependencies:
|
||||
client-only "0.0.1"
|
||||
|
||||
stylis@4.1.3:
|
||||
stylis@4.1.3, stylis@^4.0.6:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz"
|
||||
integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==
|
||||
|
@ -14676,6 +14836,11 @@ text-table@^0.2.0:
|
|||
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
|
||||
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
|
||||
|
||||
throttle-debounce@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
|
||||
integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
|
||||
|
||||
through2@^2.0.0:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
|
||||
|
@ -14772,6 +14937,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
|
|||
regex-not "^1.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
toggle-selection@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
|
||||
integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==
|
||||
|
||||
toidentifier@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
|
||||
|
@ -14822,6 +14992,11 @@ ts-dedent@^2.0.0, ts-dedent@^2.2.0:
|
|||
resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz"
|
||||
integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==
|
||||
|
||||
ts-easing@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
|
||||
integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==
|
||||
|
||||
ts-morph@17.0.1:
|
||||
version "17.0.1"
|
||||
resolved "https://registry.npmjs.org/ts-morph/-/ts-morph-17.0.1.tgz"
|
||||
|
|
Loading…
Reference in New Issue