Control parsing
CLI settings and JSDocs in your repo
Once you have configured your CLI settings, you can parse your component source code using the CLI to generate JSON config describing your components. This page describes how you can control the specific config generated for each component.
Controlling which components are imported
There are 2 ways to exclude components from the Interplay config created by the CLI:
1. Custom component parsing index
We recommend creating a custom index file that only exports the components you want in Interplay, to use as the entry point for CLI parsing.
Your parsing index file must:
- Export your components individually (as named exports or
default
)
- Use the same export names as the build you provide
- Be set as the
src
entry path for the relevant package in your CLI settings file, to tell the CLI to use your custom index.
2. ignoreExports setting
If you are parsing an existing index file that contains exports you want to exclude from Interplay, you can set which export names to exclude in the ignoreExports
CLI setting for that package.
Component config structure
Before attempting to modify the component config it is useful to see an example of how it is structured. After running the parsing step you can see the config the CLI has created for your components in your .interplay/deploy/code.json
file.
"< identifier value >": {
"id": "< identifier value >",
"name": "Button "description": "Here is the component description",
"code": {
"packageName": "reactstrap",
"exportName": "Button",
"lib": "reactstrap"
},
"path": "Actions/Buttons",
"props": {
"variant": {
"name": "variant",
"type": "string"
},
"size": {
"name": "size",
"type": "string",
"enum": [ "small", "medium", "large" ],
"default": "medium",
"ui": { "hidden": true }
},
//...(more props) },
"relativePath": "src/Button.js"
},
Component
name
- the component name to display in Interplay
description
- the description text displayed in Interplay
code
- this block specifies how the Interplay accesses this component in the your build
path
- Interplay folder structure for Button (available CLI 2.0.0+)
Component props
type
- how Interplay should treat the value set for this prop
- Currently a single type is supported per prop
- Current allowed values are
string
,number
,boolean
,object
,date
,array
,Node
,Event
,Component
,fnNode
,unknown
enum
- sets the allowed values for the prop - these will appear as a dropdown in properties panel
ui.hidden
- prevent prop displaying in Interplay and plugins (can still edit online in Edit Properties)
Controlling Component Config
1. In your component source file
The Interplay parser will generate metadata from your source code. For React components you can set:
displayName - to set the name that Interplay will use for your component. If this is not set it will default to the filename containing the component.
class StatefulButton extends React.Component {
//(StatefulButton implementation)
}
StatefulButton.displayName = "Button"
propTypes (react) or type definitions for your props - we recommend controlling property type information information using prop-types or typescript types definitions in your code. The CLI parser will find this type information and use it to generate Interplay configuration.
e.g. Using proptypes to specify the allowed values for a property, which will appear as dropdown in Interplay props panel
//Button.js
import PropTypes from 'prop-types';
//(Button implementation)
Button.propTypes = {
variant: PropTypes.oneOf(['success', 'warning', 'error']),
//more Button props
}
e.g. Using typescript to specify allowed values
//Button.ts
export type Size = 'small' | 'medium' | 'large'
export interface IButtonProps {
/** The size of the button */
size?: Size //using variable
variant?: 'success' | 'warning' | 'error'; //inline values
//more Button props
}
const Button = ({ children, ...props }: IButtonProps) => {
//Button implementation
}
2. Using JSDoc tags
You can modify the component config generated by adding JSDoc tags to the component definition, or to the props definitions, using the format @interplay {type} attribute - value
type
is the type of value you are providing (string
,number
,boolean, object
orarray
)
- attribute is the dot path to the attribute you are modifying from where the JSDoc tag is applied
is used as delimiter between attribute and value
value
is the value to set, parsed based on{type}
Components
Here are some examples of setting attributes on the component object using this approach:
description
You can add normal JSDoc comments to your components and their properties and they will be used as the component description
in Interplay when discovered by the parser:
/**
* Normal JSDoc description will be set on component by Interplay
*/
class Button extends React.Component { }
You can set a custom description for Interplay with a JSDoc tag
/**
* Default description of Button
* @interplay {string} description - Custom description parsed by Interplay CLI
*
*/
class Button extends React.Component { }
path
You can create and control the folder that your component is displayed in by setting the path
attribute. On running the import, the equivalent folders will be created in Interplay if they do not already exist:
Props
Here are some examples setting attributes on a prop declaration.
/** Default description of variant prop
* @interplay {string} description - Here is my override variant description
* @interplay {boolean} ui.hidden - true
* @interplay {string} type - number
* @interplay {array} enum - ["primary", "secondary", "danger", "warning"]
* @interplay {number} default - 0
*/
variant: PropTypes.string
description
You use JSDoc comments for the prop description (as for components), and or set a custom description using an interplay JSDoc tag (as for components)
ui.hidden
You can hide component properties by setting the ui.hidden
attribute to true.
type
You can use a JSDoc tag to tell the CLI parser which type to assign for a prop. This can be useful where multiple types are available for a prop or the parser does not automatically map to one of Interplay’s supported types.
/**
* @interplay {string} type - number
*/
variant: PropTypes.string
fnNode - Render Props
A special case where you must tell the parser the prop’s type is with renderProps. To the parser, a render prop will look like any other function property. We can tell the parser this is a render prop by assigning a tag with the special type of fnNode
(function node)
/** Description of the render prop
* @interplay {string} type - fnNode
*/
myRenderProp: PropTypes.func.isRequired,<br>
3. Programmatically modifying component config
If you are using the CLI, you can intercept the parsing at different points to programmatically modify the generated configuration. This is done by overriding modifier events in your interplay.config.js
file.
More details: Programmatically modifying config
Filtering inherited properties
Typescript components often define component properties via Props that inherit common properties. This inheritance can lead to many hundreds of properties being valid on each component.
It is useful to filter out common inherited props to leave only the component-specific properties configured. When parsing react code repos, by default the CLI filters out properties inherited from the react types path **/node_modules/@types/react/index.d.ts
You can provide your own list of inherited types to be filtered by providing an array of paths in the filteredTypePaths
setting in the CLI's interplay.config.js
settings file.
Any component properties inherited from types in these files will be removed from your component configuration, unless the prop is used in one of your examples parsed by the CLI. (Any properties used in your examples are automatically preserved in the component configuration.)
Parsing custom component types (typescript)
The React plugin for the CLI uses the excellent react-docgen-typescript
library to parse typescript component metadata (augmenting the results with other parsing).
By default this library recognises common react component types, but sometimes does not recognise the component if it is exported as another type. For example:
//DropdownButton.tsx custom type example
import React, { forwardRef } from 'react';
type DropdownButtonProps = {
//DropdownButtonProps implemented here
};
const DropdownButton = forwardRef( //DropdownButton implemented here );
type CompoundedType = typeof DropdownButton & { Item: typeof Dropdown.Item; };
const Compounded = DropdownButton as CompoundedType;
Compounded.Item = Dropdown.Item;
export default Compounded; //parser does not recognise this as component
In this case we can tell the parser to recognise this custom type as a component in the CLI settings:
//CLI settings in interplay.config.js
customComponentTypes: ['CompoundedType'],