From 649d33508d925f35ec1377bdd6bed099f2455b2b Mon Sep 17 00:00:00 2001 From: Sandy Chu Date: Mon, 29 Jun 2026 09:25:34 -0700 Subject: [PATCH 1/3] Change context menu to horizontal layout --- package-lock.json | 1 + package.json | 1 + src/css/_TextSelection.scss | 11 +++---- src/util/TextSelectionManager.js | 53 ++++++++++++++++++++++++++++---- 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index ada7fa362..ed46a323e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@internetarchive/icon-close": "1.4.1", "@internetarchive/icon-dl": "1.4.1", "@internetarchive/icon-edit-pencil": "1.4.1", + "@internetarchive/icon-ellipses": "1.4.1", "@internetarchive/icon-ia-logo": "1.4.1", "@internetarchive/icon-magnify-minus": "1.4.1", "@internetarchive/icon-magnify-plus": "1.4.1", diff --git a/package.json b/package.json index c22b3c459..2d417cae8 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@internetarchive/icon-close": "1.4.1", "@internetarchive/icon-dl": "1.4.1", "@internetarchive/icon-edit-pencil": "1.4.1", + "@internetarchive/icon-ellipses": "1.4.1", "@internetarchive/icon-ia-logo": "1.4.1", "@internetarchive/icon-magnify-minus": "1.4.1", "@internetarchive/icon-magnify-plus": "1.4.1", diff --git a/src/css/_TextSelection.scss b/src/css/_TextSelection.scss index 2fb888ae5..6a78f9f8e 100644 --- a/src/css/_TextSelection.scss +++ b/src/css/_TextSelection.scss @@ -148,13 +148,14 @@ .br-select-menu__root { display: none; border-radius: 20px; - background-color: #333; +// background-color: #333; color: white; color-scheme: dark; padding: 2px; overflow: hidden; opacity: 1; transition: border-radius 0.2s, opacity 0.2s; + gap: 10px; @starting-style { opacity: 0; @@ -179,7 +180,7 @@ background: transparent; display: flex; align-items: center; - border-radius: 20px; + border-radius: 12px; font-family: inherit; color: inherit; border: 0; @@ -187,10 +188,7 @@ cursor: pointer; text-wrap: nowrap; padding: 4px; -} - -.br-select-menu__option:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: #333; } .br-select-menu__icon { @@ -198,6 +196,7 @@ flex-shrink: 0; width: 17px; height: 17px; + padding: 3px; } .br-select-menu__label { diff --git a/src/util/TextSelectionManager.js b/src/util/TextSelectionManager.js index 2ae2fe983..f4d0b30eb 100644 --- a/src/util/TextSelectionManager.js +++ b/src/util/TextSelectionManager.js @@ -7,6 +7,7 @@ import { customElement, property, query } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import '@internetarchive/icon-share'; import '@internetarchive/icon-edit-pencil/icon-edit-pencil.js'; +import '@internetarchive/icon-ellipses'; import { isIOS, isAndroid } from './browserSniffing.js'; import { genAt, genFilter } from './generators.js'; @@ -412,6 +413,9 @@ export class BRSelectMenuOption extends LitElement { if (this.icon === 'edit-pencil') { return html``; } + if (this.icon === 'ellipses') { + return html``; + } return ''; } @@ -459,6 +463,9 @@ class BRSelectMenu extends LitElement { /** @type {import('../BookReader.js').default} */ br; + /** @type {boolean} */ + showExtendedOptions = false; + /** @type {BRSelectMenuOption | null} */ @query('#copy-link-option') copyLinkOption; @@ -525,7 +532,7 @@ class BRSelectMenu extends LitElement { @mousedown=${/** @param {MouseEvent} e */ (e) => e.preventDefault()} @click=${this.handleCopyLinkToHighlight} icon="share" - label="Copy Link to Highlight" + label="Share" live-label > `; @@ -560,6 +567,19 @@ class BRSelectMenu extends LitElement { > `; } + + renderSwitchOptions() { + return html` + e.preventDefault()} + @click=${this.changeOptions} + icon="ellipses" + live-label + > + `; + } + renderLocalStorageOptions() { return html` `; } - render() { - // TODO change the second button to use a different icon + renderDefaultOptions() { return html` - ${this.copyLinkToHighlightEnabled ? this.renderCopyLinkToHighlightOption() : ''} + ${this.copyLinkToHighlightEnabled ? this.renderCopyLinkToHighlightOption() : ''} ${this.highlightAnnotationEnabled && !this.nodesForRemoval ? this.renderHighlightOption() : ''} - ${this.highlightAnnotationEnabled ? this.renderLocalStorageOptions() : ''} ${this.nodesForRemoval ? this.renderRemoveOption() : ''} `; } + renderExtendedOptions() { + return html` + ${this.renderLocalStorageOptions()} + `; + } + + render() { + // TODO change the second button to use a different icon + return html` + ${this.showExtendedOptions ? this.renderExtendedOptions() : this.renderDefaultOptions()} + ${this.renderSwitchOptions()} + `; + } + /** * @param {MouseEvent} e */ @@ -615,6 +647,15 @@ class BRSelectMenu extends LitElement { this.copyLinkOption?.showTemporaryText('Copied!'); } + /** + * @param {MouseEvent} e + */ + changeOptions(e) { + e.preventDefault(); + this.showExtendedOptions = !this.showExtendedOptions; + this.requestUpdate(); + } + /** * Returns the closest BRtextLayer element on the page that contains the target node * @param {Node} node @@ -766,7 +807,7 @@ class BRSelectMenu extends LitElement { this.style.zIndex = '1'; this.style.position = 'absolute'; - this.style.display = 'block'; + this.style.display = 'flex'; this.open = true; this.classList.remove('br-select-menu__root--scrolling'); window.removeEventListener('scroll', this._onScroll, { capture: true }); From 3333e312730b81bc8d45cf2104609fec980a95d8 Mon Sep 17 00:00:00 2001 From: Sandy Chu Date: Mon, 13 Jul 2026 13:25:52 -0700 Subject: [PATCH 2/3] Change extended menu selection to be vertical display Add new package to dependency list --- package.json | 2 +- src/css/_TextSelection.scss | 1 - src/util/TextSelectionManager.js | 20 +++++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2d417cae8..ea805cdc0 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,6 @@ "update:runtime-deps": "npm i @webcomponents/webcomponentsjs@latest interactjs@latest iso-language-codes@latest jquery@latest jquery-colorbox@latest jquery-ui@latest jquery-ui-touch-punch@latest jquery.browser@latest lit@latest soundmanager2@latest", "update:runtime-deps:test": "npm run build", "DOCS:update:ia-deps": "Packages by @internetarchive", - "update:ia-deps": "npm i @internetarchive/bergamot-translator@latest @internetarchive/ia-activity-indicator@latest @internetarchive/ia-item-navigator@latest @internetarchive/icon-bookmark@latest @internetarchive/icon-close@latest @internetarchive/icon-dl@latest @internetarchive/icon-edit-pencil@latest @internetarchive/icon-ia-logo@latest @internetarchive/icon-magnify-minus@latest @internetarchive/icon-magnify-plus@latest @internetarchive/icon-search@latest @internetarchive/icon-share@latest @internetarchive/icon-toc@latest @internetarchive/icon-visual-adjustment@latest @internetarchive/modal-manager@latest @internetarchive/shared-resize-observer@latest" + "update:ia-deps": "npm i @internetarchive/bergamot-translator@latest @internetarchive/ia-activity-indicator@latest @internetarchive/ia-item-navigator@latest @internetarchive/icon-bookmark@latest @internetarchive/icon-close@latest @internetarchive/icon-dl@latest @internetarchive/icon-edit-pencil@latest @internetarchive/icon-ellipses@latest @internetarchive/icon-ia-logo@latest @internetarchive/icon-magnify-minus@latest @internetarchive/icon-magnify-plus@latest @internetarchive/icon-search@latest @internetarchive/icon-share@latest @internetarchive/icon-toc@latest @internetarchive/icon-visual-adjustment@latest @internetarchive/modal-manager@latest @internetarchive/shared-resize-observer@latest" } } diff --git a/src/css/_TextSelection.scss b/src/css/_TextSelection.scss index 6a78f9f8e..98f9522e4 100644 --- a/src/css/_TextSelection.scss +++ b/src/css/_TextSelection.scss @@ -148,7 +148,6 @@ .br-select-menu__root { display: none; border-radius: 20px; -// background-color: #333; color: white; color-scheme: dark; padding: 2px; diff --git a/src/util/TextSelectionManager.js b/src/util/TextSelectionManager.js index f4d0b30eb..73b44273f 100644 --- a/src/util/TextSelectionManager.js +++ b/src/util/TextSelectionManager.js @@ -604,6 +604,7 @@ class BRSelectMenu extends LitElement { renderExtendedOptions() { return html` + ${this.renderDefaultOptions()} ${this.renderLocalStorageOptions()} `; } @@ -653,9 +654,24 @@ class BRSelectMenu extends LitElement { changeOptions(e) { e.preventDefault(); this.showExtendedOptions = !this.showExtendedOptions; + this.changeContextMenuStyling(); this.requestUpdate(); } + /** + * Change styling for highlight menu to show simplified or extended options + */ + changeContextMenuStyling() { + if (this.showExtendedOptions) { + this.style.display = 'block'; + this.style.gap = '0px'; + this.style.backgroundColor = '#333'; + } else { + this.style.display = 'flex'; + this.style.gap = '10px'; + this.style.backgroundColor = ''; + } + } /** * Returns the closest BRtextLayer element on the page that contains the target node * @param {Node} node @@ -802,12 +818,13 @@ class BRSelectMenu extends LitElement { this.style.left = `${left}px`; } + // Will always show the simplified menu when rendered after hiding async show() { if (this.br.plugins.translate?.userToggleTranslate) return; this.style.zIndex = '1'; this.style.position = 'absolute'; - this.style.display = 'flex'; + this.changeContextMenuStyling(); this.open = true; this.classList.remove('br-select-menu__root--scrolling'); window.removeEventListener('scroll', this._onScroll, { capture: true }); @@ -820,6 +837,7 @@ class BRSelectMenu extends LitElement { hide() { if (!this.open) return; this.style.display = 'none'; + this.showExtendedOptions = false; this.open = false; window.removeEventListener('scroll', this._onScroll, { capture: true }); this.clearNodesForRemoval(); From 9873bfa2214e8ab9938b0703039766df101ffac8 Mon Sep 17 00:00:00 2001 From: Sandy Chu Date: Wed, 15 Jul 2026 14:12:27 -0700 Subject: [PATCH 3/3] Modify CSS styling for menu --- src/css/_TextSelection.scss | 73 ++++++++++++++++++++------------ src/util/TextSelectionManager.js | 52 +++++++++-------------- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/css/_TextSelection.scss b/src/css/_TextSelection.scss index 98f9522e4..5530f8f27 100644 --- a/src/css/_TextSelection.scss +++ b/src/css/_TextSelection.scss @@ -145,16 +145,29 @@ display: none; } + +$select-menu-radius: 25px; +$select-menu-extended-radius: 10px; .br-select-menu__root { display: none; - border-radius: 20px; color: white; color-scheme: dark; padding: 2px; overflow: hidden; opacity: 1; - transition: border-radius 0.2s, opacity 0.2s; - gap: 10px; + transition: opacity 0.2s; + gap: 5px; + + &[open] { + display: flex; + } + + &[showextended] { + display: block; + gap: 0px; + background-color: #333; + border-radius: $select-menu-extended-radius; + } @starting-style { opacity: 0; @@ -164,13 +177,6 @@ opacity: 0; pointer-events: none; } -.br-select-menu__root:hover { - border-radius: 8px; -} - -.br-select-menu__root:hover .br-select-menu__option { - border-radius: 6px; -} .br-select-menu__option { --iconWidth: 15px; @@ -179,15 +185,40 @@ background: transparent; display: flex; align-items: center; - border-radius: 12px; + border-radius: $select-menu-radius; font-family: inherit; color: inherit; border: 0; - transition: background-color 0.2s, border-radius 0.2s; cursor: pointer; text-wrap: nowrap; - padding: 4px; background-color: #333; + position: relative; + + @media (pointer: coarse) and (hover: none) { + padding: 4px 8px; + #br-select-more & { + padding: 4px; + } + } + + &:hover:after { + position: absolute; + left: 2px; + right: 2px; + top: 2px; + bottom: 2px; + content: ""; + pointer-events: none; + background-color: rgba(255, 255, 255, 0.1); + border-radius: calc($select-menu-radius - 2px); + } + + .br-select-menu__root[showextended] & { + width:100%; + &:hover:after { + border-radius: calc($select-menu-extended-radius - 2px); + } + } } .br-select-menu__icon { @@ -201,21 +232,7 @@ .br-select-menu__label { margin-left: 4px; font-size: 12px; -} - -@media (hover: hover) { - .br-select-menu__label { - width: 0px; - margin-left: 0; - opacity: 0; - interpolate-size: allow-keywords; - transition: width 0.2s; - } - .br-select-menu__root:hover .br-select-menu__label { - width: auto; - margin-left: 4px; - opacity: 1; - } + margin-right: 4px; } .BRtextLayer .BRhighlight { diff --git a/src/util/TextSelectionManager.js b/src/util/TextSelectionManager.js index 73b44273f..80279c60c 100644 --- a/src/util/TextSelectionManager.js +++ b/src/util/TextSelectionManager.js @@ -437,7 +437,9 @@ export class BRSelectMenuOption extends LitElement { aria-label=${ifDefined(accessibleLabel)} > ${this.renderIcon()} - ${hasTemporaryText ? html` + ${ + !hasTemporaryText && !baseLabel ? '' : + hasTemporaryText ? html` e.preventDefault()} @click=${this.handleCopyLinkToHighlight} icon="share" - label="Share" + label="Copy Link to Highlight" live-label > `; @@ -568,14 +571,14 @@ class BRSelectMenu extends LitElement { `; } - renderSwitchOptions() { + renderShowMoreOption() { return html` e.preventDefault()} - @click=${this.changeOptions} + @click=${this.toggleExtendedMenu} icon="ellipses" - live-label + aria-label="Show more options" > `; } @@ -596,7 +599,7 @@ class BRSelectMenu extends LitElement { renderDefaultOptions() { return html` - ${this.copyLinkToHighlightEnabled ? this.renderCopyLinkToHighlightOption() : ''} + ${this.copyLinkToHighlightEnabled ? this.renderCopyLinkToHighlightOption() : ''} ${this.highlightAnnotationEnabled && !this.nodesForRemoval ? this.renderHighlightOption() : ''} ${this.nodesForRemoval ? this.renderRemoveOption() : ''} `; @@ -610,10 +613,11 @@ class BRSelectMenu extends LitElement { } render() { + const hasMoreOptions = this.br.plugins.experiments?.isEnabled('annotateHighlight'); // TODO change the second button to use a different icon return html` - ${this.showExtendedOptions ? this.renderExtendedOptions() : this.renderDefaultOptions()} - ${this.renderSwitchOptions()} + ${this.showExtended ? this.renderExtendedOptions() : this.renderDefaultOptions()} + ${!this.showExtended && hasMoreOptions ? this.renderShowMoreOption() : ""} `; } @@ -651,27 +655,11 @@ class BRSelectMenu extends LitElement { /** * @param {MouseEvent} e */ - changeOptions(e) { + toggleExtendedMenu(e) { e.preventDefault(); - this.showExtendedOptions = !this.showExtendedOptions; - this.changeContextMenuStyling(); - this.requestUpdate(); + this.showExtended = !this.showExtended; } - /** - * Change styling for highlight menu to show simplified or extended options - */ - changeContextMenuStyling() { - if (this.showExtendedOptions) { - this.style.display = 'block'; - this.style.gap = '0px'; - this.style.backgroundColor = '#333'; - } else { - this.style.display = 'flex'; - this.style.gap = '10px'; - this.style.backgroundColor = ''; - } - } /** * Returns the closest BRtextLayer element on the page that contains the target node * @param {Node} node @@ -824,7 +812,6 @@ class BRSelectMenu extends LitElement { this.style.zIndex = '1'; this.style.position = 'absolute'; - this.changeContextMenuStyling(); this.open = true; this.classList.remove('br-select-menu__root--scrolling'); window.removeEventListener('scroll', this._onScroll, { capture: true }); @@ -836,8 +823,7 @@ class BRSelectMenu extends LitElement { hide() { if (!this.open) return; - this.style.display = 'none'; - this.showExtendedOptions = false; + this.showExtended = false; this.open = false; window.removeEventListener('scroll', this._onScroll, { capture: true }); this.clearNodesForRemoval();