Initial commit: Core packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:45 +02:00
commit 12c29a983b
9512 changed files with 8379910 additions and 0 deletions

View file

@ -0,0 +1,279 @@
///
/// This file is a copy of the bootstrap _variables.scss file where all the
/// left-untouched variables definition have been removed.
///
//
// Color system
//
//Restore BS4 Colors
$blue: #007bff !default;
$pink: #e83e8c !default;
$green: #28a745 !default;
$cyan: #17a2b8 !default;
//End Restore BS4 Colors
// All of those are BS default
$white: $o-white !default;
$gray-100: $o-gray-100 !default;
$gray-200: $o-gray-200 !default;
$gray-300: $o-gray-300 !default;
$gray-400: $o-gray-400 !default;
$gray-500: $o-gray-500 !default;
$gray-600: $o-gray-600 !default;
$gray-700: $o-gray-700 !default;
$gray-800: $o-gray-800 !default;
$gray-900: $o-gray-900 !default;
$black: $o-black !default;
$primary: $o-brand-primary !default;
$secondary: $white !default;
$dark: $o-gray-900 !default;
$success: $o-success !default;
$info: $o-info !default;
$warning: $o-warning !default;
$danger: $o-danger !default;
$theme-colors: () !default;
$theme-colors: map-merge(
(
"odoo": $o-brand-odoo,
),
$theme-colors
);
// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.
// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
$min-contrast-ratio: 3 !default;
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-smooth-scroll: false !default;
// Prefix for :root CSS variables
$variable-prefix: '' !default;
// Restore negative margins disabled in BS5 by default
$enable-negative-margins: true !default;
// Enable CSS Grid classes
$enable-cssgrid: true !default;
// Spacing
$spacer: 1rem !default;
// Body
//
// Settings for the `<body>` element.
$body-bg: $o-webclient-background-color !default;
$body-color: $o-main-text-color !default;
// Links
//
// Style anchor elements.
$link-color: $o-main-link-color !default;
$link-decoration: none !default;
$link-hover-decoration: none !default;
$link-shade-percentage: 15% !default;
// Muted
//
// Style .text-muted elements
$text-muted: $o-main-color-muted !default;
// Grid columns
//
// Set the number of columns and specify the width of the gutters.
$grid-gutter-width: $o-horizontal-padding * 2 !default;
// Components
//
// Define common padding and border radius sizes and more.
$border-color: $o-border-color!default;
$border-radius: $o-border-radius !default;
$border-radius-sm: $o-border-radius-sm !default;
$border-radius-lg: $o-border-radius-lg !default;
$border-color: $o-gray-300 !default;
$component-active-color: $o-brand-primary !default;
$component-active-bg: $gray-200 !default;
$caret-width: 4px !default;
// Typography
//
// Font, line-height, and color for body text, headings, and more.
// Desired weights, not necessarily matching the final result on screen.
// Check primary_variables.scss for more info.
$font-weight-normal: $o-font-weight-normal !default;
$font-weight-bold: $o-font-weight-medium !default;
$font-family-sans-serif: $o-font-family-sans-serif !default;
$font-size-base: $o-font-size-base !default;
$line-height-base: $o-line-height-base !default;
$h1-font-size: $font-size-base * 2.0 !default;
$h2-font-size: $font-size-base * 1.5 !default;
$h3-font-size: $font-size-base * 1.3 !default;
$h4-font-size: $font-size-base * 1.2 !default;
$h5-font-size: $font-size-base * 1.1 !default;
$headings-font-family: $o-headings-font-family !default;
$headings-font-weight: $font-weight-bold !default;
$headings-color: $o-main-headings-color !default;
// Tables
//
// Customizes the `.table` component with basic values, each used across all table variations.
$table-striped-color: inherit !default;
$table-striped-bg-factor: .01 !default;
$table-hover-bg-factor: .055 !default;
$table-border-color: $gray-200 !default;
$table-group-separator-color: $gray-200 !default;
$table-cell-padding-x: .75rem !default;
$table-cell-padding-y: .75rem !default;
$table-cell-padding-x-sm: .3rem !default;
$table-cell-padding-y-sm: .5rem !default;
$table-striped-order: even !default;
$table-active-bg-factor: .05 !default;
$table-active-color: $headings-color !default;
$table-th-font-weight: $headings-font-weight !default;
// Buttons
//
$btn-font-weight: $font-weight-bold !default;
$btn-disabled-opacity: $o-opacity-disabled !default;
$btn-border-radius-lg: $border-radius !default;
// Dropdowns
//
// Dropdown menu container and contents.
$dropdown-border-color: $gray-300 !default;
$dropdown-link-color: $o-main-text-color !default;
$dropdown-link-hover-color: $gray-900 !default;
$dropdown-link-hover-bg: rgba($black, 0.08) !default;
$dropdown-link-active-color: $gray-900 !default;
$dropdown-link-active-bg: transparent !default;
$dropdown-link-disabled-color: $o-main-color-muted !default;
$dropdown-item-padding-y: $o-dropdown-vpadding !default;
$dropdown-item-padding-x: $o-dropdown-hpadding !default;
// List group
$list-group-active-color: $o-list-group-active-color !default;
$list-group-active-bg: $o-list-group-active-bg !default;
$list-group-action-hover-color: $gray-900 !default;
// Z-index master list
// Change the z-index of the modal-backdrop elements to be equal to the
// modal elements' ones. Bootstrap does not support multi-modals, and without
// this rule all the modal-backdrops are below all the opened modals.
// Indeed, bootstrap forces them to a lower z-index as the modal-backdrop
// element (unique in their supported cases) might be put after the modal
// element (if the modal is already in the DOM, hidden, then opened). This
// cannot happen in odoo though as modals are not hidden but removed from
// the DOM and are always put at the end of the body when opened.
//
// TODO the following code was disabled because it is saas-incompatible
//
// $zindex-modal-backdrop: $zindex-modal;
// Navbar
$navbar-padding-x: $spacer !default;
// Navs
$nav-tabs-link-active-bg: $white !default;
$nav-pills-border-radius: 0 !default;
$nav-pills-link-active-color: $white !default;
$nav-pills-link-active-bg: $o-brand-primary !default;
// Popovers
$popover-border-radius: $border-radius !default;
// Toasts
$toast-max-width: 320px !default;
$toast-padding-x: 1.5rem !default;
$toast-padding-y: 0.5rem !default;
$toast-font-size: $font-size-base !default;
$toast-background-color: rgba($white, .7) !default;
$toast-header-background-color: $toast-background-color !default;
// Modals
// Padding applied to the modal body
$modal-inner-padding: $o-horizontal-padding !default;
$modal-footer-margin-between: 1px !default;
$modal-lg: $o-modal-lg !default;
$modal-md: $o-modal-md !default;
$modal-content-border-radius: $border-radius !default;
$modal-scale-transform: none !default;
// Breadcrumbs
$breadcrumb-padding-y: 0 !default;
$breadcrumb-padding-x: 0 !default;
$breadcrumb-margin-bottom: 0 !default;
$breadcrumb-bg: $o-control-panel-background-color !default;
$breadcrumb-item-padding: .2em !default;
// Code
$code-color: $o-main-code-color!default;
// User input typically entered via keyboard
$kbd-color: $o-gray-700 !default;
$kbd-bg: $o-gray-100 !default;
$kbd-box-shadow: 0px 1px 1px rgba($o-black, 0.2), inset 0px -1px 1px 1px rgba($o-gray-200, 0.8), inset 0px 2px 0px 0px rgba($o-white, 0.8) !default;
// Input
$input-bg: transparent !default;
$input-focus-border-color: $o-brand-primary !default;
$form-check-input-checked-color: $o-brand-lightsecondary !default;
$form-check-input-checked-border-color: $o-brand-primary !default;
$form-check-input-checked-bg-color: $o-brand-primary !default;
$form-switch-checked-color: $o-white !default;
$form-range-thumb-bg: $primary !default;
// Badge
$badge-color: inherit !default;
$badge-padding-y: 0.25em !default;
$badge-padding-x: 0.4em !default;
// Placeholder color
$input-placeholder-color: $gray-600 !default;
// Card
$card-spacer-y: $spacer !default; // BS Default
$card-cap-padding-y: $card-spacer-y !default;

