From 6633a4715fb64a34184c64eba92fe119938737f6 Mon Sep 17 00:00:00 2001 From: Hans Oksendahl Date: Tue, 29 Mar 2016 13:51:07 -0700 Subject: [PATCH] Added the page header component and associated demo page Refactored PageHeader component --- components/SLDSPageHeader/Base/index.jsx | 53 +++ components/SLDSPageHeader/BreadCrumb/index.js | 60 ++++ components/SLDSPageHeader/DetailBlock.jsx | 129 +++++++ components/SLDSPageHeader/DetailRow.jsx | 79 +++++ components/SLDSPageHeader/Info.jsx | 49 +++ .../SLDSPageHeader/ObjectHome/index.jsx | 76 +++++ .../SLDSPageHeader/RecordHome/index.jsx | 76 +++++ .../SLDSPageHeader/RelatedList/index.js | 75 +++++ components/SLDSPageHeader/Title.jsx | 68 ++++ components/SLDSPageHeader/index.jsx | 314 ++++++++++++++++++ components/SLDSPageHeader/randomId.js | 6 + demo/CodeMirror.jsx | 2 +- demo/Samples.js | 4 + demo/code-snippets/PageHeaderExamples1.js | 16 + demo/code-snippets/PageHeaderExamples2.js | 49 +++ demo/code-snippets/PageHeaderExamples3.js | 67 ++++ demo/code-snippets/PageHeaderExamples4.js | 67 ++++ demo/docs/components.json | 251 ++++++++++++++ demo/index.js | 2 + demo/pages/PageHeaderSection.jsx | 68 ++++ demo/pages/index.jsx | 2 +- lib/SLDSPageHeader/DetailBlock.js | 84 +++++ lib/SLDSPageHeader/DetailRow.js | 84 +++++ lib/SLDSPageHeader/Info.js | 86 +++++ lib/SLDSPageHeader/Title.js | 109 ++++++ lib/SLDSPageHeader/index.js | 110 ++++++ scripts/component-docs.js | 1 + 27 files changed, 1985 insertions(+), 2 deletions(-) create mode 100644 components/SLDSPageHeader/Base/index.jsx create mode 100644 components/SLDSPageHeader/BreadCrumb/index.js create mode 100644 components/SLDSPageHeader/DetailBlock.jsx create mode 100644 components/SLDSPageHeader/DetailRow.jsx create mode 100644 components/SLDSPageHeader/Info.jsx create mode 100644 components/SLDSPageHeader/ObjectHome/index.jsx create mode 100644 components/SLDSPageHeader/RecordHome/index.jsx create mode 100644 components/SLDSPageHeader/RelatedList/index.js create mode 100644 components/SLDSPageHeader/Title.jsx create mode 100644 components/SLDSPageHeader/index.jsx create mode 100644 components/SLDSPageHeader/randomId.js create mode 100644 demo/code-snippets/PageHeaderExamples1.js create mode 100644 demo/code-snippets/PageHeaderExamples2.js create mode 100644 demo/code-snippets/PageHeaderExamples3.js create mode 100644 demo/code-snippets/PageHeaderExamples4.js create mode 100644 demo/pages/PageHeaderSection.jsx create mode 100644 lib/SLDSPageHeader/DetailBlock.js create mode 100644 lib/SLDSPageHeader/DetailRow.js create mode 100644 lib/SLDSPageHeader/Info.js create mode 100644 lib/SLDSPageHeader/Title.js create mode 100644 lib/SLDSPageHeader/index.js diff --git a/components/SLDSPageHeader/Base/index.jsx b/components/SLDSPageHeader/Base/index.jsx new file mode 100644 index 0000000000..cccb493e19 --- /dev/null +++ b/components/SLDSPageHeader/Base/index.jsx @@ -0,0 +1,53 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; + +const displayName = 'SLDSPageHeaderBase'; +const propTypes = { + /** + * Icon node passed by SLDSPageHeader + */ + icon: React.PropTypes.node, + /** + * Title node passed by SLDSPageHeader + */ + title: React.PropTypes.node, + /** + * Info node passed by SLDSPageHeader + */ + info: React.PropTypes.node, +}; +const defaultProps = {}; + +class Base extends Component { + render() { + return ( +
+
+ { this.props.icon } +
+
+ { this.props.title } + { this.props.info } +
+
+ ); + } +} + +Base.displayName = displayName; +Base.propTypes = propTypes; +Base.defaultProps = defaultProps; + +module.exports = Base; diff --git a/components/SLDSPageHeader/BreadCrumb/index.js b/components/SLDSPageHeader/BreadCrumb/index.js new file mode 100644 index 0000000000..7d9102b0e0 --- /dev/null +++ b/components/SLDSPageHeader/BreadCrumb/index.js @@ -0,0 +1,60 @@ +import React, { Component } from 'react'; +import randomId from '../randomId'; + +const displayName = 'SLDSBreadCrumb'; +const propTypes = { + /** + * The assistive text for the breadcrumb trail + */ + assistiveText: React.PropTypes.string, + /** + * An array of react elements presumably anchor elements. + */ + trail: React.PropTypes.array, +}; +const defaultProps = {}; + +class SLDSBreadCrumb extends Component { + render() { + const { + assistiveText, + trail, + } = this.props; + const id = `SLDSBreadCrumb.${randomId()}`; + let trailElement; + + const renderTrail = () => { + const breadCrumbTrail = trail.map((crumb, i) => { + const crumbId = `${id}.${i}`; + + return ( +
  • {crumb}
  • + ); + }); + + return ( +
      + {breadCrumbTrail} +
    + ); + }; + + trailElement = renderTrail(); + + return ( + + ); + } +} + +SLDSBreadCrumb.displayName = displayName; +SLDSBreadCrumb.propTypes = propTypes; +SLDSBreadCrumb.defaultProps = defaultProps; + +export default SLDSBreadCrumb; diff --git a/components/SLDSPageHeader/DetailBlock.jsx b/components/SLDSPageHeader/DetailBlock.jsx new file mode 100644 index 0000000000..74cdce1cf9 --- /dev/null +++ b/components/SLDSPageHeader/DetailBlock.jsx @@ -0,0 +1,129 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; + +const displayName = 'SLDSPageHeaderDetailRow'; +const propTypes = { + /** + * Optional class name + */ + className: React.PropTypes.string, + /** + * label + */ + label: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * The content property can be a string or a React element + */ + content: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * Sets whether the fields truncate + */ + truncate: React.PropTypes.bool.isRequired, + flavor: React.PropTypes.string, +}; +const defaultProps = { + label: '', + content: '', + truncate: true, + flavor: '1-of-4', +}; + +class DetailBlock extends Component { + render() { + const { + className, + label, + content, + truncate, + flavor, + } = this.props; + const attr = omit([ + 'className', + 'label', + 'content', + 'truncate', + 'flavor', + ], this.props); + const classes = this._getClassNames(className, flavor); + let labelElement; + let contentElement; + + /** + * Render the label + */ + const renderLabel = () => { + const type = typeof label; + + if (type === 'string') { + const labelClasses = classnames('slds-text-heading--label-normal', { + 'slds-truncate': truncate, + }); + + return ( +

    {label}

    + ); + } else { + return label; + } + }; + + /** + * Render the title + */ + const renderContent = () => { + const type = typeof content; + + if (type === 'string') { + const labelClasses = classnames('slds-text-body--regular', { + 'slds-truncate': truncate, + }); + + return ( +

    {content}

    + ); + } else { + return content; + } + }; + + labelElement = renderLabel(); + contentElement = renderContent(); + + return ( +
  • + {labelElement} + {contentElement} +
  • + ); + } + + _getClassNames(className, flavor) { + return classnames('slds-page-header__detail-block', className, { + [`slds-size--${flavor}`]: flavor, + }); + } +} + +DetailBlock.displayName = displayName; +DetailBlock.propTypes = propTypes; +DetailBlock.defaultProps = defaultProps; + +module.exports = DetailBlock; diff --git a/components/SLDSPageHeader/DetailRow.jsx b/components/SLDSPageHeader/DetailRow.jsx new file mode 100644 index 0000000000..8104573ce9 --- /dev/null +++ b/components/SLDSPageHeader/DetailRow.jsx @@ -0,0 +1,79 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; +import randomId from './randomId'; +import DetailBlock from './DetailBlock'; + +const displayName = 'SLDSPageHeaderDetailRow'; +const propTypes = { + /** + * Optional class name + */ + className: React.PropTypes.string, + /** + * An array of detail blocks + */ + details: React.PropTypes.array, +}; +const defaultProps = {}; + +class DetailRow extends Component { + render() { + const { children, className, details } = this.props; + const attr = omit(['children', 'className'], this.props); + const classes = this._getClassNames(className); + + let detailsElement; + + /** + * Render the deets + */ + const renderDetails = () => { + if (children !== void(0)) { + return children; + } else { + return details.map((detail, i) => { + const id = randomId(); + const key = `SLDSPageHeader.detailBlock.${i}.${id}`; + + return ( + + ); + }); + } + }; + + detailsElement = renderDetails(); + + return ( + + ); + } + + _getClassNames(className) { + return classnames('slds-grid slds-page-header__detail-row', className); + } +} + +DetailRow.displayName = displayName; +DetailRow.propTypes = propTypes; +DetailRow.defaultProps = defaultProps; + +module.exports = DetailRow; diff --git a/components/SLDSPageHeader/Info.jsx b/components/SLDSPageHeader/Info.jsx new file mode 100644 index 0000000000..783a9ac148 --- /dev/null +++ b/components/SLDSPageHeader/Info.jsx @@ -0,0 +1,49 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; + +const displayName = 'SLDSPageHeaderInfo'; +const propTypes = { + /** + * Optional class name + */ + className: React.PropTypes.string, +}; +const defaultProps = { + className: '', +}; + +class Info extends Component { + render() { + const { children, className } = this.props; + const attr = omit(['children', 'className'], this.props); + const classes = this._getClassNames(className); + + return ( +

    + {children} +

    + ); + } + + _getClassNames(className) { + return classnames('slds-page-header__info', className); + } +} + +Info.displayName = displayName; +Info.propTypes = propTypes; +Info.defaultProps = defaultProps; + +module.exports = Info; diff --git a/components/SLDSPageHeader/ObjectHome/index.jsx b/components/SLDSPageHeader/ObjectHome/index.jsx new file mode 100644 index 0000000000..e13c80d51b --- /dev/null +++ b/components/SLDSPageHeader/ObjectHome/index.jsx @@ -0,0 +1,76 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import DetailRow from '../DetailRow'; + +const displayName = 'SLDSPageHeaderObjectHome'; +const propTypes = { + /** + * Icon node passed by SLDSPageHeader + */ + icon: React.PropTypes.node, + /** + * Title node passed by SLDSPageHeader + */ + title: React.PropTypes.node, + /** + * Info node passed by SLDSPageHeader + */ + info: React.PropTypes.node, + /** + * Content to appear on the right hand side of the page header + */ + contentRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * Nav content which appears in the upper right hand corner. + */ + navRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), +}; +const defaultProps = {}; + +class ObjectHome extends Component { + render() { + return ( +
    +
    +
    + { this.props.label } + { this.props.title } +
    +
    + { this.props.navRight } +
    +
    +
    +
    + { this.props.info } +
    +
    + { this.props.contentRight } +
    +
    +
    + ); + } +} + +ObjectHome.displayName = displayName; +ObjectHome.propTypes = propTypes; +ObjectHome.defaultProps = defaultProps; + +module.exports = ObjectHome; diff --git a/components/SLDSPageHeader/RecordHome/index.jsx b/components/SLDSPageHeader/RecordHome/index.jsx new file mode 100644 index 0000000000..9cda00bd87 --- /dev/null +++ b/components/SLDSPageHeader/RecordHome/index.jsx @@ -0,0 +1,76 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import DetailRow from '../DetailRow'; + +const displayName = 'SLDSPageHeaderRecordHome'; +const propTypes = { + /** + * Icon node passed by SLDSPageHeader + */ + icon: React.PropTypes.node, + /** + * Title node passed by SLDSPageHeader + */ + title: React.PropTypes.node, + /** + * Info node passed by SLDSPageHeader + */ + info: React.PropTypes.node, + /** + * Content to appear on the right hand side of the page header + */ + contentRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * An array of detail blocks + */ + details: React.PropTypes.array, +}; +const defaultProps = {}; + +class RecordHome extends Component { + render() { + const { details } = this.props; + + return ( +
    +
    +
    +
    +
    + { this.props.icon } +
    +
    + { this.props.label } + { this.props.title } + { this.props.info } +
    +
    +
    +
    + { this.props.contentRight } +
    +
    + +
    + ); + } +} + +RecordHome.displayName = displayName; +RecordHome.propTypes = propTypes; +RecordHome.defaultProps = defaultProps; + +module.exports = RecordHome; diff --git a/components/SLDSPageHeader/RelatedList/index.js b/components/SLDSPageHeader/RelatedList/index.js new file mode 100644 index 0000000000..34e390ba7b --- /dev/null +++ b/components/SLDSPageHeader/RelatedList/index.js @@ -0,0 +1,75 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; + +const displayName = 'SLDSPageHeaderRelatedList'; +const propTypes = { + /** + * Icon node passed by SLDSPageHeader + */ + icon: React.PropTypes.node, + /** + * Title node passed by SLDSPageHeader + */ + title: React.PropTypes.node, + /** + * Info node passed by SLDSPageHeader + */ + info: React.PropTypes.node, + /** + * Content to appear on the right hand side of the page header + */ + contentRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * Nav content which appears in the upper right hand corner. + */ + navRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), +}; +const defaultProps = {}; + +class RelatedList extends Component { + render() { + return ( +
    +
    +
    + { this.props.label } + { this.props.title } +
    +
    + { this.props.navRight } +
    +
    +
    +
    + { this.props.info } +
    +
    + { this.props.contentRight } +
    +
    +
    + ); + } +} + +RelatedList.displayName = displayName; +RelatedList.propTypes = propTypes; +RelatedList.defaultProps = defaultProps; + +module.exports = RelatedList; diff --git a/components/SLDSPageHeader/Title.jsx b/components/SLDSPageHeader/Title.jsx new file mode 100644 index 0000000000..079cc926eb --- /dev/null +++ b/components/SLDSPageHeader/Title.jsx @@ -0,0 +1,68 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; + +const displayName = 'SLDSPageHeaderTitle'; +const propTypes = { + /** + * Sets whether the title will truncate its content responsively. + */ + truncate: React.PropTypes.bool, + /** + * Sets the vertical alignment on the title + */ + align: React.PropTypes.oneOf(['top', 'middle', 'bottom']), + /** + * The title string (required) + */ + title: React.PropTypes.string.isRequired, + /** + * Optional class name + */ + className: React.PropTypes.string, +}; +const defaultProps = { + truncate: true, + align: 'middle', + title: 'Page Header Title', + className: '', +}; + +class Title extends Component { + render() { + const { children, title, truncate, align, className } = this.props; + const attr = omit(['children', 'title', 'truncate', 'align', 'className'], this.props); + const classes = this._getClassNames(truncate, align, className); + + return ( +

    + {title} + {children} +

    + ); + } + + _getClassNames(truncate, align, className) { + return classnames('slds-page-header__title', className, { + 'slds-truncate': truncate, + [`slds-align-${align}`]: align, + }); + } +} + +Title.displayName = displayName; +Title.propTypes = propTypes; +Title.defaultProps = defaultProps; + +module.exports = Title; diff --git a/components/SLDSPageHeader/index.jsx b/components/SLDSPageHeader/index.jsx new file mode 100644 index 0000000000..0162136546 --- /dev/null +++ b/components/SLDSPageHeader/index.jsx @@ -0,0 +1,314 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React, { Component } from 'react'; +import classnames from 'classnames'; +import omit from 'lodash.omit'; +import Info from './Info'; +import Title from './Title'; +import DetailRow from './DetailRow'; +import DetailBlock from './DetailBlock'; +import Base from './Base'; +import RecordHome from './RecordHome'; +import ObjectHome from './ObjectHome'; +import SLDSIcon from '../SLDSIcon'; +import SLDSBreadCrumb from './BreadCrumb'; + +const displayName = 'SLDSPageHeader'; +const propTypes = { + /** + * Optional class name + */ + className: React.PropTypes.string, + /** + * The type of component + */ + variant: React.PropTypes.string, + /** + * The info property can be a string or a React element + */ + label: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * The title property can be a string or a React element + */ + title: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * The info property can be a string or a React element + */ + info: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * The page header icon + */ + icon: React.PropTypes.element, + /** + * Name of the icon. Visit Lightning Design System Icons to reference icon names. + */ + iconName: React.PropTypes.string, + /** + * The icons category + */ + iconCategory: React.PropTypes.oneOf(['action', 'custom', 'doctype', 'standard', 'utility']), + /** + * If omitted, icon position is centered. + */ + iconPosition: React.PropTypes.oneOf(['left', 'right']), + iconSize: React.PropTypes.oneOf(['x-small', 'small', 'medium', 'large']), + /** + * For icon variants, please reference Lightning Design System Icons. + */ + iconVariant: React.PropTypes.oneOf(['bare', 'container', 'border', 'border-filled', 'small', 'more']), + /** + * Content to appear on the right hand side of the page header + */ + contentRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * An array of buttons which appear on the component's right hand side. + */ + details: React.PropTypes.array, + /** + * Nav content which appears in the upper right hand corner. + */ + navRight: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element, + ]), + /** + * An array of react elements presumably anchor elements. + */ + trail: React.PropTypes.array, +}; + +const defaultProps = { + className: '', + variant: 'base', + navRight: '', + contentRight: '', + details: [], + trail: [], +}; + +/** + * The SLDSPageHeader component adds SLDSPageHeader, SLDSPageHeader.Info, SLDSPageHeader.Title, SLDSPageHeader.DetailRow, and SLDSPageHeader.DetailBlock. + */ +class PageHeader extends Component { + render() { + const { + className, + icon, + iconName, + iconCategory, + iconPosition, + iconSize, + iconVariant, + label, + title, + info, + variant, + contentRight, + navRight, + details, + trail, + } = this.props; + /** + * OPTIMIZE ES7 style object destructuring removes the need for _.omit. + * + * Example: + * + * const {foo, ...bar} = this.props; + */ + const attr = omit([ + 'className', + 'icon', + 'iconName', + 'iconCategory', + 'iconPosition', + 'iconSize', + 'iconVariant', + 'label', + 'title', + 'info', + 'variant', + 'contentRight', + 'navRight', + 'details', + 'trail', + ], this.props); + const classes = this._getClassNames(className); + + /** + * Initialize component variables + */ + let labelElement; + let iconElement; + let titleElement; + let infoElement; + let contentRightElement; + let navRightElement; + let Variant; + + /** + * Render the icon + */ + const renderIcon = () => { + if (icon) { + return icon; + } else if (iconName) { + return ( + + ); + } + }; + + /** + * Render the label + */ + const renderLabel = () => { + const type = typeof label; + + if (trail.length > 0) { + return ( + + ); + } else { + if (type === 'string') { + return

    {label}

    ; + } else { + return label; + } + } + }; + + /** + * Render the title + */ + const renderTitle = () => { + const type = typeof title; + + if (type === 'string') { + return ; + } else { + return title; + } + }; + + /** + * Render info + */ + const renderInfo = () => { + const type = typeof info; + + if (type === 'string') { + return <Info>{info}</Info>; + } else { + return info; + } + }; + + /** + * Steal contentRight's children + */ + const renderNavRight = () => { + const type = typeof navRight; + + if (type !== 'string') { + return ( + <div + className="slds-col slds-no-flex slds-grid slds-align-top" + {...navRight.props} /> + ); + } else { + return navRight; + } + }; + + /** + * Steal contentRight's children + */ + const renderContentRight = () => { + const type = typeof contentRight; + + if (type !== 'string') { + return ( + <div className="slds-grid" {...contentRight.props} /> + ); + } else { + return contentRight; + } + }; + + labelElement = renderLabel(); + iconElement = renderIcon(); + titleElement = renderTitle(); + infoElement = renderInfo(); + navRightElement = renderNavRight(); + contentRightElement = renderContentRight(); + + switch (variant) { + case 'objectHome': + Variant = ObjectHome; + break; + case 'recordHome': + Variant = RecordHome; + break; + case 'relatedList': + Variant = RelatedList; + break; + default: + Variant = Base; + } + + return ( + <div className={classes} role="banner" {...attr}> + <Variant + label={labelElement} + icon={iconElement} + title={titleElement} + info={infoElement} + contentRight={contentRightElement} + navRight={navRightElement} + details={details} /> + </div> + ); + } + + _getClassNames(className) { + return classnames('slds-page-header', className); + } +} + +PageHeader.displayName = displayName; +PageHeader.propTypes = propTypes; +PageHeader.defaultProps = defaultProps; + +module.exports = PageHeader; +module.exports.Info = Info; +module.exports.Title = Title; +module.exports.DetailRow = DetailRow; +module.exports.DetailBlock = DetailBlock; diff --git a/components/SLDSPageHeader/randomId.js b/components/SLDSPageHeader/randomId.js new file mode 100644 index 0000000000..27d58875b7 --- /dev/null +++ b/components/SLDSPageHeader/randomId.js @@ -0,0 +1,6 @@ +/** + * Create a pseudo-random id for creating keys + */ +export default function randomId() { + return Math.random().toString().substr(2); +} diff --git a/demo/CodeMirror.jsx b/demo/CodeMirror.jsx index 561f46a7fd..2586e4eb5f 100644 --- a/demo/CodeMirror.jsx +++ b/demo/CodeMirror.jsx @@ -19,6 +19,7 @@ const SLDSMenuDropdown = require('../components/SLDSMenuDropdown'); const SLDSMenuPicklist = require('../components/SLDSMenuPicklist'); const SLDSModal = require('../components/SLDSModal'); const SLDSNotification = require('../components/SLDSNotification'); +const SLDSPageHeader = require('../components/SLDSPageHeader'); const SLDSPopoverTooltip = require('../components/SLDSPopoverTooltip'); const SLDSDatepickerSingleSelect = require('../components/SLDSDatepickerSingleSelect'); const SLDSTimepicker = require('../components/SLDSTimepicker'); @@ -226,4 +227,3 @@ CodeMirror.propTypes = propTypes; CodeMirror.defaultProps = defaultProps; module.exports = CodeMirror; - diff --git a/demo/Samples.js b/demo/Samples.js index d5906659c2..40d4eca069 100644 --- a/demo/Samples.js +++ b/demo/Samples.js @@ -15,6 +15,10 @@ const Samples = { Notifications1: require('fs').readFileSync('demo/code-snippets/NotificationExamples1.js', 'utf8'), Notifications2: require('fs').readFileSync('demo/code-snippets/NotificationExamples2.js', 'utf8'), Notifications3: require('fs').readFileSync('demo/code-snippets/NotificationExamples3.js', 'utf8'), + PageHeaders1: require('fs').readFileSync('demo/code-snippets/PageHeaderExamples1.js', 'utf8'), + PageHeaders2: require('fs').readFileSync('demo/code-snippets/PageHeaderExamples2.js', 'utf8'), + PageHeaders3: require('fs').readFileSync('demo/code-snippets/PageHeaderExamples3.js', 'utf8'), + PageHeaders4: require('fs').readFileSync('demo/code-snippets/PageHeaderExamples4.js', 'utf8'), Picklists: require('fs').readFileSync('demo/code-snippets/PicklistExamples.js', 'utf8'), Picklists1: require('fs').readFileSync('demo/code-snippets/PicklistExamples-1.js', 'utf8'), CustomPicklists: require('fs').readFileSync('demo/code-snippets/PicklistCustomExamples.js', 'utf8'), diff --git a/demo/code-snippets/PageHeaderExamples1.js b/demo/code-snippets/PageHeaderExamples1.js new file mode 100644 index 0000000000..d8eb2448b9 --- /dev/null +++ b/demo/code-snippets/PageHeaderExamples1.js @@ -0,0 +1,16 @@ +class PageHeaderExample extends React.Component { + + render(){ + return ( + <SLDSPageHeader + iconAssistiveText="Opportunity" + iconCategory="standard" + iconName="opportunity" + title="Rohde Corp - 80,000 Widgets" + info="Mark Jaeckal • Unlimited Customer • 11/13/15" /> + ); + } + +} + +ReactDOM.render(<PageHeaderExample />, mountNode); diff --git a/demo/code-snippets/PageHeaderExamples2.js b/demo/code-snippets/PageHeaderExamples2.js new file mode 100644 index 0000000000..ec98b550f3 --- /dev/null +++ b/demo/code-snippets/PageHeaderExamples2.js @@ -0,0 +1,49 @@ +class PageHeaderExample extends React.Component { + + render() { + const contentRight = ( + <div> + <SLDSButtonStateful + key="PageHeaderFollowButton" + disabled={false} + iconSize="medium" + responsive={false} + stateOne={{ iconName: "add", label: "Follow" }} + stateTwo={{ iconName: "check", label: "Following" }} + stateThree={{ iconName: "close", label: "Unfollow" }} /> + <SLDSButtonGroup key=""> + <SLDSButton + label="Edit" /> + <SLDSButton + label="Delete" /> + <SLDSButton + label="Clone" /> + <SLDSButton + iconName="down" + assistiveText="More" /> + </SLDSButtonGroup> + </div> + ); + + const details = [ + { label: 'Field 1', content: 'Description that demonstrates truncation with content.' }, + { label: 'Field 2', content: 'Multiple Values' }, + { label: 'Field 3', content: (<a href="#">Hyperlink</a>) }, + { label: 'Field 4', content: 'Description (2-line truncation)' }, + ]; + + return ( + <SLDSPageHeader + iconAssistiveText="User" + iconCategory="standard" + iconName="user" + label="Record Type" + title="Record Title" + variant="recordHome" + contentRight={contentRight} + details={details} /> + ); + } +} + +ReactDOM.render(<PageHeaderExample />, mountNode); diff --git a/demo/code-snippets/PageHeaderExamples3.js b/demo/code-snippets/PageHeaderExamples3.js new file mode 100644 index 0000000000..25bdb28bd6 --- /dev/null +++ b/demo/code-snippets/PageHeaderExamples3.js @@ -0,0 +1,67 @@ +class PageHeaderExample extends React.Component { + + render() { + const navRight = ( + <div className="slds-button-group" role="group"> + <button className="slds-button slds-button--neutral">New Lead</button> + <div className="slds-button--last"> + <SLDSButton + iconName="down" + variant="icon" + iconVariant="border-filled" + assistiveText="More Actions" /> + </div> + </div> + ); + + const contentRight = ( + <div> + <SLDSButton + iconName="settings" + variant="icon" + iconVariant="more" + className="slds-m-left--xx-small" + assistiveText="Settings" /> + <SLDSButton + iconName="table" + variant="icon" + iconVariant="more" + className="slds-m-left--xx-small" + assistiveText="Table" /> + <SLDSButtonGroup> + <SLDSButton + iconName="chart" + variant="icon" + iconVariant="border" + assistiveText="Chart" /> + <SLDSButton + iconName="filterList" + variant="icon" + iconVariant="border" + className="slds-m-left--xx-small" + assistiveText="Filter List" /> + <SLDSButton + iconName="sort" + variant="icon" + iconVariant="more" + className="slds-m-left--xx-small" + assistiveText="Sort" /> + </SLDSButtonGroup> + </div> + ); + + return ( + <SLDSPageHeader + label="Leads" + title="My Leads (truncates)" + navRight={navRight} + contentRight={contentRight} + variant="objectHome" + truncate={true} + info="10 items • sorted by name" /> + ); + } + +} + +ReactDOM.render(<PageHeaderExample />, mountNode); diff --git a/demo/code-snippets/PageHeaderExamples4.js b/demo/code-snippets/PageHeaderExamples4.js new file mode 100644 index 0000000000..a1c293bfd7 --- /dev/null +++ b/demo/code-snippets/PageHeaderExamples4.js @@ -0,0 +1,67 @@ +class PageHeaderExample extends React.Component { + + render() { + const navRight = ( + <div className="slds-button-group" role="group"> + <button className="slds-button slds-button--neutral">Add Contact</button> + <div className="slds-button--last"> + <SLDSButton + iconName="down" + variant="icon" + iconVariant="border-filled" + assistiveText="More Actions" /> + </div> + </div> + ); + + const contentRight = ( + <div> + <SLDSButton + iconName="table" + variant="icon" + iconVariant="more" + className="slds-m-left--xx-small" + assistiveText="Table" /> + <SLDSButtonGroup> + <SLDSButton + iconName="chart" + variant="icon" + iconVariant="border" + className="slds-m-left--xx-small" + assistiveText="Chart" /> + <SLDSButton + iconName="filterList" + variant="icon" + iconVariant="border" + className="slds-m-left--xx-small" + assistiveText="Filter List" /> + <SLDSButton + iconName="sort" + variant="icon" + iconVariant="more" + className="slds-m-left--xx-small" + assistiveText="Sort" /> + </SLDSButtonGroup> + </div> + ); + + const trail = [ + (<a href="#">Accounts</a>), + (<a href="#">Company One</a>), + ]; + + return ( + <SLDSPageHeader + title="Contacts (will truncate)" + navRight={navRight} + contentRight={contentRight} + variant="objectHome" + truncate={true} + trail={trail} + info="10 items • sorted by name" /> + ); + } + +} + +ReactDOM.render(<PageHeaderExample />, mountNode); diff --git a/demo/docs/components.json b/demo/docs/components.json index 746de3ab7c..f75684d3e6 100644 --- a/demo/docs/components.json +++ b/demo/docs/components.json @@ -1245,6 +1245,257 @@ } } }, + "SLDSPageHeader": { + "description": "The SLDSPageHeader component adds SLDSPageHeader, SLDSPageHeader.Info, SLDSPageHeader.Title, SLDSPageHeader.DetailRow, and SLDSPageHeader.DetailBlock.", + "displayName": "SLDSPageHeader", + "props": { + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Optional class name", + "defaultValue": { + "value": "''", + "computed": false + } + }, + "variant": { + "type": { + "name": "string" + }, + "required": false, + "description": "The type of component", + "defaultValue": { + "value": "'base'", + "computed": false + } + }, + "label": { + "type": { + "name": "union", + "value": [ + { + "name": "string" + }, + { + "name": "element" + } + ] + }, + "required": false, + "description": "The info property can be a string or a React element" + }, + "title": { + "type": { + "name": "union", + "value": [ + { + "name": "string" + }, + { + "name": "element" + } + ] + }, + "required": false, + "description": "The title property can be a string or a React element" + }, + "info": { + "type": { + "name": "union", + "value": [ + { + "name": "string" + }, + { + "name": "element" + } + ] + }, + "required": false, + "description": "The info property can be a string or a React element" + }, + "icon": { + "type": { + "name": "element" + }, + "required": false, + "description": "The page header icon" + }, + "iconName": { + "type": { + "name": "string" + }, + "required": false, + "description": "Name of the icon. Visit <a href=\"http://www.lightningdesignsystem.com/resources/icons\">Lightning Design System Icons</a> to reference icon names." + }, + "iconCategory": { + "type": { + "name": "enum", + "value": [ + { + "value": "'action'", + "computed": false + }, + { + "value": "'custom'", + "computed": false + }, + { + "value": "'doctype'", + "computed": false + }, + { + "value": "'standard'", + "computed": false + }, + { + "value": "'utility'", + "computed": false + } + ] + }, + "required": false, + "description": "The icons category" + }, + "iconPosition": { + "type": { + "name": "enum", + "value": [ + { + "value": "'left'", + "computed": false + }, + { + "value": "'right'", + "computed": false + } + ] + }, + "required": false, + "description": "If omitted, icon position is centered." + }, + "iconSize": { + "type": { + "name": "enum", + "value": [ + { + "value": "'x-small'", + "computed": false + }, + { + "value": "'small'", + "computed": false + }, + { + "value": "'medium'", + "computed": false + }, + { + "value": "'large'", + "computed": false + } + ] + }, + "required": false, + "description": "" + }, + "iconVariant": { + "type": { + "name": "enum", + "value": [ + { + "value": "'bare'", + "computed": false + }, + { + "value": "'container'", + "computed": false + }, + { + "value": "'border'", + "computed": false + }, + { + "value": "'border-filled'", + "computed": false + }, + { + "value": "'small'", + "computed": false + }, + { + "value": "'more'", + "computed": false + } + ] + }, + "required": false, + "description": "For icon variants, please reference <a href='http://www.lightningdesignsystem.com/components/buttons/#icon'>Lightning Design System Icons</a>." + }, + "contentRight": { + "type": { + "name": "union", + "value": [ + { + "name": "string" + }, + { + "name": "element" + } + ] + }, + "required": false, + "description": "Content to appear on the right hand side of the page header", + "defaultValue": { + "value": "''", + "computed": false + } + }, + "details": { + "type": { + "name": "array" + }, + "required": false, + "description": "An array of buttons which appear on the component's right hand side.", + "defaultValue": { + "value": "[]", + "computed": false + } + }, + "navRight": { + "type": { + "name": "union", + "value": [ + { + "name": "string" + }, + { + "name": "element" + } + ] + }, + "required": false, + "description": "Nav content which appears in the upper right hand corner.", + "defaultValue": { + "value": "''", + "computed": false + } + }, + "trail": { + "type": { + "name": "array" + }, + "required": false, + "description": "An array of react elements presumably anchor <a> elements.", + "defaultValue": { + "value": "[]", + "computed": false + } + } + } + }, "SLDSPopoverTooltip": { "description": "The SLDSPopoverTooltip component is variant of the Lightning Design System Popover component. This component wraps an element that triggers it to open. It must be a focusable child element (either a button or anchor) so that keyboard users can navigate to it.", "displayName": "SLDSPopoverTooltip", diff --git a/demo/index.js b/demo/index.js index 0104f0c214..8b6c1ac5c1 100644 --- a/demo/index.js +++ b/demo/index.js @@ -24,6 +24,7 @@ import IconSection from './pages/IconSection'; import LookupSection from './pages/LookupSection'; import ModalSection from './pages/ModalSection'; import NotificationSection from './pages/NotificationSection'; +import PageHeaderSection from './pages/PageHeaderSection'; import PicklistSection from './pages/PicklistSection'; import TooltipSection from './pages/TooltipSection'; @@ -46,6 +47,7 @@ const routes = ( <Route name="lookup" path="lookup" handler={LookupSection}/> <Route name="modal" path="modal" handler={ModalSection}/> <Route name="notification" path="notification" handler={NotificationSection}/> + <Route name="page-header" path="page-header" handler={PageHeaderSection}/> <Route name="picklist" path="picklist" handler={PicklistSection}/> <Route name="tooltip" path="tooltip" handler={TooltipSection}/> <Route name="faq" path="faq" handler={FAQ} /> diff --git a/demo/pages/PageHeaderSection.jsx b/demo/pages/PageHeaderSection.jsx new file mode 100644 index 0000000000..fed58c5bc6 --- /dev/null +++ b/demo/pages/PageHeaderSection.jsx @@ -0,0 +1,68 @@ +/* +Copyright (c) 2015, salesforce.com, inc. All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import React from 'react'; +import CodeMirror from 'demo/CodeMirror'; +import Samples from 'demo/Samples'; +import PropTable from 'demo/PropTable'; +import DOCS from 'docs'; +import ComponentHeader from 'demo/pages/components/componentHeader'; + +const displayName = 'PageHeaderSection'; +const propTypes = {}; +const defaultProps = {}; + +class PageHeaderSection extends React.Component { + + constructor(props) { + super(props); + this.state = {}; + } + + getDescription() { + const desc = DOCS.SLDSPageHeader.description; + return { __html: desc }; + } + + render() { + const docs = DOCS.SLDSPageHeader ? true : false; + return ( + <div className="slds-p-around--medium"> + <ComponentHeader cmpName="SLDSPageHeader" cmpUrl="http://www.lightningdesignsystem.com/components/page-headers" /> + <div className="copy-text"> + {docs ? <p dangerouslySetInnerHTML={this.getDescription()} className="slds-p-vertical--small" style={{ maxWidth: '800px' }} /> : null} + </div> + <section className="slds-p-vertical--large"> + <h4 className="slds-text-heading--small">Base</h4> + <CodeMirror codeText={Samples.PageHeaders1} /> + </section> + <section className="slds-p-vertical--large"> + <h4 className="slds-text-heading--small">Record Home</h4> + <CodeMirror codeText={Samples.PageHeaders2} /> + </section> + <section className="slds-p-vertical--large"> + <h4 className="slds-text-heading--small">Object Home</h4> + <CodeMirror codeText={Samples.PageHeaders3} /> + </section> + <section className="slds-p-vertical--large"> + <h4 className="slds-text-heading--small">Related List</h4> + <CodeMirror codeText={Samples.PageHeaders4} /> + </section> + <PropTable component="SLDSPageHeader" /> + </div> + ); + } + +} + +PageHeaderSection.displayName = displayName; +PageHeaderSection.propTypes = propTypes; +PageHeaderSection.defaultProps = defaultProps; + +module.exports = PageHeaderSection; diff --git a/demo/pages/index.jsx b/demo/pages/index.jsx index d14a2d268b..8a16555e6d 100644 --- a/demo/pages/index.jsx +++ b/demo/pages/index.jsx @@ -14,7 +14,6 @@ import Router from 'react-router'; const { Route, DefaultRoute, RouteHandler, Link } = Router; import SLDSGrid from '../../components/SLDSGrid'; - module.exports = React.createClass( { getDefaultProps () { return {}; @@ -69,6 +68,7 @@ module.exports = React.createClass( { <li><Link to="picklist" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">MenuPicklist</Link></li> <li><Link to="modal" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">Modal</Link></li> <li><Link to="notification" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">Notification</Link></li> + <li><Link to="page-header" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">PageHeader</Link></li> <li><Link to="tooltip" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">PopoverTooltip</Link></li> <li><Link to="timepicker" className="a-plain slds-p-horizontal--x-large slds-p-vertical--x-small">TimePicker</Link></li> diff --git a/lib/SLDSPageHeader/DetailBlock.js b/lib/SLDSPageHeader/DetailBlock.js new file mode 100644 index 0000000000..e5d931386a --- /dev/null +++ b/lib/SLDSPageHeader/DetailBlock.js @@ -0,0 +1,84 @@ +'use strict'; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +var _lodash = require('lodash.omit'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (c) 2015, salesforce.com, inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var displayName = 'SLDSPageHeaderDetailRow'; +var propTypes = { + /** + * Optional class name + */ + className: _react2.default.PropTypes.string +}; +var defaultProps = {}; + +var DetailBlock = function (_Component) { + _inherits(DetailBlock, _Component); + + function DetailBlock() { + _classCallCheck(this, DetailBlock); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(DetailBlock).apply(this, arguments)); + } + + _createClass(DetailBlock, [{ + key: 'render', + value: function render() { + var _props = this.props; + var children = _props.children; + var className = _props.className; + + var attr = (0, _lodash2.default)(['children', 'className'], this.props); + var classes = this._getClassNames(className); + + return _react2.default.createElement( + 'li', + _extends({ className: classes }, attr), + children + ); + } + }, { + key: '_getClassNames', + value: function _getClassNames(className) { + return (0, _classnames2.default)('slds-page-header__detail-block', className); + } + }]); + + return DetailBlock; +}(_react.Component); + +DetailBlock.displayName = displayName; +DetailBlock.propTypes = propTypes; +DetailBlock.defaultProps = defaultProps; + +module.exports = DetailBlock; \ No newline at end of file diff --git a/lib/SLDSPageHeader/DetailRow.js b/lib/SLDSPageHeader/DetailRow.js new file mode 100644 index 0000000000..08c3c9d989 --- /dev/null +++ b/lib/SLDSPageHeader/DetailRow.js @@ -0,0 +1,84 @@ +'use strict'; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +var _lodash = require('lodash.omit'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (c) 2015, salesforce.com, inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var displayName = 'SLDSPageHeaderDetailRow'; +var propTypes = { + /** + * Optional class name + */ + className: _react2.default.PropTypes.string +}; +var defaultProps = {}; + +var DetailRow = function (_Component) { + _inherits(DetailRow, _Component); + + function DetailRow() { + _classCallCheck(this, DetailRow); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(DetailRow).apply(this, arguments)); + } + + _createClass(DetailRow, [{ + key: 'render', + value: function render() { + var _props = this.props; + var children = _props.children; + var className = _props.className; + + var attr = (0, _lodash2.default)(['children', 'className'], this.props); + var classes = this._getClassNames(className); + + return _react2.default.createElement( + 'ul', + _extends({ className: classes }, attr), + children + ); + } + }, { + key: '_getClassNames', + value: function _getClassNames(className) { + return (0, _classnames2.default)('slds-grid slds-page-header__detail-row', className); + } + }]); + + return DetailRow; +}(_react.Component); + +DetailRow.displayName = displayName; +DetailRow.propTypes = propTypes; +DetailRow.defaultProps = defaultProps; + +module.exports = DetailRow; \ No newline at end of file diff --git a/lib/SLDSPageHeader/Info.js b/lib/SLDSPageHeader/Info.js new file mode 100644 index 0000000000..8413c273ec --- /dev/null +++ b/lib/SLDSPageHeader/Info.js @@ -0,0 +1,86 @@ +'use strict'; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +var _lodash = require('lodash.omit'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (c) 2015, salesforce.com, inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var displayName = 'SLDSPageHeaderInfo'; +var propTypes = { + /** + * Optional class name + */ + className: _react2.default.PropTypes.string +}; +var defaultProps = { + className: '' +}; + +var Info = function (_Component) { + _inherits(Info, _Component); + + function Info() { + _classCallCheck(this, Info); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(Info).apply(this, arguments)); + } + + _createClass(Info, [{ + key: 'render', + value: function render() { + var _props = this.props; + var children = _props.children; + var className = _props.className; + + var attr = (0, _lodash2.default)(['children', 'className'], this.props); + var classes = this._getClassNames(className); + + return _react2.default.createElement( + 'p', + _extends({ className: classes }, attr), + children + ); + } + }, { + key: '_getClassNames', + value: function _getClassNames(className) { + return (0, _classnames2.default)('slds-page-header__info', className); + } + }]); + + return Info; +}(_react.Component); + +Info.displayName = displayName; +Info.propTypes = propTypes; +Info.defaultProps = defaultProps; + +module.exports = Info; \ No newline at end of file diff --git a/lib/SLDSPageHeader/Title.js b/lib/SLDSPageHeader/Title.js new file mode 100644 index 0000000000..06d8f9d557 --- /dev/null +++ b/lib/SLDSPageHeader/Title.js @@ -0,0 +1,109 @@ +'use strict'; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _classnames2 = require('classnames'); + +var _classnames3 = _interopRequireDefault(_classnames2); + +var _lodash = require('lodash.omit'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (c) 2015, salesforce.com, inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var displayName = 'SLDSPageHeaderTitle'; +var propTypes = { + /** + * Sets whether the title will truncate its content responsively. + */ + truncate: _react2.default.PropTypes.bool, + /** + * Sets the vertical alignment on the title + */ + align: _react2.default.PropTypes.oneOf(['top', 'middle', 'bottom']), + /** + * The title string (required) + */ + title: _react2.default.PropTypes.string.isRequired, + /** + * Optional class name + */ + className: _react2.default.PropTypes.string +}; +var defaultProps = { + truncate: true, + align: 'middle', + title: 'Page Header Title', + className: '' +}; + +var Title = function (_Component) { + _inherits(Title, _Component); + + function Title() { + _classCallCheck(this, Title); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(Title).apply(this, arguments)); + } + + _createClass(Title, [{ + key: 'render', + value: function render() { + var _props = this.props; + var children = _props.children; + var title = _props.title; + var truncate = _props.truncate; + var align = _props.align; + var className = _props.className; + + var attr = (0, _lodash2.default)(['children', 'title', 'truncate', 'align', 'className'], this.props); + var classes = this._getClassNames(truncate, align, className); + + return _react2.default.createElement( + 'p', + _extends({ className: classes, title: title }, attr), + title, + children + ); + } + }, { + key: '_getClassNames', + value: function _getClassNames(truncate, align, className) { + return (0, _classnames3.default)('slds-page-header__title', className, _defineProperty({ + 'slds-truncate': truncate + }, 'slds-align-' + align, align)); + } + }]); + + return Title; +}(_react.Component); + +Title.displayName = displayName; +Title.propTypes = propTypes; +Title.defaultProps = defaultProps; + +module.exports = Title; \ No newline at end of file diff --git a/lib/SLDSPageHeader/index.js b/lib/SLDSPageHeader/index.js new file mode 100644 index 0000000000..5aabd9a20d --- /dev/null +++ b/lib/SLDSPageHeader/index.js @@ -0,0 +1,110 @@ +'use strict'; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +var _Info = require('./Info'); + +var _Info2 = _interopRequireDefault(_Info); + +var _Title = require('./Title'); + +var _Title2 = _interopRequireDefault(_Title); + +var _DetailRow = require('./DetailRow'); + +var _DetailRow2 = _interopRequireDefault(_DetailRow); + +var _DetailBlock = require('./DetailBlock'); + +var _DetailBlock2 = _interopRequireDefault(_DetailBlock); + +var _lodash = require('lodash.omit'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (c) 2015, salesforce.com, inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var displayName = 'SLDSPageHeader'; +var propTypes = { + /** + * Optional class name + */ + className: _react2.default.PropTypes.string +}; +var defaultProps = { + className: '' +}; + +/** + * The SLDSPageHeader component adds SLDSPageHeader, SLDSPageHeader.Info, SLDSPageHeader.Title, SLDSPageHeader.DetailRow, and SLDSPageHeader.DetailBlock. + */ + +var PageHeader = function (_Component) { + _inherits(PageHeader, _Component); + + function PageHeader() { + _classCallCheck(this, PageHeader); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(PageHeader).apply(this, arguments)); + } + + _createClass(PageHeader, [{ + key: 'render', + value: function render() { + var _props = this.props; + var children = _props.children; + var className = _props.className; + + var attr = (0, _lodash2.default)(['children', 'className'], this.props); + var classes = this._getClassNames(className); + + return _react2.default.createElement( + 'div', + _extends({ className: classes, role: 'banner' }, attr), + children + ); + } + }, { + key: '_getClassNames', + value: function _getClassNames(className) { + return (0, _classnames2.default)('slds-page-header', className); + } + }]); + + return PageHeader; +}(_react.Component); + +PageHeader.displayName = displayName; +PageHeader.propTypes = propTypes; +PageHeader.defaultProps = defaultProps; + +module.exports = PageHeader; +module.exports.Info = _Info2.default; +module.exports.Title = _Title2.default; +module.exports.DetailRow = _DetailRow2.default; +module.exports.DetailBlock = _DetailBlock2.default; \ No newline at end of file diff --git a/scripts/component-docs.js b/scripts/component-docs.js index dea34a3624..f0b25b223a 100644 --- a/scripts/component-docs.js +++ b/scripts/component-docs.js @@ -12,6 +12,7 @@ var componentNames = [ 'SLDSMenuPicklist', 'SLDSModal', 'SLDSNotification', + 'SLDSPageHeader', 'SLDSPopoverTooltip', 'SLDSDatepickerSingleSelect', 'SLDSTimepicker',