Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit417c528

Browse files
authored
Merge pull request#320 from mousheng/mention_component
Add mention component
2 parentsbbe7184 +1a56b61 commit417c528

File tree

10 files changed

+320
-3
lines changed

10 files changed

+320
-3
lines changed
Lines changed: 1 addition & 0 deletions
Loading

‎client/packages/lowcoder-design/src/icons/index.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,5 @@ export { ReactComponent as CompressIcon } from "icons/icon-compress.svg";
289289
export{ReactComponentasTableCellsIcon}from"icons/icon-table-cells.svg";// Added By Aqib Mirza
290290
export{ReactComponentasTimeLineIcon}from"icons/icon-timeline-comp.svg"
291291
export{ReactComponentasLottieIcon}from"icons/icon-lottie.svg";
292-
export{ReactComponentasAutoCompleteCompIcon}from"icons/icon-autocomplete-comp.svg";
292+
export{ReactComponentasMentionIcon}from"icons/icon-mention-comp.svg";
293+
export{ReactComponentasAutoCompleteCompIcon}from"icons/icon-autocomplete-comp.svg";
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
import{useState,useEffect}from"react";
2+
import{
3+
NameConfig,
4+
NameConfigPlaceHolder,
5+
NameConfigRequired,
6+
withExposingConfigs,
7+
}from"comps/generators/withExposing";
8+
import{Section,sectionNames}from"lowcoder-design";
9+
import{BoolControl}from"../../controls/boolControl";
10+
import{AutoHeightControl}from"../../controls/autoHeightControl";
11+
import{UICompBuilder}from"../../generators";
12+
import{FormDataPropertyView}from"../formComp/formDataConstants";
13+
import{
14+
checkMentionListData,
15+
textInputChildren,
16+
}from"./textInputConstants";
17+
import{
18+
withMethodExposing,
19+
refMethods,
20+
}from"../../generators/withMethodExposing";
21+
import{styleControl}from"comps/controls/styleControl";
22+
importstyledfrom"styled-components";
23+
import{
24+
InputLikeStyle,
25+
InputLikeStyleType,
26+
}from"comps/controls/styleControlConstants";
27+
import{
28+
disabledPropertyView,
29+
hiddenPropertyView,
30+
maxLengthPropertyView,
31+
minLengthPropertyView,
32+
readOnlyPropertyView,
33+
requiredPropertyView,
34+
}from"comps/utils/propertyUtils";
35+
import{booleanExposingStateControl}from"comps/controls/codeStateControl";
36+
import{trans}from"i18n";
37+
import{RefControl}from"comps/controls/refControl";
38+
import{TextAreaRef}from"antd/lib/input/TextArea";
39+
import{Mentions,ConfigProvider}from"antd";
40+
import{blurMethod,focusWithOptions}from"comps/utils/methodUtils";
41+
importtype{MentionsOptionProps}from"antd/es/mentions";
42+
import{
43+
textInputValidate,
44+
}from"../textInputComp/textInputConstants";
45+
import{jsonControl}from"@lowcoder-ee/comps/controls/codeControl";
46+
// 事件控制
47+
import{
48+
submitEvent,
49+
eventHandlerControl,
50+
mentionEvent,
51+
focusEvent,
52+
blurEvent,
53+
changeEvent
54+
}from"comps/controls/eventHandlerControl";
55+
56+
constWrapper=styled.div<{
57+
$style:InputLikeStyleType;
58+
}>`
59+
height: 100%;
60+
61+
.ant-input-clear-icon {
62+
opacity: 0.45;
63+
color:${(props)=>props.$style.text};
64+
top: 10px;
65+
66+
&:hover {
67+
opacity: 0.65;
68+
color:${(props)=>props.$style.text};
69+
}
70+
}
71+
`;
72+
73+
constEventOptions=[
74+
focusEvent,
75+
blurEvent,
76+
changeEvent,
77+
mentionEvent,
78+
submitEvent,
79+
]asconst;
80+
81+
letMentionTmpComp=(function(){
82+
constchildrenMap={
83+
...textInputChildren,
84+
viewRef:RefControl<TextAreaRef>,
85+
allowClear:BoolControl,
86+
autoHeight:AutoHeightControl,
87+
style:styleControl(InputLikeStyle),
88+
mentionList:jsonControl(checkMentionListData,{
89+
"@":["Li Lei","Han Meimei"],
90+
"#":["123","456","789"],
91+
}),
92+
onEvent:eventHandlerControl(EventOptions),
93+
invalid:booleanExposingStateControl("invalid"),
94+
};
95+
96+
returnnewUICompBuilder(childrenMap,(props)=>{
97+
const{ mentionList}=props;
98+
const[validateState,setvalidateState]=useState({});
99+
const[activationFlag,setActivationFlag]=useState(false);
100+
const[prefix,setPrefix]=useState<PrefixType>("@");
101+
typePrefixType="@"|keyoftypeofmentionList;
102+
103+
// 获取提及搜索关键字
104+
constonSearch=(_:string,newPrefix:PrefixType)=>{
105+
setPrefix(newPrefix);
106+
};
107+
constonChange=(value:string)=>{
108+
props.value.onChange(value);
109+
props.onEvent("change");
110+
};
111+
112+
constonPressEnter=(e:any)=>{
113+
if(e.shiftKey){
114+
e.preventDefault();
115+
props.onEvent("submit");
116+
}
117+
};
118+
119+
constonSelect=(option:MentionsOptionProps)=>{
120+
props.onEvent("mention");
121+
};
122+
constgetValidate=(value:any):""|"warning"|"error"|undefined=>{
123+
if(
124+
value.hasOwnProperty("validateStatus")&&
125+
value["validateStatus"]==="error"
126+
)
127+
return"error";
128+
return"";
129+
};
130+
131+
constgetTextInputValidate=()=>{
132+
return{
133+
value:{value:props.value.value},
134+
required:props.required,
135+
minLength:props?.minLength??0,
136+
maxLength:props?.maxLength??0,
137+
validationType:props.validationType,
138+
regex:props.regex,
139+
customRule:props.customRule,
140+
};
141+
};
142+
143+
useEffect(()=>{
144+
if(activationFlag){
145+
consttemp=textInputValidate(getTextInputValidate());
146+
setvalidateState(temp);
147+
props.invalid.onChange(temp.validateStatus!=="");
148+
}
149+
},[
150+
props.value.value,
151+
props.required,
152+
props?.minLength,
153+
props?.maxLength,
154+
props.validationType,
155+
props.regex,
156+
props.customRule,
157+
]);
158+
returnprops.label({
159+
required:props.required,
160+
children:(
161+
<Wrapper$style={props.style}>
162+
<ConfigProvider
163+
theme={{
164+
token:{
165+
colorBgContainer:props.style.background,
166+
colorBorder:props.style.border,
167+
borderRadius:parseInt(props.style.radius),
168+
colorText:props.style.text,
169+
colorPrimary:props.style.accent,
170+
},
171+
}}
172+
>
173+
<Mentions
174+
prefix={Object.keys(mentionList)}
175+
onFocus={()=>{
176+
setActivationFlag(true);
177+
props.onEvent("focus");
178+
}}
179+
onBlur={()=>props.onEvent("blur")}
180+
onPressEnter={onPressEnter}
181+
onSearch={onSearch}
182+
onChange={onChange}
183+
onSelect={onSelect}
184+
placeholder={props.placeholder}
185+
value={props.value.value}
186+
disabled={props.disabled}
187+
status={getValidate(validateState)}
188+
options={(mentionList[prefix]||[]).map((value:string)=>({
189+
key:value,
190+
value,
191+
label:value,
192+
}))}
193+
autoSize={props.autoHeight}
194+
style={{height:"100%",maxHeight:"100%",resize:"none",padding:props.style.padding}}
195+
readOnly={props.readOnly}
196+
/>
197+
</ConfigProvider>
198+
</Wrapper>
199+
),
200+
style:props.style,
201+
...validateState,
202+
});
203+
})
204+
.setPropertyViewFn((children)=>(
205+
<>
206+
<Sectionname={sectionNames.basic}>
207+
{children.mentionList.propertyView({
208+
label:trans("mention.mentionList"),
209+
})}
210+
{children.value.propertyView({label:trans("prop.defaultValue")})}
211+
{children.placeholder.propertyView({
212+
label:trans("prop.placeholder"),
213+
})}
214+
</Section>
215+
<FormDataPropertyView{...children}/>
216+
{children.label.getPropertyView()}
217+
218+
<Sectionname={sectionNames.interaction}>
219+
{children.onEvent.getPropertyView()}
220+
{disabledPropertyView(children)}
221+
</Section>
222+
223+
<Sectionname={sectionNames.advanced}>
224+
{readOnlyPropertyView(children)}
225+
</Section>
226+
227+
<Sectionname={sectionNames.validation}>
228+
{requiredPropertyView(children)}
229+
{children.validationType.propertyView({
230+
label:trans("prop.textType"),
231+
})}
232+
{minLengthPropertyView(children)}
233+
{maxLengthPropertyView(children)}
234+
{children.customRule.propertyView({})}
235+
</Section>
236+
237+
<Sectionname={sectionNames.layout}>
238+
{children.autoHeight.getPropertyView()}
239+
{hiddenPropertyView(children)}
240+
</Section>
241+
242+
<Sectionname={sectionNames.style}>
243+
{children.style.getPropertyView()}
244+
</Section>
245+
</>
246+
))
247+
.build();
248+
})();
249+
250+
MentionTmpComp=classextendsMentionTmpComp{
251+
overrideautoHeight():boolean{
252+
returnthis.children.autoHeight.getView();
253+
}
254+
};
255+
256+
constTextareaTmp2Comp=withMethodExposing(
257+
MentionTmpComp,
258+
refMethods([focusWithOptions,blurMethod])
259+
);
260+
261+
exportconstMentionComp=withExposingConfigs(TextareaTmp2Comp,[
262+
newNameConfig("value",trans("export.inputValueDesc")),
263+
NameConfigPlaceHolder,
264+
NameConfigRequired,
265+
newNameConfig("invalid",trans("export.invalidDesc")),
266+
newNameConfig("hidden",trans("export.hiddenDesc")),
267+
newNameConfig("disabled",trans("export.disabledDesc")),
268+
]);

