diff --git a/packages/nc-gui-v2/components/cell/Percent.vue b/packages/nc-gui-v2/components/cell/Percent.vue
new file mode 100644
index 0000000000..dde455185c
--- /dev/null
+++ b/packages/nc-gui-v2/components/cell/Percent.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
diff --git a/packages/nc-gui-v2/components/smartsheet-header/CellIcon.vue b/packages/nc-gui-v2/components/smartsheet-header/CellIcon.vue
index 76fd47e4b9..b5c69c0508 100644
--- a/packages/nc-gui-v2/components/smartsheet-header/CellIcon.vue
+++ b/packages/nc-gui-v2/components/smartsheet-header/CellIcon.vue
@@ -18,6 +18,7 @@ import AttachmentIcon from '~icons/mdi/image-multiple-outline'
import URLIcon from '~icons/mdi/link'
import EmailIcon from '~icons/mdi/email'
import CurrencyIcon from '~icons/mdi/currency-usd-circle-outline'
+import PercentIcon from '~icons/mdi/percent-outline'
const { columnMeta } = defineProps<{ columnMeta?: ColumnType }>()
@@ -56,6 +57,8 @@ const icon = computed(() => {
return URLIcon
} else if (additionalColMeta.isCurrency) {
return CurrencyIcon
+ } else if (additionalColMeta.isPercent) {
+ return PercentIcon
} else if (additionalColMeta.isString) {
return StringIcon
} else {
diff --git a/packages/nc-gui-v2/components/smartsheet/Cell.vue b/packages/nc-gui-v2/components/smartsheet/Cell.vue
index 0ede86205d..781209c7b6 100644
--- a/packages/nc-gui-v2/components/smartsheet/Cell.vue
+++ b/packages/nc-gui-v2/components/smartsheet/Cell.vue
@@ -43,6 +43,7 @@ const {
isString,
isSingleSelect,
isMultiSelect,
+ isPercent,
} = useColumn(column)
@@ -202,6 +203,7 @@ todo :
+
diff --git a/packages/nc-gui-v2/composables/useColumn.ts b/packages/nc-gui-v2/composables/useColumn.ts
index e46397fd87..f71afb6015 100644
--- a/packages/nc-gui-v2/composables/useColumn.ts
+++ b/packages/nc-gui-v2/composables/useColumn.ts
@@ -31,6 +31,7 @@ export function useColumn(column: ColumnType) {
const isRating = uiDatatype === UITypes.Rating
const isCurrency = uiDatatype === 'Currency'
const isDuration = uiDatatype === UITypes.Duration
+ const isPercent = uiDatatype === UITypes.Percent
const isAutoSaved = [
UITypes.SingleLineText,
UITypes.LongText,
@@ -72,5 +73,6 @@ export function useColumn(column: ColumnType) {
isManualSaved,
isSingleSelect,
isMultiSelect,
+ isPercent,
}
}
diff --git a/packages/nc-gui-v2/utils/percentUtils.ts b/packages/nc-gui-v2/utils/percentUtils.ts
new file mode 100644
index 0000000000..de32276d6b
--- /dev/null
+++ b/packages/nc-gui-v2/utils/percentUtils.ts
@@ -0,0 +1,30 @@
+export const precisions = [
+ { id: 0, title: '1' },
+ { id: 1, title: '1.0' },
+ { id: 2, title: '1.00' },
+ { id: 3, title: '1.000' },
+ { id: 4, title: '1.0000' },
+ { id: 5, title: '1.00000' },
+ { id: 6, title: '1.000000' },
+ { id: 7, title: '1.0000000' },
+ { id: 8, title: '1.00000000' },
+]
+
+export function renderPercent(value: any, precision: number, withPercentSymbol = true) {
+ if (!value) return value
+ value = (Number(value) * 100).toFixed(precision)
+ if (withPercentSymbol) return padPercentSymbol(value)
+ return value
+}
+
+export function isValidPercent(value: any, negative: boolean): boolean {
+ return negative ? /^-?\d{1,20}(\.\d+)?$/.test(value) : /^\d{1,20}(\.\d+)?$/.test(value)
+}
+
+export function getPercentStep(precision: number): string {
+ return (1 / 10 ** precision).toString()
+}
+
+function padPercentSymbol(value: any) {
+ return value ? `${value}%` : value
+}