ai-design-system 0.1.29 → 0.1.30
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/components/features/PageLayout/PageLayout.mocks.ts +27 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +31 -51
- package/components/features/PageLayout/PageLayout.tsx +56 -12
- package/components/features/PageLayout/usePageLayout.d.ts +4 -0
- package/components/features/PageLayout/usePageLayout.mock.ts +64 -1
- package/components/features/RefinementPanel/RefinementPanel.stories.tsx +2 -2
- package/components/features/RefinementPanel/useRefinementPanel.mock.ts +8 -0
- package/dist/index.cjs +19 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +36 -0
- package/dist/index.d.ts +287 -0
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Mock data for PageLayout feature stories
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { FileChangeData } from '@/components/composites/FileQueue'
|
|
6
|
+
import type { RefinementMessage } from '@/components/features/RefinementPanel'
|
|
7
|
+
|
|
5
8
|
export const mockSidebarConfig = {
|
|
6
9
|
logo: { icon: 'command', text: 'Acme Inc.', href: '/' },
|
|
7
10
|
mainNavigation: [
|
|
@@ -34,3 +37,27 @@ export const mockHeaderConfigWithTabs = {
|
|
|
34
37
|
],
|
|
35
38
|
defaultTab: 'agent',
|
|
36
39
|
}
|
|
40
|
+
|
|
41
|
+
export const mockPageLayoutRefinementMessages: RefinementMessage[] = [
|
|
42
|
+
{
|
|
43
|
+
id: '1',
|
|
44
|
+
type: 'human',
|
|
45
|
+
role: 'user',
|
|
46
|
+
content: 'Please optimize this workflow for better performance',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: '2',
|
|
50
|
+
type: 'ai',
|
|
51
|
+
role: 'orchestrator',
|
|
52
|
+
content: "I'll analyze the workflow and suggest optimizations for better performance.",
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
export const mockPageLayoutFileChanges: FileChangeData[] = [
|
|
57
|
+
{
|
|
58
|
+
id: '1',
|
|
59
|
+
filename: 'workflow.json',
|
|
60
|
+
status: 'modified',
|
|
61
|
+
path: 'workflow.json',
|
|
62
|
+
},
|
|
63
|
+
]
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
-
import { useState } from 'react'
|
|
3
2
|
import { PageLayout } from './PageLayout'
|
|
4
|
-
import { usePageLayoutMock } from './usePageLayout.mock'
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { usePageLayoutMock, usePageLayoutStoryActionsMock } from './usePageLayout.mock'
|
|
4
|
+
import {
|
|
5
|
+
mockHeaderConfig,
|
|
6
|
+
mockHeaderConfigWithTabs,
|
|
7
|
+
mockPageLayoutFileChanges,
|
|
8
|
+
mockPageLayoutRefinementMessages,
|
|
9
|
+
mockSidebarConfig,
|
|
10
|
+
} from './PageLayout.mocks'
|
|
11
|
+
import { WorkflowBuilder } from '../WorkflowBuilder/WorkflowBuilder'
|
|
12
|
+
import { RefinementPanel } from '../RefinementPanel/RefinementPanel'
|
|
13
|
+
import { mockEdges, mockNodes, mockVersions } from '../WorkflowBuilder/WorkflowBuilder.mocks'
|
|
9
14
|
|
|
10
15
|
const meta = {
|
|
11
16
|
title: 'Features/PageLayout',
|
|
@@ -33,8 +38,8 @@ export const Default: Story = {
|
|
|
33
38
|
{
|
|
34
39
|
id: 'file-explorer',
|
|
35
40
|
content: (
|
|
36
|
-
<div className="h-full
|
|
37
|
-
<h3 className="font-medium
|
|
41
|
+
<div className="h-full rounded-lg border bg-muted p-4">
|
|
42
|
+
<h3 className="mb-2 font-medium">File Explorer</h3>
|
|
38
43
|
<p className="text-sm text-muted-foreground">Project files and folders</p>
|
|
39
44
|
</div>
|
|
40
45
|
),
|
|
@@ -47,8 +52,8 @@ export const Default: Story = {
|
|
|
47
52
|
{
|
|
48
53
|
id: 'editor',
|
|
49
54
|
content: (
|
|
50
|
-
<div className="h-full
|
|
51
|
-
<h3 className="font-medium
|
|
55
|
+
<div className="h-full rounded-lg border bg-muted p-4">
|
|
56
|
+
<h3 className="mb-2 font-medium">Editor</h3>
|
|
52
57
|
<p className="text-sm text-muted-foreground">Main editing area</p>
|
|
53
58
|
</div>
|
|
54
59
|
),
|
|
@@ -66,8 +71,8 @@ export const Default: Story = {
|
|
|
66
71
|
{
|
|
67
72
|
id: 'properties',
|
|
68
73
|
content: (
|
|
69
|
-
<div className="h-full
|
|
70
|
-
<h3 className="font-medium
|
|
74
|
+
<div className="h-full rounded-lg border bg-muted p-4">
|
|
75
|
+
<h3 className="mb-2 font-medium">Properties</h3>
|
|
71
76
|
<p className="text-sm text-muted-foreground">File and project properties</p>
|
|
72
77
|
</div>
|
|
73
78
|
),
|
|
@@ -91,40 +96,18 @@ export const Default: Story = {
|
|
|
91
96
|
export const WithStateManagement: Story = {
|
|
92
97
|
render: () => {
|
|
93
98
|
const layoutState = usePageLayoutMock()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const mockMessages = [
|
|
97
|
-
{
|
|
98
|
-
id: '1',
|
|
99
|
-
type: 'human' as const,
|
|
100
|
-
role: 'user' as const,
|
|
101
|
-
content: 'Please optimize this workflow for better performance',
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
id: '2',
|
|
105
|
-
type: 'ai' as const,
|
|
106
|
-
role: 'orchestrator' as const,
|
|
107
|
-
content: 'I\'ll analyze the workflow and suggest optimizations for better performance.',
|
|
108
|
-
},
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
const mockFileChanges = [
|
|
112
|
-
{
|
|
113
|
-
id: '1',
|
|
114
|
-
filename: 'workflow.json',
|
|
115
|
-
status: 'modified' as const,
|
|
116
|
-
path: 'workflow.json',
|
|
117
|
-
changes: '+ Added parallel processing\n+ Optimized node connections',
|
|
118
|
-
},
|
|
119
|
-
]
|
|
120
|
-
|
|
99
|
+
const actions = usePageLayoutStoryActionsMock()
|
|
100
|
+
|
|
121
101
|
return (
|
|
122
102
|
<PageLayout
|
|
123
103
|
sidebar={mockSidebarConfig}
|
|
124
104
|
header={{
|
|
125
105
|
...mockHeaderConfigWithTabs,
|
|
106
|
+
defaultTab: layoutState.activeTab,
|
|
126
107
|
onTabChange: layoutState.onTabChange,
|
|
127
108
|
}}
|
|
109
|
+
isLoading={layoutState.isLoading}
|
|
110
|
+
loadingMessage={layoutState.loadingMessage}
|
|
128
111
|
defaultSidebarOpen={layoutState.isSidebarOpen}
|
|
129
112
|
layoutSections={[
|
|
130
113
|
{
|
|
@@ -136,11 +119,10 @@ export const WithStateManagement: Story = {
|
|
|
136
119
|
versions={mockVersions}
|
|
137
120
|
nodes={mockNodes}
|
|
138
121
|
edges={mockEdges}
|
|
139
|
-
onVersionSelect={
|
|
140
|
-
onSave={
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
onRedo={() => console.log('Redo')}
|
|
122
|
+
onVersionSelect={actions.onVersionSelect}
|
|
123
|
+
onSave={actions.onSave}
|
|
124
|
+
onUndo={actions.onUndo}
|
|
125
|
+
onRedo={actions.onRedo}
|
|
144
126
|
hasUnsavedChanges={true}
|
|
145
127
|
canUndo={true}
|
|
146
128
|
canRedo={false}
|
|
@@ -154,13 +136,11 @@ export const WithStateManagement: Story = {
|
|
|
154
136
|
id: 'refinement-panel',
|
|
155
137
|
content: (
|
|
156
138
|
<RefinementPanel
|
|
157
|
-
messages={
|
|
158
|
-
fileChanges={
|
|
159
|
-
onSubmit={
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
onApprove={() => console.log('Changes approved')}
|
|
163
|
-
onReject={() => console.log('Changes rejected')}
|
|
139
|
+
messages={mockPageLayoutRefinementMessages}
|
|
140
|
+
fileChanges={mockPageLayoutFileChanges}
|
|
141
|
+
onSubmit={actions.onSubmit}
|
|
142
|
+
onApprove={actions.onApprove}
|
|
143
|
+
onReject={actions.onReject}
|
|
164
144
|
placeholder="Ask for workflow optimizations or describe changes..."
|
|
165
145
|
/>
|
|
166
146
|
),
|
|
@@ -2,10 +2,30 @@ import * as React from "react"
|
|
|
2
2
|
import { AppSidebar, type AppSidebarProps } from "@/components/blocks/AppSidebar"
|
|
3
3
|
import { LayoutProvider } from "@/components/blocks/LayoutProvider"
|
|
4
4
|
import { SectionLayout } from "@/components/blocks/SectionLayout/SectionLayout"
|
|
5
|
-
import type {
|
|
5
|
+
import type { SectionLayoutSection } from "@/components/blocks/SectionLayout/interfaces"
|
|
6
6
|
import { AppHeader, type AppHeaderProps } from "@/components/composites/AppHeader"
|
|
7
7
|
import { PageContainer } from "@/components/composites/PageContainer"
|
|
8
8
|
|
|
9
|
+
function PageLayoutLoadingState({ message }: { message: string }) {
|
|
10
|
+
return (
|
|
11
|
+
<div className="flex h-full min-h-0 flex-1 items-center justify-center px-6 py-10">
|
|
12
|
+
<div className="w-full max-w-3xl space-y-5">
|
|
13
|
+
<div className="inline-flex w-fit animate-pulse rounded-md bg-muted px-3 py-1 text-sm text-muted-foreground">
|
|
14
|
+
{message}
|
|
15
|
+
</div>
|
|
16
|
+
<div className="space-y-3">
|
|
17
|
+
<div className="h-10 w-1/3 animate-pulse rounded-md bg-muted/70" />
|
|
18
|
+
<div className="h-24 w-full animate-pulse rounded-xl bg-muted/60" />
|
|
19
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
20
|
+
<div className="h-36 animate-pulse rounded-xl bg-muted/55" />
|
|
21
|
+
<div className="h-36 animate-pulse rounded-xl bg-muted/55" />
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
9
29
|
/**
|
|
10
30
|
* PageLayout Feature
|
|
11
31
|
*
|
|
@@ -56,6 +76,24 @@ export interface PageLayoutProps {
|
|
|
56
76
|
* Optional when layoutSections is provided
|
|
57
77
|
*/
|
|
58
78
|
children?: React.ReactNode
|
|
79
|
+
/**
|
|
80
|
+
* Whether the page content should render a built-in loading state.
|
|
81
|
+
*/
|
|
82
|
+
isLoading?: boolean
|
|
83
|
+
/**
|
|
84
|
+
* Optional loading message shown inside the built-in shimmer state.
|
|
85
|
+
* @default "Loading..."
|
|
86
|
+
*/
|
|
87
|
+
loadingMessage?: string
|
|
88
|
+
/**
|
|
89
|
+
* Optional custom shimmer/loading UI provided by the consumer.
|
|
90
|
+
* When omitted, PageLayout renders its built-in default shimmer state.
|
|
91
|
+
*/
|
|
92
|
+
loadingShimmer?: React.ReactNode
|
|
93
|
+
/**
|
|
94
|
+
* Custom loading fallback. When provided, this replaces the built-in shimmer layout.
|
|
95
|
+
*/
|
|
96
|
+
loadingFallback?: React.ReactNode
|
|
59
97
|
/**
|
|
60
98
|
* Additional CSS classes
|
|
61
99
|
*/
|
|
@@ -107,6 +145,10 @@ export const PageLayout = React.memo<PageLayoutProps>(
|
|
|
107
145
|
sidebar,
|
|
108
146
|
header,
|
|
109
147
|
children,
|
|
148
|
+
isLoading = false,
|
|
149
|
+
loadingMessage = "Loading...",
|
|
150
|
+
loadingShimmer,
|
|
151
|
+
loadingFallback,
|
|
110
152
|
className,
|
|
111
153
|
defaultSidebarOpen = true,
|
|
112
154
|
sidebarWidth = "var(--spacing-sidebar-width)",
|
|
@@ -116,17 +158,19 @@ export const PageLayout = React.memo<PageLayoutProps>(
|
|
|
116
158
|
layoutStorageKey,
|
|
117
159
|
dragHandleColor = "border",
|
|
118
160
|
}) => {
|
|
119
|
-
const contentArea =
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
161
|
+
const contentArea = isLoading
|
|
162
|
+
? (loadingShimmer ?? loadingFallback ?? <PageLayoutLoadingState message={loadingMessage} />)
|
|
163
|
+
: layoutSections ? (
|
|
164
|
+
<SectionLayout
|
|
165
|
+
sections={layoutSections}
|
|
166
|
+
orientation={layoutOrientation}
|
|
167
|
+
storageKey={layoutStorageKey}
|
|
168
|
+
dragHandleColor={dragHandleColor}
|
|
169
|
+
className="flex-1 min-h-0"
|
|
170
|
+
/>
|
|
171
|
+
) : (
|
|
172
|
+
<div className="flex min-h-0 flex-1 flex-col">{children}</div>
|
|
173
|
+
)
|
|
130
174
|
|
|
131
175
|
const pageContainer = (
|
|
132
176
|
<PageContainer className={`overflow-hidden ${className ?? ""}`}>
|
|
@@ -12,6 +12,10 @@ export interface UsePageLayoutReturn {
|
|
|
12
12
|
isSidebarOpen: boolean
|
|
13
13
|
/** Currently active tab value */
|
|
14
14
|
activeTab: string
|
|
15
|
+
/** Whether a page-level loading state is active */
|
|
16
|
+
isLoading: boolean
|
|
17
|
+
/** Optional message for the page-level loading state */
|
|
18
|
+
loadingMessage?: string
|
|
15
19
|
/** Toggle sidebar open/closed */
|
|
16
20
|
toggleSidebar: () => void
|
|
17
21
|
/** Set sidebar open state */
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { useState, useCallback } from 'react'
|
|
1
|
+
import { useState, useCallback, useEffect, useRef } from 'react'
|
|
2
|
+
import type { FormEvent } from 'react'
|
|
3
|
+
import type { PromptInputMessage } from '@/components/ai-elements/prompt-input'
|
|
2
4
|
import type { UsePageLayoutReturn } from './usePageLayout.d'
|
|
3
5
|
|
|
4
6
|
/**
|
|
@@ -7,15 +9,36 @@ import type { UsePageLayoutReturn } from './usePageLayout.d'
|
|
|
7
9
|
export const usePageLayoutMock = (): UsePageLayoutReturn => {
|
|
8
10
|
const [isSidebarOpen, setIsSidebarOpen] = useState(true)
|
|
9
11
|
const [activeTab, setActiveTab] = useState('agent')
|
|
12
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
13
|
+
const loadingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
return () => {
|
|
17
|
+
if (loadingTimerRef.current) {
|
|
18
|
+
clearTimeout(loadingTimerRef.current)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}, [])
|
|
10
22
|
|
|
11
23
|
const handleTabChange = useCallback((value: string) => {
|
|
12
24
|
console.log('🔄 State Management - Tab switched to:', value)
|
|
13
25
|
setActiveTab(value)
|
|
26
|
+
setIsLoading(true)
|
|
27
|
+
|
|
28
|
+
if (loadingTimerRef.current) {
|
|
29
|
+
clearTimeout(loadingTimerRef.current)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
loadingTimerRef.current = setTimeout(() => {
|
|
33
|
+
setIsLoading(false)
|
|
34
|
+
}, 900)
|
|
14
35
|
}, [])
|
|
15
36
|
|
|
16
37
|
return {
|
|
17
38
|
isSidebarOpen,
|
|
18
39
|
activeTab,
|
|
40
|
+
isLoading,
|
|
41
|
+
loadingMessage: `Loading ${activeTab} view...`,
|
|
19
42
|
toggleSidebar: () => {
|
|
20
43
|
const newState = !isSidebarOpen
|
|
21
44
|
console.log('🔄 State Management - Sidebar toggled to:', newState)
|
|
@@ -32,3 +55,43 @@ export const usePageLayoutMock = (): UsePageLayoutReturn => {
|
|
|
32
55
|
},
|
|
33
56
|
}
|
|
34
57
|
}
|
|
58
|
+
|
|
59
|
+
export function usePageLayoutStoryActionsMock() {
|
|
60
|
+
const onVersionSelect = useCallback((id: string) => {
|
|
61
|
+
console.log('🔄 State Management - Selected version:', id)
|
|
62
|
+
}, [])
|
|
63
|
+
|
|
64
|
+
const onSave = useCallback(() => {
|
|
65
|
+
console.log('🔄 State Management - Workflow saved')
|
|
66
|
+
}, [])
|
|
67
|
+
|
|
68
|
+
const onUndo = useCallback(() => {
|
|
69
|
+
console.log('🔄 State Management - Undo')
|
|
70
|
+
}, [])
|
|
71
|
+
|
|
72
|
+
const onRedo = useCallback(() => {
|
|
73
|
+
console.log('🔄 State Management - Redo')
|
|
74
|
+
}, [])
|
|
75
|
+
|
|
76
|
+
const onSubmit = useCallback((message: PromptInputMessage, _event: FormEvent<HTMLFormElement>) => {
|
|
77
|
+
console.log('🔄 State Management - Refinement request:', message)
|
|
78
|
+
}, [])
|
|
79
|
+
|
|
80
|
+
const onApprove = useCallback(() => {
|
|
81
|
+
console.log('🔄 State Management - Changes approved')
|
|
82
|
+
}, [])
|
|
83
|
+
|
|
84
|
+
const onReject = useCallback(() => {
|
|
85
|
+
console.log('🔄 State Management - Changes rejected')
|
|
86
|
+
}, [])
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
onVersionSelect,
|
|
90
|
+
onSave,
|
|
91
|
+
onUndo,
|
|
92
|
+
onRedo,
|
|
93
|
+
onSubmit,
|
|
94
|
+
onApprove,
|
|
95
|
+
onReject,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -110,7 +110,7 @@ export const MultiAgentReviewState: Story = {
|
|
|
110
110
|
export const WithStateManagement: Story = {
|
|
111
111
|
render: () => {
|
|
112
112
|
// Use mocked hook for state management
|
|
113
|
-
const { messages, fileChanges,
|
|
113
|
+
const { messages, fileChanges, onSubmit, handleApprove, handleReject } =
|
|
114
114
|
useRefinementPanelMock({
|
|
115
115
|
initialMessages: inputStateMessages,
|
|
116
116
|
reviewMessages: reviewStateMessages,
|
|
@@ -123,7 +123,7 @@ export const WithStateManagement: Story = {
|
|
|
123
123
|
messages={messages}
|
|
124
124
|
fileChanges={fileChanges}
|
|
125
125
|
placeholder="Ask a question or describe a task..."
|
|
126
|
-
onSubmit={
|
|
126
|
+
onSubmit={onSubmit}
|
|
127
127
|
onApprove={handleApprove}
|
|
128
128
|
onReject={handleReject}
|
|
129
129
|
/>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useState, useCallback } from "react";
|
|
2
2
|
import type { RefinementMessage } from "./RefinementPanel";
|
|
3
3
|
import type { FileChangeData } from "@/components/composites/FileQueue";
|
|
4
|
+
import type { PromptInputMessage } from "@/components/ai-elements/prompt-input";
|
|
5
|
+
import type { FormEvent } from "react";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Mock hook for RefinementPanel state management
|
|
@@ -18,6 +20,7 @@ export interface UseRefinementPanelReturn {
|
|
|
18
20
|
fileChanges: FileChangeData[];
|
|
19
21
|
loading: boolean;
|
|
20
22
|
handleSubmit: (prompt: string) => Promise<void>;
|
|
23
|
+
onSubmit: (message: PromptInputMessage, event: FormEvent<HTMLFormElement>) => Promise<void>;
|
|
21
24
|
handleApprove: () => Promise<void>;
|
|
22
25
|
handleReject: () => Promise<void>;
|
|
23
26
|
}
|
|
@@ -62,6 +65,10 @@ export function useRefinementPanelMock(
|
|
|
62
65
|
setLoading(false);
|
|
63
66
|
}, [reviewMessages, reviewFileChanges, apiDelay]);
|
|
64
67
|
|
|
68
|
+
const onSubmit = useCallback(async (message: PromptInputMessage, _event: FormEvent<HTMLFormElement>) => {
|
|
69
|
+
await handleSubmit(message.text);
|
|
70
|
+
}, [handleSubmit]);
|
|
71
|
+
|
|
65
72
|
// Simulate approval: clear file changes and add success message
|
|
66
73
|
const handleApprove = useCallback(async () => {
|
|
67
74
|
setLoading(true);
|
|
@@ -115,6 +122,7 @@ export function useRefinementPanelMock(
|
|
|
115
122
|
fileChanges,
|
|
116
123
|
loading,
|
|
117
124
|
handleSubmit,
|
|
125
|
+
onSubmit,
|
|
118
126
|
handleApprove,
|
|
119
127
|
handleReject,
|
|
120
128
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1671,11 +1671,28 @@ var PageContainer = React3__namespace.memo(({ children, className }) => {
|
|
|
1671
1671
|
return /* @__PURE__ */ jsxRuntime.jsx(SidebarInset2, { className, children });
|
|
1672
1672
|
});
|
|
1673
1673
|
PageContainer.displayName = "PageContainer";
|
|
1674
|
+
function PageLayoutLoadingState({ message }) {
|
|
1675
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full min-h-0 flex-1 items-center justify-center px-6 py-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-3xl space-y-5", children: [
|
|
1676
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex w-fit animate-pulse rounded-md bg-muted px-3 py-1 text-sm text-muted-foreground", children: message }),
|
|
1677
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1678
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-10 w-1/3 animate-pulse rounded-md bg-muted/70" }),
|
|
1679
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-24 w-full animate-pulse rounded-xl bg-muted/60" }),
|
|
1680
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [
|
|
1681
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-36 animate-pulse rounded-xl bg-muted/55" }),
|
|
1682
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-36 animate-pulse rounded-xl bg-muted/55" })
|
|
1683
|
+
] })
|
|
1684
|
+
] })
|
|
1685
|
+
] }) });
|
|
1686
|
+
}
|
|
1674
1687
|
var PageLayout = React3__namespace.memo(
|
|
1675
1688
|
({
|
|
1676
1689
|
sidebar,
|
|
1677
1690
|
header,
|
|
1678
1691
|
children,
|
|
1692
|
+
isLoading = false,
|
|
1693
|
+
loadingMessage = "Loading...",
|
|
1694
|
+
loadingShimmer,
|
|
1695
|
+
loadingFallback,
|
|
1679
1696
|
className,
|
|
1680
1697
|
defaultSidebarOpen = true,
|
|
1681
1698
|
sidebarWidth = "var(--spacing-sidebar-width)",
|
|
@@ -1685,7 +1702,8 @@ var PageLayout = React3__namespace.memo(
|
|
|
1685
1702
|
layoutStorageKey,
|
|
1686
1703
|
dragHandleColor = "border"
|
|
1687
1704
|
}) => {
|
|
1688
|
-
|
|
1705
|
+
var _a;
|
|
1706
|
+
const contentArea = isLoading ? (_a = loadingShimmer != null ? loadingShimmer : loadingFallback) != null ? _a : /* @__PURE__ */ jsxRuntime.jsx(PageLayoutLoadingState, { message: loadingMessage }) : layoutSections ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1689
1707
|
SectionLayout,
|
|
1690
1708
|
{
|
|
1691
1709
|
sections: layoutSections,
|