How to use @instructure/ui-decorator - 9 common examples

To help you get started, we’ve selected a few @instructure/ui-decorator examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github instructure / instructure-ui / packages / ui-testable / src / testable.js View on Github external
*/

import { findDOMNode } from 'react-dom'

import { decorator } from '@instructure/ui-decorator'


const testable = (
  process.env.NODE_ENV === 'production' &&
  // If you would like to the `data-cid` attributes on elements even in your
  // production builds (like if you are using them in your e2e builds or
  // something), you need to set the environment variable
  // ALWAYS_APPEND_UI_TESTABLE_LOCATORS=1
  // We do this because adding those `data-cid` locators slows things down.
  !process.env.ALWAYS_APPEND_UI_TESTABLE_LOCATORS
) ? () => (Component => Component) : decorator((ComposedComponent) => {

  const displayName = ComposedComponent.displayName || ComposedComponent.name
  const locator = {
    attribute: 'data-cid',
    value: displayName
  }
  const selector = `[${locator.attribute}~="${locator.value}"]`
  class TestableComponent extends ComposedComponent {
    static selector = selector
    componentDidMount (...args) {
      if (super.componentDidMount) {
        super.componentDidMount(...args)
      }
      this.appendLocatorAttribute()
    }
    componentDidUpdate (...args) {
github instructure / instructure-ui / packages / ui-testable / src / index.js View on Github external
* 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 { findDOMNode } from 'react-dom'

import { decorator } from '@instructure/ui-decorator'

export default decorator((ComposedComponent) => {
  const displayName = ComposedComponent.displayName || ComposedComponent.name
  const locator = {
    attribute: 'data-cid',
    value: displayName
  }
  const selector = `[${locator.attribute}~="${locator.value}"]`
  class TestableComponent extends ComposedComponent {
    static selector = selector
    componentDidMount (...args) {
      if (super.componentDidMount) {
        super.componentDidMount(...args)
      }
      this.appendLocatorAttribute()
    }
    componentDidUpdate (...args) {
      if (super.componentDidUpdate) {
github instructure / instructure-ui / packages / ui-react-utils / src / hack.js View on Github external
*  class Example extends Component {
*    static propTypes = {
*      currentProp: PropTypes.func
*    }
*  }
*  export default hack(['hackProp'])(Example)
* ```
*
* @module hack
* @param {array} hackProps
* @param {string} message
* @return {function} React component flagged as having hack props
*/
const hack = process.env.NODE_ENV == 'production'
  ? () => (Component => Component)
  : decorator((ComposedComponent, hackProps, message) => {
      return class HackComponent extends ComposedComponent {
        componentDidMount() {
          if (hackProps) {
            warnHackProps(ComposedComponent.displayName, this.props, hackProps, message)
          }

          if (super.componentDidMount) {
            super.componentDidMount()
          }
        }

        componentDidUpdate(prevProps, prevState, prevContext) {
          if (hackProps) {
            warnHackProps(ComposedComponent.displayName, this.props, hackProps, message)
          }
github instructure / instructure-ui / packages / ui-react-utils / src / windowMessageListener.js View on Github external
import { ownerWindow } from '@instructure/ui-dom-utils'

/**
 * ---
 * category: utilities/react
 * ---
 * A decorator or higher order component that provides methods
 * for cross-origin communication (between iframes/windows).
 *
 * see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
 * @module windowMessageListener
 * @param {Function} messageHandler a handler for messages recieved by the component
 * @param {Function} validSource an optional function that would restrict message handling to a specified source.
 * @returns {Function} a function that decorates a React component with the behavior
 */
 const windowMessageListener = decorator((ComposedComponent, messageHandler, validSource) => {
   return class extends ComposedComponent {
     static postMessage = function (target, message, origin) {
       target.postMessage(message, origin)
     }

     componentDidMount () {
       const win = ownerWindow(this)

       win.addEventListener('message', this.handleMessage, false)

       if (super.componentDidMount) {
         super.componentDidMount()
       }
     }

     componentWillUnmount () {
github instructure / instructure-ui / packages / ui-i18n / src / bidirectional.js View on Github external
*     return this.dir === bidirectional.DIRECTION.rtl ? <div>rtl</div> : <div>ltr</div>
*   }
* }
*
* export default bidirectional()(Example)
* ```
*
* When used as a child of [ApplyTextDirection](#ApplyTextDirection), bidirectional components use
* the direction provided in the context. When used without [ApplyTextDirection](#ApplyTextDirection),
* the direction can be supplied explicitly via the `dir` prop. If no `dir` prop is provided,
* bidirectional components query the documentElement for the `dir` attribute, defaulting to `ltr`
* if it is not present.
*
* @return {function} composes the bidirectional component.
*/
const bidirectional = decorator((ComposedComponent) =&gt; {
  return class BidirectionalComponent extends ComposedComponent {
    static propTypes = {
      ...ComposedComponent.propTypes,
      dir: PropTypes.oneOf(Object.values(TextDirectionContext.DIRECTION))
    }

    static contextTypes = {
      ...ComposedComponent.contextTypes,
      ...TextDirectionContext.types
    }

    _defaultDirection = getTextDirection()

    get dir () {
      const context = TextDirectionContext.getTextDirectionContext(this.context) || {}
github instructure / instructure-ui / packages / ui-react-utils / src / deprecated.js View on Github external
const deprecated = (() => {
  if (process.env.NODE_ENV === 'production') {
    const deprecated = function () {
      return ComposedComponent => ComposedComponent
    }

    deprecated.deprecatePropValues = () => {}
    deprecated.warnDeprecatedProps = () => {}
    deprecated.warnDeprecatedComponent = () => {}
    deprecated.changedPackageWarning = () => {}

    return deprecated
  }

  const deprecated = decorator((ComposedComponent, version, oldProps, message) => {
    /**
    * ---
    * category: utilities/react
    * ---
    * Deprecate React component props. Warnings will display in the console when deprecated
    * props are used. Include the version number when the deprecated component will be removed.
    *
    * ```js
    *  class Example extends Component {
    *    static propTypes = {
    *      currentProp: PropTypes.func
    *    }
    *  }
    *  export default deprecated('7.0.0', {
    *    deprecatedProp: 'currentProp',
    *    nowNonExistentProp: true
github instructure / instructure-ui / packages / ui-themeable / src / themeable.js View on Github external
* consuming this file directly from "/src" (as opposed to "/es" or "/lib" like normal)
 * because they need this file to not have the babel "class" transform ran against it
 * (aka they need it to use real es6 `class`es, since you can't extend real es6
 * class from es5 transpiled code)
 *
 * Which means that for the time being, we can't use any other es6/7/8 features in
 * here that aren't supported by "last 2 edge versions" since we can't rely on babel
 * to transpile them for those apps.
 *
 * So, that means don't use "static" class properties (like `static PropTypes = {...}`),
 * or object spread (like "{...foo, ..bar}")" in this file until instUI 7 is released.
 * Once we release instUI 7, the plan is to stop transpiling the "/es" dir for ie11
 * so once we do that, this caveat no longer applies.
 */

const themeable = decorator((ComposedComponent, theme, styles = {}, adapter) => {
  const displayName = ComposedComponent.displayName || ComposedComponent.name
  let componentId = `${(styles && styles.componentId) || uid()}`
  if (process.env.NODE_ENV !== 'production') {
    componentId = `${displayName}__${componentId}`
    warn(
      parseInt(React.version) >= 15,
      `[themeable] React 15 or higher is required. You are running React version ${React.version}.`,
    )
  }

  const contextKey = Symbol(componentId)

  let template = () => {}

  if (styles && styles.template) {
    template = (typeof styles.template === 'function') ? styles.template : () => {
github instructure / instructure-ui / packages / ui-react-utils / src / experimental.js View on Github external
* 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 { decorator } from '@instructure/ui-decorator'
import { warn } from '@instructure/console/macro'

const experimental = process.env.NODE_ENV == 'production'
  ? () => (Component => Component)
  : decorator((ComposedComponent, experimentalProps, message) => {
    return class ExperimentalComponent extends ComposedComponent {
      componentDidMount() {
        if (!this.props.__dangerouslyIgnoreExperimentalWarnings) {
          if (experimentalProps) {
            warnExperimentalProps(ComposedComponent.displayName, this.props, experimentalProps, message)
          } else {
            warnExperimentalComponent(ComposedComponent.displayName, message)
          }
        }

        if (super.componentDidMount) {
          super.componentDidMount()
        }
      }

      componentDidUpdate(prevProps, prevState, prevContext) {
github instructure / instructure-ui / packages / ui-utils / src / react / containerQuery.js View on Github external
* A decorator or higher order component to provide the ability to style a
 * React component with container queries.
 *
 * The containerQuery HOC provides a `size` getter so that you can alter the behavior
 * of the component based on the size of its container.
 *
 * The `size` will be updated whenever the dimensions of the container change,
 * and will be passed as a parameter to the onSizeChange prop provided.
 *
 * So that CSS rules can be applied based on the dimensions of the container,
 * custom data attributes are added to the container DOM element.
 *
 * @param {Object} query
 * @returns {Function} a function that creates an element with containerQuery behavior
 */
export default decorator((ComposedComponent, query) => {
  const getSelectorMap = function (el) {
    return query && parseQuery(query, el)
  }

  return class extends ComposedComponent {
    static getSelectorMap = getSelectorMap

    static propTypes = {
      ...ComposedComponent.propTypes,
      onSizeChange: PropTypes.func
    }

    updateAttributes = (size) => {
      if (this._size && (this._size.width === size.width && this._size.height === size.height)) {
        return
      }

@instructure/ui-decorator

A utility to wrap (decorates) a React component class adding functionality.

MIT
Latest version published 10 days ago

Package Health Score

87 / 100
Full package analysis

Popular @instructure/ui-decorator functions