@nascentdigital/funnel-editor 4.6.7 → 5.0.2

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 (185) hide show
  1. package/dist/EditorApp.js +1 -1
  2. package/dist/EditorRoutes.js +7 -5
  3. package/dist/changesets/screens/ChangeSetViewer.js +1 -1
  4. package/dist/changesets/screens/ChangeSetsExplorer.js +1 -2
  5. package/dist/collection/hooks/CollectionController.d.ts +5 -16
  6. package/dist/collection/hooks/CollectionController.js +18 -37
  7. package/dist/collection/hooks/ICollectionController.d.ts +24 -0
  8. package/dist/collection/hooks/ICollectionController.js +20 -0
  9. package/dist/collection/hooks/index.d.ts +1 -0
  10. package/dist/collection/hooks/index.js +1 -0
  11. package/dist/collection/hooks/useCollectionController.d.ts +3 -3
  12. package/dist/collection/screens/CollectionEditor.js +2 -2
  13. package/dist/components.d.ts +15 -3
  14. package/dist/components.js +18 -3
  15. package/dist/core/components/feedback/dialog/MinimalDialogLayout.js +1 -1
  16. package/dist/core/components/fields/BooleanField.d.ts +2 -1
  17. package/dist/core/components/fields/BooleanField.js +2 -2
  18. package/dist/core/components/fields/DateField.d.ts +2 -1
  19. package/dist/core/components/fields/DateField.js +2 -2
  20. package/dist/core/components/fields/DynamicPagesEditor.d.ts +2 -1
  21. package/dist/core/components/fields/DynamicPagesEditor.js +1 -1
  22. package/dist/core/components/fields/EnumField.d.ts +2 -1
  23. package/dist/core/components/fields/EnumField.js +2 -2
  24. package/dist/core/components/fields/FieldCard.d.ts +1 -0
  25. package/dist/core/components/fields/FieldCard.js +8 -1
  26. package/dist/core/components/fields/FieldEditor.d.ts +2 -1
  27. package/dist/core/components/fields/FieldEditor.js +11 -11
  28. package/dist/core/components/fields/FieldLayout.d.ts +2 -1
  29. package/dist/core/components/fields/FieldLayout.js +3 -3
  30. package/dist/core/components/fields/ListEditor.d.ts +2 -1
  31. package/dist/core/components/fields/ListEditor.js +5 -6
  32. package/dist/core/components/fields/OptInField.d.ts +2 -1
  33. package/dist/core/components/fields/OptInField.js +43 -3
  34. package/dist/core/components/fields/RichTextEditor.js +1 -1
  35. package/dist/core/components/fields/RichTextField.d.ts +2 -1
  36. package/dist/core/components/fields/RichTextField.js +3 -5
  37. package/dist/core/components/fields/TextField.d.ts +2 -0
  38. package/dist/core/components/fields/TextField.js +2 -2
  39. package/dist/core/components/fields/TimestampField.d.ts +2 -1
  40. package/dist/core/components/fields/TimestampField.js +3 -3
  41. package/dist/core/components/fields/asset/AssetEditor.d.ts +1 -2
  42. package/dist/core/components/fields/asset/AssetEditor.js +29 -49
  43. package/dist/core/components/fields/asset/AssetPicker.js +6 -6
  44. package/dist/core/components/fields/asset/AssetUploader.d.ts +1 -2
  45. package/dist/core/components/fields/asset/AssetUploader.js +39 -35
  46. package/dist/core/components/fields/asset/preview/VideoPreview.js +16 -11
  47. package/dist/core/components/fields/asset/useAssetFields.d.ts +2 -17
  48. package/dist/core/components/fields/asset/useAssetFields.js +0 -21
  49. package/dist/core/components/fields/collection/CollectionEditor.d.ts +2 -1
  50. package/dist/core/components/fields/collection/CollectionEditor.js +18 -4
  51. package/dist/core/components/fields/collection/CollectionPicker.d.ts +2 -2
  52. package/dist/core/components/fields/collection/CollectionPicker.js +3 -4
  53. package/dist/core/components/fields/dynamicPages/PagePriorityDialog.js +1 -1
  54. package/dist/core/components/fields/embed/EmbeddedVideoEditor.d.ts +2 -2
  55. package/dist/core/components/fields/embed/EmbeddedVideoEditor.js +50 -31
  56. package/dist/core/components/fields/factories/AssetFactory.d.ts +3 -3
  57. package/dist/core/components/fields/factories/AssetFactory.js +18 -13
  58. package/dist/core/components/fields/factories/CollectionFactory.d.ts +3 -3
  59. package/dist/core/components/fields/factories/CollectionFactory.js +20 -13
  60. package/dist/core/components/fields/factories/EmbeddedVideoFactory.d.ts +3 -3
  61. package/dist/core/components/fields/factories/EmbeddedVideoFactory.js +17 -8
  62. package/dist/core/components/fields/factories/FieldValueFactory.d.ts +7 -5
  63. package/dist/core/components/fields/factories/FieldValueFactory.js +57 -13
  64. package/dist/core/components/fields/factories/LinkFactory.d.ts +3 -3
  65. package/dist/core/components/fields/factories/LinkFactory.js +17 -8
  66. package/dist/core/components/fields/factories/MediaFactory.d.ts +13 -0
  67. package/dist/core/components/fields/factories/MediaFactory.js +212 -0
  68. package/dist/core/components/fields/factories/ObjectFactory.d.ts +3 -2
  69. package/dist/core/components/fields/factories/ObjectFactory.js +16 -2
  70. package/dist/core/components/fields/factories/TextFactory.d.ts +3 -3
  71. package/dist/core/components/fields/factories/TextFactory.js +16 -10
  72. package/dist/core/components/fields/link/LinkEditor.d.ts +2 -2
  73. package/dist/core/components/fields/link/LinkEditor.js +18 -6
  74. package/dist/core/components/fields/list/CreateFieldButton.js +1 -1
  75. package/dist/core/components/fields/media/MediaCard.d.ts +7 -0
  76. package/dist/core/components/fields/media/MediaCard.js +92 -0
  77. package/dist/core/components/fields/media/MediaEditor.d.ts +36 -0
  78. package/dist/core/components/fields/media/MediaEditor.js +264 -0
  79. package/dist/core/components/fields/media/index.d.ts +2 -0
  80. package/dist/core/components/fields/media/index.js +18 -0
  81. package/dist/core/components/fields/object/ObjectEditor.d.ts +2 -1
  82. package/dist/core/components/fields/object/ObjectEditor.js +16 -2
  83. package/dist/core/components/fields/page/PagePicker.js +1 -1
  84. package/dist/core/components/interaction/Combobox.js +1 -1
  85. package/dist/core/components/interaction/MultiSelectControls.js +2 -5
  86. package/dist/core/components/interaction/Popup.d.ts +11 -7
  87. package/dist/core/components/interaction/Popup.js +8 -6
  88. package/dist/core/components/interaction/QuickEditor.js +1 -1
  89. package/dist/core/components/interaction/QuickInput.d.ts +2 -4
  90. package/dist/core/components/interaction/QuickInput.js +6 -2
  91. package/dist/core/components/interaction/QuickPicker.js +1 -1
  92. package/dist/core/components/interaction/SideSheet.js +1 -1
  93. package/dist/core/components/interaction/centersheet/CenterSheet.js +7 -1
  94. package/dist/core/components/interaction/centersheet/CenterSheetContainer.js +3 -1
  95. package/dist/core/components/interaction/menu/Menu.d.ts +8 -19
  96. package/dist/core/components/interaction/menu/Menu.js +26 -60
  97. package/dist/core/components/interaction/menu/useMenuController.d.ts +4 -2
  98. package/dist/core/components/interaction/menu/useMenuController.js +4 -1
  99. package/dist/core/components/transitions/FadeIn.js +1 -1
  100. package/dist/core/components/visuals/Icon.d.ts +1 -1
  101. package/dist/core/components/visuals/Icon.js +3 -0
  102. package/dist/core/containers/AssetRepositoryContainer.d.ts +2 -0
  103. package/dist/core/containers/AssetRepositoryContainer.js +18 -0
  104. package/dist/core/containers/CollectionRepositoryContainer.d.ts +2 -0
  105. package/dist/core/containers/CollectionRepositoryContainer.js +18 -0
  106. package/dist/core/containers/PageRepositoryContainer.d.ts +2 -0
  107. package/dist/core/containers/PageRepositoryContainer.js +18 -0
  108. package/dist/core/containers/index.d.ts +3 -0
  109. package/dist/core/containers/index.js +19 -0
  110. package/dist/core/domain/Block.js +2 -1
  111. package/dist/core/domain/BlockConfiguration.d.ts +4 -1
  112. package/dist/core/domain/BlockConfiguration.js +59 -3
  113. package/dist/core/domain/Collection.d.ts +7 -25
  114. package/dist/core/domain/Collection.js +2 -16
  115. package/dist/core/domain/CollectionBrowser.d.ts +3 -2
  116. package/dist/core/domain/CollectionBrowser.js +3 -3
  117. package/dist/core/domain/CollectionFieldProxy.d.ts +12 -8
  118. package/dist/core/domain/CollectionFieldProxy.js +15 -9
  119. package/dist/core/domain/CollectionGroup.d.ts +0 -5
  120. package/dist/core/domain/CollectionGroup.js +0 -7
  121. package/dist/core/domain/CollectionSummary.d.ts +2 -2
  122. package/dist/core/domain/Collections.d.ts +3 -3
  123. package/dist/core/domain/Collections.js +4 -6
  124. package/dist/core/domain/ICollection.d.ts +72 -0
  125. package/dist/core/domain/ICollection.js +20 -0
  126. package/dist/core/domain/IPage.d.ts +16 -1
  127. package/dist/core/domain/Page.js +2 -2
  128. package/dist/core/domain/Pages.js +4 -6
  129. package/dist/core/domain/SectionBlock.js +2 -1
  130. package/dist/core/domain/Site.d.ts +4 -4
  131. package/dist/core/domain/Site.js +3 -5
  132. package/dist/core/domain/index.d.ts +1 -1
  133. package/dist/core/domain/index.js +1 -1
  134. package/dist/core/hooks/index.d.ts +4 -3
  135. package/dist/core/hooks/index.js +4 -3
  136. package/dist/core/hooks/useAssetRepository.d.ts +3 -0
  137. package/dist/core/hooks/useAssetRepository.js +11 -0
  138. package/dist/core/hooks/useCollection.d.ts +4 -4
  139. package/dist/core/hooks/useCollectionRepository.d.ts +3 -2
  140. package/dist/core/hooks/useCollectionRepository.js +4 -4
  141. package/dist/core/hooks/useCollections.js +4 -0
  142. package/dist/core/hooks/usePageRepository.d.ts +3 -2
  143. package/dist/core/hooks/usePageRepository.js +4 -4
  144. package/dist/core/hooks/useSite.js +4 -0
  145. package/dist/core/hooks/useTempFields.d.ts +2 -3
  146. package/dist/core/index.d.ts +1 -0
  147. package/dist/core/index.js +1 -0
  148. package/dist/core/repository/AssetRepository.d.ts +10 -0
  149. package/dist/core/repository/AssetRepository.js +22 -0
  150. package/dist/core/repository/CollectionRepository.d.ts +22 -21
  151. package/dist/core/repository/CollectionRepository.js +23 -161
  152. package/dist/core/repository/CollectionSerializer.d.ts +4 -1
  153. package/dist/core/repository/CollectionSerializer.js +3 -3
  154. package/dist/core/repository/IAssetRepository.d.ts +25 -0
  155. package/dist/core/repository/ICollectionRepository.d.ts +61 -0
  156. package/dist/core/repository/ICollectionRepository.js +2 -0
  157. package/dist/core/repository/IPageRepository.d.ts +40 -0
  158. package/dist/core/repository/IPageRepository.js +2 -0
  159. package/dist/core/repository/PageRepository.d.ts +5 -8
  160. package/dist/core/repository/PageRepository.js +7 -280
  161. package/dist/core/repository/SerializeCollectionUpdate.d.ts +8 -0
  162. package/dist/core/repository/SerializeCollectionUpdate.js +168 -0
  163. package/dist/core/repository/SerializePageUpdate.d.ts +10 -0
  164. package/dist/core/repository/SerializePageUpdate.js +292 -0
  165. package/dist/core/repository/index.d.ts +4 -0
  166. package/dist/core/repository/index.js +4 -0
  167. package/dist/core/splash/SplashContainer.d.ts +4 -2
  168. package/dist/core/splash/SplashContainer.js +3 -3
  169. package/dist/dashboard/screens/Dashboard.js +1 -1
  170. package/dist/devtools/screens/Devtools.js +1 -1
  171. package/dist/explore/components/CreatePageDialog.d.ts +2 -2
  172. package/dist/explore/screens/CollectionExplorer.js +1 -1
  173. package/dist/explore/screens/CollectionsExplorer.js +1 -1
  174. package/dist/explore/screens/PageExplorer.js +1 -1
  175. package/dist/explore/screens/SiteExplorer.js +1 -1
  176. package/dist/page/components/BlockEditor.js +1 -1
  177. package/dist/page/components/SettingsEditor.js +0 -7
  178. package/dist/page/components/config/BlockConfigButton.js +71 -14
  179. package/dist/page/screens/PageEditor.js +1 -1
  180. package/dist/styles/index.css +24 -20
  181. package/dist/styles/tailwind.js +1 -0
  182. package/dist/users/screens/UserExplorer.js +1 -1
  183. package/package.json +2 -2
  184. package/dist/core/domain/TranslateSchema.d.ts +0 -7
  185. /package/dist/core/{domain/TranslateSchema.js → repository/IAssetRepository.js} +0 -0
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  exports.ObjectEditor = void 0;
4
15
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -14,13 +25,16 @@ exports.ObjectEditor = (0, react_1.forwardRef)(function ObjectEditor(_, ref) {
14
25
  const [result, setResult] = (0, react_1.useState)();
15
26
  const [schema, setSchema] = (0, react_1.useState)();
16
27
  const [field, setField] = (0, react_1.useState)();
28
+ const [popupProps, setPopupProps] = (0, react_1.useState)();
17
29
  // sync field
18
30
  (0, hooks_1.useField)(field);
19
31
  // export service
20
32
  (0, react_1.useImperativeHandle)(ref, () => ({
21
- edit: async ({ schema, field: existingField }) => {
33
+ edit: async (_a) => {
34
+ var { schema, field: existingField } = _a, popupProps = __rest(_a, ["schema", "field"]);
22
35
  // reset state
23
36
  setSchema(schema);
37
+ setPopupProps(popupProps);
24
38
  // create new field (clone data from existing field if provided)
25
39
  const clonedField = funnel_core_1.ObjectField.forSchema(schema);
26
40
  if (existingField) {
@@ -58,5 +72,5 @@ exports.ObjectEditor = (0, react_1.forwardRef)(function ObjectEditor(_, ref) {
58
72
  return null;
59
73
  }
60
74
  // render
61
- return ((0, jsx_runtime_1.jsxs)(interaction_1.CenterSheet, { className: "h-full flex flex-col gap-l6", name: field.name, open: !!deferral && result === undefined, onClose: onClose, onClosed: onClosed, children: [(0, jsx_runtime_1.jsxs)("div", { className: "h-48 flex items-center gap-l4 px-l7", children: [(0, jsx_runtime_1.jsx)(interaction_1.IconButton, { icon: "X", onClick: onClose }), (0, jsx_runtime_1.jsx)("h1", { className: "label-sm text-content-primary", children: field.name }), (0, jsx_runtime_1.jsx)("span", { className: "flex-1" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "primary", size: "sm", disabled: !field.modified, onClick: () => setResult(field.value), children: field.isNew ? 'Create' : 'Update' })] }), (0, jsx_runtime_1.jsx)(FieldsPanel_1.FieldsPanel, { className: "flex-1 px-l7", title: schema.name, fields: field.fields })] }));
75
+ return ((0, jsx_runtime_1.jsxs)(interaction_1.CenterSheet, { className: "h-full flex flex-col gap-l6", name: field.name, open: !!deferral && result === undefined, onClose: onClose, onClosed: onClosed, children: [(0, jsx_runtime_1.jsxs)("div", { className: "h-48 flex items-center gap-l8 px-l7", children: [(0, jsx_runtime_1.jsx)(interaction_1.IconButton, { icon: "X", onClick: onClose }), (0, jsx_runtime_1.jsx)("h1", { className: "label-sm text-content-primary", children: field.name }), (0, jsx_runtime_1.jsx)("span", { className: "flex-1" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "primary", size: "sm", disabled: !field.modified, onClick: () => setResult(field.value), children: field.isNew ? 'Create' : 'Update' })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 flex flex-col gap-l10 px-l6 py-l10 overflow-y-scroll scrollbar-thin bg-background", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(FieldsPanel_1.FieldsPanel, { className: "flex-1", title: schema.name, fields: field.fields, autoFocus: true }) })] }));
62
76
  });
@@ -205,7 +205,7 @@ exports.PagePicker = (0, react_1.forwardRef)(function PagePicker({ language }, r
205
205
  ? 'Primary'
206
206
  : filter.template.name }), tagOptions === null || tagOptions === void 0 ? void 0 : tagOptions.map(({ group, tags: groupTags }) => (0, jsx_runtime_1.jsx)(interaction_1.ChipFilters, { title: group.name, multiselect: true, options: groupTags.values().toArray(), selectedOptions: tagFilters.filter(tag => groupTags.has(tag)), onToggle: (tag, selected) => setTagFilters(tags => selected
207
207
  ? [...tags, tag]
208
- : tags.filter(t => t !== tag)), onToggleAll: () => setTagFilters(tags => tags.filter(tag => !groupTags.has(tag))), renderLabel: tag => tag.name }, group.id))] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: renderPicker({ site, language, disabledIds, error, pageFilters, pageFilter, tagOptions, tagFilters, pagesSchema, pages, onPick, setTagTooltip }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end items-center p-l8 border-t border-solid border-border-l1", children: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onCancel, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(interaction_1.Popup, { className: (0, classnames_1.default)('max-w-[200px] bg-surface2 rounded-md p-l5', 'border border-solid border-border-l1 shadow-tooltip', 'flex flex-wrap items-center gap-l4'), open: !!tagTooltip, anchor: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.anchor, anchorOffset: 4, placement: "top", disableOverlay: true, onClose: () => setTagTooltip(undefined), children: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.tags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)) })] })] }));
208
+ : tags.filter(t => t !== tag)), onToggleAll: () => setTagFilters(tags => tags.filter(tag => !groupTags.has(tag))), renderLabel: tag => tag.name }, group.id))] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: renderPicker({ site, language, disabledIds, error, pageFilters, pageFilter, tagOptions, tagFilters, pagesSchema, pages, onPick, setTagTooltip }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end items-center p-l8 border-t border-solid border-border-l1", children: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onCancel, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(interaction_1.Popup, { className: (0, classnames_1.default)('max-w-[200px] bg-surface2 rounded-md p-l5', 'border border-solid border-border-l1 shadow-tooltip', 'flex flex-wrap items-center gap-l4'), open: !!tagTooltip, anchor: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.anchor, anchorOffset: 4, placement: "top", disableOverlay: true, onClose: () => setTagTooltip(undefined), children: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.tags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)) })] })] }));
209
209
  });
210
210
  function renderPicker({ site, language, disabledIds, error, pageFilters, pageFilter, tagOptions, tagFilters, pagesSchema, pages, onPick, setTagTooltip }) {
211
211
  // show error if we have one
@@ -70,7 +70,7 @@ function Combobox({ id: externalId, className, size = 'md', maxRows = 6, rowHeig
70
70
  }), style: {
71
71
  minWidth: button ? `${button.offsetWidth}px` : 'auto',
72
72
  maxHeight: maxRows * rowHeight + (rowPaddingY * 2)
73
- }, role: "listbox", children: options.map((option, index) => {
73
+ }, role: "listbox", tabIndex: -1, children: options.map((option, index) => {
74
74
  // render
75
75
  const optionKey = getOptionId(id, option);
76
76
  const selected = option.id === selectedOptionId;
@@ -57,11 +57,11 @@ exports.MultiSelectControls = (0, react_1.forwardRef)(function MultiSelectContro
57
57
  };
58
58
  // render controls when selecting
59
59
  if (selecting) {
60
- return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('flex flex-wrap items-center gap-l5', className), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "sm", onClick: selectedIdCount < idCount ? onSelectAll : onDeselectAll, children: selectedIdCount < idCount ? selectAllLabel : deselectAllLabel }), actions, (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "sm", onClick: onSelectCancel, children: cancelLabel })] }));
60
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('flex flex-wrap items-center gap-l5', className), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "xs", onClick: selectedIdCount < idCount ? onSelectAll : onDeselectAll, children: selectedIdCount < idCount ? selectAllLabel : deselectAllLabel }), actions, (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "xs", onClick: onSelectCancel, children: cancelLabel })] }));
61
61
  }
