dslinter 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/LICENSE +201 -0
  3. package/README.md +104 -0
  4. package/bin/dslinter.mjs +29 -0
  5. package/components.json +20 -0
  6. package/package.json +90 -0
  7. package/src/components/InlineCode.tsx +5 -0
  8. package/src/components/icons.tsx +121 -0
  9. package/src/components/ui/badge.tsx +52 -0
  10. package/src/components/ui/button.tsx +57 -0
  11. package/src/components/ui/checkbox.tsx +25 -0
  12. package/src/components/ui/command.tsx +183 -0
  13. package/src/components/ui/dialog.tsx +156 -0
  14. package/src/components/ui/hover-card.tsx +42 -0
  15. package/src/components/ui/input.tsx +22 -0
  16. package/src/components/ui/label.tsx +19 -0
  17. package/src/components/ui/select.tsx +149 -0
  18. package/src/components/ui/table.tsx +118 -0
  19. package/src/components/ui/toggle-group.tsx +83 -0
  20. package/src/components/ui/toggle.tsx +45 -0
  21. package/src/dashboard/ComponentCatalog.tsx +210 -0
  22. package/src/dashboard/ComponentUsageDetails.tsx +109 -0
  23. package/src/dashboard/DashboardBody.tsx +71 -0
  24. package/src/dashboard/FindingsList.tsx +151 -0
  25. package/src/dashboard/ScoreStrip.tsx +28 -0
  26. package/src/dashboard/TokenWall.tsx +241 -0
  27. package/src/dashboard/aggregate.ts +73 -0
  28. package/src/dashboard/paths.ts +10 -0
  29. package/src/dashboard/useWorkspaceReport.ts +136 -0
  30. package/src/index.ts +67 -0
  31. package/src/lib/utils.ts +6 -0
  32. package/src/playground/definePlayground.tsx +99 -0
  33. package/src/playground/enumerateControlCombinations.test.ts +112 -0
  34. package/src/playground/enumerateControlCombinations.ts +74 -0
  35. package/src/report/a11yForModule.ts +35 -0
  36. package/src/report/codeScoreForModule.ts +41 -0
  37. package/src/report/modulePathMatch.ts +27 -0
  38. package/src/report/tokenStyleFindingsForModule.ts +24 -0
  39. package/src/shell/ComponentPlaygroundPane.tsx +438 -0
  40. package/src/shell/DashboardCommandPalette.tsx +134 -0
  41. package/src/shell/DashboardLayout.tsx +230 -0
  42. package/src/shell/EmptyCard.tsx +21 -0
  43. package/src/shell/GovernancePane.tsx +77 -0
  44. package/src/shell/PlaygroundA11yAndCode.tsx +387 -0
  45. package/src/shell/PlaygroundControlField.tsx +213 -0
  46. package/src/shell/PlaygroundControls.tsx +66 -0
  47. package/src/shell/PlaygroundUsageCode.tsx +51 -0
  48. package/src/shell/PlaygroundVariantMatrix.tsx +68 -0
  49. package/src/shell/Section.tsx +34 -0
  50. package/src/shell/Sidebar.tsx +203 -0
  51. package/src/shell/TokensPane.tsx +26 -0
  52. package/src/shell/controlApiTable.ts +53 -0
  53. package/src/shell/hashRoute.ts +49 -0
  54. package/src/shell/playgroundUsageHighlight.ts +53 -0
  55. package/src/shell/playgroundUsageTwoslash.ts +69 -0
  56. package/src/shell/useHashRoute.ts +29 -0
  57. package/src/styles/dashboard-theme.css +188 -0
  58. package/src/types/controls.ts +62 -0
  59. package/src/types/defaultTailwindTypography.ts +55 -0
  60. package/src/types/playground.ts +21 -0
  61. package/src/types/preview.ts +8 -0
  62. package/src/types/report.ts +116 -0
  63. package/src/types/tokenCatalog.ts +54 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * DSLinter dashboard design tokens + shadcn/ui theme.
