@faasjs/ant-design 8.0.0-beta.5 → 8.0.0-beta.7

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.mjs CHANGED
@@ -1,886 +1,1034 @@
1
- import { createSplittingContext, FaasDataWrapper as FaasDataWrapper$1, withFaasData as withFaasData$1, useEqualEffect, FaasReactClient, useEqualCallback, ErrorBoundary as ErrorBoundary$1, OptionalWrapper, faas } from '@faasjs/react';
2
- export { FaasReactClient, faas, useFaas } from '@faasjs/react';
3
- import { Form as Form$1, Spin, Drawer, Modal, message, notification, ConfigProvider as ConfigProvider$1, Typography, Descriptions, Input, Button, Row, Col, DatePicker, Switch, Select, InputNumber, Radio, Result, Skeleton, Table as Table$1, Tabs as Tabs$1, theme, Alert, Space } from 'antd';
4
- export { Drawer, Modal } from 'antd';
5
- import { BrowserRouter, useNavigate, Routes as Routes$1, Route, useLocation } from 'react-router-dom';
6
- import { defaultsDeep, cloneDeep, isNil, uniqBy } from 'lodash-es';
7
- import { createContext, useState, useContext, cloneElement, isValidElement, createElement, useEffect, Suspense } from 'react';
8
- export { lazy } from 'react';
9
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
10
- import { PlusOutlined, MinusCircleOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons';
11
- import dayjs2 from 'dayjs';
1
+ import { ErrorBoundary as ErrorBoundary$1, FaasDataWrapper as FaasDataWrapper$1, FaasReactClient, OptionalWrapper, createSplittingContext, faas, useEqualCallback, useEqualEffect, useFaas, withFaasData as withFaasData$1 } from "@faasjs/react";
2
+ import { Alert, Button, Col, ConfigProvider as ConfigProvider$1, DatePicker, Descriptions, Drawer, Form as Form$1, Input, InputNumber, Modal, Radio, Result, Row, Select, Skeleton, Space, Spin, Switch, Table as Table$1, Tabs as Tabs$1, Typography, message, notification, theme } from "antd";
3
+ import { BrowserRouter, Route, Routes as Routes$1, useLocation, useNavigate } from "react-router-dom";
4
+ import { cloneDeep, defaultsDeep, isNil, uniqBy } from "lodash-es";
5
+ import { Suspense, cloneElement, createContext, createElement, isValidElement, lazy, useContext, useEffect, useState } from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { CheckOutlined, CloseOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
8
+ import dayjs from "dayjs";
12
9
 
13
- // src/App.tsx
10
+ //#region src/Loading.tsx
11
+ /**
12
+ * Loading component based on Spin
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <Loading /> // display loading
17
+ *
18
+ * <Loading loading={ !remoteData }>
19
+ * <div>{remoteData}</div>
20
+ * </Loading>
21
+ * ```
22
+ */
14
23
  function Loading(props) {
15
- if (props.loading === false) return /* @__PURE__ */ jsx(Fragment, { children: props.children });
16
- return /* @__PURE__ */ jsx(
17
- "div",
18
- {
19
- style: {
20
- ...props.style || {},
21
- ...!props.size || props.size === "large" ? {
22
- margin: "20vh auto",
23
- textAlign: "center"
24
- } : {}
25
- },
26
- children: /* @__PURE__ */ jsx(Spin, { size: props.size || "large" })
27
- }
28
- );
24
+ if (props.loading === false) return /* @__PURE__ */ jsx(Fragment, { children: props.children });
25
+ return /* @__PURE__ */ jsx("div", {
26
+ style: {
27
+ ...props.style || {},
28
+ ...!props.size || props.size === "large" ? {
29
+ margin: "20vh auto",
30
+ textAlign: "center"
31
+ } : {}
32
+ },
33
+ children: /* @__PURE__ */ jsx(Spin, { size: props.size || "large" })
34
+ });
29
35
  }
36
+
37
+ //#endregion
38
+ //#region src/FaasDataWrapper.tsx
39
+ /**
40
+ * FaasDataWrapper component with Loading
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * function MyComponent (props: FaasDataInjection) {
45
+ * return <div>{ props.data }</div>
46
+ * }
47
+ *
48
+ * function MyPage () {
49
+ * return <FaasDataWrapper action="test" params={{ a: 1 }}>
50
+ * <MyComponent />
51
+ * </FaasDataWrapper>
52
+ * }
53
+ * ```
54
+ */
30
55
  function FaasDataWrapper(props) {
31
- return /* @__PURE__ */ jsx(
32
- FaasDataWrapper$1,
33
- {
34
- fallback: props.loading || /* @__PURE__ */ jsx(Loading, { ...props.loadingProps }),
35
- ...props
36
- }
37
- );
56
+ return /* @__PURE__ */ jsx(FaasDataWrapper$1, {
57
+ fallback: props.loading || /* @__PURE__ */ jsx(Loading, { ...props.loadingProps }),
58
+ ...props
59
+ });
38
60
  }
61
+ /**
62
+ * HOC to wrap a component with FaasDataWrapper and Loading
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * const MyComponent = withFaasData(({ data }) => <div>{data.name}</div>, { action: 'test', params: { a: 1 } })
67
+ * ```
68
+ */
39
69
  function withFaasData(Component, faasProps) {
40
- return withFaasData$1(Component, {
41
- fallback: faasProps.loading || /* @__PURE__ */ jsx(Loading, { ...faasProps.loadingProps }),
42
- ...faasProps
43
- });
70
+ return withFaasData$1(Component, {
71
+ fallback: faasProps.loading || /* @__PURE__ */ jsx(Loading, { ...faasProps.loadingProps }),
72
+ ...faasProps
73
+ });
44
74
  }
45
- var zh = {
46
- lang: "zh",
47
- blank: "\u7A7A",
48
- all: "\u5168\u90E8",
49
- submit: "\u63D0\u4EA4",
50
- pageNotFound: "\u9875\u9762\u672A\u627E\u5230",
51
- add: "\u6DFB\u52A0",
52
- delete: "\u5220\u9664",
53
- required: "\u5FC5\u586B",
54
- search: "\u641C\u7D22",
55
- reset: "\u91CD\u7F6E"
75
+
76
+ //#endregion
77
+ //#region src/Config.tsx
78
+ const zh = {
79
+ lang: "zh",
80
+ blank: "",
81
+ all: "全部",
82
+ submit: "提交",
83
+ pageNotFound: "页面未找到",
84
+ add: "添加",
85
+ delete: "删除",
86
+ required: "必填",
87
+ search: "搜索",
88
+ reset: "重置"
56
89
  };
57
- var en = {
58
- lang: "en",
59
- blank: "Empty",
60
- all: "All",
61
- submit: "Submit",
62
- pageNotFound: "Page Not Found",
63
- add: "Add",
64
- delete: "Delete",
65
- required: "is required",
66
- search: "Search",
67
- reset: "Reset"
90
+ const en = {
91
+ lang: "en",
92
+ blank: "Empty",
93
+ all: "All",
94
+ submit: "Submit",
95
+ pageNotFound: "Page Not Found",
96
+ add: "Add",
97
+ delete: "Delete",
98
+ required: "is required",
99
+ search: "Search",
100
+ reset: "Reset"
68
101
  };
69
- var baseTheme = {
70
- lang: "en",
71
- common: en,
72
- Blank: { text: en.blank },
73
- Form: { submit: { text: en.submit } },
74
- Title: {
75
- separator: " - ",
76
- suffix: ""
77
- },
78
- Link: { style: {} }
102
+ const baseTheme = {
103
+ lang: "en",
104
+ common: en,
105
+ Blank: { text: en.blank },
106
+ Form: { submit: { text: en.submit } },
107
+ Title: {
108
+ separator: " - ",
109
+ suffix: ""
110
+ },
111
+ Link: { style: {} }
79
112
  };
80
- var ConfigContext = createContext({
81
- theme: baseTheme
82
- });
113
+ const ConfigContext = createContext({ theme: baseTheme });
114
+ /**
115
+ * Config for `@faasjs/ant-design` components.
116
+ *
117
+ * @example
118
+ * ```tsx
119
+ * import { ConfigProvider } from '@faasjs/ant-design'
120
+ *
121
+ * <ConfigProvider theme={{ common: { blank: 'Empty' } }}>
122
+ * <Blank />
123
+ * </ConfigProvider>
124
+ * ```
125
+ */
83
126
  function ConfigProvider(props) {
84
- const [theme2, setTheme] = useState();
85
- useEqualEffect(() => {
86
- const lang = props.theme?.lang || (!props.theme?.lang && /^zh/i.test(navigator.language) ? "zh" : "en");
87
- if (lang === "zh") {
88
- setTheme(
89
- defaultsDeep(
90
- props.theme,
91
- {
92
- lang: "zh",
93
- common: zh,
94
- Blank: { text: zh.blank },
95
- Form: { submit: { text: zh.submit } }
96
- },
97
- baseTheme
98
- )
99
- );
100
- } else setTheme(defaultsDeep(props.theme, baseTheme));
101
- if (props.faasClientOptions) FaasReactClient(props.faasClientOptions);
102
- }, [props.theme]);
103
- if (!theme2) return null;
104
- return /* @__PURE__ */ jsx(ConfigContext.Provider, { value: { theme: theme2 }, children: props.children });
127
+ const [theme, setTheme] = useState();
128
+ useEqualEffect(() => {
129
+ if ((props.theme?.lang || (!props.theme?.lang && /^zh/i.test(navigator.language) ? "zh" : "en")) === "zh") setTheme(defaultsDeep(props.theme, {
130
+ lang: "zh",
131
+ common: zh,
132
+ Blank: { text: zh.blank },
133
+ Form: { submit: { text: zh.submit } }
134
+ }, baseTheme));
135
+ else setTheme(defaultsDeep(props.theme, baseTheme));
136
+ if (props.faasClientOptions) FaasReactClient(props.faasClientOptions);
137
+ }, [props.theme]);
138
+ if (!theme) return null;
139
+ return /* @__PURE__ */ jsx(ConfigContext.Provider, {
140
+ value: { theme },
141
+ children: props.children
142
+ });
105
143
  }
106
144
  function useConfigContext() {
107
- return useContext(ConfigContext);
145
+ return useContext(ConfigContext);
108
146
  }
147
+
148
+ //#endregion
149
+ //#region src/Drawer.tsx
150
+ /**
151
+ * Hook style drawer
152
+ *
153
+ * ```tsx
154
+ * function Example() {
155
+ * const { drawer, setDrawerProps } = useDrawer()
156
+ *
157
+ * return <>
158
+ * <Button onClick={ () => setDrawerProps(prev => ({ open: !prev.open})) }>
159
+ * Toggle
160
+ * </Button>
161
+ * {drawer}
162
+ * </>
163
+ * }
164
+ * ```
165
+ */
109
166
  function useDrawer(init) {
110
- const [props, setProps] = useState({
111
- open: false,
112
- ...init
113
- });
114
- const setDrawerProps = useEqualCallback(
115
- (changes) => {
116
- const changed = typeof changes === "function" ? changes(props) : changes;
117
- setProps((prev) => ({ ...prev, ...changed }));
118
- },
119
- [setProps]
120
- );
121
- return {
122
- drawer: /* @__PURE__ */ jsx(
123
- Drawer,
124
- {
125
- onClose: () => setProps((prev) => ({
126
- ...prev,
127
- open: false
128
- })),
129
- ...props
130
- }
131
- ),
132
- drawerProps: props,
133
- setDrawerProps
134
- };
167
+ const [props, setProps] = useState({
168
+ open: false,
169
+ ...init
170
+ });
171
+ const setDrawerProps = useEqualCallback((changes) => {
172
+ const changed = typeof changes === "function" ? changes(props) : changes;
173
+ setProps((prev) => ({
174
+ ...prev,
175
+ ...changed
176
+ }));
177
+ }, [setProps]);
178
+ return {
179
+ drawer: /* @__PURE__ */ jsx(Drawer, {
180
+ onClose: () => setProps((prev) => ({
181
+ ...prev,
182
+ open: false
183
+ })),
184
+ ...props
185
+ }),
186
+ drawerProps: props,
187
+ setDrawerProps
188
+ };
135
189
  }
190
+
191
+ //#endregion
192
+ //#region src/ErrorBoundary.tsx
136
193
  function ErrorChildren(props) {
137
- return /* @__PURE__ */ jsx(
138
- Alert,
139
- {
140
- type: "error",
141
- message: props.errorMessage,
142
- description: /* @__PURE__ */ jsx(
143
- "pre",
144
- {
145
- style: {
146
- fontSize: "0.9em",
147
- overflowX: "auto"
148
- },
149
- children: props.errorDescription
150
- }
151
- )
152
- }
153
- );
194
+ return /* @__PURE__ */ jsx(Alert, {
195
+ type: "error",
196
+ message: props.errorMessage,
197
+ description: /* @__PURE__ */ jsx("pre", {
198
+ style: {
199
+ fontSize: "0.9em",
200
+ overflowX: "auto"
201
+ },
202
+ children: props.errorDescription
203
+ })
204
+ });
154
205
  }
206
+ /**
207
+ * Styled error boundary.
208
+ */
155
209
  function ErrorBoundary(props) {
156
- return /* @__PURE__ */ jsx(ErrorBoundary$1, { errorChildren: /* @__PURE__ */ jsx(ErrorChildren, {}), ...props });
210
+ return /* @__PURE__ */ jsx(ErrorBoundary$1, {
211
+ errorChildren: /* @__PURE__ */ jsx(ErrorChildren, {}),
212
+ ...props
213
+ });
157
214
  }
215
+
216
+ //#endregion
217
+ //#region src/Modal.tsx
218
+ /**
219
+ * Hook style modal
220
+ *
221
+ * ```tsx
222
+ * function Example() {
223
+ * const { modal, setModalProps } = useModal()
224
+ *
225
+ * return <>
226
+ * <Button onClick={() => setModalProps({ open: true })}>Open Modal</Button>
227
+ * {modal}
228
+ * </>
229
+ * }
230
+ * ```
231
+ */
158
232
  function useModal(init) {
159
- const [props, setProps] = useState({ open: false, ...init });
160
- const setModalProps = useEqualCallback(
161
- (changes) => {
162
- const changed = typeof changes === "function" ? changes(props) : changes;
163
- setProps((prev) => ({ ...prev, ...changed }));
164
- },
165
- [setProps]
166
- );
167
- return {
168
- modal: /* @__PURE__ */ jsx(
169
- Modal,
170
- {
171
- onCancel: () => setProps((prev) => ({
172
- ...prev,
173
- open: false
174
- })),
175
- ...props
176
- }
177
- ),
178
- modalProps: props,
179
- setModalProps
180
- };
233
+ const [props, setProps] = useState({
234
+ open: false,
235
+ ...init
236
+ });
237
+ const setModalProps = useEqualCallback((changes) => {
238
+ const changed = typeof changes === "function" ? changes(props) : changes;
239
+ setProps((prev) => ({
240
+ ...prev,
241
+ ...changed
242
+ }));
243
+ }, [setProps]);
244
+ return {
245
+ modal: /* @__PURE__ */ jsx(Modal, {
246
+ onCancel: () => setProps((prev) => ({
247
+ ...prev,
248
+ open: false
249
+ })),
250
+ ...props
251
+ }),
252
+ modalProps: props,
253
+ setModalProps
254
+ };
181
255
  }
182
- var AppContext = createSplittingContext([
183
- "message",
184
- "notification",
185
- "modalProps",
186
- "setModalProps",
187
- "drawerProps",
188
- "setDrawerProps"
256
+
257
+ //#endregion
258
+ //#region src/App.tsx
259
+ const AppContext = createSplittingContext([
260
+ "message",
261
+ "notification",
262
+ "modalProps",
263
+ "setModalProps",
264
+ "drawerProps",
265
+ "setDrawerProps"
189
266
  ]);
190
267
  function RoutesApp(props) {
191
- const location = useLocation();
192
- const { drawerProps, setDrawerProps, modalProps, setModalProps } = useApp();
193
- useEqualEffect(() => {
194
- console.debug("location", location);
195
- if (drawerProps.open) setDrawerProps({ open: false });
196
- if (modalProps.open) setModalProps({ open: false });
197
- }, [location]);
198
- return /* @__PURE__ */ jsx(Fragment, { children: props.children });
268
+ const location = useLocation();
269
+ const { drawerProps, setDrawerProps, modalProps, setModalProps } = useApp();
270
+ useEqualEffect(() => {
271
+ console.debug("location", location);
272
+ if (drawerProps.open) setDrawerProps({ open: false });
273
+ if (modalProps.open) setModalProps({ open: false });
274
+ }, [location]);
275
+ return /* @__PURE__ */ jsx(Fragment, { children: props.children });
199
276
  }
277
+ /**
278
+ * App component with Ant Design & FaasJS
279
+ *
280
+ * - Based on Ant Design's [ConfigProvider](https://ant.design/components/config-provider/).
281
+ * - Integrated Ant Design's [Message](https://ant.design/components/message/) and [Notification](https://ant.design/components/notification/).
282
+ * - Based on FaasJS's [ConfigProvider](https://faasjs.com/doc/ant-design/#configprovider).
283
+ * - 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).
284
+ * - Integrated React Router's [BrowserRouter](https://api.reactrouter.com/v7/interfaces/react_router.BrowserRouterProps.html).
285
+ *
286
+ * @example
287
+ * ```tsx
288
+ * import { App } from '@faasjs/ant-design'
289
+ *
290
+ * export default function () {
291
+ * return (
292
+ * <App
293
+ * configProviderProps={{}} // https://ant.design/components/config-provider/#API
294
+ * browserRouterProps={{}} // https://api.reactrouter.com/v7/interfaces/react_router.BrowserRouterProps.html
295
+ * errorBoundaryProps={{}} // https://faasjs.com/doc/ant-design/#errorboundary
296
+ * faasConfigProviderProps={{}} // https://faasjs.com/doc/ant-design/#configprovider
297
+ * >
298
+ * <div>content</div>
299
+ * </App>
300
+ * )
301
+ * }
302
+ * ```
303
+ */
200
304
  function App(props) {
201
- const [messageApi, messageContextHolder] = message.useMessage();
202
- const [notificationApi, notificationContextHolder] = notification.useNotification();
203
- const { modal, modalProps, setModalProps } = useModal();
204
- const { drawer, drawerProps, setDrawerProps } = useDrawer();
205
- return /* @__PURE__ */ jsx(
206
- OptionalWrapper,
207
- {
208
- condition: !!props.configProviderProps,
209
- Wrapper: ConfigProvider$1,
210
- wrapperProps: props.configProviderProps,
211
- children: /* @__PURE__ */ jsx(
212
- AppContext.Provider,
213
- {
214
- value: {
215
- message: messageApi,
216
- notification: notificationApi,
217
- drawerProps,
218
- setDrawerProps,
219
- modalProps,
220
- setModalProps
221
- },
222
- children: /* @__PURE__ */ jsx(
223
- ConfigProvider,
224
- {
225
- ...props.faasConfigProviderProps,
226
- faasClientOptions: {
227
- onError: (action) => async (res) => {
228
- if ("message" in res && res.toString().includes("AbortError"))
229
- return;
230
- console.error(`[FaasJS][${action}]`, res);
231
- messageApi.error("message" in res ? res.message : "Unknown error");
232
- },
233
- ...props.faasConfigProviderProps ? props.faasConfigProviderProps.faasClientOptions : {}
234
- },
235
- children: /* @__PURE__ */ jsx(ErrorBoundary, { ...props.errorBoundaryProps, children: /* @__PURE__ */ jsxs(
236
- OptionalWrapper,
237
- {
238
- condition: typeof document !== "undefined" && props.browserRouterProps !== false,
239
- Wrapper: BrowserRouter,
240
- wrapperProps: props.browserRouterProps,
241
- children: [
242
- messageContextHolder,
243
- notificationContextHolder,
244
- modal,
245
- drawer,
246
- props.browserRouterProps !== false ? /* @__PURE__ */ jsx(RoutesApp, { children: props.children }) : props.children
247
- ]
248
- }
249
- ) })
250
- }
251
- )
252
- }
253
- )
254
- }
255
- );
305
+ const [messageApi, messageContextHolder] = message.useMessage();
306
+ const [notificationApi, notificationContextHolder] = notification.useNotification();
307
+ const { modal, modalProps, setModalProps } = useModal();
308
+ const { drawer, drawerProps, setDrawerProps } = useDrawer();
309
+ return /* @__PURE__ */ jsx(OptionalWrapper, {
310
+ condition: !!props.configProviderProps,
311
+ Wrapper: ConfigProvider$1,
312
+ wrapperProps: props.configProviderProps,
313
+ children: /* @__PURE__ */ jsx(AppContext.Provider, {
314
+ value: {
315
+ message: messageApi,
316
+ notification: notificationApi,
317
+ drawerProps,
318
+ setDrawerProps,
319
+ modalProps,
320
+ setModalProps
321
+ },
322
+ children: /* @__PURE__ */ jsx(ConfigProvider, {
323
+ ...props.faasConfigProviderProps,
324
+ faasClientOptions: {
325
+ onError: (action) => async (res) => {
326
+ if ("message" in res && res.toString().includes("AbortError")) return;
327
+ console.error(`[FaasJS][${action}]`, res);
328
+ messageApi.error("message" in res ? res.message : "Unknown error");
329
+ },
330
+ ...props.faasConfigProviderProps ? props.faasConfigProviderProps.faasClientOptions : {}
331
+ },
332
+ children: /* @__PURE__ */ jsx(ErrorBoundary, {
333
+ ...props.errorBoundaryProps,
334
+ children: /* @__PURE__ */ jsxs(OptionalWrapper, {
335
+ condition: typeof document !== "undefined" && props.browserRouterProps !== false,
336
+ Wrapper: BrowserRouter,
337
+ wrapperProps: props.browserRouterProps,
338
+ children: [
339
+ messageContextHolder,
340
+ notificationContextHolder,
341
+ modal,
342
+ drawer,
343
+ props.browserRouterProps !== false ? /* @__PURE__ */ jsx(RoutesApp, { children: props.children }) : props.children
344
+ ]
345
+ })
346
+ })
347
+ })
348
+ })
349
+ });
256
350
  }
257
- var useApp = AppContext.use;
351
+ /**
352
+ * Get app context.
353
+ *
354
+ * ```ts
355
+ * import { useApp } from '@faasjs/ant-design'
356
+ *
357
+ * const { message, notification, setModalProps, setDrawerProps } = useApp()
358
+ * ```
359
+ */
360
+ const useApp = AppContext.use;
258
361
  App.useApp = useApp;
362
+
363
+ //#endregion
364
+ //#region src/Blank.tsx
365
+ /**
366
+ * Blank component.
367
+ *
368
+ * If value is undefined or null, return text, otherwise return value.
369
+ *
370
+ * @example
371
+ * ```tsx
372
+ * import { Blank } from '@faasjs/ant-design'
373
+ *
374
+ * <Blank value={undefined} text="Empty" />
375
+ * ```
376
+ */
259
377
  function Blank(options) {
260
- const { theme: theme2 } = useConfigContext();
261
- return !options || options.value === void 0 || options.value === null || Array.isArray(options.value) && !options.value.length || options.value === "" ? /* @__PURE__ */ jsx(Typography.Text, { disabled: true, children: options?.text || theme2.Blank.text }) : options.value;
378
+ const { theme } = useConfigContext();
379
+ return !options || options.value === void 0 || options.value === null || Array.isArray(options.value) && !options.value.length || options.value === "" ? /* @__PURE__ */ jsx(Typography.Text, {
380
+ disabled: true,
381
+ children: options?.text || theme.Blank.text
382
+ }) : options.value;
262
383
  }
384
+
385
+ //#endregion
386
+ //#region src/data.ts
387
+ /**
388
+ * Converts an identifier string to a title case string.
389
+ *
390
+ * This function takes an identifier string with words separated by underscores,
391
+ * capitalizes the first letter of each word, and joins them together without spaces.
392
+ *
393
+ * @param id - The identifier string to convert.
394
+ * @returns The converted title case string.
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * idToTitle('example_id'); // returns 'ExampleId'
399
+ * ```
400
+ */
263
401
  function idToTitle(id) {
264
- if (typeof id === "number") return id.toString();
265
- const splitted = id.split(/(\s|_|-)/).filter((word) => !/(\s|_|-)/.test(word)).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
266
- return splitted.charAt(0).toUpperCase() + splitted.slice(1);
402
+ if (typeof id === "number") return id.toString();
403
+ const splitted = id.split(/(\s|_|-)/).filter((word) => !/(\s|_|-)/.test(word)).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
404
+ return splitted.charAt(0).toUpperCase() + splitted.slice(1);
267
405
  }
406
+ /**
407
+ * convert string[] or number[] to { label, value }[]
408
+ */
268
409
  function transferOptions(options) {
269
- if (!options) return [];
270
- return options.map(
271
- (item) => typeof item === "object" ? item : {
272
- label: idToTitle(item.toString()),
273
- value: item
274
- }
275
- );
410
+ if (!options) return [];
411
+ return options.map((item) => typeof item === "object" ? item : {
412
+ label: idToTitle(item.toString()),
413
+ value: item
414
+ });
276
415
  }
277
416
  function transferValue(type, value) {
278
- if (!type) type = "string";
279
- if (!type.endsWith("[]") && (typeof value === "undefined" || value === null || value === "" || value === "null" || value === "undefined"))
280
- return null;
281
- if (type.endsWith("[]")) {
282
- if (!value) value = [];
283
- if (typeof value === "string") value = value.split(",").filter(Boolean);
284
- if (!Array.isArray(value)) value = [value];
285
- value = value.map(
286
- (item) => transferValue(type.replace("[]", ""), item)
287
- );
288
- }
289
- switch (type) {
290
- case "boolean":
291
- if (typeof value === "string") value = value === "true";
292
- break;
293
- case "number":
294
- if (typeof value === "string") value = Number(value);
295
- break;
296
- case "date":
297
- case "time":
298
- if (typeof value === "number" && value.toString().length === 10)
299
- value = value * 1e3;
300
- if (!dayjs2.isDayjs(value)) value = dayjs2(value);
301
- break;
302
- }
303
- return value;
417
+ if (!type) type = "string";
418
+ if (!type.endsWith("[]") && (typeof value === "undefined" || value === null || value === "" || value === "null" || value === "undefined")) return null;
419
+ if (type.endsWith("[]")) {
420
+ if (!value) value = [];
421
+ if (typeof value === "string") value = value.split(",").filter(Boolean);
422
+ if (!Array.isArray(value)) value = [value];
423
+ value = value.map((item) => transferValue(type.replace("[]", ""), item));
424
+ }
425
+ switch (type) {
426
+ case "boolean":
427
+ if (typeof value === "string") value = value === "true";
428
+ break;
429
+ case "number":
430
+ if (typeof value === "string") value = Number(value);
431
+ break;
432
+ case "date":
433
+ case "time":
434
+ if (typeof value === "number" && value.toString().length === 10) value = value * 1e3;
435
+ if (!dayjs.isDayjs(value)) value = dayjs(value);
436
+ break;
437
+ }
438
+ return value;
304
439
  }
440
+ /**
441
+ * Clone a UnionFaasItemElement with the given props.
442
+ *
443
+ * This function takes a UnionFaasItemElement and props, and returns a cloned element.
444
+ * If the provided element is a valid React element, it clones it with the new props.
445
+ * Otherwise, it creates a new element from the provided element and props.
446
+ *
447
+ * @param element - The UnionFaasItemElement to be cloned.
448
+ * @param props - The props to be applied to the cloned element.
449
+ * @returns The cloned element with the applied props.
450
+ */
305
451
  function cloneUnionFaasItemElement(element, props) {
306
- return cloneElement(
307
- isValidElement(element) ? element : createElement(element),
308
- props
309
- );
452
+ return cloneElement(isValidElement(element) ? element : createElement(element), props);
310
453
  }
454
+
455
+ //#endregion
456
+ //#region src/Description.tsx
311
457
  function DescriptionItemContent(props) {
312
- const [computedProps, setComputedProps] = useState();
313
- useEffect(() => {
314
- const propsCopy = { ...props };
315
- propsCopy.item.title = propsCopy.item.title ?? idToTitle(propsCopy.item.id);
316
- if (!propsCopy.item.type) propsCopy.item.type = "string";
317
- if (propsCopy.item.options?.length) {
318
- propsCopy.item.options = transferOptions(propsCopy.item.options);
319
- }
320
- propsCopy.value = transferValue(propsCopy.item.type, propsCopy.value);
321
- if (propsCopy.item.options && propsCopy.value !== null) {
322
- if (propsCopy.item.type.endsWith("[]"))
323
- propsCopy.value = propsCopy.value.map(
324
- (v) => propsCopy.item.options.find((option) => option.value === v)?.label || v
325
- );
326
- else if (["string", "number", "boolean"].includes(propsCopy.item.type))
327
- propsCopy.value = props.item.options.find((option) => option.value === props.value)?.label || props.value;
328
- }
329
- setComputedProps(propsCopy);
330
- }, [props]);
331
- if (!computedProps) return null;
332
- if (computedProps.item.descriptionChildren === null || computedProps.item.children === null || computedProps.item.descriptionRender === null || computedProps.item.render === null)
333
- return null;
334
- const children = computedProps.item.descriptionChildren || computedProps.item.children;
335
- if (children)
336
- return cloneUnionFaasItemElement(children, {
337
- scene: "description",
338
- value: computedProps.value,
339
- values: computedProps.values,
340
- index: 0
341
- });
342
- const render = computedProps.item.descriptionRender || computedProps.item.render;
343
- if (render)
344
- return /* @__PURE__ */ jsx(Fragment, { children: render(computedProps.value, computedProps.values, 0, "description") });
345
- if (computedProps.extendTypes?.[computedProps.item.type]) {
346
- if (computedProps.extendTypes[computedProps.item.type].children)
347
- return cloneUnionFaasItemElement(
348
- computedProps.extendTypes[computedProps.item.type].children,
349
- {
350
- scene: "description",
351
- value: computedProps.value,
352
- values: computedProps.values
353
- }
354
- );
355
- if (computedProps.extendTypes[computedProps.item.type].render)
356
- return /* @__PURE__ */ jsx(Fragment, { children: computedProps.extendTypes[computedProps.item.type].render(
357
- computedProps.value,
358
- computedProps.values,
359
- 0,
360
- "description"
361
- ) });
362
- throw Error(`${computedProps.item.type} requires children or render`);
363
- }
364
- if (computedProps.value === null || Array.isArray(computedProps.value) && !computedProps.value.length)
365
- return /* @__PURE__ */ jsx(Blank, {});
366
- switch (computedProps.item.type) {
367
- case "string[]":
368
- return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.join(", ") });
369
- case "number":
370
- return computedProps.value || null;
371
- case "number[]":
372
- return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.join(", ") });
373
- case "boolean":
374
- return computedProps.value ? /* @__PURE__ */ jsx(
375
- CheckOutlined,
376
- {
377
- style: {
378
- marginTop: "4px",
379
- color: "#52c41a"
380
- }
381
- }
382
- ) : /* @__PURE__ */ jsx(
383
- CloseOutlined,
384
- {
385
- style: {
386
- marginTop: "4px",
387
- color: "#ff4d4f"
388
- }
389
- }
390
- );
391
- case "time":
392
- return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.format("YYYY-MM-DD HH:mm:ss") });
393
- case "date":
394
- return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.format("YYYY-MM-DD") });
395
- case "object":
396
- if (!computedProps.value) return /* @__PURE__ */ jsx(Blank, {});
397
- return /* @__PURE__ */ jsx(
398
- Description,
399
- {
400
- items: computedProps.item.object,
401
- dataSource: computedProps.value,
402
- column: 1
403
- }
404
- );
405
- case "object[]":
406
- if (!computedProps.value?.length)
407
- return /* @__PURE__ */ jsx(Blank, {});
408
- return /* @__PURE__ */ jsx(Space, { direction: "vertical", children: computedProps.value.map(
409
- (value, index) => /* @__PURE__ */ jsx(
410
- Description,
411
- {
412
- items: computedProps.item.object,
413
- dataSource: value,
414
- column: 1
415
- },
416
- index
417
- )
418
- ) });
419
- default:
420
- return computedProps.value || null;
421
- }
458
+ const [computedProps, setComputedProps] = useState();
459
+ useEffect(() => {
460
+ const propsCopy = { ...props };
461
+ propsCopy.item.title = propsCopy.item.title ?? idToTitle(propsCopy.item.id);
462
+ if (!propsCopy.item.type) propsCopy.item.type = "string";
463
+ if (propsCopy.item.options?.length) propsCopy.item.options = transferOptions(propsCopy.item.options);
464
+ propsCopy.value = transferValue(propsCopy.item.type, propsCopy.value);
465
+ if (propsCopy.item.options && propsCopy.value !== null) {
466
+ if (propsCopy.item.type.endsWith("[]")) propsCopy.value = propsCopy.value.map((v) => propsCopy.item.options.find((option) => option.value === v)?.label || v);
467
+ else if ([
468
+ "string",
469
+ "number",
470
+ "boolean"
471
+ ].includes(propsCopy.item.type)) propsCopy.value = props.item.options.find((option) => option.value === props.value)?.label || props.value;
472
+ }
473
+ setComputedProps(propsCopy);
474
+ }, [props]);
475
+ if (!computedProps) return null;
476
+ const itemType = computedProps.item.type ?? "string";
477
+ if (computedProps.item.descriptionChildren === null || computedProps.item.children === null || computedProps.item.descriptionRender === null || computedProps.item.render === null) return null;
478
+ const children = computedProps.item.descriptionChildren || computedProps.item.children;
479
+ if (children) return cloneUnionFaasItemElement(children, {
480
+ scene: "description",
481
+ value: computedProps.value,
482
+ values: computedProps.values,
483
+ index: 0
484
+ });
485
+ const render = computedProps.item.descriptionRender || computedProps.item.render;
486
+ if (render) return /* @__PURE__ */ jsx(Fragment, { children: render(computedProps.value, computedProps.values, 0, "description") });
487
+ if (computedProps.extendTypes?.[itemType]) {
488
+ const extendType = computedProps.extendTypes[itemType];
489
+ if (extendType.children) return cloneUnionFaasItemElement(extendType.children, {
490
+ scene: "description",
491
+ value: computedProps.value,
492
+ values: computedProps.values
493
+ });
494
+ if (extendType.render) return /* @__PURE__ */ jsx(Fragment, { children: extendType.render(computedProps.value, computedProps.values, 0, "description") });
495
+ throw Error(`${itemType} requires children or render`);
496
+ }
497
+ if (computedProps.value === null || Array.isArray(computedProps.value) && !computedProps.value.length) return /* @__PURE__ */ jsx(Blank, {});
498
+ switch (itemType) {
499
+ case "string[]": return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.join(", ") });
500
+ case "number": return computedProps.value || null;
501
+ case "number[]": return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.join(", ") });
502
+ case "boolean": return computedProps.value ? /* @__PURE__ */ jsx(CheckOutlined, { style: {
503
+ marginTop: "4px",
504
+ color: "#52c41a"
505
+ } }) : /* @__PURE__ */ jsx(CloseOutlined, { style: {
506
+ marginTop: "4px",
507
+ color: "#ff4d4f"
508
+ } });
509
+ case "time": return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.format("YYYY-MM-DD HH:mm:ss") });
510
+ case "date": return /* @__PURE__ */ jsx(Fragment, { children: computedProps.value.format("YYYY-MM-DD") });
511
+ case "object":
512
+ if (!computedProps.value) return /* @__PURE__ */ jsx(Blank, {});
513
+ return /* @__PURE__ */ jsx(Description, {
514
+ items: computedProps.item.object || [],
515
+ dataSource: computedProps.value,
516
+ column: 1
517
+ });
518
+ case "object[]":
519
+ if (!computedProps.value?.length) return /* @__PURE__ */ jsx(Blank, {});
520
+ return /* @__PURE__ */ jsx(Space, {
521
+ direction: "vertical",
522
+ children: computedProps.value.map((value, index) => /* @__PURE__ */ jsx(Description, {
523
+ items: computedProps.item.object || [],
524
+ dataSource: value,
525
+ column: 1
526
+ }, index))
527
+ });
528
+ default: return computedProps.value || null;
529
+ }
422
530
  }
