@akinon/ui-shell-dev 1.3.5 → 1.3.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.
@@ -0,0 +1,3 @@
1
+ <svg width="53" height="52" viewBox="0 0 53 52" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M38.3113 27.0107C37.5819 26.3304 36.7339 25.7864 35.7661 25.3776C34.7983 24.9698 33.7626 24.7654 32.6567 24.7654C31.5508 24.7654 30.5139 24.9698 29.5461 25.3776C28.5784 25.7864 27.7303 26.3304 27.0021 27.0107C26.2727 27.6921 25.6944 28.4762 25.2672 29.3674C24.8399 30.2586 24.6263 31.1866 24.6263 32.1514C24.6263 33.3638 24.8399 34.4767 25.2672 35.4912C25.6944 36.5068 26.2727 37.3839 27.0021 38.1269C27.7303 38.8689 28.5784 39.4508 29.5461 39.8715C30.5139 40.2922 31.5508 40.502 32.6567 40.502C33.7626 40.502 34.7983 40.2922 35.7661 39.8715C36.7339 39.4508 37.5819 38.8689 38.3113 38.1269C39.0395 37.3839 39.6178 36.5068 40.0451 35.4912C40.4723 34.4767 40.686 33.3638 40.686 32.1514C40.686 31.1866 40.4723 30.2586 40.0451 29.3674C39.6178 28.4762 39.0395 27.6921 38.3113 27.0107ZM35.4823 17.9505L26.3774 0L0 52H52.7536L46.5423 39.7547C45.8464 41.0525 44.9822 42.2109 43.9475 43.2297C42.5525 44.6033 40.8931 45.6675 38.9705 46.4213C37.0478 47.1763 34.9429 47.5537 32.6566 47.5537C30.3693 47.5537 28.2644 47.1763 26.3417 46.4213C24.4191 45.6675 22.7608 44.6033 21.3658 43.2297C19.9707 41.8561 18.8832 40.2295 18.1053 38.3497C17.3252 36.4689 16.9358 34.3912 16.9358 32.1135C16.9358 30.0109 17.3695 28.075 18.2369 26.3055C19.1033 24.5372 20.2664 23.0155 21.724 21.7403C23.1816 20.4662 24.8582 19.4766 26.7571 18.7714C28.6539 18.0663 30.6207 17.7137 32.6566 17.7137C33.6136 17.7137 34.5555 17.7948 35.4823 17.9505Z" fill="#D2282E"/>
3
+ </svg>
package/dist/index.html CHANGED
@@ -24,7 +24,7 @@
24
24
  box-sizing: border-box;
25
25
  }
26
26
  </style>
27
- <script type="module" crossorigin src="/assets/index-CDUI6TEB.js"></script>
27
+ <script type="module" crossorigin src="/assets/index-CNgx52S6.js"></script>
28
28
  <link rel="stylesheet" crossorigin href="/assets/index-BFs1gfY5.css">
29
29
  </head>
30
30
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/ui-shell-dev",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "private": false,
5
5
  "description": "Development shell application for Akinon UI Protocol plugins",
6
6
  "type": "module",
