# ModalFooter

**📖 Live documentation:** https://cds.coinbase.com/components/overlay/ModalFooter/?platform=mobile

A footer component for Modal.

## Import

```tsx
import { ModalFooter } from '@coinbase/cds-mobile/overlays/modal/ModalFooter'
```

## Examples

ModalFooter provides a consistent action area for [Modal](/components/overlay/Modal). It accepts `primaryAction` and optional `secondaryAction` buttons using [ButtonGroup](/components/inputs/ButtonGroup) for layout.

### Basics

Pass a `primaryAction` button to create a simple footer. The footer automatically displays a top border.

```jsx
function BasicExample() {
  const [visible, setVisible] = useState(false);
  return (
    <>
      <Button onPress={() => setVisible(true)}>Open Modal</Button>
      <Modal onRequestClose={() => setVisible(false)} visible={visible}>
        <ModalHeader title="Success" closeAccessibilityLabel="Close" />
        <ModalBody>
          <Text>Your changes have been saved.</Text>
        </ModalBody>
        <ModalFooter primaryAction={<Button onPress={() => setVisible(false)}>Done</Button>} />
      </Modal>
    </>
  );
}
```

### Two Actions

Add a `secondaryAction` for cancel/dismiss patterns. By default, buttons display side-by-side horizontally.

```jsx
function TwoActionsExample() {
  const [visible, setVisible] = useState(false);
  return (
    <>
      <Button onPress={() => setVisible(true)}>Open Modal</Button>
      <Modal onRequestClose={() => setVisible(false)} visible={visible}>
        <ModalHeader title="Confirm Action" closeAccessibilityLabel="Close" />
        <ModalBody>
          <Text>Are you sure you want to proceed with this action?</Text>
        </ModalBody>
        <ModalFooter
          primaryAction={<Button onPress={() => setVisible(false)}>Confirm</Button>}
          secondaryAction={
            <Button onPress={() => setVisible(false)} variant="secondary">
              Cancel
            </Button>
          }
        />
      </Modal>
    </>
  );
}
```

### Vertical Layout

Use `direction="vertical"` to stack buttons. The primary action appears on top when stacked.

```jsx
function VerticalExample() {
  const [visible, setVisible] = useState(false);
  return (
    <>
      <Button onPress={() => setVisible(true)}>Open Modal</Button>
      <Modal onRequestClose={() => setVisible(false)} visible={visible}>
        <ModalHeader title="Subscribe" closeAccessibilityLabel="Close" />
        <ModalBody>
          <Text>Get premium features for $9.99/month.</Text>
        </ModalBody>
        <ModalFooter
          direction="vertical"
          primaryAction={<Button onPress={() => setVisible(false)}>Subscribe Now</Button>}
          secondaryAction={
            <Button onPress={() => setVisible(false)} variant="secondary">
              Maybe Later
            </Button>
          }
        />
      </Modal>
    </>
  );
}
```

### Destructive Actions

Use `variant="negative"` on the primary button for destructive actions.

```jsx
function DestructiveExample() {
  const [visible, setVisible] = useState(false);
  return (
    <>
      <Button onPress={() => setVisible(true)}>Delete Account</Button>
      <Modal onRequestClose={() => setVisible(false)} visible={visible}>
        <ModalHeader title="Delete Account" closeAccessibilityLabel="Close" />
        <ModalBody>
          <Text>This action cannot be undone. All your data will be permanently deleted.</Text>
        </ModalBody>
        <ModalFooter
          primaryAction={
            <Button onPress={() => setVisible(false)} variant="negative">
              Delete
            </Button>
          }
          secondaryAction={
            <Button onPress={() => setVisible(false)} variant="secondary">
              Cancel
            </Button>
          }
        />
      </Modal>
    </>
  );
}
```

### Loading State

Show a loading state on the primary button while an action is processing.

