@khipu/design-system 0.2.0-alpha.48 → 0.2.0-alpha.49

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@khipu/design-system/beercss",
3
- "version": "0.2.0-alpha.48",
3
+ "version": "0.2.0-alpha.49",
4
4
  "description": "Khipu BeerCSS bundle with Material Design 3 and Khipu customizations",
5
- "buildDate": "2026-06-16T00:13:24.044Z",
5
+ "buildDate": "2026-06-16T20:10:15.782Z",
6
6
  "includes": {
7
7
  "beercss": "4.0.1",
8
8
  "khipu-tokens": "latest",
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "scopeClass": ".kds-theme-root",
21
21
  "cdn": {
22
- "css": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.48/dist/beercss/khipu-beercss.min.css",
23
- "cssScoped": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.48/dist/beercss/khipu-beercss.scoped.min.css",
24
- "js": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.48/dist/beercss/khipu-beercss.min.js"
22
+ "css": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.49/dist/beercss/khipu-beercss.min.css",
23
+ "cssScoped": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.49/dist/beercss/khipu-beercss.scoped.min.css",
24
+ "js": "https://cdn.jsdelivr.net/npm/@khipu/design-system@0.2.0-alpha.49/dist/beercss/khipu-beercss.min.js"
25
25
  }
26
26
  }
package/dist/index.d.mts CHANGED
@@ -2556,6 +2556,11 @@ declare const KdsButton: React__default.ForwardRefExoticComponent<KdsButtonProps
2556
2556
  * - El wrapper DEBE tener `.prefix` cuando hay icono al inicio (alinea la label al lado del icono).
2557
2557
  * - El wrapper DEBE tener `.suffix` cuando hay icono al final.
2558
2558
  *
2559
+ * Variante `revealable` (campo de contraseña con mostrar/ocultar):
2560
+ * - El toggle es un `<a role="button">` — BeerCSS posiciona como icono del field a
2561
+ * `:is(i, img, svg, progress.circle, a)` y da `pointer-events: all` solo a `<a>`/`.front`,
2562
+ * así que el anchor es el elemento interactivo idiomático del field (no `<button>`).
2563
+ *
2559
2564
  * @gsp `mat:textField`, `mat:emailField`, `mat:passwordField`, `mat:numberField` (taglib `matFieldImpl`)
2560
2565
  */
2561
2566
 
@@ -2572,6 +2577,20 @@ interface KdsTextFieldProps extends Omit<React__default.InputHTMLAttributes<HTML
2572
2577
  startIcon?: string;
2573
2578
  /** Material Symbol al final del input (aplica clase `.suffix`). */
2574
2579
  endIcon?: string;
2580
+ /**
2581
+ * Campo de contraseña con toggle interactivo de mostrar/ocultar.
2582
+ *
2583
+ * Renderiza un botón "ojo" como suffix que alterna el `type` del input entre
2584
+ * `password` (oculto) y `text` (visible). Cuando es `true`, el `type` se
2585
+ * gestiona internamente (se ignora la prop `type`). No tiene efecto si el
2586
+ * field es `readOnly`. Toma precedencia sobre `endIcon`.
2587
+ */
2588
+ revealable?: boolean;
2589
+ /**
2590
+ * aria-label del toggle de contraseña, para i18n.
2591
+ * @default 'Mostrar u ocultar contraseña'
2592
+ */
2593
+ revealLabel?: string;
2575
2594
  }
2576
2595
  declare const KdsTextField: React__default.ForwardRefExoticComponent<KdsTextFieldProps & React__default.RefAttributes<HTMLInputElement>>;
2577
2596
 
package/dist/index.d.ts CHANGED
@@ -2556,6 +2556,11 @@ declare const KdsButton: React__default.ForwardRefExoticComponent<KdsButtonProps
2556
2556
  * - El wrapper DEBE tener `.prefix` cuando hay icono al inicio (alinea la label al lado del icono).
2557
2557
  * - El wrapper DEBE tener `.suffix` cuando hay icono al final.
2558
2558
  *
2559
+ * Variante `revealable` (campo de contraseña con mostrar/ocultar):
2560
+ * - El toggle es un `<a role="button">` — BeerCSS posiciona como icono del field a
2561
+ * `:is(i, img, svg, progress.circle, a)` y da `pointer-events: all` solo a `<a>`/`.front`,
2562
+ * así que el anchor es el elemento interactivo idiomático del field (no `<button>`).
2563
+ *
2559
2564
  * @gsp `mat:textField`, `mat:emailField`, `mat:passwordField`, `mat:numberField` (taglib `matFieldImpl`)
2560
2565
  */
2561
2566
 
