-
Notifications
You must be signed in to change notification settings - Fork 118
H-5976: Fix display of tooltips for readonly inputs #8285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
289cf54
Remove DisabledTooltip wrapper and inline tooltip logic
kube 9c737c2
Fix Switch tooltip by wrapping with ark.span for proper event forwarding
kube 180d288
Add disabled and tooltip props to SegmentGroup component
kube 16e658e
Use ID composition for SegmentGroup tooltip to avoid layout-breaking …
kube 39448b5
Use display:contents wrapper for SegmentGroup tooltip
kube 958fb41
Fix SegmentGroup tooltip using ArkTooltip.Trigger with asChild
kube 1a70954
Disable delete buttons in properties panels during simulation
kube 57f8d65
Add tooltip to Dynamics switch when no type is selected
kube d13cd43
Disable Visualizer toggle during simulation
kube 303c763
Keep editor read-only when simulation is complete
kube 2d7a53f
Prevent Delete/Backspace keyboard deletion in read-only mode
kube 07273d1
Use useIsReadOnly hook in SDCPN canvas view
kube 060eed5
Disable add/delete buttons in sidebar lists during read-only mode
kube 6108b91
Add changeset for read-only tooltips fix
kube e8c28b7
Fix CodeEditor overlay blocking scroll in read-only mode
kube 1b95fc3
Fix SegmentGroup tooltip nesting structure
kube 4b5d663
Fix Tooltip to work on disabled elements
kube 5d3dd19
Fix Tooltip wrapper to use flex instead of inline-flex
kube 24e3357
Add width: 100% to Tooltip wrapper for block elements
kube e0e8032
Use div instead of span for Tooltip wrapper
kube 83b22c8
Fix Tooltip wrapper to preserve input dimensions
kube 3620c95
Refactor Tooltip component with display variants and fix readonly guards
kube 401ea89
Remove unused `mode` variable from SDCPNView
kube 1cc91a8
Add withTooltip HoC to reduce tooltip boilerplate in components
kube 1cc11b2
Add reusable form components and refactor properties panels
kube 9b44186
Replace interface with type in form component props
kube 68ef34f
Fix CodeEditor tooltip and listener issues from AI review
kube 1f85b90
Fix duplicate listener registration and add arc tooltips
kube 99fdc4d
Improve type dropdown UX and simplify CodeEditor tooltip
kube File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@hashintel/petrinaut": patch | ||
| --- | ||
|
|
||
| Fix read-only tooltips to always show during simulation mode |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import { cva } from "@hashintel/ds-helpers/css"; | ||
|
|
||
| import { withTooltip } from "./hoc/with-tooltip"; | ||
|
|
||
| const buttonStyle = cva({ | ||
| base: { | ||
| display: "inline-flex", | ||
| alignItems: "center", | ||
| justifyContent: "center", | ||
| gap: "[6px]", | ||
| fontSize: "[12px]", | ||
| padding: "[4px 8px]", | ||
| border: "[1px solid rgba(0, 0, 0, 0.2)]", | ||
| borderRadius: "[4px]", | ||
| backgroundColor: "[white]", | ||
| color: "[#333]", | ||
| cursor: "pointer", | ||
| transition: "[all 0.15s ease]", | ||
| _hover: { | ||
| backgroundColor: "[rgba(0, 0, 0, 0.05)]", | ||
| }, | ||
| _active: { | ||
| backgroundColor: "[rgba(0, 0, 0, 0.1)]", | ||
| }, | ||
| }, | ||
| variants: { | ||
| isDisabled: { | ||
| true: { | ||
| opacity: "[0.5]", | ||
| cursor: "not-allowed", | ||
| _hover: { | ||
| backgroundColor: "[white]", | ||
| }, | ||
| }, | ||
| false: {}, | ||
| }, | ||
| variant: { | ||
| default: {}, | ||
| ghost: { | ||
| border: "none", | ||
| backgroundColor: "[transparent]", | ||
| _hover: { | ||
| backgroundColor: "[rgba(0, 0, 0, 0.05)]", | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| defaultVariants: { | ||
| isDisabled: false, | ||
| variant: "default", | ||
| }, | ||
| }); | ||
|
|
||
| type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & { | ||
| /** Button variant */ | ||
| variant?: "default" | "ghost"; | ||
| /** Button content */ | ||
| children: React.ReactNode; | ||
| /** Ref to the button element */ | ||
| ref?: React.Ref<HTMLButtonElement>; | ||
| }; | ||
|
|
||
| const ButtonBase: React.FC<ButtonProps> = ({ | ||
| variant = "default", | ||
| disabled, | ||
| className, | ||
| children, | ||
| ref, | ||
| ...props | ||
| }) => ( | ||
| <button | ||
| ref={ref} | ||
| type="button" | ||
| disabled={disabled} | ||
| className={`${buttonStyle({ isDisabled: disabled, variant })}${className ? ` ${className}` : ""}`} | ||
| {...props} | ||
| > | ||
| {children} | ||
| </button> | ||
| ); | ||
|
|
||
| export const Button = withTooltip(ButtonBase, "block"); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import { css, cva } from "@hashintel/ds-helpers/css"; | ||
| import type { EditorProps, Monaco } from "@monaco-editor/react"; | ||
| import MonacoEditor from "@monaco-editor/react"; | ||
| import type { editor } from "monaco-editor"; | ||
| import { useCallback, useRef } from "react"; | ||
|
|
||
| import { Tooltip } from "./tooltip"; | ||
|
|
||
| const containerStyle = cva({ | ||
| base: { | ||
| position: "relative", | ||
| border: "[1px solid rgba(0, 0, 0, 0.1)]", | ||
| borderRadius: "[4px]", | ||
| overflow: "hidden", | ||
| }, | ||
| variants: { | ||
| isReadOnly: { | ||
| true: { | ||
| filter: "[grayscale(20%) brightness(98%)]", | ||
| cursor: "not-allowed", | ||
| }, | ||
| false: {}, | ||
| }, | ||
| }, | ||
| }); | ||
|
kube marked this conversation as resolved.
|
||
|
|
||
| type CodeEditorProps = Omit<EditorProps, "theme"> & { | ||
| tooltip?: string; | ||
| }; | ||
|
|
||
| /** | ||
| * Code editor component that wraps Monaco Editor. | ||
| * | ||
| * @param tooltip - Optional tooltip to show when hovering over the editor. | ||
| * In read-only mode, the tooltip also appears when attempting to edit. | ||
| */ | ||
| export const CodeEditor: React.FC<CodeEditorProps> = ({ | ||
| tooltip, | ||
| options, | ||
| height, | ||
| onMount, | ||
| ...props | ||
| }) => { | ||
| const isReadOnly = options?.readOnly === true; | ||
| const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null); | ||
|
|
||
| const handleMount = useCallback( | ||
| (editorInstance: editor.IStandaloneCodeEditor, monaco: Monaco) => { | ||
| editorRef.current = editorInstance; | ||
| // Call the original onMount if provided | ||
| onMount?.(editorInstance, monaco); | ||
| }, | ||
| [onMount], | ||
| ); | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| const editorOptions: EditorProps["options"] = { | ||
| minimap: { enabled: false }, | ||
| scrollBeyondLastLine: false, | ||
| fontSize: 12, | ||
| lineNumbers: "off", | ||
| folding: true, | ||
| glyphMargin: false, | ||
| lineDecorationsWidth: 0, | ||
| lineNumbersMinChars: 3, | ||
| padding: { top: 8, bottom: 8 }, | ||
| fixedOverflowWidgets: true, | ||
| ...options, | ||
| }; | ||
|
|
||
| const editorElement = ( | ||
| <div className={containerStyle({ isReadOnly })} style={{ height }}> | ||
| <MonacoEditor | ||
| theme="vs-light" | ||
| height="100%" | ||
| options={editorOptions} | ||
| onMount={handleMount} | ||
| {...props} | ||
| /> | ||
| </div> | ||
| ); | ||
|
|
||
| // Regular tooltip for non-read-only mode (if tooltip is provided) | ||
| if (tooltip) { | ||
| return ( | ||
| <Tooltip | ||
| content={tooltip} | ||
| display="block" | ||
| className={css({ | ||
| flex: "1", | ||
| })} | ||
| > | ||
| {editorElement} | ||
| </Tooltip> | ||
| ); | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| } | ||
|
|
||
| return editorElement; | ||
| }; | ||
43 changes: 0 additions & 43 deletions
43
libs/@hashintel/petrinaut/src/components/disabled-tooltip.tsx
This file was deleted.
Oops, something went wrong.
63 changes: 63 additions & 0 deletions
63
libs/@hashintel/petrinaut/src/components/hoc/with-tooltip.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import type { ComponentType } from "react"; | ||
|
|
||
| import { Tooltip } from "../tooltip"; | ||
|
|
||
| type WithTooltipProps = { | ||
| /** Tooltip to show when hovering (useful for explaining disabled state). */ | ||
| tooltip?: string; | ||
| /** | ||
| * Display mode for the tooltip wrapper element. | ||
| * - "block": For full-width elements like inputs/selects (default) | ||
| * - "inline": For inline elements like buttons in flex containers | ||
| */ | ||
| tooltipDisplay?: "block" | "inline"; | ||
| }; | ||
|
|
||
| /** | ||
| * Higher-Order Component that adds tooltip support to any component. | ||
| * | ||
| * When `tooltip` prop is provided, the component is wrapped with a Tooltip. | ||
| * When `tooltip` is undefined/empty, the component renders unwrapped. | ||
| * | ||
| * @param Component - The component to wrap | ||
| * @param defaultDisplay - Default display mode for the tooltip wrapper ("block" | "inline") | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * const MyButtonBase: React.FC<{ onClick: () => void }> = ({ onClick }) => ( | ||
| * <button onClick={onClick}>Click me</button> | ||
| * ); | ||
| * | ||
| * export const MyButton = withTooltip(MyButtonBase, "inline"); | ||
| * | ||
| * // Usage: | ||
| * <MyButton onClick={handleClick} tooltip="Click to submit" /> | ||
| * ``` | ||
| */ | ||
| export function withTooltip<P extends object>( | ||
| Component: ComponentType<P>, | ||
| defaultDisplay: "block" | "inline" = "block", | ||
| ): ComponentType<P & WithTooltipProps> { | ||
| const WrappedComponent: React.FC<P & WithTooltipProps> = ({ | ||
| tooltip, | ||
| tooltipDisplay = defaultDisplay, | ||
| ...props | ||
| }) => { | ||
| const element = <Component {...(props as P)} />; | ||
|
|
||
| if (!tooltip) { | ||
| return element; | ||
| } | ||
|
|
||
| return ( | ||
| <Tooltip content={tooltip} display={tooltipDisplay}> | ||
| {element} | ||
| </Tooltip> | ||
| ); | ||
| }; | ||
|
|
||
| // Set display name for debugging | ||
| WrappedComponent.displayName = `withTooltip(${Component.displayName ?? Component.name})`; | ||
|
|
||
| return WrappedComponent; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.