@serhii.olishevskyi/docs 1.2.2 → 1.2.4

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.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as React$1 from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { TextFieldProps, SelectProps, SelectChangeEvent, IconButtonProps, TooltipProps, SxProps, Theme, TypographyProps } from '@mui/material';
3
+ import { TextFieldProps, SelectProps, SelectChangeEvent, FormControlLabelProps, SwitchProps, CheckboxProps, IconButtonProps, TooltipProps, SxProps, Theme, TypographyProps } from '@mui/material';
4
+ import { SystemProps } from '@mui/system';
4
5
  import * as _supabase_supabase_js from '@supabase/supabase-js';
5
6
  import { SupabaseClient, User, Session } from '@supabase/supabase-js';
6
7
  import * as i18next from 'i18next';
@@ -104,6 +105,50 @@ interface SelectComponentProps<T = string> extends Omit<SelectProps<T | T[]>, 'o
104
105
  defaultValueOnClear?: T;
105
106
  }
106
107
 
108
+ type SwitchComponentProps = Omit<FormControlLabelProps, 'control' | 'label'> & {
109
+ checked?: boolean;
110
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
111
+ /**
112
+ * Общая метка switch (если одинаковая для обох состояний)
113
+ */
114
+ label?: ReactNode;
115
+ /**
116
+ * Метка, когда Switch в состоянии checked === true
117
+ */
118
+ checkedLabel?: ReactNode;
119
+ /**
120
+ * Метка, когда Switch в состоянии checked === false
121
+ */
122
+ uncheckedLabel?: ReactNode;
123
+ /**
124
+ * Ключ перевода для интерактивного редактирования (TranslationDialog)
125
+ */
126
+ overrideNamespace?: string;
127
+ switchProps?: SwitchProps;
128
+ };
129
+
130
+ type CheckboxComponentProps = Omit<FormControlLabelProps, 'control' | 'label'> & {
131
+ checked?: boolean;
132
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
133
+ /**
134
+ * Общая метка switch (если одинаковая для обох состояний)
135
+ */
136
+ label?: ReactNode;
137
+ /**
138
+ * Метка, когда Checkbox в состоянии checked === true
139
+ */
140
+ checkedLabel?: ReactNode;
141
+ /**
142
+ * Метка, когда Checkbox в состоянии checked === false
143
+ */
144
+ uncheckedLabel?: ReactNode;
145
+ /**
146
+ * Ключ перевода для интерактивного редактирования (TranslationDialog)
147
+ */
148
+ overrideNamespace?: string;
149
+ switchProps?: CheckboxProps;
150
+ };
151
+
107
152
  interface CopyClipboardButtonComponentProps extends Omit<IconButtonProps, 'onClick'> {
108
153
  overrideNamespace?: string;
109
154
  /** Текст, який буде скопійовано в буфер обміну */
@@ -303,6 +348,25 @@ interface ExpandableNoteComponentProps extends Omit<TypographyProps, 'children'>
303
348
  label?: React__default.ReactNode;
304
349
  }
305
350
 