```jsx
function LoadingExample() {
  const [visible, setVisible] = useState(false);
  const [loading, setLoading] = useState(false);

  const handleSave = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setVisible(false);
    }, 2000);
  };

  return (
    <>
      <Button onPress={() => setVisible(true)}>Open Modal</Button>
      <Modal onRequestClose={() => setVisible(false)} visible={visible}>
        <ModalHeader title="Save Changes" closeAccessibilityLabel="Close" />
        <ModalBody>
          <Text>Your changes will be saved to the server.</Text>
        </ModalBody>
        <ModalFooter
          primaryAction={
            <Button onPress={handleSave} loading={loading}>
              Save
            </Button>
          }
          secondaryAction={
            <Button onPress={() => setVisible(false)} variant="secondary" disabled={loading}>
              Cancel
            </Button>
          }
        />
      </Modal>
    </>
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `primaryAction` | `ReactElement<SharedProps & Pick<SharedAccessibilityProps, accessibilityLabel> & AccessibilityProps & ComponentEventHandlerProps & Pick<PressableProps, style \| onPress \| hitSlop> & Omit<InteractableBaseProps, style \| pressed> & { noScaleOnPress?: boolean \| undefined; onPressIn?: ((event: GestureResponderEvent) => void) \| undefined; onPressOut?: ((event: GestureResponderEvent) => void) \| undefined; feedback?: HapticFeedbackType \| undefined; loading?: boolean \| undefined; debounceTime?: number \| undefined; disableDebounce?: boolean \| undefined; } & { variant?: ButtonVariant \| undefined; disabled?: boolean \| undefined; loading?: boolean \| undefined; progressCircleSize?: number \| undefined; transparent?: boolean \| undefined; block?: boolean \| undefined; compact?: boolean \| undefined; children: ReactNode; start?: ReactNode; startIcon?: IconName \| undefined; startIconActive?: boolean \| undefined; end?: ReactNode; endIcon?: IconName \| undefined; endIconActive?: boolean \| undefined; flush?: end \| start \| undefined; name?: string \| undefined; noScaleOnPress?: boolean \| undefined; numberOfLines?: number \| undefined; } & { onPress?: ((event: GestureResponderEvent) => void) \| null \| undefined; }, string \| JSXElementConstructor<any>>` | Yes | `-` | Primary action button |
| `alignContent` | `flex-start \| flex-end \| center \| stretch \| space-between \| space-around \| space-evenly` | No | `-` | - |
| `alignItems` | `flex-start \| flex-end \| center \| stretch \| baseline` | No | `-` | - |
| `alignSelf` | `auto \| FlexAlignType` | No | `-` | - |
| `animated` | `boolean` | No | `-` | - |
| `aspectRatio` | `string \| number` | No | `-` | - |
| `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
| `borderBottomLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
| `borderBottomRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
| `borderBottomWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
| `borderColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
| `borderEndWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
| `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
| `borderStartWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
| `borderTopLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
| `borderTopRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
| `borderTopWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
| `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
| `bordered` | `boolean` | No | `-` | Add a border around all sides of the box. |
| `borderedBottom` | `boolean` | No | `-` | Add a border to the bottom side of the box. |
| `borderedEnd` | `boolean` | No | `-` | Add a border to the trailing side of the box. |
| `borderedHorizontal` | `boolean` | No | `-` | Add a border to the leading and trailing sides of the box. |
| `borderedStart` | `boolean` | No | `-` | Add a border to the leading side of the box. |
| `borderedTop` | `boolean` | No | `-` | Add a border to the top side of the box. |
| `borderedVertical` | `boolean` | No | `-` | Add a border to the top and bottom sides of the box. |
| `bottom` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `color` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
| `columnGap` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `dangerouslySetBackground` | `string` | No | `-` | - |
| `direction` | `horizontal \| vertical` | No | `horizontal Stack buttons vertically or horizontally.` | - |
| `display` | `flex \| none \| contents` | No | `-` | - |
| `elevation` | `0 \| 1 \| 2` | No | `-` | Determines box shadow styles. Parent should have overflow set to visible to ensure styles are not clipped. |
| `flexBasis` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `flexDirection` | `row \| column \| row-reverse \| column-reverse` | No | `-` | - |
| `flexGrow` | `number` | No | `-` | - |
| `flexShrink` | `number` | No | `-` | - |
| `flexWrap` | `wrap \| nowrap \| wrap-reverse` | No | `-` | - |
| `font` | `inherit \| FontFamily` | No | `-` | - |
| `fontFamily` | `inherit \| FontFamily` | No | `-` | - |
| `fontSize` | `inherit \| FontSize` | No | `-` | - |
| `fontWeight` | `inherit \| FontWeight` | No | `-` | - |
| `gap` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `height` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `justifyContent` | `flex-start \| flex-end \| center \| space-between \| space-around \| space-evenly` | No | `-` | - |
| `left` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `lineHeight` | `inherit \| LineHeight` | No | `-` | - |
| `margin` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginBottom` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginEnd` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginStart` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginTop` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginX` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `marginY` | `0 \| -1 \| -2 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5` | No | `-` | - |
| `maxHeight` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `maxWidth` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `minHeight` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `minWidth` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `onPointerCancel` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerCancelCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerDown` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerDownCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerEnter` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerEnterCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerLeave` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerLeaveCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerMove` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerMoveCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerUp` | `((event: PointerEvent) => void)` | No | `-` | - |
| `onPointerUpCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
| `opacity` | `number \| AnimatedNode` | No | `-` | - |
| `overflow` | `visible \| hidden \| scroll` | No | `-` | - |
| `padding` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingBottom` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingEnd` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingStart` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingTop` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingX` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `paddingY` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `pin` | `top \| bottom \| left \| right \| all` | No | `-` | Direction in which to absolutely pin the box. |
| `position` | `absolute \| relative \| static` | No | `-` | - |
| `right` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `rowGap` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5` | No | `-` | - |
| `secondaryAction` | `ReactElement<SharedProps & Pick<SharedAccessibilityProps, accessibilityLabel> & AccessibilityProps & ComponentEventHandlerProps & Pick<PressableProps, style \| onPress \| hitSlop> & Omit<InteractableBaseProps, style \| pressed> & { noScaleOnPress?: boolean; onPressIn?: ((event: GestureResponderEvent) => void) \| undefined; onPressOut?: ((event: GestureResponderEvent) => void) \| undefined; feedback?: HapticFeedbackType \| undefined; loading?: boolean \| undefined; debounceTime?: number \| undefined; disableDebounce?: boolean \| undefined; } & { variant?: ButtonVariant \| undefined; disabled?: boolean \| undefined; loading?: boolean \| undefined; progressCircleSize?: number \| undefined; transparent?: boolean \| undefined; block?: boolean \| undefined; compact?: boolean \| undefined; children: ReactNode; start?: ReactNode; startIcon?: IconName \| undefined; startIconActive?: boolean \| undefined; end?: ReactNode; endIcon?: IconName \| undefined; endIconActive?: boolean \| undefined; flush?: end \| start \| undefined; name?: string \| undefined; noScaleOnPress?: boolean \| undefined; numberOfLines?: number \| undefined; } & { onPress?: ((event: GestureResponderEvent) => void) \| null \| undefined; }, string \| JSXElementConstructor<any>> \| undefined` | No | `-` | Secondary action button |
| `style` | `false \|  \| RegisteredStyle<ViewStyle> \| Value \| AnimatedInterpolation<string \| number> \| WithAnimatedObject<ViewStyle> \| WithAnimatedArray<Falsy \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<Falsy \| ViewStyle \| RegisteredStyle<ViewStyle>> \| readonly (Falsy \| ViewStyle \| RegisteredStyle<ViewStyle>)[]> \| null` | No | `-` | - |
| `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID Used to locate this view in end-to-end tests. |
| `textAlign` | `left \| right \| auto \| center \| justify` | No | `-` | - |
| `textDecorationLine` | `none \| underline \| line-through \| underline line-through` | No | `-` | - |
| `textDecorationStyle` | `solid \| dotted \| dashed \| double` | No | `-` | - |
| `textTransform` | `none \| capitalize \| uppercase \| lowercase` | No | `-` | - |
| `top` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `transform` | `string \| readonly (({ scaleX: AnimatableNumericValue; } & { scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ scaleY: AnimatableNumericValue; } & { scaleX?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ translateX: AnimatableNumericValue \| ${number}%; } & { scaleX?: undefined; scaleY?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ translateY: AnimatableNumericValue \| ${number}%; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ perspective: AnimatableNumericValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotate: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateX: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateY: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateZ: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ scale: AnimatableNumericValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ skewX: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ skewY: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; matrix?: undefined; }) \| ({ matrix: AnimatableNumericValue[]; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; }))[]` | No | `-` | - |
| `userSelect` | `none \| auto \| text \| contain \| all` | No | `-` | - |
| `width` | `null \| number \| AnimatedNode \| auto \| ${number}%` | No | `-` | - |
| `zIndex` | `number` | No | `-` | - |


