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

feat(tools): add pfe cli #2336

Draft
wants to merge 47 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
57f6e4e
feat(tools): add pfe cli
bennypowers Feb 2, 2023
a64b684
chore: update test runner config
bennypowers Feb 2, 2023
80333aa
fix(tools): rename lint-exports command to lint exports
bennypowers Feb 2, 2023
6afbe2d
fix(tools): improve lint command
bennypowers Feb 2, 2023
76c2652
chore: lint package exports on commit
bennypowers Feb 2, 2023
e97d76e
fix(tools): improve lint exports
bennypowers Feb 2, 2023
6ef0890
chore: update deps
bennypowers Feb 2, 2023
c3a482a
fix: lint package.json
bennypowers Feb 2, 2023
0b8d909
feat(tools): lint existence of exports
bennypowers Feb 2, 2023
b4464e8
style: refactor
bennypowers Feb 2, 2023
0eac0ab
chore: update deps
bennypowers Apr 21, 2023
60f670b
Merge branch 'main' into feat/tools/pfe-cli
bennypowers Jul 6, 2023
e19ba55
feat(tools): cli analyze command (wip)
bennypowers Jul 9, 2023
8d0256f
style: rename local var
bennypowers Jul 10, 2023
76cc99d
fix(tools): format errors with typescript utils
bennypowers Jul 10, 2023
733e37c
fix(accordion): specify type in private function
bennypowers Jul 10, 2023
20fd943
chore: fix tsconfig for elements package
bennypowers Jul 10, 2023
7ab372f
chore: fix tsconfig for elements
bennypowers Jul 10, 2023
dcd93d0
fix: simp for typescript 4.7
bennypowers Jul 10, 2023
be80bd0
feat: wip gen-manifest
bennypowers Jul 13, 2023
369b028
fix: debug gen-manifest
bennypowers Jul 18, 2023
9361941
Merge branch 'main' into feat/tools/pfe-cli
bennypowers Aug 22, 2023
6549b5c
feat: wip cli analyze
bennypowers Aug 22, 2023
55d5419
feat!: move cli to its own package
bennypowers Aug 22, 2023
b7e85c5
fix(core): remove typescript augmentations
bennypowers Aug 22, 2023
c72aaff
chore: deps
bennypowers Aug 22, 2023
4b17efe
fix: analyzer deps
bennypowers Aug 22, 2023
a7a0552
fix: analyzer post-processing
bennypowers Aug 22, 2023
1c68f5e
refactor(pfe-cli): shuffle files
bennypowers Aug 24, 2023
f4beea6
chore: eslint config
bennypowers Aug 24, 2023
0c6784d
fix(pfe-cli): write demo info to manifests
bennypowers Aug 24, 2023
9a82bc6
chore(elements): fix tsconfig
bennypowers Aug 24, 2023
f5d067f
fix(pfe-cli): clean up output
bennypowers Aug 24, 2023
4020a6a
fix(pfe-cli): help text for analyze
bennypowers Aug 24, 2023
15192db
chore: update deps
bennypowers Aug 24, 2023
bc57277
chore: sort contributors
bennypowers Aug 24, 2023
0373c38
feat: lint changesets
bennypowers Aug 24, 2023
69e2bd6
chore: test runner ignores
bennypowers Aug 24, 2023
02c71fd
style: lint
bennypowers Aug 24, 2023
e1a5ba3
fix: just make markdown lint an eslint thing
bennypowers Aug 24, 2023
1c77b6b
fix(core): use browser globals (typescript)
bennypowers Aug 27, 2023
6765fee
fix(pfe-cli): clean up output
bennypowers Aug 27, 2023
6514189
fix(elements): move declaration from monorepo root
bennypowers Aug 29, 2023
aeb5f87
fix(pfe-cli): shuffle files, fixes
bennypowers Aug 29, 2023
9478632
chore: better wireit for analyze
bennypowers Aug 29, 2023
0231855
fix(pfe-cli): edge cases to export-maps hack
bennypowers Aug 29, 2023
92373b8
refactor(pfe-tools)!: remove 11ty cem templates
bennypowers Sep 1, 2023
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
5 changes: 5 additions & 0 deletions .changeset/create-element-use-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@patternfly/create-element": patch
---

Use the new `pfe` cli to generate elements
23 changes: 23 additions & 0 deletions .changeset/pfe-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
"@patternfly/pfe-tools": minor
"@patternfly/create-element": patch
---

