snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-16 05:09:45 +05:00
commit bcf6ef63ad
7118 changed files with 1236854 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { LocaleService } from '@univerjs/core';
import { InputNumber, Select } from '@univerjs/design';
import { getCurrencyType, getDecimalFromPattern, setPatternDecimal } from '@univerjs/sheets-numfmt';
import { useDependency } from '@univerjs/ui';
import { useContext, useLayoutEffect, useMemo, useState } from 'react';
import { UserHabitCurrencyContext } from '../../controllers/user-habit.controller';
export const isAccountingPanel = (pattern: string) => {
const type = getCurrencyType(pattern);
return !!type && pattern.startsWith('_(');
};
export function AccountingPanel(props: IBusinessComponentProps) {
const { defaultPattern, onActionChange, onChange } = props;
const [decimal, setDecimal] = useState(() => getDecimalFromPattern(defaultPattern || '', 2));
const userHabitCurrency = useContext(UserHabitCurrencyContext);
const [suffix, setSuffix] = useState(() => getCurrencyType(defaultPattern) || userHabitCurrency[0]);
const options = useMemo(() => userHabitCurrency.map((key) => ({ label: key, value: key })), []);
const localeService = useDependency(LocaleService);
useLayoutEffect(() => {
onActionChange(() => setPatternDecimal(`_("${suffix}"* #,##0${decimal > 0 ? '.0' : ''}_)`, decimal));
}, [decimal, onActionChange, suffix]);
const handleSelect = (v: string) => {
setSuffix(v);
onChange(setPatternDecimal(`_("${v}"* #,##0${decimal > 0 ? '.0' : ''}_)`, decimal));
};
const handleDecimalChange = (v: number | null) => {
const decimal = v || 0;
setDecimal(decimal);
onChange(setPatternDecimal(`_("${suffix}"* #,##0${decimal > 0 ? '.0' : ''}_)`, decimal));
};
return (
<div>
<div className="univer-mt-4 univer-flex univer-justify-between">
<div className="option">
<div className="univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.decimalLength')}
</div>
<div className="univer-mt-2 univer-w-32">
<InputNumber
value={decimal}
step={1}
precision={0}
max={20}
min={0}
onChange={handleDecimalChange}
/>
</div>
</div>
<div className="option">
<div className="univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.currencyType')}
</div>
<div className="univer-mt-2 univer-w-36">
<Select
options={options}
value={suffix}
onChange={handleSelect}
/>
</div>
</div>
</div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.accountingDes')}
</div>
</div>
);
};

View File

