@3dsource/source-ui-native 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +64 -0
  2. package/eslint.config.js +37 -0
  3. package/ng-package.json +7 -0
  4. package/package.json +9 -0
  5. package/src/lib/components/source-badge/components/source-badge.component.html +20 -0
  6. package/src/lib/components/source-badge/components/source-badge.component.scss +76 -0
  7. package/src/lib/components/source-badge/components/source-badge.component.ts +62 -0
  8. package/src/lib/components/source-badge/constants/index.ts +2 -0
  9. package/src/lib/components/source-badge/constants/sourceBadgeSize.ts +8 -0
  10. package/src/lib/components/source-badge/constants/sourceBadgeType.ts +11 -0
  11. package/src/lib/components/source-badge/index.ts +2 -0
  12. package/src/lib/components/source-banner/components/source-banner.component.html +10 -0
  13. package/src/lib/components/source-banner/components/source-banner.component.scss +75 -0
  14. package/src/lib/components/source-banner/components/source-banner.component.ts +25 -0
  15. package/src/lib/components/source-banner/constants/sourceBannerType.ts +10 -0
  16. package/src/lib/components/source-banner/index.ts +2 -0
  17. package/src/lib/components/source-button/components/source-button.component.html +44 -0
  18. package/src/lib/components/source-button/components/source-button.component.scss +355 -0
  19. package/src/lib/components/source-button/components/source-button.component.ts +220 -0
  20. package/src/lib/components/source-button/constants/index.ts +4 -0
  21. package/src/lib/components/source-button/constants/sourceButtonAppearance.ts +7 -0
  22. package/src/lib/components/source-button/constants/sourceButtonColorScheme.ts +8 -0
  23. package/src/lib/components/source-button/constants/sourceButtonSize.ts +8 -0
  24. package/src/lib/components/source-button/constants/sourceButtonType.ts +8 -0
  25. package/src/lib/components/source-button/index.ts +3 -0
  26. package/src/lib/components/source-button/interfaces/defaultSourceButton.config.ts +24 -0
  27. package/src/lib/components/source-button/interfaces/index.ts +2 -0
  28. package/src/lib/components/source-button/interfaces/sourceButton.interface.ts +26 -0
  29. package/src/lib/components/source-copyright/components/source-copyright.component.html +20 -0
  30. package/src/lib/components/source-copyright/components/source-copyright.component.scss +81 -0
  31. package/src/lib/components/source-copyright/components/source-copyright.component.ts +18 -0
  32. package/src/lib/components/source-copyright/index.ts +1 -0
  33. package/src/lib/components/source-divider/components/source-divider.component.html +5 -0
  34. package/src/lib/components/source-divider/components/source-divider.component.scss +15 -0
  35. package/src/lib/components/source-divider/components/source-divider.component.ts +18 -0
  36. package/src/lib/components/source-divider/index.ts +1 -0
  37. package/src/lib/components/source-hint/components/source-hint.component.html +8 -0
  38. package/src/lib/components/source-hint/components/source-hint.component.scss +31 -0
  39. package/src/lib/components/source-hint/components/source-hint.component.ts +18 -0
  40. package/src/lib/components/source-hint/index.ts +1 -0
  41. package/src/lib/components/source-icon-button/components/source-icon-button.component.html +18 -0
  42. package/src/lib/components/source-icon-button/components/source-icon-button.component.scss +89 -0
  43. package/src/lib/components/source-icon-button/components/source-icon-button.component.ts +87 -0
  44. package/src/lib/components/source-icon-button/constants/index.ts +3 -0
  45. package/src/lib/components/source-icon-button/constants/sourceIconButtonShape.ts +7 -0
  46. package/src/lib/components/source-icon-button/constants/sourceIconButtonSize.ts +10 -0
  47. package/src/lib/components/source-icon-button/constants/sourceIconButtonType.ts +8 -0
  48. package/src/lib/components/source-icon-button/index.ts +2 -0
  49. package/src/lib/components/source-loading/components/source-loading.component.html +40 -0
  50. package/src/lib/components/source-loading/components/source-loading.component.scss +62 -0
  51. package/src/lib/components/source-loading/components/source-loading.component.ts +79 -0
  52. package/src/lib/components/source-loading/constants/sourceLoadingLineCap.ts +7 -0
  53. package/src/lib/components/source-loading/index.ts +1 -0
  54. package/src/lib/components/source-logo-loading/components/source-logo-loading.component.html +23 -0
  55. package/src/lib/components/source-logo-loading/components/source-logo-loading.component.scss +33 -0
  56. package/src/lib/components/source-logo-loading/components/source-logo-loading.component.ts +21 -0
  57. package/src/lib/components/source-logo-loading/index.ts +1 -0
  58. package/src/lib/components/source-slider/components/source-slider.component.html +38 -0
  59. package/src/lib/components/source-slider/components/source-slider.component.scss +132 -0
  60. package/src/lib/components/source-slider/components/source-slider.component.ts +122 -0
  61. package/src/lib/components/source-slider/index.ts +1 -0
  62. package/src/lib/styles/base.scss +68 -0
  63. package/src/lib/styles/elements/_src-button.scss +235 -0
  64. package/src/lib/styles/elements/_src-input.scss +83 -0
  65. package/src/lib/styles/elements/_src-list.scss +82 -0
  66. package/src/lib/styles/elements/_src-select.scss +71 -0
  67. package/src/lib/styles/elements/elements.scss +4 -0
  68. package/src/lib/styles/fonts/Inter-VariableFont_slnt,wght.woff2 +0 -0
  69. package/src/lib/styles/fonts.scss +18 -0
  70. package/src/lib/styles/source.ui.scss +23 -0
  71. package/src/lib/styles/typography.scss +90 -0
  72. package/src/lib/styles/utils.scss +40 -0
  73. package/src/lib/styles/variables/_borders.scss +14 -0
  74. package/src/lib/styles/variables/_colors-aliases.scss +39 -0
  75. package/src/lib/styles/variables/_colors.scss +64 -0
  76. package/src/lib/styles/variables/_shadows.scss +9 -0
  77. package/src/lib/styles/variables/_typography.scss +32 -0
  78. package/src/lib/styles/variables/index.scss +5 -0
  79. package/src/public-api.ts +10 -0
  80. package/tsconfig.lib.json +13 -0
  81. package/tsconfig.lib.prod.json +11 -0
