UNPKG

@salesforce/design-system-react

Version:

Salesforce Lightning Design System for React

178 lines (158 loc) 4.39 kB
/* Copyright (c) 2015-present, salesforce.com, inc. All rights reserved */ /* Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license */ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import ToggleButton, { TOGGLE_BUTTON_WIDTH } from './private/toggle-button'; import { SPLIT_VIEW } from '../../utilities/constants'; import generateId from '../../utilities/generate-id'; const propTypes = { /** * **Assistive text for accessibility** * * `toggleButtonOpen`: The button used to open the split view. * * `toggleButtonClose`: The button used to close the split view. */ assistiveText: PropTypes.shape({ toggleButtonOpen: PropTypes.string, toggleButtonClose: PropTypes.string, }), /** * HTML Id for the component. */ id: PropTypes.string, /** * CSS classes to be added to the root `div` tag. Uses `classNames` [API](https://github.com/JedWatson/classnames). */ className: PropTypes.oneOfType([ PropTypes.array, PropTypes.object, PropTypes.string, ]), /** * Sets the split view to be open or closed. */ isOpen: PropTypes.bool, /** * Event Callbacks * * `onClose`: Triggered when the split view has closed. * * `onOpen`: Triggered when the split view has opened. */ events: PropTypes.shape({ onClose: PropTypes.func, onOpen: PropTypes.func, }), /** * The React component that is rendered in the master section. * You need to pass in an array of elements in order for the scrolling to in the SplitViewList to work correctly. * React requires that you also supply a unique `key` for each element [React Lists and Keys](https://reactjs.org/docs/lists-and-keys.html#keys). */ master: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.element), PropTypes.element, ]).isRequired, /** * The width of the master section. */ masterWidth: PropTypes.string, /** * The React component that is rendered in the detail section. */ detail: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.element), PropTypes.element, ]).isRequired, }; const defaultProps = { assistiveText: { toggleButtonOpen: 'Close split view', toggleButtonClose: 'Open split view', }, events: {}, masterWidth: '20rem', }; /** * Split view is used to navigate between records in a list while staying on the same screen. */ class SplitView extends React.Component { static displayName = SPLIT_VIEW; static propTypes = propTypes; static defaultProps = defaultProps; constructor(props) { super(props); this.state = { isOpen: typeof props.isOpen === 'boolean' ? props.isOpen : true, }; this.generatedId = generateId(); } getId() { return this.props.id || this.generatedId; } getIsOpen() { return typeof this.props.isOpen === 'boolean' ? this.props.isOpen : this.state.isOpen; } getMasterViewId() { return `master_view_${this.getId()}`; } toggle(event) { if (typeof this.props.isOpen !== 'boolean') { this.setState((prevState) => ({ isOpen: !prevState.isOpen, })); } const isOpen = this.getIsOpen(); if (isOpen && this.props.events.onClose) { this.props.events.onClose(event); } else if (!isOpen && this.props.events.onOpen) { this.props.events.onOpen(event); } } render() { return ( <div id={this.getId()} className={classNames('slds-grid', this.props.className)} style={{ height: '100%', }} > <div style={{ maxWidth: this.getIsOpen() ? this.props.masterWidth : '0', minWidth: this.getIsOpen() ? this.props.masterWidth : '0', }} className={classNames( 'slds-split-view_container', { 'slds-is-open': this.getIsOpen() }, { 'slds-is-closed': !this.getIsOpen() } )} > <ToggleButton assistiveText={this.props.assistiveText} ariaControls={this.getMasterViewId()} isOpen={this.getIsOpen()} events={{ onClick: (event) => this.toggle(event), }} /> <article id={this.getMasterViewId()} className="slds-split-view slds-grid slds-grid_vertical slds-grow slds-scrollable_none" > {this.getIsOpen() ? this.props.master : null} </article> </div> <div style={{ marginLeft: TOGGLE_BUTTON_WIDTH, }} className="slds-grow slds-scrollable_y" > {this.props.detail} </div> </div> ); } } export default SplitView;