62
62
  // or render control to enter selection
63
63
  else {
64
- return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "sm", onClick: onSelectStart, children: editLabel }) }));
64
+ return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "xs", onClick: onSelectStart, children: editLabel }) }));
65
65
  }
66
66
  });
67
67
  // hook
@@ -73,16 +73,13 @@ function useMultiSelectControls() {
73
73
  (0, react_1.useEffect)(() => {
74
74
  // skip if not bound
75
75
  if (!multiSelect) {
76
- console.debug('[useMultiSelectControls] controls not ready');
77
76
  return;
78
77
  }
79
- console.debug('[useMultiSelectControls] binding to controls');
80
78
  // touch on event
81
79
  const subscription = multiSelect.events$.subscribe(touch);
82
80
  // unsubscribe on unmount
83
81
  return () => subscription.unsubscribe();
84
82
  }, [touch, multiSelect]);
85
- console.debug('[useMultiSelectControls] updated', multiSelect);
86
83
  // return selector
87
84
  return [setMultiSelect, multiSelect];
88
85
  }
@@ -1,13 +1,15 @@
1
1
  import { Callback, Placement, Rect } from '@nascentdigital/funnel-core';
2
2
  import { HTMLContainer } from '@nascentdigital/funnel-ui';
3
- import { HTMLAttributes, ReactNode, CSSProperties } from 'react';
4
- export declare function Popup({ className, style, anchor, anchorOffset, placement, viewportPadding, animation, backdrop, disabled, disableDismiss, disableOverlay, open, onOpened: onOpenedRaw, onClose, onClosed: onClosedRaw, onKeyDown: onKeyDownRaw, children, ...props }: Popup.Props): import("react/jsx-runtime").JSX.Element | null;
3
+ import { CSSProperties, HTMLAttributes, ReactNode } from 'react';
4
+ export declare function Popup({ className, style, anchor, anchorOffset, placement, animation, backdrop, disabled, disableDismiss, disableOverlay, open, onOpened: onOpenedRaw, onClose, onClosed: onClosedRaw, onKeyDown: onKeyDownRaw, children, ...props }: Popup.Props): import("react/jsx-runtime").JSX.Element | null;
5
5
  export declare namespace Popup {
6
+ type Anchor = string;
7
+ type Animation = 'in' | 'out' | 'in-out';
8
+ type Backdrop = 'none' | 'glass';
6
9
  type Props = HTMLAttributes<HTMLDivElement> & {
7
- anchor?: Anchor;
10
+ anchor?: Anchor | ReactNode;
8
11
  anchorOffset?: number;
9
12
  placement?: Placement;
10
- viewportPadding?: number;
11
13
  animation?: Animation;
12
14
  backdrop?: Backdrop;
13
15
  disabled?: boolean;
@@ -18,9 +20,11 @@ export declare namespace Popup {
18
20
  onClose?: Callback.Void;
19
21
  onClosed?: Callback.Void;
20
22
  };
21
- type Anchor = string | ReactNode;
22
- type Animation = 'in' | 'out' | 'in-out';
23
- type Backdrop = 'none' | 'glass';
23
+ namespace Props {
24
+ type Delegated = Pick<Props, 'anchorOffset' | 'placement'> & {
25
+ anchor?: Popup.Anchor;
26
+ };
27
+ }
24
28
  const anchorClassName: "anchor/[--nd-popup-anchor]";
25
29
  function getAnchorStyle(anchorId: string, styles?: CSSProperties): CSSProperties;
26
30
  type Frame = {
@@ -26,7 +26,7 @@ const react_dom_1 = require("react-dom");
26
26
  const Animate_1 = require("./Animate");
27
27
  // component
28
28
  function Popup(_a) {
29
- var { className, style = {}, anchor, anchorOffset, placement = 'bottom', viewportPadding, animation = 'in-out', backdrop = 'none', disabled = false, disableDismiss = false, disableOverlay = false, open = false, onOpened: onOpenedRaw = funnel_core_1.Fn.NoOp, onClose = funnel_core_1.Fn.NoOp, onClosed: onClosedRaw = funnel_core_1.Fn.NoOp, onKeyDown: onKeyDownRaw, children } = _a, props = __rest(_a, ["className", "style", "anchor", "anchorOffset", "placement", "viewportPadding", "animation", "backdrop", "disabled", "disableDismiss", "disableOverlay", "open", "onOpened", "onClose", "onClosed", "onKeyDown", "children"]);
29
+ var { className, style = {}, anchor, anchorOffset = 4, placement = 'bottom', animation = 'in-out', backdrop = 'none', disabled = false, disableDismiss = false, disableOverlay = false, open = false, onOpened: onOpenedRaw = funnel_core_1.Fn.NoOp, onClose = funnel_core_1.Fn.NoOp, onClosed: onClosedRaw = funnel_core_1.Fn.NoOp, onKeyDown: onKeyDownRaw, children } = _a, props = __rest(_a, ["className", "style", "anchor", "anchorOffset", "placement", "animation", "backdrop", "disabled", "disableDismiss", "disableOverlay", "open", "onOpened", "onClose", "onClosed", "onKeyDown", "children"]);
30
30
  // bind context
31
31
  const id = (0, react_1.useId)();
32
32
  const anchorId = typeof anchor === 'string'
@@ -89,7 +89,7 @@ function Popup(_a) {
89
89
  }
90
90
  };
91
91
  // render
92
- const { popupContainerClassName, popupClassName } = getPopupClassNames({ anchor, anchorId, anchorOffset, placement });
92
+ const { popupContainerClassName, popupClassName, popupStyles } = getPopupClassNames({ anchor, anchorId, anchorOffset, placement });
93
93
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchor && typeof anchor !== 'string' &&
94
94
  (0, jsx_runtime_1.jsx)(Popup.AnchorElement, { tag: "div", anchorId: anchorId, children: anchor }), (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", children: open &&
95
95
  (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(framer_motion_1.motion.div, { id: id, className: (0, classnames_1.default)(popupContainerClassName, 'fixed inset-0 z-popup', {
@@ -98,8 +98,8 @@ function Popup(_a) {
98
98
  (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { className: (0, classnames_1.default)('fixed inset-0 z-backdrop', {
99
99
  'backdrop-blur-[9px] bg-glass/backdrop will-change-[backdrop-filter]': backdrop === 'glass'
100
100
  }) }, "backdrop"), (0, jsx_runtime_1.jsx)("div", Object.assign({}, props, { ref: contentRef, className: (0, classnames_1.default)(className, popupClassName, 'pointer-events-auto'), style: anchor
101
- ? Popup.getAnchorStyle(anchorId, { margin: `${anchorOffset !== null && anchorOffset !== void 0 ? anchorOffset : 0}px` })
102
- : undefined, onKeyDown: onKeyDown, children: children }))] }, id) }) }), document.body)] }));
101
+ ? Popup.getAnchorStyle(anchorId, Object.assign({ margin: `${anchorOffset !== null && anchorOffset !== void 0 ? anchorOffset : 0}px` }, popupStyles))
102
+ : popupStyles, onKeyDown: onKeyDown, children: children }))] }, id) }) }), document.body)] }));
103
103
  }
