forked from zendesk/copenhagen_theme
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(nav): add deps for nav UI and UI components
- Loading branch information
Showing
28 changed files
with
46,229 additions
and
3,337 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"name": "Copenhagen", | ||
"name": "Copenhagen Test", | ||
"author": "Zendesk", | ||
"version": "4.2.2", | ||
"api_version": 4, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import { FC, PropsWithChildren } from 'react'; | ||
|
||
import cn from 'classnames'; | ||
import { Theme } from '../../utils/storage'; | ||
import formatHrefAsMailto from '../../utils/formatHrefAsMailto'; | ||
import React from 'react'; | ||
|
||
interface PrimaryButtonProps extends ButtonBaseProps { | ||
label: string; | ||
color?: 'accent-1' | 'accent-2'; | ||
size?: 'medium' | 'large'; | ||
fullWidth?: boolean; | ||
theme?: Theme; | ||
} | ||
|
||
interface PrimaryLinkProps extends LinkBaseProps { | ||
label: string; | ||
color?: 'accent-1' | 'accent-2' | 'surface-3'; | ||
size?: 'medium' | 'large'; | ||
fullWidth?: boolean; | ||
theme?: Theme; | ||
} | ||
|
||
export const PrimaryButton: FC<PrimaryLinkProps | PrimaryButtonProps> = (props) => { | ||
const { color = 'accent-1', size = 'medium', fullWidth = false, theme } = props; | ||
const containerStyle = cn('transition-colors flex flex-row items-center justify-center', { | ||
'bg-light-accent-1 dark:bg-dark-accent-1 hover:bg-light-accent-1-hovered dark:hover:bg-dark-accent-1-hovered': | ||
!theme && color === 'accent-1', | ||
'bg-light-accent-2 dark:bg-dark-accent-2 hover:bg-light-accent-2-hovered dark:hover:bg-dark-accent-2-hovered': | ||
!theme && color === 'accent-2', | ||
'bg-light-surface-3 dark:bg-dark-surface-3 hover:bg-light-surface-3-hovered dark:hover:bg-dark-surface-3-hovered': | ||
!theme && color === 'surface-3', | ||
'bg-dark-accent-1 hover:bg-dark-accent-1-hovered': theme === 'dark' && color === 'accent-1', | ||
'bg-light-accent-1 hover:bg-light-accent-1-hovered': theme === 'light' && color === 'accent-1', | ||
'bg-dark-accent-2 hover:bg-dark-accent-2-hovered': theme === 'dark' && color === 'accent-2', | ||
'bg-light-accent-2 hover:bg-light-accent-2-hovered': theme === 'light' && color === 'accent-2', | ||
'rounded-small px-padding-small py-padding-small-dense': size === 'medium', | ||
'rounded-medium px-padding-large p-padding-medium': size === 'large', | ||
}); | ||
const textStyle = cn({ | ||
'text-white': color === 'accent-1', | ||
'text-light-accent-1 dark:text-dark-accent-1': color === 'accent-2', | ||
'text-light-neutral-1 dark:text-dark-neutral-1': color === 'surface-3', | ||
'button-label-4': size === 'medium', | ||
'button-label-2': size === 'large', | ||
}); | ||
|
||
if ('href' in props) { | ||
const { label, href, ariaLabel, className, onClick } = props; | ||
|
||
return ( | ||
<div | ||
className={cn('PrimaryButton flex', { | ||
'w-full': fullWidth, | ||
})} | ||
> | ||
<LinkBase | ||
href={href} | ||
className={cn(containerStyle, className, { | ||
'w-full': fullWidth, | ||
})} | ||
ariaLabel={ariaLabel} | ||
onClick={onClick} | ||
> | ||
<span className={textStyle}>{label}</span> | ||
</LinkBase> | ||
</div> | ||
); | ||
} | ||
|
||
const { label, onClick, ariaLabel, role, className } = props; | ||
|
||
return ( | ||
<div className="PrimaryButton flex"> | ||
<ButtonBase | ||
onClick={onClick} | ||
className={cn(containerStyle, className)} | ||
ariaLabel={ariaLabel} | ||
role={role} | ||
> | ||
<span className={textStyle}>{label}</span> | ||
</ButtonBase> | ||
</div> | ||
); | ||
}; | ||
|
||
interface TextButtonProps extends ButtonBaseProps { | ||
label: string; | ||
textClassName?: string; | ||
} | ||
|
||
interface TextLinkProps extends LinkBaseProps { | ||
label: string; | ||
textClassName?: string; | ||
} | ||
|
||
export const TextButton: FC<TextButtonProps | TextLinkProps> = (props) => { | ||
const containerStyle = 'TextButton group'; | ||
const textStyle = 'decoration-inherit'; | ||
const textClassName = props.textClassName; | ||
|
||
if ('href' in props) { | ||
const { label, href, ariaLabel, className, onClick } = props; | ||
|
||
return ( | ||
<LinkBase | ||
href={href} | ||
className={cn(containerStyle, className)} | ||
ariaLabel={ariaLabel} | ||
onClick={onClick} | ||
> | ||
<span className={cn(textStyle, textClassName)}>{label}</span> | ||
</LinkBase> | ||
); | ||
} | ||
|
||
const { label, onClick, ariaLabel, role, className } = props; | ||
|
||
return ( | ||
<ButtonBase | ||
onClick={onClick} | ||
className={cn(containerStyle, className)} | ||
ariaLabel={ariaLabel} | ||
role={role} | ||
> | ||
<span className={cn(textStyle, textClassName)}>{label}</span> | ||
</ButtonBase> | ||
); | ||
}; | ||
|
||
type ButtonBaseProps = { | ||
className?: string; | ||
onClick?: () => void; | ||
ariaLabel?: string; | ||
role?: string; | ||
}; | ||
|
||
export const ButtonBase: FC<PropsWithChildren<ButtonBaseProps>> = ({ | ||
className, | ||
onClick, | ||
children, | ||
ariaLabel, | ||
role, | ||
}) => { | ||
return ( | ||
<button onClick={onClick} className={className} aria-label={ariaLabel} role={role}> | ||
{children} | ||
</button> | ||
); | ||
}; | ||
|
||
type LinkBaseProps = { | ||
className?: string; | ||
href: string; | ||
ariaLabel?: string; | ||
onClick?: () => void; | ||
}; | ||
|
||
const OPEN_IN_NEW_TAB_PROPS = { target: '_blank', rel: 'noreferrer noopener' }; | ||
const OPEN_IN_CURRENT_TAB_PROPS = { target: '_self' }; | ||
|
||
export const LinkBase: FC<PropsWithChildren<LinkBaseProps>> = ({ | ||
className, | ||
href, | ||
children, | ||
ariaLabel, | ||
onClick, | ||
}) => { | ||
const isInternalLink = href.startsWith('/') || href.startsWith('#'); | ||
const targetProps = isInternalLink ? OPEN_IN_CURRENT_TAB_PROPS : OPEN_IN_NEW_TAB_PROPS; | ||
|
||
return ( | ||
<a | ||
className={className} | ||
href={formatHrefAsMailto(href)} | ||
aria-label={ariaLabel} | ||
onClick={onClick} | ||
{...targetProps} | ||
> | ||
{children} | ||
</a> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React, { FC, createContext, PropsWithChildren, useState, useContext, useEffect } from 'react'; | ||
|
||
import { ThemeManager, Theme } from '../utils/storage'; | ||
|
||
type UIProviderProps = { | ||
theme: Theme; | ||
toggleTheme: () => void; | ||
}; | ||
|
||
export const UIContext = createContext<UIProviderProps | undefined>(undefined); | ||
|
||
export const useUIProvider = () => { | ||
const context = useContext(UIContext); | ||
|
||
if (context === undefined) { | ||
throw new Error('useUIProvider must be used within a UIProvider'); | ||
} | ||
|
||
return context; | ||
}; | ||
|
||
export const UIProvider: FC<PropsWithChildren> = ({ children }) => { | ||
const [theme, setTheme] = useState<Theme>('light'); | ||
|
||
useEffect(() => { | ||
if (typeof window !== 'undefined') { | ||
const currentTheme = ThemeManager.get(); | ||
|
||
if (!currentTheme) { | ||
ThemeManager.set('light'); | ||
} else { | ||
setTheme(currentTheme); | ||
} | ||
} | ||
}, []); | ||
|
||
const toggleTheme = () => { | ||
setTheme((prev) => { | ||
const newTheme = prev === 'dark' ? 'light' : 'dark'; | ||
ThemeManager.set(newTheme); | ||
return newTheme; | ||
}); | ||
}; | ||
|
||
return ( | ||
<UIContext.Provider | ||
value={{ | ||
theme, | ||
toggleTheme, | ||
}} | ||
> | ||
{children} | ||
</UIContext.Provider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const DOMAIN = 'zendesk.com'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
export type Tag = { | ||
title: string; | ||
slug: string; | ||
}; | ||
|
||
export type GlobalSettings = { | ||
navigationTopics: Tag[] | null; | ||
topNavigationApp: { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
} | null; | ||
footerLinksTopics: | ||
| { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}[] | ||
| null; | ||
footerLinksEcosystem: | ||
| { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}[] | ||
| null; | ||
footerLinksCompany: | ||
| { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}[] | ||
| null; | ||
footerLinksHelp: | ||
| { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}[] | ||
| null; | ||
footerGithubLink: string | null; | ||
footerXLink: string | null; | ||
footerDiscordLink: string | null; | ||
connectBlockTitle: string; | ||
connectBlockSupportTitle: string; | ||
connectBlockSupportButton: { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}; | ||
connectBlockSocialTitle: string; | ||
connectBlockSocialButton: { | ||
id: string; | ||
key: string | ''; // Label of the link | ||
value: string | ''; // URL of the link | ||
}; | ||
connectBlockNewsletterTitle: string; | ||
}; |
Oops, something went wrong.