@msn-control/liftoff 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -224
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/UPSTREAM_LICENSE.txt +21 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +520 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/packaged/gitignore +27 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/README.md +25 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/components.json +22 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/eslint.config.js +23 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/index.html +13 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +6597 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package.json +60 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/public/power-apps.svg +55 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/App.tsx +17 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/assets/react.svg +1 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/mode-toggle.tsx +37 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/badge.tsx +46 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/button.tsx +60 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/calendar.tsx +211 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/card.tsx +92 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/chart.tsx +355 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/checkbox.tsx +32 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/command.tsx +184 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dialog.tsx +141 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dropdown-menu.tsx +257 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/input.tsx +21 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/label.tsx +22 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/popover.tsx +46 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/progress.tsx +29 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/select.tsx +185 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/separator.tsx +26 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/skeleton.tsx +13 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/table.tsx +114 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tabs.tsx +66 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/textarea.tsx +18 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tooltip.tsx +61 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/hooks/use-theme.ts +11 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/index.css +131 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/lib/utils.ts +6 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/main.tsx +10 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/_layout.tsx +31 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/home.tsx +59 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/not-found.tsx +14 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/query-provider.tsx +26 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/sonner-provider.tsx +23 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/theme-provider.tsx +64 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/router.tsx +24 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.app.json +34 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.json +13 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.node.json +26 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/vite.config.ts +19 -0
- package/assets/power-apps-code-app/README.md +27 -0
- package/dist/args.d.ts +33 -0
- package/dist/args.js +100 -38
- package/dist/args.js.map +1 -1
- package/dist/catalogs.d.ts +3 -1
- package/dist/catalogs.js +23 -0
- package/dist/catalogs.js.map +1 -1
- package/dist/cli.js +6 -1
- package/dist/cli.js.map +1 -1
- package/dist/code-apps-plugin.d.ts +13 -0
- package/dist/code-apps-plugin.js +69 -0
- package/dist/code-apps-plugin.js.map +1 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +669 -321
- package/dist/commands.js.map +1 -1
- package/dist/file-system.d.ts +16 -1
- package/dist/file-system.js +320 -10
- package/dist/file-system.js.map +1 -1
- package/dist/framework-adapters.d.ts +5 -2
- package/dist/framework-adapters.js +5 -2
- package/dist/framework-adapters.js.map +1 -1
- package/dist/genai-templates.d.ts +6 -6
- package/dist/genai-templates.js +0 -3
- package/dist/genai-templates.js.map +1 -1
- package/dist/interactive.d.ts +80 -6
- package/dist/interactive.js +338 -142
- package/dist/interactive.js.map +1 -1
- package/dist/migrate-plan.d.ts +4 -4
- package/dist/migrate-plan.js +1 -1
- package/dist/migrate-plan.js.map +1 -1
- package/dist/planner.d.ts +5 -0
- package/dist/planner.js +197 -53
- package/dist/planner.js.map +1 -1
- package/dist/power-apps-assets.d.ts +30 -0
- package/dist/power-apps-assets.js +131 -0
- package/dist/power-apps-assets.js.map +1 -0
- package/dist/power-apps-templates.d.ts +3 -0
- package/dist/power-apps-templates.js +140 -0
- package/dist/power-apps-templates.js.map +1 -0
- package/dist/power-apps-validation.d.ts +1 -0
- package/dist/power-apps-validation.js +79 -0
- package/dist/power-apps-validation.js.map +1 -0
- package/dist/process-runner.js +9 -6
- package/dist/process-runner.js.map +1 -1
- package/dist/project-dependencies.d.ts +7 -4
- package/dist/project-dependencies.js +16 -4
- package/dist/project-dependencies.js.map +1 -1
- package/dist/published-verifier.js +1 -1
- package/dist/published-verifier.js.map +1 -1
- package/dist/standard-templates.d.ts +4 -4
- package/dist/standard-templates.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +196 -50
- package/dist/templates.js.map +1 -1
- package/dist/terminal.d.ts +99 -3
- package/dist/terminal.js +482 -66
- package/dist/terminal.js.map +1 -1
- package/dist/types.d.ts +73 -15
- package/dist/workstation.d.ts +10 -5
- package/dist/workstation.js +25 -10
- package/dist/workstation.js.map +1 -1
- package/docs/assets/liftoff-terminal.svg +33 -0
- package/docs/azure-deployment.md +66 -0
- package/docs/cli-reference.md +128 -0
- package/docs/configuration-and-manifests.md +102 -0
- package/docs/existing-repositories.md +87 -0
- package/docs/getting-started.md +114 -0
- package/docs/prerequisites.md +99 -0
- package/docs/project-structure.md +119 -0
- package/docs/safety-and-consent.md +98 -0
- package/docs/spec-workflows-and-agents.md +92 -0
- package/docs/troubleshooting.md +133 -0
- package/docs/workloads.md +128 -0
- package/package.json +8 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
data-slot="table-container"
|
|
9
|
+
className="relative w-full overflow-x-auto"
|
|
10
|
+
>
|
|
11
|
+
<table
|
|
12
|
+
data-slot="table"
|
|
13
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
21
|
+
return (
|
|
22
|
+
<thead
|
|
23
|
+
data-slot="table-header"
|
|
24
|
+
className={cn("[&_tr]:border-b", className)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
31
|
+
return (
|
|
32
|
+
<tbody
|
|
33
|
+
data-slot="table-body"
|
|
34
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
41
|
+
return (
|
|
42
|
+
<tfoot
|
|
43
|
+
data-slot="table-footer"
|
|
44
|
+
className={cn(
|
|
45
|
+
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
54
|
+
return (
|
|
55
|
+
<tr
|
|
56
|
+
data-slot="table-row"
|
|
57
|
+
className={cn(
|
|
58
|
+
"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
67
|
+
return (
|
|
68
|
+
<th
|
|
69
|
+
data-slot="table-head"
|
|
70
|
+
className={cn(
|
|
71
|
+
"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
72
|
+
className
|
|
73
|
+
)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
80
|
+
return (
|
|
81
|
+
<td
|
|
82
|
+
data-slot="table-cell"
|
|
83
|
+
className={cn(
|
|
84
|
+
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
85
|
+
className
|
|
86
|
+
)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function TableCaption({
|
|
93
|
+
className,
|
|
94
|
+
...props
|
|
95
|
+
}: React.ComponentProps<"caption">) {
|
|
96
|
+
return (
|
|
97
|
+
<caption
|
|
98
|
+
data-slot="table-caption"
|
|
99
|
+
className={cn("text-muted-foreground mt-4 text-sm", className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
Table,
|
|
107
|
+
TableHeader,
|
|
108
|
+
TableBody,
|
|
109
|
+
TableFooter,
|
|
110
|
+
TableHead,
|
|
111
|
+
TableRow,
|
|
112
|
+
TableCell,
|
|
113
|
+
TableCaption,
|
|
114
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
|
|
8
|
+
function Tabs({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<TabsPrimitive.Root
|
|
14
|
+
data-slot="tabs"
|
|
15
|
+
className={cn("flex flex-col gap-2", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function TabsList({
|
|
22
|
+
className,
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof TabsPrimitive.List>) {
|
|
25
|
+
return (
|
|
26
|
+
<TabsPrimitive.List
|
|
27
|
+
data-slot="tabs-list"
|
|
28
|
+
className={cn(
|
|
29
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function TabsTrigger({
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
41
|
+
return (
|
|
42
|
+
<TabsPrimitive.Trigger
|
|
43
|
+
data-slot="tabs-trigger"
|
|
44
|
+
className={cn(
|
|
45
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function TabsContent({
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
57
|
+
return (
|
|
58
|
+
<TabsPrimitive.Content
|
|
59
|
+
data-slot="tabs-content"
|
|
60
|
+
className={cn("flex-1 outline-none", className)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
11
|
+
className
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Textarea }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
|
|
8
|
+
function TooltipProvider({
|
|
9
|
+
delayDuration = 0,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
12
|
+
return (
|
|
13
|
+
<TooltipPrimitive.Provider
|
|
14
|
+
data-slot="tooltip-provider"
|
|
15
|
+
delayDuration={delayDuration}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function Tooltip({
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
24
|
+
return (
|
|
25
|
+
<TooltipProvider>
|
|
26
|
+
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
27
|
+
</TooltipProvider>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function TooltipTrigger({
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
34
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function TooltipContent({
|
|
38
|
+
className,
|
|
39
|
+
sideOffset = 0,
|
|
40
|
+
children,
|
|
41
|
+
...props
|
|
42
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
|
43
|
+
return (
|
|
44
|
+
<TooltipPrimitive.Portal>
|
|
45
|
+
<TooltipPrimitive.Content
|
|
46
|
+
data-slot="tooltip-content"
|
|
47
|
+
sideOffset={sideOffset}
|
|
48
|
+
className={cn(
|
|
49
|
+
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
|
|
56
|
+
</TooltipPrimitive.Content>
|
|
57
|
+
</TooltipPrimitive.Portal>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useContext } from "react"
|
|
2
|
+
import { ThemeProviderContext } from "@/providers/theme-provider"
|
|
3
|
+
|
|
4
|
+
export const useTheme = () => {
|
|
5
|
+
const context = useContext(ThemeProviderContext)
|
|
6
|
+
|
|
7
|
+
if (context === undefined)
|
|
8
|
+
throw new Error("useTheme must be used within a ThemeProvider")
|
|
9
|
+
|
|
10
|
+
return context
|
|
11
|
+
}
|
package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/index.css
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
|
|
4
|
+
@custom-variant dark (&:is(.dark *));
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
8
|
+
line-height: 1.5;
|
|
9
|
+
font-weight: 400;
|
|
10
|
+
|
|
11
|
+
font-synthesis: none;
|
|
12
|
+
text-rendering: optimizeLegibility;
|
|
13
|
+
-webkit-font-smoothing: antialiased;
|
|
14
|
+
-moz-osx-font-smoothing: grayscale;
|
|
15
|
+
--radius: 0.625rem;
|
|
16
|
+
--background: oklch(1 0 0);
|
|
17
|
+
--foreground: oklch(0.145 0 0);
|
|
18
|
+
--card: oklch(1 0 0);
|
|
19
|
+
--card-foreground: oklch(0.145 0 0);
|
|
20
|
+
--popover: oklch(1 0 0);
|
|
21
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
22
|
+
--primary: oklch(0.205 0 0);
|
|
23
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
24
|
+
--secondary: oklch(0.97 0 0);
|
|
25
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
26
|
+
--muted: oklch(0.97 0 0);
|
|
27
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
28
|
+
--accent: oklch(0.97 0 0);
|
|
29
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
30
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
31
|
+
--border: oklch(0.922 0 0);
|
|
32
|
+
--input: oklch(0.922 0 0);
|
|
33
|
+
--ring: oklch(0.708 0 0);
|
|
34
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
35
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
36
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
37
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
38
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
39
|
+
--sidebar: oklch(0.985 0 0);
|
|
40
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
41
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
42
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
43
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
44
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
45
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
46
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@theme inline {
|
|
50
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
51
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
52
|
+
--radius-lg: var(--radius);
|
|
53
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
54
|
+
--color-background: var(--background);
|
|
55
|
+
--color-foreground: var(--foreground);
|
|
56
|
+
--color-card: var(--card);
|
|
57
|
+
--color-card-foreground: var(--card-foreground);
|
|
58
|
+
--color-popover: var(--popover);
|
|
59
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
60
|
+
--color-primary: var(--primary);
|
|
61
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
62
|
+
--color-secondary: var(--secondary);
|
|
63
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
64
|
+
--color-muted: var(--muted);
|
|
65
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
66
|
+
--color-accent: var(--accent);
|
|
67
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
68
|
+
--color-destructive: var(--destructive);
|
|
69
|
+
--color-border: var(--border);
|
|
70
|
+
--color-input: var(--input);
|
|
71
|
+
--color-ring: var(--ring);
|
|
72
|
+
--color-chart-1: var(--chart-1);
|
|
73
|
+
--color-chart-2: var(--chart-2);
|
|
74
|
+
--color-chart-3: var(--chart-3);
|
|
75
|
+
--color-chart-4: var(--chart-4);
|
|
76
|
+
--color-chart-5: var(--chart-5);
|
|
77
|
+
--color-sidebar: var(--sidebar);
|
|
78
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
79
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
80
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
81
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
82
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
83
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
84
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.dark {
|
|
88
|
+
--background: oklch(0.145 0 0);
|
|
89
|
+
--foreground: oklch(0.985 0 0);
|
|
90
|
+
--card: oklch(0.205 0 0);
|
|
91
|
+
--card-foreground: oklch(0.985 0 0);
|
|
92
|
+
--popover: oklch(0.205 0 0);
|
|
93
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
94
|
+
--primary: oklch(0.922 0 0);
|
|
95
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
96
|
+
--secondary: oklch(0.269 0 0);
|
|
97
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
98
|
+
--muted: oklch(0.269 0 0);
|
|
99
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
100
|
+
--accent: oklch(0.269 0 0);
|
|
101
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
102
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
103
|
+
--border: oklch(1 0 0 / 10%);
|
|
104
|
+
--input: oklch(1 0 0 / 15%);
|
|
105
|
+
--ring: oklch(0.556 0 0);
|
|
106
|
+
--chart-1: oklch(0.488 0.243 264.376);
|
|
107
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
108
|
+
--chart-3: oklch(0.769 0.188 70.08);
|
|
109
|
+
--chart-4: oklch(0.627 0.265 303.9);
|
|
110
|
+
--chart-5: oklch(0.645 0.246 16.439);
|
|
111
|
+
--sidebar: oklch(0.205 0 0);
|
|
112
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
113
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
114
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
115
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
116
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
117
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
118
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@layer base {
|
|
122
|
+
html, body, #root {
|
|
123
|
+
height: 100%;
|
|
124
|
+
}
|
|
125
|
+
* {
|
|
126
|
+
@apply border-border outline-ring/50;
|
|
127
|
+
}
|
|
128
|
+
body {
|
|
129
|
+
@apply bg-background text-foreground;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Outlet, NavLink } from "react-router-dom"
|
|
2
|
+
|
|
3
|
+
type LayoutProps = { showHeader?: boolean }
|
|
4
|
+
|
|
5
|
+
export default function Layout({ showHeader = true }: LayoutProps) {
|
|
6
|
+
return (
|
|
7
|
+
<div className="min-h-dvh flex flex-col">
|
|
8
|
+
{showHeader && (
|
|
9
|
+
<header className="h-14 border-b flex items-center">
|
|
10
|
+
<div className="mx-auto w-full max-w-7xl px-6 flex items-center justify-between">
|
|
11
|
+
<nav className="flex items-center gap-4">
|
|
12
|
+
<NavLink to="/" end
|
|
13
|
+
className={({ isActive }) =>
|
|
14
|
+
`text-sm text-muted-foreground hover:text-foreground ${isActive ? "text-foreground font-medium" : ""}`
|
|
15
|
+
}
|
|
16
|
+
>
|
|
17
|
+
Home
|
|
18
|
+
</NavLink>
|
|
19
|
+
</nav>
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
)}
|
|
23
|
+
|
|
24
|
+
<main className="flex-1 flex">
|
|
25
|
+
<div className="flex-1 mx-auto w-full max-w-7xl">
|
|
26
|
+
<Outlet />
|
|
27
|
+
</div>
|
|
28
|
+
</main>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
import powerAppsLogo from "/power-apps.svg"
|
|
3
|
+
import reactLogo from "@/assets/react.svg"
|
|
4
|
+
import { Button } from "@/components/ui/button"
|
|
5
|
+
import { Card, CardContent } from "@/components/ui/card"
|
|
6
|
+
import { ModeToggle } from "@/components/mode-toggle"
|
|
7
|
+
import { toast } from "sonner"
|
|
8
|
+
|
|
9
|
+
export default function HomePage() {
|
|
10
|
+
const [count, setCount] = useState(0)
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="h-full grid place-items-center">
|
|
14
|
+
<div className="w-full max-w-7xl px-8 text-center flex flex-col items-center space-y-6">
|
|
15
|
+
|
|
16
|
+
<div className="flex items-center justify-center space-x-8">
|
|
17
|
+
<a href="https://github.com/microsoft/PowerAppsCodeApps" target="_blank" rel="noreferrer noopener">
|
|
18
|
+
<img
|
|
19
|
+
src={powerAppsLogo}
|
|
20
|
+
className="h-24 w-24 transition-transform hover:scale-105"
|
|
21
|
+
alt="Power Apps logo"
|
|
22
|
+
/>
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://react.dev" target="_blank" rel="noreferrer noopener">
|
|
25
|
+
<img
|
|
26
|
+
src={reactLogo}
|
|
27
|
+
className="h-24 w-24 transition-transform hover:scale-105 motion-safe:animate-[spin_20s_linear_infinite]"
|
|
28
|
+
alt="React logo"
|
|
29
|
+
/>
|
|
30
|
+
</a>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<h1 className="text-5xl leading-tight tracking-tight">Power + Code</h1>
|
|
34
|
+
|
|
35
|
+
<Card>
|
|
36
|
+
<CardContent className="flex flex-col items-center space-y-4">
|
|
37
|
+
<Button variant="outline" onClick={() => setCount((c) => c + 1)}>
|
|
38
|
+
count is {count}
|
|
39
|
+
</Button>
|
|
40
|
+
<p className="text-sm text-muted-foreground">
|
|
41
|
+
Edit <code className="text-foreground">src/App.tsx</code> and save to test HMR
|
|
42
|
+
</p>
|
|
43
|
+
</CardContent>
|
|
44
|
+
</Card>
|
|
45
|
+
|
|
46
|
+
<div className="flex items-center justify-center gap-4">
|
|
47
|
+
<Button variant="outline" onClick={() => toast.info("Hello from Power Apps!")}>
|
|
48
|
+
!
|
|
49
|
+
</Button>
|
|
50
|
+
<ModeToggle />
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<p className="text-muted-foreground text-sm">
|
|
54
|
+
Click on the Power Apps and React logos to learn more
|
|
55
|
+
</p>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Link } from "react-router-dom"
|
|
2
|
+
import { Button } from "@/components/ui/button"
|
|
3
|
+
|
|
4
|
+
export default function NotFoundPage() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="min-h-full grid place-items-center">
|
|
7
|
+
<div className="w-full max-w-7xl px-8 text-center flex flex-col items-center space-y-6">
|
|
8
|
+
<h1 className="text-5xl leading-tight tracking-tight">404 – Not found</h1>
|
|
9
|
+
<p className="text-muted-foreground">This isn't the page you're looking for.</p>
|
|
10
|
+
<Button variant="outline"><Link to="/">Go home</Link></Button>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
)
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
|
3
|
+
|
|
4
|
+
type QueryProviderProps = { children: React.ReactNode }
|
|
5
|
+
|
|
6
|
+
const queryClient = new QueryClient({
|
|
7
|
+
defaultOptions: {
|
|
8
|
+
queries: {
|
|
9
|
+
retry: false,
|
|
10
|
+
refetchOnWindowFocus: false,
|
|
11
|
+
staleTime: 5 * 60 * 1000, // 5 min
|
|
12
|
+
gcTime: 10 * 60 * 1000 // 10 min
|
|
13
|
+
},
|
|
14
|
+
mutations: {
|
|
15
|
+
retry: false
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export function QueryProvider({ children }: QueryProviderProps) {
|
|
21
|
+
return (
|
|
22
|
+
<QueryClientProvider client={queryClient}>
|
|
23
|
+
{children}
|
|
24
|
+
</QueryClientProvider>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Toaster } from "sonner"
|
|
3
|
+
import { useTheme } from "@/hooks/use-theme"
|
|
4
|
+
|
|
5
|
+
type SonnerProviderProps = { children: React.ReactNode }
|
|
6
|
+
|
|
7
|
+
export function SonnerProvider({ children }: SonnerProviderProps) {
|
|
8
|
+
const { theme } = useTheme();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
{children}
|
|
13
|
+
<Toaster
|
|
14
|
+
position="top-center"
|
|
15
|
+
theme={theme}
|
|
16
|
+
richColors
|
|
17
|
+
expand
|
|
18
|
+
duration={3000}
|
|
19
|
+
visibleToasts={3}
|
|
20
|
+
/>
|
|
21
|
+
</>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createContext, useEffect, useState } from "react"
|
|
2
|
+
|
|
3
|
+
export type Theme = "dark" | "light" | "system"
|
|
4
|
+
|
|
5
|
+
type ThemeProviderProps = {
|
|
6
|
+
children: React.ReactNode
|
|
7
|
+
defaultTheme?: Theme
|
|
8
|
+
storageKey?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type ThemeProviderState = {
|
|
12
|
+
theme: Theme
|
|
13
|
+
setTheme: (theme: Theme) => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const initialState: ThemeProviderState = {
|
|
17
|
+
theme: "system",
|
|
18
|
+
setTheme: () => null,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
|
|
22
|
+
|
|
23
|
+
export function ThemeProvider({
|
|
24
|
+
children,
|
|
25
|
+
defaultTheme = "system",
|
|
26
|
+
storageKey = "app-theme",
|
|
27
|
+
...props
|
|
28
|
+
}: ThemeProviderProps) {
|
|
29
|
+
const [theme, setTheme] = useState<Theme>(
|
|
30
|
+
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const root = window.document.documentElement
|
|
35
|
+
|
|
36
|
+
root.classList.remove("light", "dark")
|
|
37
|
+
|
|
38
|
+
if (theme === "system") {
|
|
39
|
+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
|
|
40
|
+
.matches
|
|
41
|
+
? "dark"
|
|
42
|
+
: "light"
|
|
43
|
+
|
|
44
|
+
root.classList.add(systemTheme)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
root.classList.add(theme)
|
|
49
|
+
}, [theme])
|
|
50
|
+
|
|
51
|
+
const value = {
|
|
52
|
+
theme,
|
|
53
|
+
setTheme: (theme: Theme) => {
|
|
54
|
+
localStorage.setItem(storageKey, theme)
|
|
55
|
+
setTheme(theme)
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<ThemeProviderContext.Provider {...props} value={value}>
|
|
61
|
+
{children}
|
|
62
|
+
</ThemeProviderContext.Provider>
|
|
63
|
+
)
|
|
64
|
+
}
|
package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/router.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createBrowserRouter } from "react-router-dom"
|
|
2
|
+
import Layout from "@/pages/_layout"
|
|
3
|
+
import HomePage from "@/pages/home"
|
|
4
|
+
import NotFoundPage from "@/pages/not-found"
|
|
5
|
+
|
|
6
|
+
// IMPORTANT: Do not remove or modify the code below!
|
|
7
|
+
// Normalize basename when hosted in Power Apps
|
|
8
|
+
const BASENAME = new URL(".", location.href).pathname
|
|
9
|
+
if (location.pathname.endsWith("/index.html")) {
|
|
10
|
+
history.replaceState(null, "", BASENAME + location.search + location.hash);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const router = createBrowserRouter([
|
|
14
|
+
{
|
|
15
|
+
path: "/",
|
|
16
|
+
element: <Layout showHeader={false} />,
|
|
17
|
+
errorElement: <NotFoundPage />,
|
|
18
|
+
children: [
|
|
19
|
+
{ index: true, element: <HomePage /> },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
], {
|
|
23
|
+
basename: BASENAME // IMPORTANT: Set basename for proper routing when hosted in Power Apps
|
|
24
|
+
})
|