Skip to content

Commit 2cb574c

Browse files
3emankormoreankor
andauthored
add light icon to project create page (harness#1203)
Co-authored-by: Andrew Koreykin <[email protected]>
1 parent 58ee5d0 commit 2cb574c

File tree

9 files changed

+71
-66
lines changed

9 files changed

+71
-66
lines changed

apps/design-system/src/utils/theme-utils.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FullTheme } from '@harnessio/ui/context'
1+
import { FullTheme, IThemeStore } from '@harnessio/ui/context'
22

33
export enum Themes {
44
DARK_STANDARD_LOW = 'dark-std-low',
@@ -19,7 +19,8 @@ export const getTheme = () => {
1919
return Themes.DARK
2020
}
2121

22-
export const useThemeStore = () => ({
22+
export const useThemeStore = (): IThemeStore => ({
2323
theme: getTheme() as FullTheme,
24-
setTheme: (_: FullTheme) => {}
24+
setTheme: (_: FullTheme) => {},
25+
isLightTheme: false
2526
})

apps/gitness/src/framework/context/ThemeContext.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const useThemeStore = create<IThemeStore>()(
1212
persist(
1313
set => ({
1414
theme: undefined,
15-
setTheme: (newTheme: FullTheme) => set({ theme: newTheme })
15+
setTheme: (newTheme: FullTheme) => set({ theme: newTheme }),
16+
isLightTheme: false
1617
}),
1718
{
1819
name: 'canary-ui-theme' // LocalStorage key
@@ -25,7 +26,7 @@ interface ThemeProviderProps {
2526
defaultTheme: FullTheme
2627
}
2728
export function ThemeProvider({ children, defaultTheme }: ThemeProviderProps) {
28-
const { theme, setTheme } = useThemeStore()
29+
const { theme, setTheme, isLightTheme } = useThemeStore()
2930
const isMFE = useIsMFE()
3031

3132
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
@@ -73,7 +74,7 @@ export function ThemeProvider({ children, defaultTheme }: ThemeProviderProps) {
7374
}, [theme, setTheme, systemMode])
7475

7576
return (
76-
<UIThemeProvider theme={theme} setTheme={setTheme}>
77+
<UIThemeProvider theme={theme} setTheme={setTheme} isLightTheme={isLightTheme}>
7778
{children}
7879
</UIThemeProvider>
7980
)

packages/ui/src/components/icon/icon.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { FC } from 'react'
22

33
import { useTheme } from '@/context'
44
import { cn } from '@utils/cn'
5-
import { isLightTheme } from '@utils/is-light-theme'
65

76
import { IconNameMap } from './icon-name-map'
87

@@ -17,16 +16,16 @@ export interface IconProps {
1716
}
1817

1918
const Icon: FC<IconProps> = ({ name, size = 16, height, width, className, themeDependent = false }) => {
20-
const { theme } = useTheme()
19+
const { isLightTheme } = useTheme()
2120

2221
const isLightIconAvailable = !!IconNameMap[`${name}-light` as keyof typeof IconNameMap]
2322

2423
const Component =
25-
themeDependent && isLightTheme(theme) && isLightIconAvailable
24+
themeDependent && isLightTheme && isLightIconAvailable
2625
? IconNameMap[`${name}-light` as keyof typeof IconNameMap]
2726
: IconNameMap[name]
2827

29-
const shouldInvert = themeDependent && isLightTheme(theme) && !isLightIconAvailable
28+
const shouldInvert = themeDependent && isLightTheme && !isLightIconAvailable
3029

3130
return <Component className={cn({ invert: shouldInvert }, className)} width={width || size} height={height || size} />
3231
}

packages/ui/src/context/theme/theme-context.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
import { createContext, PropsWithChildren, useContext } from 'react'
1+
import { createContext, PropsWithChildren, useContext, useMemo } from 'react'
22

3-
import { defaultTheme, IThemeStore } from '@/context'
3+
import { defaultTheme, IThemeStore, ModeType } from '@/context'
44

55
const ThemeContext = createContext<Required<IThemeStore> | undefined>({
66
theme: defaultTheme,
7-
setTheme: () => void 0
7+
setTheme: () => void 0,
8+
isLightTheme: false
89
})
910

10-
export const ThemeProvider = ({ children, ...rest }: PropsWithChildren<IThemeStore>) => {
11-
return (
12-
<ThemeContext.Provider
13-
value={{
14-
...rest,
15-
theme: rest?.theme ?? defaultTheme
16-
}}
17-
>
18-
{children}
19-
</ThemeContext.Provider>
20-
)
11+
export const ThemeProvider = ({ children, theme: themeProp, ...rest }: PropsWithChildren<IThemeStore>) => {
12+
const theme = themeProp ?? defaultTheme
13+
const isLightTheme = useMemo(() => theme.includes(ModeType.Light), [theme])
14+
15+
return <ThemeContext.Provider value={{ ...rest, theme, isLightTheme }}>{children}</ThemeContext.Provider>
2116
}
2217

2318
export const useTheme = () => {

packages/ui/src/context/theme/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type FullTheme = `${ModeType}-${ColorType}-${ContrastType}`
2121
export interface IThemeStore {
2222
theme?: FullTheme
2323
setTheme: (theme: FullTheme) => void
24+
isLightTheme: boolean
2425
}
2526

2627
export const defaultTheme = `${ModeType.Dark}-${ColorType.Standard}-${ContrastType.Standard}` as FullTheme

packages/ui/src/utils/is-light-theme.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/ui/src/views/layouts/Floating1ColumnLayout.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useTheme } from '@/context'
12
import { cn } from '@utils/cn'
23

34
type HighlightTheme = 'blue' | 'green' | 'error'
@@ -66,43 +67,49 @@ const highlightThemes = {
6667

6768
interface HighlightedFloatingLayoutProps extends Floating1ColumnLayoutProps {
6869
theme: HighlightTheme
70+
hasGradients?: boolean
6971
}
7072

7173
const HighlightedFloatingLayout = ({ children, className, theme = 'blue' }: HighlightedFloatingLayoutProps) => {
74+
const { isLightTheme } = useTheme()
75+
76+
const hasGradients = !isLightTheme
7277
const { topAdditionalGradient, topGradient, bottomGradient } = highlightThemes[theme]
7378
const isError = theme === 'error'
7479

7580
return (
7681
<Floating1ColumnLayout className={cn(className, 'relative max-w-full overflow-hidden')}>
77-
<div className="pointer-events-none absolute inset-0 z-0" aria-hidden>
78-
<span
79-
className={cn(
80-
'absolute blur-[30px] top-0 left-1/2 -translate-y-1/2 w-[528px] h-[178px] rounded-[100%] opacity-10 mix-blend-plus-lighter',
81-
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_30%,transparent_100%)]',
82-
'transition-[transform,background-color] ease-in-out duration-700',
83-
isError ? '-translate-x-[28%]' : ' -translate-x-[65%]',
84-
topAdditionalGradient
85-
)}
86-
/>
87-
<span
88-
className={cn(
89-
'absolute blur-[30px] top-3.5 -translate-y-1/2 left-1/2 w-[895px] h-[377px] rounded-[100%] opacity-[0.14]',
90-
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_0%,transparent_100%)]',
91-
'transition-[transform,background-color] ease-in-out duration-700',
92-
isError ? '-translate-x-[11%]' : ' -translate-x-[84.5%]',
93-
topGradient
94-
)}
95-
/>
96-
<span
97-
className={cn(
98-
'absolute blur-[30px] bottom-0 translate-y-1/2 left-1/2 w-[895px] h-[261px] rounded-[100%] opacity-[0.08]',
99-
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_0%,transparent_100%)]',
100-
'transition-[transform,background-color] ease-in-out duration-700',
101-
isError ? '-translate-x-[88.5%]' : ' -translate-x-[104px]',
102-
bottomGradient
103-
)}
104-
/>
105-
</div>
82+
{hasGradients && (
83+
<div className="pointer-events-none absolute inset-0 z-0" aria-hidden>
84+
<span
85+
className={cn(
86+
'absolute blur-[30px] top-0 left-1/2 -translate-y-1/2 w-[528px] h-[178px] rounded-[100%] opacity-10 mix-blend-plus-lighter',
87+
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_30%,transparent_100%)]',
88+
'transition-[transform,background-color] ease-in-out duration-700',
89+
isError ? '-translate-x-[28%]' : ' -translate-x-[65%]',
90+
topAdditionalGradient
91+
)}
92+
/>
93+
<span
94+
className={cn(
95+
'absolute blur-[30px] top-3.5 -translate-y-1/2 left-1/2 w-[895px] h-[377px] rounded-[100%] opacity-[0.14]',
96+
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_0%,transparent_100%)]',
97+
'transition-[transform,background-color] ease-in-out duration-700',
98+
isError ? '-translate-x-[11%]' : ' -translate-x-[84.5%]',
99+
topGradient
100+
)}
101+
/>
102+
<span
103+
className={cn(
104+
'absolute blur-[30px] bottom-0 translate-y-1/2 left-1/2 w-[895px] h-[261px] rounded-[100%] opacity-[0.08]',
105+
'[mask-image:radial-gradient(50%_50%_at_50%_50%,#000_0%,transparent_100%)]',
106+
'transition-[transform,background-color] ease-in-out duration-700',
107+
isError ? '-translate-x-[88.5%]' : ' -translate-x-[104px]',
108+
bottomGradient
109+
)}
110+
/>
111+
</div>
112+
)}
106113