@@ -0,0 +1,122 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { isPatternEqualWithoutDecimal, LocaleService } from '@univerjs/core';
import { InputNumber, Select, SelectList } from '@univerjs/design';
import {
getCurrencyFormatOptions,
getCurrencyType,
getDecimalFromPattern,
setPatternDecimal,
} from '@univerjs/sheets-numfmt';
import { useDependency } from '@univerjs/ui';
import { useContext, useLayoutEffect, useMemo, useState } from 'react';
import { UserHabitCurrencyContext } from '../../controllers/user-habit.controller';
export const isCurrencyPanel = (pattern: string) => {
const type = getCurrencyType(pattern);
return !!type && !pattern.startsWith('_(');
};
export function CurrencyPanel(props: IBusinessComponentProps) {
const { onActionChange, onChange: onValueChange } = props;
const localeService = useDependency(LocaleService);
const userHabitCurrency = useContext(UserHabitCurrencyContext);
const [suffix, setSuffix] = useState(() => getCurrencyType(props.defaultPattern) || userHabitCurrency[0]);
const [decimal, setDecimal] = useState(() => getDecimalFromPattern(props.defaultPattern || '', 2));
const [pattern, setPattern] = useState(() => {
const negativeOptions = getCurrencyFormatOptions(suffix);
const pattern =
negativeOptions.find((item) => isPatternEqualWithoutDecimal(item.value, props.defaultPattern))?.value ||
negativeOptions[0].value;
return pattern;
});
const negativeOptions = useMemo(() => getCurrencyFormatOptions(suffix), [suffix]);
const options = useMemo(() => userHabitCurrency.map((key) => ({ label: key, value: key })), [userHabitCurrency]);
useLayoutEffect(() => {
onActionChange(() => setPatternDecimal(pattern, decimal));
}, [decimal, onActionChange, pattern]);
const onSelect = (value: string) => {
if (value === undefined) {
return;
}
setSuffix(value);
const pattern = getCurrencyFormatOptions(value)[0].value;
setPattern(pattern);
onValueChange(setPatternDecimal(pattern, decimal));
};
const onChange = (value: any) => {
if (value === undefined) {
return;
}
setPattern(value);
onValueChange(setPatternDecimal(value, decimal));
};
const onDecimalChange = (v: number | null) => {
setDecimal(v || 0);
onValueChange(setPatternDecimal(pattern, v || 0));
};
return (
<div>
<div className="univer-mt-4 univer-flex univer-justify-between">
<div className="option">
<div className="univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.decimalLength')}
</div>
<div className="univer-mt-2 univer-w-32">
<InputNumber
value={decimal}
max={20}
min={0}
onChange={onDecimalChange}
/>
</div>
</div>
<div className="option">
<div className="univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.currencyType')}
</div>
<div className="univer-mt-2 univer-w-36">
<Select
value={suffix}
options={options}
onChange={onSelect}
/>
</div>
</div>
</div>
<div className="label univer-mt-4">
{localeService.t<LocaleKey>('sheets-numfmt-ui.negType')}
</div>
<div className="univer-mt-2">
<SelectList value={pattern} options={negativeOptions} onChange={onChange} />
</div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.currencyDes')}
</div>
</div>
);
};

View File

@@ -0,0 +1,126 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { ILocalStorageService, LocaleService } from '@univerjs/core';
import { borderClassName, clsx, Input } from '@univerjs/design';
import { CheckMarkIcon } from '@univerjs/icons';
import { CURRENCYFORMAT, DATEFMTLISG, NUMBERFORMAT } from '@univerjs/sheets-numfmt';
import { useDependency } from '@univerjs/ui';
import { useEffect, useLayoutEffect, useState } from 'react';
import { UserHabitController } from '../../controllers/user-habit.controller';
const key = 'customFormat';
const historyPatternKey = 'numfmt_custom_pattern';
export function CustomFormat(props: IBusinessComponentProps) {
const { defaultPattern, onActionChange, onChange } = props;
const userHabitController = useDependency(UserHabitController);
const localStorageService = useDependency(ILocalStorageService);
const localeService = useDependency(LocaleService);
const [pattern, setPattern] = useState(defaultPattern);
useLayoutEffect(() => {
onActionChange(() => {
userHabitController.markHabit(key, pattern);
localStorageService.getItem<string[]>(historyPatternKey).then((list = []) => {
const _list = [...new Set([pattern, ...(list || [])])].splice(0, 10).filter((e) => !!e);
localStorageService.setItem(historyPatternKey, _list);
});
return pattern;
});
}, [localStorageService, onActionChange, pattern, userHabitController]);
const [options, setOptions] = useState<(string | number)[]>([]);
useEffect(() => {
let cancelled = false;
void localStorageService.getItem<string[]>(historyPatternKey).then((historyList) => {
const list = [
...CURRENCYFORMAT.map((item) => item.suffix('$')),
...DATEFMTLISG.map((item) => item.suffix),
...NUMBERFORMAT.map((item) => item.suffix),
...(historyList ?? []),
];
return userHabitController.addHabit(key, []).then(() => userHabitController.getHabit(key, list));
}).then((list) => {
if (!cancelled) {
setOptions([...new Set(list)]);
}
});
return () => {
cancelled = true;
};
}, [localStorageService, userHabitController]);
const handleClick = (p: string) => {
setPattern(p);
onChange(p);
};
const handleBlur = () => {
onChange(pattern);
};
return (
<div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.customFormat')}
</div>
<Input
placeholder={localeService.t<LocaleKey>('sheets-numfmt-ui.customFormat')}
onBlur={handleBlur}
value={pattern}
onChange={setPattern}
className="univer-mt-2 univer-w-full"
/>
<div
className={clsx(
'univer-mt-2 univer-max-h-[400px] univer-overflow-auto univer-rounded-lg univer-p-2',
borderClassName
)}
>
{options.map((p) => (
<div
key={p}
onClick={() => handleClick(p as string)}
className={`
univer-flex univer-cursor-pointer univer-items-center univer-gap-1.5 univer-py-1.5
univer-text-sm
`}
>
<div className="univer-flex univer-w-4 univer-items-center univer-text-primary-600">
{pattern === p && <CheckMarkIcon />}
</div>
<div>
{p}
</div>
</div>
))}
</div>
<div
className={`
univer-mt-3 univer-text-sm univer-text-gray-600
dark:!univer-text-gray-200
`}
>
{localeService.t<LocaleKey>('sheets-numfmt-ui.customFormatDes')}
</div>
</div>
);
}

