Chore/315 remove blueprint from token dapp (#423)

* fix: nav colors

* chore: replace blueprint progress bar

* chore: remove blueprint overlay and no unused components

* feat: add radio group to ui-toolkit

* feat: adjust disabled opacity and use radio in forms on staking flow

* chore: rename RadioItem to just Radio

* chore: replace country selector with plain select

* fix: key prop warnings

* feat: convert token drawer from blueprint drawer to radix dialog

* chore: remove blueprint core and blueprint select dependencies

* fix: add missing data test id for header title

* fix: spacing on token disassociate page

* fix: missing key props on vesting chart

* feat: update radio button design

* style: radio button UI tweaks

Co-authored-by: PeteWilliams <me@petewilliams.info>
This commit is contained in:
Matthew Russell 2022-05-23 05:04:15 -04:00 committed by GitHub
parent 34502a7c7f
commit 38352c511f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 339 additions and 351 deletions

View File

@ -10,9 +10,9 @@ export const BulletHeader = ({ tag, children, style }: BulletHeaderProps) => {
return React.createElement(
tag,
{ className: 'mt-24 pt-8 pb-20 uppercase', style },
[
<span className="inline-block w-[12px] h-[12px] mr-12 bg-white" />,
children,
]
<>
<span className="inline-block w-[12px] h-[12px] mr-12 bg-white" />
{children}
</>
);
};

View File

@ -9,7 +9,9 @@ export const ConnectedVegaKey = ({ pubKey }: { pubKey: string | null }) => {
<strong data-testid="connected-vega-key-label">
{pubKey ? t('Connected Vega key') : <ConnectToVega />}
</strong>
<p data-testid="connected-vega-key">{pubKey}</p>
<p className="mb-12" data-testid="connected-vega-key">
{pubKey}
</p>
</section>
);
};

View File

