From 96e6949ff5569c350811223de6856fcfa3900c5f Mon Sep 17 00:00:00 2001 From: Carlos Lopez Jr Date: Thu, 9 Jun 2016 14:07:34 -0400 Subject: [PATCH 1/2] fix(select): support for md-inline-form, more configurable SCSS Create better flexibility for manipulating select while still following Material Design spec - Add `md-inline-form` support - Add alignment math to SCSS - Support custom margin and padding for `md-select` - Dynamically adjust bottom margin to allow denser layouts Fixes #8712. Closes #8716. --- package-lock.json | 6 +-- src/components/select/select.js | 2 +- src/components/select/select.scss | 65 +++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9c7c6243d5..1e79b9ea182 100644 --- a/package-lock.json +++ b/package-lock.json @@ -418,7 +418,7 @@ "ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha1-Y3S03V1HGP884npnGjscrQdxMqk=", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { "ansi-wrap": "^0.1.0" @@ -4164,7 +4164,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "functional-red-black-tree": { @@ -10654,7 +10654,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "scss-tokenizer": { diff --git a/src/components/select/select.js b/src/components/select/select.js index 787a8c4eddc..94ac3f78408 100755 --- a/src/components/select/select.js +++ b/src/components/select/select.js @@ -2067,7 +2067,7 @@ function SelectProvider($$interimElementProvider) { transformOrigin = '50% 100%'; } } else { - left = (targetRect.left + centeredRect.left - centeredRect.paddingLeft) + 2; + left = (targetRect.left + centeredRect.left - centeredRect.paddingLeft); top = Math.floor(targetRect.top + targetRect.height / 2 - centeredRect.height / 2 - centeredRect.top + contentNode.scrollTop) + 2; diff --git a/src/components/select/select.scss b/src/components/select/select.scss index 5472e4b7851..2a593e02bfb 100755 --- a/src/components/select/select.scss +++ b/src/components/select/select.scss @@ -6,9 +6,23 @@ $select-option-height: 48px !default; $select-option-padding: 16px !default; $select-container-padding: 16px !default; $select-container-transition-duration: 350ms !default; +$select-value-padding-top: 6px; +$select-value-padding-bottom: 4px; $select-max-visible-options: 5 !default; +// from input.scss +$input-container-margin-top: 18px !default; +$input-container-padding-top: 2px !default; +$input-padding-top: 2px !default; +$input-padding-bottom: 1px !default; + +$input-alignment: ($input-padding-top + $input-padding-bottom) + - ($select-value-padding-top + $select-value-padding-bottom); +$md-inline-alignment: ($input-container-margin-top + $input-container-padding-top) + + ($input-padding-top + $input-padding-bottom) + - ($select-value-padding-top + $select-value-padding-bottom); + // Fixes the animations with the floating label when select is inside an input container md-input-container { &:not([md-no-float]) { @@ -20,7 +34,7 @@ md-input-container { &.md-input-focused { &:not([md-no-float]) { .md-select-placeholder span:first-child { - transform: translateY(-22px) translateX(-2px) scale(0.75); + transform: translate(-2px, -22px) scale(0.75); } } } @@ -47,7 +61,6 @@ md-input-container { margin: 3*$baseline-grid auto !important; } - // enter: md-select scales in, then options fade in. &.md-active { display: block; @@ -72,11 +85,19 @@ md-input-container { } } -md-input-container > md-select { - margin: 0; - order: 2; +.md-inline-form md-select { + margin-top: $md-inline-alignment; } +md-input-container { + > md-select, + .md-inline-form & > md-select { + margin-top: $input-alignment; + } + > md-select { + order: 2; + } +} // Show the asterisk on the placeholder if the element is required // @@ -103,7 +124,6 @@ md-input-container.md-input-invalid { md-select { display: flex; - margin: 2.5*$baseline-grid 0 3*$baseline-grid + 2 0; &[required], &.ng-required { &.ng-empty.ng-invalid:not(.md-no-asterisk) { @@ -124,6 +144,12 @@ md-select { // to create a dotted line under the input. background-size: 4px 1px; background-repeat: repeat-x; + // Add to padding-bottom to keep dotted line aligned with other bottom borders + // Sub from padding-top to keep height consistent + // Translate text 1px up to keep in alignment + padding-bottom: $select-value-padding-bottom + 1; + padding-top: $select-value-padding-top - 1; + transform: translateY(1px); } &:focus { @@ -138,20 +164,14 @@ md-select { } &.ng-invalid.ng-touched { .md-select-value { - border-bottom-style: solid; - padding-bottom: 1px; + border-bottom: 2px solid; } } &:focus { .md-select-value { border-bottom-width: $select-border-width-default + 1px; border-bottom-style: solid; - padding-bottom: 0; - } - &.ng-invalid.ng-touched { - .md-select-value { - padding-bottom: 0; - } + padding-bottom: $select-value-padding-bottom - 1; } } } @@ -187,8 +207,8 @@ md-input-container md-select { .md-select-value { display: flex; align-items: center; - padding-top: 2px; - padding-bottom: 1px; + padding-top: $select-value-padding-top; + padding-bottom: $select-value-padding-bottom; @include rtl(padding-left, 0, $input-container-padding); @include rtl(padding-right, $input-container-padding, 0); border-bottom-width: $select-border-width-default; @@ -196,8 +216,10 @@ md-input-container md-select { background-color: rgba(0,0,0,0); position: relative; box-sizing: content-box; - min-width: 8 * $baseline-grid; + min-width: 11 * $baseline-grid; min-height: 26px; + margin-bottom: auto; + -ms-flex-item-align: start; // workaround for margin-bottom: auto flex-grow: 1; > span:not(.md-select-icon) { @@ -217,8 +239,7 @@ md-input-container md-select { @include rtl(align-items, flex-end, flex-start); @include rtl(text-align, right, left); width: 3 * $baseline-grid; - margin: 0 .5 * $baseline-grid; - transform: translate3d(0, -2px, 0); + transform: translateY(-2px); font-size: 1.2rem; } @@ -227,9 +248,11 @@ md-input-container md-select { content: '\25BC'; position: relative; top: 2px; + @include rtl(right, -4px, auto); + @include rtl(left, auto, -4px); speak: none; - font-size: 13px; - transform: scaleY(0.5) scaleX(1); + font-size: 16px; + transform: scaleY(0.5); } &.md-select-placeholder { From 04a4612d113879493ab70415d16a7eac880b2ca1 Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Tue, 28 Jul 2020 04:32:36 -0400 Subject: [PATCH 2/2] fix(checkbox, date-picker, input, radio-button, select, switch): md-inline-form support - add inline form demo - add `ng-messages` to `md-select` in input errors demo - consolidate SCSS variables - fix padding above `ng-messages` to align with spec - `8px` - add docs for `md-inline-form` - fix `md-radio-group` issues with inline form layout - revert some changes to and fix some issues with `md-select` SCSS from previous commit --- src/components/checkbox/checkbox.scss | 11 +-- src/components/datepicker/datePicker.scss | 2 +- src/components/input/_input-variables.scss | 6 +- src/components/input/demoErrors/index.html | 3 + .../input/demoInlineForm/index.html | 83 +++++++++++++++++++ src/components/input/demoInlineForm/script.js | 25 ++++++ .../input/demoInlineForm/style.scss | 8 ++ src/components/input/input.js | 37 ++++++++- src/components/input/input.scss | 16 ++-- src/components/input/input.spec.js | 5 -- .../radioButton/demoBasicUsage/index.html | 2 +- src/components/radioButton/radio-button.scss | 11 ++- src/components/select/select.scss | 24 ++---- src/components/switch/switch.scss | 4 +- 14 files changed, 187 insertions(+), 50 deletions(-) create mode 100644 src/components/input/demoInlineForm/index.html create mode 100644 src/components/input/demoInlineForm/script.js create mode 100644 src/components/input/demoInlineForm/style.scss diff --git a/src/components/checkbox/checkbox.scss b/src/components/checkbox/checkbox.scss index 1a7de6e143a..03ffef8b033 100644 --- a/src/components/checkbox/checkbox.scss +++ b/src/components/checkbox/checkbox.scss @@ -12,15 +12,8 @@ $checkbox-min-height: 48px !default; $checkbox-min-height-dense: 36px !default; $checkbox-text-margin: 36px !default; -// from input.scss -$input-container-margin-top: 18px !default; -$input-container-padding-top: 2px !default; -$input-padding-top: 2px !default; -$input-padding-bottom: 1px !default; -$input-border: 1px !default; - -$md-inline-alignment: $input-container-margin-top + $input-container-padding-top - + $input-padding-top + $input-padding-bottom + $input-border +$md-inline-alignment: $input-container-vertical-margin + $input-container-padding + + $input-padding-top + $input-padding-bottom + $input-border-width-default - $checkbox-text-margin-top !default; .md-inline-form { diff --git a/src/components/datepicker/datePicker.scss b/src/components/datepicker/datePicker.scss index a1b2fe31a0c..b9a6cc7d28b 100644 --- a/src/components/datepicker/datePicker.scss +++ b/src/components/datepicker/datePicker.scss @@ -17,7 +17,7 @@ md-datepicker { .md-inline-form { md-datepicker { - margin-top: 12px; + margin-top: $input-container-vertical-margin - 6px; } } diff --git a/src/components/input/_input-variables.scss b/src/components/input/_input-variables.scss index 4b52cb9d764..1d64caa2738 100644 --- a/src/components/input/_input-variables.scss +++ b/src/components/input/_input-variables.scss @@ -1,4 +1,6 @@ $input-container-padding: 2px !default; +$input-container-vertical-margin: 18px !default; +$input-container-horizontal-margin: 0px !default; $input-label-default-offset: 24px !default; $input-label-default-scale: 1.0 !default; @@ -11,11 +13,13 @@ $input-border-width-default: 1px !default; $input-border-width-focused: 2px !default; $input-line-height: 26px !default; $input-padding-top: 2px !default; +$input-padding-bottom: $input-border-width-focused - $input-border-width-default !default; $input-error-font-size: 12px !default; $input-error-height: 24px !default; $input-error-line-height: $input-error-font-size + 2px !default; -$error-padding-top: ($input-error-height - $input-error-line-height) / 2 !default; +// From Text field spec +$error-padding-top: $baseline-grid !default; $icon-offset: 36px !default; diff --git a/src/components/input/demoErrors/index.html b/src/components/input/demoErrors/index.html index 4bd70271bb0..dd17bc7f50f 100644 --- a/src/components/input/demoErrors/index.html +++ b/src/components/input/demoErrors/index.html @@ -27,6 +27,9 @@ Application Website +
+
This is required.
+
diff --git a/src/components/input/demoInlineForm/index.html b/src/components/input/demoInlineForm/index.html new file mode 100644 index 00000000000..ab01bdf74e4 --- /dev/null +++ b/src/components/input/demoInlineForm/index.html @@ -0,0 +1,83 @@ +
+
+
+ + + + + + + + + + + + + + + {{state.abbrev}} + + + + + + + + +
+
+ + + + + + + + + + {{state.abbrev}} + + + + + + + + + + + I agree to the license terms. + +
+
+ + + + + + + + + + + + Opt-in to emails + +
+
+ + + + + + + + TypeScript + JavaScript + Java + C# + +
+
+ +
diff --git a/src/components/input/demoInlineForm/script.js b/src/components/input/demoInlineForm/script.js new file mode 100644 index 00000000000..674e9159e54 --- /dev/null +++ b/src/components/input/demoInlineForm/script.js @@ -0,0 +1,25 @@ +angular.module('inputInlineForm', ['ngMaterial', 'ngMessages']) +.controller('DemoCtrl', function ($scope) { + $scope.user = { + title: 'Developer', + email: 'ipsum@lorem.com', + firstName: '', + lastName: '', + company: 'Google', + address: '1600 Amphitheatre Pkwy', + city: 'Mountain View', + state: null, + stateOfBirth: 'CA', + description: 'Loves TypeScript 💖', + postalCode: '94043', + licenseAccepted: true, + submissionDate: null, + marketingOptIn: true + }; + + $scope.states = ('AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD MA MI MN MS ' + + 'MO MT NE NV NH NJ NM NY NC ND OH OK OR PA RI SC SD TN TX UT VT VA WA WV WI ' + + 'WY').split(' ').map(function (state) { + return {abbrev: state}; + }); +}); diff --git a/src/components/input/demoInlineForm/style.scss b/src/components/input/demoInlineForm/style.scss new file mode 100644 index 00000000000..676a2c3d6d1 --- /dev/null +++ b/src/components/input/demoInlineForm/style.scss @@ -0,0 +1,8 @@ +.demo-inline-form-container { + padding: 16px; + + .demo-radio-button-label { + margin: 18px 16px; + padding-top: 6px; + } +} diff --git a/src/components/input/input.js b/src/components/input/input.js index e62efb86d7c..b29da30c971 100644 --- a/src/components/input/input.js +++ b/src/components/input/input.js @@ -89,11 +89,46 @@ if (window._mdMocksIncluded) { * *

When disabling floating labels

* - * * * * * + * + *

Aligning Form Elements

+ * Wrap your form elements with the `md-inline-form` class in order to align them horizontally + * within a form. + * + * + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * {{ state }} + * + * + * + * + * + * + * + * + * + * + * I agree to the license terms. + * + * + *
+ *
*/ function mdInputContainerDirective($mdTheming, $parse, $$rAF) { diff --git a/src/components/input/input.scss b/src/components/input/input.scss index 2e06e3b57c5..35ad09b96c3 100644 --- a/src/components/input/input.scss +++ b/src/components/input/input.scss @@ -3,7 +3,7 @@ md-input-container { display: inline-block; position: relative; padding: $input-container-padding; - margin: 18px 0; + margin: $input-container-vertical-margin $input-container-horizontal-margin; vertical-align: middle; &.md-block { @@ -51,15 +51,15 @@ md-input-container { input[type="month"], input[type="time"], input[type="week"] { - min-height: $input-line-height; + min-height: $input-line-height + $input-padding-top * 2; } textarea { resize: none; overflow: hidden; &.md-input { - min-height: $input-line-height; - -ms-flex-preferred-size: auto; //IE fix + min-height: $input-line-height + $input-padding-top * 2; + -ms-flex-preferred-size: auto; // IE fix } // The height usually gets set to 1 line by `.md-input`. @@ -153,12 +153,12 @@ md-input-container { background: none; padding-top: $input-padding-top; - padding-bottom: $input-border-width-focused - $input-border-width-default; + padding-bottom: $input-padding-bottom; @include rtl(padding-left, 0, $input-container-padding); @include rtl(padding-right, $input-container-padding, 0); border-width: 0 0 $input-border-width-default 0; line-height: $input-line-height; - height: $input-line-height + ($input-padding-top * 2); + height: $input-line-height + $input-padding-top * 2; -ms-flex-preferred-size: $input-line-height; //IE fix border-radius: 0; border-style: solid; // Firefox fix @@ -200,7 +200,6 @@ md-input-container { order: 4; overflow: hidden; @include rtl(clear, left, right); - } .md-input-message-animation, .md-char-counter { @@ -213,9 +212,6 @@ md-input-container { // Default state for messages is to be visible opacity: 1; margin-top: 0; - - // Add some top padding which is equal to half the difference between the expected height - // and the actual height padding-top: $error-padding-top; &:not(.md-char-counter) { diff --git a/src/components/input/input.spec.js b/src/components/input/input.spec.js index 71d684264b8..6def3e51817 100644 --- a/src/components/input/input.spec.js +++ b/src/components/input/input.spec.js @@ -1,9 +1,6 @@ describe('md-input-container directive', function() { var $rootScope, $compile, $timeout, pageScope, $material; - var invalidAnimation, messagesAnimation, messageAnimation; - var $animProvider; - beforeEach(module('ngAria', 'material.components.input', 'ngMessages')); // Setup/grab our variables @@ -916,8 +913,6 @@ describe('md-input-container directive', function() { createAndAppendElement('rows="5"'); ngTextarea.val('1\n2\n3\n4\n5\n6\n7'); ngTextarea.triggerHandler('input'); - expect(textarea.rows).toBe(7); - ngTextarea.val(''); ngTextarea.triggerHandler('input'); expect(textarea.rows).toBe(5); diff --git a/src/components/radioButton/demoBasicUsage/index.html b/src/components/radioButton/demoBasicUsage/index.html index 7bb088244f0..c3a063175c7 100644 --- a/src/components/radioButton/demoBasicUsage/index.html +++ b/src/components/radioButton/demoBasicUsage/index.html @@ -5,7 +5,7 @@ Apple - Banana + Banana Mango diff --git a/src/components/radioButton/radio-button.scss b/src/components/radioButton/radio-button.scss index 05498c6c7de..97e0be6cc38 100644 --- a/src/components/radioButton/radio-button.scss +++ b/src/components/radioButton/radio-button.scss @@ -146,14 +146,21 @@ md-radio-group { .md-inline-form { md-radio-group { - margin: 18px 0 19px; + margin: $input-container-vertical-margin 0 $input-container-vertical-margin + 1px; md-radio-button { display: inline-block; height: 30px; - padding: 2px; + padding: 2px 10px 2px 6px; box-sizing: border-box; margin-top: 0; margin-bottom: 0; + + .md-label { + top: 4px; + } + .md-container { + margin-top: 2px; + } } } } diff --git a/src/components/select/select.scss b/src/components/select/select.scss index 2a593e02bfb..0b2799d7cfe 100755 --- a/src/components/select/select.scss +++ b/src/components/select/select.scss @@ -6,20 +6,14 @@ $select-option-height: 48px !default; $select-option-padding: 16px !default; $select-container-padding: 16px !default; $select-container-transition-duration: 350ms !default; -$select-value-padding-top: 6px; -$select-value-padding-bottom: 4px; +$select-value-padding-top: 2px; +$select-value-padding-bottom: 1px; $select-max-visible-options: 5 !default; -// from input.scss -$input-container-margin-top: 18px !default; -$input-container-padding-top: 2px !default; -$input-padding-top: 2px !default; -$input-padding-bottom: 1px !default; - $input-alignment: ($input-padding-top + $input-padding-bottom) - ($select-value-padding-top + $select-value-padding-bottom); -$md-inline-alignment: ($input-container-margin-top + $input-container-padding-top) +$md-inline-alignment: ($input-container-vertical-margin + $input-container-padding) + ($input-padding-top + $input-padding-bottom) - ($select-value-padding-top + $select-value-padding-bottom); @@ -162,16 +156,10 @@ md-select { &:hover { cursor: pointer } - &.ng-invalid.ng-touched { - .md-select-value { - border-bottom: 2px solid; - } - } &:focus { .md-select-value { - border-bottom-width: $select-border-width-default + 1px; - border-bottom-style: solid; - padding-bottom: $select-value-padding-bottom - 1; + border-bottom: $select-border-width-default + 1px solid; + padding-bottom: $select-value-padding-bottom - 1px; } } } @@ -251,7 +239,7 @@ md-input-container md-select { @include rtl(right, -4px, auto); @include rtl(left, auto, -4px); speak: none; - font-size: 16px; + font-size: 13px; transform: scaleY(0.5); } diff --git a/src/components/switch/switch.scss b/src/components/switch/switch.scss index 9b0100fc547..41c33757be2 100644 --- a/src/components/switch/switch.scss +++ b/src/components/switch/switch.scss @@ -6,8 +6,8 @@ $switch-margin: 16px !default; .md-inline-form { md-switch { - margin-top: 18px; - margin-bottom: 19px; + margin-top: $input-container-vertical-margin; + margin-bottom: $input-container-vertical-margin + 1px; } }