Skip to content

Commit

Permalink
docs: simplify CSS docs (#309)
Browse files Browse the repository at this point in the history
### 🎯 Goal

With the new documentation design, we want to have nice and crisp docs.
The docs of CSS variables have complex tables that are hard to
understand, and harder to style. To help the docs effort, we're creating
a simplified version of the docs.

If customers don't like the simplified version, we can restore it.
  • Loading branch information
szuperaz authored Sep 12, 2024
1 parent 4ec7b2e commit ebf1aaa
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 303 deletions.
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

0 comments on commit ebf1aaa

Please sign in to comment.