@faasjs/ant-design 8.0.0-beta.1 → 8.0.0-beta.10

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