radtools 0.1.0

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 (133) hide show
  1. package/README.md +108 -0
  2. package/bin/radtools.js +5 -0
  3. package/dist/cli/index.js +427 -0
  4. package/package.json +55 -0
  5. package/templates/api-routes/assets/optimize/route.ts +94 -0
  6. package/templates/api-routes/assets/route.ts +159 -0
  7. package/templates/api-routes/components/create-folder/route.ts +55 -0
  8. package/templates/api-routes/components/route.ts +156 -0
  9. package/templates/api-routes/fonts/route.ts +96 -0
  10. package/templates/api-routes/fonts/upload/route.ts +79 -0
  11. package/templates/api-routes/read-css/route.ts +29 -0
  12. package/templates/api-routes/write-css/route.ts +423 -0
  13. package/templates/components/Rad_os/AppWindow.tsx +423 -0
  14. package/templates/components/Rad_os/MobileAppModal.tsx +76 -0
  15. package/templates/components/Rad_os/WindowTitleBar.tsx +290 -0
  16. package/templates/components/icons/Icon.tsx +224 -0
  17. package/templates/components/icons/README.md +85 -0
  18. package/templates/components/icons/index.ts +20 -0
  19. package/templates/components/icons.tsx +164 -0
  20. package/templates/components/ui/Accordion.tsx +268 -0
  21. package/templates/components/ui/Alert.tsx +111 -0
  22. package/templates/components/ui/Badge.tsx +87 -0
  23. package/templates/components/ui/Breadcrumbs.tsx +88 -0
  24. package/templates/components/ui/Button.tsx +249 -0
  25. package/templates/components/ui/Card.tsx +137 -0
  26. package/templates/components/ui/Checkbox.tsx +137 -0
  27. package/templates/components/ui/ContextMenu.tsx +220 -0
  28. package/templates/components/ui/Dialog.tsx +264 -0
  29. package/templates/components/ui/Divider.tsx +70 -0
  30. package/templates/components/ui/DropdownMenu.tsx +301 -0
  31. package/templates/components/ui/HelpPanel.tsx +119 -0
  32. package/templates/components/ui/Input.tsx +176 -0
  33. package/templates/components/ui/Popover.tsx +211 -0
  34. package/templates/components/ui/Progress.tsx +158 -0
  35. package/templates/components/ui/Select.tsx +134 -0
  36. package/templates/components/ui/Sheet.tsx +316 -0
  37. package/templates/components/ui/Slider.tsx +223 -0
  38. package/templates/components/ui/Switch.tsx +155 -0
  39. package/templates/components/ui/Tabs.tsx +253 -0
  40. package/templates/components/ui/Toast.tsx +192 -0
  41. package/templates/components/ui/Tooltip.tsx +129 -0
  42. package/templates/components/ui/hooks/useModalBehavior.ts +66 -0
  43. package/templates/components/ui/index.ts +84 -0
  44. package/templates/devtools/DevToolsPanel.tsx +261 -0
  45. package/templates/devtools/DevToolsProvider.tsx +43 -0
  46. package/templates/devtools/components/BreakpointIndicator.tsx +49 -0
  47. package/templates/devtools/components/ColorPicker.tsx +33 -0
  48. package/templates/devtools/components/ComponentsSecondaryNav.tsx +44 -0
  49. package/templates/devtools/components/ContextualFooter.tsx +56 -0
  50. package/templates/devtools/components/DraggablePanel.tsx +43 -0
  51. package/templates/devtools/components/PrimaryNavigationFooter.tsx +254 -0
  52. package/templates/devtools/components/SearchableColorDropdown.tsx +253 -0
  53. package/templates/devtools/components/SecondaryNavigation.tsx +36 -0
  54. package/templates/devtools/components/TokenDropdown.tsx +47 -0
  55. package/templates/devtools/components/TypographyFooter.tsx +145 -0
  56. package/templates/devtools/hooks/useMockState.ts +16 -0
  57. package/templates/devtools/index.ts +17 -0
  58. package/templates/devtools/lib/componentScanner.ts +78 -0
  59. package/templates/devtools/lib/cssParser.ts +465 -0
  60. package/templates/devtools/lib/searchIndexes.ts +45 -0
  61. package/templates/devtools/lib/selectorGenerator.ts +86 -0
  62. package/templates/devtools/store/index.ts +66 -0
  63. package/templates/devtools/store/slices/assetsSlice.ts +106 -0
  64. package/templates/devtools/store/slices/componentsSlice.ts +59 -0
  65. package/templates/devtools/store/slices/mockStatesSlice.ts +77 -0
  66. package/templates/devtools/store/slices/panelSlice.ts +17 -0
  67. package/templates/devtools/store/slices/typographySlice.ts +538 -0
  68. package/templates/devtools/store/slices/variablesSlice.ts +167 -0
  69. package/templates/devtools/tabs/AssetsTab/AssetGrid.tsx +76 -0
  70. package/templates/devtools/tabs/AssetsTab/FolderTree.tsx +53 -0
  71. package/templates/devtools/tabs/AssetsTab/UploadDropzone.tsx +76 -0
  72. package/templates/devtools/tabs/AssetsTab/index.tsx +182 -0
  73. package/templates/devtools/tabs/ComponentsTab/AddTabButton.tsx +63 -0
  74. package/templates/devtools/tabs/ComponentsTab/ComponentList.tsx +153 -0
  75. package/templates/devtools/tabs/ComponentsTab/DesignSystemTab.tsx +1515 -0
  76. package/templates/devtools/tabs/ComponentsTab/DynamicFolderTab.tsx +113 -0
  77. package/templates/devtools/tabs/ComponentsTab/PropDisplay.tsx +55 -0
  78. package/templates/devtools/tabs/ComponentsTab/index.tsx +167 -0
  79. package/templates/devtools/tabs/ComponentsTab/previews/.gitkeep +4 -0
  80. package/templates/devtools/tabs/ComponentsTab/previews/Rad_os.tsx +262 -0
  81. package/templates/devtools/tabs/ComponentsTab/tabConfig.ts +53 -0
  82. package/templates/devtools/tabs/MockStatesTab/index.tsx +29 -0
  83. package/templates/devtools/tabs/TypographyTab/FontManager.tsx +421 -0
  84. package/templates/devtools/tabs/TypographyTab/TypographyStylesDisplay.tsx +290 -0
  85. package/templates/devtools/tabs/TypographyTab/index.tsx +98 -0
  86. package/templates/devtools/tabs/VariablesTab/BaseColorEditor.tsx +267 -0
  87. package/templates/devtools/tabs/VariablesTab/BorderRadiusEditor.tsx +37 -0
  88. package/templates/devtools/tabs/VariablesTab/ColorModeSelector.tsx +235 -0
  89. package/templates/devtools/tabs/VariablesTab/index.tsx +100 -0
  90. package/templates/devtools/types/index.ts +99 -0
  91. package/templates/globals.css +574 -0
  92. package/templates/hooks/index.ts +1 -0
  93. package/templates/hooks/useWindowManager.ts +212 -0
  94. package/templates/public/assets/icons/avatar.svg +18 -0
  95. package/templates/public/assets/icons/checkmark-filled.svg +14 -0
  96. package/templates/public/assets/icons/checkmark.svg +14 -0
  97. package/templates/public/assets/icons/chevron-down.svg +14 -0
  98. package/templates/public/assets/icons/close.svg +14 -0
  99. package/templates/public/assets/icons/copy.svg +14 -0
  100. package/templates/public/assets/icons/download.svg +14 -0
  101. package/templates/public/assets/icons/expand.svg +31 -0
  102. package/templates/public/assets/icons/file-blank.svg +17 -0
  103. package/templates/public/assets/icons/file-image.svg +19 -0
  104. package/templates/public/assets/icons/file-written.svg +17 -0
  105. package/templates/public/assets/icons/folder-closed.svg +17 -0
  106. package/templates/public/assets/icons/folder-open.svg +17 -0
  107. package/templates/public/assets/icons/hamburger.svg +18 -0
  108. package/templates/public/assets/icons/home-outline.svg +28 -0
  109. package/templates/public/assets/icons/home.svg +30 -0
  110. package/templates/public/assets/icons/hourglass.svg +25 -0
  111. package/templates/public/assets/icons/information-circle.svg +14 -0
  112. package/templates/public/assets/icons/information.svg +17 -0
  113. package/templates/public/assets/icons/lightning.svg +14 -0
  114. package/templates/public/assets/icons/locked.svg +17 -0
  115. package/templates/public/assets/icons/not-allowed.svg +14 -0
  116. package/templates/public/assets/icons/plus.svg +5 -0
  117. package/templates/public/assets/icons/power-thin.svg +17 -0
  118. package/templates/public/assets/icons/power.svg +17 -0
  119. package/templates/public/assets/icons/question-block.svg +14 -0
  120. package/templates/public/assets/icons/question.svg +17 -0
  121. package/templates/public/assets/icons/refresh-block.svg +14 -0
  122. package/templates/public/assets/icons/refresh.svg +17 -0
  123. package/templates/public/assets/icons/save.svg +14 -0
  124. package/templates/public/assets/icons/search.svg +25 -0
  125. package/templates/public/assets/icons/settings.svg +14 -0
  126. package/templates/public/assets/icons/trash-full.svg +21 -0
  127. package/templates/public/assets/icons/trash-open.svg +23 -0
  128. package/templates/public/assets/icons/trash.svg +18 -0
  129. package/templates/public/assets/icons/unlocked.svg +17 -0
  130. package/templates/public/assets/icons/waring-triangle-filled.svg +17 -0
  131. package/templates/public/assets/icons/warning-triangle-filled-2.svg +30 -0
  132. package/templates/public/assets/icons/warning-triangle-lines.svg +29 -0
  133. package/templates/public/assets/icons/wrench.svg +17 -0
