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

Automate the markdown generation for the CSS variables. #137

Closed
wants to merge 1 commit into from
Closed
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
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"lint": "stylelint '**/*.scss' --max-warnings 0",
"build:ci": "yarn && yarn lint && yarn build",
"start": "yarn build-v1 && sass --watch src/v1/index.scss dist/css/index.css",
"start-v2": "yarn build-v2 && sass --watch src/v2/styles/index.scss dist/v2/css/index.css"
"start-v2": "yarn build-v2 && sass --watch src/v2/styles/index.scss dist/v2/css/index.css",
"build-docs": "sass src/v2/styles/index.scss | ./scripts/generate-variables.mjs"
},
"release": {
"branches": [
Expand Down Expand Up @@ -56,7 +57,9 @@
"sass": "^1.39.2",
"semantic-release": "^18.0.1",
"stylelint": "^13.13.1",
"stylelint-config-sass-guidelines": "^8.0.0"
"stylelint-config-sass-guidelines": "^8.0.0",
"tree-sitter": "^0.20.0",
"tree-sitter-css": "^0.19.0"
},
"files": [
"dist",
Expand Down
177 changes: 177 additions & 0 deletions scripts/generate-variables.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#!/usr/bin/env node

// TODO:
// capture light/dark vars into their own fields
import Parser from 'tree-sitter';
import CSS from 'tree-sitter-css';
import fs from 'fs';
import process from 'process';

process.stdin.on('data', (data) => {
parseCssToVariables(data.toString());
});

function parseCssToVariables(cssCode) {
const parser = new Parser();
parser.setLanguage(CSS);

const VARIABLE_SELECTOR = '.str-chat';
const LIGHT_THEME_SELECTOR = `.str-chat,
.str-chat__theme-light`;
const DARK_THEME_SELECTOR = `.str-chat__theme-dark`;
const commentParser = new RegExp('/\\*\\s*(.+?)(?:\\. )?(Used in.+)?\\s*\\*/');
const colorVariableMatch = new RegExp(/green|blue|red|grey|yellow/);

const unrecognizedCssVariables = [];
const processedCssVariables = {
colors: {},
spacing: [],
borderRadius: [],
font: [],
components: {},
lightTheme: [],
darkTheme: [],
};

const tree = parser.parse(cssCode);

tree.rootNode.children.forEach((child) => {
if (child.type === 'rule_set') {
const selector = child.child(0).text;
if (
selector == VARIABLE_SELECTOR ||
selector == LIGHT_THEME_SELECTOR ||
selector === DARK_THEME_SELECTOR
) {
const contents = child.child(1).children.slice(1, -1);

contents.forEach((child, index) => {
if (child.type === 'declaration') {
if (child.child(0).text.startsWith('--')) {
let comment = { description: '', usage: '' };
if (index > 0) {
let prevNode = contents[index - 1];
if (prevNode.type === 'comment') {
const matches = prevNode.text.match(commentParser);
comment.description = matches[1];
comment.usage = matches[2];
}
}

const varName = child.child(0).text;

const variableInfo = {
varName,
varValue: child.children
.slice(2, -1)
.map((value) => value.text)
.join(' '),
};
if (comment.description) {
variableInfo.description = comment.description;
}
if (comment.usage) {
variableInfo.usage = comment.usage;
}

if (selector === LIGHT_THEME_SELECTOR) {
processedCssVariables.lightTheme.push(variableInfo);
return;
}

if (selector === DARK_THEME_SELECTOR) {
processedCssVariables.darkTheme.push(variableInfo);
return;
}

const colorMatch = varName.match(colorVariableMatch);
if (colorMatch !== null) {
const colorName = colorMatch[0];
if (!processedCssVariables.colors[colorName]) {
processedCssVariables.colors[colorName] = new Array();
}
processedCssVariables.colors[colorName].push(variableInfo);
return;
}

if (varName.includes('__border-radius')) {
processedCssVariables.borderRadius.push(variableInfo);
return;
}

if (varName.includes('__font-family')) {
processedCssVariables.font.push(variableInfo);
return;
}

if (varName.includes('spacing')) {
processedCssVariables.spacing.push(variableInfo);
return;
}

const componentNameMatch = varName.match(
/\--str-chat__(?!primary|secondary|active|on|background|text|disabled|danger)(.+?)-(font|border|box|color|background|hover|selected|margin|overlay|filter)/,
);

if (componentNameMatch !== null) {
const componentName = componentNameMatch[1];
if (!processedCssVariables.components[componentName]) {
processedCssVariables.components[componentName] = [];
}
processedCssVariables.components[componentName].push(variableInfo);
return;
}
unrecognizedCssVariables.push(variableInfo);
}
}
});
}
}
});

// TODO: write those to .mdx files and include them in the docs
console.log(writeVariablesToTable(processedCssVariables.lightTheme));

if (unrecognizedCssVariables.length > 0) {
console.log(
`Unrecognized CSS variables - ${JSON.stringify(unrecognizedCssVariables, null, 2)}`,
);
}
}

function writeVariablesToTable(variables, path) {
const includeDescriptionColumn = variables.some((variable) => variable.description !== undefined);
const includeUsageColumn = variables.some((variable) => variable.usage !== undefined);

const columns = ['Name', 'Default Value'];
if (includeDescriptionColumn) {
columns.push('Description');
}

if (includeUsageColumn) {
columns.push('Used in');
}

const table = `<table>
<thead><tr>${columns.map((col) => `<th>${col}</th>`).join('')}</tr></thead>
<tbody>
${variables
.map((variable) => {
let varMarkup = `<tr><td><code>${variable.varName}</code></td><td>${variable.varValue}</td>`;
if (includeDescriptionColumn) {
varMarkup += `<td>${variable.description || ''}</td>`;
}

if (includeUsageColumn) {
varMarkup += `<td>${variable.usage || ''}</td>`;
}

varMarkup += `</tr>`;
return varMarkup;
})
.join('\n')}
</tbody>
</table>`;

return table;
}
40 changes: 39 additions & 1 deletion src/v2/styles/_theme-variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
}

.str-chat {
// used for elements where sizing is necessary (such as icons, avatar)
/* used for elements where sizing is necessary (such as icons, avatar) */
--str-chat__spacing-px: 1px;
// used for margins, padding
--str-chat__spacing-0_5: 0.125rem;
Expand Down Expand Up @@ -91,49 +91,87 @@

.str-chat,
.str-chat__theme-light {
/* Used for emphasis, brands can inject their main color using this variable. Used in Links, buttons, avatar fallback background, etc. */
--str-chat__primary-color: var(--str-chat__blue500);
/* Used for emphasis, brands can inject their main color using this variable, it has less emphasis than primary color. Used in Selected message reaction background color */
--str-chat__primary-color-low-emphasis: var(--str-chat__blue300);
/* Used to indicate that a UI element with primary color is in an active state. Used in Pressed buttons */
--str-chat__active-primary-color: var(--str-chat__blue600);
/* If the primary color is used as a background, text/icons are displayed in this color. Used in Button color, text on avatar fallback, etc. */
--str-chat__on-primary-color: var(--str-chat__grey50);
/* Used as a background color for the main chat UI components. Used in Channel list background */
--str-chat__background-color: var(--str-chat__grey50);
/* Used as a background color for the main chat UI components. Used in Channel background, message list background, message input background */
--str-chat__secondary-background-color: var(--str-chat__grey50);
/* Used as a background color to give emphasis, but less vibrant than the primary color. Used in Background of messages sent by the current user */
--str-chat__primary-surface-color: var(--str-chat__blue100);
/* A neutral color used to give emphasis to different surfaces. Used in Selected channel preview background, borders */
--str-chat__surface-color: var(--str-chat__grey300);
/* A neutral color used to give emphasis to different surfaces. Used in Background of received messages, reactions, etc. */
--str-chat__secondary-surface-color: var(--str-chat__grey200);
/* The main color used for texts/icons. Used in Messages, channel header, channel title in the channel preview, etc. */
--str-chat__text-color: var(--str-chat__grey950);
/* Used for texts/icons that need less emphasis. Used in The latest message in the channel preview, deleted message text, default icon state, etc. */
--str-chat__text-low-emphasis-color: var(--str-chat__grey500);
/* Used for displaying disabled UI elements (typically buttons). Used in Disabled send button etc. */
--str-chat__disabled-color: var(--str-chat__grey400);
/* Used for text/icon colors if disabled color is used as a background color. Used in Text on disabled send button etc. */
--str-chat__on-disabled-color: var(--str-chat__grey50);
/* Used for error messages, and destructive actions. Used in Delete action label etc. */
--str-chat__danger-color: var(--str-chat__red400);
--str-chat__online-indicator-color: var(--str-chat__green500);
--str-chat__message-highlight-color: var(--str-chat__yellow100);
/* Used for displaying the unread badge. Used in Background of the unread badge */
--str-chat__unread-badge-color: var(--str-chat__red400);
/* Used for text/icon colors if unread badge color is used as a background color. Used in Text on the unread badge */
--str-chat__on-unread-badge-color: var(--str-chat__grey50);
/* The background color used for overlays. Used in Modal overlay color, attachment preview overlay */
--str-chat__overlay-color: rgba(252, 252, 252, 0.9);
/* The background color used for subtle overlays. Used in Image gallery */
--str-chat__secondary-overlay: rgba(0, 0, 0, 0.2);
/* The text/icon color used on subtle overlays. Used in Image gallery */
--str-chat__secondary-overlay-text-color: var(--str-chat__grey50);
}

.str-chat__theme-dark {
/* Used for emphasis, brands can inject their main color using this variable. Used in Links, buttons, avatar fallback background, etc. */
--str-chat__primary-color: var(--str-chat__blue400);
/* Used for emphasis, brands can inject their main color using this variable, it has less emphasis than primary color. Used in Selected message reaction background color */
--str-chat__primary-color-low-emphasis: var(--str-chat__blue700);
/* Used to indicate that a UI element with primary color is in an active state. Used in Pressed buttons */
--str-chat__active-primary-color: var(--str-chat__blue600);
/* If the primary color is used as a background, text/icons are displayed in this color. Used in Button color, text on avatar fallback, etc. */
--str-chat__on-primary-color: var(--str-chat__grey50);
/* Used as a background color for the main chat UI components. Used in Channel list background */
--str-chat__background-color: var(--str-chat__grey950);
/* Used as a background color for the main chat UI components. Used in Channel background, message list background, message input background */
--str-chat__secondary-background-color: var(--str-chat__grey900);
/* Used as a background color to give emphasis, but less vibrant than the primary color. Used in Background of messages sent by the current user */
--str-chat__primary-surface-color: var(--str-chat__blue900);
/* A neutral color used to give emphasis to different surfaces. Used in Selected channel preview background, borders */
--str-chat__surface-color: var(--str-chat__grey700);
/* A neutral color used to give emphasis to different surfaces. Used in Background of received messages, reactions, etc. */
--str-chat__secondary-surface-color: var(--str-chat__grey800);
/* The main color used for texts/icons. Used in Messages, channel header, channel title in the channel preview, etc. */
--str-chat__text-color: var(--str-chat__grey50);
/* Used for texts/icons that need less emphasis. Used in The latest message in the channel preview, deleted message text, default icon state, etc. */
--str-chat__text-low-emphasis-color: var(--str-chat__grey500);
/* Used for displaying disabled UI elements (typically buttons). Used in Disabled send button etc. */
--str-chat__disabled-color: var(--str-chat__grey600);
/* Used for text/icon colors if disabled color is used as a background color. Used in Text on disabled send button etc. */
--str-chat__on-disabled-color: var(--str-chat__grey50);
/* Used for error messages, and destructive actions. Used in Delete action label etc. */
--str-chat__danger-color: var(--str-chat__red600);
--str-chat__online-indicator-color: var(--str-chat__green500);
--str-chat__message-highlight-color: var(--str-chat__yellow900);
/* Used for displaying the unread badge. Used in Background of the unread badge */
--str-chat__unread-badge-color: var(--str-chat__red400);
/* Used for text/icon colors if unread badge color is used as a background color. Used in Text on the unread badge */
--str-chat__on-unread-badge-color: var(--str-chat__grey50);
/* The background color used for overlays. Used in Modal overlay color, attachment preview overlay */
--str-chat__overlay-color: rgba(0, 0, 0, 0.7);
/* The background color used for subtle overlays. Used in Image gallery */
--str-chat__secondary-overlay: rgba(0, 0, 0, 0.4);
/* The text/icon color used on subtle overlays. Used in Image gallery */
--str-chat__secondary-overlay-text-color: var(--str-chat__grey50);
}
Loading