@@ -2572,6 +2577,20 @@ interface KdsTextFieldProps extends Omit<React__default.InputHTMLAttributes<HTML
2572
2577
  startIcon?: string;
2573
2578
  /** Material Symbol al final del input (aplica clase `.suffix`). */
2574
2579
  endIcon?: string;
2580
+ /**
2581
+ * Campo de contraseña con toggle interactivo de mostrar/ocultar.
2582
+ *
2583
+ * Renderiza un botón "ojo" como suffix que alterna el `type` del input entre
2584
+ * `password` (oculto) y `text` (visible). Cuando es `true`, el `type` se
2585
+ * gestiona internamente (se ignora la prop `type`). No tiene efecto si el
2586
+ * field es `readOnly`. Toma precedencia sobre `endIcon`.
2587
+ */
2588
+ revealable?: boolean;
2589
+ /**
2590
+ * aria-label del toggle de contraseña, para i18n.
2591
+ * @default 'Mostrar u ocultar contraseña'
2592
+ */
2593
+ revealLabel?: string;
2575
2594
  }
2576
2595
  declare const KdsTextField: React__default.ForwardRefExoticComponent<KdsTextFieldProps & React__default.RefAttributes<HTMLInputElement>>;
2577
2596
 
package/dist/index.js CHANGED
@@ -1179,10 +1179,23 @@ var KdsTextField = (0, import_react2.forwardRef)(
1179
1179
  required,
1180
1180
  className,
1181
1181
  id,
1182
+ type,
1183
+ revealable,
1184
+ revealLabel = "Mostrar u ocultar contrase\xF1a",
1182
1185
  ...props
1183
1186
  }, ref) => {
1187
+ const [revealed, setRevealed] = (0, import_react2.useState)(false);
1184
1188
  const fieldId = id || `kds-field-${label.toLowerCase().replace(/\s+/g, "-")}`;
1185
- const hasSuffix = !!endIcon || readOnly;
1189
+ const isRevealable = !!revealable && !readOnly && !props.disabled;
1190
+ const inputType = isRevealable ? revealed ? "text" : "password" : type;
1191
+ const hasSuffix = !!endIcon || readOnly || isRevealable;
1192
+ const toggleReveal = () => setRevealed((v) => !v);
1193
+ const onToggleKeyDown = (e) => {
1194
+ if (e.key === "Enter" || e.key === " ") {
1195
+ e.preventDefault();
1196
+ toggleReveal();
1197
+ }
1198
+ };
1186
1199
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1187
1200
  "div",
1188
1201
  {
@@ -1204,6 +1217,7 @@ var KdsTextField = (0, import_react2.forwardRef)(
1204
1217
  {
1205
1218
  ref,
1206
1219
  id: fieldId,
1220
+ type: inputType,
1207
1221
  readOnly,
1208
1222
  required,
1209
1223
  ...props,
@@ -1215,7 +1229,20 @@ var KdsTextField = (0, import_react2.forwardRef)(
1215
1229
  required && " *"
1216
1230
  ] }),
1217
1231
  readOnly && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", { className: "material-symbols-outlined", children: "lock" }),
1218
- endIcon && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", { className: "material-symbols-outlined", children: endIcon }),
1232
+ isRevealable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1233
+ "a",
1234
+ {
1235
+ className: "kds-field-reveal",
1236
+ role: "button",
1237
+ tabIndex: 0,
1238
+ "aria-label": revealLabel,
1239
+ "aria-pressed": revealed,
1240
+ onClick: toggleReveal,
1241
+ onKeyDown: onToggleKeyDown,
1242
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", { className: "material-symbols-outlined", "aria-hidden": "true", children: revealed ? "visibility" : "visibility_off" })
1243
+ }
1244
+ ),
1245
+ endIcon && !readOnly && !isRevealable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", { className: "material-symbols-outlined", children: endIcon }),
1219
1246
  helperText && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "helper", children: helperText })
1220
1247
  ]
1221
1248
  }
