diff options
Diffstat (limited to 'browser/components/newtab/content-src/asrouter/components/SnippetBase')
-rw-r--r-- | browser/components/newtab/content-src/asrouter/components/SnippetBase/SnippetBase.jsx | 121 | ||||
-rw-r--r-- | browser/components/newtab/content-src/asrouter/components/SnippetBase/_SnippetBase.scss | 117 |
2 files changed, 238 insertions, 0 deletions
diff --git a/browser/components/newtab/content-src/asrouter/components/SnippetBase/SnippetBase.jsx b/browser/components/newtab/content-src/asrouter/components/SnippetBase/SnippetBase.jsx new file mode 100644 index 0000000000..fd25337fbf --- /dev/null +++ b/browser/components/newtab/content-src/asrouter/components/SnippetBase/SnippetBase.jsx @@ -0,0 +1,121 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import React from "react"; + +export class SnippetBase extends React.PureComponent { + constructor(props) { + super(props); + this.onBlockClicked = this.onBlockClicked.bind(this); + this.onDismissClicked = this.onDismissClicked.bind(this); + this.setBlockButtonRef = this.setBlockButtonRef.bind(this); + this.onBlockButtonMouseEnter = this.onBlockButtonMouseEnter.bind(this); + this.onBlockButtonMouseLeave = this.onBlockButtonMouseLeave.bind(this); + this.state = { blockButtonHover: false }; + } + + componentDidMount() { + if (this.blockButtonRef) { + this.blockButtonRef.addEventListener( + "mouseenter", + this.onBlockButtonMouseEnter + ); + this.blockButtonRef.addEventListener( + "mouseleave", + this.onBlockButtonMouseLeave + ); + } + } + + componentWillUnmount() { + if (this.blockButtonRef) { + this.blockButtonRef.removeEventListener( + "mouseenter", + this.onBlockButtonMouseEnter + ); + this.blockButtonRef.removeEventListener( + "mouseleave", + this.onBlockButtonMouseLeave + ); + } + } + + setBlockButtonRef(element) { + this.blockButtonRef = element; + } + + onBlockButtonMouseEnter() { + this.setState({ blockButtonHover: true }); + } + + onBlockButtonMouseLeave() { + this.setState({ blockButtonHover: false }); + } + + onBlockClicked() { + if (this.props.provider !== "preview") { + this.props.sendUserActionTelemetry({ + event: "BLOCK", + id: this.props.UISurface, + }); + } + + this.props.onBlock(); + } + + onDismissClicked() { + if (this.props.provider !== "preview") { + this.props.sendUserActionTelemetry({ + event: "DISMISS", + id: this.props.UISurface, + }); + } + + this.props.onDismiss(); + } + + renderDismissButton() { + if (this.props.footerDismiss) { + return ( + <div className="footer"> + <div className="footer-content"> + <button + className="ASRouterButton secondary" + onClick={this.onDismissClicked} + > + {this.props.content.scene2_dismiss_button_text} + </button> + </div> + </div> + ); + } + + const label = this.props.content.block_button_text || "Remove this"; + return ( + <button + className="blockButton" + title={label} + aria-label={label} + onClick={this.onBlockClicked} + ref={this.setBlockButtonRef} + /> + ); + } + + render() { + const { props } = this; + const { blockButtonHover } = this.state; + + const containerClassName = `SnippetBaseContainer${ + props.className ? ` ${props.className}` : "" + }${blockButtonHover ? " active" : ""}`; + + return ( + <div className={containerClassName} style={this.props.textStyle}> + <div className="innerWrapper">{props.children}</div> + {this.renderDismissButton()} + </div> + ); + } +} diff --git a/browser/components/newtab/content-src/asrouter/components/SnippetBase/_SnippetBase.scss b/browser/components/newtab/content-src/asrouter/components/SnippetBase/_SnippetBase.scss new file mode 100644 index 0000000000..86bc30fa8b --- /dev/null +++ b/browser/components/newtab/content-src/asrouter/components/SnippetBase/_SnippetBase.scss @@ -0,0 +1,117 @@ +.SnippetBaseContainer { + position: fixed; + z-index: 2; + bottom: 0; + left: 0; + right: 0; + background-color: var(--newtab-background-color-secondary); + color: var(--newtab-text-primary-color); + font-size: 14px; + line-height: 20px; + border-top: 1px solid transparent; + box-shadow: $shadow-secondary; + display: flex; + align-items: center; + + a { + cursor: pointer; + color: var(--newtab-primary-action-background); + + &:hover { + text-decoration: underline; + } + + [lwt-newtab-brighttext] & { + font-weight: bold; + } + } + + input { + &[type='checkbox'] { + margin-inline-start: 0; + } + } + + .innerWrapper { + margin: 0 auto; + display: flex; + align-items: center; + padding: 12px $section-horizontal-padding; + // This is to account for the block button on smaller screens + padding-inline-end: 36px; + max-width: $wrapper-max-width-large + ($section-horizontal-padding * 2); + + @media (min-width: $break-point-large) { + padding-inline-end: $section-horizontal-padding; + } + + @media (min-width: $break-point-widest) { + max-width: $wrapper-max-width-widest + ($section-horizontal-padding * 2); + } + } + + .blockButton { + display: none; + background: none; + border: 0; + position: absolute; + top: 20px; + inset-inline-end: 12px; + height: 16px; + width: 16px; + background-image: url('chrome://global/skin/icons/close.svg'); + -moz-context-properties: fill; + color: inherit; + fill: currentColor; + opacity: 0.5; + margin-top: -8px; + padding: 0; + cursor: pointer; + } + + &:hover .blockButton { + display: block; + } + + .icon { + height: 42px; + width: 42px; + margin-inline-end: 12px; + flex-shrink: 0; + } +} + +.snippets-preview-banner { + font-size: 15px; + line-height: 42px; + color: var(--newtab-text-primary-color); + background: var(--newtab-background-color-secondary); + text-align: center; + position: absolute; + top: 0; + width: 100%; + + span { + vertical-align: middle; + } +} + +// We show snippet icons for both themes and conditionally hide +// based on which theme is currently active +body { + &:not([lwt-newtab-brighttext]) { + .icon-dark-theme, + .icon.icon-dark-theme, + .scene2Icon .icon-dark-theme { + display: none; + } + } + + &[lwt-newtab-brighttext] { + .icon-light-theme, + .icon.icon-light-theme, + .scene2Icon .icon-light-theme { + display: none; + } + } +} |