@funidata/fudis-core 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.
- package/README.md +1 -0
- package/_index.scss +24 -0
- package/package.json +42 -0
- package/src/assets/fonts/fonts.scss +33 -0
- package/src/assets/fonts/woff/FiraSans-Light.woff2 +0 -0
- package/src/assets/fonts/woff/FiraSans-Medium.woff2 +0 -0
- package/src/assets/fonts/woff/FiraSans-Regular.woff2 +0 -0
- package/src/assets/fonts/woff/FiraSans-SemiBold.woff2 +0 -0
- package/src/components/button/button.scss +58 -0
- package/src/components/button/button.stories.js +49 -0
- package/src/foundations/borders/mixins.scss +57 -0
- package/src/foundations/borders/tokens.scss +5 -0
- package/src/foundations/breakpoints/mixins.scss +29 -0
- package/src/foundations/breakpoints/tokens.scss +23 -0
- package/src/foundations/colors/mixins.scss +20 -0
- package/src/foundations/colors/tokens.scss +54 -0
- package/src/foundations/focus/mixins.scss +33 -0
- package/src/foundations/focus/tokens.scss +6 -0
- package/src/foundations/grid/mixins.scss +30 -0
- package/src/foundations/grid/tokens.scss +18 -0
- package/src/foundations/spacing/classes.scss +28 -0
- package/src/foundations/spacing/mixins.scss +60 -0
- package/src/foundations/spacing/tokens.scss +31 -0
- package/src/foundations/typography/mixins.scss +287 -0
- package/src/foundations/typography/tokens.scss +41 -0
- package/src/foundations/utilities/classes.scss +53 -0
- package/src/foundations/utilities/mixins.scss +57 -0
- package/src/foundations/z-index/mixins.scss +11 -0
- package/src/foundations/z-index/tokens.scss +17 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Do not edit - CI will overwrite this file with the root README.md on release.
|
package/_index.scss
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Export all Core SCSS files here
|
|
3
|
+
*/
|
|
4
|
+
@forward './src/assets/fonts/fonts';
|
|
5
|
+
@forward './src/foundations/borders/tokens';
|
|
6
|
+
@forward './src/foundations/breakpoints/tokens';
|
|
7
|
+
@forward './src/foundations/colors/tokens';
|
|
8
|
+
@forward './src/foundations/focus/tokens';
|
|
9
|
+
@forward './src/foundations/grid/tokens';
|
|
10
|
+
@forward './src/foundations/spacing/tokens';
|
|
11
|
+
@forward './src/foundations/typography/tokens';
|
|
12
|
+
@forward './src/foundations/z-index/tokens';
|
|
13
|
+
@forward './src/foundations/borders/mixins';
|
|
14
|
+
@forward './src/foundations/breakpoints/mixins';
|
|
15
|
+
@forward './src/foundations/colors/mixins';
|
|
16
|
+
@forward './src/foundations/focus/mixins';
|
|
17
|
+
@forward './src/foundations/grid/mixins';
|
|
18
|
+
@forward './src/foundations/spacing/mixins';
|
|
19
|
+
@forward './src/foundations/typography/mixins';
|
|
20
|
+
@forward './src/foundations/utilities/mixins';
|
|
21
|
+
@forward './src/foundations/z-index/mixins';
|
|
22
|
+
@forward './src/foundations/spacing/classes';
|
|
23
|
+
@forward './src/foundations/utilities/classes';
|
|
24
|
+
@forward './src/components/button/button';
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@funidata/fudis-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Core styles and foundations for Fudis Design System",
|
|
5
|
+
"files": [
|
|
6
|
+
"src",
|
|
7
|
+
"./_index.scss"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "storybook dev -p 6007",
|
|
11
|
+
"build:storybook": "storybook build",
|
|
12
|
+
"build:dist": "scripts/copy-files.sh",
|
|
13
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/funidata/fudis-core.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"funidata",
|
|
21
|
+
"design-system",
|
|
22
|
+
"core-styles",
|
|
23
|
+
"foundations"
|
|
24
|
+
],
|
|
25
|
+
"author": "Funidata Ltd",
|
|
26
|
+
"license": "CC-BY-NC-SA-4.0",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/funidata/fudis-core/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/funidata/fudis-core#readme",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@storybook/addon-a11y": "^8.6.12",
|
|
33
|
+
"@storybook/addon-essentials": "^8.6.12",
|
|
34
|
+
"@storybook/addon-storysource": "^8.6.12",
|
|
35
|
+
"@storybook/blocks": "^8.6.12",
|
|
36
|
+
"@storybook/html": "^8.6.12",
|
|
37
|
+
"@storybook/html-vite": "^8.6.12",
|
|
38
|
+
"@storybook/test": "^8.6.12",
|
|
39
|
+
"sass-embedded": "^1.86.3",
|
|
40
|
+
"storybook": "^8.6.12"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* stylelint-disable property-disallowed-list */
|
|
2
|
+
|
|
3
|
+
// Light, 300
|
|
4
|
+
@font-face {
|
|
5
|
+
font-family: 'Fira Sans';
|
|
6
|
+
src: url('./woff/FiraSans-Light.woff2');
|
|
7
|
+
font-weight: 300;
|
|
8
|
+
font-style: normal;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Regular, 400
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: 'Fira Sans';
|
|
14
|
+
src: url('./woff/FiraSans-Regular.woff2');
|
|
15
|
+
font-weight: 400;
|
|
16
|
+
font-style: normal;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Medium, 500
|
|
20
|
+
@font-face {
|
|
21
|
+
font-family: 'Fira Sans';
|
|
22
|
+
src: url('./woff/FiraSans-Medium.woff2');
|
|
23
|
+
font-weight: 500;
|
|
24
|
+
font-style: normal;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Semibold, 600
|
|
28
|
+
@font-face {
|
|
29
|
+
font-family: 'Fira Sans';
|
|
30
|
+
src: url('./woff/FiraSans-SemiBold.woff2');
|
|
31
|
+
font-weight: 600;
|
|
32
|
+
font-style: normal;
|
|
33
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
@use '../../foundations/colors/mixins.scss' as colors;
|
|
2
|
+
@use '../../foundations/focus/mixins.scss' as focus;
|
|
3
|
+
@use '../../foundations/borders/mixins.scss' as borders;
|
|
4
|
+
@use '../../foundations/typography/mixins.scss' as typography;
|
|
5
|
+
@use '../../foundations/spacing/tokens.scss' as spacing;
|
|
6
|
+
@use '../../foundations/utilities/mixins.scss' as utilities;
|
|
7
|
+
|
|
8
|
+
.fudis-button {
|
|
9
|
+
@include utilities.box-reset;
|
|
10
|
+
@include borders.border-radius('2px');
|
|
11
|
+
@include colors.bg-color('transparent');
|
|
12
|
+
@include typography.button-typography;
|
|
13
|
+
@include borders.border('2px', 'solid', 'primary');
|
|
14
|
+
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
padding: 0 spacing.$spacing-xs;
|
|
20
|
+
min-width: spacing.$spacing-xxl;
|
|
21
|
+
vertical-align: middle;
|
|
22
|
+
|
|
23
|
+
&:focus {
|
|
24
|
+
@include focus.focus-generic;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&[aria-disabled='true'] {
|
|
28
|
+
@include colors.text-color('gray-dark');
|
|
29
|
+
@include colors.bg-color('gray-light');
|
|
30
|
+
@include borders.border('2px', 'solid', 'transparent');
|
|
31
|
+
@include borders.outline('1px', 'dashed', 'gray-middle');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&__primary {
|
|
35
|
+
@include colors.text-color('white');
|
|
36
|
+
@include colors.bg-color('primary');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&__secondary {
|
|
40
|
+
@include colors.text-color('primary');
|
|
41
|
+
@include colors.bg-color('white');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&__tertiary {
|
|
45
|
+
@include colors.text-color('primary');
|
|
46
|
+
@include borders.border('2px', 'solid', 'transparent');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&__size {
|
|
50
|
+
&__small {
|
|
51
|
+
min-height: spacing.$spacing-md;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&__medium {
|
|
55
|
+
min-height: spacing.$spacing-lg;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
title: "Components/Button",
|
|
3
|
+
decorators: [
|
|
4
|
+
(storyFn) =>
|
|
5
|
+
`<div style="display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-start;">${storyFn()}</div>`,
|
|
6
|
+
],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Primary = () => `
|
|
10
|
+
<button class="fudis-button fudis-button__primary fudis-button__size__medium">
|
|
11
|
+
Primary
|
|
12
|
+
</button>
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const Secondary = () => `
|
|
16
|
+
<button class="fudis-button fudis-button__secondary fudis-button__size__medium">
|
|
17
|
+
Secondary
|
|
18
|
+
</button>
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const Tertiary = () => `
|
|
22
|
+
<button class="fudis-button fudis-button__tertiary fudis-button__size__medium">
|
|
23
|
+
Tertiary
|
|
24
|
+
</button>
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const Primary_Small = () => `
|
|
28
|
+
<button class="fudis-button fudis-button__primary fudis-button__size__small">
|
|
29
|
+
Primary Small
|
|
30
|
+
</button>
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const Secondary_Small = () => `
|
|
34
|
+
<button class="fudis-button fudis-button__secondary fudis-button__size__small">
|
|
35
|
+
Secondary Small
|
|
36
|
+
</button>
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
export const Tertiary_Small = () => `
|
|
40
|
+
<button class="fudis-button fudis-button__tertiary fudis-button__size__small">
|
|
41
|
+
Tertiary Small
|
|
42
|
+
</button>
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
export const Disabled = () => `
|
|
46
|
+
<button aria-disabled="true" class="fudis-button fudis-button__primary fudis-button__size__medium">
|
|
47
|
+
Disabled
|
|
48
|
+
</button>
|
|
49
|
+
`;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* stylelint-disable @stylistic/block-opening-brace-space-before */
|
|
2
|
+
/* stylelint-disable declaration-property-value-disallowed-list */
|
|
3
|
+
/* stylelint-disable property-disallowed-list */
|
|
4
|
+
@use 'sass:map';
|
|
5
|
+
@use './../colors/tokens.scss' as colors;
|
|
6
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
7
|
+
@use './tokens.scss' as borderTokens;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Generates border, i. e.:
|
|
11
|
+
border: 2px solid $primary-dark;
|
|
12
|
+
*/
|
|
13
|
+
@mixin border($width, $style, $color) {
|
|
14
|
+
@if map.has-key(spacing.$pixel-tokens, $width) and
|
|
15
|
+
map.has-key(borderTokens.$border-styles, $style) and
|
|
16
|
+
map.has-key(colors.$colors, $color)
|
|
17
|
+
{
|
|
18
|
+
border: map.get(spacing.$pixel-tokens, $width)
|
|
19
|
+
map.get(borderTokens.$border-styles, $style)
|
|
20
|
+
map.get(colors.$colors, $color);
|
|
21
|
+
} @else {
|
|
22
|
+
@error 'Unknown border parameter. Please check foundations/borders/mixins.scss for accepted arguments.';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
Generates outline i.e. outline: 2px solid $primary-dark;
|
|
28
|
+
*/
|
|
29
|
+
@mixin outline($width, $style, $color) {
|
|
30
|
+
@if map.has-key(spacing.$pixel-tokens, $width) and
|
|
31
|
+
map.has-key(borderTokens.$border-styles, $style) and
|
|
32
|
+
map.has-key(colors.$colors, $color)
|
|
33
|
+
{
|
|
34
|
+
outline: map.get(spacing.$pixel-tokens, $width)
|
|
35
|
+
map.get(borderTokens.$border-styles, $style)
|
|
36
|
+
map.get(colors.$colors, $color);
|
|
37
|
+
outline-offset: -(map.get(spacing.$pixel-tokens, $width));
|
|
38
|
+
} @else {
|
|
39
|
+
@error 'Unknown border parameter. Please check foundations/borders/mixins.scss for accepted arguments.';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@mixin border-radius($width) {
|
|
44
|
+
@if map.has-key(spacing.$pixel-tokens, $width) {
|
|
45
|
+
border-radius: map.get(spacing.$pixel-tokens, $width);
|
|
46
|
+
} @else {
|
|
47
|
+
@error 'Unknown border-radius of #{$width}. It can only be "1px", "2px" or "3px"';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@mixin border-none() {
|
|
52
|
+
border: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@mixin outline-none() {
|
|
56
|
+
outline: none;
|
|
57
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* stylelint-disable @stylistic/block-opening-brace-space-before */
|
|
2
|
+
@use 'sass:map';
|
|
3
|
+
@use './tokens';
|
|
4
|
+
|
|
5
|
+
@mixin breakpoint($breakpoint) {
|
|
6
|
+
@if map.has-key(tokens.$breakpoints, $breakpoint) {
|
|
7
|
+
$breakpoint-value: map.get(tokens.$breakpoints, $breakpoint);
|
|
8
|
+
|
|
9
|
+
@media screen and (min-width: #{$breakpoint-value}) {
|
|
10
|
+
@content;
|
|
11
|
+
}
|
|
12
|
+
} @else {
|
|
13
|
+
@error 'Unknown minimum breakpoint of #{$breakpoint}. Accepted arguments are: "xxl", "xl", "lg", "md", "sm", "xs".';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@mixin breakpoint-max($breakpoint) {
|
|
18
|
+
@if map.has-key(tokens.$max-breakpoints, $breakpoint) and $breakpoint != 'xs'
|
|
19
|
+
{
|
|
20
|
+
$breakpoint-value: map.get(tokens.$max-breakpoints, $breakpoint);
|
|
21
|
+
$calc-max-width: calc($breakpoint-value - 0.01em);
|
|
22
|
+
|
|
23
|
+
@media screen and (max-width: #{$calc-max-width}) {
|
|
24
|
+
@content;
|
|
25
|
+
}
|
|
26
|
+
} @else {
|
|
27
|
+
@error 'Unknown maximum breakpoint of #{$breakpoint}. Accepted arguments are: "xxl", "xl", "lg", "md", and "sm"';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Meant to be used as "min-width" for breakpoints
|
|
2
|
+
$breakpoint-xxl: 100em; // 1600px-;
|
|
3
|
+
$breakpoint-xl: 75em; // 1200px-1599px;
|
|
4
|
+
$breakpoint-lg: 62em; // 992px-1199px;
|
|
5
|
+
$breakpoint-md: 48em; // 768px-991px;
|
|
6
|
+
$breakpoint-sm: 36em; // 576px-767px;
|
|
7
|
+
$breakpoint-xs: 0; // 0-575px;
|
|
8
|
+
|
|
9
|
+
$breakpoints: (
|
|
10
|
+
'xxl': $breakpoint-xxl,
|
|
11
|
+
'xl': $breakpoint-xl,
|
|
12
|
+
'lg': $breakpoint-lg,
|
|
13
|
+
'md': $breakpoint-md,
|
|
14
|
+
'sm': $breakpoint-sm,
|
|
15
|
+
'xs': $breakpoint-xs,
|
|
16
|
+
);
|
|
17
|
+
$max-breakpoints: (
|
|
18
|
+
'xxl': $breakpoint-xxl,
|
|
19
|
+
'xl': $breakpoint-xl,
|
|
20
|
+
'lg': $breakpoint-lg,
|
|
21
|
+
'md': $breakpoint-md,
|
|
22
|
+
'sm': $breakpoint-sm,
|
|
23
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use './tokens' as colors;
|
|
3
|
+
|
|
4
|
+
@mixin text-color($color) {
|
|
5
|
+
@if map.has-key(colors.$colors, $color) {
|
|
6
|
+
/* stylelint-disable-next-line property-disallowed-list */
|
|
7
|
+
color: map.get(colors.$colors, $color);
|
|
8
|
+
} @else {
|
|
9
|
+
@error 'Unknown palette color of #{$color}. Check colors/tokens.scss file for accepted arguments.';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@mixin bg-color($color) {
|
|
14
|
+
@if map.has-key(colors.$colors, $color) {
|
|
15
|
+
/* stylelint-disable-next-line property-disallowed-list */
|
|
16
|
+
background-color: map.get(colors.$colors, $color);
|
|
17
|
+
} @else {
|
|
18
|
+
@error 'Unknown palette background color of #{$color}. Check colors/tokens.scss file for accepted arguments.';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
|
|
3
|
+
/* stylelint-disable color-no-hex */
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
--- Primary Colors ---
|
|
7
|
+
*/
|
|
8
|
+
$color-primary-light: var(--fudis-color-primary-light);
|
|
9
|
+
$color-primary: var(--fudis-color-primary);
|
|
10
|
+
$color-primary-dark: var(--fudis-color-primary-dark);
|
|
11
|
+
$color-primary-extra-dark: var(--fudis-color-primary-extra-dark);
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
--- Secondary & Accent Colors ---
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Grays
|
|
18
|
+
|
|
19
|
+
$color-black: #000000;
|
|
20
|
+
$color-white: #ffffff;
|
|
21
|
+
$color-gray-extra-light: #f1f1f1;
|
|
22
|
+
$color-gray-light: #d4d4d4;
|
|
23
|
+
$color-gray-middle: #727272;
|
|
24
|
+
$color-gray-dark: #484848;
|
|
25
|
+
|
|
26
|
+
// Accent colors
|
|
27
|
+
|
|
28
|
+
$color-red-light: #f8dcd9;
|
|
29
|
+
$color-red: #b83c2e;
|
|
30
|
+
$color-yellow-light: #fdefb4;
|
|
31
|
+
$color-yellow: #f1c40f;
|
|
32
|
+
$color-green-light: #c6ecd6;
|
|
33
|
+
$color-green: #1e874b;
|
|
34
|
+
$color-focus-primary: #1076db;
|
|
35
|
+
$colors: (
|
|
36
|
+
'primary-light': $color-primary-light,
|
|
37
|
+
'primary': $color-primary,
|
|
38
|
+
'primary-dark': $color-primary-dark,
|
|
39
|
+
'primary-extra-dark': $color-primary-extra-dark,
|
|
40
|
+
'black': $color-black,
|
|
41
|
+
'white': $color-white,
|
|
42
|
+
'gray-extra-light': $color-gray-extra-light,
|
|
43
|
+
'gray-light': $color-gray-light,
|
|
44
|
+
'gray-middle': $color-gray-middle,
|
|
45
|
+
'gray-dark': $color-gray-dark,
|
|
46
|
+
'red-light': $color-red-light,
|
|
47
|
+
'red': $color-red,
|
|
48
|
+
'yellow-light': $color-yellow-light,
|
|
49
|
+
'yellow': $color-yellow,
|
|
50
|
+
'green-light': $color-green-light,
|
|
51
|
+
'green': $color-green,
|
|
52
|
+
'focus-primary': $color-focus-primary,
|
|
53
|
+
'transparent': transparent,
|
|
54
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* stylelint-disable property-disallowed-list */
|
|
2
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
3
|
+
@use './../borders/mixins.scss' as borders;
|
|
4
|
+
@use './../colors/tokens' as colors;
|
|
5
|
+
@use './tokens' as tokens;
|
|
6
|
+
|
|
7
|
+
@mixin focus-generic {
|
|
8
|
+
outline: tokens.$focus-generic-outline;
|
|
9
|
+
outline-offset: spacing.$pixel-1;
|
|
10
|
+
box-shadow: 0 0 0 spacing.$spacing-xxs colors.$color-white;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@mixin focus-form-field {
|
|
14
|
+
@include borders.border('1px', 'solid', 'focus-primary');
|
|
15
|
+
|
|
16
|
+
outline: tokens.$focus-form-field-outline;
|
|
17
|
+
outline-offset: -(spacing.$pixel-2);
|
|
18
|
+
box-shadow: 0 0 0 spacing.$pixel-1 colors.$color-white;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@mixin focus-checkbox {
|
|
22
|
+
@include borders.outline('2px', 'solid', 'primary');
|
|
23
|
+
|
|
24
|
+
outline-offset: -(spacing.$pixel-1);
|
|
25
|
+
width: spacing.$checkbox-size;
|
|
26
|
+
height: spacing.$checkbox-size;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@mixin focus-dropdown {
|
|
30
|
+
outline: tokens.$focus-generic-outline;
|
|
31
|
+
outline-offset: -(spacing.$pixel-2);
|
|
32
|
+
box-shadow: 0 0 0 spacing.$spacing-xxs colors.$color-white;
|
|
33
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
@use './../colors/tokens.scss' as colors;
|
|
2
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
3
|
+
|
|
4
|
+
// Variables for Generic and Form field focus outlines
|
|
5
|
+
$focus-generic-outline: spacing.$pixel-2 dashed colors.$color-gray-dark;
|
|
6
|
+
$focus-form-field-outline: spacing.$pixel-2 solid colors.$color-focus-primary;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use './tokens' as tokens;
|
|
3
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
4
|
+
|
|
5
|
+
@mixin grid-max-width($width) {
|
|
6
|
+
@if map.has-key(tokens.$grid-widths, $width) {
|
|
7
|
+
$grid-width-value: map.get(tokens.$grid-widths, $width);
|
|
8
|
+
|
|
9
|
+
max-width: $grid-width-value;
|
|
10
|
+
|
|
11
|
+
@if $width == xl or $width == xxl {
|
|
12
|
+
gap: spacing.$spacing-lg spacing.$spacing-lg;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@if $width == md or $width == lg {
|
|
16
|
+
gap: spacing.$spacing-md spacing.$spacing-md;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@if $width == sm or $width == xs {
|
|
20
|
+
gap: spacing.$spacing-sm spacing.$spacing-sm;
|
|
21
|
+
}
|
|
22
|
+
} @else {
|
|
23
|
+
@error 'Unknown grid width of #{$width}. Accepted arguments are: "xxl", "xl", "lg", "md", "sm", "xs".';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@mixin grid-xs-margins() {
|
|
28
|
+
margin-right: spacing.$spacing-sm;
|
|
29
|
+
margin-left: spacing.$spacing-sm;
|
|
30
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// TODO: is $grid-width-xs actually needed? Check from designers was there a reasoning for it
|
|
2
|
+
|
|
3
|
+
/* stylelint-disable unit-disallowed-list */
|
|
4
|
+
$grid-width-xs: calc(34rem / var(--fudis-rem-multiplier)); // 320px-544px
|
|
5
|
+
$grid-width-sm: calc(34rem / var(--fudis-rem-multiplier)); // 544px
|
|
6
|
+
$grid-width-md: calc(45rem / var(--fudis-rem-multiplier)); // 720px
|
|
7
|
+
$grid-width-lg: calc(60rem / var(--fudis-rem-multiplier)); // 960px
|
|
8
|
+
$grid-width-xl: calc(65rem / var(--fudis-rem-multiplier)); // 1040px
|
|
9
|
+
$grid-width-xxl: calc(96.25rem / var(--fudis-rem-multiplier)); // 1540px
|
|
10
|
+
|
|
11
|
+
$grid-widths: (
|
|
12
|
+
'xxl': $grid-width-xxl,
|
|
13
|
+
'xl': $grid-width-xl,
|
|
14
|
+
'lg': $grid-width-lg,
|
|
15
|
+
'md': $grid-width-md,
|
|
16
|
+
'sm': $grid-width-sm,
|
|
17
|
+
'xs': $grid-width-xs,
|
|
18
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@use './tokens.scss' as spacing;
|
|
2
|
+
@use './mixins.scss' as mixins;
|
|
3
|
+
@use './../breakpoints/mixins.scss' as breakpoints;
|
|
4
|
+
@include mixins.spacing-classes('fudis');
|
|
5
|
+
|
|
6
|
+
@include breakpoints.breakpoint('xs') {
|
|
7
|
+
@include mixins.spacing-classes('fudis-xs');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@include breakpoints.breakpoint('sm') {
|
|
11
|
+
@include mixins.spacing-classes('fudis-sm');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@include breakpoints.breakpoint('md') {
|
|
15
|
+
@include mixins.spacing-classes('fudis-md');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@include breakpoints.breakpoint('lg') {
|
|
19
|
+
@include mixins.spacing-classes('fudis-lg');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@include breakpoints.breakpoint('xl') {
|
|
23
|
+
@include mixins.spacing-classes('fudis-xl');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@include breakpoints.breakpoint('xxl') {
|
|
27
|
+
@include mixins.spacing-classes('fudis-xxl');
|
|
28
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* stylelint-disable declaration-no-important */
|
|
2
|
+
@use './tokens.scss' as spacing;
|
|
3
|
+
|
|
4
|
+
$direction-attributes: (
|
|
5
|
+
'm': 'margin',
|
|
6
|
+
'mt': 'margin-top',
|
|
7
|
+
'mb': 'margin-bottom',
|
|
8
|
+
'ml': 'margin-left',
|
|
9
|
+
'mr': 'margin-right',
|
|
10
|
+
'p': 'padding',
|
|
11
|
+
'pt': 'padding-top',
|
|
12
|
+
'pb': 'padding-bottom',
|
|
13
|
+
'pl': 'padding-left',
|
|
14
|
+
'pr': 'padding-right',
|
|
15
|
+
);
|
|
16
|
+
$spacing-tokens: (
|
|
17
|
+
'none': spacing.$spacing-none,
|
|
18
|
+
'xxs': spacing.$spacing-xxs,
|
|
19
|
+
'xs': spacing.$spacing-xs,
|
|
20
|
+
'sm': spacing.$spacing-sm,
|
|
21
|
+
'md': spacing.$spacing-md,
|
|
22
|
+
'lg': spacing.$spacing-lg,
|
|
23
|
+
'xl': spacing.$spacing-xl,
|
|
24
|
+
'xxl': spacing.$spacing-xxl,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
@mixin spacing-classes($prefix) {
|
|
28
|
+
@each $sKey, $sValue in $spacing-tokens {
|
|
29
|
+
@each $dirKey, $dirValue in $direction-attributes {
|
|
30
|
+
// Generates for desired screen size margin or padding with desired direction. E.g. .fudis-lg-ml-sm or .fudis-sm-pt-xl
|
|
31
|
+
.#{$prefix}-#{$dirKey}-#{$sKey} {
|
|
32
|
+
#{$dirValue}: #{$sValue} !important;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Generates horizontal margins e.g. .fudis-lg-mx-sm
|
|
37
|
+
.#{$prefix}-mx-#{$sKey} {
|
|
38
|
+
margin-right: #{$sValue} !important;
|
|
39
|
+
margin-left: #{$sValue} !important;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Generates vertical margins e.g. .fudis-lg-my-sm
|
|
43
|
+
.#{$prefix}-my-#{$sKey} {
|
|
44
|
+
margin-top: #{$sValue} !important;
|
|
45
|
+
margin-bottom: #{$sValue} !important;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Generates horizontal padding e.g. .fudis-lg-px-sm
|
|
49
|
+
.#{$prefix}-px-#{$sKey} {
|
|
50
|
+
padding-right: #{$sValue} !important;
|
|
51
|
+
padding-left: #{$sValue} !important;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Generates vertical padding e.g. .fudis-lg-py-sm
|
|
55
|
+
.#{$prefix}-py-#{$sKey} {
|
|
56
|
+
padding-top: #{$sValue} !important;
|
|
57
|
+
padding-bottom: #{$sValue} !important;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* stylelint-disable unit-disallowed-list */
|
|
2
|
+
|
|
3
|
+
// Spacing values, based on default 16px base value
|
|
4
|
+
$spacing-none: 0; // 0px
|
|
5
|
+
$spacing-xxs: calc(0.25rem / var(--fudis-rem-multiplier)); // 4px
|
|
6
|
+
$spacing-xs: calc(0.5rem / var(--fudis-rem-multiplier)); // 8px
|
|
7
|
+
$spacing-sm: calc(1rem / var(--fudis-rem-multiplier)); // 16px
|
|
8
|
+
$spacing-md: calc(1.5rem / var(--fudis-rem-multiplier)); // 24px
|
|
9
|
+
$spacing-lg: calc(2rem / var(--fudis-rem-multiplier)); // 32px
|
|
10
|
+
$spacing-xl: calc(2.5rem / var(--fudis-rem-multiplier)); // 40px
|
|
11
|
+
$spacing-xxl: calc(4rem / var(--fudis-rem-multiplier)); // 64px
|
|
12
|
+
|
|
13
|
+
$pixel-1: 1px;
|
|
14
|
+
$pixel-2: 2px;
|
|
15
|
+
$pixel-3: 3px;
|
|
16
|
+
|
|
17
|
+
// Used with borders, border-radius and letter-spacing mixins. Any value >=4px should be used from spacing values above.
|
|
18
|
+
$pixel-tokens: (
|
|
19
|
+
'1px': $pixel-1,
|
|
20
|
+
'2px': $pixel-2,
|
|
21
|
+
'3px': $pixel-3,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Form input width tokens
|
|
25
|
+
$input-width-xs: calc(5.75rem / var(--fudis-rem-multiplier));
|
|
26
|
+
$input-width-sm: calc(10rem / var(--fudis-rem-multiplier));
|
|
27
|
+
$input-width-md: calc(14rem / var(--fudis-rem-multiplier));
|
|
28
|
+
$input-width-lg: calc(23rem / var(--fudis-rem-multiplier));
|
|
29
|
+
|
|
30
|
+
// Fixed size for checkboxes' visual input box. Clickable input area should be 2rem high.
|
|
31
|
+
$checkbox-size: calc(1.25rem / var(--fudis-rem-multiplier));
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/* stylelint-disable property-disallowed-list */
|
|
2
|
+
/* stylelint-disable unit-disallowed-list */
|
|
3
|
+
@use 'sass:map';
|
|
4
|
+
@use './../breakpoints/mixins.scss' as breakpoints;
|
|
5
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
6
|
+
@use './../colors/mixins.scss' as colors;
|
|
7
|
+
@use './../focus/mixins.scss' as focus;
|
|
8
|
+
@use './tokens.scss' as tokens;
|
|
9
|
+
|
|
10
|
+
// Body Text
|
|
11
|
+
|
|
12
|
+
@mixin body-text-lg-light {
|
|
13
|
+
text-transform: initial;
|
|
14
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
15
|
+
font-family: tokens.$font-family;
|
|
16
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
17
|
+
font-weight: tokens.$font-weight-light;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@mixin body-text-lg-regular {
|
|
21
|
+
text-transform: initial;
|
|
22
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
23
|
+
font-family: tokens.$font-family;
|
|
24
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
25
|
+
font-weight: tokens.$font-weight-regular;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@mixin body-text-md-light {
|
|
29
|
+
text-transform: initial;
|
|
30
|
+
line-height: tokens.$body-text-md-line-height;
|
|
31
|
+
font-family: tokens.$font-family;
|
|
32
|
+
font-size: tokens.$body-text-md-font-size;
|
|
33
|
+
font-weight: tokens.$font-weight-light;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@mixin body-text-md-regular {
|
|
37
|
+
text-transform: initial;
|
|
38
|
+
line-height: tokens.$body-text-md-line-height;
|
|
39
|
+
font-family: tokens.$font-family;
|
|
40
|
+
font-size: tokens.$body-text-md-font-size;
|
|
41
|
+
font-weight: tokens.$font-weight-regular;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@mixin body-text-sm-regular {
|
|
45
|
+
text-transform: initial;
|
|
46
|
+
line-height: tokens.$body-text-sm-line-height;
|
|
47
|
+
font-family: tokens.$font-family;
|
|
48
|
+
font-size: tokens.$body-text-sm-font-size;
|
|
49
|
+
font-weight: tokens.$font-weight-regular;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Headings
|
|
53
|
+
|
|
54
|
+
@mixin heading-xxl {
|
|
55
|
+
line-height: tokens.$heading-lg-line-height;
|
|
56
|
+
font-family: tokens.$font-family;
|
|
57
|
+
font-size: tokens.$heading-xxl-font-size;
|
|
58
|
+
font-weight: tokens.$font-weight-medium;
|
|
59
|
+
|
|
60
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
61
|
+
font-size: tokens.$heading-xl-font-size;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@mixin heading-xl {
|
|
66
|
+
line-height: tokens.$heading-lg-line-height;
|
|
67
|
+
font-family: tokens.$font-family;
|
|
68
|
+
font-size: tokens.$heading-xl-font-size;
|
|
69
|
+
font-weight: tokens.$font-weight-medium;
|
|
70
|
+
|
|
71
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
72
|
+
line-height: tokens.$heading-md-line-height;
|
|
73
|
+
font-size: tokens.$heading-lg-font-size;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@mixin heading-lg {
|
|
78
|
+
line-height: tokens.$heading-md-line-height;
|
|
79
|
+
font-family: tokens.$font-family;
|
|
80
|
+
font-size: tokens.$heading-lg-font-size;
|
|
81
|
+
font-weight: tokens.$font-weight-medium;
|
|
82
|
+
|
|
83
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
84
|
+
font-size: tokens.$heading-md-font-size;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@mixin heading-md {
|
|
89
|
+
line-height: tokens.$heading-md-line-height;
|
|
90
|
+
font-family: tokens.$font-family;
|
|
91
|
+
font-size: tokens.$heading-md-font-size;
|
|
92
|
+
font-weight: tokens.$font-weight-medium;
|
|
93
|
+
|
|
94
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
95
|
+
line-height: tokens.$heading-sm-line-height;
|
|
96
|
+
font-size: tokens.$heading-sm-font-size;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@mixin heading-sm {
|
|
101
|
+
line-height: tokens.$heading-sm-line-height;
|
|
102
|
+
font-family: tokens.$font-family;
|
|
103
|
+
font-size: tokens.$heading-sm-font-size;
|
|
104
|
+
font-weight: tokens.$font-weight-medium;
|
|
105
|
+
|
|
106
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
107
|
+
font-size: tokens.$heading-xs-font-size;
|
|
108
|
+
font-weight: tokens.$font-weight-bold;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@mixin heading-xs {
|
|
113
|
+
line-height: tokens.$heading-sm-line-height;
|
|
114
|
+
font-family: tokens.$font-family;
|
|
115
|
+
font-size: tokens.$heading-xs-font-size;
|
|
116
|
+
font-weight: tokens.$font-weight-bold;
|
|
117
|
+
|
|
118
|
+
@include breakpoints.breakpoint-max('sm') {
|
|
119
|
+
font-size: tokens.$heading-xxs-font-size;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@mixin heading-xxs {
|
|
124
|
+
line-height: tokens.$heading-sm-line-height;
|
|
125
|
+
font-family: tokens.$font-family;
|
|
126
|
+
font-size: tokens.$heading-xxs-font-size;
|
|
127
|
+
font-weight: tokens.$font-weight-bold;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Table caption
|
|
131
|
+
|
|
132
|
+
@mixin table-caption {
|
|
133
|
+
text-transform: uppercase;
|
|
134
|
+
line-height: tokens.$text-input-line-height;
|
|
135
|
+
font-family: tokens.$font-family;
|
|
136
|
+
font-size: tokens.$body-text-md-font-size;
|
|
137
|
+
font-weight: tokens.$font-weight-regular;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Other UI styles
|
|
141
|
+
|
|
142
|
+
// Text-input, text-area, dropdown, legend components
|
|
143
|
+
|
|
144
|
+
@mixin text-field-label {
|
|
145
|
+
text-transform: uppercase;
|
|
146
|
+
line-height: tokens.$form-label-line-height;
|
|
147
|
+
font-family: tokens.$font-family;
|
|
148
|
+
font-size: tokens.$body-text-md-font-size;
|
|
149
|
+
font-weight: tokens.$font-weight-regular;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@mixin text-field-input {
|
|
153
|
+
line-height: tokens.$text-input-line-height;
|
|
154
|
+
font-family: tokens.$font-family;
|
|
155
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
156
|
+
font-weight: tokens.$font-weight-light;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@mixin select-group-label {
|
|
160
|
+
line-height: tokens.$text-input-line-height;
|
|
161
|
+
font-family: tokens.$font-family;
|
|
162
|
+
font-size: tokens.$body-text-sm-font-size;
|
|
163
|
+
font-weight: tokens.$font-weight-light;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Badge component
|
|
167
|
+
|
|
168
|
+
@mixin badge-typography {
|
|
169
|
+
text-transform: uppercase;
|
|
170
|
+
line-height: tokens.$badge-line-height;
|
|
171
|
+
font-family: tokens.$font-family;
|
|
172
|
+
font-size: tokens.$body-text-sm-font-size;
|
|
173
|
+
font-weight: tokens.$font-weight-regular;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Description-list component
|
|
177
|
+
|
|
178
|
+
@mixin description-list-key-typography {
|
|
179
|
+
@include text-field-label;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@mixin description-list-value-typography {
|
|
183
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
184
|
+
font-family: tokens.$font-family;
|
|
185
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
186
|
+
font-weight: tokens.$font-weight-light;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@mixin description-list-compact-key-typography {
|
|
190
|
+
text-transform: none;
|
|
191
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
192
|
+
font-family: tokens.$font-family;
|
|
193
|
+
font-size: tokens.$body-text-md-font-size;
|
|
194
|
+
font-weight: tokens.$font-weight-light;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
@mixin description-list-compact-value-typography {
|
|
198
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
199
|
+
font-family: tokens.$font-family;
|
|
200
|
+
font-size: tokens.$body-text-md-font-size;
|
|
201
|
+
font-weight: tokens.$font-weight-regular;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Button component
|
|
205
|
+
|
|
206
|
+
@mixin button-typography {
|
|
207
|
+
@include letter-spacing('1px');
|
|
208
|
+
|
|
209
|
+
text-transform: uppercase;
|
|
210
|
+
line-height: tokens.$body-text-sm-line-height;
|
|
211
|
+
/* stylelint-disable-next-line @stylistic/declaration-colon-space-after */
|
|
212
|
+
font-family:
|
|
213
|
+
tokens.$font-family, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
214
|
+
font-size: tokens.$body-text-md-font-size;
|
|
215
|
+
font-weight: tokens.$font-weight-bold;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@mixin letter-spacing($width) {
|
|
219
|
+
@if map.has-key(spacing.$pixel-tokens, $width) {
|
|
220
|
+
letter-spacing: map.get(spacing.$pixel-tokens, $width);
|
|
221
|
+
} @else {
|
|
222
|
+
@error 'Unknown letter-spacing parameter. It can only be "1px", "2px" or "3px"';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Expandable component
|
|
227
|
+
|
|
228
|
+
@mixin expandable-regular-typography {
|
|
229
|
+
line-height: tokens.$body-text-lg-line-height;
|
|
230
|
+
font-family: tokens.$font-family;
|
|
231
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
232
|
+
font-weight: tokens.$font-weight-regular;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@mixin expandable-sub-title-typography {
|
|
236
|
+
font-family: tokens.$font-family;
|
|
237
|
+
font-size: tokens.$body-text-sm-font-size;
|
|
238
|
+
font-weight: tokens.$font-weight-light;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Link component
|
|
242
|
+
|
|
243
|
+
@mixin text-link {
|
|
244
|
+
@include colors.text-color('primary-dark');
|
|
245
|
+
|
|
246
|
+
display: inline-block;
|
|
247
|
+
position: relative;
|
|
248
|
+
text-decoration: underline solid;
|
|
249
|
+
font-family: tokens.$font-family;
|
|
250
|
+
overflow-wrap: anywhere;
|
|
251
|
+
|
|
252
|
+
&:focus {
|
|
253
|
+
@include focus.focus-generic;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@mixin link-md {
|
|
258
|
+
@include text-link;
|
|
259
|
+
|
|
260
|
+
font-size: tokens.$body-text-md-font-size;
|
|
261
|
+
font-weight: tokens.$font-weight-regular;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@mixin link-lg {
|
|
265
|
+
@include text-link;
|
|
266
|
+
|
|
267
|
+
font-size: tokens.$body-text-lg-font-size;
|
|
268
|
+
font-weight: tokens.$font-weight-regular;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@mixin link-inherit {
|
|
272
|
+
@include text-link;
|
|
273
|
+
|
|
274
|
+
font-size: inherit;
|
|
275
|
+
font-weight: inherit;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Empty state
|
|
279
|
+
|
|
280
|
+
@mixin text-emptystate {
|
|
281
|
+
@include colors.text-color('gray-middle');
|
|
282
|
+
|
|
283
|
+
font-family: tokens.$font-family;
|
|
284
|
+
font-size: tokens.$body-text-md-font-size;
|
|
285
|
+
font-weight: tokens.$font-weight-regular;
|
|
286
|
+
font-style: tokens.$font-style-italic;
|
|
287
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* stylelint-disable unit-disallowed-list */
|
|
2
|
+
|
|
3
|
+
$font-family: 'Fira Sans', sans-serif;
|
|
4
|
+
|
|
5
|
+
// Body text font size
|
|
6
|
+
$body-text-lg-font-size: calc(1rem / var(--fudis-rem-multiplier));
|
|
7
|
+
$body-text-md-font-size: calc(0.875rem / var(--fudis-rem-multiplier));
|
|
8
|
+
$body-text-sm-font-size: calc(0.75rem / var(--fudis-rem-multiplier));
|
|
9
|
+
|
|
10
|
+
// Heading font size
|
|
11
|
+
$heading-xxl-font-size: calc(2.25rem / var(--fudis-rem-multiplier));
|
|
12
|
+
$heading-xl-font-size: calc(1.75rem / var(--fudis-rem-multiplier));
|
|
13
|
+
$heading-lg-font-size: calc(1.5rem / var(--fudis-rem-multiplier));
|
|
14
|
+
$heading-md-font-size: calc(1.25rem / var(--fudis-rem-multiplier));
|
|
15
|
+
$heading-sm-font-size: calc(1.125rem / var(--fudis-rem-multiplier));
|
|
16
|
+
$heading-xs-font-size: calc(1rem / var(--fudis-rem-multiplier));
|
|
17
|
+
$heading-xxs-font-size: calc(0.875rem / var(--fudis-rem-multiplier));
|
|
18
|
+
|
|
19
|
+
// Body text line height
|
|
20
|
+
$body-text-lg-line-height: calc(1.25rem / var(--fudis-rem-multiplier));
|
|
21
|
+
$body-text-md-line-height: calc(1.125rem / var(--fudis-rem-multiplier));
|
|
22
|
+
$body-text-sm-line-height: calc(1rem / var(--fudis-rem-multiplier));
|
|
23
|
+
|
|
24
|
+
// Heading line heights
|
|
25
|
+
$heading-lg-line-height: calc(2.5rem / var(--fudis-rem-multiplier));
|
|
26
|
+
$heading-md-line-height: calc(1.75rem / var(--fudis-rem-multiplier));
|
|
27
|
+
$heading-sm-line-height: calc(1.125rem / var(--fudis-rem-multiplier));
|
|
28
|
+
|
|
29
|
+
// Other UI line heights
|
|
30
|
+
$text-input-line-height: calc(1.25rem / var(--fudis-rem-multiplier));
|
|
31
|
+
$form-label-line-height: calc(1.5rem / var(--fudis-rem-multiplier));
|
|
32
|
+
$badge-line-height: calc(0.875rem / var(--fudis-rem-multiplier));
|
|
33
|
+
|
|
34
|
+
// Font weight
|
|
35
|
+
$font-weight-light: 300;
|
|
36
|
+
$font-weight-regular: 400;
|
|
37
|
+
$font-weight-medium: 500;
|
|
38
|
+
$font-weight-bold: 600;
|
|
39
|
+
|
|
40
|
+
// Font styles
|
|
41
|
+
$font-style-italic: italic;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
@use './mixins.scss' as mixins;
|
|
2
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
3
|
+
@use './../borders/mixins.scss' as border;
|
|
4
|
+
@use './../colors/mixins.scss' as colors;
|
|
5
|
+
|
|
6
|
+
.fudis-visually-hidden {
|
|
7
|
+
@include mixins.visually-hidden;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.fudis-box-reset {
|
|
11
|
+
@include mixins.box-reset;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Invalid and disabled state styles for input elemenets
|
|
15
|
+
|
|
16
|
+
.fudis-form-input {
|
|
17
|
+
@include border.border('1px', 'solid', 'gray-middle');
|
|
18
|
+
@include colors.bg-color('white');
|
|
19
|
+
|
|
20
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
21
|
+
&.ng-touched,
|
|
22
|
+
&--touched {
|
|
23
|
+
&[aria-invalid='true'] {
|
|
24
|
+
@include border.border('1px', 'solid', 'red');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&[aria-disabled='true'] {
|
|
29
|
+
@include border.border('1px', 'dashed', 'gray-middle');
|
|
30
|
+
@include colors.bg-color('gray-extra-light');
|
|
31
|
+
|
|
32
|
+
cursor: default;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.fudis-input-size {
|
|
38
|
+
&__xs {
|
|
39
|
+
max-width: spacing.$input-width-xs;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&__sm {
|
|
43
|
+
max-width: spacing.$input-width-sm;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&__md {
|
|
47
|
+
max-width: spacing.$input-width-md;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&__lg {
|
|
51
|
+
max-width: spacing.$input-width-lg;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* stylelint-disable property-disallowed-list */
|
|
2
|
+
/* stylelint-disable unit-disallowed-list */
|
|
3
|
+
@use './../spacing/tokens.scss' as spacing;
|
|
4
|
+
@use './../colors/tokens.scss' as colors;
|
|
5
|
+
@use './../typography/mixins.scss' as typography;
|
|
6
|
+
@use './../borders/mixins.scss' as borders;
|
|
7
|
+
@use './../focus/mixins.scss' as focus;
|
|
8
|
+
|
|
9
|
+
@mixin visually-hidden() {
|
|
10
|
+
position: absolute;
|
|
11
|
+
left: 0;
|
|
12
|
+
opacity: 0;
|
|
13
|
+
margin: -1px;
|
|
14
|
+
outline: 0;
|
|
15
|
+
border: 0;
|
|
16
|
+
padding: 0;
|
|
17
|
+
width: 1px;
|
|
18
|
+
height: 1px;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
white-space: nowrap;
|
|
21
|
+
clip: rect(0 0 0 0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@mixin box-reset() {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
margin: 0;
|
|
27
|
+
padding: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@mixin text-input() {
|
|
31
|
+
@include typography.text-field-input;
|
|
32
|
+
@include borders.border-radius('2px');
|
|
33
|
+
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
padding: spacing.$spacing-xxs spacing.$spacing-sm;
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: spacing.$spacing-xl;
|
|
38
|
+
|
|
39
|
+
&:focus {
|
|
40
|
+
@include focus.focus-form-field;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@mixin text-area() {
|
|
45
|
+
@include typography.text-field-input;
|
|
46
|
+
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
display: block;
|
|
49
|
+
padding: spacing.$spacing-xxs;
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: calc(5rem / var(--fudis-rem-multiplier));
|
|
52
|
+
resize: vertical; // Enable resizing the textarea only vertically. Can be also 'none' if we want to disable resizing all together
|
|
53
|
+
|
|
54
|
+
&:focus {
|
|
55
|
+
@include focus.focus-form-field;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use './tokens' as tokens;
|
|
3
|
+
|
|
4
|
+
@mixin z-index($layer-name) {
|
|
5
|
+
@if map.has-key(tokens.$layer-names, $layer-name) {
|
|
6
|
+
/* stylelint-disable-next-line property-disallowed-list */
|
|
7
|
+
z-index: map.get(tokens.$layer-names, $layer-name);
|
|
8
|
+
} @else {
|
|
9
|
+
@error 'Unknown z-index layer name of #{$layer-name}. Accepted names are: "dropdown-menu", "dialog" and "alert".';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Add new z-index layer names when needed. Do not clutter, keep z-index options minimum.
|
|
3
|
+
*/
|
|
4
|
+
$z-index-dropdown-menu: 100;
|
|
5
|
+
$z-index-dialog: 200;
|
|
6
|
+
$z-index-alert: 300;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* If we don't want to maintain static z-index numbers, this could be refactored so that we have an array of layer names
|
|
10
|
+
* and z-indexes are calculated according to the array indexes * 100.
|
|
11
|
+
* This way the possible top/below priority doesn't need manual refactoring of the z-index values above.
|
|
12
|
+
*/
|
|
13
|
+
$layer-names: (
|
|
14
|
+
'dropdown-menu': $z-index-dropdown-menu,
|
|
15
|
+
'dialog': $z-index-dialog,
|
|
16
|
+
'alert': $z-index-alert,
|
|
17
|
+
);
|