423
531
  DescriptionItemContent.displayName = "DescriptionItemContent";
424
- function Description({
425
- faasData,
426
- dataSource,
427
- renderTitle,
428
- extendTypes,
429
- ...props
430
- }) {
431
- if (faasData && !dataSource)
432
- return /* @__PURE__ */ jsx(
433
- FaasDataWrapper,
434
- {
435
- render: ({ data }) => /* @__PURE__ */ jsx(
436
- Description,
437
- {
438
- ...props,
439
- dataSource: data,
440
- renderTitle,
441
- extendTypes
442
- }
443
- ),
444
- ...faasData
445
- }
446
- );
447
- return /* @__PURE__ */ jsx(
448
- Descriptions,
449
- {
450
- ...props,
451
- title: typeof renderTitle === "function" ? renderTitle(dataSource) : props.title,
452
- items: props.items.filter(
453
- (item) => item && !(item.descriptionChildren === null || item.children === null || item.descriptionRender === null || item.render === null) && (!item.if || item.if(dataSource))
454
- ).map((item) => ({
455
- ...item,
456
- key: item.id,
457
- label: item.title ?? idToTitle(item.id),
458
- children: /* @__PURE__ */ jsx(
459
- DescriptionItemContent,
460
- {
461
- item,
462
- value: dataSource ? dataSource[item.id] : null,
463
- values: dataSource,
464
- extendTypes
465
- }
466
- )
467
- }))
468
- }
469
- );
532
+ /**
533
+ * Description component
534
+ *
535
+ * - Based on [Ant Design Descriptions](https://ant.design/components/descriptions/).
536
+ *
537
+ * @example
538
+ * ```tsx
539
+ * import { Description } from '@faasjs/ant-design'
540
+ *
541
+ * <Description
542
+ * title="Title"
543
+ * items={[
544
+ * {
545
+ * id: 'id',
546
+ * title: 'Title',
547
+ * type: 'string',
548
+ * },
549
+ * ]}
550
+ * dataSource={{ id: 'value' }}
551
+ * />
552
+ * ```
553
+ */
554
+ function Description({ faasData, dataSource, renderTitle, extendTypes, ...props }) {
555
+ if (faasData && !dataSource) return /* @__PURE__ */ jsx(FaasDataWrapper, {
556
+ render: ({ data }) => /* @__PURE__ */ jsx(Description, {
557
+ ...props,
558
+ dataSource: data,
559
+ ...renderTitle ? { renderTitle } : {},
560
+ ...extendTypes ? { extendTypes } : {}
561
+ }),
562
+ ...faasData
563
+ });
564
+ return /* @__PURE__ */ jsx(Descriptions, {
565
+ ...props,
566
+ title: typeof renderTitle === "function" ? renderTitle(dataSource) : props.title,
567
+ items: props.items.filter((item) => item && !(item.descriptionChildren === null || item.children === null || item.descriptionRender === null || item.render === null) && (!item.if || item.if(dataSource))).map((item) => ({
568
+ ...item,
569
+ key: item.id,
570
+ label: item.title ?? idToTitle(item.id),
571
+ children: /* @__PURE__ */ jsx(DescriptionItemContent, {
572
+ item,
573
+ value: dataSource ? dataSource[item.id] : null,
574
+ ...dataSource ? { values: dataSource } : {},
575
+ ...extendTypes ? { extendTypes } : {}
576
+ })
577
+ }))
578
+ });
470
579
  }
471
580
  Description.displayName = "Description";
581
+
582
+ //#endregion
583
+ //#region src/FormItem.tsx
472
584
  function isOptionsProps(item) {
473
- return item && Array.isArray(item.options);
585
+ return item && Array.isArray(item.options);
474
586
  }
475
587
  function processProps(propsCopy, config) {
476
- propsCopy.title = propsCopy.title ?? idToTitle(propsCopy.id);
477
- if (!propsCopy.label && propsCopy.label !== false)
478
- propsCopy.label = propsCopy.title;
479
- if (!propsCopy.name) propsCopy.name = propsCopy.id;
480
- if (!propsCopy.type) propsCopy.type = "string";
481
- if (!propsCopy.rules) propsCopy.rules = [];
482
- if (propsCopy.required) {
483
- if (propsCopy.type.endsWith("[]"))
484
- propsCopy.rules.push({
485
- required: true,
486
- validator: async (_, values) => {
487
- if (!values || values.length < 1)
488
- return Promise.reject(
489
- Error(`${propsCopy.label || propsCopy.title} ${config.required}`)
490
- );
491
- }
492
- });
493
- else
494
- propsCopy.rules.push({
495
- required: true,
496
- message: `${propsCopy.label || propsCopy.title} ${config.required}`
497
- });
498
- }
499
- if (!propsCopy.input) propsCopy.input = {};
500
- if (isOptionsProps(propsCopy))
501
- propsCopy.input.options = transferOptions(propsCopy.options);
502
- switch (propsCopy.type) {
503
- case "boolean":
504
- propsCopy.valuePropName = "checked";
505
- break;
506
- case "object":
507
- if (!Array.isArray(propsCopy.name)) propsCopy.name = [propsCopy.name];
508
- for (const sub of propsCopy.object) {
509
- if (!sub.name) sub.name = propsCopy.name.concat(sub.id);
510
- processProps(sub, config);
511
- }
512
- break;
513
- }
514
- return propsCopy;
588
+ propsCopy.title = propsCopy.title ?? idToTitle(propsCopy.id);
589
+ if (!propsCopy.label && propsCopy.label !== false) propsCopy.label = propsCopy.title;
590
+ if (!propsCopy.name) propsCopy.name = propsCopy.id;
591
+ if (!propsCopy.type) propsCopy.type = "string";
592
+ if (!propsCopy.rules) propsCopy.rules = [];
593
+ if (propsCopy.required) if (propsCopy.type.endsWith("[]")) propsCopy.rules.push({
594
+ required: true,
595
+ validator: async (_, values) => {
596
+ if (!values || values.length < 1) return Promise.reject(Error(`${propsCopy.label || propsCopy.title} ${config.required}`));
597
+ }
598
+ });
599
+ else propsCopy.rules.push({
600
+ required: true,
601
+ message: `${propsCopy.label || propsCopy.title} ${config.required}`
602
+ });
603
+ if (!propsCopy.input) propsCopy.input = {};
604
+ if (isOptionsProps(propsCopy)) propsCopy.input.options = transferOptions(propsCopy.options);
605
+ switch (propsCopy.type) {
606
+ case "boolean":
607
+ propsCopy.valuePropName = "checked";
608
+ break;
609
+ case "object":
610
+ if (!Array.isArray(propsCopy.name)) propsCopy.name = [propsCopy.name];
611
+ for (const sub of propsCopy.object || []) {
612
+ if (!sub.name) sub.name = propsCopy.name.concat(sub.id);
613
+ processProps(sub, config);
614
+ }
615
+ break;
616
+ }
617
+ return propsCopy;
515
618
  }
619
+ /**
620
+ * FormItem
621
+ *
622
+ * - Based on [Ant Design Form.Item](https://ant.design/components/form#formitem).
623
+ * - Can be used without [Form](https://faasjs.com/doc/ant-design/#form).
624
+ *
625
+ * @example
626
+ * ```tsx
627
+ * // use inline type
628
+ * <FormItem type='string' id='name' />
629
+ *
630
+ * // use custom type
631
+ * <FormItem id='password'>
632
+ * <Input.Password />
633
+ * </>
634
+ * ```
635
+ */
516
636
  function FormItem(props) {
517
- const [computedProps, setComputedProps] = useState();
518
- const [extendTypes, setExtendTypes] = useState();
519
- const { theme: theme2 } = useConfigContext();
520
- const [hidden, setHidden] = useState(props.hidden || false);
521
- useEffect(() => {
522
- const { extendTypes: extendTypes2, ...propsCopy } = { ...props };
523
- if (extendTypes2) {
524
- setExtendTypes(extendTypes2);
525
- }
526
- if (propsCopy.if) {
527
- const condition = propsCopy.if;
528
- const originShouldUpdate = propsCopy.shouldUpdate;
529
- propsCopy.shouldUpdate = (prev, cur) => {
530
- const show = condition(cur);
531
- const shouldUpdate = hidden !== show;
532
- setHidden(!show);
533
- const origin = originShouldUpdate ? typeof originShouldUpdate === "boolean" ? originShouldUpdate : originShouldUpdate(prev, cur, {}) : true;
534
- return shouldUpdate || origin;
535
- };
536
- delete propsCopy.if;
537
- delete propsCopy.hidden;
538
- }
539
- setComputedProps(processProps(propsCopy, theme2.common));
540
- }, [props]);
541
- if (!computedProps) return null;
542
- if (hidden)
543
- return /* @__PURE__ */ jsx(
544
- Form$1.Item,
545
- {
546
- ...computedProps,
547
- id: computedProps.id.toString(),
548
- noStyle: true,
549
- rules: [],
550
- children: /* @__PURE__ */ jsx(Input, { type: "hidden", hidden: true })
551
- }
552
- );
553
- if (computedProps.formChildren === null || computedProps.children === null || computedProps.formRender === null || computedProps.render === null)
554
- return null;
555
- const children = computedProps.formChildren || computedProps.children;
556
- if (children)
557
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: cloneUnionFaasItemElement(children, { scene: "form" }) });
558
- const render = computedProps.formRender || computedProps.render;
559
- if (render)
560
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: render(null, null, 0, "form") });
561
- if (extendTypes?.[computedProps.type])
562
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: cloneUnionFaasItemElement(extendTypes[computedProps.type].children, {
563
- scene: "form"
564
- }) });
565
- switch (computedProps.type) {
566
- case "string":
567
- if (isOptionsProps(computedProps))
568
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: computedProps.options.length > 10 ? /* @__PURE__ */ jsx(Select, { ...computedProps.input }) : /* @__PURE__ */ jsx(Radio.Group, { ...computedProps.input }) });
569
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(Input, { ...computedProps.input }) });
570
- case "string[]":
571
- if (isOptionsProps(computedProps))
572
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(Select, { mode: "multiple", ...computedProps.input }) });
573
- return /* @__PURE__ */ jsx(
574
- Form$1.List,
575
- {
576
- name: computedProps.name,
577
- rules: computedProps.rules,
578
- children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [
579
- computedProps.label && /* @__PURE__ */ jsx("div", { className: "ant-form-item-label", children: /* @__PURE__ */ jsx(
580
- "label",
581
- {
582
- className: computedProps.rules.find((r) => r.required) && "ant-form-item-required",
583
- children: computedProps.label
584
- }
585
- ) }),
586
- fields.map((field) => {
587
- const { key, ...fieldProps } = field;
588
- return /* @__PURE__ */ jsx(Form$1.Item, { id: key.toString(), children: /* @__PURE__ */ jsxs(Row, { gutter: 24, style: { flexFlow: "row nowrap" }, children: [
589
- /* @__PURE__ */ jsx(Col, { span: 23, children: /* @__PURE__ */ jsx(Form$1.Item, { ...fieldProps, noStyle: true, children: /* @__PURE__ */ jsx(Input, { ...computedProps.input }) }) }),
590
- /* @__PURE__ */ jsx(Col, { span: 1, children: !computedProps.input?.disabled && (!computedProps.rules.find((r) => r.required) || key > 0) && /* @__PURE__ */ jsx(
591
- Button,
592
- {
593
- danger: true,
594
- type: "link",
595
- style: { float: "right" },
596
- icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}),
597
- onClick: () => remove(field.name)
598
- }
599
- ) })
600
- ] }) }, key);
601
- }),
602
- /* @__PURE__ */ jsxs(Form$1.Item, { children: [
603
- !computedProps.input?.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsx(
604
- Button,
605
- {
606
- type: "dashed",
607
- block: true,
608
- onClick: () => add(),
609
- icon: /* @__PURE__ */ jsx(PlusOutlined, {})
610
- }
611
- ),
612
- computedProps.extra && /* @__PURE__ */ jsx("div", { className: "ant-form-item-extra", children: computedProps.extra }),
613
- /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
614
- ] })
615
- ] })
616
- }
617
- );
618
- case "number":
619
- if (computedProps.options)
620
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: computedProps.options.length > 10 ? /* @__PURE__ */ jsx(Select, { ...computedProps.input }) : /* @__PURE__ */ jsx(Radio.Group, { ...computedProps.input }) });
621
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(
622
- InputNumber,
623
- {
624
- style: { width: "100%" },
625
- ...computedProps.input
626
- }
627
- ) });
628
- case "number[]":
629
- if (computedProps.options)
630
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(Select, { mode: "multiple", ...computedProps.input }) });
631
- return /* @__PURE__ */ jsx(
632
- Form$1.List,
633
- {
634
- name: computedProps.name,
635
- rules: computedProps.rules,
636
- children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [
637
- computedProps.label && /* @__PURE__ */ jsx("div", { className: "ant-form-item-label", children: /* @__PURE__ */ jsx(
638
- "label",
639
- {
640
- className: computedProps.rules?.find(
641
- (r) => r.required
642
- ) && "ant-form-item-required",
643
- children: computedProps.label
644
- }
645
- ) }),
646
- fields.map((field) => {
647
- const { key, ...fieldProps } = field;
648
- return /* @__PURE__ */ jsx(Form$1.Item, { id: key.toString(), children: /* @__PURE__ */ jsxs(Row, { gutter: 24, style: { flexFlow: "row nowrap" }, children: [
649
- /* @__PURE__ */ jsx(Col, { span: 23, children: /* @__PURE__ */ jsx(Form$1.Item, { ...fieldProps, noStyle: true, children: /* @__PURE__ */ jsx(
650
- InputNumber,
651
- {
652
- style: { width: "100%" },
653
- ...computedProps.input
654
- }
655
- ) }) }),
656
- /* @__PURE__ */ jsx(Col, { span: 1, children: !computedProps.input?.disabled && (!computedProps.rules.find((r) => r.required) || key > 0) && /* @__PURE__ */ jsx(
657
- Button,
658
- {
659
- danger: true,
660
- type: "link",
661
- style: { float: "right" },
662
- icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}),
663
- onClick: () => remove(field.name)
664
- }
665
- ) })
666
- ] }) }, key);
667
- }),
668
- /* @__PURE__ */ jsxs(Form$1.Item, { children: [
669
- !computedProps.input?.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsx(
670
- Button,
671
- {
672
- type: "dashed",
673
- block: true,
674
- onClick: () => add(),
675
- icon: /* @__PURE__ */ jsx(PlusOutlined, {})
676
- }
677
- ),
678
- computedProps.extra && /* @__PURE__ */ jsx("div", { className: "ant-form-item-extra", children: computedProps.extra }),
679
- /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
680
- ] })
681
- ] })
682
- }
683
- );
684
- case "boolean":
685
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(Switch, { ...computedProps.input }) });
686
- case "date":
687
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(DatePicker, { ...computedProps.input }) });
688
- case "time":
689
- return /* @__PURE__ */ jsx(Form$1.Item, { ...computedProps, id: computedProps.id.toString(), children: /* @__PURE__ */ jsx(
690
- DatePicker,
691
- {
692
- ...{ ...computedProps.input, showTime: true }
693
- }
694
- ) });
695
- case "object":
696
- return /* @__PURE__ */ jsxs(Fragment, { children: [
697
- computedProps.label && /* @__PURE__ */ jsx("div", { className: "ant-form-item-label", children: /* @__PURE__ */ jsx(
698
- "label",
699
- {
700
- className: computedProps.rules?.find((r) => r.required) && "ant-form-item-required",
701
- children: computedProps.label
702
- }
703
- ) }),
704
- computedProps.object.map((o) => /* @__PURE__ */ jsx(FormItem, { ...o }, o.id))
705
- ] });
706
- case "object[]":
707
- return /* @__PURE__ */ jsx(
708
- Form$1.List,
709
- {
710
- name: computedProps.name,
711
- rules: computedProps.rules,
712
- children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [
713
- fields.map((field) => /* @__PURE__ */ jsxs(
714
- Form$1.Item,
715
- {
716
- id: field.key.toString(),
717
- style: { marginBottom: 0 },
718
- children: [
719
- /* @__PURE__ */ jsx("div", { className: "ant-form-item-label", children: /* @__PURE__ */ jsxs("label", { children: [
720
- computedProps.label,
721
- " ",
722
- field.name + 1,
723
- !computedProps.disabled && (!computedProps.rules.find((r) => r.required) || field.key > 0) && /* @__PURE__ */ jsx(
724
- Button,
725
- {
726
- danger: true,
727
- type: "link",
728
- onClick: () => remove(field.name),
729
- children: theme2.common.delete
730
- }
731
- )
732
- ] }) }),
733
- /* @__PURE__ */ jsx(Row, { gutter: 24, children: computedProps.object.map((o) => /* @__PURE__ */ jsx(Col, { span: o.col || 24, children: /* @__PURE__ */ jsx(FormItem, { ...o, name: [field.name, o.id] }) }, o.id)) })
734
- ]
735
- },
736
- field.key
737
- )),
738
- /* @__PURE__ */ jsxs(Form$1.Item, { children: [
739
- !computedProps.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsxs(
740
- Button,
741
- {
742
- type: "dashed",
743
- block: true,
744
- onClick: () => add(),
745
- icon: /* @__PURE__ */ jsx(PlusOutlined, {}),
746
- children: [
747
- theme2.common.add,
748
- " ",
749
- computedProps.label
750
- ]
751
- }
752
- ),
753
- computedProps.extra && /* @__PURE__ */ jsx("div", { className: "ant-form-item-extra", children: computedProps.extra }),
754
- /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
755
- ] })
756
- ] })
757
- }
758
- );
759
- default:
760
- return null;
761
- }
637
+ const [computedProps, setComputedProps] = useState();
638
+ const [extendTypes, setExtendTypes] = useState();
639
+ const { theme } = useConfigContext();
640
+ const [hidden, setHidden] = useState(props.hidden || false);
641
+ useEffect(() => {
642
+ const { extendTypes, ...propsCopy } = { ...props };
643
+ if (extendTypes) setExtendTypes(extendTypes);
644
+ if (propsCopy.if) {
645
+ const condition = propsCopy.if;
646
+ const originShouldUpdate = propsCopy.shouldUpdate;
647
+ propsCopy.shouldUpdate = (prev, cur) => {
648
+ const show = condition(cur);
649
+ const shouldUpdate = hidden !== show;
650
+ setHidden(!show);
651
+ const origin = originShouldUpdate ? typeof originShouldUpdate === "boolean" ? originShouldUpdate : originShouldUpdate(prev, cur, {}) : true;
652
+ return shouldUpdate || origin;
653
+ };
654
+ delete propsCopy.if;
655
+ delete propsCopy.hidden;
656
+ }
657
+ setComputedProps(processProps(propsCopy, theme.common));
658
+ }, [props]);
659
+ if (!computedProps) return null;
660
+ const itemType = computedProps.type ?? "string";
661
+ if (hidden) return /* @__PURE__ */ jsx(Form$1.Item, {
662
+ ...computedProps,
663
+ id: computedProps.id.toString(),
664
+ noStyle: true,
665
+ rules: [],
666
+ children: /* @__PURE__ */ jsx(Input, {
667
+ type: "hidden",
668
+ hidden: true
669
+ })
670
+ });
671
+ if (computedProps.formChildren === null || computedProps.children === null || computedProps.formRender === null || computedProps.render === null) return null;
672
+ const children = computedProps.formChildren || computedProps.children;
673
+ if (children) return /* @__PURE__ */ jsx(Form$1.Item, {
674
+ ...computedProps,
675
+ id: computedProps.id.toString(),
676
+ children: cloneUnionFaasItemElement(children, { scene: "form" })
677
+ });
678
+ const render = computedProps.formRender || computedProps.render;
679
+ if (render) return /* @__PURE__ */ jsx(Form$1.Item, {
680
+ ...computedProps,
681
+ id: computedProps.id.toString(),
682
+ children: render(void 0, Object.create(null), 0, "form")
683
+ });
684
+ const extendType = extendTypes?.[itemType];
685
+ if (extendType?.children) return /* @__PURE__ */ jsx(Form$1.Item, {
686
+ ...computedProps,
687
+ id: computedProps.id.toString(),
688
+ children: cloneUnionFaasItemElement(extendType.children, { scene: "form" })
689
+ });
690
+ switch (itemType) {
691
+ case "string":
692
+ if (isOptionsProps(computedProps)) return /* @__PURE__ */ jsx(Form$1.Item, {
693
+ ...computedProps,
694
+ id: computedProps.id.toString(),
695
+ children: computedProps.options.length > 10 ? /* @__PURE__ */ jsx(Select, { ...computedProps.input }) : /* @__PURE__ */ jsx(Radio.Group, { ...computedProps.input })
696
+ });
697
+ return /* @__PURE__ */ jsx(Form$1.Item, {
698
+ ...computedProps,
699
+ id: computedProps.id.toString(),
700
+ children: /* @__PURE__ */ jsx(Input, { ...computedProps.input })
701
+ });
702
+ case "string[]":
703
+ if (isOptionsProps(computedProps)) return /* @__PURE__ */ jsx(Form$1.Item, {
704
+ ...computedProps,
705
+ id: computedProps.id.toString(),
706
+ children: /* @__PURE__ */ jsx(Select, {
707
+ mode: "multiple",
708
+ ...computedProps.input
709
+ })
710
+ });
711
+ return /* @__PURE__ */ jsx(Form$1.List, {
712
+ name: computedProps.name,
713
+ rules: computedProps.rules,
714
+ children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [
715
+ computedProps.label && /* @__PURE__ */ jsx("div", {
716
+ className: "ant-form-item-label",
717
+ children: /* @__PURE__ */ jsx("label", {
718
+ className: (computedProps.rules || []).find((r) => r.required) && "ant-form-item-required",
719
+ children: computedProps.label
720
+ })
721
+ }),
722
+ fields.map((field) => {
723
+ const { key, ...fieldProps } = field;
724
+ return /* @__PURE__ */ jsx(Form$1.Item, {
725
+ id: key.toString(),
726
+ children: /* @__PURE__ */ jsxs(Row, {
727
+ gutter: 24,
728
+ style: { flexFlow: "row nowrap" },
729
+ children: [/* @__PURE__ */ jsx(Col, {
730
+ span: 23,
731
+ children: /* @__PURE__ */ jsx(Form$1.Item, {
732
+ ...fieldProps,
733
+ noStyle: true,
734
+ children: /* @__PURE__ */ jsx(Input, { ...computedProps.input })
735
+ })
736
+ }), /* @__PURE__ */ jsx(Col, {
737
+ span: 1,
738
+ children: !computedProps.input?.disabled && (!(computedProps.rules || []).find((r) => r.required) || key > 0) && /* @__PURE__ */ jsx(Button, {
739
+ danger: true,
740
+ type: "link",
741
+ style: { float: "right" },
742
+ icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}),
743
+ onClick: () => remove(field.name)
744
+ })
745
+ })]
746
+ })
747
+ }, key);
748
+ }),
749
+ /* @__PURE__ */ jsxs(Form$1.Item, { children: [
750
+ !computedProps.input?.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsx(Button, {
751
+ type: "dashed",
752
+ block: true,
753
+ onClick: () => add(),
754
+ icon: /* @__PURE__ */ jsx(PlusOutlined, {})
755
+ }),
756
+ computedProps.extra && /* @__PURE__ */ jsx("div", {
757
+ className: "ant-form-item-extra",
758
+ children: computedProps.extra
759
+ }),
760
+ /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
761
+ ] })
762
+ ] })
763
+ });
764
+ case "number":
765
+ if (isOptionsProps(computedProps)) return /* @__PURE__ */ jsx(Form$1.Item, {
766
+ ...computedProps,
767
+ id: computedProps.id.toString(),
768
+ children: computedProps.options.length > 10 ? /* @__PURE__ */ jsx(Select, { ...computedProps.input }) : /* @__PURE__ */ jsx(Radio.Group, { ...computedProps.input })
769
+ });
770
+ return /* @__PURE__ */ jsx(Form$1.Item, {
771
+ ...computedProps,
772
+ id: computedProps.id.toString(),
773
+ children: /* @__PURE__ */ jsx(InputNumber, {
774
+ style: { width: "100%" },
775
+ ...computedProps.input
776
+ })
777
+ });
778
+ case "number[]":
779
+ if (isOptionsProps(computedProps)) return /* @__PURE__ */ jsx(Form$1.Item, {
780
+ ...computedProps,
781
+ id: computedProps.id.toString(),
782
+ children: /* @__PURE__ */ jsx(Select, {
783
+ mode: "multiple",
784
+ ...computedProps.input
785
+ })
786
+ });
787
+ return /* @__PURE__ */ jsx(Form$1.List, {
788
+ name: computedProps.name,
789
+ rules: computedProps.rules,
790
+ children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [
791
+ computedProps.label && /* @__PURE__ */ jsx("div", {
792
+ className: "ant-form-item-label",
793
+ children: /* @__PURE__ */ jsx("label", {
794
+ className: computedProps.rules?.find((r) => r.required) && "ant-form-item-required",
795
+ children: computedProps.label
796
+ })
797
+ }),
798
+ fields.map((field) => {
799
+ const { key, ...fieldProps } = field;
800
+ return /* @__PURE__ */ jsx(Form$1.Item, {
801
+ id: key.toString(),
802
+ children: /* @__PURE__ */ jsxs(Row, {
803
+ gutter: 24,
804
+ style: { flexFlow: "row nowrap" },
805
+ children: [/* @__PURE__ */ jsx(Col, {
806
+ span: 23,
807
+ children: /* @__PURE__ */ jsx(Form$1.Item, {
808
+ ...fieldProps,
809
+ noStyle: true,
810
+ children: /* @__PURE__ */ jsx(InputNumber, {
811
+ style: { width: "100%" },
812
+ ...computedProps.input
813
+ })
814
+ })
815
+ }), /* @__PURE__ */ jsx(Col, {
816
+ span: 1,
817
+ children: !computedProps.input?.disabled && (!(computedProps.rules || []).find((r) => r.required) || key > 0) && /* @__PURE__ */ jsx(Button, {
818
+ danger: true,
819
+ type: "link",
820
+ style: { float: "right" },
821
+ icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}),
822
+ onClick: () => remove(field.name)
823
+ })
824
+ })]
825
+ })
826
+ }, key);
827
+ }),
828
+ /* @__PURE__ */ jsxs(Form$1.Item, { children: [
829
+ !computedProps.input?.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsx(Button, {
830
+ type: "dashed",
831
+ block: true,
832
+ onClick: () => add(),
833
+ icon: /* @__PURE__ */ jsx(PlusOutlined, {})
834
+ }),
835
+ computedProps.extra && /* @__PURE__ */ jsx("div", {
836
+ className: "ant-form-item-extra",
837
+ children: computedProps.extra
838
+ }),
839
+ /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
840
+ ] })
841
+ ] })
842
+ });
843
+ case "boolean": return /* @__PURE__ */ jsx(Form$1.Item, {
844
+ ...computedProps,
845
+ id: computedProps.id.toString(),
846
+ children: /* @__PURE__ */ jsx(Switch, { ...computedProps.input })
847
+ });
848
+ case "date": return /* @__PURE__ */ jsx(Form$1.Item, {
849
+ ...computedProps,
850
+ id: computedProps.id.toString(),
851
+ children: /* @__PURE__ */ jsx(DatePicker, { ...computedProps.input })
852
+ });
853
+ case "time": return /* @__PURE__ */ jsx(Form$1.Item, {
854
+ ...computedProps,
855
+ id: computedProps.id.toString(),
856
+ children: /* @__PURE__ */ jsx(DatePicker, {
857
+ ...computedProps.input,
858
+ showTime: true
859
+ })
860
+ });
861
+ case "object": {
862
+ const objectItems = computedProps.object || [];
863
+ return /* @__PURE__ */ jsxs(Fragment, { children: [computedProps.label && /* @__PURE__ */ jsx("div", {
864
+ className: "ant-form-item-label",
865
+ children: /* @__PURE__ */ jsx("label", {
866
+ className: computedProps.rules?.find((r) => r.required) && "ant-form-item-required",
867
+ children: computedProps.label
868
+ })
869
+ }), objectItems.map((o) => /* @__PURE__ */ jsx(FormItem, { ...o }, o.id))] });
870
+ }
871
+ case "object[]": return /* @__PURE__ */ jsx(Form$1.List, {
872
+ name: computedProps.name,
873
+ rules: computedProps.rules,
874
+ children: (fields, { add, remove }, { errors }) => /* @__PURE__ */ jsxs(Fragment, { children: [fields.map((field) => /* @__PURE__ */ jsxs(Form$1.Item, {
875
+ id: field.key.toString(),
876
+ style: { marginBottom: 0 },
877
+ children: [/* @__PURE__ */ jsx("div", {
878
+ className: "ant-form-item-label",
879
+ children: /* @__PURE__ */ jsxs("label", { children: [
880
+ computedProps.label,
881
+ " ",
882
+ field.name + 1,
883
+ !computedProps.disabled && (!(computedProps.rules || []).find((r) => r.required) || field.key > 0) && /* @__PURE__ */ jsx(Button, {
884
+ danger: true,
885
+ type: "link",
886
+ onClick: () => remove(field.name),
887
+ children: theme.common.delete
888
+ })
889
+ ] })
890
+ }), /* @__PURE__ */ jsx(Row, {
891
+ gutter: 24,
892
+ children: (computedProps.object || []).map((o) => /* @__PURE__ */ jsx(Col, {
893
+ span: o.col || 24,
894
+ children: /* @__PURE__ */ jsx(FormItem, {
895
+ ...o,
896
+ name: [field.name, o.id]
897
+ })
898
+ }, o.id))
899
+ })]
900
+ }, field.key)), /* @__PURE__ */ jsxs(Form$1.Item, { children: [
901
+ !computedProps.disabled && (!computedProps.maxCount || computedProps.maxCount > fields.length) && /* @__PURE__ */ jsxs(Button, {
902
+ type: "dashed",
903
+ block: true,
904
+ onClick: () => add(),
905
+ icon: /* @__PURE__ */ jsx(PlusOutlined, {}),
906
+ children: [
907
+ theme.common.add,
908
+ " ",
909
+ computedProps.label
910
+ ]
911
+ }),
912
+ computedProps.extra && /* @__PURE__ */ jsx("div", {
913
+ className: "ant-form-item-extra",
914
+ children: computedProps.extra
915
+ }),
916
+ /* @__PURE__ */ jsx(Form$1.ErrorList, { errors })
917
+ ] })] })
918
+ });
919
+ default: return null;
920
+ }
762
921
  }
