@dufy_asesorias/widget-dufy-kit 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/dist/index.es.js +127 -0
- package/dist/index.umd.js +1 -0
- package/dist/widget-dufy-kit.css +3 -0
- package/index.d.ts +127 -0
- package/package.json +36 -0
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import e, { useEffect as t, useState as n } from "react";
|
|
2
|
+
import { Edit3 as r, Save as i, X as a } from "lucide-react";
|
|
3
|
+
import o from "react-select";
|
|
4
|
+
//#region src/EditableField/EditableField.jsx
|
|
5
|
+
var s = ({ field: s, label: c, value: l, type: u = "text", options: d = [], placeholder: f = "", isAdmin: p = !1, onSave: m, onCancel: h, onInputChange: g, validation: _ = null, disabled: v = !1, required: y = !1, min: b = null, max: x = null, rows: S = 3, className: C = "" }) => {
|
|
6
|
+
let [w, T] = n(!1), [E, D] = n(""), [O, k] = n("");
|
|
7
|
+
return t(() => {
|
|
8
|
+
!w && l !== void 0 && D(u === "react-select" ? d.find((e) => e.value === l) || null : l);
|
|
9
|
+
}, [
|
|
10
|
+
l,
|
|
11
|
+
w,
|
|
12
|
+
u,
|
|
13
|
+
d
|
|
14
|
+
]), /* @__PURE__ */ e.createElement("div", { className: `flex items-start justify-between p-3 bg-brand-bgWidget rounded-lg ${C}` }, /* @__PURE__ */ e.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ e.createElement("label", { className: "text-sm text-gray-600 block mb-1" }, c, " ", y && /* @__PURE__ */ e.createElement("span", { className: "text-brand-danger" }, "*")), w ? /* @__PURE__ */ e.createElement("div", null, (() => {
|
|
15
|
+
let t = {
|
|
16
|
+
value: E || "",
|
|
17
|
+
onChange: (e) => D(e.target.value),
|
|
18
|
+
className: `w-full p-2 border rounded-md focus:ring-2 focus:ring-brand-primary focus:border-brand-primary ${O ? "border-brand-danger" : "border-gray-300"}`,
|
|
19
|
+
placeholder: f,
|
|
20
|
+
autoFocus: !0,
|
|
21
|
+
disabled: v
|
|
22
|
+
};
|
|
23
|
+
return u === "react-select" ? /* @__PURE__ */ e.createElement(o, {
|
|
24
|
+
value: E,
|
|
25
|
+
onChange: (e) => D(e),
|
|
26
|
+
options: d,
|
|
27
|
+
placeholder: f,
|
|
28
|
+
isDisabled: v,
|
|
29
|
+
styles: {
|
|
30
|
+
control: (e, t) => ({
|
|
31
|
+
...e,
|
|
32
|
+
border: `1px solid ${O ? "#dc2626" : t.isFocused ? "var(--color-brand-primary, #4f46e5)" : "#d1d5db"}`,
|
|
33
|
+
boxShadow: t.isFocused ? "0 0 0 2px #eff6ff" : "none"
|
|
34
|
+
}),
|
|
35
|
+
option: (e, t) => ({
|
|
36
|
+
...e,
|
|
37
|
+
backgroundColor: t.isSelected ? "#4f46e5" : t.isFocused ? "#eff6ff" : "transparent",
|
|
38
|
+
color: t.isSelected ? "white" : "#374151"
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}) : u === "textarea" ? /* @__PURE__ */ e.createElement("textarea", {
|
|
42
|
+
...t,
|
|
43
|
+
rows: S
|
|
44
|
+
}) : /* @__PURE__ */ e.createElement("input", {
|
|
45
|
+
...t,
|
|
46
|
+
type: u,
|
|
47
|
+
min: b,
|
|
48
|
+
max: x
|
|
49
|
+
});
|
|
50
|
+
})(), O && /* @__PURE__ */ e.createElement("p", { className: "text-brand-danger text-xs mt-1" }, O)) : /* @__PURE__ */ e.createElement("span", { className: `font-medium text-gray-800 break-words ${!l && l !== 0 ? "text-gray-400 italic" : ""}` }, u === "react-select" ? d.find((e) => e.value === l)?.label || l || "No especificado" : l || "No especificado")), p && /* @__PURE__ */ e.createElement("div", { className: "ml-4 flex gap-2 flex-shrink-0" }, w ? /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("button", {
|
|
51
|
+
onClick: async () => {
|
|
52
|
+
let e = u === "react-select" ? E ? E.value : null : E;
|
|
53
|
+
if (y && !e && e !== 0) {
|
|
54
|
+
k("Este campo es obligatorio");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
m && await m(s, e), T(!1), k("");
|
|
59
|
+
} catch (e) {
|
|
60
|
+
k(e.message || "Error al guardar");
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
className: "p-1 text-brand-success hover:bg-brand-successLight rounded"
|
|
64
|
+
}, /* @__PURE__ */ e.createElement(i, { size: 16 })), /* @__PURE__ */ e.createElement("button", {
|
|
65
|
+
onClick: () => T(!1),
|
|
66
|
+
className: "p-1 text-brand-danger hover:bg-brand-dangerLight rounded"
|
|
67
|
+
}, /* @__PURE__ */ e.createElement(a, { size: 16 }))) : /* @__PURE__ */ e.createElement("button", {
|
|
68
|
+
onClick: () => T(!0),
|
|
69
|
+
className: "p-1 text-brand-edit hover:bg-brand-editLight rounded"
|
|
70
|
+
}, /* @__PURE__ */ e.createElement(r, { size: 16 }))));
|
|
71
|
+
}, c = ({ field: t, label: o, value: s, isAdmin: c = !1, onSave: l, required: u = !1, disabled: d = !1, className: f = "", labels: p = {
|
|
72
|
+
true: "Sí",
|
|
73
|
+
false: "No"
|
|
74
|
+
}, displayAs: m = "toggle" }) => {
|
|
75
|
+
let [h, g] = n(!1), [_, v] = n(null), [y, b] = n("");
|
|
76
|
+
return /* @__PURE__ */ e.createElement("div", { className: `flex items-center justify-between p-3 bg-brand-bgWidget rounded-lg ${f}` }, /* @__PURE__ */ e.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ e.createElement("label", { className: "text-sm text-gray-600 block mb-1" }, o, u && m !== "toggle" && /* @__PURE__ */ e.createElement("span", { className: "text-brand-danger ml-1" }, "*")), h ? /* @__PURE__ */ e.createElement("div", null, m === "toggle" ? /* @__PURE__ */ e.createElement("label", {
|
|
77
|
+
htmlFor: `${t}_toggle`,
|
|
78
|
+
className: "relative inline-flex items-center cursor-pointer"
|
|
79
|
+
}, /* @__PURE__ */ e.createElement("input", {
|
|
80
|
+
type: "checkbox",
|
|
81
|
+
id: `${t}_toggle`,
|
|
82
|
+
className: "sr-only peer",
|
|
83
|
+
checked: _ === !0,
|
|
84
|
+
onChange: () => v(!_),
|
|
85
|
+
disabled: d
|
|
86
|
+
}), /* @__PURE__ */ e.createElement("div", { className: "w-11 h-6 bg-gray-300 rounded-full peer peer-focus:ring-2 peer-focus:ring-brand-editLight peer-checked:bg-brand-primary peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all" }), /* @__PURE__ */ e.createElement("span", { className: "ml-3 text-sm font-medium text-gray-700 select-none" }, _ ? p.true : p.false)) : /* @__PURE__ */ e.createElement("div", { className: "space-y-2" }, [!0, !1].map((n) => /* @__PURE__ */ e.createElement("label", {
|
|
87
|
+
key: n.toString(),
|
|
88
|
+
className: "flex items-center cursor-pointer"
|
|
89
|
+
}, /* @__PURE__ */ e.createElement("input", {
|
|
90
|
+
type: "radio",
|
|
91
|
+
name: `${t}_boolean`,
|
|
92
|
+
checked: _ === n,
|
|
93
|
+
onChange: () => v(n),
|
|
94
|
+
className: "mr-3 h-4 w-4 text-brand-primary focus:ring-brand-primary border-gray-300",
|
|
95
|
+
disabled: d
|
|
96
|
+
}), /* @__PURE__ */ e.createElement("span", { className: "text-sm text-gray-700" }, n ? p.true : p.false)))), y && /* @__PURE__ */ e.createElement("p", { className: "text-brand-danger text-xs mt-2" }, y)) : /* @__PURE__ */ e.createElement("span", { className: `break-words ${!s && s !== 0 && m !== "toggle" ? "text-gray-400 italic" : "font-medium text-gray-800"}` }, s === !0 ? p.true : s === !1 || m === "toggle" ? p.false : "No especificado")), c && /* @__PURE__ */ e.createElement("div", { className: "ml-4 flex gap-2 flex-shrink-0" }, h ? /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("button", {
|
|
97
|
+
onClick: async () => {
|
|
98
|
+
if (u && _ == null) {
|
|
99
|
+
b("Este campo es obligatorio");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
l && await l(t, _), g(!1), b("");
|
|
104
|
+
} catch (e) {
|
|
105
|
+
b(e.message || "Error al guardar");
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
disabled: d,
|
|
109
|
+
className: "p-1 text-brand-success hover:bg-brand-successLight rounded disabled:opacity-50",
|
|
110
|
+
title: "Guardar"
|
|
111
|
+
}, /* @__PURE__ */ e.createElement(i, { size: 16 })), /* @__PURE__ */ e.createElement("button", {
|
|
112
|
+
onClick: () => {
|
|
113
|
+
g(!1), v(null), b("");
|
|
114
|
+
},
|
|
115
|
+
className: "p-1 text-brand-danger hover:bg-brand-dangerLight rounded",
|
|
116
|
+
title: "Cancelar"
|
|
117
|
+
}, /* @__PURE__ */ e.createElement(a, { size: 16 }))) : /* @__PURE__ */ e.createElement("button", {
|
|
118
|
+
onClick: () => {
|
|
119
|
+
d || (g(!0), v(m === "toggle" ? s ?? !1 : s), b(""));
|
|
120
|
+
},
|
|
121
|
+
disabled: d,
|
|
122
|
+
className: "p-1 text-brand-edit hover:bg-brand-editLight rounded disabled:opacity-50",
|
|
123
|
+
title: "Editar"
|
|
124
|
+
}, /* @__PURE__ */ e.createElement(r, { size: 16 }))));
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
export { c as BooleanField, s as EditableField };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("lucide-react"),require("react-select")):typeof define==`function`&&define.amd?define([`exports`,`react`,`lucide-react`,`react-select`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.WidgetDufyKit={},e.React,e.LucideReact,e.Select))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e},d=(e,t,n)=>(n=e==null?{}:i(c(e)),u(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e));t=d(t,1),r=d(r,1),e.BooleanField=({field:e,label:r,value:i,isAdmin:a=!1,onSave:o,required:s=!1,disabled:c=!1,className:l=``,labels:u={true:`Sí`,false:`No`},displayAs:d=`toggle`})=>{let[f,p]=(0,t.useState)(!1),[m,h]=(0,t.useState)(null),[g,_]=(0,t.useState)(``);return t.default.createElement(`div`,{className:`flex items-center justify-between p-3 bg-brand-bgWidget rounded-lg ${l}`},t.default.createElement(`div`,{className:`flex-1 min-w-0`},t.default.createElement(`label`,{className:`text-sm text-gray-600 block mb-1`},r,s&&d!==`toggle`&&t.default.createElement(`span`,{className:`text-brand-danger ml-1`},`*`)),f?t.default.createElement(`div`,null,d===`toggle`?t.default.createElement(`label`,{htmlFor:`${e}_toggle`,className:`relative inline-flex items-center cursor-pointer`},t.default.createElement(`input`,{type:`checkbox`,id:`${e}_toggle`,className:`sr-only peer`,checked:m===!0,onChange:()=>h(!m),disabled:c}),t.default.createElement(`div`,{className:`w-11 h-6 bg-gray-300 rounded-full peer peer-focus:ring-2 peer-focus:ring-brand-editLight peer-checked:bg-brand-primary peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all`}),t.default.createElement(`span`,{className:`ml-3 text-sm font-medium text-gray-700 select-none`},m?u.true:u.false)):t.default.createElement(`div`,{className:`space-y-2`},[!0,!1].map(n=>t.default.createElement(`label`,{key:n.toString(),className:`flex items-center cursor-pointer`},t.default.createElement(`input`,{type:`radio`,name:`${e}_boolean`,checked:m===n,onChange:()=>h(n),className:`mr-3 h-4 w-4 text-brand-primary focus:ring-brand-primary border-gray-300`,disabled:c}),t.default.createElement(`span`,{className:`text-sm text-gray-700`},n?u.true:u.false)))),g&&t.default.createElement(`p`,{className:`text-brand-danger text-xs mt-2`},g)):t.default.createElement(`span`,{className:`break-words ${!i&&i!==0&&d!==`toggle`?`text-gray-400 italic`:`font-medium text-gray-800`}`},i===!0?u.true:i===!1||d===`toggle`?u.false:`No especificado`)),a&&t.default.createElement(`div`,{className:`ml-4 flex gap-2 flex-shrink-0`},f?t.default.createElement(t.default.Fragment,null,t.default.createElement(`button`,{onClick:async()=>{if(s&&m==null){_(`Este campo es obligatorio`);return}try{o&&await o(e,m),p(!1),_(``)}catch(e){_(e.message||`Error al guardar`)}},disabled:c,className:`p-1 text-brand-success hover:bg-brand-successLight rounded disabled:opacity-50`,title:`Guardar`},t.default.createElement(n.Save,{size:16})),t.default.createElement(`button`,{onClick:()=>{p(!1),h(null),_(``)},className:`p-1 text-brand-danger hover:bg-brand-dangerLight rounded`,title:`Cancelar`},t.default.createElement(n.X,{size:16}))):t.default.createElement(`button`,{onClick:()=>{c||(p(!0),h(d===`toggle`?i??!1:i),_(``))},disabled:c,className:`p-1 text-brand-edit hover:bg-brand-editLight rounded disabled:opacity-50`,title:`Editar`},t.default.createElement(n.Edit3,{size:16}))))},e.EditableField=({field:e,label:i,value:a,type:o=`text`,options:s=[],placeholder:c=``,isAdmin:l=!1,onSave:u,onCancel:d,onInputChange:f,validation:p=null,disabled:m=!1,required:h=!1,min:g=null,max:_=null,rows:v=3,className:y=``})=>{let[b,x]=(0,t.useState)(!1),[S,C]=(0,t.useState)(``),[w,T]=(0,t.useState)(``);return(0,t.useEffect)(()=>{!b&&a!==void 0&&C(o===`react-select`?s.find(e=>e.value===a)||null:a)},[a,b,o,s]),t.default.createElement(`div`,{className:`flex items-start justify-between p-3 bg-brand-bgWidget rounded-lg ${y}`},t.default.createElement(`div`,{className:`flex-1 min-w-0`},t.default.createElement(`label`,{className:`text-sm text-gray-600 block mb-1`},i,` `,h&&t.default.createElement(`span`,{className:`text-brand-danger`},`*`)),b?t.default.createElement(`div`,null,(()=>{let e={value:S||``,onChange:e=>C(e.target.value),className:`w-full p-2 border rounded-md focus:ring-2 focus:ring-brand-primary focus:border-brand-primary ${w?`border-brand-danger`:`border-gray-300`}`,placeholder:c,autoFocus:!0,disabled:m};return o===`react-select`?t.default.createElement(r.default,{value:S,onChange:e=>C(e),options:s,placeholder:c,isDisabled:m,styles:{control:(e,t)=>({...e,border:`1px solid ${w?`#dc2626`:t.isFocused?`var(--color-brand-primary, #4f46e5)`:`#d1d5db`}`,boxShadow:t.isFocused?`0 0 0 2px #eff6ff`:`none`}),option:(e,t)=>({...e,backgroundColor:t.isSelected?`#4f46e5`:t.isFocused?`#eff6ff`:`transparent`,color:t.isSelected?`white`:`#374151`})}}):o===`textarea`?t.default.createElement(`textarea`,{...e,rows:v}):t.default.createElement(`input`,{...e,type:o,min:g,max:_})})(),w&&t.default.createElement(`p`,{className:`text-brand-danger text-xs mt-1`},w)):t.default.createElement(`span`,{className:`font-medium text-gray-800 break-words ${!a&&a!==0?`text-gray-400 italic`:``}`},o===`react-select`?s.find(e=>e.value===a)?.label||a||`No especificado`:a||`No especificado`)),l&&t.default.createElement(`div`,{className:`ml-4 flex gap-2 flex-shrink-0`},b?t.default.createElement(t.default.Fragment,null,t.default.createElement(`button`,{onClick:async()=>{let t=o===`react-select`?S?S.value:null:S;if(h&&!t&&t!==0){T(`Este campo es obligatorio`);return}try{u&&await u(e,t),x(!1),T(``)}catch(e){T(e.message||`Error al guardar`)}},className:`p-1 text-brand-success hover:bg-brand-successLight rounded`},t.default.createElement(n.Save,{size:16})),t.default.createElement(`button`,{onClick:()=>x(!1),className:`p-1 text-brand-danger hover:bg-brand-dangerLight rounded`},t.default.createElement(n.X,{size:16}))):t.default.createElement(`button`,{onClick:()=>x(!0),className:`p-1 text-brand-edit hover:bg-brand-editLight rounded`},t.default.createElement(n.Edit3,{size:16}))))}});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-brand-bgWidget:#fff;--color-brand-primary:#4f46e5;--color-brand-danger:#dc2626;--color-brand-dangerLight:#fef2f2;--color-brand-success:#16a34a;--color-brand-successLight:#f0fdf4;--color-brand-edit:#2563eb;--color-brand-editLight:#eff6ff}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.relative{position:relative}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mr-3{margin-right:calc(var(--spacing) * 3)}.mb-1{margin-bottom:var(--spacing)}.ml-1{margin-left:var(--spacing)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.w-4{width:calc(var(--spacing) * 4)}.w-11{width:calc(var(--spacing) * 11)}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.cursor-pointer{cursor:pointer}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.gap-2{gap:calc(var(--spacing) * 2)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-brand-danger{border-color:var(--color-brand-danger)}.border-gray-300{border-color:var(--color-gray-300)}.bg-brand-bgWidget{background-color:var(--color-brand-bgWidget)}.bg-gray-300{background-color:var(--color-gray-300)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.break-words{overflow-wrap:break-word}.text-brand-danger{color:var(--color-brand-danger)}.text-brand-edit{color:var(--color-brand-edit)}.text-brand-primary{color:var(--color-brand-primary)}.text-brand-success{color:var(--color-brand-success)}.text-gray-400{color:var(--color-gray-400)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.italic{font-style:italic}.select-none{-webkit-user-select:none;user-select:none}.peer-checked\:bg-brand-primary:is(:where(.peer):checked~*){background-color:var(--color-brand-primary)}.peer-focus\:ring-2:is(:where(.peer):focus~*){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.peer-focus\:ring-brand-editLight:is(:where(.peer):focus~*){--tw-ring-color:var(--color-brand-editLight)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0\.5:after{content:var(--tw-content);top:calc(var(--spacing) * .5)}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:h-5:after{content:var(--tw-content);height:calc(var(--spacing) * 5)}.after\:w-5:after{content:var(--tw-content);width:calc(var(--spacing) * 5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-gray-300:after{content:var(--tw-content);border-color:var(--color-gray-300)}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-full:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.peer-checked\:after\:border-white:is(:where(.peer):checked~*):after{content:var(--tw-content);border-color:var(--color-white)}@media (hover:hover){.hover\:bg-brand-dangerLight:hover{background-color:var(--color-brand-dangerLight)}.hover\:bg-brand-editLight:hover{background-color:var(--color-brand-editLight)}.hover\:bg-brand-successLight:hover{background-color:var(--color-brand-successLight)}}.focus\:border-brand-primary:focus{border-color:var(--color-brand-primary)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-brand-primary:focus{--tw-ring-color:var(--color-brand-primary)}.disabled\:opacity-50:disabled{opacity:.5}}@keyframes flash{0%{background-color:#e0f2fe}to{background-color:#0000}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
|
|
3
|
+
/*$vite$:1*/
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface EditableFieldProps {
|
|
4
|
+
// === PROPIEDADES BÁSICAS ===
|
|
5
|
+
|
|
6
|
+
/** Identificador único del campo (usado en los callbacks). */
|
|
7
|
+
field: string;
|
|
8
|
+
|
|
9
|
+
/** Etiqueta visible del campo que se muestra sobre el input. */
|
|
10
|
+
label: string;
|
|
11
|
+
|
|
12
|
+
/** Valor actual del campo (estado controlado). */
|
|
13
|
+
value: any;
|
|
14
|
+
|
|
15
|
+
/** * Tipo de campo interactivo.
|
|
16
|
+
* @default 'text'
|
|
17
|
+
*/
|
|
18
|
+
type?: 'text' | 'number' | 'date' | 'datetime' | 'time' | 'email' | 'tel' | 'textarea' | 'select' | 'react-select';
|
|
19
|
+
|
|
20
|
+
// === OPCIONES Y CONFIGURACIÓN ===
|
|
21
|
+
|
|
22
|
+
/** * Opciones de selección para tipos 'select' o 'react-select'.
|
|
23
|
+
* Formatos válidos: `['Opción 1', 'Opción 2']` o `[{ value: '1', label: 'Elegir 1' }]`
|
|
24
|
+
* @default []
|
|
25
|
+
*/
|
|
26
|
+
options?: (string | { value: any; label: string })[];
|
|
27
|
+
|
|
28
|
+
/** Texto translúcido de ayuda cuando el campo está vacío o en edición. */
|
|
29
|
+
placeholder?: string;
|
|
30
|
+
|
|
31
|
+
/** * Determina si se muestran los botones de acción para editar/guardar.
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
isAdmin?: boolean;
|
|
35
|
+
|
|
36
|
+
/** Deshabilita el campo bloqueando la edición. */
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
|
|
39
|
+
/** Si es true, valida que el campo no quede vacío antes de guardar. */
|
|
40
|
+
required?: boolean;
|
|
41
|
+
|
|
42
|
+
/** Clases CSS adicionales para estilizar el contenedor del widget. */
|
|
43
|
+
className?: string;
|
|
44
|
+
|
|
45
|
+
// === VALIDACIÓN Y RESTRICCIONES ===
|
|
46
|
+
|
|
47
|
+
/** * Función de validación personalizada en tiempo real.
|
|
48
|
+
* @returns Un string con el mensaje de error o `null`/`undefined` si es válido.
|
|
49
|
+
*/
|
|
50
|
+
validation?: ((value: any) => string | null | undefined) | null;
|
|
51
|
+
|
|
52
|
+
/** Valor mínimo permitido (exclusivo para tipo 'number', 'date', 'datetime', 'time'). */
|
|
53
|
+
min?: number | string | null;
|
|
54
|
+
|
|
55
|
+
/** Valor máximo permitido (exclusivo para tipo 'number', 'date', 'datetime', 'time'). */
|
|
56
|
+
max?: number | string | null;
|
|
57
|
+
|
|
58
|
+
/** * Número de filas iniciales visibles.
|
|
59
|
+
* @default 3
|
|
60
|
+
*/
|
|
61
|
+
rows?: number;
|
|
62
|
+
|
|
63
|
+
// === CALLBACKS ===
|
|
64
|
+
|
|
65
|
+
/** Función asíncrona obligatoria que se ejecuta al presionar el botón de Guardar. */
|
|
66
|
+
onSave: (field: string, newValue: any) => void | Promise<void>;
|
|
67
|
+
|
|
68
|
+
/** Función callback ejecutada al presionar el botón de Cancelar la edición. */
|
|
69
|
+
onCancel?: (field: string) => void;
|
|
70
|
+
|
|
71
|
+
/** * Función callback disparada en cada pulsación de tecla o cambio del input.
|
|
72
|
+
* @param field Identificador del campo.
|
|
73
|
+
* @param currentValue Valor procesado según el tipo de campo seleccionado.
|
|
74
|
+
* @param rawValue Valor nativo del evento de entrada.
|
|
75
|
+
*/
|
|
76
|
+
onInputChange?: (field: string, currentValue: any, rawValue: any) => void;
|
|
77
|
+
|
|
78
|
+
// === FORMATEO Y VISUALIZACIÓN ===
|
|
79
|
+
|
|
80
|
+
/** Función opcional para transformar el texto final cuando el campo está en modo lectura. */
|
|
81
|
+
formatDisplay?: ((value: any) => string) | null;
|
|
82
|
+
|
|
83
|
+
// === PROPIEDADES ESPECÍFICAS PARA REACT-SELECT ===
|
|
84
|
+
|
|
85
|
+
/** Permite al usuario limpiar la selección actual con un botón 'x'. */
|
|
86
|
+
isClearable?: boolean;
|
|
87
|
+
|
|
88
|
+
/** Permite filtrar u buscar opciones escribiendo texto en el select. */
|
|
89
|
+
isSearchable?: boolean;
|
|
90
|
+
|
|
91
|
+
/** Muestra una animación de carga dentro del select dinámico. */
|
|
92
|
+
isLoading?: boolean;
|
|
93
|
+
|
|
94
|
+
/** Función o string para modificar el mensaje cuando no hay resultados en la búsqueda. */
|
|
95
|
+
noOptionsMessage?: ((obj: { inputValue: string }) => string) | string;
|
|
96
|
+
|
|
97
|
+
/** Función auxiliar para mapear un valor primitivo a su objeto de opción correspondiente. */
|
|
98
|
+
getOptionFromValue?: ((options: any[], value: any) => any | null) | null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* ### EditableField — Dufy Asesorías
|
|
103
|
+
* Componente interactivo que permite editar diferentes tipos de datos directamente in-line,
|
|
104
|
+
* con soporte nativo para validaciones, múltiples tipos de inputs y estados controlados.
|
|
105
|
+
* * ---
|
|
106
|
+
* **Ejemplo de uso básico (Texto):**
|
|
107
|
+
* ```jsx
|
|
108
|
+
* <EditableField
|
|
109
|
+
* field="nombre"
|
|
110
|
+
* label="Nombre del Consultor"
|
|
111
|
+
* value="Andrés Durán"
|
|
112
|
+
* required
|
|
113
|
+
* onSave={(field, value) => asignarNombre(field, value)}
|
|
114
|
+
* />
|
|
115
|
+
* ```
|
|
116
|
+
* * **Ejemplo avanzado (React Select):**
|
|
117
|
+
* ```jsx
|
|
118
|
+
* <EditableField
|
|
119
|
+
* field="categoria"
|
|
120
|
+
* label="Categoría de Asesoría"
|
|
121
|
+
* type="react-select"
|
|
122
|
+
* options={[{ value: 'tech', label: 'Tecnología' }]}
|
|
123
|
+
* onSave={async (field, value) => await guardarEnBaseDatos(field, value)}
|
|
124
|
+
* />
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export const EditableField: React.FC<EditableFieldProps>;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dufy_asesorias/widget-dufy-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.umd.js",
|
|
6
|
+
"module": "./dist/index.es.js",
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"import": "./dist/index.es.js",
|
|
12
|
+
"require": "./dist/index.umd.js",
|
|
13
|
+
"style": "./dist/widget-dufy-kit.css"
|
|
14
|
+
},
|
|
15
|
+
"./dist/*": "./dist/*"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"index.d.ts"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "vite build",
|
|
23
|
+
"local": "npm run build && yalc push",
|
|
24
|
+
"publicar": "npm run build && npm publish --access public"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
28
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@vitejs/plugin-react": "^6.0.3"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@tailwindcss/vite": "^4.3.1"
|
|
35
|
+
}
|
|
36
|
+
}
|