@webiny/app-admin 6.5.0-beta.4 → 6.5.0-beta.6

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 (92) hide show
  1. package/base/Base/FieldRenderers/HorizontalTabsRenderer.d.ts +2 -2
  2. package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.d.ts +2 -2
  3. package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js +1 -1
  4. package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js.map +1 -1
  5. package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.d.ts +8 -4
  6. package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.d.ts +2 -2
  7. package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js +1 -1
  8. package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js.map +1 -1
  9. package/base/Base/FieldRenderers/ObjectRenderer/{TemplatePicker.d.ts → TemplatePicker/AddTemplateButton.d.ts} +1 -1
  10. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.js +24 -0
  11. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.js.map +1 -0
  12. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.d.ts +13 -0
  13. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.js +21 -0
  14. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.js.map +1 -0
  15. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.d.ts +3 -0
  16. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.js +35 -0
  17. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.js.map +1 -0
  18. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.d.ts +8 -0
  19. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.js +22 -0
  20. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.js.map +1 -0
  21. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.d.ts +10 -0
  22. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.js +46 -0
  23. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.js.map +1 -0
  24. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.d.ts +8 -0
  25. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.js +16 -0
  26. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.js.map +1 -0
  27. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.d.ts +10 -0
  28. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.js +22 -0
  29. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.js.map +1 -0
  30. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.d.ts +3 -0
  31. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.js +35 -0
  32. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.js.map +1 -0
  33. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/index.d.ts +1 -0
  34. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/index.js +1 -0
  35. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/types.d.ts +6 -0
  36. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/types.js +0 -0
  37. package/base/Base/FieldRenderers/VerticalTabsRenderer.d.ts +2 -2
  38. package/components/IconPicker/IconPickerComponent.d.ts +2 -2
  39. package/components/IconPicker/IconPickerComponent.js +1 -1
  40. package/components/IconPicker/IconPickerComponent.js.map +1 -1
  41. package/components/ListView/ListViewBulkActions.d.ts +2 -2
  42. package/components/ListView/ListViewContent.d.ts +2 -2
  43. package/components/ListView/ListViewFilters.d.ts +2 -2
  44. package/components/ListView/index.d.ts +6 -6
  45. package/components/RolesMultiAutocomplete/index.js +1 -1
  46. package/components/RolesMultiAutocomplete/index.js.map +1 -1
  47. package/components/Table/components/Table/TableInner.d.ts +2 -2
  48. package/components/TeamsMultiAutocomplete/index.js +1 -1
  49. package/components/TeamsMultiAutocomplete/index.js.map +1 -1
  50. package/domain/Identity.js +1 -1
  51. package/domain/Identity.js.map +1 -1
  52. package/features/debugger/Debugger.d.ts +2 -2
  53. package/features/debugger/DebuggerIndicator.d.ts +2 -2
  54. package/features/debugger/DebuggerView.d.ts +2 -2
  55. package/features/formModel/FieldBuilder.test.js +13 -0
  56. package/features/formModel/FieldBuilder.test.js.map +1 -1
  57. package/features/formModel/FormErrors.d.ts +2 -2
  58. package/features/formModel/FormModel.test.js +205 -2
  59. package/features/formModel/FormModel.test.js.map +1 -1
  60. package/features/formModel/FormView.d.ts +8 -4
  61. package/features/formModel/ObjectField.d.ts +2 -0
  62. package/features/formModel/ObjectField.js +19 -3
  63. package/features/formModel/ObjectField.js.map +1 -1
  64. package/features/formModel/PresenterErrors.d.ts +2 -2
  65. package/features/formModel/abstractions.d.ts +16 -0
  66. package/features/formModel/abstractions.js.map +1 -1
  67. package/features/formModel/demo/FormModelDemo.d.ts +2 -2
  68. package/features/formModel/fieldTypes/DateTimeFieldType.js +5 -4
  69. package/features/formModel/fieldTypes/DateTimeFieldType.js.map +1 -1
  70. package/features/formModel/fieldTypes/ObjectFieldType.d.ts +3 -1
  71. package/features/formModel/fieldTypes/ObjectFieldType.js +23 -1
  72. package/features/formModel/fieldTypes/ObjectFieldType.js.map +1 -1
  73. package/features/notifications/NotificationsRenderer.d.ts +2 -2
  74. package/hooks/useSnackbar.js.map +1 -1
  75. package/package.json +34 -34
  76. package/presentation/accessManagement/apiKeys/ApiKeysPresenter.js +1 -2
  77. package/presentation/accessManagement/apiKeys/ApiKeysPresenter.js.map +1 -1
  78. package/presentation/accessManagement/apiKeys/components/ApiKeysView.d.ts +2 -2
  79. package/presentation/accessManagement/roles/RolesPresenter.js +1 -2
  80. package/presentation/accessManagement/roles/RolesPresenter.js.map +1 -1
  81. package/presentation/accessManagement/roles/components/RolesView.d.ts +2 -2
  82. package/presentation/accessManagement/teams/TeamsPresenter.js +1 -2
  83. package/presentation/accessManagement/teams/TeamsPresenter.js.map +1 -1
  84. package/presentation/accessManagement/teams/components/TeamsView.d.ts +2 -2
  85. package/presentation/installation/components/SystemInstaller/SystemInstaller.d.ts +2 -2
  86. package/presentation/listPresenter/QueryMatcher.js +3 -3
  87. package/presentation/listPresenter/QueryMatcher.js.map +1 -1
  88. package/presentation/trashBin/components/BulkActions/DeleteItems.d.ts +2 -2
  89. package/presentation/trashBin/components/BulkActions/RestoreItems.d.ts +2 -2
  90. package/presentation/trashBin/components/TrashBinOverlay.d.ts +2 -2
  91. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js +0 -68
  92. package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
2
  import type { TabsNodeRendererProps } from "../../../features/formModel/FormView.js";
