UNPKG

@postnord/web-components

Version:

PostNord Web Components

204 lines (203 loc) 7.91 kB
/*! * Built with Stencil * By PostNord. */ /** @ts-ignore */ import entries from "../../../../pn-stats"; import * as svgIcons from "pn-design-assets/pn-assets/icons.js"; import * as svgFlags from "pn-design-assets/pn-assets/flags.js"; import * as illustrations from "pn-design-assets/pn-assets/illustrations.js"; const icons = { ...svgIcons, ...svgFlags }; const createMethodList = (list) => { const section = document.createElement('section'); const title = document.createElement('h4'); title.id = 'methods'; title.textContent = 'Methods'; section.prepend(title); const htmlList = document.createElement('ul'); list.forEach(({ signature, docs, returns }) => { const htmlItem = document.createElement('li'); htmlItem.innerHTML = ` <p style="margin-bottom: .25em;">${docs}</p> <p style="margin-top: .25em;"><code>${signature}</code><br/>Returns type: <code data-code></code></p> `; htmlItem.querySelector('code[data-code]').textContent = returns.type; htmlList.appendChild(htmlItem); }); section.appendChild(htmlList); return section; }; const createList = (title, list, helpertext) => { const section = document.createElement('section'); section.innerHTML += `<h4 id="${title.toLowerCase().replace(' ', '-')}">${title}</h4>`; if (helpertext) section.innerHTML += `<p>${helpertext}</p>`; const ul = document.createElement('ul'); list.forEach((tagName) => { const link = document.createElement('pn-text-link'); link.innerText = tagName; const entry = entries.find(entry => entry.endsWith(`/${tagName}.tsx`)); const noPnName = tagName.replace('pn-', ''); const href = entry.replaceAll('pn-', '').replace(`/${noPnName}.tsx`, ''); const sbLink = `./?path=/docs/components/${href.split('/').join('-')}--docs`; link.setAttribute('href', sbLink); const li = document.createElement('li'); li.appendChild(link); ul.appendChild(li); }); section.appendChild(ul); return section; }; const createDetailObject = (detail) => { if (!detail.match('{')) return `<code>${detail}</code>`; const codeBlock = document.createElement('code'); const data = detail .replace('{ ', '') .replace(' }', '') .split(';') .filter(Boolean) .map((item) => item.trim()); const codeStart = document.createElement('pre'); codeStart.innerText = '{'; codeBlock.appendChild(codeStart); data.forEach(item => { const codeProp = document.createElement('pre'); codeProp.style.whiteSpace = 'nowrap'; codeProp.innerHTML = `\xa0\xa0${item};`; codeBlock.appendChild(codeProp); }); const codeEnd = document.createElement('pre'); codeEnd.innerText = '}'; codeBlock.appendChild(codeEnd); return codeBlock.outerHTML; }; const table = (title, list) => { const section = document.createElement('section'); section.innerHTML += `<h4 id="${title.toLowerCase().replace(' ', '-')}">${title}</h4>`; const pnTable = document.createElement('pn-table'); pnTable.setAttribute('color', 'gray'); const table = document.createElement('table'); const theader = document.createElement('thead'); theader.innerHTML += `<tr><th>Name</th><th>Description</th>${list?.[0]?.event ? '<th>Detail object</th>' : ''}</tr>`; table.appendChild(theader); const tbody = document.createElement('tbody'); list.forEach(({ event, name, docs, detail }) => { const row = document.createElement('tr'); row.innerHTML += `<td>\`${event || name}\`</td><td>${docs}</td>${detail ? `<td>${createDetailObject(detail)}</td>` : ''}`; tbody.appendChild(row); }); table.appendChild(tbody); pnTable.appendChild(table); section.appendChild(pnTable); return section; }; const createTextDocs = ({ tag, docs, events, docsTags, slots, methods, dependents = [], dependencies = [], }) => { const container = document.createElement('article'); const ps = docs.split('\n\n').filter(Boolean); ps.forEach((paragraphs) => { container.innerHTML += `<p>${paragraphs}</p>`; }); if (events?.length) { const eventsTable = table('Events', events); container.appendChild(eventsTable); } const nativeEvents = docsTags.filter(({ name }) => name.startsWith('native')); if (nativeEvents?.length) { const nEvents = nativeEvents.map(({ name, text }) => ({ name: name.replace('native', '').toLowerCase(), docs: text, })); const eventsTable = table('Native events', nEvents); container.appendChild(eventsTable); } if (methods?.length) { const methodList = createMethodList(methods); container.appendChild(methodList); } if (slots?.length) { const slotsTable = table('Slots', slots); container.appendChild(slotsTable); } if (dependents?.length) { const dep = createList('Used by', dependents, `The \`${tag}\` is used by the following components:`); container.appendChild(dep); } if (dependencies?.length) { const deps = createList('Depends on', dependencies, `The \`${tag}\` needs the following components to work:`); container.appendChild(deps); } return container; }; export const createDocumentation = (docs) => { const argTypes = createArgTypes(docs.props); const textContent = createTextDocs(docs); return { argTypes, textContent: textContent.outerHTML, }; }; /** * @param name The name of the component you want to create. Ex: 'pn-button'. * @param args The storybook args coming from the Stories.render function. * * @returns The custom element with its props assigned. */ export const createComponent = (name, args) => { const keys = Object.keys(args); const host = document.createElement(name); keys.forEach(key => { const prop = args[key]; if (prop || prop === 0) { const isIcon = key === 'icon'; const isIllustration = key === 'illustration'; host.setAttribute(key.replace(/[A-Z]/g, m => '-' + m.toLowerCase()), isIcon ? icons[prop] : isIllustration ? illustrations[prop] : prop); } }); return host; }; export const createArgTypes = (props) => { const argTypes = {}; props.forEach(prop => { const category = prop.docsTags.find(({ name }) => name === 'category')?.text; const required = prop.required ? ' *' : ''; let type = prop.values[0].type; if (type === '""') { prop.values[0].value = ''; type = 'string'; } argTypes[prop.name] = { name: prop.attr + required, description: prop.docs, /** @ts-ignore */ type, table: { category: category || null, defaultValue: { summary: prop.default, }, }, }; if (prop.type === 'number') { argTypes[prop.name].type = 'number'; } const hasOptions = prop.values.filter(({ value }) => value)?.length > 1; if (hasOptions) { argTypes[prop.name].options = prop.values.map(({ value }) => value); argTypes[prop.name].control = 'select'; } const hide = !!prop.docsTags.find(({ name }) => name === 'hide'); if (hide) delete argTypes[prop.name]; }); if (argTypes.icon) { argTypes.icon.control = 'select'; argTypes.icon.options = ['', ...Object.keys(icons)]; } if (argTypes.illustration) { argTypes.illustration.control = 'select'; argTypes.illustration.options = ['', ...Object.keys(illustrations)]; } return argTypes; }; //# sourceMappingURL=story.js.map