Skip to content

Commit 0537572

Browse files
PanchoutNathanAntoLC
authored andcommitted
♻️(frontend) icon component refactoring
- Add variant to IconComponent and remove $isMaterialIcon prop - Replace all Text component used as icon with the Icon component.
1 parent 8aab007 commit 0537572

File tree

15 files changed

+55
-145
lines changed

15 files changed

+55
-145
lines changed

src/frontend/apps/impress/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"@sentry/nextjs": "9.3.0",
3131
"@tanstack/react-query": "5.67.1",
3232
"canvg": "4.0.3",
33+
"clsx": "2.1.1",
3334
"cmdk": "1.0.4",
3435
"crisp-sdk-web": "1.0.25",
3536
"docx": "9.1.1",
Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,24 @@
1+
import clsx from 'clsx';
12
import { css } from 'styled-components';
23

34
import { Text, TextType } from '@/components';
4-
import { useCunninghamTheme } from '@/cunningham';
55

66
type IconProps = TextType & {
77
iconName: string;
8+
variant?: 'filled' | 'outlined';
89
};
9-
export const Icon = ({ iconName, ...textProps }: IconProps) => {
10-
return (
11-
<Text $isMaterialIcon {...textProps}>
12-
{iconName}
13-
</Text>
14-
);
15-
};
16-
17-
interface IconBGProps extends TextType {
18-
iconName: string;
19-
}
20-
21-
export const IconBG = ({ iconName, ...textProps }: IconBGProps) => {
22-
const { colorsTokens } = useCunninghamTheme();
23-
10+
export const Icon = ({
11+
iconName,
12+
variant = 'outlined',
13+
...textProps
14+
}: IconProps) => {
2415
return (
2516
<Text
26-
$isMaterialIcon
27-
$size="36px"
28-
$theme="primary"
29-
$variation="600"
30-
$background={colorsTokens()['primary-bg']}
31-
$css={`
32-
border: 1px solid ${colorsTokens()['primary-200']};
33-
user-select: none;
34-
`}
35-
$radius="12px"
36-
$padding="4px"
37-
$margin="auto"
3817
{...textProps}
39-
className={`--docs--icon-bg ${textProps.className || ''}`}
18+
className={clsx('--docs--icon-bg', textProps.className, {
19+
'material-icons-filled': variant === 'filled',
20+
'material-icons': variant === 'outlined',
21+
})}
4022
>
4123
{iconName}
4224
</Text>
@@ -49,15 +31,13 @@ type IconOptionsProps = TextType & {
4931

5032
export const IconOptions = ({ isHorizontal, ...props }: IconOptionsProps) => {
5133
return (
52-
<Text
34+
<Icon
5335
{...props}
54-
$isMaterialIcon
36+
iconName={isHorizontal ? 'more_horiz' : 'more_vert'}
5537
$css={css`
5638
user-select: none;
5739
${props.$css}
5840
`}
59-
>
60-
{isHorizontal ? 'more_horiz' : 'more_vert'}
61-
</Text>
41+
/>
6242
);
6343
};

src/frontend/apps/impress/src/components/Text.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ type TextSizes = keyof typeof sizes;
1111
export interface TextProps extends BoxProps {
1212
as?: 'p' | 'span' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
1313
$elipsis?: boolean;
14-
$isMaterialIcon?: boolean;
1514
$weight?: CSSProperties['fontWeight'];
1615
$textAlign?: CSSProperties['textAlign'];
1716
$size?: TextSizes | (string & {});
@@ -57,14 +56,14 @@ export const TextStyled = styled(Box)<TextProps>`
5756
`;
5857

5958
const Text = forwardRef<HTMLElement, ComponentPropsWithRef<typeof TextStyled>>(
60-
({ className, $isMaterialIcon, ...props }, ref) => {
59+
({ className, ...props }, ref) => {
6160
return (
6261
<TextStyled
6362
ref={ref}
6463
as="span"
6564
$theme="greyscale"
6665
$variation="text"
67-
className={`${className || ''}${$isMaterialIcon ? ' material-icons' : ''}`}
66+
className={className}
6867
{...props}
6968
/>
7069
);

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/AIButton.tsx

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { PropsWithChildren, ReactNode, useMemo } from 'react';
1414
import { useTranslation } from 'react-i18next';
1515

1616
import { isAPIError } from '@/api';
17-
import { Box, Text } from '@/components';
17+
import { Box, Icon } from '@/components';
1818
import { useDocOptions, useDocStore } from '@/docs/doc-management/';
1919

2020
import {
@@ -108,11 +108,7 @@ export function AIGroupButton() {
108108
data-test="ai-actions"
109109
label="AI"
110110
mainTooltip={t('AI Actions')}
111-
icon={
112-
<Text $isMaterialIcon $size="l">
113-
auto_awesome
114-
</Text>
115-
}
111+
icon={<Icon iconName="auto_awesome" $size="l" />}
116112
/>
117113
</Components.Generic.Menu.Trigger>
118114
<Components.Generic.Menu.Dropdown
@@ -124,66 +120,42 @@ export function AIGroupButton() {
124120
<AIMenuItemTransform
125121
action="prompt"
126122
docId={currentDoc.id}
127-
icon={
128-
<Text $isMaterialIcon $size="s">
129-
text_fields
130-
</Text>
131-
}
123+
icon={<Icon iconName="text_fields" $size="s" />}
132124
>
133125
{t('Use as prompt')}
134126
</AIMenuItemTransform>
135127
<AIMenuItemTransform
136128
action="rephrase"
137129
docId={currentDoc.id}
138-
icon={
139-
<Text $isMaterialIcon $size="s">
140-
refresh
141-
</Text>
142-
}
130+
icon={<Icon iconName="refresh" $size="s" />}
143131
>
144132
{t('Rephrase')}
145133
</AIMenuItemTransform>
146134
<AIMenuItemTransform
147135
action="summarize"
148136
docId={currentDoc.id}
149-
icon={
150-
<Text $isMaterialIcon $size="s">
151-
summarize
152-
</Text>
153-
}
137+
icon={<Icon iconName="summarize" $size="s" />}
154138
>
155139
{t('Summarize')}
156140
</AIMenuItemTransform>
157141
<AIMenuItemTransform
158142
action="correct"
159143
docId={currentDoc.id}
160-
icon={
161-
<Text $isMaterialIcon $size="s">
162-
check
163-
</Text>
164-
}
144+
icon={<Icon iconName="check" $size="s" />}
165145
>
166146
{t('Correct')}
167147
</AIMenuItemTransform>
168148
<AIMenuItemTransform
169149
action="beautify"
170150
docId={currentDoc.id}
171-
icon={
172-
<Text $isMaterialIcon $size="s">
173-
draw
174-
</Text>
175-
}
151+
icon={<Icon iconName="draw" $size="s" />}
176152
>
177153
{t('Beautify')}
178154
</AIMenuItemTransform>
179155
<AIMenuItemTransform
180156
action="emojify"
181157
docId={currentDoc.id}
182-
icon={
183-
<Text $isMaterialIcon $size="s">
184-
emoji_emotions
185-
</Text>
186-
}
158+
icon={<Icon iconName="emoji_emotions" $size="s" />}
187159
>
188160
{t('Emojify')}
189161
</AIMenuItemTransform>
@@ -197,9 +169,7 @@ export function AIGroupButton() {
197169
subTrigger={true}
198170
>
199171
<Box $direction="row" $gap="0.6rem">
200-
<Text $isMaterialIcon $size="s">
201-
translate
202-
</Text>
172+
<Icon iconName="translate" $size="s" />
203173
{t('Language')}
204174
</Box>
205175
</Components.Generic.Menu.Item>

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/ModalConfirmDownloadUnsafe.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Button, Modal, ModalSize } from '@openfun/cunningham-react';
22
import { useTranslation } from 'react-i18next';
33

4-
import { Box, Text } from '@/components';
4+
import { Box, Icon, Text } from '@/components';
55

66
interface ModalConfirmDownloadUnsafeProps {
77
onClose: () => void;
@@ -52,9 +52,7 @@ export const ModalConfirmDownloadUnsafe = ({
5252
$variation="1000"
5353
$direction="row"
5454
>
55-
<Text $isMaterialIcon $theme="warning">
56-
warning
57-
</Text>
55+
<Icon iconName="warning" $theme="warning" />
5856
{t('Warning')}
5957
</Text>
6058
}

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DividerBlock.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { insertOrUpdateBlock } from '@blocknote/core';
22
import { createReactBlockSpec } from '@blocknote/react';
33
import { TFunction } from 'i18next';
44

5-
import { Box, Text } from '@/components';
5+
import { Box, Icon } from '@/components';
66
import { useCunninghamTheme } from '@/cunningham';
77

88
import { DocsBlockNoteEditor } from '../../types';
@@ -45,11 +45,7 @@ export const getDividerReactSlashMenuItems = (
4545
},
4646
aliases: ['divider', 'hr', 'horizontal rule', 'line', 'separator'],
4747
group,
48-
icon: (
49-
<Text $isMaterialIcon $size="18px">
50-
remove
51-
</Text>
52-
),
48+
icon: <Icon iconName="remove" $size="18px" />,
5349
subtext: t('Add a horizontal line'),
5450
},
5551
];

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/QuoteBlock.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { defaultProps, insertOrUpdateBlock } from '@blocknote/core';
22
import { BlockTypeSelectItem, createReactBlockSpec } from '@blocknote/react';
33
import { TFunction } from 'i18next';
4-
import React from 'react';
54

6-
import { Box, Text } from '@/components';
5+
import { Box, Icon } from '@/components';
76
import { useCunninghamTheme } from '@/cunningham';
87

98
import { DocsBlockNoteEditor } from '../../types';
@@ -54,11 +53,7 @@ export const getQuoteReactSlashMenuItems = (
5453
},
5554
aliases: ['quote', 'blockquote', 'citation'],
5655
group,
57-
icon: (
58-
<Text $isMaterialIcon $size="18px">
59-
format_quote
60-
</Text>
61-
),
56+
icon: <Icon iconName="format_quote" $size="18px" />,
6257
subtext: t('Add a quote block'),
6358
},
6459
];
@@ -68,10 +63,6 @@ export const getQuoteFormattingToolbarItems = (
6863
): BlockTypeSelectItem => ({
6964
name: t('Quote'),
7065
type: 'quote',
71-
icon: () => (
72-
<Text $isMaterialIcon $size="16px">
73-
format_quote
74-
</Text>
75-
),
66+
icon: () => <Icon iconName="format_quote" $size="16px" />,
7667
isSelected: (block) => block.type === 'quote',
7768
});

src/frontend/apps/impress/src/features/docs/doc-versioning/components/VersionList.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import { DateTime } from 'luxon';
33
import { useTranslation } from 'react-i18next';
44

55
import { APIError } from '@/api';
6-
import { Box, BoxButton, InfiniteScroll, Text, TextErrors } from '@/components';
6+
import {
7+
Box,
8+
BoxButton,
9+
Icon,
10+
InfiniteScroll,
11+
Text,
12+
TextErrors,
13+
} from '@/components';
714
import { Doc } from '@/docs/doc-management';
815
import { useDate } from '@/hook';
916

@@ -68,9 +75,7 @@ const VersionListState = ({
6875
causes={error.cause}
6976
icon={
7077
error.status === 502 ? (
71-
<Text $isMaterialIcon $theme="danger">
72-
wifi_off
73-
</Text>
78+
<Icon iconName="wifi_off" $theme="danger" />
7479
) : undefined
7580
}
7681
/>

src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,7 @@ export default function HomeBanner() {
7676
) : (
7777
<Button
7878
onClick={() => gotoLogin()}
79-
icon={
80-
<Text $isMaterialIcon $color="white">
81-
bolt
82-
</Text>
83-
}
79+
icon={<Icon iconName="bolt" $color="white" />}
8480
>
8581
{t('Start Writing')}
8682
</Button>

src/frontend/apps/impress/src/features/home/components/HomeContent.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Button } from '@openfun/cunningham-react';
22
import { Trans, useTranslation } from 'react-i18next';
33
import { css } from 'styled-components';
44

5-
import { Box, Text } from '@/components';
5+
import { Box, Icon, Text } from '@/components';
66
import { useCunninghamTheme } from '@/cunningham';
77
import { Footer } from '@/features/footer';
88
import { LeftPanel } from '@/features/left-panel';
@@ -155,11 +155,7 @@ export function HomeContent() {
155155
$margin={{ top: 'small' }}
156156
>
157157
<Button
158-
icon={
159-
<Text $isMaterialIcon $color="white">
160-
chat
161-
</Text>
162-
}
158+
icon={<Icon iconName="chat" $color="white" />}
163159
href="https://matrix.to/#/#docs-official:matrix.org"
164160
target="_blank"
165161
>

0 commit comments

Comments
 (0)