@abyss-project/commons-front-core 3.0.0 → 3.0.1

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 (119) hide show
  1. package/dist/{CookieConsentSettings.component-CgiQCgFX.js → CookieConsentSettings.component-BLgzLD-Z.js} +499 -443
  2. package/dist/components/Avatars/ProjectAvatar/ProjectAvatar.component.d.ts +3 -0
  3. package/dist/components/Avatars/UserAvatar/UserAvatar.component.d.ts +3 -0
  4. package/dist/components/Cards/ProjectCard/ProjectCard.component.d.ts +1 -0
  5. package/dist/components/CommandPalette/AbyssCommandPalette.d.ts +9 -0
  6. package/dist/components/CommandPalette/types.d.ts +63 -0
  7. package/dist/components/CommandPalette/useCommandPaletteHotkey.d.ts +9 -0
  8. package/dist/components/CookieConsent/AbyssCookieConsentProvider.d.ts +9 -0
  9. package/dist/components/CookieConsent/privacy-link.constant.d.ts +25 -0
  10. package/dist/components/Data/AbyssTable/AbyssTable.component.d.ts +16 -2
  11. package/dist/components/Data/AbyssTable/abyss-table.logic.d.ts +72 -0
  12. package/dist/components/Inputs/AbyssNumberField/AbyssNumberField.component.d.ts +18 -0
  13. package/dist/components/Inputs/AbyssNumberField/format.d.ts +28 -0
  14. package/dist/components/Inputs/CloudImport/CloudImport.component.d.ts +1 -0
  15. package/dist/components/Inputs/ColorPalette/ColorPalette.component.d.ts +2 -0
  16. package/dist/components/Inputs/ContextSelector/ContextSelector.component.d.ts +25 -0
  17. package/dist/components/Inputs/DatePeriodPicker/DatePeriodPicker.component.d.ts +32 -0
  18. package/dist/components/Inputs/DatePeriodPicker/date-period-picker.logic.d.ts +54 -0
  19. package/dist/components/Inputs/DatePeriodPicker/date-period-presets.util.d.ts +8 -0
  20. package/dist/components/Inputs/LanguageFlagLabel/LanguageFlagLabel.component.d.ts +13 -0
  21. package/dist/components/Inputs/LanguageFlagLabel/language-flags.d.ts +10 -0
  22. package/dist/components/Inputs/PasswordInput/PasswordInput.component.d.ts +16 -0
  23. package/dist/components/Inputs/ProjectLinkSelector/index.d.ts +1 -1
  24. package/dist/components/Layouts/AbyssBillingPlan/AbyssBillingPlan.component.d.ts +2 -0
  25. package/dist/components/Layouts/AbyssFamilyBanner/AbyssFamilyBanner.component.d.ts +12 -0
  26. package/dist/components/Layouts/AbyssLayoutProvider/index.d.ts +1 -1
  27. package/dist/components/Layouts/AbyssSidebar/index.d.ts +2 -2
  28. package/dist/components/Modals/AbyssModal/AbyssModal.component.d.ts +6 -0
  29. package/dist/components/Modals/QRCodeModal/QRCodeModal.component.d.ts +1 -0
  30. package/dist/components/Modals/UserSettingsModal/UserSettingsModal.component.d.ts +5 -0
  31. package/dist/components/Modals/UserSettingsModal/index.d.ts +1 -1
  32. package/dist/components/PdfEditor/hooks/use-pdf-document.d.ts +12 -0
  33. package/dist/components/PdfEditor/hooks/use-uploaded-docs.d.ts +9 -0
  34. package/dist/components/PdfEditor/operations/actions.d.ts +14 -0
  35. package/dist/components/PdfEditor/operations/compute-page-order.d.ts +11 -0
  36. package/dist/components/PdfEditor/operations/extract.d.ts +5 -0
  37. package/dist/components/PdfEditor/operations/pdf-data-url.d.ts +4 -0
  38. package/dist/components/PdfEditor/operations/rasterize.d.ts +17 -0
  39. package/dist/components/PdfEditor/operations/redact.d.ts +8 -0
  40. package/dist/components/PdfEditor/operations/rotate-coords.d.ts +25 -0
  41. package/dist/components/PdfEditor/signature/SignaturePicker.d.ts +3 -0
  42. package/dist/components/PdfEditor/signature/SignatureSaveButton.d.ts +3 -0
  43. package/dist/components/PdfEditor/signature/resolve-asset.d.ts +17 -0
  44. package/dist/components/PdfEditor/tools/RedactTool.d.ts +6 -0
  45. package/dist/components/PdfEditor/tools/Toolbar.d.ts +9 -0
  46. package/dist/components/PdfEditor/tools/tool-options-ui.d.ts +1 -0
  47. package/dist/components/PdfEditor/types.d.ts +85 -0
  48. package/dist/components/PdfEditor/viewer/PageOverlay.d.ts +10 -0
  49. package/dist/components/PdfEditor/viewer/PdfCanvas.d.ts +1 -0
  50. package/dist/components/PdfEditor/viewer/ViewerControls.d.ts +4 -0
  51. package/dist/components/QuotaGauge/AbyssQuotaGauge.component.d.ts +39 -0
  52. package/dist/components/QuotaGauge/bubble-placement.d.ts +40 -0
  53. package/dist/components/QuotaGauge/gauge-segments.d.ts +56 -0
  54. package/dist/components/QuotaOffer/AbyssQuotaOffer.component.d.ts +60 -0
  55. package/dist/components/QuotaOffer/quota-offer-state.d.ts +64 -0
  56. package/dist/components/QuotaReached/QuotaReachedDialog.component.d.ts +10 -0
  57. package/dist/components/QuotaReached/billing-quota-error.d.ts +7 -0
  58. package/dist/components/QuotaReached/quota-dialog.store.d.ts +10 -0
  59. package/dist/components/QuotaReached/quota-service-meta.d.ts +4 -0
  60. package/dist/components/Support/SupportCategorySelect.component.d.ts +3 -0
  61. package/dist/components/Support/SupportStatusTimeline.component.d.ts +2 -0
  62. package/dist/components/Support/index.d.ts +2 -2
  63. package/dist/components/Support/support-attachment.logic.d.ts +10 -0
  64. package/dist/components/Support/support-author.logic.d.ts +9 -0
  65. package/dist/components/Support/support-create-stepper.logic.d.ts +13 -0
  66. package/dist/components/Support/support-message-input.logic.d.ts +8 -0
  67. package/dist/components/Support/support-status-timeline.logic.d.ts +16 -0
  68. package/dist/components/Support/types.d.ts +55 -0
  69. package/dist/components/Utils/AbyssBackground/AbyssBackground.component.d.ts +3 -0
  70. package/dist/components/Utils/AbyssFamilyMenuSection/AbyssFamilyMenuSection.d.ts +9 -0
  71. package/dist/components/Utils/AbyssLayoutMenu/index.d.ts +1 -1
  72. package/dist/components/Utils/AbyssLayoutNotifications/AbyssLayoutNotifications.component.d.ts +4 -0
  73. package/dist/components/Utils/AbyssLayoutNotifications/index.d.ts +1 -1
  74. package/dist/components/Utils/ImportButton/ImportButton.component.d.ts +4 -0
  75. package/dist/components/Utils/Toast/AbyssToast.component.d.ts +6 -0
  76. package/dist/components/Utils/WaterParticles/WaterParticles.component.d.ts +8 -0
  77. package/dist/cookie-consent.js +1 -1
  78. package/dist/hooks/use-public-users.hook.d.ts +39 -0
  79. package/dist/hooks/use-rich-intl.hook.d.ts +13 -5
  80. package/dist/hooks/use-theme-transition.hook.d.ts +13 -0
  81. package/dist/{index-CXNLGqpN.js → index-13QCr6ei.js} +1 -1
  82. package/dist/{index-0WPkkm3C.js → index-B4s0xpO9.js} +3 -3
  83. package/dist/{index-DXDfaFmT.js → index-BBH7n9Up.js} +4 -4
  84. package/dist/{index-DQgswKg1.js → index-BI7XXRdP.js} +3 -3
  85. package/dist/{index-BqjTmumL.js → index-BbuvDSp0.js} +2 -2
  86. package/dist/{index-D2ot8DZ4.js → index-Bhok95RO.js} +2 -2
  87. package/dist/{index-FF8J68dM.js → index-BjbDo-BN.js} +14320 -11454
  88. package/dist/{index-Ctm2mN4b.js → index-C2iksP8T.js} +2 -2
  89. package/dist/{index-CgqzFzYH.js → index-CKXa4BvM.js} +2 -2
  90. package/dist/{index-B9n8aGer.js → index-Ci9slz4U.js} +2 -2
  91. package/dist/{index-BSa7pbNq.js → index-CoGr-vvT.js} +3 -3
  92. package/dist/{index-C1NWZqnA.js → index-Cw4n4Q97.js} +2 -2
  93. package/dist/{index-d9VwJ6nR.js → index-DKSA-U8A.js} +2 -2
  94. package/dist/{index-CAqpnDEx.js → index-DQ6hF6bv.js} +4 -4
  95. package/dist/{index-D5IIOkfu.js → index-DVDFaXUS.js} +2 -2
  96. package/dist/{index-DpeaEf87.js → index-Dfs8HrMj.js} +2 -2
  97. package/dist/{index-2gSMCEyX.js → index-Dn5fa9DE.js} +3 -3
  98. package/dist/{index-CdpydxgB.js → index-DqW8ipJ0.js} +2 -2
  99. package/dist/{index-C7bGgD6e.js → index-Dt86SHUY.js} +2 -2
  100. package/dist/{index-BN-71mBQ.js → index-DucVTPTi.js} +2 -2
  101. package/dist/{index-C02uLNDS.js → index-TJMhsU_S.js} +2 -2
  102. package/dist/{index-cYFrJDdQ.js → index-x_CknZJ4.js} +4 -4
  103. package/dist/index.js +2 -2
  104. package/dist/theme/augmentation.d.ts +6 -0
  105. package/dist/theme/index.d.ts +11 -4
  106. package/dist/theme/palettes/common.d.ts +13 -0
  107. package/dist/theme/palettes/dark.d.ts +1 -0
  108. package/dist/theme/palettes/light.d.ts +1 -0
  109. package/dist/theme/tokens/animations.d.ts +3 -0
  110. package/dist/theme/tokens/borders.d.ts +3 -0
  111. package/dist/theme/tokens/colors.d.ts +27 -0
  112. package/dist/theme/tokens/shadows.d.ts +8 -0
  113. package/dist/theme/tokens/transitions.d.ts +4 -0
  114. package/dist/theme/tokens/typography.d.ts +6 -0
  115. package/dist/utils/share-notification.utils.d.ts +9 -0
  116. package/dist/utils/space-display-name.utils.d.ts +8 -0
  117. package/package.json +14 -13
  118. package/tsconfig.json +26 -25
  119. package/vite.config.ts +1 -17
