123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- import React, { useState } from "react";
- import classnames from "classnames";
- import { Input } from "antd";
- import styles from "./PriceOptions.less";
- import { exportStyleSizeClass } from '../Utils/utils';
-
- /**
- * rowModa: "single" 单行 | "multi" 两行
- * price:number 金额
- * onPriceChange: (value: price) => void
- * size: "small" | "normal" | "large" 样式暂无支持
- * focusScroll:boolean 点击时是否自动滚动到输入框处
- * withTitle:boolean 是否显示标题
- * titleText:string|dom 标题内容
- * inputPlaceholderText:string 输入框默认内容
- * priceOptions:Array 金额按钮数组,默认为 [100, 600, 800]
- * priceRender:Function 金额按钮内部数字渲染字样
- * inputPriceRender:Function 输入框金额字体渲染字样
- * inputSuffix:string|dom Antd组件Suffix属性
- * injectOptions: { priceBtnClass, priceInputClass } 分别控制具体渲染按钮和输入框样式
- * inputRef:React.RefObject<any> Input的Ref
- * @interface Props
- */
- interface Props {
- rowMode: "single" | "multi";
- price: number;
- onPriceChange: (v: number) => void;
- size: "small" | "normal" | "large";
- focusScroll: boolean;
- withTitle: boolean;
- allowZero: boolean;
- titleText?: string | JSX.Element[] | JSX.Element;
- inputPlaceholderText?: string;
- priceOptions?: Array<any>;
- priceRender?: Function;
- inputPriceRender?: Function;
- inputSuffix?: string | JSX.Element[] | JSX.Element;
- injectOptions?: {
- priceBtnClass: (isActive: boolean) => any;
- priceInputClass: Function;
- }
- inputRef: React.RefObject<any>;
- }
-
- const PriceOptions = ({
- price,
- onPriceChange,
- allowZero,
- rowMode = "single",
- size = "normal",
- focusScroll = true,
- withTitle = true,
- titleText = "Price",
- inputPlaceholderText = "Others",
- priceOptions = [100, 600, 800],
- priceRender = (i: any) => i / 100,
- inputPriceRender = (i: any) => (i ? i / 100 : ""),
- inputSuffix = "¥",
- injectOptions = {
- priceBtnClass: () => undefined,
- priceInputClass: () => undefined,
- },
- inputRef
- }: Props) => {
- const defaultOptions = priceOptions;
- // 控制是否为其他金额输入情况
- const [inputStatus, setInputStatus] = useState(false);
- const [inputPrice, setInputPrice] = useState('');
-
- return (
- <div className={classnames(styles.options, {
- [styles.multi]: rowMode === "multi",
- ...exportStyleSizeClass(styles, size),
- })}>
- {withTitle ? (titleText || null) : null}
- <div className={styles.infoItem}>
- <span className={styles.priceBtn}>
- {defaultOptions.map(item => {
- const isActive = price === item && !inputStatus;
- return (
- <span
- className={classnames({
- [styles.priceItem]: true,
- [styles.active]: !injectOptions.priceBtnClass(isActive) && isActive,
- ...injectOptions.priceBtnClass(isActive),
- })}
- key={item}
- onClick={() => {
- onPriceChange(item);
- setInputStatus(false);
- }}
- >
- {priceRender(item)}
- </span>
- );
- })}
- </span>
- <Input
- ref={inputRef}
- className={classnames(styles.priceInput, {...injectOptions.priceInputClass()})}
- onMouseEnter={() => {
- if (inputStatus && inputRef && inputRef.current) {
- inputRef.current.focus();
- inputRef.current.select();
- }
- }}
- suffix={inputSuffix}
- value={inputStatus ? inputPriceRender(inputPrice) : ""}
- placeholder={inputPlaceholderText}
- onChange={e => {
- const n = +e.target.value;
- if (Number.isNaN(n)) {
- return;
- }
- if (!allowZero && n === 0) {
- return;
- }
- // 测试暂时改成1分
- setInputPrice(`${n * 100}`);
- onPriceChange(n * 100);
- }}
- onClick={e => {
- if (!inputStatus) {
- setInputPrice('');
- setInputStatus(true);
- }
- }}
- onFocus={e => {
- e.target.placeholder = "";
- if (inputStatus) {
- setInputPrice(`${price}`);
- } else {
- setInputPrice('');
- setInputStatus(true);
- }
- if (focusScroll) {
- e.target.scrollIntoView();
- }
- }}
- onBlur={e => {
- e.target.placeholder = inputPlaceholderText;
- if (inputPrice) {
- setInputStatus(true);
- } else {
- setInputStatus(false);
- }
- }}
- />
- </div>
- </div>
- );
- };
-
- export default PriceOptions;
|