@postnord/web-components
Version:
PostNord Web Components
204 lines (203 loc) • 7.91 kB
JavaScript
/*!
* 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