@prosperitainova/dumbo-react-native
Version:
Dumbo for React Native Library
497 lines (493 loc) • 14.2 kB
JavaScript
"use strict";
import React from 'react';
import { StyleSheet, View, Pressable, Keyboard } from 'react-native';
import { createIcon, styleReferenceBreaker } from '../../helpers';
import { Text } from '../Text';
import { BaseTextInput, getTextInputStyle } from '../BaseTextInputs';
import { getNavigationListItemStyle } from '../NavigationListItem';
import { getColor } from '../../styles/colors';
import ChevronRightIcon from '@carbon/icons/es/chevron--right/20';
import CheckmarkIcon from '@carbon/icons/es/checkmark--outline/20';
import EmptyCheckmarkIcon from '@carbon/icons/es/radio-button/20';
import { Toggle } from '../Toggle';
import { Slider } from '../Slider';
/**
* `text` - plain text input. Use textInputProps for advanced controls.
* `password` - secure text input. Use textInputProps for advanced controls.
* `textarea` - plain text input with multi line support. Use textInputProps for advanced controls.
* `toggle` - Toggle field
* `toggle-inline` - Toggle inline (single line) field. Label and toggle are on single line (not stacked)
* `header` - Header with text and supported secondary text. This is for logical breaking up of form items.
* `static` - Static data to render (view only)
* `slider` - Slider bar to render
* `checkbox` - Checkbox to render. This can also be used as radio for checking proper items in the list. Use `overrideActiveCheckboxIcon` to override the icon
* `button` - Button to render. Supports icon via `buttonIcon`.
* `divider` - Empty space to divide form items.
*/
/** Props for FormItem component */
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/**
* FormItem component for rendering form items that are full bleed. This renders multiple types of form items. See props for types.
*
* {@link https://github.com/carbon-design-system/carbon-react-native/blob/main/example/src/Views/FormItem.tsx | Example code}
*/
export class FormItem extends React.Component {
state = {
error: false,
active: false
};
get noBottomPadding() {
const {
type
} = this.props;
return ['password', 'number', 'date', 'text', 'text-area', 'header', 'header-compact', 'divider'].includes(type);
}
get noDirectHelperText() {
const {
type
} = this.props;
return this.noBottomPadding || ['checkbox'].includes(type);
}
get noDirectLabel() {
const {
type
} = this.props;
return ['header', 'header-compact', 'divider', 'button', 'checkbox', 'toggle-inline'].includes(type);
}
get mainColor() {
const {
disabled
} = this.props;
return getColor(disabled ? 'textDisabled' : 'textPrimary');
}
get styles() {
const {
type,
disabled,
renderToggleCheckboxLeft
} = this.props;
const noRightPadding = ['password', 'number', 'date'].includes(type);
const noBottomPadding = this.noBottomPadding;
const helperTextColor = getColor(disabled ? 'textDisabled' : 'textHelper');
const baseWrapper = styleReferenceBreaker(getNavigationListItemStyle(), {
flexDirection: 'column',
padding: 14,
paddingRight: noRightPadding ? 0 : 16,
paddingLeft: 16,
paddingBottom: noBottomPadding ? 0 : 14,
borderColor: 'transparent',
borderWidth: 2
});
return StyleSheet.create({
wrapper: baseWrapper,
headerWrapper: {
padding: 16,
paddingTop: 32
},
headerCompactWrapper: {
padding: 16
},
dividerWrapper: {
height: 32
},
contentArea: {
width: '100%',
flexDirection: 'column'
},
headerContent: {
color: getColor('textSecondary')
},
headerContentDescription: {
color: getColor('textSecondary'),
paddingTop: 4
},
staticText: {
paddingTop: 8,
color: getColor('textSecondary')
},
textInput: {
width: '100%',
paddingTop: 0
},
buttonText: {
color: this.mainColor,
flex: 1
},
toggleText: {
color: this.mainColor,
flex: 1,
paddingTop: 13,
paddingBottom: 13,
paddingLeft: renderToggleCheckboxLeft ? 30 : undefined
},
toggleInlineText: {
paddingTop: 13,
paddingBottom: 13,
marginRight: 12,
color: getColor(disabled ? 'textDisabled' : 'textSecondary')
},
toggleInlineLabel: {
color: this.mainColor,
flex: 1,
paddingTop: 13,
paddingBottom: 13
},
toggleWrapper: {
paddingTop: 0
},
toggleDirectWrapper: {
paddingTop: 8
},
sliderIcons: {
paddingTop: 14
},
slider: {
flex: 1
},
helperText: {
color: helperTextColor
},
checkboxButton: {
...baseWrapper,
flex: 1,
flexDirection: 'row'
},
checkboxHelperText: {
color: helperTextColor,
marginTop: 0
},
checkboxTextWrapper: {
flex: 1,
paddingLeft: renderToggleCheckboxLeft ? 30 : undefined
}
});
}
triggerChange = value => {
const {
onChange
} = this.props;
if (typeof onChange === 'function') {
onChange(value);
}
};
onPress = event => {
const {
dismissKeyboardOnPress,
onPress
} = this.props;
if (dismissKeyboardOnPress && typeof Keyboard?.dismiss === 'function') {
Keyboard.dismiss();
}
if (typeof onPress === 'function') {
onPress(event);
}
};
get headerContent() {
const {
label,
helperText,
descriptionFirstHeader
} = this.props;
const items = [];
if (label) {
items.push(/*#__PURE__*/_jsx(Text, {
style: this.styles.headerContent,
type: "heading-compact-01",
text: label
}, "label"));
}
if (helperText) {
items.push(/*#__PURE__*/_jsx(Text, {
style: this.styles.headerContentDescription,
type: "helper-text-01",
text: helperText
}, "helperText"));
}
if (descriptionFirstHeader) {
items.reverse();
}
return items;
}
get inputContent() {
const {
type,
value,
textInputProps,
disabled,
helperText
} = this.props;
const changeText = textValue => {
this.triggerChange(textValue);
};
const handleFullBleed = (newActive, newError) => {
const {
active,
error
} = this.state;
if (active !== newActive || error !== newError) {
this.setState({
active: newActive,
error: newError
});
}
};
return /*#__PURE__*/_jsx(BaseTextInput, {
...(textInputProps || {}),
fullBleedCallback: handleFullBleed,
style: this.styles.textInput,
type: type,
disabled: disabled,
helperText: helperText,
value: String(value || ''),
onChangeText: changeText
});
}
get toggleContent() {
const {
label,
textBreakMode,
disabled,
value,
toggleValueText,
renderToggleCheckboxLeft,
type
} = this.props;
const inline = type === 'toggle-inline';
const changeValue = textValue => {
this.triggerChange(textValue);
};
const items = [/*#__PURE__*/_jsx(Text, {
text: typeof toggleValueText === 'function' ? toggleValueText(!!value) : String(value),
style: inline ? this.styles.toggleInlineText : this.styles.toggleText,
breakMode: textBreakMode
}, "label"), /*#__PURE__*/_jsx(Toggle, {
label: label || '',
style: this.styles.toggleWrapper,
toggleWrapperStyle: this.styles.toggleDirectWrapper,
hideLabel: true,
disabled: disabled,
toggled: !!value,
onChange: changeValue
}, "toggle")];
if (inline) {
items.unshift(/*#__PURE__*/_jsx(Text, {
style: this.styles.toggleInlineLabel,
text: label
}));
}
return renderToggleCheckboxLeft && !inline ? items.reverse() : items;
}
get staticContent() {
const {
value,
textBreakMode
} = this.props;
return /*#__PURE__*/_jsx(Text, {
style: this.styles.staticText,
text: String(value || ''),
breakMode: textBreakMode
});
}
get sliderContent() {
const {
label,
value,
disabled,
sliderProps
} = this.props;
const changeValue = sliderValue => {
this.triggerChange(String(sliderValue));
};
return /*#__PURE__*/_jsxs(_Fragment, {
children: [!!sliderProps?.leftIcon && /*#__PURE__*/_jsx(View, {
style: this.styles.sliderIcons,
children: createIcon(sliderProps.leftIcon, 20, 20, this.mainColor)
}), /*#__PURE__*/_jsx(Slider, {
style: this.styles.slider,
value: Number(value),
label: label || '',
minValue: sliderProps?.minValue || 0,
maxValue: sliderProps?.maxValue || 100,
hideRangeLabels: sliderProps?.hideRangeLabels,
onChange: changeValue,
disabled: disabled,
hideTextInput: true,
hideLabel: true
}), !!sliderProps?.rightIcon && /*#__PURE__*/_jsx(View, {
style: this.styles.sliderIcons,
children: createIcon(sliderProps.rightIcon, 20, 20, this.mainColor)
})]
});
}
get checkboxContent() {
const {
label,
textBreakMode,
disabled,
value,
helperText,
overrideActiveCheckboxIcon,
renderToggleCheckboxLeft
} = this.props;
const changeValue = () => {
this.triggerChange(!value);
};
const items = [/*#__PURE__*/_jsxs(View, {
style: this.styles.checkboxTextWrapper,
children: [/*#__PURE__*/_jsx(Text, {
text: label,
breakMode: textBreakMode
}), !!helperText && /*#__PURE__*/_jsx(Text, {
type: "helper-text-02",
style: styleReferenceBreaker(getTextInputStyle().helperText, this.styles.checkboxHelperText),
text: helperText
})]
}, "label"), createIcon(value ? overrideActiveCheckboxIcon || CheckmarkIcon : EmptyCheckmarkIcon, 20, 20, this.mainColor, 'icon')];
return /*#__PURE__*/_jsx(Pressable, {
style: this.styles.checkboxButton,
disabled: disabled,
accessibilityLabel: label,
accessibilityRole: "button",
onPress: changeValue,
children: renderToggleCheckboxLeft ? items.reverse() : items
});
}
get buttonContent() {
const {
label,
textBreakMode,
buttonIcon
} = this.props;
return /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(Text, {
text: label,
style: this.styles.buttonText,
breakMode: textBreakMode
}), createIcon(buttonIcon || ChevronRightIcon, 20, 20, this.mainColor)]
});
}
get contentArea() {
const {
type
} = this.props;
let content = null;
const finalStyle = styleReferenceBreaker(this.styles.contentArea);
switch (type) {
case 'header':
case 'header-compact':
content = this.headerContent;
break;
case 'toggle':
case 'toggle-inline':
content = this.toggleContent;
finalStyle.flexDirection = 'row';
break;
case 'static':
content = this.staticContent;
break;
case 'slider':
content = this.sliderContent;
finalStyle.flexDirection = 'row';
break;
case 'checkbox':
content = this.checkboxContent;
finalStyle.flexDirection = 'row';
break;
case 'button':
content = this.buttonContent;
finalStyle.flexDirection = 'row';
break;
case 'divider':
content = null;
break;
case 'text':
case 'password':
case 'text-area':
case 'number':
case 'date':
default:
content = this.inputContent;
break;
}
return /*#__PURE__*/_jsx(View, {
style: finalStyle,
children: content
});
}
get wrapperStyle() {
const {
type
} = this.props;
switch (type) {
case 'header':
return this.styles.headerWrapper;
case 'header-compact':
return this.styles.headerCompactWrapper;
case 'divider':
return this.styles.dividerWrapper;
default:
return this.styles.wrapper;
}
}
render() {
const {
componentProps,
style,
lastItem,
label,
helperText,
type,
onLongPress,
disabled
} = this.props;
const {
active,
error
} = this.state;
const finalStyle = styleReferenceBreaker(this.wrapperStyle);
if (lastItem) {
finalStyle.borderBottomWidth = 0;
}
if (error) {
finalStyle.borderBottomWidth = 2;
finalStyle.borderColor = getColor('supportError');
finalStyle.borderBottomColor = getColor('supportError');
} else if (active) {
finalStyle.borderBottomWidth = 2;
finalStyle.borderColor = getColor('focus');
finalStyle.borderBottomColor = getColor('focus');
}
const primaryContent = /*#__PURE__*/_jsxs(_Fragment, {
children: [!!(label && !this.noDirectLabel) && /*#__PURE__*/_jsx(Text, {
type: "label-02",
style: getTextInputStyle().label,
text: label
}), this.contentArea, !!(helperText && !this.noDirectHelperText) && /*#__PURE__*/_jsx(Text, {
type: "helper-text-02",
style: styleReferenceBreaker(getTextInputStyle().helperText, this.styles.helperText),
text: helperText
})]
});
if (type === 'button') {
return /*#__PURE__*/_jsx(Pressable, {
style: styleReferenceBreaker(finalStyle, style),
disabled: disabled,
accessibilityLabel: label,
accessibilityRole: "button",
onPress: this.onPress,
onLongPress: onLongPress,
...(componentProps || {}),
children: primaryContent
});
}
if (type === 'checkbox') {
return this.contentArea;
}
return /*#__PURE__*/_jsx(View, {
style: styleReferenceBreaker(finalStyle, style),
...(componentProps || {}),
children: primaryContent
});
}
}
//# sourceMappingURL=index.js.map