@@ -0,0 +1,3 @@
1
+ <svg width="53" height="52" viewBox="0 0 53 52" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M38.3113 27.0107C37.5819 26.3304 36.7339 25.7864 35.7661 25.3776C34.7983 24.9698 33.7626 24.7654 32.6567 24.7654C31.5508 24.7654 30.5139 24.9698 29.5461 25.3776C28.5784 25.7864 27.7303 26.3304 27.0021 27.0107C26.2727 27.6921 25.6944 28.4762 25.2672 29.3674C24.8399 30.2586 24.6263 31.1866 24.6263 32.1514C24.6263 33.3638 24.8399 34.4767 25.2672 35.4912C25.6944 36.5068 26.2727 37.3839 27.0021 38.1269C27.7303 38.8689 28.5784 39.4508 29.5461 39.8715C30.5139 40.2922 31.5508 40.502 32.6567 40.502C33.7626 40.502 34.7983 40.2922 35.7661 39.8715C36.7339 39.4508 37.5819 38.8689 38.3113 38.1269C39.0395 37.3839 39.6178 36.5068 40.0451 35.4912C40.4723 34.4767 40.686 33.3638 40.686 32.1514C40.686 31.1866 40.4723 30.2586 40.0451 29.3674C39.6178 28.4762 39.0395 27.6921 38.3113 27.0107ZM35.4823 17.9505L26.3774 0L0 52H52.7536L46.5423 39.7547C45.8464 41.0525 44.9822 42.2109 43.9475 43.2297C42.5525 44.6033 40.8931 45.6675 38.9705 46.4213C37.0478 47.1763 34.9429 47.5537 32.6566 47.5537C30.3693 47.5537 28.2644 47.1763 26.3417 46.4213C24.4191 45.6675 22.7608 44.6033 21.3658 43.2297C19.9707 41.8561 18.8832 40.2295 18.1053 38.3497C17.3252 36.4689 16.9358 34.3912 16.9358 32.1135C16.9358 30.0109 17.3695 28.075 18.2369 26.3055C19.1033 24.5372 20.2664 23.0155 21.724 21.7403C23.1816 20.4662 24.8582 19.4766 26.7571 18.7714C28.6539 18.0663 30.6207 17.7137 32.6566 17.7137C33.6136 17.7137 34.5555 17.7948 35.4823 17.9505Z" fill="#D2282E"/>
3
+ </svg>
@@ -7,7 +7,8 @@ import { useLocation, useNavigate } from 'react-router-dom';
7
7
  import {
8
8
  getFullpageNavigationItems,
9
9
  getPluginNavigationItems,
10
- getStaticNavigationItems
10
+ getStaticNavigationItems,
11
+ getStaticNavigationItemsBottom
11
12
  } from '../utils/navigation';
12
13
 
