@sanity/table
Version:
Table schema type and input component for Sanity Studio
1 lines • 31.6 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../node_modules/@sanity/uuid/node_modules/uuid/dist/esm-browser/rng.js","../node_modules/@sanity/uuid/node_modules/uuid/dist/esm-browser/regex.js","../node_modules/@sanity/uuid/node_modules/uuid/dist/esm-browser/validate.js","../node_modules/@sanity/uuid/node_modules/uuid/dist/esm-browser/stringify.js","../node_modules/@sanity/uuid/node_modules/uuid/dist/esm-browser/v4.js","../src/components/TableInput.tsx","../src/components/TableMenu.tsx","../src/components/TableComponent.tsx","../src/components/TableIcon.tsx","../src/components/TablePreview.tsx","../src/index.ts"],"sourcesContent":["// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation. Also,\n // find the complete implementation of crypto (msCrypto) on IE11.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);\n\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n\n return getRandomValues(rnds8);\n}","export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;","import REGEX from './regex.js';\n\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\n\nexport default validate;","import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nvar byteToHex = [];\n\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).substr(1));\n}\n\nfunction stringify(arr) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;","import rng from './rng.js';\nimport stringify from './stringify.js';\n\nfunction v4(options, buf, offset) {\n options = options || {};\n var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return stringify(rnds);\n}\n\nexport default v4;","import { RemoveIcon } from '@sanity/icons';\nimport { Box, Button, TextInput } from '@sanity/ui';\nimport type { FormEvent } from 'react';\n\nimport type { TableRow } from './TableComponent';\n\ninterface TableInputProps {\n rows: TableRow[];\n updateCell: (\n e: FormEvent<HTMLInputElement>,\n rowIndex: number,\n cellIndex: number\n ) => void;\n removeRow: (index: number) => void;\n removeColumn: (index: number) => void;\n}\n\nexport const TableInput = (props: TableInputProps) => {\n const updateCell = props.updateCell;\n\n const renderRowCell = (rowIndex: number) =>\n function RowCell(cell: string, cellIndex: number) {\n return (\n <td key={`cell-${rowIndex}-${cellIndex}`}>\n <TextInput\n fontSize={1}\n padding={3}\n value={cell}\n onChange={e => updateCell(e, rowIndex, cellIndex)}\n />\n </td>\n );\n };\n\n const renderRow = (row: TableRow, rowIndex: number) => {\n const renderCell = renderRowCell(rowIndex);\n\n return (\n <tr key={`row-${rowIndex}`}>\n {row.cells.map(renderCell)}\n {\n <td key={rowIndex}>\n <Box marginLeft={1} style={{ textAlign: 'center' }}>\n <Button\n icon={RemoveIcon}\n padding={2}\n onClick={() => props.removeRow(rowIndex)}\n mode=\"bleed\"\n />\n </Box>\n </td>\n }\n </tr>\n );\n };\n\n return (\n <table style={{ width: '100%' }}>\n <tbody>\n {props.rows.map(renderRow)}\n <tr>\n {(props.rows[0]?.cells || []).map((_, i) => (\n <td key={i}>\n <Box marginTop={1} style={{ textAlign: 'center' }}>\n <Button\n icon={RemoveIcon}\n padding={2}\n onClick={() => props.removeColumn(i)}\n mode=\"bleed\"\n />\n </Box>\n </td>\n ))}\n </tr>\n </tbody>\n </table>\n );\n};\n","import { AddIcon, ControlsIcon, WarningOutlineIcon } from '@sanity/icons';\nimport {\n Box,\n Button,\n Card,\n Dialog,\n Inline,\n Menu,\n MenuButton,\n MenuDivider,\n MenuItem,\n Placement,\n TextInput,\n} from '@sanity/ui';\nimport { type FormEventHandler, useState } from 'react';\n\ninterface TableMenuProps {\n addColumns: (count: number) => void;\n addColumnAt: (index: number) => void;\n addRows: (count: number) => void;\n addRowAt: (index: number) => void;\n remove: () => void;\n placement: Placement;\n}\n\nexport const TableMenu = (props: TableMenuProps) => {\n const { remove: handleRemove } = props;\n const [dialog, setDialog] = useState<{\n type: string;\n callback: (count: number) => void;\n } | null>(null);\n\n const [count, setCount] = useState<string | undefined>('');\n\n const updateCount: FormEventHandler<HTMLInputElement> = e => {\n setCount(e.currentTarget.value);\n };\n\n const addRows = () => {\n setDialog({ type: 'rows', callback: c => props.addRows(c) });\n };\n\n const addRowAt = () => {\n setDialog({ type: 'rows', callback: index => props.addRowAt(index) });\n };\n\n const addColumns = () => {\n setDialog({\n type: 'columns',\n callback: c => props.addColumns(c),\n });\n };\n\n const addColumnsAt = () => {\n setDialog({ type: 'columns', callback: index => props.addColumnAt(index) });\n };\n\n const onConfirm = () => {\n const parsedCount = parseInt(count ?? '0', 10);\n\n if (parsedCount < 100) {\n setDialog(null);\n dialog?.callback(parsedCount);\n setCount(undefined);\n }\n };\n\n return (\n <>\n {dialog && (\n <Dialog\n header={`Add ${dialog.type}`}\n id=\"dialog-add\"\n onClose={() => setDialog(null)}\n zOffset={1000}\n >\n <Card padding={4}>\n <TextInput\n style={{ textAlign: 'left' }}\n fontSize={2}\n padding={3}\n type=\"number\"\n value={count}\n onChange={updateCount}\n />\n <Box marginTop={4}>\n <Inline space={1} style={{ textAlign: 'right' }}>\n <Button\n text=\"Cancel\"\n mode=\"ghost\"\n onClick={() => setDialog(null)}\n />\n <Button text=\"Confirm\" tone=\"critical\" onClick={onConfirm} />\n </Inline>\n </Box>\n </Card>\n </Dialog>\n )}\n <MenuButton\n button={\n <Button icon={ControlsIcon} fontSize={1} padding={2} mode=\"ghost\" />\n }\n id=\"menu-button-example\"\n menu={\n <Menu>\n <MenuItem\n icon={AddIcon}\n fontSize={1}\n text=\"Add Row(s)\"\n onClick={addRows}\n />\n <MenuItem\n icon={AddIcon}\n fontSize={1}\n text=\"Add Row At Index\"\n onClick={addRowAt}\n />\n <MenuItem\n icon={AddIcon}\n fontSize={1}\n text=\"Add Column(s)\"\n onClick={addColumns}\n />\n <MenuItem\n icon={AddIcon}\n fontSize={1}\n text=\"Add Column At Index\"\n onClick={addColumnsAt}\n />\n <MenuDivider />\n <MenuItem\n icon={WarningOutlineIcon}\n fontSize={1}\n text=\"Remove\"\n tone=\"critical\"\n onClick={handleRemove}\n />\n </Menu>\n }\n popover={{ placement: props.placement }}\n />\n </>\n );\n};\n","/* eslint-disable consistent-return */\nimport { AddIcon } from '@sanity/icons';\nimport { Box, Button, Card, Dialog, Flex, Inline, Text } from '@sanity/ui';\nimport { uuid } from '@sanity/uuid';\nimport { type FormEvent, useState } from 'react';\nimport { type ObjectInputProps, set, unset } from 'sanity';\n\nimport { TableInput } from './TableInput';\nimport { TableMenu } from './TableMenu';\n\nconst deepClone: <T>(data: T) => T =\n globalThis.structuredClone ?? (data => JSON.parse(JSON.stringify(data)));\n\nexport interface TableValue {\n _type: 'table';\n rows: TableRow[];\n}\n\nexport type TableProps = ObjectInputProps<TableValue>;\n\nexport type TableRow = {\n _type: string;\n _key: string;\n cells: string[];\n};\n\n// TODO refactor deeplone stuff to use proper patches\n// TODO use callback all the things\n\nexport const TableComponent = (props: TableProps & { rowType?: string }) => {\n const { rowType = 'tableRow', value, onChange } = props;\n const [dialog, setDialog] = useState<{\n type: string;\n callback: () => void;\n } | null>(null);\n\n const updateValue = (v?: Omit<TableValue, '_type'>) => {\n return onChange(set(v));\n };\n\n const resetValue = () => {\n return onChange(unset());\n };\n\n const createTable = () => {\n const newValue: Omit<TableValue, '_type'> = {\n rows: [\n {\n _type: rowType,\n _key: uuid(),\n cells: ['', ''],\n },\n {\n _type: rowType,\n _key: uuid(),\n cells: ['', ''],\n },\n ],\n };\n return updateValue({ ...value, ...newValue });\n };\n\n const confirmRemoveTable = () => {\n setDialog({ type: 'table', callback: removeTable });\n };\n\n const removeTable = () => {\n resetValue();\n setDialog(null);\n };\n\n const addRows = (count = 1) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n // Calculate the column count from the first row\n const columnCount = value?.rows[0].cells.length ?? 0;\n for (let i = 0; i < count; i++) {\n // Add as many cells as we have columns\n newValue.rows.push({\n _type: rowType,\n _key: uuid(),\n cells: Array(columnCount).fill(''),\n });\n }\n // eslint-disable-next-line consistent-return\n return updateValue(newValue);\n };\n\n const addRowAt = (index = 0) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n // Calculate the column count from the first row\n const columnCount = value.rows[0].cells.length;\n\n newValue.rows.splice(index, 0, {\n _type: rowType,\n _key: uuid(),\n cells: Array(columnCount).fill(''),\n });\n\n // eslint-disable-next-line consistent-return\n return updateValue(newValue);\n };\n\n const removeRow = (index: number) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n newValue.rows.splice(index, 1);\n updateValue(newValue);\n setDialog(null);\n };\n\n const confirmRemoveRow = (index: number) => {\n if (!value) {\n return;\n }\n if (value.rows.length <= 1) return confirmRemoveTable();\n return setDialog({ type: 'row', callback: () => removeRow(index) });\n };\n\n const confirmRemoveColumn = (index: number) => {\n if (!value) {\n return;\n }\n if (value.rows[0].cells.length <= 1) return confirmRemoveTable();\n return setDialog({ type: 'column', callback: () => removeColumn(index) });\n };\n\n const addColumns = (count: number) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n // Add a cell to each of the rows\n newValue.rows.forEach((_, i) => {\n for (let j = 0; j < count; j++) {\n newValue.rows[i].cells.push('');\n }\n });\n return updateValue(newValue);\n };\n\n const addColumnAt = (index: number) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n\n newValue.rows.forEach((_, i) => {\n newValue.rows[i].cells.splice(index, 0, '');\n });\n\n return updateValue(newValue);\n };\n\n const removeColumn = (index: number) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n newValue.rows.forEach(row => {\n row.cells.splice(index, 1);\n });\n updateValue(newValue);\n setDialog(null);\n };\n\n const updateCell = (\n e: FormEvent<HTMLInputElement>,\n rowIndex: number,\n cellIndex: number\n ) => {\n if (!value) {\n return;\n }\n const newValue = deepClone(value);\n newValue.rows[rowIndex].cells[cellIndex] = (\n e.target as HTMLInputElement\n ).value;\n return updateValue(newValue);\n };\n\n return (\n <div>\n {dialog && (\n <Dialog\n header={`Remove ${dialog.type}`}\n id=\"dialog-remove\"\n onClose={() => setDialog(null)}\n zOffset={1000}\n >\n <Card padding={4}>\n <Text>Are you sure you want to remove this {dialog.type}?</Text>\n <Box marginTop={4}>\n <Inline space={1} style={{ textAlign: 'right' }}>\n <Button\n text=\"Cancel\"\n mode=\"ghost\"\n onClick={() => setDialog(null)}\n />\n <Button\n text=\"Confirm\"\n tone=\"critical\"\n onClick={() => dialog.callback()}\n />\n </Inline>\n </Box>\n </Card>\n </Dialog>\n )}\n <Box>\n <Flex justify=\"flex-end\">\n {value?.rows?.length && (\n <TableMenu\n addColumns={addColumns}\n addColumnAt={addColumnAt}\n addRows={addRows}\n addRowAt={addRowAt}\n remove={confirmRemoveTable}\n placement=\"left\"\n />\n )}\n </Flex>\n </Box>\n {value?.rows?.length && (\n <TableInput\n rows={value.rows}\n removeRow={confirmRemoveRow}\n removeColumn={confirmRemoveColumn}\n updateCell={updateCell}\n />\n )}\n {(!value || !value?.rows?.length) && (\n <Inline space={1}>\n <Button\n fontSize={1}\n padding={3}\n icon={AddIcon}\n text=\"Create Table\"\n tone=\"primary\"\n mode=\"ghost\"\n onClick={createTable}\n />\n </Inline>\n )}\n </div>\n );\n};\n\nexport function createTableComponent(rowType: string) {\n return function Table(props: TableProps) {\n return <TableComponent {...props} rowType={rowType} />;\n };\n}\n","export function TableIcon() {\n return (\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n >\n <path d=\"M3 3h18v18H3zM21 9H3M21 15H3M12 3v18\" />\n </svg>\n );\n}\n","import { Box, Card, Grid, Inline, Label, Text } from '@sanity/ui';\nimport type { PreviewProps } from 'sanity';\n\nimport type { TableRow } from './TableComponent';\nimport { TableIcon } from './TableIcon';\n\ninterface ValueProps {\n rows?: TableRow[];\n title?: string;\n}\n\nconst Table = ({ rows }: { rows: TableRow[] }) => {\n const numCols = rows.length === 0 ? 0 : rows[0].cells.length;\n\n return (\n <Grid columns={numCols} padding={2}>\n {rows.map(row =>\n row.cells.map((cell, i) => (\n <Card\n key={row._key + i}\n padding={2}\n style={{ outline: '1px solid #DFE2E9' }}\n >\n <Text style={{ textOverflow: 'elipsis' }}>{cell}</Text>\n </Card>\n ))\n )}\n </Grid>\n );\n};\n\nexport const TablePreview = (props: ValueProps & PreviewProps) => {\n const { schemaType, rows = [], title = 'Title missing' } = props;\n\n return (\n <>\n <Box padding={3}>\n <Inline space={3}>\n <Card>\n <Label size={4}>\n <TableIcon />\n </Label>\n </Card>\n <Card>\n <Text>{schemaType?.title ?? title}</Text>\n </Card>\n </Inline>\n </Box>\n <Box padding={2}>\n {rows.length === 0 ? (\n <Label muted>Empty Table</Label>\n ) : (\n <Table rows={rows} />\n )}\n </Box>\n </>\n );\n};\n","import { definePlugin, defineType } from 'sanity';\n\nimport {\n createTableComponent,\n TableComponent,\n} from './components/TableComponent';\nimport { TablePreview } from './components/TablePreview';\nexport type {\n TableProps,\n TableRow,\n TableValue,\n} from './components/TableComponent';\n\nexport { TableComponent, TablePreview };\n\nexport interface TableConfig {\n rowType?: string;\n}\n\nexport const table = definePlugin<TableConfig | void>(config => {\n const tableRowSchema = defineType({\n title: 'Table Row',\n name: config?.rowType || 'tableRow',\n type: 'object',\n fields: [\n {\n name: 'cells',\n type: 'array',\n of: [{ type: 'string' }],\n },\n ],\n });\n\n const tableSchema = defineType({\n title: 'Table',\n name: 'table',\n type: 'object',\n fields: [\n {\n name: 'rows',\n type: 'array',\n of: [\n {\n type: tableRowSchema.name,\n },\n ],\n },\n ],\n components: {\n /* eslint-disable @typescript-eslint/no-explicit-any */\n input: createTableComponent(tableRowSchema.name) as any,\n preview: TablePreview as any,\n /* eslint-enable @typescript-eslint/no-explicit-any */\n },\n preview: {\n select: {\n rows: 'rows',\n title: 'title',\n },\n prepare: ({ title, rows = [] }) => ({\n title,\n rows,\n }),\n },\n });\n\n return {\n name: 'table',\n schema: {\n types: [tableRowSchema, tableSchema],\n },\n };\n});\n"],"names":["_a","jsx","TextInput","Box","Button","RemoveIcon","useState","jsxs","Fragment","Dialog","Card","Inline","MenuButton","ControlsIcon","Menu","MenuItem","AddIcon","MenuDivider","WarningOutlineIcon","set","unset","uuid","Text","Flex","Grid","Label","definePlugin","defineType"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}