diff --git a/packages/core/package.json b/packages/core/package.json index 616dfb7e..8fadd697 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@fileverse-dev/fortune-core", - "version": "1.3.12", + "version": "1.3.12-mixed", "main": "lib/index.js", "module": "es/index.js", "typings": "lib/index.d.ts", diff --git a/packages/core/src/events/keyboard.ts b/packages/core/src/events/keyboard.ts index bf1e5baa..5589e6aa 100644 --- a/packages/core/src/events/keyboard.ts +++ b/packages/core/src/events/keyboard.ts @@ -155,129 +155,169 @@ function handleControlPlusArrowKey( e: KeyboardEvent, shiftPressed: boolean ) { - if (ctx.luckysheetCellUpdate.length > 0) return; - const idx = getSheetIndex(ctx, ctx.currentSheetId); if (_.isNil(idx)) return; const file = ctx.luckysheetfile[idx]; - if (!file || !file.row || !file.column) return; const maxRow = file.row; const maxCol = file.column; - let last; - if (ctx.luckysheet_select_save && ctx.luckysheet_select_save.length > 0) - last = ctx.luckysheet_select_save[ctx.luckysheet_select_save.length - 1]; + if (_.isNil(maxRow) || _.isNil(maxCol)) return; + + const last = + ctx.luckysheet_select_save && ctx.luckysheet_select_save.length > 0 + ? ctx.luckysheet_select_save[ctx.luckysheet_select_save.length - 1] + : undefined; if (!last) return; const currR = last.row_focus; const currC = last.column_focus; if (_.isNil(currR) || _.isNil(currC)) return; - const startR = last.row[0]; - const endR = last.row[1]; - const startC = last.column[0]; - const endC = last.column[1]; + const startR = last.row?.[0]; + const endR = last.row?.[1]; + const startC = last.column?.[0]; + const endC = last.column?.[1]; + if (_.isNil(startR) || _.isNil(endR) || _.isNil(startC) || _.isNil(endC)) { + return; + } const horizontalOffset = currC - endC !== 0 ? currC - endC : currC - startC; const verticalOffset = currR - endR !== 0 ? currR - endR : currR - startR; const sheetData = file.data; if (!sheetData) return; - let selectedLimit; switch (e.key) { case "ArrowUp": - selectedLimit = moveToEdge( - sheetData, - e.key, - currC, - -1, - 0, - startR, - endR, - startC, - endC, - maxRow, - maxCol - ); - if (shiftPressed) { - moveHighlightRange(ctx, "down", verticalOffset, "rangeOfSelect"); - moveHighlightRange(ctx, "down", selectedLimit - currR, "rangeOfSelect"); - } else { - moveHighlightCell(ctx, "down", selectedLimit - currR, "rangeOfSelect"); + { + const selectedLimit = moveToEdge( + sheetData, + e.key, + currC, + -1, + 0, + startR, + endR, + startC, + endC, + maxRow, + maxCol + ); + if (shiftPressed) { + moveHighlightRange(ctx, "down", verticalOffset, "rangeOfSelect"); + moveHighlightRange( + ctx, + "down", + selectedLimit - currR, + "rangeOfSelect" + ); + } else { + moveHighlightCell( + ctx, + "down", + selectedLimit - currR, + "rangeOfSelect" + ); + } } break; case "ArrowDown": - selectedLimit = moveToEdge( - sheetData, - e.key, - currC, - 1, - 0, - startR, - endR, - startC, - endC, - maxRow, - maxCol - ); - if (shiftPressed) { - moveHighlightRange(ctx, "down", verticalOffset, "rangeOfSelect"); - moveHighlightRange(ctx, "down", selectedLimit - currR, "rangeOfSelect"); - } else { - moveHighlightCell(ctx, "down", selectedLimit - currR, "rangeOfSelect"); + { + const selectedLimit = moveToEdge( + sheetData, + e.key, + currC, + 1, + 0, + startR, + endR, + startC, + endC, + maxRow, + maxCol + ); + if (shiftPressed) { + moveHighlightRange(ctx, "down", verticalOffset, "rangeOfSelect"); + moveHighlightRange( + ctx, + "down", + selectedLimit - currR, + "rangeOfSelect" + ); + } else { + moveHighlightCell( + ctx, + "down", + selectedLimit - currR, + "rangeOfSelect" + ); + } } break; case "ArrowLeft": - selectedLimit = moveToEdge( - sheetData, - e.key, - currR, - 0, - -1, - startR, - endR, - startC, - endC, - maxRow, - maxCol - ); - if (shiftPressed) { - moveHighlightRange(ctx, "right", horizontalOffset, "rangeOfSelect"); - moveHighlightRange( - ctx, - "right", - selectedLimit - currC, - "rangeOfSelect" + { + const selectedLimit = moveToEdge( + sheetData, + e.key, + currR, + 0, + -1, + startR, + endR, + startC, + endC, + maxRow, + maxCol ); - } else { - moveHighlightCell(ctx, "right", selectedLimit - currC, "rangeOfSelect"); + if (shiftPressed) { + moveHighlightRange(ctx, "right", horizontalOffset, "rangeOfSelect"); + moveHighlightRange( + ctx, + "right", + selectedLimit - currC, + "rangeOfSelect" + ); + } else { + moveHighlightCell( + ctx, + "right", + selectedLimit - currC, + "rangeOfSelect" + ); + } } break; case "ArrowRight": - selectedLimit = moveToEdge( - sheetData, - e.key, - currR, - 0, - 1, - startR, - endR, - startC, - endC, - maxRow, - maxCol - ); - if (shiftPressed) { - moveHighlightRange(ctx, "right", horizontalOffset, "rangeOfSelect"); - moveHighlightRange( - ctx, - "right", - selectedLimit - currC, - "rangeOfSelect" + { + const selectedLimit = moveToEdge( + sheetData, + e.key, + currR, + 0, + 1, + startR, + endR, + startC, + endC, + maxRow, + maxCol ); - } else { - moveHighlightCell(ctx, "right", selectedLimit - currC, "rangeOfSelect"); + if (shiftPressed) { + moveHighlightRange(ctx, "right", horizontalOffset, "rangeOfSelect"); + moveHighlightRange( + ctx, + "right", + selectedLimit - currC, + "rangeOfSelect" + ); + } else { + moveHighlightCell( + ctx, + "right", + selectedLimit - currC, + "rangeOfSelect" + ); + } } break; default: @@ -886,7 +926,29 @@ export async function handleGlobalKeyDown( kstr === "ArrowLeft" || kstr === "ArrowRight" ) { - handleArrowKey(ctx, e); + const isEditing = ctx.luckysheetCellUpdate.length > 0; + const inputText = cellInput?.innerText ?? ""; + const isFormulaEdit = isEditing && inputText.trim().startsWith("="); + const enteredByTyping = cache.enteredEditByTyping === true; + + // Only when we entered edit by typing (not double-click): arrow keys + // commit and move to next cell in that direction. + if (isEditing && !isFormulaEdit && enteredByTyping) { + updateCell( + ctx, + ctx.luckysheetCellUpdate[0], + ctx.luckysheetCellUpdate[1], + cellInput, + undefined, + canvas + ); + cache.enteredEditByTyping = false; + handleArrowKey(ctx, e); + e.preventDefault(); + } else { + // Double-click edit mode or formula: preserve existing behavior + handleArrowKey(ctx, e); + } } else if ( !( (kcode >= 112 && kcode <= 123) || @@ -921,6 +983,8 @@ export async function handleGlobalKeyDown( ctx.luckysheetCellUpdate = [row_index, col_index]; cache.overwriteCell = true; + cache.overwriteCellFirstChar = e.key; + cache.enteredEditByTyping = true; // if (kstr === "Backspace") { // $("#luckysheet-rich-text-editor").html("
"); @@ -931,6 +995,7 @@ export async function handleGlobalKeyDown( // $("#luckysheet-rich-text-editor"), // kcode // ); + e.preventDefault(); } } } diff --git a/packages/core/src/events/mouse.ts b/packages/core/src/events/mouse.ts index faa5be66..6dbf7eff 100644 --- a/packages/core/src/events/mouse.ts +++ b/packages/core/src/events/mouse.ts @@ -1437,6 +1437,7 @@ export function handleCellAreaDoubleClick( col_index = column_focus; } + globalCache.enteredEditByTyping = false; luckysheetUpdateCell(ctx, row_index, col_index); // } } diff --git a/packages/core/src/events/paste.ts b/packages/core/src/events/paste.ts index 060b4d76..6fe4d451 100644 --- a/packages/core/src/events/paste.ts +++ b/packages/core/src/events/paste.ts @@ -7,11 +7,11 @@ import { // execFunctionGroup, } from "../modules/formula"; import { getdatabyselection } from "../modules/cell"; -import { update, datenum_local } from "../modules/format"; +import { update, genarate } from "../modules/format"; import { normalizeSelection, selectionCache } from "../modules/selection"; import { Cell, CellMatrix } from "../types"; import { getSheetIndex, isAllowEdit } from "../utils"; -import { hasPartMC, isRealNum, detectDateFormat } from "../modules/validation"; +import { hasPartMC, isRealNum } from "../modules/validation"; import { getBorderInfoCompute } from "../modules/border"; import { expandRowsAndColumns, storeSheetParamALL } from "../modules/sheet"; import { jfrefreshgrid } from "../modules/refresh"; @@ -699,41 +699,48 @@ function pasteHandler(ctx: Context, data: any, borderInfo?: any) { } if (originCell) { - // If destination cell already has a date format, try to parse pasted string into a date serial - if (originCell.ct && originCell.ct.t === "d" && !isUrl) { - const df = detectDateFormat(originalValueStr); - if (df) { - const dateObj = new Date( - df.year, - df.month - 1, - df.day, - df.hours, - df.minutes, - df.seconds - ); - originCell.v = datenum_local(dateObj); - } else { - // Not a date: preserve original text so user can apply formats later - originCell.v = originalValueStr; - } - } else { - // Default: keep pasted value (numbers already parsed above) - originCell.v = isUrl ? originalValueStr : value; - } - - if (originCell.ct != null && originCell.ct.fa != null) { - // If value is not a numeric serial for date formats, avoid calling update - if (originCell.ct.t === "d" && typeof originCell.v !== "number") { - originCell.m = String(originCell.v); + if (!isUrl) { + const generated = genarate(originalValueStr); + if (generated) { + const [genM, genCt, genV] = generated; + if (genCt?.t === "d") { + // Pasted value is a date — always update ct so toolbar shows "Date" + originCell.v = genV; + originCell.m = genM ?? originalValueStr; + originCell.ct = genCt; + } else { + // Not a date: preserve destination format, just update value + originCell.v = value; + if (originCell.ct != null && originCell.ct.fa != null) { + if ( + originCell.ct.t === "d" && + typeof originCell.v !== "number" + ) { + originCell.m = String(originCell.v); + } else { + originCell.m = update(originCell.ct.fa, originCell.v); + } + } else { + originCell.m = + typeof originCell.v === "boolean" + ? String(originCell.v) + : originCell.v; + } + } } else { - originCell.m = update(originCell.ct.fa, originCell.v); + originCell.v = value; + if (originCell.ct != null && originCell.ct.fa != null) { + originCell.m = update(originCell.ct.fa, originCell.v); + } else { + originCell.m = + typeof originCell.v === "boolean" + ? String(originCell.v) + : originCell.v; + } } } else { - // Convert boolean to string if needed, since m only accepts string | number - originCell.m = - typeof originCell.v === "boolean" - ? String(originCell.v) - : originCell.v; + originCell.v = originalValueStr; + originCell.m = originalValueStr; } if (originCell.f != null && originCell.f.length > 0) { @@ -774,18 +781,16 @@ function pasteHandler(ctx: Context, data: any, borderInfo?: any) { t: "s", }; } else { - // Preserve original pasted text when creating new cells (automatic format) - cell.v = originalValueStr; - cell.m = originalValueStr; - cell.ct = { fa: "General", t: "g" }; // check if hex value to handle hex address if (/^0x?[a-fA-F0-9]+$/.test(value)) { - cell.m = value; - cell.ct = { - fa: "@", - t: "s", - }; cell.v = value; + cell.m = value; + cell.ct = { fa: "@", t: "s" }; + } else { + const [m, ct, v] = genarate(originalValueStr) ?? []; + cell.v = v ?? originalValueStr; + cell.m = m != null ? String(m) : originalValueStr; + cell.ct = ct ?? { fa: "General", t: "g" }; } } diff --git a/packages/core/src/locale/en.ts b/packages/core/src/locale/en.ts index 25cb4c1c..cdb86e3a 100644 --- a/packages/core/src/locale/en.ts +++ b/packages/core/src/locale/en.ts @@ -11674,6 +11674,8 @@ export default { conditionformat_textContains: "Conditional format - Text Contains", conditionformat_textContains_title: "Format cells containing the following text", + conditionformat_empty: "Conditional format - Empty", + conditionformat_empty_title: "Format cells that are empty", conditionformat_occurrenceDate: "Conditional format - Occurrence Date", conditionformat_occurrenceDate_title: "Format cells containing the following dates", @@ -11780,6 +11782,7 @@ export default { between2: "", contain: "Contain", textContains: "Text contains", + empty: "Empty", duplicateValue: "Duplicate value", uniqueValue: "Unique value", top: "Top", diff --git a/packages/core/src/locale/es.ts b/packages/core/src/locale/es.ts index 3f04055a..06ed075b 100644 --- a/packages/core/src/locale/es.ts +++ b/packages/core/src/locale/es.ts @@ -11657,6 +11657,8 @@ export default { conditionformat_textContains: "Conditionformat-TextContains", conditionformat_textContains_title: "Dar formato a las celdas que contienen el siguiente texto", + conditionformat_empty: "Conditional format - Empty", + conditionformat_empty_title: "Dar formato a las celdas vacías", conditionformat_occurrenceDate: "Conditionformat-OccurrenceDate", conditionformat_occurrenceDate_title: "Dar formato a celdas que contienen las siguientes fechas", @@ -11768,6 +11770,7 @@ export default { between2: "", contain: "Contiene", textContains: "Texto contiene", + empty: "Vacío", duplicateValue: "Valor duplicado", uniqueValue: "Valor Unico", top: "Mejor", diff --git a/packages/core/src/locale/hi.ts b/packages/core/src/locale/hi.ts index 5891d7e0..a6140922 100644 --- a/packages/core/src/locale/hi.ts +++ b/packages/core/src/locale/hi.ts @@ -11696,6 +11696,8 @@ export default { conditionformat_textContains: "Conditionformat-TextContains", conditionformat_textContains_title: "निम्नलिखित पाठ वाली कोशिकाओं को प्रारूपित करें", + conditionformat_empty: "Conditional format - Empty", + conditionformat_empty_title: "खाली कोशिकाओं को प्रारूपित करें", conditionformat_occurrenceDate: "Conditionformat-OccurrenceDate", conditionformat_occurrenceDate_title: "निम्नलिखित तिथियों वाली कोशिकाओं को प्रारूपित करें", @@ -11806,6 +11808,7 @@ export default { between2: "", contain: "शामिल", textContains: "पाठ शामिल है", + empty: "खाली", duplicateValue: "डुप्लिकेट मान", uniqueValue: "अद्वितीय मान", top: "शीर्ष", diff --git a/packages/core/src/locale/zh.ts b/packages/core/src/locale/zh.ts index 7c5b1b40..3b7fe7f7 100644 --- a/packages/core/src/locale/zh.ts +++ b/packages/core/src/locale/zh.ts @@ -11723,6 +11723,8 @@ export default { conditionformat_equal_title: "为等于以下值的单元格设置格式", conditionformat_textContains: "条件格式——文本包含", conditionformat_textContains_title: "为包含以下文本的单元格设置格式", + conditionformat_empty: "条件格式——空值", + conditionformat_empty_title: "为空单元格设置格式", conditionformat_occurrenceDate: "条件格式——发生日期", conditionformat_occurrenceDate_title: "为包含以下日期的单元格设置格式", conditionformat_duplicateValue: "条件格式——重复值", @@ -11825,6 +11827,7 @@ export default { between2: "之间", contain: "包含", textContains: "文本包含", + empty: "空值", duplicateValue: "重复值", uniqueValue: "唯一值", top: "前", diff --git a/packages/core/src/locale/zh_tw.ts b/packages/core/src/locale/zh_tw.ts index 2197eb8d..a23bd33b 100644 --- a/packages/core/src/locale/zh_tw.ts +++ b/packages/core/src/locale/zh_tw.ts @@ -11680,6 +11680,8 @@ export default { conditionformat_equal_title: "為等於以下值的儲存格設定格式", conditionformat_textContains: "條件格式——文字包含", conditionformat_textContains_title: "為包含以下文字的儲存格設定格式", + conditionformat_empty: "條件格式——空值", + conditionformat_empty_title: "為空儲存格設定格式", conditionformat_occurrenceDate: "條件格式——發生日期", conditionformat_occurrenceDate_title: "為包含以下日期的儲存格設定格式", conditionformat_duplicateValue: "條件格式——重複值", @@ -11782,6 +11784,7 @@ export default { between2: "之間", contain: "包含", textContains: "文字包含", + empty: "空值", duplicateValue: "重複值", uniqueValue: "唯一值", top: "前", diff --git a/packages/core/src/modules/ConditionFormat.ts b/packages/core/src/modules/ConditionFormat.ts index d45fba03..c51f502b 100644 --- a/packages/core/src/modules/ConditionFormat.ts +++ b/packages/core/src/modules/ConditionFormat.ts @@ -976,6 +976,42 @@ export function compute(ctx: Context, ruleArr: any, d: CellMatrix) { } } } + } else if (conditionName === "empty") { + // Format cells that are empty (no value or blank) + for ( + let r = cellrange[s].row[0]; + r <= cellrange[s].row[1]; + r += 1 + ) { + for ( + let c = cellrange[s].column[0]; + c <= cellrange[s].column[1]; + c += 1 + ) { + const cell = _.isNil(d[r]) || _.isNil(d[r][c]) ? null : d[r][c]; + const isEmpty = + _.isNil(cell) || _.isNil(cell.v) || isRealNull(cell.v); + if (isEmpty) { + if (`${r}_${c}` in computeMap) { + computeMap[`${r}_${c}`].textColor = textColor; + computeMap[`${r}_${c}`].cellColor = cellColor; + computeMap[`${r}_${c}`].bold = bold; + computeMap[`${r}_${c}`].italic = italic; + computeMap[`${r}_${c}`].underline = underline; + computeMap[`${r}_${c}`].strikethrough = strikethrough; + } else { + computeMap[`${r}_${c}`] = { + textColor, + cellColor, + bold, + italic, + underline, + strikethrough, + }; + } + } + } + } } else if (conditionName === "between") { // UPDATED BETWEEN COMPARISON WITH STRING SUPPORT // 循环应用范围计算 diff --git a/packages/core/src/modules/format.ts b/packages/core/src/modules/format.ts index f16269ff..793dfbc6 100644 --- a/packages/core/src/modules/format.ts +++ b/packages/core/src/modules/format.ts @@ -228,20 +228,24 @@ export function genarate(value: string | number | boolean) { ct.t = "d"; const map: Record = { - "yyyy-MM-dd": "dd/MM/yyyy", - "yyyy-MM-dd HH:mm": "dd/MM/yyyy", - "yyyy-MM-ddTHH:mm": "dd/MM/yyyy", - "yyyy/MM/dd": "dd/MM/yyyy", - "yyyy/MM/dd HH:mm": "dd/MM/yyyy", + "yyyy-MM-dd": "yyyy-MM-dd", + "yyyy-MM-dd HH:mm": "yyyy-MM-dd HH:mm", + "yyyy-MM-ddTHH:mm": "yyyy-MM-dd HH:mm", + "yyyy/MM/dd": "yyyy/MM/dd", + "yyyy/MM/dd HH:mm": "yyyy/MM/dd HH:mm", "yyyy.MM.dd": "yyyy.MM.dd", "MM/dd/yyyy h:mm AM/PM": "MM/dd/yyyy h:mm AM/PM", "MM/dd/yyyy": "MM/dd/yyyy", "M/d/yyyy": "M/d/yyyy", "MM/dd/yy": "MM/dd/yy", "dd/MM/yyyy": "dd/MM/yyyy", - "dd-MM-yyyy": "dd/MM/yyyy", + "dd-MM-yyyy": "dd-MM-yyyy", "dd.MM.yyyy": "dd.MM.yyyy", - named: "dd/MM/yyyy", + "named-mdy-full": "mmmm d, yyyy", + "named-mdy-abbr": "mmm d, yyyy", + "named-dmy-full": "d mmmm yyyy", + "named-dmy-abbr": "d mmm yyyy", + "named-abbr-dashes": "mmm-d-yyyy", }; ct.fa = map[df.formatType] || "dd/MM/yyyy"; @@ -265,6 +269,7 @@ export function update(fmt: string, v: any) { } export function is_date(fmt: string, v?: any) { + console.log(SSF.is_date(fmt, v), "is_date"); return SSF.is_date(fmt, v); } diff --git a/packages/core/src/modules/validation.ts b/packages/core/src/modules/validation.ts index eb5269c1..f8796607 100644 --- a/packages/core/src/modules/validation.ts +++ b/packages/core/src/modules/validation.ts @@ -109,6 +109,7 @@ const MONTH_NAME_MAP: Record = { const MONTH_NAMES_RE = "january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|jun|jul|aug|sep|oct|nov|dec"; const MONTH_ABBR_RE = "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec"; +const MONTH_ABBR_SET = new Set(MONTH_ABBR_RE.split("|")); function isValidDateParts(year: number, month: number, day: number): boolean { if (year < 1900) return false; @@ -355,6 +356,7 @@ export function detectDateFormat(str: string): DateFormatInfo | null { const d = +m[2]; const y = +m[3]; if (mo && isValidDateParts(y, mo, d)) { + const isAbbr = MONTH_ABBR_SET.has(m[1].toLowerCase()); return { year: y, month: mo, @@ -362,7 +364,7 @@ export function detectDateFormat(str: string): DateFormatInfo | null { hours: 0, minutes: 0, seconds: 0, - formatType: "named", + formatType: isAbbr ? "named-mdy-abbr" : "named-mdy-full", }; } } @@ -376,6 +378,7 @@ export function detectDateFormat(str: string): DateFormatInfo | null { const mo = MONTH_NAME_MAP[m[2].toLowerCase()]; const y = +m[3]; if (mo && isValidDateParts(y, mo, d)) { + const isAbbr = MONTH_ABBR_SET.has(m[2].toLowerCase()); return { year: y, month: mo, @@ -383,7 +386,7 @@ export function detectDateFormat(str: string): DateFormatInfo | null { hours: 0, minutes: 0, seconds: 0, - formatType: "named", + formatType: isAbbr ? "named-dmy-abbr" : "named-dmy-full", }; } } @@ -402,7 +405,7 @@ export function detectDateFormat(str: string): DateFormatInfo | null { hours: 0, minutes: 0, seconds: 0, - formatType: "named", + formatType: "named-abbr-dashes", }; } } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 06e3354b..7136829b 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -305,6 +305,9 @@ export type GlobalCache = { verticalScrollLock?: boolean; horizontalScrollLock?: boolean; overwriteCell?: boolean; + overwriteCellFirstChar?: string; + /** True when current cell was opened for edit by typing (not double-click). Used so arrow keys commit+move only in that case. */ + enteredEditByTyping?: boolean; ignoreWriteCell?: boolean; doNotFocus?: boolean; doNotUpdateCell?: boolean; diff --git a/packages/react/package.json b/packages/react/package.json index a0a00316..8f73e011 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@fileverse-dev/fortune-react", - "version": "1.3.12", + "version": "1.3.12-mixed", "main": "lib/index.js", "types": "lib/index.d.ts", "module": "es/index.js", @@ -16,7 +16,7 @@ "tsc": "tsc" }, "dependencies": { - "@fileverse-dev/fortune-core": "1.3.12", + "@fileverse-dev/fortune-core": "1.3.12-mixed", "@fileverse/ui": "5.0.0", "@tippyjs/react": "^4.2.6", "@types/regenerator-runtime": "^0.13.6", diff --git a/packages/react/src/components/ConditionFormat/ConditionRules.tsx b/packages/react/src/components/ConditionFormat/ConditionRules.tsx index dde571c7..46f26b63 100644 --- a/packages/react/src/components/ConditionFormat/ConditionRules.tsx +++ b/packages/react/src/components/ConditionFormat/ConditionRules.tsx @@ -317,6 +317,7 @@ const ConditionRules: React.FC<{ context?: any }> = ({ context }) => { { text: "between", value: "[]", label: "Between" }, { text: "equal", value: "=", label: "Equal" }, { text: "textContains", value: "()", label: "Text Contains" }, + { text: "empty", value: "", label: "Empty" }, { text: "occurrenceDate", value: conditionformat.yesterday, @@ -443,8 +444,11 @@ const ConditionRules: React.FC<{ context?: any }> = ({ context }) => { (conditionformat as any)[ allConditionFormats[key].conditionName ] - }{" "} - {allConditionFormats[key].conditionValue?.[0]} + } + {allConditionFormats[key].conditionName !== "empty" && + ` ${ + allConditionFormats[key].conditionValue?.[0] ?? "" + }`}

= ({ context }) => {