|
| 1 | +importstyledfrom"styled-components"; |
| 2 | +import{RecordConstructorToView}from"lowcoder-core"; |
| 3 | +import{styleControl}from"comps/controls/styleControl"; |
| 4 | +import_from"lodash"; |
| 5 | +import{ |
| 6 | +AvatarStyle, |
| 7 | +AvatarStyleType, |
| 8 | +}from"comps/controls/styleControlConstants"; |
| 9 | +import{UICompBuilder}from"comps/generators/uiCompBuilder"; |
| 10 | +import{withDefault}from"../generators"; |
| 11 | +import{ |
| 12 | +NameConfig, |
| 13 | +NameConfigHidden, |
| 14 | +withExposingConfigs, |
| 15 | +}from"comps/generators/withExposing"; |
| 16 | +import{Section,sectionNames}from"lowcoder-design"; |
| 17 | +import{hiddenPropertyView}from"comps/utils/propertyUtils"; |
| 18 | +import{trans}from"i18n"; |
| 19 | +import{NumberControl}from"comps/controls/codeControl"; |
| 20 | +import{IconControl}from"comps/controls/iconControl"; |
| 21 | +import{ |
| 22 | +clickEvent, |
| 23 | +eventHandlerControl, |
| 24 | +}from"../controls/eventHandlerControl"; |
| 25 | +import{Avatar,AvatarProps,Badge,Dropdown,Menu}from"antd"; |
| 26 | +import{LeftRightControl,dropdownControl}from"../controls/dropdownControl"; |
| 27 | +import{stringExposingStateControl}from"../controls/codeStateControl"; |
| 28 | +import{BoolControl}from"../controls/boolControl"; |
| 29 | +import{BadgeBasicSection,badgeChildren}from"./badgeComp/badgeConstants"; |
| 30 | +import{DropdownOptionControl}from"../controls/optionsControl"; |
| 31 | +import{ReactElement,useContext}from"react"; |
| 32 | +import{CompNameContext,EditorContext}from"../editorState"; |
| 33 | + |
| 34 | +constAvatarWrapper=styled(Avatar)<AvatarProps&{$cursorPointer:boolean,$style:AvatarStyleType}>` |
| 35 | + background:${(props)=>props.$style.background}; |
| 36 | + color:${(props)=>props.$style.fill}; |
| 37 | + cursor:${(props)=>props.$cursorPointer ?'pointer' :''}; |
| 38 | +`; |
| 39 | + |
| 40 | +constWrapper=styled.div<{iconSize:number,labelPosition:string}>` |
| 41 | +display: flex; |
| 42 | +width: 100%; |
| 43 | +height: 100%; |
| 44 | +padding: 0px; |
| 45 | +align-items: center; |
| 46 | +flex-direction:${(props)=>props.labelPosition==='left' ?'row' :'row-reverse'}; |
| 47 | +` |
| 48 | + |
| 49 | +constLabelWrapper=styled.div<{iconSize:number,alignmentPosition:string}>` |
| 50 | +width: calc(100% -${(props)=>props.iconSize}px); |
| 51 | +display: flex; |
| 52 | +padding-left: 5px; |
| 53 | +padding-right: 5px; |
| 54 | +flex-direction: column; |
| 55 | +justify-content: flex-end; |
| 56 | +align-items:${(props)=>props.alignmentPosition==='left' ?'flex-start' :'flex-end'}; |
| 57 | +` |
| 58 | +constLabelSpan=styled.span<{color:string}>` |
| 59 | +max-width: 100%; |
| 60 | +overflow: hidden; |
| 61 | +text-overflow: ellipsis; |
| 62 | +white-space: nowrap; |
| 63 | +font-weight: bold; |
| 64 | +color:${(props)=>props.color}; |
| 65 | +` |
| 66 | +constCaptionSpan=styled.span<{color:string}>` |
| 67 | +max-width: 100%; |
| 68 | +overflow: hidden; |
| 69 | +text-overflow: ellipsis; |
| 70 | +white-space: nowrap; |
| 71 | +color:${(props)=>props.color}; |
| 72 | +` |
| 73 | +constEventOptions=[clickEvent]asconst; |
| 74 | +constsharpOptions=[ |
| 75 | +{label:trans("avatarComp.square"),value:"square"}, |
| 76 | +{label:trans("avatarComp.circle"),value:"circle"}, |
| 77 | +]asconst; |
| 78 | + |
| 79 | +constsideOptions=[ |
| 80 | +{label:trans('labelProp.left'),value:"left"}, |
| 81 | +{label:trans('labelProp.right'),value:"right"}, |
| 82 | +]asconst; |
| 83 | + |
| 84 | +constchildrenMap={ |
| 85 | +style:styleControl(AvatarStyle), |
| 86 | +icon:withDefault(IconControl,"/icon:solid/user"), |
| 87 | +iconSize:withDefault(NumberControl,40), |
| 88 | +onEvent:eventHandlerControl(EventOptions), |
| 89 | +shape:dropdownControl(sharpOptions,"circle"), |
| 90 | +title:stringExposingStateControl("title",""), |
| 91 | +src:stringExposingStateControl("src",""), |
| 92 | +avatarLabel:stringExposingStateControl("avatarLabel","{{currentUser.name}}"), |
| 93 | +avatarCatption:stringExposingStateControl("avatarCatption","{{currentUser.email}}"), |
| 94 | +labelPosition:dropdownControl(sideOptions,'left'), |
| 95 | +alignmentPosition:withDefault(LeftRightControl,'left'), |
| 96 | +enableDropdownMenu:BoolControl, |
| 97 | +options:DropdownOptionControl, |
| 98 | + ...badgeChildren, |
| 99 | +}; |
| 100 | + |
| 101 | +constAvatarView=(props:RecordConstructorToView<typeofchildrenMap>)=>{ |
| 102 | +const{ shape, title, src, iconSize}=props; |
| 103 | +constcomp=useContext(EditorContext).getUICompByName(useContext(CompNameContext)); |
| 104 | +consteventsCount=comp ?Object.keys(comp?.children.comp.children.onEvent.children).length :0; |
| 105 | +consthasIcon=props.options.findIndex((option)=>(option.prefixIconasReactElement)?.props.value)>-1; |
| 106 | +constitems=props.options |
| 107 | +.filter((option)=>!option.hidden) |
| 108 | +.map((option,index)=>({ |
| 109 | +title:option.label, |
| 110 | +label:option.label, |
| 111 | +key:option.label+" - "+index, |
| 112 | +disabled:option.disabled, |
| 113 | +icon:hasIcon&&<span>{option.prefixIcon}</span>, |
| 114 | +onEvent:option.onEvent, |
| 115 | +})); |
| 116 | +constmenu=( |
| 117 | +<Menu |
| 118 | +items={items} |
| 119 | +onClick={({ key})=>items.find((o)=>o.key===key)?.onEvent("click")} |
| 120 | +/> |
| 121 | +); |
| 122 | +return( |
| 123 | +<Dropdown |
| 124 | +menu={{ items}} |
| 125 | +placement={props.labelPosition==='left' ?"bottomLeft" :"bottomRight"} |
| 126 | +arrow |
| 127 | +disabled={!props.enableDropdownMenu} |
| 128 | +dropdownRender={()=>menu} |
| 129 | +> |
| 130 | +<WrappericonSize={props.iconSize}labelPosition={props.labelPosition}> |
| 131 | +<Badge |
| 132 | +count={props.badgeCount.value} |
| 133 | +dot={props.badgeType==='dot'} |
| 134 | +size={props.badgeSize} |
| 135 | +overflowCount={props.overflowCount} |
| 136 | +title={props.badgeTitle} |
| 137 | +offset={props.shape==='circle' ?[-2,6] :[0,0]} |
| 138 | +> |
| 139 | +<AvatarWrapper |
| 140 | +size={iconSize} |
| 141 | +icon={title.value!=='' ?null :props.icon} |
| 142 | +shape={shape} |
| 143 | +$style={props.style} |
| 144 | +src={src.value} |
| 145 | +$cursorPointer={eventsCount>0} |
| 146 | +onClick={()=>props.onEvent("click")} |
| 147 | +> |
| 148 | +{title.value} |
| 149 | +</AvatarWrapper> |
| 150 | +</Badge> |
| 151 | +<LabelWrappericonSize={props.iconSize}alignmentPosition={props.alignmentPosition}> |
| 152 | +<LabelSpancolor={props.style.label}>{props.avatarLabel.value}</LabelSpan> |
| 153 | +<CaptionSpancolor={props.style.caption}>{props.avatarCatption.value}</CaptionSpan> |
| 154 | +</LabelWrapper> |
| 155 | +</Wrapper> |
| 156 | +</Dropdown> |
| 157 | +); |
| 158 | +}; |
| 159 | + |
| 160 | +letAvatarBasicComp=(function(){ |
| 161 | +returnnewUICompBuilder(childrenMap,(props)=><AvatarView{...props}/>) |
| 162 | +.setPropertyViewFn((children)=>( |
| 163 | +<> |
| 164 | +<Sectionname={sectionNames.basic}> |
| 165 | +{children.src.propertyView({ |
| 166 | +label:trans("avatarComp.src"), |
| 167 | +placeholder:"http://xxxx/xx.jpg", |
| 168 | +tooltip:trans("avatarComp.avatarCompTooltip"), |
| 169 | +})} |
| 170 | +{children.title.propertyView({ |
| 171 | +label:trans("avatarComp.title"), |
| 172 | +tooltip:trans("avatarComp.avatarCompTooltip"), |
| 173 | +})} |
| 174 | +{children.icon.propertyView({ |
| 175 | +label:trans("avatarComp.icon"), |
| 176 | +IconType:"All", |
| 177 | +tooltip:trans("avatarComp.avatarCompTooltip"), |
| 178 | +})} |
| 179 | +{children.shape.propertyView({ |
| 180 | +label:trans("avatarComp.shape"), |
| 181 | +radioButton:true, |
| 182 | +})} |
| 183 | +{ |
| 184 | +children.iconSize.propertyView({ |
| 185 | +label:trans("avatarComp.iconSize"), |
| 186 | +})} |
| 187 | +{ |
| 188 | +children.enableDropdownMenu.propertyView({ |
| 189 | +label:trans("avatarComp.enableDropDown") |
| 190 | +})} |
| 191 | +{children.enableDropdownMenu.getView()&&children.options.propertyView({})} |
| 192 | +</Section> |
| 193 | +<Sectionname={trans('avatarComp.label')}> |
| 194 | +{ |
| 195 | +children.avatarLabel.propertyView({ |
| 196 | +label:trans("avatarComp.label"), |
| 197 | +})} |
| 198 | +{ |
| 199 | +children.avatarCatption.propertyView({ |
| 200 | +label:trans("avatarComp.caption"), |
| 201 | +})} |
| 202 | +{ |
| 203 | +children.labelPosition.propertyView({ |
| 204 | +label:trans("avatarComp.labelPosition"), |
| 205 | +radioButton:true, |
| 206 | +})} |
| 207 | +{ |
| 208 | +children.alignmentPosition.propertyView({ |
| 209 | +label:trans("avatarComp.alignmentPosition"), |
| 210 | +radioButton:true, |
| 211 | +})} |
| 212 | +</Section> |
| 213 | +{<BadgeBasicSection{...children}/>} |
| 214 | +<Sectionname={sectionNames.interaction}> |
| 215 | +{children.onEvent.getPropertyView()} |
| 216 | +</Section> |
| 217 | +<Sectionname={sectionNames.layout}> |
| 218 | +{hiddenPropertyView(children)} |
| 219 | +</Section> |
| 220 | +<Sectionname={sectionNames.style}> |
| 221 | +{children.style.getPropertyView()} |
| 222 | +</Section> |
| 223 | +</> |
| 224 | +)) |
| 225 | +.build(); |
| 226 | +})(); |
| 227 | + |
| 228 | + |
| 229 | +exportconstAvatarComp=withExposingConfigs(AvatarBasicComp,[ |
| 230 | +NameConfigHidden, |
| 231 | +newNameConfig("badgeCount",trans("button.textDesc")), |
| 232 | +]); |