mirror of
https://github.com/dream-num/univer.git
synced 2026-10-02 04:24:34 +08:00
perf(design): optimize clsx runtime (#7633)
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
"dependencies": {
|
||||
"@tsdown/css": "^0.22.14",
|
||||
"@typescript-eslint/parser": "^8.65.0",
|
||||
"@vitest/coverage-istanbul": "^4.1.11",
|
||||
"@vitest/coverage-istanbul": "^5.0.0",
|
||||
"autoprefixer": "^10.5.4",
|
||||
"eslint-plugin-better-tailwindcss": "^4.7.0",
|
||||
"eslint-plugin-header": "^3.1.1",
|
||||
@@ -48,7 +48,7 @@
|
||||
"tailwindcss": "3.4.18",
|
||||
"tsdown": "^0.22.14",
|
||||
"unplugin-vue": "^7.2.0",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@univerjs/icons": "1.38.0",
|
||||
|
||||
@@ -192,14 +192,14 @@ A package MUST NOT reference a key whose first segment is another package's name
|
||||
```typescript
|
||||
// In @univerjs/sheets-filter
|
||||
// 🚫 references a key from the UI package
|
||||
localeService.t('sheets-filter-ui.panel.empty')
|
||||
localeService.t<LocaleKey>('sheets-filter-ui.panel.empty')
|
||||
|
||||
// In @univerjs/sheets-filter-ui
|
||||
// 🚫 references a key from a common/utility package
|
||||
localeService.t('sheets-ui.permission.dialog.filterErr')
|
||||
localeService.t<LocaleKey>('sheets-ui.permission.dialog.filterErr')
|
||||
|
||||
// ✅ sink the key into your own locale file
|
||||
localeService.t('sheets-filter-ui.permission.filterErr')
|
||||
localeService.t<LocaleKey>('sheets-filter-ui.permission.filterErr')
|
||||
```
|
||||
|
||||
### Namespace must be the single root key
|
||||
|
||||
@@ -52,6 +52,6 @@
|
||||
"tsx": "^4.22.4",
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.11",
|
||||
"vitest": "^4.1.10"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@
|
||||
"tailwindcss": "3.4.18",
|
||||
"turbo": "^2.10.8",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "eslint --fix"
|
||||
|
||||
@@ -88,6 +88,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,6 @@
|
||||
"@univerjs/sheets": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/src/helper/clsx.generated.ts
|
||||
@@ -61,6 +61,7 @@
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"prepare": "node scripts/generate-clsx.mts",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"coverage": "vitest run --coverage",
|
||||
@@ -83,10 +84,8 @@
|
||||
"@radix-ui/react-slot": "^1.3.3",
|
||||
"@univerjs/icons": "1.38.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "1.1.1",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "2.6.0"
|
||||
"sonner": "^2.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "6.9.1",
|
||||
@@ -95,9 +94,10 @@
|
||||
"postcss": "^8.5.26",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"tailwind-merge": "2.6.0",
|
||||
"tailwindcss": "3.4.18",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import type { Config } from 'tailwind-merge';
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { createRequire } from 'node:module';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { getDefaultConfig, validators } from 'tailwind-merge';
|
||||
|
||||
type ClassGroup = Config<string, string>['classGroups'][string];
|
||||
|
||||
const config = getDefaultConfig();
|
||||
const groupNames = Object.keys(config.classGroups);
|
||||
const validatorNames = Object.keys(validators).sort() as Array<keyof typeof validators>;
|
||||
const groupIds = new Map(groupNames.map((name, index) => [name, index + 1]));
|
||||
|
||||
interface IRule {
|
||||
literals: string[];
|
||||
validators: number;
|
||||
}
|
||||
|
||||
function visit(definitions: ClassGroup, prefix: string, rules: Map<string, IRule>) {
|
||||
const rule = rules.get(prefix) ?? { literals: [], validators: 0 };
|
||||
rules.set(prefix, rule);
|
||||
for (const definition of definitions) {
|
||||
if (typeof definition === 'string') {
|
||||
rule.literals.push(definition);
|
||||
} else if (typeof definition === 'function') {
|
||||
if ('isThemeGetter' in definition) {
|
||||
visit(definition(config.theme), prefix, rules);
|
||||
continue;
|
||||
}
|
||||
|
||||
const validator = validatorNames.findIndex((name) => validators[name] === definition);
|
||||
if (validator === -1) {
|
||||
throw new Error(`Unknown Tailwind v3 validator: ${definition.name}`);
|
||||
}
|
||||
|
||||
rule.validators |= 1 << validator;
|
||||
} else {
|
||||
for (const [part, children] of Object.entries(definition)) {
|
||||
visit(children, prefix + (prefix ? '-' : '') + part, rules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const classGroups = Object.values(config.classGroups).map((definitions) => {
|
||||
const rules = new Map<string, IRule>();
|
||||
visit(definitions, '', rules);
|
||||
return Array.from(rules)
|
||||
.filter(([, rule]) => rule.literals.length || rule.validators)
|
||||
.map(([prefix, rule]) => `['${prefix}', ${rule.literals.length ? `'${rule.literals.join(' ')}'` : 'null'}, ${rule.validators}]`);
|
||||
});
|
||||
|
||||
function serializeConflicts(conflicts: Record<string, readonly string[] | undefined>) {
|
||||
return Object.entries(conflicts).map(([name, targets]) =>
|
||||
` ${groupIds.get(name)}: [${targets!.map((target) => groupIds.get(target)).join(', ')}],`
|
||||
).join('\n');
|
||||
}
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const packageDir = resolve(dirname(require.resolve('tailwind-merge')), '..');
|
||||
const license = readFileSync(resolve(packageDir, 'LICENSE.md'), 'utf8').trim();
|
||||
const header = readFileSync(new URL('../src/helper/clsx.ts', import.meta.url), 'utf8').split('\n\n')[0];
|
||||
const output = `${header}
|
||||
|
||||
// Generated by pnpm --filter @univerjs/design prepare. Do not edit.
|
||||
// Complete tailwind-merge 2.6.0 / Tailwind CSS 3.4 rules; the runtime supplies the univer- prefix.
|
||||
/*!
|
||||
${license.split('\n').map((line) => ` *${line ? ` ${line}` : ''}`).join('\n')}
|
||||
*/
|
||||
|
||||
export const VALIDATOR_NAMES = [${validatorNames.map((name) => `'${name}'`).join(', ')}] as const;
|
||||
|
||||
// Group IDs are one-based. Each rule contains a prefix, literal suffixes and a validator bitmask.
|
||||
export const CLASS_GROUPS: ReadonlyArray<ReadonlyArray<readonly [prefix: string, literals: string | null, validators: number]>> = [
|
||||
${classGroups.map((rules) => ` [${rules.join(', ')}],`).join('\n')}
|
||||
];
|
||||
|
||||
export const CLASS_CONFLICTS: Record<number, readonly number[]> = {
|
||||
${serializeConflicts(config.conflictingClassGroups)}
|
||||
};
|
||||
|
||||
export const POSTFIX_CONFLICTS: Record<number, readonly number[]> = {
|
||||
${serializeConflicts(config.conflictingClassGroupModifiers)}
|
||||
};
|
||||
`;
|
||||
|
||||
writeFileSync(new URL('../src/helper/clsx.generated.ts', import.meta.url), output);
|
||||
@@ -16,9 +16,24 @@
|
||||
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { clsx } from '../clsx';
|
||||
|
||||
describe('clsx', () => {
|
||||
it('flattens conditional values without caching mutable arrays or objects by identity', () => {
|
||||
const active = { 'univer-h-8': false };
|
||||
const values = ['univer-h-6'];
|
||||
const inputs = [values, active, [false, null, undefined, 0, Number.NaN, '', true, 7, 1n]];
|
||||
|
||||
expect(clsx(...inputs)).toBe('univer-h-6 7');
|
||||
active['univer-h-8'] = true;
|
||||
expect(clsx(...inputs)).toBe('univer-h-8 7');
|
||||
values.push('univer-p-2');
|
||||
expect(clsx(...inputs)).toBe('univer-p-2 univer-h-8 7');
|
||||
expect(clsx()).toBe('');
|
||||
expect(clsx(' \n univer-p-2\t univer-p-4 ')).toBe('univer-p-4');
|
||||
});
|
||||
|
||||
it('merges Univer-prefixed conflicting utilities', () => {
|
||||
expect(clsx('univer-h-6', 'univer-h-[78px]')).toBe('univer-h-[78px]');
|
||||
expect(clsx('univer-px-3', 'univer-px-8')).toBe('univer-px-8');
|
||||
@@ -37,4 +52,53 @@ describe('clsx', () => {
|
||||
|
||||
expect(clsx(buttonVariants({ size: 'small', className: 'univer-h-[78px]' }))).toBe('univer-h-[78px]');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['univer-pr-2 univer-px-4', 'univer-px-4'],
|
||||
['univer-px-4 univer-pr-2', 'univer-px-4 univer-pr-2'],
|
||||
['univer-p-2 univer-px-4', 'univer-p-2 univer-px-4'],
|
||||
['univer-px-4 univer-p-2', 'univer-p-2'],
|
||||
['univer-w-2 univer-h-4 univer-size-8', 'univer-size-8'],
|
||||
['univer-size-8 univer-w-2', 'univer-size-8 univer-w-2'],
|
||||
['-univer-m-2 univer-m-4', 'univer-m-4'],
|
||||
['univer-p-2 !univer-p-4 !univer-p-8', 'univer-p-2 !univer-p-8'],
|
||||
['univer-leading-8 univer-text-sm/6', 'univer-text-sm/6'],
|
||||
['univer-text-sm/6 univer-leading-8', 'univer-text-sm/6 univer-leading-8'],
|
||||
['univer-w-1/2 univer-w-3/4', 'univer-w-3/4'],
|
||||
['univer-bg-opacity-25 univer-bg-opacity-50 univer-bg-red-500/50', 'univer-bg-opacity-50 univer-bg-red-500/50'],
|
||||
['univer-text-opacity-25 univer-text-opacity-75', 'univer-text-opacity-75'],
|
||||
])('resolves directional and v3-specific conflicts: %s', (input, expected) => {
|
||||
expect(clsx(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['hover:focus:univer-p-2 focus:hover:univer-p-4', 'focus:hover:univer-p-4'],
|
||||
['hover:univer-p-2 focus:univer-p-4', 'hover:univer-p-2 focus:univer-p-4'],
|
||||
['dark:hover:!univer-p-2 hover:dark:!univer-p-4', 'hover:dark:!univer-p-4'],
|
||||
['[&:nth-child(2)]:univer-p-2 [&:nth-child(2)]:univer-p-4', '[&:nth-child(2)]:univer-p-4'],
|
||||
['hover:[&_a]:univer-p-2 [&_a]:hover:univer-p-4', 'hover:[&_a]:univer-p-2 [&_a]:hover:univer-p-4'],
|
||||
['group-hover/menu:univer-p-2 group-hover/menu:univer-p-4', 'group-hover/menu:univer-p-4'],
|
||||
['data-[state=open]:univer-p-2 data-[state=open]:univer-p-4', 'data-[state=open]:univer-p-4'],
|
||||
])('keeps variant scopes distinct: %s', (input, expected) => {
|
||||
expect(clsx(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['univer-text-[length:var(--size)] univer-text-[color:var(--color)]', 'univer-text-[length:var(--size)] univer-text-[color:var(--color)]'],
|
||||
['univer-bg-[url(https://example.com/a-b.svg)] univer-bg-red-500', 'univer-bg-[url(https://example.com/a-b.svg)] univer-bg-red-500'],
|
||||
['univer-bg-[size:20px_30px] univer-bg-cover', 'univer-bg-cover'],
|
||||
['univer-shadow-[0_1px_2px_black] univer-shadow-red-500', 'univer-shadow-[0_1px_2px_black] univer-shadow-red-500'],
|
||||
['[color:red] [color:blue] [background:red]', '[color:blue] [background:red]'],
|
||||
['hover:[--gutter:1rem] hover:[--gutter:2rem]', 'hover:[--gutter:2rem]'],
|
||||
['p-2 p-4 univer-custom univer-custom', 'p-2 p-4 univer-custom univer-custom'],
|
||||
['univer-p-unknown univer-p-2', 'univer-p-unknown univer-p-2'],
|
||||
['constructor toString __proto__ univer-constructor univer-toString', 'constructor toString __proto__ univer-constructor univer-toString'],
|
||||
])('recognizes arbitrary values and preserves external classes: %s', (input, expected) => {
|
||||
expect(clsx(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('handles the v3 leading important marker before a font-size/line-height postfix', () => {
|
||||
expect(clsx('!univer-leading-8 !univer-text-sm/6')).toBe('!univer-text-sm/6');
|
||||
expect(clsx('!univer-text-red-500 !univer-text-sm/6')).toBe('!univer-text-red-500 !univer-text-sm/6');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,13 +14,256 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-restricted-imports */
|
||||
import type { ClassValue } from 'clsx';
|
||||
import { clsx as cn } from 'clsx';
|
||||
import { extendTailwindMerge } from 'tailwind-merge';
|
||||
import { CLASS_CONFLICTS, CLASS_GROUPS, POSTFIX_CONFLICTS, VALIDATOR_NAMES } from './clsx.generated';
|
||||
|
||||
const twMerge = extendTailwindMerge({ prefix: 'univer-' });
|
||||
export type ClassValue = string | number | bigint | boolean | null | undefined | ClassValue[] | Record<string, unknown>;
|
||||
|
||||
export function clsx(...inputs: ClassValue[]) {
|
||||
return twMerge(cn(inputs));
|
||||
interface IClassToken {
|
||||
id: number | string;
|
||||
conflicts: readonly (number | string)[];
|
||||
}
|
||||
|
||||
const arbitraryValue = /^\[(?:([a-z-]+):)?(.+)\]$/i;
|
||||
const lengthValue = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
|
||||
const colorValue = /^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/;
|
||||
|
||||
function isNumber(value: string) {
|
||||
return Boolean(value) && !Number.isNaN(Number(value));
|
||||
}
|
||||
|
||||
function isArbitrary(value: string, labels: string[], test: (value: string) => boolean = () => false) {
|
||||
const match = arbitraryValue.exec(value);
|
||||
return !!match && (match[1] ? labels.includes(match[1]) : test(match[2]));
|
||||
}
|
||||
|
||||
// Tailwind v3 validators, adapted from tailwind-merge 2.6.0.
|
||||
// Its MIT license is included with the generated rules in clsx.generated.ts.
|
||||
const validators: Record<typeof VALIDATOR_NAMES[number], (value: string) => boolean> = {
|
||||
isAny: () => true,
|
||||
isArbitraryImage: (value) => isArbitrary(value, ['image', 'url'], (value) => /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/.test(value)),
|
||||
isArbitraryLength: (value) => isArbitrary(value, ['length'], (value) => lengthValue.test(value) && !colorValue.test(value)),
|
||||
isArbitraryNumber: (value) => isArbitrary(value, ['number'], isNumber),
|
||||
isArbitraryPosition: (value) => isArbitrary(value, ['position']),
|
||||
isArbitraryShadow: (value) => isArbitrary(value, [], (value) => /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/.test(value)),
|
||||
isArbitrarySize: (value) => isArbitrary(value, ['length', 'size', 'percentage']),
|
||||
isArbitraryValue: (value) => arbitraryValue.test(value),
|
||||
isInteger: (value) => Boolean(value) && Number.isInteger(Number(value)),
|
||||
isLength: (value) => isNumber(value) || ['px', 'full', 'screen'].includes(value) || /^\d+\/\d+$/.test(value),
|
||||
isNumber,
|
||||
isPercent: (value) => value.endsWith('%') && isNumber(value.slice(0, -1)),
|
||||
isTshirtSize: (value) => /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/.test(value),
|
||||
};
|
||||
|
||||
const classValidators = VALIDATOR_NAMES.map((name) => validators[name]);
|
||||
const classPatterns = new Map<string, number[]>();
|
||||
const classGroups = new Map<string, number>();
|
||||
const cache = new Map<string, string>();
|
||||
const cacheKeys = cache.keys();
|
||||
const tokens = new Map<string, IClassToken | null>();
|
||||
const tokenKeys = tokens.keys();
|
||||
const plainTokens: IClassToken[] = [];
|
||||
|
||||
CLASS_GROUPS.forEach((rules, index) => {
|
||||
for (const [prefix, literals, mask] of rules) {
|
||||
if (literals !== null) {
|
||||
for (const suffix of literals.split(' ')) {
|
||||
classGroups.set(prefix + (prefix && suffix ? '-' : '') + suffix, index + 1);
|
||||
}
|
||||
}
|
||||
if (mask) {
|
||||
const patterns = classPatterns.get(prefix) ?? [];
|
||||
patterns.push(index + 1, mask);
|
||||
classPatterns.set(prefix, patterns);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function getClassGroup(className: string): number | string | undefined {
|
||||
const positive = className.startsWith('-') ? className.slice(1) : className;
|
||||
if (!positive.startsWith('univer-')) {
|
||||
// Arbitrary properties are unprefixed in Tailwind v3, including in prefixed projects.
|
||||
const property = /^\[([^:]+):.+\]$/.exec(className);
|
||||
return property ? `arbitrary..${property[1]}` : undefined;
|
||||
}
|
||||
|
||||
const utility = positive.slice(7);
|
||||
const exact = classGroups.get(utility);
|
||||
if (exact !== undefined) {
|
||||
return exact;
|
||||
}
|
||||
|
||||
// Longest prefix first preserves v3's precedence (e.g. border-x width before border color).
|
||||
for (let end = utility.lastIndexOf('-'); end > 0; end = utility.lastIndexOf('-', end - 1)) {
|
||||
const rules = classPatterns.get(utility.slice(0, end));
|
||||
if (!rules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = utility.slice(end + 1);
|
||||
for (let index = 0; index < rules.length; index += 2) {
|
||||
// Visit only the validators present in the precompiled bitmask.
|
||||
for (let mask = rules[index + 1]; mask; mask &= mask - 1) {
|
||||
const validator = 31 - Math.clz32(mask & -mask);
|
||||
if (classValidators[validator](value)) {
|
||||
return rules[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function joinClasses(inputs: ClassValue[]): string {
|
||||
let result = '';
|
||||
for (const value of inputs) {
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let joined = '';
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
joined = String(value);
|
||||
} else if (Array.isArray(value)) {
|
||||
joined = joinClasses(value);
|
||||
} else if (typeof value === 'object') {
|
||||
for (const key in value) {
|
||||
if (value[key]) {
|
||||
result += (result ? ' ' : '') + key;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (joined) {
|
||||
result += (result ? ' ' : '') + joined;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseClassName(original: string) {
|
||||
const modifiers: string[] = [];
|
||||
let sortable: string[] = [];
|
||||
let depth = 0;
|
||||
let start = 0;
|
||||
let slash = -1;
|
||||
|
||||
for (let position = 0; position < original.length; position++) {
|
||||
const character = original[position];
|
||||
if (depth === 0 && character === ':') {
|
||||
const modifier = original.slice(start, position);
|
||||
if (modifier.startsWith('[')) {
|
||||
modifiers.push(...sortable.sort(), modifier);
|
||||
sortable = [];
|
||||
} else {
|
||||
sortable.push(modifier);
|
||||
}
|
||||
start = position + 1;
|
||||
} else if (depth === 0 && character === '/') {
|
||||
slash = position;
|
||||
} else if (character === '[') {
|
||||
depth++;
|
||||
} else if (character === ']') {
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
|
||||
const important = original[start] === '!';
|
||||
if (important) {
|
||||
// Strip v3's leading ! before slicing / so text-sm/6 remains a font size, not a color.
|
||||
start++;
|
||||
}
|
||||
|
||||
let hasPostfix = slash > start;
|
||||
let group = getClassGroup(original.slice(start, hasPostfix ? slash : undefined));
|
||||
if (group === undefined && hasPostfix) {
|
||||
group = getClassGroup(original.slice(start));
|
||||
hasPostfix = false;
|
||||
}
|
||||
|
||||
modifiers.push(...sortable.sort());
|
||||
return { group, hasPostfix, scope: `${modifiers.join(':')}|${important ? '!' : ''}` };
|
||||
}
|
||||
|
||||
function getClassToken(original: string): IClassToken | null {
|
||||
// Arbitrary values often change on every call; retaining them costs more than reusing their group.
|
||||
const cacheable = original.indexOf('[') === -1;
|
||||
if (cacheable) {
|
||||
const cached = tokens.get(original);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
let group: number | string | undefined;
|
||||
let scope = '|';
|
||||
let hasPostfix = false;
|
||||
if (original.indexOf(':') === -1 && original.indexOf('/') === -1) {
|
||||
const important = original[0] === '!';
|
||||
group = getClassGroup(important ? original.slice(1) : original);
|
||||
scope = important ? '|!' : '|';
|
||||
} else {
|
||||
({ group, scope, hasPostfix } = parseClassName(original));
|
||||
}
|
||||
|
||||
const token = group === undefined ? null : createClassToken(group, scope, hasPostfix);
|
||||
if (cacheable) {
|
||||
if (tokens.size >= 2048) {
|
||||
tokens.delete(tokenKeys.next().value!);
|
||||
}
|
||||
tokens.set(original, token);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
function createClassToken(group: number | string, scope: string, hasPostfix: boolean): IClassToken {
|
||||
const plain = scope === '|' || scope === '|!';
|
||||
const offset = scope === '|!' ? CLASS_GROUPS.length : 0;
|
||||
const id = plain && typeof group === 'number' ? group + offset : scope + group;
|
||||
const postfix = hasPostfix && typeof group === 'number' ? POSTFIX_CONFLICTS[group] : undefined;
|
||||
const cached = typeof id === 'number' && !postfix ? plainTokens[id] : undefined;
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const conflicts = typeof group === 'number'
|
||||
? [...(CLASS_CONFLICTS[group] ?? []), ...(postfix ?? [])].map((conflict) => plain ? conflict + offset : scope + conflict)
|
||||
: [];
|
||||
const token = { id, conflicts };
|
||||
if (typeof id === 'number' && !postfix) {
|
||||
plainTokens[id] = token;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/** Joins conditional classes and resolves Tailwind CSS v3 conflicts for the univer- prefix. */
|
||||
export function clsx(...inputs: ClassValue[]): string {
|
||||
const classList = inputs.length === 1 && typeof inputs[0] === 'string' ? inputs[0] : joinClasses(inputs);
|
||||
const cached = cache.get(classList);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const classes = classList.trim().split(/\s+/);
|
||||
const conflicts = new Set<number | string>();
|
||||
let result = '';
|
||||
|
||||
for (let index = classes.length - 1; index >= 0; index--) {
|
||||
const original = classes[index];
|
||||
const token = getClassToken(original);
|
||||
if (token) {
|
||||
if (conflicts.has(token.id)) {
|
||||
continue;
|
||||
}
|
||||
conflicts.add(token.id);
|
||||
for (const conflict of token.conflicts) {
|
||||
conflicts.add(conflict);
|
||||
}
|
||||
}
|
||||
|
||||
result = original + (result ? ` ${result}` : '');
|
||||
}
|
||||
|
||||
if (cache.size >= 1000) {
|
||||
cache.delete(cacheKeys.next().value!);
|
||||
}
|
||||
cache.set(classList, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,6 @@
|
||||
"react": "18.3.1",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.10"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { LocaleKey } from '../locale/types';
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import { DocLayoutProgressService } from '../services/doc-layout-progress.service';
|
||||
@@ -26,7 +27,7 @@ export function DocLayoutProgress() {
|
||||
}
|
||||
|
||||
const { progress } = progressState;
|
||||
const label = localeService.t('docs-ui.layout.progress');
|
||||
const label = localeService.t<LocaleKey>('docs-ui.layout.progress');
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { LocaleKey } from '../locale/types';
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { LoadingMultiIcon } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
@@ -37,7 +38,7 @@ export function DocLayoutRecovery() {
|
||||
aria-hidden
|
||||
className="univer-size-5 univer-animate-spin univer-text-violet-500"
|
||||
/>
|
||||
<span>{localeService.t('docs-ui.layout.recovering')}</span>
|
||||
<span>{localeService.t<LocaleKey>('docs-ui.layout.recovering')}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tsdown": "^0.22.14",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,6 @@
|
||||
"@univerjs/sheets-formula": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,6 @@
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,6 @@
|
||||
"@univerjs/network": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@
|
||||
"@univerjs/sheets-formula": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,6 @@
|
||||
"@univerjs/network": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,6 @@
|
||||
"rxjs": "^7.8.2",
|
||||
"tailwindcss": "3.4.18",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11",
|
||||
"vitest": "^5.0.0",
|
||||
"vue": "^3.5.40"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,6 @@
|
||||
"tailwindcss": "3.4.18",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import type { ComponentProps } from 'react';
|
||||
import type { LocaleKey } from '../../../locale/types';
|
||||
import type { IMenuSchema } from '../../../services/menu/menu-manager.service';
|
||||
import type { MobileDrawerSnap } from '../../components/mobile-drawer/MobileDrawer';
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
@@ -62,7 +63,7 @@ function MobileMenuDrawerContent(props: IMobileMenuDrawerProps) {
|
||||
<div dir={direction} className="univer-fixed univer-inset-0 univer-z-[1080] univer-flex univer-items-end">
|
||||
<button
|
||||
type="button"
|
||||
aria-label={localeService.t('ui.rangeSelector.cancel')}
|
||||
aria-label={localeService.t<LocaleKey>('ui.rangeSelector.cancel')}
|
||||
className={clsx(resetButtonClassName, `
|
||||
!univer-absolute !univer-inset-0 !univer-m-0 !univer-block !univer-appearance-none
|
||||
!univer-rounded-none !univer-border-0 !univer-bg-black/35 !univer-p-0 univer-backdrop-blur-[2px]
|
||||
@@ -72,8 +73,8 @@ function MobileMenuDrawerContent(props: IMobileMenuDrawerProps) {
|
||||
<MobileDrawer
|
||||
componentName="mobile-menu-drawer"
|
||||
snap={drawerSnap}
|
||||
expandLabel={localeService.t('ui.ribbon.more')}
|
||||
collapseLabel={localeService.t('ui.ribbon.more')}
|
||||
expandLabel={localeService.t<LocaleKey>('ui.ribbon.more')}
|
||||
collapseLabel={localeService.t<LocaleKey>('ui.ribbon.more')}
|
||||
onSnapChange={setDrawerSnap}
|
||||
onClose={onClose}
|
||||
role="dialog"
|
||||
@@ -90,7 +91,7 @@ function MobileMenuDrawerContent(props: IMobileMenuDrawerProps) {
|
||||
? (
|
||||
<button
|
||||
type="button"
|
||||
aria-label={localeService.t('ui.navigation.back')}
|
||||
aria-label={localeService.t<LocaleKey>('ui.navigation.back')}
|
||||
className={clsx(resetButtonClassName, `
|
||||
univer-size-10 univer-rounded-xl univer-text-gray-700
|
||||
active:univer-bg-gray-200
|
||||
@@ -114,7 +115,7 @@ function MobileMenuDrawerContent(props: IMobileMenuDrawerProps) {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label={localeService.t('ui.rangeSelector.cancel')}
|
||||
aria-label={localeService.t<LocaleKey>('ui.rangeSelector.cancel')}
|
||||
className={clsx(resetButtonClassName, `
|
||||
univer-size-10 univer-rounded-xl univer-text-gray-700
|
||||
active:univer-bg-gray-200
|
||||
|
||||
@@ -85,6 +85,6 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.2",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+429
-342
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,6 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.11"
|
||||
"vitest": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user