3
- export declare const HorizontalTabsRenderer: (({ node }: TabsNodeRendererProps) => React.JSX.Element) & {
4
- displayName: string;
3
+ export declare const HorizontalTabsRenderer: (({ node }: TabsNodeRendererProps) => React.JSX.Element) & React.NamedExoticComponent<TabsNodeRendererProps> & {
4
+ readonly type: ({ node }: TabsNodeRendererProps) => React.JSX.Element;
5
5
  };
@@ -5,7 +5,7 @@ interface MultiValueDynamicZoneProps {
5
5
  addItemLabel: string;
6
6
  showContainer?: boolean;
7
7
  }
8
- export declare const MultiValueDynamicZone: (({ field, addItemLabel, showContainer }: MultiValueDynamicZoneProps) => React.JSX.Element) & {
9
- displayName: string;
8
+ export declare const MultiValueDynamicZone: (({ field, addItemLabel, showContainer }: MultiValueDynamicZoneProps) => React.JSX.Element) & React.NamedExoticComponent<MultiValueDynamicZoneProps> & {
9
+ readonly type: ({ field, addItemLabel, showContainer }: MultiValueDynamicZoneProps) => React.JSX.Element;
10
10
  };
11
11
  export {};
@@ -14,7 +14,7 @@ import { TEMPLATE_DISCRIMINATOR } from "../../../../../features/formModel/Object
14
14
  import { ClipboardFeature } from "../../../../../features/clipboard/feature.js";
15
15
  import { useConfirmationDialog } from "../../../../../hooks/useConfirmationDialog.js";
16
16
  import { NestedLayout } from "../ObjectFieldComponents.js";
17
- import { AddTemplateButton } from "../TemplatePicker.js";
17
+ import { AddTemplateButton } from "../TemplatePicker/index.js";
18
18
  import { MultiValueDynamicZonePresenter } from "./abstractions.js";
19
19
  const MultiValueDynamicZone = observer(({ field, addItemLabel, showContainer = true })=>{
20
20
  const toast = useToast();
@@ -1 +1 @@
1
- {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Accordion, Button, Tooltip, useToast } from \"@webiny/admin-ui\";\nimport { useFeature, useContainer } from \"@webiny/app\";\nimport { hasSubtreeFocusRequest } from \"~/features/formModel/index.js\";\nimport { ReactComponent as CopyIcon } from \"@webiny/icons/content_copy.svg\";\nimport { ReactComponent as PasteIcon } from \"@webiny/icons/content_paste.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete_outline.svg\";\nimport { ReactComponent as CloneIcon } from \"@webiny/icons/library_add.svg\";\nimport { ReactComponent as ArrowUpIcon } from \"@webiny/icons/expand_less.svg\";\nimport { ReactComponent as ArrowDownIcon } from \"@webiny/icons/expand_more.svg\";\nimport { ReactComponent as HorizontalRuleIcon } from \"@webiny/icons/horizontal_rule.svg\";\nimport type { IObjectFieldItemVM, IObjectFieldVM } from \"~/features/formModel/index.js\";\nimport { TEMPLATE_DISCRIMINATOR } from \"~/features/formModel/ObjectField.js\";\nimport { ClipboardFeature } from \"~/features/clipboard/feature.js\";\nimport { useConfirmationDialog } from \"~/hooks/useConfirmationDialog.js\";\nimport { NestedLayout } from \"../ObjectFieldComponents.js\";\nimport { AddTemplateButton } from \"../TemplatePicker.js\";\nimport {\n MultiValueDynamicZonePresenter,\n type IMultiValueDynamicZonePresenter\n} from \"./abstractions.js\";\nimport type { ISortableItemProps } from \"~/presentation/sortable/index.js\";\nimport { Separator } from \"@webiny/admin-ui\";\n\ninterface MultiValueDynamicZoneProps {\n field: IObjectFieldVM;\n addItemLabel: string;\n showContainer?: boolean;\n}\n\nexport const MultiValueDynamicZone = observer(\n ({ field, addItemLabel, showContainer = true }: MultiValueDynamicZoneProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n const container = useContainer();\n\n const presenter = useMemo<IMultiValueDynamicZonePresenter>(() => {\n const p = container.resolve(MultiValueDynamicZonePresenter);\n p.init({ type: `dz:${field.name}`, onReorder: (from, to) => field.moveItem(from, to) });\n return p;\n }, []);\n\n useEffect(() => {\n return () => presenter.dispose();\n }, [presenter]);\n\n // Force the DZ list container open when a focus request lands anywhere\n // in its subtree, so \"jump to field\" can cascade through collapsed levels.\n const focusInside = hasSubtreeFocusRequest(field.items.flatMap(i => i.fields));\n const [containerOpen, setContainerOpen] = useState(true);\n useEffect(() => {\n if (focusInside) {\n setContainerOpen(true);\n }\n }, [focusInside]);\n\n const itemCount = field.items.length;\n\n const clipboardItem = clipboard.item;\n const canPaste =\n clipboardItem !== null &&\n clipboardItem.type === \"wby.dz\" &&\n typeof clipboardItem.data[TEMPLATE_DISCRIMINATOR] === \"string\" &&\n field.availableTemplates.some(t => t.id === clipboardItem.data[TEMPLATE_DISCRIMINATOR]);\n\n const content = (\n <div className={\"flex flex-col gap-lg\"}>\n {itemCount > 0 ? (\n <Accordion\n background={\"base\"}\n variant={\"container\"}\n className={\"gap-md flex flex-col\"}\n >\n {field.items.map((item, index) => (\n <TemplatedListItem\n key={item.key}\n item={item}\n index={index}\n total={itemCount}\n templates={field.availableTemplates}\n disabled={field.disabled}\n sortable={presenter.getItemProps(index)}\n />\n ))}\n </Accordion>\n ) : null}\n {!field.disabled && (\n <div className={\"flex gap-sm items-center\"}>\n <AddTemplateButton\n label={addItemLabel}\n templates={field.availableTemplates}\n onSelect={template => field.addItem(template.id)}\n />\n {canPaste && (\n <Button\n size={\"sm\"}\n variant={\"tertiary\"}\n text={\"Paste\"}\n icon={<PasteIcon />}\n onClick={() => {\n const pasted = clipboard.paste();\n if (pasted) {\n field.addItem(pasted.data);\n toast.showSuccessToast({\n title: \"Pasted from clipboard.\"\n });\n }\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n\n if (!showContainer) {\n return (\n <>\n <Separator labelPosition={\"start\"} variant={\"accent\"}>\n <span className={\"text-accent-primary text-lg font-semibold\"}>\n {field.label ?? \"\"} ({itemCount})\n </span>\n </Separator>\n <div className={\"mt-md\"}>{content}</div>\n </>\n );\n }\n\n const label = `${field.label || \"\"}${itemCount ? ` (${itemCount})` : \"\"}`;\n\n return (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n icon={\n <Accordion.Item.Icon\n color={\"accent\"}\n label={\"Dynamic Zone\"}\n icon={<HorizontalRuleIcon />}\n />\n }\n title={label}\n open={containerOpen}\n onOpenChange={setContainerOpen}\n >\n {content}\n </Accordion.Item>\n </Accordion>\n );\n }\n);\n\ninterface TemplatedListItemProps {\n item: IObjectFieldItemVM;\n index: number;\n total: number;\n templates: { id: string; label: string }[];\n disabled: boolean;\n sortable: ISortableItemProps;\n}\n\nconst TemplatedListItem = observer(\n ({ item, index, total, templates, disabled, sortable }: TemplatedListItemProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n const { showConfirmation } = useConfirmationDialog({\n title: \"Delete item\",\n message: \"Are you sure you want to delete this item? This action is not reversible.\",\n acceptLabel: \"Yes, I'm sure!\",\n cancelLabel: \"No, leave it.\"\n });\n\n const template = templates.find(t => t.id === item.templateId);\n const title = template?.label || `Item #${index + 1}`;\n\n // Force this item open when a focus request lands anywhere in its subtree.\n const focusInside = hasSubtreeFocusRequest(item.fields);\n const [open, setOpen] = useState(false);\n useEffect(() => {\n if (focusInside) {\n setOpen(true);\n }\n }, [focusInside]);\n\n const onDelete = () => {\n showConfirmation(() => {\n item.remove();\n });\n };\n\n const actions = (\n <>\n <Accordion.Item.Action\n icon={<Tooltip trigger={<ArrowUpIcon />} content={\"Move up\"} />}\n onClick={item.moveUp}\n disabled={index === 0}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<ArrowDownIcon />} content={\"Move down\"} />}\n onClick={item.moveDown}\n disabled={index === total - 1}\n />\n <Accordion.Item.Action.Separator />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<CopyIcon />} content={\"Copy to clipboard\"} />}\n onClick={() => {\n clipboard.copy({ type: \"wby.dz\", data: item.getClonedData() });\n toast.showSuccessToast({ title: \"Copied to clipboard.\" });\n }}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<CloneIcon />} content={\"Duplicate\"} />}\n onClick={item.duplicate}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<DeleteIcon />} content={\"Delete\"} />}\n onClick={onDelete}\n />\n </>\n );\n\n return (\n <div\n ref={sortable.ref}\n data-sortable-item=\"\"\n className={\"relative\"}\n style={{ opacity: sortable.isDragging ? 0.4 : 1 }}\n >\n {sortable.closestEdge === \"top\" && (\n <DropIndicator position={\"top\"} isFirst={index === 0} />\n )}\n <Accordion.Item\n title={title}\n actions={disabled ? null : actions}\n open={open}\n onOpenChange={setOpen}\n draggable={!disabled}\n dragHandleRef={sortable.handleRef}\n >\n <NestedLayout layout={item.layout} />\n </Accordion.Item>\n {sortable.closestEdge === \"bottom\" && (\n <DropIndicator position={\"bottom\"} isLast={index === total - 1} />\n )}\n </div>\n );\n }\n);\n\nconst DropIndicator = ({\n position,\n isFirst = false,\n isLast = false\n}: {\n position: \"top\" | \"bottom\";\n isFirst?: boolean;\n isLast?: boolean;\n}) => {\n let offset = \"calc(var(--spacing-md) / -2)\";\n if (position === \"top\" && isFirst) {\n offset = \"0px\";\n }\n if (position === \"bottom\" && isLast) {\n offset = \"0px\";\n }\n\n return (\n <div\n className={\"absolute left-0 right-0 z-10\"}\n style={{\n [position]: offset,\n transform: position === \"top\" ? \"translateY(-50%)\" : \"translateY(50%)\"\n }}\n >\n <div className={\"w-full h-[2px] bg-primary rounded-full\"} />\n </div>\n );\n};\n"],"names":["MultiValueDynamicZone","observer","field","addItemLabel","showContainer","toast","useToast","clipboard","useFeature","ClipboardFeature","container","useContainer","presenter","useMemo","p","MultiValueDynamicZonePresenter","from","to","useEffect","focusInside","hasSubtreeFocusRequest","i","containerOpen","setContainerOpen","useState","itemCount","clipboardItem","canPaste","TEMPLATE_DISCRIMINATOR","t","content","Accordion","item","index","TemplatedListItem","AddTemplateButton","template","Button","PasteIcon","pasted","Separator","label","HorizontalRuleIcon","total","templates","disabled","sortable","showConfirmation","useConfirmationDialog","title","open","setOpen","onDelete","actions","Tooltip","ArrowUpIcon","ArrowDownIcon","CopyIcon","CloneIcon","DeleteIcon","DropIndicator","NestedLayout","position","isFirst","isLast","offset"],"mappings":"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"}
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Accordion, Button, Tooltip, useToast } from \"@webiny/admin-ui\";\nimport { useFeature, useContainer } from \"@webiny/app\";\nimport { hasSubtreeFocusRequest } from \"~/features/formModel/index.js\";\nimport { ReactComponent as CopyIcon } from \"@webiny/icons/content_copy.svg\";\nimport { ReactComponent as PasteIcon } from \"@webiny/icons/content_paste.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete_outline.svg\";\nimport { ReactComponent as CloneIcon } from \"@webiny/icons/library_add.svg\";\nimport { ReactComponent as ArrowUpIcon } from \"@webiny/icons/expand_less.svg\";\nimport { ReactComponent as ArrowDownIcon } from \"@webiny/icons/expand_more.svg\";\nimport { ReactComponent as HorizontalRuleIcon } from \"@webiny/icons/horizontal_rule.svg\";\nimport type { IObjectFieldItemVM, IObjectFieldVM } from \"~/features/formModel/index.js\";\nimport { TEMPLATE_DISCRIMINATOR } from \"~/features/formModel/ObjectField.js\";\nimport { ClipboardFeature } from \"~/features/clipboard/feature.js\";\nimport { useConfirmationDialog } from \"~/hooks/useConfirmationDialog.js\";\nimport { NestedLayout } from \"../ObjectFieldComponents.js\";\nimport { AddTemplateButton } from \"../TemplatePicker/index.js\";\nimport {\n MultiValueDynamicZonePresenter,\n type IMultiValueDynamicZonePresenter\n} from \"./abstractions.js\";\nimport type { ISortableItemProps } from \"~/presentation/sortable/index.js\";\nimport { Separator } from \"@webiny/admin-ui\";\n\ninterface MultiValueDynamicZoneProps {\n field: IObjectFieldVM;\n addItemLabel: string;\n showContainer?: boolean;\n}\n\nexport const MultiValueDynamicZone = observer(\n ({ field, addItemLabel, showContainer = true }: MultiValueDynamicZoneProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n const container = useContainer();\n\n const presenter = useMemo<IMultiValueDynamicZonePresenter>(() => {\n const p = container.resolve(MultiValueDynamicZonePresenter);\n p.init({ type: `dz:${field.name}`, onReorder: (from, to) => field.moveItem(from, to) });\n return p;\n }, []);\n\n useEffect(() => {\n return () => presenter.dispose();\n }, [presenter]);\n\n // Force the DZ list container open when a focus request lands anywhere\n // in its subtree, so \"jump to field\" can cascade through collapsed levels.\n const focusInside = hasSubtreeFocusRequest(field.items.flatMap(i => i.fields));\n const [containerOpen, setContainerOpen] = useState(true);\n useEffect(() => {\n if (focusInside) {\n setContainerOpen(true);\n }\n }, [focusInside]);\n\n const itemCount = field.items.length;\n\n const clipboardItem = clipboard.item;\n const canPaste =\n clipboardItem !== null &&\n clipboardItem.type === \"wby.dz\" &&\n typeof clipboardItem.data[TEMPLATE_DISCRIMINATOR] === \"string\" &&\n field.availableTemplates.some(t => t.id === clipboardItem.data[TEMPLATE_DISCRIMINATOR]);\n\n const content = (\n <div className={\"flex flex-col gap-lg\"}>\n {itemCount > 0 ? (\n <Accordion\n background={\"base\"}\n variant={\"container\"}\n className={\"gap-md flex flex-col\"}\n >\n {field.items.map((item, index) => (\n <TemplatedListItem\n key={item.key}\n item={item}\n index={index}\n total={itemCount}\n templates={field.availableTemplates}\n disabled={field.disabled}\n sortable={presenter.getItemProps(index)}\n />\n ))}\n </Accordion>\n ) : null}\n {!field.disabled && (\n <div className={\"flex gap-sm items-center\"}>\n <AddTemplateButton\n label={addItemLabel}\n templates={field.availableTemplates}\n onSelect={template => field.addItem(template.id)}\n />\n {canPaste && (\n <Button\n size={\"sm\"}\n variant={\"tertiary\"}\n text={\"Paste\"}\n icon={<PasteIcon />}\n onClick={() => {\n const pasted = clipboard.paste();\n if (pasted) {\n field.addItem(pasted.data);\n toast.showSuccessToast({\n title: \"Pasted from clipboard.\"\n });\n }\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n\n if (!showContainer) {\n return (\n <>\n <Separator labelPosition={\"start\"} variant={\"accent\"}>\n <span className={\"text-accent-primary text-lg font-semibold\"}>\n {field.label ?? \"\"} ({itemCount})\n </span>\n </Separator>\n <div className={\"mt-md\"}>{content}</div>\n </>\n );\n }\n\n const label = `${field.label || \"\"}${itemCount ? ` (${itemCount})` : \"\"}`;\n\n return (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n icon={\n <Accordion.Item.Icon\n color={\"accent\"}\n label={\"Dynamic Zone\"}\n icon={<HorizontalRuleIcon />}\n />\n }\n title={label}\n open={containerOpen}\n onOpenChange={setContainerOpen}\n >\n {content}\n </Accordion.Item>\n </Accordion>\n );\n }\n);\n\ninterface TemplatedListItemProps {\n item: IObjectFieldItemVM;\n index: number;\n total: number;\n templates: { id: string; label: string }[];\n disabled: boolean;\n sortable: ISortableItemProps;\n}\n\nconst TemplatedListItem = observer(\n ({ item, index, total, templates, disabled, sortable }: TemplatedListItemProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n const { showConfirmation } = useConfirmationDialog({\n title: \"Delete item\",\n message: \"Are you sure you want to delete this item? This action is not reversible.\",\n acceptLabel: \"Yes, I'm sure!\",\n cancelLabel: \"No, leave it.\"\n });\n\n const template = templates.find(t => t.id === item.templateId);\n const title = template?.label || `Item #${index + 1}`;\n\n // Force this item open when a focus request lands anywhere in its subtree.\n const focusInside = hasSubtreeFocusRequest(item.fields);\n const [open, setOpen] = useState(false);\n useEffect(() => {\n if (focusInside) {\n setOpen(true);\n }\n }, [focusInside]);\n\n const onDelete = () => {\n showConfirmation(() => {\n item.remove();\n });\n };\n\n const actions = (\n <>\n <Accordion.Item.Action\n icon={<Tooltip trigger={<ArrowUpIcon />} content={\"Move up\"} />}\n onClick={item.moveUp}\n disabled={index === 0}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<ArrowDownIcon />} content={\"Move down\"} />}\n onClick={item.moveDown}\n disabled={index === total - 1}\n />\n <Accordion.Item.Action.Separator />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<CopyIcon />} content={\"Copy to clipboard\"} />}\n onClick={() => {\n clipboard.copy({ type: \"wby.dz\", data: item.getClonedData() });\n toast.showSuccessToast({ title: \"Copied to clipboard.\" });\n }}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<CloneIcon />} content={\"Duplicate\"} />}\n onClick={item.duplicate}\n />\n <Accordion.Item.Action\n icon={<Tooltip trigger={<DeleteIcon />} content={\"Delete\"} />}\n onClick={onDelete}\n />\n </>\n );\n\n return (\n <div\n ref={sortable.ref}\n data-sortable-item=\"\"\n className={\"relative\"}\n style={{ opacity: sortable.isDragging ? 0.4 : 1 }}\n >\n {sortable.closestEdge === \"top\" && (\n <DropIndicator position={\"top\"} isFirst={index === 0} />\n )}\n <Accordion.Item\n title={title}\n actions={disabled ? null : actions}\n open={open}\n onOpenChange={setOpen}\n draggable={!disabled}\n dragHandleRef={sortable.handleRef}\n >\n <NestedLayout layout={item.layout} />\n </Accordion.Item>\n {sortable.closestEdge === \"bottom\" && (\n <DropIndicator position={\"bottom\"} isLast={index === total - 1} />\n )}\n </div>\n );\n }\n);\n\nconst DropIndicator = ({\n position,\n isFirst = false,\n isLast = false\n}: {\n position: \"top\" | \"bottom\";\n isFirst?: boolean;\n isLast?: boolean;\n}) => {\n let offset = \"calc(var(--spacing-md) / -2)\";\n if (position === \"top\" && isFirst) {\n offset = \"0px\";\n }\n if (position === \"bottom\" && isLast) {\n offset = \"0px\";\n }\n\n return (\n <div\n className={\"absolute left-0 right-0 z-10\"}\n style={{\n [position]: offset,\n transform: position === \"top\" ? \"translateY(-50%)\" : \"translateY(50%)\"\n }}\n >\n <div className={\"w-full h-[2px] bg-primary rounded-full\"} />\n </div>\n );\n};\n"],"names":["MultiValueDynamicZone","observer","field","addItemLabel","showContainer","toast","useToast","clipboard","useFeature","ClipboardFeature","container","useContainer","presenter","useMemo","p","MultiValueDynamicZonePresenter","from","to","useEffect","focusInside","hasSubtreeFocusRequest","i","containerOpen","setContainerOpen","useState","itemCount","clipboardItem","canPaste","TEMPLATE_DISCRIMINATOR","t","content","Accordion","item","index","TemplatedListItem","AddTemplateButton","template","Button","PasteIcon","pasted","Separator","label","HorizontalRuleIcon","total","templates","disabled","sortable","showConfirmation","useConfirmationDialog","title","open","setOpen","onDelete","actions","Tooltip","ArrowUpIcon","ArrowDownIcon","CopyIcon","CloneIcon","DeleteIcon","DropIndicator","NestedLayout","position","isFirst","isLast","offset"],"mappings":"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"}
@@ -3,8 +3,12 @@ import type { IObjectFieldItemVM, LayoutNodeVM } from "../../../../features/form
3
3
  import type { ISortableItemProps } from "../../../../presentation/sortable/index.js";
