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.
- package/.browserslistrc +17 -0
- package/karma.conf.js +44 -0
- package/ng-package.json +10 -0
- package/package.json +3 -10
- package/src/assets/bloomandwild/variables.css +21 -13
- package/src/assets/bloomon/variables.css +21 -13
- package/src/assets/global/scss-breakpoints.scss +1 -1
- package/src/assets/global/typography.scss +4 -6
- package/src/assets/global/variables.css +5 -2
- package/src/lib/components/button/button.component.html +16 -0
- package/src/lib/components/button/button.component.scss +188 -0
- package/src/lib/components/button/button.component.spec.ts +25 -0
- package/src/lib/components/button/button.component.ts +95 -0
- package/src/lib/components/button/button.modifiers.scss +101 -0
- package/src/lib/components/button/button.ts +48 -0
- package/src/lib/components/icon/icon.component.html +5 -0
- package/src/lib/components/icon/icon.component.scss +5 -0
- package/src/lib/components/icon/icon.component.spec.ts +25 -0
- package/src/lib/components/icon/icon.component.ts +50 -0
- package/src/lib/components/icon/icon.ts +25 -0
- package/src/lib/components/layout/Layout.ts +64 -0
- package/src/lib/components/layout/_layout.scss +105 -0
- package/src/lib/components/layout/box/box.component.scss +124 -0
- package/src/lib/components/layout/box/box.component.ts +103 -0
- package/src/lib/components/layout/container/container.component.scss +66 -0
- package/src/lib/components/layout/container/container.component.ts +70 -0
- package/src/lib/components/layout/grid/grid.component.scss +162 -0
- package/src/lib/components/layout/grid/grid.component.ts +103 -0
- package/src/lib/components/layout/stack/stack.component.scss +60 -0
- package/src/lib/components/layout/stack/stack.component.ts +58 -0
- package/src/lib/components/text/text.component.html +1 -0
- package/src/lib/components/text/text.component.scss +33 -0
- package/src/lib/components/text/text.component.spec.ts +25 -0
- package/src/lib/components/text/text.component.ts +29 -0
- package/src/lib/components/text/text.ts +1 -0
- package/src/lib/oasys-lib.module.ts +42 -0
- package/src/lib/oasys-lib.service.spec.ts +16 -0
- package/src/lib/oasys-lib.service.ts +9 -0
- package/src/lib/services/token.service.ts +37 -0
- package/src/lib/services/window.service.ts +16 -0
- package/{public-api.d.ts → src/public-api.ts} +7 -1
- package/src/test.ts +27 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.lib.prod.json +7 -0
- package/tsconfig.spec.json +17 -0
- package/bundles/oasys-lib.umd.js +0 -629
- package/bundles/oasys-lib.umd.js.map +0 -1
- package/esm2015/lib/components/button/button.component.js +0 -97
- package/esm2015/lib/components/button/button.js +0 -2
- package/esm2015/lib/components/icon/icon.component.js +0 -58
- package/esm2015/lib/components/icon/icon.js +0 -2
- package/esm2015/lib/components/layout/Layout.js +0 -2
- package/esm2015/lib/components/layout/box/box.component.js +0 -99
- package/esm2015/lib/components/layout/container/container.component.js +0 -81
- package/esm2015/lib/components/layout/grid/grid.component.js +0 -104
- package/esm2015/lib/components/layout/stack/stack.component.js +0 -65
- package/esm2015/lib/components/text/text.js +0 -2
- package/esm2015/lib/oasys-lib.module.js +0 -66
- package/esm2015/lib/services/token.service.js +0 -41
- package/esm2015/lib/services/window.service.js +0 -19
- package/esm2015/oasys-lib.js +0 -5
- package/esm2015/public-api.js +0 -11
- package/fesm2015/oasys-lib.js +0 -601
- package/fesm2015/oasys-lib.js.map +0 -1
- package/lib/components/button/button.component.d.ts +0 -32
- package/lib/components/button/button.component.d.ts.map +0 -1
- package/lib/components/button/button.d.ts +0 -18
- package/lib/components/button/button.d.ts.map +0 -1
- package/lib/components/icon/icon.component.d.ts +0 -26
- package/lib/components/icon/icon.component.d.ts.map +0 -1
- package/lib/components/icon/icon.d.ts +0 -3
- package/lib/components/icon/icon.d.ts.map +0 -1
- package/lib/components/layout/Layout.d.ts +0 -27
- package/lib/components/layout/Layout.d.ts.map +0 -1
- package/lib/components/layout/box/box.component.d.ts +0 -28
- package/lib/components/layout/box/box.component.d.ts.map +0 -1
- package/lib/components/layout/container/container.component.d.ts +0 -21
- package/lib/components/layout/container/container.component.d.ts.map +0 -1
- package/lib/components/layout/grid/grid.component.d.ts +0 -31
- package/lib/components/layout/grid/grid.component.d.ts.map +0 -1
- package/lib/components/layout/stack/stack.component.d.ts +0 -21
- package/lib/components/layout/stack/stack.component.d.ts.map +0 -1
- package/lib/components/text/text.d.ts +0 -2
- package/lib/components/text/text.d.ts.map +0 -1
- package/lib/oasys-lib.module.d.ts +0 -15
- package/lib/oasys-lib.module.d.ts.map +0 -1
- package/lib/services/token.service.d.ts +0 -12
- package/lib/services/token.service.d.ts.map +0 -1
- package/lib/services/window.service.d.ts +0 -7
- package/lib/services/window.service.d.ts.map +0 -1
- package/oasys-lib.d.ts +0 -6
- package/oasys-lib.d.ts.map +0 -1
- 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,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
|
+
|