Commit 3b2cc12a4f624b4db9c745daa0cbfe7d3e945769

Authored by 李婷
1 parent 184fa4a3

feat: 选择图标组件

... ... @@ -19,5 +19,6 @@ export * from './qx-search-input';
19 19 export * from './qx-dynamic-component';
20 20 export * from './qx-widget-icon';
21 21 export * from './qx-flow-node-selector';
  22 +export * from './qx-icon-selector';
22 23
23 24
... ...
  1 +// 图标形态
  2 +export enum ICON_SHAPE {
  3 + line = '线性',
  4 + fill = '面性',
  5 +}
  6 +
  7 +// 图标所属分类
  8 +export const ICON_CLASSIFY: any = {
  9 + // media: '媒体',
  10 + logo: 'Logo',
  11 + file: '文件',
  12 + education: '教育',
  13 + // editor: '编辑',
  14 + device: '设备',
  15 + development: '研发',
  16 + design: '设计',
  17 + map: '地图',
  18 + building: '建筑',
  19 + business: '商业',
  20 + contact: '联络',
  21 + system: '系统',
  22 + user: '用户',
  23 + transport: '交通',
  24 + weather: '天气',
  25 +};
  26 +
  27 +export const BG_COLORS: string[] = [
  28 + // '#F5212C',
  29 + // '#FA541C',
  30 + // '#FAAD14',
  31 + // '#ED7B2E',
  32 + // '#10C2C2',
  33 + // '#00A870',
  34 + // '#EC49B4',
  35 + // '#834EC2',
  36 + // '#242835',
  37 + '#FC6746',
  38 + '#1FBCD2',
  39 + '#FD9727',
  40 + '#50AE55',
  41 + '#B81E51',
  42 + '#4054B2',
  43 + '#465A63',
  44 +];
  45 +
  46 +export const FORM_GROUP: any = {
  47 + form: 'icon-app-file-fill',
  48 + group: 'icon-app-folder-2-fill',
  49 + report: 'icon-app-shuju',
  50 + url: 'icon-app-share-forward-fill',
  51 + page: 'icon-app-presentation-2-fill',
  52 + dataset: 'icon-app-coin-2-fill',
  53 + datasetCube: 'icon-app-box-3-fill',
  54 +};
  55 +
  56 +export const ICONS: any = {
  57 + system: [
  58 + 'icon-app-add-circle',
  59 + 'icon-app-alert',
  60 + 'icon-app-alert-octagon',
  61 + 'icon-app-brush',
  62 + 'icon-app-certificate',
  63 + 'icon-app-check-circle',
  64 + 'icon-app-close-circle',
  65 + 'icon-app-database',
  66 + 'icon-app-delete-back',
  67 + 'icon-app-door',
  68 + 'icon-app-earlywarning',
  69 + 'icon-app-entrance',
  70 + 'icon-app-exit',
  71 + 'icon-app-eye-close',
  72 + 'icon-app-filter-2',
  73 + 'icon-app-forbid-circle',
  74 + 'icon-app-grid-2',
  75 + 'icon-app-grid',
  76 + 'icon-app-key-1',
  77 + 'icon-app-lock',
  78 + 'icon-app-minus-circle',
  79 + 'icon-app-open-door',
  80 + 'icon-app-open',
  81 + 'icon-app-power',
  82 + 'icon-app-question',
  83 + 'icon-app-restore',
  84 + 'icon-app-setting-4',
  85 + 'icon-app-settings-1',
  86 + 'icon-app-settings-2',
  87 + 'icon-app-share-2',
  88 + 'icon-app-share-3',
  89 + 'icon-app-share-forward',
  90 + 'icon-app-shield-2',
  91 + 'icon-app-shield-3',
  92 + 'icon-app-shield-4',
  93 + 'icon-app-shield',
  94 + 'icon-app-smile',
  95 + 'icon-app-t-shirt',
  96 + 'icon-app-thumb-down',
  97 + 'icon-app-thumb-up',
  98 + 'icon-app-time',
  99 + 'icon-app-version',
  100 + 'icon-app-warning',
  101 + ],
  102 + device: [
  103 + 'icon-app-alarm-2',
  104 + 'icon-app-airplay',
  105 + 'icon-app-alarm-1',
  106 + 'icon-app-battery-charging',
  107 + 'icon-app-battery',
  108 + 'icon-app-bluetooth',
  109 + 'icon-app-bluetooth-off',
  110 + 'icon-app-bulb',
  111 + 'icon-app-ceiling-lamp',
  112 + 'icon-app-cellphone',
  113 + 'icon-app-cellphone-vibration',
  114 + 'icon-app-chip',
  115 + 'icon-app-computer-camera',
  116 + 'icon-app-computer',
  117 + 'icon-app-dashboaricon-app',
  118 + 'icon-app-desk-lamp',
  119 + 'icon-app-device',
  120 + 'icon-app-flash',
  121 + 'icon-app-fridge',
  122 + 'icon-app-laptop',
  123 + 'icon-app-microscope',
  124 + 'icon-app-paicon-app',
  125 + 'icon-app-plugin',
  126 + 'icon-app-print',
  127 + 'icon-app-qrcode',
  128 + 'icon-app-radar-2',
  129 + 'icon-app-radar',
  130 + 'icon-app-radio',
  131 + 'icon-app-sandglass',
  132 + 'icon-app-scan-2',
  133 + 'icon-app-scan',
  134 + 'icon-app-telescope',
  135 + 'icon-app-tv-1',
  136 + 'icon-app-tv-2',
  137 + 'icon-app-wifi',
  138 + 'icon-app-wifi-off',
  139 + ],
  140 + user: [
  141 + 'icon-app-user-1',
  142 + 'icon-app-user-2',
  143 + 'icon-app-user-4',
  144 + 'icon-app-user-5',
  145 + 'icon-app-badge',
  146 + 'icon-app-contacts',
  147 + 'icon-app-male',
  148 + 'icon-app-female',
  149 + 'icon-app-group',
  150 + 'icon-app-IDcard',
  151 + 'icon-app-user-add',
  152 + 'icon-app-user-follow',
  153 + 'icon-app-user-remove',
  154 + ],
  155 + business: [
  156 + 'icon-app-auction',
  157 + 'icon-app-award',
  158 + 'icon-app-bank-card',
  159 + 'icon-app-basket',
  160 + 'icon-app-block',
  161 + 'icon-app-calendar',
  162 + 'icon-app-chart-bar',
  163 + 'icon-app-chart-line',
  164 + 'icon-app-coin-2',
  165 + 'icon-app-coin',
  166 + 'icon-app-copper-coin',
  167 + 'icon-app-copyright',
  168 + 'icon-app-coupon',
  169 + 'icon-app-currency-bitcoin-2',
  170 + 'icon-app-currency-cny',
  171 + 'icon-app-currency-dollar',
  172 + 'icon-app-currency-euro',
  173 + 'icon-app-flag-1',
  174 + 'icon-app-flag-3',
  175 + 'icon-app-luggage',
  176 + 'icon-app-medal',
  177 + 'icon-app-presentation-2',
  178 + 'icon-app-red-packet',
  179 + 'icon-app-red-packet-open',
  180 + 'icon-app-safe-box',
  181 + 'icon-app-seal',
  182 + 'icon-app-shopping-bag-1',
  183 + 'icon-app-shopping-cart-2',
  184 + 'icon-app-tag',
  185 + 'icon-app-target',
  186 + 'icon-app-trophy',
  187 + 'icon-app-vip-1',
  188 + 'icon-app-vip-2',
  189 + 'icon-app-vip-3',
  190 + 'icon-app-wallet-2',
  191 + 'icon-app-wallet',
  192 + 'icon-app-service',
  193 + ],
  194 + building: [
  195 + 'icon-app-bridge',
  196 + 'icon-app-building-1',
  197 + 'icon-app-building-4',
  198 + 'icon-app-campground',
  199 + 'icon-app-factory',
  200 + 'icon-app-greatwall',
  201 + 'icon-app-home-1',
  202 + 'icon-app-home-2',
  203 + 'icon-app-home-3',
  204 + 'icon-app-home-4',
  205 + 'icon-app-lighthouse',
  206 + 'icon-app-monument',
  207 + 'icon-app-pavilon',
  208 + 'icon-app-store',
  209 + 'icon-app-tower',
  210 + ],
  211 + file: [
  212 + 'icon-app-attachment',
  213 + 'icon-app-box-2',
  214 + 'icon-app-box-3',
  215 + 'icon-app-box',
  216 + 'icon-app-clipboard',
  217 + 'icon-app-copy',
  218 + 'icon-app-docment',
  219 + 'icon-app-download-2',
  220 + 'icon-app-download',
  221 + 'icon-app-file-download',
  222 + 'icon-app-file-export',
  223 + 'icon-app-file',
  224 + 'icon-app-file-import',
  225 + 'icon-app-file-new',
  226 + 'icon-app-file-zip',
  227 + 'icon-app-folder-2',
  228 + 'icon-app-link-2',
  229 + 'icon-app-paper',
  230 + 'icon-app-pic',
  231 + 'icon-app-save',
  232 + 'icon-app-search-1',
  233 + 'icon-app-search',
  234 + 'icon-app-unlink-2',
  235 + 'icon-app-upload-2',
  236 + 'icon-app-upload-3',
  237 + 'icon-app-upload',
  238 + 'icon-app-zoom-in',
  239 + 'icon-app-zoom-out',
  240 + ],
  241 + education: [
  242 + 'icon-app-book-2',
  243 + 'icon-app-book-4',
  244 + 'icon-app-book-5',
  245 + 'icon-app-book',
  246 + 'icon-app-bookmark',
  247 + 'icon-app-desk',
  248 + 'icon-app-flask-2',
  249 + 'icon-app-flask',
  250 + 'icon-app-globe',
  251 + 'icon-app-mortarboard',
  252 + 'icon-app-science',
  253 + 'icon-app-diary',
  254 + ],
  255 + contact: [
  256 + 'icon-app-chat-1',
  257 + 'icon-app-chat-2',
  258 + 'icon-app-chat-3',
  259 + 'icon-app-invite',
  260 + 'icon-app-mail-send',
  261 + 'icon-app-message-1',
  262 + 'icon-app-message-2',
  263 + 'icon-app-message-4',
  264 + ],
  265 + transport: [
  266 + 'icon-app-airplane',
  267 + 'icon-app-baby-carriage',
  268 + 'icon-app-bus',
  269 + 'icon-app-car-2',
  270 + 'icon-app-charging-pilen',
  271 + 'icon-app-ebike',
  272 + 'icon-app-flighicon-app-land',
  273 + 'icon-app-flighicon-app-takeoff',
  274 + 'icon-app-gas-station',
  275 + 'icon-app-riding',
  276 + 'icon-app-run',
  277 + 'icon-app-scooter',
  278 + 'icon-app-ship',
  279 + 'icon-app-train-2',
  280 + 'icon-app-train',
  281 + 'icon-app-truck',
  282 + 'icon-app-ufo',
  283 + 'icon-app-walk',
  284 + ],
  285 + development: [
  286 + 'icon-app-braces',
  287 + 'icon-app-bug',
  288 + 'icon-app-code',
  289 + 'icon-app-cursor',
  290 + 'icon-app-department',
  291 + 'icon-app-directory',
  292 + 'icon-app-git-commit',
  293 + 'icon-app-git-compare',
  294 + 'icon-app-git-pull-request-close',
  295 + 'icon-app-git-pull-request',
  296 + 'icon-app-performance',
  297 + 'icon-app-terminal-box',
  298 + 'icon-app-terminal',
  299 + 'icon-app-web',
  300 + ],
  301 + design: [
  302 + 'icon-app-anticlockwise',
  303 + 'icon-app-bling',
  304 + 'icon-app-brightness',
  305 + 'icon-app-clockwise',
  306 + 'icon-app-color-filter',
  307 + 'icon-app-layout',
  308 + 'icon-app-mosaic',
  309 + 'icon-app-paint-2',
  310 + 'icon-app-palette-2',
  311 + 'icon-app-paster',
  312 + 'icon-app-quill-pen',
  313 + 'icon-app-ruler',
  314 + 'icon-app-scale',
  315 + 'icon-app-edit-3',
  316 + 'icon-app-tablicon-app',
  317 + ],
  318 + weather: [
  319 + 'icon-app-cloud-lightning',
  320 + 'icon-app-cloud-snoicon-app',
  321 + 'icon-app-lightning',
  322 + 'icon-app-moon-cloudy',
  323 + 'icon-app-moon',
  324 + 'icon-app-rain',
  325 + 'icon-app-sun-cloudy',
  326 + 'icon-app-sun',
  327 + 'icon-app-sunrise',
  328 + 'icon-app-sunset',
  329 + 'icon-app-thermometer',
  330 + 'icon-app-typhoon',
  331 + 'icon-app-umbrella',
  332 + 'icon-app-wind',
  333 + ],
  334 + logo: [
  335 + 'icon-app-alipay',
  336 + 'icon-app-android-2',
  337 + 'icon-app-android',
  338 + 'icon-app-apple',
  339 + 'icon-app-chrome',
  340 + 'icon-app-dingding',
  341 + 'icon-app-messenger',
  342 + 'icon-app-moment',
  343 + 'icon-app-qiyeweixin',
  344 + 'icon-app-telegram',
  345 + 'icon-app-wechat',
  346 + 'icon-app-windows',
  347 + ],
  348 + map: [
  349 + 'icon-app-compass',
  350 + 'icon-app-earth',
  351 + 'icon-app-location-2',
  352 + 'icon-app-map',
  353 + 'icon-app-navigation',
  354 + 'icon-app-route',
  355 + 'icon-app-world-2',
  356 + ],
  357 +};
  358 +
  359 +export const MAP_OLD_ICONS: any = {
  360 + 'icon-shiming': '',
  361 + 'icon-pingtai': '',
  362 + 'icon-feiji': '',
  363 + 'icon-hezuo': '',
  364 + 'icon-yinhang': '',
  365 + 'icon-wenjianbao': '',
  366 + 'icon-pailie': '',
  367 + 'icon-app-caigou': 'icon-app-shopping-cart-2-fill',
  368 + 'icon-app-qudao': 'icon-app-department-fill',
  369 + 'icon-app-renqun': 'icon-app-group-fill',
  370 + 'icon-app-kefu': 'icon-app-service-fill',
  371 + 'icon-app-anquan': 'icon-app-shield-3-fill',
  372 + 'icon-app-wangluo': '',
  373 + 'icon-app-pachong': '',
  374 + 'icon-app-hexin': 'icon-app-science-fill',
  375 + 'icon-app-erweima': 'icon-app-qrcode-fill',
  376 + 'icon-app-shujujiankong': 'icon-app-presentation-2-fill',
  377 + 'icon-app-xingneng': 'icon-app-chip-fill',
  378 + 'icon-app-jiankong': 'icon-app-computer-camera-fill',
  379 + 'icon-app-quanqiu': 'icon-app-world-2-fill',
  380 + 'icon-app-qizhi': 'icon-app-flag-1-fill',
  381 + 'icon-app-zhenshikexin': 'icon-app-certificate-fill',
  382 + 'icon-app-jiangzhang': 'icon-app-award-fill',
  383 + 'icon-app-daikuan': 'icon-app-wallet-2-fill',
  384 + 'icon-app-yusan': 'icon-app-umbrella-fill',
  385 + 'icon-app-xiajia': '',
  386 + 'icon-app-naozhong': 'icon-app-alarm-1-fill',
  387 + 'icon-app-mima': '',
  388 + 'icon-app-fangxiang': 'icon-app-dashboaricon-app-fill',
  389 + 'icon-app-zhouqi': 'icon-app-sandglass-fill',
  390 + 'icon-app-chaxun': 'icon-app-search-1-fill',
  391 + 'icon-app-qiye': 'icon-app-building-1-fill',
  392 + 'icon-app-qianyue': 'icon-app-quill-pen-fill',
  393 + 'icon-app-chanpin': 'icon-app-box-3-fill',
  394 + 'icon-app-APP': 'icon-app-cellphone-fill',
  395 + 'icon-app-fengkong': 'icon-app-shield-4-fill',
  396 + 'icon-app-tuisong': 'icon-app-mail-send-fill',
  397 + 'icon-app-yinzhang': 'icon-app-seal-fill',
  398 + 'icon-app-shouye': 'icon-app-home-4-fill',
  399 + 'icon-app-zhuti': '',
  400 + 'icon-app-yujing': '',
  401 + 'icon-app-zhanbi': '',
  402 + 'icon-app-bianji': 'icon-app-edit-3-fill',
  403 + 'icon-app-shanchu': '',
  404 + 'icon-app-yanzhengma': 'icon-app-shield-2-fill',
  405 + 'icon-app-dingwei': '',
  406 + 'icon-app-shuqian': 'icon-app-tag-fill',
  407 + 'icon-app-gaoxing': 'icon-app-smile-fill',
  408 + 'icon-app-xiangji': '',
  409 + 'icon-app-zhengzhaozhizhao': 'icon-app-IDcard-fill',
  410 + 'icon-app-jinbi': 'icon-app-coin-2-fill',
  411 + 'icon-app-suoxiao': '',
  412 + 'icon-app-bobei': 'icon-app-copper-coin-fill',
  413 + 'icon-app-huankuan': '',
  414 + 'icon-app-jiqiren': 'icon-app-android-fill',
  415 + 'icon-app-yuyin': '',
  416 + 'icon-app-toupiao': 'icon-app-invite-fill',
  417 + 'icon-app-qianbao': '',
  418 + 'icon-app-yuqi': '',
  419 + 'icon-app-yinhangka': '',
  420 + 'icon-app-wenjianjia': 'icon-app-folder-2-fill',
  421 + 'icon-app-wenjian': 'icon-app-file-fill',
  422 + 'icon-app-shujuku': 'icon-app-database-fill',
  423 + 'icon-app-tishi': '',
  424 + 'icon-app-tupian': '',
  425 + 'icon-app-sousuo': 'icon-app-search-fill',
  426 + 'icon-app-shuju': 'icon-app-performance-fill',
  427 + 'icon-app-shaixuan': '',
  428 + 'icon-app-shexiang': '',
  429 + 'icon-app-rizhi': 'icon-app-diary-fill',
  430 + 'icon-app-rili': 'icon-app-calendar-fill',
  431 + 'icon-app-renlianshibie': 'icon-app-user-4-fill',
  432 + 'icon-app-qukuai': 'icon-app-block-fill',
  433 + 'icon-app-quanwei': 'icon-app-user-5-fill',
  434 + 'icon-app-quanxian': '',
  435 + 'icon-app-jishufuwu': 'icon-app-terminal-box-fill',
  436 + 'icon-app-lunchuan': 'icon-app-ship-fill',
  437 + 'icon-app-mubiao': 'icon-app-target-fill',
  438 + 'icon-app-kaifang': 'icon-app-open-fill',
  439 + 'icon-app-qianbi': '',
  440 + 'icon-app-lianjie': '',
  441 + 'icon-app-piaoju': 'icon-app-coupon-fill',
  442 + 'icon-app-peizhi': 'icon-app-settings-2-fill',
  443 + 'icon-app-qiche': 'icon-app-car-2-fill',
  444 + 'icon-app-kaishi': '',
  445 + 'icon-app-biaoji': '',
  446 + 'icon-app-guanbituichu': 'icon-app-power-fill',
  447 + 'icon-app-diannao': 'icon-app-computer-fill',
  448 + 'icon-app-daichuli': 'icon-app-time-fill',
  449 + 'icon-app-jinggao': 'icon-app-alert-fill',
  450 + 'icon-app-huoche': 'icon-app-truck-fill',
  451 + 'icon-app-jieqing': 'icon-app-currency-cny-fill',
  452 + 'icon-app-huangguan': 'icon-app-vip-2-fill',
  453 + 'icon-app-gouwu': 'icon-app-shopping-bag-1-fill',
  454 + 'icon-app-dayin': '',
  455 + 'icon-app-fenxiang': 'icon-app-share-forward-fill',
  456 + 'icon-app-biaoge': 'icon-app-tablicon-app-fill',
  457 + 'icon-app-chulizhong': '',
  458 + 'icon-app-zanting': '',
  459 + 'icon-app-zuanshi': 'icon-app-vip-1-fill',
  460 +};
