@crisp-ui-kit/crisp 0.57.3 → 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.
Files changed (169) hide show
  1. package/dist/assigneepicker.css +13 -0
  2. package/dist/assigneepicker.d.ts +7 -0
  3. package/dist/assigneepicker.layered.css +15 -0
  4. package/dist/button.css +1 -1
  5. package/dist/button.layered.css +1 -1
  6. package/dist/cjs/components/button/button.recipe.js +15 -10
  7. package/dist/cjs/components/datatable/datatable.js +6 -3
  8. package/dist/cjs/components/datatable/datatable.recipe.js +35 -2
  9. package/dist/cjs/components/menu/menu.js +48 -8
  10. package/dist/cjs/components/multiselect/multiselect.js +3 -0
  11. package/dist/cjs/components/multiselect/multiselect.recipe.js +18 -0
  12. package/dist/cjs/components/select/select.js +2 -2
  13. package/dist/cjs/components/select/select.recipe.js +19 -0
  14. package/dist/cjs/core/index.js +2 -1
  15. package/dist/cjs/core/place-floating.js +38 -0
  16. package/dist/cjs/index.js +8 -0
  17. package/dist/cjs/product/assigneepicker/assigneepicker.js +127 -0
  18. package/dist/cjs/product/assigneepicker/assigneepicker.recipe.js +36 -0
  19. package/dist/cjs/product/assigneepicker/index.js +7 -0
  20. package/dist/cjs/product/notesgallery/index.js +7 -0
  21. package/dist/cjs/product/notesgallery/notesgallery.js +80 -0
  22. package/dist/cjs/product/notesgallery/notesgallery.recipe.js +46 -0
  23. package/dist/cjs/product/objectpagemenu/index.js +17 -0
  24. package/dist/cjs/product/objectpagemenu/objectpagemenu.js +26 -0
  25. package/dist/cjs/product/objectpagemenu/objectpagemenu.recipe.js +30 -0
  26. package/dist/cjs/product/objectsettings/objectsettings.js +107 -14
  27. package/dist/cjs/product/recordpage/recordpage.js +64 -5
  28. package/dist/cjs/product/recordpage/recordpage.recipe.js +38 -0
  29. package/dist/cjs/product/recordpicker/index.js +7 -0
  30. package/dist/cjs/product/recordpicker/recordpicker.js +100 -0
  31. package/dist/cjs/product/recordpicker/recordpicker.recipe.js +36 -0
  32. package/dist/cjs/product/savedviews/index.js +2 -1
  33. package/dist/cjs/product/savedviews/savedviews.js +22 -0
  34. package/dist/cjs/product/savedviews/savedviews.recipe.js +47 -0
  35. package/dist/cjs/product/share/index.js +7 -0
  36. package/dist/cjs/product/share/share.js +179 -0
  37. package/dist/cjs/product/share/share.recipe.js +114 -0
  38. package/dist/cjs/product/shortcutssheet/index.js +17 -0
  39. package/dist/cjs/product/shortcutssheet/shortcutssheet.js +125 -0
  40. package/dist/cjs/product/shortcutssheet/shortcutssheet.recipe.js +50 -0
  41. package/dist/cjs/product/taskeditpopover/index.js +7 -0
  42. package/dist/cjs/product/taskeditpopover/taskeditpopover.js +159 -0
  43. package/dist/cjs/product/taskeditpopover/taskeditpopover.recipe.js +68 -0
  44. package/dist/cjs/product/workspaceswitchermenu/index.js +17 -0
  45. package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.js +38 -0
  46. package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +34 -0
  47. package/dist/cjs/tokens/palette.js +27 -0
  48. package/dist/cjs/tokens/semantic.js +20 -0
  49. package/dist/datatable.css +40 -7
  50. package/dist/datatable.layered.css +40 -7
  51. package/dist/esm/components/button/button.recipe.js +15 -10
  52. package/dist/esm/components/datatable/datatable.js +6 -3
  53. package/dist/esm/components/datatable/datatable.recipe.js +35 -2
  54. package/dist/esm/components/menu/menu.js +47 -7
  55. package/dist/esm/components/multiselect/multiselect.js +3 -0
  56. package/dist/esm/components/multiselect/multiselect.recipe.js +18 -0
  57. package/dist/esm/components/select/select.js +2 -2
  58. package/dist/esm/components/select/select.recipe.js +19 -0
  59. package/dist/esm/core/index.js +1 -1
  60. package/dist/esm/core/place-floating.js +37 -0
  61. package/dist/esm/index.js +8 -0
  62. package/dist/esm/product/assigneepicker/assigneepicker.js +91 -0
  63. package/dist/esm/product/assigneepicker/assigneepicker.recipe.js +33 -0
  64. package/dist/esm/product/assigneepicker/index.js +2 -0
  65. package/dist/esm/product/notesgallery/index.js +2 -0
  66. package/dist/esm/product/notesgallery/notesgallery.js +44 -0
  67. package/dist/esm/product/notesgallery/notesgallery.recipe.js +43 -0
  68. package/dist/esm/product/objectpagemenu/index.js +1 -0
  69. package/dist/esm/product/objectpagemenu/objectpagemenu.js +23 -0
  70. package/dist/esm/product/objectpagemenu/objectpagemenu.recipe.js +27 -0
  71. package/dist/esm/product/objectsettings/objectsettings.js +106 -13
  72. package/dist/esm/product/recordpage/recordpage.js +64 -5
  73. package/dist/esm/product/recordpage/recordpage.recipe.js +38 -0
  74. package/dist/esm/product/recordpicker/index.js +2 -0
  75. package/dist/esm/product/recordpicker/recordpicker.js +64 -0
  76. package/dist/esm/product/recordpicker/recordpicker.recipe.js +33 -0
  77. package/dist/esm/product/savedviews/index.js +1 -1
  78. package/dist/esm/product/savedviews/savedviews.js +22 -1
  79. package/dist/esm/product/savedviews/savedviews.recipe.js +47 -0
  80. package/dist/esm/product/share/index.js +2 -0
  81. package/dist/esm/product/share/share.js +143 -0
  82. package/dist/esm/product/share/share.recipe.js +111 -0
  83. package/dist/esm/product/shortcutssheet/index.js +1 -0
  84. package/dist/esm/product/shortcutssheet/shortcutssheet.js +88 -0
  85. package/dist/esm/product/shortcutssheet/shortcutssheet.recipe.js +47 -0
  86. package/dist/esm/product/taskeditpopover/index.js +2 -0
  87. package/dist/esm/product/taskeditpopover/taskeditpopover.js +123 -0
  88. package/dist/esm/product/taskeditpopover/taskeditpopover.recipe.js +65 -0
  89. package/dist/esm/product/workspaceswitchermenu/index.js +1 -0
  90. package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.js +35 -0
  91. package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +31 -0
  92. package/dist/esm/tokens/palette.js +27 -0
  93. package/dist/esm/tokens/semantic.js +20 -0
  94. package/dist/multiselect.css +18 -0
  95. package/dist/multiselect.layered.css +18 -0
  96. package/dist/native/tokens.d.ts +1 -1
  97. package/dist/native/tokens.js +56 -4
  98. package/dist/notesgallery.css +15 -0
  99. package/dist/notesgallery.d.ts +7 -0
  100. package/dist/notesgallery.layered.css +17 -0
  101. package/dist/objectpagemenu.css +3 -0
  102. package/dist/objectpagemenu.d.ts +7 -0
  103. package/dist/objectpagemenu.layered.css +5 -0
  104. package/dist/recordpage.css +36 -0
  105. package/dist/recordpage.layered.css +36 -0
  106. package/dist/recordpicker.css +13 -0
  107. package/dist/recordpicker.d.ts +7 -0
  108. package/dist/recordpicker.layered.css +15 -0
  109. package/dist/savedviews.css +47 -0
  110. package/dist/savedviews.layered.css +47 -0
  111. package/dist/select.css +19 -0
  112. package/dist/select.layered.css +19 -0
  113. package/dist/share.css +84 -0
  114. package/dist/share.d.ts +7 -0
  115. package/dist/share.layered.css +86 -0
  116. package/dist/shortcutssheet.css +24 -0
  117. package/dist/shortcutssheet.d.ts +7 -0
  118. package/dist/shortcutssheet.layered.css +26 -0
  119. package/dist/styles.css +387 -8
  120. package/dist/styles.layered.css +387 -8
  121. package/dist/taskeditpopover.css +36 -0
  122. package/dist/taskeditpopover.d.ts +7 -0
  123. package/dist/taskeditpopover.layered.css +38 -0
  124. package/dist/tokens.css +26 -0
  125. package/dist/tokens.json +56 -4
  126. package/dist/types/components/button/button.recipe.d.ts +2 -3
  127. package/dist/types/components/datatable/datatable.d.ts +8 -0
  128. package/dist/types/components/menu/menu.d.ts +50 -7
  129. package/dist/types/components/multiselect/multiselect.d.ts +9 -0
  130. package/dist/types/components/select/select.d.ts +10 -0
  131. package/dist/types/core/index.d.ts +1 -1
  132. package/dist/types/core/place-floating.d.ts +37 -0
  133. package/dist/types/index.d.ts +8 -0
  134. package/dist/types/product/assigneepicker/assigneepicker.d.ts +36 -0
  135. package/dist/types/product/assigneepicker/assigneepicker.recipe.d.ts +3 -0
  136. package/dist/types/product/assigneepicker/index.d.ts +2 -0
  137. package/dist/types/product/notesgallery/index.d.ts +2 -0
  138. package/dist/types/product/notesgallery/notesgallery.d.ts +54 -0
  139. package/dist/types/product/notesgallery/notesgallery.recipe.d.ts +3 -0
  140. package/dist/types/product/objectpagemenu/index.d.ts +1 -0
  141. package/dist/types/product/objectpagemenu/objectpagemenu.d.ts +40 -0
  142. package/dist/types/product/objectpagemenu/objectpagemenu.recipe.d.ts +17 -0
  143. package/dist/types/product/objectsettings/objectsettings.d.ts +71 -15
  144. package/dist/types/product/recordpage/index.d.ts +1 -1
  145. package/dist/types/product/recordpage/recordpage.d.ts +96 -1
  146. package/dist/types/product/recordpicker/index.d.ts +2 -0
  147. package/dist/types/product/recordpicker/recordpicker.d.ts +38 -0
  148. package/dist/types/product/recordpicker/recordpicker.recipe.d.ts +3 -0
  149. package/dist/types/product/savedviews/index.d.ts +1 -1
  150. package/dist/types/product/savedviews/savedviews.d.ts +36 -0
  151. package/dist/types/product/share/index.d.ts +2 -0
  152. package/dist/types/product/share/share.d.ts +85 -0
  153. package/dist/types/product/share/share.recipe.d.ts +3 -0
  154. package/dist/types/product/shortcutssheet/index.d.ts +1 -0
  155. package/dist/types/product/shortcutssheet/shortcutssheet.d.ts +49 -0
  156. package/dist/types/product/shortcutssheet/shortcutssheet.recipe.d.ts +3 -0
  157. package/dist/types/product/taskeditpopover/index.d.ts +2 -0
  158. package/dist/types/product/taskeditpopover/taskeditpopover.d.ts +67 -0
  159. package/dist/types/product/taskeditpopover/taskeditpopover.recipe.d.ts +3 -0
  160. package/dist/types/product/workspaceswitchermenu/index.d.ts +1 -0
  161. package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.d.ts +54 -0
  162. package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.recipe.d.ts +19 -0
  163. package/dist/types/tokens/contract.d.ts +13 -0
  164. package/dist/types/tokens/palette.d.ts +52 -0
  165. package/dist/types/tokens/semantic.d.ts +20 -0
  166. package/dist/workspaceswitchermenu.css +4 -0
  167. package/dist/workspaceswitchermenu.d.ts +7 -0
  168. package/dist/workspaceswitchermenu.layered.css +6 -0
  169. package/package.json +41 -1
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SharePopover = SharePopover;
37
+ const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const lucide_react_1 = require("lucide-react");
39
+ const React = __importStar(require("react"));
40
+ const avatar_1 = require("../../components/avatar");
41
+ const input_1 = require("../../components/input");
42
+ const select_1 = require("../../components/select");
43
+ const tabs_1 = require("../../components/tabs");
44
+ const core_1 = require("../../core");
45
+ const share_recipe_1 = require("./share.recipe");
46
+ /**
47
+ * A Share/permissions popover — measured live on app.attio.com (both an
48
+ * object table's and a List's own "Share" trigger, techpartners workspace):
49
+ * Members/Automations pill tabs, a "Workspace access" row (avatar + label +
50
+ * a `Read and write ⌄`-style role select), an optional plan-gated upsell
51
+ * slot, a "Clear permissions" action, an "Individual members" list (one row
52
+ * per member, its own role select), and — on the Automations tab — a
53
+ * search box + role select + "Add" row. Both tabs share a trailing "Learn
54
+ * more about permissions" link.
55
+ *
56
+ * Its own floating shell (not the generic `Popover`): the measured surface
57
+ * is 440px wide, past `Popover`'s 360px content cap. See share.recipe.ts.
58
+ */
59
+ function SharePopover({ trigger, align = "end", open: openProp, defaultOpen, onOpenChange, tab: tabProp, defaultTab = "members", onTabChange, membersTabLabel: membersTabLabelProp, automationsTabLabel: automationsTabLabelProp, workspaceIcon, workspaceAccessLabel: workspaceAccessLabelProp, workspaceAccessValue, workspaceAccessOptions, onWorkspaceAccessChange, advancedSharing, onClearPermissions, clearPermissionsLabel: clearPermissionsLabelProp, members, membersSectionLabel: membersSectionLabelProp, memberRoleOptions, onMemberAccessChange, automationSearchValue, defaultAutomationSearchValue, onAutomationSearchChange, automationSearchPlaceholder: automationSearchPlaceholderProp, automationRoleValue, automationRoleOptions, onAutomationRoleChange, onAddAutomation, addAutomationDisabled, addAutomationLabel: addAutomationLabelProp, learnMoreHref, learnMoreLabel: learnMoreLabelProp, "aria-label": ariaLabel, className, ...rest }) {
60
+ const membersTabLabel = (0, core_1.useCrispMessage)(membersTabLabelProp, "Members");
61
+ const automationsTabLabel = (0, core_1.useCrispMessage)(automationsTabLabelProp, "Automations");
62
+ const workspaceAccessLabel = (0, core_1.useCrispMessage)(workspaceAccessLabelProp, "Workspace access");
63
+ const clearPermissionsLabel = (0, core_1.useCrispMessage)(clearPermissionsLabelProp, "Clear permissions");
64
+ const membersSectionLabel = (0, core_1.useCrispMessage)(membersSectionLabelProp, "Individual members");
65
+ const automationSearchPlaceholder = (0, core_1.useCrispMessage)(automationSearchPlaceholderProp, "Search...");
66
+ const addAutomationLabel = (0, core_1.useCrispMessage)(addAutomationLabelProp, "Add");
67
+ const learnMoreLabel = (0, core_1.useCrispMessage)(learnMoreLabelProp, "Learn more about permissions");
68
+ const surfaceId = React.useId();
69
+ const triggerId = trigger.props.id ?? `${surfaceId}-trigger`;
70
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false);
71
+ const open = openProp ?? internalOpen;
72
+ const setOpen = React.useCallback((next) => {
73
+ if (openProp === undefined)
74
+ setInternalOpen(next);
75
+ onOpenChange?.(next);
76
+ }, [openProp, onOpenChange]);
77
+ const [internalTab, setInternalTab] = React.useState(defaultTab);
78
+ const activeTab = tabProp ?? internalTab;
79
+ const selectTab = (t) => {
80
+ if (tabProp === undefined)
81
+ setInternalTab(t);
82
+ onTabChange?.(t);
83
+ };
84
+ const [internalSearch, setInternalSearch] = React.useState(defaultAutomationSearchValue ?? "");
85
+ const searchValue = automationSearchValue ?? internalSearch;
86
+ const setSearch = (q) => {
87
+ if (automationSearchValue === undefined)
88
+ setInternalSearch(q);
89
+ onAutomationSearchChange?.(q);
90
+ };
91
+ const rootRef = React.useRef(null);
92
+ const triggerRef = React.useRef(null);
93
+ const contentRef = React.useRef(null);
94
+ const [pos, setPos] = React.useState({});
95
+ const [up, setUp] = React.useState(false);
96
+ const place = () => {
97
+ const el = triggerRef.current;
98
+ if (!el)
99
+ return;
100
+ const { style, up: flipUp } = (0, core_1.placeFloating)({
101
+ rect: el.getBoundingClientRect(),
102
+ align,
103
+ gap: 6,
104
+ flipBelow: 320,
105
+ anchor: el,
106
+ });
107
+ setUp(flipUp);
108
+ setPos(style);
109
+ };
110
+ // biome-ignore lint/correctness/useExhaustiveDependencies: reposition each time it opens
111
+ React.useLayoutEffect(() => {
112
+ if (open)
113
+ place();
114
+ }, [open]);
115
+ React.useEffect(() => {
116
+ if (!open || !contentRef.current)
117
+ return;
118
+ return (0, core_1.registerFloatingLayer)(contentRef.current);
119
+ }, [open]);
120
+ const close = React.useCallback(() => {
121
+ setOpen(false);
122
+ }, [setOpen]);
123
+ React.useEffect(() => {
124
+ if (!open)
125
+ return;
126
+ const onDown = (e) => {
127
+ const target = e.target;
128
+ if (rootRef.current?.contains(target))
129
+ return;
130
+ if (contentRef.current?.contains(target))
131
+ return;
132
+ if ((0, core_1.isInsideLaterFloatingLayer)(target, contentRef.current))
133
+ return;
134
+ close();
135
+ };
136
+ document.addEventListener("pointerdown", onDown);
137
+ return () => document.removeEventListener("pointerdown", onDown);
138
+ }, [open, close]);
139
+ React.useEffect(() => {
140
+ if (!open)
141
+ return;
142
+ const onKey = (e) => {
143
+ if (e.key !== "Escape")
144
+ return;
145
+ if ((0, core_1.hasNestedFloatingLayer)(contentRef.current))
146
+ return;
147
+ close();
148
+ };
149
+ document.addEventListener("keydown", onKey);
150
+ return () => document.removeEventListener("keydown", onKey);
151
+ }, [open, close]);
152
+ const triggerEl = React.cloneElement(trigger, {
153
+ ref: triggerRef,
154
+ id: triggerId,
155
+ "aria-haspopup": "dialog",
156
+ "aria-expanded": open,
157
+ "aria-controls": open ? surfaceId : undefined,
158
+ onClick: (e) => {
159
+ trigger.props.onClick?.(e);
160
+ setOpen(!open);
161
+ },
162
+ });
163
+ const tablistRef = React.useRef(null);
164
+ const tabEntries = React.useMemo(() => [{ value: "members" }, { value: "automations" }], []);
165
+ const { onKeyDown: onTabKeyDown, tabIndexFor } = (0, tabs_1.useTablistKeyboard)({
166
+ tabs: tabEntries,
167
+ active: activeTab,
168
+ select: (v) => selectTab(v),
169
+ listRef: tablistRef,
170
+ });
171
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: rootRef, className: (0, share_recipe_1.shareRecipe)({ className }), children: [triggerEl, open && ((0, jsx_runtime_1.jsx)(core_1.FloatingPortal, { sourceRef: rootRef, children: (0, jsx_runtime_1.jsxs)("div", { ref: contentRef, className: "crisp-share-content", role: "dialog", id: surfaceId, "aria-label": ariaLabel, "aria-labelledby": ariaLabel ? undefined : triggerId, "data-up": up ? "" : undefined, style: pos, ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { ref: tablistRef, className: "crisp-share-tabs", role: "tablist", onKeyDown: onTabKeyDown, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", "data-value": "members", "aria-selected": activeTab === "members", tabIndex: tabIndexFor("members"), className: "crisp-share-tab", onClick: () => selectTab("members"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Users, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }), membersTabLabel] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", "data-value": "automations", "aria-selected": activeTab === "automations", tabIndex: tabIndexFor("automations"), className: "crisp-share-tab", onClick: () => selectTab("automations"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Play, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }), automationsTabLabel] })] }), activeTab === "members" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-share-row", children: [workspaceIcon ?? ((0, jsx_runtime_1.jsx)(avatar_1.Avatar, { size: "lg", tone: "brand", children: typeof workspaceAccessLabel === "string"
172
+ ? workspaceAccessLabel.charAt(0)
173
+ : null })), (0, jsx_runtime_1.jsx)("span", { className: "crisp-share-row-label", children: workspaceAccessLabel }), (0, jsx_runtime_1.jsx)(select_1.Select, { variant: "ghost", width: "auto", options: workspaceAccessOptions, value: workspaceAccessValue, onValueChange: onWorkspaceAccessChange, "aria-label": workspaceAccessLabel })] }), advancedSharing, onClearPermissions && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-share-clear", onClick: onClearPermissions, children: clearPermissionsLabel })), members && members.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: "crisp-share-section-label", children: membersSectionLabel }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-share-members", children: members.map((m) => ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-share-member", children: [m.avatar ?? ((0, jsx_runtime_1.jsx)(avatar_1.Avatar, { size: "lg", tone: "brand", children: typeof m.name === "string"
174
+ ? m.name.charAt(0).toUpperCase()
175
+ : null })), (0, jsx_runtime_1.jsxs)("span", { className: "crisp-share-member-text", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-share-member-name", children: m.name }), m.email && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-share-member-email", children: m.email }))] }), (0, jsx_runtime_1.jsx)(select_1.Select, { variant: "ghost", width: "auto", options: memberRoleOptions, value: m.access, disabled: m.accessDisabled, onValueChange: (v) => onMemberAccessChange?.(m.id, v), "aria-label": typeof m.name === "string"
176
+ ? `${m.name}'s access`
177
+ : undefined })] }, m.id))) })] }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-share-automations-row", children: [(0, jsx_runtime_1.jsx)(input_1.Input, { value: searchValue, onChange: (e) => setSearch(e.target.value), placeholder: automationSearchPlaceholder, "aria-label": automationSearchPlaceholder }), (0, jsx_runtime_1.jsx)(select_1.Select, { variant: "ghost", width: "auto", options: automationRoleOptions, value: automationRoleValue, onValueChange: onAutomationRoleChange, "aria-label": automationsTabLabel }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-share-add", disabled: addAutomationDisabled, onClick: onAddAutomation, children: addAutomationLabel })] })), (0, jsx_runtime_1.jsxs)("a", { className: "crisp-share-learnmore", href: learnMoreHref, target: "_blank", rel: "noreferrer", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }), learnMoreLabel] })] }) }))] }));
178
+ }
179
+ SharePopover.displayName = "SharePopover";
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shareRecipe = void 0;
4
+ const core_1 = require("../../core");
5
+ const tokens_1 = require("../../tokens");
6
+ // SharePopover's shell — measured live on app.attio.com (both the object
7
+ // table's and a List's own "Share" trigger, techpartners workspace,
8
+ // 2026-09-27): a 440px-wide floating panel, radius 12 (xl), the same
9
+ // layered popover shadow every other floating surface uses (`e.floating`
10
+ // matched the measured box-shadow's four layers exactly, so no new shadow
11
+ // literal was needed).
12
+ //
13
+ // This is its own floating shell rather than a reuse of the generic
14
+ // `Popover` (components/popover): that recipe caps its content at
15
+ // `min(360px, 92vw)`, and 440px measured wider than that on every sample.
16
+ // `product/savedviews` already sets the precedent for a product surface
17
+ // owning its own portaled shell over the generic one when the measured
18
+ // geometry doesn't fit it.
19
+ //
20
+ // Three muted-text alphas were measured that don't match any existing
21
+ // color token: the workspace-access/role value text (`rgba(0,0,0,.55)`),
22
+ // the "Individual members" section label (`rgba(0,0,0,.5)`), and the
23
+ // inactive-tab/footer-link text (`rgba(0,0,0,.63)` — this one incidentally
24
+ // equals `fgAlertDescription`'s light value, but that token is Dialog's own
25
+ // alert-description colour, a different surface, so it is not reused here).
26
+ // Rather than add new palette entries for three one-off alphas (tokens/**
27
+ // is another lane's file), each is expressed as `color-mix(in srgb,
28
+ // fgPrimary N%, transparent)` — the same idiom `segmented`'s own track
29
+ // background already uses for its 5% tint — so the value is theme-reactive
30
+ // (it scales with fgPrimary's dark value too) without a new token or a
31
+ // flat literal that would go stale in dark mode.
32
+ const mutedText = (pct) => `color-mix(in srgb, ${tokens_1.contract.fgPrimary} ${pct}%, transparent)`;
33
+ const config = (0, core_1.defineRecipe)({
34
+ name: "share",
35
+ base: `display: contents; font-family: ${tokens_1.contract.font.sans};`,
36
+ globalCss: `
37
+ .crisp-share-content {
38
+ font-family: ${tokens_1.contract.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
39
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box;
40
+ width: 440px; max-width: 92vw;
41
+ padding: ${tokens_1.contract.space["3"]}; display: flex; flex-direction: column; gap: ${tokens_1.contract.space["3"]};
42
+ border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; color: ${tokens_1.contract.fgPrimary};
43
+ box-shadow: ${tokens_1.elevation.floating};
44
+ opacity: 1; transform: none; transform-origin: top right;
45
+ transition: opacity 0.08s ease, transform 0.08s ease;
46
+ @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); }
47
+ }
48
+ .crisp-share-content[data-up] { transform-origin: bottom right; }
49
+
50
+ .crisp-share-tabs { display: flex; align-items: center; gap: ${tokens_1.contract.space["1"]}; }
51
+ .crisp-share-tab {
52
+ box-sizing: border-box; display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]};
53
+ height: ${tokens_1.contract.size.row}; padding: 0 ${tokens_1.contract.space["2"]}; border: none; border-radius: ${tokens_1.contract.radius.md};
54
+ background: transparent; color: ${mutedText(63)};
55
+ font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; letter-spacing: -0.07px;
56
+ cursor: pointer; transition: background-color .12s ease, color .12s ease;
57
+ }
58
+ .crisp-share-tab svg { flex-shrink: 0; }
59
+ .crisp-share-tab:hover { color: ${tokens_1.contract.fgPrimary}; }
60
+ .crisp-share-tab[aria-selected="true"] { background: ${tokens_1.contract.bgSurfaceMuted}; color: ${tokens_1.contract.fgPrimary}; }
61
+
62
+ .crisp-share-row { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; min-height: 34px; }
63
+ .crisp-share-row-label { flex: 1; min-width: 0; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; letter-spacing: -0.07px; }
64
+ .crisp-share-row .crisp-select { flex-shrink: 0; }
65
+ .crisp-share-row .crisp-select .crisp-select-value,
66
+ .crisp-share-row .crisp-select .crisp-select-chevron { color: ${mutedText(55)}; }
67
+
68
+ .crisp-share-clear {
69
+ align-self: flex-start; margin: 0; padding: 0; border: none; background: none;
70
+ font-family: inherit; font-size: ${tokens_1.contract.text.md}; font-weight: ${tokens_1.contract.weight.medium};
71
+ color: ${mutedText(63)}; cursor: pointer;
72
+ }
73
+ .crisp-share-clear:hover { color: ${tokens_1.contract.fgPrimary}; text-decoration: underline; }
74
+
75
+ .crisp-share-section-label {
76
+ margin: 0; font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: ${mutedText(50)};
77
+ }
78
+ .crisp-share-members { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["2"]}; }
79
+ .crisp-share-member { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; }
80
+ .crisp-share-member-text { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: ${tokens_1.contract.space["1.5"]}; overflow: hidden; }
81
+ .crisp-share-member-name { flex-shrink: 0; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; letter-spacing: -0.07px; }
82
+ .crisp-share-member-email { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${mutedText(55)}; letter-spacing: -0.07px; }
83
+ .crisp-share-member .crisp-select { flex-shrink: 0; }
84
+ .crisp-share-member .crisp-select .crisp-select-value,
85
+ .crisp-share-member .crisp-select .crisp-select-chevron { color: ${mutedText(55)}; }
86
+
87
+ .crisp-share-automations-row { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; }
88
+ .crisp-share-automations-row .crisp-input { flex: 1; min-width: 0; }
89
+ .crisp-share-automations-row .crisp-select { flex-shrink: 0; }
90
+
91
+ .crisp-share-add {
92
+ flex-shrink: 0; box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
93
+ height: 32px; padding: 0 ${tokens_1.contract.space["2.5"]}; border: none; border-radius: ${tokens_1.contract.radius.lg};
94
+ background: ${tokens_1.contract.bgBrandSolid}; color: ${tokens_1.contract.fgOnBrand};
95
+ font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; letter-spacing: -0.07px;
96
+ cursor: pointer; transition: background-color .12s ease, opacity .12s ease;
97
+ }
98
+ .crisp-share-add:hover:not(:disabled) { background: ${tokens_1.contract.bgBrandSolidPressed}; }
99
+ .crisp-share-add:disabled { opacity: 0.4; cursor: not-allowed; }
100
+
101
+ .crisp-share-learnmore {
102
+ display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]};
103
+ font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${mutedText(63)};
104
+ text-decoration: none;
105
+ }
106
+ .crisp-share-learnmore:hover { color: ${tokens_1.contract.fgPrimary}; }
107
+ .crisp-share-learnmore svg { flex-shrink: 0; }
108
+ `,
109
+ variants: {},
110
+ defaultVariants: {},
111
+ compoundVariants: [],
112
+ });
113
+ exports.shareRecipe = (0, core_1.resolveRecipe)(config);
114
+ exports.default = config;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./shortcutssheet"), exports);
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.defaultShortcutSections = void 0;
37
+ exports.ShortcutsSheet = ShortcutsSheet;
38
+ const jsx_runtime_1 = require("react/jsx-runtime");
39
+ const lucide_react_1 = require("lucide-react");
40
+ const React = __importStar(require("react"));
41
+ const drawer_1 = require("../../components/drawer");
42
+ const kbd_1 = require("../../components/kbd");
43
+ const core_1 = require("../../core");
44
+ /** The physical Enter/Return key's printed glyph — not a reading-direction
45
+ * indicator (a real keyboard prints the same ↵ shape under any locale), so
46
+ * unlike `LogOut` elsewhere it is deliberately left unmirrored (excused in
47
+ * `build/spec-check.mjs`'s own RTL icon-mirroring ALLOW list). */
48
+ const enterKey = () => (0, jsx_runtime_1.jsx)(lucide_react_1.CornerDownLeft, { size: 16, strokeWidth: 1.75 });
49
+ /**
50
+ * Attio's own canonical keyboard-shortcut list (crisp#615), live-measured
51
+ * off app.attio.com/techpartners' "Keyboard shortcuts" panel (Help →
52
+ * "Shortcuts") — 34 rows across 4 sections. The issue's own quoted table
53
+ * collapsed a few of these ("Navigate to the cell above/right/below/left",
54
+ * "Go to next/previous cell") into one row each; the live panel renders
55
+ * them as separate rows, which is what this list follows.
56
+ */
57
+ exports.defaultShortcutSections = [
58
+ {
59
+ label: "General",
60
+ rows: [
61
+ { description: "Open quick actions", steps: [["⌘", "K"]] },
62
+ { description: "Open search", steps: [["/"]] },
63
+ { description: "Create a new note", steps: [["N"]] },
64
+ { description: "Create a new entry", steps: [["E"]] },
65
+ { description: "Create a new task", steps: [["T"]] },
66
+ { description: "Create a new email", steps: [["C"]] },
67
+ { description: "Go to home page", steps: [["G"], ["H"]] },
68
+ { description: "Go to tasks page", steps: [["G"], ["T"]] },
69
+ { description: "Go to all notes page", steps: [["G"], ["N"]] },
70
+ { description: "Go to all people page", steps: [["G"], ["P"]] },
71
+ { description: "Go to all companies page", steps: [["G"], ["C"]] },
72
+ { description: "Go to email drafts page", steps: [["G"], ["E"]] },
73
+ { description: "Toggle sidebar", steps: [["⌘", "."]] },
74
+ { description: "Navigate up", steps: [["↑"]] },
75
+ { description: "Navigate down", steps: [["↓"]] },
76
+ ],
77
+ },
78
+ {
79
+ label: "Record page",
80
+ rows: [
81
+ { description: "Go to next tab", steps: [["⌥", "→"]] },
82
+ { description: "Go to previous tab", steps: [["⌥", "←"]] },
83
+ ],
84
+ },
85
+ {
86
+ label: "Table view",
87
+ rows: [
88
+ { description: "Navigate to the cell above", steps: [["↑"]] },
89
+ { description: "Navigate to the cell to the right", steps: [["→"]] },
90
+ { description: "Navigate to the cell below", steps: [["↓"]] },
91
+ { description: "Navigate to the cell to the left", steps: [["←"]] },
92
+ { description: "Jump to bottom", steps: [["⌘", "↓"]] },
93
+ { description: "Jump to top", steps: [["⌘", "↑"]] },
94
+ { description: "Select/deselect current row", steps: [["⇧", "␣"]] },
95
+ { description: "Group select rows up", steps: [["⇧", "↑"]] },
96
+ { description: "Group select rows down", steps: [["⇧", "↓"]] },
97
+ { description: "Group select to top", steps: [["⌘", "⇧", "↑"]] },
98
+ { description: "Group select to bottom", steps: [["⌘", "⇧", "↓"]] },
99
+ {
100
+ description: "Open record page for current entry",
101
+ steps: [["⌘", enterKey()]],
102
+ },
103
+ { description: "Select/deselect all rows", steps: [["⌘", "A"]] },
104
+ { description: "Go to next cell", steps: [["⇥"]] },
105
+ { description: "Go to previous cell", steps: [["⇧", "⇥"]] },
106
+ { description: "Edit cell / go to next cell", steps: [[enterKey()]] },
107
+ ],
108
+ },
109
+ {
110
+ label: "Help",
111
+ rows: [{ description: "Open help drawer", steps: [["?"]] }],
112
+ },
113
+ ];
114
+ /**
115
+ * Attio's "Keyboard shortcuts" panel (crisp#615, parity row P-106) — a
116
+ * `Drawer` narrowed to the measured 360px (Drawer's own default is 420px),
117
+ * listing `sections` grouped with a hairline-free 10px row rhythm and a
118
+ * 20px gap before each new section label.
119
+ */
120
+ function ShortcutsSheet({ open, onOpenChange, sections = exports.defaultShortcutSections, title: titleProp, thenLabel: thenLabelProp, closeLabel, className, ...rest }) {
121
+ const title = (0, core_1.useCrispMessage)(titleProp, "Keyboard shortcuts");
122
+ const thenLabel = (0, core_1.useCrispMessage)(thenLabelProp, "then");
123
+ return ((0, jsx_runtime_1.jsx)(drawer_1.Drawer, { open: open, onOpenChange: onOpenChange, title: title, closeLabel: closeLabel, className: (0, core_1.cx)("crisp-shortcutssheet-panel", className), ...rest, children: (0, jsx_runtime_1.jsx)(drawer_1.DrawerBody, { children: (0, jsx_runtime_1.jsx)("div", { className: "crisp-shortcutssheet-body", children: sections.map((section) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "crisp-shortcutssheet-section-label", children: section.label }), section.rows.map((row) => ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-shortcutssheet-row", children: [(0, jsx_runtime_1.jsx)("div", { className: "crisp-shortcutssheet-desc", children: row.description }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-shortcutssheet-keys", children: row.steps.map((step, stepIndex) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [stepIndex > 0 && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-shortcutssheet-then", children: thenLabel })), step.map((glyph, glyphIndex) => ((0, jsx_runtime_1.jsx)(kbd_1.Kbd, { children: glyph }, glyphIndex)))] }, stepIndex))) })] }, String(row.description))))] }, String(section.label)))) }) }) }));
124
+ }
125
+ ShortcutsSheet.displayName = "ShortcutsSheet";
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shortcutssheetRecipe = void 0;
4
+ const core_1 = require("../../core");
5
+ const tokens_1 = require("../../tokens");
6
+ // Attio's "Keyboard shortcuts" panel (crisp#615), live-measured off
7
+ // app.attio.com/techpartners — a second overlay reached from Help →
8
+ // "Shortcuts": 360px wide (narrower than Drawer's own 420px default, hence
9
+ // the width override below), 16px body padding (already Drawer's own
10
+ // `crisp-drawer-body`, unchanged), rows 10px apart, a 20px gap before a new
11
+ // section (expressed as the flex column's own 10px `gap` plus another 10px
12
+ // on every section label but the first, rather than a second gap value),
13
+ // section labels 12px/500, row descriptions 14px/500 — both the SAME
14
+ // `color-mix(fgPrimary, 63%)` muted-text tint RecordPage's own notes already
15
+ // established (crisp#871), and the "then" connector between a sequential
16
+ // shortcut's two steps at 11px/500 in Kbd's own 50%-fgPrimary tint (the
17
+ // same de-emphasis, on the same kind of supporting glyph).
18
+ const config = (0, core_1.defineRecipe)({
19
+ name: "shortcutssheet",
20
+ base: "",
21
+ globalCss: `
22
+ /* Overrides Drawer's own 420px default (specificity: .crisp-drawer
23
+ .crisp-drawer-content.crisp-shortcutssheet-panel, higher than
24
+ Drawer's .crisp-drawer .crisp-drawer-content regardless of which
25
+ chunk of dist/styles.css concatenates first). */
26
+ .crisp-drawer .crisp-drawer-content.crisp-shortcutssheet-panel { width: 360px; }
27
+
28
+ .crisp-shortcutssheet-body { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["2.5"]}; }
29
+ .crisp-shortcutssheet-section-label {
30
+ font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium};
31
+ color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent);
32
+ }
33
+ .crisp-shortcutssheet-section-label:not(:first-child) { margin-top: ${tokens_1.contract.space["2.5"]}; }
34
+ .crisp-shortcutssheet-row { display: flex; align-items: center; justify-content: space-between; gap: ${tokens_1.contract.space["1"]}; }
35
+ .crisp-shortcutssheet-desc {
36
+ font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium};
37
+ color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent);
38
+ }
39
+ .crisp-shortcutssheet-keys { display: flex; align-items: center; gap: ${tokens_1.contract.space["1"]}; flex-shrink: 0; }
40
+ .crisp-shortcutssheet-then {
41
+ font-size: ${tokens_1.contract.text.xs}; font-weight: ${tokens_1.contract.weight.medium};
42
+ color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 50%, transparent);
43
+ }
44
+ `,
45
+ variants: {},
46
+ defaultVariants: {},
47
+ compoundVariants: [],
48
+ });
49
+ exports.shortcutssheetRecipe = (0, core_1.resolveRecipe)(config);
50
+ exports.default = config;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.taskeditpopoverRecipe = exports.TaskEditPopover = void 0;
4
+ var taskeditpopover_1 = require("./taskeditpopover");
5
+ Object.defineProperty(exports, "TaskEditPopover", { enumerable: true, get: function () { return taskeditpopover_1.TaskEditPopover; } });
6
+ var taskeditpopover_recipe_1 = require("./taskeditpopover.recipe");
7
+ Object.defineProperty(exports, "taskeditpopoverRecipe", { enumerable: true, get: function () { return taskeditpopover_recipe_1.taskeditpopoverRecipe; } });