diff options
Diffstat (limited to 'src/content/dependencies/generateListingIndexList.js')
-rw-r--r-- | src/content/dependencies/generateListingIndexList.js | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/content/dependencies/generateListingIndexList.js b/src/content/dependencies/generateListingIndexList.js new file mode 100644 index 00000000..e4a2f5c7 --- /dev/null +++ b/src/content/dependencies/generateListingIndexList.js @@ -0,0 +1,130 @@ +import {empty, stitchArrays} from '../../util/sugar.js'; + +export default { + contentDependencies: ['generateColorStyleVariables', 'linkListing'], + extraDependencies: ['html', 'language', 'wikiData'], + + sprawl({listingTargetSpec, wikiInfo}) { + return {listingTargetSpec, wikiInfo}; + }, + + query(sprawl) { + const query = {}; + + const targetListings = + sprawl.listingTargetSpec + .map(({listings}) => + listings + .filter(listing => + !listing.featureFlag || + sprawl.wikiInfo[listing.featureFlag])); + + query.wikiColor = sprawl.wikiInfo.color; + + query.targets = + sprawl.listingTargetSpec + .filter((target, index) => !empty(targetListings[index])); + + query.targetListings = + targetListings + .filter(listings => !empty(listings)) + + return query; + }, + + relations(relation, query) { + return { + wikiColorVariables: relation('generateColorStyleVariables', query.wikiColor), + + listingLinks: + query.targetListings + .map(listings => + listings.map(listing => relation('linkListing', listing))), + }; + }, + + data(query, sprawl, currentListing) { + const data = {}; + + data.targetStringsKeys = + query.targets + .map(({stringsKey}) => stringsKey); + + data.listingStringsKeys = + query.targetListings + .map(listings => + listings.map(({stringsKey}) => stringsKey)); + + if (currentListing) { + data.currentTargetIndex = + query.targets + .indexOf(currentListing.target); + + data.currentListingIndex = + query.targetListings + .find(listings => listings.includes(currentListing)) + .indexOf(currentListing); + } + + return data; + }, + + slots: { + mode: {validate: v => v.is('content', 'sidebar')}, + }, + + generate(data, relations, slots, {html, language}) { + const listingLinkLists = + stitchArrays({ + listingLinks: relations.listingLinks, + listingStringsKeys: data.listingStringsKeys, + }).map(({listingLinks, listingStringsKeys}, targetIndex) => + html.tag('ul', + stitchArrays({ + listingLink: listingLinks, + listingStringsKey: listingStringsKeys, + }).map(({listingLink, listingStringsKey}, listingIndex) => + html.tag('li', + {class: + targetIndex === data.currentTargetIndex && + listingIndex === data.currentListingIndex && + 'current'}, + listingLink + .slot('content', language.$(`listingPage.${listingStringsKey}.title.short`)))))); + + const targetTitles = + data.targetStringsKeys + .map(stringsKey => language.$(`listingPage.target.${stringsKey}`)); + + switch (slots.mode) { + case 'sidebar': + return html.tags( + stitchArrays({ + targetTitle: targetTitles, + listingLinkList: listingLinkLists, + }).map(({targetTitle, listingLinkList}, targetIndex) => + html.tag('details', + { + open: targetIndex === data.currentTargetIndex, + class: targetIndex === data.currentTargetIndex && 'current', + }, + [ + html.tag('summary', {style: relations.wikiColorVariables}, + html.tag('span', {class: 'group-name'}, targetTitle)), + + listingLinkList, + ]))); + + case 'content': + return ( + html.tag('dl', + stitchArrays({ + targetTitle: targetTitles, + listingLinkList: listingLinkLists, + }).map(({targetTitle, listingLinkList}) => [ + html.tag('dt', {class: ['content-heading']}, targetTitle), + html.tag('dd', listingLinkList), + ]))); + } + }, +}; |