View file

@ -0,0 +1,80 @@
// Color system
//
// Note: all of these variables use BS default values, will be eventually
// overridden by website and are declared here just to allow components
// customization (eg. form-range)
// gray-color-variables
$white: #fff !default;
$gray-400: #ced4da !default;
// color-variables
$blue: #0d6efd !default;
// theme-color-variables
$primary: $blue !default;
// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.
// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
$min-contrast-ratio: $o-frontend-min-contrast-ratio !default;
// Body
$body-bg: $white !default; // BS Default
// Components
//
// Define common padding and border radius sizes and more.
$border-width: 1px !default; // BS Default
// Fonts
//
// Font, line-height, and color for body text, headings, and more.
$font-family-sans-serif: o-add-unicode-support-font($o-system-fonts) !default;
$font-size-base: (14 / 16) * 1rem !default;
// Inherit color for blockquote-footer, use text-muted on top of it if you want
// a muted one. This is defined here to be consistent in the whole frontend, as
// when used with background classes, it should not be forced to a gray color.
$blockquote-small-color: inherit !default;
// Link
$link-decoration: none !default;
// Forms
$input-transition: background-color .05s ease-in-out, border-color .05s ease-in-out, box-shadow .05s ease-in-out !default;
$form-check-input-border: $border-width solid $gray-400 !default;
$form-check-input-border-radius: 0 !default;
$form-range-track-height: .1rem !default;
$form-range-thumb-border: $border-width solid $primary !default;
$form-range-thumb-bg: $body-bg !default;
$form-range-thumb-active-bg: $primary !default;
// Figures
// Inherit color for figure-caption, use text-muted on top of it if you want
// a muted one. This is defined here to be consistent in the whole frontend, as
// when used with background classes, it should not be forced to a gray color.
$figure-caption-color: inherit !default;
// Accordion
$accordion-border-width: 0 !default;
$accordion-button-color: inherit !default;
$accordion-button-active-bg: inherit !default;
$accordion-button-active-color: inherit !default;
$accordion-icon-color: $accordion-button-color !default;
$accordion-icon-width: 1rem !default;
$accordion-icon-transform: rotate(0deg) !default;
$accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path transform='#{rotate(90, 8, 8)}' fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
// Offcanvas
$offcanvas-border-width: 0 !default;
$offcanvas-backdrop-opacity: .3 !default;

View file

