mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
refactor(sheets-conditional-formatting): migrate styles from LESS to Tailwind CSS (#5133)
Co-authored-by: GitHub Actions <actions@github.com>
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
"univer-cli": "bin/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/parser": "^8.31.0",
|
||||
"@typescript-eslint/parser": "^8.31.1",
|
||||
"@vitejs/plugin-react": "^4.4.1",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vitest/coverage-istanbul": "^3.1.2",
|
||||
@@ -38,7 +38,7 @@
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-rem-to-px": "^0.1.1",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vite-plugin-dts": "^4.5.3",
|
||||
"vite-plugin-external": "^6.2.1",
|
||||
"vitest": "^3.1.2"
|
||||
@@ -46,7 +46,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@univerjs/icons": "^0.3.24",
|
||||
"@univerjs/icons-svg": "^0.3.22",
|
||||
"@univerjs/icons-svg": "^0.3.24",
|
||||
"@univerjs/protocol": "0.1.45"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
@@ -27,7 +27,6 @@
|
||||
"@univerjs/docs-drawing-ui": "workspace:*",
|
||||
"@univerjs/docs-hyper-link-ui": "workspace:*",
|
||||
"@univerjs/docs-mention-ui": "workspace:*",
|
||||
|
||||
"@univerjs/docs-quick-insert-ui": "workspace:*",
|
||||
"@univerjs/docs-thread-comment-ui": "workspace:*",
|
||||
"@univerjs/docs-ui": "workspace:*",
|
||||
@@ -36,7 +35,7 @@
|
||||
"@univerjs/engine-formula": "workspace:*",
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"@univerjs/find-replace": "workspace:*",
|
||||
"@univerjs/icons": "0.3.23",
|
||||
"@univerjs/icons": "0.3.24",
|
||||
"@univerjs/mockdata": "workspace:*",
|
||||
"@univerjs/network": "workspace:*",
|
||||
"@univerjs/rpc": "workspace:*",
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^22.15.3",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/design": "workspace:*",
|
||||
"@vitejs/plugin-react": "^4.4.1",
|
||||
@@ -72,7 +72,7 @@
|
||||
"fs-extra": "^11.3.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^15.5.1",
|
||||
"posthog-node": "^4.14.0",
|
||||
"posthog-node": "^4.15.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"release-it": "^17.11.0",
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2",
|
||||
"vue": "^3.5.13"
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
"@univerjs/sheets": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ interface ICountBarProps {
|
||||
|
||||
export function CountBar(_props: ICountBarProps) {
|
||||
return (
|
||||
<section className="univer-flex univer-flex-shrink-0 univer-flex-grow-0 univer-basis-[260px] univer-justify-end">
|
||||
<section className="univer-flex univer-flex-shrink-0 univer-justify-end">
|
||||
<ZoomSlider />
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
},
|
||||
"browser": {
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,13 +85,12 @@
|
||||
"devDependencies": {
|
||||
"@types/react-grid-layout": "^1.3.5",
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"less": "^4.3.0",
|
||||
"postcss": "^8.5.3",
|
||||
"react": "18.3.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
.cf-style-edit {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 10px 0px;
|
||||
.button-item {
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius-base);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0px 3px;
|
||||
&:hover {
|
||||
background-color: rgb(var(--grey-100));
|
||||
}
|
||||
}
|
||||
.isActive {
|
||||
background-color: rgb(var(--grey-100));
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -21,7 +21,6 @@ import { removeUndefinedAttr } from '@univerjs/sheets-conditional-formatting';
|
||||
import { ComponentManager, useDependency } from '@univerjs/ui';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ColorPicker } from '../color-picker';
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface IConditionalStyleEditorProps {
|
||||
className?: string;
|
||||
@@ -101,13 +100,16 @@ export const ConditionalStyleEditor = (props: IConditionalStyleEditorProps) => {
|
||||
}
|
||||
onChange(removeUndefinedAttr(resultStyle));
|
||||
}, [isBold, isItalic, isUnderline, isStrikethrough, fontColor, bgColor]);
|
||||
|
||||
const buttonItemClassName = 'univer-flex univer-cursor-pointer univer-items-center univer-rounded univer-px-1';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(styles.cfStyleEdit, className)}
|
||||
>
|
||||
<div className={clsx('univer-my-2.5 univer-flex univer-justify-between', className)}>
|
||||
{BoldSingleIcon && (
|
||||
<div
|
||||
className={clsx({ [styles.isActive]: getBooleanFromNumber(isBold || BooleanNumber.FALSE) }, styles.buttonItem)}
|
||||
className={clsx(buttonItemClassName, {
|
||||
'univer-bg-gray-100': getBooleanFromNumber(isBold || BooleanNumber.FALSE),
|
||||
})}
|
||||
onClick={() => isBoldSet(getAnotherBooleanNumber(isBold))}
|
||||
>
|
||||
<BoldSingleIcon />
|
||||
@@ -115,7 +117,9 @@ export const ConditionalStyleEditor = (props: IConditionalStyleEditorProps) => {
|
||||
)}
|
||||
{ItalicSingleIcon && (
|
||||
<div
|
||||
className={clsx({ [styles.isActive]: getBooleanFromNumber(isItalic || BooleanNumber.FALSE) }, styles.buttonItem)}
|
||||
className={clsx(buttonItemClassName, {
|
||||
'univer-bg-gray-100': getBooleanFromNumber(isItalic || BooleanNumber.FALSE),
|
||||
})}
|
||||
onClick={() => isItalicSet(getAnotherBooleanNumber(isItalic))}
|
||||
>
|
||||
<ItalicSingleIcon />
|
||||
@@ -123,7 +127,9 @@ export const ConditionalStyleEditor = (props: IConditionalStyleEditorProps) => {
|
||||
)}
|
||||
{UnderlineSingleIcon && (
|
||||
<div
|
||||
className={clsx({ [styles.isActive]: getBooleanFromNumber(isUnderline || BooleanNumber.FALSE) }, styles.buttonItem)}
|
||||
className={clsx(buttonItemClassName, {
|
||||
'univer-bg-gray-100': getBooleanFromNumber(isUnderline || BooleanNumber.FALSE),
|
||||
})}
|
||||
onClick={() => isUnderlineSet(getAnotherBooleanNumber(isUnderline))}
|
||||
>
|
||||
<UnderlineSingleIcon />
|
||||
@@ -131,7 +137,9 @@ export const ConditionalStyleEditor = (props: IConditionalStyleEditorProps) => {
|
||||
)}
|
||||
{StrikethroughSingle && (
|
||||
<div
|
||||
className={clsx({ [styles.isActive]: getBooleanFromNumber(isStrikethrough || BooleanNumber.FALSE) }, styles.buttonItem)}
|
||||
className={clsx(buttonItemClassName, {
|
||||
'univer-bg-gray-100': getBooleanFromNumber(isStrikethrough || BooleanNumber.FALSE),
|
||||
})}
|
||||
onClick={() => isStrikethroughSet(getAnotherBooleanNumber(isStrikethrough))}
|
||||
>
|
||||
<StrikethroughSingle />
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
.conditional-formatting-wrap {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.cf-rule-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.preview {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
.create-rule {
|
||||
margin-bottom: 20px;
|
||||
.button {
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-base);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--padding-base);
|
||||
cursor: pointer;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
}
|
||||
.title {
|
||||
margin-top: var(--margin-base);
|
||||
font-size: 15px;
|
||||
color: rgb(var(--text-color-secondary));
|
||||
}
|
||||
.label {
|
||||
font-size: 12px;
|
||||
margin-top: var(--margin-sm);
|
||||
color: rgb(var(--text-color-secondary));
|
||||
}
|
||||
.label-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.input-width {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import type { IConditionFormattingRule } from '@univerjs/sheets-conditional-formatting';
|
||||
import styles from './index.module.less';
|
||||
import { RuleList } from './rule-list';
|
||||
import { useState } from 'react';
|
||||
import { RuleEdit } from './rule-edit';
|
||||
import { RuleList } from './rule-list';
|
||||
|
||||
interface IConditionFormattingPanelProps { rule?: IConditionFormattingRule };
|
||||
|
||||
@@ -41,7 +40,7 @@ export const ConditionFormattingPanel = (props: IConditionFormattingPanelProps)
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.conditionalFormattingWrap}>
|
||||
<div className="univer-flex univer-h-full univer-flex-col univer-justify-between">
|
||||
{isShowRuleEditor
|
||||
? (
|
||||
<RuleEdit onCancel={handleCancel} rule={currentEditRule} />
|
||||
|
||||
+105
-62
@@ -19,15 +19,14 @@ import type { IColorScale, IConditionalFormattingRuleConfig } from '@univerjs/sh
|
||||
import type { IFormulaEditorRef } from '@univerjs/sheets-formula-ui';
|
||||
import type { IStyleEditorProps } from './type';
|
||||
import { IUniverInstanceService, LocaleService, UniverInstanceType } from '@univerjs/core';
|
||||
import { clsx, InputNumber, Select } from '@univerjs/design';
|
||||
import { InputNumber, Select } from '@univerjs/design';
|
||||
import { CFRuleType, CFValueType, createDefaultValueByValueType } from '@univerjs/sheets-conditional-formatting';
|
||||
import { FormulaEditor } from '@univerjs/sheets-formula-ui';
|
||||
import { useDependency, useSidebarClick } from '@univerjs/ui';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { ColorPicker } from '../../color-picker';
|
||||
import { Preview } from '../../preview';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
import { previewClassName } from './styles';
|
||||
|
||||
const createOptionItem = (text: string, localeService: LocaleService) => ({ label: localeService.t(`sheet.cf.valueType.${text}`), value: text });
|
||||
|
||||
@@ -57,16 +56,16 @@ const TextInput = (props: { id: string; type: CFValueType | 'none'; value: numbe
|
||||
}, [type]);
|
||||
|
||||
const formulaEditorRef = useRef<IFormulaEditorRef>(null);
|
||||
const [isFocusFormulaEditor, isFocusFormulaEditorSet] = useState(false);
|
||||
const [isFocusFormulaEditor, setIsFocusFormulaEditor] = useState(false);
|
||||
|
||||
useSidebarClick((e: MouseEvent) => {
|
||||
const isOutSide = formulaEditorRef.current?.isClickOutSide(e);
|
||||
isOutSide && isFocusFormulaEditorSet(false);
|
||||
isOutSide && setIsFocusFormulaEditor(false);
|
||||
});
|
||||
|
||||
if (type === CFValueType.formula) {
|
||||
return (
|
||||
<div style={{ width: '100%', marginLeft: 4 }}>
|
||||
<div className="univer-ml-1 univer-w-full">
|
||||
<FormulaEditor
|
||||
initValue={formulaInitValue as any}
|
||||
unitId={unitId}
|
||||
@@ -76,7 +75,7 @@ const TextInput = (props: { id: string; type: CFValueType | 'none'; value: numbe
|
||||
const formula = v || '';
|
||||
onChange(formula);
|
||||
}}
|
||||
onFocus={() => isFocusFormulaEditorSet(true)}
|
||||
onFocus={() => setIsFocusFormulaEditor(true)}
|
||||
ref={formulaEditorRef}
|
||||
/>
|
||||
</div>
|
||||
@@ -95,14 +94,14 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
const medianOptions = [createOptionItem('none', localeService), ...commonOptions];
|
||||
const maxOptions = [createOptionItem(CFValueType.max, localeService), ...commonOptions];
|
||||
|
||||
const [minType, minTypeSet] = useState(() => {
|
||||
const [minType, setMinType] = useState(() => {
|
||||
const defaultV = CFValueType.min;
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
}
|
||||
return rule.config[0]?.value.type || defaultV;
|
||||
});
|
||||
const [medianType, medianTypeSet] = useState<CFValueType | 'none'>(() => {
|
||||
const [medianType, setMedianType] = useState<CFValueType | 'none'>(() => {
|
||||
const defaultV = 'none';
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -112,7 +111,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
}
|
||||
return rule.config[1]?.value.type || defaultV;
|
||||
});
|
||||
const [maxType, maxTypeSet] = useState(() => {
|
||||
const [maxType, setMaxType] = useState(() => {
|
||||
const defaultV = CFValueType.max;
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -120,7 +119,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
return rule.config[rule.config.length - 1]?.value.type || defaultV;
|
||||
});
|
||||
|
||||
const [minValue, minValueSet] = useState(() => {
|
||||
const [minValue, setMinValue] = useState(() => {
|
||||
const defaultV = 10;
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -128,7 +127,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
const valueConfig = rule.config[0];
|
||||
return valueConfig?.value.value === undefined ? defaultV : valueConfig?.value.value;
|
||||
});
|
||||
const [medianValue, medianValueSet] = useState(() => {
|
||||
const [medianValue, setMedianValue] = useState(() => {
|
||||
const defaultV = 50;
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -139,7 +138,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
const v = rule.config[1]?.value.value;
|
||||
return v === undefined ? defaultV : v;
|
||||
});
|
||||
const [maxValue, maxValueSet] = useState(() => {
|
||||
const [maxValue, setMaxValue] = useState(() => {
|
||||
const defaultV = 90;
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -148,14 +147,14 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
return v === undefined ? defaultV : v;
|
||||
});
|
||||
|
||||
const [minColor, minColorSet] = useState(() => {
|
||||
const [minColor, setMinColor] = useState(() => {
|
||||
const defaultV = '#d0d9fb';
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
}
|
||||
return rule.config[0]?.color || defaultV;
|
||||
});
|
||||
const [medianColor, medianColorSet] = useState(() => {
|
||||
const [medianColor, setMedianColor] = useState(() => {
|
||||
const defaultV = '#7790f3';
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -165,7 +164,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
}
|
||||
return rule.config[1]?.color || defaultV;
|
||||
});
|
||||
const [maxColor, maxColorSet] = useState(() => {
|
||||
const [maxColor, setMaxColor] = useState(() => {
|
||||
const defaultV = '#2e55ef';
|
||||
if (!rule) {
|
||||
return defaultV;
|
||||
@@ -217,29 +216,24 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className={stylesBase.title}>{localeService.t('sheet.cf.panel.styleRule')}</div>
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<div className={previewClassName}>
|
||||
<Preview rule={getResult({ minType, medianType, maxType, minValue, medianValue, maxValue, minColor, medianColor, maxColor }) as IConditionalFormattingRuleConfig} />
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.min')}</div>
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
univer-mt-3
|
||||
`, 'univer-box-border univer-h-8')}
|
||||
>
|
||||
<div className="univer-mt-3 univer-text-xs univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.valueType.min')}
|
||||
</div>
|
||||
<div className="univer-mt-3 univer-flex univer-h-8 univer-items-center">
|
||||
<Select
|
||||
className="univer-flex-shrink-0"
|
||||
options={minOptions}
|
||||
value={minType}
|
||||
onChange={(v) => {
|
||||
minTypeSet(v as CFValueType);
|
||||
setMinType(v as CFValueType);
|
||||
const value = createDefaultValueByValueType(v as CFValueType, 10);
|
||||
minValueSet(value);
|
||||
setMinValue(value);
|
||||
handleChange({ minType: v as CFValueType, medianType, maxType, minValue: value, medianValue, maxValue, minColor, medianColor, maxColor });
|
||||
}}
|
||||
/>
|
||||
@@ -249,7 +243,7 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
value={minValue}
|
||||
type={minType}
|
||||
onChange={(v) => {
|
||||
minValueSet(v);
|
||||
setMinValue(v);
|
||||
handleChange({ minType, medianType, maxType, minValue: v, medianValue, maxValue, minColor, medianColor, maxColor });
|
||||
}}
|
||||
/>
|
||||
@@ -257,27 +251,32 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
className="univer-ml-1"
|
||||
color={minColor}
|
||||
onChange={(v) => {
|
||||
minColorSet(v);
|
||||
setMinColor(v);
|
||||
handleChange({ minType, medianType, maxType, minValue, medianValue, maxValue, minColor: v, medianColor, maxColor });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.panel.medianValue')}</div>
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
univer-mt-3
|
||||
`, 'univer-box-border univer-h-8')}
|
||||
>
|
||||
<div className="univer-mt-3 univer-text-xs univer-text-gray-600">{localeService.t('sheet.cf.panel.medianValue')}</div>
|
||||
<div className="univer-mt-3 univer-flex univer-h-8 univer-items-center">
|
||||
<Select
|
||||
className="univer-flex-shrink-0"
|
||||
options={medianOptions}
|
||||
value={medianType}
|
||||
onChange={(v) => {
|
||||
medianTypeSet(v as CFValueType);
|
||||
setMedianType(v as CFValueType);
|
||||
const value = createDefaultValueByValueType(v as CFValueType, 50);
|
||||
medianValueSet(value);
|
||||
handleChange({ minType, medianType: v as CFValueType, maxType, minValue, medianValue: value, maxValue, minColor, medianColor, maxColor });
|
||||
setMedianValue(value);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType: v as CFValueType,
|
||||
maxType,
|
||||
minValue,
|
||||
medianValue: value,
|
||||
maxValue,
|
||||
minColor,
|
||||
medianColor,
|
||||
maxColor,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -287,8 +286,18 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
value={medianValue}
|
||||
type={medianType}
|
||||
onChange={(v) => {
|
||||
medianValueSet(v);
|
||||
handleChange({ minType, medianType, maxType, minValue, medianValue: v, maxValue, minColor, medianColor, maxColor });
|
||||
setMedianValue(v);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType,
|
||||
maxType,
|
||||
minValue,
|
||||
medianValue: v,
|
||||
maxValue,
|
||||
minColor,
|
||||
medianColor,
|
||||
maxColor,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{medianType !== 'none' && (
|
||||
@@ -296,29 +305,44 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
className="univer-ml-1"
|
||||
color={medianColor}
|
||||
onChange={(v) => {
|
||||
medianColorSet(v);
|
||||
handleChange({ minType, medianType, maxType, minValue, medianValue, maxValue, minColor, medianColor: v, maxColor });
|
||||
setMedianColor(v);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType,
|
||||
maxType,
|
||||
minValue,
|
||||
medianValue,
|
||||
maxValue,
|
||||
minColor,
|
||||
medianColor: v,
|
||||
maxColor,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.max')}</div>
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
univer-mt-3 univer-box-border univer-h-8
|
||||
`)}
|
||||
>
|
||||
<div className="univer-mt-3 univer-text-xs univer-text-gray-600">{localeService.t('sheet.cf.valueType.max')}</div>
|
||||
<div className="univer-mt-3 univer-flex univer-h-8 univer-items-center">
|
||||
<Select
|
||||
className="univer-flex-shrink-0"
|
||||
options={maxOptions}
|
||||
value={maxType}
|
||||
onChange={(v) => {
|
||||
maxTypeSet(v as CFValueType);
|
||||
setMaxType(v as CFValueType);
|
||||
const value = createDefaultValueByValueType(v as CFValueType, 90);
|
||||
maxValueSet(value);
|
||||
handleChange({ minType, medianType, maxType: v as CFValueType, minValue, medianValue, maxValue: value, minColor, medianColor, maxColor });
|
||||
setMaxValue(value);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType,
|
||||
maxType: v as CFValueType,
|
||||
minValue,
|
||||
medianValue,
|
||||
maxValue: value,
|
||||
minColor,
|
||||
medianColor,
|
||||
maxColor,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
@@ -327,20 +351,39 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
value={maxValue}
|
||||
type={maxType}
|
||||
onChange={(v) => {
|
||||
maxValueSet(v);
|
||||
handleChange({ minType, medianType, maxType, minValue, medianValue, maxValue: v, minColor, medianColor, maxColor });
|
||||
setMaxValue(v);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType,
|
||||
maxType,
|
||||
minValue,
|
||||
medianValue,
|
||||
maxValue: v,
|
||||
minColor,
|
||||
medianColor,
|
||||
maxColor,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<ColorPicker
|
||||
className="univer-ml-1"
|
||||
color={maxColor}
|
||||
onChange={(v) => {
|
||||
maxColorSet(v);
|
||||
handleChange({ minType, medianType, maxType, minValue, medianValue, maxValue, minColor, medianColor, maxColor: v });
|
||||
setMaxColor(v);
|
||||
handleChange({
|
||||
minType,
|
||||
medianType,
|
||||
maxType,
|
||||
minValue,
|
||||
medianValue,
|
||||
maxValue,
|
||||
minColor,
|
||||
medianColor,
|
||||
maxColor: v,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+85
-66
@@ -26,8 +26,7 @@ import { useDependency, useSidebarClick } from '@univerjs/ui';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { ColorPicker } from '../../color-picker';
|
||||
import { Preview } from '../../preview';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
import { previewClassName } from './styles';
|
||||
|
||||
const createOptionItem = (text: CFValueType, localeService: LocaleService) => ({ label: localeService.t(`sheet.cf.valueType.${text}`), value: text });
|
||||
|
||||
@@ -38,11 +37,11 @@ const InputText = (props: { disabled?: boolean; id: string; className: string; t
|
||||
const subUnitId = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!.getActiveSheet()?.getSheetId();
|
||||
|
||||
const formulaEditorRef = useRef<IFormulaEditorRef>(null);
|
||||
const [isFocusFormulaEditor, isFocusFormulaEditorSet] = useState(false);
|
||||
const [isFocusFormulaEditor, setIsFocusFormulaEditor] = useState(false);
|
||||
|
||||
useSidebarClick((e: MouseEvent) => {
|
||||
const isOutSide = formulaEditorRef.current?.isClickOutSide(e);
|
||||
isOutSide && isFocusFormulaEditorSet(false);
|
||||
isOutSide && setIsFocusFormulaEditor(false);
|
||||
});
|
||||
|
||||
const _value = useRef(value);
|
||||
@@ -58,10 +57,11 @@ const InputText = (props: { disabled?: boolean; id: string; className: string; t
|
||||
max: Number.MAX_SAFE_INTEGER,
|
||||
};
|
||||
}, [type]);
|
||||
|
||||
if (type === CFValueType.formula) {
|
||||
const v = String(_value.current).startsWith('=') ? String(_value.current) || '' : '=';
|
||||
return (
|
||||
<div style={{ width: '100%', marginLeft: 12 }}>
|
||||
<div className="univer-ml-3 univer-w-full">
|
||||
<FormulaEditor
|
||||
initValue={v as any}
|
||||
unitId={unitId}
|
||||
@@ -71,7 +71,7 @@ const InputText = (props: { disabled?: boolean; id: string; className: string; t
|
||||
const formula = v || '';
|
||||
onChange(formula);
|
||||
}}
|
||||
onFocus={() => isFocusFormulaEditorSet(true)}
|
||||
onFocus={() => setIsFocusFormulaEditor(true)}
|
||||
ref={formulaEditorRef}
|
||||
/>
|
||||
</div>
|
||||
@@ -224,27 +224,29 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={stylesBase.title}>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<Preview rule={getResult({ isGradient, minValue, minValueType, maxValue, maxValueType, positiveColor, nativeColor, isShowValue }) as IConditionalFormattingRuleConfig} />
|
||||
<div className={previewClassName}>
|
||||
<Preview
|
||||
rule={getResult({
|
||||
isGradient,
|
||||
minValue,
|
||||
minValueType,
|
||||
maxValue,
|
||||
maxValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue,
|
||||
}) as IConditionalFormattingRuleConfig}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={stylesBase.label}>
|
||||
<div className="univer-mt-3 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.fillType')}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`
|
||||
univer-ml-1 univer-mt-3
|
||||
${stylesBase.labelContainer}
|
||||
`}
|
||||
>
|
||||
<div className="univer-ml-1 univer-mt-3 univer-flex univer-items-center">
|
||||
<RadioGroup
|
||||
value={isGradient}
|
||||
onChange={(v) => {
|
||||
@@ -253,23 +255,27 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
}}
|
||||
>
|
||||
<Radio value="0">
|
||||
<span className={styles.text}>{localeService.t('sheet.cf.panel.pureColor')}</span>
|
||||
<span className="univer-text-xs">{localeService.t('sheet.cf.panel.pureColor')}</span>
|
||||
</Radio>
|
||||
<Radio value="1">
|
||||
<span className={styles.text}>{localeService.t('sheet.cf.panel.gradient')}</span>
|
||||
<span className="univer-text-xs">{localeService.t('sheet.cf.panel.gradient')}</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
<div
|
||||
className={`
|
||||
${styles.utilItem}
|
||||
univer-ml-6
|
||||
`}
|
||||
>
|
||||
<div className="univer-ml-6 univer-flex univer-items-center univer-text-xs">
|
||||
<Checkbox
|
||||
checked={!isShowValue}
|
||||
onChange={(v) => {
|
||||
setIsShowValue(!v);
|
||||
_handleChange({ isGradient: v as string, minValue, minValueType, maxValue, maxValueType, positiveColor, nativeColor, isShowValue: !v });
|
||||
_handleChange({
|
||||
isGradient: v as string,
|
||||
minValue,
|
||||
minValueType,
|
||||
maxValue,
|
||||
maxValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue: !v,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{localeService.t('sheet.cf.panel.onlyShowDataBar')}
|
||||
@@ -277,23 +283,10 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.panel.colorSet')}</div>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.labelContainer}
|
||||
univer-ml-1 univer-mt-3
|
||||
`}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.labelContainer}
|
||||
`}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
${styles.text}
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-3 univer-text-sm univer-text-gray-600">{localeService.t('sheet.cf.panel.colorSet')}</div>
|
||||
<div className="univer-ml-1 univer-mt-3 univer-flex univer-items-center">
|
||||
<div className="univer-flex univer-items-center">
|
||||
<div className="univer-text-xs">
|
||||
{localeService.t('sheet.cf.panel.native')}
|
||||
</div>
|
||||
<ColorPicker
|
||||
@@ -301,17 +294,8 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
onChange={handleNativeColorChange}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.labelContainer}
|
||||
univer-ml-3
|
||||
`}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
${styles.text}
|
||||
`}
|
||||
>
|
||||
<div className="univer-ml-3 univer-flex univer-items-center">
|
||||
<div className="univer-text-xs">
|
||||
{localeService.t('sheet.cf.panel.positive')}
|
||||
</div>
|
||||
<ColorPicker
|
||||
@@ -323,7 +307,7 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.min')}</div>
|
||||
<div className="univer-mt-3 univer-text-sm univer-text-gray-600">{localeService.t('sheet.cf.valueType.min')}</div>
|
||||
<div className="univer-mt-3 univer-flex univer-items-center">
|
||||
<Select
|
||||
className="univer-w-1/2 univer-flex-shrink-0"
|
||||
@@ -333,23 +317,41 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
setMinValueType(v as CFValueType);
|
||||
const value = createDefaultValueByValueType(v as CFValueType, 10);
|
||||
minValueSet(value);
|
||||
_handleChange({ isGradient, minValue: value, minValueType: v as CFValueType, maxValue, maxValueType, positiveColor, nativeColor, isShowValue });
|
||||
_handleChange({
|
||||
isGradient,
|
||||
minValue: value,
|
||||
minValueType: v as CFValueType,
|
||||
maxValue,
|
||||
maxValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<InputText
|
||||
disabled={!isShowInput(minValueType)}
|
||||
id="min"
|
||||
type={minValueType}
|
||||
className="univer-ml-3"
|
||||
disabled={!isShowInput(minValueType)}
|
||||
type={minValueType}
|
||||
value={minValue}
|
||||
onChange={(v) => {
|
||||
minValueSet(v || 0);
|
||||
_handleChange({ isGradient, minValue: v || 0, minValueType, maxValue, maxValueType, positiveColor, nativeColor, isShowValue });
|
||||
_handleChange({
|
||||
isGradient,
|
||||
minValue: v || 0,
|
||||
minValueType,
|
||||
maxValue,
|
||||
maxValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.max')}</div>
|
||||
<div className="univer-mt-3 univer-text-sm univer-text-gray-600">{localeService.t('sheet.cf.valueType.max')}</div>
|
||||
<div className="univer-mt-3 univer-flex univer-items-center">
|
||||
<Select
|
||||
className="univer-w-1/2 univer-flex-shrink-0"
|
||||
@@ -359,7 +361,16 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
setMaxValueType(v as CFValueType);
|
||||
const value = createDefaultValueByValueType(v as CFValueType, 90);
|
||||
setMaxValue(value);
|
||||
_handleChange({ isGradient, minValue, minValueType, maxValue: value, maxValueType: v as CFValueType, positiveColor, nativeColor, isShowValue });
|
||||
_handleChange({
|
||||
isGradient,
|
||||
minValue,
|
||||
minValueType,
|
||||
maxValue: value,
|
||||
maxValueType: v as CFValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<InputText
|
||||
@@ -370,12 +381,20 @@ export const DataBarStyleEditor = (props: IStyleEditorProps) => {
|
||||
value={maxValue}
|
||||
onChange={(v) => {
|
||||
setMaxValue(v || 0);
|
||||
_handleChange({ isGradient, minValue, minValueType, maxValue: v || 0, maxValueType, positiveColor, nativeColor, isShowValue });
|
||||
_handleChange({
|
||||
isGradient,
|
||||
minValue,
|
||||
minValueType,
|
||||
maxValue: v || 0,
|
||||
maxValueType,
|
||||
positiveColor,
|
||||
nativeColor,
|
||||
isShowValue,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+14
-24
@@ -25,8 +25,7 @@ import { useDependency, useSidebarClick } from '@univerjs/ui';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { ConditionalStyleEditor } from '../../conditional-style-editor';
|
||||
import { Preview } from '../../preview';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
import { previewClassName } from './styles';
|
||||
|
||||
export const FormulaStyleEditor = (props: IStyleEditorProps) => {
|
||||
const { onChange, interceptorManager } = props;
|
||||
@@ -38,16 +37,16 @@ export const FormulaStyleEditor = (props: IStyleEditorProps) => {
|
||||
const rule = props.rule?.type === CFRuleType.highlightCell ? props.rule : undefined as IRankHighlightCell | IAverageHighlightCell | undefined;
|
||||
|
||||
const divEleRef = useRef<HTMLDivElement>(null);
|
||||
const [isFocusFormulaEditor, isFocusFormulaEditorSet] = useState(false);
|
||||
const [isFocusFormulaEditor, setIsFocusFormulaEditor] = useState(false);
|
||||
const formulaEditorRef = useRef<IFormulaEditorRef>(null);
|
||||
const [style, styleSet] = useState<IHighlightCell['style']>({});
|
||||
const [formula, formulaSet] = useState(() => {
|
||||
const [style, setStyle] = useState<IHighlightCell['style']>({});
|
||||
const [formula, setFormula] = useState(() => {
|
||||
if (rule?.subType === CFSubRuleType.formula) {
|
||||
return rule.value;
|
||||
}
|
||||
return '=';
|
||||
});
|
||||
const [formulaError, formulaErrorSet] = useState<string | undefined>(undefined);
|
||||
const [formulaError, setFormulaError] = useState<string | undefined>(undefined);
|
||||
|
||||
const getResult = (config: {
|
||||
style: IHighlightCell['style'];
|
||||
@@ -73,7 +72,7 @@ export const FormulaStyleEditor = (props: IStyleEditorProps) => {
|
||||
const dispose = interceptorManager.intercept(interceptorManager.getInterceptPoints().beforeSubmit, {
|
||||
handler: (v, _c, next) => {
|
||||
if (formulaError || formula.length === 1 || !formula.startsWith('=')) {
|
||||
formulaErrorSet(localeService.t('sheet.cf.errorMessage.formulaError'));
|
||||
setFormulaError(localeService.t('sheet.cf.errorMessage.formulaError'));
|
||||
return false;
|
||||
}
|
||||
return next(v);
|
||||
@@ -91,34 +90,29 @@ export const FormulaStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
useSidebarClick((e: MouseEvent) => {
|
||||
const isOutSide = formulaEditorRef.current?.isClickOutSide(e);
|
||||
isOutSide && isFocusFormulaEditorSet(false);
|
||||
isOutSide && setIsFocusFormulaEditor(false);
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={divEleRef}>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.title}
|
||||
univer-mt-4
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<div className="univer-mt-3">
|
||||
<FormulaEditor
|
||||
onChange={(formula) => {
|
||||
formulaSet(formula);
|
||||
setFormula(formula);
|
||||
_onChange({ style, formula });
|
||||
}}
|
||||
onVerify={(result, formula) => {
|
||||
if (!result || formula.length === 1) {
|
||||
formulaErrorSet(localeService.t('sheet.cf.errorMessage.formulaError'));
|
||||
setFormulaError(localeService.t('sheet.cf.errorMessage.formulaError'));
|
||||
} else {
|
||||
formulaErrorSet(undefined);
|
||||
setFormulaError(undefined);
|
||||
}
|
||||
}}
|
||||
errorText={formulaError}
|
||||
onFocus={() => { isFocusFormulaEditorSet(true); }}
|
||||
onFocus={() => { setIsFocusFormulaEditor(true); }}
|
||||
isFocus={isFocusFormulaEditor}
|
||||
initValue={formula as any}
|
||||
unitId={workbook.getUnitId()}
|
||||
@@ -128,18 +122,14 @@ export const FormulaStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<div className={previewClassName}>
|
||||
<Preview rule={getResult({ style, formula }) as IConditionalFormattingRuleConfig} />
|
||||
</div>
|
||||
<ConditionalStyleEditor
|
||||
style={rule?.style}
|
||||
className="univer-mt-3"
|
||||
onChange={(v) => {
|
||||
styleSet(v);
|
||||
setStyle(v);
|
||||
_onChange({ style: v, formula });
|
||||
}}
|
||||
/>
|
||||
|
||||
+33
-40
@@ -33,12 +33,11 @@ import {
|
||||
createDefaultValue,
|
||||
} from '@univerjs/sheets-conditional-formatting';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { ConditionalStyleEditor } from '../../conditional-style-editor';
|
||||
import { Preview } from '../../preview';
|
||||
import { WrapperError } from '../../wrapper-error/WrapperError';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
import { previewClassName } from './styles';
|
||||
|
||||
const createOptionItem = (text: string, localeService: LocaleService) => ({ label: localeService.t(`sheet.cf.operator.${text}`), value: text });
|
||||
type IValue = number | string | [number, number];
|
||||
@@ -55,16 +54,16 @@ const HighlightCellInput = (props: {
|
||||
const { type, operator, onChange, value, interceptorManager } = props;
|
||||
|
||||
const localeService = useDependency(LocaleService);
|
||||
const [inputNumberValue, inputNumberValueSet] = useState(() => typeof value === 'number' ? value : 0);
|
||||
const [numberError, numberErrorSet] = useState('');
|
||||
const [inputNumberValue, setInputNumberValue] = useState(() => typeof value === 'number' ? value : 0);
|
||||
const [numberError, setNumberError] = useState('');
|
||||
|
||||
const [inputTextValue, inputTextValueSet] = useState(() => typeof value === 'string' ? value : '');
|
||||
const [textError, textErrorSet] = useState('');
|
||||
const [inputNumberMin, inputNumberMinSet] = useState(() => Array.isArray(value) ? value[0] === undefined ? 0 : value[0] : 0);
|
||||
const [numberMinError, numberMinErrorSet] = useState('');
|
||||
const [inputTextValue, setInputTextValue] = useState(() => typeof value === 'string' ? value : '');
|
||||
const [textError, setTextError] = useState('');
|
||||
const [inputNumberMin, setInputNumberMin] = useState(() => Array.isArray(value) ? value[0] === undefined ? 0 : value[0] : 0);
|
||||
const [numberMinError, setNumberMinError] = useState('');
|
||||
|
||||
const [inputNumberMax, inputNumberMaxSet] = useState(() => Array.isArray(value) ? value[1] === undefined ? 100 : value[1] : 100);
|
||||
const [numberMaxError, numberMaxErrorSet] = useState('');
|
||||
const [inputNumberMax, setInputNumberMax] = useState(() => Array.isArray(value) ? value[1] === undefined ? 100 : value[1] : 100);
|
||||
const [numberMaxError, setNumberMaxError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
switch (type) {
|
||||
@@ -93,7 +92,7 @@ const HighlightCellInput = (props: {
|
||||
case CFSubRuleType.text: {
|
||||
if ([CFTextOperator.beginsWith, CFTextOperator.containsText, CFTextOperator.endsWith, CFTextOperator.notEqual, CFTextOperator.notContainsText, CFTextOperator.equal].includes(operator as any)) {
|
||||
if (!inputTextValue) {
|
||||
textErrorSet(localeService.t('sheet.cf.errorMessage.notBlank'));
|
||||
setTextError(localeService.t('sheet.cf.errorMessage.notBlank'));
|
||||
return false;
|
||||
}
|
||||
return next(v);
|
||||
@@ -112,7 +111,7 @@ const HighlightCellInput = (props: {
|
||||
case CFSubRuleType.text: {
|
||||
if ([CFTextOperator.beginsWith, CFTextOperator.endsWith, CFTextOperator.containsText, CFTextOperator.notContainsText, CFTextOperator.equal, CFTextOperator.notEqual].includes(operator as CFTextOperator)) {
|
||||
const _onChange = (value: string) => {
|
||||
inputTextValueSet(value);
|
||||
setInputTextValue(value);
|
||||
onChange(value);
|
||||
};
|
||||
return (
|
||||
@@ -121,7 +120,7 @@ const HighlightCellInput = (props: {
|
||||
<Input
|
||||
value={inputTextValue}
|
||||
onChange={(v) => {
|
||||
textErrorSet('');
|
||||
setTextError('');
|
||||
_onChange(v);
|
||||
}}
|
||||
/>
|
||||
@@ -134,9 +133,9 @@ const HighlightCellInput = (props: {
|
||||
case CFSubRuleType.number: {
|
||||
if ([CFNumberOperator.equal, CFNumberOperator.notEqual, CFNumberOperator.greaterThan, CFNumberOperator.greaterThanOrEqual, CFNumberOperator.lessThan, CFNumberOperator.lessThanOrEqual].includes(operator as CFNumberOperator)) {
|
||||
const _onChange = (value: number | null) => {
|
||||
inputNumberValueSet(value || 0);
|
||||
setInputNumberValue(value || 0);
|
||||
onChange(value || 0);
|
||||
numberErrorSet('');
|
||||
setNumberError('');
|
||||
};
|
||||
return (
|
||||
<div className="univer-mt-3">
|
||||
@@ -154,24 +153,19 @@ const HighlightCellInput = (props: {
|
||||
}
|
||||
if ([CFNumberOperator.between, CFNumberOperator.notBetween].includes(operator as CFNumberOperator)) {
|
||||
const onChangeMin = (_value: number | null) => {
|
||||
inputNumberMinSet(_value || 0);
|
||||
setInputNumberMin(_value || 0);
|
||||
const value: [number, number] = [_value || 0, inputNumberMax];
|
||||
onChange(value);
|
||||
numberMinErrorSet('');
|
||||
setNumberMinError('');
|
||||
};
|
||||
const onChangeMax = (_value: number | null) => {
|
||||
inputNumberMaxSet(_value || 0);
|
||||
setInputNumberMax(_value || 0);
|
||||
const value: [number, number] = [inputNumberMin, _value || 0];
|
||||
onChange(value);
|
||||
numberMaxErrorSet('');
|
||||
setNumberMaxError('');
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
univer-mt-3
|
||||
${stylesBase.labelContainer}
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-3 univer-flex univer-items-center">
|
||||
<WrapperError errorText={numberMinError}>
|
||||
<InputNumber min={Number.MIN_SAFE_INTEGER} max={Number.MAX_SAFE_INTEGER} value={inputNumberMin} onChange={onChangeMin} />
|
||||
</WrapperError>
|
||||
@@ -285,7 +279,7 @@ export const HighlightCellStyleEditor = (props: IStyleEditorProps<any, ITextHigh
|
||||
return v;
|
||||
});
|
||||
|
||||
const [style, styleSet] = useState<IHighlightCell['style']>({});
|
||||
const [style, setStyle] = useState<IHighlightCell['style']>({});
|
||||
|
||||
const getResult = useMemo(() => (option: { subType?: string; operator?: string; value?: IValue; style?: IHighlightCell['style'] }) => {
|
||||
switch (option.subType || subType) {
|
||||
@@ -373,12 +367,7 @@ export const HighlightCellStyleEditor = (props: IStyleEditorProps<any, ITextHigh
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.title}
|
||||
univer-mt-4
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<div className="univer-flex univer-justify-between univer-gap-4">
|
||||
@@ -397,19 +386,23 @@ export const HighlightCellStyleEditor = (props: IStyleEditorProps<any, ITextHigh
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<HighlightCellInput key={inputRenderKey} value={value} interceptorManager={interceptorManager} type={subType} operator={operator} rule={rule} onChange={onInputChange} />
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<HighlightCellInput
|
||||
key={inputRenderKey}
|
||||
value={value}
|
||||
interceptorManager={interceptorManager}
|
||||
type={subType}
|
||||
operator={operator}
|
||||
rule={rule}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
<div className={previewClassName}>
|
||||
<Preview rule={getResult({}) as IConditionalFormattingRuleConfig} />
|
||||
</div>
|
||||
<ConditionalStyleEditor
|
||||
style={rule?.style}
|
||||
className="univer-ml-1"
|
||||
onChange={(v) => {
|
||||
styleSet(v);
|
||||
setStyle(v);
|
||||
onChange(getResult({ style: v }));
|
||||
}}
|
||||
/>
|
||||
|
||||
+99
-69
@@ -36,8 +36,6 @@ import {
|
||||
import { FormulaEditor } from '@univerjs/sheets-formula-ui';
|
||||
import { ILayoutService, useDependency, useScrollYOverContainer, useSidebarClick } from '@univerjs/ui';
|
||||
import { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const getIcon = (iconType: string, iconId: string | number) => {
|
||||
const arr = iconMap[iconType] || [];
|
||||
@@ -45,15 +43,11 @@ const getIcon = (iconType: string, iconId: string | number) => {
|
||||
};
|
||||
|
||||
const TextInput = (props: { id: number; type: CFValueType; value: number | string; onChange: (v: number | string) => void; error?: string }) => {
|
||||
const { error, type, onChange } = props;
|
||||
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const unitId = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!.getUnitId();
|
||||
const subUnitId = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!.getActiveSheet()?.getSheetId();
|
||||
const className = useMemo(() => {
|
||||
if (props.error) {
|
||||
return styles.errorInput;
|
||||
}
|
||||
return '';
|
||||
}, [props.error]);
|
||||
|
||||
const formulaEditorRef = useRef<IFormulaEditorRef>(null);
|
||||
const [isFocusFormulaEditor, isFocusFormulaEditorSet] = useState(false);
|
||||
@@ -63,14 +57,20 @@ const TextInput = (props: { id: number; type: CFValueType; value: number | strin
|
||||
isOutSide && isFocusFormulaEditorSet(false);
|
||||
});
|
||||
return (
|
||||
<div className={styles.positionRelative}>
|
||||
{props.type !== CFValueType.formula
|
||||
<div className="univer-relative">
|
||||
{type !== CFValueType.formula
|
||||
? (
|
||||
<>
|
||||
<InputNumber className={className} value={Number(props.value) || 0} onChange={(v) => props.onChange(v ?? 0)} />
|
||||
{props.error && (
|
||||
<div className={styles.errorText}>
|
||||
{props.error}
|
||||
<InputNumber
|
||||
className={clsx({
|
||||
'univer-border-red-500': error,
|
||||
})}
|
||||
value={Number(props.value) || 0}
|
||||
onChange={(v) => onChange(v ?? 0)}
|
||||
/>
|
||||
{error && (
|
||||
<div className="univer-absolute univer-text-xs univer-text-red-500">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -78,16 +78,16 @@ const TextInput = (props: { id: number; type: CFValueType; value: number | strin
|
||||
: (
|
||||
<div className="univer-w-full">
|
||||
<FormulaEditor
|
||||
ref={formulaEditorRef}
|
||||
initValue={String(props.value) as any}
|
||||
unitId={unitId}
|
||||
subUnitId={subUnitId}
|
||||
isFocus={isFocusFormulaEditor}
|
||||
onChange={(v = '') => {
|
||||
const formula = v || '';
|
||||
props.onChange(formula);
|
||||
onChange(formula);
|
||||
}}
|
||||
onFocus={() => isFocusFormulaEditorSet(true)}
|
||||
ref={formulaEditorRef}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -101,35 +101,46 @@ const createDefaultConfigItem = (iconType: IIconType, index: number, list: unkno
|
||||
iconId: String(index),
|
||||
});
|
||||
|
||||
interface IconGroupListProps {
|
||||
interface IIconGroupListProps {
|
||||
onClick: (iconType: IIconType) => void;
|
||||
iconType?: IIconType;
|
||||
};
|
||||
const IconGroupList = forwardRef<HTMLDivElement, IconGroupListProps>((props, ref) => {
|
||||
const IconGroupList = forwardRef<HTMLDivElement, IIconGroupListProps>((props, ref) => {
|
||||
const { onClick } = props;
|
||||
const localeService = useDependency(LocaleService);
|
||||
|
||||
const handleClick = (iconType: IIconType) => {
|
||||
props.onClick(iconType);
|
||||
onClick(iconType);
|
||||
};
|
||||
return (
|
||||
<div ref={ref} className={styles.iconGroupList}>
|
||||
<div ref={ref} className="univer-w-80">
|
||||
{iconGroup.map((group, index) => {
|
||||
return (
|
||||
<div key={index} className={styles.group}>
|
||||
<div className={styles.title}>{localeService.t(group.title)}</div>
|
||||
<div className={styles.itemContent}>
|
||||
<div key={index} className="univer-mb-3">
|
||||
<div className="univer-mb-1 univer-text-sm">{localeService.t(group.title)}</div>
|
||||
<div className="univer-flex univer-flex-wrap">
|
||||
{group.group.map((groupItem) => {
|
||||
return (
|
||||
<div className={styles.itemWrap} key={groupItem.name} onClick={() => { handleClick(groupItem.name); }}>
|
||||
<div className={styles.item}>
|
||||
<div
|
||||
key={groupItem.name}
|
||||
className="univer-mb-1 univer-flex univer-w-1/2 univer-items-center"
|
||||
onClick={() => { handleClick(groupItem.name); }}
|
||||
>
|
||||
<a
|
||||
className={`
|
||||
univer-cursor-pointer univer-rounded
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
{groupItem.list.map((base64, index) => (
|
||||
<img
|
||||
key={index}
|
||||
className="univer-size-5"
|
||||
src={base64}
|
||||
draggable={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -143,6 +154,8 @@ const IconGroupList = forwardRef<HTMLDivElement, IconGroupListProps>((props, ref
|
||||
});
|
||||
|
||||
const IconItemList = (props: { onClick: (iconType: IIconType, iconId: string) => void; iconType?: IIconType; iconId: string }) => {
|
||||
const { onClick } = props;
|
||||
|
||||
const list = useMemo(() => {
|
||||
const result: { iconType: IIconType; iconId: string; base64: string }[] = [];
|
||||
for (const key in iconMap) {
|
||||
@@ -158,28 +171,40 @@ const IconItemList = (props: { onClick: (iconType: IIconType, iconId: string) =>
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
const handleClick = (item: typeof list[0]) => {
|
||||
props.onClick(item.iconType, item.iconId);
|
||||
onClick(item.iconType, item.iconId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.iconItemListWrap}>
|
||||
<div className={styles.none} onClick={() => handleClick({ iconType: EMPTY_ICON_TYPE as any, iconId: '', base64: '' })}>
|
||||
<div>
|
||||
<div
|
||||
className="univer-mb-2.5 univer-flex univer-cursor-pointer univer-items-center univer-pl-1"
|
||||
onClick={() => handleClick({ iconType: EMPTY_ICON_TYPE as any, iconId: '', base64: '' })}
|
||||
>
|
||||
<SlashSingle className="univer-size-5" />
|
||||
<span>无单元格图标</span>
|
||||
<span className="univer-ml-2">无单元格图标</span>
|
||||
</div>
|
||||
<div className={styles.iconItemList}>
|
||||
<div className="univer-flex univer-w-64 univer-flex-wrap">
|
||||
{list.map((item) => (
|
||||
<div key={`${item.iconType}_${item.iconId}`} className={styles.item}>
|
||||
<div
|
||||
key={`${item.iconType}_${item.iconId}`}
|
||||
className={`
|
||||
univer-mb-2 univer-mr-2 univer-flex univer-cursor-pointer univer-items-center
|
||||
univer-justify-center univer-rounded
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
<img
|
||||
className="univer-size-5"
|
||||
onClick={() => handleClick(item)}
|
||||
src={item.base64}
|
||||
draggable={false}
|
||||
onClick={() => handleClick(item)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
@@ -235,8 +260,8 @@ const IconSetRuleEdit = (props: {
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.label}
|
||||
univer-flex univer-items-center univer-justify-between
|
||||
univer-mt-3 univer-flex univer-items-center univer-justify-between univer-text-sm
|
||||
univer-text-gray-600
|
||||
`}
|
||||
>
|
||||
<div
|
||||
@@ -250,7 +275,7 @@ const IconSetRuleEdit = (props: {
|
||||
<>
|
||||
{!isFirst && !isEnd && localeService.t('sheet.cf.iconSet.rule')}
|
||||
{!isFirst && !isEnd && (
|
||||
<span className={styles.stress}>
|
||||
<span className="univer-font-medium univer-text-gray-600">
|
||||
(
|
||||
{localeService.t('sheet.cf.iconSet.when')}
|
||||
{localeService.t(`sheet.cf.symbol.${getOppositeOperator(preItem.operator)}`)}
|
||||
@@ -272,8 +297,22 @@ const IconSetRuleEdit = (props: {
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className={clsx(styles.dropdownIcon, 'univer-box-border univer-h-7')}>
|
||||
{icon ? <img src={icon} className={styles.icon} /> : <SlashSingle className={styles.icon} />}
|
||||
<div
|
||||
className={`
|
||||
univer-box-border univer-flex univer-h-8 univer-w-full univer-items-center
|
||||
univer-justify-between univer-rounded-md univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-bg-white univer-px-4 univer-py-2 univer-text-xs
|
||||
univer-text-gray-600 univer-transition-all
|
||||
hover:univer-border-primary-600
|
||||
`}
|
||||
>
|
||||
{icon
|
||||
? <img src={icon} className="univer-size-4" draggable={false} />
|
||||
: (
|
||||
<SlashSingle
|
||||
className="univer-size-4"
|
||||
/>
|
||||
)}
|
||||
<MoreDownSingle />
|
||||
</div>
|
||||
</Dropdown>
|
||||
@@ -287,15 +326,9 @@ const IconSetRuleEdit = (props: {
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<div
|
||||
className={`
|
||||
univer-w-[45%]
|
||||
${stylesBase.label}
|
||||
`}
|
||||
style={{ marginTop: 0 }}
|
||||
>
|
||||
<div className="univer-mt-0 univer-w-[45%] univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.iconSet.rule')}
|
||||
<span className={styles.stress}>
|
||||
<span className="univer-font-medium univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.iconSet.when')}
|
||||
{localeService.t(`sheet.cf.symbol.${getOppositeOperator(preItem.operator)}`)}
|
||||
{lessThanText}
|
||||
@@ -309,9 +342,8 @@ const IconSetRuleEdit = (props: {
|
||||
<>
|
||||
<div
|
||||
className={`
|
||||
univer-mt-3
|
||||
${stylesBase.label}
|
||||
univer-flex univer-items-center univer-justify-between univer-gap-4
|
||||
univer-mt-3 univer-flex univer-items-center univer-justify-between univer-gap-4
|
||||
univer-text-sm univer-text-gray-600
|
||||
`}
|
||||
>
|
||||
<div>
|
||||
@@ -515,11 +547,11 @@ export const IconSet = (props: IStyleEditorProps<unknown, IIconSet>) => {
|
||||
useScrollYOverContainer(iconGroupListEl, layoutService.rootContainerElement);
|
||||
|
||||
return (
|
||||
<div className={styles.iconSet}>
|
||||
<div className={stylesBase.title}>{localeService.t('sheet.cf.panel.styleRule')}</div>
|
||||
<div
|
||||
className="univer-mt-3"
|
||||
>
|
||||
<div>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<div className="univer-mt-3">
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
@@ -533,28 +565,26 @@ export const IconSet = (props: IStyleEditorProps<unknown, IIconSet>) => {
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className={clsx(styles.dropdownIcon, 'univer-box-border univer-h-7 univer-w-auto')}>
|
||||
<div
|
||||
className={clsx(`
|
||||
univer-box-border univer-flex univer-h-8 univer-w-full univer-items-center
|
||||
univer-justify-between univer-rounded-md univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-bg-white univer-px-4 univer-py-2 univer-text-xs
|
||||
univer-text-gray-600 univer-transition-all
|
||||
hover:univer-border-primary-600
|
||||
`)}
|
||||
>
|
||||
{previewIcon}
|
||||
<MoreDownSingle />
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
univer-mt-3
|
||||
${styles.renderConfig}
|
||||
`}
|
||||
>
|
||||
<div className={styles.utilItem}>
|
||||
<div className="univer-mt-3 univer-flex univer-items-center univer-text-xs">
|
||||
<div className="univer-flex univer-items-center univer-text-xs">
|
||||
<Checkbox onChange={reverseIcon} />
|
||||
{localeService.t('sheet.cf.iconSet.reverseIconOrder')}
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
${styles.utilItem}
|
||||
univer-ml-6
|
||||
`}
|
||||
>
|
||||
<div className="univer-ml-6 univer-flex univer-items-center univer-text-xs">
|
||||
<Checkbox checked={!isShowValue} onChange={(v) => { isShowValueSet(!v); }} />
|
||||
{localeService.t('sheet.cf.iconSet.onlyShowIcon')}
|
||||
</div>
|
||||
|
||||
@@ -20,11 +20,10 @@ import { LocaleService } from '@univerjs/core';
|
||||
import { Checkbox, InputNumber, Select } from '@univerjs/design';
|
||||
import { CFNumberOperator, CFRuleType, CFSubRuleType } from '@univerjs/sheets-conditional-formatting';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ConditionalStyleEditor } from '../../conditional-style-editor';
|
||||
import { Preview } from '../../preview';
|
||||
import stylesBase from '../index.module.less';
|
||||
import styles from './index.module.less';
|
||||
import { previewClassName } from './styles';
|
||||
|
||||
export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
const { onChange, interceptorManager } = props;
|
||||
@@ -33,7 +32,7 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
const rule = props.rule?.type === CFRuleType.highlightCell ? props.rule : undefined as IRankHighlightCell | IAverageHighlightCell | undefined;
|
||||
const options = [{ label: localeService.t('sheet.cf.panel.isNotBottom'), value: 'isNotBottom' }, { label: localeService.t('sheet.cf.panel.isBottom'), value: 'isBottom' }, { label: localeService.t('sheet.cf.panel.greaterThanAverage'), value: 'greaterThanAverage' }, { label: localeService.t('sheet.cf.panel.lessThanAverage'), value: 'lessThanAverage' }];
|
||||
|
||||
const [type, typeSet] = useState(() => {
|
||||
const [type, setType] = useState(() => {
|
||||
const defaultV = options[0].value;
|
||||
const type = rule?.type;
|
||||
if (!rule) {
|
||||
@@ -64,7 +63,7 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
}
|
||||
return defaultV;
|
||||
});
|
||||
const [value, valueSet] = useState(() => {
|
||||
const [value, setValue] = useState(() => {
|
||||
const defaultV = 10;
|
||||
const type = rule?.type;
|
||||
if (!rule) {
|
||||
@@ -82,7 +81,7 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
}
|
||||
return defaultV;
|
||||
});
|
||||
const [isPercent, isPercentSet] = useState(() => {
|
||||
const [isPercent, setIsPercent] = useState(() => {
|
||||
const defaultV = false;
|
||||
const type = rule?.type;
|
||||
if (!rule) {
|
||||
@@ -101,7 +100,7 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
return defaultV;
|
||||
});
|
||||
|
||||
const [style, styleSet] = useState<IHighlightCell['style']>({});
|
||||
const [style, setStyle] = useState<IHighlightCell['style']>({});
|
||||
|
||||
const getResult = (config: {
|
||||
type: string;
|
||||
@@ -142,12 +141,7 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.title}
|
||||
univer-mt-4
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleRule')}
|
||||
</div>
|
||||
<Select
|
||||
@@ -155,38 +149,29 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
value={type}
|
||||
options={options}
|
||||
onChange={(v) => {
|
||||
typeSet(v);
|
||||
setType(v);
|
||||
_onChange({ type: v, isPercent, value, style });
|
||||
}}
|
||||
/>
|
||||
{['isNotBottom', 'isBottom'].includes(type) && (
|
||||
<div
|
||||
className={`
|
||||
${stylesBase.labelContainer}
|
||||
univer-mt-3
|
||||
`}
|
||||
>
|
||||
<div className="univer-mt-3 univer-flex univer-items-center">
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={1000}
|
||||
value={value}
|
||||
onChange={(v) => {
|
||||
const value = v || 0;
|
||||
valueSet(value);
|
||||
setValue(value);
|
||||
_onChange({ type, isPercent, value, style });
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className={`
|
||||
univer-ml-3
|
||||
${stylesBase.labelContainer}
|
||||
${styles.text}
|
||||
`}
|
||||
className="univer-ml-3 univer-flex univer-items-center univer-text-xs"
|
||||
>
|
||||
<Checkbox
|
||||
checked={isPercent}
|
||||
onChange={(v) => {
|
||||
isPercentSet(!!v);
|
||||
setIsPercent(!!v);
|
||||
_onChange({ type, isPercent: !!v, value, style });
|
||||
}}
|
||||
/>
|
||||
@@ -195,18 +180,14 @@ export const RankStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<div className={previewClassName}>
|
||||
<Preview rule={getResult({ type, isPercent, value, style }) as IConditionalFormattingRuleConfig} />
|
||||
</div>
|
||||
<ConditionalStyleEditor
|
||||
style={rule?.style}
|
||||
className="univer-mt-3"
|
||||
onChange={(v) => {
|
||||
styleSet(v);
|
||||
setStyle(v);
|
||||
_onChange({ type, isPercent, value, style: v });
|
||||
}}
|
||||
/>
|
||||
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
.cf-rule-style-editor {
|
||||
.cf-error-text {
|
||||
color: rgb(var(--red-500));
|
||||
font-size: var(--font-size-xxs);
|
||||
margin-top: var(--margin-xxs);
|
||||
}
|
||||
|
||||
.cf-preview-wrap {
|
||||
margin-top: var(--margin-lg);
|
||||
padding: var(--padding-xs) var(--padding-sm);
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-base);
|
||||
}
|
||||
.text {
|
||||
font-size: var(--font-size-xxs);
|
||||
}
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn-list {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: var(--margin-base);
|
||||
}
|
||||
|
||||
.util-item {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
font-size: var(--font-size-xxs);
|
||||
}
|
||||
|
||||
.icon-set {
|
||||
.render-config {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: var(--font-size-xxs);
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.dropdown-icon {
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-base);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
padding: var(--padding-sm) var(--padding-lg);
|
||||
font-size: var(--font-size-xxs);
|
||||
color: rgb(var(--text-color-secondary));
|
||||
transition: all 0.15s;
|
||||
&:hover {
|
||||
border-color: rgb(var(--primary-color)) !important;
|
||||
}
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.error-input {
|
||||
border: 1px solid rgb(var(--red-400));
|
||||
}
|
||||
.error-text {
|
||||
color: rgb(var(--red-400));
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-group-list {
|
||||
padding: var(--padding-base);
|
||||
font-size: var(--font-size-xs);
|
||||
box-sizing: border-box;
|
||||
width: 328px;
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
outline: none;
|
||||
box-shadow: var(--box-shadow-base);
|
||||
.title {
|
||||
font-size: 13px;
|
||||
margin-bottom: var(--margin-xxs);
|
||||
}
|
||||
.group {
|
||||
margin-bottom: var(--margin-sm);
|
||||
}
|
||||
.item-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.item-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: 50%;
|
||||
margin-bottom: 4px;
|
||||
.item {
|
||||
border-radius: var(--border-radius-base);
|
||||
cursor: pointer;
|
||||
:not(:first-child).icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgb(var(--bg-color-hover));
|
||||
}
|
||||
}
|
||||
:not(:first-child).icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
.icon-item-list-wrap {
|
||||
padding: var(--padding-base) 4px var(--padding-base) var(--padding-base);
|
||||
font-size: var(--font-size-xs);
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
outline: none;
|
||||
box-shadow: var(--box-shadow-base);
|
||||
.none {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
padding-left: 4px;
|
||||
span {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-item-list {
|
||||
display: flex;
|
||||
width: 252px;
|
||||
flex-wrap: wrap;
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: var(--border-radius-base);
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgb(var(--bg-color-hover));
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.width100 {
|
||||
width: 100%;
|
||||
}
|
||||
.stress {
|
||||
color: rgb(var(--text-color));
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -26,13 +26,11 @@ import { AddCfCommand, CFRuleType, CFSubRuleType, ConditionalFormattingRuleModel
|
||||
import { RangeSelector } from '@univerjs/sheets-formula-ui';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import styleBase from '../index.module.less';
|
||||
import { ColorScaleStyleEditor } from './ColorScale';
|
||||
import { DataBarStyleEditor } from './DataBar';
|
||||
import { FormulaStyleEditor } from './Formula';
|
||||
import { HighlightCellStyleEditor } from './HighlightCell';
|
||||
import { IconSet } from './IconSet';
|
||||
import styles from './index.module.less';
|
||||
import { RankStyleEditor } from './Rank';
|
||||
import { beforeSubmit, submit } from './type';
|
||||
|
||||
@@ -231,8 +229,10 @@ export const RuleEdit = (props: IRuleEditProps) => {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className={styles.cfRuleStyleEditor}>
|
||||
<div className={styleBase.title}>{localeService.t('sheet.cf.panel.range')}</div>
|
||||
<div>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.range')}
|
||||
</div>
|
||||
<div className="univer-mt-4">
|
||||
<RangeSelector
|
||||
unitId={unitId}
|
||||
@@ -241,9 +241,11 @@ export const RuleEdit = (props: IRuleEditProps) => {
|
||||
onChange={(_, text) => onRangeSelectorChange(text)}
|
||||
onVerify={handleVerify}
|
||||
/>
|
||||
{errorText && <div className={styles.cfErrorText}>{errorText}</div>}
|
||||
{errorText && <div className="univer-mt-1 univer-text-xs univer-text-red-500">{errorText}</div>}
|
||||
</div>
|
||||
<div className="univer-mt-4 univer-text-sm univer-text-gray-600">
|
||||
{localeService.t('sheet.cf.panel.styleType')}
|
||||
</div>
|
||||
<div className={styleBase.title}>{localeService.t('sheet.cf.panel.styleType')}</div>
|
||||
<Select
|
||||
className="univer-mt-4 univer-w-full"
|
||||
value={ruleType}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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 const previewClassName = 'univer-mt-5 univer-px-1 univer-py-2 univer-border univer-border-solid univer-border-gray-200 univer-rounded';
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createInterceptorKey } from '@univerjs/core';
|
||||
import type { InterceptorManager } from '@univerjs/core';
|
||||
import type { IConditionalFormattingRuleConfig } from '@univerjs/sheets-conditional-formatting';
|
||||
import { createInterceptorKey } from '@univerjs/core';
|
||||
|
||||
export const beforeSubmit = createInterceptorKey<boolean, null>('beforeSubmit');
|
||||
export const submit = createInterceptorKey<any, null>('submit');
|
||||
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
.cf-rule-list {
|
||||
.rule-selector {
|
||||
color: rgb(var(--text-color-secondary));
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.select {
|
||||
color: rgb(var(--text-color));
|
||||
width: 138px;
|
||||
.select-selector {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.select-selection-item {
|
||||
top: -2px;
|
||||
left: 4px;
|
||||
}
|
||||
.select-selection-search-input {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.btn-list {
|
||||
font-size: 16px;
|
||||
color: black;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.gap {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
padding: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgb(var(--grey-300));
|
||||
}
|
||||
}
|
||||
.disabled {
|
||||
color: rgb(var(--grey-500));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.rule-item {
|
||||
padding: 8px 32px 8px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
border-radius: var(--border-radius-base);
|
||||
.rule-describe {
|
||||
max-width: 100%;
|
||||
min-width: 0px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 1;
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: 21px;
|
||||
.rule-type {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #1e222b;
|
||||
}
|
||||
.rule-range {
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
color: #7a7a7a;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: rgb(var(--grey-100));
|
||||
}
|
||||
&.active {
|
||||
background-color: rgb(var(--grey-100));
|
||||
}
|
||||
.draggableHandle {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: var(--border-radius-base);
|
||||
cursor: grab;
|
||||
// &:hover {
|
||||
// background-color: rgb(var(--grey-300));
|
||||
// }
|
||||
}
|
||||
&:hover {
|
||||
.delete-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.draggableHandle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.delete-item {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius-base);
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
&:hover {
|
||||
background-color: rgb(var(--grey-300));
|
||||
}
|
||||
}
|
||||
& .active {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.grid-layout-wrap {
|
||||
width: calc(100% - 2 * var(--padding-sm) + 2 * var(--padding-xl));
|
||||
margin-left: calc(-1 * var(--padding-xl));
|
||||
padding-left: var(--padding-sm);
|
||||
.react-grid-item {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
:global .react-grid-item.react-grid-placeholder {
|
||||
background: rgb(var(--grey-300)) !important;
|
||||
}
|
||||
+93
-72
@@ -40,7 +40,6 @@ import GridLayout from 'react-grid-layout';
|
||||
import { debounceTime, Observable } from 'rxjs';
|
||||
import { ConditionalFormattingI18nController } from '../../../controllers/cf.i18n.controller';
|
||||
import { Preview } from '../../preview';
|
||||
import styles from './index.module.less';
|
||||
import 'react-grid-layout/css/styles.css';
|
||||
import 'react-resizable/css/styles.css';
|
||||
|
||||
@@ -319,13 +318,13 @@ export const RuleList = (props: IRuleListProps) => {
|
||||
}, [ruleList]);
|
||||
|
||||
return (
|
||||
<div className={styles.cfRuleList}>
|
||||
<div className={styles.ruleSelector}>
|
||||
<div>
|
||||
<div>
|
||||
<div className="univer-flex univer-items-center univer-justify-between univer-gap-2 univer-text-sm">
|
||||
<div className="univer-flex univer-items-center univer-gap-2">
|
||||
{conditionalFormattingI18nController.tWithReactNode(
|
||||
'sheet.cf.panel.managerRuleSelect',
|
||||
<Select
|
||||
className={styles.select}
|
||||
className="univer-w-36"
|
||||
options={selectOption}
|
||||
value={selectValue}
|
||||
onChange={(v) => { setSelectValue(v); }}
|
||||
@@ -334,97 +333,119 @@ export const RuleList = (props: IRuleListProps) => {
|
||||
</div>
|
||||
<div className="univer-flex univer-justify-end">
|
||||
<Tooltip title={localeService.t('sheet.cf.panel.createRule')} placement="bottom">
|
||||
<div
|
||||
className="univer-size-5"
|
||||
<a
|
||||
className="univer-size-5 univer-cursor-pointer"
|
||||
onClick={handleCreate}
|
||||
>
|
||||
<IncreaseSingle />
|
||||
</div>
|
||||
</a>
|
||||
</Tooltip>
|
||||
{(ruleList.length && isHasAllRuleEditPermission)
|
||||
? (
|
||||
<Tooltip title={localeService.t('sheet.cf.panel.clear')} placement="bottom">
|
||||
<div
|
||||
className={clsx(styles.gap, 'univer-size-5')}
|
||||
<a
|
||||
className="univer-size-5 univer-cursor-pointer"
|
||||
onClick={handleClear}
|
||||
>
|
||||
<DeleteSingle />
|
||||
</div>
|
||||
<DeleteSingle className="univer-text-red-500" />
|
||||
</a>
|
||||
</Tooltip>
|
||||
)
|
||||
: (
|
||||
<div className={clsx(styles.gap, styles.disabled)}>
|
||||
<DeleteSingle />
|
||||
<div>
|
||||
<DeleteSingle className="univer-text-gray-300" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ref={layoutContainerRef} className={styles.gridLayoutWrap}>
|
||||
{layoutWidth
|
||||
? (
|
||||
<GridLayout
|
||||
draggableHandle=".draggableHandle"
|
||||
layout={layout}
|
||||
cols={12}
|
||||
rowHeight={60}
|
||||
width={layoutWidth}
|
||||
margin={[0, 10]}
|
||||
onDragStop={handleDragStop}
|
||||
onDragStart={handleDragStart}
|
||||
>
|
||||
{ruleListByPermissionCheck?.map((rule, index) => {
|
||||
return (
|
||||
<div key={`${rule.cfId}`}>
|
||||
|
||||
<div ref={layoutContainerRef}>
|
||||
{layoutWidth > 0 && (
|
||||
<GridLayout
|
||||
className={`
|
||||
[&_.react-grid-item]:univer-transition-none
|
||||
[&_.react-grid-placeholder]:univer-rounded [&_.react-grid-placeholder]:!univer-bg-gray-200
|
||||
`}
|
||||
draggableHandle=".draggableHandle"
|
||||
layout={layout}
|
||||
cols={12}
|
||||
rowHeight={60}
|
||||
width={layoutWidth}
|
||||
margin={[0, 10]}
|
||||
onDragStop={handleDragStop}
|
||||
onDragStart={handleDragStart}
|
||||
>
|
||||
{ruleListByPermissionCheck?.map((rule, index) => {
|
||||
return (
|
||||
<div key={`${rule.cfId}`}>
|
||||
<div
|
||||
className={clsx(`
|
||||
univer-group univer-relative univer-flex univer-items-center
|
||||
univer-justify-between univer-rounded univer-py-2 univer-pl-5 univer-pr-8
|
||||
hover:univer-bg-gray-100
|
||||
`, {
|
||||
'univer-bg-gray-100': draggingId === index,
|
||||
})}
|
||||
onMouseMove={() => {
|
||||
rule.ranges !== currentRuleRanges && currentRuleRangesSet(rule.ranges);
|
||||
}}
|
||||
onMouseLeave={() => currentRuleRangesSet([])}
|
||||
onClick={() => {
|
||||
onClick(rule);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={clsx(styles.ruleItem, {
|
||||
[styles.active]: draggingId === index,
|
||||
})}
|
||||
onMouseMove={() => {
|
||||
rule.ranges !== currentRuleRanges && currentRuleRangesSet(rule.ranges);
|
||||
}}
|
||||
onMouseLeave={() => currentRuleRangesSet([])}
|
||||
onClick={() => {
|
||||
onClick(rule);
|
||||
}}
|
||||
className={clsx(`
|
||||
univer-absolute univer-left-0 univer-hidden univer-size-5
|
||||
univer-cursor-grab univer-items-center univer-justify-center
|
||||
univer-rounded
|
||||
group-hover:univer-flex
|
||||
`, 'draggableHandle')}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div
|
||||
className={clsx(styles.draggableHandle, 'draggableHandle')}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<SequenceSingle />
|
||||
<SequenceSingle />
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
univer-min-w-0 univer-max-w-full univer-flex-shrink univer-overflow-hidden
|
||||
`}
|
||||
>
|
||||
<div className="univer-text-sm univer-text-gray-900">
|
||||
{getRuleDescribe(rule, localeService)}
|
||||
</div>
|
||||
<div className={styles.ruleDescribe}>
|
||||
<div className={styles.ruleType}>
|
||||
{getRuleDescribe(rule, localeService)}
|
||||
</div>
|
||||
<div className={styles.ruleRange}>
|
||||
{rule.ranges.map((range) => serializeRange(range)).join(',')}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Preview rule={rule.rule} />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(styles.deleteItem, {
|
||||
[styles.active]: draggingId === index,
|
||||
})}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDelete(rule);
|
||||
currentRuleRangesSet([]);
|
||||
}}
|
||||
>
|
||||
<DeleteSingle />
|
||||
<div className="univer-text-xs univer-text-gray-400">
|
||||
{rule.ranges.map((range) => serializeRange(range)).join(',')}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Preview rule={rule.rule} />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(`
|
||||
univer-absolute univer-right-1 univer-hidden univer-size-6
|
||||
univer-cursor-pointer univer-items-center univer-justify-center
|
||||
univer-rounded
|
||||
group-hover:univer-flex
|
||||
hover:univer-bg-gray-200
|
||||
`, {
|
||||
'univer-flex univer-items-center univer-justify-center': draggingId === index,
|
||||
})}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDelete(rule);
|
||||
currentRuleRangesSet([]);
|
||||
}}
|
||||
>
|
||||
<DeleteSingle />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</GridLayout>
|
||||
)
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</GridLayout>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.cf-preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
min-width: 72px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
@@ -16,16 +16,16 @@
|
||||
|
||||
import type { IConditionalFormattingRuleConfig } from '@univerjs/sheets-conditional-formatting';
|
||||
import { BooleanNumber, ColorKit } from '@univerjs/core';
|
||||
import { clsx } from '@univerjs/design';
|
||||
import { SlashSingle } from '@univerjs/icons';
|
||||
import { CFRuleType, DEFAULT_BG_COLOR, DEFAULT_FONT_COLOR, defaultDataBarNativeColor, defaultDataBarPositiveColor, getColorScaleFromValue, iconMap } from '@univerjs/sheets-conditional-formatting';
|
||||
import React, { useMemo } from 'react';
|
||||
import styles from './index.module.less';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
|
||||
const rule = props.rule;
|
||||
if (!rule) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!rule) return null;
|
||||
|
||||
const colorList = useMemo(() => {
|
||||
if (rule.type === CFRuleType.colorScale) {
|
||||
const config = rule.config.map((c, index) => ({ color: new ColorKit(c.color), value: index }));
|
||||
@@ -35,6 +35,7 @@ export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
|
||||
}
|
||||
return null;
|
||||
}, [rule]);
|
||||
|
||||
const iconSet = useMemo(() => {
|
||||
if (rule.type === CFRuleType.iconSet) {
|
||||
return rule.config.map((item) => {
|
||||
@@ -43,34 +44,53 @@ 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`;
|
||||
|
||||
switch (rule.type) {
|
||||
case CFRuleType.dataBar:
|
||||
{
|
||||
const { isGradient } = rule.config;
|
||||
const commonStyle = { width: '50%', height: '100%' };
|
||||
const positiveColor = isGradient ? `linear-gradient(to right, ${rule.config.positiveColor || defaultDataBarPositiveColor}, rgb(255 255 255))` : rule.config.positiveColor;
|
||||
const nativeColor = isGradient ? `linear-gradient(to right, rgb(255 255 255),${rule.config.nativeColor || defaultDataBarNativeColor})` : rule.config.nativeColor;
|
||||
|
||||
return (
|
||||
<div className={styles.cfPreview}>
|
||||
<div style={{ ...commonStyle, background: nativeColor, border: `1px solid ${rule.config.nativeColor || defaultDataBarNativeColor}` }} />
|
||||
<div style={{ ...commonStyle, background: positiveColor, border: `1px solid ${rule.config.positiveColor || defaultDataBarPositiveColor}` }} />
|
||||
<div className={previewClassName}>
|
||||
<div
|
||||
className="univer-h-full univer-w-1/2"
|
||||
style={{
|
||||
background: nativeColor,
|
||||
border: `1px solid ${rule.config.nativeColor || defaultDataBarNativeColor}`,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="univer-h-full univer-w-1/2"
|
||||
style={{
|
||||
background: positiveColor,
|
||||
border: `1px solid ${rule.config.positiveColor || defaultDataBarPositiveColor}`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
case CFRuleType.colorScale: {
|
||||
return colorList && (
|
||||
<div className={styles.cfPreview}>
|
||||
<div className={previewClassName}>
|
||||
{colorList.map((item, index) => (
|
||||
<div key={index} style={{ width: `${100 / colorList.length}%`, height: '100%', background: item }} />
|
||||
<div key={index} className="univer-h-full" style={{ width: `${100 / colorList.length}%`, background: item }} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
case CFRuleType.iconSet: {
|
||||
return iconSet && (
|
||||
<div className={styles.cfPreview}>
|
||||
{iconSet.map((base64, index) => (base64 ? <img style={{ height: '100%' }} key={index} src={base64} /> : <SlashSingle key={index} />))}
|
||||
<div className={previewClassName}>
|
||||
{iconSet.map((base64, index) => (
|
||||
base64 ?
|
||||
<img key={index} className="univer-h-full" src={base64} draggable={false} />
|
||||
: <SlashSingle key={index} />))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -83,18 +103,22 @@ export const Preview = (props: { rule?: IConditionalFormattingRuleConfig }) => {
|
||||
const bgColor = bg?.rgb ?? DEFAULT_BG_COLOR;
|
||||
const fontColor = cl?.rgb ?? DEFAULT_FONT_COLOR;
|
||||
const style = {
|
||||
fontWeight: isBold ? 'bold' : undefined,
|
||||
fontStyle: isItalic ? 'italic' : undefined,
|
||||
textDecoration: `${isUnderline ? 'underline' : ''} ${isStrikethrough ? 'line-through' : ''}`.replace(/^ /, '') || undefined,
|
||||
textDecoration: `${isUnderline ? 'underline' : ''} ${isStrikethrough ? 'line-through' : ''}`.replace(/^ /, '') ?? undefined,
|
||||
backgroundColor: bgColor,
|
||||
color: fontColor,
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={style} className={styles.cfPreview}>
|
||||
<div
|
||||
className={clsx(previewClassName, {
|
||||
'univer-font-bold': isBold,
|
||||
'univer-italic': isItalic,
|
||||
})}
|
||||
style={style}
|
||||
>
|
||||
123
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -80,10 +80,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/icons-svg": "^0.3.22",
|
||||
"@univerjs/icons-svg": "^0.3.24",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/sheets": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"@univerjs/docs": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@univerjs/sheets-note-ui",
|
||||
"version": "0.6.10",
|
||||
"version": "0.7.0-beta.0",
|
||||
"private": false,
|
||||
"description": "Univer sheets note UI plugin",
|
||||
"author": "DreamNum <developer@univer.ai>",
|
||||
@@ -64,6 +64,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@univerjs/core": "workspace:*",
|
||||
"@univerjs/design": "workspace:*",
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"@univerjs/icons": "^0.3.24",
|
||||
"@univerjs/sheets": "workspace:*",
|
||||
@@ -75,9 +76,10 @@
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"less": "^4.1.3",
|
||||
"typescript": "^5.4.3",
|
||||
"vite": "^4.5.2",
|
||||
"vitest": "^1.3.1"
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import './global.css';
|
||||
|
||||
export * from './plugin';
|
||||
export * from './services/sheets-note-popup.service';
|
||||
export * from './views/note';
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { ISheetNote } from '@univerjs/sheets-note';
|
||||
import type { IPopup } from '@univerjs/ui';
|
||||
import type { IUniverSheetsNoteUIPluginConfig } from '../plugin';
|
||||
import { ICommandService, LocaleService } from '@univerjs/core';
|
||||
import { clsx, scrollbarClassName } from '@univerjs/design';
|
||||
import { SheetDeleteNoteCommand, SheetsNoteModel, SheetUpdateNoteCommand } from '@univerjs/sheets-note';
|
||||
import { useConfigValue, useDebounceFn, useDependency } from '@univerjs/ui';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
@@ -111,16 +112,17 @@ export const SheetsNote = (props: { popup: IPopup<{ location: ISheetLocationBase
|
||||
|
||||
return (
|
||||
<textarea
|
||||
style={{ width: note.width, height: note.height }}
|
||||
ref={textareaRef}
|
||||
className={`
|
||||
univer-note-textarea univer-resize-both univer-ml-[1px] univer-rounded univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-p-2 univer-shadow
|
||||
data-u-comp="note-textarea"
|
||||
className={clsx(`
|
||||
univer-resize-both univer-ml-[1px] univer-rounded univer-border univer-border-solid univer-border-gray-200
|
||||
univer-p-2 univer-shadow
|
||||
focus:univer-outline-none
|
||||
`}
|
||||
`, scrollbarClassName)}
|
||||
style={{ width: note.width, height: note.height }}
|
||||
value={note.note}
|
||||
onChange={handleNoteChange}
|
||||
placeholder={localeService.t('note.placeholder')}
|
||||
onChange={handleNoteChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@univerjs/sheets-note",
|
||||
"version": "0.6.10",
|
||||
"version": "0.7.0-beta.0",
|
||||
"private": false,
|
||||
"description": "Univer sheets note base plugin",
|
||||
"author": "DreamNum <developer@univer.ai>",
|
||||
@@ -77,7 +77,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ export class SheetsNotePlugin extends Plugin {
|
||||
static override type = UniverInstanceType.UNIVER_SHEET;
|
||||
|
||||
constructor(
|
||||
@Inject(Injector) protected override readonly _injector: Injector,
|
||||
@IConfigService private readonly _configService: IConfigService
|
||||
@IConfigService private readonly _configService: IConfigService,
|
||||
@Inject(Injector) protected override readonly _injector: Injector
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import styles from './index.module.less';
|
||||
import { ZoomSlider } from './ZoomSlider';
|
||||
|
||||
interface ICountBarProps {
|
||||
@@ -26,7 +23,7 @@ interface ICountBarProps {
|
||||
|
||||
export function CountBar(props: ICountBarProps) {
|
||||
return (
|
||||
<section className={styles.countBar}>
|
||||
<section className="univer-flex univer-flex-shrink-0 univer-justify-end">
|
||||
<ZoomSlider />
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
import type { IScrollState } from './sheet-bar-tabs/utils/slide-tab-bar';
|
||||
import { ICommandService, IPermissionService } from '@univerjs/core';
|
||||
import { clsx } from '@univerjs/design';
|
||||
import { IncreaseSingle, MoreSingle } from '@univerjs/icons';
|
||||
import { InsertSheetCommand, WorkbookCreateSheetPermission, WorkbookEditablePermission } from '@univerjs/sheets';
|
||||
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useActiveWorkbook } from '../../components/hook';
|
||||
import { ISheetBarService } from '../../services/sheet-bar/sheet-bar.service';
|
||||
import styles from './index.module.less';
|
||||
import { SheetBarButton } from './sheet-bar-button/SheetBarButton';
|
||||
import { SheetBarMenu } from './sheet-bar-menu/SheetBarMenu';
|
||||
import { SheetBarTabs } from './sheet-bar-tabs/SheetBarTabs';
|
||||
@@ -78,8 +75,8 @@ export const SheetBar = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.sheetBar, 'univer-relative univer-flex univer-h-full univer-flex-1')}>
|
||||
<div className={styles.sheetBarOptions}>
|
||||
<div className="univer-relative univer-flex univer-h-full univer-min-w-0 univer-flex-1">
|
||||
<div className="univer-flex univer-items-center univer-pl-2">
|
||||
{/* Add sheet button */}
|
||||
<SheetBarButton onClick={addSheet} disabled={!(workbookCreateSheetPermission?.value && workbookEditablePermission?.value)}>
|
||||
<IncreaseSingle />
|
||||
@@ -95,12 +92,13 @@ export const SheetBar = () => {
|
||||
{(!leftScrollState || !rightScrollState) && (
|
||||
<div
|
||||
className={`
|
||||
${styles.sheetBarOptions}
|
||||
${styles.sheetBarOptionsDivider}
|
||||
univer-relative univer-flex univer-items-center univer-px-2
|
||||
after:univer-absolute after:univer-right-0 after:univer-top-1/2 after:univer-h-4 after:univer-w-px
|
||||
after:-univer-translate-y-1/2 after:univer-bg-gray-200 after:univer-content-[""]
|
||||
`}
|
||||
>
|
||||
<SheetBarButton disabled={leftScrollState} onClick={handleScrollLeft}>
|
||||
<MoreSingle style={{ transform: 'rotateZ(180deg)' }} />
|
||||
<MoreSingle className="univer-rotate-180" />
|
||||
</SheetBarButton>
|
||||
<SheetBarButton disabled={rightScrollState} onClick={handleScrollRight}>
|
||||
<MoreSingle />
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
@sheet-bar-max-width: 1515px;
|
||||
@status-bar-max-width: 332px;
|
||||
@zoom-slider-width: 260px;
|
||||
@margin-right: -4px;
|
||||
|
||||
.sheet-bar {
|
||||
min-width: calc(100% - @zoom-slider-width - @status-bar-max-width);
|
||||
max-width: calc(100% - @zoom-slider-width);
|
||||
|
||||
&-options {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
margin: var(--margin-xxs);
|
||||
|
||||
transition: display 0.2s;
|
||||
|
||||
&-divider::after {
|
||||
content: '';
|
||||
|
||||
display: block;
|
||||
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin: 0 var(--margin-xs);
|
||||
|
||||
background-color: rgb(var(--grey-400));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export function RenderSheetFooter() {
|
||||
{sheetBar && <SheetBar />}
|
||||
{statisticBar && <StatusBar />}
|
||||
{menus && footerMenus.length && (
|
||||
<div className="univer-mr-2 univer-flex univer-gap-2">
|
||||
<div className="univer-box-border univer-flex univer-gap-2 univer-px-2">
|
||||
{footerMenus.map((item) => item.children?.map((child) => (
|
||||
child?.item && (
|
||||
<ToolbarItem
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
|
||||
import type { IFunctionNames } from '@univerjs/engine-formula';
|
||||
import type { FC } from 'react';
|
||||
import { LocaleService, numfmt } from '@univerjs/core';
|
||||
import { MessageType, Tooltip } from '@univerjs/design';
|
||||
import { FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT } from '@univerjs/engine-formula';
|
||||
import { IClipboardInterfaceService, IMessageService, useDependency } from '@univerjs/ui';
|
||||
import React from 'react';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface IStatisticItem {
|
||||
name: IFunctionNames;
|
||||
@@ -52,7 +50,7 @@ interface IFunctionNameMap {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export const CopyableStatisticItem: React.FC<IStatisticItem> = (item: IStatisticItem) => {
|
||||
export const CopyableStatisticItem: FC<IStatisticItem> = (item: IStatisticItem) => {
|
||||
const localeService = useDependency(LocaleService);
|
||||
const messageService = useDependency(IMessageService);
|
||||
const clipboardService = useDependency(IClipboardInterfaceService);
|
||||
@@ -68,7 +66,14 @@ export const CopyableStatisticItem: React.FC<IStatisticItem> = (item: IStatistic
|
||||
};
|
||||
return (
|
||||
<Tooltip title={localeService.t('statusbar.clickToCopy')} placement="top">
|
||||
<div key={item.name} className={styles.statisticItem} onClick={copyToClipboard}>
|
||||
<div
|
||||
key={item.name}
|
||||
className={`
|
||||
univer-flex univer-max-w-24 univer-cursor-default univer-truncate univer-text-center univer-text-xs
|
||||
univer-text-gray-400
|
||||
`}
|
||||
onClick={copyToClipboard}
|
||||
>
|
||||
<span>
|
||||
{`${localeService.t(
|
||||
functionDisplayNames?.[item.name as string] || (item.name as string)
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
*/
|
||||
|
||||
import type { Nullable } from '@univerjs/core';
|
||||
import type { ComponentType } from 'react';
|
||||
import type { IUniverSheetsUIConfig } from '../../controllers/config.schema';
|
||||
import type { IStatusBarServiceStatus, StatusBarService } from '../../services/status-bar.service';
|
||||
import type { IStatisticItem } from './CopyableStatisticItem';
|
||||
import { debounce } from '@univerjs/core';
|
||||
import { clsx } from '@univerjs/design';
|
||||
import { useConfigValue, useDependency } from '@univerjs/ui';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { SHEETS_UI_PLUGIN_CONFIG_KEY } from '../../controllers/config.schema';
|
||||
import { IStatusBarService } from '../../services/status-bar.service';
|
||||
import { CopyableStatisticItem } from './CopyableStatisticItem';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const SINGLE_MODE_WIDTH = 800;
|
||||
const ROW_COUNT_THRESHOLD = 3;
|
||||
@@ -120,10 +120,10 @@ export const StatusBar = () => {
|
||||
const useStatisticLayout = (
|
||||
showList: IStatisticItem[],
|
||||
rowCountThreshold: number,
|
||||
CopyableStatisticItem: React.ComponentType<IStatisticItem>
|
||||
CopyableStatisticItem: ComponentType<IStatisticItem>
|
||||
) => {
|
||||
if (!showStatistic) return null;
|
||||
const renderContent = React.useMemo(() => {
|
||||
const renderContent = useMemo(() => {
|
||||
if (showList.length > rowCountThreshold) {
|
||||
const doubleLineList = showList.reduce<IStatisticItem[][]>((acc, _, index) => {
|
||||
if (index % 2 === 0) {
|
||||
@@ -135,10 +135,7 @@ export const StatusBar = () => {
|
||||
return (
|
||||
<>
|
||||
{doubleLineList.map((item, index) => (
|
||||
<div
|
||||
key={`stat-col-${index}`}
|
||||
className={styles.statisticListColumn}
|
||||
>
|
||||
<div key={`stat-col-${index}`}>
|
||||
{item[0] && (
|
||||
<CopyableStatisticItem
|
||||
key={item[0].name}
|
||||
@@ -177,12 +174,16 @@ export const StatusBar = () => {
|
||||
return (
|
||||
show && (
|
||||
<div
|
||||
className={clsx(styles.statusBar, {
|
||||
[styles.singleMode]: isSingle,
|
||||
className={clsx(`
|
||||
univer-relative univer-box-border univer-flex univer-items-center univer-px-2
|
||||
after:univer-absolute after:univer-right-0 after:univer-top-1/2 after:univer-block after:univer-h-4
|
||||
after:univer-w-px after:-univer-translate-y-1/2 after:univer-bg-gray-200 after:univer-content-[""]
|
||||
`, {
|
||||
'univer-max-w-32': isSingle,
|
||||
'univer-max-w-80': !isSingle,
|
||||
})}
|
||||
>
|
||||
<div className="univer-flex">{renderContent}</div>
|
||||
<div className={styles.statusBarDiv} />
|
||||
<div className="univer-flex univer-gap-x-2">{renderContent}</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
@statistic-menu-value-width: 55px;
|
||||
|
||||
.status-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 332px;
|
||||
|
||||
&.single-mode {
|
||||
max-width: 136px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-bar-div {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin-left: 10px;
|
||||
background: rgb(var(--grey-400, #ccc));
|
||||
}
|
||||
|
||||
.statistic {
|
||||
&-list-column &-item {
|
||||
font-size: 12px;
|
||||
line-height: 140%;
|
||||
color: rgb(var(--grey-500));
|
||||
}
|
||||
|
||||
&-item {
|
||||
cursor: default;
|
||||
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
max-width: 106px;
|
||||
margin-right: 8px;
|
||||
|
||||
font-size: var(--font-size-xxs);
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
line-height: 20px; /* 181.818% */
|
||||
color: rgb(var(--grey-900));
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: rgb(var(--color-black));
|
||||
}
|
||||
}
|
||||
|
||||
&-picker {
|
||||
display: grid;
|
||||
gap: var(--margin-sm);
|
||||
align-items: center;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 196px;
|
||||
padding: var(--padding-base);
|
||||
|
||||
font-size: var(--font-size-xs);
|
||||
|
||||
background-color: rgb(var(--color-white));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--box-shadow-lg);
|
||||
}
|
||||
|
||||
&-picker-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
&-more {
|
||||
transform: rotate(90deg);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
font-size: 12px;
|
||||
color: rgb(var(--grey-600, #e8e8e8));
|
||||
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgb(var(--grey-300, #e8e8e8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"@univerjs/network": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.2",
|
||||
"vue": "^3.5.13"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user