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
[Labs] Tooltip 2 #1438
[Labs] Tooltip 2 #1438
Conversation
isModal -> hasBackdrop
Fix Popover 2 testsPreview: documentation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uncontrolled mode isn't working yet
that's strange; are you sure Popover2's uncontrolled mode works?
}; | ||
|
||
public render() { | ||
const { children, intent, tooltipClassName } = this.props; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing openOnTargetFocus
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we're spreading the rest props already, so that should be enough? I also added a defaultProps
field for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually according to @giladgray we don't even need it in defaultProps
because it's already in Popover2
and unchanged here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could do the following to avoid passing unsupported props?
const { children, intent, tooltipClassName, ...restProps } = this.props;
<Tooltip2 {...restProps} ... />
Yup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @llorca! A few loose ends.
* If false, it is attached to a new element appended to `<body>`. | ||
* @default false | ||
*/ | ||
inline?: boolean; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why add this? It comes from the extends
to share docs with other component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which extends
exactly? I didn't see any so I was super confused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extends IOverlayableProps
on the interface itself, line 30. please remove this prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@llorca yep, this prop is already available in the props interface due to the fact that IPopoverProps2 extends IOverlayableProps
. Note in overlay.tsx#L49
that IOverlayableProps
already includes inline?: boolean
, so we should delete this re-definition here.
@@ -255,12 +262,12 @@ export class Popover2 extends AbstractComponent<IPopover2Props, IPopover2State> | |||
const target = React.cloneElement(children.target, | |||
// force disable single Tooltip child when popover is open (BLUEPRINT-552) | |||
(isOpen && children.target.type === Tooltip) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for Tooltip2 here, disabled
doesn't exist on original Tooltip
openOnTargetFocus: true, | ||
placement: "auto", | ||
rootElementTag: "span", | ||
transitionDuration: 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please only set defaults for props that have different defaults than Popover2
. If they're the same then it's best to only set default in one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will remove. Was confused cause I didn't see where Popover2
extends the tooltip stuff.
packages/labs/src/labs.md
Outdated
@@ -165,6 +165,8 @@ This interface is generic, accepting a type parameter `<T>` for an item in the l | |||
- ...except for the handful of Tether-specific props, which are now Popper.js-specific: | |||
- 🔥 `position: Position` → `placement: PopperJS.Placement` | |||
- 🔥 `tetherOptions: ITetherOptions` → `modifiers: PopperJS.Modifiers` | |||
- 🔥 `isModal` → `hasBackdrop` | |||
- 🔥 `isDisabled` → `disabled` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't fit with the description of Tether-specific
@@ -223,3 +225,9 @@ Modifiers are the tool through which you customize Popper.js's behavior. It defi | |||
<div class="pt-callout pt-intent-primary pt-icon-info-sign"> | |||
To understand all the Popper.js modifiers available to you, you'll want to read [the Popper.js Modifiers documentation](https://popper.js.org/popper-documentation.html#modifiers). | |||
</div> | |||
|
|||
@## Tooltip 2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any docs? Anything? At least explain it's a thin wrapper to add css class and change some defaults
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add docs later, I want to get it working first
@@ -199,6 +199,12 @@ | |||
} | |||
} | |||
|
|||
.docs-tooltip2-example { | |||
> div { | |||
margin-bottom: $pt-grid-size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you put things in <p>
tags instead which already have margin bottom?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what it was before, had to change it because I was getting this error:
Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>. See ... SomeComponent > p > ... > SomeOtherComponent > ReactTooltip > div.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh sure that old thing
@@ -260,7 +260,7 @@ export class Popover2 extends AbstractComponent<IPopover2Props, IPopover2State> | |||
|
|||
const children = this.understandChildren(); | |||
const targetTabIndex = this.props.openOnTargetFocus && this.isHoverInteractionKind() ? 0 : undefined; | |||
const target = React.cloneElement(children.target, | |||
const target: JSX.Element = React.cloneElement(children.target, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary, otherwise we get:
error TS7022: 'target' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Error started showing up after changing Tooltip
to Tooltip2
below
Add type to target variablePreview: documentation |
Merge branch 'al/tooltip2' of github.com:palantir/blueprint into al/tooltip2Preview: documentation |
public static defaultProps: Partial<ITooltip2Props> = { | ||
hoverCloseDelay: 0, | ||
hoverOpenDelay: 100, | ||
isOpen: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ remove this default, that's why uncontrolled mode doesn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💀
packages/labs/src/labs.md
Outdated
- ...except for the handful of Tether-specific props, which are now Popper.js-specific: | ||
- all the classic `Popover` features are still supported, with the same names except... | ||
- 🔥 `isModal` → `hasBackdrop` | ||
- 🔥 `isDisabled` → `disabled` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inconsistent indentation, use two spaces here for minimal diff
/** | ||
* Whether or not the tooltip is visible. Passing this property will put the tooltip in | ||
* controlled mode, where the only way to change visibility is by updating this property. | ||
* @default undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this line, we don't declare undefined
defaults
|
||
/** | ||
* Whether or not the tooltip is visible. Passing this property will put the tooltip in | ||
* controlled mode, where the only way to change visibility is by updating this property. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"property" -> "prop"
}; | ||
|
||
public render() { | ||
const { children, intent, tooltipClassName } = this.props; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could do the following to avoid passing unsupported props?
const { children, intent, tooltipClassName, ...restProps } = this.props;
<Tooltip2 {...restProps} ... />
hoverCloseDelay: 0, | ||
hoverOpenDelay: 100, | ||
isOpen: false, | ||
openOnTargetFocus: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
: { tabIndex: targetTabIndex }, | ||
); | ||
|
||
const isContentEmpty = (children.content == null); | ||
if (isContentEmpty && !this.props.isDisabled && isOpen !== false && !Utils.isNodeEnv("production")) { | ||
if (isContentEmpty && !this.props.disabled && isOpen !== false && !Utils.isNodeEnv("production")) { | ||
console.warn("[Blueprint] Disabling <Popover> with empty/whitespace content..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Popover2
?
|
||
public static defaultProps: Partial<ITooltip2Props> = { | ||
hoverCloseDelay: 0, | ||
hoverOpenDelay: 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pull this out into a tooltipConstants.ts
file if it's the same as the hoverOpenDelay
in Tooltip
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why? This is used only for the tooltip component, so we'd have to delete that file anyway when we kill Tooltip
and rename Tooltip2
to Tooltip
in 2.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to ensure they behave identically / to not duplicate subtle values in two places. If we're sure not to export
said tooltipConstants.ts
file, should be fine.
hoverOpenDelay: 100, | ||
isOpen: false, | ||
openOnTargetFocus: true, | ||
transitionDuration: 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
Uncontrolled mode now workingPreview: documentation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looking good! Left questions. Now for the docs!
inheritDarkTheme?: boolean; | ||
inline?: boolean; | ||
interactionKind?: PopoverInteractionKind; | ||
isModal?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Motivation for hasBackdrop
vs isModal
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly consistency with Overlay
. Happy to change hasBackdrop
to something better later
* If false, it is attached to a new element appended to `<body>`. | ||
* @default false | ||
*/ | ||
inline?: boolean; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@llorca yep, this prop is already available in the props interface due to the fact that IPopoverProps2 extends IOverlayableProps
. Note in overlay.tsx#L49
that IOverlayableProps
already includes inline?: boolean
, so we should delete this re-definition here.
@@ -85,7 +93,7 @@ export interface IPopover2Props extends IOverlayableProps, IProps { | |||
* When modal popovers are opened, they become focused. | |||
* @default false | |||
*/ | |||
isModal?: boolean; | |||
hasBackdrop?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the description need to change if we're changing the prop name? (e.g. is it worth using the word "modal" anymore?)
(isOpen && children.target.type === Tooltip) | ||
? { isDisabled: true, tabIndex: targetTabIndex } | ||
(isOpen && children.target.type === Tooltip2) | ||
? { disabled: true, tabIndex: targetTabIndex } | ||
: { tabIndex: targetTabIndex }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe a little more concise like this?
const target: JSX.Element = React.cloneElement(children.target, {
// force disable single Tooltip child when popover is open (BLUEPRINT-552)
disabled: isOpen && children.target.type === Tooltip2 ? true : this.props.disabled,
tabIndex: targetTagIndex,
});
Fine as is though.
|
||
public static defaultProps: Partial<ITooltip2Props> = { | ||
hoverCloseDelay: 0, | ||
hoverOpenDelay: 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to ensure they behave identically / to not duplicate subtle values in two places. If we're sure not to export
said tooltipConstants.ts
file, should be fine.
* The content that will be displayed inside of the tooltip. | ||
*/ | ||
content: JSX.Element | string; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want defaultIsOpen
? And disabled
?
* @default 100 | ||
*/ | ||
hoverOpenDelay?: number; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want inheritDarkTheme
, inline
, or (for controlled mode) isOpen
?
* portal which holds the tooltip if `inline` is set to `false`. | ||
*/ | ||
portalClassName?: string; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want rootElementTag
?
Sorry about the confusion around which props to include or not, should be good to go now! |
Add more propsPreview: documentation |
Add some docsPreview: documentation | table |
packages/labs/src/labs.md
Outdated
@@ -228,6 +228,8 @@ Modifiers are the tool through which you customize Popper.js's behavior. It defi | |||
|
|||
@## Tooltip 2.0 | |||
|
|||
`Tooltip2` uses [`Popover2`](#labs.popover-2.0) under the hood. The public API is the same as [`Tooltip`](#core/components/tooltip), though note that the `isDisabled` prop has been renamed to `disabled`. Read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Can you kick text to a few different lines to achieve shorter line length in the markdown file?
- There's a trailing word,
Read
, that seems superfluous.
@llorca Needs tests, but everything else looks fine to me! EDIT: Apparently we don't need to write tests for |
Remove unnecessary wordPreview: documentation | table |
I believe all comments have been addressed.
Checklist
Changes proposed in this pull request:
Tooltip
2.0 based onPopover
2.0.