104
104
  // extension
105
105
  (function (Popup) {
@@ -145,14 +145,16 @@ function getPopupClassNames({ anchor, placement }) {
145
145
  'anchored-left-span-bottom': placement === 'left-start',
146
146
  'anchored-right': placement === 'right',
147
147
  'anchored-bottom-span-left': placement === 'bottom-end'
148
- })
148
+ }),
149
+ popupStyles: { positionTryFallbacks: 'flip-y, flip-x' }
149
150
  };
150
151
  }
151
152
  // or treat as modal if there's no anchor
152
153
  else {
153
154
  return {
154
155
  popupContainerClassName: 'flex flex-col justify-end items-center sm:justify-center',
155
- popupClassName: 'z-dialog'
156
+ popupClassName: 'z-dialog',
157
+ popupStyles: {}
156
158
  };
157
159
  }
158
160
  }
@@ -29,5 +29,5 @@ function QuickEditor(_a) {
29
29
  'w-[320px]': size === 'md',
30
30
  'w-[288px]': size === 'sm'
31
31
  }), open: open, onClose: onClose, children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-content-primary flex justify-between items-center gap-l8 px-l8 pt-l8 pb-l4", children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-sm text-pretty", children: title }), (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { className: "shrink-0", icon: "X", size: "xs", onClick: onClose })] }), tip &&
32
- (0, jsx_runtime_1.jsx)(feedback_1.Note, { className: "mt-l2 mb-l4 mx-l8", variant: "tip", size: size === 'md' ? 'sm' : 'xs', children: (0, jsx_runtime_1.jsx)(funnel_ui_1.Markup, { markdown: `**Tip:** ${tip}` }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", children: children })] })));
32
+ (0, jsx_runtime_1.jsx)(feedback_1.Note, { className: "mt-l2 mb-l4 mx-l8", variant: "tip", size: size === 'md' ? 'sm' : 'xs', children: (0, jsx_runtime_1.jsx)(funnel_ui_1.Markup, { markdown: `**Tip:** ${tip}` }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", tabIndex: -1, children: children })] })));
33
33
  }
@@ -1,4 +1,4 @@
1
- import { RequiredBy, Schema } from '@nascentdigital/funnel-core';
1
+ import { Schema } from '@nascentdigital/funnel-core';
2
2
  import { Popup } from './Popup';
3
3
  export declare const QuickInput: import("react").ForwardRefExoticComponent<import("react").RefAttributes<QuickInput.Ref<Schema.Field.Type.Simple.NonRef>>>;
4
4
  export declare namespace QuickInput {
@@ -8,10 +8,8 @@ export declare namespace QuickInput {
8
8
  open(args: CaptureArgs<TSchema>): Promise<Schema.Field.Value.ForSimpleType<TSchema> | undefined>;
9
9
  close(): void;
10
10
  }
11
- type CaptureArgs<TSchema extends Schema.Field.Type.Simple.NonRef = Schema.Field.Type.Simple.NonRef> = PopupProps & {
11
+ type CaptureArgs<TSchema extends Schema.Field.Type.Simple.NonRef = Schema.Field.Type.Simple.NonRef> = Popup.Props.Delegated & {
12
12
  schema: TSchema;
13
13
  initialValue?: Schema.Field.Value.ForSimpleType<TSchema>;
14
14
  };
15
15
  }
16
- type PopupProps = RequiredBy<Omit<Popup.Props, 'className' | 'animation' | 'disableClickDismiss' | 'open' | 'onOpened' | 'onClose' | 'onClosed' | 'children'>, 'anchor' | 'placement'>;
17
- export {};
@@ -127,11 +127,15 @@ exports.QuickInput = (0, react_1.forwardRef)(function QuickInput(_, ref) {
127
127
  break;
128
128
  }
129
129
  };
130
+ // skip if not ready
131
+ if (!popupProps) {
132
+ return null;
133
+ }
130
134
  // render
131
- return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, (popupProps !== null && popupProps !== void 0 ? popupProps : {}), { className: (0, classnames_1.default)('glass-overlay w-[330px] flex items-center gap-l5 p-l5 interpolate', 'border-t border-solid border-glass-stroke-l1 rounded-full', {
135
+ return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({ className: (0, classnames_1.default)('glass-overlay w-[330px] flex items-center gap-l5 p-l5 interpolate', 'border-t border-solid border-glass-stroke-l1 rounded-full', {
132
136
  'opacity-none': !opened,
133
137
  'opacity-full': opened
134
- }), animation: "out", open: deferral && ready, onOpened: () => setOpened(true), onClose: onClose, onClosed: () => setOpened(false), children: [(0, jsx_runtime_1.jsx)(FieldErrorController_1.FieldErrorController, { errorLevel: errorLevel, children: renderInput({ field, onKeyDown }) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "sm", onClick: onSave, children: "Save" })] })));
138
+ }), animation: "out", open: deferral && ready, onOpened: () => setOpened(true), onClose: onClose, onClosed: () => setOpened(false) }, popupProps, { children: [(0, jsx_runtime_1.jsx)(FieldErrorController_1.FieldErrorController, { errorLevel: errorLevel, children: renderInput({ field, onKeyDown }) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "sm", onClick: onSave, children: "Save" })] })));
135
139
  });
