@studiolxd/brand 49.23.0 → 49.24.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/CHANGELOG.md +46 -0
- package/dist/_shared/brandmessagescontext.js +2 -2
- package/dist/_shared/colorpicker.js +247 -223
- package/dist/_types/atoms/Popover/Popover.d.ts +19 -3
- package/dist/_types/messages/BrandMessages.d.ts +7 -1
- package/dist/_types/messages/BrandMessagesContext.d.ts +7 -1
- package/dist/_types/messages/index.d.ts +1 -1
- package/dist/_types/molecules/ColorPicker/ColorPicker.d.ts +21 -2
- package/dist/_types/sections/AppHeader/AppHeader.d.ts +5 -2
- package/dist/popover.js +15 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,52 @@ El paquete sigue [semver](https://semver.org/lang/es/): **patch** para bug fixes
|
|
|
7
7
|
regeneración de `dist`, **minor** para componentes/props/variantes/tokens nuevos, **major**
|
|
8
8
|
para breaking changes.
|
|
9
9
|
|
|
10
|
+
## [49.24.0] — 2026-10-04
|
|
11
|
+
|
|
12
|
+
> **Minor.** Disparador propio y ancla sin disparador en `ColorPicker`, a petición de creator (la barra
|
|
13
|
+
> de texto enriquecido y la celda de una tabla). Sin tocar nada, todo sigue igual.
|
|
14
|
+
|
|
15
|
+
### `ColorPicker`: `trigger` y `anchor`
|
|
16
|
+
|
|
17
|
+
- **`trigger`**: un elemento propio como disparador en lugar de la muestra —un `Toggle` con glifo y
|
|
18
|
+
`ColorSwatch size="sm"`, un `Button`—, con el patrón del `trigger` de `Popover`/`Menu` y las props
|
|
19
|
+
por `render` (`useRender`, como `Button`). Recibe `id`, `aria-haspopup="dialog"`, `aria-expanded`,
|
|
20
|
+
`aria-controls`, `aria-label`/`aria-labelledby`, `aria-invalid`, `disabled` y la descripción con el
|
|
21
|
+
valor (`colorPicker.value`/`empty`); lo que el elemento ya traiga gana, salvo la descripción, que se
|
|
22
|
+
suma, y `disabled`. El `ref` del selector se suma al suyo. El foco vuelve a él al cerrar. No lee
|
|
23
|
+
`colorPicker.trigger`: se nombra por sí mismo o por `aria-label`/la etiqueta.
|
|
24
|
+
- **`anchor`**: coloca el panel contra otro elemento (la prop `anchor` de `Popover`). Sin `trigger`
|
|
25
|
+
no se pinta ninguna muestra: el panel se abre con `open` controlado, y al cerrarse el foco vuelve a
|
|
26
|
+
donde estaba antes de abrir.
|
|
27
|
+
- `ColorPickerField` reenvía las dos; con `trigger`, la etiqueta sigue nombrando el elemento.
|
|
28
|
+
- Stories «Con disparador propio» y «Anclado sin disparador», y sus `Test — …`.
|
|
29
|
+
|
|
30
|
+
### `Popover`: `anchor`, y `trigger` opcional
|
|
31
|
+
|
|
32
|
+
- **`anchor`** (tipo `PopoverAnchor`): la prop `anchor` del Positioner de Base UI, tal cual.
|
|
33
|
+
- **`trigger` pasa a opcional**: sin él no se pinta disparador y el panel se abre con `open` contra
|
|
34
|
+
`anchor`.
|
|
35
|
+
|
|
36
|
+
## [49.23.1] — 2026-10-04
|
|
37
|
+
|
|
38
|
+
> **Patch.** `appHeader` pasa a ser **opcional** en `BrandMessages`. En 49.23.0 entró obligatorio y un
|
|
39
|
+
> catálogo tipado estricto —un literal pasado a `BrandMessagesProvider` sin conversión, como el de
|
|
40
|
+
> `public-shell` en slxd— dejaba de compilar aunque no usara el logo: una minor no puede romper la
|
|
41
|
+
> compilación de nadie. Si ya declaraste `appHeader`, no hay que tocar nada.
|
|
42
|
+
|
|
43
|
+
- `BrandMessages.appHeader?` y `AppHeaderMessages.logo?`: solo hacen falta si algún `AppHeader` lleva
|
|
44
|
+
`logo` sin `logoLabel`.
|
|
45
|
+
- **Si ese caso llega sin `appHeader.logo` en el catálogo, `AppHeader` lanza** («el catálogo montado no
|
|
46
|
+
trae «appHeader.logo»»), igual que cualquier otra clave ausente: no hay castellano de respaldo y un
|
|
47
|
+
enlace sin nombre accesible tiene que verse en desarrollo. Documentado en `AppHeader` §
|
|
48
|
+
«Internacionalización».
|
|
49
|
+
- `BrandMessagesReader` lee los espacios opcionales sin `undefined` en el tipo devuelto (tipo nuevo
|
|
50
|
+
`BrandMessagesNamespace`); para los espacios obligatorios no cambia nada.
|
|
51
|
+
- Test de tipos (`BrandMessages.types.test.ts`): compila con el compilador de TypeScript un catálogo
|
|
52
|
+
sin `appHeader` contra `BrandMessages`, con un caso de control que sí debe fallar.
|
|
53
|
+
- Revisado el resto de 49.23.0: no añadió ningún otro campo obligatorio a tipos públicos (las props
|
|
54
|
+
nuevas de `AppHeader` ya eran opcionales).
|
|
55
|
+
|
|
10
56
|
## [49.23.0] — 2026-10-04
|
|
11
57
|
|
|
12
58
|
> **Minor.** Ranura `logo` en `AppHeader`, a petición de Homenize. Espacio nuevo `appHeader` en
|
|
@@ -4,10 +4,10 @@ var n = e(null);
|
|
|
4
4
|
function r(e) {
|
|
5
5
|
let r = t(n);
|
|
6
6
|
return function(t, n) {
|
|
7
|
-
if (n
|
|
7
|
+
if (n != null) return n;
|
|
8
8
|
if (!r) throw Error(`@studiolxd/brand: falta el texto «${String(e)}.${String(t)}» y no hay catálogo montado. Monta <BrandMessagesProvider> en la raíz de la aplicación con los textos del idioma vigente, o pasa la prop suelta en este uso concreto.`);
|
|
9
9
|
let i = r[e]?.[t];
|
|
10
|
-
if (i
|
|
10
|
+
if (i == null) throw Error(`@studiolxd/brand: el catálogo montado no trae «${String(e)}.${String(t)}».`);
|
|
11
11
|
return i;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
@@ -7,61 +7,62 @@ import { Popover as i } from "../popover.js";
|
|
|
7
7
|
import { Slider as a } from "../slider.js";
|
|
8
8
|
import { t as o } from "./css-properties.js";
|
|
9
9
|
import { ColorSwatch as s } from "../color-swatch.js";
|
|
10
|
-
import {
|
|
11
|
-
import { jsx as
|
|
12
|
-
import {
|
|
10
|
+
import { cloneElement as c, forwardRef as l, useCallback as u, useId as d, useRef as f, useState as p } from "react";
|
|
11
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
12
|
+
import { useRender as g } from "@base-ui/react/use-render";
|
|
13
|
+
import { useDirection as _ } from "@base-ui/react/direction-provider";
|
|
13
14
|
//#region src/stories/molecules/ColorPicker/ColorArea.tsx
|
|
14
|
-
var
|
|
15
|
-
let
|
|
15
|
+
var v = 1, y = 10, b = (e) => Math.min(100, Math.max(0, e)), x = l(function({ hueColor: e, saturation: t, brightness: n, onChange: r, onCommit: i, label: a, roleDescription: s, valueText: c, disabled: l = !1 }, d) {
|
|
16
|
+
let p = _() === "rtl", h = f(null), g = f(null), x = f({
|
|
16
17
|
s: 0,
|
|
17
18
|
v: 0
|
|
18
19
|
}), S = o({
|
|
19
|
-
"--color-picker-area-x": `${
|
|
20
|
+
"--color-picker-area-x": `${p ? 100 - t : t}%`,
|
|
20
21
|
"--color-picker-area-y": `${100 - n}%`,
|
|
21
22
|
"--color-picker-area-hue": e
|
|
22
|
-
}), C =
|
|
23
|
-
|
|
23
|
+
}), C = u((e) => {
|
|
24
|
+
h.current = e, S(e);
|
|
24
25
|
}, [S]), w = (e) => {
|
|
25
26
|
let t = e.currentTarget.getBoundingClientRect(), n = t.width ? (e.clientX - t.left) / t.width : 0, r = t.height ? (e.clientY - t.top) / t.height : 0;
|
|
26
27
|
return {
|
|
27
|
-
s:
|
|
28
|
-
v:
|
|
28
|
+
s: b((p ? 1 - n : n) * 100),
|
|
29
|
+
v: b((1 - r) * 100)
|
|
29
30
|
};
|
|
30
31
|
}, T = () => {
|
|
31
|
-
((typeof
|
|
32
|
+
((typeof d == "function" ? null : d?.current) ?? h.current?.querySelector("[role=\"slider\"]"))?.focus({ preventScroll: !0 });
|
|
32
33
|
}, E = (e) => {
|
|
33
|
-
if (
|
|
34
|
+
if (l || e.button !== 0) return;
|
|
34
35
|
e.preventDefault();
|
|
35
36
|
try {
|
|
36
37
|
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
37
38
|
} catch {}
|
|
38
|
-
|
|
39
|
+
g.current = e.pointerId, T();
|
|
39
40
|
let t = w(e);
|
|
40
41
|
x.current = t, r(t);
|
|
41
42
|
}, D = (e) => {
|
|
42
|
-
if (
|
|
43
|
+
if (g.current !== e.pointerId) return;
|
|
43
44
|
let t = w(e);
|
|
44
45
|
x.current = t, r(t);
|
|
45
46
|
}, O = (e) => {
|
|
46
|
-
if (
|
|
47
|
-
|
|
47
|
+
if (g.current === e.pointerId) {
|
|
48
|
+
g.current = null;
|
|
48
49
|
try {
|
|
49
50
|
e.currentTarget.releasePointerCapture?.(e.pointerId);
|
|
50
51
|
} catch {}
|
|
51
52
|
i(x.current);
|
|
52
53
|
}
|
|
53
54
|
}, k = (e) => {
|
|
54
|
-
if (
|
|
55
|
-
let a = e.shiftKey ?
|
|
55
|
+
if (l) return;
|
|
56
|
+
let a = e.shiftKey ? y : v, { s: o, v: s } = {
|
|
56
57
|
s: t,
|
|
57
58
|
v: n
|
|
58
59
|
};
|
|
59
60
|
switch (e.key) {
|
|
60
61
|
case "ArrowRight":
|
|
61
|
-
o +=
|
|
62
|
+
o += p ? -a : a;
|
|
62
63
|
break;
|
|
63
64
|
case "ArrowLeft":
|
|
64
|
-
o +=
|
|
65
|
+
o += p ? a : -a;
|
|
65
66
|
break;
|
|
66
67
|
case "ArrowUp":
|
|
67
68
|
s += a;
|
|
@@ -70,10 +71,10 @@ var g = 1, _ = 10, v = (e) => Math.min(100, Math.max(0, e)), y = c(function({ hu
|
|
|
70
71
|
s -= a;
|
|
71
72
|
break;
|
|
72
73
|
case "PageUp":
|
|
73
|
-
e.shiftKey ? o +=
|
|
74
|
+
e.shiftKey ? o += y : s += y;
|
|
74
75
|
break;
|
|
75
76
|
case "PageDown":
|
|
76
|
-
e.shiftKey ? o -=
|
|
77
|
+
e.shiftKey ? o -= y : s -= y;
|
|
77
78
|
break;
|
|
78
79
|
case "Home":
|
|
79
80
|
e.ctrlKey || e.metaKey ? s = 0 : o = 0;
|
|
@@ -85,37 +86,37 @@ var g = 1, _ = 10, v = (e) => Math.min(100, Math.max(0, e)), y = c(function({ hu
|
|
|
85
86
|
}
|
|
86
87
|
e.preventDefault();
|
|
87
88
|
let c = {
|
|
88
|
-
s:
|
|
89
|
-
v:
|
|
89
|
+
s: b(o),
|
|
90
|
+
v: b(s)
|
|
90
91
|
};
|
|
91
92
|
r(c), i(c);
|
|
92
93
|
};
|
|
93
|
-
return /* @__PURE__ */
|
|
94
|
+
return /* @__PURE__ */ m("div", {
|
|
94
95
|
ref: C,
|
|
95
96
|
className: "color-picker__area",
|
|
96
|
-
"data-direction":
|
|
97
|
-
"data-disabled":
|
|
97
|
+
"data-direction": p ? "rtl" : "ltr",
|
|
98
|
+
"data-disabled": l ? "" : void 0,
|
|
98
99
|
onPointerDown: E,
|
|
99
100
|
onPointerMove: D,
|
|
100
101
|
onPointerUp: O,
|
|
101
102
|
onPointerCancel: O,
|
|
102
|
-
children: /* @__PURE__ */
|
|
103
|
-
ref:
|
|
103
|
+
children: /* @__PURE__ */ m("div", {
|
|
104
|
+
ref: d,
|
|
104
105
|
className: "color-picker__area-thumb",
|
|
105
106
|
role: "slider",
|
|
106
|
-
tabIndex:
|
|
107
|
+
tabIndex: l ? -1 : 0,
|
|
107
108
|
"aria-label": a,
|
|
108
109
|
"aria-roledescription": s,
|
|
109
110
|
"aria-valuemin": 0,
|
|
110
111
|
"aria-valuemax": 100,
|
|
111
112
|
"aria-valuenow": Math.round(t),
|
|
112
113
|
"aria-valuetext": c,
|
|
113
|
-
"aria-disabled":
|
|
114
|
+
"aria-disabled": l || void 0,
|
|
114
115
|
onKeyDown: k
|
|
115
116
|
})
|
|
116
117
|
});
|
|
117
|
-
}),
|
|
118
|
-
function
|
|
118
|
+
}), S = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
119
|
+
function C(e) {
|
|
119
120
|
let t = e.trim().replace(/^#/, "");
|
|
120
121
|
if (!/^[0-9a-f]+$/i.test(t)) return null;
|
|
121
122
|
let n;
|
|
@@ -130,12 +131,12 @@ function x(e) {
|
|
|
130
131
|
a: n.length === 8 ? r(3) / 255 : 1
|
|
131
132
|
};
|
|
132
133
|
}
|
|
133
|
-
var
|
|
134
|
-
function
|
|
135
|
-
let a = `#${
|
|
136
|
-
return i ? `${a}${S(
|
|
134
|
+
var w = (e) => S(Math.round(e), 0, 255).toString(16).padStart(2, "0");
|
|
135
|
+
function T({ r: e, g: t, b: n, a: r }, i) {
|
|
136
|
+
let a = `#${w(e)}${w(t)}${w(n)}`;
|
|
137
|
+
return i ? `${a}${w(S(r, 0, 1) * 255)}` : a;
|
|
137
138
|
}
|
|
138
|
-
function
|
|
139
|
+
function E({ r: e, g: t, b: n, a: r }) {
|
|
139
140
|
let i = e / 255, a = t / 255, o = n / 255, s = Math.max(i, a, o), c = s - Math.min(i, a, o), l = 0;
|
|
140
141
|
return c !== 0 && (l = s === i ? (a - o) / c % 6 : s === a ? (o - i) / c + 2 : (i - a) / c + 4, l *= 60, l < 0 && (l += 360)), {
|
|
141
142
|
h: l,
|
|
@@ -144,8 +145,8 @@ function w({ r: e, g: t, b: n, a: r }) {
|
|
|
144
145
|
a: r
|
|
145
146
|
};
|
|
146
147
|
}
|
|
147
|
-
function
|
|
148
|
-
let i = (e % 360 + 360) % 360, a =
|
|
148
|
+
function D({ h: e, s: t, v: n, a: r }) {
|
|
149
|
+
let i = (e % 360 + 360) % 360, a = S(t, 0, 100) / 100, o = S(n, 0, 100) / 100, s = o * a, c = s * (1 - Math.abs(i / 60 % 2 - 1)), l = o - s, u;
|
|
149
150
|
return u = i < 60 ? [
|
|
150
151
|
s,
|
|
151
152
|
c,
|
|
@@ -174,21 +175,21 @@ function T({ h: e, s: t, v: n, a: r }) {
|
|
|
174
175
|
r: (u[0] + l) * 255,
|
|
175
176
|
g: (u[1] + l) * 255,
|
|
176
177
|
b: (u[2] + l) * 255,
|
|
177
|
-
a:
|
|
178
|
+
a: S(r, 0, 1)
|
|
178
179
|
};
|
|
179
180
|
}
|
|
180
|
-
function
|
|
181
|
-
let t =
|
|
182
|
-
return t ?
|
|
181
|
+
function O(e) {
|
|
182
|
+
let t = C(e);
|
|
183
|
+
return t ? E(t) : null;
|
|
183
184
|
}
|
|
184
|
-
function
|
|
185
|
-
return
|
|
185
|
+
function k(e, t) {
|
|
186
|
+
return T(D(e), t);
|
|
186
187
|
}
|
|
187
|
-
function
|
|
188
|
-
let n =
|
|
189
|
-
return n ?
|
|
188
|
+
function A(e, t) {
|
|
189
|
+
let n = C(e);
|
|
190
|
+
return n ? T(n, t) : null;
|
|
190
191
|
}
|
|
191
|
-
function
|
|
192
|
+
function ee() {
|
|
192
193
|
return [
|
|
193
194
|
0,
|
|
194
195
|
60,
|
|
@@ -197,7 +198,7 @@ function k() {
|
|
|
197
198
|
240,
|
|
198
199
|
300,
|
|
199
200
|
360
|
|
200
|
-
].map((e) =>
|
|
201
|
+
].map((e) => k({
|
|
201
202
|
h: e,
|
|
202
203
|
s: 100,
|
|
203
204
|
v: 100,
|
|
@@ -206,205 +207,228 @@ function k() {
|
|
|
206
207
|
}
|
|
207
208
|
//#endregion
|
|
208
209
|
//#region src/stories/molecules/ColorPicker/ColorPicker.tsx
|
|
209
|
-
var
|
|
210
|
+
var j = {
|
|
210
211
|
h: 0,
|
|
211
212
|
s: 0,
|
|
212
213
|
v: 0,
|
|
213
214
|
a: 1
|
|
214
|
-
},
|
|
215
|
-
let
|
|
216
|
-
|
|
217
|
-
let
|
|
218
|
-
...
|
|
215
|
+
}, te = l(function({ value: l, defaultValue: v = null, onValueChange: y, onValueCommitted: b, alpha: S = !1, presets: C, clearable: w = !1, onClear: T, open: E, defaultOpen: D = !1, onOpenChange: te, size: M = "md", disabled: N = !1, error: P = !1, locale: ne = "es-ES", id: re, name: F, "aria-label": I, "aria-labelledby": L, "aria-describedby": ie, dialogLabel: ae, clearLabel: oe, trigger: R, anchor: z, className: se }, B) {
|
|
216
|
+
let V = e("colorPicker"), H = _() === "rtl", [ce, U] = p(D), W = E ?? ce, G = l !== void 0, [le, ue] = p(v), K = G ? l : le, q = K ? A(K, S) : null, [J, de] = p(() => q && O(q) || j), [fe, pe] = p(q);
|
|
217
|
+
q !== fe && (pe(q), q && k(J, S) !== q && de(O(q) ?? j));
|
|
218
|
+
let me = k(J, S), he = k({
|
|
219
|
+
...J,
|
|
219
220
|
a: 1
|
|
220
|
-
}, !1), Y =
|
|
221
|
-
let n =
|
|
221
|
+
}, !1), Y = u((e, t) => {
|
|
222
|
+
let n = S ? e : {
|
|
222
223
|
...e,
|
|
223
224
|
a: 1
|
|
224
225
|
};
|
|
225
|
-
|
|
226
|
-
let r =
|
|
227
|
-
|
|
226
|
+
de(n);
|
|
227
|
+
let r = k(n, S);
|
|
228
|
+
G || ue(r), y?.(r), t && b?.(r);
|
|
228
229
|
}, [
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
]), [X, Z] =
|
|
234
|
-
|
|
235
|
-
let
|
|
236
|
-
let n =
|
|
230
|
+
S,
|
|
231
|
+
G,
|
|
232
|
+
y,
|
|
233
|
+
b
|
|
234
|
+
]), [X, Z] = p(null), [ge, _e] = p(W);
|
|
235
|
+
W !== ge && (_e(W), W || Z(null));
|
|
236
|
+
let ve = (e, t) => {
|
|
237
|
+
let n = A(e, S), r = n ? O(n) : null;
|
|
237
238
|
return r ? (Y(r, t), !0) : !1;
|
|
238
|
-
},
|
|
239
|
+
}, ye = (e) => {
|
|
239
240
|
let t = e.target.value;
|
|
240
241
|
Z(t);
|
|
241
242
|
let n = t.trim().replace(/^#/, "").length;
|
|
242
|
-
(n === 6 ||
|
|
243
|
-
},
|
|
244
|
-
X !== null &&
|
|
245
|
-
},
|
|
246
|
-
|
|
247
|
-
},
|
|
248
|
-
e &&
|
|
249
|
-
},
|
|
250
|
-
"--color-picker-hue-gradient": `linear-gradient(to ${
|
|
251
|
-
"--color-picker-alpha-gradient": `linear-gradient(to ${
|
|
252
|
-
}),
|
|
253
|
-
...
|
|
243
|
+
(n === 6 || S && n === 8) && ve(t, !0);
|
|
244
|
+
}, be = () => {
|
|
245
|
+
X !== null && ve(X, !0), Z(null);
|
|
246
|
+
}, xe = () => {
|
|
247
|
+
G || ue(null), T?.(), E === void 0 && U(!1);
|
|
248
|
+
}, Se = (e, t) => {
|
|
249
|
+
e && N || (E === void 0 && U(e), te?.(e, t));
|
|
250
|
+
}, Ce = f(null), Q = d(), we = o({
|
|
251
|
+
"--color-picker-hue-gradient": `linear-gradient(to ${H ? "left" : "right"}, ${ee().join(", ")})`,
|
|
252
|
+
"--color-picker-alpha-gradient": `linear-gradient(to ${H ? "left" : "right"}, transparent, ${he})`
|
|
253
|
+
}), Te = (e) => Y({
|
|
254
|
+
...J,
|
|
254
255
|
s: e.s,
|
|
255
256
|
v: e.v
|
|
256
|
-
}, !1),
|
|
257
|
-
...
|
|
257
|
+
}, !1), Ee = (e) => Y({
|
|
258
|
+
...J,
|
|
258
259
|
s: e.s,
|
|
259
260
|
v: e.v
|
|
260
|
-
}, !0),
|
|
261
|
+
}, !0), De = (C ?? []).map((e) => ({
|
|
261
262
|
...e,
|
|
262
|
-
hex:
|
|
263
|
-
})).filter((e) => e.hex !== null),
|
|
263
|
+
hex: A(e.color, S)
|
|
264
|
+
})).filter((e) => e.hex !== null), Oe = [
|
|
264
265
|
"color-picker",
|
|
265
266
|
M === "md" ? "" : `color-picker--${M}`,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
].filter(Boolean).join(" "),
|
|
269
|
-
ref:
|
|
270
|
-
id:
|
|
267
|
+
P ? "color-picker--error" : "",
|
|
268
|
+
se ?? ""
|
|
269
|
+
].filter(Boolean).join(" "), ke = [Q, ie].filter(Boolean).join(" "), Ae = /* @__PURE__ */ h("button", {
|
|
270
|
+
ref: B,
|
|
271
|
+
id: re,
|
|
271
272
|
type: "button",
|
|
272
273
|
className: "color-picker__trigger",
|
|
273
|
-
disabled:
|
|
274
|
-
"aria-label": I ?? (L ? void 0 :
|
|
274
|
+
disabled: N,
|
|
275
|
+
"aria-label": I ?? (L ? void 0 : V("trigger")),
|
|
275
276
|
"aria-labelledby": I ? void 0 : L,
|
|
276
|
-
"aria-describedby":
|
|
277
|
+
"aria-describedby": ke,
|
|
277
278
|
"aria-haspopup": "dialog",
|
|
278
|
-
"aria-expanded":
|
|
279
|
-
"aria-invalid":
|
|
280
|
-
children: [/* @__PURE__ */
|
|
281
|
-
color:
|
|
279
|
+
"aria-expanded": W,
|
|
280
|
+
"aria-invalid": P || void 0,
|
|
281
|
+
children: [/* @__PURE__ */ m(s, {
|
|
282
|
+
color: K,
|
|
282
283
|
className: "color-picker__swatch"
|
|
283
|
-
}), /* @__PURE__ */
|
|
284
|
-
id:
|
|
285
|
-
children:
|
|
284
|
+
}), /* @__PURE__ */ m(t, {
|
|
285
|
+
id: Q,
|
|
286
|
+
children: K ? V("value")(q ?? K) : V("empty")
|
|
286
287
|
})]
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
label:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
"
|
|
389
|
-
"
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
288
|
+
}), je = R?.props ?? {}, Me = g({
|
|
289
|
+
render: R && c(R, {
|
|
290
|
+
disabled: N || je.disabled || void 0,
|
|
291
|
+
"aria-describedby": [ke, je["aria-describedby"]].filter(Boolean).join(" ")
|
|
292
|
+
}),
|
|
293
|
+
ref: B,
|
|
294
|
+
enabled: R !== void 0,
|
|
295
|
+
props: {
|
|
296
|
+
id: re,
|
|
297
|
+
"aria-label": I,
|
|
298
|
+
"aria-labelledby": I ? void 0 : L,
|
|
299
|
+
"aria-haspopup": "dialog",
|
|
300
|
+
"aria-expanded": W,
|
|
301
|
+
"aria-invalid": P || void 0
|
|
302
|
+
}
|
|
303
|
+
}), $;
|
|
304
|
+
return Me ? $ = Me : z === void 0 && ($ = Ae), /* @__PURE__ */ h("div", {
|
|
305
|
+
className: Oe,
|
|
306
|
+
children: [
|
|
307
|
+
F && /* @__PURE__ */ m("input", {
|
|
308
|
+
type: "hidden",
|
|
309
|
+
name: F,
|
|
310
|
+
value: q ?? ""
|
|
311
|
+
}),
|
|
312
|
+
R && /* @__PURE__ */ m(t, {
|
|
313
|
+
id: Q,
|
|
314
|
+
children: K ? V("value")(q ?? K) : V("empty")
|
|
315
|
+
}),
|
|
316
|
+
/* @__PURE__ */ m(i, {
|
|
317
|
+
trigger: $,
|
|
318
|
+
anchor: z,
|
|
319
|
+
label: V("dialog", ae),
|
|
320
|
+
open: W,
|
|
321
|
+
onOpenChange: Se,
|
|
322
|
+
side: "bottom",
|
|
323
|
+
align: "start",
|
|
324
|
+
initialFocus: Ce,
|
|
325
|
+
className: "color-picker__popover",
|
|
326
|
+
children: /* @__PURE__ */ h("div", {
|
|
327
|
+
ref: we,
|
|
328
|
+
className: "color-picker__panel",
|
|
329
|
+
children: [
|
|
330
|
+
/* @__PURE__ */ m(x, {
|
|
331
|
+
ref: Ce,
|
|
332
|
+
hueColor: k({
|
|
333
|
+
h: J.h,
|
|
334
|
+
s: 100,
|
|
335
|
+
v: 100,
|
|
336
|
+
a: 1
|
|
337
|
+
}, !1),
|
|
338
|
+
saturation: J.s,
|
|
339
|
+
brightness: J.v,
|
|
340
|
+
onChange: Te,
|
|
341
|
+
onCommit: Ee,
|
|
342
|
+
label: V("area"),
|
|
343
|
+
roleDescription: V("areaDescription"),
|
|
344
|
+
valueText: V("areaValue")(Math.round(J.s), Math.round(J.v))
|
|
345
|
+
}),
|
|
346
|
+
/* @__PURE__ */ m(a, {
|
|
347
|
+
className: "color-picker__channel color-picker__channel--hue",
|
|
348
|
+
label: V("hue"),
|
|
349
|
+
min: 0,
|
|
350
|
+
max: 360,
|
|
351
|
+
step: 1,
|
|
352
|
+
value: Math.round(J.h),
|
|
353
|
+
format: {
|
|
354
|
+
style: "unit",
|
|
355
|
+
unit: "degree"
|
|
356
|
+
},
|
|
357
|
+
locale: ne,
|
|
358
|
+
onValueChange: (e) => Y({
|
|
359
|
+
...J,
|
|
360
|
+
h: e
|
|
361
|
+
}, !1),
|
|
362
|
+
onValueCommitted: (e) => Y({
|
|
363
|
+
...J,
|
|
364
|
+
h: e
|
|
365
|
+
}, !0)
|
|
366
|
+
}),
|
|
367
|
+
S && /* @__PURE__ */ m(a, {
|
|
368
|
+
className: "color-picker__channel color-picker__channel--alpha",
|
|
369
|
+
label: V("alpha"),
|
|
370
|
+
min: 0,
|
|
371
|
+
max: 100,
|
|
372
|
+
step: 1,
|
|
373
|
+
value: Math.round(J.a * 100),
|
|
374
|
+
format: {
|
|
375
|
+
style: "unit",
|
|
376
|
+
unit: "percent"
|
|
377
|
+
},
|
|
378
|
+
locale: ne,
|
|
379
|
+
onValueChange: (e) => Y({
|
|
380
|
+
...J,
|
|
381
|
+
a: e / 100
|
|
382
|
+
}, !1),
|
|
383
|
+
onValueCommitted: (e) => Y({
|
|
384
|
+
...J,
|
|
385
|
+
a: e / 100
|
|
386
|
+
}, !0)
|
|
387
|
+
}),
|
|
388
|
+
/* @__PURE__ */ m(r, {
|
|
389
|
+
className: "color-picker__hex",
|
|
390
|
+
type: "text",
|
|
391
|
+
size: M,
|
|
392
|
+
"aria-label": V("hex"),
|
|
393
|
+
autoComplete: "off",
|
|
394
|
+
spellCheck: !1,
|
|
395
|
+
maxLength: S ? 9 : 7,
|
|
396
|
+
value: X ?? me,
|
|
397
|
+
onChange: ye,
|
|
398
|
+
onBlur: be,
|
|
399
|
+
onKeyDown: (e) => {
|
|
400
|
+
e.key === "Enter" && (e.preventDefault(), be());
|
|
401
|
+
}
|
|
402
|
+
}),
|
|
403
|
+
De.length > 0 && /* @__PURE__ */ m("div", {
|
|
404
|
+
className: "color-picker__presets",
|
|
405
|
+
role: "group",
|
|
406
|
+
"aria-label": V("presets"),
|
|
407
|
+
children: De.map((e) => /* @__PURE__ */ m("button", {
|
|
408
|
+
type: "button",
|
|
409
|
+
className: "color-picker__preset",
|
|
410
|
+
title: e.title,
|
|
411
|
+
"aria-label": e.title,
|
|
412
|
+
"aria-pressed": e.hex === me,
|
|
413
|
+
onClick: () => Y(O(e.hex) ?? j, !0),
|
|
414
|
+
children: /* @__PURE__ */ m(s, {
|
|
415
|
+
color: e.hex,
|
|
416
|
+
className: "color-picker__preset-swatch"
|
|
417
|
+
})
|
|
418
|
+
}, `${e.hex}-${e.title}`))
|
|
419
|
+
}),
|
|
420
|
+
w && /* @__PURE__ */ m(n, {
|
|
421
|
+
variant: "ghost",
|
|
422
|
+
size: "sm",
|
|
423
|
+
className: "color-picker__clear",
|
|
424
|
+
onClick: xe,
|
|
425
|
+
children: V("clear", oe)
|
|
426
|
+
})
|
|
427
|
+
]
|
|
428
|
+
})
|
|
405
429
|
})
|
|
406
|
-
|
|
430
|
+
]
|
|
407
431
|
});
|
|
408
432
|
});
|
|
409
433
|
//#endregion
|
|
410
|
-
export {
|
|
434
|
+
export { te as t };
|
|
@@ -8,9 +8,25 @@ import './Popover.css';
|
|
|
8
8
|
* forma a mano.
|
|
9
9
|
*/
|
|
10
10
|
export type PopoverChangeDetails = Parameters<NonNullable<React.ComponentProps<typeof BasePopover.Root>['onOpenChange']>>[1];
|
|
11
|
+
/**
|
|
12
|
+
* Elemento contra el que se coloca el panel cuando no es el disparador. Es la
|
|
13
|
+
* prop `anchor` del Positioner de Base UI, tal cual: un elemento, un `ref`, un
|
|
14
|
+
* elemento virtual o una función que lo devuelva.
|
|
15
|
+
*/
|
|
16
|
+
export type PopoverAnchor = React.ComponentProps<typeof BasePopover.Positioner>['anchor'];
|
|
11
17
|
export interface PopoverProps {
|
|
12
|
-
/**
|
|
13
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Elemento que abre el panel. Recibe las props del disparador vía `render`.
|
|
20
|
+
* Sin él no se pinta disparador: el panel se abre con `open` y se coloca
|
|
21
|
+
* contra `anchor`.
|
|
22
|
+
*/
|
|
23
|
+
trigger?: ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Coloca el panel contra otro elemento que no es el disparador —o, sin
|
|
26
|
+
* disparador, contra el único que hay—. Por defecto, el disparador. Sin
|
|
27
|
+
* disparador, al cerrarse el foco vuelve a donde estaba antes de abrir.
|
|
28
|
+
*/
|
|
29
|
+
anchor?: PopoverAnchor;
|
|
14
30
|
/** Contenido del panel. */
|
|
15
31
|
children: ReactNode;
|
|
16
32
|
/**
|
|
@@ -74,4 +90,4 @@ export interface PopoverProps {
|
|
|
74
90
|
* mantener el panel abierto cuando el clic cae en algo que el motor no
|
|
75
91
|
* reconoce como suyo.
|
|
76
92
|
*/
|
|
77
|
-
export declare function Popover({ trigger, children, label, open, defaultOpen, onOpenChange, onPointerDownOutside, onFocusOutside, onEscapeKeyDown, side, align, sideOffset, initialFocus, container, className, }: PopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
93
|
+
export declare function Popover({ trigger, anchor, children, label, open, defaultOpen, onOpenChange, onPointerDownOutside, onFocusOutside, onEscapeKeyDown, side, align, sideOffset, initialFocus, container, className, }: PopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -143,7 +143,13 @@ export interface BrandMessages {
|
|
|
143
143
|
menuButton: MenuButtonMessages;
|
|
144
144
|
appRoot: AppRootMessages;
|
|
145
145
|
appShell: AppShellMessages;
|
|
146
|
-
|
|
146
|
+
/**
|
|
147
|
+
* **Opcional** (desde v49.23.1): solo lo lee el `AppHeader` cuando lleva
|
|
148
|
+
* `logo` y no recibe `logoLabel`. En v49.23.0 entró obligatorio y rompía la
|
|
149
|
+
* compilación de catálogos que no usan el logo. Si un `AppHeader` lo
|
|
150
|
+
* necesita y falta, lanza como cualquier otra clave ausente.
|
|
151
|
+
*/
|
|
152
|
+
appHeader?: AppHeaderMessages;
|
|
147
153
|
sidebar: SidebarMessages;
|
|
148
154
|
sidebarNav: SidebarNavMessages;
|
|
149
155
|
siteNav: SiteNavMessages;
|
|
@@ -11,8 +11,14 @@ export declare const BrandMessagesContext: import("react").Context<BrandMessages
|
|
|
11
11
|
* consumidor la pasa.
|
|
12
12
|
*/
|
|
13
13
|
export interface BrandMessagesReader<K extends keyof BrandMessages> {
|
|
14
|
-
<N extends keyof
|
|
14
|
+
<N extends keyof BrandMessagesNamespace<K>>(key: N, override?: BrandMessagesNamespace<K>[N]): NonNullable<BrandMessagesNamespace<K>[N]>;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* El espacio de un componente, sin el `undefined` de los espacios opcionales
|
|
18
|
+
* (`appHeader`): el lector nunca devuelve `undefined`, porque si el texto
|
|
19
|
+
* falta lanza.
|
|
20
|
+
*/
|
|
21
|
+
export type BrandMessagesNamespace<K extends keyof BrandMessages> = NonNullable<BrandMessages[K]>;
|
|
16
22
|
/**
|
|
17
23
|
* El lector del espacio de un componente. Se llama **en el punto donde el
|
|
18
24
|
* texto se pinta**, no al principio del render: así un componente que no
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { BrandMessagesProvider } from './BrandMessagesProvider';
|
|
2
2
|
export type { BrandMessagesProviderProps } from './BrandMessagesProvider';
|
|
3
3
|
export { useBrandMessages } from './BrandMessagesContext';
|
|
4
|
-
export type { BrandMessagesReader } from './BrandMessagesContext';
|
|
4
|
+
export type { BrandMessagesReader, BrandMessagesNamespace } from './BrandMessagesContext';
|
|
5
5
|
export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, SiteSearchMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, ColorPickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, AppHeaderMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, ClockWidgetMessages, HeatmapMessages, OrgChartMessages, PlanningGridMessages, RecurrenceFieldMessages, TimelineMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, } from './BrandMessages';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { PopoverAnchor, PopoverChangeDetails } from '../../atoms/Popover/Popover';
|
|
2
3
|
import './ColorPicker.css';
|
|
3
4
|
/**
|
|
4
5
|
* El cromo del selector de color. Ninguno trae el castellano puesto: salen
|
|
@@ -115,6 +116,24 @@ export interface ColorPickerProps {
|
|
|
115
116
|
dialogLabel?: string;
|
|
116
117
|
/** Texto de «Quitar color». **Sin default**: sin él, `colorPicker.clear`. */
|
|
117
118
|
clearLabel?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Disparador propio en lugar de la muestra: un `Toggle` con icono, un
|
|
121
|
+
* `Button`… Como el `trigger` de `Popover`, recibe las props del disparador
|
|
122
|
+
* por `render`, así que tiene que reenviarlas (y el `ref`) a su elemento.
|
|
123
|
+
* El selector le añade `id`, `disabled`, `aria-haspopup`, `aria-expanded`,
|
|
124
|
+
* `aria-invalid`, `aria-label` / `aria-labelledby` y la descripción con el
|
|
125
|
+
* valor actual; lo que el elemento ya traiga gana, salvo la descripción, que
|
|
126
|
+
* se suma, y `disabled`, que basta con que lo diga uno. Lo que pinte dentro
|
|
127
|
+
* (y su `pressed`, si es un `Toggle`) lo decide quien lo usa.
|
|
128
|
+
*/
|
|
129
|
+
trigger?: ReactElement<Record<string, unknown>>;
|
|
130
|
+
/**
|
|
131
|
+
* Coloca el panel contra un elemento que no es el disparador —la celda de una
|
|
132
|
+
* tabla— (la prop `anchor` de `Popover`). Sin `trigger`, no se pinta ningún
|
|
133
|
+
* disparador: el panel se abre solo con `open`, y al cerrarse el foco vuelve
|
|
134
|
+
* a donde estaba antes de abrir.
|
|
135
|
+
*/
|
|
136
|
+
anchor?: PopoverAnchor;
|
|
118
137
|
/** Se añade DESPUÉS de las clases propias. */
|
|
119
138
|
className?: string;
|
|
120
139
|
}
|
|
@@ -125,6 +144,6 @@ export interface ColorPickerProps {
|
|
|
125
144
|
*
|
|
126
145
|
* Todo es Base UI salvo el área 2D: el `Popover` (foco, portal, cierre), las
|
|
127
146
|
* bandas (`Slider`) y el campo (`Input`) son los de brand. El `ref` va al
|
|
128
|
-
* disparador.
|
|
147
|
+
* disparador, sea la muestra o el `trigger` propio.
|
|
129
148
|
*/
|
|
130
149
|
export declare const ColorPicker: import("react").ForwardRefExoticComponent<ColorPickerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -12,8 +12,11 @@ export type AppHeaderLogoLinkProps = {
|
|
|
12
12
|
* que `siteHeader.logo`.
|
|
13
13
|
*/
|
|
14
14
|
export interface AppHeaderMessages {
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Texto accesible del enlace del logotipo. Opcional, como el espacio entero:
|
|
17
|
+
* solo hace falta si algún `AppHeader` lleva `logo` sin `logoLabel`.
|
|
18
|
+
*/
|
|
19
|
+
logo?: string;
|
|
17
20
|
}
|
|
18
21
|
export interface AppHeaderProps {
|
|
19
22
|
/**
|
package/dist/popover.js
CHANGED
|
@@ -12,26 +12,27 @@ function a() {
|
|
|
12
12
|
let e = document.documentElement;
|
|
13
13
|
return i(getComputedStyle(e).getPropertyValue("--popover-offset").trim());
|
|
14
14
|
}
|
|
15
|
-
function o({ trigger: i,
|
|
16
|
-
let
|
|
15
|
+
function o({ trigger: i, anchor: o, children: s, label: c, open: l, defaultOpen: u, onOpenChange: d, onPointerDownOutside: f, onFocusOutside: p, onEscapeKeyDown: m, side: h = "bottom", align: g = "start", sideOffset: _, initialFocus: v, container: y, className: b }) {
|
|
16
|
+
let x = e(y);
|
|
17
17
|
return /* @__PURE__ */ n(r.Root, {
|
|
18
|
-
open:
|
|
19
|
-
defaultOpen:
|
|
18
|
+
open: l,
|
|
19
|
+
defaultOpen: u,
|
|
20
20
|
onOpenChange: (e, t) => {
|
|
21
|
-
e || (t.reason === "outside-press" ?
|
|
21
|
+
e || (t.reason === "outside-press" ? f?.(t) : t.reason === "focus-out" ? p?.(t) : t.reason === "escape-key" && m?.(t)), d?.(e, t);
|
|
22
22
|
},
|
|
23
|
-
children: [/* @__PURE__ */ t(r.Trigger, { render: i }), /* @__PURE__ */ t(r.Portal, {
|
|
24
|
-
container:
|
|
23
|
+
children: [i !== void 0 && /* @__PURE__ */ t(r.Trigger, { render: i }), /* @__PURE__ */ t(r.Portal, {
|
|
24
|
+
container: x,
|
|
25
25
|
children: /* @__PURE__ */ t(r.Positioner, {
|
|
26
26
|
className: "popover__positioner",
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
anchor: o,
|
|
28
|
+
side: h,
|
|
29
|
+
align: g,
|
|
30
|
+
sideOffset: _ ?? a,
|
|
30
31
|
children: /* @__PURE__ */ t(r.Popup, {
|
|
31
|
-
"aria-label":
|
|
32
|
-
initialFocus:
|
|
33
|
-
className: ["popover",
|
|
34
|
-
children:
|
|
32
|
+
"aria-label": c,
|
|
33
|
+
initialFocus: v,
|
|
34
|
+
className: ["popover", b].filter(Boolean).join(" "),
|
|
35
|
+
children: s
|
|
35
36
|
})
|
|
36
37
|
})
|
|
37
38
|
})]
|