refactor: @hera/plugin-core (#1081)
Reviewed-on: daoyoucloud/tachybase#1081
This commit is contained in:
parent
7092559ea0
commit
8fdd5d4fe9
@ -1,38 +1,34 @@
|
||||
import React, { ComponentType, ReactElement } from 'react';
|
||||
import { define, observable } from '@tachybase/schema';
|
||||
import { APIClientOptions, getSubAppName } from '@tachybase/sdk';
|
||||
|
||||
import { i18n as i18next } from 'i18next';
|
||||
import get from 'lodash/get';
|
||||
import merge from 'lodash/merge';
|
||||
import set from 'lodash/set';
|
||||
import React, { ComponentType, FC, ReactElement } from 'react';
|
||||
import { get, merge, set } from 'lodash';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { Link, NavLink, Navigate } from 'react-router-dom';
|
||||
import { Link, Navigate, NavLink } from 'react-router-dom';
|
||||
|
||||
import { APIClient, APIClientProvider } from '../api-client';
|
||||
import { CSSVariableProvider } from '../css-variable';
|
||||
import { CollectionField } from '../data-source/collection-field/CollectionField';
|
||||
import { DataSourceApplicationProvider } from '../data-source/components/DataSourceApplicationProvider';
|
||||
import { DataBlockProvider } from '../data-source/data-block/DataBlockProvider';
|
||||
import { DataSourceManager, type DataSourceManagerOptions } from '../data-source/data-source/DataSourceManager';
|
||||
import { AntdAppProvider, GlobalThemeProvider } from '../global-theme';
|
||||
import { i18n } from '../i18n';
|
||||
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
|
||||
import { AppComponent, BlankComponent, defaultAppComponents } from './components';
|
||||
import type { Plugin } from './Plugin';
|
||||
import { PluginManager, PluginType } from './PluginManager';
|
||||
import { PluginSettingOptions, PluginSettingsManager } from './PluginSettingsManager';
|
||||
import { ComponentTypeAndString, RouterManager, RouterOptions } from './RouterManager';
|
||||
import { WebSocketClient, WebSocketClientOptions } from './WebSocketClient';
|
||||
import { AppComponent, BlankComponent, defaultAppComponents } from './components';
|
||||
import { SchemaInitializer, SchemaInitializerManager } from './schema-initializer';
|
||||
import * as schemaInitializerComponents from './schema-initializer/components';
|
||||
import { SchemaSettings, SchemaSettingsManager } from './schema-settings';
|
||||
import { compose, normalizeContainer } from './utils';
|
||||
import { defineGlobalDeps } from './utils/globalDeps';
|
||||
import { getRequireJs } from './utils/requirejs';
|
||||
|
||||
import { CollectionField } from '../data-source/collection-field/CollectionField';
|
||||
import { DataSourceApplicationProvider } from '../data-source/components/DataSourceApplicationProvider';
|
||||
import { DataBlockProvider } from '../data-source/data-block/DataBlockProvider';
|
||||
import { DataSourceManager, type DataSourceManagerOptions } from '../data-source/data-source/DataSourceManager';
|
||||
|
||||
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
|
||||
import type { Plugin } from './Plugin';
|
||||
import type { RequireJS } from './utils/requirejs';
|
||||
import { getRequireJs, type RequireJS } from './utils/requirejs';
|
||||
import { WebSocketClient, WebSocketClientOptions } from './WebSocketClient';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -319,7 +315,7 @@ export class Application {
|
||||
}
|
||||
|
||||
getRootComponent() {
|
||||
const Root: FC = () => <AppComponent app={this} />;
|
||||
const Root = () => <AppComponent app={this} />;
|
||||
return Root;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
import React from 'react';
|
||||
import * as tachybaseComponents from '@tachybase/components';
|
||||
import * as tachybaseEvaluators from '@tachybase/evaluators/client';
|
||||
import * as formilyCore from '@tachybase/schema';
|
||||
import * as formilyJsonSchema from '@tachybase/schema';
|
||||
import * as formilyPath from '@tachybase/schema';
|
||||
import * as formilyReact from '@tachybase/schema';
|
||||
import * as formilyJsonReactive from '@tachybase/schema';
|
||||
import * as formilyReactiveReact from '@tachybase/schema';
|
||||
import * as formilyShared from '@tachybase/schema';
|
||||
import * as formilyValidator from '@tachybase/schema';
|
||||
import * as tachybaseSchema from '@tachybase/schema';
|
||||
import * as tachybaseSDK from '@tachybase/sdk';
|
||||
import * as tachybaseClientUtils from '@tachybase/utils/client';
|
||||
@ -60,22 +52,9 @@ export function defineGlobalDeps(requirejs: RequireJS) {
|
||||
requirejs.define('i18next', () => i18next);
|
||||
requirejs.define('react-i18next', () => reactI18next);
|
||||
|
||||
// formily
|
||||
requirejs.define('@formily/core', () => formilyCore);
|
||||
requirejs.define('@formily/react', () => formilyReact);
|
||||
requirejs.define('@formily/shared', () => formilyShared);
|
||||
requirejs.define('@formily/json-schema', () => formilyJsonSchema);
|
||||
requirejs.define('@formily/reactive', () => formilyJsonReactive);
|
||||
requirejs.define('@formily/path', () => formilyPath);
|
||||
requirejs.define('@formily/validator', () => formilyValidator);
|
||||
requirejs.define('@formily/reactive-react', () => formilyReactiveReact);
|
||||
|
||||
// tachybase
|
||||
requirejs.define('@tachybase/utils', () => tachybaseClientUtils);
|
||||
requirejs.define('@tachybase/utils/client', () => tachybaseClientUtils);
|
||||
requirejs.define('@tachybase/client', () => tachybaseClient);
|
||||
requirejs.define('@tachybase/client/client', () => tachybaseClient);
|
||||
requirejs.define('@tachybase/evaluators', () => tachybaseEvaluators);
|
||||
requirejs.define('@tachybase/evaluators/client', () => tachybaseEvaluators);
|
||||
requirejs.define('@tachybase/sdk', () => tachybaseSDK);
|
||||
requirejs.define('@tachybase/schema', () => tachybaseSchema);
|
||||
@ -94,5 +73,4 @@ export function defineGlobalDeps(requirejs: RequireJS) {
|
||||
requirejs.define('lodash', () => lodash);
|
||||
requirejs.define('ahooks', () => ahooks);
|
||||
requirejs.define('@emotion/css', () => emotionCss);
|
||||
requirejs.define('dayjs', () => dayjs);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { ChangeEvent, useCallback, useEffect } from 'react';
|
||||
import { Field, Form, untracked, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
||||
import { isURL, parse } from '@tachybase/utils/client';
|
||||
|
||||
import { App, message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import get from 'lodash/get';
|
||||
import omit from 'lodash/omit';
|
||||
@ -13,7 +13,6 @@ import { useReactToPrint } from 'react-to-print';
|
||||
import {
|
||||
AssociationFilter,
|
||||
useCollectionRecord,
|
||||
useDataLoadingMode,
|
||||
useDataSourceHeaders,
|
||||
useFormActiveFields,
|
||||
useFormBlockContext,
|
||||
@ -193,15 +192,12 @@ export const useCreateActionProps = () => {
|
||||
const actionSchema = useFieldSchema();
|
||||
const actionField = useField();
|
||||
const compile = useCompile();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
const { updateAssociationValues } = useFormBlockContext();
|
||||
const collectValues = useCollectValuesToSubmit();
|
||||
const action = record.isNew ? actionField.componentProps.saveMode || 'create' : 'update';
|
||||
const filterKeys = actionField.componentProps.filterKeys?.checked || [];
|
||||
const dataLoadingMode = useDataLoadingMode();
|
||||
|
||||
console.log('dataLoadingMode', dataLoadingMode);
|
||||
|
||||
return {
|
||||
async onClick() {
|
||||
@ -271,6 +267,7 @@ export const useAssociationCreateActionProps = () => {
|
||||
const { setVisible, fieldSchema } = useActionContext();
|
||||
const actionSchema = useFieldSchema();
|
||||
const actionField = useField();
|
||||
const { message } = App.useApp();
|
||||
const { fields, getField, getTreeParentField, name } = useCollection_deprecated();
|
||||
const compile = useCompile();
|
||||
const filterByTk = useFilterByTk();
|
||||
@ -510,7 +507,7 @@ export const useCustomizeUpdateActionProps = () => {
|
||||
const navigate = useNavigate();
|
||||
const compile = useCompile();
|
||||
const form = useForm();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
const variables = useVariables();
|
||||
const localVariables = useLocalVariables({ currentForm: form });
|
||||
const { name, getField } = useCollection_deprecated();
|
||||
@ -605,7 +602,7 @@ export const useCustomizeRequestActionProps = () => {
|
||||
const currentUser = currentUserContext?.data?.data;
|
||||
const actionField = useField();
|
||||
const { setVisible } = useActionContext();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
const { getActiveFieldsName } = useFormActiveFields() || {};
|
||||
|
||||
return {
|
||||
@ -694,7 +691,7 @@ export const useUpdateActionProps = () => {
|
||||
const compile = useCompile();
|
||||
const actionField = useField();
|
||||
const { updateAssociationValues } = useFormBlockContext();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
const data = useParamsFromRecord();
|
||||
const variables = useVariables();
|
||||
const localVariables = useLocalVariables({ currentForm: form });
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { createContext, useContext, useMemo, useState } from 'react';
|
||||
|
||||
import { Checkbox, message, Table } from 'antd';
|
||||
import { App, Checkbox, Table } from 'antd';
|
||||
import { omit } from 'lodash';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -42,12 +42,12 @@ export const SettingCenterProvider = (props) => {
|
||||
|
||||
export const SettingsCenterConfigure = () => {
|
||||
const app = useApp();
|
||||
const { message } = App.useApp();
|
||||
const { styles } = useStyles();
|
||||
const record = useRecord();
|
||||
const api = useAPIClient();
|
||||
const compile = useCompile();
|
||||
const settings = app.pluginSettingsManager.getList(false);
|
||||
console.log(settings);
|
||||
const allAclSnippets = app.pluginSettingsManager.getAclSnippets();
|
||||
const [snippets, setSnippets] = useState<string[]>([]);
|
||||
const allChecked = useMemo(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Checkbox, message, Table } from 'antd';
|
||||
import { App, Checkbox, Table } from 'antd';
|
||||
import { uniq } from 'lodash';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -45,6 +45,7 @@ export const MenuConfigure = () => {
|
||||
const { styles } = useStyles();
|
||||
const record = useRecord();
|
||||
const api = useAPIClient();
|
||||
const { message } = App.useApp();
|
||||
const { items } = useMenuItems();
|
||||
const { t } = useTranslation();
|
||||
const allUids = findUids(items);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
import { message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useAPIClient } from '../../../api-client';
|
||||
@ -21,6 +21,7 @@ export const PermissionProvider = (props) => {
|
||||
const api = useAPIClient();
|
||||
const record = useRecord();
|
||||
const { t } = useTranslation();
|
||||
const { message } = App.useApp();
|
||||
const { snippets } = record;
|
||||
snippets?.forEach((key) => {
|
||||
record[key] = true;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { FC, useState } from 'react';
|
||||
|
||||
import { ClockCircleOutlined, DeleteOutlined, ReadOutlined, ReloadOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
import { App, Card, Divider, message, Popconfirm, Space, Switch, Typography } from 'antd';
|
||||
import { App, Card, Divider, Popconfirm, Space, Switch, Typography } from 'antd';
|
||||
import classnames from 'classnames';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
@ -22,7 +22,7 @@ export const SwitchAction = (props: IPluginData) => {
|
||||
const { name, enabled, builtIn, error, isCompatible } = props;
|
||||
const api = useAPIClient();
|
||||
const { t } = useTranslation();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
return (
|
||||
<Switch
|
||||
aria-label="enable"
|
||||
@ -70,7 +70,7 @@ function PluginInfo(props: IPluginInfo) {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const api = useAPIClient();
|
||||
const { modal } = App.useApp();
|
||||
const { modal, message } = App.useApp();
|
||||
const [showUploadForm, setShowUploadForm] = useState(false);
|
||||
const reload = () => window.location.reload();
|
||||
const title = displayName || name || packageName;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { ISchema, uid, useForm } from '@tachybase/schema';
|
||||
|
||||
import { Card, message } from 'antd';
|
||||
import { App, Card } from 'antd';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -38,6 +38,7 @@ const useSystemSettingsValues = (options) => {
|
||||
const useSaveSystemSettingsValues = () => {
|
||||
const { setVisible } = useActionContext();
|
||||
const form = useForm();
|
||||
const { message } = App.useApp();
|
||||
const { mutate, data } = useSystemSettings();
|
||||
const api = useAPIClient();
|
||||
const { t } = useTranslation();
|
||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||
import { useForm } from '@tachybase/schema';
|
||||
|
||||
import { DeleteOutlined, ExclamationCircleFilled } from '@ant-design/icons';
|
||||
import { Button, message } from 'antd';
|
||||
import { App, Button } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -75,6 +75,7 @@ export const useBulkDestroyAction = () => {
|
||||
const { resource } = useResourceContext();
|
||||
const ctx = useActionContext();
|
||||
const { t } = useTranslation();
|
||||
const { message } = App.useApp();
|
||||
const form = useForm();
|
||||
const { cascade } = form?.values || {};
|
||||
return {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useField, useForm } from '@tachybase/schema';
|
||||
|
||||
import { message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import omit from 'lodash/omit';
|
||||
@ -431,8 +431,8 @@ export const useCreateActionWithoutRefresh = (actionCallback?: (values: any) =>
|
||||
|
||||
export const useUpdateViewAction = (actionCallback?: (filterByTk: string, values: any) => void) => {
|
||||
const form = useForm();
|
||||
const ctx = useActionContext();
|
||||
// const { refresh } = useResourceActionContext();
|
||||
const { message } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
const { resource, targetKey } = useResourceContext();
|
||||
const { [targetKey]: filterByTk } = useRecord();
|
||||
return {
|
||||
@ -440,8 +440,7 @@ export const useUpdateViewAction = (actionCallback?: (filterByTk: string, values
|
||||
await form.submit();
|
||||
const res = await resource.update({ filterByTk, values: form.values });
|
||||
actionCallback?.(filterByTk, res?.data?.data);
|
||||
// refresh();
|
||||
message.success('保存成功');
|
||||
message.success(t('Save successfully.'));
|
||||
},
|
||||
};
|
||||
};
|
||||
@ -503,6 +502,7 @@ export const useDestroyAction = (actionCallback?: (key: string) => void) => {
|
||||
export const useBulkDestroyAction = (actionCallback?: (keys: string[]) => void) => {
|
||||
const { state, setState, refresh } = useResourceActionContext();
|
||||
const { resource } = useResourceContext();
|
||||
const { message } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
return {
|
||||
async run() {
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { Drawer } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
import { OpenSize } from './';
|
||||
import { useStyles } from './Action.Drawer.style';
|
||||
import { useActionContext } from './hooks';
|
||||
@ -16,7 +18,7 @@ const openSizeWidthMap = new Map<OpenSize, string>([
|
||||
export const ActionDrawer: ComposedActionDrawer = observer(
|
||||
(props) => {
|
||||
const { footerNodeName = 'Action.Drawer.Footer', ...others } = props;
|
||||
const { visible, setVisible, openSize = 'middle', drawerProps, modalProps } = useActionContext();
|
||||
const { visible, setVisible, openSize = 'middle', drawerProps } = useActionContext();
|
||||
const schema = useFieldSchema();
|
||||
const field = useField();
|
||||
const { componentCls, hashId } = useStyles();
|
||||
|
@ -8,9 +8,7 @@ import { useActionContext } from './hooks';
|
||||
export const ActionContext = createContext<ActionContextProps>({});
|
||||
ActionContext.displayName = 'ActionContext';
|
||||
|
||||
export const ActionContextProvider: React.FC<ActionContextProps & { value?: ActionContextProps; children: any }> = (
|
||||
props,
|
||||
) => {
|
||||
export const ActionContextProvider = (props: ActionContextProps & { value?: ActionContextProps; children: any }) => {
|
||||
const contextProps = useActionContext();
|
||||
return (
|
||||
<ActionContext.Provider value={{ ...contextProps, ...props, ...props?.value }}>
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { useFieldSchema, useForm } from '@tachybase/schema';
|
||||
import { App } from 'antd';
|
||||
import { useContext } from 'react';
|
||||
import { useFieldSchema, useForm } from '@tachybase/schema';
|
||||
|
||||
import { App } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useIsDetailBlock } from '../../../block-provider/FormBlockProvider';
|
||||
import { ActionContext } from './context';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
connect,
|
||||
mapProps,
|
||||
@ -12,7 +12,7 @@ import {
|
||||
} from '@tachybase/schema';
|
||||
|
||||
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { message, Space } from 'antd';
|
||||
import { App, Space } from 'antd';
|
||||
import { isFunction } from 'mathjs';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -53,6 +53,7 @@ export const filterAnalyses = (filters): any[] => {
|
||||
const InternalAssociationSelect = observer(
|
||||
(props: AssociationSelectProps) => {
|
||||
const { objectValue = true } = props;
|
||||
const { message } = App.useApp();
|
||||
const field: any = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const service = useServiceOptions(props);
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { TreeSelect } from '@tachybase/components';
|
||||
import { Field, ISchema, onFieldChange, Schema, useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -250,6 +250,7 @@ export const MenuDesigner = () => {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const api = useAPIClient();
|
||||
const { message } = App.useApp();
|
||||
const { dn, refresh } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
const menuSchema = findMenuSchema(fieldSchema);
|
||||
|
@ -10,10 +10,7 @@ import {
|
||||
useFieldSchema,
|
||||
} from '@tachybase/schema';
|
||||
|
||||
import { message } from 'antd';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import set from 'lodash/set';
|
||||
import { cloneDeep, get, set } from 'lodash';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { APIClient, useAPIClient } from '../../api-client';
|
||||
@ -185,7 +182,6 @@ export class Designable {
|
||||
});
|
||||
}
|
||||
onSuccess?.(res?.data?.data);
|
||||
message.success(t('Saved successfully'), 0.2);
|
||||
});
|
||||
this.on('patch', async ({ schema }) => {
|
||||
this.refresh();
|
||||
@ -199,7 +195,6 @@ export class Designable {
|
||||
...schema,
|
||||
},
|
||||
});
|
||||
message.success(t('Saved successfully'), 0.2);
|
||||
});
|
||||
this.on('batchPatch', async ({ schemas }) => {
|
||||
this.refresh();
|
||||
@ -208,7 +203,6 @@ export class Designable {
|
||||
method: 'post',
|
||||
data: schemas,
|
||||
});
|
||||
message.success(t('Saved successfully'), 0.2);
|
||||
});
|
||||
this.on('remove', async ({ removed }) => {
|
||||
let schemas = [];
|
||||
@ -230,7 +224,6 @@ export class Designable {
|
||||
data: schemas,
|
||||
});
|
||||
}
|
||||
message.success(t('Saved successfully'), 0.2);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { ISchema, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
||||
|
||||
import { message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
import { SchemaComponent, useActionContext, useAPIClient, useDesignable, useProps, useRecord } from '../..';
|
||||
@ -11,6 +11,7 @@ import { useGetAriaLabelOfSchemaInitializer } from '../hooks/useGetAriaLabelOfSc
|
||||
export const TabPaneInitializers = (props?: any) => {
|
||||
const { designable, insertBeforeEnd } = useDesignable();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { message } = App.useApp();
|
||||
const { isCreate, isBulkEdit, options } = props;
|
||||
const { gridInitializer } = options;
|
||||
const { getAriaLabel } = useGetAriaLabelOfSchemaInitializer();
|
||||
|
@ -1,17 +1,20 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { ArrayBase } from '@tachybase/components';
|
||||
import { useForm } from '@tachybase/schema';
|
||||
import { message } from 'antd';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { App } from 'antd';
|
||||
import LRUCache from 'lru-cache';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { getAssociationPath } from '../../block-provider/hooks';
|
||||
import { useCollectionManager_deprecated } from '../../collection-manager';
|
||||
import { useCompile } from '../../schema-component';
|
||||
import { TreeNode } from './TreeLabel';
|
||||
import { systemKeys } from './hooks/useCollectionState';
|
||||
import LRUCache from 'lru-cache';
|
||||
import { TreeNode } from './TreeLabel';
|
||||
|
||||
export const useSyncFromForm = (fieldSchema, collection?, callBack?) => {
|
||||
const { getCollectionJoinField, getCollectionFields } = useCollectionManager_deprecated();
|
||||
const { message } = App.useApp();
|
||||
const array = ArrayBase.useArray();
|
||||
const index = ArrayBase.useIndex();
|
||||
const record = ArrayBase.useRecord();
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useForm } from '@tachybase/schema';
|
||||
|
||||
import { Button, Input, message } from 'antd';
|
||||
import { App, Button, Input } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -17,6 +17,7 @@ const useStyles = createStyles(({ css }) => {
|
||||
});
|
||||
|
||||
export default function VerificationCode({ targetFieldName = 'phone', actionType, value, onChange }) {
|
||||
const { message } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
const { styles } = useStyles();
|
||||
const api = useAPIClient();
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { connect, mapProps } from '@tachybase/schema';
|
||||
|
||||
import { Button } from 'antd';
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
|
||||
import SignaturePad from './SignaturePad';
|
||||
|
||||
export const SignatureInput = connect(
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import SigPad, { Options, PointGroup, ToSVGOptions } from 'signature_pad';
|
||||
import { debounce } from 'throttle-debounce';
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { callHideEvent } from './registerEvent';
|
||||
|
||||
function ContextMenuItem({ children, onClick, disabled, preventClose, attributes, className }) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { useRef, useCallback } from 'react';
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import { callShowEvent, callHideEvent } from './registerEvent';
|
||||
|
||||
import { callHideEvent, callShowEvent } from './registerEvent';
|
||||
|
||||
function ContextMenuTrigger({ children, id, disableWhileShiftPressed, attributes, disable, className }) {
|
||||
const menuTrigger = useRef(null);
|
||||
|
@ -95,7 +95,9 @@
|
||||
.zoom-enter-active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
transform-origin: top left;
|
||||
}
|
||||
.zoom-exit {
|
||||
@ -106,7 +108,9 @@
|
||||
.zoom-exit-active {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
transform-origin: top left;
|
||||
}
|
||||
// zoom in animation start
|
||||
@ -119,7 +123,9 @@
|
||||
.toTopLeft-enter-active {
|
||||
opacity: 1;
|
||||
transform: translate(0px, 0px);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
.toTopLeft-exit {
|
||||
opacity: 1;
|
||||
@ -128,7 +134,9 @@
|
||||
.toTopLeft-exit-active {
|
||||
opacity: 0;
|
||||
transform: translate(10px, 10px);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
// to top left animation start
|
||||
|
||||
@ -140,7 +148,9 @@
|
||||
.rightToLeft-enter-active {
|
||||
opacity: 1;
|
||||
transform: translateX(0px);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
.rightToLeft-exit {
|
||||
opacity: 1;
|
||||
@ -149,7 +159,9 @@
|
||||
.rightToLeft-exit-active {
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
// right to left animation start
|
||||
|
||||
@ -161,7 +173,9 @@
|
||||
.pop-enter-active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
.pop-exit {
|
||||
opacity: 1;
|
||||
@ -170,7 +184,9 @@
|
||||
.pop-exit-active {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
transition: opacity 200ms, transform 200ms;
|
||||
transition:
|
||||
opacity 200ms,
|
||||
transform 200ms;
|
||||
}
|
||||
// right to left animation start
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React, { useCallback, useState, useRef } from 'react';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import ContextMenuItem from './contextMenuItem';
|
||||
|
||||
function Submenu({ children, title, attributes, className }) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { SchemaComponent } from '@tachybase/client';
|
||||
import React from 'react';
|
||||
import { SchemaComponent } from '@tachybase/client';
|
||||
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
|
||||
import { ErrorBoundaryFallBack } from './ErrorBoundary';
|
||||
|
||||
export const CustomAssociatedField = (props) => {
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { SchemaComponent, SchemaSettings, useApp, useDesignable, usePlugin } from '@tachybase/client';
|
||||
import React from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { useTranslation } from '../../locale';
|
||||
import { useField, useFieldSchema } from '@tachybase/schema';
|
||||
import { SchemaComponent, SchemaSettings, useApp, useDesignable, usePlugin } from '@tachybase/client';
|
||||
import { Field } from '@tachybase/database';
|
||||
import { useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
|
||||
import { useCustomComponent } from '../../hooks/useCustomComponent';
|
||||
import { useTranslation } from '../../locale';
|
||||
import { CustomComponentType } from './custom-components';
|
||||
import { ErrorBoundaryFallBack } from './ErrorBoundary';
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { SchemaComponent } from '@tachybase/client';
|
||||
import React from 'react';
|
||||
import { SchemaComponent } from '@tachybase/client';
|
||||
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
|
||||
import { ErrorBoundaryFallBack } from './ErrorBoundary';
|
||||
|
||||
export const CustomField = (props) => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useTranslation } from '../../locale';
|
||||
|
||||
export const ErrorBoundaryFallBack = () => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ReactFC } from '@tachybase/schema';
|
||||
import { ComponentType, MemoExoticComponent } from 'react';
|
||||
import { ReactFC } from '@tachybase/schema';
|
||||
|
||||
export interface CustomFunctionComponent<P = {}> extends React.FunctionComponent<P> {
|
||||
__componentType: CustomComponentType;
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { connect, mapProps } from '@tachybase/schema';
|
||||
import { Button } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { connect, mapProps } from '@tachybase/schema';
|
||||
|
||||
import { Button } from 'antd';
|
||||
|
||||
import ModalFullScreen from '../modal-full-screen/ModalFullScreen';
|
||||
import Sheet, { SheetRef } from './Sheet';
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import { ISchema, RecursionField, connect, observer, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
ActionContextProvider,
|
||||
CollectionProvider_deprecated,
|
||||
@ -8,7 +7,9 @@ import {
|
||||
useDesignable,
|
||||
useRequest,
|
||||
} from '@tachybase/client';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { connect, ISchema, observer, RecursionField, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
const viewerSchema: ISchema = {
|
||||
type: 'void',
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { css } from '@tachybase/client';
|
||||
import { ArrayCollapse } from '@tachybase/components';
|
||||
import { Form } from '@tachybase/schema';
|
||||
import { observer, useField, useFieldSchema } from '@tachybase/schema';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
FormBlockContext,
|
||||
RecordProvider,
|
||||
SchemaComponent,
|
||||
getShouldChange,
|
||||
useCollectionManager_deprecated,
|
||||
__UNSAFE__VariablesContextType,
|
||||
__UNSAFE__DynamicComponentProps,
|
||||
__UNSAFE__VariableOption,
|
||||
__UNSAFE__VariablesContextType,
|
||||
css,
|
||||
FormBlockContext,
|
||||
getShouldChange,
|
||||
RecordProvider,
|
||||
SchemaComponent,
|
||||
useCollectionManager_deprecated,
|
||||
} from '@tachybase/client';
|
||||
import React, { useMemo } from 'react';
|
||||
import { ArrayCollapse } from '@tachybase/components';
|
||||
import { Form, observer, useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { FilterContext } from './context';
|
||||
import { VariableInput } from './VariableInput';
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { ObjectField } from '@tachybase/schema';
|
||||
import { Schema } from '@tachybase/schema';
|
||||
import { createContext } from 'react';
|
||||
import { ObjectField, Schema } from '@tachybase/schema';
|
||||
|
||||
export interface FilterContextProps {
|
||||
field?: ObjectField & { collectionName?: string };
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { css } from '@tachybase/client';
|
||||
|
||||
import { Button } from 'antd';
|
||||
|
||||
export const ModalHeader = (props) => {
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import { css } from '@tachybase/client';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
|
||||
import { MobileOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
|
||||
import { useTranslation } from '../../locale';
|
||||
|
||||
export const MobileLink = () => {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { uid } from '@tachybase/schema';
|
||||
import { css, useAPIClient, useApp } from '@tachybase/client';
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { css, useAPIClient, useApp } from '@tachybase/client';
|
||||
import { uid } from '@tachybase/schema';
|
||||
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import _ from 'lodash';
|
||||
|
||||
const OnlineUserManger = () => {
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { DrawBox } from './DrawBox';
|
||||
import { npxLine } from './utils';
|
||||
import { drawFontLine } from './utils';
|
||||
import { npx } from './utils';
|
||||
import { thinLineWidth } from './utils';
|
||||
import { dpr } from './utils';
|
||||
import { dpr, drawFontLine, npx, npxLine, thinLineWidth } from './utils';
|
||||
|
||||
interface Attr {
|
||||
align?: 'left' | 'center' | 'right';
|
||||
|
@ -1,24 +1,22 @@
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
import DropdownColor from './dropdown_color';
|
||||
import DropdownLineType from './dropdown_linetype';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
|
||||
function buildTable(...trs) {
|
||||
return h('table', '').child(
|
||||
h('tbody', '').children(...trs),
|
||||
);
|
||||
return h('table', '').child(h('tbody', '').children(...trs));
|
||||
}
|
||||
|
||||
function buildTd(iconName) {
|
||||
return h('td', '').child(
|
||||
h('div', `${cssPrefix}-border-palette-cell`).child(
|
||||
new Icon(`border-${iconName}`),
|
||||
).on('click', () => {
|
||||
this.mode = iconName;
|
||||
const { mode, style, color } = this;
|
||||
this.change({ mode, style, color });
|
||||
}),
|
||||
h('div', `${cssPrefix}-border-palette-cell`)
|
||||
.child(new Icon(`border-${iconName}`))
|
||||
.on('click', () => {
|
||||
this.mode = iconName;
|
||||
const { mode, style, color } = this;
|
||||
this.change({ mode, style, color });
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -42,11 +40,9 @@ export default class BorderPalette {
|
||||
h('td', `${cssPrefix}-border-palette-left`).child(
|
||||
buildTable(
|
||||
h('tr', '').children(
|
||||
...['all', 'inside', 'horizontal', 'vertical', 'outside'].map(it => buildTd.call(this, it)),
|
||||
),
|
||||
h('tr', '').children(
|
||||
...['left', 'top', 'right', 'bottom', 'none'].map(it => buildTd.call(this, it)),
|
||||
...['all', 'inside', 'horizontal', 'vertical', 'outside'].map((it) => buildTd.call(this, it)),
|
||||
),
|
||||
h('tr', '').children(...['left', 'top', 'right', 'bottom', 'none'].map((it) => buildTd.call(this, it))),
|
||||
),
|
||||
),
|
||||
h('td', `${cssPrefix}-border-palette-right`).children(
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
import Icon from './icon';
|
||||
import FormInput from './form_input';
|
||||
import Dropdown from './dropdown';
|
||||
// Record: temp not used
|
||||
// import { xtoast } from './message';
|
||||
import { tf } from '../locale/locale';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import FormInput from './form_input';
|
||||
import Icon from './icon';
|
||||
|
||||
class DropdownMore extends Dropdown {
|
||||
constructor(click) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HComponent } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import { HComponent } from './element';
|
||||
|
||||
export default class Button extends HComponent {
|
||||
// type: primary
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { t } from '../locale/locale';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { t } from '../locale/locale';
|
||||
|
||||
function addMonth(date, step) {
|
||||
date.setMonth(date.getMonth() + step);
|
||||
@ -37,28 +37,23 @@ export default class Calendar {
|
||||
this.headerLeftEl = h('div', 'calendar-header-left');
|
||||
this.bodyEl = h('tbody', '');
|
||||
this.buildAll();
|
||||
this.el = h('div', 'x-spreadsheet-calendar')
|
||||
.children(
|
||||
h('div', 'calendar-header').children(
|
||||
this.headerLeftEl,
|
||||
h('div', 'calendar-header-right').children(
|
||||
h('a', 'calendar-prev')
|
||||
.on('click.stop', () => this.prev())
|
||||
.child(new Icon('chevron-left')),
|
||||
h('a', 'calendar-next')
|
||||
.on('click.stop', () => this.next())
|
||||
.child(new Icon('chevron-right')),
|
||||
),
|
||||
this.el = h('div', 'x-spreadsheet-calendar').children(
|
||||
h('div', 'calendar-header').children(
|
||||
this.headerLeftEl,
|
||||
h('div', 'calendar-header-right').children(
|
||||
h('a', 'calendar-prev')
|
||||
.on('click.stop', () => this.prev())
|
||||
.child(new Icon('chevron-left')),
|
||||
h('a', 'calendar-next')
|
||||
.on('click.stop', () => this.next())
|
||||
.child(new Icon('chevron-right')),
|
||||
),
|
||||
h('table', 'calendar-body').children(
|
||||
h('thead', '').child(
|
||||
h('tr', '').children(
|
||||
...t('calendar.weeks').map(week => h('th', 'cell').child(week)),
|
||||
),
|
||||
),
|
||||
this.bodyEl,
|
||||
),
|
||||
);
|
||||
),
|
||||
h('table', 'calendar-body').children(
|
||||
h('thead', '').child(h('tr', '').children(...t('calendar.weeks').map((week) => h('th', 'cell').child(week)))),
|
||||
this.bodyEl,
|
||||
),
|
||||
);
|
||||
this.selectChange = () => {};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,18 @@
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
|
||||
const themeColorPlaceHolders = ['#ffffff', '#000100', '#e7e5e6', '#445569', '#5b9cd6', '#ed7d31', '#a5a5a5', '#ffc001', '#4371c6', '#71ae47'];
|
||||
const themeColorPlaceHolders = [
|
||||
'#ffffff',
|
||||
'#000100',
|
||||
'#e7e5e6',
|
||||
'#445569',
|
||||
'#5b9cd6',
|
||||
'#ed7d31',
|
||||
'#a5a5a5',
|
||||
'#ffc001',
|
||||
'#4371c6',
|
||||
'#71ae47',
|
||||
];
|
||||
|
||||
const themeColors = [
|
||||
['#f2f2f2', '#7f7f7f', '#d0cecf', '#d5dce4', '#deeaf6', '#fce5d5', '#ededed', '#fff2cd', '#d9e2f3', '#e3efd9'],
|
||||
@ -11,7 +22,18 @@ const themeColors = [
|
||||
['#7f7f7f', '#0c0c0c', '#171516', '#222a35', '#1f4e7a', '#843c0a', '#525252', '#7e6000', '#203864', '#365624'],
|
||||
];
|
||||
|
||||
const standardColors = ['#c00000', '#fe0000', '#fdc101', '#ffff01', '#93d051', '#00b04e', '#01b0f1', '#0170c1', '#012060', '#7030a0'];
|
||||
const standardColors = [
|
||||
'#c00000',
|
||||
'#fe0000',
|
||||
'#fdc101',
|
||||
'#ffff01',
|
||||
'#93d051',
|
||||
'#00b04e',
|
||||
'#01b0f1',
|
||||
'#0170c1',
|
||||
'#012060',
|
||||
'#7030a0',
|
||||
];
|
||||
|
||||
function buildTd(bgcolor) {
|
||||
return h('td', '').child(
|
||||
@ -28,14 +50,12 @@ export default class ColorPalette {
|
||||
const table = h('table', '').children(
|
||||
h('tbody', '').children(
|
||||
h('tr', `${cssPrefix}-theme-color-placeholders`).children(
|
||||
...themeColorPlaceHolders.map(color => buildTd.call(this, color)),
|
||||
...themeColorPlaceHolders.map((color) => buildTd.call(this, color)),
|
||||
),
|
||||
...themeColors.map(it => h('tr', `${cssPrefix}-theme-colors`).children(
|
||||
...it.map(color => buildTd.call(this, color)),
|
||||
)),
|
||||
h('tr', `${cssPrefix}-standard-colors`).children(
|
||||
...standardColors.map(color => buildTd.call(this, color)),
|
||||
...themeColors.map((it) =>
|
||||
h('tr', `${cssPrefix}-theme-colors`).children(...it.map((color) => buildTd.call(this, color))),
|
||||
),
|
||||
h('tr', `${cssPrefix}-standard-colors`).children(...standardColors.map((color) => buildTd.call(this, color))),
|
||||
),
|
||||
);
|
||||
this.el.child(table);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
import { tf } from '../locale/locale';
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
|
||||
const menuItems = [
|
||||
{ key: 'copy', title: tf('contextmenu.copy'), label: 'Ctrl+C' },
|
||||
@ -36,14 +36,11 @@ function buildMenuItem(item) {
|
||||
this.itemClick(item.key);
|
||||
this.hide();
|
||||
})
|
||||
.children(
|
||||
item.title(),
|
||||
h('div', 'label').child(item.label || ''),
|
||||
);
|
||||
.children(item.title(), h('div', 'label').child(item.label || ''));
|
||||
}
|
||||
|
||||
function buildMenu() {
|
||||
return menuItems.map(it => buildMenuItem.call(this, it));
|
||||
return menuItems.map((it) => buildMenuItem.call(this, it));
|
||||
}
|
||||
|
||||
export default class ContextMenu {
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import Calendar from './calendar';
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class Datepicker {
|
||||
constructor() {
|
||||
this.calendar = new Calendar(new Date());
|
||||
this.el = h('div', `${cssPrefix}-datepicker`).child(
|
||||
this.calendar.el,
|
||||
).hide();
|
||||
this.el = h('div', `${cssPrefix}-datepicker`).child(this.calendar.el).hide();
|
||||
}
|
||||
|
||||
setValue(date) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HComponent, h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h, HComponent } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
|
||||
export default class Dropdown extends HComponent {
|
||||
constructor(title, width, showArrow, placement, ...children) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
function buildItemWithIcon(iconName) {
|
||||
return h('div', `${cssPrefix}-item`).child(new Icon(iconName));
|
||||
@ -10,11 +10,12 @@ function buildItemWithIcon(iconName) {
|
||||
export default class DropdownAlign extends Dropdown {
|
||||
constructor(aligns, align) {
|
||||
const icon = new Icon(`align-${align}`);
|
||||
const naligns = aligns.map(it => buildItemWithIcon(`align-${it}`)
|
||||
.on('click', () => {
|
||||
const naligns = aligns.map((it) =>
|
||||
buildItemWithIcon(`align-${it}`).on('click', () => {
|
||||
this.setTitle(it);
|
||||
this.change(it);
|
||||
}));
|
||||
}),
|
||||
);
|
||||
super(icon, 'auto', true, 'bottom-left', ...naligns);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BorderPalette from './border_palette';
|
||||
import Dropdown from './dropdown';
|
||||
import Icon from './icon';
|
||||
import BorderPalette from './border_palette';
|
||||
|
||||
export default class DropdownBorder extends Dropdown {
|
||||
constructor() {
|
||||
|
@ -1,12 +1,10 @@
|
||||
import ColorPalette from './color_palette';
|
||||
import Dropdown from './dropdown';
|
||||
import Icon from './icon';
|
||||
import ColorPalette from './color_palette';
|
||||
|
||||
export default class DropdownColor extends Dropdown {
|
||||
constructor(iconName, color) {
|
||||
const icon = new Icon(iconName)
|
||||
.css('height', '16px')
|
||||
.css('border-bottom', `3px solid ${color}`);
|
||||
const icon = new Icon(iconName).css('height', '16px').css('border-bottom', `3px solid ${color}`);
|
||||
const colorPalette = new ColorPalette();
|
||||
colorPalette.change = (v) => {
|
||||
this.setTitle(v);
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import { baseFonts } from '../core/font';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import { baseFonts } from '../core/font';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class DropdownFont extends Dropdown {
|
||||
constructor() {
|
||||
const nfonts = baseFonts.map(it => h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.setTitle(it.title);
|
||||
this.change(it);
|
||||
})
|
||||
.child(it.title));
|
||||
const nfonts = baseFonts.map((it) =>
|
||||
h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.setTitle(it.title);
|
||||
this.change(it);
|
||||
})
|
||||
.child(it.title),
|
||||
);
|
||||
super(baseFonts[0].title, '160px', true, 'bottom-left', ...nfonts);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import { fontSizes } from '../core/font';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import { fontSizes } from '../core/font';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class DropdownFontSize extends Dropdown {
|
||||
constructor() {
|
||||
const nfontSizes = fontSizes.map(it => h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.setTitle(`${it.pt}`);
|
||||
this.change(it);
|
||||
})
|
||||
.child(`${it.pt}`));
|
||||
const nfontSizes = fontSizes.map((it) =>
|
||||
h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.setTitle(`${it.pt}`);
|
||||
this.change(it);
|
||||
})
|
||||
.child(`${it.pt}`),
|
||||
);
|
||||
super('10', '60px', true, 'bottom-left', ...nfontSizes);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import { baseFormats } from '../core/format';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import { baseFormats } from '../core/format';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class DropdownFormat extends Dropdown {
|
||||
constructor() {
|
||||
@ -13,11 +13,10 @@ export default class DropdownFormat extends Dropdown {
|
||||
if (it.key === 'divider') {
|
||||
item.addClass('divider');
|
||||
} else {
|
||||
item.child(it.title())
|
||||
.on('click', () => {
|
||||
this.setTitle(it.title());
|
||||
this.change(it);
|
||||
});
|
||||
item.child(it.title()).on('click', () => {
|
||||
this.setTitle(it.title());
|
||||
this.change(it);
|
||||
});
|
||||
if (it.label) item.child(h('div', 'label').html(it.label));
|
||||
}
|
||||
return item;
|
||||
|
@ -1,17 +1,19 @@
|
||||
import Dropdown from './dropdown';
|
||||
import Icon from './icon';
|
||||
import { h } from './element';
|
||||
import { baseFormulas } from '../core/formula';
|
||||
import { cssPrefix } from '../config';
|
||||
import { baseFormulas } from '../core/formula';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
|
||||
export default class DropdownFormula extends Dropdown {
|
||||
constructor() {
|
||||
const nformulas = baseFormulas.map(it => h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.hide();
|
||||
this.change(it);
|
||||
})
|
||||
.child(it.key));
|
||||
const nformulas = baseFormulas.map((it) =>
|
||||
h('div', `${cssPrefix}-item`)
|
||||
.on('click', () => {
|
||||
this.hide();
|
||||
this.change(it);
|
||||
})
|
||||
.child(it.key),
|
||||
);
|
||||
super(new Icon('formula'), '180px', true, 'bottom-left', ...nformulas);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,29 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
const lineTypes = [
|
||||
['thin', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" style="user-select: none;"></line></svg>'],
|
||||
['medium', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="2" style="user-select: none;"><line x1="0" y1="1.0" x2="50" y2="1.0" stroke-width="2" stroke="black" style="user-select: none;"></line></svg>'],
|
||||
['thick', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="3" style="user-select: none;"><line x1="0" y1="1.5" x2="50" y2="1.5" stroke-width="3" stroke="black" style="user-select: none;"></line></svg>'],
|
||||
['dashed', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" stroke-dasharray="2" style="user-select: none;"></line></svg>'],
|
||||
['dotted', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" stroke-dasharray="1" style="user-select: none;"></line></svg>'],
|
||||
[
|
||||
'thin',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" style="user-select: none;"></line></svg>',
|
||||
],
|
||||
[
|
||||
'medium',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="50" height="2" style="user-select: none;"><line x1="0" y1="1.0" x2="50" y2="1.0" stroke-width="2" stroke="black" style="user-select: none;"></line></svg>',
|
||||
],
|
||||
[
|
||||
'thick',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="50" height="3" style="user-select: none;"><line x1="0" y1="1.5" x2="50" y2="1.5" stroke-width="3" stroke="black" style="user-select: none;"></line></svg>',
|
||||
],
|
||||
[
|
||||
'dashed',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" stroke-dasharray="2" style="user-select: none;"></line></svg>',
|
||||
],
|
||||
[
|
||||
'dotted',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="50" height="1" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" stroke-dasharray="1" style="user-select: none;"></line></svg>',
|
||||
],
|
||||
// ['double', '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="3" style="user-select: none;"><line x1="0" y1="0.5" x2="50" y2="0.5" stroke-width="1" stroke="black" style="user-select: none;"></line><line x1="0" y1="2.5" x2="50" y2="2.5" stroke-width="1" stroke="black" style="user-select: none;"></line></svg>'],
|
||||
];
|
||||
|
||||
@ -16,17 +31,17 @@ export default class DropdownLineType extends Dropdown {
|
||||
constructor(type) {
|
||||
const icon = new Icon('line-type');
|
||||
let beforei = 0;
|
||||
const lineTypeEls = lineTypes.map((it, iti) => h('div', `${cssPrefix}-item state ${type === it[0] ? 'checked' : ''}`)
|
||||
.on('click', () => {
|
||||
lineTypeEls[beforei].toggle('checked');
|
||||
lineTypeEls[iti].toggle('checked');
|
||||
beforei = iti;
|
||||
this.hide();
|
||||
this.change(it);
|
||||
})
|
||||
.child(
|
||||
h('div', `${cssPrefix}-line-type`).html(it[1]),
|
||||
));
|
||||
const lineTypeEls = lineTypes.map((it, iti) =>
|
||||
h('div', `${cssPrefix}-item state ${type === it[0] ? 'checked' : ''}`)
|
||||
.on('click', () => {
|
||||
lineTypeEls[beforei].toggle('checked');
|
||||
lineTypeEls[iti].toggle('checked');
|
||||
beforei = iti;
|
||||
this.hide();
|
||||
this.change(it);
|
||||
})
|
||||
.child(h('div', `${cssPrefix}-line-type`).html(it[1])),
|
||||
);
|
||||
|
||||
super(icon, 'auto', false, 'bottom-left', ...lineTypeEls);
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
//* global window */
|
||||
import { cssPrefix } from '../config';
|
||||
import Datepicker from './datepicker';
|
||||
import { h } from './element';
|
||||
import Suggest from './suggest';
|
||||
import Datepicker from './datepicker';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
// import { mouseMoveUp } from '../event';
|
||||
|
||||
function resetTextareaSize() {
|
||||
const { inputText } = this;
|
||||
if (!/^\s*$/.test(inputText)) {
|
||||
const {
|
||||
textlineEl, textEl, areaOffset,
|
||||
} = this;
|
||||
const { textlineEl, textEl, areaOffset } = this;
|
||||
const txts = inputText.split('\n');
|
||||
const maxTxtSize = Math.max(...txts.map(it => it.length));
|
||||
const maxTxtSize = Math.max(...txts.map((it) => it.length));
|
||||
const tlOffset = textlineEl.offset();
|
||||
const fontWidth = tlOffset.width / inputText.length;
|
||||
const tlineWidth = (maxTxtSize + 1) * fontWidth + 5;
|
||||
@ -23,7 +22,7 @@ function resetTextareaSize() {
|
||||
if (tlineWidth > maxWidth) {
|
||||
twidth = maxWidth;
|
||||
h1 += parseInt(tlineWidth / maxWidth, 10);
|
||||
h1 += (tlineWidth % maxWidth) > 0 ? 1 : 0;
|
||||
h1 += tlineWidth % maxWidth > 0 ? 1 : 0;
|
||||
}
|
||||
textEl.css('width', `${twidth}px`);
|
||||
}
|
||||
@ -61,7 +60,7 @@ function inputEventHandler(evt) {
|
||||
const { suggest, textlineEl, validator } = this;
|
||||
const { cell } = this;
|
||||
if (cell !== null) {
|
||||
if (('editable' in cell && cell.editable === true) || (cell.editable === undefined)) {
|
||||
if (('editable' in cell && cell.editable === true) || cell.editable === undefined) {
|
||||
this.inputText = v;
|
||||
if (validator) {
|
||||
if (validator.type === 'list') {
|
||||
@ -174,18 +173,17 @@ export default class Editor {
|
||||
});
|
||||
this.areaEl = h('div', `${cssPrefix}-editor-area`)
|
||||
.children(
|
||||
this.textEl = h('textarea', '')
|
||||
.on('input', evt => inputEventHandler.call(this, evt))
|
||||
(this.textEl = h('textarea', '')
|
||||
.on('input', (evt) => inputEventHandler.call(this, evt))
|
||||
.on('paste.stop', () => {})
|
||||
.on('keydown', evt => keydownEventHandler.call(this, evt)),
|
||||
this.textlineEl = h('div', 'textline'),
|
||||
.on('keydown', (evt) => keydownEventHandler.call(this, evt))),
|
||||
(this.textlineEl = h('div', 'textline')),
|
||||
this.suggest.el,
|
||||
this.datepicker.el,
|
||||
)
|
||||
.on('mousemove.stop', () => {})
|
||||
.on('mousedown.stop', () => {});
|
||||
this.el = h('div', `${cssPrefix}-editor`)
|
||||
.child(this.areaEl).hide();
|
||||
this.el = h('div', `${cssPrefix}-editor`).child(this.areaEl).hide();
|
||||
this.suggest.bindInputEvents(this.textEl);
|
||||
|
||||
this.areaOffset = null;
|
||||
@ -217,14 +215,10 @@ export default class Editor {
|
||||
}
|
||||
|
||||
setOffset(offset, suggestPosition = 'top') {
|
||||
const {
|
||||
textEl, areaEl, suggest, freeze, el,
|
||||
} = this;
|
||||
const { textEl, areaEl, suggest, freeze, el } = this;
|
||||
if (offset) {
|
||||
this.areaOffset = offset;
|
||||
const {
|
||||
left, top, width, height, l, t,
|
||||
} = offset;
|
||||
const { left, top, width, height, l, t } = offset;
|
||||
// console.log('left:', left, ',top:', top, ', freeze:', freeze);
|
||||
const elOffset = { left: 0, top: 0 };
|
||||
// top left
|
||||
|
@ -1,4 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
class Element {
|
||||
el: HTMLElement;
|
||||
private _data: Record<string, any>;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import { h } from './element';
|
||||
|
||||
const patterns = {
|
||||
number: /(^\d+$)|(^\d+(\.\d{0,4})?$)/,
|
||||
@ -18,8 +18,7 @@ export default class FormField {
|
||||
this.tip = h('div', 'tip').child('tip').hide();
|
||||
this.input = input;
|
||||
this.input.vchange = () => this.validate();
|
||||
this.el = h('div', `${cssPrefix}-form-field`)
|
||||
.children(this.label, input.el, this.tip);
|
||||
this.el = h('div', `${cssPrefix}-form-field`).children(this.label, input.el, this.tip);
|
||||
}
|
||||
|
||||
isShow() {
|
||||
@ -44,9 +43,7 @@ export default class FormField {
|
||||
}
|
||||
|
||||
validate() {
|
||||
const {
|
||||
input, rule, tip, el,
|
||||
} = this;
|
||||
const { input, rule, tip, el } = this;
|
||||
const v = input.val();
|
||||
if (rule.required) {
|
||||
if (/^\s*$/.test(v)) {
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
|
||||
export default class FormInput {
|
||||
constructor(width, hint) {
|
||||
this.vchange = () => {};
|
||||
this.el = h('div', `${cssPrefix}-form-input`);
|
||||
this.input = h('input', '').css('width', width)
|
||||
.on('input', evt => this.vchange(evt))
|
||||
this.input = h('input', '')
|
||||
.css('width', width)
|
||||
.on('input', (evt) => this.vchange(evt))
|
||||
.attr('placeholder', hint);
|
||||
this.el.child(this.input);
|
||||
}
|
||||
|
@ -1,22 +1,26 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import Suggest from './suggest';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class FormSelect {
|
||||
constructor(key, items, width, getTitle = it => it, change = () => {}) {
|
||||
constructor(key, items, width, getTitle = (it) => it, change = () => {}) {
|
||||
this.key = key;
|
||||
this.getTitle = getTitle;
|
||||
this.vchange = () => {};
|
||||
this.el = h('div', `${cssPrefix}-form-select`);
|
||||
this.suggest = new Suggest(items.map(it => ({ key: it, title: this.getTitle(it) })), (it) => {
|
||||
this.itemClick(it.key);
|
||||
change(it.key);
|
||||
this.vchange(it.key);
|
||||
}, width, this.el);
|
||||
this.el.children(
|
||||
this.itemEl = h('div', 'input-text').html(this.getTitle(key)),
|
||||
this.suggest.el,
|
||||
).on('click', () => this.show());
|
||||
this.suggest = new Suggest(
|
||||
items.map((it) => ({ key: it, title: this.getTitle(it) })),
|
||||
(it) => {
|
||||
this.itemClick(it.key);
|
||||
change(it.key);
|
||||
this.vchange(it.key);
|
||||
},
|
||||
width,
|
||||
this.el,
|
||||
);
|
||||
this.el
|
||||
.children((this.itemEl = h('div', 'input-text').html(this.getTitle(key))), this.suggest.el)
|
||||
.on('click', () => this.show());
|
||||
}
|
||||
|
||||
show() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { HComponent, h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h, HComponent } from './element';
|
||||
|
||||
export default class Icon extends HComponent {
|
||||
constructor(name) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* global document */
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export function xtoast(title, content) {
|
||||
const el = h('div', `${cssPrefix}-toast`);
|
||||
|
@ -1,20 +1,23 @@
|
||||
/* global document */
|
||||
/* global window */
|
||||
import { h } from './element';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import { bind, unbind } from './event';
|
||||
import Icon from './icon';
|
||||
|
||||
export default class Modal {
|
||||
constructor(title, content, width = '600px') {
|
||||
this.title = title;
|
||||
this.el = h('div', `${cssPrefix}-modal`).css('width', width).children(
|
||||
h('div', `${cssPrefix}-modal-header`).children(
|
||||
new Icon('close').on('click.stop', () => this.hide()),
|
||||
this.title,
|
||||
),
|
||||
h('div', `${cssPrefix}-modal-content`).children(...content),
|
||||
).hide();
|
||||
this.el = h('div', `${cssPrefix}-modal`)
|
||||
.css('width', width)
|
||||
.children(
|
||||
h('div', `${cssPrefix}-modal-header`).children(
|
||||
new Icon('close').on('click.stop', () => this.hide()),
|
||||
this.title,
|
||||
),
|
||||
h('div', `${cssPrefix}-modal-content`).children(...content),
|
||||
)
|
||||
.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
|
@ -1,35 +1,39 @@
|
||||
import Modal from './modal';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import Button from './button';
|
||||
import { h } from './element';
|
||||
import FormField from './form_field';
|
||||
import FormInput from './form_input';
|
||||
import FormSelect from './form_select';
|
||||
import FormField from './form_field';
|
||||
import Button from './button';
|
||||
import { t } from '../locale/locale';
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import Modal from './modal';
|
||||
|
||||
const fieldLabelWidth = 100;
|
||||
|
||||
export default class ModalValidation extends Modal {
|
||||
constructor() {
|
||||
const mf = new FormField(
|
||||
new FormSelect('cell',
|
||||
new FormSelect(
|
||||
'cell',
|
||||
['cell'], // cell|row|column
|
||||
'100%',
|
||||
it => t(`dataValidation.modeType.${it}`)),
|
||||
(it) => t(`dataValidation.modeType.${it}`),
|
||||
),
|
||||
{ required: true },
|
||||
`${t('dataValidation.range')}:`,
|
||||
fieldLabelWidth,
|
||||
);
|
||||
const rf = new FormField(
|
||||
new FormInput('120px', 'E3 or E3:F12'),
|
||||
{ required: true, pattern: /^([A-Z]{1,2}[1-9]\d*)(:[A-Z]{1,2}[1-9]\d*)?$/ },
|
||||
);
|
||||
const rf = new FormField(new FormInput('120px', 'E3 or E3:F12'), {
|
||||
required: true,
|
||||
pattern: /^([A-Z]{1,2}[1-9]\d*)(:[A-Z]{1,2}[1-9]\d*)?$/,
|
||||
});
|
||||
const cf = new FormField(
|
||||
new FormSelect('list',
|
||||
new FormSelect(
|
||||
'list',
|
||||
['list', 'number', 'date', 'phone', 'email'],
|
||||
'100%',
|
||||
it => t(`dataValidation.type.${it}`),
|
||||
it => this.criteriaSelected(it)),
|
||||
(it) => t(`dataValidation.type.${it}`),
|
||||
(it) => this.criteriaSelected(it),
|
||||
),
|
||||
{ required: true },
|
||||
`${t('dataValidation.criteria')}:`,
|
||||
fieldLabelWidth,
|
||||
@ -37,45 +41,25 @@ export default class ModalValidation extends Modal {
|
||||
|
||||
// operator
|
||||
const of = new FormField(
|
||||
new FormSelect('be',
|
||||
new FormSelect(
|
||||
'be',
|
||||
['be', 'nbe', 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'],
|
||||
'160px',
|
||||
it => t(`dataValidation.operator.${it}`),
|
||||
it => this.criteriaOperatorSelected(it)),
|
||||
(it) => t(`dataValidation.operator.${it}`),
|
||||
(it) => this.criteriaOperatorSelected(it),
|
||||
),
|
||||
{ required: true },
|
||||
).hide();
|
||||
// min, max
|
||||
const minvf = new FormField(
|
||||
new FormInput('70px', '10'),
|
||||
{ required: true },
|
||||
).hide();
|
||||
const maxvf = new FormField(
|
||||
new FormInput('70px', '100'),
|
||||
{ required: true, type: 'number' },
|
||||
).hide();
|
||||
const minvf = new FormField(new FormInput('70px', '10'), { required: true }).hide();
|
||||
const maxvf = new FormField(new FormInput('70px', '100'), { required: true, type: 'number' }).hide();
|
||||
// value
|
||||
const svf = new FormField(
|
||||
new FormInput('120px', 'a,b,c'),
|
||||
{ required: true },
|
||||
);
|
||||
const vf = new FormField(
|
||||
new FormInput('70px', '10'),
|
||||
{ required: true, type: 'number' },
|
||||
).hide();
|
||||
const svf = new FormField(new FormInput('120px', 'a,b,c'), { required: true });
|
||||
const vf = new FormField(new FormInput('70px', '10'), { required: true, type: 'number' }).hide();
|
||||
|
||||
super(t('contextmenu.validation'), [
|
||||
h('div', `${cssPrefix}-form-fields`).children(
|
||||
mf.el,
|
||||
rf.el,
|
||||
),
|
||||
h('div', `${cssPrefix}-form-fields`).children(
|
||||
cf.el,
|
||||
of.el,
|
||||
minvf.el,
|
||||
maxvf.el,
|
||||
vf.el,
|
||||
svf.el,
|
||||
),
|
||||
h('div', `${cssPrefix}-form-fields`).children(mf.el, rf.el),
|
||||
h('div', `${cssPrefix}-form-fields`).children(cf.el, of.el, minvf.el, maxvf.el, vf.el, svf.el),
|
||||
h('div', `${cssPrefix}-buttons`).children(
|
||||
new Button('cancel').on('click', () => this.btnClick('cancel')),
|
||||
new Button('remove').on('click', () => this.btnClick('remove')),
|
||||
@ -101,9 +85,7 @@ export default class ModalValidation extends Modal {
|
||||
}
|
||||
|
||||
criteriaSelected(it) {
|
||||
const {
|
||||
of, minvf, maxvf, vf, svf,
|
||||
} = this;
|
||||
const { of, minvf, maxvf, vf, svf } = this;
|
||||
if (it === 'date' || it === 'number') {
|
||||
of.show();
|
||||
minvf.rule.type = it;
|
||||
@ -134,9 +116,7 @@ export default class ModalValidation extends Modal {
|
||||
|
||||
criteriaOperatorSelected(it) {
|
||||
if (!it) return;
|
||||
const {
|
||||
minvf, maxvf, vf,
|
||||
} = this;
|
||||
const { minvf, maxvf, vf } = this;
|
||||
if (it === 'be' || it === 'nbe') {
|
||||
minvf.show();
|
||||
maxvf.show();
|
||||
@ -186,12 +166,12 @@ export default class ModalValidation extends Modal {
|
||||
}
|
||||
}
|
||||
// console.log(mode, ref, type, operator, value);
|
||||
this.change('save',
|
||||
mode,
|
||||
ref,
|
||||
{
|
||||
type, operator, required: false, value,
|
||||
});
|
||||
this.change('save', mode, ref, {
|
||||
type,
|
||||
operator,
|
||||
required: false,
|
||||
value,
|
||||
});
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
@ -199,15 +179,9 @@ export default class ModalValidation extends Modal {
|
||||
// validation: { mode, ref, validator }
|
||||
setValue(v) {
|
||||
if (v) {
|
||||
const {
|
||||
mf, rf, cf, of, svf, vf, minvf, maxvf,
|
||||
} = this;
|
||||
const {
|
||||
mode, ref, validator,
|
||||
} = v;
|
||||
const {
|
||||
type, operator, value,
|
||||
} = validator || { type: 'list' };
|
||||
const { mf, rf, cf, of, svf, vf, minvf, maxvf } = this;
|
||||
const { mode, ref, validator } = v;
|
||||
const { type, operator, value } = validator || { type: 'list' };
|
||||
mf.val(mode || 'cell');
|
||||
rf.val(ref);
|
||||
cf.val(type);
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* global window document */
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import Button from './button';
|
||||
import { Draw } from '../canvas';
|
||||
import { renderCell } from './table';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import Button from './button';
|
||||
import { h } from './element';
|
||||
import { renderCell } from './table';
|
||||
|
||||
// resolution: 72 => 595 x 842
|
||||
// 150 => 1240 x 1754
|
||||
|
@ -1,20 +1,24 @@
|
||||
/* global window */
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import { mouseMoveUp } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default class Resizer {
|
||||
constructor(vertical = false, minDistance) {
|
||||
this.moving = false;
|
||||
this.vertical = vertical;
|
||||
this.el = h('div', `${cssPrefix}-resizer ${vertical ? 'vertical' : 'horizontal'}`).children(
|
||||
this.unhideHoverEl = h('div', `${cssPrefix}-resizer-hover`)
|
||||
.on('dblclick.stop', evt => this.mousedblclickHandler(evt))
|
||||
.css('position', 'absolute').hide(),
|
||||
this.hoverEl = h('div', `${cssPrefix}-resizer-hover`)
|
||||
.on('mousedown.stop', evt => this.mousedownHandler(evt)),
|
||||
this.lineEl = h('div', `${cssPrefix}-resizer-line`).hide(),
|
||||
).hide();
|
||||
this.el = h('div', `${cssPrefix}-resizer ${vertical ? 'vertical' : 'horizontal'}`)
|
||||
.children(
|
||||
(this.unhideHoverEl = h('div', `${cssPrefix}-resizer-hover`)
|
||||
.on('dblclick.stop', (evt) => this.mousedblclickHandler(evt))
|
||||
.css('position', 'absolute')
|
||||
.hide()),
|
||||
(this.hoverEl = h('div', `${cssPrefix}-resizer-hover`).on('mousedown.stop', (evt) =>
|
||||
this.mousedownHandler(evt),
|
||||
)),
|
||||
(this.lineEl = h('div', `${cssPrefix}-resizer-line`).hide()),
|
||||
)
|
||||
.hide();
|
||||
// cell rect
|
||||
this.cRect = null;
|
||||
this.finishedFn = null;
|
||||
@ -34,15 +38,10 @@ export default class Resizer {
|
||||
// rect : {top, left, width, height}
|
||||
// line : {width, height}
|
||||
show(rect, line) {
|
||||
const {
|
||||
moving, vertical, hoverEl, lineEl, el,
|
||||
unhideHoverEl,
|
||||
} = this;
|
||||
const { moving, vertical, hoverEl, lineEl, el, unhideHoverEl } = this;
|
||||
if (moving) return;
|
||||
this.cRect = rect;
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = rect;
|
||||
const { left, top, width, height } = rect;
|
||||
el.offset({
|
||||
left: vertical ? left + width - 5 : left,
|
||||
top: vertical ? top : top + height - 5,
|
||||
@ -64,10 +63,12 @@ export default class Resizer {
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.el.offset({
|
||||
left: 0,
|
||||
top: 0,
|
||||
}).hide();
|
||||
this.el
|
||||
.offset({
|
||||
left: 0,
|
||||
top: 0,
|
||||
})
|
||||
.hide();
|
||||
this.hideUnhide();
|
||||
}
|
||||
|
||||
@ -77,38 +78,40 @@ export default class Resizer {
|
||||
|
||||
mousedownHandler(evt) {
|
||||
let startEvt = evt;
|
||||
const {
|
||||
el, lineEl, cRect, vertical, minDistance,
|
||||
} = this;
|
||||
const { el, lineEl, cRect, vertical, minDistance } = this;
|
||||
let distance = vertical ? cRect.width : cRect.height;
|
||||
// console.log('distance:', distance);
|
||||
lineEl.show();
|
||||
mouseMoveUp(window, (e) => {
|
||||
this.moving = true;
|
||||
if (startEvt !== null && e.buttons === 1) {
|
||||
// console.log('top:', top, ', left:', top, ', cRect:', cRect);
|
||||
if (vertical) {
|
||||
distance += e.movementX;
|
||||
if (distance > minDistance) {
|
||||
el.css('left', `${cRect.left + distance}px`);
|
||||
}
|
||||
} else {
|
||||
distance += e.movementY;
|
||||
if (distance > minDistance) {
|
||||
el.css('top', `${cRect.top + distance}px`);
|
||||
mouseMoveUp(
|
||||
window,
|
||||
(e) => {
|
||||
this.moving = true;
|
||||
if (startEvt !== null && e.buttons === 1) {
|
||||
// console.log('top:', top, ', left:', top, ', cRect:', cRect);
|
||||
if (vertical) {
|
||||
distance += e.movementX;
|
||||
if (distance > minDistance) {
|
||||
el.css('left', `${cRect.left + distance}px`);
|
||||
}
|
||||
} else {
|
||||
distance += e.movementY;
|
||||
if (distance > minDistance) {
|
||||
el.css('top', `${cRect.top + distance}px`);
|
||||
}
|
||||
}
|
||||
startEvt = e;
|
||||
}
|
||||
startEvt = e;
|
||||
}
|
||||
}, () => {
|
||||
startEvt = null;
|
||||
lineEl.hide();
|
||||
this.moving = false;
|
||||
this.hide();
|
||||
if (this.finishedFn) {
|
||||
if (distance < minDistance) distance = minDistance;
|
||||
this.finishedFn(cRect, distance);
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
startEvt = null;
|
||||
lineEl.hide();
|
||||
this.moving = false;
|
||||
this.hide();
|
||||
if (this.finishedFn) {
|
||||
if (distance < minDistance) distance = minDistance;
|
||||
this.finishedFn(cRect, distance);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { h, HComponent } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { h, HComponent } from './element';
|
||||
|
||||
export default class Scrollbar {
|
||||
private el: HComponent;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { h } from './element';
|
||||
import { cssPrefix } from '../config';
|
||||
import { CellRange } from '../core/cell_range';
|
||||
import { h } from './element';
|
||||
|
||||
const selectorHeightBorderWidth = 2 * 2 - 1;
|
||||
let startZIndex = 10;
|
||||
@ -11,8 +11,7 @@ class SelectorElement {
|
||||
this.autoFocus = autoFocus;
|
||||
this.inputChange = () => {};
|
||||
this.cornerEl = h('div', `${cssPrefix}-selector-corner`);
|
||||
this.areaEl = h('div', `${cssPrefix}-selector-area`)
|
||||
.child(this.cornerEl).hide();
|
||||
this.areaEl = h('div', `${cssPrefix}-selector-area`).child(this.cornerEl).hide();
|
||||
this.clipboardEl = h('div', `${cssPrefix}-selector-clipboard`).hide();
|
||||
this.autofillEl = h('div', `${cssPrefix}-selector-autofill`).hide();
|
||||
this.el = h('div', `${cssPrefix}-selector`)
|
||||
@ -20,12 +19,11 @@ class SelectorElement {
|
||||
.children(this.areaEl, this.clipboardEl, this.autofillEl)
|
||||
.hide();
|
||||
if (useHideInput) {
|
||||
this.hideInput = h('input', '')
|
||||
.on('compositionend', (evt) => {
|
||||
this.inputChange(evt.target.value);
|
||||
});
|
||||
this.el.child(this.hideInputDiv = h('div', 'hide-input').child(this.hideInput));
|
||||
this.el.child(this.hideInputDiv = h('div', 'hide-input').child(this.hideInput));
|
||||
this.hideInput = h('input', '').on('compositionend', (evt) => {
|
||||
this.inputChange(evt.target.value);
|
||||
});
|
||||
this.el.child((this.hideInputDiv = h('div', 'hide-input').child(this.hideInput)));
|
||||
this.el.child((this.hideInputDiv = h('div', 'hide-input').child(this.hideInput)));
|
||||
}
|
||||
startZIndex += 1;
|
||||
}
|
||||
@ -41,9 +39,7 @@ class SelectorElement {
|
||||
}
|
||||
|
||||
setAreaOffset(v) {
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = v;
|
||||
const { left, top, width, height } = v;
|
||||
const of = {
|
||||
width: width - selectorHeightBorderWidth + 0.8,
|
||||
height: height - selectorHeightBorderWidth + 0.8,
|
||||
@ -62,9 +58,7 @@ class SelectorElement {
|
||||
}
|
||||
|
||||
setClipboardOffset(v) {
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = v;
|
||||
const { left, top, width, height } = v;
|
||||
this.clipboardEl.offset({
|
||||
left,
|
||||
top,
|
||||
@ -74,15 +68,15 @@ class SelectorElement {
|
||||
}
|
||||
|
||||
showAutofill(v) {
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = v;
|
||||
this.autofillEl.offset({
|
||||
width: width - selectorHeightBorderWidth,
|
||||
height: height - selectorHeightBorderWidth,
|
||||
left,
|
||||
top,
|
||||
}).show();
|
||||
const { left, top, width, height } = v;
|
||||
this.autofillEl
|
||||
.offset({
|
||||
width: width - selectorHeightBorderWidth,
|
||||
height: height - selectorHeightBorderWidth,
|
||||
left,
|
||||
top,
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
hideAutofill() {
|
||||
@ -100,9 +94,7 @@ class SelectorElement {
|
||||
|
||||
function calBRAreaOffset(offset) {
|
||||
const { data } = this;
|
||||
const {
|
||||
left, top, width, height, scroll, l, t,
|
||||
} = offset;
|
||||
const { left, top, width, height, scroll, l, t } = offset;
|
||||
const ftwidth = data.freezeTotalWidth();
|
||||
const ftheight = data.freezeTotalHeight();
|
||||
let left0 = left - ftwidth;
|
||||
@ -119,28 +111,30 @@ function calBRAreaOffset(offset) {
|
||||
|
||||
function calTAreaOffset(offset) {
|
||||
const { data } = this;
|
||||
const {
|
||||
left, width, height, l, t, scroll,
|
||||
} = offset;
|
||||
const { left, width, height, l, t, scroll } = offset;
|
||||
const ftwidth = data.freezeTotalWidth();
|
||||
let left0 = left - ftwidth;
|
||||
if (ftwidth > l) left0 -= scroll.x;
|
||||
return {
|
||||
left: left0, top: t, width, height,
|
||||
left: left0,
|
||||
top: t,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
function calLAreaOffset(offset) {
|
||||
const { data } = this;
|
||||
const {
|
||||
top, width, height, l, t, scroll,
|
||||
} = offset;
|
||||
const { top, width, height, l, t, scroll } = offset;
|
||||
const ftheight = data.freezeTotalHeight();
|
||||
let top0 = top - ftheight;
|
||||
// console.log('ftheight:', ftheight, ', t:', t);
|
||||
if (ftheight > t) top0 -= scroll.y;
|
||||
return {
|
||||
left: l, top: top0, width, height,
|
||||
left: l,
|
||||
top: top0,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
@ -216,13 +210,7 @@ export default class Selector {
|
||||
this.indexes = null;
|
||||
this.range = null;
|
||||
this.arange = null;
|
||||
this.el = h('div', `${cssPrefix}-selectors`)
|
||||
.children(
|
||||
this.tl.el,
|
||||
this.t.el,
|
||||
this.l.el,
|
||||
this.br.el,
|
||||
).hide();
|
||||
this.el = h('div', `${cssPrefix}-selectors`).children(this.tl.el, this.t.el, this.l.el, this.br.el).hide();
|
||||
|
||||
// for performance
|
||||
this.lastri = -1;
|
||||
@ -242,9 +230,7 @@ export default class Selector {
|
||||
}
|
||||
|
||||
resetOffset() {
|
||||
const {
|
||||
data, tl, t, l, br,
|
||||
} = this;
|
||||
const { data, tl, t, l, br } = this;
|
||||
const freezeHeight = data.freezeTotalHeight();
|
||||
const freezeWidth = data.freezeTotalWidth();
|
||||
if (freezeHeight > 0 || freezeWidth > 0) {
|
||||
@ -331,9 +317,7 @@ export default class Selector {
|
||||
// console.log('ri:', ri, ', ci:', ci);
|
||||
// const [sri, sci] = this.sIndexes;
|
||||
// const [eri, eci] = this.eIndexes;
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this.range;
|
||||
const { sri, sci, eri, eci } = this.range;
|
||||
const [nri, nci] = [ri, ci];
|
||||
// const rn = eri - sri;
|
||||
// const cn = eci - sci;
|
||||
@ -381,9 +365,7 @@ export default class Selector {
|
||||
const offset = this.data.getRect(this.arange);
|
||||
offset.width += 2;
|
||||
offset.height += 2;
|
||||
const {
|
||||
br, l, t, tl,
|
||||
} = this;
|
||||
const { br, l, t, tl } = this;
|
||||
br.showAutofill(calBRAreaOffset.call(this, offset));
|
||||
l.showAutofill(calLAreaOffset.call(this, offset));
|
||||
t.showAutofill(calTAreaOffset.call(this, offset));
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* global window */
|
||||
import { cssPrefix } from '../config';
|
||||
import { formulas } from '../core/formula';
|
||||
import ContextMenu from './contextmenu';
|
||||
import Editor from './editor';
|
||||
import { h } from './element';
|
||||
import { bind, mouseMoveUp, bindTouch, createEventEmitter } from './event';
|
||||
import { bind, bindTouch, createEventEmitter, mouseMoveUp } from './event';
|
||||
import { xtoast } from './message';
|
||||
import ModalValidation from './modal_validation';
|
||||
import Print from './print';
|
||||
import Resizer from './resizer';
|
||||
import Scrollbar from './scrollbar';
|
||||
import Selector from './selector';
|
||||
import Editor from './editor';
|
||||
import Print from './print';
|
||||
import ContextMenu from './contextmenu';
|
||||
import SortFilter from './sort_filter';
|
||||
import Table from './table';
|
||||
import Toolbar from './toolbar/index';
|
||||
import ModalValidation from './modal_validation';
|
||||
import SortFilter from './sort_filter';
|
||||
import { xtoast } from './message';
|
||||
import { cssPrefix } from '../config';
|
||||
import { formulas } from '../core/formula';
|
||||
|
||||
/**
|
||||
* @desc throttle fn
|
||||
|
@ -1,15 +1,16 @@
|
||||
import { h } from './element';
|
||||
import Button from './button';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import Button from './button';
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
|
||||
function buildMenu(clsName) {
|
||||
return h('div', `${cssPrefix}-item ${clsName}`);
|
||||
}
|
||||
|
||||
function buildSortItem(it) {
|
||||
return buildMenu('state').child(t(`sort.${it}`))
|
||||
return buildMenu('state')
|
||||
.child(t(`sort.${it}`))
|
||||
.on('click.stop', () => this.itemClick(it));
|
||||
}
|
||||
|
||||
@ -20,9 +21,11 @@ function buildFilterBody(items) {
|
||||
itemKeys.forEach((it, index) => {
|
||||
const cnt = items[it];
|
||||
const active = filterValues.includes(it) ? 'checked' : '';
|
||||
filterbEl.child(h('div', `${cssPrefix}-item state ${active}`)
|
||||
.on('click.stop', () => this.filterClick(index, it))
|
||||
.children(it === '' ? t('filter.empty') : it, h('div', 'label').html(`(${cnt})`)));
|
||||
filterbEl.child(
|
||||
h('div', `${cssPrefix}-item state ${active}`)
|
||||
.on('click.stop', () => this.filterClick(index, it))
|
||||
.children(it === '' ? t('filter.empty') : it, h('div', 'label').html(`(${cnt})`)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,19 +39,18 @@ export default class SortFilter {
|
||||
constructor() {
|
||||
this.filterbEl = h('div', `${cssPrefix}-body`);
|
||||
this.filterhEl = h('div', `${cssPrefix}-header state`).on('click.stop', () => this.filterClick(0, 'all'));
|
||||
this.el = h('div', `${cssPrefix}-sort-filter`).children(
|
||||
this.sortAscEl = buildSortItem.call(this, 'asc'),
|
||||
this.sortDescEl = buildSortItem.call(this, 'desc'),
|
||||
buildMenu('divider'),
|
||||
h('div', `${cssPrefix}-filter`).children(
|
||||
this.filterhEl,
|
||||
this.filterbEl,
|
||||
),
|
||||
h('div', `${cssPrefix}-buttons`).children(
|
||||
new Button('cancel').on('click', () => this.btnClick('cancel')),
|
||||
new Button('ok', 'primary').on('click', () => this.btnClick('ok')),
|
||||
),
|
||||
).hide();
|
||||
this.el = h('div', `${cssPrefix}-sort-filter`)
|
||||
.children(
|
||||
(this.sortAscEl = buildSortItem.call(this, 'asc')),
|
||||
(this.sortDescEl = buildSortItem.call(this, 'desc')),
|
||||
buildMenu('divider'),
|
||||
h('div', `${cssPrefix}-filter`).children(this.filterhEl, this.filterbEl),
|
||||
h('div', `${cssPrefix}-buttons`).children(
|
||||
new Button('cancel').on('click', () => this.btnClick('cancel')),
|
||||
new Button('ok', 'primary').on('click', () => this.btnClick('ok')),
|
||||
),
|
||||
)
|
||||
.hide();
|
||||
// this.setFilters(['test1', 'test2', 'text3']);
|
||||
this.ci = null;
|
||||
this.sortDesc = null;
|
||||
@ -81,17 +83,20 @@ export default class SortFilter {
|
||||
if (it === 'all') {
|
||||
if (children.length === filterValues.length) {
|
||||
this.filterValues = [];
|
||||
children.forEach(i => h(i).checked(false));
|
||||
children.forEach((i) => h(i).checked(false));
|
||||
} else {
|
||||
this.filterValues = Array.from(values);
|
||||
children.forEach(i => h(i).checked(true));
|
||||
children.forEach((i) => h(i).checked(true));
|
||||
}
|
||||
} else {
|
||||
const checked = h(children[index]).toggle('checked');
|
||||
if (checked) {
|
||||
filterValues.push(it);
|
||||
} else {
|
||||
filterValues.splice(filterValues.findIndex(i => i === it), 1);
|
||||
filterValues.splice(
|
||||
filterValues.findIndex((i) => i === it),
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
||||
resetFilterHeader.call(this);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import { bindClickoutside, unbindClickoutside } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
function inputMovePrev(evt) {
|
||||
evt.preventDefault();
|
||||
@ -77,8 +77,7 @@ export default class Suggest {
|
||||
}
|
||||
|
||||
setOffset(v) {
|
||||
this.el.cssRemoveKeys('top', 'bottom')
|
||||
.offset(v);
|
||||
this.el.cssRemoveKeys('top', 'bottom').offset(v);
|
||||
}
|
||||
|
||||
hide() {
|
||||
@ -97,7 +96,7 @@ export default class Suggest {
|
||||
search(word) {
|
||||
let { items } = this;
|
||||
if (!/^\s*$/.test(word)) {
|
||||
items = items.filter(it => (it.key || it).startsWith(word.toUpperCase()));
|
||||
items = items.filter((it) => (it.key || it).startsWith(word.toUpperCase()));
|
||||
}
|
||||
items = items.map((it) => {
|
||||
let { title } = it;
|
||||
@ -125,11 +124,15 @@ export default class Suggest {
|
||||
}
|
||||
const { el } = this;
|
||||
// items[0].toggle();
|
||||
el.html('').children(...items).show();
|
||||
bindClickoutside(el.parent(), () => { this.hide(); });
|
||||
el.html('')
|
||||
.children(...items)
|
||||
.show();
|
||||
bindClickoutside(el.parent(), () => {
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
|
||||
bindInputEvents(input) {
|
||||
input.on('keydown', evt => inputKeydownHandler.call(this, evt));
|
||||
input.on('keydown', (evt) => inputKeydownHandler.call(this, evt));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Draw, DrawBox, npx, thinLineWidth } from '../canvas';
|
||||
import { stringAt } from '../core/alphabet';
|
||||
import { getFontSizePxByPt } from '../core/font';
|
||||
import _cell from '../core/cell';
|
||||
import { formulam } from '../core/formula';
|
||||
import { getFontSizePxByPt } from '../core/font';
|
||||
import { formatm } from '../core/format';
|
||||
import { formulam } from '../core/formula';
|
||||
|
||||
import { Draw, DrawBox, thinLineWidth, npx } from '../canvas';
|
||||
// gobal var
|
||||
const cellPaddingWidth = 5;
|
||||
const tableFixedHeaderCleanStyle = { fillStyle: '#f4f5f8' };
|
||||
|
@ -1,18 +1,18 @@
|
||||
/* global window */
|
||||
import { h } from './element';
|
||||
import { bind } from './event';
|
||||
import tooltip from './tooltip';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import Dropdown from './dropdown';
|
||||
import DropdownAlign from './dropdown_align';
|
||||
import DropdownBorder from './dropdown_border';
|
||||
import DropdownColor from './dropdown_color';
|
||||
import DropdownFont from './dropdown_font';
|
||||
import DropdownFontSize from './dropdown_fontsize';
|
||||
import DropdownFormat from './dropdown_format';
|
||||
import DropdownFormula from './dropdown_formula';
|
||||
import DropdownColor from './dropdown_color';
|
||||
import DropdownAlign from './dropdown_align';
|
||||
import DropdownBorder from './dropdown_border';
|
||||
import Dropdown from './dropdown';
|
||||
import { h } from './element';
|
||||
import { bind } from './event';
|
||||
import Icon from './icon';
|
||||
import { cssPrefix } from '../config';
|
||||
import { t } from '../locale/locale';
|
||||
import tooltip from './tooltip';
|
||||
|
||||
function buildIcon(name) {
|
||||
return new Icon(name);
|
||||
@ -37,18 +37,17 @@ function buildButtonWithIcon(tooltipdata, iconName, change = () => {}) {
|
||||
}
|
||||
|
||||
function bindDropdownChange() {
|
||||
this.ddFormat.change = it => this.change('format', it.key);
|
||||
this.ddFont.change = it => this.change('font-name', it.key);
|
||||
this.ddFormula.change = it => this.change('formula', it.key);
|
||||
this.ddFontSize.change = it => this.change('font-size', it.pt);
|
||||
this.ddTextColor.change = it => this.change('color', it);
|
||||
this.ddFillColor.change = it => this.change('bgcolor', it);
|
||||
this.ddAlign.change = it => this.change('align', it);
|
||||
this.ddVAlign.change = it => this.change('valign', it);
|
||||
this.ddBorder.change = it => this.change('border', it);
|
||||
this.ddFormat.change = (it) => this.change('format', it.key);
|
||||
this.ddFont.change = (it) => this.change('font-name', it.key);
|
||||
this.ddFormula.change = (it) => this.change('formula', it.key);
|
||||
this.ddFontSize.change = (it) => this.change('font-size', it.pt);
|
||||
this.ddTextColor.change = (it) => this.change('color', it);
|
||||
this.ddFillColor.change = (it) => this.change('bgcolor', it);
|
||||
this.ddAlign.change = (it) => this.change('align', it);
|
||||
this.ddVAlign.change = (it) => this.change('valign', it);
|
||||
this.ddBorder.change = (it) => this.change('border', it);
|
||||
}
|
||||
|
||||
|
||||
function toggleChange(type) {
|
||||
let elName = type;
|
||||
const types = type.split('-');
|
||||
@ -82,9 +81,7 @@ function initBtns2() {
|
||||
}
|
||||
|
||||
function moreResize() {
|
||||
const {
|
||||
el, btns, moreEl, ddMore, btns2,
|
||||
} = this;
|
||||
const { el, btns, moreEl, ddMore, btns2 } = this;
|
||||
const { moreBtns, contentEl } = ddMore;
|
||||
el.css('width', `${this.widthFn() - 60}px`);
|
||||
const elBox = el.box();
|
||||
@ -130,38 +127,58 @@ export default class Toolbar {
|
||||
this.ddBorder = new DropdownBorder();
|
||||
this.ddMore = new DropdownMore();
|
||||
this.btnChildren = [
|
||||
this.undoEl = buildButtonWithIcon(`${t('toolbar.undo')} (Ctrl+Z)`, 'undo', () => this.change('undo')),
|
||||
this.redoEl = buildButtonWithIcon(`${t('toolbar.undo')} (Ctrl+Y)`, 'redo', () => this.change('redo')),
|
||||
(this.undoEl = buildButtonWithIcon(`${t('toolbar.undo')} (Ctrl+Z)`, 'undo', () => this.change('undo'))),
|
||||
(this.redoEl = buildButtonWithIcon(`${t('toolbar.undo')} (Ctrl+Y)`, 'redo', () => this.change('redo'))),
|
||||
// this.printEl = buildButtonWithIcon('Print (Ctrl+P)', 'print', () => this.change('print')),
|
||||
this.paintformatEl = buildButtonWithIcon(`${t('toolbar.paintformat')}`, 'paintformat', () => toggleChange.call(this, 'paintformat')),
|
||||
this.clearformatEl = buildButtonWithIcon(`${t('toolbar.clearformat')}`, 'clearformat', () => this.change('clearformat')),
|
||||
(this.paintformatEl = buildButtonWithIcon(`${t('toolbar.paintformat')}`, 'paintformat', () =>
|
||||
toggleChange.call(this, 'paintformat'),
|
||||
)),
|
||||
(this.clearformatEl = buildButtonWithIcon(`${t('toolbar.clearformat')}`, 'clearformat', () =>
|
||||
this.change('clearformat'),
|
||||
)),
|
||||
buildDivider(),
|
||||
buildButton(`${t('toolbar.format')}`).child(this.ddFormat.el),
|
||||
buildDivider(),
|
||||
buildButton(`${t('toolbar.font')}`).child(this.ddFont.el),
|
||||
buildButton(`${t('toolbar.fontSize')}`).child(this.ddFontSize.el),
|
||||
buildDivider(),
|
||||
this.fontBoldEl = buildButtonWithIcon(`${t('toolbar.fontBold')} (Ctrl+B)`, 'bold', () => toggleChange.call(this, 'font-bold')),
|
||||
this.fontItalicEl = buildButtonWithIcon(`${t('toolbar.fontItalic')} (Ctrl+I)`, 'italic', () => toggleChange.call(this, 'font-italic')),
|
||||
this.underlineEl = buildButtonWithIcon(`${t('toolbar.underline')} (Ctrl+U)`, 'underline', () => toggleChange.call(this, 'underline')),
|
||||
this.strikeEl = buildButtonWithIcon(`${t('toolbar.strike')}`, 'strike', () => toggleChange.call(this, 'strike')),
|
||||
(this.fontBoldEl = buildButtonWithIcon(`${t('toolbar.fontBold')} (Ctrl+B)`, 'bold', () =>
|
||||
toggleChange.call(this, 'font-bold'),
|
||||
)),
|
||||
(this.fontItalicEl = buildButtonWithIcon(`${t('toolbar.fontItalic')} (Ctrl+I)`, 'italic', () =>
|
||||
toggleChange.call(this, 'font-italic'),
|
||||
)),
|
||||
(this.underlineEl = buildButtonWithIcon(`${t('toolbar.underline')} (Ctrl+U)`, 'underline', () =>
|
||||
toggleChange.call(this, 'underline'),
|
||||
)),
|
||||
(this.strikeEl = buildButtonWithIcon(`${t('toolbar.strike')}`, 'strike', () =>
|
||||
toggleChange.call(this, 'strike'),
|
||||
)),
|
||||
buildButton(`${t('toolbar.textColor')}`).child(this.ddTextColor.el),
|
||||
buildDivider(),
|
||||
buildButton(`${t('toolbar.fillColor')}`).child(this.ddFillColor.el),
|
||||
buildButton(`${t('toolbar.border')}`).child(this.ddBorder.el),
|
||||
this.mergeEl = buildButtonWithIcon(`${t('toolbar.merge')}`, 'merge', () => toggleChange.call(this, 'merge')),
|
||||
(this.mergeEl = buildButtonWithIcon(`${t('toolbar.merge')}`, 'merge', () => toggleChange.call(this, 'merge'))),
|
||||
buildDivider(),
|
||||
buildButton(`${t('toolbar.align')}`).child(this.ddAlign.el),
|
||||
buildButton(`${t('toolbar.valign')}`).child(this.ddVAlign.el),
|
||||
this.textwrapEl = buildButtonWithIcon(`${t('toolbar.textwrap')}`, 'textwrap', () => toggleChange.call(this, 'textwrap')),
|
||||
(this.textwrapEl = buildButtonWithIcon(`${t('toolbar.textwrap')}`, 'textwrap', () =>
|
||||
toggleChange.call(this, 'textwrap'),
|
||||
)),
|
||||
buildDivider(),
|
||||
// this.linkEl = buildButtonWithIcon('Insert link', 'link'),
|
||||
// this.chartEl = buildButtonWithIcon('Insert chart', 'chart'),
|
||||
this.freezeEl = buildButtonWithIcon(`${t('toolbar.freeze')}`, 'freeze', () => toggleChange.call(this, 'freeze')),
|
||||
this.autofilterEl = buildButtonWithIcon(`${t('toolbar.autofilter')}`, 'autofilter', () => toggleChange.call(this, 'autofilter')),
|
||||
(this.freezeEl = buildButtonWithIcon(`${t('toolbar.freeze')}`, 'freeze', () =>
|
||||
toggleChange.call(this, 'freeze'),
|
||||
)),
|
||||
(this.autofilterEl = buildButtonWithIcon(`${t('toolbar.autofilter')}`, 'autofilter', () =>
|
||||
toggleChange.call(this, 'autofilter'),
|
||||
)),
|
||||
buildButton(`${t('toolbar.formula')}`).child(this.ddFormula.el),
|
||||
// buildDivider(),
|
||||
this.moreEl = buildButton(`${t('toolbar.more')}`).child(this.ddMore.el).hide(),
|
||||
(this.moreEl = buildButton(`${t('toolbar.more')}`)
|
||||
.child(this.ddMore.el)
|
||||
.hide()),
|
||||
];
|
||||
this.el = h('div', `${cssPrefix}-toolbar`);
|
||||
this.btns = h('div', `${cssPrefix}-toolbar-btns`).children(...this.btnChildren);
|
||||
@ -197,8 +214,7 @@ export default class Toolbar {
|
||||
// console.log('canUndo:', data.canUndo());
|
||||
this.undoEl.disabled(!data.canUndo());
|
||||
this.redoEl.disabled(!data.canRedo());
|
||||
this.mergeEl.active(data.canUnmerge())
|
||||
.disabled(!data.selector.multiple());
|
||||
this.mergeEl.active(data.canUnmerge()).disabled(!data.selector.multiple());
|
||||
this.autofilterEl.active(!data.canAutofilter());
|
||||
// this.mergeEl.disabled();
|
||||
// console.log('selectedCell:', style, cell);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownAlign from '../dropdown_align';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Align extends DropdownItem {
|
||||
constructor(value) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownBorder from '../dropdown_border';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Border extends DropdownItem {
|
||||
constructor() {
|
||||
|
@ -10,10 +10,8 @@ export default class DropdownItem extends Item {
|
||||
element() {
|
||||
const { tag } = this;
|
||||
this.dd = this.dropdown();
|
||||
this.dd.change = it => this.change(tag, this.getValue(it));
|
||||
return super.element().child(
|
||||
this.dd,
|
||||
);
|
||||
this.dd.change = (it) => this.change(tag, this.getValue(it));
|
||||
return super.element().child(this.dd);
|
||||
}
|
||||
|
||||
setState(v) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownColor from '../dropdown_color';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class FillColor extends DropdownItem {
|
||||
constructor(color) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownFont from '../dropdown_font';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Font extends DropdownItem {
|
||||
constructor() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownFontsize from '../dropdown_fontsize';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Format extends DropdownItem {
|
||||
constructor() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownFormat from '../dropdown_format';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Format extends DropdownItem {
|
||||
constructor() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownFormula from '../dropdown_formula';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Format extends DropdownItem {
|
||||
constructor() {
|
||||
|
@ -1,9 +1,10 @@
|
||||
import Item from './item';
|
||||
import Icon from '../icon';
|
||||
import Item from './item';
|
||||
|
||||
export default class IconItem extends Item {
|
||||
element() {
|
||||
return super.element()
|
||||
return super
|
||||
.element()
|
||||
.child(new Icon(this.tag))
|
||||
.on('click', () => this.change(this.tag));
|
||||
}
|
||||
|
@ -1,33 +1,32 @@
|
||||
/* global window */
|
||||
|
||||
import { cssPrefix } from '../../config';
|
||||
import { h } from '../element';
|
||||
import { bind } from '../event';
|
||||
import Align from './align';
|
||||
import Valign from './valign';
|
||||
import Autofilter from './autofilter';
|
||||
import Bold from './bold';
|
||||
import Italic from './italic';
|
||||
import Strike from './strike';
|
||||
import Underline from './underline';
|
||||
import Border from './border';
|
||||
import Clearformat from './clearformat';
|
||||
import Paintformat from './paintformat';
|
||||
import TextColor from './text_color';
|
||||
import FillColor from './fill_color';
|
||||
import FontSize from './font_size';
|
||||
import Font from './font';
|
||||
import FontSize from './font_size';
|
||||
import Format from './format';
|
||||
import Formula from './formula';
|
||||
import Freeze from './freeze';
|
||||
import Merge from './merge';
|
||||
import Redo from './redo';
|
||||
import Undo from './undo';
|
||||
import Print from './print';
|
||||
import Textwrap from './textwrap';
|
||||
import More from './more';
|
||||
import Italic from './italic';
|
||||
import Item from './item';
|
||||
|
||||
import { h } from '../element';
|
||||
import { cssPrefix } from '../../config';
|
||||
import { bind } from '../event';
|
||||
import Merge from './merge';
|
||||
import More from './more';
|
||||
import Paintformat from './paintformat';
|
||||
import Print from './print';
|
||||
import Redo from './redo';
|
||||
import Strike from './strike';
|
||||
import TextColor from './text_color';
|
||||
import Textwrap from './textwrap';
|
||||
import Underline from './underline';
|
||||
import Undo from './undo';
|
||||
import Valign from './valign';
|
||||
|
||||
function buildDivider() {
|
||||
return h('div', `${cssPrefix}-toolbar-divider`);
|
||||
@ -51,9 +50,7 @@ function initBtns2() {
|
||||
}
|
||||
|
||||
function moreResize() {
|
||||
const {
|
||||
el, btns, moreEl, btns2,
|
||||
} = this;
|
||||
const { el, btns, moreEl, btns2 } = this;
|
||||
const { moreBtns, contentEl } = moreEl.dd;
|
||||
el.css('width', `${this.widthFn()}px`);
|
||||
const elBox = el.box();
|
||||
@ -112,47 +109,34 @@ export default class Toolbar {
|
||||
const style = data.defaultStyle();
|
||||
this.items = [
|
||||
[
|
||||
this.undoEl = new Undo(),
|
||||
this.redoEl = new Redo(),
|
||||
(this.undoEl = new Undo()),
|
||||
(this.redoEl = new Redo()),
|
||||
new Print(),
|
||||
this.paintformatEl = new Paintformat(),
|
||||
this.clearformatEl = new Clearformat(),
|
||||
(this.paintformatEl = new Paintformat()),
|
||||
(this.clearformatEl = new Clearformat()),
|
||||
],
|
||||
buildDivider(),
|
||||
[
|
||||
this.formatEl = new Format(),
|
||||
],
|
||||
[(this.formatEl = new Format())],
|
||||
buildDivider(),
|
||||
[(this.fontEl = new Font()), (this.fontSizeEl = new FontSize())],
|
||||
buildDivider(),
|
||||
[
|
||||
this.fontEl = new Font(),
|
||||
this.fontSizeEl = new FontSize(),
|
||||
(this.boldEl = new Bold()),
|
||||
(this.italicEl = new Italic()),
|
||||
(this.underlineEl = new Underline()),
|
||||
(this.strikeEl = new Strike()),
|
||||
(this.textColorEl = new TextColor(style.color)),
|
||||
],
|
||||
buildDivider(),
|
||||
[
|
||||
this.boldEl = new Bold(),
|
||||
this.italicEl = new Italic(),
|
||||
this.underlineEl = new Underline(),
|
||||
this.strikeEl = new Strike(),
|
||||
this.textColorEl = new TextColor(style.color),
|
||||
],
|
||||
[(this.fillColorEl = new FillColor(style.bgcolor)), (this.borderEl = new Border()), (this.mergeEl = new Merge())],
|
||||
buildDivider(),
|
||||
[
|
||||
this.fillColorEl = new FillColor(style.bgcolor),
|
||||
this.borderEl = new Border(),
|
||||
this.mergeEl = new Merge(),
|
||||
(this.alignEl = new Align(style.align)),
|
||||
(this.valignEl = new Valign(style.valign)),
|
||||
(this.textwrapEl = new Textwrap()),
|
||||
],
|
||||
buildDivider(),
|
||||
[
|
||||
this.alignEl = new Align(style.align),
|
||||
this.valignEl = new Valign(style.valign),
|
||||
this.textwrapEl = new Textwrap(),
|
||||
],
|
||||
buildDivider(),
|
||||
[
|
||||
this.freezeEl = new Freeze(),
|
||||
this.autofilterEl = new Autofilter(),
|
||||
this.formulaEl = new Formula(),
|
||||
],
|
||||
[(this.freezeEl = new Freeze()), (this.autofilterEl = new Autofilter()), (this.formulaEl = new Formula())],
|
||||
];
|
||||
|
||||
const { extendToolbar = {} } = data.settings;
|
||||
@ -169,7 +153,7 @@ export default class Toolbar {
|
||||
this.items.push(btns);
|
||||
}
|
||||
|
||||
this.items.push([this.moreEl = new More()]);
|
||||
this.items.push([(this.moreEl = new More())]);
|
||||
|
||||
this.el = h('div', `${cssPrefix}-toolbar`);
|
||||
this.btns = h('div', `${cssPrefix}-toolbar-btns`);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { cssPrefix } from '../../config';
|
||||
import tooltip from '../tooltip';
|
||||
import { h } from '../element';
|
||||
import { t } from '../../locale/locale';
|
||||
import { h } from '../element';
|
||||
import tooltip from '../tooltip';
|
||||
|
||||
export default class Item {
|
||||
// tooltip
|
||||
@ -9,7 +9,7 @@ export default class Item {
|
||||
// shortcut: shortcut key
|
||||
constructor(tag, shortcut, value) {
|
||||
this.tip = '';
|
||||
if (tag) this.tip = t(`toolbar.${tag.replace(/-[a-z]/g, c => c[1].toUpperCase())}`);
|
||||
if (tag) this.tip = t(`toolbar.${tag.replace(/-[a-z]/g, (c) => c[1].toUpperCase())}`);
|
||||
if (shortcut) this.tip += ` (${shortcut})`;
|
||||
this.tag = tag;
|
||||
this.shortcut = shortcut;
|
||||
|
@ -1,9 +1,8 @@
|
||||
import Dropdown from '../dropdown';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
import { cssPrefix } from '../../config';
|
||||
import Dropdown from '../dropdown';
|
||||
import { h } from '../element';
|
||||
import Icon from '../icon';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
class DropdownMore extends Dropdown {
|
||||
constructor() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownColor from '../dropdown_color';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class TextColor extends DropdownItem {
|
||||
constructor(color) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import Item from './item';
|
||||
import Icon from '../icon';
|
||||
import Item from './item';
|
||||
|
||||
export default class ToggleItem extends Item {
|
||||
element() {
|
||||
const { tag } = this;
|
||||
return super.element()
|
||||
return super
|
||||
.element()
|
||||
.child(new Icon(tag))
|
||||
.on('click', () => this.click());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import DropdownItem from './dropdown_item';
|
||||
import DropdownAlign from '../dropdown_align';
|
||||
import DropdownItem from './dropdown_item';
|
||||
|
||||
export default class Valign extends DropdownItem {
|
||||
constructor(value) {
|
||||
|
@ -1,21 +1,18 @@
|
||||
/* global document */
|
||||
import { cssPrefix } from '../config';
|
||||
import { h } from './element';
|
||||
import { bind } from './event';
|
||||
import { cssPrefix } from '../config';
|
||||
|
||||
export default function tooltip(html, target) {
|
||||
if (target.classList.contains('active')) {
|
||||
return;
|
||||
}
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = target.getBoundingClientRect();
|
||||
const { left, top, width, height } = target.getBoundingClientRect();
|
||||
const el = h('div', `${cssPrefix}-tooltip`).html(html).show();
|
||||
document.body.appendChild(el.el);
|
||||
const elBox = el.box();
|
||||
// console.log('elBox:', elBox);
|
||||
el.css('left', `${left + (width / 2) - (elBox.width / 2)}px`)
|
||||
.css('top', `${top + height + 2}px`);
|
||||
el.css('left', `${left + width / 2 - elBox.width / 2}px`).css('top', `${top + height + 2}px`);
|
||||
|
||||
bind(target, 'mouseleave', () => {
|
||||
if (document.body.contains(el.el)) {
|
||||
|
@ -1,6 +1,33 @@
|
||||
import './_.prototypes';
|
||||
|
||||
const alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
const alphabets = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z',
|
||||
];
|
||||
|
||||
/** index number 2 letters
|
||||
* @example stringAt(26) ==> 'AA'
|
||||
@ -30,11 +57,10 @@ export function stringAt(index) {
|
||||
*/
|
||||
export function indexAt(str) {
|
||||
let ret = 0;
|
||||
for(let i = 0; i !== str.length; ++i) ret = 26 * ret + str.charCodeAt(i) - 64;
|
||||
for (let i = 0; i !== str.length; ++i) ret = 26 * ret + str.charCodeAt(i) - 64;
|
||||
return ret - 1;
|
||||
}
|
||||
|
||||
|
||||
// B10 => x,y
|
||||
/** translate A1-tag to XY-tag
|
||||
* @date 2019-10-10
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { CellRange } from './cell_range';
|
||||
|
||||
// operator: all|eq|neq|gt|gte|lt|lte|in|be
|
||||
// value:
|
||||
// in => []
|
||||
@ -65,7 +66,7 @@ export default class AutoFilter {
|
||||
setData({ ref, filters, sort }) {
|
||||
if (ref != null) {
|
||||
this.ref = ref;
|
||||
this.filters = filters.map(it => new Filter(it.ci, it.operator, it.value));
|
||||
this.filters = filters.map((it) => new Filter(it.ci, it.operator, it.value));
|
||||
if (sort) {
|
||||
this.sort = new Sort(sort.ci, sort.order);
|
||||
}
|
||||
@ -75,7 +76,7 @@ export default class AutoFilter {
|
||||
getData() {
|
||||
if (this.active()) {
|
||||
const { ref, filters, sort } = this;
|
||||
return { ref, filters: filters.map(it => it.getData()), sort };
|
||||
return { ref, filters: filters.map((it) => it.getData()), sort };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -171,15 +171,15 @@ const evalSuffixExpr = (srcStack, formulaMap, cellRender, cellList) => {
|
||||
if (!Number.isNaN(left)) left = Number(left);
|
||||
let ret = false;
|
||||
if (fc === '=') {
|
||||
ret = (left === top);
|
||||
ret = left === top;
|
||||
} else if (expr === '>') {
|
||||
ret = (left > top);
|
||||
ret = left > top;
|
||||
} else if (expr === '>=') {
|
||||
ret = (left >= top);
|
||||
ret = left >= top;
|
||||
} else if (expr === '<') {
|
||||
ret = (left < top);
|
||||
ret = left < top;
|
||||
} else if (expr === '<=') {
|
||||
ret = (left <= top);
|
||||
ret = left <= top;
|
||||
}
|
||||
stack.push(ret);
|
||||
} else if (Array.isArray(expr)) {
|
||||
@ -221,6 +221,4 @@ const cellRender = (src, formulaMap, getCellText, cellList = []) => {
|
||||
export default {
|
||||
render: cellRender,
|
||||
};
|
||||
export {
|
||||
infixExprToSuffixExpr,
|
||||
};
|
||||
export { infixExprToSuffixExpr };
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { xy2expr, expr2xy } from './alphabet';
|
||||
import { expr2xy, xy2expr } from './alphabet';
|
||||
|
||||
class CellRange {
|
||||
constructor(sri, sci, eri, eci, w = 0, h = 0) {
|
||||
@ -30,16 +30,12 @@ class CellRange {
|
||||
} else if (args.length === 2) {
|
||||
[ri, ci] = args;
|
||||
}
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci } = this;
|
||||
return sri <= ri && ri <= eri && sci <= ci && ci <= eci;
|
||||
}
|
||||
|
||||
each(cb, rowFilter = () => true) {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci } = this;
|
||||
for (let i = sri; i <= eri; i += 1) {
|
||||
if (rowFilter(i)) {
|
||||
for (let j = sci; j <= eci; j += 1) {
|
||||
@ -50,41 +46,27 @@ class CellRange {
|
||||
}
|
||||
|
||||
contains(other) {
|
||||
return this.sri <= other.sri
|
||||
&& this.sci <= other.sci
|
||||
&& this.eri >= other.eri
|
||||
&& this.eci >= other.eci;
|
||||
return this.sri <= other.sri && this.sci <= other.sci && this.eri >= other.eri && this.eci >= other.eci;
|
||||
}
|
||||
|
||||
// within
|
||||
within(other) {
|
||||
return this.sri >= other.sri
|
||||
&& this.sci >= other.sci
|
||||
&& this.eri <= other.eri
|
||||
&& this.eci <= other.eci;
|
||||
return this.sri >= other.sri && this.sci >= other.sci && this.eri <= other.eri && this.eci <= other.eci;
|
||||
}
|
||||
|
||||
// disjoint
|
||||
disjoint(other) {
|
||||
return this.sri > other.eri
|
||||
|| this.sci > other.eci
|
||||
|| other.sri > this.eri
|
||||
|| other.sci > this.eci;
|
||||
return this.sri > other.eri || this.sci > other.eci || other.sri > this.eri || other.sci > this.eci;
|
||||
}
|
||||
|
||||
// intersects
|
||||
intersects(other) {
|
||||
return this.sri <= other.eri
|
||||
&& this.sci <= other.eci
|
||||
&& other.sri <= this.eri
|
||||
&& other.sci <= this.eci;
|
||||
return this.sri <= other.eri && this.sci <= other.eci && other.sri <= this.eri && other.sci <= this.eci;
|
||||
}
|
||||
|
||||
// union
|
||||
union(other) {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci } = this;
|
||||
return new CellRange(
|
||||
other.sri < sri ? other.sri : sri,
|
||||
other.sci < sci ? other.sci : sci,
|
||||
@ -103,9 +85,7 @@ class CellRange {
|
||||
const addRet = (sri, sci, eri, eci) => {
|
||||
ret.push(new CellRange(sri, sci, eri, eci));
|
||||
};
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci } = this;
|
||||
const dsr = other.sri - sri;
|
||||
const dsc = other.sci - sci;
|
||||
const der = eri - other.eri;
|
||||
@ -168,16 +148,11 @@ class CellRange {
|
||||
}
|
||||
|
||||
size() {
|
||||
return [
|
||||
this.eri - this.sri + 1,
|
||||
this.eci - this.sci + 1,
|
||||
];
|
||||
return [this.eri - this.sri + 1, this.eci - this.sci + 1];
|
||||
}
|
||||
|
||||
toString() {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci } = this;
|
||||
let ref = xy2expr(sci, sri);
|
||||
if (this.multiple()) {
|
||||
ref = `${ref}:${xy2expr(eci, eri)}`;
|
||||
@ -186,9 +161,7 @@ class CellRange {
|
||||
}
|
||||
|
||||
clone() {
|
||||
const {
|
||||
sri, sci, eri, eci, w, h,
|
||||
} = this;
|
||||
const { sri, sci, eri, eci, w, h } = this;
|
||||
return new CellRange(sri, sci, eri, eci, w, h);
|
||||
}
|
||||
|
||||
@ -199,10 +172,7 @@ class CellRange {
|
||||
*/
|
||||
|
||||
equals(other) {
|
||||
return this.eri === other.eri
|
||||
&& this.eci === other.eci
|
||||
&& this.sri === other.sri
|
||||
&& this.sci === other.sci;
|
||||
return this.eri === other.eri && this.eci === other.eci && this.sri === other.sri && this.sci === other.sci;
|
||||
}
|
||||
|
||||
static valueOf(ref) {
|
||||
@ -219,6 +189,4 @@ class CellRange {
|
||||
|
||||
export default CellRange;
|
||||
|
||||
export {
|
||||
CellRange,
|
||||
};
|
||||
export { CellRange };
|
||||
|
@ -1,9 +1,7 @@
|
||||
import helper from './helper';
|
||||
|
||||
class Cols {
|
||||
constructor({
|
||||
len, width, indexWidth, minWidth,
|
||||
}) {
|
||||
constructor({ len, width, indexWidth, minWidth }) {
|
||||
this._ = {};
|
||||
this.len = len;
|
||||
this.width = width;
|
||||
@ -70,7 +68,7 @@ class Cols {
|
||||
}
|
||||
|
||||
sumWidth(min, max) {
|
||||
return helper.rangeSum(min, max, i => this.getWidth(i));
|
||||
return helper.rangeSum(min, max, (i) => this.getWidth(i));
|
||||
}
|
||||
|
||||
totalWidth() {
|
||||
@ -79,6 +77,4 @@ class Cols {
|
||||
}
|
||||
|
||||
export default {};
|
||||
export {
|
||||
Cols,
|
||||
};
|
||||
export { Cols };
|
||||
|
@ -1,18 +1,18 @@
|
||||
/* global document */
|
||||
|
||||
import Selector from './selector';
|
||||
import Scroll from './scroll';
|
||||
import History from './history';
|
||||
import Clipboard from './clipboard';
|
||||
import AutoFilter from './auto_filter';
|
||||
import { Merges } from './merge';
|
||||
import helper from './helper';
|
||||
import { Rows } from './row';
|
||||
import { Cols } from './col';
|
||||
import { Validations } from './validation';
|
||||
import { CellRange } from './cell_range';
|
||||
import { expr2xy, xy2expr } from './alphabet';
|
||||
import { t } from '../locale/locale';
|
||||
import { expr2xy, xy2expr } from './alphabet';
|
||||
import AutoFilter from './auto_filter';
|
||||
import { CellRange } from './cell_range';
|
||||
import Clipboard from './clipboard';
|
||||
import { Cols } from './col';
|
||||
import helper from './helper';
|
||||
import History from './history';
|
||||
import { Merges } from './merge';
|
||||
import { Rows } from './row';
|
||||
import Scroll from './scroll';
|
||||
import Selector from './selector';
|
||||
import { Validations } from './validation';
|
||||
|
||||
// private methods
|
||||
/*
|
||||
@ -148,9 +148,7 @@ function copyPaste(srcCellRange, dstCellRange, what, autofill = false) {
|
||||
function cutPaste(srcCellRange, dstCellRange) {
|
||||
const { clipboard, rows, merges } = this;
|
||||
rows.cutPaste(srcCellRange, dstCellRange);
|
||||
merges.move(srcCellRange,
|
||||
dstCellRange.sri - srcCellRange.sri,
|
||||
dstCellRange.sci - srcCellRange.sci);
|
||||
merges.move(srcCellRange, dstCellRange.sri - srcCellRange.sri, dstCellRange.sci - srcCellRange.sci);
|
||||
clipboard.clear();
|
||||
}
|
||||
|
||||
@ -168,9 +166,7 @@ function setStyleBorder(ri, ci, bss) {
|
||||
|
||||
function setStyleBorders({ mode, style, color }) {
|
||||
const { styles, selector, rows } = this;
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = selector.range;
|
||||
const { sri, sci, eri, eci } = selector.range;
|
||||
const multiple = !this.isSingleSelected();
|
||||
if (!multiple) {
|
||||
if (mode === 'inside' || mode === 'horizontal' || mode === 'vertical') {
|
||||
@ -179,7 +175,10 @@ function setStyleBorders({ mode, style, color }) {
|
||||
}
|
||||
if (mode === 'outside' && !multiple) {
|
||||
setStyleBorder.call(this, sri, sci, {
|
||||
top: [style, color], bottom: [style, color], left: [style, color], right: [style, color],
|
||||
top: [style, color],
|
||||
bottom: [style, color],
|
||||
left: [style, color],
|
||||
right: [style, color],
|
||||
});
|
||||
} else if (mode === 'none') {
|
||||
selector.range.each((ri, ci) => {
|
||||
@ -193,8 +192,13 @@ function setStyleBorders({ mode, style, color }) {
|
||||
cell.style = this.addStyle(ns);
|
||||
}
|
||||
});
|
||||
} else if (mode === 'all' || mode === 'inside' || mode === 'outside'
|
||||
|| mode === 'horizontal' || mode === 'vertical') {
|
||||
} else if (
|
||||
mode === 'all' ||
|
||||
mode === 'inside' ||
|
||||
mode === 'outside' ||
|
||||
mode === 'horizontal' ||
|
||||
mode === 'vertical'
|
||||
) {
|
||||
const merges = [];
|
||||
for (let ri = sri; ri <= eri; ri += 1) {
|
||||
for (let ci = sci; ci <= eci; ci += 1) {
|
||||
@ -210,7 +214,7 @@ function setStyleBorders({ mode, style, color }) {
|
||||
}
|
||||
}
|
||||
}
|
||||
mergeIndexes.forEach(it => merges.splice(it, 1));
|
||||
mergeIndexes.forEach((it) => merges.splice(it, 1));
|
||||
if (ci > eci) break;
|
||||
// jump merges -- end
|
||||
const cell = rows.getCell(ri, ci);
|
||||
@ -308,14 +312,7 @@ function getCellColByX(x, scrollOffsetx) {
|
||||
const fsw = this.freezeTotalWidth();
|
||||
let inits = cols.indexWidth;
|
||||
if (fsw + cols.indexWidth < x) inits -= scrollOffsetx;
|
||||
const [ci, left, width] = helper.rangeReduceIf(
|
||||
0,
|
||||
cols.len,
|
||||
inits,
|
||||
cols.indexWidth,
|
||||
x,
|
||||
i => cols.getWidth(i),
|
||||
);
|
||||
const [ci, left, width] = helper.rangeReduceIf(0, cols.len, inits, cols.indexWidth, x, (i) => cols.getWidth(i));
|
||||
if (left <= 0) {
|
||||
return { ci: -1, left: 0, width: cols.indexWidth };
|
||||
}
|
||||
@ -406,9 +403,7 @@ export default class DataProxy {
|
||||
|
||||
copyToSystemClipboard(evt) {
|
||||
let copyText = [];
|
||||
const {
|
||||
sri, eri, sci, eci,
|
||||
} = this.selector.range;
|
||||
const { sri, eri, sci, eci } = this.selector.range;
|
||||
|
||||
for (let ri = sri; ri <= eri; ri += 1) {
|
||||
const row = [];
|
||||
@ -420,7 +415,7 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
// Adding \n and why not adding \r\n is to support online office and client MS office and WPS
|
||||
copyText = copyText.map(row => row.join('\t')).join('\n');
|
||||
copyText = copyText.map((row) => row.join('\t')).join('\n');
|
||||
|
||||
// why used this
|
||||
// cuz http protocol will be blocked request clipboard by browser
|
||||
@ -433,9 +428,12 @@ export default class DataProxy {
|
||||
// this need https protocol
|
||||
/* global navigator */
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(copyText).then(() => {}, (err) => {
|
||||
console.log('text copy to the system clipboard error ', copyText, err);
|
||||
});
|
||||
navigator.clipboard.writeText(copyText).then(
|
||||
() => {},
|
||||
(err) => {
|
||||
console.log('text copy to the system clipboard error ', copyText, err);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,8 +494,8 @@ export default class DataProxy {
|
||||
pasteFromText(txt) {
|
||||
let lines = [];
|
||||
|
||||
if (/\r\n/.test(txt)) lines = txt.split('\r\n').map(it => it.replace(/"/g, '').split('\t'));
|
||||
else lines = txt.split('\n').map(it => it.replace(/"/g, '').split('\t'));
|
||||
if (/\r\n/.test(txt)) lines = txt.split('\r\n').map((it) => it.replace(/"/g, '').split('\t'));
|
||||
else lines = txt.split('\n').map((it) => it.replace(/"/g, '').split('\t'));
|
||||
|
||||
if (lines.length) {
|
||||
const { rows, selector } = this;
|
||||
@ -522,12 +520,8 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
calSelectedRangeByEnd(ri, ci) {
|
||||
const {
|
||||
selector, rows, cols, merges,
|
||||
} = this;
|
||||
let {
|
||||
sri, sci, eri, eci,
|
||||
} = selector.range;
|
||||
const { selector, rows, cols, merges } = this;
|
||||
let { sri, sci, eri, eci } = selector.range;
|
||||
const cri = selector.ri;
|
||||
const cci = selector.ci;
|
||||
let [nri, nci] = [ri, ci];
|
||||
@ -537,18 +531,14 @@ export default class DataProxy {
|
||||
else [sri, eri] = [nri, cri];
|
||||
if (nci > cci) [sci, eci] = [cci, nci];
|
||||
else [sci, eci] = [nci, cci];
|
||||
selector.range = merges.union(new CellRange(
|
||||
sri, sci, eri, eci,
|
||||
));
|
||||
selector.range = merges.union(new CellRange(sri, sci, eri, eci));
|
||||
selector.range = merges.union(selector.range);
|
||||
// console.log('selector.range:', selector.range);
|
||||
return selector.range;
|
||||
}
|
||||
|
||||
calSelectedRangeByStart(ri, ci) {
|
||||
const {
|
||||
selector, rows, cols, merges,
|
||||
} = this;
|
||||
const { selector, rows, cols, merges } = this;
|
||||
let cellRange = merges.getFirstIncludes(ri, ci);
|
||||
// console.log('cellRange:', cellRange, ri, ci, merges);
|
||||
if (cellRange === null) {
|
||||
@ -579,9 +569,7 @@ export default class DataProxy {
|
||||
const { ri, ci, range } = selector;
|
||||
if (selector.multiple()) {
|
||||
const [rn, cn] = selector.size();
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = range;
|
||||
const { sri, sci, eri, eci } = range;
|
||||
if (rn > 1) {
|
||||
for (let i = sci; i <= eci; i += 1) {
|
||||
const cell = rows.getCellOrNew(eri + 1, i);
|
||||
@ -605,16 +593,25 @@ export default class DataProxy {
|
||||
if (property === 'format') {
|
||||
cstyle.format = value;
|
||||
cell.style = this.addStyle(cstyle);
|
||||
} else if (property === 'font-bold' || property === 'font-italic'
|
||||
|| property === 'font-name' || property === 'font-size') {
|
||||
} else if (
|
||||
property === 'font-bold' ||
|
||||
property === 'font-italic' ||
|
||||
property === 'font-name' ||
|
||||
property === 'font-size'
|
||||
) {
|
||||
const nfont = {};
|
||||
nfont[property.split('-')[1]] = value;
|
||||
cstyle.font = Object.assign(cstyle.font || {}, nfont);
|
||||
cell.style = this.addStyle(cstyle);
|
||||
} else if (property === 'strike' || property === 'textwrap'
|
||||
|| property === 'underline'
|
||||
|| property === 'align' || property === 'valign'
|
||||
|| property === 'color' || property === 'bgcolor') {
|
||||
} else if (
|
||||
property === 'strike' ||
|
||||
property === 'textwrap' ||
|
||||
property === 'underline' ||
|
||||
property === 'align' ||
|
||||
property === 'valign' ||
|
||||
property === 'color' ||
|
||||
property === 'bgcolor'
|
||||
) {
|
||||
cstyle[property] = value;
|
||||
cell.style = this.addStyle(cstyle);
|
||||
} else {
|
||||
@ -640,7 +637,7 @@ export default class DataProxy {
|
||||
if (autoFilter.active()) {
|
||||
const filter = autoFilter.getFilter(ci);
|
||||
if (filter) {
|
||||
const vIndex = filter.value.findIndex(v => v === oldText);
|
||||
const vIndex = filter.value.findIndex((v) => v === oldText);
|
||||
if (vIndex >= 0) {
|
||||
filter.value.splice(vIndex, 1, text);
|
||||
}
|
||||
@ -660,14 +657,11 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
xyInSelectedRect(x, y) {
|
||||
const {
|
||||
left, top, width, height,
|
||||
} = this.getSelectedRect();
|
||||
const { left, top, width, height } = this.getSelectedRect();
|
||||
const x1 = x - this.cols.indexWidth;
|
||||
const y1 = y - this.rows.height;
|
||||
// console.log('x:', x, ',y:', y, 'left:', left, 'top:', top);
|
||||
return x1 > left && x1 < (left + width)
|
||||
&& y1 > top && y1 < (top + height);
|
||||
return x1 > left && x1 < left + width && y1 > top && y1 < top + height;
|
||||
}
|
||||
|
||||
getSelectedRect() {
|
||||
@ -683,17 +677,17 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
getRect(cellRange) {
|
||||
const {
|
||||
scroll, rows, cols, exceptRowSet,
|
||||
} = this;
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = cellRange;
|
||||
const { scroll, rows, cols, exceptRowSet } = this;
|
||||
const { sri, sci, eri, eci } = cellRange;
|
||||
// console.log('sri:', sri, ',sci:', sci, ', eri:', eri, ', eci:', eci);
|
||||
// no selector
|
||||
if (sri < 0 && sci < 0) {
|
||||
return {
|
||||
left: 0, l: 0, top: 0, t: 0, scroll,
|
||||
left: 0,
|
||||
l: 0,
|
||||
top: 0,
|
||||
t: 0,
|
||||
scroll,
|
||||
};
|
||||
}
|
||||
const left = cols.sumWidth(0, sci);
|
||||
@ -723,9 +717,7 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
getCellRectByXY(x, y) {
|
||||
const {
|
||||
scroll, merges, rows, cols,
|
||||
} = this;
|
||||
const { scroll, merges, rows, cols } = this;
|
||||
let { ri, top, height } = getCellRowByY.call(this, y, scroll.y);
|
||||
let { ci, left, width } = getCellColByX.call(this, x, scroll.x);
|
||||
if (ci === -1) {
|
||||
@ -739,20 +731,21 @@ export default class DataProxy {
|
||||
if (merge) {
|
||||
ri = merge.sri;
|
||||
ci = merge.sci;
|
||||
({
|
||||
left, top, width, height,
|
||||
} = this.cellRect(ri, ci));
|
||||
({ left, top, width, height } = this.cellRect(ri, ci));
|
||||
}
|
||||
}
|
||||
return {
|
||||
ri, ci, left, top, width, height,
|
||||
ri,
|
||||
ci,
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
isSingleSelected() {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this.selector.range;
|
||||
const { sri, sci, eri, eci } = this.selector.range;
|
||||
const cell = this.getCell(sri, sci);
|
||||
if (cell && cell.merge) {
|
||||
const [rn, cn] = cell.merge;
|
||||
@ -762,9 +755,7 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
canUnmerge() {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = this.selector.range;
|
||||
const { sri, sci, eri, eci } = this.selector.range;
|
||||
const cell = this.getCell(sri, sci);
|
||||
if (cell && cell.merge) {
|
||||
const [rn, cn] = cell.merge;
|
||||
@ -872,13 +863,15 @@ export default class DataProxy {
|
||||
rows.insertColumn(sci, n);
|
||||
si = sci;
|
||||
cols.len += n;
|
||||
Object.keys(cols._).reverse().forEach((colIndex) => {
|
||||
const col = parseInt(colIndex, 10);
|
||||
if (col >= sci) {
|
||||
cols._[col + n] = cols._[col];
|
||||
delete cols._[col];
|
||||
}
|
||||
});
|
||||
Object.keys(cols._)
|
||||
.reverse()
|
||||
.forEach((colIndex) => {
|
||||
const col = parseInt(colIndex, 10);
|
||||
if (col >= sci) {
|
||||
cols._[col + n] = cols._[col];
|
||||
delete cols._[col];
|
||||
}
|
||||
});
|
||||
}
|
||||
merges.shift(type, si, n, (ri, ci, rn, cn) => {
|
||||
const cell = rows.getCell(ri, ci);
|
||||
@ -891,13 +884,9 @@ export default class DataProxy {
|
||||
// type: row | column
|
||||
delete(type) {
|
||||
this.changeData(() => {
|
||||
const {
|
||||
rows, merges, selector, cols,
|
||||
} = this;
|
||||
const { rows, merges, selector, cols } = this;
|
||||
const { range } = selector;
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = selector.range;
|
||||
const { sri, sci, eri, eci } = selector.range;
|
||||
const [rsize, csize] = selector.range.size();
|
||||
let si = sri;
|
||||
let size = rsize;
|
||||
@ -907,7 +896,7 @@ export default class DataProxy {
|
||||
rows.deleteColumn(sci, eci);
|
||||
si = range.sci;
|
||||
size = csize;
|
||||
cols.len -= (eci - sci + 1);
|
||||
cols.len -= eci - sci + 1;
|
||||
Object.keys(cols._).forEach((colIndex) => {
|
||||
const col = parseInt(colIndex, 10);
|
||||
if (col >= sci) {
|
||||
@ -932,9 +921,7 @@ export default class DataProxy {
|
||||
scrollx(x, cb) {
|
||||
const { scroll, freeze, cols } = this;
|
||||
const [, fci] = freeze;
|
||||
const [
|
||||
ci, left, width,
|
||||
] = helper.rangeReduceIf(fci, cols.len, 0, 0, x, i => cols.getWidth(i));
|
||||
const [ci, left, width] = helper.rangeReduceIf(fci, cols.len, 0, 0, x, (i) => cols.getWidth(i));
|
||||
// console.log('fci:', fci, ', ci:', ci);
|
||||
let x1 = left;
|
||||
if (x > 0) x1 += width;
|
||||
@ -948,9 +935,7 @@ export default class DataProxy {
|
||||
scrolly(y, cb) {
|
||||
const { scroll, freeze, rows } = this;
|
||||
const [fri] = freeze;
|
||||
const [
|
||||
ri, top, height,
|
||||
] = helper.rangeReduceIf(fri, rows.len, 0, 0, y, i => rows.getHeight(i));
|
||||
const [ri, top, height] = helper.rangeReduceIf(fri, rows.len, 0, 0, y, (i) => rows.getHeight(i));
|
||||
let y1 = top;
|
||||
if (y > 0) y1 += height;
|
||||
// console.log('ri:', ri, ' ,y:', y1);
|
||||
@ -986,7 +971,11 @@ export default class DataProxy {
|
||||
}
|
||||
// console.log('data:', this.d);
|
||||
return {
|
||||
left, top, width, height, cell,
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
cell,
|
||||
};
|
||||
}
|
||||
|
||||
@ -996,7 +985,7 @@ export default class DataProxy {
|
||||
|
||||
getCellTextOrDefault(ri, ci) {
|
||||
const cell = this.getCell(ri, ci);
|
||||
return (cell && cell.text) ? cell.text : '';
|
||||
return cell && cell.text ? cell.text : '';
|
||||
}
|
||||
|
||||
getCellStyle(ri, ci) {
|
||||
@ -1010,7 +999,7 @@ export default class DataProxy {
|
||||
getCellStyleOrDefault(ri, ci) {
|
||||
const { styles, rows } = this;
|
||||
const cell = rows.getCell(ri, ci);
|
||||
const cellStyle = (cell && cell.style !== undefined) ? styles[cell.style] : {};
|
||||
const cellStyle = cell && cell.style !== undefined ? styles[cell.style] : {};
|
||||
return helper.merge(this.defaultStyle(), cellStyle);
|
||||
}
|
||||
|
||||
@ -1108,9 +1097,7 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
viewRange() {
|
||||
const {
|
||||
scroll, rows, cols, freeze, exceptRowSet,
|
||||
} = this;
|
||||
const { scroll, rows, cols, freeze, exceptRowSet } = this;
|
||||
// console.log('scroll:', scroll, ', freeze:', freeze)
|
||||
let { ri, ci } = scroll;
|
||||
if (ri <= 0) [ri] = freeze;
|
||||
@ -1135,16 +1122,13 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
eachMergesInView(viewRange, cb) {
|
||||
this.merges.filterIntersects(viewRange)
|
||||
.forEach(it => cb(it));
|
||||
this.merges.filterIntersects(viewRange).forEach((it) => cb(it));
|
||||
}
|
||||
|
||||
hideRowsOrCols() {
|
||||
const { rows, cols, selector } = this;
|
||||
const [rlen, clen] = selector.size();
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = selector.range;
|
||||
const { sri, sci, eri, eci } = selector.range;
|
||||
if (rlen === rows.len) {
|
||||
for (let ci = sci; ci <= eci; ci += 1) {
|
||||
cols.setHide(ci, true);
|
||||
@ -1224,8 +1208,7 @@ export default class DataProxy {
|
||||
|
||||
setData(d) {
|
||||
Object.keys(d).forEach((property) => {
|
||||
if (property === 'merges' || property === 'rows'
|
||||
|| property === 'cols' || property === 'validations') {
|
||||
if (property === 'merges' || property === 'rows' || property === 'cols' || property === 'validations') {
|
||||
this[property].setData(d[property]);
|
||||
} else if (property === 'freeze') {
|
||||
const [x, y] = expr2xy(d[property]);
|
||||
@ -1240,9 +1223,7 @@ export default class DataProxy {
|
||||
}
|
||||
|
||||
getData() {
|
||||
const {
|
||||
name, freeze, styles, merges, rows, cols, validations, autoFilter,
|
||||
} = this;
|
||||
const { name, freeze, styles, merges, rows, cols, validations, autoFilter } = this;
|
||||
return {
|
||||
name,
|
||||
freeze: xy2expr(freeze[1], freeze[0]),
|
||||
|
@ -68,9 +68,4 @@ function fonts(ary = []) {
|
||||
}
|
||||
|
||||
export default {};
|
||||
export {
|
||||
fontSizes,
|
||||
fonts,
|
||||
baseFonts,
|
||||
getFontSizePxByPt,
|
||||
};
|
||||
export { fontSizes, fonts, baseFonts, getFontSizePxByPt };
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { tf } from '../locale/locale';
|
||||
|
||||
const formatStringRender = v => v;
|
||||
const formatStringRender = (v) => v;
|
||||
|
||||
const formatNumberRender = (v) => {
|
||||
// match "-12.1" or "12" or "12.1"
|
||||
@ -37,28 +37,28 @@ const baseFormats = [
|
||||
title: tf('format.percent'),
|
||||
type: 'number',
|
||||
label: '10.12%',
|
||||
render: v => `${v}%`,
|
||||
render: (v) => `${v}%`,
|
||||
},
|
||||
{
|
||||
key: 'rmb',
|
||||
title: tf('format.rmb'),
|
||||
type: 'number',
|
||||
label: '¥10.00',
|
||||
render: v => `¥${formatNumberRender(v)}`,
|
||||
render: (v) => `¥${formatNumberRender(v)}`,
|
||||
},
|
||||
{
|
||||
key: 'usd',
|
||||
title: tf('format.usd'),
|
||||
type: 'number',
|
||||
label: '$10.00',
|
||||
render: v => `$${formatNumberRender(v)}`,
|
||||
render: (v) => `$${formatNumberRender(v)}`,
|
||||
},
|
||||
{
|
||||
key: 'eur',
|
||||
title: tf('format.eur'),
|
||||
type: 'number',
|
||||
label: '€10.00',
|
||||
render: v => `€${formatNumberRender(v)}`,
|
||||
render: (v) => `€${formatNumberRender(v)}`,
|
||||
},
|
||||
{
|
||||
key: 'date',
|
||||
@ -102,9 +102,5 @@ baseFormats.forEach((f) => {
|
||||
formatm[f.key] = f;
|
||||
});
|
||||
|
||||
export default {
|
||||
};
|
||||
export {
|
||||
formatm,
|
||||
baseFormats,
|
||||
};
|
||||
export default {};
|
||||
export { formatm, baseFormats };
|
||||
|
@ -18,22 +18,22 @@ const baseFormulas = [
|
||||
{
|
||||
key: 'SUM',
|
||||
title: tf('formula.sum'),
|
||||
render: ary => ary.reduce((a, b) => numberCalc('+', a, b), 0),
|
||||
render: (ary) => ary.reduce((a, b) => numberCalc('+', a, b), 0),
|
||||
},
|
||||
{
|
||||
key: 'AVERAGE',
|
||||
title: tf('formula.average'),
|
||||
render: ary => ary.reduce((a, b) => Number(a) + Number(b), 0) / ary.length,
|
||||
render: (ary) => ary.reduce((a, b) => Number(a) + Number(b), 0) / ary.length,
|
||||
},
|
||||
{
|
||||
key: 'MAX',
|
||||
title: tf('formula.max'),
|
||||
render: ary => Math.max(...ary.map(v => Number(v))),
|
||||
render: (ary) => Math.max(...ary.map((v) => Number(v))),
|
||||
},
|
||||
{
|
||||
key: 'MIN',
|
||||
title: tf('formula.min'),
|
||||
render: ary => Math.min(...ary.map(v => Number(v))),
|
||||
render: (ary) => Math.min(...ary.map((v) => Number(v))),
|
||||
},
|
||||
{
|
||||
key: 'IF',
|
||||
@ -43,17 +43,17 @@ const baseFormulas = [
|
||||
{
|
||||
key: 'AND',
|
||||
title: tf('formula.and'),
|
||||
render: ary => ary.every(it => it),
|
||||
render: (ary) => ary.every((it) => it),
|
||||
},
|
||||
{
|
||||
key: 'OR',
|
||||
title: tf('formula.or'),
|
||||
render: ary => ary.some(it => it),
|
||||
render: (ary) => ary.some((it) => it),
|
||||
},
|
||||
{
|
||||
key: 'CONCAT',
|
||||
title: tf('formula.concat'),
|
||||
render: ary => ary.join(''),
|
||||
render: (ary) => ary.join(''),
|
||||
},
|
||||
/* support: 1 + A1 + B2 * 3
|
||||
{
|
||||
@ -88,11 +88,6 @@ baseFormulas.forEach((f) => {
|
||||
formulam[f.key] = f;
|
||||
});
|
||||
|
||||
export default {
|
||||
};
|
||||
export default {};
|
||||
|
||||
export {
|
||||
formulam,
|
||||
formulas,
|
||||
baseFormulas,
|
||||
};
|
||||
export { formulam, formulas, baseFormulas };
|
||||
|
@ -48,7 +48,7 @@ function equals(obj1, obj2) {
|
||||
objOrAry: obejct or Array
|
||||
cb: (value, index | key) => { return value }
|
||||
*/
|
||||
const sum = (objOrAry, cb = value => value) => {
|
||||
const sum = (objOrAry, cb = (value) => value) => {
|
||||
let total = 0;
|
||||
let size = 0;
|
||||
Object.keys(objOrAry).forEach((key) => {
|
||||
|
@ -10,7 +10,7 @@ class Merges {
|
||||
}
|
||||
|
||||
deleteWithin(cr) {
|
||||
this._ = this._.filter(it => !it.within(cr));
|
||||
this._ = this._.filter((it) => !it.within(cr));
|
||||
}
|
||||
|
||||
getFirstIncludes(ri, ci) {
|
||||
@ -24,7 +24,7 @@ class Merges {
|
||||
}
|
||||
|
||||
filterIntersects(cellRange) {
|
||||
return new Merges(this._.filter(it => it.intersects(cellRange)));
|
||||
return new Merges(this._.filter((it) => it.intersects(cellRange)));
|
||||
}
|
||||
|
||||
intersects(cellRange) {
|
||||
@ -56,9 +56,7 @@ class Merges {
|
||||
// type: row | column
|
||||
shift(type, index, n, cbWithin) {
|
||||
this._.forEach((cellRange) => {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = cellRange;
|
||||
const { sri, sci, eri, eci } = cellRange;
|
||||
const range = cellRange;
|
||||
if (type === 'row') {
|
||||
if (sri >= index) {
|
||||
@ -93,16 +91,14 @@ class Merges {
|
||||
}
|
||||
|
||||
setData(merges) {
|
||||
this._ = merges.map(merge => CellRange.valueOf(merge));
|
||||
this._ = merges.map((merge) => CellRange.valueOf(merge));
|
||||
return this;
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this._.map(merge => merge.toString());
|
||||
return this._.map((merge) => merge.toString());
|
||||
}
|
||||
}
|
||||
|
||||
export default {};
|
||||
export {
|
||||
Merges,
|
||||
};
|
||||
export { Merges };
|
||||
|
@ -1,5 +1,5 @@
|
||||
import helper from './helper';
|
||||
import { expr2expr } from './alphabet';
|
||||
import helper from './helper';
|
||||
|
||||
class Rows {
|
||||
constructor({ len, height }) {
|
||||
@ -111,9 +111,7 @@ class Rows {
|
||||
|
||||
// what: all | format | text
|
||||
copyPaste(srcCellRange, dstCellRange, what, autofill = false, cb = () => {}) {
|
||||
const {
|
||||
sri, sci, eri, eci,
|
||||
} = srcCellRange;
|
||||
const { sri, sci, eri, eci } = srcCellRange;
|
||||
const dsri = dstCellRange.sri;
|
||||
const dsci = dstCellRange.sci;
|
||||
const deri = dstCellRange.eri;
|
||||
@ -140,7 +138,7 @@ class Rows {
|
||||
// ncell.text
|
||||
if (autofill && ncell && ncell.text && ncell.text.length > 0) {
|
||||
const { text } = ncell;
|
||||
let n = (jj - dsci) + (ii - dsri) + 2;
|
||||
let n = jj - dsci + (ii - dsri) + 2;
|
||||
if (!isAdd) {
|
||||
n -= dn + 1;
|
||||
}
|
||||
@ -156,9 +154,11 @@ class Rows {
|
||||
if (/^\d+$/.test(word)) return word;
|
||||
return expr2expr(word, xn, yn);
|
||||
});
|
||||
} else if ((rn <= 1 && cn > 1 && (dsri > eri || deri < sri))
|
||||
|| (cn <= 1 && rn > 1 && (dsci > eci || deci < sci))
|
||||
|| (rn <= 1 && cn <= 1)) {
|
||||
} else if (
|
||||
(rn <= 1 && cn > 1 && (dsri > eri || deri < sri)) ||
|
||||
(cn <= 1 && rn > 1 && (dsci > eci || deci < sci)) ||
|
||||
(rn <= 1 && cn <= 1)
|
||||
) {
|
||||
const result = /[\\.\d]+$/.exec(text);
|
||||
// console.log('result:', result);
|
||||
if (result !== null) {
|
||||
@ -215,7 +215,7 @@ class Rows {
|
||||
nri += n;
|
||||
this.eachCells(ri, (ci, cell) => {
|
||||
if (cell.text && cell.text[0] === '=') {
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, word => expr2expr(word, 0, n, (x, y) => y >= sri));
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, (word) => expr2expr(word, 0, n, (x, y) => y >= sri));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -236,7 +236,7 @@ class Rows {
|
||||
ndata[nri - n] = row;
|
||||
this.eachCells(ri, (ci, cell) => {
|
||||
if (cell.text && cell.text[0] === '=') {
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, word => expr2expr(word, 0, -n, (x, y) => y > eri));
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, (word) => expr2expr(word, 0, -n, (x, y) => y > eri));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -253,7 +253,7 @@ class Rows {
|
||||
if (nci >= sci) {
|
||||
nci += n;
|
||||
if (cell.text && cell.text[0] === '=') {
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, word => expr2expr(word, n, 0, x => x >= sci));
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, (word) => expr2expr(word, n, 0, (x) => x >= sci));
|
||||
}
|
||||
}
|
||||
rndata[nci] = cell;
|
||||
@ -273,7 +273,7 @@ class Rows {
|
||||
} else if (nci > eci) {
|
||||
rndata[nci - n] = cell;
|
||||
if (cell.text && cell.text[0] === '=') {
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, word => expr2expr(word, -n, 0, x => x > eci));
|
||||
cell.text = cell.text.replace(/[a-zA-Z]{1,3}\d+/g, (word) => expr2expr(word, -n, 0, (x) => x > eci));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -351,6 +351,4 @@ class Rows {
|
||||
}
|
||||
|
||||
export default {};
|
||||
export {
|
||||
Rows,
|
||||
};
|
||||
export { Rows };
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user