update to blueprintjs 5.x

This commit is contained in:
David Lechner
2023-06-28 14:42:55 -05:00
committed by David Lechner
parent 2fc3bea48f
commit 65e5627568
57 changed files with 369 additions and 889 deletions
+3 -3
View File
@@ -7,11 +7,11 @@
{
"name": "Launch Chrome",
"request": "launch",
"type": "pwa-chrome",
"type": "chrome",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"linux": {
"runtimeExecutable": "/usr/bin/chromium-browser"
"runtimeExecutable": "/usr/bin/google-chrome-stable"
}
},
{
@@ -29,7 +29,7 @@
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": ["<node_internals>/**"],
"type": "pwa-node"
"type": "node"
}
]
}
-4
View File
@@ -564,10 +564,6 @@ module.exports = function (webpackEnv) {
].filter(Boolean),
},
plugins: [
// https://github.com/palantir/blueprint/issues/2193
new webpack.NormalModuleReplacementPlugin(
/.*\/@blueprintjs\/icons\/lib\/esm\/iconSvgPaths.*/,
path.resolve(__dirname, "../src/blueprintjs-icons.js")),
new CopyPlugin({
patterns: [
{
+1 -3
View File
@@ -9,9 +9,7 @@
},
"dependencies": {
"@babel/core": "^7.22.5",
"@blueprintjs/core": "^4.20.2",
"@blueprintjs/popover2": "^1.14.11",
"@blueprintjs/select": "^4.9.24",
"@blueprintjs/core": "^5.0.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@pybricks/firmware": "7.5.0",
"@pybricks/ide-docs": "2.9.0",
+6 -3
View File
@@ -3,6 +3,7 @@
import './activities.scss';
import { Icon, Tab, Tabs } from '@blueprintjs/core';
import { Cog, Document } from '@blueprintjs/icons';
import React, { useCallback, useEffect, useRef } from 'react';
import Explorer from '../explorer/Explorer';
import Settings from '../settings/Settings';
@@ -114,8 +115,7 @@ const Activities: React.FunctionComponent = () => {
title={
<Icon
htmlTitle={i18n.translate('explorer')}
size={35}
icon="document"
icon={<Document size={35} />}
/>
}
panel={<Explorer />}
@@ -128,7 +128,10 @@ const Activities: React.FunctionComponent = () => {
className="pb-activities-tablist-tab"
id={Activity.Settings}
title={
<Icon htmlTitle={i18n.translate('settings')} size={35} icon="cog" />
<Icon
htmlTitle={i18n.translate('settings')}
icon={<Cog size={35} />}
/>
}
panel={<Settings />}
panelClassName="pb-activities-tabview"
+5 -4
View File
@@ -10,6 +10,7 @@ import {
Intent,
Pre,
} from '@blueprintjs/core';
import { ChevronDown, ChevronRight, Duplicate, Error, Virus } from '@blueprintjs/icons';
import React, { useState } from 'react';
import { useId } from 'react-aria';
import type { CreateToast } from '../toasterTypes';
@@ -37,7 +38,7 @@ const UnexpectedErrorAlert: React.FunctionComponent<UnexpectedErrorAlertProps> =
aria-labelledby={labelId}
minimal={true}
small={true}
icon={isExpanded ? 'chevron-down' : 'chevron-right'}
icon={isExpanded ? <ChevronDown /> : <ChevronRight />}
onClick={() => setIsExpanded((v) => !v)}
/>
<span id={labelId}>{i18n.translate('technicalInfo')}</span>
@@ -51,7 +52,7 @@ const UnexpectedErrorAlert: React.FunctionComponent<UnexpectedErrorAlertProps> =
<ButtonGroup minimal={true} fill={true}>
<Button
intent={Intent.DANGER}
icon="duplicate"
icon={<Duplicate />}
onClick={() =>
navigator.clipboard.writeText(
`\`\`\`\n${error.stack || error.message}\n\`\`\``,
@@ -62,7 +63,7 @@ const UnexpectedErrorAlert: React.FunctionComponent<UnexpectedErrorAlertProps> =
</Button>
<AnchorButton
intent={Intent.DANGER}
icon="virus"
icon={<Virus />}
href={`https://github.com/pybricks/support/issues?q=${encodeURIComponent(
'is:issue',
)}+${encodeURIComponent(error.message)}`}
@@ -82,7 +83,7 @@ export const unexpectedError: CreateToast<{ error: Error }> = (
{ error },
) => ({
message: <UnexpectedErrorAlert error={error} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+5 -5
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
// Copyright (c) 2022-2023 The Pybricks Authors
import { IToastOptions, ToastProps, ToasterInstance } from '@blueprintjs/core';
import { ToastOptions, ToastProps, Toaster } from '@blueprintjs/core';
import { waitFor } from '@testing-library/dom';
import { AsyncSaga } from '../../test';
import { alertsDidShowAlert, alertsShowAlert } from './actions';
@@ -11,10 +11,10 @@ afterEach(() => {
jest.clearAllMocks();
});
class TestToaster implements ToasterInstance {
private toasts = new Array<IToastOptions>();
class TestToaster implements Toaster {
private toasts = new Array<ToastOptions>();
public getToasts(): IToastOptions[] {
public getToasts(): ToastOptions[] {
return this.toasts;
}
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -13,7 +14,7 @@ const UpdateServerFailure: React.FunctionComponent = () => {
export const updateServerFailure: CreateToast = (onAction) => ({
message: <UpdateServerFailure />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -19,7 +20,7 @@ const BluetoothNotAvailable: React.FunctionComponent = () => {
export const bluetoothNotAvailable: CreateToast = (onAction) => ({
message: <BluetoothNotAvailable />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -13,7 +14,7 @@ const Disconnected: React.FunctionComponent = () => {
export const disconnected: CreateToast = (onAction) => ({
message: <Disconnected />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -27,7 +28,7 @@ const MissingService: React.FunctionComponent<MissingServiceProps> = ({
export const missingService: CreateToast<MissingServiceProps> = (onAction, props) => ({
message: <MissingService {...props} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { WarningSign } from '@blueprintjs/icons';
import React from 'react';
import { appName } from '../../app/constants';
import type { CreateToast } from '../../toasterTypes';
@@ -43,7 +44,7 @@ export const newPybricksProfile: CreateToast<NewPybricksProfileProps> = (
props,
) => ({
message: <NewPybricksProfile {...props} />,
icon: 'warning-sign',
icon: <WarningSign />,
intent: Intent.WARNING,
timeout: 15000, // long message, need more time to read
onDismiss: () => onAction('dismiss'),
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -13,7 +14,7 @@ const NoGatt: React.FunctionComponent = () => {
export const noGatt: CreateToast = (onAction) => ({
message: <NoGatt />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+4 -3
View File
@@ -3,6 +3,7 @@
import './index.scss';
import { AnchorButton, Button, Intent } from '@blueprintjs/core';
import { Download, Help, InfoSign } from '@blueprintjs/icons';
import React from 'react';
import { pybricksBluetoothTroubleshootingUrl } from '../../app/constants';
import ExternalLinkIcon from '../../components/ExternalLinkIcon';
@@ -21,11 +22,11 @@ const NoHub: React.FunctionComponent<NoHubProps> = ({ onFlashFirmware }) => {
<p>{i18n.translate('noHub.message')}</p>
<p>{i18n.translate('noHub.suggestion')}</p>
<div className="pb-ble-alerts-buttons">
<Button icon="download" onClick={onFlashFirmware}>
<Button icon={<Download />} onClick={onFlashFirmware}>
{i18n.translate('noHub.flashFirmwareButton')}
</Button>
<AnchorButton
icon="help"
icon={<Help />}
href={pybricksBluetoothTroubleshootingUrl}
target="_blank"
rel="noopener"
@@ -40,7 +41,7 @@ const NoHub: React.FunctionComponent<NoHubProps> = ({ onFlashFirmware }) => {
export const noHub: CreateToast<never, 'dismiss' | 'flashFirmware'> = (onAction) => ({
message: <NoHub onFlashFirmware={() => onAction('flashFirmware')} />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
timeout: 15000,
onDismiss: () => onAction('dismiss'),
+3 -2
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Button, Code, Intent } from '@blueprintjs/core';
import { Duplicate, Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { isIOS, isLinux } from '../../utils/os';
@@ -23,7 +24,7 @@ const NoWebBluetooth: React.FunctionComponent = () => {
chrome://flags/#enable-experimental-web-platform-features
</Code>
<Button
icon="duplicate"
icon={<Duplicate />}
small={true}
minimal={true}
onClick={() =>
@@ -41,7 +42,7 @@ const NoWebBluetooth: React.FunctionComponent = () => {
export const noWebBluetooth: CreateToast = (onAction) => ({
message: <NoWebBluetooth />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+3 -2
View File
@@ -3,6 +3,7 @@
import './index.scss';
import { Button, Intent } from '@blueprintjs/core';
import { Download, InfoSign } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -20,7 +21,7 @@ const OldFirmware: React.FunctionComponent<OldFirmwareProps> = ({
<>
<p>{i18n.translate('oldFirmware.message')}</p>
<div className="pb-ble-alerts-buttons">
<Button icon="download" onClick={onFlashFirmware}>
<Button icon={<Download />} onClick={onFlashFirmware}>
{i18n.translate('oldFirmware.flashFirmware.label')}
</Button>
</div>
@@ -32,7 +33,7 @@ export const oldFirmware: CreateToast<never, 'dismiss' | 'flashFirmware'> = (
onAction,
) => ({
message: <OldFirmware onFlashFirmware={() => onAction('flashFirmware')} />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
onDismiss: () => onAction('dismiss'),
});
-105
View File
@@ -1,105 +0,0 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
// HACK: Prevent webpack from picking up all icons.
// https://github.com/palantir/blueprint/issues/2193
// istanbul ignore file
import {
Add,
Archive,
Blank,
Chat,
ChevronDown,
ChevronRight,
Clipboard,
Code,
Cog,
Cross,
Disable,
Document,
Download,
Duplicate,
Edit,
Error,
Export,
Heart,
Help,
Import,
InfoSign,
Lightbulb,
Manual,
Play,
Plus,
Redo,
Refresh,
Share,
Tick,
TickCircle,
Trash,
Undo,
Virus,
WarningSign,
} from '@blueprintjs/icons/lib/esm/generated-icons/16px/paths';
import {
Cog as Cog20,
Document as Document20,
Error as Error20,
InfoSign as InfoSign20,
Manual as Manual20,
Trash as Trash20,
WarningSign as WarningSign20,
} from '@blueprintjs/icons/lib/esm/generated-icons/20px/paths';
import { pascalCase } from 'change-case';
export function iconNameToPathsRecordKey(name) {
return pascalCase(name);
}
export const IconSvgPaths16 = {
Add,
Archive,
Blank,
Chat,
ChevronDown,
ChevronRight,
Clipboard,
Code,
Cog,
Cross,
Disable,
Document,
Download,
Duplicate,
Edit,
Error,
Export,
Heart,
Help,
Import,
InfoSign,
Lightbulb,
Manual,
Play,
Plus,
Redo,
Refresh,
Share,
Tick,
TickCircle,
Trash,
Undo,
Virus,
WarningSign,
};
export const IconSvgPaths20 = {
Cog: Cog20,
Document: Document20,
Error: Error20,
InfoSign: InfoSign20,
Manual: Manual20,
Trash: Trash20,
WarningSign: WarningSign20,
};
+3 -3
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022-2023 The Pybricks Authors
import { Classes, Icon, IconName, IconSize, Spinner } from '@blueprintjs/core';
import { Classes, Icon, IconSize, Spinner } from '@blueprintjs/core';
import { mergeRefs, useId } from '@react-aria/utils';
import classNames from 'classnames';
import React, { useRef } from 'react';
@@ -21,7 +21,7 @@ type ButtonProps = {
/** When true, the button will use the {@link Classes.MINIMAL} style. */
minimal?: boolean;
/** Icon that will be displayed to the left of the button content. */
icon: IconName;
icon: JSX.Element;
/** A reference to the underlying <button> HTML element. */
elementRef?: React.ForwardedRef<HTMLButtonElement>;
/** Called when the button is pressed. */
@@ -78,7 +78,7 @@ export const Button: React.FunctionComponent<ButtonProps> = ({
/>
) : (
<>
<Icon icon={icon} aria-hidden />
<Icon icon={icon} />
{isLabelVisible && (
<span id={labelId} className={Classes.BUTTON_TEXT}>
{label}
+4 -4
View File
@@ -3,17 +3,17 @@
// Icon for indicating external links
import { Icon } from '@blueprintjs/core';
import React from 'react';
import './clipboard.scss';
import { Icon } from '@blueprintjs/core';
import { Duplicate } from '@blueprintjs/icons';
import React from 'react';
const ClipboardIcon: React.FunctionComponent = () => {
return (
<span className="pb-clipboard">
&nbsp;
<sup>
<Icon icon="duplicate" iconSize={12} />
<Icon icon={<Duplicate size={12} />} />
</sup>
</span>
);
+4 -4
View File
@@ -3,17 +3,17 @@
// Icon for indicating external links
import { Icon } from '@blueprintjs/core';
import React from 'react';
import './external-link.scss';
import { Icon } from '@blueprintjs/core';
import { Share } from '@blueprintjs/icons';
import React from 'react';
const ExternalLinkIcon: React.FunctionComponent = () => {
return (
<span className="pb-external-link">
&nbsp;
<sup>
<Icon icon="share" iconSize={12} />
<Icon icon={<Share size={12} />} />
</sup>
</span>
);
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Classes } from '@blueprintjs/core';
import { Help } from '@blueprintjs/icons';
import React, { useCallback, useEffect, useState } from 'react';
import { OverlayContainer } from 'react-aria';
import { useBoolean } from 'usehooks-ts';
@@ -55,7 +56,7 @@ const HelpButton: React.FunctionComponent<HelpButtonProps> = ({
helpForLabel,
})}
minimal
icon="help"
icon={<Help />}
elementRef={setOpenButton}
onPress={setIsDialogOpenTrue}
/>
+3 -3
View File
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
// Copyright (c) 2022-2023 The Pybricks Authors
@use '@blueprintjs/core/lib/scss/variables' as bp;
.#{bp.$ns}-popover2-open.#{bp.$ns}-popover2-placement-right {
.#{bp.$ns}-popover-open.#{bp.$ns}-popover-placement-right {
animation: open-right 0.25s;
}
.#{bp.$ns}-popover2-close.#{bp.$ns}-popover2-placement-right {
.#{bp.$ns}-popover-close.#{bp.$ns}-popover-placement-right {
animation: close-right 0.25s;
}
+9 -15
View File
@@ -3,11 +3,10 @@
import './HelpDialog.scss';
import { Classes } from '@blueprintjs/core';
import { Classes as Classes2 } from '@blueprintjs/popover2';
import {
POPOVER_ARROW_SVG_SIZE,
Popover2Arrow,
} from '@blueprintjs/popover2/lib/cjs/popover2Arrow';
PopoverArrow,
} from '@blueprintjs/core/lib/cjs/components/popover/popoverArrow';
import classNames from 'classnames';
import React, { PropsWithChildren, useEffect, useMemo, useRef, useState } from 'react';
import {
@@ -88,11 +87,6 @@ const HelpDialog: React.FunctionComponent<PropsWithChildren<HelpDialogProps>> =
),
);
// HACK: workaround https://github.com/palantir/blueprint/pull/5302
useEffect(() => {
arrow?.setAttribute('aria-hidden', 'true');
}, [arrow]);
// HACK: since there are not keyboard focusable elements for autoFocus
// we have to manually focus the only focusable element in the dialog,
// otherwise the FocusScope doesn't work.
@@ -110,7 +104,7 @@ const HelpDialog: React.FunctionComponent<PropsWithChildren<HelpDialogProps>> =
<div className={Classes.OVERLAY_BACKDROP} {...underlayProps}>
<div
className={classNames(
Classes2.POPOVER2_TRANSITION_CONTAINER,
Classes.POPOVER_TRANSITION_CONTAINER,
Classes.OVERLAY_CONTENT,
)}
ref={setPopperElement}
@@ -119,14 +113,14 @@ const HelpDialog: React.FunctionComponent<PropsWithChildren<HelpDialogProps>> =
>
<div
className={classNames(
Classes2.POPOVER2,
`${Classes2.POPOVER2}-${isOpen ? 'open' : 'close'}`,
`${Classes2.POPOVER2_CONTENT_PLACEMENT}-right`,
Classes2.POPOVER2_CONTENT_SIZING,
Classes.POPOVER,
`${Classes.POPOVER}-${isOpen ? 'open' : 'close'}`,
`${Classes.POPOVER_CONTENT_PLACEMENT}-right`,
Classes.POPOVER_CONTENT_SIZING,
)}
onAnimationEnd={onAnimationEnd}
>
<Popover2Arrow
<PopoverArrow
arrowProps={{ ref: setArrow, style: styles.arrow }}
placement={state?.placement ?? 'auto'}
/>
@@ -141,7 +135,7 @@ const HelpDialog: React.FunctionComponent<PropsWithChildren<HelpDialogProps>> =
// clicking anywhere in the dialog closes it
onClick={onClose}
>
<div id={descId} className={Classes2.POPOVER2_CONTENT}>
<div id={descId} className={Classes.POPOVER_CONTENT}>
{children}
</div>
<DismissButton
+5 -10
View File
@@ -2,7 +2,7 @@
// Copyright (c) 2021-2023 The Pybricks Authors
import { Classes } from '@blueprintjs/core';
import { act, cleanup, fireEvent, waitFor } from '@testing-library/react';
import { act, cleanup, waitFor } from '@testing-library/react';
import * as monaco from 'monaco-editor';
import React from 'react';
import { testRender, uuid } from '../../test';
@@ -130,15 +130,10 @@ describe('Editor', () => {
editor.queryByRole('menu', { name: 'Editor context menu' }),
).toBeNull();
// HACK: monaco editor uses deprecated event fields (keyCode),
// so regular userEvent.type() doesn't work. testing library
// doesn't have ContextMenu in its keymap either.
fireEvent(
editor.getByRole('textbox', { name: /^Editor content/ }),
new KeyboardEvent('keydown', {
key: 'ContextMenu',
code: 'ContextMenu',
keyCode: 93,
await act(() =>
user.pointer({
keys: '[MouseRight]',
target: editor.getByRole('textbox', { name: /^Editor content/ }),
}),
);
+25 -16
View File
@@ -5,17 +5,26 @@ import './editor.scss';
import {
Button,
Classes,
IOverlayLifecycleProps,
IconName,
ContextMenu,
Menu,
MenuDivider,
MenuItem,
OverlayLifecycleProps,
ResizeSensor,
Tab,
TabId,
Tabs,
Text,
} from '@blueprintjs/core';
import { ContextMenu2, ResizeSensor2 } from '@blueprintjs/popover2';
import {
Blank,
Clipboard,
Cross,
Duplicate,
Manual,
Redo,
Undo,
} from '@blueprintjs/icons';
import classNames from 'classnames';
import * as monaco from 'monaco-editor';
import tomorrowNightEightiesTheme from 'monaco-themes/themes/Tomorrow-Night-Eighties.json';
@@ -76,7 +85,7 @@ type EditorContextMenuItemProps = Readonly<{
/** The menu item label. */
label: string;
/** The menu item icon. */
icon: IconName;
icon: JSX.Element;
/** The keyboard shortcut that triggers the same action. */
keyboardShortcut: string;
/** Controls the menu item disabled state. */
@@ -134,7 +143,7 @@ const EditorContextMenu: React.FunctionComponent<EditorContextMenuProps> = ({
<Menu aria-label={i18n.translate('contextMenu.label')} role="menu">
<EditorContextMenuItem
label={i18n.translate('copy')}
icon="duplicate"
icon={<Duplicate />}
keyboardShortcut={isMacOS() ? 'Cmd-C' : 'Ctrl-C'}
disabled={!hasSelection}
editor={editor}
@@ -142,7 +151,7 @@ const EditorContextMenu: React.FunctionComponent<EditorContextMenuProps> = ({
/>
<EditorContextMenuItem
label={i18n.translate('paste')}
icon="clipboard"
icon={<Clipboard />}
keyboardShortcut={isMacOS() ? 'Cmd-V' : 'Ctrl-V'}
disabled={!model}
editor={editor}
@@ -150,7 +159,7 @@ const EditorContextMenu: React.FunctionComponent<EditorContextMenuProps> = ({
/>
<EditorContextMenuItem
label={i18n.translate('selectAll')}
icon="blank"
icon={<Blank />}
keyboardShortcut={isMacOS() ? 'Cmd-A' : 'Ctrl-A'}
disabled={!model}
editor={editor}
@@ -159,7 +168,7 @@ const EditorContextMenu: React.FunctionComponent<EditorContextMenuProps> = ({
<MenuDivider />
<EditorContextMenuItem
label={i18n.translate('undo')}
icon="undo"
icon={<Undo />}
keyboardShortcut={isMacOS() ? 'Cmd-Z' : 'Ctrl-Z'}
disabled={!canUndo}
editor={editor}
@@ -167,7 +176,7 @@ const EditorContextMenu: React.FunctionComponent<EditorContextMenuProps> = ({
/>
<EditorContextMenuItem
label={i18n.translate('redo')}
icon="redo"
icon={<Redo />}
keyboardShortcut={isMacOS() ? 'Cmd-Shift-Z' : 'Ctrl-Shift-Z'}
disabled={!canRedo}
editor={editor}
@@ -221,7 +230,7 @@ const TabCloseButton: React.FunctionComponent<TabCloseButtonProps> = ({ uuid })
})}
minimal={true}
small={true}
icon="cross"
icon={<Cross />}
// tabs are closed with delete button by keyboard, so
// don't focus the close button
tabIndex={-1}
@@ -440,7 +449,7 @@ const Editor: React.FunctionComponent = () => {
[],
);
const popoverProps = useMemo<IOverlayLifecycleProps>(
const popoverProps = useMemo<OverlayLifecycleProps>(
() => ({
onOpened: (e) => {
// a11y: focus the first item in the menu when the menu opens
@@ -497,8 +506,8 @@ const Editor: React.FunctionComponent = () => {
return (
<div className="pb-editor">
<EditorTabs onChange={() => editor?.focus()} />
<ResizeSensor2 onResize={() => editor?.layout()}>
<ContextMenu2
<ResizeSensor onResize={() => editor?.layout()}>
<ContextMenu
className={classNames('pb-editor-tabpanel', isEmpty && 'pb-empty')}
role="tabpanel"
aria-label={isEmpty ? i18n.translate('welcome') : fileName}
@@ -510,13 +519,13 @@ const Editor: React.FunctionComponent = () => {
>
<Welcome isVisible={isEmpty} />
<div className="pb-editor-monaco" ref={editorRef} />
</ContextMenu2>
</ResizeSensor2>
</ContextMenu>
</ResizeSensor>
<Button
className="pb-editor-doc-button"
minimal
large
icon="manual"
icon={<Manual />}
title={
isSettingShowDocsEnabled
? i18n.translate('docs.hide')
+2 -2
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2022 The Pybricks Authors
// Copyright (c) 2020-2023 The Pybricks Authors
// Custom styling for the Editor control.
@@ -30,7 +30,7 @@
overflow-x: auto;
@include pb.background-contrast(6%);
.bp4-tab-list > * {
.#{bp.$ns}-tab-list > * {
padding-left: bp.$pt-grid-size * 1.5;
&:not(:last-child) {
+2
View File
@@ -226,6 +226,8 @@ describe('tree item', () => {
const treeItem = explorer.getByRole('treeitem', { name: 'test.file' });
await act(() => user.click(treeItem));
dispatch.mockClear();
await act(() => user.keyboard('{Delete}'));
expect(dispatch).toHaveBeenCalledWith(
+21 -11
View File
@@ -7,11 +7,21 @@ import './explorer.scss';
import {
Button,
ButtonGroup,
Classes,
Divider,
HotkeyConfig,
IconName,
useHotkeys,
} from '@blueprintjs/core';
import {
Archive,
Document,
Duplicate,
Edit,
Export,
Import,
Plus,
Trash,
} from '@blueprintjs/icons';
import React, {
MouseEventHandler,
useCallback,
@@ -64,7 +74,7 @@ type ActionButtonProps = {
/** The DOM id for this instance. */
id: string;
/** The icon to use for the button. */
icon: IconName;
icon: JSX.Element;
/** The tooltip/title text. */
tooltip: string;
/** Callback for button click event. */
@@ -134,13 +144,13 @@ const FileActionButtonGroup: React.FunctionComponent<ActionButtonGroupProps> = (
>
<ActionButton
id={renameButtonId}
icon="edit"
icon={<Edit />}
tooltip={i18n.translate('treeItem.renameTooltip', { fileName })}
onClick={() => dispatch(explorerRenameFile(fileName))}
/>
<ActionButton
id={duplicateButtonId}
icon="duplicate"
icon={<Duplicate />}
tooltip={i18n.translate('treeItem.duplicateTooltip', {
fileName,
})}
@@ -153,13 +163,13 @@ const FileActionButtonGroup: React.FunctionComponent<ActionButtonGroupProps> = (
// and it also matches the direction of the arrow on the
// archive icon which is also used to indicate an export/
// download operation
icon="import"
icon={<Import />}
tooltip={i18n.translate('treeItem.exportTooltip', { fileName })}
onClick={() => dispatch(explorerExportFile(fileName))}
/>
<ActionButton
id={deleteButtonId}
icon="trash"
icon={<Trash />}
tooltip={i18n.translate('treeItem.deleteTooltip', { fileName })}
onClick={() =>
dispatch(explorerDeleteFile(fileName, item.index as UUID))
@@ -188,7 +198,7 @@ const Header: React.FunctionComponent = () => {
<ButtonGroup minimal={true}>
<ActionButton
id={archiveButtonId}
icon="archive"
icon={<Archive />}
tooltip={i18n.translate('header.toolbar.exportAll')}
onClick={() => dispatch(explorerArchiveAllFiles())}
/>
@@ -197,13 +207,13 @@ const Header: React.FunctionComponent = () => {
// NB: the "export" icon has an arrow pointing up, which is
// what we want here since import is analogous to upload
// even though this is the "import" action
icon="export"
icon={<Export />}
tooltip={i18n.translate('header.toolbar.import')}
onClick={() => dispatch(explorerImportFiles())}
/>
<ActionButton
id={newButtonId}
icon="plus"
icon={<Plus />}
tooltip={i18n.translate('header.toolbar.addNew')}
onClick={() => dispatch(explorerCreateNewFile())}
/>
@@ -322,7 +332,7 @@ const TreeContainer: React.FunctionComponent<RenderProps<'renderTreeContainer'>>
onKeyDown: handleDuplicateKeyDown,
},
{
combo: 'del',
combo: 'delete',
label: 'Delete',
disabled: !hotKeyActive,
preventDefault: true,
@@ -372,7 +382,7 @@ const FileTree: React.FunctionComponent = () => {
index,
data: {
fileName: file.path,
icon: 'document',
icon: <Document className={Classes.TREE_NODE_ICON} />,
secondaryLabel: (
<TreeItemContext.Consumer>
{(item) => <FileActionButtonGroup item={item} />}
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -20,7 +21,7 @@ export const fileInUse: CreateToast<{ fileName: string }> = (
{ fileName },
) => ({
message: <FileInUseAlert fileName={fileName} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+3 -2
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Icon, Intent } from '@blueprintjs/core';
import { InfoSign, Plus } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -11,7 +12,7 @@ const NoFilesToBackup: React.FunctionComponent = () => {
return (
<>
{i18n.translate('noFilesToBackup.message', {
icon: <Icon icon="plus" />,
icon: <Icon icon={<Plus />} />,
})}
</>
);
@@ -19,7 +20,7 @@ const NoFilesToBackup: React.FunctionComponent = () => {
export const noFilesToBackup: CreateToast = (onAction) => ({
message: <NoFilesToBackup />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { InfoSign } from '@blueprintjs/icons';
import React from 'react';
import { pythonFileExtension } from '../../pybricksMicropython/lib';
import type { CreateToast } from '../../toasterTypes';
@@ -21,7 +22,7 @@ const NoPyFiles: React.FunctionComponent = () => {
export const noPyFiles: CreateToast = (onAction) => ({
message: <NoPyFiles />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
onDismiss: () => onAction('dismiss'),
});
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Alert, Classes, Intent } from '@blueprintjs/core';
import { Trash } from '@blueprintjs/icons';
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { useSelector } from '../../reducers';
@@ -35,7 +36,7 @@ const DeleteFileAlert: React.FunctionComponent = () => {
canEscapeKeyCancel={true}
canOutsideClickCancel={true}
isOpen={isOpen}
icon="trash"
icon={<Trash />}
intent={Intent.DANGER}
confirmButtonText={i18n.translate('action.accept')}
cancelButtonText={i18n.translate('action.cancel')}
+2 -1
View File
@@ -10,6 +10,7 @@ import {
Switch,
Text,
} from '@blueprintjs/core';
import { Plus } from '@blueprintjs/icons';
import React, { useCallback, useRef, useState } from 'react';
import { useId } from 'react-aria';
import { useDispatch } from 'react-redux';
@@ -69,7 +70,7 @@ const NewFileWizard: React.FunctionComponent = () => {
return (
<Dialog
icon="plus"
icon={<Plus />}
title={i18n.translate('title')}
isOpen={isOpen}
onOpening={() => setFileName('')}
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Button, Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -25,7 +26,7 @@ const DfuError: React.FunctionComponent<DfuErrorProps> = ({ onTryAgain }) => {
export const dfuError: CreateToast<never, 'dismiss' | 'tryAgain'> = (onAction) => ({
message: <DfuError onTryAgain={() => onAction('tryAgain')} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent, ProgressBar } from '@blueprintjs/core';
import { Download } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -42,7 +43,7 @@ const FlashProgress: React.FunctionComponent<FlashProgressProps> = ({
export const flashProgress: CreateToast<FlashProgressProps> = (onAction, props) => ({
message: <FlashProgress {...props} />,
icon: 'download',
icon: <Download />,
intent: Intent.PRIMARY,
// close one second after progress is complete
timeout: (props.progress ?? 0) < 1 ? 0 : 1000,
+5 -4
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { AnchorButton, Button, Intent } from '@blueprintjs/core';
import { Download, Help, InfoSign } from '@blueprintjs/icons';
import React from 'react';
import {
pybricksUsbDfuTroubleshootingUrl,
@@ -29,13 +30,13 @@ const NoDfuHub: React.FunctionComponent<NoDfuHubProps> = ({
{isLinux() && <p>{i18n.translate('noDfuHub.suggestion1.linux')}</p>}
<div className="pb-ble-alerts-buttons">
{isWindows() && (
<Button icon="download" onClick={onInstallWindowsDriver}>
<Button icon={<Download />} onClick={onInstallWindowsDriver}>
{i18n.translate('noDfuHub.installUsbDriverButton')}
</Button>
)}
{isLinux() && (
<AnchorButton
icon="help"
icon={<Help />}
href={pybricksUsbLinuxUdevRulesUrl}
target="_blank"
rel="noopener"
@@ -45,7 +46,7 @@ const NoDfuHub: React.FunctionComponent<NoDfuHubProps> = ({
</AnchorButton>
)}
<AnchorButton
icon="help"
icon={<Help />}
href={pybricksUsbDfuTroubleshootingUrl}
target="_blank"
rel="noopener"
@@ -64,7 +65,7 @@ export const noDfuHub: CreateToast<never, 'dismiss' | 'installWindowsDriver'> =
message: (
<NoDfuHub onInstallWindowsDriver={() => onAction('installWindowsDriver')} />
),
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -13,7 +14,7 @@ const NoDfuInterface: React.FunctionComponent = () => {
export const noDfuInterface: CreateToast = (onAction) => ({
message: <NoDfuInterface />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -18,7 +19,7 @@ const NoWebUsb: React.FunctionComponent = () => {
export const noWebUsb: CreateToast = (onAction) => ({
message: <NoWebUsb />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { InfoSign } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -13,7 +14,7 @@ const ReleaseButton: React.FunctionComponent = () => {
export const releaseButton: CreateToast = (onAction) => ({
message: <ReleaseButton />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
onDismiss: () => onAction('dismiss'),
});
@@ -3,6 +3,7 @@
import './bootloaderInstructions.scss';
import { Callout, Intent } from '@blueprintjs/core';
import { WarningSign } from '@blueprintjs/icons';
import classNames from 'classnames';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
@@ -370,7 +371,7 @@ const BootloaderInstructions: React.FunctionComponent<BootloaderInstructionsProp
)}
{hubHasUSB(hubType) && isLinux() && (
<Callout intent={Intent.WARNING} icon="warning-sign">
<Callout intent={Intent.WARNING} icon={<WarningSign />}>
{i18n.translate('warning.linux.message', {
learnMore: (
<>
@@ -389,7 +390,7 @@ const BootloaderInstructions: React.FunctionComponent<BootloaderInstructionsProp
)}
{hubHasUSB(hubType) && isWindows() && (
<Callout intent={Intent.WARNING} icon="warning-sign">
<Callout intent={Intent.WARNING} icon={<WarningSign />}>
{i18n.translate('warning.windows.message', {
instructions: (
<a
@@ -15,10 +15,11 @@ import {
Intent,
MultistepDialog,
NonIdealState,
Popover,
Pre,
Spinner,
} from '@blueprintjs/core';
import { Classes as Classes2, Popover2 } from '@blueprintjs/popover2';
import { ChevronDown, ChevronRight, Error, Heart } from '@blueprintjs/icons';
import { FirmwareMetadata, HubType } from '@pybricks/firmware';
import { fileOpen } from 'browser-fs-access';
import classNames from 'classnames';
@@ -124,7 +125,7 @@ const UnsupportedHubs: React.FunctionComponent = () => {
'selectHubPanel.notOnListButton.info.mindstorms.help.sponsor',
)}
</VisuallyHidden>
<Icon icon="heart" />
<Icon icon={<Heart />} />
</>
),
},
@@ -282,13 +283,13 @@ const SelectHubPanel: React.FunctionComponent<SelectHubPanelProps> = ({
<>
<p>{i18n.translate('selectHubPanel.message')}</p>
<HubPicker />
<Popover2
popoverClassName={Classes2.POPOVER2_CONTENT_SIZING}
<Popover
popoverClassName={Classes.POPOVER_CONTENT_SIZING}
placement="right-end"
content={<UnsupportedHubs />}
renderTarget={({ isOpen: _isOpen, ref, ...targetProps }) => (
<Button
elementRef={ref as React.Ref<HTMLButtonElement>}
ref={ref as React.Ref<HTMLButtonElement>}
{...targetProps}
>
{i18n.translate('selectHubPanel.notOnListButton.label')}
@@ -301,7 +302,7 @@ const SelectHubPanel: React.FunctionComponent<SelectHubPanelProps> = ({
<Button
minimal={true}
small={true}
icon={isAdvancedOpen ? 'chevron-down' : 'chevron-right'}
icon={isAdvancedOpen ? <ChevronDown /> : <ChevronRight />}
onClick={() => setIsAdvancedOpen((v) => !v)}
>
{i18n.translate('selectHubPanel.advanced.label')}
@@ -360,7 +361,7 @@ const AcceptLicensePanel: React.FunctionComponent<AcceptLicensePanelProps> = ({
<Pre>{selectedFirmwareData.licenseText}</Pre>
) : (
<NonIdealState
icon={selectedFirmwareError ? 'error' : <Spinner />}
icon={selectedFirmwareError ? <Error /> : <Spinner />}
description={
selectedFirmwareError
? i18n.translate('licensePanel.licenseText.error')
@@ -411,7 +412,7 @@ const ConfigureOptionsPanel: React.FunctionComponent<SelectOptionsPanelProps> =
rightElement={
isHubNameValid ? undefined : (
<Icon
icon="error"
icon={<Error />}
intent={Intent.DANGER}
tagName="div"
/>
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { Error } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -36,7 +37,7 @@ export const userProgramSize: CreateToast<UserProgramSizeProps> = (
props,
) => ({
message: <UserProgramSize {...props} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
});
+1 -2
View File
@@ -4,7 +4,6 @@
// css files
@use 'normalize.css/normalize';
@use '@blueprintjs/core/lib/css/blueprint';
@use '@blueprintjs/popover2/lib/css/blueprint-popover2';
// sass files
@use 'sass:color';
@@ -167,7 +166,7 @@ a.#{bp.$ns}-button {
}
// make disabled:checked radio buttons appear as not checked
&.#{bp.$ns}-radio input:disabled:checked ~ .bp4-control-indicator {
&.#{bp.$ns}-radio input:disabled:checked ~ .#{bp.$ns}-control-indicator {
// color definition is same as $minimal-button-background-color-hover,
// which is used to define $control-background-color-disabled and
// $dark-control-background-color-disabled variables
+2 -1
View File
@@ -14,6 +14,7 @@ import {
Spinner,
Text,
} from '@blueprintjs/core';
import { InfoSign } from '@blueprintjs/icons';
import { Item } from '@react-stately/collections';
import { ListProps, ListState, useListState } from '@react-stately/list';
import type { Node, Selection } from '@react-types/shared';
@@ -244,7 +245,7 @@ const LicenseDialog: React.FunctionComponent<LicenseDialogProps> = ({
onClose={onClose}
>
<div className={Classes.DIALOG_BODY}>
<Callout className={Classes.INTENT_PRIMARY} icon="info-sign">
<Callout className={Classes.INTENT_PRIMARY} icon={<InfoSign />}>
{i18n.translate('description', {
name: appName,
})}
+6 -2
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Button, Intent } from '@blueprintjs/core';
import { Code, Error } from '@blueprintjs/icons';
import React, { useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { editorGoto } from '../../editor/actions';
@@ -36,7 +37,10 @@ const CompilerError: React.FunctionComponent<CompilerErrorProps> = ({ error }) =
<p>{i18n.translate('compilerError.message')}</p>
<pre className="pb-mpy-alerts-compile-error">{error.join('\n')}</pre>
{file && uuid && (
<Button icon="code" onClick={() => dispatch(editorGoto(uuid, line))}>
<Button
icon={<Code />}
onClick={() => dispatch(editorGoto(uuid, line))}
>
{i18n.translate('compilerError.gotoErrorButton')}
</Button>
)}
@@ -49,7 +53,7 @@ export const compilerError: CreateToast<CompilerErrorProps, 'dismiss' | 'gotoErr
props,
) => ({
message: <CompilerError {...props} />,
icon: 'error',
icon: <Error />,
intent: Intent.DANGER,
timeout: 0,
onDismiss: () => onAction('dismiss'),
+5 -5
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2022 The Pybricks Authors
// Copyright (c) 2021-2023 The Pybricks Authors
import type { IToastOptions, ToasterInstance } from '@blueprintjs/core';
import type { ToastOptions, Toaster } from '@blueprintjs/core';
import { FirmwareReaderError, FirmwareReaderErrorCode } from '@pybricks/firmware';
import { mock } from 'jest-mock-extended';
import { AnyAction } from 'redux';
@@ -36,10 +36,10 @@ import { add } from './actions';
import { I18nId } from './i18n';
import notification from './sagas';
function createTestToasterSaga(): { toaster: ToasterInstance; saga: AsyncSaga } {
const toasts = new Map<string, IToastOptions>();
function createTestToasterSaga(): { toaster: Toaster; saga: AsyncSaga } {
const toasts = new Map<string, ToastOptions>();
const toaster = mock<ToasterInstance>({
const toaster = mock<Toaster>({
show: (props, key) => {
return key ?? '';
},
+11 -10
View File
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2022 The Pybricks Authors
// Copyright (c) 2020-2023 The Pybricks Authors
// Saga for managing notifications (toasts)
import { ActionProps, IconName, Intent, LinkProps } from '@blueprintjs/core';
import { ActionProps, Intent, LinkProps } from '@blueprintjs/core';
import { Error, Help, InfoSign, Refresh, WarningSign } from '@blueprintjs/icons';
import { Replacements } from '@shopify/react-i18n';
import React from 'react';
import { channel } from 'redux-saga';
@@ -58,26 +59,26 @@ function mapIntent(level: Level): Intent {
}
}
function mapIcon(level: Level): IconName | undefined {
function mapIcon(level: Level): JSX.Element | undefined {
switch (level) {
case Level.Error:
return 'error';
return React.createElement(Error);
case Level.Warning:
return 'warning-sign';
return React.createElement(WarningSign);
case Level.Info:
return 'info-sign';
return React.createElement(InfoSign);
default:
return undefined;
}
}
/**
* Converts a URL to an action that can be passed to `ToasterInstance.show()`.
* Converts a URL to an action that can be passed to `Toaster.show()`.
* @param helpUrl A URL.
*/
function helpAction(helpUrl: string): ActionProps & LinkProps & { rel: string } {
return {
icon: 'help',
icon: React.createElement(Help),
href: helpUrl,
target: '_blank',
rel: 'noopener',
@@ -87,7 +88,7 @@ function helpAction(helpUrl: string): ActionProps & LinkProps & { rel: string }
function dispatchAction(
messageId: I18nId,
onClick: (event: React.MouseEvent<HTMLElement>) => void,
icon?: IconName,
icon?: JSX.Element,
): ActionProps {
return {
icon: icon,
@@ -271,7 +272,7 @@ function* showServiceWorkerUpdate(): Generator {
const userAction = dispatchAction(
I18nId.ServiceWorkerUpdateAction,
ch.put,
'refresh',
React.createElement(Refresh),
);
yield* showSingleton(
Level.Info,
+30 -12
View File
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2023 The Pybricks Authors
import './settings.scss';
import {
AnchorButton,
ButtonGroup,
@@ -8,6 +9,16 @@ import {
FormGroup,
Switch,
} from '@blueprintjs/core';
import {
Add,
Chat,
Download,
Help,
InfoSign,
Lightbulb,
Refresh,
Virus,
} from '@blueprintjs/icons';
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { useTernaryDarkMode } from 'usehooks-ts';
@@ -30,7 +41,6 @@ import { useSelector } from '../reducers';
import { tourStart } from '../tour/actions';
import { isMacOS } from '../utils/os';
import { useI18n } from './i18n';
import './settings.scss';
const Settings: React.FunctionComponent = () => {
const [isAboutDialogOpen, setIsAboutDialogOpen] = useState(false);
@@ -82,14 +92,14 @@ const Settings: React.FunctionComponent = () => {
<Button
id="pb-settings-flash-pybricks-button"
minimal={true}
icon="download"
icon={<Download />}
label={i18n.translate('firmware.flashPybricksButton.label')}
onPress={() => dispatch(firmwareInstallPybricks())}
/>
<Button
id="pb-settings-flash-official-button"
minimal={true}
icon="download"
icon={<Download />}
label={i18n.translate('firmware.flashLegoButton.label', {
lego: legoRegisteredTrademark,
})}
@@ -101,30 +111,38 @@ const Settings: React.FunctionComponent = () => {
<Button
id="pb-settings-tour-button"
label={i18n.translate('app.tour.label')}
icon="info-sign"
icon={<InfoSign />}
onPress={() => {
dispatch(tourStart());
return true;
}}
/>
<AnchorButton
icon="lightbulb"
icon={<Lightbulb />}
href={pybricksProjectsUrl}
target="blank_"
>
{i18n.translate('help.projects.label')}
<ExternalLinkIcon />
</AnchorButton>
<AnchorButton icon="help" href={pybricksSupportUrl} target="blank_">
<AnchorButton
icon={<Help />}
href={pybricksSupportUrl}
target="blank_"
>
{i18n.translate('help.support.label')}
<ExternalLinkIcon />
</AnchorButton>
<AnchorButton icon="chat" href={pybricksGitterUrl} target="blank_">
<AnchorButton
icon={<Chat />}
href={pybricksGitterUrl}
target="blank_"
>
{i18n.translate('help.chat.label')}
<ExternalLinkIcon />
</AnchorButton>
<AnchorButton
icon="virus"
icon={<Virus />}
href={pybricksBugReportsUrl}
target="blank_"
>
@@ -145,7 +163,7 @@ const Settings: React.FunctionComponent = () => {
{hasUnresolvedInstallPrompt && (
<Button
label={i18n.translate('app.install.label')}
icon="add"
icon={<Add />}
onPress={() => dispatch(appShowInstallPrompt())}
loading={promptingInstall}
/>
@@ -154,7 +172,7 @@ const Settings: React.FunctionComponent = () => {
(isServiceWorkerRegistered && !updateAvailable)) && (
<Button
label={i18n.translate('app.checkForUpdate.label')}
icon="refresh"
icon={<Refresh />}
onPress={() => dispatch(appCheckForUpdate())}
loading={checkingForUpdate}
/>
@@ -163,13 +181,13 @@ const Settings: React.FunctionComponent = () => {
(isServiceWorkerRegistered && updateAvailable)) && (
<Button
label={i18n.translate('app.restart.label')}
icon="refresh"
icon={<Refresh />}
onPress={() => dispatch(appReload())}
/>
)}
<Button
label={i18n.translate('app.about.label')}
icon="info-sign"
icon={<InfoSign />}
onPress={() => {
setIsAboutDialogOpen(true);
return true;
-52
View File
@@ -9,10 +9,6 @@ import '@testing-library/jest-dom/extend-expect';
import 'navigator.locks';
import crypto from 'crypto';
import { inspect } from 'util';
import {
KeyCodes,
Modifiers,
} from '@blueprintjs/core/lib/cjs/components/hotkeys/hotkeyParser';
// @ts-expect-error no typings
import matchMediaPolyfill from 'mq-polyfill';
import { config } from 'react-transition-group';
@@ -42,54 +38,6 @@ if (!Element.prototype.scrollTo) {
Element.prototype.scrollTo = jest.fn();
}
// HACK: work around https://github.com/palantir/blueprint/issues/4165
// userEvent.keyboard does not set which, so we have to do a reverse lookup
// using the blueprintjs keymap.
// handle cases that are not simple lower case conversion
const specialCases: Record<string, string> = {
Control: 'ctrl',
' ': 'space',
ArrowDown: 'down',
ArrowLeft: 'left',
ArrowRight: 'right',
ArrowUp: 'up',
Delete: 'del',
Insert: 'ins',
Escape: 'esc',
};
function addWhichToKeyboardEvent(e: KeyboardEvent) {
// blueprints and testing-library both don't do this one
if (e.key === 'ContextMenu') {
// HACK: work around lack of ContextMenu key support in user-events
if (e.target !== null) {
e.target.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }));
}
return;
}
const blueprintsKeyName = specialCases[e.key] ?? e.key.toLowerCase();
let which = 0;
for (const [k, v] of Object.entries(KeyCodes).concat(Object.entries(Modifiers))) {
if (v === blueprintsKeyName) {
which = Number(k);
break;
}
}
if (which === 0) {
console.warn('unsupported key:', e.key, e.code);
}
Object.defineProperty(e, 'which', { value: which });
}
document.addEventListener('keydown', addWhichToKeyboardEvent, { capture: true });
document.addEventListener('keypress', addWhichToKeyboardEvent, { capture: true });
document.addEventListener('keyup', addWhichToKeyboardEvent, { capture: true });
Object.defineProperty(global.self, 'crypto', {
value: crypto.webcrypto,
});
+2 -1
View File
@@ -3,6 +3,7 @@
import './sponsorsDialog.scss';
import { AnchorButton, Classes, Dialog, Intent } from '@blueprintjs/core';
import { Heart } from '@blueprintjs/icons';
import classNames from 'classnames';
import React from 'react';
import { useDispatch } from 'react-redux';
@@ -29,7 +30,7 @@ const SponsorDialog: React.FunctionComponent = () => {
title={i18n.translate('title', { pybricks: 'Pybricks' })}
isOpen={showDialog}
onClose={() => dispatch(sponsorHideDialog())}
icon="heart"
icon={<Heart />}
>
<div className={classNames(Classes.DIALOG_BODY, Classes.RUNNING_TEXT)}>
<h4>{i18n.translate('whoAreWe.heading')}</h4>
+2 -1
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import { InfoSign } from '@blueprintjs/icons';
import React from 'react';
import type { CreateToast } from '../../toasterTypes';
import { useI18n } from './i18n';
@@ -14,7 +15,7 @@ const AddressCopied: React.FunctionComponent = () => {
export const addressCopied: CreateToast = (onAction) => {
return {
message: <AddressCopied />,
icon: 'info-sign',
icon: <InfoSign />,
intent: Intent.PRIMARY,
timeout: 5000,
onDismiss: () => onAction('dismiss'),
+15 -14
View File
@@ -1,16 +1,19 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2023 The Pybricks Authors
import './status-bar.scss';
import {
Button,
Classes,
Icon,
IconSize,
Intent,
Popover,
PopoverProps,
ProgressBar,
Spinner,
} from '@blueprintjs/core';
import { Classes as Classes2, Popover2, Popover2Props } from '@blueprintjs/popover2';
import { Disable, Error, TickCircle } from '@blueprintjs/icons';
import classNames from 'classnames';
import React, { useMemo } from 'react';
import { BleConnectionState } from '../ble/reducers';
@@ -18,10 +21,8 @@ import { CompletionEngineStatus } from '../editor/redux/codeCompletion';
import { useSelector } from '../reducers';
import { useI18n } from './i18n';
import './status-bar.scss';
const commonPopoverProps: Partial<Popover2Props> = {
popoverClassName: Classes2.POPOVER2_CONTENT_SIZING,
const commonPopoverProps: Partial<PopoverProps> = {
popoverClassName: Classes.POPOVER_CONTENT_SIZING,
placement: 'top',
};
@@ -34,11 +35,11 @@ const CompletionEngineIndicator: React.FunctionComponent = () => {
case CompletionEngineStatus.Loading:
return <Spinner size={IconSize.STANDARD} />;
case CompletionEngineStatus.Ready:
return <Icon icon="tick-circle" />;
return <Icon icon={<TickCircle />} />;
case CompletionEngineStatus.Failed:
return <Icon icon="error" />;
return <Icon icon={<Error />} />;
default:
return <Icon icon="disable" />;
return <Icon icon={<Disable />} />;
}
}, [status]);
@@ -56,7 +57,7 @@ const CompletionEngineIndicator: React.FunctionComponent = () => {
}, [status, i18n]);
return (
<Popover2 {...commonPopoverProps} content={message}>
<Popover {...commonPopoverProps} content={message}>
<div
aria-label={i18n.translate('completionEngineStatus.label')}
role="button"
@@ -65,7 +66,7 @@ const CompletionEngineIndicator: React.FunctionComponent = () => {
>
{icon}
</div>
</Popover2>
</Popover>
);
};
@@ -76,7 +77,7 @@ const HubInfoButton: React.FunctionComponent = () => {
const deviceFirmwareVersion = useSelector((s) => s.ble.deviceFirmwareVersion);
return (
<Popover2
<Popover
{...commonPopoverProps}
content={
<table className="no-wrap" style={{ userSelect: 'text' }}>
@@ -106,7 +107,7 @@ const HubInfoButton: React.FunctionComponent = () => {
<Button title={i18n.translate('hubInfo.title')} minimal={true}>
{deviceName}
</Button>
</Popover2>
</Popover>
);
};
@@ -116,7 +117,7 @@ const BatteryIndicator: React.FunctionComponent = () => {
const lowBatteryWarning = useSelector((s) => s.ble.deviceLowBatteryWarning);
return (
<Popover2
<Popover
{...commonPopoverProps}
content={
<span className="no-wrap">
@@ -138,7 +139,7 @@ const BatteryIndicator: React.FunctionComponent = () => {
</div>
<div className="pb-battery-indicator-tip" />
</div>
</Popover2>
</Popover>
);
};
+61 -51
View File
@@ -3,9 +3,15 @@
import 'xterm/css/xterm.css';
import './terminal.scss';
import { Menu, MenuDivider, MenuItem, ResizeSensor } from '@blueprintjs/core';
import { ContextMenu2, ContextMenu2ContentProps } from '@blueprintjs/popover2';
import React, { useContext, useEffect, useMemo, useRef } from 'react';
import {
ContextMenu,
Menu,
MenuDivider,
MenuItem,
ResizeSensor,
} from '@blueprintjs/core';
import { Blank, Clipboard, Duplicate, Trash } from '@blueprintjs/icons';
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useTernaryDarkMode } from 'usehooks-ts';
import { Terminal as XTerm } from 'xterm';
@@ -56,52 +62,58 @@ function createXTerm(): { xterm: XTerm; fitAddon: FitAddon } {
return { xterm, fitAddon };
}
function createContextMenu(
xterm: XTerm,
): (props: ContextMenu2ContentProps) => JSX.Element {
const ContextMenu = (_props: ContextMenu2ContentProps): JSX.Element => {
const i18n = useI18n();
type ContextMenuContentProps = { xterm: XTerm };
return (
<Menu>
<MenuItem
onClick={(): void => {
const selected = xterm.getSelection();
if (selected) {
navigator.clipboard.writeText(selected);
}
}}
text={i18n.translate('copy')}
icon="duplicate"
label={isMacOS() ? 'Cmd-C' : 'Ctrl-Shift-C'}
disabled={!xterm.hasSelection()}
/>
<MenuItem
onClick={async (): Promise<void> => {
xterm.paste(await navigator.clipboard.readText());
}}
text={i18n.translate('paste')}
icon="clipboard"
label={isMacOS() ? 'Cmd-V' : 'Ctrl-V'}
/>
<MenuItem
onClick={() => xterm.selectAll()}
text={i18n.translate('selectAll')}
icon="blank"
/>
<MenuDivider />
<MenuItem
onClick={(): void => xterm.clear()}
text={i18n.translate('clear')}
icon="trash"
/>
</Menu>
);
};
const ContextMenuContent: React.FunctionComponent<ContextMenuContentProps> = ({
xterm,
}) => {
const i18n = useI18n();
const [hasSelection, setHasSelection] = useState(xterm.hasSelection());
return ContextMenu;
}
useEffect(() => {
const subscription = xterm.onSelectionChange(() => {
setHasSelection(xterm.hasSelection());
});
return () => subscription.dispose();
}, [xterm, setHasSelection]);
return (
<Menu>
<MenuItem
onClick={(): void => {
const selected = xterm.getSelection();
if (selected) {
navigator.clipboard.writeText(selected);
}
}}
text={i18n.translate('copy')}
icon={<Duplicate />}
label={isMacOS() ? 'Cmd-C' : 'Ctrl-Shift-C'}
disabled={!hasSelection}
/>
<MenuItem
onClick={async (): Promise<void> => {
xterm.paste(await navigator.clipboard.readText());
}}
text={i18n.translate('paste')}
icon={<Clipboard />}
label={isMacOS() ? 'Cmd-V' : 'Ctrl-V'}
/>
<MenuItem
onClick={() => xterm.selectAll()}
text={i18n.translate('selectAll')}
icon={<Blank />}
/>
<MenuDivider />
<MenuItem
onClick={(): void => xterm.clear()}
text={i18n.translate('clear')}
icon={<Trash />}
/>
</Menu>
);
};
const Terminal: React.FunctionComponent = () => {
const { xterm, fitAddon } = useMemo(createXTerm, [createXTerm]);
const terminalRef = useRef<HTMLDivElement>(null);
@@ -181,8 +193,6 @@ const Terminal: React.FunctionComponent = () => {
return () => onDataHandle.dispose();
}, [dispatch, xterm]);
const contextMenu = useMemo(() => createContextMenu(xterm), [xterm]);
useEffect(() => {
const listener = () => {
xterm.focus();
@@ -224,9 +234,9 @@ const Terminal: React.FunctionComponent = () => {
}, [xterm, bellRef, bellOverlayRef, bellTimeoutRef]);
return (
<ContextMenu2
<ContextMenu
className="h-100"
content={contextMenu}
content={<ContextMenuContent xterm={xterm} />}
popoverProps={{ onClosed: () => xterm.focus() }}
>
<audio hidden preload="auto" ref={bellRef}>
@@ -236,7 +246,7 @@ const Terminal: React.FunctionComponent = () => {
<ResizeSensor onResize={(): void => fitAddon.fit()}>
<div ref={terminalRef} className="h-100" />
</ResizeSensor>
</ContextMenu2>
</ContextMenu>
);
};
+4 -4
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2022 The Pybricks Authors
// Copyright (c) 2021-2023 The Pybricks Authors
import type { ToastProps, ToasterInstance } from '@blueprintjs/core';
import type { ToastProps, Toaster } from '@blueprintjs/core';
/**
* Template type alert callbacks.
@@ -25,6 +25,6 @@ export type CreateToast<
> = (onAction: ToastActionHandler<A>, props: P) => ToastProps;
/**
* Type compatible with React.RefObject<ToasterInstance>.
* Type compatible with React.RefObject<Toaster>.
*/
export type ToasterRef = { current: ToasterInstance | null };
export type ToasterRef = { current: Toaster | null };
+3 -3
View File
@@ -7,9 +7,9 @@ import {
Intent,
Spinner,
SpinnerSize,
Tooltip,
useHotkeys,
} from '@blueprintjs/core';
import { Tooltip2 } from '@blueprintjs/popover2';
import { mergeProps } from '@react-aria/utils';
import classNames from 'classnames';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
@@ -96,7 +96,7 @@ const ActionButton: React.FunctionComponent<ActionButtonProps> = ({
}, [enabled, onAction]);
return (
<Tooltip2
<Tooltip
content={tooltip}
placement="bottom"
hoverOpenDelay={tooltipDelay}
@@ -109,7 +109,7 @@ const ActionButton: React.FunctionComponent<ActionButtonProps> = ({
id={id}
aria-disabled={enabled === false}
aria-label={label}
elementRef={tooltipTargetRef as React.Ref<HTMLButtonElement>}
ref={tooltipTargetRef}
{...mergeProps(tooltipTargetProps, {
className: classNames(
'pb-toolbar-action-button',
+11 -3
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2022-2023 The Pybricks Authors
import { Colors, Icon } from '@blueprintjs/core';
import { Archive, Play, Plus } from '@blueprintjs/icons';
import React, { useCallback, useMemo, useState } from 'react';
import Joyride, {
ACTIONS,
@@ -41,7 +42,7 @@ const AddFileStep = React.memo(function AddFileStep() {
return (
<p>
{i18n.translate('steps.newFile.message', {
icon: <Icon icon="plus" style={{ verticalAlign: 'text-top' }} />,
icon: <Icon icon={<Plus />} style={{ verticalAlign: 'text-top' }} />,
})}
</p>
);
@@ -55,7 +56,12 @@ const BackupFilesStep = React.memo(function BackupFilesStep() {
<p>{i18n.translate('steps.backupFiles.message')}</p>
<p>
{i18n.translate('steps.backupFiles.action', {
icon: <Icon icon="archive" style={{ verticalAlign: 'text-top' }} />,
icon: (
<Icon
icon={<Archive />}
style={{ verticalAlign: 'text-top' }}
/>
),
})}
</p>
</>
@@ -99,7 +105,9 @@ const DownloadAndRunStep = React.memo(function DownloadAndRunStep() {
<>
<p>
{i18n.translate('steps.downloadAndRun.message', {
icon: <Icon icon="play" style={{ verticalAlign: 'text-top' }} />,
icon: (
<Icon icon={<Play />} style={{ verticalAlign: 'text-top' }} />
),
})}
</p>
<p>{i18n.translate('steps.downloadAndRun.runAgain')}</p>
+7 -9
View File
@@ -11,10 +11,10 @@ import {
Classes,
Colors,
Icon,
IconName,
InputGroup,
MaybeElement,
} from '@blueprintjs/core';
import { ChevronRight, Tick } from '@blueprintjs/icons';
import React, { createContext } from 'react';
import { TreeItem, TreeRenderProps } from 'react-complex-tree';
import { useBoolean } from 'usehooks-ts';
@@ -26,7 +26,8 @@ const cx = (...classNames: Array<string | undefined | false>): string =>
/** Node item data similar to blueprintsjs TreeNodeInfo */
export type TreeItemData = {
readonly icon?: IconName | MaybeElement;
/** Optional icon. Element must include `className={Classes.TREE_NODE_ICON}`! */
readonly icon?: MaybeElement;
readonly secondaryLabel?: string | MaybeElement;
};
@@ -111,11 +112,7 @@ const Item: React.FunctionComponent<RenderProps<'renderItem'>> = (props) => {
) : (
<span className={Classes.TREE_NODE_CARET_NONE} />
)}
<Icon
className={Classes.TREE_NODE_ICON}
icon={props.item.data.icon}
aria-hidden={true}
/>
<Icon icon={props.item.data.icon} />
{props.title}
{props.item.data.secondaryLabel && isHover && (
<span className={Classes.TREE_NODE_SECONDARY_LABEL}>
@@ -131,7 +128,7 @@ const Item: React.FunctionComponent<RenderProps<'renderItem'>> = (props) => {
const ItemArrow: React.FunctionComponent<RenderProps<'renderItemArrow'>> = (props) => (
<Icon
icon="chevron-right"
icon={<ChevronRight />}
className={cx(
Classes.TREE_NODE_CARET,
props.context.isExpanded
@@ -206,8 +203,9 @@ const RenameInput: React.FunctionComponent<RenderProps<'renderRenameInput'>> = (
</span>
<span className={Classes.TREE_NODE_SECONDARY_LABEL}>
<Button
icon="tick"
icon={<Tick />}
{...props.submitButtonProps}
ref={props.submitButtonRef}
type="submit"
minimal={true}
small={true}
+47 -484
View File
@@ -1469,7 +1469,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
version: 7.18.3
resolution: "@babel/runtime@npm:7.18.3"
dependencies:
@@ -1525,28 +1525,25 @@ __metadata:
languageName: node
linkType: hard
"@blueprintjs/colors@npm:^4.2.1":
version: 4.2.1
resolution: "@blueprintjs/colors@npm:4.2.1"
"@blueprintjs/colors@npm:^5.0.0":
version: 5.0.0
resolution: "@blueprintjs/colors@npm:5.0.0"
dependencies:
tslib: ~2.5.0
checksum: d8073d0146f1d9b99e1d9dbbe4ab5b57d41c41f7a70da287b4dd6f02781df52b772e66348b79a3a6c9a7d9ed311d93934d2a4413da04ebfd215cfae143bed446
checksum: 2a2e7b64bb253224994e7813aa3ed2092d634378818114a6cbe2f6f9b4338bf3063965542df98c69aaf8f82e4d2c09ccf87d7a673b49b039a71ba949fe7671f3
languageName: node
linkType: hard
"@blueprintjs/core@npm:^4.20.2":
version: 4.20.2
resolution: "@blueprintjs/core@npm:4.20.2"
"@blueprintjs/core@npm:^5.0.1":
version: 5.0.1
resolution: "@blueprintjs/core@npm:5.0.1"
dependencies:
"@blueprintjs/colors": ^4.2.1
"@blueprintjs/icons": ^4.16.0
"@juggle/resize-observer": ^3.4.0
"@types/dom4": ^2.0.2
"@blueprintjs/colors": ^5.0.0
"@blueprintjs/icons": ^5.0.0
"@popperjs/core": ^2.11.7
classnames: ^2.3.1
dom4: ^2.1.5
normalize.css: ^8.0.1
popper.js: ^1.16.1
react-popper: ^1.3.11
react-popper: ^2.3.0
react-transition-group: ^4.4.5
tslib: ~2.5.0
peerDependencies:
@@ -1559,32 +1556,17 @@ __metadata:
bin:
upgrade-blueprint-2.0.0-rename: scripts/upgrade-blueprint-2.0.0-rename.sh
upgrade-blueprint-3.0.0-rename: scripts/upgrade-blueprint-3.0.0-rename.sh
checksum: 71ed794ee48fb73e7e66facb218b92f2ddbefa05636c4e9a8b94a643ef587e3f22cb5880d1a26b0764494047d8ece719a4bc4865c7c68616de980f7d8ed16da3
checksum: 86a41e33adae6c79b0d840962551dbc54b2e8af0c109a67b46b361d08424b5e41d5bf75dd0f11d4b36d0e430a17ca3881d19f0dd14c86a62b14b60c411248889
languageName: node
linkType: hard
"@blueprintjs/icons@npm:^4.16.0":
version: 4.16.0
resolution: "@blueprintjs/icons@npm:4.16.0"
"@blueprintjs/icons@npm:^5.0.0":
version: 5.0.0
resolution: "@blueprintjs/icons@npm:5.0.0"
dependencies:
change-case: ^4.1.2
classnames: ^2.3.1
tslib: ~2.5.0
checksum: d7d1d2ada376401df46b23977338686b6a5cfd203cf92fafb2bd5c19f9a8f4b1134277b6e3bf758b1df763bcf4fb89f80fb157c8ce49d732f1f6ca1f71942e8c
languageName: node
linkType: hard
"@blueprintjs/popover2@npm:^1.14.11":
version: 1.14.11
resolution: "@blueprintjs/popover2@npm:1.14.11"
dependencies:
"@blueprintjs/core": ^4.20.2
"@juggle/resize-observer": ^3.4.0
"@popperjs/core": ^2.11.7
classnames: ^2.3.1
dom4: ^2.1.5
react-popper: ^2.3.0
tslib: ~2.5.0
peerDependencies:
"@types/react": ^16.14.32 || 17 || 18
react: ^16.8 || 17 || 18
@@ -1592,26 +1574,7 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 1f7a0dbfb1e7ed1f76ea84b596baf4f3b21dca3a8afe88603d53bfa6043718f5e75c701d3a92b75b10ed9980e24beb46fdecfc75ed55108716650bf6d6b7bb83
languageName: node
linkType: hard
"@blueprintjs/select@npm:^4.9.24":
version: 4.9.24
resolution: "@blueprintjs/select@npm:4.9.24"
dependencies:
"@blueprintjs/core": ^4.20.2
"@blueprintjs/popover2": ^1.14.11
classnames: ^2.3.1
tslib: ~2.5.0
peerDependencies:
"@types/react": ^16.14.32 || 17 || 18
react: ^16.8 || 17 || 18
react-dom: ^16.8 || 17 || 18
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 1ba595f58f36a8c0df3f8707ed035814021d7b3ca763182941e2a5f0844d79888cd12811c787eeb1b33669f43fd6b90d7cef9750c715fe9145d144c558ca800a
checksum: 68ee2cae7fe7232ad50a053edb45681983a84b6d748da865bbed64f23a71639ac67923c47c4431d4ff2c3e83d3ced2fa1c88b1ade00fd2f2ae343719f37e1db3
languageName: node
linkType: hard
@@ -1655,16 +1618,7 @@ __metadata:
languageName: node
linkType: hard
"@csstools/css-parser-algorithms@npm:^2.1.1":
version: 2.1.1
resolution: "@csstools/css-parser-algorithms@npm:2.1.1"
peerDependencies:
"@csstools/css-tokenizer": ^2.1.1
checksum: 0ba3f3d38b99c933d12c6cb7fc348a9c0056a1e23b8a4b7e66b79295b5071bc443c4c3ed87ad7f155ce7e76e49c20c582dc27d804c9a45c82e5bd37585870d60
languageName: node
linkType: hard
"@csstools/css-parser-algorithms@npm:^2.2.0":
"@csstools/css-parser-algorithms@npm:^2.1.1, @csstools/css-parser-algorithms@npm:^2.2.0":
version: 2.2.0
resolution: "@csstools/css-parser-algorithms@npm:2.2.0"
peerDependencies:
@@ -2116,19 +2070,6 @@ __metadata:
languageName: node
linkType: hard
"@hypnosphi/create-react-context@npm:^0.3.1":
version: 0.3.1
resolution: "@hypnosphi/create-react-context@npm:0.3.1"
dependencies:
gud: ^1.0.0
warning: ^4.0.3
peerDependencies:
prop-types: ^15.0.0
react: ">=0.14.0"
checksum: d2f069a562e138057aa067e1483e28cea3193bbacd33ca9528131f31e656939cfeb552af760b3be437d3a8074315a8854fc6d5d89878e2746618ad930c817122
languageName: node
linkType: hard
"@internationalized/date@npm:^3.3.0":
version: 3.3.0
resolution: "@internationalized/date@npm:3.3.0"
@@ -2468,17 +2409,7 @@ __metadata:
languageName: node
linkType: hard
"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.17
resolution: "@jridgewell/trace-mapping@npm:0.3.17"
dependencies:
"@jridgewell/resolve-uri": 3.1.0
"@jridgewell/sourcemap-codec": 1.4.14
checksum: 9d703b859cff5cd83b7308fd457a431387db5db96bd781a63bf48e183418dd9d3d44e76b9e4ae13237f6abeeb25d739ec9215c1d5bfdd08f66f750a50074a339
languageName: node
linkType: hard
"@jridgewell/trace-mapping@npm:^0.3.18":
"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.18
resolution: "@jridgewell/trace-mapping@npm:0.3.18"
dependencies:
@@ -2488,13 +2419,6 @@ __metadata:
languageName: node
linkType: hard
"@juggle/resize-observer@npm:^3.4.0":
version: 3.4.0
resolution: "@juggle/resize-observer@npm:3.4.0"
checksum: 2505028c05cc2e17639fcad06218b1c4b60f932a4ebb4b41ab546ef8c157031ae377e3f560903801f6d01706dbefd4943b6c4704bf19ed86dfa1c62f1473a570
languageName: node
linkType: hard
"@leichtgewicht/ip-codec@npm:^2.0.1":
version: 2.0.4
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
@@ -2663,9 +2587,7 @@ __metadata:
resolution: "@pybricks/pybricks-code@workspace:."
dependencies:
"@babel/core": ^7.22.5
"@blueprintjs/core": ^4.20.2
"@blueprintjs/popover2": ^1.14.11
"@blueprintjs/select": ^4.9.24
"@blueprintjs/core": ^5.0.1
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
"@pybricks/firmware": 7.5.0
"@pybricks/ide-docs": 2.9.0
@@ -4605,23 +4527,7 @@ __metadata:
languageName: node
linkType: hard
"@testing-library/dom@npm:^9.0.0":
version: 9.3.0
resolution: "@testing-library/dom@npm:9.3.0"
dependencies:
"@babel/code-frame": ^7.10.4
"@babel/runtime": ^7.12.5
"@types/aria-query": ^5.0.1
aria-query: ^5.0.0
chalk: ^4.1.0
dom-accessibility-api: ^0.5.9
lz-string: ^1.5.0
pretty-format: ^27.0.2
checksum: 790f4da6a8cbe7da8b7769e81e68caea1aed5b5f1973b808895692a945fb854fe8acdc66ffc34b6a57ec49bad9d76ccdd69b632ea8a82ad61d1e97d76cfdf9ec
languageName: node
linkType: hard
"@testing-library/dom@npm:^9.3.1":
"@testing-library/dom@npm:^9.0.0, @testing-library/dom@npm:^9.3.1":
version: 9.3.1
resolution: "@testing-library/dom@npm:9.3.1"
dependencies:
@@ -4777,13 +4683,6 @@ __metadata:
languageName: node
linkType: hard
"@types/dom4@npm:^2.0.2":
version: 2.0.2
resolution: "@types/dom4@npm:2.0.2"
checksum: 33af62348979c54dc227ad6c943c374a5e0e4af17f6d7d18957662c1247242ec8e0718a43a62bf4288de6d5e6e59f8e1801a499e3aa2e3899bf116e5b3170805
languageName: node
linkType: hard
"@types/eslint-scope@npm:^3.7.3":
version: 3.7.3
resolution: "@types/eslint-scope@npm:3.7.3"
@@ -4950,14 +4849,7 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:*":
version: 18.16.16
resolution: "@types/node@npm:18.16.16"
checksum: 0efad726dd1e0bef71c392c708fc5d78c5b39c46b0ac5186fee74de4ccb1b2e847b3fa468da67d62812f56569da721b15bf31bdc795e6c69b56c73a45079ed2d
languageName: node
linkType: hard
"@types/node@npm:^18.16.18":
"@types/node@npm:*, @types/node@npm:^18.16.18":
version: 18.16.18
resolution: "@types/node@npm:18.16.18"
checksum: d32d8a0a04cd3f5ecb361bcb42f3a07623881ac90d680e06bf626defb3c663a94860d11690babe607cfe67265eceeb8a59ba5fe40c0e49f5a1b01e0088640469
@@ -4999,16 +4891,7 @@ __metadata:
languageName: node
linkType: hard
"@types/react-dom@npm:^18.0.0":
version: 18.2.4
resolution: "@types/react-dom@npm:18.2.4"
dependencies:
"@types/react": "*"
checksum: 8301f35cf1cbfec8c723e9477aecf87774e3c168bd457d353b23c45064737213d3e8008b067c6767b7b08e4f2b3823ee239242a6c225fc91e7f8725ef8734124
languageName: node
linkType: hard
"@types/react-dom@npm:^18.2.6":
"@types/react-dom@npm:^18.0.0, @types/react-dom@npm:^18.2.6":
version: 18.2.6
resolution: "@types/react-dom@npm:18.2.6"
dependencies:
@@ -5035,18 +4918,7 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:*":
version: 18.2.9
resolution: "@types/react@npm:18.2.9"
dependencies:
"@types/prop-types": "*"
"@types/scheduler": "*"
csstype: ^3.0.2
checksum: f155256171a2d701eb962a1d3aa2a1c9ee36d9dd4a4aecb911d29e50717aab1a76914aef25242665147c455b9e8d081d1a60275d13ca81075c148ebd6607414a
languageName: node
linkType: hard
"@types/react@npm:^18.2.14":
"@types/react@npm:*, @types/react@npm:^18.2.14":
version: 18.2.14
resolution: "@types/react@npm:18.2.14"
dependencies:
@@ -5230,31 +5102,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.5.0, @typescript-eslint/eslint-plugin@npm:^5.55.0":
version: 5.59.9
resolution: "@typescript-eslint/eslint-plugin@npm:5.59.9"
dependencies:
"@eslint-community/regexpp": ^4.4.0
"@typescript-eslint/scope-manager": 5.59.9
"@typescript-eslint/type-utils": 5.59.9
"@typescript-eslint/utils": 5.59.9
debug: ^4.3.4
grapheme-splitter: ^1.0.4
ignore: ^5.2.0
natural-compare-lite: ^1.4.0
semver: ^7.3.7
tsutils: ^3.21.0
peerDependencies:
"@typescript-eslint/parser": ^5.0.0
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
checksum: bd2428e307085d7fa6699913b6e61d65eb450bbcd26f884390cbf16722b80e1d80dc289c72774be1cdffd022744894204c3242f40ba3ffdfa05d3f210c4130bb
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.60.1":
"@typescript-eslint/eslint-plugin@npm:^5.5.0, @typescript-eslint/eslint-plugin@npm:^5.55.0, @typescript-eslint/eslint-plugin@npm:^5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/eslint-plugin@npm:5.60.1"
dependencies:
@@ -5289,24 +5137,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:^5.5.0, @typescript-eslint/parser@npm:^5.55.0":
version: 5.59.9
resolution: "@typescript-eslint/parser@npm:5.59.9"
dependencies:
"@typescript-eslint/scope-manager": 5.59.9
"@typescript-eslint/types": 5.59.9
"@typescript-eslint/typescript-estree": 5.59.9
debug: ^4.3.4
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
checksum: 69b07d0a5bc6e1d24d23916c057ea9f2f53a0e7fb6dabadff92987c299640edee2c013fb93269322c7124e87b5c515529001397eae33006dfb40e1dcdf1902d7
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:^5.60.1":
"@typescript-eslint/parser@npm:^5.5.0, @typescript-eslint/parser@npm:^5.55.0, @typescript-eslint/parser@npm:^5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/parser@npm:5.60.1"
dependencies:
@@ -5333,16 +5164,6 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:5.59.9":
version: 5.59.9
resolution: "@typescript-eslint/scope-manager@npm:5.59.9"
dependencies:
"@typescript-eslint/types": 5.59.9
"@typescript-eslint/visitor-keys": 5.59.9
checksum: 362c22662d844440a7e14223d8cc0722f77ff21ad8f78deb0ee3b3f21de01b8846bf25fbbf527544677e83d8ff48008b3f7d40b39ddec55994ea4a1863e9ec0a
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/scope-manager@npm:5.60.1"
@@ -5353,24 +5174,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:5.59.9, @typescript-eslint/type-utils@npm:^5.50.0, @typescript-eslint/type-utils@npm:^5.55.0":
version: 5.59.9
resolution: "@typescript-eslint/type-utils@npm:5.59.9"
dependencies:
"@typescript-eslint/typescript-estree": 5.59.9
"@typescript-eslint/utils": 5.59.9
debug: ^4.3.4
tsutils: ^3.21.0
peerDependencies:
eslint: "*"
peerDependenciesMeta:
typescript:
optional: true
checksum: 6bc2619c5024c152b181eff1f44c9b5e7d0fc75ce9403f03b39d59fc1e13191b2fbaf6730f26a1caae22922ac47489f39c2cebccdd713588f6963169ed2a7958
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:5.60.1":
"@typescript-eslint/type-utils@npm:5.60.1, @typescript-eslint/type-utils@npm:^5.50.0, @typescript-eslint/type-utils@npm:^5.55.0":
version: 5.60.1
resolution: "@typescript-eslint/type-utils@npm:5.60.1"
dependencies:
@@ -5394,13 +5198,6 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/types@npm:5.59.9":
version: 5.59.9
resolution: "@typescript-eslint/types@npm:5.59.9"
checksum: 283f8fee1ee590eeccc2e0fcd3526c856c4b1e2841af2cdcd09eeac842a42cfb32f6bc8b40385380f3dbc3ee29da30f1819115eedf9e16f69ff5a160aeddd8fa
languageName: node
linkType: hard
"@typescript-eslint/types@npm:5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/types@npm:5.60.1"
@@ -5426,24 +5223,6 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:5.59.9":
version: 5.59.9
resolution: "@typescript-eslint/typescript-estree@npm:5.59.9"
dependencies:
"@typescript-eslint/types": 5.59.9
"@typescript-eslint/visitor-keys": 5.59.9
debug: ^4.3.4
globby: ^11.1.0
is-glob: ^4.0.3
semver: ^7.3.7
tsutils: ^3.21.0
peerDependenciesMeta:
typescript:
optional: true
checksum: c0c9b81f20a2a4337f07bc3ccdc9c1dabd765f59096255ed9a149e91e5c9517b25c2b6655f8f073807cfc13500c7451fbd9bb62e5e572c07cc07945ab042db89
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/typescript-estree@npm:5.60.1"
@@ -5480,25 +5259,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:5.59.9, @typescript-eslint/utils@npm:^5.13.0, @typescript-eslint/utils@npm:^5.50.0, @typescript-eslint/utils@npm:^5.55.0":
version: 5.59.9
resolution: "@typescript-eslint/utils@npm:5.59.9"
dependencies:
"@eslint-community/eslint-utils": ^4.2.0
"@types/json-schema": ^7.0.9
"@types/semver": ^7.3.12
"@typescript-eslint/scope-manager": 5.59.9
"@typescript-eslint/types": 5.59.9
"@typescript-eslint/typescript-estree": 5.59.9
eslint-scope: ^5.1.1
semver: ^7.3.7
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
checksum: 22ec5962886de7dcf65f99c37aad9fb189a3bef6b2b07c81887fb82a0e8bf137246da58e64fb02141352285708440be13acd7f6db1ca19e96f86724813ac4646
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:5.60.1":
"@typescript-eslint/utils@npm:5.60.1, @typescript-eslint/utils@npm:^5.13.0, @typescript-eslint/utils@npm:^5.50.0, @typescript-eslint/utils@npm:^5.55.0":
version: 5.60.1
resolution: "@typescript-eslint/utils@npm:5.60.1"
dependencies:
@@ -5526,16 +5287,6 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:5.59.9":
version: 5.59.9
resolution: "@typescript-eslint/visitor-keys@npm:5.59.9"
dependencies:
"@typescript-eslint/types": 5.59.9
eslint-visitor-keys: ^3.3.0
checksum: 2909ce761f7fe546592cd3c43e33263d8a5fa619375fd2fdffbc72ffc33e40d6feacafb28c79f36c638fcc2225048e7cc08c61cbac6ca63723dc68610d80e3e6
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:5.60.1":
version: 5.60.1
resolution: "@typescript-eslint/visitor-keys@npm:5.60.1"
@@ -5858,7 +5609,7 @@ __metadata:
languageName: node
linkType: hard
"ajv-keywords@npm:^5.0.0, ajv-keywords@npm:^5.1.0":
"ajv-keywords@npm:^5.1.0":
version: 5.1.0
resolution: "ajv-keywords@npm:5.1.0"
dependencies:
@@ -5881,19 +5632,7 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:^8.0.0, ajv@npm:^8.6.0, ajv@npm:^8.8.0":
version: 8.11.0
resolution: "ajv@npm:8.11.0"
dependencies:
fast-deep-equal: ^3.1.1
json-schema-traverse: ^1.0.0
require-from-string: ^2.0.2
uri-js: ^4.2.2
checksum: 5e0ff226806763be73e93dd7805b634f6f5921e3e90ca04acdf8db81eed9d8d3f0d4c5f1213047f45ebbf8047ffe0c840fa1ef2ec42c3a644899f69aa72b5bef
languageName: node
linkType: hard
"ajv@npm:^8.9.0":
"ajv@npm:^8.0.0, ajv@npm:^8.6.0, ajv@npm:^8.9.0":
version: 8.12.0
resolution: "ajv@npm:8.12.0"
dependencies:
@@ -6038,7 +5777,7 @@ __metadata:
languageName: node
linkType: hard
"aria-query@npm:5.1.3":
"aria-query@npm:5.1.3, aria-query@npm:^5.0.0":
version: 5.1.3
resolution: "aria-query@npm:5.1.3"
dependencies:
@@ -6057,13 +5796,6 @@ __metadata:
languageName: node
linkType: hard
"aria-query@npm:^5.0.0":
version: 5.0.0
resolution: "aria-query@npm:5.0.0"
checksum: c41f98866c5a304561ee8cae55856711cddad6f3f85d8cb43cc5f79667078d9b8979ce32d244c1ff364e6463a4d0b6865804a33ccc717fed701b281cf7dc6296
languageName: node
linkType: hard
"array-buffer-byte-length@npm:^1.0.0":
version: 1.0.0
resolution: "array-buffer-byte-length@npm:1.0.0"
@@ -6586,21 +6318,7 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.3, browserslist@npm:^4.21.4, browserslist@npm:^4.21.5":
version: 4.21.7
resolution: "browserslist@npm:4.21.7"
dependencies:
caniuse-lite: ^1.0.30001489
electron-to-chromium: ^1.4.411
node-releases: ^2.0.12
update-browserslist-db: ^1.0.11
bin:
browserslist: cli.js
checksum: 3d0d025e6d381c4db5e71b538258952660ba574c060832095f182a9877ca798836fa550736269e669a2080e486f0cfdf5d3bcf2769b9f7cf123f6c6b8c005f8f
languageName: node
linkType: hard
"browserslist@npm:^4.21.9":
"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.3, browserslist@npm:^4.21.4, browserslist@npm:^4.21.5, browserslist@npm:^4.21.9":
version: 4.21.9
resolution: "browserslist@npm:4.21.9"
dependencies:
@@ -6753,14 +6471,7 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001489":
version: 1.0.30001491
resolution: "caniuse-lite@npm:1.0.30001491"
checksum: ce8e1343dd2ba058902b58dffa7f3695fd251a7ef51a7f0903ab8e62b32becd9f7f590cbebb3f1966cdfff0c2fc8e7154ac116e0b39730bd2f2e17103f5e6c3b
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001503":
"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001503":
version: 1.0.30001503
resolution: "caniuse-lite@npm:1.0.30001503"
checksum: cd5f0af37655ff71ec4ab3c49124d75e0b8b68de625d07ea80e9a82329e616b5203d5dad6865192653be9da50081c06878f081ab069dac0be35adf29aa1599cd
@@ -7279,19 +6990,7 @@ __metadata:
languageName: node
linkType: hard
"cosmiconfig@npm:^8.1.3":
version: 8.1.3
resolution: "cosmiconfig@npm:8.1.3"
dependencies:
import-fresh: ^3.2.1
js-yaml: ^4.1.0
parse-json: ^5.0.0
path-type: ^4.0.0
checksum: b3d277bc3a8a9e649bf4c3fc9740f4c52bf07387481302aa79839f595045368903bf26ea24a8f7f7b8b180bf46037b027c5cb63b1391ab099f3f78814a147b2b
languageName: node
linkType: hard
"cosmiconfig@npm:^8.2.0":
"cosmiconfig@npm:^8.1.3, cosmiconfig@npm:^8.2.0":
version: 8.2.0
resolution: "cosmiconfig@npm:8.2.0"
dependencies:
@@ -7670,20 +7369,6 @@ __metadata:
languageName: node
linkType: hard
"deep-equal@npm:^1.1.1":
version: 1.1.1
resolution: "deep-equal@npm:1.1.1"
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
checksum: f92686f2c5bcdf714a75a5fa7a9e47cb374a8ec9307e717b8d1ce61f56a75aaebf5619c2a12b8087a705b5a2f60d0292c35f8b58cb1f72e3268a3a15cab9f78d
languageName: node
linkType: hard
"deep-equal@npm:^2.0.5":
version: 2.2.1
resolution: "deep-equal@npm:2.2.1"
@@ -7747,17 +7432,7 @@ __metadata:
languageName: node
linkType: hard
"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4":
version: 1.1.4
resolution: "define-properties@npm:1.1.4"
dependencies:
has-property-descriptors: ^1.0.0
object-keys: ^1.1.1
checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b
languageName: node
linkType: hard
"define-properties@npm:^1.2.0":
"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0":
version: 1.2.0
resolution: "define-properties@npm:1.2.0"
dependencies:
@@ -7986,13 +7661,6 @@ __metadata:
languageName: node
linkType: hard
"dom4@npm:^2.1.5":
version: 2.1.6
resolution: "dom4@npm:2.1.6"
checksum: c15ad56afbd1a02a20c0c40215f45a6a28d4fc4740b39359c8f64c693dc5ed4db2944f40b7ce3b7072e87a87986d0c4d355e0abe0f2106648b91e3d19ad696b0
languageName: node
linkType: hard
"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0":
version: 2.3.0
resolution: "domelementtype@npm:2.3.0"
@@ -8107,13 +7775,6 @@ __metadata:
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.4.411":
version: 1.4.413
resolution: "electron-to-chromium@npm:1.4.413"
checksum: 6d702b84e2c5fb8d97cbaec759556c4f801572e62eab2098919061e2f3e7cbca71b9f170a4efb023001d4fd59e8603b4d7004dafc64d89c9f19db4642fdbd012
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.4.431":
version: 1.4.432
resolution: "electron-to-chromium@npm:1.4.432"
@@ -9309,18 +8970,7 @@ __metadata:
languageName: node
linkType: hard
"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3":
version: 1.1.3
resolution: "get-intrinsic@npm:1.1.3"
dependencies:
function-bind: ^1.1.1
has: ^1.0.3
has-symbols: ^1.0.3
checksum: 152d79e87251d536cf880ba75cfc3d6c6c50e12b3a64e1ea960e73a3752b47c69f46034456eae1b0894359ce3bc64c55c186f2811f8a788b75b638b06fab228a
languageName: node
linkType: hard
"get-intrinsic@npm:^1.2.0":
"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0":
version: 1.2.1
resolution: "get-intrinsic@npm:1.2.1"
dependencies:
@@ -9509,13 +9159,6 @@ __metadata:
languageName: node
linkType: hard
"gud@npm:^1.0.0":
version: 1.0.0
resolution: "gud@npm:1.0.0"
checksum: 3e2eb37cf794364077c18f036d6aa259c821c7fd188f2b7935cb00d589d82a41e0ebb1be809e1a93679417f62f1ad0513e745c3cf5329596e489aef8c5e5feae
languageName: node
linkType: hard
"gzip-size@npm:^6.0.0":
version: 6.0.0
resolution: "gzip-size@npm:6.0.0"
@@ -9979,18 +9622,7 @@ __metadata:
languageName: node
linkType: hard
"internal-slot@npm:^1.0.3":
version: 1.0.3
resolution: "internal-slot@npm:1.0.3"
dependencies:
get-intrinsic: ^1.1.0
has: ^1.0.3
side-channel: ^1.0.4
checksum: 1944f92e981e47aebc98a88ff0db579fd90543d937806104d0b96557b10c1f170c51fb777b97740a8b6ddeec585fca8c39ae99fd08a8e058dfc8ab70937238bf
languageName: node
linkType: hard
"internal-slot@npm:^1.0.4":
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4":
version: 1.0.5
resolution: "internal-slot@npm:1.0.5"
dependencies:
@@ -10034,7 +9666,7 @@ __metadata:
languageName: node
linkType: hard
"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1":
"is-arguments@npm:^1.1.1":
version: 1.1.1
resolution: "is-arguments@npm:1.1.1"
dependencies:
@@ -10251,7 +9883,7 @@ __metadata:
languageName: node
linkType: hard
"is-regex@npm:^1.0.4, is-regex@npm:^1.1.4":
"is-regex@npm:^1.1.4":
version: 1.1.4
resolution: "is-regex@npm:1.1.4"
dependencies:
@@ -12077,7 +11709,7 @@ __metadata:
languageName: node
linkType: hard
"object-is@npm:^1.0.1, object-is@npm:^1.1.5":
"object-is@npm:^1.1.5":
version: 1.1.5
resolution: "object-is@npm:1.1.5"
dependencies:
@@ -12486,7 +12118,7 @@ __metadata:
languageName: node
linkType: hard
"popper.js@npm:^1.14.4, popper.js@npm:^1.16.0, popper.js@npm:^1.16.1":
"popper.js@npm:^1.16.0":
version: 1.16.1
resolution: "popper.js@npm:1.16.1"
checksum: c56ae5001ec50a77ee297a8061a0221d99d25c7348d2e6bcd3e45a0d0f32a1fd81bca29d46cb0d4bdf13efb77685bd6a0ce93f9eb3c608311a461f945fffedbe
@@ -13438,7 +13070,7 @@ __metadata:
languageName: node
linkType: hard
"prop-types@npm:^15.6.1, prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
version: 15.8.1
resolution: "prop-types@npm:15.8.1"
dependencies:
@@ -13776,23 +13408,6 @@ __metadata:
languageName: node
linkType: hard
"react-popper@npm:^1.3.11":
version: 1.3.11
resolution: "react-popper@npm:1.3.11"
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
peerDependencies:
react: 0.14.x || ^15.0.0 || ^16.0.0 || ^17.0.0
checksum: a0f5994f5799f1c7364498f74df123dd2561fff4ae834b10fdcca74d9a8e159b523ed1f0708db33bad606933ab4f0d5ce9c90e48cbb671bf30016c890f3c7ea4
languageName: node
linkType: hard
"react-popper@npm:^2.3.0":
version: 2.3.0
resolution: "react-popper@npm:2.3.0"
@@ -14036,18 +13651,7 @@ __metadata:
languageName: node
linkType: hard
"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.4.3":
version: 1.4.3
resolution: "regexp.prototype.flags@npm:1.4.3"
dependencies:
call-bind: ^1.0.2
define-properties: ^1.1.3
functions-have-names: ^1.2.2
checksum: 51228bae732592adb3ededd5e15426be25f289e9c4ef15212f4da73f4ec3919b6140806374b8894036a86020d054a8d2657d3fee6bb9b4d35d8939c20030b7a6
languageName: node
linkType: hard
"regexp.prototype.flags@npm:^1.5.0":
"regexp.prototype.flags@npm:^1.4.3, regexp.prototype.flags@npm:^1.5.0":
version: 1.5.0
resolution: "regexp.prototype.flags@npm:1.5.0"
dependencies:
@@ -14418,18 +14022,7 @@ __metadata:
languageName: node
linkType: hard
"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1":
version: 3.1.2
resolution: "schema-utils@npm:3.1.2"
dependencies:
"@types/json-schema": ^7.0.8
ajv: ^6.12.5
ajv-keywords: ^3.5.2
checksum: 39683edfe3beff018cdb1ae4fa296fc55cea13a080aa2b4d9351895cd64b22ba4d87e2e548c2a2ac1bc76e60980670adb0f413a58104479f1a0c12e5663cb8ca
languageName: node
linkType: hard
"schema-utils@npm:^3.2.0":
"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0":
version: 3.3.0
resolution: "schema-utils@npm:3.3.0"
dependencies:
@@ -14440,19 +14033,7 @@ __metadata:
languageName: node
linkType: hard
"schema-utils@npm:^4.0.0":
version: 4.0.0
resolution: "schema-utils@npm:4.0.0"
dependencies:
"@types/json-schema": ^7.0.9
ajv: ^8.8.0
ajv-formats: ^2.1.1
ajv-keywords: ^5.0.0
checksum: c843e92fdd1a5c145dbb6ffdae33e501867f9703afac67bdf35a685e49f85b1dcc10ea250033175a64bd9d31f0555bc6785b8359da0c90bcea30cf6dfbb55a8f
languageName: node
linkType: hard
"schema-utils@npm:^4.0.1":
"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1":
version: 4.1.0
resolution: "schema-utils@npm:4.1.0"
dependencies:
@@ -14503,18 +14084,7 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8":
version: 7.5.1
resolution: "semver@npm:7.5.1"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: d16dbedad53c65b086f79524b9ef766bf38670b2395bdad5c957f824dcc566b624988013564f4812bcace3f9d405355c3635e2007396a39d1bffc71cfec4a2fc
languageName: node
linkType: hard
"semver@npm:^7.5.3":
"semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3":
version: 7.5.3
resolution: "semver@npm:7.5.3"
dependencies:
@@ -15687,13 +15257,6 @@ __metadata:
languageName: node
linkType: hard
"typed-styles@npm:^0.0.7":
version: 0.0.7
resolution: "typed-styles@npm:0.0.7"
checksum: 36a6ad6bee008c15ddb8c2425eaf9aee37d2841985b4c44406ea4cf57080a9c30b6f9f3feb842ac952354733ac53299ee44f68d83f734486e8344d413f8c8c0d
languageName: node
linkType: hard
"typescript-compare@npm:^0.0.2":
version: 0.0.2
resolution: "typescript-compare@npm:0.0.2"
@@ -15997,7 +15560,7 @@ __metadata:
languageName: node
linkType: hard
"warning@npm:^4.0.2, warning@npm:^4.0.3":
"warning@npm:^4.0.2":
version: 4.0.3
resolution: "warning@npm:4.0.3"
dependencies: