diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f1aa2e3..d823ff4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Added better error message when no files to backup ([support#681]). - Added multi-step firmware flashing dialog. - Added support for flashing firmware via USB DFU. +- Added an interactive introductory tour of the app. ### Fixed - Fixed deleting files that are not open in the editor. diff --git a/package.json b/package.json index 9f41c77a..657e0607 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "react-dev-utils": "^12.0.1", "react-dom": "^16.13.1", "react-dropzone": "^14.2.2", + "react-joyride": "^2.5.0", "react-monaco-editor": "^0.49.0", "react-popper": "^2.3.0", "react-redux": "^8.0.2", diff --git a/src/activities/Activities.test.tsx b/src/activities/Activities.test.tsx index d5f0c0dd..315fbeb0 100644 --- a/src/activities/Activities.test.tsx +++ b/src/activities/Activities.test.tsx @@ -4,7 +4,8 @@ import { cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; -import Activities, { Activity } from './Activities'; +import Activities from './Activities'; +import { Activity } from './hooks'; afterEach(() => { cleanup(); diff --git a/src/activities/Activities.tsx b/src/activities/Activities.tsx index 7eb27f31..9eb60787 100644 --- a/src/activities/Activities.tsx +++ b/src/activities/Activities.tsx @@ -4,32 +4,18 @@ import './activities.scss'; import { Icon, Tab, Tabs } from '@blueprintjs/core'; import React, { useCallback, useEffect, useRef } from 'react'; -import { useLocalStorage } from 'usehooks-ts'; import Explorer from '../explorer/Explorer'; import Settings from '../settings/Settings'; +import { Activity, useActivitiesSelectedActivity } from './hooks'; import { useI18n } from './i18n'; -/** Indicates the selected activity. */ -export enum Activity { - /** No activity is selected. */ - None = 'activity.none', - /** The explorer activity is selected. */ - Explorer = 'activity.explorer', - /** The settings activity is selected. */ - Settings = 'activity.settings', -} - /** * React component that acts as a tab control to select activities. */ const Activities: React.VoidFunctionComponent = () => { + const [selectedActivity, setSelectedActivity] = useActivitiesSelectedActivity(); const i18n = useI18n(); - const [selectedActivity, setSelectedActivity] = useLocalStorage( - 'activities.selectedActivity', - Activity.Explorer, - ); - const handleAction = useCallback( (newActivity: Activity) => { // if activity is already selected, select none @@ -110,6 +96,7 @@ const Activities: React.VoidFunctionComponent = () => { ref={tabsRef} > { onMouseDown={(e) => e.stopPropagation()} /> { @@ -196,6 +197,7 @@ const App: React.VFC = () => { + ); }; diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 63b13b21..7bf1235d 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -8,6 +8,8 @@ import React, { useRef } from 'react'; import { FocusRing, useButton } from 'react-aria'; type ButtonProps = { + /** Optional DOM ID for the button. */ + id?: string; /** The label for the button. */ label: string; /** If true, the label will not be visible (will use aria-label instead). */ @@ -28,6 +30,7 @@ type ButtonProps = { /** Similar to Blueprint.js button with better accessibility. */ export const Button: React.VoidFunctionComponent = ({ + id, label, hideLabel, description, @@ -59,6 +62,7 @@ export const Button: React.VoidFunctionComponent = ({ {/* useButton() breaks the native browser :focus-visible :-/ */}