@mui/icons-material#Search TypeScript Examples

The following examples show how to use @mui/icons-material#Search. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: input.tsx    From Search-Next with GNU General Public License v3.0 6 votes vote down vote up
Input: FC<InputProps> = (props) => {
  const { inputBoxRef, inputRef, handleBtnClick, ...rest } = props;
  const { t } = useTranslation();

  return (
    <div
      ref={inputBoxRef}
      className="flex justify-center items-center rounded-md shadow-xl overflow-hidden"
    >
      <input
        className="py-2 px-4 border-none leading-4 sm:leading-7 outline-none flex-grow rounded-tr-none rounded-br-none placeholder-gray-400 focus:placeholder-gray-200 transition-all"
        type="text"
        ref={inputRef}
        {...rest}
      />
      <Button
        className="w-16 sm:w-24 rounded-tl-none flex gap-2 items-center justify-center whitespace-nowrap leading-4 sm:leading-7 text-center tracking-widest rounded-bl-none bg-primary text-white"
        size="large"
        variant="contained"
        disableElevation
        onClick={handleBtnClick}
      >
        <Search />
        {t('sou-suo')}
      </Button>
    </div>
  );
}
Example #2
Source File: searchInput.tsx    From Search-Next with GNU General Public License v3.0 6 votes vote down vote up
function SearchInput() {
  return (
    <Paper
      component="form"
      sx={{ p: '2px 4px', display: 'flex', alignItems: 'center', width: 400 }}
    >
      <IconButton sx={{ p: '10px' }} aria-label="menu">
        <Menu />
      </IconButton>
      <InputBase
        sx={{ ml: 1, flex: 1 }}
        placeholder="Search Google Maps"
        inputProps={{ 'aria-label': 'search google maps' }}
      />
      <IconButton type="submit" sx={{ p: '10px' }} aria-label="search">
        <Search />
      </IconButton>
    </Paper>
  );
}
Example #3
Source File: PlayerList.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Players: React.FC = () => {
  const his = useHistory()
  const plugin = usePlugin()
  const [page, setPage] = useState(0)
  const [loading, setLoading] = useState(true)
  const [state, setState] = useState<number | null>(null)
  const [activedPlayer, setActivedPlayer] = useState<PlayerData | null>(null)
  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
  const [data, setData] = useState<{ count: number, players: PlayerData[] }>(() => ({ count: 0, players: [] }))
  const globalData = useGlobalData()
  const { hasWhitelist } = globalData
  const refresh = () => {
    setLoading(true)
    plugin.emit('playerList:fetchPage', (it: any) => {
      if (it.players == null) it.players = []
      setData(it)
      setLoading(false)
    }, page, state === 1 || state === 2 ? state : 0, null)
  }
  useMemo(refresh, [page, state])
  const close = () => {
    setAnchorEl(null)
    setActivedPlayer(null)
  }

  return <Card>
    <CardHeader
      title={lang.playerList.title}
      action={
        <ToggleButtonGroup
          size='small'
          color={(state === 1 ? 'warning' : state === 2 ? 'error' : undefined) as any}
          value={state}
          exclusive
          onChange={(_, it) => {
            if (it === 3) return
            setState(it)
            if (state === 3) refresh()
          }}
        >
          <ToggleButton disabled={loading} value={1}><Star /></ToggleButton>
          <ToggleButton disabled={loading} value={2}><Block /></ToggleButton>
          <ToggleButton disabled={loading} value={3} onClick={() => state !== 3 && dialog(lang.playerList.nameToSearch, lang.username)
            .then(filter => {
              if (filter == null) return
              his.push('/NekoMaid/playerList/' + filter)
              setState(3)
              setLoading(true)
              plugin.emit('playerList:fetchPage', (it: any) => {
                if (it.players == null) it.players = []
                setPage(0)
                setData(it)
                setLoading(false)
              }, page, 0, filter.toLowerCase())
            })}><Search /></ToggleButton>
        </ToggleButtonGroup>
      }
    />
    <Divider />
    <Box sx={{ position: 'relative' }}>
      <CircularLoading loading={loading} />
      <TableContainer>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell padding='checkbox' />
              <TableCell>{lang.username}</TableCell>
              <TableCell align='right'>{minecraft['stat.minecraft.play_time']}</TableCell>
              <TableCell align='right'>{lang.playerList.lastPlay}</TableCell>
              <TableCell align='right'>{lang.operations}</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data.players.map(it => <TableRow key={it.name}>
              <TableCell sx={{ cursor: 'pointer', padding: theme => theme.spacing(1, 1, 1, 2) }} onClick={() => his.push('/NekoMaid/playerList/' + it.name)}>
                <Avatar src={getSkin(globalData, it.name, true)} imgProps={{ crossOrigin: 'anonymous', style: { width: 40, height: 40 } }} variant='rounded' />
              </TableCell>
              <TableCell>{it.name}</TableCell>
              <TableCell align='right'>{dayjs.duration(it.playTime / 20, 'seconds').humanize()}</TableCell>
              <TableCell align='right'>{dayjs(it.lastOnline).fromNow()}</TableCell>
              <TableCell align='right'>
                {(state === 1 || hasWhitelist) && <Tooltip title={lang.playerList[it.whitelisted ? 'clickToRemoveWhitelist' : 'clickToAddWhitelist']}>
                  <IconButton onClick={() => whitelist(it.name, plugin, refresh, !it.whitelisted)}>
                    {it.whitelisted ? <Star color='warning' /> : <StarBorder />}
                  </IconButton>
                </Tooltip>}
                <Tooltip title={it.ban == null ? lang.playerList.clickToBan : lang.playerList.banned + ': ' + it.ban}>
                  <IconButton onClick={() => banPlayer(it.name, plugin, refresh, it.ban == null)}>
                    <Block color={it.ban == null ? undefined : 'error'} />
                  </IconButton>
                </Tooltip>
                {actions.length
                  ? <IconButton onClick={e => {
                    setActivedPlayer(anchorEl ? null : it)
                    setAnchorEl(anchorEl ? null : e.currentTarget)
                  }}><MoreHoriz /></IconButton>
                  : null}
              </TableCell>
            </TableRow>)}
          </TableBody>
        </Table>
      </TableContainer>
      <TablePagination
        rowsPerPageOptions={[]}
        component='div'
        count={data.count}
        rowsPerPage={10}
        page={page}
        onPageChange={(_, it) => !loading && setPage(it)}
      />
    </Box>
    <Menu
      anchorEl={anchorEl}
      open={Boolean(anchorEl)}
      onClose={() => setAnchorEl(null)}
    >{actions.map((It, i) => <It key={i} onClose={close} player={activedPlayer} />)}</Menu>
  </Card>
}
Example #4
Source File: Vault.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Vault: React.FC = () => {
  const his = useHistory()
  const plugin = usePlugin()
  const globalData = useGlobalData()
  const { hasVaultPermission, hasVaultChat, vaultEconomy, hasVaultGroups } = globalData
  const [players, setPlayers] = useState<PlayerInfo[]>([])
  const [count, setCount] = useState(-1)
  const [page, setPage] = useState(0)
  const [sortModel, setSortModel] = useState<GridSortItem[]>([])
  const [groups, setGroups] = useState<GroupInfo[]>([])
  const [selectedId, setSelectedId] = useState<string | undefined>()
  const [selectedPlayer, setSelectedPlayer] = useState<string | undefined>()
  const [isGroup, setIsGroup] = useState(false)
  const balanceSort = sortModel[0]?.sort
  const refresh = (res?: boolean) => {
    if (res != null) action(res)
    setCount(-1)
    plugin.emit('vault:fetch', (a, b) => {
      setCount(a)
      setPlayers(b)
    }, page, balanceSort)
  }
  useEffect(refresh, [page, balanceSort])
  useEffect(() => { plugin.emit('vault:fetchGroups', setGroups) }, [])

  const columns: any[] = [
    {
      field: '',
      sortable: false,
      width: 60,
      renderCell: (it: GridCellParams) => <Avatar
        src={getSkin(globalData, it.id, true)}
        imgProps={{ crossOrigin: 'anonymous', onClick () { his.push('/NekoMaid/playerList/' + it.id) }, style: { width: 40, height: 40 } }}
        variant='rounded'
        sx={{ cursor: 'pointer' }}
      />
    },
    {
      field: 'id',
      headerName: lang.username,
      sortable: false,
      width: 200
    }
  ]
  const columns2: any[] = [
    {
      field: 'id',
      headerName: lang.vault.groupName,
      sortable: false,
      width: 160
    }
  ]

  if (hasVaultGroups) {
    columns.push({
      field: 'group',
      headerName: lang.vault.defaultGroup,
      width: 110,
      sortable: false
    })
  }
  if (hasVaultChat) {
    const a = {
      field: 'prefix',
      headerName: lang.vault.prefix,
      width: 110,
      editable: true,
      sortable: false
    }
    const b = {
      field: 'suffix',
      headerName: lang.vault.suffix,
      width: 110,
      editable: true,
      sortable: false
    }
    columns.push(a, b)
    columns2.push(a, b)
  }
  if (vaultEconomy) {
    columns.push({
      field: 'balance',
      headerName: lang.vault.balance,
      editable: true,
      width: 110,
      valueFormatter: ({ value }: any) => (value === 0 || value === 1 ? vaultEconomy.singular : vaultEconomy.plural) +
        (vaultEconomy.digits === -1 ? value : value.toFixed(vaultEconomy.digits))
    })
  }
  if (hasVaultPermission) {
    columns.push({
      field: '_',
      headerName: lang.operations,
      width: 88,
      sortable: false,
      renderCell: (it: GridCellParams) => <>
        {hasVaultGroups && <Tooltip title={lang.vault.managePermissionGroup}>
          <IconButton onClick={() => setSelectedPlayer(it.id as any)} size='small'><GroupsIcon /></IconButton>
        </Tooltip>}
        <Tooltip title={lang.vault.managePermission}><IconButton onClick={() => {
          setSelectedId(it.id as any)
          setIsGroup(false)
        }} size='small'><ListIcon /></IconButton></Tooltip>
      </>
    })
    if (hasVaultGroups) {
      columns2.push({
        field: '_',
        headerName: lang.operations,
        width: 66,
        sortable: false,
        renderCell: (it: GridCellParams) => <Tooltip title={lang.vault.managePermission}><IconButton onClick={() => {
          setSelectedId(it.id as any)
          setIsGroup(true)
        }} size='small'><ListIcon /></IconButton></Tooltip>
      })
    }
  }

  const playerList = <Card>
    <CardHeader
      title={lang.playerList.title}
      action={<IconButton onClick={() => dialog(lang.playerList.nameToSearch, lang.username).then(filter => {
        if (!filter) return refresh()
        setCount(-1)
        plugin.emit('vault:fetch', (a, b) => {
          setCount(a)
          setPlayers(b)
          success()
        }, page, sortModel.find(it => it.field === 'balance'), filter.toLowerCase())
      })}
    ><Search /></IconButton>} />
    <Divider />
    <div style={{ height: 594, width: '100%' }}>
      <DataGrid
        pagination
        disableColumnMenu
        hideFooterSelectedRowCount
        rows={players}
        columns={columns}
        pageSize={10}
        rowCount={count === -1 ? 0 : count}
        loading={count === -1}
        onPageChange={setPage}
        paginationMode='server'
        sortingMode='server'
        sortModel={sortModel}
        onSortModelChange={it => !isEqual(sortModel, it) && setSortModel(it)}
        onCellEditCommit={({ field, id, value }) => {
          let flag = false
          switch (field) {
            case 'balance':
              if (isNaN(+value!)) refresh()
              else plugin.emit('vault:setBalance', refresh, id, +value!)
              break
            case 'prefix': flag = true
            // eslint-disable-next-line no-fallthrough
            case 'suffix':
              plugin.emit('vault:setChat', refresh, id, false, flag, value || null)
          }
        }}
      />
    </div>
  </Card>

  return <Box sx={{ minHeight: '100%', py: 3, '& .MuiDataGrid-root': { border: 'none' } }}>
    <Toolbar />
    <Container maxWidth={false}>
      {hasVaultGroups
        ? <Grid container spacing={3}>
        <Grid item lg={8} md={12} xl={8} xs={12}>{playerList}</Grid>
        <Grid item lg={4} md={12} xl={4} xs={12}>
          <Card>
            <CardHeader title={lang.vault.permissionGroup} />
            <Divider />
            <div style={{ height: 594, width: '100%' }}>
              <DataGrid
                hideFooter
                disableColumnMenu
                rows={groups}
                columns={columns2}
                onCellEditCommit={({ field, id, value }) => {
                  let flag = false
                  switch (field) {
                    case 'prefix': flag = true
                    // eslint-disable-next-line no-fallthrough
                    case 'suffix':
                      plugin.emit('vault:setChat', (res: boolean) => {
                        action(res)
                        plugin.emit('vault:fetchGroups', setGroups)
                      }, id, true, flag, value || null)
                  }
                }}
              />
            </div>
          </Card>
        </Grid>
        </Grid>
        : playerList}
    </Container>
    <PermissionDialog plugin={plugin} id={selectedId} onClose={() => setSelectedId(undefined)} isGroup={isGroup} />
    {hasVaultGroups && <Groups plugin={plugin} id={selectedPlayer} onClose={() => setSelectedPlayer(undefined)} groups={groups} />}
  </Box>
}
Example #5
Source File: router.tsx    From Search-Next with GNU General Public License v3.0 4 votes vote down vote up
routers: Router[] = [
  {
    path: '/',
    title: '首页',
    component: lazy(() => import('@pages/index')),
  },
  {
    path: 'navigation/:classify',
    title: '导航',
    component: lazy(() => import('@pages/navigation')),
  },
  {
    path: 'setting',
    title: '设置',
    exact: false,
    component: SettingPage,
    routes: [
      {
        title: '账户',
        path: 'auth',
        component: Auth,
        routes: [
          {
            title: '账户信息',
            icon: <ManageAccounts />,
            path: 'info',
            component: Info,
          },
          {
            title: '其他账户',
            icon: <SupervisorAccount />,
            path: 'others',
            component: Others,
          },
        ],
      },
      {
        title: '个性化',
        path: 'personalise',
        component: Personalise,
        routes: [
          {
            title: '背景',
            icon: <PhotoLibrary />,
            path: 'background',
            component: Background,
          },
          {
            title: 'Logo',
            icon: <Brush />,
            path: 'logo',
            component: Logo,
          },
          {
            title: '主题',
            icon: <ColorLens />,
            path: 'theme',
            component: Theme,
          },
        ],
      },
      {
        title: '功能',
        icon: <FeaturedPlayList />,
        path: 'features',
        component: Features,
        routes: [
          {
            title: '导航页',
            icon: <NavigationIcon />,
            path: 'navigation',
            component: Navigation,
          },
          {
            title: '通知与消息',
            icon: <MessageIcon />,
            path: 'message',
            component: Message,
            routes: [
              {
                title: '版本更新',
                icon: <NewReleases />,
                path: 'release',
                component: ReleasesView,
              },
            ],
          },
        ],
      },
      {
        title: '数据',
        path: 'data',
        component: Data,
        routes: [
          {
            title: '备份与恢复',
            icon: <SettingsBackupRestore />,
            path: 'backup',
            component: Backup,
          },
        ],
      },
      {
        title: '实验室',
        path: 'lab',
        component: Lab,
        routes: [
          {
            title: '第三方API',
            icon: <Api />,
            path: 'otherApis',
            component: OtherApis,
          },
          {
            title: '搜索引擎',
            icon: <Search />,
            path: 'search-engine',
            component: Engine,
            routes: [
              {
                title: '搜索引擎详情',
                icon: <Search />,
                path: 'engine-detail/:id',
                component: EngineDetail,
              },
            ],
          },
          {
            title: '天气',
            icon: <WbSunny />,
            path: 'weather',
            component: Weather,
            status: 'process',
          },
          {
            title: '搜索框',
            icon: <Search />,
            path: 'search-bar',
            component: SearchBar,
            status: 'process',
          },
        ],
      },
      {
        title: '关于',
        path: 'about',
        component: About,
        routes: [
          {
            title: '历史版本记录',
            icon: <Update />,
            path: 'releases',
            component: Releases,
          },
          {
            title: '历史提交记录',
            icon: <Update />,
            path: 'commits',
            component: Commits,
          },
          {
            title: '用户体验计划',
            icon: <BugReportOutlined />,
            path: 'beta',
            component: Beta,
          },
          {
            title: '项目依赖',
            icon: <FolderOutlined />,
            path: 'dependencies',
            component: Dependencies,
          },
        ],
      },
    ],
  },
  {
    path: '/help/:text',
    title: '帮助',
    component: lazy(() => import('@pages/help')),
  },
]
Example #6
Source File: index.tsx    From Search-Next with GNU General Public License v3.0 4 votes vote down vote up
navigations: Navigation[] = [
  {
    id: 'aa4c4b672c8a47d2b2289b60eb3c82b1',
    name: '社交',
    path: 'social',
    icon: <Group />,
    color: '',
    isShow: true,
    children: [
      {
        id: '4e1c3a03242b4361a22a4daf8ced88bf',
        name: '新浪微博',
        url: 'https://www.weibo.com/',
        intro: '随时随地发现新鲜事',
        icon: 'weibo',
        color: '#ff8140',
        isShow: true,
      },
      {
        id: '68178f885c7b44e78ddc0be67b478644',
        name: '百度贴吧',
        url: 'https://tieba.baidu.com/',
        intro: '全球领先的中文社区',
        icon: 'tieba',
        color: '#3385ff',
        isShow: true,
      },
      {
        id: '854c6ae11b334bdbb0cd6c71c8598533',
        name: '简书',
        url: 'https://www.jianshu.com/',
        intro: '创作你的创作',
        icon: 'jianshu',
        color: '#ea6f5a',
        isShow: true,
      },
      {
        id: 'f24d86cb6b9d44c5a2b9cf5bc7f4ee1e',
        name: '知乎',
        url: 'https://www.zhihu.com/',
        intro: '有问题,就会有答案',
        icon: 'zhihu',
        color: '#0084ff',
        isShow: true,
      },
      {
        id: '210638b8452c4163a34ea3b62f41ff51',
        name: 'Facebook',
        url: 'https://www.facebook.com/',
        intro: 'Facebook,讓你與親朋好友保持聯繫,隨時分享生活精彩點滴。',
        icon: 'facebook',
        color: '#4267b2',
        isShow: true,
      },
      {
        id: '7e99a1ce468943c8bfb27421b7015022',
        name: 'Twitter',
        url: 'https://twitter.com/',
        intro: '聚焦当下',
        icon: 'twitter',
        color: 'rgb(29, 161, 242)',
        isShow: true,
      },
    ],
  },
  {
    id: 'db71f9da04b4404980df79ab396fed3e',
    name: '购物',
    path: 'shopping',
    icon: <ShoppingCart />,
    color: '',
    isShow: true,
    children: [
      {
        id: '3238186bed334acaab3868275204ffaa',
        name: '淘宝',
        url: 'https://www.taobao.com/',
        intro: '淘!我喜欢',
        icon: 'taobao',
        color: '#FF5502',
        isShow: true,
      },
      {
        id: '96837d86dd784f59bffb6b137663113e',
        name: '京东',
        url: 'https://www.jd.com/',
        intro: '正品低价、品质保障、配送及时、轻松购物!',
        icon: 'jd',
        color: '#DE281F',
        isShow: true,
      },
      {
        id: '39e282377aa748d18a9c4673a47f0750',
        name: '天猫',
        url: 'https://www.tmall.com/',
        intro: '理想生活上天猫',
        icon: 'tmall',
        color: '#FF0036',
        isShow: true,
      },
      {
        id: '53a8556e6a6540739981fac260245801',
        name: '小米商城',
        url: 'https://www.mi.com/',
        intro: '让全球每个人都能享受到科技带来的美好生活',
        icon: 'mistore',
        color: '#FF6A00',
        isShow: true,
      },
      {
        id: '62d4349dae7441d19022a2dcc39e869d',
        name: '小米有品',
        url: 'https://www.xiaomiyoupin.com/',
        intro: '科技让生活更有品',
        icon: 'xiaomiyoupin',
        color: '#9F8052',
        isShow: true,
      },
    ],
  },
  {
    id: 'bbe93ee4303e45d1a136257d3568fb52',
    name: '邮箱',
    path: 'email',
    icon: <Email />,
    color: '',
    isShow: true,
    children: [
      {
        id: '1e8cc25c39a94d499b3ca0abcd5e5be8',
        name: 'QQ邮箱',
        url: 'https://mail.qq.com/',
        intro: 'QQ邮箱,常联系!',
        icon: 'qqemail',
        color: '#279BDF',
        isShow: true,
      },
      {
        id: '107d2cb69be04ae38d7fa66b7cad84de',
        name: '网易邮箱',
        url: 'https://mail.163.com/',
        intro: '中文邮箱第一品牌',
        icon: '163email',
        color: '#CE0326',
        isShow: true,
      },
      {
        id: '620f38307ad24ec28ace2d7e8a1c095b',
        name: 'Gmail',
        url: 'https://mail.google.com/',
        intro: '',
        icon: 'gmail',
        color: '#FBBC04',
        isShow: true,
      },
      {
        id: '895b4c0a9cee4eaeaeeafdbc97f4924a',
        name: 'Outlook',
        url: 'https://outlook.live.com/',
        intro: '',
        icon: 'outlook',
        color: '#0078D4',
        isShow: true,
      },
    ],
  },
  {
    id: '12f724761f054016adbf6d0d8721659d',
    name: '新闻',
    path: 'news',
    icon: <SpeakerNotes />,
    color: '',
    isShow: true,
    children: [
      {
        id: 'aacdc4b5794949fb8ad888446049bea8',
        name: '新华网',
        url: 'http://www.xinhuanet.com/',
        intro: '让新闻离你更近',
        icon: 'xinhuanet',
        color: '#083B90',
        isShow: true,
      },
      {
        id: 'c71edd4daad34f4bb51438d33b27c950',
        name: '中国日报',
        url: 'http://cn.chinadaily.com.cn/',
        intro: '传播中国,影响世界',
        icon: 'chinadaily',
        color: '#083961',
        isShow: true,
      },
      {
        id: 'ecfbad28800f42c686e46c9616cacb65',
        name: '环球网',
        url: 'https://www.huanqiu.com/',
        intro: '全球生活新门户',
        icon: 'huanqiu',
        color: '#90080E',
        isShow: true,
      },
      {
        id: 'a0629197d9b34b4f99f19cad0904ab1d',
        name: '央视网',
        url: 'https://www.cctv.com/',
        intro: '世界就在眼前',
        icon: 'cctv',
        color: '#BF0614',
        isShow: true,
      },
      {
        id: '05ec015eefa44e3eb1e157e7f3d07f85',
        name: '观察者网',
        url: 'https://www.guancha.cn/',
        intro: '为全球华人读者提供集新鲜、热点、深度、趣味于一体的时政资讯。',
        icon: 'guancha',
        color: '#BD0509',
        isShow: true,
      },
      {
        id: '099a7ead0c524d32930c9beb4916c663',
        name: '腾讯网',
        url: 'https://www.qq.com/',
        icon: 'guancha',
        color: '#1479D7',
        isShow: true,
      },
      {
        id: '6ef1b75ca1514e38bb5e5eddc0f6e0ea',
        name: '网易',
        url: 'https://www.163.com/',
        icon: '163',
        color: '#E10000',
        isShow: true,
      },
    ],
  },
  {
    id: '082ae5f250084a4b9188c68e8ba316b0',
    name: '视频',
    path: 'video',
    icon: <VideoLibrary />,
    color: '',
    isShow: true,
    children: [
      {
        id: '2e1b53aff19941abb4de1438692cf799',
        name: 'YouTube',
        url: 'https://www.youtube.com/',
        intro:
          'Enjoy the videos and music you love, upload original content, and share it all with friends.',
        icon: 'youtube',
        color: '#FF0000',
        isShow: true,
      },
      {
        id: 'c4d166f506fe4f38aa7a33141d957a5f',
        name: 'bilibili',
        url: 'https://bilibili.com',
        intro: '哔哩哔哩 (゜-゜)つロ 干杯~',
        icon: 'bilibili',
        color: '#00A1D6',
        isShow: true,
      },
    ],
  },
  {
    id: '476820684e894185949c8bd461fa91b5',
    name: '科技数码',
    path: 'digital',
    icon: <DevicesOther />,
    color: '',
    isShow: true,
    children: [
      {
        id: '322ac9b788c64d02bb28b158c14ea17c',
        name: 'IT之家',
        url: 'https://www.ithome.com/',
        intro: '爱科技,爱这里',
        icon: 'ithome',
        color: '#D22222',
        isShow: true,
      },
      {
        id: 'cac91d6480324410a661730bca0288db',
        name: '中关村在线',
        url: 'https://www.zol.com.cn/',
        intro: '大中华区专业IT网站',
        icon: 'zol',
        color: '#3686F1',
        isShow: true,
      },
      {
        id: 'b5fdb91ab4cb4ce79abf483c07b80187',
        name: '少数派',
        url: 'https://sspai.com/',
        intro: '高效工作,品质生活',
        icon: 'sspai',
        color: '#751617',
        isShow: true,
      },
      {
        id: '65fb7df831234b4d886ae117b5682853',
        name: '快科技',
        url: 'https://www.mydrivers.com/',
        intro: '科技改变未来',
        icon: 'mydrivers',
        color: '#FF902C',
        isShow: true,
      },
      {
        id: '980359e6eeb84962b51240dfbe6de012',
        name: '数字尾巴',
        url: 'https://www.dgtle.com/',
        intro: '分享美好数字生活',
        icon: 'dgtle',
        color: '#9A9A9A',
        isShow: true,
      },
      {
        id: '56e0023b3fb94387b28f5827ba21b2b8',
        name: '爱范儿',
        url: 'https://www.ifanr.com/',
        intro: '让未来触手可及',
        icon: 'ifanr',
        color: '#B52C02',
        isShow: true,
      },
      {
        id: '5683720e54e44d50a27a8f2e0f2687c5',
        name: '充电头网',
        url: 'https://www.chongdiantou.com/',
        intro: '我们只谈充电',
        icon: 'chongdiantouCC',
        color: '#23499E',
        isShow: true,
      },
    ],
  },
  {
    id: 'b89ff1c092cd4c0594ebf8b2b2b351fc',
    name: '看图',
    path: 'picture',
    icon: <BurstModeSharp />,
    color: '',
    isShow: true,
    children: [
      {
        id: '86dd7950cc984c1194358346bb408608',
        name: '天空之城',
        url: 'https://www.skypixel.com/',
        intro: '全球航拍爱好者和专业摄影师的作品社区',
        icon: 'skypixel',
        color: '#000000',
        isShow: true,
      },
      {
        id: 'ad91019e59ad447ab2c91d85c35bf841',
        name: '极像素',
        url: 'https://www.sigoo.com/',
        intro: '高像素看世界',
        icon: 'sigoo',
        color: '#C24422',
        isShow: true,
      },
      {
        id: '16ccfaced7b04cb28d24d069679fc05a',
        name: 'CNU',
        url: 'http://www.cnu.cc/',
        icon: 'cnu',
        color: '#CC0000',
        isShow: true,
      },
      {
        id: '9583b9a849834c56b85c1c1050e2cfb1',
        name: 'Pexels',
        url: 'https://www.pexels.com/zh-cn/',
        intro: '才华横溢的摄影作者在这里免费分享最精彩的素材图片和视频。',
        icon: 'pexels',
        color: '#05A081',
        isShow: true,
      },
      {
        id: 'dc820c3149aa4b0e8a070605264457a8',
        name: '图虫',
        url: 'https://tuchong.com/',
        intro: '优质摄影师交流社区',
        icon: 'tuchong',
        color: '#FF328C',
        isShow: true,
      },
    ],
  },
  {
    id: '0151319abdb6435688d4d3082a4f69f5',
    name: '开发',
    path: 'develop',
    icon: <Code />,
    color: '',
    isShow: true,
    children: [
      {
        id: '038ce5a511564b74a02b566e1ad02e61',
        name: 'React',
        url: 'https://react.docschina.org/',
        intro: '用于构建用户界面的 JavaScript 库',
        icon: 'react',
        color: '#61DAFB',
        isShow: true,
      },
      {
        id: '553324cb3a614441b23ae13082412d45',
        name: 'VusJs',
        url: 'https://v3.cn.vuejs.org/',
        intro: '渐进式 JavaScript 框架',
        icon: 'vuejs',
        color: '#41B883',
        isShow: true,
      },
      {
        id: 'a0383758c5ec46f0a24d913e6929872f',
        name: 'AngularJS',
        url: 'https://www.angularjs.net.cn/',
        intro: '一个开发动态Web应用的框架。',
        icon: 'angularjs',
        color: '#E23237',
        isShow: true,
      },
      {
        id: '8d34bc84c31048a8beb9b0f144f3fa5e',
        name: 'Flutter中文网',
        url: 'https://flutterchina.club/',
        intro: '极速构建漂亮的原生应用。',
        icon: 'flutterchina',
        color: '#0091EA',
        isShow: true,
      },
      {
        id: '879a26836b83420898d1e4daf45b5035',
        name: 'FlutterCN',
        url: 'https://flutter.cn/',
        intro:
          'Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。',
        icon: 'fluttercn',
        color: '#ED4845',
        isShow: true,
      },
      {
        id: '82d5e217d8fb4906a8b818e2052a0130',
        name: 'Flutter Gallery',
        url: 'https://gallery.flutter.dev/#/',
        intro:
          'Flutter Gallery is a resource to help developers evaluate and use Flutter',
        icon: 'fluttergallery',
        color: '#FF8383',
        isShow: true,
      },
      {
        id: '8a03034d7cb246f5bb9a77a435e6e772',
        name: 'NodeJs',
        url: 'https://nodejs.org/zh-cn/',
        intro: 'Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境。',
        icon: 'nodejs',
        color: '#3E863D',
        isShow: true,
      },
      {
        id: '6864605527e74850ac7a62d5605891b4',
        name: 'Webpack',
        url: 'https://www.webpackjs.com/',
        intro: '让一切变得简单',
        icon: 'webpackjs',
        color: '#55A7DD',
        isShow: true,
      },
      {
        id: '2e33301054214c98997b8b273a7a41b9',
        name: 'UmiJs',
        url: 'https://umijs.org/zh-CN',
        intro: '插件化的企业级前端应用框架。',
        icon: 'umijs',
        color: '#1890FF',
        isShow: true,
      },
      {
        id: 'fae86853bc2147298985b624f0222b66',
        name: 'UmiJs',
        url: 'http://www.electronjs.org/',
        intro: '使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序',
        icon: 'electronjs',
        color: '#9FEAF9',
        isShow: true,
      },
      {
        id: 'c62839ace4d74d6e9f9ac4096e30a85a',
        name: 'React Native',
        url: 'https://reactnative.cn/',
        intro: '使用 React 来创建 Android 和 iOS 的原生应用',
        icon: 'reactnative',
        color: '#61DAFB',
        isShow: true,
      },
      {
        id: '2d07a5cfbf5440fa83e615d2a5bccc11',
        name: 'Uni App',
        url: 'https://uniapp.dcloud.io/',
        intro: '基于VueJs的多端开发框架',
        icon: 'uniapp',
        color: '#2A9938',
        isShow: true,
      },
      {
        id: '26b9fc15b3c643f98ec3a31a76ca86c0',
        name: 'npm',
        url: 'https://www.npmjs.com/',
        intro: 'build amazing things',
        icon: 'uniapp',
        color: '#CB0303',
        isShow: true,
      },
      {
        id: 'f2aedbbbcf844badad3dff3b3d965001',
        name: 'Tailwind CSS',
        url: 'https://www.tailwindcss.cn/',
        intro: '无需离开您的HTML,即可快速建立现代网站。',
        icon: 'tailwindcss',
        color: '#06B6D4',
        isShow: true,
      },
      {
        id: 'afc961364c5144689866add534c6719c',
        name: 'Vite',
        url: 'https://cn.vitejs.dev/',
        intro: '下一代前端开发与构建工具',
        icon: 'vitejs',
        color: '#646CFF',
        isShow: true,
      },
      {
        id: 'e5bab6816cf4495892a8bafaf436b400',
        name: 'webpack',
        url: 'https://www.webpackjs.com/',
        intro: '让一切变得简单',
        icon: 'webpackjs',
        color: '#55A7DD',
        isShow: true,
      },
      {
        id: '8adc9d543405497b95279847ef9db1d4',
        name: 'Amp What',
        url: 'http://www.amp-what.com/',
        intro: 'Discover your character',
        icon: 'webpackjs',
        color: '#333333',
        isShow: true,
      },
    ],
  },
  {
    id: 'abc0adc7e979468b88134e958e2ed14e',
    name: '技术社区',
    path: 'community',
    icon: <LocalCafe />,
    color: '',
    isShow: true,
    children: [
      {
        id: '464583eeb36d4e488ce0dbfd55f24757',
        name: 'GitHub',
        url: 'https://github.com/',
        intro: '全球最大的开源技术社区',
        icon: 'github',
        color: '#2D333B',
        isShow: true,
      },
      {
        id: 'c8647d41918e491d96ecf951ec2ed158',
        name: '掘金',
        url: 'https://juejin.cn/',
        intro: '代码不止,掘金不停',
        icon: 'juejin',
        color: '#1E80FF',
        isShow: true,
      },
      {
        id: 'e984ca4cfb934a2d9848a5101641ef81',
        name: 'CSDN',
        url: 'https://www.csdn.net/',
        intro: '专业开发者社区',
        icon: 'csdn',
        color: '#FC5531',
        isShow: true,
      },
      {
        id: 'd8795f22326d4bbeaf58004f57de9eed',
        name: 'Segmentfault CN',
        url: 'https://segmentfault.com/',
        intro: '检索,交流和分享任何技术编程相关的问题及知识。',
        icon: 'segmentfault',
        color: '#39B95C',
        isShow: true,
      },
      {
        id: '52f700fa8bc7411cbfc86bf7f572ee80',
        name: 'InfoQ',
        url: 'https://www.infoq.cn/',
        intro: '促进软件开发及相关领域知识与创新的传播',
        icon: 'infoq',
        color: '#0B76DB',
        isShow: true,
      },
      {
        id: '94356aa909ab47fb86a45c5850bd1aaf',
        name: '极客学院Wiki',
        url: 'https://wiki.jikexueyuan.com/',
        intro: 'IT技术图文教程库',
        icon: 'jikexueyuan',
        color: '#39B95C',
        isShow: true,
      },
      {
        id: '7c0daf094bdc4fa7936981f3a07617c8',
        name: '开源中国',
        url: 'https://www.oschina.net/',
        intro: '中文开源技术交流社区',
        icon: 'oschina',
        color: '#21B351',
        isShow: true,
      },
      {
        id: 'd380fc254f0b4428a7359c2ac654fc75',
        name: '博客园',
        url: 'https://www.cnblogs.com/',
        intro: '开发者的网上家园',
        icon: 'cnblogs',
        color: '#2E7ACC',
        isShow: true,
      },
      {
        id: '0237ea70b65b4facbce9d286030aee88',
        name: 'Stackoverflow',
        url: 'https://stackoverflow.com/',
        intro: 'Where Developers Learn, Share, & Build Careers',
        icon: 'stackoverflow',
        color: '#F48024',
        isShow: true,
      },
      {
        id: 'ebc0a7c723224376a7a20016351c706b',
        name: '链滴',
        url: 'https://ld246.com/',
        intro: '记录生活,连接点滴',
        icon: 'ld246',
        color: '#D23F31',
        isShow: true,
      },
    ],
  },
  {
    id: '2f2480b6e2974694a89f962e24fa1de0',
    name: '图标库',
    path: 'icons',
    icon: <Apps />,
    color: '',
    isShow: true,
    children: [
      {
        id: '75f6ae67b74a4457bb91edc58654ade1',
        name: 'Font Awesome',
        url: 'https://fontawesome.com/',
        intro:
          "Get vector icons and social logos on your website with Font Awesome, the web's most popular icon set and toolkit.",
        icon: 'fontawesome',
        color: '#183153',
        isShow: true,
      },
      {
        id: '1ab297fb419642f0adfa8e1d304daa6f',
        name: 'Icon Font',
        url: 'https://www.iconfont.cn/',
        icon: 'iconfont',
        color: '#183153',
        isShow: true,
      },
      {
        id: '18bcd286eaf942829a2e6322084ab679',
        name: 'Material Icons',
        url: 'https://fonts.google.com/icons',
        intro:
          'Material Icons are available in five styles and a range of downloadable sizes and densities. The icons are based on the core Material Design principles and metrics.',
        icon: 'materialicons',
        color: '#BDBDBD',
        isShow: true,
      },
      {
        id: 'fcdfc66efc524d73849c6cbc52fa10a5',
        name: 'Simple Icons',
        url: 'https://simpleicons.org/',
        intro: 'Free SVG icons for popular brands',
        icon: 'simpleicons',
        color: '#222222',
        isShow: true,
      },
    ],
  },
  {
    id: '597891a55a2545b29b6c6af63e319d4c',
    name: '工具',
    path: 'tools',
    icon: <Build />,
    color: '',
    isShow: true,
    children: [
      {
        id: '47e97fedff2d40779e072dc6ee7ddd16',
        name: 'VS Code',
        url: 'https://code.visualstudio.com/',
        intro: 'Code editing. Redefined.',
        icon: 'vscode',
        color: '#22A5F1',
        isShow: true,
      },
      {
        id: '5e5f263d87564a8289a111cd7113ba00',
        name: 'Jetbrains',
        url: 'https://www.jetbrains.com/',
        intro: 'Essential tools for software developers and teams',
        icon: 'jetbrains',
        color: '#080809',
        isShow: true,
      },
      {
        id: '26701f2812b54667afe396e80e522d05',
        name: 'Atom',
        url: 'https://atom.io/',
        intro: 'A hackable text editor for the 21st Century',
        icon: 'atom',
        color: '#E0AD38',
        isShow: true,
      },
      {
        id: '7ceff82cbfc7472687e3bf637107ebfb',
        name: 'HBuilderX',
        url: 'https://www.dcloud.io/hbuilderx.html',
        intro: 'HBuilderX 是轻如编辑器、强如IDE的合体版本。',
        icon: 'hubilderx',
        color: '#1A9F35',
        isShow: true,
      },
      {
        id: '83b6b56394114522be7c36d8c2a6bd2d',
        name: 'uTools',
        url: 'https://u.tools/',
        intro: '你的生产力工具集',
        icon: 'utools',
        color: '#172B4D',
        isShow: true,
      },
      {
        id: '42a414464d7847d586bd58ee6c83a147',
        name: 'typora',
        url: 'https://typora.io/',
        intro: 'A TRULY MINIMAL MARKDOWN EDITOR.',
        icon: 'typora',
        color: '#999999',
        isShow: true,
      },
      {
        id: 'ae2689493e4a42d896b4867ad75fa605',
        name: 'PicGo',
        url: 'https://picgo.github.io/PicGo-Doc/zh/',
        intro: '图片上传、管理新体验',
        icon: 'picgo',
        color: '#4CA4E3',
        isShow: true,
      },
      {
        id: '0f2d7d7a0529413d8af90c16c3e41336',
        name: '思源笔记',
        url: 'https://b3log.org/siyuan/',
        intro:
          '思源笔记是一款本地优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。融合块、大纲和双向链接,构建你永恒的数字花园。',
        icon: 'siyuan',
        color: '#D23E31',
        isShow: true,
      },
      {
        id: '98be956869b8407883f3ab690a541069',
        name: 'RunJs',
        url: 'https://runjs.app/',
        intro: 'The JavaScript playground for your desktop',
        icon: 'runjs',
        color: '#F7DF1E',
        isShow: true,
      },
      {
        id: 'd7d5fa1b79384985bf7dd449a0f41303',
        name: 'Sourcetree',
        url: 'https://www.sourcetreeapp.com/',
        intro: 'Simplicity and power in a beautiful Git GUI',
        icon: 'sourcetreeapp',
        color: '#2684FF',
        isShow: true,
      },
      {
        id: 'dc14fce2bc1e4b4faaeb8f02a5ef1c98',
        name: 'Apifox',
        url: 'https://www.apifox.cn/',
        intro: 'API 文档、调试、Mock、测试一体化协作平台',
        icon: 'apifox',
        color: '#F65150',
        isShow: true,
      },
      {
        id: 'd1474b8bf88a4f33b33c54c26bd2479f',
        name: 'Figma',
        url: 'https://www.figma.com/',
        intro: 'The collaborative interface design tool.',
        icon: 'figma',
        color: '#A259FF',
        isShow: true,
      },
      {
        id: 'ee6806d9d0db413482c387649d7146e5',
        name: 'ShareX',
        url: 'https://getsharex.com/',
        intro: 'Screen capture, file sharing and productivity tool',
        icon: 'sharex',
        color: '#313642',
        isShow: true,
      },
    ],
  },
  {
    id: 'af73c0d3e7cd49269e30a8fda67dd1e5',
    name: '发现',
    path: 'find',
    icon: <Search />,
    color: '',
    isShow: true,
    children: [
      {
        id: '551d2ced5e4a4e7eba712fb0e512ff32',
        name: 'EmojiAll官方网站',
        url: 'https://www.emojiall.com/',
        intro: 'Emoji大全 | Emoji表情符号字典',
        icon: 'emojiall',
        color: '#FD5D3B',
        isShow: true,
      },
      {
        id: 'df30201ec4764704b3c6d42edd4af4dc',
        name: 'gitmoji',
        url: 'https://gitmoji.dev/',
        intro: 'An emoji guide for your commit messages',
        icon: 'gitmoji',
        color: '#FFDD67',
        isShow: true,
      },
    ],
  },
]
Example #7
Source File: index.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 4 votes vote down vote up
SearchInput = (props: SearchInputProps) => {
    const {
        onFilter,
        debounceWait,
        totalItems,
        foundItems,
        totalSubItems,
        foundSubItems,
    } = props;
    const [searchText, setSearchText] = useState('');
    const [isSearching, setIsSearching] = useState(false);
    const [filterVaultsWithWarnings, setFilterVaultsWithWarnings] =
        useState(false);
    const [healthCheckFilter, setHealthCheckFilter] = useState('');

    const debounceFilter = useCallback(
        debounce((newSearchText, flags) => {
            const newSearchTextLowerCase = newSearchText.toLowerCase();
            onFilter(newSearchTextLowerCase, flags, healthCheckFilter);
            setIsSearching(false);
        }, debounceWait),
        [debounceWait, isSearching]
    );

    // Event listener called on every change
    const onChange = useCallback(
        (event: ChangeEvent) => {
            const value = (event.target as HTMLInputElement).value;
            setIsSearching(true);
            setSearchText(value);
            debounceFilter(value, getCurrentFlags(filterVaultsWithWarnings));
        },
        [filterVaultsWithWarnings, searchText, isSearching, healthCheckFilter]
    );

    const onFilterVaultsWithWarnings = useCallback(
        (e: ChangeEvent<HTMLInputElement>) => {
            setFilterVaultsWithWarnings(e.target.checked);
            setIsSearching(true);
            const newSearchTextLowerCase = searchText.toLowerCase();
            onFilter(
                newSearchTextLowerCase,
                getCurrentFlags(e.target.checked),
                healthCheckFilter
            );
            setIsSearching(false);
        },
        [searchText, isSearching, healthCheckFilter]
    );
    const handleClickClearSearch = useCallback(() => {
        setSearchText('');
        setFilterVaultsWithWarnings(false);
        onFilter('', getCurrentFlags(false), '');
    }, [onFilter]);
    const healthCheckFilterChange = useCallback(
        (e: SelectChangeEvent<unknown>) => {
            setHealthCheckFilter((e.target as HTMLInputElement).value);
            setIsSearching(true);
            const newSearchTextLowerCase = searchText.toLowerCase();
            onFilter(
                newSearchTextLowerCase,
                getCurrentFlags(filterVaultsWithWarnings),
                (e.target as HTMLInputElement).value
            );
            setIsSearching(false);
        },
        [searchText, healthCheckFilter, isSearching]
    );

    const renderSearchingLabel = useCallback(() => {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let render: any;
        if (isSearching) {
            render = (
                <div>
                    <ProgressSpinnerBar label="results" />
                </div>
            );
        } else {
            render = (
                <>
                    {healthCheckFilter !== '' && (
                        <WarningLabel
                            warningText={'HealthCheck Filter is ON!'}
                        />
                    )}
                    <ResultsLabel
                        title="Vaults"
                        totalItems={totalItems}
                        foundItems={foundItems}
                        displayFound={true}
                        isSearching={isSearching}
                    />
                    <ResultsLabel
                        title="Strategies"
                        totalItems={totalSubItems}
                        foundItems={foundSubItems}
                        displayFound={true}
                        isSearching={isSearching}
                    />
                </>
            );
        }

        return render;
    }, [isSearching, totalItems, foundItems, totalSubItems, foundSubItems]);

    return (
        <div>
            <StyledForm>
                <Grid container direction="row" alignItems="center" spacing={3}>
                    <Grid item xs={12} sm={6}>
                        <StyledContainer maxWidth="lg">
                            <StyledTextField
                                variant="outlined"
                                onChange={onChange}
                                type="search"
                                value={searchText}
                                placeholder="Search by vault/strategy address/name, strategist address, token name/symbol, share token symbol/name or API version."
                                InputProps={
                                    searchText == ''
                                        ? {
                                              startAdornment: (
                                                  <InputAdornment position="end">
                                                      <Search />
                                                  </InputAdornment>
                                              ),
                                          }
                                        : {
                                              endAdornment: (
                                                  <InputAdornment position="end">
                                                      <IconButton
                                                          aria-label="delete"
                                                          onClick={
                                                              handleClickClearSearch
                                                          }
                                                          size="large"
                                                      >
                                                          <Delete />
                                                      </IconButton>
                                                  </InputAdornment>
                                              ),
                                          }
                                }
                            />
                        </StyledContainer>
                    </Grid>
                    <Grid item xs={12} sm={3}>
                        <StyledContainer maxWidth="lg">
                            <StyledFormControlLabel
                                control={
                                    <Switch
                                        checked={filterVaultsWithWarnings}
                                        onChange={onFilterVaultsWithWarnings}
                                        color="primary"
                                    />
                                }
                                labelPlacement="start"
                                label="Vaults with warnings"
                            />
                        </StyledContainer>
                    </Grid>
                    <Grid item xs={12} sm={3}>
                        <StyledContainer maxWidth="lg">
                            <StyledFormControlLabel
                                control={
                                    <StyledSelect
                                        displayEmpty
                                        variant="standard"
                                        defaultValue=""
                                        value={healthCheckFilter}
                                        onChange={healthCheckFilterChange}
                                    >
                                        <MenuItem value="">All</MenuItem>
                                        <MenuItem value="Enabled">
                                            Enabled
                                        </MenuItem>
                                        <MenuItem value="Disabled">
                                            Disabled
                                        </MenuItem>
                                        <MenuItem value="None">
                                            Not Set
                                        </MenuItem>
                                    </StyledSelect>
                                }
                                labelPlacement="start"
                                label="HealthCheck"
                            />
                        </StyledContainer>
                    </Grid>
                </Grid>
            </StyledForm>
            <StyledContainerResult maxWidth="lg">
                {renderSearchingLabel()}
            </StyledContainerResult>
        </div>
    );
}