@abpjs/theme-shared 0.8.0 → 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.mjs CHANGED
@@ -817,6 +817,7 @@ function LoaderBar({
817
817
  }
818
818
 
819
819
  // src/components/modal/Modal.tsx
820
+ import React6 from "react";
820
821
  import {
821
822
  Dialog as Dialog2,
822
823
  Portal as Portal3,
@@ -846,9 +847,12 @@ function getSizeWidth(size) {
846
847
  function Modal({
847
848
  visible,
848
849
  onVisibleChange,
850
+ busy = false,
849
851
  size = "md",
850
852
  centered = true,
851
853
  modalClass,
854
+ height,
855
+ minHeight,
852
856
  header,
853
857
  children,
854
858
  footer,
@@ -858,9 +862,24 @@ function Modal({
858
862
  scrollBehavior = "inside",
859
863
  motionPreset = "scale",
860
864
  trapFocus = true,
861
- preventScroll = true
865
+ preventScroll = true,
866
+ onInit
862
867
  }) {
868
+ const prevVisibleRef = React6.useRef(false);
869
+ const onInitRef = React6.useRef(onInit);
870
+ React6.useEffect(() => {
871
+ onInitRef.current = onInit;
872
+ }, [onInit]);
873
+ React6.useEffect(() => {
874
+ if (visible && !prevVisibleRef.current && onInitRef.current) {
875
+ onInitRef.current();
876
+ }
877
+ prevVisibleRef.current = visible;
878
+ }, [visible]);
863
879
  const handleOpenChange = (details) => {
880
+ if (busy && !details.open) {
881
+ return;
882
+ }
864
883
  onVisibleChange?.(details.open);
865
884
  };
866
885
  return /* @__PURE__ */ jsx7(
@@ -869,8 +888,8 @@ function Modal({
869
888
  open: visible,
870
889
  onOpenChange: handleOpenChange,
871
890
  placement: centered ? "center" : "top",
872
- closeOnInteractOutside: closeOnOverlayClick,
873
- closeOnEscape,
891
+ closeOnInteractOutside: closeOnOverlayClick && !busy,
892
+ closeOnEscape: closeOnEscape && !busy,
874
893
  scrollBehavior,
875
894
  motionPreset,
876
895
  trapFocus,
@@ -884,6 +903,8 @@ function Modal({
884
903
  width: getSizeWidth(size),
885
904
  maxWidth: size === "full" ? "100vw" : void 0,
886
905
  maxHeight: size === "full" ? "100vh" : void 0,
906
+ height,
907
+ minHeight,
887
908
  children: [
888
909
  (header || showCloseButton) && /* @__PURE__ */ jsxs4(Fragment, { children: [
889
910
  /* @__PURE__ */ jsx7(Dialog2.Header, { children: /* @__PURE__ */ jsxs4(Flex3, { justify: "space-between", align: "center", width: "100%", children: [
@@ -1064,6 +1085,356 @@ function FormField({
1064
1085
  ] });
1065
1086
  }
1066
1087
 
1088
+ // src/components/change-password/ChangePassword.tsx
1089
+ import { useEffect as useEffect3 } from "react";
1090
+ import {
1091
+ Button as Button5,
1092
+ VStack as VStack2,
1093
+ Input,
1094
+ Field as Field2
1095
+ } from "@chakra-ui/react";
1096
+ import { useForm } from "react-hook-form";
1097
+ import { useLocalization as useLocalization3, useProfile } from "@abpjs/core";
1098
+ import { Check } from "lucide-react";
1099
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
1100
+ function ChangePassword({
1101
+ visible,
1102
+ onVisibleChange
1103
+ }) {
1104
+ const { t } = useLocalization3();
1105
+ const { changePassword } = useProfile();
1106
+ const toaster = useToaster();
1107
+ const {
1108
+ register,
1109
+ handleSubmit,
1110
+ watch,
1111
+ reset,
1112
+ formState: { errors, isSubmitting }
1113
+ } = useForm({
1114
+ defaultValues: {
1115
+ password: "",
1116
+ newPassword: "",
1117
+ repeatNewPassword: ""
1118
+ }
1119
+ });
1120
+ const newPassword = watch("newPassword");
1121
+ useEffect3(() => {
1122
+ if (visible) {
1123
+ reset();
1124
+ }
1125
+ }, [visible, reset]);
1126
+ const onSubmit = async (data) => {
1127
+ try {
1128
+ await changePassword({
1129
+ currentPassword: data.password,
1130
+ newPassword: data.newPassword
1131
+ });
1132
+ toaster.success(
1133
+ t("AbpIdentity::PasswordChangedMessage") || "Password changed successfully",
1134
+ t("AbpUi::Success") || "Success"
1135
+ );
1136
+ onVisibleChange(false);
1137
+ } catch (error) {
1138
+ toaster.error(
1139
+ error instanceof Error ? error.message : "An error occurred",
1140
+ t("AbpIdentity::PasswordChangeFailed") || "Failed to change password"
1141
+ );
1142
+ }
1143
+ };
1144
+ const handleClose = () => {
1145
+ if (!isSubmitting) {
1146
+ onVisibleChange(false);
1147
+ }
1148
+ };
1149
+ const passwordValidation = {
1150
+ required: t("AbpIdentity::ThisFieldIsRequired") || "This field is required",
1151
+ minLength: {
1152
+ value: 6,
1153
+ message: t("AbpIdentity::PasswordTooShort") || "Password must be at least 6 characters"
1154
+ },
1155
+ validate: {
1156
+ hasLowercase: (value) => /[a-z]/.test(value) || t("AbpIdentity::PasswordRequiresLower") || "Password must contain a lowercase letter",
1157
+ hasUppercase: (value) => /[A-Z]/.test(value) || t("AbpIdentity::PasswordRequiresUpper") || "Password must contain an uppercase letter",
1158
+ hasNumber: (value) => /[0-9]/.test(value) || t("AbpIdentity::PasswordRequiresDigit") || "Password must contain a number",
1159
+ hasSpecial: (value) => /[!@#$%^&*(),.?":{}|<>]/.test(value) || t("AbpIdentity::PasswordRequiresNonAlphanumeric") || "Password must contain a special character"
1160
+ }
1161
+ };
1162
+ const modalFooter = /* @__PURE__ */ jsxs8(Fragment3, { children: [
1163
+ /* @__PURE__ */ jsx12(Button5, { variant: "ghost", mr: 3, onClick: handleClose, disabled: isSubmitting, children: t("AbpIdentity::Cancel") || "Cancel" }),
1164
+ /* @__PURE__ */ jsxs8(
1165
+ Button5,
1166
+ {
1167
+ colorPalette: "blue",
1168
+ type: "submit",
1169
+ loading: isSubmitting,
1170
+ form: "change-password-form",
1171
+ children: [
1172
+ /* @__PURE__ */ jsx12(Check, { size: 16 }),
1173
+ t("AbpIdentity::Save") || "Save"
1174
+ ]
1175
+ }
1176
+ )
1177
+ ] });
1178
+ return /* @__PURE__ */ jsx12(
1179
+ Modal,
1180
+ {
1181
+ visible,
1182
+ onVisibleChange,
1183
+ busy: isSubmitting,
1184
+ header: t("AbpIdentity::ChangePassword") || "Change Password",
1185
+ footer: modalFooter,
1186
+ centered: true,
1187
+ children: /* @__PURE__ */ jsx12("form", { id: "change-password-form", onSubmit: handleSubmit(onSubmit), children: /* @__PURE__ */ jsxs8(VStack2, { gap: 4, children: [
1188
+ /* @__PURE__ */ jsxs8(Field2.Root, { invalid: !!errors.password, children: [
1189
+ /* @__PURE__ */ jsxs8(Field2.Label, { children: [
1190
+ t("AbpIdentity::DisplayName:CurrentPassword") || "Current Password",
1191
+ /* @__PURE__ */ jsx12(Field2.RequiredIndicator, {})
1192
+ ] }),
1193
+ /* @__PURE__ */ jsx12(
1194
+ Input,
1195
+ {
1196
+ type: "password",
1197
+ ...register("password", {
1198
+ required: t("AbpIdentity::ThisFieldIsRequired") || "This field is required"
1199
+ })
1200
+ }
1201
+ ),
1202
+ /* @__PURE__ */ jsx12(Field2.ErrorText, { children: errors.password?.message })
1203
+ ] }),
1204
+ /* @__PURE__ */ jsxs8(Field2.Root, { invalid: !!errors.newPassword, children: [
1205
+ /* @__PURE__ */ jsxs8(Field2.Label, { children: [
1206
+ t("AbpIdentity::DisplayName:NewPassword") || "New Password",
1207
+ /* @__PURE__ */ jsx12(Field2.RequiredIndicator, {})
1208
+ ] }),
1209
+ /* @__PURE__ */ jsx12(
1210
+ Input,
1211
+ {
1212
+ type: "password",
1213
+ ...register("newPassword", passwordValidation)
1214
+ }
1215
+ ),
1216
+ /* @__PURE__ */ jsx12(Field2.ErrorText, { children: errors.newPassword?.message })
1217
+ ] }),
1218
+ /* @__PURE__ */ jsxs8(Field2.Root, { invalid: !!errors.repeatNewPassword, children: [
1219
+ /* @__PURE__ */ jsxs8(Field2.Label, { children: [
1220
+ t("AbpIdentity::DisplayName:NewPasswordConfirm") || "Confirm New Password",
1221
+ /* @__PURE__ */ jsx12(Field2.RequiredIndicator, {})
1222
+ ] }),
1223
+ /* @__PURE__ */ jsx12(
1224
+ Input,
1225
+ {
1226
+ type: "password",
1227
+ ...register("repeatNewPassword", {
1228
+ required: t("AbpIdentity::ThisFieldIsRequired") || "This field is required",
1229
+ validate: (value) => value === newPassword || t("AbpIdentity::Identity.PasswordConfirmationFailed") || "Passwords do not match"
1230
+ })
1231
+ }
1232
+ ),
1233
+ /* @__PURE__ */ jsx12(Field2.ErrorText, { children: errors.repeatNewPassword?.message })
1234
+ ] })
1235
+ ] }) })
1236
+ }
1237
+ );
1238
+ }
1239
+
1240
+ // src/components/profile/Profile.tsx
1241
+ import { useEffect as useEffect4 } from "react";
1242
+ import {
1243
+ Button as Button6,
1244
+ VStack as VStack3,
1245
+ HStack,
1246
+ Input as Input2,
1247
+ Field as Field3
1248
+ } from "@chakra-ui/react";
1249
+ import { useForm as useForm2 } from "react-hook-form";
1250
+ import { useLocalization as useLocalization4, useProfile as useProfile2 } from "@abpjs/core";
1251
+ import { Check as Check2 } from "lucide-react";
1252
+ import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
1253
+ function Profile({
1254
+ visible,
1255
+ onVisibleChange
1256
+ }) {
1257
+ const { t } = useLocalization4();
1258
+ const { profile, fetchProfile, updateProfile, loading } = useProfile2();
1259
+ const toaster = useToaster();
1260
+ const {
1261
+ register,
1262
+ handleSubmit,
1263
+ reset,
1264
+ formState: { errors, isSubmitting }
1265
+ } = useForm2({
1266
+ defaultValues: {
1267
+ userName: "",
1268
+ email: "",
1269
+ name: "",
1270
+ surname: "",
1271
+ phoneNumber: ""
1272
+ }
1273
+ });
1274
+ const modalBusy = isSubmitting || loading;
1275
+ useEffect4(() => {
1276
+ if (visible) {
1277
+ fetchProfile().then(() => {
1278
+ });
1279
+ }
1280
+ }, [visible, fetchProfile]);
1281
+ useEffect4(() => {
1282
+ if (profile) {
1283
+ reset({
1284
+ userName: profile.userName || "",
1285
+ email: profile.email || "",
1286
+ name: profile.name || "",
1287
+ surname: profile.surname || "",
1288
+ phoneNumber: profile.phoneNumber || ""
1289
+ });
1290
+ }
1291
+ }, [profile, reset]);
1292
+ const onSubmit = async (data) => {
1293
+ try {
1294
+ await updateProfile(data);
1295
+ toaster.success(
1296
+ t("AbpIdentity::ProfileUpdatedMessage") || "Profile updated successfully",
1297
+ t("AbpUi::Success") || "Success"
1298
+ );
1299
+ onVisibleChange(false);
1300
+ } catch (error) {
1301
+ toaster.error(
1302
+ error instanceof Error ? error.message : "An error occurred",
1303
+ t("AbpIdentity::ProfileUpdateFailed") || "Failed to update profile"
1304
+ );
1305
+ }
1306
+ };
1307
+ const handleClose = () => {
1308
+ if (!modalBusy) {
1309
+ onVisibleChange(false);
1310
+ }
1311
+ };
1312
+ const modalFooter = /* @__PURE__ */ jsxs9(Fragment4, { children: [
1313
+ /* @__PURE__ */ jsx13(Button6, { variant: "ghost", mr: 3, onClick: handleClose, disabled: modalBusy, children: t("AbpIdentity::Cancel") || "Cancel" }),
1314
+ /* @__PURE__ */ jsxs9(
1315
+ Button6,
1316
+ {
1317
+ colorPalette: "blue",
1318
+ type: "submit",
1319
+ loading: modalBusy,
1320
+ form: "profile-form",
1321
+ children: [
1322
+ /* @__PURE__ */ jsx13(Check2, { size: 16 }),
1323
+ t("AbpIdentity::Save") || "Save"
1324
+ ]
1325
+ }
1326
+ )
1327
+ ] });
1328
+ return /* @__PURE__ */ jsx13(
1329
+ Modal,
1330
+ {
1331
+ visible,
1332
+ onVisibleChange,
1333
+ busy: modalBusy,
1334
+ header: t("AbpIdentity::PersonalInfo") || "Personal Info",
1335
+ footer: modalFooter,
1336
+ size: "lg",
1337
+ centered: true,
1338
+ children: /* @__PURE__ */ jsx13("form", { id: "profile-form", onSubmit: handleSubmit(onSubmit), children: /* @__PURE__ */ jsxs9(VStack3, { gap: 4, children: [
1339
+ /* @__PURE__ */ jsxs9(Field3.Root, { invalid: !!errors.userName, children: [
1340
+ /* @__PURE__ */ jsxs9(Field3.Label, { children: [
1341
+ t("AbpIdentity::DisplayName:UserName") || "Username",
1342
+ /* @__PURE__ */ jsx13(Field3.RequiredIndicator, {})
1343
+ ] }),
1344
+ /* @__PURE__ */ jsx13(
1345
+ Input2,
1346
+ {
1347
+ type: "text",
1348
+ ...register("userName", {
1349
+ required: t("AbpIdentity::ThisFieldIsRequired") || "This field is required",
1350
+ maxLength: {
1351
+ value: 256,
1352
+ message: "Maximum 256 characters"
1353
+ }
1354
+ })
1355
+ }
1356
+ ),
1357
+ /* @__PURE__ */ jsx13(Field3.ErrorText, { children: errors.userName?.message })
1358
+ ] }),
1359
+ /* @__PURE__ */ jsxs9(HStack, { gap: 4, w: "full", children: [
1360
+ /* @__PURE__ */ jsxs9(Field3.Root, { invalid: !!errors.name, flex: 1, children: [
1361
+ /* @__PURE__ */ jsx13(Field3.Label, { children: t("AbpIdentity::DisplayName:Name") || "Name" }),
1362
+ /* @__PURE__ */ jsx13(
1363
+ Input2,
1364
+ {
1365
+ type: "text",
1366
+ ...register("name", {
1367
+ maxLength: {
1368
+ value: 64,
1369
+ message: "Maximum 64 characters"
1370
+ }
1371
+ })
1372
+ }
1373
+ ),
1374
+ /* @__PURE__ */ jsx13(Field3.ErrorText, { children: errors.name?.message })
1375
+ ] }),
1376
+ /* @__PURE__ */ jsxs9(Field3.Root, { invalid: !!errors.surname, flex: 1, children: [
1377
+ /* @__PURE__ */ jsx13(Field3.Label, { children: t("AbpIdentity::DisplayName:Surname") || "Surname" }),
1378
+ /* @__PURE__ */ jsx13(
1379
+ Input2,
1380
+ {
1381
+ type: "text",
1382
+ ...register("surname", {
1383
+ maxLength: {
1384
+ value: 64,
1385
+ message: "Maximum 64 characters"
1386
+ }
1387
+ })
1388
+ }
1389
+ ),
1390
+ /* @__PURE__ */ jsx13(Field3.ErrorText, { children: errors.surname?.message })
1391
+ ] })
1392
+ ] }),
1393
+ /* @__PURE__ */ jsxs9(Field3.Root, { invalid: !!errors.email, children: [
1394
+ /* @__PURE__ */ jsxs9(Field3.Label, { children: [
1395
+ t("AbpIdentity::DisplayName:EmailAddress") || "Email Address",
1396
+ /* @__PURE__ */ jsx13(Field3.RequiredIndicator, {})
1397
+ ] }),
1398
+ /* @__PURE__ */ jsx13(
1399
+ Input2,
1400
+ {
1401
+ type: "email",
1402
+ ...register("email", {
1403
+ required: t("AbpIdentity::ThisFieldIsRequired") || "This field is required",
1404
+ pattern: {
1405
+ value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
1406
+ message: t("AbpIdentity::InvalidEmail") || "Invalid email address"
1407
+ },
1408
+ maxLength: {
1409
+ value: 256,
1410
+ message: "Maximum 256 characters"
1411
+ }
1412
+ })
1413
+ }
1414
+ ),
1415
+ /* @__PURE__ */ jsx13(Field3.ErrorText, { children: errors.email?.message })
1416
+ ] }),
1417
+ /* @__PURE__ */ jsxs9(Field3.Root, { invalid: !!errors.phoneNumber, children: [
1418
+ /* @__PURE__ */ jsx13(Field3.Label, { children: t("AbpIdentity::DisplayName:PhoneNumber") || "Phone Number" }),
1419
+ /* @__PURE__ */ jsx13(
1420
+ Input2,
1421
+ {
1422
+ type: "tel",
1423
+ ...register("phoneNumber", {
1424
+ maxLength: {
1425
+ value: 16,
1426
+ message: "Maximum 16 characters"
1427
+ }
1428
+ })
1429
+ }
1430
+ ),
1431
+ /* @__PURE__ */ jsx13(Field3.ErrorText, { children: errors.phoneNumber?.message })
1432
+ ] })
1433
+ ] }) })
1434
+ }
1435
+ );
1436
+ }
1437
+
1067
1438
  // src/providers/ThemeSharedProvider.tsx
1068
1439
  import { ChakraProvider, LocaleProvider } from "@chakra-ui/react";
1069
1440
 
@@ -1302,11 +1673,11 @@ var abpSystem = createAbpSystem();
1302
1673
  // src/components/ui/color-mode.tsx
1303
1674
  import { ClientOnly, IconButton, Skeleton, Span } from "@chakra-ui/react";
1304
1675
  import { ThemeProvider, useTheme } from "next-themes";
1305
- import * as React8 from "react";
1676
+ import * as React11 from "react";
1306
1677
  import { Moon, Sun } from "lucide-react";
1307
- import { jsx as jsx12 } from "react/jsx-runtime";
1678
+ import { jsx as jsx14 } from "react/jsx-runtime";
1308
1679
  function ColorModeProvider(props) {
1309
- return /* @__PURE__ */ jsx12(ThemeProvider, { attribute: "class", disableTransitionOnChange: true, ...props });
1680
+ return /* @__PURE__ */ jsx14(ThemeProvider, { attribute: "class", disableTransitionOnChange: true, ...props });
1310
1681
  }
1311
1682
  function useColorMode() {
1312
1683
  const { resolvedTheme, setTheme, forcedTheme } = useTheme();
@@ -1322,11 +1693,11 @@ function useColorMode() {
1322
1693
  }
1323
1694
  function ColorModeIcon() {
1324
1695
  const { colorMode } = useColorMode();
1325
- return colorMode === "dark" ? /* @__PURE__ */ jsx12(Moon, {}) : /* @__PURE__ */ jsx12(Sun, {});
1696
+ return colorMode === "dark" ? /* @__PURE__ */ jsx14(Moon, {}) : /* @__PURE__ */ jsx14(Sun, {});
1326
1697
  }
1327
- var ColorModeButton = React8.forwardRef(function ColorModeButton2(props, ref) {
1698
+ var ColorModeButton = React11.forwardRef(function ColorModeButton2(props, ref) {
1328
1699
  const { toggleColorMode } = useColorMode();
1329
- return /* @__PURE__ */ jsx12(ClientOnly, { fallback: /* @__PURE__ */ jsx12(Skeleton, { boxSize: "9" }), children: /* @__PURE__ */ jsx12(
1700
+ return /* @__PURE__ */ jsx14(ClientOnly, { fallback: /* @__PURE__ */ jsx14(Skeleton, { boxSize: "9" }), children: /* @__PURE__ */ jsx14(
1330
1701
  IconButton,
1331
1702
  {
1332
1703
  onClick: toggleColorMode,
@@ -1341,13 +1712,13 @@ var ColorModeButton = React8.forwardRef(function ColorModeButton2(props, ref) {
1341
1712
  height: "5"
1342
1713
  }
1343
1714
  },
1344
- children: /* @__PURE__ */ jsx12(ColorModeIcon, {})
1715
+ children: /* @__PURE__ */ jsx14(ColorModeIcon, {})
1345
1716
  }
1346
1717
  ) });
1347
1718
  });
1348
- var LightMode = React8.forwardRef(
1719
+ var LightMode = React11.forwardRef(
1349
1720
  function LightMode2(props, ref) {
1350
- return /* @__PURE__ */ jsx12(
1721
+ return /* @__PURE__ */ jsx14(
1351
1722
  Span,
1352
1723
  {
1353
1724
  color: "fg",
@@ -1361,9 +1732,9 @@ var LightMode = React8.forwardRef(
1361
1732
  );
1362
1733
  }
1363
1734
  );
1364
- var DarkMode = React8.forwardRef(
1735
+ var DarkMode = React11.forwardRef(
1365
1736
  function DarkMode2(props, ref) {
1366
- return /* @__PURE__ */ jsx12(
1737
+ return /* @__PURE__ */ jsx14(
1367
1738
  Span,
1368
1739
  {
1369
1740
  color: "fg",
@@ -1380,7 +1751,7 @@ var DarkMode = React8.forwardRef(
1380
1751
 
1381
1752
  // src/providers/ThemeSharedProvider.tsx
1382
1753
  import { useDirection } from "@abpjs/core";
1383
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1754
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
1384
1755
  function ThemeSharedProvider({
1385
1756
  children,
1386
1757
  renderToasts = true,
@@ -1394,13 +1765,13 @@ function ThemeSharedProvider({
1394
1765
  const system = themeOverrides ? createAbpSystem(themeOverrides) : abpSystem;
1395
1766
  const { endSide } = useDirection();
1396
1767
  toastPosition = `bottom-${endSide}`;
1397
- const content = /* @__PURE__ */ jsx13(ToasterProvider, { children: /* @__PURE__ */ jsxs8(ConfirmationProvider, { children: [
1768
+ const content = /* @__PURE__ */ jsx15(ToasterProvider, { children: /* @__PURE__ */ jsxs10(ConfirmationProvider, { children: [
1398
1769
  children,
1399
- renderToasts && /* @__PURE__ */ jsx13(ToastContainer, { position: toastPosition }),
1400
- renderConfirmation && /* @__PURE__ */ jsx13(ConfirmationDialog, {})
1770
+ renderToasts && /* @__PURE__ */ jsx15(ToastContainer, { position: toastPosition }),
1771
+ renderConfirmation && /* @__PURE__ */ jsx15(ConfirmationDialog, {})
1401
1772
  ] }) });
1402
1773
  const colorModeProps = enableColorMode ? { defaultTheme: defaultColorMode } : { forcedTheme: "light" };
1403
- return /* @__PURE__ */ jsx13(ChakraProvider, { value: system, children: /* @__PURE__ */ jsx13(LocaleProvider, { locale, children: /* @__PURE__ */ jsx13(ColorModeProvider, { ...colorModeProps, children: content }) }) });
1774
+ return /* @__PURE__ */ jsx15(ChakraProvider, { value: system, children: /* @__PURE__ */ jsx15(LocaleProvider, { locale, children: /* @__PURE__ */ jsx15(ColorModeProvider, { ...colorModeProps, children: content }) }) });
1404
1775
  }
1405
1776
 
1406
1777
  // src/utils/styles.ts
@@ -1480,6 +1851,7 @@ export {
1480
1851
  Alert,
1481
1852
  Button3 as Button,
1482
1853
  Dialog2 as ChakraDialog,
1854
+ ChangePassword,
1483
1855
  Checkbox,
1484
1856
  ConfirmationDialog,
1485
1857
  ConfirmationProvider,
@@ -1491,6 +1863,7 @@ export {
1491
1863
  AbpModalBody as ModalBody,
1492
1864
  AbpModalFooter as ModalFooter,
1493
1865
  AbpModalHeader as ModalHeader,
1866
+ Profile,
1494
1867
  THEME_SHARED_STYLES,
1495
1868
  ThemeSharedProvider,
1496
1869
  ToastContainer,
@@ -1,2 +1,4 @@
1
1
  export * from './toaster';
2
2
  export * from './confirmation';
3
+ export * from './setting-management';
4
+ export * from './statistics';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Setting management models for theme-shared
3
+ * Translated from @abp/ng.theme.shared v0.9.0
4
+ */
5
+ /**
6
+ * Represents a settings tab in the settings management UI.
7
+ */
8
+ export interface SettingTab {
9
+ /** Display name of the tab */
10
+ name: string;
11
+ /** Order/priority for tab sorting */
12
+ order: number;
13
+ /** Required policy to view this tab */
14
+ requiredPolicy?: string;
15
+ /** URL/route for this settings tab */
16
+ url?: string;
17
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Statistics models for theme-shared
3
+ * Translated from @abp/ng.theme.shared v0.9.0
4
+ */
5
+ export declare namespace Statistics {
6
+ /**
7
+ * Response from statistics API
8
+ */
9
+ interface Response {
10
+ data: Data;
11
+ }
12
+ /**
13
+ * Statistics data - key-value pairs of metric names and values
14
+ */
15
+ interface Data {
16
+ [key: string]: number;
17
+ }
18
+ /**
19
+ * Filter for statistics queries
20
+ */
21
+ interface Filter {
22
+ startDate: string | Date;
23
+ endDate: string | Date;
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abpjs/theme-shared",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "ABP Framework Theme Shared components for React - translated from @abp/ng.theme.shared",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,11 +25,13 @@
25
25
  "@emotion/react": "^11.11.0",
26
26
  "lucide-react": "^0.400.0",
27
27
  "next-themes": "^0.4.6",
28
+ "react-hook-form": "^7.48.0",
28
29
  "react-icons": "^5.5.0",
29
- "@abpjs/core": "0.8.0"
30
+ "@abpjs/core": "1.0.0"
30
31
  },
31
32
  "devDependencies": {
32
- "@abp/ng.theme.shared": "0.8.0"
33
+ "@abp/ng.theme.shared": "1.0.0",
34
+ "@vitest/coverage-v8": "^1.6.1"
33
35
  },
34
36
  "author": "tekthar.com",
35
37
  "license": "LGPL-3.0",
@@ -52,6 +54,7 @@
52
54
  "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
53
55
  "format:check": "prettier --check \"src/**/*.{ts,tsx,json,md}\"",
54
56
  "type-check": "tsc --noEmit",
55
- "test": "vitest"
57
+ "test": "vitest run",
58
+ "test:watch": "vitest"
56
59
  }
57
60
  }