Skip to content
This repository was archived by the owner on Jul 29, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions packages/fab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,19 @@ import '@material/react-fab/dist/fab.css';
The Fab can be used with the `span`, `i`, `img` or `svg` elements. It can also be used with the
[Material Icon](../material-icon) react component.
```html
<Fab>
<span className="material-icons">favorite</span>
</Fab>
<Fab icon={<span className="material-icons">favorite</span>}/>

<Fab>
<i className="material-icons">favorite</i>
</Fab>
<Fab icon={<i className="material-icons">favorite</i>}/>

<Fab>
<Fab icon={
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24">
...
</svg>
</Fab>
}/>

<Fab>
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>}/>

<Fab>
<MaterialIcon icon="favorite"/>
</Fab>
<Fab icon={<MaterialIcon icon="favorite"/>}/>
```

## Props
Expand All @@ -56,6 +48,7 @@ Prop Name | Type | Description
--- | --- | ---
className | String | Classes to be applied to the root element.
mini | n/a | Enables the mini variant.
icon | Element | The icon.

## Sass Mixins

Expand Down
35 changes: 16 additions & 19 deletions packages/fab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,33 @@ import withRipple from '@material/react-ripple';

export class Fab extends React.Component {

state = {
classList: new Set(),
};

get classes() {
const {classList} = this.state;
const {
mini,
className,
} = this.props;

return classnames('mdc-fab', Array.from(classList), className, {
return classnames('mdc-fab', className, {
'mdc-fab--mini': mini,
});
}

addIconClassToAllChildren = () => {
return React.Children.map(this.props.children, (item) => {
const className = `${item.props.className} mdc-fab__icon`;
const props = Object.assign({}, item.props, {className});
return React.cloneElement(item, props);
});
};
renderIcon() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment for lines above^

You are not using this.state.classList. Please remove that from state.

const {icon} = this.props;

if (!icon) {
return;
}

const updatedProps = {
className: classnames('mdc-fab__icon', icon.props.className),
};
return React.cloneElement(icon, updatedProps);
}

render() {
const {
/* eslint-disable */
children,
className,
unbounded,
mini,
Expand All @@ -47,24 +46,22 @@ export class Fab extends React.Component {
className={this.classes}
ref={initRipple}
{...otherProps}>
{this.addIconClassToAllChildren()}
{this.renderIcon()}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment for line above ^ remove children from list, since you don't use it

</button>
);
}
}

Fab.propTypes = {
mini: PropTypes.bool,
icon: PropTypes.element,
className: PropTypes.string,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.element),
PropTypes.element,
]).isRequired,
initRipple: PropTypes.func,
};

Fab.defaultProps = {
mini: false,
icon: null,
className: '',
initRipple: () => {},
};
Expand Down
162 changes: 66 additions & 96 deletions test/screenshot/fab/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,131 +8,101 @@ import MaterialIcon from '../../../packages/material-icon';

