Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: icon sets #1844

Merged
merged 7 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions docs/_includes/layouts/pages/basic.njk
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,21 @@ layout: layouts/base.njk
{% include 'partials/component/masthead.njk' %}
{% include 'partials/component/sidenav.njk' %}

{%- if hasToc -%}
{%- set tags = tocTags or ['h2'] -%}
{%- set table = content | toc(tags=tocTags) -%}
{%- endif -%}

<rh-surface id="main"
role="main"
color-palette="lightest">
<article {% if hasToc and (content | toc).length > 0 %}class="has-toc"{% endif %}>
<article {{ "class=has-toc" if table.length > 0 }}>

{% include 'partials/component/header.njk' %}
{% if hasToc and (content | toc).length > 0 %}

{% if table.length > 0 %}
<uxdot-toc summary="On this page">
{{ content | toc(tags=tocTags or ['h2']) | safe }}
{{ table | safe }}
</uxdot-toc>
{% endif %}

Expand Down
1 change: 1 addition & 0 deletions docs/_includes/partials/component/sidenav.njk
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

{% endfor %}

<uxdot-sidenav-item href="/icons/">Icons</uxdot-sidenav-item>
<uxdot-sidenav-item href="/design-code-status/">Design/code status</uxdot-sidenav-item>
<uxdot-sidenav-item href="/release-notes/">Release notes</uxdot-sidenav-item>
<uxdot-sidenav-item href="/support/">Get support</uxdot-sidenav-item>
Expand Down
40 changes: 29 additions & 11 deletions docs/_plugins/table-of-contents.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
const ignoreAttribute = 'data-toc-exclude';