@ -1,30 +1,7 @@
import { MenuItem } from '@blueprintjs/core';
import type { ItemPredicate } from '@blueprintjs/select';
import { Suggest } from '@blueprintjs/select';
import { Select } from '@vegaprotocol/ui-toolkit';
import type { ICountry } from '../../routes/claim/claim-form';
import countryData from './country-data';
const CountrySuggest = Suggest.ofType<ICountry>();
export const filterCountry: ItemPredicate<ICountry> = (
query,
country,
_index,
exactMatch
) => {
const normalizedTitle = country.name.toLowerCase();
const normalizedQuery = query.toLowerCase();
if (exactMatch) {
return normalizedTitle === normalizedQuery;
} else if (query.length === 2) {
return normalizedQuery === country.code.toLowerCase();
} else {
return normalizedTitle.indexOf(normalizedQuery) >= 0;
}
};
export interface CountrySelectorProps {
onSelectCountry: (countryCode: string) => void;
code: string | null | undefined;
@ -36,30 +13,18 @@ export const CountrySelector = ({
}: CountrySelectorProps) => {
return (
<div data-testid="country-selector">
<CountrySuggest
selectedItem={
countryData.find((c) => c.code === code) || countryData[0]
}
items={countryData}
itemRenderer={(item, { handleClick, modifiers }) => (
<MenuItem
data-testid={item.code}
key={item.code}
text={item.name}
active={modifiers.active}
disabled={modifiers.disabled}
onClick={handleClick}
/>
)}
onItemSelect={(item) => {
onSelectCountry(item.code);
}}
inputValueRenderer={(item) => item.name}
popoverProps={{ minimal: true }}
noResults={<MenuItem disabled={true} text="No results." />}
itemPredicate={filterCountry}
fill={true}
/>
<Select
value={code ? code : undefined}
onChange={(e) => onSelectCountry(e.target.value)}
>
{countryData.map((country) => {
return (
<option value={country.code} key={country.code}>
{country.name}
</option>
);
})}
</Select>
</div>
);
};

View File

@ -1,10 +1,10 @@
import { Intent, ProgressBar } from '@blueprintjs/core';
import { format, formatDistanceStrict } from 'date-fns';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import arrow from '../../images/back.png';
import { DATE_FORMAT_DETAILED } from '../../lib/date-formats';
import { ProgressBar } from '../progress-bar';
export interface EpochCountdownProps {
id: string;
@ -68,12 +68,7 @@ export function EpochCountdown({
: t('Awaiting next epoch')}
</p>
</div>
<ProgressBar
animate={false}
value={progress}
stripes={false}
intent={Intent.NONE}
/>
<ProgressBar value={progress} />
<div className="flex mt-4 text-ui-small">
<p>{format(startDate, DATE_FORMAT_DETAILED)}</p>
<div className="flex-1 text-center">

View File

@ -1 +0,0 @@
export * from './modal';

View File

@ -1,13 +0,0 @@
import React from 'react';
interface ModalProps {
children: React.ReactNode;
title: string;
}
export const Modal = ({ children, title }: ModalProps) => (
<div className="relative top-0 left-[calc(50vw_-_200px)] w-[400px] my-[10vh] mx-0 bg-white text-black z-30">
<h2 className="text-center py-12">{title}</h2>
<div className="pt-0 px-20 pb-20">{children}</div>
</div>
);

View File

@ -0,0 +1,25 @@
@keyframes slideIn {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
@keyframes slideOut {
from {
transform: translateX(0);
}
to {
transform: translateX(100%);
}
}
.drawer-content[data-state='open'] {
animation: slideIn 150ms ease-out forwards;
}
.drawer-content[data-state='closed'] {
animation: slideOut 150ms ease-in forwards;
}

View File

@ -1,6 +1,9 @@
import { Drawer } from '@blueprintjs/core';
import './nav.css';
import classNames from 'classnames';
import debounce from 'lodash/debounce';
import React from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import { useTranslation } from 'react-i18next';
import { Link, NavLink } from 'react-router-dom';
@ -126,10 +129,10 @@ const NavHeader = ({ fairground }: { fairground: boolean }) => {
)}
</Link>
<h1
data-testid="header-title"
className={`text-[28px] lg:text-h3 pl-8 ${
fairground ? 'text-black' : 'text-white'
}`}
data-testid="header-title"
>
{fairground ? t('fairgroundTitle') : t('title')}
</h1>
@ -148,6 +151,13 @@ const IconLine = ({ inverted }: { inverted: boolean }) => (
const NavDrawer = ({ inverted }: { inverted: boolean }) => {
const { appState, appDispatch } = useAppState();
const drawerContentClasses = classNames(
'drawer-content', // needed for css animation
// Positions the modal in the center of screen
'fixed w-[80vw] max-w-[420px] top-0 right-0',
'flex flex-col flex-nowrap justify-between h-full bg-banner overflow-y-scroll border-l border-white',
'bg-black text-white-95'
);
return (
<>
<button
@ -164,29 +174,30 @@ const NavDrawer = ({ inverted }: { inverted: boolean }) => {
<IconLine inverted={inverted} />
</button>
<Drawer
isOpen={appState.drawerOpen}
onClose={() =>
<Dialog.Root
open={appState.drawerOpen}
onOpenChange={(isOpen) =>
appDispatch({
type: AppStateActionType.SET_DRAWER,
isOpen: false,
isOpen,
})
}
size="80%"
className="border border-white max-w-[420px]"
>
<div className="flex flex-col flex-nowrap justify-between h-full bg-banner overflow-y-scroll">
<div>
<DrawerSection>
<EthWallet />
</DrawerSection>
<DrawerSection>
<VegaWallet />
</DrawerSection>
</div>
<NavLinks isDesktop={false} />
</div>
</Drawer>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-white/15" />
<Dialog.Content className={drawerContentClasses}>
<div>
<DrawerSection>
<EthWallet />
</DrawerSection>
<DrawerSection>
<VegaWallet />
</DrawerSection>
</div>
<NavLinks isDesktop={false} />
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
</>
);
};
@ -206,35 +217,36 @@ const NavLinks = ({ isDesktop }: { isDesktop: boolean }) => {
{ route: Routes.WITHDRAW, text: t('Withdraw') },
{ route: Routes.GOVERNANCE, text: t('Governance') },
];
const navClasses = classNames('flex', {
'flex-row gap-8 mt-8 uppercase': isDesktop,
'flex-col': !isDesktop,
});
return (
<nav
className={`flex uppercase
${isDesktop ? 'flex-row mt-8' : 'flex-col'}`}
>
{routes.map(({ route, text }) => (
<NavLink
{...linkProps}
to={route}
className={({ isActive }) =>
`no-underline hover:no-underline
${
isDesktop
? `py-4 px-16 ${
isActive
? 'bg-black text-white'
: 'bg-transparent text-black hover:text-white'
}`
: `border-t border-white p-20 ${
isActive
? 'bg-vega-yellow text-black hover:text-black'
: 'bg-black text-white hover:text-vega-yellow'
}`
}`
}
>
{text}
</NavLink>
))}
<nav className={navClasses}>
{routes.map(({ route, text }) => {
return (
<NavLink
{...linkProps}
to={route}
key={route}
className={({ isActive }) => {
const linkClasses = classNames(
'no-underline hover:no-underline',
{
'bg-vega-yellow text-black hover:text-black': isActive,
'bg-black text-white': !isActive,
'py-2 px-12': isDesktop,
'border-t border-white p-20': !isDesktop,
}
);
return linkClasses;
}}
>
{text}
</NavLink>
);
})}
</nav>
);
};

View File

@ -0,0 +1 @@
export * from './progress-bar';

View File

@ -0,0 +1,34 @@
export interface ProgressBarProps {
value: number;
}
export const ProgressBar = ({ value }: ProgressBarProps) => {
const percent = value == null ? undefined : 100 * clamp(value, 0, 1);
// don't set width if value is null (rely on default CSS value)
const width = percent == null ? undefined : percent + '%';
return (
<div
aria-valuemax={100}
aria-valuemin={0}
aria-valuenow={percent == null ? undefined : Math.round(percent)}
role="progressbar"
className="relative border h-[21px]"
>
<div
className="bg-white h-full absolute transition-[width] ease-in-out"
style={{ width }}
/>
</div>
);
};
function clamp(val: number, min: number, max: number) {
if (val == null) {
return val;
}
if (max < min) {
throw new Error('clamp: max cannot be less than min');
}
return Math.min(Math.max(val, min), max);
}

View File

@ -1,4 +1,4 @@
import { Radio, RadioGroup } from '@blueprintjs/core';
import { RadioGroup, Radio } from '@vegaprotocol/ui-toolkit';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -18,24 +18,24 @@ export const StakingMethodRadio = ({
}) => {
const { t } = useTranslation();
return (
<RadioGroup
inline={true}
onChange={(e) => {
// @ts-ignore can't recognise .value
setSelectedStakingMethod(e.target.value);
}}
selectedValue={selectedStakingMethod || undefined}
>
<Radio
data-testid="associate-radio-contract"
label={t('Vesting contract')}
value={StakingMethod.Contract}
/>
<Radio
data-testid="associate-radio-wallet"
label={t('Wallet')}
value={StakingMethod.Wallet}
/>
</RadioGroup>
<div className="mb-12">
<RadioGroup
onChange={(value) => {
setSelectedStakingMethod(value as StakingMethod);
}}
value={selectedStakingMethod || undefined}
>
<Radio
id="associate-radio-contract"
label={t('Vesting contract')}
value={StakingMethod.Contract}
/>
<Radio
id="associate-radio-wallet"
label={t('Wallet')}
value={StakingMethod.Wallet}
/>
</RadioGroup>
</div>
);
};

View File

@ -1,6 +1,5 @@
import { Overlay } from '@blueprintjs/core';
import type { TxData } from '@vegaprotocol/smart-contracts-sdk';
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
import { Dialog, EtherscanLink } from '@vegaprotocol/ui-toolkit';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -11,8 +10,6 @@ import {
import { useContracts } from '../../contexts/contracts/contracts-context';
import { truncateMiddle } from '../../lib/truncate-middle';
import { Tick } from '../icons';
import { Loader } from '../loader';
import { Modal } from '../modal';
const TransactionModalTh = ({ children }: { children: React.ReactNode }) => (
<th className="border-b border-black-25 text-black-60 text-left font-normal">
@ -35,23 +32,9 @@ export const TransactionModal = () => {
const { transactions } = useContracts();
const { appState, appDispatch } = useAppState();
const close = React.useCallback(
() =>
appDispatch({
type: AppStateActionType.SET_TRANSACTION_OVERLAY,
isOpen: false,
}),
[appDispatch]
);
const renderStatus = (txObj: TxData) => {
if (!txObj.receipt) {
return (
<TransactionModalStatus>
<Loader invert={true} />
<span>{t('pending')}</span>
</TransactionModalStatus>
);
return <TransactionModalStatus>{t('pending')}</TransactionModalStatus>;
}
if (txObj.receipt.confirmations >= txObj.requiredConfirmations) {
@ -65,53 +48,52 @@ export const TransactionModal = () => {
return (
<TransactionModalStatus>
<Loader invert={true} />
<span>
{t('confirmationsRemaining', {
confirmations: txObj.receipt.confirmations,
required: txObj.requiredConfirmations,
})}
</span>
{t('confirmationsRemaining', {
confirmations: txObj.receipt.confirmations,
required: txObj.requiredConfirmations,
})}
</TransactionModalStatus>
);
};
return (
<Overlay
className="bp3-dark"
isOpen={appState.transactionOverlay}
onClose={close}
transitionDuration={0}
<Dialog
open={appState.transactionOverlay}
title={t('ethTransactionModalTitle')}
onChange={(isOpen) =>
appDispatch({
type: AppStateActionType.SET_TRANSACTION_OVERLAY,
isOpen,
})
}
>
<Modal title={t('ethTransactionModalTitle')}>
{transactions.length ? (
<table className="w-full">
<thead>
<tr>
<TransactionModalTh>{t('transaction')}</TransactionModalTh>
<TransactionModalTh>{t('status')}</TransactionModalTh>
</tr>
</thead>
<tbody>
{transactions.map((t) => {
return (
<tr key={t.tx.hash}>
<TransactionModalTd>
<EtherscanLink
tx={t.tx.hash}
text={truncateMiddle(t.tx.hash)}
/>
</TransactionModalTd>
<TransactionModalTd>{renderStatus(t)}</TransactionModalTd>
</tr>
);
})}
</tbody>
</table>
) : (
<p>{t('noTransactions')}</p>
)}
</Modal>
</Overlay>
{transactions.length ? (
<table className="w-full">
<thead>
<tr>
<TransactionModalTh>{t('transaction')}</TransactionModalTh>
<TransactionModalTh>{t('status')}</TransactionModalTh>
</tr>
</thead>
<tbody>
{transactions.map((t) => {
return (
<tr key={t.tx.hash}>
<TransactionModalTd>
<EtherscanLink
tx={t.tx.hash}
text={truncateMiddle(t.tx.hash)}
/>
</TransactionModalTd>
<TransactionModalTd>{renderStatus(t)}</TransactionModalTd>
</tr>
);
})}
</tbody>
</table>
) : (
<p>{t('noTransactions')}</p>
)}
</Dialog>
);
};

View File

@ -52,20 +52,24 @@ export const DisassociatePage = ({
return (
<section className="disassociate-page" data-testid="disassociate-page">
<p>
<p className="mb-12">
{t(
'Use this form to disassociate VEGA tokens with a Vega key. This returns them to either the Ethereum wallet that used the Staking bridge or the vesting contract.'
)}
</p>
<p>
<p className="mb-12">
<span className="text-vega-red">{t('Warning')}:</span>{' '}
{t(
'Any Tokens that have been nominated to a node will sacrifice any Rewards they are due for the current epoch. If you do not wish to sacrifices fees you should remove stake from a node at the end of an epoch before disassocation.'
)}
</p>
<h1>{t('What Vega wallet are you removing Tokens from?')}</h1>
<h2 className="text-h4 mb-8">
{t('What Vega wallet are you removing Tokens from?')}
</h2>
<ConnectedVegaKey pubKey={vegaKey.pub} />
<h1>{t('What tokens would you like to return?')}</h1>
<h2 className="text-h4 mb-8">
{t('What tokens would you like to return?')}
</h2>
<StakingMethodRadio
setSelectedStakingMethod={setSelectedStakingMethod}
selectedStakingMethod={selectedStakingMethod}

View File

@ -1,5 +1,4 @@
import { gql, useApolloClient } from '@apollo/client';
import { Radio, RadioGroup } from '@blueprintjs/core';
import * as Sentry from '@sentry/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -19,7 +18,7 @@ import type {
import { StakeFailure } from './stake-failure';
import { StakePending } from './stake-pending';
import { StakeSuccess } from './stake-success';
import { Button, FormGroup } from '@vegaprotocol/ui-toolkit';
import { Button, FormGroup, RadioGroup, Radio } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import type {
DelegateSubmissionBody,
@ -210,28 +209,26 @@ export const StakingForm = ({
<h2 className="text-h4 mb-8">{t('Manage your stake')}</h2>
<FormGroup>
<RadioGroup
onChange={(e) => {
onChange={(value) => {
// @ts-ignore value does exist on target
const value = e.target.value;
setAction(value);
navigate(`?action=${value}`, {
replace: true,
});
}}
selectedValue={action}
inline={true}
value={action}
>
<Radio
disabled={availableStakeToAdd.isEqualTo(0)}
value={Actions.Add}
label="Add"
data-testid="add-stake-radio"
id="add-stake-radio"
/>
<Radio
disabled={availableStakeToRemove.isEqualTo(0)}
value={Actions.Remove}
label="Remove"
data-testid="remove-stake-radio"
id="remove-stake-radio"
/>
</RadioGroup>
</FormGroup>

View File

@ -38,7 +38,7 @@ export const VestingChart = () => {
['orange', Colors.orange],
['yellow', Colors.yellow.DEFAULT],
].map(([key, color]) => (
<linearGradient id={key} x1="0" y1="0" x2="0" y2="1">
<linearGradient key={key} id={key} x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor={color} stopOpacity={0.85} />
<stop offset="100%" stopColor={color} stopOpacity={0} />
</linearGradient>

View File

@ -1,34 +1,3 @@
@import '~@blueprintjs/core/lib/css/blueprint.css';
@import '~@blueprintjs/icons/lib/css/blueprint-icons.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
a,
a:hover {
color: white;
}
.modal a,
.modal a:hover {
color: black;
}
.bp3-dark .bp3-input {
background-color: #3f3f3f;
}
.epoch-countdown .bp3-progress-bar {
border: 1px solid white;
border-radius: 0;
height: 21px;
}
.epoch-countdown .bp3-progress-bar .bp3-progress-meter {
border-radius: 0;
}
.bp3-dark .epoch-countdown .bp3-progress-bar .bp3-progress-meter {
background-color: white;
}

View File

@ -126,7 +126,7 @@ module.exports = {
DEFAULT: '0.225rem',
md: '0.3rem',
lg: '0.5rem',
full: '9999px',
full: '100%',
},
fontFamily: {
mono: ['Roboto Mono', ...defaultTheme.fontFamily.mono],
@ -180,5 +180,6 @@ module.exports = {
callout: '5px 5px 0 1px rgba(255, 255, 255, 0.05)',
focus: '0px 0px 0px 1px #FFFFFF, 0px 0px 3px 2px #FFE600',
'focus-dark': '0px 0px 0px 1px #000000, 0px 0px 3px 2px #FFE600',
radio: '1px 1px 0 0',
},
};

View File

@ -15,6 +15,7 @@ export * from './input-error';
export * from './key-value-table';
export * from './loader';
export * from './lozenge';
export * from './radio-group';
export * from './select';
export * from './splash';
export * from './text-area';

View File

@ -0,0 +1 @@
export * from './radio-group';

View File

@ -0,0 +1,18 @@
import type { Story, Meta } from '@storybook/react';
import { RadioGroup, Radio } from './radio-group';
export default {
component: RadioGroup,
title: 'RadioGroup',
} as Meta;
const Template: Story = (args) => (
<RadioGroup>
<Radio id="item-1" value="1" label="Item 1" />
<Radio id="item-2" value="2" label="Item 2" />
<Radio id="item-3" value="3" label="Disabled item" disabled={true} />
<Radio id="item-4" value="4" label="Error" hasError={true} />
</RadioGroup>
);
export const Default = Template.bind({});

View File

@ -0,0 +1,63 @@
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
import classNames from 'classnames';
import type { ReactNode } from 'react';
interface RadioGroupProps {
children: ReactNode;
defaultValue?: string;
value?: string;
onChange?: (value: string) => void;
}
export const RadioGroup = ({ children, onChange }: RadioGroupProps) => {
return (
<RadioGroupPrimitive.Root
onValueChange={onChange}
className="flex flex-row gap-24"
>
{children}
</RadioGroupPrimitive.Root>
);
};
interface RadioProps {
id: string;
value: string;
label: string;
disabled?: boolean;
hasError?: boolean;
}
export const Radio = ({ id, value, label, disabled, hasError }: RadioProps) => {
const wrapperClasses = classNames('flex flex-row gap-8 items-center', {
'opacity-50': disabled,
});
const itemClasses = classNames(
'flex justify-center items-center',
'w-[17px] h-[17px] rounded-full border',
'focus:outline-0 focus-visible:outline-0',
'focus-visible:shadow-radio focus-visible:shadow-vega-pink dark:focus-visible:shadow-vega-yellow',
'border-black-60 dark:border-white-60',
'dark:bg-white-25',
{
'border-black-60 dark:border-white-60': !hasError,
'border-intent-danger dark:border-intent-danger': hasError,
}
);
return (
<div className={wrapperClasses}>
<RadioGroupPrimitive.Item
value={value}
className={itemClasses}
id={id}
data-testid={id}
disabled={disabled}
>
<RadioGroupPrimitive.Indicator className="w-[7px] h-[7px] bg-vega-pink dark:bg-vega-yellow rounded-full" />
</RadioGroupPrimitive.Item>
<label htmlFor={id} className={disabled ? '' : 'cursor-pointer'}>
{label}
</label>
</div>
);
};

View File

@ -14,15 +14,14 @@
"private": true,
"dependencies": {
"@apollo/client": "^3.5.8",
"@blueprintjs/core": "^3.47.0",
"@blueprintjs/icons": "^3.32.0",
"@blueprintjs/select": "^3.16.6",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@mui/material": "^5.6.2",
"@nrwl/next": "13.10.3",
"@radix-ui/react-dialog": "^0.1.5",
"@radix-ui/react-dropdown-menu": "^0.1.6",
"@radix-ui/react-radio-group": "^0.1.5",
"@radix-ui/react-tabs": "^0.1.5",
"@radix-ui/react-tooltip": "^0.1.7",
"@sentry/nextjs": "^6.19.3",

135
yarn.lock
View File

@ -1283,30 +1283,7 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@blueprintjs/colors@^4.0.0-alpha.3":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@blueprintjs/colors/-/colors-4.0.5.tgz#7841a62b350f94fd2f2cc36e04c9e62d19e6986d"
integrity sha512-5ewWnDdUzyP7hnfidIPyAykGmjHAY2xjcUPM3J2hmnAQ4FORWPv7Mr3PJ9D0D7GfZV/ACx3URRclE1MXfvVlGA==
"@blueprintjs/core@^3.47.0", "@blueprintjs/core@^3.54.0":
version "3.54.0"
resolved "https://registry.yarnpkg.com/@blueprintjs/core/-/core-3.54.0.tgz#7269f34eccdf0d2874377c5ad973ca2a31562221"
integrity sha512-u2c1s6MNn0ocxhnC6CuiG5g3KV6b4cKUvSobznepA9SC3/AL1s3XOvT7DLWoHRv2B/vBOHFYEDzLw2/vlcGGZg==
dependencies:
"@blueprintjs/colors" "^4.0.0-alpha.3"
"@blueprintjs/icons" "^3.33.0"
"@juggle/resize-observer" "^3.3.1"
"@types/dom4" "^2.0.1"
classnames "^2.2"
dom4 "^2.1.5"
normalize.css "^8.0.1"
popper.js "^1.16.1"
react-lifecycles-compat "^3.0.4"
react-popper "^1.3.7"
react-transition-group "^2.9.0"
tslib "~2.3.1"
"@blueprintjs/icons@^3.32.0", "@blueprintjs/icons@^3.33.0":
"@blueprintjs/icons@^3.32.0":
version "3.33.0"
resolved "https://registry.yarnpkg.com/@blueprintjs/icons/-/icons-3.33.0.tgz#4dacdb7731abdf08d1ab240f3a23a185df60918b"
integrity sha512-Q6qoSDIm0kRYQZISm59UUcDCpV3oeHulkLuh3bSlw0HhcSjvEQh2PSYbtaifM60Q4aK4PCd6bwJHg7lvF1x5fQ==
@ -1314,15 +1291,6 @@
classnames "^2.2"
tslib "~2.3.1"
"@blueprintjs/select@^3.16.6":
version "3.19.1"
resolved "https://registry.yarnpkg.com/@blueprintjs/select/-/select-3.19.1.tgz#b5e8baa6f182a0647651a57fde8d1d97eaa1e997"
integrity sha512-8UJIZMaWXRMQHr14wbmzJc/CklcSKxOU5JUux0xXKQz/hDW/g1a650tlwJmnxufvRdShbGinlVfHupCs0EL6sw==
dependencies:
"@blueprintjs/core" "^3.54.0"
classnames "^2.2"
tslib "~2.3.1"
"@cnakazawa/watch@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
@ -2183,14 +2151,6 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@hypnosphi/create-react-context@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6"
integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==
dependencies:
gud "^1.0.0"
warning "^4.0.3"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@ -3510,6 +3470,17 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-label@0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
integrity sha512-Au9+n4/DhvjR0IHhvZ1LPdx/OW+3CGDie30ZyCkbSHIuLp4/CV4oPPGBwJ1vY99Jog3zyQhsGww9MXj8O9Aj/A==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-id" "0.1.5"
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-menu@0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-0.1.6.tgz#7f9521a10f6a9cd819b33b33d5ed9538d79b2e75"
@ -3575,6 +3546,23 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "0.1.2"
"@radix-ui/react-radio-group@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-0.1.5.tgz#ca8a676123a18b44804aff10af46129e2c2b37c3"
integrity sha512-ybgHsmh/V2crKvK6xZ56dpPul7b+vyxcq7obWqHbr5W6Ca11wdm0E7lS0i/Y6pgfIKYOWIARmZYDpRMEeRCPOw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "0.1.0"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-label" "0.1.5"
"@radix-ui/react-presence" "0.1.2"
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-roving-focus" "0.1.5"
"@radix-ui/react-use-controllable-state" "0.1.0"
"@radix-ui/react-use-previous" "0.1.1"
"@radix-ui/react-use-size" "0.1.1"
"@radix-ui/react-roving-focus@0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-0.1.5.tgz#cc48d17a36b56f253d54905b0fd60ee134cb97ee"
@ -5457,11 +5445,6 @@
"@types/d3-interpolate" "^2"
"@types/d3-selection" "^2"
"@types/dom4@^2.0.1":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/dom4/-/dom4-2.0.2.tgz#6495303f049689ce936ed328a3e5ede9c51408ee"
integrity sha512-Rt4IC1T7xkCWa0OG1oSsPa0iqnxlDeQqKXZAHrQGLb7wFGncWm85MaxKUjAGejOrUynOgWlFi4c6S6IyJwoK4g==
"@types/eslint-scope@^3.7.3":
version "3.7.3"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
@ -10333,18 +10316,6 @@ deep-eql@^3.0.1:
dependencies:
type-detect "^4.0.0"
deep-equal@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
dependencies:
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@ -10628,11 +10599,6 @@ dom-walk@^0.1.0:
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
dom4@^2.1.5:
version "2.1.6"
resolved "https://registry.yarnpkg.com/dom4/-/dom4-2.1.6.tgz#c90df07134aa0dbd81ed4d6ba1237b36fc164770"
integrity sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA==
domain-browser@4.19.0:
version "4.19.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1"
@ -12721,11 +12687,6 @@ graphql-ws@^5.6.3:
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38"
integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==
gud@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==
handle-thing@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@ -13905,7 +13866,7 @@ is-reference@^1.2.1:
dependencies:
"@types/estree" "*"
is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4:
is-regex@^1.1.2, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
@ -16242,11 +16203,6 @@ normalize-url@^6.0.1, normalize-url@^6.1.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
normalize.css@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3"
integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@ -17201,11 +17157,6 @@ polished@^4.0.5:
dependencies:
"@babel/runtime" "^7.17.8"
popper.js@^1.14.4, popper.js@^1.16.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
portfinder@^1.0.28:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
@ -17712,7 +17663,7 @@ prompts@^2.0.1, prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -18104,19 +18055,6 @@ react-popper-tooltip@^3.1.1:
"@popperjs/core" "^2.5.4"
react-popper "^2.2.4"
react-popper@^1.3.7:
version "1.3.11"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
dependencies:
"@babel/runtime" "^7.1.2"
"@hypnosphi/create-react-context" "^0.3.1"
deep-equal "^1.1.1"
popper.js "^1.14.4"
prop-types "^15.6.1"
typed-styles "^0.0.7"
warning "^4.0.2"
react-popper@^2.2.4:
version "2.2.5"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96"
@ -18260,7 +18198,7 @@ react-textarea-autosize@^8.3.0:
use-composed-ref "^1.0.0"
use-latest "^1.0.0"
react-transition-group@2.9.0, react-transition-group@^2.9.0:
react-transition-group@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
@ -18527,7 +18465,7 @@ regexp-tree@^0.1.24, regexp-tree@~0.1.1:
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d"
integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==
regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1:
regexp.prototype.flags@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307"
integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==
@ -20892,11 +20830,6 @@ typed-assert@^1.0.8:
resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.9.tgz#8af9d4f93432c4970ec717e3006f33f135b06213"
integrity sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==
typed-styles@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==
typedarray-to-buffer@3.1.5, typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@ -21500,7 +21433,7 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.12"
warning@^4.0.2, warning@^4.0.3:
warning@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==