taro-react-uilib 1.4.35 → 1.4.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import{__read as e}from"../node_modules/tslib/tslib.es6.js";import t,{useState as n,useEffect as a,useCallback as o}from"react";import r from"classnames";import{View as l}from"@tarojs/components";import{pxTransform as u}from"../src/utils/index.js";import m from"../Badge/index.js";import c from"../Space/index.js";import p from"../node_modules/react-transition-group/esm/CSSTransition.js";var i=[{text:1,value:1,type:"number"},{text:2,value:2,type:"number"},{text:3,value:3,type:"number"},{text:"",value:"",type:"delete"},{text:4,value:4,type:"number"},{text:5,value:5,type:"number"},{text:6,value:6,type:"number"},{text:"",value:"",type:"none"},{text:7,value:7,type:"number"},{text:8,value:8,type:"number"},{text:9,value:9,type:"number"},{text:"",value:"",type:"none"},{text:"00",value:"00",type:"number"},{text:0,value:0,type:"number"},{text:"",value:"",type:"close"},{text:"",value:"",type:"none"}],s=[{text:1,value:1,type:"number"},{text:2,value:2,type:"number"},{text:3,value:3,type:"number"},{text:"",value:"",type:"delete"},{text:4,value:4,type:"number"},{text:5,value:5,type:"number"},{text:6,value:6,type:"number"},{text:"",value:"",type:"none"},{text:7,value:7,type:"number"},{text:8,value:8,type:"number"},{text:9,value:9,type:"number"},{text:"",value:"",type:"none"},{text:"·",value:".",type:"number"},{text:0,value:0,type:"number"},{text:"",value:"",type:"close"},{text:"",value:"",type:"none"}],d=function(d){var y=d.onBlur,x=d.show,v=d.maxLength,b=void 0===v?Number.MAX_SAFE_INTEGER:v,f=d.closeOnClickSpace,k=void 0===f||f,h=d.onClose,E=d.onChange,g=d.value,N=d.className,C=d.onConfirm,T=d.recommend,j=void 0===T?[]:T,I=d.header,O=d.disabled,S=void 0!==O&&O,_=d.tip,L=d.decimal,w=d.dataTrackId,A=e(n(g),2),P=A[0],B=A[1];function R(e){h&&h(e),y&&y(e)}a((function(){return k&&document.addEventListener("click",R),function(){document.removeEventListener("click",R)}}),[]),a((function(){B(g)}),[g]);var F=o((function(e,t){var n=t.type,a=t.value;if("h5"===process.env.TARO_ENV&&e.stopImmediatePropagation(),!S&&"none"!==n&&("."!==a||""!==P))if("close"!==n){var o=P;"delete"===n?o=P.slice(0,P.length-1):o.replace(/^0+/g,"").length<b&&(o=P+a),L&&0===a&&""===P&&(o=a+"."),"."===a&&P.includes(".")||"number"===n&&P.indexOf(".")>-1&&P.length-P.indexOf(".")==3||o!==P&&(B(o),null==E||E(o))}else R(e)}),[P,S]),G=L?s:i,M=r("xh-amount-keyboard",N);return t.createElement(p,{classNames:"slide-up",in:x,unmountOnExit:!0,timeout:200},t.createElement(l,{className:M},t.createElement(l,{className:"xh-amount-keyboard-header"},t.createElement(l,{className:"xh-amount-keyboard-header-wrapper"},I||j.length>0&&t.createElement(l,{className:"xh-amount-keyboard-header-wrapper-text"},"猜您想借"," ",t.createElement(c,{style:{marginLeft:u(24)}},null==j?void 0:j.map((function(e,n){return t.createElement(l,{dataTrackId:"".concat(w,"-recommend-").concat(n),key:n,onClick:function(t){return function(e,t){e.stopPropagation(),null==C||C("".concat(t),!0)}(t,e)}},t.createElement(m,{content:"¥".concat(e),key:n}))})))),_)),t.createElement(l,{className:"xh-amount-keyboard-body"},G.map((function(e,n){return t.createElement(l,{key:n,dataTrackId:"".concat(w,"-key-").concat(n),className:r("xh-amount-keyboard-body-key",{none:"none"===e.type,delete:"delete"===e.type,close:"close"===e.type}),onClick:function(t){F(t,e)}},e.text)})),t.createElement(l,{dataTrackId:"".concat(w,"-confirm-fake"),className:"xh-amount-keyboard-body-key confirm-fake",onClick:function(e){e.stopPropagation(),null==C||C(P)}},"确定"))))};export{d as default};
1
+ import{__read as e}from"../node_modules/tslib/tslib.es6.js";import t,{useState as n,useEffect as a,useCallback as o}from"react";import r from"classnames";import{View as l}from"@tarojs/components";import{pxTransform as u}from"../src/utils/index.js";import m from"../Badge/index.js";import c from"../Space/index.js";import i from"../node_modules/react-transition-group/esm/CSSTransition.js";var p=[{text:1,value:1,type:"number"},{text:2,value:2,type:"number"},{text:3,value:3,type:"number"},{text:"",value:"",type:"delete"},{text:4,value:4,type:"number"},{text:5,value:5,type:"number"},{text:6,value:6,type:"number"},{text:"",value:"",type:"none"},{text:7,value:7,type:"number"},{text:8,value:8,type:"number"},{text:9,value:9,type:"number"},{text:"",value:"",type:"none"},{text:"00",value:"00",type:"number"},{text:0,value:0,type:"number"},{text:"",value:"",type:"close"},{text:"",value:"",type:"none"}],s=[{text:1,value:1,type:"number"},{text:2,value:2,type:"number"},{text:3,value:3,type:"number"},{text:"",value:"",type:"delete"},{text:4,value:4,type:"number"},{text:5,value:5,type:"number"},{text:6,value:6,type:"number"},{text:"",value:"",type:"none"},{text:7,value:7,type:"number"},{text:8,value:8,type:"number"},{text:9,value:9,type:"number"},{text:"",value:"",type:"none"},{text:"·",value:".",type:"number"},{text:0,value:0,type:"number"},{text:"",value:"",type:"close"},{text:"",value:"",type:"none"}],d=function(d){var y=d.onBlur,v=d.show,x=d.maxLength,b=void 0===x?Number.MAX_SAFE_INTEGER:x,f=d.closeOnClickSpace,k=void 0===f||f,h=d.onClose,E=d.onChange,g=d.value,N=d.className,C=d.onConfirm,T=d.recommend,j=void 0===T?[]:T,I=d.header,_=d.disabled,O=void 0!==_&&_,S=d.tip,A=d.decimal,L=d.dataTrackId,w=void 0===L?"Amount_Keyboard":L,P=e(n(g),2),B=P[0],R=P[1];function F(e){h&&h(e),y&&y(e)}a((function(){return k&&document.addEventListener("click",F),function(){document.removeEventListener("click",F)}}),[]),a((function(){R(g)}),[g]);var G=o((function(e,t){var n=t.type,a=t.value;if("h5"===process.env.TARO_ENV&&e.stopImmediatePropagation(),!O&&"none"!==n&&("."!==a||""!==B))if("close"!==n){var o=B;"delete"===n?o=B.slice(0,B.length-1):o.replace(/^0+/g,"").length<b&&(o=B+a),A&&0===a&&""===B&&(o=a+"."),"."===a&&B.includes(".")||"number"===n&&B.indexOf(".")>-1&&B.length-B.indexOf(".")==3||o!==B&&(R(o),null==E||E(o))}else F(e)}),[B,O]),K=A?s:p,M=r("xh-amount-keyboard",N);return t.createElement(i,{classNames:"slide-up",in:v,unmountOnExit:!0,timeout:200},t.createElement(l,{className:M},t.createElement(l,{className:"xh-amount-keyboard-header"},t.createElement(l,{className:"xh-amount-keyboard-header-wrapper"},I||j.length>0&&t.createElement(l,{className:"xh-amount-keyboard-header-wrapper-text"},"猜您想借"," ",t.createElement(c,{style:{marginLeft:u(24)}},null==j?void 0:j.map((function(e,n){return t.createElement(l,{dataTrackId:"".concat(w,"-recommend-").concat(n),key:n,onClick:function(t){return function(e,t){e.stopPropagation(),null==C||C("".concat(t),!0)}(t,e)}},t.createElement(m,{content:"¥".concat(e),key:n}))})))),S)),t.createElement(l,{className:"xh-amount-keyboard-body"},K.map((function(e,n){return t.createElement(l,{key:n,dataTrackId:"".concat(w,"-key-").concat(n),className:r("xh-amount-keyboard-body-key",{none:"none"===e.type,delete:"delete"===e.type,close:"close"===e.type}),onClick:function(t){G(t,e)}},e.text)})),t.createElement(l,{dataTrackId:"".concat(w,"-confirm-fake"),className:"xh-amount-keyboard-body-key confirm-fake",onClick:function(e){e.stopPropagation(),null==C||C(B)}},"确定"))))};export{d as default};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/AmountKeyboard/index.tsx"],"sourcesContent":["import React, {\n FC,\n useState,\n useEffect,\n MouseEvent,\n ReactNode,\n useCallback,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { ITouchEvent, View } from \"@tarojs/components\";\nimport { pxTransform } from \"@/utils\";\n\nimport Badge from \"../Badge\";\nimport \"./index.scss\";\nimport { XHComponentCommonProps } from \"../../types\";\nimport Space from \"../Space\";\n\nexport type NumberKeyboardProps = {\n show: boolean;\n /**\n * 是否支持小数,小数保留小数点后两位,默认不支持\n */\n decimal?: boolean;\n showClose?: boolean;\n closeOnClickSpace?: boolean;\n maxLength?: number;\n onBlur?: (e: MouseEvent | Event) => void;\n onClose?: (e: MouseEvent | Event) => void;\n onChange?: (value: string) => void;\n value: string;\n header?: ReactNode;\n /**\n *\n * @param value 输入值\n * @param recommend 是否是点击推荐金额触发\n * @returns void\n */\n onConfirm?: (value: string, recommend?: boolean) => void;\n recommend?: Array<number | string>;\n tip?: ReactNode;\n disabled?: boolean;\n dataTrackId?: string;\n} & XHComponentCommonProps;\n\nexport type KeyType = \"number\" | \"delete\" | \"string\" | \"none\" | \"close\";\n\nexport interface IKey {\n text: number | string;\n value: number | string;\n type: KeyType;\n}\n\nconst XHAmountKeys: IKey[] = [\n { text: 1, value: 1, type: \"number\" },\n { text: 2, value: 2, type: \"number\" },\n { text: 3, value: 3, type: \"number\" },\n { text: \"\", value: \"\", type: \"delete\" },\n { text: 4, value: 4, type: \"number\" },\n { text: 5, value: 5, type: \"number\" },\n { text: 6, value: 6, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: 7, value: 7, type: \"number\" },\n { text: 8, value: 8, type: \"number\" },\n { text: 9, value: 9, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: \"00\", value: \"00\", type: \"number\" },\n { text: 0, value: 0, type: \"number\" },\n { text: \"\", value: \"\", type: \"close\" },\n { text: \"\", value: \"\", type: \"none\" },\n];\n\nconst XHAmountKeysWithDot: IKey[] = [\n { text: 1, value: 1, type: \"number\" },\n { text: 2, value: 2, type: \"number\" },\n { text: 3, value: 3, type: \"number\" },\n { text: \"\", value: \"\", type: \"delete\" },\n { text: 4, value: 4, type: \"number\" },\n { text: 5, value: 5, type: \"number\" },\n { text: 6, value: 6, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: 7, value: 7, type: \"number\" },\n { text: 8, value: 8, type: \"number\" },\n { text: 9, value: 9, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: \"·\", value: \".\", type: \"number\" },\n { text: 0, value: 0, type: \"number\" },\n { text: \"\", value: \"\", type: \"close\" },\n { text: \"\", value: \"\", type: \"none\" },\n];\n\nconst AmountKeyboard: FC<NumberKeyboardProps> = props => {\n const {\n onBlur,\n show,\n maxLength = Number.MAX_SAFE_INTEGER,\n closeOnClickSpace = true,\n onClose,\n onChange,\n value,\n className,\n onConfirm,\n recommend = [],\n header,\n disabled = false,\n tip,\n decimal,\n dataTrackId,\n } = props;\n const [input, setInput] = useState(value);\n\n useEffect(() => {\n if (closeOnClickSpace) {\n document.addEventListener(\"click\", handleClose);\n }\n\n return () => {\n document.removeEventListener(\"click\", handleClose);\n };\n }, []);\n\n useEffect(() => {\n setInput(value);\n }, [value]);\n\n function handleClose(e): void {\n onClose && onClose(e);\n onBlur && onBlur(e);\n }\n\n const handleOnRecommand = (e: ITouchEvent, amount: number | string) => {\n e.stopPropagation();\n onConfirm?.(`${amount}`, true);\n };\n\n const handleKeyPress = useCallback(\n (e, { type, value }: IKey): void => {\n if (process.env.TARO_ENV === \"h5\") {\n e.stopImmediatePropagation();\n }\n if (disabled) return;\n if (type === \"none\") return;\n // 第一个字符不能是.\n if (value === \".\" && input === \"\") return;\n if (type === \"close\") {\n handleClose(e);\n return;\n }\n let newInput = input;\n if (type === \"delete\") {\n newInput = input.slice(0, input.length - 1);\n } else if (newInput.replace(/^0+/g, \"\").length < maxLength) {\n newInput = input + value;\n }\n // 支持小数点的情况下,如果第一个是0,自动填充.\n if (decimal && value === 0 && input === \"\") newInput = value + \".\";\n\n // 不能包含多个小数点\n if (value === \".\" && input.includes(\".\")) return;\n // 保留两位小数\n if (\n type === \"number\" &&\n input.indexOf(\".\") > -1 &&\n input.length - input.indexOf(\".\") === 3\n )\n return;\n\n // 前后两个值相等就不触发onchange\n if (newInput === input) return;\n setInput(newInput);\n onChange?.(newInput);\n },\n [input, disabled]\n );\n\n const renderKeys = decimal ? XHAmountKeysWithDot : XHAmountKeys;\n\n const handleConfirm = (e: ITouchEvent) => {\n e.stopPropagation();\n onConfirm?.(input);\n };\n const keyboardcls = classNames(\"xh-amount-keyboard\", className);\n\n return (\n <CSSTransition classNames=\"slide-up\" in={show} unmountOnExit timeout={200}>\n <View className={keyboardcls}>\n <View className=\"xh-amount-keyboard-header\">\n <View className=\"xh-amount-keyboard-header-wrapper\">\n {header ||\n (recommend.length > 0 && (\n <View className=\"xh-amount-keyboard-header-wrapper-text\">\n 猜您想借{\" \"}\n <Space style={{ marginLeft: pxTransform(24) }}>\n {recommend?.map((amount, index) => (\n <View\n // @ts-ignore\n dataTrackId={`${dataTrackId}-recommend-${index}`}\n key={index}\n onClick={e => handleOnRecommand(e, amount)}\n >\n <Badge content={`¥${amount}`} key={index} />\n </View>\n ))}\n </Space>\n </View>\n ))}\n {tip}\n </View>\n </View>\n <View className=\"xh-amount-keyboard-body\">\n {renderKeys.map((key, index) => (\n <View\n key={index}\n // @ts-ignore\n dataTrackId={`${dataTrackId}-key-${index}`}\n className={classNames(\"xh-amount-keyboard-body-key\", {\n none: key.type === \"none\",\n delete: key.type === \"delete\",\n close: key.type === \"close\",\n })}\n onClick={e => {\n handleKeyPress(e, key);\n }}\n >\n {key.text}\n </View>\n ))}\n <View\n // @ts-ignore\n dataTrackId={`${dataTrackId}-confirm-fake`}\n className=\"xh-amount-keyboard-body-key confirm-fake\"\n onClick={handleConfirm}\n >\n 确定\n </View>\n </View>\n </View>\n </CSSTransition>\n );\n};\n\nexport default AmountKeyboard;\n"],"names":["XHAmountKeys","text","value","type","XHAmountKeysWithDot","AmountKeyboard","props","onBlur","show","_a","maxLength","Number","MAX_SAFE_INTEGER","_b","closeOnClickSpace","onClose","onChange","className","onConfirm","_c","recommend","header","_d","disabled","tip","decimal","dataTrackId","_e","__read","useState","input","setInput","handleClose","e","useEffect","document","addEventListener","removeEventListener","handleKeyPress","useCallback","process","env","TARO_ENV","stopImmediatePropagation","newInput","slice","length","replace","includes","indexOf","renderKeys","keyboardcls","classNames","React","createElement","CSSTransition","in","unmountOnExit","timeout","View","Space","style","marginLeft","pxTransform","map","amount","index","concat","key","onClick","stopPropagation","handleOnRecommand","Badge","content","none","delete","close"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/AmountKeyboard/index.tsx"],"sourcesContent":["import React, {\n FC,\n useState,\n useEffect,\n MouseEvent,\n ReactNode,\n useCallback,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { ITouchEvent, View } from \"@tarojs/components\";\nimport { pxTransform } from \"@/utils\";\n\nimport Badge from \"../Badge\";\nimport \"./index.scss\";\nimport { XHComponentCommonProps } from \"../../types\";\nimport Space from \"../Space\";\n\nexport type NumberKeyboardProps = {\n show: boolean;\n /**\n * 是否支持小数,小数保留小数点后两位,默认不支持\n */\n decimal?: boolean;\n showClose?: boolean;\n closeOnClickSpace?: boolean;\n maxLength?: number;\n onBlur?: (e: MouseEvent | Event) => void;\n onClose?: (e: MouseEvent | Event) => void;\n onChange?: (value: string) => void;\n value: string;\n header?: ReactNode;\n /**\n *\n * @param value 输入值\n * @param recommend 是否是点击推荐金额触发\n * @returns void\n */\n onConfirm?: (value: string, recommend?: boolean) => void;\n recommend?: Array<number | string>;\n tip?: ReactNode;\n disabled?: boolean;\n dataTrackId?: string;\n} & XHComponentCommonProps;\n\nexport type KeyType = \"number\" | \"delete\" | \"string\" | \"none\" | \"close\";\n\nexport interface IKey {\n text: number | string;\n value: number | string;\n type: KeyType;\n}\n\nconst XHAmountKeys: IKey[] = [\n { text: 1, value: 1, type: \"number\" },\n { text: 2, value: 2, type: \"number\" },\n { text: 3, value: 3, type: \"number\" },\n { text: \"\", value: \"\", type: \"delete\" },\n { text: 4, value: 4, type: \"number\" },\n { text: 5, value: 5, type: \"number\" },\n { text: 6, value: 6, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: 7, value: 7, type: \"number\" },\n { text: 8, value: 8, type: \"number\" },\n { text: 9, value: 9, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: \"00\", value: \"00\", type: \"number\" },\n { text: 0, value: 0, type: \"number\" },\n { text: \"\", value: \"\", type: \"close\" },\n { text: \"\", value: \"\", type: \"none\" },\n];\n\nconst XHAmountKeysWithDot: IKey[] = [\n { text: 1, value: 1, type: \"number\" },\n { text: 2, value: 2, type: \"number\" },\n { text: 3, value: 3, type: \"number\" },\n { text: \"\", value: \"\", type: \"delete\" },\n { text: 4, value: 4, type: \"number\" },\n { text: 5, value: 5, type: \"number\" },\n { text: 6, value: 6, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: 7, value: 7, type: \"number\" },\n { text: 8, value: 8, type: \"number\" },\n { text: 9, value: 9, type: \"number\" },\n { text: \"\", value: \"\", type: \"none\" },\n { text: \"·\", value: \".\", type: \"number\" },\n { text: 0, value: 0, type: \"number\" },\n { text: \"\", value: \"\", type: \"close\" },\n { text: \"\", value: \"\", type: \"none\" },\n];\n\nconst AmountKeyboard: FC<NumberKeyboardProps> = props => {\n const {\n onBlur,\n show,\n maxLength = Number.MAX_SAFE_INTEGER,\n closeOnClickSpace = true,\n onClose,\n onChange,\n value,\n className,\n onConfirm,\n recommend = [],\n header,\n disabled = false,\n tip,\n decimal,\n dataTrackId = \"Amount_Keyboard\",\n } = props;\n const [input, setInput] = useState(value);\n\n useEffect(() => {\n if (closeOnClickSpace) {\n document.addEventListener(\"click\", handleClose);\n }\n\n return () => {\n document.removeEventListener(\"click\", handleClose);\n };\n }, []);\n\n useEffect(() => {\n setInput(value);\n }, [value]);\n\n function handleClose(e): void {\n onClose && onClose(e);\n onBlur && onBlur(e);\n }\n\n const handleOnRecommand = (e: ITouchEvent, amount: number | string) => {\n e.stopPropagation();\n onConfirm?.(`${amount}`, true);\n };\n\n const handleKeyPress = useCallback(\n (e, { type, value }: IKey): void => {\n if (process.env.TARO_ENV === \"h5\") {\n e.stopImmediatePropagation();\n }\n if (disabled) return;\n if (type === \"none\") return;\n // 第一个字符不能是.\n if (value === \".\" && input === \"\") return;\n if (type === \"close\") {\n handleClose(e);\n return;\n }\n let newInput = input;\n if (type === \"delete\") {\n newInput = input.slice(0, input.length - 1);\n } else if (newInput.replace(/^0+/g, \"\").length < maxLength) {\n newInput = input + value;\n }\n // 支持小数点的情况下,如果第一个是0,自动填充.\n if (decimal && value === 0 && input === \"\") newInput = value + \".\";\n\n // 不能包含多个小数点\n if (value === \".\" && input.includes(\".\")) return;\n // 保留两位小数\n if (\n type === \"number\" &&\n input.indexOf(\".\") > -1 &&\n input.length - input.indexOf(\".\") === 3\n )\n return;\n\n // 前后两个值相等就不触发onchange\n if (newInput === input) return;\n setInput(newInput);\n onChange?.(newInput);\n },\n [input, disabled]\n );\n\n const renderKeys = decimal ? XHAmountKeysWithDot : XHAmountKeys;\n\n const handleConfirm = (e: ITouchEvent) => {\n e.stopPropagation();\n onConfirm?.(input);\n };\n const keyboardcls = classNames(\"xh-amount-keyboard\", className);\n\n return (\n <CSSTransition classNames=\"slide-up\" in={show} unmountOnExit timeout={200}>\n <View className={keyboardcls}>\n <View className=\"xh-amount-keyboard-header\">\n <View className=\"xh-amount-keyboard-header-wrapper\">\n {header ||\n (recommend.length > 0 && (\n <View className=\"xh-amount-keyboard-header-wrapper-text\">\n 猜您想借{\" \"}\n <Space style={{ marginLeft: pxTransform(24) }}>\n {recommend?.map((amount, index) => (\n <View\n // @ts-ignore\n dataTrackId={`${dataTrackId}-recommend-${index}`}\n key={index}\n onClick={e => handleOnRecommand(e, amount)}\n >\n <Badge content={`¥${amount}`} key={index} />\n </View>\n ))}\n </Space>\n </View>\n ))}\n {tip}\n </View>\n </View>\n <View className=\"xh-amount-keyboard-body\">\n {renderKeys.map((key, index) => (\n <View\n key={index}\n // @ts-ignore\n dataTrackId={`${dataTrackId}-key-${index}`}\n className={classNames(\"xh-amount-keyboard-body-key\", {\n none: key.type === \"none\",\n delete: key.type === \"delete\",\n close: key.type === \"close\",\n })}\n onClick={e => {\n handleKeyPress(e, key);\n }}\n >\n {key.text}\n </View>\n ))}\n <View\n // @ts-ignore\n dataTrackId={`${dataTrackId}-confirm-fake`}\n className=\"xh-amount-keyboard-body-key confirm-fake\"\n onClick={handleConfirm}\n >\n 确定\n </View>\n </View>\n </View>\n </CSSTransition>\n );\n};\n\nexport default AmountKeyboard;\n"],"names":["XHAmountKeys","text","value","type","XHAmountKeysWithDot","AmountKeyboard","props","onBlur","show","_a","maxLength","Number","MAX_SAFE_INTEGER","_b","closeOnClickSpace","onClose","onChange","className","onConfirm","_c","recommend","header","_d","disabled","tip","decimal","_e","dataTrackId","_f","__read","useState","input","setInput","handleClose","e","useEffect","document","addEventListener","removeEventListener","handleKeyPress","useCallback","process","env","TARO_ENV","stopImmediatePropagation","newInput","slice","length","replace","includes","indexOf","renderKeys","keyboardcls","classNames","React","createElement","CSSTransition","in","unmountOnExit","timeout","View","Space","style","marginLeft","pxTransform","map","amount","index","concat","key","onClick","stopPropagation","handleOnRecommand","Badge","content","none","delete","close"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{__read as t}from"../../node_modules/tslib/tslib.es6.js";import e,{useState as n,useRef as a,useCallback as r,useEffect as i}from"react";import{createSelectorQuery as o}from"@tarojs/taro";import{View as l,ScrollView as c}from"@tarojs/components";import s from"classnames";import m from"./TabItem.js";var u=function(m){var u=m.children,f=void 0===u?[]:u,h=m.lineColor,b=void 0===h?"#FE5E00":h,d=m.titleActiveColor,v=void 0===d?"#333":d,g=m.titleInctiveColor,x=void 0===g?"#999":g,p=m.onChange,C=m.content,R=m.selectIndex,E=void 0===R?0:R,N=m.isOverflowNav,A=void 0!==N&&N,w=t(n(0),2),T=w[0],k=w[1],y=t(n(0),2),I=y[0],B=y[1],j=t(n(0),2),M=j[0],O=j[1],W=t(n(0),2),X=W[0],_=W[1],V=a([]),F=a([]),L=a([]),q=a(null),z=a(null),D=a(null),G=function(t,e,n,a){if(!e||!A)return 0;var r=t.left-n-(e.width-t.width)/2,i=Math.max(0,a-e.width);return Math.max(0,Math.min(r,i))},H=r((function(e){var n=f.filter(Boolean);if(!(e<0||e>=n.length))if("h5"!==process.env.TARO_ENV)D.current=setTimeout((function(){var n=o();n.selectAll(".xh-tabbar-nav-item").boundingClientRect(),n.select(".xh-tabbar-nav").boundingClientRect(),n.selectAll(".xh-tabbar-content-item").boundingClientRect(),n.selectAll(".xh-tabbar-content-slot").boundingClientRect(),n.select(".xh-tabbar-nav-scroll").boundingClientRect(),n.exec((function(n){var a=t(n,5),r=a[0],i=a[1],o=a[2],l=a[3],c=a[4],s=(null==i?void 0:i.node)||i;if(r[e]&&s&&c){var m=r[e],u=i,f=m.left+m.width/2-u.left;if(O(f),A){var h=G(m,c,i.left,i.width);_(h)}}o[e]&&k(o[e].height),l[0]&&B(l[0].height)}))}),50);else{var a=V.current[e],r=L.current[0],i=F.current[e],l=null==a?void 0:a.parentElement,c=q.current;if(a&&l&&c){var s=a.getBoundingClientRect(),m=l.getBoundingClientRect(),u=c.getBoundingClientRect(),h=s.left+s.width/2-m.left;if(O(h),A){var b=G(s,u,m.left,l.offsetWidth);_(b)}}if(r){var d=r.getBoundingClientRect();B(d.height)}if(i){var v=i.getBoundingClientRect();k(v.height)}}}),[f,A]);i((function(){return H(E),function(){D.current&&clearTimeout(D.current)}}),[E,H]);return e.createElement(l,{className:"xh-tabbar"},e.createElement(c,{scrollX:!0,scrollLeft:X,className:"xh-tabbar-nav-scroll",ref:q,scrollWithAnimation:A,scrollAnchoring:A},e.createElement(l,{className:"xh-tabbar-nav",ref:z,style:{width:A?"fit-content":"100%"}},f.map((function(t,n){return e.createElement(l,{key:n,"data-index":n,dataTrackId:t.props.dataTrackId||"xh-tabbar-nav-item-".concat(n),ref:function(t){return V.current[n]=t},className:s("xh-tabbar-nav-item",{"more-item":A}),style:{color:E===n?v:x,flex:A?"none":"1"},onClick:function(){return function(t){if(t!==E&&(H(t),p&&p(t),"h5"===process.env.TARO_ENV)){var e=o();e.selectAll(".xh-tabbar-content-item").boundingClientRect(),e.selectAll(".xh-tabbar-content-slot").boundingClientRect(),e.exec((function(e){if(e[0][t]){var n=e[0][t].height;k(n),e[1][t]&&B(e[1][t].height)}}))}}(n)}},t.props.TabItemComponent||t.props.title)})),e.createElement("div",{className:"xh-tabbar-nav-line",style:{background:"".concat(b),transform:"translateX(".concat(M,"px) translate(-50%, -50%)"),WebkitTransform:"translateX(".concat(M,"px) translate(-50%, -50%)"),transition:"transform 0.3s ease"}}))),e.createElement(l,{className:"xh-tabbar-content",style:{width:"".concat(100*f.length,"%"),height:T+I?"".concat(T+I,"px"):"auto"}},C&&e.createElement(l,{className:"xh-tabbar-content-slot",ref:L},C),f.map((function(t,n){return e.createElement(l,{key:n,ref:function(t){return F.current[n]=t},className:s("xh-tabbar-content-item",{"xh-tabbar-content-item-dispaly":E!==n,"xh-tabbar-content-item-active":E===n})},t.props.children)}))))};u.Item=m;export{u as default};
1
+ import{__read as t}from"../../node_modules/tslib/tslib.es6.js";import e,{useState as n,useRef as a,useCallback as r,useEffect as i}from"react";import{createSelectorQuery as o}from"@tarojs/taro";import{View as l,ScrollView as c}from"@tarojs/components";import s from"classnames";import m from"./TabItem.js";var f=function(m){var f=m.children,u=void 0===f?[]:f,h=m.lineColor,b=void 0===h?"#FE5E00":h,d=m.titleActiveColor,v=void 0===d?"#333":d,x=m.titleInctiveColor,g=void 0===x?"#999":x,p=m.onChange,C=m.content,R=m.selectIndex,E=void 0===R?0:R,N=m.isOverflowNav,T=void 0!==N&&N,w=t(n(0),2),A=w[0],k=w[1],y=t(n(0),2),I=y[0],B=y[1],j=t(n(0),2),M=j[0],O=j[1],X=t(n(0),2),_=X[0],V=X[1],W=a([]),F=a([]),L=a([]),q=a(null),z=a(null),D=a(null),G=function(t,e,n,a){if(!e||!T)return 0;var r=t.left-n-(e.width-t.width)/2,i=Math.max(0,a-e.width);return Math.max(0,Math.min(r,i))},H=r((function(e){var n=u.filter(Boolean);if(!(e<0||e>=n.length))if("h5"!==process.env.TARO_ENV)D.current=setTimeout((function(){var n=o();n.selectAll(".xh-tabbar-nav-item").boundingClientRect(),n.select(".xh-tabbar-nav").boundingClientRect(),n.selectAll(".xh-tabbar-content-item").boundingClientRect(),n.selectAll(".xh-tabbar-content-slot").boundingClientRect(),n.select(".xh-tabbar-nav-scroll").boundingClientRect(),n.exec((function(n){var a=t(n,5),r=a[0],i=a[1],o=a[2],l=a[3],c=a[4],s=(null==i?void 0:i.node)||i;if(r[e]&&s&&c){var m=r[e],f=i,u=m.left+m.width/2-f.left;if(O(u),T){var h=G(m,c,i.left,i.width);V(h)}}o[e]&&k(o[e].height),l[0]&&B(l[0].height)}))}),50);else{var a=W.current[e],r=L.current[0],i=F.current[e],l=null==a?void 0:a.parentElement,c=q.current;if(a&&l&&c){var s=a.getBoundingClientRect(),m=l.getBoundingClientRect(),f=c.getBoundingClientRect(),h=s.left+s.width/2-m.left;if(O(h),T){var b=G(s,f,m.left,l.offsetWidth);c.scrollTo({left:b})}}if(r){var d=r.getBoundingClientRect();B(d.height)}if(i){var v=i.getBoundingClientRect();k(v.height)}}}),[u,T]);i((function(){return H(E),function(){D.current&&clearTimeout(D.current)}}),[E,H]);return e.createElement(l,{className:"xh-tabbar"},e.createElement(c,{scrollX:!0,scrollLeft:_,className:"xh-tabbar-nav-scroll",ref:q},e.createElement(l,{className:"xh-tabbar-nav",ref:z,style:{width:T?"fit-content":"100%"}},u.map((function(t,n){return e.createElement(l,{key:n,"data-index":n,dataTrackId:t.props.dataTrackId||"xh-tabbar-nav-item-".concat(n),ref:function(t){return W.current[n]=t},className:s("xh-tabbar-nav-item",{"more-item":T}),style:{color:E===n?v:g,flex:T?"none":"1"},onClick:function(){return function(t){if(t!==E&&(H(t),p&&p(t),"h5"===process.env.TARO_ENV)){var e=o();e.selectAll(".xh-tabbar-content-item").boundingClientRect(),e.selectAll(".xh-tabbar-content-slot").boundingClientRect(),e.exec((function(e){if(e[0][t]){var n=e[0][t].height;k(n),e[1][t]&&B(e[1][t].height)}}))}}(n)}},t.props.TabItemComponent||t.props.title)})),e.createElement("div",{className:"xh-tabbar-nav-line",style:{background:"".concat(b),transform:"translateX(".concat(M,"px) translate(-50%, -50%)"),WebkitTransform:"translateX(".concat(M,"px) translate(-50%, -50%)"),transition:"transform 0.3s ease"}}))),e.createElement(l,{className:"xh-tabbar-content",style:{width:"".concat(100*u.length,"%"),height:A+I?"".concat(A+I,"px"):"auto"}},C&&e.createElement(l,{className:"xh-tabbar-content-slot",ref:L},C),u.map((function(t,n){return e.createElement(l,{key:n,ref:function(t){return F.current[n]=t},className:s("xh-tabbar-content-item",{"xh-tabbar-content-item-dispaly":E!==n,"xh-tabbar-content-item-active":E===n})},t.props.children)}))))};f.Item=m;export{f as default};
2
2
  //# sourceMappingURL=Tabbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabbar.js","sources":["../../../../src/components/Tabbar/tabbar/Tabbar.tsx"],"sourcesContent":["import React, {\n FC,\n ReactElement,\n useEffect,\n useState,\n ReactNode,\n useRef,\n useCallback,\n} from \"react\";\nimport { createSelectorQuery } from \"@tarojs/taro\";\nimport { View, ScrollView } from \"@tarojs/components\";\nimport classNames from \"classnames\";\nimport Item from \"./TabItem\";\n\n/**\n * Tab切换\n *\n * @param children //子组件\n * @param animated //是否开启转场动画\n * @param selectIndex //默认选中第几个\n * @param lineColor //下划线颜色\n * @param titleActiveColor //标题选中态颜色\n * @param titleInctiveColor //标题默认态颜色\n * @param onChange //切换回调事件\n * @param content //item公共节点\n * @param isOverflowNav //是否超宽导航(超过屏幕宽度,自动滚动)\n *\n */\n\nexport interface TabProps {\n children: ReactElement[];\n animated?: boolean;\n lineColor?: string;\n titleActiveColor?: string;\n titleInctiveColor?: string;\n onChange?: (index: number) => void;\n content?: string | ReactNode;\n selectIndex: number;\n isOverflowNav?: boolean;\n}\n\nexport interface TabsComponent<P = {}> extends FC<P> {\n Item: typeof Item;\n}\n\nconst XHTabs: TabsComponent<TabProps> = props => {\n const {\n children = [],\n // animated = false,\n lineColor = \"#FE5E00\",\n titleActiveColor = \"#333\",\n titleInctiveColor = \"#999\",\n onChange,\n content,\n selectIndex = 0,\n isOverflowNav = false,\n } = props;\n\n const [tabContentHeight, setTabContentHeight] = useState(0);\n const [tabSlotHeight, setTabSlotHeight] = useState(0);\n const [lineLeft, setLineLeft] = useState(0); // 下划线左偏移,核心:通过状态控制下划线位置,确保同步更新和动画过渡\n const [navLeft, setNavLeft] = useState(0); // 导航滚动位置,核心:通过状态控制滚动位置,适配超宽导航\n // Ref定义\n const itemNavRef = useRef<(HTMLDivElement | null)[]>([]);\n const itemContentRef = useRef<(HTMLDivElement | null)[]>([]);\n const itemSlotRef = useRef<(HTMLDivElement | null)[]>([]);\n const navScrollRef = useRef<HTMLDivElement | null>(null); // 滚动容器ref\n const navContainerRef = useRef<HTMLDivElement | null>(null);\n const timerRef = useRef<NodeJS.Timeout | null>(null); // 定时器ref,避免闭包丢失\n\n // 统一滚动计算逻辑:H5/小程序通用\n const computeScroll = (\n itemRect: any,\n scrollRect: any,\n containerLeft: number,\n containerWidth: number\n ) => {\n if (!scrollRect || !isOverflowNav) return 0;\n // 元素在导航容器内的绝对偏移(视口坐标转容器坐标)\n const itemOffsetInNav = itemRect.left - containerLeft;\n // 居中滚动值:让选中项尽量居中显示\n let targetScroll =\n itemOffsetInNav - (scrollRect.width - itemRect.width) / 2;\n // 最大可滚动距离:总导航宽度 - 可视区域宽度\n const maxScroll = Math.max(0, containerWidth - scrollRect.width);\n // 边界处理:不小于0,不大于最大可滚动距离\n return Math.max(0, Math.min(targetScroll, maxScroll));\n };\n\n // 抽离位置/尺寸计算逻辑,复用(初始化+切换都调用)\n const calculateTabInfo = useCallback(\n (targetIndex: number) => {\n // 过滤空children,避免索引越界\n const validChildren = children.filter(Boolean);\n if (targetIndex < 0 || targetIndex >= validChildren.length) return;\n\n // H5端:直接通过ref获取元素信息,核心:同步更新,无需等待DOM渲染\n if (process.env.TARO_ENV === \"h5\") {\n const navItem = itemNavRef.current[targetIndex];\n const slotItem = itemSlotRef.current[0];\n const contentItem = itemContentRef.current[targetIndex];\n const navContainer = navItem?.parentElement as HTMLDivElement;\n const scrollContainer = navScrollRef.current;\n\n // 计算下划线位置\n if (navItem && navContainer && scrollContainer) {\n const itemRect = navItem.getBoundingClientRect();\n const containerRect = navContainer.getBoundingClientRect();\n const scrollRect = scrollContainer.getBoundingClientRect();\n const centerX =\n itemRect.left + itemRect.width / 2 - containerRect.left;\n setLineLeft(centerX);\n\n if (isOverflowNav) {\n const targetScroll = computeScroll(\n itemRect,\n scrollRect,\n containerRect.left,\n navContainer.offsetWidth\n );\n setNavLeft(targetScroll);\n // console.log(\"scrollContainer\", scrollContainer.scrollTo);\n\n // scrollContainer.scrollTo({\n // left: targetScroll,\n // // behavior: \"instant\",\n // });\n }\n }\n\n if (slotItem) {\n const slotRect = slotItem.getBoundingClientRect();\n setTabSlotHeight(slotRect.height);\n }\n if (contentItem) {\n const contentRect = contentItem.getBoundingClientRect();\n setTabContentHeight(contentRect.height);\n }\n return;\n }\n\n // 小程序端:必须用createSelectorQuery,保留极短延迟(50ms),适配小程序DOM渲染时机\n timerRef.current = setTimeout(() => {\n const query = createSelectorQuery();\n query.selectAll(\".xh-tabbar-nav-item\").boundingClientRect();\n query.select(\".xh-tabbar-nav\").boundingClientRect(); // 导航容器(下划线定位基准)\n query.selectAll(\".xh-tabbar-content-item\").boundingClientRect();\n query.selectAll(\".xh-tabbar-content-slot\").boundingClientRect();\n query.select(\".xh-tabbar-nav-scroll\").boundingClientRect(); // 滚动容器\n query.exec(res => {\n const [\n navRects,\n navContainerRect,\n contentRects,\n slotRects,\n scrollRect,\n ] = res;\n const navContainer = navContainerRect?.node || navContainerRect;\n // 下划线宽度+内容高度\n if (navRects[targetIndex] && navContainer && scrollRect) {\n const itemRect = navRects[targetIndex];\n const containerRect = navContainerRect;\n const centerX =\n itemRect.left + itemRect.width / 2 - containerRect.left;\n setLineLeft(centerX);\n\n // 计算ScrollView滚动距离(选中项居中)\n if (isOverflowNav) {\n const targetScroll = computeScroll(\n itemRect,\n scrollRect,\n navContainerRect.left,\n navContainerRect.width\n );\n setNavLeft(targetScroll);\n }\n }\n // 内容高度计算(保持不变)\n if (contentRects[targetIndex]) {\n setTabContentHeight(contentRects[targetIndex].height);\n }\n // Slot高度查询取[0],因为Slot只有一个节点\n if (slotRects[0]) {\n setTabSlotHeight(slotRects[0].height);\n }\n });\n }, 50);\n },\n [children, isOverflowNav]\n );\n\n useEffect(() => {\n calculateTabInfo(selectIndex);\n // 清理定时器,防止内存泄漏\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, [selectIndex, calculateTabInfo]);\n\n // 点击导航项\n const handleClick = (index: number): void => {\n if (index === selectIndex) return; // 点击当前选中项,不做处理\n // 同步计算目标项位置,下划线立即更新\n calculateTabInfo(index);\n // 触发切换回调\n onChange && onChange(index);\n\n // 小程序端单独处理内容高度(H5已在calculateTabInfo中处理)\n if (process.env.TARO_ENV === \"h5\") {\n // 点击导航获取内容高度和slot高度\n const query = createSelectorQuery();\n query.selectAll(\".xh-tabbar-content-item\").boundingClientRect();\n query.selectAll(\".xh-tabbar-content-slot\").boundingClientRect();\n query.exec(res => {\n if (!res[0][index]) return;\n const height: number = res[0][index].height;\n\n setTabContentHeight(height);\n if (!res[1][index]) return;\n setTabSlotHeight(res[1][index].height);\n });\n }\n };\n\n // 下划线\n function renderLine(): ReactElement | null {\n return (\n <div\n className=\"xh-tabbar-nav-line\"\n style={{\n background: `${lineColor}`,\n transform: `translateX(${lineLeft}px) translate(-50%, -50%)`,\n WebkitTransform: `translateX(${lineLeft}px) translate(-50%, -50%)`,\n transition: \"transform 0.3s ease\", // 小程序端动画过渡\n }}\n />\n );\n }\n\n // 导航栏\n function renderNav() {\n return (\n <ScrollView\n scrollX\n scrollLeft={navLeft}\n className=\"xh-tabbar-nav-scroll\"\n ref={navScrollRef}\n scrollWithAnimation={isOverflowNav}\n scrollAnchoring={isOverflowNav}\n >\n <View\n className=\"xh-tabbar-nav\"\n ref={navContainerRef}\n style={{ width: isOverflowNav ? \"fit-content\" : \"100%\" }}\n >\n {children.map((child, index) => (\n <View\n key={index}\n data-index={index}\n // @ts-ignore\n dataTrackId={\n child.props.dataTrackId || `xh-tabbar-nav-item-${index}`\n }\n ref={el => (itemNavRef.current[index] = el)}\n className={classNames(\"xh-tabbar-nav-item\", {\n \"more-item\": isOverflowNav,\n })}\n style={{\n color:\n selectIndex === index ? titleActiveColor : titleInctiveColor,\n flex: isOverflowNav ? \"none\" : \"1\",\n }}\n onClick={() => handleClick(index)}\n >\n {child.props.TabItemComponent || child.props.title}\n </View>\n ))}\n {renderLine()}\n </View>\n </ScrollView>\n );\n }\n\n return (\n <View className=\"xh-tabbar\">\n {renderNav()}\n <View\n className=\"xh-tabbar-content\"\n style={{\n width: `${children.length * 100}%`,\n height:\n tabContentHeight + tabSlotHeight\n ? `${tabContentHeight + tabSlotHeight}px`\n : \"auto\",\n }}\n >\n {content && (\n <View className=\"xh-tabbar-content-slot\" ref={itemSlotRef}>\n {content}\n </View>\n )}\n {children.map((child, index) => (\n <View\n key={index}\n ref={el => (itemContentRef.current[index] = el)}\n className={classNames(\"xh-tabbar-content-item\", {\n \"xh-tabbar-content-item-dispaly\": selectIndex !== index,\n \"xh-tabbar-content-item-active\": selectIndex === index,\n })}\n >\n {child.props.children}\n </View>\n ))}\n </View>\n </View>\n );\n};\n\nXHTabs.Item = Item;\n\nexport default XHTabs;\nexport const TabItem = Item;\n"],"names":["XHTabs","props","_a","children","_b","lineColor","_c","titleActiveColor","_d","titleInctiveColor","onChange","content","_e","selectIndex","_f","isOverflowNav","_g","__read","useState","tabContentHeight","setTabContentHeight","_h","tabSlotHeight","setTabSlotHeight","_j","lineLeft","setLineLeft","_k","navLeft","setNavLeft","itemNavRef","useRef","itemContentRef","itemSlotRef","navScrollRef","navContainerRef","timerRef","computeScroll","itemRect","scrollRect","containerLeft","containerWidth","targetScroll","left","width","maxScroll","Math","max","min","calculateTabInfo","useCallback","targetIndex","validChildren","filter","Boolean","length","process","env","TARO_ENV","current","setTimeout","query","createSelectorQuery","selectAll","boundingClientRect","select","exec","res","navRects","navContainerRect","contentRects","slotRects","navContainer","node","containerRect","centerX","height","navItem","slotItem","contentItem","parentElement","scrollContainer","getBoundingClientRect","offsetWidth","slotRect","contentRect","useEffect","clearTimeout","React","createElement","View","className","ScrollView","scrollX","scrollLeft","ref","scrollWithAnimation","scrollAnchoring","style","map","child","index","key","dataTrackId","concat","el","classNames","color","flex","onClick","handleClick","TabItemComponent","title","background","transform","WebkitTransform","transition","Item"],"mappings":"kTA6CM,IAAAA,EAAkC,SAAAC,GAEpC,IAAAC,EASED,EAAKE,SATPA,OAAQ,IAAAD,EAAG,GAAEA,EAEbE,EAOEH,EAPmBI,UAArBA,OAAS,IAAAD,EAAG,UAASA,EACrBE,EAMEL,EAAKM,iBANPA,OAAmB,IAAAD,EAAA,SACnBE,EAKEP,EALwBQ,kBAA1BA,OAAoB,IAAAD,EAAA,OAAMA,EAC1BE,EAIET,EAJMS,SACRC,EAGEV,UAFFW,EAEEX,EAAKY,YAFPA,aAAc,EAACD,EACfE,EACEb,EAAKc,cADPA,OAAa,IAAAD,GAAQA,EAGjBE,EAAAC,EAA0CC,EAAS,GAAE,GAApDC,EAAgBH,EAAA,GAAEI,OACnBC,EAAAJ,EAAoCC,EAAS,GAAE,GAA9CI,EAAaD,EAAA,GAAEE,OAChBC,EAAAP,EAA0BC,EAAS,GAAE,GAApCO,OAAUC,EAA0BF,EAAA,GACrCG,EAAAV,EAAwBC,EAAS,GAAE,GAAlCU,OAASC,EAAyBF,EAAA,GAEnCG,EAAaC,EAAkC,IAC/CC,EAAiBD,EAAkC,IACnDE,EAAcF,EAAkC,IAChDG,EAAeH,EAA8B,MAC7CI,EAAkBJ,EAA8B,MAChDK,EAAWL,EAA8B,MAGzCM,EAAgB,SACpBC,EACAC,EACAC,EACAC,GAEA,IAAKF,IAAexB,EAAe,OAAO,EAE1C,IAEI2B,EAFoBJ,EAASK,KAAOH,GAGnBD,EAAWK,MAAQN,EAASM,OAAS,EAEpDC,EAAYC,KAAKC,IAAI,EAAGN,EAAiBF,EAAWK,OAE1D,OAAOE,KAAKC,IAAI,EAAGD,KAAKE,IAAIN,EAAcG,GAC5C,EAGMI,EAAmBC,GACvB,SAACC,GAEC,IAAMC,EAAgBjD,EAASkD,OAAOC,SACtC,KAAIH,EAAc,GAAKA,GAAeC,EAAcG,QAGpD,GAA6B,OAAzBC,QAAQC,IAAIC,SA6ChBtB,EAASuB,QAAUC,YAAW,WAC5B,IAAMC,EAAQC,IACdD,EAAME,UAAU,uBAAuBC,qBACvCH,EAAMI,OAAO,kBAAkBD,qBAC/BH,EAAME,UAAU,2BAA2BC,qBAC3CH,EAAME,UAAU,2BAA2BC,qBAC3CH,EAAMI,OAAO,yBAAyBD,qBACtCH,EAAMK,MAAK,SAAAC,GACH,IAAAjE,EAAAe,EAMFkD,KALFC,OACAC,OACAC,OACAC,OACAhC,OAEIiC,GAAeH,aAAA,EAAAA,EAAkBI,OAAQJ,EAE/C,GAAID,EAASjB,IAAgBqB,GAAgBjC,EAAY,CACvD,IAAMD,EAAW8B,EAASjB,GACpBuB,EAAgBL,EAChBM,EACJrC,EAASK,KAAOL,EAASM,MAAQ,EAAI8B,EAAc/B,KAIrD,GAHAjB,EAAYiD,GAGR5D,EAAe,CACjB,IAAM2B,EAAeL,EACnBC,EACAC,EACA8B,EAAiB1B,KACjB0B,EAAiBzB,OAEnBf,EAAWa,EACZ,CACF,CAEG4B,EAAanB,IACf/B,EAAoBkD,EAAanB,GAAayB,QAG5CL,EAAU,IACZhD,EAAiBgD,EAAU,GAAGK,OAElC,GACD,GAAE,QAzFH,CACE,IAAMC,EAAU/C,EAAW6B,QAAQR,GAC7B2B,EAAW7C,EAAY0B,QAAQ,GAC/BoB,EAAc/C,EAAe2B,QAAQR,GACrCqB,EAAeK,aAAA,EAAAA,EAASG,cACxBC,EAAkB/C,EAAayB,QAGrC,GAAIkB,GAAWL,GAAgBS,EAAiB,CAC9C,IAAM3C,EAAWuC,EAAQK,wBACnBR,EAAgBF,EAAaU,wBAC7B3C,EAAa0C,EAAgBC,wBAC7BP,EACJrC,EAASK,KAAOL,EAASM,MAAQ,EAAI8B,EAAc/B,KAGrD,GAFAjB,EAAYiD,GAER5D,EAAe,CACjB,IAAM2B,EAAeL,EACnBC,EACAC,EACAmC,EAAc/B,KACd6B,EAAaW,aAEftD,EAAWa,EAOZ,CACF,CAED,GAAIoC,EAAU,CACZ,IAAMM,EAAWN,EAASI,wBAC1B3D,EAAiB6D,EAASR,OAC3B,CACD,GAAIG,EAAa,CACf,IAAMM,EAAcN,EAAYG,wBAChC9D,EAAoBiE,EAAYT,OACjC,CAEF,CAgDH,GACA,CAACzE,EAAUY,IAGbuE,GAAU,WAGR,OAFArC,EAAiBpC,GAEV,WACDuB,EAASuB,SAAS4B,aAAanD,EAASuB,QAC9C,CACF,GAAG,CAAC9C,EAAaoC,IAsFjB,OACEuC,EAACC,cAAAC,EAAK,CAAAC,UAAU,aA1CdH,EAACC,cAAAG,EACC,CAAAC,WACAC,WAAYlE,EACZ+D,UAAU,uBACVI,IAAK7D,EACL8D,oBAAqBjF,EACrBkF,gBAAiBlF,GAEjByE,EAACC,cAAAC,EACC,CAAAC,UAAU,gBACVI,IAAK5D,EACL+D,MAAO,CAAEtD,MAAO7B,EAAgB,cAAgB,SAE/CZ,EAASgG,KAAI,SAACC,EAAOC,GAAU,OAC9Bb,gBAACE,EAAI,CACHY,IAAKD,eACOA,EAEZE,YACEH,EAAMnG,MAAMsG,aAAe,sBAAsBC,OAAAH,GAEnDN,IAAK,SAAAU,GAAM,OAAC3E,EAAW6B,QAAQ0C,GAASI,GACxCd,UAAWe,EAAW,qBAAsB,CAC1C,YAAa3F,IAEfmF,MAAO,CACLS,MACE9F,IAAgBwF,EAAQ9F,EAAmBE,EAC7CmG,KAAM7F,EAAgB,OAAS,KAEjC8F,QAAS,WAAM,OAxEP,SAACR,GACnB,GAAIA,IAAUxF,IAEdoC,EAAiBoD,GAEjB3F,GAAYA,EAAS2F,GAGQ,OAAzB7C,QAAQC,IAAIC,UAAmB,CAEjC,IAAMG,EAAQC,IACdD,EAAME,UAAU,2BAA2BC,qBAC3CH,EAAME,UAAU,2BAA2BC,qBAC3CH,EAAMK,MAAK,SAAAC,GACT,GAAKA,EAAI,GAAGkC,GAAZ,CACA,IAAMzB,EAAiBT,EAAI,GAAGkC,GAAOzB,OAErCxD,EAAoBwD,GACfT,EAAI,GAAGkC,IACZ9E,EAAiB4C,EAAI,GAAGkC,GAAOzB,OALJ,CAM7B,GACD,CACH,CAkD2BkC,CAAYT,EAAM,GAEhCD,EAAMnG,MAAM8G,kBAAoBX,EAAMnG,MAAM+G,MAnBjB,IA5BpCxB,EACEC,cAAA,MAAA,CAAAE,UAAU,qBACVO,MAAO,CACLe,WAAY,GAAGT,OAAAnG,GACf6G,UAAW,cAAcV,OAAA/E,EAAmC,6BAC5D0F,gBAAiB,cAAcX,OAAA/E,EAAmC,6BAClE2F,WAAY,2BAqDhB5B,EAAAC,cAACC,EACC,CAAAC,UAAU,oBACVO,MAAO,CACLtD,MAAO,GAAG4D,OAAkB,IAAlBrG,EAASoD,OAAe,KAClCqB,OACEzD,EAAmBG,EACf,GAAAkF,OAAGrF,EAAmBG,EAAiB,MACvC,SAGPX,GACC6E,EAACC,cAAAC,GAAKC,UAAU,yBAAyBI,IAAK9D,GAC3CtB,GAGJR,EAASgG,KAAI,SAACC,EAAOC,GAAU,OAC9Bb,EAAAC,cAACC,EACC,CAAAY,IAAKD,EACLN,IAAK,SAAAU,GAAM,OAACzE,EAAe2B,QAAQ0C,GAASI,CAAG,EAC/Cd,UAAWe,EAAW,yBAA0B,CAC9C,iCAAkC7F,IAAgBwF,EAClD,gCAAiCxF,IAAgBwF,KAGlDD,EAAMnG,MAAME,SAEhB,KAIT,EAEAH,EAAOqH,KAAOA"}
1
+ {"version":3,"file":"Tabbar.js","sources":["../../../../src/components/Tabbar/tabbar/Tabbar.tsx"],"sourcesContent":["import React, {\n FC,\n ReactElement,\n useEffect,\n useState,\n ReactNode,\n useRef,\n useCallback,\n} from \"react\";\nimport { createSelectorQuery } from \"@tarojs/taro\";\nimport { View, ScrollView } from \"@tarojs/components\";\nimport classNames from \"classnames\";\nimport Item from \"./TabItem\";\n\n/**\n * Tab切换\n *\n * @param children //子组件\n * @param animated //是否开启转场动画\n * @param selectIndex //默认选中第几个\n * @param lineColor //下划线颜色\n * @param titleActiveColor //标题选中态颜色\n * @param titleInctiveColor //标题默认态颜色\n * @param onChange //切换回调事件\n * @param content //item公共节点\n * @param isOverflowNav //是否超宽导航(超过屏幕宽度,自动滚动)\n *\n */\n\nexport interface TabProps {\n children: ReactElement[];\n animated?: boolean;\n lineColor?: string;\n titleActiveColor?: string;\n titleInctiveColor?: string;\n onChange?: (index: number) => void;\n content?: string | ReactNode;\n selectIndex: number;\n isOverflowNav?: boolean;\n}\n\nexport interface TabsComponent<P = {}> extends FC<P> {\n Item: typeof Item;\n}\n\nconst XHTabs: TabsComponent<TabProps> = props => {\n const {\n children = [],\n // animated = false,\n lineColor = \"#FE5E00\",\n titleActiveColor = \"#333\",\n titleInctiveColor = \"#999\",\n onChange,\n content,\n selectIndex = 0,\n isOverflowNav = false,\n } = props;\n\n const [tabContentHeight, setTabContentHeight] = useState(0);\n const [tabSlotHeight, setTabSlotHeight] = useState(0);\n const [lineLeft, setLineLeft] = useState(0); // 下划线左偏移,核心:通过状态控制下划线位置,确保同步更新和动画过渡\n const [navLeft, setNavLeft] = useState(0); // 导航滚动位置,核心:通过状态控制滚动位置,适配超宽导航\n // Ref定义\n const itemNavRef = useRef<(HTMLDivElement | null)[]>([]);\n const itemContentRef = useRef<(HTMLDivElement | null)[]>([]);\n const itemSlotRef = useRef<(HTMLDivElement | null)[]>([]);\n const navScrollRef = useRef<HTMLDivElement | null>(null); // 滚动容器ref\n const navContainerRef = useRef<HTMLDivElement | null>(null);\n const timerRef = useRef<NodeJS.Timeout | null>(null); // 定时器ref,避免闭包丢失\n\n // 统一滚动计算逻辑:H5/小程序通用\n const computeScroll = (\n itemRect: any,\n scrollRect: any,\n containerLeft: number,\n containerWidth: number\n ) => {\n if (!scrollRect || !isOverflowNav) return 0;\n // 元素在导航容器内的绝对偏移(视口坐标转容器坐标)\n const itemOffsetInNav = itemRect.left - containerLeft;\n // 居中滚动值:让选中项尽量居中显示\n let targetScroll =\n itemOffsetInNav - (scrollRect.width - itemRect.width) / 2;\n // 最大可滚动距离:总导航宽度 - 可视区域宽度\n const maxScroll = Math.max(0, containerWidth - scrollRect.width);\n // 边界处理:不小于0,不大于最大可滚动距离\n return Math.max(0, Math.min(targetScroll, maxScroll));\n };\n\n // 抽离位置/尺寸计算逻辑,复用(初始化+切换都调用)\n const calculateTabInfo = useCallback(\n (targetIndex: number) => {\n // 过滤空children,避免索引越界\n const validChildren = children.filter(Boolean);\n if (targetIndex < 0 || targetIndex >= validChildren.length) return;\n\n // H5端:直接通过ref获取元素信息,核心:同步更新,无需等待DOM渲染\n if (process.env.TARO_ENV === \"h5\") {\n const navItem = itemNavRef.current[targetIndex];\n const slotItem = itemSlotRef.current[0];\n const contentItem = itemContentRef.current[targetIndex];\n const navContainer = navItem?.parentElement as HTMLDivElement;\n const scrollContainer = navScrollRef.current;\n\n // 计算下划线位置\n if (navItem && navContainer && scrollContainer) {\n const itemRect = navItem.getBoundingClientRect();\n const containerRect = navContainer.getBoundingClientRect();\n const scrollRect = scrollContainer.getBoundingClientRect();\n const centerX =\n itemRect.left + itemRect.width / 2 - containerRect.left;\n setLineLeft(centerX);\n\n if (isOverflowNav) {\n const targetScroll = computeScroll(\n itemRect,\n scrollRect,\n containerRect.left,\n navContainer.offsetWidth\n );\n scrollContainer.scrollTo({\n left: targetScroll,\n // behavior: \"instant\",\n });\n }\n }\n\n if (slotItem) {\n const slotRect = slotItem.getBoundingClientRect();\n setTabSlotHeight(slotRect.height);\n }\n if (contentItem) {\n const contentRect = contentItem.getBoundingClientRect();\n setTabContentHeight(contentRect.height);\n }\n return;\n }\n\n // 小程序端:必须用createSelectorQuery,保留极短延迟(50ms),适配小程序DOM渲染时机\n timerRef.current = setTimeout(() => {\n const query = createSelectorQuery();\n query.selectAll(\".xh-tabbar-nav-item\").boundingClientRect();\n query.select(\".xh-tabbar-nav\").boundingClientRect(); // 导航容器(下划线定位基准)\n query.selectAll(\".xh-tabbar-content-item\").boundingClientRect();\n query.selectAll(\".xh-tabbar-content-slot\").boundingClientRect();\n query.select(\".xh-tabbar-nav-scroll\").boundingClientRect(); // 滚动容器\n query.exec(res => {\n const [\n navRects,\n navContainerRect,\n contentRects,\n slotRects,\n scrollRect,\n ] = res;\n const navContainer = navContainerRect?.node || navContainerRect;\n // 下划线宽度+内容高度\n if (navRects[targetIndex] && navContainer && scrollRect) {\n const itemRect = navRects[targetIndex];\n const containerRect = navContainerRect;\n const centerX =\n itemRect.left + itemRect.width / 2 - containerRect.left;\n setLineLeft(centerX);\n\n // 计算ScrollView滚动距离(选中项居中)\n if (isOverflowNav) {\n const targetScroll = computeScroll(\n itemRect,\n scrollRect,\n navContainerRect.left,\n navContainerRect.width\n );\n setNavLeft(targetScroll);\n }\n }\n // 内容高度计算(保持不变)\n if (contentRects[targetIndex]) {\n setTabContentHeight(contentRects[targetIndex].height);\n }\n // Slot高度查询取[0],因为Slot只有一个节点\n if (slotRects[0]) {\n setTabSlotHeight(slotRects[0].height);\n }\n });\n }, 50);\n },\n [children, isOverflowNav]\n );\n\n useEffect(() => {\n calculateTabInfo(selectIndex);\n // 清理定时器,防止内存泄漏\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, [selectIndex, calculateTabInfo]);\n\n // 点击导航项\n const handleClick = (index: number): void => {\n if (index === selectIndex) return; // 点击当前选中项,不做处理\n // 同步计算目标项位置,下划线立即更新\n calculateTabInfo(index);\n // 触发切换回调\n onChange && onChange(index);\n\n // 小程序端单独处理内容高度(H5已在calculateTabInfo中处理)\n if (process.env.TARO_ENV === \"h5\") {\n // 点击导航获取内容高度和slot高度\n const query = createSelectorQuery();\n query.selectAll(\".xh-tabbar-content-item\").boundingClientRect();\n query.selectAll(\".xh-tabbar-content-slot\").boundingClientRect();\n query.exec(res => {\n if (!res[0][index]) return;\n const height: number = res[0][index].height;\n\n setTabContentHeight(height);\n if (!res[1][index]) return;\n setTabSlotHeight(res[1][index].height);\n });\n }\n };\n\n // 下划线\n function renderLine(): ReactElement | null {\n return (\n <div\n className=\"xh-tabbar-nav-line\"\n style={{\n background: `${lineColor}`,\n transform: `translateX(${lineLeft}px) translate(-50%, -50%)`,\n WebkitTransform: `translateX(${lineLeft}px) translate(-50%, -50%)`,\n transition: \"transform 0.3s ease\", // 小程序端动画过渡\n }}\n />\n );\n }\n\n // 导航栏\n function renderNav() {\n return (\n <ScrollView\n scrollX\n scrollLeft={navLeft}\n className=\"xh-tabbar-nav-scroll\"\n ref={navScrollRef}\n >\n <View\n className=\"xh-tabbar-nav\"\n ref={navContainerRef}\n style={{ width: isOverflowNav ? \"fit-content\" : \"100%\" }}\n >\n {children.map((child, index) => (\n <View\n key={index}\n data-index={index}\n // @ts-ignore\n dataTrackId={\n child.props.dataTrackId || `xh-tabbar-nav-item-${index}`\n }\n ref={el => (itemNavRef.current[index] = el)}\n className={classNames(\"xh-tabbar-nav-item\", {\n \"more-item\": isOverflowNav,\n })}\n style={{\n color:\n selectIndex === index ? titleActiveColor : titleInctiveColor,\n flex: isOverflowNav ? \"none\" : \"1\",\n }}\n onClick={() => handleClick(index)}\n >\n {child.props.TabItemComponent || child.props.title}\n </View>\n ))}\n {renderLine()}\n </View>\n </ScrollView>\n );\n }\n\n return (\n <View className=\"xh-tabbar\">\n {renderNav()}\n <View\n className=\"xh-tabbar-content\"\n style={{\n width: `${children.length * 100}%`,\n height:\n tabContentHeight + tabSlotHeight\n ? `${tabContentHeight + tabSlotHeight}px`\n : \"auto\",\n }}\n >\n {content && (\n <View className=\"xh-tabbar-content-slot\" ref={itemSlotRef}>\n {content}\n </View>\n )}\n {children.map((child, index) => (\n <View\n key={index}\n ref={el => (itemContentRef.current[index] = el)}\n className={classNames(\"xh-tabbar-content-item\", {\n \"xh-tabbar-content-item-dispaly\": selectIndex !== index,\n \"xh-tabbar-content-item-active\": selectIndex === index,\n })}\n >\n {child.props.children}\n </View>\n ))}\n </View>\n </View>\n );\n};\n\nXHTabs.Item = Item;\n\nexport default XHTabs;\nexport const TabItem = Item;\n"],"names":["XHTabs","props","_a","children","_b","lineColor","_c","titleActiveColor","_d","titleInctiveColor","onChange","content","_e","selectIndex","_f","isOverflowNav","_g","__read","useState","tabContentHeight","setTabContentHeight","_h","tabSlotHeight","setTabSlotHeight","_j","lineLeft","setLineLeft","_k","navLeft","setNavLeft","itemNavRef","useRef","itemContentRef","itemSlotRef","navScrollRef","navContainerRef","timerRef","computeScroll","itemRect","scrollRect","containerLeft","containerWidth","targetScroll","left","width","maxScroll","Math","max","min","calculateTabInfo","useCallback","targetIndex","validChildren","filter","Boolean","length","process","env","TARO_ENV","current","setTimeout","query","createSelectorQuery","selectAll","boundingClientRect","select","exec","res","navRects","navContainerRect","contentRects","slotRects","navContainer","node","containerRect","centerX","height","navItem","slotItem","contentItem","parentElement","scrollContainer","getBoundingClientRect","offsetWidth","scrollTo","slotRect","contentRect","useEffect","clearTimeout","React","createElement","View","className","ScrollView","scrollX","scrollLeft","ref","style","map","child","index","key","dataTrackId","concat","el","classNames","color","flex","onClick","handleClick","TabItemComponent","title","background","transform","WebkitTransform","transition","Item"],"mappings":"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"}