@donotdev/cli 0.0.18 → 0.0.20

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 (150) hide show
  1. package/dependencies-matrix.json +42 -55
  2. package/dist/bin/commands/bump.js +5 -2
  3. package/dist/bin/commands/coach.js +8177 -0
  4. package/dist/bin/commands/create-app.js +6 -6
  5. package/dist/bin/commands/create-project.js +23 -9
  6. package/dist/bin/commands/deploy.js +99 -59
  7. package/dist/bin/commands/doctor.js +243 -698
  8. package/dist/bin/commands/emu.js +2 -2
  9. package/dist/bin/commands/format.js +4 -1
  10. package/dist/bin/commands/get-demo.js +8351 -0
  11. package/dist/bin/commands/make-admin.js +773 -152
  12. package/dist/bin/commands/setup.js +524 -1713
  13. package/dist/bin/commands/staging.js +17870 -0
  14. package/dist/bin/commands/sync-secrets.js +2 -11
  15. package/dist/bin/commands/type-check.js +7738 -1712
  16. package/dist/bin/dndev.js +868 -199
  17. package/dist/bin/donotdev.js +868 -199
  18. package/dist/index.js +127 -67
  19. package/package.json +1 -1
  20. package/templates/app-demo/index.html.example +147 -10
  21. package/templates/app-demo/public/apple-touch-icon.png.example +0 -0
  22. package/templates/app-demo/public/favicon.svg.example +1 -0
  23. package/templates/app-demo/public/icon-192x192.png.example +0 -0
  24. package/templates/app-demo/public/icon-512x512.png.example +0 -0
  25. package/templates/app-demo/src/App.tsx.example +7 -11
  26. package/templates/app-demo/src/config/app.ts.example +13 -48
  27. package/templates/app-demo/src/entities/booking.ts.example +75 -0
  28. package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
  29. package/templates/app-demo/src/entities/product.ts.example +50 -0
  30. package/templates/app-demo/src/entities/quote.ts.example +70 -0
  31. package/templates/app-demo/src/globals.css.example +5 -1
  32. package/templates/app-demo/src/main.tsx.example +13 -7
  33. package/templates/app-demo/src/pages/ChangelogPage.tsx.example +41 -0
  34. package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
  35. package/templates/app-demo/src/pages/DashboardPage.tsx.example +17 -0
  36. package/templates/app-demo/src/pages/HomePage.tsx.example +339 -60
  37. package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
  38. package/templates/app-demo/src/pages/PricingPage.tsx.example +41 -0
  39. package/templates/app-demo/src/pages/ProductsPage.tsx.example +19 -0
  40. package/templates/app-demo/src/pages/ProfilePage.tsx.example +18 -0
  41. package/templates/app-demo/src/pages/SettingsPage.tsx.example +17 -0
  42. package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +118 -0
  43. package/templates/app-demo/src/pages/ShowcasePage.tsx.example +93 -0
  44. package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
  45. package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
  46. package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
  47. package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +25 -0
  48. package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +23 -0
  49. package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +23 -0
  50. package/templates/app-demo/src/themes.css.example +289 -77
  51. package/templates/app-demo/stats.html.example +4949 -0
  52. package/templates/app-demo/tsconfig.json.example +1 -1
  53. package/templates/app-demo/vite.config.ts.example +23 -48
  54. package/templates/app-expo/README.md.example +1 -1
  55. package/templates/app-expo/app/index.tsx.example +1 -1
  56. package/templates/app-next/src/locales/home_en.json.example +6 -6
  57. package/templates/app-vite/src/locales/home_en.json.example +6 -6
  58. package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
  59. package/templates/overlay-firebase/env.fragment.example +1 -1
  60. package/templates/overlay-firebase/env.fragment.expo.example +1 -1
  61. package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
  62. package/templates/overlay-supabase/env.fragment.example +1 -1
  63. package/templates/overlay-supabase/env.fragment.expo.example +1 -1
  64. package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
  65. package/templates/overlay-vercel/env.fragment.example +1 -1
  66. package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
  67. package/templates/root-consumer/AI.md.example +4 -3
  68. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
  69. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
  70. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
  71. package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
  72. package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
  73. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  74. package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
  75. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
  76. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
  77. package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
  78. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
  79. package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +19 -15
  80. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
  81. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
  82. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
  83. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
  84. package/templates/root-consumer/guides/dndev/advanced/COOKIE_REFERENCE.md.example +252 -252
  85. package/templates/root-consumer/guides/dndev/advanced/VERSION_CONTROL.md.example +174 -174
  86. package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
  87. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
  88. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
  89. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
  90. package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
  91. package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
  92. package/dist/bin/commands/agent-setup.d.ts +0 -6
  93. package/dist/bin/commands/agent-setup.d.ts.map +0 -1
  94. package/dist/bin/commands/agent-setup.js.map +0 -1
  95. package/dist/bin/commands/build.d.ts +0 -11
  96. package/dist/bin/commands/build.d.ts.map +0 -1
  97. package/dist/bin/commands/build.js.map +0 -1
  98. package/dist/bin/commands/bump.d.ts +0 -11
  99. package/dist/bin/commands/bump.d.ts.map +0 -1
  100. package/dist/bin/commands/bump.js.map +0 -1
  101. package/dist/bin/commands/cacheout.d.ts +0 -11
  102. package/dist/bin/commands/cacheout.d.ts.map +0 -1
  103. package/dist/bin/commands/cacheout.js.map +0 -1
  104. package/dist/bin/commands/create-app.d.ts +0 -11
  105. package/dist/bin/commands/create-app.d.ts.map +0 -1
  106. package/dist/bin/commands/create-app.js.map +0 -1
  107. package/dist/bin/commands/create-project.d.ts +0 -11
  108. package/dist/bin/commands/create-project.d.ts.map +0 -1
  109. package/dist/bin/commands/create-project.js.map +0 -1
  110. package/dist/bin/commands/deploy.d.ts +0 -11
  111. package/dist/bin/commands/deploy.d.ts.map +0 -1
  112. package/dist/bin/commands/deploy.js.map +0 -1
  113. package/dist/bin/commands/dev.d.ts +0 -11
  114. package/dist/bin/commands/dev.d.ts.map +0 -1
  115. package/dist/bin/commands/dev.js.map +0 -1
  116. package/dist/bin/commands/doctor.d.ts +0 -6
  117. package/dist/bin/commands/doctor.d.ts.map +0 -1
  118. package/dist/bin/commands/doctor.js.map +0 -1
  119. package/dist/bin/commands/emu.d.ts +0 -11
  120. package/dist/bin/commands/emu.d.ts.map +0 -1
  121. package/dist/bin/commands/emu.js.map +0 -1
  122. package/dist/bin/commands/format.d.ts +0 -11
  123. package/dist/bin/commands/format.d.ts.map +0 -1
  124. package/dist/bin/commands/format.js.map +0 -1
  125. package/dist/bin/commands/make-admin.d.ts +0 -11
  126. package/dist/bin/commands/make-admin.d.ts.map +0 -1
  127. package/dist/bin/commands/make-admin.js.map +0 -1
  128. package/dist/bin/commands/preview.d.ts +0 -11
  129. package/dist/bin/commands/preview.d.ts.map +0 -1
  130. package/dist/bin/commands/preview.js.map +0 -1
  131. package/dist/bin/commands/setup.d.ts +0 -6
  132. package/dist/bin/commands/setup.d.ts.map +0 -1
  133. package/dist/bin/commands/setup.js.map +0 -1
  134. package/dist/bin/commands/sync-secrets.d.ts +0 -11
  135. package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
  136. package/dist/bin/commands/sync-secrets.js.map +0 -1
  137. package/dist/bin/commands/type-check.d.ts +0 -14
  138. package/dist/bin/commands/type-check.d.ts.map +0 -1
  139. package/dist/bin/commands/type-check.js.map +0 -1
  140. package/dist/bin/commands/wai.d.ts +0 -11
  141. package/dist/bin/commands/wai.d.ts.map +0 -1
  142. package/dist/bin/commands/wai.js.map +0 -1
  143. package/dist/index.d.ts +0 -8
  144. package/dist/index.d.ts.map +0 -1
  145. package/dist/index.js.map +0 -1
  146. package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
  147. package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
  148. package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
  149. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
  150. package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
