@trii/components 2.0.103 → 3.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.
Files changed (39) hide show
  1. package/async-state/package.json +9 -0
  2. package/dist/async-state.d.ts +184 -0
  3. package/dist/cjs/async-state.js +2 -0
  4. package/dist/cjs/async-state.js.map +1 -0
  5. package/dist/cjs/index.js +36 -36
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/esm/async-state.js +2 -0
  8. package/dist/esm/async-state.js.map +1 -0
  9. package/dist/esm/index.js +38 -38
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/index.d.ts +346 -5
  12. package/dist/types/asyncState/asyncState.d.ts +99 -0
  13. package/dist/types/asyncState/getErrorMessage.d.ts +16 -0
  14. package/dist/types/asyncState/index.d.ts +15 -0
  15. package/dist/types/asyncState/types.d.ts +17 -0
  16. package/dist/types/asyncState/useAsyncData.d.ts +51 -0
  17. package/dist/types/components/AsyncContent/AsyncContent.d.ts +48 -0
  18. package/dist/types/components/AsyncContent/index.d.ts +2 -0
  19. package/dist/types/components/ContactSidebar/ChatDetailsSidebar.d.ts +17 -3
  20. package/dist/types/components/ContactSidebar/SidebarContent.d.ts +9 -4
  21. package/dist/types/components/ContactSidebar/components/PanelView/PanelView.d.ts +1 -4
  22. package/dist/types/components/ContactSidebar/components/PanelView/components/ContactMedia/ContactMedia.d.ts +0 -1
  23. package/dist/types/components/ContactSidebar/components/PanelView/components/GroupData/GroupData.d.ts +0 -1
  24. package/dist/types/components/ContactSidebar/components/PanelView/components/index.d.ts +0 -3
  25. package/dist/types/components/ContactSidebar/components/PanelView/layout/SectionCard/SectionCard.d.ts +1 -1
  26. package/dist/types/components/ContactSidebar/components/PanelView/types/ContactProps.d.ts +0 -1
  27. package/dist/types/components/ContactSidebar/components/TabsMenu/TabsMenu.d.ts +0 -3
  28. package/dist/types/components/ContactSidebar/components/index.d.ts +0 -3
  29. package/dist/types/components/EmptyState/EmptyState.d.ts +22 -0
  30. package/dist/types/components/EmptyState/index.d.ts +2 -0
  31. package/dist/types/components/ErrorState/ErrorState.d.ts +23 -0
  32. package/dist/types/components/ErrorState/index.d.ts +2 -0
  33. package/dist/types/components/PanelErrorBoundary/PanelErrorBoundary.d.ts +55 -0
  34. package/dist/types/components/PanelErrorBoundary/index.d.ts +2 -0
  35. package/dist/types/components/index.d.ts +8 -0
  36. package/dist/types/i18n/config.d.ts +6 -0
  37. package/dist/types/i18n/useComponentsTranslation.d.ts +17 -0
  38. package/dist/types/index.d.ts +1 -0
  39. package/package.json +5 -3
@@ -23,6 +23,12 @@ interface ChatDetailsSidebarBaseProps {
23
23
  * propia instancia de i18n, así que no sigue solo los cambios del host.
24
24
  */
25
25
  language?: string;
26
+ /**
27
+ * Gate de visibilidad (CSS display) del panel. Para hosts que renderizan
28
+ * vistas hermanas alternadas por CSS: el panel queda montado (conserva su
29
+ * estado y sus datos) pero oculto mientras `active` es false. Default: true.
30
+ */
31
+ active?: boolean;
26
32
  }
