diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/scss/utils.scss | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/src/scss/utils.scss')
| -rw-r--r-- | addons/web/static/src/scss/utils.scss | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/addons/web/static/src/scss/utils.scss b/addons/web/static/src/scss/utils.scss new file mode 100644 index 00000000..0fcca801 --- /dev/null +++ b/addons/web/static/src/scss/utils.scss @@ -0,0 +1,437 @@ +/// +/// This file regroups the odoo mixins. They are available in every asset bundle. +/// + +// ------------------------------------------------------------------ +// Caret +// ------------------------------------------------------------------ +@mixin utils-caret-boilerplate { + content: ""; + display: inline-block; + width: 0; + height: 0; + vertical-align: middle; +} + +// ------------------------------------------------------------------ +// Position absolute +// ------------------------------------------------------------------ +@mixin o-position-absolute($top: auto, $right: auto, $bottom: auto, $left: auto) { + position: absolute; + top: $top; + left: $left; + bottom: $bottom; + right: $right; +} + +// ------------------------------------------------------------------ +// Position sticky +// ------------------------------------------------------------------ +@mixin o-position-sticky($top: auto, $right: auto, $bottom: auto, $left: auto) { + position: -webkit-sticky; + position: sticky; + top: $top; + left: $left; + bottom: $bottom; + right: $right; +} + +// ------------------------------------------------------------------ +// Text overflow +// ------------------------------------------------------------------ +@mixin o-text-overflow($display: inline-block, $max-width: 100%) { + display: $display; + max-width: $max-width; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: top; // To update display context changed by overflow:hidden +} + +// ------------------------------------------------------------------ +// Hovering effects +// ------------------------------------------------------------------ +@mixin o-hover-opacity($default-opacity: 0.5, $hover-opacity: 1) { + opacity: $default-opacity; + + &:hover, &:focus, &.focus { + opacity: $hover-opacity; + } +} + +//------------------------------------------------------------------------------ +// Colors +//------------------------------------------------------------------------------ + +@function luma($color) { + @return ((red($color) * .299) + (green($color) * .587) + (blue($color) * .114)) / 255 * 100%; +} +// +// Given two colors, returns the one which has the most constrast with another +// given color. Careful: if you want to find the text color which will suit the +// most on a given background color, you should use the 'color-yiq' function. +// +@function o-get-most-contrast($color, $c1, $c2, $background: #FFFFFF, $threshold: false, $cross-mix: true) { + $background: if($background == null, #FFFFFF, $background); + + $real-color: mix(rgba($color, 1.0), $background, percentage(alpha($color))); + $luma: luma($real-color); + + $cross-color: if($cross-mix, $real-color, $background); + + $real-c1: mix(rgba($c1, 1.0), $cross-color, percentage(alpha($c1))); + $luma-c1: luma($real-c1); + + $real-c2: mix(rgba($c2, 1.0), $cross-color, percentage(alpha($c2))); + $luma-c2: luma($real-c2); + + $-dark: if($luma-c1 <= $luma-c2, $c1, $c2); + $-light: if($luma-c1 > $luma-c2, $c1, $c2); + + @if $threshold == false { + // Automatic threshold: give a really small preference to light results + // as bootstrap does by default (mainly by compatibility at the moment + // this code is written) + $threshold: ($luma-c1 + $luma-c2) * 0.515; // 150 / 145.63 * 0.5 would be the BS value + } + + @return if($luma > $threshold, $-dark, $-light); +} + +// Extend placeholder which adds a chess-like background below the color and +// image of an element to preview the transparency of that color and image. +// This is done thanks to both ::before and ::after elements so they must both +// be available. +%o-preview-alpha-background { + position: relative; + z-index: 0; + + &::before { + content: ""; + @include o-position-absolute(0, 0, 0, 0); + z-index: -1; + background-image: url('/web/static/src/img/transparent.png'); + background-size: 10px auto; + border-radius: inherit; + } + &::after { + content: ""; + @include o-position-absolute(0, 0, 0, 0); + z-index: -1; + background: inherit; // Inherit all background properties + border-radius: inherit; + } +} + +// ------------------------------------------------------------------ +// Padding +// ------------------------------------------------------------------ +@mixin o-webclient-padding($top: 0px, $right: $o-horizontal-padding, $bottom: 0px, $left: $o-horizontal-padding) { + padding-top: $top; + padding-right: $right; + padding-bottom: $bottom; + padding-left: $left; +} + +// ------------------------------------------------------------------ +// Caret +// ------------------------------------------------------------------ +@mixin o-caret-down($caret-width: $caret-width) { + @include utils-caret-boilerplate; + border-bottom: 0; + border-left: $caret-width solid transparent; + border-right: $caret-width solid transparent; + border-top: $caret-width solid; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +@mixin o-caret-up($caret-width: $caret-width) { + @include utils-caret-boilerplate; + border-bottom: $caret-width solid; + border-left: $caret-width solid transparent; + border-right: $caret-width solid transparent; + border-top: 0; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +@mixin o-caret-left($caret-width: $caret-width) { + @include utils-caret-boilerplate; + border-bottom: $caret-width solid transparent; + border-left: 0; + border-right: $caret-width solid; + border-top: $caret-width solid transparent; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +@mixin o-caret-right($caret-width: $caret-width) { + @include utils-caret-boilerplate; + border-bottom: $caret-width solid transparent; + border-left: $caret-width solid; + border-right: 0; + border-top: $caret-width solid transparent; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} + +// ------------------------------------------------------------------ +// Hovering effects +// ------------------------------------------------------------------ +@mixin o-hover-text-color($default-color: $body-color, $hover-color: $link-color) { + color: $default-color; + + &:hover, &:focus, &.focus { + color: $hover-color; + } +} + +// ------------------------------------------------------------------ +// Mixin to define variations for btn-links and muted btn-links +// ------------------------------------------------------------------ +@mixin o-btn-link-variant($color, $color-active) { + text-transform: none; + @include o-hover-text-color($default-color: $color, $hover-color: $color-active); + + &, &:hover, &:focus, &:active, &.active { + border-color: transparent; + background-color: transparent; + } + + &.text-muted, .text-muted { + @include o-hover-opacity; + @include o-hover-text-color($default-color: $text-muted, $hover-color: $color-active); + } +} + +// Odoo defines a limited Noto font-family for a small variety of unicode +// characters that are not necessary defined in the user system or even defined +// but not properly readable. This function allows to add this font family in a +// given font list. +// +// @param {list} $font - a list of font names ending with the generic one. +// @param {integer} [$index] - the position where to add the support font, if +// not given, it will be placed before the generic one. +@function o-add-unicode-support-font($font, $index: false) { + @if $index == false { + $index: length($font); + } + + $-with-support-font: (); + @for $i from 1 through length($font) { + @if $i == $index { + $-with-support-font: append($-with-support-font, 'Odoo Unicode Support Noto', $separator: comma); + } + $-with-support-font: append($-with-support-font, nth($font, $i), $separator: comma); + } + + @return $-with-support-font; +} + +// Function to remove all null values of a map +@function o-map-omit($map) { + $-map: (); + @each $key, $value in $map { + @if $value != null { + $-map: map-merge($-map, ( + $key: $value, + )); + } + } + @return $-map; +} + +// Function to swap two values in a list +@function o-swap($list, $i, $j) { + $tmp: nth($list, $i); + $list: set-nth($list, $i, nth($list, $j)); + @return set-nth($list, $j, $tmp); +} + +// Function to get an element of a list with a default value in case the index +// is out-of-bounds; also return that value if the retrieved value is null. +@function o-safe-nth($list, $index, $default: null) { + $value: if($index > 0 and $index <= length($list), nth($list, $index), null); + @return if($value != null, $value, $default); +} + +// Function to get an element of a map with a default value in case the key +// does not exist; also return that value if the retrieved value is null. +@function o-safe-get($map, $key, $default: null) { + $value: map-get($map, $key); + @return if($value != null, $value, $default); +} + +// ------- Kanban grouped mixins ------- +@mixin o-kanban-icon($base-opacity: 0.5) { + display: block; + text-align: center; + color: $o-main-text-color; + font-size: $font-size-sm; + cursor: pointer; + @include o-hover-opacity($base-opacity); +} +@mixin o-kanban-tag-color { + @for $size from 1 through length($o-colors) { + // Note: the first color is supposed to be invisible if there is a color + // field but it is used as a default color when there is no color field + &.o_tag_color_#{$size - 1} span { + background-color: nth($o-colors, $size); + } + } +} +@mixin o-kanban-record-color { + @for $size from 2 through length($o-colors) { + // Note: the first color is not defined as it is the 'no color' for kanban + .oe_kanban_color_#{$size - 1}::after { + background-color: nth($o-colors, $size); + } + } +} +@mixin o-kanban-slim-col { + position: relative; + flex: 0 0 auto; + margin: 0; + padding: 0 floor($o-kanban-group-padding * 0.7); + cursor: pointer; +} +@mixin o-kanban-header-title { + display: flex; + align-items: center; + height: $o-kanban-header-title-height; + line-height: 2.2; + color: $headings-color; +} +@mixin o-kanban-v-title { + @include o-position-absolute($o-kanban-inside-vgutter * 2, $left: floor(-$o-kanban-inside-vgutter * 1.2)); + transform-origin: left bottom 0; + transform: rotate(90deg); + overflow: visible; + white-space: nowrap; + font-size: 15px; +} + +// ------- Kanban records mixins ------- +@mixin o-kanban-record-title($font-size) { + color: $headings-color; + font-size: $font-size; + font-weight: 500; + margin-bottom: 0; + margin-top: 0; +} +@mixin o-kanban-dropdown($padding-base: $o-kanban-inside-vgutter) { + padding: $padding-base/2 $padding-base; + border: none; + border-left: 1px solid transparent; + vertical-align: top; + color: $body-color; + + &:hover { + color: $headings-color; + } + &:focus, &:active, &:focus:active { + outline: none; + } +} +@mixin o-kanban-dropdown-open { + position: relative; + background: white; + border-color: gray('400'); + z-index: $zindex-dropdown + 1; +} +@mixin o-kanban-dropdown-menu { + @include o-position-absolute($right: -1px); + margin-top: -1px; + border-color: gray('400'); +} +@mixin o-kanban-colorpicker { + max-width: 150px; + padding: 3px ($o-dropdown-hpadding - $o-kanban-inner-hmargin) 3px $o-dropdown-hpadding; + + > li { + display: inline-block; + margin: $o-kanban-inner-hmargin $o-kanban-inner-hmargin 0 0; + border: 1px solid white; + box-shadow: 0 0 0 1px gray('300'); + + > a { + display: block; + + &::after { + content: ""; + display: block; + width: 20px; + height: 15px; + } + } + + // No Color + &:first-child > a { + position: relative; + &::before { + content: ""; + @include o-position-absolute(-2px, $left: 10px); + display: block; + width: 1px; + height: 20px; + transform: rotate(45deg); + background-color: red; + } + &::after { + background-color: white; + } + } + } +} + +// Emulate dropdown links +@mixin o-kanban-dashboard-dropdown-link($link-padding-gap: $o-dropdown-hpadding) { + padding: 0; + + > a { + margin: auto auto auto (-$link-padding-gap); + padding: 3px $link-padding-gap; + color: $body-color; + display: block; + + &:hover { + background-color: gray('300'); + color: $headings-color; + } + } + &:last-child { + margin-bottom: 5px; + } +} + +// No content helper +@mixin o-nocontent-empty { + pointer-events: auto; + max-width: 650px; + margin: auto; + padding: 15px; + z-index: 1000; + text-align: center; + color: $o-tooltip-text-color; + font-size: 115%; + + > p:first-of-type { + margin-top: 0; + color: $o-tooltip-title-text-color; + font-weight: bold; + font-size: 125%; + } + + a { + cursor: pointer; + } +} + +%o-nocontent-init-image { + content: ""; + display: block; + margin: auto; + background-size: cover; +} + +%o-nocontent-empty-document { + @extend %o-nocontent-init-image; + @include size(120px, 80px); + margin-top: 30px; + margin-bottom: 30px; + background: transparent url(/web/static/src/img/empty_folder.svg) no-repeat center; +} |
