Skip to content

Commit 5919277

Browse files
committed
图标选择组件添加antD图标
iconControl add antd icon
1 parent f4e0103 commit 5919277

File tree

4 files changed

+80
-28
lines changed

4 files changed

+80
-28
lines changed

client/packages/lowcoder-design/src/components/iconSelect/index.tsx

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
22
import type { IconDefinition } from "@fortawesome/free-regular-svg-icons";
33
import { Popover } from "antd";
4-
import { ActionType } from '@rc-component/trigger/lib/interface';
4+
import { ActionType } from "@rc-component/trigger/lib/interface";
55
import { TacoInput } from "components/tacoInput";
66
import { Tooltip } from "components/toolTip";
77
import { trans } from "i18n/design";
88
import _ from "lodash";
9-
import { ReactNode, useEffect, useCallback, useMemo, useRef, useState } from "react";
9+
import {
10+
ReactNode,
11+
useEffect,
12+
useCallback,
13+
useMemo,
14+
useRef,
15+
useState,
16+
} from "react";
1017
import Draggable from "react-draggable";
1118
import { List, ListRowProps } from "react-virtualized";
1219
import styled from "styled-components";
1320
import { CloseIcon, SearchIcon } from "icons";
21+
import { ANTDICON } from "../../../../lowcoder/src/comps/comps/timelineComp/antIcon";
1422

1523
const PopupContainer = styled.div`
1624
width: 408px;
@@ -110,11 +118,23 @@ const IconItemContainer = styled.div`
110118

111119
class Icon {
112120
readonly title: string;
113-
constructor(readonly def: IconDefinition, readonly names: string[]) {
114-
this.title = def.iconName.split("-").map(_.upperFirst).join(" ");
121+
constructor(readonly def: IconDefinition | any, readonly names: string[]) {
122+
if (def?.iconName) {
123+
this.title = def.iconName.split("-").map(_.upperFirst).join(" ");
124+
} else {
125+
this.title = names[0].slice(5);
126+
this.def = def;
127+
}
115128
}
116129
getView() {
117-
return <FontAwesomeIcon icon={this.def} style={{ width: "1em", height: "1em" }} />;
130+
if (this.names[0].startsWith("antd/")) return this.def;
131+
else
132+
return (
133+
<FontAwesomeIcon
134+
icon={this.def}
135+
style={{ width: "1em", height: "1em" }}
136+
/>
137+
);
118138
}
119139
}
120140

@@ -144,14 +164,25 @@ async function getAllIcons() {
144164
}
145165
}
146166
}
167+
//append ant icon
168+
for (let key of Object.keys(ANTDICON)) {
169+
ret["antd/" + key] = new Icon(
170+
ANTDICON[key.toLowerCase() as keyof typeof ANTDICON],
171+
["antd/" + key]
172+
);
173+
}
147174
allIcons = ret;
148175
return ret;
149176
}
150177

151178
export const iconPrefix = "/icon:";
152179

153180
export function removeQuote(value?: string) {
154-
return value ? (value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value) : "";
181+
return value
182+
? value.startsWith('"') && value.endsWith('"')
183+
? value.slice(1, -1)
184+
: value
185+
: "";
155186
}
156187