351
+ interface PageLink {
352
+ text: ReactNode;
353
+ href?: string;
354
+ external?: boolean;
355
+ onClick?: React__default.MouseEventHandler<HTMLButtonElement> | undefined;
356
+ hidden?: boolean;
357
+ }
358
+ interface PageLinkWidgetProps {
359
+ overrideNamespace?: string;
360
+ title: ReactNode;
361
+ subheader?: ReactNode;
362
+ description: ReactNode;
363
+ icon?: React__default.ReactElement;
364
+ links: PageLink[];
365
+ actionButtonText?: ReactNode;
366
+ bgcolor?: SystemProps<Theme>['bgcolor'];
367
+ onActionButtonClick?: () => void;
368
+ }
369
+
306
370
  declare const UI: {
307
371
  Inputs: {
308
372
  TextField: React$1.FC<TextFieldComponentProps>;
@@ -310,6 +374,8 @@ declare const UI: {
310
374
  EmailField: React$1.FC<EmailInputComponentProps>;
311
375
  Search: React$1.FC<SearchComponentProps>;
312
376
  Select: <T extends string | number>({ overrideNamespace, label, value, options, onChange, id, fullWidth, size, multiple, withCheckboxes, clearable, maxSelect, disabled, maxDisplayedTags, helperText, defaultValueOnClear, sx, ...restProps }: SelectComponentProps<T>) => React$1.JSX.Element;
377
+ Checkbox: React$1.FC<CheckboxComponentProps>;
378
+ Switch: React$1.FC<SwitchComponentProps>;
313
379
  Url: typeof UrlComponent;
314
380
  };
315
381
  Buttons: {
@@ -325,8 +391,13 @@ declare const UI: {
325
391
  ExpandableNote: React$1.FC<ExpandableNoteComponentProps>;
326
392
  };
327
393
  Widgets: {
328
- ProtectedLanguageSelector: React$1.FC<{}>;
329
- PublicLanguageSelector: React$1.FC<{}>;
394
+ Locales: {
395
+ ProtectedLanguageSelector: React$1.FC<{}>;
396
+ PublicLanguageSelector: React$1.FC<{}>;
397
+ };
398
+ Pages: {
399
+ PageLinkWidget: React$1.FC<PageLinkWidgetProps>;
400
+ };
330
401
  };
331
402
  };
332
403
 
@@ -667,4 +738,4 @@ declare const Hooks: {
667
738
  };
668
739
  };
669
740
 
670
- export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type CompanyMember, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps, type ExpandableNoteComponentProps, type FullCompanyMemberItem, Hooks, type Language, LocalizationProvider, type Membership, type MembershipRole, type MyAvatarComponentProps, type NumberInputComponentProps, Providers, type SaveCompanyUserPayload, type SearchComponentProps, type SelectComponentProps, type SelectOption, Services, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps, type UserGroupedSessions, type UserPopoverComponentProps, type UserProfile, type UserRoleChipComponentProps, type UserSessionItem, type UserSettings, UserSettingsProvider, type UserStatusChipComponentProps, type UserStatusType, defaultUserSettings, initI18n, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
741
+ export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type CheckboxComponentProps, type CompanyMember, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps, type ExpandableNoteComponentProps, type FullCompanyMemberItem, Hooks, type Language, LocalizationProvider, type Membership, type MembershipRole, type MyAvatarComponentProps, type NumberInputComponentProps, type PageLink, type PageLinkWidgetProps, Providers, type SaveCompanyUserPayload, type SearchComponentProps, type SelectComponentProps, type SelectOption, Services, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type SwitchComponentProps, type TextFieldComponentProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps, type UserGroupedSessions, type UserPopoverComponentProps, type UserProfile, type UserRoleChipComponentProps, type UserSessionItem, type UserSettings, UserSettingsProvider, type UserStatusChipComponentProps, type UserStatusType, defaultUserSettings, initI18n, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as React$1 from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { TextFieldProps, SelectProps, SelectChangeEvent, IconButtonProps, TooltipProps, SxProps, Theme, TypographyProps } from '@mui/material';
3
+ import { TextFieldProps, SelectProps, SelectChangeEvent, FormControlLabelProps, SwitchProps, CheckboxProps, IconButtonProps, TooltipProps, SxProps, Theme, TypographyProps } from '@mui/material';
4
+ import { SystemProps } from '@mui/system';
4
5
  import * as _supabase_supabase_js from '@supabase/supabase-js';
5
6
  import { SupabaseClient, User, Session } from '@supabase/supabase-js';
6
7
  import * as i18next from 'i18next';
@@ -104,6 +105,50 @@ interface SelectComponentProps<T = string> extends Omit<SelectProps<T | T[]>, 'o
104
105
  defaultValueOnClear?: T;
105
106
  }
106
107
 
108
+ type SwitchComponentProps = Omit<FormControlLabelProps, 'control' | 'label'> & {
109
+ checked?: boolean;
110
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
111
+ /**
112
+ * Общая метка switch (если одинаковая для обох состояний)
113
+ */
114
+ label?: ReactNode;
115
+ /**
116
+ * Метка, когда Switch в состоянии checked === true
117
+ */
118
+ checkedLabel?: ReactNode;
119
+ /**
120
+ * Метка, когда Switch в состоянии checked === false
121
+ */
122
+ uncheckedLabel?: ReactNode;
123
+ /**
124
+ * Ключ перевода для интерактивного редактирования (TranslationDialog)
125
+ */
126
+ overrideNamespace?: string;
127
+ switchProps?: SwitchProps;
128
+ };
129
+
130
+ type CheckboxComponentProps = Omit<FormControlLabelProps, 'control' | 'label'> & {
131
+ checked?: boolean;
132
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
133
+ /**
134
+ * Общая метка switch (если одинаковая для обох состояний)
135
+ */
136
+ label?: ReactNode;
137
+ /**
138
+ * Метка, когда Checkbox в состоянии checked === true
139
+ */
140
+ checkedLabel?: ReactNode;
141
+ /**
142
+ * Метка, когда Checkbox в состоянии checked === false
143
+ */
144
+ uncheckedLabel?: ReactNode;
145
+ /**
146
+ * Ключ перевода для интерактивного редактирования (TranslationDialog)
147
+ */
148
+ overrideNamespace?: string;
149
+ switchProps?: CheckboxProps;
150
+ };
151
+
107
152
  interface CopyClipboardButtonComponentProps extends Omit<IconButtonProps, 'onClick'> {
108
153
  overrideNamespace?: string;
109
154
  /** Текст, який буде скопійовано в буфер обміну */
@@ -303,6 +348,25 @@ interface ExpandableNoteComponentProps extends Omit<TypographyProps, 'children'>
303
348
  label?: React__default.ReactNode;
304
349
  }
