@prosperitainova/dumbo-react-native
Version:
Dumbo for React Native Library
266 lines (262 loc) • 8.5 kB
JavaScript
"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