From 6132683e7e80636453b5aa0fb5c6ec01eb95de3a Mon Sep 17 00:00:00 2001 From: Nikita Barsukov Date: Mon, 29 Jan 2024 14:28:33 +0300 Subject: [PATCH] feat(core)!: `Loader` has new algorithm to calculate `stroke-width` (#6550) --- .../components/loader/loader.component.ts | 1 + .../core/components/loader/loader.style.less | 97 +++++++++---------- .../components/loader/loader.template.html | 9 +- .../components/loader/examples/5/index.html | 3 + .../components/loader/examples/5/index.less | 27 ++++++ .../components/loader/examples/5/index.ts | 14 +++ .../components/loader/loader.component.ts | 6 ++ .../components/loader/loader.module.ts | 2 + .../components/loader/loader.template.html | 14 +++ 9 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 projects/demo/src/modules/components/loader/examples/5/index.html create mode 100644 projects/demo/src/modules/components/loader/examples/5/index.less create mode 100644 projects/demo/src/modules/components/loader/examples/5/index.ts diff --git a/projects/core/components/loader/loader.component.ts b/projects/core/components/loader/loader.component.ts index 97451d4d513a..8d1c0150bf03 100644 --- a/projects/core/components/loader/loader.component.ts +++ b/projects/core/components/loader/loader.component.ts @@ -26,6 +26,7 @@ import {TUI_LOADER_OPTIONS, TuiLoaderOptions} from './loader.options'; }) export class TuiLoaderComponent { @Input() + @HostBinding('attr.data-size') size = this.options.size; @Input() diff --git a/projects/core/components/loader/loader.style.less b/projects/core/components/loader/loader.style.less index bafd7fb139f6..7992e30058fb 100644 --- a/projects/core/components/loader/loader.style.less +++ b/projects/core/components/loader/loader.style.less @@ -1,26 +1,49 @@ @import '@taiga-ui/core/styles/taiga-ui-local'; -@size-xs: 0.75rem; -@size-s: 1rem; -@size-m: 1.5rem; -@size-l: 2.5rem; -@size-xl: 3.5rem; -@size-xxl: 5rem; -@width-xs: 38; -@width-s: 25; -@width-m: 17; -@width-l: 15; -@width-xl: 14; -@width-xxl: 10; +// Safari doesn't support rem units for all properties of ``. +// ``'s wrapper has `font-size: 1rem` to use em units as rem ones interchangeably +@circle-diameter: { + xs: 0.75em; + s: 1em; + m: 1.5em; + l: 2.5em; + xl: 3.5em; + xxl: 5em; +}; :host { position: relative; display: flex; min-width: 1.5rem; + --tui-thickness: calc(var(--t-diameter) / 12); &._loading { overflow: hidden; } + + &[data-size='xs'] { + --t-diameter: @circle-diameter[xs]; + } + + &[data-size='s'] { + --t-diameter: @circle-diameter[s]; + } + + &[data-size='m'] { + --t-diameter: @circle-diameter[m]; + } + + &[data-size='l'] { + --t-diameter: @circle-diameter[l]; + } + + &[data-size='xl'] { + --t-diameter: @circle-diameter[xl]; + } + + &[data-size='xxl'] { + --t-diameter: @circle-diameter[xxl]; + } } .t-content { @@ -48,11 +71,13 @@ align-items: center; justify-content: center; min-width: 100%; + min-height: var(--t-diameter); flex-shrink: 0; align-self: center; color: var(--tui-text-01); stroke: var(--tui-primary); animation: tuiFadeIn var(--tui-duration); + font-size: 1rem; // to use em units as rem ones interchangeably (Safari) &&_horizontal { flex-direction: row; @@ -62,36 +87,6 @@ color: inherit; stroke: currentColor; } - - &[data-size='xs'] { - font-size: @size-xs; - stroke-width: @width-xs; - } - - &[data-size='s'] { - font-size: @size-s; - stroke-width: @width-s; - } - - &[data-size='m'] { - font-size: @size-m; - stroke-width: @width-m; - } - - &[data-size='l'] { - font-size: @size-l; - stroke-width: @width-l; - } - - &[data-size='xl'] { - font-size: @size-xl; - stroke-width: @width-xl; - } - - &[data-size='xxl'] { - font-size: @size-xxl; - stroke-width: @width-xxl; - } } .t-text { @@ -131,18 +126,16 @@ } }); display: block; - min-width: 1em; - max-width: 1em; - min-height: 1em; - max-height: 1em; - margin: @space -0.5em; + width: var(--t-diameter); + height: var(--t-diameter); + margin: @space calc(var(--t-diameter) / -2); border-radius: 100%; overflow: hidden; animation: tuiLoaderRotate 4s linear infinite; } -@radius: 3.125em; // don't use rem units (Safari doesn't support rem units inside ) -@circumference: 2 * pi() * @radius; +@radius: calc(var(--t-diameter) / 2 - var(--tui-thickness)); +@circumference: calc(2 * pi() * @radius); @keyframes tuiLoaderDashOffset { 0% { @@ -150,7 +143,7 @@ } 50% { - stroke-dashoffset: 0.05 * @circumference; + stroke-dashoffset: calc(0.05 * @circumference); } 100% { @@ -159,11 +152,11 @@ } .t-circle { - font-size: 1rem; // to use em units as rem ones interchangeably (Safari) r: @radius; stroke-dasharray: @circumference; fill: none; stroke: inherit; - stroke-width: inherit; + // Use native CSS max function instead LESS one + stroke-width: ~'max(var(--tui-thickness), 1.5px)'; animation: tuiLoaderDashOffset 4s linear infinite; } diff --git a/projects/core/components/loader/loader.template.html b/projects/core/components/loader/loader.template.html index 12c1929bc94f..cf565ce65ecf 100644 --- a/projects/core/components/loader/loader.template.html +++ b/projects/core/components/loader/loader.template.html @@ -11,20 +11,19 @@
diff --git a/projects/demo/src/modules/components/loader/examples/5/index.html b/projects/demo/src/modules/components/loader/examples/5/index.html new file mode 100644 index 000000000000..649c8e3387ec --- /dev/null +++ b/projects/demo/src/modules/components/loader/examples/5/index.html @@ -0,0 +1,3 @@ + + + diff --git a/projects/demo/src/modules/components/loader/examples/5/index.less b/projects/demo/src/modules/components/loader/examples/5/index.less new file mode 100644 index 000000000000..bcce6f901266 --- /dev/null +++ b/projects/demo/src/modules/components/loader/examples/5/index.less @@ -0,0 +1,27 @@ +tui-loader { + min-width: 3.5rem; + + &:nth-child(1) { + /** + Don't use `rem` units if you support Safari. + Safari doesn't support `rem` units for `stroke-*` properties of ``. + Use `em` units => they will be interpreted as `rem` ones + (`` has `font-size: 1rem`). + Or just use simple `px` units. + */ + --tui-thickness: 0.125em; + } + + &:nth-child(2) { + --tui-thickness: 4px; + } + + &:nth-child(3) { + --tui-thickness: 8px; + } +} + +:host { + display: flex; + gap: 2rem; +} diff --git a/projects/demo/src/modules/components/loader/examples/5/index.ts b/projects/demo/src/modules/components/loader/examples/5/index.ts new file mode 100644 index 000000000000..4743ff16f9f9 --- /dev/null +++ b/projects/demo/src/modules/components/loader/examples/5/index.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; +import {tuiLoaderOptionsProvider} from '@taiga-ui/core'; + +@Component({ + selector: 'tui-loader-example-5', + templateUrl: './index.html', + styleUrls: ['./index.less'], + encapsulation, + changeDetection, + providers: [tuiLoaderOptionsProvider({size: 'xl'})], +}) +export class TuiLoaderExample5 {} diff --git a/projects/demo/src/modules/components/loader/loader.component.ts b/projects/demo/src/modules/components/loader/loader.component.ts index 51414743d42d..0f2a982f456d 100644 --- a/projects/demo/src/modules/components/loader/loader.component.ts +++ b/projects/demo/src/modules/components/loader/loader.component.ts @@ -39,6 +39,12 @@ export class ExampleTuiLoaderComponent { HTML: import('./examples/4/index.html?raw'), }; + readonly example5: TuiDocExample = { + HTML: import('./examples/5/index.html?raw'), + LESS: import('./examples/5/index.less?raw'), + TypeScript: import('./examples/5/index.ts?raw'), + }; + showLoader = true; inheritColor = false; diff --git a/projects/demo/src/modules/components/loader/loader.module.ts b/projects/demo/src/modules/components/loader/loader.module.ts index e6f328d2f7a5..4296eb2d58e1 100644 --- a/projects/demo/src/modules/components/loader/loader.module.ts +++ b/projects/demo/src/modules/components/loader/loader.module.ts @@ -11,6 +11,7 @@ import {TuiLoaderExample1} from './examples/1'; import {TuiLoaderExample2} from './examples/2'; import {TuiLoaderExample3} from './examples/3'; import {TuiLoaderExample4} from './examples/4'; +import {TuiLoaderExample5} from './examples/5'; import {ExampleTuiLoaderComponent} from './loader.component'; @NgModule({ @@ -32,6 +33,7 @@ import {ExampleTuiLoaderComponent} from './loader.component'; TuiLoaderExample2, TuiLoaderExample3, TuiLoaderExample4, + TuiLoaderExample5, ], exports: [ExampleTuiLoaderComponent], }) diff --git a/projects/demo/src/modules/components/loader/loader.template.html b/projects/demo/src/modules/components/loader/loader.template.html index e2e5a9b0d411..e56ce75d22f6 100644 --- a/projects/demo/src/modules/components/loader/loader.template.html +++ b/projects/demo/src/modules/components/loader/loader.template.html @@ -35,6 +35,20 @@ > + + + + Use css-variable + --tui-thickness + to customize width of the circle stroke. By default, it is 1/12 of diameter. + + +