13
14
  export const Navigation: React.FC = () => {
@@ -17,11 +18,12 @@ export const Navigation: React.FC = () => {
17
18
  const [selectedKey, setSelectedKey] = useState('/');
18
19
  const [openKeys, setOpenKeys] = useState<string[]>([]);
19
20
  const items = getStaticNavigationItems();
21
+ const itemsBottom = getStaticNavigationItemsBottom();
20
22
  const fullpageItems = getFullpageNavigationItems(
21
23
  apps,
22
24
  configs as Map<number, any>
23
25
  );
24
- const pluginItems = getPluginNavigationItems();
26
+ const pluginItems = getPluginNavigationItems(apps);
25
27
 
26
28
  useEffect(() => {
27
29
  setSelectedKey(location.pathname);
@@ -44,7 +46,7 @@ export const Navigation: React.FC = () => {
44
46
  <Menu
45
47
  mode="inline"
46
48
  selectedKeys={[selectedKey]}
47
- items={[...items, ...fullpageItems, ...pluginItems]}
49
+ items={[...items, ...fullpageItems, ...pluginItems, ...itemsBottom]}
48
50
  onClick={onClick}
49
51
  theme="dark"
50
52
  openKeys={openKeys}
@@ -83,18 +83,14 @@ export const PluginTestPage: React.FC = () => {
83
83
  textAlign: 'center',
84
84
  padding: '48px',
85
85
  border: '1px dashed #d9d9d9',
86
- borderRadius: '8px',
87
- backgroundColor: '#fafafa'
86
+ borderRadius: '8px'
88
87
  }}
89
88
  >
90
- <h3>No Plugin Configurations Found</h3>
89
+ <h2>No Plugin Configurations Found</h2>
91
90
  <p>
92
91
  No plugin applications with placeholder configurations were
93
- found.
94
- </p>
95
- <p>
96
- Make sure your shell configuration includes plugin apps with
97
- placeholder IDs.
92
+ found. <br /> Make sure your shell configuration includes plugin
93
+ apps with placeholder IDs.
98
94
  </p>
99
95
  </div>
100
96
  )}
@@ -1,86 +1,136 @@
1
1
  import { useAppShell } from '@akinon/app-shell';
2
- import { Button, Card, Divider, Tag } from '@akinon/ui-react';
2
+ import { Card, Divider, Tag } from '@akinon/ui-react';
3
3
  import React from 'react';
4
- import { useNavigate } from 'react-router-dom';
4
+
5
+ import { ShellConfig } from '@/types';
6
+
7
+ // Component to display shared data from shell config
8
+ const SharedDataDisplay: React.FC<{ data: Record<string, unknown> }> = ({
9
+ data
10
+ }) => {
11
+ // Filter out default fields to show only custom data from config
12
+ const customData = { ...data };
13
+ delete customData.lng;
14
+ delete customData.username;
15
+ delete customData.searchParams;
16
+
17
+ return (
18
+ <pre
19
+ style={{
20
+ backgroundColor: '#1e1e1e',
21
+ color: '#d4d4d4',
22
+ padding: '16px',
23
+ borderRadius: '6px',
24
+ border: '1px solid #424b6b',
25
+ fontSize: '13px',
26
+ fontFamily:
27
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace',
28
+ lineHeight: '1.5',
29
+ overflow: 'auto',
30
+ margin: 0,
31
+ whiteSpace: 'pre-wrap',
32
+ wordBreak: 'break-word'
33
+ }}
34
+ >
35
+ {Object.keys(customData).length > 0
36
+ ? JSON.stringify(customData, null, 2)
37
+ : '// No custom data configured in shell.config.js\n// Add data to the "data" field to share it with your application'}
38
+ </pre>
39
+ );
40
+ };
5
41
 
6
42
  export const WelcomePage: React.FC = () => {
7
- const navigate = useNavigate();
8
43
  const { apps } = useAppShell();
9
- const app = apps[0]; // Get the first (and likely only) app
44
+
45
+ const config: ShellConfig = (
46
+ window as unknown as { __SHELL_CONFIG__?: ShellConfig }
47
+ ).__SHELL_CONFIG__ as ShellConfig;
48
+ const data = config.data;
10
49
 
11
50
  return (
12
51
  <div>
13
- <Card title="Application Configuration" style={{ marginBottom: '24px' }}>
14
- <div
15
- style={{
16
- display: 'grid',
17
- gridTemplateColumns: '1fr 1fr',
18
- gap: '16px'
19
- }}
20
- >
21
- <div>
22
- <strong>Application Name:</strong>
23
- <p style={{ margin: '12px 0 4px 0' }}>
24
- {app?.name || 'Development App'}
25
- </p>
26
- </div>
27
- <div>
28
- <strong>Application Type:</strong>
29
- <p style={{ margin: '12px 0 4px 0' }}>
30
- <Tag color={app?.type === 'full_page' ? 'blue' : 'green'}>
31
- {app?.type === 'full_page' ? 'fullpage' : 'plugin'}
32
- </Tag>
33
- </p>
34
- </div>
35
- <div>
36
- <strong>Development URL:</strong>
37
- <p
38
- style={{
39
- margin: '12px 0 4px 0',
40
- color: '#999',
41
- fontFamily: 'monospace',
42
- fontSize: '13px'
43
- }}
44
- >
45
- {app?.url || 'http://localhost:4001'}
46
- </p>
52
+ <Card title="Applications Configuration" className="mb-8">
53
+ {apps.length === 0 ? (
54
+ <p style={{ color: '#999' }}>No applications configured</p>
55
+ ) : (
56
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
57
+ {apps.map((app, index) => (
58
+ <div key={app.id} style={{
59
+ borderBottom: index < apps.length - 1 ? '1px solid #e0e0e0' : 'none',
60
+ paddingBottom: index < apps.length - 1 ? '20px' : '0'
61
+ }}>
62
+ <h4 style={{ margin: '0 0 16px 0' }}>
63
+ {app.name} {apps.length > 1 && `(App ${index + 1})`}
64
+ </h4>
65
+ <div
66
+ style={{
67
+ display: 'grid',
68
+ gridTemplateColumns: '1fr 1fr',
69
+ gap: '16px'
70
+ }}
71
+ >
72
+ <div>
73
+ <strong>Application Type:</strong>
74
+ <p style={{ margin: '12px 0 4px 0' }}>
75
+ <Tag color={app.type === 'full_page' ? 'blue' : 'green'}>
76
+ {app.type === 'full_page' ? 'Full Page' : 'Plugin'}
77
+ </Tag>
78
+ </p>
79
+ </div>
80
+ <div>
81
+ <strong>Development URL:</strong>
82
+ <p
83
+ style={{
84
+ margin: '12px 0 4px 0',
85
+ color: '#999',
86
+ fontFamily: 'monospace',
87
+ fontSize: '13px'
88
+ }}
89
+ >
90
+ {app.url}
91
+ </p>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ ))}
96
+ <div style={{ marginTop: '10px' }}>
97
+ <strong>Shell Theme:</strong>
98
+ <p style={{ margin: '12px 0 4px 0', color: '#999' }}>
99
+ {config.shell.theme}
100
+ </p>
101
+ </div>
47
102
  </div>
48
- <div>
49
- <strong>Shell Theme:</strong>
50
- <p style={{ margin: '12px 0 4px 0', color: '#999' }}>omnitron</p>
51
- </div>
52
- </div>
103
+ )}
53
104
  </Card>
54
105
 
55
- <Card title="Quick Actions" style={{ marginBottom: '24px' }}>
56
- <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>
57
- <Button
58
- type="primary"
59
- onClick={() => navigate(`/external/${app?.slug}`)}
60
- >
61
- Launch Application
62
- </Button>
63
- {app?.type === 'plugin' && (
64
- <Button onClick={() => navigate('/plugin-test')}>
65
- Test Plugin Integration
66
- </Button>
67
- )}
68
- </div>
106
+ <Card title="Shared Data" className="mb-8">
107
+ {data && <SharedDataDisplay data={data} />}
69
108
  </Card>
70
109
 
71
- <Card title="Development Instructions">
110
+ <Card title="Development Instructions" className="mb-8">
72
111
  <div style={{ lineHeight: '1.6' }}>
73
112
  <h4 style={{ margin: '0 0 8px 0' }}>Getting Started:</h4>
74
113
  <ol style={{ paddingLeft: '20px' }}>
75
114
  <li>
76
- Make sure your application is running at{' '}
77
- <code>{app?.url || 'http://localhost:4001'}</code>
115
+ Make sure your application{apps.length > 1 ? 's are' : ' is'} running at{' '}
116
+ <code>{apps.length > 0 ? apps[0].url : 'http://localhost:4001'}</code>
117
+ {apps.length > 1 && (
118
+ <>
119
+ {' and '}
120
+ {apps.slice(1).map((a, i) => (
121
+ <span key={a.id}>
122
+ {i > 0 && ', '}
123
+ <code>{a.url}</code>
124
+ </span>
125
+ ))}
126
+ </>
127
+ )}
78
128
  </li>
79
129
  <li>
80
130
  Click &quot;Launch Application&quot; to load your app in the shell
81
131
  environment
82
132
  </li>
83
- {app?.type === 'plugin' && (
133
+ {apps.some(a => a.type === 'plugin') && (
84
134
  <li>
85
135
  Use &quot;Test Plugin Integration&quot; to test your plugin in
86
136
  different placeholder configurations
@@ -94,24 +144,309 @@ export const WelcomePage: React.FC = () => {
94
144
  <Divider />
95
145
 
96
146
  <h4 style={{ margin: '16px 0 8px 0' }}>
97
- Application Type:{' '}
98
- {app?.type === 'full_page' ? 'fullpage' : 'plugin'}
147
+ Application Types:{' '}
148
+ {apps.map((a, i) => (
149
+ <span key={a.id}>
150
+ {i > 0 && ', '}
151
+ {a.type === 'full_page' ? 'Full Page' : 'Plugin'}
152
+ </span>
153
+ ))}
99
154
  </h4>
100
- {app?.type === 'full_page' ? (
155
+ {apps.some(a => a.type === 'full_page') && (
101
156
  <p style={{ margin: 0, color: '#666' }}>
102
- Your fullpage application will render as complete pages within the
157
+ Full page applications render as complete pages within the
103
158
  shell environment, providing full control over the content area
104
159
  and routing.
105
160
  </p>
106
- ) : (
107
- <p style={{ margin: 0, color: '#666' }}>
108
- Your plugin application will render within designated placeholders
161
+ )}
162
+ {apps.some(a => a.type === 'plugin') && (
163
+ <p style={{ margin: '8px 0 0 0', color: '#666' }}>
164
+ Plugin applications render within designated placeholders
109
165
  in the host application, providing component-level integration
110
166
  capabilities.
111
167
  </p>
112
168
  )}
113
169
  </div>
114
170
  </Card>
171
+
172
+ <Card title="Component Usage">
173
+ <div style={{ lineHeight: '1.6' }}>
174
+ <h4 style={{ margin: '0 0 8px 0' }}>@akinon/ui-* Components:</h4>
175
+ <p style={{ margin: '0 0 16px 0', color: '#999' }}>
176
+ This shell environment includes all Akinon UI components. You can
177
+ use them in your application by importing from the respective
178
+ packages.
179
+ </p>
180
+
181
+ <pre
182
+ style={{
183
+ backgroundColor: '#1e1e1e',
184
+ color: '#d4d4d4',
185
+ padding: '16px',
186
+ borderRadius: '6px',
187
+ border: '1px solid #424b6b',
188
+ fontSize: '13px',
189
+ fontFamily:
190
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace',
191
+ lineHeight: '1.5',
192
+ overflow: 'auto',
193
+ margin: 0,
194
+ whiteSpace: 'pre-wrap',
195
+ wordBreak: 'break-word'
196
+ }}
197
+ >
198
+ {`// Import components from @akinon/ui-react (main package)
199
+ import { Button, Card, Input, Modal } from '@akinon/ui-react';
200
+
201
+ // Or import from specific packages
202
+ import { Button } from '@akinon/ui-button';
203
+ import { Card } from '@akinon/ui-card';
204
+ import { Input } from '@akinon/ui-input';
205
+ import { Modal } from '@akinon/ui-modal';
206
+
207
+ // Usage in your component
208
+ function MyComponent() {
209
+ return (
210
+ <Card title="Example Card">
211
+ <Input placeholder="Enter text here" />
212
+ <Button type="primary">Submit</Button>
213
+ </Card>
214
+ );
215
+ }`}
216
+ </pre>
217
+
218
+ <h3 style={{ margin: '16px 0 8px 0' }}>Available Components:</h3>
219
+
220
+ <h4 style={{ margin: '24px 0 12px 0', fontSize: '16px' }}>
221
+ Data Display
222
+ </h4>
223
+ <div style={{ marginBottom: '20px' }}>
224
+ {[
225
+ { name: 'Avatar', pkg: '@akinon/ui-avatar' },
226
+ { name: 'Badge', pkg: '@akinon/ui-badge' },
227
+ { name: 'Carousel', pkg: '@akinon/ui-carousel' },
228
+ { name: 'Image', pkg: '@akinon/ui-image' },
229
+ { name: 'List', pkg: '@akinon/ui-list' },
230
+ { name: 'Popover', pkg: '@akinon/ui-popover' },
231
+ { name: 'Table', pkg: '@akinon/ui-table' },
232
+ { name: 'Tag', pkg: '@akinon/ui-tag' },
233
+ { name: 'Tooltip', pkg: '@akinon/ui-tooltip' },
234
+ { name: 'Tree', pkg: '@akinon/ui-tree' },
235
+ { name: 'Typography', pkg: '@akinon/ui-typography' }
236
+ ].map((component, index, array) => (
237
+ <div
238
+ key={component.name}
239
+ style={{
240
+ display: 'flex',
241
+ justifyContent: 'space-between',
242
+ alignItems: 'center',
243
+ padding: '8px 0',
244
+ borderBottom:
245
+ index < array.length - 1 ? '1px solid #4c5679' : 'none'
246
+ }}
247
+ >
248
+ <span>{component.name}</span>
249
+ <code
250
+ style={{
251
+ backgroundColor: '#1e1e1e',
252
+ color: '#d4d4d4',
253
+ padding: '4px 8px',
254
+ borderRadius: '4px',
255
+ border: '1px solid #424b6b',
256
+ fontSize: '12px',
257
+ fontFamily:
258
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace'
259
+ }}
260
+ >
261
+ {component.pkg}
262
+ </code>
263
+ </div>
264
+ ))}
265
+ </div>
266
+
267
+ <h4 style={{ margin: '24px 0 12px 0', fontSize: '16px' }}>
268
+ Feedback
269
+ </h4>
270
+ <div style={{ marginBottom: '20px' }}>
271
+ {[
272
+ { name: 'Alert', pkg: '@akinon/ui-alert' },
273
+ { name: 'Drawer', pkg: '@akinon/ui-drawer' },
274
+ { name: 'Message', pkg: '@akinon/ui-message' },
275
+ { name: 'Modal', pkg: '@akinon/ui-modal' },
276
+ { name: 'Notification', pkg: '@akinon/ui-notification' },
277
+ { name: 'Progress', pkg: '@akinon/ui-progress' },
278
+ { name: 'Result', pkg: '@akinon/ui-result' },
279
+ { name: 'Skeleton', pkg: '@akinon/ui-skeleton' },
280
+ { name: 'Spin', pkg: '@akinon/ui-spin' }
281
+ ].map((component, index, array) => (
282
+ <div
283
+ key={component.name}
284
+ style={{
285
+ display: 'flex',
286
+ justifyContent: 'space-between',
287
+ alignItems: 'center',
288
+ padding: '8px 0',
289
+ borderBottom:
290
+ index < array.length - 1 ? '1px solid #4c5679' : 'none'
291
+ }}
292
+ >
293
+ <span>{component.name}</span>
294
+ <code
295
+ style={{
296
+ backgroundColor: '#1e1e1e',
297
+ color: '#d4d4d4',
298
+ padding: '4px 8px',
299
+ borderRadius: '4px',
300
+ border: '1px solid #424b6b',
301
+ fontSize: '12px',
302
+ fontFamily:
303
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace'
304
+ }}
305
+ >
306
+ {component.pkg}
307
+ </code>
308
+ </div>
309
+ ))}
310
+ </div>
311
+
312
+ <h4 style={{ margin: '24px 0 12px 0', fontSize: '16px' }}>Form</h4>
313
+ <div style={{ marginBottom: '20px' }}>
314
+ {[
315
+ { name: 'AutoComplete', pkg: '@akinon/ui-auto-complete' },
316
+ { name: 'Button', pkg: '@akinon/ui-button' },
317
+ { name: 'Checkbox', pkg: '@akinon/ui-checkbox' },
318
+ { name: 'ColorPicker', pkg: '@akinon/ui-color-picker' },
319
+ { name: 'DatePicker', pkg: '@akinon/ui-date-picker' },
320
+ { name: 'Input', pkg: '@akinon/ui-input' },
321
+ { name: 'InputNumber', pkg: '@akinon/ui-input-number' },
322
+ { name: 'Radio', pkg: '@akinon/ui-radio' },
323
+ { name: 'Select', pkg: '@akinon/ui-select' },
324
+ { name: 'Slider', pkg: '@akinon/ui-slider' },
325
+ { name: 'Switch', pkg: '@akinon/ui-switch' },
326
+ { name: 'TimePicker', pkg: '@akinon/ui-time-picker' },
327
+ { name: 'Transfer', pkg: '@akinon/ui-transfer' },
328
+ { name: 'TreeSelect', pkg: '@akinon/ui-tree-select' },
329
+ { name: 'Upload', pkg: '@akinon/ui-upload' }
330
+ ].map((component, index, array) => (
331
+ <div
332
+ key={component.name}
333
+ style={{
334
+ display: 'flex',
335
+ justifyContent: 'space-between',
336
+ alignItems: 'center',
337
+ padding: '8px 0',
338
+ borderBottom:
339
+ index < array.length - 1 ? '1px solid #4c5679' : 'none'
340
+ }}
341
+ >
342
+ <span>{component.name}</span>
343
+ <code
344
+ style={{
345
+ backgroundColor: '#1e1e1e',
346
+ color: '#d4d4d4',
347
+ padding: '4px 8px',
348
+ borderRadius: '4px',
349
+ border: '1px solid #424b6b',
350
+ fontSize: '12px',
351
+ fontFamily:
352
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace'
353
+ }}
354
+ >
355
+ {component.pkg}
356
+ </code>
357
+ </div>
358
+ ))}
359
+ </div>
360
+
361
+ <h4 style={{ margin: '24px 0 12px 0', fontSize: '16px' }}>Layout</h4>
362
+ <div style={{ marginBottom: '20px' }}>
363
+ {[
364
+ { name: 'Card', pkg: '@akinon/ui-card' },
365
+ { name: 'Collapse', pkg: '@akinon/ui-collapse' },
366
+ { name: 'Divider', pkg: '@akinon/ui-divider' },
367
+ { name: 'Layout', pkg: '@akinon/ui-layout' },
368
+ { name: 'Space', pkg: '@akinon/ui-space' }
369
+ ].map((component, index, array) => (
370
+ <div
371
+ key={component.name}
372
+ style={{
373
+ display: 'flex',
374
+ justifyContent: 'space-between',
375
+ alignItems: 'center',
376
+ padding: '8px 0',
377
+ borderBottom:
378
+ index < array.length - 1 ? '1px solid #4c5679' : 'none'
379
+ }}
380
+ >
381
+ <span>{component.name}</span>
382
+ <code
383
+ style={{
384
+ backgroundColor: '#1e1e1e',
385
+ color: '#d4d4d4',
386
+ padding: '4px 8px',
387
+ borderRadius: '4px',
388
+ border: '1px solid #424b6b',
389
+ fontSize: '12px',
390
+ fontFamily:
391
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace'
392
+ }}
393
+ >
394
+ {component.pkg}
395
+ </code>
396
+ </div>
397
+ ))}
398
+ </div>
399
+
400
+ <h4 style={{ margin: '24px 0 12px 0', fontSize: '16px' }}>
401
+ Navigation
402
+ </h4>
403
+ <div style={{ marginBottom: '20px' }}>
404
+ {[
405
+ { name: 'Breadcrumb', pkg: '@akinon/ui-breadcrumb' },
406
+ { name: 'Dropdown', pkg: '@akinon/ui-dropdown' },
407
+ { name: 'Menu', pkg: '@akinon/ui-menu' },
408
+ { name: 'Pagination', pkg: '@akinon/ui-pagination' },
409
+ { name: 'Segmented', pkg: '@akinon/ui-segmented' },
410
+ { name: 'Steps', pkg: '@akinon/ui-steps' },
411
+ { name: 'Tour', pkg: '@akinon/ui-tour' }
412
+ ].map((component, index, array) => (
413
+ <div
414
+ key={component.name}
415
+ style={{
416
+ display: 'flex',
417
+ justifyContent: 'space-between',
418
+ alignItems: 'center',
419
+ padding: '8px 0',
420
+ borderBottom:
421
+ index < array.length - 1 ? '1px solid #4c5679' : 'none'
422
+ }}
423
+ >
424
+ <span>{component.name}</span>
425
+ <code
426
+ style={{
427
+ backgroundColor: '#1e1e1e',
428
+ color: '#d4d4d4',
429
+ padding: '4px 8px',
430
+ borderRadius: '4px',
431
+ border: '1px solid #424b6b',
432
+ fontSize: '12px',
433
+ fontFamily:
434
+ '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace'
435
+ }}
436
+ >
437
+ {component.pkg}
438
+ </code>
439
+ </div>
440
+ ))}
441
+ </div>
442
+
443
+ <p style={{ margin: '0', color: '#999', fontSize: '14px' }}>
444
+ <strong>Note:</strong> All components follow Ant Design API
445
+ conventions with Akinon-specific styling and theming. Check the
446
+ Storybook documentation for detailed usage examples and props.
447
+ </p>
448
+ </div>
449
+ </Card>
115
450
  </div>
116
451
  );
117
452
  };
package/src/providers.tsx CHANGED
@@ -17,16 +17,14 @@ export const Providers: React.FC<ProvidersProps> = ({ config, children }) => {
17
17
  const navigate = useNavigate();
18
18
 
19
19
  // Convert shell config to apps format for AppShellProvider
20
- const apps: RegisteredApp[] = [
21
- {
22
- id: 1,
23
- url: config.plugin.url,
24
- slug: config.plugin.name.toLowerCase().replace(/\s+/g, '-'),
25
- path: '', // Empty path for development like playground
26
- type: config.plugin.type === 'fullpage' ? 'full_page' : 'plugin',
27
- name: config.plugin.name
28
- }
29
- ];
20
+ const apps: RegisteredApp[] = config.apps.map((app, index) => ({
21
+ id: index + 1,
22
+ url: app.url,
23
+ slug: app.name.toLowerCase().replace(/\s+/g, '-'),
24
+ path: '', // Empty path for development like playground
25
+ type: app.type,
26
+ name: app.navTitle || app.name // Use navTitle if provided, otherwise use name
27
+ }));
30
28
 
31
29
  const navigation: ShellNavigation = {
32
30
  navigate: ({ id, path, external }: any) => {
@@ -41,7 +39,8 @@ export const Providers: React.FC<ProvidersProps> = ({ config, children }) => {
41
39
  const data = {
42
40
  lng: 'en',
43
41
  username: 'Developer',
44
- searchParams: Object.fromEntries([...searchParams])
42
+ searchParams: Object.fromEntries([...searchParams]),
43
+ ...(config.data || {})
45
44
  };
46
45
 
47
46
  const defaultActions = {