@@ -18,8 +18,11 @@ type Props = {
18
18
  cache?: string;
19
19
  sx?: SxProps;
20
20
  getProjectPictureUrl: (projectId: string) => string;
21
+ /** Enable project info popup on click */
21
22
  showProfile?: boolean;
23
+ /** Project info to display in popup */
22
24
  profileInfo?: ProjectAvatarProfileInfo;
25
+ /** Callback when avatar is clicked */
23
26
  onClick?: () => void;
24
27
  };
25
28
  declare const ProjectAvatar: FC<Props>;
@@ -14,8 +14,11 @@ type Props = {
14
14
  cache?: string;
15
15
  sx?: SxProps;
16
16
  getProfilePictureUrl: (userId: string) => string;
17
+ /** Enable profile popup on click */
17
18
  showProfile?: boolean;
19
+ /** Profile info to display in popup */
18
20
  profileInfo?: UserAvatarProfileInfo;
21
+ /** Callback when avatar is clicked (even without popup) */
19
22
  onClick?: () => void;
20
23
  };
21
24
  declare const UserAvatar: FC<Props>;
@@ -21,6 +21,7 @@ type Props = {
21
21
  followingTooltip?: string;
22
22
  formatLanguage?: (language: string) => string;
23
23
  formatNumber?: (n: number) => string;
24
+ /** 'compact' reduces banner height and hides some details */
24
25
  variant?: 'default' | 'compact';
25
26
  };
