UNPKG

@prosperitainova/dumbo-react-native

Version:
282 lines (279 loc) 8.73 kB
"use strict"; import React from 'react'; import { ActionSheetIOS, Platform, Pressable, ScrollView, StyleSheet, View, Modal as ReactModal, Image } from 'react-native'; import { createIcon, pressableFeedbackStyle, styleReferenceBreaker } from '../../helpers'; import { modalPresentations } from '../../constants/constants'; import { getColor } from '../../styles/colors'; import { Overlay } from '../Overlay'; import { Text } from '../Text'; import { zIndexes } from '../../styles/z-index'; import { SafeAreaWrapper } from '../SafeAreaWrapper'; /** Item to pass to ActionSheet */ /** Props for ActionSheet component */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * ActionSheet component for the choice option at the bottom of a screen. * Render a popup (from bottom) to show menu options for when non Yes/No questions are needed. * Uses the OS ActionSheet if supported. Otherwise renders a custom one with similar styling. * * {@link https://github.com/carbon-design-system/carbon-react-native/blob/main/example/src/Views/ActionSheet.tsx | Example code} */ export class ActionSheet extends React.Component { get styles() { const { fullBleed } = this.props; return StyleSheet.create({ modal: { zIndex: zIndexes.actionSheet }, safeAreaWrapper: { position: 'relative', flexGrow: 1, flexDirection: 'row-reverse', justifyContent: 'center' }, containerWrapper: { flexGrow: 1, flexDirection: 'row-reverse', margin: fullBleed ? 0 : 16, maxWidth: 480 }, blurBackground: { zIndex: zIndexes.behind, position: 'absolute', top: 0, right: 0, left: 0, bottom: 0, flex: 1 }, wrapper: { backgroundColor: getColor('layer01'), alignSelf: 'flex-end', width: '100%' }, textArea: { padding: 16, paddingBottom: 0, paddingTop: 22, borderBottomColor: getColor('borderSubtle01'), borderBottomWidth: 1 }, titleNoBody: { marginBottom: 8 }, body: { marginBottom: 8, color: getColor('textHelper') }, optionsWrapper: { maxHeight: '50%' }, options: { flexGrow: 0 }, option: { padding: 13, paddingLeft: 16, flexDirection: 'row' }, cancelButton: { backgroundColor: getColor('buttonSecondary'), padding: 13, paddingLeft: 16 }, cancelButtonText: { color: getColor('textOnColor') }, backgroundPress: { zIndex: zIndexes.behind, position: 'absolute', top: 0, right: 0, left: 0, bottom: 0, flex: 1 }, iconStyle: { width: 20, height: 20, paddingTop: 1 }, iconImageStyle: { width: 20, height: 20 }, textStyle: { flex: 1 } }); } handleSystemTrigger = () => { const { open, title, body, items, cancelButtonIndex } = this.props; const options = items.filter(item => !item.hidden); const dangerIndex = options.findIndex(item => item.danger); if (open) { ActionSheetIOS.showActionSheetWithOptions({ destructiveButtonIndex: dangerIndex > -1 ? dangerIndex : undefined, options: options.map(item => item.text), title: title, message: body, cancelButtonIndex: cancelButtonIndex }, index => { const action = options[index]; if (action) { action.onPress(); } }); } }; get useSystemActionSheet() { const { forceCustomActionSheet } = this.props; return Platform.OS === 'ios' && !forceCustomActionSheet; } getStateStyle = state => { return state.pressed ? { backgroundColor: getColor('buttonSecondaryActive') } : undefined; }; getCancelStateStyle = state => { return state.pressed ? { backgroundColor: getColor('layerActive01') } : undefined; }; get customActionSheet() { const { open, title, body, items, cancelButtonIndex } = this.props; const options = items.filter(item => !item.hidden); const cancel = options.splice(cancelButtonIndex || 0, 1)[0] || { text: '', onPress: () => {} }; if (!open) { return null; } const invisibleButton = /*#__PURE__*/_jsx(Pressable, { onPress: cancel.onPress, style: this.styles.backgroundPress, accessible: false, accessibilityRole: "none", accessibilityLabel: cancel.text }); return /*#__PURE__*/_jsxs(ReactModal, { style: this.styles.modal, supportedOrientations: modalPresentations, transparent: true, onRequestClose: cancel.onPress, children: [/*#__PURE__*/_jsx(Overlay, { style: this.styles.blurBackground }), /*#__PURE__*/_jsxs(SafeAreaWrapper, { style: this.styles.safeAreaWrapper, children: [invisibleButton, /*#__PURE__*/_jsxs(View, { style: this.styles.containerWrapper, children: [invisibleButton, /*#__PURE__*/_jsxs(View, { style: this.styles.wrapper, children: [/*#__PURE__*/_jsxs(View, { style: this.styles.textArea, children: [/*#__PURE__*/_jsx(Text, { style: body ? undefined : this.styles.titleNoBody, type: "heading-compact-01", text: title }), !!body && /*#__PURE__*/_jsx(Text, { style: this.styles.body, type: "helper-text-01", text: body })] }), /*#__PURE__*/_jsx(View, { style: this.styles.optionsWrapper, children: /*#__PURE__*/_jsx(ScrollView, { bounces: false, style: this.styles.options, children: options.map((item, index) => { const finalStyle = styleReferenceBreaker(this.styles.option); const lastItem = index === options.length - 1; let imageItem; if (item.icon?.icon) { imageItem = createIcon(item.icon.icon, 20, 20); } else if (item.icon?.image) { imageItem = /*#__PURE__*/_jsx(Image, { style: this.styles.iconImageStyle, resizeMode: "contain", source: item.icon.image }); } if (item.danger) { finalStyle.backgroundColor = getColor('buttonDangerPrimary'); } if (item.divider && !lastItem) { finalStyle.borderBottomColor = finalStyle.borderBottomColor || getColor('borderSubtle00'); finalStyle.borderBottomWidth = finalStyle.borderBottomWidth || 1; } return /*#__PURE__*/_jsxs(Pressable, { style: state => pressableFeedbackStyle(state, finalStyle, this.getStateStyle), accessibilityLabel: item.text, onPress: () => { item.onPress(); }, children: [/*#__PURE__*/_jsx(Text, { style: this.styles.textStyle, text: item.text }), !!imageItem && /*#__PURE__*/_jsx(View, { style: this.styles.iconStyle, children: imageItem })] }, index); }) }) }), /*#__PURE__*/_jsx(Pressable, { style: state => pressableFeedbackStyle(state, this.styles.cancelButton, this.getCancelStateStyle), accessibilityLabel: cancel.text, onPress: () => { cancel.onPress(); }, children: /*#__PURE__*/_jsx(Text, { style: this.styles.cancelButtonText, text: cancel.text }) })] })] })] })] }); } componentDidUpdate(previousProps) { const { open } = this.props; if (previousProps.open !== open) { if (this.useSystemActionSheet) { this.handleSystemTrigger(); } } } componentDidMount() { if (this.useSystemActionSheet) { this.handleSystemTrigger(); } } render() { if (!this.useSystemActionSheet) { return this.customActionSheet; } return null; } } //# sourceMappingURL=index.js.map