‎client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import{BoolControl}from"comps/controls/boolControl";
2+
import{check}from"util/convertUtils";
23
import{
34
BoolCodeControl,
45
CustomRuleControl,
@@ -268,3 +269,14 @@ export const inputRefMethods = [
268269
(comp.children.viewRef.viewRef?.input?.setRangeTextasany)?.(...params),
269270
},
270271
];
272+
273+
exportfunctioncheckMentionListData(data:any){
274+
if(data==="")return{}
275+
for(constkeyindata){
276+
check(data[key],["array"],key,(node)=>{
277+
check(node,["string"],);
278+
returnnode
279+
})
280+
}
281+
returndata
282+
}

‎client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@ export const successEvent: EventConfigType = {
305305
value:"success",
306306
description:trans("event.successDesc"),
307307
};
308+
exportconstmentionEvent:EventConfigType={
309+
label:trans("event.mention"),
310+
value:"mention",
311+
description:trans("event.mentionDesc"),
312+
};
308313

309314
exportconstInputEventHandlerControl=eventHandlerControl([
310315
changeEvent,

‎client/packages/lowcoder/src/comps/index.tsx‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import {
9494
VideoCompIcon,
9595
TimeLineIcon,
9696
LottieIcon,
97+
MentionIcon,
9798
AutoCompleteCompIcon,
9899
}from"lowcoder-design";
99100

@@ -121,7 +122,8 @@ import { RemoteCompInfo } from "types/remoteComp";
121122
import{ScannerComp}from"./comps/buttonComp/scannerComp";
122123
import{SignatureComp}from"./comps/signatureComp";
123124
import{TimeLineComp}from"./comps/timelineComp/timelineComp";
124-
import{AutoCompleteComp}from"./comps/autoCompleteComp/autoCompleteComp";
125+
import{MentionComp}from"./comps/textInputComp/mentionComp";
126+
import{AutoCompleteComp}from"./comps/autoCompleteComp/autoCompleteComp"
125127
//Added by Aqib Mirza
126128
import{JsonLottieComp}from"./comps/jsonComp/jsonLottieComp";
127129

@@ -857,6 +859,15 @@ const uiCompMap: Registry = {
857859
h:55,
858860
},
859861
},
862+
mention:{
863+
name:trans("uiComp.mentionCompName"),
864+
enName:"mention",
865+
description:trans("uiComp.mentionCompDesc"),
866+
categories:["dataInputText"],
867+
icon:MentionIcon,
868+
keywords:trans("uiComp.mentionCompKeywords"),
869+
comp:MentionComp,
870+
},
860871
autocomplete:{
861872
name:trans("uiComp.autoCompleteCompName"),
862873
enName:"autoComplete",

‎client/packages/lowcoder/src/comps/uiCompRegistry.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export type UICompType =
112112
|"signature"
113113
|"jsonLottie"//Added By Aqib Mirza
114114
|"timeline"
115+
|"mention"
115116
|"autocomplete"
116117

117118
exportconstuiCompRegistry={}asRecord<UICompType|string,UICompManifest>;

‎client/packages/lowcoder/src/i18n/locales/en.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ export const en = {
262262
parseDesc:"Triggers on parse",
263263
success:"Success",
264264
successDesc:"Triggers on success",
265+
mention:"mention",
266+
mentionDesc:"Triggers on mention",
265267
},
266268
themeDetail:{
267269
primary:"Brand color",
@@ -845,6 +847,9 @@ export const en = {
845847
timelineCompName:"Time Line",
846848
timelineCompDesc:"Time Line",
847849
timelineCompKeywords:"",
850+
mentionCompName:"mention",
851+
mentionCompDesc:"mention",
852+
mentionCompKeywords:"",
848853
autoCompleteCompName:"autoComplete",
849854
autoCompleteCompDesc:"autoComplete",
850855
autoCompleteCompKeywords:"",
@@ -2471,6 +2476,9 @@ export const en = {
24712476
clickedObjectDesc:"clicked item data",
24722477
clickedIndexDesc:"clicked item index",
24732478
},
2479+
mention:{
2480+
mentionList:"mention list",
2481+
},
24742482
autoComplete:{
24752483
value:"auto complete value",
24762484
checkedValueFrom:"checked value from",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp