diff --git a/example/src/Examples/ListAccordionExample.tsx b/example/src/Examples/ListAccordionExample.tsx
index 58c3841de5..ac2ab35771 100644
--- a/example/src/Examples/ListAccordionExample.tsx
+++ b/example/src/Examples/ListAccordionExample.tsx
@@ -56,6 +56,17 @@ const ListAccordionExample = () => {
/>
+
+
+ }
+ title="Expandable list item"
+ expandDirection="upwards"
+ >
+
+
+
+
);
};
diff --git a/example/src/Examples/ListAccordionGroupExample.tsx b/example/src/Examples/ListAccordionGroupExample.tsx
index 51861858bb..8aa81bd001 100644
--- a/example/src/Examples/ListAccordionGroupExample.tsx
+++ b/example/src/Examples/ListAccordionGroupExample.tsx
@@ -71,6 +71,25 @@ const ListAccordionGroupExample = () => {
+
+
+ }
+ title="Expandable list item"
+ id="1"
+ >
+
+
+
+ }
+ title="Expandable list item 2"
+ id="2"
+ >
+
+
+
+
);
};
diff --git a/src/components/List/ListAccordion.tsx b/src/components/List/ListAccordion.tsx
index 75505c7367..2691035188 100644
--- a/src/components/List/ListAccordion.tsx
+++ b/src/components/List/ListAccordion.tsx
@@ -18,7 +18,7 @@ import { ListAccordionGroupContext } from './ListAccordionGroup';
import type { ListChildProps, Style } from './utils';
import { getAccordionColors, getLeftStyles } from './utils';
import { useInternalTheme } from '../../core/theming';
-import type { ThemeProp } from '../../types';
+import type { InternalTheme, ThemeProp } from '../../types';
import MaterialCommunityIcon from '../MaterialCommunityIcon';
import TouchableRipple, {
Props as TouchableRippleProps,
@@ -136,6 +136,10 @@ export type Props = {
* This can be used to enlarge the touchable area beyond the visible component.
*/
hitSlop?: TouchableRippleProps['hitSlop'];
+ /**
+ * Sets expansion direction for the accordion.
+ */
+ expandDirection?: 'downwards' | 'upwards';
};
/**
@@ -175,6 +179,39 @@ export type Props = {
* export default MyComponent;
* ```
*/
+function getExpandedContent({
+ isExpanded,
+ children,
+ left,
+ theme,
+}: {
+ isExpanded: boolean;
+ children: React.ReactNode;
+ left?: Props['left'];
+ theme: InternalTheme;
+}) {
+ return isExpanded
+ ? React.Children.map(children, (child) => {
+ if (
+ !left ||
+ !React.isValidElement(child) ||
+ child.props.left ||
+ child.props.right
+ ) {
+ return child;
+ }
+
+ return React.cloneElement(child, {
+ style: [
+ theme.isV3 ? styles.childV3 : styles.child,
+ child.props.style,
+ ],
+ theme,
+ });
+ })
+ : null;
+}
+
const ListAccordion = ({
left,
right,
@@ -202,6 +239,7 @@ const ListAccordion = ({
titleMaxFontSizeMultiplier,
descriptionMaxFontSizeMultiplier,
hitSlop,
+ expandDirection = 'downwards',
}: Props) => {
const theme = useInternalTheme(themeOverrides);
const [expanded, setExpanded] = React.useState(
@@ -252,8 +290,17 @@ const ListAccordion = ({
groupContext && id !== undefined
? () => groupContext.onAccordionPress(id)
: handlePressAction;
+
+ const expandedContent = getExpandedContent({
+ isExpanded,
+ children,
+ left,
+ theme,
+ });
+
return (
+ {expandDirection === 'upwards' ? expandedContent : null}
- {isExpanded
- ? React.Children.map(children, (child) => {
- if (
- left &&
- React.isValidElement(child) &&
- !child.props.left &&
- !child.props.right
- ) {
- return React.cloneElement(child, {
- style: [
- theme.isV3 ? styles.childV3 : styles.child,
- child.props.style,
- ],
- theme,
- });
- }
-
- return child;
- })
- : null}
+ {expandDirection === 'downwards' ? expandedContent : null}
);
};
diff --git a/src/components/List/ListAccordionGroup.tsx b/src/components/List/ListAccordionGroup.tsx
index 15e148ae6e..c56a9e5dba 100644
--- a/src/components/List/ListAccordionGroup.tsx
+++ b/src/components/List/ListAccordionGroup.tsx
@@ -13,11 +13,16 @@ export type Props = {
* React elements containing list accordions
*/
children: React.ReactNode;
+ /**
+ * Sets expansion direction for all accordions in the group.
+ */
+ expandDirection?: 'downwards' | 'upwards';
};
export type ListAccordionGroupContextType = {
expandedId: string | number | undefined;
onAccordionPress: (expandedId: string | number) => void;
+ expandDirection?: 'downwards' | 'upwards';
} | null;
export const ListAccordionGroupContext =
@@ -60,6 +65,7 @@ const ListAccordionGroup = ({
expandedId: expandedIdProp,
onAccordionPress,
children,
+ expandDirection = 'downwards',
}: Props) => {
const [expandedId, setExpandedId] = React.useState<
string | number | undefined
@@ -76,6 +82,7 @@ const ListAccordionGroup = ({
value={{
expandedId: expandedIdProp || expandedId, // component can be controlled or uncontrolled
onAccordionPress: onAccordionPress || onAccordionPressDefault,
+ expandDirection,
}}
>
{children}