From 9f2666cf9af5a53a19c47f4f221f436135610a7c Mon Sep 17 00:00:00 2001 From: Dhruv Parmar <83108871+dhruvjsx@users.noreply.github.com> Date: Tue, 1 Jul 2025 10:15:35 +0530 Subject: [PATCH] Fix(ui): primary color customization (#21777) * replaced blue color with primary color * fixed follow button styling for customized primary color * preseved previous color for default color scheme * fixed sidebar colors * testing changes * fixed minor changes * completed with map approach * removed package-lock file * fixed yarn lock file * fixed yarn --- .../src/main/resources/ui/package.json | 2 + .../ui/src/assets/svg/ic-star-filled.svg | 2 +- .../ActivityFeedTab/activity-feed-tab.less | 12 +-- .../TaskFeedCard/task-feed-card.less | 4 +- .../components/BlockEditor/block-editor.less | 2 +- .../entity-header-title.less | 4 + .../Entity/Task/TaskTab/task-tab-new.less | 10 +-- .../explore-search-card.less | 4 +- .../CarouselLayout/carousel-layout.less | 2 +- .../MyData/LeftSidebar/left-sidebar.less | 9 +- .../ProfileCard/profile-details.less | 7 +- .../rich-text-editor-previewer.less | 2 +- .../AntDConfigProvider/AntDConfigProvider.tsx | 35 +++++++- .../customize-details-page.less | 2 +- .../settings-navigation-page.less | 2 +- .../resources/ui/src/styles/colorPallet.ts | 89 +++++++++++++++++++ .../resources/ui/src/styles/variables.less | 33 ++++--- .../src/main/resources/ui/yarn.lock | 10 +++ 18 files changed, 189 insertions(+), 42 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/src/styles/colorPallet.ts diff --git a/openmetadata-ui/src/main/resources/ui/package.json b/openmetadata-ui/src/main/resources/ui/package.json index 0773458293c..3f3ad782239 100644 --- a/openmetadata-ui/src/main/resources/ui/package.json +++ b/openmetadata-ui/src/main/resources/ui/package.json @@ -73,6 +73,7 @@ "@tiptap/starter-kit": "^2.3.0", "@tiptap/suggestion": "^2.3.0", "@toast-ui/react-editor": "^3.1.8", + "@types/tinycolor2": "^1.4.6", "@windmillcode/quill-emoji": "^2.0.1000", "analytics": "^0.8.1", "antd": "4.24.16", @@ -126,6 +127,7 @@ "showdown": "^2.1.0", "socket.io-client": "^4.5.1", "styled-components": "^6.1.8", + "tinycolor2": "^1.6.0", "turndown": "^7.1.2", "use-analytics": "1.1.0", "zustand": "^4.5.0" diff --git a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-star-filled.svg b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-star-filled.svg index 9f95c58585d..08ae2538c89 100644 --- a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-star-filled.svg +++ b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-star-filled.svg @@ -1,6 +1,6 @@ - + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/activity-feed-tab.less b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/activity-feed-tab.less index 42d2a509965..7412ec0a430 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/activity-feed-tab.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/activity-feed-tab.less @@ -139,8 +139,8 @@ } .activity-feed-card-new.is-active { - background: #eff8ff; - border: 1px solid #84caff; + background: @primary-50; + border: 1px solid @primary-3; } .activity-feed-card-message { @@ -333,7 +333,7 @@ line-height: 20px; &.selected { - color: #2e90fa; + color: @primary-5; } } @@ -352,7 +352,7 @@ align-items: center; &.active { - background-color: #2e90fa !important; + background-color: @primary-5 !important; } .task-count-text { @@ -375,10 +375,10 @@ .active { box-shadow: 0px 1px 2px 0px rgba(10, 13, 18, 0.05); - background-color: #f5faff; + background-color: @primary-25; svg path { - fill: #2e90fa; + fill: @primary-5; } } } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/TaskFeedCard/task-feed-card.less b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/TaskFeedCard/task-feed-card.less index 1c52d78ec64..f49fde1416e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/TaskFeedCard/task-feed-card.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/TaskFeedCard/task-feed-card.less @@ -44,8 +44,8 @@ border: 0.5px solid #eaecf5; &.active { - border-left: 4px solid #1570ef; - background: #eff8ff; + border-left: 4px solid @primary-color; + background: @primary-50; } .task-created-by-text { color: @primary-heading-color; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/BlockEditor/block-editor.less b/openmetadata-ui/src/main/resources/ui/src/components/BlockEditor/block-editor.less index a8fe510a8fc..976b0f5839b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/BlockEditor/block-editor.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/BlockEditor/block-editor.less @@ -18,7 +18,7 @@ @hover-bg: #00000005; @callout-bg: #f8f8fa; @callout-warning-bg: #fff3dc; -@callout-info-bg: #d1e9ff; +@callout-info-bg: @primary-1; @callout-danger-bg: #ff4c3b33; @callout-border: #afafc1; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/entity-header-title.less b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/entity-header-title.less index 7203dffda8c..64a25e0d7bd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/entity-header-title.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/entity-header-title.less @@ -42,6 +42,10 @@ align-items: center; justify-content: center; } + svg { + // to make follow button icon color same as primary color + color: @primary-color; + } span.ant-typography { margin-left: 0px; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/Task/TaskTab/task-tab-new.less b/openmetadata-ui/src/main/resources/ui/src/components/Entity/Task/TaskTab/task-tab-new.less index c0f42db9f3b..3953abaa261 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/Task/TaskTab/task-tab-new.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/Task/TaskTab/task-tab-new.less @@ -33,7 +33,7 @@ line-height: 20px; } &:hover { - color: #1570ef !important; + color: @primary-color !important; } svg { @@ -72,13 +72,13 @@ cursor: pointer; border-bottom: none; &:hover { - background: #f5faff; - color: #1570ef !important; + background: @primary-25; + color: @primary-color !important; } &.ant-dropdown-menu-item-selected { - background: #f5faff; - color: #1570ef !important; + background: @primary-25; + color: @primary-color !important; } &:last-child { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less b/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less index 4294f51e466..a9c7ff7b205 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less @@ -27,8 +27,8 @@ font-weight: @font-regular; } &.highlight-card { - border-left: 4px solid #1570ef; - background: #eff8ff !important; + border-left: 4px solid @primary-color; + background: @primary-50 !important; } &:last-child { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Layout/CarouselLayout/carousel-layout.less b/openmetadata-ui/src/main/resources/ui/src/components/Layout/CarouselLayout/carousel-layout.less index 32b17edec03..13ddd4622d0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Layout/CarouselLayout/carousel-layout.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/Layout/CarouselLayout/carousel-layout.less @@ -19,7 +19,7 @@ padding: @size-lg; position: relative; overflow: hidden; - background: linear-gradient(45deg, #194185 0%, #2e90fa 100%); + background: linear-gradient(45deg, @primary-9 0%, @primary-5 100%); border-radius: @size-mlg; display: flex; flex-direction: column; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less index 49fc794dd4f..13ade2c5d07 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less @@ -11,10 +11,9 @@ * limitations under the License. */ @import (reference) url('../../../styles/variables.less'); - -@selected-color: #1570ef; -@hover-color: #d1e9ff; -@active-color: #175cd3; +@selected-color: @primary-color; +@hover-color: @primary-1; +@active-color: @primary-7; @left-sidebar-icon-size: 28px; .logo-container { @@ -196,7 +195,7 @@ .ant-menu-submenu.ant-menu-submenu-open { border-width: 0px 1px 1px 1px; border-style: solid; - border-color: #53b1fd; + border-color: @primary-4; color: @white; border-radius: 12px; overflow: hidden; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfileCard/profile-details.less b/openmetadata-ui/src/main/resources/ui/src/components/ProfileCard/profile-details.less index 4c0f5165a18..8757fd6c625 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfileCard/profile-details.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfileCard/profile-details.less @@ -10,6 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@import (reference) url('../../styles/variables.less'); .profile-management-popover .ant-popover-inner-content::before, .profile-management-popover .ant-popover-arrow { display: none !important; @@ -46,13 +47,13 @@ } &:hover { - background-color: #f5faff; + background-color: @primary-25; svg path { - fill: #1570ef; + fill: @primary-color; } } &:hover .ant-typography { - color: #1570ef; + color: @primary-color; } } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/RichTextEditor/rich-text-editor-previewer.less b/openmetadata-ui/src/main/resources/ui/src/components/common/RichTextEditor/rich-text-editor-previewer.less index f9e9c8a3511..0ea313eb247 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/RichTextEditor/rich-text-editor-previewer.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/RichTextEditor/rich-text-editor-previewer.less @@ -215,7 +215,7 @@ } .admonition_tip, .admonition_info { - background-color: #d1e9ff; + background-color: @primary-1; border-left-color: @info-color; } .admonition_tip { diff --git a/openmetadata-ui/src/main/resources/ui/src/context/AntDConfigProvider/AntDConfigProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/context/AntDConfigProvider/AntDConfigProvider.tsx index 01dbc0160f5..c0d9087dde4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/context/AntDConfigProvider/AntDConfigProvider.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/context/AntDConfigProvider/AntDConfigProvider.tsx @@ -11,14 +11,47 @@ * limitations under the License. */ import { ConfigProvider } from 'antd'; -import { FC, ReactNode } from 'react'; +import { FC, ReactNode, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; +import { DEFAULT_THEME } from '../../constants/Appearance.constants'; import { useApplicationStore } from '../../hooks/useApplicationStore'; +import { generatePalette } from '../../styles/colorPallet'; const AntDConfigProvider: FC<{ children: ReactNode }> = ({ children }) => { const { i18n } = useTranslation(); const { applicationConfig } = useApplicationStore(); + useEffect(() => { + const palette = generatePalette( + applicationConfig?.customTheme?.primaryColor ?? DEFAULT_THEME.primaryColor + ); + palette.forEach((color, index) => { + switch (index) { + case 0: + document.documentElement.style.setProperty(`--ant-primary-25`, color); + + break; + case 1: + document.documentElement.style.setProperty(`--ant-primary-50`, color); + + break; + default: + document.documentElement.style.setProperty( + `--ant-primary-${index - 1}`, + color + ); + } + }); + document.documentElement.style.setProperty( + `--ant-primary-color-hover`, + palette[6] + ); + document.documentElement.style.setProperty( + `--ant-primary-color-active`, + palette[8] + ); + }, [applicationConfig?.customTheme?.primaryColor]); + ConfigProvider.config({ theme: { ...applicationConfig?.customTheme, diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/CustomizeDetailsPage/customize-details-page.less b/openmetadata-ui/src/main/resources/ui/src/pages/CustomizeDetailsPage/customize-details-page.less index b2483ff5f3a..f8fb950ec7a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/CustomizeDetailsPage/customize-details-page.less +++ b/openmetadata-ui/src/main/resources/ui/src/pages/CustomizeDetailsPage/customize-details-page.less @@ -26,6 +26,6 @@ } .customize-page-header { - border: 0.5px solid #84caff; + border: 0.5px solid @primary-3; } } diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/SettingsNavigationPage/settings-navigation-page.less b/openmetadata-ui/src/main/resources/ui/src/pages/SettingsNavigationPage/settings-navigation-page.less index e6b1064c50e..687f54eb377 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/SettingsNavigationPage/settings-navigation-page.less +++ b/openmetadata-ui/src/main/resources/ui/src/pages/SettingsNavigationPage/settings-navigation-page.less @@ -34,7 +34,7 @@ } &:hover { - background: #f5faff; + background: @primary-25; } } .ant-tree-node-content-wrapper.ant-tree-node-selected { diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/colorPallet.ts b/openmetadata-ui/src/main/resources/ui/src/styles/colorPallet.ts new file mode 100644 index 00000000000..7e9f8c1532f --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/styles/colorPallet.ts @@ -0,0 +1,89 @@ +/* + * Copyright 2025 Collate. + * 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. + */ +import tinycolor, { ColorFormats } from 'tinycolor2'; + +const clamp = (val: number, min: number, max: number) => + Math.max(min, Math.min(max, val)); + +const deltas = [ + { + h: -4.954128440366901, + s: 0.128, + l: 0.47058823529411775, + }, + { + h: -8.704128440366986, + s: 0.128, + l: 0.45882352941176474, + }, + { + h: -6.2584762664539255, + s: 0.128, + l: 0.4, + }, + { + h: -8.460621946860499, + s: 0.128, + l: 0.3392156862745098, + }, + { + h: -9.10046990378163, + s: 0.128, + l: 0.24901960784313726, + }, + { + h: -8.130599028602262, + s: 0.1050114942528736, + l: 0.14901960784313728, + }, + { + h: -3.777657852131682, + s: 0.08127102803738318, + l: 0.07058823529411762, + }, + { + h: 0, + s: 0, + l: 0, + }, + { + h: 3.024594963888319, + s: -0.06858119658119666, + l: -0.05098039215686273, + }, + { + h: 4.770009490667491, + s: -0.12070466321243523, + l: -0.13137254901960782, + }, + { + h: 2.823649337410785, + s: -0.18845569620253155, + l: -0.19999999999999996, + }, +]; +const applyDelta = (base: ColorFormats.HSL, delta: ColorFormats.HSL) => ({ + h: base.h + delta.h, + s: clamp(base.s + delta.s, 0, 1), + l: clamp(base.l + delta.l, 0, 1), +}); + +export const generatePalette = (newPrimaryHex: string) => { + const baseHSL = tinycolor(newPrimaryHex).toHsl(); + + return deltas.map((delta) => { + const newColor = applyDelta(baseHSL, delta); + + return tinycolor(newColor).toHexString(); + }); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/variables.less b/openmetadata-ui/src/main/resources/ui/src/styles/variables.less index 10095a3e9f3..de27b8f75c1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/styles/variables.less +++ b/openmetadata-ui/src/main/resources/ui/src/styles/variables.less @@ -19,10 +19,19 @@ @error-color: ~'var(--ant-error-color)'; @info-color: ~'var(--ant-info-color)'; @link-color: ~'var(--ant-primary-color)'; -@primary-1: ~'var(--ant-primary-1)'; @radio-button-checked-bg: ~'var(--ant-primary-1)'; @highlight-color: #f41111; - +@primary-25: ~'var(--ant-primary-25)'; +@primary-50: ~'var(--ant-primary-50)'; +@primary-1: ~'var(--ant-primary-1)'; +@primary-2: ~'var(--ant-primary-2)'; +@primary-3: ~'var(--ant-primary-3)'; +@primary-4: ~'var(--ant-primary-4)'; +@primary-5: ~'var(--ant-primary-5)'; +@primary-6: ~'var(--ant-primary-6)'; +@primary-7: ~'var(--ant-primary-7)'; +@primary-8: ~'var(--ant-primary-8)'; +@primary-9: ~'var(--ant-primary-9)'; @green-1: #28a744; @green-2: #ebf9f4; @green-3: #48ca9e; @@ -85,21 +94,21 @@ @blue-6: #eff5ff; @blue-7: #3062d4; @blue-8: #f5f8ff; -@blue-9: #175cd3; +@blue-9: @primary-7; @blue-10: #005bc4; -@blue-12: #1570ef; +@blue-12: @primary-color; @blue-13: #e0f2fe; -@blue-14: #f5faff; -@blue-16: #84caff; +@blue-14: @primary-25; +@blue-16: @primary-3; @blue-17: #0968da; @blue-18: #e3e3e3; @blue-20: #d5d9eb; @blue-21: #026aa2; @blue-22: #f0f9ff; @blue-23: #e6f1fe; -@blue-24: #2e90fa; -@blue-25: #b2ddff; -@blue-26: #1849a9; +@blue-24: @primary-5; +@blue-25: @primary-2; +@blue-26: @primary-8; @blue-27: #2196f3; @blue-28: #e3f2fd4d; @grey-text: #2c2c2c; @@ -136,7 +145,7 @@ @box-shadow-base: 0px 2px 10px rgba(0, 0, 0, 0.12); @button-box-shadow-default: 0px 1px 2px 0px rgba(10, 13, 18, 0.05); @button-box-shadow-hover: 0px 1px 2px 0px rgba(10, 13, 18, 0.05); -@button-box-shadow-focus: 0px 0px 0px 4px rgba(209, 233, 255, 1); +@button-box-shadow-focus: 0px 0px 0px 4px @primary-1; @button-box-shadow-disabled: 0px 1px 2px 0px rgba(10, 13, 18, 0.05); @button-box-shadow-grey: 0px 1px 2px 0px rgba(10, 13, 18, 0.05), 0px 0px 0px 4px #f5f5f5; @@ -203,7 +212,7 @@ @alert-error: @red-13; @alert-info: @blue-16; @alert-info-icon: @blue-12; -@alert-info-icon-bg-1: #d1e9ff; +@alert-info-icon-bg-1: @primary-1; @alert-info-icon-bg-2: @primary-button-background; @alert-success-icon: @green-13; @alert-success-icon-bg-1: @green-12; @@ -370,7 +379,7 @@ @primary-heading-color: @blue-9; @navigation-text-color: #787486; -@primary-button-background: #eff8ff; +@primary-button-background: @primary-50; // button sizes @btn-height-sm: 36px; diff --git a/openmetadata-ui/src/main/resources/ui/yarn.lock b/openmetadata-ui/src/main/resources/ui/yarn.lock index 04834eb828d..9f046fc1333 100644 --- a/openmetadata-ui/src/main/resources/ui/yarn.lock +++ b/openmetadata-ui/src/main/resources/ui/yarn.lock @@ -4747,6 +4747,11 @@ dependencies: "@types/jest" "*" +"@types/tinycolor2@^1.4.6": + version "1.4.6" + resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.6.tgz#670cbc0caf4e58dd61d1e3a6f26386e473087f06" + integrity sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw== + "@types/trusted-types@^2.0.2": version "2.0.4" resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz" @@ -14284,6 +14289,11 @@ tiny-invariant@^1.1.0, tiny-invariant@^1.3.1: resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tinycolor2@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" + integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== + tippy.js@^6.3.7: version "6.3.7" resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz"