import * as React from 'react';
import classNames from 'classnames';
import {generateId} from '../utils';
export type IconTypeType =
| 'academic_cap'
| 'achievement'
| 'add_more'
| 'ai'
| 'all_questions'
| 'answer_bubble'
| 'answer'
| 'answers'
| 'apple'
| 'archive_checked'
| 'archive'
| 'arrow_double_right'
| 'arrow_down'
| 'arrow_left'
| 'arrow_right'
| 'arrow_top_right'
| 'arrow_up'
| 'ask_bubble'
| 'ask_parent_to_pay'
| 'attachment'
| 'autopublish'
| 'bell_checked'
| 'bell_outlined'
| 'best_answer'
| 'block'
| 'bold'
| 'brainly_oval'
| 'brainly_parallelogram'
| 'bulb_checked'
| 'bulb_filled'
| 'bulb'
| 'bulleted_list'
| 'calendar'
| 'camera'
| 'caret_down'
| 'caret_up'
| 'chapter'
| 'chat'
| 'check'
| 'check_circle'
| 'chevron_double_down'
| 'chevron_double_right'
| 'chevron_down'
| 'chevron_left'
| 'chevron_right'
| 'chevron_up'
| 'chevrons_horizontal'
| 'circle'
| 'clear'
| 'clipboard'
| 'clipboard_outlined'
| 'close'
| 'collapse'
| 'comment_outlined'
| 'comment'
| 'counter'
| 'credit_card'
| 'crop'
| 'crown_outlined'
| 'crown'
| 'cup'
| 'cursor_select'
| 'cyrillic'
| 'discord'
| 'document'
| 'dot'
| 'draw'
| 'drawing_mode'
| 'envelope'
| 'equation'
| 'eraser'
| 'european'
| 'exclamation_mark'
| 'expand'
| 'facebook'
| 'filters'
| 'forwad'
| 'friend_add'
| 'friend_checked'
| 'friend_pending'
| 'friend_remove'
| 'friends'
| 'fullscreen'
| 'funnel'
| 'ginny'
| 'globe'
| 'google'
| 'graph'
| 'greek'
| 'heading'
| 'heart_outlined'
| 'heart'
| 'highlight'
| 'home'
| 'how_to_scan'
| 'image_library'
| 'image'
| 'influence'
| 'info_outlined'
| 'info'
| 'instagram'
| 'italic'
| 'keyboard'
| 'less'
| 'line'
| 'link'
| 'linkedin'
| 'lock_with_play'
| 'logout'
| 'math_scan'
| 'medium'
| 'megaphone'
| 'menu'
| 'message_new'
| 'messages'
| 'mic'
| 'minimize'
| 'mic_muted'
| 'minus_in_circle_outlined'
| 'money_transfer'
| 'more'
| 'multiselect_checked'
| 'multiselect_unchecked'
| 'notifications'
| 'numbered_list'
| 'open_in_new_tab'
| 'options'
| 'padlock_open'
| 'padlock'
| 'pause'
| 'pdf'
| 'pencil'
| 'pi'
| 'play'
| 'plus'
| 'points'
| 'printer'
| 'profile_settings'
| 'profile_view'
| 'profile'
| 'question_alt'
| 'question'
| 'quote'
| 'recent_questions_alt'
| 'recent_questions'
| 'rectangle'
| 'reload'
| 'report_flag_outlined'
| 'report_flag'
| 'rotate_90'
| 'rotate'
| 'search'
| 'search_add'
| 'seen'
| 'send'
| 'settings'
| 'share'
| 'shield'
| 'sidebar_left'
| 'sidebar_right'
| 'smartphone'
| 'sms'
| 'spark'
| 'sparks'
| 'star_half_outlined'
| 'star_half'
| 'star_outlined'
| 'star'
| 'subtitle'
| 'sup_sub'
| 'symbols'
| 'textbook'
| 'thumb_down_outlined'
| 'thumb_down'
| 'thumb_up_outlined'
| 'thumb_up'
| 'title'
| 'tiktok'
| 'toughest_questions_alt'
| 'toughest_questions'
| 'trash'
| 'triangle'
| 'twitter'
| 'underlined'
| 'unseen'
| 'upload'
| 'user_block'
| 'verified'
| 'view_checked'
| 'warning'
| 'youtube'
| 'gift';
export type IconColorType =
| 'adaptive'
| 'icon-black'
| 'icon-white'
| 'icon-blue-50'
| 'icon-blue-60'
| 'icon-indigo-50'
| 'icon-indigo-60'
| 'icon-green-50'
| 'icon-green-60'
| 'icon-yellow-50'
| 'icon-yellow-60'
| 'icon-red-50'
| 'icon-red-60'
| 'icon-gray-70'
| 'icon-gray-60'
| 'icon-gray-50'
| 'icon-gray-40';
export type IconAsType = 'div' | 'span';
export type IconSizeType = 16 | 24 | 32 | 40 | 56 | 80 | 104;
export const TYPE = {
ACADEMIC_CAP: 'academic_cap',
ACHIEVEMENT: 'achievement',
ADD_MORE: 'add_more',
AI: 'ai',
ALL_QUESTIONS: 'all_questions',
ANSWER_BUBBLE: 'answer_bubble',
ANSWER: 'answer',
ANSWERS: 'answers',
APPLE: 'apple',
ARCHIVE_CHECKED: 'archive_checked',
ARCHIVE: 'archive',
ARROW_DOUBLE_RIGHT: 'arrow_double_right',
ARROW_DOWN: 'arrow_down',
ARROW_LEFT: 'arrow_left',
ARROW_RIGHT: 'arrow_right',
ARROW_TOP_RIGHT: 'arrow_top_right',
ARROW_UP: 'arrow_up',
ASK_BUBBLE: 'ask_bubble',
ASK_PARENT_TO_PAY: 'ask_parent_to_pay',
ATTACHMENT: 'attachment',
AUTOPUBLISH: 'autopublish',
BELL_CHECKED: 'bell_checked',
BELL_OUTLINED: 'bell_outlined',
BEST_ANSWER: 'best_answer',
BLOCK: 'block',
BOLD: 'bold',
BRAINLY_OVAL: 'brainly_oval',
BRAINLY_PARALLELOGRAM: 'brainly_parallelogram',
BULB_CHECKED: 'bulb_checked',
BULB_FILLED: 'bulb_filled',
BULB: 'bulb',
BULLETED_LIST: 'bulleted_list',
CALENDAR: 'calendar',
CAMERA: 'camera',
CARET_DOWN: 'caret_down',
CARET_UP: 'caret_up',
CHAPTER: 'chapter',
CHECK: 'check',
CHAT: 'chat',
CHECK_CIRCLE: 'check_circle',
CHEVRON_DOUBLE_DOWN: 'chevron_double_down',
CHEVRON_DOUBLE_RIGHT: 'chevron_double_right',
CHEVRON_DOWN: 'chevron_down',
CHEVRON_LEFT: 'chevron_left',
CHEVRON_RIGHT: 'chevron_right',
CHEVRON_UP: 'chevron_up',
CHEVRONS_HORIZONTAL: 'chevrons_horizontal',
CIRCLE: 'circle',
CLEAR: 'clear',
CLIPBOARD: 'clipboard',
CLIPBOARD_OUTLINED: 'clipboard_outlined',
CLOSE: 'close',
COLLAPSE: 'collapse',
COMMENT_OUTLINED: 'comment_outlined',
COMMENT: 'comment',
COUNTER: 'counter',
CREDIT_CARD: 'credit_card',
CROP: 'crop',
CROWN_OUTLINED: 'crown_outlined',
CROWN: 'crown',
CUP: 'cup',
CURSOR_SELECT: 'cursor_select',
CYRILLIC: 'cyrillic',
DOCUMENT: 'document',
DOT: 'dot',
DISCORD: 'discord',
DRAW: 'draw',
DRAWING_MODE: 'drawing_mode',
ENVELOPE: 'envelope',
EQUATION: 'equation',
ERASER: 'eraser',
EUROPEAN: 'european',
EXCLAMATION_MARK: 'exclamation_mark',
EXPAND: 'expand',
FACEBOOK: 'facebook',
FILTERS: 'filters',
FORWARD: 'forward',
FRIEND_ADD: 'friend_add',
FRIEND_CHECKED: 'friend_checked',
FRIEND_PENDING: 'friend_pending',
FRIEND_REMOVE: 'friend_remove',
FRIENDS: 'friends',
FULLSCREEN: 'fullscreen',
FUNNEL: 'funnel',
GINNY: 'ginny',
GLOBE: 'globe',
GOOGLE: 'google',
GRAPH: 'graph',
GREEK: 'greek',
HEADING: 'heading',
HEART_OUTLINED: 'heart_outlined',
HEART: 'heart',
HIGHLIGHT: 'highlight',
HOME: 'home',
HOW_TO_SCAN: 'how_to_scan',
IMAGE_LIBRARY: 'image_library',
IMAGE: 'image',
INFLUENCE: 'influence',
INFO_OUTLINED: 'info_outlined',
INFO: 'info',
INSTRAGRAM: 'instagram',
ITALIC: 'italic',
KEYBOARD: 'keyboard',
LESS: 'less',
LINE: 'line',
LINK: 'link',
LINKEDIN: 'linkedin',
LOCK_WITH_PLAY: 'lock_with_play',
LOGOUT: 'logout',
MATH_SCAN: 'math_scan',
MEDIUM: 'medium',
MEGAPHONE: 'megaphone',
MENU: 'menu',
MESSAGE_NEW: 'message_new',
MESSAGES: 'messages',
MIC: 'mic',
MINIMIZE: 'minimize',
MIC_MUTED: 'mic_muted',
MINUS_IN_CIRCLE_OUTLIEND: 'minus_in_circle_outlined',
MONEY_TRANSFER: 'money_transfer',
MORE: 'more',
MULTISELECT_CHECKED: 'multiselect_checked',
MULTISELECT_UNCHECKED: 'multiselect_unchecked',
NOTIFICATIONS: 'notifications',
NUMBERED_LIST: 'numbered_list',
OPEN_IN_NEW_TAB: 'open_in_new_tab',
OPTIONS: 'options',
PADLOCK_OPEN: 'padlock_open',
PADLOCK: 'padlock',
PAUSE: 'pause',
PDF: 'pdf',
PENCIL: 'pencil',
PI: 'pi',
PLAY: 'play',
PLUS: 'plus',
POINTS: 'points',
PRINTER: 'printer',
PROFILE_SETTINGS: 'profile_settings',
PROFILE_VIEW: 'profile_view',
PROFILE: 'profile',
QUESTION_ALT: 'question_alt',
QUESTION: 'question',
QUOTE: 'quote',
RECENT_QUESTIONS_ALT: 'recent_questions_alt',
RECENT_QUESTIONS: 'recent_questions',
RECTANGLE: 'rectangle',
RELOAD: 'reload',
REPORT_FLAG_OUTLINED: 'report_flag_outlined',
REPORT_FLAG: 'report_flag',
ROTATE_90: 'rotate_90',
ROTATE: 'rotate',
SEARCH: 'search',
SEARCH_ADD: 'search_add',
SEEN: 'seen',
SEND: 'send',
SETTINGS: 'settings',
SHARE: 'share',
SHIELD: 'shield',
SIDEBAR_LEFT: 'sidebar_left',
SIDEBAR_RIGHT: 'sidebar_right',
SMARTPHONE: 'smartphone',
SMS: 'sms',
SPARK: 'spark',
SPARKS: 'sparks',
STAR_HALF_OUTLINED: 'star_half_outlined',
STAR_HALF: 'star_half',
STAR_OUTLINED: 'star_outlined',
STAR: 'star',
SUBTITLE: 'subtitle',
SUP_SUB: 'sup_sub',
SYMBOLS: 'symbols',
TEXTBOOK: 'textbook',
THUMB_DOWN_OUTLINED: 'thumb_down_outlined',
THUMB_DOWN: 'thumb_down',
THUMB_UP_OUTLINED: 'thumb_up_outlined',
THUMB_UP: 'thumb_up',
TITLE: 'title',
TIKTOK: 'tiktok',
TOUGHEST_QUESTIONS_ALT: 'toughest_questions_alt',
TOUGHEST_QUESTIONS: 'toughest_questions',
TRASH: 'trash',
TRIANGLE: 'triangle',
TWITTER: 'twitter',
UNDERLINED: 'underlined',
UNSEEN: 'unseen',
UPLOAD: 'upload',
USER_BLOCK: 'user_block',
VERIFIED: 'verified',
VIEW_CHECKED: 'view_checked',
WARNING: 'warning',
YOUTUBE: 'youtube',
GIFT: 'gift',
} as const;
export const ICON_COLOR = {
ADAPTIVE: 'adaptive',
'icon-black': 'icon-black',
'icon-white': 'icon-white',
'icon-blue-50': 'icon-blue-50',
'icon-blue-60': 'icon-blue-60',
'icon-indigo-50': 'icon-indigo-50',
'icon-indigo-60': 'icon-indigo-60',
'icon-green-50': 'icon-green-50',
'icon-green-60': 'icon-green-60',
'icon-yellow-50': 'icon-yellow-50',
'icon-yellow-60': 'icon-yellow-60',
'icon-red-50': 'icon-red-50',
'icon-red-60': 'icon-red-60',
'icon-gray-70': 'icon-gray-70',
'icon-gray-60': 'icon-gray-60',
'icon-gray-50': 'icon-gray-50',
'icon-gray-40': 'icon-gray-40',
} as const;
export const ICON_TAG_TYPE = {
DIV: 'div',
SPAN: 'span',
} as const;
export const SIZE = [16, 24, 32, 40, 56, 80, 104];
export type IconPropsType =
| ({
/**
* Additional class names
*/
className?: string | null | undefined;
/**
* Icons colors example, see more in SG interactive
* @example
* @see color="adaptive" https://styleguide.brainly.com/latest/docs/interactive.html?color=adaptive#icons
*/
color?: IconColorType | null | undefined;
/**
* Icons size example, see more in SG interactive
* @example
* @see size="24" https://styleguide.brainly.com/latest/docs/interactive.html?size=24#icons
*/
size?: IconSizeType | null | undefined;
/**
* Icons types example, see more in SG interactive
* @example
* @see type="heart" https://styleguide.brainly.com/latest/docs/interactive.html?type=heart#icons
*/
type: IconTypeType;
/**
* Option to change tag to span, which allows correct HTML structure
* @example
*/
as?: IconAsType;
/**
* An accessible, short-text description; defaults to `type`
*/
title?: string;
/**
* An accessible, long-text description
*/
description?: string;
} & Omit<
React.AllHTMLAttributes,
'className' | 'color' | 'size' | 'type' | 'as' | 'title' | 'description'
>)
| ({
/**
* Children to be rendered inside Icon
*/
children: React.ReactNode;
/**
* Additional class names
*/
className?: string | null | undefined;
/**
* Icons colors example, see more in SG interactive
* @example
* @see color="adaptive" https://styleguide.brainly.com/latest/docs/interactive.html?color=adaptive#icons
*/
color?: IconColorType | null | undefined;
/**
* Icons size example, see more in SG interactive
* @example
* @see size="24" https://styleguide.brainly.com/latest/docs/interactive.html?size=24#icons
*/
size?: IconSizeType | null | undefined;
/**
* Option to change tag to span, which allows correct HTML structure
* @example
*/
as?: IconAsType;
/**
* An accessible, short-text description; defaults to `type`
*/
title?: string;
/**
* An accessible, long-text description
*/
description?: string;
} & Omit<
React.AllHTMLAttributes,
| 'children'
| 'className'
| 'color'
| 'size'
| 'as'
| 'title'
| 'description'
>);
function generateIdSuffix(type: string) {
return `${type}-${generateId()}`;
}
const Icon = ({
color = ICON_COLOR['icon-white'],
size = 24,
type,
children,
as = 'div',
className,
title,
description,
...props
}: IconPropsType) => {
const iconClass = classNames(
'sg-icon',
{
[`sg-icon--${String(color)}`]: color,
[`sg-icon--x${String(size)}`]: size,
},
className
);
const iconType = `#icon-${type}`;
const Tag = as;
// @ts-ignore TS2345
const idSuffix = generateIdSuffix(type);
const titleId = `title-${idSuffix}`;
const defaultTitle = String(type).replace(/_/g, ' ');
const descId = `desc-${idSuffix}`;
const labelledBy = description ? `${titleId} ${descId}` : titleId;
const ariaLabel = type
? undefined
: [title, description].filter(Boolean).join(', ');
// suppressHydrationWarning is used until 'useId' hook is available
return (
{type ? (
) : (
children
)}
);
};
export default Icon;