@ -0,0 +1,340 @@
///
/// This file regroups the CSS rules made to fix/extend bootstrap in all places
/// where it is used in Odoo (backend / frontend / reports / ...)
///
.alert {
// Alerts are block elements with relative positioning.
// They would go over floating elements, which is never what we want.
clear: both;
}
// Extend bootstrap to create background and text utilities for gray colors too
// Note: the card-body rule below needs those grays utilities to be defined
// before so that the related o-bg-color text-muted rules work.
@each $color, $value in $grays {
@include bg-variant(".bg-#{$color}", $value);
@include text-emphasis-variant(".text-#{$color}", $value);
}
// Restore text-X from BS4 that use text-emphasis-variant
@each $color, $value in $theme-colors {
@include text-emphasis-variant(".text-#{$color}", $value);
}
.card-body {
// BS4 colored cards do not have a very popular design. This will reset them
// to a BS3-like one: only the header and footer are colored and the body
// will use the color of a default card background with a light opacity.
// Limitation: bg-* utilities cannot be used on card-body elements anymore.
@include o-bg-color(rgba($card-bg, $o-card-body-bg-opacity));
&:first-child {
@include border-top-radius($card-inner-border-radius);
}
&:last-child {
@include border-bottom-radius($card-inner-border-radius);
}
&.row {
// The 'row' class should not be used on a 'card-body' element but if
// it is done, our custom bg color would overflow the card. As a fix
// for those cases (normally only one at the time this fix is made),
// remove the background color.
// TODO remove me in master.
background-color: transparent !important;
}
.table-striped > tbody > tr:nth-of-type(odd) > * {
// As the 'card-body' colors are established using '$card-bg' and
// '$o-card-body-bg-opacity', we shouldn't let elements inside
// '.table-striped' take their color from the body as they currently do.
// This leads to even lines having a color that contrasts with
// '$card-bg', and odd lines contrasting with '$body-bg'. This becomes
// problematic when one is light and the other is dark.
color: inherit;
}
}
.accordion {
.collapsing, .collapse.show {
> .card-body:first-child {
// Above background color would overflow on the card-header border
// without this
margin-top: $card-border-width;
}
}
}
.toast-header {
background-clip: border-box;
}
.toast-body {
// Same as card-body, see explanation above
@include o-bg-color(opacify($toast-background-color, 0.08));
}
// Modify modals so that their scrollable element is the modal-body (except in
// mobile).
// TODO: should be replaced by .modal-dialog-scrollable class
@include media-breakpoint-up(sm) {
:not(.s_popup) > .modal {
.modal-dialog {
height: 100%;
padding: $modal-dialog-margin-y-sm-up 0;
margin: 0 auto;
}
.modal-content {
max-height: 100%;
}
.modal-header, .modal-footer {
flex: 0 0 auto;
}
.modal-body {
overflow: auto;
min-height: 0;
}
}
}
// Do not display the backdrop element added by bootstrap in the body and add a
// background on the modal to keep the same effect. The bootstrap backdrop was
// probably useful for compatibility with <IE9 but is no longer needed. This
// also avoids z-index issues because modals could be opened in an element
// (e.g. the website #wrapwrap) whose stacking context is different of the body
// one (where the backdrop is opened). This would make the backdrop appears on
// top of the modal.
.modal-backdrop {
display: none;
}
.modal:not([data-bs-backdrop="false"]) {
background-color: rgba($modal-backdrop-bg, $modal-backdrop-opacity);
}
// Force field label pointer to cursor
.form-check, .form-select {
@include o-field-pointer();
}
// Disable RTL for the dropdown position
.dropdown-menu {
&[x-placement^="top"],
&[x-placement^="right"],
&[x-placement^="bottom"],
&[x-placement^="left"] {
/*rtl:ignore*/
right: auto;
}
}
// Disable RTL for the popover position
.popover {
right: auto#{"/*rtl:ignore*/"};
}
// Review $link-decoration behavior
@if $link-decoration and $link-decoration != none {
.btn:not(.btn-link), .nav-link, .dropdown-item, .page-link, .breadcrumb-item > a, .badge, .fa {
&, &:hover, &:focus {
text-decoration: none;
}
}
}
// Generating bootstrap color buttons was disabled (see import_bootstrap.scss).
// We do it ourself here with a tweak: we introduce btn-fill-* (working as the
// normal btn-* classes (in opposition to btn-outline-* classes). We then map
// the btn-* classes to either btn-fill-* or btn-outline-* classes depending on
// the configuration. We also allow to define a border-color different than the
// background color.
$o-btn-bg-colors: () !default;
$o-btn-border-colors: () !default;
@each $color, $value in $theme-colors {
$-bg-color: map-get($o-btn-bg-colors, $color) or $value;
$-border-color: map-get($o-btn-border-colors, $color) or $-bg-color;
.btn-fill-#{$color} {
@include button-variant($-bg-color, $-border-color);
}
}
@each $color, $value in $theme-colors {
$-bg-color: map-get($o-btn-bg-colors, $color) or $value;
$-border-color: map-get($o-btn-border-colors, $color) or $-bg-color;
.btn-outline-#{$color} {
@include button-outline-variant($-border-color);
}
}
$o-btn-outline-defaults: () !default;
@each $color, $value in $theme-colors {
.btn-#{$color} {
@if index($o-btn-outline-defaults, $color) {
@extend .btn-outline-#{$color};
} @else {
@extend .btn-fill-#{$color};
}
}
}
// Compensate navbar brand padding if no visible border
@if alpha($navbar-dark-toggler-border-color) < 0.001 {
.navbar-dark .navbar-toggler {
padding-left: 0;
padding-right: 0;
}
}
@if alpha($navbar-light-toggler-border-color) < 0.001 {
.navbar-light .navbar-toggler {
padding-left: 0;
padding-right: 0;
}
}
// Review bootstrap navbar to work with different nav styles
$o-navbar-nav-pills-link-padding-x: $nav-link-padding-x !default;
$o-navbar-nav-pills-link-border-radius: $nav-pills-border-radius !default;
.navbar-nav.nav-pills .nav-link {
// The rules is needed so that the padding is not reset to 0 in mobile.
// Also use default nav-link paddings instead of navbar ones.
padding-right: $o-navbar-nav-pills-link-padding-x;
padding-left: $o-navbar-nav-pills-link-padding-x;
@if $o-navbar-nav-pills-link-border-radius != $nav-pills-border-radius {
@include border-radius($o-navbar-nav-pills-link-border-radius);
}
}
.carousel-control-next .visually-hidden {
left: 50%; // Avoid horizontal scrollbar in Chrome
}
// Modal
.modal-content {
// If the text color of the body (used for the text color in modals) is not
// visible due to insufficient contrast with the modal background, we adjust
// the text color in the modal using the following code. For example, if the
// user sets a black background for its website and the text color of the
// body is white, the text will not be visible on modals with a white
// background.
@if $modal-content-color == null {
color: adjust-color-to-background($body-color, $modal-content-bg);
.table-striped > tbody > tr:nth-of-type(odd) > * {
// When the website background is dark (resulting in light-colored
// body text), the text color of the odd rows of striped tables
// matches the body text color. Consequently, it becomes invisible
// on the light background of a modal. To address this, we inherit
// the text color from 'modal-content,' which is also tied to the
// body text color but adapts appropriately within modals (see
// above).
color: inherit;
}
// This prevents these elements from taking their colors from the body
// inside a modal.
// We need to exclude 'oe_structure' that are areas containing editable
// snippets. Indeed, this code was added in a stable version, and we are
// doing everything not to alter the content edited by users. For
// example in Website, without this 'not', the 's_website_form' snippets
// with a black background in modals and on websites with a black
// background would have their input background changing from black to
// white.
// TODO: In Master, find a more consistent way to define the background
// color of 's_website_form' snippet inputs inside a modal.
&:where(:not(.oe_structure)) {
@if ($input-bg == $body-bg) and ($input-color == $body-color) {
.form-control {
background-color: $modal-content-bg;
color: inherit;
}
}
@if ($form-select-bg == $body-bg) and ($form-select-color == $body-color) {
.form-select {
background-color: $modal-content-bg;
color: inherit;
}
}
@if $form-check-input-bg == $body-bg {
.form-check-input:not(:checked) {
background-color: $modal-content-bg;
}
}
}
}
.text-muted {
color: adjust-color-to-background($text-muted, $modal-content-bg, mute-color($color-contrast-light), mute-color($color-contrast-dark)) !important;
}
}
// Popover
.popover {
// The popover can have a different background color than that of the body.
// Here, we adjust the text color of the popover in case the body color
// (used by default for the text color of popovers) is not visible inside a
// popover due to a lack of contrast (e.g. on a website with a dark
// background).
@if $popover-header-color == null {
.popover-header {
color: adjust-color-to-background($body-color, $popover-header-bg);
}
}
@if $popover-body-color == $body-color {
.popover-body {
color: adjust-color-to-background($body-color, $popover-bg);
}
}
}
$-color-for-gray-200-bg: adjust-color-to-background($body-color, $gray-200);
// Input group text (e.g. Date time picker)
.input-group-text {
// Adapt only if the variables have their default values.
@if ($input-group-addon-bg == $gray-200) and ($input-group-addon-color == $body-color) {
color: $-color-for-gray-200-bg;
}
}
// File upload button
.form-control::file-selector-button {
@if ($form-file-button-bg == $gray-200) and ($form-file-button-color == $body-color) {
color: $-color-for-gray-200-bg;
}
}
// offcanvas
.offcanvas {
@if $offcanvas-color == null {
color: adjust-color-to-background($body-color, $offcanvas-bg-color);
@if $form-check-input-bg == $body-bg {
.form-check-input:where(:not(:checked)) {
background-color: $offcanvas-bg-color;
}
}
@if $form-range-thumb-bg == $body-bg {
.form-range{
&::-webkit-slider-thumb {
&:where(:not(:active)) {
background-color: $offcanvas-bg-color;
}
}
&::-moz-range-thumb {
&:where(:not(:active)) {
background-color: $offcanvas-bg-color;
}
}
}
}
}
}
// Button within input-group (e.g., "search bar")
.input-group {
.btn:first-child, .btn:last-child {
@include border-radius($input-border-radius, 0);
}
}
// Dropdown
.dropdown .dropdown-menu {
.text-muted {
color: adjust-color-to-background($text-muted, $dropdown-bg, mute-color($color-contrast-light), mute-color($color-contrast-dark)) !important;
}
}

