跳到主要内容

FormWrapper

White card of a fixed width that the portal's sign-in and wizard forms sit on. It is a shadowed, rounded box 320px wide that drops all of its decoration on a phone.

FormWrapperFormWrapper

Use this when / not when​

  • Use for a short standalone form on a page of its own — sign in, create a portal, reset a password — where the form is the page's only content.
  • Not for a form inside an existing page or panel. The card is 320px wide and cannot be widened by a prop, and its shadow reads as a second surface on top of one you already have.
  • Not as a general-purpose card — Card is that, without the fixed width.
  • Not around a field on its own. FieldContainer is what arranges a label, a control and an error line.

Import​

import { FormWrapper } from "@onlyoffice/apps-ui-kit/components/form-wrapper";

Also exported from the root barrel @onlyoffice/apps-ui-kit.

FormWrapperProps is not exported — type a wrapper's props yourself.

Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme: the background and the shadow are chosen by the light and dark classes the provider sets.

Stories​

Default​

The card on its own around a heading and a line of text, to judge its width, padding, corners and shadow before a form goes in. Change the class, id or inline styles live in the Controls panel below.

DefaultDefault

With Login Form​

A sign-in form as the card is meant to hold it: an email field, a password field and a primary button. Each field row is given a width of 100% and each control scale, so they span the card instead of shrinking to their content.

With Login FormWith Login Form

With Registration Form​

A longer form with four fields, to show that the card keeps its fixed width and only grows taller as fields are added.

With Registration FormWith Registration Form

Css Customization​

Every overridable variable set on a wrapper around one card -- the variables are listed under CSS variables on this page. Set the minimum and the maximum width together: either one alone is clamped by the other.

Css CustomizationCss Customization

Minimal example​

The card centres its children and sizes itself, so the page only has to place it.

import { Button, ButtonSize } from "@onlyoffice/apps-ui-kit/components/button";
import { FieldContainer } from "@onlyoffice/apps-ui-kit/components/field-container";
import { FormWrapper } from "@onlyoffice/apps-ui-kit/components/form-wrapper";
import {
InputSize,
InputType,
TextInput,
} from "@onlyoffice/apps-ui-kit/components/text-input";

export function SignIn({
email,
onEmailChange,
onSubmit,
}: {
email: string;
onEmailChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onSubmit: () => void;
}) {
return (
<div style={{ display: "flex", justifyContent: "center", padding: 48 }}>
<FormWrapper>
<FieldContainer
isVertical
labelVisible
labelText="Email"
style={{ width: "100%" }}
>
<TextInput
type={InputType.email}
size={InputSize.base}
value={email}
onChange={onEmailChange}
scale
/>
</FieldContainer>
<Button
primary
scale
size={ButtonSize.normal}
label="Sign in"
onClick={onSubmit}
/>
</FormWrapper>
</div>
);
}

Props​

PropertyTypeDescription
childrenReact.ReactNodeThe form. Every child is centred horizontally by the wrapper's own flex column.
className?stringApplied to the card.
id?stringApplied to the card.
style?React.CSSPropertiesApplied to the card.

Recipes​

A wider card​

Both min-width and max-width are set, so widening the card means moving the pair. Setting only the maximum leaves the minimum holding it at 320px.

import { FormWrapper } from "@onlyoffice/apps-ui-kit/components/form-wrapper";

export function WideForm({ children }: { children: React.ReactNode }) {
return (
<FormWrapper
style={
{
"--form-wrapper-min-width": "480px",
"--form-wrapper-max-width": "480px",
} as React.CSSProperties
}
>
{children}
</FormWrapper>
);
}

Behaviour the types don't state​

  • The width is fixed, and it is not a prop. min-width and max-width are both 320px on a desktop and both 416px on a tablet, so the card ignores its container. Override --form-wrapper-min-width and --form-wrapper-max-width together — setting one leaves the other clamping.
  • On a phone the card stops being a card. Under the mobile breakpoint the padding, radius, shadow and background are all removed — the last two with !important, so neither style nor a class of yours can put them back. The form ends up flush against the page.
  • Children are centred. The card is a flex column with align-items: center, so a child without a width of its own shrinks to its content instead of filling the card. Give inputs and buttons scale to make them span it — and a FieldContainer row style={{ width: "100%" }} as well, since it is a flex box with no width of its own and scale only fills the row the control sits in.
  • It brings 32px of padding, which is on top of any margin the children carry — FieldContainer's own 16px bottom margin among them.
  • id, className and style are spread onto the card, and any other DOM attribute you pass goes with them even though the type does not list it.

CSS variables​

VariableDefaultEffect
--form-wrapper-bgwhite / blackBackground of the card
--form-wrapper-shadowtheme popup shadowShadow under the card
--form-wrapper-radius12pxCorner radius
--form-wrapper-padding32pxPadding inside the card
--form-wrapper-max-width320pxLargest width; 416px on a tablet
--form-wrapper-min-width320pxSmallest width; 416px on a tablet

Under the mobile breakpoint the card sets its own padding, radius, shadow and background, so none of those four variables has an effect on a phone — the background and the shadow with !important, which a style or a class of yours cannot beat either. The two width variables work on a desktop only: a tablet fixes the width at 416px and a phone at 100%. Set the minimum and the maximum together, since either one alone is clamped by the other.

Accessibility​

  • The card is a plain <div>: it carries no landmark and no heading. Put your own <form> inside it, and a heading above the fields, or the page has no structure at all.
  • Centring is visual only; the reading order is the order of the children.
  • Nothing here is focusable, and the card does not trap focus — it is not a dialog.

Test ids​

Elementdata-testid
The cardform-wrapper

It cannot be overridden by a prop.