136
140
  function renderInput({ field, onKeyDown }) {
137
141
  // skip if there's no field
@@ -96,7 +96,7 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ variant, ti
96
96
  'flex flex-wrap gap-l5 items-center ': variant === 'card',
97
97
  'w-[288px]': variant === 'card' && items.length < 4,
98
98
  'w-[372px] max-h-[213px]': variant === 'card' && items.length >= 4
99
- }), children: items.map(item => renderCard({
99
+ }), tabIndex: -1, children: items.map(item => renderCard({
100
100
  item,
101
101
  content: renderItem(item),
102
102
  selected: item.id === selectedItem,
@@ -154,7 +154,7 @@ function SideSheet(_a) {
154
154
  'w-full md:w-screen-sm': size === 'lg'
155
155
  }), variants: breakpoint === 'xs' || breakpoint === 'sm'
156
156
  ? Animate_1.Animate.Variants.slideFromBottom
157
- : Animate_1.Animate.Variants.slideFromLeft, initial: "initial", animate: "animate", exit: "exit", onAnimationComplete: definition => onAnimationComplete(definition), onKeyDown: onKeyDown, tabIndex: -1, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'w-full h-full max-h-full pointer-events-auto', 'flex flex-col', 'bg-background border-solid border-border-l1', 'max-md:border-t max-md:rounded-tl-md max-md:rounded-tr-md', 'md:border-l md:rounded-tl-md md:rounded-bl-md'), children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-sm text-content-primary px-l8 pt-l8 pb-l4", children: title }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", children: children }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('flex justify-end items-center gap-l4 p-l8', 'border-t border-solid border-border-l1'), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "sm", disabled: locked, onClick: onClose, children: "Cancel" }), customActions &&
157
+ : Animate_1.Animate.Variants.slideFromLeft, initial: "initial", animate: "animate", exit: "exit", onAnimationComplete: definition => onAnimationComplete(definition), onKeyDown: onKeyDown, tabIndex: -1, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'w-full h-full max-h-full pointer-events-auto', 'flex flex-col', 'bg-background border-solid border-border-l1', 'max-md:border-t max-md:rounded-tl-md max-md:rounded-tr-md', 'md:border-l md:rounded-tl-md md:rounded-bl-md'), children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-sm text-content-primary px-l8 pt-l8 pb-l4", children: title }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", tabIndex: -1, children: children }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('flex justify-end items-center gap-l4 p-l8', 'border-t border-solid border-border-l1'), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "sm", disabled: locked, onClick: onClose, children: "Cancel" }), customActions &&
158
158
  (0, jsx_runtime_1.jsx)("div", { className: "flex-1 flex justify-end items-center gap-l4", children: customActions }), (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "primary", size: "sm", loading: state === 'saving', disabled: disableSave || locked, onClick: onSave, children: renderSaveLabel(state) })] })] }) }))] }, id) }), document.body);