305
350
 
351
+ interface PageLink {
352
+ text: ReactNode;
353
+ href?: string;
354
+ external?: boolean;
355
+ onClick?: React__default.MouseEventHandler<HTMLButtonElement> | undefined;
356
+ hidden?: boolean;
357
+ }
358
+ interface PageLinkWidgetProps {
359
+ overrideNamespace?: string;
360
+ title: ReactNode;
361
+ subheader?: ReactNode;
362
+ description: ReactNode;
363
+ icon?: React__default.ReactElement;
364
+ links: PageLink[];
365
+ actionButtonText?: ReactNode;
366
+ bgcolor?: SystemProps<Theme>['bgcolor'];
367
+ onActionButtonClick?: () => void;
368
+ }
369
+
306
370
  declare const UI: {
307
371
  Inputs: {
308
372
  TextField: React$1.FC<TextFieldComponentProps>;
@@ -310,6 +374,8 @@ declare const UI: {
310
374
  EmailField: React$1.FC<EmailInputComponentProps>;
311
375
  Search: React$1.FC<SearchComponentProps>;
312
376
  Select: <T extends string | number>({ overrideNamespace, label, value, options, onChange, id, fullWidth, size, multiple, withCheckboxes, clearable, maxSelect, disabled, maxDisplayedTags, helperText, defaultValueOnClear, sx, ...restProps }: SelectComponentProps<T>) => React$1.JSX.Element;
377
+ Checkbox: React$1.FC<CheckboxComponentProps>;
378
+ Switch: React$1.FC<SwitchComponentProps>;
313
379
  Url: typeof UrlComponent;
314
380
  };
315
381
  Buttons: {
@@ -325,8 +391,13 @@ declare const UI: {
325
391
  ExpandableNote: React$1.FC<ExpandableNoteComponentProps>;
326
392
  };
327
393
  Widgets: {
328
- ProtectedLanguageSelector: React$1.FC<{}>;
329
- PublicLanguageSelector: React$1.FC<{}>;
394
+ Locales: {
395
+ ProtectedLanguageSelector: React$1.FC<{}>;
396
+ PublicLanguageSelector: React$1.FC<{}>;
397
+ };
398
+ Pages: {
399
+ PageLinkWidget: React$1.FC<PageLinkWidgetProps>;
400
+ };
330
401
  };
331
402
  };
332
403
 
@@ -667,4 +738,4 @@ declare const Hooks: {
667
738
  };
668
739
  };
669
740
 
670
- export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type CompanyMember, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps, type ExpandableNoteComponentProps, type FullCompanyMemberItem, Hooks, type Language, LocalizationProvider, type Membership, type MembershipRole, type MyAvatarComponentProps, type NumberInputComponentProps, Providers, type SaveCompanyUserPayload, type SearchComponentProps, type SelectComponentProps, type SelectOption, Services, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps, type UserGroupedSessions, type UserPopoverComponentProps, type UserProfile, type UserRoleChipComponentProps, type UserSessionItem, type UserSettings, UserSettingsProvider, type UserStatusChipComponentProps, type UserStatusType, defaultUserSettings, initI18n, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
741
+ export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type CheckboxComponentProps, type CompanyMember, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps, type ExpandableNoteComponentProps, type FullCompanyMemberItem, Hooks, type Language, LocalizationProvider, type Membership, type MembershipRole, type MyAvatarComponentProps, type NumberInputComponentProps, type PageLink, type PageLinkWidgetProps, Providers, type SaveCompanyUserPayload, type SearchComponentProps, type SelectComponentProps, type SelectOption, Services, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type SwitchComponentProps, type TextFieldComponentProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps, type UserGroupedSessions, type UserPopoverComponentProps, type UserProfile, type UserRoleChipComponentProps, type UserSessionItem, type UserSettings, UserSettingsProvider, type UserStatusChipComponentProps, type UserStatusType, defaultUserSettings, initI18n, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
package/dist/index.js CHANGED
@@ -4400,6 +4400,208 @@ var ExpandableNoteComponent = ({
4400
4400
  );
4401
4401
  };
4402
4402
 
4403
+ // src/UI/widgets/page/PageLinkWidget.tsx
4404
+ var import_icons_material3 = require("@mui/icons-material");
4405
+ var import_material21 = require("@mui/material");
4406
+ var import_react28 = __toESM(require("react"));
4407
+ var import_react_router_dom = require("react-router-dom");
4408
+ init_context();
4409
+ var import_jsx_runtime31 = require("react/jsx-runtime");
4410
+ var PageLinkWidget = ({
4411
+ overrideNamespace,
4412
+ title,
4413
+ subheader,
4414
+ description,
4415
+ icon,
4416
+ links,
4417
+ actionButtonText,
4418
+ onActionButtonClick,
4419
+ bgcolor
4420
+ }) => {
4421
+ const navigate = (0, import_react_router_dom.useNavigate)();
4422
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4423
+ import_material21.Card,
4424
+ {
4425
+ sx: (theme) => ({
4426
+ height: "100%",
4427
+ display: "flex",
4428
+ flexDirection: "column",
4429
+ boxShadow: 3,
4430
+ bgcolor,
4431
+ color: bgcolor ? typeof bgcolor === "string" && bgcolor.includes(".") ? theme.palette.getContrastText(
4432
+ bgcolor.split(".").reduce((acc, key) => acc[key], theme.palette)
4433
+ ) : typeof bgcolor === "function" ? theme.palette.getContrastText(bgcolor(theme)) : theme.palette.getContrastText(bgcolor) : "text.primary"
4434
+ }),
4435
+ children: [
4436
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4437
+ import_material21.CardHeader,
4438
+ {
4439
+ avatar: icon ? import_react28.default.cloneElement(icon, {
4440
+ sx: { color: bgcolor ? "inherit" : "primary", ...icon.props.sx }
4441
+ }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_icons_material3.Settings, { color: bgcolor ? "inherit" : "primary" }),
4442
+ title: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Typography, { variant: "h6", component: "div", color: "inherit", children: typeof title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: title }) : title }),
4443
+ subheader: subheader && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Typography, { variant: "body2", sx: { opacity: 0.8, color: "inherit" }, children: typeof subheader === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: subheader }) : subheader })
4444
+ }
4445
+ ),
4446
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Divider, { sx: { borderColor: "inherit", opacity: 0.2 } }),
4447
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material21.CardContent, { sx: { flexGrow: 1 }, children: [
4448
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Typography, { variant: "body2", sx: { opacity: 0.85, color: "inherit" }, children: typeof description === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: description }) : description }),
4449
+ links && links.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.List, { dense: true, disablePadding: true, children: links.filter((f) => !f.hidden).map((link, index) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4450
+ import_material21.ListItem,
4451
+ {
4452
+ disablePadding: true,
4453
+ sx: {
4454
+ mt: 1,
4455
+ // Запрещаем ListItem менять цвет фона при наведении
4456
+ "&:hover": {
4457
+ backgroundColor: "transparent"
4458
+ }
4459
+ },
4460
+ children: [
4461
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4462
+ import_material21.ListItemIcon,
4463
+ {
4464
+ sx: { minWidth: 30, cursor: "pointer", color: "inherit" },
4465
+ onClick: () => {
4466
+ if (link?.href) navigate(link.href);
4467
+ },
4468
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_icons_material3.ArrowRight, { fontSize: "small", color: "inherit" })
4469
+ }
4470
+ ),
4471
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.ListItemText, { children: link.onClick ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4472
+ import_material21.Button,
4473
+ {
4474
+ size: "small",
4475
+ variant: "text",
4476
+ color: bgcolor ? "inherit" : "primary",
4477
+ onClick: link.onClick,
4478
+ sx: {
4479
+ fontWeight: 500,
4480
+ textTransform: "none",
4481
+ // Отключает автоматические заглавные буквы (UPPERCASE)
4482
+ padding: 0,
4483
+ minWidth: "auto",
4484
+ justifyContent: "flex-start",
4485
+ textAlign: "left",
4486
+ transition: "opacity 0.2s ease-in-out",
4487
+ "&:hover": {
4488
+ opacity: 0.75,
4489
+ backgroundColor: "transparent",
4490
+ // Убирает стандартную серую подложку при ховере кнопки
4491
+ textDecoration: "underline"
4492
+ // Эффект подчеркивания, как у ссылки
4493
+ }
4494
+ },
4495
+ children: link.text
4496
+ }
4497
+ ) : link.href ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4498
+ import_material21.Link,
4499
+ {
4500
+ component: import_react_router_dom.Link,
4501
+ to: link.href,
4502
+ target: link.external ? "_blank" : "_self",
4503
+ rel: link.external ? "noopener noreferrer" : "",
4504
+ underline: "hover",
4505
+ color: bgcolor ? "inherit" : "primary",
4506
+ sx: {
4507
+ fontWeight: 500,
4508
+ display: "inline-block",
4509
+ transition: "opacity 0.2s ease-in-out",
4510
+ "&:hover": {
4511
+ opacity: 0.75,
4512
+ backgroundColor: "transparent"
4513
+ }
4514
+ },
4515
+ children: typeof link.text === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: link.text }) : link.text
4516
+ }
4517
+ ) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Typography, { variant: "body2", sx: { fontWeight: 500, color: "inherit" }, children: typeof link.text === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: link.text }) : link.text }) })
4518
+ ]
4519
+ },
4520
+ index
4521
+ )) })
4522
+ ] }),
4523
+ actionButtonText && onActionButtonClick && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.CardActions, { sx: { justifyContent: "flex-end", padding: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material21.Button, { size: "small", variant: "contained", onClick: onActionButtonClick, children: typeof actionButtonText === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TranslateText, { overrideNamespace, children: actionButtonText }) : actionButtonText }) })
4524
+ ]
4525
+ }
4526
+ );
4527
+ };
4528
+
4529
+ // src/UI/components/inputs/CheckboxComponent.tsx
4530
+ var import_material22 = require("@mui/material");
4531
+ init_TranslateText();
4532
+ var import_jsx_runtime32 = require("react/jsx-runtime");
4533
+ var CheckboxComponent = ({
4534
+ checked = false,
4535
+ onChange,
4536
+ label,
4537
+ checkedLabel,
4538
+ uncheckedLabel,
4539
+ overrideNamespace,
4540
+ switchProps,
4541
+ ...props
4542
+ }) => {
4543
+ const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
4544
+ const renderLabel = (node) => {
4545
+ if (typeof node === "string") {
4546
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TranslateText, { overrideNamespace, children: node });
4547
+ }
4548
+ return node;
4549
+ };
4550
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material22.Box, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4551
+ import_material22.FormControlLabel,
4552
+ {
4553
+ control: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4554
+ import_material22.Checkbox,
4555
+ {
4556
+ checked,
4557
+ onChange,
4558
+ ...switchProps
4559
+ }
4560
+ ),
4561
+ label: renderLabel(currentLabel),
4562
+ ...props
4563
+ }
4564
+ ) }) });
4565
+ };
4566
+
4567
+ // src/UI/components/inputs/SwitchComponent.tsx
4568
+ var import_material23 = require("@mui/material");
4569
+ init_TranslateText();
4570
+ var import_jsx_runtime33 = require("react/jsx-runtime");
4571
+ var SwitchComponent = ({
4572
+ checked = false,
4573
+ onChange,
4574
+ label,
4575
+ checkedLabel,
4576
+ uncheckedLabel,
4577
+ overrideNamespace,
4578
+ switchProps,
4579
+ ...props
4580
+ }) => {
4581
+ const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
4582
+ const renderLabel = (node) => {
4583
+ if (typeof node === "string") {
4584
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TranslateText, { overrideNamespace, children: node });
4585
+ }
4586
+ return node;
4587
+ };
4588
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material23.Box, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4589
+ import_material23.FormControlLabel,
4590
+ {
4591
+ control: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4592
+ import_material23.Switch,
4593
+ {
4594
+ checked,
4595
+ onChange,
4596
+ ...switchProps
4597
+ }
4598
+ ),
4599
+ label: renderLabel(currentLabel),
4600
+ ...props
4601
+ }
4602
+ ) }) });
4603
+ };
4604
+
4403
4605
  // src/UI/index.ts
