diff --git a/packages/playground/admin/app/components/navigation.tsx b/packages/playground/admin/app/components/navigation.tsx index 279fb84bd..88de28ffd 100644 --- a/packages/playground/admin/app/components/navigation.tsx +++ b/packages/playground/admin/app/components/navigation.tsx @@ -17,10 +17,10 @@ export const Navigation = () => { } label={'Repeater'}> - - - - + + + + } label={'Grid'}> @@ -39,6 +39,7 @@ export const Navigation = () => { + } label={'Upload'}> diff --git a/packages/playground/admin/app/pages/select.tsx b/packages/playground/admin/app/pages/select.tsx index b7557bc08..14ed77b7f 100644 --- a/packages/playground/admin/app/pages/select.tsx +++ b/packages/playground/admin/app/pages/select.tsx @@ -3,7 +3,7 @@ import { Binding, PersistButton } from '../../lib/components/binding' import { EntitySubTree } from '@contember/interface' import * as React from 'react' import { Field } from '@contember/react-binding' -import { InputField, MultiSelectField, SelectField, SortableMultiSelectField } from '../../lib/components/form' +import { InputField, MultiSelectField, SelectEnumField, SelectField, SortableMultiSelectField } from '../../lib/components/form' export const hasOne = () => <> @@ -70,3 +70,20 @@ export const createNewForm = () => <> + +export const enumSelect = () => <> + + + + + +
+ +
+
+
+ diff --git a/packages/playground/admin/lib/components/form/inputs.tsx b/packages/playground/admin/lib/components/form/inputs.tsx index 4472f11ac..3b38e45b5 100644 --- a/packages/playground/admin/lib/components/form/inputs.tsx +++ b/packages/playground/admin/lib/components/form/inputs.tsx @@ -6,7 +6,7 @@ import { TextareaAutosize } from '../ui/textarea' import { FormLabelUI } from './ui' import { FormCheckbox, FormCheckboxProps, FormFieldScope, FormInput, FormInputProps, FormLabel, FormRadioInput, FormRadioItemProps } from '@contember/react-form' import { FormContainer, FormContainerProps } from './container' -import { Component, Field, SugaredRelativeSingleField } from '@contember/interface' +import { Component } from '@contember/interface' export type InputFieldProps = diff --git a/packages/playground/admin/lib/components/form/select.tsx b/packages/playground/admin/lib/components/form/select.tsx index a81292962..b1625ff49 100644 --- a/packages/playground/admin/lib/components/form/select.tsx +++ b/packages/playground/admin/lib/components/form/select.tsx @@ -1,8 +1,23 @@ -import { MultiSelectInput, MultiSelectInputProps, SelectInput, SelectInputProps, SortableMultiSelectInput, SortableMultiSelectInputProps } from '../select' +import { + MultiSelectInput, + MultiSelectInputProps, + SelectDefaultPlaceholderUI, + SelectInput, + SelectInputActionsUI, + SelectInputProps, + SelectInputUI, + SelectInputWrapperUI, + SelectListItemUI, + SelectPopoverContent, + SortableMultiSelectInput, + SortableMultiSelectInputProps, +} from '../select' import * as React from 'react' import { FormContainer, FormContainerProps } from './container' -import { FormHasManyRelationScope, FormHasOneRelationScope } from '@contember/react-form' -import { Component } from '@contember/interface' +import { FormFieldScope, FormHasManyRelationScope, FormHasOneRelationScope, useFormFieldId } from '@contember/react-form' +import { Component, Field, SugaredRelativeSingleField, useField } from '@contember/interface' +import { Popover, PopoverTrigger } from '../ui/popover' +import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' export type SelectFieldProps = @@ -52,3 +67,57 @@ export const SortableMultiSelectField = Component ) }) + +export type SelectEnumFieldProps = + & Omit + & { + field: SugaredRelativeSingleField['field'] + options: Record + placeholder?: React.ReactNode + defaultValue?: string + } + +export const SelectEnumField = Component( + ({ field, label, description, options, placeholder }) => { + return ( + + + + + + ) + }, + ({ field, defaultValue }) => , + 'SelectEnumField', +) + +const SelectEnumFieldInner = ({ field, options, placeholder }: SelectEnumFieldProps) => { + const [open, setOpen] = React.useState(false) + const fieldAccessor = useField(field) + const id = useFormFieldId() + return ( + + + + + {fieldAccessor.value ? options[fieldAccessor.value] : placeholder ?? } + + {open ? : } + + + + + + {Object.entries(options).map(([value, label]) => ( + { + fieldAccessor.updateValue(value) + setOpen(false) + }}> + {label} + + ))} + + + + ) +} diff --git a/packages/playground/admin/lib/components/select/multi-select.tsx b/packages/playground/admin/lib/components/select/multi-select.tsx index aaf340a90..fa11e0b57 100644 --- a/packages/playground/admin/lib/components/select/multi-select.tsx +++ b/packages/playground/admin/lib/components/select/multi-select.tsx @@ -1,6 +1,17 @@ import * as React from 'react' import { ReactNode } from 'react' -import { MultiSelectItemContentUI, MultiSelectItemRemoveButtonUI, MultiSelectItemUI, SelectCreateNewTrigger, SelectDefaultPlaceholderUI, SelectInputActionsUI, SelectInputUI, SelectListItemUI, SelectPopoverContent } from './ui' +import { + MultiSelectItemContentUI, + MultiSelectItemRemoveButtonUI, + MultiSelectItemUI, + SelectCreateNewTrigger, + SelectDefaultPlaceholderUI, + SelectInputActionsUI, + SelectInputUI, + SelectInputWrapperUI, + SelectListItemUI, + SelectPopoverContent, +} from './ui' import { ChevronDownIcon } from 'lucide-react' import { Popover, PopoverTrigger } from '../ui/popover' import { Component, SugaredQualifiedEntityList, SugaredRelativeEntityList } from '@contember/interface' @@ -9,6 +20,7 @@ import { SelectListInner } from './list' import { MultiSelect, SelectDataView, SelectEachValue, SelectItemTrigger, SelectOption, SelectPlaceholder } from '@contember/react-select' import { CreateEntityDialog } from './create-new' import { DataViewUnionFilterFields } from '@contember/react-dataview' +import { useFormFieldId } from '@contember/react-form' export type MultiSelectInputProps = & { @@ -21,32 +33,36 @@ export type MultiSelectInputProps = } export const MultiSelectInput = Component(({ field, queryField, options, children, placeholder, createNewForm }) => { + const id = useFormFieldId() return (
- - - - {placeholder ?? } - + + + + + {placeholder ?? } + - - - - {children} - - - e.stopPropagation()} /> - - - + + + + {children} + + + e.stopPropagation()} /> + + + + + + + + + - - - - - + }> @@ -69,4 +85,10 @@ export const MultiSelectInput = Component(({ field, query
) +}, ({ field, options, children }) => { + return ( + + {children} + + ) }) diff --git a/packages/playground/admin/lib/components/select/select.tsx b/packages/playground/admin/lib/components/select/select.tsx index 25ab09de3..2e7a32873 100644 --- a/packages/playground/admin/lib/components/select/select.tsx +++ b/packages/playground/admin/lib/components/select/select.tsx @@ -5,12 +5,13 @@ import { Component, SugaredQualifiedEntityList } from '@contember/interface' import { Button } from '../ui/button' import { SugaredRelativeSingleEntity } from '@contember/react-binding' import { ChevronDownIcon, XIcon } from 'lucide-react' -import { SelectCreateNewTrigger, SelectDefaultPlaceholderUI, SelectInputActionsUI, SelectInputUI, SelectListItemUI, SelectPopoverContent } from './ui' +import { SelectCreateNewTrigger, SelectDefaultPlaceholderUI, SelectInputActionsUI, SelectInputUI, SelectInputWrapperUI, SelectListItemUI, SelectPopoverContent } from './ui' import { SelectListInner } from './list' import { Select, SelectDataView, SelectEachValue, SelectItemTrigger, SelectOption, SelectPlaceholder } from '@contember/react-select' import { CreateEntityDialog } from './create-new' import { SelectDefaultFilter } from './filter' import { DataViewUnionFilterFields } from '@contember/react-dataview' +import { useFormFieldId } from '@contember/react-form' export type SelectInputProps = & { @@ -25,36 +26,37 @@ export type SelectInputProps = export const SelectInput = Component(({ field, queryField, options, children, placeholder, createNewForm }) => { const [open, setOpen] = React.useState(false) + const id = useFormFieldId() return (