@abyss-project/commons-front-core 8.2.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -125
- package/catalog/catalog-entries.ts +17 -1
- package/catalog/cloud-picker-fixture.tsx +97 -0
- package/catalog/pages/Avatar.tsx +94 -0
- package/catalog/pages/Callout.tsx +67 -0
- package/catalog/pages/CloudImport.tsx +35 -0
- package/catalog/pages/ContextSelector.tsx +103 -0
- package/catalog/pages/CopyField.tsx +29 -0
- package/catalog/pages/DropZone.tsx +37 -0
- package/catalog/pages/FormField.tsx +54 -0
- package/catalog/pages/ImportButton.tsx +45 -0
- package/catalog/pages/ImportFromCloudModal.tsx +33 -0
- package/catalog/pages/Menu.tsx +2 -1
- package/catalog/pages/NumberField.tsx +46 -0
- package/catalog/pages/QRCodeModal.tsx +26 -0
- package/catalog/pages/SettingsRow.tsx +67 -0
- package/catalog/pages/Tabs.tsx +72 -0
- package/catalog/pages/UsageMeter.tsx +58 -0
- package/catalog/pages/index.ts +30 -2
- package/dist/{AbyssCookieConsentProvider-TE46ywnd.js → AbyssCookieConsentProvider-B-PlGbFf.js} +1096 -946
- package/dist/{CookieConsentSettings.component-BKsYgpMa.js → CookieConsentSettings.component-DEGCDEJW.js} +1 -1
- package/dist/components/business/CloudImport/CloudImport.d.ts +24 -0
- package/dist/components/business/CloudImport/cloud-import-tree.d.ts +22 -0
- package/dist/components/business/ImportFromCloudModal/ImportFromCloudModal.d.ts +21 -0
- package/dist/components/business/QRCodeModal/QRCodeModal.d.ts +18 -0
- package/dist/components/business/QRCodeModal/QRCodeModal.spec.d.ts +1 -0
- package/dist/components/business/index.d.ts +3 -0
- package/dist/components/data/DataTable/data-table.types.d.ts +10 -0
- package/dist/components/data/UsageMeter/UsageMeter.d.ts +31 -0
- package/dist/components/data/UsageMeter/UsageMeter.spec.d.ts +1 -0
- package/dist/components/data/index.d.ts +1 -0
- package/dist/components/inputs/ContextSelector/ContextSelector.d.ts +60 -0
- package/dist/components/inputs/ContextSelector/ContextSelector.spec.d.ts +1 -0
- package/dist/components/inputs/CopyField/CopyField.d.ts +19 -0
- package/dist/components/inputs/CopyField/CopyField.spec.d.ts +1 -0
- package/dist/components/inputs/DropZone/DropZone.d.ts +30 -0
- package/dist/components/inputs/DropZone/DropZone.spec.d.ts +1 -0
- package/dist/components/inputs/FormField/FormField.d.ts +29 -0
- package/dist/components/inputs/FormField/FormField.spec.d.ts +1 -0
- package/dist/components/inputs/ImportButton/ImportButton.d.ts +33 -0
- package/dist/components/inputs/ImportButton/ImportButton.spec.d.ts +1 -0
- package/dist/components/inputs/NumberField/NumberField.d.ts +21 -0
- package/dist/components/inputs/NumberField/NumberField.spec.d.ts +1 -0
- package/dist/components/inputs/NumberField/number-input.d.ts +13 -0
- package/dist/components/inputs/SettingsRow/SettingsRow.d.ts +16 -0
- package/dist/components/inputs/SettingsRow/SettingsRow.spec.d.ts +1 -0
- package/dist/components/inputs/index.d.ts +7 -0
- package/dist/components/layers/Menu/Menu.d.ts +2 -0
- package/dist/components/meaning/Avatar/Avatar.d.ts +41 -0
- package/dist/components/meaning/Avatar/Avatar.spec.d.ts +1 -0
- package/dist/components/meaning/index.d.ts +1 -0
- package/dist/components/states/Callout/Callout.d.ts +25 -0
- package/dist/components/states/Callout/Callout.spec.d.ts +1 -0
- package/dist/components/states/index.d.ts +1 -0
- package/dist/components/structure/Tabs/Tabs.d.ts +34 -0
- package/dist/components/structure/Tabs/Tabs.spec.d.ts +1 -0
- package/dist/components/structure/index.d.ts +1 -0
- package/dist/cookie-consent.js +2 -2
- package/dist/design-theme-CKTz_cOa.js +15490 -0
- package/dist/hooks/use-rich-intl.hook.d.ts +150 -0
- package/dist/{index-Dhz388yW.js → index-7N3J68EI.js} +2 -2
- package/dist/{index-BI8z_ZwK.js → index-B3rK_-T4.js} +4 -4
- package/dist/{index-BZfgg1Dp.js → index-B6qHo25Z.js} +2 -2
- package/dist/{index-D490I-Im.js → index-BMaAO_4e.js} +2 -2
- package/dist/{index-FS21eF3a.js → index-B_jSh70G.js} +3 -3
- package/dist/{index-B-Gq5Zeh.js → index-B_yywet5.js} +3 -3
- package/dist/{index-BR66kEMM.js → index-Bdtvzv-J.js} +2 -2
- package/dist/{index-C-bs2P06.js → index-Bh2_8FCK.js} +2 -2
- package/dist/{index-BXs_bBcm.js → index-Bpg9TBMX.js} +1 -1
- package/dist/{index-4BMCQ_6u.js → index-Bpnf8xKI.js} +2 -2
- package/dist/{index-DPxFwYmx.js → index-Bw2swxVq.js} +2 -2
- package/dist/{index-DjLWvtUt.js → index-BxxZgBFn.js} +2 -2
- package/dist/{index-C6ZLgLu-.js → index-Ca9tzEsn.js} +2 -2
- package/dist/{index-Bi3OW3pz.js → index-Csvh-AG6.js} +2 -2
- package/dist/{index-ltq6POQa.js → index-CwuklsUK.js} +3 -3
- package/dist/{index-csvcp4rP.js → index-DFC9xBY9.js} +2 -2
- package/dist/{index-C4VmhCn7.js → index-DfUcsAJv.js} +4 -4
- package/dist/{index-Bu5LDz63.js → index-DqedXp41.js} +3 -3
- package/dist/{index-CK9kVK6Y.js → index-DwXNHQIp.js} +4 -4
- package/dist/{index-Dm6584pR.js → index-_UY_fqvv.js} +28373 -34464
- package/dist/{index-DC-vg2P2.js → index-dVVflNge.js} +2 -2
- package/dist/{index-DistZiPf.js → index-sEWp0xIC.js} +2 -2
- package/dist/index.js +7214 -5051
- package/dist/legacy/components/QuotaOffer/AbyssQuotaOffer.component.d.ts +1 -1
- package/dist/legacy/components/QuotaOffer/index.d.ts +2 -2
- package/dist/legacy.js +142 -142
- package/dist/theme/tokens/semantic.d.ts +1 -1
- package/dist/translations/en.d.ts +75 -0
- package/dist/translations/fr.d.ts +75 -0
- package/dist/utils/cloud-accept.utils.spec.d.ts +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/quota-offer-state.utils.spec.d.ts +1 -0
- package/package.json +3 -3
- package/dist/design-theme-CN_6fRX3.js +0 -9344
- /package/dist/{legacy/components/Inputs/CloudImport/cloud-accept.spec.d.ts → components/business/CloudImport/CloudImport.spec.d.ts} +0 -0
- /package/dist/{legacy/components/QuotaOffer/quota-offer-state.spec.d.ts → components/business/ImportFromCloudModal/ImportFromCloudModal.spec.d.ts} +0 -0
- /package/dist/{legacy/components/Inputs/CloudImport/cloud-accept.d.ts → utils/cloud-accept.utils.d.ts} +0 -0
- /package/dist/{legacy/components/QuotaOffer/quota-offer-state.d.ts → utils/quota-offer-state.utils.d.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as e, jsxs as a } from "react/jsx-runtime";
|
|
2
2
|
import { useState as m, useEffect as C } from "react";
|
|
3
3
|
import { Card as v, CardContent as b, Stack as u, Typography as o, FormControlLabel as l, Box as r, Checkbox as d, Button as M } from "@mui/material";
|
|
4
|
-
import { g as R, u as x } from "./AbyssCookieConsentProvider-
|
|
4
|
+
import { g as R, u as x } from "./AbyssCookieConsentProvider-B-PlGbFf.js";
|
|
5
5
|
const B = () => {
|
|
6
6
|
const t = R(), { consent: i, save: y } = x(), [h, g] = m((i == null ? void 0 : i.analytics) ?? !1), [k, f] = m((i == null ? void 0 : i.marketing) ?? !1), c = i == null ? void 0 : i.analytics, n = i == null ? void 0 : i.marketing;
|
|
7
7
|
return C(() => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IFile, ISpace } from '@abyss-project/cloud';
|
|
2
|
+
import { CloudPicker } from '../../../hooks/cloud-picker.types';
|
|
3
|
+
export interface CloudImportProps {
|
|
4
|
+
/** Picker state and actions, as returned by `useCloudPicker`. */
|
|
5
|
+
cloudPicker: CloudPicker;
|
|
6
|
+
/** Receives the Space the files were picked from, and the picked files. */
|
|
7
|
+
onImport(space: ISpace, files: IFile[]): void;
|
|
8
|
+
/** Several files can be picked; one otherwise. */
|
|
9
|
+
multiple?: boolean;
|
|
10
|
+
/** Files larger than this, in bytes, are not listed. */
|
|
11
|
+
maxSize?: number;
|
|
12
|
+
/**
|
|
13
|
+
* The files offered, as the HTML `accept` attribute lists them: MIME types (`application/pdf`),
|
|
14
|
+
* wildcards (`image/*`) and extensions (`.pdf`). Absent or empty: every file.
|
|
15
|
+
*/
|
|
16
|
+
accept?: string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The AbyssCloud picker: the user picks a Space (personal, one group per organization, shared
|
|
20
|
+
* with them), opens its folders and picks files, then imports them. Mounting it provisions the
|
|
21
|
+
* Spaces (`cloudPicker.refresh`); a failed provisioning with nothing listed offers one « Créer mon
|
|
22
|
+
* cloud » retry. Files larger than `maxSize` or of a type `accept` refuses are not listed.
|
|
23
|
+
*/
|
|
24
|
+
export declare function CloudImport({ cloudPicker, onImport, multiple, maxSize, accept, }: CloudImportProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IFile, IFolder } from '@abyss-project/cloud';
|
|
2
|
+
/** What decides whether a cloud file is offered, and how picked files are tracked. */
|
|
3
|
+
export interface CloudTreeContext {
|
|
4
|
+
multiple: boolean;
|
|
5
|
+
maxSize?: number;
|
|
6
|
+
accept?: string[];
|
|
7
|
+
selectedIds: ReadonlySet<string>;
|
|
8
|
+
getFileThumbnailUrl(fileId: string): string;
|
|
9
|
+
/** Adds the files to the selection (replaces it when not `multiple`). */
|
|
10
|
+
select(files: IFile[]): void;
|
|
11
|
+
unselect(files: IFile[]): void;
|
|
12
|
+
}
|
|
13
|
+
/** The key of a file in the selection. */
|
|
14
|
+
export declare const fileKey: (file: IFile) => string;
|
|
15
|
+
/** Whether a file is listed: within the size limit and of an accepted type. */
|
|
16
|
+
export declare const isOffered: (file: IFile, maxSize: number | undefined, accept: string[] | undefined) => boolean;
|
|
17
|
+
/** The list of a folder level: sub-folders first, then the files the picker offers. */
|
|
18
|
+
export declare function CloudTreeLevel({ folders, files, context, }: {
|
|
19
|
+
folders: IFolder[];
|
|
20
|
+
files: IFile[];
|
|
21
|
+
context: CloudTreeContext;
|
|
22
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IFile, ISpace } from '@abyss-project/cloud';
|
|
2
|
+
import { CloudPicker } from '../../../hooks/cloud-picker.types';
|
|
3
|
+
export interface ImportFromCloudModalProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onClose(): void;
|
|
6
|
+
/** Receives the Space the files were picked from, and the files; the modal then closes. */
|
|
7
|
+
onImport(space: ISpace, files: IFile[]): void | Promise<void>;
|
|
8
|
+
/** Picker state and actions, as returned by `useCloudPicker`. */
|
|
9
|
+
cloudPicker: CloudPicker;
|
|
10
|
+
multiple?: boolean;
|
|
11
|
+
/** Files larger than this, in bytes, are not listed. */
|
|
12
|
+
maxSize?: number;
|
|
13
|
+
/** The files offered, as the HTML `accept` attribute lists them. Absent or empty: every file. */
|
|
14
|
+
accept?: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The AbyssCloud picker (`CloudImport`) in a `Modal`: a bottom sheet below 768 px. Importing hands
|
|
18
|
+
* the files to `onImport` and closes the modal; the host runs the import and reports its outcome.
|
|
19
|
+
* The picker mounts on opening, which is what provisions the user's Spaces.
|
|
20
|
+
*/
|
|
21
|
+
export declare function ImportFromCloudModal({ open, onClose, onImport, cloudPicker, multiple, maxSize, accept, }: ImportFromCloudModalProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface QRCodeModalProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onClose(): void;
|
|
4
|
+
/** The link the QR code encodes. */
|
|
5
|
+
url: string;
|
|
6
|
+
/** Hides the « Partager » button. */
|
|
7
|
+
maskShareButton?: boolean;
|
|
8
|
+
/** Hides the link and its copy button. */
|
|
9
|
+
maskCopyButton?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Side of the QR code image, in px: large enough for a phone camera across a desk. */
|
|
12
|
+
export declare const QR_CODE_SIZE = 200;
|
|
13
|
+
/**
|
|
14
|
+
* A link as a QR code, in a `Modal` (a bottom sheet below 768 px): the code on a light page, the
|
|
15
|
+
* link with its copy button (`CopyField`), and « Partager », which opens the device's share sheet
|
|
16
|
+
* or, without one, copies the link.
|
|
17
|
+
*/
|
|
18
|
+
export declare function QRCodeModal({ open, onClose, url, maskShareButton, maskCopyButton, }: QRCodeModalProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -29,6 +29,16 @@ export interface DataColumn<T> {
|
|
|
29
29
|
mono?: boolean;
|
|
30
30
|
/** `Default` when absent; an `Optional` column is hidden from 768 to 1199 px. */
|
|
31
31
|
priority?: ColumnPriority;
|
|
32
|
+
/**
|
|
33
|
+
* The cells run over several lines instead of being cut by an ellipsis (words stay whole): for a
|
|
34
|
+
* label whose whole text matters. The other columns keep their single line.
|
|
35
|
+
*/
|
|
36
|
+
wrap?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The header is read by assistive technologies but not drawn: a narrow column of icon actions
|
|
39
|
+
* whose label would only show cut.
|
|
40
|
+
*/
|
|
41
|
+
hideHeader?: boolean;
|
|
32
42
|
}
|
|
33
43
|
export interface DataTableSelection {
|
|
34
44
|
selected: string[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Shares of `max` (0.8 = 80 %) from which the meter turns to the warning, then danger color. */
|
|
2
|
+
export interface UsageMeterThresholds {
|
|
3
|
+
warning: number;
|
|
4
|
+
danger: number;
|
|
5
|
+
}
|
|
6
|
+
export interface UsageMeterProps {
|
|
7
|
+
/** The consumption, in the unit of `max`. */
|
|
8
|
+
value: number;
|
|
9
|
+
/** The ceiling. Without it, only the value is shown, no gauge. */
|
|
10
|
+
max?: number;
|
|
11
|
+
thresholds?: UsageMeterThresholds;
|
|
12
|
+
label: string;
|
|
13
|
+
/** Formats `value` and `max` for display (`intl.formatNumber`, bytes, credits). */
|
|
14
|
+
formatValue(value: number): string;
|
|
15
|
+
}
|
|
16
|
+
/** How full the meter is, against its thresholds. */
|
|
17
|
+
export declare enum UsageLevel {
|
|
18
|
+
Normal = "normal",
|
|
19
|
+
Warning = "warning",
|
|
20
|
+
Danger = "danger"
|
|
21
|
+
}
|
|
22
|
+
/** The level of a consumption share, against the thresholds (none: always normal). */
|
|
23
|
+
export declare const usageLevel: (share: number, thresholds?: UsageMeterThresholds) => UsageLevel;
|
|
24
|
+
/**
|
|
25
|
+
* A consumption against its ceiling (storage, credits, quota): the label, the value and the
|
|
26
|
+
* ceiling in mono, and a gauge filled with the accent, then the warning and danger colors once
|
|
27
|
+
* the share reaches `thresholds`. The gauge is a `meter` named by the label, its value text the
|
|
28
|
+
* formatted "value of max"; a consumption above the ceiling fills it whole. Without `max`, the
|
|
29
|
+
* value alone.
|
|
30
|
+
*/
|
|
31
|
+
export declare function UsageMeter({ value, max, thresholds, label, formatValue, }: UsageMeterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/** The three scopes a context can take. */
|
|
3
|
+
export declare enum ContextKind {
|
|
4
|
+
Personal = "personal",
|
|
5
|
+
Organization = "organization",
|
|
6
|
+
Project = "project"
|
|
7
|
+
}
|
|
8
|
+
/** The selected context: the personal space, a whole organization, or one of its projects. */
|
|
9
|
+
export type ContextValue = {
|
|
10
|
+
kind: ContextKind.Personal;
|
|
11
|
+
} | {
|
|
12
|
+
kind: ContextKind.Organization;
|
|
13
|
+
organizationId: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: ContextKind.Project;
|
|
16
|
+
organizationId: string;
|
|
17
|
+
projectId: string;
|
|
18
|
+
};
|
|
19
|
+
/** A project of an organization. */
|
|
20
|
+
export interface ContextSelectorProject {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
/** A `ProjectAvatar`, for instance; a folder icon without it. */
|
|
24
|
+
avatar?: ReactNode;
|
|
25
|
+
}
|
|
26
|
+
/** An organization the user belongs to, with its projects. */
|
|
27
|
+
export interface ContextSelectorOrganization {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
/** An `OrganizationAvatar`, for instance; a building icon without it. */
|
|
31
|
+
avatar?: ReactNode;
|
|
32
|
+
projects?: ContextSelectorProject[];
|
|
33
|
+
}
|
|
34
|
+
/** The personal space. */
|
|
35
|
+
export interface ContextSelectorPersonal {
|
|
36
|
+
/** The user's alias, for instance; « Mon espace » without it. */
|
|
37
|
+
label?: string;
|
|
38
|
+
/** A `UserAvatar`, for instance; a person icon without it. */
|
|
39
|
+
avatar?: ReactNode;
|
|
40
|
+
}
|
|
41
|
+
export interface ContextSelectorData {
|
|
42
|
+
personal: ContextSelectorPersonal;
|
|
43
|
+
organizations: ContextSelectorOrganization[];
|
|
44
|
+
}
|
|
45
|
+
export interface ContextSelectorProps {
|
|
46
|
+
data: ContextSelectorData;
|
|
47
|
+
value: ContextValue;
|
|
48
|
+
onChange(next: ContextValue): void;
|
|
49
|
+
/** Label above the field, its accessible name. */
|
|
50
|
+
label: string;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The scope picker of a page: the personal space first, then one group per organization (headed
|
|
55
|
+
* by its name) holding an entry for the whole organization and one per project. The field shows
|
|
56
|
+
* the avatar of the selected context; typing filters the entries. Avatars are passed by the host
|
|
57
|
+
* (they need its storage URLs) and are hidden from assistive technology: the label names each
|
|
58
|
+
* entry.
|
|
59
|
+
*/
|
|
60
|
+
export declare function ContextSelector({ data, value, onChange, label, disabled, }: ContextSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface CopyFieldProps {
|
|
2
|
+
value: string;
|
|
3
|
+
/** Hides the value behind dots until the user reveals it; the copy button still copies it. */
|
|
4
|
+
masked?: boolean;
|
|
5
|
+
/** Called each time the user reveals a masked value. */
|
|
6
|
+
onReveal?(): void;
|
|
7
|
+
/** Label of the copy button, named after what it copies ("Copier la clé"). */
|
|
8
|
+
copyLabel: string;
|
|
9
|
+
}
|
|
10
|
+
/** How long the copy button shows its check mark after a copy, in ms. */
|
|
11
|
+
export declare const COPY_FEEDBACK_MS = 2000;
|
|
12
|
+
/**
|
|
13
|
+
* A value to copy (API key, connection identifier): shown in mono in a read-only box, with a
|
|
14
|
+
* button that copies it to the clipboard. Masked, the value is replaced by dots and a toggle
|
|
15
|
+
* reveals it (calling `onReveal`). The outcome of a copy is announced in a polite live region; a
|
|
16
|
+
* success turns the copy icon into a check mark for a moment, a failure is also written under the
|
|
17
|
+
* field.
|
|
18
|
+
*/
|
|
19
|
+
export declare function CopyField({ value, masked, onReveal, copyLabel, }: CopyFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Accept } from 'react-dropzone';
|
|
3
|
+
import { CloudImportWiring } from '../../../hooks/cloud-picker.types';
|
|
4
|
+
export interface DropZoneProps {
|
|
5
|
+
/** The files dropped or picked from the device, once the size and type checks passed. */
|
|
6
|
+
onDrop(files: File[]): void;
|
|
7
|
+
/** Several files at once. Defaults to `true`. */
|
|
8
|
+
multiple?: boolean;
|
|
9
|
+
/** Accepted types, as `react-dropzone` reads them: `{ 'image/*': ['.png', '.jpg'] }`. */
|
|
10
|
+
accept?: Accept;
|
|
11
|
+
/** Largest accepted file, in bytes; shown under the zone. */
|
|
12
|
+
maxSize?: number;
|
|
13
|
+
/** Title above the zone, which names it. */
|
|
14
|
+
title?: string;
|
|
15
|
+
/**
|
|
16
|
+
* AbyssCloud picker (from `useCloudPicker`) plus the import action, which receives the Space
|
|
17
|
+
* the files were picked from. The AbyssCloud entry exists only when this is passed.
|
|
18
|
+
*/
|
|
19
|
+
cloudImport?: CloudImportWiring;
|
|
20
|
+
/** Replaces the icon and the prompt inside the zone (a preview of the current file, say). */
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A zone to drop files on, with a button that opens the device's file picker and, when
|
|
25
|
+
* `cloudImport` is wired, an « Importer depuis AbyssCloud » entry. Files larger than `maxSize` and
|
|
26
|
+
* types `accept` refuses are left out, and the reason is written under the zone (`role="alert"`);
|
|
27
|
+
* a single file that is too large is not handed over at all. Cloud files arrive through
|
|
28
|
+
* `cloudImport.onImport`, never through `onDrop`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function DropZone({ onDrop, multiple, accept, maxSize, title, cloudImport, children, }: DropZoneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface FormFieldProps {
|
|
3
|
+
label: string;
|
|
4
|
+
/** A hint under the field, always shown. */
|
|
5
|
+
help?: ReactNode;
|
|
6
|
+
/** The error message: the field turns to the danger color and is marked invalid. */
|
|
7
|
+
error?: ReactNode;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* One MUI control of the input family, without a label of its own: `OutlinedInput`,
|
|
11
|
+
* `InputBase`, or `Select`.
|
|
12
|
+
*/
|
|
13
|
+
children: ReactElement<FieldControlProps>;
|
|
14
|
+
}
|
|
15
|
+
/** What the field gives its control so that the label, the hint and the error reach it. */
|
|
16
|
+
interface FieldControlProps {
|
|
17
|
+
id?: string;
|
|
18
|
+
'aria-describedby'?: string;
|
|
19
|
+
labelId?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A labelled form field (mock-up `.field`): the label above the control, a hint and an error
|
|
23
|
+
* under it. The control gets the `id` the label points to (its own `id` when it has one) and an
|
|
24
|
+
* `aria-describedby` listing the hint and the error; a `Select` also gets the `labelId` that
|
|
25
|
+
* names its listbox button. The error and `required` state reach the control through the MUI form
|
|
26
|
+
* control: red border, `aria-invalid`, the `required` attribute and the asterisk of the label.
|
|
27
|
+
*/
|
|
28
|
+
export declare function FormField({ label, help, error, required, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ChangeEvent, MouseEvent, ReactElement } from 'react';
|
|
2
|
+
import { CloudImportWiring } from '../../../hooks/cloud-picker.types';
|
|
3
|
+
/** What the trigger receives: it opens the menu of sources. */
|
|
4
|
+
interface TriggerProps {
|
|
5
|
+
onClick?(event: MouseEvent<HTMLElement>): void;
|
|
6
|
+
'aria-haspopup'?: 'menu';
|
|
7
|
+
'aria-expanded'?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ImportButtonProps {
|
|
10
|
+
/** The trigger, a button: it opens the menu of sources. */
|
|
11
|
+
children: ReactElement<TriggerProps>;
|
|
12
|
+
/** An import is running: the entries are disabled. */
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
/** « Mon ordinateur »: receives the change event of the file input. */
|
|
15
|
+
handleFileUpload(event: ChangeEvent<HTMLInputElement>): Promise<void>;
|
|
16
|
+
/** « Lien URL »: the entry exists only when this is passed. */
|
|
17
|
+
handleUploadFromUrl?(url: string): Promise<void>;
|
|
18
|
+
multiple?: boolean;
|
|
19
|
+
/** Largest file the AbyssCloud picker lists, in bytes. */
|
|
20
|
+
maxSize?: number;
|
|
21
|
+
/** Accepted types, as the HTML `accept` attribute lists them. */
|
|
22
|
+
accept?: string[];
|
|
23
|
+
/** AbyssCloud picker plus the import action: the « AbyssCloud » entry exists only when passed. */
|
|
24
|
+
cloudImport?: CloudImportWiring;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Wraps a trigger and opens a menu of upload sources: the device's files, a link (with
|
|
28
|
+
* `handleUploadFromUrl`) and AbyssCloud (with `cloudImport`). The link opens a small modal whose
|
|
29
|
+
* address is checked before it can be confirmed; it closes once the import succeeded and says so
|
|
30
|
+
* when it failed. AbyssCloud opens `ImportFromCloudModal`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ImportButton({ children, isLoading, handleFileUpload, handleUploadFromUrl, multiple, maxSize, accept, cloudImport, }: ImportButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface NumberFieldProps {
|
|
2
|
+
label: string;
|
|
3
|
+
/** The number shown; `null` for an empty field. */
|
|
4
|
+
value: number | null;
|
|
5
|
+
/** Called with each number typed, `null` once emptied, and the clamped, rounded number on leave. */
|
|
6
|
+
onChange(value: number | null): void;
|
|
7
|
+
/** Digits kept after the decimal mark: 0 for a quantity (default), 2 for an amount. */
|
|
8
|
+
decimals?: number;
|
|
9
|
+
/** Lowest number kept when the field is left; 0 by default. */
|
|
10
|
+
min?: number;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
/** Unit or currency shown at the end of the field (`€`, `Go`). */
|
|
13
|
+
adornment?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A labelled number input that follows the language of the viewer: « 1 234,50 » in French,
|
|
17
|
+
* « 1,234.50 » in English. While focused it shows what is typed (either decimal mark is read);
|
|
18
|
+
* on leaving it clamps to `min`, rounds to `decimals` and formats again. A value changed from
|
|
19
|
+
* outside (a linked field) is shown at once unless the field is being edited.
|
|
20
|
+
*/
|
|
21
|
+
export declare function NumberField({ label, value, onChange, decimals, min, disabled, adornment, }: NumberFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The grouping and decimal separators of a locale. */
|
|
2
|
+
export interface LocaleSeparators {
|
|
3
|
+
group: string;
|
|
4
|
+
decimal: string;
|
|
5
|
+
}
|
|
6
|
+
/** The grouping and decimal separators of a locale, read from `Intl` (never hardcoded). */
|
|
7
|
+
export declare const getLocaleSeparators: (locale: string) => LocaleSeparators;
|
|
8
|
+
/**
|
|
9
|
+
* Reads a typed number: the grouping separators of the locale (and the usual whitespace) are
|
|
10
|
+
* dropped, then « , » or « . » is the decimal mark, so « 50,5 » and « 50.5 » give the same number.
|
|
11
|
+
* Empty or non-numeric text gives `null`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const parseNumberInput: (raw: string, separators: LocaleSeparators) => number | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface SettingsRowProps {
|
|
3
|
+
label: string;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
/** The control of the setting: a switch, a select, a button. */
|
|
6
|
+
control: ReactNode;
|
|
7
|
+
/** `id` of the form element inside `control`: the label then labels it (`<label for>`). */
|
|
8
|
+
htmlFor?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* One setting of a settings list: its label and description on the left, its
|
|
12
|
+
* control on the right, rows split by a 1 px rule. Below 768 px the control goes under the text.
|
|
13
|
+
* The row is a `group` named by the label and described by the description; with `htmlFor` the
|
|
14
|
+
* label also labels the form element of the control.
|
|
15
|
+
*/
|
|
16
|
+
export declare function SettingsRow({ label, description, control, htmlFor, }: SettingsRowProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,3 +3,10 @@ export * from './DateField/DateField';
|
|
|
3
3
|
export * from './DateRangeField/DateRangeField';
|
|
4
4
|
export * from './ColorField/ColorField';
|
|
5
5
|
export * from './SegmentedControl/SegmentedControl';
|
|
6
|
+
export * from './FormField/FormField';
|
|
7
|
+
export * from './NumberField/NumberField';
|
|
8
|
+
export * from './SettingsRow/SettingsRow';
|
|
9
|
+
export * from './CopyField/CopyField';
|
|
10
|
+
export * from './ContextSelector/ContextSelector';
|
|
11
|
+
export * from './DropZone/DropZone';
|
|
12
|
+
export * from './ImportButton/ImportButton';
|
|
@@ -10,6 +10,8 @@ export declare enum MenuSeparator {
|
|
|
10
10
|
export interface MenuItem {
|
|
11
11
|
id: string;
|
|
12
12
|
label: string;
|
|
13
|
+
/** Secondary line under the label; it describes the item (`aria-describedby`) without renaming it. */
|
|
14
|
+
description?: string;
|
|
13
15
|
icon?: ReactNode;
|
|
14
16
|
/** Shortcut hint shown at the end of the row, such as `⌘D`; the host binds the key itself. */
|
|
15
17
|
shortcut?: string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Side of an avatar when the host gives none, in px. */
|
|
2
|
+
export declare const AVATAR_DEFAULT_SIZE = 32;
|
|
3
|
+
export interface UserAvatarProps {
|
|
4
|
+
userId: string;
|
|
5
|
+
/** The user's alias: accessible name, and its initial while there is no picture. */
|
|
6
|
+
alias: string;
|
|
7
|
+
/** Whether the user has uploaded a picture; without one, no request is made. */
|
|
8
|
+
hasThumbnail: boolean;
|
|
9
|
+
/** Changes when the picture does (a timestamp after an upload): appended to the URL. */
|
|
10
|
+
cache?: string;
|
|
11
|
+
/** Side in px. Defaults to `AVATAR_DEFAULT_SIZE`. */
|
|
12
|
+
size?: number;
|
|
13
|
+
/** URL of a user's picture, from the host's storage helpers. */
|
|
14
|
+
getProfilePictureUrl(userId: string): string;
|
|
15
|
+
}
|
|
16
|
+
/** A person: their picture in a disc, or the initial of their alias. */
|
|
17
|
+
export declare function UserAvatar({ userId, alias, hasThumbnail, cache, size, getProfilePictureUrl, }: UserAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export interface OrganizationAvatarProps {
|
|
19
|
+
orgId: string;
|
|
20
|
+
/** The organization's name: accessible name, and its initial while there is no logo. */
|
|
21
|
+
name: string;
|
|
22
|
+
hasThumbnail: boolean;
|
|
23
|
+
cache?: string;
|
|
24
|
+
size?: number;
|
|
25
|
+
/** URL of an organization's logo, from the host's storage helpers. */
|
|
26
|
+
getLogoUrl(orgId: string): string;
|
|
27
|
+
}
|
|
28
|
+
/** An organization: its logo in a rounded square, or the initial of its name. */
|
|
29
|
+
export declare function OrganizationAvatar({ orgId, name, hasThumbnail, cache, size, getLogoUrl, }: OrganizationAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export interface ProjectAvatarProps {
|
|
31
|
+
projectId: string;
|
|
32
|
+
/** The project's title: accessible name, and its initial while there is no picture. */
|
|
33
|
+
title: string;
|
|
34
|
+
hasThumbnail: boolean;
|
|
35
|
+
cache?: string;
|
|
36
|
+
size?: number;
|
|
37
|
+
/** URL of a project's picture, from the host's storage helpers. */
|
|
38
|
+
getProjectPictureUrl(projectId: string): string;
|
|
39
|
+
}
|
|
40
|
+
/** A project: its picture in a rounded square, or the initial of its title. */
|
|
41
|
+
export declare function ProjectAvatar({ projectId, title, hasThumbnail, cache, size, getProjectPictureUrl, }: ProjectAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export declare enum CalloutSeverity {
|
|
3
|
+
Info = "info",
|
|
4
|
+
Success = "success",
|
|
5
|
+
Warning = "warning",
|
|
6
|
+
Danger = "danger"
|
|
7
|
+
}
|
|
8
|
+
export interface CalloutProps {
|
|
9
|
+
severity: CalloutSeverity;
|
|
10
|
+
title?: string;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
/** A button or a link, placed after the text (under it below 768 px). */
|
|
13
|
+
action?: ReactNode;
|
|
14
|
+
/** Shows a close button; the host removes the callout. */
|
|
15
|
+
onClose?(): void;
|
|
16
|
+
/** Replaces the icon of the severity. */
|
|
17
|
+
icon?: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A banner inside a page (overdue invoice, trial, quota reached): the soft fill and 1 px border of
|
|
21
|
+
* its severity, the severity icon, an optional title, the text, an optional action and an
|
|
22
|
+
* optional close button. A danger callout is an `alert` (announced as soon as it appears), the
|
|
23
|
+
* others a `status`; a titled callout is named by its title.
|
|
24
|
+
*/
|
|
25
|
+
export declare function Callout({ severity, title, children, action, onClose, icon, }: CalloutProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The two rows of tabs: the page navigation, and a quieter sub-navigation under it. */
|
|
2
|
+
export declare enum TabsVariant {
|
|
3
|
+
Primary = "primary",
|
|
4
|
+
Secondary = "secondary"
|
|
5
|
+
}
|
|
6
|
+
export interface TabItem<V extends string = string> {
|
|
7
|
+
value: V;
|
|
8
|
+
label: string;
|
|
9
|
+
/** Route inside the app: the tab becomes a router link. */
|
|
10
|
+
to?: string;
|
|
11
|
+
/** A count (formatted with the viewer's locale) or a short text after the label. */
|
|
12
|
+
badge?: number | string;
|
|
13
|
+
/** Left out of the row, as if absent (an entry the viewer has no right to). */
|
|
14
|
+
hidden?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface TabsProps<V extends string = string> {
|
|
17
|
+
items: TabItem<V>[];
|
|
18
|
+
/** Value of the selected tab. */
|
|
19
|
+
value: V;
|
|
20
|
+
/** Called with the value of the tab the user activates (click, Enter, Space). */
|
|
21
|
+
onChange?(value: V): void;
|
|
22
|
+
variant: TabsVariant;
|
|
23
|
+
'aria-label': string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A row of tabs (mock-up `.tabs`): the primary variant underlines the selected tab with the
|
|
27
|
+
* accent over a 1 px rule, the secondary one fills it with `bg.raised`. A tab with `to` is a
|
|
28
|
+
* router link (the page navigation of the account), any other a button. A `tablist` with one tab
|
|
29
|
+
* stop, on the selected tab: the arrow keys move the focus between tabs (wrapping), Home and End
|
|
30
|
+
* jump to the ends, Enter or Space activates. The row scrolls sideways when the tabs do not fit,
|
|
31
|
+
* with a fade at its end while tabs are left beyond it, and keeps the selected or focused tab in
|
|
32
|
+
* view, including when the row is first laid out or resized. Below 768 px every tab is 44 px tall.
|
|
33
|
+
*/
|
|
34
|
+
export declare function Tabs<V extends string>({ items, value, onChange, variant, 'aria-label': ariaLabel, }: TabsProps<V>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cookie-consent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as e, c as a, C as n, D as C, R as i, V as t, d as r, f as A, r as k, e as c, u as l, b, a as f, w as u } from "./AbyssCookieConsentProvider-
|
|
2
|
-
import { C as E } from "./CookieConsentSettings.component-
|
|
1
|
+
import { A as e, c as a, C as n, D as C, R as i, V as t, d as r, f as A, r as k, e as c, u as l, b, a as f, w as u } from "./AbyssCookieConsentProvider-B-PlGbFf.js";
|
|
2
|
+
import { C as E } from "./CookieConsentSettings.component-DEGCDEJW.js";
|
|
3
3
|
export {
|
|
4
4
|
e as AbyssCookieConsentProvider,
|
|
5
5
|
a as COOKIE_NAME,
|