Feat/246 Add candle chart controls (#281)
* Add candle chart controls * Improve dropdown menu styling * Use latest pennant version * Use translation helper * Square off highlighted corners
This commit is contained in:
parent
492eef0fd0
commit
dca1af7391
@ -1,11 +1,42 @@
|
||||
import 'pennant/dist/style.css';
|
||||
|
||||
import { Chart, Interval } from 'pennant';
|
||||
import {
|
||||
Chart,
|
||||
ChartType,
|
||||
Interval,
|
||||
Overlay,
|
||||
Study,
|
||||
chartTypeLabels,
|
||||
intervalLabels,
|
||||
overlayLabels,
|
||||
studyLabels,
|
||||
} from 'pennant';
|
||||
import { VegaDataSource } from './data-source';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { useContext, useMemo, useState } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItemIndicator,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuTrigger,
|
||||
Icon,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import type { IconName } from '@blueprintjs/icons';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const chartTypeIcon = new Map<ChartType, IconName>([
|
||||
[ChartType.AREA, IconNames.TIMELINE_AREA_CHART],
|
||||
[ChartType.CANDLE, IconNames.WATERFALL_CHART],
|
||||
[ChartType.LINE, IconNames.TIMELINE_LINE_CHART],
|
||||
[ChartType.OHLC, IconNames.WATERFALL_CHART],
|
||||
]);
|
||||
|
||||
export type CandlesChartContainerProps = {
|
||||
marketId: string;
|
||||
@ -18,11 +49,148 @@ export const CandlesChartContainer = ({
|
||||
const { keypair } = useVegaWallet();
|
||||
const theme = useContext(ThemeContext);
|
||||
|
||||
const [interval, setInterval] = useState<Interval>(Interval.I15M);
|
||||
const [chartType, setChartType] = useState<ChartType>(ChartType.CANDLE);
|
||||
const [overlays, setOverlays] = useState<Overlay[]>([]);
|
||||
const [studies, setStudies] = useState<Study[]>([]);
|
||||
|
||||
const dataSource = useMemo(() => {
|
||||
return new VegaDataSource(client, marketId, keypair?.pub);
|
||||
}, [client, marketId, keypair]);
|
||||
|
||||
return (
|
||||
<Chart dataSource={dataSource} interval={Interval.I15M} theme={theme} />
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="px-8 flex flex-row flex-wrap gap-8">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild={true}>
|
||||
<Button appendIconName="caret-down" variant="secondary">
|
||||
{t('Interval')}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuRadioGroup
|
||||
value={interval}
|
||||
onValueChange={(value) => {
|
||||
setInterval(value as Interval);
|
||||
}}
|
||||
>
|
||||
{Object.values(Interval).map((timeInterval) => (
|
||||
<DropdownMenuRadioItem
|
||||
key={timeInterval}
|
||||
inset
|
||||
value={timeInterval}
|
||||
>
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{intervalLabels[timeInterval]}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild={true}>
|
||||
<Button appendIconName="caret-down" variant="secondary">
|
||||
<Icon name={chartTypeIcon.get(chartType) as IconName} />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuRadioGroup
|
||||
value={chartType}
|
||||
onValueChange={(value) => {
|
||||
setChartType(value as ChartType);
|
||||
}}
|
||||
>
|
||||
{Object.values(ChartType).map((type) => (
|
||||
<DropdownMenuRadioItem key={type} inset value={type}>
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{chartTypeLabels[type]}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild={true}>
|
||||
<Button appendIconName="caret-down" variant="secondary">
|
||||
{t('Overlays')}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{Object.values(Overlay).map((overlay) => (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={overlay}
|
||||
checked={overlays.includes(overlay)}
|
||||
inset
|
||||
onCheckedChange={() => {
|
||||
const newOverlays = [...overlays];
|
||||
const index = overlays.findIndex((item) => item === overlay);
|
||||
|
||||
index !== -1
|
||||
? newOverlays.splice(index, 1)
|
||||
: newOverlays.push(overlay);
|
||||
|
||||
setOverlays(newOverlays);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{overlayLabels[overlay]}
|
||||
</DropdownMenuCheckboxItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild={true}>
|
||||
<Button appendIconName="caret-down" variant="secondary">
|
||||
{t('Studies')}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{Object.values(Study).map((study) => (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={study}
|
||||
inset
|
||||
checked={studies.includes(study)}
|
||||
onCheckedChange={() => {
|
||||
const newStudies = [...studies];
|
||||
const index = studies.findIndex((item) => item === study);
|
||||
|
||||
index !== -1
|
||||
? newStudies.splice(index, 1)
|
||||
: newStudies.push(study);
|
||||
|
||||
setStudies(newStudies);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{studyLabels[study]}
|
||||
</DropdownMenuCheckboxItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<Chart
|
||||
dataSource={dataSource}
|
||||
options={{
|
||||
chartType: chartType,
|
||||
overlays: overlays,
|
||||
studies: studies,
|
||||
}}
|
||||
interval={interval}
|
||||
theme={theme}
|
||||
onOptionsChanged={(options) => {
|
||||
setStudies(options.studies ?? []);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import type { ApolloClient } from '@apollo/client';
|
||||
import { gql } from '@apollo/client';
|
||||
import type { Candle, DataSource } from 'pennant';
|
||||
import { Interval } from 'pennant';
|
||||
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
import type { Chart, ChartVariables } from './__generated__/Chart';
|
||||
@ -12,6 +11,7 @@ import type {
|
||||
CandlesSubVariables,
|
||||
} from './__generated__/CandlesSub';
|
||||
import type { Subscription } from 'zen-observable-ts';
|
||||
import { Interval } from '@vegaprotocol/types';
|
||||
|
||||
export const CANDLE_FRAGMENT = gql`
|
||||
fragment CandleFields on Candle {
|
||||
|
@ -0,0 +1,93 @@
|
||||
import { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuItemIndicator,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from './dropdown-menu';
|
||||
import { Button } from '../button';
|
||||
import { Icon } from '../icon';
|
||||
|
||||
export default {
|
||||
title: 'DropdownMenu',
|
||||
} as ComponentMeta<typeof DropdownMenu>;
|
||||
|
||||
export const CheckboxItems = () => {
|
||||
const checkboxItems = [
|
||||
{ label: 'Bollinger bands', state: useState(false) },
|
||||
{ label: 'Envelope', state: useState(true) },
|
||||
{ label: 'EMA', state: useState(false) },
|
||||
{ label: 'Moving average', state: useState(false) },
|
||||
{ label: 'Price monitoring bands', state: useState(false) },
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: 'center', padding: 50 }}>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button appendIconName="chevron-down">Options</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{checkboxItems.map(({ label, state: [checked, setChecked] }) => (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={label}
|
||||
inset
|
||||
checked={checked}
|
||||
onCheckedChange={setChecked}
|
||||
>
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{label}
|
||||
</DropdownMenuCheckboxItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const RadioItems = () => {
|
||||
const files = ['README.md', 'index.js', 'page.css'];
|
||||
const [file, setFile] = useState(files[1]);
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: 'center', padding: 50 }}>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button appendIconName="chevron-down">Open</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem inset onSelect={() => console.log('minimize')}>
|
||||
Minimize window
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem inset onSelect={() => console.log('zoom')}>
|
||||
Zoom
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem inset onSelect={() => console.log('smaller')}>
|
||||
Smaller
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuRadioGroup value={file} onValueChange={setFile}>
|
||||
{files.map((file) => (
|
||||
<DropdownMenuRadioItem key={file} inset value={file}>
|
||||
{file}
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<p>Selected file: {file}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
145
libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx
Normal file
145
libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx
Normal file
@ -0,0 +1,145 @@
|
||||
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
||||
import classNames from 'classnames';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
const itemStyles = classNames([
|
||||
'text-ui',
|
||||
'text-black',
|
||||
'dark:text-white',
|
||||
'flex',
|
||||
'items-center',
|
||||
'justify-between',
|
||||
'leading-1',
|
||||
'cursor-default',
|
||||
'select-none',
|
||||
'whitespace-nowrap',
|
||||
'h-[25px]',
|
||||
'py-0',
|
||||
'pr-8',
|
||||
'color-black',
|
||||
]);
|
||||
|
||||
const itemClass = classNames(itemStyles, [
|
||||
'focus:bg-vega-yellow',
|
||||
'dark:focus:bg-vega-yellow',
|
||||
'focus:text-black',
|
||||
'dark:focus:text-black',
|
||||
'focus:outline-none',
|
||||
]);
|
||||
|
||||
function getItemClasses(inset: boolean) {
|
||||
return classNames(itemClass, inset ? 'pl-28' : 'pl-4', 'relative');
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the parts of a dropdown menu.
|
||||
*/
|
||||
export const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||
|
||||
/**
|
||||
* The button that toggles the dropdown menu.
|
||||
* By default, the {@link DropdownMenuContent} will position itself against the trigger.
|
||||
*/
|
||||
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
||||
|
||||
/**
|
||||
* Used to group multiple {@link DropdownMenuRadioItem}s.
|
||||
*/
|
||||
export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
||||
|
||||
/**
|
||||
* The component that pops out when the dropdown menu is open.
|
||||
*/
|
||||
export const DropdownMenuContent = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.Content>
|
||||
>(({ className, ...contentProps }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.Content
|
||||
{...contentProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(
|
||||
'inline-block box-border border-1 border-black bg-white dark:bg-black p-4',
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* The component that contains the dropdown menu items.
|
||||
*/
|
||||
export const DropdownMenuItem = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset = false, ...itemProps }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.Item
|
||||
{...itemProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(getItemClasses(inset), className)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* An item that can be controlled and rendered like a checkbox.
|
||||
*/
|
||||
export const DropdownMenuCheckboxItem = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset = false, ...checkboxItemProps }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
{...checkboxItemProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(getItemClasses(inset), className)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* An item that can be controlled and rendered like a radio.
|
||||
*/
|
||||
export const DropdownMenuRadioItem = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset = false, ...radioItemprops }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
{...radioItemprops}
|
||||
ref={forwardedRef}
|
||||
className={classNames(getItemClasses(inset), className)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* Renders when the parent {@link DropdownMenuCheckboxItem} or {@link DropdownMenuRadioItem} is checked.
|
||||
* You can style this element directly, or you can use it as a wrapper to put an icon into, or both.
|
||||
*/
|
||||
export const DropdownMenuItemIndicator = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.ItemIndicator>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.ItemIndicator>
|
||||
>(({ className, ...itemIndicatorProps }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.ItemIndicator
|
||||
{...itemIndicatorProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(
|
||||
'absolute inline-flex justify-center align-middle left-0 w-24',
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* Used to visually separate items in the dropdown menu.
|
||||
*/
|
||||
export const DropdownMenuSeparator = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.Separator>
|
||||
>(({ className, ...separatorProps }, forwardedRef) => (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
{...separatorProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames('h-px my-1 mx-2.5 bg-black', className)}
|
||||
/>
|
||||
));
|
1
libs/ui-toolkit/src/components/dropdown-menu/index.ts
Normal file
1
libs/ui-toolkit/src/components/dropdown-menu/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './dropdown-menu';
|
@ -5,6 +5,7 @@ export * from './callout';
|
||||
export * from './card';
|
||||
export * from './copy-with-tooltip';
|
||||
export * from './dialog';
|
||||
export * from './dropdown-menu';
|
||||
export * from './etherscan-link';
|
||||
export * from './form-group';
|
||||
export * from './icon';
|
||||
|
@ -22,6 +22,7 @@
|
||||
"@blueprintjs/select": "^3.16.6",
|
||||
"@nrwl/next": "13.10.3",
|
||||
"@radix-ui/react-dialog": "^0.1.5",
|
||||
"@radix-ui/react-dropdown-menu": "^0.1.6",
|
||||
"@radix-ui/react-tabs": "^0.1.5",
|
||||
"@radix-ui/react-tooltip": "^0.1.7",
|
||||
"@sentry/nextjs": "^6.19.3",
|
||||
@ -53,7 +54,7 @@
|
||||
"immer": "^9.0.12",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "^12.0.7",
|
||||
"pennant": "0.4.7",
|
||||
"pennant": "0.4.8",
|
||||
"postcss": "^8.4.6",
|
||||
"react": "17.0.2",
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
|
53
yarn.lock
53
yarn.lock
@ -3307,6 +3307,20 @@
|
||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
||||
|
||||
"@radix-ui/react-dropdown-menu@^0.1.6":
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz#3203229788cd57e552c9f19dcc7008e2b545919c"
|
||||
integrity sha512-RZhtzjWwJ4ZBN7D8ek4Zn+ilHzYuYta9yIxFnbC0pfqMnSi67IQNONo1tuuNqtFh9SRHacPKc65zo+kBBlxtdg==
|
||||
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-id" "0.1.5"
|
||||
"@radix-ui/react-menu" "0.1.6"
|
||||
"@radix-ui/react-primitive" "0.1.4"
|
||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||
|
||||
"@radix-ui/react-focus-guards@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-0.1.0.tgz#ba3b6f902cba7826569f8edc21ff8223dece7def"
|
||||
@ -3332,6 +3346,30 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||
|
||||
"@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"
|
||||
integrity sha512-ho3+bhpr3oAFkOBJ8VkUb1BcGoiZBB3OmcWPqa6i5RTUKrzNX/d6rauochu2xDlWjiRtpVuiAcsTVOeIC4FbYQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "0.1.0"
|
||||
"@radix-ui/react-collection" "0.1.4"
|
||||
"@radix-ui/react-compose-refs" "0.1.0"
|
||||
"@radix-ui/react-context" "0.1.1"
|
||||
"@radix-ui/react-dismissable-layer" "0.1.5"
|
||||
"@radix-ui/react-focus-guards" "0.1.0"
|
||||
"@radix-ui/react-focus-scope" "0.1.4"
|
||||
"@radix-ui/react-id" "0.1.5"
|
||||
"@radix-ui/react-popper" "0.1.4"
|
||||
"@radix-ui/react-portal" "0.1.4"
|
||||
"@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-callback-ref" "0.1.0"
|
||||
"@radix-ui/react-use-direction" "0.1.0"
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "^2.4.0"
|
||||
|
||||
"@radix-ui/react-popper@0.1.4":
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-0.1.4.tgz#dfc055dcd7dfae6a2eff7a70d333141d15a5d029"
|
||||
@ -3453,6 +3491,13 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||
|
||||
"@radix-ui/react-use-direction@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7"
|
||||
integrity sha512-NajpY/An9TCPSfOVkgWIdXJV+VuWl67PxB6kOKYmtNAFHvObzIoh8o0n9sAuwSAyFCZVq211FEf9gvVDRhOyiA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@radix-ui/react-use-escape-keydown@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz#dc80cb3753e9d1bd992adbad9a149fb6ea941874"
|
||||
@ -16634,10 +16679,10 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
|
||||
|
||||
pennant@0.4.7:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-0.4.7.tgz#b1541f57d563c8a14f026292f6f88c059938f31a"
|
||||
integrity sha512-HKpQS9wUMdH7aqdiOTwWwXAd2GhxKT1RF//f9utYhTuWFK5dK44EvWiaOTol+ddpN30GStK4KxO8s2OkeYLvPw==
|
||||
pennant@0.4.8:
|
||||
version "0.4.8"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-0.4.8.tgz#a19a5aa862621f1ac868a44c1e62fc4db1250d95"
|
||||
integrity sha512-/vk81reu4643Ol4C7sZ+SaJujpT8eHQmmETb/HmqzMR9pOY5rqMpOTzY5OMQO4SM8amvO40BkOaHt1HSnANcKA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@d3fc/d3fc-technical-indicator" "^8.0.1"
|
||||
|
Loading…
Reference in New Issue
Block a user