diff --git a/jest.config.js b/jest.config.js index e648e6f2..c6da2987 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,5 +8,6 @@ module.exports = { lines: 80, statements: 80 } - } + }, + setupFilesAfterEnv: ['/jest.setup.ts'], }; diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 00000000..7b0828bf --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/package-lock.json b/package-lock.json index 62ec2af7..12767eb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,11 @@ "@commitlint/cli": "^17.7.2", "@commitlint/config-conventional": "^17.7.0", "@mui/icons-material": "^5.15.11", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.1.2", - "@types/jest": "^29.5.11", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.18", + "@types/jest": "^29.5.12", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.12.0", "@typescript-eslint/parser": "^6.12.0", "commitizen": "^4.3.0", @@ -77,6 +78,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", + "dev": true + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -2709,6 +2716,70 @@ "node": ">=14" } }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.3.2", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, "node_modules/@testing-library/react": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.1.2.tgz", @@ -2855,9 +2926,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -2954,19 +3025,18 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.2.45", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", - "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", + "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.2.18", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", - "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", "dev": true, "dependencies": { "@types/react": "*" @@ -2981,11 +3051,6 @@ "@types/react": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, "node_modules/@types/semver": { "version": "7.5.3", "dev": true, @@ -4497,6 +4562,12 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", diff --git a/package.json b/package.json index 6153da37..c5d658ed 100644 --- a/package.json +++ b/package.json @@ -43,10 +43,11 @@ "@commitlint/cli": "^17.7.2", "@commitlint/config-conventional": "^17.7.0", "@mui/icons-material": "^5.15.11", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.1.2", - "@types/jest": "^29.5.11", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.18", + "@types/jest": "^29.5.12", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.12.0", "@typescript-eslint/parser": "^6.12.0", "commitizen": "^4.3.0", diff --git a/src/__testing__/AddIcon.test.tsx b/src/__testing__/AddIcon.test.tsx deleted file mode 100644 index 412d774c..00000000 --- a/src/__testing__/AddIcon.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { render } from '@testing-library/react'; -import { AddIcon } from '../icons'; - -describe('AddIcon', () => { - it('renders without errors', () => { - render(); - }); - - it('applies width and height', () => { - const { getByTestId } = render(); - const svgElement = getByTestId('add-icon-svg'); - expect(svgElement.getAttribute('width')).toBe('24'); - expect(svgElement.getAttribute('height')).toBe('24'); - }); -}); diff --git a/src/__testing__/ApplicationIcon.test.tsx b/src/__testing__/ApplicationIcon.test.tsx deleted file mode 100644 index 32b71832..00000000 --- a/src/__testing__/ApplicationIcon.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { render } from '@testing-library/react'; -import { ApplicationIcon } from '../icons'; - -describe('ApplicationIcon', () => { - it('renders without errors', () => { - render(); - }); - - it('applies width and height', () => { - const { getByTestId } = render(); - const svgElement = getByTestId('application-icon-svg'); - expect(svgElement.getAttribute('width')).toBe('24'); - expect(svgElement.getAttribute('height')).toBe('24'); - }); -}); diff --git a/src/__testing__/BusIcon.test.tsx b/src/__testing__/BusIcon.test.tsx deleted file mode 100644 index 67841891..00000000 --- a/src/__testing__/BusIcon.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { render } from '@testing-library/react'; -import { BusIcon } from '../icons'; - -describe('BusIcon', () => { - it('renders without errors', () => { - render(); - }); - - it('applies width and height', () => { - const { getByTestId } = render(); - const svgElement = getByTestId('bus-icon-svg'); - expect(svgElement.getAttribute('width')).toBe('24'); - expect(svgElement.getAttribute('height')).toBe('24'); - }); -}); diff --git a/src/__testing__/CircleIcon.test.tsx b/src/__testing__/CircleIcon.test.tsx deleted file mode 100644 index 8049db62..00000000 --- a/src/__testing__/CircleIcon.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { render } from '@testing-library/react'; -import { CircleIcon } from '../icons'; - -describe('CircleIcon', () => { - it('renders without errors', () => { - render(); - }); - - it('applies width and height', () => { - const { getByTestId } = render(); - const svgElement = getByTestId('circle-icon-svg'); - expect(svgElement.getAttribute('width')).toBe('24'); - expect(svgElement.getAttribute('height')).toBe('24'); - }); -}); diff --git a/src/__testing__/SistentIcon.test.tsx b/src/__testing__/SistentIcon.test.tsx new file mode 100644 index 00000000..035893ed --- /dev/null +++ b/src/__testing__/SistentIcon.test.tsx @@ -0,0 +1,55 @@ +// SistentIcon.test.tsx +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { render, screen } from '@testing-library/react'; +import { DEFAULT_WHITE_FILL } from '../constants/constants'; +import SistentIcon from '../icons/SistentIcon'; + +describe('SistentIcon', () => { + test('renders correctly with default props', () => { + render(); + const iconElement = screen.getByRole('img'); + expect(iconElement).toBeInTheDocument(); + expect(iconElement).toHaveAttribute('width', 32); + expect(iconElement).toHaveAttribute('height', 32); + expect(iconElement).toHaveAttribute('fill', 'CHARCOAL_FILL'); + }); + + test('renders correctly with custom props', () => { + render( + + + + ); + const iconElement = screen.getByTestId('custom-icon'); + expect(iconElement).toBeInTheDocument(); + expect(iconElement).toHaveAttribute('width', '40'); + expect(iconElement).toHaveAttribute('height', '40'); + expect(iconElement).toHaveAttribute('fill', 'red'); + expect(iconElement).toHaveAttribute('stroke', 'blue'); + expect(iconElement).toHaveAttribute('stroke-width', '2'); + expect(iconElement).toHaveAttribute('viewBox', '0 0 24 24'); + }); + + test('renders correctly in dark mode', () => { + const darkTheme = createTheme({ + palette: { + mode: 'dark' + } + }); + render( + + + + ); + const iconElement = screen.getByRole('img'); + expect(iconElement).toBeInTheDocument(); + expect(iconElement).toHaveAttribute('fill', DEFAULT_WHITE_FILL); + }); +}); diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 3b23acd7..8e5a60e6 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -1,8 +1,12 @@ +import { black, carribean, charcoal, keppel, white } from '../theme'; + export const DEFAULT_WIDTH = '24'; export const DEFAULT_HEIGHT = '24'; -export const DEFAULT_FILL = '#000'; +export const DEFAULT_FILL = black.main; export const DEFAULT_FILL_NONE = 'none'; -export const KEPPEL_GREEN_FILL = '#00B39F'; -export const CARIBBEAN_GREEN_FILL = '#00D3A9'; -export const DEFAULT_STROKE = '#000'; +export const KEPPEL_GREEN_FILL = keppel[40]; +export const CARIBBEAN_GREEN_FILL = carribean[50]; +export const CHARCOAL_FILL = charcoal[40]; +export const DEFAULT_STROKE = black.main; export const DEFAULT_STROKE_WIDTH = '2'; +export const DEFAULT_WHITE_FILL = white.main; diff --git a/src/icons/AddCircle/AddCircleIcon.tsx b/src/icons/Add/AddCircleOutlineIcon.tsx similarity index 52% rename from src/icons/AddCircle/AddCircleIcon.tsx rename to src/icons/Add/AddCircleOutlineIcon.tsx index ce8be483..d733aadb 100644 --- a/src/icons/AddCircle/AddCircleIcon.tsx +++ b/src/icons/Add/AddCircleOutlineIcon.tsx @@ -1,24 +1,20 @@ -import { DEFAULT_FILL_NONE, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const AddIconCircleBordered = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = DEFAULT_FILL_NONE, - ...props -}: IconProps): JSX.Element => { +function AddCircleOutline({ fill = 'none', ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} -export default AddIconCircleBordered; +export default AddCircleOutline; + +export { AddCircleOutline }; diff --git a/src/icons/Add/AddIcon.tsx b/src/icons/Add/AddIcon.tsx index b2524af8..7526d617 100644 --- a/src/icons/Add/AddIcon.tsx +++ b/src/icons/Add/AddIcon.tsx @@ -1,16 +1,10 @@ -import { DEFAULT_FILL_NONE, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const AddIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = DEFAULT_FILL_NONE, - ...props -}: IconProps): JSX.Element => { +function AddIcon({ fill = 'none', ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} export default AddIcon; + +export { AddIcon }; diff --git a/src/icons/Add/index.ts b/src/icons/Add/index.ts index f9daca9f..8ae55bcb 100644 --- a/src/icons/Add/index.ts +++ b/src/icons/Add/index.ts @@ -1 +1,2 @@ +export { default as AddCircleOutlineIcon } from './AddCircleOutlineIcon'; export { default as AddIcon } from './AddIcon'; diff --git a/src/icons/AddCircle/index.ts b/src/icons/AddCircle/index.ts deleted file mode 100644 index 2b4a88c0..00000000 --- a/src/icons/AddCircle/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as AddCircleIcon } from './AddCircleIcon'; diff --git a/src/icons/Alert/index.tsx b/src/icons/Alert/index.tsx index 535fb8b2..a40ff526 100644 --- a/src/icons/Alert/index.tsx +++ b/src/icons/Alert/index.tsx @@ -1,26 +1,20 @@ -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -function AlertIcon({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = 'currentColor', - ...props -}: IconProps): JSX.Element { +function AlertIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); } diff --git a/src/icons/Application/ApplicationIcon.tsx b/src/icons/Application/ApplicationIcon.tsx index 177c7078..5e8e9654 100644 --- a/src/icons/Application/ApplicationIcon.tsx +++ b/src/icons/Application/ApplicationIcon.tsx @@ -1,26 +1,60 @@ -import { FC } from 'react'; -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +/** @TODO Review the fill colors, because it is different than ApplicationOutlineIcon */ +import { styled } from '@mui/material/styles'; +import { CARIBBEAN_GREEN_FILL, CHARCOAL_FILL, KEPPEL_GREEN_FILL } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -const ApplicationIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, +type ApplicationIconProps = { + primaryFill?: string; + secondaryFill?: string; + keppelColors?: boolean; +} & IconProps; + +const StyledSistentIcon = styled(SistentIcon, { + name: 'ApplicationIcon', + slot: 'Root', + overridesResolver: (props, styles) => [ + styles.root, + props.keppelColors && { '& path:nth-of-type(1)': { fill: KEPPEL_GREEN_FILL } }, + props.keppelColors && { '& path:nth-of-type(3)': { fill: KEPPEL_GREEN_FILL } }, + props.keppelColors && { '& path:nth-of-type(2)': { fill: CARIBBEAN_GREEN_FILL } } + ] +})(() => ({ + // Add any additional styles here +})); + +function ApplicationIcon({ + primaryFill = CHARCOAL_FILL, + secondaryFill = CHARCOAL_FILL, + keppelColors = false, ...props -}) => { +}: ApplicationIconProps): React.JSX.Element { + const primaryColor = keppelColors ? KEPPEL_GREEN_FILL : primaryFill; + const secondaryColor = keppelColors ? CARIBBEAN_GREEN_FILL : secondaryFill; + return ( - - - - - + + + + ); -}; +} export default ApplicationIcon; +export { ApplicationIcon }; diff --git a/src/icons/Application/ApplicationOutlineIcon.tsx b/src/icons/Application/ApplicationOutlineIcon.tsx new file mode 100644 index 00000000..51a4afae --- /dev/null +++ b/src/icons/Application/ApplicationOutlineIcon.tsx @@ -0,0 +1,63 @@ +import { useTheme } from '@mui/material/styles'; +import { + CARIBBEAN_GREEN_FILL, + DEFAULT_FILL_NONE, + DEFAULT_STROKE, + DEFAULT_WHITE_FILL, + KEPPEL_GREEN_FILL +} from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; +import { IconProps } from '../types'; + +type ApplicationIconOutlineProps = { + fill?: string; + stroke?: string; + keppelColors?: boolean; +} & IconProps; + +function ApplicationIconOutline({ + fill = DEFAULT_FILL_NONE, + stroke = DEFAULT_STROKE, + keppelColors = false, + ...props +}: ApplicationIconOutlineProps): React.JSX.Element { + const theme = useTheme(); + const isDarkMode = theme.palette.mode === 'dark'; + + const fillColor = keppelColors ? KEPPEL_GREEN_FILL : isDarkMode ? DEFAULT_WHITE_FILL : fill; + const strokeColor = keppelColors + ? CARIBBEAN_GREEN_FILL + : isDarkMode + ? DEFAULT_WHITE_FILL + : stroke; + + return ( + + + + + + ); +} + +export default ApplicationIconOutline; +export { ApplicationIconOutline }; diff --git a/src/icons/Application/KeppelApplicationIcon.tsx b/src/icons/Application/KeppelApplicationIcon.tsx deleted file mode 100644 index 9810dbe6..00000000 --- a/src/icons/Application/KeppelApplicationIcon.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { FC } from 'react'; -import { - CARIBBEAN_GREEN_FILL, - DEFAULT_HEIGHT, - DEFAULT_WIDTH, - KEPPEL_GREEN_FILL -} from '../../constants/constants'; -import { IconProps } from '../types'; - -type KeppelApplicationIconProps = { - primaryFill: string; - secondaryFill: string; -} & IconProps; - -export const KeppelApplicationIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - primaryFill = KEPPEL_GREEN_FILL, - secondaryFill = CARIBBEAN_GREEN_FILL, - ...props -}) => { - return ( - - - - - - ); -}; - -export default KeppelApplicationIcon; diff --git a/src/icons/Application/OutlinedApplicationIcon.tsx b/src/icons/Application/OutlinedApplicationIcon.tsx deleted file mode 100644 index 588ff167..00000000 --- a/src/icons/Application/OutlinedApplicationIcon.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { FC } from 'react'; -import { - DEFAULT_FILL_NONE, - DEFAULT_HEIGHT, - DEFAULT_STROKE, - DEFAULT_WIDTH -} from '../../constants/constants'; -import { IconProps } from '../types'; - -export const OutlinedApplicationIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = DEFAULT_FILL_NONE, - stroke = DEFAULT_STROKE, - ...props -}) => { - return ( - - - - - - ); -}; - -export default OutlinedApplicationIcon; diff --git a/src/icons/Application/index.ts b/src/icons/Application/index.ts index 9854399b..e09b1827 100644 --- a/src/icons/Application/index.ts +++ b/src/icons/Application/index.ts @@ -1,3 +1,2 @@ export { default as ApplicationIcon } from './ApplicationIcon'; -export { default as KeppelApplicationIcon } from './KeppelApplicationIcon'; -export { default as OutlinedApplicationIcon } from './OutlinedApplicationIcon'; +export { default as ApplicationOutlineIcon } from './ApplicationOutlineIcon'; diff --git a/src/icons/Bell/BellIcon.tsx b/src/icons/Bell/BellIcon.tsx index c90fefec..6c4f0bda 100644 --- a/src/icons/Bell/BellIcon.tsx +++ b/src/icons/Bell/BellIcon.tsx @@ -1,22 +1,20 @@ -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import React from 'react'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const BellIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - ...props -}: IconProps): JSX.Element => { +function BellIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} export default BellIcon; + +export { BellIcon }; diff --git a/src/icons/Bus/BusIcon.tsx b/src/icons/Bus/BusIcon.tsx index be0e4bcd..6aa867f6 100644 --- a/src/icons/Bus/BusIcon.tsx +++ b/src/icons/Bus/BusIcon.tsx @@ -1,18 +1,12 @@ -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const BusIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - ...props -}: IconProps): JSX.Element => { +function BusIcon({ ...props }: IconProps): React.JSX.Element { return ( - @@ -21,8 +15,10 @@ export const BusIcon = ({ - + ); -}; +} export default BusIcon; + +export { BusIcon }; diff --git a/src/icons/Circle/CircleIcon.tsx b/src/icons/Circle/CircleIcon.tsx index e6ca6523..63140b42 100644 --- a/src/icons/Circle/CircleIcon.tsx +++ b/src/icons/Circle/CircleIcon.tsx @@ -1,16 +1,11 @@ -import { DEFAULT_FILL, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import React from 'react'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const CircleIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = DEFAULT_FILL, - ...props -}: IconProps): JSX.Element => { +function CircleIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} export default CircleIcon; + +export { CircleIcon }; diff --git a/src/icons/Circle/OutlinedCircleIcon.tsx b/src/icons/Circle/CircleOutlineIcon.tsx similarity index 50% rename from src/icons/Circle/OutlinedCircleIcon.tsx rename to src/icons/Circle/CircleOutlineIcon.tsx index 0af52fa9..9fe59725 100644 --- a/src/icons/Circle/OutlinedCircleIcon.tsx +++ b/src/icons/Circle/CircleOutlineIcon.tsx @@ -1,24 +1,23 @@ -import { - DEFAULT_FILL_NONE, - DEFAULT_HEIGHT, - DEFAULT_STROKE, - DEFAULT_STROKE_WIDTH, - DEFAULT_WIDTH -} from '../../constants/constants'; +import { useTheme } from '@mui/material/styles'; +import { CHARCOAL_FILL, DEFAULT_FILL_NONE, DEFAULT_STROKE_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const OutlinedCircleIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, +function CircleOutlineIcon({ fill = DEFAULT_FILL_NONE, - stroke = DEFAULT_STROKE, + stroke = CHARCOAL_FILL, strokeWidth = DEFAULT_STROKE_WIDTH, ...props -}: IconProps): JSX.Element => { +}: IconProps): React.JSX.Element { + const theme = useTheme(); + const isDarkMode = theme.palette.mode === 'dark'; + + const fillColor = isDarkMode ? 'transparent' : fill; + const strokeColor = isDarkMode ? CHARCOAL_FILL : stroke; + return ( - - + ); -}; +} -export default OutlinedCircleIcon; +export default CircleOutlineIcon; +export { CircleOutlineIcon }; diff --git a/src/icons/Circle/index.ts b/src/icons/Circle/index.ts index ab03e9cd..5e8b6851 100644 --- a/src/icons/Circle/index.ts +++ b/src/icons/Circle/index.ts @@ -1,2 +1,2 @@ export { default as CircleIcon } from './CircleIcon'; -export { default as OutlinedCircleIcon } from './OutlinedCircleIcon'; +export { default as CircleOutlineIcon } from './CircleOutlineIcon'; diff --git a/src/icons/Clone/CloneIcon.tsx b/src/icons/Clone/CloneIcon.tsx index cc8302d4..4aee654c 100644 --- a/src/icons/Clone/CloneIcon.tsx +++ b/src/icons/Clone/CloneIcon.tsx @@ -1,23 +1,19 @@ -import { FC } from 'react'; -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const CloneIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - ...props -}) => { +function CloneIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} export default CloneIcon; + +export { CloneIcon }; diff --git a/src/icons/Close/CloseIcon.tsx b/src/icons/Close/CloseIcon.tsx index 7b291a6e..c6ed0172 100644 --- a/src/icons/Close/CloseIcon.tsx +++ b/src/icons/Close/CloseIcon.tsx @@ -1,25 +1,18 @@ -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const CloseIcon = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = 'currentColor', - ...props -}: IconProps): JSX.Element => { +function CloseIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} -export default CloseIcon; +export { CloseIcon }; diff --git a/src/icons/Fullscreen/FullScreenExitIcon.tsx b/src/icons/Fullscreen/FullScreenExitIcon.tsx index 5c0d80bb..07283895 100644 --- a/src/icons/Fullscreen/FullScreenExitIcon.tsx +++ b/src/icons/Fullscreen/FullScreenExitIcon.tsx @@ -1,24 +1,18 @@ -import { FC } from 'react'; -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const FullScreenExitIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - ...props -}) => { +function FullScreenExitIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} -export default FullScreenExitIcon; +export { FullScreenExitIcon }; diff --git a/src/icons/Fullscreen/FullScreenIcon.tsx b/src/icons/Fullscreen/FullScreenIcon.tsx index 9e63a74e..d4a0fdf5 100644 --- a/src/icons/Fullscreen/FullScreenIcon.tsx +++ b/src/icons/Fullscreen/FullScreenIcon.tsx @@ -1,24 +1,18 @@ -import { FC } from 'react'; -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -export const FullScreenIcon: FC = ({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - ...props -}) => { +function FullScreenIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); -}; +} -export default FullScreenIcon; +export { FullScreenIcon }; diff --git a/src/icons/Read/index.tsx b/src/icons/Read/index.tsx index 1fb96211..35babe51 100644 --- a/src/icons/Read/index.tsx +++ b/src/icons/Read/index.tsx @@ -1,33 +1,22 @@ -import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import React from 'react'; +import SistentIcon from '../SistentIcon'; import { IconProps } from '../types'; -function ReadIcon({ - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, - fill = 'currentColor', - ...props -}: IconProps): JSX.Element { +function ReadIcon({ ...props }: IconProps): React.JSX.Element { return ( - - + ); } -export default ReadIcon; - export { ReadIcon }; diff --git a/src/icons/SistentIcon/index.tsx b/src/icons/SistentIcon/index.tsx new file mode 100644 index 00000000..10b84ebe --- /dev/null +++ b/src/icons/SistentIcon/index.tsx @@ -0,0 +1,51 @@ +import Box from '@mui/material/Box'; +import { useTheme } from '@mui/material/styles'; +import { CHARCOAL_FILL, DEFAULT_WHITE_FILL } from '../../constants/constants'; +import { IconProps } from '../types'; + +export type IconSize = 'xsmall' | 'small' | 'medium' | 'large'; + +const iconSizes: Record = { + xsmall: { width: 16, height: 16 }, + small: { width: 24, height: 24 }, + medium: { width: 32, height: 32 }, + large: { width: 40, height: 40 } +}; + +export default function SistentIcon({ + title, + size = 'small', + fill = CHARCOAL_FILL, + stroke, + strokeWidth, + viewBox, + sx, + children, + ...rest +}: IconProps) { + const { width, height } = iconSizes[size]; + const theme = useTheme(); + const isDarkMode = theme.palette.mode === 'dark'; + + const fillColor = isDarkMode ? DEFAULT_WHITE_FILL : fill || CHARCOAL_FILL; + const strokeColor = isDarkMode && stroke ? DEFAULT_WHITE_FILL : stroke; + + return ( + + {title && {title}} + {children} + + ); +} diff --git a/src/icons/types.ts b/src/icons/types.ts index 9c08ee1a..a77a94ec 100644 --- a/src/icons/types.ts +++ b/src/icons/types.ts @@ -1,10 +1,14 @@ +import { BoxProps, SxProps, Theme } from '@mui/material'; import React from 'react'; +import { IconSize } from './SistentIcon'; export type IconProps = { - children?: never; + children?: React.ReactNode; color?: string; title?: string; width?: number | string; height?: number | string; - fill?: string; -} & React.SVGProps; + size?: IconSize; + sx?: SxProps; +} & Omit & + React.SVGProps; diff --git a/src/theme/palette.ts b/src/theme/palette.ts index dc22cc79..6a3f4c32 100644 --- a/src/theme/palette.ts +++ b/src/theme/palette.ts @@ -158,23 +158,23 @@ declare module '@mui/material/styles' { // Defines the options available for the palette. interface PaletteOptions { - border: { - default: string; - strong: string; - brand: string; - normal: string; + border?: { + default?: string; + strong?: string; + brand?: string; + normal?: string; neutral?: { default: string; alt: string; }; }; - icon: { - default: string; - secondary: string; - brand: string; - inverse: string; - weather: string; - disabled: string; + icon?: { + default?: string; + secondary?: string; + brand?: string; + inverse?: string; + weather?: string; + disabled?: string; neutral?: { default: string; alt: string;