diff --git a/packages/s2-core/__tests__/spreadsheet/spread-sheet-with-switcher-spec.tsx b/packages/s2-core/__tests__/spreadsheet/switcher-spec.tsx
similarity index 77%
rename from packages/s2-core/__tests__/spreadsheet/spread-sheet-with-switcher-spec.tsx
rename to packages/s2-core/__tests__/spreadsheet/switcher-spec.tsx
index 9391e4f2e5..648f985ecc 100644
--- a/packages/s2-core/__tests__/spreadsheet/spread-sheet-with-switcher-spec.tsx
+++ b/packages/s2-core/__tests__/spreadsheet/switcher-spec.tsx
@@ -1,10 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
-import { getContainer } from '../util/helpers';
-import { SheetEntry } from '../util/sheet-entry';
+import { getContainer } from 'tests/util/helpers';
import { Switcher } from '@/components/switcher';
-import { SwitcherItem } from '@/components/switcher/interface';
+import { SwitcherFields, SwitcherItem } from '@/components/switcher/interface';
+import 'antd/dist/antd.min.css';
const mockRows: SwitcherItem[] = [
{ id: 'area', displayName: '区域' },
@@ -43,29 +43,30 @@ const mockValues: SwitcherItem[] = [
];
function MainLayout() {
- const values = ['cost', 'price', 'cost/price'];
-
+ const fields: SwitcherFields = {
+ rows: {
+ items: mockRows,
+ },
+ columns: {
+ items: mockCols,
+ },
+ values: {
+ selectable: true,
+ expandable: true,
+ items: mockValues,
+ },
+ };
return (
{
// eslint-disable-next-line no-console
console.log('result: ', result);
}}
/>
-
);
}
diff --git a/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.tsx b/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.tsx
index 7bb5767fad..48dd53a1ce 100644
--- a/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.tsx
+++ b/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.tsx
@@ -15,7 +15,7 @@ import {
TableSheet,
} from '@/index';
import { Switcher } from '@/components/switcher';
-import { SwitcherItem } from '@/components/switcher/interface';
+import { SwitcherFields } from '@/components/switcher/interface';
let s2: TableSheet;
@@ -159,14 +159,18 @@ function MainLayout({ callback }) {
};
}, []);
- const switcherValues: SwitcherItem[] = columns.map((field) => {
- return {
- id: field,
- displayName: find(meta, { field })?.name,
- checked: true,
- };
- });
-
+ const switcherFields: SwitcherFields = {
+ columns: {
+ selectable: true,
+ items: columns.map((field) => {
+ return {
+ id: field,
+ displayName: find(meta, { field })?.name,
+ checked: true,
+ };
+ }),
+ },
+ };
useEffect(() => {
callback({
setShowPagination,
@@ -177,11 +181,11 @@ function MainLayout({ callback }) {
{
console.log('result: ', result);
- const { hiddenValues } = result;
- setHiddenColumnFields(hiddenValues);
+ const { hideItems } = result.columns;
+ setHiddenColumnFields(hideItems.map((i) => i.id));
}}
/>
{
- describe('useVisible Test', () => {
- test('should update visible status correctly when call show or hide function', () => {
- const { result } = renderHook(() => useVisible());
-
- expect(result.current.visible).toBeFalsy();
-
- act(() => {
- result.current.show();
- });
- expect(result.current.visible).toBeTruthy();
-
- act(() => {
- result.current.hide();
- });
- expect(result.current.visible).toBeFalsy();
- });
-
- test('should update visible status correctly when call toggle function', () => {
- const { result } = renderHook(() => useVisible(true));
-
- expect(result.current.visible).toBeTruthy();
-
- act(() => {
- result.current.toggle();
- });
- expect(result.current.visible).toBeFalsy();
-
- act(() => {
- result.current.toggle();
- });
- expect(result.current.visible).toBeTruthy();
- });
- });
-
- describe('useCustomChild Test', () => {
- test('should render default child without specify custom child', () => {
- const { result } = renderHook(() =>
- useCustomChild(default child
),
- );
-
- expect(result.current.props.children).toEqual('default child');
- });
-
- test('should render custom child with specify custom child', () => {
- const { result } = renderHook(() =>
- useCustomChild(default child
, custom child
),
- );
-
- expect(result.current.props.children).toEqual('custom child');
- });
- });
-
- describe('useHide Test', () => {
- test('should return true when every dimension items is empty', () => {
- const mockData: DimensionType[] = [
- {
- type: 'value',
- displayName: '指标',
- items: [],
- },
- ];
- const { result } = renderHook(() => useHide(mockData));
-
- expect(result.current).toBeTruthy();
- });
-
- test('should return true when every dimension has items', () => {
- const mockData: DimensionType[] = [
- {
- type: 'value',
- displayName: '指标',
- items: [
- {
- id: 'price',
- displayName: '价格',
- checked: true,
- },
- {
- id: 'city',
- displayName: '城市',
- checked: true,
- },
- ],
- },
- ];
- const { result } = renderHook(() => useHide(mockData));
-
- expect(result.current).toBeFalsy();
- });
- });
-});
diff --git a/packages/s2-core/__tests__/unit/components/dimension-switch/util.spec.ts b/packages/s2-core/__tests__/unit/components/dimension-switch/util.spec.ts
deleted file mode 100644
index a1b693c666..0000000000
--- a/packages/s2-core/__tests__/unit/components/dimension-switch/util.spec.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { DimensionType } from '@/components/dimension-switch/dimension';
-import { getDimensionsByPredicate } from '@/components/dimension-switch/util';
-
-describe('Dimension Switch Util Test', () => {
- const mockData: DimensionType[] = [
- {
- type: 'measure',
- displayName: '维度',
- items: [
- {
- id: 'city',
- displayName: '城市',
- checked: true,
- },
- {
- id: 'count',
- displayName: '数量',
- checked: true,
- },
- {
- id: 'price',
- displayName: '价格',
- checked: false,
- },
- ],
- },
- ];
-
- test('should return all checked item ids', () => {
- expect(
- getDimensionsByPredicate(mockData, (value) => value.checked),
- ).toEqual({
- measure: ['city', 'count'],
- });
- });
-
- test('should return all unchecked item ids', () => {
- expect(
- getDimensionsByPredicate(mockData, (value) => !value.checked),
- ).toEqual({
- measure: ['price'],
- });
- });
-});
diff --git a/packages/s2-core/__tests__/unit/components/switcher/util.spec.ts b/packages/s2-core/__tests__/unit/components/switcher/util.spec.ts
index 2fcf98843a..7d4fa22cb6 100644
--- a/packages/s2-core/__tests__/unit/components/switcher/util.spec.ts
+++ b/packages/s2-core/__tests__/unit/components/switcher/util.spec.ts
@@ -1,15 +1,20 @@
-import { getNonEmptyFieldCount } from './../../../../src/components/switcher/util';
import { FieldType } from '@/components/switcher/constant';
-import { SwitcherItem, SwitcherState } from '@/components/switcher/interface';
import {
+ SwitcherItem,
+ SwitcherState,
+ SwitcherFields,
+} from '@/components/switcher/interface';
+import {
+ getNonEmptyFieldCount,
+ getSwitcherState,
getSwitcherClassName,
getMainLayoutClassName,
- shouldDimensionCrossRows,
- isMeasureType,
+ shouldCrossRows,
moveItem,
checkItem,
generateSwitchResult,
} from '@/components/switcher/util';
+
describe('switcher util test', () => {
test('should return correct class name with prefix', () => {
expect(getSwitcherClassName('content', 'text')).toEqual(
@@ -46,21 +51,16 @@ describe('switcher util test', () => {
);
test('should return true if nonempty count is less than max count', () => {
- expect(shouldDimensionCrossRows(2)).toBeTrue();
+ expect(shouldCrossRows(2, FieldType.Rows)).toBeTrue();
});
test('should return true if nonempty count is greater than max count', () => {
- expect(shouldDimensionCrossRows(3)).toBeFalse();
- expect(shouldDimensionCrossRows(4)).toBeFalse();
- });
-
- test('should return true if field type is values', () => {
- expect(isMeasureType(FieldType.Values)).toBeTrue();
+ expect(shouldCrossRows(3, FieldType.Rows)).toBeFalse();
+ expect(shouldCrossRows(4, FieldType.Rows)).toBeFalse();
});
- test('should return false if field type is not values', () => {
- expect(isMeasureType(FieldType.Rows)).toBeFalse();
- expect(isMeasureType(FieldType.Cols)).toBeFalse();
+ test('should return true if field type is value', () => {
+ expect(shouldCrossRows(1, FieldType.Values)).toBeTrue();
});
describe('move item test', () => {
@@ -256,10 +256,39 @@ describe('switcher util test', () => {
});
test('should return generate switch result when values have no children', () => {
expect(generateSwitchResult(state)).toEqual({
- rows: ['r1', 'r2'],
- cols: ['c1', 'c2'],
- values: ['v1', 'v2'],
- hiddenValues: [],
+ rows: {
+ items: [
+ {
+ id: 'r1',
+ },
+ {
+ id: 'r2',
+ },
+ ],
+ hideItems: [],
+ },
+ columns: {
+ items: [
+ {
+ id: 'c1',
+ },
+ {
+ id: 'c2',
+ },
+ ],
+ hideItems: [],
+ },
+ values: {
+ items: [
+ {
+ id: 'v1',
+ },
+ {
+ id: 'v2',
+ },
+ ],
+ hideItems: [],
+ },
});
});
@@ -280,11 +309,47 @@ describe('switcher util test', () => {
id: 'v2',
},
];
+
expect(generateSwitchResult(state)).toEqual({
- rows: ['r1', 'r2'],
- cols: ['c1', 'c2'],
- values: ['v1', 'vc1', 'vc2', 'v2'],
- hiddenValues: [],
+ rows: {
+ items: [
+ {
+ id: 'r1',
+ },
+ {
+ id: 'r2',
+ },
+ ],
+ hideItems: [],
+ },
+ columns: {
+ items: [
+ {
+ id: 'c1',
+ },
+ {
+ id: 'c2',
+ },
+ ],
+ hideItems: [],
+ },
+ values: {
+ items: [
+ {
+ id: 'v1',
+ },
+ {
+ id: 'vc1',
+ },
+ {
+ id: 'vc2',
+ },
+ {
+ id: 'v2',
+ },
+ ],
+ hideItems: [],
+ },
});
});
@@ -314,11 +379,84 @@ describe('switcher util test', () => {
},
];
expect(generateSwitchResult(state)).toEqual({
- rows: ['r1', 'r2'],
- cols: ['c1', 'c2'],
- values: ['v1', 'vc1', 'vc2', 'v2', 'vc3'],
- hiddenValues: ['vc1', 'v2', 'vc3'],
+ rows: {
+ items: [
+ {
+ id: 'r1',
+ },
+ {
+ id: 'r2',
+ },
+ ],
+ hideItems: [],
+ },
+ columns: {
+ items: [
+ {
+ id: 'c1',
+ },
+ {
+ id: 'c2',
+ },
+ ],
+ hideItems: [],
+ },
+ values: {
+ items: [
+ {
+ id: 'v1',
+ },
+ {
+ id: 'vc1',
+ checked: false,
+ },
+ {
+ id: 'vc2',
+ },
+ {
+ id: 'v2',
+ checked: false,
+ },
+ {
+ id: 'vc3',
+ checked: false,
+ },
+ ],
+ hideItems: [
+ {
+ id: 'vc1',
+ checked: false,
+ },
+ {
+ id: 'v2',
+ checked: false,
+ },
+ {
+ id: 'vc3',
+ checked: false,
+ },
+ ],
+ },
});
});
});
+
+ test('should return switcher state from switcher fields', () => {
+ const fields: SwitcherFields = {
+ rows: {
+ items: [{ id: 'row' }],
+ },
+ columns: {
+ items: [{ id: 'column' }],
+ },
+ values: {
+ items: [{ id: 'value' }],
+ },
+ };
+ expect(getSwitcherState(fields)).toEqual({
+ rows: [{ id: 'row' }],
+ columns: [{ id: 'column' }],
+ values: [{ id: 'value' }],
+ });
+ });
});
diff --git a/packages/s2-core/package.json b/packages/s2-core/package.json
index 408113a4ab..5ae14fabd1 100644
--- a/packages/s2-core/package.json
+++ b/packages/s2-core/package.json
@@ -75,7 +75,7 @@
"bundlesize": [
{
"path": "./dist/s2.min.js",
- "maxSize": "120 kB"
+ "maxSize": "200 kB"
},
{
"path": "./dist/s2.min.css",
diff --git a/packages/s2-core/src/common/i18n/en_US.ts b/packages/s2-core/src/common/i18n/en_US.ts
index 4d89b8cdca..55fc0075ad 100644
--- a/packages/s2-core/src/common/i18n/en_US.ts
+++ b/packages/s2-core/src/common/i18n/en_US.ts
@@ -30,5 +30,5 @@ export const EN_US = {
行头: 'Rows',
列头: 'Cols',
值: 'Values',
- 展开同环比: 'Expand DerivedValues',
+ 展开子项: 'Expand Children',
};
diff --git a/packages/s2-core/src/common/i18n/zh_CN.ts b/packages/s2-core/src/common/i18n/zh_CN.ts
index b9aef61901..1eb01ccfca 100644
--- a/packages/s2-core/src/common/i18n/zh_CN.ts
+++ b/packages/s2-core/src/common/i18n/zh_CN.ts
@@ -31,5 +31,5 @@ export const ZH_CN = {
行头: '行头',
列头: '列头',
值: '值',
- 展开同环比: '展开同环比',
+ 展开子项: '展开子项',
};
diff --git a/packages/s2-core/src/components/dimension-switch/dimension/index.less b/packages/s2-core/src/components/dimension-switch/dimension/index.less
deleted file mode 100644
index 2685c9d7c7..0000000000
--- a/packages/s2-core/src/components/dimension-switch/dimension/index.less
+++ /dev/null
@@ -1,83 +0,0 @@
-.dimension {
- display: flex;
- flex-direction: column;
- width: 200px;
-
- &-display-name {
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 24px;
- color: black;
- font-size: 12px;
-
- .search-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 24px;
- height: 24px;
- padding: 0;
- border: none;
- box-shadow: none;
-
- &:hover {
- background-color: rgba(0, 0, 0, 0.03);
- }
- }
- }
-
- &-items {
- flex: auto;
- min-height: 90px;
- max-height: 180px;
- margin-top: 8px;
- padding: 0 8px;
- overflow-y: auto;
- border: 1px solid rgba(0, 0, 0, 0.15);
-
- .dimension-item {
- .ant-checkbox-wrapper {
- &:hover {
- background-color: rgba(0, 0, 0, 0.03);
- }
-
- display: flex;
- width: 100%;
- height: 24px;
- margin: 2px 0;
-
- & > span:nth-child(2) {
- flex: 1;
- padding: 0;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- }
-
- &-name {
- margin-left: 8px;
- font-size: 12px;
- }
- }
- }
-
- .summary {
- height: 28px;
- margin-top: 8px;
- padding-left: 8px;
- line-height: 28px;
- cursor: pointer;
-
- .total {
- margin-left: 4px;
- color: rgba(0, 0, 0, 0.45);
- }
-
- .reset {
- float: right;
- color: rgba(0, 0, 0, 0.45);
- }
- }
-}
diff --git a/packages/s2-core/src/components/dimension-switch/dimension/index.tsx b/packages/s2-core/src/components/dimension-switch/dimension/index.tsx
deleted file mode 100644
index 66d95013b5..0000000000
--- a/packages/s2-core/src/components/dimension-switch/dimension/index.tsx
+++ /dev/null
@@ -1,217 +0,0 @@
-import { SearchOutlined } from '@ant-design/icons';
-import { Button, Checkbox, Input, Tooltip } from 'antd';
-import React, { FC, useEffect, useRef, useState } from 'react';
-import { i18n } from '@/common/i18n';
-import './index.less';
-
-export interface DimensionItem {
- id: string;
- displayName: string;
- checked: boolean;
- disabled?: boolean;
-}
-
-export interface DimensionType {
- type: string;
- displayName: string;
- items: DimensionItem[];
-}
-
-interface DimensionProps extends DimensionType {
- keepSearching?: boolean;
- onSelect: (type: string, idList: string[], checked: boolean) => void;
-}
-
-export const Dimension: FC = ({
- type,
- displayName,
- items,
- keepSearching = false,
- onSelect,
-}) => {
- const [height, setHeight] = useState(0);
- const ref = useRef();
-
- const [searching, setSearching] = useState(keepSearching);
- const [filterChecked, setFilterChecked] = useState(false);
- const [keyword, setKeyword] = useState('');
-
- const checkedList = items.filter((i) => i.checked).map((i) => i.id);
-
- // eslint-disable-next-line no-nested-ternary
- const filterResult = filterChecked
- ? items.filter((i) => i.checked)
- : keyword
- ? items.filter((i) => new RegExp(keyword, 'i').test(i.displayName))
- : items;
-
- const filterCheckedCount = filterResult.filter((i) => i.checked).length;
-
- const indeterminate =
- filterCheckedCount > 0 && filterCheckedCount < filterResult.length;
- const checkedAll =
- filterResult.length > 0 && filterCheckedCount === filterResult.length;
-
- const onShowSearchInput = () => {
- setSearching(true);
- setFilterChecked(false);
-
- const onHideSearchingInput = (event) => {
- const target: HTMLElement = event.target;
- // 排除items区域,所有 checkbox 及其 label 文字的点击
- if (
- target.tagName === 'INPUT' ||
- target.tagName === 'LABEL' ||
- (target.tagName === 'SPAN' &&
- target.parentElement.tagName === 'LABEL') ||
- target.className.startsWith('dimension-item')
- ) {
- return;
- }
-
- setSearching(false);
- setKeyword('');
-
- document.removeEventListener('click', onHideSearchingInput);
- };
-
- document.addEventListener('click', onHideSearchingInput);
- };
-
- const onUpdateCheckItem = (itemId: string, checked: boolean) => {
- onSelect(type, [itemId], checked);
- };
-
- const onUpdateCheckedAll = (checked: boolean) => {
- onSelect(
- type,
- filterResult.map((i) => i.id),
- checked,
- );
- };
-
- const onFilterAllChecked = () => {
- setFilterChecked(true);
- setKeyword('');
- if (!keepSearching) {
- setSearching(false);
- }
- };
- useEffect(() => {
- setHeight(ref.current.offsetHeight);
- }, []);
-
- return (
-
-
- {searching ? (
- }
- autoFocus={true}
- placeholder={i18n('请输入关键字搜索')}
- allowClear={true}
- value={keyword}
- onChange={(e) => setKeyword(e.target.value)}
- />
- ) : (
- <>
- {displayName}
-
- }
- className={'search-btn'}
- onClick={onShowSearchInput}
- />
-
- >
- )}
-
-
-
- {filterResult.map((i) => (
-
- ))}
-
-
-
- onUpdateCheckedAll(e.target.checked)}
- />
-
-
- {i18n('已选 {} 项').replace('{}', checkedList.length)}
-
-
- {filterChecked && (
-
- )}
-
-
- );
-};
-
-interface DimensionItemProps extends DimensionItem {
- onUpdateCheckItem: (id: string, checked: boolean) => void;
-}
-
-const DimensionItem: FC = ({
- id,
- checked,
- disabled,
- displayName,
- onUpdateCheckItem,
-}) => {
- const ref = useRef();
- const [ellipsis, setEllipsis] = useState(false);
-
- useEffect(() => {
- // 针对超长文字,添加 tooltip
- setEllipsis(
- ref.current.offsetWidth > ref.current.parentElement.offsetWidth,
- );
- }, []);
-
- return (
-
- {
- onUpdateCheckItem(id, e.target.checked);
- }}
- >
- {ellipsis ? (
-
-
- {displayName}
-
-
- ) : (
-
- {displayName}
-
- )}
-
-
- );
-};
diff --git a/packages/s2-core/src/components/dimension-switch/hooks.tsx b/packages/s2-core/src/components/dimension-switch/hooks.tsx
deleted file mode 100644
index d96e5ac0c4..0000000000
--- a/packages/s2-core/src/components/dimension-switch/hooks.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { isEmpty } from 'lodash';
-import { Children, ReactElement, ReactNode, useState } from 'react';
-import { DimensionType } from './dimension';
-
-export const useVisible = (defaultVisible = false) => {
- const [visible, setVisible] = useState(defaultVisible);
- const show = () => {
- setVisible(true);
- };
- const hide = () => {
- setVisible(false);
- };
- const toggle = () => {
- setVisible(!visible);
- };
- return { visible, show, hide, toggle };
-};
-
-export const useCustomChild = (
- defaultChild: ReactElement,
- child?: ReactNode,
-) => {
- return (child ? Children.only(child) : defaultChild) as ReactElement;
-};
-
-export const useHide = (data: DimensionType[]) => {
- return data.every((dimension) => isEmpty(dimension.items));
-};
diff --git a/packages/s2-core/src/components/dimension-switch/index.less b/packages/s2-core/src/components/dimension-switch/index.less
deleted file mode 100644
index fdaa7b57b2..0000000000
--- a/packages/s2-core/src/components/dimension-switch/index.less
+++ /dev/null
@@ -1,69 +0,0 @@
-@prefix: s2-dimension-switch;
-@dropdown-prefix: s2-dropdown;
-
-.@{prefix}-overlay {
- .ant-modal-body,
- .ant-popover-inner {
- overflow: hidden;
- }
-}
-
-.@{prefix}-icon-button {
- padding: 0 !important;
- border: none !important;
- box-shadow: none !important;
-}
-
-.@{prefix}-popover-title {
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 40px;
- .@{prefix}-icon-button {
- color: rgba(0, 0, 0, 0.45);
- }
-}
-
-.@{dropdown-prefix}-overlay {
- .ant-popover-inner-content {
- position: relative;
- padding: 8px;
-
- [class^='dimension-items'] {
- border: none;
- }
-
- [class^='summary'] {
- position: absolute;
- bottom: 10px;
- z-index: 10;
- width: 148px;
- }
- }
-}
-.@{dropdown-prefix} {
- display: inline-flex;
- align-items: center;
- min-width: 94px;
- max-width: 250px;
- height: 24px;
- font-size: 12px;
- border-bottom: 1px solid #f0f0f0;
- cursor: pointer;
-
- .label {
- margin-right: 10px;
- color: #000;
- white-space: nowrap;
- opacity: 0.65;
- }
-
- .content {
- flex: auto;
- margin-right: 5px;
- overflow: hidden;
- color: #000;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-}
diff --git a/packages/s2-core/src/components/dimension-switch/index.tsx b/packages/s2-core/src/components/dimension-switch/index.tsx
deleted file mode 100644
index 8edf6ee8c0..0000000000
--- a/packages/s2-core/src/components/dimension-switch/index.tsx
+++ /dev/null
@@ -1,174 +0,0 @@
-import React, { cloneElement, FC } from 'react';
-import { Modal, Popover, Button } from 'antd';
-import {
- DownOutlined,
- EditOutlined,
- SwapOutlined,
- UpOutlined,
- CloseOutlined,
-} from '@ant-design/icons';
-import cx from 'classnames';
-import { DimensionType } from './dimension';
-import { DimensionSwitch } from './switch';
-import { useCustomChild, useVisible, useHide } from './hooks';
-import { i18n } from '@/common/i18n';
-import './index.less';
-
-interface DimensionSwitchMultipleProps {
- overlayClassName?: string;
- data: DimensionType[];
- onUpdateDisableItems?: (type: string, checkedList: string[]) => string[];
- onSubmit?: (result: DimensionType[]) => void;
-}
-export const DimensionSwitchModal: FC<
- DimensionSwitchMultipleProps & { onModalVisibilityChange?: () => void }
-> = ({
- overlayClassName,
- data,
- onSubmit: onOuterSubmit,
- onUpdateDisableItems,
- children,
- onModalVisibilityChange,
-}) => {
- const { visible, show, hide } = useVisible();
- const shouldHide = useHide(data);
- const child = useCustomChild(
- }
- />,
- children,
- );
- const onSubmit = (result: DimensionType[]) => {
- hide();
- onOuterSubmit?.(result);
- };
- const open = () => {
- onModalVisibilityChange?.();
- show();
- };
- return shouldHide ? null : (
- <>
- {cloneElement(child, { onClick: open })}
- hide()}
- destroyOnClose={true}
- width="fit-content"
- wrapClassName={cx('s2-dimension-switch-overlay', overlayClassName)}
- afterClose={onModalVisibilityChange}
- >
-
-
- >
- );
-};
-
-export const DimensionSwitchPopover: FC = ({
- overlayClassName,
- data,
- onSubmit: onOuterSubmit,
- onUpdateDisableItems,
- children,
-}) => {
- const { visible, toggle, hide } = useVisible();
- const shouldHide = useHide(data);
- const child = useCustomChild(
- }>
- {i18n('切换指标')}
- ,
- children,
- );
- const onSubmit = (result: DimensionType[]) => {
- hide();
- onOuterSubmit?.(result);
- };
- return shouldHide ? null : (
-
- {i18n('选择分析信息')}{' '}
- }
- onClick={hide}
- />
-
- }
- content={
-
- }
- overlayClassName={cx('s2-dimension-switch-overlay', overlayClassName)}
- destroyTooltipOnHide={true}
- >
- {cloneElement(child, { onClick: toggle })}
-
- );
-};
-
-interface DimensionSwitchDropdownProps {
- overlayClassName?: string;
- dimension: DimensionType;
- onUpdateDisableItems?: (type: string, checkedList: string[]) => string[];
- onSubmit?: (result: DimensionType[]) => void;
-}
-export const DimensionSwitchDropdown: FC = ({
- overlayClassName,
- dimension,
- onSubmit: onOuterSubmit,
- onUpdateDisableItems,
-}) => {
- const selectContent = dimension.items
- .filter((i) => i.checked)
- .map((i) => i.displayName)
- .join(', ');
-
- const { visible, toggle, hide } = useVisible();
- const onSubmit = (result: DimensionType[]) => {
- hide();
- onOuterSubmit?.(result);
- };
-
- return (
-
- }
- destroyTooltipOnHide={true}
- overlayClassName={cx(
- 's2-dimension-switch-overlay',
- 's2-dropdown-overlay',
- overlayClassName,
- )}
- >
-
- {dimension.displayName}
- {selectContent}
- {visible ? : }
-
-
- );
-};
diff --git a/packages/s2-core/src/components/dimension-switch/switch/index.less b/packages/s2-core/src/components/dimension-switch/switch/index.less
deleted file mode 100644
index ef7b4e9ccb..0000000000
--- a/packages/s2-core/src/components/dimension-switch/switch/index.less
+++ /dev/null
@@ -1,38 +0,0 @@
-.dimension-switch {
- &-body {
- display: grid;
- grid-gap: 16px;
- }
-
- &-footer {
- position: relative;
- display: flex;
- justify-content: flex-end;
- margin-top: 8px;
- padding-top: 8px;
-
- &::before {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- margin: 0 -30px;
- border-top: 1px solid #f0f0f0;
- content: '';
- }
- }
-
- button {
- padding: 0 8px;
- }
-
- button + button {
- margin-left: 8px;
- }
-
- .ant-btn-background-ghost {
- background-color: white !important;
- border: none;
- box-shadow: none;
- }
-}
diff --git a/packages/s2-core/src/components/dimension-switch/switch/index.tsx b/packages/s2-core/src/components/dimension-switch/switch/index.tsx
deleted file mode 100644
index f423b30eb7..0000000000
--- a/packages/s2-core/src/components/dimension-switch/switch/index.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import React, { useState, FC } from 'react';
-import { Button } from 'antd';
-import { get, isEqual, reduce } from 'lodash';
-import { Dimension, DimensionType } from '../dimension';
-import { getDimensionsByPredicate, OperatedType } from '../util';
-import { i18n } from '@/common/i18n';
-import './index.less';
-
-export interface DimensionSwitchProps {
- data: DimensionType[];
- keepSearching?: boolean;
- onUpdateDisableItems?: (type: string, checkedList: string[]) => string[];
- onSubmit: (result: DimensionType[]) => void;
-}
-
-export const DimensionSwitch: FC = ({
- data,
- keepSearching,
- onUpdateDisableItems,
- onSubmit: onOuterSubmit,
-}) => {
- const [{ defaultChecked, defaultDisabled }] = useState(() => ({
- defaultChecked: getDimensionsByPredicate(data, (i) => i.checked),
- defaultDisabled: getDimensionsByPredicate(data, (i) => i.disabled),
- }));
-
- const [checkedTypeObj, setCheckedTypeObj] =
- useState(defaultChecked);
- const [disabledTypeObj, setDisabledTypeObj] =
- useState(defaultDisabled);
-
- const onSelect = (type: string, idList: string[], checked: boolean) => {
- const oldCheckedList = get(checkedTypeObj, type, []);
- let newCheckedList = checked
- ? oldCheckedList.concat(idList)
- : oldCheckedList.filter((i) => !idList.includes(i));
-
- const disabledList = onUpdateDisableItems?.(type, newCheckedList) ?? [];
-
- newCheckedList = newCheckedList.filter((i) => !disabledList.includes(i));
-
- setCheckedTypeObj({ ...checkedTypeObj, [type]: newCheckedList });
- setDisabledTypeObj({ ...disabledTypeObj, [type]: disabledList });
- };
-
- const assembleData = () => {
- return data
- .filter((d) => d.items.length > 0)
- .map((d) => {
- return {
- ...d,
- items: d.items.map((i) => ({
- ...i,
- checked: !!checkedTypeObj[d.type]?.includes(i.id),
- disabled: !!disabledTypeObj[d.type]?.includes(i.id),
- })),
- };
- });
- };
-
- const onSubmit = () => {
- const result = assembleData();
- onOuterSubmit(result);
- };
-
- const onReset = () => {
- setCheckedTypeObj(defaultChecked);
- setDisabledTypeObj(defaultDisabled);
- };
-
- const actual = assembleData();
-
- // 小于4个时,放在一行排列,否则每行两列
- const dimensionCount = actual.length;
-
- const disabledResetBtn = isEqual(defaultChecked, checkedTypeObj);
- const disabledSubmitBtn =
- disabledResetBtn ||
- reduce(checkedTypeObj, (sum, items) => sum + items.length, 0) === 0;
-
- return (
-
-
- {actual.map((i) => (
-
- ))}
-
-
-
-
-
-
- );
-};
diff --git a/packages/s2-core/src/components/dimension-switch/util.ts b/packages/s2-core/src/components/dimension-switch/util.ts
deleted file mode 100644
index 57a4920580..0000000000
--- a/packages/s2-core/src/components/dimension-switch/util.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { DimensionType, DimensionItem } from './dimension';
-
-export interface OperatedType {
- [type: string]: string[];
-}
-
-export const getDimensionsByPredicate = (
- data: DimensionType[],
- predicate: (value: DimensionItem) => boolean,
-) => {
- return data.reduce((obj, t) => {
- obj[t.type] = t.items.filter(predicate).map((i) => i.id);
- return obj;
- }, {} as OperatedType);
-};
diff --git a/packages/s2-core/src/components/icons/index.less b/packages/s2-core/src/components/icons/index.less
index cd8504598f..6679a48a3f 100644
--- a/packages/s2-core/src/components/icons/index.less
+++ b/packages/s2-core/src/components/icons/index.less
@@ -1,4 +1,4 @@
-@pre: s2-icon;
+@pre: antv-s2-icon;
.@{pre} {
margin-right: 10px;
diff --git a/packages/s2-core/src/components/icons/index.tsx b/packages/s2-core/src/components/icons/index.tsx
index 98b944ace1..c4290aadd5 100644
--- a/packages/s2-core/src/components/icons/index.tsx
+++ b/packages/s2-core/src/components/icons/index.tsx
@@ -1,11 +1,11 @@
import React, { FC } from 'react';
import './index.less';
-const PRECLASS = 'spreadsheet-icon';
+const ICON_CLS = 'antv-s2-icon';
export const CalendarIcon: FC = () => (