✨ Added `pfe` CLI

Initially provides two commands:

```
pfe [<cmd>] [args]

Commands:
pfe analyze <packagePath> Ensure package.json contains the required package
exports
pfe generate [args] Generate an element [aliases: new]

Options:
--version Show version number [boolean]
--help Show help [boolean]

Read the docs at https://patternflyelements.org
```
4 changes: 4 additions & 0 deletions .changeset/pfe-tools-no-cem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@patternfly/pfe-tools": major
---
Removed custom-elements-manifest analyzer plugins
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ tools/**/*.js
!elements/*/demo/*.js
elements/*/demo/*.html

tools/create-element/templates/**/*
tools/pfe-cli/commands/generate/templates/**/*
node_modules
node_modules/**/*
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"overrides": [
{
"files": [
"./tools/create-element/**/*"
"./tools/pfe-cli/**/*.ts"
],
"rules": {
"no-console": "off"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ tools/*/test/**/*.png
!core/**/*.config.js
!tools/**/*.config.js

!elements/declaration.d.ts
!elements/*/demo/*
!core/*/demo/*
!tools/*/demo/*
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.12.1
v18.16.0
13 changes: 13 additions & 0 deletions .remarkrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { readFile } from 'node:fs/promises';
import remarkFrontmatter from 'remark-frontmatter';
import remarkLintFrontmatterSchema from 'remark-lint-frontmatter-schema';

export default {
plugins: [
remarkFrontmatter,
[remarkLintFrontmatterSchema, ['error', {
embed: JSON.parse(await readFile(new URL('./scripts/pfe-changesets.schema.json', import.meta.url), 'utf8')),
schemas: {
'./changeset/*.md': ['https://patternflyelements.org/changeset.schema.json']
} }] ] ],
};
4 changes: 2 additions & 2 deletions core/pfe-core/controllers/overflow-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class OverflowController implements ReactiveController {
#items: HTMLElement[] = [];

#scrollTimeoutDelay = 0;
#scrollTimeout?: ReturnType<typeof setTimeout>;
#scrollTimeout?: number;

/** Default state */
#hideOverflowButtons = false;
Expand Down Expand Up @@ -59,7 +59,7 @@ export class OverflowController implements ReactiveController {

onScroll = () => {
clearTimeout(this.#scrollTimeout);
this.#scrollTimeout = setTimeout(() => this.#setOverflowState(), this.#scrollTimeoutDelay);
this.#scrollTimeout = window.setTimeout(() => this.#setOverflowState(), this.#scrollTimeoutDelay);
};

scrollLeft() {
Expand Down
8 changes: 4 additions & 4 deletions core/pfe-core/decorators/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ export function time(tag?: string) {
const END_TAG = `end-${TAG}`;

if (window.PfeConfig.trackPerformance) {
performance.mark(START_TAG);
window.performance.mark(START_TAG);
}

const x = f.call(this, ...args);

const ret = () => {
if (window.PfeConfig.trackPerformance) {
performance.mark(END_TAG);
performance.measure(TAG, START_TAG, END_TAG);
window.performance.mark(END_TAG);
window.performance.measure(TAG, START_TAG, END_TAG);
// eslint-disable-next-line no-console
console.log(Array.from(performance.getEntriesByName(TAG)).pop());
console.log(Array.from(window.performance.getEntriesByName(TAG)).pop());
}
return x;
};
Expand Down
1 change: 1 addition & 0 deletions core/pfe-core/functions/deprecatedCustomEvent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* Construct a CustomEvent with the given name and detail.
* The event bubbles and is composed.
* @deprecated
*/
export function deprecatedCustomEvent<T>(name: string, detail?: T): CustomEvent<T> {
return new CustomEvent(name, {
Expand Down
8 changes: 4 additions & 4 deletions core/pfe-core/functions/isElementInView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* This function returns whether or not an element is within the viewable area of a container. If partial is true,
* then this function will return true even if only part of the element is in view.
*
* @param {HTMLElement} container The container to check if the element is in view of.
* @param {HTMLElement} element The element to check if it is view
* @param {boolean} partial true if partial view is allowed
* @param {boolean} strict true if strict mode is set, never consider the container width and element width
* @param container The container to check if the element is in view of.
* @param element The element to check if it is view
* @param partial true if partial view is allowed
* @param strict true if strict mode is set, never consider the container width and element width
*
* @returns True if the component is in View.
*/
Expand Down
5 changes: 2 additions & 3 deletions core/pfe-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@
},
"scripts": {
"clean": "git clean -fX -e node_modules -e tsconfig.tsbuildinfo",
"analyze": "cem analyze",
"analyze": "pfe analyze .",
"test": "wtr --files './test/*.spec.ts' --config ../../web-test-runner.config.js"
},
"dependencies": {
"@floating-ui/dom": "^1.2.6",
"lit": "^2.7.2"
"lit": "^2.8.0"
},
"repository": {
"type": "git",
Expand All @@ -69,7 +69,6 @@
"**/*.d.ts",
"**/*.js",
"**/*.js.map",
"!custom-elements-manifest.config.js",
"custom-elements.json",
"!demo/*",
"!docs/*",
Expand Down
Empty file.
4 changes: 1 addition & 3 deletions docs/_data/importMap.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
const fs = require('fs');
const path = require('path');
const { promisify } = require('node:util');
const Glob = require('glob');
const glob = promisify(Glob);
const { glob } = require('glob');

const packageLock = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package-lock.json')));

Expand Down
152 changes: 152 additions & 0 deletions docs/_plugins/element-docs.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
const path = require('path');

function innerMD(content = '') {
const trimmed = content.trim();
return trimmed && `\n\n\n${trimmed}\n\n\n`;
}

function type(content = '', { lang = 'ts' } = {}) {
return content?.trim?.() &&
`\n\n\`\`\`${lang}\n${content.trim()}\n\n\`\`\`\n\n`;
}

// TODO: Object.groupBy instead of reduce
function undeprecate(acc, x) {
acc ??= {};
acc.deprecated ??= [];
acc.current ??= [];
if (x.deprecated) {
acc.deprecated.push(x);
} else {
acc.current.push(x);
}
return acc;
}

/** @param {import('@11ty/eleventy/src/UserConfig')} eleventyConfig */
module.exports = function(eleventyConfig) {
/**
* docs pages contain a #styling-hooks anchor as back compat for older versions of the page
* to prevent this id from rendering more than once, we track the number of times each page
* renders css custom properties.
*/
const cssStylingHookIdTracker = new WeakSet();

async function render(tpl, content, kwargs) {
return eleventyConfig.javascriptFunctions.renderFile(
path.join(process.cwd(), '/docs/_plugins/element-docs/templates/', tpl),
{ content, ...kwargs },
);
}

/** Rebuild the site in watch mode when the templates for this plugin change */
eleventyConfig.addWatchTarget('docs/_plugins/element-docs/templates/*.njk');

eleventyConfig.addFilter('cemMdHeading', (header, length = 2) =>
innerMD(`${Array.from({ length }, () => '#').join('')} ${header}`));

eleventyConfig.addFilter('cemInnerMD', innerMD);

eleventyConfig.addFilter('cemType', type);

eleventyConfig.addPairedAsyncShortcode('band', async function(content, kwargs) {
return render('band.njk', content, kwargs);
});

/**
* Render the overview of a component page
*/
eleventyConfig.addPairedAsyncShortcode('renderOverview', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const description = docsPage.manifest.getDescription(tagName);
const header = kwargs.title ?? this.title;
const { renderTitleInOverview = false } = this.options ?? {};
const renderedTitle =
!renderTitleInOverview ? ''
: await render('band.njk', '', { level: 1, header });
return `${renderedTitle}\n${await render('overview.njk', content, { description, ...kwargs })}`;
});

/**
* Render the list of element attributes
*/
eleventyConfig.addPairedAsyncShortcode('renderAttributes', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: attributes } = docsPage.manifest.getAttributes(tagName).reduce(undeprecate, {});
return render('attributes.njk', content, { attributes, deprecated, ...kwargs });
});

/**
* Render the list of element DOM properties
* @deprecated: render your own templates. To be removed in version 3
*/
eleventyConfig.addPairedAsyncShortcode('renderProperties', async function(content = '', kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: properties } = docsPage.manifest.getProperties(tagName).reduce(undeprecate, {});
return render('properties.njk', content, { properties, deprecated, ...kwargs });
});

/**
* Render a table of element CSS Custom Properties
* @deprecated: render your own templates. To be removed in version 3
*/
eleventyConfig.addPairedAsyncShortcode('renderCssCustomProperties', async function(content, kwargs = {}) {
const hasStylingHooks = cssStylingHookIdTracker.has(this);
cssStylingHookIdTracker.add(this);
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: cssProperties } = docsPage.manifest.getCssCustomProperties(tagName).reduce(undeprecate, {});
return render('css-custom-properties.njk', content, { cssProperties, deprecated, hasStylingHooks, ...kwargs });
});

/**
* Render the list of element CSS Shadow Parts
* @deprecated: render your own templates. To be removed in version 3
*/
eleventyConfig.addPairedAsyncShortcode('renderCssParts', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: parts } = docsPage.manifest.getCssParts(tagName).reduce(undeprecate, {});
return render('css-shadow-parts.njk', content, { parts, deprecated, ...kwargs });
});

/**
* Render the list of events for the element
*/
eleventyConfig.addPairedAsyncShortcode('renderEvents', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: events } = docsPage.manifest.getEvents(tagName).reduce(undeprecate, {});
return render('events.njk', content, { events, deprecated, ...kwargs });
});

/**
* Render the installation instructions for the element
*/
eleventyConfig.addPairedAsyncShortcode('renderInstallation', async function(content, kwargs = {}) {
return `${await render('install.njk', content, kwargs)}`;
});

/**
* Render the list of element methods
*/
eleventyConfig.addPairedAsyncShortcode('renderMethods', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: methods } = docsPage.manifest.getMethods(tagName).reduce(undeprecate, {});
return render('methods.njk', content, { methods, deprecated, ...kwargs });
});

