diff --git a/packages/marko-web-theme-monorail/components/directory-facets/facet-container/facet-container.marko b/packages/marko-web-theme-monorail/components/directory-facets/facet-container/facet-container.marko new file mode 100644 index 000000000..e564cfc8c --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/facet-container/facet-container.marko @@ -0,0 +1,23 @@ +$ const { facets, title, description, aliases, initiallyExpanded, searchQuery } = input; + + + + + + ${title} + + + + + $!{description} + + + + + diff --git a/packages/marko-web-theme-monorail/components/directory-facets/facet-container/marko.json b/packages/marko-web-theme-monorail/components/directory-facets/facet-container/marko.json new file mode 100644 index 000000000..10b067eca --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/facet-container/marko.json @@ -0,0 +1,25 @@ +{ + "": { + "template": "./facet-container.marko", + "@facets": { + "type": "array", + "required": true + }, + "@title": "string", + "@description": "string", + "@content-type": "string", + "@search-query": "string", + "@initially-expanded": { + "type": "boolean", + "default-value": false + }, + "@active-id": { + "type": "string", + "required": true + }, + "@aliases": { + "type": "array", + "required": true + } + } +} diff --git a/packages/marko-web-theme-monorail/components/directory-facets/facet-list/facet-list.marko b/packages/marko-web-theme-monorail/components/directory-facets/facet-list/facet-list.marko new file mode 100644 index 000000000..8cfa655c8 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/facet-list/facet-list.marko @@ -0,0 +1,62 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const block = "directory-facets"; + +$ const { + facets, + activeId, + aliases, + initiallyExpanded, + searchQuery +} = input; + +$ const isActiveId = ({id}) => (activeId && (`${activeId}` === `${id}`)); +$ facets.sort((a, b) => a.name.localeCompare(b.name)); + + $ const expandedClass = (initiallyExpanded) ? `${block}__list ${block}__list--open` : `${block}__list`; + + + $ const children = getAsArray(facet, "children.edges").map(({ node }) => node); + $ const isOpen = aliases.includes(facet.alias); + $ const isActive = isActiveId(facet); + + $ const classNames = [`${block}__item`, `${block}__item--${facet.id}`]; + $ const linkClasses = [`${block}__link`] + $ if (isOpen) classNames.push(`${block}__item--open`); + $ if (isActive) linkClasses.push(`${block}__link--active`); + + $ const facetLink = searchQuery ? `/${facet.alias}?searchQuery=${searchQuery}` : `/${facet.alias}`; + + ${facet.name} + + + + + + .${block}__list`, + elementTarget: `.${block}__link--active`, + offset: -12, + } + /> + + + + + + diff --git a/packages/marko-web-theme-monorail/components/directory-facets/facet-list/marko.json b/packages/marko-web-theme-monorail/components/directory-facets/facet-list/marko.json new file mode 100644 index 000000000..c9f33d209 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/facet-list/marko.json @@ -0,0 +1,22 @@ +{ + "": { + "template": "./facet-list.marko", + "@search-query": "string", + "@facets": { + "type": "array", + "required": true + }, + "@active-id": { + "type": "string", + "required": true + }, + "@aliases": { + "type": "array", + "required": true + }, + "@initially-expanded": { + "type": "boolean", + "default-value": false + } + } +} diff --git a/packages/marko-web-theme-monorail/components/directory-facets/facet.marko b/packages/marko-web-theme-monorail/components/directory-facets/facet.marko new file mode 100644 index 000000000..184fd3423 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/facet.marko @@ -0,0 +1,14 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const facets = getAsArray(input, "facets"); +$ const aliases = getAsArray(input, "aliases"); + diff --git a/packages/marko-web-theme-monorail/components/directory-facets/find-active-facet.js b/packages/marko-web-theme-monorail/components/directory-facets/find-active-facet.js new file mode 100644 index 000000000..3d462367b --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/find-active-facet.js @@ -0,0 +1,22 @@ +const build = (facets, total = [], entries) => { + facets.forEach((facet) => { + const { id, name, values } = facet; + const current = entries ? [{ id, name }, ...entries] : [{ id, name }]; + total.push(current); + if (Array.isArray(values) && values.length) build(values, total, current); + }); + return total; +}; + +module.exports = (facets, activeId) => { + const map = new Map(); + const flat = build(facets); + flat.forEach((row) => { + const primary = row.shift(); + const parentIds = row.map(r => r.id); + map.set(`${primary.id}`, { ...primary, parentIds, activeIds: [primary.id, ...parentIds] }); + }); + const active = map.get(`${activeId}`); + if (active) return active; + return { parentIds: [], activeIds: [] }; +}; diff --git a/packages/marko-web-theme-monorail/components/directory-facets/index.marko b/packages/marko-web-theme-monorail/components/directory-facets/index.marko new file mode 100644 index 000000000..fb42d2b45 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/index.marko @@ -0,0 +1,27 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import categorySectionsFragment from "../../graphql/fragments/category-sections" + +$ const activeId = defaultValue(input.activeId, null); +$ const aliases = defaultValue(input.aliases, []); +$ const contentType = defaultValue(input.contentType, ""); +$ const searchQuery = defaultValue(input.searchQuery, null); +$ const primaryAlias = defaultValue(input.primaryAlias, "directory"); +$ const title = defaultValue(input.title, ""); +$ const description = defaultValue(input.description, ""); +$ const withToggle = defaultValue(input.withToggle, false); + + $ const children = getAsArray(node, "children.edges").map(({ node }) => node); + + diff --git a/packages/marko-web-theme-monorail/components/directory-facets/marko.json b/packages/marko-web-theme-monorail/components/directory-facets/marko.json new file mode 100644 index 000000000..596c985aa --- /dev/null +++ b/packages/marko-web-theme-monorail/components/directory-facets/marko.json @@ -0,0 +1,38 @@ +{ + "taglib-imports": [ + "./facet-list/marko.json", + "./facet-container/marko.json" + ], + "": { + "template": "./facet.marko", + "@facets": "array", + "@content-type": "string", + "@search-query": "string", + "@aliases": "array", + "@active-id": "expression", + "@title": "string", + "@description": "string", + "@initially-expanded": { + "type": "boolean", + "default-value": false + } + }, + "": { + "template": "./index.marko", + "@aliases": "array", + "@active-id": "number", + "@content-type": "string", + "@search-query": "string", + "@primary-alias": "string", + "@title": "string", + "@description": "string", + "@with-toggle": { + "type": "boolean", + "default-value": false + }, + "@initially-expanded": { + "type": "boolean", + "default-value": false + } + } +} diff --git a/packages/marko-web-theme-monorail/components/marko.json b/packages/marko-web-theme-monorail/components/marko.json index 06fcdbc5e..a4be70223 100644 --- a/packages/marko-web-theme-monorail/components/marko.json +++ b/packages/marko-web-theme-monorail/components/marko.json @@ -5,6 +5,7 @@ "./blocks/marko.json", "./client-side-blocks/marko.json", "./content-attribution/marko.json", + "./directory-facets/marko.json", "./flows/marko.json", "./gam/marko.json", "./identity-x/marko.json", diff --git a/packages/marko-web-theme-monorail/graphql/fragments/category-sections.js b/packages/marko-web-theme-monorail/graphql/fragments/category-sections.js new file mode 100644 index 000000000..ae2378428 --- /dev/null +++ b/packages/marko-web-theme-monorail/graphql/fragments/category-sections.js @@ -0,0 +1,25 @@ +const gql = require('graphql-tag'); + +module.exports = gql` +fragment WebsiteSectionHierarchyFragment on WebsiteSection { + id + alias + name + hierarchy { + id + name + alias + canonicalPath + } + children(input: { pagination: { limit: 0 } }) { + edges { + node { + id + alias + name + } + } + } +} + +`;