mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
feat: update SheetTableThemePanel for improved theme handling and UI responsiveness (#5267)
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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': '根据当前子表回放本地录制...',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
+5
-10
@@ -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') : ''}
|
||||
|
||||
+11
-14
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user