diff --git a/src/components/accordion/_accordion.scss b/src/components/accordion/_accordion.scss index 28cb1b9d56af..0e7ac2ab7260 100644 --- a/src/components/accordion/_accordion.scss +++ b/src/components/accordion/_accordion.scss @@ -26,7 +26,7 @@ .#{$prefix}--accordion__arrow { @include focus-outline('border'); overflow: visible; // safari fix - outline-offset: -.5px; // safari fix + outline-offset: -0.5px; // safari fix } } @@ -53,7 +53,7 @@ .#{$prefix}--accordion__arrow { @include focus-outline('border'); overflow: visible; // safari fix - outline-offset: -.5px; // safari fix + outline-offset: -0.5px; // safari fix } } } @@ -82,22 +82,52 @@ @include typescale('zeta'); } } -} -.#{$prefix}--accordion__item--active { - overflow: visible; + .#{$prefix}--accordion__item--active { + overflow: visible; - .#{$prefix}--accordion__content { - padding-top: $spacing-md; - padding-bottom: $spacing-lg; - height: auto; - visibility: visible; - opacity: 1; - transition: all $transition--expansion $carbon--ease-in; + .#{$prefix}--accordion__content { + padding-top: $spacing-md; + padding-bottom: $spacing-lg; + height: auto; + visibility: visible; + opacity: 1; + transition: all $transition--expansion $carbon--ease-in; + } + + .#{$prefix}--accordion__arrow { + transform: rotate(90deg); + fill: $brand-01; + } } - .#{$prefix}--accordion__arrow { - transform: rotate(90deg); - fill: $brand-01; + // Skeleton state + .#{$prefix}--accordion.#{$prefix}--skeleton .#{$prefix}--accordion__heading, + .#{$prefix}--accordion.#{$prefix}--skeleton .#{$prefix}--accordion__button { + cursor: default; + } + + .#{$prefix}--accordion.#{$prefix}--skeleton .#{$prefix}--accordion__arrow { + pointer-events: none; + fill: $ui-05; + cursor: default; + + &:hover, + &:focus, + &:active { + border: none; + outline: none; + cursor: default; + } + } + + .#{$prefix}--skeleton .#{$prefix}--accordion__heading:focus .#{$prefix}--accordion__arrow { + border: none; + outline: none; + cursor: default; + } + + .#{$prefix}--accordion__title.#{$prefix}--skeleton__text { + margin-bottom: 0; } } diff --git a/src/components/breadcrumb/_breadcrumb.scss b/src/components/breadcrumb/_breadcrumb.scss index e80b0bf4653f..f031978970ab 100644 --- a/src/components/breadcrumb/_breadcrumb.scss +++ b/src/components/breadcrumb/_breadcrumb.scss @@ -63,4 +63,11 @@ } } } + + // Skeleton State + .#{$prefix}--breadcrumb.#{$prefix}--skeleton .#{$prefix}--link { + @include skeleton; + width: rem(100px); + height: 1rem; + } } diff --git a/src/components/button/_button.scss b/src/components/button/_button.scss index e0329ed9d717..35fe43b30af8 100644 --- a/src/components/button/_button.scss +++ b/src/components/button/_button.scss @@ -180,4 +180,10 @@ .#{$prefix}--btn--tertiary + .#{$prefix}--btn--danger--primary { margin-left: $spacing-md; } + + // Skeleton State + .#{$prefix}--btn.#{$prefix}--skeleton { + @include skeleton; + width: rem(150px); + } } diff --git a/src/components/checkbox/_checkbox.scss b/src/components/checkbox/_checkbox.scss index adfccdbae38d..18f2a95fd7de 100644 --- a/src/components/checkbox/_checkbox.scss +++ b/src/components/checkbox/_checkbox.scss @@ -160,4 +160,16 @@ } } } + + // Skeleton state + .#{$prefix}--checkbox-label.#{$prefix}--skeleton { + @include skeleton; + width: rem(100px); + height: rem(18px); + + &:after, + &:before { + border: none; + } + } } diff --git a/src/components/code-snippet/_code-snippet.scss b/src/components/code-snippet/_code-snippet.scss index bebd67edd4d6..de2acd0078e1 100644 --- a/src/components/code-snippet/_code-snippet.scss +++ b/src/components/code-snippet/_code-snippet.scss @@ -91,4 +91,24 @@ top: 1rem; right: 1.25rem; } + + // Skeleton State + .#{$prefix}--snippet--code.#{$prefix}--skeleton { + height: rem(98px); + } + + .#{$prefix}--snippet--terminal.#{$prefix}--skeleton { + height: rem(56px); + } + + .#{$prefix}--snippet.#{$prefix}--skeleton .#{$prefix}--snippet-container { + height: 100%; + } + + .#{$prefix}--snippet.#{$prefix}--skeleton code { + @include skeleton; + width: 100%; + height: 1rem; + display: block; + } } diff --git a/src/components/data-table-v2/_data-table-v2-skeleton.scss b/src/components/data-table-v2/_data-table-v2-skeleton.scss new file mode 100644 index 000000000000..f1f5faf7b601 --- /dev/null +++ b/src/components/data-table-v2/_data-table-v2-skeleton.scss @@ -0,0 +1,45 @@ +@import '../../globals/scss/import-once'; + +@include exports('data-table-v2-skeleton') { + .#{$prefix}--data-table-v2.#{$prefix}--skeleton { + th { + border-bottom: 1px solid $brand-01; + + &:nth-child(3n + 1) { + width: 10%; + } + + &:nth-child(3n + 2) { + width: 30%; + } + + &:nth-child(3n + 3) { + width: 15%; + } + } + + th span, + td span { + @include skeleton; + width: 75%; + height: 1rem; + display: block; + } + + tr:hover { + td { + border-color: $ui-04; + background: transparent; + + &:first-of-type, + &:last-of-type { + border-color: $ui-04; + } + } + } + } + + .#{$prefix}--data-table-v2.#{$prefix}--skeleton .#{$prefix}--table-sort-v2 { + pointer-events: none; + } +} diff --git a/src/components/data-table-v2/_data-table-v2.scss b/src/components/data-table-v2/_data-table-v2.scss index 11cdccd04b07..7aef754bef24 100644 --- a/src/components/data-table-v2/_data-table-v2.scss +++ b/src/components/data-table-v2/_data-table-v2.scss @@ -7,3 +7,4 @@ @import 'data-table-v2-expandable'; @import 'data-table-v2-sort'; @import 'data-table-v2-inline-edit'; +@import 'data-table-v2-skeleton'; diff --git a/src/components/date-picker/_date-picker.scss b/src/components/date-picker/_date-picker.scss index 15347e9fb811..bb0f4e93ac13 100644 --- a/src/components/date-picker/_date-picker.scss +++ b/src/components/date-picker/_date-picker.scss @@ -349,4 +349,21 @@ .flatpickr-next-month { padding-top: 5px; } + + // Skeleton State + .#{$prefix}--date-picker.#{$prefix}--skeleton input, + .#{$prefix}--date-picker__input.#{$prefix}--skeleton { + @include skeleton; + width: 100%; + + &::-webkit-input-placeholder { + color: transparent; + } + } + + .#{$prefix}--date-picker.#{$prefix}--skeleton .#{$prefix}--label { + @include skeleton; + width: rem(75px); + height: rem(14px); + } } diff --git a/src/components/dropdown/_dropdown.scss b/src/components/dropdown/_dropdown.scss index 098c868b7e89..9e9e3929f640 100644 --- a/src/components/dropdown/_dropdown.scss +++ b/src/components/dropdown/_dropdown.scss @@ -212,4 +212,9 @@ color: $text-01; } } + + // Skeleton State + .#{$prefix}--dropdown-v2.#{$prefix}--skeleton { + @include skeleton; + } } diff --git a/src/components/form/_form.scss b/src/components/form/_form.scss index 1d8cc6387138..bd467bdc08de 100644 --- a/src/components/form/_form.scss +++ b/src/components/form/_form.scss @@ -40,6 +40,13 @@ opacity: 0.5; } + // Skeleton State + .#{$prefix}--label.#{$prefix}--skeleton { + @include skeleton; + width: rem(75px); + height: rem(14px); + } + input[data-invalid], textarea[data-invalid], select[data-invalid] { diff --git a/src/components/number-input/_number-input.scss b/src/components/number-input/_number-input.scss index e2c2c2e675a5..0e56c3a910b4 100644 --- a/src/components/number-input/_number-input.scss +++ b/src/components/number-input/_number-input.scss @@ -99,13 +99,24 @@ fill: $brand-02; } } -} -.#{$prefix}--number[data-invalid] { - input[type='number'] { - box-shadow: 0 2px 0px 0px $support-01; + .#{$prefix}--number[data-invalid] { + input[type='number'] { + box-shadow: 0 2px 0px 0px $support-01; + } + ~ .#{$prefix}--form-requirement { + max-height: rem(200px); + } } - ~ .#{$prefix}--form-requirement { - max-height: rem(200px); + + // Skeleton State + .#{$prefix}--number.#{$prefix}--skeleton { + @include skeleton; + width: 100%; + height: 2.5rem; + + input[type='number'] { + display: none; + } } } diff --git a/src/components/pagination/_pagination.scss b/src/components/pagination/_pagination.scss index 81a5bcdf5af7..b3f2b378580d 100644 --- a/src/components/pagination/_pagination.scss +++ b/src/components/pagination/_pagination.scss @@ -176,4 +176,10 @@ $css--helpers: true; right: 0.3rem; } } + + // Skeleton state + .#{$prefix}--pagination.#{$prefix}--skeleton .#{$prefix}--skeleton__text { + margin-right: 1rem; + margin-bottom: 0; + } } diff --git a/src/components/progress-indicator/_progress-indicator.scss b/src/components/progress-indicator/_progress-indicator.scss index 000202673f70..b4c4e0d088ac 100644 --- a/src/components/progress-indicator/_progress-indicator.scss +++ b/src/components/progress-indicator/_progress-indicator.scss @@ -108,4 +108,11 @@ background-color: $brand-01; } } + + // Skeleton State + .#{$prefix}--progress.#{$prefix}--skeleton .#{$prefix}--progress-label { + @include skeleton; + height: rem(12px); + width: rem(40px); + } } diff --git a/src/components/radio-button/_radio-button.scss b/src/components/radio-button/_radio-button.scss index 4e6b22399164..0039aa1e5233 100644 --- a/src/components/radio-button/_radio-button.scss +++ b/src/components/radio-button/_radio-button.scss @@ -67,4 +67,15 @@ .#{$prefix}--radio-button:focus + .#{$prefix}--radio-button__label .#{$prefix}--radio-button__appearance { @include focus-outline('blurred'); } + + // Skeleton State + .#{$prefix}--radio-button__label.#{$prefix}--skeleton { + @include skeleton; + width: rem(100px); + height: rem(18px); + } + + .#{$prefix}--radio-button__label.#{$prefix}--skeleton .#{$prefix}--radio-button__appearance { + display: none; + } } diff --git a/src/components/search/_search.scss b/src/components/search/_search.scss index af21bbedb8f4..4285361fc561 100644 --- a/src/components/search/_search.scss +++ b/src/components/search/_search.scss @@ -143,4 +143,14 @@ .#{$prefix}--search-view--hidden { display: none; } + + .#{$prefix}--search--lg.#{$prefix}--skeleton .#{$prefix}--search-input, + .#{$prefix}--search--sm.#{$prefix}--skeleton .#{$prefix}--search-input { + @include skeleton; + width: 100%; + + &::-webkit-input-placeholder { + color: transparent; + } + } } diff --git a/src/components/skeleton/_skeleton-icon.scss b/src/components/skeleton/_skeleton-icon.scss new file mode 100644 index 000000000000..ef59f7c5b5e6 --- /dev/null +++ b/src/components/skeleton/_skeleton-icon.scss @@ -0,0 +1,10 @@ +@import '../../globals/scss/import-once'; + +@include exports('skeleton-icon') { + .#{$prefix}--icon--skeleton { + @include skeleton; + display: inline-block; + width: rem(16px); + height: rem(16px); + } +} diff --git a/src/components/skeleton/_skeleton-text.scss b/src/components/skeleton/_skeleton-text.scss new file mode 100644 index 000000000000..dc04c4cfb3a4 --- /dev/null +++ b/src/components/skeleton/_skeleton-text.scss @@ -0,0 +1,15 @@ +@import '../../globals/scss/import-once'; + +@include exports('skeleton-text') { + .#{$prefix}--skeleton__text { + @include skeleton; + width: 100%; + height: 1rem; + margin-bottom: $spacing-xs; + } + + .#{$prefix}--skeleton__heading { + height: 1.5rem; + margin-bottom: $spacing-sm; + } +} diff --git a/src/components/skeleton/_skeleton.scss b/src/components/skeleton/_skeleton.scss new file mode 100644 index 000000000000..d0cd65e39524 --- /dev/null +++ b/src/components/skeleton/_skeleton.scss @@ -0,0 +1,6 @@ +@import '../../globals/scss/vars'; +@import '../../globals/scss/spacing'; +@import '../../globals/scss/helper-mixins'; + +@import 'skeleton-text'; +@import 'skeleton-icon'; diff --git a/src/components/skeleton/skeleton.html b/src/components/skeleton/skeleton.html new file mode 100644 index 000000000000..9853f6f3a993 --- /dev/null +++ b/src/components/skeleton/skeleton.html @@ -0,0 +1,124 @@ + +