View file

@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// Bootstrap Mixins and Functions Extensions
// Those will affect the way bootstrap is generated wherever bootstrap is used
//------------------------------------------------------------------------------
// This variable must be defined here instead of bootstrap overridden files
// otherwise we will have deprecation messages for assets_common generation
$enable-deprecation-messages: false !default;
// Override color-contrast function to handle the alpha component of colors
@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio, $main-background: $body-bg) {
$real-color: opaque($main-background, $background);
$foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
$max-ratio: 0;
$max-ratio-color: null;
@each $color in $foregrounds {
$contrast-ratio: contrast-ratio($real-color, $color);
@if $contrast-ratio > $min-contrast-ratio {
@return $color;
} @else if $contrast-ratio > $max-ratio {
$max-ratio: $contrast-ratio;
$max-ratio-color: $color;
}
}
@warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$real-color} (mix of given color and background)...";
@return $max-ratio-color;
}
@function mute-color($color) {
@return scale-color($color, $alpha: -30%);
}
// This placeholder regroups the rules that will apply on all elements with a
// bg-* class (see o-bg-color, bg-variant). The optimized-css way would be to
// have a common class for them all.
%o-bg-color-component-color-reset {
h1, h2, h3, h4, h5, h6 {
color: inherit;
}
}
$o-yiq-min-opacity-threshold: 0.3 !default;
$o-color-extras-nesting-selector: '&' !default;
@mixin o-bg-color($color, $text-color: null, $with-extras: true, $important: true, $yiq-min-opacity-threshold: $o-yiq-min-opacity-threshold, $background: $body-bg, $nesting-selector: $o-color-extras-nesting-selector) {
@if ($color) {
$-yiq-threshold-met: alpha($color) > $yiq-min-opacity-threshold;
$-yiq-color: if($text-color, $text-color, if($-yiq-threshold-met, color-contrast($color, $main-background: $background), null));
background-color: $color#{if($important, ' !important', '')};
color: $-yiq-color; // not important so that text utilities still work
@if $with-extras and $-yiq-threshold-met {
#{$nesting-selector} {
@extend %o-bg-color-component-color-reset;
.text-muted {
// Always important since the basic BS rule is important
color: mute-color($-yiq-color) !important;
}
}
}
}
}
// Override background utilities so that they come with a default contrasted
// color (especially useful in the frontend editor for example). Also modifies
// the way .text-muted elements are rendered in those environments.
@mixin bg-variant($parent, $color, $text-color: null) {
#{$parent} {
@include o-bg-color($color, $text-color);
}
a#{$parent},
button#{$parent} {
&:hover, &:focus {
@include o-bg-color(darken($color, 10%), $text-color, false);
}
}
}
@mixin bg-gradient-variant($parent, $color, $text-color: null) {
#{$parent} {
@include o-bg-color($color, $text-color);
background-image: linear-gradient(180deg, mix($body-bg, $color, 15%), $color) !important;
background-repeat: repeat-x !important;
}
}