View File

@@ -0,0 +1,80 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { LocaleService, numfmt } from '@univerjs/core';
import { SelectList } from '@univerjs/design';
import { getDateFormatOptions } from '@univerjs/sheets-numfmt';
import { useDependency } from '@univerjs/ui';
import { useLayoutEffect, useMemo, useState } from 'react';
export const isDatePanel = (pattern: string) => {
const info = numfmt.getFormatInfo(pattern);
return (
getDateFormatOptions()
.map((item) => item.value)
.includes(pattern) || ['date', 'datetime', 'time'].includes(info.type)
);
};
export function DatePanel(props: IBusinessComponentProps) {
const { onActionChange, onChange, defaultPattern } = props;
const options = useMemo(getDateFormatOptions, []);
const localeService = useDependency(LocaleService);
const [suffix, setSuffix] = useState(() => {
if (defaultPattern) {
const item = options.find((item) => item.value === defaultPattern);
if (item) {
return item.value;
}
}
return options[0].value;
});
useLayoutEffect(() => {
onActionChange(() => suffix);
}, [onActionChange, suffix]);
const handleChange = (v: any) => {
if (v === undefined) {
return;
}
setSuffix(v);
onChange(v);
};
return (
<div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.dateType')}
</div>
<div className="univer-mt-2">
<SelectList value={suffix} options={options} onChange={handleChange} />
</div>
<div
className={`
univer-mt-3.5 univer-text-sm/5 univer-text-gray-600
dark:!univer-text-gray-200
`}
>
{localeService.t<LocaleKey>('sheets-numfmt-ui.dateDes')}
</div>
</div>
);
};

View File

@@ -0,0 +1,45 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { LocaleService } from '@univerjs/core';
import { useDependency } from '@univerjs/ui';
import { useLayoutEffect } from 'react';
export const isGeneralPanel = (pattern: string) => !pattern;
export function GeneralPanel(props: IBusinessComponentProps) {
const localeService = useDependency(LocaleService);
const { onActionChange } = props;
useLayoutEffect(() => {
onActionChange(() => '');
}, [onActionChange]);
return (
<div>
<div
className={`
univer-mt-3.5 univer-text-sm/5 univer-text-gray-600
dark:!univer-text-gray-200
`}
>
{localeService.t<LocaleKey>('sheets-numfmt-ui.generalDes')}
</div>
</div>
);
}

View File

