@opencosmos/ui 1.3.1
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.
- package/.claude/CLAUDE.md +239 -0
- package/README.md +161 -0
- package/dist/cli.mjs +151 -0
- package/dist/dates.d.mts +20 -0
- package/dist/dates.d.ts +20 -0
- package/dist/dates.js +240 -0
- package/dist/dates.js.map +1 -0
- package/dist/dates.mjs +203 -0
- package/dist/dates.mjs.map +1 -0
- package/dist/dnd.d.mts +126 -0
- package/dist/dnd.d.ts +126 -0
- package/dist/dnd.js +274 -0
- package/dist/dnd.js.map +1 -0
- package/dist/dnd.mjs +250 -0
- package/dist/dnd.mjs.map +1 -0
- package/dist/fontThemes-Dh8mtXES.d.mts +868 -0
- package/dist/fontThemes-Dh8mtXES.d.ts +868 -0
- package/dist/forms.d.mts +38 -0
- package/dist/forms.d.ts +38 -0
- package/dist/forms.js +198 -0
- package/dist/forms.js.map +1 -0
- package/dist/forms.mjs +159 -0
- package/dist/forms.mjs.map +1 -0
- package/dist/hooks-1b8WaQf1.d.mts +225 -0
- package/dist/hooks-CKW8vE9H.d.ts +225 -0
- package/dist/hooks.d.mts +3 -0
- package/dist/hooks.d.ts +3 -0
- package/dist/hooks.js +971 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.mjs +943 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/index-DscTIrZ2.d.mts +29 -0
- package/dist/index-DscTIrZ2.d.ts +29 -0
- package/dist/index.d.mts +3382 -0
- package/dist/index.d.ts +3382 -0
- package/dist/index.js +15146 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +14802 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers-CXPDMsl7.d.mts +30 -0
- package/dist/providers-Dn_Msjvz.d.ts +30 -0
- package/dist/providers.d.mts +3 -0
- package/dist/providers.d.ts +3 -0
- package/dist/providers.js +1885 -0
- package/dist/providers.js.map +1 -0
- package/dist/providers.mjs +1859 -0
- package/dist/providers.mjs.map +1 -0
- package/dist/tables.d.mts +10 -0
- package/dist/tables.d.ts +10 -0
- package/dist/tables.js +248 -0
- package/dist/tables.js.map +1 -0
- package/dist/tables.mjs +218 -0
- package/dist/tables.mjs.map +1 -0
- package/dist/tokens.d.mts +1065 -0
- package/dist/tokens.d.ts +1065 -0
- package/dist/tokens.js +2637 -0
- package/dist/tokens.js.map +1 -0
- package/dist/tokens.mjs +2555 -0
- package/dist/tokens.mjs.map +1 -0
- package/dist/utils-CIIM7dAC.d.ts +986 -0
- package/dist/utils-Cs04sxth.d.mts +986 -0
- package/dist/utils.d.mts +4 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +874 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +806 -0
- package/dist/utils.mjs.map +1 -0
- package/dist/validation-Bj1ye-v_.d.mts +114 -0
- package/dist/validation-Bj1ye-v_.d.ts +114 -0
- package/dist/webgl.d.mts +104 -0
- package/dist/webgl.d.ts +104 -0
- package/dist/webgl.js +226 -0
- package/dist/webgl.js.map +1 -0
- package/dist/webgl.mjs +195 -0
- package/dist/webgl.mjs.map +1 -0
- package/package.json +267 -0
- package/src/cli.ts +206 -0
- package/src/component-registry.ts +183 -0
- package/src/components/actions/Button.test.tsx +61 -0
- package/src/components/actions/Button.tsx +70 -0
- package/src/components/actions/Link.tsx +78 -0
- package/src/components/actions/Magnetic.tsx +68 -0
- package/src/components/actions/Toggle.test.tsx +40 -0
- package/src/components/actions/Toggle.tsx +47 -0
- package/src/components/actions/ToggleGroup.tsx +70 -0
- package/src/components/actions/index.ts +5 -0
- package/src/components/backgrounds/FaultyTerminal.tsx +426 -0
- package/src/components/backgrounds/OrbBackground.tsx +424 -0
- package/src/components/backgrounds/WarpBackground.tsx +358 -0
- package/src/components/backgrounds/index.ts +3 -0
- package/src/components/blocks/Hero.tsx +142 -0
- package/src/components/blocks/social/OpenGraphCard.tsx +243 -0
- package/src/components/cursor/SplashCursor.tsx +1315 -0
- package/src/components/cursor/TargetCursor.tsx +187 -0
- package/src/components/cursor/index.ts +2 -0
- package/src/components/data-display/AspectImage.tsx +73 -0
- package/src/components/data-display/Avatar.test.tsx +35 -0
- package/src/components/data-display/Avatar.tsx +55 -0
- package/src/components/data-display/Badge.test.tsx +43 -0
- package/src/components/data-display/Badge.tsx +84 -0
- package/src/components/data-display/Brand.tsx +123 -0
- package/src/components/data-display/Calendar.tsx +70 -0
- package/src/components/data-display/Card.test.tsx +92 -0
- package/src/components/data-display/Card.tsx +115 -0
- package/src/components/data-display/Code.tsx +210 -0
- package/src/components/data-display/CollapsibleCodeBlock.tsx +238 -0
- package/src/components/data-display/DataTable.tsx +119 -0
- package/src/components/data-display/DescriptionList.tsx +41 -0
- package/src/components/data-display/GitHubIcon.tsx +44 -0
- package/src/components/data-display/Heading.test.tsx +36 -0
- package/src/components/data-display/Heading.tsx +83 -0
- package/src/components/data-display/StatCard.tsx +195 -0
- package/src/components/data-display/Table.tsx +133 -0
- package/src/components/data-display/Text.test.tsx +48 -0
- package/src/components/data-display/Text.tsx +144 -0
- package/src/components/data-display/Timeline.tsx +194 -0
- package/src/components/data-display/TreeView.tsx +226 -0
- package/src/components/data-display/Typewriter.tsx +119 -0
- package/src/components/data-display/VariableWeightText.tsx +130 -0
- package/src/components/data-display/index.ts +19 -0
- package/src/components/feedback/Alert.test.tsx +44 -0
- package/src/components/feedback/Alert.tsx +65 -0
- package/src/components/feedback/EmptyState.tsx +113 -0
- package/src/components/feedback/Progress.test.tsx +60 -0
- package/src/components/feedback/Progress.tsx +30 -0
- package/src/components/feedback/ProgressBar.tsx +158 -0
- package/src/components/feedback/Skeleton.test.tsx +39 -0
- package/src/components/feedback/Skeleton.tsx +45 -0
- package/src/components/feedback/Sonner.tsx +28 -0
- package/src/components/feedback/Spinner.test.tsx +33 -0
- package/src/components/feedback/Spinner.tsx +99 -0
- package/src/components/feedback/Stepper.tsx +307 -0
- package/src/components/feedback/Toast/Toast.tsx +243 -0
- package/src/components/feedback/Toast/index.ts +2 -0
- package/src/components/feedback/index.ts +9 -0
- package/src/components/forms/Checkbox.test.tsx +40 -0
- package/src/components/forms/Checkbox.tsx +31 -0
- package/src/components/forms/ColorPicker.tsx +118 -0
- package/src/components/forms/Combobox.tsx +96 -0
- package/src/components/forms/DragDrop.tsx +440 -0
- package/src/components/forms/FileUpload.tsx +252 -0
- package/src/components/forms/FilterButton.tsx +65 -0
- package/src/components/forms/Form.tsx +197 -0
- package/src/components/forms/Input.test.tsx +46 -0
- package/src/components/forms/Input.tsx +43 -0
- package/src/components/forms/InputOTP.tsx +81 -0
- package/src/components/forms/Label.test.tsx +20 -0
- package/src/components/forms/Label.tsx +25 -0
- package/src/components/forms/RadioGroup.tsx +51 -0
- package/src/components/forms/SearchBar.tsx +215 -0
- package/src/components/forms/Select.test.tsx +118 -0
- package/src/components/forms/Select.tsx +274 -0
- package/src/components/forms/Slider.tsx +29 -0
- package/src/components/forms/Switch.test.tsx +76 -0
- package/src/components/forms/Switch.tsx +30 -0
- package/src/components/forms/TextField.tsx +152 -0
- package/src/components/forms/Textarea.test.tsx +41 -0
- package/src/components/forms/Textarea.tsx +29 -0
- package/src/components/forms/ThemeSwitcher.tsx +290 -0
- package/src/components/forms/ThemeToggle.tsx +151 -0
- package/src/components/forms/index.ts +19 -0
- package/src/components/layout/Accordion.test.tsx +66 -0
- package/src/components/layout/Accordion.tsx +64 -0
- package/src/components/layout/AspectRatio.tsx +7 -0
- package/src/components/layout/Carousel.tsx +277 -0
- package/src/components/layout/Collapsible.test.tsx +40 -0
- package/src/components/layout/Collapsible.tsx +31 -0
- package/src/components/layout/Container.test.tsx +45 -0
- package/src/components/layout/Container.tsx +99 -0
- package/src/components/layout/CustomizerPanel.tsx +400 -0
- package/src/components/layout/DatePicker.tsx +57 -0
- package/src/components/layout/Footer/Footer.tsx +175 -0
- package/src/components/layout/Footer/index.ts +2 -0
- package/src/components/layout/GlassSurface.tsx +82 -0
- package/src/components/layout/Grid.test.tsx +31 -0
- package/src/components/layout/Grid.tsx +130 -0
- package/src/components/layout/Header/Header.tsx +450 -0
- package/src/components/layout/Header/index.ts +2 -0
- package/src/components/layout/PageLayout.tsx +180 -0
- package/src/components/layout/PageTemplate.tsx +158 -0
- package/src/components/layout/Resizable.tsx +48 -0
- package/src/components/layout/ScrollArea.tsx +53 -0
- package/src/components/layout/Separator.test.tsx +28 -0
- package/src/components/layout/Separator.tsx +29 -0
- package/src/components/layout/Sidebar.tsx +171 -0
- package/src/components/layout/Stack.test.tsx +41 -0
- package/src/components/layout/Stack.tsx +89 -0
- package/src/components/layout/glass-surface.css +60 -0
- package/src/components/layout/index.ts +18 -0
- package/src/components/motion/AnimatedBeam.tsx +159 -0
- package/src/components/navigation/Breadcrumb.test.tsx +57 -0
- package/src/components/navigation/Breadcrumb.tsx +119 -0
- package/src/components/navigation/Breadcrumbs.tsx +221 -0
- package/src/components/navigation/Command.tsx +159 -0
- package/src/components/navigation/Menubar.tsx +115 -0
- package/src/components/navigation/NavLink.tsx +55 -0
- package/src/components/navigation/NavigationMenu.tsx +125 -0
- package/src/components/navigation/Pagination.tsx +121 -0
- package/src/components/navigation/SecondaryNav.tsx +100 -0
- package/src/components/navigation/Tabs.test.tsx +47 -0
- package/src/components/navigation/Tabs.tsx +60 -0
- package/src/components/navigation/TertiaryNav.tsx +90 -0
- package/src/components/navigation/index.ts +10 -0
- package/src/components/overlays/AlertDialog.test.tsx +69 -0
- package/src/components/overlays/AlertDialog.tsx +166 -0
- package/src/components/overlays/ContextMenu.tsx +243 -0
- package/src/components/overlays/Dialog.test.tsx +79 -0
- package/src/components/overlays/Dialog.tsx +158 -0
- package/src/components/overlays/Drawer.tsx +128 -0
- package/src/components/overlays/Dropdown.tsx +253 -0
- package/src/components/overlays/DropdownMenu.tsx +242 -0
- package/src/components/overlays/HoverCard.tsx +32 -0
- package/src/components/overlays/Modal.tsx +250 -0
- package/src/components/overlays/NotificationCenter.tsx +364 -0
- package/src/components/overlays/Popover.test.tsx +40 -0
- package/src/components/overlays/Popover.tsx +46 -0
- package/src/components/overlays/Sheet.tsx +163 -0
- package/src/components/overlays/Tooltip.test.tsx +33 -0
- package/src/components/overlays/Tooltip.tsx +32 -0
- package/src/components/overlays/index.ts +12 -0
- package/src/dates.ts +2 -0
- package/src/dnd.ts +1 -0
- package/src/forms.ts +1 -0
- package/src/globals.css +187 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useForm.ts +247 -0
- package/src/hooks/useMotionPreference.test.ts +102 -0
- package/src/hooks/useMotionPreference.ts +78 -0
- package/src/hooks/useTheme.ts +58 -0
- package/src/hooks.ts +9 -0
- package/src/index.ts +168 -0
- package/src/lib/animations.ts +356 -0
- package/src/lib/breadcrumbs.ts +94 -0
- package/src/lib/colors.ts +493 -0
- package/src/lib/store/customizer.ts +482 -0
- package/src/lib/store/index.ts +3 -0
- package/src/lib/store/theme.ts +55 -0
- package/src/lib/syntax-parser/index.ts +50 -0
- package/src/lib/syntax-parser/patterns.ts +64 -0
- package/src/lib/syntax-parser/tokenizer.ts +117 -0
- package/src/lib/syntax-parser/types.ts +27 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/validation.ts +204 -0
- package/src/lib/webgl/Color.ts +11 -0
- package/src/lib/webgl/Mesh.ts +41 -0
- package/src/lib/webgl/Program.ts +118 -0
- package/src/lib/webgl/Renderer.ts +51 -0
- package/src/lib/webgl/Triangle.ts +27 -0
- package/src/lib/webgl/Vec3.ts +18 -0
- package/src/lib/webgl/index.ts +13 -0
- package/src/nativewind-env.d.ts +1 -0
- package/src/providers/ThemeProvider.tsx +461 -0
- package/src/providers/index.ts +1 -0
- package/src/providers.ts +7 -0
- package/src/tables.ts +1 -0
- package/src/test/setup.ts +39 -0
- package/src/theme.css +158 -0
- package/src/tokens.ts +7 -0
- package/src/utils.ts +12 -0
- package/src/webgl.ts +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opencosmos/ui",
|
|
3
|
+
"version": "1.3.1",
|
|
4
|
+
"description": "Sage Design Engine — Make it Lovable. 100 accessible React components, three themes, user-controlled motion.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Shalom Ormsby",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/shalomormsby/sage-design-engine.git",
|
|
14
|
+
"directory": "packages/ui"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://thesage.dev",
|
|
17
|
+
"bugs": "https://github.com/shalomormsby/sage-design-engine/issues",
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react",
|
|
20
|
+
"components",
|
|
21
|
+
"ui",
|
|
22
|
+
"design-system",
|
|
23
|
+
"tailwind",
|
|
24
|
+
"radix",
|
|
25
|
+
"accessible",
|
|
26
|
+
"themes",
|
|
27
|
+
"mcp",
|
|
28
|
+
"ai"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"bin": {
|
|
34
|
+
"opencosmos-ui": "dist/cli.mjs"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"src",
|
|
39
|
+
".claude",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"import": "./dist/index.mjs",
|
|
46
|
+
"require": "./dist/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./tokens": {
|
|
49
|
+
"types": "./dist/tokens.d.ts",
|
|
50
|
+
"import": "./dist/tokens.mjs",
|
|
51
|
+
"require": "./dist/tokens.js"
|
|
52
|
+
},
|
|
53
|
+
"./hooks": {
|
|
54
|
+
"types": "./dist/hooks.d.ts",
|
|
55
|
+
"import": "./dist/hooks.mjs",
|
|
56
|
+
"require": "./dist/hooks.js"
|
|
57
|
+
},
|
|
58
|
+
"./utils": {
|
|
59
|
+
"types": "./dist/utils.d.ts",
|
|
60
|
+
"import": "./dist/utils.mjs",
|
|
61
|
+
"require": "./dist/utils.js"
|
|
62
|
+
},
|
|
63
|
+
"./providers": {
|
|
64
|
+
"types": "./dist/providers.d.ts",
|
|
65
|
+
"import": "./dist/providers.mjs",
|
|
66
|
+
"require": "./dist/providers.js"
|
|
67
|
+
},
|
|
68
|
+
"./webgl": {
|
|
69
|
+
"types": "./dist/webgl.d.ts",
|
|
70
|
+
"import": "./dist/webgl.mjs",
|
|
71
|
+
"require": "./dist/webgl.js"
|
|
72
|
+
},
|
|
73
|
+
"./forms": {
|
|
74
|
+
"types": "./dist/forms.d.ts",
|
|
75
|
+
"import": "./dist/forms.mjs",
|
|
76
|
+
"require": "./dist/forms.js"
|
|
77
|
+
},
|
|
78
|
+
"./dates": {
|
|
79
|
+
"types": "./dist/dates.d.ts",
|
|
80
|
+
"import": "./dist/dates.mjs",
|
|
81
|
+
"require": "./dist/dates.js"
|
|
82
|
+
},
|
|
83
|
+
"./tables": {
|
|
84
|
+
"types": "./dist/tables.d.ts",
|
|
85
|
+
"import": "./dist/tables.mjs",
|
|
86
|
+
"require": "./dist/tables.js"
|
|
87
|
+
},
|
|
88
|
+
"./dnd": {
|
|
89
|
+
"types": "./dist/dnd.d.ts",
|
|
90
|
+
"import": "./dist/dnd.mjs",
|
|
91
|
+
"require": "./dist/dnd.js"
|
|
92
|
+
},
|
|
93
|
+
"./globals.css": "./src/globals.css",
|
|
94
|
+
"./theme.css": "./src/theme.css"
|
|
95
|
+
},
|
|
96
|
+
"scripts": {
|
|
97
|
+
"build": "tsup",
|
|
98
|
+
"dev": "tsup --watch",
|
|
99
|
+
"lint": "eslint src/",
|
|
100
|
+
"test": "vitest run",
|
|
101
|
+
"test:watch": "vitest",
|
|
102
|
+
"typecheck": "tsc --noEmit",
|
|
103
|
+
"size": "size-limit",
|
|
104
|
+
"size:check": "size-limit --limit"
|
|
105
|
+
},
|
|
106
|
+
"size-limit": [
|
|
107
|
+
{
|
|
108
|
+
"name": "Core (index)",
|
|
109
|
+
"path": "dist/index.mjs",
|
|
110
|
+
"limit": "450 KB"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "WebGL",
|
|
114
|
+
"path": "dist/webgl.mjs",
|
|
115
|
+
"limit": "10 KB"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "Forms",
|
|
119
|
+
"path": "dist/forms.mjs",
|
|
120
|
+
"limit": "11 KB"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "Dates",
|
|
124
|
+
"path": "dist/dates.mjs",
|
|
125
|
+
"limit": "33 KB"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "Tables",
|
|
129
|
+
"path": "dist/tables.mjs",
|
|
130
|
+
"limit": "10 KB"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "DnD",
|
|
134
|
+
"path": "dist/dnd.mjs",
|
|
135
|
+
"limit": "10 KB"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "Hooks",
|
|
139
|
+
"path": "dist/hooks.mjs",
|
|
140
|
+
"limit": "40 KB"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "Providers",
|
|
144
|
+
"path": "dist/providers.mjs",
|
|
145
|
+
"limit": "60 KB"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "Tokens",
|
|
149
|
+
"path": "dist/tokens.mjs",
|
|
150
|
+
"limit": "70 KB"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "Utils",
|
|
154
|
+
"path": "dist/utils.mjs",
|
|
155
|
+
"limit": "25 KB"
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"peerDependencies": {
|
|
159
|
+
"@dnd-kit/core": "^6.3.1",
|
|
160
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
161
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
162
|
+
"@hookform/resolvers": "^3.10.0",
|
|
163
|
+
"@tanstack/react-table": "^8.21.3",
|
|
164
|
+
"date-fns": "^4.1.0",
|
|
165
|
+
"framer-motion": "*",
|
|
166
|
+
"react": "*",
|
|
167
|
+
"react-day-picker": "^9.13.0",
|
|
168
|
+
"react-hook-form": "^7.70.0",
|
|
169
|
+
"zod": "^3.24.1"
|
|
170
|
+
},
|
|
171
|
+
"peerDependenciesMeta": {
|
|
172
|
+
"@dnd-kit/core": {
|
|
173
|
+
"optional": true
|
|
174
|
+
},
|
|
175
|
+
"@dnd-kit/sortable": {
|
|
176
|
+
"optional": true
|
|
177
|
+
},
|
|
178
|
+
"@dnd-kit/utilities": {
|
|
179
|
+
"optional": true
|
|
180
|
+
},
|
|
181
|
+
"@hookform/resolvers": {
|
|
182
|
+
"optional": true
|
|
183
|
+
},
|
|
184
|
+
"@tanstack/react-table": {
|
|
185
|
+
"optional": true
|
|
186
|
+
},
|
|
187
|
+
"date-fns": {
|
|
188
|
+
"optional": true
|
|
189
|
+
},
|
|
190
|
+
"react-day-picker": {
|
|
191
|
+
"optional": true
|
|
192
|
+
},
|
|
193
|
+
"react-hook-form": {
|
|
194
|
+
"optional": true
|
|
195
|
+
},
|
|
196
|
+
"zod": {
|
|
197
|
+
"optional": true
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"dependencies": {
|
|
201
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
202
|
+
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
203
|
+
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
|
204
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
205
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
206
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
207
|
+
"@radix-ui/react-context-menu": "^2.2.16",
|
|
208
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
209
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
210
|
+
"@radix-ui/react-hover-card": "^1.1.15",
|
|
211
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
212
|
+
"@radix-ui/react-menubar": "^1.1.16",
|
|
213
|
+
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
214
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
215
|
+
"@radix-ui/react-progress": "^1.1.8",
|
|
216
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
217
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
218
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
219
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
220
|
+
"@radix-ui/react-slider": "^1.3.6",
|
|
221
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
222
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
223
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
224
|
+
"@radix-ui/react-toggle": "^1.1.10",
|
|
225
|
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
226
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
227
|
+
"class-variance-authority": "^0.7.0",
|
|
228
|
+
"clsx": "^2.1.0",
|
|
229
|
+
"cmdk": "^1.1.1",
|
|
230
|
+
"embla-carousel-react": "^8.6.0",
|
|
231
|
+
"input-otp": "^1.4.2",
|
|
232
|
+
"lucide-react": "^0.562.0",
|
|
233
|
+
"react-dropzone": "^15.0.0",
|
|
234
|
+
"react-resizable-panels": "^4.4.0",
|
|
235
|
+
"sonner": "^2.0.7",
|
|
236
|
+
"tailwind-merge": "^3.0.0",
|
|
237
|
+
"vaul": "^1.1.2",
|
|
238
|
+
"zustand": "^5.0.9"
|
|
239
|
+
},
|
|
240
|
+
"devDependencies": {
|
|
241
|
+
"@dnd-kit/core": "^6.3.1",
|
|
242
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
243
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
244
|
+
"@hookform/resolvers": "^3.10.0",
|
|
245
|
+
"@size-limit/preset-small-lib": "^12.0.0",
|
|
246
|
+
"@tanstack/react-table": "^8.21.3",
|
|
247
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
248
|
+
"@testing-library/react": "^16.3.2",
|
|
249
|
+
"@testing-library/user-event": "^14.6.1",
|
|
250
|
+
"@types/react": "^19",
|
|
251
|
+
"date-fns": "^4.1.0",
|
|
252
|
+
"eslint": "^9.39.2",
|
|
253
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
254
|
+
"framer-motion": "^12.26.2",
|
|
255
|
+
"jsdom": "^28.0.0",
|
|
256
|
+
"react-day-picker": "^9.13.0",
|
|
257
|
+
"react-hook-form": "^7.70.0",
|
|
258
|
+
"size-limit": "^12.0.0",
|
|
259
|
+
"tailwindcss": "^4.0.0",
|
|
260
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
261
|
+
"tsup": "^8.0.0",
|
|
262
|
+
"typescript": "^5.0.0",
|
|
263
|
+
"typescript-eslint": "^8.54.0",
|
|
264
|
+
"vitest": "^4.0.18",
|
|
265
|
+
"zod": "^3.24.1"
|
|
266
|
+
}
|
|
267
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join, dirname, resolve } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Resolve package root (works from dist/cli.js → package root)
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const __filename_ = typeof __filename !== 'undefined' ? __filename : fileURLToPath(import.meta.url);
|
|
9
|
+
const PKG_ROOT = resolve(dirname(__filename_), '..');
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Import transform
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export function transformImports(source: string): string {
|
|
15
|
+
return source
|
|
16
|
+
// ../../lib/utils → ./utils (cn utility — we scaffold it alongside)
|
|
17
|
+
.replace(/from\s+['"]\.\.\/\.\.\/lib\/utils['"]/g, `from './utils'`)
|
|
18
|
+
// ../../lib/* → @opencosmos/ui/utils
|
|
19
|
+
.replace(/from\s+['"]\.\.\/\.\.\/lib\/[^'"]+['"]/g, `from '@opencosmos/ui/utils'`)
|
|
20
|
+
// ../../hooks/* → @opencosmos/ui/hooks
|
|
21
|
+
.replace(/from\s+['"]\.\.\/\.\.\/hooks\/[^'"]+['"]/g, `from '@opencosmos/ui/hooks'`)
|
|
22
|
+
// ../category/Component → @opencosmos/ui (cross-component imports)
|
|
23
|
+
.replace(/from\s+['"]\.\.\/[^.][^'"]*['"]/g, `from '@opencosmos/ui'`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// cn() utility source (scaffolded alongside ejected components)
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
const CN_UTILS_SOURCE = `import { type ClassValue, clsx } from "clsx";
|
|
30
|
+
import { twMerge } from "tailwind-merge";
|
|
31
|
+
|
|
32
|
+
export function cn(...inputs: ClassValue[]) {
|
|
33
|
+
return twMerge(clsx(inputs));
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Scan src/components to find a component file by name (case-insensitive)
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
function findComponent(name: string): { filePath: string; category: string } | null {
|
|
41
|
+
const srcDir = join(PKG_ROOT, 'src', 'components');
|
|
42
|
+
if (!existsSync(srcDir)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const lowerName = name.toLowerCase();
|
|
47
|
+
|
|
48
|
+
for (const category of readdirSync(srcDir)) {
|
|
49
|
+
const categoryPath = join(srcDir, category);
|
|
50
|
+
if (!statSync(categoryPath).isDirectory()) continue;
|
|
51
|
+
|
|
52
|
+
for (const file of readdirSync(categoryPath)) {
|
|
53
|
+
if (file.toLowerCase() === `${lowerName}.tsx` || file.toLowerCase() === `${lowerName}.ts`) {
|
|
54
|
+
return { filePath: join(categoryPath, file), category };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// List all available components grouped by category
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
function listComponents(): void {
|
|
66
|
+
const srcDir = join(PKG_ROOT, 'src', 'components');
|
|
67
|
+
if (!existsSync(srcDir)) {
|
|
68
|
+
console.error('Error: Could not find component source directory.');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('\n @opencosmos/ui — Available Components\n');
|
|
73
|
+
|
|
74
|
+
for (const category of readdirSync(srcDir).sort()) {
|
|
75
|
+
const categoryPath = join(srcDir, category);
|
|
76
|
+
if (!statSync(categoryPath).isDirectory()) continue;
|
|
77
|
+
|
|
78
|
+
const components = readdirSync(categoryPath)
|
|
79
|
+
.filter((f) => f.endsWith('.tsx') && !f.startsWith('index') && !f.includes('.test.'))
|
|
80
|
+
.map((f) => f.replace(/\.tsx$/, ''));
|
|
81
|
+
|
|
82
|
+
if (components.length === 0) continue;
|
|
83
|
+
|
|
84
|
+
console.log(` ${category}/`);
|
|
85
|
+
for (const comp of components.sort()) {
|
|
86
|
+
console.log(` ${comp}`);
|
|
87
|
+
}
|
|
88
|
+
console.log();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Eject a component
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
function ejectComponent(name: string, targetDir: string): void {
|
|
96
|
+
const found = findComponent(name);
|
|
97
|
+
|
|
98
|
+
if (!found) {
|
|
99
|
+
console.error(`\n Error: Component "${name}" not found.\n`);
|
|
100
|
+
console.error(' Run `npx @opencosmos/ui eject --list` to see available components.\n');
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const source = readFileSync(found.filePath, 'utf-8');
|
|
105
|
+
const transformed = transformImports(source);
|
|
106
|
+
|
|
107
|
+
// Ensure target directory exists
|
|
108
|
+
const resolvedDir = resolve(process.cwd(), targetDir);
|
|
109
|
+
mkdirSync(resolvedDir, { recursive: true });
|
|
110
|
+
|
|
111
|
+
// Write transformed component
|
|
112
|
+
const fileName = found.filePath.split('/').pop()!;
|
|
113
|
+
const destPath = join(resolvedDir, fileName);
|
|
114
|
+
writeFileSync(destPath, transformed, 'utf-8');
|
|
115
|
+
|
|
116
|
+
// Scaffold utils.ts if not present
|
|
117
|
+
const utilsPath = join(resolvedDir, 'utils.ts');
|
|
118
|
+
if (!existsSync(utilsPath)) {
|
|
119
|
+
writeFileSync(utilsPath, CN_UTILS_SOURCE, 'utf-8');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Extract external dependencies from the source for user guidance
|
|
123
|
+
const deps = new Set<string>();
|
|
124
|
+
const importRegex = /from\s+['"](@[^/'"]+\/[^'"]+|[^.@/'"][^'"]*)['"]/g;
|
|
125
|
+
let match;
|
|
126
|
+
while ((match = importRegex.exec(source)) !== null) {
|
|
127
|
+
const pkg = match[1];
|
|
128
|
+
// Skip internal @opencosmos imports and react (always present)
|
|
129
|
+
if (pkg.startsWith('@opencosmos/') || pkg === 'react') continue;
|
|
130
|
+
// Normalize scoped packages to package name
|
|
131
|
+
const pkgName = pkg.startsWith('@') ? pkg.split('/').slice(0, 2).join('/') : pkg.split('/')[0];
|
|
132
|
+
deps.add(pkgName);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.log(`\n Ejected ${name} successfully!\n`);
|
|
136
|
+
console.log(` ${destPath}`);
|
|
137
|
+
if (!existsSync(join(resolvedDir, 'utils.ts'))) {
|
|
138
|
+
// utils was just created
|
|
139
|
+
}
|
|
140
|
+
console.log(` ${utilsPath} (cn utility)\n`);
|
|
141
|
+
|
|
142
|
+
if (deps.size > 0) {
|
|
143
|
+
console.log(' Required dependencies:');
|
|
144
|
+
console.log(` pnpm add ${[...deps].sort().join(' ')}\n`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
console.log(' Update your imports:');
|
|
148
|
+
console.log(` import { ${name} } from './${targetDir}/${name}'\n`);
|
|
149
|
+
console.log(' The ejected component still works with @opencosmos/ui themes and CSS variables.');
|
|
150
|
+
console.log(' You now own it — modify freely.\n');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// CLI entry point
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
function main(): void {
|
|
157
|
+
const args = process.argv.slice(2);
|
|
158
|
+
|
|
159
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
160
|
+
console.log(`
|
|
161
|
+
@opencosmos/ui eject — Copy component source into your project
|
|
162
|
+
|
|
163
|
+
Usage:
|
|
164
|
+
npx @opencosmos/ui eject <ComponentName> [--dir <path>]
|
|
165
|
+
npx @opencosmos/ui eject --list
|
|
166
|
+
|
|
167
|
+
Options:
|
|
168
|
+
--dir <path> Target directory (default: src/components/ui)
|
|
169
|
+
--list List all available components
|
|
170
|
+
--help Show this help message
|
|
171
|
+
|
|
172
|
+
Examples:
|
|
173
|
+
npx @opencosmos/ui eject Button
|
|
174
|
+
npx @opencosmos/ui eject Dialog --dir components/sage
|
|
175
|
+
`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (args.includes('--list')) {
|
|
180
|
+
listComponents();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Parse: eject <name> [--dir <path>]
|
|
185
|
+
const command = args[0];
|
|
186
|
+
if (command !== 'eject') {
|
|
187
|
+
console.error(`\n Unknown command: ${command}\n Run with --help for usage.\n`);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const componentName = args[1];
|
|
192
|
+
if (!componentName || componentName.startsWith('--')) {
|
|
193
|
+
console.error('\n Error: Component name is required.\n Usage: npx @opencosmos/ui eject <ComponentName>\n');
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let targetDir = 'src/components/ui';
|
|
198
|
+
const dirIdx = args.indexOf('--dir');
|
|
199
|
+
if (dirIdx !== -1 && args[dirIdx + 1]) {
|
|
200
|
+
targetDir = args[dirIdx + 1];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
ejectComponent(componentName, targetDir);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
main();
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Registry - Source of Truth
|
|
3
|
+
*
|
|
4
|
+
* This file serves as the authoritative source for component counts,
|
|
5
|
+
* categories, and organization. Used by:
|
|
6
|
+
* - Documentation (Sage Studio)
|
|
7
|
+
* - MCP Server registry
|
|
8
|
+
* - Marketing materials
|
|
9
|
+
* - Internal tooling
|
|
10
|
+
*
|
|
11
|
+
* ⚠️ IMPORTANT: When adding a new component, follow the complete workflow:
|
|
12
|
+
* See: /.agent/workflows/register-new-component.md
|
|
13
|
+
*
|
|
14
|
+
* The workflow includes:
|
|
15
|
+
* - Creating the component in packages/ui
|
|
16
|
+
* - Registering in Sage Studio (apps/web)
|
|
17
|
+
* - Updating THIS registry file
|
|
18
|
+
* - Updating MCP server registry
|
|
19
|
+
* - Version bumping and npm publishing
|
|
20
|
+
*
|
|
21
|
+
* Last Updated: 2026-02-28
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export const BRAND = {
|
|
25
|
+
productName: 'Sage Design Engine',
|
|
26
|
+
productNameShort: 'Sage',
|
|
27
|
+
themeNames: {
|
|
28
|
+
organic: 'Terra',
|
|
29
|
+
technical: 'Volt',
|
|
30
|
+
neutral: 'Studio',
|
|
31
|
+
},
|
|
32
|
+
tagline: "The Solopreneur's Development Stack",
|
|
33
|
+
mission: 'AI-Native components for velocity',
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
export const COMPONENT_REGISTRY = {
|
|
37
|
+
/**
|
|
38
|
+
* Total count of all exported UI components from @thesage/ui
|
|
39
|
+
*/
|
|
40
|
+
totalCount: 100,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Core categories following functional organization pattern
|
|
44
|
+
* (what components DO, not abstract hierarchy)
|
|
45
|
+
*/
|
|
46
|
+
coreCategories: {
|
|
47
|
+
actions: {
|
|
48
|
+
count: 5,
|
|
49
|
+
description: 'Components that trigger behavior',
|
|
50
|
+
examples: ['Button', 'Link', 'Toggle', 'ToggleGroup', 'Magnetic'],
|
|
51
|
+
},
|
|
52
|
+
forms: {
|
|
53
|
+
count: 19,
|
|
54
|
+
description: 'Components that collect user input',
|
|
55
|
+
examples: ['Input', 'Select', 'Checkbox', 'Switch', 'Textarea', 'ColorPicker', 'SearchBar', 'FileUpload'],
|
|
56
|
+
},
|
|
57
|
+
navigation: {
|
|
58
|
+
count: 10,
|
|
59
|
+
description: 'Components that help users move through content',
|
|
60
|
+
examples: ['Tabs', 'Breadcrumb', 'Pagination', 'NavigationMenu', 'Command'],
|
|
61
|
+
},
|
|
62
|
+
overlays: {
|
|
63
|
+
count: 12,
|
|
64
|
+
description: 'Components that display contextual content',
|
|
65
|
+
examples: ['Dialog', 'Tooltip', 'Popover', 'Drawer', 'Modal', 'Sheet', 'NotificationCenter'],
|
|
66
|
+
},
|
|
67
|
+
feedback: {
|
|
68
|
+
count: 9,
|
|
69
|
+
description: 'Components that communicate system state',
|
|
70
|
+
examples: ['Alert', 'Toast', 'Progress', 'Spinner', 'Skeleton', 'EmptyState', 'Stepper'],
|
|
71
|
+
},
|
|
72
|
+
'data-display': {
|
|
73
|
+
count: 19,
|
|
74
|
+
description: 'Components that present information',
|
|
75
|
+
examples: ['Card', 'Table', 'Badge', 'Avatar', 'Heading', 'Text', 'Code', 'Calendar', 'StatCard', 'Timeline', 'TreeView'],
|
|
76
|
+
},
|
|
77
|
+
layout: {
|
|
78
|
+
count: 18,
|
|
79
|
+
description: 'Components for spatial organization',
|
|
80
|
+
examples: ['Accordion', 'Separator', 'Stack', 'Grid', 'Container', 'ScrollArea', 'GlassSurface'],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Specialty categories for advanced interactions and effects
|
|
86
|
+
*/
|
|
87
|
+
specialtyCategories: {
|
|
88
|
+
backgrounds: {
|
|
89
|
+
count: 2,
|
|
90
|
+
description: 'Animated background effects',
|
|
91
|
+
examples: ['WarpBackground', 'FaultyTerminal'],
|
|
92
|
+
},
|
|
93
|
+
cursor: {
|
|
94
|
+
count: 2,
|
|
95
|
+
description: 'Interactive cursor effects',
|
|
96
|
+
examples: ['SplashCursor', 'TargetCursor'],
|
|
97
|
+
},
|
|
98
|
+
blocks: {
|
|
99
|
+
count: 1,
|
|
100
|
+
description: 'Composed page blocks',
|
|
101
|
+
examples: ['Hero', 'OpenGraphCard'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Supporting APIs (not counted as components)
|
|
107
|
+
*/
|
|
108
|
+
supportingAPIs: {
|
|
109
|
+
providers: ['ThemeProvider'],
|
|
110
|
+
hooks: ['useTheme', 'useMotionPreference', 'useForm'],
|
|
111
|
+
utilities: ['animations', 'breadcrumbs', 'colors', 'utils', 'validation', 'syntax-parser'],
|
|
112
|
+
stores: ['themeStore', 'customizerStore'],
|
|
113
|
+
},
|
|
114
|
+
} as const;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Computed totals
|
|
118
|
+
*/
|
|
119
|
+
export const COMPONENT_COUNTS = {
|
|
120
|
+
core: Object.values(COMPONENT_REGISTRY.coreCategories).reduce(
|
|
121
|
+
(sum, cat) => sum + cat.count,
|
|
122
|
+
0
|
|
123
|
+
), // 84
|
|
124
|
+
specialty: Object.values(COMPONENT_REGISTRY.specialtyCategories).reduce(
|
|
125
|
+
(sum, cat) => sum + cat.count,
|
|
126
|
+
0
|
|
127
|
+
), // 5
|
|
128
|
+
total: COMPONENT_REGISTRY.totalCount, // 89
|
|
129
|
+
} as const;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Marketing-friendly descriptions
|
|
133
|
+
*/
|
|
134
|
+
export const MARKETING_COPY = {
|
|
135
|
+
short: '100 production-ready components',
|
|
136
|
+
medium: '100 components across 7 core categories, plus specialty backgrounds and motion effects',
|
|
137
|
+
long: '100 thoughtfully designed components organized by function: actions, forms, navigation, overlays, feedback, data display, and layout—plus specialty components for backgrounds, cursor interactions, and animated effects.',
|
|
138
|
+
} as const;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Documentation usage examples
|
|
142
|
+
*/
|
|
143
|
+
export const DOC_EXAMPLES = {
|
|
144
|
+
// For overview sections
|
|
145
|
+
overview: `${COMPONENT_COUNTS.total} components across ${Object.keys(COMPONENT_REGISTRY.coreCategories).length
|
|
146
|
+
} core categories`,
|
|
147
|
+
|
|
148
|
+
// For detailed breakdowns
|
|
149
|
+
breakdown: `
|
|
150
|
+
- **Actions** (${COMPONENT_REGISTRY.coreCategories.actions.count}): ${COMPONENT_REGISTRY.coreCategories.actions.description}
|
|
151
|
+
- **Forms** (${COMPONENT_REGISTRY.coreCategories.forms.count}): ${COMPONENT_REGISTRY.coreCategories.forms.description}
|
|
152
|
+
- **Navigation** (${COMPONENT_REGISTRY.coreCategories.navigation.count}): ${COMPONENT_REGISTRY.coreCategories.navigation.description}
|
|
153
|
+
- **Overlays** (${COMPONENT_REGISTRY.coreCategories.overlays.count}): ${COMPONENT_REGISTRY.coreCategories.overlays.description}
|
|
154
|
+
- **Feedback** (${COMPONENT_REGISTRY.coreCategories.feedback.count}): ${COMPONENT_REGISTRY.coreCategories.feedback.description}
|
|
155
|
+
- **Data Display** (${COMPONENT_REGISTRY.coreCategories['data-display'].count}): ${COMPONENT_REGISTRY.coreCategories['data-display'].description}
|
|
156
|
+
- **Layout** (${COMPONENT_REGISTRY.coreCategories.layout.count}): ${COMPONENT_REGISTRY.coreCategories.layout.description}
|
|
157
|
+
`.trim(),
|
|
158
|
+
} as const;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Decision Documentation: Why these numbers?
|
|
162
|
+
*
|
|
163
|
+
* **What counts as a component:**
|
|
164
|
+
* - Any UI element exported from packages/ui/src/index.ts
|
|
165
|
+
* - Follows React component pattern (returns JSX)
|
|
166
|
+
* - Can be imported and used directly
|
|
167
|
+
*
|
|
168
|
+
* **What doesn't count:**
|
|
169
|
+
* - Providers (utility, not UI)
|
|
170
|
+
* - Hooks (utility, not UI)
|
|
171
|
+
* - Utility functions
|
|
172
|
+
* - Type definitions
|
|
173
|
+
*
|
|
174
|
+
* **Category philosophy:**
|
|
175
|
+
* - Functional organization (what it DOES, not what it IS)
|
|
176
|
+
* - Industry standard (matches Material UI, Radix patterns)
|
|
177
|
+
* - No arbitrary tiers - if exported, it's official
|
|
178
|
+
*
|
|
179
|
+
* **Maintenance:**
|
|
180
|
+
* - Update this file when adding/removing components
|
|
181
|
+
* - Run: grep -c "^export \* from './components/" packages/ui/src/index.ts
|
|
182
|
+
* - Verify count matches COMPONENT_REGISTRY.totalCount
|
|
183
|
+
*/
|