763
922
  FormItem.useStatus = Form$1.Item.useStatus;
923
+
924
+ //#endregion
925
+ //#region src/Form.tsx
764
926
  function isFormItemProps(item) {
765
- return item.id !== void 0;
927
+ return item.id !== void 0;
766
928
  }
929
+ /**
930
+ * Form component with Ant Design & FaasJS
931
+ *
932
+ * - Based on [Ant Design Form](https://ant.design/components/form/).
933
+ */
767
934
  function Form(props) {
768
- const [loading, setLoading] = useState(false);
769
- const [computedProps, setComputedProps] = useState();
770
- const [submit, setSubmit] = useState();
771
- const config = useConfigContext();
772
- const [extendTypes, setExtendTypes] = useState();
773
- const [form] = Form$1.useForm(props.form);
774
- const [initialValues, setInitialValues] = useState(
775
- props.initialValues || /* @__PURE__ */ Object.create(null)
776
- );
777
- useEffect(() => {
778
- const { submit: submit2, ...propsCopy } = {
779
- ...props,
780
- form
781
- };
782
- if (typeof submit2 !== "undefined") setSubmit(submit2);
783
- if (propsCopy.initialValues && propsCopy.items?.length) {
784
- for (const key in propsCopy.initialValues) {
785
- propsCopy.initialValues[key] = transferValue(
786
- propsCopy.items.find((item) => isFormItemProps(item) && item.id === key)?.type,
787
- propsCopy.initialValues[key]
788
- );
789
- }
790
- setInitialValues(propsCopy.initialValues);
791
- delete propsCopy.initialValues;
792
- }
793
- if (propsCopy.items?.length)
794
- for (const item of propsCopy.items) {
795
- if (isFormItemProps(item) && item.if)
796
- item.hidden = !item.if(initialValues || /* @__PURE__ */ Object.create(null));
797
- }
798
- if (propsCopy.onFinish) {
799
- propsCopy.onFinish = async (values) => {
800
- setLoading(true);
801
- try {
802
- if (submit2?.to?.action) {
803
- await props.onFinish(
804
- values,
805
- async (values2) => faas(
806
- submit2.to.action,
807
- submit2.to.params ? {
808
- ...values2,
809
- ...submit2.to.params
810
- } : values2
811
- )
812
- );
813
- } else await props.onFinish(values);
814
- } catch (error) {
815
- console.error(error);
816
- }
817
- setLoading(false);
818
- };
819
- } else if (submit2 && submit2.to?.action) {
820
- propsCopy.onFinish = async (values) => {
821
- setLoading(true);
822
- return faas(
823
- submit2.to.action,
824
- submit2.to.params ? {
825
- ...values,
826
- ...submit2.to.params
827
- } : values
828
- ).then((result) => {
829
- if (submit2.to.then)
830
- submit2.to.then(result);
831
- return result;
832
- }).catch((error) => {
833
- if (submit2.to.catch)
834
- submit2.to.catch(error);
835
- return Promise.reject(error);
836
- }).finally(() => {
837
- if (submit2.to.finally)
838
- submit2.to.finally();
839
- setLoading(false);
840
- });
841
- };
842
- }
843
- if (propsCopy.extendTypes) {
844
- setExtendTypes(propsCopy.extendTypes);
845
- delete propsCopy.extendTypes;
846
- }
847
- setComputedProps(propsCopy);
848
- }, [props]);
849
- const onValuesChange = useEqualCallback(
850
- (changedValues, allValues) => {
851
- console.debug("Form:onValuesChange", changedValues, allValues);
852
- if (props.onValuesChange) {
853
- props.onValuesChange(changedValues, allValues);
854
- }
855
- if (!props.items) return;
856
- for (const key in changedValues) {
857
- const item = computedProps.items.find(
858
- (i) => isFormItemProps(i) && i.id === key
859
- );
860
- if (item?.onValueChange)
861
- item.onValueChange(changedValues[key], allValues, form);
862
- }
863
- },
864
- [computedProps]
865
- );
866
- useEffect(() => {
867
- if (!initialValues) return;
868
- console.debug("Form:initialValues", initialValues);
869
- form.setFieldsValue(initialValues);
870
- setInitialValues(null);
871
- }, [computedProps]);
872
- if (!computedProps) return null;
873
- return /* @__PURE__ */ jsxs(Form$1, { ...computedProps, onValuesChange, children: [
874
- computedProps.beforeItems,
875
- computedProps.items?.map((item) => {
876
- if (isFormItemProps(item))
877
- return /* @__PURE__ */ jsx(FormItem, { ...item, extendTypes }, item.id);
878
- return item;
879
- }),
880
- computedProps.children,
881
- typeof submit !== "boolean" && /* @__PURE__ */ jsx(Button, { htmlType: "submit", type: "primary", loading, children: submit?.text || config.theme.Form.submit.text }),
882
- computedProps.footer
883
- ] });
935
+ const [loading, setLoading] = useState(false);
936
+ const [computedProps, setComputedProps] = useState();
937
+ const [submit, setSubmit] = useState();
938
+ const config = useConfigContext();
939
+ const [extendTypes, setExtendTypes] = useState();
940
+ const [form] = Form$1.useForm(props.form);
941
+ const [initialValues, setInitialValues] = useState(props.initialValues || Object.create(null));
942
+ useEffect(() => {
943
+ const { submit, ...propsCopy } = {
944
+ ...props,
945
+ form
946
+ };
947
+ if (typeof submit !== "undefined") setSubmit(submit);
948
+ if (propsCopy.initialValues && propsCopy.items?.length) {
949
+ for (const key in propsCopy.initialValues) propsCopy.initialValues[key] = transferValue(propsCopy.items.find((item) => isFormItemProps(item) && item.id === key)?.type, propsCopy.initialValues[key]);
950
+ setInitialValues(propsCopy.initialValues);
951
+ delete propsCopy.initialValues;
952
+ }
953
+ if (propsCopy.items?.length) {
954
+ for (const item of propsCopy.items) if (isFormItemProps(item) && item.if) item.hidden = !item.if(initialValues || Object.create(null));
955
+ }
956
+ const submitTo = typeof submit === "object" ? submit.to : void 0;
957
+ if (propsCopy.onFinish) {
958
+ const originOnFinish = propsCopy.onFinish;
959
+ propsCopy.onFinish = async (values) => {
960
+ setLoading(true);
961
+ try {
962
+ if (submitTo?.action) await originOnFinish(values, async (nextValues) => faas(submitTo.action, submitTo.params ? {
963
+ ...nextValues,
964
+ ...submitTo.params
965
+ } : nextValues));
966
+ else await originOnFinish(values);
967
+ } catch (error) {
968
+ console.error(error);
969
+ }
970
+ setLoading(false);
971
+ };
972
+ } else if (submitTo?.action) propsCopy.onFinish = async (values) => {
973
+ setLoading(true);
974
+ return faas(submitTo.action, submitTo.params ? {
975
+ ...values,
976
+ ...submitTo.params
977
+ } : values).then((result) => {
978
+ submitTo.then?.(result);
979
+ return result;
980
+ }).catch((error) => {
981
+ submitTo.catch?.(error);
982
+ return Promise.reject(error);
983
+ }).finally(() => {
984
+ submitTo.finally?.();
985
+ setLoading(false);
986
+ });
987
+ };
988
+ if (propsCopy.extendTypes) {
989
+ setExtendTypes(propsCopy.extendTypes);
990
+ delete propsCopy.extendTypes;
991
+ }
992
+ setComputedProps(propsCopy);
993
+ }, [props]);
994
+ const onValuesChange = useEqualCallback((changedValues, allValues) => {
995
+ console.debug("Form:onValuesChange", changedValues, allValues);
996
+ if (props.onValuesChange) props.onValuesChange(changedValues, allValues);
997
+ if (!props.items) return;
998
+ for (const key in changedValues) {
999
+ const item = computedProps?.items?.find((i) => isFormItemProps(i) && i.id === key);
1000
+ if (item?.onValueChange) item.onValueChange(changedValues[key], allValues, form);
1001
+ }
1002
+ }, [computedProps]);
1003
+ useEffect(() => {
1004
+ if (!initialValues) return;
1005
+ console.debug("Form:initialValues", initialValues);
1006
+ form.setFieldsValue(initialValues);
1007
+ setInitialValues(null);
1008
+ }, [computedProps]);
1009
+ if (!computedProps) return null;
1010
+ return /* @__PURE__ */ jsxs(Form$1, {
1011
+ ...computedProps,
1012
+ onValuesChange,
1013
+ children: [
1014
+ computedProps.beforeItems,
1015
+ computedProps.items?.map((item) => {
1016
+ if (isFormItemProps(item)) return /* @__PURE__ */ jsx(FormItem, {
1017
+ ...item,
1018
+ ...extendTypes ? { extendTypes } : {}
1019
+ }, item.id);
1020
+ return item;
1021
+ }),
1022
+ computedProps.children,
1023
+ typeof submit !== "boolean" && /* @__PURE__ */ jsx(Button, {
1024
+ htmlType: "submit",
1025
+ type: "primary",
1026
+ loading,
1027
+ children: submit?.text || config.theme.Form.submit.text
1028
+ }),
1029
+ computedProps.footer
1030
+ ]
1031
+ });
884
1032
  }
