mirror of
https://github.com/strapi/strapi.git
synced 2025-09-05 22:57:56 +00:00
Merge pull request #4784 from strapi/ctb/add-search-icon
[CTB] Add search for component's icon
This commit is contained in:
commit
4019bca044
@ -0,0 +1,12 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { colors } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
const Search = styled.input`
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 21px;
|
||||||
|
outline: 0;
|
||||||
|
color: ${colors.leftMenu.black};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Search;
|
@ -0,0 +1,34 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { colors } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
const SearchWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
margin-top: -2px;
|
||||||
|
&::after {
|
||||||
|
display: block;
|
||||||
|
content: '';
|
||||||
|
height: 2px;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
background: ${colors.leftMenu.lightGrey};
|
||||||
|
}
|
||||||
|
> svg {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 15px;
|
||||||
|
left: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 0;
|
||||||
|
padding: 5px 0 0px 5px;
|
||||||
|
line-height: 11px;
|
||||||
|
outline: 0;
|
||||||
|
i,
|
||||||
|
svg {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default SearchWrapper;
|
@ -36,6 +36,17 @@ const Wrapper = styled.div`
|
|||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
color: #bdbdbd;
|
color: #bdbdbd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 2px;
|
||||||
|
color: #919bae;
|
||||||
|
> button {
|
||||||
|
margin-top: -8px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Wrapper.defaultProps = {
|
Wrapper.defaultProps = {
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { createRef, useEffect, useState } from 'react';
|
||||||
import { Label, ErrorMessage } from '@buffetjs/styles';
|
import { Label, ErrorMessage } from '@buffetjs/styles';
|
||||||
import { AutoSizer, Collection } from 'react-virtualized';
|
import { AutoSizer, Collection } from 'react-virtualized';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import useDataManager from '../../hooks/useDataManager';
|
import useDataManager from '../../hooks/useDataManager';
|
||||||
import CellRenderer from './CellRenderer';
|
import CellRenderer from './CellRenderer';
|
||||||
|
import Search from './Search';
|
||||||
|
import SearchWrapper from './SearchWrapper';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
const ComponentIconPicker = ({
|
const ComponentIconPicker = ({
|
||||||
@ -15,9 +18,7 @@ const ComponentIconPicker = ({
|
|||||||
value,
|
value,
|
||||||
}) => {
|
}) => {
|
||||||
const { allIcons, allComponentsIconAlreadyTaken } = useDataManager();
|
const { allIcons, allComponentsIconAlreadyTaken } = useDataManager();
|
||||||
const [originalIcon] = useState(value);
|
const initialIcons = allIcons.filter(ico => {
|
||||||
|
|
||||||
const icons = allIcons.filter(ico => {
|
|
||||||
if (isCreating) {
|
if (isCreating) {
|
||||||
return !allComponentsIconAlreadyTaken.includes(ico);
|
return !allComponentsIconAlreadyTaken.includes(ico);
|
||||||
}
|
}
|
||||||
@ -27,6 +28,18 @@ const ComponentIconPicker = ({
|
|||||||
.filter(icon => icon !== originalIcon)
|
.filter(icon => icon !== originalIcon)
|
||||||
.includes(ico);
|
.includes(ico);
|
||||||
});
|
});
|
||||||
|
const ref = createRef();
|
||||||
|
const [originalIcon] = useState(value);
|
||||||
|
const [showSearch, setShowSearch] = useState(false);
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [icons, setIcons] = useState(initialIcons);
|
||||||
|
const toggleSearch = () => setShowSearch(prev => !prev);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (showSearch && ref.current) {
|
||||||
|
ref.current.focus();
|
||||||
|
}
|
||||||
|
}, [ref, showSearch]);
|
||||||
|
|
||||||
const cellCount = icons.length;
|
const cellCount = icons.length;
|
||||||
|
|
||||||
@ -54,9 +67,42 @@ const ComponentIconPicker = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper error={error !== null}>
|
<Wrapper error={error !== null}>
|
||||||
<Label htmlFor={name} style={{ marginBottom: 12 }}>
|
<div className="search">
|
||||||
{label}
|
<Label htmlFor={name} style={{ marginBottom: 12 }}>
|
||||||
</Label>
|
{label}
|
||||||
|
</Label>
|
||||||
|
{!showSearch ? (
|
||||||
|
<button onClick={toggleSearch} type="button">
|
||||||
|
<FontAwesomeIcon icon="search" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<SearchWrapper>
|
||||||
|
<FontAwesomeIcon icon="search" />
|
||||||
|
<button onClick={toggleSearch}></button>
|
||||||
|
<Search
|
||||||
|
ref={ref}
|
||||||
|
onChange={({ target: { value } }) => {
|
||||||
|
setSearch(value);
|
||||||
|
setIcons(() =>
|
||||||
|
initialIcons.filter(icon => icon.includes(value))
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
value={search}
|
||||||
|
placeholder="search…"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setSearch('');
|
||||||
|
setIcons(initialIcons);
|
||||||
|
toggleSearch();
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon="times" />
|
||||||
|
</button>
|
||||||
|
</SearchWrapper>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<AutoSizer disableHeight>
|
<AutoSizer disableHeight>
|
||||||
{({ width }) => {
|
{({ width }) => {
|
||||||
return (
|
return (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user