/src/PropertyFieldAlignPicker.ts

https://github.com/OlivierCC/sp-client-custom-fields · TypeScript · 225 lines · 108 code · 14 blank · 103 comment · 11 complexity · f67f5dbc9043d1a2fbf252804b215f78 MD5 · raw file

  1. /**
  2. * @file PropertyFieldAlignPicker.ts
  3. * Define a custom field of type PropertyFieldAlignPicker for
  4. * the SharePoint Framework (SPfx)
  5. *
  6. * @copyright 2016 Olivier Carpentier
  7. * Released under MIT licence
  8. */
  9. import * as React from 'react';
  10. import * as ReactDom from 'react-dom';
  11. import {
  12. IPropertyPaneField,
  13. PropertyPaneFieldType,
  14. IPropertyPaneCustomFieldProps
  15. } from '@microsoft/sp-webpart-base';
  16. import PropertyFieldAlignPickerHost, { IPropertyFieldAlignPickerHostProps } from './PropertyFieldAlignPickerHost';
  17. /**
  18. * @interface
  19. * Public properties of the PropertyFieldAlignPicker custom field
  20. *
  21. */
  22. export interface IPropertyFieldAlignPickerProps {
  23. /**
  24. * @var
  25. * Property field label displayed on top
  26. */
  27. label: string;
  28. /**
  29. * @var
  30. * Initial value
  31. */
  32. initialValue?: string;
  33. /**
  34. * @function
  35. * Defines a onPropertyChange function to raise when the selected Color changed.
  36. * Normally this function must be always defined with the 'this.onPropertyChange.bind(this)'
  37. * method of the web part object.
  38. */
  39. onPropertyChanged(propertyPath: string, oldValue: any, newValue: any): void;
  40. /**
  41. * @function
  42. * This API is called to render the web part.
  43. * Normally this function must be always defined with the 'this.render.bind(this)'
  44. * method of the web part object.
  45. */
  46. render(): void;
  47. /**
  48. * This property is used to indicate the web part's PropertyPane interaction mode: Reactive or NonReactive.
  49. * The default behaviour is Reactive.
  50. */
  51. disableReactivePropertyChanges?: boolean;
  52. /**
  53. * @var
  54. * Parent Web Part properties
  55. */
  56. properties: any;
  57. /**
  58. * @var
  59. * An UNIQUE key indicates the identity of this control
  60. */
  61. key?: string;
  62. /**
  63. * Whether the property pane field is enabled or not.
  64. */
  65. disabled?: boolean;
  66. /**
  67. * The method is used to get the validation error message and determine whether the input value is valid or not.
  68. *
  69. * When it returns string:
  70. * - If valid, it returns empty string.
  71. * - If invalid, it returns the error message string and the text field will
  72. * show a red border and show an error message below the text field.
  73. *
  74. * When it returns Promise<string>:
  75. * - The resolved value is display as error message.
  76. * - The rejected, the value is thrown away.
  77. *
  78. */
  79. onGetErrorMessage?: (value: string) => string | Promise<string>;
  80. /**
  81. * Custom Field will start to validate after users stop typing for `deferredValidationTime` milliseconds.
  82. * Default value is 200.
  83. */
  84. deferredValidationTime?: number;
  85. }
  86. /**
  87. * @interface
  88. * Private properties of the PropertyFieldAlignPicker custom field.
  89. * We separate public & private properties to include onRender & onDispose method waited
  90. * by the PropertyFieldCustom, witout asking to the developer to add it when he's using
  91. * the PropertyFieldAlignPicker.
  92. *
  93. */
  94. export interface IPropertyFieldAlignPickerPropsInternal extends IPropertyPaneCustomFieldProps {
  95. label: string;
  96. initialValue?: string;
  97. targetProperty: string;
  98. onRender(elem: HTMLElement): void;
  99. onDispose(elem: HTMLElement): void;
  100. onPropertyChanged(propertyPath: string, oldValue: any, newValue: any): void;
  101. render(): void;
  102. disableReactivePropertyChanges?: boolean;
  103. properties: any;
  104. key: string;
  105. disabled?: boolean;
  106. onGetErrorMessage?: (value: string) => string | Promise<string>;
  107. deferredValidationTime?: number;
  108. }
  109. /**
  110. * @interface
  111. * Represents a PropertyFieldAlignPicker object
  112. *
  113. */
  114. class PropertyFieldAlignPickerBuilder implements IPropertyPaneField<IPropertyFieldAlignPickerPropsInternal> {
  115. //Properties defined by IPropertyPaneField
  116. public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom;
  117. public targetProperty: string;
  118. public properties: IPropertyFieldAlignPickerPropsInternal;
  119. //Custom properties
  120. private label: string;
  121. private initialValue: string;
  122. private onPropertyChanged: (propertyPath: string, oldValue: any, newValue: any) => void;
  123. private customProperties: any;
  124. private key: string;
  125. private disabled: boolean = false;
  126. private onGetErrorMessage: (value: string) => string | Promise<string>;
  127. private deferredValidationTime: number = 200;
  128. private renderWebPart: () => void;
  129. private disableReactivePropertyChanges: boolean = false;
  130. /**
  131. * @function
  132. * Ctor
  133. */
  134. public constructor(_targetProperty: string, _properties: IPropertyFieldAlignPickerPropsInternal) {
  135. this.render = this.render.bind(this);
  136. this.targetProperty = _properties.targetProperty;
  137. this.properties = _properties;
  138. this.label = _properties.label;
  139. this.initialValue = _properties.initialValue;
  140. this.properties.onDispose = this.dispose;
  141. this.properties.onRender = this.render;
  142. this.onPropertyChanged = _properties.onPropertyChanged;
  143. this.customProperties = _properties.properties;
  144. this.key = _properties.key;
  145. if (_properties.disabled === true)
  146. this.disabled = _properties.disabled;
  147. this.onGetErrorMessage = _properties.onGetErrorMessage;
  148. if (_properties.deferredValidationTime !== undefined)
  149. this.deferredValidationTime = _properties.deferredValidationTime;
  150. this.renderWebPart = _properties.render;
  151. if (_properties.disableReactivePropertyChanges !== undefined && _properties.disableReactivePropertyChanges != null)
  152. this.disableReactivePropertyChanges = _properties.disableReactivePropertyChanges;
  153. }
  154. /**
  155. * @function
  156. * Renders the field content
  157. */
  158. private render(elem: HTMLElement): void {
  159. //Construct the JSX properties
  160. const element: React.ReactElement<IPropertyFieldAlignPickerHostProps> = React.createElement(PropertyFieldAlignPickerHost, {
  161. label: this.label,
  162. initialValue: this.initialValue,
  163. targetProperty: this.targetProperty,
  164. onDispose: this.dispose,
  165. onRender: this.render,
  166. onPropertyChanged: this.onPropertyChanged,
  167. properties: this.customProperties,
  168. key: this.key,
  169. disabled: this.disabled,
  170. onGetErrorMessage: this.onGetErrorMessage,
  171. deferredValidationTime: this.deferredValidationTime,
  172. render: this.renderWebPart,
  173. disableReactivePropertyChanges: this.disableReactivePropertyChanges
  174. });
  175. //Calls the REACT content generator
  176. ReactDom.render(element, elem);
  177. }
  178. /**
  179. * @function
  180. * Disposes the current object
  181. */
  182. private dispose(elem: HTMLElement): void {
  183. }
  184. }
  185. /**
  186. * @function
  187. * Helper method to create the customer field on the PropertyPane.
  188. * @param targetProperty - Target property the custom field is associated to.
  189. * @param properties - Strongly typed custom field properties.
  190. */
  191. export function PropertyFieldAlignPicker(targetProperty: string, properties: IPropertyFieldAlignPickerProps): IPropertyPaneField<IPropertyFieldAlignPickerPropsInternal> {
  192. //Create an internal properties object from the given properties
  193. var newProperties: IPropertyFieldAlignPickerPropsInternal = {
  194. label: properties.label,
  195. targetProperty: targetProperty,
  196. initialValue: properties.initialValue,
  197. onPropertyChanged: properties.onPropertyChanged,
  198. properties: properties.properties,
  199. onDispose: null,
  200. onRender: null,
  201. key: properties.key,
  202. disabled: properties.disabled,
  203. onGetErrorMessage: properties.onGetErrorMessage,
  204. deferredValidationTime: properties.deferredValidationTime,
  205. render: properties.render,
  206. disableReactivePropertyChanges: properties.disableReactivePropertyChanges
  207. };
  208. //Calls the PropertyFieldAlignPicker builder object
  209. //This object will simulate a PropertyFieldCustom to manage his rendering process
  210. return new PropertyFieldAlignPickerBuilder(targetProperty, newProperties);
  211. }