Skip to main content
Flowra
PricingCommunityFAQ
JoinStart with Flowra
  • PricingPlans, seats and payment
  • Frequently asked questionsEverything you have asked, in one place
  • Contact usWrite to the right team
  • CommunityKaro Studio, who make Flowra

For your team

  • Marketing teamsCampaigns from brief to launch
  • Product and dev teamsFeatures and bugs with full context
  • Design and content teamsBrief, files and delivery side by side
  • Operations teamsWork, documents and costs you can track
  • Sales and services teamsFrom meeting to contract and payment
  • Remote teamsOnline meeting to delivery, on your time

For your role

  • Project managersAction stories instead of chasing the team
  • Freelancers and consultantsFrom brief to contract and settlement

For your workflow

  • Meeting to actionMeeting decisions as trackable work
  • Actions with financial contextCosts next to the work that caused them
  • Actions with contract contextEvery commitment as trackable work
  • Brief to project deliveryEvery project step, one complete action
See all solutionsStart with FlowraJoin
++
Flowra design system

Fundamentals

PrinciplesVoice and writingCopy rules for each surfaceGlossaryRTL and languagesNumbers and datesAccessibility

Foundations

ColorDark modePrintingTypographySpacing and layoutRadius and shadowLayersMotionNotification soundKeyboard shortcutsIconsService logos

Components

ButtonsText fieldPickerDate and timeCheckboxRadioKeySegmented controlSliderMenu and sheetDialogCard and listTables and data listsBadge, pill, and switchTabs and filtersAvatarEmpty and loading statesProgress and stepsToastFloating helpNavigationPage headerAssistants

Patterns

Connector pageList, filter, and searchForm layoutCreation flowUpgrade promptConfirmation and irreversible actionsPhone layoutFixed bars and scrolling

Brand

Flowra brandMark and logoBrand colorBrand typographyMisuse

Design system/Components

Dialog

The dialog is the app's highest interactive layer: it opens centered on desktop and rises from the bottom like a sheet on phones, with a handle you can drag down.

In codecomponents/knowledge/ui.tsxcomponents/confirm.tsxcomponents/sheet-grow.tsx

On this page

  1. Live example
  2. Anatomy
  3. On phones
  4. When
  5. Code
  6. Sizes
  7. Accessibility

Live example

Open the dialog. Tap the backdrop, press Escape, or tap ✕; all three close it.

Live example

Anatomy

  1. BackgroundA 45 percent warm dim with a 3px blur; tapping it closes the dialog.
  2. HeaderAn icon in a soft orange circle, a 15px heading, a subheading, and a close button.
  3. BodyThe only part that scrolls.
  4. FooterButtons, separated by a dashed line; always visible.

On phones

Below 640px, every .modal becomes full width, sticks to the bottom of the screen, gets 24px top corners, and rises with the sheet curve. The handle is drawn with ::before, with no extra markup. SheetGrow lets you drag the sheet to full screen or down.

This behavior lives in CSS for every dialog, not in each component; a new dialog is correct on phones with no extra work.

Width (desktop)460pxDialog: default width; .modal itself 440px
Max height78vhPhone 88vh
Radius18pxPhone 24px 24px 0 0
Layerz 1200
OpeningpopIn 0.3s springPhone 0.34s sheet

When

When to use it

  • A short task you need to finish before moving on: creating, editing a record, confirming.
  • A form that depends on the current page and shouldn't leave it.

When not to

  • Long reading or a multi-step task; build it its own page.
  • Reporting something that just happened; a toast is enough.
  • A dialog on top of a dialog.

Code

<Dialog
  open={open}
  onClose={() => setOpen(false)}
  title={tr("اقدام تازه")}
  icon={paths.plus}
  footer={
    <>
      <button className="btn btn-ghost flex-1" onClick={() => setOpen(false)}>{tr("انصراف")}</button>
      <button className="btn btn-dark flex-1" onClick={save}>{tr("ساخت اقدام")}</button>
    </>
  }