... ...
  1 +@import '~@qx/ui/src/style/variable.less';
  2 +
  3 +.qx-select-icon-container {
  4 + position: relative;
  5 + font-size: 0;
  6 +
  7 + .cover-icon,
  8 + .cover-img {
  9 + height: 48px;
  10 + width: 48px;
  11 + border-radius: 8px;
  12 +
  13 + &.cover-icon {
  14 + color: #ffffff;
  15 + background-color: @B8;
  16 +
  17 + svg {
  18 + width: 24px;
  19 + height: 24px;
  20 + margin: 12px;
  21 + }
  22 + }
  23 + }
  24 + .anticon-edit {
  25 + position: absolute;
  26 + top: 0;
  27 + left: 0;
  28 + display: none;
  29 + padding: 12px;
  30 + color: #fff;
  31 + font-size: 24px;
  32 + background-color: rgba(0, 0, 0, 0.6);
  33 + border-radius: 8px;
  34 + cursor: pointer;
  35 + }
  36 + &:hover {
  37 + .anticon-edit {
  38 + display: inline-block;
  39 + }
  40 + }
  41 +}
  42 +
  43 +.qx-icon-picker-overlay {
  44 + width: 490px;
  45 +
  46 + .ant-popover-inner {
  47 + border-radius: 8px;
  48 +
  49 + .ant-popover-inner-content {
  50 + color: rgba(0, 0, 0, 0.85);
  51 + }
  52 +
  53 + .ant-tabs-nav::before {
  54 + display: none;
  55 + }
  56 + .ant-tabs-tabpane {
  57 + display: flex;
  58 + flex-direction: column;
  59 + height: 336px;
  60 + }
  61 + .ant-tabs-tabpane-hidden {
  62 + display: none;
  63 + }
  64 + }
  65 +}
  66 +
  67 +.qx-select-custom-icons {
  68 + position: relative;
  69 + .block-color-box {
  70 + position: relative;
  71 + display: flex;
  72 + justify-content: space-between;
  73 + flex-wrap: nowrap;
  74 + padding-bottom: 16px;
  75 +
  76 + .block-color {
  77 + width: 32px;
  78 + height: 32px;
  79 + font-size: 16px;
  80 + text-align: center;
  81 + vertical-align: middle;
  82 + border-radius: 4px;
  83 + cursor: pointer;
  84 + &--default {
  85 + color: #fff;
  86 + background-color: @B8;
  87 + }
  88 + }
  89 + }
  90 + .anticon-check {
  91 + color: #fff;
  92 + vertical-align: middle;
  93 + }
  94 + .block-icon-box {
  95 + position: relative;
  96 + display: flex;
  97 + flex-direction: row;
  98 + height: 288px;
  99 +
  100 + &.height336 {
  101 + height: 336px;
  102 + }
  103 +
  104 + &::after {
  105 + content: '';
  106 + position: absolute;
  107 + top: 0;
  108 + left: -16px;
  109 + right: -16px;
  110 + height: 1px;
  111 + background-color: #e9e9ea;
  112 + }
  113 +
  114 + .icon-list {
  115 + position: relative;
  116 + height: 100%;
  117 + overflow: auto;
  118 + flex: 1;
  119 +
  120 + .icon-classify-label {
  121 + font-size: 12px;
  122 + color: #7c7e86;
  123 + line-height: 20px;
  124 + padding: 16px 0 12px;
  125 + }
  126 + .icon-classify-list {
  127 + display: flex;
  128 + flex-direction: row;
  129 + flex-wrap: wrap;
  130 +
  131 + .block-icon {
  132 + width: 12.5%;
  133 + height: 32px;
  134 + text-align: center;
  135 + cursor: pointer;
  136 +
  137 + .anticon {
  138 + height: 32px;
  139 + width: 32px;
  140 + border-radius: 4px;
  141 + padding-top: 6px;
  142 + box-sizing: border-box;
  143 + display: inline-block;
  144 +
  145 + &:hover {
  146 + background: @N3;
  147 + border-radius: 4px;
  148 + color: #50535d;
  149 + }
  150 +
  151 + svg {
  152 + width: 20px;
  153 + height: 20px;
  154 + }
  155 + }
  156 +
  157 + &--default {
  158 + color: #fff !important;
  159 + background-color: @B8 !important;
  160 + }
  161 + }
  162 + }
  163 + }
  164 + .icon-classify {
  165 + display: flex;
  166 + flex-direction: column;
  167 + width: 96px;
  168 + border-left: 1px solid #e9e9ea;
  169 + margin-right: -16px;
  170 + align-items: center;
  171 +
  172 + .classify-switch {
  173 + margin: 12px 0 16px;
  174 + }
  175 +
  176 + .classify-label-list {
  177 + flex: 1;
  178 + width: 100%;
  179 + overflow: auto;
  180 +
  181 + .classify-label {
  182 + font-size: 12px;
  183 + color: #50535d;
  184 + line-height: 24px;
  185 + width: 64px;
  186 + margin: 4px auto;
  187 + text-align: center;
  188 + cursor: pointer;
  189 +
  190 + &:hover {
  191 + background: @N3;
  192 + border-radius: 4px;
  193 + color: #50535d;
  194 + }
  195 + &.active {
  196 + position: relative;
  197 + color: @B8;
  198 + background-color: @B3;
  199 + border-radius: 4px;
  200 + }
  201 + &:first-child {
  202 + margin-top: 0;
  203 + }
  204 + &:last-child {
  205 + margin-bottom: 0;
  206 + }
  207 + }
  208 + }
  209 + }
  210 + }
  211 + .custom-icon-box {
  212 + display: flex;
  213 + flex-direction: row;
  214 + overflow: auto;
  215 + height: 336px;
  216 + justify-content: flex-start;
  217 + align-content: flex-start;
  218 + flex-wrap: wrap;
  219 + padding-top: 10px;
  220 +
  221 + .custom-icon-item {
  222 + width: 12.5%;
  223 +
  224 + .qx-custom-preview {
  225 + position: relative;
  226 + width: 40px;
  227 + height: 40px;
  228 + margin: 0 10px 10px 0;
  229 + padding: 6px 0;
  230 + text-align: center;
  231 + border: 1px solid #d9d9d9;
  232 + border-radius: 2px;
  233 + box-sizing: border-box;
  234 +
  235 + &:hover {
  236 + cursor: pointer;
  237 +
  238 + .qx-custom-preview_text {
  239 + display: block;
  240 + }
  241 +
  242 + .qx-custom-preview_icon {
  243 + display: block;
  244 + cursor: pointer;
  245 + }
  246 + }
  247 +
  248 + &_icon {
  249 + position: absolute;
  250 + top: -6px;
  251 + right: -6px;
  252 + z-index: 9999;
  253 + display: none;
  254 + width: 14px;
  255 + height: 14px;
  256 + color: white;
  257 + line-height: 10px;
  258 + text-align: center;
  259 + background-color: rgb(207, 207, 207);
  260 + border-radius: 50%;
  261 + }
  262 + }
  263 +
  264 + .qx-custom-upload {
  265 + width: 40px !important;
  266 + margin: 0 10px 10px 0;
  267 +
  268 + .ant-upload.ant-upload-select {
  269 + display: flex;
  270 + align-items: center;
  271 + justify-content: center;
  272 + width: 40px;
  273 + height: 40px;
  274 + border: 1px solid #d9d9d9;
  275 + border-radius: 2px;
  276 + cursor: pointer;
  277 +
  278 + .ant-upload {
  279 + width: 100%;
  280 + }
  281 +
  282 + img {
  283 + width: 24px;
  284 + height: 24px;
  285 + }
  286 + }
  287 + }
  288 + }
  289 + }
  290 +}
  291 +
  292 +.qx-select-custom-desc-icon-wrap {
  293 + position: relative;
  294 +
  295 + .custom-desc-icon {
  296 + position: absolute;
  297 + top: 50%;
  298 + transform: translateY(-50%);
  299 + color: @N7;
  300 + margin-left: 4px;
  301 + }
  302 +}
  303 +