885
1033
  Form.useForm = Form$1.useForm;
886
1034
  Form.useFormInstance = Form$1.useFormInstance;
@@ -889,685 +1037,646 @@ Form.Item = FormItem;
889
1037
  Form.List = Form$1.List;
890
1038
  Form.ErrorList = Form$1.ErrorList;
891
1039
  Form.Provider = Form$1.Provider;
1040
+
1041
+ //#endregion
1042
+ //#region src/Link.tsx
1043
+ /**
1044
+ * Link component with button
1045
+ *
1046
+ * @example
1047
+ * ```tsx
1048
+ * // pure link
1049
+ * <Link href="/">Home</Link>
1050
+ *
1051
+ * // link with button
1052
+ * <Link href="/" button={{ type:'primary' }}>Home</Link>
1053
+ * ```
1054
+ */
892
1055
  function Link(props) {
893
- const { theme: theme2 } = useConfigContext();
894
- const navigate = useNavigate();
895
- const target = props.target || theme2.Link?.target || (props.href.startsWith("http") ? "_blank" : void 0);
896
- let computedStyle = {
897
- ...theme2.Link.style || {},
898
- cursor: "pointer",
899
- ...props.style
900
- };
901
- if (props.block)
902
- computedStyle = Object.assign(
903
- {
904
- display: "block",
905
- width: "100%"
906
- },
907
- computedStyle
908
- );
909
- if (props.button)
910
- return /* @__PURE__ */ jsx(
911
- Button,
912
- {
913
- ...props.button || {},
914
- style: computedStyle,
915
- onClick: (e) => {
916
- props.onClick ? props.onClick(e) : target === "_blank" ? window.open(props.href) : navigate(props.href);
917
- e.preventDefault();
918
- },
919
- children: props.children ?? props.text
920
- }
921
- );
922
- return /* @__PURE__ */ jsx(
923
- Typography.Link,
924
- {
925
- href: props.href,
926
- target,
927
- style: computedStyle,
928
- copyable: props.copyable,
929
- onClick: (e) => {
930
- e.preventDefault();
931
- if (props.onClick) {
932
- props.onClick(e);
933
- return;
934
- }
935
- if (target === "_blank") {
936
- window.open(props.href);
937
- return;
938
- }
939
- navigate(props.href);
940
- },
941
- children: props.children ?? props.text
942
- }
943
- );
1056
+ const { theme } = useConfigContext();
1057
+ const navigate = useNavigate();
1058
+ const target = props.target || theme.Link?.target || (props.href.startsWith("http") ? "_blank" : void 0);
1059
+ let computedStyle = {
1060
+ ...theme.Link.style || {},
1061
+ cursor: "pointer",
1062
+ ...props.style
1063
+ };
1064
+ if (props.block) computedStyle = Object.assign({
1065
+ display: "block",
1066
+ width: "100%"
1067
+ }, computedStyle);
1068
+ const buttonProps = props.button && typeof props.button === "object" ? props.button : void 0;
1069
+ const copyableProps = typeof props.copyable === "undefined" ? {} : { copyable: props.copyable };
1070
+ if (props.button) return /* @__PURE__ */ jsx(Button, {
1071
+ ...buttonProps,
1072
+ style: computedStyle,
1073
+ onClick: (e) => {
1074
+ props.onClick ? props.onClick(e) : target === "_blank" ? window.open(props.href) : navigate(props.href);
1075
+ e.preventDefault();
1076
+ },
1077
+ children: props.children ?? props.text
1078
+ });
1079
+ return /* @__PURE__ */ jsx(Typography.Link, {
1080
+ href: props.href,
1081
+ target,
1082
+ style: computedStyle,
1083
+ ...copyableProps,
1084
+ onClick: (e) => {
1085
+ e.preventDefault();
1086
+ if (props.onClick) {
1087
+ props.onClick(e);
1088
+ return;
1089
+ }
1090
+ if (target === "_blank") {
1091
+ window.open(props.href);
1092
+ return;
1093
+ }
1094
+ navigate(props.href);
1095
+ },
1096
+ children: props.children ?? props.text
1097
+ });
944
1098
  }
1099
+
1100
+ //#endregion
1101
+ //#region src/Routers.tsx
945
1102
  function PageNotFound() {
946
- const { theme: theme2 } = useConfigContext();
947
- return /* @__PURE__ */ jsx(Result, { status: "404", title: theme2.common.pageNotFound });
1103
+ const { theme } = useConfigContext();
1104
+ return /* @__PURE__ */ jsx(Result, {
1105
+ status: "404",
1106
+ title: theme.common.pageNotFound
1107
+ });
948
1108
  }
1109
+ /**
1110
+ * Routes with lazy loading and 404 page.
1111
+ *
1112
+ * @example
1113
+ * ```tsx
1114
+ * import { Routes, lazy } from '@faasjs/ant-design'
1115
+ * import { BrowserRouter } from 'react-router-dom'
1116
+ *
1117
+ * export function App () {
1118
+ * return <BrowserRouter>
1119
+ * <Routes routes={[
1120
+ * {
1121
+ * path: '/',
1122
+ * page: lazy(() => import('./pages/home'))
1123
+ * }
1124
+ * ]} />
1125
+ * </BrowserRouter>
1126
+ * }
1127
+ * ```
1128
+ */
949
1129
  function Routes(props) {
950
- return /* @__PURE__ */ jsxs(Routes$1, { children: [
951
- props.routes.map((r) => /* @__PURE__ */ jsx(
952
- Route,
953
- {
954
- ...r,
955
- element: r.element || /* @__PURE__ */ jsx(
956
- Suspense,
957
- {
958
- fallback: props.fallback || /* @__PURE__ */ jsx("div", { style: { padding: "24px" }, children: /* @__PURE__ */ jsx(Skeleton, { active: true }) }),
959
- children: /* @__PURE__ */ jsx(r.page, {})
960
- }
961
- )
962
- },
963
- r.path
964
- )),
965
- /* @__PURE__ */ jsx(Route, { path: "*", element: props.notFound || /* @__PURE__ */ jsx(PageNotFound, {}) }, "*")
966
- ] });
1130
+ return /* @__PURE__ */ jsxs(Routes$1, { children: [props.routes.map((r) => {
1131
+ const Page = r.page;
1132
+ return /* @__PURE__ */ jsx(Route, {
1133
+ ...r,
1134
+ element: r.element || (Page ? /* @__PURE__ */ jsx(Suspense, {
1135
+ fallback: props.fallback || /* @__PURE__ */ jsx("div", {
1136
+ style: { padding: "24px" },
1137
+ children: /* @__PURE__ */ jsx(Skeleton, { active: true })
1138
+ }),
1139
+ children: /* @__PURE__ */ jsx(Page, {})
1140
+ }) : void 0)
1141
+ }, r.path);
1142
+ }), /* @__PURE__ */ jsx(Route, {
1143
+ path: "*",
1144
+ element: props.notFound || /* @__PURE__ */ jsx(PageNotFound, {})
1145
+ }, "*")] });
967
1146
  }