View file

@ -0,0 +1,63 @@
//==============================================================================
// Bootstrap Mixins and Functions Extensions
// Those will affect how bootstrap is generated in the backend only
//==============================================================================
// Function used to retrive a text color prioritizing our finetuned ones.
//------------------------------------------------------------------------------
@function o-text-color($key) {
$-all-text-colors: map-merge($theme-colors, $o-theme-text-colors);
@if map-has-key($-all-text-colors, $key) {
@return map-get($-all-text-colors, $key);
}
@return false;
}
// Customize boostrap 'text-emphasis-variant' mixin allowing text colors other
// than the '$theme-colors' ones.
// It prioritizes the '$o-theme-text-colors' map and fallbacks to default.
//------------------------------------------------------------------------------
@mixin text-emphasis-variant($parent, $color) {
$-hover: $link-shade-percentage;
// Check for the color name in '$theme-colors'.
$color-name: null;
@each $-name, $-value in $theme-colors {
@if $-value == $color {
$color-name: $-name;
}
}
// Retrive the finetuned text color or fallback to default.
$color-value: o-text-color($color-name) or $color;
#{$parent} {
color: $color-value!important;
}
a#{$parent}, button#{$parent} {
&:hover, &:focus {
color: darken($color-value, $-hover) !important;
}
}
// Handle a very specific exception for the 'fa-circle' class when used in
// conjunction with contextual classes to achieve "status" graphical elements.
// Ideally any '.fa-circle.text-x'occurrency should be replaced with the
// 'o_status' component that uses background-color rather than text-color.
@if map-has-key($o-theme-text-colors, $color-name) {
#{$parent}.fa-circle {
color: $color!important;
}
a#{$parent}.fa-circle, button#{$parent}.fa-circle {
&:hover, &:focus {
color: darken($color, $-hover) !important;
}
}
}
}

View file