... ...
  1 +### 选择icon
  2 +
  3 +###
  4 +
  5 +```tsx
  6 +import { request, QxIconSelector } from '@qx/common';
  7 +import React, { useState } from 'react';
  8 +
  9 +export default () => {
  10 + const [value, setValue] = useState({
  11 + showThemePicker: true,
  12 + iconColor: "#B81E51",
  13 + type : "icon-app-eye-close-fill"
  14 + });
  15 + return (
  16 + <QxIconSelector
  17 + value={value}
  18 + onChange={(values)=> {
  19 + console.log(values,'lllll')
  20 + setValue(values)
  21 + }}
  22 + />
  23 + );
  24 +};
  25 +```
  26 +
  27 +<API></API>
... ...
  1 +import React, { useEffect, useRef, useState } from 'react';
  2 +import defaultImg from './img/default_cover.png';
  3 +import classNames from 'classnames';
  4 +import _ from 'lodash';
  5 +import {
  6 + Image,
  7 + message,
  8 + Popconfirm,
  9 + Popover,
  10 + Spin,
  11 + Tabs,
  12 + Tooltip,
  13 + Upload,
  14 + Switch,
  15 +} from 'antd';
  16 +import {
  17 + CheckOutlined,
  18 + CloseOutlined,
  19 + EditOutlined,
  20 + PlusOutlined,
  21 + ExclamationCircleOutlined,
  22 +} from '@ant-design/icons';
  23 +import {
  24 + FORM_GROUP,
  25 + ICON_CLASSIFY,
  26 + BG_COLORS,
  27 + ICONS,
  28 + MAP_OLD_ICONS,
  29 +} from './enum';
  30 +import { deleteImg, getHistoryDataImg } from './service';
  31 +import './index.less';
  32 +import {QxBaseIcon, UploadFile} from "@qx/common";
  33 +
  34 +interface IconProps {
  35 + value: {
  36 + type: string; // icon图标标识或者是http的url
  37 + iconColor: string; // icon图标颜色
  38 + belongTo?: string;
  39 + showThemePicker?: boolean; // 是否展示主题选择模块
  40 + };
  41 + onChange: (value: {
  42 + type: string;
  43 + iconColor: string;
  44 + belongTo?: string;
  45 + showThemePicker: boolean | undefined;
  46 + }) => void;
  47 +}
  48 +export const QxIconSelector: React.FC<IconProps> = (props) => {
  49 + const { value, onChange } = props;
  50 + const { iconColor, belongTo, showThemePicker } = value || {};
  51 +
  52 + const defaultIcon =
  53 + (belongTo && FORM_GROUP[belongTo]) || 'icon-app-grid-2-fill';
  54 + const icon =
  55 + MAP_OLD_ICONS[value?.type] || // 映射老图标的标识
  56 + ((value?.type?.includes('http') || // 自定义图标http直接返回
  57 + !Object.keys(MAP_OLD_ICONS).includes(value?.type)) &&
  58 + value?.type) ||
  59 + defaultIcon; // 默认值
  60 + const [bgColor, setBgColor] = useState<string>('');
  61 + const [blockIcon, setBlockIcon] = useState<string>('');
  62 + const [iconType, setIconType] = useState<'system' | 'custom'>();
  63 + const [historyImg, setHistoryImg] = useState<any[]>([]);
  64 + const [getDataLoading, setGetDataLoading] = useState<boolean>(false);
  65 + const [uploading, setUploading] = useState<boolean>(false);
  66 + const [iconShape, setIconShape] = useState<'fill' | 'line'>('fill');
  67 + const [activeClassify, setActiveClassify] = useState<string>('');
  68 + const iconListRef = useRef<HTMLDivElement>(null);
  69 +
  70 + // 新增应用时传递初始icon
  71 + if (value && !value.type) {
  72 + onChange({
  73 + type: icon,
  74 + iconColor: iconColor,
  75 + belongTo,
  76 + showThemePicker,
  77 + });
  78 + }
  79 +
  80 + const findClassifyByIcon = (icon: string) => {
  81 + const splitIcon = icon?.split('-') || [];
  82 + splitIcon.pop();
  83 + const joinIcon = splitIcon.join('-');
  84 + return (
  85 + Object.keys(ICONS).find((cfy) => ICONS[cfy].includes(joinIcon)) || ''
  86 + );
  87 + };
  88 +
  89 + const scrollIntoView = (dom: HTMLElement, params: any = {}) => {
  90 + dom.scrollIntoView(
  91 + Object.assign({ block: 'start', inline: 'nearest' }, params),
  92 + );
  93 + };
  94 +
  95 + useEffect(() => {
  96 + setBlockIcon(icon);
  97 + setBgColor(iconColor || '');
  98 + setIconType(icon?.includes('http') ? 'custom' : 'system');
  99 + setIconShape(icon?.split('-').pop() === 'line' ? 'line' : 'fill');
  100 + }, [icon, iconColor]);
  101 +
  102 + useEffect(() => {
  103 + const cfy = findClassifyByIcon(icon);
  104 + setActiveClassify(cfy);
  105 + }, []);
  106 +
  107 + const onClickPopover = () => {
  108 + setTimeout(() => {
  109 + const cfy = findClassifyByIcon(blockIcon);
  110 + const iconItemDom: any = document.querySelector(
  111 + `div[icon-name=${blockIcon}]`,
  112 + );
  113 + // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  114 + iconItemDom && scrollIntoView(iconItemDom);
  115 + setTimeout(() => {
  116 + // 恢复icon滚动副作用
  117 + const iconCfyDOm: any = document.getElementById(
  118 + `qx-icon-classify-${cfy}`,
  119 + );
  120 + setActiveClassify(cfy);
  121 + // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  122 + iconCfyDOm && scrollIntoView(iconCfyDOm, { block: 'center' });
  123 + }, 1000);
  124 + }, 500);
  125 + };
  126 +
  127 + const onTabsChange = async (key: string) => {
  128 + if (key === 'custom') {
  129 + //获取历史上传的数据
  130 + try {
  131 + setGetDataLoading(true);
  132 + const res = await getHistoryDataImg({
  133 + appCode: 'my_icon',
  134 + funCode: 'my_icon',
  135 + mediaType: 'img',
  136 + });
  137 + setHistoryImg(res.list || []);
  138 + setGetDataLoading(false);
  139 + } catch (e) {
  140 + setHistoryImg([]);
  141 + setGetDataLoading(false);
  142 + }
  143 + }
  144 + };
  145 +
  146 + const onIconShapeChange = (checked: boolean) => {
  147 + setIconShape(checked ? 'line' : 'fill');
  148 + const icon = blockIcon?.split('-');
  149 + icon.pop();
  150 + icon.push(checked ? 'line' : 'fill');
  151 + onChange({
  152 + type: icon.join('-'),
  153 + iconColor: bgColor,
  154 + belongTo,
  155 + showThemePicker,
  156 + });
  157 + };
  158 +
  159 + const onScrollIconList = _.throttle(
  160 + () => {
  161 + Object.keys(ICONS).forEach((cfy) => {
  162 + const iconItemDom: any = document.getElementById(`qx-icon-list-${cfy}`);
  163 + const distance = Math.abs(
  164 + iconItemDom?.offsetTop - (iconListRef.current?.scrollTop || 0),
  165 + );
  166 + if (distance < 40) {
  167 + const iconCfyDOm: any = document.getElementById(
  168 + `qx-icon-classify-${cfy}`,
  169 + );
  170 + scrollIntoView(iconCfyDOm, { block: 'center' });
  171 + setActiveClassify(cfy);
  172 + }
  173 + });
  174 + },
  175 + 30,
  176 + { leading: false },
  177 + );
  178 +
  179 + const onSelectClassify = (cfy: string) => {
  180 + setActiveClassify(cfy);
  181 + const iconItemDom: any = document.getElementById(`qx-icon-list-${cfy}`);
  182 + scrollIntoView(iconItemDom);
  183 + // window.scrollTo({ top: iconItemDom.offsetTop, behavior: 'smooth' });
  184 + };
  185 +
  186 + const handleUpload = (file: any) => {
  187 + // console.log('文件对象:',file);
  188 + const imgArr = _.cloneDeep(historyImg);
  189 + const formData = {
  190 + file: 'file',
  191 + appCode: 'my_icon',
  192 + funCode: 'my_icon',
  193 + publicFile: true, //长期有效文件
  194 + };
  195 + UploadFile(
  196 + file,
  197 + formData,
  198 + () => {},
  199 + (cr: any) => {
  200 + // console.log('回调数据:',cr)
  201 + const thumbUrl = cr.data?.qgImg?.urlMap?.thumb;
  202 + if (Boolean(cr.success) && cr.data && cr.data.fileId && thumbUrl) {
  203 + // message.success('上传成功')
  204 + setIconType('custom');
  205 + setBlockIcon(thumbUrl);
  206 + onChange({
  207 + type: thumbUrl,
  208 + iconColor: bgColor,
  209 + belongTo,
  210 + showThemePicker,
  211 + });
  212 + setUploading(false);
  213 + imgArr.unshift(cr.data);
  214 + } else {
  215 + // 上传失败
  216 + message.error('上传失败');
  217 + }
  218 + setHistoryImg([...imgArr]);
  219 + },
  220 + );
  221 + };
  222 +
  223 + const beforeUpload = (file: any) => {
  224 + // console.log(file);
  225 + const fileType =
  226 + file.type === 'image/jpeg' ||
  227 + file.type === 'image/png' ||
  228 + file.type === 'image/jpg';
  229 + if (!fileType) {
  230 + message.error('请选择jpg或png或jpeg格式的文件');
  231 + }
  232 + const fileSize = file.size / 1024 / 1024 < 1;
  233 + if (!fileSize) {
  234 + message.error('请选择小于1MB的文件');
  235 + }
  236 + if (fileType && fileSize) {
  237 + //如果文件符合上传条件
  238 + setUploading(true);
  239 + handleUpload(file);
  240 + }
  241 + };
  242 +
  243 + const handleDelete = async (fileId: string, index: number) => {
  244 + const imgArr = _.cloneDeep(historyImg);
  245 + await deleteImg([fileId]);
  246 + imgArr.splice(index, 1);
  247 + setHistoryImg([...imgArr]);
  248 + };
  249 +
  250 + const renderContent = () => {
  251 + return (
  252 + <div className={'qx-select-custom-icons'}>
  253 + <Tabs
  254 + defaultActiveKey={'system'}
  255 + centered
  256 + tabBarGutter={60}
  257 + onChange={onTabsChange}
  258 + >
  259 + <Tabs.TabPane tab="系统图标" key="system">
  260 + {showThemePicker ? (
  261 + <div className="block-color-box">
  262 + {/* 系统默认颜色 */}
  263 + <div
  264 + className={'block-color block-color--default'}
  265 + onClick={() => {
  266 + onChange({
  267 + type: blockIcon,
  268 + iconColor: '',
  269 + belongTo,
  270 + showThemePicker,
  271 + });
  272 + }}
  273 + >
  274 + {!bgColor && <CheckOutlined />}
  275 + </div>
  276 + {BG_COLORS.map((color: string) => {
  277 + return (
  278 + <div
  279 + key={color}
  280 + style={{ backgroundColor: color }}
  281 + className={'block-color'}
  282 + onClick={() => {
  283 + onChange({
  284 + type: blockIcon,
  285 + iconColor: color,
  286 + belongTo,
  287 + showThemePicker,
  288 + });
  289 + }}
  290 + >
  291 + {color === bgColor && <CheckOutlined />}
  292 + </div>
  293 + );
  294 + })}
  295 + </div>
  296 + ) : null}
  297 + <div
  298 + className={classNames(
  299 + 'block-icon-box',
  300 + !showThemePicker && 'height336',
  301 + )}
  302 + >
  303 + <div
  304 + className="icon-list"
  305 + ref={iconListRef}
  306 + onScroll={onScrollIconList}
  307 + >
  308 + {Object.keys(ICONS).map((cfy) => {
  309 + return (
  310 + <div id={`qx-icon-list-${cfy}`} key={cfy}>
  311 + <div className="icon-classify-label">
  312 + {ICON_CLASSIFY[cfy]}
  313 + </div>
  314 + <div className="icon-classify-list">
  315 + {ICONS[cfy].map((item: string) => {
  316 + const icon = `${item}-${iconShape}`;
  317 + return (
  318 + <div
  319 + key={icon}
  320 + className={'block-icon'}
  321 + icon-name={icon}
  322 + >
  323 + <QxBaseIcon
  324 + type={icon}
  325 + onClick={() => {
  326 + onChange({
  327 + type: icon,
  328 + iconColor: bgColor,
  329 + belongTo,
  330 + showThemePicker,
  331 + });
  332 + const cfy = findClassifyByIcon(icon);
  333 + const iconCfyDOm: any =
  334 + document.getElementById(
  335 + `qx-icon-classify-${cfy}`,
  336 + );
  337 + scrollIntoView(iconCfyDOm, {
  338 + block: 'center',
  339 + });
  340 + setActiveClassify(cfy);
  341 + }}
  342 + style={{
  343 + color:
  344 + bgColor && icon === blockIcon
  345 + ? '#fff'
  346 + : 'rgba(0, 0, 0, 0.45)',
  347 + backgroundColor:
  348 + icon === blockIcon ? bgColor : '',
  349 + }}
  350 + className={classNames({
  351 + 'block-icon--default':
  352 + icon === blockIcon && !bgColor,
  353 + })}
  354 + />
  355 + </div>
  356 + );
  357 + })}
  358 + </div>
  359 + </div>
  360 + );
  361 + })}
  362 + </div>
  363 + <div className="icon-classify">
  364 + <Switch
  365 + checked={iconShape === 'line' ? true : false}
  366 + className="classify-switch"
  367 + checkedChildren="线性"
  368 + unCheckedChildren="面性"
  369 + onChange={onIconShapeChange}
  370 + />
  371 + <div className="classify-label-list">
  372 + {Object.keys(ICONS).map((cfy) => {
  373 + return (
  374 + <div
  375 + id={`qx-icon-classify-${cfy}`}
  376 + className={classNames(
  377 + 'classify-label',
  378 + activeClassify === cfy && 'active',
  379 + )}
  380 + key={cfy}
  381 + onClick={() => onSelectClassify(cfy)}
  382 + >
  383 + {ICON_CLASSIFY[cfy]}
  384 + </div>
  385 + );
  386 + })}
  387 + </div>
  388 + </div>
  389 + </div>
  390 + </Tabs.TabPane>
  391 + <Tabs.TabPane
  392 + tab={
  393 + <div className="qx-select-custom-desc-icon-wrap">
  394 + 自定义图标&ensp;
  395 + <Tooltip
  396 + title={
  397 + '请选择1MB以内的jpg、jpeg或png图片,建议尺寸144*144像素'
  398 + }
  399 + color="#ffffff"
  400 + overlayStyle={{ maxWidth: '240px' }}
  401 + overlayInnerStyle={{
  402 + fontSize: '14px',
  403 + color: '#50535D',
  404 + textAlign: 'justify',
  405 + lineHeight: '22px',
  406 + }}
  407 + placement={'right'}
  408 + >
  409 + <ExclamationCircleOutlined className="custom-desc-icon" />
  410 + </Tooltip>
  411 + </div>
  412 + }
  413 + key="custom"
  414 + >
  415 + <Spin spinning={getDataLoading} style={{ top: '70px' }}>
  416 + <div className="custom-icon-box">
  417 + <div className="custom-icon-item">
  418 + <Upload
  419 + name="icon"
  420 + listType="picture-card"
  421 + accept=".jpg,.png"
  422 + maxCount={1}
  423 + showUploadList={false}
  424 + beforeUpload={beforeUpload}
  425 + className={'qx-custom-upload'}
  426 + >
  427 + <PlusOutlined />
  428 + </Upload>
  429 + </div>
  430 + {historyImg && historyImg.length ? (
  431 + <>
  432 + <div
  433 + style={{
  434 + height: '40px',
  435 + width: '40px',
  436 + textAlign: 'center',
  437 + paddingTop: '10px',
  438 + display: uploading ? '' : 'none',
  439 + margin: '0 10px 10px 0',
  440 + }}
  441 + >
  442 + <Spin tip={''} size={'small'} spinning={true} />
  443 + </div>
  444 + {/*<Image.PreviewGroup>*/}
  445 + {historyImg.map((item: any, index: number) => {
  446 + return (
  447 + <div className="custom-icon-item" key={index}>
  448 + <div className={'qx-custom-preview'}>
  449 + <Popconfirm
  450 + title={`确定要删除这张图片吗?`}
  451 + okText="确定"
  452 + cancelText="取消"
  453 + onConfirm={() => handleDelete(item.fileId, index)}
  454 + >
  455 + <div className={'qx-custom-preview_icon'}>
  456 + <CloseOutlined style={{ fontSize: '8px' }} />
  457 + </div>
  458 + </Popconfirm>
  459 + <Image
  460 + src={item?.qgImg?.urlMap?.thumb || 'error'}
  461 + fallback={defaultImg}
  462 + preview={false}
  463 + style={{ width: '24px', height: '24px' }}
  464 + onClick={() => {
  465 + setBlockIcon(item?.qgImg?.urlMap?.thumb);
  466 + setIconType('custom');
  467 + onChange({
  468 + type: item?.qgImg?.urlMap?.thumb,
  469 + iconColor: bgColor,
  470 + belongTo,
  471 + showThemePicker,
  472 + });
  473 + }}
  474 + />
  475 + </div>
  476 + </div>
  477 + );
  478 + })}
  479 + {/*</Image.PreviewGroup>*/}
  480 + </>
  481 + ) : null}
  482 + </div>
  483 + </Spin>
  484 + </Tabs.TabPane>
  485 + </Tabs>
  486 + </div>
  487 + );
  488 + };
  489 + return (
  490 + <div className="qx-select-icon-container" style={{ width: 'auto' }}>
  491 + <Popover
  492 + content={renderContent}
  493 + placement="right"
  494 + trigger="click"
  495 + overlayClassName={'qx-icon-picker-overlay'}
  496 + onOpenChange={onClickPopover}
  497 + // getPopupContainer={(triggerNode) => triggerNode} // 图标不跟随标签
  498 + >
  499 + {iconType === 'custom' ? (
  500 + <Image
  501 + className="cover-img"
  502 + src={blockIcon || 'error'}
  503 + fallback={defaultImg}
  504 + preview={false}
  505 + />
  506 + ) : (
  507 + <QxBaseIcon
  508 + className="cover-icon default__icon"
  509 + type={blockIcon}
  510 + style={{ backgroundColor: bgColor }}
  511 + />
  512 + )}
  513 + <EditOutlined />
  514 + </Popover>
  515 + </div>
  516 + );
  517 +};
