sunpeak 0.2.4 → 0.2.6
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 +10 -0
- package/dist/index.cjs +264 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -12
- package/dist/index.d.ts +212 -12
- package/dist/index.js +246 -76
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.cjs +250 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +12 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.js +243 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/styles/globals.css +0 -1
- package/package.json +10 -2
- package/template/README.md +38 -2
- package/template/dev/main.tsx +51 -48
- package/template/mcp/server.ts +66 -0
- package/template/package.json +3 -0
- package/template/postcss.config.js +5 -0
- package/template/src/App.tsx +8 -4
- package/template/src/components/sunpeak-card.tsx +43 -12
- package/template/src/components/sunpeak-carousel.tsx +42 -8
- package/template/src/index.chatgpt.tsx +8 -0
- package/template/src/styles/globals.css +0 -1
- package/template/tsup.config.ts +29 -2
- package/template/vite.config.ts +2 -0
package/template/README.md
CHANGED
|
@@ -19,12 +19,48 @@ Edit [src/App.tsx](./src/App.tsx) to build your app UI.
|
|
|
19
19
|
```
|
|
20
20
|
src/
|
|
21
21
|
├── App.tsx # Your main app component
|
|
22
|
-
└── components
|
|
22
|
+
└── components/ # Your shadcn/ui React components
|
|
23
|
+
|
|
24
|
+
mcp/
|
|
25
|
+
└── server.ts # MCP server for testing in ChatGPT
|
|
23
26
|
|
|
24
27
|
dist/ # Build output (generated)
|
|
25
28
|
└── chatgpt/ # ChatGPT builds
|
|
26
29
|
```
|
|
27
30
|
|
|
31
|
+
## Testing
|
|
32
|
+
|
|
33
|
+
### Testing Locally
|
|
34
|
+
|
|
35
|
+
Run the following scripts, and manually QA the UI from the dev server:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm lint
|
|
39
|
+
pnpm typecheck
|
|
40
|
+
pnpm test
|
|
41
|
+
pnpm build
|
|
42
|
+
pnpm dev
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Testing in ChatGPT
|
|
46
|
+
|
|
47
|
+
Test your app directly in ChatGPT using the built-in MCP server:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Build your app. You must rebuild your app for changes to take effect.
|
|
51
|
+
pnpm build
|
|
52
|
+
|
|
53
|
+
# 2. Start the MCP server.
|
|
54
|
+
pnpm mcp
|
|
55
|
+
|
|
56
|
+
# 3. In another terminal, run a tunnel. For example:
|
|
57
|
+
ngrok http 6766
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The server will run on `http://localhost:6766` and serve your App component with dummy data from `mcp/server.ts`.
|
|
61
|
+
|
|
62
|
+
You can then connect to the tunnel `/mcp` path from ChatGPT in developer mode to see your UI in action.
|
|
63
|
+
|
|
28
64
|
## Build & Deploy
|
|
29
65
|
|
|
30
66
|
Build your app for production:
|
|
@@ -36,7 +72,7 @@ pnpm build
|
|
|
36
72
|
This creates optimized builds in the `dist/` directory:
|
|
37
73
|
|
|
38
74
|
- `dist/chatgpt/index.js` - ChatGPT iframe component
|
|
39
|
-
- Host this file somewhere and reference it as a resource in your MCP server.
|
|
75
|
+
- Host this file somewhere and reference it as a resource in your production MCP server.
|
|
40
76
|
|
|
41
77
|
## Resources
|
|
42
78
|
|
package/template/dev/main.tsx
CHANGED
|
@@ -4,53 +4,55 @@ import { ChatGPTSimulator } from 'sunpeak';
|
|
|
4
4
|
import { App } from '@/App';
|
|
5
5
|
import './styles.css';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
7
|
+
const toolOutput = {
|
|
8
|
+
places: [
|
|
9
|
+
{
|
|
10
|
+
id: '1',
|
|
11
|
+
name: 'Lady Bird Lake',
|
|
12
|
+
rating: 4.5,
|
|
13
|
+
category: 'Waterfront',
|
|
14
|
+
location: 'Austin',
|
|
15
|
+
image: 'https://images.unsplash.com/photo-1520950237264-dfe336995c34?w=400&h=400&fit=crop',
|
|
16
|
+
description: 'Scenic lake perfect for kayaking, paddleboarding, and trails.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: '2',
|
|
20
|
+
name: 'Texas State Capitol',
|
|
21
|
+
rating: 4.8,
|
|
22
|
+
category: 'Historic Site',
|
|
23
|
+
location: 'Austin',
|
|
24
|
+
image: 'https://images.unsplash.com/photo-1664231978322-4d0b45c7027b?w=400&h=400&fit=crop',
|
|
25
|
+
description: 'Stunning capitol building with free tours and beautiful grounds.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: '3',
|
|
29
|
+
name: 'The Paramount Theatre',
|
|
30
|
+
rating: 4.7,
|
|
31
|
+
category: 'Architecture',
|
|
32
|
+
location: 'Austin',
|
|
33
|
+
image: 'https://images.unsplash.com/photo-1583097090970-4d3b940ea1a0?w=400&h=400&fit=crop',
|
|
34
|
+
description: 'Century-old performance and movie theatre in the heart of downtown Austin.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: '4',
|
|
38
|
+
name: 'Zilker Park',
|
|
39
|
+
rating: 4.7,
|
|
40
|
+
category: 'Park',
|
|
41
|
+
location: 'Austin',
|
|
42
|
+
image: 'https://images.unsplash.com/photo-1563828568124-f800803ba13c?w=400&h=400&fit=crop',
|
|
43
|
+
description: 'Popular park with trails, sports fields, and Barton Springs Pool.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: '5',
|
|
47
|
+
name: 'South Congress Avenue',
|
|
48
|
+
rating: 4.6,
|
|
49
|
+
category: 'Landmark',
|
|
50
|
+
location: 'Austin',
|
|
51
|
+
image: 'https://images.unsplash.com/photo-1588993608283-7f0eda4438be?w=400&h=400&fit=crop',
|
|
52
|
+
description: 'Vibrant street with unique shops, restaurants, and live music.',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
54
56
|
|
|
55
57
|
createRoot(document.getElementById('root')!).render(
|
|
56
58
|
<StrictMode>
|
|
@@ -58,8 +60,9 @@ createRoot(document.getElementById('root')!).render(
|
|
|
58
60
|
appName="Splorin"
|
|
59
61
|
appIcon="✈️"
|
|
60
62
|
userMessage="Show me popular places to visit in Austin Texas"
|
|
63
|
+
toolOutput={toolOutput}
|
|
61
64
|
>
|
|
62
|
-
<App
|
|
65
|
+
<App />
|
|
63
66
|
</ChatGPTSimulator>
|
|
64
67
|
</StrictMode>
|
|
65
68
|
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { runMCPServer } from 'sunpeak/mcp';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
// Dummy data matching the dev script
|
|
8
|
+
const toolOutput = {
|
|
9
|
+
places: [
|
|
10
|
+
{
|
|
11
|
+
id: '1',
|
|
12
|
+
name: 'Lady Bird Lake',
|
|
13
|
+
rating: 4.5,
|
|
14
|
+
category: 'Waterfront',
|
|
15
|
+
location: 'Austin',
|
|
16
|
+
image: 'https://images.unsplash.com/photo-1520950237264-dfe336995c34?w=400&h=400&fit=crop',
|
|
17
|
+
description: 'Scenic lake perfect for kayaking, paddleboarding, and trails.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: '2',
|
|
21
|
+
name: 'Texas State Capitol',
|
|
22
|
+
rating: 4.8,
|
|
23
|
+
category: 'Historic Site',
|
|
24
|
+
location: 'Austin',
|
|
25
|
+
image: 'https://images.unsplash.com/photo-1664231978322-4d0b45c7027b?w=400&h=400&fit=crop',
|
|
26
|
+
description: 'Stunning capitol building with free tours and beautiful grounds.',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: '3',
|
|
30
|
+
name: 'The Paramount Theatre',
|
|
31
|
+
rating: 4.7,
|
|
32
|
+
category: 'Architecture',
|
|
33
|
+
location: 'Austin',
|
|
34
|
+
image: 'https://images.unsplash.com/photo-1583097090970-4d3b940ea1a0?w=400&h=400&fit=crop',
|
|
35
|
+
description: 'Century-old performance and movie theatre in the heart of downtown Austin.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: '4',
|
|
39
|
+
name: 'Zilker Park',
|
|
40
|
+
rating: 4.7,
|
|
41
|
+
category: 'Park',
|
|
42
|
+
location: 'Austin',
|
|
43
|
+
image: 'https://images.unsplash.com/photo-1563828568124-f800803ba13c?w=400&h=400&fit=crop',
|
|
44
|
+
description: 'Popular park with trails, sports fields, and Barton Springs Pool.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: '5',
|
|
48
|
+
name: 'South Congress Avenue',
|
|
49
|
+
rating: 4.6,
|
|
50
|
+
category: 'Landmark',
|
|
51
|
+
location: 'Austin',
|
|
52
|
+
image: 'https://images.unsplash.com/photo-1588993608283-7f0eda4438be?w=400&h=400&fit=crop',
|
|
53
|
+
description: 'Vibrant street with unique shops, restaurants, and live music.',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
runMCPServer({
|
|
59
|
+
name: 'my-sunpeak-app',
|
|
60
|
+
version: '0.1.0',
|
|
61
|
+
distPath: path.resolve(__dirname, '../dist/chatgpt/index.global.js'),
|
|
62
|
+
toolName: 'show-places',
|
|
63
|
+
toolDescription: 'Show popular places in Austin',
|
|
64
|
+
dummyData: toolOutput,
|
|
65
|
+
port: 6766,
|
|
66
|
+
});
|
package/template/package.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsup",
|
|
8
8
|
"dev": "vite",
|
|
9
|
+
"mcp": "tsx mcp/server.ts",
|
|
9
10
|
"lint": "eslint . --ext .ts,.tsx --fix",
|
|
10
11
|
"typecheck": "tsc --noEmit",
|
|
11
12
|
"test": "vitest run"
|
|
@@ -27,7 +28,9 @@
|
|
|
27
28
|
"tw-animate-css": "^1.4.0"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
31
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
30
32
|
"@tailwindcss/vite": "^4.1.17",
|
|
33
|
+
"postcss": "^8.4.49",
|
|
31
34
|
"@testing-library/jest-dom": "^6.9.1",
|
|
32
35
|
"@testing-library/react": "^16.3.0",
|
|
33
36
|
"@testing-library/user-event": "^14.6.1",
|
package/template/src/App.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { useWidgetProps } from 'sunpeak';
|
|
1
2
|
import { SunpeakCarousel, SunpeakCard } from './components';
|
|
3
|
+
import 'tw-animate-css';
|
|
2
4
|
import '@/styles/globals.css';
|
|
3
5
|
import '@/styles/chatgpt.css';
|
|
4
6
|
|
|
@@ -12,14 +14,16 @@ export interface Place {
|
|
|
12
14
|
description: string;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export interface
|
|
16
|
-
|
|
17
|
+
export interface AppData extends Record<string, unknown> {
|
|
18
|
+
places: Place[];
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
export function App(
|
|
21
|
+
export function App() {
|
|
22
|
+
const data = useWidgetProps<AppData>(() => ({ places: [] }));
|
|
23
|
+
|
|
20
24
|
return (
|
|
21
25
|
<SunpeakCarousel gap={16} showArrows={true} showEdgeGradients={true} cardWidth={220}>
|
|
22
|
-
{data.map((place) => (
|
|
26
|
+
{data.places.map((place) => (
|
|
23
27
|
<SunpeakCard
|
|
24
28
|
key={place.id}
|
|
25
29
|
image={place.image}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
|
+
import { useWidgetState } from "sunpeak"
|
|
2
3
|
import { cn } from "@/lib/index"
|
|
3
4
|
import {
|
|
4
5
|
Card,
|
|
@@ -15,10 +16,27 @@ export interface SunpeakButtonProps extends Omit<React.ComponentProps<typeof But
|
|
|
15
16
|
onClick: () => void
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
export interface SunpeakCardData extends Record<string, unknown> {
|
|
20
|
+
image?: string
|
|
21
|
+
imageAlt?: string
|
|
22
|
+
imageMaxWidth?: number
|
|
23
|
+
imageMaxHeight?: number
|
|
24
|
+
header?: React.ReactNode
|
|
25
|
+
metadata?: React.ReactNode
|
|
26
|
+
children?: React.ReactNode
|
|
27
|
+
button1?: SunpeakButtonProps
|
|
28
|
+
button2?: SunpeakButtonProps
|
|
29
|
+
variant?: "default" | "bordered" | "elevated"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SunpeakCardState extends Record<string, unknown> {
|
|
33
|
+
selectedVariant?: "default" | "bordered" | "elevated"
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
export interface SunpeakCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
19
37
|
children?: React.ReactNode
|
|
20
|
-
image
|
|
21
|
-
imageAlt
|
|
38
|
+
image?: string
|
|
39
|
+
imageAlt?: string
|
|
22
40
|
imageMaxWidth?: number
|
|
23
41
|
imageMaxHeight?: number
|
|
24
42
|
header?: React.ReactNode
|
|
@@ -31,22 +49,35 @@ export interface SunpeakCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
31
49
|
export const SunpeakCard = React.forwardRef<HTMLDivElement, SunpeakCardProps>(
|
|
32
50
|
(
|
|
33
51
|
{
|
|
34
|
-
children,
|
|
35
|
-
image,
|
|
36
|
-
imageAlt,
|
|
37
|
-
imageMaxWidth = 400,
|
|
38
|
-
imageMaxHeight = 400,
|
|
39
|
-
header,
|
|
40
|
-
metadata,
|
|
41
|
-
button1,
|
|
42
|
-
button2,
|
|
43
|
-
variant = "default",
|
|
52
|
+
children: childrenProp,
|
|
53
|
+
image: imageProp,
|
|
54
|
+
imageAlt: imageAltProp,
|
|
55
|
+
imageMaxWidth: imageMaxWidthProp = 400,
|
|
56
|
+
imageMaxHeight: imageMaxHeightProp = 400,
|
|
57
|
+
header: headerProp,
|
|
58
|
+
metadata: metadataProp,
|
|
59
|
+
button1: button1Prop,
|
|
60
|
+
button2: button2Prop,
|
|
61
|
+
variant: variantProp = "default",
|
|
44
62
|
className,
|
|
45
63
|
onClick,
|
|
46
64
|
...props
|
|
47
65
|
},
|
|
48
66
|
ref
|
|
49
67
|
) => {
|
|
68
|
+
const [widgetState] = useWidgetState<SunpeakCardState>(() => ({}))
|
|
69
|
+
|
|
70
|
+
const children = childrenProp
|
|
71
|
+
const image = imageProp
|
|
72
|
+
const imageAlt = imageAltProp
|
|
73
|
+
const imageMaxWidth = imageMaxWidthProp
|
|
74
|
+
const imageMaxHeight = imageMaxHeightProp
|
|
75
|
+
const header = headerProp
|
|
76
|
+
const metadata = metadataProp
|
|
77
|
+
const button1 = button1Prop
|
|
78
|
+
const button2 = button2Prop
|
|
79
|
+
const variant = widgetState?.selectedVariant ?? variantProp
|
|
80
|
+
|
|
50
81
|
const hasButtons = button1 || button2
|
|
51
82
|
|
|
52
83
|
const handleCardClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import { WheelGesturesPlugin } from "embla-carousel-wheel-gestures"
|
|
3
|
+
import { useWidgetState, useDisplayMode } from "sunpeak"
|
|
3
4
|
import { cn } from "@/lib/index"
|
|
4
5
|
import {
|
|
5
6
|
Carousel,
|
|
@@ -10,6 +11,18 @@ import {
|
|
|
10
11
|
type CarouselApi,
|
|
11
12
|
} from "@/components/shadcn/carousel"
|
|
12
13
|
|
|
14
|
+
export interface SunpeakCarouselData extends Record<string, unknown> {
|
|
15
|
+
children?: React.ReactNode
|
|
16
|
+
gap?: number
|
|
17
|
+
showArrows?: boolean
|
|
18
|
+
showEdgeGradients?: boolean
|
|
19
|
+
cardWidth?: number | { inline?: number; fullscreen?: number }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SunpeakCarouselState extends Record<string, unknown> {
|
|
23
|
+
currentIndex?: number
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
export type SunpeakCarouselProps = {
|
|
14
27
|
children?: React.ReactNode
|
|
15
28
|
gap?: number
|
|
@@ -25,15 +38,26 @@ export const SunpeakCarousel = React.forwardRef<
|
|
|
25
38
|
>(
|
|
26
39
|
(
|
|
27
40
|
{
|
|
28
|
-
children,
|
|
29
|
-
gap = 16,
|
|
30
|
-
showArrows = true,
|
|
31
|
-
showEdgeGradients = true,
|
|
32
|
-
cardWidth,
|
|
41
|
+
children: childrenProp,
|
|
42
|
+
gap: gapProp = 16,
|
|
43
|
+
showArrows: showArrowsProp = true,
|
|
44
|
+
showEdgeGradients: showEdgeGradientsProp = true,
|
|
45
|
+
cardWidth: cardWidthProp,
|
|
33
46
|
className,
|
|
34
47
|
},
|
|
35
48
|
ref
|
|
36
49
|
) => {
|
|
50
|
+
const [widgetState, setWidgetState] = useWidgetState<SunpeakCarouselState>(() => ({
|
|
51
|
+
currentIndex: 0,
|
|
52
|
+
}))
|
|
53
|
+
const displayMode = useDisplayMode()
|
|
54
|
+
|
|
55
|
+
const children = childrenProp
|
|
56
|
+
const gap = gapProp
|
|
57
|
+
const showArrows = showArrowsProp
|
|
58
|
+
const showEdgeGradients = showEdgeGradientsProp
|
|
59
|
+
const cardWidth = cardWidthProp
|
|
60
|
+
|
|
37
61
|
const [api, setApi] = React.useState<CarouselApi>()
|
|
38
62
|
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
|
|
39
63
|
const [canScrollNext, setCanScrollNext] = React.useState(false)
|
|
@@ -44,6 +68,11 @@ export const SunpeakCarousel = React.forwardRef<
|
|
|
44
68
|
const onSelect = () => {
|
|
45
69
|
setCanScrollPrev(api.canScrollPrev())
|
|
46
70
|
setCanScrollNext(api.canScrollNext())
|
|
71
|
+
|
|
72
|
+
const currentIndex = api.selectedScrollSnap()
|
|
73
|
+
if (widgetState?.currentIndex !== currentIndex) {
|
|
74
|
+
setWidgetState({ currentIndex })
|
|
75
|
+
}
|
|
47
76
|
}
|
|
48
77
|
|
|
49
78
|
onSelect()
|
|
@@ -54,7 +83,7 @@ export const SunpeakCarousel = React.forwardRef<
|
|
|
54
83
|
api.off("select", onSelect)
|
|
55
84
|
api.off("reInit", onSelect)
|
|
56
85
|
}
|
|
57
|
-
}, [api])
|
|
86
|
+
}, [api, widgetState?.currentIndex, setWidgetState])
|
|
58
87
|
|
|
59
88
|
const childArray = React.Children.toArray(children)
|
|
60
89
|
|
|
@@ -62,8 +91,13 @@ export const SunpeakCarousel = React.forwardRef<
|
|
|
62
91
|
if (typeof cardWidth === "number") {
|
|
63
92
|
return `${cardWidth}px`
|
|
64
93
|
}
|
|
65
|
-
if (cardWidth
|
|
66
|
-
|
|
94
|
+
if (cardWidth && typeof cardWidth === "object") {
|
|
95
|
+
if (displayMode === "fullscreen" && cardWidth.fullscreen) {
|
|
96
|
+
return `${cardWidth.fullscreen}px`
|
|
97
|
+
}
|
|
98
|
+
if (cardWidth.inline) {
|
|
99
|
+
return `${cardWidth.inline}px`
|
|
100
|
+
}
|
|
67
101
|
}
|
|
68
102
|
return "220px"
|
|
69
103
|
}
|
package/template/tsup.config.ts
CHANGED
|
@@ -1,23 +1,50 @@
|
|
|
1
1
|
import { defineConfig } from 'tsup';
|
|
2
|
+
import postcss from 'postcss';
|
|
3
|
+
import tailwindcss from '@tailwindcss/postcss';
|
|
4
|
+
import type { Plugin } from 'esbuild';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
|
|
7
|
+
function postcssPlugin(): Plugin {
|
|
8
|
+
return {
|
|
9
|
+
name: 'postcss',
|
|
10
|
+
setup(build) {
|
|
11
|
+
build.onLoad({ filter: /\.css$/ }, async (args) => {
|
|
12
|
+
const css = fs.readFileSync(args.path, 'utf8');
|
|
13
|
+
const result = await postcss([tailwindcss()]).process(css, {
|
|
14
|
+
from: args.path,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
contents: result.css,
|
|
18
|
+
loader: 'css',
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
2
24
|
|
|
3
25
|
export default defineConfig({
|
|
4
26
|
entry: {
|
|
5
|
-
'chatgpt/index': 'src/
|
|
27
|
+
'chatgpt/index': 'src/index.chatgpt.tsx',
|
|
6
28
|
},
|
|
7
|
-
format: ['
|
|
29
|
+
format: ['iife'],
|
|
8
30
|
dts: false,
|
|
9
31
|
sourcemap: false,
|
|
10
32
|
clean: true,
|
|
11
33
|
external: [],
|
|
34
|
+
noExternal: [/.*/],
|
|
12
35
|
treeshake: true,
|
|
13
36
|
splitting: false,
|
|
14
37
|
minify: true,
|
|
15
38
|
outDir: 'dist',
|
|
16
39
|
injectStyle: true,
|
|
40
|
+
globalName: 'SunpeakApp',
|
|
41
|
+
esbuildPlugins: [postcssPlugin()],
|
|
17
42
|
esbuildOptions(options) {
|
|
18
43
|
options.bundle = true;
|
|
19
44
|
options.platform = 'browser';
|
|
20
45
|
options.target = 'es2020';
|
|
21
46
|
options.jsx = 'automatic';
|
|
47
|
+
// Enable "style" condition for CSS-only packages like tw-animate-css
|
|
48
|
+
options.conditions = ['style', 'import', 'module', 'browser', 'default'];
|
|
22
49
|
},
|
|
23
50
|
});
|