diff --git a/.npmignore b/.npmignore
index bf5fcafcb..2f26e1a02 100644
--- a/.npmignore
+++ b/.npmignore
@@ -51,3 +51,6 @@ CssMigrationWebpackPlugin.js
.babelrc
.prettierignore
.eslintignore
+/docs
+.idea
+yarn.lock
diff --git a/docs/src/routes/linear-progress/sample.txt b/docs/src/routes/linear-progress/sample.txt
index 72535cc65..caad3de3a 100644
--- a/docs/src/routes/linear-progress/sample.txt
+++ b/docs/src/routes/linear-progress/sample.txt
@@ -6,7 +6,7 @@ export default class SnackbarPage extends Component {
render(){
return (
-
+
);
}
diff --git a/package-lock.json b/package-lock.json
index 8a8f9873f..11bcf1590 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "preact-material-components",
- "version": "1.5.1-alpha3",
+ "version": "1.5.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1994,7 +1994,6 @@
"version": "7.0.0-beta.56",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-beta.56.tgz",
"integrity": "sha512-vP9XV2VP013UEyZdU9eWClCsm6rQPUYHVNCfmpcv5uKviW7mKmUZq71Y5cr5dYsFKfnGDxSo8h6plUGR60lwHg==",
- "dev": true,
"requires": {
"regenerator-runtime": "^0.12.0"
},
@@ -2002,8 +2001,7 @@
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
- "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==",
- "dev": true
+ "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
@@ -5616,12 +5614,12 @@
}
},
"eslint-config-prettier": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz",
- "integrity": "sha512-ag8YEyBXsm3nmOv1Hz991VtNNDMRa+MNy8cY47Pl4bw6iuzqKbJajXdqUpiw13STdLLrznxgm1hj9NhxeOYq0A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.0.1.tgz",
+ "integrity": "sha512-vA0TB8HCx/idHXfKHYcg9J98p0Q8nkfNwNAoP7e+ywUidn6ScaFS5iqncZAHPz+/a0A/tp657ulFHFx/2JDP4Q==",
"dev": true,
"requires": {
- "get-stdin": "^5.0.1"
+ "get-stdin": "^6.0.0"
}
},
"eslint-plugin-prettier": {
@@ -6160,14 +6158,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6182,20 +6178,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -6312,8 +6305,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -6325,7 +6317,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -6340,7 +6331,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -6348,14 +6338,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -6374,7 +6362,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -6455,8 +6442,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -6468,7 +6454,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -6590,7 +6575,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -6693,9 +6677,9 @@
"dev": true
},
"get-stdin": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
- "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
"dev": true
},
"get-stream": {
diff --git a/package.json b/package.json
index 23703a0f4..3dab16f6b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "preact-material-components",
- "version": "1.5.1-alpha3",
+ "version": "1.5.1",
"description": "preact wrapper for \"Material Components for the web\"",
"module": "index.js",
"main": "dist",
diff --git a/ts/Base/MaterialComponent.ts b/ts/Base/MaterialComponent.ts
index 78e515361..019c88246 100644
--- a/ts/Base/MaterialComponent.ts
+++ b/ts/Base/MaterialComponent.ts
@@ -1,7 +1,8 @@
+import MDCComponent from '@material/base/component';
import {MDCRipple} from '@material/ripple';
import autobind from 'autobind-decorator';
import {Component, VNode} from 'preact';
-import {OmitAttrs} from './types';
+import {SoftMerge} from './types';
export interface IMaterialComponentOwnProps {
ripple?: boolean;
@@ -9,11 +10,15 @@ export interface IMaterialComponentOwnProps {
export interface IMaterialComponentOwnState {}
-type MaterialComponentProps = PropType &
- IMaterialComponentOwnProps &
- OmitAttrs;
+export type MaterialComponentProps = SoftMerge<
+ PropType & IMaterialComponentOwnProps,
+ JSX.HTMLAttributes
+>;
-type MaterialComponentState = StateType & IMaterialComponentOwnState;
+export type MaterialComponentState = StateType &
+ IMaterialComponentOwnState;
+
+const doNotRemoveProps = ['disabled'];
/**
* Base class for every Material component in this package
@@ -38,15 +43,23 @@ export abstract class MaterialComponent<
/** This will again be used to add apt classname to the component */
protected abstract componentName: string;
+ /**
+ * Props of which change the MDComponent will be informed.
+ * Override to use.
+ * When used do not forget to include this.afterComponentDidMount() at the end of your componentDidMount function.
+ * Requires this.MDComponent to be defined.
+ */
+ protected mdcNotifyProps?: string[];
+
/** The final class name given to the dom */
protected classText?: string | null;
protected ripple?: MDCRipple | null;
-
protected control?: Element;
+ protected MDComponent?: MDCComponent;
public render(props): VNode {
if (!this.classText) {
- this.classText = this.buildClassName();
+ this.classText = this.buildClassName(props);
}
// Fetch a VNode
const componentProps = props;
@@ -75,6 +88,10 @@ export abstract class MaterialComponent<
.join(' ');
// Clean this shit of proxy attributes
this.mdcProps.forEach(prop => {
+ // TODO: Fix this better
+ if (prop in doNotRemoveProps) {
+ return;
+ }
delete element.attributes[prop];
});
return element;
@@ -87,12 +104,37 @@ export abstract class MaterialComponent<
}
}
+ public componentWillUpdate(nextProps: MaterialComponentProps) {
+ if (this.MDComponent && this.mdcNotifyProps) {
+ for (const prop of this.mdcNotifyProps) {
+ if (this.props[prop] !== nextProps[prop]) {
+ this.MDComponent[prop] = nextProps[prop];
+ }
+ }
+ }
+ for (const prop of this.mdcProps) {
+ if (this.props[prop] !== nextProps[prop]) {
+ this.classText = this.buildClassName(nextProps);
+ break;
+ }
+ }
+ }
+
public componentWillUnmount() {
if (this.ripple) {
this.ripple.destroy();
}
}
+ @autobind
+ protected afterComponentDidMount() {
+ if (this.MDComponent && this.mdcNotifyProps) {
+ for (const prop of this.mdcNotifyProps) {
+ this.MDComponent[prop] = this.props[prop];
+ }
+ }
+ }
+
// Shared setter for the root element ref
@autobind
protected setControlRef(control?: Element) {
@@ -101,14 +143,14 @@ export abstract class MaterialComponent<
/** Build the className based on component names and mdc props */
@autobind
- protected buildClassName() {
+ protected buildClassName(props: MaterialComponentProps) {
// Class name based on component name
let classText = 'mdc-' + this.componentName;
// Loop over mdcProps to turn them into classNames
- for (const propKey in this.props) {
- if (this.props.hasOwnProperty(propKey)) {
- const prop = this.props[propKey];
+ for (const propKey in props) {
+ if (props.hasOwnProperty(propKey)) {
+ const prop = props[propKey];
if (typeof prop === 'boolean' && prop) {
if (this.mdcProps.indexOf(propKey) !== -1) {
classText += ` mdc-${this.componentName}--${propKey}`;
diff --git a/ts/Base/types.ts b/ts/Base/types.ts
index 578702c21..2c6d7ae6b 100644
--- a/ts/Base/types.ts
+++ b/ts/Base/types.ts
@@ -1,11 +1,18 @@
-export type Diff<
- T extends string | number | symbol,
- U extends string | number | symbol
-> = ({[P in T]: P} & {[P in U]: never} & {[x: string]: never})[T];
-
-export type Omit = Pick>;
-
+/**
+ * Excludes all keys of the first type, that are also on the second type
+ *
+ * Example:
+ * type X = OmitAttrs<{b: () => void, c: any}, {a: number, b: string}>; // {c: any}
+ */
export type OmitAttrs<
T extends {[attr: string]: any},
O extends {[attr: string]: any}
-> = Pick>;
+> = Pick>;
+
+/**
+ * Merge two types and any keys that are also in the first get deleted in the second
+ *
+ * Example:
+ * type Y = SoftMerge<{a: number, b: string}, {b: () => void, c: any}>; // {a: number, b: string, c: any}
+ */
+export type SoftMerge = A & OmitAttrs;
diff --git a/ts/Checkbox/index.tsx b/ts/Checkbox/index.tsx
index 356914f77..21eb4419b 100644
--- a/ts/Checkbox/index.tsx
+++ b/ts/Checkbox/index.tsx
@@ -27,13 +27,14 @@ export class Checkbox extends MaterialComponent<
protected componentName = 'checkbox';
protected mdcProps = ['disabled'];
protected MDComponent?: MDCCheckbox;
+ protected mdcNotifyProps = ['checked', 'indeterminate', 'disabled'];
public componentDidMount() {
super.componentDidMount();
if (this.control) {
this.MDComponent = new MDCCheckbox(this.control);
- toggleCheckbox(defaultProps, this.props, this.MDComponent);
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -43,10 +44,6 @@ export class Checkbox extends MaterialComponent<
}
}
- public componentWillUpdate(nextProps) {
- toggleCheckbox(this.props, nextProps, this.MDComponent);
- }
-
@autobind
protected materialDom(allprops) {
return (
@@ -76,25 +73,4 @@ export class Checkbox extends MaterialComponent<
}
}
-/*
- * Function to add declarative opening/closing to drawer
- */
-function toggleCheckbox(oldprops, newprops, cbox) {
- if (
- 'checked' in oldprops &&
- 'checked' in newprops &&
- oldprops.checked !== newprops.checked
- ) {
- cbox.checked = newprops.checked;
- }
-
- if (
- 'indeterminate' in oldprops &&
- 'indeterminate' in newprops &&
- oldprops.indeterminate !== newprops.indeterminate
- ) {
- cbox.indeterminate = newprops.indeterminate;
- }
-}
-
export default Checkbox;
diff --git a/ts/Drawer/index.tsx b/ts/Drawer/index.tsx
index 9fce2f85b..5e7aa69f0 100644
--- a/ts/Drawer/index.tsx
+++ b/ts/Drawer/index.tsx
@@ -16,13 +16,6 @@ export interface ITemporaryDrawerProps extends IDrawerProps {}
export interface ITemporaryDrawerState extends IDrawerState {}
-/**
- * Default props for drawers
- */
-const defaultProps = {
- open: false
-};
-
export class TemporaryDrawer extends MaterialComponent<
ITemporaryDrawerProps,
ITemporaryDrawerState
@@ -30,6 +23,7 @@ export class TemporaryDrawer extends MaterialComponent<
protected componentName = 'drawer--temporary';
protected mdcProps = [];
protected MDComponent?: MDCTemporaryDrawer;
+ protected mdcNotifyProps = ['open'];
public componentDidMount() {
super.componentDidMount();
@@ -37,8 +31,8 @@ export class TemporaryDrawer extends MaterialComponent<
this.MDComponent = new MDCTemporaryDrawer(this.control);
this.MDComponent.listen('MDCTemporaryDrawer:open', this.open);
this.MDComponent.listen('MDCTemporaryDrawer:close', this.close);
- toggleDrawer(defaultProps, this.props, this.MDComponent);
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -50,10 +44,6 @@ export class TemporaryDrawer extends MaterialComponent<
}
}
- public componentWillUpdate(nextProps) {
- toggleDrawer(this.props, nextProps, this.MDComponent);
- }
-
@autobind
protected open(e) {
if (this.props.onOpen) {
@@ -123,6 +113,7 @@ export class PersistentDrawer extends MaterialComponent<
protected componentName = 'drawer--persistent';
protected mdcProps = [];
protected MDComponent?: MDCPersistentDrawer;
+ protected mdcNotifyProps = ['open'];
public componentDidMount() {
super.componentDidMount();
@@ -130,7 +121,6 @@ export class PersistentDrawer extends MaterialComponent<
this.MDComponent = new MDCPersistentDrawer(this.control);
this.MDComponent.listen('MDCPersistentDrawer:open', this.open);
this.MDComponent.listen('MDCPersistentDrawer:close', this.close);
- toggleDrawer(defaultProps, this.props, this.MDComponent);
}
}
@@ -141,10 +131,7 @@ export class PersistentDrawer extends MaterialComponent<
this.MDComponent.unlisten('MDCPersistentDrawer:open', this.open);
this.MDComponent.destroy();
}
- }
-
- public componentWillUpdate(nextProps) {
- toggleDrawer(this.props, nextProps, this.MDComponent);
+ this.afterComponentDidMount();
}
@autobind
@@ -243,19 +230,6 @@ export class DrawerItem extends ListLinkItem<
}
}
-/**
- * Function to add declarative opening/closing to drawer
- */
-function toggleDrawer(oldprops, newprops, drawer) {
- if (
- 'open' in oldprops &&
- 'open' in newprops &&
- oldprops.open !== newprops.open
- ) {
- drawer.open = newprops.open;
- }
-}
-
export class Drawer {
public static readonly DrawerContent = DrawerContent;
public static readonly DrawerHeader = DrawerHeader;
diff --git a/ts/LinearProgress/index.tsx b/ts/LinearProgress/index.tsx
index 73d1fac69..b928f6829 100644
--- a/ts/LinearProgress/index.tsx
+++ b/ts/LinearProgress/index.tsx
@@ -15,16 +15,31 @@ export class LinearProgress extends MaterialComponent<
ILinearProgressProps,
ILinearProgressState
> {
+ public defaultProps = {
+ determinate: true
+ };
+
protected componentName = 'linear-progress';
- protected mdcProps = ['indeterminate', 'reversed'];
+ protected mdcProps = ['reversed', 'indeterminate'];
protected themeProps = ['primary', 'secondary'];
protected MDComponent?: MDCLinearProgress;
+ protected mdcNotifyProps = ['progress'];
public componentDidMount() {
super.componentDidMount();
if (this.control) {
this.MDComponent = new MDCLinearProgress(this.control);
- updateProgress(this.props, this.MDComponent);
+ this.MDComponent.determinate = !this.props.indeterminate;
+ this.MDComponent.reverse = !!this.props.reversed;
+ }
+ this.afterComponentDidMount();
+ }
+
+ public componentWillUpdate(nextProps: ILinearProgressProps) {
+ super.componentWillUpdate(nextProps);
+ if (this.MDComponent) {
+ this.MDComponent.determinate = !this.props.indeterminate;
+ this.MDComponent.reverse = !!nextProps.reversed;
}
}
@@ -35,10 +50,6 @@ export class LinearProgress extends MaterialComponent<
}
}
- public componentWillUpdate(nextProps) {
- updateProgress(nextProps, this.MDComponent);
- }
-
@autobind
protected materialDom(props) {
// TODO: Fix theme props
@@ -57,10 +68,4 @@ export class LinearProgress extends MaterialComponent<
}
}
-function updateProgress(props, progressBar) {
- if (!props.indeterminate && props.progress) {
- progressBar.progress = props.progress;
- }
-}
-
export default LinearProgress;
diff --git a/ts/Menu/index.tsx b/ts/Menu/index.tsx
index ecc5135c2..7ce8c7c84 100644
--- a/ts/Menu/index.tsx
+++ b/ts/Menu/index.tsx
@@ -54,6 +54,7 @@ export class Menu extends MaterialComponent {
'open-from-bottom-right'
];
protected MDComponent?: MDCMenu;
+ protected mdcNotifyProps = ['open'];
public componentDidMount() {
super.componentDidMount();
@@ -61,8 +62,8 @@ export class Menu extends MaterialComponent {
this.MDComponent = new MDCMenu(this.control);
this.MDComponent.listen('MDCMenu:selected', this.select);
this.MDComponent.listen('MDCMenu:cancel', this.cancel);
- toggleMenu(Menu.defaultProps, this.props, this.MDComponent);
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -74,10 +75,6 @@ export class Menu extends MaterialComponent {
}
}
- public componentWillUpdate(nextProps) {
- toggleMenu(this.props, nextProps, this.MDComponent);
- }
-
@autobind
protected select(e) {
if (this.props.onSelect) {
@@ -113,17 +110,4 @@ export class Menu extends MaterialComponent {
}
}
-/*
- * Function to add declarative opening/closing to drawer
- */
-function toggleMenu(oldprops, newprops, menu) {
- if (
- 'open' in oldprops &&
- 'open' in newprops &&
- oldprops.open !== newprops.open
- ) {
- menu.open = newprops.open;
- }
-}
-
export default Menu;
diff --git a/ts/Radio/index.tsx b/ts/Radio/index.tsx
index 219eed534..ea376a382 100644
--- a/ts/Radio/index.tsx
+++ b/ts/Radio/index.tsx
@@ -14,19 +14,14 @@ export class Radio extends MaterialComponent {
protected componentName = 'radio';
protected mdcProps = ['disabled'];
protected MDComponent?: MDCRadio;
+ protected mdcNotifyProps = ['checked'];
public componentDidMount() {
super.componentDidMount();
if (this.control) {
this.MDComponent = new MDCRadio(this.control);
- toggleRadio(
- {
- checked: false
- },
- this.props,
- this.MDComponent
- );
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -36,10 +31,6 @@ export class Radio extends MaterialComponent {
}
}
- public componentWillUpdate(nextProps) {
- toggleRadio(this.props, nextProps, this.MDComponent);
- }
-
@autobind
protected materialDom(allprops) {
const {className, ...props} = allprops;
@@ -55,17 +46,4 @@ export class Radio extends MaterialComponent {
}
}
-/*
- * Function to add declarative checked to radio
- */
-function toggleRadio(oldprops, newprops, radio) {
- if (
- 'checked' in oldprops &&
- 'checked' in newprops &&
- oldprops.checked !== newprops.checked
- ) {
- radio.checked = newprops.checked;
- }
-}
-
export default Radio;
diff --git a/ts/TabBar/index.tsx b/ts/TabBar/index.tsx
index 5f1fd298c..56c44dea6 100644
--- a/ts/TabBar/index.tsx
+++ b/ts/TabBar/index.tsx
@@ -3,13 +3,6 @@ import autobind from 'autobind-decorator';
import {h} from 'preact';
import MaterialComponent from '../Base/MaterialComponent';
-/*
- * Default props for tabs
- */
-const defaultProps = {
- activeTabIndex: 0
-};
-
export interface ITabLabelProps {}
export interface ITabLabelState {}
export class TabLabel extends MaterialComponent<
@@ -44,10 +37,13 @@ export class TabIcon extends MaterialComponent {
export interface ITabProps {
active?: boolean;
}
+
export interface ITabState {}
+
export class Tab extends MaterialComponent {
protected componentName = 'tab';
protected mdcProps = ['active'];
+ protected mdcNotifyProps = ['active'];
@autobind
protected materialDom(props) {
@@ -72,24 +68,7 @@ export interface ITabsProps {
export interface ITabsState {}
-/*
- * Function to add declarative opening/closing to drawer
- */
-function setActiveTabIndex(
- oldprops: ITabsProps,
- newprops: ITabsProps,
- tabs: MDCTabBar
-) {
- if (
- oldprops.activeTabIndex &&
- newprops.activeTabIndex &&
- oldprops.activeTabIndex !== newprops.activeTabIndex
- ) {
- tabs.activeTabIndex = newprops.activeTabIndex;
- }
-}
-
-export class Tabs extends MaterialComponent {
+export class TabBar extends MaterialComponent {
public static readonly Tab = Tab;
public static readonly TabLabel = TabLabel;
public static readonly TabIcon = TabIcon;
@@ -97,13 +76,14 @@ export class Tabs extends MaterialComponent {
protected componentName = 'tab-bar';
protected mdcProps = [];
protected MDComponent?: MDCTabBar;
+ protected mdcNotifyProps = ['activeTabIndex'];
public componentDidMount() {
super.componentDidMount();
if (this.control) {
this.MDComponent = new MDCTabBar(this.control);
- setActiveTabIndex(defaultProps, this.props, this.MDComponent);
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -113,12 +93,6 @@ export class Tabs extends MaterialComponent {
}
}
- public componentWillUpdate(nextProps) {
- if (this.MDComponent) {
- setActiveTabIndex(this.props, nextProps, this.MDComponent);
- }
- }
-
@autobind
protected materialDom(props) {
return (
@@ -133,4 +107,4 @@ export class Tabs extends MaterialComponent {
}
}
-export default Tabs;
+export default TabBar;
diff --git a/ts/Tabs/index.tsx b/ts/Tabs/index.tsx
index 1f466702f..94be3b1c3 100644
--- a/ts/Tabs/index.tsx
+++ b/ts/Tabs/index.tsx
@@ -178,13 +178,14 @@ export class Tabs extends MaterialComponent {
protected componentName = 'tab-bar';
protected mdcProps = ['icon-tab-bar', 'icons-with-text'];
protected MDComponent?: MDCTabBar;
+ protected mdcNotifyProps = ['activeTabIndex'];
public componentDidMount() {
super.componentDidMount();
if (this.control) {
this.MDComponent = new MDCTabBar(this.control);
- setActiveTabIndex(defaultProps, this.props, this.MDComponent);
}
+ this.afterComponentDidMount();
}
public componentWillUnmount() {
@@ -194,12 +195,6 @@ export class Tabs extends MaterialComponent {
}
}
- public componentWillUpdate(nextProps) {
- if (this.MDComponent) {
- setActiveTabIndex(this.props, nextProps, this.MDComponent);
- }
- }
-
@autobind
protected materialDom(props) {
return (
diff --git a/ts/TextField/index.tsx b/ts/TextField/index.tsx
index 65107a97d..1396d26f3 100644
--- a/ts/TextField/index.tsx
+++ b/ts/TextField/index.tsx
@@ -1,7 +1,10 @@
import {MDCTextField} from '@material/textfield';
import autobind from 'autobind-decorator';
import {Component, h} from 'preact';
-import MaterialComponent from '../Base/MaterialComponent';
+import MaterialComponent, {
+ MaterialComponentProps
+} from '../Base/MaterialComponent';
+import {SoftMerge} from '../Base/types';
import Icon from '../Icon';
export interface IHelperTextProps {
@@ -53,7 +56,9 @@ export interface ITextFieldInputProps {
leadingIcon?: string;
trailingIcon?: string;
outerStyle?: {[key: string]: string};
- onInit: (c: MDCTextField) => any | void;
+ onInit?: (c: MDCTextField) => any | void;
+ valid?: boolean;
+ value?: string;
}
export interface ITextFieldInputState {
@@ -83,6 +88,8 @@ export class TextFieldInput extends MaterialComponent<
'outlined'
];
+ protected mdcNotifyProps = ['valid', 'disabled'];
+
public componentDidMount() {
super.componentDidMount();
this.setState(
@@ -95,16 +102,15 @@ export class TextFieldInput extends MaterialComponent<
if (this.props.onInit) {
this.props.onInit(this.MDComponent);
}
- setValid({valid: true}, this.props, this.MDComponent);
+ if (this.props.value) {
+ this.MDComponent.value = this.props.value;
+ }
}
+ this.afterComponentDidMount();
}
);
}
- public componentWillUpdate(nextProps) {
- setValid(this.props, nextProps, this.MDComponent);
- }
-
public componentWillUnmount() {
super.componentWillUnmount();
if (this.MDComponent) {
@@ -173,6 +179,17 @@ export class TextFieldInput extends MaterialComponent<
);
}
+
+ @autobind
+ protected buildClassName(
+ props: MaterialComponentProps
+ ) {
+ let cn: string = super.buildClassName(props);
+ if (this.MDComponent) {
+ cn += ' mdc-text-field--upgraded';
+ }
+ return cn;
+ }
}
type input_type =
@@ -200,7 +217,7 @@ type input_type =
| 'url'
| 'week';
-export interface ITextFieldProps extends JSX.HTMLAttributes {
+export interface ITextFieldProps {
fullwidth?: boolean;
textarea?: boolean;
type?: input_type;
@@ -216,13 +233,17 @@ export interface ITextFieldProps extends JSX.HTMLAttributes {
leadingIcon?: string; // TODO: Add to docs
trailingIcon?: string; // TODO: Add to docs
outerStyle?: {[key: string]: string};
+ value?: string;
}
export interface ITextFieldState {
showFloatingLabel: boolean;
}
-export class TextField extends Component {
+export class TextField extends Component<
+ SoftMerge,
+ ITextFieldState
+> {
public static readonly defaultProps = {
outerStyle: {}
};
@@ -299,14 +320,4 @@ export class TextField extends Component {
}
}
-function setValid(oldprops, newprops, textfield) {
- if (
- 'valid' in oldprops &&
- 'valid' in newprops &&
- oldprops.valid !== newprops.valid
- ) {
- textfield.valid = newprops.valid;
- }
-}
-
export default TextField;