4
4
  export declare const NestedLayout: (({ layout }: {
5
5
  layout: LayoutNodeVM[];
6
- }) => React.JSX.Element) & {
7
- displayName: string;
6
+ }) => React.JSX.Element) & React.NamedExoticComponent<{
7
+ layout: LayoutNodeVM[];
8
+ }> & {
9
+ readonly type: ({ layout }: {
10
+ layout: LayoutNodeVM[];
11
+ }) => React.JSX.Element;
8
12
  };
9
13
  export interface ListItemRendererProps {
10
14
  item: IObjectFieldItemVM;
@@ -16,8 +20,8 @@ export interface ListItemRendererProps {
16
20
  disabled: boolean;
17
21
  sortable?: ISortableItemProps;
18
22
  }
19
- export declare const ListItemRenderer: (({ item, index, total, label, itemTitle, itemDescription, disabled, sortable }: ListItemRendererProps) => React.JSX.Element) & {
20
- displayName: string;
23
+ export declare const ListItemRenderer: (({ item, index, total, label, itemTitle, itemDescription, disabled, sortable }: ListItemRendererProps) => React.JSX.Element) & React.NamedExoticComponent<ListItemRendererProps> & {
24
+ readonly type: ({ item, index, total, label, itemTitle, itemDescription, disabled, sortable }: ListItemRendererProps) => React.JSX.Element;
21
25
  };
22
26
  export interface AddItemButtonProps {
23
27
  label?: string;
@@ -5,7 +5,7 @@ interface SingleValueDynamicZoneProps {
5
5
  addItemLabel: string;
6
6
  showContainer?: boolean;
7
7
  }
8
- export declare const SingleValueDynamicZone: (({ field, addItemLabel, showContainer }: SingleValueDynamicZoneProps) => React.JSX.Element) & {
9
- displayName: string;
8
+ export declare const SingleValueDynamicZone: (({ field, addItemLabel, showContainer }: SingleValueDynamicZoneProps) => React.JSX.Element) & React.NamedExoticComponent<SingleValueDynamicZoneProps> & {
9
+ readonly type: ({ field, addItemLabel, showContainer }: SingleValueDynamicZoneProps) => React.JSX.Element;
10
10
  };
11
11
  export {};
@@ -11,7 +11,7 @@ import { TEMPLATE_DISCRIMINATOR } from "../../../../features/formModel/ObjectFie
11
11
  import { ClipboardFeature } from "../../../../features/clipboard/feature.js";
12
12
  import { useConfirmationDialog } from "../../../../hooks/useConfirmationDialog.js";
13
13
  import { NestedLayout } from "./ObjectFieldComponents.js";
14
- import { AddTemplateButton } from "./TemplatePicker.js";
14
+ import { AddTemplateButton } from "./TemplatePicker/index.js";
15
15
  const SingleValueDynamicZone = observer(({ field, addItemLabel, showContainer = true })=>{
16
16
  const toast = useToast();
17
17
  const { clipboard } = useFeature(ClipboardFeature);
@@ -1 +1 @@
1
- {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js","sources":["../../../../../src/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Accordion, Button, Tooltip, useToast } from \"@webiny/admin-ui\";\nimport { useFeature } from \"@webiny/app\";\nimport { hasSubtreeFocusRequest } from \"~/features/formModel/index.js\";\nimport { ReactComponent as CopyIcon } from \"@webiny/icons/content_copy.svg\";\nimport { ReactComponent as PasteIcon } from \"@webiny/icons/content_paste.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete.svg\";\nimport { ReactComponent as HorizontalRuleIcon } from \"@webiny/icons/horizontal_rule.svg\";\nimport type { IObjectFieldVM } from \"~/features/formModel/index.js\";\nimport { TEMPLATE_DISCRIMINATOR } from \"~/features/formModel/ObjectField.js\";\nimport { ClipboardFeature } from \"~/features/clipboard/feature.js\";\nimport { useConfirmationDialog } from \"~/hooks/useConfirmationDialog.js\";\nimport { NestedLayout } from \"./ObjectFieldComponents.js\";\nimport { AddTemplateButton } from \"./TemplatePicker.js\";\nimport { Separator } from \"@webiny/admin-ui\";\n\ninterface SingleValueDynamicZoneProps {\n field: IObjectFieldVM;\n addItemLabel: string;\n showContainer?: boolean;\n}\n\nexport const SingleValueDynamicZone = observer(\n ({ field, addItemLabel, showContainer = true }: SingleValueDynamicZoneProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n\n // Force both the DZ container and the active-template accordion open\n // when a focus request lands anywhere in the subtree, so \"jump to\n // field\" can cascade through collapsed levels.\n const focusInside = hasSubtreeFocusRequest(field.fields);\n const [containerOpen, setContainerOpen] = useState(true);\n const [templateOpen, setTemplateOpen] = useState(false);\n useEffect(() => {\n if (focusInside) {\n setContainerOpen(true);\n setTemplateOpen(true);\n }\n }, [focusInside]);\n\n const activeTemplate =\n field.activeTemplateId !== null\n ? field.availableTemplates.find(t => t.id === field.activeTemplateId)\n : undefined;\n\n const { showConfirmation } = useConfirmationDialog({\n title: \"Remove template\",\n message: \"Are you sure you want to remove this item? This action is not reversible.\",\n acceptLabel: \"Yes, I'm sure!\",\n cancelLabel: \"No, leave it.\"\n });\n\n const onClear = () => {\n showConfirmation(() => {\n field.onChange(null);\n });\n };\n\n const clipboardItem = clipboard.item;\n const canPaste =\n clipboardItem !== null &&\n clipboardItem.type === \"wby.dz\" &&\n typeof clipboardItem.data[TEMPLATE_DISCRIMINATOR] === \"string\" &&\n field.availableTemplates.some(t => t.id === clipboardItem.data[TEMPLATE_DISCRIMINATOR]);\n\n const content = (\n <>\n {activeTemplate ? (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n title={activeTemplate.label}\n open={templateOpen}\n onOpenChange={setTemplateOpen}\n actions={\n field.disabled ? null : (\n <>\n <Accordion.Item.Action\n icon={\n <Tooltip\n trigger={<CopyIcon />}\n content={\"Copy to clipboard\"}\n />\n }\n onClick={() => {\n clipboard.copy({\n type: \"wby.dz\",\n data: field.getClonedData()\n });\n toast.showSuccessToast({\n title: \"Copied to clipboard.\"\n });\n }}\n />\n <Accordion.Item.Action\n icon={\n <Tooltip\n trigger={<DeleteIcon />}\n content={\"Delete\"}\n />\n }\n onClick={onClear}\n />\n </>\n )\n }\n >\n <NestedLayout layout={field.layout} />\n </Accordion.Item>\n </Accordion>\n ) : null}\n {!activeTemplate && !field.disabled && (\n <div className={\"flex gap-sm items-center\"}>\n <AddTemplateButton\n label={addItemLabel}\n templates={field.availableTemplates}\n onSelect={template => field.setTemplate(template.id)}\n />\n {canPaste && (\n <Button\n size={\"sm\"}\n variant={\"tertiary\"}\n text={\"Paste\"}\n icon={<PasteIcon />}\n onClick={() => {\n const pasted = clipboard.paste();\n if (pasted) {\n field.onChange(pasted.data);\n toast.showSuccessToast({\n title: \"Pasted from clipboard.\"\n });\n }\n }}\n />\n )}\n </div>\n )}\n </>\n );\n\n if (!showContainer) {\n return (\n <>\n <Separator labelPosition={\"start\"} variant={\"accent\"}>\n <span className={\"text-accent-primary text-lg font-semibold\"}>\n {field.label ?? \"\"}\n </span>\n </Separator>\n <div className={\"mt-md\"}>{content}</div>\n </>\n );\n }\n\n return (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n icon={\n <Accordion.Item.Icon\n color={\"accent\"}\n label={\"Dynamic Zone\"}\n icon={<HorizontalRuleIcon />}\n />\n }\n title={field.label}\n open={containerOpen}\n onOpenChange={setContainerOpen}\n >\n {content}\n </Accordion.Item>\n </Accordion>\n );\n }\n);\n"],"names":["SingleValueDynamicZone","observer","field","addItemLabel","showContainer","toast","useToast","clipboard","useFeature","ClipboardFeature","focusInside","hasSubtreeFocusRequest","containerOpen","setContainerOpen","useState","templateOpen","setTemplateOpen","useEffect","activeTemplate","t","undefined","showConfirmation","useConfirmationDialog","onClear","clipboardItem","canPaste","TEMPLATE_DISCRIMINATOR","content","Accordion","Tooltip","CopyIcon","DeleteIcon","NestedLayout","AddTemplateButton","template","Button","PasteIcon","pasted","Separator","HorizontalRuleIcon"],"mappings":"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"}
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js","sources":["../../../../../src/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Accordion, Button, Tooltip, useToast } from \"@webiny/admin-ui\";\nimport { useFeature } from \"@webiny/app\";\nimport { hasSubtreeFocusRequest } from \"~/features/formModel/index.js\";\nimport { ReactComponent as CopyIcon } from \"@webiny/icons/content_copy.svg\";\nimport { ReactComponent as PasteIcon } from \"@webiny/icons/content_paste.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete.svg\";\nimport { ReactComponent as HorizontalRuleIcon } from \"@webiny/icons/horizontal_rule.svg\";\nimport type { IObjectFieldVM } from \"~/features/formModel/index.js\";\nimport { TEMPLATE_DISCRIMINATOR } from \"~/features/formModel/ObjectField.js\";\nimport { ClipboardFeature } from \"~/features/clipboard/feature.js\";\nimport { useConfirmationDialog } from \"~/hooks/useConfirmationDialog.js\";\nimport { NestedLayout } from \"./ObjectFieldComponents.js\";\nimport { AddTemplateButton } from \"./TemplatePicker/index.js\";\nimport { Separator } from \"@webiny/admin-ui\";\n\ninterface SingleValueDynamicZoneProps {\n field: IObjectFieldVM;\n addItemLabel: string;\n showContainer?: boolean;\n}\n\nexport const SingleValueDynamicZone = observer(\n ({ field, addItemLabel, showContainer = true }: SingleValueDynamicZoneProps) => {\n const toast = useToast();\n const { clipboard } = useFeature(ClipboardFeature);\n\n // Force both the DZ container and the active-template accordion open\n // when a focus request lands anywhere in the subtree, so \"jump to\n // field\" can cascade through collapsed levels.\n const focusInside = hasSubtreeFocusRequest(field.fields);\n const [containerOpen, setContainerOpen] = useState(true);\n const [templateOpen, setTemplateOpen] = useState(false);\n useEffect(() => {\n if (focusInside) {\n setContainerOpen(true);\n setTemplateOpen(true);\n }\n }, [focusInside]);\n\n const activeTemplate =\n field.activeTemplateId !== null\n ? field.availableTemplates.find(t => t.id === field.activeTemplateId)\n : undefined;\n\n const { showConfirmation } = useConfirmationDialog({\n title: \"Remove template\",\n message: \"Are you sure you want to remove this item? This action is not reversible.\",\n acceptLabel: \"Yes, I'm sure!\",\n cancelLabel: \"No, leave it.\"\n });\n\n const onClear = () => {\n showConfirmation(() => {\n field.onChange(null);\n });\n };\n\n const clipboardItem = clipboard.item;\n const canPaste =\n clipboardItem !== null &&\n clipboardItem.type === \"wby.dz\" &&\n typeof clipboardItem.data[TEMPLATE_DISCRIMINATOR] === \"string\" &&\n field.availableTemplates.some(t => t.id === clipboardItem.data[TEMPLATE_DISCRIMINATOR]);\n\n const content = (\n <>\n {activeTemplate ? (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n title={activeTemplate.label}\n open={templateOpen}\n onOpenChange={setTemplateOpen}\n actions={\n field.disabled ? null : (\n <>\n <Accordion.Item.Action\n icon={\n <Tooltip\n trigger={<CopyIcon />}\n content={\"Copy to clipboard\"}\n />\n }\n onClick={() => {\n clipboard.copy({\n type: \"wby.dz\",\n data: field.getClonedData()\n });\n toast.showSuccessToast({\n title: \"Copied to clipboard.\"\n });\n }}\n />\n <Accordion.Item.Action\n icon={\n <Tooltip\n trigger={<DeleteIcon />}\n content={\"Delete\"}\n />\n }\n onClick={onClear}\n />\n </>\n )\n }\n >\n <NestedLayout layout={field.layout} />\n </Accordion.Item>\n </Accordion>\n ) : null}\n {!activeTemplate && !field.disabled && (\n <div className={\"flex gap-sm items-center\"}>\n <AddTemplateButton\n label={addItemLabel}\n templates={field.availableTemplates}\n onSelect={template => field.setTemplate(template.id)}\n />\n {canPaste && (\n <Button\n size={\"sm\"}\n variant={\"tertiary\"}\n text={\"Paste\"}\n icon={<PasteIcon />}\n onClick={() => {\n const pasted = clipboard.paste();\n if (pasted) {\n field.onChange(pasted.data);\n toast.showSuccessToast({\n title: \"Pasted from clipboard.\"\n });\n }\n }}\n />\n )}\n </div>\n )}\n </>\n );\n\n if (!showContainer) {\n return (\n <>\n <Separator labelPosition={\"start\"} variant={\"accent\"}>\n <span className={\"text-accent-primary text-lg font-semibold\"}>\n {field.label ?? \"\"}\n </span>\n </Separator>\n <div className={\"mt-md\"}>{content}</div>\n </>\n );\n }\n\n return (\n <Accordion background={\"base\"} variant={\"container\"}>\n <Accordion.Item\n icon={\n <Accordion.Item.Icon\n color={\"accent\"}\n label={\"Dynamic Zone\"}\n icon={<HorizontalRuleIcon />}\n />\n }\n title={field.label}\n open={containerOpen}\n onOpenChange={setContainerOpen}\n >\n {content}\n </Accordion.Item>\n </Accordion>\n );\n }\n);\n"],"names":["SingleValueDynamicZone","observer","field","addItemLabel","showContainer","toast","useToast","clipboard","useFeature","ClipboardFeature","focusInside","hasSubtreeFocusRequest","containerOpen","setContainerOpen","useState","templateOpen","setTemplateOpen","useEffect","activeTemplate","t","undefined","showConfirmation","useConfirmationDialog","onClear","clipboardItem","canPaste","TEMPLATE_DISCRIMINATOR","content","Accordion","Tooltip","CopyIcon","DeleteIcon","NestedLayout","AddTemplateButton","template","Button","PasteIcon","pasted","Separator","HorizontalRuleIcon"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { ITemplateVM } from "../../../../features/formModel/index.js";
2
+ import type { ITemplateVM } from "../../../../../features/formModel/index.js";
3
3
  export interface AddTemplateButtonProps {
4
4
  templates: ITemplateVM[];
5
5
  onSelect: (template: ITemplateVM) => void;
@@ -0,0 +1,24 @@
1
+ import react from "react";
2
+ import { Button, Dialog } from "@webiny/admin-ui";
3
+ import { ReactComponent } from "@webiny/icons/add.svg";
4
+ import { TemplateGallery } from "./TemplateGallery.js";
5
+ const AddTemplateButton = ({ templates, onSelect, label, size = "sm", variant = "tertiary" })=>/*#__PURE__*/ react.createElement("div", {
6
+ className: "flex justify-between items-center"
7
+ }, /*#__PURE__*/ react.createElement(Dialog, {
8
+ size: "lg",
9
+ className: "w-[800px]",
10
+ trigger: /*#__PURE__*/ react.createElement(Button, {
11
+ size: size,
12
+ variant: variant,
13
+ text: label,
14
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null)
15
+ }),
16
+ title: "Insert a template",
17
+ info: /*#__PURE__*/ react.createElement(react.Fragment, null)
18
+ }, /*#__PURE__*/ react.createElement(TemplateGallery, {
19
+ templates: templates,
20
+ onSelect: onSelect
21
+ })));
22
+ export { AddTemplateButton };
23
+
24
+ //# sourceMappingURL=AddTemplateButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.tsx"],"sourcesContent":["import React from \"react\";\nimport { Button } from \"@webiny/admin-ui\";\nimport { Dialog } from \"@webiny/admin-ui\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport type { ITemplateVM } from \"~/features/formModel/index.js\";\nimport { TemplateGallery } from \"./TemplateGallery.js\";\n\nexport interface AddTemplateButtonProps {\n templates: ITemplateVM[];\n onSelect: (template: ITemplateVM) => void;\n label?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n variant?: \"primary\" | \"secondary\" | \"tertiary\";\n}\n\nexport const AddTemplateButton = ({\n templates,\n onSelect,\n label,\n size = \"sm\",\n variant = \"tertiary\"\n}: AddTemplateButtonProps) => {\n return (\n <div className={\"flex justify-between items-center\"}>\n <Dialog\n size={\"lg\"}\n className={\"w-[800px]\"}\n trigger={<Button size={size} variant={variant} text={label} icon={<AddIcon />} />}\n title={\"Insert a template\"}\n info={<></>}\n >\n <TemplateGallery templates={templates} onSelect={onSelect} />\n </Dialog>\n </div>\n );\n};\n"],"names":["AddTemplateButton","templates","onSelect","label","size","variant","Dialog","Button","AddIcon","TemplateGallery"],"mappings":";;;;AAeO,MAAMA,oBAAoB,CAAC,EAC9BC,SAAS,EACTC,QAAQ,EACRC,KAAK,EACLC,OAAO,IAAI,EACXC,UAAU,UAAU,EACC,GACd,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,QAAMA;QACH,MAAM;QACN,WAAW;QACX,uBAAS,oBAACC,QAAMA;YAAC,MAAMH;YAAM,SAASC;YAAS,MAAMF;YAAO,oBAAM,oBAACK,gBAAOA;;QAC1E,OAAO;QACP,oBAAM;qBAEN,oBAACC,iBAAeA;QAAC,WAAWR;QAAW,UAAUC"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import type { ITemplateVM } from "../../../../../features/formModel/index.js";
3
+ interface SelectableTemplateProps {
4
+ template: ITemplateVM;
5
+ onSelect: (template: ITemplateVM) => void;
6
+ className: string;
7
+ children: React.ReactNode;
8
+ }
9
+ /**
10
+ * A focusable, clickable wrapper that inserts the template and closes the dialog.
11
+ */
12
+ export declare const SelectableTemplate: ({ template, onSelect, className, children }: SelectableTemplateProps) => React.JSX.Element;
13
+ export {};
@@ -0,0 +1,21 @@
1
+ import react from "react";
2
+ import { Dialog } from "@webiny/admin-ui";
3
+ const selectOnEnterOrSpace = (event)=>{
4
+ if ("Enter" !== event.key && " " !== event.key) return;
5
+ event.preventDefault();
6
+ event.currentTarget.click();
7
+ };
8
+ const FOCUS_CLASSES = "focus-visible:outline-none focus-visible:ring-lg focus-visible:ring-primary-dimmed";
9
+ const SelectableTemplate = ({ template, onSelect, className, children })=>/*#__PURE__*/ react.createElement(Dialog.Close, {
10
+ asChild: true
11
+ }, /*#__PURE__*/ react.createElement("div", {
12
+ role: "button",
13
+ tabIndex: 0,
14
+ "aria-label": `Insert ${template.label}`,
15
+ onClick: ()=>onSelect(template),
16
+ onKeyDown: selectOnEnterOrSpace,
17
+ className: `group cursor-pointer ${FOCUS_CLASSES} ${className}`
18
+ }, children));
19
+ export { SelectableTemplate };
20
+
21
+ //# sourceMappingURL=SelectableTemplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.tsx"],"sourcesContent":["import React from \"react\";\nimport { Dialog } from \"@webiny/admin-ui\";\nimport type { ITemplateVM } from \"~/features/formModel/index.js\";\n\n/**\n * Templates are picked by clicking a card or a row. Enter and Space do the same for keyboard users,\n * and go through `click()` so `Dialog.Close` closes the dialog too.\n */\nconst selectOnEnterOrSpace = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== \"Enter\" && event.key !== \" \") {\n return;\n }\n event.preventDefault();\n event.currentTarget.click();\n};\n\nconst FOCUS_CLASSES =\n \"focus-visible:outline-none focus-visible:ring-lg focus-visible:ring-primary-dimmed\";\n\ninterface SelectableTemplateProps {\n template: ITemplateVM;\n onSelect: (template: ITemplateVM) => void;\n className: string;\n children: React.ReactNode;\n}\n\n/**\n * A focusable, clickable wrapper that inserts the template and closes the dialog.\n */\nexport const SelectableTemplate = ({\n template,\n onSelect,\n className,\n children\n}: SelectableTemplateProps) => {\n return (\n <Dialog.Close asChild>\n <div\n role={\"button\"}\n tabIndex={0}\n aria-label={`Insert ${template.label}`}\n onClick={() => onSelect(template)}\n onKeyDown={selectOnEnterOrSpace}\n className={`group cursor-pointer ${FOCUS_CLASSES} ${className}`}\n >\n {children}\n </div>\n </Dialog.Close>\n );\n};\n"],"names":["selectOnEnterOrSpace","event","FOCUS_CLASSES","SelectableTemplate","template","onSelect","className","children","Dialog"],"mappings":";;AAQA,MAAMA,uBAAuB,CAACC;IAC1B,IAAIA,AAAc,YAAdA,MAAM,GAAG,IAAgBA,AAAc,QAAdA,MAAM,GAAG,EAClC;IAEJA,MAAM,cAAc;IACpBA,MAAM,aAAa,CAAC,KAAK;AAC7B;AAEA,MAAMC,gBACF;AAYG,MAAMC,qBAAqB,CAAC,EAC/BC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EACTC,QAAQ,EACc,GACf,WAAP,GACI,oBAACC,OAAO,KAAK;QAAC;qBACV,oBAAC;QACG,MAAM;QACN,UAAU;QACV,cAAY,CAAC,OAAO,EAAEJ,SAAS,KAAK,EAAE;QACtC,SAAS,IAAMC,SAASD;QACxB,WAAWJ;QACX,WAAW,CAAC,qBAAqB,EAAEE,cAAc,CAAC,EAAEI,WAAW;OAE9DC"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { TemplateItemProps } from "./types.js";
3
+ export declare const TemplateCard: ({ template, onSelect }: TemplateItemProps) => React.JSX.Element;
@@ -0,0 +1,35 @@
1
+ import react from "react";
2
+ import { Button, Text } from "@webiny/admin-ui";
3
+ import { ReactComponent } from "@webiny/icons/add_circle_outline.svg";
4
+ import { SelectableTemplate } from "./SelectableTemplate.js";
5
+ import { TemplateIcon } from "./TemplateIcon.js";
6
+ const TemplateCard = ({ template, onSelect })=>/*#__PURE__*/ react.createElement(SelectableTemplate, {
7
+ template: template,
8
+ onSelect: onSelect,
9
+ className: "flex flex-col justify-between bg-neutral-base overflow-hidden rounded-lg w-[173px] relative shadow-sm"
10
+ }, /*#__PURE__*/ react.createElement("div", null, /*#__PURE__*/ react.createElement("div", {
11
+ className: "flex items-center justify-center py-xxl w-full bg-neutral-dimmed"
12
+ }, /*#__PURE__*/ react.createElement(TemplateIcon, {
13
+ icon: template.icon,
14
+ size: 40
15
+ })), /*#__PURE__*/ react.createElement("div", {
16
+ className: "py-sm-extra px-md"
17
+ }, /*#__PURE__*/ react.createElement(Text, {
18
+ size: "md",
19
+ className: "mb-xs text-neutral-primary font-semibold"
20
+ }, template.label), template.description && /*#__PURE__*/ react.createElement(Text, {
21
+ size: "sm",
22
+ as: "div",
23
+ className: "text-neutral-muted line-clamp-2"
24
+ }, template.description))), /*#__PURE__*/ react.createElement("div", {
25
+ className: "absolute inset-0 hidden items-center justify-center bg-white/80 group-hover:flex group-focus-visible:flex"
26
+ }, /*#__PURE__*/ react.createElement(Button, {
27
+ size: "lg",
28
+ variant: "primary",
29
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
30
+ tabIndex: -1,
31
+ "aria-hidden": true
32
+ }, "Insert")));
33
+ export { TemplateCard };
34
+
35
+ //# sourceMappingURL=TemplateCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.tsx"],"sourcesContent":["import React from \"react\";\nimport { Button } from \"@webiny/admin-ui\";\nimport { Text } from \"@webiny/admin-ui\";\nimport { ReactComponent as PlusIcon } from \"@webiny/icons/add_circle_outline.svg\";\nimport { SelectableTemplate } from \"./SelectableTemplate.js\";\nimport { TemplateIcon } from \"./TemplateIcon.js\";\nimport type { TemplateItemProps } from \"./types.js\";\n\nexport const TemplateCard = ({ template, onSelect }: TemplateItemProps) => {\n return (\n <SelectableTemplate\n template={template}\n onSelect={onSelect}\n className={\n \"flex flex-col justify-between bg-neutral-base overflow-hidden rounded-lg w-[173px] relative shadow-sm\"\n }\n >\n <div>\n <div className={\"flex items-center justify-center py-xxl w-full bg-neutral-dimmed\"}>\n <TemplateIcon icon={template.icon} size={40} />\n </div>\n <div className={\"py-sm-extra px-md\"}>\n <Text size={\"md\"} className={\"mb-xs text-neutral-primary font-semibold\"}>\n {template.label}\n </Text>\n {template.description && (\n <Text size={\"sm\"} as={\"div\"} className={\"text-neutral-muted line-clamp-2\"}>\n {template.description}\n </Text>\n )}\n </div>\n </div>\n\n <div\n className={\n \"absolute inset-0 hidden items-center justify-center bg-white/80 group-hover:flex group-focus-visible:flex\"\n }\n >\n <Button\n size={\"lg\"}\n variant={\"primary\"}\n icon={<PlusIcon />}\n tabIndex={-1}\n aria-hidden={true}\n >\n Insert\n </Button>\n </div>\n </SelectableTemplate>\n );\n};\n"],"names":["TemplateCard","template","onSelect","SelectableTemplate","TemplateIcon","Text","Button","PlusIcon"],"mappings":";;;;;AAQO,MAAMA,eAAe,CAAC,EAAEC,QAAQ,EAAEC,QAAQ,EAAqB,GAC3D,WAAP,GACI,oBAACC,oBAAkBA;QACf,UAAUF;QACV,UAAUC;QACV,WACI;qBAGJ,oBAAC,2BACG,oBAAC;QAAI,WAAW;qBACZ,oBAACE,cAAYA;QAAC,MAAMH,SAAS,IAAI;QAAE,MAAM;uBAE7C,oBAAC;QAAI,WAAW;qBACZ,oBAACI,MAAIA;QAAC,MAAM;QAAM,WAAW;OACxBJ,SAAS,KAAK,GAElBA,SAAS,WAAW,IAAI,WAAJ,GACjB,oBAACI,MAAIA;QAAC,MAAM;QAAM,IAAI;QAAO,WAAW;OACnCJ,SAAS,WAAW,mBAMrC,oBAAC;QACG,WACI;qBAGJ,oBAACK,QAAMA;QACH,MAAM;QACN,SAAS;QACT,oBAAM,oBAACC,gBAAQA;QACf,UAAU;QACV,eAAa;OAChB"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import type { ITemplateVM } from "../../../../../features/formModel/index.js";
3
+ interface TemplateGalleryProps {
4
+ templates: ITemplateVM[];
5
+ onSelect: (template: ITemplateVM) => void;
6
+ }
7
+ export declare const TemplateGallery: ({ templates, onSelect }: TemplateGalleryProps) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,22 @@
1
+ import react, { useState } from "react";
2
+ import { TemplateGalleryToolbar } from "./TemplateGalleryToolbar.js";
3
+ import { TemplateList } from "./TemplateList.js";
4
+ const TemplateGallery = ({ templates, onSelect })=>{
5
+ const [viewMode, setViewMode] = useState("grid");
6
+ const [search, setSearch] = useState("");
7
+ const query = search.toLowerCase();
8
+ const filteredTemplates = templates.filter((template)=>template.label.toLowerCase().includes(query));
9
+ return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(TemplateGalleryToolbar, {
10
+ search: search,
11
+ onSearch: setSearch,
12
+ viewMode: viewMode,
13
+ onViewMode: setViewMode
14
+ }), /*#__PURE__*/ react.createElement(TemplateList, {
15
+ viewMode: viewMode,
16
+ templates: filteredTemplates,
17
+ onSelect: onSelect
18
+ }));
19
+ };
20
+ export { TemplateGallery };
21
+
22
+ //# sourceMappingURL=TemplateGallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport type { ITemplateVM } from \"~/features/formModel/index.js\";\nimport { TemplateGalleryToolbar } from \"./TemplateGalleryToolbar.js\";\nimport { TemplateList } from \"./TemplateList.js\";\nimport type { ViewMode } from \"./types.js\";\n\ninterface TemplateGalleryProps {\n templates: ITemplateVM[];\n onSelect: (template: ITemplateVM) => void;\n}\n\nexport const TemplateGallery = ({ templates, onSelect }: TemplateGalleryProps) => {\n const [viewMode, setViewMode] = useState<ViewMode>(\"grid\");\n const [search, setSearch] = useState(\"\");\n\n const query = search.toLowerCase();\n const filteredTemplates = templates.filter(template =>\n template.label.toLowerCase().includes(query)\n );\n\n return (\n <>\n <TemplateGalleryToolbar\n search={search}\n onSearch={setSearch}\n viewMode={viewMode}\n onViewMode={setViewMode}\n />\n <TemplateList viewMode={viewMode} templates={filteredTemplates} onSelect={onSelect} />\n </>\n );\n};\n"],"names":["TemplateGallery","templates","onSelect","viewMode","setViewMode","useState","search","setSearch","query","filteredTemplates","template","TemplateGalleryToolbar","TemplateList"],"mappings":";;;AAWO,MAAMA,kBAAkB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAwB;IACzE,MAAM,CAACC,UAAUC,YAAY,GAAGC,SAAmB;IACnD,MAAM,CAACC,QAAQC,UAAU,GAAGF,SAAS;IAErC,MAAMG,QAAQF,OAAO,WAAW;IAChC,MAAMG,oBAAoBR,UAAU,MAAM,CAACS,CAAAA,WACvCA,SAAS,KAAK,CAAC,WAAW,GAAG,QAAQ,CAACF;IAG1C,OAAO,WAAP,GACI,wDACI,oBAACG,wBAAsBA;QACnB,QAAQL;QACR,UAAUC;QACV,UAAUJ;QACV,YAAYC;sBAEhB,oBAACQ,cAAYA;QAAC,UAAUT;QAAU,WAAWM;QAAmB,UAAUP;;AAGtF"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { ViewMode } from "./types.js";
3
+ interface TemplateGalleryToolbarProps {
4
+ search: string;
5
+ onSearch: (search: string) => void;
6
+ viewMode: ViewMode;
7
+ onViewMode: (viewMode: ViewMode) => void;
8
+ }
9
+ export declare const TemplateGalleryToolbar: ({ search, onSearch, viewMode, onViewMode }: TemplateGalleryToolbarProps) => React.JSX.Element;
10
+ export {};
@@ -0,0 +1,46 @@
1
+ import react from "react";
2
+ import { DelayedOnChange, Icon, Input, ToggleGroup } from "@webiny/admin-ui";
3
+ import { ReactComponent } from "@webiny/icons/search.svg";
4
+ import { ReactComponent as grid_view_svg_ReactComponent } from "@webiny/icons/grid_view.svg";
5
+ import { ReactComponent as list_svg_ReactComponent } from "@webiny/icons/list.svg";
6
+ const TemplateGalleryToolbar = ({ search, onSearch, viewMode, onViewMode })=>/*#__PURE__*/ react.createElement("div", {
7
+ className: "flex items-center gap-sm pb-md pt-xs"
8
+ }, /*#__PURE__*/ react.createElement("div", {
9
+ className: "flex-1 min-w-0"
10
+ }, /*#__PURE__*/ react.createElement(DelayedOnChange, {
11
+ value: search,
12
+ onChange: onSearch
13
+ }, ({ value, onChange })=>/*#__PURE__*/ react.createElement(Input, {
14
+ autoFocus: true,
15
+ value: value,
16
+ onChange: onChange,
17
+ placeholder: "Search templates...",
18
+ startIcon: /*#__PURE__*/ react.createElement(Icon, {
19
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
20
+ label: "Search"
21
+ }),
22
+ size: "md",
23
+ variant: "primary"
24
+ }))), /*#__PURE__*/ react.createElement("div", {
25
+ className: "shrink-0"
26
+ }, /*#__PURE__*/ react.createElement(ToggleGroup, {
27
+ type: "single",
28
+ value: viewMode,
29
+ onChange: (value)=>onViewMode(value),
30
+ items: [
31
+ {
32
+ id: "grid",
33
+ value: "grid",
34
+ icon: /*#__PURE__*/ react.createElement(grid_view_svg_ReactComponent, null)
35
+ },
36
+ {
37
+ id: "list",
38
+ value: "list",
39
+ icon: /*#__PURE__*/ react.createElement(list_svg_ReactComponent, null)
40
+ }
41
+ ],
42
+ variant: "ghost"
43
+ })));
44
+ export { TemplateGalleryToolbar };
45
+
46
+ //# sourceMappingURL=TemplateGalleryToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.tsx"],"sourcesContent":["import React from \"react\";\nimport { DelayedOnChange } from \"@webiny/admin-ui\";\nimport { Icon } from \"@webiny/admin-ui\";\nimport { Input } from \"@webiny/admin-ui\";\nimport { ToggleGroup } from \"@webiny/admin-ui\";\nimport { ReactComponent as SearchIcon } from \"@webiny/icons/search.svg\";\nimport { ReactComponent as GridIcon } from \"@webiny/icons/grid_view.svg\";\nimport { ReactComponent as ListIcon } from \"@webiny/icons/list.svg\";\nimport type { ViewMode } from \"./types.js\";\n\ninterface TemplateGalleryToolbarProps {\n search: string;\n onSearch: (search: string) => void;\n viewMode: ViewMode;\n onViewMode: (viewMode: ViewMode) => void;\n}\n\nexport const TemplateGalleryToolbar = ({\n search,\n onSearch,\n viewMode,\n onViewMode\n}: TemplateGalleryToolbarProps) => {\n return (\n <div className={\"flex items-center gap-sm pb-md pt-xs\"}>\n <div className={\"flex-1 min-w-0\"}>\n <DelayedOnChange value={search} onChange={onSearch}>\n {({ value, onChange }) => (\n <Input\n autoFocus={true}\n value={value}\n onChange={onChange}\n placeholder={\"Search templates...\"}\n startIcon={<Icon icon={<SearchIcon />} label={\"Search\"} />}\n size={\"md\"}\n variant={\"primary\"}\n />\n )}\n </DelayedOnChange>\n </div>\n <div className={\"shrink-0\"}>\n <ToggleGroup\n type=\"single\"\n value={viewMode}\n onChange={value => onViewMode(value as ViewMode)}\n items={[\n { id: \"grid\", value: \"grid\", icon: <GridIcon /> },\n { id: \"list\", value: \"list\", icon: <ListIcon /> }\n ]}\n variant=\"ghost\"\n />\n </div>\n </div>\n );\n};\n"],"names":["TemplateGalleryToolbar","search","onSearch","viewMode","onViewMode","DelayedOnChange","value","onChange","Input","Icon","SearchIcon","ToggleGroup","GridIcon","ListIcon"],"mappings":";;;;;AAiBO,MAAMA,yBAAyB,CAAC,EACnCC,MAAM,EACNC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACgB,GACnB,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAAC;QAAI,WAAW;qBACZ,oBAACC,iBAAeA;QAAC,OAAOJ;QAAQ,UAAUC;OACrC,CAAC,EAAEI,KAAK,EAAEC,QAAQ,EAAE,iBACjB,oBAACC,OAAKA;YACF,WAAW;YACX,OAAOF;YACP,UAAUC;YACV,aAAa;YACb,yBAAW,oBAACE,MAAIA;gBAAC,oBAAM,oBAACC,gBAAUA;gBAAK,OAAO;;YAC9C,MAAM;YACN,SAAS;4BAKzB,oBAAC;QAAI,WAAW;qBACZ,oBAACC,aAAWA;QACR,MAAK;QACL,OAAOR;QACP,UAAUG,CAAAA,QAASF,WAAWE;QAC9B,OAAO;YACH;gBAAE,IAAI;gBAAQ,OAAO;gBAAQ,MAAM,WAAN,GAAM,oBAACM,8BAAQA;YAAI;YAChD;gBAAE,IAAI;gBAAQ,OAAO;gBAAQ,MAAM,WAAN,GAAM,oBAACC,yBAAQA;YAAI;SACnD;QACD,SAAQ"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import type { ITemplateIcon } from "../../../../../features/formModel/index.js";
3
+ interface TemplateIconProps {
4
+ icon: ITemplateIcon | undefined;
5
+ size: number;
6
+ }
7
+ export declare const TemplateIcon: ({ icon, size }: TemplateIconProps) => React.JSX.Element | null;
8
+ export {};
@@ -0,0 +1,16 @@
1
+ import react from "react";
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
+ const TemplateIcon = ({ icon, size })=>{
4
+ if (!icon) return null;
5
+ return /*#__PURE__*/ react.createElement(FontAwesomeIcon, {
6
+ className: "text-neutral-xstrong",
7
+ icon: icon.name.split("/"),
8
+ style: {
9
+ width: size,
10
+ height: size
11
+ }
12
+ });
13
+ };
14
+ export { TemplateIcon };
15
+
16
+ //# sourceMappingURL=TemplateIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.tsx"],"sourcesContent":["import React from \"react\";\nimport type { IconProp } from \"@fortawesome/fontawesome-svg-core\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type { ITemplateIcon } from \"~/features/formModel/index.js\";\n\ninterface TemplateIconProps {\n icon: ITemplateIcon | undefined;\n size: number;\n}\n\nexport const TemplateIcon = ({ icon, size }: TemplateIconProps) => {\n if (!icon) {\n return null;\n }\n\n return (\n <FontAwesomeIcon\n className={\"text-neutral-xstrong\"}\n icon={icon.name.split(\"/\") as IconProp}\n style={{ width: size, height: size }}\n />\n );\n};\n"],"names":["TemplateIcon","icon","size","FontAwesomeIcon"],"mappings":";;AAUO,MAAMA,eAAe,CAAC,EAAEC,IAAI,EAAEC,IAAI,EAAqB;IAC1D,IAAI,CAACD,MACD,OAAO;IAGX,OAAO,WAAP,GACI,oBAACE,iBAAeA;QACZ,WAAW;QACX,MAAMF,KAAK,IAAI,CAAC,KAAK,CAAC;QACtB,OAAO;YAAE,OAAOC;YAAM,QAAQA;QAAK;;AAG/C"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { ITemplateVM } from "../../../../../features/formModel/index.js";
3
+ import type { ViewMode } from "./types.js";
4
+ interface TemplateListProps {
5
+ viewMode: ViewMode;
6
+ templates: ITemplateVM[];
7
+ onSelect: (template: ITemplateVM) => void;
8
+ }
9
+ export declare const TemplateList: ({ viewMode, templates, onSelect }: TemplateListProps) => React.JSX.Element;
10
+ export {};
@@ -0,0 +1,22 @@
1
+ import react from "react";
2
+ import { TemplateCard } from "./TemplateCard.js";
3
+ import { TemplateListItem } from "./TemplateListItem.js";
4
+ const TemplateList = ({ viewMode, templates, onSelect })=>{
5
+ if ("list" === viewMode) return /*#__PURE__*/ react.createElement("div", {
6
+ className: "flex flex-col gap-y-sm mb-xs"
7
+ }, templates.map((template)=>/*#__PURE__*/ react.createElement(TemplateListItem, {
8
+ key: template.id,
9
+ template: template,
10
+ onSelect: onSelect
11
+ })));
12
+ return /*#__PURE__*/ react.createElement("div", {
13
+ className: "gap-md flex flex-wrap p-xs mb-xs"
14
+ }, templates.map((template)=>/*#__PURE__*/ react.createElement(TemplateCard, {
15
+ key: template.id,
16
+ template: template,
17
+ onSelect: onSelect
18
+ })));
19
+ };
20
+ export { TemplateList };
21
+
22
+ //# sourceMappingURL=TemplateList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.tsx"],"sourcesContent":["import React from \"react\";\nimport type { ITemplateVM } from \"~/features/formModel/index.js\";\nimport { TemplateCard } from \"./TemplateCard.js\";\nimport { TemplateListItem } from \"./TemplateListItem.js\";\nimport type { ViewMode } from \"./types.js\";\n\ninterface TemplateListProps {\n viewMode: ViewMode;\n templates: ITemplateVM[];\n onSelect: (template: ITemplateVM) => void;\n}\n\nexport const TemplateList = ({ viewMode, templates, onSelect }: TemplateListProps) => {\n if (viewMode === \"list\") {\n return (\n <div className={\"flex flex-col gap-y-sm mb-xs\"}>\n {templates.map(template => (\n <TemplateListItem key={template.id} template={template} onSelect={onSelect} />\n ))}\n </div>\n );\n }\n\n return (\n <div className={\"gap-md flex flex-wrap p-xs mb-xs\"}>\n {templates.map(template => (\n <TemplateCard key={template.id} template={template} onSelect={onSelect} />\n ))}\n </div>\n );\n};\n"],"names":["TemplateList","viewMode","templates","onSelect","template","TemplateListItem","TemplateCard"],"mappings":";;;AAYO,MAAMA,eAAe,CAAC,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,QAAQ,EAAqB;IAC7E,IAAIF,AAAa,WAAbA,UACA,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;OACXC,UAAU,GAAG,CAACE,CAAAA,WAAAA,WAAAA,GACX,oBAACC,kBAAgBA;YAAC,KAAKD,SAAS,EAAE;YAAE,UAAUA;YAAU,UAAUD;;IAMlF,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;OACXD,UAAU,GAAG,CAACE,CAAAA,WAAAA,WAAAA,GACX,oBAACE,cAAYA;YAAC,KAAKF,SAAS,EAAE;YAAE,UAAUA;YAAU,UAAUD;;AAI9E"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { TemplateItemProps } from "./types.js";
3
+ export declare const TemplateListItem: ({ template, onSelect }: TemplateItemProps) => React.JSX.Element;
@@ -0,0 +1,35 @@
1
+ import react from "react";
2
+ import { Button, Text } from "@webiny/admin-ui";
3
+ import { ReactComponent } from "@webiny/icons/add_circle_outline.svg";
4
+ import { SelectableTemplate } from "./SelectableTemplate.js";
5
+ import { TemplateIcon } from "./TemplateIcon.js";
6
+ const TemplateListItem = ({ template, onSelect })=>/*#__PURE__*/ react.createElement(SelectableTemplate, {
7
+ template: template,
8
+ onSelect: onSelect,
9
+ className: "flex items-center py-sm-extra px-md rounded-lg bg-neutral-light hover:bg-[#f1f2f4]"
10
+ }, /*#__PURE__*/ react.createElement("div", {
11
+ className: "flex items-center justify-center shrink-0 pr-md"
12
+ }, /*#__PURE__*/ react.createElement(TemplateIcon, {
13
+ icon: template.icon,
14
+ size: 24
15
+ })), /*#__PURE__*/ react.createElement("div", {
16
+ className: "flex-1 min-w-0"
17
+ }, /*#__PURE__*/ react.createElement(Text, {
18
+ size: "md",
19
+ className: "text-neutral-primary font-semibold truncate"
20
+ }, template.label), template.description && /*#__PURE__*/ react.createElement(Text, {
21
+ size: "sm",
22
+ as: "div",
23
+ className: "text-neutral-muted"
24
+ }, template.description)), /*#__PURE__*/ react.createElement("div", {
25
+ className: "hidden group-hover:block group-focus-visible:block"
26
+ }, /*#__PURE__*/ react.createElement(Button, {
27
+ size: "md",
28
+ variant: "primary",
29
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
30
+ tabIndex: -1,
31
+ "aria-hidden": true
32
+ }, "Insert")));
33
+ export { TemplateListItem };
34
+
35
+ //# sourceMappingURL=TemplateListItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.js","sources":["../../../../../../src/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.tsx"],"sourcesContent":["import React from \"react\";\nimport { Button } from \"@webiny/admin-ui\";\nimport { Text } from \"@webiny/admin-ui\";\nimport { ReactComponent as PlusIcon } from \"@webiny/icons/add_circle_outline.svg\";\nimport { SelectableTemplate } from \"./SelectableTemplate.js\";\nimport { TemplateIcon } from \"./TemplateIcon.js\";\nimport type { TemplateItemProps } from \"./types.js\";\n\n// Used #f1f2f4 b/c in Figma, the color was result of multiple colors combined.\nexport const TemplateListItem = ({ template, onSelect }: TemplateItemProps) => {\n return (\n <SelectableTemplate\n template={template}\n onSelect={onSelect}\n className={\n \"flex items-center py-sm-extra px-md rounded-lg bg-neutral-light hover:bg-[#f1f2f4]\"\n }\n >\n <div className={\"flex items-center justify-center shrink-0 pr-md\"}>\n <TemplateIcon icon={template.icon} size={24} />\n </div>\n <div className={\"flex-1 min-w-0\"}>\n <Text size={\"md\"} className={\"text-neutral-primary font-semibold truncate\"}>\n {template.label}\n </Text>\n {template.description && (\n <Text size={\"sm\"} as={\"div\"} className={\"text-neutral-muted\"}>\n {template.description}\n </Text>\n )}\n </div>\n <div className={\"hidden group-hover:block group-focus-visible:block\"}>\n <Button\n size={\"md\"}\n variant={\"primary\"}\n icon={<PlusIcon />}\n tabIndex={-1}\n aria-hidden={true}\n >\n Insert\n </Button>\n </div>\n </SelectableTemplate>\n );\n};\n"],"names":["TemplateListItem","template","onSelect","SelectableTemplate","TemplateIcon","Text","Button","PlusIcon"],"mappings":";;;;;AASO,MAAMA,mBAAmB,CAAC,EAAEC,QAAQ,EAAEC,QAAQ,EAAqB,GAC/D,WAAP,GACI,oBAACC,oBAAkBA;QACf,UAAUF;QACV,UAAUC;QACV,WACI;qBAGJ,oBAAC;QAAI,WAAW;qBACZ,oBAACE,cAAYA;QAAC,MAAMH,SAAS,IAAI;QAAE,MAAM;uBAE7C,oBAAC;QAAI,WAAW;qBACZ,oBAACI,MAAIA;QAAC,MAAM;QAAM,WAAW;OACxBJ,SAAS,KAAK,GAElBA,SAAS,WAAW,IAAI,WAAJ,GACjB,oBAACI,MAAIA;QAAC,MAAM;QAAM,IAAI;QAAO,WAAW;OACnCJ,SAAS,WAAW,kBAIjC,oBAAC;QAAI,WAAW;qBACZ,oBAACK,QAAMA;QACH,MAAM;QACN,SAAS;QACT,oBAAM,oBAACC,gBAAQA;QACf,UAAU;QACV,eAAa;OAChB"}