@wwog/react 1.2.17 → 1.2.19

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.
package/README.md CHANGED
@@ -199,10 +199,7 @@ function Example() {
199
199
  <Clamp
200
200
  text="This is a long text that will be truncated with ellipsis..."
201
201
  maxLine={2}
202
- lineHeight={20}
203
- ellipsis={true}
204
202
  extraContent={<button>See more</button>}
205
- bgColor="#fff"
206
203
  />
207
204
  );
208
205
  }
@@ -210,12 +207,8 @@ function Example() {
210
207
 
211
208
  - `text`: The text content to be displayed.
212
209
  - `maxLine`: Maximum number of lines, defaults to 1.
213
- - `lineHeight`: Line height in pixels, defaults to 20.
214
- - `ellipsis`: Whether to display ellipsis, defaults to false.
215
- - `ellipsisContent`: Custom ellipsis content, defaults to `<span>...</span>`.
216
210
  - `extraContent`: Extra content to display at the end of the text, such as a "See more" button.
217
211
  - `extraHeight`: Height of the extra content, defaults to 20.
218
- - `bgColor`: Background color, defaults to white ('#fff').
219
212
  - `wrapperStyle`: Style for the wrapper container.
220
213
 
221
214
  #### `<Pipe>` (v1.1.7+)
package/dist/index.d.mts CHANGED
@@ -386,28 +386,11 @@ interface ClampProps {
386
386
  * @default 20
387
387
  */
388
388
  extraHeight?: number;
389
- /**
390
- * @description 是否显示省略号
391
- * @description_en whether to display ellipsis
392
- */
393
- ellipsis?: boolean;
394
- /**
395
- * @description 替换省略号内容
396
- * @description_en replace ellipsis content
397
- * @default '<span>...</span>'
398
- */
399
- ellipsisContent?: React$1.ReactNode;
400
389
  /**
401
390
  * @description 显示的文本
402
391
  * @description_en text to be displayed
403
392
  */
404
393
  text: string;
405
- /**
406
- * @description 背景颜色,请不要使用`wrapperStyle`覆盖此设置,因纯兼容性的css方式实现。默认白色
407
- * @description_en background color, please do not use `wrapperStyle` to override this setting, because it is implemented in a pure compatible css way. Default white
408
- * @default '#fff'
409
- */
410
- bgColor?: string;
411
394
  wrapperStyle?: React$1.CSSProperties;
412
395
  }
413
396
  /**
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import r,{useMemo as h,Children as W,Fragment as S,isValidElement as J,cloneElement as _,useEffect as H,useState as M,useRef as T,useLayoutEffect as L,useCallback as V}from"react";function I(t,n){if(t===void 0)return;let e=0;if(Array.isArray(t)){for(const l of t)if(n(l,e++)===!1)break}else n(t,e)}const Z=(t,n)=>t===n,E=t=>r.createElement(r.Fragment,null,t.children);E.displayName="Switch_Case";const w=t=>r.createElement(r.Fragment,null,t.children);w.displayName="Switch_Default";const y=t=>{const{value:n,compare:e=Z,children:l,strict:o=!1}=t,a=new Set;let i=null,c=null,d=!1;return I(l,(u,s)=>{if(!r.isValidElement(u))throw new Error(`Switch Children only accepts valid React elements at index ${s}`);const f=u.type;if(f.displayName===E.displayName){const m=u.props;if(a.has(m.value))throw new Error(`Switch found duplicate Case value at index ${s}: ${JSON.stringify(m.value)}${o?" (detected in strict mode)":""}`);if(a.add(m.value),!i&&e(n,m.value)&&(i=m.children,o===!1))return!1}else if(f.displayName===w.displayName){if(d)throw new Error(`Switch can only have one Default child at index ${s}`);if(d=!0,c=u.props.children,!o&&i)return!1}else throw new Error(`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(f.displayName||f.name||f)} at index ${s}`)}),r.createElement(r.Fragment,null,i??c)};y.displayName="Switch",y.Case=E,y.Default=w,y.createTyped=function(){return{Switch:y,Case:E,Default:w}};const v=t=>r.createElement(r.Fragment,null,t.children),N=({children:t})=>r.createElement(r.Fragment,null,t),b=t=>r.createElement(r.Fragment,null,t.children);v.displayName="If_Then",N.displayName="If_Else",b.displayName="If_ElseIf";const p=({condition:t,children:n})=>{let e=null,l=null;const o=[];if(r.Children.forEach(n,a=>{if(!r.isValidElement(a))throw new Error("If component only accepts valid React elements");const i=a.type;if(i.displayName===v.displayName){if(e)throw new Error("If component can only have one Then child");e=a}else if(i.displayName===b.displayName)o.push(a);else if(i.displayName===N.displayName){if(l)throw new Error("If component can only have one Else child");l=a}else throw new Error(`If component only accepts 'Then', 'ElseIf', or 'Else' elements as children, found: ${String(i.displayName||i.name||i)}`)}),t)return e?r.createElement(r.Fragment,null,e.props.children):null;for(const a of o)if(a.props.condition)return r.createElement(r.Fragment,null,a.props.children);return l?r.createElement(r.Fragment,null,l.props.children):null};p.displayName="If",p.Then=v,p.ElseIf=b,p.Else=N,p.createTyped=function(){return{If:p,Then:v,ElseIf:b,Else:N}};const C=({condition:t,children:n})=>t?r.createElement(r.Fragment,null,n):null,z=({condition:t,children:n})=>t===!1?r.createElement(r.Fragment,null,n):null,G=({all:t,any:n,none:e,children:l,fallback:o})=>h(()=>(t&&(n||e)&&console.warn('When: Multiple condition types (all, any, none) provided; "all" takes precedence.'),!!(t&&t.length>0&&t.every(Boolean)||n&&n.length>0&&n.some(Boolean)||e&&e.length>0&&e.every(a=>!a))),[t,n,e])?r.createElement(r.Fragment,null,l):r.createElement(r.Fragment,null,o||null),q=({data:t,transform:n,render:e,fallback:l})=>{const o=h(()=>n.reduce((a,i)=>i(a),t),[t,n]);return o==null?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(o))},K=t=>{const{children:n,h:e,w:l,size:o,height:a,width:i,className:c}=t;return r.createElement("div",{style:{width:o||l||i,height:o||e||a,flexShrink:0},className:c},n)},Q=({let:t,props:n,children:e,fallback:l})=>{const o=h(()=>typeof t=="function"?t(n):t,[t,n]);return!e||!Object.keys(o).length?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(o))};function F(...t){const n=new Set;for(const e of t)if(e){if(typeof e=="string")n.add(e);else if(Array.isArray(e))e.forEach(l=>n.add(l));else if(typeof e=="object")for(const[l,o]of Object.entries(e))o&&n.add(l)}return Array.from(n).join(" ")}const U=t=>typeof t=="object"&&!!t,x=({className:t,children:n,asWrapper:e=!1})=>{if(!n)return null;if(W.count(n)>1)return console.error("<Styles>: children has more than one child. Please check your code."),r.createElement(S,null,n);if(!t)return r.createElement(S,null,n);const l=typeof t=="string"?t:F(...Object.values(t));if(e)return r.createElement(e===!0?"div":e,{className:l},n);if(J(n)){const o=n;let a=o?.props?.className;return o?.type?.displayName===x.displayName&&U(a)&&(a=F(...Object.values(a))),_(n,{className:F(l,a)})}return console.error("<Styles>: children is not a valid React element. Please check your code."),r.createElement(S,null,n)};x.displayName="W/Styles";const X=t=>{const{index:n=0,options:e,next:l,render:o}=t;H(()=>{if(e.length<n+1)throw new Error(`Index ${n} is out of bounds for options array of length ${e.length}. Defaulting to first option.`)},[n,e]);const[a,i]=M(n),c=()=>{i(d=>e.length?l?l(d,e):(d+1)%e.length:d)};return o(e[a],c)},$=t=>{const{maxLine:n=1,text:e,extraHeight:l=22,extraContent:o,wrapperStyle:a}=t;T(null);const i=T(null),[c,d]=M(!1),u=h(()=>!(e==null||e===""),[e]);return L(()=>{if(!i.current)return;const s=document.createElement("div");s.textContent=e,s.style.position="absolute",s.style.width="100%",s.style.wordBreak="break-all",s.style.top="100%",i.current.appendChild(s);const f=document.createRange();f.setStart(s.firstChild,0),f.setEnd(s.firstChild,e.length),f.getClientRects().length>n?d(!0):d(!1),i.current.removeChild(s)},[n,e]),r.createElement(C,{condition:u},r.createElement("div",{ref:i,style:{overflow:"hidden",position:"relative",width:"100%",display:"flex",...a}},r.createElement("div",{style:{display:"-webkit-box",WebkitBoxOrient:"vertical",WebkitLineClamp:n,overflow:"hidden",wordBreak:"break-all"}},r.createElement(C,{condition:c},r.createElement("div",{style:{float:"right",height:"100%",marginBottom:-l}}),r.createElement("div",{style:{float:"right",clear:"both",height:l}},o)),e)))};function ee(t){const{items:n,renderItem:e,filter:l}=t;return n?r.createElement(S,null,n.map((o,a)=>l&&!l(o)?null:e(o,a))):(console.error("ArrayRender: items is null"),null)}function te({source:t,format:n,children:e}){const l=h(()=>{if(t instanceof Date)return t;if(typeof t=="string"||typeof t=="number"){const a=new Date(t);return isNaN(a.getTime())?null:a}return null},[t]),o=h(()=>l?n?n(l):l.toLocaleString():null,[l,n]);return!o||!e?null:r.createElement(r.Fragment,null,e(o))}const ne="onChange",re="value";function le(t){const{defaultValue:n,onBeforeChange:e,trigger:l=ne,valuePropName:o=re,props:a}=t,i=Object.prototype.hasOwnProperty.call(a,o),[c,d]=M(n),u=i?a[o]:c,s=h(()=>a[l],[a,l]),f=V(m=>{const g=typeof m=="function"?m(u):m;e&&e(g,u)===!1||(i||d(g),s&&s(g))},[i,e,u,s]);return[u,f]}function ae(t,...n){try{const e=t(...n);return e instanceof Promise?e:Promise.resolve(e)}catch(e){return Promise.reject(e)}}const A=typeof Promise.try=="function"?Promise.try.bind(Promise):ae;function oe(t,n){let e=typeof t=="function"?t():t;const l=[],o=()=>e,a=c=>{const d=e;e=typeof c=="function"?c():c,l.forEach(u=>u(e)),n&&A(n,e,d).catch(u=>{console.error("Error in external state side effect, Please do it within side effects:",u)})},i=()=>{const[c,d]=r.useState(e);return r.useEffect(()=>(l.push(d),()=>{const u=l.indexOf(d);u>-1&&l.splice(u,1)}),[]),[c,a]};return{get:o,set:a,use:i,useGetter:()=>{const[c]=i();return c},__listeners:l}}function ie(t,n){const e=n||new Date,l=e.getFullYear(),o=e.getMonth()+1,a=e.getDate(),i=e.getHours(),c=e.getMinutes(),d=e.getSeconds(),u=e.getMilliseconds(),s=e.getDay(),f=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],m=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],P=["January","February","March","April","May","June","July","August","September","October","November","December"],Y=m[s],D=f[s],k=o-1,O=P[k],j=g[k],R={YY:l.toString().slice(2),YYYY:l.toString(),M:o.toString(),MM:o.toString().padStart(2,"0"),MMM:j,MMMM:O,D:a.toString(),DD:a.toString().padStart(2,"0"),d:s.toString(),dd:D,ddd:D,dddd:Y,H:i.toString(),HH:i.toString().padStart(2,"0"),h:(i%12).toString(),hh:(i%12).toString().padStart(2,"0"),m:c.toString(),mm:c.toString().padStart(2,"0"),s:d.toString(),ss:d.toString().padStart(2,"0"),SSS:u.toString().padStart(3,"0"),Z:"+08:00",ZZ:"+0800",A:i<12?"AM":"PM",a:i<12?"am":"pm"};return t.replace(/YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|SSS|Z{1,2}|A|a/g,B=>R[B])}class se{count=0;next(){return this.count++}}export{ee as ArrayRender,$ as Clamp,se as Counter,te as DateRender,z as False,p as If,q as Pipe,Q as Scope,K as SizeBox,x as Styles,y as Switch,X as Toggle,C as True,G as When,I as childrenLoop,oe as createExternalState,F as cx,ie as formatDate,A as safePromiseTry,le as useControlled};
1
+ import r,{useMemo as p,Children as B,Fragment as S,isValidElement as W,cloneElement as J,useEffect as R,useState as C,useRef as _,useLayoutEffect as L,useCallback as z}from"react";function A(t,n){if(t===void 0)return;let e=0;if(Array.isArray(t)){for(const l of t)if(n(l,e++)===!1)break}else n(t,e)}const V=(t,n)=>t===n,E=t=>r.createElement(r.Fragment,null,t.children);E.displayName="Switch_Case";const w=t=>r.createElement(r.Fragment,null,t.children);w.displayName="Switch_Default";const g=t=>{const{value:n,compare:e=V,children:l,strict:o=!1}=t,a=new Set;let i=null,c=null,d=!1;return A(l,(s,m)=>{if(!r.isValidElement(s))throw new Error(`Switch Children only accepts valid React elements at index ${m}`);const u=s.type;if(u.displayName===E.displayName){const f=s.props;if(a.has(f.value))throw new Error(`Switch found duplicate Case value at index ${m}: ${JSON.stringify(f.value)}${o?" (detected in strict mode)":""}`);if(a.add(f.value),!i&&e(n,f.value)&&(i=f.children,o===!1))return!1}else if(u.displayName===w.displayName){if(d)throw new Error(`Switch can only have one Default child at index ${m}`);if(d=!0,c=s.props.children,!o&&i)return!1}else throw new Error(`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(u.displayName||u.name||u)} at index ${m}`)}),r.createElement(r.Fragment,null,i??c)};g.displayName="Switch",g.Case=E,g.Default=w,g.createTyped=function(){return{Switch:g,Case:E,Default:w}};const v=t=>r.createElement(r.Fragment,null,t.children),N=({children:t})=>r.createElement(r.Fragment,null,t),b=t=>r.createElement(r.Fragment,null,t.children);v.displayName="If_Then",N.displayName="If_Else",b.displayName="If_ElseIf";const y=({condition:t,children:n})=>{let e=null,l=null;const o=[];if(r.Children.forEach(n,a=>{if(!r.isValidElement(a))throw new Error("If component only accepts valid React elements");const i=a.type;if(i.displayName===v.displayName){if(e)throw new Error("If component can only have one Then child");e=a}else if(i.displayName===b.displayName)o.push(a);else if(i.displayName===N.displayName){if(l)throw new Error("If component can only have one Else child");l=a}else throw new Error(`If component only accepts 'Then', 'ElseIf', or 'Else' elements as children, found: ${String(i.displayName||i.name||i)}`)}),t)return e?r.createElement(r.Fragment,null,e.props.children):null;for(const a of o)if(a.props.condition)return r.createElement(r.Fragment,null,a.props.children);return l?r.createElement(r.Fragment,null,l.props.children):null};y.displayName="If",y.Then=v,y.ElseIf=b,y.Else=N,y.createTyped=function(){return{If:y,Then:v,ElseIf:b,Else:N}};const D=({condition:t,children:n})=>t?r.createElement(r.Fragment,null,n):null,Z=({condition:t,children:n})=>t===!1?r.createElement(r.Fragment,null,n):null,G=({all:t,any:n,none:e,children:l,fallback:o})=>p(()=>(t&&(n||e)&&console.warn('When: Multiple condition types (all, any, none) provided; "all" takes precedence.'),!!(t&&t.length>0&&t.every(Boolean)||n&&n.length>0&&n.some(Boolean)||e&&e.length>0&&e.every(a=>!a))),[t,n,e])?r.createElement(r.Fragment,null,l):r.createElement(r.Fragment,null,o||null),q=({data:t,transform:n,render:e,fallback:l})=>{const o=p(()=>n.reduce((a,i)=>i(a),t),[t,n]);return o==null?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(o))},K=t=>{const{children:n,h:e,w:l,size:o,height:a,width:i,className:c}=t;return r.createElement("div",{style:{width:o||l||i,height:o||e||a,flexShrink:0},className:c},n)},Q=({let:t,props:n,children:e,fallback:l})=>{const o=p(()=>typeof t=="function"?t(n):t,[t,n]);return!e||!Object.keys(o).length?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(o))};function M(...t){const n=new Set;for(const e of t)if(e){if(typeof e=="string")n.add(e);else if(Array.isArray(e))e.forEach(l=>n.add(l));else if(typeof e=="object")for(const[l,o]of Object.entries(e))o&&n.add(l)}return Array.from(n).join(" ")}const U=t=>typeof t=="object"&&!!t,k=({className:t,children:n,asWrapper:e=!1})=>{if(!n)return null;if(B.count(n)>1)return console.error("<Styles>: children has more than one child. Please check your code."),r.createElement(S,null,n);if(!t)return r.createElement(S,null,n);const l=typeof t=="string"?t:M(...Object.values(t));if(e)return r.createElement(e===!0?"div":e,{className:l},n);if(W(n)){const o=n;let a=o?.props?.className;return o?.type?.displayName===k.displayName&&U(a)&&(a=M(...Object.values(a))),J(n,{className:M(l,a)})}return console.error("<Styles>: children is not a valid React element. Please check your code."),r.createElement(S,null,n)};k.displayName="W/Styles";const X=t=>{const{index:n=0,options:e,next:l,render:o}=t;R(()=>{if(e.length<n+1)throw new Error(`Index ${n} is out of bounds for options array of length ${e.length}. Defaulting to first option.`)},[n,e]);const[a,i]=C(n),c=()=>{i(d=>e.length?l?l(d,e):(d+1)%e.length:d)};return o(e[a],c)},$=t=>{const{maxLine:n=1,text:e,extraHeight:l=22,extraContent:o,wrapperStyle:a}=t,i=_(null),[c,d]=C(!1),s=p(()=>!(e==null||e===""),[e]),m=()=>{if(!i.current)return;const u=document.createElement("div");u.textContent=e;const f=getComputedStyle(i.current);u.style.width=f.width,u.style.fontSize=f.fontSize,u.style.lineHeight=f.lineHeight,u.style.wordBreak="break-all",u.style.visibility="hidden",document.body.appendChild(u);const h=parseInt(getComputedStyle(u).lineHeight)||20,F=u.offsetHeight,x=Math.round(F/h);document.body.removeChild(u),d(x>n)};return L(()=>{s&&m()},[n,e,s]),r.createElement(D,{condition:s},r.createElement("div",{ref:i,style:{overflow:"hidden",width:"100%",display:"flex",...a}},r.createElement("div",{style:{display:"-webkit-box",WebkitBoxOrient:"vertical",WebkitLineClamp:n,overflow:"hidden",wordBreak:"break-all"}},r.createElement(D,{condition:c},r.createElement("div",{style:{float:"right",height:"100%",marginBottom:-l}}),r.createElement("div",{style:{float:"right",clear:"both",height:l}},o)),e)))};function ee(t){const{items:n,renderItem:e,filter:l}=t;return n?r.createElement(S,null,n.map((o,a)=>l&&!l(o)?null:e(o,a))):(console.error("ArrayRender: items is null"),null)}function te({source:t,format:n,children:e}){const l=p(()=>{if(t instanceof Date)return t;if(typeof t=="string"||typeof t=="number"){const a=new Date(t);return isNaN(a.getTime())?null:a}return null},[t]),o=p(()=>l?n?n(l):l.toLocaleString():null,[l,n]);return!o||!e?null:r.createElement(r.Fragment,null,e(o))}const ne="onChange",re="value";function le(t){const{defaultValue:n,onBeforeChange:e,trigger:l=ne,valuePropName:o=re,props:a}=t,i=Object.prototype.hasOwnProperty.call(a,o),[c,d]=C(n),s=i?a[o]:c,m=p(()=>a[l],[a,l]),u=z(f=>{const h=typeof f=="function"?f(s):f;e&&e(h,s)===!1||(i||d(h),m&&m(h))},[i,e,s,m]);return[s,u]}function ae(t,...n){try{const e=t(...n);return e instanceof Promise?e:Promise.resolve(e)}catch(e){return Promise.reject(e)}}const P=typeof Promise.try=="function"?Promise.try.bind(Promise):ae;function oe(t,n){let e=typeof t=="function"?t():t;const l=[],o=()=>e,a=c=>{const d=e;e=typeof c=="function"?c():c,l.forEach(s=>s(e)),n&&P(n,e,d).catch(s=>{console.error("Error in external state side effect, Please do it within side effects:",s)})},i=()=>{const[c,d]=r.useState(e);return r.useEffect(()=>(l.push(d),()=>{const s=l.indexOf(d);s>-1&&l.splice(s,1)}),[]),[c,a]};return{get:o,set:a,use:i,useGetter:()=>{const[c]=i();return c},__listeners:l}}function ie(t,n){const e=n||new Date,l=e.getFullYear(),o=e.getMonth()+1,a=e.getDate(),i=e.getHours(),c=e.getMinutes(),d=e.getSeconds(),s=e.getMilliseconds(),m=e.getDay(),u=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],f=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],h=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],F=["January","February","March","April","May","June","July","August","September","October","November","December"],x=f[m],T=u[m],I=o-1,Y=F[I],O=h[I],H={YY:l.toString().slice(2),YYYY:l.toString(),M:o.toString(),MM:o.toString().padStart(2,"0"),MMM:O,MMMM:Y,D:a.toString(),DD:a.toString().padStart(2,"0"),d:m.toString(),dd:T,ddd:T,dddd:x,H:i.toString(),HH:i.toString().padStart(2,"0"),h:(i%12).toString(),hh:(i%12).toString().padStart(2,"0"),m:c.toString(),mm:c.toString().padStart(2,"0"),s:d.toString(),ss:d.toString().padStart(2,"0"),SSS:s.toString().padStart(3,"0"),Z:"+08:00",ZZ:"+0800",A:i<12?"AM":"PM",a:i<12?"am":"pm"};return t.replace(/YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|SSS|Z{1,2}|A|a/g,j=>H[j])}class se{count=0;next(){return this.count++}}export{ee as ArrayRender,$ as Clamp,se as Counter,te as DateRender,Z as False,y as If,q as Pipe,Q as Scope,K as SizeBox,k as Styles,g as Switch,X as Toggle,D as True,G as When,A as childrenLoop,oe as createExternalState,M as cx,ie as formatDate,P as safePromiseTry,le as useControlled};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wwog/react",
3
- "version": "1.2.17",
3
+ "version": "1.2.19",
4
4
  "description": "A practical React component library providing declarative flow control and common UI utility components to make your React code more concise and readable.",
5
5
  "keywords": [
6
6
  "react",
@@ -15,28 +15,11 @@ export interface ClampProps {
15
15
  * @default 20
16
16
  */
17
17
  extraHeight?: number;
18
- /**
19
- * @description 是否显示省略号
20
- * @description_en whether to display ellipsis
21
- */
22
- ellipsis?: boolean;
23
- /**
24
- * @description 替换省略号内容
25
- * @description_en replace ellipsis content
26
- * @default '<span>...</span>'
27
- */
28
- ellipsisContent?: React.ReactNode;
29
18
  /**
30
19
  * @description 显示的文本
31
20
  * @description_en text to be displayed
32
21
  */
33
22
  text: string;
34
- /**
35
- * @description 背景颜色,请不要使用`wrapperStyle`覆盖此设置,因纯兼容性的css方式实现。默认白色
36
- * @description_en background color, please do not use `wrapperStyle` to override this setting, because it is implemented in a pure compatible css way. Default white
37
- * @default '#fff'
38
- */
39
- bgColor?: string;
40
23
  wrapperStyle?: React.CSSProperties;
41
24
  }