>
  <TextField floating label={tr("عنوان")} value={title} onChange={(e) => setTitle(e.target.value)} />
</Dialog>

Sizes

Headerpadding 20px 20px 12px · gap 10px
Header icon36px · icon 16px--accent on --accent-soft
Heading15px / 600 · truncate
Subtitle11.5px · --text-secondary
Close button30px · radius 999px · icon 15pxHover: --red on --red-soft
Bodypadding 0 20px 16px · gap 14px
Footerpadding 12px 20px 20px · gap 8px · dashed-top
Footer button (desktop)min-width 128px · end of the row
Footer button (phone)flex 1 1 0 · min-height 48px · radius 12px
Backgroundrgba(20, 16, 12, 0.45) · blur(3px)
Phone full-screen100dvh · radius 0data-expanded with SheetGrow

Accessibility

  • Escape closes it through a keydown listener on window; a higher Floating panel catches Escape first, so one Escape doesn't close two layers.
  • The close button has the aria-label and title “Close”.
  • Dialog and DialogShell have role="dialog", aria-modal="true", aria-labelledby pointing to the title, and tabIndex=-1; ConfirmDialog has the same with role="alertdialog".
  • When it opens, focus moves to the element with data-autofocus; if there isn't one, to the first focusable element; and if there isn't one either, to the dialog itself. Tab and Shift+Tab cycle inside as long as this dialog is the topmost .modal; a Floating panel opened from inside it keeps its own focus. On close, focus returns to whatever opened the dialog. All of this is useDialogA11y in lib/use-dialog-a11y.ts.
  • Closing happens on mousedown on the backdrop; mousedown inside the dialog is stopped, so dragging text from inside to outside doesn't close the dialog.
  • With reduced motion, the phone dialog fades in over 0.18 seconds instead of sliding up.

Do

A title that says what's being created or changed: “New action”.

Don't

“Form” or “Edit” with no object.

Do

The primary action goes last in the footer; on desktop the row is aligned to the end.

Don't

Buttons that stretch edge to edge on desktop; the footer no longer allows it.

Do

A long body scrolls while the header and footer stay fixed.

Don't

Scrolling the whole dialog, which pushes the footer buttons out of view.

Why

On desktop the dialog footer keeps buttons as wide as their labels, because a wide “+ New schedule” bar reads as a banner, not a button. On phones the same footer is a thumb bar and the buttons share the width.

Related pages

Confirmation and irreversible actionsConfirmDialog, the delete confirmation dialog.Creation flowA creation form inside a dialog, with buttons in the footer.MotionThe spring opening and the sheet rising.Phone layoutOn phones, a dialog is a sheet.Radius and shadow18 radius and the tallest shadow.AccessibilityEscape, the backdrop, and the close button.AssistantsThe assistant window is the same dialog.
PreviousMenu and sheetNextCard and list

Related pages

  • PageBrand kitThe Flowra mark and logo, colors, typography, clear space and minimum size, and the brand kit files to download.
  • PageDocumentationThe complete Flowra guide: actions, calendar, meetings, knowledge, files, Folio, chat, network, finance, connectors, settings and AI, each with its connections.
  • PageChangelogWhat each release added to Flowra, what got better, and what’s coming next.
  • PageContact usReach the right team: support, sales and plans, partnerships, careers, or security and privacy.
Flowra

Flowra is an all-in-one workspace for managing tasks, projects, finances, meetings, and teamwork, powered by AI to keep everything organized in one place.

Solutions for teams

  • Marketing teams
  • Product and dev teams
  • Design and content teams
  • Operations teams
  • Sales and services teams
  • Remote teams

Roles and flows

  • Project managers
  • Freelancers and consultants
  • Meeting to action
  • Actions with financial context
  • Actions with contract context
  • Brief to project delivery

With Flowra

  • All solutions
  • Pricing
  • Frequently asked questions
  • Documentation
  • Contact us
  • Brand kit
  • Design system
Crafted by Karo Studio
SecurityPrivacyTermsCookies
Version 0.16.0