Skip to content

Commit

Permalink
feat: Create component "Tile" (#250) (#74)
Browse files Browse the repository at this point in the history
### Changes made 
- New component `Tile` created

---

### My pull request is for
- [ ] A bugfix
- [x] A new component
- [ ] An existing component update

### Also, it complies with the following
- In case of a `new component`
- [x] A folder with its name on `src/components/CORRESPONDING_CATEGORY`
  - [x] A `index.tsx` file where the component will be coded
- [x] New and/or updated interfaces, types, tuples and enums for the
component
- [x] A `index.test.ts` file for its units tests and create the needed
to reach at least 90% of code coverage
- [x] A `index.stories.tsx` file for storybook stories and add at least
2 stories for different scenarios

---

### Screenshots
`In case of have differences between old and new functionality, please
provide a 'Before vs After' comparrison in order to show in a graphic
way your contribution`
  • Loading branch information
NicolasOmar authored Jan 23, 2024
2 parents 563f7a6 + 6ab3119 commit f5877ac
Show file tree
Hide file tree
Showing 26 changed files with 696 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/components/atoms/Checkbox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
// TYPES & INTERFACES
import { CheckBoxProps } from '../../../interfaces/atomProps'
import { ChildrenType } from '../../../types/componentEnums'
import { ChildrenType } from '../../../types/domTypes'
// FUNCTIONS
import { parseClasses, parseTestId } from '../../../functions/parsers'

Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/Icon/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Icon from '.'
// TYPES & INTERFACES
import { IconProps } from '../../../interfaces/atomProps'
import { SizeWithoutNormalType } from '../../../types/styleTypes'
import { IconSizeEnum } from '../../../types/componentEnums'
import { IconSizeEnum } from '../../../types/domTypes'
// MOCKS
import { testing } from './index.mocks.json'

Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
// TYPES & INTERFACES
import { IconProps } from '../../../interfaces/atomProps'
import { TextColorType } from '../../../types/styleTypes'
import { IconSizeEnum } from '../../../types/componentEnums'
import { IconSizeEnum } from '../../../types/domTypes'
// FUNCTIONS
import { parseClasses, parseTestId } from '../../../functions/parsers'

Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/Image/index.mocks.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"testing": {
"basicTestId": "test-image-1by1",
"basicTestId": "test-image",
"testSrc": "https://bulma.io/images/placeholders/256x256.png",
"testClasses": {
"isRounded": "is-rounded"
Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/Image/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Image: React.FC<ImageProps> = ({
containerStyle = null,
src,
alt = null,
fixedSize = 'is-1by1',
fixedSize = null,
isRounded = false
}) => {
const imageContainerClasses = parseClasses([
Expand Down
36 changes: 36 additions & 0 deletions src/components/atoms/Tile/index.mocks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"testing": {
"basicTestId": "test-tile",
"testClasses": [
{
"name": "context",
"value": "is-ancestor",
"result": "is-ancestor"
},
{
"name": "color",
"value": "is-danger",
"result": "notification is-danger"
},
{
"name": "isVertical",
"value": true,
"result": "is-vertical"
}
],
"basicChild": {
"children": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit. Vestibulum volutpat tellus diam, consequat gravida libero rhoncus ut. Morbi maximus, leo sit amet vehicula eleifend, nunc dui porta orci, quis semper odio felis ut quam."
},
"halfSize": {
"size": "is-6"
},
"colored": {
"color": "is-primary"
}
},
"storybook": {
"parameters": {
"componentSubtitle": "A single tile element to build 2-dimensional Metro-like, Pinterest-like, or whatever-you-like grids"
}
}
}
37 changes: 37 additions & 0 deletions src/components/atoms/Tile/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { StoryFn, Meta } from '@storybook/react'
// COMPONENTS
import Tile from '.'
import { Image } from '../index'
// TYPES & INTERFACES
import { TileProps } from '../../../interfaces/atomProps'
// FUNCTIONS
// MOCKS
import { storybook, testing } from './index.mocks.json'
import imageMocks from '../Image/index.mocks.json'

export default {
title: 'Atoms/Tile',
component: Tile,
...storybook,
args: testing.basicChild
} as Meta<typeof Tile>

const Template: StoryFn<typeof Tile> = args => <Tile {...args} />

export const BasicExample = Template.bind({})

export const HalfSize = Template.bind({})
HalfSize.args = testing.halfSize as TileProps

export const Colored = Template.bind({})
Colored.args = {
...HalfSize.args,
...testing.colored
} as TileProps

export const WithImage = Template.bind({})
WithImage.args = {
...Colored.args,
children: <Image src={imageMocks.testing.testSrc} />
} as TileProps
39 changes: 39 additions & 0 deletions src/components/atoms/Tile/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import { cleanup, render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
// COMPONENTS
import Tile from '.'
// TYPES & INTERFACES
import { TileProps } from '../../../interfaces/atomProps'
// FUNCTIONS
// MOCKS
import { testing } from './index.mocks.json'

describe('Tile', () => {
const { basicTestId, testClasses } = testing

test('Should render the component', () => {
render(<Tile />)
const testTile = screen.getByTestId(basicTestId)

expect(testTile).toBeInTheDocument()
})

test('Should render the component with specific classes', () => {
testClasses.forEach(({ name, value, result }) => {
const testIdWithClass = `${basicTestId}-${result.replace(
/is-|has-|notification /gm,
''
)}`
const classTestObject: TileProps = {
[name]: value
}

render(<Tile {...classTestObject} />)

const testStylingPropValueTileGroup = screen.getByTestId(testIdWithClass)
expect(testStylingPropValueTileGroup.className).toContain(result)
cleanup()
})
})
})
54 changes: 54 additions & 0 deletions src/components/atoms/Tile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
// COMPONENTS
// TYPES & INTERFACES
import { TileProps } from '../../../interfaces/atomProps'
// FUNCTIONS
import { parseClasses, parseTestId } from '../../../functions/parsers'

const Tile: React.FC<TileProps> = ({
testId = null,
cssClasses = null,
style = null,
children,
context = null,
size = null,
color = null,
isVertical = false
}) => {
const tileClasses = parseClasses([
'tile',
context,
size,
color ? `notification ${color}` : null,
isVertical ? 'is-vertical' : null,
cssClasses
])
const tileTestId =
testId ??
parseTestId({
tag: 'tile',
parsedClasses: tileClasses,
rules: [
{
regExp: /notification |tile/gm,
replacer: ''
},
{
regExp: /is-/gm,
replacer: '-'
}
]
})

return (
<section
data-testid={tileTestId}
className={tileClasses}
style={style ?? undefined}
>
{children}
</section>
)
}

export default Tile
1 change: 1 addition & 0 deletions src/components/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export { default as Image } from './Image'
export { default as PaginationItem } from './PaginationItem'
export { default as TabItem } from './TabItem'
export { default as LevelHeader } from './LevelHeader'
export { default as Tile } from './Tile'
28 changes: 28 additions & 0 deletions src/components/molecules/TileBox/index.mocks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"testing": {
"basicTestId": "test-tileBox-child",
"extensionTestId": "box",
"testClasses": [
{
"name": "color",
"value": "is-danger",
"result": "notification is-danger"
},
{
"name": "isVertical",
"value": true,
"result": "is-vertical"
}
]
},
"storybook": {
"parameters": {
"componentSubtitle": "A small abstraction of original Tile component",
"docs": {
"description": {
"component": "Focused for `TileGroup` implementation where is needed a boxed child Tile to set up the grid styling."
}
}
}
}
}
38 changes: 38 additions & 0 deletions src/components/molecules/TileBox/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import { StoryFn, Meta } from '@storybook/react'
// COMPONENTS
import TileBox from '.'
import { Image } from '../../atoms'
// TYPES & INTERFACES
import { TileProps } from '../../../interfaces/atomProps'
// FUNCTIONS
// MOCKS
import { storybook } from './index.mocks.json'
import tileMocks from '../../atoms/Tile/index.mocks.json'
import imageMocks from '../../atoms/Image/index.mocks.json'

export default {
title: 'Molecules/TileBox',
component: TileBox,
...storybook,
args: tileMocks.testing.basicChild
} as Meta<typeof TileBox>

const Template: StoryFn<typeof TileBox> = args => <TileBox {...args} />

export const BasicExample = Template.bind({})

export const HalfSize = Template.bind({})
HalfSize.args = tileMocks.testing.halfSize as TileProps

export const Colored = Template.bind({})
Colored.args = {
...HalfSize.args,
...tileMocks.testing.colored
} as TileProps

export const WithImage = Template.bind({})
WithImage.args = {
...Colored.args,
children: <Image src={imageMocks.testing.testSrc} />
} as TileProps
40 changes: 40 additions & 0 deletions src/components/molecules/TileBox/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import { cleanup, render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
// COMPONENTS
import TileBox from '.'
// TYPES & INTERFACES
import { TileBoxProps } from '../../../interfaces/moleculeProps'
// FUNCTIONS
// MOCKS
import { testing } from './index.mocks.json'

describe('TileBox', () => {
const { basicTestId, extensionTestId, testClasses } = testing

test('Should render the component', () => {
render(<TileBox />)
const testTileBox = screen.getByTestId(`${basicTestId}${extensionTestId}`)

expect(testTileBox).toBeInTheDocument()
})

test('Should render the component with specific classes', () => {
testClasses.forEach(({ name, value, result }) => {
const testIdWithClass = `${basicTestId}-${result.replace(
/is-|has-|notification /gm,
''
)}${extensionTestId}`
const classTestObject: TileBoxProps = {
[name]: value
}

render(<TileBox {...classTestObject} />)

const testStylingPropValueTileBoxGroup =
screen.getByTestId(testIdWithClass)
expect(testStylingPropValueTileBoxGroup.className).toContain(result)
cleanup()
})
})
})
59 changes: 59 additions & 0 deletions src/components/molecules/TileBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react'
// COMPONENTS
import { Tile } from '../../atoms'
// TYPES & INTERFACES
import { TileBoxProps } from '../../../interfaces/moleculeProps'
// FUNCTIONS
import { parseClasses, parseTestId } from '../../../functions/parsers'

const TileBox: React.FC<TileBoxProps> = ({
testId = null,
cssClasses = 'box',
style = null,
children = null,
context = 'is-child',
size,
color,
isVertical
}) => {
const tileBoxClasses = parseClasses([
'tileBox',
context,
size,
color ? `notification ${color}` : null,
isVertical ? 'is-vertical' : null,
cssClasses
])
const tileBoxTestId =
testId ??
parseTestId({
tag: 'tileBox',
parsedClasses: tileBoxClasses,
rules: [
{
regExp: /notification |tileBox/gm,
replacer: ''
},
{
regExp: /is-/gm,
replacer: '-'
}
]
})

return (
<Tile
testId={tileBoxTestId}
cssClasses={cssClasses}
style={style ?? undefined}
isVertical={isVertical}
context={context}
size={size}
color={color}
>
{children ?? undefined}
</Tile>
)
}

export default TileBox
1 change: 1 addition & 0 deletions src/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { default as InputControl } from './InputControl'
export { default as PanelBlock } from './PanelBlock'
export { default as PanelTabs } from './PanelTabs'
export { default as LevelItem } from '../molecules/LevelItem'
export { default as TileBox } from './TileBox'
Loading

0 comments on commit f5877ac

Please sign in to comment.