diff --git a/packages/fab/index.js b/packages/fab/index.js
deleted file mode 100644
index 97af1c110..000000000
--- a/packages/fab/index.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// The MIT License
-//
-// Copyright (c) 2018 Google, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import classnames from 'classnames';
-
-import {withRipple} from '@material/react-ripple';
-
-export class Fab extends React.Component {
- get classes() {
- const {
- mini,
- textLabel,
- className,
- } = this.props;
-
- const extended = textLabel.length > 0;
-
- return classnames('mdc-fab', className, {
- 'mdc-fab--mini': mini,
- 'mdc-fab--extended': extended,
- });
- }
-
- renderIcon() {
- const {icon} = this.props;
-
- if (!icon) {
- return;
- }
-
- const updatedProps = {
- className: classnames('mdc-fab__icon', icon.props.className),
- };
- return React.cloneElement(icon, updatedProps);
- }
-
- renderTextLabel() {
- const {textLabel} = this.props;
-
- if (textLabel.length === 0) {
- return;
- }
-
- return (
-
- {textLabel}
-
- );
- }
-
- render() {
- const {
- /* eslint-disable */
- className,
- unbounded,
- mini,
- textLabel,
- /* eslint-enable */
- initRipple,
- ...otherProps
- } = this.props;
-
- return (
-
- );
- }
-}
-
-Fab.propTypes = {
- mini: PropTypes.bool,
- icon: PropTypes.element,
- textLabel: PropTypes.string,
- className: PropTypes.string,
- initRipple: PropTypes.func,
-};
-
-Fab.defaultProps = {
- mini: false,
- icon: null,
- textLabel: '',
- className: '',
- initRipple: () => {},
-};
-
-export default withRipple(Fab);
diff --git a/packages/fab/index.tsx b/packages/fab/index.tsx
new file mode 100644
index 000000000..4d8e5864d
--- /dev/null
+++ b/packages/fab/index.tsx
@@ -0,0 +1,80 @@
+// The MIT License
+//
+// Copyright (c) 2018 Google, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import * as React from 'react';
+import * as classnames from 'classnames';
+import * as Ripple from '@material/react-ripple';
+
+export interface FabProps extends Ripple.InjectedProps {
+ mini?: boolean;
+ icon?: React.ReactElement;
+ textLabel?: string;
+ className?: string;
+ initRipple: React.Ref;
+ unbounded: boolean;
+}
+
+const Icon: React.FunctionComponent<{icon?: React.ReactElement}> = ({icon}) => {
+ if (!icon) {
+ return null;
+ }
+ const updatedProps = {
+ className: classnames('mdc-fab__icon', icon.props.className),
+ };
+ return React.cloneElement(icon, updatedProps);
+};
+
+const TextLabel: React.FunctionComponent<{textLabel: string}> = ({
+ textLabel, // eslint-disable-line react/prop-types
+}) => {
+ if (textLabel.length === 0) {
+ return null;
+ }
+ return {textLabel};
+};
+
+export const Fab: React.FunctionComponent> = ({
+ /* eslint-disable react/prop-types */
+ mini = false,
+ icon,
+ textLabel = '',
+ className = '',
+ initRipple = () => {},
+ unbounded,
+ /* eslint-enable react/prop-types */
+ ...otherProps
+}) => {
+ const extended = textLabel.length > 0;
+ const classes = classnames('mdc-fab', className, {
+ 'mdc-fab--mini': mini,
+ 'mdc-fab--extended': extended,
+ });
+
+ return (
+
+ );
+};
+
+export default Ripple.withRipple(Fab);
diff --git a/test/screenshot/fab/index.js b/test/screenshot/fab/index.js
deleted file mode 100644
index 7b4e95ae1..000000000
--- a/test/screenshot/fab/index.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import React from 'react';
-import Fab from '../../../packages/fab';
-
-import '../../../packages/fab/index.scss';
-import './index.scss';
-import MaterialIcon from '../../../packages/material-icon';
-
-const FabScreenshotTest = () => {
- return (
-