/**
* Render the list of the element's slots
*/
eleventyConfig.addPairedAsyncShortcode('renderSlots', async function(content, kwargs = {}) {
const docsPage = this.ctx._;
const tagName = docsPage.packageTagName(kwargs);
const { deprecated, current: slots } = docsPage.manifest.getSlots(tagName).reduce(undeprecate, {});
return render('slots.njk', content, { slots, deprecated, ...kwargs });
});
};
37 changes: 37 additions & 0 deletions docs/_plugins/element-docs/templates/attributes.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% set level = level or 2 %}
{% set header = header or 'Attributes' %}

<section class="band api attributes api-properties">
{{ header | cemMdHeading(level) | safe }} {% if not content and not attributes.length %}

<em>None</em> {%- else -%}

{{ content | cemInnerMD | safe }}
<dl> {%- for attribute in attributes -%}
<dt><strong><code>{{ attribute.name }}</code></strong></dt>
<dd>
{{- attribute.description | cemInnerMD | safe -}}
<dl class="member"> {%- if attribute.fieldName -%}
<dt>DOM Property</dt> <dd><code>{{ attribute.fieldName }}</code></dd> {%- endif -%}
<dt>Type</dt> <dd class="inline-type"> {{- (attribute.type.text or 'unknown') | cemType | safe -}} </dd>
<dt>Default</dt> <dd class="inline-type">{{- (attribute.default or 'unknown') | cemType | safe -}}</dd>
</dl>
</dd> {%- endfor -%}
</dl> {%- endif -%} {%- if deprecated.length -%}

<details>
<summary>{{ ('Deprecated ' + header) | cemMdHeading(level + 1) | safe }}</summary>
<dl> {%- for attribute in deprecated -%}
<dt><strong><code>{{ attribute.name }}</code></strong></dt>
<dd>
{{- attribute.description | cemInnerMD | safe -}}
<em>Note: {{ attribute.name }} is deprecated. {{ item.deprecated | cemInnerMD | safe }}</em>
<dl class="member"> {%- if attribute.fieldName -%}
<dt>DOM Property</dt> <dd><code>{{ attribute.fieldName }}</code></dd> {%- endif -%}
<dt>Type</dt> <dd class="inline-type"> {{- (attribute.type.text or 'unknown') | cemType | safe -}} </dd>
<dt>Default</dt> <dd class="inline-type"> {{- (attribute.default or 'unknown') | cemType | safe -}} </dd>
</dl>
</dd> {%- endfor -%}
</dl>
</details>{%- endif -%}
</section>
6 changes: 6 additions & 0 deletions docs/_plugins/element-docs/templates/band.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% set level = level or 2 %}

<section class="band">
{{ header | cemMdHeading(level) | safe }}
{{ content | cemInnerMD | safe }}
</section>
Loading