import { Classes } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { useField, useStore } from '@tanstack/react-form'; import { useCallback, useMemo, useState } from 'react'; import { FaRegTrashAlt } from 'react-icons/fa'; import { Button, FieldGroupSVGTextStyleFields, TableDragRowHandler, createTableColumnHelper, withForm, } from 'react-science/ui'; import type { z } from 'zod'; import { useChartData } from '../../../../context/ChartContext.js'; import { getSpectraObjectPaths } from '../../../../utility/getSpectraObjectPaths.js'; import { CellActions, CellActionsButton, CellCheckbox, CellInput, TableSettings, } from '../ui/table.js'; import { TableSection } from '../ui/table_section.js'; import type { infoBlockFieldTabValidationWithUUID } from '../validation/title_block_tab_validation.js'; import { defaultGeneralSettingsFormValues } from '../validation.js'; export const TitleBlockTab = withForm({ defaultValues: defaultGeneralSettingsFormValues, render: ({ form }) => { const { Section, AppField } = form; return ( <>
{({ Checkbox }) => }
); }, }); type Field = z.input; function getEmptyField(): Field { return { label: '', format: '', jpath: '', visible: true, uuid: crypto.randomUUID(), }; } const TableFields = withForm({ defaultValues: defaultGeneralSettingsFormValues, render: function Fields({ form }) { const { Field } = form; const fields = useField({ form, name: 'infoBlock.fields', mode: 'array', }); const { removeValue, setValue, pushValue, name } = fields; const [autoFocus, setAutoFocus] = useState(''); function onAddField() { const value = getEmptyField(); pushValue(value, { dontRunListeners: true }); setAutoFocus(value.uuid); } const { data } = useChartData(); const { datalist } = useMemo(() => getSpectraObjectPaths(data), [data]); const onDeleteAt = useCallback( (index: number) => { removeValue(index); }, [removeValue], ); const columns = useMemo(() => { const columnHelper = createTableColumnHelper(); return [ columnHelper.display({ id: 'dnd', header: '', meta: { tdStyle: { textAlign: 'center' }, }, cell: () => , }), columnHelper.accessor('label', { header: () => 'Label', cell: ({ row: { index, original } }) => ( {(field) => ( { field.handleBlur(); setAutoFocus(''); }} intent={!field.state.meta.isValid ? 'danger' : undefined} /> )} ), }), columnHelper.accessor('jpath', { header: 'Field', cell: ({ row: { index } }) => ( {(field) => ( )} ), }), columnHelper.accessor('format', { header: 'Format', cell: ({ row: { index } }) => ( {(field) => ( )} ), }), columnHelper.accessor('visible', { header: 'Visible', meta: { tdStyle: { textAlign: 'center' }, }, cell: ({ row: { index } }) => ( {(field) => ( field.handleChange(e.currentTarget.checked)} /> )} ), }), columnHelper.display({ id: 'actions', header: '', meta: { thStyle: { width: '60px', }, }, cell: ({ row: { index } }) => { return ( onDeleteAt(index)} > ); }, }), ]; }, [Field, autoFocus, datalist, name, onDeleteAt]); const onRowOrderChanged = useCallback( (value: Field[]) => { setValue(value); }, [setValue], ); // It seems fields.setValue don't always trigger rerender // so fields.state.value can de-sync and cause weird behavior with DnD reorder. const fieldsData = useStore(fields.store, (s) => s.value); return ( Add Field } > ); }, }); function getRowId(row: Field) { return row.uuid; } const TableDragRowHandlerStyled = styled(TableDragRowHandler)` margin: 0 2px; `;