Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
*/
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) {
* 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) {
* 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)
}
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 () {
* 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) => {
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) || {}
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
* 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 : () => {
* 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) {
* 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
}