Skip to content

Commit

Permalink
Merge pull request #163 from GetStream/variable-documentation-enhance…
Browse files Browse the repository at this point in the history
…ment

Variable documentation enhancement
  • Loading branch information
szuperaz authored Aug 8, 2022
2 parents 875c51a + 4076645 commit b0645a0
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 161 deletions.
35 changes: 35 additions & 0 deletions doc-templates/global-variables.template.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
id: global-variables
sidebar_position: 2
title: Global variables
---

import SDKSpecific from './SDKSpecific';

CSS variables are the easiest way to customize the theme. The variables are organized into two layers:

- Global
- Component

This page contains information about the global variables.

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'

All global theme variables are defined in: [https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/\_global-theme-variables.scss](https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/_global-theme-variables.scss)

## Layout variables

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

All global theme variables are defined in: [https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/\_global-layout-variables.scss](https://github.com/GetStream/stream-chat-css/blob/main/src-v2/styles/_global-layout-variables.scss)

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).
2 changes: 1 addition & 1 deletion doc-templates/palette-variables.template.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Palette variables

import SDKSpecific from './SDKSpecific';

A color palette is defined inside the library that used to define default values for the [theme variables](./theme-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 [theme variables](./theme-variables.mdx).
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'

Expand Down
29 changes: 0 additions & 29 deletions doc-templates/theme-variables.template.mdx

This file was deleted.

17 changes: 7 additions & 10 deletions docs/theming/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,25 +86,20 @@ Our theming system has various customization options allowing for both smaller a

CSS variables are the easiest way to customize the theme. The variables are organized into two layers:

- theme
- global
- component

#### Theme variables
#### Global variables

You can use theme layer variables to apply changes to the whole chat UI (as opposed to changing the design of individual components). These variables can be grouped into four categories:
You can use global variables to apply changes to the whole chat UI (as opposed to changing the design of individual components).

- Colors
- Fonts
- Border radiuses
- Spacing (makes the chat UI more spacious/compact)

The [full list of theme variables](./theme-variables.mdx) can be found in our theme variables guide.
The [full list of global variables](./global-variables.mdx) can be found in our global variables guide.

Here is the default chat UI:

<img src={ChatUiScreenshot} width='500' />

Here is how you can customize theme variables:
Here is how you can customize global variables:

<SDKSpecific name="angular">

Expand Down Expand Up @@ -330,6 +325,8 @@ The result will be a minimalistic UI without
- borders
- shadows

Please note that if you're only using the layout rules, you can only use the layout CSS variables.

## Dark and light themes

The default theme has dark and light variants. Here is how you can switch between the different themes:
Expand Down
24 changes: 17 additions & 7 deletions scripts/generate-docs.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as fs from 'fs';
import { extractVariables } from './parser';
import { getComponentVariablesOutput, getPaletteVariablesOutput, getThemeVariablesOutput } from './output';
import { getComponentVariablesOutput, getPaletteVariablesOutput, getGlobalVariablesOutput } from './output';

const themeVariables = extractVariables('./src/v2/styles/_theme-variables.scss');
const componentVariables = extractVariables('./src/v2/**/*-theme.scss', themeVariables);
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 themeVariablesOutput = getThemeVariablesOutput(themeVariables);
const globalThemeVariablesOutput = getGlobalVariablesOutput(globalThemeVariables);
const globalLayoutVariablesOutput = getGlobalVariablesOutput(globalLayoutVariables);
const componentVariablesOutput = getComponentVariablesOutput(componentVariables);
const paletteVariablesOutput = getPaletteVariablesOutput(paletteVariables);

Expand All @@ -29,12 +31,20 @@ updateAutogeneratedSlot(
);

updateAutogeneratedSlot(
`./doc-templates/theme-variables.template.mdx`,
`./doc-templates/global-variables.template.mdx`,
`[//]: # '#SLOT-autogenerated-theme-variables'`,
themeVariablesOutput,
`./docs/theming/theme-variables.mdx`,
globalThemeVariablesOutput,
`./docs/theming/global-variables.mdx`,
);

updateAutogeneratedSlot(
`./docs/theming/global-variables.mdx`,
`[//]: # '#SLOT-autogenerated-layout-variables'`,
globalLayoutVariablesOutput,
`./docs/theming/global-variables.mdx`,
);


updateAutogeneratedSlot(
`./doc-templates/component-variables.template.mdx`,
`[//]: # '#SLOT-autogenerated-component-variables'`,
Expand Down
100 changes: 65 additions & 35 deletions scripts/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import dedent from 'dedent';
import prettier from 'prettier';
import type { VariableGroup, VariableInfo } from './parser';

export const getThemeVariablesOutput = (data: Map<string, VariableInfo>) => {
type Column = {name: string, key: keyof VariableInfo | 'usedIn', type: 'code' | 'text'};
type Group = {name: string, regexp: RegExp, columns: Column[]};

const row = (v: VariableInfo, group: Group) => {
const usedIn = [...v.referencedIn].map(componentLink).join(', ');
const info = {...v, usedIn};
return dedent`${group.columns.map(c => `| ${c.type === 'code' ? '\`' : ''}${info[c.key] || ''}${c.type === 'code' ? '\`' : ''}`).join('')}|`;
};
type Column = {name: string, key: keyof VariableInfo | 'usedIn', type: 'code' | 'text'};
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 => `| ${c.type === 'code' ? '\`' : ''}${info[c.key] || ''}${c.type === 'code' ? '\`' : ''}`).join('')}|`;
};

export const getGlobalVariablesOutput = (data: Map<string, VariableInfo>) => {
const nameColumn: Column = {name: 'Name', key: 'name', type: 'code'};
const valueColumn: Column = {name: 'Value', key: 'value', type: 'code'};
const valueDarkColumn: Column = {name: 'Value (dark mode)', key: 'valueDarkMode', type: 'code'};
Expand All @@ -20,19 +20,20 @@ export const getThemeVariablesOutput = (data: Map<string, VariableInfo>) => {

const groups = [
{name: 'Colors', regexp: /color/, columns: [nameColumn, valueColumn, valueDarkColumn, descriptionColumn, usedInColumn]},
{name: 'Fonts', regexp: /(__font|-text)/, 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();

groups.forEach(g => variablesByGroups.set(g, []));

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;
}
Expand All @@ -41,42 +42,63 @@ export const getThemeVariablesOutput = (data: Map<string, VariableInfo>) => {

let output = '';
groups.forEach(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`;
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`;
}
});

return format(output);
};

export const getComponentVariablesOutput = (data: Map<string, VariableInfo>) => {
const row = (v: VariableInfo) => {
return `| \`${v.name}\` | \`${v.value}\` | ${v.description || ''} |`;
};
const nameColumn: Column = {name: 'Name', key: 'name', type: 'code'};
const valueColumn: Column = {name: 'Value', key: 'value', type: 'code'};
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, string[]> = new Map();
const componentsGroups: Map<VariableGroup, Map<Group, string[]>> = new Map();
data.forEach((v) => {
const componentGroup = v.definedIn;
if (componentGroup) {
if (!componentsGroups.get(componentGroup)) {
componentsGroups.set(componentGroup, []);
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));
}
componentsGroups.get(componentGroup)?.push(row(v));
}
});

