@wwog/react 1.2.13 → 1.2.15

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
@@ -187,6 +187,37 @@ function UserList({ users }) {
187
187
  }
188
188
  ```
189
189
 
190
+ #### `<Clamp>` (v1.2.14+)
191
+
192
+ A component for displaying text with a fixed number of lines, ellipsis, and optional extra content. Highly compatible without using webkit-box or JavaScript tricks.
193
+
194
+ ```tsx
195
+ import { Clamp } from "@wwog/react";
196
+
197
+ function Example() {
198
+ return (
199
+ <Clamp
200
+ text="This is a long text that will be truncated with ellipsis..."
201
+ maxLine={2}
202
+ lineHeight={20}
203
+ ellipsis={true}
204
+ extraContent={<button>See more</button>}
205
+ bgColor="#fff"
206
+ />
207
+ );
208
+ }
209
+ ```
210
+
211
+ - `text`: The text content to be displayed.
212
+ - `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
+ - `extraContent`: Extra content to display at the end of the text, such as a "See more" button.
217
+ - `extraHeight`: Height of the extra content, defaults to 20.
218
+ - `bgColor`: Background color, defaults to white ('#fff').
219
+ - `wrapperStyle`: Style for the wrapper container.
220
+
190
221
  #### `<Pipe>` (v1.1.7+)
191
222
 
192
223
  A declarative data pipeline component for multi-step data transformation and chaining.
