Skip to content

Commit

Permalink
MWPW-136872 first draft for filter blocks (adobecom#107)
Browse files Browse the repository at this point in the history
- using sidenav web component dep,
- using separate spectrum dep,
- introducing unit tests in CC
  • Loading branch information
npeltier authored and yesil committed Dec 20, 2023
1 parent 225a647 commit 7df21b1
Show file tree
Hide file tree
Showing 10 changed files with 13,388 additions and 750 deletions.
Empty file.
38 changes: 38 additions & 0 deletions creativecloud/blocks/sidenav/sidenav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createTag } from '../../scripts/utils.js';
import { html, css, LitElement } from '/creativecloud/deps/lit-all.min.js';
import('/creativecloud/deps/merch-spectrum.min.js');
import('../../deps/sidenav.js');

const getValueFromLabel = (label) => label
.trim()
.toLowerCase()
.replace(/(and|-)/g, '')
.replace(/\s+/g, '-');

const appendSidenavItem = (parent, li) => {
const label = li.childNodes[0]?.textContent;
const value = getValueFromLabel(label);
const item = createTag('sp-sidenav-item', { label, value });
parent.append(item);
const childList = li.querySelector('ul');
if (childList) {
childList.querySelectorAll('li').forEach((grandChild) => {
appendSidenavItem(item, grandChild);
});
}
parent.append(item);
};

export default function init(el) {
const paragraph = el.querySelector('p');
paragraph?.remove();
const root = el.querySelector('ul');
if (root) {
const title = paragraph?.textContent;
const rootNav = createTag('filter-sidenav', { title });
root.querySelectorAll(':scope > li').forEach((li) => {
appendSidenavItem(rootNav, li);
});
root.parentNode.replaceChild(rootNav, root);
}
}
278 changes: 278 additions & 0 deletions creativecloud/deps/lit-all.min.js

Large diffs are not rendered by default.

4,013 changes: 4,013 additions & 0 deletions creativecloud/deps/merch-spectrum.min.js

Large diffs are not rendered by default.

132 changes: 132 additions & 0 deletions creativecloud/deps/sidenav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Tue, 14 Nov 2023 13:43:15 GMT

// src/filter-sidenav.js
import { html, css, LitElement } from "./lit-all.min.js";

// src/deeplink.js
function parseState(hash = window.location.hash) {
const result = [];
const keyValuePairs = hash.replace(/^#/, "").split("&");
for (const pair of keyValuePairs) {
const [key, value = ""] = pair.split("=");
if (key) {
result.push([key, decodeURIComponent(value)]);
}
}
return Object.fromEntries(result);
}
function pushState(state) {
const hash = new URLSearchParams(window.location.hash.slice(1));
Object.entries(state).forEach(([key, value]) => {
if (value) {
hash.set(key, value);
} else {
hash.delete(key);
}
});
window.location.hash = decodeURIComponent(hash.toString());
}

// src/filter-sidenav.js
var FilterSideNav = class extends LitElement {
static properties = {
title: { type: String },
label: { type: String }
};
static styles = css`
:host {
display: block;
contain: content;
}
h2 {
font-size: 11px;
font-style: normal;
font-weight: 500;
height: 32px;
letter-spacing: 0.06em;
padding: 0 12px;
line-height: 32px;
color: var(--color-gray-600);
}
`;
/*
* set the state of the sidenav based on the URL
*/
setStateFromPageLoad() {
const { filter: value } = parseState();
if (value) {
const element = this.shadowRoot.querySelector(
`sp-sidenav-item[value=${value}]`
);
if (element) {
element.click();
}
}
}
pushNavState(value) {
if (value) {
pushState({ filter: value });
}
}
/**
* click handler to manage first level items state of sidenav
* @param {*} param
*/
handleClick({ target: item }) {
const { value, parentNode } = item;
if (parentNode && parentNode.tagName === "SP-SIDENAV") {
this.pushNavState(value);
item.setAttribute("selected", "");
parentNode.querySelectorAll(
"sp-sidenav-item[expanded],sp-sidenav-item[selected]"
).forEach((item2) => {
if (item2.value !== value) {
item2.removeAttribute("expanded");
item2.removeAttribute("selected");
}
});
}
}
/**
* leaf level item selection handler
* @param {*} event
*/
selectionChanged({ target: { value } }) {
this.pushNavState(value);
}
/**
* dub sidenav tree inside shadow dom's sp-sidenav element
*/
dubSideNavTree() {
const sidenav = this.shadowRoot.querySelector("sp-sidenav");
this.querySelectorAll(":scope > sp-sidenav-item").forEach((item) => {
item.addEventListener("click", this.handleClick.bind(this));
sidenav.appendChild(item);
});
}
connectedCallback() {
super.connectedCallback();
this.updateComplete.then(async () => {
this.dubSideNavTree();
this.setStateFromPageLoad();
});
}
render() {
return html`<div aria-label="${this.label}" data-daa-lh="${this.label}">
<h2>${this.title}</h2>
<sp-theme theme="spectrum" color="light" scale="medium">
<sp-sidenav
variant="multilevel"
manageTabIndex="true"
@change="${this.selectionChanged}"
label="${this.label}"
>
</sp-sidenav>
</sp-theme>
</div>`;
}
};
customElements.define("filter-sidenav", FilterSideNav);
export {
FilterSideNav
};
5 changes: 5 additions & 0 deletions creativecloud/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ export const [setLibs, getLibs] = (() => {
}, () => libs,
];
})();

const miloLibs = setLibs('/libs');

const { createTag } = await import(`${miloLibs}/utils/utils.js`);
export { createTag };
Loading

0 comments on commit 7df21b1

Please sign in to comment.