Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@cobalt-ui/plugin-css

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cobalt-ui/plugin-css - npm Package Compare versions

Comparing version 0.4.3 to 0.5.1

test/fixtures/typography/dist/tokens.css

12

CHANGELOG.md
# @cobalt-ui/plugin-css
## 0.5.1
### Patch Changes
- Update core
## 0.5.0
### Minor Changes
- 8845084: Add typography class support
## 0.4.3

@@ -4,0 +16,0 @@

4

dist/index.d.ts

@@ -26,6 +26,6 @@ import type { ParsedColorToken, ParsedCubicBezierToken, ParsedDimensionToken, ParsedDurationToken, ParsedFileToken, ParsedFontToken, ParsedGradientToken, ParsedShadowToken, ParsedTransitionToken, ParsedTypographyToken, ParsedURLToken, Plugin } from '@cobalt-ui/core';

transform?: Partial<TokenTransformer>;
/** don’t like CSS variable names? Change it! */
transformVariableNames?(id: string): string;
/** prefix variable names */
prefix?: string;
}
export default function css(options?: Options): Plugin;
export {};

@@ -11,3 +11,3 @@ import color from 'better-color-tools';

let filename = options?.filename || './tokens.css';
let format = options?.transformVariableNames || defaultFormatter;
let prefix = options?.prefix || '';
let transform = {

@@ -34,19 +34,28 @@ ...(options?.transform || {}),

transform.gradient = transformGradient;
if (!transform.typography)
transform.typography = transformTypography;
if (!transform.transition)
transform.transition = transformTransition;
const i = new Indenter();
function defaultFormatter(id) {
return id.replace(DOT_UNDER_GLOB_RE, '-');
}
function makeVars(tokens, wrapper = ':root', indentLv = 0) {
function makeVars(tokens, indentLv = 0, generateRoot = false) {
const output = [];
output.push(i.indent(`${wrapper} {`, indentLv));
if (generateRoot)
output.push(i.indent(':root {', indentLv));
for (const [id, value] of Object.entries(tokens)) {
output.push(i.indent(`${format(id).replace(DASH_PREFIX_RE, '--')}: ${value};`, indentLv + 1));
output.push(i.indent(`${id.replace(DASH_PREFIX_RE, `--${prefix}`).replace(DOT_UNDER_GLOB_RE, '-')}: ${value};`, indentLv + (generateRoot ? 1 : 0)));
}
output.push(i.indent('}', indentLv));
if (generateRoot)
output.push(i.indent('}', indentLv));
return output;
}
function makeTypography(tokens, indentLv = 0) {
const output = [];
for (const [id, properties] of Object.entries(tokens)) {
output.push('');
output.push(i.indent(`.${id.replace(DOT_UNDER_GLOB_RE, '-')} {`, indentLv));
for (const [property, value] of Object.entries(properties)) {
output.push(i.indent(`${property}: ${Array.isArray(value) ? formatFontNames(value) : value};`, indentLv + 1));
}
output.push(i.indent('}', indentLv));
}
return output;
}
function makeP3(input) {

@@ -77,6 +86,29 @@ const output = [];

const tokenVals = {};
const typographyVals = {};
const modeVals = {};
const typographyModeVals = {};
const selectors = [];
// transformation (1 pass through all tokens + modes)
for (const token of tokens) {
// exception: typography tokens require CSS classes
if (token.type === 'typography') {
typographyVals[token.id] = token.value;
if (token.mode && options?.modeSelectors) {
for (let [modeID, modeSelectors] of Object.entries(options.modeSelectors)) {
const [groupRoot, modeName] = parseModeSelector(modeID);
if ((groupRoot && !token.id.startsWith(groupRoot)) || !token.mode[modeName])
continue;
if (!Array.isArray(selectors))
modeSelectors = [selectors];
for (const selector of modeSelectors) {
if (!selectors.includes(selector))
selectors.push(selector);
if (!modeVals[selector])
modeVals[selector] = {};
typographyModeVals[selector][token.id] = token.mode[modeName];
}
}
}
continue;
}
const transformer = transform[token.type];

@@ -119,7 +151,8 @@ if (!transformer)

code.push('');
code.push(...makeVars(tokenVals));
code.push('');
code.push(...makeVars(tokenVals, 0, true));
code.push(...makeTypography(typographyVals));
// modes
for (const selector of selectors) {
if (!Object.keys(modeVals[selector]).length) {
code.push('');
if (!Object.keys(modeVals[selector]).length && !Object.keys(typographyModeVals[selector]).length) {
// eslint-disable-next-line no-console

@@ -130,31 +163,24 @@ console.warn(`${FG_YELLOW}@cobalt-ui/plugin-css${RESET} can’t find any tokens for "${selector}"`);

const wrapper = selector.trim().replace(SELECTOR_BRACKET_RE, '');
if (selector.startsWith('@')) {
code.push(i.indent(`${wrapper} {`, 0));
code.push(...makeVars(modeVals[selector], ':root', 1));
code.push(i.indent('}', 0));
}
else {
code.push(...makeVars(modeVals[selector], wrapper));
}
code.push(`${wrapper} {`);
if (modeVals[selector])
code.push(...makeVars(modeVals[selector], 1, wrapper.startsWith('@')));
if (typographyModeVals[selector])
code.push(...makeTypography(typographyModeVals[selector], 1));
code.push('}');
}
code.push('');
// P3
if (tokens.some((t) => t.type === 'color' || t.type === 'gradient' || t.type === 'shadow')) {
code.push('');
code.push(i.indent(`@media (color-gamut: p3) {`, 0));
code.push(...makeP3(makeVars(tokenVals, ':root', 1)));
code.push('');
code.push(...makeP3(makeVars(tokenVals, 1, true)));
for (const selector of selectors) {
code.push('');
const wrapper = selector.trim().replace(SELECTOR_BRACKET_RE, '');
if (selector.startsWith('@')) {
code.push(i.indent(`${wrapper} {`, 1));
code.push(...makeP3(makeVars(modeVals[selector], ':root', 2)));
code.push(i.indent('}', 1));
}
else {
code.push(...makeP3(makeVars(modeVals[selector], wrapper, 1)));
}
code.push(i.indent(`${wrapper} {`, 1));
code.push(...makeP3(makeVars(modeVals[selector], 2, wrapper.startsWith('@'))));
code.push(i.indent('}', 1));
}
code.push(i.indent('}', 0));
code.push('');
}
code.push('');
return [

@@ -205,8 +231,2 @@ {

}
/** transform typography */
function transformTypography(value) {
const hasLineHeight = typeof value.lineHeight === 'number' || typeof value.lineHeight === 'string';
let size = value.fontSize || hasLineHeight ? `${value.fontSize}${hasLineHeight ? `/${value.lineHeight}` : ''}` : '';
return [value.fontStyle, value.fontWeight, size, formatFontNames(value.fontName || [])].filter((v) => !!v).join(' ');
}
/** transform transition */

@@ -213,0 +233,0 @@ function transformTransition(value) {

{
"name": "@cobalt-ui/plugin-css",
"description": "Generate CSS from your design tokens schema (requires @cobalt-ui/cli)",
"version": "0.4.3",
"version": "0.5.1",
"author": {

@@ -26,4 +26,4 @@ "name": "Drew Powers",

"devDependencies": {
"@cobalt-ui/cli": "^0.3.7",
"@cobalt-ui/core": "^0.3.4",
"@cobalt-ui/cli": "^0.3.8",
"@cobalt-ui/core": "^0.4.0",
"@types/mime": "^2.0.3",

@@ -30,0 +30,0 @@ "@types/svgo": "^2.6.1",

@@ -14,2 +14,3 @@ import type {

ParsedTypographyToken,
ParsedTypographyValue,
ParsedURLToken,

@@ -51,4 +52,4 @@ Plugin,

transform?: Partial<TokenTransformer>;
/** don’t like CSS variable names? Change it! */
transformVariableNames?(id: string): string;
/** prefix variable names */
prefix?: string;
}

@@ -59,3 +60,3 @@

let filename = options?.filename || './tokens.css';
let format = options?.transformVariableNames || defaultFormatter;
let prefix = options?.prefix || '';
let transform = {

@@ -73,3 +74,2 @@ ...(options?.transform || {}),

if (!transform.gradient) transform.gradient = transformGradient;
if (!transform.typography) transform.typography = transformTypography;
if (!transform.transition) transform.transition = transformTransition;

@@ -79,13 +79,22 @@

function defaultFormatter(id: string): string {
return id.replace(DOT_UNDER_GLOB_RE, '-');
function makeVars(tokens: Record<string, any>, indentLv = 0, generateRoot = false): string[] {
const output: string[] = [];
if (generateRoot) output.push(i.indent(':root {', indentLv));
for (const [id, value] of Object.entries(tokens)) {
output.push(i.indent(`${id.replace(DASH_PREFIX_RE, `--${prefix}`).replace(DOT_UNDER_GLOB_RE, '-')}: ${value};`, indentLv + (generateRoot ? 1 : 0)));
}
if (generateRoot) output.push(i.indent('}', indentLv));
return output;
}
function makeVars(tokens: Record<string, any>, wrapper = ':root', indentLv = 0): string[] {
function makeTypography(tokens: Record<string, ParsedTypographyValue>, indentLv = 0): string[] {
const output: string[] = [];
output.push(i.indent(`${wrapper} {`, indentLv));
for (const [id, value] of Object.entries(tokens)) {
output.push(i.indent(`${format(id).replace(DASH_PREFIX_RE, '--')}: ${value};`, indentLv + 1));
for (const [id, properties] of Object.entries(tokens)) {
output.push('');
output.push(i.indent(`.${id.replace(DOT_UNDER_GLOB_RE, '-')} {`, indentLv));
for (const [property, value] of Object.entries(properties)) {
output.push(i.indent(`${property}: ${Array.isArray(value) ? formatFontNames(value) : value};`, indentLv + 1));
}
output.push(i.indent('}', indentLv));
}
output.push(i.indent('}', indentLv));
return output;

@@ -119,3 +128,5 @@ }

const tokenVals: { [id: string]: any } = {};
const typographyVals: { [id: string]: ParsedTypographyValue } = {};
const modeVals: { [selector: string]: { [id: string]: any } } = {};
const typographyModeVals: { [selector: string]: { [id: string]: ParsedTypographyValue } } = {};
const selectors: string[] = [];

@@ -125,2 +136,21 @@

for (const token of tokens) {
// exception: typography tokens require CSS classes
if (token.type === 'typography') {
typographyVals[token.id] = token.value as ParsedTypographyValue;
if (token.mode && options?.modeSelectors) {
for (let [modeID, modeSelectors] of Object.entries(options.modeSelectors)) {
const [groupRoot, modeName] = parseModeSelector(modeID);
if ((groupRoot && !token.id.startsWith(groupRoot)) || !token.mode[modeName]) continue;
if (!Array.isArray(selectors)) modeSelectors = [selectors];
for (const selector of modeSelectors) {
if (!selectors.includes(selector)) selectors.push(selector);
if (!modeVals[selector]) modeVals[selector] = {};
typographyModeVals[selector][token.id] = token.mode[modeName] as ParsedTypographyValue;
}
}
}
continue;
}
const transformer = transform[token.type];

@@ -159,8 +189,9 @@ if (!transformer) throw new Error(`No transformer found for token type "${token.type}"`);

code.push('');
code.push(...makeVars(tokenVals));
code.push('');
code.push(...makeVars(tokenVals, 0, true));
code.push(...makeTypography(typographyVals));
// modes
for (const selector of selectors) {
if (!Object.keys(modeVals[selector]).length) {
code.push('');
if (!Object.keys(modeVals[selector]).length && !Object.keys(typographyModeVals[selector]).length) {
// eslint-disable-next-line no-console

@@ -171,31 +202,25 @@ console.warn(`${FG_YELLOW}@cobalt-ui/plugin-css${RESET} can’t find any tokens for "${selector}"`);

const wrapper = selector.trim().replace(SELECTOR_BRACKET_RE, '');
if (selector.startsWith('@')) {
code.push(i.indent(`${wrapper} {`, 0));
code.push(...makeVars(modeVals[selector], ':root', 1));
code.push(i.indent('}', 0));
} else {
code.push(...makeVars(modeVals[selector], wrapper));
}
code.push(`${wrapper} {`);
if (modeVals[selector]) code.push(...makeVars(modeVals[selector], 1, wrapper.startsWith('@')));
if (typographyModeVals[selector]) code.push(...makeTypography(typographyModeVals[selector], 1));
code.push('}');
}
code.push('');
// P3
if (tokens.some((t) => t.type === 'color' || t.type === 'gradient' || t.type === 'shadow')) {
code.push('');
code.push(i.indent(`@media (color-gamut: p3) {`, 0));
code.push(...makeP3(makeVars(tokenVals, ':root', 1)));
code.push('');
code.push(...makeP3(makeVars(tokenVals, 1, true)));
for (const selector of selectors) {
code.push('');
const wrapper = selector.trim().replace(SELECTOR_BRACKET_RE, '');
if (selector.startsWith('@')) {
code.push(i.indent(`${wrapper} {`, 1));
code.push(...makeP3(makeVars(modeVals[selector], ':root', 2)));
code.push(i.indent('}', 1));
} else {
code.push(...makeP3(makeVars(modeVals[selector], wrapper, 1)));
}
code.push(i.indent(`${wrapper} {`, 1));
code.push(...makeP3(makeVars(modeVals[selector], 2, wrapper.startsWith('@'))));
code.push(i.indent('}', 1));
}
code.push(i.indent('}', 0));
code.push('');
}
code.push('');
return [

@@ -247,8 +272,2 @@ {

}
/** transform typography */
function transformTypography(value: ParsedTypographyToken['value']): string {
const hasLineHeight = typeof value.lineHeight === 'number' || typeof value.lineHeight === 'string';
let size = value.fontSize || hasLineHeight ? `${value.fontSize}${hasLineHeight ? `/${value.lineHeight}` : ''}` : '';
return [value.fontStyle, value.fontWeight, size, formatFontNames((value.fontName as any) || [])].filter((v) => !!v).join(' ');
}
/** transform transition */

@@ -255,0 +274,0 @@ function transformTransition(value: ParsedTransitionToken['value']): string {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc