- added spreadsheet form element;
This commit is contained in:
84
src/components/FormField/components/Spreadsheet/index.js
Normal file
84
src/components/FormField/components/Spreadsheet/index.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets';
|
||||
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core';
|
||||
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US';
|
||||
import '@univerjs/preset-sheets-core/lib/index.css';
|
||||
|
||||
const parseWorkbook = (val) => {
|
||||
if (!val) return null;
|
||||
if (typeof val === 'object' && val.sheets) return val;
|
||||
if (typeof val === 'string') {
|
||||
try {
|
||||
const parsed = JSON.parse(val);
|
||||
return parsed && parsed.sheets ? parsed : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const Spreadsheet = ({ fieldName, defaultValue, setDataFn, template }) => {
|
||||
const containerRef = useRef(null);
|
||||
const univerRef = useRef(null);
|
||||
const univerAPIRef = useRef(null);
|
||||
const saveTimerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
const { univer, univerAPI } = createUniver({
|
||||
locale: LocaleType.EN_US,
|
||||
locales: {
|
||||
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
|
||||
},
|
||||
presets: [
|
||||
UniverSheetsCorePreset({
|
||||
container: containerRef.current,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
univerRef.current = univer;
|
||||
univerAPIRef.current = univerAPI;
|
||||
|
||||
const initialData = parseWorkbook(defaultValue) || parseWorkbook(template) || { name: 'Sheet' };
|
||||
univerAPI.createWorkbook(initialData);
|
||||
|
||||
univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, () => {
|
||||
clearTimeout(saveTimerRef.current);
|
||||
saveTimerRef.current = setTimeout(() => {
|
||||
const wb = univerAPIRef.current?.getActiveWorkbook();
|
||||
if (wb) {
|
||||
setDataFn(fieldName, wb.save());
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
|
||||
return () => {
|
||||
clearTimeout(saveTimerRef.current);
|
||||
if (univerRef.current) {
|
||||
univerRef.current.dispose();
|
||||
univerRef.current = null;
|
||||
univerAPIRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
useEffect(() => {
|
||||
const el = containerRef.current;
|
||||
if (!el) return;
|
||||
const handler = (e) => { e.stopPropagation(); e.preventDefault(); };
|
||||
el.addEventListener('wheel', handler, { passive: false });
|
||||
return () => el.removeEventListener('wheel', handler);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{ width: '100%', height: '500px' }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Spreadsheet;
|
||||
@@ -19,6 +19,7 @@ import Table from './components/Table';
|
||||
import PasswordField from './components/PasswordField';
|
||||
import CriteriaTable from './components/CriteriaTable';
|
||||
import FileSelect from './components/FileSelect';
|
||||
import Spreadsheet from './components/Spreadsheet';
|
||||
|
||||
const FormField = (props) => {
|
||||
const fields = {
|
||||
@@ -38,6 +39,7 @@ const FormField = (props) => {
|
||||
criteria_table: CriteriaTable,
|
||||
password: PasswordField,
|
||||
fileselect: FileSelect,
|
||||
spreadsheet: Spreadsheet,
|
||||
}
|
||||
const Comp = !isNil(fields[props.type]) ? fields[props.type] : null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user