Skip to content

Commit

Permalink
feat(dashboard): separator component aligned with design system (#7426)
Browse files Browse the repository at this point in the history
  • Loading branch information
scopsy authored Jan 4, 2025
1 parent 2a0db46 commit ae0c2b0
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 56 deletions.
24 changes: 12 additions & 12 deletions apps/dashboard/src/components/create-workflow-button.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ComponentProps, useState } from 'react';
import { useForm } from 'react-hook-form';
import { RiArrowRightSLine } from 'react-icons/ri';
import { ExternalLink } from '@/components/shared/external-link';
import { useNavigate } from 'react-router-dom';
import { z } from 'zod';
import { type CreateWorkflowDto, WorkflowCreationSourceEnum, slugify } from '@novu/shared';
import { createWorkflow } from '@/api/workflows';
import { Button } from '@/components/primitives/button';
import { FormField, FormItem, FormLabel, FormControl, FormMessage, Form } from '@/components/primitives/form/form';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/primitives/form/form';
import { Input, InputField } from '@/components/primitives/input';
import { Separator } from '@/components/primitives/separator';
import {
Expand All @@ -24,11 +15,20 @@ import {
} from '@/components/primitives/sheet';
import { TagInput } from '@/components/primitives/tag-input';
import { Textarea } from '@/components/primitives/textarea';
import { ExternalLink } from '@/components/shared/external-link';
import { useEnvironment } from '@/context/environment/hooks';
import { useTags } from '@/hooks/use-tags';
import { AUTOCOMPLETE_PASSWORD_MANAGERS_OFF } from '@/utils/constants';
import { QueryKeys } from '@/utils/query-keys';
import { buildRoute, ROUTES } from '@/utils/routes';
import { AUTOCOMPLETE_PASSWORD_MANAGERS_OFF } from '@/utils/constants';
import { zodResolver } from '@hookform/resolvers/zod';
import { type CreateWorkflowDto, slugify, WorkflowCreationSourceEnum } from '@novu/shared';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ComponentProps, useState } from 'react';
import { useForm } from 'react-hook-form';
import { RiArrowRightSLine } from 'react-icons/ri';
import { useNavigate } from 'react-router-dom';
import { z } from 'zod';
import { MAX_DESCRIPTION_LENGTH, MAX_TAG_ELEMENTS, workflowSchema } from './workflow-editor/schema';

type CreateWorkflowButtonProps = ComponentProps<typeof SheetTrigger>;
Expand Down Expand Up @@ -137,7 +137,7 @@ export const CreateWorkflowButton = (props: CreateWorkflowButtonProps) => {
)}
/>

<Separator className="bg-neutral-alpha-100" />
<Separator />

