Skip to content

Commit

Permalink
feat: extract @solid-design-system/theming package (#708)
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Saile authored Jan 30, 2024
1 parent cad20cb commit ce7f177
Show file tree
Hide file tree
Showing 15 changed files with 426 additions and 15 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ packages/components/src/react
packages/components/src/_components
packages/components/scripts
packages/components/custom-elements-manifest.config.ts
packages/theming/types/
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,9 @@ jobs:
GH_TOKEN: ${{ secrets.PAT_RELEASE_KARL }}
NPM_TOKEN: ${{ secrets.NPM_RELEASE_TOKEN_MARIO_HAMANN }}
run: cd packages/components && pnpm release

- name: (theming) Run Semantic Release
env:
GH_TOKEN: ${{ secrets.PAT_RELEASE_KARL }}
NPM_TOKEN: ${{ secrets.NPM_RELEASE_TOKEN_MARIO_HAMANN }}
run: cd packages/theming && pnpm release
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ The placeholder package provides placeholder images that can be used alongside t

The tokens package contains all the design tokens used in the Solid Design System.

**4. Theming**
The theming package provides a color calculation service for the Solid Design System.

## Quick Start

To get started with the code steps, follow these instructions:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React, { useState, useEffect, useCallback } from 'react';
import { AddonPanel, Form } from '@storybook/components';
import { PARAM_KEY, PANEL_DEFAULTS } from './constants';
import { useGlobals } from '@storybook/manager-api';
import { calculateColorsAsCss } from './colorCalculations';
import theme from '../../../../tokens/src/create-theme.cjs';
import { calculateColorsAsCss } from '@solid-design-system/theming';

const { Textarea, Button } = Form;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Renderer, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/types';
import { useEffect, useGlobals } from '@storybook/preview-api';
import { PARAM_KEY, PANEL_DEFAULTS } from './constants';
import { calculateColorsAsCss } from './colorCalculations';
import theme from 'tailwind-theme';
import { calculateColorsAsCss } from '@solid-design-system/theming';

export const withGlobals = (StoryFn: StoryFunction<Renderer>, context: StoryContext<Renderer>) => {
const [globals] = useGlobals();
Expand Down
2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@
"@storybook/theming": "^7.5.3",
"@storybook/web-components": "^7.5.3",
"@storybook/web-components-vite": "^7.5.3",
"@solid-design-system/theming": "workspace:*",
"@types/mocha": "^10.0.4",
"@types/sinon": "^17.0.1",
"@web/test-runner": "^0.18.0",
"@web/test-runner-commands": "^0.9.0",
"@web/test-runner-playwright": "^0.11.0",
"autoprefixer": "^10.4.16",
"cem-plugin-vs-code-custom-data-generator": "^1.4.2",
"chroma-js": "^2.4.2",
"chromatic": "^10.0.0",
"comment-parser": "^1.4.1",
"cssnano": "^6.0.1",
Expand Down
4 changes: 4 additions & 0 deletions packages/theming/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
.cache
dist
node_modules
3 changes: 3 additions & 0 deletions packages/theming/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Theming

The Solid Design System Theming package provides a color calculation service.
77 changes: 77 additions & 0 deletions packages/theming/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"name": "@solid-design-system/theming",
"version": "0.0.1",
"description": "This package provides a color calculation service for the Solid Design System.",
"main": "./src/index.js",
"scripts": {
"build.types": "tsc --project tsconfig.json",
"release": "semantic-release --tagFormat 'theming/${version}' -e semantic-release-monorepo",
"release.dry": "semantic-release -d --tagFormat 'theming/${version}' -e semantic-release-monorepo"
},
"type": "module",
"exports": {
".": "./src/index.js"
},
"types": "./types/index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/solid-design-system/solid.git",
"directory": "packages/theming"
},
"keywords": [],
"homepage": "https://solid-design-system.fe.union-investment.de/x.x.x/storybook/",
"files": [
"src",
"types"
],
"author": "Union Investment",
"license": "MIT",
"readme": "README.md",
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"semantic-release": "^19.0.5",
"semantic-release-monorepo": "^7.0.5",
"typescript": "5.3.3"
},
"release": {
"branches": [
"main"
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/npm",
{
"npmPublish": true
}
],
[
"@semantic-release/git",
{
"message": "chore(release/theming): ${nextRelease.version} [skip actions]\n\n${nextRelease.notes}",
"assets": [
"CHANGELOG.md",
"package.json"
]
}
],
[
"@semantic-release/github",
{
"successComment": false
}
]
]
},
"dependencies": {
"chroma-js": "^2.4.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ const extractRGB = str => {
};

