Skip to content

Commit

Permalink
feat: add font size prop into icon component (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
matheus-rosa-jsm authored Feb 14, 2024
1 parent f7b39f4 commit d00c774
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 22 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export namespace Components {
interface AtomIcon {
"color"?: Color;
"icon"?: IconProps;
"size"?: 'small' | 'large';
"size"?: Size;
}
interface AtomInput {
"autocomplete"?: 'on' | 'off';
Expand Down Expand Up @@ -543,7 +543,7 @@ declare namespace LocalJSX {
interface AtomIcon {
"color"?: Color;
"icon"?: IconProps;
"size"?: 'small' | 'large';
"size"?: Size;
}
interface AtomInput {
"autocomplete"?: 'on' | 'off';
Expand Down
28 changes: 16 additions & 12 deletions packages/core/src/components/icon/icon.spec.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { newSpecPage } from '@stencil/core/testing'
import { SpecPage, newSpecPage } from '@stencil/core/testing'

import { AtomIcon } from './icon'

const URL_MOCK = 'https://atomium.juntossomosmais.com.br/icons'

describe('atom-icon', () => {
it('should render ion-icon element', async () => {
const page = await newSpecPage({
let page: SpecPage

beforeEach(async () => {
page = await newSpecPage({
components: [AtomIcon],
html: `<atom-icon icon="heart" color="primary" size="large"></atom-icon>`,
})
})

it('should size attributte to be filed with size prop when its an enum type', () => {
expect(page?.root?.shadowRoot).toEqualHtml(`
<ion-icon color="primary" icon="${URL_MOCK}/heart.svg" size="large"></ion-icon>
`)
})

if (!page?.root?.shadowRoot) {
throw new Error('page.root is undefined')
}
it('should style font-size to be filed with size prop when its an number type', async () => {
page?.root?.setAttribute('size', '10')

await page.waitForChanges()

expect(page.root).toEqualHtml(`
<atom-icon aria-hidden="true" color="primary" icon="heart" size="large">
<mock:shadow-root>
<ion-icon color="primary" icon="${URL_MOCK}/heart.svg" size="large"></ion-icon>
</mock:shadow-root>
</atom-icon>
expect(page?.root?.shadowRoot).toEqualHtml(`
<ion-icon color="primary" icon="${URL_MOCK}/heart.svg" size="" style="font-size: 10px;"></ion-icon>
`)
})
})
32 changes: 29 additions & 3 deletions packages/core/src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Color } from '@ionic/core'
import { Component, Host, Prop, h } from '@stencil/core'
import { Component, Host, Prop, State, Watch, h } from '@stencil/core'

import { IconProps } from '../../icons'

const CDN_URL = 'https://atomium.juntossomosmais.com.br/icons'

type Size = 'small' | 'large' | number

@Component({
tag: 'atom-icon',
styleUrl: 'icon.scss',
Expand All @@ -13,15 +15,39 @@ const CDN_URL = 'https://atomium.juntossomosmais.com.br/icons'
export class AtomIcon {
@Prop() color?: Color
@Prop() icon?: IconProps
@Prop() size?: 'small' | 'large'
@Prop() size?: Size

@State() validateSize?: string = ''
@State() fontSize?: string = ''

private updateSize(newSize: Size) {
this.validateSize = ''
this.fontSize = ''

if (newSize === 'small' || newSize === 'large') {
this.validateSize = newSize
} else if (newSize > 0) {
this.fontSize = `${newSize}px`
}
}

@Watch('size')
watchPropHandler(newSize: Size) {
this.updateSize(newSize)
}

componentWillLoad() {
this.updateSize(this.size)
}

render(): JSX.Element {
return (
<Host aria-hidden='true'>
<ion-icon
icon={`${CDN_URL}/${this.icon}.svg`}
color={this.color}
size={this.size}
size={this.validateSize}
style={{ fontSize: this.fontSize }}
/>
</Host>
)
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/components/icon/stories/icon.args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export const IconStoryArgs = {
},
},
size: {
control: 'select',
description: 'The size of the icon.',
options: ['small', 'large'],
control: 'text',
description:
'The size of the icon. Use large or small to change the size of the icon or pass a number to set the font-size in pixels.',
table: {
category: Category.PROPERTIES,
},
Expand All @@ -49,5 +49,5 @@ export const IconStoryArgs = {
export const IconComponentArgs = {
icon: 'heart',
color: 'secondary',
size: 'large',
size: '',
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Meta, StoryObj } from '@storybook/web-components'

import { html } from 'lit'

import { IconComponentArgs, IconStoryArgs } from './icon.args'
Expand Down

0 comments on commit d00c774

Please sign in to comment.