4404
4606
  var UI = {
4405
4607
  Inputs: {
@@ -4408,6 +4610,8 @@ var UI = {
4408
4610
  EmailField: EmailInputComponent,
4409
4611
  Search: SearchComponent,
4410
4612
  Select: SelectComponent,
4613
+ Checkbox: CheckboxComponent,
4614
+ Switch: SwitchComponent,
4411
4615
  Url: UrlComponent
4412
4616
  },
4413
4617
  Buttons: {
@@ -4426,8 +4630,13 @@ var UI = {
4426
4630
  Row: FormRow,
4427
4631
  },*/
4428
4632
  Widgets: {
4429
- ProtectedLanguageSelector: LanguageSelector,
4430
- PublicLanguageSelector
4633
+ Locales: {
4634
+ ProtectedLanguageSelector: LanguageSelector,
4635
+ PublicLanguageSelector
4636
+ },
4637
+ Pages: {
4638
+ PageLinkWidget
4639
+ }
4431
4640
  }
4432
4641
  };
4433
4642
 
@@ -4454,16 +4663,16 @@ var Services = {
4454
4663
  };
4455
4664
 
4456
4665
  // src/hooks/useUserStatus.ts
4457
- var import_react28 = require("react");
4666
+ var import_react29 = require("react");
4458
4667
  init_deviceId();
4459
4668
  init_context();
4460
4669
  var ONLINE_THRESHOLD_MINUTES = 2;
4461
4670
  var AWAY_THRESHOLD_MINUTES = 15;
4462
4671
  var useUserStatus2 = (userId, initialLastSeenAt, currentAuthUserId) => {
4463
4672
  const supabase = useSupabase();
4464
- const [status, setStatus] = (0, import_react28.useState)("offline");
4465
- const [lastSeen, setLastSeen] = (0, import_react28.useState)(initialLastSeenAt ?? null);
4466
- const lastSeenRef = (0, import_react28.useRef)(initialLastSeenAt ?? null);
4673
+ const [status, setStatus] = (0, import_react29.useState)("offline");
4674
+ const [lastSeen, setLastSeen] = (0, import_react29.useState)(initialLastSeenAt ?? null);
4675
+ const lastSeenRef = (0, import_react29.useRef)(initialLastSeenAt ?? null);
4467
4676
  lastSeenRef.current = lastSeen;
4468
4677
  const calculateStatus = (isOnline, lastSeenIso) => {
4469
4678
  if (isOnline) return "online";
@@ -4479,7 +4688,7 @@ var useUserStatus2 = (userId, initialLastSeenAt, currentAuthUserId) => {
4479
4688
  }
4480
4689
  return "offline";
4481
4690
  };
4482
- (0, import_react28.useEffect)(() => {
4691
+ (0, import_react29.useEffect)(() => {
4483
4692
  if (!userId) return;
4484
4693
  let isMounted = true;
4485
4694
  const isSelf = currentAuthUserId && userId === currentAuthUserId;
package/dist/index.mjs CHANGED
@@ -1653,6 +1653,226 @@ var ExpandableNoteComponent = ({
1653
1653
  );
1654
1654
  };
1655
1655
 
1656
+ // src/UI/widgets/page/PageLinkWidget.tsx
1657
+ import { ArrowRight, Settings } from "@mui/icons-material";
1658
+ import {
1659
+ Button as Button2,
1660
+ Card,
1661
+ CardActions,
1662
+ CardContent,
1663
+ CardHeader,
1664
+ Divider,
1665
+ List,
1666
+ ListItem,
1667
+ ListItemIcon,
1668
+ ListItemText as ListItemText2,
1669
+ Typography as Typography6,
1670
+ Link as MuiLink
1671
+ } from "@mui/material";
1672
+ import React10 from "react";
1673
+ import { Link as RouterLink, useNavigate } from "react-router-dom";
1674
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1675
+ var PageLinkWidget = ({
1676
+ overrideNamespace,
1677
+ title,
1678
+ subheader,
1679
+ description,
1680
+ icon,
1681
+ links,
1682
+ actionButtonText,
1683
+ onActionButtonClick,
1684
+ bgcolor
1685
+ }) => {
1686
+ const navigate = useNavigate();
1687
+ return /* @__PURE__ */ jsxs10(
1688
+ Card,
1689
+ {
1690
+ sx: (theme) => ({
1691
+ height: "100%",
1692
+ display: "flex",
1693
+ flexDirection: "column",
1694
+ boxShadow: 3,
1695
+ bgcolor,
1696
+ color: bgcolor ? typeof bgcolor === "string" && bgcolor.includes(".") ? theme.palette.getContrastText(
1697
+ bgcolor.split(".").reduce((acc, key) => acc[key], theme.palette)
1698
+ ) : typeof bgcolor === "function" ? theme.palette.getContrastText(bgcolor(theme)) : theme.palette.getContrastText(bgcolor) : "text.primary"
1699
+ }),
1700
+ children: [
1701
+ /* @__PURE__ */ jsx11(
1702
+ CardHeader,
1703
+ {
1704
+ avatar: icon ? React10.cloneElement(icon, {
1705
+ sx: { color: bgcolor ? "inherit" : "primary", ...icon.props.sx }
1706
+ }) : /* @__PURE__ */ jsx11(Settings, { color: bgcolor ? "inherit" : "primary" }),
1707
+ title: /* @__PURE__ */ jsx11(Typography6, { variant: "h6", component: "div", color: "inherit", children: typeof title === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: title }) : title }),
1708
+ subheader: subheader && /* @__PURE__ */ jsx11(Typography6, { variant: "body2", sx: { opacity: 0.8, color: "inherit" }, children: typeof subheader === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: subheader }) : subheader })
1709
+ }
1710
+ ),
1711
+ /* @__PURE__ */ jsx11(Divider, { sx: { borderColor: "inherit", opacity: 0.2 } }),
1712
+ /* @__PURE__ */ jsxs10(CardContent, { sx: { flexGrow: 1 }, children: [
1713
+ /* @__PURE__ */ jsx11(Typography6, { variant: "body2", sx: { opacity: 0.85, color: "inherit" }, children: typeof description === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: description }) : description }),
1714
+ links && links.length > 0 && /* @__PURE__ */ jsx11(List, { dense: true, disablePadding: true, children: links.filter((f) => !f.hidden).map((link, index) => /* @__PURE__ */ jsxs10(
1715
+ ListItem,
1716
+ {
1717
+ disablePadding: true,
1718
+ sx: {
1719
+ mt: 1,
1720
+ // Запрещаем ListItem менять цвет фона при наведении
1721
+ "&:hover": {
1722
+ backgroundColor: "transparent"
1723
+ }
1724
+ },
1725
+ children: [
1726
+ /* @__PURE__ */ jsx11(
1727
+ ListItemIcon,
1728
+ {
1729
+ sx: { minWidth: 30, cursor: "pointer", color: "inherit" },
1730
+ onClick: () => {
1731
+ if (link?.href) navigate(link.href);
1732
+ },
1733
+ children: /* @__PURE__ */ jsx11(ArrowRight, { fontSize: "small", color: "inherit" })
1734
+ }
1735
+ ),
1736
+ /* @__PURE__ */ jsx11(ListItemText2, { children: link.onClick ? /* @__PURE__ */ jsx11(
1737
+ Button2,
1738
+ {
1739
+ size: "small",
1740
+ variant: "text",
1741
+ color: bgcolor ? "inherit" : "primary",
1742
+ onClick: link.onClick,
1743
+ sx: {
1744
+ fontWeight: 500,
1745
+ textTransform: "none",
1746
+ // Отключает автоматические заглавные буквы (UPPERCASE)
1747
+ padding: 0,
1748
+ minWidth: "auto",
1749
+ justifyContent: "flex-start",
1750
+ textAlign: "left",
1751
+ transition: "opacity 0.2s ease-in-out",
1752
+ "&:hover": {
1753
+ opacity: 0.75,
1754
+ backgroundColor: "transparent",
1755
+ // Убирает стандартную серую подложку при ховере кнопки
1756
+ textDecoration: "underline"
1757
+ // Эффект подчеркивания, как у ссылки
1758
+ }
1759
+ },
1760
+ children: link.text
1761
+ }
1762
+ ) : link.href ? /* @__PURE__ */ jsx11(
1763
+ MuiLink,
1764
+ {
1765
+ component: RouterLink,
1766
+ to: link.href,
1767
+ target: link.external ? "_blank" : "_self",
1768
+ rel: link.external ? "noopener noreferrer" : "",
1769
+ underline: "hover",
1770
+ color: bgcolor ? "inherit" : "primary",
1771
+ sx: {
1772
+ fontWeight: 500,
1773
+ display: "inline-block",
1774
+ transition: "opacity 0.2s ease-in-out",
1775
+ "&:hover": {
1776
+ opacity: 0.75,
1777
+ backgroundColor: "transparent"
1778
+ }
1779
+ },
1780
+ children: typeof link.text === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: link.text }) : link.text
1781
+ }
1782
+ ) : /* @__PURE__ */ jsx11(Typography6, { variant: "body2", sx: { fontWeight: 500, color: "inherit" }, children: typeof link.text === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: link.text }) : link.text }) })
1783
+ ]
1784
+ },
1785
+ index
1786
+ )) })
1787
+ ] }),
1788
+ actionButtonText && onActionButtonClick && /* @__PURE__ */ jsx11(CardActions, { sx: { justifyContent: "flex-end", padding: 2 }, children: /* @__PURE__ */ jsx11(Button2, { size: "small", variant: "contained", onClick: onActionButtonClick, children: typeof actionButtonText === "string" ? /* @__PURE__ */ jsx11(TranslateText, { overrideNamespace, children: actionButtonText }) : actionButtonText }) })
1789
+ ]
1790
+ }
1791
+ );
1792
+ };
1793
+
1794
+ // src/UI/components/inputs/CheckboxComponent.tsx
1795
+ import {
1796
+ FormControlLabel,
1797
+ Checkbox as Checkbox2,
1798
+ Box as Box6
1799
+ } from "@mui/material";
1800
+ import { Fragment as Fragment9, jsx as jsx12 } from "react/jsx-runtime";
1801
+ var CheckboxComponent = ({
1802
+ checked = false,
1803
+ onChange,
1804
+ label,
1805
+ checkedLabel,
1806
+ uncheckedLabel,
1807
+ overrideNamespace,
1808
+ switchProps,
1809
+ ...props
1810
+ }) => {
1811
+ const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
1812
+ const renderLabel = (node) => {
1813
+ if (typeof node === "string") {
1814
+ return /* @__PURE__ */ jsx12(TranslateText, { overrideNamespace, children: node });
1815
+ }
1816
+ return node;
1817
+ };
1818
+ return /* @__PURE__ */ jsx12(Fragment9, { children: /* @__PURE__ */ jsx12(Box6, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5 }, children: /* @__PURE__ */ jsx12(
1819
+ FormControlLabel,
1820
+ {
1821
+ control: /* @__PURE__ */ jsx12(
1822
+ Checkbox2,
1823
+ {
1824
+ checked,
1825
+ onChange,
1826
+ ...switchProps
1827
+ }
1828
+ ),
1829
+ label: renderLabel(currentLabel),
1830
+ ...props
1831
+ }
1832
+ ) }) });
1833
+ };
1834
+
1835
+ // src/UI/components/inputs/SwitchComponent.tsx
1836
+ import {
1837
+ FormControlLabel as FormControlLabel2,
1838
+ Switch,
1839
+ Box as Box7
1840
+ } from "@mui/material";
1841
+ import { Fragment as Fragment10, jsx as jsx13 } from "react/jsx-runtime";
1842
+ var SwitchComponent = ({
1843
+ checked = false,
1844
+ onChange,
1845
+ label,
1846
+ checkedLabel,
1847
+ uncheckedLabel,
1848
+ overrideNamespace,
1849
+ switchProps,
1850
+ ...props
1851
+ }) => {
1852
+ const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
1853
+ const renderLabel = (node) => {
1854
+ if (typeof node === "string") {
1855
+ return /* @__PURE__ */ jsx13(TranslateText, { overrideNamespace, children: node });
1856
+ }
1857
+ return node;
1858
+ };
1859
+ return /* @__PURE__ */ jsx13(Fragment10, { children: /* @__PURE__ */ jsx13(Box7, { sx: { display: "inline-flex", alignItems: "center", gap: 0.5 }, children: /* @__PURE__ */ jsx13(
1860
+ FormControlLabel2,
1861
+ {
1862
+ control: /* @__PURE__ */ jsx13(
1863
+ Switch,
1864
+ {
1865
+ checked,
1866
+ onChange,
1867
+ ...switchProps
1868
+ }
1869
+ ),
1870
+ label: renderLabel(currentLabel),
1871
+ ...props
1872
+ }
1873
+ ) }) });
1874
+ };
1875
+
1656
1876
  // src/UI/index.ts
