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.
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
- package/readme.md +86 -0
package/dist/index.d.mts
ADDED
|
@@ -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.d.ts
ADDED
|
@@ -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
|