@faasjs/ant-design 8.0.0-beta.17 → 8.0.0-beta.18
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/dist/index.cjs +502 -149
- package/dist/index.d.ts +880 -266
- package/dist/index.mjs +502 -149
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -8,15 +8,24 @@ import { CheckOutlined, CloseOutlined, MinusCircleOutlined, PlusOutlined } from
|
|
|
8
8
|
import dayjs from "dayjs";
|
|
9
9
|
//#region src/Loading.tsx
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Render an Ant Design loading spinner with an optional content fallback.
|
|
12
|
+
*
|
|
13
|
+
* @param {LoadingProps} props - Loading indicator props and optional wrapped children.
|
|
12
14
|
*
|
|
13
15
|
* @example
|
|
14
16
|
* ```tsx
|
|
15
|
-
*
|
|
17
|
+
* import { Loading } from '@faasjs/ant-design'
|
|
16
18
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* export function Page({ remoteData }: { remoteData?: string }) {
|
|
20
|
+
* return (
|
|
21
|
+
* <>
|
|
22
|
+
* <Loading />
|
|
23
|
+
* <Loading loading={!remoteData}>
|
|
24
|
+
* <div>{remoteData}</div>
|
|
25
|
+
* </Loading>
|
|
26
|
+
* </>
|
|
27
|
+
* )
|
|
28
|
+
* }
|
|
20
29
|
* ```
|
|
21
30
|
*/
|
|
22
31
|
function Loading(props) {
|
|
@@ -35,18 +44,84 @@ function Loading(props) {
|
|
|
35
44
|
//#endregion
|
|
36
45
|
//#region src/FaasDataWrapper.tsx
|
|
37
46
|
/**
|
|
38
|
-
*
|
|
47
|
+
* Render the `@faasjs/react` data wrapper with an Ant Design loading fallback.
|
|
48
|
+
*
|
|
49
|
+
* When `loading` is not provided, the component renders {@link Loading} with `loadingProps` while
|
|
50
|
+
* the wrapped FaasJS request is pending.
|
|
51
|
+
*
|
|
52
|
+
* @template T - Action path or response data type used for inference.
|
|
53
|
+
* @param {FaasDataWrapperProps<T>} props - Wrapper props including loading fallbacks and request configuration.
|
|
39
54
|
*
|
|
40
55
|
* @example
|
|
41
56
|
* ```tsx
|
|
42
|
-
*
|
|
43
|
-
*
|
|
57
|
+
* import { Alert, Button } from 'antd'
|
|
58
|
+
* import { FaasDataWrapper } from '@faasjs/ant-design'
|
|
59
|
+
*
|
|
60
|
+
* type User = {
|
|
61
|
+
* name: string
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* function UserView(props: {
|
|
65
|
+
* data?: User
|
|
66
|
+
* error?: Error
|
|
67
|
+
* reload?: () => void
|
|
68
|
+
* }) {
|
|
69
|
+
* if (props.error) {
|
|
70
|
+
* return (
|
|
71
|
+
* <Alert
|
|
72
|
+
* type="error"
|
|
73
|
+
* message={props.error.message}
|
|
74
|
+
* action={
|
|
75
|
+
* <Button size="small" onClick={() => props.reload?.()}>
|
|
76
|
+
* Retry
|
|
77
|
+
* </Button>
|
|
78
|
+
* }
|
|
79
|
+
* />
|
|
80
|
+
* )
|
|
81
|
+
* }
|
|
82
|
+
*
|
|
83
|
+
* return <div>Hello, {props.data?.name}</div>
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* // Render-prop mode
|
|
87
|
+
* export function UserProfile(props: { id: number }) {
|
|
88
|
+
* return (
|
|
89
|
+
* <FaasDataWrapper<User>
|
|
90
|
+
* action="user/get"
|
|
91
|
+
* params={{ id: props.id }}
|
|
92
|
+
* loading={<div>Loading user...</div>}
|
|
93
|
+
* render={({ data, error, reload }) => {
|
|
94
|
+
* if (error) {
|
|
95
|
+
* return (
|
|
96
|
+
* <Alert
|
|
97
|
+
* type="error"
|
|
98
|
+
* message={error.message}
|
|
99
|
+
* action={
|
|
100
|
+
* <Button size="small" onClick={() => reload()}>
|
|
101
|
+
* Retry
|
|
102
|
+
* </Button>
|
|
103
|
+
* }
|
|
104
|
+
* />
|
|
105
|
+
* )
|
|
106
|
+
* }
|
|
107
|
+
*
|
|
108
|
+
* return <div>Hello, {data.name}</div>
|
|
109
|
+
* }}
|
|
110
|
+
* />
|
|
111
|
+
* )
|
|
44
112
|
* }
|
|
45
113
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
114
|
+
* // Children injection mode
|
|
115
|
+
* export function UserProfileWithChildren(props: { id: number }) {
|
|
116
|
+
* return (
|
|
117
|
+
* <FaasDataWrapper<User>
|
|
118
|
+
* action="user/get"
|
|
119
|
+
* params={{ id: props.id }}
|
|
120
|
+
* loading={<div>Loading user...</div>}
|
|
121
|
+
* >
|
|
122
|
+
* <UserView />
|
|
123
|
+
* </FaasDataWrapper>
|
|
124
|
+
* )
|
|
50
125
|
* }
|
|
51
126
|
* ```
|
|
52
127
|
*/
|
|
@@ -57,11 +132,27 @@ function FaasDataWrapper(props) {
|
|
|
57
132
|
});
|
|
58
133
|
}
|
|
59
134
|
/**
|
|
60
|
-
*
|
|
135
|
+
* Wrap a component with {@link FaasDataWrapper} and its Ant Design loading fallback.
|
|
136
|
+
*
|
|
137
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
138
|
+
* @template TComponentProps - Component props including injected Faas data fields.
|
|
139
|
+
* @param {React.FC<TComponentProps & Record<string, any>>} Component - Component that consumes injected Faas data props.
|
|
140
|
+
* @param {FaasDataWrapperProps<PathOrData>} faasProps - Request configuration forwarded to {@link FaasDataWrapper}.
|
|
141
|
+
* @returns Higher-order component that injects Faas data props.
|
|
61
142
|
*
|
|
62
143
|
* @example
|
|
63
144
|
* ```tsx
|
|
64
|
-
*
|
|
145
|
+
* import { withFaasData } from '@faasjs/ant-design'
|
|
146
|
+
*
|
|
147
|
+
* const UserCard = withFaasData(
|
|
148
|
+
* ({ data, error, reload }) =>
|
|
149
|
+
* error ? (
|
|
150
|
+
* <a onClick={() => reload()}>Retry</a>
|
|
151
|
+
* ) : (
|
|
152
|
+
* <div>{data.name}</div>
|
|
153
|
+
* ),
|
|
154
|
+
* { action: 'user/get', params: { id: 1 } },
|
|
155
|
+
* )
|
|
65
156
|
* ```
|
|
66
157
|
*/
|
|
67
158
|
function withFaasData(Component, faasProps) {
|
|
@@ -107,17 +198,29 @@ const baseTheme = {
|
|
|
107
198
|
},
|
|
108
199
|
Link: { style: {} }
|
|
109
200
|
};
|
|
201
|
+
/**
|
|
202
|
+
* React context storing the resolved FaasJS Ant Design theme.
|
|
203
|
+
*/
|
|
110
204
|
const ConfigContext = createContext({ theme: baseTheme });
|
|
111
205
|
/**
|
|
112
|
-
*
|
|
206
|
+
* Provide theme overrides and optional FaasJS client initialization for descendants.
|
|
207
|
+
*
|
|
208
|
+
* Theme overrides are merged with the built-in defaults. When `theme.lang` is omitted, the
|
|
209
|
+
* provider infers a default language from `navigator.language`.
|
|
210
|
+
*
|
|
211
|
+
* @param {ConfigProviderProps} props - Theme overrides and optional FaasJS client configuration.
|
|
113
212
|
*
|
|
114
213
|
* @example
|
|
115
214
|
* ```tsx
|
|
116
|
-
* import { ConfigProvider } from '@faasjs/ant-design'
|
|
215
|
+
* import { Blank, ConfigProvider } from '@faasjs/ant-design'
|
|
117
216
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
217
|
+
* export function Page() {
|
|
218
|
+
* return (
|
|
219
|
+
* <ConfigProvider theme={{ common: { blank: 'Empty' } }}>
|
|
220
|
+
* <Blank />
|
|
221
|
+
* </ConfigProvider>
|
|
222
|
+
* )
|
|
223
|
+
* }
|
|
121
224
|
* ```
|
|
122
225
|
*/
|
|
123
226
|
function ConfigProvider(props) {
|
|
@@ -138,24 +241,60 @@ function ConfigProvider(props) {
|
|
|
138
241
|
children: props.children
|
|
139
242
|
});
|
|
140
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Read the current `@faasjs/ant-design` config context.
|
|
246
|
+
*
|
|
247
|
+
* @returns Current config context value containing the resolved theme.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```tsx
|
|
251
|
+
* import { Blank, ConfigProvider, useConfigContext } from '@faasjs/ant-design'
|
|
252
|
+
*
|
|
253
|
+
* function EmptyState() {
|
|
254
|
+
* const { theme } = useConfigContext()
|
|
255
|
+
*
|
|
256
|
+
* return <span>{theme.common.blank}</span>
|
|
257
|
+
* }
|
|
258
|
+
*
|
|
259
|
+
* export function Page() {
|
|
260
|
+
* return (
|
|
261
|
+
* <ConfigProvider theme={{ common: { blank: 'N/A' } }}>
|
|
262
|
+
* <EmptyState />
|
|
263
|
+
* </ConfigProvider>
|
|
264
|
+
* )
|
|
265
|
+
* }
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
141
268
|
function useConfigContext() {
|
|
142
269
|
return useContext(ConfigContext);
|
|
143
270
|
}
|
|
144
271
|
//#endregion
|
|
145
272
|
//#region src/Drawer.tsx
|
|
146
273
|
/**
|
|
147
|
-
*
|
|
274
|
+
* Create a hook-managed Ant Design drawer instance.
|
|
275
|
+
*
|
|
276
|
+
* The returned setter merges partial updates into the current drawer props instead of replacing the
|
|
277
|
+
* entire state object.
|
|
148
278
|
*
|
|
279
|
+
* @param {DrawerProps} [init] - Initial drawer props.
|
|
280
|
+
* @returns Hook-managed drawer element, current props, and a state-merging setter.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
149
283
|
* ```tsx
|
|
284
|
+
* import { useDrawer } from '@faasjs/ant-design'
|
|
285
|
+
* import { Button } from 'antd'
|
|
286
|
+
*
|
|
150
287
|
* function Example() {
|
|
151
288
|
* const { drawer, setDrawerProps } = useDrawer()
|
|
152
289
|
*
|
|
153
|
-
* return
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
290
|
+
* return (
|
|
291
|
+
* <>
|
|
292
|
+
* <Button onClick={() => setDrawerProps({ open: true, title: 'Details', children: <div>Content</div> })}>
|
|
293
|
+
* Open
|
|
294
|
+
* </Button>
|
|
295
|
+
* {drawer}
|
|
296
|
+
* </>
|
|
297
|
+
* )
|
|
159
298
|
* }
|
|
160
299
|
* ```
|
|
161
300
|
*/
|
|
@@ -200,6 +339,24 @@ function ErrorChildren(props) {
|
|
|
200
339
|
}
|
|
201
340
|
/**
|
|
202
341
|
* Styled error boundary.
|
|
342
|
+
*
|
|
343
|
+
* When `errorChildren` is not provided, the fallback UI renders an Ant Design `Alert` containing
|
|
344
|
+
* the captured error message and description.
|
|
345
|
+
*
|
|
346
|
+
* @param {ErrorBoundaryProps} props - Error boundary props forwarded to the underlying React implementation.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```tsx
|
|
350
|
+
* import { ErrorBoundary } from '@faasjs/ant-design'
|
|
351
|
+
*
|
|
352
|
+
* export function Page() {
|
|
353
|
+
* return (
|
|
354
|
+
* <ErrorBoundary>
|
|
355
|
+
* <DangerousWidget />
|
|
356
|
+
* </ErrorBoundary>
|
|
357
|
+
* )
|
|
358
|
+
* }
|
|
359
|
+
* ```
|
|
203
360
|
*/
|
|
204
361
|
function ErrorBoundary(props) {
|
|
205
362
|
return /* @__PURE__ */ jsx(ErrorBoundary$1, {
|
|
@@ -210,16 +367,30 @@ function ErrorBoundary(props) {
|
|
|
210
367
|
//#endregion
|
|
211
368
|
//#region src/Modal.tsx
|
|
212
369
|
/**
|
|
213
|
-
*
|
|
370
|
+
* Create a hook-managed Ant Design modal instance.
|
|
371
|
+
*
|
|
372
|
+
* The returned setter merges partial updates into the current modal props instead of replacing the
|
|
373
|
+
* entire state object.
|
|
214
374
|
*
|
|
375
|
+
* @param {ModalProps} [init] - Initial modal props.
|
|
376
|
+
* @returns Hook-managed modal element, current props, and a state-merging setter.
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
215
379
|
* ```tsx
|
|
380
|
+
* import { useModal } from '@faasjs/ant-design'
|
|
381
|
+
* import { Button } from 'antd'
|
|
382
|
+
*
|
|
216
383
|
* function Example() {
|
|
217
384
|
* const { modal, setModalProps } = useModal()
|
|
218
385
|
*
|
|
219
|
-
* return
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
386
|
+
* return (
|
|
387
|
+
* <>
|
|
388
|
+
* <Button onClick={() => setModalProps({ open: true, title: 'Delete', children: 'Are you sure?' })}>
|
|
389
|
+
* Open Modal
|
|
390
|
+
* </Button>
|
|
391
|
+
* {modal}
|
|
392
|
+
* </>
|
|
393
|
+
* )
|
|
223
394
|
* }
|
|
224
395
|
* ```
|
|
225
396
|
*/
|
|
@@ -249,6 +420,9 @@ function useModal(init) {
|
|
|
249
420
|
}
|
|
250
421
|
//#endregion
|
|
251
422
|
//#region src/useApp.ts
|
|
423
|
+
/**
|
|
424
|
+
* Shared context storing message, notification, modal, and drawer helpers.
|
|
425
|
+
*/
|
|
252
426
|
const AppContext = createSplittingContext([
|
|
253
427
|
"message",
|
|
254
428
|
"notification",
|
|
@@ -258,12 +432,38 @@ const AppContext = createSplittingContext([
|
|
|
258
432
|
"setDrawerProps"
|
|
259
433
|
]);
|
|
260
434
|
/**
|
|
261
|
-
*
|
|
435
|
+
* Read app-level services exposed by the root `App` component.
|
|
262
436
|
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
437
|
+
* @template NewT - Narrowed app context shape to read from `AppContext`.
|
|
438
|
+
* @returns Read-only app context value.
|
|
439
|
+
*
|
|
440
|
+
* @example
|
|
441
|
+
* ```tsx
|
|
442
|
+
* import { App, useApp } from '@faasjs/ant-design'
|
|
443
|
+
* import { Button } from 'antd'
|
|
444
|
+
*
|
|
445
|
+
* function Page() {
|
|
446
|
+
* const { message, setModalProps } = useApp()
|
|
447
|
+
*
|
|
448
|
+
* return (
|
|
449
|
+
* <Button
|
|
450
|
+
* onClick={() => {
|
|
451
|
+
* message.success('Saved')
|
|
452
|
+
* setModalProps({ open: true, title: 'Done', children: 'Profile updated.' })
|
|
453
|
+
* }}
|
|
454
|
+
* >
|
|
455
|
+
* Save
|
|
456
|
+
* </Button>
|
|
457
|
+
* )
|
|
458
|
+
* }
|
|
265
459
|
*
|
|
266
|
-
*
|
|
460
|
+
* export function Root() {
|
|
461
|
+
* return (
|
|
462
|
+
* <App>
|
|
463
|
+
* <Page />
|
|
464
|
+
* </App>
|
|
465
|
+
* )
|
|
466
|
+
* }
|
|
267
467
|
* ```
|
|
268
468
|
*/
|
|
269
469
|
function useApp() {
|
|
@@ -282,25 +482,25 @@ function RoutesApp(props) {
|
|
|
282
482
|
return /* @__PURE__ */ jsx(Fragment, { children: props.children });
|
|
283
483
|
}
|
|
284
484
|
/**
|
|
285
|
-
*
|
|
485
|
+
* Render the root provider shell for a FaasJS Ant Design application.
|
|
486
|
+
*
|
|
487
|
+
* `App` initializes Ant Design message and notification APIs, exposes hook-managed modal and
|
|
488
|
+
* drawer state through {@link AppContext}, wraps descendants with {@link ErrorBoundary}, and
|
|
489
|
+
* optionally mounts React Router's `BrowserRouter`.
|
|
286
490
|
*
|
|
287
|
-
* -
|
|
288
|
-
* - Integrated Ant Design's [Message](https://ant.design/components/message/) and [Notification](https://ant.design/components/notification/).
|
|
289
|
-
* - Based on FaasJS's [ConfigProvider](https://faasjs.com/doc/ant-design/#configprovider).
|
|
290
|
-
* - Integrated FaasJS's [Modal](https://faasjs.com/doc/ant-design/#usemodal), [Drawer](https://faasjs.com/doc/ant-design/#usedrawer) and [ErrorBoundary](https://faasjs.com/doc/ant-design/#errorboundary).
|
|
291
|
-
* - Integrated React Router's [BrowserRouter](https://api.reactrouter.com/v7/interfaces/react_router.BrowserRouterProps.html).
|
|
491
|
+
* @param {AppProps} props - App shell props including providers, routing, and error handling options.
|
|
292
492
|
*
|
|
293
493
|
* @example
|
|
294
494
|
* ```tsx
|
|
295
495
|
* import { App } from '@faasjs/ant-design'
|
|
296
496
|
*
|
|
297
|
-
* export default function () {
|
|
497
|
+
* export default function Page() {
|
|
298
498
|
* return (
|
|
299
499
|
* <App
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
500
|
+
* configProviderProps={{}}
|
|
501
|
+
* browserRouterProps={{}}
|
|
502
|
+
* errorBoundaryProps={{}}
|
|
503
|
+
* faasConfigProviderProps={{}}
|
|
304
504
|
* >
|
|
305
505
|
* <div>content</div>
|
|
306
506
|
* </App>
|
|
@@ -311,8 +511,8 @@ function RoutesApp(props) {
|
|
|
311
511
|
function App(props) {
|
|
312
512
|
const [messageApi, messageContextHolder] = message.useMessage();
|
|
313
513
|
const [notificationApi, notificationContextHolder] = notification.useNotification();
|
|
314
|
-
const { modal, modalProps, setModalProps } = useModal();
|
|
315
|
-
const { drawer, drawerProps, setDrawerProps } = useDrawer();
|
|
514
|
+
const { modal, modalProps, setModalProps } = useModal({ destroyOnHidden: true });
|
|
515
|
+
const { drawer, drawerProps, setDrawerProps } = useDrawer({ destroyOnHidden: true });
|
|
316
516
|
return /* @__PURE__ */ jsx(OptionalWrapper, {
|
|
317
517
|
condition: !!props.configProviderProps,
|
|
318
518
|
Wrapper: ConfigProvider$1,
|
|
@@ -358,15 +558,20 @@ function App(props) {
|
|
|
358
558
|
//#endregion
|
|
359
559
|
//#region src/Blank.tsx
|
|
360
560
|
/**
|
|
361
|
-
*
|
|
561
|
+
* Render a disabled placeholder when a value is empty.
|
|
562
|
+
*
|
|
563
|
+
* Empty values include `undefined`, `null`, empty strings, and empty arrays.
|
|
362
564
|
*
|
|
363
|
-
*
|
|
565
|
+
* @param {BlankProps} [options] - Placeholder text and value to render.
|
|
566
|
+
* @returns Rendered value or the configured placeholder text.
|
|
364
567
|
*
|
|
365
568
|
* @example
|
|
366
569
|
* ```tsx
|
|
367
570
|
* import { Blank } from '@faasjs/ant-design'
|
|
368
571
|
*
|
|
369
|
-
*
|
|
572
|
+
* export function FieldPreview() {
|
|
573
|
+
* return <Blank value={undefined} text="Empty" />
|
|
574
|
+
* }
|
|
370
575
|
* ```
|
|
371
576
|
*/
|
|
372
577
|
function Blank(options) {
|
|
@@ -379,17 +584,14 @@ function Blank(options) {
|
|
|
379
584
|
//#endregion
|
|
380
585
|
//#region src/data.ts
|
|
381
586
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* This function takes an identifier string with words separated by underscores,
|
|
385
|
-
* capitalizes the first letter of each word, and joins them together without spaces.
|
|
587
|
+
* Convert a snake_case, kebab-case, or spaced identifier into a title-style label.
|
|
386
588
|
*
|
|
387
|
-
* @param id -
|
|
388
|
-
* @returns
|
|
589
|
+
* @param {string | number} id - Identifier to convert.
|
|
590
|
+
* @returns Generated label string.
|
|
389
591
|
*
|
|
390
592
|
* @example
|
|
391
|
-
* ```
|
|
392
|
-
* idToTitle('example_id')
|
|
593
|
+
* ```ts
|
|
594
|
+
* idToTitle('example_id') // 'Example Id'
|
|
393
595
|
* ```
|
|
394
596
|
*/
|
|
395
597
|
function idToTitle(id) {
|
|
@@ -398,7 +600,24 @@ function idToTitle(id) {
|
|
|
398
600
|
return splitted.charAt(0).toUpperCase() + splitted.slice(1);
|
|
399
601
|
}
|
|
400
602
|
/**
|
|
401
|
-
*
|
|
603
|
+
* Normalize primitive options into explicit `{ label, value }` objects.
|
|
604
|
+
*
|
|
605
|
+
* String and number options are converted with {@link idToTitle}, while pre-shaped option objects
|
|
606
|
+
* are returned as-is.
|
|
607
|
+
*
|
|
608
|
+
* @param {BaseOption[]} options - Raw option list to normalize.
|
|
609
|
+
* @returns Normalized option list.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* import { transferOptions } from '@faasjs/ant-design'
|
|
614
|
+
*
|
|
615
|
+
* transferOptions(['draft', { label: 'Published', value: 'published' }])
|
|
616
|
+
* // [
|
|
617
|
+
* // { label: 'Draft', value: 'draft' },
|
|
618
|
+
* // { label: 'Published', value: 'published' },
|
|
619
|
+
* // ]
|
|
620
|
+
* ```
|
|
402
621
|
*/
|
|
403
622
|
function transferOptions(options) {
|
|
404
623
|
if (!options) return [];
|
|
@@ -407,6 +626,25 @@ function transferOptions(options) {
|
|
|
407
626
|
value: item
|
|
408
627
|
});
|
|
409
628
|
}
|
|
629
|
+
/**
|
|
630
|
+
* Normalize raw values into the runtime shape expected by FaasJS Ant Design components.
|
|
631
|
+
*
|
|
632
|
+
* Primitive strings such as `'null'` and `'undefined'` become `null`, comma-delimited array
|
|
633
|
+
* strings are split into arrays, and date or time values are converted to `dayjs` objects.
|
|
634
|
+
*
|
|
635
|
+
* @param {FaasItemType | null | undefined} type - Target field type.
|
|
636
|
+
* @param {any} value - Raw value to normalize.
|
|
637
|
+
* @returns Normalized value for rendering or form initialization.
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```ts
|
|
641
|
+
* import { transferValue } from '@faasjs/ant-design'
|
|
642
|
+
*
|
|
643
|
+
* transferValue('number', '42') // 42
|
|
644
|
+
* transferValue('boolean', 'true') // true
|
|
645
|
+
* transferValue('string[]', 'a,b') // ['a', 'b']
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
410
648
|
function transferValue(type, value) {
|
|
411
649
|
if (!type) type = "string";
|
|
412
650
|
if (!type.endsWith("[]") && (typeof value === "undefined" || value === null || value === "" || value === "null" || value === "undefined")) return null;
|
|
@@ -432,15 +670,27 @@ function transferValue(type, value) {
|
|
|
432
670
|
return value;
|
|
433
671
|
}
|
|
434
672
|
/**
|
|
435
|
-
* Clone a UnionFaasItemElement with
|
|
673
|
+
* Clone a {@link UnionFaasItemElement} with FaasJS injection props.
|
|
674
|
+
*
|
|
675
|
+
* React elements are cloned directly, while component references are first wrapped with
|
|
676
|
+
* `createElement`.
|
|
677
|
+
*
|
|
678
|
+
* @param {UnionFaasItemElement} element - Element or component to clone.
|
|
679
|
+
* @param {any} props - Injection props such as `scene`, `value`, `values`, and `index`.
|
|
680
|
+
* @returns Cloned React element ready for rendering.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```tsx
|
|
684
|
+
* import { cloneUnionFaasItemElement, type UnionFaasItemElement } from '@faasjs/ant-design'
|
|
436
685
|
*
|
|
437
|
-
*
|
|
438
|
-
* If the provided element is a valid React element, it clones it with the new props.
|
|
439
|
-
* Otherwise, it creates a new element from the provided element and props.
|
|
686
|
+
* const Cell: UnionFaasItemElement<string> = ({ value }) => <span>{value}</span>
|
|
440
687
|
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
688
|
+
* const element = cloneUnionFaasItemElement(Cell, {
|
|
689
|
+
* scene: 'table',
|
|
690
|
+
* value: 'Hello',
|
|
691
|
+
* index: 0,
|
|
692
|
+
* })
|
|
693
|
+
* ```
|
|
444
694
|
*/
|
|
445
695
|
function cloneUnionFaasItemElement(element, props) {
|
|
446
696
|
return cloneElement(isValidElement(element) ? element : createElement(element), props);
|
|
@@ -523,31 +773,41 @@ function DescriptionItemContent(props) {
|
|
|
523
773
|
}
|
|
524
774
|
DescriptionItemContent.displayName = "DescriptionItemContent";
|
|
525
775
|
/**
|
|
526
|
-
*
|
|
776
|
+
* Render an Ant Design description list from FaasJS item metadata.
|
|
777
|
+
*
|
|
778
|
+
* The component can render a local `dataSource` directly or resolve one through `faasData`, and
|
|
779
|
+
* it applies the same item type normalization helpers used by the form and table components.
|
|
527
780
|
*
|
|
528
|
-
* -
|
|
781
|
+
* @template T - Data record shape rendered by the component.
|
|
782
|
+
* @param {DescriptionProps<T>} props - Description props including items, data source, and optional Faas data config.
|
|
783
|
+
* @throws {Error} When an entry in `extendTypes` omits both `children` and `render`.
|
|
529
784
|
*
|
|
530
785
|
* @example
|
|
531
786
|
* ```tsx
|
|
532
787
|
* import { Description } from '@faasjs/ant-design'
|
|
533
788
|
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
789
|
+
* export function Detail() {
|
|
790
|
+
* return (
|
|
791
|
+
* <Description
|
|
792
|
+
* title="Title"
|
|
793
|
+
* items={[
|
|
794
|
+
* {
|
|
795
|
+
* id: 'id',
|
|
796
|
+
* title: 'Title',
|
|
797
|
+
* type: 'string',
|
|
798
|
+
* },
|
|
799
|
+
* ]}
|
|
800
|
+
* dataSource={{ id: 'value' }}
|
|
801
|
+
* />
|
|
802
|
+
* )
|
|
803
|
+
* }
|
|
545
804
|
* ```
|
|
546
805
|
*/
|
|
547
|
-
function Description(
|
|
806
|
+
function Description(props) {
|
|
807
|
+
const { faasData, dataSource, renderTitle, extendTypes, ...descriptionProps } = props;
|
|
548
808
|
if (faasData && !dataSource) return /* @__PURE__ */ jsx(FaasDataWrapper, {
|
|
549
809
|
render: ({ data }) => /* @__PURE__ */ jsx(Description, {
|
|
550
|
-
...
|
|
810
|
+
...descriptionProps,
|
|
551
811
|
dataSource: data,
|
|
552
812
|
...renderTitle ? { renderTitle } : {},
|
|
553
813
|
...extendTypes ? { extendTypes } : {}
|
|
@@ -555,9 +815,9 @@ function Description({ faasData, dataSource, renderTitle, extendTypes, ...props
|
|
|
555
815
|
...faasData
|
|
556
816
|
});
|
|
557
817
|
return /* @__PURE__ */ jsx(Descriptions, {
|
|
558
|
-
...
|
|
559
|
-
title: typeof renderTitle === "function" ? renderTitle(dataSource) :
|
|
560
|
-
items:
|
|
818
|
+
...descriptionProps,
|
|
819
|
+
title: typeof renderTitle === "function" ? renderTitle(dataSource) : descriptionProps.title,
|
|
820
|
+
items: descriptionProps.items.filter((item) => item && !(item.descriptionChildren === null || item.children === null || item.descriptionRender === null || item.render === null) && (!item.if || item.if(dataSource))).map((item) => ({
|
|
561
821
|
...item,
|
|
562
822
|
key: item.id,
|
|
563
823
|
label: item.title ?? idToTitle(item.id),
|
|
@@ -609,20 +869,30 @@ function processProps(propsCopy, config) {
|
|
|
609
869
|
return propsCopy;
|
|
610
870
|
}
|
|
611
871
|
/**
|
|
612
|
-
*
|
|
872
|
+
* Render a FaasJS-aware Ant Design form field or nested field group.
|
|
613
873
|
*
|
|
614
|
-
*
|
|
615
|
-
* -
|
|
874
|
+
* The component derives default labels from `id`, applies required validation messages from the
|
|
875
|
+
* active theme, supports surface-specific union renderers, and can render nested `object` or
|
|
876
|
+
* `object[]` field structures.
|
|
877
|
+
*
|
|
878
|
+
* @template T - Value type rendered or edited by the form item.
|
|
879
|
+
* @param {FormItemProps<T>} props - Form item props including field metadata, rules, and custom renderers.
|
|
616
880
|
*
|
|
617
881
|
* @example
|
|
618
882
|
* ```tsx
|
|
619
|
-
*
|
|
620
|
-
*
|
|
883
|
+
* import { FormItem } from '@faasjs/ant-design'
|
|
884
|
+
* import { Input } from 'antd'
|
|
621
885
|
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
886
|
+
* export function AccountFields() {
|
|
887
|
+
* return (
|
|
888
|
+
* <>
|
|
889
|
+
* <FormItem id="name" type="string" />
|
|
890
|
+
* <FormItem id="password">
|
|
891
|
+
* <Input.Password />
|
|
892
|
+
* </FormItem>
|
|
893
|
+
* </>
|
|
894
|
+
* )
|
|
895
|
+
* }
|
|
626
896
|
* ```
|
|
627
897
|
*/
|
|
628
898
|
function FormItem(props) {
|
|
@@ -871,11 +1141,14 @@ function isFormItemProps(item) {
|
|
|
871
1141
|
return item.id !== void 0;
|
|
872
1142
|
}
|
|
873
1143
|
/**
|
|
874
|
-
*
|
|
1144
|
+
* Render a data-aware Ant Design form with optional FaasJS submission helpers.
|
|
1145
|
+
*
|
|
1146
|
+
* The component normalizes `initialValues` with {@link transferValue}, renders item definitions
|
|
1147
|
+
* through {@link FormItem}, and can either delegate submission to a custom `onFinish` handler or
|
|
1148
|
+
* the built-in FaasJS request flow configured by `faas`.
|
|
875
1149
|
*
|
|
876
|
-
*
|
|
877
|
-
* -
|
|
878
|
-
* - Use `faas` for the built-in FaasJS submit flow.
|
|
1150
|
+
* @template Values - Form values shape.
|
|
1151
|
+
* @param {FormProps<Values>} props - Form props including items, submit behavior, and FaasJS integration.
|
|
879
1152
|
*
|
|
880
1153
|
* @example
|
|
881
1154
|
* ```tsx
|
|
@@ -1064,15 +1337,27 @@ Form.Provider = Form$1.Provider;
|
|
|
1064
1337
|
//#endregion
|
|
1065
1338
|
//#region src/Link.tsx
|
|
1066
1339
|
/**
|
|
1067
|
-
*
|
|
1340
|
+
* Render a navigation-aware link or button.
|
|
1341
|
+
*
|
|
1342
|
+
* Internal links are pushed through React Router, while links with `_blank` targets are opened
|
|
1343
|
+
* with `window.open`.
|
|
1344
|
+
*
|
|
1345
|
+
* @param {LinkProps} props - Link props controlling navigation target, rendering mode, and button behavior.
|
|
1068
1346
|
*
|
|
1069
1347
|
* @example
|
|
1070
1348
|
* ```tsx
|
|
1071
|
-
*
|
|
1072
|
-
* <Link href="/">Home</Link>
|
|
1349
|
+
* import { Link } from '@faasjs/ant-design'
|
|
1073
1350
|
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1351
|
+
* export function Navigation() {
|
|
1352
|
+
* return (
|
|
1353
|
+
* <>
|
|
1354
|
+
* <Link href="/">Home</Link>
|
|
1355
|
+
* <Link href="/users/new" button={{ type: 'primary' }}>
|
|
1356
|
+
* Create User
|
|
1357
|
+
* </Link>
|
|
1358
|
+
* </>
|
|
1359
|
+
* )
|
|
1360
|
+
* }
|
|
1076
1361
|
* ```
|
|
1077
1362
|
*/
|
|
1078
1363
|
function Link(props) {
|
|
@@ -1129,6 +1414,23 @@ function Link(props) {
|
|
|
1129
1414
|
}
|
|
1130
1415
|
//#endregion
|
|
1131
1416
|
//#region src/Routers.tsx
|
|
1417
|
+
/**
|
|
1418
|
+
* Default 404 route element that uses the configured localized title.
|
|
1419
|
+
*
|
|
1420
|
+
* @example
|
|
1421
|
+
* ```tsx
|
|
1422
|
+
* import { PageNotFound, Routes } from '@faasjs/ant-design'
|
|
1423
|
+
*
|
|
1424
|
+
* export function AppRoutes() {
|
|
1425
|
+
* return (
|
|
1426
|
+
* <Routes
|
|
1427
|
+
* routes={[{ path: '/', element: <div>Home</div> }]}
|
|
1428
|
+
* notFound={<PageNotFound />}
|
|
1429
|
+
* />
|
|
1430
|
+
* )
|
|
1431
|
+
* }
|
|
1432
|
+
* ```
|
|
1433
|
+
*/
|
|
1132
1434
|
function PageNotFound() {
|
|
1133
1435
|
const { theme } = useConfigContext();
|
|
1134
1436
|
return /* @__PURE__ */ jsx(Result, {
|
|
@@ -1137,22 +1439,31 @@ function PageNotFound() {
|
|
|
1137
1439
|
});
|
|
1138
1440
|
}
|
|
1139
1441
|
/**
|
|
1140
|
-
*
|
|
1442
|
+
* Render React Router routes with lazy-page support and a default 404 route.
|
|
1443
|
+
*
|
|
1444
|
+
* The wrapper adds a catch-all route automatically and uses an Ant Design `Skeleton` fallback when
|
|
1445
|
+
* `fallback` is not provided.
|
|
1446
|
+
*
|
|
1447
|
+
* @param {RoutesProps} props - Route definitions and optional fallback or 404 elements.
|
|
1141
1448
|
*
|
|
1142
1449
|
* @example
|
|
1143
1450
|
* ```tsx
|
|
1144
1451
|
* import { Routes, lazy } from '@faasjs/ant-design'
|
|
1145
1452
|
* import { BrowserRouter } from 'react-router-dom'
|
|
1146
1453
|
*
|
|
1147
|
-
* export function App
|
|
1148
|
-
* return
|
|
1149
|
-
* <
|
|
1150
|
-
*
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1454
|
+
* export function App() {
|
|
1455
|
+
* return (
|
|
1456
|
+
* <BrowserRouter>
|
|
1457
|
+
* <Routes
|
|
1458
|
+
* routes={[
|
|
1459
|
+
* {
|
|
1460
|
+
* path: '/',
|
|
1461
|
+
* page: lazy(() => import('./pages/home')),
|
|
1462
|
+
* },
|
|
1463
|
+
* ]}
|
|
1464
|
+
* />
|
|
1465
|
+
* </BrowserRouter>
|
|
1466
|
+
* )
|
|
1156
1467
|
* }
|
|
1157
1468
|
* ```
|
|
1158
1469
|
*/
|
|
@@ -1193,12 +1504,39 @@ function processValue(item, value) {
|
|
|
1193
1504
|
return transferred;
|
|
1194
1505
|
}
|
|
1195
1506
|
/**
|
|
1196
|
-
*
|
|
1507
|
+
* Render an Ant Design table from FaasJS item metadata.
|
|
1508
|
+
*
|
|
1509
|
+
* The component can render local `dataSource` rows or resolve remote rows through `faasData`. It
|
|
1510
|
+
* also generates default filters and sorters for built-in item types unless you disable them with
|
|
1511
|
+
* the corresponding Ant Design column props.
|
|
1512
|
+
*
|
|
1513
|
+
* @template T - Row record type rendered by the table.
|
|
1514
|
+
* @template ExtendTypes - Additional item prop shape accepted by `items`.
|
|
1515
|
+
* @param {TableProps<T, ExtendTypes>} props - Table props including columns, data source, and optional Faas data config.
|
|
1516
|
+
* @throws {Error} When an entry in `extendTypes` omits both `children` and `render`.
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* ```tsx
|
|
1520
|
+
* import { Table } from '@faasjs/ant-design'
|
|
1197
1521
|
*
|
|
1198
|
-
*
|
|
1199
|
-
*
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1522
|
+
* const rows = [
|
|
1523
|
+
* { id: 1, name: 'Alice', active: true },
|
|
1524
|
+
* { id: 2, name: 'Bob', active: false },
|
|
1525
|
+
* ]
|
|
1526
|
+
*
|
|
1527
|
+
* export function UserTable() {
|
|
1528
|
+
* return (
|
|
1529
|
+
* <Table
|
|
1530
|
+
* rowKey="id"
|
|
1531
|
+
* dataSource={rows}
|
|
1532
|
+
* items={[
|
|
1533
|
+
* { id: 'name', title: 'Name' },
|
|
1534
|
+
* { id: 'active', type: 'boolean', title: 'Active' },
|
|
1535
|
+
* ]}
|
|
1536
|
+
* />
|
|
1537
|
+
* )
|
|
1538
|
+
* }
|
|
1539
|
+
* ```
|
|
1202
1540
|
*/
|
|
1203
1541
|
function Table(props) {
|
|
1204
1542
|
const [columns, setColumns] = useState();
|
|
@@ -1584,28 +1922,32 @@ function FaasDataTable({ props, columns, data, params, reload, loading }) {
|
|
|
1584
1922
|
//#endregion
|
|
1585
1923
|
//#region src/Tabs.tsx
|
|
1586
1924
|
/**
|
|
1587
|
-
*
|
|
1925
|
+
* Render an Ant Design tabs wrapper that accepts FaasJS-style tab definitions.
|
|
1588
1926
|
*
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1591
|
-
* -
|
|
1927
|
+
* Missing `key` and `label` values are derived from each tab's `id` and `title`.
|
|
1928
|
+
*
|
|
1929
|
+
* @param {TabsProps} props - Tabs props including tab items and Ant Design tab options.
|
|
1592
1930
|
*
|
|
1593
1931
|
* @example
|
|
1594
1932
|
* ```tsx
|
|
1595
1933
|
* import { Tabs } from '@faasjs/ant-design'
|
|
1596
1934
|
*
|
|
1597
|
-
*
|
|
1598
|
-
*
|
|
1599
|
-
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
*
|
|
1605
|
-
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1935
|
+
* export function Page() {
|
|
1936
|
+
* return (
|
|
1937
|
+
* <Tabs
|
|
1938
|
+
* items={[
|
|
1939
|
+
* {
|
|
1940
|
+
* id: 'id',
|
|
1941
|
+
* children: 'content',
|
|
1942
|
+
* },
|
|
1943
|
+
* 1 === 0 && {
|
|
1944
|
+
* id: 'hidden',
|
|
1945
|
+
* children: 'content',
|
|
1946
|
+
* },
|
|
1947
|
+
* ]}
|
|
1948
|
+
* />
|
|
1949
|
+
* )
|
|
1950
|
+
* }
|
|
1609
1951
|
* ```
|
|
1610
1952
|
*/
|
|
1611
1953
|
function Tabs(props) {
|
|
@@ -1621,21 +1963,24 @@ function Tabs(props) {
|
|
|
1621
1963
|
//#endregion
|
|
1622
1964
|
//#region src/Title.tsx
|
|
1623
1965
|
/**
|
|
1624
|
-
*
|
|
1966
|
+
* Update `document.title` and optionally render the title inline.
|
|
1625
1967
|
*
|
|
1626
|
-
*
|
|
1968
|
+
* The component returns `null` by default and is often used only for its side effect.
|
|
1627
1969
|
*
|
|
1628
|
-
*
|
|
1629
|
-
* // return null
|
|
1630
|
-
* <Title title='hi' /> // => change the document.title to 'hi'
|
|
1631
|
-
* <Title title={['a', 'b']} /> // => change the document.title to 'a - b'
|
|
1970
|
+
* @param {TitleProps} props - Title props controlling document title updates and optional inline rendering.
|
|
1632
1971
|
*
|
|
1633
|
-
*
|
|
1634
|
-
*
|
|
1635
|
-
*
|
|
1972
|
+
* @example
|
|
1973
|
+
* ```tsx
|
|
1974
|
+
* import { Title } from '@faasjs/ant-design'
|
|
1636
1975
|
*
|
|
1637
|
-
*
|
|
1638
|
-
*
|
|
1976
|
+
* export function DetailPage() {
|
|
1977
|
+
* return (
|
|
1978
|
+
* <>
|
|
1979
|
+
* <Title title={['Orders', 'Detail']} h1 />
|
|
1980
|
+
* <div>...</div>
|
|
1981
|
+
* </>
|
|
1982
|
+
* )
|
|
1983
|
+
* }
|
|
1639
1984
|
* ```
|
|
1640
1985
|
*/
|
|
1641
1986
|
function Title(props) {
|
|
@@ -1659,12 +2004,20 @@ function Title(props) {
|
|
|
1659
2004
|
//#endregion
|
|
1660
2005
|
//#region src/useThemeToken.ts
|
|
1661
2006
|
/**
|
|
1662
|
-
*
|
|
2007
|
+
* Read the current Ant Design theme token.
|
|
1663
2008
|
*
|
|
1664
|
-
*
|
|
1665
|
-
* and returns the `token` property from the configuration.
|
|
2009
|
+
* @returns Ant Design global token object for the active theme.
|
|
1666
2010
|
*
|
|
1667
|
-
* @
|
|
2011
|
+
* @example
|
|
2012
|
+
* ```tsx
|
|
2013
|
+
* import { useThemeToken } from '@faasjs/ant-design'
|
|
2014
|
+
*
|
|
2015
|
+
* function PrimarySwatch() {
|
|
2016
|
+
* const { colorPrimary } = useThemeToken()
|
|
2017
|
+
*
|
|
2018
|
+
* return <div style={{ width: 24, height: 24, background: colorPrimary }} />
|
|
2019
|
+
* }
|
|
2020
|
+
* ```
|
|
1668
2021
|
*/
|
|
1669
2022
|
function useThemeToken() {
|
|
1670
2023
|
return theme.useToken().token;
|