@contember/react-select 1.3.0-alpha.14
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.
- package/dist/development/components/MultiSelect.cjs +33 -0
- package/dist/development/components/MultiSelect.cjs.map +1 -0
- package/dist/development/components/MultiSelect.js +33 -0
- package/dist/development/components/MultiSelect.js.map +1 -0
- package/dist/development/components/Select.cjs +31 -0
- package/dist/development/components/Select.cjs.map +1 -0
- package/dist/development/components/Select.js +31 -0
- package/dist/development/components/Select.js.map +1 -0
- package/dist/development/components/SelectDataView.cjs +12 -0
- package/dist/development/components/SelectDataView.cjs.map +1 -0
- package/dist/development/components/SelectDataView.js +12 -0
- package/dist/development/components/SelectDataView.js.map +1 -0
- package/dist/development/components/SelectEachItem.cjs +11 -0
- package/dist/development/components/SelectEachItem.cjs.map +1 -0
- package/dist/development/components/SelectEachItem.js +11 -0
- package/dist/development/components/SelectEachItem.js.map +1 -0
- package/dist/development/components/SelectItemTrigger.cjs +17 -0
- package/dist/development/components/SelectItemTrigger.cjs.map +1 -0
- package/dist/development/components/SelectItemTrigger.js +17 -0
- package/dist/development/components/SelectItemTrigger.js.map +1 -0
- package/dist/development/components/SelectNewItem.cjs +40 -0
- package/dist/development/components/SelectNewItem.cjs.map +1 -0
- package/dist/development/components/SelectNewItem.js +40 -0
- package/dist/development/components/SelectNewItem.js.map +1 -0
- package/dist/development/components/SelectOption.cjs +22 -0
- package/dist/development/components/SelectOption.cjs.map +1 -0
- package/dist/development/components/SelectOption.js +22 -0
- package/dist/development/components/SelectOption.js.map +1 -0
- package/dist/development/components/SelectPlaceholder.cjs +10 -0
- package/dist/development/components/SelectPlaceholder.cjs.map +1 -0
- package/dist/development/components/SelectPlaceholder.js +10 -0
- package/dist/development/components/SelectPlaceholder.js.map +1 -0
- package/dist/development/components/SortableMultiSelect.cjs +36 -0
- package/dist/development/components/SortableMultiSelect.cjs.map +1 -0
- package/dist/development/components/SortableMultiSelect.js +36 -0
- package/dist/development/components/SortableMultiSelect.js.map +1 -0
- package/dist/development/contexts.cjs +24 -0
- package/dist/development/contexts.cjs.map +1 -0
- package/dist/development/contexts.js +24 -0
- package/dist/development/contexts.js.map +1 -0
- package/dist/development/index.cjs +30 -0
- package/dist/development/index.cjs.map +1 -0
- package/dist/development/index.js +30 -0
- package/dist/development/index.js.map +1 -0
- package/dist/production/components/MultiSelect.cjs +33 -0
- package/dist/production/components/MultiSelect.cjs.map +1 -0
- package/dist/production/components/MultiSelect.js +33 -0
- package/dist/production/components/MultiSelect.js.map +1 -0
- package/dist/production/components/Select.cjs +31 -0
- package/dist/production/components/Select.cjs.map +1 -0
- package/dist/production/components/Select.js +31 -0
- package/dist/production/components/Select.js.map +1 -0
- package/dist/production/components/SelectDataView.cjs +12 -0
- package/dist/production/components/SelectDataView.cjs.map +1 -0
- package/dist/production/components/SelectDataView.js +12 -0
- package/dist/production/components/SelectDataView.js.map +1 -0
- package/dist/production/components/SelectEachItem.cjs +11 -0
- package/dist/production/components/SelectEachItem.cjs.map +1 -0
- package/dist/production/components/SelectEachItem.js +11 -0
- package/dist/production/components/SelectEachItem.js.map +1 -0
- package/dist/production/components/SelectItemTrigger.cjs +17 -0
- package/dist/production/components/SelectItemTrigger.cjs.map +1 -0
- package/dist/production/components/SelectItemTrigger.js +17 -0
- package/dist/production/components/SelectItemTrigger.js.map +1 -0
- package/dist/production/components/SelectNewItem.cjs +40 -0
- package/dist/production/components/SelectNewItem.cjs.map +1 -0
- package/dist/production/components/SelectNewItem.js +40 -0
- package/dist/production/components/SelectNewItem.js.map +1 -0
- package/dist/production/components/SelectOption.cjs +22 -0
- package/dist/production/components/SelectOption.cjs.map +1 -0
- package/dist/production/components/SelectOption.js +22 -0
- package/dist/production/components/SelectOption.js.map +1 -0
- package/dist/production/components/SelectPlaceholder.cjs +10 -0
- package/dist/production/components/SelectPlaceholder.cjs.map +1 -0
- package/dist/production/components/SelectPlaceholder.js +10 -0
- package/dist/production/components/SelectPlaceholder.js.map +1 -0
- package/dist/production/components/SortableMultiSelect.cjs +36 -0
- package/dist/production/components/SortableMultiSelect.cjs.map +1 -0
- package/dist/production/components/SortableMultiSelect.js +36 -0
- package/dist/production/components/SortableMultiSelect.js.map +1 -0
- package/dist/production/contexts.cjs +24 -0
- package/dist/production/contexts.cjs.map +1 -0
- package/dist/production/contexts.js +24 -0
- package/dist/production/contexts.js.map +1 -0
- package/dist/production/index.cjs +30 -0
- package/dist/production/index.cjs.map +1 -0
- package/dist/production/index.js +30 -0
- package/dist/production/index.js.map +1 -0
- package/dist/types/components/MultiSelect.d.ts +14 -0
- package/dist/types/components/MultiSelect.d.ts.map +1 -0
- package/dist/types/components/Select.d.ts +14 -0
- package/dist/types/components/Select.d.ts.map +1 -0
- package/dist/types/components/SelectDataView.d.ts +7 -0
- package/dist/types/components/SelectDataView.d.ts.map +1 -0
- package/dist/types/components/SelectEachItem.d.ts +5 -0
- package/dist/types/components/SelectEachItem.d.ts.map +1 -0
- package/dist/types/components/SelectItemTrigger.d.ts +7 -0
- package/dist/types/components/SelectItemTrigger.d.ts.map +1 -0
- package/dist/types/components/SelectNewItem.d.ts +5 -0
- package/dist/types/components/SelectNewItem.d.ts.map +1 -0
- package/dist/types/components/SelectOption.d.ts +7 -0
- package/dist/types/components/SelectOption.d.ts.map +1 -0
- package/dist/types/components/SelectPlaceholder.d.ts +5 -0
- package/dist/types/components/SelectPlaceholder.d.ts.map +1 -0
- package/dist/types/components/SortableMultiSelect.d.ts +18 -0
- package/dist/types/components/SortableMultiSelect.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +10 -0
- package/dist/types/components/index.d.ts.map +1 -0
- package/dist/types/contexts.d.ts +15 -0
- package/dist/types/contexts.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dist/types/types/events.d.ts +6 -0
- package/dist/types/types/events.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/package.json +59 -0
- package/src/components/MultiSelect.tsx +55 -0
- package/src/components/Select.tsx +53 -0
- package/src/components/SelectDataView.tsx +17 -0
- package/src/components/SelectEachItem.tsx +13 -0
- package/src/components/SelectItemTrigger.tsx +19 -0
- package/src/components/SelectNewItem.tsx +54 -0
- package/src/components/SelectOption.tsx +22 -0
- package/src/components/SelectPlaceholder.tsx +7 -0
- package/src/components/SortableMultiSelect.tsx +65 -0
- package/src/components/index.ts +9 -0
- package/src/contexts.ts +25 -0
- package/src/index.ts +3 -0
- package/src/tsconfig.json +13 -0
- package/src/types/events.ts +6 -0
- package/src/types/index.ts +1 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Entity, EntityAccessor, EntitySubTree, QueryLanguage, TreeRootId, TreeRootIdProvider, useEnvironment, useExtendTree, useGetEntitySubTree } from '@contember/react-binding'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import { ReactNode, useEffect, useMemo, useState } from 'react'
|
|
4
|
+
import { useSelectOptions } from '../contexts'
|
|
5
|
+
|
|
6
|
+
export const SelectNewItem = ({ children }: { children: ReactNode }) => {
|
|
7
|
+
const options = useSelectOptions()
|
|
8
|
+
const env = useEnvironment()
|
|
9
|
+
const { entityName } = useMemo((() => QueryLanguage.desugarQualifiedEntityList({ entities: options }, env)), [env, options])
|
|
10
|
+
|
|
11
|
+
const [state, setState] = useState<{ entity: EntityAccessor, treeRootId: TreeRootId } | null>(null)
|
|
12
|
+
const extendTree = useExtendTree()
|
|
13
|
+
const getSubTree = useGetEntitySubTree()
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
(async () => {
|
|
17
|
+
const treeRootId = await extendTree(<>
|
|
18
|
+
<EntitySubTree entity={{
|
|
19
|
+
entityName,
|
|
20
|
+
}} expectedMutation={'none'} isUnpersisted isCreating>
|
|
21
|
+
{children}
|
|
22
|
+
</EntitySubTree>
|
|
23
|
+
</>)
|
|
24
|
+
if (!treeRootId) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const entity = getSubTree({
|
|
29
|
+
entity: {
|
|
30
|
+
entityName: entityName,
|
|
31
|
+
},
|
|
32
|
+
isCreating: true,
|
|
33
|
+
}, treeRootId)
|
|
34
|
+
setState({
|
|
35
|
+
entity,
|
|
36
|
+
treeRootId,
|
|
37
|
+
})
|
|
38
|
+
})()
|
|
39
|
+
}, [children, entityName, extendTree, getSubTree])
|
|
40
|
+
|
|
41
|
+
if (!state) {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<>
|
|
47
|
+
<TreeRootIdProvider treeRootId={state.treeRootId}>
|
|
48
|
+
<Entity accessor={state.entity}>
|
|
49
|
+
{children}
|
|
50
|
+
</Entity>
|
|
51
|
+
</TreeRootIdProvider>
|
|
52
|
+
</>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { forwardRef, ReactNode } from 'react'
|
|
2
|
+
import { useSelectIsSelected } from '../contexts'
|
|
3
|
+
import { Slot } from '@radix-ui/react-slot'
|
|
4
|
+
import { useEntity } from '@contember/react-binding'
|
|
5
|
+
import { dataAttribute } from '@contember/utilities'
|
|
6
|
+
|
|
7
|
+
export type SelectOptionProps = {
|
|
8
|
+
children: ReactNode
|
|
9
|
+
action?: 'select' | 'unselect' | 'toggle'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const SelectOption = forwardRef<HTMLElement, SelectOptionProps>(({ action, ...props }, ref) => {
|
|
13
|
+
const isSelected = useSelectIsSelected()
|
|
14
|
+
const entity = useEntity()
|
|
15
|
+
return (
|
|
16
|
+
<Slot
|
|
17
|
+
ref={ref}
|
|
18
|
+
data-selected={dataAttribute(isSelected?.(entity))}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
)
|
|
22
|
+
})
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react'
|
|
2
|
+
import { useSelectCurrentEntities } from '../contexts'
|
|
3
|
+
|
|
4
|
+
export const SelectPlaceholder = ({ children }: { children: ReactNode }) => {
|
|
5
|
+
const hasEntities = useSelectCurrentEntities().length > 0
|
|
6
|
+
return hasEntities ? null : <>{children}</>
|
|
7
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React, { ReactNode, useCallback, useMemo } from 'react'
|
|
2
|
+
import { SelectCurrentEntitiesContext, SelectHandler, SelectHandleSelectContext, SelectIsSelectedContext, SelectOptionsContext } from '../contexts'
|
|
3
|
+
import { Component, EntityAccessor, HasOne, SugaredQualifiedEntityList, SugaredRelativeEntityList, SugaredRelativeSingleEntity, SugaredRelativeSingleField, useEntityList } from '@contember/react-binding'
|
|
4
|
+
import { useReferentiallyStableCallback } from '@contember/react-utils'
|
|
5
|
+
import { Repeater } from '@contember/react-repeater'
|
|
6
|
+
import { SelectEvents } from '../types'
|
|
7
|
+
|
|
8
|
+
export type SortableMultiSelectProps =
|
|
9
|
+
& {
|
|
10
|
+
children: ReactNode
|
|
11
|
+
field: SugaredRelativeEntityList['field']
|
|
12
|
+
options: SugaredQualifiedEntityList['entities']
|
|
13
|
+
sortableBy: SugaredRelativeSingleField['field']
|
|
14
|
+
connectAt: SugaredRelativeSingleEntity['field']
|
|
15
|
+
}
|
|
16
|
+
& SelectEvents
|
|
17
|
+
|
|
18
|
+
export const SortableMultiSelect = Component(({ field, children, sortableBy, connectAt, options, onSelect, onUnselect }: SortableMultiSelectProps) => {
|
|
19
|
+
const list = useEntityList({ field })
|
|
20
|
+
const entitiesArr = useMemo(() => Array.from(list), [list])
|
|
21
|
+
|
|
22
|
+
const selectedEntities = useMemo(() => Array.from(list).map(it => it.getEntity({ field: connectAt }).id), [connectAt, list])
|
|
23
|
+
|
|
24
|
+
const handler = useReferentiallyStableCallback<SelectHandler>((entity, action = 'toggle') => {
|
|
25
|
+
const isSelected = selectedEntities.includes(entity.id)
|
|
26
|
+
if (action === 'toggle') {
|
|
27
|
+
action = isSelected ? 'unselect' : 'select'
|
|
28
|
+
}
|
|
29
|
+
if (action === 'unselect' && isSelected) {
|
|
30
|
+
Array.from(list).find(it => it.getEntity({ field: connectAt }).id === entity.id)?.deleteEntity()
|
|
31
|
+
onUnselect?.(entity)
|
|
32
|
+
} else if (action === 'select' && !isSelected) {
|
|
33
|
+
list.createNewEntity(getEntity => {
|
|
34
|
+
getEntity().connectEntityAtField({ field: connectAt }, entity)
|
|
35
|
+
onSelect?.(entity)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
const isSelected = useCallback((entity: EntityAccessor) => {
|
|
40
|
+
return selectedEntities.includes(entity.id)
|
|
41
|
+
}, [selectedEntities])
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Repeater field={field} sortableBy={sortableBy} initialEntityCount={0}>
|
|
45
|
+
<SelectCurrentEntitiesContext.Provider value={entitiesArr}>
|
|
46
|
+
<SelectIsSelectedContext.Provider value={isSelected}>
|
|
47
|
+
<SelectHandleSelectContext.Provider value={handler}>
|
|
48
|
+
<SelectOptionsContext.Provider value={options}>
|
|
49
|
+
{children}
|
|
50
|
+
</SelectOptionsContext.Provider>
|
|
51
|
+
</SelectHandleSelectContext.Provider>
|
|
52
|
+
</SelectIsSelectedContext.Provider>
|
|
53
|
+
</SelectCurrentEntitiesContext.Provider>
|
|
54
|
+
</Repeater>
|
|
55
|
+
)
|
|
56
|
+
}, ({ children, field, sortableBy, connectAt }) => {
|
|
57
|
+
return (
|
|
58
|
+
<Repeater field={field} sortableBy={sortableBy} initialEntityCount={0}>
|
|
59
|
+
<HasOne field={connectAt}>
|
|
60
|
+
{children}
|
|
61
|
+
</HasOne>
|
|
62
|
+
</Repeater>
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './MultiSelect'
|
|
2
|
+
export * from './Select'
|
|
3
|
+
export * from './SelectNewItem'
|
|
4
|
+
export * from './SelectDataView'
|
|
5
|
+
export * from './SelectEachItem'
|
|
6
|
+
export * from './SelectItemTrigger'
|
|
7
|
+
export * from './SelectOption'
|
|
8
|
+
export * from './SelectPlaceholder'
|
|
9
|
+
export * from './SortableMultiSelect'
|
package/src/contexts.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createRequiredContext } from '@contember/react-utils'
|
|
2
|
+
import { EntityAccessor, SugaredQualifiedEntityList } from '@contember/react-binding'
|
|
3
|
+
|
|
4
|
+
const _SelectCurrentEntitiesContext = createRequiredContext<EntityAccessor[]>('SelectCurrentEntitiesContext')
|
|
5
|
+
/** @internal */
|
|
6
|
+
export const SelectCurrentEntitiesContext = _SelectCurrentEntitiesContext[0]
|
|
7
|
+
export const useSelectCurrentEntities = _SelectCurrentEntitiesContext[1]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const _SelectIsSelectedContext = createRequiredContext<(entity: EntityAccessor) => boolean>('SelectIsSelectedContext')
|
|
12
|
+
/** @internal */
|
|
13
|
+
export const SelectIsSelectedContext = _SelectIsSelectedContext[0]
|
|
14
|
+
export const useSelectIsSelected = _SelectIsSelectedContext[1]
|
|
15
|
+
|
|
16
|
+
export type SelectHandler = (entity: EntityAccessor, action?: 'select' | 'unselect' | 'toggle') => void
|
|
17
|
+
const _SelectHandleSelectContext = createRequiredContext<SelectHandler>('SelectHandleSelectContext')
|
|
18
|
+
/** @internal */
|
|
19
|
+
export const SelectHandleSelectContext = _SelectHandleSelectContext[0]
|
|
20
|
+
export const useSelectHandleSelect = _SelectHandleSelectContext[1]
|
|
21
|
+
|
|
22
|
+
const _SelectOptionsContext = createRequiredContext<SugaredQualifiedEntityList['entities']>('SelectOptionsContext')
|
|
23
|
+
/** @internal */
|
|
24
|
+
export const SelectOptionsContext = _SelectOptionsContext[0]
|
|
25
|
+
export const useSelectOptions = _SelectOptionsContext[1]
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.settings.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../dist/types"
|
|
5
|
+
},
|
|
6
|
+
"references": [
|
|
7
|
+
{ "path": "../../react-binding/src" },
|
|
8
|
+
{ "path": "../../react-dataview/src" },
|
|
9
|
+
{ "path": "../../react-repeater/src" },
|
|
10
|
+
{ "path": "../../react-utils/src" },
|
|
11
|
+
{ "path": "../../utilities/src" },
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './events'
|