27
33
  /**
28
34
  * Qué mostrar. Hay dos formas y son excluyentes; TypeScript falla si no se pasa
@@ -55,9 +61,17 @@ type ChatDetailsSidebarTarget = {
55
61
  };
56
62
  export type ChatDetailsSidebarProps = ChatDetailsSidebarBaseProps & ChatDetailsSidebarTarget;
57
63
  /**
58
- * Shell del sidebar (en camino al paquete npm): recibe las props del
59
- * contrato (docs/CONTRATO_CHATDETAILSSIDEBAR.md) y monta los providers
60
- * internos. La orquestación de UI vive en SidebarContent.
64
+ * Panel de contacto reutilizable: la ficha completa de un contacto/empresa
65
+ * (datos, conversaciones, archivos, media, historial, eventos, tareas, shop,
66
+ * relaciones, grupos de WhatsApp) con su riel vertical de tabs, skeleton y
67
+ * overlay de carga. Recibe las props del contrato y monta los providers
68
+ * internos; la orquestación de tabs vive en SidebarContent.
69
+ *
70
+ * El shell de vistas (header Contacto/Interacción/Asistente) es del host: este
71
+ * componente renderiza SOLO la vista de contacto y expone `active` para que el
72
+ * host lo alterne por CSS con sus vistas hermanas sin desmontarlo. Debe
73
+ * colocarse dentro de un contenedor flex con `position: relative` (el overlay
74
+ * y el skeleton se posicionan contra ese contenedor). Ver README.md.
61
75
  */
62
76
  declare const ChatDetailsSidebar: (props: ChatDetailsSidebarProps) => import("react/jsx-runtime").JSX.Element;
63
77
  export default ChatDetailsSidebar;
@@ -1,11 +1,16 @@
1
1
  import { IConversation } from '@trii/types/dist/Conversations';
2
2
  export interface SidebarContentProps {
3
3
  conversation: IConversation | null;
4
+ /** Gate CSS de visibilidad del panel (ver ChatDetailsSidebar.active). */
5
+ active: boolean;
4
6
  }
5
7
  /**
6
- * Orquestación de UI del sidebar (tabs, overlay, skeleton). Vive dentro de
7
- * los providers internos (SidebarProps + SidebarData) para poder disparar
8
- * los fetches del mini-store sin tocar el store del host.
8
+ * Orquestación de UI del panel de contacto (tabs, overlay, skeleton). Vive
9
+ * dentro de los providers internos (SidebarProps + SidebarData) para poder
10
+ * disparar los fetches del mini-store sin tocar el store del host.
11
+ *
12
+ * El root es un Fragment: skeleton/panel/overlay se posicionan contra el
13
+ * contenedor `position: relative` que provee el host.
9
14
  */
10
- declare const SidebarContent: ({ conversation }: SidebarContentProps) => import("react/jsx-runtime").JSX.Element;
15
+ declare const SidebarContent: ({ conversation, active }: SidebarContentProps) => import("react/jsx-runtime").JSX.Element;
11
16
  export default SidebarContent;
@@ -1,9 +1,6 @@
1
- import { SectionRefs } from '../../hooks/useSectionRefs';
2
1
  type PanelViewProps = {
3
- sectionRefs: SectionRefs;
4
- setValue: (value: number) => void;
2
+ /** Índice del tab activo (lo controla TabsMenu vía SidebarContent). */
5
3
  value: number;
6
- isClicked: boolean;
7
4
  };
8
5
  declare const PanelView: ({ value }: PanelViewProps) => import("react/jsx-runtime").JSX.Element;
9
6
  export default PanelView;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  type ContactProps = {
3
3
  contactId: string;
4
- handleClick?: () => void;
5
4
  defaultExpanded?: boolean;
6
5
  };
7
6
  declare const ContactMedia: React.ForwardRefExoticComponent<ContactProps & React.RefAttributes<HTMLElement>>;
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  type Props = {
3
- handleClick: () => void;
4
3
  defaultExpanded?: boolean;
5
4
  };
6
5
  declare const GroupData: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<HTMLElement>>;
@@ -5,13 +5,10 @@ export { default as ContactFiles } from './ContactFiles';
5
5
  export { default as ContactMedia } from './ContactMedia';
6
6
  export { default as ContactHistory } from './ContactHistory';
7
7
  export { default as ContactNotes } from './ContactNotes';
8
- export { default as ContactRepairs } from './ContactRepairs';
9
8
  export { default as ContactEvent } from './ContactEvent';