ReactDOM.render((
<div>
<Fab className="demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab className="demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab className="demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab className="demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<Fab className="demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab className="demo-button"
icon={<i className="material-icons">directions_transit</i>} />
<Fab className="demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab className="demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab className="demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab mini className="demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab mini className="demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab mini className="demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab mini className="demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
</svg>} />
<Fab className="demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
<Fab mini className="demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab mini className="demo-button"
icon={<span className="material-icons">directions_transit</span>} />
<Fab mini className="demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab mini className="demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab mini className="demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab className="demo-ink-color demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab className="demo-ink-color demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab className="demo-ink-color demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab className="demo-ink-color demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
</svg>} />
<Fab mini className="demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
<Fab className="demo-ink-color demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab className="demo-ink-color demo-button"
icon={<span className="material-icons">directions_transit</span>} />
<Fab className="demo-ink-color demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab className="demo-ink-color demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab className="demo-ink-color demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab mini className="demo-ink-color demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab mini className="demo-ink-color demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab mini className="demo-ink-color demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab mini className="demo-ink-color demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
</svg>} />
<Fab className="demo-ink-color demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
<Fab mini className="demo-ink-color demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab mini className="demo-ink-color demo-button"
icon={<span className="material-icons">directions_transit</span>} />
<Fab mini className="demo-ink-color demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab mini className="demo-ink-color demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab mini className="demo-ink-color demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab className="demo-fill-color demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab className="demo-fill-color demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab className="demo-fill-color demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab className="demo-fill-color demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
</svg>} />
<Fab mini className="demo-ink-color demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
<Fab className="demo-fill-color demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab className="demo-fill-color demo-button"
icon={<span className="material-icons">directions_transit</span>} />
<Fab className="demo-fill-color demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab className="demo-fill-color demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab className="demo-fill-color demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
<Fab mini className="demo-fill-color demo-button">
<i className="material-icons">favorite</i>
</Fab>
<Fab mini className="demo-fill-color demo-button">
<span className="material-icons">directions_transit</span>
</Fab>
<Fab mini className="demo-fill-color demo-button">
<MaterialIcon icon="add"/>
</Fab>
<Fab mini className="demo-fill-color demo-button">
<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
</svg>} />
<Fab className="demo-fill-color demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
<Fab mini className="demo-fill-color demo-button"
icon={<i className="material-icons">favorite</i>} />
<Fab mini className="demo-fill-color demo-button"
icon={<span className="material-icons">directions_transit</span>} />
<Fab mini className="demo-fill-color demo-button"
icon={<MaterialIcon icon="add"/>} />
<Fab mini className="demo-fill-color demo-button"
icon={<svg xmlns="http://www.w3.org/2000/svg" className="material-icons" viewBox="0 0 24 24" fill="#000000">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M23 12c0-6.07-4.93-11-11-11S1 5.93 1 12s4.93 11 11 11 11-4.93 11-11zM5 17.64C3.75 16.1 3 14.14 3
12c0-2.13.76-4.08 2-5.63v11.27zM17.64 5H6.36C7.9 3.75 9.86 3 12 3s4.1.75 5.64 2zM12 14.53L8.24 7h7.53L12
14.53zM17 9v8h-4l4-8zm-6 8H7V9l4 8zm6.64 2c-1.55 1.25-3.51 2-5.64 2s-4.1-.75-5.64-2h11.28zM21 12c0 2.14-.75
4.1-2 5.64V6.37c1.24 1.55 2 3.5 2 5.63z"/>
</svg>
</Fab>
<Fab mini className="demo-fill-color demo-button">
<img className="material-icons" src="/images/ic_button_24px.svg"/>
</Fab>
</svg>} />
<Fab mini className="demo-fill-color demo-button"
icon={<img className="material-icons" src="/images/ic_button_24px.svg"/>} />
</div>
), document.getElementById('app'));
18 changes: 6 additions & 12 deletions test/unit/fab/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,38 @@ test('has correct mini class', () => {
test('i tag is rendered', () => {
const icon = <i className='test-action-icon-1'></i>;
const wrapper = mount(
<Fab>
{icon}
</Fab>
<Fab icon={icon}/>
);
assert.isTrue(wrapper.find('button').children('.mdc-fab__icon').length !== 0);
});

test('span tag is rendered', () => {
const icon = <span className='test-action-icon-1'></span>;
const wrapper = mount(
<Fab>
{icon}
</Fab>
<Fab icon={icon}/>
);
assert.isTrue(wrapper.find('button').children('.mdc-fab__icon').length !== 0);
});

test('a tag is rendered', () => {
const icon = <a href="#" className='test-action-icon-1'></a>;
const wrapper = mount(
<Fab>
{icon}
</Fab>
<Fab icon={icon}/>
);
assert.isTrue(wrapper.find('button').children('.mdc-fab__icon').length !== 0);
});

test('i tag is rendered with mdc-fab__icon class', () => {
const wrapper = mount(<Fab><i className="test-class-1"></i></Fab>);
const wrapper = mount(<Fab icon={<i className="test-class-1"></i>}/>);
assert.isTrue(wrapper.find('button').find('.test-class-1').hasClass('mdc-fab__icon'));
});

test('span tag is rendered with mdc-fab__icon class', () => {
const wrapper = mount(<Fab><span className="test-class-1"></span></Fab>);
const wrapper = mount(<Fab icon={<span className="test-class-1"></span>}/>);
assert.isTrue(wrapper.find('.test-class-1').hasClass('mdc-fab__icon'));
});

test('a tag is rendered with mdc-fab__icon class', () => {
const wrapper = mount(<Fab><a className="test-class-1"></a></Fab>);
const wrapper = mount(<Fab icon={<a className="test-class-1"></a>}/>);
assert.isTrue(wrapper.find('.test-class-1').hasClass('mdc-fab__icon'));
});