From 45b8a9f7fe4c798f100edc21d92b63e681325e0e Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:32 +0000 Subject: [PATCH 01/59] feat(nc-gui): form view v2 setup --- .../nc-gui/components/smartsheet/Form.vue | 1001 +++++++++-------- .../nc-gui/components/tabs/Smartsheet.vue | 2 +- 2 files changed, 561 insertions(+), 442 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 9418a28734..cc62355778 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -1,5 +1,7 @@ + diff --git a/packages/nc-gui/components/tabs/Smartsheet.vue b/packages/nc-gui/components/tabs/Smartsheet.vue index 23fceac8a6..269212f5cc 100644 --- a/packages/nc-gui/components/tabs/Smartsheet.vue +++ b/packages/nc-gui/components/tabs/Smartsheet.vue @@ -171,7 +171,7 @@ watch([activeViewTitleOrId, activeTableId], () => {
-
+
From eb6023e13568e50b5ad295177a8184d17a272ed4 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:33 +0000 Subject: [PATCH 02/59] fix(nc-gui): show and hide fields form view --- .../nc-gui/components/smartsheet/Form.vue | 725 +++++++++--------- packages/nc-gui/composables/useViewColumns.ts | 2 +- 2 files changed, 343 insertions(+), 384 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index cc62355778..2ca13202a5 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -80,7 +80,7 @@ reloadEventHook.on(async () => { setFormData() }) -const { showAll, hideAll, saveOrUpdate } = useViewColumnsOrThrow() +const { fields, showAll, hideAll, saveOrUpdate } = useViewColumnsOrThrow() const { state, row } = useProvideSmartsheetRowStore( meta, @@ -121,6 +121,8 @@ const { t } = useI18n() const { betaFeatureToggleState } = useBetaFeatureToggle() +const visibleColumns = computed(() => localColumns.value.filter((f) => f.show).sort((a, b) => a.order - b.order)) + const updateView = useDebounceFn( () => { updateFormView(formViewData.value) @@ -187,63 +189,56 @@ function onMoveCallback(event: any) { } } -function onMove(event: any) { - const { newIndex, element, oldIndex } = event.added || event.moved || event.removed +function onMove(event: any, isVisibleFormFields = false) { + const { newIndex, element, oldIndex } = event.moved - if (event.added) { - element.show = true - } + const fieldIndex = fields.value?.findIndex((f) => f?.fk_column_id === element.fk_column_id) - if (event.removed) { - if (shouldSkipColumn(element)) { - return - } - element.show = false - saveOrUpdate(element, oldIndex) + if (fieldIndex === -1 || fieldIndex === undefined) return + + const localColumnIndex = localColumns.value?.findIndex((c) => c.fk_column_id === element.fk_column_id) + + if (!localColumns.value.length || localColumns.value.length === 1) { + element.order = 1 + } else if (localColumns.value.length - 1 === newIndex) { + element.order = (localColumns.value[newIndex - 1]?.order || 0) + 1 + } else if (newIndex === 0) { + element.order = (localColumns.value[1]?.order || 0) / 2 } else { - if (!localColumns.value.length || localColumns.value.length === 1) { - element.order = 1 - } else if (localColumns.value.length - 1 === newIndex) { - element.order = (localColumns.value[newIndex - 1]?.order || 0) + 1 - } else if (newIndex === 0) { - element.order = (localColumns.value[1]?.order || 0) / 2 - } else { - element.order = ((localColumns.value[newIndex - 1]?.order || 0) + (localColumns.value[newIndex + 1].order || 0)) / 2 - } - saveOrUpdate(element, newIndex) + element.order = ((localColumns.value[newIndex - 1]?.order || 0) + (localColumns.value[newIndex + 1].order || 0)) / 2 } + saveOrUpdate(element, fieldIndex) + $e('a:form-view:reorder') } -function hideColumn(idx: number) { - if (shouldSkipColumn(localColumns.value[idx])) { +function showOrHideColumn(column: Record, show: boolean) { + if (shouldSkipColumn(column)) { // Required field can't be moved message.info(t('msg.info.requriedFieldsCantBeMoved')) return } - saveOrUpdate( - { - ...localColumns.value[idx], - show: false, - }, - idx, - ) + const fieldIndex = fields.value?.findIndex((f) => f?.fk_column_id === column.fk_column_id) - reloadEventHook.trigger() + if (fieldIndex !== -1 && fieldIndex !== undefined) { + saveOrUpdate( + { + ...column, + show: show, + }, + fieldIndex, + ) - $e('a:form-view:hide-columns') -} + reloadEventHook.trigger() -async function addAllColumns() { - for (const col of (localColumns as Record)?.value) { - if (!systemFieldsIds.value.includes(col.fk_column_id)) { - col.show = true + if (show) { + $e('a:form-view:show-columns') + } else { + $e('a:form-view:hide-columns') } } - await showAll(systemFieldsIds.value) - $e('a:form-view:add-all') } function shouldSkipColumn(col: Record) { @@ -252,16 +247,24 @@ function shouldSkipColumn(col: Record) { ) } -async function removeAllColumns() { - for (const col of (localColumns as Record)?.value) { - if (!shouldSkipColumn(col)) col.show = false +async function handleAddOrRemoveAllColumns(value: boolean) { + if (value) { + for (const col of (localColumns as Record)?.value) { + col.show = true + } + await showAll(systemFieldsIds.value) + $e('a:form-view:add-all') + } else { + for (const col of (localColumns as Record)?.value) { + if (!shouldSkipColumn(col)) col.show = false + } + await hideAll( + (localColumns as Record)?.value + .filter((col: Record) => shouldSkipColumn(col)) + .map((col: Record) => col.fk_column_id), + ) + $e('a:form-view:remove-all') } - await hideAll( - (localColumns as Record)?.value - .filter((col: Record) => shouldSkipColumn(col)) - .map((col: Record) => col.fk_column_id), - ) - $e('a:form-view:remove-all') } async function checkSMTPStatus() { @@ -279,6 +282,7 @@ async function checkSMTPStatus() { function setFormData() { const col = formColumnData?.value || [] + systemFieldsIds.value = getSystemColumns(col).map((c) => c.fk_column_id) formViewData.value = { ...formViewData.value, @@ -295,14 +299,12 @@ function setFormData() { emailMe.value = data[user.value?.email as string] localColumns.value = col - .filter((f) => f.show && !hiddenColTypes.includes(f.uidt)) + .filter((f) => !hiddenColTypes.includes(f.uidt) && !systemFieldsIds.value.includes(f.fk_column_id)) .sort((a, b) => a.order - b.order) .map((c) => ({ ...c, required: !!c.required })) editEnabled.value = new Array(localColumns.value.length).fill(false) - systemFieldsIds.value = getSystemColumns(col).map((c) => c.fk_column_id) - hiddenColumns.value = col.filter( (f) => !f.show && !systemFieldsIds.value.includes(f.fk_column_id) && !hiddenColTypes.includes(f.uidt), ) @@ -371,10 +373,6 @@ function handleMouseUp(col: Record, hiddenColIndex: number) { col.order = (index ? localColumns.value[index - 1].order : 0) + 1 col.show = true - /** remove column from hiddenColumns and add to localColumns */ - localColumns.value.push(col) - hiddenColumns.value.splice(hiddenColIndex, 1) - saveOrUpdate(col, index) } } @@ -445,301 +443,329 @@ const onFormItemClick = (element: any) => { - +
- - -
- - - + +
+ +
+
+ +
-
+ + + + + + +
{{ formViewData.heading }}
- -
- - - -
+ + + +
{{ formViewData.subheading || '---' }}
+
- - -
- +
- {{ $t('general.submit') }} - -
- + Select fields from right panel to add here +
+ +
+ +
+ + Crear Form + + + {{ $t('general.submit') }} + +
- + + + +
+ + NocoDB +
NocoDB Forms
+
- +
Form Fields
- 22/26 Field + + {{ visibleColumns.length }}/{{ localColumns.length }} Field +
{ :trigger="['click']" overlay-class-name="nc-dropdown-form-add-column" > + { @click.stop="showColumnDropdown = true" >
- + Add Field
@@ -771,29 +797,6 @@ const onFormItemClick = (element: any) => { />
-
{
-
-
+
+
{{ $t('title.noFieldsFound') }}
- { :key="field.id" class="p-2 flex flex-row items-center border-b-1 last:border-none first:rounded-t-lg border-gray-200" :data-testid="`nc-form-field-item-${field.title}`" - @click.stop >
@@ -857,36 +851,47 @@ const onFormItemClick = (element: any) => { {{ field.title }} +  *
- +
+
@@ -957,60 +962,8 @@ const onFormItemClick = (element: any) => {
- -
+ +
@@ -1086,4 +1039,10 @@ const onFormItemClick = (element: any) => { } .nc-form-fields-list { } +.nc-form-scrollbar { + @apply scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent; + &::-webkit-scrollbar-thumb:hover { + @apply !scrollbar-thumb-gray-300; + } +} diff --git a/packages/nc-gui/composables/useViewColumns.ts b/packages/nc-gui/composables/useViewColumns.ts index 7771e4e6cd..f5877c7597 100644 --- a/packages/nc-gui/composables/useViewColumns.ts +++ b/packages/nc-gui/composables/useViewColumns.ts @@ -54,7 +54,6 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState( const loadViewColumns = async () => { if (!meta || !view) return - let order = 1 if (view.value?.id) { @@ -113,6 +112,7 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState( } const showAll = async (ignoreIds?: any) => { + console.log('show all', fields.value) if (isLocalMode.value) { fields.value = fields.value?.map((field: Field) => ({ ...field, From 011459fcecc0a59c68de5251a349f5844d63c41b Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:33 +0000 Subject: [PATCH 03/59] fix(nc-gui): color picker more colors icon alignment --- packages/nc-gui/components/general/ColorPicker.vue | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/nc-gui/components/general/ColorPicker.vue b/packages/nc-gui/components/general/ColorPicker.vue index 50c4d44a59..1cfc5d49af 100644 --- a/packages/nc-gui/components/general/ColorPicker.vue +++ b/packages/nc-gui/components/general/ColorPicker.vue @@ -58,13 +58,12 @@ watch(picked, (n, _o) => { > {{ compare(picked, color) ? '✓' : '' }} -
From a0031925c7f75767505946d0e6c2b6c133f2ca50 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:34 +0000 Subject: [PATCH 04/59] feat(nc-gui): form theme color --- .../nc-gui/components/smartsheet/Form.vue | 304 +++++++++++------- 1 file changed, 180 insertions(+), 124 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 2ca13202a5..4c000bafd4 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -28,6 +28,7 @@ import { useViewColumnsOrThrow, useViewData, watch, + parseProp, } from '#imports' provide(IsFormInj, ref(true)) @@ -57,6 +58,8 @@ const { $api, $e } = useNuxtApp() const { isUIAllowed } = useRoles() +const { appInfo } = useGlobal() + const formState = reactive({}) const secondsRemain = ref(0) @@ -213,10 +216,10 @@ function onMove(event: any, isVisibleFormFields = false) { $e('a:form-view:reorder') } -function showOrHideColumn(column: Record, show: boolean) { +function showOrHideColumn(column: Record, show: boolean, isSidePannel = false) { if (shouldSkipColumn(column)) { // Required field can't be moved - message.info(t('msg.info.requriedFieldsCantBeMoved')) + !isSidePannel && message.info(t('msg.info.requriedFieldsCantBeMoved')) return } @@ -226,7 +229,7 @@ function showOrHideColumn(column: Record, show: boolean) { saveOrUpdate( { ...column, - show: show, + show, }, fieldIndex, ) @@ -288,6 +291,11 @@ function setFormData() { ...formViewData.value, submit_another_form: !!(formViewData.value?.submit_another_form ?? 0), show_blank_form: !!(formViewData.value?.show_blank_form ?? 0), + meta: { + hide_branding: false, + theme_color: '#F9F9FA', + ...(parseProp(formViewData.value?.meta) ?? {}), + }, } // email me @@ -443,9 +451,21 @@ const onFormItemClick = (element: any) => {
- +
+
{
- - - -
- - NocoDB -
NocoDB Forms
-
+ - +
@@ -803,7 +824,7 @@ const onFormItemClick = (element: any) => { v-model:value="searchQuery" data-testid="nc-form-field-search-input" class="!h-9 !px-3 !py-1 !rounded-lg" - :placeholder="$t('placeholder.searchFields') + '...'" + :placeholder="`${$t('placeholder.searchFields')}...`" >
@@ -1042,15 +1065,18 @@ const onFormItemClick = (element: any) => { } } -.form-meta-input::placeholder { - @apply text-[#3d3d3d] italic; +.form-meta-input { + @apply !rounded-lg !text-sm; + &::placeholder { + @apply !text-gray-500; + } } -.nc-form-input-label, +.nc-form-input-label { + @apply !px-4 !py-2; +} .nc-form-input-help-text { - &::placeholder { - @apply !text-gray-500 !text-xs; - } + @apply !px-3 !py-1; } .nc-form-help-text, @@ -1101,4 +1127,8 @@ const onFormItemClick = (element: any) => { :deep(.nc-form-theme-color-picker .color-selector) { @apply !text-white; } + +:deep(.nc-form-field-body .nc-cell) { + @apply my-0; +} From 4eb7128fe71164c1abea7f1e112d21a5e2b91cd2 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:34 +0000 Subject: [PATCH 06/59] style(nc-gui): fix typo in `transition-colors` css class --- packages/nc-gui/assets/style.scss | 2 +- packages/nc-gui/pages/index/[typeOrId]/[baseId]/index.vue | 2 +- packages/nc-gui/pages/projects/index/list.vue | 2 +- packages/nc-gui/windi.config.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nc-gui/assets/style.scss b/packages/nc-gui/assets/style.scss index c4c43b762b..f3330b1469 100644 --- a/packages/nc-gui/assets/style.scss +++ b/packages/nc-gui/assets/style.scss @@ -613,7 +613,7 @@ a { } .nc-click-transition { - @apply transform transition-transform transition-color !text-gray-400 !hover:(scale-130 !text-gray-500) !active:(scale-100 !text-gray-500); + @apply transform transition-transform transition-colors !text-gray-400 !hover:(scale-130 !text-gray-500) !active:(scale-100 !text-gray-500); } .nc-click-transition-1 { diff --git a/packages/nc-gui/pages/index/[typeOrId]/[baseId]/index.vue b/packages/nc-gui/pages/index/[typeOrId]/[baseId]/index.vue index 49249e5c00..ed2a6014e5 100644 --- a/packages/nc-gui/pages/index/[typeOrId]/[baseId]/index.vue +++ b/packages/nc-gui/pages/index/[typeOrId]/[baseId]/index.vue @@ -133,7 +133,7 @@ useEventListener(document, 'keydown', async (e: KeyboardEvent) => { .nc-left-sidebar { .nc-sidebar-left-toggle-icon { - @apply opacity-0 transition-opactity duration-200 transition-color text-gray-500/80 hover:text-gray-500/100; + @apply opacity-0 transition-opacity duration-200 transition-colors text-gray-500/80 hover:text-gray-500/100; .nc-left-sidebar { @apply !border-r-0; diff --git a/packages/nc-gui/pages/projects/index/list.vue b/packages/nc-gui/pages/projects/index/list.vue index 07e5fe436e..ab612d96fa 100644 --- a/packages/nc-gui/pages/projects/index/list.vue +++ b/packages/nc-gui/pages/projects/index/list.vue @@ -30,7 +30,7 @@ const openProject = async (base: BaseType) => { @@ -1129,7 +1136,7 @@ const onFormItemClick = (element: any) => { .nc-form-fields-list { } .nc-form-scrollbar { - @apply scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent; + @apply scrollbar scrollbar-thin scrollbar-thumb-gray-200 scrollbar-track-transparent; &::-webkit-scrollbar-thumb:hover { @apply !scrollbar-thumb-gray-300; } From 005bd04154e4db4fbb3b94e7e02f1612fd5a2651 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:35 +0000 Subject: [PATCH 09/59] fix(nc-gui): clear form & default banner image --- .../nc-gui/assets/img/form-banner-left.png | Bin 0 -> 10656 bytes .../nc-gui/assets/img/form-banner-right.png | Bin 0 -> 10309 bytes .../nc-gui/components/smartsheet/Form.vue | 43 +++++++++++++----- 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 packages/nc-gui/assets/img/form-banner-left.png create mode 100644 packages/nc-gui/assets/img/form-banner-right.png diff --git a/packages/nc-gui/assets/img/form-banner-left.png b/packages/nc-gui/assets/img/form-banner-left.png new file mode 100644 index 0000000000000000000000000000000000000000..793bd374fb430a62705ed2fb97ee0d2414fd90bc GIT binary patch literal 10656 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 literal 0 HcmV?d00001 diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 48b2450d97..0007db1201 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -60,7 +60,7 @@ const { isUIAllowed } = useRoles() const { appInfo } = useGlobal() -const formState = reactive({}) +let formState = reactive({}) const secondsRemain = ref(0) @@ -151,6 +151,12 @@ async function submitForm() { submitted.value = true } +async function clearForm() { + formState = {} + state.value = {} + reloadEventHook.trigger() +} + function isDbRequired(column: Record) { if (hiddenCols.includes(column.fk_column_id)) { return false @@ -413,7 +419,7 @@ watch(view, (nextView) => { }) const onFormItemClick = (element: any) => { - if (isLocked.value) return + if (isLocked.value || !isEditable) return activeRow.value = element.title } @@ -465,18 +471,26 @@ const onFormItemClick = (element: any) => { :style="{background:(formViewData?.meta as Record).theme_color}" >
-
+
+ +
+ form-banner-left' + +
+ form-banner-logo' +
+ + form-banner-left' +
{ ghost-class="nc-form-field-ghost" class="h-full px-4 lg:px-6" :move="onMoveCallback" - :disabled="isLocked" + :disabled="isLocked || !isEditable" @change="onMove($event, true)" @start="drag = true" @end="drag = false" > diff --git a/packages/nc-gui/components/general/FormBranding.vue b/packages/nc-gui/components/general/FormBranding.vue new file mode 100644 index 0000000000..2bb11c0f11 --- /dev/null +++ b/packages/nc-gui/components/general/FormBranding.vue @@ -0,0 +1,13 @@ + + + diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 5bbf5507ce..4eb8b9abd9 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -15,6 +15,7 @@ import { extractSdkResponseErrorMsg, iconMap, inject, + isEeUI, message, onClickOutside, parseProp, @@ -58,8 +59,6 @@ const { $api, $e } = useNuxtApp() const { isUIAllowed } = useRoles() -const { appInfo } = useGlobal() - let formState = reactive({}) const secondsRemain = ref(0) @@ -387,18 +386,6 @@ watch(submitted, (v) => { } }) -function handleMouseUp(col: Record, hiddenColIndex: number) { - if (isLocked.value) return - - if (!moved.value) { - const index = localColumns.value.length - col.order = (index ? localColumns.value[index - 1].order : 0) + 1 - col.show = true - - saveOrUpdate(col, index) - } -} - const columnSupportsScanning = (elementType: UITypes) => betaFeatureToggleState.show && [UITypes.SingleLineText, UITypes.Number, UITypes.Email, UITypes.URL, UITypes.LongText].includes(elementType) @@ -471,30 +458,12 @@ const onFormItemClick = (element: any) => { :style="{background:(formViewData?.meta as Record).theme_color}" >
-
- - - -
- form-banner-left' - -
- form-banner-logo' -
- - form-banner-left' -
-
+ + + -
- - NocoDB -
NocoDB Forms
+
+
@@ -992,13 +959,20 @@ const onFormItemClick = (element: any) => {
+ Hide NocoDB Branding
From 4b251bd91f68706bd0b16c38d4b102bcafc034c4 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:16:37 +0000 Subject: [PATCH 12/59] chore(nc-gui): lint --- packages/nc-gui/components/smartsheet/Form.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 4eb8b9abd9..e5c99e838a 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -105,8 +105,6 @@ const systemFieldsIds = ref[]>([]) const showColumnDropdown = ref(false) -const moved = ref(false) - const drag = ref(false) const emailMe = ref(false) @@ -199,7 +197,8 @@ function onMoveCallback(event: any) { // Todo: reorder visible form fields function onMove(event: any, isVisibleFormFields = false) { - let { newIndex, element, oldIndex } = event.moved + const { oldIndex } = event.moved + let { newIndex, element } = event.moved const fieldIndex = fields.value?.findIndex((f) => f?.fk_column_id === element.fk_column_id) @@ -740,6 +739,7 @@ const onFormItemClick = (element: any) => {
+
Date: Thu, 22 Feb 2024 16:16:38 +0000 Subject: [PATCH 13/59] fix(nc-gui): updated color picker --- .../nc-gui/components/general/ColorPicker.vue | 24 +++++++++++++---- .../nc-gui/components/smartsheet/Form.vue | 26 +++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/nc-gui/components/general/ColorPicker.vue b/packages/nc-gui/components/general/ColorPicker.vue index 3ff39967a4..04013f0323 100644 --- a/packages/nc-gui/components/general/ColorPicker.vue +++ b/packages/nc-gui/components/general/ColorPicker.vue @@ -7,6 +7,8 @@ interface Props { rowSize?: number advanced?: boolean pickButton?: boolean + borders?: string[] + isNewDesign?: boolean } const props = withDefaults(defineProps(), { @@ -15,6 +17,7 @@ const props = withDefaults(defineProps(), { rowSize: 10, advanced: true, pickButton: false, + isNewDesign: false, }) const emit = defineEmits(['input', 'closeModal']) @@ -52,11 +55,14 @@ watch(picked, (n, _o) => { v-for="(color, i) of colors.slice((colId - 1) * rowSize, colId * rowSize)" :key="`color-${colId}-${i}`" class="color-selector" - :class="compare(picked, color) ? 'selected' : ''" - :style="{ 'background-color': `${color}` }" + :class="{ 'selected': compare(picked, color), 'new-design': isNewDesign }" + :style="{ + 'background-color': `${color}`, + 'border': borders?.length && borders[i] ? `1px solid ${borders[i]}` : undefined, + }" @click="selectColor(color, true)" > - {{ compare(picked, color) ? '✓' : '' }} + {{ compare(picked, color) && !isNewDesign ? '✓' : '' }}