@fairys/valtio-form-basic 0.0.8
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/README.md +10 -0
- package/esm/form/form.d.ts +66 -0
- package/esm/form/form.item.d.ts +150 -0
- package/esm/form/form.item.js +163 -0
- package/esm/form/form.js +17 -0
- package/esm/form/instance/index.d.ts +64 -0
- package/esm/form/instance/index.js +140 -0
- package/esm/form/layout.d.ts +2728 -0
- package/esm/form/layout.js +125 -0
- package/esm/index.d.ts +4 -0
- package/esm/index.js +4 -0
- package/esm/interface.d.ts +4 -0
- package/esm/interface.js +0 -0
- package/esm/styles/index.css +266 -0
- package/lib/index.js +87 -0
- package/package.json +38 -0
- package/src/form/form.item.tsx +382 -0
- package/src/form/form.tsx +68 -0
- package/src/form/instance/index.ts +219 -0
- package/src/form/layout.tsx +321 -0
- package/src/index.tsx +4 -0
- package/src/interface.ts +4 -0
- package/src/styles/index.css +41 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, useRef } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { proxy, useSnapshot } from 'valtio';
|
|
4
|
+
|
|
5
|
+
export interface FairysValtioFormLayoutContextOptions {
|
|
6
|
+
/**列数据*/
|
|
7
|
+
colCount?: number;
|
|
8
|
+
/**规则校验失败错误提示位置*/
|
|
9
|
+
errorLayout?: 'left-bottom' | 'right-bottom' | 'top-right' | 'top-left';
|
|
10
|
+
/**
|
|
11
|
+
* label显示模式
|
|
12
|
+
* @platform taro 支持 between
|
|
13
|
+
*/
|
|
14
|
+
labelMode?: 'left' | 'top' | 'between';
|
|
15
|
+
/**表单项 className*/
|
|
16
|
+
formItemClassName?: string;
|
|
17
|
+
/**表单项 style*/
|
|
18
|
+
formItemStyle?: React.CSSProperties;
|
|
19
|
+
/**表单项 label className*/
|
|
20
|
+
formItemLabelClassName?: string;
|
|
21
|
+
/**表单项 label style*/
|
|
22
|
+
formItemLabelStyle?: React.CSSProperties;
|
|
23
|
+
/**表单项 body className*/
|
|
24
|
+
formItemBodyClassName?: string;
|
|
25
|
+
/**表单项 body style*/
|
|
26
|
+
formItemBodyStyle?: React.CSSProperties;
|
|
27
|
+
/**
|
|
28
|
+
* 底部边框类型
|
|
29
|
+
*/
|
|
30
|
+
borderedType?: 'bottom' | 'body';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayoutContextOptions {
|
|
34
|
+
/**
|
|
35
|
+
* @description gap 属性是用来设置网格行与列之间的间隙,该属性是row-gap and column-gap的简写形式。
|
|
36
|
+
*/
|
|
37
|
+
gap?: string | number;
|
|
38
|
+
/**标题*/
|
|
39
|
+
title?: React.ReactNode;
|
|
40
|
+
/**额外内容*/
|
|
41
|
+
extra?: React.ReactNode;
|
|
42
|
+
/**内容*/
|
|
43
|
+
children?: React.ReactNode;
|
|
44
|
+
/**是否占据整行*/
|
|
45
|
+
isAllColSpan?: boolean;
|
|
46
|
+
className?: string;
|
|
47
|
+
style?: React.CSSProperties;
|
|
48
|
+
/**头部ClassName*/
|
|
49
|
+
headerClassName?: string;
|
|
50
|
+
/**头部样式*/
|
|
51
|
+
headerStyle?: React.CSSProperties;
|
|
52
|
+
/**内容ClassName*/
|
|
53
|
+
bodyClassName?: string;
|
|
54
|
+
/**内容样式*/
|
|
55
|
+
bodyStyle?: React.CSSProperties;
|
|
56
|
+
/**是否边框*/
|
|
57
|
+
bordered?: boolean;
|
|
58
|
+
/**显示阴影*/
|
|
59
|
+
boxShadow?: boolean;
|
|
60
|
+
/**最后一个是否显示底部边框*/
|
|
61
|
+
lastItemBordered?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class FairysValtioFormLayoutInstance {
|
|
65
|
+
state = proxy<FairysValtioFormLayoutContextOptions>({
|
|
66
|
+
colCount: 1,
|
|
67
|
+
errorLayout: 'right-bottom',
|
|
68
|
+
labelMode: 'between',
|
|
69
|
+
borderedType: 'bottom',
|
|
70
|
+
});
|
|
71
|
+
updated = (options: FairysValtioFormLayoutContextOptions = {}) => {
|
|
72
|
+
const keys = Object.keys(options);
|
|
73
|
+
for (let index = 0; index < keys.length; index++) {
|
|
74
|
+
const key = keys[index];
|
|
75
|
+
this.state[key] = options[key];
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const useFairysValtioFormLayoutInstance = (instance?: FairysValtioFormLayoutInstance) => {
|
|
81
|
+
const ref = useRef<FairysValtioFormLayoutInstance>();
|
|
82
|
+
if (!ref.current) {
|
|
83
|
+
if (instance) {
|
|
84
|
+
ref.current = instance;
|
|
85
|
+
} else {
|
|
86
|
+
ref.current = new FairysValtioFormLayoutInstance();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return ref.current;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const FairysValtioFormLayoutContext = createContext<FairysValtioFormLayoutInstance>(
|
|
93
|
+
new FairysValtioFormLayoutInstance(),
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
export const useFairysValtioFormLayoutContext = () => {
|
|
97
|
+
const instance = useContext(FairysValtioFormLayoutContext);
|
|
98
|
+
const state = useSnapshot(instance.state);
|
|
99
|
+
return [state, instance] as const;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 布局属性处理
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
*
|
|
107
|
+
* ```tsx
|
|
108
|
+
import { Fragment } from 'react'
|
|
109
|
+
import { useFairysValtioFormLayoutAttrs, FairysValtioFormLayoutContext } from "@fairys/valtio-form"
|
|
110
|
+
import type { FairysValtioFormLayoutAttrsProps } from "@fairys/valtio-form"
|
|
111
|
+
|
|
112
|
+
export interface LayoutProps extends FairysValtioFormLayoutAttrsProps {}
|
|
113
|
+
|
|
114
|
+
export const Layout = (props: LayoutProps) => {
|
|
115
|
+
const { children, title, extra } = props
|
|
116
|
+
const {
|
|
117
|
+
formLayoutInstance,
|
|
118
|
+
layoutName, layoutStyle,
|
|
119
|
+
headerName, headerStyle,
|
|
120
|
+
headerTitleName, headerExtraName,
|
|
121
|
+
bodyName, bodyStyle
|
|
122
|
+
} = useFairysValtioFormLayoutAttrs(props)
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<FairysValtioFormLayoutContext.Provider value={formLayoutInstance}>
|
|
126
|
+
<div className={layoutName} style={layoutStyle}>
|
|
127
|
+
<div>
|
|
128
|
+
{title || extra ? (
|
|
129
|
+
<div style={headerStyle} className={headerName}>
|
|
130
|
+
<div className={headerTitleName}>{title}</div>
|
|
131
|
+
<div className={headerExtraName}>{extra}</div>
|
|
132
|
+
</div>
|
|
133
|
+
) : (
|
|
134
|
+
<Fragment />
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
<div className={bodyName} style={bodyStyle}>
|
|
138
|
+
{children}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</FairysValtioFormLayoutContext.Provider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
*
|
|
146
|
+
*/
|
|
147
|
+
export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttrsProps) {
|
|
148
|
+
const formLayoutInstance = useFairysValtioFormLayoutInstance();
|
|
149
|
+
const [state] = useFairysValtioFormLayoutContext();
|
|
150
|
+
const parent_colCount = state.colCount || 1;
|
|
151
|
+
const parent_errorLayout = state.errorLayout || 'right-bottom';
|
|
152
|
+
const parent_labelMode = state.labelMode || 'between';
|
|
153
|
+
const parent_formItemClassName = state.formItemClassName;
|
|
154
|
+
const parent_formItemStyle = state.formItemStyle;
|
|
155
|
+
const parent_formItemLabelClassName = state.formItemLabelClassName;
|
|
156
|
+
const parent_formItemLabelStyle = state.formItemLabelStyle;
|
|
157
|
+
const parent_formItemBodyClassName = state.formItemBodyClassName;
|
|
158
|
+
const parent_formItemBodyStyle = state.formItemBodyStyle;
|
|
159
|
+
const parent_borderedType = state.borderedType || 'bottom';
|
|
160
|
+
|
|
161
|
+
const {
|
|
162
|
+
colCount = parent_colCount,
|
|
163
|
+
errorLayout = parent_errorLayout,
|
|
164
|
+
labelMode = parent_labelMode,
|
|
165
|
+
formItemClassName = parent_formItemClassName,
|
|
166
|
+
formItemStyle = parent_formItemStyle,
|
|
167
|
+
formItemLabelClassName = parent_formItemLabelClassName,
|
|
168
|
+
formItemLabelStyle = parent_formItemLabelStyle,
|
|
169
|
+
formItemBodyClassName = parent_formItemBodyClassName,
|
|
170
|
+
formItemBodyStyle = parent_formItemBodyStyle,
|
|
171
|
+
borderedType = parent_borderedType,
|
|
172
|
+
lastItemBordered = true,
|
|
173
|
+
gap,
|
|
174
|
+
isAllColSpan = false,
|
|
175
|
+
className,
|
|
176
|
+
style,
|
|
177
|
+
headerClassName,
|
|
178
|
+
headerStyle,
|
|
179
|
+
bodyClassName,
|
|
180
|
+
bodyStyle,
|
|
181
|
+
bordered,
|
|
182
|
+
boxShadow,
|
|
183
|
+
} = props;
|
|
184
|
+
|
|
185
|
+
useMemo(
|
|
186
|
+
() =>
|
|
187
|
+
formLayoutInstance.updated({
|
|
188
|
+
colCount,
|
|
189
|
+
errorLayout,
|
|
190
|
+
labelMode,
|
|
191
|
+
formItemClassName,
|
|
192
|
+
formItemStyle,
|
|
193
|
+
formItemLabelClassName,
|
|
194
|
+
formItemLabelStyle,
|
|
195
|
+
formItemBodyClassName,
|
|
196
|
+
formItemBodyStyle,
|
|
197
|
+
borderedType,
|
|
198
|
+
}),
|
|
199
|
+
[
|
|
200
|
+
colCount,
|
|
201
|
+
errorLayout,
|
|
202
|
+
labelMode,
|
|
203
|
+
formItemClassName,
|
|
204
|
+
formItemStyle,
|
|
205
|
+
formItemLabelClassName,
|
|
206
|
+
formItemLabelStyle,
|
|
207
|
+
formItemBodyClassName,
|
|
208
|
+
formItemBodyStyle,
|
|
209
|
+
borderedType,
|
|
210
|
+
],
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
const layoutCls = useMemo(
|
|
214
|
+
() =>
|
|
215
|
+
clsx(
|
|
216
|
+
`fairys-valtio-form-layout fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-md`,
|
|
217
|
+
{
|
|
218
|
+
'fairys-valtio-form-layout-all-col-span': isAllColSpan,
|
|
219
|
+
'fairys-taro-form-valtio-layout-box-shadow': boxShadow,
|
|
220
|
+
'fairystaroform__border fairystaroform__border-solid fairystaroform__border-gray-200': bordered,
|
|
221
|
+
'fairys-valtio-form-layout-last-item-no-border': !lastItemBordered,
|
|
222
|
+
},
|
|
223
|
+
className,
|
|
224
|
+
),
|
|
225
|
+
[className, isAllColSpan, bordered, boxShadow, lastItemBordered],
|
|
226
|
+
);
|
|
227
|
+
const headerCls = useMemo(
|
|
228
|
+
() =>
|
|
229
|
+
clsx(
|
|
230
|
+
`fairys-valtio-form-layout-header fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-[12px] fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border`,
|
|
231
|
+
{
|
|
232
|
+
'fairystaroform__px-[8px]': bordered || boxShadow,
|
|
233
|
+
'fairystaroform__px-[4px]': !bordered && !boxShadow,
|
|
234
|
+
},
|
|
235
|
+
headerClassName,
|
|
236
|
+
),
|
|
237
|
+
[headerClassName, bordered, boxShadow],
|
|
238
|
+
);
|
|
239
|
+
const headerTitleCls = useMemo(
|
|
240
|
+
() =>
|
|
241
|
+
clsx(
|
|
242
|
+
`fairys-valtio-form-layout-header-title fairystaroform__text-[14px] fairystaroform__font-bold fairystaroform__box-border`,
|
|
243
|
+
),
|
|
244
|
+
[],
|
|
245
|
+
);
|
|
246
|
+
const headerExtraCls = useMemo(() => clsx(`fairys-valtio-form-layout-header-extra fairystaroform__box-border`), []);
|
|
247
|
+
|
|
248
|
+
const body_base = useMemo(() => {
|
|
249
|
+
return clsx(
|
|
250
|
+
'fairys-valtio-form-layout-body fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__gap-[2px] fairystaroform__box-border',
|
|
251
|
+
bodyClassName,
|
|
252
|
+
);
|
|
253
|
+
}, [bodyClassName]);
|
|
254
|
+
|
|
255
|
+
const styleBase = useMemo(() => {
|
|
256
|
+
const css: React.CSSProperties = {};
|
|
257
|
+
if (typeof gap === 'string') {
|
|
258
|
+
css.gap = gap;
|
|
259
|
+
}
|
|
260
|
+
if (typeof gap === 'number') {
|
|
261
|
+
css.gap = `${gap}px`;
|
|
262
|
+
}
|
|
263
|
+
if (colCount) {
|
|
264
|
+
css.gridTemplateColumns = `repeat(${colCount}, auto)`;
|
|
265
|
+
}
|
|
266
|
+
return css;
|
|
267
|
+
}, [colCount, gap]);
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
colCount,
|
|
271
|
+
errorLayout,
|
|
272
|
+
labelMode,
|
|
273
|
+
borderedType,
|
|
274
|
+
formLayoutInstance,
|
|
275
|
+
//======================
|
|
276
|
+
layoutName: layoutCls,
|
|
277
|
+
layoutStyle: style,
|
|
278
|
+
//======================
|
|
279
|
+
headerName: headerCls,
|
|
280
|
+
headerStyle: headerStyle,
|
|
281
|
+
headerTitleName: headerTitleCls,
|
|
282
|
+
headerExtraName: headerExtraCls,
|
|
283
|
+
//======================
|
|
284
|
+
bodyName: body_base,
|
|
285
|
+
bodyStyle: { ...styleBase, ...bodyStyle },
|
|
286
|
+
} as FairysValtioFormLayoutAttrsReturn;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface FairysValtioFormLayoutAttrsReturn {
|
|
290
|
+
/**列数*/
|
|
291
|
+
colCount: number;
|
|
292
|
+
/**规则校验失败错误提示位置*/
|
|
293
|
+
errorLayout: string;
|
|
294
|
+
/**
|
|
295
|
+
* label显示模式
|
|
296
|
+
* @platform taro 支持 between
|
|
297
|
+
*/
|
|
298
|
+
labelMode: string;
|
|
299
|
+
/**
|
|
300
|
+
* 底部边框类型
|
|
301
|
+
*/
|
|
302
|
+
borderedType: string;
|
|
303
|
+
/**表单布局实例*/
|
|
304
|
+
formLayoutInstance: FairysValtioFormLayoutInstance;
|
|
305
|
+
/**布局ClassName*/
|
|
306
|
+
layoutName: string;
|
|
307
|
+
/**布局样式*/
|
|
308
|
+
layoutStyle: React.CSSProperties;
|
|
309
|
+
/**头部ClassName*/
|
|
310
|
+
headerName: string;
|
|
311
|
+
/**头部样式*/
|
|
312
|
+
headerStyle: React.CSSProperties;
|
|
313
|
+
/**头部标题ClassName*/
|
|
314
|
+
headerTitleName: string;
|
|
315
|
+
/**头部额外内容ClassName*/
|
|
316
|
+
headerExtraName: string;
|
|
317
|
+
/**内容ClassName*/
|
|
318
|
+
bodyName: string;
|
|
319
|
+
/**内容样式*/
|
|
320
|
+
bodyStyle: React.CSSProperties;
|
|
321
|
+
}
|
package/src/index.tsx
ADDED
package/src/interface.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@unocss preflights;
|
|
2
|
+
@unocss default;
|
|
3
|
+
|
|
4
|
+
.fairys-valtio-form-item-label.show-colon::after {
|
|
5
|
+
content: ':';
|
|
6
|
+
display: inline-block;
|
|
7
|
+
text-align: center;
|
|
8
|
+
margin: 0;
|
|
9
|
+
margin-inline-end: 0.1rem;
|
|
10
|
+
margin-inline-start: 0.1rem;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fairys-valtio-form-item-label.required::before {
|
|
15
|
+
content: '*';
|
|
16
|
+
color: red;
|
|
17
|
+
display: inline-block;
|
|
18
|
+
margin-inline-end: 0.2rem;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.fairys-valtio-form-layout.fairys-form-layout-all-col-span {
|
|
23
|
+
grid-column: 1 / -1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.fairys-valtio-form-layout.fairys-form-layout-box-shadow {
|
|
27
|
+
box-shadow: 0 6px 16px -8px #00000014, 0 9px 28px #0000000d, 0 12px 48px 16px #00000008;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.fairys-valtio-form-layout + .fairys-valtio-form-layout {
|
|
31
|
+
margin-top: 12px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.fairys-valtio-form-layout-last-item-no-border > .fairys-valtio-form-layout-body > .fairys-valtio-form-item:last-child,
|
|
35
|
+
.fairys-valtio-form-layout-last-item-no-border
|
|
36
|
+
> .fairys-valtio-form-layout-body
|
|
37
|
+
> .fairys-valtio-form-item:last-child
|
|
38
|
+
> .fairys-valtio-form-item-container
|
|
39
|
+
> .fairys-valtio-form-item-body {
|
|
40
|
+
border-bottom: 0px;
|
|
41
|
+
}
|