Skip to content

Commit

Permalink
build(docs-generate): override type in docs generation (#3169)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideMininni-Fincons authored Oct 24, 2024
1 parent 2f3dc21 commit 5702592
Show file tree
Hide file tree
Showing 14 changed files with 56 additions and 58 deletions.
1 change: 1 addition & 0 deletions src/elements/checkbox/checkbox-panel/checkbox-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type SbbCheckboxPanelStateChange = Extract<
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @event {Event} change - Event fired on change.
* @event {InputEvent} input - Event fired on input.
* @overrideType value - string | null
*/
export
@customElement('sbb-checkbox-panel')
Expand Down
3 changes: 0 additions & 3 deletions src/elements/checkbox/checkbox-panel/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ The component provides the same accessibility features as the native checkbox.
Always provide an accessible label via `aria-label` for checkboxes without descriptive text content.
If you don't want the label to appear next to the checkbox, you can use `aria-label` to specify an appropriate label.

<!-- Override
@type value => string \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
1 change: 1 addition & 0 deletions src/elements/checkbox/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import '../../visual-checkbox.js';
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @event {Event} change - Event fired on change.
* @event {InputEvent} input - Event fired on input.
* @overrideType value - string | null
*/
export
@customElement('sbb-checkbox')
Expand Down
3 changes: 0 additions & 3 deletions src/elements/checkbox/checkbox/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ If you don't want the label to appear next to the checkbox, you can use `aria-la
<sbb-checkbox aria-label="Subscribed to email message"></sbb-checkbox>
```

<!-- Override
@type value => string \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
1 change: 1 addition & 0 deletions src/elements/file-selector/file-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type DOMEvent = globalThis.Event;
* @event {CustomEvent<File[]>} fileChanged - An event which is emitted each time the file list changes.
* @event change - An event which is emitted each time the user modifies the value. Unlike the input event, the change event is not necessarily fired for each alteration to an element's value
* @event input - An event which is emitted each time the value changes as a direct result of a user action.
* @overrideType value - string | null
*/
export
@customElement('sbb-file-selector')
Expand Down
3 changes: 0 additions & 3 deletions src/elements/file-selector/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ It's suggested to have a different value for each variant, e.g.:
></sbb-file-selector>
```

<!-- Override
@type value => string \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
3 changes: 0 additions & 3 deletions src/elements/select/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@ Opened panel:
| <kbd>Shift</kbd><kbd>Up Arrow</kbd> | If `multiple`, moves to the next non-disabled option and toggle its selection. |
| Any char or number | If exists, select the first non-disabled matching option after the selected value. |

<!-- Override
@type value => string \| string[] \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
1 change: 1 addition & 0 deletions src/elements/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface SelectChange {
* @cssprop [--sbb-select-z-index=var(--sbb-overlay-default-z-index)] - To specify a custom stack order,
* the `z-index` can be overridden by defining this CSS variable. The default `z-index` of the
* component is set to `var(--sbb-overlay-default-z-index)` with a value of `1000`.
* @overrideType value - string | string[] | null
*/
export
@customElement('sbb-select')
Expand Down
3 changes: 0 additions & 3 deletions src/elements/slider/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ The `sbb-slider` has the following behaviour on keypress when focused:
| End | Set the value to the maximum. |
| Home | Set the value to the minimum. |

<!-- Override
@type value => string \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
1 change: 1 addition & 0 deletions src/elements/slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import '../icon.js';
* @slot prefix - Use this slot to render an icon on the left side of the input.
* @slot suffix - Use this slot to render an icon on the right side of the input.
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @overrideType value - string | null
*/
export
@customElement('sbb-slider')
Expand Down
3 changes: 0 additions & 3 deletions src/elements/toggle-check/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ you can not provide it and then use `aria-label` to specify an appropriate label
<sbb-toggle-check aria-label="Subscribed to email message"></sbb-toggle-check>
```

<!-- Override
@type value => string \| null
-->
<!-- Auto Generated Below -->

## Properties
Expand Down
1 change: 1 addition & 0 deletions src/elements/toggle-check/toggle-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import style from './toggle-check.scss?lit&inline';
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @event {Event} change - Event fired on change.
* @event {InputEvent} input - Event fired on input.
* @overrideType value - string | null
*/
export
@customElement('sbb-toggle-check')
Expand Down
41 changes: 1 addition & 40 deletions tools/docs/docs_generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,55 +27,19 @@ const componentsFolder = './src';
const inheritedFromColumnIndex = 6;
const propertyColumnIndex = 1;
const attributeColumnIndex = 2;
const typeColumnIndex = 3;

function getAttributeName(propertyName: string, attributes: Attribute[]): string {
const name = propertyName.replace(/['`]/g, '').trim();
const attr = attributes.find((a) => a.fieldName === name)?.name;
return attr ? `\`${attr}\`` : '-';
}

