feat: update SheetTableThemePanel for improved theme handling and UI responsiveness (#5267)

This commit is contained in:
白熱
2025-05-26 14:36:26 +08:00
committed by GitHub
parent 889740f7e6
commit d891f1614b
45 changed files with 358 additions and 313 deletions
+1 -1
View File
@@ -19,7 +19,6 @@ import path from 'node:path';
import process from 'node:process';
import fs from 'fs-extra';
import sortKeys from 'sort-keys';
import localPkg from '../package.json';
import { peerDepsMap } from './data';
@@ -78,6 +77,7 @@ export function cleanupPkgPlugin(): Plugin {
generateBundle() {
const hasLocales = fs.existsSync(path.resolve(process.cwd(), 'src/locale'));
const hasFacade = fs.existsSync(path.resolve(process.cwd(), 'src/facade/index.ts'));
pkg.version = localPkg.version;
pkg.publishConfig = {
access: 'public',
main: './lib/es/index.js',
+1 -1
View File
@@ -93,7 +93,7 @@ export function App() {
title={TITLE_MAP[id]}
toolbarControls={<div />}
>
<div id={`app-${id}`} style={{ height: '100%' }}>
<div id={`app-${id}`} className="univer-h-full">
{TITLE_MAP[id]}
</div>
</MosaicWindow>
File diff suppressed because one or more lines are too long
@@ -14,21 +14,17 @@
* limitations under the License.
*/
export const RangeLoading = () => {
const divStyle = {
width: '100%',
height: '100%',
backgroundColor: '#fff',
border: '1px solid #ccc',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center' as const,
transformOrigin: 'top left',
};
import { borderClassName, clsx } from '@univerjs/design';
export const RangeLoading = () => {
return (
<div style={divStyle}>
<div
className={clsx(`
univer-flex univer-size-full univer-origin-top-left univer-items-center univer-justify-center
univer-bg-white
dark:univer-bg-gray-900
`, borderClassName)}
>
Loading...
</div>
);
@@ -85,12 +85,12 @@ export const UniFloatingToolbar = React.forwardRef<IFloatingToolbarRef, { node:
return (
<div
ref={setFloating}
className={`
univer-flex univer-items-center univer-gap-2 univer-rounded-md univer-bg-white univer-text-sm
univer-text-primary-600
dark:!univer-bg-gray-900
`}
ref={setFloating}
style={{ position: strategy, top: y ?? 0, left: x ?? 0 }}
>
<div
@@ -20,6 +20,8 @@ const locale = {
title: 'Record Actions',
record: 'Record Actions...',
'replay-local': 'Replace Local Record...',
'replay-local-name': 'Replace Local Record by Subunit...',
'replay-local-active': 'Replace Local Record by Current Subunit...',
},
},
};
@@ -22,6 +22,8 @@ const locale: typeof enUS = {
title: 'ثبت اقدامات',
record: 'ثبت اقدامات...',
'replay-local': 'بازپخش محلی ثبت...',
'replay-local-name': 'بازپخش محلی ثبت بر اساس نام زیر واحد...',
'replay-local-active': 'بازپخش محلی ثبت بر اساس زیر واحد فعلی...',
},
},
};
@@ -22,6 +22,8 @@ const locale: typeof enUS = {
title: 'Enregistrer les actions',
record: 'Enregistrer les actions...',
'replay-local': 'Lecture de l\'enregistrement local...',
'replay-local-name': 'Remplacer l\'enregistrement local par le sous-unité...',
'replay-local-active': 'Remplacer l\'enregistrement local par le sous-unité actuel...',
},
},
};
@@ -22,6 +22,8 @@ const locale: typeof enUS = {
title: 'Record Actions',
record: 'Record Actions...',
'replay-local': 'Replace Local Record...',
'replay-local-name': 'Replace Local Record by Subunit...',
'replay-local-active': 'Replace Local Record by Current Subunit...',
},
},
};
@@ -22,6 +22,8 @@ const locale: typeof enUS = {
title: 'Record Actions',
record: 'Record Actions...',
'replay-local': 'Replace Local Record...',
'replay-local-name': 'Replace Local Record by Subunit...',
'replay-local-active': 'Replace Local Record by Current Subunit...',
},
},
};
@@ -22,6 +22,8 @@ const locale: typeof enUS = {
title: '操作录制',
record: '录制操作...',
'replay-local': '回放本地录制...',
'replay-local-name': '根据子表名回放本地录制...',
'replay-local-active': '根据当前子表回放本地录制...',
},
},
};
+5 -3
View File
@@ -19,9 +19,11 @@ import type enUS from './en-US';
const locale: typeof enUS = {
'action-recorder': {
menu: {
title: '操作录制',
record: '录制操作...',
'replay-local': '回放本地录制...',
title: '操作錄製',
record: '錄製操作...',
'replay-local': '回放本地錄製...',
'replay-local-name': '根據子表名回放本地錄製...',
'replay-local-active': '根據當前子表回放本地錄製...',
},
},
};
@@ -20,9 +20,10 @@ import { Button } from '../button/Button';
import { Input } from '../input/Input';
export interface IInputNumberProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'defaultValue'> {
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'defaultValue' | 'size'> {
value?: number | null;
defaultValue?: number;
size?: 'mini' | 'small';
min?: number;
max?: number;
step?: number;
@@ -44,6 +45,7 @@ export const InputNumber = forwardRef<HTMLInputElement, IInputNumberProps>(
{
value,
defaultValue,
size = 'small',
min = Number.MIN_SAFE_INTEGER,
max = Number.MAX_SAFE_INTEGER,
step = 1,
@@ -315,6 +317,7 @@ export const InputNumber = forwardRef<HTMLInputElement, IInputNumberProps>(
<Input
ref={mergedRef}
className={clsx('univer-box-border', inputClassName)}
size={size}
value={inputValue}
disabled={disabled}
onChange={handleInputChange}
@@ -33,6 +33,7 @@ export const inputVariants = cva(
{
variants: {
size: {
mini: 'univer-h-7 univer-px-1.5 univer-text-sm',
small: 'univer-h-8 univer-px-2 univer-text-sm',
middle: 'univer-h-10 univer-px-3 univer-text-base',
large: 'univer-h-12 univer-px-4 univer-text-lg',
@@ -165,9 +166,9 @@ export const Input = forwardRef<HTMLInputElement, IInputProps>(
type="button"
onClick={handleClear}
className={`
univer-flex univer-size-4 univer-cursor-pointer univer-rounded-full univer-border-none
univer-bg-transparent univer-p-1 univer-text-gray-400 univer-transition-colors
univer-duration-200
univer-flex univer-size-4 univer-cursor-pointer univer-items-center
univer-rounded-full univer-border-none univer-bg-transparent univer-p-1
univer-text-gray-400 univer-transition-colors univer-duration-200
focus:univer-outline-none
hover:univer-text-gray-500
`}
@@ -110,6 +110,7 @@ const createMessage = (() => {
};
useEffect(() => {
const timers: number[] = [];
addMessage = (message) => {
const id = String(messageCount++);
setState((prev) => ({
@@ -117,13 +118,20 @@ const createMessage = (() => {
}));
if (message.duration !== Infinity) {
setTimeout(() => {
const timer = window.setTimeout(() => {
setState((prev) => ({
messages: prev.messages.filter((t) => t.id !== id),
}));
}, message.duration || 3000);
timers.push(timer);
}
};
return () => {
timers.forEach((timer) => {
window.clearTimeout(timer);
});
};
}, []);
return createPortal(
@@ -18,10 +18,10 @@ import type { ReactNode } from 'react';
import type { IDropdownMenuProps } from '../dropdown-menu/DropdownMenu';
import { MoreDownSingle } from '@univerjs/icons';
import { useMemo, useState } from 'react';
import { borderClassName } from '../../helper/class-utilities';
import { clsx } from '../../helper/clsx';
import { Badge } from '../badge/Badge';
import { DropdownMenu } from '../dropdown-menu/DropdownMenu';
import { selectClassName } from './Select';
interface IOption {
label?: string | ReactNode;
@@ -125,12 +125,7 @@ export function MultipleSelect(props: IMultipleSelectProps) {
>
<div
data-u-comp="multiple-select"
className={clsx(`
univer-box-border univer-inline-flex univer-h-8 univer-min-w-36 univer-items-center
univer-justify-between univer-rounded-lg univer-bg-white univer-px-2.5 univer-transition-colors
univer-duration-200
dark:!univer-bg-gray-700 dark:!univer-text-white
`, borderClassName, {
className={clsx(selectClassName, {
'univer-border-primary-600 univer-outline-none univer-ring-2 univer-ring-primary-50 dark:!univer-ring-primary-900': open && !borderless,
'univer-border-transparent univer-bg-transparent hover:univer-border-transparent': borderless,
'univer-cursor-not-allowed': disabled,
@@ -65,6 +65,12 @@ export interface ISelectProps {
onChange: (value: string) => void;
}
export const selectClassName = clsx(`
univer-box-border univer-inline-flex univer-h-8 univer-min-w-36 univer-items-center univer-justify-between
univer-gap-2 univer-rounded-lg univer-bg-white univer-px-2.5 univer-transition-colors univer-duration-200
dark:!univer-bg-gray-700 dark:!univer-text-white
`, borderClassName);
export function Select(props: ISelectProps) {
const {
className,
@@ -149,12 +155,7 @@ export function Select(props: ISelectProps) {
>
<div
data-u-comp="select"
className={clsx(`
univer-box-border univer-inline-flex univer-h-8 univer-min-w-36 univer-items-center
univer-justify-between univer-gap-2 univer-rounded-lg univer-bg-white univer-px-2.5
univer-transition-colors univer-duration-200
dark:!univer-bg-gray-700 dark:!univer-text-white
`, borderClassName, {
className={clsx(selectClassName, {
'univer-border-primary-600 univer-outline-none univer-ring-2 univer-ring-primary-50 dark:!univer-ring-primary-900': open && !borderless,
'univer-border-transparent univer-bg-transparent hover:univer-border-transparent': borderless,
'univer-cursor-not-allowed': disabled,
@@ -68,7 +68,7 @@ export const DocPrintingFloatDom = (props: IPrintingFloatDomProps) => {
.filter(([_, floatDom]) => !(floatDom.position.endX < 0 || floatDom.position.endY < 0 || floatDom.position.startX > width || floatDom.position.startY > height)), [floatDomInfos, scene, offset, width, height]);
return (
<div style={{ position: 'absolute', top: 0, left: 0 }}>
<div className="univer-absolute univer-left-0 univer-top-0">
{floatDomParams.map(([id, floatDom]) => (
<PrintFloatDomSingle key={id} layer={floatDom} id={id} position={floatDom.position} />
))}
@@ -176,8 +176,7 @@ export function ParagraphSetting() {
<div className="univer-flex univer-justify-between item-center">
<div className="univer-mt-3 univer-text-xs">{localeService.t('doc.paragraphSetting.lineSpace')}</div>
<div
className="univer-mt-4 univer-flex univer-flex-col univer-gap-1.5"
style={{ width: 162 }}
className="univer-mt-4 univer-flex univer-w-[162px] univer-flex-col univer-gap-1.5"
>
<Select
value={`${spacingRule}`}
@@ -45,8 +45,7 @@ export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
}
}, [rule]);
const previewClassName = `univer-pointer-events-none univer-flex univer-h-5 univer-min-w-[72px] univer-items-center
univer-justify-center univer-text-xs`;
const previewClassName = 'univer-pointer-events-none univer-flex univer-h-5 univer-min-w-[72px] univer-items-center univer-justify-center univer-text-xs';
switch (rule.type) {
case CFRuleType.dataBar:
@@ -58,17 +57,17 @@ export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
return (
<div className={previewClassName}>
<div
className="univer-h-full univer-w-1/2"
className="univer-h-full univer-w-1/2 univer-border univer-border-solid"
style={{
background: nativeColor,
border: `1px solid ${rule.config.nativeColor || defaultDataBarNativeColor}`,
borderColor: rule.config.nativeColor ?? defaultDataBarNativeColor,
}}
/>
<div
className="univer-h-full univer-w-1/2"
className="univer-h-full univer-w-1/2 univer-border univer-border-solid"
style={{
background: positiveColor,
border: `1px solid ${rule.config.positiveColor || defaultDataBarPositiveColor}`,
borderColor: rule.config.positiveColor ?? defaultDataBarPositiveColor,
}}
/>
</div>
@@ -79,7 +78,11 @@ export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
return colorList && (
<div className={previewClassName}>
{colorList.map((item, index) => (
<div key={index} className="univer-h-full" style={{ width: `${100 / colorList.length}%`, background: item }} />
<div
key={index}
className="univer-h-full"
style={{ width: `${100 / colorList.length}%`, background: item }}
/>
))}
</div>
);
@@ -14,22 +14,17 @@
* limitations under the License.
*/
import React from 'react';
import type { ReactElement } from 'react';
// TODO@gggpound: Error checking needs to be implemented by the form control
export const WrapperError = (props: {
errorText: string;
children: React.ReactElement;
children: ReactElement;
}) => {
return (
<div style={{ position: 'relative' }}>
<div style={{
position: 'absolute',
zIndex: 999,
bottom: '-13px',
fontSize: '10px',
color: 'red',
}}
<div className="univer-relative">
<div
className="univer-absolute univer-bottom-[-13px] univer-z-[999] univer-text-[10px] univer-text-red-500"
>
{props.errorText}
</div>
@@ -248,7 +248,7 @@ export function DataValidationDetail() {
const shouldHideFormula = operators.length && !localRule.operator;
return (
<div data-u-comp="data-validation-detail">
<div data-u-comp="data-validation-detail" className="univer-py-2">
<FormLayout
label={localeService.t('dataValidation.panel.range')}
error={(!localRule.ranges.length || isRangeError) ? localeService.t('dataValidation.panel.rangeError') : ''}
@@ -17,7 +17,6 @@
import type { IFormulaInputProps } from '@univerjs/data-validation';
import type { ListValidator } from '@univerjs/sheets-data-validation';
import type { IFormulaEditorRef } from '@univerjs/sheets-formula-ui';
import type { CSSProperties } from 'react';
import { DataValidationType, isFormulaString, LocaleService, Tools } from '@univerjs/core';
import { DataValidationModel, DataValidatorRegistryService } from '@univerjs/data-validation';
import { borderClassName, clsx, DraggableList, Dropdown, FormLayout, Input, Radio, RadioGroup } from '@univerjs/design';
@@ -122,19 +121,17 @@ const ColorSelect = (props: IColorSelectProps) => {
);
};
const Template = (props: { item: IDropdownItem; commonProps: any; style?: CSSProperties }) => {
const { item, commonProps, style } = props;
const Template = (props: { item: IDropdownItem; commonProps: any; className?: string }) => {
const { item, commonProps, className } = props;
const { onItemChange, onItemDelete } = commonProps;
return (
<div className="univer-flex univer-items-center univer-gap-2" style={style}>
{!item.isRef
? (
<div className={clsx('univer-cursor-move', 'draggableHandle')}>
<SequenceSingle />
</div>
)
: null}
<div className={clsx('univer-flex univer-items-center univer-gap-2', className)}>
{!item.isRef && (
<div className={clsx('univer-cursor-move', 'draggableHandle')}>
<SequenceSingle />
</div>
)}
<ColorSelect
value={item.color}
onChange={(color) => {
@@ -377,14 +374,14 @@ export function ListFormulaInput(props: IFormulaInputProps) {
}}
/>
{refFinalList.length > 0 && (
<div style={{ marginTop: '12px' }}>
<div className="univer-mt-3">
{refFinalList.map((item) => {
return (
<Template
key={item.id}
className="univer-mb-3"
item={item}
commonProps={{ onItemChange: handleRefItemChange }}
style={{ marginBottom: 12 }}
/>
);
})}
@@ -394,7 +391,7 @@ export function ListFormulaInput(props: IFormulaInputProps) {
)
: (
<FormLayout error={formula1Res}>
<div style={{ marginTop: '-12px' }}>
<div className="-univer-mt-3">
<DraggableList
list={strList}
onListChange={setStrList}
@@ -100,7 +100,7 @@ export function FilterPanel() {
</div>
)
: (
<div style={{ flex: 1 }} />
<div className="univer-flex-1" />
)}
<div
data-u-comp="sheets-filter-panel-footer"
@@ -112,7 +112,7 @@ export function FilterPanel() {
<Button variant="link" onClick={onClearCriteria} disabled={clearFilterDisabled}>
{localeService.t('sheets-filter.panel.clear-filter')}
</Button>
<span className="univer-space-x-2">
<span className="univer-flex univer-gap-2">
<Button variant="default" onClick={onCancel}>
{localeService.t('sheets-filter.panel.cancel')}
</Button>
@@ -157,10 +157,9 @@ export function RangeSelectorDialog(props: IRangeSelectorDialogProps) {
mask={false}
maskClosable={false}
footer={(
<footer>
<footer className="univer-flex univer-gap-2">
<Button onClick={onClose}>{localeService.t('rangeSelector.cancel')}</Button>
<Button
style={{ marginLeft: 10 }}
variant="primary"
onClick={() => {
onConfirm(
@@ -189,12 +188,13 @@ export function RangeSelectorDialog(props: IRangeSelectorDialogProps) {
className="univer-mb-2 univer-flex univer-items-center univer-gap-4"
>
<Input
className="univer-w-full"
className={clsx('univer-w-full', {
'univer-border-primary-600': focusIndex === index,
})}
placeholder={localeService.t('rangeSelector.placeHolder')}
onFocus={() => setFocusIndex(index)}
value={text}
onChange={(value) => handleRangeInput(index, value)}
style={{ borderColor: focusIndex === index ? 'rgb(var(--primary-color))' : undefined }}
/>
{ranges.length > 1 && (
<DeleteSingle
@@ -593,7 +593,7 @@ export const CellLinkEdit = () => {
setPayload={setPayload}
/>
)}
<div className="univer-flex univer-flex-row univer-justify-end">
<div className="univer-flex univer-flex-row univer-justify-end univer-gap-2">
<Button
onClick={() => {
if (editing) {
@@ -606,7 +606,6 @@ export const CellLinkEdit = () => {
</Button>
<Button
variant="primary"
style={{ marginLeft: 8 }}
onClick={async () => {
handleSubmit();
}}
@@ -49,13 +49,15 @@ export default function EmbedSortBtn(props: IEmbedSortBtnProps) {
}, [range, colIndex, sheetsSortUIService, univerInstanceService, onClose]);
return (
<ButtonGroup className="univer-mb-3 univer-w-full">
<Button className="univer-w-1/2" onClick={() => apply(true)}>
<AscendingSingle className="univer-mr-1" />
<ButtonGroup
className="univer-mb-3 univer-grid univer-w-full univer-grid-flow-col univer-grid-cols-2 univer-gap-2"
>
<Button onClick={() => apply(true)}>
<AscendingSingle />
{localeService.t('sheets-sort.general.sort-asc')}
</Button>
<Button className="univer-w-1/2" onClick={() => apply(false)}>
<DescendingSingle className="univer-mr-1" />
<Button onClick={() => apply(false)}>
<DescendingSingle />
{localeService.t('sheets-sort.general.sort-desc')}
</Button>
</ButtonGroup>
@@ -111,11 +111,7 @@ export const SheetTableAnchor = () => {
}
return (
<div
className="univer-absolute univer-z-50 univer-h-0 univer-w-0"
style={{
}}
>
<div className="univer-absolute univer-z-50 univer-h-0 univer-w-0">
{anchorPosition.map((item) => {
const table = tableManager.getTableById(unitId, item.tableId);
if (!table) return null;
@@ -139,16 +135,18 @@ export const SheetTableAnchor = () => {
<div
key={item.tableId}
className={clsx(`
univer-absolute univer-box-border univer-flex univer-cursor-pointer univer-items-center
univer-rounded-xl univer-pl-2 univer-pr-2 univer-shadow-xs
`, borderClassName)}
univer-absolute univer-box-border univer-cursor-pointer univer-items-center univer-rounded-xl
univer-pl-2 univer-pr-2 univer-shadow-xs
`, borderClassName, {
'univer-flex': !shouldHidden,
'univer-hidden': shouldHidden,
})}
style={{
left: item.x,
top: Math.max(item.y, 0),
backgroundColor: headerBgColor,
color: headerTextColor,
borderWidth: '0.5px',
display: shouldHidden ? 'none' : 'flex',
height: anchorHeight ? `${anchorHeight}px` : '24px',
}}
>
@@ -176,17 +174,14 @@ export const SheetTableAnchor = () => {
)}
</div>
<Dropdown
open={openStates[item.tableId] ?? false}
onOpenChange={(isOpen) => {
updateOpenState(item.tableId, isOpen);
}}
key={item.tableId}
align="start"
overlay={(
<div className="univer-pb-2 univer-pt-2">
<div
className={`
univer-flex univer-min-w-32 univer-cursor-pointer univer-items-center
univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
univer-gap-2 univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
hover:univer-bg-gray-200
`}
onClick={() => {
@@ -194,7 +189,7 @@ export const SheetTableAnchor = () => {
setInputValue(item.tableName);
}}
>
<RenameSingle className="univer-mr-2" />
<RenameSingle />
{localeService.t('sheets-table.rename')}
</div>
<div
@@ -206,17 +201,17 @@ export const SheetTableAnchor = () => {
onClick={() => handleChangeRange(item.tableId)}
className={`
univer-flex univer-min-w-32 univer-cursor-pointer univer-items-center
univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
univer-gap-2 univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
hover:univer-bg-gray-200
`}
>
<GridOutlineSingle className="univer-mr-2" />
<GridOutlineSingle />
{localeService.t('sheets-table.updateRange')}
</div>
<div
className={`
univer-flex univer-min-w-32 univer-cursor-pointer univer-items-center
univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
univer-gap-2 univer-pb-1 univer-pl-2 univer-pr-2 univer-pt-1 univer-text-sm
hover:univer-bg-gray-200
`}
onClick={() => {
@@ -241,7 +236,6 @@ export const SheetTableAnchor = () => {
>
<PaintBucket
extend={{ colorChannel1: 'rgb(53,91,183)' }}
className="univer-mr-2"
/>
{localeService.t('sheets-table.setTheme')}
</div>
@@ -270,7 +264,10 @@ export const SheetTableAnchor = () => {
</div>
</div>
)}
align="start"
open={openStates[item.tableId] ?? false}
onOpenChange={(isOpen) => {
updateOpenState(item.tableId, isOpen);
}}
>
<MoreDownSingle />
</Dropdown>
@@ -49,8 +49,8 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
const rangeThemeModel = useDependency(SheetRangeThemeModel);
const sheetTableThemeUIController = useDependency(SheetTableThemeUIController);
const rangeThemeMapChanged$ = useObservable(rangeThemeModel.rangeThemeMapChange$);
const tableRefresh$ = useObservable(sheetTableThemeUIController.refreshTable$);
const rangeThemeMapChanged = useObservable(rangeThemeModel.rangeThemeMapChange$);
const tableRefresh = useObservable(sheetTableThemeUIController.refreshTable$);
const errorService = useDependency(ErrorService);
@@ -122,10 +122,15 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
useEffect(() => {
setRefresh(Math.random());
}, [rangeThemeMapChanged$, tableRefresh$]);
}, [rangeThemeMapChanged, tableRefresh]);
if (!table) return null;
const headerBgIsDark = new ColorKit(headerBg).isDark();
const firstRowBgIsDark = new ColorKit(firstRowBg).isDark();
const secondRowBgIsDark = new ColorKit(secondRowBg).isDark();
const lastRowBgIsDark = new ColorKit(lastRowBg).isDark();
return (
<div>
<h5>{localeService.t('sheets-table.defaultStyle')}</h5>
@@ -141,17 +146,18 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
<div
key={item}
className={clsx(`
univer-h-10 univer-w-8 univer-cursor-pointer univer-p-px univer-border univer-border-solid
univer-border-gray-200
univer-h-10 univer-w-8 univer-cursor-pointer univer-border univer-border-solid
univer-border-gray-200 univer-p-px
[&>div]:univer-box-border [&>div]:univer-h-2.5
`, {
'univer-border-blue-500': item === themeConfig.theme,
})}
onClick={() => handleThemeChange(item)}
>
<div className="univer-box-border univer-h-2.5" style={{ background: headerRowBg, border: `${headerRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div className="univer-box-border univer-h-2.5" style={{ background: firstRowBg, border: `${firstRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div className="univer-box-border univer-h-2.5" style={{ background: secondRowBg, border: `${secondRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div className="univer-box-border univer-h-2.5" style={{ background: lastRowBg, border: `${lastRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div style={{ background: headerRowBg, border: `${headerRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div style={{ background: firstRowBg, border: `${firstRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div style={{ background: secondRowBg, border: `${secondRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
<div style={{ background: lastRowBg, border: `${lastRowBg ? TABLE_BORDER_NONE : TABLE_BORDER_DEFAULT}` }} />
</div>
);
})}
@@ -179,8 +185,8 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
<div
key={item}
className={clsx(`
univer-relative univer-h-10 univer-w-8 univer-cursor-pointer univer-p-px univer-border
univer-border-solid univer-border-gray-200
univer-relative univer-h-10 univer-w-8 univer-cursor-pointer univer-border
univer-border-solid univer-border-gray-200 univer-p-px
`, {
'univer-border-blue-500': item === themeConfig.theme,
})}
@@ -221,10 +227,12 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
className={clsx(`
univer-box-border univer-h-full univer-w-52 univer-rounded-sm univer-text-center
univer-leading-9
`, borderClassName)}
`, borderClassName, {
'univer-text-white': headerBgIsDark,
'univer-text-gray-900': !headerBgIsDark,
})}
style={{
background: headerBg,
color: new ColorKit(headerBg).isDark() ? '#fff' : '#000',
}}
>
{localeService.t('sheets-table.header')}
@@ -256,10 +264,12 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
`, borderClassName)}
>
<div
className={clsx('univer-h-4 univer-w-4 univer-rounded-lg univer-bg-gray-400', borderClassName)}
className={clsx('univer-h-4 univer-w-4 univer-rounded-lg univer-bg-gray-400', borderClassName, {
'univer-text-white': headerBgIsDark,
'univer-text-gray-900': !headerBgIsDark,
})}
style={{
background: headerBg,
color: new ColorKit(headerBg).isDark() ? '#fff' : '#000',
}}
/>
<DropdownSingle className="univer-h-2 univer-w-2" />
@@ -271,10 +281,12 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
className={clsx(`
univer-box-border univer-h-full univer-w-52 univer-rounded-sm univer-text-center
univer-leading-9
`, borderClassName)}
`, borderClassName, {
'univer-text-white': firstRowBgIsDark,
'univer-text-gray-900': !firstRowBgIsDark,
})}
style={{
background: firstRowBg,
color: new ColorKit(firstRowBg).isDark() ? '#fff' : '#000',
}}
>
{localeService.t('sheets-table.firstLine')}
@@ -319,10 +331,12 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
className={clsx(`
univer-box-border univer-h-full univer-w-52 univer-rounded-sm univer-text-center
univer-leading-9
`, borderClassName)}
`, borderClassName, {
'univer-text-white': secondRowBgIsDark,
'univer-text-gray-900': !secondRowBgIsDark,
})}
style={{
background: secondRowBg,
color: new ColorKit(secondRowBg).isDark() ? '#fff' : '#000',
}}
>
{localeService.t('sheets-table.secondLine')}
@@ -365,10 +379,12 @@ export const SheetTableThemePanel = (props: ISheetTableThemePanelProps) => {
className={clsx(`
univer-box-border univer-h-full univer-w-52 univer-rounded-sm univer-text-center
univer-leading-9
`, borderClassName)}
`, borderClassName, {
'univer-text-white': lastRowBgIsDark,
'univer-text-gray-900': !lastRowBgIsDark,
})}
style={{
background: lastRowBg,
color: new ColorKit(lastRowBg).isDark() ? '#fff' : '#000',
}}
>
{localeService.t('sheets-table.footer')}
@@ -67,6 +67,7 @@ export const MenuItemInput = (props: IMenuItemInputProps) => {
<div className="univer-w-16" onClick={(e) => e.stopPropagation()}>
<InputNumber
value={Number(inputValue)}
size="mini"
precision={0}
min={min}
max={max}
@@ -238,12 +238,7 @@ export const DefinedNameInput = (props: IDefinedNameInputProps) => {
)
)
: (FormulaEditor && (
<div
className={`
univer-relative univer-mt-4 univer-h-full univer-rounded univer-px-1.5 univer-transition-all
univer-duration-150
`}
>
<div className="univer-relative univer-mt-4 univer-h-full">
<div className="univer-relative univer-h-8 univer-select-none">
<FormulaEditor
ref={formulaEditorRef}
@@ -289,17 +284,18 @@ export const DefinedNameInput = (props: IDefinedNameInputProps) => {
/>
</div>
<div
className={clsx('univer-items-center univer-text-sm univer-text-red-500', {
className={clsx('univer-items-center univer-gap-1 univer-text-sm univer-text-red-500', {
'univer-hidden': validString.length === 0,
'univer-flex': validString.length !== 0,
})}
>
<span className="univer-mr-0.5">
<span>
{validString}
</span>
<ErrorSingle />
</div>
<div>
<div className="univer-flex univer-gap-2">
<Button
onClick={() => {
cancel?.();
@@ -308,7 +304,6 @@ export const DefinedNameInput = (props: IDefinedNameInputProps) => {
{localeService.t('definedName.cancel')}
</Button>
<Button
style={{ marginLeft: 15 }}
variant="primary"
onClick={confirmChange}
>
@@ -77,7 +77,7 @@ const SelectList = (props: ISelectListProps) => {
style={style}
>
<div
className="univer-flex-shrink-0 univer-flex-grow-0 univer-px-[14px] univer-py-2 univer-text-xs"
className="univer-flex-shrink-0 univer-flex-grow-0 univer-px-3.5 univer-py-2 univer-text-xs"
>
{title}
</div>
@@ -127,7 +127,7 @@ const SelectList = (props: ISelectListProps) => {
? (
<>
<span>{item.label.substring(0, index)}</span>
<span style={{ fontWeight: 'bold' }}>{item.label.substring(index, index + lowerFilter.length)}</span>
<span className="univer-font-semibold">{item.label.substring(index, index + lowerFilter.length)}</span>
<span>{item.label.substring(index + lowerFilter.length)}</span>
</>
)
@@ -139,7 +139,7 @@ const SelectList = (props: ISelectListProps) => {
univer-text-base univer-text-primary-500
`}
>
{selected ? <CheckMarkSingle /> : null}
{selected && <CheckMarkSingle className="univer-text-primary-600" />}
</div>
</div>
);
@@ -150,7 +150,7 @@ const SelectList = (props: ISelectListProps) => {
<>
<div
className={`
univer-my-1 univer-h-[1px] univer-flex-shrink-0 univer-flex-grow-0 univer-bg-gray-200
univer-my-1 univer-h-px univer-flex-shrink-0 univer-flex-grow-0 univer-bg-gray-200
dark:!univer-bg-gray-700
`}
/>
@@ -255,13 +255,13 @@ export function FormulaBar(props: IProps) {
<div
data-u-comp="formula-bar"
className={clsx(`
univer-box-border univer-flex univer-h-7 univer-bg-white univer-transition-[height] univer-ease-linear
univer-box-border univer-flex univer-bg-white univer-transition-[height] univer-ease-linear
dark:!univer-bg-gray-900
`, borderBottomClassName, className)}
style={{
height: ArrowDirection.Down === arrowDirection ? '28px' : '82px',
pointerEvents: editDisable ? 'none' : 'auto',
}}
`, borderBottomClassName, className, {
'univer-h-7': arrowDirection === ArrowDirection.Down,
'univer-h-20': arrowDirection === ArrowDirection.Up,
'univer-pointer-events-none': editDisable,
})}
>
<div className="univer-relative univer-box-border univer-h-full univer-w-[100px]">
<DefinedName disable={disableDefinedName ?? editDisable} />
@@ -301,12 +301,12 @@ export function FormulaBar(props: IProps) {
<CheckMarkSingle />
</span>
<span
className={clsx(`
className={`
univer-flex univer-cursor-pointer univer-items-center univer-justify-center univer-rounded
univer-p-1 univer-text-base
dark:!univer-text-white dark:hover:!univer-bg-gray-700
hover:univer-bg-gray-100
`)}
`}
onClick={handlerFxBtnClick}
>
<FxSingle />
@@ -316,10 +316,10 @@ export function FormulaBar(props: IProps) {
<div className="univer-flex univer-w-full univer-flex-1 univer-overflow-hidden univer-pl-3">
<div
ref={ref}
className="univer-relative univer-flex-1"
onPointerDown={handlePointerDown}
onPointerUp={handlePointerUp}
ref={ref}
style={{ pointerEvents: hideEditor ? 'none' : 'auto' }}
>
{FormulaEditor && (
@@ -354,17 +354,14 @@ export function FormulaBar(props: IProps) {
)}
{/* When the editor is hidden, we just cover a div on the editor because re-instantiate
the formula editor will be expensive. */}
{hideEditor
? (
<div
className={`
univer-pointer-events-none univer-relative univer-left-0 univer-top-0
univer-z-[100] univer-h-full univer-w-full univer-cursor-not-allowed
univer-bg-white
`}
/>
)
: null}
{hideEditor && (
<div
className={`
univer-pointer-events-none univer-relative univer-left-0 univer-top-0 univer-z-[100]
univer-h-full univer-w-full univer-cursor-not-allowed univer-bg-white
`}
/>
)}
</div>
<div
className={clsx(`
@@ -374,13 +371,11 @@ export function FormulaBar(props: IProps) {
`, { 'univer-cursor-not-allowed univer-text-gray-200 dark:!univer-text-gray-700': editDisable })}
onClick={handleArrowClick}
>
{arrowDirection === ArrowDirection.Down
? (
<DropdownSingle />
)
: (
<DropdownSingle style={{ transform: 'rotateZ(180deg)' }} />
)}
<DropdownSingle
className={clsx({
'univer-rotate-180': arrowDirection === ArrowDirection.Up,
})}
/>
</div>
</div>
</div>
@@ -15,7 +15,7 @@
*/
import type { IScrollState } from './sheet-bar-tabs/utils/slide-tab-bar';
import { ICommandService, IPermissionService } from '@univerjs/core';
import { ICommandService, IPermissionService, throttle } from '@univerjs/core';
import { IncreaseSingle, MoreSingle } from '@univerjs/icons';
import { InsertSheetCommand, WorkbookCreateSheetPermission, WorkbookEditablePermission } from '@univerjs/sheets';
import { useDependency, useObservable } from '@univerjs/ui';
@@ -42,22 +42,22 @@ export const SheetBar = () => {
const workbookEditablePermission = useObservable(permissionService.getPermissionPoint$(new WorkbookEditablePermission(unitId)?.id));
const workbookCreateSheetPermission = useObservable(permissionService.getPermissionPoint$(new WorkbookCreateSheetPermission(unitId)?.id));
useEffect(() => {
const subscription = sheetBarService.scroll$.subscribe((state: IScrollState) => {
updateScrollButtonState(state);
});
return () => {
subscription.unsubscribe();
};
}, []);
const updateScrollButtonState = (state: IScrollState) => {
const { leftEnd, rightEnd } = state;
setLeftScrollState(leftEnd);
setRightScrollState(rightEnd);
};
useEffect(() => {
const subscription = sheetBarService.scroll$.subscribe(throttle((state: IScrollState) => {
updateScrollButtonState(state);
}, 100));
return () => {
subscription.unsubscribe();
};
}, []);
// Complete the _addSheet, handleScrollLeft, and handleScrollRight functions
const addSheet = () => {
commandService.executeCommand(InsertSheetCommand.id);
@@ -53,7 +53,16 @@ export function SheetBarButton(props: IBaseSheetBarButtonProps) {
};
return (
<Button data-u-comp="sheet-bar-append-button" size="small" disabled={disabled} onClick={handleClick} style={style} {...restProps} variant="text" className={className}>
<Button
data-u-comp="sheet-bar-append-button"
className={className}
size="small"
disabled={disabled}
style={style}
variant="text"
onClick={handleClick}
{...restProps}
>
{children}
</Button>
);
@@ -130,9 +130,8 @@ export const ThreadCommentEditor = forwardRef<IThreadCommentEditorInstance, IThr
/>
{editing
? (
<div className="univer-mt-3 univer-flex univer-flex-row univer-justify-end">
<div className="univer-mt-3 univer-flex univer-flex-row univer-justify-end univer-gap-2">
<Button
style={{ marginRight: 12 }}
onClick={() => {
onCancel?.();
setEditing(false);
@@ -356,18 +356,14 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
return (
<div
id={`${prefix}-${unitId}-${subUnitId}-${id}`}
className={clsx(
`
univer-relative univer-box-border univer-rounded-md univer-bg-white univer-p-4
dark:!univer-bg-gray-900 dark:!univer-text-white
`,
borderClassName,
{
'univer-w-[278px]': !full,
'univer-w-full': full,
'univer-shadow': !resolved && (showHighlight || isHover || prefix === 'cell'),
}
)}
className={clsx(`
univer-relative univer-box-border univer-rounded-md univer-bg-white univer-p-4
dark:!univer-bg-gray-900 dark:!univer-text-white
`, borderClassName, {
'univer-w-[278px]': !full,
'univer-w-full': full,
'univer-shadow': !resolved && (showHighlight || isHover || prefix === 'cell'),
})}
style={style}
onClick={onClick}
onMouseEnter={() => {
@@ -379,16 +375,14 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
setIsHover(false);
}}
>
{!resolved && showHighlight
? (
<div
className={`
univer-absolute univer-left-0 univer-right-0 univer-top-0 univer-h-1.5 univer-rounded-t-md
univer-bg-yellow-400
`}
/>
)
: null}
{!resolved && showHighlight && (
<div
className={`
univer-absolute univer-left-0 univer-right-0 univer-top-0 univer-h-1.5 univer-rounded-t-md
univer-bg-yellow-400
`}
/>
)}
<div
className={`
univer-mb-4 univer-flex univer-flex-row univer-items-center univer-justify-between univer-text-sm
@@ -410,44 +404,41 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
</div>
</Tooltip>
</div>
{comments
? (
<div className="univer-flex univer-flex-shrink-0 univer-flex-grow-0 univer-flex-row">
<div
className={clsx(
`
{!!comments && (
<div className="univer-flex univer-flex-shrink-0 univer-flex-grow-0 univer-flex-row">
<div
className={clsx(
`
univer-ml-1 univer-inline-flex univer-h-6 univer-w-6 univer-cursor-pointer
univer-items-center univer-justify-center univer-rounded-[3px] univer-text-base
dark:hover:!univer-bg-gray-800
hover:univer-bg-gray-50
`,
{
'univer-text-green-500': resolved,
}
)}
onClick={handleResolve}
>
{resolved ? <ResolvedSingle /> : <SolveSingle />}
</div>
{currentUser?.userID === comments.root.personId
? (
<div
className={`
univer-ml-1 univer-inline-flex univer-h-6 univer-w-6 univer-cursor-pointer
univer-items-center univer-justify-center univer-rounded-[3px] univer-text-base
dark:hover:!univer-bg-gray-800
hover:univer-bg-gray-50
`,
{
'univer-text-green-500': resolved,
}
)}
onClick={handleResolve}
>
{resolved ? <ResolvedSingle /> : <SolveSingle />}
</div>
{currentUser?.userID === comments.root.personId
? (
<div
className={`
univer-ml-1 univer-inline-flex univer-h-6 univer-w-6 univer-cursor-pointer
univer-items-center univer-justify-center univer-rounded-[3px]
univer-text-base
dark:hover:!univer-bg-gray-800
hover:univer-bg-gray-50
`}
onClick={handleDeleteRoot}
>
<DeleteSingle />
</div>
)
: null}
</div>
)
: null}
`}
onClick={handleDeleteRoot}
>
<DeleteSingle />
</div>
)
: null}
</div>
)}
</div>
<div
ref={scroller}
@@ -456,7 +447,6 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
{renderComments.map(
(item) => (
<ThreadCommentItem
onClose={onClose}
unitId={unitId}
subUnitId={subUnitId}
item={item}
@@ -465,6 +455,7 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
editing={editingId === item.id}
resolved={comments?.root.resolved}
type={type}
onClose={onClose}
onEditingChange={(editing) => {
if (editing) {
setEditingId(item.id);
@@ -498,55 +489,53 @@ export const ThreadCommentTree = (props: IThreadCommentTreeProps) => {
)
)}
</div>
{editorVisible
? (
<div>
<ThreadCommentEditor
key={`${autoFocus}`}
ref={editorRef}
type={type}
unitId={unitId}
subUnitId={subUnitId}
onSave={async ({ text, attachments }) => {
const comment: IThreadComment = {
text,
attachments,
dT: getDT(),
id: generateRandomId(),
ref: refStr!,
personId: currentUser?.userID!,
parentId: comments?.root.id,
{editorVisible && (
<div>
<ThreadCommentEditor
key={`${autoFocus}`}
ref={editorRef}
type={type}
unitId={unitId}
subUnitId={subUnitId}
onSave={async ({ text, attachments }) => {
const comment: IThreadComment = {
text,
attachments,
dT: getDT(),
id: generateRandomId(),
ref: refStr!,
personId: currentUser?.userID!,
parentId: comments?.root.id,
unitId,
subUnitId,
threadId: comments?.root.threadId!,
};
if (onAddComment?.(comment) === false) {
return;
}
await commandService.executeCommand(
AddCommentCommand.id,
{
unitId,
subUnitId,
threadId: comments?.root.threadId!,
};
if (onAddComment?.(comment) === false) {
return;
}
await commandService.executeCommand(
AddCommentCommand.id,
{
unitId,
subUnitId,
comment,
} as IAddCommentCommandParams
);
if (scroller.current) {
scroller.current.scrollTop = scroller.current.scrollHeight;
}
}}
autoFocus={autoFocus || (!comments)}
onCancel={() => {
if (!comments) {
onClose?.();
}
}}
/>
</div>
)
: null}
comment,
} as IAddCommentCommandParams
);
if (scroller.current) {
scroller.current.scrollTop = scroller.current.scrollHeight;
}
}}
autoFocus={autoFocus || (!comments)}
onCancel={() => {
if (!comments) {
onClose?.();
}
}}
/>
</div>
)}
</div>
);
};
+4 -4
View File
@@ -298,12 +298,11 @@ export class ComponentManager {
return value.component;
} else if (value?.framework === 'vue3') {
// TODO: slot support
return (props: any) => cloneElement(
// eslint-disable-next-line ts/no-explicit-any, react/no-clone-element
return (props: Record<string, any>) => cloneElement(
createElement(VueComponentWrapper, {
component: value.component,
props: {
...props,
},
props,
})
);
} else {
@@ -329,6 +328,7 @@ async function renderVue3Component(VueComponent: ReturnType<typeof defineCompone
document.body.removeChild(container);
};
} catch (error) {
console.warn('Vue3 component render error', error);
}
}
@@ -110,13 +110,31 @@ export function CustomLabel(props: ICustomLabelProps) {
const CustomComponent = componentManager.get(labelName);
if (CustomComponent) {
nodes.push(<CustomComponent key={index++} {...customProps} className={className} value={realValue} />);
nodes.push(
<CustomComponent
key={index++}
{...customProps}
className={className}
value={realValue}
/>
);
} else {
nodes.push(<span key={index++} className={className}>{localeService.t(labelName)}</span>);
nodes.push(
<span
key={index++}
className={className}
>
{localeService.t(labelName)}
</span>
);
}
}
if (title) {
nodes.push(<span key={index++} className={className}>{typeof title === 'string' ? localeService.t(title) : title}</span>);
nodes.push(
<span key={index++} className={className}>
{typeof title === 'string' ? localeService.t(title) : title}
</span>
);
}
return <>{nodes}</>;
@@ -16,6 +16,7 @@
import type { NamedStyleType } from '@univerjs/core';
import { LocaleService, NAMED_STYLE_MAP } from '@univerjs/core';
import { clsx } from '@univerjs/design';
import { useDependency } from '../../utils/di';
export const HeadingItem = (props: { value: NamedStyleType; text: string }) => {
@@ -26,10 +27,11 @@ export const HeadingItem = (props: { value: NamedStyleType; text: string }) => {
return (
<span
className="univer-text-sm"
className={clsx('univer-text-sm', {
'univer-font-bold': style?.bl,
})}
style={{
fontSize: style?.fs,
fontWeight: style?.bl ? 'bold' : 'normal',
color: style?.cl?.rgb ?? undefined,
}}
>
@@ -147,8 +147,8 @@ export const FloatDomSingle = memo((props: { layer: IFloatDom; id: string }) =>
<div
id={id}
ref={innerDomRef}
className="univer-overflow-hidden"
style={{ position: 'absolute', ...innerStyle.current }}
className="univer-absolute univer-overflow-hidden"
style={{ ...innerStyle.current }}
>
{component}
</div>
@@ -71,16 +71,13 @@ export const PrintFloatDomSingle = memo((props: { layer: IFloatDom; id: string;
return (
<div
ref={domRef}
className="univer-z-10"
className="univer-absolute univer-z-10 univer-origin-center univer-overflow-hidden"
style={{
position: 'absolute',
top: topRef.current,
left: leftRef.current,
width: Math.max(position.endX - position.startX - 2, 0),
height: Math.max(position.endY - position.startY - 2, 0),
transform: transformRef.current,
overflow: 'hidden',
transformOrigin: 'center center',
}}
onPointerMove={(e) => {
layer.onPointerMove(e.nativeEvent);
@@ -96,10 +93,10 @@ export const PrintFloatDomSingle = memo((props: { layer: IFloatDom; id: string;
}}
>
<div
id={id}
ref={innerDomRef}
className="univer-overflow-hidden"
style={{ position: 'absolute', ...innerStyle }}
id={id}
className="univer-absolute univer-overflow-hidden"
style={{ ...innerStyle }}
>
{component}
</div>
@@ -19,6 +19,7 @@ import type { RefObject } from 'react';
import type { Observable } from 'rxjs';
import type { IUniverUIConfig } from '../../../controllers/config.schema';
import { IConfigService } from '@univerjs/core';
import { clsx } from '@univerjs/design';
import React, { createContext, useContext, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import { useEvent } from '../../../components/hooks/event';
@@ -323,10 +324,13 @@ function RectPopup(props: IRectPopupProps) {
<section
data-u-comp="rect-popup"
ref={nodeRef}
className={`
className={clsx(`
univer-pointer-events-auto univer-fixed univer-left-[-9999px] univer-top-[-9999px] univer-z-[1020]
`}
style={{ ...positionRef.current, ...hidden ? { display: 'none' } : null, zIndex }}
`, {
'univer-hidden': hidden,
'univer-animate-in univer-fade-in-70': !hidden,
})}
style={{ ...positionRef.current, zIndex }}
onPointerDown={(e) => e.stopPropagation()}
onClick={onClick}
onPointerEnter={onPointerEnter}
@@ -220,7 +220,7 @@ export function Ribbon(props: IRibbonProps) {
for (const { width, key } of sortedToolbarItems) {
totalWidth += width + 8;
if (totalWidth >= avaliableWidth) {
if (totalWidth > avaliableWidth) {
newCollapsedIds.push(key);
}
}
@@ -372,6 +372,7 @@ export function Ribbon(props: IRibbonProps) {
univer-pl-3 univer-pr-2 univer-text-sm univer-text-white
dark:!univer-bg-gray-200 dark:!univer-text-gray-800
`}
onClick={() => setGroupSelectorVisible(true)}
>
{localeService.t(activatedTab)}
<MoreDownSingle
@@ -401,9 +402,15 @@ export function Ribbon(props: IRibbonProps) {
{/* More functions dropdown */}
{collapsedIds.length > 0 && (
<div data-u-comp="ribbon-toolbar-more" className="univer-pl-2">
<div
data-u-comp="ribbon-toolbar-more"
className={`
univer-pl-2
rtl:univer-pr-2
`}
>
<Dropdown
collisionPadding={{ right: 12 }}
collisionPadding={{ right: 12, left: 12 }}
overlay={(
<div
className={`
@@ -66,9 +66,9 @@ export const TooltipWrapper = forwardRef<ITooltipWrapperRef, ITooltipProps>((pro
return (
<Tooltip
{...tooltipProps}
visible={tooltipVisible}
onVisibleChange={handleChangeTooltipVisible}
{...tooltipProps}
>
<span ref={spanRef}>
<TooltipWrapperContext.Provider value={contextValue}>
@@ -81,7 +81,7 @@ export const TooltipWrapper = forwardRef<ITooltipWrapperRef, ITooltipProps>((pro
export function DropdownWrapper(props: Omit<Partial<IDropdownProps>, 'overlay'> & { overlay: ReactNode; align?: 'start' | 'end' | 'center' }) {
const { children, overlay, disabled, align = 'start' } = props;
const { setDropdownVisible } = useContext(TooltipWrapperContext);
const { dropdownVisible, setDropdownVisible } = useContext(TooltipWrapperContext);
function handleVisibleChange(visible: boolean) {
setDropdownVisible(visible);
@@ -96,6 +96,7 @@ export function DropdownWrapper(props: Omit<Partial<IDropdownProps>, 'overlay'>
</div>
)}
disabled={disabled}
open={dropdownVisible}
onOpenChange={handleVisibleChange}
>
<div className="univer-h-full" onClick={(e) => e.stopPropagation()}>
@@ -157,7 +158,7 @@ export function DropdownMenuWrapper({
disabled?: boolean;
onOptionSelect: (option: IValueOption) => void;
}) {
const { setDropdownVisible } = useContext(TooltipWrapperContext);
const { dropdownVisible, setDropdownVisible } = useContext(TooltipWrapperContext);
const menuManagerService = useDependency(IMenuManagerService);
const [hiddenStates, setHiddenStates] = useState<Record<string, boolean>>({});
@@ -280,6 +281,7 @@ export function DropdownMenuWrapper({
align="start"
items={items}
disabled={disabled}
open={dropdownVisible}
onOpenChange={handleVisibleChange}
>
{children}
@@ -327,6 +329,7 @@ export function DropdownMenuWrapper({
align="start"
items={items}
disabled={disabled}
open={dropdownVisible}
onOpenChange={handleVisibleChange}
>
{children}