159
159
  }
160
160
  // helpers
@@ -34,8 +34,10 @@ exports.CenterSheet = (0, react_2.forwardRef)(function CenterSheet({ className,
34
34
  }), [open]);
35
35
  // handle open/close events
36
36
  (0, react_2.useEffect)(() => {
37
- // raise open event
37
+ // handle open change
38
+ let unlock = undefined;
38
39
  if (open) {
40
+ // raise open event
39
41
  eventBus.next({
40
42
  type: 'onOpen',
41
43
  sheetInfo: {
@@ -43,6 +45,8 @@ exports.CenterSheet = (0, react_2.forwardRef)(function CenterSheet({ className,
43
45
  name: nameRef.current
44
46
  }
45
47
  });
48
+ // lock tabbing
49
+ unlock = funnel_core_1.Browser.lockFocus(`#${CSS.escape(id)}`);
46
50
  }
47
51
  // or close event
48
52
  else {
@@ -51,6 +55,8 @@ exports.CenterSheet = (0, react_2.forwardRef)(function CenterSheet({ className,
51
55
  sheetId: id
52
56
  });
53
57
  }
58
+ // unlock tabbing on unmount (if locked)
59
+ return () => unlock && unlock();
54
60
  }, [id, eventBus, open]);
55
61
  // ensure close on unmount
56
62
  (0, react_2.useEffect)(() => {
@@ -58,7 +58,9 @@ function CenterSheetContainer({ children }) {
58
58
  // render
59
59
  const { sheets } = context;
60
60
  const active = sheets.length > 0;
61
- return ((0, jsx_runtime_1.jsxs)(CenterSheetContext_1.CenterSheetContext.Provider, { value: context, children: [children, (0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 pointer-events-none", children: (0, jsx_runtime_1.jsx)("div", { id: anchorId, className: "relative w-full h-full", children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('absolute inset-0 z-backdrop interpolate will-change-[backdrop-filter,opacity]', 'backdrop-blur-[9px] bg-glass-fill-l1', {
61
+ return ((0, jsx_runtime_1.jsxs)(CenterSheetContext_1.CenterSheetContext.Provider, { value: context, children: [(0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('w-dvw h-dvh', {
62
+ 'pointer-events-none': active
63
+ }), children: children }), (0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 pointer-events-none", children: (0, jsx_runtime_1.jsx)("div", { id: anchorId, className: "relative w-full h-full", children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('absolute inset-0 z-backdrop interpolate will-change-[backdrop-filter,opacity]', 'backdrop-blur-[9px] bg-glass-fill-l1/tint3', {
62
64
  'pointer-events-none opacity-none': !active,
63
65
  'pointer-events-auto opacity-full': active
64
66
  }) }, "backdrop") }) })] }));
@@ -1,25 +1,14 @@
1
1
  import { Callback } from '@nascentdigital/funnel-core';
2
2
  import { Popup } from '../Popup';
3
- import { MenuItem } from './MenuItem';
4
3
  import { MenuController } from './useMenuController';
5
4
  export declare function Menu<TItemId extends string>(props: Menu.Props<TItemId>): import("react/jsx-runtime").JSX.Element;
6
5
  export declare namespace Menu {
7
- type Props<TItemId extends string> = Props.Static<TItemId> | Props.Controlled<TItemId>;
8
- namespace Props {
9
- type Base<TItemId extends string> = {
10
- label?: string;
11
- title?: string;
12
- onItemClick?: Callback<TItemId>;
13
- };
14
- export type Static<TItemId extends string> = Omit<Popup.Props, 'children'> & Base<TItemId> & {
15
- items: ReadonlyArray<MenuItem<TItemId>>;
16
- controller?: never;
17
- selectedItem?: TItemId;
18
- };
19
- export type Controlled<TItemId extends string> = Omit<Popup.Props, 'anchor' | 'open' | 'children'> & Base<TItemId> & {
20
- items?: never;
21
- controller: MenuController<TItemId>;
22
- };
23
- export {};
24
- }
6
+ type Props<TItemId extends string> = Omit<Popup.Props.Delegated, 'anchor'> & {
7
+ className?: string;
8
+ label?: string;
9
+ title?: string;
10
+ controller: MenuController<TItemId>;
11
+ onItemClick?: Callback<TItemId>;
12
+ onClose?: Callback.Void;
13
+ };
25
14
  }
@@ -15,74 +15,40 @@ function Menu(props) {
15
15
  const { className, label, title } = props;
16
16
  const { popupProps, menuListProps } = getPopupMenuProps(props);
17
17
  // render
18
- return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, popupProps, { className: (0, classnames_1.default)(className, 'min-w-[200px] glass-overlay rounded-lg overflow-hidden'), children: [(label || title) &&
18
+ return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({ className: (0, classnames_1.default)(className, 'min-w-[200px] glass-overlay rounded-lg overflow-hidden') }, popupProps, { children: [(label || title) &&
19
19
  (0, jsx_runtime_1.jsxs)("div", { className: "border-b border-solid border-border-l1 px-l6 pt-l4 pb-l5", children: [label &&
20
20
  (0, jsx_runtime_1.jsx)("span", { className: "block body-xs text-content-secondary", children: label }), title &&
21
21
  (0, jsx_runtime_1.jsx)("h3", { className: "heading-xs text-content-primary ", children: title })] }), (0, jsx_runtime_1.jsx)(MenuList_1.MenuList, Object.assign({}, menuListProps))] })));
22
22
  }
23
23
  function getPopupMenuProps(props) {
24
- var _a, _b, _c, _d;
24
+ var _a;
25
25
  // handle controlled menu
26
26
  const anchorOffset = 4;
27
- const viewportPadding = 6;
28
- if (isMenuControlled(props)) {
29
- const { controller, onClose = funnel_core_1.Fn.NoOp } = props;
30
- return {
31
- popupProps: {
32
- placement: props.placement,
33
- anchorOffset: (_a = props.anchorOffset) !== null && _a !== void 0 ? _a : anchorOffset,
34
- viewportPadding: (_b = props.viewportPadding) !== null && _b !== void 0 ? _b : viewportPadding,
35
- anchor: controller.anchor,
36
- open: controller.isOpen,
37
- onClose: () => {
38
- controller.close();
39
- onClose();
40
- }
41
- },
42
- menuListProps: {
43
- items: controller.items,
44
- selectedItem: controller.selectedItem,
45
- onItemClick: (id) => {
46
- // close menu
47
- controller.close();
48
- // update selected item
49
- controller.selectedItem = id;
50
- // raise click
51
- if (props.onItemClick) {
52
- props.onItemClick(id);
53
- }
54
- }
27
+ const { controller, onClose = funnel_core_1.Fn.NoOp } = props;
28
+ return {
29
+ popupProps: {
30
+ anchor: controller.anchor,
31
+ anchorOffset: (_a = props.anchorOffset) !== null && _a !== void 0 ? _a : anchorOffset,
32
+ placement: props.placement,
33
+ open: controller.isOpen,
34
+ onClose: () => {
35
+ controller.close();
36
+ onClose();
55
37
  }
56
- };
57
- }
58
- // or uncontrolled
59
- else {
60
- return {
61
- popupProps: {
62
- placement: props.placement,
63
- anchorOffset: (_c = props.anchorOffset) !== null && _c !== void 0 ? _c : anchorOffset,
64
- viewportPadding: (_d = props.viewportPadding) !== null && _d !== void 0 ? _d : viewportPadding,
65
- anchor: props.anchor,
66
- open: props.open,
67
- onClose: props.onClose
68
- },
69
- menuListProps: {
70
- items: props.items,
71
- selectedItem: props.selectedItem,
72
- onItemClick: (id) => {
73
- // close menu
74
- if (props.onClose) {
75
- props.onClose();
76
- }
77
- // raise click
78
- if (props.onItemClick) {
79
- props.onItemClick(id);
80
- }
38
+ },
39
+ menuListProps: {
40
+ items: controller.items,
41
+ selectedItem: controller.selectedItem,
42
+ onItemClick: (id) => {
43
+ // close menu
44
+ controller.close();
45
+ // update selected item
46
+ controller.selectedItem = id;
47
+ // raise click
48
+ if (props.onItemClick) {
49
+ props.onItemClick(id);
81
50
  }
82
51
  }
83
- };
84
- }
85
- }
86
- function isMenuControlled(props) {
87
- return 'controller' in props;
52
+ }
53
+ };
88
54
  }
@@ -1,4 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
+ import { Popup } from '../Popup';
2
3
  import { MenuItem } from './MenuItem';
3
4
  export declare function useMenuController<TItemId extends string = string, TContext = any>(items?: ReadonlyArray<MenuItem<TItemId>>): MenuController<TItemId, TContext>;
4
5
  export declare class MenuController<TItemId extends string, TContext = any> {
@@ -6,17 +7,18 @@ export declare class MenuController<TItemId extends string, TContext = any> {
6
7
  private _items?;
7
8
  private _selectedItem?;
8
9
  private _anchor?;
10
+ private _open;
9
11
  constructor(items?: ReadonlyArray<MenuItem<TItemId>>);
10
12
  get items(): ReadonlyArray<MenuItem<TItemId>>;
11
13
  set items(items: ReadonlyArray<MenuItem<TItemId>> | undefined);
12
14
  get selectedItem(): TItemId | undefined;
13
15
  set selectedItem(item: TItemId | undefined);
14
- get anchor(): string | undefined;
16
+ get anchor(): Popup.Anchor | undefined;
15
17
  private _context?;
16
18
  get context(): TContext | undefined;
17
19
  get changed$(): Observable<Date>;
18
20
  get isOpen(): boolean;
19
- open(anchor: string, context?: TContext): void;
21
+ open(anchor?: Popup.Anchor, context?: TContext): void;
20
22
  close(): void;
21
23
  private raiseChange;
22
24
  }
@@ -26,6 +26,7 @@ class MenuController {
26
26
  // initialize instance variables
27
27
  this._changed$ = new rxjs_1.Subject();
28
28
  this._items = items;
29
+ this._open = false;
29
30
  }
30
31
  get items() {
31
32
  var _a;
@@ -52,15 +53,17 @@ class MenuController {
52
53
  return this._changed$;
53
54
  }
54
55
  get isOpen() {
55
- return !!this._anchor;
56
+ return this._open;
56
57
  }
57
58
  open(anchor, context) {
58
59
  this._anchor = anchor;
59
60
  this._context = context;
61
+ this._open = true;
60
62
  this.raiseChange();
61
63
  }
62
64
  close() {
63
65
  delete this._anchor;
66
+ this._open = false;
64
67
  this.raiseChange();
65
68
  }
66
69
  raiseChange() {
@@ -25,5 +25,5 @@ function FadeIn(_a) {
25
25
  // render
26
26
  return ((0, jsx_runtime_1.jsx)(react_1.motion.div, Object.assign({ className: (0, classnames_1.default)(className, {
27
27
  'will-change-[opacity,filter]': variant === 'blur'
28
- }), variants: interaction_1.Animate.Variants.fade, initial: "initial", animate: "animate", exit: "exit" }, props)));
28
+ }), variants: interaction_1.Animate.Variants.fade, initial: "initial", animate: "animate", exit: "exit" }, props, { tabIndex: -1 })));
29
29
  }
@@ -6,7 +6,7 @@ export declare namespace Icon {
6
6
  size?: Size;
7
7
  };
8
8
  type Size = 'xl' | 'lg' | 'md' | 'sm' | 'xs' | 'xxs' | 'nav' | 'card' | Sizing;
9
- type Variant = 'Archive' | 'ArrowLeft' | 'ArrowRight' | 'ArrowLeftRight' | 'Atom' | 'Blocks' | 'Bold' | 'Check' | 'ChevronDown' | 'ChevronRight' | 'ChevronUp' | 'Circle' | 'CircleAlert' | 'CircleCheck' | 'CircleCheckBig' | 'CirclePlus' | 'CircleQuestionMark' | 'CloudCheck' | 'CloudUpload' | 'CornerDownRight' | 'EllipsisVertical' | 'Eye' | 'EyeOff' | 'File' | 'FileDown' | 'FilePlusCorner' | 'FileSearchCorner' | 'Goal' | 'Globe' | 'GripVertical' | 'HatGlasses' | 'History' | 'Highlighter' | 'Image' | 'ImageDown' | 'Info' | 'Italic' | 'Layers' | 'LayoutTemplate' | 'Link' | 'Link2' | 'List' | 'ListChecks' | 'ListIndentDecrease' | 'ListIndentIncrease' | 'ListOrdered' | 'Lock' | 'LockOpen' | 'Mail' | 'MessageSquareQuote' | 'Minus' | 'Monitor' | 'MonitorCog' | 'Moon' | 'NotebookPen' | 'Pencil' | 'Pin' | 'Plus' | 'Redo' | 'RefreshCw' | 'RotateCcw' | 'RotateCw' | 'SearchCode' | 'Settings' | 'Smartphone' | 'SquarePlay' | 'Star' | 'Strikethrough' | 'Subscript' | 'Sun' | 'Superscript' | 'TextAlignStart' | 'Trash' | 'TriangleAlert' | 'Trophy' | 'Underline' | 'Undo' | 'Upload' | 'UserRound' | 'X';
9
+ type Variant = 'Archive' | 'ArrowLeft' | 'ArrowRight' | 'ArrowLeftRight' | 'Atom' | 'Blocks' | 'Bold' | 'Check' | 'ChevronDown' | 'ChevronRight' | 'ChevronUp' | 'Circle' | 'CircleAlert' | 'CircleCheck' | 'CircleCheckBig' | 'CirclePlus' | 'CircleQuestionMark' | 'CloudCheck' | 'CloudUpload' | 'CornerDownRight' | 'EllipsisVertical' | 'Eye' | 'EyeOff' | 'File' | 'FileDown' | 'FilePlusCorner' | 'FileSearchCorner' | 'Goal' | 'Globe' | 'GripVertical' | 'HatGlasses' | 'History' | 'Highlighter' | 'Image' | 'ImageDown' | 'Info' | 'Italic' | 'Layers' | 'LayoutTemplate' | 'Link' | 'Link2' | 'List' | 'ListChecks' | 'ListIndentDecrease' | 'ListIndentIncrease' | 'ListOrdered' | 'Lock' | 'LockOpen' | 'Mail' | 'MessageSquareQuote' | 'Minus' | 'Monitor' | 'MonitorCog' | 'Moon' | 'NotebookPen' | 'Pencil' | 'Pin' | 'Plus' | 'Redo' | 'RefreshCw' | 'RotateCcw' | 'RotateCw' | 'Search' | 'SearchCode' | 'Settings' | 'Smartphone' | 'SquarePlay' | 'Star' | 'Strikethrough' | 'Subscript' | 'Sun' | 'Superscript' | 'TextAlignStart' | 'Trash' | 'TriangleAlert' | 'Trophy' | 'Underline' | 'Undo' | 'Upload' | 'UserRound' | 'X';
10
10
  namespace Variant {
11
11
  function filter(value: any): value is Variant;
12
12
  }
@@ -80,6 +80,7 @@ function Icon({ className, variant, size: sizing = 'md' }) {
80
80
  'RefreshCw',
81
81
  'RotateCcw',
82
82
  'RotateCw',
83
+ 'Search',
83
84
  'SearchCode',
84
85
  'Settings',
85
86
  'Smartphone',
@@ -235,6 +236,8 @@ function getIcon(variant) {
235
236
  return lucide_react_1.RotateCcw;
236
237
  case 'RotateCw':
237
238
  return lucide_react_1.RotateCw;
239
+ case 'Search':
240
+ return lucide_react_1.Search;
238
241
  case 'SearchCode':
239
242
  return lucide_react_1.SearchCode;
240
243
  case 'Settings':
@@ -0,0 +1,2 @@
1
+ import { PropsWithChildren } from 'react';
2
+ export declare function AssetRepositoryContainer({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetRepositoryContainer = AssetRepositoryContainer;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const client_1 = require("../client");
7
+ const hooks_1 = require("../hooks");
8
+ const repository_1 = require("../repository");
9
+ // container
10
+ function AssetRepositoryContainer({ children }) {
11
+ // bind to hooks
12
+ const client = (0, client_1.useEditorApi)();
13
+ const repository = (0, react_1.useMemo)(() => {
14
+ return new repository_1.AssetRepository(client);
15
+ }, [client]);
16
+ // render
17
+ return ((0, jsx_runtime_1.jsx)(hooks_1.AssetRepositoryContext.Provider, { value: repository, children: children }));
18
+ }
@@ -0,0 +1,2 @@
1
+ import { PropsWithChildren } from 'react';
2
+ export declare function CollectionRepositoryContainer({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CollectionRepositoryContainer = CollectionRepositoryContainer;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const client_1 = require("../client");
7
+ const hooks_1 = require("../hooks");
8
+ const repository_1 = require("../repository");
9
+ // container
10
+ function CollectionRepositoryContainer({ children }) {
11
+ // bind to hooks
12
+ const client = (0, client_1.useEditorApi)();
13
+ const repository = (0, react_1.useMemo)(() => {
14
+ return new repository_1.CollectionRepository(client);
15
+ }, [client]);
16
+ // render
17
+ return ((0, jsx_runtime_1.jsx)(hooks_1.CollectionRepositoryContext.Provider, { value: repository, children: children }));
18
+ }
@@ -0,0 +1,2 @@
1
+ import { PropsWithChildren } from 'react';
2
+ export declare function PageRepositoryContainer({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PageRepositoryContainer = PageRepositoryContainer;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const client_1 = require("../client");
7
+ const hooks_1 = require("../hooks");
8
+ const repository_1 = require("../repository");
9
+ // container
10
+ function PageRepositoryContainer({ children }) {
11
+ // bind to hooks
12
+ const client = (0, client_1.useEditorApi)();
13
+ const repository = (0, react_1.useMemo)(() => {
14
+ return new repository_1.PageRepository(client);
15
+ }, [client]);
16
+ // render
17
+ return ((0, jsx_runtime_1.jsx)(hooks_1.PageRepositoryContext.Provider, { value: repository, children: children }));
18
+ }
@@ -0,0 +1,3 @@
1
+ export * from './AssetRepositoryContainer';
2
+ export * from './CollectionRepositoryContainer';
3
+ export * from './PageRepositoryContainer';