Commit ad8b9077 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Convert `AdderToolbar` to TypeScript

parent aaee569a
...@@ -6,22 +6,16 @@ import { ...@@ -6,22 +6,16 @@ import {
PointerDownIcon, PointerDownIcon,
PointerUpIcon, PointerUpIcon,
} from '@hypothesis/frontend-shared/lib/next'; } from '@hypothesis/frontend-shared/lib/next';
import type { IconComponent } from '@hypothesis/frontend-shared/lib/types';
import { useShortcut } from '../../shared/shortcut'; import { useShortcut } from '../../shared/shortcut';
/**
* @typedef {import('@hypothesis/frontend-shared/lib/types').IconComponent} IconComponent
*/
/** /**
* Render an inverted light-on-dark "pill" with the given `badgeCount` * Render an inverted light-on-dark "pill" with the given `badgeCount`
* (annotation count). This is rendered instead of an icon on the toolbar * (annotation count). This is rendered instead of an icon on the toolbar
* button for "show"-ing associated annotations for the current selection. * button for "show"-ing associated annotations for the current selection.
*
* @param {object} props
* @param {number} props.badgeCount
*/ */
function NumberIcon({ badgeCount }) { function NumberIcon({ badgeCount }: { badgeCount: number }) {
return ( return (
<span <span
className={classnames( className={classnames(
...@@ -39,11 +33,12 @@ function NumberIcon({ badgeCount }) { ...@@ -39,11 +33,12 @@ function NumberIcon({ badgeCount }) {
/** /**
* Render an arrow pointing up or down from the AdderToolbar. This arrow * Render an arrow pointing up or down from the AdderToolbar. This arrow
* should point roughly to the end of the user selection in the document. * should point roughly to the end of the user selection in the document.
*
* @param {object} props
* @param {'up'|'down'} props.arrowDirection
*/ */
function AdderToolbarArrow({ arrowDirection }) { function AdderToolbarArrow({
arrowDirection,
}: {
arrowDirection: 'up' | 'down';
}) {
return ( return (
<div <div
className={classnames( className={classnames(
...@@ -61,15 +56,21 @@ function AdderToolbarArrow({ arrowDirection }) { ...@@ -61,15 +56,21 @@ function AdderToolbarArrow({ arrowDirection }) {
); );
} }
/** type ToolbarButtonProps = {
* @param {object} props badgeCount?: number;
* @param {number} [props.badgeCount] icon?: IconComponent;
* @param {IconComponent} [props.icon] label: string;
* @param {string} props.label onClick: () => void;
* @param {() => void} props.onClick shortcut: string | null;
* @param {string|null} props.shortcut };
*/
function ToolbarButton({ badgeCount, icon: Icon, label, onClick, shortcut }) { function ToolbarButton({
badgeCount,
icon: Icon,
label,
onClick,
shortcut,
}: ToolbarButtonProps) {
useShortcut(shortcut, onClick); useShortcut(shortcut, onClick);
const title = shortcut ? `${label} (${shortcut})` : label; const title = shortcut ? `${label} (${shortcut})` : label;
...@@ -100,38 +101,72 @@ function ToolbarButton({ badgeCount, icon: Icon, label, onClick, shortcut }) { ...@@ -100,38 +101,72 @@ function ToolbarButton({ badgeCount, icon: Icon, label, onClick, shortcut }) {
); );
} }
/** export type Command = 'annotate' | 'highlight' | 'show' | 'hide';
* Union of possible toolbar commands.
*
* @typedef {'annotate'|'highlight'|'show'|'hide'} Command
*/
/** type AdderToolbarProps = {
* @typedef AdderToolbarProps /**
* @prop {'up'|'down'} arrowDirection - * Number of annotations associated with the selected text. If non-zero, a
* Whether the arrow pointing out of the toolbar towards the selected text * Show" button is displayed to allow the user to see the annotations that
* should appear above the toolbar pointing Up or below the toolbar pointing * correspond to the selection.
* Down. */
* @prop {boolean} isVisible - Whether to show the toolbar or not. annotationCount?: number;
* @prop {(c: Command) => void} onCommand - Called when a toolbar button is clicked. /**
* @prop {number} [annotationCount] - * Whether the arrow pointing out of the toolbar towards the selected text
* Number of annotations associated with the selected text. * should appear above the toolbar pointing up or below the toolbar pointing
* If non-zero, a "Show" button is displayed to allow the user to see the * down.
* annotations that correspond to the selection. */
*/ arrowDirection: 'up' | 'down';
/** The toolbar is always rendered, but is not always visible. */
isVisible: boolean;
/** Called when a toolbar button is clicked */
onCommand: (c: Command) => void;
};
/** /**
* The toolbar that is displayed above or below selected text in the document, * The toolbar that is displayed above or below selected text in the document,
* providing options to create annotations or highlights. * providing options to create annotations or highlights.
* *
<<<<<<< HEAD:src/annotator/components/AdderToolbar.js
* @param {AdderToolbarProps} props * @param {AdderToolbarProps} props
=======
* The toolbar has nuanced styling for hover. The component structure is:
*
* <AdderToolbar>
* <div.group>
* <button.hover-group><AnnotateIcon />Annotate</button>
* <button.hover-group><HighlightIcon />Highlight</button>
* <div>[vertical separator]</div>
* <button.hover-group><span><NumberIcon /></span>[count]</button>
* </div.group>
* <AdderToolbarArrow />
* </AdderToolbar>
*
* Behavior: When div.group is hovered, all descendant buttons and their
* contents dim, except for the contents of the button that is directly hovered,
* which are darkened. This is intended to make the hovered button stand out,
* and the non-hovered buttons recede.
*
* This is achieved by:
* - Setting the .group class on the div that contains the buttons. This allows
* buttons to style themselves based on the combination of the div.group's
* hover state and their own "local" hover state. `group` is available in
* Tailwind out of the box; see
* https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state
* - The challenge is in getting the "badge" in NumberIcon to dim and darken its
* background appropriately. `hover-group-hover` is a custom tailwind variant
* that allows NumberIcon to style itself based on the hover states of
* both div.group AND its parent button.hover-group. We need to ensure this
* badge will darken when its parent button is hovered, even if it is not
* hovered directly.
*
>>>>>>> 544c8e5c6 (Convert `AdderToolbar` to TypeScript):src/annotator/components/AdderToolbar.tsx
*/ */
export default function AdderToolbar({ export default function AdderToolbar({
arrowDirection, arrowDirection,
isVisible, isVisible,
onCommand, onCommand,
annotationCount = 0, annotationCount = 0,
}) { }: AdderToolbarProps) {
// Since the selection toolbar is only shown when there is a selection // Since the selection toolbar is only shown when there is a selection
// of static text, we can use a plain key without any modifier as // of static text, we can use a plain key without any modifier as
// the shortcut. This avoids conflicts with browser/OS shortcuts. // the shortcut. This avoids conflicts with browser/OS shortcuts.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment