feature(ui-library): Added own library of UI components to replace digi-ng. Skeleton is first component moved (TV-850)
Squashed commit of the following: commit d76e32cd99e2e823142f4410e66c66df5e096041 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Thu Oct 28 10:28:02 2021 +0200 Move styles to own library commit 85f0a5788ebdd7309499b1b623f4ac1046f45811 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Thu Oct 28 10:09:23 2021 +0200 double quotes in html commit eeb600cd631e3478c136795a8109e8927546b14b Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Oct 27 16:42:48 2021 +0200 UI library with copy of digi-ng's skeleton commit 11a24c0eef173e6b2f087eca5e96063036e6394b Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Oct 27 16:06:43 2021 +0200 Update .eslintrc.json commit 3c4b2e4823dbd8e9ca8dd332966bd10ac0fc098f Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Oct 27 15:08:32 2021 +0200 add nx library
This commit is contained in:
22
libs/styles/.eslintrc.json
Normal file
22
libs/styles/.eslintrc.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
|
||||
"parserOptions": { "project": ["libs/styles/tsconfig.*?.json"] },
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{ "type": "attribute", "prefix": "mina-sidor-fa-web", "style": "camelCase" }
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{ "type": "element", "prefix": "mina-sidor-fa-web", "style": "kebab-case" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "files": ["*.html"], "extends": ["plugin:@nrwl/nx/angular-template"], "rules": {} }
|
||||
]
|
||||
}
|
||||
7
libs/styles/README.md
Normal file
7
libs/styles/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# styles
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test styles` to execute the unit tests.
|
||||
23
libs/styles/jest.config.js
Normal file
23
libs/styles/jest.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
displayName: 'styles',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
astTransformers: {
|
||||
before: [
|
||||
'jest-preset-angular/build/InlineFilesTransformer',
|
||||
'jest-preset-angular/build/StripStylesTransformer',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/libs/styles',
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/AngularSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/HTMLCommentSerializer.js',
|
||||
],
|
||||
};
|
||||
1
libs/styles/src/functions/_rem.scss
Normal file
1
libs/styles/src/functions/_rem.scss
Normal file
@@ -0,0 +1 @@
|
||||
@import '~@digi/styles/src/base/functions/rem';
|
||||
13
libs/styles/src/mixins/_a11y.scss
Normal file
13
libs/styles/src/mixins/_a11y.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
@mixin msfa__a11y-sr-only {
|
||||
border: 0;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
-webkit-clip-path: inset(50%);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
21
libs/styles/src/mixins/_backdrop.scss
Normal file
21
libs/styles/src/mixins/_backdrop.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
@import '../variables/z-index';
|
||||
|
||||
@mixin msfa__backdrop($zIndex: $msfa__z-index-default, $fullScreen: true, $opaqueBackground: false) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: $zIndex;
|
||||
|
||||
@if $opaqueBackground {
|
||||
background-color: var(--digi--ui--color--background);
|
||||
} @else {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
@if $fullScreen {
|
||||
position: fixed;
|
||||
} @else {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
46
libs/styles/src/mixins/_buttons.scss
Normal file
46
libs/styles/src/mixins/_buttons.scss
Normal file
@@ -0,0 +1,46 @@
|
||||
@import '~@digi/core/dist/collection/components/_button/button/button.css';
|
||||
|
||||
@mixin msfa__button($type: 'primary') {
|
||||
padding: var(--digi-button--padding);
|
||||
border-radius: var(--digi-button--border-radius);
|
||||
transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s;
|
||||
text-decoration: none;
|
||||
font-weight: var(--digi-button--font-weight);
|
||||
font-size: var(--digi-button--font-size);
|
||||
width: var(--digi-button--width);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
text-align: var(--digi-button--text-align);
|
||||
border: var(--digi-button--border);
|
||||
outline: var(--digi-button--outline);
|
||||
border-color: var(--digi-button--border-color);
|
||||
|
||||
@if $type == 'secondary' {
|
||||
background-color: var(--digi-button--background--secondary);
|
||||
color: var(--digi-button--color--secondary);
|
||||
} @else if $type == 'tertiary' {
|
||||
background-color: transparent;
|
||||
color: var(--digi-button--color--tertiary);
|
||||
border-width: 0;
|
||||
} @else {
|
||||
background-color: var(--digi-button--background);
|
||||
color: var(--digi-button--color);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
outline: var(--digi-button--outline--focus);
|
||||
border-color: var(--digi-button--border-color--hover);
|
||||
|
||||
@if $type == 'secondary' {
|
||||
background-color: var(--digi-button--background--secondary--hover);
|
||||
color: var(--digi-button--color--secondary);
|
||||
} @else if $type == 'tertiary' {
|
||||
color: var(--digi-button--color--tertiary--hover);
|
||||
} @else {
|
||||
background-color: var(--digi-button--background--hover);
|
||||
color: var(--digi-button--color--hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
libs/styles/src/mixins/_flex.scss
Normal file
5
libs/styles/src/mixins/_flex.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
@mixin msfa__flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
25
libs/styles/src/mixins/_form.scss
Normal file
25
libs/styles/src/mixins/_form.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
@import '../variables/colors';
|
||||
@import '../variables/gutters';
|
||||
|
||||
|
||||
@mixin msfa__fieldset($legendAsHeading: true) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
|
||||
legend {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
|
||||
@if $legendAsHeading {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: var(--digi--layout--gutter--xs);
|
||||
margin: 0;
|
||||
font-weight: var(--digi--typography--font-weight--bold);
|
||||
font-size: var(--digi--typography--font-size--s);
|
||||
border-bottom: 1px solid var(--digi--ui--color--background--off);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
libs/styles/src/mixins/_icon.scss
Normal file
7
libs/styles/src/mixins/_icon.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
@mixin msfa__digi-ng-icon($width: 1em) {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: $width;
|
||||
max-height: $width;
|
||||
}
|
||||
42
libs/styles/src/mixins/_link.scss
Normal file
42
libs/styles/src/mixins/_link.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
@mixin msfa__link($ignore-visited: false, $theme: 'dark') {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: var(--digi--typography--color--link);
|
||||
font-size: var(--digi--typography--font-size);
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
gap: var(--digi--layout--gutter--xs);
|
||||
|
||||
@if ($theme == 'light') {
|
||||
color: var(--digi--typography--color--text--light);
|
||||
|
||||
&:visited {
|
||||
color: var(--digi--typography--color--text--light);
|
||||
|
||||
&:hover {
|
||||
color: var(--digi--typography--color--text--light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@if ($ignore-visited) {
|
||||
&:visited {
|
||||
color: var(--digi--typography--color--link);
|
||||
|
||||
&:hover {
|
||||
color: var(--digi--typography--color--link--active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin msfa__button-as-link($ignore-visited: false) {
|
||||
@include msfa__link($ignore-visited);
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
5
libs/styles/src/mixins/_list.scss
Normal file
5
libs/styles/src/mixins/_list.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
@mixin msfa__reset-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
107
libs/styles/src/styles.scss
Normal file
107
libs/styles/src/styles.scss
Normal file
@@ -0,0 +1,107 @@
|
||||
@import '@digi/core/dist/digi/digi.css';
|
||||
@import '~@angular/cdk/overlay-prebuilt.css';
|
||||
@import 'mixins/a11y';
|
||||
@import 'mixins/backdrop';
|
||||
@import 'mixins/icon';
|
||||
@import 'mixins/link';
|
||||
@import 'variables/z-index';
|
||||
|
||||
* {
|
||||
font-family: var(--digi--typography--font-family);
|
||||
box-sizing: border-box;
|
||||
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-weight: var(--digi--typography--font-weight);
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: var(--digi--typography--font-family);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
dl {
|
||||
dt {
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Make all digi icons display inline-flex to make them get the correct height.
|
||||
[class^='sc-digi-icon'],
|
||||
.digi-button__icon {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
// Fix issue with too long modal-content. This makes it scrollable.
|
||||
.digi-ng-dialog-base__content {
|
||||
max-height: 90vh;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.digi-ng-dialog {
|
||||
position: fixed;
|
||||
z-index: $msfa__z-index-backdrop;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
// Removing margins from digi fieldset component.
|
||||
.digi-form-fieldset {
|
||||
margin: 0;
|
||||
|
||||
&__legend {
|
||||
margin-bottom: var(--digi--layout--gutter--s);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.msfa {
|
||||
&__a11y-sr-only {
|
||||
@include msfa__a11y-sr-only;
|
||||
}
|
||||
|
||||
&__small-text {
|
||||
font-size: 0.875em !important;
|
||||
}
|
||||
|
||||
&__backdrop {
|
||||
@include msfa__backdrop($msfa__z-index-default, false);
|
||||
|
||||
&--full-screen {
|
||||
@include msfa__backdrop($msfa__z-index-backdrop);
|
||||
}
|
||||
}
|
||||
|
||||
&__digi-icon {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
&__link {
|
||||
@include msfa__link(false, 'light');
|
||||
|
||||
&--ignore-visited:visited {
|
||||
@include msfa__link(true, 'light');
|
||||
}
|
||||
}
|
||||
}
|
||||
1
libs/styles/src/variables/_breakpoints.scss
Normal file
1
libs/styles/src/variables/_breakpoints.scss
Normal file
@@ -0,0 +1 @@
|
||||
@import '~@digi/styles/src/layout/variables/layout__variables';
|
||||
7
libs/styles/src/variables/_colors.scss
Normal file
7
libs/styles/src/variables/_colors.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
@import '~@digi/styles/src/ui/variables/ui__variables';
|
||||
|
||||
// AF DIGI Variables
|
||||
$digi--ui--color--primary-light: lighten($digi--ui--color--primary, 10%);
|
||||
$digi--ui--color--primary: $digi--ui--color--stratos;
|
||||
|
||||
// Local variables
|
||||
13
libs/styles/src/variables/_gutters.scss
Normal file
13
libs/styles/src/variables/_gutters.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
@import '~@digi/styles/src/layout/variables/layout__variables';
|
||||
@import '../functions/rem';
|
||||
|
||||
// AF DIGI Variables
|
||||
$digi--layout--gutter--xs: var(--digi--layout--gutter--xs);
|
||||
$digi--layout--gutter--s: var(--digi--layout--gutter--s);
|
||||
$digi--layout--gutter--m: rem(12);
|
||||
$digi--layout--gutter: var(--digi--layout--gutter);
|
||||
$digi--layout--gutter--l: rem(25);
|
||||
$digi--layout--gutter--xl: rem(40);
|
||||
$digi--layout--gutter--xxl: rem(60);
|
||||
|
||||
// Local variables
|
||||
1
libs/styles/src/variables/_navigation.scss
Normal file
1
libs/styles/src/variables/_navigation.scss
Normal file
@@ -0,0 +1 @@
|
||||
$msfa__navigation-height: 4rem;
|
||||
1
libs/styles/src/variables/_shadows.scss
Normal file
1
libs/styles/src/variables/_shadows.scss
Normal file
@@ -0,0 +1 @@
|
||||
$msfa__shadow: 0 0.2rem 0.6rem 0 var(--digi--ui--color--shadow);
|
||||
9
libs/styles/src/variables/_z-index.scss
Normal file
9
libs/styles/src/variables/_z-index.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
$msfa__z-index-default: 0;
|
||||
$msfa__z-index-header: 1;
|
||||
$msfa__z-index-sidebar: 1;
|
||||
$msfa__z-index-footer: 0;
|
||||
$msfa__z-index-selector-panel: 1;
|
||||
$msfa__z-index-backdrop: 1000;
|
||||
$msfa__z-index-skip-to-content: 2;
|
||||
$msfa__z-index-toast: 9999;
|
||||
$msfa__z-index-popover: 1;
|
||||
13
libs/styles/tsconfig.json
Normal file
13
libs/styles/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
19
libs/styles/tsconfig.lib.json
Normal file
19
libs/styles/tsconfig.lib.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": ["dom", "es2018"]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": ["src/test-setup.ts", "**/*.spec.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
10
libs/styles/tsconfig.spec.json
Normal file
10
libs/styles/tsconfig.spec.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
21
libs/ui/.eslintrc.json
Normal file
21
libs/ui/.eslintrc.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{ "type": "attribute", "prefix": "mina-sidor-fa-web", "style": "camelCase" }
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{ "type": "element", "prefix": "mina-sidor-fa-web", "style": "kebab-case" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "files": ["*.html"], "extends": ["plugin:@nrwl/nx/angular-template"], "rules": {} }
|
||||
]
|
||||
}
|
||||
7
libs/ui/README.md
Normal file
7
libs/ui/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# ui
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test ui` to execute the unit tests.
|
||||
23
libs/ui/jest.config.js
Normal file
23
libs/ui/jest.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
displayName: 'ui',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
astTransformers: {
|
||||
before: [
|
||||
'jest-preset-angular/build/InlineFilesTransformer',
|
||||
'jest-preset-angular/build/StripStylesTransformer',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/libs/ui',
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/AngularSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/HTMLCommentSerializer.js',
|
||||
],
|
||||
};
|
||||
6
libs/ui/loader/loader-type.enum.ts
Normal file
6
libs/ui/loader/loader-type.enum.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export enum UiLoaderType {
|
||||
FULL_SCREEN = 'fullscreen',
|
||||
FULL_BLANK_SCREEN = 'full-blank-screen',
|
||||
ABSOLUTE = 'absolute',
|
||||
PADDED = 'padded',
|
||||
}
|
||||
4
libs/ui/loader/loader.component.html
Normal file
4
libs/ui/loader/loader.component.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div [ngClass]="loaderClass">
|
||||
asdf
|
||||
<digi-icon-spinner [ngClass]="spinnerClass"></digi-icon-spinner>
|
||||
</div>
|
||||
40
libs/ui/loader/loader.component.scss
Normal file
40
libs/ui/loader/loader.component.scss
Normal file
@@ -0,0 +1,40 @@
|
||||
@import 'mixins/backdrop';
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/z-index';
|
||||
|
||||
@keyframes spinning {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-loader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&--padded {
|
||||
padding: $digi--layout--gutter--l;
|
||||
}
|
||||
|
||||
&--absolute {
|
||||
@include msfa__backdrop($msfa__z-index-backdrop, false);
|
||||
}
|
||||
|
||||
&--full-screen {
|
||||
@include msfa__backdrop($msfa__z-index-backdrop);
|
||||
}
|
||||
|
||||
&--full-blank-screen {
|
||||
@include msfa__backdrop($msfa__z-index-backdrop, true, true);
|
||||
}
|
||||
|
||||
&__spinner {
|
||||
display: inline-flex;
|
||||
animation: spinning 1s linear infinite;
|
||||
|
||||
&--s {
|
||||
width: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
libs/ui/loader/loader.component.spec.ts
Normal file
26
libs/ui/loader/loader.component.spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { LoaderComponent } from './loader.component';
|
||||
|
||||
describe('LoaderComponent', () => {
|
||||
let component: LoaderComponent;
|
||||
let fixture: ComponentFixture<LoaderComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [LoaderComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
15
libs/ui/loader/loader.component.stories.ts
Normal file
15
libs/ui/loader/loader.component.stories.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { LoaderComponent } from './loader.component';
|
||||
import { UiLoaderModule } from './loader.module';
|
||||
|
||||
export default { title: 'Loader', component: LoaderComponent };
|
||||
|
||||
const componentModule = {
|
||||
moduleMetadata: {
|
||||
imports: [UiLoaderModule],
|
||||
},
|
||||
};
|
||||
|
||||
export const standard = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-loader></ui-loader>',
|
||||
});
|
||||
25
libs/ui/loader/loader.component.ts
Normal file
25
libs/ui/loader/loader.component.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { UiLoaderType } from './loader-type.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-loader',
|
||||
templateUrl: './loader.component.html',
|
||||
styleUrls: ['./loader.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class LoaderComponent {
|
||||
private readonly _defaultClass = 'ui-loader';
|
||||
@Input() uiType: UiLoaderType = UiLoaderType.PADDED;
|
||||
@Input() uiSize: 's' | 'm' = 'm';
|
||||
|
||||
get loaderClass(): string {
|
||||
if (this.uiType) {
|
||||
return `${this._defaultClass} ${this._defaultClass}--${this.uiType as string}`;
|
||||
}
|
||||
return this._defaultClass;
|
||||
}
|
||||
|
||||
get spinnerClass(): string {
|
||||
return `${this._defaultClass}__spinner ${this._defaultClass}__spinner--${this.uiSize}`;
|
||||
}
|
||||
}
|
||||
11
libs/ui/loader/loader.module.ts
Normal file
11
libs/ui/loader/loader.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { LoaderComponent } from './loader.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [LoaderComponent],
|
||||
imports: [CommonModule],
|
||||
exports: [LoaderComponent],
|
||||
})
|
||||
export class UiLoaderModule {}
|
||||
11
libs/ui/skeleton/skeleton.component.html
Normal file
11
libs/ui/skeleton/skeleton.component.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="ui-skeleton" data-digi-ng-component>
|
||||
<div *ngIf="uiText" class="ui-skeleton__top"></div>
|
||||
<p *ngIf="uiText" class="ui-skeleton__text">{{ uiText }}</p>
|
||||
<div class="ui-skeleton__header"></div>
|
||||
<div *ngFor="let stub of stubs" class="ui-skeleton__lines">
|
||||
<div class="ui-skeleton__line"></div>
|
||||
<div class="ui-skeleton__line"></div>
|
||||
<div class="ui-skeleton__line"></div>
|
||||
<div class="ui-skeleton__line ui-skeleton__line--last"></div>
|
||||
</div>
|
||||
</div>
|
||||
91
libs/ui/skeleton/skeleton.component.scss
Normal file
91
libs/ui/skeleton/skeleton.component.scss
Normal file
@@ -0,0 +1,91 @@
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/breakpoints';
|
||||
|
||||
$typography__margin--text: u(6);
|
||||
$animation__duration--sweep: 4s;
|
||||
$ui__color--gray-10: #f5f5f5;
|
||||
$ui__color--gray-20: #efefef;
|
||||
$ui__color--gray-30: #d1d1d1;
|
||||
$ui__color--skeleton-text: linear-gradient(
|
||||
to left,
|
||||
$ui__color--gray-20,
|
||||
$ui__color--gray-20 40%,
|
||||
$ui__color--gray-10 50%,
|
||||
$ui__color--gray-20 60%,
|
||||
$ui__color--gray-20
|
||||
);
|
||||
$ui__color--skeleton-head: linear-gradient(
|
||||
to left,
|
||||
$ui__color--gray-30,
|
||||
$ui__color--gray-30 40%,
|
||||
$ui__color--gray-20 50%,
|
||||
$ui__color--gray-30 60%,
|
||||
$ui__color--gray-30
|
||||
);
|
||||
$skeleton__top--height: 2.5rem;
|
||||
$skeleton__top--height-desktop: 4.5rem;
|
||||
$skeleton__header--height: 1rem + 0.46875rem;
|
||||
$skeleton__header--height-desktop: 2rem + 0.3125rem;
|
||||
|
||||
:host {
|
||||
|
||||
.ui-skeleton__top {
|
||||
animation: ui-skeleton__animation $animation__duration--sweep infinite;
|
||||
height: $skeleton__top--height;
|
||||
background: $ui__color--skeleton-text;
|
||||
background-size: 400%;
|
||||
width: 25%;
|
||||
margin-bottom: var(--digi--layout--gutter--m);
|
||||
|
||||
@media (min-width: $digi--layout--breakpoint--l) {
|
||||
height: $skeleton__top--height-desktop;
|
||||
width: 20%;
|
||||
margin-bottom: $digi--layout--gutter--l;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-skeleton__header {
|
||||
animation: ui-skeleton__animation $animation__duration--sweep infinite;
|
||||
background: $ui__color--skeleton-head;
|
||||
background-size: 400%;
|
||||
width: 33%;
|
||||
height: $skeleton__header--height;
|
||||
margin-bottom: var(----digi--layout--gutter--s);
|
||||
|
||||
@media (min-width: $digi--layout--breakpoint--l) {
|
||||
height: $skeleton__header--height-desktop;
|
||||
margin-bottom: $digi--layout--gutter--l;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-skeleton__line {
|
||||
animation: ui-skeleton__animation $animation__duration--sweep 0.5s infinite;
|
||||
background: $ui__color--skeleton-text;
|
||||
background-size: 400%;
|
||||
margin-bottom: var(--digi--layout--gutter--xs);
|
||||
height: var(--digi--typography--font-size);
|
||||
}
|
||||
|
||||
|
||||
.ui-skeleton__line--last {
|
||||
width: 75%;
|
||||
margin-bottom: var(--digi--layout--gutter);
|
||||
}
|
||||
|
||||
.ui-skeleton__text {
|
||||
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
margin-bottom: $typography__margin--text / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ui-skeleton__animation {
|
||||
0% {
|
||||
background-position-x: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position-x: 0%;
|
||||
}
|
||||
}
|
||||
40
libs/ui/skeleton/skeleton.component.stories.ts
Normal file
40
libs/ui/skeleton/skeleton.component.stories.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { SkeletonComponent } from './skeleton.component';
|
||||
import { UiSkeletonModule } from './skeleton.module';
|
||||
|
||||
export default { title: 'Skeleton', component: SkeletonComponent };
|
||||
|
||||
const componentModule = {
|
||||
moduleMetadata: {
|
||||
imports: [UiSkeletonModule],
|
||||
},
|
||||
};
|
||||
|
||||
export const standard = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton></ui-skeleton>',
|
||||
});
|
||||
|
||||
export const limitedMultiLine = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton [uiCount]="2"></ui-skeleton>',
|
||||
});
|
||||
|
||||
export const extensiveMultiLine = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton [uiCount]="5"></ui-skeleton>',
|
||||
});
|
||||
|
||||
export const paragraphless = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton [uiCount]="0"></ui-skeleton>',
|
||||
});
|
||||
|
||||
export const customText = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton uiText="I am a custom text..."></ui-skeleton>',
|
||||
});
|
||||
|
||||
export const noText = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-skeleton uiText=""></ui-skeleton>',
|
||||
});
|
||||
25
libs/ui/skeleton/skeleton.component.ts
Normal file
25
libs/ui/skeleton/skeleton.component.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Placeholder for content being loaded
|
||||
*
|
||||
* ##Usage
|
||||
* ``import {SkeletonModule} from '@ui/skeleton';``
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-skeleton',
|
||||
templateUrl: './skeleton.component.html',
|
||||
styleUrls: ['./skeleton.component.scss'],
|
||||
})
|
||||
export class SkeletonComponent {
|
||||
/**
|
||||
* The amount of skeleton sections
|
||||
*/
|
||||
@Input() uiCount: number | undefined;
|
||||
|
||||
@Input() uiText = 'Laddar sidan';
|
||||
|
||||
get stubs(): string[] {
|
||||
return Array(this.uiCount);
|
||||
}
|
||||
}
|
||||
10
libs/ui/skeleton/skeleton.module.ts
Normal file
10
libs/ui/skeleton/skeleton.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SkeletonComponent } from './skeleton.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [SkeletonComponent],
|
||||
exports: [SkeletonComponent],
|
||||
})
|
||||
export class UiSkeletonModule {}
|
||||
13
libs/ui/tsconfig.json
Normal file
13
libs/ui/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
19
libs/ui/tsconfig.lib.json
Normal file
19
libs/ui/tsconfig.lib.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": ["dom", "es2018"]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": ["src/test-setup.ts", "**/*.spec.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
10
libs/ui/tsconfig.spec.json
Normal file
10
libs/ui/tsconfig.spec.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user