Skeleton Text

+
+
+ +

Button

+ + +

Label

+ + +

Breadcrumb

+
+
+   +
+
+   +
+
+   +
+
+ +

Dropdown

+
+
+ +
+
+ +

Progress Indicator

+ + +

Toggle

+
+ + +
+ +

Small Toggle

+
+ + +
+ +

Slider

+
+ +
+
+
+
+
+
+
+
+ +

Tag

+ + +

Tabs

+ + +

Icon

+
\ No newline at end of file diff --git a/src/components/slider/_slider.scss b/src/components/slider/_slider.scss index dee04a43efc4..21bc32cc8866 100644 --- a/src/components/slider/_slider.scss +++ b/src/components/slider/_slider.scss @@ -124,4 +124,22 @@ display: none; } } + + // Skeleton state + .#{$prefix}--slider-container.#{$prefix}--skeleton .#{$prefix}--slider__range-label { + @include skeleton; + width: rem(20px); + height: rem(12px); + } + + .#{$prefix}--slider-container.#{$prefix}--skeleton .#{$prefix}--slider__track { + cursor: default; + pointer-events: none; + } + + .#{$prefix}--slider-container.#{$prefix}--skeleton .#{$prefix}--slider__thumb { + left: 50%; + cursor: default; + pointer-events: none; + } } diff --git a/src/components/structured-list/_structured-list.scss b/src/components/structured-list/_structured-list.scss index 59fa54cc6de8..07d9b991e232 100644 --- a/src/components/structured-list/_structured-list.scss +++ b/src/components/structured-list/_structured-list.scss @@ -128,6 +128,40 @@ } } + // Skeleton State + .#{$prefix}--structured-list.#{$prefix}--skeleton { + .#{$prefix}--structured-list-th { + &:first-child { + width: 8%; + } + + &:nth-child(3n + 2) { + width: 30%; + } + + &:nth-child(3n + 3) { + width: 15%; + } + } + + .bx--structured-list-th span { + @include skeleton; + width: 75%; + height: 1rem; + display: block; + } + } + + .#{$prefix}--structured-list.#{$prefix}--structured-list--border.#{$prefix}--skeleton { + .#{$prefix}--structured-list-th:first-child { + width: 5%; + + span { + display: none; + } + } + } + // Deprecated class .#{$prefix}--structured-list-content { @include typescale('zeta'); diff --git a/src/components/tabs/_tabs.scss b/src/components/tabs/_tabs.scss index 29862c4663a7..33b5075f715b 100644 --- a/src/components/tabs/_tabs.scss +++ b/src/components/tabs/_tabs.scss @@ -73,7 +73,7 @@ display: flex; flex-direction: column; z-index: z('dropdown'); - + @include breakpoint(bp--sm--major) { @include typescale('epsilon'); flex-direction: row; @@ -178,4 +178,25 @@ } } } + + // Skeleton state + .#{$prefix}--tabs.#{$prefix}--skeleton { + pointer-events: none; + cursor: default; + } + + .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs__nav-link { + @include skeleton; + width: rem(75px); + height: rem(12px); + } + + .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger { + @include skeleton; + width: rem(100px); + } + + .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger svg { + @include hidden; + } } diff --git a/src/components/tag/_tag.scss b/src/components/tag/_tag.scss index 0693e1af5f51..278e10127cd2 100644 --- a/src/components/tag/_tag.scss +++ b/src/components/tag/_tag.scss @@ -50,4 +50,17 @@ .#{$prefix}--tag--private { @include tag-theme($color__yellow-10, $color__yellow-60); } + + // Skeleton state + .#{$prefix}--tag.#{$prefix}--skeleton { + @include tag-theme($color__gray-1, $color__navy-gray-4); + width: rem(60px); + + &:after { + @include skeleton; + content: ''; + height: rem(6px); + width: 100%; + } + } } diff --git a/src/components/text-area/_text-area.scss b/src/components/text-area/_text-area.scss index 78a80bb00202..b9c29b7ce7a5 100644 --- a/src/components/text-area/_text-area.scss +++ b/src/components/text-area/_text-area.scss @@ -41,4 +41,14 @@ border: $input-border; } } + + // Skeleton State + #{$prefix}--text-area.#{$prefix}--skeleton { + @include skeleton; + height: rem(100px); + + &::-webkit-input-placeholder { + color: transparent; + } + } } diff --git a/src/components/text-input/_text-input.scss b/src/components/text-input/_text-input.scss index 1b6aecc4d732..05c6a1d0eae3 100644 --- a/src/components/text-input/_text-input.scss +++ b/src/components/text-input/_text-input.scss @@ -43,4 +43,14 @@ border: $input-border; } } + + // Skeleton State + .#{$prefix}--text-input.#{$prefix}--skeleton { + @include skeleton; + width: 100%; + + &::-webkit-input-placeholder { + color: transparent; + } + } } diff --git a/src/components/toggle/_toggle.scss b/src/components/toggle/_toggle.scss index 8ec754f66301..15128aa10a4c 100644 --- a/src/components/toggle/_toggle.scss +++ b/src/components/toggle/_toggle.scss @@ -174,4 +174,37 @@ transition: $transition--base $carbon--standard-easing; } } + + // Skeleton state + .#{$prefix}--toggle.#{$prefix}--skeleton + .#{$prefix}--toggle__label { + cursor: default; + } + + .#{$prefix}--toggle.#{$prefix}--skeleton + .#{$prefix}--toggle__label > .#{$prefix}--toggle__appearance { + &:before, + &:after { + background-color: $brand-01; + border-color: $brand-01; + cursor: default; + } + } + + .#{$prefix}--toggle.#{$prefix}--skeleton + .#{$prefix}--toggle__label > .#{$prefix}--toggle__text--left, + .#{$prefix}--toggle.#{$prefix}--skeleton + .#{$prefix}--toggle__label > .#{$prefix}--toggle__text--right { + @include skeleton; + width: rem(20px); + height: rem(12px); + } + + .#{$prefix}--toggle.#{$prefix}--skeleton + .#{$prefix}--toggle__label > .#{$prefix}--toggle__appearance { + &:before { + background: transparent; + border-color: $ui-05; + } + + &:after { + background-color: $ui-05; + border: none; + } + } } diff --git a/src/globals/scss/_helper-mixins.scss b/src/globals/scss/_helper-mixins.scss index 28831b9b3ccd..fce392bed627 100644 --- a/src/globals/scss/_helper-mixins.scss +++ b/src/globals/scss/_helper-mixins.scss @@ -105,12 +105,93 @@ $deprecations--reasons: append($deprecations--reasons, $reason) !global; @content; } @else { - @warn 'Deprecated code was found, this code will be removed before the next release of Carbon. -REASON: #{$reason}'; + @warn 'Deprecated code was found, this code will be removed before the next release of Carbon. REASON: #{$reason}'; @content; } } +// 💀 Skeleton loading animation + +@mixin skeleton { + position: relative; + border: none; + padding: 0; + box-shadow: none; + pointer-events: none; + background: $skeleton; + + &:hover, + &:focus, + &:active { + border: none; + outline: none; + cursor: default; + } + + &:before { + content: ''; + width: 0%; + height: 100%; + position: absolute; + top: 0; + left: 0; + opacity: 0.3; + background: $skeleton; + animation: 3000ms ease-in-out skeleton infinite; + } +} + +@keyframes skeleton { + 0% { + width: 0%; + left: 0; + right: auto; + opacity: 0.3; + } + 20% { + width: 100%; + left: 0; + right: auto; + opacity: 1; + } + 28% { + width: 100%; + left: auto; + right: 0; + } + 51% { + width: 0%; + left: auto; + right: 0; + } + 58% { + width: 0%; + left: auto; + right: 0; + } + 82% { + width: 100%; + left: auto; + right: 0; + } + 83% { + width: 100%; + left: 0; + right: auto; + } + 96% { + width: 0%; + left: 0; + right: auto; + } + 100% { + width: 0%; + left: 0; + right: auto; + opacity: 0.3; + } +} + //---------------------------------------------- // Deprecated // --------------------------------------------- diff --git a/src/globals/scss/_vars.scss b/src/globals/scss/_vars.scss index a3a19b4eb2c6..6b974decd354 100644 --- a/src/globals/scss/_vars.scss +++ b/src/globals/scss/_vars.scss @@ -34,7 +34,7 @@ $text-01: $color__blue-90 !default; $text-02: $color__navy-gray-6 !default; $text-03: $color__navy-gray-6 !default; $field-01: rgba($color__blue-51, 0.1) !default; -$support-01: #E0182D !default; +$support-01: #e0182d !default; $support-02: $color__green-40 !default; $support-03: $color__yellow-30 !default; $support-04: $color__blue-30 !default; @@ -65,7 +65,7 @@ $accordion-flex-direction: row !default; $accordion-justify-content: flex-start !default; $accordion-arrow-margin: 0 0 0 $spacing-2xs !default; $accordion-title-margin: 0 0 0 $spacing-md !default; -$accordion-content-padding: 0 $spacing-md 0 $spacing-2xl !default; +$accordion-content-padding: 0 $spacing-md 0 $spacing-2xl !default; // Card $card-text-align: center !default; @@ -101,3 +101,7 @@ $radio-border-width: 2px !default; // Structured Theme Variables $structured-list-padding: 2rem !default; $structured-list-text-transform: none !default; + +// Skeleton Loading + +$skeleton: rgba($color__blue-51, 0.1) !default; //old $field-01 diff --git a/src/globals/scss/styles.scss b/src/globals/scss/styles.scss index 9fa964a35a65..970ea3665c25 100644 --- a/src/globals/scss/styles.scss +++ b/src/globals/scss/styles.scss @@ -98,6 +98,7 @@ $deprecations--message: 'Deprecated code was found, this code will be removed be @import '../../components/tile/tile'; @import '../../components/lightbox/lightbox'; @import '../../components/carousel/carousel'; +@import '../../components/skeleton/skeleton'; //------------------------------------- // 🙈 Hidden (Not exposed on website)