const calculateLuminanceMap = colorObject => {
let relevantColors = {
const relevantColors = {
accent: { ...colorObject['accent'] },
primary: { ...colorObject['primary'] },
neutral: { ...colorObject['neutral'] }
};

let luminanceMaps = {};
const luminanceMaps = {};

for (let colorType in relevantColors) {
let luminanceMap = {};
for (const colorType in relevantColors) {
const luminanceMap = {};

for (let scale in colorObject[colorType]) {
for (const scale in colorObject[colorType]) {
const rgbStr = extractRGB(colorObject[colorType][scale]);

// If we successfully extracted the RGB string
Expand Down Expand Up @@ -78,7 +78,7 @@ const adjustLuminanceMap = (color, luminanceMap, forcedShade) => {
// Calculate the gradients for the linear adjustment
const gradient = difference / (1000 - referenceShade);

let adjustedLuminanceMap = { ...luminanceMap }; // Clone the original map to avoid mutating it directly
const adjustedLuminanceMap = { ...luminanceMap }; // Clone the original map to avoid mutating it directly

// Apply the linear function to adjust the luminance values
Object.keys(adjustedLuminanceMap).forEach(key => {
Expand Down Expand Up @@ -145,11 +145,34 @@ export const calculateColorsForType = (type, theme, colors, useNormalizedLuminan
return tokens;
};

/**
* Generates CSS custom properties (variables) for color themes based on the provided colors and theme configuration.
* This function calculates the luminance values for each color type (primary, accent, etc.) and creates a color scale.
* The color scales are then transformed into CSS custom properties.
*
* @param {Object} colors - An object containing color definitions (e.g., primary, accent) with their respective hex values.
* @param {Object} theme - Theme object containing color configurations. The @solid-design-system/tokens theme can be used as reference.
* @param {boolean} useNormalizedLuminanceMap - A boolean flag to determine whether to use a normalized luminance map or the calculated one.
* @param {boolean} useForcedShades - A boolean flag to decide if forced shades should be applied.
* @returns {string} A string containing CSS custom properties for the defined color types and their shades.
*
* @example
* // Example usage:
* const colors = { primary: '#ff5733', accent: '#33c3f0', ... };
* const theme = { accentColor: {...}, backgroundColor: {...}, ...};
* const cssProperties = calculateColorsAsCss(colors, theme, true, false);
* console.log(cssProperties); // Outputs CSS custom properties as a string
*/
export const calculateColorsAsCss = (colors, theme, useNormalizedLuminanceMap, useForcedShades) => {
let allTokens = ':root{\n /* Copy & paste into your theme */\n';

Object.keys(colors).forEach(type => {
allTokens += calculateColorsForType(type, theme, colors, useNormalizedLuminanceMap, useForcedShades);
if (type === 'black' || type === 'white') {
// Add the color directly without generating shades
allTokens += ` --sd-color-${type}: ${colors[type]};\n`;
} else {
allTokens += calculateColorsForType(type, theme, colors, useNormalizedLuminanceMap, useForcedShades);
}
});

allTokens += '}';
Expand Down
3 changes: 3 additions & 0 deletions packages/theming/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { calculateColorsAsCss } from './color-calculation';

export { calculateColorsAsCss };
15 changes: 15 additions & 0 deletions packages/theming/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"declaration": true,
"allowJs": true,
"emitDeclarationOnly": true,
"outDir": "./types",
"baseUrl": ".",
"paths": {
"*": ["./src/*"]
}
},
"include": [
"./src/**/*.js",
],
}
13 changes: 13 additions & 0 deletions packages/theming/types/color-calculation.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function calculateColorsForType(
type: any,
theme: any,
colors: any,
useNormalizedLuminanceMap: any,
useForcedShades: any
): string;
export function calculateColorsAsCss(
colors: any,
theme: any,
useNormalizedLuminanceMap: boolean,
useForcedShades: boolean
): string;
2 changes: 2 additions & 0 deletions packages/theming/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { calculateColorsAsCss };
import { calculateColorsAsCss } from './color-calculation';
Loading

0 comments on commit ce7f177

Please sign in to comment.