@@ -0,0 +1,128 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { FormatType } from '@univerjs/sheets';
import type { LocaleKey } from '../../locale/types';
import { ICommandService, LocaleService, Range, RegionService } from '@univerjs/core';
import { Separator } from '@univerjs/design';
import { SheetsSelectionsService } from '@univerjs/sheets';
import {
getCurrencySymbolByLocale,
getPatternPreview,
getPatternType,
SetNumfmtCommand,
SheetsNumfmtCellContentController,
} from '@univerjs/sheets-numfmt';
import { ILayoutService, useDependency, useObservable } from '@univerjs/ui';
import { useMemo } from 'react';
import { OpenNumfmtPanelOperator } from '../../commands/operations/open.numfmt.panel.operation';
import { MENU_OPTIONS } from '../../menu/number-format-options';
export const MORE_NUMFMT_TYPE_KEY = 'sheets-numfmt-ui.moreNumfmtType';
export const OPTIONS_KEY = 'sheets-numfmt-ui.moreNumfmtType.options';
export function MoreNumfmtType(props: { value?: string }) {
const { value } = props;
const localeService = useDependency(LocaleService);
const text = value ?? localeService.t<LocaleKey>('sheets-numfmt-ui.general');
return <span className="univer-text-sm">{text}</span>;
};
export function Options() {
const commandService = useDependency(ICommandService);
const localeService = useDependency(LocaleService);
const regionService = useDependency(RegionService);
const layoutService = useDependency(ILayoutService);
const sheetsNumfmtCellContentController = useDependency(SheetsNumfmtCellContentController);
const direction = useObservable(localeService.direction$, localeService.getDirection());
const region = useObservable(regionService.currentRegion$, regionService.getCurrentRegion());
const selectionManagerService = useDependency(SheetsSelectionsService);
const setNumfmt = (pattern: string | null) => {
const selection = selectionManagerService.getCurrentLastSelection();
if (!selection) {
return;
}
const range = selection.range;
const values: Array<{ row: number; col: number; pattern?: string; type?: FormatType }> = [];
Range.foreach(range, (row, col) => {
if (pattern) {
values.push({ row, col, pattern, type: getPatternType(pattern) });
} else {
values.push({ row, col });
}
});
commandService.executeCommand(SetNumfmtCommand.id, { values });
layoutService.focus();
};
const menuOptions = useMemo(() => {
const currencySymbol = getCurrencySymbolByLocale(region);
return MENU_OPTIONS(currencySymbol);
}, [region]);
const handleClick = (index: number) => {
if (index === 0) {
setNumfmt(null);
} else if (index === menuOptions.length - 1) {
// CATUION: This is a command, not a menu item
commandService.executeCommand(OpenNumfmtPanelOperator.id);
layoutService.focus();
} else {
const item = menuOptions[index] as { pattern: string };
item.pattern && setNumfmt(item.pattern);
}
};
const defaultValue = 1220;
return (
<div dir={direction} className="univer-grid univer-gap-1 univer-p-1.5">
{menuOptions.map((item, index) => {
if (item === '|') {
return <Separator key={index} />;
}
return (
<div
key={index}
className={`
univer-flex univer-h-7 univer-cursor-default univer-items-center univer-justify-between
univer-gap-6 univer-rounded univer-px-2 univer-text-sm
hover:univer-bg-gray-100
dark:hover:!univer-bg-gray-700
`}
onClick={() => handleClick(index)}
>
<span>{localeService.t<LocaleKey>(item.label)}</span>
<span
className={`
univer-text-xs univer-text-gray-500
dark:!univer-text-gray-400
`}
>
{item.pattern ? getPatternPreview(item.pattern || '', defaultValue, sheetsNumfmtCellContentController.locale).result.trim() : ''}
</span>
</div>
);
})}
</div>
);
};

View File