42
25
 
@@ -54,7 +37,6 @@ export const Clamp: FC<ClampProps> = (props) => {
54
37
  extraContent,
55
38
  wrapperStyle,
56
39
  } = props;
57
- const fullTextRef = useRef<HTMLDivElement>(null);
58
40
  const wrapperRef = useRef<HTMLDivElement>(null);
59
41
  const [showExtra, setShowExtra] = useState(false);
60
42
  const isValidText = useMemo(() => {
@@ -62,37 +44,42 @@ export const Clamp: FC<ClampProps> = (props) => {
62
44
  return true;
63
45
  }, [text]);
64
46
 
65
- useLayoutEffect(() => {
47
+ const checkTextOverflow = () => {
66
48
  if (!wrapperRef.current) {
67
49
  return;
68
50
  }
69
51
  const measureWrapper = document.createElement("div");
70
52
  measureWrapper.textContent = text;
71
- measureWrapper.style.position = "absolute";
72
- measureWrapper.style.width = "100%";
53
+ const wrapperStyle = getComputedStyle(wrapperRef.current);
54
+ measureWrapper.style.width = wrapperStyle.width;
55
+ measureWrapper.style.fontSize = wrapperStyle.fontSize;
56
+ measureWrapper.style.lineHeight = wrapperStyle.lineHeight;
73
57
  measureWrapper.style.wordBreak = "break-all";
74
- measureWrapper.style.top = "100%";
58
+ measureWrapper.style.visibility = "hidden";
75
59
 
76
- wrapperRef.current.appendChild(measureWrapper);
77
- const range = document.createRange();
78
- range.setStart(measureWrapper.firstChild!, 0);
79
- range.setEnd(measureWrapper.firstChild!, text.length);
80
- const rects = range.getClientRects();
81
- if (rects.length > maxLine) {
82
- setShowExtra(true);
83
- } else {
84
- setShowExtra(false);
85
- }
60
+ document.body.appendChild(measureWrapper);
61
+
62
+ const lineHeight =
63
+ parseInt(getComputedStyle(measureWrapper).lineHeight) || 20;
64
+ const height = measureWrapper.offsetHeight;
65
+ const lines = Math.round(height / lineHeight);
66
+
67
+ document.body.removeChild(measureWrapper);
86
68
 
87
- wrapperRef.current.removeChild(measureWrapper);
88
- }, [maxLine, text]);
69
+ setShowExtra(lines > maxLine);
70
+ };
71
+
72
+ useLayoutEffect(() => {
73
+ if (isValidText) {
74
+ checkTextOverflow();
75
+ }
76
+ }, [maxLine, text, isValidText]);
89
77
  return (
90
78
  <True condition={isValidText}>
91
79
  <div
92
80
  ref={wrapperRef}
93
81
  style={{
94
82
  overflow: "hidden",
95
- position: "relative",
96
83
  width: "100%",
97
84
  display: "flex",
98
85
  ...wrapperStyle,