@typix-editor/extension-max-length 1.0.0 → 1.0.1
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/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var w=Object.defineProperty;var
|
|
2
|
+
var w=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var z=(t,n)=>{for(var o in n)w(t,o,{get:n[o],enumerable:!0})},A=(t,n,o,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of W(n))!B.call(t,i)&&i!==o&&w(t,i,{get:()=>n[i],enumerable:!(s=P(n,i))||s.enumerable});return t};var G=t=>A(w({},"__esModule",{value:!0}),t);var j={};z(j,{MaxLengthExtension:()=>S});module.exports=G(j);var I=require("@lexical/react/LexicalComposerContext"),y=require("@lexical/selection"),$=require("@lexical/utils"),g=require("lexical"),u=require("react");function N(t,n,o){switch(o||(t=t.replace(/\s/g,"")),n){case"words":return t.trim().split(/\s+/).filter(s=>s.length>0).length;case"bytes":return new Blob([t]).size;default:if(typeof Intl<"u"&&"Segmenter"in Intl)try{return[...new Intl.Segmenter().segment(t)].length}catch{console.warn("Intl.Segmenter not available, using fallback")}return U(t)}}function U(t){let n=t.match(/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g);return n?n.length:0}function S({maxLength:t,mode:n="characters",onLimitReached:o,onChange:s,warningThreshold:i=.9,onWarning:f,strategy:l="prevent",countWhitespace:p=!0,customCounter:d,debug:b=!1}){let[m]=(0,I.useLexicalComposerContext)(),L=(0,u.useRef)(null),h=(0,u.useRef)(!1),C=(0,u.useRef)({maxLength:t,mode:n,onLimitReached:o,onChange:s,warningThreshold:i,onWarning:f,strategy:l,countWhitespace:p,customCounter:d,debug:b});(0,u.useEffect)(()=>{C.current={maxLength:t,mode:n,onLimitReached:o,onChange:s,warningThreshold:i,onWarning:f,strategy:l,countWhitespace:p,customCounter:d,debug:b}},[t,n,o,s,i,f,l,p,d,b]);let c=(0,u.useCallback)((...F)=>{C.current.debug&&console.log("[MaxLength]",...F)},[]);return(0,u.useEffect)(()=>{c("Registering max length extension",{maxLength:t,mode:n,strategy:l});let F=m.registerNodeTransform(g.RootNode,M=>{let E=(0,g.$getSelection)();if(!(0,g.$isRangeSelection)(E)||!E.isCollapsed())return;let e=C.current,x=m.getEditorState(),T=M.getTextContent(),r=e.customCounter?e.customCounter(T):N(T,e.mode,e.countWhitespace),D=x.read(()=>M.getTextContent()),R=e.customCounter?e.customCounter(D):N(D,e.mode,e.countWhitespace);if(c("Content length",{current:r,previous:R,max:e.maxLength}),r!==R&&e.onChange){let a=e.maxLength-r;e.onChange(r,e.maxLength,a)}let v=Math.floor(e.maxLength*e.warningThreshold);if(r>=v&&r<e.maxLength&&!h.current&&e.onWarning){h.current=!0;let a=e.maxLength-r;c("Warning threshold reached",{currentLength:r,warningLimit:v}),e.onWarning(r,e.maxLength,a)}if(r<v&&(h.current=!1),r>e.maxLength){let a=r-e.maxLength;c("Limit exceeded",{exceeded:a,strategy:e.strategy}),e.onLimitReached&&e.onLimitReached(r,e.maxLength,a);let k=E.anchor;switch(e.strategy){case"prevent":R===e.maxLength&&L.current!==x?(c("Restoring previous state"),L.current=x,(0,$.$restoreEditorState)(m,x)):(c("Trimming from cursor",{amount:a}),(0,y.$trimTextContentFromAnchor)(m,k,a));break;case"trim":c("Trimming from cursor",{amount:a}),(0,y.$trimTextContentFromAnchor)(m,k,a);break}}});return()=>{c("Unregistering max length extension"),F(),L.current=null,h.current=!1}},[m,c]),null}S.displayName="Typix.MaxLengthExtension";0&&(module.exports={MaxLengthExtension});
|
package/dist/index.d.cts
CHANGED
|
@@ -37,9 +37,8 @@ interface MaxLengthExtensionProps {
|
|
|
37
37
|
* Strategy when limit is exceeded
|
|
38
38
|
* @default 'prevent' - Prevents further input
|
|
39
39
|
* @alternative 'trim' - Trims oldest content
|
|
40
|
-
* @alternative 'truncate' - Truncates from cursor position
|
|
41
40
|
*/
|
|
42
|
-
strategy?: 'prevent' | 'trim'
|
|
41
|
+
strategy?: 'prevent' | 'trim';
|
|
43
42
|
/**
|
|
44
43
|
* Whether to count whitespace
|
|
45
44
|
* @default true
|
package/dist/index.d.ts
CHANGED
|
@@ -37,9 +37,8 @@ interface MaxLengthExtensionProps {
|
|
|
37
37
|
* Strategy when limit is exceeded
|
|
38
38
|
* @default 'prevent' - Prevents further input
|
|
39
39
|
* @alternative 'trim' - Trims oldest content
|
|
40
|
-
* @alternative 'truncate' - Truncates from cursor position
|
|
41
40
|
*/
|
|
42
|
-
strategy?: 'prevent' | 'trim'
|
|
41
|
+
strategy?: 'prevent' | 'trim';
|
|
43
42
|
/**
|
|
44
43
|
* Whether to count whitespace
|
|
45
44
|
* @default true
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import{useLexicalComposerContext as
|
|
2
|
+
import{useLexicalComposerContext as N}from"@lexical/react/LexicalComposerContext";import{$trimTextContentFromAnchor as M}from"@lexical/selection";import{$restoreEditorState as I}from"@lexical/utils";import{$getSelection as $,$isRangeSelection as P,RootNode as W}from"lexical";import{useCallback as B,useEffect as T,useRef as R}from"react";function D(t,o,c){switch(c||(t=t.replace(/\s/g,"")),o){case"words":return t.trim().split(/\s+/).filter(a=>a.length>0).length;case"bytes":return new Blob([t]).size;default:if(typeof Intl<"u"&&"Segmenter"in Intl)try{return[...new Intl.Segmenter().segment(t)].length}catch{console.warn("Intl.Segmenter not available, using fallback")}return z(t)}}function z(t){let o=t.match(/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g);return o?o.length:0}function k({maxLength:t,mode:o="characters",onLimitReached:c,onChange:a,warningThreshold:l=.9,onWarning:h,strategy:u="prevent",countWhitespace:x=!0,customCounter:f,debug:p=!1}){let[i]=N(),d=R(null),m=R(!1),b=R({maxLength:t,mode:o,onLimitReached:c,onChange:a,warningThreshold:l,onWarning:h,strategy:u,countWhitespace:x,customCounter:f,debug:p});T(()=>{b.current={maxLength:t,mode:o,onLimitReached:c,onChange:a,warningThreshold:l,onWarning:h,strategy:u,countWhitespace:x,customCounter:f,debug:p}},[t,o,c,a,l,h,u,x,f,p]);let s=B((...L)=>{b.current.debug&&console.log("[MaxLength]",...L)},[]);return T(()=>{s("Registering max length extension",{maxLength:t,mode:o,strategy:u});let L=i.registerNodeTransform(W,v=>{let C=$();if(!P(C)||!C.isCollapsed())return;let e=b.current,g=i.getEditorState(),w=v.getTextContent(),n=e.customCounter?e.customCounter(w):D(w,e.mode,e.countWhitespace),y=g.read(()=>v.getTextContent()),F=e.customCounter?e.customCounter(y):D(y,e.mode,e.countWhitespace);if(s("Content length",{current:n,previous:F,max:e.maxLength}),n!==F&&e.onChange){let r=e.maxLength-n;e.onChange(n,e.maxLength,r)}let E=Math.floor(e.maxLength*e.warningThreshold);if(n>=E&&n<e.maxLength&&!m.current&&e.onWarning){m.current=!0;let r=e.maxLength-n;s("Warning threshold reached",{currentLength:n,warningLimit:E}),e.onWarning(n,e.maxLength,r)}if(n<E&&(m.current=!1),n>e.maxLength){let r=n-e.maxLength;s("Limit exceeded",{exceeded:r,strategy:e.strategy}),e.onLimitReached&&e.onLimitReached(n,e.maxLength,r);let S=C.anchor;switch(e.strategy){case"prevent":F===e.maxLength&&d.current!==g?(s("Restoring previous state"),d.current=g,I(i,g)):(s("Trimming from cursor",{amount:r}),M(i,S,r));break;case"trim":s("Trimming from cursor",{amount:r}),M(i,S,r);break}}});return()=>{s("Unregistering max length extension"),L(),d.current=null,m.current=!1}},[i,s]),null}k.displayName="Typix.MaxLengthExtension";export{k as MaxLengthExtension};
|