microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.33k stars 675 forks source link

Feature Proposal: Form Control #82

Open LucasHaines opened 5 years ago

LucasHaines commented 5 years ago

Proposal: Form Control

Summary

The Form control enables layout, alignment, and grouping of form elements. Form elements are different control types associated with data input.

Rationale

Creating a form is a very common scenario for Enterprise and LOB applications. Easily creating a form that is evenly spaced, appropriately sized, semantically grouped, accessible, and contains the needed actions is a manual process using Grid (or other layout controls). While this is not difficult, it can be time consuming and cumbersome.

When creating a form using any of the layout panels provided today, Narrator support is only provided at the control level. No context is provided to user. Example: if the field is required, how many, which section, etc. by creating a Form layout control this can be provided to user for free and allow developers to focus on functionality and not layout.

Note: Data/Input validation will be tracked in a separate issue.

Functional Requirements

# Feature Priority
1 Able to create sections with headers Must
2 Able to support multiple columns Must
3 Able to define actions (Submit, Cancel, etc) Must
4 Able to group controls on one line Must
5 Able to override padding and margin per section or overall form Must
6 Support Compact density spacing rules Must
7 Support expand/collapse behavior for Form Sections Should
8 Wrap sections based on window size Should
9 Use inline actions or command bar actions Should
10 Able to add items to form dynamical Should
11 Support for data binding Should
12 Draw a line under each section Should
13 Dedicated area for grouped validation errors Could
14 Support inline actions next to input fields Could

Usage Examples

Create a single column form with inline actions

At default the control will create a single column form respecting spacing rules with actions at the bottom.

image

Create a multi-column form with sections and groups

By providing a few properties the Form control can easily adapt to more complex data input scenarios. Without the need to define row and column definitions. The spacing rules are built into the Form control.

image

Detailed Feature Design

Visual Anatomy of a Form

image

The Form control contains a three different components.

  1. FormSection: Collection of controls relative to each other in layout equally spaced across specified columns.
  2. FormGroup: Collection of controls within a section relative to each other in layout. Spaced based on parameters given.
  3. FormActions: Collection of commands associated with the overall Form control.

Default Spacing

The Forms control will provide default spacing rules but these can be overwritten in markup. image

Creating a Complex Form

The example below used FormSection and FormGroup to build a Form for a new patient.

         <Form Name="NewPatient">
            <FormSection Header="Name" Columns="2">
                <TextBox Header="First name"/>

                <TextBox Header="Last name"/>

                <FormGroup Columns="Auto, *">
                    <TextBox Header="M.I." Width="40"/>

                    <ComboBox Header="Suffix" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <TextBox Header="Last name"/>
            </FormSection>

            <FormSection Header="Basic info" Columns="2">
                <TextBox Header="Pharmacy ID"/>

                <ComboBox Header="Emergency priorty level" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <FormGroup>
                    <CalendarDatePicker Header="Date of birth" HorizontalAlignment="Stretch"/>

                    <TextBox Header="SSN"/>
                </FormGroup>

                <TextBox Header="Citizenship"/>

                <TextBox Header="Place of birth"/>

                <ComboBox Header="Birth state (US only)" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <FormGroup>
                    <ComboBox Header="Gender" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Ethnicity" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <FormGroup>
                    <ComboBox Header="Martial Status" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Religion" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <ComboBox Header="Primary language" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <ComboBox Header="Secondary language" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
            </FormSection>

            <FormSection Header="Contact" Columns="2">
                <TextBox Header="Address 1"/>

                <TextBox Header="Address 2"/>

                <TextBox Header="City"/>

                <FormGroup>
                    <ComboBox Header="State" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <FormGroup Columns="*,Auto">
                        <TextBox Header="Zip"/>

                        <Button Margin="0,28,0,0" Content="..."/>
                    </FormGroup>
                </FormGroup>

                <FormGroup Columns="*,Auto">
                    <TextBox Header="Facility"/>

                    <Button Margin="0,28,0,0" Content="..."/>
                </FormGroup>

                <FormGroup>
                    <TextBox Header="Room"/>

                    <TextBox Header="Community"/>
                </FormGroup>

                <FormGroup>
                    <ComboBox Header="Aware Dx" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Aware Px" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <TextBox Header="Mapsco #"/>

                <TextBox Header="Primary phone" PlaceholderText="123-456-7890"/>

                <TextBox Header="Email"/>
            </FormSection>
        </Form>

Rendered version of markup

image

Accessibility

State Action Narrator
User has tabbed to the first field in the form Focus is set on the first field Form 'name' section 'headervalue', section 1 of n textbox, field 1 of n, narrator begins to read the control as it does today
Form is tabbed through Tab Button: will advance to next control.

