{"version":3,"file":"token-value-css.mjs","names":[],"sources":["../src/token-value-css.ts"],"sourcesContent":["import { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/color-formats.ts';\nimport type { SlimListedToken } from '#/snapshot-for-wire.ts';\nimport type { BorderValue, DashedStrokeStyleValue, ShadowLayer } from '#/token-value-types.ts';\n\n/**\n * Display a composite sub-field dimension (shadow offset / blur / spread,\n * border width, …) in the preview tables. Renders `—` for a missing\n * sub-field and falls back to JSON for shapes it doesn't recognize.\n *\n * Distinct from `formatTokenValue`'s internal `formatInternalDimension`,\n * which formats a token's top-level value and has no `—` placeholder — these\n * are the per-layer sample formatters shared by `ShadowPreview` + `BorderPreview`.\n */\nexport function formatDimension(raw: unknown): string {\n  if (raw == null) return '—';\n  if (typeof raw === 'number') return String(raw);\n  if (typeof raw === 'string') return raw;\n  if (typeof raw === 'object') {\n    const v = raw as { value?: unknown; unit?: unknown };\n    if (typeof v.value === 'number' && typeof v.unit === 'string') {\n      return `${v.value}${v.unit}`;\n    }\n  }\n  return JSON.stringify(raw);\n}\n\n/** Display a composite sub-field color via the active format; `—` when absent. */\nexport function formatSubColor(raw: unknown, format: ColorFormat): string {\n  if (raw == null) return '—';\n  return formatColor(raw, format).value;\n}\n\n/**\n * Single-line display string for any DTCG token `$value`. Prefers\n * plugin-css's `previewValue` from the Token Listing for non-color tokens\n * (and for color when the toolbar format is hex); other color formats route\n * through local colorjs.io. A raw primitive `$value` is the fallback only\n * when no `previewValue` is present.\n */\nexport function formatTokenValue(\n  value: unknown,\n  $type: string | undefined,\n  colorFormat: ColorFormat,\n  listing?: SlimListedToken,\n): string {\n  if (value == null) return '';\n\n  const preview = listing?.previewValue;\n  if (preview !== undefined) {\n    const previewStr = typeof preview === 'string' ? cleanFloatNoise(preview) : String(preview);\n    if ($type !== 'color') return previewStr;\n    if (colorFormat === 'hex') return previewStr;\n  }\n\n  if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n    return String(value);\n  }\n\n  switch ($type) {\n    case 'color':\n      return formatColor(value, colorFormat).value;\n    case 'dimension':\n    case 'duration':\n      return formatInternalDimension(value);\n    case 'fontFamily':\n      return formatFontFamily(value);\n    case 'fontWeight':\n    case 'lineHeight':\n    case 'letterSpacing':\n    case 'opacity':\n    case 'number':\n      return formatPrimitive(value);\n    case 'cubicBezier':\n      return formatCubicBezier(value);\n    case 'strokeStyle':\n      return formatStrokeStyle(value);\n    case 'shadow':\n      return formatShadow(value, colorFormat);\n    case 'border':\n      return formatBorder(value, colorFormat);\n    default:\n      return formatUnknown(value);\n  }\n}\n\nfunction formatInternalDimension(v: unknown): string {\n  if (typeof v === 'string' || typeof v === 'number') return String(v);\n  if (v && typeof v === 'object') {\n    const d = v as { value?: unknown; unit?: unknown };\n    if (typeof d.value === 'number' && typeof d.unit === 'string') return `${d.value}${d.unit}`;\n  }\n  return formatUnknown(v);\n}\n\n// The leading `\\d+` is bounded to 15 digits so a long run of digits with no\n// following `.` (adversarial input) can't force catastrophic backtracking;\n// no real dimension/number token has a 16+ digit integer part.\nfunction cleanFloatNoise(s: string): string {\n  return s.replace(/-?\\d{1,15}\\.\\d{8,}/g, (m) => `${+Number(m).toFixed(3)}`);\n}\n\nfunction formatFontFamily(v: unknown): string {\n  if (typeof v === 'string') return v;\n  if (Array.isArray(v)) return v.map(String).join(', ');\n  return formatUnknown(v);\n}\n\nfunction formatPrimitive(v: unknown): string {\n  if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n  return formatUnknown(v);\n}\n\nfunction formatCubicBezier(v: unknown): string {\n  if (Array.isArray(v) && v.length === 4) {\n    return `cubic-bezier(${v.map((n) => (typeof n === 'number' ? n : 0)).join(', ')})`;\n  }\n  return formatUnknown(v);\n}\n\nfunction formatStrokeStyle(v: unknown): string {\n  if (typeof v === 'string') return v;\n  if (v && typeof v === 'object') {\n    const s = v as DashedStrokeStyleValue;\n    const parts: string[] = ['dashed'];\n    if (Array.isArray(s.dashArray)) {\n      parts.push(s.dashArray.map((n) => formatDimension(n)).join(' '));\n    }\n    if (typeof s.lineCap === 'string') parts.push(s.lineCap);\n    return parts.join(' · ');\n  }\n  return formatUnknown(v);\n}\n\nfunction formatShadow(v: unknown, colorFormat: ColorFormat): string {\n  const layers = Array.isArray(v) ? v : [v];\n  const parts = layers.map((layer) => {\n    if (!layer || typeof layer !== 'object') return formatUnknown(layer);\n    const s = layer as ShadowLayer;\n    const pieces = [\n      formatInternalDimension(s.offsetX),\n      formatInternalDimension(s.offsetY),\n      formatInternalDimension(s.blur),\n      formatInternalDimension(s.spread),\n      formatColor(s.color, colorFormat).value,\n    ].filter((p) => p !== '');\n    if (s.inset) pieces.push('inset');\n    return pieces.join(' ');\n  });\n  return parts.join(', ');\n}\n\nfunction formatBorder(v: unknown, colorFormat: ColorFormat): string {\n  if (!v || typeof v !== 'object') return formatUnknown(v);\n  const b = v as BorderValue;\n  const width = formatInternalDimension(b.width);\n  const style = formatPrimitive(b.style);\n  const color = formatColor(b.color, colorFormat).value;\n  return [width, style, color].filter((p) => p !== '').join(' ');\n}\n\nfunction formatUnknown(v: unknown): string {\n  if (v == null) return '';\n  if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n  try {\n    return JSON.stringify(v).slice(0, 120);\n  } catch {\n    return String(v);\n  }\n}\n"],"mappings":"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"}