Patterns · Token export

Token export

Tek kaynak (DTCG JSON) → tüm hedefler (CSS, Tailwind, iOS, Android, Figma). Style Dictionary ile build. Ad-hoc renk/boy değişikliği yapan PR'lar burada başlamalı; başka yerde tanımlanan token geçersiz kabul edilir.

01 · DTCG · tek kaynak

tokens/colors.json
JSON · DTCG
{
  "$schema": "https://design-tokens.org/schema.json",
  "color": {
    "primary": {
      "500": { "$value": "#059669", "$type": "color",
                "$description": "Brand primary · pasta yeşili. Light bg, dark text üzerinde AAA." },
      "600": { "$value": "#047857", "$type": "color" }
    },
    "semantic": {
      "text": {
        "default": { "$value": "{color.neutral.900}", "$type": "color" },
        "muted":   { "$value": "{color.neutral.500}", "$type": "color" }
      }
    }
  },
  "space": {
    "4":  { "$value": "16px", "$type": "dimension" },
    "6":  { "$value": "24px", "$type": "dimension" }
  },
  "radius": {
    "md": { "$value": "8px",  "$type": "dimension" },
    "lg": { "$value": "12px", "$type": "dimension" }
  }
}

02a · CSS variables

/* dist/css/tokens.css · auto-generated, do not edit */
:root {
  /* color · primary */
  --nb-color-primary-500: #059669;
  --nb-color-primary-600: #047857;

  /* color · semantic */
  --nb-color-text-default: #111827;
  --nb-color-text-muted:   #6b7280;

  /* space */
  --nb-space-4: 16px;
  --nb-space-6: 24px;

  /* radius */
  --nb-radius-md: 8px;
  --nb-radius-lg: 12px;
}

[data-theme="dark"] {
  --nb-color-primary-500: #10b981;
  --nb-color-text-default: #fafafa;
  --nb-color-text-muted:   #a1a1aa;
}

02b · Tailwind config

// dist/js/tailwind.tokens.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          500: 'var(--nb-color-primary-500)',
          600: 'var(--nb-color-primary-600)',
        },
        text: {
          DEFAULT: 'var(--nb-color-text-default)',
          muted:   'var(--nb-color-text-muted)',
        },
      },
      spacing: { '4': 'var(--nb-space-4)',
                 '6': 'var(--nb-space-6)' },
      borderRadius: { md: 'var(--nb-radius-md)',
                      lg: 'var(--nb-radius-lg)' },
    },
  },
};

02c · iOS · Swift

// dist/ios/NBTokens.swift
import SwiftUI

enum NBColor {
  static let primary500 = Color("primary-500")
  static let textDefault = Color("text-default")
  static let textMuted   = Color("text-muted")
}
enum NBSpace {
  static let s4: CGFloat = 16
  static let s6: CGFloat = 24
}
enum NBRadius {
  static let md: CGFloat = 8
  static let lg: CGFloat = 12
}

02d · Android · Compose

// dist/android/Tokens.kt
object NBColor {
  val primary500 = Color(0xFF059669)
  val textDefault = Color(0xFF111827)
  val textMuted   = Color(0xFF6B7280)
}
object NBSpace {
  val s4 = 16.dp
  val s6 = 24.dp
}
object NBRadius {
  val md = 8.dp
  val lg = 12.dp
}

03 · Build pipeline

// style-dictionary.config.js
module.exports = {
  source: ['tokens/**/*.json'],
  platforms: {
    css:     { transformGroup: 'css',  buildPath: 'dist/css/',
               files: [{ destination: 'tokens.css', format: 'css/variables' }] },
    tailwind:{ transformGroup: 'js',   buildPath: 'dist/js/',
               files: [{ destination: 'tailwind.tokens.js', format: 'javascript/module' }] },
    ios:     { transformGroup: 'ios-swift', buildPath: 'dist/ios/',
               files: [{ destination: 'NBTokens.swift', format: 'ios-swift/class.swift' }] },
    android: { transformGroup: 'compose', buildPath: 'dist/android/',
               files: [{ destination: 'Tokens.kt', format: 'compose/object' }] },
    figma:   { transformGroup: 'figma',  buildPath: 'dist/figma/',
               files: [{ destination: 'tokens.json', format: 'json/nested' }] }
  }
};

# package.json scripts
# "tokens:build": "style-dictionary build"
# "tokens:watch": "style-dictionary build --watch"

Kurallar

· Tek kaynak: tüm tokenlar tokens/*.json'da. CSS, Swift, Kotlin'de hard-coded değer kabul edilmez (CI'da grep ile bloklanır).
· Naming: kebab-case, alanlar nokta ile (color.primary.500); export'ta platform-prefix (--nb-, NB) eklenir.
· Reference: semantic tokenlar primitive'lere referansla — text.default → neutral.900. Çift değer ("#111827") yasak; tek değişiklikte her iki yer güncellenmez.
· Tema: light/dark için aynı isim, farklı value. CSS'de [data-theme="dark"] selector ile override; iOS'ta Color Asset (Any/Dark); Android'de qualifier.
· Versiyonlama: tokens npm package olarak yayınlanır (@nexberry/tokens). Major bump = breaking (token sil/yeniden adlandır), minor = ekle, patch = value değişimi.
· Figma: Tokens Studio plugin dist/figma/tokens.json'u import eder; designer'lar canlı senkronla çalışır.
· Yasak: PR'da color: #059669, padding: 16px, borderRadius: 8 gibi magic value. Hep var(--nb-*), NBColor.*, NBSpace.*.