Up/Down Arrow: scroll the page up and down
standard control behavior
User tabbed to the first control in the following section Focus is set on the first field of the control Form 'name' section 'headervalue' section 2 of n, field 1 of n, narrator begins to read the control as it does today
Focus is set on action button Button is focused Form 'name' action 1 of n, narrator reads the control as it does today

Open Questions

michael-hawker commented 5 years ago

Interesting idea. I like the idea of gaining form consistency especially for layout, accessibility, and navigation perspectives.

I'd be nice to have an option to make sections that can be collapsed/expanded for long forms or settings pages. That may need something like the Expander control from the Toolkit though too.

It does seem to align with the Grid efforts, but I could see this using that, especially if it's a data-bound list or object. It'd be nice to see it somehow could read/consume a set of properties from an object via reflection to show the form and data-bind to the object's properties. -- I believe @mrlacey was exploring something related with Rapid XAML Toolkit though slightly different, but I could see WindowsTemplateStudio using this for their settings page, eh @crutkas?

LucasHaines commented 5 years ago

@michael-hawker Great feedback, really love the idea of having an expand/collapse behavior on form sections. I added it to the functional requirements. Will expand in the usage scenarios and code example. Thanks for the pointer.

Data binding is something we want to support in the long term. It's captured in the requirements as a "Should".

michael-hawker commented 5 years ago

@LucasHaines yeah, I just implemented a setting page in my app and it was long and sprawling, adding the sections collapsed really made a big impact on navigability.

Look at the spec for #79 too, as the expand/collapse parts would overlap, especially if only one section should be open at a time (an option in their scenario). Would be nice to centralize those two code pieces to another control that can be used outside or for Accordion drawers. Could be cool to have an expander type control that can act like a radio grouping where only 1 can be open at a time.

mrlacey commented 5 years ago

Some thoughts/comments

LucasHaines commented 5 years ago

@mrlacey Thanks for the feedback! We do want to strike a balance with this control of functionality and ease of use. We want to avoid bloating this control and really focus on a single consistent form experience that is great with no additional work but can support customization.

mdtauk commented 5 years ago

Might I suggest that if this control was to be built, that some consideration be made with those multi-column groups, so a narrow width will re-arrange the form elements.

LucasHaines commented 5 years ago

I will update the feature request to call this our more detailed. I will also adda proposed list of resrouces for consistent styling. But all in all, your suggestions are spot on.

mdtauk commented 5 years ago

There is a UWP Doc page about best practice for Forms. https://docs.microsoft.com/en-gb/windows/uwp/design/controls-and-patterns/forms

Whatever happens with this proposal, there should be consistency with the Fluent, Windows, Office, and Docs teams to clearly define how to do it.

jamesmcroft commented 5 years ago

How would you envision this working with custom built input controls?

One of the projects I work on is an enterprise application which relies heavily on form-based views which have heavily customized in-house input controls to support data validation and unique input experiences.

Would this control also look to handle scenarios where certain sections or input fields should be visible based on the values of other fields? I know there would be other ways of achieving this outside of the control.

mdtauk commented 5 years ago

You could have a form content panel control, which would contain the custom control/third party control - but still supports the responsive reflow, sizing, tabbing, etc

The form control would ensure consistent spacing between items, handle flow, resize and possibly pagination and multi-step forms, whilst maintaining input values from multiple pages before submitting.

LucasHaines commented 5 years ago

I'm removing the assignee field to indicate that this proposal is going to the freezer for us to take a look at later.

quantasm commented 4 years ago

There does not appear to be a winui PropertyGrid control yet. However, this Form Control feature proposal would go some way to allow some kind of grouped PropertyGrid. They could almost be the same control with only the layout and spacing determine if Form Control 'looks' like a form or a propertygrid.

niels9001 commented 4 years ago

Love this proposal!

One small comment: how would we deal with inconsistent spacing between controls?

Example image

In this example, all input controls (ToggleSwitch / NumberBox / ToggleSwitch) have the same Margin: 0, 12, 0, 0.

As you can see this results in a consistency, as a ToggleSwitch and CheckBox make use of additional whitepace. within their controls.

mdtauk commented 3 years ago

This control proposal should be considered alongside Aligning Control Headers to the Left (and Right) #4643 Allow on/off label placement on either side of ToggleSwitch #3696

mdtauk commented 3 years ago

A new Microsoft Teams UI kit has been added in Figma, and there is guidance for creating Forms, which could be useful for this discussion and proposal.

image image

michael-hawker commented 3 years ago

Since this has been called out for both data entry form layouts and setting page layouts, wanted to link to this twitter thread about the latter via @niels9001:

Settings Refresh Design

Also a mention of using Expander to collapse form sections.

mdtauk commented 3 years ago

The Figma file for WinUI 2.6 has no guidance for the laying out of Forms or the best practice that is being implemented in the new Settings and Store apps.

I still think this control needs to happen, but it would be a good idea for the design teams to document best practices and redlines for spacing and positioning of these elements.

heartacker commented 1 year ago

any update?