diff --git a/README.md b/README.md index e2410d14e..a205e247d 100644 --- a/README.md +++ b/README.md @@ -1 +1,1212 @@ -Repository for react github-source \ No newline at end of file +# Syncfusion React UI Components Library (Essential JS 2) + Syncfusion React UI Components library has been built from the ground up to be lightweight, responsive, modular and touch friendly. It offers 70+ UI components that every applications will ever need. + > This is a commercial product and requires a paid license for possession or use. Syncfusion’s licensed software, including this component, is subject to the terms and conditions of Syncfusion's EULA (https://www.syncfusion.com/eula/es/). To acquire a license, you can purchase one at https://www.syncfusion.com/sales/products or start a free 30-day trial here (https://www.syncfusion.com/account/manage-trials/start-trials). +> +> A free community license (https://www.syncfusion.com/products/communitylicense) is also available for companies and individuals whose organizations have less than $1 million USD in annual gross revenue and five or fewer developers. + ## Resources + * [Getting Started](https://ej2.syncfusion.com/react/documentation/getting-started/quick-start?utm_source=npm&utm_campaign=ej2-react-ui-components) +* [View Online Demos](https://ej2.syncfusion.com/react/demos?utm_source=npm&utm_campaign=ej2-react-ui-components) +* [Product Page](https://www.syncfusion.com/react-ui-components?utm_source=npm&utm_campaign=ej2-react-ui-components) + ## Framework highlights + ### Lightweight and user friendly + The entire Library framework is built from scratch to be lightweight and modular. Its footprint can be reduced further by including only the specific components and features your application requires. + ### Modular architecture + All components have been built as modules to enable selective referencing, so only the components and features you need are included in your application. + ### Built for performance + Performance is critical for delivering a good user experience. We ensure that all our components are designed and built to achieve the best performance possible. + ### Responsive and touch friendly + All the components are touch friendly and render adaptively based on the device they are on to provide optimal usage experience on phones, tablets and desktops. + ### Stunning built-in themes + Pixel-perfect built-in themes are available in material, bootstrap and fabric design. In addition, it comes with Accessible high-contrast theme and an online tool "[Theme Studio](https://ej2.syncfusion.com/themestudio/)" to customize the provided built-in themes. + ### Globalization simplified + Easily build applications to be used by a global audience in various language and culture settings. + ### Stay current + With our commitment to at least four major updates per year, you receive the most up-to-date functionality and new components in addition to monthly service packs and bug fixes. Custom patches are available as needed. + + ## Control List + +### Grids + +
+ Data Grid + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Pivot Table + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Spreadsheet + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Tree Grid + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ In-place Editor + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Rich Text Editor + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Word Processor + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ AutoComplete + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ ComboBox + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Dropdown List + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Dropdown Tree + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ List Box + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ MultiSelect Dropdown + | ++ Source + | ++ Live demo + | ++ Documentation + | +
+ Checkbox + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Radio Button + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Toggle Switch Button + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Color Picker + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ File Upload + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Input Mask + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Numeric Textbox + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Range Slider + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ TextBox + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Signature + | ++ Source + | ++ Live demo + | ++ Documentation + | +
+ Calendar + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ DatePicker + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ DateRangePicker + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ DateTime Picker + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ TimePicker + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Gantt Chart + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Scheduler + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Accordion + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Breadcrumb + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Carousel + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Context Menu + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Menu Bar + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Sidebar + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Tabs + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Toolbar + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ TreeView + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ File Manager + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Button + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Chips + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Button Group + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Dropdown Menu + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Progress Button + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Split Button + | ++ Source + | ++ Live demo + | ++ Documentation + | +
+ Avatar + | +
+ ![]() |
+ + Styles + | ++ Live demo + | ++ Documentation + | +
+ Card + | ++ Styles + | ++ Live demo + | ++ Documentation + | +|
+ Dashboard Layout + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Splitter + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Dialog + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Tooltip + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ ListView + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Badge + | +
+ ![]() |
+ + Styles + | ++ Live demo + | ++ Documentation + | +
+ Toast + | ++ Source + | ++ Live demo + | ++ Documentation + | +|
+ Progress Bar + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Query Builder UI + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ PDF Viewer + | +
+ ![]() |
+ + Source + | ++ Live demo + | ++ Documentation + | +
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
extends React.PureComponent
{ + public static isDirective: boolean = true; + public render(): JSX.Element | null { + return null; + } +} diff --git a/components/base/src/component-base.ts b/components/base/src/component-base.ts new file mode 100644 index 000000000..4c6358855 --- /dev/null +++ b/components/base/src/component-base.ts @@ -0,0 +1,602 @@ +/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types */ +/** + * React Component Base + */ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { extend, isNullOrUndefined, setValue, getValue, isObject, onIntlChange } from '@syncfusion/ej2-base'; +/** + * Interface for processing directives + */ +interface Directive { + children: Object; + type: { + name: string; + propertyName: string; + isDirective: boolean; + moduleName: string; + isService: boolean; + }; + value: string; + isDirective: boolean; + isService: boolean; + mapper: string; + props: { [key: string]: Object }; +} + + +interface Changes { + index?: number; + value?: Object; + key?: string; +} +interface ObjectValidator { + status?: boolean; + changedProperties?: Changes[]; +} +const defaulthtmlkeys: string[] = ['alt', 'className', 'disabled', 'form', 'id', + 'readOnly', 'style', 'tabIndex', 'title', 'type', 'name', + 'onClick', 'onFocus', 'onBlur']; +const delayUpdate: string[] = ['accordion', 'tab', 'splitter']; +const isColEName: RegExp = /\]/; + +export class ComponentBase
extends React.Component
{
+ /**
+ * @private
+ */
+ public static reactUid: number = 1;
+ private setProperties: Function;
+ private element: any;
+ private mountingState: any = false;
+ private appendTo: Function;
+ private destroy: Function;
+ private getModuleName: () => string;
+ private prevProperties: Object;
+ private checkInjectedModules: boolean;
+ private curModuleName: string;
+ private getInjectedModules: Function;
+ private injectedModules: Object[];
+ private skipRefresh: string[];
+ protected htmlattributes: { [key: string]: Object };
+ private controlAttributes: string[];
+ public directivekeys: { [key: string]: Object };
+ private attrKeys: string[] = [];
+ private cachedTimeOut: number = 0;
+ private isAppendCalled: boolean = false;
+ private initRenderCalled: boolean = false;
+ private isReactForeceUpdate: boolean = false;
+ private isReact: boolean = true;
+ private isshouldComponentUpdateCalled: boolean = false;
+ private modelObserver: any;
+ private isDestroyed: boolean;
+ private isCreated: boolean = false;
+ private isProtectedOnChange: boolean;
+ private canDelayUpdate: boolean;
+ private reactElement: HTMLElement;
+ public portals: any;
+ protected value: any;
+ protected columns: any;
+ private clsName: boolean;
+
+ // Lifecycle methods are changed by React team and so we can deprecate this method and use
+ // Reference link:https://reactjs.org/docs/react-component.html#unsafe_componentWillMount
+
+ public componentDidMount(): void {
+ this.refreshChild(true);
+ this.canDelayUpdate = delayUpdate.indexOf(this.getModuleName()) !== -1;
+ // Used timeout to resolve template binding
+ // Reference link: https://github.com/facebook/react/issues/10309#issuecomment-318433235
+ this.renderReactComponent();
+ if (this.portals && this.portals.length) {
+ this.mountingState = true;
+ this.renderReactTemplates();
+ this.mountingState = false;
+ }
+ }
+
+ public componentDidUpdate(prev: Object): any {
+ if (!this.isshouldComponentUpdateCalled && this.initRenderCalled && !this.isReactForeceUpdate) {
+ if (prev !== this.props) {
+ this.isshouldComponentUpdateCalled = true;
+ this.updateProperties(this.props, false, prev);
+ }
+ }
+ }
+
+ private renderReactComponent(): void {
+ const ele: Element = this.reactElement;
+ if (ele && !this.isAppendCalled) {
+ this.isAppendCalled = true;
+ this.appendTo(ele);
+ }
+ }
+
+ // Lifecycle methods are changed by React team and so we can deprecate this method and use
+ // Reference link:https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops
+ /**
+ * @param {Object} nextProps - Specifies the property value.
+ * @returns {boolean} - Returns boolean value.
+ * @private
+ */
+ public shouldComponentUpdate(nextProps: Object): boolean {
+ this.isshouldComponentUpdateCalled = true;
+ if (!this.initRenderCalled) {
+ this.updateProperties(nextProps, true);
+ return true;
+ }
+ if (!this.isAppendCalled) {
+ clearTimeout(this.cachedTimeOut);
+ this.isAppendCalled = true;
+ this.appendTo(this.reactElement);
+ }
+ this.updateProperties(nextProps);
+ return true;
+ }
+
+ private updateProperties(nextProps: Object, silent?: boolean, prev?: Object): void {
+ const dProps: Object = extend({}, nextProps);
+ const keys: string[] = Object.keys(nextProps);
+ const prevProps: Object = extend({}, prev || this.props);
+ // The statelessTemplates props value is taken from sample level property or default component property.
+ const statelessTemplates: string[] = !isNullOrUndefined(prevProps['statelessTemplates']) ? prevProps['statelessTemplates'] :
+ (!isNullOrUndefined(this['statelessTemplateProps']) ? this['statelessTemplateProps'] : []);
+ for (const propkey of keys) {
+ const isClassName: boolean = propkey === 'className';
+ if (propkey === 'children'){
+ continue;
+ }
+ if (!isClassName && !isNullOrUndefined(this.htmlattributes[`${propkey}`]) &&
+ this.htmlattributes[`${propkey}`] !== dProps[`${propkey}`]) {
+ this.htmlattributes[`${propkey}`] = dProps[`${propkey}`];
+ }
+ if (this.compareValues(prevProps[`${propkey}`], nextProps[`${propkey}`])) {
+ delete dProps[`${propkey}`];
+ } else if (this.attrKeys.indexOf(propkey) !== -1) {
+ if (isClassName) {
+ this.clsName = true;
+ const propsClsName: string[] = prevProps[`${propkey}`].split(' ');
+ for (let i: number = 0; i < propsClsName.length; i++) {
+ this.element.classList.remove(propsClsName[parseInt(i.toString(), 10)]);
+ }
+ const dpropsClsName: string[] = dProps[`${propkey}`].split(' ');
+ for (let j: number = 0; j < dpropsClsName.length; j++) {
+ this.element.classList.add(dpropsClsName[parseInt(j.toString(), 10)]);
+ }
+ } else if (propkey !== 'disabled' && !Object.prototype.hasOwnProperty.call((this as any).properties, propkey)) {
+ delete dProps[`${propkey}`];
+ }
+ }
+ else if (propkey === 'value' && nextProps[`${propkey}`] === this[`${propkey}`]) {
+ delete dProps[`${propkey}`];
+ }
+ else if (statelessTemplates.indexOf(propkey) > -1 && ((propkey === 'content' && typeof dProps[`${propkey}`] === 'function') || (nextProps[`${propkey}`].toString() === this[`${propkey}`].toString()))) {
+ delete dProps[`${propkey}`];
+ }
+ }
+ if (dProps['children']) {
+ delete dProps['children'];
+ }
+ if (this.initRenderCalled && (this.canDelayUpdate || (prevProps as any).delayUpdate)) {
+ setTimeout(() => {
+ this.refreshProperties(dProps, nextProps, silent);
+ });
+ } else {
+ this.refreshProperties(dProps, nextProps, silent);
+ }
+ }
+ public refreshProperties(dProps: Object, nextProps: Object, silent?: boolean): void {
+ const statelessTemplates: string[] = !isNullOrUndefined(this.props['statelessTemplates']) ? this.props['statelessTemplates'] : [];
+ if (Object.keys(dProps).length) {
+ if (!silent) {
+ this.processComplexTemplate(dProps, (this as any));
+ }
+ this.setProperties(dProps, silent);
+ }
+ if (statelessTemplates.indexOf('directiveTemplates') === -1) {
+ this.refreshChild(silent, nextProps);
+ }
+ }
+
+ private processComplexTemplate(curObject: Object, context: { complexTemplate: Object }): void {
+ const compTemplate: Object = context.complexTemplate;
+ if (compTemplate) {
+ for (const prop in compTemplate) {
+ if (Object.prototype.hasOwnProperty.call(compTemplate, prop)) {
+ const PropVal: string = compTemplate[`${prop}`];
+ if (curObject[`${prop}`]) {
+ setValue(PropVal, getValue(prop, curObject), curObject);
+ }
+ }
+ }
+ }
+ }
+
+ public getDefaultAttributes(): Object {
+ this.isReact = true;
+ const propKeys: string[] = Object.keys(this.props);
+ //let stringValue: string[] = ['autocomplete', 'dropdownlist', 'combobox'];
+ const ignoreProps: string[] = ['children', 'statelessTemplates', 'immediateRender', 'isLegacyTemplate', 'delayUpdate'];
+ // if ((stringValue.indexOf(this.getModuleName()) !== -1) && (!isNullOrUndefined(this.props["value"]))) {
+ // this.value = (<{ [key: string]: Object }>this.props)["value"];
+ // }
+ if (!this.htmlattributes) {
+ this.htmlattributes = {};
+ }
+ this.attrKeys = defaulthtmlkeys.concat(this.controlAttributes || []);
+ for (const prop of propKeys) {
+ if (prop.indexOf('data-') !== -1 || prop.indexOf('aria-') !== -1 || this.attrKeys.indexOf(prop) !== -1 || (Object.keys((this as any).properties).indexOf(`${prop}`) === -1 && ignoreProps.indexOf(`${prop}`) === -1)) {
+ if (this.htmlattributes[`${prop}`] !== (<{ [key: string]: Object }>this.props)[`${prop}`]) {
+ this.htmlattributes[`${prop}`] = (<{ [key: string]: Object }>this.props)[`${prop}`];
+ }
+ }
+ }
+ if (!this.htmlattributes.ref) {
+ this.htmlattributes.ref = (ele: any ) => {
+ this.reactElement = ele;
+ };
+ const keycompoentns: string[] = ['autocomplete', 'combobox', 'dropdownlist', 'dropdowntree', 'multiselect',
+ 'listbox', 'colorpicker', 'numerictextbox', 'textbox', 'smarttextarea',
+ 'uploader', 'maskedtextbox', 'slider', 'datepicker', 'datetimepicker', 'daterangepicker', 'timepicker', 'checkbox', 'switch', 'radio', 'rating', 'textarea', 'multicolumncombobox'];
+ if (keycompoentns.indexOf(this.getModuleName()) !== -1) {
+ this.htmlattributes.key = '' + ComponentBase.reactUid;
+ ComponentBase.reactUid++;
+ if ((this as any).type && !this.htmlattributes['type']) {
+ this.htmlattributes['type'] = (this as any).multiline ? 'hidden' : (this as any).type;
+ }
+ if ((this as any).name && !this.htmlattributes['name']) {
+ this.htmlattributes['name'] = (this as any).name;
+ }
+ }
+
+ }
+ if (this.clsName) {
+ const clsList: string[] = this.element.classList;
+ const className: any = this.htmlattributes['className'];
+ for (let i: number = 0; i < clsList.length; i++){
+ if ((className.indexOf(clsList[parseInt(i.toString(), 10)]) === -1)){
+ this.htmlattributes['className'] = this.htmlattributes['className'] + ' ' + clsList[parseInt(i.toString(), 10)];
+ }
+ }
+ }
+ return this.htmlattributes;
+ }
+
+ public trigger(eventName: string, eventProp?: any, successHandler?: any): void {
+ if (this.isDestroyed !== true && this.modelObserver) {
+ if (isColEName.test(eventName)) {
+ const handler: Function = getValue(eventName, this);
+ if (handler) {
+ handler.call(this, eventProp);
+ if (successHandler) {
+ successHandler.call(this, eventProp);
+ }
+ }
+ else if (successHandler) {
+ successHandler.call(this, eventProp);
+ }
+ }
+ if ((eventName === 'change' || eventName === 'input')) {
+ if ((this.props as any).onChange && (eventProp as any).event) {
+ (this.props as any).onChange.call(undefined, {
+ syntheticEvent: (eventProp as any).event,
+ nativeEvent: { text: (eventProp as any).value },
+ value: (eventProp as any).value,
+ target: this
+ });
+ }
+ }
+ const prevDetection: boolean = this.isProtectedOnChange;
+ this.isProtectedOnChange = false;
+ if (eventName === 'created') {
+ setTimeout(() => {
+ this.isCreated = true;
+ if (!this.isDestroyed) {
+ this.modelObserver.notify(eventName, eventProp, successHandler);
+ }
+ }, 10);
+ } else {
+ this.modelObserver.notify(eventName, eventProp, successHandler);
+ }
+ this.isProtectedOnChange = prevDetection;
+ }
+
+ }
+ private compareValues(value1: any, value2: any): boolean {
+ const typeVal: string = typeof value1;
+ const typeVal2: string = typeof value2;
+ if (typeVal === typeVal2) {
+ if (value1 === value2) {
+ return true;
+ }
+ if ((!isNullOrUndefined(value1) && value1.constructor) !== (!isNullOrUndefined(value2) && value2.constructor)) {
+ return false;
+ }
+ if (value1 instanceof Date ||
+ value1 instanceof RegExp ||
+ value1 instanceof String ||
+ value1 instanceof Number
+ ) {
+ return value1.toString() === value2.toString();
+ }
+ if (isObject(value1) || Array.isArray(value1)) {
+ let tempVal: Object[] = value1;
+ let tempVal2: Object[] = value2;
+ if (isObject(tempVal)) {
+ tempVal = [value1];
+ tempVal2 = [value2];
+ }
+ return this.compareObjects(tempVal, tempVal2).status;
+ }
+ if (value1.moduleName &&
+ value1.moduleName === value2.moduleName &&
+ (value1.moduleName === 'query' ||
+ value1.moduleName === 'datamanager')) {
+ if (JSON.stringify(value1) === JSON.stringify(value2)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ public compareObjects(oldProps: any, newProps: any, propName?: string): ObjectValidator {
+ let status: boolean = true;
+ const lenSimilarity: boolean = (oldProps.length === newProps.length);
+ const diffArray: Changes[] = [];
+ const templateProps: any = !isNullOrUndefined(this['templateProps']) ? this['templateProps'] : [];
+ if (lenSimilarity) {
+ for (let i: number = 0, len: number = newProps.length; i < len; i++) {
+ const curObj: { [key: string]: Object } = {};
+ const oldProp: { [key: string]: Object } = oldProps[parseInt(i.toString(), 10)];
+ const newProp: { [key: string]: Object } = newProps[parseInt(i.toString(), 10)];
+ const keys: string[] = Object.keys(newProp);
+ if (keys.length !== 0) {
+ for (const key of keys) {
+ const oldValue: any = oldProp[`${key}`];
+ const newValue: any = newProp[`${key}`];
+ if (key === 'items') {
+ for (let _j: number = 0; _j < newValue.length; _j++) {
+ if (this.getModuleName() === 'richtexteditor' && typeof(newValue[parseInt(_j.toString(), 10)]) === 'object') {
+ return {status: true};
+ }
+ }
+ }
+ if (this.getModuleName() === 'grid' && key === 'field') {
+ curObj[`${key}`] = newValue;
+ }
+ if (!Object.prototype.hasOwnProperty.call(oldProp, key) || !((templateProps.length > 0 && templateProps.indexOf(`${key}`) === -1 && typeof(newValue) === 'function') ? this.compareValues(oldValue.toString(), newValue.toString()) : this.compareValues(oldValue, newValue))) {
+ if (!propName) {
+ return { status: false };
+ }
+ status = false;
+ curObj[`${key}`] = newValue;
+ }
+ }
+ }
+ else if (newProps[parseInt(i.toString(), 10)] === oldProps[parseInt(i.toString(), 10)]) {
+ status = true;
+ }
+ else {
+ if (!propName) {
+ return { status: false };
+ }
+ status = false;
+ }
+ if (this.getModuleName() === 'grid' && propName === 'columns' && isNullOrUndefined(curObj['field'])) {
+ curObj['field'] = undefined;
+ }
+ if (Object.keys(curObj).length) {
+ diffArray.push({ index: i, value: curObj, key: propName });
+ }
+ }
+ } else {
+ status = false;
+ }
+ return { status: status, changedProperties: diffArray };
+ }
+ private refreshChild(silent: boolean, props?: Object): void {
+ if (this.checkInjectedModules) {
+ const prevModule: Object[] = this.getInjectedModules() || [];
+ const curModule: Object[] = this.getInjectedServices() || [];
+ for (const mod of curModule) {
+ if (prevModule.indexOf(mod) === -1) {
+ prevModule.push(mod);
+ }
+ }
+ this.injectedModules = prevModule;
+ }
+ if (this.directivekeys) {
+ let changedProps: Changes[] = []; let key: string = '';
+ const directiveValue: { [key: string]: Object } = <{ [key: string]: Object }>this.validateChildren(
+ {}, this.directivekeys, (<{ children: React.ReactNode }>(props || this.props)));
+ if (directiveValue && Object.keys(directiveValue).length) {
+ if (!silent && this.skipRefresh) {
+ for (const fields of this.skipRefresh) {
+ delete directiveValue[`${fields}`];
+ }
+ }
+ if (this.prevProperties) {
+ const dKeys: any = Object.keys(this.prevProperties);
+ for (let i: number = 0; i < dKeys.length; i++) {
+ key = dKeys[parseInt(i.toString(), 10)];
+ if (!Object.prototype.hasOwnProperty.call(directiveValue, key)) {
+ continue;
+ }
+ const compareOutput: any = this.compareObjects(this.prevProperties[`${key}`], directiveValue[`${key}`], key);
+ if (compareOutput.status) {
+ delete directiveValue[`${key}`];
+ } else {
+ if (compareOutput.changedProperties.length) {
+ changedProps = changedProps.concat(compareOutput.changedProperties);
+ }
+ const obj: Object = {};
+ obj[`${key}`] = directiveValue[`${key}`];
+ this.prevProperties = extend(this.prevProperties, obj);
+ }
+ }
+ } else {
+ this.prevProperties = extend({}, directiveValue, {}, true);
+ }
+ if (changedProps.length) {
+ if (this.getModuleName() === 'grid' && key === 'columns') {
+ for (let _c1: number = 0, allColumns: any = this.columns; _c1 < allColumns.length; _c1++) {
+ const compareField1: any = getValue('field', allColumns[parseInt(_c1.toString(), 10)]);
+ const compareField2: any = getValue(_c1 + '.value.field', changedProps);
+ if (compareField1 === compareField2) {
+ const propInstance: any = getValue(changedProps[parseInt(_c1.toString(), 10)].key + '.' + changedProps[parseInt(_c1.toString(), 10)].index, this);
+ if (propInstance && propInstance.setProperties) {
+ propInstance.setProperties(changedProps[parseInt(_c1.toString(), 10)].value);
+ }
+ else {
+ extend(propInstance, changedProps[parseInt(_c1.toString(), 10)].value);
+ }
+ }
+ else {
+ this.setProperties(directiveValue, silent);
+ }
+ }
+ }
+ else {
+ for (const changes of changedProps) {
+ const propInstance: any = getValue(changes.key + '.' + changes.index, this);
+ if (propInstance && propInstance.setProperties) {
+ propInstance.setProperties(changes.value);
+ }
+ else {
+ extend(propInstance, changes.value);
+ }
+ }
+ }
+ }
+ else {
+ this.setProperties(directiveValue, silent);
+ }
+ }
+ }
+ }
+
+ public componentWillUnmount(): void {
+ clearTimeout(this.cachedTimeOut);
+ const modulesName: string[] = ['dropdowntree', 'checkbox'];
+ const hasModule: boolean = ((!modulesName.indexOf(this.getModuleName())) ? document.body.contains(this.element) : true);
+ if (this.initRenderCalled && this.isAppendCalled && this.element && hasModule && !this.isDestroyed && this.isCreated) {
+ this.destroy();
+ }
+ onIntlChange.offIntlEvents();
+ }
+
+ public appendReactElement (element: any, container: HTMLElement): void {
+ const portal: any = (ReactDOM as any).createPortal(element, container);
+ if (!this.portals) {
+ this.portals = [portal];
+ }
+ else {
+ this.portals.push(portal);
+ }
+ }
+ public renderReactTemplates (callback?: any): void {
+ this.isReactForeceUpdate = true;
+ if (callback) {
+ this.forceUpdate(callback);
+ } else {
+ this.forceUpdate();
+ }
+ this.isReactForeceUpdate = false;
+ }
+ public clearTemplate(templateNames: string[], index?: any, callback?: any): void {
+ const tempPortal: any = [];
+ if (templateNames && templateNames.length) {
+ Array.prototype.forEach.call(templateNames, (propName: string) => {
+ let propIndexCount: number = 0;
+ this.portals.forEach((portal: any) => {
+ if (portal.propName === propName) {
+ tempPortal.push(propIndexCount);
+ propIndexCount++;
+ }
+ });
+ if (!isNullOrUndefined(index) && this.portals[index as number] && this.portals[index as number].propName === propName) {
+ this.portals.splice(index, 1);
+ } else {
+ for (let i: number = 0; i < this.portals.length; i++) {
+ if (this.portals[parseInt(i.toString(), 10)].propName === propName) {
+ this.portals.splice(i, 1);
+ i--;
+ }
+ }
+ }
+ });
+ } else {
+ this.portals = [];
+ }
+ this.renderReactTemplates(callback);
+ }
+ private validateChildren(
+ childCache: { [key: string]: Object },
+ mapper: { [key: string]: Object },
+ props: { children: React.ReactNode }): Object {
+ let flag: boolean = false;
+ const childs: React.ReactNode[] & Directive[] = (
+ Getting Started .
+ Online demos .
+ Learn more
+
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
-
-
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+
+Trusted by the world's leading companies
+
+
+
+
+ Getting Started . + Online demos . + Learn more +
+ +
+
+Trusted by the world's leading companies
+
+
+
+