@speakeasy-api/moonshine 2.0.0-alpha.1 → 2.0.0-alpha.2

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 (330) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -23
  3. package/package.json +33 -50
  4. package/scripts/generate-utility-docs.js +324 -0
  5. package/src/assets/icons/external/github.svg +3 -0
  6. package/src/assets/icons/external/maven.svg +152 -0
  7. package/src/assets/icons/external/npm.svg +4 -0
  8. package/src/assets/icons/external/nuget.svg +5 -0
  9. package/src/assets/icons/external/packagist.svg +1 -0
  10. package/src/assets/icons/external/pypi.svg +182 -0
  11. package/src/assets/icons/external/rubygems.svg +14 -0
  12. package/src/assets/icons/external/terraform.svg +1 -0
  13. package/src/assets/icons/languages/csharp.svg +1 -0
  14. package/src/assets/icons/languages/go.svg +1 -0
  15. package/src/assets/icons/languages/java.svg +1 -0
  16. package/src/assets/icons/languages/json.svg +2 -0
  17. package/src/assets/icons/languages/php.svg +1 -0
  18. package/src/assets/icons/languages/postman.svg +3 -0
  19. package/src/assets/icons/languages/python.svg +1 -0
  20. package/src/assets/icons/languages/ruby.svg +1 -0
  21. package/src/assets/icons/languages/swift.svg +1 -0
  22. package/src/assets/icons/languages/terraform.svg +1 -0
  23. package/src/assets/icons/languages/typescript.svg +1 -0
  24. package/src/assets/icons/languages/unity.svg +1 -0
  25. package/src/base.css +12 -12
  26. package/src/components/AIChat/AIChatContainer.tsx +71 -0
  27. package/src/components/AIChat/AIChatMessage.tsx +135 -0
  28. package/src/components/AIChat/AIChatMessageComposer.tsx +175 -0
  29. package/src/components/AIChat/AIChatMessageList.tsx +34 -0
  30. package/src/components/AIChat/AIChatModelSelector.tsx +159 -0
  31. package/src/components/AIChat/componentsTypes.ts +36 -0
  32. package/src/components/AIChat/context.ts +15 -0
  33. package/src/components/AIChat/index.ts +12 -0
  34. package/src/components/AIChat/parts/AIChatMessageFilePart.tsx +129 -0
  35. package/src/components/AIChat/parts/AIChatMessageReasoningPart.tsx +23 -0
  36. package/src/components/AIChat/parts/AIChatMessageSourcePart.tsx +58 -0
  37. package/src/components/AIChat/parts/AIChatMessageTextPart.tsx +33 -0
  38. package/src/components/AIChat/parts/AIChatMessageToolInvocationPart.tsx +53 -0
  39. package/src/components/AIChat/parts/AIChatMessageToolPart.tsx +395 -0
  40. package/src/components/AIChat/parts/AIChatMessageToolResultPart.tsx +46 -0
  41. package/src/components/AIChat/toolCallApproval.ts +61 -0
  42. package/src/components/AIChat/types.ts +97 -0
  43. package/src/components/ActionBar/index.tsx +184 -0
  44. package/src/components/Alert/index.tsx +118 -0
  45. package/src/components/Alert/types.ts +12 -0
  46. package/src/components/AppLayout/context.tsx +31 -0
  47. package/src/components/AppLayout/index.tsx +550 -0
  48. package/src/components/AppLayout/provider.tsx +40 -0
  49. package/src/components/AppLayout/useAppLayoutKeys.ts +26 -0
  50. package/src/components/Badge/index.tsx +227 -0
  51. package/src/components/Button/index.tsx +531 -0
  52. package/src/components/Card/index.tsx +193 -0
  53. package/src/components/CodeEditorLayout/index.tsx +394 -0
  54. package/src/components/CodeEditorLayout/styles.module.css +8 -0
  55. package/src/components/CodeHighlight/Pre.tsx +63 -0
  56. package/src/components/CodePlayground/index.tsx +411 -0
  57. package/src/components/CodeSnippet/codeSnippet.css +97 -0
  58. package/src/components/CodeSnippet/index.tsx +224 -0
  59. package/src/components/Combobox/index.tsx +193 -0
  60. package/src/components/Command/index.tsx +152 -0
  61. package/src/components/Container/index.tsx +31 -0
  62. package/src/components/ContextDropdown/index.tsx +150 -0
  63. package/src/components/Dialog/index.tsx +123 -0
  64. package/src/components/DragNDrop/DragNDropArea.tsx +30 -0
  65. package/src/components/DragNDrop/DragOverlay.tsx +4 -0
  66. package/src/components/DragNDrop/Draggable.tsx +97 -0
  67. package/src/components/DragNDrop/Droppable.tsx +51 -0
  68. package/src/components/Dropdown/index.tsx +201 -0
  69. package/src/components/ExternalPill/index.tsx +58 -0
  70. package/src/components/Facepile/index.tsx +309 -0
  71. package/src/components/GradientCircle/gradientCircle.css +34 -0
  72. package/src/components/GradientCircle/index.tsx +143 -0
  73. package/src/components/Grid/index.tsx +150 -0
  74. package/src/components/Heading/index.tsx +54 -0
  75. package/src/components/HighlightedText/index.tsx +152 -0
  76. package/src/components/Icon/customIcons/createCustomLucideIcon.ts +25 -0
  77. package/src/components/Icon/customIcons/gems.ts +26 -0
  78. package/{dist/go-CiWl_aXI.mjs → src/components/Icon/customIcons/go.ts} +21 -19
  79. package/src/components/Icon/customIcons/index.ts +11 -0
  80. package/{dist/maven-DhmnGXoB.mjs → src/components/Icon/customIcons/maven.ts} +17 -15
  81. package/src/components/Icon/customIcons/npm.ts +19 -0
  82. package/{dist/nuget-5a2icRS2.mjs → src/components/Icon/customIcons/nuget.ts} +17 -15
  83. package/src/components/Icon/customIcons/packagist.ts +124 -0
  84. package/{dist/pypi-DsuRYjdK.mjs → src/components/Icon/customIcons/pypi.ts} +16 -14
  85. package/src/components/Icon/index.tsx +83 -0
  86. package/src/components/Icon/isIconName.ts +10 -0
  87. package/src/components/Icon/names.ts +14 -0
  88. package/src/components/IconButton/index.tsx +51 -0
  89. package/src/components/Input/index.tsx +98 -0
  90. package/src/components/KeyHint/index.tsx +118 -0
  91. package/src/components/LanguageIndicator/index.tsx +68 -0
  92. package/src/components/Link/index.tsx +153 -0
  93. package/src/components/LoggedInUserMenu/index.tsx +116 -0
  94. package/src/components/Logo/Animated.tsx +191 -0
  95. package/src/components/Logo/index.tsx +17 -0
  96. package/src/components/Logo/speakeasy-logo.riv +0 -0
  97. package/src/components/Logo/svgs/index.tsx +126 -0
  98. package/src/components/Modal/index.tsx +104 -0
  99. package/src/components/PageHeader/index.tsx +227 -0
  100. package/src/components/PageHeader/styles.module.css +27 -0
  101. package/src/components/Popover/index.tsx +35 -0
  102. package/src/components/PromptInput/index.tsx +372 -0
  103. package/src/components/PullRequestLink/index.tsx +64 -0
  104. package/src/components/ResizablePanel/index.tsx +119 -0
  105. package/src/components/Score/index.module.css +32 -0
  106. package/src/components/Score/index.tsx +268 -0
  107. package/src/components/ScrollArea/index.tsx +48 -0
  108. package/src/components/SegmentedButton/index.module.css +19 -0
  109. package/src/components/SegmentedButton/index.tsx +101 -0
  110. package/src/components/Select/index.tsx +159 -0
  111. package/src/components/Separator/index.tsx +23 -0
  112. package/src/components/Skeleton/index.tsx +61 -0
  113. package/src/components/Skeleton/skeleton.css +52 -0
  114. package/src/components/Stack/index.tsx +137 -0
  115. package/src/components/Subnav/index.tsx +315 -0
  116. package/src/components/Switch/index.tsx +29 -0
  117. package/src/components/Table/context/context.tsx +19 -0
  118. package/src/components/Table/context/tableProvider.tsx +39 -0
  119. package/src/components/Table/index.tsx +707 -0
  120. package/src/components/Table/styles.module.css +25 -0
  121. package/src/components/Tabs/index.tsx +87 -0
  122. package/src/components/TargetLanguageIcon/index.tsx +84 -0
  123. package/src/components/Text/index.tsx +59 -0
  124. package/src/components/ThemeSwitcher/index.tsx +118 -0
  125. package/src/components/Timeline/index.tsx +290 -0
  126. package/src/components/Tooltip/index.tsx +41 -0
  127. package/src/components/UserAvatar/index.tsx +87 -0
  128. package/src/components/UserAvatar/sizeMap.ts +12 -0
  129. package/src/components/Wizard/index.tsx +208 -0
  130. package/src/components/Wizard/types.ts +17 -0
  131. package/src/components/WorkspaceSelector/CreateOrg.tsx +95 -0
  132. package/src/components/WorkspaceSelector/CreateWorkspace.tsx +196 -0
  133. package/src/components/WorkspaceSelector/OrgList.tsx +115 -0
  134. package/src/components/WorkspaceSelector/OrgSelector.tsx +207 -0
  135. package/src/components/WorkspaceSelector/RecentWorkspaces.tsx +83 -0
  136. package/src/components/WorkspaceSelector/ScrollingList.tsx +84 -0
  137. package/src/components/WorkspaceSelector/SearchBox.tsx +40 -0
  138. package/src/components/WorkspaceSelector/WorkspaceItem.tsx +37 -0
  139. package/src/components/WorkspaceSelector/WorkspaceList.tsx +107 -0
  140. package/src/components/WorkspaceSelector/index.tsx +400 -0
  141. package/src/components/WorkspaceSelector/styles.css +74 -0
  142. package/src/components/__beta__/CLIWizard/index.tsx +357 -0
  143. package/src/components/__beta__/CLIWizard/terminal-command.tsx +108 -0
  144. package/src/components/__beta__/CLIWizard/terminal.tsx +83 -0
  145. package/src/components/__beta__/README.md +3 -0
  146. package/src/components/index.mdx +38 -0
  147. package/src/context/ConfigContext.tsx +43 -0
  148. package/src/context/ModalContext.tsx +118 -0
  149. package/src/context/theme.ts +1 -0
  150. package/src/hooks/useAppLayout.ts +10 -0
  151. package/src/hooks/useConfig.ts +10 -0
  152. package/src/hooks/useIsMounted.ts +13 -0
  153. package/src/hooks/useModal.tsx +10 -0
  154. package/src/hooks/useTailwindBreakpoint.ts +47 -0
  155. package/src/hooks/useTheme.ts +13 -0
  156. package/src/index.ts +234 -0
  157. package/src/lib/assert.ts +9 -0
  158. package/src/lib/codeUtils.ts +177 -0
  159. package/src/lib/debounce.ts +9 -0
  160. package/src/lib/responsiveMappers.ts +69 -0
  161. package/src/lib/responsiveUtils.ts +23 -0
  162. package/src/lib/storybookUtils.tsx +26 -0
  163. package/src/lib/typeUtils.ts +109 -0
  164. package/src/lib/utils.ts +85 -0
  165. package/src/styles/codeSyntax.css +59 -0
  166. package/src/styles/globals.css +51 -0
  167. package/src/types.ts +200 -0
  168. package/src/utilities.css +347 -6
  169. package/src/vite-env.d.ts +6 -0
  170. package/types/utilities.d.ts +43 -1
  171. package/dist/components/AIChat/AIChatContainer.d.ts +0 -25
  172. package/dist/components/AIChat/AIChatMessage.d.ts +0 -19
  173. package/dist/components/AIChat/AIChatMessageComposer.d.ts +0 -22
  174. package/dist/components/AIChat/AIChatMessageList.d.ts +0 -6
  175. package/dist/components/AIChat/AIChatModelSelector.d.ts +0 -14
  176. package/dist/components/AIChat/componentsTypes.d.ts +0 -11
  177. package/dist/components/AIChat/context.d.ts +0 -3
  178. package/dist/components/AIChat/index.d.ts +0 -12
  179. package/dist/components/AIChat/parts/AIChatMessageFilePart.d.ts +0 -7
  180. package/dist/components/AIChat/parts/AIChatMessageReasoningPart.d.ts +0 -5
  181. package/dist/components/AIChat/parts/AIChatMessageSourcePart.d.ts +0 -9
  182. package/dist/components/AIChat/parts/AIChatMessageTextPart.d.ts +0 -5
  183. package/dist/components/AIChat/parts/AIChatMessageToolInvocationPart.d.ts +0 -6
  184. package/dist/components/AIChat/parts/AIChatMessageToolPart.d.ts +0 -33
  185. package/dist/components/AIChat/parts/AIChatMessageToolResultPart.d.ts +0 -5
  186. package/dist/components/AIChat/toolCallApproval.d.ts +0 -15
  187. package/dist/components/AIChat/types.d.ts +0 -78
  188. package/dist/components/ActionBar/index.d.ts +0 -36
  189. package/dist/components/Alert/index.d.ts +0 -18
  190. package/dist/components/Alert/types.d.ts +0 -4
  191. package/dist/components/Badge/index.d.ts +0 -10
  192. package/dist/components/Button/index.d.ts +0 -11
  193. package/dist/components/Card/index.d.ts +0 -47
  194. package/dist/components/CodeEditorLayout/index.d.ts +0 -101
  195. package/dist/components/CodePlayground/index.d.ts +0 -108
  196. package/dist/components/CodePlayground/lineNumbers.d.ts +0 -2
  197. package/dist/components/CodePlayground/tokenTransitions.d.ts +0 -2
  198. package/dist/components/CodePlayground/wordWrap.d.ts +0 -2
  199. package/dist/components/CodeSnippet/index.d.ts +0 -50
  200. package/dist/components/Combobox/index.d.ts +0 -35
  201. package/dist/components/Command/index.d.ts +0 -80
  202. package/dist/components/Container/index.d.ts +0 -9
  203. package/dist/components/ContextDropdown/index.d.ts +0 -7
  204. package/dist/components/ContextDropdown/provider.d.ts +0 -22
  205. package/dist/components/ContextDropdown/useModal.d.ts +0 -11
  206. package/dist/components/Dialog/index.d.ts +0 -19
  207. package/dist/components/DragNDrop/DragNDropArea.d.ts +0 -8
  208. package/dist/components/DragNDrop/DragOverlay.d.ts +0 -1
  209. package/dist/components/DragNDrop/Draggable.d.ts +0 -29
  210. package/dist/components/DragNDrop/Droppable.d.ts +0 -28
  211. package/dist/components/Dropdown/index.d.ts +0 -27
  212. package/dist/components/ExternalPill/index.d.ts +0 -12
  213. package/dist/components/Facepile/index.d.ts +0 -16
  214. package/dist/components/GradientCircle/index.d.ts +0 -10
  215. package/dist/components/Grid/index.d.ts +0 -80
  216. package/dist/components/Heading/index.d.ts +0 -12
  217. package/dist/components/HighlightedText/index.d.ts +0 -19
  218. package/dist/components/Icon/customIcons/createCustomLucideIcon.d.ts +0 -3
  219. package/dist/components/Icon/customIcons/gems.d.ts +0 -2
  220. package/dist/components/Icon/customIcons/go.d.ts +0 -2
  221. package/dist/components/Icon/customIcons/index.d.ts +0 -10
  222. package/dist/components/Icon/customIcons/maven.d.ts +0 -2
  223. package/dist/components/Icon/customIcons/npm.d.ts +0 -2
  224. package/dist/components/Icon/customIcons/nuget.d.ts +0 -2
  225. package/dist/components/Icon/customIcons/packagist.d.ts +0 -2
  226. package/dist/components/Icon/customIcons/pypi.d.ts +0 -2
  227. package/dist/components/Icon/index.d.ts +0 -10
  228. package/dist/components/Icon/isIconName.d.ts +0 -2
  229. package/dist/components/Icon/names.d.ts +0 -6
  230. package/dist/components/Input/index.d.ts +0 -8
  231. package/dist/components/KeyHint/index.d.ts +0 -16
  232. package/dist/components/LanguageIndicator/index.d.ts +0 -7
  233. package/dist/components/Link/index.d.ts +0 -19
  234. package/dist/components/LoggedInUserMenu/index.d.ts +0 -17
  235. package/dist/components/Logo/Animated.d.ts +0 -7
  236. package/dist/components/Logo/index.d.ts +0 -7
  237. package/dist/components/Logo/svgs/index.d.ts +0 -6
  238. package/dist/components/Navbar/Slim.d.ts +0 -33
  239. package/dist/components/Navbar/index.d.ts +0 -15
  240. package/dist/components/PageHeader/index.d.ts +0 -45
  241. package/dist/components/Popover/index.d.ts +0 -8
  242. package/dist/components/PromptInput/index.d.ts +0 -55
  243. package/dist/components/PullRequestLink/index.d.ts +0 -10
  244. package/dist/components/ResizablePanel/index.d.ts +0 -26
  245. package/dist/components/Score/index.d.ts +0 -37
  246. package/dist/components/ScrollArea/index.d.ts +0 -5
  247. package/dist/components/Select/index.d.ts +0 -13
  248. package/dist/components/Separator/index.d.ts +0 -6
  249. package/dist/components/Skeleton/index.d.ts +0 -27
  250. package/dist/components/Stack/index.d.ts +0 -33
  251. package/dist/components/Subnav/index.d.ts +0 -12
  252. package/dist/components/Switch/index.d.ts +0 -4
  253. package/dist/components/Table/context/context.d.ts +0 -8
  254. package/dist/components/Table/context/tableProvider.d.ts +0 -6
  255. package/dist/components/Table/index.d.ts +0 -94
  256. package/dist/components/Tabs/index.d.ts +0 -21
  257. package/dist/components/TargetLanguageIcon/index.d.ts +0 -7
  258. package/dist/components/Text/index.d.ts +0 -19
  259. package/dist/components/ThemeSwitcher/index.d.ts +0 -5
  260. package/dist/components/Tooltip/index.d.ts +0 -8
  261. package/dist/components/UserAvatar/index.d.ts +0 -9
  262. package/dist/components/UserAvatar/sizeMap.d.ts +0 -3
  263. package/dist/components/Wizard/index.d.ts +0 -19
  264. package/dist/components/Wizard/types.d.ts +0 -15
  265. package/dist/components/WorkspaceSelector/CreateOrg.d.ts +0 -6
  266. package/dist/components/WorkspaceSelector/CreateWorkspace.d.ts +0 -17
  267. package/dist/components/WorkspaceSelector/OrgList.d.ts +0 -11
  268. package/dist/components/WorkspaceSelector/OrgSelector.d.ts +0 -13
  269. package/dist/components/WorkspaceSelector/RecentWorkspaces.d.ts +0 -11
  270. package/dist/components/WorkspaceSelector/ScrollingList.d.ts +0 -21
  271. package/dist/components/WorkspaceSelector/SearchBox.d.ts +0 -9
  272. package/dist/components/WorkspaceSelector/WorkspaceItem.d.ts +0 -9
  273. package/dist/components/WorkspaceSelector/WorkspaceList.d.ts +0 -10
  274. package/dist/components/WorkspaceSelector/index.d.ts +0 -34
  275. package/dist/components/__beta__/CLIWizard/index.d.ts +0 -21
  276. package/dist/components/__beta__/CLIWizard/terminal-command.d.ts +0 -19
  277. package/dist/components/__beta__/CLIWizard/terminal.d.ts +0 -26
  278. package/dist/context/ConfigContext.d.ts +0 -18
  279. package/dist/context/theme.d.ts +0 -1
  280. package/dist/createCustomLucideIcon-YlrRX5h9.mjs +0 -19
  281. package/dist/createCustomLucideIcon-YlrRX5h9.mjs.map +0 -1
  282. package/dist/gems-BcsO9cXq.mjs +0 -24
  283. package/dist/gems-BcsO9cXq.mjs.map +0 -1
  284. package/dist/github-kgjMtfE7.mjs +0 -11
  285. package/dist/github-kgjMtfE7.mjs.map +0 -1
  286. package/dist/go-CiWl_aXI.mjs.map +0 -1
  287. package/dist/hooks/useConfig.d.ts +0 -2
  288. package/dist/hooks/useIsMounted.d.ts +0 -1
  289. package/dist/hooks/useTailwindBreakpoint.d.ts +0 -3
  290. package/dist/hooks/useTheme.d.ts +0 -6
  291. package/dist/index-COXZ9O-g.mjs +0 -50882
  292. package/dist/index-COXZ9O-g.mjs.map +0 -1
  293. package/dist/index.d.ts +0 -73
  294. package/dist/lib/assert.d.ts +0 -2
  295. package/dist/lib/codeUtils.d.ts +0 -35
  296. package/dist/lib/debounce.d.ts +0 -1
  297. package/dist/lib/responsiveMappers.d.ts +0 -10
  298. package/dist/lib/responsiveUtils.d.ts +0 -3
  299. package/dist/lib/storybookUtils.d.ts +0 -5
  300. package/dist/lib/typeUtils.d.ts +0 -24
  301. package/dist/lib/utils.d.ts +0 -23
  302. package/dist/lucide-icons-BDw0imyx.mjs +0 -28054
  303. package/dist/lucide-icons-BDw0imyx.mjs.map +0 -1
  304. package/dist/maven-DhmnGXoB.mjs.map +0 -1
  305. package/dist/maven-W_nkSDNW.mjs +0 -107
  306. package/dist/maven-W_nkSDNW.mjs.map +0 -1
  307. package/dist/moonshine.es.js +0 -114
  308. package/dist/moonshine.es.js.map +0 -1
  309. package/dist/npm-BWTcVvFH.mjs +0 -11
  310. package/dist/npm-BWTcVvFH.mjs.map +0 -1
  311. package/dist/npm-CvQ4GKW4.mjs +0 -17
  312. package/dist/npm-CvQ4GKW4.mjs.map +0 -1
  313. package/dist/nuget-5a2icRS2.mjs.map +0 -1
  314. package/dist/nuget-CV5HU1JR.mjs +0 -11
  315. package/dist/nuget-CV5HU1JR.mjs.map +0 -1
  316. package/dist/packagist-CET6q9hi.mjs +0 -118
  317. package/dist/packagist-CET6q9hi.mjs.map +0 -1
  318. package/dist/packagist-D01fn9N_.mjs +0 -11
  319. package/dist/packagist-D01fn9N_.mjs.map +0 -1
  320. package/dist/pypi-DLh6kIJe.mjs +0 -11
  321. package/dist/pypi-DLh6kIJe.mjs.map +0 -1
  322. package/dist/pypi-DsuRYjdK.mjs.map +0 -1
  323. package/dist/rubygems-DeiNjcDV.mjs +0 -11
  324. package/dist/rubygems-DeiNjcDV.mjs.map +0 -1
  325. package/dist/speakeasy-logo-ByBTXLWb.mjs +0 -5
  326. package/dist/speakeasy-logo-ByBTXLWb.mjs.map +0 -1
  327. package/dist/style.css +0 -1
  328. package/dist/terraform-C4aktQ0o.mjs +0 -11
  329. package/dist/terraform-C4aktQ0o.mjs.map +0 -1
  330. package/dist/types.d.ts +0 -80