1147
+
1148
+ //#endregion
1149
+ //#region src/Table.tsx
968
1150
  function processValue(item, value) {
969
- const transferred = transferValue(item.type, value);
970
- if (transferred === null || Array.isArray(transferred) && transferred.length === 0)
971
- return /* @__PURE__ */ jsx(Blank, {});
972
- if (item.options) {
973
- if (item.type.endsWith("[]"))
974
- return transferred.map(
975
- (v) => item.options.find((option) => option.value === v)?.label || v
976
- ).join(", ");
977
- if (["string", "number", "boolean"].includes(item.type))
978
- return item.options.find((option) => option.value === transferred)?.label || transferred;
979
- }
980
- if (item.type.endsWith("[]")) return transferred.join(", ");
981
- if (["date", "time"].includes(item.type))
982
- return transferred.format(
983
- item.type === "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss"
984
- );
985
- return value;
1151
+ const itemType = item.type ?? "string";
1152
+ const transferred = transferValue(itemType, value);
1153
+ if (transferred === null || Array.isArray(transferred) && transferred.length === 0) return /* @__PURE__ */ jsx(Blank, {});
1154
+ if (item.options) {
1155
+ if (itemType.endsWith("[]")) return transferred.map((v) => item.options.find((option) => option.value === v)?.label || v).join(", ");
1156
+ if ([
1157
+ "string",
1158
+ "number",
1159
+ "boolean"
1160
+ ].includes(itemType)) return item.options.find((option) => option.value === transferred)?.label || transferred;
1161
+ }
1162
+ if (itemType.endsWith("[]")) return transferred.join(", ");
1163
+ if (["date", "time"].includes(itemType)) return transferred.format(itemType === "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss");
1164
+ return transferred;
986
1165
  }
