From 69dc4d8b075cd6abf48edf458d4b69c73f73dc90 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 5 Sep 2023 19:24:02 +0200 Subject: [PATCH 01/16] refactor: rename ActionButton to IconButton Also: - `ActionButtonWithMenu` => `IconButtonWithMenu` - `ActionToolbar` => `Toolbar` The reasons: - Allow for Action component to use names starting with Action. - Match design system specification, rather than the reference implementation where namings may have historical reasons. --- README.md | 6 +-- packages/example-app/package.json | 1 - .../src/ProjectView/ProjectToolWindow.tsx | 8 +-- .../SearchEverywherePopup.tsx | 6 +-- .../VersionControl/Branches/BranchesPopup.tsx | 16 +++--- .../ActionButtons/ChangeListsActionButton.tsx | 8 +-- .../ActionButtons/GroupByActionButton.tsx | 6 +-- .../ActionButtons/ViewOptionsActionButton.tsx | 6 +-- .../ChangesView/ChangesViewToolbar.tsx | 24 ++++----- .../ChangesViewTreeContextMenu.tsx | 2 +- .../Changes/ChangesView/CommitActionsRow.tsx | 10 ++-- .../Changes/Rollback/RollbackWindow.tsx | 28 +++++----- .../modal-window_menu.cy.tsx | 6 +-- packages/jui/src/ActionButton/index.ts | 1 - .../jui/src/ActionSystem/ActionsProvider.tsx | 52 ++++++++++++++++--- .../ActionSystem/components/ActionButton.tsx | 6 +-- .../components/ActionsMenu.cy.tsx | 5 +- .../jui/src/ActionSystem/components/index.ts | 7 +-- .../useCreateDefaultActionGroup.tsx | 4 +- .../jui/src/ActionSystem/defaultKeymap.tsx | 4 ++ packages/jui/src/ActionSystem/index.ts | 2 + packages/jui/src/Checkbox/Checkbox.tsx | 2 +- .../IconButton.tsx} | 21 +++++--- packages/jui/src/IconButton/index.ts | 1 + .../IconButtonWithMenu.tsx} | 22 ++++---- packages/jui/src/Menu/Menu.stories.tsx | 12 ++--- .../jui/src/Menu/SpeedSearchMenu.stories.tsx | 14 ++--- .../src/ModalWindow/ModalWindow.stories.tsx | 28 +++++----- packages/jui/src/Popup/Popup.stories.tsx | 6 +-- .../jui/src/Popup/PopupTrigger.stories.tsx | 6 +-- packages/jui/src/Popup/PopupTrigger.tsx | 2 +- packages/jui/src/Tabs/TabsOverflowMenu.tsx | 6 +-- .../stories/ToolWindows.stories.tsx | 6 +-- .../stories/components/FakeExecution.tsx | 24 ++++----- .../DefaultToolWindowHeader.tsx | 18 +++---- .../ToolWindowSettingsIconMenu.tsx | 5 +- packages/jui/src/ToolWindowsImpl/index.ts | 2 +- .../ToolWindowsImpl/useToolWindowActions.tsx | 4 +- .../ActionToolbar.tsx => Toolbar/Toolbar.tsx} | 31 +++++------ .../src/Tooltip/TooltipTrigger.stories.tsx | 30 +++++------ packages/jui/src/index.ts | 6 +-- packages/jui/src/theme.stories.tsx | 6 +-- .../{ActionToolbar.mdx => Toolbar.mdx} | 2 +- 43 files changed, 251 insertions(+), 211 deletions(-) delete mode 100644 packages/jui/src/ActionButton/index.ts rename packages/jui/src/{ActionButton/ActionButton.tsx => IconButton/IconButton.tsx} (85%) create mode 100644 packages/jui/src/IconButton/index.ts rename packages/jui/src/{ActionButtonWithMenu/ActionButtonWithMenu.tsx => IconButtonWithMenu/IconButtonWithMenu.tsx} (80%) rename packages/jui/src/{ActionToolbar/ActionToolbar.tsx => Toolbar/Toolbar.tsx} (76%) rename packages/website/docs/components/{ActionToolbar.mdx => Toolbar.mdx} (90%) diff --git a/README.md b/README.md index f3d778c7..6d45b313 100644 --- a/README.md +++ b/README.md @@ -119,15 +119,15 @@ https://user-images.githubusercontent.com/3150694/232305636-e8b63780-4777-4d27-8 ❌ - Action Button + Icon Button (aka ActionButton) ✅ - Action Button with menu 🧬 + Icon Button with menu 🧬 ✅ - Action Toolbar + Toolbar ✅ diff --git a/packages/example-app/package.json b/packages/example-app/package.json index d8e964cb..70be8023 100644 --- a/packages/example-app/package.json +++ b/packages/example-app/package.json @@ -10,7 +10,6 @@ "alias": { "caf": "caf/dist/esm/index.mjs", "@intellij-platform/core/utils/tree-utils": "@intellij-platform/core/src/utils/tree-utils", - "@intellij-platform/core/ActionSystem/components": "@intellij-platform/core/src/ActionSystem/components", "@intellij-platform/core/utils/array-utils": "@intellij-platform/core/src/utils/array-utils" }, "dependencies": { diff --git a/packages/example-app/src/ProjectView/ProjectToolWindow.tsx b/packages/example-app/src/ProjectView/ProjectToolWindow.tsx index abb0a8af..4ac73369 100644 --- a/packages/example-app/src/ProjectView/ProjectToolWindow.tsx +++ b/packages/example-app/src/ProjectView/ProjectToolWindow.tsx @@ -1,13 +1,13 @@ import React from "react"; import { useRecoilValue } from "recoil"; import { + ActionButton, ActionDefinition, CommonActionId, DefaultToolWindow, PlatformIcon, useTreeActions, } from "@intellij-platform/core"; -import { Action } from "@intellij-platform/core/ActionSystem/components"; import { projectViewTreeRefState, @@ -33,9 +33,9 @@ export function ProjectToolWindow() { actions={[...actions, ...projectViewActions]} additionalActions={ <> - - - + + + } > diff --git a/packages/example-app/src/SearchEverywhere/SearchEverywherePopup.tsx b/packages/example-app/src/SearchEverywhere/SearchEverywherePopup.tsx index 80e2d635..074a534c 100644 --- a/packages/example-app/src/SearchEverywhere/SearchEverywherePopup.tsx +++ b/packages/example-app/src/SearchEverywhere/SearchEverywherePopup.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react"; import { useRecoilState, useSetRecoilState } from "recoil"; import { - ActionButton, + IconButton, ActionDefinition, ActionsProvider, FocusScope, @@ -350,9 +350,9 @@ export function SearchEverywherePopup() { {currentTabContributor?.headerFilters} - + - + diff --git a/packages/example-app/src/VersionControl/Branches/BranchesPopup.tsx b/packages/example-app/src/VersionControl/Branches/BranchesPopup.tsx index 5733b484..a16749c4 100644 --- a/packages/example-app/src/VersionControl/Branches/BranchesPopup.tsx +++ b/packages/example-app/src/VersionControl/Branches/BranchesPopup.tsx @@ -1,8 +1,8 @@ import path from "path"; import React, { useState } from "react"; import { - ActionButton, - ActionToolbar, + IconButton, + Toolbar, ActionTooltip, BalloonActionLink, Bounds, @@ -108,21 +108,21 @@ export function BranchesPopup({ onClose }: { onClose: () => void }) { {title} - + }> - { notImplemented(); onClose(); }} > - + } > - { setBranchesPopupPersistedSize(undefined); @@ -134,9 +134,9 @@ export function BranchesPopup({ onClose }: { onClose: () => void }) { }} > - + - + } diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ChangeListsActionButton.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ChangeListsActionButton.tsx index 1d07a964..379ca91f 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ChangeListsActionButton.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ChangeListsActionButton.tsx @@ -1,11 +1,11 @@ import React from "react"; import { - ActionButtonWithMenu, + IconButtonWithMenu, PlatformIcon, useAction, } from "@intellij-platform/core"; import { VcsActionIds } from "../../../VcsActionIds"; -import { ActionsMenu } from "@intellij-platform/core/ActionSystem/components"; +import { ActionsMenu } from "@intellij-platform/core"; import { notNull } from "@intellij-platform/core/utils/array-utils"; export const ChangeListsActionButton = (): React.ReactElement => { @@ -18,12 +18,12 @@ export const ChangeListsActionButton = (): React.ReactElement => { ].filter(notNull); return ( - ( )} > - + ); }; diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/GroupByActionButton.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/GroupByActionButton.tsx index 58c60b59..50ac4b64 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/GroupByActionButton.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/GroupByActionButton.tsx @@ -6,7 +6,7 @@ import { GroupingIds, } from "../ChangesView.state"; import { - ActionButtonWithMenu, + IconButtonWithMenu, Item, Menu, PlatformIcon, @@ -27,7 +27,7 @@ export const GroupByActionButton = (): React.ReactElement => { ); return ( - ( { )} > - + ); }; diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ViewOptionsActionButton.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ViewOptionsActionButton.tsx index 0b4fb6ec..e7731247 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ViewOptionsActionButton.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/ActionButtons/ViewOptionsActionButton.tsx @@ -5,7 +5,7 @@ import { showRelatedFilesState, } from "../ChangesView.state"; import { - ActionButtonWithMenu, + IconButtonWithMenu, Item, Menu, PlatformIcon, @@ -21,7 +21,7 @@ export const ViewOptionsActionButton = (): React.ReactElement => { const viewOptions = { showRelatedFiles, showIgnoredFiles }; return ( - ( { )} > - + ); }; diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewToolbar.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewToolbar.tsx index 27349305..7b93462c 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewToolbar.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewToolbar.tsx @@ -1,37 +1,37 @@ import { - ActionToolbar, - ActionToolbarSeparator, + Toolbar, + ToolbarSeparator, ActionTooltip, CommonActionId, TooltipTrigger, + ActionButton, } from "@intellij-platform/core"; import { ChangeListsActionButton } from "./ActionButtons/ChangeListsActionButton"; import { GroupByActionButton } from "./ActionButtons/GroupByActionButton"; import { ViewOptionsActionButton } from "./ActionButtons/ViewOptionsActionButton"; import React from "react"; -import { Action } from "@intellij-platform/core/ActionSystem/components"; import { VcsActionIds } from "../../VcsActionIds"; export function ChangesViewToolbar() { return ( - - - - + + + + }> - - + + }> }> - - - + + + ); } diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewTreeContextMenu.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewTreeContextMenu.tsx index cdf5d07f..2535ce6c 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewTreeContextMenu.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/ChangesViewTreeContextMenu.tsx @@ -3,7 +3,7 @@ import { selectedKeysState } from "./ChangesView.state"; import { DividerItem, useAction } from "@intellij-platform/core"; import React from "react"; import { VcsActionIds } from "../../VcsActionIds"; -import { ActionsMenu } from "@intellij-platform/core/ActionSystem/components"; +import { ActionsMenu } from "@intellij-platform/core"; import { notNull } from "@intellij-platform/core/utils/array-utils"; export const ChangesViewTreeContextMenu = () => { diff --git a/packages/example-app/src/VersionControl/Changes/ChangesView/CommitActionsRow.tsx b/packages/example-app/src/VersionControl/Changes/ChangesView/CommitActionsRow.tsx index 6688023a..ed28dc6e 100644 --- a/packages/example-app/src/VersionControl/Changes/ChangesView/CommitActionsRow.tsx +++ b/packages/example-app/src/VersionControl/Changes/ChangesView/CommitActionsRow.tsx @@ -1,7 +1,7 @@ import React from "react"; import { useRecoilState, useRecoilValue } from "recoil"; import { - ActionButton, + IconButton, ActionHelpTooltip, ActionTooltip, Checkbox, @@ -68,16 +68,16 @@ export function CommitActionsRow() { } > - + - + } > - + - + diff --git a/packages/example-app/src/VersionControl/Changes/Rollback/RollbackWindow.tsx b/packages/example-app/src/VersionControl/Changes/Rollback/RollbackWindow.tsx index cc313ec3..cc58fccb 100644 --- a/packages/example-app/src/VersionControl/Changes/Rollback/RollbackWindow.tsx +++ b/packages/example-app/src/VersionControl/Changes/Rollback/RollbackWindow.tsx @@ -2,10 +2,10 @@ import React, { Key, useRef, useState } from "react"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import { Selection } from "@react-types/shared"; import { - ActionButton, - ActionButtonWithMenu, + IconButton, + IconButtonWithMenu, ActionsProvider, - ActionToolbar, + Toolbar, Button, Checkbox, CommonActionId, @@ -23,8 +23,8 @@ import { useNestedSelectionState, useTreeActions, WindowLayout, + ActionButton, } from "@intellij-platform/core"; -import { Action } from "@intellij-platform/core/ActionSystem/components"; import { changesTreeNodesState } from "../ChangesView/ChangesView.state"; import { getChangeListTreeItemProps } from "../ChangesView/changesTreeNodeRenderers"; @@ -116,11 +116,11 @@ export function RollbackWindow() { {({ shortcutHandlerProps }) => (
- - + + - - + ( - - + + - - - - + + + +
diff --git a/packages/jui/integration-tests/modal-window_menu.cy.tsx b/packages/jui/integration-tests/modal-window_menu.cy.tsx index 1f864712..29c98264 100644 --- a/packages/jui/integration-tests/modal-window_menu.cy.tsx +++ b/packages/jui/integration-tests/modal-window_menu.cy.tsx @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { - ActionButton, + IconButton, FocusScope, Item, Menu, @@ -31,9 +31,9 @@ const ModalOnMenuItem = () => { )} > {(props, ref) => ( - + - + )} {isOpen && ( diff --git a/packages/jui/src/ActionButton/index.ts b/packages/jui/src/ActionButton/index.ts deleted file mode 100644 index 4b6341ed..00000000 --- a/packages/jui/src/ActionButton/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./ActionButton"; diff --git a/packages/jui/src/ActionSystem/ActionsProvider.tsx b/packages/jui/src/ActionSystem/ActionsProvider.tsx index 01ca9bdf..ffb2b7bb 100644 --- a/packages/jui/src/ActionSystem/ActionsProvider.tsx +++ b/packages/jui/src/ActionSystem/ActionsProvider.tsx @@ -19,23 +19,48 @@ import { dfsVisit } from "@intellij-platform/core/utils/tree-utils"; export interface ActionContext { element: Element | null; + /** + * UI event that triggered the action, if a shortcut triggered the action. + */ event: | React.MouseEvent | React.KeyboardEvent | null; } +/** + * Represents the definition of an action. + * @interface + */ export interface ActionDefinition { + /** + * The unique identifier for the action. Used to assign shortcuts to the action, via a {@link Keymap}. + */ id: string; + /** + * The title of an action. + * This value will be used as the text in UI display for the action. + */ title: string; - actionPerformed: ( - /** - * UI event that triggered the action, if a shortcut triggered the action. - */ - context: ActionContext - ) => void; + /** + * The function that will be executed when the action is performed. + * @param context It provides further information about the action event. + */ + actionPerformed: (context: ActionContext) => void; + /** + * An optional icon for an action. + * If provided, it will be displayed along with the title in the UI. + */ icon?: React.ReactNode; + /** + * An optional description for an action. + * If provided, it can be displayed as additional information about the action in the UI. + */ description?: string; + /** + * An optional disable state for an action. + * If set to `true`, this action would be in disabled state and cannot be performed. + */ isDisabled?: boolean; } @@ -61,7 +86,13 @@ export interface MutableAction } export type Action = Readonly; +/** + * Represents the properties required for the ActionsProvider component. + */ interface ActionsProviderProps { + /** + * A collection of action definitions. + */ actions: ActionDefinition[]; children: (args: { shortcutHandlerProps: HTMLAttributes; @@ -83,6 +114,15 @@ function generateId() { const ACTION_PROVIDER_ID_ATTRIBUTE = "data-action-provider"; const ACTION_PROVIDER_ID_DATA_PREFIX = "action_provider_id_"; const actionProvidersMap = new Map(); + +/** + * Provides a set of actions for the wrapped UI. Uses the currently provided keymap to find the shortcuts + * for each action, and passes the necessary event handlers for the shortcuts, to the `children` render function. + * + * @param {Array} props.actions - The actions to be provided. + * @param {boolean} [props.useCapture] - Specifies whether to use capture phase for event handling. + * @param {Function} props.children - Render function that accepts shortcutHandlerProps as argument. + */ export function ActionsProvider(props: ActionsProviderProps): JSX.Element { const parentContext = useContext(ActionsContext); const keymap = useKeymap(); diff --git a/packages/jui/src/ActionSystem/components/ActionButton.tsx b/packages/jui/src/ActionSystem/components/ActionButton.tsx index 8a6cb676..d23361fd 100644 --- a/packages/jui/src/ActionSystem/components/ActionButton.tsx +++ b/packages/jui/src/ActionSystem/components/ActionButton.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useAction } from "@intellij-platform/core/ActionSystem"; -import { ActionButton as ActionButtonUI } from "@intellij-platform/core/ActionButton"; +import { IconButton } from "@intellij-platform/core/IconButton"; import { ActionTooltip, TooltipTrigger } from "@intellij-platform/core/Tooltip"; export const ActionButton = ({ @@ -18,12 +18,12 @@ export const ActionButton = ({ return <>; } const actionButton = ( - action?.perform()} isDisabled={action.isDisabled} > {action.icon || children} - + ); if (action.title) { return ( diff --git a/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx b/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx index 5e2c5def..d8147a57 100644 --- a/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx +++ b/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx @@ -1,8 +1,5 @@ import React from "react"; -import { - ActionItem, - ActionsMenu, -} from "@intellij-platform/core/ActionSystem/components"; +import { ActionItem, ActionsMenu } from "@intellij-platform/core"; import { ActionGroupDefinition, ActionsProvider, diff --git a/packages/jui/src/ActionSystem/components/index.ts b/packages/jui/src/ActionSystem/components/index.ts index 12338391..6d51729a 100644 --- a/packages/jui/src/ActionSystem/components/index.ts +++ b/packages/jui/src/ActionSystem/components/index.ts @@ -1,13 +1,10 @@ -import { ActionButton } from "./ActionButton"; +export { ActionButton } from "./ActionButton"; export { ActionsMenu, + renderActionAsMenuItem, type ActionMenuProps, type ActionItem, } from "./ActionsMenu"; export { ActionGroupMenu, type ActionGroupMenuProps } from "./ActionGroupMenu"; -export const Action = { - Button: ActionButton, -}; - export { useCreateDefaultActionGroup } from "./useCreateDefaultActionGroup"; diff --git a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx index 3cfd3c3d..ef9bea8e 100644 --- a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx +++ b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx @@ -1,3 +1,4 @@ +import { flatten } from "ramda"; import React from "react"; import { ActionGroupDefinition, @@ -10,8 +11,7 @@ import { } from "@intellij-platform/core/ActionSystem"; import { SpeedSearchMenu } from "@intellij-platform/core/Menu"; import { useEventCallback } from "@intellij-platform/core/utils/useEventCallback"; -import { renderActionAsMenuItem } from "@intellij-platform/core/ActionSystem/components/ActionsMenu"; -import { flatten } from "ramda"; +import { renderActionAsMenuItem } from "./ActionsMenu"; export const useCreateDefaultActionGroup = () => { const { show } = usePopupManager(); diff --git a/packages/jui/src/ActionSystem/defaultKeymap.tsx b/packages/jui/src/ActionSystem/defaultKeymap.tsx index de24ed82..49bb640a 100644 --- a/packages/jui/src/ActionSystem/defaultKeymap.tsx +++ b/packages/jui/src/ActionSystem/defaultKeymap.tsx @@ -17,6 +17,10 @@ import { CommonActionId } from "@intellij-platform/core/ActionSystem/CommonActio // TODO: OS specific defaults // TODO: extract and export action ids // NOTE: defaultKeymap doesn't belong to ActionSystem semantically. Would be something to be moved to a separate module +/** + * Default Intellij Idea keymapping for common action ids, including tool window actions. + * @see CommonActionId + */ export const defaultKeymap: Keymap = { [RESIZE_TOOL_WINDOW_RIGHT_ACTION_ID]: [ { diff --git a/packages/jui/src/ActionSystem/index.ts b/packages/jui/src/ActionSystem/index.ts index 88a6b26c..da03b136 100644 --- a/packages/jui/src/ActionSystem/index.ts +++ b/packages/jui/src/ActionSystem/index.ts @@ -6,3 +6,5 @@ export * from "./ActionShortcut"; export * from "./CommonActionIds"; export * from "./shortcutToString"; export * from "./ActionGroup"; + +export * from "./components"; diff --git a/packages/jui/src/Checkbox/Checkbox.tsx b/packages/jui/src/Checkbox/Checkbox.tsx index f4bb2b14..de2c3064 100644 --- a/packages/jui/src/Checkbox/Checkbox.tsx +++ b/packages/jui/src/Checkbox/Checkbox.tsx @@ -28,7 +28,7 @@ export interface CheckboxProps * a questionably better UX. * Note: Passing {@link excludeFromTabOrder} will still let the checkbox be focusable, while `preventFocus`, doesn't * let the component get focused at all. - * TODO(potential): it might be nicer to have a `preventFocusOnPress` prop consistent with ActionButton, instead. + * TODO(potential): it might be nicer to have a `preventFocusOnPress` prop consistent with IconButton, instead. * In that case preventing focus completely would be achieved with `preventFocusOnPres` and `excludeFromTabOrder`. */ preventFocus?: boolean; diff --git a/packages/jui/src/ActionButton/ActionButton.tsx b/packages/jui/src/IconButton/IconButton.tsx similarity index 85% rename from packages/jui/src/ActionButton/ActionButton.tsx rename to packages/jui/src/IconButton/IconButton.tsx index 6946e2cd..4f6e282c 100644 --- a/packages/jui/src/ActionButton/ActionButton.tsx +++ b/packages/jui/src/IconButton/IconButton.tsx @@ -4,7 +4,7 @@ import { styled } from "../styled"; import { mergeProps, useObjectRef } from "@react-aria/utils"; import { useFocusable } from "@react-aria/focus"; -export interface ActionButtonProps +export interface IconButtonProps extends PressProps, // Maybe we should allow any arbitrary HTMLProps props, instead of whitelisting? Pick< @@ -12,10 +12,13 @@ export interface ActionButtonProps "onFocus" | "onBlur" | "style" | "className" > { children?: React.ReactNode; + /** + * The minimum width/height of the button. + */ minSize?: number; /** - * Whether the button should be focusable by pressing tab. The default is true for action buttons, which means they - * are not included in the tab order. + * Whether the button should be focusable by pressing tab. The default is true for icon buttons (aka. action buttons), + * which means they are not included in the tab order. */ excludeFromTabOrder?: boolean; } @@ -23,7 +26,7 @@ export interface ActionButtonProps export const DEFAULT_MINIMUM_BUTTON_SIZE = 22; export const NAVBAR_MINIMUM_BUTTON_SIZE = 20; -export const StyledActionButton = styled.button<{ minSize: number }>` +export const StyledIconButton = styled.button<{ minSize: number }>` position: relative; // to allow absolutely positioned overlays like an dropdown icon at the bottom right corner background: none; color: inherit; @@ -58,7 +61,11 @@ export const StyledActionButton = styled.button<{ minSize: number }>` } `; -export const ActionButton = React.forwardRef(function ActionButton( +/** + * Icon button, aka Action Button, in the reference implementation. + * @see https://jetbrains.github.io/ui/controls/icon_button/ + */ +export const IconButton = React.forwardRef(function IconButton( { minSize = DEFAULT_MINIMUM_BUTTON_SIZE, preventFocusOnPress = true, @@ -72,7 +79,7 @@ export const ActionButton = React.forwardRef(function ActionButton( onPressUp, shouldCancelOnPointerExit, ...otherProps - }: ActionButtonProps, + }: IconButtonProps, forwardedRef: ForwardedRef ) { // FIXME: use useButton @@ -93,7 +100,7 @@ export const ActionButton = React.forwardRef(function ActionButton( }); return ( - & { /** * whether the default arrow should be removed or not. false by default. @@ -22,22 +22,22 @@ type ActionButtonWithMenuProps = ActionButtonProps & noArrow?: boolean; }; /** - * Renders an ActionButton which opens a menu. by default a down arrow icon is shown as an overlay on the rendered + * Renders an IconButton which opens a menu. by default a down arrow icon is shown as an overlay on the rendered * icon, but it can be disabled by passing `noArrow`. It also restores the focus to the previously focused element, * when the menu is closed. * @param renderMenu: render prop for rendering the menu - * @param children: the content of the action button + * @param children: the content of the icon button * @param noArrow: whether the default arrow should be removed or not. false by default. - * @param buttonProps: the rest of the props that will be passed down to ActionButton + * @param buttonProps: the rest of the props that will be passed down to IconButton * * TODO: Add story and write test for focus restoration, noArrow, and basic functionality. */ -export const ActionButtonWithMenu = ({ +export const IconButtonWithMenu = ({ renderMenu, children, noArrow = false, ...buttonProps -}: ActionButtonWithMenuProps) => { +}: IconButtonWithMenuProps) => { const previouslyFocusedElementRef = useRef(); return ( {(props, ref) => ( - { if (e.relatedTarget && e.relatedTarget instanceof HTMLElement) { @@ -61,7 +61,7 @@ export const ActionButtonWithMenu = ({ > {children} {!noArrow && } - + )} ); diff --git a/packages/jui/src/Menu/Menu.stories.tsx b/packages/jui/src/Menu/Menu.stories.tsx index f8495f7d..3d2cda19 100644 --- a/packages/jui/src/Menu/Menu.stories.tsx +++ b/packages/jui/src/Menu/Menu.stories.tsx @@ -3,8 +3,8 @@ import { StoryObj, StoryFn, Meta } from "@storybook/react"; import { Item } from "@react-stately/collections"; import { ContextMenuContainer, styled } from "@intellij-platform/core"; -import { ActionButton } from "../ActionButton"; -import { ActionToolbar } from "../ActionToolbar/ActionToolbar"; +import { IconButton } from "../IconButton"; +import { Toolbar } from "@intellij-platform/core/Toolbar/Toolbar"; import { Divider, DividerItem } from "../Collections/Divider"; import { PlatformIcon } from "../Icon"; import { styledComponentsControlsExclude } from "../story-helpers"; @@ -198,7 +198,7 @@ export const MenuWithTrigger: StoryObj< : undefined, }} > - + ( @@ -216,12 +216,12 @@ export const MenuWithTrigger: StoryObj< )} > {(props, ref) => ( - + - + )} - + ); }, diff --git a/packages/jui/src/Menu/SpeedSearchMenu.stories.tsx b/packages/jui/src/Menu/SpeedSearchMenu.stories.tsx index b059eeb3..95b29b0c 100644 --- a/packages/jui/src/Menu/SpeedSearchMenu.stories.tsx +++ b/packages/jui/src/Menu/SpeedSearchMenu.stories.tsx @@ -2,11 +2,7 @@ import React from "react"; import { Meta, StoryFn } from "@storybook/react"; import { PlatformIcon } from "@intellij-platform/core/Icon"; import { DividerItem, Item } from "@intellij-platform/core/Collections"; -import { - ActionButton, - ActionToolbar, - MenuTrigger, -} from "@intellij-platform/core"; +import { IconButton, Toolbar, MenuTrigger } from "@intellij-platform/core"; import { Section } from "@react-stately/collections"; import { styledComponentsControlsExclude } from "../story-helpers"; @@ -93,7 +89,7 @@ export const WithTrigger = { menuProps: Partial>; }) => { return ( - + ( {(props, ref) => ( - + - + )} - + ); }, }; diff --git a/packages/jui/src/ModalWindow/ModalWindow.stories.tsx b/packages/jui/src/ModalWindow/ModalWindow.stories.tsx index 3b334b6b..6e766ea6 100644 --- a/packages/jui/src/ModalWindow/ModalWindow.stories.tsx +++ b/packages/jui/src/ModalWindow/ModalWindow.stories.tsx @@ -4,8 +4,8 @@ import { ModalWindow, ModalWindowProps } from "./ModalWindow"; import { SpeedSearchTreeSample } from "@intellij-platform/core/story-components"; import { Bounds, containedWithin } from "@intellij-platform/core/Overlay"; import { - ActionButton, - ActionToolbar, + IconButton, + Toolbar, Button, Checkbox, PlatformIcon, @@ -234,23 +234,23 @@ export const WithTallFooter: StoryObj = { content={
- - + + - - + + - - + + - - + + - - + + - - + +
diff --git a/packages/jui/src/Popup/Popup.stories.tsx b/packages/jui/src/Popup/Popup.stories.tsx index 06cfea86..a0e27b17 100644 --- a/packages/jui/src/Popup/Popup.stories.tsx +++ b/packages/jui/src/Popup/Popup.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Meta, StoryFn, StoryObj } from "@storybook/react"; import { - ActionButton, + IconButton, Checkbox, FocusScope, PlatformIcon, @@ -197,9 +197,9 @@ export const CustomHeader: StoryObj = { 6+ usages - + - + } diff --git a/packages/jui/src/Popup/PopupTrigger.stories.tsx b/packages/jui/src/Popup/PopupTrigger.stories.tsx index f3a27525..906e4675 100644 --- a/packages/jui/src/Popup/PopupTrigger.stories.tsx +++ b/packages/jui/src/Popup/PopupTrigger.stories.tsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { Meta, StoryFn, StoryObj } from "@storybook/react"; import { - ActionButton, + IconButton, Checkbox, PlatformIcon, Popup, @@ -20,9 +20,9 @@ export default { component: PopupTrigger, args: { children: ( - + - + ), popup: ( diff --git a/packages/jui/src/Popup/PopupTrigger.tsx b/packages/jui/src/Popup/PopupTrigger.tsx index d02f1656..335e9f72 100644 --- a/packages/jui/src/Popup/PopupTrigger.tsx +++ b/packages/jui/src/Popup/PopupTrigger.tsx @@ -22,7 +22,7 @@ export interface PopupTriggerProps /** * Popup opened by a trigger. `trigger` can be an element of any pressable component (such as {@link Button} or - * {@link ActionButton}), and is rendered in place. Similar to {@link Popup component}, `children` defines the content + * {@link IconButton}), and is rendered in place. Similar to {@link Popup component}, `children` defines the content * of Popup. */ export const PopupTrigger = React.forwardRef(function PopupTrigger( diff --git a/packages/jui/src/Tabs/TabsOverflowMenu.tsx b/packages/jui/src/Tabs/TabsOverflowMenu.tsx index fa2a5fa4..2fd57a38 100644 --- a/packages/jui/src/Tabs/TabsOverflowMenu.tsx +++ b/packages/jui/src/Tabs/TabsOverflowMenu.tsx @@ -1,7 +1,7 @@ import { Collection, Node } from "@react-types/shared"; import { Item } from "@react-stately/collections"; import { Menu, MenuTrigger } from "@intellij-platform/core/Menu"; -import { ActionButton } from "@intellij-platform/core/ActionButton"; +import { IconButton } from "@intellij-platform/core/IconButton"; import { PlatformIcon } from "@intellij-platform/core/Icon"; import React, { Key } from "react"; @@ -40,9 +40,9 @@ export const TabsOverflowMenu = ({ }} > {(props, ref) => ( - + - + )} )} diff --git a/packages/jui/src/ToolWindows/stories/ToolWindows.stories.tsx b/packages/jui/src/ToolWindows/stories/ToolWindows.stories.tsx index 22b8c9d9..f6701dba 100644 --- a/packages/jui/src/ToolWindows/stories/ToolWindows.stories.tsx +++ b/packages/jui/src/ToolWindows/stories/ToolWindows.stories.tsx @@ -13,7 +13,7 @@ import { import { indexBy, map } from "ramda"; import React, { useState } from "react"; import packageJson from "../../../package.json"; -import { ActionButton } from "../../ActionButton"; +import { IconButton } from "../../IconButton"; import { SpeedSearchTreeSample } from "../../story-components"; import { styledComponentsControlsExclude } from "../../story-helpers"; import { DefaultToolWindow } from "../../ToolWindowsImpl/DefaultToolWindow"; @@ -52,9 +52,9 @@ const windows = [ headerContent="Project" additionalActions={ <> - + - + } > diff --git a/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx b/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx index 15502403..ae994aee 100644 --- a/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx +++ b/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; -import { ActionToolbar } from "../../../ActionToolbar/ActionToolbar"; -import { ActionButton } from "../../../ActionButton"; +import { Toolbar } from "@intellij-platform/core/Toolbar/Toolbar"; +import { IconButton } from "../../../IconButton"; import { PlatformIcon } from "../../../Icon"; import { StyledHorizontalSeparator } from "../../../StyledSeparator"; import { styled } from "../../../styled"; @@ -74,21 +74,21 @@ export const FakeExecutionToolbar = ({ execution: Execution; toggle: (executionId: string) => void; }) => ( - - toggle(id)}> + + toggle(id)}> - - toggle(id)}> + + toggle(id)}> - + - + - - + + - - + + ); export const VerticalFlexContainer = styled.div` diff --git a/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx b/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx index c62d2e01..0b20ab23 100644 --- a/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx +++ b/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx @@ -1,18 +1,18 @@ import React, { HTMLProps } from "react"; -import { ActionButton } from "@intellij-platform/core/ActionButton"; -import { ActionToolbar } from "@intellij-platform/core/ActionToolbar/ActionToolbar"; +import { IconButton } from "@intellij-platform/core/IconButton"; +import { Toolbar } from "@intellij-platform/core/Toolbar/Toolbar"; import { PlatformIcon } from "@intellij-platform/core/Icon"; import { MenuTrigger } from "@intellij-platform/core/Menu/MenuTrigger"; import { ActionTooltip, TooltipTrigger } from "@intellij-platform/core/Tooltip"; import { styled } from "@intellij-platform/core/styled"; import { StyledHorizontalSeparator } from "@intellij-platform/core/StyledSeparator"; import { UnknownThemeProp } from "@intellij-platform/core/Theme/Theme"; -import { Action } from "@intellij-platform/core/ActionSystem/components"; import { ToolWindowSettingsIconMenu } from "./ToolWindowSettingsIconMenu"; import { DOCK_TOOL_WINDOW_ACTION_ID, HIDE_ACTIVE_WINDOW_ACTION_ID, } from "./ToolWindowActionIds"; +import { ActionButton } from "@intellij-platform/core/ActionSystem"; export interface ToolWindowHeaderProps extends Omit, "ref" | "as"> { @@ -65,14 +65,14 @@ export const DefaultToolWindowHeader: React.FC = ({ {children} - + {additionalActions && ( <> {additionalActions} )} - + { return ; @@ -80,14 +80,14 @@ export const DefaultToolWindowHeader: React.FC = ({ > {(props, ref) => ( }> - + - + )} - - + + ); diff --git a/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx b/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx index ac137d30..c4594d0f 100644 --- a/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx +++ b/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx @@ -5,10 +5,7 @@ import { useAction, useActionGroup, } from "@intellij-platform/core/ActionSystem"; -import { - ActionItem, - ActionsMenu, -} from "@intellij-platform/core/ActionSystem/components/ActionsMenu"; +import { ActionItem, ActionsMenu } from "@intellij-platform/core/ActionSystem"; import { MOVE_TO_ACTION_GROUP_ID, TOOL_WINDOW_RESIZE_ACTION_GROUP_ID, diff --git a/packages/jui/src/ToolWindowsImpl/index.ts b/packages/jui/src/ToolWindowsImpl/index.ts index 881dc827..bb721836 100644 --- a/packages/jui/src/ToolWindowsImpl/index.ts +++ b/packages/jui/src/ToolWindowsImpl/index.ts @@ -1,6 +1,6 @@ /** * Default implementation of Tool Window UI. Unlike the core part of ToolWindow API, this module depends - * on other modules and components, e.g. Menu, ActionButton, Tabs, Action System, etc. + * on other modules and components, e.g. Menu, IconButton, Tabs, Action System, etc. */ export * from "./DefaultToolWindows"; export * from "./useToolWindowsActions"; diff --git a/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx b/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx index ee52c95f..cf8fff6e 100644 --- a/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx +++ b/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx @@ -23,8 +23,8 @@ import { UNDOCK_MODE_ACTION_ID, WINDOW_MODE_ACTION_ID, } from "./ToolWindowActionIds"; -import { ActionGroupDefinition } from "@intellij-platform/core/ActionSystem/ActionGroup"; -import { useCreateDefaultActionGroup } from "@intellij-platform/core/ActionSystem/components"; +import { ActionGroupDefinition } from "@intellij-platform/core/ActionSystem"; +import { useCreateDefaultActionGroup } from "@intellij-platform/core/ActionSystem"; // Resize steps in Intellij Platform is calculated based on the size of a "W" character and some // configuration (ide.windowSystem.hScrollChars). Although it's technically feasible, it seems not necessary diff --git a/packages/jui/src/ActionToolbar/ActionToolbar.tsx b/packages/jui/src/Toolbar/Toolbar.tsx similarity index 76% rename from packages/jui/src/ActionToolbar/ActionToolbar.tsx rename to packages/jui/src/Toolbar/Toolbar.tsx index 80ed4eb5..1058967c 100644 --- a/packages/jui/src/ActionToolbar/ActionToolbar.tsx +++ b/packages/jui/src/Toolbar/Toolbar.tsx @@ -1,20 +1,21 @@ -import { Theme } from "@intellij-platform/core/Theme"; import React, { useContext } from "react"; -import { StyledActionButton } from "../ActionButton"; +import { Theme } from "@intellij-platform/core/Theme"; + +import { StyledIconButton } from "../IconButton"; import { styled } from "../styled"; import { StyledHorizontalSeparator, StyledVerticalSeparator, } from "../StyledSeparator"; -interface ActionToolbarProps { +interface ToolbarProps { orientation?: "vertical" | "horizontal"; /** * Whether to include a border to the bottom/right the toolbar, or not. */ hasBorder?: boolean; } -const StyledActionToolbar = styled.div` +const StyledToolbar = styled.div` display: flex; `; @@ -31,7 +32,7 @@ const getBorder = ({ theme.dark ? "rgb(50,50,50)" : "rgb(192, 192, 192)" )}` : "none"; -const StyledHorizontalActionToolbar = styled(StyledActionToolbar)<{ +const StyledHorizontalToolbar = styled(StyledToolbar)<{ hasBorder?: boolean; }>` padding: 2px; @@ -42,12 +43,12 @@ const StyledHorizontalActionToolbar = styled(StyledActionToolbar)<{ // NOTE: in the original implementation, there is no empty space between buttons, but buttons have kind of an // invisible left padding, which is mouse-intractable, but doesn't visually seem a part of the button. // Although implementable, it didn't seem necessary to follow the exact same thing. Margin should be fine. - ${StyledActionButton} { + ${StyledIconButton} { margin: 0 2px 0 2px; } `; -const StyledVerticalActionToolbar = styled(StyledActionToolbar)<{ +const StyledVerticalToolbar = styled(StyledToolbar)<{ hasBorder?: boolean; }>` flex-direction: column; @@ -57,7 +58,7 @@ const StyledVerticalActionToolbar = styled(StyledActionToolbar)<{ ${StyledVerticalSeparator} { margin: 4px 1px; } - ${StyledActionButton} { + ${StyledIconButton} { margin: 2px 0 1px 0; } `; @@ -74,7 +75,7 @@ const OrientationContext = React.createContext<"horizontal" | "vertical">( * - hidden, shown by arrow. Similar to actions in Git->Log. Note that the behaviour for horizontal and vertical * modes are different apparently. */ -export const ActionToolbar: React.FC = ({ +export const Toolbar: React.FC = ({ orientation = "horizontal", hasBorder = false, children, @@ -82,22 +83,22 @@ export const ActionToolbar: React.FC = ({ return ( {orientation === "horizontal" ? ( - + {children} - + ) : ( - + {children} - + )} ); }; /** - * Separator to be used between action buttons in an action toolbar. + * Separator to be used between items in a toolbar. */ -export const ActionToolbarSeparator = (): React.ReactElement => { +export const ToolbarSeparator = (): React.ReactElement => { const orientation = useContext(OrientationContext); return orientation === "horizontal" ? ( diff --git a/packages/jui/src/Tooltip/TooltipTrigger.stories.tsx b/packages/jui/src/Tooltip/TooltipTrigger.stories.tsx index 9f60688b..1633b67f 100644 --- a/packages/jui/src/Tooltip/TooltipTrigger.stories.tsx +++ b/packages/jui/src/Tooltip/TooltipTrigger.stories.tsx @@ -2,10 +2,10 @@ import { Meta, StoryFn, StoryObj } from "@storybook/react"; import React from "react"; import { Tooltip } from "./Tooltip"; import { - ActionButton, + IconButton, ActionHelpTooltip, - ActionToolbar, - ActionToolbarSeparator, + Toolbar, + ToolbarSeparator, Button, Link, PlatformIcon, @@ -69,24 +69,24 @@ export const All: StoryFn = () => { }> - + }> - + - + }> - + - + - + }> - + - + - + = () => { /> } > - + - + - + ); }; diff --git a/packages/jui/src/index.ts b/packages/jui/src/index.ts index 17b234ce..9a182f34 100644 --- a/packages/jui/src/index.ts +++ b/packages/jui/src/index.ts @@ -7,9 +7,9 @@ export * from "./Menu"; export * from "./ToolWindows"; export * from "./ToolWindowsImpl"; export * from "./ActionSystem"; -export * from "./ActionButton"; -export * from "./ActionToolbar/ActionToolbar"; -export * from "./ActionButtonWithMenu/ActionButtonWithMenu"; +export * from "./IconButton"; +export * from "@intellij-platform/core/Toolbar/Toolbar"; +export * from "@intellij-platform/core/IconButtonWithMenu/IconButtonWithMenu"; export * from "./Icon"; export * from "./TextWithHighlights/TextWithHighlights"; export * from "./SpeedSearch"; diff --git a/packages/jui/src/theme.stories.tsx b/packages/jui/src/theme.stories.tsx index c3477442..0cb44653 100644 --- a/packages/jui/src/theme.stories.tsx +++ b/packages/jui/src/theme.stories.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { indexBy, map } from "ramda"; import { Meta, StoryFn } from "@storybook/react"; import { - ActionButton, + IconButton, ActionHelpTooltip, ActionTooltip, AutoHoverPlatformIcon, @@ -71,9 +71,9 @@ export const Theme: StoryFn = () => { headerContent="SpeedSearchTree" additionalActions={ <> - + - + } > diff --git a/packages/website/docs/components/ActionToolbar.mdx b/packages/website/docs/components/Toolbar.mdx similarity index 90% rename from packages/website/docs/components/ActionToolbar.mdx rename to packages/website/docs/components/Toolbar.mdx index 687f6dbb..de3c4668 100644 --- a/packages/website/docs/components/ActionToolbar.mdx +++ b/packages/website/docs/components/Toolbar.mdx @@ -4,4 +4,4 @@ import { RefToIntellijPlatform } from "@site/src/components/RefToIntellijPlatform.tsx"; import { Example } from "@site/src/components/ExampleContext"; -# Action Toolbar +# Toolbar From ae7316df87f14778d7be3d29d08d39f03c7f5ec8 Mon Sep 17 00:00:00 2001 From: Alireza Date: Sat, 9 Sep 2023 21:42:40 +0200 Subject: [PATCH 02/16] fix(action-system): fix a bug in detecting action items in ActionsMenu Also, unofficially allow for menu sections with divider, to avoid the need for a separate item. It's not clear at this point, if it makes sense to make it an option on the public API, and it's only internally used in ActionsMenu --- .../ActionSystem/components/ActionGroupMenu.tsx | 4 +--- .../src/ActionSystem/components/ActionsMenu.tsx | 7 +++++-- packages/jui/src/Menu/renderMenuNodes.tsx | 17 +++++++++++------ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx b/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx index 51aa93a6..21d2957a 100644 --- a/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx +++ b/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx @@ -6,9 +6,7 @@ export type ActionGroupMenuProps = Omit & { actionGroup: ActionGroup; }; /** - * Renders children of an action group as a menu - * - * TODO: handle isPopup in children groups to render the child group as either a section or submenu + * Renders children of an action group as a menu. */ export const ActionGroupMenu = ({ actionGroup, diff --git a/packages/jui/src/ActionSystem/components/ActionsMenu.tsx b/packages/jui/src/ActionSystem/components/ActionsMenu.tsx index dbd963d2..37c6ea20 100644 --- a/packages/jui/src/ActionSystem/components/ActionsMenu.tsx +++ b/packages/jui/src/ActionSystem/components/ActionsMenu.tsx @@ -16,7 +16,7 @@ type ActionGroupAsMenuItem = Pick< export type ActionItem = ActionGroupAsMenuItem | Action | DividerItem; function isAction(item: ActionItem): item is Action { - return "actionPerformed" in item; + return "perform" in item; } export type ActionMenuProps = { @@ -70,7 +70,10 @@ export function renderActionAsMenuItem( const isGroup = "children" in action; if (isGroup && !action.isPopup) { return ( -
+ // `title` is intentionally not passed, as menu sections created from action groups usually don't have title. + // Maybe it should be an option? + // @ts-expect-error: hasDivider is not yet made a public API. +
{renderActionAsMenuItem}
); diff --git a/packages/jui/src/Menu/renderMenuNodes.tsx b/packages/jui/src/Menu/renderMenuNodes.tsx index 616674d0..cfaa2f4c 100644 --- a/packages/jui/src/Menu/renderMenuNodes.tsx +++ b/packages/jui/src/Menu/renderMenuNodes.tsx @@ -17,12 +17,17 @@ export function renderMenuNodes( return ; case "section": return ( - + <> + {node.props.hasDivider && ( + + )} + + ); case "divider": return ; From ef220a9bda7a6d2ff1e9727f406e6f5597554a88 Mon Sep 17 00:00:00 2001 From: Alireza Date: Sat, 9 Sep 2023 21:48:29 +0200 Subject: [PATCH 03/16] docs: improve live code blocks UI Long code examples are now collapsed by default. --- .../src/theme/CodeBlock/Expandable.tsx | 72 +++++++ .../src/theme/CodeBlock/Playground.tsx | 200 ++++++++++++++++++ .../website/src/theme/CodeBlock/icons.tsx | 21 ++ packages/website/src/theme/CodeBlock/index.js | 8 +- 4 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 packages/website/src/theme/CodeBlock/Expandable.tsx create mode 100644 packages/website/src/theme/CodeBlock/Playground.tsx create mode 100644 packages/website/src/theme/CodeBlock/icons.tsx diff --git a/packages/website/src/theme/CodeBlock/Expandable.tsx b/packages/website/src/theme/CodeBlock/Expandable.tsx new file mode 100644 index 00000000..1b8b2765 --- /dev/null +++ b/packages/website/src/theme/CodeBlock/Expandable.tsx @@ -0,0 +1,72 @@ +import React, { useEffect, useRef, useState } from "react"; +import styled from "styled-components"; + +const StyledSvg = styled.svg` + position: absolute; + width: 24px; + left: 50%; + bottom: 1rem; + transform: translate(-50%, 0) rotate(180deg); +`; + +const StyledExpandButton = styled.div` + position: absolute; + width: 100%; + height: 50%; + bottom: 0; + background: linear-gradient(0deg, rgba(255, 255, 255, 1), transparent); + cursor: pointer; + ${StyledSvg} { + opacity: 0; + transition: opacity 0.3s; + } + &:hover ${StyledSvg} { + opacity: 1; + } +`; +const StyledContainer = styled.div<{ expanded: boolean }>` + position: relative; + max-height: ${({ expanded }) => (expanded ? undefined : "200px")}; +`; + +export function Expandable({ + children, + expanded, + onExpand, + isExpandable, + setIsExpandable, +}: { + children: React.ReactNode; + expanded: boolean; + onExpand: () => void; + isExpandable: boolean; + setIsExpandable: (isExpandable: boolean) => void; +}) { + const ref = useRef(); + useEffect(() => { + const expandable = ref.current?.scrollHeight > ref.current?.offsetHeight; + if (expandable !== isExpandable) { + setIsExpandable(expandable); + } + }); + return ( + + {children} + {!expanded && isExpandable && ( + + + + + + )} + + ); +} diff --git a/packages/website/src/theme/CodeBlock/Playground.tsx b/packages/website/src/theme/CodeBlock/Playground.tsx new file mode 100644 index 00000000..8a6a7104 --- /dev/null +++ b/packages/website/src/theme/CodeBlock/Playground.tsx @@ -0,0 +1,200 @@ +/** + * NOTE: this file is copied from Docusaurus repo, to customize the live code blocks UI, since the exported + * functionality doesn't allow for the needed customizations. + * Original file: https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx + */ + +import React, { useState } from "react"; +import clsx from "clsx"; +import useIsBrowser from "@docusaurus/useIsBrowser"; +import { LiveEditor, LiveError, LivePreview, LiveProvider } from "react-live"; +import Translate from "@docusaurus/Translate"; +import BrowserOnly from "@docusaurus/BrowserOnly"; +import { + ErrorBoundaryTryAgainButton, + usePrismTheme, +} from "@docusaurus/theme-common"; +import ErrorBoundary from "@docusaurus/ErrorBoundary"; + +import type { Props } from "@theme/Playground"; +import type { Props as ErrorProps } from "@theme/Error"; + +import styles from "@docusaurus/theme-live-codeblock/lib/theme/Playground/styles.module.css"; +import { Expandable } from "./Expandable"; +import { + PlatformIcon, + IconButton, + ThemeProvider, + Theme, + ActionTooltip, + TooltipTrigger, +} from "@intellij-platform/core"; +import lightThemeJson from "@intellij-platform/core/themes/intellijlaf.theme.json"; + +function Header({ + children, + icons, +}: { + children: React.ReactNode; + icons?: React.ReactNode; +}) { + return ( +
+ {children} + {icons} +
+ ); +} + +function LivePreviewLoader() { + // Is it worth improving/translating? + return
Loading...
; +} + +function ErrorFallback({ error, tryAgain }: ErrorProps): JSX.Element { + return ( +
+

{error.message}

+ +
+ ); +} + +function Preview() { + // No SSR for the live preview + // See https://github.com/facebook/docusaurus/issues/5747 + return ( + }> + {() => ( + <> + }> + + + + + )} + + ); +} + +function ResultWithHeader() { + return ( + <> +
+ + Result + +
+ {/* https://github.com/facebook/docusaurus/issues/5747 */} +
+ +
+ + ); +} + +function ThemedLiveEditor({ + expanded, + isExpandable, + onExpand, + setIsExpandable, +}: { + expanded: boolean; + isExpandable: boolean; + onExpand: () => void; + setIsExpandable: (expandable: boolean) => void; +}) { + const isBrowser = useIsBrowser(); + return ( + + + + ); +} + +function EditorWithHeader() { + const [expanded, setExpanded] = useState(false); + const [expandable, setExpandable] = useState(false); + return ( + <> +
+ {(expanded || expandable) && ( + + } + > + setExpanded((expanded) => !expanded)} + > + + + + )} + + } + > + + Live Editor + +
+ setExpanded(true)} + isExpandable={expandable} + setIsExpandable={setExpandable} + /> + + ); +} + +export default function Playground({ + children, + transformCode, + ...props +}: Props): JSX.Element { + const prismTheme = usePrismTheme(); + + const noInline = props.metastring?.includes("noInline") ?? false; + + return ( + <> +
+ `${code};`)} + theme={prismTheme} + {...props} + > + + + +
+ + ); +} diff --git a/packages/website/src/theme/CodeBlock/icons.tsx b/packages/website/src/theme/CodeBlock/icons.tsx new file mode 100644 index 00000000..d5387812 --- /dev/null +++ b/packages/website/src/theme/CodeBlock/icons.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const expandIcon = ( + + + + + + + + +); diff --git a/packages/website/src/theme/CodeBlock/index.js b/packages/website/src/theme/CodeBlock/index.js index a63bddff..b936d732 100644 --- a/packages/website/src/theme/CodeBlock/index.js +++ b/packages/website/src/theme/CodeBlock/index.js @@ -7,7 +7,7 @@ import React from "react"; import { useTheme } from "styled-components"; -import Playground from "@theme/Playground"; +import Playground from "./Playground"; import ReactLiveScope from "@theme/ReactLiveScope"; import CodeBlock from "@theme-init/CodeBlock"; import clsx from "clsx"; @@ -32,8 +32,12 @@ const withThemeBackground = (Component) => { function WithThemeBackground(props) { const theme = useTheme(); const content = ; - const style = { "--ifm-list-item-margin": 0 }; + const style = { + "--ifm-list-item-margin": 0, + }; + if (props.themed) { + style.color = theme.color("*.foreground"); style["--ifm-pre-background"] = theme.color("*.background"); } return ( From 4c994650bdd26606c10b8e3dc0bb5494844f6894 Mon Sep 17 00:00:00 2001 From: Alireza Date: Sat, 9 Sep 2023 21:50:08 +0200 Subject: [PATCH 04/16] docs: improve collections guide --- packages/website/docs/guides/Collections.mdx | 21 ++++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/website/docs/guides/Collections.mdx b/packages/website/docs/guides/Collections.mdx index b5a15495..ff474b74 100644 --- a/packages/website/docs/guides/Collections.mdx +++ b/packages/website/docs/guides/Collections.mdx @@ -3,7 +3,7 @@ # Collections -A good number of components like List, Tree, Menu, Tabs, etc. display a collection of items. +A good number of components such as List, Tree, Menu, Tabs, etc. display a collection of items. [@react-stately/collections](https://react-spectrum.adobe.com/react-stately/collections.html) is used for all of them to provide a uniform and flexible API that would allow for both static jsx-based or dynamic source of items. @@ -15,17 +15,14 @@ on the item object. It's important to understand this assumption that the render not any other piece of state from the closure, for example. :::info -Item renderer function is assumed to be a pure function that depends only on its single argument, the item -object. +The item renderer function should be a pure function that relies exclusively on its single argument: the item object. ::: -In some cases however, there might be a need to render some UI based on a something other than the item object itself. -Below is a few ways to do that. +However, in certain scenarios, you might need to render UI elements based on factors other than the item object. Here are a few ways to achieve this: -### Using context +xwxw### Using context -TODO (important point: especially useful for components that implement virtual rendering, as only a limited number of -items are mounted at each moment, and changes to the additional state would only affect those, without collection being rebuilt) +TODO (This is particularly useful for components implementing virtual rendering, where only a limited number of items are mounted at a time, and changes to additional state should affect only those without rebuilding the entire collection). ### Wrapping items with extra state @@ -33,14 +30,12 @@ TODO ### Disabling or limiting cache -Passing `true` to `cacheInvalidation` prop in components that support it will disable caching altogether, but can -drastically reduce the performance for large number of components. In a test on a [Tree](../components/Tree) with 400 elements, -it was ~10x slower with cache being disabled. +For components that support it, you can control caching by setting the `cacheInvalidation` prop. Passing `true` to this prop will disable caching entirely, but it may significantly reduce performance for large collections. In a performance test on a [Tree](../components/Tree) with 400 elements, disabling the cache resulted in a ~10x slower rendering. -A middle ground is to pass an array of cache invalidators instead of turning the cache off completely: +A middle-ground approach is to pass an array of cache invalidators instead of completely turning off the cache: ```tsx ... ``` -This would invalidate the cache only when `nestedSelection` is changed. +This configuration will only invalidate the cache when `nestedSelection` changes. From b09be03a5027a9ecda1603d2658c821e9dc106cd Mon Sep 17 00:00:00 2001 From: Alireza Date: Sat, 9 Sep 2023 21:50:32 +0200 Subject: [PATCH 05/16] docs: add initial documentation for the action system --- .../website/docs/components/ToolWindows.mdx | 4 + packages/website/docs/guides/ActionSystem.mdx | 372 ++++++++++++++++++ packages/website/src/theme/CodeBlock/index.js | 1 + 3 files changed, 377 insertions(+) create mode 100644 packages/website/docs/guides/ActionSystem.mdx diff --git a/packages/website/docs/components/ToolWindows.mdx b/packages/website/docs/components/ToolWindows.mdx index 45e6a09f..8aae6c13 100644 --- a/packages/website/docs/components/ToolWindows.mdx +++ b/packages/website/docs/components/ToolWindows.mdx @@ -317,6 +317,10 @@ toolWindowState({ }); ``` +## Tool window actions + +TODO + ## Advanced API ### Hiding tool window bars diff --git a/packages/website/docs/guides/ActionSystem.mdx b/packages/website/docs/guides/ActionSystem.mdx new file mode 100644 index 00000000..45d27b6e --- /dev/null +++ b/packages/website/docs/guides/ActionSystem.mdx @@ -0,0 +1,372 @@ +--- +--- + +# Actions + +:::warning Experimental +The current implementation of the action system is experimental and is likely to undergo significant revisions to meet +the performance demands of real-world applications with thousands of actions. +::: + +An _action_ represents an available functionality, without specifying how it's invoked. Shortcuts can separately be +assigned to actions via a `keymap`, allowing for a customizable and personalized user experience. The action system, +at its core, is only about defining actions for each part of the UI and associating these actions with +shortcuts, without any direct dependencies on other aspects of the design system. However, there are +[UI components](#ui-components) available to facilitate creation of toolbars and menus based on actions. + +:::note +The core functionality of the action system may be extracted into a standalone package in the future, +making it a reusable component for applications built using any design system. +::: + +The action system consists of the following primary components: + +- `ActionsProvider` component, which allows for defining actions for a UI area. +- `KeymapProvider` component, which allows for assigning shortcut(s) to actions. +- UI components that helps with creating menus, toolbars, etc. based on action system abstractions. + +Below is a basic example of how these components are used. +Subsequent sections will provide detailed explanations of the components and interfaces involved. + +```tsx live noInline noPadding themed +const StyledDiv = styled.div` + &:focus { + outline: 4px solid ${({ theme }) => theme.color("Button.focusedBorderColor")}!important; + outline-offset: 2px; + } +`; +render( + + , + actionPerformed: () => alert("My Action performed"), + }, + ]} + > + {({ shortcutHandlerProps }) => ( +
+ + Click here to focus, then press Shift+D + +
+
+ Or press this button: +
+
+ )} +
+
+); +``` + +## Defining actions + +`ActionsProvider` is used as a wrapper component that defines available actions for the wrapped UI. +Multiple, potentially nested `ActionsProvider` may be rendered in an application. `ActionProvider` itself doesn't render +any wrapper element. Shortcut event handler props are passed to `children` which is expected to be a render function: + +```tsx + + {({ shortcutHandlerProps }) =>
...
} +
+``` + +`actions` is an array of objects implementing `ActionDefinition` interface. At minimum, an action must have: + +- `id`: A unique identifier based on which shortcuts are assigned in `keymap`. +- `actionPerformed`: A function to be invoked when the action is triggered, e.g. via a shortcut. +- `title`: The only mandatory presentation information for the action. + +Moreover, an action has the following optional properties: + +- `isDisabled`: If `true`, prevents action from being performed. [Action UI components](#ui-components) will also utilize + this field to either disable or hide the corresponding UI component. +- `icon`: A React node to be used as the associated icon for the action. It's required if the action is to be rendered + as an [ActionButton](#actionbutton), and optional for [menu items](#menu). +- `description`: Plain text, additional description about the action. Not used in [ActionButton](#actionbutton), or + [menu items](#menu). + +### Action Groups + +An ActionGroup is a special type of action with a list of children actions. An action group itself can be performed. + +### Default action group + +A default implementation of action group is available, which when performed, opens a [Popup](../components/popup), +presenting the children actions in a [SpeedSearchMenu](../components/Menu#speedsearchmenu). The default action +group requires [PopupManager](../components/Popup#popupmanager), for opening the popup. + +`useCreateDefaultActionGroup` returns a function that creates action groups: + +```tsx +import { useCreateDefaultActionGroup } from "@intellij-platform/core"; + +const createDefaultActionGroup = useCreateDefaultActionGroup(); + +createDefaultActionGroup({ + id: "MY_ACTION_GROUP", + title: "My Action Group", + children: [ + /* action definitions */ + ], +}); +``` + +```tsx themed live noInline +function ExampleApp({ children }) { + return ( + + + {children} + + + ); +} +function DefaultActionGroupExample() { + const createDefaultActionGroup = useCreateDefaultActionGroup(); + + return ( + , + children: [ + { + id: "New Changelist...", + title: "New Changelist...", + icon: , + actionPerformed: () => alert("New Changelist..."), + }, + { + id: "Edit Changelist...", + title: "Edit Changelist...", + icon: , + actionPerformed: () => alert("Edit Changelist..."), + }, + { + id: "Move to another changelist...", + title: "Move to another changelist...", + actionPerformed: () => alert("Edit Changelist..."), + }, + ], + }), + ]} + > + {({ shortcutHandlerProps }) => ( +
+ +
+ )} +
+ ); +} + +render( + + + +); +``` + +## Using actions + +`useActions` can be used to query the list of all provided actions. Use `useAction` instead to query an specific action, +by id. The queried `Action` object has a `perform` method which can be invoked e.g. when a menu item or a button is +pressed. Note that `Action` interface is quite similar but not identical to `ActionDefinition`. + +```tsx +function MyActionButton() { + const action = useAction("MY_ACTION"); + return action && ; +} +``` + +`useActionGroup` is also similar to `useAction`, but it asserts the queried action is a group. + +### Query actions based on DOM elements + +`useAction` or `useActions` is the canonical API for accessing currently provided actions from a React component. +`getAvailableActionsFor` is an alternative API that allows for querying available actions from a DOM element. This can +be useful in specific scenarios such as the implementation of the [find action][find-action-in-the-reference-impl]. +You can also check out the implementation of "find action" action [in the example app][find-action-in-example-app]. + +### UI components + +`useAction`, and `useActionGroup` can be used to query actions and create a menu or toolbar out of them. For typical +use cases, however, there are convenient components that interface on `Action` or action id. + +### Menu + +Use `ActionsMenu` to render a list of action objects as a menu. `ActionGroup` items are rendered as a section or a +submenu, depending on `isPopup` property of the action group object. +Note that `ActionsMenu` just provides an interface based on action items, but it doesn't query any action from the +actions context, and just uses action properties to create menu items from it. + +```tsx themed live +, + shortcut: "⌘X", + perform: () => alert("Cut"), + }, + { + id: "Copy", + title: "Copy", + icon: , + shortcut: "⌘C", + perform: () => alert("Copy"), + }, + { + id: "Copy Path/Reference...", + title: "Copy Path/Reference...", + perform: () => alert("Copy Path/Reference..."), + }, + { + id: "Paste", + title: "Paste", + icon: , + shortcut: "⌘V", + perform: () => alert("Paste"), + }, + new DividerItem(), + { + id: "Compare with...", + title: "Diff", + icon: , + shortcut: "⌘D", + perform: () => alert("Diff"), + }, + ]} +/> +``` + +Use `ActionGroupMenu` to render actions of an action group, as a menu: + +```tsx themed live +, + shortcut: "⌘X", + perform: () => alert("Cut"), + }, + { + id: "Copy", + title: "Copy", + icon: , + shortcut: "⌘C", + perform: () => alert("Copy"), + }, + { + id: "Copy Path/Reference...", + title: "Copy Path/Reference...", + perform: () => alert("Copy Path/Reference..."), + }, + { + id: "Paste", + title: "Paste", + icon: , + shortcut: "⌘V", + perform: () => alert("Paste"), + }, + { + id: "DIFF_ACTION_GROUP", + title: "Diff actions", + children: [ + { + id: "Compare with...", + title: "Diff", + icon: , + shortcut: "⌘D", + perform: () => alert("Diff"), + }, + ], + }, + ], + }} +/> +``` + +### ActionButton + +Use `ActionButton` to create an `IconButton` based on a provided action. Unlike `ActionsMenu` and `ActionGroupMenu`, +`ActionButton` interfaces on action ID, and queries the target action via `useAction`. If the action doesn't exist, +it renders nothing. + +```jsx live themed noPadding +, + actionPerformed: () => alert("Refresh"), + }, + ]} +> + {({ shortcutHandlerProps }) => ( +
+ +
+ )} +
+``` + +## Shortcuts and key mapping + +A `Keymap` is a mapping from action ids to a list of associated shortcuts. In an application that uses actions, the +`KeymapProvider` is typically used as a top level wrapper, to provide a keymap. + +```tsx +import {Keymap, KeymapProvider} from '@intellij-platform/core'; + +const keymap: Keymap = isMac() ? macKeymap : defaultKeymap; +... +``` + +## Differences with the Intellij Platform + +While the action system almost replicates [Intellij Platform's Action System][action-system], there are some design +differences worth noting: + +TODO + +[action-system]: https://plugins.jetbrains.com/docs/intellij/basic-action-system.html +[find-action-in-the-reference-impl]: https://www.jetbrains.com/idea/guide/tutorials/presenting/find-action +[find-action-in-example-app]: https://github.com/alirezamirian/jui/blob/master/packages/example-app/src/SearchEverywhere/contributors/action/actionsSearchContributor.tsx diff --git a/packages/website/src/theme/CodeBlock/index.js b/packages/website/src/theme/CodeBlock/index.js index b936d732..85dc0164 100644 --- a/packages/website/src/theme/CodeBlock/index.js +++ b/packages/website/src/theme/CodeBlock/index.js @@ -39,6 +39,7 @@ const withThemeBackground = (Component) => { if (props.themed) { style.color = theme.color("*.foreground"); style["--ifm-pre-background"] = theme.color("*.background"); + style["--ifm-code-background"] = "none"; } return (
Date: Sun, 10 Sep 2023 21:30:42 +0200 Subject: [PATCH 06/16] fix(actions): fix a regression in the default action group --- .../useCreateDefaultActionGroup.tsx | 72 ++++++++++--------- packages/jui/src/Popup/PopupManager.tsx | 1 - 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx index ef9bea8e..9dc7b2dc 100644 --- a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx +++ b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx @@ -22,42 +22,44 @@ export const useCreateDefaultActionGroup = () => { context: ActionContext ) => { show(({ close }) => ( - { - // The need for calculating `allActions` is a consequence of the issue explained in the note above. - const allActions = flatten( - children.map((item) => - isActionGroupDefinition(item) ? item.children : item - ) - ); - const action = allActions.find((action) => action.id === key); - if (action && !action.isDisabled) { - action.actionPerformed(context); + + { + // The need for calculating `allActions` is a consequence of the issue explained in the note above. + const allActions = flatten( + children.map((item) => + isActionGroupDefinition(item) ? item.children : item + ) + ); + const action = allActions.find((action) => action.id === key); + if (action && !action.isDisabled) { + action.actionPerformed(context); + } + }} + onClose={close} + autoFocus="first" + > + {(item) => + renderActionAsMenuItem({ + ...item, + // a consequence of the issue explained in the note above. + shortcut: getActionShortcut(item.id), + }) } - }} - onClose={close} - autoFocus="first" - > - {(item) => - renderActionAsMenuItem({ - ...item, - // a consequence of the issue explained in the note above. - shortcut: getActionShortcut(item.id), - }) - } - - } - header={title} - /> + + } + header={title} + /> + )); } ); diff --git a/packages/jui/src/Popup/PopupManager.tsx b/packages/jui/src/Popup/PopupManager.tsx index e53b0c5e..6dd997ff 100644 --- a/packages/jui/src/Popup/PopupManager.tsx +++ b/packages/jui/src/Popup/PopupManager.tsx @@ -7,7 +7,6 @@ import React, { useState, } from "react"; import { Popup, PopupProps } from "./Popup"; -import { props } from "ramda"; import { PopupControllerContext } from "@intellij-platform/core/Popup/PopupContext"; interface PopupManagerAPI { From 4f4ae1a04347a982717dbe58c92f83b1bee9ab2b Mon Sep 17 00:00:00 2001 From: Alireza Date: Mon, 11 Sep 2023 22:07:28 +0200 Subject: [PATCH 07/16] chore: fix a build error Many imports are changed, but the root cause turned out to be ActionSystem/components/ActionsMenu.tsx importing DividerItem from "@intellij-platform/core/Collections". Not clear why, and the error was found by trial and error and binary-searching, but importing it from the direct file solved the issue for now. --- packages/jui/src/ActionSystem/Action.ts | 72 +++++++++++++++ packages/jui/src/ActionSystem/ActionGroup.tsx | 2 +- .../jui/src/ActionSystem/ActionsProvider.tsx | 90 +++---------------- .../jui/src/ActionSystem/KeymapProvider.tsx | 4 +- .../ActionSystem/components/ActionButton.tsx | 2 +- .../components/ActionGroupMenu.tsx | 4 +- .../ActionSystem/components/ActionsMenu.tsx | 11 +-- .../jui/src/ActionSystem/components/index.ts | 4 + .../useCreateDefaultActionGroup.tsx | 8 +- .../jui/src/ActionSystem/defaultKeymap.tsx | 5 +- packages/jui/src/ActionSystem/index.ts | 6 +- .../jui/src/ActionSystem/useActionGroup.tsx | 5 +- packages/jui/src/Balloon/index.ts | 2 +- packages/jui/src/Collections/Divider.ts | 25 +++--- packages/jui/src/Menu/Menu.stories.tsx | 2 +- .../stories/components/FakeExecution.tsx | 2 +- .../DefaultToolWindowHeader.tsx | 2 +- .../ToolWindowSettingsIconMenu.tsx | 5 +- .../ToolWindowsImpl/useToolWindowActions.tsx | 2 +- packages/jui/src/index.ts | 5 +- 20 files changed, 134 insertions(+), 124 deletions(-) create mode 100644 packages/jui/src/ActionSystem/Action.ts diff --git a/packages/jui/src/ActionSystem/Action.ts b/packages/jui/src/ActionSystem/Action.ts new file mode 100644 index 00000000..e22fc737 --- /dev/null +++ b/packages/jui/src/ActionSystem/Action.ts @@ -0,0 +1,72 @@ +import React from "react"; +import { Shortcut } from "@intellij-platform/core/ActionSystem/Shortcut"; + +export interface ActionContext { + element: Element | null; + /** + * UI event that triggered the action, if a shortcut triggered the action. + */ + event: + | React.MouseEvent + | React.KeyboardEvent + | null; +} + +/** + * Represents the definition of an action. + * @interface + */ +export interface ActionDefinition { + /** + * The unique identifier for the action. Used to assign shortcuts to the action, via a {@link Keymap}. + */ + id: string; + /** + * The title of an action. + * This value will be used as the text in UI display for the action. + */ + title: string; + /** + * The function that will be executed when the action is performed. + * @param context It provides further information about the action event. + */ + actionPerformed: (context: ActionContext) => void; + /** + * An optional icon for an action. + * If provided, it will be displayed along with the title in the UI. + */ + icon?: React.ReactNode; + /** + * An optional description for an action. + * If provided, it can be displayed as additional information about the action in the UI. + */ + description?: string; + /** + * An optional disable state for an action. + * If set to `true`, this action would be in disabled state and cannot be performed. + */ + isDisabled?: boolean; +} + +export interface MutableAction + extends Pick< + ActionDefinition, + "title" | "icon" | "description" | "isDisabled" + > { + id: string; + /** + * shortcuts assigned to this action based on the keymap context + */ + shortcuts: readonly Shortcut[] | undefined; + /** + * string representation of the shortcuts + */ + shortcut: string | undefined; + + /** + * Performs the action, if it's enabled. + */ + perform: (context?: ActionContext) => void; +} + +export type Action = Readonly; diff --git a/packages/jui/src/ActionSystem/ActionGroup.tsx b/packages/jui/src/ActionSystem/ActionGroup.tsx index 72c6e34c..f6cc757c 100644 --- a/packages/jui/src/ActionSystem/ActionGroup.tsx +++ b/packages/jui/src/ActionSystem/ActionGroup.tsx @@ -1,7 +1,7 @@ import { Action, ActionDefinition, -} from "@intellij-platform/core/ActionSystem/ActionsProvider"; +} from "@intellij-platform/core/ActionSystem/Action"; export type ActionInResolvedGroup = Action & { parent: ResolvedActionGroup }; diff --git a/packages/jui/src/ActionSystem/ActionsProvider.tsx b/packages/jui/src/ActionSystem/ActionsProvider.tsx index ffb2b7bb..4af23e7e 100644 --- a/packages/jui/src/ActionSystem/ActionsProvider.tsx +++ b/packages/jui/src/ActionSystem/ActionsProvider.tsx @@ -1,12 +1,11 @@ -import { - Keymap, - useKeymap, -} from "@intellij-platform/core/ActionSystem/KeymapProvider"; import { pick, sortBy } from "ramda"; import React, { HTMLAttributes, useContext, useEffect, useState } from "react"; -import { shortcutToString } from "@intellij-platform/core/ActionSystem/shortcutToString"; -import { useShortcuts } from "@intellij-platform/core/ActionSystem/useShortcut"; -import { Shortcut } from "@intellij-platform/core/ActionSystem/Shortcut"; +import { useEventCallback } from "@intellij-platform/core/utils/useEventCallback"; +import { dfsVisit } from "@intellij-platform/core/utils/tree-utils"; + +import { Keymap, useKeymap } from "./KeymapProvider"; +import { shortcutToString } from "./shortcutToString"; +import { useShortcuts } from "./useShortcut"; import { ActionGroup, ActionInResolvedGroup, @@ -14,77 +13,12 @@ import { isActionGroupDefinition, MutableActionGroup, } from "./ActionGroup"; -import { useEventCallback } from "@intellij-platform/core/utils/useEventCallback"; -import { dfsVisit } from "@intellij-platform/core/utils/tree-utils"; - -export interface ActionContext { - element: Element | null; - /** - * UI event that triggered the action, if a shortcut triggered the action. - */ - event: - | React.MouseEvent - | React.KeyboardEvent - | null; -} - -/** - * Represents the definition of an action. - * @interface - */ -export interface ActionDefinition { - /** - * The unique identifier for the action. Used to assign shortcuts to the action, via a {@link Keymap}. - */ - id: string; - /** - * The title of an action. - * This value will be used as the text in UI display for the action. - */ - title: string; - /** - * The function that will be executed when the action is performed. - * @param context It provides further information about the action event. - */ - actionPerformed: (context: ActionContext) => void; - /** - * An optional icon for an action. - * If provided, it will be displayed along with the title in the UI. - */ - icon?: React.ReactNode; - /** - * An optional description for an action. - * If provided, it can be displayed as additional information about the action in the UI. - */ - description?: string; - /** - * An optional disable state for an action. - * If set to `true`, this action would be in disabled state and cannot be performed. - */ - isDisabled?: boolean; -} - -export interface MutableAction - extends Pick< - ActionDefinition, - "title" | "icon" | "description" | "isDisabled" - > { - id: string; - /** - * shortcuts assigned to this action based on the keymap context - */ - shortcuts: readonly Shortcut[] | undefined; - /** - * string representation of the shortcuts - */ - shortcut: string | undefined; - - /** - * Performs the action, if it's enabled. - */ - perform: (context?: ActionContext) => void; -} -export type Action = Readonly; +import { + Action, + ActionContext, + ActionDefinition, + MutableAction, +} from "@intellij-platform/core/ActionSystem/Action"; /** * Represents the properties required for the ActionsProvider component. diff --git a/packages/jui/src/ActionSystem/KeymapProvider.tsx b/packages/jui/src/ActionSystem/KeymapProvider.tsx index 586c383b..42030dc8 100644 --- a/packages/jui/src/ActionSystem/KeymapProvider.tsx +++ b/packages/jui/src/ActionSystem/KeymapProvider.tsx @@ -1,6 +1,6 @@ import React, { useContext } from "react"; -import { Shortcut } from "@intellij-platform/core/ActionSystem/Shortcut"; -import { defaultKeymap } from "@intellij-platform/core/ActionSystem/defaultKeymap"; +import { Shortcut } from "./Shortcut"; +import { defaultKeymap } from "./defaultKeymap"; export interface Keymap { [actionId: string]: ReadonlyArray; diff --git a/packages/jui/src/ActionSystem/components/ActionButton.tsx b/packages/jui/src/ActionSystem/components/ActionButton.tsx index d23361fd..2030548a 100644 --- a/packages/jui/src/ActionSystem/components/ActionButton.tsx +++ b/packages/jui/src/ActionSystem/components/ActionButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useAction } from "@intellij-platform/core/ActionSystem"; +import { useAction } from "@intellij-platform/core/ActionSystem/ActionsProvider"; import { IconButton } from "@intellij-platform/core/IconButton"; import { ActionTooltip, TooltipTrigger } from "@intellij-platform/core/Tooltip"; diff --git a/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx b/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx index 21d2957a..1eb71310 100644 --- a/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx +++ b/packages/jui/src/ActionSystem/components/ActionGroupMenu.tsx @@ -1,6 +1,6 @@ -import { ActionGroup } from "@intellij-platform/core/ActionSystem"; import React from "react"; -import { ActionMenuProps, ActionsMenu } from "./ActionsMenu"; +import { type ActionGroup } from "@intellij-platform/core/ActionSystem/ActionGroup"; +import { type ActionMenuProps, ActionsMenu } from "./ActionsMenu"; export type ActionGroupMenuProps = Omit & { actionGroup: ActionGroup; diff --git a/packages/jui/src/ActionSystem/components/ActionsMenu.tsx b/packages/jui/src/ActionSystem/components/ActionsMenu.tsx index 37c6ea20..f28bf973 100644 --- a/packages/jui/src/ActionSystem/components/ActionsMenu.tsx +++ b/packages/jui/src/ActionSystem/components/ActionsMenu.tsx @@ -1,13 +1,10 @@ import React from "react"; import { flatten } from "ramda"; import { Menu, MenuItemLayout } from "@intellij-platform/core/Menu"; -import { - Divider, - DividerItem, - Item, -} from "@intellij-platform/core/Collections"; -import { Action, ActionGroup } from "@intellij-platform/core/ActionSystem"; -import { Section } from "@react-stately/collections"; +import { Divider, Item, Section } from "@intellij-platform/core/Collections"; +import { DividerItem } from "@intellij-platform/core/Collections/Divider"; // Importing from /Collections breaks the build for some reason +import { type ActionGroup } from "@intellij-platform/core/ActionSystem/ActionGroup"; +import { type Action } from "@intellij-platform/core/ActionSystem/Action"; type ActionGroupAsMenuItem = Pick< ActionGroup, diff --git a/packages/jui/src/ActionSystem/components/index.ts b/packages/jui/src/ActionSystem/components/index.ts index 6d51729a..6291bfde 100644 --- a/packages/jui/src/ActionSystem/components/index.ts +++ b/packages/jui/src/ActionSystem/components/index.ts @@ -1,3 +1,7 @@ +/** + * Action system components. Intentionally re-exported only from the root index file, and not the index.ts in + * ActionSystem. + */ export { ActionButton } from "./ActionButton"; export { ActionsMenu, diff --git a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx index 9dc7b2dc..4d327491 100644 --- a/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx +++ b/packages/jui/src/ActionSystem/components/useCreateDefaultActionGroup.tsx @@ -1,17 +1,15 @@ import { flatten } from "ramda"; import React from "react"; import { - ActionGroupDefinition, + type ActionGroupDefinition, isActionGroupDefinition, } from "@intellij-platform/core/ActionSystem/ActionGroup"; +import { useGetActionShortcut } from "@intellij-platform/core/ActionSystem/ActionShortcut"; import { Popup, usePopupManager } from "@intellij-platform/core/Popup"; -import { - ActionContext, - useGetActionShortcut, -} from "@intellij-platform/core/ActionSystem"; import { SpeedSearchMenu } from "@intellij-platform/core/Menu"; import { useEventCallback } from "@intellij-platform/core/utils/useEventCallback"; import { renderActionAsMenuItem } from "./ActionsMenu"; +import { ActionContext } from "@intellij-platform/core/ActionSystem/Action"; export const useCreateDefaultActionGroup = () => { const { show } = usePopupManager(); diff --git a/packages/jui/src/ActionSystem/defaultKeymap.tsx b/packages/jui/src/ActionSystem/defaultKeymap.tsx index 49bb640a..41023d11 100644 --- a/packages/jui/src/ActionSystem/defaultKeymap.tsx +++ b/packages/jui/src/ActionSystem/defaultKeymap.tsx @@ -1,4 +1,3 @@ -import { Keymap } from "@intellij-platform/core/ActionSystem/KeymapProvider"; import { FOCUS_EDITOR_ACTION_ID, HIDE_ACTIVE_WINDOW_ACTION_ID, @@ -12,7 +11,9 @@ import { // For some reason importing from shorter paths doesn't work as expected in cypress ¯\_(ツ)_/¯ // Weirdly, `import *` works in that case. } from "@intellij-platform/core/ToolWindowsImpl/ToolWindowActionIds"; -import { CommonActionId } from "@intellij-platform/core/ActionSystem/CommonActionIds"; + +import { Keymap } from "./KeymapProvider"; +import { CommonActionId } from "./CommonActionIds"; // TODO: OS specific defaults // TODO: extract and export action ids diff --git a/packages/jui/src/ActionSystem/index.ts b/packages/jui/src/ActionSystem/index.ts index da03b136..07efa74c 100644 --- a/packages/jui/src/ActionSystem/index.ts +++ b/packages/jui/src/ActionSystem/index.ts @@ -6,5 +6,7 @@ export * from "./ActionShortcut"; export * from "./CommonActionIds"; export * from "./shortcutToString"; export * from "./ActionGroup"; - -export * from "./components"; +export { Action } from "@intellij-platform/core/ActionSystem/Action"; +export { MutableAction } from "@intellij-platform/core/ActionSystem/Action"; +export { ActionDefinition } from "@intellij-platform/core/ActionSystem/Action"; +export { ActionContext } from "@intellij-platform/core/ActionSystem/Action"; diff --git a/packages/jui/src/ActionSystem/useActionGroup.tsx b/packages/jui/src/ActionSystem/useActionGroup.tsx index 0a0e359e..0a4ff64d 100644 --- a/packages/jui/src/ActionSystem/useActionGroup.tsx +++ b/packages/jui/src/ActionSystem/useActionGroup.tsx @@ -1,8 +1,5 @@ import { useAction } from "./ActionsProvider"; -import { - isResolvedActionGroup, - ResolvedActionGroup, -} from "@intellij-platform/core/ActionSystem/ActionGroup"; +import { isResolvedActionGroup, ResolvedActionGroup } from "./ActionGroup"; export const useActionGroup = ( actionGroupId: string diff --git a/packages/jui/src/Balloon/index.ts b/packages/jui/src/Balloon/index.ts index 89768b64..7ce96ddd 100644 --- a/packages/jui/src/Balloon/index.ts +++ b/packages/jui/src/Balloon/index.ts @@ -1,3 +1,3 @@ export * from "./Balloon"; export * from "./BalloonManager"; -export { StyledBalloonsStack } from "@intellij-platform/core/Balloon/StyledBalloonsStack"; +export { StyledBalloonsStack } from "./StyledBalloonsStack"; diff --git a/packages/jui/src/Collections/Divider.ts b/packages/jui/src/Collections/Divider.ts index 7a8a604f..b656f223 100644 --- a/packages/jui/src/Collections/Divider.ts +++ b/packages/jui/src/Collections/Divider.ts @@ -15,6 +15,19 @@ import { ItemProps } from "@react-types/shared"; import { PartialNode } from "@react-stately/collections"; interface DividerProps {} + +/** + * To be used in dynamic collections, just to provide a key and make it easy to check in the render + * function to figure out what to render (an Item or a Divider) + */ +export class DividerItem { + private static seq = 0; + key = "divider_" + DividerItem.seq++; + get id() { + return this.key; + } +} + function Divider({}: DividerProps): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars return null as any; @@ -36,15 +49,3 @@ Divider.getCollectionNode = function* getCollectionNode( hasChildNodes: false, }; }; - -/** - * To be used in dynamic collections, just to provide a key and make it easy to check in the render - * function to figure out what to render (an Item or a Divider) - */ -export class DividerItem { - private static seq = 0; - key = "divider_" + DividerItem.seq++; - get id() { - return this.key; - } -} diff --git a/packages/jui/src/Menu/Menu.stories.tsx b/packages/jui/src/Menu/Menu.stories.tsx index 3d2cda19..89900912 100644 --- a/packages/jui/src/Menu/Menu.stories.tsx +++ b/packages/jui/src/Menu/Menu.stories.tsx @@ -4,7 +4,7 @@ import { Item } from "@react-stately/collections"; import { ContextMenuContainer, styled } from "@intellij-platform/core"; import { IconButton } from "../IconButton"; -import { Toolbar } from "@intellij-platform/core/Toolbar/Toolbar"; +import { Toolbar } from "../Toolbar/Toolbar"; import { Divider, DividerItem } from "../Collections/Divider"; import { PlatformIcon } from "../Icon"; import { styledComponentsControlsExclude } from "../story-helpers"; diff --git a/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx b/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx index ae994aee..8e2d3197 100644 --- a/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx +++ b/packages/jui/src/ToolWindows/stories/components/FakeExecution.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { Toolbar } from "@intellij-platform/core/Toolbar/Toolbar"; +import { Toolbar } from "../../../Toolbar/Toolbar"; import { IconButton } from "../../../IconButton"; import { PlatformIcon } from "../../../Icon"; import { StyledHorizontalSeparator } from "../../../StyledSeparator"; diff --git a/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx b/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx index 0b20ab23..9e2de406 100644 --- a/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx +++ b/packages/jui/src/ToolWindowsImpl/DefaultToolWindowHeader.tsx @@ -12,7 +12,7 @@ import { DOCK_TOOL_WINDOW_ACTION_ID, HIDE_ACTIVE_WINDOW_ACTION_ID, } from "./ToolWindowActionIds"; -import { ActionButton } from "@intellij-platform/core/ActionSystem"; +import { ActionButton } from "@intellij-platform/core/ActionSystem/components"; export interface ToolWindowHeaderProps extends Omit, "ref" | "as"> { diff --git a/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx b/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx index c4594d0f..15786ce7 100644 --- a/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx +++ b/packages/jui/src/ToolWindowsImpl/ToolWindowSettingsIconMenu.tsx @@ -5,7 +5,10 @@ import { useAction, useActionGroup, } from "@intellij-platform/core/ActionSystem"; -import { ActionItem, ActionsMenu } from "@intellij-platform/core/ActionSystem"; +import { + ActionItem, + ActionsMenu, +} from "@intellij-platform/core/ActionSystem/components"; import { MOVE_TO_ACTION_GROUP_ID, TOOL_WINDOW_RESIZE_ACTION_GROUP_ID, diff --git a/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx b/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx index cf8fff6e..62cd0fd9 100644 --- a/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx +++ b/packages/jui/src/ToolWindowsImpl/useToolWindowActions.tsx @@ -24,7 +24,7 @@ import { WINDOW_MODE_ACTION_ID, } from "./ToolWindowActionIds"; import { ActionGroupDefinition } from "@intellij-platform/core/ActionSystem"; -import { useCreateDefaultActionGroup } from "@intellij-platform/core/ActionSystem"; +import { useCreateDefaultActionGroup } from "@intellij-platform/core/ActionSystem/components"; // Resize steps in Intellij Platform is calculated based on the size of a "W" character and some // configuration (ide.windowSystem.hScrollChars). Although it's technically feasible, it seems not necessary diff --git a/packages/jui/src/index.ts b/packages/jui/src/index.ts index 9a182f34..45cb2f07 100644 --- a/packages/jui/src/index.ts +++ b/packages/jui/src/index.ts @@ -7,9 +7,10 @@ export * from "./Menu"; export * from "./ToolWindows"; export * from "./ToolWindowsImpl"; export * from "./ActionSystem"; +export * from "./ActionSystem/components"; export * from "./IconButton"; -export * from "@intellij-platform/core/Toolbar/Toolbar"; -export * from "@intellij-platform/core/IconButtonWithMenu/IconButtonWithMenu"; +export * from "./Toolbar/Toolbar"; +export * from "./IconButtonWithMenu/IconButtonWithMenu"; export * from "./Icon"; export * from "./TextWithHighlights/TextWithHighlights"; export * from "./SpeedSearch"; From 23879b44591738e45d99a9d35be136d98550e41d Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 12 Sep 2023 22:35:34 +0200 Subject: [PATCH 08/16] upgrade cypress to v13 to fix the new weird issue on the CI pipeline: libva error: va_getDriverName() failed with unknown libva error,driver_name=(null) https://github.com/cypress-io/cypress/issues/27741 --- packages/jui/package.json | 6 +- yarn.lock | 327 +++++++++++++++++++++++--------------- 2 files changed, 203 insertions(+), 130 deletions(-) diff --git a/packages/jui/package.json b/packages/jui/package.json index 7e730f7d..052001cc 100644 --- a/packages/jui/package.json +++ b/packages/jui/package.json @@ -81,7 +81,7 @@ "@babel/core": "^7.13.15", "@babel/plugin-proposal-decorators": "^7.17.12", "@babel/preset-typescript": "7.13.0", - "@percy/cli": "^1.16.0", + "@percy/cli": "^1.27.1", "@percy/cypress": "^3.1.2", "@react-stately/data": "^3.4.2", "@react-types/button": "^3.4.1", @@ -103,9 +103,9 @@ "buffer": "^6.0.3", "circular-dependency-plugin": "^5.2.2", "crypto-browserify": "^3.12.0", - "cypress": "^12.1.0", + "cypress": "^13.2.0", "cypress-plugin-snapshots": "1.4.4", - "cypress-real-events": "^1.7.4", + "cypress-real-events": "^1.10.3", "hygen": "^6.2.11", "jest": "^29.0.3", "path-browserify": "^1.0.1", diff --git a/yarn.lock b/yarn.lock index 11049ccb..e17d1309 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3051,9 +3051,9 @@ __metadata: languageName: node linkType: hard -"@cypress/request@npm:^2.88.10": - version: 2.88.10 - resolution: "@cypress/request@npm:2.88.10" +"@cypress/request@npm:^3.0.0": + version: 3.0.1 + resolution: "@cypress/request@npm:3.0.1" dependencies: aws-sign2: ~0.7.0 aws4: ^1.8.0 @@ -3068,12 +3068,12 @@ __metadata: json-stringify-safe: ~5.0.1 mime-types: ~2.1.19 performance-now: ^2.1.0 - qs: ~6.5.2 + qs: 6.10.4 safe-buffer: ^5.1.2 - tough-cookie: ~2.5.0 + tough-cookie: ^4.1.3 tunnel-agent: ^0.6.0 uuid: ^8.3.2 - checksum: 69c3e3b332e9be4866a900f6bcca5d274d8cea6c99707fbcce061de8dbab11c9b1e39f4c017f6e83e6e682717781d4f6106fd6b7cf9546580fcfac353b6676cf + checksum: 7175522ebdbe30e3c37973e204c437c23ce659e58d5939466615bddcd58d778f3a8ea40f087b965ae8b8138ea8d102b729c6eb18c6324f121f3778f4a2e8e727 languageName: node linkType: hard @@ -4064,7 +4064,7 @@ __metadata: "@babel/core": ^7.13.15 "@babel/plugin-proposal-decorators": ^7.17.12 "@babel/preset-typescript": 7.13.0 - "@percy/cli": ^1.16.0 + "@percy/cli": ^1.27.1 "@percy/cypress": ^3.1.2 "@react-aria/button": ^3.4.1 "@react-aria/checkbox": ^3.3.1 @@ -4120,9 +4120,9 @@ __metadata: buffer: ^6.0.3 circular-dependency-plugin: ^5.2.2 crypto-browserify: ^3.12.0 - cypress: ^12.1.0 + cypress: ^13.2.0 cypress-plugin-snapshots: 1.4.4 - cypress-real-events: ^1.7.4 + cypress-real-events: ^1.10.3 hygen: ^6.2.11 jest: ^29.0.3 path-browserify: ^1.0.1 @@ -6335,128 +6335,129 @@ __metadata: languageName: node linkType: hard -"@percy/cli-app@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-app@npm:1.16.0" +"@percy/cli-app@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-app@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 - "@percy/cli-exec": 1.16.0 - checksum: 90566bf5ecc7ab113f068ec3c097d76d943f24933b52f06f4e47716eb897cbf04b0330594c6387cb1699896e2f473c8d3dd54576a26e1cdd2d7c8caf9cb676fb + "@percy/cli-command": 1.27.1 + "@percy/cli-exec": 1.27.1 + checksum: e18f83f37615f36441eca1a2b1367a1cb4c4ac5feeaa94334e41f5aae8c7d27ee308fe229f6dfac6f078a88083a011e917525f68af66f5d295df179f3bef8a5d languageName: node linkType: hard -"@percy/cli-build@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-build@npm:1.16.0" +"@percy/cli-build@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-build@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 - checksum: 6ef171552ff61a687d91f4f7a2a190168e8ecb167ea5e7f1488510f0d9b570bb692b59bd7184664cd3155a409bc7cff655d2a124b166eef88c0469d12184b9bc + "@percy/cli-command": 1.27.1 + checksum: 9c38fd9a581d84f1e1819837c7fa71c6fc8ae44b360095d88ef95837154b13a9385482aedac67d87a7e9c5837de057c845352286a7e3bdb49d6220d53b7f8d39 languageName: node linkType: hard -"@percy/cli-command@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-command@npm:1.16.0" +"@percy/cli-command@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-command@npm:1.27.1" dependencies: - "@percy/config": 1.16.0 - "@percy/core": 1.16.0 - "@percy/logger": 1.16.0 + "@percy/config": 1.27.1 + "@percy/core": 1.27.1 + "@percy/logger": 1.27.1 bin: percy-cli-readme: bin/readme.js - checksum: 06833a9b31578e1985f284b072d0b98964b940c46d83ffa6a9bec4feec753521422b562e9c5f6fe941185567bb6fb3718a4559aa34eca6eeed931e083ad778bd + checksum: 5cc7b07562b5ea4c1bcfd853ed7ad88c41d787cdc99b9ac26fcb4cfad6f02b938c0ba67726daa478c6f7e37fe27e11605e4363cc8c5bc6740da1ba0dd7ae35e2 languageName: node linkType: hard -"@percy/cli-config@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-config@npm:1.16.0" +"@percy/cli-config@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-config@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 - checksum: 187144b81d21af8724f9cfb33995b6ad9736d4fd50987c9223e616766efd44db31cb18e618e387d085e8281e893e5979c200dd0965b2bcd67b78eed26743213f + "@percy/cli-command": 1.27.1 + checksum: cd5e269ab05c66abc10f8531a3a4f48af4bf3f7a6138a1734908f44075ad1f67e083c0b31c4398c85bb4afb7e67775441b2ccfc27ead7c4d8657e3c45013f27e languageName: node linkType: hard -"@percy/cli-exec@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-exec@npm:1.16.0" +"@percy/cli-exec@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-exec@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 + "@percy/cli-command": 1.27.1 cross-spawn: ^7.0.3 which: ^2.0.2 - checksum: 78b64f36683db44859a0a82bd49984adeb5fd7aaa5105bed4574cc4f7a3a6fcc88bb05c823e1736bf505cd73c04771c7908dcc938f42cfc23bde9ffec4d54172 + checksum: cfc682142e7553d0b8084f500734a016001bf2c0b5a7e6cfb2033559dcbb9b3255bc97725ffd2c7de4a9d03c926d3dce7667f3a606e1161619afc2c3640a765a languageName: node linkType: hard -"@percy/cli-snapshot@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-snapshot@npm:1.16.0" +"@percy/cli-snapshot@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-snapshot@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 + "@percy/cli-command": 1.27.1 yaml: ^2.0.0 - checksum: 87461a6036d4e15299bea7cb6c4b64564eace7385eae48e708ed75322ed3fdd2b179a42437e675a025ee0191c943655b718a81d48a3fe5789f71fba0c88f183b + checksum: 7b20b514fe0096857ecc1f0158810090b57fac2131a69251699e6de41fd1a1bb6af00ad8a3759f4379cf86312bb033aa438e2879fcf057e59371a141548c3dbd languageName: node linkType: hard -"@percy/cli-upload@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/cli-upload@npm:1.16.0" +"@percy/cli-upload@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/cli-upload@npm:1.27.1" dependencies: - "@percy/cli-command": 1.16.0 + "@percy/cli-command": 1.27.1 fast-glob: ^3.2.11 image-size: ^1.0.0 - checksum: 8bab3fea7583abdc42403034e86e2d52821099749df0452751f24857ededf801ff7a69adf752a807e0d913e51d7503ad05608da7056cf77f2038a4f97bfb4232 + checksum: 18d34c3574e6c71aa91dd131a67067c8795b777f40c1d2ca07c44a012da58a2992bc4b30d300d0bd1f4bb78794677f7733bc448002471143e32be2be70382b0c languageName: node linkType: hard -"@percy/cli@npm:^1.16.0": - version: 1.16.0 - resolution: "@percy/cli@npm:1.16.0" +"@percy/cli@npm:^1.27.1": + version: 1.27.1 + resolution: "@percy/cli@npm:1.27.1" dependencies: - "@percy/cli-app": 1.16.0 - "@percy/cli-build": 1.16.0 - "@percy/cli-command": 1.16.0 - "@percy/cli-config": 1.16.0 - "@percy/cli-exec": 1.16.0 - "@percy/cli-snapshot": 1.16.0 - "@percy/cli-upload": 1.16.0 - "@percy/client": 1.16.0 - "@percy/logger": 1.16.0 + "@percy/cli-app": 1.27.1 + "@percy/cli-build": 1.27.1 + "@percy/cli-command": 1.27.1 + "@percy/cli-config": 1.27.1 + "@percy/cli-exec": 1.27.1 + "@percy/cli-snapshot": 1.27.1 + "@percy/cli-upload": 1.27.1 + "@percy/client": 1.27.1 + "@percy/logger": 1.27.1 bin: percy: bin/run.cjs - checksum: fb4131670028399d0a4d76d1f6e35ac4691683a7d77ed8d69206ac6ca1e95272df2a5349c72fa4ff96506f8d0e0b74dd94cc1a5ea5fcd97043dba7d2d305772f + checksum: 5c3770bb94fcc4216121a4af53f8d0f5551e77549295879904d82a0adeddfe42c229cc0d74da1c80d452d13ca45dcd5b4902338fe673e45ebd416f5080635e39 languageName: node linkType: hard -"@percy/client@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/client@npm:1.16.0" +"@percy/client@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/client@npm:1.27.1" dependencies: - "@percy/env": 1.16.0 - "@percy/logger": 1.16.0 - checksum: c42ffd61cbd491101bed62d7c0f1dafd4ca40d8c8601cf6dacfcc8cabf626bb828d0ff2eefc9aa77454dd3b0bc79152f2f0895000a5c7d461c69280f68584b58 + "@percy/env": 1.27.1 + "@percy/logger": 1.27.1 + checksum: 51d317cd19ec2f3140d8eb291a94f00f4f3e934f3078aa12daee87f3900a7a7a11ca8a7454c78543cfb6ba3a1d3db1aefb5597b9bb46320583189ccf365b9a96 languageName: node linkType: hard -"@percy/config@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/config@npm:1.16.0" +"@percy/config@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/config@npm:1.27.1" dependencies: - "@percy/logger": 1.16.0 + "@percy/logger": 1.27.1 ajv: ^8.6.2 - cosmiconfig: ^7.0.0 + cosmiconfig: ^8.0.0 yaml: ^2.0.0 - checksum: 652000a556c593a3ed539e21d094cca918342af899ea919b2722d50e5a1a51567637ed0618dc95a1f7f8e465dc5a68d69b9be02efc72f622ee37845d82b25599 + checksum: c1f171573871843bd4f4785d5e95fe64cbedd7e6258061e2b8acf0faa63f5b5d579f679ad18af4d6aa8bcb08779710b7e2a522199a81979af61d6d0b008d0e71 languageName: node linkType: hard -"@percy/core@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/core@npm:1.16.0" +"@percy/core@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/core@npm:1.27.1" dependencies: - "@percy/client": 1.16.0 - "@percy/config": 1.16.0 - "@percy/dom": 1.16.0 - "@percy/logger": 1.16.0 + "@percy/client": 1.27.1 + "@percy/config": 1.27.1 + "@percy/dom": 1.27.1 + "@percy/logger": 1.27.1 + "@percy/webdriver-utils": 1.27.1 content-disposition: ^0.5.4 cross-spawn: ^7.0.3 extract-zip: ^2.0.1 @@ -6466,7 +6467,7 @@ __metadata: path-to-regexp: ^6.2.0 rimraf: ^3.0.2 ws: ^8.0.0 - checksum: a8202db2a65b0dcb16d879f900cdddb5b5cc0138aec88867f54471f0ed52e5debb8b1f43c620a7dc1fdcfefd9f4b7b8457153f4b0bc2643c6b01a2cc2c4cbe24 + checksum: f658011b00b10c284a3d13ed62fb6d7c80e1d8ddcc177a5b9907c564f342d86d608748b2eaaae08f486bdd267658fd8c77c4f1263b6a3c9c5b63ac43b842b653 languageName: node linkType: hard @@ -6481,24 +6482,33 @@ __metadata: languageName: node linkType: hard -"@percy/dom@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/dom@npm:1.16.0" - checksum: 433c2823c82ab4aa2636e3b17658df50765733fa6f645a80ede2dd8e3ee0199cbc62c265b5e77f75919cda2304ef071066f8d1be16b713048298bc66acfb94f0 +"@percy/dom@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/dom@npm:1.27.1" + checksum: 951081184eb1a253baac5d43e5f4e265d9fc65845482a34a1f4bad72c7de64f3873c2739a3a3e84096805e62c4bd7c9fb06afa6b1a8cabad871c7b0b819d8e95 + languageName: node + linkType: hard + +"@percy/env@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/env@npm:1.27.1" + dependencies: + "@percy/logger": 1.27.1 + checksum: 070b19a2d76b3345d51f4085aef88e3be61ddd27b2db0d1c673047a03c33e76801e01b14441090f8a88a6127f4d417dd680d666d8acf04b2976d1269a201692d languageName: node linkType: hard -"@percy/env@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/env@npm:1.16.0" - checksum: 88fba7c4be5ce5c5662d20c3d7d4b2c6df66c516a4e0c0c5e0327768d480eeda8490a9503f60dfd8720df0dfa34481633d3c284a12c25cda87cef3e5381a5e3f +"@percy/logger@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/logger@npm:1.27.1" + checksum: a3c1d40878c2a9182f0b98ed27e7d56c8693fe504598fc869aaac4eca06676abefccaa03b5d9c41e33ea8957d07bbef6c7dae01dcf681c1969dcb6bc13f8ab38 languageName: node linkType: hard -"@percy/logger@npm:1.16.0": - version: 1.16.0 - resolution: "@percy/logger@npm:1.16.0" - checksum: 172d2271a6ffd04d1990d616067f1440fb0a236b65f1c52072722e1c6e9c308110bcce86f9ccf91266e1857e83a1d40aed2db2f6dfb947efaf5db59004001d99 +"@percy/sdk-utils@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/sdk-utils@npm:1.27.1" + checksum: c0c97233b8afdf3b70b8ad57e20f074bc7adbe26af625088a8e67d9e244b1445f5b5f705152994316eabbb608309ee0fc420693366fa857f2eab6666fb0f90e7 languageName: node linkType: hard @@ -6509,6 +6519,16 @@ __metadata: languageName: node linkType: hard +"@percy/webdriver-utils@npm:1.27.1": + version: 1.27.1 + resolution: "@percy/webdriver-utils@npm:1.27.1" + dependencies: + "@percy/config": 1.27.1 + "@percy/sdk-utils": 1.27.1 + checksum: 847b2eef1c6aed6f8e54b103b3af0af7b4e6278584c60b85cb32547515c52b0cabd1e4bb64dd5b8ffcc73df4d50c6a37d72c966a150b8bbe3c1b08160da6dc2a + languageName: node + linkType: hard + "@philpl/buble@npm:^0.19.7": version: 0.19.7 resolution: "@philpl/buble@npm:0.19.7" @@ -9974,13 +9994,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^14.14.31": - version: 14.18.12 - resolution: "@types/node@npm:14.18.12" - checksum: 8a0273caa0584020adb8802784fc7d4f18f05e6c205335b7f3818a91d6b0c22736b9f51da3428d5bc54076ad47f1a4d6d57990a3ce8489a520ac66b2b3ff24bc - languageName: node - linkType: hard - "@types/node@npm:^16.0.0": version: 16.18.44 resolution: "@types/node@npm:16.18.44" @@ -9995,6 +10008,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.17.5": + version: 18.17.15 + resolution: "@types/node@npm:18.17.15" + checksum: eed11d4398ccdb999a4c65658ee75de621a4ad57aece48ed2fb8803b1e2711fadf58d8aefbdb0a447d69cf3cba602ca32fe0fc92077575950a796e1dc13baa0f + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.1 resolution: "@types/normalize-package-data@npm:2.4.1" @@ -13244,6 +13264,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^8.0.0": + version: 8.3.5 + resolution: "cosmiconfig@npm:8.3.5" + dependencies: + import-fresh: ^3.3.0 + js-yaml: ^4.1.0 + parse-json: ^5.2.0 + path-type: ^4.0.0 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: c6e44bb3cabf268b70049e7bd4ee8ecf00068854e53cbc32f9104794927ef406817f9e64e1c4949bd10776b604c01f7b50674336fcd2d5b9efc4cf8277fdf025 + languageName: node + linkType: hard + "crc-32@npm:^1.2.0": version: 1.2.0 resolution: "crc-32@npm:1.2.0" @@ -13649,22 +13686,22 @@ __metadata: languageName: node linkType: hard -"cypress-real-events@npm:^1.7.4": - version: 1.7.4 - resolution: "cypress-real-events@npm:1.7.4" +"cypress-real-events@npm:^1.10.3": + version: 1.10.3 + resolution: "cypress-real-events@npm:1.10.3" peerDependencies: - cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x - checksum: 6b796b765b3e959264c9e967c1c3d735aeb1225ce27e9a00021c0a797019545202a8a3c13539c16321cd2dcb0008c556f80714655a69da3d45e4ea08d62f9b0c + cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x || ^12.x || ^13.x + checksum: 9a6d4addb33b16fcf4e4eb55c21589b626203303f8e60b441b5ed50d55c55424b5587efd91a7b79fbca7d4fbc544829d2793e9c29fdf94dfa7ecaf5f661b105e languageName: node linkType: hard -"cypress@npm:^12.1.0": - version: 12.1.0 - resolution: "cypress@npm:12.1.0" +"cypress@npm:^13.2.0": + version: 13.2.0 + resolution: "cypress@npm:13.2.0" dependencies: - "@cypress/request": ^2.88.10 + "@cypress/request": ^3.0.0 "@cypress/xvfb": ^1.2.4 - "@types/node": ^14.14.31 + "@types/node": ^18.17.5 "@types/sinonjs__fake-timers": 8.1.1 "@types/sizzle": ^2.3.2 arch: ^2.2.0 @@ -13676,10 +13713,10 @@ __metadata: check-more-types: ^2.24.0 cli-cursor: ^3.1.0 cli-table3: ~0.6.1 - commander: ^5.1.0 + commander: ^6.2.1 common-tags: ^1.8.0 dayjs: ^1.10.4 - debug: ^4.3.2 + debug: ^4.3.4 enquirer: ^2.3.6 eventemitter2: 6.4.7 execa: 4.1.0 @@ -13694,19 +13731,20 @@ __metadata: listr2: ^3.8.3 lodash: ^4.17.21 log-symbols: ^4.0.0 - minimist: ^1.2.6 + minimist: ^1.2.8 ospath: ^1.2.2 pretty-bytes: ^5.6.0 + process: ^0.11.10 proxy-from-env: 1.0.0 request-progress: ^3.0.0 - semver: ^7.3.2 + semver: ^7.5.3 supports-color: ^8.1.1 tmp: ~0.2.1 untildify: ^4.0.0 yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: 238ea125f396594a84ba096e0eaebe6f0d6b60b3b232a3f6e36420f9fa7a9218211df8dc6ad2a4f6cc0cc2fd77d4e0eb0932b409a73ff8434e78e880a36f59a7 + checksum: 7647814f07626bd63e7b8dc4d066179fa40bf492c588bbc2626d983a2baab6cb77c29958dc92442f277e0a8e94866decc51c4de306021739c47e32baf5970219 languageName: node linkType: hard @@ -20335,6 +20373,13 @@ __metadata: languageName: node linkType: hard +"minimist@npm:^1.2.8": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 + languageName: node + linkType: hard + "minimisted@npm:^2.0.0": version: 2.0.1 resolution: "minimisted@npm:2.0.1" @@ -22533,10 +22578,10 @@ __metadata: languageName: node linkType: hard -"psl@npm:^1.1.28": - version: 1.8.0 - resolution: "psl@npm:1.8.0" - checksum: 6150048ed2da3f919478bee8a82f3828303bc0fc730fb015a48f83c9977682c7b28c60ab01425a72d82a2891a1681627aa530a991d50c086b48a3be27744bde7 +"psl@npm:^1.1.33": + version: 1.9.0 + resolution: "psl@npm:1.9.0" + checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d languageName: node linkType: hard @@ -22663,10 +22708,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.5.2": - version: 6.5.2 - resolution: "qs@npm:6.5.2" - checksum: 24af7b9928ba2141233fba2912876ff100403dba1b08b20c3b490da9ea6c636760445ea2211a079e7dfa882a5cf8f738337b3748c8bdd0f93358fa8881d2db8f +"qs@npm:6.10.4": + version: 6.10.4 + resolution: "qs@npm:6.10.4" + dependencies: + side-channel: ^1.0.4 + checksum: 31e4fedd759d01eae52dde6692abab175f9af3e639993c5caaa513a2a3607b34d8058d3ae52ceeccf37c3025f22ed5e90e9ddd6c2537e19c0562ddd10dc5b1eb languageName: node linkType: hard @@ -22677,6 +22724,13 @@ __metadata: languageName: node linkType: hard +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 5641ea231bad7ef6d64d9998faca95611ed4b11c2591a8cae741e178a974f6a8e0ebde008475259abe1621cb15e692404e6b6626e927f7b849d5c09392604b15 + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -25611,13 +25665,15 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:~2.5.0": - version: 2.5.0 - resolution: "tough-cookie@npm:2.5.0" +"tough-cookie@npm:^4.1.3": + version: 4.1.3 + resolution: "tough-cookie@npm:4.1.3" dependencies: - psl: ^1.1.28 + psl: ^1.1.33 punycode: ^2.1.1 - checksum: 16a8cd090224dd176eee23837cbe7573ca0fa297d7e468ab5e1c02d49a4e9a97bb05fef11320605eac516f91d54c57838a25864e8680e27b069a5231d8264977 + universalify: ^0.2.0 + url-parse: ^1.5.3 + checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc languageName: node linkType: hard @@ -26135,6 +26191,13 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.2.0": + version: 0.2.0 + resolution: "universalify@npm:0.2.0" + checksum: e86134cb12919d177c2353196a4cc09981524ee87abf621f7bc8d249dbbbebaec5e7d1314b96061497981350df786e4c5128dbf442eba104d6e765bc260678b5 + languageName: node + linkType: hard + "universalify@npm:^2.0.0": version: 2.0.0 resolution: "universalify@npm:2.0.0" @@ -26276,6 +26339,16 @@ __metadata: languageName: node linkType: hard +"url-parse@npm:^1.5.3": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: ^2.1.1 + requires-port: ^1.0.0 + checksum: fbdba6b1d83336aca2216bbdc38ba658d9cfb8fc7f665eb8b17852de638ff7d1a162c198a8e4ed66001ddbf6c9888d41e4798912c62b4fd777a31657989f7bdf + languageName: node + linkType: hard + "url@npm:^0.11.0": version: 0.11.0 resolution: "url@npm:0.11.0" From 419e89b2dac19dfd717402975f7501c6e3a51def Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 12 Sep 2023 22:52:14 +0200 Subject: [PATCH 09/16] upgrade cypress image and Node.js in the CI pipeline --- .github/workflows/CI.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 6b4bc880..278a4dd3 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 14.17.0 + node-version: 16.16.0 cache: yarn - name: Install Dependencies 🔧 @@ -40,7 +40,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 14.17.0 + node-version: 16.16.0 cache: yarn - name: Install Dependencies 🔧 @@ -72,7 +72,7 @@ jobs: matrix: group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] runs-on: ubuntu-latest # note: macos doesn't have docker installed! - container: cypress/browsers:node14.17.0-chrome91-ff89 + container: cypress/browsers:node16.16.0-chrome107-ff107-edge env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} @@ -89,7 +89,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 14.17.0 + node-version: 16.16.0 cache: yarn - name: Install Dependencies 🔧 From f5616f8c0c344b70b6e6fb433d187257890b9958 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 12 Sep 2023 23:32:02 +0200 Subject: [PATCH 10/16] Attempting to fix test regressions - A regression in a ActionsMenu test case, due to section title being removed - A regression in many tests suites seemingly related to the upgrade of cypress-real-events. So reverting back to the previously working version. --- packages/jui/package.json | 2 +- .../src/ActionSystem/components/ActionsMenu.cy.tsx | 3 ++- yarn.lock | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/jui/package.json b/packages/jui/package.json index 052001cc..c95c957f 100644 --- a/packages/jui/package.json +++ b/packages/jui/package.json @@ -105,7 +105,7 @@ "crypto-browserify": "^3.12.0", "cypress": "^13.2.0", "cypress-plugin-snapshots": "1.4.4", - "cypress-real-events": "^1.10.3", + "cypress-real-events": "1.7.4", "hygen": "^6.2.11", "jest": "^29.0.3", "path-browserify": "^1.0.1", diff --git a/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx b/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx index d8147a57..eafc1569 100644 --- a/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx +++ b/packages/jui/src/ActionSystem/components/ActionsMenu.cy.tsx @@ -72,6 +72,7 @@ describe("ActionsMenu", () => { ); cy.findByRole("menuitem", { name: "Action 1" }).should("not.exist"); + cy.findByRole("group", { name: "Action Group 1" }).should("not.exist"); cy.findByRole("menuitem", { name: "Action Group 1" }).click(); cy.findByRole("menuitem", { name: "Action 1" }); }); @@ -106,7 +107,7 @@ describe("ActionsMenu", () => { ); cy.findByRole("menuitem", { name: "Action 1" }); - cy.findByRole("group", { name: "Action Group 1" }); + cy.findByRole("group"); }); it("performs selected action", () => { diff --git a/yarn.lock b/yarn.lock index e17d1309..9de3f660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4122,7 +4122,7 @@ __metadata: crypto-browserify: ^3.12.0 cypress: ^13.2.0 cypress-plugin-snapshots: 1.4.4 - cypress-real-events: ^1.10.3 + cypress-real-events: 1.7.4 hygen: ^6.2.11 jest: ^29.0.3 path-browserify: ^1.0.1 @@ -13686,12 +13686,12 @@ __metadata: languageName: node linkType: hard -"cypress-real-events@npm:^1.10.3": - version: 1.10.3 - resolution: "cypress-real-events@npm:1.10.3" +"cypress-real-events@npm:1.7.4": + version: 1.7.4 + resolution: "cypress-real-events@npm:1.7.4" peerDependencies: - cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x || ^12.x || ^13.x - checksum: 9a6d4addb33b16fcf4e4eb55c21589b626203303f8e60b441b5ed50d55c55424b5587efd91a7b79fbca7d4fbc544829d2793e9c29fdf94dfa7ecaf5f661b105e + cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x + checksum: 6b796b765b3e959264c9e967c1c3d735aeb1225ce27e9a00021c0a797019545202a8a3c13539c16321cd2dcb0008c556f80714655a69da3d45e4ea08d62f9b0c languageName: node linkType: hard From c0f79791ace258be2c9dfdf06917114771294915 Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 13 Sep 2023 08:17:45 +0200 Subject: [PATCH 11/16] chore: make sure yarn.lock is not changed on the CI pipeline --- .github/workflows/CI.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 278a4dd3..8d23e377 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -24,7 +24,7 @@ jobs: cache: yarn - name: Install Dependencies 🔧 - run: yarn + run: yarn install --immutable build_and_test: runs-on: ubuntu-latest @@ -44,7 +44,7 @@ jobs: cache: yarn - name: Install Dependencies 🔧 - run: yarn + run: yarn install --immutable - name: Type Check ʦ run: yarn run type-check @@ -93,7 +93,7 @@ jobs: cache: yarn - name: Install Dependencies 🔧 - run: yarn + run: yarn install --immutable - name: Run Cypress Tests ✅ if: ${{ env.IS_PR_JUST_MERGED == 'true' || env.IS_PR_WITH_PERCY == 'true' }} From f8a647507b8261953b464658f7d521725dc7ef0d Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 13 Sep 2023 10:40:26 +0200 Subject: [PATCH 12/16] robust a few test cases Some tests started to fail after the Github Action ubuntu container and cypress are upgraded --- packages/jui/src/Checkbox/Checkbox.cy.tsx | 4 ++-- packages/jui/src/ToolWindows/ToolWindows.cy.tsx | 3 ++- packages/jui/src/Tree/Tree.cy.tsx | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/jui/src/Checkbox/Checkbox.cy.tsx b/packages/jui/src/Checkbox/Checkbox.cy.tsx index f37285f6..6aef6491 100644 --- a/packages/jui/src/Checkbox/Checkbox.cy.tsx +++ b/packages/jui/src/Checkbox/Checkbox.cy.tsx @@ -40,7 +40,7 @@ describe("Checkbox", () => { ); cy.get("#dummyInput").focus(); // tabbing to the text input cy.realPress("Tab"); // next tab should move focus to the checkbox - cy.focused().should("have.attr", "type", "checkbox"); + cy.findByRole("checkbox").should("be.focused"); cy.mount(
@@ -50,7 +50,7 @@ describe("Checkbox", () => { ); cy.get("#dummyInput").focus(); // tabbing to the text input cy.realPress("Tab"); // next tab should not focus the checkbox since excludeFromTabOrder is passed - cy.focused().should("not.exist"); + cy.findByRole("checkbox").should("not.be.focused"); }); it("supports preventFocus", () => { diff --git a/packages/jui/src/ToolWindows/ToolWindows.cy.tsx b/packages/jui/src/ToolWindows/ToolWindows.cy.tsx index 7dfa9744..18a64a1e 100644 --- a/packages/jui/src/ToolWindows/ToolWindows.cy.tsx +++ b/packages/jui/src/ToolWindows/ToolWindows.cy.tsx @@ -42,6 +42,7 @@ const SimpleToolWindows = ({ >