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(compiler): customize readme mermaid diagram colors #5980

Merged
merged 8 commits into from
Sep 11, 2024
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Please see our [Contributor Code of Conduct](https://github.com/ionic-team/stenc
1. There's no need to install a specific version of npm or Node right now, it shall be done automatically for you in
the next step
5. Run `npm ci`
6. Run `npm install.jest` to install dependencies for Stencil's testing submodule
6. Run `npm run install.jest` to install dependencies for Stencil's testing submodule


### Updates
Expand Down
1,578 changes: 1,578 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/compiler/docs/readme/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEFAULT_TARGET_COMPONENT_STYLES = { background: '#f9f', textColor: '#333' };
Tardigrada777 marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 17 additions & 0 deletions src/compiler/docs/readme/docs-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,23 @@ const normalizeColumnWidth = (rows: RowData[]) => {
}
};

/**
* Checks if a given string is a valid hexadecimal color representation.
*
* @param str - The string to be checked.
* @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
*
* @example
* isHexColor('#FF00AA'); // true
* isHexColor('#f0f'); // true
* isHexColor('#abcde'); // false (too many characters)
* isHexColor('FF00AA'); // false (missing #)
*/
export const isHexColor = (str: string): boolean => {
const hexColorRegex = /^#([0-9A-Fa-f]{3}){1,2}$/;
return hexColorRegex.test(str);
}

interface ColumnData {
text: string;
width: number;
Expand Down
30 changes: 27 additions & 3 deletions src/compiler/docs/readme/markdown-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { normalizePath, relative } from '@utils';
import { normalizePath, relative} from '@utils';

import type * as d from '../../../declarations';
import { DEFAULT_TARGET_COMPONENT_STYLES } from './constants';
import { isHexColor } from "./docs-util";

export const depsToMarkdown = (cmp: d.JsonDocsComponent, cmps: d.JsonDocsComponent[]) => {
export const depsToMarkdown = (
cmp: d.JsonDocsComponent,
cmps: d.JsonDocsComponent[],
targetComponentConfig: d.StencilDocsConfig['markdown']['targetComponent'] = DEFAULT_TARGET_COMPONENT_STYLES,
) => {
const content: string[] = [];

const deps = Object.entries(cmp.dependencyGraph);

if (deps.length === 0) {
return content;
}
Expand All @@ -20,6 +28,7 @@ export const depsToMarkdown = (cmp: d.JsonDocsComponent, cmps: d.JsonDocsCompone
content.push(...usedBy);
content.push(``);
}

if (cmp.dependencies.length > 0) {
const dependsOn = cmp.dependencies.map((tag) => '- ' + getCmpLink(cmp, tag, cmps));

Expand All @@ -29,6 +38,21 @@ export const depsToMarkdown = (cmp: d.JsonDocsComponent, cmps: d.JsonDocsCompone
content.push(``);
}

const { background: defaultBackground, textColor: defaultTextColor } = DEFAULT_TARGET_COMPONENT_STYLES;

let {
background = defaultBackground,
textColor = defaultTextColor,
} = targetComponentConfig;

if (!isHexColor(background)) {
background = defaultBackground;
}

if (!isHexColor(textColor)) {
textColor = defaultTextColor;
}
Tardigrada777 marked this conversation as resolved.
Show resolved Hide resolved

content.push(`### Graph`);
content.push('```mermaid');
content.push('graph TD;');
Expand All @@ -38,7 +62,7 @@ export const depsToMarkdown = (cmp: d.JsonDocsComponent, cmps: d.JsonDocsCompone
});
});

content.push(` style ${cmp.tag} fill:#f9f,stroke:#333,stroke-width:4px`);
content.push(` style ${cmp.tag} fill:${background},stroke:${textColor},stroke-width:4px`);

content.push('```');

Expand Down
8 changes: 6 additions & 2 deletions src/compiler/docs/readme/output-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const generateReadme = async (
await getUserReadmeContent(compilerCtx, readmeOutputPath)
: userContent;

const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput);
const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput, config?.docs?.markdown);

const results = await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
if (results.changedContent) {
Expand All @@ -74,9 +74,13 @@ export const generateMarkdown = (
cmp: d.JsonDocsComponent,
cmps: d.JsonDocsComponent[],
readmeOutput: d.OutputTargetDocsReadme,
markdownConfig?: d.StencilDocsConfig['markdown'],
) => {
//If the readmeOutput.dependencies is true or undefined the dependencies will be generated.
const dependencies = readmeOutput.dependencies !== false ? depsToMarkdown(cmp, cmps) : [];
const dependencies = readmeOutput.dependencies !== false
? depsToMarkdown(cmp, cmps, markdownConfig?.targetComponent)
: [];

return [
userContent || '',
AUTO_GENERATE_COMMENT,
Expand Down
27 changes: 26 additions & 1 deletion src/compiler/docs/test/docs-util.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MarkdownTable } from '../../docs/readme/docs-util';
import { isHexColor, MarkdownTable } from '../../docs/readme/docs-util';

describe('markdown-table', () => {
it('header', () => {
Expand Down Expand Up @@ -46,3 +46,28 @@ describe('markdown-table', () => {
expect(o).toEqual([]);
});
});

describe('isHexColor', () => {
it('should return true for valid hex colors', () => {
expect(isHexColor('#FFF')).toBe(true);
expect(isHexColor('#FFFFFF')).toBe(true);
expect(isHexColor('#000000')).toBe(true);
expect(isHexColor('#f0f0f0')).toBe(true);
expect(isHexColor('#aBcDeF')).toBe(true);
});

it('should return false for invalid hex colors', () => {
expect(isHexColor('FFF')).toBe(false);
expect(isHexColor('#GGGGGG')).toBe(false);
expect(isHexColor('#FF')).toBe(false);
expect(isHexColor('#FFFFFFF')).toBe(false);
expect(isHexColor('#FF0000FF')).toBe(false);
});

it('should return false for non-string inputs', () => {
expect(isHexColor('123')).toBe(false);
expect(isHexColor('true')).toBe(false);
expect(isHexColor('{}')).toBe(false);
expect(isHexColor('[]')).toBe(false);
});
})
34 changes: 34 additions & 0 deletions src/declarations/stencil-public-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ export interface StencilConfig {
*/
env?: { [prop: string]: string | undefined };

docs?: StencilDocsConfig;

globalScript?: string;
srcIndexHtml?: string;
watch?: boolean;
Expand Down Expand Up @@ -1683,6 +1685,38 @@ export interface CopyTask {
keepDirStructure?: boolean;
}

/**
* Configuration for generating documentation from Stencil components.
*/
export interface StencilDocsConfig {

/**
* Options for processing and rendering Markdown documentation files.
*/
markdown: {

/**
* Styling for how the target component will be represented within documentation (e.g., in component diagrams).
*/
targetComponent: {
/**
* Background color used for nodes representing the component in diagrams (e.g., Mermaid graphs).
* Use standard color names or hex codes.
* @example '#f0f0f0' (light gray)
*/
background: string;

/**
* Text color used within nodes representing the component in diagrams (e.g., Mermaid graphs).
* Use standard color names or hex codes.
* @example '#333' (dark gray)
*/
textColor: string;
};
};
Tardigrada777 marked this conversation as resolved.
Show resolved Hide resolved
}


// TODO(STENCIL-882): Remove this interface [BREAKING_CHANGE]
export interface BundlingConfig {
/**
Expand Down