@@ -0,0 +1,97 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { LocaleKey } from '../../locale/types';
import type { IBusinessComponentProps } from './interface';
import { isPatternEqualWithoutDecimal, LocaleService } from '@univerjs/core';
import { InputNumber, SelectList } from '@univerjs/design';
import {
getDecimalFromPattern,
getNumberFormatOptions,
isPatternHasDecimal,
setPatternDecimal,
} from '@univerjs/sheets-numfmt';
import { useDependency } from '@univerjs/ui';
import { useLayoutEffect, useMemo, useState } from 'react';
export const isThousandthPercentilePanel = (pattern: string) =>
getNumberFormatOptions().some((item) => isPatternEqualWithoutDecimal(item.value, pattern));
export function ThousandthPercentilePanel(props: IBusinessComponentProps) {
const { onActionChange, onChange } = props;
const localeService = useDependency(LocaleService);
const options = useMemo(getNumberFormatOptions, []);
const [decimal, setDecimal] = useState(() => getDecimalFromPattern(props.defaultPattern || '', 0));
const [suffix, setSuffix] = useState(() => {
const item = options.find((item) => isPatternEqualWithoutDecimal(item.value, props.defaultPattern || ''));
return item?.value || options[0].value;
});
const pattern = useMemo(() => setPatternDecimal(suffix, Number(decimal || 0)), [suffix, decimal]);
const isInputDisable = !isPatternHasDecimal(suffix);
const handleDecimalChange = (decimal: number | null) => {
setDecimal(decimal || 0);
onChange(setPatternDecimal(suffix, Number(decimal || 0)));
};
const handleClick = (v: any) => {
if (v === undefined) {
return;
}
setDecimal(getDecimalFromPattern(v, 0));
setSuffix(v);
onChange(v);
};
useLayoutEffect(() => {
onActionChange(() => pattern);
}, [onActionChange, pattern]);
return (
<div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{localeService.t<LocaleKey>('sheets-numfmt-ui.decimalLength')}
</div>
<div className="univer-mt-2">
<InputNumber
disabled={isInputDisable}
value={decimal}
max={20}
min={0}
onChange={handleDecimalChange}
/>
</div>
<div className="univer-mt-4 univer-text-sm univer-text-gray-400">
{' '}
{localeService.t<LocaleKey>('sheets-numfmt-ui.negType')}
</div>
<div className="univer-mt-2">
<SelectList onChange={handleClick} options={options} value={suffix} />
</div>
<div
className={`
univer-mt-3.5 univer-text-sm/5 univer-text-gray-600
dark:!univer-text-gray-200
`}
>
{localeService.t<LocaleKey>('sheets-numfmt-ui.thousandthPercentileDes')}
</div>
</div>
);
};

View File

@@ -0,0 +1,22 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface IBusinessComponentProps {
onChange: (result: string) => void;
onActionChange: (action: () => string | null) => void;
defaultValue: number;
defaultPattern: string;
}

View File

@@ -0,0 +1,71 @@
/**
* Copyright 2023-present DreamNum Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Meta, StoryObj } from '@storybook/react';
import type { Dependency } from '@univerjs/core';
import type { ISheetNumfmtPanelProps } from '../../SheetNumfmtPanel';
import { LocaleService, LocaleType } from '@univerjs/core';
import { RediContext } from '@univerjs/ui';
import { useContext, useState } from 'react';
import { UserHabitController } from '../../../controllers/user-habit.controller';
import enUS from '../../../locale/en-US';
import ruRU from '../../../locale/ru-RU';
import zhCN from '../../../locale/zh-CN';
import { SheetNumfmtPanel } from '../../SheetNumfmtPanel';
const meta: Meta = {
title: 'numfmt',
parameters: {
layout: 'centered',
},
};
export default meta;
export const NumfmtPanel: StoryObj<ISheetNumfmtPanelProps> = {
render() {
const { injector } = useContext(RediContext);
const [inject] = useState(() => {
const deps: Dependency[] = [
[UserHabitController],
];
injector?.get(LocaleService).load({
[LocaleType.EN_US]: enUS,
[LocaleType.ZH_CN]: zhCN,
[LocaleType.RU_RU]: ruRU,
});
deps.forEach((dependency) => injector?.add(dependency));
return injector;
});
return (
<RediContext.Provider value={{ injector: inject }}>
<div className="univer-w-[340px]">
<SheetNumfmtPanel
value={{ defaultPattern: '', defaultValue: 123123, row: 2, col: 3 }}
onChange={(_pattern) => {
// empty
}}
/>
</div>
</RediContext.Provider>
);
},
};