From 685c14f08a36b230b7079d039201c7006f31bccd Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Sun, 16 Jul 2023 00:51:58 +0000 Subject: [PATCH] Bug 1839965 - Create default shopping card. r=shopping-reviewers,fluent-reviewers,flod,kpatenio,jhirsch Differential Revision: https://phabricator.services.mozilla.com/D182250 UltraBlame original commit: 0ad42d8961e77a5704876c869b2c501869810f61 --- .../shopping/content/highlights.css | 17 ---- .../shopping/content/highlights.mjs | 21 ++--- .../shopping/content/shopping-card.css | 80 ++++++++++++++++ .../shopping/content/shopping-card.mjs | 93 +++++++++++++++++++ .../components/shopping/content/shopping.ftl | 3 +- .../components/shopping/content/shopping.html | 2 +- browser/components/shopping/jar.mn | 3 +- .../stories/shopping-card.stories.mjs | 65 +++++++++++++ 8 files changed, 253 insertions(+), 31 deletions(-) delete mode 100644 browser/components/shopping/content/highlights.css create mode 100644 browser/components/shopping/content/shopping-card.css create mode 100644 browser/components/shopping/content/shopping-card.mjs create mode 100644 browser/components/storybook/stories/shopping-card.stories.mjs diff --git a/browser/components/shopping/content/highlights.css b/browser/components/shopping/content/highlights.css deleted file mode 100644 index de736556dc02..000000000000 --- a/browser/components/shopping/content/highlights.css +++ /dev/null @@ -1,17 +0,0 @@ -/* 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/. */ - - /* Separate heading and list of highlights into rows */ - #review-highlights-wrapper { - display: grid; - grid-template-rows: 1rem auto; - margin: 1em; - row-gap: 1em; - } - -#review-highlights-heading { - font-size: 1em; - font-weight: 600; - margin: 0; -} diff --git a/browser/components/shopping/content/highlights.mjs b/browser/components/shopping/content/highlights.mjs index c8db3411a32d..31d3b9e0988f 100644 --- a/browser/components/shopping/content/highlights.mjs +++ b/browser/components/shopping/content/highlights.mjs @@ -9,6 +9,8 @@ import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/shopping/highlight-item.mjs"; +// eslint-disable-next-line import/no-unassigned-import +import "chrome://browser/content/shopping/shopping-card.mjs"; const { ShoppingUtils } = ChromeUtils.importESModule( "chrome://browser/content/shopping/ShoppingUtils.sys.mjs" @@ -108,17 +110,14 @@ class ReviewHighlights extends MozLitElement { highlightsTemplate.push(highlightEl); } return html` - -
-

