diff --git a/packages/playground/admin/app/pages/blocks.tsx b/packages/playground/admin/app/pages/blocks.tsx index 2e1b006f3..05271a7e2 100644 --- a/packages/playground/admin/app/pages/blocks.tsx +++ b/packages/playground/admin/app/pages/blocks.tsx @@ -6,7 +6,7 @@ import { DefaultBlockRepeater } from '../../lib/components/block-repeater' import { ImageField, InputField, RadioEnumField, TextareaField } from '../../lib/components/form' import { UploadedImageView } from '../../lib/components/upload' import { Block } from '@contember/react-block-repeater' -import { AlertOctagonIcon, ImageIcon, TextIcon } from 'lucide-react' +import { AlertOctagonIcon, ColumnsIcon, ImageIcon, TextIcon } from 'lucide-react' import { cn } from '../../lib/utils/cn' export default () => <> @@ -64,7 +64,7 @@ export default () => <> /> Image with text} + label={<> Image with text} form={<> diff --git a/packages/playground/admin/lib/components/block-repeater.tsx b/packages/playground/admin/lib/components/block-repeater.tsx index 04d9f05bf..190252294 100644 --- a/packages/playground/admin/lib/components/block-repeater.tsx +++ b/packages/playground/admin/lib/components/block-repeater.tsx @@ -1,24 +1,26 @@ import { Component, DeleteEntityTrigger, PersistTrigger, StaticRender, useEntity } from '@contember/interface' import { RepeaterSortable, RepeaterSortableDragOverlay, RepeaterSortableEachItem, RepeaterSortableItemActivator, RepeaterSortableItemNode } from '@contember/react-repeater-dnd-kit' -import { GripVerticalIcon, TrashIcon } from 'lucide-react' +import { GripVerticalIcon, PlusCircleIcon, TrashIcon } from 'lucide-react' import { Button } from './ui/button' import { uic } from '../utils/uic' import { Sheet, SheetClose, SheetContent, SheetFooter, SheetHeader, SheetTitle } from './ui/sheet' import { BlockRepeater, BlockRepeaterAddItemTrigger, BlockRepeaterProps, useBlockRepeaterConfig, useBlockRepeaterCurrentBlock } from '@contember/react-block-repeater' import { RepeaterDropIndicator, RepeaterRemoveItemButton } from './repeater' -import { RepeaterEmpty } from '@contember/react-repeater' +import { RepeaterAddItemIndex, RepeaterEmpty } from '@contember/react-repeater' import { dict } from '../dict' import { FeedbackTrigger } from './binding' import { createRequiredContext } from '@contember/react-utils' -import { useId, useState } from 'react' +import { useEffect, useId, useState } from 'react' import { Label } from './ui/label' import { Switch } from './ui/switch' +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './ui/dropdown' +import { cn } from '../utils/cn' export const BlockRepeaterItemsWrapperUI = uic('div', { - baseClass: 'rounded border border-gray-300 p-4 flex flex-col', + baseClass: 'rounded border border-gray-300 px-4 py-8 flex flex-col', }) export const BlockRepeaterItemUI = uic('div', { - baseClass: ' relative border-b transition-all group', + baseClass: 'relative border-t transition-all group', }) export const BlockRepeaterDragOverlayUI = uic('div', { baseClass: 'rounded border border-gray-300 p-4 relative bg-opacity-60 bg-gray-100 backdrop-blur-sm', @@ -46,7 +48,7 @@ export const DefaultBlockRepeater = Component(({ chil - +
@@ -72,7 +74,7 @@ const ToggleEditMode = ({ setEditMode, editMode }: { setEditMode: (value: boolea ) } -export const BlockRepeaterSortable = Component(() => { +export const BlockRepeaterSortable = Component<{ sortableBy: DefaultBlockRepeaterProps['sortableBy'] }>(({ sortableBy }) => { return ( @@ -82,7 +84,7 @@ export const BlockRepeaterSortable = Component(() => { -
+
@@ -93,6 +95,7 @@ export const BlockRepeaterSortable = Component(() => { +
@@ -107,13 +110,13 @@ export const BlockRepeaterSortable = Component(() => { ) }) -export const BlockRepeaterAddButtons = () => { +export const BlockRepeaterAddButtons = ({ index }: { index?: RepeaterAddItemIndex }) => { const { blocks } = useBlockRepeaterConfig() return (
{Object.values(blocks).map(it => ( - - @@ -150,6 +153,34 @@ export const BlockRepeaterContent = () => { } + +const BlockRepeaterAddItemBefore = ({ sortableBy }: { sortableBy: DefaultBlockRepeaterProps['sortableBy'] }) => { + const entity = useEntity() + const order = sortableBy ? entity.getField(sortableBy).value : null + const { blocks } = useBlockRepeaterConfig() + if (order === null) { + return null + } + return ( + + + + + + {Object.values(blocks).map(it => ( + + + {it.label || it.name} + + + ))} + + + ) +} + const BlockRepeaterEditSheetInner = ({ open, setOpen }: { open: boolean, setOpen: (value: boolean) => void }) => { const block = useBlockRepeaterCurrentBlock() const form = block?.form diff --git a/packages/react-repeater/src/internal/useCreateRepeaterMethods.tsx b/packages/react-repeater/src/internal/useCreateRepeaterMethods.tsx index 16aeae687..a2406785f 100644 --- a/packages/react-repeater/src/internal/useCreateRepeaterMethods.tsx +++ b/packages/react-repeater/src/internal/useCreateRepeaterMethods.tsx @@ -32,8 +32,8 @@ export const useCreateRepeaterMethods = ({ accessor, sortableBy }: { } })() entities.createNewEntity((getEntity, options) => { - const newSorted = sortedEntities.splice(resolvedIndex, 0, getEntity()) - repairEntitiesOrder(sortableBy, newSorted) + sortedEntities.splice(resolvedIndex, 0, getEntity()) + repairEntitiesOrder(sortableBy, sortedEntities) preprocess?.(getEntity, options) }) }, @@ -71,8 +71,8 @@ export const useCreateRepeaterMethods = ({ accessor, sortableBy }: { const sortedEntities = sortEntities(Array.from(entities), sortableBy) const currentIndex = sortedEntities.findIndex(it => it.id === entity.id) if (currentIndex !== -1) { - const newSorted = sortedEntities.splice(currentIndex, 1) - repairEntitiesOrder(sortableBy, newSorted) + sortedEntities.splice(currentIndex, 1) + repairEntitiesOrder(sortableBy, sortedEntities) } } entity.deleteEntity()