mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 16:31:47 +00:00
Cody UI updates (#58828)
This commit is contained in:
parent
44224ffc93
commit
2dc7073cd3
@ -28,3 +28,7 @@
|
||||
.modal {
|
||||
width: 50rem;
|
||||
}
|
||||
|
||||
.release-stage {
|
||||
color: var(--gray-07);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import type { ReactElement } from 'react'
|
||||
|
||||
import { mdiHelpCircleOutline, mdiTrendingUp, mdiDownload, mdiInformation } from '@mdi/js'
|
||||
import classNames from 'classnames'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useQuery, useMutation } from '@sourcegraph/http-client'
|
||||
import {
|
||||
@ -10,6 +11,7 @@ import {
|
||||
PageHeader,
|
||||
Link,
|
||||
H4,
|
||||
H5,
|
||||
H2,
|
||||
Text,
|
||||
ButtonLink,
|
||||
@ -18,6 +20,7 @@ import {
|
||||
LoadingSpinner,
|
||||
} from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import { Page } from '../../components/Page'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { useFeatureFlag } from '../../featureFlags/useFeatureFlag'
|
||||
@ -41,9 +44,13 @@ import styles from './CodyManagementPage.module.scss'
|
||||
|
||||
interface CodyManagementPageProps {
|
||||
isSourcegraphDotCom: boolean
|
||||
authenticatedUser: AuthenticatedUser | null
|
||||
}
|
||||
|
||||
export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps> = ({ isSourcegraphDotCom }) => {
|
||||
export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps> = ({
|
||||
isSourcegraphDotCom,
|
||||
authenticatedUser,
|
||||
}) => {
|
||||
const parameters = useSearchParameters()
|
||||
|
||||
const utm_source = parameters.get('utm_source')
|
||||
@ -71,6 +78,14 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
}
|
||||
}, [data?.currentUser, changeCodyPlan, enrollPro])
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
if (!!data && !data?.currentUser) {
|
||||
navigate('/sign-in?returnTo=/cody/manage')
|
||||
}
|
||||
}, [data, navigate])
|
||||
|
||||
if (!isCodyEnabled() || !isSourcegraphDotCom || !isEnabled || !data?.currentUser) {
|
||||
return null
|
||||
}
|
||||
@ -147,7 +162,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
<LoadingSpinner />
|
||||
)}
|
||||
</div>
|
||||
<H4 className="mb-0">Autocompletes</H4>
|
||||
<H4 className="mb-0">Autocomplete suggestions</H4>
|
||||
{!codyProEnabled && (
|
||||
<Text className="text-muted mb-0" size="small">
|
||||
this month
|
||||
@ -178,7 +193,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
<LoadingSpinner />
|
||||
)}
|
||||
</div>
|
||||
<H4 className="mb-0">Chat Messages</H4>
|
||||
<H4 className="mb-0">Chat messages and commands</H4>
|
||||
{!codyProEnabled && (
|
||||
<Text className="text-muted mb-0" size="small">
|
||||
this month
|
||||
@ -194,7 +209,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
</Text>
|
||||
</div>
|
||||
<Text className="text-muted mb-0" size="small">
|
||||
Until 14th of February 2023
|
||||
Until 14th of February 2024
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
@ -208,10 +223,15 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
<Text className="text-muted mb-0">Cody integrates with your workflow.</Text>
|
||||
</div>
|
||||
<div>
|
||||
<ButtonLink to="/cody/pricing" variant="secondary" outline={true} size="sm">
|
||||
<Link
|
||||
to="https://sourcegraph.com/community"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-muted text-sm"
|
||||
>
|
||||
<Icon svgPath={mdiHelpCircleOutline} className="mr-1" aria-hidden={true} />
|
||||
Missing an editor?
|
||||
</ButtonLink>
|
||||
Have feedback? Join our community Discord to let us know!
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
{editorGroups.map((group, index) => (
|
||||
@ -228,7 +248,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
'border-left': index !== 0,
|
||||
})}
|
||||
>
|
||||
<div className="d-flex mb-3">
|
||||
<div className="d-flex mb-3 align-items-center">
|
||||
<div>
|
||||
<img
|
||||
alt={editor.name}
|
||||
@ -242,6 +262,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
{editor.publisher}
|
||||
</Text>
|
||||
<Text className={classNames('mb-0', styles.ideName)}>{editor.name}</Text>
|
||||
<H5 className={styles.releaseStage}>{editor.releaseStage}</H5>
|
||||
</div>
|
||||
</div>
|
||||
<Link
|
||||
@ -298,7 +319,7 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
|
||||
))}
|
||||
</div>
|
||||
</Page>
|
||||
<CodyOnboarding />
|
||||
<CodyOnboarding authenticatedUser={authenticatedUser} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -189,3 +189,8 @@
|
||||
.fade-in-up-animation {
|
||||
animation: 1.5s fadeInUp;
|
||||
}
|
||||
|
||||
.blank-placeholder {
|
||||
min-width: 11.25rem;
|
||||
min-height: 17rem;
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import React, { useState, useEffect, useCallback } from 'react'
|
||||
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary'
|
||||
import { Modal, H5, H2, H3, Text, Button, useSearchParameters } from '@sourcegraph/wildcard'
|
||||
import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
|
||||
import { Modal, H5, H2, Text, Button, useSearchParameters } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import { HubSpotForm } from '../../marketing/components/HubSpotForm'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { EventName } from '../../util/constants'
|
||||
|
||||
@ -37,20 +40,6 @@ export const editorGroups: IEditor[][] = [
|
||||
releaseStage: 'Beta',
|
||||
instructions: JetBrainsInstructions,
|
||||
},
|
||||
{
|
||||
icon: 'NeoVim',
|
||||
name: 'Neovim',
|
||||
publisher: 'Neovim Team',
|
||||
releaseStage: 'Experimental',
|
||||
},
|
||||
{
|
||||
icon: 'AndroidStudio',
|
||||
name: 'Android Studio',
|
||||
publisher: 'Google',
|
||||
releaseStage: 'Beta',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
icon: 'PhpStorm',
|
||||
name: 'PhpStorm ',
|
||||
@ -63,6 +52,8 @@ export const editorGroups: IEditor[][] = [
|
||||
publisher: 'Jetbrains',
|
||||
releaseStage: 'Beta',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
icon: 'WebStorm',
|
||||
name: 'WebStorm',
|
||||
@ -75,14 +66,26 @@ export const editorGroups: IEditor[][] = [
|
||||
publisher: 'JetBrains',
|
||||
releaseStage: 'Beta',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
icon: 'GoLand',
|
||||
name: 'GoLand',
|
||||
publisher: 'JetBrains',
|
||||
releaseStage: 'Beta',
|
||||
},
|
||||
{
|
||||
icon: 'AndroidStudio',
|
||||
name: 'Android Studio',
|
||||
publisher: 'Google',
|
||||
releaseStage: 'Beta',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
icon: 'NeoVim',
|
||||
name: 'Neovim',
|
||||
publisher: 'Neovim Team',
|
||||
releaseStage: 'Experimental',
|
||||
},
|
||||
{
|
||||
icon: 'Emacs',
|
||||
name: 'Emacs',
|
||||
@ -92,7 +95,12 @@ export const editorGroups: IEditor[][] = [
|
||||
],
|
||||
]
|
||||
|
||||
export function CodyOnboarding(): JSX.Element | null {
|
||||
export function CodyOnboarding({
|
||||
authenticatedUser,
|
||||
}: {
|
||||
authenticatedUser: AuthenticatedUser | null
|
||||
}): JSX.Element | null {
|
||||
const [showEditorStep, setShowEditorStep] = useState(false)
|
||||
const [completed = true, setOnboardingCompleted] = useTemporarySetting('cody.onboarding.completed', false)
|
||||
// steps start from 0
|
||||
const [step = -1, setOnboardingStep] = useTemporarySetting('cody.onboarding.step', 0)
|
||||
@ -102,52 +110,134 @@ export function CodyOnboarding(): JSX.Element | null {
|
||||
const parameters = useSearchParameters()
|
||||
const enrollPro = parameters.get('pro') === 'true'
|
||||
|
||||
if (completed || step === -1 || step > 2) {
|
||||
if (!showEditorStep && (completed || step === -1 || step > 1)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (!authenticatedUser) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal isOpen={true} aria-label="Cody Onboarding" className={styles.modal} position="center">
|
||||
{step === 0 && <WelcomeStep onNext={onNext} pro={enrollPro} />}
|
||||
{step === 1 && <PurposeStep onNext={onNext} pro={enrollPro} />}
|
||||
{step === 2 && (
|
||||
<EditorStep onNext={onNext} onCompleted={() => setOnboardingCompleted(true)} pro={enrollPro} />
|
||||
{step === 1 && (
|
||||
<PurposeStep
|
||||
authenticatedUser={authenticatedUser}
|
||||
onNext={() => {
|
||||
onNext()
|
||||
setOnboardingCompleted(true)
|
||||
setShowEditorStep(true)
|
||||
}}
|
||||
pro={enrollPro}
|
||||
/>
|
||||
)}
|
||||
{showEditorStep && (
|
||||
<EditorStep
|
||||
onCompleted={() => {
|
||||
setShowEditorStep(false)
|
||||
}}
|
||||
pro={enrollPro}
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
function WelcomeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX.Element {
|
||||
const [show, setShow] = useState(false)
|
||||
const isLightTheme = useIsLightTheme()
|
||||
useEffect(() => {
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_WELCOME_VIEWED, { tier: pro ? 'pro' : 'free' })
|
||||
}, [pro])
|
||||
|
||||
useEffect(() => {
|
||||
// theme is not ready on first render, it defaults to system theme.
|
||||
// so we need to wait a bit before showing the welcome video.
|
||||
setTimeout(() => {
|
||||
setShow(true)
|
||||
}, 500)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={classNames('d-flex flex-column align-items-center p-5')}>
|
||||
<video width="180" className={classNames('mb-5', styles.welcomeVideo)} autoPlay={true} muted={true}>
|
||||
<source src="https://storage.googleapis.com/sourcegraph-assets/codyWelcomeAnim.mp4" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<Text className={classNames('mb-4 pb-4', styles.fadeIn, styles.fadeSecond, styles.welcomeSubtitle)}>
|
||||
Ready to breeze through the basics and get comfortable with Cody{pro ? ' to Cody Pro Trial' : ''}?
|
||||
</Text>
|
||||
<Button
|
||||
onClick={onNext}
|
||||
variant="primary"
|
||||
size="lg"
|
||||
className={classNames(styles.fadeIn, styles.fadeThird)}
|
||||
>
|
||||
Sure, let's dive in!
|
||||
</Button>
|
||||
{show ? (
|
||||
<>
|
||||
<video width="180" className={classNames('mb-5', styles.welcomeVideo)} autoPlay={true} muted={true}>
|
||||
<source
|
||||
src={
|
||||
isLightTheme
|
||||
? 'https://storage.googleapis.com/sourcegraph-assets/codyWelcomeAnim.mp4'
|
||||
: 'https://storage.googleapis.com/sourcegraph-assets/codyWelcomeAnim_dark.mp4'
|
||||
}
|
||||
type="video/mp4"
|
||||
/>
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<Text className={classNames('mb-4 pb-4', styles.fadeIn, styles.fadeSecond, styles.welcomeSubtitle)}>
|
||||
Ready to breeze through the basics and get comfortable with Cody
|
||||
{pro ? ' to Cody Pro Trial' : ''}?
|
||||
</Text>
|
||||
<Button
|
||||
onClick={onNext}
|
||||
variant="primary"
|
||||
size="lg"
|
||||
className={classNames(styles.fadeIn, styles.fadeThird)}
|
||||
>
|
||||
Sure, let's dive in!
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<div className={styles.blankPlaceholder} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function PurposeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX.Element {
|
||||
function PurposeStep({
|
||||
onNext,
|
||||
pro,
|
||||
authenticatedUser,
|
||||
}: {
|
||||
onNext: () => void
|
||||
pro: boolean
|
||||
authenticatedUser: AuthenticatedUser
|
||||
}): JSX.Element {
|
||||
const [useCase, setUseCase] = useState<'work' | 'personal' | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_VIEWED, { tier: pro ? 'pro' : 'free' })
|
||||
}, [pro])
|
||||
|
||||
const primaryEmail = authenticatedUser.emails.find(email => email.isPrimary)?.email
|
||||
|
||||
const handleFormReady = useCallback((form: HTMLFormElement) => {
|
||||
const workInput = form.querySelector('input[name="using_cody_for_work"]')
|
||||
const personalInput = form.querySelector('input[name="using_cody_for_personal"]')
|
||||
|
||||
const handleChange = (e: Event): void => {
|
||||
const target = e.target as HTMLInputElement
|
||||
const isChecked = target.checked
|
||||
const name = target.name
|
||||
|
||||
if (name === 'using_cody_for_work' && isChecked) {
|
||||
setUseCase('work')
|
||||
} else if (name === 'using_cody_for_personal' && isChecked) {
|
||||
setUseCase('personal')
|
||||
} else {
|
||||
setUseCase(null)
|
||||
}
|
||||
}
|
||||
|
||||
workInput?.addEventListener('change', handleChange)
|
||||
personalInput?.addEventListener('change', handleChange)
|
||||
|
||||
return () => {
|
||||
workInput?.removeEventListener('change', handleChange)
|
||||
personalInput?.removeEventListener('change', handleChange)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="border-bottom pb-3 mb-3">
|
||||
@ -156,16 +246,32 @@ function PurposeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX
|
||||
This will allow us to understand our audience better and guide your journey
|
||||
</Text>
|
||||
</div>
|
||||
<div className="d-flex align-items-center border-bottom mb-3 pb-3">
|
||||
<div className="d-flex align-items-center border-bottom mb-3 pb-3 justify-content-center">
|
||||
<HubSpotForm
|
||||
formId="85548efc-a879-4553-9ef0-a8da8fdcf541"
|
||||
onFormSubmitted={() => {
|
||||
if (useCase) {
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_SELECTED, { useCase })
|
||||
}
|
||||
onNext()
|
||||
}}
|
||||
userId={authenticatedUser.id}
|
||||
userEmail={primaryEmail}
|
||||
masterFormName="qualificationSurvey"
|
||||
onFormReady={handleFormReady}
|
||||
/>
|
||||
{/* TODO(naman): remove after PR feedback
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={() => {
|
||||
onKeyDown={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_SELECTED, { useCase: 'work' })
|
||||
onNext()
|
||||
}}
|
||||
className="border-right flex-1 d-flex flex-column justify-content-center cursor-pointer align-items-center py-3 px-2"
|
||||
onClick={() => {
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_SELECTED, { useCase: 'work' })
|
||||
onNext()
|
||||
}}
|
||||
@ -177,11 +283,13 @@ function PurposeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex-1 d-flex flex-column justify-content-center cursor-pointer align-items-center py-3 px-2"
|
||||
onKeyDown={() => {
|
||||
onKeyDown={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_SELECTED, { useCase: 'personal' })
|
||||
onNext()
|
||||
}}
|
||||
onClick={() => {
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_PURPOSE_SELECTED, { useCase: 'personal' })
|
||||
onNext()
|
||||
}}
|
||||
@ -189,6 +297,7 @@ function PurposeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX
|
||||
<PersonalIcon />
|
||||
<H3 className="mb-0 mt-2">Personal projects</H3>
|
||||
</div>
|
||||
*/}
|
||||
</div>
|
||||
<Text size="small" className="text-muted text-center mb-0">
|
||||
Pick one to move forward
|
||||
@ -197,15 +306,7 @@ function PurposeStep({ onNext, pro }: { onNext: () => void; pro: boolean }): JSX
|
||||
)
|
||||
}
|
||||
|
||||
function EditorStep({
|
||||
onNext,
|
||||
onCompleted,
|
||||
pro,
|
||||
}: {
|
||||
onNext: () => void
|
||||
onCompleted: () => void
|
||||
pro: boolean
|
||||
}): JSX.Element {
|
||||
function EditorStep({ onCompleted, pro }: { onCompleted: () => void; pro: boolean }): JSX.Element {
|
||||
useEffect(() => {
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_CHOOSE_EDITOR_VIEWED, { tier: pro ? 'pro' : 'free' })
|
||||
}, [pro])
|
||||
@ -287,7 +388,7 @@ function EditorStep({
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="d-flex justify-content-end align-items-center">
|
||||
<Text
|
||||
className="mb-0 text-muted cursor-pointer"
|
||||
size="small"
|
||||
@ -296,16 +397,15 @@ function EditorStep({
|
||||
eventLogger.log(EventName.CODY_ONBOARDING_CHOOSE_EDITOR_SKIPPED, { tier: pro ? 'pro' : 'free' })
|
||||
}}
|
||||
>
|
||||
Skip
|
||||
</Text>
|
||||
<Text className="mb-0 text-muted" size="small">
|
||||
Pick one to move forward
|
||||
Skip for now
|
||||
</Text>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/* TODO(naman): remove after PR feedback
|
||||
|
||||
const WorkIcon = (): JSX.Element => (
|
||||
<svg width="60" height="60" viewBox="0 0 75 75" fill="none">
|
||||
<path
|
||||
@ -363,3 +463,4 @@ const PersonalIcon = (): JSX.Element => (
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
*/
|
||||
|
||||
@ -47,6 +47,7 @@ export function JetBrainsInstructions({
|
||||
<ButtonLink
|
||||
variant="primary"
|
||||
to="https://marketplace.visualstudio.com/items?itemName=sourcegraph.cody-ai"
|
||||
target="_blank"
|
||||
>
|
||||
Open Marketplace
|
||||
</ButtonLink>
|
||||
|
||||
@ -3,6 +3,7 @@ import type { ReactElement } from 'react'
|
||||
|
||||
import { mdiTrendingUp } from '@mdi/js'
|
||||
import classNames from 'classnames'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useQuery } from '@sourcegraph/http-client'
|
||||
import { Icon, PageHeader, Button, H1, H2, H3, Text, ButtonLink, useSearchParameters, H4 } from '@sourcegraph/wildcard'
|
||||
@ -46,6 +47,14 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
const [showUpgradeToPro, setShowUpgradeToPro] = useState<boolean>(false)
|
||||
const [showCancelPro, setShowCancelPro] = useState<boolean>(false)
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
if (!!data && !data?.currentUser) {
|
||||
navigate('/sign-in?returnTo=/cody/subscription')
|
||||
}
|
||||
}, [data, navigate])
|
||||
|
||||
if (!isCodyEnabled() || !isSourcegraphDotCom || !isEnabled || !data?.currentUser || !authenticatedUser) {
|
||||
return null
|
||||
}
|
||||
@ -225,6 +234,8 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
className="flex-1 mt-3"
|
||||
variant="secondary"
|
||||
outline={true}
|
||||
to="https://sourcegraph.com/contact/request-info?utm_source=cody_subscription_page"
|
||||
target="_blank"
|
||||
onClick={() => {
|
||||
eventLogger.log(EventName.CODY_SUBSCRIPTION_PLAN_CLICKED, { tier: 'enterprise' })
|
||||
}}
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
position: relative;
|
||||
text-align: center;
|
||||
transition: all 0.15s linear;
|
||||
background-color: var(--violet-04) !important;
|
||||
border-color: var(--violet-04) !important;
|
||||
background-color: #0b70db !important;
|
||||
border-color: #0b70db !important;
|
||||
color: var(--white);
|
||||
border-radius: 0.3125rem;
|
||||
border-style: solid;
|
||||
@ -19,13 +19,13 @@
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--violet-05) !important;
|
||||
border-color: var(--violet-05) !important;
|
||||
background-color: #0864c6 !important;
|
||||
border-color: #0864c6 !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--violet-05) !important;
|
||||
border-color: var(--violet-05) !important;
|
||||
background-color: #0864c6 !important;
|
||||
border-color: #0864c6 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: var(--violet-04);
|
||||
border-color: #0b70db;
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@
|
||||
|
||||
:global(.hs-input)[type='checkbox']:checked,
|
||||
:global(.hs-input)[type='radio']:checked {
|
||||
accent-color: var(--violet-04);
|
||||
accent-color: #0b70db;
|
||||
}
|
||||
|
||||
:global(.actions) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user