pa-floating-window 1.0.0

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 ADDED
@@ -0,0 +1,52 @@
1
+ # pa-floating-window
2
+
3
+ A plug-and-play React floating window widget for feature requests and feedback. Zero configuration, completely unstyled out of the box so it just works!
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install pa-floating-window
9
+ # or
10
+ yarn add pa-floating-window
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Simply import the `FeedbackWidget` into your layout or app root and pass your API endpoint where you want the feedback to be sent.
16
+
17
+ ```tsx
18
+ import { FeedbackWidget } from 'pa-floating-window';
19
+
20
+ export default function App() {
21
+ return (
22
+ <div>
23
+ <h1>My Application</h1>
24
+
25
+ {/* Add the widget anywhere in your dom, it will float automatically */}
26
+ <FeedbackWidget
27
+ apiUrl="https://your-hackbyte-deployment.vercel.app/api/feedback"
28
+ primaryColor="#3b82f6" // Optional: customize the main theme color
29
+ />
30
+ </div>
31
+ );
32
+ }
33
+ ```
34
+
35
+ ## Props
36
+
37
+ | Prop | Type | Default | Description |
38
+ | ---- | ---- | ------- | ----------- |
39
+ | `apiUrl` | string | **Required** | The absolute URL of your REST API to send the `POST` request to. |
40
+ | `primaryColor` | string | `#3b82f6` | Optional hex/rgb value to change the base color of the button and action button. |
41
+
42
+ ## payload structure
43
+
44
+ The widget will send a `POST` request to your `apiUrl` containing the following JSON structure:
45
+
46
+ ```json
47
+ {
48
+ "title": "Dark Mode Support",
49
+ "description": "It would be great if the app had a dark mode.",
50
+ "email": "user@example.com"
51
+ }
52
+ ```
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface FeedbackWidgetProps {
4
+ /**
5
+ * The URL of your API endpoint to send the feedback data to.
6
+ * Example: https://your-domain.com/api/feedback
7
+ */
8
+ apiUrl: string;
9
+ /**
10
+ * Optional primary color for the button and accents.
11
+ * Defaults to a pleasant blue (#3b82f6)
12
+ */
13
+ primaryColor?: string;
14
+ }
15
+ declare function FeedbackWidget({ apiUrl, primaryColor }: FeedbackWidgetProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { FeedbackWidget, type FeedbackWidgetProps };
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface FeedbackWidgetProps {
4
+ /**
5
+ * The URL of your API endpoint to send the feedback data to.
6
+ * Example: https://your-domain.com/api/feedback
7
+ */
8
+ apiUrl: string;
9
+ /**
10
+ * Optional primary color for the button and accents.
11
+ * Defaults to a pleasant blue (#3b82f6)
12
+ */
13
+ primaryColor?: string;
14
+ }
15
+ declare function FeedbackWidget({ apiUrl, primaryColor }: FeedbackWidgetProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { FeedbackWidget, type FeedbackWidgetProps };
package/dist/index.js ADDED
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ FeedbackWidget: () => FeedbackWidget
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+ var import_react = require("react");
27
+ var import_jsx_runtime = require("react/jsx-runtime");
28
+ function FeedbackWidget({ apiUrl, primaryColor = "#3b82f6" }) {
29
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
30
+ const [title, setTitle] = (0, import_react.useState)("");
31
+ const [description, setDescription] = (0, import_react.useState)("");
32
+ const [email, setEmail] = (0, import_react.useState)("");
33
+ const [status, setStatus] = (0, import_react.useState)("idle");
34
+ const handleSubmit = async (e) => {
35
+ e.preventDefault();
36
+ if (!title.trim() || !description.trim() || !email.trim()) return;
37
+ setStatus("loading");
38
+ try {
39
+ const response = await fetch(apiUrl, {
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json" },
42
+ body: JSON.stringify({ title, description, email })
43
+ });
44
+ if (response.ok) {
45
+ setStatus("success");
46
+ setTitle("");
47
+ setDescription("");
48
+ setTimeout(() => {
49
+ setIsOpen(false);
50
+ setStatus("idle");
51
+ }, 2e3);
52
+ } else {
53
+ setStatus("error");
54
+ }
55
+ } catch (error) {
56
+ console.error("Feedback Widget Error:", error);
57
+ setStatus("error");
58
+ }
59
+ };
60
+ const containerStyle = {
61
+ position: "fixed",
62
+ bottom: "24px",
63
+ right: "24px",
64
+ zIndex: 999999,
65
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
66
+ };
67
+ const buttonStyle = {
68
+ backgroundColor: primaryColor,
69
+ color: "white",
70
+ border: "none",
71
+ borderRadius: "9999px",
72
+ padding: "16px",
73
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
74
+ cursor: "pointer",
75
+ display: "flex",
76
+ alignItems: "center",
77
+ gap: "8px",
78
+ fontWeight: 500,
79
+ fontSize: "16px",
80
+ transition: "transform 0.2s ease-in-out"
81
+ };
82
+ const modalStyle = {
83
+ position: "absolute",
84
+ bottom: "80px",
85
+ right: "0",
86
+ width: "384px",
87
+ // w-96 roughly
88
+ backgroundColor: "white",
89
+ borderRadius: "8px",
90
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
91
+ border: "1px solid #e5e7eb",
92
+ padding: "24px",
93
+ boxSizing: "border-box",
94
+ display: isOpen ? "block" : "none"
95
+ };
96
+ const headerStyle = {
97
+ display: "flex",
98
+ justifyContent: "space-between",
99
+ alignItems: "center",
100
+ marginBottom: "16px"
101
+ };
102
+ const labelStyle = {
103
+ display: "block",
104
+ fontSize: "14px",
105
+ fontWeight: 500,
106
+ color: "#374151",
107
+ marginBottom: "4px"
108
+ };
109
+ const inputStyle = {
110
+ width: "100%",
111
+ padding: "8px 12px",
112
+ border: "1px solid #d1d5db",
113
+ borderRadius: "8px",
114
+ fontSize: "14px",
115
+ boxSizing: "border-box",
116
+ outline: "none",
117
+ fontFamily: "inherit",
118
+ marginBottom: "16px"
119
+ };
120
+ const submitBtnStyle = {
121
+ width: "100%",
122
+ backgroundColor: primaryColor,
123
+ color: "white",
124
+ fontWeight: 500,
125
+ padding: "8px 16px",
126
+ borderRadius: "8px",
127
+ border: "none",
128
+ cursor: status === "loading" ? "not-allowed" : "pointer",
129
+ fontSize: "16px",
130
+ opacity: status === "loading" ? 0.7 : 1
131
+ };
132
+ const statusMsgStyle = {
133
+ fontSize: "14px",
134
+ marginTop: "12px",
135
+ textAlign: "center",
136
+ color: status === "success" ? "#10b981" : "#ef4444",
137
+ display: status === "success" || status === "error" ? "block" : "none"
138
+ };
139
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: containerStyle, children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: modalStyle, children: [
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: headerStyle, children: [
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: 0, fontSize: "18px", fontWeight: 600, color: "#1f2937" }, children: "Submit Feature Request" }),
143
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
144
+ "button",
145
+ {
146
+ onClick: () => setIsOpen(false),
147
+ style: { background: "none", border: "none", cursor: "pointer", color: "#9ca3af" },
148
+ "aria-label": "Close",
149
+ type: "button",
150
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
151
+ }
152
+ )
153
+ ] }),
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: labelStyle, children: "Feature Title" }),
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
158
+ "input",
159
+ {
160
+ type: "text",
161
+ required: true,
162
+ value: title,
163
+ onChange: (e) => setTitle(e.target.value),
164
+ placeholder: "Enter feature title",
165
+ style: inputStyle
166
+ }
167
+ )
168
+ ] }),
169
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
170
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: labelStyle, children: "Description" }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
172
+ "textarea",
173
+ {
174
+ required: true,
175
+ rows: 3,
176
+ value: description,
177
+ onChange: (e) => setDescription(e.target.value),
178
+ placeholder: "Describe the feature you'd like to see...",
179
+ style: { ...inputStyle, resize: "none" }
180
+ }
181
+ )
182
+ ] }),
183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
184
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: labelStyle, children: "Enter your Email ID" }),
185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
186
+ "input",
187
+ {
188
+ type: "email",
189
+ required: true,
190
+ value: email,
191
+ onChange: (e) => setEmail(e.target.value),
192
+ placeholder: "Please enter your email ID",
193
+ style: inputStyle
194
+ }
195
+ )
196
+ ] }),
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", disabled: status === "loading", style: submitBtnStyle, children: status === "loading" ? "Submitting..." : "Submit Request" }),
198
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: statusMsgStyle, children: status === "success" ? "Thank you for your feedback!" : "Something went wrong. Please try again." })
199
+ ] })
200
+ ] }),
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => setIsOpen(!isOpen), style: buttonStyle, children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }),
203
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { display: "inline" }, children: "Request Feature" })
204
+ ] }) })
205
+ ] });
206
+ }
207
+ // Annotate the CommonJS export names for ESM import in node:
208
+ 0 && (module.exports = {
209
+ FeedbackWidget
210
+ });
211
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import React, { useState, CSSProperties, FormEvent } from \"react\";\n\nexport interface FeedbackWidgetProps {\n /**\n * The URL of your API endpoint to send the feedback data to.\n * Example: https://your-domain.com/api/feedback\n */\n apiUrl: string;\n /**\n * Optional primary color for the button and accents. \n * Defaults to a pleasant blue (#3b82f6)\n */\n primaryColor?: string;\n}\n\nexport function FeedbackWidget({ apiUrl, primaryColor = \"#3b82f6\" }: FeedbackWidgetProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [title, setTitle] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n \n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"success\" | \"error\">(\"idle\");\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!title.trim() || !description.trim() || !email.trim()) return;\n\n setStatus(\"loading\");\n\n try {\n const response = await fetch(apiUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ title, description, email }),\n });\n\n if (response.ok) {\n setStatus(\"success\");\n setTitle(\"\");\n setDescription(\"\");\n // Auto-close after a success\n setTimeout(() => {\n setIsOpen(false);\n setStatus(\"idle\");\n }, 2000);\n } else {\n setStatus(\"error\");\n }\n } catch (error) {\n console.error(\"Feedback Widget Error:\", error);\n setStatus(\"error\");\n }\n };\n\n // --- Styles ---\n const containerStyle: CSSProperties = {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n zIndex: 999999,\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n };\n\n const buttonStyle: CSSProperties = {\n backgroundColor: primaryColor,\n color: \"white\",\n border: \"none\",\n borderRadius: \"9999px\",\n padding: \"16px\",\n boxShadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n fontWeight: 500,\n fontSize: \"16px\",\n transition: \"transform 0.2s ease-in-out\",\n };\n\n const modalStyle: CSSProperties = {\n position: \"absolute\",\n bottom: \"80px\",\n right: \"0\",\n width: \"384px\", // w-96 roughly\n backgroundColor: \"white\",\n borderRadius: \"8px\",\n boxShadow: \"0 25px 50px -12px rgba(0, 0, 0, 0.25)\",\n border: \"1px solid #e5e7eb\",\n padding: \"24px\",\n boxSizing: \"border-box\",\n display: isOpen ? \"block\" : \"none\",\n };\n\n const headerStyle: CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"16px\",\n };\n\n const labelStyle: CSSProperties = {\n display: \"block\",\n fontSize: \"14px\",\n fontWeight: 500,\n color: \"#374151\",\n marginBottom: \"4px\",\n };\n\n const inputStyle: CSSProperties = {\n width: \"100%\",\n padding: \"8px 12px\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n fontFamily: \"inherit\",\n marginBottom: \"16px\",\n };\n\n const submitBtnStyle: CSSProperties = {\n width: \"100%\",\n backgroundColor: primaryColor,\n color: \"white\",\n fontWeight: 500,\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: status === \"loading\" ? \"not-allowed\" : \"pointer\",\n fontSize: \"16px\",\n opacity: status === \"loading\" ? 0.7 : 1,\n };\n\n const statusMsgStyle: CSSProperties = {\n fontSize: \"14px\",\n marginTop: \"12px\",\n textAlign: \"center\",\n color: status === \"success\" ? \"#10b981\" : \"#ef4444\",\n display: status === \"success\" || status === \"error\" ? \"block\" : \"none\",\n };\n\n return (\n <div style={containerStyle}>\n <div style={modalStyle}>\n <div style={headerStyle}>\n <h3 style={{ margin: 0, fontSize: \"18px\", fontWeight: 600, color: \"#1f2937\" }}>\n Submit Feature Request\n </h3>\n <button\n onClick={() => setIsOpen(false)}\n style={{ background: \"none\", border: \"none\", cursor: \"pointer\", color: \"#9ca3af\" }}\n aria-label=\"Close\"\n type=\"button\"\n >\n <svg width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <form onSubmit={handleSubmit}>\n <div>\n <label style={labelStyle}>Feature Title</label>\n <input\n type=\"text\"\n required\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Enter feature title\"\n style={inputStyle}\n />\n </div>\n\n <div>\n <label style={labelStyle}>Description</label>\n <textarea\n required\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe the feature you'd like to see...\"\n style={{ ...inputStyle, resize: \"none\" }}\n />\n </div>\n\n <div>\n <label style={labelStyle}>Enter your Email ID</label>\n <input\n type=\"email\"\n required\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Please enter your email ID\"\n style={inputStyle}\n />\n </div>\n\n <button type=\"submit\" disabled={status === \"loading\"} style={submitBtnStyle}>\n {status === \"loading\" ? \"Submitting...\" : \"Submit Request\"}\n </button>\n\n <div style={statusMsgStyle}>\n {status === \"success\" ? \"Thank you for your feedback!\" : \"Something went wrong. Please try again.\"}\n </div>\n </form>\n </div>\n\n <button onClick={() => setIsOpen(!isOpen)} style={buttonStyle}>\n {isOpen ? (\n <svg width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <>\n <svg width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n <span style={{ display: \"inline\" }}>Request Feature</span>\n </>\n )}\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,186 @@
1
+ // src/index.tsx
2
+ import { useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ function FeedbackWidget({ apiUrl, primaryColor = "#3b82f6" }) {
5
+ const [isOpen, setIsOpen] = useState(false);
6
+ const [title, setTitle] = useState("");
7
+ const [description, setDescription] = useState("");
8
+ const [email, setEmail] = useState("");
9
+ const [status, setStatus] = useState("idle");
10
+ const handleSubmit = async (e) => {
11
+ e.preventDefault();
12
+ if (!title.trim() || !description.trim() || !email.trim()) return;
13
+ setStatus("loading");
14
+ try {
15
+ const response = await fetch(apiUrl, {
16
+ method: "POST",
17
+ headers: { "Content-Type": "application/json" },
18
+ body: JSON.stringify({ title, description, email })
19
+ });
20
+ if (response.ok) {
21
+ setStatus("success");
22
+ setTitle("");
23
+ setDescription("");
24
+ setTimeout(() => {
25
+ setIsOpen(false);
26
+ setStatus("idle");
27
+ }, 2e3);
28
+ } else {
29
+ setStatus("error");
30
+ }
31
+ } catch (error) {
32
+ console.error("Feedback Widget Error:", error);
33
+ setStatus("error");
34
+ }
35
+ };
36
+ const containerStyle = {
37
+ position: "fixed",
38
+ bottom: "24px",
39
+ right: "24px",
40
+ zIndex: 999999,
41
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
42
+ };
43
+ const buttonStyle = {
44
+ backgroundColor: primaryColor,
45
+ color: "white",
46
+ border: "none",
47
+ borderRadius: "9999px",
48
+ padding: "16px",
49
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
50
+ cursor: "pointer",
51
+ display: "flex",
52
+ alignItems: "center",
53
+ gap: "8px",
54
+ fontWeight: 500,
55
+ fontSize: "16px",
56
+ transition: "transform 0.2s ease-in-out"
57
+ };
58
+ const modalStyle = {
59
+ position: "absolute",
60
+ bottom: "80px",
61
+ right: "0",
62
+ width: "384px",
63
+ // w-96 roughly
64
+ backgroundColor: "white",
65
+ borderRadius: "8px",
66
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
67
+ border: "1px solid #e5e7eb",
68
+ padding: "24px",
69
+ boxSizing: "border-box",
70
+ display: isOpen ? "block" : "none"
71
+ };
72
+ const headerStyle = {
73
+ display: "flex",
74
+ justifyContent: "space-between",
75
+ alignItems: "center",
76
+ marginBottom: "16px"
77
+ };
78
+ const labelStyle = {
79
+ display: "block",
80
+ fontSize: "14px",
81
+ fontWeight: 500,
82
+ color: "#374151",
83
+ marginBottom: "4px"
84
+ };
85
+ const inputStyle = {
86
+ width: "100%",
87
+ padding: "8px 12px",
88
+ border: "1px solid #d1d5db",
89
+ borderRadius: "8px",
90
+ fontSize: "14px",
91
+ boxSizing: "border-box",
92
+ outline: "none",
93
+ fontFamily: "inherit",
94
+ marginBottom: "16px"
95
+ };
96
+ const submitBtnStyle = {
97
+ width: "100%",
98
+ backgroundColor: primaryColor,
99
+ color: "white",
100
+ fontWeight: 500,
101
+ padding: "8px 16px",
102
+ borderRadius: "8px",
103
+ border: "none",
104
+ cursor: status === "loading" ? "not-allowed" : "pointer",
105
+ fontSize: "16px",
106
+ opacity: status === "loading" ? 0.7 : 1
107
+ };
108
+ const statusMsgStyle = {
109
+ fontSize: "14px",
110
+ marginTop: "12px",
111
+ textAlign: "center",
112
+ color: status === "success" ? "#10b981" : "#ef4444",
113
+ display: status === "success" || status === "error" ? "block" : "none"
114
+ };
115
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
116
+ /* @__PURE__ */ jsxs("div", { style: modalStyle, children: [
117
+ /* @__PURE__ */ jsxs("div", { style: headerStyle, children: [
118
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: "18px", fontWeight: 600, color: "#1f2937" }, children: "Submit Feature Request" }),
119
+ /* @__PURE__ */ jsx(
120
+ "button",
121
+ {
122
+ onClick: () => setIsOpen(false),
123
+ style: { background: "none", border: "none", cursor: "pointer", color: "#9ca3af" },
124
+ "aria-label": "Close",
125
+ type: "button",
126
+ children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
127
+ }
128
+ )
129
+ ] }),
130
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
131
+ /* @__PURE__ */ jsxs("div", { children: [
132
+ /* @__PURE__ */ jsx("label", { style: labelStyle, children: "Feature Title" }),
133
+ /* @__PURE__ */ jsx(
134
+ "input",
135
+ {
136
+ type: "text",
137
+ required: true,
138
+ value: title,
139
+ onChange: (e) => setTitle(e.target.value),
140
+ placeholder: "Enter feature title",
141
+ style: inputStyle
142
+ }
143
+ )
144
+ ] }),
145
+ /* @__PURE__ */ jsxs("div", { children: [
146
+ /* @__PURE__ */ jsx("label", { style: labelStyle, children: "Description" }),
147
+ /* @__PURE__ */ jsx(
148
+ "textarea",
149
+ {
150
+ required: true,
151
+ rows: 3,
152
+ value: description,
153
+ onChange: (e) => setDescription(e.target.value),
154
+ placeholder: "Describe the feature you'd like to see...",
155
+ style: { ...inputStyle, resize: "none" }
156
+ }
157
+ )
158
+ ] }),
159
+ /* @__PURE__ */ jsxs("div", { children: [
160
+ /* @__PURE__ */ jsx("label", { style: labelStyle, children: "Enter your Email ID" }),
161
+ /* @__PURE__ */ jsx(
162
+ "input",
163
+ {
164
+ type: "email",
165
+ required: true,
166
+ value: email,
167
+ onChange: (e) => setEmail(e.target.value),
168
+ placeholder: "Please enter your email ID",
169
+ style: inputStyle
170
+ }
171
+ )
172
+ ] }),
173
+ /* @__PURE__ */ jsx("button", { type: "submit", disabled: status === "loading", style: submitBtnStyle, children: status === "loading" ? "Submitting..." : "Submit Request" }),
174
+ /* @__PURE__ */ jsx("div", { style: statusMsgStyle, children: status === "success" ? "Thank you for your feedback!" : "Something went wrong. Please try again." })
175
+ ] })
176
+ ] }),
177
+ /* @__PURE__ */ jsx("button", { onClick: () => setIsOpen(!isOpen), style: buttonStyle, children: isOpen ? /* @__PURE__ */ jsx("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
178
+ /* @__PURE__ */ jsx("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }),
179
+ /* @__PURE__ */ jsx("span", { style: { display: "inline" }, children: "Request Feature" })
180
+ ] }) })
181
+ ] });
182
+ }
183
+ export {
184
+ FeedbackWidget
185
+ };
186
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import React, { useState, CSSProperties, FormEvent } from \"react\";\n\nexport interface FeedbackWidgetProps {\n /**\n * The URL of your API endpoint to send the feedback data to.\n * Example: https://your-domain.com/api/feedback\n */\n apiUrl: string;\n /**\n * Optional primary color for the button and accents. \n * Defaults to a pleasant blue (#3b82f6)\n */\n primaryColor?: string;\n}\n\nexport function FeedbackWidget({ apiUrl, primaryColor = \"#3b82f6\" }: FeedbackWidgetProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [title, setTitle] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n \n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"success\" | \"error\">(\"idle\");\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!title.trim() || !description.trim() || !email.trim()) return;\n\n setStatus(\"loading\");\n\n try {\n const response = await fetch(apiUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ title, description, email }),\n });\n\n if (response.ok) {\n setStatus(\"success\");\n setTitle(\"\");\n setDescription(\"\");\n // Auto-close after a success\n setTimeout(() => {\n setIsOpen(false);\n setStatus(\"idle\");\n }, 2000);\n } else {\n setStatus(\"error\");\n }\n } catch (error) {\n console.error(\"Feedback Widget Error:\", error);\n setStatus(\"error\");\n }\n };\n\n // --- Styles ---\n const containerStyle: CSSProperties = {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n zIndex: 999999,\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n };\n\n const buttonStyle: CSSProperties = {\n backgroundColor: primaryColor,\n color: \"white\",\n border: \"none\",\n borderRadius: \"9999px\",\n padding: \"16px\",\n boxShadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n fontWeight: 500,\n fontSize: \"16px\",\n transition: \"transform 0.2s ease-in-out\",\n };\n\n const modalStyle: CSSProperties = {\n position: \"absolute\",\n bottom: \"80px\",\n right: \"0\",\n width: \"384px\", // w-96 roughly\n backgroundColor: \"white\",\n borderRadius: \"8px\",\n boxShadow: \"0 25px 50px -12px rgba(0, 0, 0, 0.25)\",\n border: \"1px solid #e5e7eb\",\n padding: \"24px\",\n boxSizing: \"border-box\",\n display: isOpen ? \"block\" : \"none\",\n };\n\n const headerStyle: CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"16px\",\n };\n\n const labelStyle: CSSProperties = {\n display: \"block\",\n fontSize: \"14px\",\n fontWeight: 500,\n color: \"#374151\",\n marginBottom: \"4px\",\n };\n\n const inputStyle: CSSProperties = {\n width: \"100%\",\n padding: \"8px 12px\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n fontFamily: \"inherit\",\n marginBottom: \"16px\",\n };\n\n const submitBtnStyle: CSSProperties = {\n width: \"100%\",\n backgroundColor: primaryColor,\n color: \"white\",\n fontWeight: 500,\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: status === \"loading\" ? \"not-allowed\" : \"pointer\",\n fontSize: \"16px\",\n opacity: status === \"loading\" ? 0.7 : 1,\n };\n\n const statusMsgStyle: CSSProperties = {\n fontSize: \"14px\",\n marginTop: \"12px\",\n textAlign: \"center\",\n color: status === \"success\" ? \"#10b981\" : \"#ef4444\",\n display: status === \"success\" || status === \"error\" ? \"block\" : \"none\",\n };\n\n return (\n <div style={containerStyle}>\n <div style={modalStyle}>\n <div style={headerStyle}>\n <h3 style={{ margin: 0, fontSize: \"18px\", fontWeight: 600, color: \"#1f2937\" }}>\n Submit Feature Request\n </h3>\n <button\n onClick={() => setIsOpen(false)}\n style={{ background: \"none\", border: \"none\", cursor: \"pointer\", color: \"#9ca3af\" }}\n aria-label=\"Close\"\n type=\"button\"\n >\n <svg width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <form onSubmit={handleSubmit}>\n <div>\n <label style={labelStyle}>Feature Title</label>\n <input\n type=\"text\"\n required\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Enter feature title\"\n style={inputStyle}\n />\n </div>\n\n <div>\n <label style={labelStyle}>Description</label>\n <textarea\n required\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe the feature you'd like to see...\"\n style={{ ...inputStyle, resize: \"none\" }}\n />\n </div>\n\n <div>\n <label style={labelStyle}>Enter your Email ID</label>\n <input\n type=\"email\"\n required\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Please enter your email ID\"\n style={inputStyle}\n />\n </div>\n\n <button type=\"submit\" disabled={status === \"loading\"} style={submitBtnStyle}>\n {status === \"loading\" ? \"Submitting...\" : \"Submit Request\"}\n </button>\n\n <div style={statusMsgStyle}>\n {status === \"success\" ? \"Thank you for your feedback!\" : \"Something went wrong. Please try again.\"}\n </div>\n </form>\n </div>\n\n <button onClick={() => setIsOpen(!isOpen)} style={buttonStyle}>\n {isOpen ? (\n <svg width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <>\n <svg width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n <span style={{ display: \"inline\" }}>Request Feature</span>\n </>\n )}\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "pa-floating-window",
3
+ "version": "1.0.0",
4
+ "description": "A plug-and-play React floating window widget for feature requests and feedback.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "require": "./dist/index.js",
11
+ "import": "./dist/index.mjs",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch"
21
+ },
22
+ "peerDependencies": {
23
+ "react": ">=16.8.0",
24
+ "react-dom": ">=16.8.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/react": "^18.2.0",
28
+ "@types/react-dom": "^18.2.0",
29
+ "react": "^18.2.0",
30
+ "react-dom": "^18.2.0",
31
+ "tsup": "^8.0.2",
32
+ "typescript": "^5.3.3"
33
+ },
34
+ "keywords": [
35
+ "react",
36
+ "feedback",
37
+ "widget",
38
+ "floating",
39
+ "window"
40
+ ],
41
+ "author": "HackByte",
42
+ "license": "MIT"
43
+ }