[FIX] *: remove display: contents from field widgets and adapt code

With the conversion of the views to owl, we added an extra div around
fields that represents the whole field, and wraps potentially multiple
elements that may be rendered by a field widget. This changes the DOM
structure, and to allow concrete fields to control everything about the
way they are displayed, we decided to use the css rule "display:
contents" for that div. As it turns out, while this does give more
control to the field widget, it breaks a lot of existing css rules, and
also prevents classes that are applied on that div from the arch from
affecting any css property related to layout (such as margin, position
or padding).

Because of that, we decided to revert this change, and set this div's
display property to inline-block (the same as legacy field widgets) and
adapt the few fields where this does not work out of the box, which
fixes many issues.

Part-of: odoo/odoo#98711
This commit is contained in:
Samuel Degueldre
2022-08-25 03:11:45 +02:00
committed by Aaron Bohy
parent c8de959617
commit a6dd7075b3
10 changed files with 62 additions and 269 deletions
+2 -2
View File
@@ -111,8 +111,8 @@
<field name="free_member"/>
<label for="membership_state"/>
<div>
<field name="membership_state"/>
<button name="%(action_membership_invoice_view)d" type="action" string="Buy Membership"
<field name="membership_state" class="oe_inline"/>
<button name="%(action_membership_invoice_view)d" type="action" string="Buy Membership"
attrs="{'invisible':[('free_member','=',True)]}" class="oe_link"/>
</div>
</group>
@@ -186,7 +186,7 @@ html .o_web_client > .o_action_manager > .o_action > .o_content > .o_controller_
.oe_stat_button {
flex-basis: 33.333333%;
border-width: 1px;
border: 1px solid $border-color;
margin-top: -1px;
margin-left: -1px;
height: 57.5px;
@@ -39,7 +39,7 @@
<t t-name="project.StatButtonsSection" owl="1">
<div class="o_rightpanel_section">
<div class="o_form_view">
<div class="oe_button_box o_full">
<div class="oe_button_box o-form-buttonbox">
<t t-foreach="state.data.buttons" t-as="button" t-key="button.action">
<button class="btn oe_stat_button" t-if="button.show"
t-on-click="onProjectActionClick"
@@ -5,7 +5,7 @@
.nav.nav-tabs {
flex-flow: row nowrap;
}
}
&.vertical {
+9 -11
View File
@@ -62,10 +62,8 @@
.o_field_widget {
// Default display and alignment of widget and internal <input/>
text-align: inherit;
display: inline-block;
&.o_legacy_field_widget {
display: inline-block;
}
input.o_input {
display: inline-block;
text-align: inherit;
@@ -136,16 +134,16 @@
// Many2One
&.o_field_many2one {
flex-direction: column;
}
.o_field_many2one_selection {
display: flex;
width: 100%;
}
.o_field_many2one_selection {
display: flex;
width: 100%;
}
.o_external_button {
padding-top: 0;
padding-bottom: 0;
}
.o_external_button {
padding-top: 0;
padding-bottom: 0;
}
// Many2OneAvatar
@@ -1,8 +1,3 @@
.o_field_cursor_disabled {
cursor: not-allowed;
}
// TODO: remove legacy selector when there are no remaining legacy fields in codebase
div.o_field_widget:not(.o_legacy_field_widget) {
display: contents;
}
@@ -10,7 +10,7 @@
// that cases.
box-shadow: inset 0 -1px 0 $border-color;
> .btn.oe_stat_button, > .o_dropdown_more {
.btn.oe_stat_button {
flex: 0 0 auto;
width: percentage(1/3); // Adapt the number of visible buttons for each screen width
@include media-breakpoint-up(md) {
@@ -24,20 +24,6 @@
}
}
> .btn.oe_stat_button.o-dropdown {
.o_button_more {
height:100%;
width: 100%;
&:after {
@include o-caret-right
};
}
&.show .o_button_more:after {
@include o-caret-down;
}
}
.btn.oe_stat_button {
color: $o-main-text-color;
height: $o-statbutton-height;
@@ -46,11 +32,8 @@
text-align: left;
white-space: nowrap;
background-color: transparent;
opacity: 0.8;
border-radius: 0px;
margin-bottom: 0; // If the button comes from a field
border: 0 solid map-get($grays, '300');
text-transform: capitalize !important;
&:hover, &:focus {
background-color: rgba(black, 0.03);
@@ -117,63 +100,40 @@
&:hover .o_stat_info > .o_not_hover {
display: none !important
}
}
.oe_stat_button {
border-left: 1px solid $border-color;
}
&.o_full > .oe_stat_button:first-child {
border-left: none;
}
&.o_button_more {
padding: 0 !important;
> .o_dropdown_toggler {
text-align: center;
width: 100%;
height: 100%;
// "More" button and dropdown
.oe_stat_button.dropdown {
> .o_button_more {
width: 100%;
height: 100%;
&:after {
margin-left: 5px;
@include o-caret-down;
}
}
&.show > .o_button_more {
&:after {
@include o-caret-up;
}
}
.o_dropdown_more {
width: 150px;
> .dropdown-item {
border: none;
border-bottom: 1px solid map-get($grays, '300');
margin: 0;
padding: 0;
background-color: transparent;
&:after {
margin-left: 5px;
@include o-caret-down;
}
&[aria-expanded="true"]:after {
margin-left: 5px;
@include o-caret-up;
border-bottom: 1px solid $border-color;
.oe_stat_button {
border: none;
width: 100%;
}
}
}
}
&.o-full .oe_stat_button:not(.o_invisible_modifier) ~ .oe_stat_button {
border-left: 1px solid $border-color;
}
&.o-not-full .oe_stat_button {
border-left: 1px solid $border-color;
}
// > .o_dropdown_more {
// @include o-position-absolute(100%, 0);
// min-width: 0;
// border: none;
// border: 1px solid map-get($grays, '300');
// margin: 0;
// padding: 0;
// @include media-breakpoint-down(md) {
// // avoid b4 drowdown inline style
// position: relative !important;
// transform: none !important;
// will-change: inherit!important;
// margin-bottom: 20px;
// width: 100%;
// border-width: 0px;
// }
// > .btn.oe_stat_button {
// width: 100%;
// border: none;
// border-bottom: 1px solid map-get($grays, '300');
// @include media-breakpoint-down(md) {
// display: inline-block;
// width: percentage(1/3);
// }
// }
// }
}
@@ -9,9 +9,9 @@
<t t-slot="{{ button_value }}" t-foreach="visibleButtons" t-as="button" t-key="button_value" />
<t t-if="additionalButtons.length" >
<Dropdown togglerClass="'btn o_button_more'" class="'btn oe_stat_button'">
<Dropdown togglerClass="'btn o_button_more'" menuClass="'o_dropdown_more p-0'" class="'btn oe_stat_button'">
<t t-set-slot="toggler"><span>More</span></t>
<DropdownItem t-foreach="additionalButtons" t-as="button" t-key="button_value">
<DropdownItem t-foreach="additionalButtons" t-as="button" t-key="button_value" class="'p-0'">
<t t-slot="{{ button_value }}" />
</DropdownItem>
</Dropdown>
@@ -1,7 +1,7 @@
// Define left and right padding according to screen resolution
@mixin o-form-sheet-inner-left-padding {
padding-left: $o-horizontal-padding;
@include media-breakpoint-between(lg, xxl, $o-extra-grid-breakpoints) {
@include media-breakpoint-between(lg, $o-extra-grid-breakpoints) {
padding-left: $o-horizontal-padding*2;
}
}
@@ -10,7 +10,7 @@
}
@mixin o-form-sheet-inner-right-padding {
padding-right: $o-horizontal-padding;
@include media-breakpoint-between(lg, xxl, $o-extra-grid-breakpoints) {
@include media-breakpoint-between(lg, $o-extra-grid-breakpoints) {
padding-right: $o-horizontal-padding*2;
}
}
@@ -18,7 +18,7 @@
@mixin o-form-sheet-negative-margin {
margin-left: -$o-horizontal-padding;
margin-right: -$o-horizontal-padding;
@include media-breakpoint-between(lg, xxl, $o-extra-grid-breakpoints) {
@include media-breakpoint-between(lg, $o-extra-grid-breakpoints) {
margin-left: -$o-horizontal-padding*2;
margin-right: -$o-horizontal-padding*2;
}
@@ -167,7 +167,7 @@ $o-form-label-margin-right: 0px;
width: auto!important;
}
}
&.o_field_many2one_selection {
.o_field_many2one_selection {
width: 100% !important;
}
}
@@ -247,162 +247,6 @@ $o-form-label-margin-right: 0px;
}
}
// Button box
.oe_button_box {
position: relative;
display: block;
margin-bottom: $o-sheet-vpadding;
margin-top: -$o-sheet-vpadding;
@include o-form-sheet-negative-margin;
text-align: right;
// Use box-shadow instead of border-bottom because some button boxes are
// empty in some cases and we do not want to see a floating border in
// that cases.
box-shadow: inset 0 -1px 0 $border-color;
.oe_stat_button, .o_dropdown_more {
border: 0 solid $border-color;
}
&.o_full .oe_stat_button:not(.o_invisible_modifier) ~ .oe_stat_button,
&.o_not_full .oe_stat_button {
border-left-width: $border-width;
}
.btn.oe_stat_button, > .o_dropdown_more {
flex: 0 0 auto;
width: percentage(1/3); // Adapt the number of visible buttons for each screen width
@include media-breakpoint-up(md) {
width: percentage(1/5);
}
@include media-breakpoint-up(lg) {
width: percentage(1/7);
}
@include media-breakpoint-up(xl) {
width: percentage(1/8);
}
}
.btn.oe_stat_button {
color: $o-main-text-color;
height: $o-statbutton-height;
// Use !important to avoid touch_device style
padding: 0 $o-statbutton-spacing 0 0 !important; // padding-left will be achieved through margin-left of content
text-align: left;
white-space: nowrap;
background-color: transparent;
opacity: 0.8;
border-radius: 0px;
margin-bottom: 0; // If the button comes from a field
&:hover, &:focus {
background-color: rgba(black, 0.03);
color: inherit;
opacity: 1;
}
> .o_button_icon {
margin-left: $o-statbutton-spacing; // To create the button padding left (firefox bug)
display: inline-block;
vertical-align: middle;
line-height: $o-statbutton-height;
width: 30%;
&:before {
font-size: 22px;
vertical-align: middle;
}
}
> .o_field_percent_pie {
margin-left: $o-statbutton-spacing; // To create the button padding left (firefox bug)
}
// Some buttons only display text without using StatInfo template
> span {
@include o-text-overflow(block);
white-space: normal; // text on several lines if needed
}
> .o_stat_info, > span { // contains the value and text
display: inline-block;
vertical-align: middle;
font-weight: $font-weight-normal;
max-width: 70%;
padding-right: $o-statbutton-spacing;
line-height: 1.3;
> .o_stat_value, > .o_stat_text {
@include o-text-overflow(block);
line-height: 1.2;
}
.o_stat_value {
font-weight: $font-weight-bold;
color: $o-brand-odoo;
}
.o_stat_text .o_field_empty {
display: none;
}
}
&:not(:disabled) {
> .o_stat_info .o_field_widget, > span .o_field_widget {
cursor: pointer;
}
}
&:not(:hover) .o_stat_info > .o_hover {
display: none !important;
}
&:hover .o_stat_info > .o_not_hover {
display: none !important
}
&.o_button_more {
text-align: center;
&:after {
margin-left: 5px;
@include o-caret-down;
}
&[aria-expanded="true"]:after {
margin-left: 5px;
@include o-caret-up;
}
}
}
> .o_dropdown_more {
@include o-position-absolute(100%, 0);
min-width: 0;
border-width: 0 $border-width;
box-sizing: content-box;
margin: 0;
padding: 0;
@include media-breakpoint-down(md) {
// avoid b4 drowdown inline style
position: relative !important;
transform: none !important;
will-change: inherit!important;
margin-bottom: 20px;
width: 100%;
border-width: 0px;
}
> .btn.oe_stat_button {
width: 100%;
// Override stronger ':not(.o_invisible_modifier) ~' rule
border-width: 0 0 $border-width!important;
@include media-breakpoint-down(md) {
display: inline-block;
width: percentage(1/3);
}
}
}
}
// Title
.oe_title {
> h1, > h2, > h3 {
@@ -428,16 +272,14 @@ $o-form-label-margin-right: 0px;
// Avatar
.oe_avatar {
> div {
float: right;
margin-bottom: 10px;
float: right;
margin-bottom: 10px;
> img {
max-width: $o-avatar-size;
max-height: $o-avatar-size;
vertical-align: top;
border: 1px solid $o-gray-300;
}
> div > img {
max-width: $o-avatar-size;
max-height: $o-avatar-size;
vertical-align: top;
border: 1px solid $o-gray-300;
}
}
@@ -474,12 +316,6 @@ $o-form-label-margin-right: 0px;
@include o-td-label-style;
}
vertical-align: top;
span, .o_field_boolean, .oe_avatar, .o_form_uri {
&.o_field_widget {
width: auto;
}
}
}
.o_field_widget {
@@ -162,6 +162,10 @@
pointer-events: none;
}
.o_field_website_redirect_button {
display: contents;
}
.o_legacy_kanban_view.o_theme_kanban {
$o-theme-kanban-gray: #fcfcfc;
background-color: $o-theme-kanban-gray;