@sanity/orderable-document-list 1.5.1 → 2.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/helpers/constants.ts","../src/helpers/parseOrderRank.ts","../src/helpers/initialRank.ts","../src/fields/orderRankField.ts","../src/fields/orderRankOrdering.ts","../src/OrderableContext.ts","../src/Document.tsx","../src/helpers/client.ts","../src/helpers/reorderDocuments.ts","../src/DraggableList.tsx","../src/helpers/getFilteredDedupedDocs.ts","../src/helpers/query.ts","../src/DocumentListQuery.tsx","../src/DocumentListWrapper.tsx","../src/helpers/resetOrder.ts","../src/OrderableDocumentList.tsx","../src/desk-structure/orderableDocumentListDeskItem.ts"],"sourcesContent":["export const ORDER_FIELD_NAME = `orderRank` as const\n\n// same version we are using in the vision plugin\nexport const API_VERSION = `v2025-06-27` as const\n","import {LexoRank} from 'lexorank'\n\n// Safely parse a LexoRank string; fall back if invalid\nexport function parseOrderRank(value: unknown, fallback: LexoRank): LexoRank {\n if (typeof value !== 'string') {\n console.warn('[orderable-document-list] Invalid orderRank value (expected string):', value)\n return fallback\n }\n\n try {\n return LexoRank.parse(value)\n } catch (err) {\n console.warn(\n '[orderable-document-list] Failed to parse orderRank value:',\n value,\n 'Error:',\n err instanceof Error ? err.message : String(err),\n )\n return fallback\n }\n}\n","import {LexoRank} from 'lexorank'\n\nimport type {NewItemPosition} from '../types'\nimport {parseOrderRank} from './parseOrderRank'\n\n// Use in initial value field by passing in the rank value of the last document\n// If not value passed, generate a sensibly low rank\nexport function initialRank(\n compareRankValue: unknown = ``,\n newItemPosition: NewItemPosition = 'after',\n) {\n const compareRank = parseOrderRank(compareRankValue, LexoRank.min())\n const rank =\n newItemPosition === 'before' ? compareRank.genPrev().genPrev() : compareRank.genNext().genNext()\n\n return rank.toString()\n}\n","import {defineField, type FieldDefinition, type StringDefinition} from 'sanity'\n\nimport {API_VERSION, ORDER_FIELD_NAME} from '../helpers/constants'\nimport {initialRank} from '../helpers/initialRank'\nimport type {NewItemPosition} from '../types'\n\nexport interface RankFieldConfig extends Partial<\n Omit<StringDefinition, 'name' | 'type' | 'initialValue'>\n> {\n type: string\n newItemPosition?: NewItemPosition\n}\n\nexport const orderRankField = (config: RankFieldConfig): FieldDefinition<'string'> => {\n if (!config?.type) {\n throw new Error(\n `\n type must be provided.\n Example: orderRankField({type: 'category'})\n `,\n )\n }\n\n const {type, newItemPosition = 'after', ...rest} = config\n return defineField({\n title: 'Order Rank',\n readOnly: true,\n hidden: true,\n ...rest,\n name: ORDER_FIELD_NAME,\n type: 'string',\n initialValue: async (value, {getClient}) => {\n void value\n const direction = newItemPosition === 'before' ? 'asc' : 'desc'\n\n const lastDocOrderRank = await getClient({apiVersion: API_VERSION}).fetch<string | undefined>(\n `*[_type == $type]|order(@[$order] ${direction})[0][$order]`,\n {type, order: ORDER_FIELD_NAME},\n {tag: 'orderable-document-list.last-doc-order-rank'},\n )\n return initialRank(lastDocOrderRank, newItemPosition)\n },\n })\n}\n","import type {SortOrdering} from 'sanity'\n\nimport {ORDER_FIELD_NAME} from '../helpers/constants'\n\nexport const orderRankOrdering: SortOrdering = {\n title: 'Ordered',\n name: 'ordered',\n by: [{field: ORDER_FIELD_NAME, direction: 'asc'}],\n}\n","import {createContext} from 'react'\n\nexport interface OrderableContextValue {\n showIncrements?: boolean\n}\n\nexport const OrderableContext = createContext<OrderableContextValue>({})\n","import {ChevronDownIcon, ChevronUpIcon, DragHandleIcon} from '@sanity/icons'\nimport {AvatarCounter, Card, Box, Button, Flex, Text, Tooltip} from '@sanity/ui'\nimport {useContext, useMemo, type ReactNode} from 'react'\nimport {\n useSchema,\n PreviewCard,\n Preview,\n DocumentStatusIndicator,\n DocumentStatus,\n useDocumentVersionInfo,\n} from 'sanity'\nimport {usePaneRouter} from 'sanity/structure'\n\nimport {OrderableContext} from './OrderableContext'\nimport type {SanityDocumentWithOrder} from './types'\n\nexport interface DocumentProps {\n doc: SanityDocumentWithOrder\n entities: SanityDocumentWithOrder[]\n increment: (\n index: number,\n nextIndex: number,\n docId: string,\n entities: SanityDocumentWithOrder[],\n ) => void\n index: number\n isFirst: boolean\n isLast: boolean\n dragBadge: number | false\n}\n\nexport function Document({\n doc,\n increment,\n entities,\n index,\n isFirst,\n isLast,\n dragBadge,\n}: DocumentProps) {\n const {showIncrements} = useContext(OrderableContext)\n const schema = useSchema()\n const router = usePaneRouter()\n const versionsInfo = useDocumentVersionInfo(doc._id)\n\n const {ChildLink, groupIndex, routerPanesState} = router\n\n const currentDoc = routerPanesState[groupIndex + 1]?.[0]?.id || false\n const pressed = currentDoc === doc._id || currentDoc === doc._id.replace(`drafts.`, ``)\n const selected = pressed && routerPanesState.length === groupIndex + 2\n const schemaType = schema.get(doc._type)\n\n const Link = useMemo(\n () =>\n function LinkComponent(linkProps: {children: ReactNode}) {\n return <ChildLink {...linkProps} childId={doc._id} />\n },\n [ChildLink, doc._id],\n )\n\n if (!schemaType) {\n return null\n }\n\n const tooltip = (\n <DocumentStatus\n draft={versionsInfo.draft}\n published={versionsInfo.published}\n versions={versionsInfo.versions}\n />\n )\n\n return (\n <PreviewCard\n __unstable_focusRing\n // @ts-expect-error PreviewCard's polymorphic `as` prop does not accept ChildLink's type.\n as={Link}\n data-as=\"a\"\n data-ui=\"PaneItem\"\n radius={2}\n pressed={pressed}\n selected={selected}\n sizing=\"border\"\n tabIndex={-1}\n tone=\"inherit\"\n width=\"100%\"\n flex={1}\n >\n <Flex align=\"center\">\n <Box paddingX={2} style={{flexShrink: 0}}>\n <Text size={2}>\n <DragHandleIcon cursor=\"grab\" />\n </Text>\n </Box>\n {showIncrements && (\n <Flex style={{flexShrink: 0}} align=\"center\" gap={1} paddingRight={1}>\n <Button\n padding={2}\n mode=\"ghost\"\n onClick={() => increment(index, index - 1, doc._id, entities)}\n disabled={isFirst}\n icon={ChevronUpIcon}\n />\n <Button\n padding={2}\n mode=\"ghost\"\n disabled={isLast}\n onClick={() => increment(index, index + 1, doc._id, entities)}\n icon={ChevronDownIcon}\n />\n </Flex>\n )}\n <Box style={{width: `100%`}}>\n <Flex flex={1} align=\"center\" justify=\"space-between\" paddingRight={3}>\n <Preview layout=\"default\" value={doc} schemaType={schemaType} />\n\n <Tooltip content={tooltip} portal placement=\"right\" boundaryElement={null}>\n <Flex align=\"center\" style={{flexShrink: 0}}>\n <DocumentStatusIndicator\n draft={versionsInfo.draft}\n published={versionsInfo.published}\n versions={versionsInfo.versions}\n />\n </Flex>\n </Tooltip>\n </Flex>\n </Box>\n {dragBadge && (\n <Card tone=\"default\" marginRight={4} radius={5}>\n <AvatarCounter count={dragBadge} />\n </Card>\n )}\n </Flex>\n </PreviewCard>\n )\n}\n","import {type SanityClient, useClient, usePerspective} from 'sanity'\n\nimport {API_VERSION} from './constants'\n\nexport function useSanityClient(): SanityClient {\n const {perspectiveStack} = usePerspective()\n\n return useClient({apiVersion: API_VERSION}).withConfig({perspective: perspectiveStack})\n}\n","import type {DraggableLocation} from '@hello-pangea/dnd'\nimport {LexoRank} from 'lexorank'\nimport type {PatchOperations} from 'sanity'\n\nimport type {SanityDocumentWithOrder} from '../types'\nimport {ORDER_FIELD_NAME} from './constants'\nimport {parseOrderRank} from './parseOrderRank'\n\nexport interface ReorderArgs {\n entities: SanityDocumentWithOrder[]\n selectedIds: string[]\n source: DraggableLocation\n destination: DraggableLocation\n}\n\nexport interface ReorderReturn {\n newOrder: SanityDocumentWithOrder[]\n patches: [string, PatchOperations][]\n message: string\n}\n\nfunction lexicographicalSort(a: SanityDocumentWithOrder, b: SanityDocumentWithOrder) {\n if (!a[ORDER_FIELD_NAME] || !b[ORDER_FIELD_NAME]) {\n return 0\n } else if (a[ORDER_FIELD_NAME] < b[ORDER_FIELD_NAME]) {\n return -1\n } else if (a[ORDER_FIELD_NAME] > b[ORDER_FIELD_NAME]) {\n return 1\n }\n return 0\n}\n\nexport const reorderDocuments = ({\n entities,\n selectedIds,\n source,\n destination,\n}: ReorderArgs): ReorderReturn => {\n const startIndex = source.index\n const endIndex = destination.index\n const isMovingUp = startIndex > endIndex\n const selectedItems = entities.filter((item) => selectedIds.includes(item._id))\n const message = [\n 'Moved',\n selectedItems.length === 1 ? '1 document' : `${selectedItems.length} documents`,\n isMovingUp ? 'up' : 'down',\n 'from position',\n `${startIndex + 1} to ${endIndex + 1}`,\n ].join(' ')\n\n const {all, selected} = entities.reduce<{\n all: SanityDocumentWithOrder[]\n selected: SanityDocumentWithOrder[]\n }>(\n (acc, cur, curIndex) => {\n // Selected items get spread in below, so skip them here\n if (selectedIds.includes(cur._id)) {\n return {all: acc.all, selected: acc.selected}\n }\n\n // Drop selected items in\n if (curIndex === endIndex) {\n const prevIndex = curIndex - 1\n const prevRank = parseOrderRank(entities[prevIndex]?.[ORDER_FIELD_NAME], LexoRank.min())\n const curRank = parseOrderRank(cur[ORDER_FIELD_NAME], LexoRank.min())\n const nextIndex = curIndex + 1\n const nextRank = parseOrderRank(entities[nextIndex]?.[ORDER_FIELD_NAME], LexoRank.max())\n\n let betweenRank = isMovingUp ? prevRank.between(curRank) : curRank.between(nextRank)\n\n // For each selected item, assign a new orderRank between now and next\n for (const selectedItem of selectedItems) {\n selectedItem[ORDER_FIELD_NAME] = betweenRank.toString()\n betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank)\n }\n\n return {\n // The `all` array gets sorted by order field later anyway\n // so that this probably isn't necessary ¯\\_(ツ)_/¯\n all: isMovingUp\n ? [...acc.all, ...selectedItems, cur]\n : [...acc.all, cur, ...selectedItems],\n selected: selectedItems,\n }\n }\n\n return {all: [...acc.all, cur], selected: acc.selected}\n },\n {all: [], selected: []},\n )\n\n const patches = selected.flatMap((doc) => {\n const docPatches: [string, PatchOperations][] = [\n [\n doc._id,\n {\n set: {\n [ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME],\n },\n },\n ],\n ]\n\n // If it's a draft, we need to patch the published document as well\n if (doc._id.startsWith('drafts.') && doc.hasPublished) {\n docPatches.push([\n doc._id.replace('drafts.', ''),\n {\n set: {\n [ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME],\n },\n },\n ])\n }\n\n return docPatches\n })\n\n // Safety-check to make sure everything is in order\n const allSorted = all.sort(lexicographicalSort)\n\n return {newOrder: allSorted, patches, message}\n}\n","import {\n DragDropContext,\n Draggable,\n Droppable,\n type DropResult,\n type DraggableLocation,\n} from '@hello-pangea/dnd'\nimport {Box, Card, useToast} from '@sanity/ui'\nimport {useEffect, useState, useMemo, useCallback, type CSSProperties} from 'react'\nimport type {PatchOperations} from 'sanity'\nimport {usePaneRouter} from 'sanity/structure'\n\nimport {Document} from './Document'\nimport {useSanityClient} from './helpers/client'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\nimport {reorderDocuments} from './helpers/reorderDocuments'\nimport type {SanityDocumentWithOrder} from './types'\n\ninterface ListSetting {\n isDuplicate: boolean\n isGhosting: boolean\n isDragging: boolean\n isSelected: boolean\n}\n\ninterface DragResultLike {\n draggableId: string\n source: DraggableLocation\n destination: DraggableLocation | null\n}\n\nexport interface DraggableListProps {\n data: SanityDocumentWithOrder[]\n listIsUpdating: boolean\n setListIsUpdating: (val: boolean) => void\n}\n\nconst getItemStyle = (\n draggableStyle: CSSProperties | undefined,\n itemIsUpdating: boolean,\n): CSSProperties => ({\n userSelect: 'none',\n transition: 'opacity 500ms ease-in-out',\n opacity: itemIsUpdating ? 0.2 : 1,\n pointerEvents: itemIsUpdating ? 'none' : undefined,\n ...draggableStyle,\n})\n\nconst cardTone = (settings: ListSetting) => {\n const {isDuplicate, isGhosting, isDragging, isSelected} = settings\n\n if (isGhosting) return 'transparent'\n if (isDragging || isSelected) return 'primary'\n if (isDuplicate) return 'caution'\n\n return undefined\n}\n\nexport function DraggableList({data, listIsUpdating, setListIsUpdating}: DraggableListProps) {\n const toast = useToast()\n const router = usePaneRouter()\n const {groupIndex, routerPanesState} = router\n\n const currentDoc = routerPanesState[groupIndex + 1]?.[0]?.id || false\n\n // Maintains local state order before transaction completes\n const [orderedData, setOrderedData] = useState<SanityDocumentWithOrder[]>(data)\n const displayedData = listIsUpdating ? orderedData : data\n\n const [draggingId, setDraggingId] = useState('')\n const [selectedIds, setSelectedIds] = useState<string[]>(currentDoc ? [currentDoc] : [])\n\n const clearSelected = useCallback(() => setSelectedIds([]), [setSelectedIds])\n\n const handleSelect = useCallback(\n (clickedId: string, index: number, nativeEvent: MouseEvent) => {\n const isSelected = selectedIds.includes(clickedId)\n const selectMultiple = nativeEvent.shiftKey\n const isUsingWindows = navigator.appVersion.indexOf('Win') !== -1\n const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey\n\n let updatedIds: string[] = []\n\n // No modifier keys pressed during click:\n // - update selected to just this one\n // - open document\n if (!selectMultiple && !selectAdditional) {\n return setSelectedIds([clickedId])\n }\n\n // If shift key was held, prevent default to avoid new window opening\n if (selectMultiple) {\n nativeEvent.preventDefault()\n }\n\n // Shift key was held, add id's between last selected and this one\n // ...before adding this one\n if (selectMultiple && !isSelected) {\n const lastSelectedId = selectedIds[selectedIds.length - 1] ?? clickedId\n const lastSelectedIndex = displayedData.findIndex((item) => item._id === lastSelectedId)\n\n const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex\n const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex\n\n const betweenIds = displayedData\n .filter((_, itemIndex) => itemIndex > firstSelected && itemIndex < lastSelected)\n .map((item) => item._id)\n\n updatedIds = [...selectedIds, ...betweenIds, clickedId]\n } else if (isSelected) {\n // Toggle off a single id\n updatedIds = selectedIds.filter((id) => id !== clickedId)\n } else {\n // Toggle on a single id\n updatedIds = [...selectedIds, clickedId]\n }\n\n return setSelectedIds(updatedIds)\n },\n [displayedData, selectedIds],\n )\n\n const client = useSanityClient()\n\n const transactPatches = useCallback(\n async (patches: [string, PatchOperations][], message: string) => {\n const transaction = client.transaction()\n\n patches.forEach(([docId, ops]) => {\n transaction.patch(docId, ops)\n })\n\n try {\n const updated = await transaction.commit({\n visibility: 'sync',\n tag: 'orderable-document-list.reorder',\n })\n clearSelected()\n setDraggingId('')\n setListIsUpdating(false)\n toast.push({\n title: `${\n updated.results.length === 1 ? '1 document' : `${updated.results.length} documents`\n } reordered`,\n status: 'success',\n description: message,\n })\n } catch {\n setDraggingId('')\n setListIsUpdating(false)\n toast.push({\n title: 'Reordering failed',\n status: 'error',\n })\n }\n },\n [client, clearSelected, setListIsUpdating, toast],\n )\n\n const handleDragEnd = useCallback(\n (result: DragResultLike | undefined, entities: SanityDocumentWithOrder[]) => {\n setDraggingId('')\n\n const {source, destination, draggableId} = result ?? {}\n\n // Don't do anything if nothing changed\n if (source?.index === destination?.index) return\n\n // Don't do anything if we don't have the entitites\n if (!entities.length || !draggableId || !source || !destination) return\n\n // A document can be dragged without being one-of-many-selected\n const effectedIds = selectedIds.length > 0 ? selectedIds : [draggableId]\n\n // Don't do anything if we don't have ids to effect\n if (effectedIds.length === 0) return\n\n // Update state to update styles + prevent data refetching\n setListIsUpdating(true)\n setSelectedIds(effectedIds)\n\n const {newOrder, patches, message} = reorderDocuments({\n entities,\n selectedIds: effectedIds,\n source,\n destination,\n })\n\n // Update local state\n if (newOrder.length > 0) {\n setOrderedData(newOrder)\n }\n\n // Transact new order patches\n if (patches.length > 0) {\n void transactPatches(patches, message)\n }\n },\n [selectedIds, transactPatches, setListIsUpdating],\n )\n\n const handleDragStart = useCallback(\n (start: {draggableId: string}) => {\n const id = start.draggableId\n const selected = selectedIds.includes(id)\n\n // if dragging an item that is not selected - unselect all items\n if (!selected) clearSelected()\n\n setDraggingId(id)\n },\n [selectedIds, clearSelected],\n )\n\n // Move one document up or down one place, by fake invoking the drag function\n const incrementIndex = useCallback(\n (shiftFrom: number, shiftTo: number, id: string, entities: SanityDocumentWithOrder[]) => {\n const result: DragResultLike = {\n draggableId: id,\n source: {droppableId: 'documentSortZone', index: shiftFrom},\n destination: {droppableId: 'documentSortZone', index: shiftTo},\n }\n\n return handleDragEnd(result, entities)\n },\n [handleDragEnd],\n )\n\n const onWindowKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n clearSelected()\n }\n },\n [clearSelected],\n )\n\n useEffect(() => {\n window.addEventListener('keydown', onWindowKeyDown)\n\n return () => {\n window.removeEventListener('keydown', onWindowKeyDown)\n }\n }, [onWindowKeyDown])\n\n // Find all items with duplicate order field\n const duplicateOrders = useMemo(() => {\n if (displayedData.length === 0) return []\n\n const orderField = displayedData.map((item) => item[ORDER_FIELD_NAME])\n\n return orderField.filter((item, index) => orderField.indexOf(item) !== index)\n }, [displayedData])\n\n const onDragEnd = useCallback(\n (result: DropResult) => handleDragEnd(result, displayedData),\n [displayedData, handleDragEnd],\n )\n\n return (\n <DragDropContext onDragStart={handleDragStart} onDragEnd={onDragEnd}>\n <Droppable droppableId=\"documentSortZone\">\n {(provided) => (\n <div {...provided.droppableProps} ref={provided.innerRef}>\n {displayedData.map((item, index) => (\n <Draggable\n key={`${item._id}-${item[ORDER_FIELD_NAME]}`}\n draggableId={item._id}\n index={index}\n >\n {(innerProvided, innerSnapshot) => {\n const isSelected = selectedIds.includes(item._id)\n const isDragging = innerSnapshot.isDragging\n const isGhosting = Boolean(!isDragging && draggingId && isSelected)\n const isUpdating = listIsUpdating && isSelected\n const isDisabled = !item[ORDER_FIELD_NAME]\n const isDuplicate = duplicateOrders.includes(item[ORDER_FIELD_NAME])\n const tone = cardTone({isDuplicate, isGhosting, isDragging, isSelected})\n const selectedCount = selectedIds.length\n\n const dragBadge = isDragging && selectedCount > 1 ? selectedCount : false\n\n return (\n <div\n ref={innerProvided.innerRef}\n {...innerProvided.draggableProps}\n {...innerProvided.dragHandleProps}\n style={\n isDisabled\n ? {opacity: 0.2, pointerEvents: 'none'}\n : getItemStyle(innerProvided.draggableProps.style, isUpdating)\n }\n >\n <Box paddingBottom={1}>\n <Card\n tone={tone}\n shadow={isDragging ? 2 : undefined}\n radius={2}\n onClick={(e) => handleSelect(item._id, index, e.nativeEvent)}\n >\n <Document\n doc={item}\n entities={displayedData}\n increment={incrementIndex}\n index={index}\n isFirst={index === 0}\n isLast={index === displayedData.length - 1}\n dragBadge={dragBadge}\n />\n </Card>\n </Box>\n </div>\n )\n }}\n </Draggable>\n ))}\n {provided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n )\n}\n","import {getPublishedId, getVersionFromId, isDraftId, isPublishedId, isVersionId} from 'sanity'\n\nimport type {SanityDocumentWithOrder} from '../types'\n\nconst isVersionForCurrentPerspective = (\n document: SanityDocumentWithOrder,\n perspectiveName: string,\n publishedId: string,\n) => {\n return (\n document._id &&\n isVersionId(document._id) &&\n getVersionFromId(document._id) === perspectiveName &&\n getPublishedId(document._id) === publishedId\n )\n}\n\n// this removes dedupped docs from the list and makes sure that it keeps the right docs\n// in the list while preserving the order established by the orderRank field\nexport const getFilteredDedupedDocs = (\n documents: SanityDocumentWithOrder[],\n perspectiveName?: string,\n): SanityDocumentWithOrder[] => {\n // Flatten the documents array in case it's nested (like in test data)\n const flatDocuments = documents.flat()\n const dedupedDocuments: SanityDocumentWithOrder[] = []\n\n for (const cur of flatDocuments) {\n if (!cur._id) {\n continue\n }\n\n // Handle version-only documents\n if (isVersionId(cur._id)) {\n const versionFromId = getVersionFromId(cur._id)\n const isCorrectVersion = versionFromId === perspectiveName\n\n // Only include versions that match the current perspective\n if (\n perspectiveName &&\n perspectiveName !== 'drafts' &&\n perspectiveName !== 'published' &&\n isCorrectVersion\n ) {\n dedupedDocuments.push(cur)\n }\n continue\n }\n\n // Handle published perspective - only include published documents\n if (perspectiveName === 'published') {\n if (isPublishedId(cur._id)) {\n dedupedDocuments.push(cur)\n }\n continue\n }\n\n // in situations where the document is not a draft, we need to check if\n // the version should override a published document or a draft\n if (!isDraftId(cur._id)) {\n const publishedId = getPublishedId(cur._id)\n\n // Check if there's a version that matches the perspectiveName\n const hasMatchingVersion =\n perspectiveName && perspectiveName !== 'drafts' && perspectiveName !== 'published'\n ? flatDocuments.some((doc) =>\n isVersionForCurrentPerspective(doc, perspectiveName, publishedId),\n )\n : false\n\n // Check if there's a draft\n const hasDraft = flatDocuments.some((doc) => doc._id === `drafts.${cur._id}`)\n const hasDuplicatePublished = flatDocuments.some((doc) => doc !== cur && doc._id === cur._id)\n\n // Priority: version > draft > published\n // If there's a matching version, skip published\n if (!hasMatchingVersion && !hasDraft && !hasDuplicatePublished) {\n dedupedDocuments.push(cur)\n }\n continue\n }\n\n // For drafts, check if there's a version for this document in version perspective\n if (perspectiveName && perspectiveName !== 'drafts' && perspectiveName !== 'published') {\n const baseId = getPublishedId(cur._id)\n const hasVersion = flatDocuments.some((doc) =>\n isVersionForCurrentPerspective(doc, perspectiveName, baseId),\n )\n\n // If there's a version for this document, skip the draft\n if (hasVersion) {\n continue\n }\n }\n\n // Check if the draft has a published version\n cur.hasPublished = flatDocuments.some((doc) => doc._id === cur._id.replace(`drafts.`, ``))\n\n dedupedDocuments.push(cur)\n }\n\n return dedupedDocuments\n}\n","import {ORDER_FIELD_NAME} from './constants'\n\nexport interface DocumentListQueryProps {\n type: string\n filter?: string\n params?: Record<string, unknown>\n currentVersion?: string\n}\n\nexport interface DocumentListQueryResult {\n query: string\n queryParams: Record<string, string | number | boolean | string[]>\n}\n\nconst DEFAULT_PARAMS = {}\n\nexport function getDocumentQuery({\n type,\n filter,\n params = DEFAULT_PARAMS,\n currentVersion,\n}: DocumentListQueryProps): DocumentListQueryResult {\n let perspectiveFilter = null\n if (currentVersion === 'published') {\n perspectiveFilter = '!(_id in path(\"drafts.**\")) && !(_id in path(\"versions.**\"))'\n } else if (currentVersion === 'drafts') {\n // Show drafts, and published when no draft exists\n perspectiveFilter = `\n (_id in path(\"drafts.**\") || (!(_id in path(\"drafts.**\")) && !(_id in path(\"versions.**\"))))\n `\n } else {\n // Default behavior: prioritize drafts over published when both exist\n // the priority should be a version\n perspectiveFilter = `(sanity::partOfRelease($currentVersion) || (!(_id in path(\"drafts.**\")) && !(_id in path(\"versions.**\"))) || (_id in path(\"drafts.**\")))`\n }\n\n const querySelect = `*[_type == $type ${perspectiveFilter ? `&& ${perspectiveFilter}` : ''}${filter ? `&& ${filter}` : ''}]`\n const queryOrder = `|order(@[$order] asc)`\n const queryFields = `{_id, _type, ${ORDER_FIELD_NAME}}`\n\n const query = `${querySelect}${queryOrder}${queryFields}`\n const queryParams = {\n ...params,\n type,\n order: ORDER_FIELD_NAME,\n ...(currentVersion && {currentVersion}),\n }\n\n return {query, queryParams}\n}\n","import {Box, Flex, Container, Spinner, Stack, Text} from '@sanity/ui'\nimport {useMemo, useState} from 'react'\nimport {useListeningQuery, Feedback} from 'sanity-plugin-utils'\n\nimport {DraggableList} from './DraggableList'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\nimport {getFilteredDedupedDocs} from './helpers/getFilteredDedupedDocs'\nimport {getDocumentQuery, type DocumentListQueryProps} from './helpers/query'\nimport type {SanityDocumentWithOrder} from './types'\n\nexport function DocumentListQuery(props: DocumentListQueryProps) {\n const [listIsUpdating, setListIsUpdating] = useState(false)\n\n const {query, queryParams} = getDocumentQuery(props)\n\n const {\n data: _queryData,\n loading,\n error,\n } = useListeningQuery<SanityDocumentWithOrder[]>(query, {\n params: queryParams,\n initialValue: [],\n })\n\n const queryData = useMemo(() => (Array.isArray(_queryData) ? _queryData : []), [_queryData])\n\n const data = useMemo(\n () => getFilteredDedupedDocs(queryData, props.currentVersion),\n [props.currentVersion, queryData],\n )\n\n const unorderedDataCount = useMemo(\n () => data.filter((doc) => !doc[ORDER_FIELD_NAME]).length,\n [data],\n )\n\n if (loading) {\n return (\n <Flex style={{width: `100%`, height: `100%`}} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )\n }\n\n if (error) {\n return (\n <Box padding={2}>\n <Feedback tone=\"critical\" title=\"There was an error\" description=\"Please try again later\" />\n </Box>\n )\n }\n\n if (data.length === 0) {\n return (\n <Flex align=\"center\" direction=\"column\" height=\"fill\" justify=\"center\">\n <Container width={1}>\n <Box paddingX={4} paddingY={5}>\n <Text align=\"center\" muted>\n No documents of this type\n </Text>\n </Box>\n </Container>\n </Flex>\n )\n }\n\n return (\n <Stack gap={1} style={{overflow: `auto`, height: `100%`}}>\n <Box padding={2}>\n {unorderedDataCount > 0 && (\n <Box marginBottom={2}>\n <Feedback\n tone=\"caution\"\n description={\n <>\n {unorderedDataCount}/{data.length} documents have no order. Select{' '}\n <strong>Reset Order</strong> from the menu above to fix.\n </>\n }\n />\n </Box>\n )}\n <DraggableList\n data={data}\n listIsUpdating={listIsUpdating}\n setListIsUpdating={setListIsUpdating}\n />\n </Box>\n </Stack>\n )\n}\n","import {useToast, Box, type ToastParams} from '@sanity/ui'\nimport {useEffect, useMemo} from 'react'\nimport {useSchema} from 'sanity'\nimport {Feedback} from 'sanity-plugin-utils'\n\nimport {DocumentListQuery} from './DocumentListQuery'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\nimport {OrderableContext} from './OrderableContext'\n\nexport interface DocumentListWrapperProps {\n showIncrements: boolean\n type: string\n resetOrderTransaction: ToastParams\n filter?: string\n params?: Record<string, unknown>\n currentVersion?: string\n}\n\n// 1. Validate first that the schema has been configured for ordering\n// 2. Setup context for showIncrements\nexport function DocumentListWrapper({\n type,\n showIncrements,\n resetOrderTransaction,\n filter,\n params,\n currentVersion,\n}: DocumentListWrapperProps) {\n const toast = useToast()\n const schema = useSchema()\n const orderableContextValue = useMemo(() => ({showIncrements}), [showIncrements])\n\n useEffect(() => {\n if (resetOrderTransaction?.title && resetOrderTransaction?.status) {\n toast.push(resetOrderTransaction)\n }\n }, [resetOrderTransaction, toast])\n\n const schemaIsInvalid = useMemo(() => {\n // Option not passed\n if (!type) {\n return (\n <>\n No <code>type</code> was configured\n </>\n )\n }\n\n const typeSchema = schema.get(type)\n\n // Schema not found\n if (!typeSchema) {\n return (\n <>\n Schema <code>{type}</code> not found\n </>\n )\n }\n\n // Schema lacks an order field\n if (\n !('fields' in typeSchema) ||\n !typeSchema.fields.some((field) => field?.name === ORDER_FIELD_NAME)\n ) {\n return (\n <>\n Schema <code>{type}</code> must have an <code>{ORDER_FIELD_NAME}</code> field of type{' '}\n <code>string</code>\n </>\n )\n }\n\n // Schema's order field is not a string\n if (\n 'fields' in typeSchema &&\n typeSchema.fields.some(\n (field) => field?.name === ORDER_FIELD_NAME && field?.type?.name !== 'string',\n )\n ) {\n return (\n <>\n <code>{ORDER_FIELD_NAME}</code> field on Schema <code>{type}</code> must be{' '}\n <code>string</code> type\n </>\n )\n }\n\n return ''\n }, [type, schema])\n\n if (schemaIsInvalid) {\n return (\n <Box padding={2}>\n <Feedback description={schemaIsInvalid} tone=\"caution\" />\n </Box>\n )\n }\n\n return (\n <OrderableContext.Provider value={orderableContextValue}>\n <DocumentListQuery\n type={type}\n filter={filter}\n params={params}\n currentVersion={currentVersion}\n />\n </OrderableContext.Provider>\n )\n}\n","import type {MultipleMutationResult, SanityClient} from '@sanity/client'\nimport {LexoRank} from 'lexorank'\n\nimport {ORDER_FIELD_NAME} from './constants'\nimport {getDocumentQuery, type DocumentListQueryProps} from './query'\n\nexport interface ResetOrderParams extends DocumentListQueryProps {\n client: SanityClient\n currentVersion?: string\n}\n\n// Function to wipe and re-do ordering with LexoRank\n// Will at least attempt to start with the current order\nexport async function resetOrder(params: ResetOrderParams): Promise<MultipleMutationResult | null> {\n const {client, currentVersion, ...queryProps} = params\n const {query, queryParams} = getDocumentQuery({...queryProps, currentVersion})\n\n const documents = await client.fetch<\n Array<{\n _id: string\n _type: string\n [ORDER_FIELD_NAME]: string\n }>\n >(query, queryParams, {\n tag: 'orderable-document-list.reset-order',\n })\n\n if (documents.length === 0) {\n return null\n }\n\n let aLexoRank = LexoRank.min()\n\n const transaction = documents\n .map((doc) => doc._id)\n .reduce((trx, documentId) => {\n // Generate next rank before even the first document so there's room to move!\n aLexoRank = aLexoRank.genNext().genNext()\n\n return trx.patch(documentId, {\n set: {[ORDER_FIELD_NAME]: aLexoRank.toString()},\n })\n }, client.transaction())\n\n return transaction.commit({\n visibility: 'async',\n tag: 'orderable-document-list.reset-order',\n })\n}\n","import type {SanityClient} from '@sanity/client'\nimport type {ToastParams} from '@sanity/ui'\nimport {Component} from 'react'\n\nimport {DocumentListWrapper} from './DocumentListWrapper'\nimport {resetOrder} from './helpers/resetOrder'\n\nexport interface OrderableDocumentListProps {\n options: {\n type: string\n client: SanityClient\n filter?: string\n params?: Record<string, unknown>\n currentVersion?: string\n }\n}\n\ninterface State {\n showIncrements: boolean\n resetOrderTransaction: ToastParams\n}\n\n// Must use a Class Component here so the actionHandlers can be called\nexport class OrderableDocumentList extends Component<OrderableDocumentListProps, State> {\n constructor(props: OrderableDocumentListProps) {\n super(props)\n this.state = {\n showIncrements: false,\n resetOrderTransaction: {},\n }\n }\n\n actionHandlers = {\n showIncrements: () => {\n this.setState((state) => ({\n showIncrements: !state.showIncrements,\n }))\n },\n\n resetOrder: async () => {\n this.setState(() => ({\n resetOrderTransaction: {\n status: `info`,\n title: `Reordering started...`,\n closable: true,\n },\n }))\n\n const update = await resetOrder(this.props.options)\n\n const reorderWasSuccessful = update?.results?.length\n\n this.setState(() => ({\n resetOrderTransaction: {\n status: reorderWasSuccessful ? `success` : `info`,\n title: reorderWasSuccessful\n ? `Reordered ${update.results.length === 1 ? `Document` : `Documents`}`\n : `Reordering failed`,\n closable: true,\n },\n }))\n },\n }\n\n override render() {\n const {options} = this.props\n const {type, filter, params, currentVersion} = options\n\n if (!type) {\n return null\n }\n\n return (\n <DocumentListWrapper\n filter={filter}\n params={params}\n type={type}\n showIncrements={this.state.showIncrements}\n resetOrderTransaction={this.state.resetOrderTransaction}\n currentVersion={currentVersion}\n />\n )\n }\n}\n","import {GenerateIcon, SortIcon} from '@sanity/icons'\nimport {type ComponentType} from 'react'\nimport type {ConfigContext} from 'sanity'\nimport {type ListItem, type MenuItem, type StructureBuilder} from 'sanity/structure'\n\nimport {API_VERSION} from '../helpers/constants'\nimport {OrderableDocumentList} from '../OrderableDocumentList'\n\nexport interface OrderableListConfig {\n type: string\n id?: string\n title?: string\n icon?: ComponentType\n params?: Record<string, unknown>\n filter?: string\n menuItems?: MenuItem[]\n createIntent?: boolean\n context: ConfigContext\n S: StructureBuilder\n}\n\nexport function orderableDocumentListDeskItem(config: OrderableListConfig): ListItem {\n if (!config?.type || !config.context || !config.S) {\n throw new Error(`\n type, context and S (StructureBuilder) must be provided.\n context and S are available when configuring structure.\n Example: orderableDocumentListDeskItem({type: 'category'})\n `)\n }\n\n const {type, filter, menuItems = [], createIntent, params, title, icon, id, context, S} = config\n const {schema, getClient} = context\n const maybePerspectiveStack: unknown = Reflect.get(context, 'perspectiveStack')\n const perspectiveStack =\n Array.isArray(maybePerspectiveStack) &&\n maybePerspectiveStack.every((item): item is string => typeof item === 'string')\n ? maybePerspectiveStack\n : []\n const client = getClient({apiVersion: API_VERSION})\n // the first position in the perspective stack is the current version\n const currentVersion = perspectiveStack[0]\n\n const listTitle = title ?? `Orderable ${type}`\n const listId = id ?? `orderable-${type}`\n const listIcon = icon ?? SortIcon\n const typeTitle = schema.get(type)?.title ?? type\n const defaultMenuItems = [...menuItems]\n\n if (createIntent !== false) {\n defaultMenuItems.push(\n S.menuItem()\n .title(`Create new ${typeTitle}`)\n .intent({type: 'create', params: {type}})\n .serialize(),\n )\n }\n\n return S.listItem()\n .title(listTitle)\n .id(listId)\n .icon(listIcon)\n .schemaType(type)\n .child(\n Object.assign(\n S.documentTypeList(type)\n .canHandleIntent(() => createIntent !== false)\n .serialize(),\n {\n // Prevents the component from re-rendering when switching documents\n __preserveInstance: true,\n // Prevents the component from NOT re-rendering when switching listItems\n key: listId,\n\n type: 'component',\n component: OrderableDocumentList,\n options: {type, filter, params, client, currentVersion},\n menuItems: [\n ...defaultMenuItems,\n S.menuItem().title(`Reset Order`).icon(GenerateIcon).action(`resetOrder`).serialize(),\n S.menuItem()\n .title(`Toggle Increments`)\n .icon(SortIcon)\n .action(`showIncrements`)\n .serialize(),\n ],\n },\n ),\n )\n .serialize()\n}\n"],"names":["ORDER_FIELD_NAME","API_VERSION","parseOrderRank","value","fallback","console","warn","LexoRank","parse","err","Error","message","String","initialRank","compareRankValue","newItemPosition","compareRank","min","genPrev","genNext","toString","orderRankField","config","type","rest","defineField","title","readOnly","hidden","name","initialValue","getClient","direction","lastDocOrderRank","apiVersion","fetch","order","tag","orderRankOrdering","by","field","OrderableContext","createContext","Document","t0","$","_c","doc","increment","entities","index","isFirst","isLast","dragBadge","showIncrements","useContext","schema","useSchema","router","usePaneRouter","versionsInfo","useDocumentVersionInfo","_id","ChildLink","groupIndex","routerPanesState","currentDoc","id","t1","replace","pressed","selected","length","t2","_type","get","schemaType","t3","linkProps","Link","t4","draft","published","versions","tooltip","t5","for","flexShrink","t6","Symbol","t7","ChevronUpIcon","ChevronDownIcon","t8","width","t9","t10","t11","t12","t13","t14","t15","t16","useSanityClient","perspectiveStack","usePerspective","useClient","withConfig","perspective","lexicographicalSort","a","b","reorderDocuments","selectedIds","source","destination","startIndex","endIndex","isMovingUp","selectedItems","filter","item","includes","join","all","reduce","acc","cur","curIndex","prevIndex","prevRank","curRank","nextIndex","nextRank","max","betweenRank","between","selectedItem","patches","flatMap","docPatches","set","startsWith","hasPublished","push","newOrder","sort","getItemStyle","draggableStyle","itemIsUpdating","userSelect","transition","opacity","pointerEvents","undefined","cardTone","settings","isDuplicate","isGhosting","isDragging","isSelected","DraggableList","data","listIsUpdating","setListIsUpdating","toast","useToast","orderedData","setOrderedData","useState","displayedData","draggingId","setDraggingId","setSelectedIds","clearSelected","useCallback","handleSelect","clickedId","nativeEvent","selectMultiple","shiftKey","selectAdditional","navigator","appVersion","indexOf","ctrlKey","metaKey","updatedIds","preventDefault","lastSelectedId","lastSelectedIndex","findIndex","firstSelected","lastSelected","betweenIds","_","itemIndex","map","client","transactPatches","transaction","forEach","docId","ops","patch","updated","commit","visibility","results","status","description","handleDragEnd","result","draggableId","effectedIds","handleDragStart","start","incrementIndex","shiftFrom","shiftTo","droppableId","onWindowKeyDown","event","key","useEffect","window","addEventListener","removeEventListener","duplicateOrders","useMemo","orderField","onDragEnd","provided","droppableProps","innerRef","innerProvided","innerSnapshot","Boolean","isUpdating","isDisabled","tone","selectedCount","draggableProps","dragHandleProps","style","e","placeholder","isVersionForCurrentPerspective","document","perspectiveName","publishedId","isVersionId","getVersionFromId","getPublishedId","getFilteredDedupedDocs","documents","flatDocuments","flat","dedupedDocuments","isCorrectVersion","isPublishedId","isDraftId","hasMatchingVersion","some","hasDraft","hasDuplicatePublished","baseId","DEFAULT_PARAMS","getDocumentQuery","params","currentVersion","perspectiveFilter","querySelect","queryOrder","queryFields","query","queryParams","DocumentListQuery","props","_queryData","loading","error","useListeningQuery","Array","isArray","queryData","_temp","unorderedDataCount","height","overflow","DocumentListWrapper","resetOrderTransaction","orderableContextValue","bb0","typeSchema","fields","_temp2","schemaIsInvalid","field_0","resetOrder","queryProps","aLexoRank","trx","documentId","OrderableDocumentList","Component","constructor","state","actionHandlers","setState","closable","update","options","reorderWasSuccessful","render","orderableDocumentListDeskItem","context","S","menuItems","createIntent","icon","maybePerspectiveStack","Reflect","every","listTitle","listId","listIcon","SortIcon","typeTitle","defaultMenuItems","menuItem","intent","serialize","listItem","child","Object","assign","documentTypeList","canHandleIntent","__preserveInstance","component","GenerateIcon","action"],"mappings":"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"}
package/package.json CHANGED
@@ -1,111 +1,61 @@
1
1
  {
2
2
  "name": "@sanity/orderable-document-list",
3
- "version": "1.5.1",
3
+ "version": "2.0.1",
4
4
  "description": "Drag-and-drop Document Ordering without leaving the Editing surface",
5
5
  "keywords": [
6
6
  "sanity",
7
7
  "sanity-plugin"
8
8
  ],
9
- "homepage": "https://github.com/sanity-io/orderable-document-list#readme",
9
+ "homepage": "https://github.com/sanity-io/plugins/tree/main/plugins/@sanity/orderable-document-list",
10
10
  "bugs": {
11
- "url": "https://github.com/sanity-io/orderable-document-list/issues"
11
+ "url": "https://github.com/sanity-io/plugins/issues"
12
12
  },
13
+ "license": "MIT",
14
+ "author": "Sanity.io <hello@sanity.io>",
13
15
  "repository": {
14
16
  "type": "git",
15
- "url": "git@github.com:sanity-io/orderable-document-list.git"
17
+ "url": "git+ssh://git@github.com/sanity-io/plugins.git",
18
+ "directory": "plugins/@sanity/orderable-document-list"
16
19
  },
17
- "license": "MIT",
18
- "author": "Sanity.io <hello@sanity.io>",
19
- "sideEffects": false,
20
+ "files": [
21
+ "dist"
22
+ ],
20
23
  "type": "module",
24
+ "types": "./dist/index.d.ts",
21
25
  "exports": {
22
- ".": {
23
- "source": "./src/index.ts",
24
- "import": "./lib/index.js",
25
- "require": "./lib/index.cjs",
26
- "default": "./lib/index.js"
27
- },
26
+ ".": "./dist/index.js",
28
27
  "./package.json": "./package.json"
29
28
  },
30
- "main": "./lib/index.cjs",
31
- "module": "./lib/index.js",
32
- "types": "./lib/index.d.ts",
33
- "files": [
34
- "lib",
35
- "sanity.json",
36
- "src",
37
- "v2-incompatible.js"
38
- ],
39
- "scripts": {
40
- "build": "plugin-kit verify-package --silent && pkg-utils build --strict --check --clean",
41
- "dev": "sanity dev",
42
- "clean": "rimraf lib",
43
- "compile": "tsc --noEmit",
44
- "format": "prettier --write --cache --ignore-unknown .",
45
- "link-watch": "plugin-kit link-watch",
46
- "lint": "eslint .",
47
- "lint:fix": "eslint . --fix",
48
- "prepare": "husky install",
49
- "prepublishOnly": "npm run build",
50
- "watch": "pkg-utils watch --strict",
51
- "test": "vitest"
52
- },
53
- "husky": {
54
- "hooks": {
55
- "pre-commit": "npm run lint:fix"
56
- }
57
- },
58
- "browserslist": "extends @sanity/browserslist-config",
59
29
  "dependencies": {
60
30
  "@hello-pangea/dnd": "^18.0.1",
31
+ "@sanity/client": "^7.22.1",
61
32
  "@sanity/icons": "^3.5.3",
62
- "@sanity/incompatible-plugin": "^1.0.5",
63
- "@sanity/ui": "^2.10.11",
33
+ "@sanity/ui": "^3.2.0",
64
34
  "lexorank": "^1.0.4",
65
- "sanity-plugin-utils": "^1.6.8"
35
+ "sanity-plugin-utils": "2.0.1"
66
36
  },
67
37
  "devDependencies": {
68
- "@commitlint/cli": "^19.6.1",
69
- "@commitlint/config-conventional": "^19.6.0",
70
- "@sanity/pkg-utils": "^6.12.0",
71
- "@sanity/plugin-kit": "^4.0.18",
72
- "@sanity/vision": "^4.1.0",
73
- "@sanity/semantic-release-preset": "^5.0.0",
74
- "@types/react": "^19",
75
- "@typescript-eslint/eslint-plugin": "^5.61.0",
76
- "@typescript-eslint/parser": "^5.61.0",
77
- "babel-eslint": "^10.1.0",
78
- "eslint": "^8.44.0",
79
- "eslint-config-prettier": "^8.8.0",
80
- "eslint-config-sanity": "^6.0.0",
81
- "eslint-plugin-prettier": "^5.2.1",
82
- "eslint-plugin-react": "^7.32.2",
83
- "eslint-plugin-react-hooks": "^4.6.0",
84
- "husky": "^8.0.3",
85
- "lint-staged": "^15.4.3",
86
- "prettier": "^3.4.2",
87
- "prettier-plugin-packagejson": "^2.5.6",
88
- "react": "^19",
89
- "react-dom": "19",
90
- "react-is": "^19",
91
- "rimraf": "^6.0.1",
92
- "sanity": "^4.1.0",
93
- "semantic-release": "^24.2.0",
94
- "styled-components": "^6.1.15",
95
- "typescript": "^5.1.6",
96
- "vitest": "^3.2.4"
38
+ "@sanity/pkg-utils": "^10.5.4",
39
+ "@types/react": "^19.2.14",
40
+ "@types/react-dom": "^19.2.3",
41
+ "babel-plugin-react-compiler": "^1.0.0",
42
+ "react": "^19.2.5",
43
+ "react-dom": "^19.2.5",
44
+ "sanity": "^6.0.0",
45
+ "styled-components": "^6.4.2",
46
+ "@repo/package.config": "0.0.0",
47
+ "@repo/tsconfig": "0.0.0"
97
48
  },
98
49
  "peerDependencies": {
99
- "react": "^18 || ^19",
100
- "react-dom": "^18 || ^19",
101
- "sanity": "^3.77.0 || ^4.0.0-0 || ^5.0.0",
50
+ "react": "^19.2",
51
+ "react-dom": "^19.2",
52
+ "sanity": "^5 || ^6.0.0-0",
102
53
  "styled-components": "^6.1"
103
54
  },
104
- "overrides": {
105
- "conventional-changelog-conventionalcommits": ">= 8.0.0"
106
- },
107
55
  "engines": {
108
- "node": ">=18"
56
+ "node": ">=20.19 <22 || >=22.12"
109
57
  },
110
- "sanityExchangeUrl": "https://www.sanity.io/plugins/orderable-document-list"
111
- }
58
+ "scripts": {
59
+ "build": "pkg build --strict --check --clean"
60
+ }
61
+ }
package/README.md DELETED
@@ -1,218 +0,0 @@
1
- # @sanity/orderable-document-list
2
-
3
- > For the v2 version, please refer to the [v2-branch](https://github.com/sanity-io/orderable-document-list/tree/studio-v2).
4
-
5
- # What is it?
6
-
7
- Drag-and-drop Document Ordering without leaving the Editing surface.
8
-
9
- ![2022-04-26 12 23 39](https://user-images.githubusercontent.com/9684022/165289621-dbd9d841-028e-40c7-be14-7398fcdb1210.gif)
10
-
11
- This plugin aims to be OS-like in that you can select and move multiple documents by holding `shift` and clicking a second item, and toggling on/off selections by holding `command/control`.
12
-
13
- ## Requirements
14
-
15
- A Sanity Studio with [Desk Structure](https://www.sanity.io/docs/structure-builder-introduction) configured:
16
-
17
- ```ts
18
- import {defineConfig} from 'sanity'
19
- import {structureTool, StructureBuilder} from 'sanity/structure'
20
-
21
- export default defineConfig({
22
- //...
23
- plugins: [
24
- structureTool({
25
- structure: (S, context) => {
26
- /* Structure code */
27
- },
28
- }),
29
- ],
30
- })
31
- ```
32
-
33
- ## Installation
34
-
35
- Run the following command in your studio directory
36
-
37
- ```sh
38
- npm install --save @sanity/orderable-document-list
39
- ```
40
-
41
- or
42
-
43
- ```sh
44
- yarn add @sanity/orderable-document-list
45
- ```
46
-
47
- ## Usage
48
-
49
- ### 1. Import the Document List into your Desk Structure
50
-
51
- The config parameter requires `type`, `S` and `context`. It also accepts `title`, `icon`, `filter` and `params`.
52
- `S` and `context` are available in desk-tool structure callback, and should be forwarded as is:
53
-
54
- ```ts
55
- import {defineConfig} from 'sanity'
56
- import {structureTool, StructureBuilder} from 'sanity/structure'
57
- import {orderableDocumentListDeskItem} from '@sanity/orderable-document-list'
58
-
59
- export default defineConfig({
60
- //...
61
- plugins: [
62
- structureTool({
63
- structure: (S, context) => {
64
- return S.list()
65
- .title('Content')
66
- .items([
67
- // Minimum required configuration
68
- orderableDocumentListDeskItem({type: 'category', S, context}),
69
-
70
- // Optional configuration
71
- orderableDocumentListDeskItem({
72
- type: 'project',
73
- title: 'Projects',
74
- icon: Paint,
75
- // Required if using multiple lists of the same 'type'
76
- id: 'orderable-en-projects',
77
- // See notes on adding a `filter` below
78
- filter: `__i18n_lang == $lang`,
79
- params: {
80
- lang: 'en_US',
81
- },
82
- createIntent: false, // do not add an option for item creation
83
- menuItems: [], // allow an array of `S.menuItem()` to be injected to orderable document list menu
84
- // pass from the structure callback params above
85
- S,
86
- context,
87
- }),
88
-
89
- // ... all other desk items, e.g. all other document types not already included
90
- // @see https://www.sanity.io/docs/studio/structure-builder-cheat-sheet#k4eb3b1891dc2
91
- ...S.documentTypeListItems().filter((item) => !(['category', 'project'].includes(item.getId())))
92
- ])
93
- },
94
- }),
95
- ],
96
- })
97
- ```
98
-
99
- **Caution: Adding a `filter`**
100
-
101
- By default, the plugin will display _all_ documents of the same `type`. However, you may wish to add a `filter` to reduce this down to a subset of documents. A typical usecase is for [internationalized document schema](https://github.com/sanity-io/document-internationalization) to order documents of just the base language version.
102
-
103
- However, order ranks are still computed based on _all_ documents of the same `type`. Creating multiple lists with different `filter` settings could produce unexpected results.
104
-
105
- ### 2. Add the `orderRank` field to your schema(s).
106
-
107
- You must pass in the `type` of the schema and the schema `context`, to create an `initialValue` value.
108
- Context is available in the schema callback, and should be forwarded as is.
109
-
110
- Additionally, pass in overrides for the field, such as making it visible by passing `hidden: false`.
111
-
112
- You cannot override the `name`, `type` or `initialValue` attributes.
113
-
114
- You can configure the placement of new documents by setting `newItemPosition` to `before` (defaults to `after`).
115
-
116
- ```js
117
- // sanity.config.js
118
- import {defineConfig} from "sanity";
119
- import {structureTool, StructureBuilder} from "sanity/structure";
120
- import {orderRankField, orderRankOrdering} from '@sanity/orderable-document-list'
121
-
122
- export default defineConfig({
123
- //...
124
- plugins: [
125
- structureTool({structure: (S, context) => {/* snip */}})
126
- ],
127
- schema: {
128
- types: (previousTypes) => {
129
- return [
130
- ...previousTypes,
131
- {
132
- name: "category",
133
- title: "Category",
134
- type: "document",
135
- // Optional: The plugin also exports a set of 'orderings' for use in other Document Lists
136
- // https://www.sanity.io/docs/sort-orders
137
- orderings: [orderRankOrdering],
138
- fields: [
139
- // Minimum required configuration
140
- orderRankField({ type: "category" }),
141
-
142
- // OR placing new documents on top
143
- orderRankField({ type: "category", newItemPosition: "before" }),
144
-
145
- // OR you can override _some_ of the field settings
146
- orderRankField({ type: "category", hidden: false }),
147
-
148
- // ...all other fields
149
- ],
150
- },
151
- ]
152
- }
153
- }
154
- }
155
- ```
156
-
157
- ### 3. Generate initial Ranks
158
-
159
- On first load, your Document list will not have any Order. You can select "Reset Order" from the menu in the top right of the list.
160
- You can also re-run this at any time.
161
-
162
- The `orderRankField` will query the last/first Document to set an `initialValue` to come after/before it.
163
- The placement of new documents can be configured by `newItemPosition` on the `orderRankField` in the document.
164
-
165
- ## Querying Ordered Documents
166
-
167
- Now when writing a GROQ Query for Documents, use the `orderRank` field value to return ordered results:
168
-
169
- ```groq
170
- *[_type == "category"]|order(orderRank)
171
- ```
172
-
173
- If fetching documents using [the `document-internationalization` plugin](https://github.com/sanity-io/document-internationalization), you may want to sort by the rank of the base document when the document is not in the base language, so all locales share the same order. When changing the order of documents using this plugin, the `orderRank` field of documents in alternate locales won't be updated. The query below ensures a consistent order for documents in the base language and in alternate languages.
174
-
175
- ```groq
176
- *[_type == "category" && __i18n_lang == $lang]|order(coalesce(__i18n_base->orderRank, orderRank))
177
- ```
178
-
179
- ## Notes
180
-
181
- To get this first version out the door there are few configuration settings and a lot of opinions. Such as:
182
-
183
- - The `name` of the `orderRank` field is constant
184
- - The ability to only sort across _all_ Documents of a `type`
185
-
186
- Feedback and PRs welcome :)
187
-
188
- ### Breaking change in the v3 version
189
-
190
- `orderableDocumentListDeskItem` requires context from sanity config now.
191
- See the examples above.
192
-
193
- ## How it works
194
-
195
- Uses [kvandakes](https://github.com/kvandake)'s [TypeScript implementation](https://github.com/kvandake/lexorank-ts) of [Jira's Lexorank](https://www.youtube.com/watch?v=OjQv9xMoFbg) to create a "lexographical" Document order.
196
-
197
- Put simply it updates the position of an individual – or many – Documents in an ordered list without updating any others. It's fast.
198
-
199
- ## Develop & test
200
-
201
- To run this plugin locally and develop, it uses the internal test studio used by the Development teams. You need to run install and npm run dev and you will have a clear and easy example to use.
202
-
203
- This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
204
- with default configuration for build & watch scripts.
205
-
206
- See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
207
- on how to run this plugin with hotreload in the studio.
208
-
209
- ### Release new version
210
-
211
- Run ["CI & Release" workflow](https://github.com/sanity-io/orderable-document-list/actions/workflows/main.yml).
212
- Make sure to select the v3 branch and check "Release new version".
213
-
214
- Semantic release will only release on configured branches, so it is safe to run release on any branch.
215
-
216
- ## License
217
-
218
- [MIT](LICENSE) © Sanity.io