(core) Add info and hover tooltips

Summary:
Adds tooltip buttons to various parts of the UI that either open a popup with
information when clicked, or show a label on hover.

Test Plan: Project tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3657
This commit is contained in:
George Gevoian
2022-10-19 16:06:05 -07:00
parent acc218398d
commit 4c662253a9
16 changed files with 435 additions and 134 deletions

View File

@@ -1,7 +1,8 @@
import {DocPageModel} from 'app/client/models/DocPageModel';
import {urlState} from 'app/client/models/gristUrlState';
import {docListHeader} from 'app/client/ui/DocMenuCss';
import {infoTooltip} from 'app/client/ui/tooltips';
import {GristTooltips, TooltipContentFunc} from 'app/client/ui/GristTooltips';
import {withInfoTooltip} from 'app/client/ui/tooltips';
import {mediaXSmall, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {loadingDots, loadingSpinner} from 'app/client/ui2018/loaders';
@@ -79,10 +80,7 @@ export class DocumentUsage extends Disposable {
maximumValue: maxValue ?? DEFAULT_MAX_DATA_SIZE,
unit: 'MB',
shouldHideLimits: maxValue === undefined,
tooltipContent: () => cssTooltipBody(
dom('div', 'The total size of all data in this document, excluding attachments.'),
dom('div', 'Updates every 5 minutes.'),
),
tooltipContentFunc: GristTooltips.dataSize,
formatValue: (val) => {
// To display a nice, round number for `maximumValue`, we first convert
// to KiBs (base-2), and then convert to MBs (base-10). Normally, we wouldn't
@@ -269,7 +267,7 @@ interface MetricOptions {
// If true, limits will always be hidden, even if `maximumValue` is a positive number.
shouldHideLimits?: boolean;
// Shows an icon next to the metric name that displays a tooltip on hover.
tooltipContent?(): DomContents;
tooltipContentFunc?: TooltipContentFunc;
formatValue?(value: number): string;
}
@@ -279,11 +277,15 @@ interface MetricOptions {
* close `currentValue` is to hitting `maximumValue`.
*/
function buildUsageMetric(options: MetricOptions, ...domArgs: DomElementArg[]) {
const {name, tooltipContent} = options;
const {name, tooltipContentFunc} = options;
return cssUsageMetric(
cssMetricName(
cssOverflowableText(name, testId('name')),
tooltipContent ? infoTooltip(tooltipContent()) : null,
tooltipContentFunc
? withInfoTooltip(
cssOverflowableText(name, testId('name')),
tooltipContentFunc()
)
: cssOverflowableText(name, testId('name')),
),
buildUsageProgressBar(options),
...domArgs,
@@ -425,12 +427,6 @@ const cssSpinner = styled('div', `
margin-top: 32px;
`);
const cssTooltipBody = styled('div', `
display: flex;
flex-direction: column;
gap: 8px;
`);
const cssLoadingDots = styled(loadingDots, `
--dot-size: 8px;
`);

View File

@@ -134,15 +134,26 @@ Command.prototype._run = function() {
return this._activeFunc.apply(null, arguments);
};
/**
* Returns a comma-separated string of all keyboard shortcuts, or `null` if no
* shortcuts exist.
*/
Command.prototype.getKeysDesc = function() {
if (this.humanKeys.length === 0) { return null; }
return `(${this.humanKeys.join(', ')})`;
};
/**
* Returns the text description for the command, including the keyboard shortcuts.
*/
Command.prototype.getDesc = function() {
var desc = this.desc;
if (this.humanKeys.length) {
desc += " (" + this.humanKeys.join(", ") + ")";
}
return desc;
var parts = [this.desc];
var keysDesc = this.getKeysDesc();
if (keysDesc) { parts.push(keysDesc); }
return parts.join(' ');
};
/**