@komensal/ui 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -0
- package/dist/index.d.ts +550 -3
- package/dist/index.js +101 -20
- package/dist/index.js.map +1 -1
- package/package.json +11 -7
package/dist/index.js
CHANGED
|
@@ -110,7 +110,55 @@ import * as React2 from "react";
|
|
|
110
110
|
|
|
111
111
|
// src/components/spinner.tsx
|
|
112
112
|
import clsx2 from "clsx";
|
|
113
|
-
|
|
113
|
+
|
|
114
|
+
// src/lib/i18n.ts
|
|
115
|
+
import i18n from "i18next";
|
|
116
|
+
import { initReactI18next, useTranslation } from "react-i18next";
|
|
117
|
+
|
|
118
|
+
// src/locales/es/ui.json
|
|
119
|
+
var ui_default = {
|
|
120
|
+
otpField: {
|
|
121
|
+
description: "Se ha enviado un c\xF3digo OTP a tu correo . Revisa tu bandeja de entrada."
|
|
122
|
+
},
|
|
123
|
+
inputField: {
|
|
124
|
+
showPassword: "Mostrar contrase\xF1a",
|
|
125
|
+
hidePassword: "Ocultar contrase\xF1a",
|
|
126
|
+
clear: "Limpiar"
|
|
127
|
+
},
|
|
128
|
+
dialog: {
|
|
129
|
+
close: "Cerrar"
|
|
130
|
+
},
|
|
131
|
+
selectInput: {
|
|
132
|
+
placeholder: "Selecciona...",
|
|
133
|
+
loading: "Cargando...",
|
|
134
|
+
search: "Buscar...",
|
|
135
|
+
noResults: "Sin resultados."
|
|
136
|
+
},
|
|
137
|
+
passwordChecklist: {
|
|
138
|
+
minLength: "M\xEDnimo {{min}} caracteres",
|
|
139
|
+
hasUpperAndLower: "Una may\xFAscula y min\xFAscula",
|
|
140
|
+
hasNumber: "Un n\xFAmero",
|
|
141
|
+
hasSpecialChar: "Un car\xE1cter especial"
|
|
142
|
+
},
|
|
143
|
+
spinner: {
|
|
144
|
+
loading: "Cargando..."
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/lib/i18n.ts
|
|
149
|
+
var uiI18n = i18n.createInstance();
|
|
150
|
+
void uiI18n.use(initReactI18next).init({
|
|
151
|
+
defaultNS: "ui",
|
|
152
|
+
fallbackLng: "es",
|
|
153
|
+
interpolation: { escapeValue: false },
|
|
154
|
+
lng: "es",
|
|
155
|
+
ns: ["ui"],
|
|
156
|
+
resources: { es: { ui: ui_default } }
|
|
157
|
+
});
|
|
158
|
+
var setUiLanguage = (lng) => uiI18n.changeLanguage(lng);
|
|
159
|
+
var useUiT = () => useTranslation("ui", { i18n: uiI18n }).t;
|
|
160
|
+
|
|
161
|
+
// src/components/spinner.tsx
|
|
114
162
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
115
163
|
var sizes = {
|
|
116
164
|
lg: "70",
|
|
@@ -124,8 +172,8 @@ var variants = {
|
|
|
124
172
|
primary: "var(--color-spinner-primary)",
|
|
125
173
|
secondary: "var(--color-spinner-secondary)"
|
|
126
174
|
};
|
|
127
|
-
var Spinner = ({ className = "", size = "md", variant = "primary" }) => {
|
|
128
|
-
const
|
|
175
|
+
var Spinner = ({ className = "", loadingLabel, size = "md", variant = "primary" }) => {
|
|
176
|
+
const t = useUiT();
|
|
129
177
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
130
178
|
/* @__PURE__ */ jsx3(
|
|
131
179
|
"svg",
|
|
@@ -164,7 +212,7 @@ var Spinner = ({ className = "", size = "md", variant = "primary" }) => {
|
|
|
164
212
|
] })
|
|
165
213
|
}
|
|
166
214
|
),
|
|
167
|
-
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: t("spinner.loading") })
|
|
215
|
+
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: loadingLabel ?? t("spinner.loading") })
|
|
168
216
|
] });
|
|
169
217
|
};
|
|
170
218
|
|
|
@@ -292,7 +340,6 @@ import * as React4 from "react";
|
|
|
292
340
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
293
341
|
import { Cross2Icon } from "@radix-ui/react-icons";
|
|
294
342
|
import * as React3 from "react";
|
|
295
|
-
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
296
343
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
297
344
|
var Dialog = DialogPrimitive.Root;
|
|
298
345
|
var DialogTrigger = DialogPrimitive.Trigger;
|
|
@@ -312,8 +359,8 @@ var DialogOverlay = React3.forwardRef(({ className, isAbsolute = false, ...props
|
|
|
312
359
|
));
|
|
313
360
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
314
361
|
var DialogContent = React3.forwardRef(
|
|
315
|
-
({ children, className, container, isAbsolute = false, isCloseIcon = false, overlayClassName, ...props }, ref) => {
|
|
316
|
-
const
|
|
362
|
+
({ children, className, closeLabel, container, isAbsolute = false, isCloseIcon = false, overlayClassName, ...props }, ref) => {
|
|
363
|
+
const t = useUiT();
|
|
317
364
|
return /* @__PURE__ */ jsxs6(DialogPortal, { container, children: [
|
|
318
365
|
/* @__PURE__ */ jsx6(DialogOverlay, { className: overlayClassName, isAbsolute }),
|
|
319
366
|
/* @__PURE__ */ jsxs6(
|
|
@@ -330,7 +377,7 @@ var DialogContent = React3.forwardRef(
|
|
|
330
377
|
children,
|
|
331
378
|
isCloseIcon && /* @__PURE__ */ jsxs6(DialogPrimitive.Close, { className: "data-[state=open]:text-muted ring-offset-surface focus:ring-ring data-[state=open]:bg-hover border-border bg-border absolute top-11 right-8 flex h-8 w-8 min-w-8 cursor-pointer items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none", children: [
|
|
332
379
|
/* @__PURE__ */ jsx6(Cross2Icon, { className: "text-body hover:text-primary-dark h-4 w-4" }),
|
|
333
|
-
/* @__PURE__ */ jsx6("span", { className: "sr-only", children: t("dialog.close") })
|
|
380
|
+
/* @__PURE__ */ jsx6("span", { className: "sr-only", children: closeLabel ?? t("dialog.close") })
|
|
334
381
|
] })
|
|
335
382
|
]
|
|
336
383
|
}
|
|
@@ -529,7 +576,6 @@ FormMessage.displayName = "FormMessage";
|
|
|
529
576
|
|
|
530
577
|
// src/components/form-fields/input-field.tsx
|
|
531
578
|
import { useState } from "react";
|
|
532
|
-
import { useTranslation as useTranslation3 } from "react-i18next";
|
|
533
579
|
import { FaRegEye, FaRegEyeSlash } from "react-icons/fa6";
|
|
534
580
|
import { RxCross2 } from "react-icons/rx";
|
|
535
581
|
|
|
@@ -590,8 +636,10 @@ var LabelField = ({ label, labelClassName, name, visualRequired }) => {
|
|
|
590
636
|
// src/components/form-fields/input-field.tsx
|
|
591
637
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
592
638
|
var InputField = ({
|
|
639
|
+
clearLabel,
|
|
593
640
|
control,
|
|
594
641
|
disabled,
|
|
642
|
+
hidePasswordLabel,
|
|
595
643
|
inputClassName,
|
|
596
644
|
isClearable,
|
|
597
645
|
label,
|
|
@@ -600,10 +648,11 @@ var InputField = ({
|
|
|
600
648
|
name,
|
|
601
649
|
onClear,
|
|
602
650
|
placeholder,
|
|
651
|
+
showPasswordLabel,
|
|
603
652
|
type = "text",
|
|
604
653
|
visualRequired
|
|
605
654
|
}) => {
|
|
606
|
-
const
|
|
655
|
+
const t = useUiT();
|
|
607
656
|
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
608
657
|
const togglePasswordVisibility = () => {
|
|
609
658
|
setIsPasswordVisible((prev) => !prev);
|
|
@@ -662,7 +711,7 @@ var InputField = ({
|
|
|
662
711
|
{
|
|
663
712
|
className: "focus:outline-none",
|
|
664
713
|
onClick: onClear,
|
|
665
|
-
title: t("inputField.clear"),
|
|
714
|
+
title: clearLabel ?? t("inputField.clear"),
|
|
666
715
|
type: "button",
|
|
667
716
|
children: /* @__PURE__ */ jsx12(RxCross2, { size: 18 })
|
|
668
717
|
}
|
|
@@ -672,7 +721,7 @@ var InputField = ({
|
|
|
672
721
|
{
|
|
673
722
|
className: "focus:outline-none",
|
|
674
723
|
onClick: togglePasswordVisibility,
|
|
675
|
-
title: isPasswordVisible ? t("inputField.hidePassword") : t("inputField.showPassword"),
|
|
724
|
+
title: isPasswordVisible ? hidePasswordLabel ?? t("inputField.hidePassword") : showPasswordLabel ?? t("inputField.showPassword"),
|
|
676
725
|
type: "button",
|
|
677
726
|
children: isPasswordVisible ? /* @__PURE__ */ jsx12(FaRegEye, { size: 18 }) : /* @__PURE__ */ jsx12(FaRegEyeSlash, { size: 20 })
|
|
678
727
|
}
|
|
@@ -694,13 +743,27 @@ var DEFAULT_CENTER = { lat: 4.711, lng: -74.0721 };
|
|
|
694
743
|
var PICKER_MAP_ID = "komensal-restaurant-map";
|
|
695
744
|
var SELECTED_ZOOM = 15;
|
|
696
745
|
var DEBOUNCE_MS = 300;
|
|
746
|
+
var parseComponents = (components) => {
|
|
747
|
+
const find = (type) => components.find((c) => c.types.includes(type));
|
|
748
|
+
const country = find("country");
|
|
749
|
+
const department = find("administrative_area_level_1");
|
|
750
|
+
const city = find("locality") ?? find("administrative_area_level_2");
|
|
751
|
+
return {
|
|
752
|
+
city: city?.long ?? null,
|
|
753
|
+
country: country?.short ?? null,
|
|
754
|
+
countryName: country?.long ?? null,
|
|
755
|
+
department: department?.long ?? null
|
|
756
|
+
};
|
|
757
|
+
};
|
|
697
758
|
var CITY_ZOOM = 12;
|
|
698
759
|
var MapPickerContent = ({
|
|
699
760
|
centerOn,
|
|
761
|
+
countryCode,
|
|
700
762
|
disabled,
|
|
701
763
|
hasError,
|
|
702
764
|
locationQuery,
|
|
703
765
|
locationZoom,
|
|
766
|
+
onAddressResolved,
|
|
704
767
|
onChange,
|
|
705
768
|
placeholder,
|
|
706
769
|
value
|
|
@@ -709,6 +772,7 @@ var MapPickerContent = ({
|
|
|
709
772
|
const geocodingLib = useMapsLibrary("geocoding");
|
|
710
773
|
const map = useMap(PICKER_MAP_ID);
|
|
711
774
|
const onChangeRef = useRef(onChange);
|
|
775
|
+
const onResolvedRef = useRef(onAddressResolved);
|
|
712
776
|
const geocoder = useMemo(
|
|
713
777
|
() => geocodingLib ? new geocodingLib.Geocoder() : null,
|
|
714
778
|
[geocodingLib]
|
|
@@ -721,6 +785,7 @@ var MapPickerContent = ({
|
|
|
721
785
|
const [position, setPosition] = useState2(null);
|
|
722
786
|
useEffect(() => {
|
|
723
787
|
onChangeRef.current = onChange;
|
|
788
|
+
onResolvedRef.current = onAddressResolved;
|
|
724
789
|
});
|
|
725
790
|
useEffect(() => {
|
|
726
791
|
setInputValue(value);
|
|
@@ -768,6 +833,7 @@ var MapPickerContent = ({
|
|
|
768
833
|
}
|
|
769
834
|
try {
|
|
770
835
|
const result = await placesLib.AutocompleteSuggestion.fetchAutocompleteSuggestions({
|
|
836
|
+
includedRegionCodes: countryCode ? [countryCode.toLowerCase()] : void 0,
|
|
771
837
|
input,
|
|
772
838
|
sessionToken
|
|
773
839
|
});
|
|
@@ -777,7 +843,7 @@ var MapPickerContent = ({
|
|
|
777
843
|
setSuggestions([]);
|
|
778
844
|
}
|
|
779
845
|
},
|
|
780
|
-
[placesLib, sessionToken]
|
|
846
|
+
[placesLib, sessionToken, countryCode]
|
|
781
847
|
);
|
|
782
848
|
const reverseGeocode = useCallback(
|
|
783
849
|
async (latLng) => {
|
|
@@ -785,9 +851,14 @@ var MapPickerContent = ({
|
|
|
785
851
|
try {
|
|
786
852
|
const { results } = await geocoder.geocode({ location: latLng });
|
|
787
853
|
if (results.length > 0) {
|
|
788
|
-
const
|
|
854
|
+
const result = results[0];
|
|
855
|
+
const address = result.formatted_address;
|
|
789
856
|
setInputValue(address);
|
|
790
857
|
onChangeRef.current(address);
|
|
858
|
+
const parts = parseComponents(
|
|
859
|
+
result.address_components.map((c) => ({ long: c.long_name, short: c.short_name, types: c.types }))
|
|
860
|
+
);
|
|
861
|
+
onResolvedRef.current?.({ address, lat: latLng.lat, lng: latLng.lng, ...parts });
|
|
791
862
|
}
|
|
792
863
|
} catch {
|
|
793
864
|
return;
|
|
@@ -806,15 +877,21 @@ var MapPickerContent = ({
|
|
|
806
877
|
const prediction = suggestion.placePrediction;
|
|
807
878
|
if (!prediction) return;
|
|
808
879
|
const place = prediction.toPlace();
|
|
809
|
-
await place.fetchFields({ fields: ["formattedAddress", "location"] });
|
|
880
|
+
await place.fetchFields({ fields: ["formattedAddress", "location", "addressComponents"] });
|
|
810
881
|
const address = place.formattedAddress ?? prediction.text.text;
|
|
811
882
|
setInputValue(address);
|
|
812
883
|
onChangeRef.current(address);
|
|
813
884
|
setSuggestions([]);
|
|
814
885
|
setShowDropdown(false);
|
|
886
|
+
const lat = place.location?.lat() ?? null;
|
|
887
|
+
const lng = place.location?.lng() ?? null;
|
|
815
888
|
if (place.location) {
|
|
816
889
|
setPosition({ lat: place.location.lat(), lng: place.location.lng() });
|
|
817
890
|
}
|
|
891
|
+
const parts = parseComponents(
|
|
892
|
+
(place.addressComponents ?? []).map((c) => ({ long: c.longText, short: c.shortText, types: c.types }))
|
|
893
|
+
);
|
|
894
|
+
onResolvedRef.current?.({ address, lat, lng, ...parts });
|
|
818
895
|
if (placesLib) setSessionToken(new placesLib.AutocompleteSessionToken());
|
|
819
896
|
};
|
|
820
897
|
const handleBlur = () => {
|
|
@@ -1018,7 +1095,6 @@ function OTPField({
|
|
|
1018
1095
|
// src/components/select-input.tsx
|
|
1019
1096
|
import { ChevronDown, ChevronUp, Clock, XIcon } from "lucide-react";
|
|
1020
1097
|
import { cloneElement, useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
|
|
1021
|
-
import { useTranslation as useTranslation4 } from "react-i18next";
|
|
1022
1098
|
|
|
1023
1099
|
// src/components/popover.tsx
|
|
1024
1100
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
@@ -1045,7 +1121,7 @@ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
|
1045
1121
|
// src/components/select-input.tsx
|
|
1046
1122
|
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1047
1123
|
var SelectInput = (props) => {
|
|
1048
|
-
const
|
|
1124
|
+
const t = useUiT();
|
|
1049
1125
|
const {
|
|
1050
1126
|
ableDeleteOption,
|
|
1051
1127
|
className,
|
|
@@ -1055,12 +1131,15 @@ var SelectInput = (props) => {
|
|
|
1055
1131
|
labelKey = "label",
|
|
1056
1132
|
leftIcon,
|
|
1057
1133
|
loading = false,
|
|
1134
|
+
loadingLabel,
|
|
1135
|
+
noResultsLabel,
|
|
1058
1136
|
onBlur,
|
|
1059
1137
|
onChange,
|
|
1060
1138
|
onValueChangeCallBack = () => void 0,
|
|
1061
1139
|
placeholder,
|
|
1062
1140
|
placeholderClassName = "",
|
|
1063
1141
|
search = false,
|
|
1142
|
+
searchPlaceholder,
|
|
1064
1143
|
timeField = false,
|
|
1065
1144
|
value = "",
|
|
1066
1145
|
valueKey = "value"
|
|
@@ -1138,7 +1217,7 @@ var SelectInput = (props) => {
|
|
|
1138
1217
|
role: "combobox",
|
|
1139
1218
|
variant: "primary",
|
|
1140
1219
|
children: loading ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
1141
|
-
t("selectInput.loading"),
|
|
1220
|
+
loadingLabel ?? t("selectInput.loading"),
|
|
1142
1221
|
" ",
|
|
1143
1222
|
/* @__PURE__ */ jsx18(Spinner, {})
|
|
1144
1223
|
] }) : /* @__PURE__ */ jsxs14("div", { className: "relative flex h-5 w-full items-center", children: [
|
|
@@ -1179,11 +1258,11 @@ var SelectInput = (props) => {
|
|
|
1179
1258
|
{
|
|
1180
1259
|
className: "mb-1 rounded-sm",
|
|
1181
1260
|
onChange: (e) => setQuery(e.target.value),
|
|
1182
|
-
placeholder: t("selectInput.search"),
|
|
1261
|
+
placeholder: searchPlaceholder ?? t("selectInput.search"),
|
|
1183
1262
|
value: query
|
|
1184
1263
|
}
|
|
1185
1264
|
),
|
|
1186
|
-
/* @__PURE__ */ jsx18(CommandEmpty, { className: "text-center", children: t("selectInput.noResults") }),
|
|
1265
|
+
/* @__PURE__ */ jsx18(CommandEmpty, { className: "text-center", children: noResultsLabel ?? t("selectInput.noResults") }),
|
|
1187
1266
|
/* @__PURE__ */ jsx18(CommandList, { children: /* @__PURE__ */ jsx18(CommandGroup, { className: "p-0", children: filteredOptions.map((item) => {
|
|
1188
1267
|
const labelValue = item[labelKey];
|
|
1189
1268
|
const valueValue = item[valueKey];
|
|
@@ -1704,7 +1783,9 @@ export {
|
|
|
1704
1783
|
inputFocus,
|
|
1705
1784
|
inputPlaceholder,
|
|
1706
1785
|
registerToastEmitter,
|
|
1786
|
+
setUiLanguage,
|
|
1707
1787
|
toast,
|
|
1788
|
+
uiI18n,
|
|
1708
1789
|
useFormField
|
|
1709
1790
|
};
|
|
1710
1791
|
//# sourceMappingURL=index.js.map
|