summaryrefslogtreecommitdiff
path: root/addons/web/static/src/scss/utils.scss
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/scss/utils.scss
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/static/src/scss/utils.scss')
-rw-r--r--addons/web/static/src/scss/utils.scss437
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;
+}