1166
+ /**
1167
+ * Table component with Ant Design & FaasJS
1168
+ *
1169
+ * - Based on [Ant Design Table](https://ant.design/components/table/).
1170
+ * - Support FaasJS injection.
1171
+ * - Auto generate filter dropdown (disable with `filterDropdown: false`).
1172
+ * - Auto generate sorter (disable with `sorter: false`).
1173
+ */
987
1174
  function Table(props) {
988
- const [columns, setColumns] = useState();
989
- const { theme: theme2 } = useConfigContext();
990
- const generateFilterDropdown = (item) => {
991
- if (item.filterDropdown && item.filterDropdown !== true) return;
992
- if (item.options.length < 11) {
993
- if (!item.filters)
994
- item.filters = item.options.map((o) => ({
995
- text: o.label,
996
- value: o.value
997
- }));
998
- return;
999
- }
1000
- item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => /* @__PURE__ */ jsx(
1001
- "div",
1002
- {
1003
- style: {
1004
- padding: 8,
1005
- width: "200px"
1006
- },
1007
- onKeyDown: (e) => e.stopPropagation(),
1008
- children: /* @__PURE__ */ jsx(
1009
- Select,
1010
- {
1011
- options: item.options,
1012
- allowClear: true,
1013
- showSearch: true,
1014
- style: { width: "100%" },
1015
- placeholder: `${theme2.common.search} ${item.title}`,
1016
- value: selectedKeys,
1017
- onChange: (v) => {
1018
- setSelectedKeys(v?.length ? v : []);
1019
- confirm();
1020
- },
1021
- mode: "multiple",
1022
- filterOption: (input, option) => {
1023
- if (!input || !option || !option.label) return true;
1024
- input = input.trim();
1025
- return option.value === input || option.label.toString().toLowerCase().includes(input.toLowerCase());
1026
- }
1027
- }
1028
- )
1029
- }
1030
- );
1031
- return item;
1032
- };
1033
- useEffect(() => {
1034
- const items = cloneDeep(props.items).filter(
1035
- (item) => !(item.tableChildren === null || item.children === null || item.tableRender === null || item.render === null)
1036
- );
1037
- for (const item of items) {
1038
- if (!item.key) item.key = item.id;
1039
- if (!item.dataIndex) item.dataIndex = item.id;
1040
- item.title = item.title ?? idToTitle(item.id);
1041
- if (!item.type) item.type = "string";
1042
- if (item.options?.length) {
1043
- item.options = transferOptions(item.options);
1044
- item.filters = item.options.map((o) => ({
1045
- text: o.label,
1046
- value: o.value
1047
- })).concat({
1048
- text: /* @__PURE__ */ jsx(Blank, {}),
1049
- value: null
1050
- });
1051
- generateFilterDropdown(item);
1052
- }
1053
- const children = item.tableChildren || item.children;
1054
- if (children) {
1055
- item.render = (value, values) => cloneUnionFaasItemElement(children, {
1056
- scene: "table",
1057
- value,
1058
- values,
1059
- index: 0
1060
- });
1061
- delete item.children;
1062
- delete item.tableChildren;
1063
- continue;
1064
- }
1065
- const render = item.tableRender || item.render;
1066
- if (render) {
1067
- item.render = (value, values) => render(value, values, 0, "table");
1068
- delete item.tableRender;
1069
- continue;
1070
- }
1071
- if (props.extendTypes?.[item.type]) {
1072
- if (props.extendTypes[item.type].children) {
1073
- item.render = (value, values) => cloneUnionFaasItemElement(props.extendTypes[item.type].children, {
1074
- scene: "table",
1075
- value,
1076
- values,
1077
- index: 0
1078
- });
1079
- } else if (props.extendTypes[item.type].render)
1080
- item.render = (value, values) => props.extendTypes[item.type].render(value, values, 0, "table");
1081
- else throw Error(`${item.type} requires children or render`);
1082
- continue;
1083
- }
1084
- switch (item.type) {
1085
- case "string":
1086
- if (!item.render) item.render = (value) => processValue(item, value);
1087
- if (item.filterDropdown !== false) {
1088
- if (!item.onFilter && !props.faasData)
1089
- item.onFilter = (value, row) => {
1090
- if (!value || isNil(value)) return true;
1091
- if (isNil(row[item.id])) return false;
1092
- return row[item.id].trim().toLowerCase().includes(value.trim().toLowerCase());
1093
- };
1094
- if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto")
1095
- item.filterDropdown = ({
1096
- setSelectedKeys,
1097
- confirm,
1098
- clearFilters
1099
- }) => /* @__PURE__ */ jsx(
1100
- Input.Search,
1101
- {
1102
- placeholder: `${theme2.common.search} ${item.title}`,
1103
- allowClear: true,
1104
- onSearch: (v) => {
1105
- if (v) {
1106
- setSelectedKeys([v]);
1107
- } else {
1108
- setSelectedKeys([]);
1109
- clearFilters();
1110
- }
1111
- confirm();
1112
- }
1113
- }
1114
- );
1115
- }
1116
- break;
1117
- case "string[]":
1118
- if (!item.render) item.render = (value) => processValue(item, value);
1119
- if (item.filterDropdown !== false) {
1120
- if (!item.onFilter && !props.faasData)
1121
- item.onFilter = (value, row) => {
1122
- if (value === null && (!row[item.id] || !row[item.id].length))
1123
- return true;
1124
- if (!row[item.id] || !row[item.id].length || !value)
1125
- return false;
1126
- return row[item.id].some(
1127
- (v) => v.trim().toLowerCase().includes(value.trim().toLowerCase())
1128
- );
1129
- };
1130
- if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto")
1131
- item.filterDropdown = ({
1132
- setSelectedKeys,
1133
- confirm,
1134
- clearFilters
1135
- }) => /* @__PURE__ */ jsx(
1136
- Input.Search,
1137
- {
1138
- placeholder: `${theme2.common.search} ${item.title}`,
1139
- allowClear: true,
1140
- onSearch: (v) => {
1141
- if (v) {
1142
- setSelectedKeys([v]);
1143
- } else {
1144
- setSelectedKeys([]);
1145
- clearFilters();
1146
- }
1147
- confirm();
1148
- }
1149
- }
1150
- );
1151
- }
1152
- break;
1153
- case "number":
1154
- if (!item.render) item.render = (value) => processValue(item, value);
1155
- if (typeof item.sorter === "undefined")
1156
- item.sorter = (a, b) => a[item.id] - b[item.id];
1157
- if (item.filterDropdown !== false) {
1158
- if (!item.onFilter && !props.faasData)
1159
- item.onFilter = (value, row) => {
1160
- if (value === null) return true;
1161
- if (isNil(row[item.id])) return false;
1162
- return value == row[item.id];
1163
- };
1164
- if (typeof item.filterDropdown === "undefined" && !item.filters)
1165
- item.filterDropdown = ({
1166
- setSelectedKeys,
1167
- confirm,
1168
- clearFilters
1169
- }) => /* @__PURE__ */ jsx(
1170
- Input.Search,
1171
- {
1172
- placeholder: `${theme2.common.search} ${item.title}`,
1173
- allowClear: true,
1174
- onSearch: (v) => {
1175
- if (v) {
1176
- setSelectedKeys([Number(v)]);
1177
- } else {
1178
- setSelectedKeys([]);
1179
- clearFilters();
1180
- }
1181
- confirm();
1182
- }
1183
- }
1184
- );
1185
- }
1186
- break;
1187
- case "number[]":
1188
- if (!item.render)
1189
- item.render = (value) => processValue(item, value).join(", ");
1190
- if (item.filterDropdown !== false) {
1191
- if (!item.onFilter && !props.faasData)
1192
- item.onFilter = (value, row) => {
1193
- if (value === null && (!row[item.id] || !row[item.id].length))
1194
- return true;
1195
- if (!row[item.id] || !row[item.id].length) return false;
1196
- return row[item.id].includes(Number(value));
1197
- };
1198
- if (typeof item.filterDropdown === "undefined" && !item.filters)
1199
- item.filterDropdown = ({
1200
- setSelectedKeys,
1201
- confirm,
1202
- clearFilters
1203
- }) => /* @__PURE__ */ jsx(
1204
- Input.Search,
1205
- {
1206
- placeholder: `${theme2.common.search} ${item.title}`,
1207
- allowClear: true,
1208
- onSearch: (v) => {
1209
- if (v) {
1210
- setSelectedKeys([Number(v)]);
1211
- } else {
1212
- setSelectedKeys([]);
1213
- clearFilters();
1214
- }
1215
- confirm();
1216
- }
1217
- }
1218
- );
1219
- }
1220
- break;
1221
- case "boolean":
1222
- if (!item.render)
1223
- item.render = (value) => isNil(value) ? /* @__PURE__ */ jsx(Blank, {}) : value ? /* @__PURE__ */ jsx(
1224
- CheckOutlined,
1225
- {
1226
- style: {
1227
- marginTop: "4px",
1228
- color: "#52c41a"
1229
- }
1230
- }
1231
- ) : /* @__PURE__ */ jsx(
1232
- CloseOutlined,
1233
- {
1234
- style: {
1235
- marginTop: "4px",
1236
- color: "#ff4d4f"
1237
- }
1238
- }
1239
- );
1240
- if (item.filterDropdown !== false) {
1241
- if (typeof item.filterDropdown === "undefined")
1242
- item.filterDropdown = ({
1243
- setSelectedKeys,
1244
- selectedKeys,
1245
- confirm
1246
- }) => /* @__PURE__ */ jsxs(
1247
- Radio.Group,
1248
- {
1249
- style: { padding: 8 },
1250
- buttonStyle: "solid",
1251
- value: JSON.stringify(selectedKeys[0]),
1252
- onChange: (e) => {
1253
- const Values = {
1254
- true: true,
1255
- false: false,
1256
- null: null
1257
- };
1258
- setSelectedKeys(
1259
- e.target.value ? [Values[e.target.value]] : []
1260
- );
1261
- confirm();
1262
- },
1263
- children: [
1264
- /* @__PURE__ */ jsx(Radio.Button, { children: theme2.common.all }),
1265
- /* @__PURE__ */ jsx(Radio.Button, { value: "true", children: /* @__PURE__ */ jsx(
1266
- CheckOutlined,
1267
- {
1268
- style: {
1269
- color: "#52c41a",
1270
- verticalAlign: "middle"
1271
- }
1272
- }
1273
- ) }),
1274
- /* @__PURE__ */ jsx(Radio.Button, { value: "false", children: /* @__PURE__ */ jsx(
1275
- CloseOutlined,
1276
- {
1277
- style: {
1278
- verticalAlign: "middle",
1279
- color: "#ff4d4f"
1280
- }
1281
- }
1282
- ) }),
1283
- /* @__PURE__ */ jsx(Radio.Button, { value: "null", children: theme2.common.blank })
1284
- ]
1285
- }
1286
- );
1287
- if (!item.onFilter && !props.faasData)
1288
- item.onFilter = (value, row) => {
1289
- switch (value) {
1290
- case true:
1291
- return !isNil(row[item.id]) && row[item.id] !== false;
1292
- case false:
1293
- return !isNil(row[item.id]) && !row[item.id];
1294
- default:
1295
- return isNil(row[item.id]);
1296
- }
1297
- };
1298
- }
1299
- break;
1300
- case "date":
1301
- if (!item.render) item.render = (value) => processValue(item, value);
1302
- if (typeof item.sorter === "undefined")
1303
- item.sorter = (a, b, order) => {
1304
- if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1305
- if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1306
- return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1307
- };
1308
- if (item.filterDropdown !== false) {
1309
- if (typeof item.filterDropdown === "undefined")
1310
- item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(
1311
- DatePicker.RangePicker,
1312
- {
1313
- onChange: (dates) => {
1314
- setSelectedKeys(
1315
- dates?.[0] && dates[1] ? [
1316
- [
1317
- dates[0].startOf("day").toISOString(),
1318
- dates[1].endOf("day").toISOString()
1319
- ]
1320
- ] : []
1321
- );
1322
- confirm();
1323
- }
1324
- }
1325
- );
1326
- if (!item.onFilter && !props.faasData)
1327
- item.onFilter = (value, row) => {
1328
- if (isNil(value[0])) return true;
1329
- if (isNil(row[item.id])) return false;
1330
- return dayjs2(row[item.id]) >= dayjs2(value[0]) && dayjs2(row[item.id]) <= dayjs2(value[1]);
1331
- };
1332
- }
1333
- break;
1334
- case "time":
1335
- item.width = item.width ?? 200;
1336
- if (!item.render) item.render = (value) => processValue(item, value);
1337
- if (typeof item.sorter === "undefined")
1338
- item.sorter = (a, b, order) => {
1339
- if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1340
- if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1341
- return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1342
- };
1343
- if (item.filterDropdown !== false) {
1344
- if (typeof item.filterDropdown === "undefined")
1345
- item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(
1346
- DatePicker.RangePicker,
1347
- {
1348
- onChange: (dates) => {
1349
- setSelectedKeys(
1350
- dates?.[0] && dates[1] ? [
1351
- [
1352
- dates[0].startOf("day").toISOString(),
1353
- dates[1].endOf("day").toISOString()
1354
- ]
1355
- ] : []
1356
- );
1357
- confirm();
1358
- }
1359
- }
1360
- );
1361
- if (!item.onFilter && !props.faasData)
1362
- item.onFilter = (value, row) => {
1363
- if (isNil(value[0])) return true;
1364
- if (isNil(row[item.id])) return false;
1365
- return dayjs2(row[item.id]) >= dayjs2(value[0]) && dayjs2(row[item.id]) <= dayjs2(value[1]);
1366
- };
1367
- }
1368
- break;
1369
- case "object":
1370
- if (!item.render)
1371
- item.render = (value) => /* @__PURE__ */ jsx(
1372
- Description,
1373
- {
1374
- items: item.object,
1375
- dataSource: value || {},
1376
- column: 1
1377
- }
1378
- );
1379
- break;
1380
- case "object[]":
1381
- if (!item.render)
1382
- item.render = (value) => /* @__PURE__ */ jsx(Fragment, { children: value.map((v, i) => /* @__PURE__ */ jsx(
1383
- Description,
1384
- {
1385
- items: item.object,
1386
- dataSource: v || [],
1387
- column: 1
1388
- },
1389
- i
1390
- )) });
1391
- break;
1392
- default:
1393
- if (!item.render) item.render = (value) => processValue(item, value);
1394
- if (item.filterDropdown !== false && !item.onFilter && !props.faasData)
1395
- item.onFilter = (value, row) => {
1396
- if (value === null && isNil(row[item.id])) return true;
1397
- return value === row[item.id];
1398
- };
1399
- break;
1400
- }
1401
- }
1402
- setColumns(items);
1403
- }, [props.items]);
1404
- useEffect(() => {
1405
- if (!props.dataSource || !columns) return;
1406
- for (const column of columns) {
1407
- if (column.optionsType === "auto" && !column.options && !column.filters) {
1408
- const options = uniqBy(props.dataSource, column.id).map(
1409
- (v) => ({
1410
- label: v[column.id],
1411
- value: v[column.id]
1412
- })
1413
- );
1414
- if (options.length)
1415
- setColumns((prev) => {
1416
- const newColumns = [...prev];
1417
- const index = newColumns.findIndex((item) => item.id === column.id);
1418
- newColumns[index].options = options;
1419
- generateFilterDropdown(newColumns[index]);
1420
- return newColumns;
1421
- });
1422
- }
1423
- }
1424
- }, [props.dataSource, columns]);
1425
- if (!columns) return null;
1426
- if (props.dataSource)
1427
- return /* @__PURE__ */ jsx(
1428
- Table$1,
1429
- {
1430
- ...props,
1431
- rowKey: props.rowKey || "id",
1432
- columns,
1433
- dataSource: props.dataSource
1434
- }
1435
- );
1436
- return /* @__PURE__ */ jsx(FaasDataWrapper, { ...props.faasData, children: /* @__PURE__ */ jsx(FaasDataTable, { props, columns }) });
1175
+ const [columns, setColumns] = useState();
1176
+ const { theme } = useConfigContext();
1177
+ const generateFilterDropdown = (item) => {
1178
+ if (item.filterDropdown && item.filterDropdown !== true) return;
1179
+ if (!item.options?.length) return;
1180
+ if (item.options.length < 11) {
1181
+ if (!item.filters) item.filters = item.options.map((o) => ({
1182
+ text: o.label,
1183
+ value: o.value
1184
+ }));
1185
+ return;
1186
+ }
1187
+ item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => /* @__PURE__ */ jsx("div", {
1188
+ style: {
1189
+ padding: 8,
1190
+ width: "200px"
1191
+ },
1192
+ onKeyDown: (e) => e.stopPropagation(),
1193
+ children: /* @__PURE__ */ jsx(Select, {
1194
+ options: item.options,
1195
+ allowClear: true,
1196
+ showSearch: true,
1197
+ style: { width: "100%" },
1198
+ placeholder: `${theme.common.search} ${item.title}`,
1199
+ value: selectedKeys,
1200
+ onChange: (v) => {
1201
+ setSelectedKeys(v?.length ? v : []);
1202
+ confirm();
1203
+ },
1204
+ mode: "multiple",
1205
+ filterOption: (input, option) => {
1206
+ if (!input || !option || !option.label) return true;
1207
+ input = input.trim();
1208
+ return option.value === input || option.label.toString().toLowerCase().includes(input.toLowerCase());
1209
+ }
1210
+ })
1211
+ });
1212
+ return item;
1213
+ };
1214
+ useEffect(() => {
1215
+ const items = cloneDeep(props.items).filter((item) => !(item.tableChildren === null || item.children === null || item.tableRender === null || item.render === null));
1216
+ for (const item of items) {
1217
+ if (!item.key) item.key = item.id;
1218
+ if (!item.dataIndex) item.dataIndex = item.id;
1219
+ const itemType = item.type ?? "string";
1220
+ item.title = item.title ?? idToTitle(item.id);
1221
+ item.type = itemType;
1222
+ if (item.options?.length) {
1223
+ item.options = transferOptions(item.options);
1224
+ item.filters = item.options.map((o) => ({
1225
+ text: o.label,
1226
+ value: o.value
1227
+ })).concat({
1228
+ text: /* @__PURE__ */ jsx(Blank, {}),
1229
+ value: null
1230
+ });
1231
+ generateFilterDropdown(item);
1232
+ }
1233
+ const children = item.tableChildren || item.children;
1234
+ if (children) {
1235
+ item.render = (value, values) => cloneUnionFaasItemElement(children, {
1236
+ scene: "table",
1237
+ value,
1238
+ values,
1239
+ index: 0
1240
+ });
1241
+ delete item.children;
1242
+ delete item.tableChildren;
1243
+ continue;
1244
+ }
1245
+ const render = item.tableRender || item.render;
1246
+ if (render) {
1247
+ item.render = (value, values) => render(value, values, 0, "table");
1248
+ delete item.tableRender;
1249
+ continue;
1250
+ }
1251
+ const extendType = props.extendTypes?.[itemType];
1252
+ if (extendType) {
1253
+ const extendChildren = extendType.children;
1254
+ if (extendChildren) item.render = (value, values) => cloneUnionFaasItemElement(extendChildren, {
1255
+ scene: "table",
1256
+ value,
1257
+ values,
1258
+ index: 0
1259
+ });
1260
+ else {
1261
+ const extendRender = extendType.render;
1262
+ if (extendRender) item.render = (value, values) => extendRender(value, values, 0, "table");
1263
+ else throw Error(`${itemType} requires children or render`);
1264
+ }
1265
+ continue;
1266
+ }
1267
+ switch (itemType) {
1268
+ case "string":
1269
+ if (!item.render) item.render = (value) => processValue(item, value);
1270
+ if (item.filterDropdown !== false) {
1271
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1272
+ if (!value || isNil(value)) return true;
1273
+ if (isNil(row[item.id])) return false;
1274
+ return row[item.id].trim().toLowerCase().includes(value.trim().toLowerCase());
1275
+ };
1276
+ if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1277
+ placeholder: `${theme.common.search} ${item.title}`,
1278
+ allowClear: true,
1279
+ onSearch: (v) => {
1280
+ if (v) setSelectedKeys([v]);
1281
+ else {
1282
+ setSelectedKeys([]);
1283
+ clearFilters?.();
1284
+ }
1285
+ confirm();
1286
+ }
1287
+ });
1288
+ }
1289
+ break;
1290
+ case "string[]":
1291
+ if (!item.render) item.render = (value) => processValue(item, value);
1292
+ if (item.filterDropdown !== false) {
1293
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1294
+ if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1295
+ if (!row[item.id] || !row[item.id].length || !value) return false;
1296
+ return row[item.id].some((v) => v.trim().toLowerCase().includes(value.trim().toLowerCase()));
1297
+ };
1298
+ if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1299
+ placeholder: `${theme.common.search} ${item.title}`,
1300
+ allowClear: true,
1301
+ onSearch: (v) => {
1302
+ if (v) setSelectedKeys([v]);
1303
+ else {
1304
+ setSelectedKeys([]);
1305
+ clearFilters?.();
1306
+ }
1307
+ confirm();
1308
+ }
1309
+ });
1310
+ }
1311
+ break;
1312
+ case "number":
1313
+ if (!item.render) item.render = (value) => processValue(item, value);
1314
+ if (typeof item.sorter === "undefined") item.sorter = (a, b) => a[item.id] - b[item.id];
1315
+ if (item.filterDropdown !== false) {
1316
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1317
+ if (value === null) return true;
1318
+ if (isNil(row[item.id])) return false;
1319
+ return value == row[item.id];
1320
+ };
1321
+ if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1322
+ placeholder: `${theme.common.search} ${item.title}`,
1323
+ allowClear: true,
1324
+ onSearch: (v) => {
1325
+ if (v) setSelectedKeys([Number(v)]);
1326
+ else {
1327
+ setSelectedKeys([]);
1328
+ clearFilters?.();
1329
+ }
1330
+ confirm();
1331
+ }
1332
+ });
1333
+ }
1334
+ break;
1335
+ case "number[]":
1336
+ if (!item.render) item.render = (value) => processValue(item, value).join(", ");
1337
+ if (item.filterDropdown !== false) {
1338
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1339
+ if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1340
+ if (!row[item.id] || !row[item.id].length) return false;
1341
+ return row[item.id].includes(Number(value));
1342
+ };
1343
+ if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1344
+ placeholder: `${theme.common.search} ${item.title}`,
1345
+ allowClear: true,
1346
+ onSearch: (v) => {
1347
+ if (v) setSelectedKeys([Number(v)]);
1348
+ else {
1349
+ setSelectedKeys([]);
1350
+ clearFilters?.();
1351
+ }
1352
+ confirm();
1353
+ }
1354
+ });
1355
+ }
1356
+ break;
1357
+ case "boolean":
1358
+ if (!item.render) item.render = (value) => isNil(value) ? /* @__PURE__ */ jsx(Blank, {}) : value ? /* @__PURE__ */ jsx(CheckOutlined, { style: {
1359
+ marginTop: "4px",
1360
+ color: "#52c41a"
1361
+ } }) : /* @__PURE__ */ jsx(CloseOutlined, { style: {
1362
+ marginTop: "4px",
1363
+ color: "#ff4d4f"
1364
+ } });
1365
+ if (item.filterDropdown !== false) {
1366
+ if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => /* @__PURE__ */ jsxs(Radio.Group, {
1367
+ style: { padding: 8 },
1368
+ buttonStyle: "solid",
1369
+ value: JSON.stringify(selectedKeys[0]),
1370
+ onChange: (e) => {
1371
+ setSelectedKeys(e.target.value ? [{
1372
+ true: true,
1373
+ false: false,
1374
+ null: null
1375
+ }[e.target.value]] : []);
1376
+ confirm();
1377
+ },
1378
+ children: [
1379
+ /* @__PURE__ */ jsx(Radio.Button, { children: theme.common.all }),
1380
+ /* @__PURE__ */ jsx(Radio.Button, {
1381
+ value: "true",
1382
+ children: /* @__PURE__ */ jsx(CheckOutlined, { style: {
1383
+ color: "#52c41a",
1384
+ verticalAlign: "middle"
1385
+ } })
1386
+ }),
1387
+ /* @__PURE__ */ jsx(Radio.Button, {
1388
+ value: "false",
1389
+ children: /* @__PURE__ */ jsx(CloseOutlined, { style: {
1390
+ verticalAlign: "middle",
1391
+ color: "#ff4d4f"
1392
+ } })
1393
+ }),
1394
+ /* @__PURE__ */ jsx(Radio.Button, {
1395
+ value: "null",
1396
+ children: theme.common.blank
1397
+ })
1398
+ ]
1399
+ });
1400
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1401
+ switch (value) {
1402
+ case true: return !isNil(row[item.id]) && row[item.id] !== false;
1403
+ case false: return !isNil(row[item.id]) && !row[item.id];
1404
+ default: return isNil(row[item.id]);
1405
+ }
1406
+ };
1407
+ }
1408
+ break;
1409
+ case "date":
1410
+ if (!item.render) item.render = (value) => processValue(item, value);
1411
+ if (typeof item.sorter === "undefined") item.sorter = (a, b, order) => {
1412
+ if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1413
+ if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1414
+ return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1415
+ };
1416
+ if (item.filterDropdown !== false) {
1417
+ if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(DatePicker.RangePicker, { onChange: (dates) => {
1418
+ setSelectedKeys(dates?.[0] && dates[1] ? [[dates[0].startOf("day").toISOString(), dates[1].endOf("day").toISOString()]] : []);
1419
+ confirm();
1420
+ } });
1421
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1422
+ if (isNil(value[0])) return true;
1423
+ if (isNil(row[item.id])) return false;
1424
+ return dayjs(row[item.id]) >= dayjs(value[0]) && dayjs(row[item.id]) <= dayjs(value[1]);
1425
+ };
1426
+ }
1427
+ break;
1428
+ case "time":
1429
+ item.width = item.width ?? 200;
1430
+ if (!item.render) item.render = (value) => processValue(item, value);
1431
+ if (typeof item.sorter === "undefined") item.sorter = (a, b, order) => {
1432
+ if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1433
+ if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1434
+ return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1435
+ };
1436
+ if (item.filterDropdown !== false) {
1437
+ if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(DatePicker.RangePicker, { onChange: (dates) => {
1438
+ setSelectedKeys(dates?.[0] && dates[1] ? [[dates[0].startOf("day").toISOString(), dates[1].endOf("day").toISOString()]] : []);
1439
+ confirm();
1440
+ } });
1441
+ if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1442
+ if (isNil(value[0])) return true;
1443
+ if (isNil(row[item.id])) return false;
1444
+ return dayjs(row[item.id]) >= dayjs(value[0]) && dayjs(row[item.id]) <= dayjs(value[1]);
1445
+ };
1446
+ }
1447
+ break;
1448
+ case "object":
1449
+ if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Description, {
1450
+ items: item.object || [],
1451
+ dataSource: value || {},
1452
+ column: 1
1453
+ });
1454
+ break;
1455
+ case "object[]":
1456
+ if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Fragment, { children: value.map((v, i) => /* @__PURE__ */ jsx(Description, {
1457
+ items: item.object || [],
1458
+ dataSource: v || [],
1459
+ column: 1
1460
+ }, i)) });
1461
+ break;
1462
+ default:
1463
+ if (!item.render) item.render = (value) => processValue(item, value);
1464
+ if (item.filterDropdown !== false && !item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1465
+ if (value === null && isNil(row[item.id])) return true;
1466
+ return value === row[item.id];
1467
+ };
1468
+ break;
1469
+ }
1470
+ }
1471
+ setColumns(items);
1472
+ }, [props.items]);
1473
+ useEffect(() => {
1474
+ if (!props.dataSource || !columns) return;
1475
+ for (const column of columns) if (column.optionsType === "auto" && !column.options && !column.filters) {
1476
+ const options = uniqBy(props.dataSource, column.id).map((v) => ({
1477
+ label: v[column.id],
1478
+ value: v[column.id]
1479
+ }));
1480
+ if (options.length) setColumns((prev) => {
1481
+ const newColumns = [...prev || []];
1482
+ const index = newColumns.findIndex((item) => item.id === column.id);
1483
+ if (index < 0) return newColumns;
1484
+ newColumns[index].options = options;
1485
+ generateFilterDropdown(newColumns[index]);
1486
+ return newColumns;
1487
+ });
1488
+ }
1489
+ }, [props.dataSource, columns]);
1490
+ if (!columns) return null;
1491
+ if (props.dataSource) return /* @__PURE__ */ jsx(Table$1, {
1492
+ ...props,
1493
+ rowKey: props.rowKey || "id",
1494
+ columns,
1495
+ dataSource: props.dataSource
1496
+ });
1497
+ if (!props.faasData) return /* @__PURE__ */ jsx(FaasDataTable, {
1498
+ props,
1499
+ columns
1500
+ });
1501
+ return /* @__PURE__ */ jsx(FaasDataWrapper, {
1502
+ ...props.faasData,
1503
+ children: /* @__PURE__ */ jsx(FaasDataTable, {
1504
+ props,
1505
+ columns
1506
+ })
1507
+ });
1437
1508
  }
