From c8be8804647fcb24cc4e393f75a184318f433a27 Mon Sep 17 00:00:00 2001 From: Matthew Oaxaca Date: Sun, 11 Feb 2018 14:59:50 -0800 Subject: [PATCH] Proposing Idea of Accordion Animation API --- .../Advanced/AccordionExampleAnimated.js | 51 +++++++++++++ .../AccordionExampleAnimatedContent.js | 50 +++++++++++++ .../modules/Accordion/Advanced/index.js | 10 +++ src/modules/Accordion/Accordion.d.ts | 2 + src/modules/Accordion/Accordion.js | 2 + src/modules/Accordion/AccordionAnimated.d.ts | 31 ++++++++ src/modules/Accordion/AccordionAnimated.js | 74 +++++++++++++++++++ src/modules/Accordion/AccordionContent.js | 42 ++++++++++- 8 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimated.js create mode 100644 docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimatedContent.js create mode 100644 src/modules/Accordion/AccordionAnimated.d.ts create mode 100644 src/modules/Accordion/AccordionAnimated.js diff --git a/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimated.js b/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimated.js new file mode 100644 index 0000000000..be25003a6a --- /dev/null +++ b/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimated.js @@ -0,0 +1,51 @@ +import React from 'react' +import { Accordion } from 'semantic-ui-react' + +const ShortContent = ( +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut varius, + nulla quis ornare suscipit, lacus diam lacinia tellus, quis pharetra + odio nulla nec erat. Nulla odio tortor, convallis vitae purus a, +
+) + +const LongContent = ( +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut varius, + nulla quis ornare suscipit, lacus diam lacinia tellus, quis pharetra + odio nulla nec erat. Nulla odio tortor, convallis vitae purus a, + finibus commodo mauris. Proin in tristique ipsum, sit amet suscipit + nulla. Nullam sed felis nec sem pharetra venenatis. Sed porta nunc vitae + ipsum feugiat, quis faucibus velit iaculis. Nam vel lacus feugiat, gravida + sapien quis, cursus nisl. Etiam mattis semper justo tincidunt fringilla. + Mauris sodales, +
+) + +const rootPanels = [ + { + title: 'Short Content', + content: { + content: ShortContent, + key: 'content-1', + }, + }, + { + title: 'Long Content', + content: { + content: LongContent, + key: 'content-2', + }, + }, +] + +const AccordionExampleTransition = () => ( + +) + +export default AccordionExampleTransition diff --git a/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimatedContent.js b/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimatedContent.js new file mode 100644 index 0000000000..7933d26799 --- /dev/null +++ b/docs/app/Examples/modules/Accordion/Advanced/AccordionExampleAnimatedContent.js @@ -0,0 +1,50 @@ +import React from 'react' +import { Accordion } from 'semantic-ui-react' + +const ShortContent = ( +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut varius, + nulla quis ornare suscipit, lacus diam lacinia tellus, quis pharetra + odio nulla nec erat. Nulla odio tortor, convallis vitae purus a, +
+) + +const LongContent = ( +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut varius, + nulla quis ornare suscipit, lacus diam lacinia tellus, quis pharetra + odio nulla nec erat. Nulla odio tortor, convallis vitae purus a, + finibus commodo mauris. Proin in tristique ipsum, sit amet suscipit + nulla. Nullam sed felis nec sem pharetra venenatis. Sed porta nunc vitae + ipsum feugiat, quis faucibus velit iaculis. Nam vel lacus feugiat, gravida + sapien quis, cursus nisl. Etiam mattis semper justo tincidunt fringilla. + Mauris sodales, +
+) + +const rootPanels = [ + { + title: 'Short Content', + content: { + animation: 'slide down', + content: ShortContent, + key: 'content-1', + transitionDuration: 300, + }, + }, + { + title: 'Long Content', + content: { + animation: 'fade down', + content: LongContent, + key: 'content-2', + transitionDuration: 300, + }, + }, +] + +const AccordionExampleTransition = () => ( + +) + +export default AccordionExampleTransition diff --git a/docs/app/Examples/modules/Accordion/Advanced/index.js b/docs/app/Examples/modules/Accordion/Advanced/index.js index c684e7e599..17ffbce5fe 100644 --- a/docs/app/Examples/modules/Accordion/Advanced/index.js +++ b/docs/app/Examples/modules/Accordion/Advanced/index.js @@ -28,6 +28,16 @@ const AccordionAdvancedExamples = () => ( description='Panels of Accordion can be rendered via shorthand prop.' examplePath='modules/Accordion/Advanced/AccordionExampleShorthand' /> + + ) diff --git a/src/modules/Accordion/Accordion.d.ts b/src/modules/Accordion/Accordion.d.ts index fbe086611f..1e9aafb367 100644 --- a/src/modules/Accordion/Accordion.d.ts +++ b/src/modules/Accordion/Accordion.d.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { default as AccordionAccordion, AccordionAccordionProps } from './AccordionAccordion'; +import { default as AccordionAnimated } from './AccordionAnimated'; import { default as AccordionContent } from './AccordionContent'; import { default as AccordionTitle } from './AccordionTitle'; @@ -22,6 +23,7 @@ export interface AccordionProps extends AccordionAccordionProps { interface AccordionComponent extends React.ComponentClass { Accordion: typeof AccordionAccordion; + Animated: typeof AccordionAnimated; Content: typeof AccordionContent; Title: typeof AccordionTitle; } diff --git a/src/modules/Accordion/Accordion.js b/src/modules/Accordion/Accordion.js index dd0e7876a7..a4448b9b31 100644 --- a/src/modules/Accordion/Accordion.js +++ b/src/modules/Accordion/Accordion.js @@ -8,6 +8,7 @@ import { useKeyOnly, } from '../../lib' import AccordionAccordion from './AccordionAccordion' +import AccordionAnimated from './AccordionAnimated' import AccordionContent from './AccordionContent' import AccordionTitle from './AccordionTitle' @@ -54,6 +55,7 @@ Accordion.propTypes = { } Accordion.Accordion = AccordionAccordion +Accordion.Animated = AccordionAnimated Accordion.Content = AccordionContent Accordion.Title = AccordionTitle diff --git a/src/modules/Accordion/AccordionAnimated.d.ts b/src/modules/Accordion/AccordionAnimated.d.ts new file mode 100644 index 0000000000..fbe086611f --- /dev/null +++ b/src/modules/Accordion/AccordionAnimated.d.ts @@ -0,0 +1,31 @@ +import * as React from 'react'; + +import { default as AccordionAccordion, AccordionAccordionProps } from './AccordionAccordion'; +import { default as AccordionContent } from './AccordionContent'; +import { default as AccordionTitle } from './AccordionTitle'; + +export interface AccordionProps extends AccordionAccordionProps { + [key: string]: any; + + /** Additional classes. */ + className?: string; + + /** Format to take up the width of its container. */ + fluid?: boolean; + + /** Format for dark backgrounds. */ + inverted?: boolean; + + /** Adds some basic styling to accordion panels. */ + styled?: boolean; +} + +interface AccordionComponent extends React.ComponentClass { + Accordion: typeof AccordionAccordion; + Content: typeof AccordionContent; + Title: typeof AccordionTitle; +} + +declare const Accordion: AccordionComponent; + +export default Accordion; diff --git a/src/modules/Accordion/AccordionAnimated.js b/src/modules/Accordion/AccordionAnimated.js new file mode 100644 index 0000000000..f2ac70a4a7 --- /dev/null +++ b/src/modules/Accordion/AccordionAnimated.js @@ -0,0 +1,74 @@ +import cx from 'classnames' +import PropTypes from 'prop-types' +import React from 'react' + +import { + customPropTypes, + useKeyOnly, + getUnhandledProps, + META, +} from '../../lib' +import AccordionAccordion from './AccordionAccordion' + +/** + * An accordion allows users to toggle the display of sections of content. + */ +function AccordionAnimated(props) { + const { + className, + fluid, + inverted, + styled, + panels, + } = props + + const classes = cx( + 'ui', + useKeyOnly(fluid, 'fluid'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(styled, 'styled'), + className, + ) + const rest = getUnhandledProps(AccordionAnimated, props) + const animatedPanels = panels.map(panel => ({ + content: { + ...panel.content, + animation: 'fade down', + transitionDuration: 300, + }, + title: panel.title, + })) + return +} + +AccordionAnimated._meta = { + name: 'AccordionAnimated', + type: META.TYPES.MODULE, +} + +AccordionAnimated.propTypes = { + /** Additional classes. */ + className: PropTypes.string, + + /** Format to take up the width of its container. */ + fluid: PropTypes.bool, + + /** Format for dark backgrounds. */ + inverted: PropTypes.bool, + + /** Adds some basic styling to accordion panels. */ + styled: PropTypes.bool, + + /** Shorthand array of props for Accordion. */ + panels: customPropTypes.every([ + customPropTypes.disallow(['children']), + PropTypes.arrayOf( + PropTypes.shape({ + content: customPropTypes.itemShorthand, + title: customPropTypes.itemShorthand, + }), + ), + ]), +} + +export default AccordionAnimated diff --git a/src/modules/Accordion/AccordionContent.js b/src/modules/Accordion/AccordionContent.js index 4c9e16156d..85e894a5c3 100644 --- a/src/modules/Accordion/AccordionContent.js +++ b/src/modules/Accordion/AccordionContent.js @@ -11,20 +11,43 @@ import { META, useKeyOnly, } from '../../lib' +import Transition from '../Transition' /** * A content sub-component for Accordion component. */ function AccordionContent(props) { - const { active, children, className, content } = props + const { + active, + animation, + children, + className, + content, + transitionDuration, + } = props + const rest = getUnhandledProps(AccordionContent, props) + const ElementType = getElementType(AccordionContent, props) + + if (transitionDuration) { + const classes = cx( + 'content', + className, + ) + return ( + + {active && ( + + {childrenUtils.isNil(children) ? content : children} + + )} + + ) + } const classes = cx( 'content', useKeyOnly(active, 'active'), className, ) - const rest = getUnhandledProps(AccordionContent, props) - const ElementType = getElementType(AccordionContent, props) - return ( {childrenUtils.isNil(children) ? content : children} @@ -47,6 +70,17 @@ AccordionContent.propTypes = { /** Shorthand for primary content. */ content: customPropTypes.contentShorthand, + + /** Animation type */ + animation: PropTypes.string, + + /** Animation type */ + transitionDuration: PropTypes.number, +} + +AccordionContent.defaultProps = { + animation: 'slide down', + transitionDuration: 0, } AccordionContent._meta = {