This page will give you an overview of the library codebase organization, conventions, and implementation. Components will always be moving toward this specification, but may not comply currently.
If you want to contribute, we hope that this overview will help you feel more comfortable.
- Top-Level folders
- Introduction to presentational components
- External architecture
- No prop breaking changes without backwards compatibility
- Review similar components before proposing a feature
- Rendered text needs a prop. Group assistive text and labels
- Use
isRequired
PropType when possible - Prefix
onRequest[ACTION]
to pre-state-change callbacks functions - Prefix
on[EVENT]
to post-event callback functions - No return values in event callback functions
- Allow
id
to be set - Callback props should be tested to see if they exist
- Prefix render props with
onRender
- Reuse existing component props by using component. No
<Button iconClassName />
. - Put private components in
private
folder - No global DOM or
window
access - Limit global event listeners usage
- Limit use of DOM
ref
- Use
refs
object for external DOM callbacks className
class is rendered on.slds-[COMPONENT]
- Use
className[NODE]
prefix for other nodes - Boolean props: Use
is
,has
, andcan
prefixes or-able
suffix - No truthy defaults for boolean type props
- Use
event, { key: value }
in callback parameters - Transpile this library before using
- Only propose SLDS components
- Internal Architecture
- Example Class
- Limit component state
- Use controlled components
- React component can differ from DOM hierarchy
- Use loose coupling and weak connascence
- Use a single return
- Define defaults in one location
- Use functions instead of loops
- No mixins
- Use one stateful component and many stateless sub-components
- No DOM node queries
- Limit external production dependencies.
- Avoid inline styles and non-SLDS classes.
- Only extend from
React.Component
- Use
classNames
for conditional CSS classes - Use design tokens for inline styles
- 500+ line files should be avoided
- Render style preference: 1)
?:
, 2)&&
, 3) Enum, 4) Sub-component - Use
handle
prefix on internal callbacks - Use entire class name string when rendering conditional class names
- No variable mutation
- No spread operator on DOM nodes
- No props in initial state
- Write tests
- Components should be accessible
- Writing documentation site examples
- Converting SLDS to Design System React
- Babel Preset folder
- Benefits of open source software
components
- React components[COMPONENT]
- components that are part of the public API__tests__
- Mocha and Jest tests__examples__
Examples used in storybook and documentation website__docs__
- storybook and documentation website imports of examplesprivate
- components that are not a part of the public API
utilities
- components that are shared between other components (not public API)
icons
- Inline icons [legacy]preset
- Babel preset published to@salesforce/babel-preset-design-system-react
scripts
- Build and release tasksstyles
- Temporary location for styles (use sparingly)utilities
- Scripts that are not React components includingcheckProp
warnings, DOM, and event helpers. (not public API)
If you are new to React, you may be trained to design components in a more complicated way than they need to be. The goal is for engineers to not have to think about markup and stylesheets. Please prioritize the simple and the flexible.
The gist of presentational components is to be a template that takes in data and passes out user events and related data to callback functions. One over-simplified way to approach it is to consider these components as Handlebars templates with event listeners.
- Take data and UI data, such as disabled buttons, from parent via props to display data and UI state correctly. Don't manipulate props with string concatenations, array pushes, and sorting within components.
- Pass mouse and keyboard events and related event data, such as the item data for the item that was clicked, up to parent state machine, so it can decide how to manipulate it's child components' props.
- Parent components should be the only components that changes data. Components should be data stateless and only reflect the data they have been given. Only UI state, such as "is this dialog open?" or "is this option active/focused" should be within components. Focus and active state should be maintained internally in order to not introduce these into your state engine store (e.g.- Redux).
This project is not Bootstrap, and we've built frameworks on top of Bootstrap. The primary audience for this project is software engineers wanting to easily implement the design artifact handed to them. Yes, contributors should over-document and explain as much as you need to, but you do not need to have components just work when you drop them on the page. In short, think functionally and limiting internal component state.
"I just updated. What just broke and why?" Why does the React child component become the the DOM parent node? Write as long of a prop description comment that is needed to understand the concept. These comments are used for the prop tables on the library documentation website.
Need to sunset a prop or change the variable type accepted? Write backwards compatible code and add console warnings that will only run in development. Use a checkProp
function to communicate to the developer that they are not using the library correctly. If the warning can become an independent module and work in multiple components, add it to the design-system-react/utilities
folder. Some examples include:
- A component has children without a specified
displayName
- Determine if trigger can be tabbed to
- Require one of multiple prop, but not both or only one of specified properties
- Warnings of property deprecation, sunsetting, and future changes
Except in rare occasions with considerable thought breaking changes will be denied. Non-backward compatible changes to component props or a new design system version that has breaking changes within it is a breaking change and this library will have to release a major version.
SLDS markup alignment and class changes within the current design system release cycle are not considered breaking changes in this library although they may break markup queries. When upgrading the design system CSS, please create a archive/stale branch labelled similar to spring-17-2.2.x
, except use the correct Salesforce release date and SLDS version that the code was intended to support.
If you need an existing prop changes, please consider some alternatives such as deprecated the old prop and proposing a new prop name (onChange
to onRowChange
for instance).
Familiarize yourself with concepts used in the rest of the library.
Be inclusive of non-english users. Any text the user can read (including hidden assistive text for screenreaders) should be able to be set via a prop for internationalization purposes. Within the component, do not concatenate strings. This assumes that you know the word order of all languages. Strings should be passed into props in their entirety. Non-visible programatic keys can be concatenated.
All assistive text for accessibility and visible text should be grouped in an object and passed in with a prop, assistiveText
and labels
respectively. This will allow consuming developers to easily find and map text to localize it.
Similar to limiting internal state, isRequired
is explicit and determines the minimal API of each component. It simplifies a component's internal code and removes conditionals.
Pre-state-change events are events that request a state change from the parent component. Pre-state-change events callbacks should check for an invalid state and prevent the invalid state. For example
- Pill's
onRequestRemove
would be called before the Pill is removed. A pill is requesting that itself be removed, but it hasn't been removed yet. *onRemove
would be called after the Pill is removed. - "Native" events, like
onClick
,onKeyDown
,onFocus
do not have the prefixonRequest
, since the callback occurs after the specified event. onRequestRemove
occurs before the event of removal, whileonKeyDown
(delete or backspace) on a Pill occurs after a key is pressed down.
This is fairly standard React convention. Post-state-change or post-user-action events are called after a state change or a user event and should have the on
prefix.
Event callback props should not communicate with the parent component through return values. To increase clarity, do use use event.preventDefault()
or return false
within a callback prop to communicate information back to the component. Trapping event bubbling is good, but components should only be communicated with by props cycling back through the state engine. All data needed to change the state or communicate an invalid state should be explicitly provided by a key in the data object of the fucntion parameter. The data object is always the second parameter of the callback.
All id
attributes in the component HTML should be unique to the page, especially if the same component is used. They should be shortid
generated by default and be able to be controlled by the consuming developer. shortid
generated id
attributes are needed to enable accessbility and sometimes used for a React key
. Letting the developer set component id
allows library and consuming application DOM snapshots tests to be consistent.
Public callback/handler function props should be tested to see if they exist before execution. Within private child components use .isRequired
PropType if the callback is needed internally for the component to function.
Render props are essentially a callback function that occurs at render and should be given all data that the default render function has access to. Use an onRender
prefix to signal that it is a standard render prop function (e.g.- onRender[nodeOrComponentName]
). In a menu item render, this would would be the options
object. This functional is always swapped out with a DOM node.
Another kind of render prop is when a prop accepts an existing Design System React component class with a prop API such as the dropdown
prop of DataTableRowActions
. Component composition with prop spread is a similar pattern to render props, but differs in that it does an element clone with a shallow prop/object merge in which it is assumed that the prop component passed in overrides any props from its parent.
In a way, this is "grandparent control" in that it surfaces the internal API of sub-components to the consuming developer in a way that the parent of the parent can control it. The parent component (such as DataTableRowActions
) shallow merges the props from itself with the component props provided from the developer. The developer's passed in component controlled by the "grandparent" takes precedence and merges in last.
This pattern creates a separation of concern and a more declarative approach that relies on child components with their own documented props instead of additional props on the parent component such as <Button iconClassName />
. Passing in <Dropdown options={} />
to a dropdown
prop limits the aliasing of props for child components that already exist (dropdownOptions
is discouraged) and reduces duplication of PropType
documentation and increases library maintainability.
React components not in a private
folder are considered public and are considered within the scope of semantic versioning for breaking changes.
Encapsulate your components. No DOM queries. If window
, document
and event listeners are needed for events, you should test for their existence. Their existence is not guaranteed.
The component should not be listening to window events directly. If a menu needs to be smaller to be responsive, consuming applications should listen for the resize event and change the correct props to make the component responsive--or a CSS solution should be found.
DOM references should only be used for tasks such as measurement.
If you need to provide a DOM node reference, create an object called refs
with keys that are semantic names of DOM nodes: refs: { triggerButton: ()=>{}, triggerInput: ()=>{} }
. ref
is a reserved prop name. This will return the component React object, not the DOM node. If you use a refs
object, you may need shallow merge the object with default props. For more information, please review Exposing DOM Refs to Parent Components.
const CustomTextInput (props) => (
<div><input ref={props.refs.input} /></div>
);
const Parent () => (
<CustomTextInput
refs={{
input: (el) => {
this.inputElement = el;
},
}}
/>
);
The className
prop should be on a consistent node. The classes passed into className
should be present on the .slds-[COMPONENT]
node and not on a container node--nor on a child of .slds-[COMPONENT]
. All other className
props should be suffixed--such as classNameMenu
or classNameContainer
.
Use classNameInput
for the classname on an input
within a component.
If a prop is a boolean, please prefix with is
or can
, has
, or suffix it with -able
. Never default a prop to true
.
This will prevent consumers from having to write propName={false}
. HTML defaults many attributes to true if no value is provided, such as checked
instead of checked="true"
. To maintain JSX's HTML-like syntax, please avoid asking a developer to use propName={false}
. This may require using the opposite word, such as isInline
instead of isModal
.
Use consistent callback parameters and names. All render callbacks, that is callbacks that determine what to render, should pass a data object with named key/values as the second parameter. Event callbacks should pass in the synthetic event, then a data object with named key/values that relate to the event. If an event callback doesn't have a user event that triggered it, pass undefined
as the event. This will look something like this.props.onCallback(event, { extraInfo: true })
.
This library will not, and is not, intended to be run in a browser as-is. This library is targeted at engineers that can optimize their builds for performance and target the browsers and environments they need to support with appropriate polyfills. Polyfills should be added at application build time.
This library should include only components which have approved patterns in Salesforce's design system. If there is a use case from a designer that conforms to a design pattern, that component should be able to be implemented with this library. This library does NOT conform to Salesforce production per se, but is open to being customized to support patterns in production if they remain generic and flexible. If you are a Salesforce employee and need a component not in SLDS, please email Stephen James.
Internal architecture should promote readability and easy maintaince.
import React from 'react';
import PropTypes from 'prop-types';
import shortid from 'shortid';
import checkProps from './check-props';
import { EXTERNAL_CONSTANT } from '../../utilities/constants';
const propTypes = {
/**
* The description of this prop (will appear in the documentation site).
*/
title: PropTypes.string.isRequired,
};
// These values will also be visible in the documentation site.
const defaultProps = {};
/**
* The description of this component (will appear in the documentation site).
*/
class DemoComponent extends React.Component {
static displayName = EXTERNAL_CONSTANT_NAME;
static propTypes = propTypes;
static defaultProps = defaultProps;
constructor(props) {
super(props);
// useful for unique DOM IDs
this.generatedId = this.props.id || shortid.generate();
// initial state
this.state = {};
}
componentWillMount() {
// Not required. This function issues console warnings to developers about props and is helpful in upgrading. All breaking changes to props must have a warning for developers when they upgrade.
checkProps(EXTERNAL_CONSTANT, this.props);
}
// Class property bound to instance. Class methods that are not React lifecycle methods should use "fat-arrow" syntax if `this` binding is needed.
toggleOpen = (event, { eventDataKey }) => {
// you can use `this` here
};
// Minimize use of multiple renders. More HTML-like JSX is preferred with ternary statements
renderSubComponent = () => null;
// Render should be last
render() {
return null;
}
}
export default DemoComponent;
If the parent application's state engine can handle it with a prop
, then don't use state. New components should always start out as controlled by their parent and only be uncontrolled (that is have state) if a use case presents itself. It's better to have a component that needs 20 props set and outputs the correct markup, than to have a component that works with no props set, yet maintains multiple internal states. We like to think of this project as design system templates with minimal logic that happen to work with the React framework. Let the library consumer create a simple container component with state. Read more about controlled components.
- Components should be able to be "controlled"--that is expose a callback and expect their parent to control them with props. Components should be controlled at first and then uncontrolled support added later if needed.
- Prefix callbacks that occur before an event with
onRequest
. Prefix callbacks that occur as a result of an event withon
. The close button in a Popover will callonRequestClose
while the Popover will callonClose
after the Popover has been closed. This is because closing isn't guarenteed withonRequestClose
, since the parent component will decide. - Please note that if controlled by its parent, a component will appear broken if just copied and pasted into an application without a parent to control its props.
- Controlled components can be stateless components, but entirely stateless components do complicate DOM selectors for the consuming applications.
A controlled <input>
has a value
prop. Rendering a controlled <input>
will reflect the value of the value
prop.
render() {
return <input type="text" value="Hello!" />;
}
User input will have no effect on the rendered element because React has declared the value to be Hello!
. To update the value in response to user input, you could use the onChange
event:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = { value: 'Hello!' };
}
handleChange = (event) => {
this.setState({ value: event.target.value });
};
render() {
return (
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
);
}
}
In this example, we are accepting the value provided by the user and updating the value
prop of the <input>
component. This pattern makes it easy to implement interfaces that respond to or validate user interactions. For example:
handleChange = (event) => {
this.setState({ value: event.target.value.substr(0, 140) });
};
This would accept user input and truncate the value to the first 140 characters.
A Controlled component does not maintain its own internal state; the component renders purely based on props.
from Controlled Components in the React documentation.
- If a component needs the ability to also manage its own state (that is to be an "uncontrolled" component) in particular situations the parent should still be able to take over and make it controlled simply by passing in a value for the prop. For instance, an
onModalClose
callback could changeisModalOpen
tofalse
when it is ready to close the modal. - For more detail and examples of this pattern, visit DIMOC: Do It Myself or Callback.
React component hierarchy doesn't always mean HTML tag hierarchy. Sometimes children become the wrapping component.
The goal should be that a contributor can understand one piece of code without understanding another and be able to easily make updates in the future. You want weak connascence between components or components and the application (such as events) and not strong connascence. This makes it easier to update one component when modifying another in the future. How easy it will be to change in the future depends on which of the nine types of connascence is being used. For instance, Connascence of Name can be simply updated with Find/Replace. PropTypes and type systems help with Connascence of Type. Connascence of Position with parameters is bad because it relies on the correct order of parameters. Objects with named keys should be used to avoid Connascence of Position.
Please do not short-circuit functions with multiple returns.
Default props or any default variable value should be defined in one location. Many objects are merged in this library and this simplifies the logic and ensures defaults are not overriding non-defaults.
const getKittenNames = (cats) => cats.filter(isKitten).map(getName)
is a great example of how to get a list of kitten names from a cats
collection without a for
, while
, or until
loop while only modifying variables within the functional scope.
Avoid implied mixins. Instead, import and use shared code and external libraries as libraries, or use higher-order components in order to more easily trace the code execution.
It is preferable to only have one stateful top-level class per component in this library. For these top-level components, it’s preferable to use class
. All sub-components should be stateless and manipulated with props if possible.
-
A
Tree
should have state. ATreeNode
should not. -
A
DataTable
should have state, aTableColumn
should not. -
Frequently used items such as badges, pills, buttons or icons should probably not have state.
-
# Know how smart/stateful React components work together with pure/dumb stateless function components.
A ref
callback is React's link to a DOM node. It is triggered on render and allows access to the DOM node asynchronously. In most cases within a component, you only need a ref
for setting focus, but refs
make testing easier. If you find yourself using querySelectorAll()
to query parts of this library within your application tests, please stop and submit a contribution that surfaces the DOM node you are needing to test. If you control the contents or children yourself, please use a ref
bound to your own JSX DOM node to test. For an example, review the renderDialog
method of Popover
and its body
ref. Once surfaced, a DOM ref
becomes part of the public API and will be treated as such.
Do not add external dependencies to production dependencies list unless absolutely necessary. Always consider the "total cost of ownership" for all dependencies.
We are blessed to have a team of great CSS developers working on our design system. Use their CSS or contribute code back to them. Some rare or temporary implementations will be approved.
Use class/extend
, but only extend from React.Component
and never another class
. This prevents class hierarchies and tight coupling being created beyond the basic React.Component
. This completely avoids the gorilla-banana problem (“what you wanted was a banana, what you got was a gorilla holding the banana, and the entire jungle” - Joe Armstrong).
This library makes extensive use of the classnames library for feeding conditional CSS classes into className
attributes and allows a variety of types such as string
, object
, and arrays
. Although longer, static classname strings are preferred more than dynamic classnames (dynamic object keys) due to searchability when updating markup. See Classnames section for more details.
Inline styles should be kept to a minimum. The best option is file a bug either in the internal bug system or at the SLDS repository. This library contains a copy of design tokens available on the SLDS site. See utilities/design-tokens/README.md
for more details.
These files should be broken into sub-components or utility libraries.
Once your data is in a correct structure, your rendering should just respond to changes in your data. Here is list of ways to render:
- Inline ternary operator
- Preferred more than a simple if-else statement
- It is more concise than if-else and can be used within JSX since it’s an expression
- Logical
&&
operator- Alternative to ternary. Use when one side of the ternary operation would return null
- Be careful that you don’t run into bugs when using multiple conditions (truthy/falsey values, especially array length of zero)
- Inline Enum objects
- Great to map different states
- Great to map nested conditions ({prop1: { }}[prop1][prop2])
- Higher Order Components or Sub-components
- Create another stateless component and use it to shield away complex conditional rendering
- Components can focus on their main purpose
- This is an abstraction and can only return one node (in React 15)
- Switch case
- Verbose (break!)
- Can only be JSX-inlined with self invoking function
- Avoid it, enums are preferred
- If-else
- Is the most basic conditional rendering
- Beginner friendly
- Cannot be inlined in JSX (needs variables)
- Multi-level/nested conditional renderings
- Avoid them for the sake of readability
- Split up components into stateless components with their own simple conditional rendering
- Use HOCs instead
- External templating components
- Avoid them and be comfortable with JSX and JavaScript
Sub-render versus ternary example
Keep variables inside the render
function.
// bad
renderSmilingStatement () {
return <div>{this.props.name}{(this.state.isSmiling) ? <span> is smiling</span> : ""}</div>;
},
render () {
return <div>{this.props.name}{this.renderSmilingStatement()}</div>;
}
// good
render () {
return (
<div>
{this.props.name}
{this.state.isSmiling
? <span> is smiling</span>
: null
}
</div>
);
}
Name the handler methods after their triggering event. Handler names should:
- begin with
handle
- end with the name of the event they handle (eg,
Click
,Change
) - be present-tense
// bad
punchABadger () { /*...*/ },
render () {
return <div onClick={this.punchABadger} />;
}
// good
handleClick () { /*...*/ },
render () {
return <div onClick={this.handleClick} />;
}
If you need to disambiguate handlers, add additional information between
handle
and the event name. For example, you can distinguish between onChange
handlers: handleNameChange
and handleAgeChange
. When you do this, ask
yourself if you should be creating a new component.
Use classNames to manage conditional classes. This allows you to search the source code for the entire class name in order to update it. Dynamic classnames are difficult to locate.
// best
render () {
return (
<div className={classnames('MyComponent', {
'MyComponent--active': this.props.active,
'MyComponent--link': this.props.variant === 'link',
})} />
}
React tries to optimize and prevent re-rendering the DOM when possible. Many times this is not what you want. Avoid solitary use of push
, pop
, shift
, unshift
, sort
, reverse
, splice
and delete
when mutating arrays. If you ever have to ask yourself, why isn't my component rendering with new props, this is likely the reason. Use the spread operator on objects and arrays--or Array.concat()
on arrays instead of directly modifying these variables that are accessed by reference. You may consider exploring some new ES6 types such as Set which are collections that help store unique values of any type.
Be careful with rest operators when passively applying unnamed and unknown props to JSX nodes. This concept allows flexibility to the consuming developer, but is difficult to track for maintainers. If rest operators should be used, be sure to deconstruct each one that is actually needed by the JSX nodes, so that the rest operator only handles "unknown props" passed in from the outside developer. In short, don't utilize any properties in the ...props
object within the component. After using const { active, className, ...rest } = props;
do not go back to using this.prop.*
anywhere in the render function.
Please review props in getInitialState is an anti-pattern.
This allows breaking changes can be detected. If a breaking change doesn't cause at least one test to fail, then add a test.
- All
props
should be tested. It is OK to test multiple props in the same test for optmization as long as they are isolated and do not affect each other (for instanceid
,classname
, andstyle
). - All event callbacks should be tested along with any data object keys outside of the synthetic event to confirm the data. The data object, if present, is typically the second parameter of an event callback.
- All mouse and keyboard interactions should be tested.
Coverage can be determined by reviewing the coverage summary at the end of npm test
. High test coverage does not imply correct logic, but low coverage implies low test quality/quantity.
- Test should run in headless browsers (
npm test
) and within a "real" browser (npm start
->http://localhost:8001/
) - Components should be capable to be rendered without a
DOM
. Test for the existence ofdocument
andwindow
before using them. - For more specifics about testing please review the testing walkthough.
-
Non-accessible component contributions are permitted but discouraged. These are labelled "prototypes" and do not follow an approved accessible user-experience pattern. Please create an additional issue to follow up with the contribution.
-
ARIA 1.1 - Recommendation Candidate for the new ARIA Spec.
-
ARIA in HTML - Reference to answer the question "Should I put ARIA on this?".
-
HTML 5.1 - Please notice the places where it informs of ARIA role for each element.
-
WCAG - SLDS and this library should be AA compliant.
- Follow the accessiblity guidelines for keyboard events on the SLDS website.
-
One of the key aspects of accessibility with React components is managing a DOM node's
focus
andblur
. This should be implemented with callback references to DOM nodes and should not useReactDOM.findDOMNode()
. Use the the current DOM noderef
prop to create a function that passes the DOM node to a callback that is provided by the parent which will control the focus once the DOM node has been rendered. -
If a component has a focusable element, such as a button or an input, write a callback function that will pass the
ref
back to it's parent.buttonRef
orinputRef
are possible prop names.
- Documentation site code is located in a private repository.
- The NPM module for this library is used for component documentation. Therefore, changes to documentation require a new version to be published.
- Documentation site examples use CodeMirror to
eval()
site examples from the NPM module.import
andexport
statements are ignored by CodeMirror. Exports fromcomponents/index.js
are the only variables available to code examples. Do notimport
any other variables or the site examples will not work.
variant
should be used for significant structure and markup or UX pattern changes that cannot exist at the same time. This may include examples, modifiers, but are usually labelled variants in SLDS. In order to clear, never make the presense of an event callback imply a markup change, other than the event attribute specified. Example: Do not make the addition ofonClick
turn aspan
into ana
tag.theme
should be used for a singleclassName
change that cannot exist at the same time as anotherclassName
. These are typically SLDS states or themes, but could be modifiers. Examples:warning
,error
,offline
,success
.- Modifiers and states that can exist at the same time and should be props by themselves, so that any combination of them are possible.
isOpen
on dialogs and menus should be able to be controlled by their parent component, but also work with internal state if it is value isundefined
- SLDS uses styling to hide hidden elements. Please do not render these elements. Exampes: menus, dialogs, tab and accordion content panels.
- In order to promote best practices, if components are used in a wrong or suboptimal way, the component should error. For instance, if
id
is a required key in option items, then the component should error out and not fallback to an array index. CustomcheckProps
warnings are the best way to provide a clear error to consuming developers. propType
comments are used in the property tables on the documentation site. Please write in markdown paragraphs.- ESlint may find errors in SLDS markup. Feel free to ask questions to the SLDS team or core maintainers of this library, but most likely the markup is intentional and well-tested. You may need to disable the error with
eslint-disable-line
oreslint-disable-next-line
. Consider ESlint lint there to catch the rule, but not the well thought-out exception. - All filenames should be "kabob case,"
this-is-the-file
. Spaces and camel-case should be converted to hyphens.
/preset
folder contains a Babel 6 preset that makes Design System React compatible with Salesforce’s supported browsers. This is a temporary location until a repository is created.
This preset enables a module bundler, such as Webpack, to transpile Design System React. Using this will make it easier to upgrade in the future without having to manually reconfigure your Babel settings to be compatible with new language features Design System React may use.
- More efficient and effective development
- Faster Time-to-Market
- Reduced development costs
- Overcoming organizational unit boundaries
- Cost and risk sharing among organizational units
- Collaboration across organizational unit boundaries
- Program-wide information exchange
- More successful reuse
- Use of competences missing at component providers
- Independence between re-users and providers
- Relief of component providers
- Better software product
- Increased code quality
- More innovative development
- More flexible utilization of developers
- Simplified developer deployment
- Collaboration of detached developers
- Enhanced knowledge management
- Community-based learning
- Openness and availability of knowledge
- Higher employee motivation
- Shareable work * Opportuntity to lead engineering community