@@ -0,0 +1,93 @@
1
+ // apps/demo/src/pages/ShowcasePage.tsx
2
+
3
+ import { useMemo, useState } from 'react';
4
+ import { useNavigate } from '@donotdev/ui';
5
+ import { Component } from 'lucide-react';
6
+
7
+ import {
8
+ Badge,
9
+ Card,
10
+ Grid,
11
+ Input,
12
+ Section,
13
+ Stack,
14
+ Tabs,
15
+ } from '@donotdev/components';
16
+
17
+ import {
18
+ COMPONENT_CONFIGS,
19
+ getCSSFamilies,
20
+ } from './components/componentConfig';
21
+
22
+ import type { PageMeta } from '@donotdev/core';
23
+ import type { CSSFamily } from './components/ComponentsData';
24
+
25
+ export const meta: PageMeta = {
26
+ icon: <Component />,
27
+ preset: 'admin',
28
+ };
29
+
30
+ export default function ShowcasePage() {
31
+ const navigate = useNavigate();
32
+ const [selectedTab, setSelectedTab] = useState<CSSFamily | 'all'>('all');
33
+ const [searchQuery, setSearchQuery] = useState('');
34
+
35
+ const componentsInTab = useMemo(() => {
36
+ return COMPONENT_CONFIGS.filter((config) => {
37
+ if (selectedTab !== 'all' && config.cssFamily !== selectedTab)
38
+ return false;
39
+ return (
40
+ searchQuery === '' ||
41
+ config.name.toLowerCase().includes(searchQuery.toLowerCase())
42
+ );
43
+ }).sort((a, b) => a.name.localeCompare(b.name));
44
+ }, [selectedTab, searchQuery]);
45
+
46
+ const cssFamilies = getCSSFamilies();
47
+
48
+ return (
49
+ <Stack gap="large">
50
+ <Stack direction="row" gap="medium" align="end" wrap="wrap">
51
+ <Input
52
+ placeholder="Filter components..."
53
+ value={searchQuery}
54
+ onChange={(e) => setSearchQuery(e.target.value)}
55
+ />
56
+ </Stack>
57
+
58
+ <Tabs
59
+ items={cssFamilies.map((family) => ({
60
+ value: family.id,
61
+ label: family.label,
62
+ content: null,
63
+ }))}
64
+ value={selectedTab}
65
+ onValueChange={(value) => setSelectedTab(value as CSSFamily | 'all')}
66
+ />
67
+
68
+ <Section
69
+ title={
70
+ cssFamilies.find((f) => f.id === selectedTab)?.label || 'Components'
71
+ }
72
+ >
73
+ <Grid cols={[1, 2, 3, 4]} gap="medium">
74
+ {componentsInTab.map((config) => (
75
+ <Card
76
+ key={config.id}
77
+ title={config.name}
78
+ clickable
79
+ onClick={() => navigate(`/showcase/${config.id}`)}
80
+ >
81
+ <Stack direction="row" justify="end">
82
+ <Badge variant="secondary">
83
+ {cssFamilies.find((f) => f.id === config.cssFamily)?.label ||
84
+ config.cssFamily}
85
+ </Badge>
86
+ </Stack>
87
+ </Card>
88
+ ))}
89
+ </Grid>
90
+ </Section>
91
+ </Stack>
92
+ );
93
+ }
@@ -46,7 +46,10 @@ const PROP_TYPE_TO_PROP_NAME: Record<string, string> = {
46
46
  * Generic state wrapper for controlled components
47
47
  * Returns [value, onChange, additionalProps]
48
48
  */
49
- function useComponentState(config: ComponentConfig, variantProps: Record<string, any>): [any, ((val: any) => void) | undefined, Record<string, any>] {
49
+ function useComponentState(
50
+ config: ComponentConfig,
51
+ variantProps: Record<string, any>
52
+ ): [any, ((val: any) => void) | undefined, Record<string, any>] {
50
53
  const { stateType, defaultStateValue } = config;
51
54
 
52
55
  if (!stateType || stateType === 'custom') {
@@ -55,15 +58,21 @@ function useComponentState(config: ComponentConfig, variantProps: Record<string,
55
58
 
56
59
  switch (stateType) {
57
60
  case 'controlled-value': {
58
- const [value, setValue] = useState<string | string[]>(defaultStateValue ?? '');
61
+ const [value, setValue] = useState<string | string[]>(
62
+ defaultStateValue ?? ''
63
+ );
59
64
  return [value, setValue, {}];
60
65
  }
61
66
  case 'controlled-checked': {
62
- const [checked, setChecked] = useState<boolean>(defaultStateValue ?? false);
67
+ const [checked, setChecked] = useState<boolean>(
68
+ defaultStateValue ?? false
69
+ );
63
70
  return [checked, setChecked, {}];
64
71
  }
65
72
  case 'controlled-pressed': {
66
- const [pressed, setPressed] = useState<boolean>(defaultStateValue ?? false);
73
+ const [pressed, setPressed] = useState<boolean>(
74
+ defaultStateValue ?? false
75
+ );
67
76
  return [pressed, setPressed, {}];
68
77
  }
69
78
  case 'controlled-range': {
@@ -71,7 +80,9 @@ function useComponentState(config: ComponentConfig, variantProps: Record<string,
71
80
  return [value, setValue, {}];
72
81
  }
73
82
  case 'controlled-date': {
74
- const [selected, setSelected] = useState<Date | undefined>(defaultStateValue ?? new Date());
83
+ const [selected, setSelected] = useState<Date | undefined>(
84
+ defaultStateValue ?? new Date()
85
+ );
75
86
  return [selected, setSelected, { mode: 'single' }];
76
87
  }
77
88
  case 'controlled-dates': {
@@ -79,7 +90,9 @@ function useComponentState(config: ComponentConfig, variantProps: Record<string,
79
90
  return [selected, setSelected, { mode: 'multiple' }];
80
91
  }
81
92
  case 'controlled-date-range': {
82
- const [selected, setSelected] = useState<{ from?: Date; to?: Date }>(defaultStateValue ?? {});
93
+ const [selected, setSelected] = useState<{ from?: Date; to?: Date }>(
94
+ defaultStateValue ?? {}
95
+ );
83
96
  return [selected, setSelected, { mode: 'range' }];
84
97
  }
85
98
  default:
@@ -93,31 +106,43 @@ export function ComponentRenderer({
93
106
  }: ComponentRendererProps) {
94
107
  const Component = config.component;
95
108
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(
96
- config.id === 'calendar' && variantProps.mode === 'single' ? new Date() : undefined
109
+ config.id === 'calendar' && variantProps.mode === 'single'
110
+ ? new Date()
111
+ : undefined
97
112
  );
98
113
  const [selectedDates, setSelectedDates] = useState<Date[]>(
99
114
  config.id === 'calendar' && variantProps.mode === 'multiple' ? [] : []
100
115
  );
101
- const [selectedRange, setSelectedRange] = useState<{ from?: Date; to?: Date }>(
102
- config.id === 'calendar' && variantProps.mode === 'range' ? {} : {}
103
- );
116
+ const [selectedRange, setSelectedRange] = useState<{
117
+ from?: Date;
118
+ to?: Date;
119
+ }>(config.id === 'calendar' && variantProps.mode === 'range' ? {} : {});
104
120
  const [sheetOpen, setSheetOpen] = useState<boolean>(false);
105
121
  const [dialogOpen, setDialogOpen] = useState<boolean>(false);
106
122
  const [alertDialogOpen, setAlertDialogOpen] = useState<boolean>(false);
107
123
  const [commandDialogOpen, setCommandDialogOpen] = useState<boolean>(false);
108
124
  const [tabCount, setTabCount] = useState<number>(2);
109
- const [generatedTabsItems, setGeneratedTabsItems] = useState<Array<{ value: string; label: string; content: string }> | null>(null);
110
- const [activeOverlayVariant, setActiveOverlayVariant] = useState<string | null>(null);
125
+ const [generatedTabsItems, setGeneratedTabsItems] = useState<Array<{
126
+ value: string;
127
+ label: string;
128
+ content: string;
129
+ }> | null>(null);
130
+ const [activeOverlayVariant, setActiveOverlayVariant] = useState<
131
+ string | null
132
+ >(null);
111
133
 
112
134
  if (config.layoutDescription) {
113
135
  return (
114
136
  <Card
115
137
  title={config.name}
116
138
  variant="muted"
117
- subtitle={config.layoutDescription || `Layout component: ${config.name}`}
139
+ subtitle={
140
+ config.layoutDescription || `Layout component: ${config.name}`
141
+ }
118
142
  >
119
143
  <Text variant="muted">
120
- {config.notes || 'This is a layout component. Use it to structure your page content.'}
144
+ {config.notes ||
145
+ 'This is a layout component. Use it to structure your page content.'}
121
146
  </Text>
122
147
  </Card>
123
148
  );
@@ -133,10 +158,15 @@ export function ComponentRenderer({
133
158
  const value = PROP_VALUES[propType as keyof typeof PROP_VALUES];
134
159
  if (value !== undefined) {
135
160
  const propName = PROP_TYPE_TO_PROP_NAME[propType] || propType;
136
-
161
+
137
162
  if (propType === 'accordionItems' && Array.isArray(value)) {
138
163
  componentProps[propName] = value.map((item) => {
139
- if (typeof item === 'object' && item !== null && 'trigger' in item && typeof item.trigger === 'string') {
164
+ if (
165
+ typeof item === 'object' &&
166
+ item !== null &&
167
+ 'trigger' in item &&
168
+ typeof item.trigger === 'string'
169
+ ) {
140
170
  const triggerContent = config.supportsCommonProps.icon ? (
141
171
  <Stack direction="row" gap="tight" align="center">
142
172
  <PROP_VALUES.icon className="dndev-size-md" />
@@ -154,21 +184,41 @@ export function ComponentRenderer({
154
184
  });
155
185
  } else if (propType === 'collapsibleContent') {
156
186
  componentProps.children = value;
157
- } else if (propType === 'commandGroups' && config.id === 'command-dialog') {
187
+ } else if (
188
+ propType === 'commandGroups' &&
189
+ config.id === 'command-dialog'
190
+ ) {
158
191
  // CommandDialog needs Command component as children
159
192
  // Type assertion: commandGroups propType always returns CommandGroup[]
160
- componentProps.children = <Command groups={value as CommandGroup[]} />;
193
+ componentProps.children = (
194
+ <Command groups={value as CommandGroup[]} />
195
+ );
161
196
  } else if (propType === 'tabsItems' && Array.isArray(value)) {
162
197
  // Use generated tabs if available, otherwise use default
163
- const tabsToUse = generatedTabsItems || (value as Array<{ value: string; label: string; content: string | ReactNode }>);
198
+ const tabsToUse =
199
+ generatedTabsItems ||
200
+ (value as Array<{
201
+ value: string;
202
+ label: string;
203
+ content: string | ReactNode;
204
+ }>);
164
205
  // Tabs needs items with content as ReactNode
165
206
  if (tabsToUse && tabsToUse.length > 0) {
166
207
  componentProps.items = tabsToUse.map((item) => ({
167
208
  ...item,
168
- content: typeof item.content === 'string' ? <Text>{item.content}</Text> : item.content,
209
+ content:
210
+ typeof item.content === 'string' ? (
211
+ <Text>{item.content}</Text>
212
+ ) : (
213
+ item.content
214
+ ),
169
215
  }));
170
216
  // Set default value to first tab if not provided
171
- if (!componentProps.defaultValue && !componentProps.value && tabsToUse[0]) {
217
+ if (
218
+ !componentProps.defaultValue &&
219
+ !componentProps.value &&
220
+ tabsToUse[0]
221
+ ) {
172
222
  componentProps.defaultValue = tabsToUse[0].value;
173
223
  }
174
224
  }
@@ -180,9 +230,22 @@ export function ComponentRenderer({
180
230
  }
181
231
 
182
232
  if (config.supportsCommonProps.content) {
183
- const usesChildren = ['button', 'badge', 'toggle', 'label', 'text', 'collapsible', 'dialog', 'sheet', 'popover', 'hover-card'].includes(config.id);
233
+ const usesChildren = [
234
+ 'button',
235
+ 'badge',
236
+ 'toggle',
237
+ 'label',
238
+ 'text',
239
+ 'collapsible',
240
+ 'dialog',
241
+ 'sheet',
242
+ 'popover',
243
+ 'hover-card',
244
+ ].includes(config.id);
184
245
  const shortLabelComponents = ['badge', 'button'];
185
- const contentValue = shortLabelComponents.includes(config.id) ? PROP_VALUES.shortLabel : PROP_VALUES.content;
246
+ const contentValue = shortLabelComponents.includes(config.id)
247
+ ? PROP_VALUES.shortLabel
248
+ : PROP_VALUES.content;
186
249
  if (usesChildren) {
187
250
  componentProps.children = contentValue;
188
251
  } else if (config.id !== 'tooltip') {
@@ -196,10 +259,16 @@ export function ComponentRenderer({
196
259
 
197
260
  if (config.needsTrigger) {
198
261
  const triggerText = config.triggerText || PROP_VALUES.trigger;
199
- const buttonVariant = variantProps.variant && config.variants?.variant?.includes(variantProps.variant)
200
- ? variantProps.variant
201
- : undefined;
202
- const triggerButton = <Button icon={PROP_VALUES.icon} variant={buttonVariant}>{triggerText}</Button>;
262
+ const buttonVariant =
263
+ variantProps.variant &&
264
+ config.variants?.variant?.includes(variantProps.variant)
265
+ ? variantProps.variant
266
+ : undefined;
267
+ const triggerButton = (
268
+ <Button icon={PROP_VALUES.icon} variant={buttonVariant}>
269
+ {triggerText}
270
+ </Button>
271
+ );
203
272
 
204
273
  if (config.id === 'tooltip') {
205
274
  componentProps.children = triggerButton;
@@ -212,7 +281,10 @@ export function ComponentRenderer({
212
281
  }
213
282
 
214
283
  // Generic state management for controlled components
215
- const [stateValue, setStateValue, stateProps] = useComponentState(config, variantProps);
284
+ const [stateValue, setStateValue, stateProps] = useComponentState(
285
+ config,
286
+ variantProps
287
+ );
216
288
 
217
289
  // Wire up state to component props based on stateType
218
290
  if (config.stateType && config.stateType !== 'custom') {
@@ -239,7 +311,7 @@ export function ComponentRenderer({
239
311
  if (config.id === 'calendar') {
240
312
  const mode = variantProps.mode || 'single';
241
313
  componentProps.mode = mode;
242
-
314
+
243
315
  if (mode === 'single') {
244
316
  componentProps.selected = selectedDate;
245
317
  componentProps.onSelect = setSelectedDate;
@@ -278,18 +350,21 @@ export function ComponentRenderer({
278
350
  const itemsToAdd = baseItems.slice(currentIndex, currentIndex + 5);
279
351
  // If we need more items than available, loop back to start
280
352
  const remainingNeeded = 5 - itemsToAdd.length;
281
- const loopedItems = remainingNeeded > 0 ? baseItems.slice(0, remainingNeeded) : [];
282
- setDisplayedItems(prev => [...prev, ...itemsToAdd, ...loopedItems]);
353
+ const loopedItems =
354
+ remainingNeeded > 0 ? baseItems.slice(0, remainingNeeded) : [];
355
+ setDisplayedItems((prev) => [...prev, ...itemsToAdd, ...loopedItems]);
283
356
  };
284
357
 
285
358
  const renderItem = (item: string, index: number) => (
286
359
  <Card title={item} variant="muted">
287
- <Text variant="muted">Item #{index + 1}: {item}</Text>
360
+ <Text variant="muted">
361
+ Item #{index + 1}: {item}
362
+ </Text>
288
363
  </Card>
289
364
  );
290
365
 
291
366
  const { items: _, renderItem: __, ...restProps } = componentProps;
292
-
367
+
293
368
  return (
294
369
  <Component
295
370
  items={displayedItems}
@@ -326,15 +401,18 @@ export function ComponentRenderer({
326
401
  const { toast } = useToast();
327
402
  const [message, setMessage] = useState<string>('');
328
403
  const [duration, setDuration] = useState<string>('5000');
329
-
330
- const toastTypes: Array<{ type: 'default' | 'success' | 'error' | 'warning' | 'info'; label: string }> = [
404
+
405
+ const toastTypes: Array<{
406
+ type: 'default' | 'success' | 'error' | 'warning' | 'info';
407
+ label: string;
408
+ }> = [
331
409
  { type: 'default', label: 'Default' },
332
410
  { type: 'success', label: 'Success' },
333
411
  { type: 'error', label: 'Error' },
334
412
  { type: 'warning', label: 'Warning' },
335
413
  { type: 'info', label: 'Info' },
336
414
  ];
337
-
415
+
338
416
  const durationOptions = [
339
417
  { value: '0', label: 'Forever (0ms)' },
340
418
  { value: '3000', label: '3 seconds' },
@@ -343,9 +421,9 @@ export function ComponentRenderer({
343
421
  { value: '6000', label: '6 seconds' },
344
422
  { value: '7000', label: '7 seconds' },
345
423
  ];
346
-
424
+
347
425
  const durationValue = parseInt(duration, 10);
348
-
426
+
349
427
  return (
350
428
  <Stack gap="large" align="center" justify="center">
351
429
  <Stack className="dndev-w-full dndev-max-w-md">
@@ -356,7 +434,10 @@ export function ComponentRenderer({
356
434
  onChange={(e) => setMessage(e.target.value)}
357
435
  onKeyDown={(e) => {
358
436
  if (e.key === 'Enter' && message.trim()) {
359
- toast({ ...(message.trim() ? { title: message } : {}), duration: durationValue });
437
+ toast({
438
+ ...(message.trim() ? { title: message } : {}),
439
+ duration: durationValue,
440
+ });
360
441
  setMessage('');
361
442
  }
362
443
  }}
@@ -364,7 +445,10 @@ export function ComponentRenderer({
364
445
  <Button
365
446
  onClick={() => {
366
447
  if (message.trim()) {
367
- toast({ ...(message.trim() ? { title: message } : {}), duration: durationValue });
448
+ toast({
449
+ ...(message.trim() ? { title: message } : {}),
450
+ duration: durationValue,
451
+ });
368
452
  setMessage('');
369
453
  }
370
454
  }}
@@ -385,11 +469,18 @@ export function ComponentRenderer({
385
469
  {toastTypes.map(({ type, label }) => (
386
470
  <Button
387
471
  key={type}
388
- variant={type === 'error' ? 'destructive' : type === 'success' ? 'primary' : 'outline'}
472
+ variant={
473
+ type === 'error'
474
+ ? 'destructive'
475
+ : type === 'success'
476
+ ? 'primary'
477
+ : 'outline'
478
+ }
389
479
  onClick={() => {
390
480
  toast({
391
481
  title: `${label} Toast`,
392
- description: message.trim() || `This is a ${type} notification`,
482
+ description:
483
+ message.trim() || `This is a ${type} notification`,
393
484
  toastType: type,
394
485
  duration: durationValue,
395
486
  });
@@ -449,11 +540,16 @@ export function ComponentRenderer({
449
540
  );
450
541
  }
451
542
  if (config.id === 'spinner') {
452
- const currentVariant = variantProps.variant || componentProps.variant || 'primary';
543
+ const currentVariant =
544
+ variantProps.variant || componentProps.variant || 'primary';
453
545
  const isActive = activeOverlayVariant === currentVariant;
454
546
  return (
455
547
  <>
456
- <Stack align="center" justify="center" style={{ minHeight: '200px', position: 'relative', zIndex: 10000 }}>
548
+ <Stack
549
+ align="center"
550
+ justify="center"
551
+ style={{ minHeight: '200px', position: 'relative', zIndex: 10000 }}
552
+ >
457
553
  <Button
458
554
  variant="ghost"
459
555
  onClick={() => {
@@ -469,7 +565,11 @@ export function ComponentRenderer({
469
565
  </Button>
470
566
  </Stack>
471
567
  {isActive && (
472
- <Component {...componentProps} overlay variant={currentVariant as any} />
568
+ <Component
569
+ {...componentProps}
570
+ overlay
571
+ variant={currentVariant as any}
572
+ />
473
573
  )}
474
574
  </>
475
575
  );
@@ -487,7 +587,7 @@ export function ComponentRenderer({
487
587
  } else if (config.stateType === 'controlled-value') {
488
588
  stateLabel = String(stateValue || '');
489
589
  }
490
-
590
+
491
591
  return (
492
592
  <Stack direction="row" align="center">
493
593
  <Component {...componentProps} />
@@ -502,10 +602,6 @@ export function ComponentRenderer({
502
602
  </Stack>
503
603
  );
504
604
  } catch (error) {
505
- return (
506
- <Text variant="destructive">
507
- Error: {String(error)}
508
- </Text>
509
- );
605
+ return <Text variant="destructive">Error: {String(error)}</Text>;
510
606
  }
511
607
  }
@@ -7,12 +7,16 @@ import { Button, Collapsible, Text, Badge } from '@donotdev/components';
7
7
  export const PROP_VALUES = {
8
8
  title: 'Title',
9
9
  subtitle: 'Subtitle',
10
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
11
- content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.',
10
+ description:
11
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
12
+ content:
13
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.',
12
14
  shortLabel: 'Lorem ipsum short',
13
15
  collapsibleContent: (
14
16
  <div className="dndev-p-md dndev-surface dndev-mt-sm">
15
- <Text variant="muted" className="dndev-mb-sm">Advanced Configuration Details:</Text>
17
+ <Text variant="muted" className="dndev-mb-sm">
18
+ Advanced Configuration Details:
19
+ </Text>
16
20
  <Text>• Cache policy: 3600s</Text>
17
21
  <Text>• Retries: 3</Text>
18
22
  <Text>• Timeout: 5000ms</Text>
@@ -27,35 +31,96 @@ export const PROP_VALUES = {
27
31
  confirmLabel: 'Confirm',
28
32
  cancelLabel: 'Cancel',
29
33
  primaryAction: <Button icon={Rocket}>Primary</Button>,
30
- secondaryAction: <Button variant="outline" icon={Rocket}>Secondary</Button>,
34
+ secondaryAction: (
35
+ <Button variant="outline" icon={Rocket}>
36
+ Secondary
37
+ </Button>
38
+ ),
31
39
  items: [
32
- { label: 'Item 1', value: '1', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' },
33
- { label: 'Item 2', value: '2', content: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.' },
34
- { label: 'Item 3', value: '3', content: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error.' },
40
+ {
41
+ label: 'Item 1',
42
+ value: '1',
43
+ content:
44
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
45
+ },
46
+ {
47
+ label: 'Item 2',
48
+ value: '2',
49
+ content:
50
+ 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.',
51
+ },
52
+ {
53
+ label: 'Item 3',
54
+ value: '3',
55
+ content:
56
+ 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error.',
57
+ },
35
58
  ],
36
59
  accordionItems: [
37
- { value: 'item-1', trigger: 'Trigger: Accordion Item 1', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' },
38
- { value: 'item-2', trigger: 'Trigger: Accordion Item 2', content: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' },
39
- { value: 'item-3', trigger: 'Trigger: Accordion Item 3', content: 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.' },
60
+ {
61
+ value: 'item-1',
62
+ trigger: 'Trigger: Accordion Item 1',
63
+ content:
64
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
65
+ },
66
+ {
67
+ value: 'item-2',
68
+ trigger: 'Trigger: Accordion Item 2',
69
+ content:
70
+ 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
71
+ },
72
+ {
73
+ value: 'item-3',
74
+ trigger: 'Trigger: Accordion Item 3',
75
+ content:
76
+ 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.',
77
+ },
40
78
  ],
41
79
  tabsItems: [
42
- { value: 'tab1', label: 'Tab 1', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.' },
43
- { value: 'tab2', label: 'Tab 2', content: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.' },
80
+ {
81
+ value: 'tab1',
82
+ label: 'Tab 1',
83
+ content:
84
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.',
85
+ },
86
+ {
87
+ value: 'tab2',
88
+ label: 'Tab 2',
89
+ content:
90
+ 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.',
91
+ },
44
92
  ],
45
93
  commandGroups: [
46
94
  {
47
95
  heading: 'Navigation',
48
96
  items: [
49
97
  { label: 'Home', description: 'Go to home', onSelect: () => {} },
50
- { label: 'Components', description: 'Open components page', onSelect: () => {} },
98
+ {
99
+ label: 'Components',
100
+ description: 'Open components page',
101
+ onSelect: () => {},
102
+ },
51
103
  { label: 'Settings', description: 'Open settings', onSelect: () => {} },
52
104
  ],
53
105
  },
54
106
  ],
55
107
  listItems: [
56
- { icon: <Check className="dndev-size-md" />, content: 'Feature enabled with icon support' },
57
- { icon: <Check className="dndev-size-md" />, content: <Text>Custom ReactNode content with <Badge>Badge</Badge></Text> },
58
- { icon: <AlertCircle className="dndev-size-md" />, content: 'Warning item with different icon' },
108
+ {
109
+ icon: <Check className="dndev-size-md" />,
110
+ content: 'Feature enabled with icon support',
111
+ },
112
+ {
113
+ icon: <Check className="dndev-size-md" />,
114
+ content: (
115
+ <Text>
116
+ Custom ReactNode content with <Badge>Badge</Badge>
117
+ </Text>
118
+ ),
119
+ },
120
+ {
121
+ icon: <AlertCircle className="dndev-size-md" />,
122
+ content: 'Warning item with different icon',
123
+ },
59
124
  { content: 'Simple text item without icon' },
60
125
  ],
61
126
  navigationItems: [
@@ -76,9 +141,21 @@ export const PROP_VALUES = {
76
141
  { value: 'option3', label: 'Option 3' },
77
142
  ],
78
143
  comboboxOptions: [
79
- { value: 'tenant1', label: 'Tenant Alpha', description: 'Primary tenant account' },
80
- { value: 'tenant2', label: 'Tenant Beta', description: 'Secondary tenant account' },
81
- { value: 'tenant3', label: 'Tenant Gamma', description: 'Test tenant account' },
144
+ {
145
+ value: 'tenant1',
146
+ label: 'Tenant Alpha',
147
+ description: 'Primary tenant account',
148
+ },
149
+ {
150
+ value: 'tenant2',
151
+ label: 'Tenant Beta',
152
+ description: 'Secondary tenant account',
153
+ },
154
+ {
155
+ value: 'tenant3',
156
+ label: 'Tenant Gamma',
157
+ description: 'Test tenant account',
158
+ },
82
159
  { value: 'owner1', label: 'John Smith', description: 'Owner - Marketing' },
83
160
  { value: 'owner2', label: 'Jane Doe', description: 'Owner - Engineering' },
84
161
  { value: 'owner3', label: 'Bob Johnson', description: 'Owner - Sales' },
@@ -116,7 +193,13 @@ export const PROP_VALUES = {
116
193
  ),
117
194
  };
118
195
 
119
- export type CSSFamily = 'surface' | 'floating' | 'interactive' | 'layout' | 'input' | 'other';
196
+ export type CSSFamily =
197
+ | 'surface'
198
+ | 'floating'
199
+ | 'interactive'
200
+ | 'layout'
201
+ | 'input'
202
+ | 'other';
120
203
 
121
204
  export type PropType =
122
205
  | 'title'
@@ -149,4 +232,3 @@ export type PropType =
149
232
  | 'footer'
150
233
  | 'avatarSrc'
151
234
  | 'avatarFallback';
152
-