@@ -0,0 +1,357 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Check, ChevronUp } from 'lucide-react'
5
+ import { AnimatePresence, motion } from 'motion/react'
6
+ import { cn } from '../../../lib/utils'
7
+ import { Text } from '../../Text/index'
8
+ import { Heading } from '../../Heading/index'
9
+ import { TerminalCommand } from './terminal-command'
10
+ import { Terminal } from './terminal'
11
+ import { WizardStep } from '../../Wizard/types'
12
+
13
+ /**
14
+ * TODO before moving out of beta:
15
+ * - Replace all these hardcoded colors with our design tokens:
16
+ * bg-[#09090b], text-zinc-400, etc
17
+ * - Make sure we're using our standard border radius
18
+ * - Move the step circle sizes into our design tokens
19
+ */
20
+
21
+ export interface CLIWizardProps {
22
+ steps: WizardStep[]
23
+ currentStep: number
24
+ completedSteps: number[]
25
+ onStepComplete?: (stepIndex: number) => void
26
+ }
27
+
28
+ const fadeUp = (i: number) => ({
29
+ initial: { opacity: 0, y: 10 },
30
+ animate: { opacity: 1, y: 0 },
31
+ exit: { opacity: 0, y: -10 },
32
+ transition: { delay: i * 0.1 },
33
+ })
34
+
35
+ const chevronVariants = {
36
+ up: { rotate: 0 },
37
+ down: { rotate: 180 },
38
+ }
39
+
40
+ export const ExpandChevron = ({
41
+ isCollapsed,
42
+ }: {
43
+ isCollapsed: boolean | undefined
44
+ }) => {
45
+ return (
46
+ <motion.div
47
+ initial="up"
48
+ animate={isCollapsed ? 'down' : 'up'}
49
+ variants={chevronVariants}
50
+ transition={{
51
+ duration: 0.2,
52
+ ease: [0.215, 0.61, 0.355, 1],
53
+ }}
54
+ >
55
+ <ChevronUp className="text-default h-4 w-4" />
56
+ </motion.div>
57
+ )
58
+ }
59
+
60
+ export function CLIWizard({
61
+ steps,
62
+ currentStep,
63
+ completedSteps,
64
+ onStepComplete,
65
+ }: CLIWizardProps) {
66
+ const [activeStep, setActiveStep] = React.useState(
67
+ Math.min(currentStep - 1, steps.length - 1)
68
+ )
69
+ React.useEffect(() => {
70
+ setActiveStep(Math.min(currentStep - 1, steps.length - 1))
71
+ }, [currentStep, steps.length])
72
+
73
+ const [copiedCommands, setCopiedCommands] = React.useState<Set<string>>(
74
+ new Set()
75
+ )
76
+
77
+ const isStepComplete = (stepIndex: number) =>
78
+ completedSteps.includes(stepIndex + 1)
79
+
80
+ const currentStepCommands = steps[activeStep]?.commands || []
81
+ const activeCommandIndex = React.useMemo(() => {
82
+ return currentStepCommands.findIndex((cmd) => !copiedCommands.has(cmd.code))
83
+ }, [copiedCommands, currentStepCommands])
84
+
85
+ return (
86
+ <motion.div
87
+ layout
88
+ className="relative overflow-hidden select-none"
89
+ transition={{
90
+ duration: 0.3,
91
+ ease: [0.645, 0.045, 0.355, 1],
92
+ }}
93
+ >
94
+ <div className="w-full py-6">
95
+ <div className="flex items-center">
96
+ <Heading variant="lg" as="h2">
97
+ Getting Started
98
+ </Heading>
99
+ </div>
100
+ </div>
101
+
102
+ <AnimatePresence initial={false}>
103
+ <motion.div
104
+ initial={{ height: 0, opacity: 0 }}
105
+ animate={{ height: 'auto', opacity: 1 }}
106
+ exit={{ height: 0, opacity: 0 }}
107
+ transition={{
108
+ duration: 0.3,
109
+ ease: [0.645, 0.045, 0.355, 1],
110
+ }}
111
+ className="overflow-hidden"
112
+ >
113
+ <div className="mt-4 grid grid-cols-1 gap-8 pb-6 md:grid-cols-12">
114
+ <SidebarSteps
115
+ steps={steps}
116
+ activeStep={activeStep}
117
+ isStepComplete={isStepComplete}
118
+ onSelectStep={setActiveStep}
119
+ />
120
+
121
+ <div className="md:col-span-7">
122
+ <Terminal
123
+ path={
124
+ currentStepCommands[activeCommandIndex]?.path ??
125
+ '~/sdk-project'
126
+ }
127
+ >
128
+ <motion.div
129
+ initial={{ height: 0, opacity: 0 }}
130
+ animate={{ height: 'auto', opacity: 1 }}
131
+ exit={{ height: 0, opacity: 0 }}
132
+ transition={{
133
+ duration: 0.3,
134
+ ease: [0.645, 0.045, 0.355, 1],
135
+ }}
136
+ >
137
+ <div className="space-y-6">
138
+ <AnimatePresence mode="wait">
139
+ {currentStepCommands.map((command, i) => (
140
+ <motion.div
141
+ key={`${activeStep}-${command.id}`}
142
+ {...fadeUp(i)}
143
+ >
144
+ <TerminalCommand
145
+ code={command.code}
146
+ language={command.language}
147
+ comment={command.comment}
148
+ copyable
149
+ fontSize="small"
150
+ path={command.path}
151
+ isActive={
152
+ !copiedCommands.has(command.code) &&
153
+ i === activeCommandIndex
154
+ }
155
+ onSelectOrCopy={() => {
156
+ const newCopied = new Set(copiedCommands)
157
+ newCopied.add(command.code)
158
+ setCopiedCommands(newCopied)
159
+
160
+ const allCommandsCopied =
161
+ currentStepCommands.every((c) =>
162
+ newCopied.has(c.code)
163
+ )
164
+ if (
165
+ allCommandsCopied &&
166
+ !isStepComplete(activeStep)
167
+ ) {
168
+ onStepComplete?.(activeStep + 1)
169
+ }
170
+ }}
171
+ />
172
+ </motion.div>
173
+ ))}
174
+ </AnimatePresence>
175
+ </div>
176
+ </motion.div>
177
+ </Terminal>
178
+ </div>
179
+ </div>
180
+ </motion.div>
181
+ </AnimatePresence>
182
+ </motion.div>
183
+ )
184
+ }
185
+
186
+ interface SidebarStepsProps {
187
+ steps: WizardStep[]
188
+ activeStep: number
189
+ isStepComplete: (stepIndex: number) => boolean
190
+ onSelectStep: (stepIndex: number) => void
191
+ }
192
+
193
+ function SidebarSteps({
194
+ steps,
195
+ activeStep,
196
+ isStepComplete,
197
+ onSelectStep,
198
+ }: SidebarStepsProps) {
199
+ return (
200
+ <div className="relative md:col-span-5">
201
+ <div className="space-y-4">
202
+ {steps.map((step, index) => {
203
+ const complete = isStepComplete(index)
204
+ const active = activeStep === index
205
+ // const isLastStep = index === steps.length - 1
206
+
207
+ return (
208
+ <div key={index}>
209
+ <div className="flex items-stretch">
210
+ <div className="flex flex-col items-center">
211
+ <div className="flex h-6 items-center justify-center">
212
+ <CircleOrCheck
213
+ isComplete={complete}
214
+ isActive={active}
215
+ index={index}
216
+ />
217
+ </div>
218
+ {/* TODO: Add line between steps, layout still needs work */}
219
+ {/* {!isLastStep && (
220
+ <LineBetweenSteps
221
+ currentIndex={index}
222
+ activeStep={activeStep}
223
+ isStepComplete={isStepComplete}
224
+ />
225
+ )} */}
226
+ </div>
227
+
228
+ <div className="min-h-[48px] flex-1 pl-3">
229
+ <button
230
+ className="w-full text-left"
231
+ onClick={() => onSelectStep(index)}
232
+ aria-expanded={active}
233
+ aria-controls={`step-content-${index}`}
234
+ >
235
+ <div className="flex h-6 items-center justify-between">
236
+ <Heading variant="xs">{step.title}</Heading>
237
+ </div>
238
+ </button>
239
+
240
+ <AnimatePresence mode="sync">
241
+ {active && (
242
+ <motion.div
243
+ key={`desc-${index}`}
244
+ id={`step-content-${index}`}
245
+ initial={{ opacity: 0, height: 0 }}
246
+ animate={{ opacity: 1, height: 'auto' }}
247
+ exit={{ opacity: 0, height: 0 }}
248
+ transition={{
249
+ duration: 0.2,
250
+ ease: [0.645, 0.045, 0.355, 1],
251
+ }}
252
+ className="mt-2 overflow-hidden"
253
+ >
254
+ <Text muted>{step.description}</Text>
255
+ </motion.div>
256
+ )}
257
+ </AnimatePresence>
258
+ </div>
259
+ </div>
260
+ </div>
261
+ )
262
+ })}
263
+ </div>
264
+ </div>
265
+ )
266
+ }
267
+
268
+ // TODO: Add line between steps, layout still needs work
269
+ // function LineBetweenSteps({
270
+ // currentIndex,
271
+ // activeStep,
272
+ // isStepComplete,
273
+ // }: {
274
+ // currentIndex: number
275
+ // activeStep: number
276
+ // isStepComplete: (i: number) => boolean
277
+ // }) {
278
+ // const stepComplete = isStepComplete(currentIndex)
279
+ // const nextIsActive = activeStep === currentIndex + 1
280
+
281
+ // const lineColor =
282
+ // stepComplete && nextIsActive ? 'bg-emerald-500' : 'bg-zinc-700'
283
+
284
+ // return <div className={`w-[1px] flex-1 ${lineColor} my-1`} />
285
+ // }
286
+
287
+ function CircleOrCheck({
288
+ isComplete,
289
+ isActive,
290
+ index,
291
+ }: {
292
+ isComplete: boolean
293
+ isActive: boolean
294
+ index: number
295
+ }) {
296
+ const variants = {
297
+ complete: {
298
+ circle: 'bg-emerald-600',
299
+ text: 'text-white',
300
+ },
301
+ active: {
302
+ circle: 'bg-surface-tertiary-inverse',
303
+ text: 'text-default-inverse',
304
+ },
305
+ default: {
306
+ circle: 'bg-surface-tertiary-default',
307
+ text: 'text-default',
308
+ },
309
+ }
310
+
311
+ const variant = isComplete ? 'complete' : isActive ? 'active' : 'default'
312
+ const { circle, text } = variants[variant]
313
+
314
+ return (
315
+ <div className="relative z-20 flex h-6 w-6 items-center justify-center">
316
+ <motion.div
317
+ className={cn('absolute inset-0 rounded-full', circle)}
318
+ initial={false}
319
+ />
320
+ <motion.div
321
+ className={cn(
322
+ 'relative z-20 flex h-full w-full items-center justify-center rounded-full',
323
+ circle,
324
+ text
325
+ )}
326
+ initial={false}
327
+ >
328
+ <AnimatePresence mode="wait">
329
+ {isComplete ? (
330
+ <motion.div
331
+ key="check"
332
+ initial={{ opacity: 0, scale: 0.5 }}
333
+ animate={{ opacity: 1, scale: 1 }}
334
+ exit={{ opacity: 0, scale: 0.5 }}
335
+ transition={{ duration: 0.2 }}
336
+ >
337
+ <Check className="size-3" strokeWidth={2.5} />
338
+ </motion.div>
339
+ ) : (
340
+ <motion.div
341
+ key="number"
342
+ initial={{ opacity: 0, scale: 0.5 }}
343
+ animate={{ opacity: 1, scale: 1 }}
344
+ exit={{ opacity: 0, scale: 0.5 }}
345
+ transition={{ duration: 0.2 }}
346
+ className="flex h-full w-full items-center justify-center text-xs font-medium"
347
+ >
348
+ {index + 1}
349
+ </motion.div>
350
+ )}
351
+ </AnimatePresence>
352
+ </motion.div>
353
+ </div>
354
+ )
355
+ }
356
+
357
+ export default CLIWizard
@@ -0,0 +1,108 @@
1
+ /**
2
+ * TODO: Clean up before moving out of beta
3
+ * - Replace hardcoded colors with our tokens (the green highlight, hover states, etc)
4
+ * - Use our standard font size tokens instead of hardcoding small/medium/large
5
+ * - Add loading state for copy action
6
+ * - Add an animation around the active command
7
+ */
8
+
9
+ import React from 'react'
10
+ import { Check, Copy } from 'lucide-react'
11
+ import { motion } from 'motion/react'
12
+ import { TerminalPrompt, TerminalOutput } from './terminal'
13
+ import { cn } from '../../../lib/utils'
14
+
15
+ interface TerminalCommandProps {
16
+ code: string
17
+ language: string
18
+ onSelectOrCopy?: () => void
19
+ copyable?: boolean
20
+ fontSize?: 'small' | 'medium' | 'large'
21
+ isActive?: boolean
22
+ comment?: string
23
+ path?: string
24
+ }
25
+
26
+ export function TerminalCommand({
27
+ code,
28
+ onSelectOrCopy,
29
+ copyable = true,
30
+ fontSize = 'medium',
31
+ isActive = false,
32
+ comment,
33
+ path,
34
+ }: TerminalCommandProps) {
35
+ const [copied, setCopied] = React.useState(false)
36
+
37
+ const handleCopy = () => {
38
+ navigator.clipboard.writeText(code)
39
+ setCopied(true)
40
+ onSelectOrCopy?.()
41
+ setTimeout(() => setCopied(false), 2000)
42
+ }
43
+
44
+ return (
45
+ <div className="group relative">
46
+ <TerminalPrompt path={path} branch="main">
47
+ <button
48
+ onClick={handleCopy}
49
+ className="w-full text-left"
50
+ aria-label={copied ? 'Copied' : 'Copy command'}
51
+ >
52
+ <div
53
+ className={cn(
54
+ 'relative -mx-2 rounded-md px-2 py-0.5 transition-colors',
55
+ isActive && 'bg-emerald-500/10',
56
+ !isActive && 'hover:bg-active'
57
+ )}
58
+ >
59
+ <div className="flex items-start gap-2">
60
+ <span className="text-emerald-500 select-none">$</span>
61
+ <span
62
+ className={cn(
63
+ 'text-default mt-0.5 flex-1 font-mono font-medium tracking-normal select-text',
64
+ fontSize === 'small' && 'text-sm',
65
+ fontSize === 'medium' && 'text-base',
66
+ fontSize === 'large' && 'text-lg'
67
+ )}
68
+ >
69
+ {code}
70
+ </span>
71
+ {copyable && (
72
+ <span
73
+ className={cn('mt-1.5 shrink-0', isActive && 'opacity-100')}
74
+ >
75
+ {copied ? (
76
+ <motion.div
77
+ initial={{ scale: 0.8 }}
78
+ animate={{ scale: 1 }}
79
+ transition={{
80
+ type: 'spring',
81
+ stiffness: 200,
82
+ damping: 10,
83
+ }}
84
+ >
85
+ <Check className="h-3.5 w-3.5 text-emerald-500" />
86
+ </motion.div>
87
+ ) : (
88
+ <Copy
89
+ className={cn(
90
+ 'h-3.5 w-3.5 transition-colors',
91
+ 'text-body-muted group-hover:text-body'
92
+ )}
93
+ />
94
+ )}
95
+ </span>
96
+ )}
97
+ </div>
98
+ </div>
99
+ </button>
100
+ </TerminalPrompt>
101
+ {comment && (
102
+ <TerminalOutput>
103
+ <span className="text-xs text-zinc-400"># {comment}</span>
104
+ </TerminalOutput>
105
+ )}
106
+ </div>
107
+ )
108
+ }
@@ -0,0 +1,83 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * TODO: Before moving out of beta
5
+ * - Need to replace these hardcoded colors with our tokens:
6
+ * - All the terminal chrome colors (#27272a, #000000, etc)
7
+ * - Use different colors for the termainal window, may offend windows users
8
+ */
9
+
10
+ import * as React from 'react'
11
+ import { TerminalIcon } from 'lucide-react'
12
+ import { cn } from '../../../lib/utils'
13
+
14
+ interface TerminalProps {
15
+ children: React.ReactNode
16
+ path?: string
17
+ }
18
+
19
+ export function Terminal({ children, path = '~' }: TerminalProps) {
20
+ return (
21
+ <div className="bg-surface-secondary-default border-neutral-softest flex h-full flex-col overflow-hidden rounded-lg border">
22
+ {/* Header */}
23
+ <div className="bg-surface-tertiary-default flex h-10 items-center justify-between px-4">
24
+ <div className="flex items-center gap-2">
25
+ <div className="flex items-center gap-1.5">
26
+ <div className="h-2.5 w-2.5 rounded-full bg-red-500" />
27
+ <div className="h-2.5 w-2.5 rounded-full bg-yellow-500" />
28
+ <div className="h-2.5 w-2.5 rounded-full bg-green-500" />
29
+ </div>
30
+ <div className="ml-3 flex items-center gap-2 text-zinc-400">
31
+ <TerminalIcon className="h-3.5 w-3.5" />
32
+ <span className="text-xs font-medium">{path}</span>
33
+ </div>
34
+ </div>
35
+ </div>
36
+
37
+ {/* Content */}
38
+ <div className="flex-grow space-y-6 overflow-y-auto p-4 font-mono text-sm">
39
+ {children}
40
+ </div>
41
+ </div>
42
+ )
43
+ }
44
+
45
+ interface TerminalPromptProps {
46
+ path?: string
47
+ branch?: string
48
+ children: React.ReactNode
49
+ isActive?: boolean
50
+ time?: string
51
+ }
52
+
53
+ export function TerminalPrompt({
54
+ path = '~',
55
+ branch,
56
+ children,
57
+ time,
58
+ }: TerminalPromptProps) {
59
+ return (
60
+ <div className="space-y-1">
61
+ <div className="flex items-center gap-2 text-xs text-zinc-400">
62
+ <span className="text-zinc-500">{path}</span>
63
+ {branch && (
64
+ <>
65
+ <span>git:</span>
66
+ <span className="text-emerald-500">({branch})</span>
67
+ </>
68
+ )}
69
+ {time && <span className="text-zinc-400">({time})</span>}
70
+ </div>
71
+ <div className="rounded-lg">{children}</div>
72
+ </div>
73
+ )
74
+ }
75
+
76
+ interface TerminalOutputProps {
77
+ children: React.ReactNode
78
+ className?: string
79
+ }
80
+
81
+ export function TerminalOutput({ children, className }: TerminalOutputProps) {
82
+ return <div className={cn('pl-4 text-zinc-400', className)}>{children}</div>
83
+ }
@@ -0,0 +1,3 @@
1
+ # Beta Components
2
+
3
+ These components are in the beta phase and are not yet ready for production use.
@@ -0,0 +1,38 @@
1
+ import { Meta } from '@storybook/addon-docs/blocks';
2
+
3
+ <Meta title="Welcome" />
4
+
5
+ # `@speakeasy/moonshine`
6
+
7
+ Speakeasy's design system is a reusable component library that helps Speakeasy contributors build out product experiences quickly and consistently.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pnpm add @speakeasy-api/moonshine
13
+ ```
14
+
15
+ Reference the CSS file in your project:
16
+
17
+ ```ts
18
+ import '@speakeasy-api/moonshine/moonshine.css'
19
+ ```
20
+
21
+
22
+ Wrap your application in the `MoonshineConfigProvider` component, passing in the HTML element where the tailwind dark/light class is applied:
23
+
24
+ ```tsx
25
+ import { MoonshineConfigProvider } from '@speakeasy-api/moonshine'
26
+
27
+ <MoonshineConfigProvider themeElement={document.documentElement}>
28
+ <App />
29
+ </MoonshineConfigProvider>
30
+ ```
31
+
32
+ Then you can import components from the package:
33
+
34
+ ```tsx
35
+ import { Grid } from '@speakeasy-api/moonshine'
36
+ ```
37
+
38
+ The package is built with [vite](https://vitejs.dev/), and is distributed in both [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs) formats.
@@ -0,0 +1,43 @@
1
+ import { createContext } from 'react'
2
+ import { Theme } from './theme'
3
+
4
+ export interface ConfigContextType {
5
+ /*
6
+ * The current theme
7
+ */
8
+ theme: Theme
9
+
10
+ /*
11
+ * Update the current theme
12
+ */
13
+ setTheme: (theme: Theme) => void
14
+ }
15
+
16
+ // eslint-disable-next-line react-refresh/only-export-components
17
+ export const ConfigContext = createContext<ConfigContextType | undefined>(
18
+ undefined
19
+ )
20
+
21
+ export interface MoonshineConfigProviderProps extends ConfigContextType {
22
+ children: React.ReactNode
23
+ }
24
+
25
+ /**
26
+ * Configures Speakeasy's design system, Moonshine, within a consuming application.
27
+ *
28
+ * @param {React.ReactNode} children - The components to be wrapped by the MoonshineConfigProvider.
29
+ * @param {Theme} theme - The current theme
30
+ * @param {function(Theme): void} setTheme - Function to update the theme
31
+ * @returns {React.ReactNode} - The components wrapped by the MoonshineConfigProvider.
32
+ */
33
+ export function MoonshineConfigProvider({
34
+ children,
35
+ theme,
36
+ setTheme,
37
+ }: MoonshineConfigProviderProps) {
38
+ return (
39
+ <ConfigContext.Provider value={{ theme, setTheme }}>
40
+ {children}
41
+ </ConfigContext.Provider>
42
+ )
43
+ }