Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sheet): sheet bar scroll button's state #454

Merged
merged 3 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ui-plugin-sheets/src/locale/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ export default {
noHide: "Can't hide, at least keep one sheet tag",
chartEditNoOpt: 'This operation is not allowed in chart editing mode!',
sheetNameSpecCharError: 'The name cannot contain:[ ] : ? * / \' "',
sheetNameCannotIsEmptyError: 'Sheet name cannot be empty',
sheetNameCannotIsEmptyError: 'The sheet name cannot be empty',
},
rightClick: {
copy: 'Copy',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-plugin-sheets/src/locale/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export default {
noHide: '不能隐藏, 至少保留一个sheet标签',
chartEditNoOpt: '图表编辑模式下不允许该操作!',
sheetNameSpecCharError: "名称不能超过31个字符,首尾不能是' 且名称不能包含:\r\n[ ] : \\ ? * /",
sheetNameCannotIsEmptyError: '名称不能为空!',
sheetNameCannotIsEmptyError: '名称不能为空',
},
rightClick: {
copy: '复制',
Expand Down
22 changes: 12 additions & 10 deletions packages/ui-plugin-sheets/src/views/sheet-bar/SheetBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { IScrollState } from './sheet-bar-tabs/utils/slide-tab-bar';
const SCROLL_WIDTH = 100;

export const SheetBar = () => {
const [leftScrollState, setLeftScrollState] = useState(false);
const [rightScrollState, setRightScrollState] = useState(false);
const [leftScrollState, setLeftScrollState] = useState(true);
const [rightScrollState, setRightScrollState] = useState(true);

const commandService = useDependency(ICommandService);
const sheetbarService = useDependency(ISheetBarService);
Expand Down Expand Up @@ -67,14 +67,16 @@ export const SheetBar = () => {
<SheetBarTabs />

{/* Scroll arrows */}
<div className={styles.sheetBarOptions}>
<SheetBarButton disabled={leftScrollState} onClick={handleScrollLeft}>
<MoreSingle style={{ transform: 'rotateZ(180deg)' }} />
</SheetBarButton>
<SheetBarButton disabled={rightScrollState} onClick={handleScrollRight}>
<MoreSingle />
</SheetBarButton>
</div>
{(!leftScrollState || !rightScrollState) && (
<div className={styles.sheetBarOptions}>
<SheetBarButton disabled={leftScrollState} onClick={handleScrollLeft}>
<MoreSingle style={{ transform: 'rotateZ(180deg)' }} />
</SheetBarButton>
<SheetBarButton disabled={rightScrollState} onClick={handleScrollRight}>
<MoreSingle />
</SheetBarButton>
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@
display: flex;
flex-direction: row;
align-items: center;

margin: var(--margin-xxs);

transition: display .2s;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
SetWorksheetOrderCommand,
SetWorksheetOrderMutation,
} from '@univerjs/base-sheets';
import { BooleanNumber, ICommandInfo, ICommandService, IUniverInstanceService } from '@univerjs/core';
import { IConfirmService } from '@univerjs/base-ui';
import { BooleanNumber, ICommandInfo, ICommandService, IUniverInstanceService, LocaleService } from '@univerjs/core';
import { useDependency } from '@wendellhu/redi/react-bindings';
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';

import { ISheetBarService } from '../../../services/sheetbar/sheetbar.service';
import sheetBarStyles from '../index.module.less';
Expand All @@ -24,25 +25,33 @@ export interface ISheetBarTabsProps {}

export function SheetBarTabs() {
const [sheetList, setSheetList] = useState<IBaseSheetBarProps[]>([]);
const [activeKey, setActiveKey] = useState<string>('');
const [subscribe, setSubscribe] = useState(false);
const [activeKey, setActiveKey] = useState('');
const [boxShadow, setBoxShadow] = useState('');
const slideTabBarRef = useRef<{ slideTabBar: SlideTabBar | null }>({ slideTabBar: null });

const univerInstanceService = useDependency(IUniverInstanceService);
const commandService = useDependency(ICommandService);
const sheetbarService = useDependency(ISheetBarService);
const workbook = univerInstanceService.getCurrentUniverSheetInstance();
const localeService = useDependency(LocaleService);
const confirmService = useDependency(IConfirmService);

let slideTabBar: SlideTabBar;
const workbook = univerInstanceService.getCurrentUniverSheetInstance();

useEffect(() => {
statusInit();
const slideTabBar = setupSlideTabBarInit();
const disposable = setupStatusUpdate();
const subscription = setupSubscribeScroll();
const subscribeList = [
setupSubscribeScroll(),
setupSubscribeScrollX(),
setupSubscribeRenameId(),
setupSubscribeAddSheet(),
];

return () => {
disposable.dispose();
subscription.unsubscribe();
slideTabBar.destroy();
subscribeList.forEach((subscribe) => subscribe.unsubscribe());
};
}, []);

Expand All @@ -52,18 +61,15 @@ export function SheetBarTabs() {
}
}, [sheetList]);

const setupSlideTabBarUpdate = () => {
const currentIndex = sheetList.findIndex((item) => item.selected);

// TODO@Dushusir: There may not be initialization each time
slideTabBar = new SlideTabBar({
const setupSlideTabBarInit = () => {
const slideTabBar = new SlideTabBar({
slideTabBarClassName: styles.slideTabBar,
slideTabBarItemActiveClassName: styles.slideTabActive,
slideTabBarItemClassName: styles.slideTabItem,
slideTabBarSpanEditClassName: styles.slideTabSpanEdit,
slideTabBarItemAutoSort: true,
slideTabRootClassName: sheetBarStyles.sheetBar,
currentIndex,
currentIndex: 0,
onChangeName: (worksheetId: string, worksheetName: string) => {
commandService.executeCommand(SetWorksheetNameCommand.id, {
worksheetId,
Expand All @@ -79,26 +85,34 @@ export function SheetBarTabs() {
onScroll: (state: IScrollState) => {
sheetbarService.setScroll(state);
},
onEmptyAlert: () => {
const id = 'slideTabBarAlert';
confirmService.open({
id,
children: { title: localeService.t('sheetConfig.sheetNameCannotIsEmptyError') },
// TODO@Dushusir: i18n
title: { title: 'There was a problem' },
onClose() {
confirmService.close(id);
},
onConfirm() {
confirmService.close(id);
},
});
},
});

// TODO@Dushusir: Can you initialize it once without using the `subscribe` label?
if (!subscribe) {
sheetbarService.scrollX$.subscribe((x: number) => {
// update scrollX
slideTabBar.setScroll(x);
});
slideTabBarRef.current.slideTabBar = slideTabBar;

sheetbarService.renameId$.subscribe((renameId: string) => {
const index = sheetList.findIndex((item) => item.sheetId === renameId);
slideTabBar.getSlideTabItems()[index].editor();
});
// FIXME@Dushusir: First time asynchronous rendering will cause flickering problems
resizeInit(slideTabBar);

sheetbarService.addSheet$.subscribe((addSheet: number) => {
slideTabBar.getScrollbar().scrollRight();
});
return slideTabBar;
};

setSubscribe(true);
}
const setupSlideTabBarUpdate = () => {
const currentIndex = sheetList.findIndex((item) => item.selected);
slideTabBarRef.current.slideTabBar?.update(currentIndex);
};

const setupStatusUpdate = () =>
Expand Down Expand Up @@ -140,6 +154,21 @@ export function SheetBarTabs() {
updateScrollButtonState(state);
});

const setupSubscribeScrollX = () =>
sheetbarService.scrollX$.subscribe((x: number) => {
slideTabBarRef.current.slideTabBar?.setScroll(x);
});

const setupSubscribeRenameId = () =>
sheetbarService.renameId$.subscribe(() => {
slideTabBarRef.current.slideTabBar?.getActiveItem()?.editor();
});

const setupSubscribeAddSheet = () =>
sheetbarService.addSheet$.subscribe(() => {
slideTabBarRef.current.slideTabBar?.getScrollbar().scrollRight();
});

const updateScrollButtonState = (state: IScrollState) => {
const { leftEnd, rightEnd } = state;
// box-shadow: inset 10px 0px 10px -10px rgba(0, 0, 0, 0.2), inset -10px 0px 10px -10px rgba(0, 0, 0, 0.2);
Expand All @@ -157,6 +186,27 @@ export function SheetBarTabs() {
setBoxShadow(boxShadow);
};

const buttonScroll = (slideTabBar: SlideTabBar) => {
sheetbarService.setScroll({
leftEnd: slideTabBar.isLeftEnd(),
rightEnd: slideTabBar.isRightEnd(),
});
};

const resizeInit = (slideTabBar: SlideTabBar) => {
// Target element
const slideTabBarContainer = document.querySelector(`.${styles.slideTabBar}`);
if (!slideTabBarContainer) return;

// Create a Resizeobserver
const observer = new ResizeObserver(() => {
buttonScroll(slideTabBar);
});

// Start the observer
observer.observe(slideTabBarContainer);
};

return (
<div className={styles.slideTabBarContainer}>
<div className={styles.slideTabBar} style={{ boxShadow }}>
Expand Down
Loading
Loading