-
${highlightsTemplate}
-
+ +
+
${highlightsTemplate}
+
+
`; } } diff --git a/browser/components/shopping/content/shopping-card.css b/browser/components/shopping/content/shopping-card.css new file mode 100644 index 000000000000..24fabf0a5a87 --- /dev/null +++ b/browser/components/shopping/content/shopping-card.css @@ -0,0 +1,80 @@ +/* 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 url("chrome://global/skin/in-content/common.css"); + +:host { + display: block; + width: 288px; + border: 1px solid var(--in-content-box-border-color); + border-radius: 8px; + background-color: var(--in-content-page-background); + box-shadow: var(--shadow-10); +} + +.shopping-card { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + padding: 12px; +} + +button { + margin: 0; +} + +#shopping-details { + width: 100%; +} + +#label-wrapper { + display: flex; + justify-content: space-between; + align-self: stretch; +} + +:host([type="accordion"]) #label-wrapper { + cursor: pointer; +} + +#header { + color: var(--in-content-text-color); + font-size: 1em; + font-weight: 600; +} + +#footer { + display: flex; + align-items: center; + justify-content: center; + padding: 8px 0; + border-top: 1px solid var(--in-content-box-border-color); +} + +details > summary { + list-style: none; +} + +details > summary:focus-visible { + outline: var(--in-content-focus-outline); +} + +.chevron-icon { + background-image: url("chrome://global/skin/icons/arrow-down.svg"); + background-position: center; + background-repeat: no-repeat; + -moz-context-properties: fill; + fill: currentColor; + width: 24px; + height: 24px; + min-width: 24px; + min-height: 24px; + padding: 0; + flex-shrink: 0; +} + +details[open] .chevron-icon { + background-image: url("chrome://global/skin/icons/arrow-up.svg"); +} diff --git a/browser/components/shopping/content/shopping-card.mjs b/browser/components/shopping/content/shopping-card.mjs new file mode 100644 index 000000000000..8eb1093f1a7c --- /dev/null +++ b/browser/components/shopping/content/shopping-card.mjs @@ -0,0 +1,93 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * 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 { html, ifDefined } from "chrome://global/content/vendor/lit.all.mjs"; +import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; + +window.MozXULElement.insertFTLIfNeeded("preview/shopping.ftl"); + +/** + * A card container to be used in the shopping sidebar. There are three card types. + * The default type where no type attribute is required and the card will have no extra functionality. + * The "accordion" type will initially not show any content. The card will contain a arrow to expand the + * card so all of the content is visible. + * + * @property {string} label - The label text that will be used for the card header + * @property {string} type - (optional) The type of card. No type specified + * will be the default card. The other available type is "accordion". + */ +class ShoppingCard extends MozLitElement { + static properties = { + label: { type: String }, + type: { type: String }, + }; + + static get queries() { + return { + detailsEl: "#shopping-details", + }; + } + + labelTemplate() { + if (this.label) { + if (this.type === "accordion") { + return html` +
+ ${this.label} + +
+ `; + } + return html` +
+ ${this.label} +
+ `; + } + return ""; + } + + cardTemplate() { + if (this.type === "accordion") { + return html` +
+ ${this.labelTemplate()} +
+
+ `; + } + return html` + ${this.labelTemplate()} +
+ +
+ `; + } + + handleChevronButtonClick() { + this.detailsEl.open = !this.detailsEl.open; + } + + render() { + return html` + +
+ ${this.cardTemplate()} +
+ `; + } +} +customElements.define("shopping-card", ShoppingCard); diff --git a/browser/components/shopping/content/shopping.ftl b/browser/components/shopping/content/shopping.ftl index cf3808a773da..18891ede60ff 100644 --- a/browser/components/shopping/content/shopping.ftl +++ b/browser/components/shopping/content/shopping.ftl @@ -10,7 +10,8 @@ shopping-page-title = { -brand-product-name } Shopping ## Strings for the product review snippets card -shopping-highlights-heading = Snippets from recent reviews +shopping-highlights-label = + .label = Snippets from recent reviews shopping-highlight-price = Price shopping-highlight-quality = Quality diff --git a/browser/components/shopping/content/shopping.html b/browser/components/shopping/content/shopping.html index a7d77e91d4de..f8e6b30c47c3 100644 --- a/browser/components/shopping/content/shopping.html +++ b/browser/components/shopping/content/shopping.html @@ -31,7 +31,7 @@
-
diff --git a/browser/components/shopping/jar.mn b/browser/components/shopping/jar.mn index 2f4431c77ecc..8072fa854b05 100644 --- a/browser/components/shopping/jar.mn +++ b/browser/components/shopping/jar.mn @@ -7,7 +7,8 @@ browser.jar: content/browser/shopping/shopping.css (content/shopping.css) content/browser/shopping/shopping.mjs (content/shopping.mjs) content/browser/shopping/ShoppingUtils.sys.mjs (content/ShoppingUtils.sys.mjs) - content/browser/shopping/highlights.css (content/highlights.css) content/browser/shopping/highlights.mjs (content/highlights.mjs) content/browser/shopping/highlight-item.css (content/highlight-item.css) content/browser/shopping/highlight-item.mjs (content/highlight-item.mjs) + content/browser/shopping/shopping-card.css (content/shopping-card.css) + content/browser/shopping/shopping-card.mjs (content/shopping-card.mjs) diff --git a/browser/components/storybook/stories/shopping-card.stories.mjs b/browser/components/storybook/stories/shopping-card.stories.mjs new file mode 100644 index 000000000000..db395d854075 --- /dev/null +++ b/browser/components/storybook/stories/shopping-card.stories.mjs @@ -0,0 +1,65 @@ +/* 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/. */ + +// eslint-disable-next-line import/no-unresolved +import { html, ifDefined } from "lit.all.mjs"; +// eslint-disable-next-line import/no-unassigned-import +import "browser/components/shopping/content/shopping-card.mjs"; + +// window.MozXULElement.insertFTLIfNeeded("preview/shopping.ftl"); + +export default { + title: "Domain-specific UI Widgets/Shopping/Shopping Card", + component: "shopping-card", + parameters: { + status: "in-development", + fluent: ` +shopping-card-label = + .label = This the label +shopping-show-more-button = Show more +shopping-show-less-button = Show less + `, + }, +}; + +const Template = ({ l10nId, rating, content, type }) => html` +
+ +
+ ${rating ? html`` : ""} +
+
${ifDefined(content)}
+
+
+`; + +export const DefaultCard = Template.bind({}); +DefaultCard.args = { + l10nId: "shopping-card-label", + content: "This is the content", +}; + +export const CardWithRating = Template.bind({}); +CardWithRating.args = { + ...DefaultCard.args, + rating: 3, +}; + +export const CardOnlyContent = Template.bind({}); +CardOnlyContent.args = { + content: "This card only contains content", +}; + +export const CardTypeAccordion = Template.bind({}); +CardTypeAccordion.args = { + ...DefaultCard.args, + content: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Nunc velit turpis, mollis a ultricies vitae, accumsan ut augue. + In a eros ac dolor hendrerit varius et at mauris.`, + type: "accordion", +};