chore: improve button a11y with storybook (#2938)

This commit is contained in:
Matti Nannt
2024-08-01 14:15:03 +02:00
committed by GitHub
parent a1d3fe5e06
commit ae266810c2
118 changed files with 3409 additions and 4716 deletions

View File

@@ -13,8 +13,8 @@
"dependencies": {
"@formbricks/js": "workspace:*",
"@formbricks/ui": "workspace:*",
"lucide-react": "^0.397.0",
"next": "14.2.4",
"lucide-react": "^0.418.0",
"next": "14.2.5",
"react": "18.3.1",
"react-dom": "18.3.1"
},

View File

@@ -12,34 +12,34 @@
},
"browserslist": "defaults, not ie <= 11",
"dependencies": {
"@algolia/autocomplete-core": "^1.17.2",
"@algolia/autocomplete-core": "^1.17.4",
"@calcom/embed-react": "^1.5.0",
"@docsearch/css": "3",
"@docsearch/react": "^3.6.0",
"@docsearch/react": "^3.6.1",
"@formbricks/lib": "workspace:*",
"@formbricks/types": "workspace:*",
"@formbricks/ui": "workspace:*",
"@headlessui/react": "^2.1.1",
"@headlessui/react": "^2.1.2",
"@headlessui/tailwindcss": "^0.2.1",
"@mapbox/rehype-prism": "^0.9.0",
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
"@next/mdx": "14.2.4",
"@next/mdx": "14.2.5",
"@paralleldrive/cuid2": "^2.2.2",
"@sindresorhus/slugify": "^2.2.1",
"@tailwindcss/typography": "^0.5.13",
"acorn": "^8.12.0",
"acorn": "^8.12.1",
"autoprefixer": "^10.4.19",
"clsx": "^2.1.1",
"fast-glob": "^3.3.2",
"flexsearch": "^0.7.43",
"framer-motion": "11.2.12",
"framer-motion": "11.3.20",
"lottie-web": "^5.12.2",
"lucide": "^0.397.0",
"lucide-react": "^0.397.0",
"lucide": "^0.418.0",
"lucide-react": "^0.418.0",
"mdast-util-to-string": "^4.0.0",
"mdx-annotations": "^0.1.4",
"next": "14.2.4",
"next": "14.2.5",
"next-plausible": "^3.12.0",
"next-seo": "^6.5.0",
"next-sitemap": "^4.2.3",
@@ -59,7 +59,7 @@
"sharp": "^0.33.4",
"shiki": "^0.14.7",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.4.4",
"tailwindcss": "^3.4.7",
"unist-util-filter": "^5.0.1",
"unist-util-visit": "^5.0.0",
"zustand": "^4.5.4"

View File

@@ -21,6 +21,7 @@ const config: StorybookConfig = {
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@chromatic-com/storybook"),
getAbsolutePath("@storybook/addon-interactions"),
getAbsolutePath("@storybook/addon-a11y"),
],
framework: {
name: getAbsolutePath("@storybook/react-vite"),

View File

@@ -12,29 +12,30 @@
},
"dependencies": {
"@formbricks/ui": "workspace:*",
"eslint-plugin-react-refresh": "^0.4.7",
"eslint-plugin-react-refresh": "^0.4.9",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.5.0",
"@chromatic-com/storybook": "^1.6.1",
"@formbricks/config-typescript": "workspace:*",
"@storybook/addon-essentials": "^8.1.10",
"@storybook/addon-interactions": "^8.1.10",
"@storybook/addon-links": "^8.1.10",
"@storybook/addon-onboarding": "^8.1.10",
"@storybook/blocks": "^8.1.10",
"@storybook/react": "^8.1.10",
"@storybook/react-vite": "^8.1.10",
"@storybook/test": "^8.1.10",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@storybook/addon-a11y": "^8.2.7",
"@storybook/addon-essentials": "^8.2.7",
"@storybook/addon-interactions": "^8.2.7",
"@storybook/addon-links": "^8.2.7",
"@storybook/addon-onboarding": "^8.2.7",
"@storybook/blocks": "^8.2.7",
"@storybook/react": "^8.2.7",
"@storybook/react-vite": "^8.2.7",
"@storybook/test": "^8.2.7",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vitejs/plugin-react": "^4.3.1",
"esbuild": "^0.21.5",
"esbuild": "^0.23.0",
"eslint-plugin-storybook": "^0.8.0",
"prop-types": "^15.8.1",
"storybook": "^8.1.10",
"tsup": "^8.1.0",
"vite": "^5.3.1"
"storybook": "^8.2.7",
"tsup": "^8.2.3",
"vite": "^5.3.5"
}
}

View File