@ -0,0 +1,14 @@
// Backport from BS 5.2
// TODO remove me when migrate to new Bootstrap 5.2 +
$prefix: '' !default;
$theme-colors: () !default;
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
@each $color, $value in $theme-colors {
$color-rgb: to-rgb($value);
.text-bg-#{$color} {
color: color-contrast($value) !important;
background-color: RGBA($color-rgb, var(--#{$prefix}bg-opacity, 1)) !important;
}
}

View file

@ -0,0 +1,108 @@
/*!
* Copied from Bootstrap v5.1.3 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
// This file is importing bootstrap. While a simple "import "bootstrap";"
// should be enough, this does not allow overridding mixins/functions.
// Overridding those is necessary for some of our need and allow to generate
// more efficient CSS than adding more rules. This file instead copies the
// content of the "bootstrap.scss" files but do not import functions, variables
// and mixins which will be handled "by hand" in _assets_helpers.
// scss-docs-start import-stack
// Configuration
// @import "functions";
// @import "variables";
// @import "mixins";
@import "utilities";
// Layout & components
@import "root";
@import "reboot";
@import "type";
@import "images";
@import "containers";
@import "grid";
// Bootstrap tables can basically be customized with the `$table-bg` and
// `$table-color` variables. The problem is that, by default, BS5 defines them
// so that the background-color is null (so transparent: displaying the
// background-color of its ancestors) but the color is forced to the body color
// (by default: white). This is a problem as soon as the ancestors background
// colors are a color close to the body text color: the text becomes invisible.
// For instance: in website,
// - Set a body background color to black, the body text will automatically
// become white.
// - Add a table in a snippet: still ok, the text in the table is white over
// the black body (the table being transparent).
// - Then set the snippet background to white -> the table text will still be
// white... but now over a white background.
//
// TODO this should be reviewed in master: it should be ok to set the variable
// $table-color to `null` thus letting the table be transparent and have the
// same text color as its parent. But in stable, changing a color variable to
// `null` could break customizations relying on the fact this is a set color. It
// would also not make sense if the user set up a `$table-bg` value going well
// with table text forced to the body color.
// Instead, here, in the very specific case we have a transparent table bg and
// table color equal to the body color, we temporarily unset the table color
// variable for the duration of the bootstrap table rules.
// Note: we cannot create a rule in an "Odoo file" to fix this as unsetting the
// color for the `.table` rule would also unset the case of a `.table.bg-XXX`
// where we still want `.bg-XXX` to force the color.
$-tmp: $table-color;
$-tmp-hover: $table-hover-color;
@if ($table-bg == null or alpha($table-bg) < 0.01) and $table-color == $body-color {
@if $table-hover-color == $table-color {
$table-hover-color: null;
}
$table-color: null;
}
@import "tables";
$table-color: $-tmp;
$table-hover-color: $-tmp-hover;
@import "forms";
// Small hack in bootstrap (see bootstrap_review.scss): prevent it to generate
// primary, secondary, and other color/outline classes by itself to be able to
// do it ourself properly.
$-tmp: $theme-colors;
$theme-colors: ();
@import "buttons";
$theme-colors: $-tmp;
@import "transitions";
@import "dropdown";
@import "button-group";
@import "nav";
@import "navbar";
@import "card";
@import "accordion";
@import "breadcrumb";
@import "pagination";
@import "badge";
@import "alert";
@import "progress";
@import "list-group";
@import "close";
@import "toasts";
@import "modal";
@import "tooltip";
@import "popover";
@import "carousel";
@import "spinners";
@import "offcanvas";
@import "placeholders";
// Helpers
@import "helpers";
// Utilities
// Moved into bundle after bs_utilities_custom.scss file to allow to extend
// the utilities
// @import "utilities/api";
// scss-docs-end import-stack

View file

@ -0,0 +1,22 @@
// For each breakpoint, define the maximum width of the container in a media query
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
@each $breakpoint, $container-max-width in $max-widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
max-width: $container-max-width;
}
}
}
//addons/web/static/lib/bootstrap-4/scss/mixins/_text-emphasis.scss
@mixin text-emphasis-variant($parent, $color) {
#{$parent} {
color: $color !important;
}
@if $link-shade-percentage != 0 {
a#{$parent} {
&:hover, &:focus {
color: darken($color, $link-shade-percentage) !important;
}
}
}
}

View file

@ -0,0 +1,82 @@
// Hack for Bootstrap 5
// In Bootstrap 4 these variables was used with map-merge()
// In Bootstrap 5 these variables has set only if they don't exist before
// PS: Another fix will be to reorder all bundle to follow Bootstrap documentation and do another
// logic that wasn't use before
// Ref:
// https://getbootstrap.com/docs/5.1/customize/sass/#colors
// Need to be include before web/static/lib/bootstrap/scss/_variables.scss
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-600: #6c757d !default;
$gray-700: #495057 !default;
$gray-800: #343a40 !default;
$gray-900: #212529 !default;
$black: #000 !default;
$grays: () !default;
$grays: map-merge((
"100": $gray-100,
"200": $gray-200,
"300": $gray-300,
"400": $gray-400,
"500": $gray-500,
"600": $gray-600,
"700": $gray-700,
"800": $gray-800,
"900": $gray-900
), $grays);
$blue: #0d6efd !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #d63384 !default;
$red: #dc3545 !default;
$orange: #fd7e14 !default;
$yellow: #ffc107 !default;
$green: #198754 !default;
$teal: #20c997 !default;
$cyan: #0dcaf0 !default;
$colors: () !default;
$colors: map-merge((
"blue": $blue,
"indigo": $indigo,
"purple": $purple,
"pink": $pink,
"red": $red,
"orange": $orange,
"yellow": $yellow,
"green": $green,
"teal": $teal,
"cyan": $cyan,
"white": $white,
"gray": $gray-600,
"gray-dark": $gray-800
), $colors);
$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
$theme-colors: () !default;
$theme-colors: map-merge((
"primary": $primary,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
), $theme-colors);

View file

@ -0,0 +1,206 @@
///
/// This file regroups the variables that style odoo components.
/// They are available in every asset bundle.
///
// Contrast ratio
$o-frontend-min-contrast-ratio: 2.9 !default;
// Color-scheme
$o-webclient-color-scheme: bright !default;
// Font sizes
$o-root-font-size: 12px !default;
$o-font-size-base: 13rem * (1px / $o-root-font-size) !default;
$o-font-size-base-touch: 15px !default;
$o-line-height-base: 1.5 !default; // This is BS default
// Global sans-serif fonts stack, defined here as we need to process
// it before actually using it (to add more unicode support with the special
// Odoo font for example). Adding unicode support is not done directly here as
// this font can be used by the website where the unicode support is already
// automatically added.
$o-system-fonts: (-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Ubuntu, "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji") !default;
// Font weights
// Caution: These values represent the desired font weights, but they may vary
// depending on the user's operating system.
// Because we rely on system fonts, the browser will interpret these values
// based on the available fonts on the user's device.
// If the exact font weight is unavailable, the browser will attempt to assign
// a suitable weight using the fallowing fallback scheme.
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#fallback_weights
$o-font-weight-normal: 400 !default;
$o-font-weight-medium: 500 !default;
$o-font-weight-bold: 700 !default;
$o-font-weight-extrabold: 800 !default;
// Colors
// This is BS default
$o-white: #FFFFFF !default;
$o-black: #000000 !default;
$o-gray-100: #f8f9fa !default;
$o-gray-200: #e9ecef !default;
$o-gray-300: #dee2e6 !default;
$o-gray-400: #ced4da !default;
$o-gray-500: #adb5bd !default;
$o-gray-600: #6c757d !default;
$o-gray-700: #495057 !default;
$o-gray-800: #343a40 !default;
$o-gray-900: #212529 !default;
$o-community-color: #71639e !default;
$o-enterprise-color: #714B67 !default;
$o-enterprise-primary-color: #017e84 !default;
$o-brand-odoo: $o-community-color !default;
$o-brand-primary: $o-community-color !default;
$o-brand-secondary: #8f8f8f !default;
$o-brand-lightsecondary: $o-gray-100 !default;
$o-success: #28a745 !default;
$o-info: #17a2b8 !default;
$o-warning: #ffac00 !default;
$o-danger: #dc3545 !default;
// Fine-tune contextual text colors.
$o-theme-text-colors: (
"success": #008818,
"info": #0180a5,
"warning": #9a6b01,
"danger": #d23f3a,
"odoo": $o-brand-odoo,
)!default;
$o-opacity-disabled: .5 !default;
$o-opacity-muted: .76 !default;
$o-font-family-sans-serif: o-add-unicode-support-font($o-system-fonts) !default;
$o-font-family-monospace: o-add-unicode-support-font((SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace)) !default;
$o-headings-font-family: o-add-unicode-support-font(("SF Pro Display", $o-system-fonts)) !default;
$o-main-text-color: $o-gray-700 !default;
$o-main-bg-color: #f0eeee !default;
$o-main-color-muted: rgba($o-main-text-color, $o-opacity-muted) !default;
$o-main-headings-color: $o-gray-900 !default;
$o-main-link-color: darken($o-brand-primary, 5%) !default;
$o-main-favorite-color: #f3cc00 !default;
$o-main-code-color: #d2317b !default;
$o-view-background-color: white !default;
$o-shadow-color: #303030 !default;
$o-form-lightsecondary: #ccc !default;
$o-list-footer-bg-color: #eee !default;
$o-list-footer-font-weight: bold !default;
$o-tooltip-background-color: $o-view-background-color !default;
$o-tooltip-color: $o-main-text-color !default;
$o-tooltip-arrow-color: white !default;
$o-tooltip-text-color: $o-main-text-color !default;
$o-tooltip-title-text-color: $o-main-headings-color !default;
$o-tooltip-title-background-color: $o-view-background-color !default;
// Components (BS)
$o-border-color: $o-gray-300 !default;
// Forms
// o-inputs
$o-input-padding-y: 2px !default;
$o-input-padding-x: 4px !default;
$o-input-border-required: $o-brand-primary !default;
// Layout
//
// Extension of BS4. This is not redefining the BS4 variable directly as we only
// need the extra ones for media queries (not creating new breakpoint classes).
// Note: default BS4 values are hardcoded here while it should be possible to
// merge with the default BS variable (but we would have to take care of
// ordering & cie).
$o-extra-grid-breakpoints: (
xs: 0,
vsm: 475px,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1534px,
) !default;
$o-form-group-cols: 12 !default;
$o-form-spacing-unit: 5px !default;
$o-horizontal-padding: 16px !default;
$o-innergroup-rpadding: 45px !default;
$o-dropdown-hpadding: 20px !default;
$o-dropdown-vpadding: 3px !default;
$o-dropdown-box-shadow: 0 1rem 1.1rem rgba(#000, .1) !default;
$o-sheet-vpadding: 24px !default;
$o-statbutton-height: 44px !default;
$o-statbutton-vpadding: 0px !default;
$o-statbutton-spacing: 6px !default;
$o-modal-lg: 980px !default;
$o-modal-md: 650px !default;
// Needed for having no spacing between sheet and mail body in mass_mailing:
// Different required cancel paddings between web and web_enterprise
$o-sheet-cancel-tpadding: 0px !default;
$o-avatar-size: 90px !default;
$o-statusbar-height: 33px !default;
$o-label-font-size-factor: 0.8 !default;
// == List group
$o-list-group-active-color: $o-gray-900 !default;
$o-list-group-active-bg: lighten(saturate(adjust-hue($o-info, 15), 1.8), 50) !default;
// == Badges
// Define a minimum width. This value is arbitrary and strictly font-related.
$o-badge-min-width: 2.5ch !default;
$o-nb-calendar-colors: 24 !default;
$o-base-settings-mobile-tabs-height: 40px !default;
$o-base-settings-mobile-tabs-overflow-gap: 3% !default;
$o-cp-breadcrumb-height: 30px !default;
$o-cp-button-sm-no-border-padding: 0.4rem;
$o-datepicker-week-color: #8f8f8f !default;
$o-card-body-bg-opacity: 0.9 !default;
// Border-radius
$o-border-radius: .25rem !default;
$o-border-radius-lg: .6rem !default;
$o-border-radius-sm: .2rem !default;
// touch
$o-touch-btn-padding: 7px 14px !default;
// Buttons
$o-btn-secondary-bg: $o-white !default;
$o-btn-secondary-hover-bg: $o-gray-100 !default;
$o-btn-secondary-hover-border: $o-gray-200 !default;
$o-btn-light-bg: $o-white !default;
$o-btn-light-border: $o-btn-light-bg !default;
$o-btn-light-background-hover: $o-gray-100 !default;

View file

@ -0,0 +1,44 @@
$o-webclient-background-color: $o-gray-100 !default;
$o-list-footer-color: null !default;
$o-list-group-header-color: lighten($o-brand-lightsecondary, 10%) !default;
// UI custom colors for tags, kanban records' colors, ...)
// Note: the first value is the old BS3 gray-light value
$o-colors: lighten(#000, 46.7%), #F06050, #F4A460, #F7CD1F, #6CC1ED, #814968,
#EB7E7F, #2C8397, #475577, #D6145F, #30C381, #9365B8 !default;
$o-colors-secondary: #aa4b6b, #30C381, #97743a, #F7CD1F, #4285F4, #8E24AA,
#D6145F, #173e43, #348F50, #AA3A38, #795548, #5e0231,
#6be585, #999966, #e9d362, #b56969, #bdc3c7, #649173,
#ea00ff, #ff0026, #8bcc00, #00bfaf, #006aff, #af00bf,
#bf001d, #bf6300, #8cff00, #00f2ff, #004ab3, #ff00d0,
#ffa600, #3acc00, #00b6bf, #0048ff, #bf7c00, #04ff00,
#00d0ff, #0036bf, #ff008c, #00bf49, #0092b3, #0004ff,
#b20062, #649173 !default;
// UI custom colors, complete list
$o-colors-complete: join(
$o-colors,
$o-colors-secondary
)!default;
$o-sheet-cancel-hpadding: $o-horizontal-padding !default;
$o-sheet-cancel-bpadding: $o-horizontal-padding !default;
$o-statusbar-arrow-width: $o-statusbar-height / 3 !default;
$o-statusbar-disabled-bg: lighten($o-brand-lightsecondary, 7%) !default;
$o-datepicker-week-bg-color: lighten($o-datepicker-week-color, 30%) !default;
// Form
// Safest for the next value would be map-get($container-max-widths, lg) as it
// is the minimal width of the default form view design for md/lg sizes
$o-form-sheet-min-width: 990px !default;
$o-form-separator-color: invert($o-view-background-color, 10%) !default;
$o-caret-down: url("data:image/svg+xml," +
"<svg xmlns='http://www.w3.org/2000/svg' width='7' height='4' viewBox='0 0 7 4'>" +
"<polygon fill='%23#{str-slice(#{$o-main-text-color}, 2)}' points='3.5 4 7 0 0 0'/>" +
"</svg>");

View file

@ -0,0 +1,244 @@
// Extend utilities
$rounded-sizes: () !default;
$rounded-sizes: map-merge(
$rounded-sizes,
(
null: $border-radius,
0: 0,
1: $border-radius-sm,
2: $border-radius,
3: $border-radius-lg,
circle: 50%,
pill: $border-radius-pill,
)
);
$utilities-opacity: () !default;
$utilities-opacity: map-merge(
$utilities-opacity,
(
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
disabled: $o-opacity-disabled,
)
);
$utilities-sizes: () !default;
$utilities-sizes: map-merge(
$utilities-sizes,
(
0: 0,
25: 25%,
50: 50%,
75: 75%,
100: 100%,
auto: auto,
)
);
$order-array: (
first: -1,
last: $grid-columns + 1,
) !default;
@for $i from 0 through $grid-columns {
$order-array: map-merge(
$order-array,
(#{$i}: $i)
);
}
$utilities: () !default;
$utilities: map-merge(
$utilities,
(
"display": map-merge(
map-get($utilities, "display"),
(
values: join(map-get(map-get($utilities, "display"), "values"), contents),
),
),
"position": map-merge(
map-get($utilities, "position"),
(
responsive: true,
),
),
"opacity": map-merge(
map-get($utilities, "opacity"),
(
values: $utilities-opacity,
),
),
"background-color": map-merge(
map-get($utilities, "background-color"),
(
values: map-merge(
map-get(map-get($utilities, "background-color"), "values"),
(
"view": $o-view-background-color,
)
)
)
),
"border-color": map-merge(
map-get($utilities, "border-color"),
(
values: map-merge(
map-get(map-get($utilities, "border-color"), "values"),
("transparent": transparent),
),
),
),
"rounded-top": (
property: border-top-left-radius border-top-right-radius,
class: rounded-top,
values: $rounded-sizes,
),
"rounded-end": (
property: border-top-right-radius border-bottom-right-radius,
class: rounded-end,
values: $rounded-sizes,
),
"rounded-bottom": (
property: border-bottom-right-radius border-bottom-left-radius,
class: rounded-bottom,
values: $rounded-sizes,
),
"rounded-start": (
property: border-bottom-left-radius border-top-left-radius,
class: rounded-start,
values: $rounded-sizes,
),
"width": map-merge(
map-get($utilities, "width"),
(
responsive: true,
values: $utilities-sizes,
),
),
"height": map-merge(
map-get($utilities, "height"),
(
responsive: true,
values: $utilities-sizes,
),
),
"max-width": map-merge(
map-get($utilities, "max-width"),
(
responsive: true,
values: $utilities-sizes,
),
),
"max-height": map-merge(
map-get($utilities, "max-height"),
(
responsive: true,
values: $utilities-sizes,
),
),
"font-family": map-merge(
map-get($utilities, "font-family"),
(
values: map-merge(
map-get(map-get($utilities, "font-family"), "values"),
(sans-serif: var(--#{$variable-prefix}font-sans-serif)),
),
),
),
"order": map-merge(
map-get($utilities, "order"),
(
values: $order-array,
),
),
),
);
// Odoo Custom Utility Classes
$utilities: map-merge(
$utilities,
(
"cursor": (
property: cursor,
values: default pointer,
),
"bg-opacity": (
css-var: true,
class: bg-opacity,
values: $utilities-opacity,
),
"flex-basis": (
responsive: true,
property: flex-basis,
values: $utilities-sizes,
),
"z-index": (
property: z-index,
values: 0 1,
),
"overflow-x": (
property: overflow-x,
values: auto hidden visible scroll,
),
"overflow-y": (
property: overflow-y,
values: auto hidden visible scroll,
),
"transition": (
property: transition,
values: (
none: none,
base: $transition-base,
fade: $transition-fade,
),
),
"min-width": (
class: min-w,
property: min-width,
values: 0,
),
)
);
// Restore text-X from BS4 that use text-emphasis-variant
// we don't merge $utilities-text-colors into $utilities
// to avoid same utilises classes generated twice.
// See bootstrap_review.scss
$utilities: map-merge(
$utilities,
(
"color": (
property: color,
class: text,
local-vars: (
"text-opacity": 1
),
values: (
"body": $body-color,
"black": $black,
"white": $white,
"muted": $text-muted,
"black-50": rgba($black, .5), // deprecated
"white-50": rgba($white, .5), // deprecated
"reset": inherit,
),
),
)
);
// Define opacity:hover classes while defining the triggerer behavior.
// Use'.opacity-trigger-hover' class to allow hovered parents to
// trigger their children ':hover' opacity state.
@each $-opacity-key, $-opacity-level in $utilities-opacity {
.opacity-#{$-opacity-key}-hover {
&:hover, .opacity-trigger-hover:hover & {
opacity: $-opacity-level!important;
}
}
}