virtual-ui-lib 1.0.38 → 1.0.40

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.js CHANGED
@@ -29,6 +29,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.js
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
+ CodeBlock: () => CodeBlock,
33
+ OtpInput: () => OtpInput,
32
34
  StatCard: () => StatCard,
33
35
  ToastNotification: () => ToastNotification
34
36
  });
@@ -162,8 +164,106 @@ var StatCard = ({
162
164
  margin: "10px 0"
163
165
  } }, change >= 0 ? "+" + change + "%" : change + "%"), /* @__PURE__ */ import_react2.default.createElement("svg", { style: { marginTop: "12px" }, width: "100%", height: "30", viewBox: "0 0 100 30", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ import_react2.default.createElement("polyline", { fill: "none", stroke: change >= 0 ? accent : negativeAccent, strokeWidth: "2", points: "0,15 10,10 20,20 30,15 40,22 50,8 60,18 70,15 80,18 90,10 100,15" })));
164
166
  };
167
+
168
+ // src/components/OtpInput/OtpInput.jsx
169
+ var import_react3 = __toESM(require("react"));
170
+ var OtpInput = ({
171
+ length = 6,
172
+ boxSize = "48px",
173
+ borderColor = "#7c3aed",
174
+ bgColor = "#1e293b",
175
+ textColor = "#f1f5f9",
176
+ radius = "8px",
177
+ onComplete
178
+ }) => {
179
+ const [otp, setOtp] = (0, import_react3.useState)(Array(length).fill(""));
180
+ const inputsRef = (0, import_react3.useRef)([]);
181
+ const handleChange = (index, value) => {
182
+ if (/\d/.test(value) || value === "") {
183
+ const newOtp = [...otp];
184
+ newOtp[index] = value;
185
+ setOtp(newOtp);
186
+ if (value !== "" && index < length - 1) {
187
+ inputsRef.current[index + 1].focus();
188
+ } else if (value === "" && index > 0) {
189
+ inputsRef.current[index - 1].focus();
190
+ }
191
+ if (newOtp.join("").length === length) {
192
+ onComplete(newOtp.join(""));
193
+ }
194
+ }
195
+ };
196
+ const handlePaste = (e) => {
197
+ const pastedData = e.clipboardData.getData("text").slice(0, length).split("");
198
+ const newOtp = Array(length).fill("").map((_, index) => pastedData[index] || "");
199
+ setOtp(newOtp);
200
+ if (newOtp.join("").length === length) {
201
+ onComplete(newOtp.join(""));
202
+ }
203
+ e.preventDefault();
204
+ };
205
+ (0, import_react3.useEffect)(() => {
206
+ inputsRef.current[0].focus();
207
+ }, []);
208
+ return /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", gap: "10px", justifyContent: "center", padding: "20px", background: bgColor, borderRadius: radius, border: "1px solid rgba(255,255,255,0.1)", boxShadow: "0 4px 20px rgba(0,0,0,0.6)" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ import_react3.default.createElement(
209
+ "input",
210
+ {
211
+ key: index,
212
+ ref: (el) => inputsRef.current[index] = el,
213
+ type: "text",
214
+ maxLength: "1",
215
+ value,
216
+ onChange: (e) => handleChange(index, e.target.value),
217
+ onFocus: (e) => e.target.select(),
218
+ onKeyDown: (e) => {
219
+ if (e.key === "Backspace" && !value && index > 0) {
220
+ inputsRef.current[index - 1].focus();
221
+ }
222
+ },
223
+ style: {
224
+ width: boxSize,
225
+ height: boxSize,
226
+ fontSize: "24px",
227
+ textAlign: "center",
228
+ borderRadius: radius,
229
+ border: `2px solid ${borderColor}`,
230
+ background: bgColor,
231
+ color: textColor,
232
+ transition: "border-color 0.2s",
233
+ outline: "none"
234
+ }
235
+ }
236
+ )), otp.join("").length === length && /* @__PURE__ */ import_react3.default.createElement("span", { style: { color: "#4ade80", fontSize: "20px" } }, "\u2705"));
237
+ };
238
+
239
+ // src/components/CodeBlock/CodeBlock.jsx
240
+ var import_react4 = __toESM(require("react"));
241
+ var CodeBlock = ({
242
+ code = "const hello = 'Hello, world!';\nconsole.log(hello);",
243
+ language = "JavaScript",
244
+ filename = "example.js",
245
+ bg = "#0d1117",
246
+ textColor = "#c9d1d9",
247
+ tokenColors = { string: "#a5d6e9", keyword: "#f9bc41", variable: "#a6e22e" },
248
+ showLineNumbers = true,
249
+ wrapWords = false
250
+ }) => {
251
+ const [copied, setCopied] = (0, import_react4.useState)(false);
252
+ const handleCopy = () => {
253
+ navigator.clipboard.writeText(code).then(() => {
254
+ setCopied(true);
255
+ setTimeout(() => setCopied(false), 2e3);
256
+ });
257
+ };
258
+ const formatCode = () => {
259
+ return code.split("\n").map((line, index) => /* @__PURE__ */ import_react4.default.createElement("div", { key: index, style: { display: "flex" } }, showLineNumbers && /* @__PURE__ */ import_react4.default.createElement("span", { style: { marginRight: "10px", color: "#58a6ff" } }, index + 1), /* @__PURE__ */ import_react4.default.createElement("span", { style: { color: tokenColors.string } }, line.replace(/(\'.*?\')/g, (match) => `<span style='color:${tokenColors.string}'>${match}</span>`))));
260
+ };
261
+ return /* @__PURE__ */ import_react4.default.createElement("div", { style: { background: bg, borderRadius: "8px", padding: "16px", fontFamily: "monospace", position: "relative" } }, filename && /* @__PURE__ */ import_react4.default.createElement("div", { style: { color: textColor, fontWeight: "bold", marginBottom: "8px" } }, filename), /* @__PURE__ */ import_react4.default.createElement("div", { style: { overflowX: wrapWords ? "auto" : "hidden", whiteSpace: wrapWords ? "normal" : "pre" } }, formatCode()), /* @__PURE__ */ import_react4.default.createElement("button", { onClick: handleCopy, style: { position: "absolute", top: "10px", right: "10px", background: copied ? "#28a745" : "#58a6ff", color: "white", border: "none", borderRadius: "4px", padding: "8px 12px", cursor: "pointer", fontSize: "14px", marginLeft: "10px" } }, copied ? "\u2713 Copied" : "Copy"), /* @__PURE__ */ import_react4.default.createElement("button", { onClick: () => wrapWords = !wrapWords, style: { position: "absolute", top: "10px", right: "90px", background: "#58a6ff", color: "white", border: "none", borderRadius: "4px", padding: "8px 12px", cursor: "pointer", fontSize: "14px" } }, wrapWords ? "Wrap Off" : "Wrap On"));
262
+ };
165
263
  // Annotate the CommonJS export names for ESM import in node:
166
264
  0 && (module.exports = {
265
+ CodeBlock,
266
+ OtpInput,
167
267
  StatCard,
168
268
  ToastNotification
169
269
  });
package/dist/index.mjs CHANGED
@@ -126,7 +126,105 @@ var StatCard = ({
126
126
  margin: "10px 0"
127
127
  } }, change >= 0 ? "+" + change + "%" : change + "%"), /* @__PURE__ */ React2.createElement("svg", { style: { marginTop: "12px" }, width: "100%", height: "30", viewBox: "0 0 100 30", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React2.createElement("polyline", { fill: "none", stroke: change >= 0 ? accent : negativeAccent, strokeWidth: "2", points: "0,15 10,10 20,20 30,15 40,22 50,8 60,18 70,15 80,18 90,10 100,15" })));
128
128
  };
129
+
130
+ // src/components/OtpInput/OtpInput.jsx
131
+ import React3, { useEffect as useEffect3, useRef, useState as useState3 } from "react";
132
+ var OtpInput = ({
133
+ length = 6,
134
+ boxSize = "48px",
135
+ borderColor = "#7c3aed",
136
+ bgColor = "#1e293b",
137
+ textColor = "#f1f5f9",
138
+ radius = "8px",
139
+ onComplete
140
+ }) => {
141
+ const [otp, setOtp] = useState3(Array(length).fill(""));
142
+ const inputsRef = useRef([]);
143
+ const handleChange = (index, value) => {
144
+ if (/\d/.test(value) || value === "") {
145
+ const newOtp = [...otp];
146
+ newOtp[index] = value;
147
+ setOtp(newOtp);
148
+ if (value !== "" && index < length - 1) {
149
+ inputsRef.current[index + 1].focus();
150
+ } else if (value === "" && index > 0) {
151
+ inputsRef.current[index - 1].focus();
152
+ }
153
+ if (newOtp.join("").length === length) {
154
+ onComplete(newOtp.join(""));
155
+ }
156
+ }
157
+ };
158
+ const handlePaste = (e) => {
159
+ const pastedData = e.clipboardData.getData("text").slice(0, length).split("");
160
+ const newOtp = Array(length).fill("").map((_, index) => pastedData[index] || "");
161
+ setOtp(newOtp);
162
+ if (newOtp.join("").length === length) {
163
+ onComplete(newOtp.join(""));
164
+ }
165
+ e.preventDefault();
166
+ };
167
+ useEffect3(() => {
168
+ inputsRef.current[0].focus();
169
+ }, []);
170
+ return /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", gap: "10px", justifyContent: "center", padding: "20px", background: bgColor, borderRadius: radius, border: "1px solid rgba(255,255,255,0.1)", boxShadow: "0 4px 20px rgba(0,0,0,0.6)" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ React3.createElement(
171
+ "input",
172
+ {
173
+ key: index,
174
+ ref: (el) => inputsRef.current[index] = el,
175
+ type: "text",
176
+ maxLength: "1",
177
+ value,
178
+ onChange: (e) => handleChange(index, e.target.value),
179
+ onFocus: (e) => e.target.select(),
180
+ onKeyDown: (e) => {
181
+ if (e.key === "Backspace" && !value && index > 0) {
182
+ inputsRef.current[index - 1].focus();
183
+ }
184
+ },
185
+ style: {
186
+ width: boxSize,
187
+ height: boxSize,
188
+ fontSize: "24px",
189
+ textAlign: "center",
190
+ borderRadius: radius,
191
+ border: `2px solid ${borderColor}`,
192
+ background: bgColor,
193
+ color: textColor,
194
+ transition: "border-color 0.2s",
195
+ outline: "none"
196
+ }
197
+ }
198
+ )), otp.join("").length === length && /* @__PURE__ */ React3.createElement("span", { style: { color: "#4ade80", fontSize: "20px" } }, "\u2705"));
199
+ };
200
+
201
+ // src/components/CodeBlock/CodeBlock.jsx
202
+ import React4, { useState as useState4 } from "react";
203
+ var CodeBlock = ({
204
+ code = "const hello = 'Hello, world!';\nconsole.log(hello);",
205
+ language = "JavaScript",
206
+ filename = "example.js",
207
+ bg = "#0d1117",
208
+ textColor = "#c9d1d9",
209
+ tokenColors = { string: "#a5d6e9", keyword: "#f9bc41", variable: "#a6e22e" },
210
+ showLineNumbers = true,
211
+ wrapWords = false
212
+ }) => {
213
+ const [copied, setCopied] = useState4(false);
214
+ const handleCopy = () => {
215
+ navigator.clipboard.writeText(code).then(() => {
216
+ setCopied(true);
217
+ setTimeout(() => setCopied(false), 2e3);
218
+ });
219
+ };
220
+ const formatCode = () => {
221
+ return code.split("\n").map((line, index) => /* @__PURE__ */ React4.createElement("div", { key: index, style: { display: "flex" } }, showLineNumbers && /* @__PURE__ */ React4.createElement("span", { style: { marginRight: "10px", color: "#58a6ff" } }, index + 1), /* @__PURE__ */ React4.createElement("span", { style: { color: tokenColors.string } }, line.replace(/(\'.*?\')/g, (match) => `<span style='color:${tokenColors.string}'>${match}</span>`))));
222
+ };
223
+ return /* @__PURE__ */ React4.createElement("div", { style: { background: bg, borderRadius: "8px", padding: "16px", fontFamily: "monospace", position: "relative" } }, filename && /* @__PURE__ */ React4.createElement("div", { style: { color: textColor, fontWeight: "bold", marginBottom: "8px" } }, filename), /* @__PURE__ */ React4.createElement("div", { style: { overflowX: wrapWords ? "auto" : "hidden", whiteSpace: wrapWords ? "normal" : "pre" } }, formatCode()), /* @__PURE__ */ React4.createElement("button", { onClick: handleCopy, style: { position: "absolute", top: "10px", right: "10px", background: copied ? "#28a745" : "#58a6ff", color: "white", border: "none", borderRadius: "4px", padding: "8px 12px", cursor: "pointer", fontSize: "14px", marginLeft: "10px" } }, copied ? "\u2713 Copied" : "Copy"), /* @__PURE__ */ React4.createElement("button", { onClick: () => wrapWords = !wrapWords, style: { position: "absolute", top: "10px", right: "90px", background: "#58a6ff", color: "white", border: "none", borderRadius: "4px", padding: "8px 12px", cursor: "pointer", fontSize: "14px" } }, wrapWords ? "Wrap Off" : "Wrap On"));
224
+ };
129
225
  export {
226
+ CodeBlock,
227
+ OtpInput,
130
228
  StatCard,
131
229
  ToastNotification
132
230
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-ui-lib",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "description": "Virtual UI React Component Library",
5
5
  "author": "Ankush",
6
6
  "license": "ISC",