@@ -0,0 +1,106 @@
1
+ import { StateCreator } from 'zustand';
2
+ import type { AssetFolder, AssetFile } from '../../types';
3
+
4
+ export interface AssetsSlice {
5
+ // State
6
+ assets: AssetFolder | null;
7
+ selectedFolder: string | null;
8
+ uploadProgress: Record<string, number>;
9
+ isLoading: boolean;
10
+
11
+ // Actions
12
+ setAssets: (assets: AssetFolder) => void;
13
+ setSelectedFolder: (path: string | null) => void;
14
+ setUploadProgress: (fileName: string, progress: number) => void;
15
+ clearUploadProgress: (fileName: string) => void;
16
+ refreshAssets: () => Promise<void>;
17
+ uploadAsset: (file: File, folder: string) => Promise<void>;
18
+ deleteAsset: (path: string) => Promise<void>;
19
+ optimizeAssets: (paths: string[]) => Promise<void>;
20
+ }
21
+
22
+ export const createAssetsSlice: StateCreator<AssetsSlice, [], [], AssetsSlice> = (set, get) => ({
23
+ assets: null,
24
+ selectedFolder: null,
25
+ uploadProgress: {},
26
+ isLoading: false,
27
+
28
+ setAssets: (assets) => set({ assets }),
29
+
30
+ setSelectedFolder: (path) => set({ selectedFolder: path }),
31
+
32
+ setUploadProgress: (fileName, progress) => set((state) => ({
33
+ uploadProgress: { ...state.uploadProgress, [fileName]: progress }
34
+ })),
35
+
36
+ clearUploadProgress: (fileName) => set((state) => {
37
+ const { [fileName]: _, ...rest } = state.uploadProgress;
38
+ return { uploadProgress: rest };
39
+ }),
40
+
41
+ refreshAssets: async () => {
42
+ set({ isLoading: true });
43
+ try {
44
+ const res = await fetch('/api/devtools/assets');
45
+ const data = await res.json();
46
+ set({ assets: data.assets, isLoading: false });
47
+ } catch (error) {
48
+ set({ isLoading: false });
49
+ }
50
+ },
51
+
52
+ uploadAsset: async (file, folder) => {
53
+ const formData = new FormData();
54
+ formData.append('file', file);
55
+ formData.append('folder', folder);
56
+
57
+ set((state) => ({
58
+ uploadProgress: { ...state.uploadProgress, [file.name]: 0 }
59
+ }));
60
+
61
+ try {
62
+ const res = await fetch('/api/devtools/assets', {
63
+ method: 'POST',
64
+ body: formData,
65
+ });
66
+
67
+ if (res.ok) {
68
+ set((state) => ({
69
+ uploadProgress: { ...state.uploadProgress, [file.name]: 100 }
70
+ }));
71
+ await get().refreshAssets();
72
+ }
73
+ } catch (error) {
74
+ // Failed to upload asset
75
+ } finally {
76
+ setTimeout(() => get().clearUploadProgress(file.name), 2000);
77
+ }
78
+ },
79
+
80
+ deleteAsset: async (path) => {
81
+ try {
82
+ await fetch('/api/devtools/assets', {
83
+ method: 'DELETE',
84
+ headers: { 'Content-Type': 'application/json' },
85
+ body: JSON.stringify({ path }),
86
+ });
87
+ await get().refreshAssets();
88
+ } catch (error) {
89
+ // Failed to delete asset
90
+ }
91
+ },
92
+
93
+ optimizeAssets: async (paths) => {
94
+ try {
95
+ await fetch('/api/devtools/assets/optimize', {
96
+ method: 'POST',
97
+ headers: { 'Content-Type': 'application/json' },
98
+ body: JSON.stringify({ files: paths }),
99
+ });
100
+ await get().refreshAssets();
101
+ } catch (error) {
102
+ // Failed to optimize assets
103
+ }
104
+ },
105
+ });
106
+
@@ -0,0 +1,59 @@
1
+ import { StateCreator } from 'zustand';
2
+ import type { DiscoveredComponent } from '../../types';
3
+
4
+ export interface ComponentsSlice {
5
+ // State
6
+ components: DiscoveredComponent[];
7
+ isLoading: boolean;
8
+ lastScanned: string | null;
9
+
10
+ // Actions
11
+ setComponents: (components: DiscoveredComponent[]) => void;
12
+ setIsLoading: (loading: boolean) => void;
13
+ scanComponents: () => Promise<void>;
14
+ refreshComponents: () => Promise<void>;
15
+ }
16
+
17
+ export const createComponentsSlice: StateCreator<ComponentsSlice, [], [], ComponentsSlice> = (set) => ({
18
+ components: [],
19
+ isLoading: false,
20
+ lastScanned: null,
21
+
22
+ setComponents: (components) => set({
23
+ components,
24
+ lastScanned: new Date().toISOString()
25
+ }),
26
+
27
+ setIsLoading: (isLoading) => set({ isLoading }),
28
+
29
+ scanComponents: async () => {
30
+ set({ isLoading: true });
31
+ try {
32
+ const res = await fetch('/api/devtools/components');
33
+ const data = await res.json();
34
+ set({
35
+ components: data.components || [],
36
+ lastScanned: new Date().toISOString(),
37
+ isLoading: false
38
+ });
39
+ } catch (error) {
40
+ set({ isLoading: false });
41
+ }
42
+ },
43
+
44
+ refreshComponents: async () => {
45
+ set({ isLoading: true });
46
+ try {
47
+ const res = await fetch('/api/devtools/components');
48
+ const data = await res.json();
49
+ set({
50
+ components: data.components || [],
51
+ lastScanned: new Date().toISOString(),
52
+ isLoading: false
53
+ });
54
+ } catch (error) {
55
+ set({ isLoading: false });
56
+ }
57
+ },
58
+ });
59
+
@@ -0,0 +1,77 @@
1
+ import { StateCreator } from 'zustand';
2
+ import type { MockState } from '../../types';
3
+
4
+ export interface MockStatesSlice {
5
+ // State
6
+ mockStates: MockState[];
7
+
8
+ // Actions
9
+ toggleMockState: (id: string) => void;
10
+ }
11
+
12
+ // Default preset states
13
+ const defaultPresets: MockState[] = [
14
+ {
15
+ id: 'wallet-connected',
16
+ name: 'Wallet Connected',
17
+ description: 'Simulates a connected wallet',
18
+ category: 'wallet',
19
+ values: {
20
+ isConnected: true,
21
+ address: '0x1234567890abcdef1234567890abcdef12345678',
22
+ balance: '1.5',
23
+ },
24
+ active: false,
25
+ },
26
+ {
27
+ id: 'wallet-disconnected',
28
+ name: 'Wallet Disconnected',
29
+ description: 'Simulates a disconnected wallet',
30
+ category: 'wallet',
31
+ values: {
32
+ isConnected: false,
33
+ address: null,
34
+ balance: '0',
35
+ },
36
+ active: false,
37
+ },
38
+ {
39
+ id: 'token-hodler',
40
+ name: 'Token Hodler',
41
+ description: 'Simulates a user holding tokens',
42
+ category: 'wallet',
43
+ values: {
44
+ isConnected: true,
45
+ address: '0x1234567890abcdef1234567890abcdef12345678',
46
+ balance: '10.5',
47
+ hasTokens: true,
48
+ },
49
+ active: false,
50
+ },
51
+ ];
52
+
53
+ export const createMockStatesSlice: StateCreator<MockStatesSlice, [], [], MockStatesSlice> = (set) => ({
54
+ mockStates: defaultPresets,
55
+
56
+ toggleMockState: (id) => set((state) => {
57
+ const targetState = state.mockStates.find((m) => m.id === id);
58
+ if (!targetState) return state;
59
+
60
+ // If activating, deactivate other states in the same category
61
+ const newActive = !targetState.active;
62
+
63
+ return {
64
+ mockStates: state.mockStates.map((m) => {
65
+ if (m.id === id) {
66
+ return { ...m, active: newActive };
67
+ }
68
+ // Deactivate other states in the same category
69
+ if (newActive && m.category === targetState.category && m.active) {
70
+ return { ...m, active: false };
71
+ }
72
+ return m;
73
+ })
74
+ };
75
+ }),
76
+ });
77
+
@@ -0,0 +1,17 @@
1
+ import { StateCreator } from 'zustand';
2
+
3
+ export interface PanelSlice {
4
+ // Fullscreen state (NOT persisted)
5
+ isFullscreen: boolean;
6
+ toggleFullscreen: () => void;
7
+ setFullscreen: (value: boolean) => void;
8
+ }
9
+
10
+ export const createPanelSlice: StateCreator<PanelSlice, [], [], PanelSlice> = (set) => ({
11
+ isFullscreen: false,
12
+
13
+ toggleFullscreen: () => set((state) => ({ isFullscreen: !state.isFullscreen })),
14
+
15
+ setFullscreen: (value) => set({ isFullscreen: value }),
16
+ });
17
+