... ...
  1 +import { request } from '@qx/common';
  2 +
  3 +// 获取用户上传的历史图片
  4 +export function getHistoryDataImg(params: any) {
  5 + return request.post(
  6 + `/qgyun-service-fs-manager/file/page?pageNum=1&pageSize=200&source=LowCode`,
  7 + {
  8 + data: params,
  9 + },
  10 + );
  11 +}
  12 +
  13 +// 删除图片(可以批量操作)
  14 +export function deleteImg(params: any) {
  15 + return request.post(`/qgyun-service-fs-manager/file/status/disable`, {
  16 + data: params,
  17 + });
  18 +}
... ...
1 1 import { createRequest } from '@qx/utils';
2   -export const request = createRequest();
  2 +import UploadFile from './uploadFile'
  3 +
  4 +const request = createRequest();
  5 +export {UploadFile, request}
3 6
... ...
  1 +import { QxUploadCore, deleteUploadFile as deleteFile } from '@qx/utils'; // 晴晴抽出
  2 +import { createRequest } from '@qx/utils';
  3 +const request = createRequest()
  4 +
  5 +const UploadFile = (
  6 + file: any,
  7 + formData: any,
  8 + progress: any,
  9 + callback?: any,
  10 + extraHandle?: {
  11 + FileDoneList?: any;
  12 + deleteTempList?: () => void;
  13 + existMsg?: string;
  14 + },
  15 + maxCount?: number,
  16 +) => {
  17 + QxUploadCore(
  18 + request,
  19 + file,
  20 + formData,
  21 + () => {},
  22 + callback,
  23 + extraHandle,
  24 + maxCount,
  25 + );
  26 +};
  27 +export default UploadFile;
  28 +
  29 +export { deleteFile };
... ...