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: simplify CSS docs #309

Merged
merged 1 commit into from
Sep 12, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ dist
# Generated docs
docs/**/*.mdx
!docs/theming/introduction.mdx
!docs/theming/palette-variables.mdx

# Mac
.DS_Store
Expand Down
9 changes: 8 additions & 1 deletion doc-templates/component-variables.template.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ CSS variables are the easiest way to customize the theme. The variables are orga
- Global
- Component

This page contains information about the component variables.
Global variables change the layout/look-and-feel of the whole chat UI, meanwhile component variables change only a part of it (for example message component).

Component variables can be further grouped in the following ways:

- **Theme variables** for changing text and background colors, borders and shadows
- **Layout variables** defined for some components (but not all) to change the size of a specific part of a component

You can find the list of components below:

[//]: # '#SLOT-autogenerated-component-variables'
16 changes: 3 additions & 13 deletions doc-templates/global-variables.template.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,11 @@ CSS variables are the easiest way to customize the theme. The variables are orga
- Global
- Component

This page contains information about the global variables.
Global variables change the layout/look-and-feel of the whole chat UI, meanwhile component variables change only a part of it (for example message component).

Global variables can be grouped into the following categories:

- Theme: colors, typography and border radiuses
- Layout: spacing (padding and margin) and sizing

You can read about each category in detail in the tables below.

## Theme variables

[//]: # '#SLOT-autogenerated-theme-variables'

## Layout variables

[//]: # '#SLOT-autogenerated-layout-variables'
- **Theme**: colors, typography and border radiuses [//]: # '#SLOT-autogenerated-theme-variables'
- **Layout**: spacing (padding and margin) and sizing [//]: # '#SLOT-autogenerated-layout-variables'

If you find that these variables are too high-level and you need more granular control, you also have the option to provide [component layer overrides](./component-variables.mdx).
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ import V2Warning from './V2Warning';

A color palette is defined inside the library that used to define default values for the [global theme variables](./global-variables.mdx). If you want to work with the default theme but want to adjust the shades (for example, change `blue500` to a lighter color), you can update the palette variables. However, if you want to change the color scheme of the theme (for example, change the primary color from blue to green), you should take a look at [global theme variables](./global-variables.mdx).

[//]: # '#SLOT-autogenerated-palette-variables'

Palette variables are defined in: [https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/\_palette-variables.scss](https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/_palette-variables.scss)
You can find the [list of palette variables on GitHub](https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/_palette-variables.scss).
24 changes: 6 additions & 18 deletions scripts/generate-docs.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import * as fs from 'fs';
import { extractVariables } from './parser';
import { getComponentVariablesOutput, getPaletteVariablesOutput, getGlobalVariablesOutput } from './output';
import { getComponentVariablesOutput, getGlobalVariablesOutput } from './output';
import { extractComponents } from './parser';

const globalThemeVariables = extractVariables('./src/v2/styles/_global-theme-variables.scss');
const globalLayoutVariables = extractVariables('./src/v2/styles/_global-layout-variables.scss');
const componentVariables = extractVariables('./src/v2/**/*-@(theme|layout).scss', globalThemeVariables);
const paletteVariables = extractVariables('./src/v2/styles/_palette-variables.scss');
const componentInfos = extractComponents('./src/v2/**/*-@(theme|layout).scss');

const globalThemeVariablesOutput = getGlobalVariablesOutput(globalThemeVariables, 'theme');
const globalLayoutVariablesOutput = getGlobalVariablesOutput(globalLayoutVariables, 'layout');
const componentVariablesOutput = getComponentVariablesOutput(componentVariables);
const paletteVariablesOutput = getPaletteVariablesOutput(paletteVariables);
const globalThemeVariablesOutput = getGlobalVariablesOutput('theme');
const globalLayoutVariablesOutput = getGlobalVariablesOutput('layout');
const componentVariablesOutput = getComponentVariablesOutput(componentInfos);

const updateAutogeneratedSlot = (
templateFilePath: string,
Expand All @@ -23,13 +19,6 @@ const updateAutogeneratedSlot = (
fs.writeFileSync(targetFilePath, targetContent, 'utf8');
};

updateAutogeneratedSlot(
`./doc-templates/palette-variables.template.mdx`,
`[//]: # '#SLOT-autogenerated-palette-variables'`,
paletteVariablesOutput,
`./docs/theming/palette-variables.mdx`,
);

updateAutogeneratedSlot(
`./doc-templates/global-variables.template.mdx`,
`[//]: # '#SLOT-autogenerated-theme-variables'`,
Expand All @@ -44,7 +33,6 @@ updateAutogeneratedSlot(
`./docs/theming/global-variables.mdx`,
);


updateAutogeneratedSlot(
`./doc-templates/component-variables.template.mdx`,
`[//]: # '#SLOT-autogenerated-component-variables'`,
Expand Down
197 changes: 21 additions & 176 deletions scripts/output.ts
Original file line number Diff line number Diff line change
@@ -1,201 +1,46 @@
import dedent from 'dedent';
import prettier from 'prettier';
import type { VariableGroup, VariableInfo } from './parser';
import type { ComponentInfo } from './parser';
import * as packagejson from '../package.json';

type Column = {
name: string;
key: keyof VariableInfo | 'usedIn';
type: 'code' | 'text' | 'values';
};
type Group = { name: string; regexp: RegExp; columns: Column[]; definedIn?: Function };

const row = (v: VariableInfo, group: Group) => {
const usedIn = [...v.referencedIn].map(componentThemeLink).join(', ');
const info = { ...v, usedIn };
return dedent`${group.columns.map((c) => `| ${getColumn(c, info)}`).join('')}|`;
};

const getColumn = (column: Column, info: VariableInfo & { usedIn?: string }) => {
if (column.type === 'values') {
return getValuesColumn(info);
} else {
return getTextOrCodeColumn(column, info);
}
};

const getValuesColumn = (info: VariableInfo & { usedIn?: string }) => {
return `<table>${info.values
.map((v) => `<tr><th>\`${v.scope}\`</th></tr><tr><td>\`${v.value}\`</td></tr>`)
.join('')}</table>`;
};

const getTextOrCodeColumn = (column: Column, info: VariableInfo & { usedIn?: string }) => {
return `${column.type === 'code' ? '`' : ''}${info[column.key] || ''}${
column.type === 'code' ? '`' : ''
}`;
};

export const getGlobalVariablesOutput = (
data: Map<string, VariableInfo>,
type: 'theme' | 'layout',
) => {
const nameColumn: Column = { name: 'Name', key: 'name', type: 'code' };
const valueColumn: Column = { name: 'Value(s)', key: 'values', type: 'values' };
const descriptionColumn: Column = { name: 'Description', key: 'description', type: 'text' };
const usedInColumn: Column = { name: 'Used in', key: 'usedIn', type: 'text' };

const groups = [
{
name: 'Colors',
regexp: /color/,
columns: [nameColumn, valueColumn, descriptionColumn, usedInColumn],
},
{
name: 'Typography',
regexp: /(__font|-text)/,
columns: [nameColumn, valueColumn, descriptionColumn, usedInColumn],
},
{ name: 'Spacing', regexp: /spacing/, columns: [nameColumn, valueColumn, descriptionColumn] },
{
name: 'Radius',
regexp: /__border-radius/,
columns: [nameColumn, valueColumn, descriptionColumn, usedInColumn],
},
{ name: 'Others', regexp: /.*/, columns: [nameColumn, valueColumn, descriptionColumn] },
];

const variablesByGroups: Map<Group, string[]> = new Map();

data.forEach((variable) => {
for (const group of groups) {
if (group.regexp.test(variable.name)) {
if (!variablesByGroups.get(group)) {
variablesByGroups.set(group, []);
}
variablesByGroups.get(group)!.push(row(variable, group));
break;
}
}
});

let output = '';
groups.forEach((group) => {
if (variablesByGroups.get(group)) {
const header =
group.columns.map((c) => `| ${c.name}`).join('') +
`| \n` +
group.columns.map(() => '|-').join('') +
`|`;
output += dedent`
### ${group.name}
${header}
${variablesByGroups.get(group)!.join('\n')}\n\n`;
}
});

output += `All global ${type} variables are defined in: [https://github.com/GetStream/stream-chat-css/tree/v${packagejson.version}/src/v2/styles/_global-${type}-variables.scss](https://github.com/GetStream/stream-chat-css/tree/v${packagejson.version}/src/v2/styles/_global-${type}-variables.scss)\n\n`;
export const getGlobalVariablesOutput = (type: 'theme' | 'layout') => {
const output = `([list of global ${type} variables](https://github.com/GetStream/stream-chat-css/tree/v${packagejson.version}/src/v2/styles/_global-${type}-variables.scss))`;

return format(output);
};

export const getComponentVariablesOutput = (data: Map<string, VariableInfo>) => {
const nameColumn: Column = { name: 'Name', key: 'name', type: 'code' };
const valueColumn: Column = { name: 'Value(s)', key: 'values', type: 'values' };
const descriptionColumn: Column = { name: 'Description', key: 'description', type: 'text' };

const subgroupDefinitions = [
{
name: 'Theme variables',
regexp: /color|border|box-shadow|overlay|background/,
columns: [nameColumn, valueColumn, descriptionColumn],
definedIn: componentThemeLink,
},
{
name: 'Layout variables',
regexp: /.*/,
columns: [nameColumn, valueColumn, descriptionColumn],
definedIn: componentLayoutLink,
},
];

const componentsGroups: Map<VariableGroup, Map<Group, string[]>> = new Map();
data.forEach((v) => {
const variableGroup = v.definedIn;
if (variableGroup) {
let existingVariableGroup = Array.from(componentsGroups.keys()).find(
(g) => g.componentName === variableGroup.componentName,
);
if (!existingVariableGroup) {
componentsGroups.set(variableGroup, new Map());
existingVariableGroup = variableGroup;
}
const componentGroup = componentsGroups.get(existingVariableGroup)!;
const subgroup = subgroupDefinitions.find((subgroup) => subgroup.regexp.test(v.name));
if (subgroup) {
if (!componentGroup.get(subgroup)) {
componentGroup.set(subgroup, []);
}
componentGroup.get(subgroup)?.push(row(v, subgroup));
}
}
});

let output = '';
Array.from(componentsGroups.entries())
.sort((e1, e2) => e1[0].componentName.localeCompare(e2[0].componentName))
.forEach(([variableGroup, variablesBySubgroups]) => {
output += dedent`
## ${variableGroup.componentName}${
variableGroup.sdkRestriction
? ` - Only available in ${variableGroup.sdkRestriction} SDK`
: ''
}\n`;

subgroupDefinitions.forEach((group) => {
if (variablesBySubgroups.get(group)) {
const header =
group.columns.map((c) => `| ${c.name}`).join('') +
`| \n` +
group.columns.map(() => '|-').join('') +
`|`;
output += dedent`
### ${group.name}
${header}
${variablesBySubgroups.get(group)!.join('\n')}\n
Defined in: ${group.definedIn(variableGroup.componentName)}\n\n`;
}
});
export const getComponentVariablesOutput = (componentInfos: ComponentInfo[]) => {
const header = `Component name | Variables | \n |-|-| \n`;
let output = header;
componentInfos
.sort((e1, e2) => e1.name.localeCompare(e2.name))
.forEach((componentInfo) => {
output += dedent`\`${componentInfo.name}\`${
componentInfo.sdkRestriction ? ` (${componentInfo.sdkRestriction} SDK only)` : ''
} | ${componentInfo.variableTypes
.map((t) =>
t === 'theme'
? componentThemeLink(componentInfo.name)
: componentLayoutLink(componentInfo.name),
)
.join(', ')}|`;
output += `\n`;
});

return format(output);
};

export const getPaletteVariablesOutput = (data: Map<string, VariableInfo>) => {
const row = (variableInfo: VariableInfo) => {
return `| \`${variableInfo.name}\` | ${getValuesColumn(variableInfo)} |`;
};
const rows = Array.from(data.values()).map(row);

let output = dedent`
| Name | Value(s) |
|------|-------|
${rows.join('\n')}`;

return format(output);
};

const componentThemeLink = (componentName: string) => {
const pathInRepo = `https://github.com/GetStream/stream-chat-css/tree/v${packagejson.version}/src/v2/styles/`;
return `[${componentName}](${pathInRepo}#COMP#/#COMP#-theme.scss)`.replaceAll(
return `[theme variables](${pathInRepo}#COMP#/#COMP#-theme.scss)`.replaceAll(
'#COMP#',
componentName,
);
};

const componentLayoutLink = (componentName: string) => {
const pathInRepo = `https://github.com/GetStream/stream-chat-css/tree/v${packagejson.version}/src/v2/styles/`;
return `[${componentName}](${pathInRepo}#COMP#/#COMP#-layout.scss)`.replaceAll(
return `[layout variables](${pathInRepo}#COMP#/#COMP#-layout.scss)`.replaceAll(
'#COMP#',
componentName,
);
Expand Down
Loading
Loading