3
+ * Host apps import once: `@import "dslinter/theme.css";` after `@import "tailwindcss"` and `@source` for this package.
4
+ */
5
+ @import "tw-animate-css";
6
+ @import "shadcn/tailwind.css";
7
+
8
+ @custom-variant dark (&:is(.dark *));
9
+
10
+ @theme inline {
11
+ --color-background: var(--background);
12
+ --color-foreground: var(--foreground);
13
+ --color-card: var(--card);
14
+ --color-card-foreground: var(--card-foreground);
15
+ --color-popover: var(--popover);
16
+ --color-popover-foreground: var(--popover-foreground);
17
+ --color-primary: var(--primary);
18
+ --color-primary-foreground: var(--primary-foreground);
19
+ --color-secondary: var(--secondary);
20
+ --color-secondary-foreground: var(--secondary-foreground);
21
+ --color-muted: var(--muted);
22
+ --color-muted-foreground: var(--muted-foreground);
23
+ --color-accent: var(--accent);
24
+ --color-accent-foreground: var(--accent-foreground);
25
+ --color-destructive: var(--destructive);
26
+ --color-destructive-foreground: var(--destructive-foreground);
27
+ --color-border: var(--border);
28
+ --color-input: var(--input);
29
+ --color-ring: var(--ring);
30
+ --color-chart-1: var(--chart-1);
31
+ --color-chart-2: var(--chart-2);
32
+ --color-chart-3: var(--chart-3);
33
+ --color-chart-4: var(--chart-4);
34
+ --color-chart-5: var(--chart-5);
35
+ --radius-sm: calc(var(--radius) * 0.6);
36
+ --radius-md: calc(var(--radius) * 0.8);
37
+ --radius-lg: var(--radius);
38
+ --radius-xl: calc(var(--radius) * 1.4);
39
+ --radius-2xl: calc(var(--radius) * 1.8);
40
+ --radius-3xl: calc(var(--radius) * 2.2);
41
+ --radius-4xl: calc(var(--radius) * 2.6);
42
+ --color-sidebar: var(--sidebar);
43
+ --color-sidebar-foreground: var(--sidebar-foreground);
44
+ --color-sidebar-primary: var(--sidebar-primary);
45
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
46
+ --color-sidebar-accent: var(--sidebar-accent);
47
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
48
+ --color-sidebar-border: var(--sidebar-border);
49
+ --color-sidebar-ring: var(--sidebar-ring);
50
+ }
51
+
52
+ @theme {
53
+ --color-primary-muted: #93c5fd;
54
+ --color-surface: #f8fafc;
55
+ --color-surface-elevated: #ffffff;
56
+ --color-surface-border: #e2e8f0;
57
+ --color-danger: #dc2626;
58
+ --color-danger-foreground: #fef2f2;
59
+ --color-success: #15803d;
60
+ --color-success-foreground: #f0fdf4;
61
+ --color-warning: #ca8a04;
62
+ --color-warning-foreground: #422006;
63
+ --spacing-layout-xs: 0.5rem;
64
+ --spacing-layout-sm: 1rem;
65
+ --spacing-layout-md: 1.5rem;
66
+ --spacing-layout-lg: 2rem;
67
+ --radius-ds: 0.5rem;
68
+ --radius-ds-lg: 0.75rem;
69
+ --animate-progress-indeterminate: progress-indeterminate 1.2s ease-in-out
70
+ infinite;
71
+
72
+ --font-sans:
73
+ ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
74
+ "Segoe UI Symbol", "Noto Color Emoji";
75
+ --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
76
+ --font-mono:
77
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
78
+ "Courier New", monospace;
79
+ }
80
+
81
+ @keyframes progress-indeterminate {
82
+ 0% {
83
+ transform: translateX(-100%);
84
+ }
85
+ 100% {
86
+ transform: translateX(350%);
87
+ }
88
+ }
89
+
90
+ :root {
91
+ color-scheme: light;
92
+ --radius: 0.625rem;
93
+ --background: oklch(1 0 0);
94
+ --foreground: oklch(0.145 0 0);
95
+ --card: oklch(1 0 0);
96
+ --card-foreground: oklch(0.145 0 0);
97
+ --popover: oklch(1 0 0);
98
+ --popover-foreground: oklch(0.145 0 0);
99
+ /* Match legacy DSLinter demo primary (blue-600) */
100
+ --primary: oklch(0.488 0.243 264.376);
101
+ --primary-foreground: oklch(0.985 0 0);
102
+ --secondary: oklch(0.97 0 0);
103
+ --secondary-foreground: oklch(0.205 0 0);
104
+ --muted: oklch(0.97 0 0);
105
+ --muted-foreground: oklch(0.556 0 0);
106
+ --accent: oklch(0.97 0 0);
107
+ --accent-foreground: oklch(0.205 0 0);
108
+ --destructive: oklch(0.577 0.245 27.325);
109
+ --destructive-foreground: oklch(0.985 0 0);
110
+ --border: oklch(0.922 0 0);
111
+ --input: oklch(0.922 0 0);
112
+ --ring: oklch(0.488 0.243 264.376);
113
+ --chart-1: oklch(0.646 0.222 41.116);
114
+ --chart-2: oklch(0.6 0.118 184.704);
115
+ --chart-3: oklch(0.398 0.07 227.392);
116
+ --chart-4: oklch(0.828 0.189 84.429);
117
+ --chart-5: oklch(0.769 0.188 70.08);
118
+ --sidebar: oklch(0.985 0 0);
119
+ --sidebar-foreground: oklch(0.145 0 0);
120
+ --sidebar-primary: oklch(0.205 0 0);
121
+ --sidebar-primary-foreground: oklch(0.985 0 0);
122
+ --sidebar-accent: oklch(0.97 0 0);
123
+ --sidebar-accent-foreground: oklch(0.205 0 0);
124
+ --sidebar-border: oklch(0.922 0 0);
125
+ --sidebar-ring: oklch(0.708 0 0);
126
+ }
127
+
128
+ .dark {
129
+ color-scheme: dark;
130
+ --background: oklch(0.145 0 0);
131
+ --foreground: oklch(0.985 0 0);
132
+ --card: oklch(0.205 0 0);
133
+ --card-foreground: oklch(0.985 0 0);
134
+ --popover: oklch(0.205 0 0);
135
+ --popover-foreground: oklch(0.985 0 0);
136
+ --primary: oklch(0.65 0.18 264);
137
+ --primary-foreground: oklch(0.145 0 0);
138
+ --secondary: oklch(0.269 0 0);
139
+ --secondary-foreground: oklch(0.985 0 0);
140
+ --muted: oklch(0.269 0 0);
141
+ --muted-foreground: oklch(0.708 0 0);
142
+ --accent: oklch(0.269 0 0);
143
+ --accent-foreground: oklch(0.985 0 0);
144
+ --destructive: oklch(0.704 0.191 22.216);
145
+ --destructive-foreground: oklch(0.985 0 0);
146
+ --border: oklch(1 0 0 / 10%);
147
+ --input: oklch(1 0 0 / 15%);
148
+ --ring: oklch(0.556 0 0);
149
+ --chart-1: oklch(0.488 0.243 264.376);
150
+ --chart-2: oklch(0.696 0.17 162.48);
151
+ --chart-3: oklch(0.769 0.188 70.08);
152
+ --chart-4: oklch(0.627 0.265 303.9);
153
+ --chart-5: oklch(0.645 0.246 16.439);
154
+ --sidebar: oklch(0.205 0 0);
155
+ --sidebar-foreground: oklch(0.985 0 0);
156
+ --sidebar-primary: oklch(0.488 0.243 264.376);
157
+ --sidebar-primary-foreground: oklch(0.985 0 0);
158
+ --sidebar-accent: oklch(0.269 0 0);
159
+ --sidebar-accent-foreground: oklch(0.985 0 0);
160
+ --sidebar-border: oklch(1 0 0 / 10%);
161
+ --sidebar-ring: oklch(0.556 0 0);
162
+ }
163
+
164
+ @layer base {
165
+ * {
166
+ @apply border-border outline-ring/50;
167
+ }
168
+ body {
169
+ @apply bg-background text-foreground font-sans;
170
+ margin: 0;
171
+ }
172
+ }
173
+
174
+ /** Subtle dot grid for playground preview areas (examples, variant matrix). */
175
+ @layer utilities {
176
+ .ds-playground-dot-surface {
177
+ background-image: radial-gradient(circle, #e2e8f0 1px, transparent 1px);
178
+ background-size: 10px 10px;
179
+ }
180
+
181
+ .dark .ds-playground-dot-surface {
182
+ background-image: radial-gradient(
183
+ circle,
184
+ rgb(148 163 184 / 0.22) 1px,
185
+ transparent 1px
186
+ );
187
+ }
188
+ }
@@ -0,0 +1,62 @@
1
+ /** Values passed from the dashboard control panel into `PlaygroundPreview`. */
2
+ export type PlaygroundArgs = Record<string, string | number | boolean>;
3
+
4
+ export type PlaygroundBooleanControl = {
5
+ key: string;
6
+ label: string;
7
+ type: "boolean";
8
+ default: boolean;
9
+ hint?: string;
10
+ };
11
+
12
+ export type PlaygroundStringControl = {
13
+ key: string;
14
+ label: string;
15
+ type: "string";
16
+ default: string;
17
+ placeholder?: string;
18
+ };
19
+
20
+ export type PlaygroundNumberControl = {
21
+ key: string;
22
+ label: string;
23
+ type: "number";
24
+ default: number;
25
+ min?: number;
26
+ max?: number;
27
+ step?: number;
28
+ };
29
+
30
+ export type PlaygroundSelectControl = {
31
+ key: string;
32
+ label: string;
33
+ type: "select";
34
+ default: string;
35
+ options: { value: string; label: string }[];
36
+ };
37
+
38
+ export type PlaygroundControl =
39
+ | PlaygroundBooleanControl
40
+ | PlaygroundStringControl
41
+ | PlaygroundNumberControl
42
+ | PlaygroundSelectControl;
43
+
44
+ export function defaultArgsFromControls(controls: PlaygroundControl[] | undefined): PlaygroundArgs {
45
+ const out: PlaygroundArgs = {};
46
+ if (!controls) return out;
47
+ for (const c of controls) {
48
+ switch (c.type) {
49
+ case "boolean":
50
+ out[c.key] = c.default;
51
+ break;
52
+ case "string":
53
+ case "select":
54
+ out[c.key] = c.default;
55
+ break;
56
+ case "number":
57
+ out[c.key] = c.default;
58
+ break;
59
+ }
60
+ }
61
+ return out;
62
+ }
@@ -0,0 +1,55 @@
1
+ import type {
2
+ TokenCatalogFontFamily,
3
+ TokenCatalogFontSize,
4
+ TokenCatalogFontWeight,
5
+ } from "./tokenCatalog";
6
+
7
+ /** Tailwind v4 default `text-*` scale (font size / line-height pairing is class-level; values are font-size). */
8
+ export const defaultTailwindFontSizes = [
9
+ { token: "xs", value: "0.75rem (12px)", tw: "text-xs" },
10
+ { token: "sm", value: "0.875rem (14px)", tw: "text-sm" },
11
+ { token: "base", value: "1rem (16px)", tw: "text-base" },
12
+ { token: "lg", value: "1.125rem (18px)", tw: "text-lg" },
13
+ { token: "xl", value: "1.25rem (20px)", tw: "text-xl" },
14
+ { token: "2xl", value: "1.5rem (24px)", tw: "text-2xl" },
15
+ { token: "3xl", value: "1.875rem (30px)", tw: "text-3xl" },
16
+ { token: "4xl", value: "2.25rem (36px)", tw: "text-4xl" },
17
+ { token: "5xl", value: "3rem (48px)", tw: "text-5xl" },
18
+ { token: "6xl", value: "3.75rem (60px)", tw: "text-6xl" },
19
+ { token: "7xl", value: "4.5rem (72px)", tw: "text-7xl" },
20
+ { token: "8xl", value: "6rem (96px)", tw: "text-8xl" },
21
+ { token: "9xl", value: "8rem (128px)", tw: "text-9xl" },
22
+ ] as const satisfies readonly TokenCatalogFontSize[];
23
+
24
+ export const defaultTailwindFontWeights = [
25
+ { token: "thin", tw: "font-thin", value: "100" },
26
+ { token: "extralight", tw: "font-extralight", value: "200" },
27
+ { token: "light", tw: "font-light", value: "300" },
28
+ { token: "normal", tw: "font-normal", value: "400" },
29
+ { token: "medium", tw: "font-medium", value: "500" },
30
+ { token: "semibold", tw: "font-semibold", value: "600" },
31
+ { token: "bold", tw: "font-bold", value: "700" },
32
+ { token: "extrabold", tw: "font-extrabold", value: "800" },
33
+ { token: "black", tw: "font-black", value: "900" },
34
+ ] as const satisfies readonly TokenCatalogFontWeight[];
35
+
36
+ /** Stacks aligned with Tailwind’s default theme fonts — keep in sync with host `@theme --font-*`. */
37
+ export const defaultTailwindFontFamilies = [
38
+ {
39
+ key: "sans",
40
+ tw: "font-sans",
41
+ value:
42
+ 'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
43
+ },
44
+ {
45
+ key: "serif",
46
+ tw: "font-serif",
47
+ value: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
48
+ },
49
+ {
50
+ key: "mono",
51
+ tw: "font-mono",
52
+ value:
53
+ 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
54
+ },
55
+ ] as const satisfies readonly TokenCatalogFontFamily[];
@@ -0,0 +1,21 @@
1
+ import type { PlaygroundArgs, PlaygroundControl } from "./controls";
2
+ import type { PlaygroundPreviewComponent } from "./preview";
3
+
4
+ export type PlaygroundMeta = {
5
+ /** Stable URL segment — matches `PlaygroundSpec.id` from dslint. */
6
+ id: string;
7
+ title: string;
8
+ /** From dslint `playground_groups` config (or manual `definePlayground`). */
9
+ group?: string;
10
+ };
11
+
12
+ export type PlaygroundEntry = {
13
+ id: string;
14
+ meta: PlaygroundMeta;
15
+ modulePath: string;
16
+ /** Optional controls shown above the preview; omit or use `[]` for static demos. */
17
+ controls: PlaygroundControl[];
18
+ /** Optional JSX-ish snippet from current `values` (consumer-defined). */
19
+ usageSnippet?: (values: PlaygroundArgs) => string;
20
+ Preview: PlaygroundPreviewComponent;
21
+ };
@@ -0,0 +1,8 @@
1
+ import type { ComponentType } from "react";
2
+ import type { PlaygroundArgs } from "./controls";
3
+
4
+ export type PlaygroundPreviewProps = {
5
+ values: PlaygroundArgs;
6
+ };
7
+
8
+ export type PlaygroundPreviewComponent = ComponentType<PlaygroundPreviewProps>;
@@ -0,0 +1,116 @@
1
+ /** Mirrors `dslint` WorkspaceReport JSON (serde). */
2
+
3
+ export type DefinitionKind =
4
+ | "function"
5
+ | "class"
6
+ | "const_arrow"
7
+ | "const_function"
8
+ | "wrapped_component"
9
+ | "export_default"
10
+ | "export_default_anonymous";
11
+
12
+ export type Severity = "error" | "warning" | "info";
13
+
14
+ export interface ComponentDefinition {
15
+ name: string;
16
+ kind: DefinitionKind;
17
+ line: number;
18
+ /** Props destructured from the first parameter, when detectable. */
19
+ declared_props?: string[];
20
+ }
21
+
22
+ export interface JsxUsage {
23
+ component: string;
24
+ line: number;
25
+ props: string[];
26
+ /** Statically-known literal prop values (non-literals omitted). */
27
+ prop_values?: Record<string, string>;
28
+ }
29
+
30
+ export interface LintFinding {
31
+ rule_id: string;
32
+ message: string;
33
+ path: string;
34
+ line: number | null;
35
+ severity: Severity;
36
+ }
37
+
38
+ export interface FileScan {
39
+ path: string;
40
+ definitions: ComponentDefinition[];
41
+ usages: JsxUsage[];
42
+ parse_errors: string[];
43
+ findings?: LintFinding[];
44
+ }
45
+
46
+ export interface GovernanceScores {
47
+ design_system_health: number;
48
+ ux_consistency: number;
49
+ accessibility: number;
50
+ maintainability: number;
51
+ }
52
+
53
+ export interface DuplicateComponent {
54
+ name: string;
55
+ locations: string[];
56
+ }
57
+
58
+ /** One individual call-site where a component is referenced. */
59
+ export interface UsageLocation {
60
+ path: string;
61
+ line: number;
62
+ props: string[];
63
+ /** Statically-known literal prop values at this call-site (non-literals omitted). */
64
+ prop_values?: Record<string, string>;
65
+ }
66
+
67
+ export interface UsageSummary {
68
+ component: string;
69
+ reference_count: number;
70
+ file_count: number;
71
+ max_props_on_single_use: number;
72
+ files: string[];
73
+ /** How many call-sites pass each named prop. */
74
+ prop_frequencies?: Record<string, number>;
75
+ /** How many call-sites pass each literal value for each prop. */
76
+ prop_value_frequencies?: Record<string, Record<string, number>>;
77
+ /** Every individual call-site with its file, line, and passed props. */
78
+ usage_locations?: UsageLocation[];
79
+ }
80
+
81
+ export interface OwnershipSummary {
82
+ owner: string;
83
+ files: number;
84
+ definitions: number;
85
+ }
86
+
87
+ /**
88
+ * Simplified prop kind from TypeScript (e.g. demo `merge-playgrounds.mjs`).
89
+ * Dashboard falls back to name heuristics when a key is missing or kind is `unknown`.
90
+ */
91
+ export type DeclaredPropKind = "boolean" | "string" | "number" | "unknown";
92
+
93
+ /** Emitted by dslint for dashboard playgrounds (no per-component TS registration). */
94
+ export interface PlaygroundSpec {
95
+ id: string;
96
+ export_name: string;
97
+ rel_path: string;
98
+ declared_props: string[];
99
+ group?: string | null;
100
+ /**
101
+ * Optional map from prop name to simplified TS kind, filled by tooling that runs the TS checker
102
+ * (demo: `merge-playgrounds.mjs`). Omitted when empty or unavailable.
103
+ */
104
+ declared_prop_kinds?: Partial<Record<string, DeclaredPropKind>>;
105
+ }
106
+
107
+ export interface WorkspaceReport {
108
+ root: string;
109
+ files: FileScan[];
110
+ findings: LintFinding[];
111
+ duplicate_components: DuplicateComponent[];
112
+ usage_by_component: UsageSummary[];
113
+ ownership: OwnershipSummary[];
114
+ scores: GovernanceScores;
115
+ playgrounds?: PlaygroundSpec[];
116
+ }
@@ -0,0 +1,54 @@
1
+ /** Shape expected by `TokenWall` — your app mirrors Tailwind / tokens into this object. */
2
+
3
+ export type TokenCatalogColor = {
4
+ token: string;
5
+ shade: string;
6
+ value: string;
7
+ tw: string;
8
+ };
9
+
10
+ export type TokenCatalogSpacing = {
11
+ token: string;
12
+ value: string;
13
+ tw: string;
14
+ };
15
+
16
+ export type TokenCatalogRadius = {
17
+ token: string;
18
+ value: string;
19
+ tw: string;
20
+ };
21
+
22
+ export type TokenCatalogFontFamily = {
23
+ /** Theme key / utility suffix, e.g. `sans` → `font-sans`. */
24
+ key: string;
25
+ /** Full CSS font-family stack for documentation. */
26
+ value: string;
27
+ tw: string;
28
+ };
29
+
30
+ export type TokenCatalogFontSize = {
31
+ token: string;
32
+ value: string;
33
+ tw: string;
34
+ };
35
+
36
+ export type TokenCatalogFontWeight = {
37
+ token: string;
38
+ tw: string;
39
+ /** Numeric weight for display, e.g. `600`. */
40
+ value?: string;
41
+ };
42
+
43
+ export type TokenCatalogTypography = {
44
+ families: readonly TokenCatalogFontFamily[];
45
+ sizes: readonly TokenCatalogFontSize[];
46
+ weights?: readonly TokenCatalogFontWeight[];
47
+ };
48
+
49
+ export type TokenCatalog = {
50
+ colors: readonly TokenCatalogColor[];
51
+ spacing: readonly TokenCatalogSpacing[];
52
+ radius: readonly TokenCatalogRadius[];
53
+ typography?: TokenCatalogTypography;
54
+ };