1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 } from "chrome://global/content/vendor/lit.all.mjs";
11 import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
14 * A collapsible card container to be used throughout Firefox View
16 * @property {string} sectionLabel - The aria-label used for the section landmark if the header is hidden with hideHeader
17 * @property {boolean} hideHeader - Optional property given if the card container should not display a header
18 * @property {boolean} isEmptyState - Optional property given if the card is used within an empty state
19 * @property {boolean} isInnerCard - Optional property given if the card a nested card within another card and given a border rather than box-shadow
20 * @property {boolean} preserveCollapseState - Whether or not the expanded/collapsed state should persist
21 * @property {string} shortPageName - Page name that the 'View all' link will navigate to and the preserveCollapseState pref will use
22 * @property {boolean} showViewAll - True if you need to display a 'View all' header link to navigate
23 * @property {boolean} toggleDisabled - Optional property given if the card container should not be collapsible
24 * @property {boolean} removeBlockEndMargin - True if you need to remove the block end margin on the card container
26 class CardContainer extends MozLitElement {
29 this.initiallyExpanded = true;
30 this.isExpanded = false;
35 sectionLabel: { type: String },
36 hideHeader: { type: Boolean },
37 isExpanded: { type: Boolean },
38 isEmptyState: { type: Boolean },
39 isInnerCard: { type: Boolean },
40 preserveCollapseState: { type: Boolean },
41 shortPageName: { type: String },
42 showViewAll: { type: Boolean },
43 toggleDisabled: { type: Boolean },
44 removeBlockEndMargin: { type: Boolean },
45 visible: { type: Boolean },
50 mainSlot: "slot[name=main]",
52 viewAllLink: ".view-all-link",
55 get detailsExpanded() {
56 return this.detailsEl.hasAttribute("open");
59 get detailsOpenPrefValue() {
60 const prefName = this.shortPageName
61 ? `browser.tabs.firefox-view.ui-state.${this.shortPageName}.open`
63 if (prefName && Services.prefs.prefHasUserValue(prefName)) {
64 return Services.prefs.getBoolPref(prefName);
70 super.connectedCallback();
71 this.isExpanded = this.detailsOpenPrefValue ?? this.initiallyExpanded;
75 if (this.isExpanded == this.detailsExpanded) {
78 this.isExpanded = this.detailsExpanded;
80 this.updateTabLists();
82 if (!this.shortPageName) {
86 if (this.preserveCollapseState) {
87 const prefName = this.shortPageName
88 ? `browser.tabs.firefox-view.ui-state.${this.shortPageName}.open`
90 Services.prefs.setBoolPref(prefName, this.isExpanded);
94 Glean.firefoxviewNext[
95 `card${this.isExpanded ? "Expanded" : "Collapsed"}CardContainer`
97 data_type: this.shortPageName,
103 new CustomEvent("card-container-view-all", {
110 willUpdate(changes) {
111 if (changes.has("visible")) {
112 this.updateTabLists();
117 let tabLists = this.querySelectorAll(
118 "fxview-tab-list, opentabs-tab-list, syncedtabs-tab-list"
121 tabLists.forEach(tabList => {
122 tabList.updatesPaused = !this.visible || !this.isExpanded;
131 href="chrome://browser/content/firefoxview/card-container.css"
138 "card-container": true,
139 inner: this.isInnerCard,
140 "empty-state": this.isEmptyState && !this.isInnerCard,
145 class="card-container-header"
146 ?hidden=${ifDefined(this.hideHeader)}
148 ?withViewAll=${this.showViewAll}
150 <slot name="header"></slot>
151 <slot name="secondary-header"></slot>
154 href="about:firefoxview#${this.shortPageName}"
155 @click=${this.viewAllClicked}
156 class="view-all-link"
157 data-l10n-id="firefoxview-view-all-link"
158 ?hidden=${!this.showViewAll}
160 <slot name="main"></slot>
161 <slot name="footer" class="card-container-footer"></slot>
166 "card-container": true,
167 inner: this.isInnerCard,
168 "empty-state": this.isEmptyState && !this.isInnerCard,
170 ?open=${this.isExpanded}
171 ?isOpenTabsView=${this.removeBlockEndMargin}
172 @toggle=${this.onToggleContainer}
173 role=${this.isInnerCard ? "presentation" : "group"}
176 class="card-container-header"
177 ?hidden=${ifDefined(this.hideHeader)}
178 ?withViewAll=${this.showViewAll}
181 class="icon chevron-icon"
183 data-l10n-id="firefoxview-collapse-button-${this.isExpanded
187 <slot name="header"></slot>
190 href="about:firefoxview#${this.shortPageName}"
191 @click=${this.viewAllClicked}
192 class="view-all-link"
193 data-l10n-id="firefoxview-view-all-link"
194 ?hidden=${!this.showViewAll}
196 <slot name="main"></slot>
197 <slot name="footer" class="card-container-footer"></slot>
203 customElements.define("card-container", CardContainer);