summaryrefslogtreecommitdiffstats
path: root/browser/components/newtab/content-src/asrouter/components/SnippetBase
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/newtab/content-src/asrouter/components/SnippetBase')
-rw-r--r--browser/components/newtab/content-src/asrouter/components/SnippetBase/SnippetBase.jsx121
-rw-r--r--browser/components/newtab/content-src/asrouter/components/SnippetBase/_SnippetBase.scss117
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;
+ }
+ }
+}