1438
- function FaasDataTable({
1439
- props,
1440
- columns,
1441
- data,
1442
- params,
1443
- reload,
1444
- loading
1445
- }) {
1446
- const [currentColumns, setCurrentColumns] = useState(columns);
1447
- useEffect(() => {
1448
- if (!data || Array.isArray(data)) return;
1449
- setCurrentColumns((prev) => {
1450
- const newColumns = [...prev];
1451
- for (const column of newColumns) {
1452
- if (data.options?.[column.id]) {
1453
- column.options = transferOptions(data.options[column.id]);
1454
- column.filters = column.options.map((v) => ({
1455
- text: v.label,
1456
- value: v.value
1457
- })).concat({
1458
- text: /* @__PURE__ */ jsx(Blank, {}),
1459
- value: null
1460
- });
1461
- column.render = (value) => processValue(column, value);
1462
- if (column.filterDropdown) delete column.filterDropdown;
1463
- continue;
1464
- }
1465
- if (column.optionsType === "auto" && !column.options && !column.filters) {
1466
- const filters = uniqBy(props.dataSource, column.id).map(
1467
- (v) => ({
1468
- text: v[column.id],
1469
- value: v[column.id]
1470
- })
1471
- );
1472
- if (filters.length)
1473
- column.filters = filters.concat({
1474
- text: /* @__PURE__ */ jsx(Blank, {}),
1475
- value: null
1476
- });
1477
- }
1478
- }
1479
- return newColumns;
1480
- });
1481
- }, [data, props.dataSource]);
1482
- if (!data)
1483
- return /* @__PURE__ */ jsx(
1484
- Table$1,
1485
- {
1486
- ...props,
1487
- loading,
1488
- rowKey: props.rowKey || "id",
1489
- columns: currentColumns,
1490
- dataSource: []
1491
- }
1492
- );
1493
- if (Array.isArray(data))
1494
- return /* @__PURE__ */ jsx(
1495
- Table$1,
1496
- {
1497
- ...props,
1498
- loading,
1499
- rowKey: props.rowKey || "id",
1500
- columns: currentColumns,
1501
- dataSource: data
1502
- }
1503
- );
1504
- return /* @__PURE__ */ jsx(
1505
- Table$1,
1506
- {
1507
- ...props,
1508
- loading,
1509
- rowKey: props.rowKey || "id",
1510
- columns: currentColumns,
1511
- dataSource: data.rows,
1512
- pagination: props.pagination === false ? false : {
1513
- ...props.pagination || /* @__PURE__ */ Object.create(null),
1514
- ...data.pagination || /* @__PURE__ */ Object.create(null)
1515
- },
1516
- onChange: (pagination, filters, sorter, extra) => {
1517
- if (props.onChange) {
1518
- const processed = props.onChange(pagination, filters, sorter, extra);
1519
- reload({
1520
- ...params || /* @__PURE__ */ Object.create(null),
1521
- pagination: processed.pagination,
1522
- filters: processed.filters,
1523
- sorter: processed.sorter,
1524
- extra: processed.extra
1525
- });
1526
- return;
1527
- }
1528
- reload({
1529
- ...params || /* @__PURE__ */ Object.create(null),
1530
- pagination,
1531
- filters,
1532
- sorter
1533
- });
1534
- }
1535
- }
1536
- );
1509
+ function FaasDataTable({ props, columns, data, params, reload, loading }) {
1510
+ const [currentColumns, setCurrentColumns] = useState(columns);
1511
+ useEffect(() => {
1512
+ if (!data || Array.isArray(data)) return;
1513
+ setCurrentColumns((prev) => {
1514
+ const newColumns = [...prev];
1515
+ for (const column of newColumns) {
1516
+ if (data.options?.[column.id]) {
1517
+ column.options = transferOptions(data.options[column.id]);
1518
+ column.filters = column.options.map((v) => ({
1519
+ text: v.label,
1520
+ value: v.value
1521
+ })).concat({
1522
+ text: /* @__PURE__ */ jsx(Blank, {}),
1523
+ value: null
1524
+ });
1525
+ column.render = (value) => processValue(column, value);
1526
+ if (column.filterDropdown) delete column.filterDropdown;
1527
+ continue;
1528
+ }
1529
+ if (column.optionsType === "auto" && !column.options && !column.filters) {
1530
+ const filters = uniqBy(props.dataSource, column.id).map((v) => ({
1531
+ text: v[column.id],
1532
+ value: v[column.id]
1533
+ }));
1534
+ if (filters.length) column.filters = filters.concat({
1535
+ text: /* @__PURE__ */ jsx(Blank, {}),
1536
+ value: null
1537
+ });
1538
+ }
1539
+ }
1540
+ return newColumns;
1541
+ });
1542
+ }, [data, props.dataSource]);
1543
+ if (!data) return /* @__PURE__ */ jsx(Table$1, {
1544
+ ...props,
1545
+ ...typeof loading === "undefined" ? {} : { loading },
1546
+ rowKey: props.rowKey || "id",
1547
+ columns: currentColumns,
1548
+ dataSource: []
1549
+ });
1550
+ if (Array.isArray(data)) return /* @__PURE__ */ jsx(Table$1, {
1551
+ ...props,
1552
+ ...typeof loading === "undefined" ? {} : { loading },
1553
+ rowKey: props.rowKey || "id",
1554
+ columns: currentColumns,
1555
+ dataSource: data
1556
+ });
1557
+ return /* @__PURE__ */ jsx(Table$1, {
1558
+ ...props,
1559
+ ...typeof loading === "undefined" ? {} : { loading },
1560
+ rowKey: props.rowKey || "id",
1561
+ columns: currentColumns,
1562
+ dataSource: data.rows,
1563
+ pagination: props.pagination === false ? false : {
1564
+ ...props.pagination || Object.create(null),
1565
+ ...data.pagination || Object.create(null)
1566
+ },
1567
+ onChange: (pagination, filters, sorter, extra) => {
1568
+ if (!reload) return;
1569
+ if (props.onChange) {
1570
+ const processed = props.onChange(pagination, filters, sorter, extra);
1571
+ reload({
1572
+ ...params || Object.create(null),
1573
+ pagination: processed.pagination,
1574
+ filters: processed.filters,
1575
+ sorter: processed.sorter,
1576
+ extra: processed.extra
1577
+ });
1578
+ return;
1579
+ }
1580
+ reload({
1581
+ ...params || Object.create(null),
1582
+ pagination,
1583
+ filters,
1584
+ sorter
1585
+ });
1586
+ }
1587
+ });
1537
1588
  }
1589
+
1590
+ //#endregion
1591
+ //#region src/Tabs.tsx
1592
+ /**
1593
+ * Tabs component with Ant Design & FaasJS
1594
+ *
1595
+ * - Based on [Ant Design Tabs](https://ant.design/components/tabs/).
1596
+ * - Support auto skip null/false tab item.
1597
+ * - Support `id` as key and label.
1598
+ *
1599
+ * @example
1600
+ * ```tsx
1601
+ * import { Tabs } from '@faasjs/ant-design'
1602
+ *
1603
+ * <Tabs
1604
+ * items={[
1605
+ * {
1606
+ * id: 'id',
1607
+ * children: 'content',
1608
+ * },
1609
+ * 1 === 0 && {
1610
+ * id: 'hidden',
1611
+ * children: 'content',
1612
+ * },
1613
+ * ]}
1614
+ * />
1615
+ * ```
1616
+ */
1538
1617
  function Tabs(props) {
1539
- return /* @__PURE__ */ jsx(
1540
- Tabs$1,
1541
- {
1542
- ...props,
1543
- items: props.items.filter(Boolean).map((i) => ({
1544
- ...i,
1545
- key: i.key ?? i.id,
1546
- label: i.label ?? i.title ?? i.id
1547
- }))
1548
- }
1549
- );
1618
+ return /* @__PURE__ */ jsx(Tabs$1, {
1619
+ ...props,
1620
+ items: props.items.filter(Boolean).map((i) => ({
1621
+ ...i,
1622
+ key: i.key ?? i.id,
1623
+ label: i.label ?? i.title ?? i.id
1624
+ }))
1625
+ });
1550
1626
  }
1627
+
1628
+ //#endregion
1629
+ //#region src/Title.tsx
1630
+ /**
1631
+ * Title is used to change the title of the page
1632
+ *
1633
+ * Return null by default.
1634
+ *
1635
+ * ```tsx
1636
+ * // return null
1637
+ * <Title title='hi' /> // => change the document.title to 'hi'
1638
+ * <Title title={['a', 'b']} /> // => change the document.title to 'a - b'
1639
+ *
1640
+ * // return h1
1641
+ * <Title title='hi' h1 /> // => <h1>hi</h1>
1642
+ * <Title title={['a', 'b']} h1 /> // => <h1>a</h1>
1643
+ *
1644
+ * // return children
1645
+ * <Title title='hi'><CustomTitle /></Title> // => <CustomTitle />
1646
+ * ```
1647
+ */
1551
1648
  function Title(props) {
1552
- const { theme: theme2 } = useConfigContext();
1553
- useEffect(() => {
1554
- const title = Array.isArray(props.title) ? props.title : [props.title];
1555
- document.title = title.concat(props.suffix || theme2.Title.suffix).filter((t) => !!t).join(props.separator || theme2.Title.separator);
1556
- }, [props, theme2.Title]);
1557
- if (props.h1) {
1558
- if (typeof props.h1 === "boolean")
1559
- return /* @__PURE__ */ jsx("h1", { children: Array.isArray(props.title) ? props.title[0] : props.title });
1560
- return /* @__PURE__ */ jsx("h1", { className: props.h1.className, style: props.h1.style, children: Array.isArray(props.title) ? props.title[0] : props.title });
1561
- }
1562
- if (props.plain)
1563
- return /* @__PURE__ */ jsx(Fragment, { children: Array.isArray(props.title) ? props.title[0] : props.title });
1564
- if (props.children)
1565
- return cloneElement(props.children, { title: props.title });
1566
- return null;
1649
+ const { theme } = useConfigContext();
1650
+ useEffect(() => {
1651
+ const title = Array.isArray(props.title) ? props.title : [props.title];
1652
+ document.title = title.concat(props.suffix || theme.Title.suffix).filter((t) => !!t).join(props.separator || theme.Title.separator);
1653
+ }, [props, theme.Title]);
1654
+ if (props.h1) {
1655
+ if (typeof props.h1 === "boolean") return /* @__PURE__ */ jsx("h1", { children: Array.isArray(props.title) ? props.title[0] : props.title });
1656
+ return /* @__PURE__ */ jsx("h1", {
1657
+ className: props.h1.className,
1658
+ style: props.h1.style,
1659
+ children: Array.isArray(props.title) ? props.title[0] : props.title
1660
+ });
1661
+ }
1662
+ if (props.plain) return /* @__PURE__ */ jsx(Fragment, { children: Array.isArray(props.title) ? props.title[0] : props.title });
1663
+ if (props.children) return cloneElement(props.children, { title: props.title });
1664
+ return null;
1567
1665
  }
1666
+
1667
+ //#endregion
1668
+ //#region src/useThemeToken.ts
1669
+ /**
1670
+ * Hook to retrieve the theme token from the Ant Design theme configuration.
1671
+ *
1672
+ * This function uses the `theme.useToken` method to get the current theme configuration
1673
+ * and returns the `token` property from the configuration.
1674
+ *
1675
+ * @returns {GlobalToken} The theme token from the Ant Design theme configuration.
1676
+ */
1568
1677
  function useThemeToken() {
1569
- const config = theme.useToken();
1570
- return config.token;
1678
+ return theme.useToken().token;
1571
1679
  }
1572
1680
 
1573
- export { App, Blank, ConfigContext, ConfigProvider, Description, ErrorBoundary, FaasDataWrapper, Form, FormItem, Link, Loading, PageNotFound, Routes, Table, Tabs, Title, cloneUnionFaasItemElement, idToTitle, transferOptions, transferValue, useApp, useConfigContext, useDrawer, useModal, useThemeToken, withFaasData };
1681
+ //#endregion
1682
+ export { App, Blank, ConfigContext, ConfigProvider, Description, Drawer, ErrorBoundary, FaasDataWrapper, FaasReactClient, Form, FormItem, Link, Loading, Modal, PageNotFound, Routes, Table, Tabs, Title, cloneUnionFaasItemElement, faas, idToTitle, lazy, transferOptions, transferValue, useApp, useConfigContext, useDrawer, useFaas, useModal, useThemeToken, withFaasData };