fix(portal): align stepper labels with circles via per-unit absolute positioning

Original macro put the 5 labels in a separate flex container below the
stepper with flex:1 each. That distributes them at 10%/30%/50%/70%/90%
(centred in 1/5 slots) while the circles distribute at 0%/25%/50%/75%/
100% (edges via space-between + line-flex). Result: labels visibly off
from their circles, getting worse the wider the row.

Restructured the macro so each circle + its label live inside a single
.o_fp_step_unit. The label is absolute-positioned at top:100% / left:50%
with translateX(-50%), so its horizontal centre always pins to the
circle's centre regardless of text width. Wider labels ('Inspected')
overflow equally to both sides instead of pushing the column.

Bumped stepper margin-bottom to 2.4rem so the absolutely-positioned
labels have clearance below. Dropped the now-unused .o_fp_step_labels
container rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-17 04:10:28 -04:00
parent a63fbe1558
commit 27badff570
2 changed files with 71 additions and 55 deletions

View File

@@ -27,17 +27,29 @@
<t t-set="active_state" t-value="active_state or 'normal'"/>
<div class="o_fp_stepper">
<t t-foreach="steps" t-as="step">
<!-- circle -->
<div t-attf-class="o_fp_step_circle #{
'o_fp_step_done' if step['status'] == 'done' else
(('o_fp_step_active_warn' if active_state == 'warn' else 'o_fp_step_active') if step['status'] == 'active' else '')
}">
<t t-if="step['status'] == 'done'"></t>
<t t-elif="step['status'] in ('active', 'pending')">
<t t-out="step_index + 1"/>
</t>
<!-- Unit = circle + its label stacked. Label is absolutely
positioned below the circle (in SCSS) so its horizontal
centre lines up with the circle no matter how wide the
text is — fixes the column-vs-edge distribution
mismatch we had with a separate labels row. -->
<div class="o_fp_step_unit">
<div t-attf-class="o_fp_step_circle #{
'o_fp_step_done' if step['status'] == 'done' else
(('o_fp_step_active_warn' if active_state == 'warn' else 'o_fp_step_active') if step['status'] == 'active' else '')
}">
<t t-if="step['status'] == 'done'"></t>
<t t-elif="step['status'] in ('active', 'pending')">
<t t-out="step_index + 1"/>
</t>
</div>
<div t-attf-class="o_fp_step_label #{
'o_fp_step_label_done' if step['status'] == 'done' else
(('o_fp_step_label_active_warn' if active_state == 'warn' else 'o_fp_step_label_active') if step['status'] == 'active' else '')
}">
<div class="o_fp_step_label_title" t-out="step['label']"/>
<div class="o_fp_step_label_time" t-out="step.get('time_label') or ''"/>
</div>
</div>
<!-- connecting line (omit after last circle) -->
<t t-if="not step_last">
<div t-attf-class="o_fp_step_line #{
'o_fp_step_line_done' if step['status'] == 'done' else
@@ -46,18 +58,6 @@
</t>
</t>
</div>
<!-- Labels under -->
<div class="o_fp_step_labels">
<t t-foreach="steps" t-as="step">
<div t-attf-class="o_fp_step_label #{
'o_fp_step_label_done' if step['status'] == 'done' else
(('o_fp_step_label_active_warn' if active_state == 'warn' else 'o_fp_step_label_active') if step['status'] == 'active' else '')
}">
<div class="o_fp_step_label_title" t-out="step['label']"/>
<div class="o_fp_step_label_time" t-out="step.get('time_label') or ''"/>
</div>
</t>
</div>
</template>
<!-- ================================================================== -->