From aaf03bdc9e3cfa0d625f9758ad059c0db9fe2abe Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Fri, 12 Jul 2019 16:52:33 -0500 Subject: v5: Forms update (#28450) * Initial spike of consolidated form checks * Stub out forms rearrangement - Prepping to drop non-custom file and range inputs - Prepping to merge custom and native checks and radios (with switches) - Prepping to merge custom select with form select - Moving docs arround so forms has it's own area given volume of CSS * Move input group Sass file to forms subdir * Start to split and move the docs around * Simpler imports * Copyediting * delete overview file * Remove commented out code * remove the custom-forms import * rewrite flex-check as form-check, replace all custom properties * Remove old forms doc * stub out new subpage link section * update migration guide * Update nav, forms overview in page nav, and descriptions * fix check bg position * fix margin-top calculation * rename .custom-select to .form-select * Update validation styles for new checks * add some vertical margin, fix inline checks * fix docs examples * better way to do this contents stuff, redo the toc while i'm at it * page restyle for docs while here * un-callout that, edit text * redo padding on toc * fix toc * start to cleanup checks docs * Rewrite Markdown tables into HTML * Redesign tables, redo their docs * Replace Open Iconic icons with custom Bootstrap icons * Redesign the docs navbar, add a subheader, redo the sidebar * Redesign docs homepage a bit * Simplify table style overrides for docs tables * Simplify docs typography for page titles and reading line length * Stub out icons page * Part of sidebar update, remove migration from nav.yml * Move toc CSS to separate partial * Change appearance of overview page * fix sidebar arrow direction * Add footer to docs layout * Update descriptions * Drop the .form-group class for margin utilities * Remove lingering form-group-margin-bottom var * improve footer spacing * add headings to range page * uncomment form range css * Rename .custom-range to .form-range * Drop unused docs var * Uncomment the comment * Remove unused variable * Fix radio image sizing * Reboot update: reset horizontal ul and ol padding * de-dupe IDs * tweak toc styles * nvm, fix dropdown versions stuff * remove sidebar nav toggle for now * broken html * fix more broken html, move css * scss linting * comment out broken helper docs * scope styles * scope styles * Fixes #25540 and fixes #26407 for v5 only * Update sidebar once more * Match new sidenav order * fix syntax error * Rename custom-file to form-file, update paths, update migration docs for previous changes in #28696 * rename back * fix size and alignment * rename that back too --- scss/forms/_form-check.scss | 116 ++++++++++++++++++++++++++ scss/forms/_form-control.scss | 115 ++++++++++++++++++++++++++ scss/forms/_form-file.scss | 72 ++++++++++++++++ scss/forms/_form-range.scss | 142 +++++++++++++++++++++++++++++++ scss/forms/_form-select.scss | 76 +++++++++++++++++ scss/forms/_input-group.scss | 188 ++++++++++++++++++++++++++++++++++++++++++ scss/forms/_labels.scss | 27 ++++++ scss/forms/_layout.scss | 101 +++++++++++++++++++++++ scss/forms/_validation.scss | 10 +++ 9 files changed, 847 insertions(+) create mode 100644 scss/forms/_form-check.scss create mode 100644 scss/forms/_form-control.scss create mode 100644 scss/forms/_form-file.scss create mode 100644 scss/forms/_form-range.scss create mode 100644 scss/forms/_form-select.scss create mode 100644 scss/forms/_input-group.scss create mode 100644 scss/forms/_labels.scss create mode 100644 scss/forms/_layout.scss create mode 100644 scss/forms/_validation.scss (limited to 'scss/forms') diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss new file mode 100644 index 000000000..b309d2e70 --- /dev/null +++ b/scss/forms/_form-check.scss @@ -0,0 +1,116 @@ +// +// Check/radio +// + +.form-check { + display: block; + min-height: $form-check-min-height; + padding-left: $form-check-padding-left; + margin-bottom: $form-check-margin-bottom; +} + +.form-check-input { + float: left; + width: $form-check-input-width; + height: $form-check-input-width; + // Todo: Change static value to base line-height? + margin-top: calc((1.5em - #{$form-check-input-width}) / 2); // line-height minus check height + margin-left: $form-check-padding-left * -1; + background-color: $form-check-input-bg; + border: $form-check-input-border; + appearance: none; + + &[type="checkbox"] { + @include border-radius($form-check-input-border-radius); + } + + &[type="radio"] { + @include border-radius($form-check-radio-border-radius); + } + + &:active { + filter: $form-check-input-active-filter; + } + + &:focus { + border-color: $form-check-input-focus-border; + outline: 0; + box-shadow: $form-check-input-focus-box-shadow; + } + + &:checked { + background-color: $form-check-input-checked-bg-color; + background-repeat: $form-check-input-checked-bg-repeat; + background-position: $form-check-input-checked-bg-position; + background-size: $form-check-input-checked-bg-size; + border-color: $form-check-input-checked-border-color; + + &[type="checkbox"] { + background-image: $form-check-input-checked-bg-image; + } + + &[type="radio"] { + background-image: $form-check-radio-checked-bg-image; + } + } + + &[type="checkbox"]:indeterminate { + background-color: $form-check-input-indeterminate-bg-color; + background-image: $form-check-input-indeterminate-bg-image; + background-repeat: $form-check-input-indeterminate-bg-repeat; + background-position: $form-check-input-indeterminate-bg-position; + background-size: $form-check-input-indeterminate-bg-size; + border-color: $form-check-input-indeterminate-border-color; + } + + // Use disabled attribute instead of :disabled pseudo-class + // Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231 + &[disabled] { + pointer-events: none; + filter: none; + opacity: .5; + + ~ .form-check-label { + opacity: .5; + } + } +} + +.form-check-label { + margin-bottom: 0; +} + +// +// Switch +// + +.form-switch { + padding-left: $form-switch-padding-left; + + .form-check-input { + width: $form-switch-width; + margin-left: $form-switch-padding-left * -1; + background-image: $form-switch-bg-image; + background-repeat: no-repeat; + background-position: left center; + background-size: calc(#{$form-switch-height} - 2px); // Get a 1px separation + @include border-radius($form-switch-border-radius); + // Todo: Figure out how to tackle these, with or without mixin? + // transition: $form-switch-transition; + // transition-property: $form-switch-transition-property; + + &:focus { + background-image: $form-switch-focus-bg-image; + } + + &:checked { + background-image: $form-switch-checked-bg-image; + background-position: $form-switch-checked-bg-position; + } + } +} + +.form-check-inline { + display: inline-block; + margin-right: $form-check-inline-margin-right; +} diff --git a/scss/forms/_form-control.scss b/scss/forms/_form-control.scss new file mode 100644 index 000000000..ce2b42662 --- /dev/null +++ b/scss/forms/_form-control.scss @@ -0,0 +1,115 @@ +// stylelint-disable selector-no-qualifying-type + +// +// Textual form controls +// + +.form-control { + display: block; + width: 100%; + height: $input-height; + padding: $input-padding-y $input-padding-x; + font-family: $input-font-family; + @include font-size($input-font-size); + font-weight: $input-font-weight; + line-height: $input-line-height; + color: $input-color; + background-color: $input-bg; + background-clip: padding-box; + border: $input-border-width solid $input-border-color; + + // Note: This has no effect on `s in CSS. + @include border-radius($input-border-radius, 0); + + @include box-shadow($input-box-shadow); + @include transition($input-transition); + + // Unstyle the caret on ` receives focus + // in IE and (under certain conditions) Edge. + // See https://github.com/twbs/bootstrap/issues/19398. + color: $input-color; + background-color: $input-bg; + } + } + + &[multiple], + &[size]:not([size="1"]) { + height: auto; + padding-right: $form-select-padding-x; + background-image: none; + } + + &:disabled { + color: $form-select-disabled-color; + background-color: $form-select-disabled-bg; + } + + // Hides the default caret in IE11 + &::-ms-expand { + display: none; + } +} + +.form-select-sm { + height: $form-select-height-sm; + padding-top: $form-select-padding-y-sm; + padding-bottom: $form-select-padding-y-sm; + padding-left: $form-select-padding-x-sm; + @include font-size($form-select-font-size-sm); +} + +.form-select-lg { + height: $form-select-height-lg; + padding-top: $form-select-padding-y-lg; + padding-bottom: $form-select-padding-y-lg; + padding-left: $form-select-padding-x-lg; + @include font-size($form-select-font-size-lg); +} diff --git a/scss/forms/_input-group.scss b/scss/forms/_input-group.scss new file mode 100644 index 000000000..099accecb --- /dev/null +++ b/scss/forms/_input-group.scss @@ -0,0 +1,188 @@ +// stylelint-disable selector-no-qualifying-type + +// +// Base styles +// + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; // For form validation feedback + align-items: stretch; + width: 100%; + + > .form-control, + > .form-select, + > .form-file { + position: relative; // For focus state's z-index + flex: 1 1 0%; + margin-bottom: 0; + + + .form-control, + + .form-select, + + .form-file { + margin-left: -$input-border-width; + } + } + + // Bring the "active" form control to the top of surrounding elements + > .form-control:focus, + > .form-select:focus, + > .form-file .form-file-input:focus ~ .form-file-label { + z-index: 3; + } + + // Bring the custom file input above the label + > .form-file .form-file-input:focus { + z-index: 4; + } + + > .form-control, + > .form-select { + &:not(:last-child) { @include border-right-radius(0); } + &:not(:first-child) { @include border-left-radius(0); } + } + + // Custom file inputs have more complex markup, thus requiring different + // border-radius overrides. + > .form-file { + display: flex; + align-items: center; + + &:not(:last-child) .form-file-label { @include border-right-radius(0); } + &:not(:first-child) .form-file-label { @include border-left-radius(0); } + } +} + + +// Prepend and append +// +// While it requires one extra layer of HTML for each, dedicated prepend and +// append elements allow us to 1) be less clever, 2) simplify our selectors, and +// 3) support HTML5 form validation. + +.input-group-prepend, +.input-group-append { + display: flex; + + // Ensure buttons are always above inputs for more visually pleasing borders. + // This isn't needed for `.input-group-text` since it shares the same border-color + // as our inputs. + .btn { + position: relative; + z-index: 2; + + &:focus { + z-index: 3; + } + } + + .btn + .btn, + .btn + .input-group-text, + .input-group-text + .input-group-text, + .input-group-text + .btn { + margin-left: -$input-border-width; + } +} + +.input-group-prepend { margin-right: -$input-border-width; } +.input-group-append { margin-left: -$input-border-width; } + + +// Textual addons +// +// Serves as a catch-all element for any text or radio/checkbox input you wish +// to prepend or append to an input. + +.input-group-text { + display: flex; + align-items: center; + padding: $input-padding-y $input-padding-x; + margin-bottom: 0; // Allow use of