@@ -83,7 +83,7 @@ export const ConnectWithFormbricks = ({
<Button
id="finishOnboarding"
className="text-slate-400 hover:text-slate-700"
variant={widgetSetupCompleted ? "darkCTA" : "minimal"}
variant={widgetSetupCompleted ? "primary" : "minimal"}
onClick={handleFinishOnboarding}
EndIcon={ArrowRight}>
{widgetSetupCompleted ? "Finish Onboarding" : "I don't know how to do it"}

View File

@@ -105,11 +105,7 @@ export const InviteOrganizationMember = ({ organization, environmentId }: Invite
}}>
Not now
</Button>
<Button
id="onboarding-inapp-invite-send-invite"
variant="darkCTA"
type={"submit"}
loading={isSubmitting}>
<Button id="onboarding-inapp-invite-send-invite" type={"submit"} loading={isSubmitting}>
Invite
</Button>
</div>

View File

@@ -136,7 +136,7 @@ export const OnboardingSetupInstructions = ({
<div className="mt-4 flex justify-between space-x-2">
<Button
id="onboarding-inapp-connect-copy-code"
variant={widgetSetupCompleted ? "secondary" : "darkCTA"}
variant={widgetSetupCompleted ? "secondary" : "primary"}
onClick={() => {
navigator.clipboard.writeText(
channel === "app" ? htmlSnippetForAppSurveys : htmlSnippetForWebsiteSurveys

View File

@@ -140,7 +140,7 @@ export const ProductSettings = ({
/>
<div className="flex w-full justify-end">
<Button variant="darkCTA" loading={isSubmitting} type="submit">
<Button loading={isSubmitting} type="submit">
Next
</Button>
</div>

View File

@@ -249,7 +249,7 @@ export const CreateNewActionTab = ({
<Button type="button" variant="minimal" onClick={resetAllStates}>
Cancel
</Button>
<Button variant="darkCTA" type="submit" loading={isSubmitting}>
<Button type="submit" loading={isSubmitting}>
Create action
</Button>
</div>

View File

@@ -224,7 +224,7 @@ export const QuestionMenu = ({
text="Changing the question type will remove the logic conditions from this question"
buttonText="Change anyway"
onConfirm={onConfirm}
buttonVariant="darkCTA"
buttonVariant="primary"
/>
</div>
);

View File

@@ -317,7 +317,6 @@ export const SurveyMenuBar = ({
{localSurvey.status !== "draft" && (
<Button
disabled={disableSave}
variant="darkCTA"
className="mr-3"
loading={isSurveySaving}
onClick={() => handleSaveAndGoBack()}>
@@ -326,7 +325,6 @@ export const SurveyMenuBar = ({
)}
{localSurvey.status === "draft" && audiencePrompt && !isLinkSurvey && (
<Button
variant="darkCTA"
onClick={() => {
setAudiencePrompt(false);
setActiveId("settings");
@@ -339,7 +337,6 @@ export const SurveyMenuBar = ({
{localSurvey.status === "draft" && (!audiencePrompt || isLinkSurvey) && (
<Button
disabled={isSurveySaving || containsEmptyTriggers}
variant="darkCTA"
loading={isSurveyPublishing}
onClick={handleSurveyPublish}>
Publish

View File

@@ -71,7 +71,7 @@ export const UpdateQuestionId = ({
disabled={localSurvey.status !== "draft" && !question.isDraft}
className={`h-10 ${isInputInvalid ? "border-red-300 focus:border-red-300" : ""}`}
/>
<Button variant="darkCTA" size="sm" onClick={saveAction} disabled={isButtonDisabled()}>
<Button size="sm" onClick={saveAction} disabled={isButtonDisabled()}>
Save
</Button>
</div>

View File

@@ -24,10 +24,7 @@ export const ConfirmationPage = ({ environmentId }: ConfirmationPageProps) => {
Thanks a lot for upgrading your Formbricks subscription.
</p>
</div>
<Button
variant="darkCTA"
className="w-full justify-center"
href={`/environments/${environmentId}/settings/billing`}>
<Button className="w-full justify-center" href={`/environments/${environmentId}/settings/billing`}>
Back to billing overview
</Button>
</div>

View File

@@ -100,7 +100,7 @@ export const AttributeSettingsTab = async ({ attributeClass, setOpen }: Attribut
</div>
{attributeClass.type !== "automatic" && (
<div className="flex space-x-2">
<Button type="submit" variant="darkCTA" loading={isAttributeBeingSubmitted}>
<Button type="submit" loading={isAttributeBeingSubmitted}>
Save changes
</Button>
</div>

View File

@@ -117,7 +117,7 @@ export const BasicCreateSegmentModal = ({
return (
<>
<Button variant="darkCTA" size="sm" onClick={() => setOpen(true)} EndIcon={PlusIcon}>
<Button size="sm" onClick={() => setOpen(true)} EndIcon={PlusIcon}>
Create segment
</Button>
@@ -239,7 +239,6 @@ export const BasicCreateSegmentModal = ({
Cancel
</Button>
<Button
variant="darkCTA"
type="submit"
loading={isCreatingSegment}
disabled={isSaveDisabled}

View File

@@ -236,7 +236,6 @@ export const BasicSegmentSettings = ({
Delete
</Button>
<Button
variant="darkCTA"
type="submit"
loading={isUpdatingSegment}
onClick={() => {

View File

@@ -224,7 +224,7 @@ export const ActionSettingsTab = ({
{actionClass.type !== "automatic" && (
<div className="flex space-x-2">
<Button type="submit" variant="darkCTA" loading={isUpdatingAction}>
<Button type="submit" loading={isUpdatingAction}>
Save changes
</Button>
</div>

View File

@@ -27,12 +27,7 @@ export const AddActionModal = ({ environmentId, actionClasses }: AddActionModalP
return (
<>
<Button
variant="darkCTA"
size="sm"
loading={isLoading}
onClick={() => setOpen(true)}
EndIcon={PlusIcon}>
<Button size="sm" loading={isLoading} onClick={() => setOpen(true)} EndIcon={PlusIcon}>
Add Action
</Button>
<Modal open={open} setOpen={setOpen} noPadding closeOnOutsideClick={false} restrictOverflow>

View File

@@ -170,7 +170,7 @@ export const MainNavigation = ({
isHidden: isViewer,
},
],
[environment.id, pathname, isViewer]
[environment.id, pathname, product?.config.channel, isViewer]
);
const dropdownNavigation = [
@@ -234,6 +234,7 @@ export const MainNavigation = ({
</Link>
)}
<Button
variant="minimal"
size="icon"
tooltipSide="right"
onClick={toggleSidebar}

View File

@@ -79,8 +79,8 @@ export const UrlShortenerForm = ({ webAppUrl }: { webAppUrl: string }) => {
onBlur={handleUrlValidation}
/>
<Button
variant="secondary"
disabled={watch("url") === ""}
variant="darkCTA"
size="sm"
type="submit"
loading={isSubmitting}>

View File

@@ -354,9 +354,7 @@ export const AddIntegrationModal = ({
</Button>
)}
<Button variant="darkCTA" type="submit">
Save
</Button>
<Button type="submit">Save</Button>
</div>
</div>
</div>

View File

@@ -83,8 +83,7 @@ export const ManageIntegration = (props: ManageIntegrationProps) => {
onClick={() => {
setDefaultValues(null);
handleModal(true);
}}
variant="darkCTA">
}}>
Link new table
</Button>
</div>

View File

@@ -288,7 +288,7 @@ export const AddIntegrationModal = ({
Cancel
</Button>
)}
<Button variant="darkCTA" type="submit" loading={isLinkingSheet}>
<Button type="submit" loading={isLinkingSheet}>
{selectedIntegration ? "Update" : "Link Sheet"}
</Button>
</div>

View File

@@ -67,7 +67,6 @@ export const ManageIntegration = ({
<span className="text-slate-500">Connected with {googleSheetIntegration.config.email}</span>
</div>
<Button
variant="darkCTA"
onClick={() => {
setSelectedIntegration(null);
setOpenAddIntegrationModal(true);

View File

@@ -6,9 +6,7 @@ const Loading = () => {
<div className="mt-6 p-6">
<GoBackButton />
<div className="mb-6 text-right">
<Button
variant="darkCTA"
className="pointer-events-none animate-pulse cursor-not-allowed select-none bg-slate-200">
<Button className="pointer-events-none animate-pulse cursor-not-allowed select-none bg-slate-200">
Link new sheet
</Button>
</div>

View File

@@ -518,7 +518,6 @@ export const AddIntegrationModal = ({
</Button>
)}
<Button
variant="darkCTA"
type="submit"
loading={isLinkingDatabase}
disabled={mapping.filter((m) => m.error).length > 0}>

View File

@@ -63,7 +63,6 @@ export const ManageIntegration = ({
</span>
</div>
<Button
variant="darkCTA"
onClick={() => {
setSelectedIntegration(null);
setOpenAddIntegrationModal(true);

View File

@@ -6,9 +6,7 @@ const Loading = () => {
<div className="mt-6 p-6">
<GoBackButton />
<div className="mb-6 text-right">
<Button
variant="darkCTA"
className="pointer-events-none animate-pulse cursor-not-allowed select-none bg-slate-200">
<Button className="pointer-events-none animate-pulse cursor-not-allowed select-none bg-slate-200">
Link new database
</Button>
</div>

View File

@@ -284,7 +284,7 @@ export const AddChannelMappingModal = ({
Cancel
</Button>
)}
<Button variant="darkCTA" type="submit" loading={isLinkingChannel}>
<Button type="submit" loading={isLinkingChannel}>
{selectedIntegration ? "Update" : "Link Channel"}
</Button>
</div>

View File

@@ -65,7 +65,6 @@ export const ManageIntegration = ({
<span className="text-slate-500">Connected with {slackIntegration.config.key.team.name}</span>
</div>
<Button
variant="darkCTA"
onClick={() => {
refreshChannels();
setSelectedIntegration(null);

View File

@@ -17,7 +17,6 @@ export const AddWebhookButton = ({ environment, surveys }: AddWebhookButtonProps
return (
<>
<Button
variant="darkCTA"
size="sm"
onClick={() => {
setAddWebhookModalOpen(true);

View File

@@ -228,7 +228,7 @@ export const AddWebhookModal = ({ environmentId, surveys, open, setOpen }: AddWe
}}>
Cancel
</Button>
<Button variant="darkCTA" type="submit" loading={creatingWebhook}>
<Button type="submit" loading={creatingWebhook}>
Add Webhook
</Button>
</div>

View File

@@ -218,7 +218,7 @@ export const WebhookSettingsTab = ({ environmentId, webhook, surveys, setOpen }:
</div>
<div className="flex space-x-2">
<Button type="submit" variant="darkCTA" loading={isUpdatingWebhook}>
<Button type="submit" loading={isUpdatingWebhook}>
Save changes
</Button>
</div>

View File

@@ -63,9 +63,7 @@ export const AddApiKeyModal = ({ open, setOpen, onSubmit }: MemberModalProps) =>
}}>
Cancel
</Button>
<Button variant="darkCTA" type="submit">
Add API Key
</Button>
<Button type="submit">Add API Key</Button>
</div>
</div>
</form>

View File

@@ -117,7 +117,6 @@ export const EditAPIKeys = ({
<div>
<Button
variant="darkCTA"
size="sm"
disabled={environmentId !== environmentTypeId}
onClick={() => {

View File

@@ -90,12 +90,7 @@ export const EditProductNameForm: React.FC<EditProductNameProps> = ({
)}
/>
<Button
type="submit"
variant="darkCTA"
size="sm"
loading={isSubmitting}
disabled={isSubmitting || !isDirty}>
<Button type="submit" size="sm" loading={isSubmitting} disabled={isSubmitting || !isDirty}>
Update
</Button>
</form>

View File

@@ -78,7 +78,6 @@ export const EditWaitingTimeForm: React.FC<EditWaitingTimeProps> = ({ product })
<Button
type="submit"
variant="darkCTA"
size="sm"
className="w-fit"
loading={isSubmitting}

View File

@@ -169,7 +169,7 @@ export const EditLogo = ({ product, environmentId, isViewer }: EditLogoProps) =>
</>
)}
{logoUrl && (
<Button onClick={saveChanges} disabled={isLoading || isViewer} variant="darkCTA" size="sm">
<Button onClick={saveChanges} disabled={isLoading || isViewer} size="sm">
{isEditing ? "Save" : "Edit"}
</Button>
)}

View File

@@ -182,7 +182,7 @@ export const EditPlacementForm = ({ product }: EditPlacementProps) => {
</>
)}
<Button variant="darkCTA" className="mt-4 w-fit" size="sm" loading={isSubmitting}>
<Button className="mt-4 w-fit" size="sm" loading={isSubmitting}>
Save
</Button>
</form>

View File

@@ -200,7 +200,7 @@ export const ThemeStyling = ({ product, environmentId, colors, isUnsplashConfigu
</div>
<div className="mt-4 flex items-center gap-2">
<Button variant="darkCTA" size="sm" type="submit">
<Button size="sm" type="submit">
Save
</Button>
<Button

View File

@@ -199,9 +199,7 @@ const Loading = () => {
<div className={cn("absolute bottom-3 h-16 w-16 rounded bg-slate-700 sm:right-3")}></div>
</div>
</div>
<Button
variant="darkCTA"
className="pointer-events-none mt-4 animate-pulse cursor-not-allowed select-none bg-slate-200">
<Button className="pointer-events-none mt-4 animate-pulse cursor-not-allowed select-none bg-slate-200">
Loading
</Button>
</div>

View File

@@ -12,7 +12,7 @@ export const EditAvatar = ({ session }) => {
<div>
<ProfileAvatar userId={session.user.id} imageUrl={session.user.imageUrl} />
<Button className="mt-4" variant="darkCTA" size="sm" disabled={true}>
<Button className="mt-4" size="sm" disabled={true}>
Upload Image
</Button>
</div>

View File

@@ -145,9 +145,7 @@ export const DisableTwoFactorModal = ({ open, setOpen }: TDisableTwoFactorModalP
Cancel
</Button>
<Button variant="darkCTA" size="sm">
Disable
</Button>
<Button size="sm">Disable</Button>
</div>
</div>
</form>

View File

@@ -67,7 +67,6 @@ export const EditProfileDetailsForm = ({ user }: { user: TUser }) => {
<Button
type="submit"
variant="darkCTA"
className="mt-4"
size="sm"
loading={isSubmitting}

View File

@@ -100,9 +100,7 @@ const ConfirmPasswordForm = ({
Cancel
</Button>
<Button variant="darkCTA" size="sm">
Confirm
</Button>
<Button size="sm">Confirm</Button>
</div>
</form>
</div>
@@ -134,7 +132,7 @@ const ScanQRCode = ({ dataUri, secret, setCurrentStep, setOpen }: TScanQRCodePro
Cancel
</Button>
<Button variant="darkCTA" size="sm" onClick={() => setCurrentStep("enterCode")}>
<Button size="sm" onClick={() => setCurrentStep("enterCode")}>
Next
</Button>
</div>
@@ -207,9 +205,7 @@ const EnterCode = ({ setCurrentStep, setOpen, refreshData }: TEnableCodeProps) =
Cancel
</Button>
<Button variant="darkCTA" size="sm">
Confirm
</Button>
<Button size="sm">Confirm</Button>
</div>
</form>
</div>
@@ -259,7 +255,6 @@ const DisplayBackupCodes = ({ backupCodes, setOpen }: TDisplayBackupCodesProps)
</Button>
<Button
variant="darkCTA"
size="sm"
onClick={() => {
navigator.clipboard.writeText(backupCodes.map((code) => formatBackupCode(code)).join("\n"));
@@ -269,7 +264,6 @@ const DisplayBackupCodes = ({ backupCodes, setOpen }: TDisplayBackupCodesProps)
</Button>
<Button
variant="darkCTA"
size="sm"
onClick={() => {
handleDownloadBackupCode();

View File

@@ -170,10 +170,7 @@ const Page = async ({ params }) => {
No call needed, no strings attached: Request a free 30-day trial license to test all features
by filling out this form:
</p>
<Button
variant="darkCTA"
href="https://app.formbricks.com/s/clvupq3y205i5yrm3sm9v1xt5"
target="_blank">
<Button href="https://app.formbricks.com/s/clvupq3y205i5yrm3sm9v1xt5" target="_blank">
Request 30-day Trial License
</Button>
<p className="mt-2 text-xs text-slate-500">No credit card. No sales call. Just test it :)</p>

View File

@@ -106,7 +106,7 @@ export const BulkInviteTab = ({ setOpen, onSubmit, canDoRoleManagement }: BulkIn
Download CSV template
</Button>
</Link>
<Button onClick={onImport} size="sm" variant="darkCTA" disabled={!csvFile}>
<Button onClick={onImport} size="sm" disabled={!csvFile}>
Import
</Button>
</div>

View File

@@ -96,7 +96,6 @@ export const OrganizationActions = ({
{!isInviteDisabled && isAdminOrOwner && (
<Button
size="sm"
variant="darkCTA"
onClick={() => {
setAddMemberModalOpen(true);
}}>

View File

@@ -92,7 +92,6 @@ export const EditOrganizationName = ({ organization, membershipRole }: EditOrgan
<Button
type="submit"
className="mt-4"
variant="darkCTA"
size="sm"
loading={isUpdatingOrganization}
disabled={isOrganizationNameInputEmpty || currentOrganizationName === previousOrganizationName}>

View File

@@ -86,7 +86,6 @@ export const EditOrganizationNameForm = ({ organization, membershipRole }: EditO
<Button
type="submit"
className="mt-4"
variant="darkCTA"
size="sm"
loading={isSubmitting}
disabled={isSubmitting || !isDirty}>

View File

@@ -93,7 +93,7 @@ export const IndividualInviteTab = ({
}}>
Cancel
</Button>
<Button variant="darkCTA" type="submit" size="sm" loading={isSubmitting}>
<Button type="submit" size="sm" loading={isSubmitting}>
Send Invitation
</Button>
</div>

View File

@@ -23,7 +23,7 @@ export const EmptyAppSurveys = ({ environment, surveyType = "app" }: TEmptyAppSu
</p>
<Link className="mt-2" href={`/environments/${environment.id}/product/${surveyType}-connection`}>
<Button variant="darkCTA" size="sm" className="flex w-[120px] justify-center">
<Button size="sm" className="flex w-[120px] justify-center">
Connect
</Button>
</Link>

View File

@@ -65,7 +65,7 @@ export const ShareSurveyResults = ({
Unpublish
</Button>
<Button variant="darkCTA" className="text-center" href={surveyUrl} target="_blank">
<Button className="text-center" href={surveyUrl} target="_blank">
View site
</Button>
</div>
@@ -84,11 +84,7 @@ export const ShareSurveyResults = ({
have the link.
</p>
</div>
<Button
type="submit"
variant="darkCTA"
className="h-full text-center"
onClick={() => handlePublish()}>
<Button type="submit" className="h-full text-center" onClick={() => handlePublish()}>
Publish to public web
</Button>
</div>

View File

@@ -48,7 +48,6 @@ export const SurveyAnalysisCTA = ({
)}
{!isViewer && (
<Button
variant="darkCTA"
size="sm"
className="h-full w-full px-3"
href={`/environments/${environment.id}/surveys/${survey.id}/edit`}>

View File

@@ -78,7 +78,6 @@ export const EmailTab = ({ surveyId, email }: EmailTabProps) => {
</>
)}
<Button
variant="darkCTA"
title="view embed code for email"
aria-label="view embed code for email"
onClick={() => {

View File

@@ -83,7 +83,6 @@ export const PanelInfoView = ({ handleInitialPageButton }: PanelInfoViewProps) =
</p>
</div>
<Button
variant="darkCTA"
className="justify-center"
href="https://formbricks.com/docs/link-surveys/market-research-panel"
target="_blank">

View File

@@ -21,7 +21,6 @@ export const WebpageTab = ({ surveyUrl }) => {
<div className="flex justify-between">
<div></div>
<Button
variant="darkCTA"
title="Embed survey in your website"
aria-label="Embed survey in your website"
onClick={() => {

View File

@@ -300,7 +300,7 @@ export const CustomFilter = ({ survey }: CustomFilterProps) => {
{isDatePickerOpen && (
<div ref={datePickerRef} className="absolute top-full z-50 my-2 rounded-md border bg-white">
<Calendar
initialFocus
autoFocus
mode="range"
defaultMonth={dateRange?.from}
selected={hoveredRange ? hoveredRange : dateRange}

View File

@@ -279,7 +279,7 @@ export const ResponseFilter = ({ survey }: ResponseFilterProps) => {
<Plus width={18} height={18} className="ml-2" />
</Button>
<div className="flex gap-2">
<Button size="sm" variant="darkCTA" onClick={handleApplyFilters}>
<Button size="sm" onClick={handleApplyFilters}>
Apply filters
</Button>
<Button size="sm" variant="minimal" onClick={handleClearAllFilters}>

View File

@@ -64,11 +64,7 @@ const Page = async ({ params, searchParams }: SurveyTemplateProps) => {
const currentProductChannel = product.config.channel ?? null;
const CreateSurveyButton = (
<Button
size="sm"
href={`/environments/${environment.id}/surveys/templates`}
variant="darkCTA"
EndIcon={PlusIcon}>
<Button size="sm" href={`/environments/${environment.id}/surveys/templates`} EndIcon={PlusIcon}>
New survey
</Button>
);

View File

@@ -59,7 +59,7 @@ export const PasswordResetForm = ({}) => {
</div>
<div>
<Button type="submit" variant="darkCTA" className="w-full justify-center" loading={loading}>
<Button type="submit" className="w-full justify-center" loading={loading}>
Reset password
</Button>
<div className="mt-3 text-center">

View File

@@ -92,12 +92,7 @@ export const ResetPasswordForm = () => {
</div>
<div>
<Button
type="submit"
variant="darkCTA"
disabled={!isValid}
className="w-full justify-center"
loading={loading}>
<Button type="submit" disabled={!isValid} className="w-full justify-center" loading={loading}>
Reset password
</Button>
</div>

View File

@@ -210,7 +210,6 @@ export const SigninForm = ({
formRef.current.requestSubmit();
}
}}
variant="darkCTA"
className="w-full justify-center"
loading={loggingIn}>
{totpLogin ? "Submit" : "Login with Email"}

View File

@@ -43,9 +43,7 @@ const Page = async ({ searchParams }) => {
<Button variant="secondary" href="/support">
Contact support
</Button>
<Button variant="darkCTA" href="/">
Go to app
</Button>
<Button href="/">Go to app</Button>
</ContentLayout>
);
} else if (!session) {
@@ -58,9 +56,7 @@ const Page = async ({ searchParams }) => {
href={`/auth/signup?inviteToken=${searchParams.token}&email=${encodedEmail}`}>
Create account
</Button>
<Button variant="darkCTA" href={`/auth/login?callbackUrl=${redirectUrl}&email=${encodedEmail}`}>
Login
</Button>
<Button href={`/auth/login?callbackUrl=${redirectUrl}&email=${encodedEmail}`}>Login</Button>
</ContentLayout>
);
} else if (session.user?.email !== email) {
@@ -71,9 +67,7 @@ const Page = async ({ searchParams }) => {
<Button variant="secondary" href="/support">
Contact support
</Button>
<Button variant="darkCTA" href="/">
Go to app
</Button>
<Button href="/">Go to app</Button>
</ContentLayout>
);
} else {
@@ -100,9 +94,7 @@ const Page = async ({ searchParams }) => {
});
return (
<ContentLayout headline="Youre in 🎉" description="Welcome to the organization.">
<Button variant="darkCTA" href="/">
Go to app
</Button>
<Button href="/">Go to app</Button>
</ContentLayout>
);
}

View File

@@ -16,9 +16,7 @@ const Error = ({ error, reset }: { error: Error; reset: () => void }) => {
<Button variant="secondary" onClick={() => reset()} className="mr-2">
Try again
</Button>
<Button variant="darkCTA" onClick={() => (window.location.href = "/")}>
Go to Dashboard
</Button>
<Button onClick={() => (window.location.href = "/")}>Go to Dashboard</Button>
</div>
</div>
);

View File

@@ -38,7 +38,7 @@ export const SurveyInactive = ({
: descriptions[status]}
</p>
{!(status === "completed" && surveyClosedMessage) && status !== "link invalid" && (
<Button variant="darkCTA" className="mt-2" href="https://formbricks.com">
<Button className="mt-2" href="https://formbricks.com">
Create your own
</Button>
)}

View File

@@ -115,7 +115,7 @@ export const VerifyEmail = ({
onChange={(e) => setEmail(e.target.value)}
onKeyPress={handleKeyPress}
/>
<Button variant="darkCTA" onClick={() => submitEmail(email)} loading={isLoading}>
<Button onClick={() => submitEmail(email)} loading={isLoading}>
Verify
</Button>
</div>

View File

@@ -12,7 +12,7 @@ const NotFound = () => {
<HelpCircleIcon className="h-20 w-20" />,
<h1 className="text-4xl font-bold text-slate-800">Survey not found.</h1>
<p className="text-lg leading-10 text-slate-500">There is no survey with this ID.</p>
<Button variant="darkCTA" className="mt-2" href="https://formbricks.com">
<Button className="mt-2" href="https://formbricks.com">
Create your own
</Button>
</div>

View File

@@ -24,7 +24,7 @@ const Page = () => {
<b>full control over your data.</b> Always.
</p>
</div>
<Button variant="darkCTA" href="/setup/signup" className="mt-6">
<Button href="/setup/signup" className="mt-6">
Get started
</Button>

View File

@@ -108,7 +108,6 @@ export const InviteMembers = ({ IS_SMTP_CONFIGURED, organizationId }: InviteMemb
<div className="space-y-2">
<Button
variant="darkCTA"
className="flex w-80 justify-center"
type="submit"
loading={isSubmitting}

View File

@@ -68,7 +68,6 @@ export const CreateOrganization = () => {
/>
<Button
type="submit"
variant="darkCTA"
className="flex w-80 justify-center"
loading={isSubmitting}
disabled={isSubmitting || organizationName.trim() === ""}>

View File

@@ -34,9 +34,7 @@ export const RemovedFromOrganization = ({ session, isFormbricksCloud }: RemovedF
isFormbricksCloud={isFormbricksCloud}
formbricksLogout={formbricksLogout}
/>
<Button variant="darkCTA" onClick={() => setIsModalOpen(true)}>
Delete account
</Button>
<Button onClick={() => setIsModalOpen(true)}>Delete account</Button>
</div>
);
};

View File

@@ -20,7 +20,6 @@ import { RATE_LIMITING_DISABLED, WEBAPP_URL } from "@formbricks/lib/constants";
export const middleware = async (request: NextRequest) => {
// issue with next auth types & Next 15; let's review when new fixes are available
// @ts-expect-error
const token = await getToken({ req: request });
if (isAuthProtectedRoute(request.nextUrl.pathname) && !token) {

View File

@@ -19,9 +19,12 @@ const getHostname = (url) => {
const nextConfig = {
assetPrefix: process.env.ASSET_PREFIX_URL || undefined,
output: "standalone",
serverExternalPackages: ["@aws-sdk"],
poweredByHeader: false,
experimental: {
serverComponentsExternalPackages: ["@aws-sdk"],
staleTimes: {
dynamic: 0,
},
outputFileTracingIncludes: {
"app/api/packages": ["../../packages/js-core/dist/*", "../../packages/surveys/dist/*"],
},

View File

@@ -26,50 +26,50 @@
"@formbricks/surveys": "workspace:*",
"@formbricks/types": "workspace:*",
"@formbricks/ui": "workspace:*",
"@hookform/resolvers": "^3.6.0",
"@hookform/resolvers": "^3.9.0",
"@json2csv/node": "^7.0.6",
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-collapsible": "^1.1.0",
"@react-email/components": "^0.0.19",
"@sentry/nextjs": "^8.12.0",
"@react-email/components": "^0.0.22",
"@sentry/nextjs": "^8.22.0",
"@vercel/og": "^0.6.2",
"@vercel/speed-insights": "^1.0.12",
"bcryptjs": "^2.4.3",
"dotenv": "^16.4.5",
"encoding": "^0.1.13",
"framer-motion": "11.2.12",
"framer-motion": "11.3.20",
"googleapis": "^140.0.1",
"jiti": "^1.21.6",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"lru-cache": "^10.2.2",
"lucide-react": "^0.397.0",
"mime": "^4.0.3",
"next": "15.0.0-rc.0",
"next-safe-action": "^7.1.3",
"lru-cache": "^11.0.0",
"lucide-react": "^0.418.0",
"mime": "^4.0.4",
"next": "14.2.5",
"next-safe-action": "^7.4.3",
"optional": "^0.1.4",
"otplib": "^12.0.1",
"papaparse": "^5.4.1",
"posthog-js": "^1.141.4",
"posthog-js": "^1.154.0",
"prismjs": "^1.29.0",
"qrcode": "^1.5.3",
"react": "19.0.0-rc-935180c7e0-20240524",
"react-dom": "19.0.0-rc-935180c7e0-20240524",
"react-hook-form": "^7.52.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-hook-form": "^7.52.1",
"react-hot-toast": "^2.4.1",
"redis": "^4.6.14",
"redis": "^4.7.0",
"sharp": "^0.33.4",
"ua-parser-js": "^1.0.38",
"webpack": "^5.92.1",
"webpack": "^5.93.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@formbricks/config-typescript": "workspace:*",
"@formbricks/eslint-config": "workspace:*",
"@neshca/cache-handler": "^1.3.2",
"@neshca/cache-handler": "^1.5.1",
"@types/bcryptjs": "^2.4.6",
"@types/lodash": "^4.17.5",
"@types/markdown-it": "^14.1.1",
"@types/lodash": "^4.17.7",
"@types/markdown-it": "^14.1.2",
"@types/papaparse": "^5.3.14",
"@types/qrcode": "^1.5.5"
}

View File

@@ -32,14 +32,14 @@
"storybook": "turbo run storybook"
},
"devDependencies": {
"@playwright/test": "^1.45.0",
"@playwright/test": "^1.45.3",
"@formbricks/eslint-config": "workspace:*",
"eslint": "^8.57.0",
"husky": "^9.0.11",
"husky": "^9.1.4",
"lint-staged": "^15.2.7",
"rimraf": "^5.0.7",
"tsx": "^4.15.7",
"turbo": "^2.0.5"
"rimraf": "^6.0.1",
"tsx": "^4.16.5",
"turbo": "^2.0.11"
},
"lint-staged": {
"(apps|packages)/**/*.{js,ts,jsx,tsx}": [
@@ -64,7 +64,7 @@
"showDetails": true
},
"dependencies": {
"@changesets/cli": "^2.27.6",
"playwright": "^1.45.0"
"@changesets/cli": "^2.27.7",
"playwright": "^1.45.3"
}
}

View File

@@ -37,8 +37,8 @@
"@formbricks/config-typescript": "workspace:*",
"@formbricks/types": "workspace:*",
"@formbricks/eslint-config": "workspace:*",
"terser": "^5.31.1",
"vite": "^5.3.1",
"terser": "^5.31.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1"
}
}

View File

@@ -3,15 +3,15 @@
"version": "0.0.0",
"private": true,
"devDependencies": {
"@next/eslint-plugin-next": "^14.2.4",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"@next/eslint-plugin-next": "^14.2.5",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vercel/style-guide": "^6.0.0",
"eslint-config-next": "^14.2.4",
"eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "^2.0.4",
"eslint-plugin-react": "7.34.3",
"eslint-config-turbo": "^2.0.11",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7"
"eslint-plugin-react-refresh": "^0.4.9"
}
}

View File

@@ -8,7 +8,7 @@
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"prettier": "^3.3.2",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.5"
}
}

View File

@@ -10,7 +10,7 @@
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.13",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.4"
"postcss": "^8.4.40",
"tailwindcss": "^3.4.7"
}
}

View File

@@ -7,7 +7,7 @@
"clean": "rimraf node_modules dist turbo"
},
"devDependencies": {
"@types/node": "20.14.5",
"@types/node": "22.0.2",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"typescript": "5.4.5"

View File

@@ -44,7 +44,7 @@
"data-migration:segments-cleanup": "ts-node ./data-migrations/20240712123456_segments_cleanup/data-migration.ts"
},
"dependencies": {
"@prisma/client": "^5.16.2",
"@prisma/client": "^5.17.0",
"@prisma/extension-accelerate": "^1.1.0",
"dotenv-cli": "^7.4.2"
},
@@ -53,7 +53,7 @@
"@formbricks/types": "workspace:*",
"@paralleldrive/cuid2": "^2.2.2",
"@formbricks/eslint-config": "workspace:*",
"prisma": "^5.16.2",
"prisma": "^5.17.0",
"prisma-dbml-generator": "^0.12.0",
"prisma-json-types-generator": "^3.0.4",
"ts-node": "^10.9.2",

View File

@@ -125,8 +125,7 @@ export function CreateSegmentModal({
onClick={() => {
setOpen(true);
}}
size="sm"
variant="darkCTA">
size="sm">
Create segment
</Button>
@@ -245,8 +244,7 @@ export function CreateSegmentModal({
onClick={() => {
handleCreateSegment();
}}
type="submit"
variant="darkCTA">
type="submit">
Create segment
</Button>
</div>

View File

@@ -229,8 +229,7 @@ export function SegmentSettings({
onClick={() => {
handleUpdateSegment();
}}
type="submit"
variant="darkCTA">
type="submit">
Save changes
</Button>

View File

@@ -34,7 +34,7 @@ export function DefaultLanguageSelect({
onConfirm: () => {
handleDefaultLanguageChange(languageCode);
},
buttonVariant: "darkCTA",
buttonVariant: "primary",
});
}}
value={`${defaultLanguage?.code}`}>

View File

@@ -235,7 +235,7 @@ const EditSaveButtons: React.FC<{
}> = ({ isEditing, onEdit, onSave, onCancel }) =>
isEditing ? (
<div className="flex gap-4">
<Button onClick={onSave} size="sm" variant="darkCTA">
<Button onClick={onSave} size="sm">
Save changes
</Button>
<Button onClick={onCancel} size="sm" variant="minimal">
@@ -243,7 +243,7 @@ const EditSaveButtons: React.FC<{
</Button>
</div>
) : (
<Button className="w-fit" onClick={onEdit} size="sm" variant="darkCTA">
<Button className="w-fit" onClick={onEdit} size="sm">
Edit languages
</Button>
);

View File

@@ -34,7 +34,7 @@ export interface ConfirmationModalProps {
open: boolean;
title: string;
buttonText: string;
buttonVariant?: "darkCTA" | "warn";
buttonVariant?: "primary" | "warn";
onConfirm: () => void;
}

View File

@@ -23,16 +23,16 @@
"@formbricks/database": "workspace:*",
"@formbricks/lib": "workspace:*",
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-collapsible": "^1.0.3",
"https-proxy-agent": "^7.0.4",
"lucide-react": "^0.395.0",
"next": "^14.2.4",
"@radix-ui/react-collapsible": "^1.1.0",
"https-proxy-agent": "^7.0.5",
"lucide-react": "^0.418.0",
"next": "^14.2.5",
"next-auth": "^4.24.7",
"node-fetch": "^3.3.2",
"react-hook-form": "^7.52.0",
"react-hook-form": "^7.52.1",
"react-hot-toast": "^2.4.1",
"server-only": "^0.0.1",
"stripe": "^15.12.0",
"stripe": "^16.5.0",
"zod": "^3.23.8"
}
}

View File

@@ -12,11 +12,11 @@
"@formbricks/lib": "workspace:*",
"@formbricks/types": "workspace:*",
"@formbricks/ui": "workspace:*",
"@react-email/components": "^0.0.19",
"@react-email/render": "^0.0.15",
"lucide-react": "^0.395.0",
"nodemailer": "^6.9.13",
"react-email": "^2.1.4"
"@react-email/components": "^0.0.22",
"@react-email/render": "^0.0.17",
"lucide-react": "^0.418.0",
"nodemailer": "^6.9.14",
"react-email": "^2.1.6"
},
"devDependencies": {
"@types/nodemailer": "^6.4.15",

View File

@@ -59,8 +59,8 @@
"@formbricks/config-typescript": "workspace:*",
"@formbricks/types": "workspace:*",
"@formbricks/eslint-config": "workspace:*",
"terser": "^5.31.1",
"vite": "^5.3.1",
"terser": "^5.31.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1"
}
}

View File

@@ -55,8 +55,8 @@
"@formbricks/config-typescript": "workspace:*",
"@formbricks/eslint-config": "workspace:*",
"@formbricks/types": "workspace:*",
"terser": "^5.31.1",
"vite": "^5.3.1",
"terser": "^5.31.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1"
},
"peerDependencies": {

View File

@@ -27,11 +27,11 @@ export const getRoleBasedSchema = <T extends z.ZodRawShape>(
return typeof data === "boolean" && data === true ? schema.strict() : data;
};
export const formatErrors = (errors: ZodIssue[]) => {
export const formatErrors = (issues: ZodIssue[]): Record<string, { _errors: string[] }> => {
return {
...errors.reduce((acc, error) => {
acc[error.path.join(".")] = {
_errors: [error.message],
...issues.reduce((acc, issue) => {
acc[issue.path.join(".")] = {
_errors: [issue.message],
};
return acc;
}, {}),
@@ -56,6 +56,7 @@ export const checkAuthorization = async <T extends z.ZodRawShape>({
const resultSchema = getRoleBasedSchema(schema, role, ...rules);
const parsedResult = resultSchema.safeParse(data);
if (!parsedResult.success) {
// @ts-expect-error -- TODO: match dynamic next-safe-action types
return returnValidationErrors(resultSchema, formatErrors(parsedResult.error.issues));
}
} else {

View File

@@ -168,7 +168,7 @@ export const CUSTOMER_IO_SITE_ID = env.CUSTOMER_IO_SITE_ID;
export const CUSTOMER_IO_API_KEY = env.CUSTOMER_IO_API_KEY;
export const UNSPLASH_ACCESS_KEY = env.UNSPLASH_ACCESS_KEY;
export const STRIPE_API_VERSION = "2024-04-10";
export const STRIPE_API_VERSION = "2024-06-20";
// Maximum number of attribute classes allowed:
export const MAX_ATTRIBUTE_CLASSES_PER_ENVIRONMENT = 150 as const;

View File

@@ -14,14 +14,14 @@
"test": "dotenv -e ../../.env -- vitest run"
},
"dependencies": {
"@aws-sdk/client-s3": "3.600.0",
"@aws-sdk/s3-presigned-post": "3.600.0",
"@aws-sdk/s3-request-presigner": "3.600.0",
"@aws-sdk/client-s3": "3.621.0",
"@aws-sdk/s3-presigned-post": "3.621.0",
"@aws-sdk/s3-request-presigner": "3.621.0",
"@formbricks/api": "*",
"@formbricks/database": "*",
"@formbricks/types": "*",
"@paralleldrive/cuid2": "^2.2.2",
"@t3-oss/env-nextjs": "^0.10.1",
"@t3-oss/env-nextjs": "^0.11.0",
"@ungap/structured-clone": "^1.2.0",
"aws-crt": "^1.21.3",
"date-fns": "^3.6.0",
@@ -33,7 +33,7 @@
"posthog-node": "^4.0.1",
"server-only": "^0.0.1",
"superjson": "^2.2.1",
"tailwind-merge": "^2.3.0"
"tailwind-merge": "^2.4.0"
},
"devDependencies": {
"@formbricks/config-typescript": "workspace:*",
@@ -43,7 +43,7 @@
"dotenv": "^16.4.5",
"@formbricks/eslint-config": "workspace:*",
"ts-node": "^10.9.2",
"vitest": "^1.6.0",
"vitest-mock-extended": "^1.3.1"
"vitest": "^2.0.5",
"vitest-mock-extended": "^2.0.0"
}
}

View File

@@ -41,17 +41,17 @@
"@formbricks/eslint-config": "workspace:*",
"@formbricks/lib": "workspace:*",
"@formbricks/types": "workspace:*",
"@preact/preset-vite": "^2.8.2",
"@preact/preset-vite": "^2.9.0",
"autoprefixer": "^10.4.19",
"concurrently": "8.2.2",
"isomorphic-dompurify": "^2.12.0",
"postcss": "^8.4.38",
"preact": "^10.22.0",
"isomorphic-dompurify": "^2.14.0",
"postcss": "^8.4.40",
"preact": "^10.23.1",
"react-date-picker": "^11.0.0",
"serve": "14.2.3",
"tailwindcss": "^3.4.4",
"terser": "^5.31.1",
"vite": "^5.3.1",
"tailwindcss": "^3.4.7",
"terser": "^5.31.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1",
"vite-tsconfig-paths": "^4.3.2"
}

View File

@@ -34,7 +34,6 @@ export const AlertDialog = ({
{declineBtnLabel || "Discard"}
</Button>
<Button
variant="darkCTA"
onClick={() => {
if (onConfirm) {
onConfirm();

View File

@@ -7,7 +7,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../Too
type SVGComponent = React.FunctionComponent<React.SVGProps<SVGSVGElement>> | LucideIcon;
export type ButtonBaseProps = {
variant?: "highlight" | "primary" | "secondary" | "minimal" | "warn" | "alert" | "darkCTA";
variant?: "highlight" | "primary" | "secondary" | "minimal" | "warn" | "alert";
size?: "base" | "sm" | "lg" | "fab" | "icon";
loading?: boolean;
disabled?: boolean;
@@ -79,8 +79,8 @@ export const Button: React.ForwardRefExoticComponent<
: "text-white bg-brand-dark focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-900 transition ease-in-out delay-50 hover:scale-105"),
variant === "primary" &&
(disabled
? "border border-transparent bg-slate-400 text-white"
: "text-white bg-brand-dark hover:bg-brand focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-900"),
? "text-slate-400 dark:text-slate-500 bg-slate-200 dark:bg-slate-800"
: "text-slate-100 hover:text-slate-50 bg-gradient-to-br from-slate-900 to-slate-800 hover:from-slate-800 hover:to-slate-700 dark:text-slate-300 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:bg-slate-700 focus:ring-neutral-500"),
variant === "minimal" &&
(disabled
@@ -98,10 +98,6 @@ export const Button: React.ForwardRefExoticComponent<
(disabled
? "text-slate-400 bg-transparent"
: "hover:bg-red-200 text-red-700 bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:bg-red-50 focus:ring-red-500"),
variant === "darkCTA" &&
(disabled
? "text-slate-400 dark:text-slate-500 bg-slate-200 dark:bg-slate-800"
: "text-slate-100 hover:text-slate-50 bg-gradient-to-br from-slate-900 to-slate-800 hover:from-slate-800 hover:to-slate-700 dark:text-slate-300 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:bg-slate-700 focus:ring-neutral-500"),
// set not-allowed cursor if disabled
loading ? "cursor-wait" : disabled ? "cursor-not-allowed" : "",

View File

@@ -13,7 +13,7 @@ const meta = {
argTypes: {
variant: {
control: "select",
options: ["highlight", "primary", "secondary", "minimal", "warn", "alert", "darkCTA"],
options: ["highlight", "primary", "secondary", "minimal", "warn", "alert"],
},
size: { control: "select", options: ["base", "sm", "lg", "fab", "icon"] },
},

View File

@@ -2,7 +2,7 @@
import { ChevronLeft, ChevronRight } from "lucide-react";
import * as React from "react";
import { DayPicker } from "react-day-picker";
import { Chevron, DayPicker } from "react-day-picker";
import { cn } from "@formbricks/lib/cn";
// import { buttonVariants } from "@/components/ui/button";
@@ -40,8 +40,14 @@ export const Calendar = ({ className, classNames, showOutsideDays = true, ...pro
...classNames,
}}
components={{
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
IconRight: () => <ChevronRight className="h-4 w-4" />,
Chevron: (props) => {
if (props.orientation === "left") {
return <ChevronLeft className="h-4 w-4" />;
} else if (props.orientation === "right") {
return <ChevronRight className="h-4 w-4" />;
}
return <Chevron {...props} />;
},
}}
{...props}
/>

View File

@@ -51,7 +51,7 @@ export const Card: React.FC<CardProps> = ({
<p className="text-xs text-slate-500">{description}</p>
<div className="mt-4 flex space-x-2">
{connectHref && (
<Button href={connectHref} target={connectNewTab ? "_blank" : "_self"} size="sm" variant="darkCTA">
<Button href={connectHref} target={connectNewTab ? "_blank" : "_self"} size="sm">
{connectText}
</Button>
)}

Some files were not shown because too many files have changed in this diff Show More