<FormField
control={form.control}
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/in-app-action-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ const ConfigureActionPopover = (props: ComponentProps<typeof PopoverTrigger> & {
<div className="flex items-center gap-2 text-sm font-medium leading-none">
<RiEdit2Line className="size-4" /> Customize button
</div>
<Separator decorative />
<Separator />
<FormField
control={control}
name={`${actionKey}.label`}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { SizeType } from '../types';
import { FilterInput } from './filter-input';
import { ClearButton } from './clear-button';
import { RiArrowDownLine, RiArrowUpLine } from 'react-icons/ri';
import { EnterLineIcon } from '../../../../icons/enter-line';
import { Separator } from '../../../separator';
import { SizeType } from '../types';
import { ClearButton } from './clear-button';
import { FilterInput } from './filter-input';

interface BaseFilterContentProps {
inputRef: React.RefObject<HTMLInputElement>;
Expand Down Expand Up @@ -35,10 +36,12 @@ export function BaseFilterContent({
}: BaseFilterContentProps) {
return (
<div className="flex h-full flex-col">
<div className="flex justify-between rounded-t-md bg-neutral-50 px-1.5 py-1">
{title && <span className="text-foreground-400 text-[11px] uppercase">{title}</span>}
{!hideClear && <ClearButton onClick={onClear} size={size} label="Reset" />}
</div>
<Separator variant="solid-text" className="px-1.5 py-1">
<div className="flex w-full justify-between rounded-t-md bg-neutral-50">
{title && <div className="uppercase leading-[16px]">{title}</div>}
{!hideClear && <ClearButton onClick={onClear} size={size} className="h-[16px]" label="Reset" />}
</div>
</Separator>

{!hideSearch && onSearchChange && (
<FilterInput
Expand Down
75 changes: 55 additions & 20 deletions apps/dashboard/src/components/primitives/separator.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,59 @@
import * as React from 'react';
import * as SeparatorPrimitive from '@radix-ui/react-separator';
import { tv, type VariantProps } from '@/utils/tv';

import { cn } from '@/utils/ui';
const SEPARATOR_ROOT_NAME = 'SeparatorRoot';

const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
'bg-neutral-alpha-200 shrink-0',
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
className
)}
{...props}
/>
));
Separator.displayName = SeparatorPrimitive.Root.displayName;
export const separatorVariants = tv({
base: 'relative flex w-full items-center',
variants: {
variant: {
line: 'h-0 before:absolute before:left-0 before:top-1/2 before:h-px before:w-full before:-translate-y-1/2 before:bg-stroke-soft',
'line-spacing': [
// base
'h-1',
// before
'before:absolute before:left-0 before:top-1/2 before:h-px before:w-full before:-translate-y-1/2 before:bg-stroke-soft',
],
'line-text': [
// base
'gap-2.5',
'text-subheading-2xs text-text-soft',
// before
'before:h-px before:w-full before:flex-1 before:bg-stroke-soft',
// after
'after:h-px after:w-full after:flex-1 after:bg-stroke-soft',
],
content: [
// base
'gap-2.5',
// before
'before:h-px before:w-full before:flex-1 before:bg-stroke-soft',
// after
'after:h-px after:w-full after:flex-1 after:bg-stroke-soft',
],
text: [
// base
'px-2 py-1',
'text-subheading-2xs text-text-soft',
],
'solid-text': [
// base
'bg-bg-weak px-3 py-1.5 uppercase',
'text-subheading-2xs text-text-soft',
],
},
},
defaultVariants: {
variant: 'line',
},
});

function Separator({
className,
variant,
...rest
}: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof separatorVariants>) {
return <div role="separator" className={separatorVariants({ variant, class: className })} {...rest} />;
}
Separator.displayName = SEPARATOR_ROOT_NAME;

export { Separator };
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useState } from 'react';
import { TimeUnitEnum } from '@novu/shared';
import { Tabs } from '@radix-ui/react-tabs';
import { useState } from 'react';
import { FieldValues, useFormContext } from 'react-hook-form';
import { TimeUnitEnum } from '@novu/shared';

import { FormField, FormLabel, FormMessagePure } from '@/components/primitives/form/form';
import { Separator } from '@/components/primitives/separator';
import { TabsContent, TabsList, TabsTrigger } from '@/components/primitives/tabs';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/primitives/tooltip';
import { AMOUNT_KEY, CRON_KEY, UNIT_KEY } from '@/components/workflow-editor/steps/digest/keys';
import { RegularDigest } from '@/components/workflow-editor/steps/digest/regular-digest';
import { ScheduledDigest } from '@/components/workflow-editor/steps/digest/scheduled-digest';
import { AMOUNT_KEY, CRON_KEY, UNIT_KEY } from '@/components/workflow-editor/steps/digest/keys';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';
import { EVERY_MINUTE_CRON } from '@/components/workflow-editor/steps/digest/utils';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';

const REGULAR_DIGEST_TYPE = 'regular';
const SCHEDULED_DIGEST_TYPE = 'scheduled';
Expand Down Expand Up @@ -111,7 +111,7 @@ export const DigestWindow = () => {
</Tooltip>
</TabsList>
</div>
<Separator className="bg-neutral-100" />
<Separator className="before:bg-neutral-100" />
<div className="bg-background rounded-b-lg p-2">
<TabsContent value={REGULAR_DIGEST_TYPE}>
<RegularDigest />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import * as Sentry from '@sentry/react';
import { HTMLAttributes, useEffect } from 'react';
import { useParams } from 'react-router-dom';

import { usePreviewStep } from '@/hooks/use-preview-step';
import { EmailPreviewHeader } from '@/components/workflow-editor/steps/email/email-preview';
import { Separator } from '@/components/primitives/separator';
import { Skeleton } from '@/components/primitives/skeleton';
import { cn } from '@/utils/ui';
import { EmailPreviewHeader } from '@/components/workflow-editor/steps/email/email-preview';
import { useWorkflow } from '@/components/workflow-editor/workflow-provider';
import { usePreviewStep } from '@/hooks/use-preview-step';
import { cn } from '@/utils/ui';

type MiniEmailPreviewProps = HTMLAttributes<HTMLDivElement>;
const MiniEmailPreview = (props: MiniEmailPreviewProps) => {
Expand All @@ -22,7 +22,7 @@ const MiniEmailPreview = (props: MiniEmailPreviewProps) => {
>
<div className="flex flex-col gap-1 py-1">
<EmailPreviewHeader className="px-2 text-sm" />
<Separator className="bg-neutral-alpha-100" />
<Separator className="before:bg-neutral-alpha-100" />
<div className="relative z-10 space-y-1 px-2">{children}</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { ChannelTypeEnum, GeneratePreviewResponseDto } from '@novu/shared';
import { useState } from 'react';
import { RiMacLine, RiSmartphoneFill } from 'react-icons/ri';

import { Separator } from '@/components/primitives/separator';
import { Skeleton } from '@/components/primitives/skeleton';
import { Tabs, TabsList, TabsTrigger } from '@/components/primitives/tabs';
import {
EmailPreviewBody,
EmailPreviewBodyMobile,
Expand All @@ -11,10 +14,7 @@ import {
EmailPreviewSubjectMobile,
} from '@/components/workflow-editor/steps/email/email-preview';
import { EmailTabsSection } from '@/components/workflow-editor/steps/email/email-tabs-section';
import { Tabs, TabsList, TabsTrigger } from '@/components/primitives/tabs';
import { TabsContent } from '@radix-ui/react-tabs';
import { Separator } from '@/components/primitives/separator';
import { Skeleton } from '@/components/primitives/skeleton';
import { ConfigurePreviewAccordion } from '../shared/configure-preview-accordion';

type EmailEditorPreviewProps = {
Expand Down Expand Up @@ -55,7 +55,7 @@ export const EmailEditorPreview = ({
<EmailTabsSection className="py-2">
<Skeleton className="h-6 w-full" />
</EmailTabsSection>
<Separator className="bg-neutral-100" />
<Separator className="before:bg-neutral-100" />
<EmailTabsSection>
<Skeleton className="h-96 w-full" />
</EmailTabsSection>
Expand All @@ -74,7 +74,7 @@ export const EmailEditorPreview = ({
</TabsContent>
<TabsContent value="desktop">
<EmailPreviewSubject subject={previewData.result.preview.subject} />
<Separator className="bg-neutral-100" />
<Separator className="before:bg-neutral-100" />
<EmailPreviewBody body={previewData.result.preview.body} className="bg-background rounded-lg" />
</TabsContent>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const EmailEditor = (props: EmailEditorProps) => {
<EmailTabsSection className="-mx-[2px] -my-[3px] px-7 py-2">
{getComponentByType({ component: subject.component })}
</EmailTabsSection>
<Separator className="bg-neutral-100" />
<Separator className="before:bg-neutral-100" />
{/* extra padding on the left to account for the drag handle */}
<EmailTabsSection className="basis-full overflow-hidden pl-10">
{getComponentByType({ component: body.component })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const InAppEditor = ({ uiSchema }: { uiSchema: UiSchema }) => {

{redirect && (
<>
<Separator className="bg-neutral-100" />
<Separator className="before:bg-neutral-100" />
<InAppTabsSection>
{getComponentByType({
component: redirect.component,
Expand Down

0 comments on commit ae0c2b0

Please sign in to comment.