10
9
  export { default as ContactTask } from './ContactTask';
11
- export { default as ContactTicket } from './ContactTicket';
12
10
  export { default as ContactButton } from './ContactButton';
13
11
  export { default as ContactPanelShop } from './ContactPanelShop';
14
12
  export { default as ContactRelations } from './ContactRelations';
15
13
  export { default as GroupData } from './GroupData';
16
14
  export { default as PremiumContactHeader } from './PremiumContactHeader';
17
- export { default as ContactHighlights } from './ContactHighlights';
@@ -5,7 +5,7 @@ type SectionCardProps = {
5
5
  children: ReactNode;
6
6
  title: string;
7
7
  defaultExpanded?: boolean;
8
- onClick: () => void;
8
+ onClick?: () => void;
9
9
  tabName: TabName;
10
10
  contactInfo?: IContact;
11
11
  onExpandChange?: (isExpanded: boolean) => void;
@@ -1,7 +1,6 @@
1
1
  import { IIntegrationButton } from '@trii/types/dist/Contacts';
2
2
  export interface ContactProps {
3
3
  contactId?: string;
4
- handleClick: () => void;
5
4
  defaultExpanded?: boolean;
6
5
  }
7
6
  export interface ContactButtonProps extends ContactProps {
@@ -1,9 +1,6 @@
1
- import { SectionRefs } from '../../hooks/useSectionRefs';
2
1
  type TabsMenuProps = {
3
2
  handleChange: (newValue: number) => void;
4
3
  value: number;
5
- sectionRefs: SectionRefs;
6
- setIsClicked: (isClicked: boolean) => void;
7
4
  };
8
5
  declare function TabsMenu({ handleChange, value }: TabsMenuProps): import("react/jsx-runtime").JSX.Element;
9
6
  export default TabsMenu;
@@ -1,6 +1,3 @@
1
1
  export { default as ContactInfoSkeleton } from './ContactInfoSkeleton';
2
- export { default as AssistantView } from './AssistantView/AssistantView';
3
- export { default as InteractionView } from './InteractionView/InteractionView';
4
2
  export { default as PanelView } from './PanelView';
5
- export { default as SidebarViewNavigation, type SidebarView, type SidebarViewDefinition, } from './SidebarViewNavigation/SidebarViewNavigation';
6
3
  export { default as TabsMenu } from './TabsMenu';
@@ -0,0 +1,22 @@
1
+ import { ReactNode } from 'react';
2
+ export interface EmptyStateProps {
3
+ /** Título principal (default: i18n `asyncState.emptyTitle`). */
4
+ title?: string;
5
+ /** Descripción secundaria (default: i18n `asyncState.emptyDescription`). */
6
+ description?: string;
7
+ /** Icono personalizado (default: `InboxIcon`). */
8
+ icon?: ReactNode;
9
+ /** Acción opcional bajo el texto (p.ej. botón "Crear el primero"). */
10
+ action?: ReactNode;
11
+ /** Versión compacta (menos padding e icono más chico). */
12
+ compact?: boolean;
13
+ /** Idioma de los textos por defecto ('es' | 'en'). Opcional: ver useComponentsTranslation. */
14
+ language?: string;
15
+ }
16
+ /**
17
+ * Estado "vacío real": la carga fue exitosa pero no hay datos que mostrar.
18
+ * No confundir con "aún no se cargó" (eso es loading) ni con un error.
19
+ * Presentacional y genérico (ver docs/ASYNC_STATE.md).
20
+ */
21
+ declare const EmptyState: ({ title, description, icon, action, compact, language, }: EmptyStateProps) => import("react/jsx-runtime").JSX.Element;
22
+ export default EmptyState;
@@ -0,0 +1,2 @@
1
+ export { default } from './EmptyState';
2
+ export type { EmptyStateProps } from './EmptyState';
@@ -0,0 +1,23 @@
1
+ export interface ErrorStateProps {
2
+ /** Título principal (default: i18n `asyncState.errorTitle`). */
3
+ title?: string;
4
+ /** Descripción secundaria (default: i18n `asyncState.errorDescription`). */
5
+ description?: string;
6
+ /** Detalle técnico o mensaje del backend (se muestra atenuado). */
7
+ error?: string | null;
8
+ /** Si se provee, muestra el botón de reintento. */
9
+ onRetry?: () => void;
10
+ /** Texto del botón de reintento (default: i18n `asyncState.retry`). */
11
+ retryLabel?: string;
12
+ /** Versión compacta (menos padding e icono más chico) para paneles angostos. */
13
+ compact?: boolean;
14
+ /** Idioma de los textos por defecto ('es' | 'en'). Opcional: ver useComponentsTranslation. */
15
+ language?: string;
16
+ }
17
+ /**
18
+ * Estado de error a nivel panel, con retry opcional.
19
+ * Presentacional y genérico: no conoce Redux ni fetching
20
+ * (ver docs/ASYNC_STATE.md).
21
+ */
22
+ declare const ErrorState: ({ title, description, error, onRetry, retryLabel, compact, language, }: ErrorStateProps) => import("react/jsx-runtime").JSX.Element;
23
+ export default ErrorState;
@@ -0,0 +1,2 @@
1
+ export { default } from './ErrorState';
2
+ export type { ErrorStateProps } from './ErrorState';
@@ -0,0 +1,55 @@
1
+ import { Component, ErrorInfo, ReactNode } from 'react';
2
+ export interface PanelErrorBoundaryProps {
3
+ children: ReactNode;
4
+ /**
5
+ * Fallback custom ante un crash de render. Puede ser un nodo o una función
6
+ * que recibe el error y `resetErrorBoundary` (para reintentar).
7
+ */
8
+ fallback?: ReactNode | ((args: {
9
+ error: Error | null;
10
+ resetErrorBoundary: () => void;
11
+ }) => ReactNode);
12
+ /** Telemetría/logging del error (p.ej. enviar a un servicio externo). */
13
+ onError?: (error: Error, info: ErrorInfo) => void;
14
+ /**
15
+ * Claves que al cambiar resetean el boundary automáticamente
16
+ * (p.ej. el id de la ruta actual, para reintentar al navegar).
17
+ */
18
+ resetKeys?: ReadonlyArray<unknown>;
19
+ /** Overrides de textos del fallback por defecto. */
20
+ title?: string;
21
+ description?: string;
22
+ /** Idioma de los textos por defecto ('es' | 'en'). Opcional: ver useComponentsTranslation. */
23
+ language?: string;
24
+ }
25
+ interface PanelErrorBoundaryState {
26
+ hasError: boolean;
27
+ error: Error | null;
28
+ }
29
+ /**
30
+ * Aísla fallos de RENDER por panel: si el contenido explota, el resto de la
31
+ * UI (hermanos, otros paneles, la navegación) sigue funcionando y el panel
32
+ * muestra un fallback con reintento.
33
+ *
34
+ * ```tsx
35
+ * <PanelErrorBoundary resetKeys={[conversationId]}>
36
+ * <ContactInfoPanel />
37
+ * </PanelErrorBoundary>
38
+ * <PanelErrorBoundary>
39
+ * <MessagesPanel />
40
+ * </PanelErrorBoundary>
41
+ * ```
42
+ *
43
+ * NOTA: los boundaries NO capturan errores de fetching (para eso está
44
+ * `<AsyncContent>`), ni de event handlers, ni de código asíncrono.
45
+ * Guía completa: docs/ASYNC_STATE.md
46
+ */
47
+ declare class PanelErrorBoundary extends Component<PanelErrorBoundaryProps, PanelErrorBoundaryState> {
48
+ state: PanelErrorBoundaryState;
49
+ static getDerivedStateFromError(error: Error): PanelErrorBoundaryState;
50
+ componentDidCatch(error: Error, info: ErrorInfo): void;
51
+ componentDidUpdate(prevProps: PanelErrorBoundaryProps): void;
52
+ reset: () => void;
53
+ render(): ReactNode;
54
+ }
55
+ export default PanelErrorBoundary;
@@ -0,0 +1,2 @@
1
+ export { default } from './PanelErrorBoundary';
2
+ export type { PanelErrorBoundaryProps } from './PanelErrorBoundary';
@@ -4,5 +4,13 @@ export type { EditContactModalProps, EditContactMode } from './EditContactModal'
4
4
  export { default as EventsDialog } from './EventsDialog';
5
5
  export type { EventsDialogProps, EventData, TaskData } from './EventsDialog';
6
6
  export type { ModalMode, ItemType, Calendar, Contact, Notification } from './EventsDialog/types';
7
+ export { default as AsyncContent } from './AsyncContent';
8
+ export type { AsyncContentProps } from './AsyncContent';
9
+ export { default as EmptyState } from './EmptyState';
10
+ export type { EmptyStateProps } from './EmptyState';
11
+ export { default as ErrorState } from './ErrorState';
12
+ export type { ErrorStateProps } from './ErrorState';
13
+ export { default as PanelErrorBoundary } from './PanelErrorBoundary';
14
+ export type { PanelErrorBoundaryProps } from './PanelErrorBoundary';
7
15
  export { default as ContactSidebar } from './ContactSidebar';
8
16
  export type { ContactSidebarProps, SidebarChatIntegration, StartConversationTarget, } from './ContactSidebar';
@@ -1,2 +1,8 @@
1
1
  declare const i18nInstance: import("i18next").i18n;
2
+ /**
3
+ * Normaliza lo que venga del anfitrión ('ES', 'En', 'es-AR', ...) a un idioma
4
+ * soportado por el paquete. El default es 'en' porque es el `fallbackLng` de
5
+ * esta instancia.
6
+ */
7
+ export declare function normalizeLanguage(language?: string): 'en' | 'es';
2
8
  export default i18nInstance;
@@ -0,0 +1,17 @@
1
+ import type { TFunction } from 'i18next';
2
+ /**
3
+ * `t` atado a la instancia del paquete, SIN montar un `I18nextProvider`.
4
+ *
5
+ * Es la diferencia con el patrón de EditContactModal/ContactSidebar: esos
6
+ * componentes son un árbol cerrado y pueden pisar el context. Las primitivas
7
+ * de estado asíncrono (`AsyncContent`, `PanelErrorBoundary`) renderizan
8
+ * children DEL ANFITRIÓN; si montaran un provider, esos children resolverían
9
+ * sus claves contra la instancia del paquete y quedarían sin traducir.
10
+ * Pasando `{ i18n }` a `useTranslation`, solo los textos propios se atan.
11
+ *
12
+ * `language` es opcional: si el anfitrión ya sincroniza el idioma con
13
+ * `i18n.changeLanguage(...)` (exportado desde el índice del paquete), no hace
14
+ * falta pasarlo.
15
+ */
16
+ export declare const useComponentsTranslation: (language?: string) => TFunction;
17
+ export default useComponentsTranslation;
@@ -1,3 +1,4 @@
1
1
  export * from './components';
2
+ export * from './asyncState';
2
3
  export { i18n } from './i18n';
3
4
  export * from './components/EventsDialog/theme';
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@trii/components",
3
- "version": "2.0.103",
3
+ "version": "3.0.0",
4
4
  "description": "Trii components package",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "files": [
9
- "dist"
9
+ "dist",
10
+ "async-state"
10
11
  ],
11
12
  "scripts": {
12
13
  "dev": "npm-run-all --parallel dev:types dev:js",
@@ -15,7 +16,8 @@
15
16
  "build": "npm-run-all --serial build:types build:js",
16
17
  "build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly",
17
18
  "build:js": "rollup -c",
18
- "test": "jest --watchAll --verbose",
19
+ "test": "jest",
20
+ "test:watch": "jest --watchAll --verbose",
19
21
  "storybook": "storybook dev -p 6006",
20
22
  "build-storybook": "storybook build"
21
23
  },