107114
{children}
108115
</Floating1ColumnLayout>

packages/ui/src/views/project/create-project-page.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { FC, useEffect, useState } from 'react'
22
import { useForm } from 'react-hook-form'
33

44
import { Button, Card, Fieldset, FormWrapper, Icon, Input, StyledLink, StyledLinkProps } from '@/components'
5+
import { useTheme } from '@/context'
56
import { Floating1ColumnLayout, TranslationStore } from '@/views'
67
import { zodResolver } from '@hookform/resolvers/zod'
78
import { cn } from '@utils/cn'
@@ -59,6 +60,8 @@ export type CreateProjectFields = z.infer<ReturnType<typeof createProjectSchema>
5960

6061
export const CreateProjectPage: FC<CreateProjectPageProps> = props => {
6162
const { error, isLoading, backLinkProps, onFormSubmit, useTranslationStore } = props
63+
const { isLightTheme } = useTheme()
64+
6265
const isAdditional = getIsAdditionalProjectPage(props)
6366
const isFirst = getIsFirstProjectPage(props)
6467
const isWithBackButton = !!backLinkProps?.to && isAdditional
@@ -101,7 +104,7 @@ export const CreateProjectPage: FC<CreateProjectPageProps> = props => {
101104

102105
return (
103106
<Floating1ColumnLayout
104-
className="flex-col justify-start bg-background-7 pt-20 sm:pt-[8.75rem]"
107+
className="bg-background-7 flex-col justify-start pt-20 sm:pt-[8.75rem]"
105108
highlightTheme={hasError ? 'error' : 'green'}
106109
verticalCenter
107110
>
@@ -117,13 +120,17 @@ export const CreateProjectPage: FC<CreateProjectPageProps> = props => {
117120

118121
<div className="relative z-10 w-80 max-w-full">
119122
<div className="mb-10 grid justify-items-center">
120-
<CreateProjectAnimatedLogo hasError={hasError} />
123+
{isLightTheme ? (
124+
<Icon size={112} name="create-workspace-light" />
125+
) : (
126+
<CreateProjectAnimatedLogo hasError={hasError} />
127+
)}
121128

122-
<Card.Title className="mt-3 text-center text-foreground-1" as="h1">
129+
<Card.Title className="text-foreground-1 mt-3 text-center" as="h1">
123130
{t('views:createProject.title', 'Create your new project')}
124131
</Card.Title>
125132

126-
<p className="mt-0.5 text-center text-sm leading-snug text-foreground-4">
133+
<p className="text-foreground-4 mt-0.5 text-center text-sm leading-snug">
127134
{t('views:createProject.description', 'Organize your repositories, pipelines and more.')}
128135
</p>
129136
</div>
@@ -165,7 +172,7 @@ export const CreateProjectPage: FC<CreateProjectPageProps> = props => {
165172
</FormWrapper>
166173

167174
{isFirst && (
168-
<p className="foreground-5 mt-4 text-center text-sm text-foreground-5">
175+
<p className="foreground-5 text-foreground-5 mt-4 text-center text-sm">
169176
{t('views:createProject.logout.question', 'Want to use a different account?')}{' '}
170177
<StyledLink {...props.logoutLinkProps} variant="accent">
171178
{t('views:createProject.logout.link', 'Log out')}

packages/ui/src/views/repo/webhooks/webhook-executions/repo-webhook-execution-details-page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { FC, useEffect, useMemo, useState } from 'react'
33
import { Badge, Button, ListActions, Spacer, Text } from '@/components'
44
import { ModeType, useTheme } from '@/context'
55
import { SandboxLayout, TranslationStore, WebhookStore } from '@/views'
6-
import { isLightTheme } from '@utils/is-light-theme'
76
import { formatDuration } from '@utils/TimeUtils'
87
import { timeAgo } from '@utils/utils'
98

@@ -29,9 +28,9 @@ export const RepoWebhookExecutionDetailsPage: FC<RepoWebhookExecutionDetailsPage
2928
const { executionId, executions } = useWebhookStore()
3029
const [codeEditorContent, setCodeEditorContent] = useState({ code: '' })
3130
const [view, setView] = useState('payload')
32-
const { theme } = useTheme()
31+
const { isLightTheme } = useTheme()
3332

34-
const monacoTheme = useMemo(() => (isLightTheme(theme) ? ModeType.Light : ModeType.Dark), [theme])
33+
const monacoTheme = useMemo(() => (isLightTheme ? ModeType.Light : ModeType.Dark), [isLightTheme])
3534

3635
const themeConfig = useMemo(
3736
() => ({

0 commit comments

Comments
 (0)