Skip to content

Commit

Permalink
Merge pull request #3002 from specify/tooltips
Browse files Browse the repository at this point in the history
Use a tooltips library
  • Loading branch information
maxpatiiuk authored Feb 22, 2023
2 parents f7837ff + 372fd4c commit 3f856e1
Show file tree
Hide file tree
Showing 33 changed files with 686 additions and 94 deletions.
18 changes: 3 additions & 15 deletions specifyweb/frontend/js_src/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
textarea,
.textarea-shadow,
select {
@apply p-1 rounded accent-brand-200 dark:accent-brand-400 ring-gray-400 shadow-sm
ring-1 dark:ring-0 border-none bg-[color:var(--field-background)]
text-[length:inherit] leading-[unset]
@apply rounded border-none bg-[color:var(--field-background)] p-1 text-[length:inherit] leading-[unset]
accent-brand-200 shadow-sm ring-1 ring-gray-400
dark:accent-brand-400 dark:ring-0
[.has-alt-background_&]:optional:bg-white
dark:[.has-alt-background_&]:optional:bg-neutral-900;
}
Expand Down Expand Up @@ -197,18 +197,6 @@
@apply rounded bg-brand-200 dark:bg-brand-400;
}

/* Display tooltips as an overlay on touch-screen devices */
@media (pointer: coarse), (hover: none) {
[title] {
@apply relative inline-flex justify-center;
}

[title]:focus::after {
@apply absolute top-[90%] w-fit border border-black bg-white p-1
text-black content-[attr(title)];
}
}

/*
* Grid-based table implementation for increased flexibility
* Does not sacrifice accessibility thanks to the [role] attributes
Expand Down
5 changes: 1 addition & 4 deletions specifyweb/frontend/js_src/lib/components/Atoms/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ const button = (name: string, className: string) =>
type: 'button',
disabled: props.disabled === true || props.onClick === undefined,
}));
/*
* FEATURE: if onClick===undefined, button should be disabled, but only if expicily
* provided
*/

