-
Notifications
You must be signed in to change notification settings - Fork 198
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
Update AdderToolbar components and styling #4753
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,18 @@ | ||
import classnames from 'classnames'; | ||
import { LabeledButton, Icon } from '@hypothesis/frontend-shared'; | ||
import { | ||
AnnotateIcon, | ||
ButtonBase, | ||
HighlightIcon, | ||
PointerDownIcon, | ||
PointerUpIcon, | ||
} from '@hypothesis/frontend-shared/lib/next'; | ||
|
||
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` | ||
* (annotation count). This is rendered instead of an icon on the toolbar | ||
|
@@ -16,11 +26,12 @@ function NumberIcon({ badgeCount }) { | |
<span | ||
className={classnames( | ||
'rounded px-1 py-0.5', | ||
'text-color-text-inverted font-bold bg-grey-7', | ||
'dim-bg' | ||
// The background color is inherited from the current text color in | ||
// the containing button and will vary depending on hover state. | ||
'bg-current' | ||
)} | ||
> | ||
{badgeCount} | ||
<span className="font-bold text-color-text-inverted">{badgeCount}</span> | ||
</span> | ||
); | ||
} | ||
|
@@ -34,55 +45,58 @@ function NumberIcon({ badgeCount }) { | |
*/ | ||
function AdderToolbarArrow({ arrowDirection }) { | ||
return ( | ||
<Icon | ||
name="pointer" | ||
classes={classnames( | ||
// Position the arrow in the horizontal center at the bottom of the | ||
// container (toolbar). Note: the arrow is pointing up at this point. | ||
'absolute left-1/2 -translate-x-1/2', | ||
// Override `1em` width/height rules in `Icon` to size the arrow as | ||
// its SVG dimensions dictate | ||
'h-auto w-auto z-2', | ||
'text-grey-3 fill-white', | ||
<div | ||
className={classnames( | ||
// Position horizontally center of the AdderToolbar | ||
'absolute left-1/2 -translate-x-1/2 z-2', | ||
'fill-white text-grey-3', | ||
{ | ||
// Down arrow: transform to point the arrow down | ||
'rotate-180': arrowDirection === 'down', | ||
// Up arrow: position vertically above the toolbar | ||
// Move the pointer to the top of the AdderToolbar | ||
'top-0 -translate-y-full': arrowDirection === 'up', | ||
} | ||
)} | ||
/> | ||
> | ||
{arrowDirection === 'up' ? <PointerUpIcon /> : <PointerDownIcon />} | ||
</div> | ||
); | ||
} | ||
|
||
/** | ||
* @param {object} props | ||
* @param {number} [props.badgeCount] | ||
* @param {string} [props.icon] | ||
* @param {IconComponent} [props.icon] | ||
* @param {string} props.label | ||
* @param {() => void} props.onClick | ||
* @param {string|null} props.shortcut | ||
*/ | ||
function ToolbarButton({ badgeCount, icon, label, onClick, shortcut }) { | ||
function ToolbarButton({ badgeCount, icon: Icon, label, onClick, shortcut }) { | ||
useShortcut(shortcut, onClick); | ||
|
||
const title = shortcut ? `${label} (${shortcut})` : label; | ||
|
||
return ( | ||
<LabeledButton | ||
className={classnames( | ||
'flex flex-col gap-y-1 items-center py-2.5 px-2', | ||
'text-annotator-sm leading-none text-grey-7', | ||
'transition-colors duration-200', | ||
'dim-item' | ||
<ButtonBase | ||
classes={classnames( | ||
'flex-col gap-y-1 py-2.5 px-2', | ||
'text-annotator-sm leading-none', | ||
// Default color when the toolbar is not hovered | ||
'text-grey-7', | ||
// When the parent .group element is hovered (but this element itself is | ||
// not), dim this button's text. This has the effect of dimming inactive | ||
// buttons. | ||
'group-hover:text-grey-5', | ||
// When the parent .group element is hovered AND this element is | ||
// hovered, this is the "active" button. Intensify the text color, which | ||
// will also darken any descendant Icon | ||
'hover:group-hover:text-grey-9' | ||
)} | ||
onClick={onClick} | ||
title={title} | ||
> | ||
{icon && <Icon classes="text-annotator-lg" name={icon} title={title} />} | ||
{Icon && <Icon className="text-annotator-lg" title={title} />} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least |
||
{typeof badgeCount === 'number' && <NumberIcon badgeCount={badgeCount} />} | ||
<span className="font-normal">{label}</span> | ||
</LabeledButton> | ||
<span>{label}</span> | ||
</ButtonBase> | ||
); | ||
} | ||
|
||
|
@@ -135,33 +149,43 @@ export default function AdderToolbar({ | |
return ( | ||
<div | ||
className={classnames( | ||
'AdderToolbar', | ||
'absolute select-none bg-white rounded shadow-adder-toolbar', | ||
// Because `.AdderToolbar` rules reset `all:initial`, we cannot use | ||
// default border values from Tailwind and have to be explicit about | ||
// all border attributes | ||
// Reset all inherited properties to their initial values. This prevents | ||
// CSS property values from the host page being inherited by elements of | ||
// the Adder, even when using Shadow DOM. | ||
'all-initial', | ||
// As we've reset all properties to initial values, we cannot rely on | ||
// default border values from Tailwind and have to be explicit about all | ||
// border attributes. | ||
'border border-solid border-grey-3', | ||
'absolute select-none bg-white rounded shadow-adder-toolbar', | ||
// Start at a very low opacity as we're going to fade in in the animation | ||
'opacity-5', | ||
{ | ||
'animate-adder-pop-up': arrowDirection === 'up' && isVisible, | ||
'animate-adder-pop-down': arrowDirection === 'down' && isVisible, | ||
} | ||
)} | ||
data-component="AdderToolbar" | ||
dir="ltr" | ||
style={{ | ||
visibility: isVisible ? 'visible' : 'hidden', | ||
}} | ||
> | ||
<div className="flex dim-items-on-hover"> | ||
<div | ||
className={classnames( | ||
// This group is used to manage hover state styling for descendant | ||
// buttons | ||
'flex group' | ||
)} | ||
> | ||
<ToolbarButton | ||
icon="annotate" | ||
icon={AnnotateIcon} | ||
onClick={() => onCommand('annotate')} | ||
label="Annotate" | ||
shortcut={annotateShortcut} | ||
/> | ||
<ToolbarButton | ||
icon="highlight" | ||
icon={HighlightIcon} | ||
onClick={() => onCommand('highlight')} | ||
label="Highlight" | ||
shortcut={highlightShortcut} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1110,10 +1110,10 @@ | |
fancy-log "^1.3.3" | ||
glob "^7.2.0" | ||
|
||
"@hypothesis/[email protected].0": | ||
version "5.4.0" | ||
resolved "https://registry.yarnpkg.com/@hypothesis/frontend-shared/-/frontend-shared-5.4.0.tgz#60b10bf5d576879176c0355dad883b465d43714d" | ||
integrity sha512-GROm1HUzEto84Mwlix2pUoZfQNLPhqKIn+Y6d1gnwjvDUU2YxUOm+TWYtqmIRCEtEAb5jnm/VUsRJ7DdI8mYlg== | ||
"@hypothesis/[email protected].1": | ||
version "5.4.1" | ||
resolved "https://registry.yarnpkg.com/@hypothesis/frontend-shared/-/frontend-shared-5.4.1.tgz#c0a6ce5c6e8ef9bc5ed5985d57c2bd1ec5f04c2a" | ||
integrity sha512-tM+pypWahpMf2x4tarbhsmw+dQluJUZv8o9CqquVS3FtUucPZ6OJn3Rml6fWMZ0k3DVrDoRMS19VONjtig27Hw== | ||
dependencies: | ||
highlight.js "^11.6.0" | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Here's an example of me adding an additional parent component to handle the positioning, and not applying that styling directly to the icon component. This is less of a real concern with icons, which have no classes applied to them other than what you set on
className
, but it's more hygienic IMHO.