@crisp-ui-kit/crisp 0.57.2 → 0.57.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assigneepicker.css +13 -0
- package/dist/assigneepicker.d.ts +7 -0
- package/dist/assigneepicker.layered.css +15 -0
- package/dist/button.css +3 -0
- package/dist/button.d.ts +2 -2
- package/dist/button.layered.css +3 -0
- package/dist/chip.css +1 -1
- package/dist/chip.layered.css +1 -1
- package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/cjs/components/button/button.recipe.js +33 -0
- package/dist/cjs/components/chip/chip.recipe.js +3 -1
- package/dist/cjs/components/datatable/datatable.js +6 -3
- package/dist/cjs/components/datatable/datatable.recipe.js +45 -6
- package/dist/cjs/components/datepickerfield/datepickerfield.js +2 -2
- package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +16 -3
- package/dist/cjs/components/menu/menu.js +65 -9
- package/dist/cjs/components/multiselect/multiselect.js +3 -0
- package/dist/cjs/components/multiselect/multiselect.recipe.js +18 -0
- package/dist/cjs/components/select/select.js +2 -2
- package/dist/cjs/components/select/select.recipe.js +19 -0
- package/dist/cjs/components/table/table.recipe.js +7 -1
- package/dist/cjs/core/floating-portal.js +7 -4
- package/dist/cjs/core/index.js +2 -1
- package/dist/cjs/core/place-floating.js +38 -0
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/product/assigneepicker/assigneepicker.js +127 -0
- package/dist/cjs/product/assigneepicker/assigneepicker.recipe.js +36 -0
- package/dist/cjs/product/assigneepicker/index.js +7 -0
- package/dist/cjs/product/inbox/inbox.js +11 -3
- package/dist/cjs/product/notesgallery/index.js +7 -0
- package/dist/cjs/product/notesgallery/notesgallery.js +80 -0
- package/dist/cjs/product/notesgallery/notesgallery.recipe.js +46 -0
- package/dist/cjs/product/objectpagemenu/index.js +17 -0
- package/dist/cjs/product/objectpagemenu/objectpagemenu.js +26 -0
- package/dist/cjs/product/objectpagemenu/objectpagemenu.recipe.js +30 -0
- package/dist/cjs/product/objectsettings/objectsettings.js +107 -14
- package/dist/cjs/product/recordpage/index.js +2 -1
- package/dist/cjs/product/recordpage/recordpage.js +112 -7
- package/dist/cjs/product/recordpage/recordpage.recipe.js +63 -0
- package/dist/cjs/product/recordpicker/index.js +7 -0
- package/dist/cjs/product/recordpicker/recordpicker.js +100 -0
- package/dist/cjs/product/recordpicker/recordpicker.recipe.js +36 -0
- package/dist/cjs/product/savedviews/index.js +2 -1
- package/dist/cjs/product/savedviews/savedviews.js +22 -0
- package/dist/cjs/product/savedviews/savedviews.recipe.js +47 -0
- package/dist/cjs/product/share/index.js +7 -0
- package/dist/cjs/product/share/share.js +179 -0
- package/dist/cjs/product/share/share.recipe.js +114 -0
- package/dist/cjs/product/shortcutssheet/index.js +17 -0
- package/dist/cjs/product/shortcutssheet/shortcutssheet.js +125 -0
- package/dist/cjs/product/shortcutssheet/shortcutssheet.recipe.js +50 -0
- package/dist/cjs/product/taskeditpopover/index.js +7 -0
- package/dist/cjs/product/taskeditpopover/taskeditpopover.js +159 -0
- package/dist/cjs/product/taskeditpopover/taskeditpopover.recipe.js +68 -0
- package/dist/cjs/product/workspaceswitchermenu/index.js +17 -0
- package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.js +38 -0
- package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +34 -0
- package/dist/cjs/tokens/palette.js +27 -0
- package/dist/cjs/tokens/semantic.js +20 -0
- package/dist/datatable.css +50 -11
- package/dist/datatable.layered.css +50 -11
- package/dist/datepickerfield.css +8 -2
- package/dist/datepickerfield.d.ts +2 -2
- package/dist/datepickerfield.layered.css +8 -2
- package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/esm/components/button/button.recipe.js +33 -0
- package/dist/esm/components/chip/chip.recipe.js +3 -1
- package/dist/esm/components/datatable/datatable.js +6 -3
- package/dist/esm/components/datatable/datatable.recipe.js +45 -6
- package/dist/esm/components/datepickerfield/datepickerfield.js +2 -2
- package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +16 -3
- package/dist/esm/components/menu/menu.js +64 -8
- package/dist/esm/components/multiselect/multiselect.js +3 -0
- package/dist/esm/components/multiselect/multiselect.recipe.js +18 -0
- package/dist/esm/components/select/select.js +2 -2
- package/dist/esm/components/select/select.recipe.js +19 -0
- package/dist/esm/components/table/table.recipe.js +7 -1
- package/dist/esm/core/floating-portal.js +7 -4
- package/dist/esm/core/index.js +1 -1
- package/dist/esm/core/place-floating.js +37 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/product/assigneepicker/assigneepicker.js +91 -0
- package/dist/esm/product/assigneepicker/assigneepicker.recipe.js +33 -0
- package/dist/esm/product/assigneepicker/index.js +2 -0
- package/dist/esm/product/inbox/inbox.js +11 -3
- package/dist/esm/product/notesgallery/index.js +2 -0
- package/dist/esm/product/notesgallery/notesgallery.js +44 -0
- package/dist/esm/product/notesgallery/notesgallery.recipe.js +43 -0
- package/dist/esm/product/objectpagemenu/index.js +1 -0
- package/dist/esm/product/objectpagemenu/objectpagemenu.js +23 -0
- package/dist/esm/product/objectpagemenu/objectpagemenu.recipe.js +27 -0
- package/dist/esm/product/objectsettings/objectsettings.js +106 -13
- package/dist/esm/product/recordpage/index.js +1 -1
- package/dist/esm/product/recordpage/recordpage.js +112 -8
- package/dist/esm/product/recordpage/recordpage.recipe.js +63 -0
- package/dist/esm/product/recordpicker/index.js +2 -0
- package/dist/esm/product/recordpicker/recordpicker.js +64 -0
- package/dist/esm/product/recordpicker/recordpicker.recipe.js +33 -0
- package/dist/esm/product/savedviews/index.js +1 -1
- package/dist/esm/product/savedviews/savedviews.js +22 -1
- package/dist/esm/product/savedviews/savedviews.recipe.js +47 -0
- package/dist/esm/product/share/index.js +2 -0
- package/dist/esm/product/share/share.js +143 -0
- package/dist/esm/product/share/share.recipe.js +111 -0
- package/dist/esm/product/shortcutssheet/index.js +1 -0
- package/dist/esm/product/shortcutssheet/shortcutssheet.js +88 -0
- package/dist/esm/product/shortcutssheet/shortcutssheet.recipe.js +47 -0
- package/dist/esm/product/taskeditpopover/index.js +2 -0
- package/dist/esm/product/taskeditpopover/taskeditpopover.js +123 -0
- package/dist/esm/product/taskeditpopover/taskeditpopover.recipe.js +65 -0
- package/dist/esm/product/workspaceswitchermenu/index.js +1 -0
- package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.js +35 -0
- package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +31 -0
- package/dist/esm/tokens/palette.js +27 -0
- package/dist/esm/tokens/semantic.js +20 -0
- package/dist/multiselect.css +18 -0
- package/dist/multiselect.layered.css +18 -0
- package/dist/native/tokens.d.ts +1 -1
- package/dist/native/tokens.js +56 -4
- package/dist/notesgallery.css +15 -0
- package/dist/notesgallery.d.ts +7 -0
- package/dist/notesgallery.layered.css +17 -0
- package/dist/objectpagemenu.css +3 -0
- package/dist/objectpagemenu.d.ts +7 -0
- package/dist/objectpagemenu.layered.css +5 -0
- package/dist/recordpage.css +59 -0
- package/dist/recordpage.layered.css +59 -0
- package/dist/recordpicker.css +13 -0
- package/dist/recordpicker.d.ts +7 -0
- package/dist/recordpicker.layered.css +15 -0
- package/dist/savedviews.css +47 -0
- package/dist/savedviews.layered.css +47 -0
- package/dist/select.css +19 -0
- package/dist/select.layered.css +19 -0
- package/dist/share.css +84 -0
- package/dist/share.d.ts +7 -0
- package/dist/share.layered.css +86 -0
- package/dist/shortcutssheet.css +24 -0
- package/dist/shortcutssheet.d.ts +7 -0
- package/dist/shortcutssheet.layered.css +26 -0
- package/dist/styles.css +438 -16
- package/dist/styles.layered.css +438 -16
- package/dist/table.css +7 -2
- package/dist/table.layered.css +7 -2
- package/dist/taskeditpopover.css +36 -0
- package/dist/taskeditpopover.d.ts +7 -0
- package/dist/taskeditpopover.layered.css +38 -0
- package/dist/tokens.css +26 -0
- package/dist/tokens.json +56 -4
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +9 -1
- package/dist/types/components/button/button.d.ts +2 -0
- package/dist/types/components/button/button.recipe.d.ts +12 -0
- package/dist/types/components/chip/chip.recipe.d.ts +1 -1
- package/dist/types/components/datatable/datatable.d.ts +8 -0
- package/dist/types/components/datepickerfield/datepickerfield.d.ts +4 -1
- package/dist/types/components/datepickerfield/datepickerfield.recipe.d.ts +18 -3
- package/dist/types/components/menu/menu.d.ts +50 -7
- package/dist/types/components/multiselect/multiselect.d.ts +9 -0
- package/dist/types/components/select/select.d.ts +10 -0
- package/dist/types/core/floating-portal.d.ts +6 -5
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/place-floating.d.ts +37 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/product/assigneepicker/assigneepicker.d.ts +36 -0
- package/dist/types/product/assigneepicker/assigneepicker.recipe.d.ts +3 -0
- package/dist/types/product/assigneepicker/index.d.ts +2 -0
- package/dist/types/product/inbox/inbox.d.ts +13 -1
- package/dist/types/product/notesgallery/index.d.ts +2 -0
- package/dist/types/product/notesgallery/notesgallery.d.ts +54 -0
- package/dist/types/product/notesgallery/notesgallery.recipe.d.ts +3 -0
- package/dist/types/product/objectpagemenu/index.d.ts +1 -0
- package/dist/types/product/objectpagemenu/objectpagemenu.d.ts +40 -0
- package/dist/types/product/objectpagemenu/objectpagemenu.recipe.d.ts +17 -0
- package/dist/types/product/objectsettings/objectsettings.d.ts +71 -15
- package/dist/types/product/recordpage/index.d.ts +1 -1
- package/dist/types/product/recordpage/recordpage.d.ts +142 -1
- package/dist/types/product/recordpicker/index.d.ts +2 -0
- package/dist/types/product/recordpicker/recordpicker.d.ts +38 -0
- package/dist/types/product/recordpicker/recordpicker.recipe.d.ts +3 -0
- package/dist/types/product/savedviews/index.d.ts +1 -1
- package/dist/types/product/savedviews/savedviews.d.ts +36 -0
- package/dist/types/product/share/index.d.ts +2 -0
- package/dist/types/product/share/share.d.ts +85 -0
- package/dist/types/product/share/share.recipe.d.ts +3 -0
- package/dist/types/product/shortcutssheet/index.d.ts +1 -0
- package/dist/types/product/shortcutssheet/shortcutssheet.d.ts +49 -0
- package/dist/types/product/shortcutssheet/shortcutssheet.recipe.d.ts +3 -0
- package/dist/types/product/taskeditpopover/index.d.ts +2 -0
- package/dist/types/product/taskeditpopover/taskeditpopover.d.ts +67 -0
- package/dist/types/product/taskeditpopover/taskeditpopover.recipe.d.ts +3 -0
- package/dist/types/product/workspaceswitchermenu/index.d.ts +1 -0
- package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.d.ts +54 -0
- package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.recipe.d.ts +19 -0
- package/dist/types/tokens/contract.d.ts +13 -0
- package/dist/types/tokens/palette.d.ts +52 -0
- package/dist/types/tokens/semantic.d.ts +20 -0
- package/dist/workspaceswitchermenu.css +4 -0
- package/dist/workspaceswitchermenu.d.ts +7 -0
- package/dist/workspaceswitchermenu.layered.css +6 -0
- package/package.json +41 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type AssigneePickerUser = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
/** A photo URL; falls back to a per-name hashed-colour initials tile,
|
|
6
|
+
* same as `PersonChip`'s own. */
|
|
7
|
+
avatar?: string;
|
|
8
|
+
};
|
|
9
|
+
export type AssigneePickerProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
|
|
10
|
+
/** Candidate users, already excluding nobody in particular -- the
|
|
11
|
+
* current `assignee` is filtered out of the list automatically. */
|
|
12
|
+
users: AssigneePickerUser[];
|
|
13
|
+
/** The task's current single assignee, or `null`/omitted for none. */
|
|
14
|
+
assignee?: AssigneePickerUser | null;
|
|
15
|
+
onAssigneeChange?: (user: AssigneePickerUser | null) => void;
|
|
16
|
+
/** Controlled search query. Omit to let the picker manage it. */
|
|
17
|
+
query?: string;
|
|
18
|
+
onQueryChange?: (query: string) => void;
|
|
19
|
+
searchLabel?: string;
|
|
20
|
+
removeLabel?: string;
|
|
21
|
+
emptyLabel?: React.ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The picker behind a task's "Assigned to" chip -- measured live on
|
|
26
|
+
* app.attio.com's Tasks page ("Edit task" -> "Assigned to You" -> its own
|
|
27
|
+
* sub-popover, `Popover`-sized at the same measured 350px): a "Find a
|
|
28
|
+
* user..." search, the current assignee as a removable pill, then a plain
|
|
29
|
+
* option list, or "No users" when nothing matches. Attio's task assignment
|
|
30
|
+
* is single-user (one pill, replaced by picking another), unlike a
|
|
31
|
+
* multi-value field.
|
|
32
|
+
*/
|
|
33
|
+
export declare function AssigneePicker({ users, assignee, onAssigneeChange, query: queryProp, onQueryChange, searchLabel: searchLabelProp, removeLabel: removeLabelProp, emptyLabel: emptyLabelProp, className, ...rest }: AssigneePickerProps): React.JSX.Element;
|
|
34
|
+
export declare namespace AssigneePicker {
|
|
35
|
+
var displayName: string;
|
|
36
|
+
}
|
|
@@ -15,6 +15,14 @@ export type InboxTab = {
|
|
|
15
15
|
label: React.ReactNode;
|
|
16
16
|
count?: number;
|
|
17
17
|
disabled?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Empty-state copy for this tab only, e.g. Notifications vs. Requests
|
|
20
|
+
* ("Requests from other users will be displayed here."). Falls back to
|
|
21
|
+
* the instance-level `emptyTitle`/`emptySubtitle`/`emptyAction` when unset.
|
|
22
|
+
*/
|
|
23
|
+
emptyTitle?: React.ReactNode;
|
|
24
|
+
emptySubtitle?: React.ReactNode;
|
|
25
|
+
emptyAction?: React.ReactNode;
|
|
18
26
|
};
|
|
19
27
|
export type InboxProps = Omit<React.ComponentPropsWithoutRef<"div">, "children" | "title"> & {
|
|
20
28
|
notifications?: InboxNotification[];
|
|
@@ -23,7 +31,11 @@ export type InboxProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"
|
|
|
23
31
|
tabs?: InboxTab[];
|
|
24
32
|
activeTab?: string;
|
|
25
33
|
onTabChange?: (id: string) => void;
|
|
26
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Empty-state text (shown when there are no notifications). A tab in
|
|
36
|
+
* `tabs` that sets its own `emptyTitle`/`emptySubtitle` overrides this
|
|
37
|
+
* for that tab only.
|
|
38
|
+
*/
|
|
27
39
|
emptyTitle?: React.ReactNode;
|
|
28
40
|
emptySubtitle?: React.ReactNode;
|
|
29
41
|
/** Optional action under the empty state (e.g. a Settings button). */
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type NotesGalleryNote = {
|
|
3
|
+
id: string;
|
|
4
|
+
/** Rendered in the card's leading author-row slot — Attio's own is a
|
|
5
|
+
* linked-record icon+name, not the note's author (that's the footer). */
|
|
6
|
+
linkedRecord?: React.ReactNode;
|
|
7
|
+
title: React.ReactNode;
|
|
8
|
+
excerpt?: React.ReactNode;
|
|
9
|
+
/** Footer row content, e.g. an avatar+name. */
|
|
10
|
+
author?: React.ReactNode;
|
|
11
|
+
date?: React.ReactNode;
|
|
12
|
+
onClick?: () => void;
|
|
13
|
+
};
|
|
14
|
+
export type NotesGalleryGroup = {
|
|
15
|
+
id: string;
|
|
16
|
+
/** e.g. "Created last month". */
|
|
17
|
+
label: React.ReactNode;
|
|
18
|
+
count: number;
|
|
19
|
+
notes: NotesGalleryNote[];
|
|
20
|
+
};
|
|
21
|
+
export type NotesGalleryProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
|
|
22
|
+
notesCount: number;
|
|
23
|
+
templatesCount: number;
|
|
24
|
+
/** "notes" | "templates" (or any consumer-chosen values via `tabValues`). */
|
|
25
|
+
activeTab?: string;
|
|
26
|
+
defaultActiveTab?: string;
|
|
27
|
+
onActiveTabChange?: (value: string) => void;
|
|
28
|
+
notesLabel?: string;
|
|
29
|
+
templatesLabel?: string;
|
|
30
|
+
/** e.g. a "Sorted by Creation date" trigger. */
|
|
31
|
+
leading?: React.ReactNode;
|
|
32
|
+
/** e.g. a list/grid `ViewToggle`, "View settings", "+ New note". */
|
|
33
|
+
trailing?: React.ReactNode;
|
|
34
|
+
favoritesLabel?: string;
|
|
35
|
+
/** Favorited note cards. Omit (or pass an empty array) for the measured
|
|
36
|
+
* dashed empty panel. */
|
|
37
|
+
favorites?: NotesGalleryNote[];
|
|
38
|
+
favoritesEmptyLabel?: string;
|
|
39
|
+
groups: NotesGalleryGroup[];
|
|
40
|
+
emptyLabel?: React.ReactNode;
|
|
41
|
+
className?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The standalone Notes gallery -- measured live on app.attio.com's Notes
|
|
45
|
+
* page: "Notes N"/"Templates N" sub-tabs, a toolbar (Sort/View
|
|
46
|
+
* toggle/settings/New note, all consumer-composed), a dashed "Favorites"
|
|
47
|
+
* region, and date-grouped card sections. The card itself is `EntityCard`
|
|
48
|
+
* (crisp#474's own "measured from a Notes grid" component) — this shell
|
|
49
|
+
* only adds the gallery chrome around it.
|
|
50
|
+
*/
|
|
51
|
+
export declare function NotesGallery({ notesCount, templatesCount, activeTab: activeTabProp, defaultActiveTab, onActiveTabChange, notesLabel: notesLabelProp, templatesLabel: templatesLabelProp, leading, trailing, favoritesLabel: favoritesLabelProp, favorites, favoritesEmptyLabel: favoritesEmptyLabelProp, groups, emptyLabel: emptyLabelProp, className, ...rest }: NotesGalleryProps): React.JSX.Element;
|
|
52
|
+
export declare namespace NotesGallery {
|
|
53
|
+
var displayName: string;
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./objectpagemenu";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
export type ObjectPageMenuProps = {
|
|
3
|
+
/** The element that opens the menu. Default: the measured 28px ghost
|
|
4
|
+
* icon button Attio uses for its own "…" — pass one only to change the
|
|
5
|
+
* trigger itself; the menu content below is fixed (Attio's own chrome,
|
|
6
|
+
* not app-specific data — the same reasoning `defaultCommandItems`
|
|
7
|
+
* already ships on). */
|
|
8
|
+
trigger?: React.ReactElement;
|
|
9
|
+
/** Fires when "Object settings" is selected. */
|
|
10
|
+
onObjectSettings?: () => void;
|
|
11
|
+
/** Fires when "Manage attributes" is selected. */
|
|
12
|
+
onManageAttributes?: () => void;
|
|
13
|
+
/** Fires when "Connect Slack workspace" is selected, inside the
|
|
14
|
+
* Notifications submenu. */
|
|
15
|
+
onConnectSlack?: () => void;
|
|
16
|
+
objectSettingsLabel?: string;
|
|
17
|
+
manageAttributesLabel?: string;
|
|
18
|
+
notificationsLabel?: string;
|
|
19
|
+
connectSlackLabel?: string;
|
|
20
|
+
/** Accessible name for the trigger button (unused when a custom
|
|
21
|
+
* `trigger` is given). */
|
|
22
|
+
"aria-label"?: string;
|
|
23
|
+
/** Which of the trigger's edges the menu lines up with (default `"end"`,
|
|
24
|
+
* matching Attio's own right-aligned placement under the "…" button at
|
|
25
|
+
* the far right of the page header). */
|
|
26
|
+
align?: "start" | "end";
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The page-level "…" menu on Attio's object page: Object settings / Manage
|
|
30
|
+
* attributes / a Notifications submenu ("Connect Slack workspace") — crisp
|
|
31
|
+
* parity checklist rows G-020/P-005 (crisp#616). Live-measured on
|
|
32
|
+
* app.attio.com/techpartners/companies: 208×114 popover (12px radius, 4px
|
|
33
|
+
* padding, 32px rows), a hairline separator before Notifications, and its
|
|
34
|
+
* submenu opening flush against the item with no gap, flipping side when
|
|
35
|
+
* the measured width doesn't fit (`placeSubmenu`, core/place-floating.ts).
|
|
36
|
+
*/
|
|
37
|
+
export declare function ObjectPageMenu({ trigger, onObjectSettings, onManageAttributes, onConnectSlack, objectSettingsLabel, manageAttributesLabel, notificationsLabel, connectSlackLabel, "aria-label": ariaLabelProp, align, }: ObjectPageMenuProps): React.JSX.Element;
|
|
38
|
+
export declare namespace ObjectPageMenu {
|
|
39
|
+
var displayName: string;
|
|
40
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ObjectPageMenu` owns no styling of its own — every visible pixel is
|
|
3
|
+
* `Menu`/`MenuItem`'s own already-measured recipe. The one thing it DOES
|
|
4
|
+
* need is the RTL mirror for its Notifications submenu chevron (crisp#616):
|
|
5
|
+
* that icon is the first direction-bearing one ever passed as a `MenuItem`
|
|
6
|
+
* `trailingIcon`, so nothing already mirrors it.
|
|
7
|
+
*
|
|
8
|
+
* Not written as `${rtlFlipCss}` (core/rtl.ts): that string relies on native
|
|
9
|
+
* CSS nesting's `&` resolving to an ENCLOSING rule, which is exactly what
|
|
10
|
+
* `Menu`'s own recipe deliberately avoids for its portaled content (see its
|
|
11
|
+
* own doc comment) — nesting this under a `.crisp-objectpagemenu` root would
|
|
12
|
+
* need a root class this component doesn't have. A plain absolute selector,
|
|
13
|
+
* matching `Menu`'s own pattern for the identical reason.
|
|
14
|
+
*/
|
|
15
|
+
declare const config: import("../..").RecipeConfig<{}>;
|
|
16
|
+
export declare const objectpagemenuRecipe: import("../..").RecipeFn<{}>;
|
|
17
|
+
export default config;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import type { SelectOption } from "../../components/select";
|
|
2
3
|
export type ObjectSummary = {
|
|
3
4
|
id: string;
|
|
4
5
|
name: React.ReactNode;
|
|
@@ -127,6 +128,9 @@ export type AttributeRow = {
|
|
|
127
128
|
dataType: React.ReactNode;
|
|
128
129
|
/** e.g. "Unique" — rendered as a plain constraint label per row. */
|
|
129
130
|
constraint?: React.ReactNode;
|
|
131
|
+
/** The attribute's own slug (crisp#673, G-107) — "Copy slug" needs
|
|
132
|
+
* something to copy; omit on a row with no slug of its own yet. */
|
|
133
|
+
slug?: string;
|
|
130
134
|
system?: boolean;
|
|
131
135
|
enriched?: boolean;
|
|
132
136
|
};
|
|
@@ -134,6 +138,21 @@ export type AttributesTableProps = {
|
|
|
134
138
|
attributes: AttributeRow[];
|
|
135
139
|
onOpenAttribute?: (id: string) => void;
|
|
136
140
|
onEditAttribute?: (id: string) => void;
|
|
141
|
+
/** crisp#673, G-107. */
|
|
142
|
+
onDuplicateAttribute?: (id: string) => void;
|
|
143
|
+
/** Defaults to a real `navigator.clipboard.writeText(id)` when omitted —
|
|
144
|
+
* the same default-with-override shape `CommentsPanel`'s `onCopyLink`
|
|
145
|
+
* already has, so a consumer only needs this to know when it happened
|
|
146
|
+
* (a toast, analytics), not to implement the copy itself. */
|
|
147
|
+
onCopyId?: (id: string) => void;
|
|
148
|
+
/** Same default-clipboard-write shape as `onCopyId`, over the row's own
|
|
149
|
+
* `slug`. A row with no `slug` renders the item disabled rather than
|
|
150
|
+
* copying an empty string. */
|
|
151
|
+
onCopySlug?: (slug: string) => void;
|
|
152
|
+
/** Opens Attio's own rename-slug flow — crisp models no slug-editing UI
|
|
153
|
+
* of its own (out of scope, same reasoning as the plan-gated notices
|
|
154
|
+
* elsewhere), just the entry point into it. */
|
|
155
|
+
onChangeSlug?: (id: string) => void;
|
|
137
156
|
onArchiveAttribute?: (id: string) => void;
|
|
138
157
|
onReorder?: (rows: AttributeRow[]) => void;
|
|
139
158
|
onCreateAttribute?: () => void;
|
|
@@ -149,14 +168,20 @@ export type AttributesTableProps = {
|
|
|
149
168
|
systemLabel?: string;
|
|
150
169
|
enrichedLabel?: string;
|
|
151
170
|
editLabel?: string;
|
|
171
|
+
duplicateLabel?: string;
|
|
172
|
+
copyIdLabel?: string;
|
|
173
|
+
copySlugLabel?: string;
|
|
174
|
+
changeSlugLabel?: string;
|
|
152
175
|
archiveLabel?: string;
|
|
153
176
|
/** Overrides the row "…" menu entirely — return the `MenuItem`s a
|
|
154
|
-
* consumer's own actions need (crisp#660). Attio's own row menu
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
177
|
+
* consumer's own actions need (crisp#660). Attio's own row menu (crisp#673,
|
|
178
|
+
* G-107, corrects this comment's former "Edit/Archive" claim — the real
|
|
179
|
+
* menu has six items) is Edit attribute/Duplicate attribute/Copy ID/Copy
|
|
180
|
+
* slug/Change slug/Archive attribute (the default, unchanged when this is
|
|
181
|
+
* omitted); a consumer whose data isn't Attio's own attribute model (no
|
|
182
|
+
* "archive"/"slug" concept, a different action set entirely) supplies its
|
|
183
|
+
* own instead of working around six fixed items that don't fit. Receives
|
|
184
|
+
* the row so an item's handler can close over its id. */
|
|
160
185
|
rowActions?: (row: AttributeRow) => React.ReactNode;
|
|
161
186
|
emptyLabel?: React.ReactNode;
|
|
162
187
|
};
|
|
@@ -169,7 +194,7 @@ export type AttributesTableProps = {
|
|
|
169
194
|
* measures 40px here — a real, small divergence left to DataTable's owner
|
|
170
195
|
* rather than patched locally (see the PR).
|
|
171
196
|
*/
|
|
172
|
-
export declare function AttributesTable({ attributes, onOpenAttribute, onEditAttribute, onArchiveAttribute, onReorder, onCreateAttribute, title: titleProp, subtitle: subtitleProp, createLabel: createLabelProp, searchPlaceholder: searchPlaceholderProp, filterLabel: filterLabelProp, nameColumnLabel: nameColumnLabelProp, dataTypeColumnLabel: dataTypeColumnLabelProp, constraintsColumnLabel: constraintsColumnLabelProp, propertiesColumnLabel: propertiesColumnLabelProp, systemLabel: systemLabelProp, enrichedLabel: enrichedLabelProp, editLabel: editLabelProp, archiveLabel: archiveLabelProp, rowActions, emptyLabel, }: AttributesTableProps): React.JSX.Element;
|
|
197
|
+
export declare function AttributesTable({ attributes, onOpenAttribute, onEditAttribute, onDuplicateAttribute, onCopyId, onCopySlug, onChangeSlug, onArchiveAttribute, onReorder, onCreateAttribute, title: titleProp, subtitle: subtitleProp, createLabel: createLabelProp, searchPlaceholder: searchPlaceholderProp, filterLabel: filterLabelProp, nameColumnLabel: nameColumnLabelProp, dataTypeColumnLabel: dataTypeColumnLabelProp, constraintsColumnLabel: constraintsColumnLabelProp, propertiesColumnLabel: propertiesColumnLabelProp, systemLabel: systemLabelProp, enrichedLabel: enrichedLabelProp, editLabel: editLabelProp, duplicateLabel: duplicateLabelProp, copyIdLabel: copyIdLabelProp, copySlugLabel: copySlugLabelProp, changeSlugLabel: changeSlugLabelProp, archiveLabel: archiveLabelProp, rowActions, emptyLabel, }: AttributesTableProps): React.JSX.Element;
|
|
173
198
|
export declare namespace AttributesTable {
|
|
174
199
|
var displayName: string;
|
|
175
200
|
}
|
|
@@ -212,6 +237,9 @@ export declare function AttributeTypeSelect({ value, onValueChange, options, aiA
|
|
|
212
237
|
export declare namespace AttributeTypeSelect {
|
|
213
238
|
var displayName: string;
|
|
214
239
|
}
|
|
240
|
+
export declare const CURRENCY_DISPLAY_OPTIONS: SelectOption[];
|
|
241
|
+
export declare const CURRENCY_DECIMAL_PLACES_OPTIONS: SelectOption[];
|
|
242
|
+
export declare const CURRENCY_GROUPING_OPTIONS: SelectOption[];
|
|
215
243
|
export type CreateAttributeDialogProps = {
|
|
216
244
|
type: string;
|
|
217
245
|
onTypeChange: (value: string) => void;
|
|
@@ -221,6 +249,27 @@ export type CreateAttributeDialogProps = {
|
|
|
221
249
|
onNameChange: (value: string) => void;
|
|
222
250
|
description: string;
|
|
223
251
|
onDescriptionChange: (value: string) => void;
|
|
252
|
+
/** Currency's own extra fields (shown only while `type === "currency"`).
|
|
253
|
+
* See `CURRENCY_DISPLAY_OPTIONS`/`CURRENCY_DECIMAL_PLACES_OPTIONS`/
|
|
254
|
+
* `CURRENCY_GROUPING_OPTIONS` for the (small, fixed) defaults; there is
|
|
255
|
+
* no default `currencyOptions` — a real currency list is the consumer's
|
|
256
|
+
* own reference data. */
|
|
257
|
+
currency?: string;
|
|
258
|
+
onCurrencyChange?: (value: string) => void;
|
|
259
|
+
currencyOptions?: SelectOption[];
|
|
260
|
+
display?: string;
|
|
261
|
+
onDisplayChange?: (value: string) => void;
|
|
262
|
+
displayOptions?: SelectOption[];
|
|
263
|
+
decimalPlaces?: string;
|
|
264
|
+
onDecimalPlacesChange?: (value: string) => void;
|
|
265
|
+
decimalPlacesOptions?: SelectOption[];
|
|
266
|
+
grouping?: string;
|
|
267
|
+
onGroupingChange?: (value: string) => void;
|
|
268
|
+
groupingOptions?: SelectOption[];
|
|
269
|
+
currencyFieldLabel?: string;
|
|
270
|
+
displayFieldLabel?: string;
|
|
271
|
+
decimalPlacesFieldLabel?: string;
|
|
272
|
+
groupingFieldLabel?: string;
|
|
224
273
|
aiAutofillEnabled?: boolean;
|
|
225
274
|
onAiAutofillChange?: (enabled: boolean) => void;
|
|
226
275
|
onSubmit: () => void;
|
|
@@ -237,15 +286,22 @@ export type CreateAttributeDialogProps = {
|
|
|
237
286
|
createLabel?: string;
|
|
238
287
|
};
|
|
239
288
|
/**
|
|
240
|
-
* "Create attribute" (crisp#637, P-125, verified live): Attribute Type
|
|
241
|
-
* select (defaults to Text
|
|
242
|
-
* +
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
289
|
+
* "Create attribute" (crisp#637/#673, P-125, verified live): Attribute Type
|
|
290
|
+
* select (defaults to Text, type-ahead search built in via `Select`'s own
|
|
291
|
+
* `searchable`) + Name (autofocused on open, and again after picking a type
|
|
292
|
+
* — G-106) + Description (optional) + Currency's own four extra required
|
|
293
|
+
* fields when `type === "currency"` (G-104) + an AI-autofill switch row,
|
|
294
|
+
* footer Cancel/Create. Built on `FormDialog` in its plain (non-`createMode`)
|
|
295
|
+
* shape — Attio's own footer here has a real Cancel button, unlike the
|
|
296
|
+
* record-create dialog `createMode` models (crisp#548), so `createMode`
|
|
297
|
+
* would be the wrong fit even though the button carries the same ⌘↵ hint;
|
|
298
|
+
* that hint is rendered locally instead. The outside-click/Escape
|
|
299
|
+
* "Discard changes" confirm gated on dirty state (G-105) needed no work
|
|
300
|
+
* here at all — `FormDialog` already tracks dirtiness generically and shows
|
|
301
|
+
* it, so this dialog inherited it for free; `CreateAttributeDialog`'s own
|
|
302
|
+
* tests below just pin the behaviour to this component specifically.
|
|
247
303
|
*/
|
|
248
|
-
export declare function CreateAttributeDialog({ type, onTypeChange, typeOptions, aiAutofillTypeOptions, name, onNameChange, description, onDescriptionChange, aiAutofillEnabled, onAiAutofillChange, onSubmit, onClose, busy, error, title: titleProp, attributeTypeLabel: attributeTypeLabelProp, nameLabel: nameLabelProp, descriptionLabel: descriptionLabelProp, descriptionPlaceholder: descriptionPlaceholderProp, aiAutofillLabel: aiAutofillLabelProp, setUpAiAutofillLabel: setUpAiAutofillLabelProp, createLabel: createLabelProp, }: CreateAttributeDialogProps): React.JSX.Element;
|
|
304
|
+
export declare function CreateAttributeDialog({ type, onTypeChange, typeOptions, aiAutofillTypeOptions, name, onNameChange, description, onDescriptionChange, currency, onCurrencyChange, currencyOptions, display, onDisplayChange, displayOptions, decimalPlaces, onDecimalPlacesChange, decimalPlacesOptions, grouping, onGroupingChange, groupingOptions, currencyFieldLabel: currencyFieldLabelProp, displayFieldLabel: displayFieldLabelProp, decimalPlacesFieldLabel: decimalPlacesFieldLabelProp, groupingFieldLabel: groupingFieldLabelProp, aiAutofillEnabled, onAiAutofillChange, onSubmit, onClose, busy, error, title: titleProp, attributeTypeLabel: attributeTypeLabelProp, nameLabel: nameLabelProp, descriptionLabel: descriptionLabelProp, descriptionPlaceholder: descriptionPlaceholderProp, aiAutofillLabel: aiAutofillLabelProp, setUpAiAutofillLabel: setUpAiAutofillLabelProp, createLabel: createLabelProp, }: CreateAttributeDialogProps): React.JSX.Element;
|
|
249
305
|
export declare namespace CreateAttributeDialog {
|
|
250
306
|
var displayName: string;
|
|
251
307
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { type Column, type ColumnType, type EntityValue, type ReferenceOption, type Row, type StatusOption, tagTone, } from "./column";
|
|
2
2
|
export { type EditableOption, editableInputType, useEditableField, } from "./editable-field";
|
|
3
|
-
export { RecordDetails, type RecordDetailsProps, RecordPage, type RecordPageHighlight, type RecordPageLabels, type RecordPageLabelsInput, type RecordPageNote, type RecordPageProps, type RecordPageSection, type RecordPageTab, type RecordPageTask, recordPageLabels, } from "./recordpage";
|
|
3
|
+
export { RecordDetails, type RecordDetailsProps, RecordPage, type RecordPageHighlight, type RecordPageLabels, type RecordPageLabelsInput, RecordPageMain, type RecordPageMainProps, type RecordPageMenuAction, type RecordPageNote, type RecordPageProps, type RecordPageSection, type RecordPageTab, type RecordPageTask, recordPageLabels, } from "./recordpage";
|
|
4
4
|
export { recordpageRecipe } from "./recordpage.recipe";
|
|
@@ -78,6 +78,22 @@ export type RecordPageQuickAction = {
|
|
|
78
78
|
icon: LucideIcon;
|
|
79
79
|
onSelect?: () => void;
|
|
80
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* One consumer-supplied item in the "…" record-actions menu (crisp#1012) —
|
|
83
|
+
* appended after Attio's own fixed group (Merge records/Configure page/Copy
|
|
84
|
+
* page URL/Copy record ID, Add to favorites), before Delete. Own group,
|
|
85
|
+
* separator-delimited on both sides, never merged into Attio's own items —
|
|
86
|
+
* the same "caller's own list, not a merge" choice `tabs` (#379) and
|
|
87
|
+
* `highlights` (#528) already make.
|
|
88
|
+
*/
|
|
89
|
+
export type RecordPageMenuAction = {
|
|
90
|
+
label: string;
|
|
91
|
+
icon: LucideIcon;
|
|
92
|
+
onSelect: () => void;
|
|
93
|
+
/** Red text/icon, `MenuItem`'s own `danger` — for a destructive action
|
|
94
|
+
* that isn't Delete itself (Delete has its own dedicated `onDelete`). */
|
|
95
|
+
danger?: boolean;
|
|
96
|
+
};
|
|
81
97
|
export type RecordPageProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
|
|
82
98
|
record: Row;
|
|
83
99
|
columns: Column[];
|
|
@@ -196,6 +212,74 @@ export type RecordPageProps = Omit<React.ComponentPropsWithoutRef<"div">, "child
|
|
|
196
212
|
* convention) — Attio's own Share opens a dialog crisp has no measured
|
|
197
213
|
* content for; only the entry point is in scope here (#864). */
|
|
198
214
|
onShare?: () => void;
|
|
215
|
+
/**
|
|
216
|
+
* crisp#1012: the header entity's `Avatar` `shape` — defaults to
|
|
217
|
+
* `"rounded"` (Attio's own CRM entities), matching `DataTable`'s own
|
|
218
|
+
* `avatarShape` prop (#892) exactly, for a consumer whose record type
|
|
219
|
+
* reads as a person (GRC's Employee, `"circle"`) rather than a company/
|
|
220
|
+
* generic entity.
|
|
221
|
+
*/
|
|
222
|
+
avatarShape?: "rounded" | "circle";
|
|
223
|
+
/**
|
|
224
|
+
* crisp#1012: wires the entity header's Pencil "edit record" button,
|
|
225
|
+
* which drew with no `onClick` at all before this. The button itself
|
|
226
|
+
* still always renders (same as Merge/Configure page/Copy page URL/Copy
|
|
227
|
+
* record ID below, and Compose email/Add to list's own documented "this
|
|
228
|
+
* component draws the chrome, a consumer wires the behaviour") — omit
|
|
229
|
+
* to keep it exactly as inert as it always was. Named `onEditRecord`,
|
|
230
|
+
* not `onEdit` — that name is already `onEdit`'s own per-FIELD commit
|
|
231
|
+
* handler above; reusing it here for a whole-record action would be two
|
|
232
|
+
* unrelated things behind one prop.
|
|
233
|
+
*/
|
|
234
|
+
onEditRecord?: () => void;
|
|
235
|
+
/**
|
|
236
|
+
* crisp#1012: wires the "…" menu's "Delete record" item, chrome-only (no
|
|
237
|
+
* `onSelect` at all) before this. Delete itself always renders — it's
|
|
238
|
+
* one of Attio's own fixed 6 items (#621/#905), not a consumer-optional
|
|
239
|
+
* one — omit to leave it exactly as inert as Merge/Configure/Copy page
|
|
240
|
+
* URL/Copy record ID already are by default.
|
|
241
|
+
*/
|
|
242
|
+
onDelete?: () => void;
|
|
243
|
+
/**
|
|
244
|
+
* crisp#1012: appends the caller's own items to the "…" menu, in their
|
|
245
|
+
* own separator-delimited group between Attio's fixed items and Delete
|
|
246
|
+
* — e.g. an object-specific "Mark reviewed", or routing "Edit" to a full
|
|
247
|
+
* external form instead of `RecordDetails`' own inline click-to-edit for
|
|
248
|
+
* an object where that's the only real editor (internal/grc's own
|
|
249
|
+
* `EDIT_OPENS_FORM`, the case this was built for). Omit for the built-in
|
|
250
|
+
* group alone.
|
|
251
|
+
*/
|
|
252
|
+
actions?: RecordPageMenuAction[];
|
|
253
|
+
/**
|
|
254
|
+
* crisp#1019: hides the plain breadcrumb row (has no effect in peek mode
|
|
255
|
+
* — when `onClose` is set, the peek header replaces it entirely already).
|
|
256
|
+
* Default `true`, no change for an existing consumer — for one whose own
|
|
257
|
+
* app shell already renders a breadcrumb of its own (a second one would
|
|
258
|
+
* otherwise double up), pass `false`.
|
|
259
|
+
*/
|
|
260
|
+
showBreadcrumb?: boolean;
|
|
261
|
+
/**
|
|
262
|
+
* crisp#1019: hides the topbar's Share button. Default `true` — Share
|
|
263
|
+
* itself is still unconditional chrome with no built-in dialog (`onShare`
|
|
264
|
+
* "renders regardless" per its own doc above); this is a SEPARATE,
|
|
265
|
+
* explicit opt-out, not tied to whether `onShare` is supplied — a missing
|
|
266
|
+
* handler must never silently hide a button an existing consumer already
|
|
267
|
+
* sees, the same reasoning #1012's `onEditRecord`/`onDelete` already
|
|
268
|
+
* settled for the "…" menu's own always-visible items.
|
|
269
|
+
*/
|
|
270
|
+
showShare?: boolean;
|
|
271
|
+
/** crisp#1019: hides the topbar's "Ask AI" button — pure Attio branding
|
|
272
|
+
* chrome with no consumer hook of its own. Default `true`. */
|
|
273
|
+
showAskAttio?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* crisp#1019: hides the topbar's Comments toggle icon (which opens
|
|
276
|
+
* `RecordPage`'s own internal comments panel) — for a consumer whose
|
|
277
|
+
* Comments live somewhere else in its own UI already (a tab, say),
|
|
278
|
+
* rather than a second, competing entry point to the same feature.
|
|
279
|
+
* Default `true`. Independent of the `comments`/`onPostComment` props
|
|
280
|
+
* above, which control the panel's DATA, not this button's visibility.
|
|
281
|
+
*/
|
|
282
|
+
showComments?: boolean;
|
|
199
283
|
};
|
|
200
284
|
/**
|
|
201
285
|
* Every chrome string RecordPage renders. Supplied as a PARTIAL map, so
|
|
@@ -239,6 +323,40 @@ export type RecordPageLabels = {
|
|
|
239
323
|
comments: string;
|
|
240
324
|
/** Empty state under the Lists panel. */
|
|
241
325
|
noLists: string;
|
|
326
|
+
/** Activity tab toolbar (#622). */
|
|
327
|
+
filters: string;
|
|
328
|
+
addMeeting: string;
|
|
329
|
+
/** Files tab empty state (#622): title, hint body, and its two actions. */
|
|
330
|
+
noFiles: string;
|
|
331
|
+
filesHint: string;
|
|
332
|
+
newFolder: string;
|
|
333
|
+
uploadFile: string;
|
|
334
|
+
/** aria-label on the Files tab empty state's "⋮" overflow button (#622). */
|
|
335
|
+
fileMoreActions: string;
|
|
336
|
+
/** Associated deals tab empty state (#622). */
|
|
337
|
+
noDealsFound: string;
|
|
338
|
+
noDealsHint: string;
|
|
339
|
+
newDeal: string;
|
|
340
|
+
/** Emails tab empty state (#987): the dedicated tab's own illustrated
|
|
341
|
+
* state, distinct from `noEmailsWith` (Overview's condensed embed). */
|
|
342
|
+
noEmails: string;
|
|
343
|
+
noEmailsHint: string;
|
|
344
|
+
configureMailbox: string;
|
|
345
|
+
/** Calls tab empty state (#988): chrome only, no real gating. */
|
|
346
|
+
upgradeToViewCalls: string;
|
|
347
|
+
callsUpgradeHint: string;
|
|
348
|
+
upgrade: string;
|
|
349
|
+
/** The "Run workflow" quick action's own popover (#620): title, search
|
|
350
|
+
* placeholder, empty state, and its "Create new workflow" link. Chrome
|
|
351
|
+
* only, like Compose email/Add to list above -- crisp has no workflow
|
|
352
|
+
* data model to search over yet. */
|
|
353
|
+
selectWorkflowTitle: string;
|
|
354
|
+
closeWorkflowPopover: string;
|
|
355
|
+
searchWorkflowsPlaceholder: string;
|
|
356
|
+
noWorkflows: string;
|
|
357
|
+
createNewWorkflow: string;
|
|
358
|
+
/** Footer keyboard hint under the "Select workflow" popover's empty list. */
|
|
359
|
+
navigate: string;
|
|
242
360
|
highlights: string;
|
|
243
361
|
recordDetails: string;
|
|
244
362
|
searchFields: string;
|
|
@@ -347,6 +465,29 @@ export declare function RecordDetails({ record, columns, sections, onEdit, label
|
|
|
347
465
|
export declare namespace RecordDetails {
|
|
348
466
|
var displayName: string;
|
|
349
467
|
}
|
|
468
|
+
export type RecordPageMainProps = React.ComponentPropsWithoutRef<"main">;
|
|
469
|
+
/**
|
|
470
|
+
* The main/tab-content column's own box, on its own (#750) — the same
|
|
471
|
+
* "standalone piece" `RecordDetails` already is for the Details column,
|
|
472
|
+
* mirrored to the other side of the layout. `RecordPage` composes this
|
|
473
|
+
* internally for its own tabbed body (below) — this exact box, not a second
|
|
474
|
+
* copy — so a consumer building a custom record page (its own tab set, its
|
|
475
|
+
* own menu, `RecordDetails` for the left column, but not the full
|
|
476
|
+
* `RecordPage`, which hardcodes the CRM tab set) gets the same
|
|
477
|
+
* Attio-measured inset: `flex: 1; min-width: 0; display: flex;
|
|
478
|
+
* flex-direction: column; min-height: 0; overflow-y: auto; padding: 12px
|
|
479
|
+
* 20px` (`recordpage.recipe.ts`'s own `.crisp-recordpage-main`) — without
|
|
480
|
+
* reaching for that internal class name directly, the only option before
|
|
481
|
+
* this existed.
|
|
482
|
+
*
|
|
483
|
+
* Needs the same single `.crisp-recordpage`-scoped ancestor `RecordDetails`
|
|
484
|
+
* already documents — wrap both in `recordpageRecipe()`, the way
|
|
485
|
+
* `RecordPage`'s own root does.
|
|
486
|
+
*/
|
|
487
|
+
export declare function RecordPageMain({ className, children, ...rest }: RecordPageMainProps): React.JSX.Element;
|
|
488
|
+
export declare namespace RecordPageMain {
|
|
489
|
+
var displayName: string;
|
|
490
|
+
}
|
|
350
491
|
/**
|
|
351
492
|
* The full-page company record view — the page that opens when you click into a
|
|
352
493
|
* record (as opposed to the peek [RecordPanel]). A top breadcrumb bar with
|
|
@@ -355,7 +496,7 @@ export declare namespace RecordDetails {
|
|
|
355
496
|
* Emails sections (Notes & Tasks are live — add and check things off). Drop it
|
|
356
497
|
* into the app's main content area.
|
|
357
498
|
*/
|
|
358
|
-
export declare function RecordPage({ record, columns, collection, labels, onBack, onToggleFull, full, onClose, closeLabel, onPrevious, previousRecordLabel, onNext, nextRecordLabel, counterLabel, className, onEdit, tabs: tabsProp, defaultTab, notes: notesProp, onAddNote, tasks: tasksProp, onAddTask, onToggleTask, sections, highlights: highlightsProp, quickActions: quickActionsProp, comments: commentsProp, onPostComment, currentUser, onShare, ...rest }: RecordPageProps): React.JSX.Element;
|
|
499
|
+
export declare function RecordPage({ record, columns, collection, labels, onBack, onToggleFull, full, onClose, closeLabel, onPrevious, previousRecordLabel, onNext, nextRecordLabel, counterLabel, className, onEdit, tabs: tabsProp, defaultTab, notes: notesProp, onAddNote, tasks: tasksProp, onAddTask, onToggleTask, sections, highlights: highlightsProp, quickActions: quickActionsProp, comments: commentsProp, onPostComment, currentUser, onShare, avatarShape, onEditRecord, onDelete, actions, showBreadcrumb, showShare, showAskAttio, showComments, ...rest }: RecordPageProps): React.JSX.Element;
|
|
359
500
|
export declare namespace RecordPage {
|
|
360
501
|
var displayName: string;
|
|
361
502
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type RecordPickerRecord = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: React.ReactNode;
|
|
5
|
+
/** Per-type icon, consumer-supplied -- crisp has no built-in
|
|
6
|
+
* object-type-to-icon mapping (same reasoning as `TaskList`'s own
|
|
7
|
+
* `record`/`meta` slots). */
|
|
8
|
+
icon?: React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
export type RecordPickerProps = Omit<React.ComponentPropsWithoutRef<"div">, "children" | "onSelect"> & {
|
|
11
|
+
records: RecordPickerRecord[];
|
|
12
|
+
/** Shows the measured "Loading..." row instead of the list (the results
|
|
13
|
+
* are still in flight). */
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
onSelect?: (record: RecordPickerRecord) => void;
|
|
16
|
+
query?: string;
|
|
17
|
+
onQueryChange?: (query: string) => void;
|
|
18
|
+
searchLabel?: string;
|
|
19
|
+
loadingLabel?: string;
|
|
20
|
+
emptyLabel?: React.ReactNode;
|
|
21
|
+
className?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The record-search picker behind a task's "Add record" chip -- measured
|
|
25
|
+
* live on app.attio.com's Tasks page ("Edit task" -> "Add record"): a
|
|
26
|
+
* "Search..." row, then a FLAT list mixed across every object type (a
|
|
27
|
+
* person result sat first, ahead of several companies, with no section
|
|
28
|
+
* headers -- unlike the mention picker's own grouped Users/Records shape,
|
|
29
|
+
* crisp#646). Attio's own live search took a moment to resolve, showing a
|
|
30
|
+
* centred spinner + "Loading..." row meanwhile; not independently
|
|
31
|
+
* re-measured against a second empty-results case, so `emptyLabel`'s
|
|
32
|
+
* default copy ("No records") is inferred by symmetry with
|
|
33
|
+
* `AssigneePicker`'s own measured "No users", not itself pixel-measured.
|
|
34
|
+
*/
|
|
35
|
+
export declare function RecordPicker({ records, loading, onSelect, query: queryProp, onQueryChange, searchLabel: searchLabelProp, loadingLabel: loadingLabelProp, emptyLabel: emptyLabelProp, className, ...rest }: RecordPickerProps): React.JSX.Element;
|
|
36
|
+
export declare namespace RecordPicker {
|
|
37
|
+
var displayName: string;
|
|
38
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { type SavedView, SavedViews, type SavedViewsProps, } from "./savedviews";
|
|
1
|
+
export { type SavedView, SavedViews, type SavedViewsProps, SavedViewsSaveBar, type SavedViewsSaveBarProps, } from "./savedviews";
|
|
2
2
|
export { savedviewsRecipe } from "./savedviews.recipe";
|
|
@@ -90,3 +90,39 @@ export declare function SavedViews({ label, icon, views, activeId, onSelect, onC
|
|
|
90
90
|
export declare namespace SavedViews {
|
|
91
91
|
var displayName: string;
|
|
92
92
|
}
|
|
93
|
+
export type SavedViewsSaveBarProps = React.ComponentPropsWithoutRef<"div"> & {
|
|
94
|
+
/** Commits the live state (filters/sort/columns/…) back onto the loaded
|
|
95
|
+
* view — Attio's own "Save for everyone". */
|
|
96
|
+
onSave: () => void;
|
|
97
|
+
/** Reverts the live state to the loaded view's own saved snapshot. */
|
|
98
|
+
onDiscard: () => void;
|
|
99
|
+
/**
|
|
100
|
+
* Saves the live state as a brand-new view instead — the split button's
|
|
101
|
+
* own chevron menu (measured: exactly one item, "Save as new view").
|
|
102
|
+
* Omit to render a plain button with no chevron/menu.
|
|
103
|
+
*/
|
|
104
|
+
onSaveAsNew?: () => void;
|
|
105
|
+
discardLabel?: string;
|
|
106
|
+
saveLabel?: string;
|
|
107
|
+
saveAsNewLabel?: string;
|
|
108
|
+
/** aria-label on the chevron trigger when `onSaveAsNew` is given. */
|
|
109
|
+
saveOptionsLabel?: string;
|
|
110
|
+
className?: string;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* The "unsaved changes" bar for a currently loaded saved view — Attio's own
|
|
114
|
+
* "Discard changes" + a split "Save for everyone ▾" button, measured live
|
|
115
|
+
* (app.attio.com, a saved Companies view with its sort changed). Not a part
|
|
116
|
+
* of `SavedViews`' own trigger/panel: Attio renders this in the page
|
|
117
|
+
* toolbar's own trailing slot, replacing whatever sits there at rest
|
|
118
|
+
* (Import/Export, "+ New …") — the same slot `TableToolbar`'s own
|
|
119
|
+
* `children` prop already documents ("Right-aligned actions after the
|
|
120
|
+
* count"). A consumer swaps this in for that slot's usual content once its
|
|
121
|
+
* own dirty check (live filters/sort/columns vs. the loaded view's
|
|
122
|
+
* snapshot) is true, and swaps it back out once it's false — this
|
|
123
|
+
* component itself carries no dirty state or visibility toggle.
|
|
124
|
+
*/
|
|
125
|
+
export declare function SavedViewsSaveBar({ onSave, onDiscard, onSaveAsNew, discardLabel: discardLabelProp, saveLabel: saveLabelProp, saveAsNewLabel: saveAsNewLabelProp, saveOptionsLabel: saveOptionsLabelProp, className, ...rest }: SavedViewsSaveBarProps): React.JSX.Element;
|
|
126
|
+
export declare namespace SavedViewsSaveBar {
|
|
127
|
+
var displayName: string;
|
|
128
|
+
}
|