26
27
  declare const ProjectCard: React.FC<Props>;
@@ -1,3 +1,12 @@
1
1
  import { FC } from 'react';
2
2
  import { AbyssCommandPaletteProps } from './types';
3
+ /**
4
+ * Presentational, fully-controlled command palette shell shared by every
5
+ * Abyss host app. It owns the MUI `Dialog`, the search input, the grouped
6
+ * result rendering, and the keyboard/mouse selection model — nothing else.
7
+ *
8
+ * It NEVER fetches, filters or scores: `groups` must already be
9
+ * filtered/scored/ordered by the host. See the folder README for the two
10
+ * supported host modes (client-side filtered vs server-side searched).
11
+ */
3
12
  export declare const AbyssCommandPalette: FC<AbyssCommandPaletteProps>;
@@ -1,22 +1,61 @@
1
1
  import { ElementType, ReactNode } from 'react';
2
2
  import { DialogProps } from '@mui/material';
3
3
  import { SxProps, Theme } from '@mui/material/styles';
4
+ /**
5
+ * A single selectable row in the palette. The host is fully responsible for
6
+ * building this shape (icon/avatar node, trailing status chip, etc.) — the
7
+ * shell only renders what it is given.
8
+ */
4
9
  export interface AbyssCommandPaletteItem {
5
10
  id: string;
6
11
  title: string;
7
12
  subtitle?: string;
13
+ /** Host-supplied icon or avatar node (e.g. `<UserAvatar />`, an MUI icon). */
8
14
  icon?: ReactNode;
15
+ /** Host-supplied trailing node (e.g. a status `<Chip />`). */
9
16
  trailing?: ReactNode;
17
+ /**
18
+ * Navigation target for this row. When set AND the palette receives a
19
+ * `linkComponent`, the row renders as a real anchor, which preserves native
20
+ * browser affordances (ctrl/cmd-click and middle-click open in a new tab).
21
+ * A plain click still goes through `onSelect`, so hosts keep full control of
22
+ * side effects (recents, analytics…). Rows without `href` (imperative
23
+ * commands such as a theme toggle) render as buttons.
24
+ */
10
25
  href?: string;
11
26
  }
27
+ /**
28
+ * A section of already-filtered, already-ordered items with an
29
+ * already-translated label. The shell never reorders or drops items from a
30
+ * group — it only skips rendering a section header for a group with zero
31
+ * items.
32
+ */
12
33
  export interface AbyssCommandPaletteGroup {
13
34
  key: string;
35
+ /** Already translated by the host. */
14
36
  label: string;
15
37
  items: AbyssCommandPaletteItem[];
16
38
  }
39
+ /**
40
+ * Visual treatment of the currently-highlighted row.
41
+ * - `'filled'` (default): a solid tinted background on the selected row.
42
+ * This is the original/admin look — unchanged.
43
+ * - `'accent'`: a left accent bar + accent-coloured label (and, via normal
44
+ * CSS color inheritance, any host icon using `color="inherit"`), with only
45
+ * a faint background tint. This is the original front look.
46
+ */
17
47
  export type AbyssCommandPaletteHighlightVariant = 'filled' | 'accent';
48
+ /**
49
+ * How a row was selected. Hosts that render rows as anchors (`href` +
50
+ * `linkComponent`) MUST check `viaAnchor` before navigating themselves:
51
+ * when it is `true` the router link already handles the navigation, so
52
+ * navigating again would push a duplicate history entry — and, on a
53
+ * ctrl/cmd-click, would hijack the current tab instead of letting the
54
+ * browser open a new one.
55
+ */
18
56
  export interface AbyssCommandPaletteSelectMeta {
19
57
  source: 'click' | 'keyboard';
58
+ /** The row rendered as an anchor AND the browser/router is handling this navigation. */
20
59
  viaAnchor: boolean;
21
60
  }