let output = '';
Array.from(componentsGroups.entries()).forEach(([variableGroup, rows]) => {
Array.from(componentsGroups.entries()).forEach(([variableGroup, variablesBySubgroups]) => {
output += dedent`
## ${variableGroup.componentName}${variableGroup.sdkRestriction ? ` - Only available in ${variableGroup.sdkRestriction} SDK` : ''}
| Name | Value | Description |
|------|-------|-------------|
${rows.join('\n')}
Defined in: ${componentLink(variableGroup.componentName)}\n\n`;
## ${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`;
}
});
});

return format(output);
Expand All @@ -96,14 +118,22 @@ export const getPaletteVariablesOutput = (data: Map<string, VariableInfo>) => {
return format(output);
};

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

const componentLayoutLink = (componentName: string) => {
const pathInRepo = 'https://github.com/GetStream/stream-chat-css/blob/main/src/v2/styles/';
return `[${componentName}](${pathInRepo}#COMP#/#COMP#-layout.scss)`.replaceAll(
'#COMP#',
componentName,
);
};

const format = (content: string) => {
return prettier.format(content, {
parser: 'markdown',
Expand Down
10 changes: 5 additions & 5 deletions src/v2/styles/AttachmentList/AttachmentList-layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
min-width: 0;

.str-chat__message-attachment--card {
max-width: calc(var(--message-max-width) - var(--str-chat__attachment-margin));
max-width: calc(var(--str-chat__message-max-width) - var(--str-chat__attachment-margin));

.str-chat__message-attachment-card--header {
position: relative;
Expand All @@ -34,8 +34,8 @@

img,
video {
max-width: calc(var(--message-max-width) - 2 * var(--str-chat__attachment-margin));
max-height: var(--message-max-width);
max-width: calc(var(--str-chat__message-max-width) - 2 * var(--str-chat__attachment-margin));
max-height: var(--str-chat__message-max-width);
object-fit: cover;
width: 100%;
height: 100%;
Expand Down Expand Up @@ -63,8 +63,8 @@
grid-template-columns: 50% 50%;
overflow: hidden;
gap: var(--str-chat__spacing-0_5);
max-width: var(--message-max-width);
max-height: var(--message-max-width);
max-width: var(--str-chat__message-max-width);
max-height: var(--str-chat__message-max-width);
margin: var(--str-chat__attachment-margin);

&.str-chat__gallery-two-rows {
Expand Down
17 changes: 9 additions & 8 deletions src/v2/styles/Message/Message-layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,30 @@
.str-chat {
/* The width/height of the message options buttons */
--str-chat__message-options-button-size: calc(var(--str-chat__spacing-px) * 26);

/* The maximum allowed width of the message component */
--str-chat__message-max-width: calc(var(--str-chat__spacing-px) * 480);
}

.str-chat__message {
--message-max-width: calc(var(--str-chat__spacing-px) * 480);

.str-chat__message-bubble {
max-width: var(--message-max-width);
max-width: var(--str-chat__message-max-width);
}
}

.str-chat__message.str-chat__message--has-attachment {
--message-max-width: calc(var(--str-chat__spacing-px) * 300);
--str-chat__message-max-width: calc(var(--str-chat__spacing-px) * 300);

.str-chat__message-bubble {
max-width: var(--message-max-width);
max-width: var(--str-chat__message-max-width);
}
}

.str-chat__quoted-message-preview {
--message-max-width: calc(var(--str-chat__spacing-px) * 180);
--str-chat__message-max-width: calc(var(--str-chat__spacing-px) * 180);

.str-chat__quoted-message-bubble {
max-width: var(--message-max-width);
max-width: var(--str-chat__message-max-width);
}
}

Expand Down Expand Up @@ -311,7 +312,7 @@

.str-chat__message-input {
.str-chat__quoted-message-bubble {
max-height: calc(var(--message-max-width) + calc(var(--str-chat__spacing-px) * 70));
max-height: calc(var(--str-chat__message-max-width) + calc(var(--str-chat__spacing-px) * 70));

.str-chat__quoted-message-text {
max-height: 100%;
Expand Down
Loading

0 comments on commit b0645a0

Please sign in to comment.