|
|
|
@ -9,7 +9,7 @@ import {prepareForTransition} from 'app/client/ui/transitions';
|
|
|
|
|
import {testId, theme, vars} from 'app/client/ui2018/cssVars';
|
|
|
|
|
import {icon} from 'app/client/ui2018/icons';
|
|
|
|
|
import {menuCssClass} from 'app/client/ui2018/menus';
|
|
|
|
|
import { dom, DomContents, DomElementArg, DomElementMethod, IDomArgs, styled } from 'grainjs';
|
|
|
|
|
import {dom, DomContents, DomElementArg, DomElementMethod, styled} from 'grainjs';
|
|
|
|
|
import Popper from 'popper.js';
|
|
|
|
|
import {cssMenu, defaultMenuOptions, IMenuOptions, setPopupToCreateDom} from 'popweasel';
|
|
|
|
|
|
|
|
|
@ -240,59 +240,43 @@ export function tooltipCloseButton(ctl: ITooltipControl): HTMLElement {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders an icon that shows a tooltip with the specified `content` on click.
|
|
|
|
|
* Renders an info icon that shows a tooltip with the specified `content` on click.
|
|
|
|
|
*/
|
|
|
|
|
function iconTooltip(
|
|
|
|
|
cssStyledFunc: (...args: IDomArgs<HTMLElement>) => HTMLElement,
|
|
|
|
|
tooltipButtonContent: HTMLElement,
|
|
|
|
|
content: DomContents,
|
|
|
|
|
menuOptions?: IMenuOptions,
|
|
|
|
|
...domArgs: DomElementArg[]
|
|
|
|
|
) {
|
|
|
|
|
return cssStyledFunc(tooltipButtonContent, (elem) => {
|
|
|
|
|
setPopupToCreateDom(
|
|
|
|
|
elem,
|
|
|
|
|
(ctl) => {
|
|
|
|
|
return cssInfoTooltipPopup(
|
|
|
|
|
cssInfoTooltipPopupCloseButton(
|
|
|
|
|
icon("CrossSmall"),
|
|
|
|
|
dom.on("click", () => ctl.close()),
|
|
|
|
|
testId("info-tooltip-close")
|
|
|
|
|
),
|
|
|
|
|
cssInfoTooltipPopupBody(content, testId("info-tooltip-popup-body")),
|
|
|
|
|
dom.cls(menuCssClass),
|
|
|
|
|
dom.cls(cssMenu.className),
|
|
|
|
|
dom.onKeyDown({
|
|
|
|
|
Enter: () => ctl.close(),
|
|
|
|
|
Escape: () => ctl.close(),
|
|
|
|
|
}),
|
|
|
|
|
(popup) => {
|
|
|
|
|
setTimeout(() => popup.focus(), 0);
|
|
|
|
|
},
|
|
|
|
|
testId("info-tooltip-popup")
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
{ ...defaultMenuOptions, ...{ placement: "bottom-end" }, ...menuOptions }
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function questionMarkTooltip(content: DomContents, menuOptions?: IMenuOptions, ...domArgs: DomElementArg[]) {
|
|
|
|
|
return iconTooltip(
|
|
|
|
|
cssQuestionMarkTooltipButton,
|
|
|
|
|
cssQuestionMark('?', testId('info-tooltip'), ...domArgs),
|
|
|
|
|
content,
|
|
|
|
|
menuOptions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function infoTooltip(content: DomContents, menuOptions?: IMenuOptions, ...domArgs: DomElementArg[]) {
|
|
|
|
|
return iconTooltip(
|
|
|
|
|
cssInfoTooltipButton,
|
|
|
|
|
icon('Info', dom.cls('info_toggle_icon'), testId('info-tooltip'), ...domArgs),
|
|
|
|
|
content, menuOptions);
|
|
|
|
|
export function infoTooltip(content: DomContents, menuOptions?: IMenuOptions, ...domArgs: DomElementArg[]) {
|
|
|
|
|
return cssInfoTooltipButton('?',
|
|
|
|
|
(elem) => {
|
|
|
|
|
setPopupToCreateDom(
|
|
|
|
|
elem,
|
|
|
|
|
(ctl) => {
|
|
|
|
|
return cssInfoTooltipPopup(
|
|
|
|
|
cssInfoTooltipPopupCloseButton(
|
|
|
|
|
icon('CrossSmall'),
|
|
|
|
|
dom.on('click', () => ctl.close()),
|
|
|
|
|
testId('info-tooltip-close'),
|
|
|
|
|
),
|
|
|
|
|
cssInfoTooltipPopupBody(
|
|
|
|
|
content,
|
|
|
|
|
testId('info-tooltip-popup-body'),
|
|
|
|
|
),
|
|
|
|
|
dom.cls(menuCssClass),
|
|
|
|
|
dom.cls(cssMenu.className),
|
|
|
|
|
dom.onKeyDown({
|
|
|
|
|
Enter: () => ctl.close(),
|
|
|
|
|
Escape: () => ctl.close(),
|
|
|
|
|
}),
|
|
|
|
|
(popup) => { setTimeout(() => popup.focus(), 0); },
|
|
|
|
|
testId('info-tooltip-popup'),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
{...defaultMenuOptions, ...{placement: 'bottom-end'}, ...menuOptions},
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
testId('info-tooltip'),
|
|
|
|
|
...domArgs,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface WithIconTooltipOptions {
|
|
|
|
|
export interface WithInfoTooltipOptions {
|
|
|
|
|
domArgs?: DomElementArg[];
|
|
|
|
|
tooltipButtonDomArgs?: DomElementArg[];
|
|
|
|
|
tooltipMenuOptions?: IMenuOptions;
|
|
|
|
@ -312,37 +296,77 @@ export interface WithIconTooltipOptions {
|
|
|
|
|
*
|
|
|
|
|
* Usage:
|
|
|
|
|
*
|
|
|
|
|
* withQuestionMarkTooltip(
|
|
|
|
|
* withInfoTooltip(
|
|
|
|
|
* dom('div', 'Hello World!'),
|
|
|
|
|
* dom('p', 'This is some text to show inside the tooltip.'),
|
|
|
|
|
* )
|
|
|
|
|
*/
|
|
|
|
|
export function withQuestionMarkTooltip(
|
|
|
|
|
export function withInfoTooltip(
|
|
|
|
|
domContents: DomContents,
|
|
|
|
|
tooltipContent: DomContents,
|
|
|
|
|
options: WithIconTooltipOptions = {},
|
|
|
|
|
options: WithInfoTooltipOptions = {},
|
|
|
|
|
) {
|
|
|
|
|
const { domArgs, tooltipButtonDomArgs, tooltipMenuOptions } = options;
|
|
|
|
|
const {domArgs, tooltipButtonDomArgs, tooltipMenuOptions} = options;
|
|
|
|
|
return cssDomWithTooltip(
|
|
|
|
|
domContents,
|
|
|
|
|
questionMarkTooltip(tooltipContent, tooltipMenuOptions, tooltipButtonDomArgs),
|
|
|
|
|
infoTooltip(tooltipContent, tooltipMenuOptions, tooltipButtonDomArgs),
|
|
|
|
|
...(domArgs ?? [])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function withInfoTooltip(
|
|
|
|
|
domContents: DomContents,
|
|
|
|
|
tooltipContent: DomContents,
|
|
|
|
|
options: WithIconTooltipOptions = {},
|
|
|
|
|
) {
|
|
|
|
|
const { domArgs, tooltipButtonDomArgs, tooltipMenuOptions } = options;
|
|
|
|
|
return cssDomWithTooltip(
|
|
|
|
|
domContents,
|
|
|
|
|
infoTooltip(tooltipContent, tooltipMenuOptions, tooltipButtonDomArgs),
|
|
|
|
|
...(domArgs ?? [])
|
|
|
|
|
/**
|
|
|
|
|
* Renders an column info icon that shows a tooltip with the specified `content` on click.
|
|
|
|
|
*/
|
|
|
|
|
export function columnInfoTooltip(content: DomContents, menuOptions?: IMenuOptions, ...domArgs: DomElementArg[]) {
|
|
|
|
|
return cssColumnInfoTooltipButton(
|
|
|
|
|
icon('Info', dom.cls("info_toggle_icon")),
|
|
|
|
|
(elem) => {
|
|
|
|
|
setPopupToCreateDom(
|
|
|
|
|
elem,
|
|
|
|
|
(ctl) => {
|
|
|
|
|
return cssInfoTooltipPopup(
|
|
|
|
|
cssInfoTooltipPopupCloseButton(
|
|
|
|
|
icon('CrossSmall'),
|
|
|
|
|
dom.on('click', () => ctl.close()),
|
|
|
|
|
testId('column-info-tooltip-close'),
|
|
|
|
|
),
|
|
|
|
|
cssInfoTooltipPopupBody(
|
|
|
|
|
content,
|
|
|
|
|
testId('column-info-tooltip-popup-body'),
|
|
|
|
|
),
|
|
|
|
|
dom.cls(menuCssClass),
|
|
|
|
|
dom.cls(cssMenu.className),
|
|
|
|
|
dom.onKeyDown({
|
|
|
|
|
Enter: () => ctl.close(),
|
|
|
|
|
Escape: () => ctl.close(),
|
|
|
|
|
}),
|
|
|
|
|
(popup) => { setTimeout(() => popup.focus(), 0); },
|
|
|
|
|
testId('column-info-tooltip-popup'),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
{ ...defaultMenuOptions, ...{ placement: 'bottom-end' }, ...menuOptions },
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
testId('column-info-tooltip'),
|
|
|
|
|
...domArgs,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cssColumnInfoTooltipButton = styled('div', `
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
--icon-color: ${theme.infoButtonFg};
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
margin-left: 5px;
|
|
|
|
|
&:hover {
|
|
|
|
|
--icon-color: ${theme.infoButtonHoverFg};
|
|
|
|
|
}
|
|
|
|
|
&:active {
|
|
|
|
|
--icon-color: ${theme.infoButtonActiveFg};
|
|
|
|
|
}
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const cssTooltip = styled('div', `
|
|
|
|
|
position: absolute;
|
|
|
|
|
z-index: 5000; /* should be higher than a modal */
|
|
|
|
@ -376,7 +400,7 @@ const cssTooltipCloseButton = styled('div', `
|
|
|
|
|
}
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
const cssQuestionMark = styled('div', `
|
|
|
|
|
const cssInfoTooltipButton = styled('div', `
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
@ -395,25 +419,6 @@ const cssQuestionMark = styled('div', `
|
|
|
|
|
}
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
const cssQuestionMarkTooltipButton = styled('div', `
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
const cssInfoTooltipButton = styled('div', `
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
--icon-color: ${theme.infoButtonFg};
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
&:hover {
|
|
|
|
|
--icon-color: ${theme.infoButtonHoverFg};
|
|
|
|
|
}
|
|
|
|
|
&:active {
|
|
|
|
|
--icon-color: ${theme.infoButtonActiveFg};
|
|
|
|
|
}
|
|
|
|
|
& > .info_toggle_icon {
|
|
|
|
|
display: block; /* don't create a line */
|
|
|
|
|
}
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
const cssInfoTooltipPopup = styled('div', `
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|