UNPKG

@prosperitainova/dumbo-react-native

Version:
266 lines (262 loc) 8.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Dropdown = void 0; var _react = _interopRequireDefault(require("react")); var _reactNative = require("react-native"); var _colors = require("../../styles/colors"); var _helpers = require("../../helpers"); var _Menu = require("../Menu"); var _BaseTextInputs = require("../BaseTextInputs"); var _Text = require("../Text"); var _ = _interopRequireDefault(require("@carbon/icons/es/chevron--down/20")); var _2 = _interopRequireDefault(require("@carbon/icons/es/chevron--up/20")); var _constants = require("../../constants/constants"); var _zIndex = require("../../styles/z-index"); var _defaultText = require("../../constants/defaultText"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** An item to pass to the Dropdown component */ /** Props for Dropdown component */ /** * Dropdown component for rendering a dropdown * * {@link https://github.com/carbon-design-system/carbon-react-native/blob/main/example/src/Views/Dropdown.tsx | Example code} */ class Dropdown extends _react.default.Component { state = { open: false, renderLeft: 0, renderRight: 0, renderTop: 0, renderBottom: 0, inverseMenu: false }; get itemColor() { const { disabled } = this.props; return disabled ? (0, _colors.getColor)('textDisabled') : (0, _colors.getColor)('textPrimary'); } get styles() { const { renderLeft, renderRight, renderTop, renderBottom, inverseMenu } = this.state; const { maxMenuHeight } = this.props; return _reactNative.StyleSheet.create({ modal: { zIndex: _zIndex.zIndexes.dropdown }, wrapper: {}, innerWrapper: { position: 'relative' }, closeModal: { zIndex: _zIndex.zIndexes.behind, top: 0, right: 0, bottom: 0, left: 0, position: 'absolute' }, menuWrapper: { position: 'absolute', top: renderTop, bottom: renderBottom, right: renderRight, left: renderLeft, maxHeight: inverseMenu ? undefined : maxMenuHeight || 280, flexDirection: inverseMenu ? 'column-reverse' : undefined, ..._colors.shadowStyle }, iconStyle: { position: 'absolute', top: 13, right: 13 }, dropdownText: { color: this.itemColor, paddingRight: 32 } }); } get textInputStyles() { const { light } = this.props; return (0, _BaseTextInputs.getTextInputStyle)(light); } get dropdownIcon() { const { open } = this.state; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: this.styles.iconStyle, children: (0, _helpers.createIcon)(open ? _2.default : _.default, 20, 20, this.itemColor) }); } toggleDropdown = () => { const { open } = this.state; this.setState({ open: !open }); }; closeDropdown = () => { this.setState({ open: false }); }; getStateStyle = state => { return state.pressed ? { backgroundColor: (0, _colors.getColor)('layerActive01'), borderColor: (0, _colors.getColor)('layerActive01') } : undefined; }; /** * Calculate where to render the overlayed dropdown menu * Sometimes didMount is not called before full render and results in all 0. setTimeout waits for load * * In event measure returns bad it will load to top of page with min width/height. * * @param item - View from reference */ setFormItemRef = item => { if (item && typeof item?.measure === 'function') { setTimeout(() => { const { renderLeft, renderRight, renderTop, renderBottom, inverseMenu } = this.state; const screenWidth = _reactNative.Dimensions.get('window').width || 320; const screenHeight = _reactNative.Dimensions.get('window').height || 320; const baseSafePadding = 44; item.measure((_fx, _fy, width, height, pageX, pageY) => { const newRenderLeft = pageX || 0; const newRenderRight = screenWidth - (newRenderLeft + (width || 200)); let newRenderTop = (pageY || 0) + (height || 200); let newRenderBottom = baseSafePadding; let newInverse = false; if (newRenderTop > screenHeight - 200) { newRenderBottom = screenHeight - (pageY || 0); newRenderTop = baseSafePadding; newInverse = true; } if (renderLeft !== newRenderLeft || renderRight !== newRenderRight || renderTop !== newRenderTop || renderBottom !== newRenderBottom || inverseMenu !== newInverse) { this.setState({ renderLeft: newRenderLeft, renderRight: newRenderRight, renderTop: newRenderTop, renderBottom: newRenderBottom, inverseMenu: newInverse }); } }); }); } }; render() { const { items, componentProps, style, label, helperText, value, onChange, disabled, closeText, valueToText, unsetText } = this.props; const { open } = this.state; const finalStyle = (0, _helpers.styleReferenceBreaker)(disabled ? this.textInputStyles.textBoxDisabled : this.textInputStyles.textBox); finalStyle.paddingTop = 10; const currentText = typeof valueToText === 'function' ? valueToText(value) : value; if (open) { finalStyle.borderBottomColor = (0, _colors.getColor)('borderSubtle01'); } const itemList = items.map((item, index) => { const newItem = Object.assign({}, item); newItem.style = { borderBottomColor: (0, _colors.getColor)('borderSubtle01'), borderBottomWidth: items.length === index + 1 ? 0 : 1, paddingRight: 0, paddingLeft: 0, marginRight: 16, marginLeft: 16 }; newItem.onPress = () => { this.setState({ open: false }); if (typeof onChange === 'function') { onChange(item); } }; return newItem; }); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: (0, _helpers.styleReferenceBreaker)(this.styles.wrapper, style), accessibilityRole: "menu", ...(componentProps || {}), children: [!!label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, { style: this.textInputStyles.label, type: "label-02", text: label }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: this.styles.innerWrapper, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, { disabled: disabled, style: state => (0, _helpers.pressableFeedbackStyle)(state, finalStyle, this.getStateStyle), accessibilityLabel: label, accessibilityHint: currentText, onPress: this.toggleDropdown, ref: this.setFormItemRef, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, { text: currentText || unsetText, breakMode: "tail", style: this.styles.dropdownText }), this.dropdownIcon] }), open && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Modal, { style: this.styles.modal, supportedOrientations: _constants.modalPresentations, transparent: true, onRequestClose: () => this.setState({ open: false }), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { style: this.styles.closeModal, accessibilityRole: "button", accessibilityLabel: closeText || _defaultText.defaultText.close, onPress: this.closeDropdown }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: this.styles.menuWrapper, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.Menu, { items: itemList }) })] })] }), !!helperText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, { style: this.textInputStyles.helperText, type: "helper-text-02", text: helperText })] }); } } exports.Dropdown = Dropdown; //# sourceMappingURL=index.js.map