diff --git a/packages/code-studio/src/assets/svg/cursor-copy.svg b/packages/code-studio/src/assets/svg/cursor-copy.svg deleted file mode 100644 index 28421e86b4..0000000000 --- a/packages/code-studio/src/assets/svg/cursor-copy.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/packages/code-studio/src/main/AppMainContainer.scss b/packages/code-studio/src/main/AppMainContainer.scss index 450484b2a2..3ac393724f 100644 --- a/packages/code-studio/src/main/AppMainContainer.scss +++ b/packages/code-studio/src/main/AppMainContainer.scss @@ -9,34 +9,6 @@ $tab-link-disabled-color: $gray-600; $nav-space: 4px; // give a gap around some buttons for focus area that are in nav bar -.grid-cursor-copy { - cursor: - url('../assets/svg/cursor-copy.svg') 8 8, - copy; -} - -.grid-cursor-linker { - cursor: - url('../assets/svg/cursor-linker.svg') 8 8, - crosshair; -} - -.grid-cursor-linker-not-allowed { - cursor: - url('../assets/svg/cursor-linker-not-allowed.svg') 8 8, - not-allowed; -} - -.linker-overlay path.link-select { - cursor: pointer; -} - -.linker-overlay.danger-delete path.link-select { - cursor: - url('../assets/svg/cursor-unlinker.svg') 8 8, - pointer; -} - .app-main-top-nav-menus { display: flex; width: 100%; diff --git a/packages/components/logos/community-wordmark-dark.svg b/packages/components/assets/logos/community-wordmark-dark.svg similarity index 100% rename from packages/components/logos/community-wordmark-dark.svg rename to packages/components/assets/logos/community-wordmark-dark.svg diff --git a/packages/components/logos/community-wordmark-light.svg b/packages/components/assets/logos/community-wordmark-light.svg similarity index 100% rename from packages/components/logos/community-wordmark-light.svg rename to packages/components/assets/logos/community-wordmark-light.svg diff --git a/packages/components/package.json b/packages/components/package.json index 2ee076961b..e157c3960f 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -58,7 +58,7 @@ "dist", "scss", "css", - "logos" + "assets" ], "sideEffects": [ "*.css" diff --git a/packages/components/src/theme/Logo.css b/packages/components/src/theme/Logo.css index 64f6c791f4..6396d2d9e4 100644 --- a/packages/components/src/theme/Logo.css +++ b/packages/components/src/theme/Logo.css @@ -1,6 +1,6 @@ :root { - --dh-logo-dark-img: url('../../logos/community-wordmark-dark.svg'); - --dh-logo-light-img: url('../../logos/community-wordmark-light.svg'); + --dh-logo-dark-img: url('../../assets/logos/community-wordmark-dark.svg'); + --dh-logo-light-img: url('../../assets/logos/community-wordmark-light.svg'); } .dh-logo { diff --git a/packages/code-studio/src/assets/svg/cursor-unlinker.svg b/packages/dashboard-core-plugins/assets/svg/cursor-unlinker.svg similarity index 100% rename from packages/code-studio/src/assets/svg/cursor-unlinker.svg rename to packages/dashboard-core-plugins/assets/svg/cursor-unlinker.svg diff --git a/packages/dashboard-core-plugins/package.json b/packages/dashboard-core-plugins/package.json index 926704a197..fff5495dee 100644 --- a/packages/dashboard-core-plugins/package.json +++ b/packages/dashboard-core-plugins/package.json @@ -68,7 +68,8 @@ "@deephaven/mocks": "file:../mocks" }, "files": [ - "dist" + "dist", + "assets" ], "sideEffects": [ "*.css" diff --git a/packages/dashboard-core-plugins/src/linker/LinkerLink.scss b/packages/dashboard-core-plugins/src/linker/LinkerLink.scss index cdb0c85e87..afba9f3ad5 100644 --- a/packages/dashboard-core-plugins/src/linker/LinkerLink.scss +++ b/packages/dashboard-core-plugins/src/linker/LinkerLink.scss @@ -128,6 +128,12 @@ $dash-size: 10; } &.danger-delete { + path.link-select { + cursor: + url('../assets/svg/cursor-unlinker.svg') 8 8, + pointer; + } + path.link-select:hover ~ path.link-background { stroke: $dash-delete-color-2; } diff --git a/packages/dashboard-core-plugins/src/panels/IrisGridPanel.scss b/packages/dashboard-core-plugins/src/panels/IrisGridPanel.scss index e5235adc1d..f798b35bfd 100644 --- a/packages/dashboard-core-plugins/src/panels/IrisGridPanel.scss +++ b/packages/dashboard-core-plugins/src/panels/IrisGridPanel.scss @@ -27,11 +27,3 @@ $panel-message-overlay-top: 30px; color: $danger; } } - -.grid-cursor-linker { - cursor: crosshair; -} - -.grid-cursor-copy { - cursor: copy; -} diff --git a/packages/grid/src/Grid.tsx b/packages/grid/src/Grid.tsx index 04cdbf2ef5..c54cc48746 100644 --- a/packages/grid/src/Grid.tsx +++ b/packages/grid/src/Grid.tsx @@ -1729,18 +1729,23 @@ class Grid extends PureComponent { event: GridKeyboardEvent ): void { const keyHandlers = this.getKeyHandlers(); + let cursor = null; for (let i = 0; i < keyHandlers.length; i += 1) { const keyHandler = keyHandlers[i]; const result = keyHandler[functionName] != null && keyHandler[functionName](event, this); if (result !== false) { + if (keyHandler.cursor != null) { + ({ cursor } = keyHandler); + } const options = result as EventHandlerResultOptions; if (options?.stopPropagation ?? true) event.stopPropagation(); if (options?.preventDefault ?? true) event.preventDefault(); break; } } + this.setState({ cursor }); } handleKeyDown(event: GridKeyboardEvent): void { diff --git a/packages/grid/src/KeyHandler.ts b/packages/grid/src/KeyHandler.ts index f6216f5adf..776b533383 100644 --- a/packages/grid/src/KeyHandler.ts +++ b/packages/grid/src/KeyHandler.ts @@ -26,6 +26,9 @@ export class KeyHandler { this.order = order; } + // Cursor to use if this returns any truthy value including { stopPropagation: false, preventDefault: false } + cursor: string | null = null; + /** * Handle a keydown event on the grid. * @param event The keyboard event diff --git a/packages/iris-grid/assets/svg/cursor-copy.svg b/packages/iris-grid/assets/svg/cursor-copy.svg new file mode 100644 index 0000000000..893bd23cc1 --- /dev/null +++ b/packages/iris-grid/assets/svg/cursor-copy.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/packages/code-studio/src/assets/svg/cursor-linker-not-allowed.svg b/packages/iris-grid/assets/svg/cursor-linker-not-allowed.svg similarity index 100% rename from packages/code-studio/src/assets/svg/cursor-linker-not-allowed.svg rename to packages/iris-grid/assets/svg/cursor-linker-not-allowed.svg diff --git a/packages/code-studio/src/assets/svg/cursor-linker.svg b/packages/iris-grid/assets/svg/cursor-linker.svg similarity index 100% rename from packages/code-studio/src/assets/svg/cursor-linker.svg rename to packages/iris-grid/assets/svg/cursor-linker.svg diff --git a/packages/iris-grid/package.json b/packages/iris-grid/package.json index d1f372ad69..7452cea1ea 100644 --- a/packages/iris-grid/package.json +++ b/packages/iris-grid/package.json @@ -68,7 +68,8 @@ "@deephaven/mocks": "file:../mocks" }, "files": [ - "dist" + "dist", + "assets" ], "sideEffects": [ "*.css" diff --git a/packages/iris-grid/src/IrisGrid.scss b/packages/iris-grid/src/IrisGrid.scss index d03356fe46..9a2cd25aa6 100644 --- a/packages/iris-grid/src/IrisGrid.scss +++ b/packages/iris-grid/src/IrisGrid.scss @@ -40,6 +40,24 @@ $cell-invalid-box-shadow: position: relative; } + .grid-cursor-copy { + cursor: + url('../assets/svg/cursor-copy.svg') 8 8, + copy; + } + + .grid-cursor-linker { + cursor: + url('../assets/svg/cursor-linker.svg') 8 8, + crosshair; + } + + .grid-cursor-linker-not-allowed { + cursor: + url('../assets/svg/cursor-linker-not-allowed.svg') 8 8, + not-allowed; + } + .table-sidebar { height: 100%; flex: 0 0 $table-sidebar-max-width; diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index 3d387c75d2..7a48cb6034 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -111,6 +111,7 @@ import PendingDataBottomBar from './PendingDataBottomBar'; import IrisGridCopyHandler, { CopyOperation } from './IrisGridCopyHandler'; import FilterInputField from './FilterInputField'; import { + CopyCellKeyHandler, ClearFilterKeyHandler, CopyKeyHandler, ReverseKeyHandler, @@ -489,7 +490,7 @@ export class IrisGrid extends Component { columnSelectionValidator: null, columnAllowedCursor: null, columnNotAllowedCursor: null, - copyCursor: null, + copyCursor: 'copy', name: 'table', onlyFetchVisibleColumns: true, showSearchBar: false, @@ -703,6 +704,7 @@ export class IrisGrid extends Component { const { dh } = model; const keyHandlers: KeyHandler[] = [ + new CopyCellKeyHandler(this), new ReverseKeyHandler(this), new ClearFilterKeyHandler(this), ]; diff --git a/packages/iris-grid/src/key-handlers/CopyCellKeyHandler.ts b/packages/iris-grid/src/key-handlers/CopyCellKeyHandler.ts new file mode 100644 index 0000000000..8bcea06008 --- /dev/null +++ b/packages/iris-grid/src/key-handlers/CopyCellKeyHandler.ts @@ -0,0 +1,45 @@ +import { KeyboardEvent } from 'react'; +import { KeyHandler } from '@deephaven/grid'; +import { ContextActionUtils } from '@deephaven/components'; +import type { Grid } from '@deephaven/grid'; +import { IrisGrid } from '../IrisGrid'; + +class CopyCellKeyHandler extends KeyHandler { + private irisGrid: IrisGrid; + + constructor(irisGrid: IrisGrid) { + super(); + + this.irisGrid = irisGrid; + this.cursor = null; + } + + onDown(event: KeyboardEvent, grid: Grid): boolean { + if ( + event.altKey && + !ContextActionUtils.isModifierKeyDown(event) && + !event.shiftKey + ) { + const { mouseX, mouseY } = grid.state; + if (mouseX == null || mouseY == null) { + return false; + } + const gridPoint = grid.getGridPointFromXY(mouseX, mouseY); + if (gridPoint.column != null && gridPoint.row != null) { + this.cursor = this.irisGrid.props.copyCursor; + return true; + } + } + return false; + } + + onUp(event: KeyboardEvent, grid: Grid): boolean { + if (this.cursor === this.irisGrid.props.copyCursor) { + this.cursor = null; + return true; + } + return false; + } +} + +export default CopyCellKeyHandler; diff --git a/packages/iris-grid/src/key-handlers/index.ts b/packages/iris-grid/src/key-handlers/index.ts index 2ddf3e7624..4570b91e76 100644 --- a/packages/iris-grid/src/key-handlers/index.ts +++ b/packages/iris-grid/src/key-handlers/index.ts @@ -1,3 +1,4 @@ +export { default as CopyCellKeyHandler } from './CopyCellKeyHandler'; export { default as CopyKeyHandler } from './CopyKeyHandler'; export { default as ReverseKeyHandler } from './ReverseKeyHandler'; export { default as ClearFilterKeyHandler } from './ClearFilterKeyHandler';