@speakeasy-api/moonshine 2.0.0-alpha.1 → 2.0.0-alpha.3
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/LICENSE +21 -0
- package/README.md +49 -23
- package/package.json +33 -50
- package/scripts/generate-utility-docs.js +324 -0
- package/src/assets/icons/external/github.svg +3 -0
- package/src/assets/icons/external/maven.svg +152 -0
- package/src/assets/icons/external/npm.svg +4 -0
- package/src/assets/icons/external/nuget.svg +5 -0
- package/src/assets/icons/external/packagist.svg +1 -0
- package/src/assets/icons/external/pypi.svg +182 -0
- package/src/assets/icons/external/rubygems.svg +14 -0
- package/src/assets/icons/external/terraform.svg +1 -0
- package/src/assets/icons/languages/csharp.svg +1 -0
- package/src/assets/icons/languages/go.svg +1 -0
- package/src/assets/icons/languages/java.svg +1 -0
- package/src/assets/icons/languages/json.svg +2 -0
- package/src/assets/icons/languages/php.svg +1 -0
- package/src/assets/icons/languages/postman.svg +3 -0
- package/src/assets/icons/languages/python.svg +1 -0
- package/src/assets/icons/languages/ruby.svg +1 -0
- package/src/assets/icons/languages/swift.svg +1 -0
- package/src/assets/icons/languages/terraform.svg +1 -0
- package/src/assets/icons/languages/typescript.svg +1 -0
- package/src/assets/icons/languages/unity.svg +1 -0
- package/src/base.css +12 -12
- package/src/components/AIChat/AIChatContainer.tsx +71 -0
- package/src/components/AIChat/AIChatMessage.tsx +135 -0
- package/src/components/AIChat/AIChatMessageComposer.tsx +175 -0
- package/src/components/AIChat/AIChatMessageList.tsx +34 -0
- package/src/components/AIChat/AIChatModelSelector.tsx +159 -0
- package/src/components/AIChat/componentsTypes.ts +36 -0
- package/src/components/AIChat/context.ts +15 -0
- package/src/components/AIChat/index.ts +12 -0
- package/src/components/AIChat/parts/AIChatMessageFilePart.tsx +129 -0
- package/src/components/AIChat/parts/AIChatMessageReasoningPart.tsx +23 -0
- package/src/components/AIChat/parts/AIChatMessageSourcePart.tsx +58 -0
- package/src/components/AIChat/parts/AIChatMessageTextPart.tsx +33 -0
- package/src/components/AIChat/parts/AIChatMessageToolInvocationPart.tsx +53 -0
- package/src/components/AIChat/parts/AIChatMessageToolPart.tsx +395 -0
- package/src/components/AIChat/parts/AIChatMessageToolResultPart.tsx +46 -0
- package/src/components/AIChat/toolCallApproval.ts +61 -0
- package/src/components/AIChat/types.ts +97 -0
- package/src/components/ActionBar/index.tsx +184 -0
- package/src/components/Alert/index.tsx +118 -0
- package/src/components/Alert/types.ts +12 -0
- package/src/components/AppLayout/context.tsx +31 -0
- package/src/components/AppLayout/index.tsx +550 -0
- package/src/components/AppLayout/provider.tsx +40 -0
- package/src/components/AppLayout/useAppLayoutKeys.ts +26 -0
- package/src/components/Badge/index.tsx +227 -0
- package/src/components/Button/index.tsx +531 -0
- package/src/components/Card/index.tsx +193 -0
- package/src/components/CodeEditorLayout/index.tsx +394 -0
- package/src/components/CodeEditorLayout/styles.module.css +8 -0
- package/src/components/CodeHighlight/Pre.tsx +63 -0
- package/src/components/CodePlayground/index.tsx +411 -0
- package/src/components/CodeSnippet/codeSnippet.css +97 -0
- package/src/components/CodeSnippet/index.tsx +224 -0
- package/src/components/Combobox/index.tsx +193 -0
- package/src/components/Command/index.tsx +152 -0
- package/src/components/Container/index.tsx +31 -0
- package/src/components/ContextDropdown/index.tsx +150 -0
- package/src/components/Dialog/index.tsx +123 -0
- package/src/components/DragNDrop/DragNDropArea.tsx +30 -0
- package/src/components/DragNDrop/DragOverlay.tsx +4 -0
- package/src/components/DragNDrop/Draggable.tsx +97 -0
- package/src/components/DragNDrop/Droppable.tsx +51 -0
- package/src/components/Dropdown/index.tsx +201 -0
- package/src/components/ExternalPill/index.tsx +58 -0
- package/src/components/Facepile/index.tsx +309 -0
- package/src/components/GradientCircle/gradientCircle.css +34 -0
- package/src/components/GradientCircle/index.tsx +143 -0
- package/src/components/Grid/index.tsx +150 -0
- package/src/components/Heading/index.tsx +54 -0
- package/src/components/HighlightedText/index.tsx +152 -0
- package/src/components/Icon/customIcons/createCustomLucideIcon.ts +25 -0
- package/src/components/Icon/customIcons/gems.ts +26 -0
- package/{dist/go-CiWl_aXI.mjs → src/components/Icon/customIcons/go.ts} +21 -19
- package/src/components/Icon/customIcons/index.ts +11 -0
- package/{dist/maven-DhmnGXoB.mjs → src/components/Icon/customIcons/maven.ts} +17 -15
- package/src/components/Icon/customIcons/npm.ts +19 -0
- package/{dist/nuget-5a2icRS2.mjs → src/components/Icon/customIcons/nuget.ts} +17 -15
- package/src/components/Icon/customIcons/packagist.ts +124 -0
- package/{dist/pypi-DsuRYjdK.mjs → src/components/Icon/customIcons/pypi.ts} +16 -14
- package/src/components/Icon/index.tsx +83 -0
- package/src/components/Icon/isIconName.ts +10 -0
- package/src/components/Icon/names.ts +14 -0
- package/src/components/IconButton/index.tsx +51 -0
- package/src/components/Input/index.tsx +98 -0
- package/src/components/KeyHint/index.tsx +118 -0
- package/src/components/LanguageIndicator/index.tsx +68 -0
- package/src/components/Link/index.tsx +153 -0
- package/src/components/LoggedInUserMenu/index.tsx +116 -0
- package/src/components/Logo/Animated.tsx +191 -0
- package/src/components/Logo/index.tsx +17 -0
- package/src/components/Logo/speakeasy-logo.riv +0 -0
- package/src/components/Logo/svgs/index.tsx +126 -0
- package/src/components/Modal/index.tsx +104 -0
- package/src/components/PageHeader/index.tsx +227 -0
- package/src/components/PageHeader/styles.module.css +27 -0
- package/src/components/Popover/index.tsx +35 -0
- package/src/components/PromptInput/index.tsx +372 -0
- package/src/components/PullRequestLink/index.tsx +64 -0
- package/src/components/ResizablePanel/index.tsx +119 -0
- package/src/components/Score/index.module.css +32 -0
- package/src/components/Score/index.tsx +268 -0
- package/src/components/ScrollArea/index.tsx +48 -0
- package/src/components/SegmentedButton/index.module.css +19 -0
- package/src/components/SegmentedButton/index.tsx +101 -0
- package/src/components/Select/index.tsx +159 -0
- package/src/components/Separator/index.tsx +23 -0
- package/src/components/Skeleton/index.tsx +61 -0
- package/src/components/Skeleton/skeleton.css +52 -0
- package/src/components/Stack/index.tsx +137 -0
- package/src/components/Subnav/index.tsx +315 -0
- package/src/components/Switch/index.tsx +29 -0
- package/src/components/Table/context/context.tsx +19 -0
- package/src/components/Table/context/tableProvider.tsx +39 -0
- package/src/components/Table/index.tsx +707 -0
- package/src/components/Table/styles.module.css +25 -0
- package/src/components/Tabs/index.tsx +87 -0
- package/src/components/TargetLanguageIcon/index.tsx +84 -0
- package/src/components/Text/index.tsx +59 -0
- package/src/components/ThemeSwitcher/index.tsx +118 -0
- package/src/components/Timeline/index.tsx +290 -0
- package/src/components/Tooltip/index.tsx +41 -0
- package/src/components/UserAvatar/index.tsx +87 -0
- package/src/components/UserAvatar/sizeMap.ts +12 -0
- package/src/components/Wizard/index.tsx +208 -0
- package/src/components/Wizard/types.ts +17 -0
- package/src/components/WorkspaceSelector/CreateOrg.tsx +95 -0
- package/src/components/WorkspaceSelector/CreateWorkspace.tsx +196 -0
- package/src/components/WorkspaceSelector/OrgList.tsx +115 -0
- package/src/components/WorkspaceSelector/OrgSelector.tsx +207 -0
- package/src/components/WorkspaceSelector/RecentWorkspaces.tsx +83 -0
- package/src/components/WorkspaceSelector/ScrollingList.tsx +84 -0
- package/src/components/WorkspaceSelector/SearchBox.tsx +40 -0
- package/src/components/WorkspaceSelector/WorkspaceItem.tsx +37 -0
- package/src/components/WorkspaceSelector/WorkspaceList.tsx +107 -0
- package/src/components/WorkspaceSelector/index.tsx +400 -0
- package/src/components/WorkspaceSelector/styles.css +74 -0
- package/src/components/__beta__/CLIWizard/index.tsx +357 -0
- package/src/components/__beta__/CLIWizard/terminal-command.tsx +108 -0
- package/src/components/__beta__/CLIWizard/terminal.tsx +83 -0
- package/src/components/__beta__/README.md +3 -0
- package/src/components/index.mdx +38 -0
- package/src/context/ConfigContext.tsx +43 -0
- package/src/context/ModalContext.tsx +118 -0
- package/src/context/theme.ts +1 -0
- package/src/hooks/useAppLayout.ts +10 -0
- package/src/hooks/useConfig.ts +10 -0
- package/src/hooks/useIsMounted.ts +13 -0
- package/src/hooks/useModal.tsx +10 -0
- package/src/hooks/useTailwindBreakpoint.ts +47 -0
- package/src/hooks/useTheme.ts +13 -0
- package/src/index.ts +234 -0
- package/src/lib/assert.ts +9 -0
- package/src/lib/codeUtils.ts +177 -0
- package/src/lib/debounce.ts +9 -0
- package/src/lib/responsiveMappers.ts +69 -0
- package/src/lib/responsiveUtils.ts +23 -0
- package/src/lib/storybookUtils.tsx +26 -0
- package/src/lib/typeUtils.ts +109 -0
- package/src/lib/utils.ts +85 -0
- package/src/styles/codeSyntax.css +59 -0
- package/src/styles/globals.css +51 -0
- package/src/types.ts +200 -0
- package/src/utilities.css +347 -6
- package/src/vite-env.d.ts +6 -0
- package/types/utilities.d.ts +43 -1
- package/dist/components/AIChat/AIChatContainer.d.ts +0 -25
- package/dist/components/AIChat/AIChatMessage.d.ts +0 -19
- package/dist/components/AIChat/AIChatMessageComposer.d.ts +0 -22
- package/dist/components/AIChat/AIChatMessageList.d.ts +0 -6
- package/dist/components/AIChat/AIChatModelSelector.d.ts +0 -14
- package/dist/components/AIChat/componentsTypes.d.ts +0 -11
- package/dist/components/AIChat/context.d.ts +0 -3
- package/dist/components/AIChat/index.d.ts +0 -12
- package/dist/components/AIChat/parts/AIChatMessageFilePart.d.ts +0 -7
- package/dist/components/AIChat/parts/AIChatMessageReasoningPart.d.ts +0 -5
- package/dist/components/AIChat/parts/AIChatMessageSourcePart.d.ts +0 -9
- package/dist/components/AIChat/parts/AIChatMessageTextPart.d.ts +0 -5
- package/dist/components/AIChat/parts/AIChatMessageToolInvocationPart.d.ts +0 -6
- package/dist/components/AIChat/parts/AIChatMessageToolPart.d.ts +0 -33
- package/dist/components/AIChat/parts/AIChatMessageToolResultPart.d.ts +0 -5
- package/dist/components/AIChat/toolCallApproval.d.ts +0 -15
- package/dist/components/AIChat/types.d.ts +0 -78
- package/dist/components/ActionBar/index.d.ts +0 -36
- package/dist/components/Alert/index.d.ts +0 -18
- package/dist/components/Alert/types.d.ts +0 -4
- package/dist/components/Badge/index.d.ts +0 -10
- package/dist/components/Button/index.d.ts +0 -11
- package/dist/components/Card/index.d.ts +0 -47
- package/dist/components/CodeEditorLayout/index.d.ts +0 -101
- package/dist/components/CodePlayground/index.d.ts +0 -108
- package/dist/components/CodePlayground/lineNumbers.d.ts +0 -2
- package/dist/components/CodePlayground/tokenTransitions.d.ts +0 -2
- package/dist/components/CodePlayground/wordWrap.d.ts +0 -2
- package/dist/components/CodeSnippet/index.d.ts +0 -50
- package/dist/components/Combobox/index.d.ts +0 -35
- package/dist/components/Command/index.d.ts +0 -80
- package/dist/components/Container/index.d.ts +0 -9
- package/dist/components/ContextDropdown/index.d.ts +0 -7
- package/dist/components/ContextDropdown/provider.d.ts +0 -22
- package/dist/components/ContextDropdown/useModal.d.ts +0 -11
- package/dist/components/Dialog/index.d.ts +0 -19
- package/dist/components/DragNDrop/DragNDropArea.d.ts +0 -8
- package/dist/components/DragNDrop/DragOverlay.d.ts +0 -1
- package/dist/components/DragNDrop/Draggable.d.ts +0 -29
- package/dist/components/DragNDrop/Droppable.d.ts +0 -28
- package/dist/components/Dropdown/index.d.ts +0 -27
- package/dist/components/ExternalPill/index.d.ts +0 -12
- package/dist/components/Facepile/index.d.ts +0 -16
- package/dist/components/GradientCircle/index.d.ts +0 -10
- package/dist/components/Grid/index.d.ts +0 -80
- package/dist/components/Heading/index.d.ts +0 -12
- package/dist/components/HighlightedText/index.d.ts +0 -19
- package/dist/components/Icon/customIcons/createCustomLucideIcon.d.ts +0 -3
- package/dist/components/Icon/customIcons/gems.d.ts +0 -2
- package/dist/components/Icon/customIcons/go.d.ts +0 -2
- package/dist/components/Icon/customIcons/index.d.ts +0 -10
- package/dist/components/Icon/customIcons/maven.d.ts +0 -2
- package/dist/components/Icon/customIcons/npm.d.ts +0 -2
- package/dist/components/Icon/customIcons/nuget.d.ts +0 -2
- package/dist/components/Icon/customIcons/packagist.d.ts +0 -2
- package/dist/components/Icon/customIcons/pypi.d.ts +0 -2
- package/dist/components/Icon/index.d.ts +0 -10
- package/dist/components/Icon/isIconName.d.ts +0 -2
- package/dist/components/Icon/names.d.ts +0 -6
- package/dist/components/Input/index.d.ts +0 -8
- package/dist/components/KeyHint/index.d.ts +0 -16
- package/dist/components/LanguageIndicator/index.d.ts +0 -7
- package/dist/components/Link/index.d.ts +0 -19
- package/dist/components/LoggedInUserMenu/index.d.ts +0 -17
- package/dist/components/Logo/Animated.d.ts +0 -7
- package/dist/components/Logo/index.d.ts +0 -7
- package/dist/components/Logo/svgs/index.d.ts +0 -6
- package/dist/components/Navbar/Slim.d.ts +0 -33
- package/dist/components/Navbar/index.d.ts +0 -15
- package/dist/components/PageHeader/index.d.ts +0 -45
- package/dist/components/Popover/index.d.ts +0 -8
- package/dist/components/PromptInput/index.d.ts +0 -55
- package/dist/components/PullRequestLink/index.d.ts +0 -10
- package/dist/components/ResizablePanel/index.d.ts +0 -26
- package/dist/components/Score/index.d.ts +0 -37
- package/dist/components/ScrollArea/index.d.ts +0 -5
- package/dist/components/Select/index.d.ts +0 -13
- package/dist/components/Separator/index.d.ts +0 -6
- package/dist/components/Skeleton/index.d.ts +0 -27
- package/dist/components/Stack/index.d.ts +0 -33
- package/dist/components/Subnav/index.d.ts +0 -12
- package/dist/components/Switch/index.d.ts +0 -4
- package/dist/components/Table/context/context.d.ts +0 -8
- package/dist/components/Table/context/tableProvider.d.ts +0 -6
- package/dist/components/Table/index.d.ts +0 -94
- package/dist/components/Tabs/index.d.ts +0 -21
- package/dist/components/TargetLanguageIcon/index.d.ts +0 -7
- package/dist/components/Text/index.d.ts +0 -19
- package/dist/components/ThemeSwitcher/index.d.ts +0 -5
- package/dist/components/Tooltip/index.d.ts +0 -8
- package/dist/components/UserAvatar/index.d.ts +0 -9
- package/dist/components/UserAvatar/sizeMap.d.ts +0 -3
- package/dist/components/Wizard/index.d.ts +0 -19
- package/dist/components/Wizard/types.d.ts +0 -15
- package/dist/components/WorkspaceSelector/CreateOrg.d.ts +0 -6
- package/dist/components/WorkspaceSelector/CreateWorkspace.d.ts +0 -17
- package/dist/components/WorkspaceSelector/OrgList.d.ts +0 -11
- package/dist/components/WorkspaceSelector/OrgSelector.d.ts +0 -13
- package/dist/components/WorkspaceSelector/RecentWorkspaces.d.ts +0 -11
- package/dist/components/WorkspaceSelector/ScrollingList.d.ts +0 -21
- package/dist/components/WorkspaceSelector/SearchBox.d.ts +0 -9
- package/dist/components/WorkspaceSelector/WorkspaceItem.d.ts +0 -9
- package/dist/components/WorkspaceSelector/WorkspaceList.d.ts +0 -10
- package/dist/components/WorkspaceSelector/index.d.ts +0 -34
- package/dist/components/__beta__/CLIWizard/index.d.ts +0 -21
- package/dist/components/__beta__/CLIWizard/terminal-command.d.ts +0 -19
- package/dist/components/__beta__/CLIWizard/terminal.d.ts +0 -26
- package/dist/context/ConfigContext.d.ts +0 -18
- package/dist/context/theme.d.ts +0 -1
- package/dist/createCustomLucideIcon-YlrRX5h9.mjs +0 -19
- package/dist/createCustomLucideIcon-YlrRX5h9.mjs.map +0 -1
- package/dist/gems-BcsO9cXq.mjs +0 -24
- package/dist/gems-BcsO9cXq.mjs.map +0 -1
- package/dist/github-kgjMtfE7.mjs +0 -11
- package/dist/github-kgjMtfE7.mjs.map +0 -1
- package/dist/go-CiWl_aXI.mjs.map +0 -1
- package/dist/hooks/useConfig.d.ts +0 -2
- package/dist/hooks/useIsMounted.d.ts +0 -1
- package/dist/hooks/useTailwindBreakpoint.d.ts +0 -3
- package/dist/hooks/useTheme.d.ts +0 -6
- package/dist/index-COXZ9O-g.mjs +0 -50882
- package/dist/index-COXZ9O-g.mjs.map +0 -1
- package/dist/index.d.ts +0 -73
- package/dist/lib/assert.d.ts +0 -2
- package/dist/lib/codeUtils.d.ts +0 -35
- package/dist/lib/debounce.d.ts +0 -1
- package/dist/lib/responsiveMappers.d.ts +0 -10
- package/dist/lib/responsiveUtils.d.ts +0 -3
- package/dist/lib/storybookUtils.d.ts +0 -5
- package/dist/lib/typeUtils.d.ts +0 -24
- package/dist/lib/utils.d.ts +0 -23
- package/dist/lucide-icons-BDw0imyx.mjs +0 -28054
- package/dist/lucide-icons-BDw0imyx.mjs.map +0 -1
- package/dist/maven-DhmnGXoB.mjs.map +0 -1
- package/dist/maven-W_nkSDNW.mjs +0 -107
- package/dist/maven-W_nkSDNW.mjs.map +0 -1
- package/dist/moonshine.es.js +0 -114
- package/dist/moonshine.es.js.map +0 -1
- package/dist/npm-BWTcVvFH.mjs +0 -11
- package/dist/npm-BWTcVvFH.mjs.map +0 -1
- package/dist/npm-CvQ4GKW4.mjs +0 -17
- package/dist/npm-CvQ4GKW4.mjs.map +0 -1
- package/dist/nuget-5a2icRS2.mjs.map +0 -1
- package/dist/nuget-CV5HU1JR.mjs +0 -11
- package/dist/nuget-CV5HU1JR.mjs.map +0 -1
- package/dist/packagist-CET6q9hi.mjs +0 -118
- package/dist/packagist-CET6q9hi.mjs.map +0 -1
- package/dist/packagist-D01fn9N_.mjs +0 -11
- package/dist/packagist-D01fn9N_.mjs.map +0 -1
- package/dist/pypi-DLh6kIJe.mjs +0 -11
- package/dist/pypi-DLh6kIJe.mjs.map +0 -1
- package/dist/pypi-DsuRYjdK.mjs.map +0 -1
- package/dist/rubygems-DeiNjcDV.mjs +0 -11
- package/dist/rubygems-DeiNjcDV.mjs.map +0 -1
- package/dist/speakeasy-logo-ByBTXLWb.mjs +0 -5
- package/dist/speakeasy-logo-ByBTXLWb.mjs.map +0 -1
- package/dist/style.css +0 -1
- package/dist/terraform-C4aktQ0o.mjs +0 -11
- package/dist/terraform-C4aktQ0o.mjs.map +0 -1
- 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,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
|
+
}
|