UNPKG

@crossed/ui

Version:

A universal & performant styling library for React Native, Next.js & React

134 lines (133 loc) 4.6 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { TextInput } from "react-native"; import { cloneElement, forwardRef, isValidElement, useCallback, useState } from "react"; import { form } from "../styles/form"; import { gapStyles } from "../styles/gap"; import { useInteraction, createStyles, composeStyles, inlineStyle, useTheme } from "@crossed/styled"; import { FormControl, FormField, FormLabel } from "./Form"; import { CloseButton } from "../buttons/CloseButton"; import { useUncontrolled } from "@crossed/core"; import { XBox } from "../layout/XBox"; import { Text } from "../typography/Text"; import { YBox } from "../layout/YBox"; const styles = createStyles(() => ({ close: { base: { padding: 0 } } })); const Input = forwardRef((allProps, ref) => { const { error, label, clearable, defaultValue, value: valueProps, onChangeText, disabled, elementRight, elementLeft, description, extra, formFieldStyle, ...props } = allProps; const [value, setValue] = useUncontrolled({ value: valueProps, defaultValue, onChange: onChangeText }); const [elementLeftWidth, setElementLeftWidth] = useState(0); const [elementRightWidth, setElementRightWidth] = useState(0); const { state, props: propsInteraction } = useInteraction(allProps); const { colors } = useTheme(); const color = colors.text.secondary; const onClear = useCallback(() => { setValue(""); }, [setValue]); const showClear = !!(clearable && value); return /* @__PURE__ */ jsx( FormField, { disabled: disabled || !props.focusable && props.focusable !== void 0, ...composeStyles( inlineStyle(() => ({ base: { flexGrow: 1 } })), formFieldStyle ).rnw(), children: /* @__PURE__ */ jsxs(YBox, { space: "xxs", children: [ !!(label || description || extra) && /* @__PURE__ */ jsxs(XBox, { alignItems: "center", space: "xxs", children: [ !!label && /* @__PURE__ */ jsx(FormLabel, { children: label }), !!description && /* @__PURE__ */ jsx(Text, { style: form.labelDescription, children: description }), !!extra && /* @__PURE__ */ jsx(Text, { style: form.labelExtra, textAlign: "right", children: extra }) ] }), /* @__PURE__ */ jsxs(XBox, { children: [ elementLeft && /* @__PURE__ */ jsx( XBox, { style: form.elementLeft, onLayout: ({ nativeEvent: { layout } }) => setElementLeftWidth(layout.width), children: isValidElement(elementLeft) && typeof elementLeft.type !== "string" && elementLeft.type.displayName === "CrossedText" ? cloneElement(elementLeft, { style: [elementLeft.style, { color }] }) : elementLeft } ), /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx( TextInput, { ref, placeholderTextColor: color, cursorColor: color, editable: !disabled, focusable: !disabled, ...props, ...propsInteraction, ...composeStyles( form.input, error && form.inputError, props.style ).rnw({ ...props, ...state, disabled, style: [ elementLeftWidth && { paddingLeft: elementLeftWidth }, elementRightWidth && { paddingRight: elementRightWidth } ] }), value, onChangeText: setValue } ) }), (!!elementRight || !!showClear) && /* @__PURE__ */ jsxs( XBox, { style: composeStyles(form.elementRight, gapStyles.xs), onLayout: ({ nativeEvent: { layout } }) => setElementRightWidth(layout.width), children: [ isValidElement(elementRight) && typeof elementRight.type !== "string" && elementRight.type.displayName === "CrossedText" ? cloneElement(elementRight, { style: [elementRight.style, { color }] }) : elementRight, !!showClear && /* @__PURE__ */ jsx(CloseButton, { onPress: onClear, style: styles.close }) ] } ) ] }), error && /* @__PURE__ */ jsx(Text, { color: "error", children: error.toString() }) ] }) } ); }); Input.displayName = "Input"; export { Input }; //# sourceMappingURL=Input.js.map