@@ -0,0 +1,81 @@
1
+ // source-copyright.component.scss
2
+ .src-copyright {
3
+ --srcCopyrightFontSize: 12px;
4
+ --srcCopyrightFontColor: var(--color-text-default, #1f2937);
5
+
6
+ &--collapsible {
7
+ --srcCopyrightSize: 32px;
8
+ --srcCopyrightBoxShadow:
9
+ 0px 8px 20px 0px rgba(23, 24, 24, 0.12),
10
+ 0px 3px 6px 0px rgba(23, 24, 24, 0.08);
11
+ --srcCopyrightExpandedWidth: 176px;
12
+ }
13
+ }
14
+
15
+ .src-link {
16
+ display: flex;
17
+ align-items: center;
18
+ font-size: var(--srcCopyrightFontSize);
19
+ font-style: normal;
20
+ font-weight: 400;
21
+ line-height: 1;
22
+ color: var(--srcCopyrightFontColor);
23
+ text-decoration: none;
24
+ transition: all 0.3s ease-in-out;
25
+
26
+ &:hover {
27
+ text-decoration: underline;
28
+ }
29
+
30
+ .src-link__icon {
31
+ width: 16px;
32
+ height: 18px;
33
+ }
34
+
35
+ .src-link__text {
36
+ color: inherit;
37
+ padding-left: 8px;
38
+ padding-top: 1px;
39
+ }
40
+ }
41
+
42
+ .src-copyright--collapsible {
43
+ width: var(--srcCopyrightSize);
44
+ height: var(--srcCopyrightSize);
45
+
46
+ .src-link {
47
+ height: 100%;
48
+ width: var(--srcCopyrightSize);
49
+ border-radius: 8px;
50
+ text-decoration: none;
51
+ background: #fff;
52
+ box-shadow: var(--srcCopyrightBoxShadow);
53
+
54
+ &:hover {
55
+ width: var(--srcCopyrightExpandedWidth);
56
+
57
+ .src-link__text {
58
+ width: 100%;
59
+ }
60
+ }
61
+ }
62
+
63
+ .src-link__icon {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: center;
67
+ flex-shrink: 0;
68
+ width: var(--srcCopyrightSize);
69
+ height: var(--srcCopyrightSize);
70
+ padding: 7px;
71
+ }
72
+
73
+ .src-link__text {
74
+ flex-shrink: 0;
75
+ overflow: hidden;
76
+ white-space: nowrap;
77
+ padding: 0;
78
+ width: 0;
79
+ transition: width 0.3s ease-in-out;
80
+ }
81
+ }
@@ -0,0 +1,18 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ input,
5
+ ViewEncapsulation,
6
+ } from '@angular/core';
7
+
8
+ @Component({
9
+ selector: 'src-copyright',
10
+ templateUrl: './source-copyright.component.html',
11
+ styleUrls: ['./source-copyright.component.scss'],
12
+ encapsulation: ViewEncapsulation.None,
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ })
15
+ export class SourceCopyrightComponent {
16
+ linkText = input('Powered by 3D Source');
17
+ isCollapsible = input(false);
18
+ }
@@ -0,0 +1 @@
1
+ export * from './components/source-copyright.component';
@@ -0,0 +1,5 @@
1
+ <hr
2
+ class="src-divider"
3
+ [style.--srcDividerColor]="thickness()"
4
+ [style.--srcDividerColor]="color()"
5
+ />
@@ -0,0 +1,15 @@
1
+ // source-divider.component.scss
2
+ .src-divider {
3
+ --srcDividerColor: var(--src-color-border-default, #e5e7eb);
4
+ --srcDividerHeight: 1px;
5
+ --srcDividerOffsetTop: 8px;
6
+ --srcDividerOffsetBottom: var(--srcDividerOffsetTop);
7
+ display: block;
8
+ width: 100%;
9
+ height: var(--srcDividerHeight);
10
+ margin-top: var(--srcDividerOffsetTop);
11
+ margin-bottom: var(--srcDividerOffsetBottom);
12
+ padding: 0;
13
+ background-color: var(--srcDividerColor);
14
+ border: none;
15
+ }
@@ -0,0 +1,18 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ input,
5
+ ViewEncapsulation,
6
+ } from '@angular/core';
7
+
8
+ @Component({
9
+ selector: 'src-divider',
10
+ templateUrl: './source-divider.component.html',
11
+ styleUrls: ['./source-divider.component.scss'],
12
+ encapsulation: ViewEncapsulation.None,
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ })
15
+ export class SourceDividerComponent {
16
+ color = input('#E5E7EB');
17
+ thickness = input('1px');
18
+ }
@@ -0,0 +1 @@
1
+ export * from './components/source-divider.component';
@@ -0,0 +1,8 @@
1
+ <p
2
+ class="src-hint"
3
+ [class.src-hint--error]="isError()"
4
+ [class.src-hint--compact]="isCompact()"
5
+ >
6
+ <ng-content select="[srcIconPrefix]"></ng-content>
7
+ <ng-content></ng-content>
8
+ </p>
@@ -0,0 +1,31 @@
1
+ // source-hint.component.scss
2
+ .src-hint {
3
+ --srcHintColor: var(--src-color-icon-default, #6b7280);
4
+ --srcHintFontSize: var(--src-fs-base, 14px);
5
+ --srcHintLineHeight: var(--src-lh-base, 1.43);
6
+ --srcHintMargin: 4px 0 0;
7
+ --srcHintIconSize: 20px;
8
+ color: var(--srcHintColor);
9
+ font-size: var(--srcHintFontSize);
10
+ font-style: normal;
11
+ display: flex;
12
+ margin: var(--srcHintMargin);
13
+ font-weight: var(--src-fw-regular, 400);
14
+ line-height: var(--srcHintLineHeight);
15
+
16
+ & > [srcIconPrefix] {
17
+ width: var(--srcHintIconSize);
18
+ height: var(--srcHintIconSize);
19
+ margin-right: 4px;
20
+ color: currentColor;
21
+ }
22
+
23
+ &--error {
24
+ --srcHintColor: var(--src-color-text-critical, #9f200a);
25
+ }
26
+
27
+ &--compact {
28
+ --srcHintFontSize: var(--src-fs-small, 12px);
29
+ --srcHintMargin: 2px 0 0;
30
+ }
31
+ }
@@ -0,0 +1,18 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ input,
5
+ ViewEncapsulation,
6
+ } from '@angular/core';
7
+
8
+ @Component({
9
+ selector: 'src-hint',
10
+ templateUrl: './source-hint.component.html',
11
+ styleUrls: ['./source-hint.component.scss'],
12
+ encapsulation: ViewEncapsulation.None,
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ })
15
+ export class SourceHintComponent {
16
+ isError = input(false);
17
+ isCompact = input(false);
18
+ }
@@ -0,0 +1 @@
1
+ export * from './components/source-hint.component';
@@ -0,0 +1,18 @@
1
+ <button
2
+ [type]="type"
3
+ [name]="name()"
4
+ class="src-icon-button"
5
+ [ngClass]="classes"
6
+ [disabled]="isDisabled()"
7
+ [attr.data-testid]="testID()"
8
+ (click)="handleClick($event)"
9
+ >
10
+ <ng-content></ng-content>
11
+
12
+ @if (counter()) {
13
+ <src-badge
14
+ [number]="counter()!"
15
+ [data-testid]="testID() + '-counter'"
16
+ ></src-badge>
17
+ }
18
+ </button>
@@ -0,0 +1,89 @@
1
+ // source-icon-button.component.scss
2
+ button.src-icon-button {
3
+ --srcButtonBgColor: transparent;
4
+ --srcButtonBgHoverColor: var(--src-color-bg-default-hover);
5
+ --srcButtonIconColor: var(--src-color-icon-default);
6
+ --srcButtonBorderRadius: var(--src-br-small);
7
+ --srcButtonPaddings: 6px;
8
+ --srcButtonIconSize: 20px;
9
+ position: relative;
10
+ display: flex;
11
+ justify-content: center;
12
+ align-items: center;
13
+ width: auto;
14
+ padding: var(--srcButtonPaddings);
15
+ color: var(--srcButtonIconColor);
16
+ background-color: var(--srcButtonBgColor);
17
+ border: none;
18
+ box-shadow: none;
19
+ border-radius: var(--srcButtonBorderRadius);
20
+ cursor: pointer;
21
+
22
+ & > src-badge {
23
+ position: absolute;
24
+ top: -7px;
25
+ right: -10px;
26
+ }
27
+
28
+ @media (hover: hover) and (pointer: fine) {
29
+ &:hover,
30
+ &:focus-visible {
31
+ --srcButtonBgColor: var(--srcButtonBgHoverColor);
32
+ --srcButtonIconColor: var(--src-color-icon-default-hover);
33
+ }
34
+ }
35
+
36
+ &:disabled,
37
+ &[disabled],
38
+ &.disabled {
39
+ cursor: default;
40
+ pointer-events: none;
41
+ --srcButtonBgColor: var(--src-color-bg-default);
42
+ --srcButtonIconColor: var(--src-color-icon-default-disabled);
43
+ }
44
+
45
+ &--round {
46
+ --srcButtonBgColor: var(--src-color-bg-strong-subdued);
47
+ --srcButtonBgHoverColor: var(--src-color-bg-strong-subdued-hover);
48
+ --srcButtonBorderRadius: 50%;
49
+ }
50
+
51
+ &--active {
52
+ --srcButtonBgColor: var(--src-color-bg-default-active);
53
+ --srcButtonIconColor: var(--src-color-icon-primary);
54
+
55
+ @media (hover: hover) and (pointer: fine) {
56
+ &:hover,
57
+ &:focus-visible {
58
+ --srcButtonBgColor: var(--src-color-bg-default-active);
59
+ --srcButtonIconColor: var(--src-color-icon-primary);
60
+ }
61
+ }
62
+ }
63
+
64
+ // size
65
+ &--xs {
66
+ --srcButtonPaddings: 1px;
67
+
68
+ & > :not(src-badge) {
69
+ width: 18px;
70
+ height: 18px;
71
+ }
72
+ }
73
+
74
+ &--sm {
75
+ --srcButtonPaddings: 2px;
76
+ }
77
+
78
+ &--default {
79
+ --srcButtonPaddings: 6px;
80
+ }
81
+
82
+ &--md {
83
+ --srcButtonPaddings: 8px;
84
+ }
85
+
86
+ &--lg {
87
+ --srcButtonPaddings: 12px;
88
+ }
89
+ }
@@ -0,0 +1,87 @@
1
+ import { NgClass } from '@angular/common';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ EventEmitter,
6
+ input,
7
+ Output,
8
+ ViewEncapsulation,
9
+ } from '@angular/core';
10
+ import {
11
+ SourceIconButtonShape,
12
+ SourceIconButtonShapeValues,
13
+ SourceIconButtonSize,
14
+ SourceIconButtonSizeValues,
15
+ SourceIconButtonType,
16
+ SourceIconButtonTypeValues,
17
+ } from '../constants';
18
+ import { SourceBadgeComponent } from '../../source-badge';
19
+
20
+ @Component({
21
+ selector: 'src-icon-button',
22
+ templateUrl: './source-icon-button.component.html',
23
+ styleUrls: ['./source-icon-button.component.scss'],
24
+ imports: [NgClass, SourceBadgeComponent],
25
+ encapsulation: ViewEncapsulation.None,
26
+ changeDetection: ChangeDetectionStrategy.OnPush,
27
+ })
28
+ export class SourceIconButtonComponent {
29
+ type = input<SourceIconButtonTypeValues>(SourceIconButtonType.BUTTON);
30
+ name = input<string | undefined>(undefined);
31
+ /**
32
+ * How big should it be?
33
+ */
34
+ size = input<SourceIconButtonSizeValues>(SourceIconButtonSize.DEFAULT);
35
+
36
+ /**
37
+ * Shape of a button
38
+ */
39
+ shape = input<SourceIconButtonShapeValues>(SourceIconButtonShape.SQUARE);
40
+ /**
41
+ * Use counter-attribute to display the counter in the top right corner of the button.
42
+ */
43
+ counter = input<number | undefined>(undefined);
44
+
45
+ /**
46
+ * Standard active state for the button
47
+ */
48
+ isActive = input(false);
49
+
50
+ /**
51
+ * Standard disabled state for button
52
+ */
53
+ isDisabled = input(false);
54
+ /**
55
+ * Test ID for the component. Provide descriptive uniq id in kebab-case.
56
+ */
57
+ testID = input('', { alias: 'data-testid' });
58
+ /**
59
+ * Optional click handler
60
+ */
61
+ @Output()
62
+ onClick = new EventEmitter<Event>();
63
+
64
+ compiledClassesList: string[] = [];
65
+
66
+ get classes() {
67
+ this.compiledClassesList = [];
68
+
69
+ this.compiledClassesList.push(`src-icon-button--${this.shape()}`);
70
+ this.compiledClassesList.push(`src-icon-button--${this.size()}`);
71
+ this.compiledClassesList.push(
72
+ this.isActive() ? 'src-icon-button--active' : '',
73
+ );
74
+
75
+ return this.compiledClassesList;
76
+ }
77
+
78
+ handleClick(event: Event) {
79
+ event.preventDefault();
80
+
81
+ if (event.currentTarget instanceof HTMLButtonElement) {
82
+ event.currentTarget.blur();
83
+ }
84
+
85
+ this.onClick.emit(event);
86
+ }
87
+ }
@@ -0,0 +1,3 @@
1
+ export * from './sourceIconButtonSize';
2
+ export * from './sourceIconButtonType';
3
+ export * from './sourceIconButtonShape';
@@ -0,0 +1,7 @@
1
+ export const SourceIconButtonShape = {
2
+ SQUARE: 'square',
3
+ ROUND: 'round',
4
+ } as const;
5
+
6
+ export type SourceIconButtonShapeValues =
7
+ (typeof SourceIconButtonShape)[keyof typeof SourceIconButtonShape];
@@ -0,0 +1,10 @@
1
+ export const SourceIconButtonSize = {
2
+ XSMALL: 'xs',
3
+ SMALL: 'sm',
4
+ MEDIUM: 'md',
5
+ LARGE: 'lg',
6
+ DEFAULT: 'default',
7
+ } as const;
8
+
9
+ export type SourceIconButtonSizeValues =
10
+ (typeof SourceIconButtonSize)[keyof typeof SourceIconButtonSize];
@@ -0,0 +1,8 @@
1
+ export const SourceIconButtonType = {
2
+ BUTTON: 'button',
3
+ SUBMIT: 'submit',
4
+ RESET: 'reset',
5
+ } as const;
6
+
7
+ export type SourceIconButtonTypeValues =
8
+ (typeof SourceIconButtonType)[keyof typeof SourceIconButtonType];
@@ -0,0 +1,2 @@
1
+ export * from './components/source-icon-button.component';
2
+ export * from './constants';
@@ -0,0 +1,40 @@
1
+ <div class="src-loading-container" [attr.data-testid]="testID()">
2
+ <svg
3
+ [ngClass]="classes"
4
+ class="src-loading"
5
+ [attr.width]="size"
6
+ [attr.height]="size"
7
+ [attr.viewBox]="getViewBox()"
8
+ version="1.1"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ style="transform: rotate(-90deg)"
11
+ [style.--srcLoadingSize]="size"
12
+ >
13
+ <!-- Background circle -->
14
+ @if (progress) {
15
+ <circle
16
+ [attr.r]="calculateRadius()"
17
+ [attr.cx]="size / 2"
18
+ [attr.cy]="size / 2"
19
+ fill="transparent"
20
+ [attr.stroke]="backgroundStrokeColor"
21
+ [attr.stroke-width]="strokeWidth"
22
+ [attr.stroke-dasharray]="getCircumference()"
23
+ stroke-dashoffset="0"
24
+ ></circle>
25
+ }
26
+
27
+ <!-- Filled circle -->
28
+ <circle
29
+ [attr.r]="calculateRadius()"
30
+ [attr.cx]="size / 2"
31
+ [attr.cy]="size / 2"
32
+ [attr.stroke]="progressStrokeColor"
33
+ [attr.stroke-width]="strokeWidth"
34
+ [attr.stroke-linecap]="lineCap"
35
+ [attr.stroke-dashoffset]="progress ? getPercentage() : 0"
36
+ fill="transparent"
37
+ [attr.stroke-dasharray]="progress ? getCircumference() : ''"
38
+ ></circle>
39
+ </svg>
40
+ </div>
@@ -0,0 +1,62 @@
1
+ // source-loading.component.scss
2
+ :host {
3
+ display: block;
4
+ }
5
+ .src-loading-container {
6
+ position: relative;
7
+ display: flex;
8
+ justify-content: center;
9
+ align-items: center;
10
+ width: 100%;
11
+ height: 100%;
12
+ }
13
+
14
+ .src-loading {
15
+ position: relative;
16
+ display: inline-block;
17
+ }
18
+
19
+ // Default loader animation
20
+ .src-loading--animation {
21
+ animation: 1.4s linear 0s infinite normal none running rotate;
22
+
23
+ circle {
24
+ transform-origin: 50% 50%;
25
+ stroke-dasharray:
26
+ calc(var(--srcLoadingSize) * 2 * 1px),
27
+ calc(var(--srcLoadingSize) * 5 * 1px);
28
+ stroke-dashoffset: 0;
29
+ animation: 1.6s ease-in-out 0s infinite normal none running spinner;
30
+ }
31
+ }
32
+
33
+ @keyframes rotate {
34
+ 0% {
35
+ transform: rotate(0deg);
36
+ }
37
+
38
+ 100% {
39
+ transform: rotate(360deg);
40
+ }
41
+ }
42
+
43
+ @keyframes spinner {
44
+ 0% {
45
+ stroke-dasharray: 1px, calc(var(--srcLoadingSize) * 5 * 1px);
46
+ stroke-dashoffset: 0;
47
+ }
48
+
49
+ 50% {
50
+ stroke-dasharray:
51
+ calc(var(--srcLoadingSize) * 2.5 * 1px),
52
+ calc(var(--srcLoadingSize) * 5 * 1px);
53
+ stroke-dashoffset: calc(var(--srcLoadingSize) * 0.4 * -1px);
54
+ }
55
+
56
+ 100% {
57
+ stroke-dasharray:
58
+ calc(var(--srcLoadingSize) * 2.5 * 1px),
59
+ calc(var(--srcLoadingSize) * 5 * 1px);
60
+ stroke-dashoffset: calc(var(--srcLoadingSize) * 3 * -1px);
61
+ }
62
+ }
@@ -0,0 +1,79 @@
1
+ import { NgClass } from '@angular/common';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ Input,
6
+ input,
7
+ ViewEncapsulation,
8
+ } from '@angular/core';
9
+ import {
10
+ SourceLoadingLineCap,
11
+ SourceLoadingLineCapValues,
12
+ } from '../constants/sourceLoadingLineCap';
13
+
14
+ @Component({
15
+ selector: 'src-loading',
16
+ templateUrl: './source-loading.component.html',
17
+ styleUrls: ['./source-loading.component.scss'],
18
+ imports: [NgClass],
19
+ encapsulation: ViewEncapsulation.None,
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ })
22
+ export class SourceLoadingComponent {
23
+ /**
24
+ * Size of the loading circle
25
+ */
26
+ @Input() size = 32;
27
+ /**
28
+ * If it just an animated circle or circular progressbar
29
+ */
30
+ @Input() progress?: number | null = null;
31
+
32
+ /**
33
+ * The stroke-linecap attribute is a presentation attribute defining the shape to be used at the end of open subpaths when they are stroked.
34
+ */
35
+ @Input() lineCap: SourceLoadingLineCapValues = SourceLoadingLineCap.ROUND;
36
+ /**
37
+ * Color of the strokes
38
+ */
39
+ @Input() backgroundStrokeColor = 'transparent';
40
+ @Input() progressStrokeColor = 'var(--src-color-brand-500, #017BFF)';
41
+ /**
42
+ * Width of the line
43
+ */
44
+ @Input() strokeWidth = 3;
45
+ /**
46
+ * Test ID for the component. Provide descriptive uniq id in kebab-case.
47
+ */
48
+ testID = input('', { alias: 'data-testid' });
49
+
50
+ compiledClassesList: string[] = [];
51
+
52
+ get classes(): string[] {
53
+ this.compiledClassesList = [];
54
+
55
+ if (this.progress !== null) {
56
+ this.compiledClassesList.push(`src-loading--progress`);
57
+ } else {
58
+ this.compiledClassesList.push(`src-loading--animation`);
59
+ }
60
+
61
+ return this.compiledClassesList;
62
+ }
63
+
64
+ calculateRadius() {
65
+ return this.size / 2 - this.strokeWidth / 2;
66
+ }
67
+
68
+ getCircumference() {
69
+ return 2 * Math.PI * this.calculateRadius();
70
+ }
71
+
72
+ getViewBox() {
73
+ return `0 0 ${this.size} ${this.size}`;
74
+ }
75
+
76
+ getPercentage() {
77
+ return Math.round(this.getCircumference() * ((100 - this.progress!) / 100));
78
+ }
79
+ }
@@ -0,0 +1,7 @@
1
+ export const SourceLoadingLineCap = {
2
+ ROUND: 'round',
3
+ SQUARE: 'square',
4
+ BUTT: 'butt',
5
+ } as const;
6
+ export type SourceLoadingLineCapValues =
7
+ (typeof SourceLoadingLineCap)[keyof typeof SourceLoadingLineCap];
@@ -0,0 +1 @@
1
+ export * from './components/source-loading.component';
@@ -0,0 +1,23 @@
1
+ <div
2
+ class="src-logo-loading"
3
+ [attr.data-testid]="testID()"
4
+ [ngStyle]="{
5
+ '--srcLogoLoadingSize': size() + 'px',
6
+ '--srcLogoLoadingStroke': strokeColor(),
7
+ }"
8
+ >
9
+ <svg
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ width="40"
12
+ height="40"
13
+ fill="none"
14
+ viewBox="0 0 40 40"
15
+ >
16
+ <path
17
+ d="M36.482 12.662v4.466c-1.092-.61-4.316-2.42-7.512-4.213l-5.236-2.938-1.717-.964-.48-.27-.126-.07-.033-.019-.008-.004-.002-.001-.245.435.244-.436a2.552 2.552 0 0 0-.71-.29 2.162 2.162 0 0 0-.758-.015l-.024.003-.024.005c-.49.113-.837.345-1.057.638a1.354 1.354 0 0 0-.275.838c.015.527.4 1.002.988 1.313.643.388 4.642 2.71 8.484 4.937l5.25 3.042 1.703.986.475.275.125.072.032.018.008.005.002.001.25-.432-.25.433.01.005c.477.262.868.868.868 1.673v5.681c-.039 1.216-.675 2.086-1.478 2.553l-.002.001-4.222 2.482v-6.197c.043-.907-.147-1.642-.525-2.236-.375-.589-.909-.998-1.489-1.3l-15.143-8.783c-.324-.195-.572-.42-.74-.689-.167-.266-.272-.6-.272-1.045V5.395a.511.511 0 0 1 .014-.206.122.122 0 0 1 .025-.04.332.332 0 0 1 .087-.064l.006-.004 4.791-2.78.008-.004c.874-.528 1.675-.758 2.433-.762.758-.005 1.512.217 2.293.652l12.45 7.22.003.002c.623.356 1.077.785 1.37 1.301.293.515.445 1.15.41 1.952Z"
18
+ />
19
+ <path
20
+ d="M3.518 27.338v-4.466c1.092.61 4.316 2.42 7.512 4.213l5.236 2.938 1.717.964.48.27.126.07.033.018.008.005.002.001.245-.435-.244.436c.24.134.464.238.71.29.253.055.494.05.758.015l.024-.003.024-.005c.49-.113.837-.345 1.057-.638.213-.286.281-.598.275-.838-.015-.527-.4-1.002-.988-1.313-.643-.388-4.642-2.71-8.484-4.937l-5.25-3.042-1.703-.986-.475-.275-.125-.072-.032-.018-.008-.005-.002-.001-.25.432.25-.433-.01-.005c-.477-.262-.868-.868-.868-1.673v-5.681c.04-1.216.675-2.086 1.478-2.553l.002-.001 4.222-2.482v6.197c-.043.907.147 1.642.525 2.236.375.589.909.998 1.489 1.3l15.143 8.783c.324.195.572.42.74.689.166.266.272.6.272 1.045v7.227a.511.511 0 0 1-.015.206.122.122 0 0 1-.024.04.334.334 0 0 1-.086.064l-.007.004-4.791 2.78-.008.004c-.874.528-1.675.758-2.433.762-.758.005-1.512-.217-2.293-.652L5.3 30.593l-.003-.002c-.623-.356-1.077-.785-1.37-1.301-.293-.515-.445-1.15-.41-1.952Z"
21
+ />
22
+ </svg>
23
+ </div>