Skip to content

Commit 010576f

Browse files
feat: icons with search (#1121)
Co-authored-by: João Salvador <[email protected]>
1 parent 5c88f54 commit 010576f

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

frontend/src/components/icons/Sprite.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint react/no-unknown-property: 0 */
22
const Sprite = () => (
33
<svg
4+
id="iconSprite"
45
focusable="false"
56
preserveAspectRatio="xMidYMid meet"
67
style={{ visibility: 'hidden', position: 'absolute', pointerEvents: 'none' }}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { ComponentStory } from '@storybook/react';
3+
4+
import Sprite from '@/components/icons/Sprite';
5+
import dedent from 'ts-dedent';
6+
import Icon from '@/components/icons/Icon';
7+
import Flex from '@/components/Primitives/Flex';
8+
import Text from '@/components/Primitives/Text';
9+
import Input from '@/components/Primitives/Input';
10+
import { FormProvider, useForm } from 'react-hook-form';
11+
import Card from './components/Card';
12+
13+
export default {
14+
title: 'Misc/Icons',
15+
component: Sprite,
16+
parameters: {
17+
layout: 'start',
18+
controls: { hideNoControlsWarning: true },
19+
docs: {
20+
description: {
21+
component: dedent`List of Icons that can be used in the \`Icon\` Primitive.`,
22+
},
23+
source: {
24+
code: null,
25+
},
26+
},
27+
},
28+
};
29+
30+
const Template: ComponentStory<typeof Sprite> = () => {
31+
const [icons, setIcons] = useState<string[]>([]);
32+
const [filteredIcons, setFilteredIcons] = useState<string[]>(icons);
33+
34+
const methods = useForm({
35+
defaultValues: {
36+
search: '',
37+
},
38+
});
39+
40+
const handleOnChange = () => {
41+
const searchValue = methods.getValues('search');
42+
setFilteredIcons(icons.filter((icon) => icon.includes(searchValue)));
43+
};
44+
45+
useEffect(() => {
46+
const iconSymbols = document.querySelectorAll('#iconSprite symbol');
47+
const iconIDs = [...iconSymbols].map((icon) => icon.getAttribute('id')!);
48+
setIcons(iconIDs);
49+
setFilteredIcons(iconIDs);
50+
}, []);
51+
52+
return (
53+
<Flex direction="column">
54+
<FormProvider {...methods}>
55+
<form
56+
style={{ margin: '0 2.5rem 2rem' }}
57+
onChange={handleOnChange}
58+
onSubmit={(e) => {
59+
e.preventDefault();
60+
}}
61+
>
62+
<Input id="search" type="text" placeholder="Search" icon="search" iconPosition="left" />
63+
</form>
64+
</FormProvider>
65+
<Flex wrap="wrap" gap="16" justify="center">
66+
{filteredIcons.map((icon) => {
67+
const displayIcon = <Icon name={icon} size={32} />;
68+
69+
return (
70+
<Card display={displayIcon} key={icon}>
71+
<Text>
72+
<Text fontWeight="bold">Name:</Text> {icon}
73+
</Text>
74+
</Card>
75+
);
76+
})}
77+
</Flex>
78+
</Flex>
79+
);
80+
};
81+
82+
export const Default = Template.bind({});
83+
Default.storyName = 'Basic Usage';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Box from '@/components/Primitives/Box';
2+
import Flex from '@/components/Primitives/Flex';
3+
import React from 'react';
4+
5+
const Card = ({ display, children }: any) => (
6+
<Box variant="bordered" css={{ width: '$260' }}>
7+
<Flex
8+
css={{ py: '$24', backgroundColor: '$white', borderRadius: '$8 $8 0 0' }}
9+
justify="center"
10+
>
11+
{display}
12+
</Flex>
13+
<Flex direction="column" css={{ p: '$12', borderTop: '1px solid $primary100' }}>
14+
{children}
15+
</Flex>
16+
</Box>
17+
);
18+
19+
export default Card;

0 commit comments

Comments
 (0)