157188
function getIconKey(value?: string) {
@@ -171,7 +202,8 @@ export function useIcon(value?: string) {
171202
function search(
172203
allIcons: Record<string, Icon>,
173204
searchText: string,
174-
searchKeywords?: Record<string, string>
205+
searchKeywords?: Record<string, string>,
206+
IconType?: "OnlyAntd" | "All" | "default" | undefined
175207
) {
176208
const tokens = searchText
177209
.toLowerCase()
@@ -182,6 +214,8 @@ function search(
182214
if (icon.names.length === 0) {
183215
return false;
184216
}
217+
if (IconType === "OnlyAntd" && !key.startsWith("antd/")) return false;
218+
if (IconType === "default" && key.startsWith("antd/")) return false;
185219
let text = icon.names
186220
.flatMap((name) => [name, searchKeywords?.[name]])
187221
.filter((t) => t)
@@ -198,16 +232,20 @@ const IconPopup = (props: {
198232
label?: ReactNode;
199233
onClose: () => void;
200234
searchKeywords?: Record<string, string>;
235+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
201236
}) => {
202237
const [searchText, setSearchText] = useState("");
203238
const [allIcons, setAllIcons] = useState<Record<string, Icon>>({});
204239
const searchResults = useMemo(
205-
() => search(allIcons, searchText, props.searchKeywords),
240+
() => search(allIcons, searchText, props.searchKeywords, props.IconType),
206241
[searchText, allIcons]
207242
);
208243
const onChangeRef = useRef(props.onChange);
209244
onChangeRef.current = props.onChange;
210-
const onChangeIcon = useCallback((key: string) => onChangeRef.current(iconPrefix + key), []);
245+
const onChangeIcon = useCallback(
246+
(key: string) => onChangeRef.current(iconPrefix + key),
247+
[]
248+
);
211249
const columnNum = 8;
212250

213251
useEffect(() => {
@@ -217,24 +255,26 @@ const IconPopup = (props: {
217255
const rowRenderer = useCallback(
218256
(p: ListRowProps) => (
219257
<IconRow key={p.key} style={p.style}>
220-
{searchResults.slice(p.index * columnNum, (p.index + 1) * columnNum).map(([key, icon]) => (
221-
<Tooltip
222-
key={key}
223-
title={icon.title}
224-
placement="bottom"
225-
align={{ offset: [0, -7, 0, 0] }}
226-
destroyTooltipOnHide
227-
>
228-
<IconItemContainer
229-
tabIndex={0}
230-
onClick={() => {
231-
onChangeIcon(key);
232-
}}
258+
{searchResults
259+
.slice(p.index * columnNum, (p.index + 1) * columnNum)
260+
.map(([key, icon]) => (
261+
<Tooltip
262+
key={key}
263+
title={icon.title}
264+
placement="bottom"
265+
align={{ offset: [0, -7, 0, 0] }}
266+
destroyTooltipOnHide
233267
>
234-
{icon.getView()}
235-
</IconItemContainer>
236-
</Tooltip>
237-
))}
268+
<IconItemContainer
269+
tabIndex={0}
270+
onClick={() => {
271+
onChangeIcon(key);
272+
}}
273+
>
274+
{icon.getView()}
275+
</IconItemContainer>
276+
</Tooltip>
277+
))}
238278
</IconRow>
239279
),
240280
[searchResults, allIcons, onChangeIcon]
@@ -279,6 +319,7 @@ export const IconSelectBase = (props: {
279319
leftOffset?: number;
280320
parent?: HTMLElement | null;
281321
searchKeywords?: Record<string, string>;
322+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
282323
}) => {
283324
const { setVisible, parent } = props;
284325
return (
@@ -290,7 +331,11 @@ export const IconSelectBase = (props: {
290331
onOpenChange={setVisible}
291332
getPopupContainer={parent ? () => parent : undefined}
292333
// hide the original background when dragging the popover is allowed
293-
overlayInnerStyle={{ border: "none", boxShadow: "none", background: "transparent" }}
334+
overlayInnerStyle={{
335+
border: "none",
336+
boxShadow: "none",
337+
background: "transparent",
338+
}}
294339
// when dragging is allowed, always re-location to avoid the popover exceeds the screen
295340
destroyTooltipOnHide
296341
content={
@@ -299,6 +344,7 @@ export const IconSelectBase = (props: {
299344
label={props.label}
300345
onClose={() => setVisible?.(false)}
301346
searchKeywords={props.searchKeywords}
347+
IconType={props.IconType}
302348
/>
303349
}
304350
>
@@ -312,6 +358,7 @@ export const IconSelect = (props: {
312358
label?: ReactNode;
313359
children?: ReactNode;
314360
searchKeywords?: Record<string, string>;
361+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
315362
}) => {
316363
const [visible, setVisible] = useState(false);
317364
return (

client/packages/lowcoder/src/comps/controls/controlParams.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface ControlParams extends CodeEditorControlParams {
1818
preInputNode?: ReactNode;
1919
childrenWrapperStyle?: CSSProperties;
2020
extraChildren?: ReactNode;
21+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
2122
}
2223

2324
export interface ControlType {

client/packages/lowcoder/src/comps/controls/dropdownControl.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface DropdownControlParams<T extends OptionsType> extends ControlParams {
2828
showSearch?: boolean;
2929
dropdownStyle?: React.CSSProperties;
3030
labelStyle?: React.CSSProperties;
31+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
3132
}
3233

3334
interface DropdownPropertyViewProps<T extends OptionsType>

client/packages/lowcoder/src/comps/controls/iconControl.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,15 @@ const IconPicker = (props: {
7575
value: string;
7676
onChange: (value: string) => void;
7777
label?: ReactNode;
78+
IconType?: "OnlyAntd" | "All" | "default" | undefined;
7879
}) => {
7980
const icon = useIcon(props.value);
8081
return (
8182
<IconSelect
8283
onChange={props.onChange}
8384
label={props.label}
8485
searchKeywords={i18nObjs.iconSearchKeywords}
86+
IconType={props.IconType}
8587
>
8688
<TacoButton style={{ width: "100%" }}>
8789
{icon ? (
@@ -251,7 +253,7 @@ export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMs
251253
{ filterText: params.label },
252254
<Wrapper>
253255
<SwitchWrapper label={params.label} tooltip={params.tooltip} lastNode={jsContent} />
254-
{this.useCodeEditor && <IconCodeEditor codeControl={this.codeControl} params={params} />}
256+
{this.useCodeEditor && <IconCodeEditor codeControl={this.codeControl} params={params}/>}
255257
</Wrapper>
256258
);
257259
}
@@ -262,6 +264,7 @@ export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMs
262264
value={this.codeControl.getView()}
263265
onChange={(x) => this.dispatchChangeValueAction(x)}
264266
label={params.label}
267+
IconType={params.IconType}
265268
/>
266269
)}
267270
</ControlPropertyViewWrapper>

0 commit comments

Comments
 (0)