oasys-lib 1.1.4 → 1.2.0

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 (93) hide show
  1. package/.browserslistrc +17 -0
  2. package/karma.conf.js +44 -0
  3. package/ng-package.json +10 -0
  4. package/package.json +3 -10
  5. package/src/assets/bloomandwild/variables.css +21 -13
  6. package/src/assets/bloomon/variables.css +21 -13
  7. package/src/assets/global/scss-breakpoints.scss +1 -1
  8. package/src/assets/global/typography.scss +4 -6
  9. package/src/assets/global/variables.css +5 -2
  10. package/src/lib/components/button/button.component.html +16 -0
  11. package/src/lib/components/button/button.component.scss +188 -0
  12. package/src/lib/components/button/button.component.spec.ts +25 -0
  13. package/src/lib/components/button/button.component.ts +95 -0
  14. package/src/lib/components/button/button.modifiers.scss +101 -0
  15. package/src/lib/components/button/button.ts +48 -0
  16. package/src/lib/components/icon/icon.component.html +5 -0
  17. package/src/lib/components/icon/icon.component.scss +5 -0
  18. package/src/lib/components/icon/icon.component.spec.ts +25 -0
  19. package/src/lib/components/icon/icon.component.ts +50 -0
  20. package/src/lib/components/icon/icon.ts +25 -0
  21. package/src/lib/components/layout/Layout.ts +64 -0
  22. package/src/lib/components/layout/_layout.scss +105 -0
  23. package/src/lib/components/layout/box/box.component.scss +124 -0
  24. package/src/lib/components/layout/box/box.component.ts +103 -0
  25. package/src/lib/components/layout/container/container.component.scss +66 -0
  26. package/src/lib/components/layout/container/container.component.ts +70 -0
  27. package/src/lib/components/layout/grid/grid.component.scss +162 -0
  28. package/src/lib/components/layout/grid/grid.component.ts +103 -0
  29. package/src/lib/components/layout/stack/stack.component.scss +60 -0
  30. package/src/lib/components/layout/stack/stack.component.ts +58 -0
  31. package/src/lib/components/text/text.component.html +1 -0
  32. package/src/lib/components/text/text.component.scss +33 -0
  33. package/src/lib/components/text/text.component.spec.ts +25 -0
  34. package/src/lib/components/text/text.component.ts +29 -0
  35. package/src/lib/components/text/text.ts +1 -0
  36. package/src/lib/oasys-lib.module.ts +42 -0
  37. package/src/lib/oasys-lib.service.spec.ts +16 -0
  38. package/src/lib/oasys-lib.service.ts +9 -0
  39. package/src/lib/services/token.service.ts +37 -0
  40. package/src/lib/services/window.service.ts +16 -0
  41. package/{public-api.d.ts → src/public-api.ts} +7 -1
  42. package/src/test.ts +27 -0
  43. package/tsconfig.lib.json +17 -0
  44. package/tsconfig.lib.prod.json +7 -0
  45. package/tsconfig.spec.json +17 -0
  46. package/bundles/oasys-lib.umd.js +0 -629
  47. package/bundles/oasys-lib.umd.js.map +0 -1
  48. package/esm2015/lib/components/button/button.component.js +0 -97
  49. package/esm2015/lib/components/button/button.js +0 -2
  50. package/esm2015/lib/components/icon/icon.component.js +0 -58
  51. package/esm2015/lib/components/icon/icon.js +0 -2
  52. package/esm2015/lib/components/layout/Layout.js +0 -2
  53. package/esm2015/lib/components/layout/box/box.component.js +0 -99
  54. package/esm2015/lib/components/layout/container/container.component.js +0 -81
  55. package/esm2015/lib/components/layout/grid/grid.component.js +0 -104
  56. package/esm2015/lib/components/layout/stack/stack.component.js +0 -65
  57. package/esm2015/lib/components/text/text.js +0 -2
  58. package/esm2015/lib/oasys-lib.module.js +0 -66
  59. package/esm2015/lib/services/token.service.js +0 -41
  60. package/esm2015/lib/services/window.service.js +0 -19
  61. package/esm2015/oasys-lib.js +0 -5
  62. package/esm2015/public-api.js +0 -11
  63. package/fesm2015/oasys-lib.js +0 -601
  64. package/fesm2015/oasys-lib.js.map +0 -1
  65. package/lib/components/button/button.component.d.ts +0 -32
  66. package/lib/components/button/button.component.d.ts.map +0 -1
  67. package/lib/components/button/button.d.ts +0 -18
  68. package/lib/components/button/button.d.ts.map +0 -1
  69. package/lib/components/icon/icon.component.d.ts +0 -26
  70. package/lib/components/icon/icon.component.d.ts.map +0 -1
  71. package/lib/components/icon/icon.d.ts +0 -3
  72. package/lib/components/icon/icon.d.ts.map +0 -1
  73. package/lib/components/layout/Layout.d.ts +0 -27
  74. package/lib/components/layout/Layout.d.ts.map +0 -1
  75. package/lib/components/layout/box/box.component.d.ts +0 -28
  76. package/lib/components/layout/box/box.component.d.ts.map +0 -1
  77. package/lib/components/layout/container/container.component.d.ts +0 -21
  78. package/lib/components/layout/container/container.component.d.ts.map +0 -1
  79. package/lib/components/layout/grid/grid.component.d.ts +0 -31
  80. package/lib/components/layout/grid/grid.component.d.ts.map +0 -1
  81. package/lib/components/layout/stack/stack.component.d.ts +0 -21
  82. package/lib/components/layout/stack/stack.component.d.ts.map +0 -1
  83. package/lib/components/text/text.d.ts +0 -2
  84. package/lib/components/text/text.d.ts.map +0 -1
  85. package/lib/oasys-lib.module.d.ts +0 -15
  86. package/lib/oasys-lib.module.d.ts.map +0 -1
  87. package/lib/services/token.service.d.ts +0 -12
  88. package/lib/services/token.service.d.ts.map +0 -1
  89. package/lib/services/window.service.d.ts +0 -7
  90. package/lib/services/window.service.d.ts.map +0 -1
  91. package/oasys-lib.d.ts +0 -6
  92. package/oasys-lib.d.ts.map +0 -1
  93. package/public-api.d.ts.map +0 -1
@@ -0,0 +1,101 @@
1
+ /* ---------------------
2
+ All button type variants
3
+ --------------------- */
4
+ $buttonTypes:
5
+ primary,
6
+ secondary,
7
+ tertiary,
8
+ primary-inverse,
9
+ secondary-inverse,
10
+ tertiary-inverse,
11
+ expressive,
12
+ danger,
13
+ facebook,
14
+ paypal,
15
+ trustpilot;
16
+
17
+
18
+
19
+ /* ---------------------
20
+ All button sizes
21
+ --------------------- */
22
+ $buttonSizes: large, small;
23
+ $outlineButtonSizes: large, small;
24
+
25
+
26
+
27
+ /* ---------------------
28
+ Generate Button Colours
29
+ --------------------- */
30
+ @mixin buttonColors($buttonType) {
31
+ background-color: var(--component-button-color-#{$buttonType}-background);
32
+ border-color: var(--component-button-color-#{$buttonType}-border);
33
+ color: var(--component-button-color-#{$buttonType}-text);
34
+
35
+ .button-overlay {
36
+ background-color: var(--component-button-color-#{$buttonType}-text);
37
+ }
38
+ }
39
+
40
+
41
+
42
+ /* ---------------------
43
+ Generate Button Sizes
44
+ --------------------- */
45
+ @mixin buttonSize($buttonSize, $isOutline: false) {
46
+
47
+ // Variables to override below
48
+ $buttonPadding: 0 !default;
49
+ $buttonBorderWidth: 0 !default;
50
+
51
+ $iconOffsetLeading: 0 !default;
52
+ $iconOffsetTrailing: 0 !default;
53
+ $iconOffsetIconOnly: 0 !default;
54
+
55
+ // Variables dont change if theres an outline
56
+ $buttonFontSize: var(--component-button-size-#{$buttonSize}-font-size);
57
+ $buttonInlineSpacing: var(--component-button-size-#{$buttonSize}-stack-spacing);
58
+
59
+
60
+ @if $isOutline== 'true' {
61
+ $buttonPadding: var(--component-button-size-#{$buttonSize}-with-outline-padding-y) var(--component-button-size-#{$buttonSize}-with-outline-padding-x);
62
+ $buttonBorderWidth: var(--component-button-size-#{$buttonSize}-with-outline-border-width);
63
+
64
+ $iconOffsetLeading: calc(var(--component-button-size-#{$buttonSize}-with-outline-icon-offset-leading) * -1);
65
+ $iconOffsetTrailing: calc(var(--component-button-size-#{$buttonSize}-with-outline-icon-offset-trailing) * -1);
66
+ $iconOffsetIconOnly: calc(var(--component-button-size-#{$buttonSize}-with-outline-icon-offset-icon-only) * -1);
67
+
68
+ } @else {
69
+ $buttonPadding: var(--component-button-size-#{$buttonSize}-padding-y) var(--component-button-size-#{$buttonSize}-padding-x);
70
+ $buttonBorderWidth: var(--component-button-size-#{$buttonSize}-border-width);
71
+
72
+ $iconOffsetLeading: calc(var(--component-button-size-#{$buttonSize}-icon-offset-leading) * -1);
73
+ $iconOffsetTrailing: calc(var(--component-button-size-#{$buttonSize}-icon-offset-trailing) * -1);
74
+ $iconOffsetIconOnly: calc(var(--component-button-size-#{$buttonSize}-icon-offset-icon-only) * -1);
75
+ }
76
+
77
+ // TODO remove properly
78
+ padding: $buttonPadding;
79
+ border-width: $buttonBorderWidth;
80
+ font-size: $buttonFontSize;
81
+
82
+ .button-content {
83
+ gap: $buttonInlineSpacing;
84
+ }
85
+
86
+ .ui-icon {
87
+
88
+ &.icon-context-leading {
89
+ margin-left: #{$iconOffsetLeading};
90
+ }
91
+
92
+ &.icon-context-trailing {
93
+ margin-right: #{$iconOffsetTrailing}
94
+ }
95
+
96
+ &.icon-context-iconOnly {
97
+ margin-left: #{$iconOffsetIconOnly};
98
+ margin-right: #{$iconOffsetIconOnly}
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,48 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { IconNames, IconContext } from '../icon/icon';
3
+
4
+
5
+ export type UIButtonBoolean = true | 'true' | false | 'false';
6
+
7
+ export type UIButtonSize = 'small' | 'large';
8
+
9
+ export type UIButtonType =
10
+ | 'primary'
11
+ | 'secondary'
12
+ | 'tertiary'
13
+ | 'primary-inverse'
14
+ | 'secondary-inverse'
15
+ | 'tertiary-inverse'
16
+ | 'expressive'
17
+ | 'danger'
18
+ | 'facebook'
19
+ | 'paypal'
20
+ | 'trustpilot';
21
+
22
+ export interface UIButton {
23
+
24
+ // Inputs
25
+
26
+ // icon name
27
+ buttonIcon: IconNames;
28
+ // color/styling of button
29
+ buttonType: UIButtonType;
30
+ // positioning for icon
31
+ buttonIconPlacement: IconContext
32
+ // button size
33
+ buttonSize: UIButtonSize;
34
+ // Full width
35
+ buttonFullWidth: UIButtonBoolean;
36
+ // For links, expects relative or absolute url
37
+ href: string;
38
+ target: string;
39
+ buttonDisabled: UIButtonBoolean;
40
+
41
+ // Private properties
42
+ buttonDisplayClasses: string[];
43
+
44
+ // Outputs
45
+
46
+ // Click event, used when no href input
47
+ buttonDidClick: EventEmitter<any>;
48
+ }
@@ -0,0 +1,5 @@
1
+ <div class="ui-icon" [ngClass]="iconDisplayClasses">
2
+ <svg xmlns="http://www.w3.org/2000/svg" attr.width="{{iconWidth}}px" attr.height="{{iconHeight}}px" attr.class="{{iconClass}}">
3
+ <use attr.xlink:href="./{{iconBrandPath}}/assets/icons/icons.svg#icon-{{iconName}}"></use>
4
+ </svg>
5
+ </div>
@@ -0,0 +1,5 @@
1
+
2
+ .ui-icon {
3
+ display: inline-flex;
4
+
5
+ }
@@ -0,0 +1,25 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { IconComponent } from './icon.component';
4
+
5
+ describe('IconComponent', () => {
6
+ let component: IconComponent;
7
+ let fixture: ComponentFixture<IconComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ IconComponent ]
12
+ })
13
+ .compileComponents();
14
+ });
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(IconComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,50 @@
1
+ import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy, OnChanges, ElementRef } from '@angular/core';
2
+ import { TokenService } from '../../services/token.service';
3
+ import { WindowService } from '../../services/window.service';
4
+ import { IconNames, IconContext } from './icon';
5
+
6
+ @Component({
7
+ selector:'ui-icon',
8
+ templateUrl: './icon.component.html',
9
+ styleUrls: ['./icon.component.scss'],
10
+ encapsulation: ViewEncapsulation.None
11
+ })
12
+ export class IconComponent implements OnInit, OnChanges {
13
+ @Input() iconSize: 'small'|'large' = 'large';
14
+ @Input() iconName!: IconNames;
15
+ @Input() iconContext: IconContext = 'none';
16
+
17
+ @Input() iconWidth?: number;
18
+ @Input() iconHeight?: number;
19
+ @Input() iconClass?: string;
20
+
21
+ size?: string;
22
+ iconBrandPath?: string;
23
+ iconDisplayClasses: string[];
24
+
25
+ constructor(private tokenService: TokenService, private windowRef: WindowService, private elementRef: ElementRef) { }
26
+
27
+ convertRemToPixels(remString: string): number {
28
+ const remNumber = parseFloat(remString.replace('rem', ''));
29
+ return remNumber * parseFloat(getComputedStyle(this.windowRef.nativeWindow.document.documentElement).fontSize);
30
+ }
31
+
32
+ ngOnChanges(): void {
33
+ this.ngOnInit();
34
+ }
35
+
36
+ ngOnInit(): void {
37
+ this.iconBrandPath = `${this.tokenService.getBrandName()}`
38
+ this.size = this.tokenService.getTokenValue(`--global-size-icon-${this.iconSize}`);
39
+
40
+ this.iconDisplayClasses = [
41
+ `icon-context-${this.iconContext}`,
42
+ `icon-size-${this.iconSize}`
43
+ ];
44
+
45
+ const sizeInPixels = this.convertRemToPixels(this.size);
46
+ this.iconWidth = sizeInPixels;
47
+ this.iconHeight = sizeInPixels;
48
+ }
49
+
50
+ }
@@ -0,0 +1,25 @@
1
+ export type IconNames =
2
+ | 'close'
3
+ | 'menu'
4
+ | 'tick'
5
+ | 'heart'
6
+ | 'heart-fill'
7
+ | 'basket'
8
+ | 'basket-fill'
9
+ | 'user'
10
+ | 'user-fill'
11
+ | 'chevron-up'
12
+ | 'chevron-down'
13
+ | 'chevron-left'
14
+ | 'chevron-right'
15
+ | 'arrow-up'
16
+ | 'arrow-down'
17
+ | 'arrow-left'
18
+ | 'arrow-right'
19
+ | 'sort'
20
+ | 'filter'
21
+ | 'pin';
22
+
23
+
24
+
25
+ export type IconContext = 'leading' | 'trailing' | 'iconOnly' | 'none';
@@ -0,0 +1,64 @@
1
+ // Most common size options
2
+ type LayoutBaseSizes =
3
+ | 'none'
4
+ | 'tight'
5
+ | 'near'
6
+ | 'default'
7
+ | 'expanded'
8
+ | undefined;
9
+
10
+ interface LayoutDeviceTypes {
11
+ 'mobile'?: string | undefined
12
+ 'tablet'?: string | undefined
13
+ 'desktop'?: string | undefined
14
+ }
15
+
16
+ interface LayoutDeviceColumns {
17
+ 'mobile'?: number | undefined
18
+ 'tablet'?: number | undefined
19
+ 'desktop'?: number | undefined
20
+ }
21
+
22
+ type ResponsiveLayoutBaseSizes = LayoutBaseSizes | LayoutDeviceTypes;
23
+
24
+ export type ResponsiveGridColumns = number | LayoutDeviceColumns;
25
+
26
+ export type LayoutBoxSizes = ResponsiveLayoutBaseSizes;
27
+ export type LayoutGapSizes = LayoutBaseSizes;
28
+
29
+ export type LayoutFillModes =
30
+ | 'fit'
31
+ | 'fill';
32
+
33
+ export type LayoutAlignment =
34
+ | 'start'
35
+ | 'center'
36
+ | 'end'
37
+ | undefined;
38
+
39
+ export type LayoutDistribute =
40
+ | LayoutFillModes
41
+ | LayoutAlignment
42
+ | 'space-between'
43
+ | 'space-around'
44
+ | 'space-evenly'
45
+ | undefined;
46
+
47
+ export type LayoutBackgrounds =
48
+ | 'transparent'
49
+ | 'primary'
50
+ | 'secondary'
51
+ | 'tertiary'
52
+ | 'quaternary'
53
+ | undefined;
54
+
55
+ export type LayoutDirections =
56
+ | 'x'
57
+ | 'y'
58
+ | undefined;
59
+
60
+ export interface LayoutContainerSizes {
61
+ 'mobile'?: string | undefined
62
+ 'tablet'?: string | undefined
63
+ 'desktop'?: string | undefined
64
+ }
@@ -0,0 +1,105 @@
1
+
2
+ $layoutAlignmentAxis: 'align-x', 'align-y';
3
+ $advancedLayoutAlignment: 'space-around', 'space-between', 'space-evenly';
4
+ $layoutGapSizes: 'none', 'tight', 'near', 'default', 'expanded', 'section';
5
+
6
+
7
+ $layoutAlignTypes: (
8
+ "start": flex-start,
9
+ "center": center,
10
+ "end": flex-end,
11
+ );
12
+
13
+ $layoutDistributeTypes: (
14
+ "fill": unset,
15
+ "start": flex-start,
16
+ "center": center,
17
+ "end": flex-end,
18
+ "space-between": space-between,
19
+ "space-around": space-around,
20
+ "space-evenly": space-evenly
21
+ );
22
+
23
+ @mixin layoutAlignmentClasses($direction: 'y'){
24
+
25
+ // Vertical Stacks
26
+
27
+ // Can be aligned:
28
+ // - 'start' (left in countries that read LTR)
29
+ // - 'center'
30
+ // - 'end' (right in countries that read LTR)
31
+
32
+ @if $direction == 'y' {
33
+
34
+ // align
35
+ @each $inputName, $cssName in $layoutAlignTypes {
36
+ &-align-#{$inputName} {
37
+ align-items: $cssName;
38
+ align-content: $cssName;
39
+ }
40
+ }
41
+
42
+ // Distribute
43
+ @each $inputName, $cssName in $layoutDistributeTypes {
44
+
45
+ &-distribute-#{$inputName} {
46
+ justify-content: $cssName;
47
+ height: 100%;
48
+ }
49
+
50
+ }
51
+ }
52
+
53
+ // Horizontal Stacks
54
+
55
+ // Can be aligned:
56
+ // - 'start' (top)
57
+ // - 'center'
58
+ // - 'end' (bottom)
59
+
60
+ // Can be distributed/spaced
61
+ // - 'stack' (none)
62
+ // - 'around'
63
+ // - 'between'
64
+ // - 'equally'
65
+
66
+ @if $direction == 'x' {
67
+
68
+ // Align
69
+ @each $inputName, $cssName in $layoutAlignTypes {
70
+
71
+ &-align-#{$inputName} {
72
+ justify-content: $cssName;
73
+ }
74
+
75
+ &-align-x-#{$inputName} {
76
+ align-items: $cssName;
77
+ align-content: $cssName;
78
+ }
79
+
80
+ }
81
+
82
+ // Distribute
83
+ @each $inputName, $cssName in $layoutDistributeTypes {
84
+
85
+ &-distribute-#{$inputName} {
86
+ justify-content: $cssName;
87
+ }
88
+
89
+ }
90
+
91
+ }
92
+
93
+ }
94
+
95
+
96
+ @mixin layoutGapSizes() {
97
+ @each $layoutGap in $layoutGapSizes {
98
+
99
+ &-#{$layoutGap} {
100
+ gap: var(--semantic-spacing-stack-#{$layoutGap});
101
+ }
102
+
103
+ }
104
+ }
105
+
@@ -0,0 +1,124 @@
1
+ @use './../layout';
2
+ @import './../../../../assets/global/responsive.scss';
3
+
4
+
5
+ $layoutBoxSizes: 'none', 'tight', 'near', 'default', 'expanded', 'section-inset';
6
+ $layoutDevices: 'mobile', 'tablet', 'laptop', 'desktop';
7
+ $layoutOverrides: 'top', 'right', 'bottom', 'left';
8
+ $layoutBackgrounds: 'transparent', 'primary', 'secondary', 'tertiary', 'quaternary';
9
+
10
+
11
+ /* ---------------------
12
+ Simple Side Overrides
13
+
14
+ Simple override of any side of the box
15
+ ie. boxSpaceTop="none"
16
+ ie. boxSpaceTop="tight"
17
+ --------------------- */
18
+
19
+ @mixin layoutBoxOverrideClasses($layoutBoxSize) {
20
+ @each $override in $layoutOverrides {
21
+ &-#{$override} {
22
+
23
+ @if $override == 'top' {
24
+ padding-top: var(--semantic-spacing-box-#{$layoutBoxSize}) !important;
25
+ }
26
+ @if $override == 'right' {
27
+ padding-right: var(--semantic-spacing-box-#{$layoutBoxSize}) !important;
28
+ }
29
+ @if $override == 'bottom' {
30
+ padding-bottom: var(--semantic-spacing-box-#{$layoutBoxSize}) !important;
31
+ }
32
+ @if $override == 'left' {
33
+ padding-left: var(--semantic-spacing-box-#{$layoutBoxSize}) !important;
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ /* ---------------------
40
+ Responsive Side Overrides
41
+
42
+ Responsive override of any side of the box
43
+ ie. [boxSpaceTop]="{mobile: 'tight', tablet: 'Near', laptop: 'default', desktop: 'expanded'}"
44
+ --------------------- */
45
+
46
+
47
+ @mixin layoutBoxResponsiveDevices($layoutBoxSize) {
48
+ @each $device in $layoutDevices {
49
+ &-#{$device} {
50
+ @if $device== 'mobile' {
51
+ @include mobile() {
52
+ padding: var(--semantic-spacing-box-#{$layoutBoxSize});
53
+ @include layoutBoxOverrideClasses($layoutBoxSize)
54
+ }
55
+ }
56
+ @if $device== 'tablet' {
57
+ @include tablet() {
58
+ padding: var(--semantic-spacing-box-#{$layoutBoxSize});
59
+ @include layoutBoxOverrideClasses($layoutBoxSize)
60
+ }
61
+ }
62
+ @if $device== 'laptop' {
63
+ @include laptop() {
64
+ padding: var(--semantic-spacing-box-#{$layoutBoxSize});
65
+ @include layoutBoxOverrideClasses($layoutBoxSize)
66
+ }
67
+ }
68
+ @if $device== 'desktop' {
69
+ @include desktop() {
70
+ padding: var(--semantic-spacing-box-#{$layoutBoxSize});
71
+ @include layoutBoxOverrideClasses($layoutBoxSize)
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ /* ---------------------
79
+ Generate all size options including overrides
80
+ --------------------- */
81
+ @mixin layoutBoxSizes() {
82
+
83
+ @each $layoutBoxSize in $layoutBoxSizes {
84
+ &-#{$layoutBoxSize} {
85
+ padding: var(--semantic-spacing-box-#{$layoutBoxSize});
86
+ @include layoutBoxResponsiveDevices($layoutBoxSize);
87
+ @include layoutBoxOverrideClasses($layoutBoxSize)
88
+ }
89
+ }
90
+
91
+ }
92
+
93
+ /* ---------------------
94
+ Box Background Colors
95
+ --------------------- */
96
+
97
+ @mixin layoutBackgrounds() {
98
+ @each $background in $layoutBackgrounds {
99
+ &-background-#{$background} {
100
+ background-color: var(--semantic-color-background-#{$background});
101
+ }
102
+ }
103
+
104
+ }
105
+
106
+ ui-box {
107
+ display: flex;
108
+ justify-self: stretch;
109
+ flex-direction: column;
110
+
111
+ &.ui-layout-box {
112
+ @include layoutBoxSizes();
113
+ @include layoutBackgrounds();
114
+ @include layout.layoutAlignmentClasses('x');
115
+
116
+ &-fit-content {
117
+ width: fit-content;
118
+ }
119
+ &-fill-container {
120
+ width: 100%;
121
+ }
122
+ }
123
+
124
+ }
@@ -0,0 +1,103 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, OnChanges, OnInit, ViewEncapsulation } from '@angular/core';
2
+ import { Input } from '@angular/core';
3
+ import { Component} from '@angular/core';
4
+ import { LayoutAlignment, LayoutBackgrounds, LayoutBoxSizes, LayoutFillModes } from '../Layout';
5
+
6
+ @Component({
7
+ selector:'ui-box',
8
+ template: '<ng-content></ng-content>',
9
+ host: {
10
+ '[class]' : 'boxLayoutClasses'
11
+ },
12
+ styleUrls: ['./box.component.scss'],
13
+ encapsulation: ViewEncapsulation.None,
14
+ changeDetection: ChangeDetectionStrategy.OnPush
15
+ })
16
+ export class LayoutBoxComponent implements OnInit, OnChanges {
17
+ didFirstInit: boolean = false;
18
+ prefix = 'ui-layout-box';
19
+ boxLayoutClasses?: string[];
20
+
21
+ @Input() boxSpace?: LayoutBoxSizes = 'default';
22
+
23
+ @Input() boxSpaceTop?: LayoutBoxSizes;
24
+ @Input() boxSpaceRight?: LayoutBoxSizes;
25
+ @Input() boxSpaceBottom?: LayoutBoxSizes;
26
+ @Input() boxSpaceLeft?: LayoutBoxSizes;
27
+
28
+ @Input() boxAlignX?: LayoutAlignment = 'start';
29
+ @Input() boxAlignY?: LayoutAlignment = 'start';
30
+
31
+ @Input() boxFillMode?: LayoutFillModes = 'fill';
32
+
33
+ @Input() boxBackground: LayoutBackgrounds = 'primary';
34
+
35
+ constructor(private changes: ChangeDetectorRef) { }
36
+
37
+ getSizeClasses(spaceInput?: LayoutBoxSizes, overrideName?: string): string[] {
38
+ if(!spaceInput || spaceInput === undefined){
39
+ return null;
40
+ }
41
+
42
+ if(typeof spaceInput === 'object'){
43
+
44
+ return Object.keys(spaceInput).map((key) => {
45
+ return `${this.prefix}-${spaceInput[key]}-${key}${overrideName ? `-${overrideName}` : ``}`
46
+ });
47
+
48
+ }
49
+
50
+ return [
51
+ this.prefix,
52
+ `${this.prefix}-${spaceInput}${overrideName ? `-${overrideName}` : ``}`
53
+ ];
54
+
55
+ }
56
+
57
+ getOverrideClasses(spaceOverrides): string[] {
58
+ const spaceTypes = ['top', 'right', 'bottom', 'left'];
59
+
60
+ return spaceOverrides.map((item, index) => {
61
+ return this.getSizeClasses(item, spaceTypes[index]);
62
+ }).filter(Boolean);
63
+ }
64
+
65
+ getAlignmentClasses(alignmentOverride): string[] {
66
+ const spaceTypes = ['align-x', 'align-y'];
67
+
68
+ return alignmentOverride.map((item, index) => {
69
+ return item ? `${this.prefix}-${spaceTypes[index]}-${item}` : undefined;
70
+ }).filter(Boolean);
71
+ }
72
+
73
+ getBackgroundClass(): string {
74
+ const value = this.boxBackground ? `${this.prefix}-background-${this.boxBackground}` : ``;
75
+ return value;
76
+ }
77
+
78
+ ngOnChanges(): void {
79
+ if(!this.didFirstInit){
80
+ return;
81
+ }
82
+ this.ngOnInit();
83
+ this.changes.markForCheck();
84
+ }
85
+
86
+ ngOnInit(): void {
87
+ const spaceOverrides = [this.boxSpaceTop, this.boxSpaceRight, this.boxSpaceBottom, this.boxSpaceLeft];
88
+ const alignmentOverride = [this.boxAlignX, this.boxAlignY];
89
+
90
+ // Basic basic classes
91
+ this.boxLayoutClasses = [
92
+ this.getSizeClasses(this.boxSpace),
93
+ this.getOverrideClasses(spaceOverrides),
94
+ this.getAlignmentClasses(alignmentOverride),
95
+ this.getBackgroundClass(),
96
+ this.boxFillMode === 'fit' ? `${this.prefix}-fit-content` : `${this.prefix}-fill-container`
97
+ ].flat(10).filter(Boolean);
98
+
99
+ this.didFirstInit = true;
100
+ }
101
+
102
+ }
103
+