برنامه نویسی

مضامین ایمن از نوع در Tailwind CSS با استفاده از متغیرهای CSS و TypeScript

توسعه جبهه مدرن نیاز به مضامین مقیاس پذیر ، نشانه های طراحی پاسخگو و انعطاف پذیری زمان اجرا دارد. با پیشرفت های اخیر در Tailwind CSS v3.4+، یعنی @theme وت @custom-variant، توسعه دهندگان اکنون می توانند با استفاده از مضامین کاملاً پویا و ایمن از نوع استفاده کنند متغیرهای CSSبا شرحوت منطق JS زمان اجرا صفربشر این مقاله یک استراتژی مضمون را که من به آن ارائه داده ام ، تشریح می کند ، که معتقدم یک رویکرد تمیز و مقیاس پذیر است که در اطراف آن ابزارها ساخته شده است. این امکان پشتیبانی آسان برای حالت های نور/تاریک و فراتر از آن (نور روز ، یکپارچهسازی با سیستمعامل و غیره) را با حداقل پیچیدگی فراهم می کند.

چرا فکر می کنم tailwind.config.js برای مضامین کافی نیست

به طور سنتی ، توسعه دهندگان رنگ ها را تعریف می کنند primaryبا accent، یا background مستقیم tailwind.config.js:

module.exports = {
  theme: {
    colors: {
      primary: '#571089',
      accent: '#ea698b',
    }
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اما در تجربه من ، این محدودیت های مختلفی را معرفی می کند:

  1. بدون دسترسی به زمان اجرا از JavaScript/TypeScript

    • اگر می خواهید از همان استفاده کنید primary رنگ در یک کتابخانه نمودار ، منطق انیمیشن یا ارائه مشروط ، باید کدگذاری را سخت یا کپی کنید.
  2. بدون پشتیبانی مستقیم از مضامین زمان اجرا

    • شما نمی توانید رنگ ها را به صورت پویا تغییر دهید (به عنوان مثال ، بین نور/تاریکی) بدون بازسازی Tailwind یا استفاده از هک های سفارشی.
  3. مقادیر تم پراکنده در چندین مکان

    • شما ممکن است داشته باشید tailwind.config.js، نقشه های SASS/SCSS ، و ثابت JS – باعث سردردهای ضد همبستگی و نگهداری می شود.

راه حل من: تم متمرکز + تولید متغیر CSS

من با ایجاد یک تایپ شده ، به این مسائل پرداختم theme.ts پرونده مانند این:

export const theme = {
  mode: 'light',
  light: {
    color: {
      primary: '#571089',
      primary_light: ['#6411ad', '#6d23b6'],
      primary_deep: ['#47126b'],
      background: '#ffffff',
    },
    font: {
      primary: 'ui-sans-serif, system-ui, sans-serif',
    }
  },
  dark: {
    color: {
      primary: '#571089',
      primary_light: ['#6411ad', '#6d23b6'],
      primary_deep: ['#47126b'],
      background: '#0a0f1c',
    },
    font: {
      primary: 'ui-sans-serif, system-ui, sans-serif',
    }
  }
} as const;
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این فراهم می کند ایمنی نوع Typescript، خودکار بودن و کنترل کامل بر ساختار.

سپس با استفاده از یک اسکریپت ساخت ساده با esbuild، من این شی را استخراج می کنم و تولید می کنم tailwind.css پرونده با پشتیبانی CSS Tailwind بومی:

// theme-generator.ts
import { buildSync } from 'esbuild';
import fs from 'fs';
import path from 'path';

const result = buildSync({
  entryPoints: ['src/config/theme/theme.ts'],
  bundle: true,
  platform: 'node',
  write: false,
  format: 'cjs',
});

const compiled = result.outputFiles[0].text;
const module = { exports: {} };
const func = new Function('module', 'exports', compiled);
func(module, module.exports);
const theme = module.exports.default || module.exports.theme || module.exports;

if (!theme || !theme.light || !theme.dark) {
  console.error('Theme format invalid or missing colors');
  process.exit(1);
}

let css = '/* Do not edit this file, this will be automatically replaced by system */\n@import "tailwindcss";\n@custom-variant dark (&:where(.dark, .dark *));\n\n@theme {\n';

const flatten = (prefix, value, isDark = false) => {
  const convertedPrefix = prefix.split("_").join("-");
  if (Array.isArray(value)) {
    value.forEach((v, i) => {
      css += `    --${convertedPrefix}-${i}${isDark ? '-dark' : ''}: ${v};\n`;
    });
  } else if (typeof value === 'object') {
    Object.entries(value).forEach(([k, v]) => {
      flatten(`${convertedPrefix}-${k}`, v, isDark);
    });
  } else {
    css += `    --${convertedPrefix}${isDark ? '-dark' : ''}: ${value};\n`;
  }
};

Object.entries(theme.light).forEach(([key, value]) => flatten(key, value));
Object.entries(theme.dark).forEach(([key, value]) => flatten(key, value, true));

css += '}';

fs.mkdirSync(path.join('src'), { recursive: true });
fs.writeFileSync(path.join('src', 'tailwind.css'), css);
console.log('✅ Tailwind theme generated at: src/tailwind.css');
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

فایل tailwind.css تولید شده

/* Do not edit this file, this will be automatically replaced by system */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

@theme {
    --color-primary: #571089;
    --color-primary-light-0: #6411ad;
    --color-primary-light-1: #6d23b6;
    --color-primary-light-2: #822faf;
    --color-primary-light-3: #973aa8;
    --color-primary-light-4: #ac46a1;
    --color-primary-deep-0: #47126b;
    --color-accent: #ea698b;
    --color-accent-deep-0: #d55d92;
    --color-accent-deep-1: #c05299;
    --color-accent-deep-2: #c05299;
    --color-background: #ffffff;
    --font-primary: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
    --color-primary-dark: #571089;
    --color-primary-light-0-dark: #6411ad;
    --color-primary-light-1-dark: #6d23b6;
    --color-primary-light-2-dark: #822faf;
    --color-primary-light-3-dark: #973aa8;
    --color-primary-light-4-dark: #ac46a1;
    --color-primary-deep-0-dark: #47126b;
    --color-accent-dark: #ea698b;
    --color-accent-deep-0-dark: #d55d92;
    --color-accent-deep-1-dark: #c05299;
    --color-accent-deep-2-dark: #c05299;
    --color-background-dark: #0a0f1c;
    --font-primary-dark: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این پرونده است تولید شده و به برنامه وارد شده است.

Tailwind + متغیرهای CSS زمان اجرا

با استفاده از این تنظیم ، استفاده بسیار تمیز می شود:

class="bg-primary dark:bg-primary-deep text-accent dark:text-accent-deep"> Hello themed world!

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

نیازی به کدگذاری نام های رنگی سخت و یا پیکربندی مجدد نیست – همه چیز است متمرکز و انعطاف پذیربشر

حالت تاریک آسان و فراتر از آن

با تشکر @custom-variant dark، این ساختار پشتیبانی می کند .dark انتخاب کنندگان خارج از کادر. اما مهمتر از همه ، اضافه کردن حالت های دیگر آسان است:

  • اضافه کردن daylightبا retroبا solarized، یا هر حالت سفارشی به theme.ts
  • برای تولید فیلمنامه را گسترش دهید --color-*--retro متغیرها
  • استفاده کردن class="retro" یا مشابه مضامین ضامن

حالت های تاریک/نور ساده است و در آیندهبشر

چرا حفظ موضوعات متمرکز موضوع

من فکر می کنم تعریف آن بسیار مهم است تمام مقادیر تم در یک مکان – در پیکربندی Tailwind ، پرونده های SCSS و ثابت JS پراکنده نیست. این تنظیم تضمین می کند:

  • ایمنی تایپ در منطق برنامه
  • بدون تکثیر یا رانش
  • تعویض تم در زمان اجرا با به روزرسانی های صفر JS
  • دید کامل به نحوه رفتار سیستم طراحی شما

خلاصه

  • من از تعبیه مستقیم رنگ ها در داخل خودداری می کنم tailwind.config.js
  • من یک تایپ شده را تعریف می کنم theme.ts متغیرهای CSS را از آن تشکیل دهید و تولید کنید
  • من از بومی Tailwind استفاده می کنم @theme وت @custom-variant حمایت
  • این اجازه می دهد تا به بسیاری از حالت های موضوعی (تاریک ، نور روز ، یکپارچهسازی با سیستمعامل و غیره) مقیاس بندی شود

✅ جایزه: جایی که این کمک می کند

  • سفارشی سازی تم داشبورد محور
  • آزمایش A/B زمان اجرا سبک ها
  • ساخت سیستم های توکن به سبک FIGMA با Tailwind

من این تنظیم را مدرن ، مقیاس پذیر و ایمن پیدا کردم. اگر از Tailwind 3.4+ استفاده می کنید ، من آن را بسیار توصیه می کنم.

به من اطلاع دهید که آیا می خواهید یک الگوی GitHub یا الگوی CLI را برای این رویکرد داشته باشید!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا