UNPKG

preact-material-components

Version:
145 lines 5.34 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { MDCRipple } from '@material/ripple'; import { bind } from 'bind-decorator'; import { Component } from 'preact'; const doNotRemoveProps = ['disabled']; /** * Base class for every Material component in this package * NOTE: every component should add a ref by the name of `control` to its root dom for autoInit Properties * * @export * @class MaterialComponent * @extends {Component} */ export class MaterialComponent extends Component { render(props) { if (!this.classText) { this.classText = this.buildClassName(props); } // Fetch a VNode const componentProps = props; const userDefinedClasses = componentProps.className || componentProps.class || ''; // We delete class props and add them later in the final // step so every component does not need to handle user specified classes. if (componentProps.class) { delete componentProps.class; } if (componentProps.className) { delete componentProps.className; } const element = this.materialDom(componentProps); let propName = 'attributes'; if ('props' in element) { propName = 'props'; // @ts-ignore element.props = element.props || {}; } else { element.attributes = element.attributes || {}; } // @ts-ignore element[propName].className = `${userDefinedClasses} ${this.getClassName(element)}` .split(' ') .filter((value, index, self) => self.indexOf(value) === index && value !== '') // Unique + exclude empty class names .join(' '); // Clean this shit of proxy attributes this.mdcProps.forEach(prop => { // TODO: Fix this better if (prop in doNotRemoveProps) { return; } // @ts-ignore delete element[propName][prop]; }); return element; } /** Attach the ripple effect */ componentDidMount() { if (this.props.ripple && this.control) { this.ripple = new MDCRipple(this.control); } } componentWillReceiveProps(nextProps) { 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; } } } componentWillUnmount() { if (this.ripple) { this.ripple.destroy(); } } 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 setControlRef(control) { this.control = control; } /** Build the className based on component names and mdc props */ buildClassName(props) { // Class name based on component name let classText = 'mdc-' + this.componentName; // Loop over mdcProps to turn them into classNames 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}`; } } } } return classText; } /** Returns the class name for element */ getClassName(element) { if (!element) { return ''; } let propName = 'attributes'; if ('props' in element) { propName = 'props'; // @ts-ignore element.props = element.props || {}; } else { element.attributes = element.attributes || {}; } // @ts-ignore const attrs = (element[propName] = element[propName] || {}); let classText = this.classText; if (attrs.class) { classText += ' ' + attrs.class; } if (attrs.className && attrs.className !== attrs.class) { classText += ' ' + attrs.className; } return classText; } } __decorate([ bind ], MaterialComponent.prototype, "setControlRef", null); export default MaterialComponent; //# sourceMappingURL=MaterialComponent.js.map