const defaults = {
tags: ['h2', 'h3', 'h4'],
tags: ['h2'],
/** @type{string[]} */
ignoredElements: [],
};
Expand Down Expand Up @@ -83,25 +83,35 @@ class Toc {
* @param {Options} options
*/
constructor(htmlstring = '', options) {
const { queryAll, hasAttribute, isElementNode } = options.Tools;
const { parse } = options.Parse5;
this.options = { ...defaults, ...options };
this.root = new Item(options);
this.html = htmlstring;
this.options = options;
this.root = new Item(this.options);
this.root.parent = this.root;

const document = parse(htmlstring);
this.parse();
}

parse() {
const { parse } = this.options.Parse5;
const { queryAll, hasAttribute, isElementNode } = this.options.Tools;

const document = parse(this.html);

const tagSet =
new Set(this.options.tags)
.difference(new Set(this.options.ignoredElements));

const headings = queryAll(document, node => isElementNode(node)
&& this.options.tags.includes(node.tagName)
&& !this.options.ignoredElements.includes(node.tagName)
const headings = queryAll(document, node =>
isElementNode(node)
&& tagSet.has(node.tagName)
&& hasAttribute(node, 'id')
&& !hasAttribute(node, ignoreAttribute));

let previous = this.root;

for (const heading of headings) {
if (isElementNode(heading)) {
const current = new Item(options, heading);
const current = new Item(this.options, heading);
const parent = getParent(previous, current);
current.parent = parent;
parent.children.push(current);
Expand All @@ -126,7 +136,15 @@ module.exports = {
async function(content, opts) {
const Parse5 = await import('parse5');
const Tools = await import('@parse5/tools');
const toc = new Toc(content, { ...options, ...opts, Parse5, Tools });
const toc = new Toc(content, {
...defaults,
...options,
...opts,
tags: opts?.tags || options?.tags,
Parse5,
Tools,
page: this.page,
});
const html = toc.serialize();
return html;
});
Expand Down
73 changes: 73 additions & 0 deletions docs/icons/icons.11ty.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// for editor highlighting
const html = String.raw;

module.exports = class IconsPage {
async data() {
return {
permalink: '/icons/index.html',
layout: 'layouts/pages/basic.njk',
title: 'Icons',
hasToc: true,
icons: await import('@rhds/icons'),
};
}

render({ icons }) {
return html`
<script type="module" src="icons.js" data-helmet></script>

<style data-helmet>
.icon-set {
padding: 0;
list-style-type: none;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--rh-space-sm);
}
</style>

<p>Click icons to copy their HTML elements</p>

<section>
<h2 id="social-icons">Social Icons</h2>
<p>These icons represent or link to social media companies</p>
<ul class="icon-set">${this.renderIcons('social', icons)}</ul>
</section>

<section>
<h2 id="standard-icons">Standard Icons</h2>
<p>Use these icons as graphics, and at large sizes</p>
<rh-alert state="warning">Avoid using these for UI elements like buttons</rh-alert>
<ul class="icon-set">${this.renderIcons('standard', icons)}</ul>
</section>

<section>
<h2 id="ui-icons">UI Icons</h2>
<p>Use these icons in UI controls like buttons and form fields</p>
<ul class="icon-set">${this.renderIcons('ui', icons)}</ul>
</section>

<section>
<h2 id="micron-icons">Microns</h2>
<p>Microns is a funny word</p>
<ul class="icon-set">${this.renderIcons('microns', icons)}</ul>
</section>
`;
}

renderIcons(set, icons) {
return Array.from(icons[set].keys(), icon => this.renderIcon({ icon, set })).join('');
}

renderIcon({ set, icon }) {
return html`
<li>
<rh-button accessible-label="Copy icon HTML for ${set} ${icon}"
icon="${icon}"
icon-set="${set}"
variant="tertiary">${icon}</rh-button>
</li>
`;
}
};

15 changes: 15 additions & 0 deletions docs/icons/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import '@rhds/elements/rh-icon/rh-icon.js';
import '@rhds/elements/rh-tooltip/rh-tooltip.js';
import { RhButton } from '@rhds/elements/rh-button/rh-button.js';
import { RhAlert } from '@rhds/elements/rh-alert/rh-alert.js';

document.addEventListener('click', async function(event) {
const { icon, iconSet } = event.target;
if (event.target instanceof RhButton && icon && iconSet) {
const html = /* html*/`<rh-icon set="${iconSet}" icon="${icon}"></rh-icon>`;
await navigator.clipboard.writeText(html);
// TODO: syntax highlight this
const message = html;
await RhAlert.toast({ heading: 'Copied', message });
}
});
1 change: 1 addition & 0 deletions eleventy.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module.exports = function(eleventyConfig) {
eleventyConfig.addPassthroughCopy('docs/styles/**/*');
eleventyConfig.addPassthroughCopy('docs/patterns/**/*.css');
eleventyConfig.addPassthroughCopy('docs/theming/**/*.css');
eleventyConfig.addPassthroughCopy('docs/icons/**/*.{css,js}');


if (isLocal) {
Expand Down
40 changes: 23 additions & 17 deletions scripts/environment.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import { join } from 'node:path';
import { readdir, stat } from 'node:fs/promises';
import { readdir } from 'node:fs/promises';

let iconSetsMap;

/**
* create a javascript map containing icon names
*/
export async function getIconSetsMap() {
if (!iconSetsMap) {
// because the icon package exports DOM nodes, but this file runs in nodejs
await import('@patternfly/pfe-core/ssr-shims.js');
const { standard, social, ui, microns } = await import('@rhds/icons');
iconSetsMap = new Map([
['social', [...social.keys()]],
['standard', [...standard.keys()]],
['ui', [...ui.keys()]],
['microns', [...microns.keys()]],
]);
}
return iconSetsMap;
}

/**
* create a javascript module containing element and icon names
*/
export async function makeDemoEnv() {
const iconsDir = join(process.cwd(), 'node_modules', '@rhds', 'icons');
const dirContents = await readdir(iconsDir);
const dirNamesOrNulls = await Promise.all(dirContents.map(async x => {
const stats = await stat(join(iconsDir, x));
if (!x.startsWith('.') && stats.isDirectory()) {
return x;
} else {
return null;
}
}));
const iconSetNames = dirNamesOrNulls.filter(x => x != null);
const iconSets = await Promise.all(iconSetNames.reverse().map(async set => {
const files = await readdir(join(iconsDir, set));
return [set, [...new Set(files.map(x => x.replace(/\..*$/, '')))]];
}));
iconSetsMap ??= await getIconSetsMap();
const javascript = String.raw; // for editor highlighting
const allElements = (await readdir(join(process.cwd(), 'elements')))
.filter(path => !path.includes('.'));
return javascript`
export const elements = ${JSON.stringify(allElements)};
export const iconSets = new Map(${JSON.stringify(iconSets)});`;
export const iconSets = new Map(${JSON.stringify(Object.fromEntries(iconSetsMap.entries()))});`;
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"es2015.iterable",
"es2020",
"es2022",
"ESNext.Collection",
"ESNext.Disposable",
"es5",
"es6",
Expand Down
Loading