package/dist/index.d.mts CHANGED
@@ -372,6 +372,56 @@ interface ToggleProps<T = boolean> {
372
372
  */
373
373
  declare const Toggle: <T>(props: ToggleProps<T>) => React$1.ReactNode;
374
374
 
375
+ interface ClampProps {
376
+ /**
377
+ * @default 20
378
+ */
379
+ lineHeight?: number;
380
+ /**
381
+ * @description 最大行数
382
+ * @description_en maximum number of lines
383
+ * @default 1
384
+ */
385
+ maxLine?: number;
386
+ extraContent?: React$1.ReactNode;
387
+ /**
388
+ * @description 用于控制额外内容的高度,如果出现没有正常显示请调节此属性
389
+ * @description_en used to control the height of the extra content. If it does not display normally, please adjust this property
390
+ * @default 20
391
+ */
392
+ extraHeight?: number;
393
+ /**
394
+ * @description 是否显示省略号
395
+ * @description_en whether to display ellipsis
396
+ */
397
+ ellipsis?: boolean;
398
+ /**
399
+ * @description 替换省略号内容
400
+ * @description_en replace ellipsis content
401
+ * @default '<span>...</span>'
402
+ */
403
+ ellipsisContent?: React$1.ReactNode;
404
+ /**
405
+ * @description 显示的文本
406
+ * @description_en text to be displayed
407
+ */
408
+ text: string;
409
+ /**
410
+ * @description 背景颜色,请不要使用`wrapperStyle`覆盖此设置,因纯兼容性的css方式实现。默认白色
411
+ * @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
412
+ * @default '#fff'
413
+ */
414
+ bgColor?: string;
415
+ wrapperStyle?: React$1.CSSProperties;
416
+ }
417
+ /**
418
+ * @description 用于固定行数,显示省略号且显示额外内容的组件。兼容性非常好,没有用到webkit-box和js。
419
+ * @description_en used to fix the number of lines, display ellipsis and display extra content. The compatibility is very good, without using webkit-box and js.
420
+ * @param props
421
+ * @returns
422
+ */
423
+ declare const Clamp: FC<ClampProps>;
424
+
375
425
  interface ArrayRenderProps<T> {
376
426
  items: T[];
377
427
  renderItem: (item: T, index: number) => React$1.ReactNode;
@@ -570,5 +620,5 @@ declare class Counter {
570
620
 
571
621
  declare const safePromiseTry: <T, U extends unknown[]>(callbackFn: (...args: U) => T | PromiseLike<T>, ...args: U) => Promise<Awaited<T>>;
572
622
 
573
- export { ArrayRender, Counter, DateRender, False, If, Pipe, Scope, SizeBox, Styles, Switch, Toggle, True, When, childrenLoop, createExternalState, cx, formatDate, safePromiseTry, useControlled };
574
- export type { ArrayRenderProps, CreateStateListener, CxInput, DateRenderProps, ElseIfProps, ElseProps, ExternalSideEffect, ExternalState, ExternalWithKernel, FalseProps, IfProps, PipeProps, ScopeProps, StylesDescriptor, StylesProps, StylesType, SwitchCaseProps, SwitchDefaultProps, SwitchProps, ThenProps, ToggleProps, TrueProps, UseControlledOptions, WhenProps };
623
+ export { ArrayRender, Clamp, Counter, DateRender, False, If, Pipe, Scope, SizeBox, Styles, Switch, Toggle, True, When, childrenLoop, createExternalState, cx, formatDate, safePromiseTry, useControlled };
624
+ export type { ArrayRenderProps, ClampProps, CreateStateListener, CxInput, DateRenderProps, ElseIfProps, ElseProps, ExternalSideEffect, ExternalState, ExternalWithKernel, FalseProps, IfProps, PipeProps, ScopeProps, StylesDescriptor, StylesProps, StylesType, SwitchCaseProps, SwitchDefaultProps, SwitchProps, ThenProps, ToggleProps, TrueProps, UseControlledOptions, WhenProps };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import r,{useMemo as h,Children as J,Fragment as S,isValidElement as _,cloneElement as R,useEffect as W,useState as x,useCallback as H}from"react";function C(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 B=(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=B,children:l,strict:o=!1}=t,a=new Set;let s=null,i=null,u=!1;return C(l,(c,d)=>{if(!r.isValidElement(c))throw new Error(`Switch Children only accepts valid React elements at index ${d}`);const m=c.type;if(m.displayName===E.displayName){const f=c.props;if(a.has(f.value))throw new Error(`Switch found duplicate Case value at index ${d}: ${JSON.stringify(f.value)}${o?" (detected in strict mode)":""}`);if(a.add(f.value),!s&&e(n,f.value)&&(s=f.children,o===!1))return!1}else if(m.displayName===w.displayName){if(u)throw new Error(`Switch can only have one Default child at index ${d}`);if(u=!0,i=c.props.children,!o&&s)return!1}else throw new Error(`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(m.displayName||m.name||m)} at index ${d}`)}),r.createElement(r.Fragment,null,s??i)};y.displayName="Switch",y.Case=E,y.Default=w,y.createTyped=function(){return{Switch:y,Case:E,Default:w}};const N=t=>r.createElement(r.Fragment,null,t.children),v=({children:t})=>r.createElement(r.Fragment,null,t),F=t=>r.createElement(r.Fragment,null,t.children);N.displayName="If_Then",v.displayName="If_Else",F.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 s=a.type;if(s.displayName===N.displayName){if(e)throw new Error("If component can only have one Then child");e=a}else if(s.displayName===F.displayName)o.push(a);else if(s.displayName===v.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(s.displayName||s.name||s)}`)}),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=N,p.ElseIf=F,p.Else=v,p.createTyped=function(){return{If:p,Then:N,ElseIf:F,Else:v}};const V=({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,z=({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),L=({data:t,transform:n,render:e,fallback:l})=>{const o=h(()=>n.reduce((a,s)=>s(a),t),[t,n]);return o==null?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(o))},G=t=>{const{children:n,h:e,w:l,size:o,height:a,width:s,className:i}=t;return r.createElement("div",{style:{width:o||l||s,height:o||e||a,flexShrink:0},className:i},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 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 K=t=>typeof t=="object"&&!!t,b=({className:t,children:n,asWrapper:e=!1})=>{if(!n)return null;if(J.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(_(n)){const o=n;let a=o?.props?.className;return o?.type?.displayName===b.displayName&&K(a)&&(a=M(...Object.values(a))),R(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)};b.displayName="W/Styles";const Q=t=>{const{index:n=0,options:e,next:l,render:o}=t;W(()=>{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,s]=x(n),i=()=>{s(u=>e.length?l?l(u,e):(u+1)%e.length:u)};return o(e[a],i)};function U(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 X({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 $="onChange",ee="value";function te(t){const{defaultValue:n,onBeforeChange:e,trigger:l=$,valuePropName:o=ee,props:a}=t,s=Object.prototype.hasOwnProperty.call(a,o),[i,u]=x(n),c=s?a[o]:i,d=h(()=>a[l],[a,l]),m=H(f=>{const g=typeof f=="function"?f(c):f;e&&e(g,c)===!1||(s||u(g),d&&d(g))},[s,e,c,d]);return[c,m]}function ne(t,...n){try{const e=t(...n);return e instanceof Promise?e:Promise.resolve(e)}catch(e){return Promise.reject(e)}}const I=typeof Promise.try=="function"?Promise.try.bind(Promise):ne;function re(t,n){let e=typeof t=="function"?t():t;const l=[],o=()=>e,a=i=>{const u=e;e=typeof i=="function"?i():i,l.forEach(c=>c(e)),n&&I(n,e,u).catch(c=>{console.error("Error in external state side effect, Please do it within side effects:",c)})},s=()=>{const[i,u]=r.useState(e);return r.useEffect(()=>(l.push(u),()=>{const c=l.indexOf(u);c>-1&&l.splice(c,1)}),[]),[i,a]};return{get:o,set:a,use:s,useGetter:()=>{const[i]=s();return i},__listeners:l}}function le(t,n){const e=n||new Date,l=e.getFullYear(),o=e.getMonth()+1,a=e.getDate(),s=e.getHours(),i=e.getMinutes(),u=e.getSeconds(),c=e.getMilliseconds(),d=e.getDay(),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],f=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],A=["January","February","March","April","May","June","July","August","September","October","November","December"],P=f[d],D=m[d],T=o-1,Y=A[T],k=g[T],O={YY:l.toString().slice(2),YYYY:l.toString(),M:o.toString(),MM:o.toString().padStart(2,"0"),MMM:k,MMMM:Y,D:a.toString(),DD:a.toString().padStart(2,"0"),d:d.toString(),dd:D,ddd:D,dddd:P,H:s.toString(),HH:s.toString().padStart(2,"0"),h:(s%12).toString(),hh:(s%12).toString().padStart(2,"0"),m:i.toString(),mm:i.toString().padStart(2,"0"),s:u.toString(),ss:u.toString().padStart(2,"0"),SSS:c.toString().padStart(3,"0"),Z:"+08:00",ZZ:"+0800",A:s<12?"AM":"PM",a:s<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=>O[j])}class ae{count=0;next(){return this.count++}}export{U as ArrayRender,ae as Counter,X as DateRender,Z as False,p as If,L as Pipe,q as Scope,G as SizeBox,b as Styles,y as Switch,Q as Toggle,V as True,z as When,C as childrenLoop,re as createExternalState,M as cx,le as formatDate,I as safePromiseTry,te as useControlled};
1
+ import r,{useMemo as p,Children as J,Fragment as S,isValidElement as _,cloneElement as R,useEffect as W,useState as C,useCallback as B}from"react";function T(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 y=t=>{const{value:n,compare:e=V,children:l,strict:a=!1}=t,o=new Set;let i=null,s=null,u=!1;return T(l,(c,d)=>{if(!r.isValidElement(c))throw new Error(`Switch Children only accepts valid React elements at index ${d}`);const m=c.type;if(m.displayName===E.displayName){const f=c.props;if(o.has(f.value))throw new Error(`Switch found duplicate Case value at index ${d}: ${JSON.stringify(f.value)}${a?" (detected in strict mode)":""}`);if(o.add(f.value),!i&&e(n,f.value)&&(i=f.children,a===!1))return!1}else if(m.displayName===w.displayName){if(u)throw new Error(`Switch can only have one Default child at index ${d}`);if(u=!0,s=c.props.children,!a&&i)return!1}else throw new Error(`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(m.displayName||m.name||m)} at index ${d}`)}),r.createElement(r.Fragment,null,i??s)};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 h=({condition:t,children:n})=>{let e=null,l=null;const a=[];if(r.Children.forEach(n,o=>{if(!r.isValidElement(o))throw new Error("If component only accepts valid React elements");const i=o.type;if(i.displayName===v.displayName){if(e)throw new Error("If component can only have one Then child");e=o}else if(i.displayName===b.displayName)a.push(o);else if(i.displayName===N.displayName){if(l)throw new Error("If component can only have one Else child");l=o}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 o of a)if(o.props.condition)return r.createElement(r.Fragment,null,o.props.children);return l?r.createElement(r.Fragment,null,l.props.children):null};h.displayName="If",h.Then=v,h.ElseIf=b,h.Else=N,h.createTyped=function(){return{If:h,Then:v,ElseIf:b,Else:N}};const k=({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,L=({all:t,any:n,none:e,children:l,fallback:a})=>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(o=>!o))),[t,n,e])?r.createElement(r.Fragment,null,l):r.createElement(r.Fragment,null,a||null),z=({data:t,transform:n,render:e,fallback:l})=>{const a=p(()=>n.reduce((o,i)=>i(o),t),[t,n]);return a==null?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(a))},G=t=>{const{children:n,h:e,w:l,size:a,height:o,width:i,className:s}=t;return r.createElement("div",{style:{width:a||l||i,height:a||e||o,flexShrink:0},className:s},n)},$=({let:t,props:n,children:e,fallback:l})=>{const a=p(()=>typeof t=="function"?t(n):t,[t,n]);return!e||!Object.keys(a).length?r.createElement(r.Fragment,null,l||null):r.createElement(r.Fragment,null,e(a))};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,a]of Object.entries(e))a&&n.add(l)}return Array.from(n).join(" ")}const q=t=>typeof t=="object"&&!!t,M=({className:t,children:n,asWrapper:e=!1})=>{if(!n)return null;if(J.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(_(n)){const a=n;let o=a?.props?.className;return a?.type?.displayName===M.displayName&&q(o)&&(o=F(...Object.values(o))),R(n,{className:F(l,o)})}return console.error("<Styles>: children is not a valid React element. Please check your code."),r.createElement(S,null,n)};M.displayName="W/Styles";const K=t=>{const{index:n=0,options:e,next:l,render:a}=t;W(()=>{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[o,i]=C(n),s=()=>{i(u=>e.length?l?l(u,e):(u+1)%e.length:u)};return a(e[o],s)},Q=t=>{const{lineHeight:n=20,maxLine:e=1,text:l,extraHeight:a=20,extraContent:o,bgColor:i="#fff",ellipsis:s=!1,ellipsisContent:u=r.createElement("span",null,"\u2026"),wrapperStyle:c}=t;return r.createElement("div",{style:{display:"flex",overflow:"hidden",position:"relative",background:i,...c}},r.createElement("div",{style:{lineHeight:`${n}px`,maxHeight:`${n*e}px`,overflow:"hidden",wordBreak:"break-all"}},r.createElement("div",{style:{float:"right",height:`calc(100% - ${a-2}px)`}}),r.createElement("div",{style:{float:"right",clear:"both",height:a}},r.createElement(k,{condition:s},u),o),l,r.createElement("div",{style:{display:"inline-block",width:"100%",height:"100%",position:"absolute",background:i}})))};function U(t){const{items:n,renderItem:e,filter:l}=t;return n?r.createElement(S,null,n.map((a,o)=>l&&!l(a)?null:e(a,o))):(console.error("ArrayRender: items is null"),null)}function X({source:t,format:n,children:e}){const l=p(()=>{if(t instanceof Date)return t;if(typeof t=="string"||typeof t=="number"){const o=new Date(t);return isNaN(o.getTime())?null:o}return null},[t]),a=p(()=>l?n?n(l):l.toLocaleString():null,[l,n]);return!a||!e?null:r.createElement(r.Fragment,null,e(a))}const ee="onChange",te="value";function ne(t){const{defaultValue:n,onBeforeChange:e,trigger:l=ee,valuePropName:a=te,props:o}=t,i=Object.prototype.hasOwnProperty.call(o,a),[s,u]=C(n),c=i?o[a]:s,d=p(()=>o[l],[o,l]),m=B(f=>{const g=typeof f=="function"?f(c):f;e&&e(g,c)===!1||(i||u(g),d&&d(g))},[i,e,c,d]);return[c,m]}function re(t,...n){try{const e=t(...n);return e instanceof Promise?e:Promise.resolve(e)}catch(e){return Promise.reject(e)}}const I=typeof Promise.try=="function"?Promise.try.bind(Promise):re;function le(t,n){let e=typeof t=="function"?t():t;const l=[],a=()=>e,o=s=>{const u=e;e=typeof s=="function"?s():s,l.forEach(c=>c(e)),n&&I(n,e,u).catch(c=>{console.error("Error in external state side effect, Please do it within side effects:",c)})},i=()=>{const[s,u]=r.useState(e);return r.useEffect(()=>(l.push(u),()=>{const c=l.indexOf(u);c>-1&&l.splice(c,1)}),[]),[s,o]};return{get:a,set:o,use:i,useGetter:()=>{const[s]=i();return s},__listeners:l}}function ae(t,n){const e=n||new Date,l=e.getFullYear(),a=e.getMonth()+1,o=e.getDate(),i=e.getHours(),s=e.getMinutes(),u=e.getSeconds(),c=e.getMilliseconds(),d=e.getDay(),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],f=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],A=["January","February","March","April","May","June","July","August","September","October","November","December"],P=f[d],x=m[d],D=a-1,Y=A[D],O=g[D],j={YY:l.toString().slice(2),YYYY:l.toString(),M:a.toString(),MM:a.toString().padStart(2,"0"),MMM:O,MMMM:Y,D:o.toString(),DD:o.toString().padStart(2,"0"),d:d.toString(),dd:x,ddd:x,dddd:P,H:i.toString(),HH:i.toString().padStart(2,"0"),h:(i%12).toString(),hh:(i%12).toString().padStart(2,"0"),m:s.toString(),mm:s.toString().padStart(2,"0"),s:u.toString(),ss:u.toString().padStart(2,"0"),SSS:c.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,H=>j[H])}class oe{count=0;next(){return this.count++}}export{U as ArrayRender,Q as Clamp,oe as Counter,X as DateRender,Z as False,h as If,z as Pipe,$ as Scope,G as SizeBox,M as Styles,y as Switch,K as Toggle,k as True,L as When,T as childrenLoop,le as createExternalState,F as cx,ae as formatDate,I as safePromiseTry,ne as useControlled};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wwog/react",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
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",
@@ -50,5 +50,5 @@
50
50
  "node": ">= 20.0.0",
51
51
  "pnpm": ">=8.15.0"
52
52
  },
53
- "packageManager": "pnpm@9.15.1+sha512.1acb565e6193efbebda772702950469150cf12bcc764262e7587e71d19dc98a423dff9536e57ea44c49bdf790ff694e83c27be5faa23d67e0c033b583be4bfcf"
53
+ "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
54
54
  }
@@ -0,0 +1,112 @@
1
+ import React, { FC } from "react";
2
+ import { True } from "../ProcessControl/If";
3
+
4
+ export interface ClampProps {
5
+ /**
6
+ * @default 20
7
+ */
8
+ lineHeight?: number;
9
+ /**
10
+ * @description 最大行数
11
+ * @description_en maximum number of lines
12
+ * @default 1
13
+ */
14
+ maxLine?: number;
15
+ extraContent?: React.ReactNode;
16
+ /**
17
+ * @description 用于控制额外内容的高度,如果出现没有正常显示请调节此属性
18
+ * @description_en used to control the height of the extra content. If it does not display normally, please adjust this property
19
+ * @default 20
20
+ */
21
+ extraHeight?: number;
22
+ /**
23
+ * @description 是否显示省略号
24
+ * @description_en whether to display ellipsis
25
+ */
26
+ ellipsis?: boolean;
27
+ /**
28
+ * @description 替换省略号内容
29
+ * @description_en replace ellipsis content
30
+ * @default '<span>...</span>'
31
+ */
32
+ ellipsisContent?: React.ReactNode;
33
+ /**
34
+ * @description 显示的文本
35
+ * @description_en text to be displayed
36
+ */
37
+ text: string;
38
+ /**
39
+ * @description 背景颜色,请不要使用`wrapperStyle`覆盖此设置,因纯兼容性的css方式实现。默认白色
40
+ * @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
41
+ * @default '#fff'
42
+ */
43
+ bgColor?: string;
44
+ wrapperStyle?: React.CSSProperties;
45
+ }
46
+
47
+ /**
48
+ * @description 用于固定行数,显示省略号且显示额外内容的组件。兼容性非常好,没有用到webkit-box和js。
49
+ * @description_en used to fix the number of lines, display ellipsis and display extra content. The compatibility is very good, without using webkit-box and js.
50
+ * @param props
51
+ * @returns
52
+ */
53
+ export const Clamp: FC<ClampProps> = (props) => {
54
+ const {
55
+ lineHeight = 20,
56
+ maxLine = 1,
57
+ text,
58
+ extraHeight = 20,
59
+ extraContent,
60
+ bgColor = "#fff",
61
+ ellipsis = false,
62
+ ellipsisContent = <span>&hellip;</span>,
63
+ wrapperStyle,
64
+ } = props;
65
+ return (
66
+ <div
67
+ style={{
68
+ display: "flex",
69
+ overflow: "hidden",
70
+ position: "relative",
71
+ background: bgColor,
72
+ ...wrapperStyle,
73
+ }}
74
+ >
75
+ <div
76
+ style={{
77
+ lineHeight: `${lineHeight}px`,
78
+ maxHeight: `${lineHeight * maxLine}px`,
79
+ overflow: "hidden",
80
+ wordBreak: "break-all"
81
+ }}
82
+ >
83
+ <div
84
+ style={{
85
+ float: "right",
86
+ height: `calc(100% - ${extraHeight - 2}px)`,
87
+ }}
88
+ ></div>
89
+ <div
90
+ style={{
91
+ float: "right",
92
+ clear: "both",
93
+ height: extraHeight,
94
+ }}
95
+ >
96
+ <True condition={ellipsis}>{ellipsisContent}</True>
97
+ {extraContent}
98
+ </div>
99
+ {text}
100
+ <div
101
+ style={{
102
+ display: "inline-block",
103
+ width: "100%",
104
+ height: "100%",
105
+ position: "absolute",
106
+ background: bgColor,
107
+ }}
108
+ ></div>
109
+ </div>
110
+ </div>
111
+ );
112
+ };
@@ -1,4 +1,5 @@
1
- export * from './SizeBox'
2
- export * from './Scope'
3
- export * from './Styles'
4
- export * from './Toggle'
1
+ export * from "./SizeBox";
2
+ export * from "./Scope";
3
+ export * from "./Styles";
4
+ export * from "./Toggle";
5
+ export * from "./Clamp";