/**
* Applies overrides to the fields table. The override rules are to be written in the readme,
* before the autogenerated section, in the following format:
*
* <!-- Override
* @type [property] => [replaceValue]
* ...
* -->
*/
function applyOverrides(newReadme: MagicString, tableRows: string[][]): void {
const overrideSection = newReadme.original.match(/<!-- Override(.|\n)*?-->/gm)?.[0];
if (!overrideSection) {
return;
}

// Types override (match: @type [property] => [replaceValue])
const typesOverride = Array.from(
overrideSection.matchAll(/@type (?<property>.*)=>(?<replace>.*)/g),
).map((ov) => ({
property: ov.groups!.property.trim(),
replace: ov.groups!.replace.trim(),
}));

typesOverride.forEach((ov) => {
const propRow = tableRows.find(
(row) => row[propertyColumnIndex].trim() === `\`${ov.property}\``,
)!;
if (!propRow) {
throw Error(`[Docs override] Could not find the "${ov.property}" property to override`);
}
propRow[typeColumnIndex] = `\`${ov.replace}\``;
});
}

/**
* Add the 'attribute' column.
* Removes the 'Inherited from' column.
* Replace 'Fields' title with 'Properties'
*/
function updateFieldsTable(
newReadme: MagicString,
newDocs: MagicString,
sections: RegExpMatchArray[],
attributes?: Attribute[],
Expand All @@ -99,9 +63,6 @@ function updateFieldsTable(
.map((match) => match[0])
.map((row) => row.split(/(?<!\\)\|/g)); // Split by not escaped '|'

// Apply overrides
applyOverrides(newReadme, tableRows);

// Remove the 'Inherited from' column
tableRows.forEach((row) => row.splice(inheritedFromColumnIndex, 1));

Expand Down Expand Up @@ -151,7 +112,7 @@ async function updateComponentReadme(
// Remove the title
newDocs.replace(/^# class: `.*`\n/m, '');

updateFieldsTable(newReadme, newDocs, sections, manifest.attributes ?? []);
updateFieldsTable(newDocs, sections, manifest.attributes ?? []);
newDocs = new MagicString(newDocs.toString());

// Unescape `
Expand Down
49 changes: 49 additions & 0 deletions tools/manifest/custom-elements-manifest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const overrideTypeKey = 'overrideType';

/**
* Docs: https://custom-elements-manifest.open-wc.org/analyzer/getting-started/
*/
Expand Down Expand Up @@ -34,6 +36,33 @@ export function createManifestConfig(library = '') {
classNode = classNode.parent;
}
}

/**
* When a generic T type is used in a superclass declaration, it overrides the type defined in derived class
* during the doc generation (as the `value` property in the `SbbFormAssociatedMixinType`).
* Using the `@overrideType` annotation in the jsDoc's derived class allows to override the type with the correct one.
*
* In this phase, the script looks for all the `@overrideType` annotations,
* and it saves them in the `classDeclaration` object as a pair <property name> / <correct type>.
*/
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
node.jsDoc?.forEach((doc) => {
doc.tags?.forEach((tag) => {
// eslint-disable-next-line lyne/local-name-rule
if (tag.tagName.getText() === overrideTypeKey) {
const [memberName, memberOverrideType] = tag.comment.split(' - ');
const classDeclaration = moduleDoc.declarations.find(
(declaration) => declaration.name === node.name.getText(),
);
if (!classDeclaration[overrideTypeKey]) {
classDeclaration[overrideTypeKey] = [{ memberName, memberOverrideType }];
} else {
classDeclaration[overrideTypeKey].push({ memberName, memberOverrideType });
}
}
});
});
}
},
packageLinkPhase({ customElementsManifest }) {
function fixModulePaths(node, pathAction) {
Expand All @@ -56,6 +85,26 @@ export function createManifestConfig(library = '') {
if (declaration.name.includes('Base')) {
delete declaration.customElement;
}

/**
* Search for all the `classDeclaration` which have the `overrideTypeKey` property,
* and update the provided property with the provided type.
*/
if (declaration[overrideTypeKey]) {
declaration[overrideTypeKey].forEach((overrideObj) => {
const memberToOverride = declaration.members.find(
(member) => member.name === overrideObj.memberName,
);
if (memberToOverride) {
memberToOverride.type = {
...memberToOverride.type,
text: overrideObj.memberOverrideType,
};
}
});
delete declaration[overrideTypeKey];
}

for (const member of declaration.members) {
if (member.name.startsWith('_') && member.default) {
const publicName = member.name.replace(/^_/, '');
Expand Down

0 comments on commit 5702592

Please sign in to comment.