1657
1877
  var UI = {
1658
1878
  Inputs: {
@@ -1661,6 +1881,8 @@ var UI = {
1661
1881
  EmailField: EmailInputComponent,
1662
1882
  Search: SearchComponent,
1663
1883
  Select: SelectComponent,
1884
+ Checkbox: CheckboxComponent,
1885
+ Switch: SwitchComponent,
1664
1886
  Url: UrlComponent
1665
1887
  },
1666
1888
  Buttons: {
@@ -1679,8 +1901,13 @@ var UI = {
1679
1901
  Row: FormRow,
1680
1902
  },*/
1681
1903
  Widgets: {
1682
- ProtectedLanguageSelector: LanguageSelector,
1683
- PublicLanguageSelector
1904
+ Locales: {
1905
+ ProtectedLanguageSelector: LanguageSelector,
1906
+ PublicLanguageSelector
1907
+ },
1908
+ Pages: {
1909
+ PageLinkWidget
1910
+ }
1684
1911
  }
1685
1912
  };
1686
1913
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serhii.olishevskyi/docs",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "DOCS.UA react packages",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -36,6 +36,7 @@
36
36
  "dependencies": {
37
37
  "@google/genai": "^2.27.0",
38
38
  "@supabase/supabase-js": "^2.117.2",
39
- "moment": "^2.31.0"
39
+ "moment": "^2.31.0",
40
+ "react-router-dom": "^7.18.4"
40
41
  }
41
42
  }