@abyss-project/commons-front-core 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CookieConsentSettings.component-CgiQCgFX.js → CookieConsentSettings.component-CSf_M5Gx.js} +505 -443
- package/dist/components/Avatars/ProjectAvatar/ProjectAvatar.component.d.ts +3 -0
- package/dist/components/Avatars/UserAvatar/UserAvatar.component.d.ts +3 -0
- package/dist/components/Cards/ProjectCard/ProjectCard.component.d.ts +1 -0
- package/dist/components/CommandPalette/AbyssCommandPalette.d.ts +9 -0
- package/dist/components/CommandPalette/types.d.ts +63 -0
- package/dist/components/CommandPalette/useCommandPaletteHotkey.d.ts +9 -0
- package/dist/components/CompanySearchAutocomplete/CompanySearchAutocomplete.d.ts +25 -0
- package/dist/components/CompanySearchAutocomplete/CompanySearchAutocomplete.error.spec.d.ts +1 -0
- package/dist/components/CompanySearchAutocomplete/index.d.ts +2 -0
- package/dist/components/CookieConsent/AbyssCookieConsentProvider.d.ts +9 -0
- package/dist/components/CookieConsent/privacy-link.constant.d.ts +25 -0
- package/dist/components/Data/AbyssTable/AbyssTable.component.d.ts +16 -2
- package/dist/components/Data/AbyssTable/abyss-table.logic.d.ts +72 -0
- package/dist/components/Inputs/AbyssNumberField/AbyssNumberField.component.d.ts +18 -0
- package/dist/components/Inputs/AbyssNumberField/format.d.ts +28 -0
- package/dist/components/Inputs/CloudImport/CloudImport.component.d.ts +1 -0
- package/dist/components/Inputs/ColorPalette/ColorPalette.component.d.ts +2 -0
- package/dist/components/Inputs/ContextSelector/ContextSelector.component.d.ts +25 -0
- package/dist/components/Inputs/DatePeriodPicker/DatePeriodPicker.component.d.ts +32 -0
- package/dist/components/Inputs/DatePeriodPicker/date-period-picker.logic.d.ts +54 -0
- package/dist/components/Inputs/DatePeriodPicker/date-period-presets.util.d.ts +8 -0
- package/dist/components/Inputs/LanguageFlagLabel/LanguageFlagLabel.component.d.ts +13 -0
- package/dist/components/Inputs/LanguageFlagLabel/language-flags.d.ts +10 -0
- package/dist/components/Inputs/PasswordInput/PasswordInput.component.d.ts +16 -0
- package/dist/components/Inputs/ProjectLinkSelector/index.d.ts +1 -1
- package/dist/components/Layouts/AbyssBillingPlan/AbyssBillingPlan.component.d.ts +2 -0
- package/dist/components/Layouts/AbyssFamilyBanner/AbyssFamilyBanner.component.d.ts +12 -0
- package/dist/components/Layouts/AbyssLayoutProvider/index.d.ts +1 -1
- package/dist/components/Layouts/AbyssSidebar/index.d.ts +2 -2
- package/dist/components/Modals/AbyssModal/AbyssModal.component.d.ts +6 -0
- package/dist/components/Modals/QRCodeModal/QRCodeModal.component.d.ts +1 -0
- package/dist/components/Modals/UserSettingsModal/UserSettingsModal.component.d.ts +5 -0
- package/dist/components/Modals/UserSettingsModal/index.d.ts +1 -1
- package/dist/components/PdfEditor/hooks/use-pdf-document.d.ts +12 -0
- package/dist/components/PdfEditor/hooks/use-uploaded-docs.d.ts +9 -0
- package/dist/components/PdfEditor/operations/actions.d.ts +14 -0
- package/dist/components/PdfEditor/operations/compute-page-order.d.ts +11 -0
- package/dist/components/PdfEditor/operations/extract.d.ts +5 -0
- package/dist/components/PdfEditor/operations/pdf-data-url.d.ts +4 -0
- package/dist/components/PdfEditor/operations/rasterize.d.ts +17 -0
- package/dist/components/PdfEditor/operations/redact.d.ts +8 -0
- package/dist/components/PdfEditor/operations/rotate-coords.d.ts +25 -0
- package/dist/components/PdfEditor/signature/SignaturePicker.d.ts +3 -0
- package/dist/components/PdfEditor/signature/SignatureSaveButton.d.ts +3 -0
- package/dist/components/PdfEditor/signature/resolve-asset.d.ts +17 -0
- package/dist/components/PdfEditor/tools/RedactTool.d.ts +6 -0
- package/dist/components/PdfEditor/tools/Toolbar.d.ts +9 -0
- package/dist/components/PdfEditor/tools/tool-options-ui.d.ts +1 -0
- package/dist/components/PdfEditor/types.d.ts +85 -0
- package/dist/components/PdfEditor/viewer/PageOverlay.d.ts +10 -0
- package/dist/components/PdfEditor/viewer/PdfCanvas.d.ts +1 -0
- package/dist/components/PdfEditor/viewer/ViewerControls.d.ts +4 -0
- package/dist/components/QuotaGauge/AbyssQuotaGauge.component.d.ts +39 -0
- package/dist/components/QuotaGauge/bubble-placement.d.ts +40 -0
- package/dist/components/QuotaGauge/gauge-segments.d.ts +56 -0
- package/dist/components/QuotaOffer/AbyssQuotaOffer.component.d.ts +60 -0
- package/dist/components/QuotaOffer/quota-offer-state.d.ts +64 -0
- package/dist/components/QuotaReached/QuotaReachedDialog.component.d.ts +10 -0
- package/dist/components/QuotaReached/billing-quota-error.d.ts +7 -0
- package/dist/components/QuotaReached/quota-dialog.store.d.ts +10 -0
- package/dist/components/QuotaReached/quota-service-meta.d.ts +4 -0
- package/dist/components/Support/SupportCategorySelect.component.d.ts +3 -0
- package/dist/components/Support/SupportStatusTimeline.component.d.ts +2 -0
- package/dist/components/Support/index.d.ts +2 -2
- package/dist/components/Support/support-attachment.logic.d.ts +10 -0
- package/dist/components/Support/support-author.logic.d.ts +9 -0
- package/dist/components/Support/support-create-stepper.logic.d.ts +13 -0
- package/dist/components/Support/support-message-input.logic.d.ts +8 -0
- package/dist/components/Support/support-status-timeline.logic.d.ts +16 -0
- package/dist/components/Support/types.d.ts +55 -0
- package/dist/components/Utils/AbyssBackground/AbyssBackground.component.d.ts +3 -0
- package/dist/components/Utils/AbyssFamilyMenuSection/AbyssFamilyMenuSection.d.ts +9 -0
- package/dist/components/Utils/AbyssLayoutMenu/index.d.ts +1 -1
- package/dist/components/Utils/AbyssLayoutNotifications/AbyssLayoutNotifications.component.d.ts +4 -0
- package/dist/components/Utils/AbyssLayoutNotifications/index.d.ts +1 -1
- package/dist/components/Utils/ImportButton/ImportButton.component.d.ts +4 -0
- package/dist/components/Utils/Toast/AbyssToast.component.d.ts +6 -0
- package/dist/components/Utils/WaterParticles/WaterParticles.component.d.ts +8 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/cookie-consent.js +1 -1
- package/dist/hooks/use-public-users.hook.d.ts +39 -0
- package/dist/hooks/use-rich-intl.hook.d.ts +27 -5
- package/dist/hooks/use-theme-transition.hook.d.ts +13 -0
- package/dist/{index-D2ot8DZ4.js → index-6vOdokCY.js} +2 -2
- package/dist/{index-cYFrJDdQ.js → index-AUELqW5Y.js} +4 -4
- package/dist/{index-DXDfaFmT.js → index-AwC_8lIT.js} +4 -4
- package/dist/{index-BN-71mBQ.js → index-B7EugME7.js} +2 -2
- package/dist/{index-0WPkkm3C.js → index-BOqcEEHH.js} +3 -3
- package/dist/{index-Ctm2mN4b.js → index-BSRrH_Gr.js} +2 -2
- package/dist/{index-DpeaEf87.js → index-BToZYvup.js} +2 -2
- package/dist/{index-CgqzFzYH.js → index-BlCa_Vlr.js} +2 -2
- package/dist/{index-FF8J68dM.js → index-BoYupKIh.js} +23908 -20833
- package/dist/{index-2gSMCEyX.js → index-BtiGEZHC.js} +3 -3
- package/dist/{index-d9VwJ6nR.js → index-C2a_Y6jF.js} +2 -2
- package/dist/{index-C7bGgD6e.js → index-CCphPqf4.js} +2 -2
- package/dist/{index-CdpydxgB.js → index-CD9GifGt.js} +2 -2
- package/dist/{index-BSa7pbNq.js → index-CDWityvJ.js} +3 -3
- package/dist/{index-CAqpnDEx.js → index-CFVsaKv5.js} +4 -4
- package/dist/{index-C1NWZqnA.js → index-CtSA_KxY.js} +2 -2
- package/dist/{index-C02uLNDS.js → index-D7WU-N9n.js} +2 -2
- package/dist/{index-D5IIOkfu.js → index-DUGpZohv.js} +2 -2
- package/dist/{index-BqjTmumL.js → index-DrHXb1cg.js} +2 -2
- package/dist/{index-B9n8aGer.js → index-GhkzA3Z-.js} +2 -2
- package/dist/{index-CXNLGqpN.js → index-RBcLmJfD.js} +1 -1
- package/dist/{index-DQgswKg1.js → index-iw6ikhdy.js} +3 -3
- package/dist/index.js +185 -184
- package/dist/theme/augmentation.d.ts +6 -0
- package/dist/theme/index.d.ts +11 -4
- package/dist/theme/palettes/common.d.ts +13 -0
- package/dist/theme/palettes/dark.d.ts +1 -0
- package/dist/theme/palettes/light.d.ts +1 -0
- package/dist/theme/tokens/animations.d.ts +3 -0
- package/dist/theme/tokens/borders.d.ts +3 -0
- package/dist/theme/tokens/colors.d.ts +27 -0
- package/dist/theme/tokens/shadows.d.ts +8 -0
- package/dist/theme/tokens/transitions.d.ts +4 -0
- package/dist/theme/tokens/typography.d.ts +6 -0
- package/dist/translations/en.d.ts +3 -0
- package/dist/translations/fr.d.ts +3 -0
- package/dist/utils/share-notification.utils.d.ts +9 -0
- package/dist/utils/space-display-name.utils.d.ts +8 -0
- package/package.json +14 -13
- package/tsconfig.json +26 -25
- package/vite.config.ts +1 -17
|
@@ -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;
|
|
@@ -2,6 +2,14 @@ export type DatePeriodPreset = {
|
|
|
2
2
|
label: string;
|
|
3
3
|
getRange: () => [Date, Date];
|
|
4
4
|
};
|
|
5
|
+
/** Translation keys backing the default presets. Both locale files define them. */
|
|
5
6
|
export declare const DEFAULT_PRESET_KEYS: readonly ["inputs.period-picker.labels.presets.7d", "inputs.period-picker.labels.presets.30d", "inputs.period-picker.labels.presets.90d", "inputs.period-picker.labels.presets.month", "inputs.period-picker.labels.presets.year"];
|
|
6
7
|
export type DefaultPresetKey = (typeof DEFAULT_PRESET_KEYS)[number];
|
|
8
|
+
/**
|
|
9
|
+
* Default presets, labelled from the active translations.
|
|
10
|
+
*
|
|
11
|
+
* These labels used to be hardcoded English literals, so every screen that did
|
|
12
|
+
* not pass its own `presets` rendered "Month" and "Year" next to a French UI.
|
|
13
|
+
* The keys already existed in both locale files; only the wiring was missing.
|
|
14
|
+
*/
|
|
7
15
|
export declare const buildDefaultPresets: (translate: (id: DefaultPresetKey) => string) => DatePeriodPreset[];
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
type Props = {
|
|
3
|
+
/** Language/locale code (e.g. ProjectLanguage.FRENCH) used to resolve the flag. */
|
|
3
4
|
code: string;
|
|
5
|
+
/** Human-readable, already-translated language name (e.g. "Français"). */
|
|
4
6
|
label: string;
|
|
7
|
+
/** Font size of the language name. Defaults to MUI body2. */
|
|
5
8
|
variant?: 'body1' | 'body2' | 'caption';
|
|
9
|
+
/** Gap between the flag and the label (MUI spacing units). */
|
|
6
10
|
gap?: number;
|
|
7
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Reusable flag + language-name row. The flag is purely decorative
|
|
14
|
+
* (`aria-hidden`) and the readable label carries the accessible text, so screen
|
|
15
|
+
* readers announce the language name without the flag noise.
|
|
16
|
+
*
|
|
17
|
+
* Renders e.g. "🇫🇷 Français" instead of a bare code or "FR - France". Use it in
|
|
18
|
+
* any language picker (`Autocomplete` option, list item, selected value) so every
|
|
19
|
+
* abyss front renders language options the same way. See the README in this folder.
|
|
20
|
+
*/
|
|
8
21
|
export declare const LanguageFlagLabel: React.FC<Props>;
|
|
9
22
|
export default LanguageFlagLabel;
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth that maps a language/locale code to its country flag
|
|
3
|
+
* emoji. Flags are stored as escaped regional-indicator code points so the file
|
|
4
|
+
* stays ASCII-safe and unambiguous in review.
|
|
5
|
+
*
|
|
6
|
+
* Codes match the `ProjectLanguage` enum used across the ecosystem (spotlight,
|
|
7
|
+
* forms, etc.) so any app can render a language option as a flag + readable name
|
|
8
|
+
* instead of a bare code or a "FR - France" style label.
|
|
9
|
+
*/
|
|
1
10
|
export declare const LANGUAGE_FLAGS: Record<string, string>;
|
|
11
|
+
/** Returns the flag emoji for a language/locale code, or '' when unknown. */
|
|
2
12
|
export declare const getLanguageFlag: (language: string) => string;
|
|
@@ -11,15 +11,31 @@ type Props = {
|
|
|
11
11
|
size?: 'small' | 'medium';
|
|
12
12
|
sx?: SxProps;
|
|
13
13
|
disabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Password-manager hint. ALWAYS set it on real auth forms — `current-password`
|
|
16
|
+
* on sign-in, `new-password` on sign-up / reset / change. Without it browsers
|
|
17
|
+
* both fail to offer the saved credential and fail to offer to save the new
|
|
18
|
+
* one, which pushes people toward weaker, memorable passwords.
|
|
19
|
+
*/
|
|
14
20
|
autoComplete?: string;
|
|
21
|
+
/** Helper or error text shown under the field. */
|
|
15
22
|
helperText?: ReactNode;
|
|
16
23
|
required?: boolean;
|
|
17
24
|
autoFocus?: boolean;
|
|
18
25
|
id?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Raw props forwarded to the underlying `input`. Use for a11y wiring
|
|
28
|
+
* (`aria-describedby`, `aria-invalid`) that has no dedicated prop here.
|
|
29
|
+
*/
|
|
19
30
|
inputProps?: Record<string, unknown>;
|
|
20
31
|
onKeyDown?: (e: KeyboardEvent<HTMLDivElement>) => void;
|
|
21
32
|
onKeyUp?: (e: KeyboardEvent<HTMLDivElement>) => void;
|
|
22
33
|
onBlur?: () => void;
|
|
23
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Text field for a password, with a show/hide toggle.
|
|
37
|
+
*
|
|
38
|
+
* See README.md in this folder for the full surface and usage notes.
|
|
39
|
+
*/
|
|
24
40
|
declare const PasswordInput: FC<Props>;
|
|
25
41
|
export default PasswordInput;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as ProjectLinkSelector } from './ProjectLinkSelector.component';
|
|
2
|
-
export type { OrganizationOption, ProjectOption, ApplicationOption, LinkType } from './ProjectLinkSelector.component';
|
|
2
|
+
export type { OrganizationOption, ProjectOption, ApplicationOption, LinkType, } from './ProjectLinkSelector.component';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { IPlanTemplate } from '@abyss-project/main';
|
|
3
3
|
type Props = {
|
|
4
|
+
/** Omitted/null when the user has no explicit billing account → shown as the
|
|
5
|
+
* free plan, so the "current plan" badge never silently disappears. */
|
|
4
6
|
planTemplate?: IPlanTemplate | null;
|
|
5
7
|
label?: string;
|
|
6
8
|
abyssUrl?: string;
|
|
@@ -12,8 +12,20 @@ type Props = {
|
|
|
12
12
|
abyssUrl?: string;
|
|
13
13
|
variant: FamilyBannerVariant;
|
|
14
14
|
};
|
|
15
|
+
/** Pure resolver — exported for unit testing (no JSX, no hooks). */
|
|
15
16
|
export declare function resolveBannerState(currentFamily: CurrentFamilyInfo | null | undefined): FamilyBannerStatus;
|
|
17
|
+
/**
|
|
18
|
+
* Pure CTA href resolver — exported for unit testing.
|
|
19
|
+
*
|
|
20
|
+
* When the user has no family (none state), returns the create-family onboarding
|
|
21
|
+
* URL (with `?intent=family` so the onboarding flow can pre-select the FAMILY
|
|
22
|
+
* user-type). When the user has a family, returns the org management URL.
|
|
23
|
+
*/
|
|
16
24
|
export declare function resolveCTAHref(currentFamily: CurrentFamilyInfo | null | undefined, abyssUrl: string | undefined): string;
|
|
25
|
+
/**
|
|
26
|
+
* Pure layout descriptor — exported for unit testing.
|
|
27
|
+
* Returns structural properties that differ between footer and settings variants.
|
|
28
|
+
*/
|
|
17
29
|
export declare function resolveVariantLayout(variant: FamilyBannerVariant): {
|
|
18
30
|
isCompact: boolean;
|
|
19
31
|
showDescription: boolean;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AbyssLayoutProvider, useAbyssLayoutStore } from './AbyssLayoutProvider.component';
|
|
1
|
+
export { AbyssLayoutProvider, useAbyssLayoutStore, } from './AbyssLayoutProvider.component';
|
|
2
2
|
export { createAbyssLayoutStore } from './abyss-layout.store';
|
|
3
3
|
export type { AbyssLayoutState, AbyssLayoutStore } from './abyss-layout.store';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as AbyssSidebar } from './AbyssSidebar.component';
|
|
2
|
-
export type { AbyssSidebarItem, AbyssSidebarSection } from './AbyssSidebar.component';
|
|
3
|
-
export { ABYSS_SIDEBAR_WIDTH, ABYSS_SIDEBAR_WIDTH_COLLAPSED } from './AbyssSidebar.component';
|
|
2
|
+
export type { AbyssSidebarItem, AbyssSidebarSection, } from './AbyssSidebar.component';
|
|
3
|
+
export { ABYSS_SIDEBAR_WIDTH, ABYSS_SIDEBAR_WIDTH_COLLAPSED, } from './AbyssSidebar.component';
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { DialogProps, SxProps } from '@mui/material';
|
|
3
3
|
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* Opt out of the built-in close button. AbyssModal owns the single close
|
|
6
|
+
* button for every modal — consumers must NOT render their own. Set this only
|
|
7
|
+
* when the modal provides its own custom close affordance.
|
|
8
|
+
*/
|
|
4
9
|
hideCloseButton?: boolean;
|
|
10
|
+
/** @deprecated Use `hideCloseButton` instead. Kept as an alias for back-compat. */
|
|
5
11
|
disableCloseButton?: boolean;
|
|
6
12
|
sxCloseButton?: SxProps;
|
|
7
13
|
onClose?: () => void;
|
|
@@ -17,6 +17,11 @@ export type UserSettingsValues = {
|
|
|
17
17
|
name: string;
|
|
18
18
|
familyName: string;
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Exported for unit testing — no React deps.
|
|
22
|
+
* `overrideFamily` is the standalone `currentFamily` prop from the component;
|
|
23
|
+
* when provided it takes precedence, otherwise falls back to `user.currentFamily`.
|
|
24
|
+
*/
|
|
20
25
|
export declare function shouldRenderFamilyBanner(user: UserSettingsUser, overrideFamily?: UserSettingsUser['currentFamily']): boolean;
|
|
21
26
|
type Props = {
|
|
22
27
|
isOpen: boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as UserSettingsModal } from './UserSettingsModal.component';
|
|
2
|
-
export type { UserSettingsUser, UserSettingsValues } from './UserSettingsModal.component';
|
|
2
|
+
export type { UserSettingsUser, UserSettingsValues, } from './UserSettingsModal.component';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
2
|
import { PdfSource } from '../types';
|
|
3
|
+
/** Decrypts password-protected bytes (e.g. via qpdf-WASM). */
|
|
3
4
|
type Decryptor = (bytes: Uint8Array, password: string) => Promise<Uint8Array>;
|
|
4
5
|
interface UsePdfDocumentResult {
|
|
5
6
|
pdfDoc: PDFDocumentProxy | null;
|
|
@@ -7,10 +8,21 @@ interface UsePdfDocumentResult {
|
|
|
7
8
|
pageCount: number;
|
|
8
9
|
loading: boolean;
|
|
9
10
|
error: Error | null;
|
|
11
|
+
/** True when the source is encrypted and a decryptor is available — the host
|
|
12
|
+
* should prompt for a password and call `unlock`. */
|
|
10
13
|
needsPassword: boolean;
|
|
14
|
+
/** True while a submitted password is being verified/applied. */
|
|
11
15
|
unlocking: boolean;
|
|
16
|
+
/** True after the last `unlock` attempt failed (wrong password). */
|
|
12
17
|
unlockFailed: boolean;
|
|
18
|
+
/** Decrypt the source with the given password and load it on success. */
|
|
13
19
|
unlock: (password: string) => void;
|
|
14
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Loads a PDF from a PdfSource and returns a PDFDocumentProxy and raw bytes.
|
|
23
|
+
*
|
|
24
|
+
* IMPORTANT: `source` must be a stable reference (useState, useMemo, or module-level constant).
|
|
25
|
+
* Passing an inline object literal will cause an infinite reload loop.
|
|
26
|
+
*/
|
|
15
27
|
export declare const usePdfDocument: (source: PdfSource | null, decryptor?: Decryptor) => UsePdfDocumentResult;
|
|
16
28
|
export {};
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
2
|
import { PdfOperation } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Loads each unique `uploadKey` referenced by PAGE_INSERT_FROM_UPLOAD ops
|
|
5
|
+
* into a PDFDocumentProxy. Returns a map keyed by uploadKey.
|
|
6
|
+
*
|
|
7
|
+
* Re-runs only when the set of uploadKeys changes. Keeps previously-committed
|
|
8
|
+
* docs alive across re-runs so that the renderer never sees a destroyed proxy
|
|
9
|
+
* mid-transition; old docs are released only after the new map is committed
|
|
10
|
+
* (or on unmount).
|
|
11
|
+
*/
|
|
3
12
|
export declare const useUploadedDocs: (operations: PdfOperation[]) => Map<string, PDFDocumentProxy>;
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { AcroFormField, EditorAction, PdfOperation, ToolKind } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Typed action creators for the editor reducer.
|
|
4
|
+
*
|
|
5
|
+
* Call sites read as intent (`dispatch(deleteOperation(id))`) instead of raw
|
|
6
|
+
* `dispatch({ type: 'DELETE_OPERATION', payload: { opId: id } })`, and the
|
|
7
|
+
* action shapes live in exactly one place so the reducer, the creators and the
|
|
8
|
+
* `EditorAction` union can never drift apart.
|
|
9
|
+
*/
|
|
10
|
+
/** Append a new operation (records an undo step). */
|
|
2
11
|
export declare const addOperation: (operation: PdfOperation) => EditorAction;
|
|
12
|
+
/** Append several operations as a single undo step. */
|
|
3
13
|
export declare const addOperations: (operations: PdfOperation[]) => EditorAction;
|
|
14
|
+
/** Fan a text/image op out to the given pages (records a single undo step). */
|
|
4
15
|
export declare const addOperationAllPages: (operation: PdfOperation, pageIndices: number[]) => EditorAction;
|
|
16
|
+
/** Replace an operation in place (records an undo step). */
|
|
5
17
|
export declare const updateOperation: (opId: string, operation: PdfOperation) => EditorAction;
|
|
18
|
+
/** Replace an operation in place WITHOUT recording history (drag frames). */
|
|
6
19
|
export declare const moveOperation: (opId: string, operation: PdfOperation) => EditorAction;
|
|
20
|
+
/** Remove an operation (records an undo step). */
|
|
7
21
|
export declare const deleteOperation: (opId: string) => EditorAction;
|
|
8
22
|
export declare const undo: () => EditorAction;
|
|
9
23
|
export declare const redo: () => EditorAction;
|
|
@@ -4,7 +4,18 @@ export interface InsertedPageRef {
|
|
|
4
4
|
uploadKey: string;
|
|
5
5
|
uploadPageIndex: number;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Maps each synthetic virtual index (>= numPages) to the uploaded page it represents.
|
|
9
|
+
* Allocation order: walk operations in array order; for each PAGE_INSERT_FROM_UPLOAD,
|
|
10
|
+
* allocate uploadPages.length consecutive synthetic indices starting at the next
|
|
11
|
+
* available counter (initial = numPages). The K-th allocated index corresponds to
|
|
12
|
+
* op.uploadPages[K].
|
|
13
|
+
*/
|
|
7
14
|
export declare function computeInsertionTable(numPages: number, operations: PdfOperation[]): Map<number, InsertedPageRef>;
|
|
15
|
+
/**
|
|
16
|
+
* Maps each synthetic virtual index that represents an inserted BLANK page to its
|
|
17
|
+
* size. Allocation order matches computeInsertionTable / computePageOrder.
|
|
18
|
+
*/
|
|
8
19
|
export declare function computeBlankPages(numPages: number, operations: PdfOperation[]): Map<number, {
|
|
9
20
|
widthPt: number;
|
|
10
21
|
heightPt: number;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import { PdfOperation } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Bake the current edits, then produce a NEW PDF containing only the selected
|
|
4
|
+
* output pages (by display index, 0-based, in the order given). Used by
|
|
5
|
+
* extract / split.
|
|
6
|
+
*/
|
|
2
7
|
export declare const extractPages: (sourceBytes: Uint8Array, operations: PdfOperation[], keepDisplayIndices: number[]) => Promise<Uint8Array>;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode a `data:application/pdf;base64,...` URL into raw bytes.
|
|
3
|
+
* Works in Node (via Buffer) and in the browser (via atob).
|
|
4
|
+
*/
|
|
1
5
|
export declare const dataUrlToBytes: (dataUrl: string) => Uint8Array;
|
|
2
6
|
export declare const isPdfDataUrl: (key: string) => boolean;
|
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
2
|
import { PdfOperation } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Browser-only pre-bake step for TRUE redaction.
|
|
5
|
+
*
|
|
6
|
+
* For every page carrying ANNOTATE_REDACT regions, render the original page to a
|
|
7
|
+
* canvas (in unrotated content space), paint opaque black boxes over the redacted
|
|
8
|
+
* rectangles, and replace the page with that flattened image. The page's text and
|
|
9
|
+
* vector content underneath is destroyed — not merely hidden — so the redacted
|
|
10
|
+
* data cannot be recovered with copy/paste or a PDF text extractor.
|
|
11
|
+
*
|
|
12
|
+
* Pages without redaction are copied through untouched (vector, selectable text
|
|
13
|
+
* preserved). The original page count and order are kept, so downstream
|
|
14
|
+
* annotation ops (which key off the source page index) still map correctly.
|
|
15
|
+
*
|
|
16
|
+
* Caller must strip the ANNOTATE_REDACT ops before the main bake — they are
|
|
17
|
+
* already baked into the raster here. Returns the source bytes unchanged when
|
|
18
|
+
* there is nothing to redact.
|
|
19
|
+
*/
|
|
3
20
|
export declare const rasterizeRedactedPages: (sourceBytes: Uint8Array, pdfProxy: PDFDocumentProxy, operations: PdfOperation[]) => Promise<Uint8Array>;
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { PdfOperation } from '../types';
|
|
2
|
+
/** A single rectangle to black out, in PDF points (top-left origin, content space). */
|
|
2
3
|
export interface RedactRect {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
5
6
|
widthPt: number;
|
|
6
7
|
heightPt: number;
|
|
7
8
|
}
|
|
9
|
+
/** True when at least one redaction op is present (cheap export-time check). */
|
|
8
10
|
export declare const hasRedactions: (operations: PdfOperation[]) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Group every redaction region by its (virtual) source page index. Pages absent
|
|
13
|
+
* from the returned map carry no redaction and must NOT be rasterized — keeping
|
|
14
|
+
* them vector preserves quality and selectable text everywhere except the pages
|
|
15
|
+
* the user explicitly redacted.
|
|
16
|
+
*/
|
|
9
17
|
export declare const collectRedactions: (operations: PdfOperation[]) => Map<number, RedactRect[]>;
|
|
@@ -1,19 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure geometry helpers for mapping points between a page's UNROTATED content
|
|
3
|
+
* space (top-left origin, y-down, PDF points) and the ROTATED view space the
|
|
4
|
+
* user actually sees and clicks on.
|
|
5
|
+
*
|
|
6
|
+
* The bake (`apply.ts`) always draws annotations in content space and then sets
|
|
7
|
+
* the page rotation, so the page content + annotations rotate together. To keep
|
|
8
|
+
* the on-screen preview identical to the baked output, the editor stores every
|
|
9
|
+
* annotation in content space and uses these helpers to (a) convert pointer
|
|
10
|
+
* input from view space back to content space on creation/drag, and (b) place
|
|
11
|
+
* the (content-space) annotations inside a single inner layer that is rotated as
|
|
12
|
+
* a whole to match the page (`innerLayerTransform`).
|
|
13
|
+
*
|
|
14
|
+
* All rotations are CLOCKWISE and assumed to be multiples of 90.
|
|
15
|
+
*/
|
|
1
16
|
export type Rotation = 0 | 90 | 180 | 270;
|
|
17
|
+
/** Clamp any (possibly negative, possibly >360) multiple of 90 into 0/90/180/270. */
|
|
2
18
|
export declare const normalizeRotation: (deg: number) => Rotation;
|
|
19
|
+
/** Rendered (view) size of a content box once rotated. 90/270 swap w/h. */
|
|
3
20
|
export declare const viewSize: (cw: number, ch: number, rotation: Rotation) => {
|
|
4
21
|
w: number;
|
|
5
22
|
h: number;
|
|
6
23
|
};
|
|
24
|
+
/** Content size from a rendered (view) size. Inverse of {@link viewSize}. */
|
|
7
25
|
export declare const contentSize: (vw: number, vh: number, rotation: Rotation) => {
|
|
8
26
|
w: number;
|
|
9
27
|
h: number;
|
|
10
28
|
};
|
|
29
|
+
/** Map a point from unrotated content space to rotated view space (clockwise). */
|
|
11
30
|
export declare const contentToView: (x: number, y: number, rotation: Rotation, cw: number, ch: number) => {
|
|
12
31
|
x: number;
|
|
13
32
|
y: number;
|
|
14
33
|
};
|
|
34
|
+
/** Map a point from rotated view space back to content space. Inverse of {@link contentToView}. */
|
|
15
35
|
export declare const viewToContent: (x: number, y: number, rotation: Rotation, cw: number, ch: number) => {
|
|
16
36
|
x: number;
|
|
17
37
|
y: number;
|
|
18
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* CSS `transform` for an inner layer sized to the content box (CW x CH pixels,
|
|
41
|
+
* already scaled) so that, after a clockwise rotation about its top-left corner,
|
|
42
|
+
* it lands exactly over the rotated page canvas in the positive quadrant.
|
|
43
|
+
*/
|
|
19
44
|
export declare const innerLayerTransform: (rotation: Rotation, contentWidthPx: number, contentHeightPx: number) => string;
|
|
@@ -5,11 +5,14 @@ interface SignaturePickerProps {
|
|
|
5
5
|
open: boolean;
|
|
6
6
|
onClose: () => void;
|
|
7
7
|
onCapture: (dataUrl: string) => void;
|
|
8
|
+
/** Called when the user picks a TEXT_BLOCK asset — receives raw text so the
|
|
9
|
+
* host can switch to text-placement mode rather than image insertion. */
|
|
8
10
|
onCaptureText?: (text: string) => void;
|
|
9
11
|
assetPalette?: AssetPalette;
|
|
10
12
|
onSaveSignature?: SaveSignatureFn;
|
|
11
13
|
resolveAssetBytes?: ResolveAssetBytes;
|
|
12
14
|
onAssetError?: (message: string) => void;
|
|
15
|
+
/** Optional URL to the host's "manage assets" page (Account → Assets). */
|
|
13
16
|
manageAssetsUrl?: string;
|
|
14
17
|
}
|
|
15
18
|
export declare const SignaturePicker: React.FC<SignaturePickerProps>;
|
|
@@ -3,6 +3,9 @@ import { AssetPalette, SaveSignatureFn } from '../types';
|
|
|
3
3
|
interface SignatureSaveButtonProps {
|
|
4
4
|
dataUrl: string | null;
|
|
5
5
|
onSave: SaveSignatureFn;
|
|
6
|
+
/** When provided and it contains at least one org bucket, a scope picker
|
|
7
|
+
* appears in the save dialog so the user can target a personal OR an
|
|
8
|
+
* organization asset. */
|
|
6
9
|
assetPalette?: AssetPalette;
|
|
7
10
|
}
|
|
8
11
|
export declare const SignatureSaveButton: React.FC<SignatureSaveButtonProps>;
|
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
import { AssetPaletteItem } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Host-provided resolver that returns a usable data URL for a server-stored
|
|
4
|
+
* asset. Authenticated hosts implement this via a presigned download so it works
|
|
5
|
+
* cross-origin (a bare `fetch` of the storage public-access URL is CORS-blocked
|
|
6
|
+
* even though an `<img>` of the same URL renders fine).
|
|
7
|
+
*/
|
|
2
8
|
export type ResolveAssetBytes = (item: AssetPaletteItem) => Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve an asset palette item to a data URL ready to embed.
|
|
11
|
+
*
|
|
12
|
+
* - Prefers the host `resolver` (authenticated, cross-origin safe).
|
|
13
|
+
* - Falls back to a direct `fetch` of `downloadUrl` — correct for same-origin or
|
|
14
|
+
* `data:` URLs (e.g. anonymous local signatures), which is why anonymous mode
|
|
15
|
+
* works without a resolver.
|
|
16
|
+
*
|
|
17
|
+
* Throws on failure so callers can surface a visible error instead of silently
|
|
18
|
+
* doing nothing.
|
|
19
|
+
*/
|
|
3
20
|
export declare const resolveAssetDataUrl: (item: AssetPaletteItem, resolver?: ResolveAssetBytes) => Promise<string>;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Redaction is destructive: on export the affected pages are flattened to an
|
|
4
|
+
* image with opaque black boxes, so the underlying text/content is gone for
|
|
5
|
+
* good. The popover makes that consequence explicit before the user draws —
|
|
6
|
+
* there is no styling to configure, only the warning + how-to.
|
|
7
|
+
*/
|
|
2
8
|
export declare const RedactTool: React.FC;
|
|
@@ -16,6 +16,7 @@ interface ToolbarProps {
|
|
|
16
16
|
resolveAssetBytes?: ResolveAssetBytes;
|
|
17
17
|
onAssetError?: (message: string) => void;
|
|
18
18
|
pendingApplyAllPages?: boolean;
|
|
19
|
+
/** Compact (narrow viewport): drop labels/filename so the bar never overflows. */
|
|
19
20
|
compact?: boolean;
|
|
20
21
|
sidebarOpen?: boolean;
|
|
21
22
|
onToggleSidebar?: () => void;
|
|
@@ -23,12 +24,20 @@ interface ToolbarProps {
|
|
|
23
24
|
onAddPageNumbers?: () => void;
|
|
24
25
|
onWatermark?: () => void;
|
|
25
26
|
onInsertImage?: () => void;
|
|
27
|
+
/** Insert an image picked from AbyssCloud (host-wired). */
|
|
26
28
|
onInsertCloudImage?: () => void;
|
|
27
29
|
onExtractPages?: () => void;
|
|
30
|
+
/** Host-provided (qpdf-WASM) actions — shown only when wired. */
|
|
28
31
|
onProtect?: () => void;
|
|
29
32
|
onCompress?: () => void;
|
|
33
|
+
/** True while a password/compress operation runs (disables those items). */
|
|
30
34
|
securing?: boolean;
|
|
35
|
+
/** Options panel for the active tool (null when the tool has none). Rendered
|
|
36
|
+
* in a popover anchored to the active tool button (bottom sheet on mobile). */
|
|
31
37
|
toolOptions?: React.ReactNode;
|
|
38
|
+
/** True while a signature/image/text is armed for placement. The anchored
|
|
39
|
+
* options popover is suppressed so it never covers the page the user must
|
|
40
|
+
* click to drop it (a non-blocking placement banner takes over instead). */
|
|
32
41
|
placementActive?: boolean;
|
|
33
42
|
}
|
|
34
43
|
export declare const Toolbar: React.FC<ToolbarProps>;
|