22
61
  export interface AbyssCommandPaletteProps {
@@ -24,18 +63,42 @@ export interface AbyssCommandPaletteProps {
24
63
  onClose: () => void;
25
64
  query: string;
26
65
  onQueryChange: (query: string) => void;
66
+ /** Already filtered/scored/ordered by the host — the shell never filters or scores. */
27
67
  groups: AbyssCommandPaletteGroup[];
28
68
  onSelect: (item: AbyssCommandPaletteItem, groupKey: string, meta: AbyssCommandPaletteSelectMeta) => void;
69
+ /** Host is fetching/searching. Drives the subtle loading indicator. */
29
70
  isLoading?: boolean;
71
+ /** Already translated by the host. */
30
72
  placeholder: string;
73
+ /** Already translated by the host. Shown when there are no items to display and not loading. */
31
74
  emptyLabel: string;
75
+ /** Already translated by the host. Shown alongside the loading indicator while there is nothing to display yet. */
32
76
  loadingLabel?: string;
77
+ /** Already translated by the host (e.g. keyboard-shortcut hints). */
33
78
  footerHints?: ReactNode;
79
+ /** Max height of the scrollable results area. Defaults to 420. */
34
80
  maxHeight?: number | string;
81
+ /** Host-supplied node rendered right-aligned inside the input row, next to the search field (e.g. an "ESC" hint badge). Omit for none. */
35
82
  inputTrailing?: ReactNode;
83
+ /** Highlighted-row visual treatment. Defaults to `'filled'` (unchanged existing look). */
36
84
  highlightVariant?: AbyssCommandPaletteHighlightVariant;
85
+ /**
86
+ * Router link component (e.g. react-router's `Link`) used to render rows that
87
+ * carry an `href` as real anchors, so ctrl/cmd-click and middle-click open a
88
+ * new tab. Omit it and every row renders as a button (no anchor semantics).
89
+ * The component receives the row's `href` as its `to` prop.
90
+ */
37
91
  linkComponent?: ElementType;
92
+ /** Render the dialog full-screen (hosts typically bind this to a mobile breakpoint). */
38
93
  fullScreen?: boolean;
94
+ /**
95
+ * Styling escape hatch for the dialog surface. When provided it REPLACES the
96
+ * shell's default paper styling (vertical offset, radius, overflow), so a
97
+ * host owns its chrome outright — border, gradient, shadow, offset — without
98
+ * fighting responsive defaults it did not ask for. The shell keeps owning
99
+ * behaviour either way.
100
+ */
39
101
  paperSx?: SxProps<Theme>;
102
+ /** Passthrough to the underlying MUI Dialog slots (e.g. a custom backdrop). */
40
103
  slotProps?: DialogProps['slotProps'];
41
104
  }
@@ -1 +1,10 @@
1
+ /**
2
+ * Opens the command palette on Cmd+K (macOS) / Ctrl+K (Windows/Linux).
3
+ * Store-agnostic: the host supplies `onOpen` (e.g. a zustand store action or
4
+ * local `setState`) so this hook has no opinion on where "open" state lives.
5
+ * Hand-written listener — no cmdk/kbar dependency.
6
+ *
7
+ * @param onOpen Called when the hotkey is pressed.
8
+ * @param enabled When `false`, the listener is not attached at all. Defaults to `true`.
9
+ */
1
10
  export declare const useCommandPaletteHotkey: (onOpen: () => void, enabled?: boolean) => void;
@@ -6,6 +6,15 @@ export interface AbyssCookieConsentProviderProps {
6
6
  consentVersion: string;
7
7
  isAuthenticated: boolean;
8
8
  domain?: string;
9
+ /**
10
+ * NO `privacyLinkHref`. The banner's link is the SAME for every app in the estate by
11
+ * definition, so it belongs to this component and not to its callers.
12
+ *
13
+ * It used to be overridable, and every single caller overrode it with the same relative path,
14
+ * `/legal/privacy` — resolved against its own domain. Seven of the eight served a 404 behind
15
+ * their cookie banner. The prop had exactly one observed use, and it was the bug; removing it
16
+ * is what makes the mistake impossible rather than merely fixed.
17
+ */
9
18
  renderBanner?: (api: UseCookieConsent) => React.ReactNode;
10
19
  }
11
20
  export declare const AbyssCookieConsentProvider: React.FC<AbyssCookieConsentProviderProps>;
@@ -1 +1,26 @@
1
+ /**
2
+ * WHERE THE COOKIE BANNER'S "LEARN MORE" LINK POINTS, FOR THE WHOLE ESTATE.
3
+ *
4
+ * ═══ WHY THIS IS A LEAF FILE ═══
5
+ *
6
+ * It imports nothing. A URL that every app depends on must be readable — and testable — without
7
+ * dragging the provider, the consent hook and the whole `@abyss-project/main` SDK behind it.
8
+ *
9
+ * ═══ WHAT IT REPLACED ═══
10
+ *
11
+ * `https://abyss-project.fr/legal/privacy` — a path the marketing site has never served. Every
12
+ * app that fell back to it, and the four that passed the same path RELATIVE to their own domain,
13
+ * offered a 404 behind a cookie banner.
14
+ *
15
+ * `/cgu` is where the estate actually states what it does with personal data (the
16
+ * « Confidentialité » article, mobile section included). The marketing site's middleware adds the
17
+ * locale itself (`/cgu` → `/fr/cgu`), so there is no language to resolve here.
18
+ *
19
+ * ⚠️ There is no standalone privacy policy anywhere in the estate. The banner's link is labelled
20
+ * « En savoir plus » / "Learn more" and asserts nothing more than that, but a dedicated policy is
21
+ * the thing to write — and when it exists, this constant is the single place to repoint.
22
+ *
23
+ * This is a DEFAULT, not a suggestion: a consuming app has no reason to pass `privacyLinkHref`.
24
+ * Each one that did pointed at its own domain, which is how four satellites came to serve a 404.
25
+ */
1
26
  export declare const DEFAULT_PRIVACY_HREF = "https://abyss-project.fr/cgu";
@@ -1,6 +1,6 @@
1
1
  import { SxProps } from '@mui/material';
2
2
  import { ColumnDef, SortingState } from '@tanstack/react-table';
3
- import { default as React, ReactNode } from 'react';
3
+ import { ReactNode } from 'react';
4
4
  export type AbyssTableFilterDef = {
5
5
  columnId: string;
6
6
  label: string;
@@ -15,8 +15,16 @@ export type AbyssTableProps<TData extends object> = {
15
15
  enablePagination?: boolean;
16
16
  defaultPageSize?: number;
17
17
  pageSizeOptions?: number[];
18
+ /**
19
+ * Server-side (manual) sorting: the table reports the sort instead of applying it.
20
+ *
21
+ * Without this, a table in `manualPagination` sorts the rows it holds — one page — against
22
+ * nothing, which reads as broken. See the README's gotcha section.
23
+ */
18
24
  manualSorting?: boolean;
25
+ /** Host-controlled sort. Only honoured under `manualSorting`. */
19
26
  sorting?: SortingState;
27
+ /** Called with the next sort when the reader clicks a column header. */
20
28
  onSortingChange?: (next: SortingState) => void;
21
29
  manualPagination?: boolean;
22
30
  pageCount?: number;
@@ -25,9 +33,15 @@ export type AbyssTableProps<TData extends object> = {
25
33
  onPageChange?: (page: number) => void;
26
34
  onPageSizeChange?: (pageSize: number) => void;
27
35
  filters?: AbyssTableFilterDef[];
36
+ /** Controlled server-side search. When provided, the toolbar search box reports
37
+ * debounced changes to the host instead of filtering client-side. */
28
38
  onSearchChange?: (value: string) => void;
39
+ /** Current search text when the host owns the search state. */
29
40
  searchValue?: string;
41
+ /** Placeholder for the search box; falls back to the existing i18n `table.search`. */
30
42
  searchPlaceholder?: string;
43
+ /** Debounce applied before calling `onSearchChange`. Defaults to 400ms (the
44
+ * value the admin's local table wrapper used). */
31
45
  searchDebounceMs?: number;
32
46
  emptyMessage?: string;
33
47
  emptyContent?: ReactNode;
@@ -38,5 +52,5 @@ export type AbyssTableProps<TData extends object> = {
38
52
  isLoading?: boolean;
39
53
  renderAboveTable?: ReactNode;
40
54
  };
41
- declare function AbyssTable<TData extends object>({ data, columns, enableGlobalFilter, enableColumnFilters, enableSorting, manualSorting, sorting: externalSorting, onSortingChange, enablePagination, defaultPageSize, pageSizeOptions, manualPagination, pageCount: externalPageCount, totalItems: externalTotalItems, currentPage: externalCurrentPage, onPageChange, onPageSizeChange, filters, onSearchChange, searchValue, searchPlaceholder, searchDebounceMs, emptyMessage, emptyContent, onRowClick, sx, tableLabel, getRowSx, isLoading, renderAboveTable, }: AbyssTableProps<TData>): React.JSX.Element;
55
+ declare function AbyssTable<TData extends object>({ data, columns, enableGlobalFilter, enableColumnFilters, enableSorting, manualSorting, sorting: externalSorting, onSortingChange, enablePagination, defaultPageSize, pageSizeOptions, manualPagination, pageCount: externalPageCount, totalItems: externalTotalItems, currentPage: externalCurrentPage, onPageChange, onPageSizeChange, filters, onSearchChange, searchValue, searchPlaceholder, searchDebounceMs, emptyMessage, emptyContent, onRowClick, sx, tableLabel, getRowSx, isLoading, renderAboveTable, }: AbyssTableProps<TData>): import("react/jsx-runtime").JSX.Element;
42
56
  export default AbyssTable;
@@ -1,26 +1,98 @@
1
+ /**
2
+ * Pure, dependency-free helpers backing AbyssTable's pagination and search
3
+ * behaviour. Kept free of React/MUI so they can be spec'd directly (commons
4
+ * has no jsdom/testing-library — all logic modules are pure-function specs).
5
+ */
1
6
  export interface ResolvePageIndexParams {
7
+ /** Whether the table is in server-side (manual) pagination mode. */
2
8
  manualPagination: boolean;
9
+ /** Host-controlled page index (0-based), when the host owns pagination. */
3
10
  externalCurrentPage?: number;
11
+ /** The table's own internal pagination state (0-based). */
4
12
  internalPageIndex: number;
5
13
  }
14
+ /**
15
+ * Resolves the page index AbyssTable renders, mirroring the component's
16
+ * existing precedence exactly:
17
+ * - manual pagination + a host-provided `currentPage` -> the host value wins.
18
+ * - manual pagination without a host-provided `currentPage` -> falls back to
19
+ * the internal pagination state.
20
+ * - non-manual (client-side) pagination -> always uses the internal state,
21
+ * regardless of `externalCurrentPage`.
22
+ */
6
23
  export declare function resolvePageIndex({ manualPagination, externalCurrentPage, internalPageIndex, }: ResolvePageIndexParams): number;
24
+ /**
25
+ * Whether the toolbar search box should operate as a controlled, debounced,
26
+ * server-side search (reporting to the host via `onSearchChange`) instead of
27
+ * AbyssTable's default client-side global filtering.
28
+ */
7
29
  export declare function shouldUseServerSearch(onSearchChange?: (value: string) => void): boolean;
30
+ /**
31
+ * Resolves the placeholder text shown in the toolbar search box: an explicit
32
+ * `searchPlaceholder` prop wins, otherwise the caller's fallback (the
33
+ * component's existing i18n `table.search` message) is used.
34
+ */
8
35
  export declare function resolveSearchPlaceholder(searchPlaceholder: string | undefined, fallback: string): string;
36
+ /** One column's sort direction, mirroring `@tanstack/react-table`'s `SortingState` entry. */
9
37
  export interface SortingEntry {
10
38
  id: string;
11
39
  desc: boolean;
12
40
  }
13
41
  export interface ResolveSortingStateParams {
42
+ /** Whether the host owns the sort and applies it itself (server-side). */
14
43
  manualSorting: boolean;
44
+ /** Host-controlled sort, when the host owns it. */
15
45
  externalSorting?: SortingEntry[];
46
+ /** The table's own internal sorting state. */
16
47
  internalSorting: SortingEntry[];
17
48
  }
49
+ /**
50
+ * Resolves the sorting state AbyssTable renders its header affordance from.
51
+ *
52
+ * The precedence mirrors `resolvePageIndex`, and for the same reason: a host that owns the sort must
53
+ * see the arrow it asked for, not one the table decided on its own. A host in manual mode that
54
+ * passes no `sorting` still gets a working header — it just has nothing to restore on a reload.
55
+ *
56
+ * Client-side sorting ignores `externalSorting` entirely, so a host cannot half-control the sort and
57
+ * end up with a header that disagrees with the rows underneath it.
58
+ */
18
59
  export declare function resolveSortingState({ manualSorting, externalSorting, internalSorting, }: ResolveSortingStateParams): SortingEntry[];
60
+ /**
61
+ * Whether the table must build a sorted row model of its own.
62
+ *
63
+ * Never under `manualSorting`: the rows it holds are one page of a result set the server already
64
+ * ordered, and re-sorting them locally reorders that page against the rest — the failure the
65
+ * README's gotcha describes, arrived at from the other direction.
66
+ */
19
67
  export declare function shouldSortRowsLocally(enableSorting: boolean, manualSorting: boolean): boolean;
68
+ /**
69
+ * Whether a column header offers a sort affordance.
70
+ *
71
+ * Client-side, the answer is TanStack's: a column with no accessor has no value to compare, so it
72
+ * cannot be sorted and `getCanSort()` says so.
73
+ *
74
+ * Under `manualSorting` that reasoning does not apply. The server does the ordering; the column only
75
+ * has to name itself. Display-only columns — a cell built from several fields, a chip, an avatar —
76
+ * are exactly the ones a host wants sortable server-side, and deferring to `getCanSort()` would make
77
+ * the whole manual-sorting API silently do nothing on them.
78
+ */
20
79
  export declare function isColumnSortable(params: {
21
80
  enableSorting: boolean;
22
81
  manualSorting: boolean;
82
+ /** The column's own `enableSorting`, `undefined` when it does not say. */
23
83
  columnEnableSorting: boolean | undefined;
84
+ /** What TanStack answers for client-side sorting. */
24
85
  canSortClientSide: boolean;
25
86
  }): boolean;
87
+ /**
88
+ * The next sort after a click on a column header, under `manualSorting`.
89
+ *
90
+ * TanStack's own toggle handler is not usable here: it no-ops on a column it considers unsortable,
91
+ * which under manual sorting is every display-only column — the ones a host most wants ordered by
92
+ * the server.
93
+ *
94
+ * The cycle is ascending, then descending, then nothing. Three states rather than two because
95
+ * "nothing" is a real answer: it is how a reader goes back to the list's own default order, and a
96
+ * two-state toggle would trap them between two orders they may not want either of.
97
+ */
26
98
  export declare function nextManualSorting(current: SortingEntry[], columnId: string): SortingEntry[];
@@ -1,16 +1,34 @@
1
1
  import { TextFieldProps } from '@mui/material';
2
2
  import { FC } from 'react';
3
3
  export type AbyssNumberFieldProps = Omit<TextFieldProps, 'value' | 'onChange'> & {
4
+ /** The numeric value */
4
5
  value: number | null;
6
+ /** Called with the raw number on change */
5
7
  onChange: (value: number | null) => void;
8
+ /** Format mode */
6
9
  mode?: 'number' | 'currency';
10
+ /** Currency symbol (default: '€') */
7
11
  currencySymbol?: string;
12
+ /** Currency position */
8
13
  currencyPosition?: 'start' | 'end';
14
+ /**
15
+ * BCP-47 locale for formatting. Defaults to the active IntlProvider locale,
16
+ * so the decimal separator follows the app language (fr -> "50,00", en ->
17
+ * "50.00"). Only override to force a specific locale.
18
+ */
9
19
  locale?: string;
20
+ /** Decimal places (default: 0 for number, 2 for currency) */
10
21
  decimals?: number;
22
+ /**
23
+ * Thousands separator. Defaults to the active locale's grouping separator;
24
+ * pass to override.
25
+ */
11
26
  thousandSeparator?: string;
27
+ /** Min value */
12
28
  min?: number;
29
+ /** Max value */
13
30
  max?: number;
31
+ /** Allow negative */
14
32
  allowNegative?: boolean;
15
33
  };
16
34
  declare const AbyssNumberField: FC<AbyssNumberFieldProps>;
@@ -1,7 +1,35 @@
1
+ /**
2
+ * Locale-aware number formatting/parsing helpers for {@link AbyssNumberField}.
3
+ *
4
+ * The decimal and grouping separators are derived from the ACTIVE locale
5
+ * (fr-FR -> "," decimal, en-* -> "." decimal) and are never hardcoded, so a
6
+ * currency value like 50 renders as "50,00 €" in French and "50.00" in English.
7
+ * Parsing is intentionally forgiving: a user typing "50,00" or "50" both
8
+ * round-trip to the numeric 50 that flows back out through onChange.
9
+ */
1
10
  export interface LocaleSeparators {
11
+ /** Thousands / grouping separator (fr-FR: narrow no-break space, en-US: ","). */
2
12
  group: string;
13
+ /** Decimal separator (fr-FR: ",", en-US: "."). */
3
14
  decimal: string;
4
15
  }
16
+ /**
17
+ * Resolve the grouping and decimal separators used by the given BCP-47 locale
18
+ * by inspecting `Intl.NumberFormat` output. Falls back to space/dot if the
19
+ * locale is unknown or Intl throws.
20
+ */
5
21
  export declare function getLocaleSeparators(locale: string): LocaleSeparators;
22
+ /**
23
+ * Format a numeric value for display using the provided locale separators.
24
+ * Returns an empty string for null/undefined/NaN.
25
+ */
6
26
  export declare function formatNumberValue(value: number | null | undefined, decimals: number, separators: LocaleSeparators): string;
27
+ /**
28
+ * Parse a user-typed string back into a number.
29
+ *
30
+ * Grouping separators (the locale's own group char plus common whitespace
31
+ * variants) are stripped first, then either "," or "." is accepted as the
32
+ * decimal marker so that fr comma-input and en dot-input both yield the same
33
+ * numeric value. Returns null for empty / non-numeric input.
34
+ */
7
35
  export declare function parseNumberInput(raw: string | null | undefined, separators: LocaleSeparators): number | null;
@@ -23,6 +23,7 @@ type Props = {
23
23
  fetchCloudRepository: (cloudId: string) => Promise<IGetRepositoryCloudData>;
24
24
  onActivateService: () => Promise<void>;
25
25
  onCreateCloud: (name: string) => Promise<void>;
26
+ /** Host-supplied resolver: avatar + label for any space. */
26
27
  getSpaceDisplay?: (space: ISpace) => CloudImportSpaceDisplay;
27
28
  };
28
29
  declare const CloudImport: React.FC<Props>;
@@ -14,6 +14,8 @@ type Props = {
14
14
  size?: ColorPaletteSize | number;
15
15
  shape?: ColorPaletteShape;
16
16
  showCustomPicker?: boolean;
17
+ /** Tooltip for the custom-color button. Pass an i18n string from the host
18
+ * (defaults to French for legacy callers). */
17
19
  customTooltip?: string;
18
20
  sx?: SxProps;
19
21
  };
@@ -1,23 +1,35 @@
1
1
  import { default as React } from 'react';
2
+ /** A project that belongs to an organization. */
2
3
  export type ContextSelectorProject = {
3
4
  id: string;
4
5
  name: string;
6
+ /** Optional custom avatar (e.g. a `ProjectAvatar`). Falls back to an icon. */
5
7
  avatar?: React.ReactNode;
6
8
  };
9
+ /** An organization the user belongs to, with its projects. */
7
10
  export type ContextSelectorOrganization = {
8
11
  id: string;
9
12
  name: string;
13
+ /** Optional custom avatar (e.g. an `OrganizationAvatar`). Falls back to an icon. */
10
14
  avatar?: React.ReactNode;
11
15
  projects?: ContextSelectorProject[];
12
16
  };
17
+ /** The personal ("Mon Espace") scope entry. */
13
18
  export type ContextSelectorPersonal = {
19
+ /** Display label (e.g. the user's alias). Falls back to the i18n "Mon Espace". */
14
20
  label?: string;
21
+ /** Optional custom avatar (e.g. a `UserAvatar`). Falls back to an icon. */
15
22
  avatar?: React.ReactNode;
16
23
  };
24
+ /** Full data shape: the personal scope plus the user's organizations. */
17
25
  export type ContextSelectorData = {
18
26
  personal: ContextSelectorPersonal;
19
27
  organizations: ContextSelectorOrganization[];
20
28
  };
29
+ /**
30
+ * The currently-selected context. A discriminated union mirroring the
31
+ * personal / organization / project scope used across the apps.
32
+ */
21
33
  export type ContextValue = {
22
34
  kind: 'personal';
23
35
  } | {
@@ -28,15 +40,28 @@ export type ContextValue = {
28
40
  organizationId: string;
29
41
  projectId: string;
30
42
  };
43
+ /**
44
+ * - `grouped`: three flat headers — "Mon Espace", "Organisation", "Projets".
45
+ * - `by-org`: "Mon Espace" first, then one group per organization (by name),
46
+ * each containing an "Organisation" entry + that org's projects.
47
+ */
31
48
  export type ContextSelectorVariant = 'grouped' | 'by-org';
32
49
  type ContextSelectorProps = {
50
+ /** Personal + organizations (each with their projects). */
33
51
  data: ContextSelectorData;
52
+ /** The currently-selected context. */
34
53
  value: ContextValue;
54
+ /** Fires with the new context when the user picks an option. */
35
55
  onChange: (next: ContextValue) => void;
56
+ /** Layout of the option list. Defaults to `grouped`. */
36
57
  variant?: ContextSelectorVariant;
58
+ /** Optional field label rendered by the inner `TextField`. */
37
59
  label?: string;
60
+ /** Optional placeholder for the inner `TextField`. */
38
61
  placeholder?: string;
62
+ /** Disables the whole control. */
39
63
  disabled?: boolean;
64
+ /** Min width of the control. Defaults to 240px. */
40
65
  minWidth?: number | string;
41
66
  };
42
67
  export declare const ContextSelector: React.FC<ContextSelectorProps>;
@@ -4,23 +4,55 @@ import { DatePeriodGranularity } from './date-period-picker.logic';
4
4
  import { DatePeriodPreset } from './date-period-presets.util';
5
5
  export type { DatePeriodGranularity } from './date-period-picker.logic';
6
6
  export type { DatePeriodPreset } from './date-period-presets.util';
7
+ /**
8
+ * Layout variant. `segmented` renders a single segmented control with a sliding
9
+ * thumb; the other values render the layouts they name. All six are supported —
10
+ * pick the one that fits the surface.
11
+ */
7
12
  export type DatePeriodVariant = 'default' | 'compact' | 'inline' | 'presets-only' | 'presets-bar' | 'segmented';
8
13
  export type DatePeriodPickerProps = {
9
14
  startDate: Date | null;
10
15
  endDate: Date | null;
11
16
  onStartDateChange: (date: Date | null) => void;
12
17
  onEndDateChange: (date: Date | null) => void;
18
+ /** Called when both dates change at once (e.g. preset click). Avoids stale-closure issues. */
13
19
  onRangeChange?: (start: Date | null, end: Date | null) => void;
20
+ /** Layout variant. @default 'default' */
14
21
  variant?: DatePeriodVariant;
22
+ /**
23
+ * Time granularity of the resolved range.
24
+ * - `'day'` (default): presets and custom ranges snap to `startOfDay` /
25
+ * `endOfDay` (day-only picker, fully backward-compatible).
26
+ * - `'minute'`: the custom-range popover exposes hour/minute fields and the
27
+ * resolved range keeps the exact selected date + time (no start/end-of-day
28
+ * snapping). When a calendar day is picked the currently entered time is
29
+ * kept (defaulting to 00:00 for start / 23:59 for end).
30
+ *
31
+ * @default 'day'
32
+ */
15
33
  granularity?: DatePeriodGranularity;
34
+ /** Custom presets. If not provided, defaults are used */
16
35
  presets?: DatePeriodPreset[];
36
+ /** Hide preset chips */
17
37
  hidePresets?: boolean;
38
+ /** Min selectable date */
18
39
  minDate?: Date;
40
+ /** Max selectable date */
19
41
  maxDate?: Date;
42
+ /** Override labels (defaults to translations) */
20
43
  startLabel?: string;
21
44
  endLabel?: string;
45
+ /** Hide the date range summary text below the picker */
22
46
  hideSummary?: boolean;
47
+ /** Override label for the Custom date button (presets-bar + segmented variants) */
23
48
  customLabel?: string;
49
+ /**
50
+ * Explicit date-fns locale used for every `format(...)` call and the picker
51
+ * calendar. The commons bundle ships its own date-fns copy, so the host's
52
+ * global `setDefaultOptions({ locale })` never reaches it — the locale must be
53
+ * passed explicitly. When omitted, the locale is resolved from the active
54
+ * react-intl language (`intl.locale`), defaulting to English.
55
+ */
24
56
  locale?: Locale;
25
57
  };
26
58
  declare const DatePeriodPicker: React.FC<DatePeriodPickerProps>;
@@ -1,25 +1,79 @@
1
1
  import { Locale } from 'date-fns';
2
2
  export type EditingBound = 'start' | 'end';
3
+ /**
4
+ * Time granularity of the resolved range.
5
+ *
6
+ * - `day` (default): bounds snap to start-of-day (start) / end-of-day (end). The
7
+ * picker behaves as a day-only range picker — fully backward-compatible.
8
+ * - `minute`: bounds keep an explicit hour/minute and resolve to the exact
9
+ * selected instant (no start/end-of-day snapping).
10
+ */
3
11
  export type DatePeriodGranularity = 'day' | 'minute';
4
12
  export type RangeUpdateInput = {
13
+ /** Which bound the user is currently editing. */
5
14
  editing: EditingBound;
15
+ /** The day the user just picked in the calendar. */
6
16
  picked: Date;
17
+ /** Current start bound (may be null/invalid). */
7
18
  startDate: Date | null;
19
+ /** Current end bound (may be null/invalid). */
8
20
  endDate: Date | null;
21
+ /**
22
+ * Time granularity. Defaults to `day` (snap to start/end of day). In `minute`
23
+ * mode the previously entered time is preserved when only the calendar day
24
+ * changes.
25
+ */
9
26
  granularity?: DatePeriodGranularity;
10
27
  };
11
28
  export type RangeUpdateResult = {
29
+ /** New start bound, or the previous reference when unchanged. */
12
30
  start: Date | null;
31
+ /** New end bound, or the previous reference when unchanged. */
13
32
  end: Date | null;
33
+ /** Whether the start reference changed. */
14
34
  startChanged: boolean;
35
+ /** Whether the end reference changed. */
15
36
  endChanged: boolean;
16
37
  };
17
38
  export type TimeChangeInput = {
39
+ /** Which bound the user is currently editing. */
18
40
  editing: EditingBound;
41
+ /** The value emitted by the time field (carries the new hour/minute). */
19
42
  time: Date;
43
+ /** Current start bound (may be null/invalid). */
20
44
  startDate: Date | null;
45
+ /** Current end bound (may be null/invalid). */
21
46
  endDate: Date | null;
22
47
  };
48
+ /**
49
+ * Pure, independent range-bound update for a calendar day pick.
50
+ *
51
+ * Each bound is edited independently: editing the END never moves the START and
52
+ * vice-versa (fixes the "changing end also moves start" regression). The only
53
+ * coupling is a validation clamp guaranteeing `end >= start`:
54
+ * - editing `start` past `end` clamps the start down to `end` (end untouched);
55
+ * - editing `end` before `start` clamps the end up to `start` (start untouched).
56
+ *
57
+ * In `day` granularity (default) bounds are normalized to start-of-day (start) /
58
+ * end-of-day (end). In `minute` granularity the previously entered time is kept
59
+ * and only the calendar day changes; the range resolves to the exact instant.
60
+ */
23
61
  export declare const computeRangeUpdate: (input: RangeUpdateInput) => RangeUpdateResult;
62
+ /**
63
+ * Pure time-of-day update (minute granularity only).
64
+ *
65
+ * Applies the hour/minute emitted by a time field to the edited bound while
66
+ * keeping that bound's calendar day. When the edited bound has no value yet, the
67
+ * time field's own day is used as the base. The same `end >= start` clamp as
68
+ * {@link computeRangeUpdate} keeps the range valid without moving the other bound.
69
+ */
24
70
  export declare const applyTimeChange: (input: TimeChangeInput) => RangeUpdateResult;
71
+ /**
72
+ * Resolve a date-fns `Locale` from an app language code (e.g. the react-intl
73
+ * `intl.locale`). Defaults to English for unknown / missing codes.
74
+ *
75
+ * The specific locales are imported directly so they survive tree-shaking inside
76
+ * the commons bundle — the host's global `setDefaultOptions` never reaches the
77
+ * bundle's own date-fns copy, so locale must always be passed explicitly.
78
+ */
25
79
  export declare const resolveDateFnsLocale: (language?: string | null) => Locale;