diff --git a/.gitignore b/.gitignore index 80122c579..e1d925764 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ yarn-error.log .idea/* types index.d.ts -computed-colors-*.json -computed-icons.ts \ No newline at end of file +computed-icons.ts +computed-colors.json diff --git a/package.json b/package.json index c20a0d282..c0182d3fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ably/ui", - "version": "14.6.9", + "version": "14.7.0", "description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.", "repository": { "type": "git", diff --git a/scripts/compute-colors.ts b/scripts/compute-colors.ts index 5ad21278c..c4a38e7e9 100644 --- a/scripts/compute-colors.ts +++ b/scripts/compute-colors.ts @@ -1,72 +1,83 @@ import fs from "fs"; import path from "path"; -import { - numericalColors, - variants, - prefixes, - Theme, - ComputedColors, -} from "../src/core/styles/colors/types"; +import { invertTailwindClassVariant } from "../src/core/styles/colors/utils"; +import { colors, prefixes, variants } from "../src/core/styles/colors/types"; -const computeColors = (base: Theme) => { - if (base !== "dark" && base !== "light") { - throw new Error(`Invalid base theme: ${base}. Expected "dark" or "light".`); - } +const directoryPath = path.join(__dirname, "../src"); +const outputPath = path.join( + __dirname, + "../src/core/styles/colors", + "computed-colors.json", +); + +const joinedVariants = variants.join("|"); +const joinedPrefixes = prefixes.join("|"); +const joinedColors = colors.join("|"); +const regex = new RegExp( + `themeColor\\("((${joinedVariants}${joinedPrefixes})-(${joinedColors})-(000|[1-9]00|1[0-3]00))"\\)`, + "g", +); + +const findStringInFiles = (dir: string) => { + const results: string[] = []; + + const readDirectory = (dir: string) => { + let files: string[]; + try { + files = fs.readdirSync(dir); + } catch (error) { + console.error(`Error reading directory ${dir}:`, error); + return; + } + + files.forEach((file) => { + const filePath = path.join(dir, file); + let stat; + try { + stat = fs.statSync(filePath); + } catch (error) { + console.error(`Error accessing ${filePath}:`, error); + return; + } - const colors = {} as ComputedColors; + if (stat.isDirectory()) { + readDirectory(filePath); + } else if (filePath.endsWith(".tsx")) { + let content = ""; + try { + content = fs.readFileSync(filePath, "utf-8"); + const matches = [...content.matchAll(regex)].map((match) => match[1]); - variants.forEach((variant) => - prefixes.forEach((property) => - numericalColors.forEach((colorSet) => - colorSet.map((color, index) => { - if (base === "dark") { - colors[`${variant}${property}-${colorSet[index]}`] = { - light: `${variant}${property}-${colorSet[colorSet.length - index - 1]}`, - }; - } else if (base === "light") { - colors[`${variant}${property}-${colorSet[index]}`] = { - dark: `${variant}${property}-${colorSet[colorSet.length - index - 1]}`, - }; + if (matches.length > 0) { + results.push(...matches); } - }), - ), - ), - ); + } catch (error) { + console.error(`Error reading file ${filePath}:`, error); + return; + } + } + }); + }; - return colors; + readDirectory(dir); + return Array.from(new Set(results)).sort(); }; -const darkOutputPath = path.join( - __dirname, - "../src/core/styles/colors", - "computed-colors-dark.json", -); -const lightOutputPath = path.join( - __dirname, - "../src/core/styles/colors", - "computed-colors-light.json", +const matches = findStringInFiles(directoryPath); + +const flippedMatches = matches.map((match) => + invertTailwindClassVariant(match), ); -async function writeComputedColors() { - try { - await Promise.all([ - fs.promises.writeFile( - darkOutputPath, - JSON.stringify(computeColors("dark"), null, 2), - "utf-8", - ), - fs.promises.writeFile( - lightOutputPath, - JSON.stringify(computeColors("light"), null, 2), - "utf-8", - ), - ]); - console.log( - `🎨 Tailwind theme classes have been computed and written to JSON files.`, - ); - } catch { - console.error(`Error persisting computed colors.`); +try { + const outputDir = path.dirname(outputPath); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); } + fs.writeFileSync(outputPath, JSON.stringify(flippedMatches)); + console.log( + `🎨 Tailwind theme classes have been computed and written to JSON files.`, + ); +} catch (error) { + console.error(`Error persisting computed colors:`, error); } - -writeComputedColors(); diff --git a/src/core/Icon/EncapsulatedIcon.tsx b/src/core/Icon/EncapsulatedIcon.tsx index c2ae698fc..50e993291 100644 --- a/src/core/Icon/EncapsulatedIcon.tsx +++ b/src/core/Icon/EncapsulatedIcon.tsx @@ -1,7 +1,7 @@ import React from "react"; import Icon, { IconProps } from "../Icon"; -import { determineThemeColor } from "../styles/colors/utils"; -import { ColorClass, Theme } from "../styles/colors/types"; +import useTheming from "../hooks/useTheming"; +import { Theme } from "../styles/colors/types"; type EncapsulatedIconProps = { theme?: Theme; @@ -18,7 +18,10 @@ const EncapsulatedIcon = ({ innerClassName, ...iconProps }: EncapsulatedIconProps) => { - const t = (color: ColorClass) => determineThemeColor("dark", theme, color); + const { themeColor } = useTheming({ + baseTheme: "dark", + theme, + }); const numericalSize = parseInt(size, 10); const numericalIconSize = iconSize ? parseInt(iconSize, 10) @@ -26,11 +29,11 @@ const EncapsulatedIcon = ({ return (
{title.content}
@@ -130,7 +132,7 @@ const PricingCards = ({ ) : null}
(descriptionsRef.current[index] = el)}>
@@ -142,18 +144,20 @@ const PricingCards = ({
className={`flex items-end gap-8 ${delimiter ? "@[520px]:flex-col @[520px]:items-start @[920px]:flex-row @[920px]:items-end" : ""}`}
>
{price.amount}
{title}
Ably{" "}
{label}
+