react-clean-paste 0.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.
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ interface SmartPasteOptions {
4
+ stripHtml?: boolean;
5
+ normalizeWhitespace?: boolean;
6
+ cleanBullets?: boolean;
7
+ fixQuotes?: boolean;
8
+ trim?: boolean;
9
+ }
10
+
11
+ declare const useSmartPaste: (onPasteCleaned: (cleanText: string) => void, options?: SmartPasteOptions) => {
12
+ onPaste: (e: React.ClipboardEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
13
+ };
14
+
15
+ declare function sanitize(text: string, opts?: SmartPasteOptions): string;
16
+
17
+ export { type SmartPasteOptions, sanitize, useSmartPaste };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ interface SmartPasteOptions {
4
+ stripHtml?: boolean;
5
+ normalizeWhitespace?: boolean;
6
+ cleanBullets?: boolean;
7
+ fixQuotes?: boolean;
8
+ trim?: boolean;
9
+ }
10
+
11
+ declare const useSmartPaste: (onPasteCleaned: (cleanText: string) => void, options?: SmartPasteOptions) => {
12
+ onPaste: (e: React.ClipboardEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
13
+ };
14
+
15
+ declare function sanitize(text: string, opts?: SmartPasteOptions): string;
16
+
17
+ export { type SmartPasteOptions, sanitize, useSmartPaste };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var u=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},f=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of c(e))!p.call(t,a)&&a!==r&&s(t,a,{get:()=>e[a],enumerable:!(i=m(e,a))||i.enumerable});return t};var g=t=>f(s({},"__esModule",{value:!0}),t);var S={};u(S,{sanitize:()=>n,useSmartPaste:()=>H});module.exports=g(S);var o=require("react");var x=t=>t.replace(/<\/?[^>]+(>|$)/g,""),P=t=>t.replace(/[“”]/g,'"').replace(/[‘’]/g,"'"),h=t=>t.replace(/\s+/g," ").trim(),z=t=>t.replace(/[•●▪]/g,"-").replace(/-\s*/g,"- ");function n(t,e){let r=t;return e?.stripHtml&&(r=x(r)),e?.fixQuotes&&(r=P(r)),e?.normalizeWhitespace&&(r=h(r)),e?.cleanBullets&&(r=z(r)),e?.trim&&(r=r.trim()),r}var H=(t,e)=>({onPaste:(0,o.useCallback)(i=>{i.preventDefault();let a=i.clipboardData.getData("text"),l=n(a,{stripHtml:!0,normalizeWhitespace:!0,cleanBullets:!0,fixQuotes:!0,trim:!0,...e});t(l)},[t,e])});0&&(module.exports={sanitize,useSmartPaste});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/useSmartPaste.ts","../src/sanitize.ts"],"sourcesContent":["export * from \"./useSmartPaste\";\r\nexport * from \"./sanitize\";\r\nexport * from \"./types\";\r\n","import React, { useCallback } from \"react\";\r\n\r\nimport { SmartPasteOptions } from \"./types\";\r\nimport { sanitize } from \"./sanitize\";\r\n\r\nexport const useSmartPaste = (\r\n onPasteCleaned: (cleanText: string) => void,\r\n options?: SmartPasteOptions\r\n) => {\r\n const handlePaste = useCallback(\r\n (e: React.ClipboardEvent<HTMLTextAreaElement | HTMLInputElement>) => {\r\n e.preventDefault();\r\n\r\n const raw = e.clipboardData.getData(\"text\");\r\n const clean = sanitize(raw, {\r\n stripHtml: true,\r\n normalizeWhitespace: true,\r\n cleanBullets: true,\r\n fixQuotes: true,\r\n trim: true,\r\n ...options\r\n });\r\n\r\n onPasteCleaned(clean);\r\n },\r\n [onPasteCleaned, options]\r\n );\r\n\r\n return { onPaste: handlePaste };\r\n};\r\n","import { SmartPasteOptions } from \"./types\";\r\n\r\nconst stripHtml = (t: string) =>\r\n t.replace(/<\\/?[^>]+(>|$)/g, \"\");\r\n\r\nconst fixQuotes = (t: string) =>\r\n t.replace(/[“”]/g, '\"').replace(/[‘’]/g, \"'\");\r\n\r\nconst normalizeWhitespace = (t: string) =>\r\n t.replace(/\\s+/g, \" \").trim();\r\n\r\nconst cleanBullets = (text: string) =>\r\n text\r\n .replace(/[•●▪]/g, \"-\")\r\n .replace(/-\\s*/g, \"- \");\r\n\r\n\r\nexport function sanitize(text: string, opts?: SmartPasteOptions) {\r\n let out = text;\r\n\r\n if (opts?.stripHtml) out = stripHtml(out);\r\n if (opts?.fixQuotes) out = fixQuotes(out);\r\n if (opts?.normalizeWhitespace) out = normalizeWhitespace(out);\r\n if (opts?.cleanBullets) out = cleanBullets(out);\r\n if (opts?.trim) out = out.trim();\r\n\r\n return out;\r\n}\r\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,EAAA,kBAAAC,IAAA,eAAAC,EAAAJ,GCAA,IAAAK,EAAmC,iBCEnC,IAAMC,EAAa,GACf,EAAE,QAAQ,kBAAmB,EAAE,EAE7BC,EAAa,GACf,EAAE,QAAQ,QAAS,GAAG,EAAE,QAAQ,QAAS,GAAG,EAE1CC,EAAuB,GACzB,EAAE,QAAQ,OAAQ,GAAG,EAAE,KAAK,EAE1BC,EAAgBC,GAClBA,EACK,QAAQ,SAAU,GAAG,EACrB,QAAQ,QAAS,IAAI,EAGvB,SAASC,EAASD,EAAcE,EAA0B,CAC7D,IAAIC,EAAMH,EAEV,OAAIE,GAAM,YAAWC,EAAMP,EAAUO,CAAG,GACpCD,GAAM,YAAWC,EAAMN,EAAUM,CAAG,GACpCD,GAAM,sBAAqBC,EAAML,EAAoBK,CAAG,GACxDD,GAAM,eAAcC,EAAMJ,EAAaI,CAAG,GAC1CD,GAAM,OAAMC,EAAMA,EAAI,KAAK,GAExBA,CACX,CDtBO,IAAMC,EAAgB,CAC3BC,EACAC,KAqBO,CAAE,WAnBW,eACjBC,GAAoE,CACnEA,EAAE,eAAe,EAEjB,IAAMC,EAAMD,EAAE,cAAc,QAAQ,MAAM,EACpCE,EAAQC,EAASF,EAAK,CAC1B,UAAW,GACX,oBAAqB,GACrB,aAAc,GACd,UAAW,GACX,KAAM,GACN,GAAGF,CACL,CAAC,EAEDD,EAAeI,CAAK,CACtB,EACA,CAACJ,EAAgBC,CAAO,CAC1B,CAE8B","names":["index_exports","__export","sanitize","useSmartPaste","__toCommonJS","import_react","stripHtml","fixQuotes","normalizeWhitespace","cleanBullets","text","sanitize","opts","out","useSmartPaste","onPasteCleaned","options","e","raw","clean","sanitize"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{useCallback as p}from"react";var o=t=>t.replace(/<\/?[^>]+(>|$)/g,""),l=t=>t.replace(/[“”]/g,'"').replace(/[‘’]/g,"'"),m=t=>t.replace(/\s+/g," ").trim(),c=t=>t.replace(/[•●▪]/g,"-").replace(/-\s*/g,"- ");function i(t,r){let e=t;return r?.stripHtml&&(e=o(e)),r?.fixQuotes&&(e=l(e)),r?.normalizeWhitespace&&(e=m(e)),r?.cleanBullets&&(e=c(e)),r?.trim&&(e=e.trim()),e}var P=(t,r)=>({onPaste:p(a=>{a.preventDefault();let s=a.clipboardData.getData("text"),n=i(s,{stripHtml:!0,normalizeWhitespace:!0,cleanBullets:!0,fixQuotes:!0,trim:!0,...r});t(n)},[t,r])});export{i as sanitize,P as useSmartPaste};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useSmartPaste.ts","../src/sanitize.ts"],"sourcesContent":["import React, { useCallback } from \"react\";\r\n\r\nimport { SmartPasteOptions } from \"./types\";\r\nimport { sanitize } from \"./sanitize\";\r\n\r\nexport const useSmartPaste = (\r\n onPasteCleaned: (cleanText: string) => void,\r\n options?: SmartPasteOptions\r\n) => {\r\n const handlePaste = useCallback(\r\n (e: React.ClipboardEvent<HTMLTextAreaElement | HTMLInputElement>) => {\r\n e.preventDefault();\r\n\r\n const raw = e.clipboardData.getData(\"text\");\r\n const clean = sanitize(raw, {\r\n stripHtml: true,\r\n normalizeWhitespace: true,\r\n cleanBullets: true,\r\n fixQuotes: true,\r\n trim: true,\r\n ...options\r\n });\r\n\r\n onPasteCleaned(clean);\r\n },\r\n [onPasteCleaned, options]\r\n );\r\n\r\n return { onPaste: handlePaste };\r\n};\r\n","import { SmartPasteOptions } from \"./types\";\r\n\r\nconst stripHtml = (t: string) =>\r\n t.replace(/<\\/?[^>]+(>|$)/g, \"\");\r\n\r\nconst fixQuotes = (t: string) =>\r\n t.replace(/[“”]/g, '\"').replace(/[‘’]/g, \"'\");\r\n\r\nconst normalizeWhitespace = (t: string) =>\r\n t.replace(/\\s+/g, \" \").trim();\r\n\r\nconst cleanBullets = (text: string) =>\r\n text\r\n .replace(/[•●▪]/g, \"-\")\r\n .replace(/-\\s*/g, \"- \");\r\n\r\n\r\nexport function sanitize(text: string, opts?: SmartPasteOptions) {\r\n let out = text;\r\n\r\n if (opts?.stripHtml) out = stripHtml(out);\r\n if (opts?.fixQuotes) out = fixQuotes(out);\r\n if (opts?.normalizeWhitespace) out = normalizeWhitespace(out);\r\n if (opts?.cleanBullets) out = cleanBullets(out);\r\n if (opts?.trim) out = out.trim();\r\n\r\n return out;\r\n}\r\n"],"mappings":"AAAA,OAAgB,eAAAA,MAAmB,QCEnC,IAAMC,EAAa,GACf,EAAE,QAAQ,kBAAmB,EAAE,EAE7BC,EAAa,GACf,EAAE,QAAQ,QAAS,GAAG,EAAE,QAAQ,QAAS,GAAG,EAE1CC,EAAuB,GACzB,EAAE,QAAQ,OAAQ,GAAG,EAAE,KAAK,EAE1BC,EAAgBC,GAClBA,EACK,QAAQ,SAAU,GAAG,EACrB,QAAQ,QAAS,IAAI,EAGvB,SAASC,EAASD,EAAcE,EAA0B,CAC7D,IAAIC,EAAMH,EAEV,OAAIE,GAAM,YAAWC,EAAMP,EAAUO,CAAG,GACpCD,GAAM,YAAWC,EAAMN,EAAUM,CAAG,GACpCD,GAAM,sBAAqBC,EAAML,EAAoBK,CAAG,GACxDD,GAAM,eAAcC,EAAMJ,EAAaI,CAAG,GAC1CD,GAAM,OAAMC,EAAMA,EAAI,KAAK,GAExBA,CACX,CDtBO,IAAMC,EAAgB,CAC3BC,EACAC,KAqBO,CAAE,QAnBWC,EACjBC,GAAoE,CACnEA,EAAE,eAAe,EAEjB,IAAMC,EAAMD,EAAE,cAAc,QAAQ,MAAM,EACpCE,EAAQC,EAASF,EAAK,CAC1B,UAAW,GACX,oBAAqB,GACrB,aAAc,GACd,UAAW,GACX,KAAM,GACN,GAAGH,CACL,CAAC,EAEDD,EAAeK,CAAK,CACtB,EACA,CAACL,EAAgBC,CAAO,CAC1B,CAE8B","names":["useCallback","stripHtml","fixQuotes","normalizeWhitespace","cleanBullets","text","sanitize","opts","out","useSmartPaste","onPasteCleaned","options","useCallback","e","raw","clean","sanitize"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "react-clean-paste",
3
+ "version": "0.0.1",
4
+ "description": "A tiny 0-dependency React hook that automatically cleans, sanitizes, and formats pasted text.",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "author": "",
12
+ "license": "MIT",
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "peerDependencies": {
18
+ "react": ">=17"
19
+ },
20
+ "devDependencies": {
21
+ "@types/react": "^19.2.10",
22
+ "tsup": "^8.0.0",
23
+ "typescript": "^5.0.0",
24
+ "vitest": "^4.0.18"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "keywords": [
30
+ "paste",
31
+ "clean",
32
+ "sanitize",
33
+ "clipboard",
34
+ "react",
35
+ "react-hook",
36
+ "input",
37
+ "text",
38
+ "html-clean",
39
+ "form",
40
+ "sanitize-text",
41
+ "clean-text"
42
+ ]
43
+ }
package/readme.md ADDED
@@ -0,0 +1,86 @@
1
+ # react-clean-paste
2
+
3
+ A tiny 0-dependency React hook that automatically cleans, formats, and sanitizes pasted text.
4
+
5
+ Users paste messy content from Word, Google Docs, emails, WhatsApp, PDFs, and more.
6
+ react-clean-paste fixes all of it instantly with one hook.
7
+
8
+ ## ✨ Features
9
+
10
+ - Remove HTML tags
11
+ - Normalize whitespace
12
+ - Convert bullets (• ● ▪) → "-"
13
+ - Fix smart quotes → normal quotes
14
+ - Trim spacing
15
+ - Fully typed (TypeScript)
16
+ - Zero dependencies
17
+ - Works with Formik, React Hook Form, Zod & any input or textarea
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install react-clean-paste
23
+ ```
24
+
25
+ ## 🚀 Quick Usage
26
+
27
+ ```tsx
28
+ import { useState } from "react";
29
+ import { useSmartPaste } from "react-clean-paste";
30
+
31
+ export default function App() {
32
+ const [value, setValue] = useState("");
33
+
34
+ const pasteHandler = useSmartPaste((cleaned) => {
35
+ setValue(cleaned);
36
+ });
37
+
38
+ return (
39
+ <textarea
40
+ {...pasteHandler}
41
+ value={value}
42
+ onChange={(e) => setValue(e.target.value)}
43
+ placeholder="Paste anything here..."
44
+ rows={6}
45
+ />
46
+ );
47
+ }
48
+ ```
49
+
50
+ ## ⚙️ Options
51
+
52
+ ```tsx
53
+ useSmartPaste((cleaned) => console.log(cleaned), {
54
+ stripHtml: true,
55
+ normalizeWhitespace: true,
56
+ cleanBullets: true,
57
+ fixQuotes: true,
58
+ trim: true
59
+ });
60
+ ```
61
+
62
+ ### Options Table
63
+
64
+ | Option | Type | Default | Description |
65
+ | ------------------- | ------- | ------- | ---------------------------------------- |
66
+ | stripHtml | boolean | true | Removes HTML tags |
67
+ | fixQuotes | boolean | true | Convert smart quotes to normal quotes |
68
+ | cleanBullets | boolean | true | Converts • ● ▪ → "-" |
69
+ | normalizeWhitespace | boolean | true | Cleans weird spacing, tabs & line breaks |
70
+ | trim | boolean | true | Trim leading & trailing spaces |
71
+
72
+ ## 🧹 Manual Sanitization (without React)
73
+
74
+ ```tsx
75
+ import { sanitize } from "react-clean-paste";
76
+
77
+ sanitize("<b>Hello</b>", { stripHtml: true });
78
+ // => "Hello"
79
+
80
+ sanitize("• One ● Two ▪ Three", { cleanBullets: true });
81
+ // => "- One - Two - Three"
82
+ ```
83
+
84
+ ## 📄 License
85
+
86
+ MIT