package/dist/index.mjs CHANGED
@@ -1057,7 +1057,7 @@ var KdsButton = forwardRef(
1057
1057
  KdsButton.displayName = "KdsButton";
1058
1058
 
1059
1059
  // src/components/core/KdsTextField/KdsTextField.tsx
1060
- import { forwardRef as forwardRef2 } from "react";
1060
+ import { forwardRef as forwardRef2, useState } from "react";
1061
1061
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1062
1062
  var KdsTextField = forwardRef2(
1063
1063
  ({
@@ -1071,10 +1071,23 @@ var KdsTextField = forwardRef2(
1071
1071
  required,
1072
1072
  className,
1073
1073
  id,
1074
+ type,
1075
+ revealable,
1076
+ revealLabel = "Mostrar u ocultar contrase\xF1a",
1074
1077
  ...props
1075
1078
  }, ref) => {
1079
+ const [revealed, setRevealed] = useState(false);
1076
1080
  const fieldId = id || `kds-field-${label.toLowerCase().replace(/\s+/g, "-")}`;
1077
- const hasSuffix = !!endIcon || readOnly;
1081
+ const isRevealable = !!revealable && !readOnly && !props.disabled;
1082
+ const inputType = isRevealable ? revealed ? "text" : "password" : type;
1083
+ const hasSuffix = !!endIcon || readOnly || isRevealable;
1084
+ const toggleReveal = () => setRevealed((v) => !v);
1085
+ const onToggleKeyDown = (e) => {
1086
+ if (e.key === "Enter" || e.key === " ") {
1087
+ e.preventDefault();
1088
+ toggleReveal();
1089
+ }
1090
+ };
1078
1091
  return /* @__PURE__ */ jsxs2(
1079
1092
  "div",
1080
1093
  {
@@ -1096,6 +1109,7 @@ var KdsTextField = forwardRef2(
1096
1109
  {
1097
1110
  ref,
1098
1111
  id: fieldId,
1112
+ type: inputType,
1099
1113
  readOnly,
1100
1114
  required,
1101
1115
  ...props,
@@ -1107,7 +1121,20 @@ var KdsTextField = forwardRef2(
1107
1121
  required && " *"
1108
1122
  ] }),
1109
1123
  readOnly && /* @__PURE__ */ jsx3("i", { className: "material-symbols-outlined", children: "lock" }),
1110
- endIcon && !readOnly && /* @__PURE__ */ jsx3("i", { className: "material-symbols-outlined", children: endIcon }),
1124
+ isRevealable && /* @__PURE__ */ jsx3(
1125
+ "a",
1126
+ {
1127
+ className: "kds-field-reveal",
1128
+ role: "button",
1129
+ tabIndex: 0,
1130
+ "aria-label": revealLabel,
1131
+ "aria-pressed": revealed,
1132
+ onClick: toggleReveal,
1133
+ onKeyDown: onToggleKeyDown,
1134
+ children: /* @__PURE__ */ jsx3("i", { className: "material-symbols-outlined", "aria-hidden": "true", children: revealed ? "visibility" : "visibility_off" })
1135
+ }
1136
+ ),
1137
+ endIcon && !readOnly && !isRevealable && /* @__PURE__ */ jsx3("i", { className: "material-symbols-outlined", children: endIcon }),
1111
1138
  helperText && /* @__PURE__ */ jsx3("span", { className: "helper", children: helperText })
1112
1139
  ]
1113
1140
  }
@@ -1220,9 +1247,9 @@ KdsSecureLoader.displayName = "KdsSecureLoader";
1220
1247
  import { forwardRef as forwardRef7 } from "react";
1221
1248
 
1222
1249
  // src/components/core/hooks/useCopyToClipboard.ts
1223
- import { useState, useCallback } from "react";
1250
+ import { useState as useState2, useCallback } from "react";
1224
1251
  function useCopyToClipboard(resetMs = 1200) {
1225
- const [copied, setCopied] = useState(false);
1252
+ const [copied, setCopied] = useState2(false);
1226
1253
  const copy = useCallback(
1227
1254
  async (text) => {
1228
1255
  try {
@@ -1555,9 +1582,9 @@ KdsChip.displayName = "KdsChip";
1555
1582
  import { forwardRef as forwardRef15 } from "react";
1556
1583
 
1557
1584
  // src/components/core/hooks/useAutoHide.ts
1558
- import { useState as useState2, useEffect, useRef } from "react";
1585
+ import { useState as useState3, useEffect, useRef } from "react";
1559
1586
  function useAutoHide(durationMs, onHide) {
1560
- const [visible, setVisible] = useState2(true);
1587
+ const [visible, setVisible] = useState3(true);
1561
1588
  const onHideRef = useRef(onHide);
1562
1589
  onHideRef.current = onHide;
1563
1590
  useEffect(() => {
@@ -1760,7 +1787,7 @@ var KdsCopyRow = forwardRef21(
1760
1787
  KdsCopyRow.displayName = "KdsCopyRow";
1761
1788
 
1762
1789
  // src/components/core/KdsCopyableTable/KdsCopyableTable.tsx
1763
- import { forwardRef as forwardRef22, useState as useState3, useRef as useRef2, useCallback as useCallback3 } from "react";
1790
+ import { forwardRef as forwardRef22, useState as useState4, useRef as useRef2, useCallback as useCallback3 } from "react";
1764
1791
  import { Fragment as Fragment2, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
1765
1792
  async function copyToClipboard(text) {
1766
1793
  try {
@@ -1797,9 +1824,9 @@ var KdsCopyableTable = forwardRef22(
1797
1824
  }, ref) => {
1798
1825
  const copiedTimers = useRef2(/* @__PURE__ */ new Map());
1799
1826
  const settlingTimers = useRef2(/* @__PURE__ */ new Map());
1800
- const [copiedRows, setCopiedRows] = useState3(/* @__PURE__ */ new Set());
1801
- const [settlingRows, setSettlingRows] = useState3(/* @__PURE__ */ new Set());
1802
- const [allCopied, setAllCopied] = useState3(false);
1827
+ const [copiedRows, setCopiedRows] = useState4(/* @__PURE__ */ new Set());
1828
+ const [settlingRows, setSettlingRows] = useState4(/* @__PURE__ */ new Set());
1829
+ const [allCopied, setAllCopied] = useState4(false);
1803
1830
  const markCopied = useCallback3((indexes, duration = 1500) => {
1804
1831
  setCopiedRows((prev) => {
1805
1832
  const next = new Set(prev);
@@ -1910,11 +1937,11 @@ var KdsCopyableTable = forwardRef22(
1910
1937
  KdsCopyableTable.displayName = "KdsCopyableTable";
1911
1938
 
1912
1939
  // src/components/core/KdsExpandPanel/KdsExpandPanel.tsx
1913
- import { forwardRef as forwardRef23, useState as useState4 } from "react";
1940
+ import { forwardRef as forwardRef23, useState as useState5 } from "react";
1914
1941
  import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
1915
1942
  var KdsExpandPanel = forwardRef23(
1916
1943
  ({ label, defaultExpanded = false, children, className, ...props }, ref) => {
1917
- const [expanded, setExpanded] = useState4(defaultExpanded);
1944
+ const [expanded, setExpanded] = useState5(defaultExpanded);
1918
1945
  return /* @__PURE__ */ jsxs19("div", { ref, className, ...props, children: [
1919
1946
  /* @__PURE__ */ jsxs19(
1920
1947
  "button",
@@ -1938,7 +1965,7 @@ KdsExpandPanel.displayName = "KdsExpandPanel";
1938
1965
  import { forwardRef as forwardRef24, useEffect as useEffect3, useRef as useRef3 } from "react";
1939
1966
 
1940
1967
  // src/components/core/hooks/useCountdown.ts
1941
- import { useState as useState5, useEffect as useEffect2 } from "react";
1968
+ import { useState as useState6, useEffect as useEffect2 } from "react";
1942
1969
  function calcRemaining(deadline) {
1943
1970
  const diff = Math.max(0, new Date(deadline).getTime() - Date.now());
1944
1971
  const totalSeconds = Math.floor(diff / 1e3);
@@ -1951,7 +1978,7 @@ function calcRemaining(deadline) {
1951
1978
  };
1952
1979
  }
1953
1980
  function useCountdown(deadline) {
1954
- const [state, setState] = useState5(() => calcRemaining(deadline));
1981
+ const [state, setState] = useState6(() => calcRemaining(deadline));
1955
1982
  useEffect2(() => {
1956
1983
  const tick = () => setState(calcRemaining(deadline));
1957
1984
  const id = setInterval(tick, 1e3);
@@ -2028,12 +2055,12 @@ var KdsBankList = forwardRef27(
2028
2055
  KdsBankList.displayName = "KdsBankList";
2029
2056
 
2030
2057
  // src/components/domain/KdsBankModal/KdsBankModal.tsx
2031
- import { forwardRef as forwardRef28, useState as useState6 } from "react";
2058
+ import { forwardRef as forwardRef28, useState as useState7 } from "react";
2032
2059
  import * as Dialog from "@radix-ui/react-dialog";
2033
2060
  import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2034
2061
  var KdsBankModal = forwardRef28(
2035
2062
  ({ open, onClose, title = "Selecciona tu banco", searchPlaceholder = "Buscar banco...", onSearch, children, className, container }, ref) => {
2036
- const [query, setQuery] = useState6("");
2063
+ const [query, setQuery] = useState7("");
2037
2064
  const handleSearch = (value) => {
2038
2065
  setQuery(value);
2039
2066
  onSearch?.(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khipu/design-system",
3
- "version": "0.2.0-alpha.48",
3
+ "version": "0.2.0-alpha.49",
4
4
  "description": "Khipu Design System - UI components and design tokens for the Khipu payment platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",