diff --git a/src/__testing__/PinIcon.test.tsx b/src/__testing__/PinIcon.test.tsx new file mode 100644 index 000000000..d9e2c114b --- /dev/null +++ b/src/__testing__/PinIcon.test.tsx @@ -0,0 +1,90 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; +import { Tooltip } from '../base/Tooltip'; +import { OutlinedPinIcon, PinIcon } from '../icons'; +import { SistentThemeProviderWithoutBaseLine } from '../theme'; + +function renderWithTheme(ui: React.ReactElement) { + return render({ui}); +} + +const icons = [ + { name: 'PinIcon', Component: PinIcon }, + { name: 'OutlinedPinIcon', Component: OutlinedPinIcon } +]; + +describe.each(icons)('$name', ({ Component }) => { + it('renders an with viewBox "0 0 24 24"', () => { + const { container } = renderWithTheme(); + const svg = container.querySelector('svg'); + expect(svg).not.toBeNull(); + expect(svg!.getAttribute('viewBox')).toBe('0 0 24 24'); + }); + + it('renders with default width and height "24", and default fill "currentColor"', () => { + const { container } = renderWithTheme(); + const svg = container.querySelector('svg'); + expect(svg).not.toBeNull(); + expect(svg!.getAttribute('width')).toBe('24'); + expect(svg!.getAttribute('height')).toBe('24'); + expect(svg!.getAttribute('fill')).toBe('currentColor'); + }); + + it('applies custom width, height, and fill props', () => { + const { container } = renderWithTheme(); + const svg = container.querySelector('svg'); + expect(svg).not.toBeNull(); + expect(svg!.getAttribute('width')).toBe('32'); + expect(svg!.getAttribute('height')).toBe('32'); + expect(svg!.getAttribute('fill')).toBe('#ff0000'); + }); + + it('forwards extra props like aria-hidden', () => { + const { container } = renderWithTheme(); + const svg = container.querySelector('svg'); + expect(svg).not.toBeNull(); + expect(svg!.getAttribute('aria-hidden')).toBe('true'); + }); + + it('attaches a forwarded ref to the rendered element', () => { + const ref = React.createRef(); + const { container } = renderWithTheme(); + const svg = container.querySelector('svg'); + expect(ref.current).toBeInstanceOf(SVGSVGElement); + expect(ref.current).toBe(svg); + }); + + it('opens MUI Tooltip when the icon is its direct child', async () => { + const { container } = renderWithTheme( + + + + ); + const svg = container.querySelector('svg'); + expect(svg).not.toBeNull(); + + fireEvent.mouseOver(svg!); + const tooltipText = await screen.findByText('Pin tooltip'); + expect(tooltipText).not.toBeNull(); + }); +}); + +describe('PinIcon and OutlinedPinIcon path comparison', () => { + it('renders different path "d" attributes for the two icons', () => { + const { container: pinContainer } = renderWithTheme(); + const { container: outlinedContainer } = renderWithTheme(); + + const pinPath = pinContainer.querySelector('path'); + const outlinedPath = outlinedContainer.querySelector('path'); + + expect(pinPath).not.toBeNull(); + expect(outlinedPath).not.toBeNull(); + + const pinD = pinPath!.getAttribute('d'); + const outlinedD = outlinedPath!.getAttribute('d'); + + expect(pinD).toBeTruthy(); + expect(outlinedD).toBeTruthy(); + expect(pinD).not.toBe(outlinedD); + }); +}); diff --git a/src/icons/Pin/OutlinedPinIcon.tsx b/src/icons/Pin/OutlinedPinIcon.tsx new file mode 100644 index 000000000..0d664f951 --- /dev/null +++ b/src/icons/Pin/OutlinedPinIcon.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { DEFAULT_FILL_NONE, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; + +export const OutlinedPinIcon = React.forwardRef( + ({ width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, fill = DEFAULT_FILL_NONE, ...props }, ref) => { + return ( + + + + ); + } +); + +OutlinedPinIcon.displayName = 'OutlinedPinIcon'; + +export default OutlinedPinIcon; diff --git a/src/icons/Pin/PinIcon.tsx b/src/icons/Pin/PinIcon.tsx new file mode 100644 index 000000000..37de4762a --- /dev/null +++ b/src/icons/Pin/PinIcon.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { DEFAULT_FILL_NONE, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; + +export const PinIcon = React.forwardRef( + ({ width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, fill = DEFAULT_FILL_NONE, ...props }, ref) => { + return ( + + + + ); + } +); + +PinIcon.displayName = 'PinIcon'; + +export default PinIcon; diff --git a/src/icons/Pin/index.ts b/src/icons/Pin/index.ts new file mode 100644 index 000000000..617020a24 --- /dev/null +++ b/src/icons/Pin/index.ts @@ -0,0 +1,2 @@ +export { default as OutlinedPinIcon } from './OutlinedPinIcon'; +export { default as PinIcon } from './PinIcon'; diff --git a/src/icons/index.ts b/src/icons/index.ts index 8299cb93e..a465d29ed 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -149,6 +149,7 @@ export * from './Pattern'; export * from './People'; export * from './Performance'; export * from './Person'; +export * from './Pin'; export * from './PlayArrow'; export * from './Pod'; export * from './Poll';