export const Button = {
/*
* When using Button.LikeLink component, consider adding [role="link"] if the
Expand Down
4 changes: 4 additions & 0 deletions specifyweb/frontend/js_src/lib/components/Atoms/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ export const Key = wrap(
'kbd',
'bg-gray-200 border-1 dark:border-none dark:bg-neutral-700 rounded-sm mx-1 p-0.5'
);

export const oneRem = Number.parseFloat(
getComputedStyle(document.documentElement).fontSize
);
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export function AttachmentCell({
(model === undefined || hasTablePermission(model.name, 'read')) && (
<Button.LikeLink
className="absolute top-0 left-0"
title={model?.label}
onClick={(): void =>
model === undefined
? handleMetaToggle()
Expand Down
2 changes: 2 additions & 0 deletions specifyweb/frontend/js_src/lib/components/Core/Contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { crash } from '../Errors/Crash';
import { ErrorBoundary } from '../Errors/ErrorBoundary';
import { loadingBar } from '../Molecules';
import { Dialog, dialogClassNames, LoadingScreen } from '../Molecules/Dialog';
import { TooltipManager } from '../Molecules/Tooltips';
import {
SetUnloadProtectsContext,
UnloadProtectsContext,
Expand Down Expand Up @@ -128,6 +129,7 @@ export function Contexts({
{children}
</React.Suspense>
</LoadingContext.Provider>
<TooltipManager />
</ErrorContext.Provider>
</ErrorBoundary>
</SetUnloadProtectsContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ const domainLevels = [
] as const;

/*
* REFACTOR: separate schema base (domain.json) from the rest of the schema
* Scoping information is loaded and populated here.
*/
export const fetchContext = load<
Expand Down
1 change: 0 additions & 1 deletion specifyweb/frontend/js_src/lib/components/Errors/Crash.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { formatError, handleAjaxError } from './FormatError';
export const raise = (error: Error, ...args: RA<unknown>): void =>
showError(error, true, ...args);

// FEATURE: softFail errors should be displayed in the UI as toasts
export const softFail =
process.env.NODE_ENV === 'development' ? raise : console.error;

Expand Down
44 changes: 20 additions & 24 deletions specifyweb/frontend/js_src/lib/components/Errors/JsonError.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import React from 'react';

import { backEndText } from '../../localization/backEnd';
import { preferencesText } from '../../localization/preferences';
import { jsonStringify } from '../../utils/utils';
import { className } from '../Atoms/className';
import { TableIcon } from '../Molecules/TableIcon';
import { schema } from '../DataModel/schema';
import { getField } from '../DataModel/helpers';
import { schema } from '../DataModel/schema';
import { TableIcon } from '../Molecules/TableIcon';

type JsonResponse = {
exception: string;
message: string;
data: any;
formattedData: string;
traceback: string;
readonly exception: string;
readonly message: string;
readonly data: any;
readonly formattedData: string;
readonly traceback: string;
};

function createJsonResponse(error: string): JsonResponse {
const json = JSON.parse(error);
const hasLocalizationKey = typeof json.data?.localizationKey === 'string';
const jsonResponse = {
return {
exception: json.exception,
message: hasLocalizationKey
? resolveBackendLocalization(json)
Expand All @@ -27,7 +28,6 @@ function createJsonResponse(error: string): JsonResponse {
formattedData: jsonStringify(json.data, 2),
traceback: json.traceback,
};
return jsonResponse;
}

export function formatJsonBackendResponse(error: string): JSX.Element {
Expand All @@ -54,7 +54,7 @@ function JsonBackendResponseFooter({
readonly response: JsonResponse;
readonly isDataOpen?: boolean;
}): JSX.Element {
const hasData = response.data == null ? false : true;
const hasData = response.data != null;
return (
<>
{hasData && (
Expand Down Expand Up @@ -84,14 +84,12 @@ function BusinessRuleExceptionHeader({
}): JSX.Element {
return (
<>
<div className={`flex space-x-2`}>
<TableIcon name={table} label={false} />
<div className="flex space-x-2">
<TableIcon label={false} name={table} />
<h2 className={className.headerPrimary}>{exception}</h2>
</div>
<div className={`flex space-x-2`}>
<em className={className.label} title={message}>
{message}
</em>
<div className="flex space-x-2">
<em className={className.label}>{message}</em>
</div>
</>
);
Expand All @@ -105,10 +103,8 @@ function formatBasicResponse(error: string): JSX.Element {
return (
<>
<h2 className={className.headerPrimary}>{response.exception}</h2>
<em className={className.label} title={response.message}>
{response.message}
</em>
<JsonBackendResponseFooter isDataOpen={true} response={response} />
<em className={className.label}>{response.message}</em>
<JsonBackendResponseFooter isDataOpen response={response} />
</>
);
}
Expand All @@ -118,8 +114,8 @@ function formatBusinessRuleException(error: string): JSX.Element {
const table: string = response.data.table;
return (
<>
<BusinessRuleExceptionHeader table={table} response={response} />
<JsonBackendResponseFooter response={response} isDataOpen={true} />
<BusinessRuleExceptionHeader response={response} table={table} />
<JsonBackendResponseFooter isDataOpen response={response} />
</>
);
}
Expand All @@ -136,8 +132,8 @@ function formatTreeBusinessRuleException(error: string): JSX.Element {
const table: string = response.data.tree;
return (
<>
<BusinessRuleExceptionHeader table={table} response={response} />
<JsonBackendResponseFooter response={response} isDataOpen={true} />
<BusinessRuleExceptionHeader response={response} table={table} />
<JsonBackendResponseFooter isDataOpen response={response} />
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ const fieldRenderers: {
},
Plugin: FormPlugin,
FilePicker({ id, mode, name, isRequired }) {
// FEATURE: consider replacing this with AttachmentsPlugin for some field names
/*
* Not sure how this is supposed to work, thus the field is rendered as
* disabled
Expand Down
5 changes: 4 additions & 1 deletion specifyweb/frontend/js_src/lib/components/FormParse/cells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,10 @@ export function parseFormCell(
const cellClass = getParsedAttribute(cellNode, 'type') ?? '';
const cellType = cellTypeTranslation[cellClass.toLowerCase()];

// FEATURE: warn on IDs that include spaces and other unsupported characters
/*
* FEATURE: warn on IDs that include spaces and other unsupported characters.
* See https://github.com/specify/specify7/issues/2871
*/
const id = getParsedAttribute(cellNode, 'id');
setLogContext({ id, type: cellType });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ export function LatLongUi({
disabled={mode === 'view'}
id={id}
name="type"
title={localityText.coordinateType()}
value={coordinateType}
onValueChange={(value): void => {
setCoordinateType(value as CoordinateType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@ export function PartialDateUi<SCHEMA extends AnySchema>({
<span className="sr-only">{formsText.datePrecision()}</span>
<Select
className="!w-auto print:hidden"
title={formsText.datePrecision()}
value={precision}
onBlur={(): void => {
if (moment === undefined) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,16 @@ export function Notifications({
icon={icons.bell}
isActive={isOpen}
isCollapsed={isCollapsed}
title={title}
onClick={handleOpen}
props={{
'aria-live': 'polite',
className:
unreadCount > 0
unreadCount > 0 && !isOpen
? '[&:not(:hover)]:!text-brand-300 [&:not(:hover)]:dark:!text-brand-400'
: undefined,
disabled: notificationCount === 0,
}}
title={title}
onClick={handleOpen}
/>
{Array.isArray(notifications) ? (
<Dialog
Expand Down
5 changes: 5 additions & 0 deletions specifyweb/frontend/js_src/lib/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { MenuItem } from '../Core/Main';
import { MenuContext } from '../Core/Main';
import { schema } from '../DataModel/schema';
import { userInformation } from '../InitialContext/userInformation';
import { titleDelay, titlePosition } from '../Molecules/Tooltips';
import { ActiveLink } from '../Router/ActiveLink';
import { usePref } from '../UserPreferences/usePref';
import type { MenuItemName } from './menuItemDefinitions';
Expand Down Expand Up @@ -219,6 +220,7 @@ export function MenuButton({
readonly onClick: string | (() => void);
readonly props?: TagProps<'a'> & TagProps<'button'>;
}): JSX.Element | null {
const [position] = usePref('header', 'appearance', 'position');
const getClassName = (isActive: boolean): string => `
p-4
${isActive ? 'bg-brand-300 !text-white' : 'text-gray-700'}
Expand All @@ -227,6 +229,9 @@ export function MenuButton({
`;
const props = {
...extraProps,
[titleDelay]: 0,
[titlePosition]:
position === 'left' ? 'right' : position === 'right' ? 'left' : undefined,
'aria-current': isActive ? 'page' : undefined,
title: isCollapsed ? title : undefined,
} as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ const treeScopes = {
/* eslint-enable @typescript-eslint/naming-convention */
} as const;

// FEATURE: allow reordering trees
/*
* FEATURE: allow reordering trees
* See https://github.com/specify/specify7/issues/2121#issuecomment-1432158152
*/
const commonTrees = ['Geography', 'Storage', 'Taxon'] as const;
const treesForPaleo = ['GeologicTimePeriod', 'LithoStrat'] as const;
const allTrees = [...commonTrees, ...treesForPaleo] as const;
Expand Down
5 changes: 4 additions & 1 deletion specifyweb/frontend/js_src/lib/components/Leaflet/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ export type LocalityPinFields = {
*/
export const MAX_TO_MANY_INDEX = 10;

// FEATURE: allow configuring this
/*
* FEATURE: allow configuring this
* See https://github.com/specify/specify7/issues/2431
*/
/**
* NOTE:
* Leaflet map on the Locality form and the CO Lifemapper badge is going
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,21 @@ export const supportsBackdropBlur = globalThis.CSS.supports(

/**
* Modal or non-modal dialog. Highly customizable. Used all over the place
*
* @remarks
* We are using a library "react-modal" to render dialogs. It worked great so
* far. However, since then we started using HeadlessUI and FloatingUI, both
* of which already provide dialogs. Might be worth at some point to migrate
* to reduce number of dependencies
*
* @remarks
* Note, if the same components renders a <Dialog>, and on the next render
* instead renders a different <Dialog> with the same parent, React would
* reuse the same <Dialog> instance. This means, if content was scrolled down,
* new dialog, with a different content would already be scrolled down.
* Possible solution would be to set container.scrollTop=0 on header change,
* though, that may introduce issues in other places, as same dialogs change
* header durring lifecycle (ResourceView)
* header during lifecycle (ResourceView)
*/
export function Dialog({
/*
Expand Down
Loading

0 comments on commit 3f856e1

Please sign in to comment.