@fairys/taro-tools-simple-form 0.0.1

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 ADDED
@@ -0,0 +1 @@
1
+ # 框架 ui 组件库
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@fairys/taro-tools-simple-form",
3
+ "author": "SunLxy <1011771396@qq.com>",
4
+ "description": "框架组件库",
5
+ "homepage": "https://github.com/autumn-fairy-tales/fairys-taro-react",
6
+ "version": "0.0.1",
7
+ "main": "lib/index.js",
8
+ "types": "esm/index.d.ts",
9
+ "module": "esm/index.js",
10
+ "license": "ISC",
11
+ "scripts": {
12
+ "build": "carefrees-rslib build --config=./rslib.config.ts",
13
+ "watch": "carefrees-rslib build --watch --config=./rslib.config.ts"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/autumn-fairy-tales/fairys-taro-react.git",
21
+ "directory": "packages/simple-form"
22
+ },
23
+ "files": [
24
+ "src",
25
+ "esm"
26
+ ],
27
+ "dependencies": {
28
+ "@carefrees/form-utils-react-taro": "^0.0.16",
29
+ "@nutui/nutui-react-taro": "^3.0.18",
30
+ "clsx": "2.1.1",
31
+ "valtio": "~2.1.5"
32
+ },
33
+ "devDependencies": {
34
+ "@types/react": "~18.2.21",
35
+ "react": "^18.0.0"
36
+ }
37
+ }
@@ -0,0 +1,46 @@
1
+ import { View, Text, ViewProps } from '@tarojs/components';
2
+ import { Calendar, CalendarProps } from '@nutui/nutui-react-taro';
3
+ import { useMemo, useState } from 'react';
4
+ import clsx from 'clsx';
5
+
6
+ export interface FairysTaroCalendarProps extends Partial<CalendarProps> {
7
+ placeholder?: string;
8
+ value?: string;
9
+ className?: string;
10
+ style?: ViewProps['style'];
11
+ onChange?: (value: string, date: string | string[]) => void;
12
+ }
13
+
14
+ export const FairysTaroCalendarBase = (props: FairysTaroCalendarProps) => {
15
+ const { placeholder = '请选择', value, className, style, onChange, ...rest } = props;
16
+ const [visible, setVisible] = useState(false);
17
+ const clsx_text = useMemo(() => {
18
+ return clsx('fairys-taro-calendar-text', {
19
+ 'fairys-taro-calendar-text-placeholder fairystaroform__text-gray-600 fairystaroform__font-normal': !value,
20
+ 'fairys-taro-calendar-text-value fairystaroform__text-black': value,
21
+ });
22
+ }, [value]);
23
+
24
+ return (
25
+ <View className={`fairys-taro-calendar ${className || ''}`} style={style}>
26
+ <Text onClick={() => setVisible(true)} className={clsx_text}>
27
+ {value || placeholder}
28
+ </Text>
29
+ <Calendar
30
+ {...rest}
31
+ visible={visible}
32
+ defaultValue={value}
33
+ onClose={() => setVisible(false)}
34
+ onConfirm={(date) => {
35
+ const [year, month, day] = date;
36
+ if (year) {
37
+ onChange?.(`${year}-${month}-${day}`, date);
38
+ } else {
39
+ onChange?.(undefined, date);
40
+ }
41
+ setVisible(false);
42
+ }}
43
+ />
44
+ </View>
45
+ );
46
+ };
@@ -0,0 +1,123 @@
1
+ import { View, Text } from '@tarojs/components';
2
+ import { Cascader, CascaderProps, CascaderOption } from '@nutui/nutui-react-taro';
3
+ import { useMemo, useState } from 'react';
4
+ import clsx from 'clsx';
5
+
6
+ export interface FairysTaroCascaderProps
7
+ extends Omit<Partial<CascaderProps>, 'visible' | 'onClose' | 'onChange' | 'value'> {
8
+ placeholder?: string;
9
+ labelInValue?: boolean;
10
+ value?: (string | number | CascaderOption)[];
11
+ onChange?: (value: (string | number | CascaderOption)[], pathNodes: CascaderOption[]) => void;
12
+ }
13
+
14
+ export const FairysTaroCascaderBase = (props: FairysTaroCascaderProps) => {
15
+ const {
16
+ placeholder = '请选择',
17
+ value,
18
+ className,
19
+ style,
20
+ onChange,
21
+ labelInValue = true,
22
+ options,
23
+ optionKey,
24
+ ...rest
25
+ } = props;
26
+ const [visible, setVisible] = useState(false);
27
+
28
+ const valueKey = optionKey?.valueKey || 'value';
29
+ const textKey = optionKey?.textKey || 'text';
30
+ const childrenKey = optionKey?.childrenKey || 'children';
31
+
32
+ const render = useMemo(() => {
33
+ if (Array.isArray(value) && value.length) {
34
+ if (labelInValue) {
35
+ return value
36
+ .map((it) => {
37
+ if (typeof it === 'string' || typeof it === 'number') {
38
+ return it;
39
+ }
40
+ if (labelInValue) {
41
+ return it?.[textKey] || '';
42
+ }
43
+ return '';
44
+ })
45
+ .filter(Boolean)
46
+ .join('/');
47
+ } else {
48
+ // 通过 options 获取数据
49
+ const _value = [];
50
+ let _options = options || [];
51
+ while (_options.length) {
52
+ const it = _options.shift();
53
+ if (typeof it === 'string' || typeof it === 'number') {
54
+ const findx = _options.findIndex((it) => it[valueKey] === it);
55
+ if (findx) {
56
+ _value.push(it?.[textKey]);
57
+ _options = it?.[childrenKey] || [];
58
+ } else {
59
+ // 没有找到对应的文本,跳出循环
60
+ break;
61
+ }
62
+ } else {
63
+ // 没有找到对应的文本,跳出循环
64
+ break;
65
+ }
66
+ }
67
+ return _value.join('/');
68
+ }
69
+ }
70
+ return '';
71
+ }, [value, labelInValue, valueKey, textKey]);
72
+
73
+ const clsx_text = useMemo(() => {
74
+ return clsx('fairys-taro-cascader-text', {
75
+ 'fairys-taro-cascader-text-placeholder fairystaroform__text-gray-600 fairystaroform__font-normal': !render,
76
+ 'fairys-taro-cascader-text-value fairystaroform__text-black': render,
77
+ });
78
+ }, [render]);
79
+
80
+ const _value = useMemo(() => {
81
+ if (Array.isArray(value) && value.length) {
82
+ return value
83
+ .map((it) => {
84
+ if (typeof it === 'string' || typeof it === 'number') {
85
+ return it;
86
+ }
87
+ if (labelInValue) {
88
+ return it[valueKey];
89
+ }
90
+ return '';
91
+ })
92
+ .filter((it) => it !== '');
93
+ }
94
+ return [];
95
+ }, [value, labelInValue, valueKey]);
96
+
97
+ return (
98
+ <View className={`fairys-taro-cascader ${className || ''}`} style={style}>
99
+ <Text onClick={() => setVisible(true)} className={clsx_text}>
100
+ {render || placeholder}
101
+ </Text>
102
+ <Cascader
103
+ {...rest}
104
+ optionKey={optionKey}
105
+ options={options}
106
+ value={_value}
107
+ visible={visible}
108
+ onChange={(value, pathNodes) => {
109
+ if (labelInValue) {
110
+ const _value = pathNodes.map((it) => {
111
+ const { children, ...rest } = it;
112
+ return rest;
113
+ });
114
+ onChange?.(_value, pathNodes);
115
+ } else {
116
+ onChange?.(value, pathNodes);
117
+ }
118
+ }}
119
+ onClose={() => setVisible(false)}
120
+ />
121
+ </View>
122
+ );
123
+ };
@@ -0,0 +1,16 @@
1
+ import { CheckboxGroup, CheckboxGroupProps, Checkbox, CheckboxProps } from '@nutui/nutui-react-taro';
2
+
3
+ export interface FairysTaroCheckboxGroupProps extends Partial<CheckboxGroupProps> {
4
+ items?: Partial<CheckboxProps>[];
5
+ }
6
+
7
+ export const FairysTaroCheckboxGroupBase = (props: FairysTaroCheckboxGroupProps) => {
8
+ const { items, className, ...rest } = props;
9
+ return (
10
+ <CheckboxGroup className={`fairys-taro-checkbox-group ${className || ''}`} direction="horizontal" {...rest}>
11
+ {items?.map((item) => (
12
+ <Checkbox key={item.value} {...item} />
13
+ ))}
14
+ </CheckboxGroup>
15
+ );
16
+ };
@@ -0,0 +1,168 @@
1
+ import { View, Text } from '@tarojs/components';
2
+ import { DatePicker, DatePickerProps, CascaderOption } from '@nutui/nutui-react-taro';
3
+ import { useMemo, useState } from 'react';
4
+ import clsx from 'clsx';
5
+
6
+ export interface FairysTaroDatePickerProps extends Omit<Partial<DatePickerProps>, 'value' | 'onChange'> {
7
+ placeholder?: string;
8
+ /**
9
+ * 日期格式
10
+ * @description
11
+ * 当 type 为 date 时,格式为 YYYY-MM-DD
12
+ * 当 type 为 time 时,格式为 HH:mm:ss
13
+ * 当 type 为 year-month 时,格式为 YYYY-MM
14
+ * 当 type 为 month-day 时,格式为 MM-DD
15
+ * 当 type 为 datehour 时,格式为 YYYY-MM-DD HH
16
+ * 当 type 为 datetime 时,格式为 YYYY-MM-DD HH:mm
17
+ * 当 type 为 hour-minutes 时,格式为 HH:mm
18
+ */
19
+ value?: string | Date;
20
+ onChange?: (value?: string) => void;
21
+ }
22
+
23
+ const getDate = (selectedValue: (string | number)[], type: DatePickerProps['type']) => {
24
+ if (Array.isArray(selectedValue) && selectedValue.length) {
25
+ const [year, month, day, hour, minute, second] = selectedValue;
26
+ // "date" | "time" | "year-month" | "month-day" | "datehour" | "datetime" | "hour-minutes"
27
+ let date = `${year}-${month}-${day} ${hour}:${minute}`;
28
+ if (type === 'date') {
29
+ date = `${year}-${month}-${day}`;
30
+ } else if (type === 'time') {
31
+ date = `${hour}:${minute}:${second}`;
32
+ } else if (type === 'year-month') {
33
+ date = `${year}-${month}`;
34
+ } else if (type === 'month-day') {
35
+ date = `${month}-${day}`;
36
+ } else if (type === 'datehour') {
37
+ date = `${year}-${month}-${day} ${hour}`;
38
+ } else if (type === 'datetime') {
39
+ date = `${year}-${month}-${day} ${hour}:${minute}`;
40
+ } else if (type === 'hour-minutes') {
41
+ date = `${hour}:${minute}`;
42
+ }
43
+ return date;
44
+ }
45
+ return undefined;
46
+ };
47
+
48
+ const renderDate = (date: string | undefined | Date, type: DatePickerProps['type']) => {
49
+ let renderStr = undefined;
50
+ let _value = undefined;
51
+ const defaultValue = new Date();
52
+ if (date) {
53
+ const isDate = date instanceof Date;
54
+ if (type === 'date') {
55
+ if (isDate) {
56
+ renderStr = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
57
+ _value = date;
58
+ } else {
59
+ const [year, month, day] = date.split(/[-|\s]/);
60
+ renderStr = `${year}-${month}-${day}`;
61
+ _value = new Date(`${year}-${month}-${day}`);
62
+ }
63
+ } else if (type === 'time') {
64
+ if (isDate) {
65
+ renderStr = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
66
+ _value = date;
67
+ } else {
68
+ const [hour, minute, second] = date.split(/[:|]/);
69
+ renderStr = `${hour}:${minute}:${second}`;
70
+ _value = new Date(
71
+ `${defaultValue.getFullYear()}-${
72
+ defaultValue.getMonth() + 1
73
+ }-${defaultValue.getDate()} ${hour}:${minute}:${second}`,
74
+ );
75
+ }
76
+ } else if (type === 'year-month') {
77
+ if (isDate) {
78
+ renderStr = `${date.getFullYear()}-${date.getMonth() + 1}`;
79
+ _value = date;
80
+ } else {
81
+ const [year, month] = date.split(/[-|\s]/);
82
+ renderStr = `${year}-${month}`;
83
+ _value = new Date(`${year}-${month}-01`);
84
+ }
85
+ } else if (type === 'month-day') {
86
+ if (isDate) {
87
+ renderStr = `${date.getMonth() + 1}-${date.getDate()}`;
88
+ _value = date;
89
+ } else {
90
+ const [month, day] = date.split(/[-|\s]/);
91
+ renderStr = `${month}-${day}`;
92
+ _value = new Date(`${defaultValue.getFullYear()}-${month}-${day}`);
93
+ }
94
+ } else if (type === 'datehour') {
95
+ if (isDate) {
96
+ renderStr = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}`;
97
+ _value = date;
98
+ } else {
99
+ const [year, month, day, hour] = date.split(/[-|\s|:]/);
100
+ renderStr = `${year}-${month}-${day} ${hour}`;
101
+ _value = new Date(`${year}-${month}-${day} ${hour}:00:00`);
102
+ }
103
+ } else if (type === 'datetime') {
104
+ if (isDate) {
105
+ renderStr = `${date.getFullYear()}-${
106
+ date.getMonth() + 1
107
+ }-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`;
108
+ _value = date;
109
+ } else {
110
+ const [year, month, day, hour, minute] = date.split(/[-|\s|:]/);
111
+ renderStr = `${year}-${month}-${day} ${hour}:${minute}`;
112
+ _value = new Date(`${year}-${month}-${day} ${hour}:${minute}:00`);
113
+ }
114
+ } else if (type === 'hour-minutes') {
115
+ if (isDate) {
116
+ renderStr = `${date.getHours()}:${date.getMinutes()}`;
117
+ _value = date;
118
+ } else {
119
+ const [hour, minute] = date.split(/[:|]/);
120
+ renderStr = `${hour}:${minute}`;
121
+ _value = new Date(
122
+ `${defaultValue.getFullYear()}-${defaultValue.getMonth() + 1}-${defaultValue.getDate()} ${hour}:${minute}:00`,
123
+ );
124
+ }
125
+ }
126
+ }
127
+ return { renderStr, _value };
128
+ };
129
+
130
+ export const FairysTaroDatePickerBase = (props: FairysTaroDatePickerProps) => {
131
+ const { placeholder = '请选择', value, className, style, onChange, type = 'date', ...rest } = props;
132
+ const [visible, setVisible] = useState(false);
133
+
134
+ const clsx_text = useMemo(() => {
135
+ return clsx('fairys-taro-date-picker-text', {
136
+ 'fairys-taro-date-picker-text-placeholder fairystaroform__text-gray-600 fairystaroform__font-normal': !value,
137
+ 'fairys-taro-date-picker-text-value fairystaroform__text-black': value,
138
+ });
139
+ }, [value]);
140
+
141
+ const render = useMemo(() => {
142
+ return renderDate(value, type);
143
+ }, [value, type]);
144
+
145
+ return (
146
+ <View className={`fairys-taro-date-picker ${className || ''}`} style={style}>
147
+ <Text onClick={() => setVisible(true)} className={clsx_text}>
148
+ {render.renderStr || placeholder}
149
+ </Text>
150
+ <DatePicker
151
+ type={type}
152
+ showChinese
153
+ {...rest}
154
+ value={render._value}
155
+ visible={visible}
156
+ onClose={() => setVisible(false)}
157
+ onConfirm={(_, selectedValue) => {
158
+ if (Array.isArray(selectedValue) && selectedValue.length) {
159
+ onChange?.(getDate(selectedValue, type));
160
+ } else {
161
+ onChange?.(undefined);
162
+ }
163
+ setVisible(false);
164
+ }}
165
+ />
166
+ </View>
167
+ );
168
+ };
@@ -0,0 +1,55 @@
1
+ import { View, Text } from '@tarojs/components';
2
+ import { Picker, TaroPickerProps, PickerOptions } from '@nutui/nutui-react-taro';
3
+ import { useMemo, useState } from 'react';
4
+ import clsx from 'clsx';
5
+
6
+ export interface FairysTaroPickerProps extends Omit<Partial<TaroPickerProps>, 'value' | 'onChange'> {
7
+ placeholder?: string;
8
+ value?: PickerOptions;
9
+ onChange?: (value: PickerOptions) => void;
10
+ }
11
+
12
+ export const FairysTaroPickerBase = (props: FairysTaroPickerProps) => {
13
+ const { placeholder = '请选择', className, style, value, onChange, ...rest } = props;
14
+
15
+ const [visible, setVisible] = useState(false);
16
+
17
+ const _renderValue = useMemo(() => {
18
+ if (Array.isArray(value)) {
19
+ return value.map((item) => item.label).join(' / ');
20
+ }
21
+ return undefined;
22
+ }, [value]);
23
+
24
+ const clsx_text = useMemo(() => {
25
+ return clsx('fairys-taro-picker-text', {
26
+ 'fairys-taro-picker-text-placeholder fairystaroform__text-gray-600 fairystaroform__font-normal': !_renderValue,
27
+ 'fairys-taro-picker-text-value fairystaroform__text-black': _renderValue,
28
+ });
29
+ }, [_renderValue]);
30
+
31
+ const _value = useMemo(() => {
32
+ if (Array.isArray(value)) {
33
+ return value.map((item) => item.value);
34
+ }
35
+ return undefined;
36
+ }, [value]);
37
+
38
+ return (
39
+ <View className={`fairys-taro-picker ${className || ''}`} style={style}>
40
+ <Text onClick={() => setVisible(true)} className={clsx_text}>
41
+ {_renderValue || placeholder}
42
+ </Text>
43
+ <Picker
44
+ {...rest}
45
+ value={_value}
46
+ visible={visible}
47
+ onClose={() => setVisible(false)}
48
+ onConfirm={(selectedOptions) => {
49
+ setVisible(false);
50
+ onChange?.(selectedOptions);
51
+ }}
52
+ />
53
+ </View>
54
+ );
55
+ };
@@ -0,0 +1,51 @@
1
+ import { View } from '@tarojs/components';
2
+ import { Button, Checkbox, Input } from '@nutui/nutui-react-taro';
3
+ import { Fragment } from 'react';
4
+ import { useFairysTaroPopupSearchBaseInstanceContext } from './instance';
5
+ import { Del, Search } from '@nutui/icons-react-taro';
6
+
7
+ export function FairysTaroPopupSearchFooterBase<T = any>() {
8
+ const [state, instance] = useFairysTaroPopupSearchBaseInstanceContext<T>();
9
+ const operationStatus = state.operationStatus;
10
+ return (
11
+ <View className="fairys-taro-popup-search-content-footer fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-nowrap fairystaroform__py-2 fairystaroform__box-border fairystaroform__px-2">
12
+ <View className="fairystaroform__flex-1 fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-nowrap fairystaroform__justify-between">
13
+ <View className="fairystaroform__flex-1">
14
+ <Checkbox checked={state.allChecked} onChange={instance.onAllChecked} label="全选" />
15
+ </View>
16
+ {operationStatus === 'manage' ? (
17
+ <View className="fairystaroform__flex-1 fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-nowrap fairystaroform__justify-end">
18
+ <Button icon={<Del color="#fff" />} type="danger" onClick={() => instance.onDeleteData()}>
19
+ 删除
20
+ </Button>
21
+ </View>
22
+ ) : (
23
+ <Fragment />
24
+ )}
25
+ </View>
26
+ {operationStatus === 'select' ? (
27
+ <View className="fairystaroform__flex-1">
28
+ <Button onClick={instance.onSave} block type="primary">
29
+ 确定
30
+ </Button>
31
+ </View>
32
+ ) : (
33
+ <Fragment />
34
+ )}
35
+ </View>
36
+ );
37
+ }
38
+
39
+ export function FairysTaroPopupSearchInputBase<T = any>() {
40
+ const [state, instance] = useFairysTaroPopupSearchBaseInstanceContext<T>({ sync: true });
41
+ const search = state.search || '';
42
+
43
+ return (
44
+ <View className="fairys-taro-popup-search-content-header fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-nowrap fairystaroform__px-1 fairystaroform__box-border fairystaroform__pr-4 fairystaroform__border-b-1 fairystaroform__border-b-solid fairystaroform__border-b-gray-200">
45
+ <Input placeholder="请输入" value={search} onChange={instance.onSearch} />
46
+ <View>
47
+ <Search className="fairys-taro-popup-search-content-header-search fairystaroform__text-gray-600 fairystaroform__cursor-pointer" />
48
+ </View>
49
+ </View>
50
+ );
51
+ }
@@ -0,0 +1,176 @@
1
+ import { View, Text } from '@tarojs/components';
2
+ import { Popup, TaroPopupProps } from '@nutui/nutui-react-taro';
3
+ import { Fragment, useMemo } from 'react';
4
+ import clsx from 'clsx';
5
+ import { useFairysTaroPopupSearchBaseInstance, FairysTaroPopupSearchBaseInstanceContext } from './instance';
6
+ import type { FairysTaroPopupSearchBaseInstanceMount } from './instance';
7
+ import { FairysTaroPopupSearchFooterBase, FairysTaroPopupSearchInputBase } from './base';
8
+ import { FairysTaroPopupSearchListVirtual } from './list.virtual';
9
+ import { FairysTaroPopupSearchListTable } from './list.table';
10
+
11
+ /**
12
+ * 如果是多选,怎么移除某几个选中项
13
+ * */
14
+
15
+ export interface FairysTaroPopupSearchProps<T = any>
16
+ extends Partial<TaroPopupProps>,
17
+ FairysTaroPopupSearchBaseInstanceMount<T> {
18
+ placeholder?: string;
19
+ /**是否显示删除按钮*/
20
+ showDeleteButton?: boolean;
21
+ /**是否显示搜索框*/
22
+ showSearch?: boolean;
23
+ /**选中项*/
24
+ value?: T | T[];
25
+ /**选择数据*/
26
+ options?: ({
27
+ label?: string;
28
+ value?: string | number;
29
+ [x: string]: any;
30
+ } & T)[];
31
+ /**
32
+ * 最大渲染个数数量
33
+ */
34
+ maxTagCount?: number;
35
+ }
36
+
37
+ export function FairysTaroPopupSearchBase<T = any>(props: FairysTaroPopupSearchProps<T>) {
38
+ const {
39
+ placeholder = '请选择',
40
+ className,
41
+ style,
42
+ value,
43
+ onChange,
44
+ onLoadData,
45
+ otherRequestParams,
46
+ maxWidth,
47
+ maxHeight,
48
+ renderText,
49
+ renderListItemText,
50
+ showDeleteButton = true,
51
+ showSearch = true,
52
+ renderList,
53
+ options,
54
+ columns,
55
+ mode = 'single',
56
+ /**列表项的唯一键值*/
57
+ rowKey = 'value',
58
+ /**提示框 显示字段*/
59
+ displayField = 'label',
60
+ /**渲染类型*/
61
+ renderType = 'list',
62
+ maxTagCount = 5,
63
+ /**表格属性*/
64
+ tableProps = {},
65
+ useTableProps,
66
+ isReplace = false,
67
+ ...rest
68
+ } = props;
69
+
70
+ const [state, instance] = useFairysTaroPopupSearchBaseInstance<T>();
71
+
72
+ instance.maxWidth = maxWidth;
73
+ instance.maxHeight = maxHeight;
74
+ instance.renderText = renderText;
75
+ instance.renderList = renderList;
76
+ instance.onLoadData = onLoadData;
77
+ instance.otherRequestParams = otherRequestParams;
78
+ instance.onChange = onChange;
79
+ instance.renderListItemText = renderListItemText;
80
+ instance.tableProps = tableProps;
81
+ instance.useTableProps = useTableProps;
82
+ instance.isReplace = isReplace;
83
+
84
+ instance.rowKey = rowKey;
85
+ instance.displayField = displayField;
86
+ instance.mode = mode;
87
+ instance.columns = columns;
88
+ instance.renderType = renderType;
89
+
90
+ const operationStatus = state.operationStatus;
91
+ const visible = state.visible;
92
+
93
+ useMemo(() => instance.ctor(), [maxWidth, maxHeight]);
94
+
95
+ useMemo(() => {
96
+ if (!isReplace) {
97
+ instance.updateState({ value, _tempValue: value });
98
+ } else {
99
+ instance.updateState({ value, _tempValue: undefined });
100
+ }
101
+ }, [value, isReplace, visible]);
102
+
103
+ useMemo(() => instance.updateState({ dataList: options || [], _tempFilterDataList: options || [] }), [options]);
104
+ useMemo(() => instance.updateState({ mode }), [mode]);
105
+ useMemo(() => instance.updateState({ columns }), [columns]);
106
+
107
+ const renderTextValue = useMemo(() => {
108
+ if (instance.renderText) {
109
+ return instance.renderText(value);
110
+ }
111
+ if (instance.mode === 'multiple') {
112
+ if (Array.isArray(value)) {
113
+ if (value.length > maxTagCount) {
114
+ return `${value
115
+ .slice(0, maxTagCount)
116
+ .map((item) => item[instance.displayField])
117
+ .join(',')}...`;
118
+ }
119
+ return value.map((item) => item[instance.displayField]).join(',');
120
+ }
121
+ return '';
122
+ }
123
+ return value?.[instance.displayField];
124
+ }, [value, mode, maxTagCount]);
125
+
126
+ const clsx_text = useMemo(() => {
127
+ // 文本溢出显示...
128
+ return clsx('fairys-taro-popup-search-text', {
129
+ 'fairys-taro-popup-search-text-placeholder fairystaroform__text-gray-600 fairystaroform__font-normal': !value,
130
+ 'fairys-taro-popup-search-text-value fairystaroform__text-black': value,
131
+ });
132
+ }, [value]);
133
+
134
+ return (
135
+ <View className={`fairys-taro-popup-search ${className || ''}`} style={style}>
136
+ <View className="fairys-taro-popup-search-text-container fairystaroform__break-all">
137
+ <Text onClick={() => instance.updateState({ visible: true })} className={clsx_text}>
138
+ {renderTextValue || placeholder}
139
+ </Text>
140
+ </View>
141
+ <Popup
142
+ lockScroll
143
+ position="bottom"
144
+ closeable
145
+ {...rest}
146
+ left={
147
+ mode === 'multiple' && !isReplace ? (
148
+ <Text onClick={instance.updateOperationStatus}>{operationStatus == 'select' ? '管理' : '完成'}</Text>
149
+ ) : (
150
+ <Fragment />
151
+ )
152
+ }
153
+ visible={visible}
154
+ onClose={instance.onClose}
155
+ overlayClassName="fairys-taro-popup-search-overlay"
156
+ className="fairys-taro-popup-search-content fairystaroform__flex fairystaroform__flex-col fairystaroform__overflow-hidden"
157
+ >
158
+ <FairysTaroPopupSearchBaseInstanceContext.Provider value={instance}>
159
+ <View className="fairys-taro-popup-search-content-inner fairystaroform__flex fairystaroform__flex-1 fairystaroform__flex-col fairystaroform__overflow-hidden">
160
+ {showSearch ? <FairysTaroPopupSearchInputBase /> : <Fragment />}
161
+ <View style={{ flex: 1, overflow: 'hidden' }}>
162
+ {renderType === 'list' ? (
163
+ <FairysTaroPopupSearchListVirtual />
164
+ ) : renderType === 'table' ? (
165
+ <FairysTaroPopupSearchListTable />
166
+ ) : (
167
+ <Fragment />
168
+ )}
169
+ </View>
170
+ {mode === 'multiple' ? <FairysTaroPopupSearchFooterBase /> : <Fragment />}
171
+ </View>
172
+ </FairysTaroPopupSearchBaseInstanceContext.Provider>
173
+ </Popup>
174
+ </View>
175
+ );
176
+ }