diff --git a/web/src/components/promql/components/PromQLBuilderOptions.vue b/web/src/components/promql/components/PromQLBuilderOptions.vue
index 73eba85153..ccaf14dcda 100644
--- a/web/src/components/promql/components/PromQLBuilderOptions.vue
+++ b/web/src/components/promql/components/PromQLBuilderOptions.vue
@@ -114,19 +114,21 @@
valueKey="value"
data-test="dashboard-promql-builder-query-type"
style="width: 120px"
+ />
+
-
-
-
-
- Query Type -
- Range: Returns time series data over a time range.
- Instant: Returns single value at a specific point in time.
-
-
-
-
-
+
+
+ Query Type -
+ Range: Returns time series data over a time range.
+ Instant: Returns single value at a specific point in time.
+
+
+
diff --git a/web/src/lib/forms/Select/OSelect.types.ts b/web/src/lib/forms/Select/OSelect.types.ts
index 4ab49080d2..36f3c4ed39 100644
--- a/web/src/lib/forms/Select/OSelect.types.ts
+++ b/web/src/lib/forms/Select/OSelect.types.ts
@@ -160,8 +160,6 @@ export interface SelectSlots {
"before-options"?: () => unknown;
/** Icon content inside the trigger on the left — matches OButton's `#icon-left` pattern */
"icon-left"?: () => unknown;
- /** Icon content inside the trigger on the right — matches OButton's `#icon-right` pattern */
- "icon-right"?: () => unknown;
/**
* Tooltip content rendered inside an info icon in the label area.
* Provide a `` element as the slot content.
diff --git a/web/src/lib/overlay/Tooltip/OTooltip.spec.ts b/web/src/lib/overlay/Tooltip/OTooltip.spec.ts
index 7c5d868d24..8797002165 100644
--- a/web/src/lib/overlay/Tooltip/OTooltip.spec.ts
+++ b/web/src/lib/overlay/Tooltip/OTooltip.spec.ts
@@ -116,6 +116,35 @@ describe("OTooltip", () => {
});
});
+ // ── Content wrapper layout ─────────────────────────────────────────────────
+ //
+ // The content wrapper used to be `inline-flex items-center gap-1.5`
+ // unconditionally, purely to align an optional keyboard-shortcut chip. But
+ // `inline-flex` turned every text run / /
of a multi-line tooltip
+ // into a separate flex item on one non-wrapping row, so each run collapsed to
+ // its longest word — text wrapped into a narrow column and short leading runs
+ // were vertically centred against the tall body (the "not aligned" bug seen
+ // across Legend / Step / Y-Axis / VRL tooltips). Flex is now applied ONLY when
+ // a shortcut is present; plain tooltips flow as normal wrapping text.
+ it("does not force inline-flex on the content wrapper without a shortcut", () => {
+ const wrapper = mountTooltip(
+ { content: "Multi line body text", open: true },
+ { default: () => h("button", "Hover") },
+ );
+ const contentSpan = wrapper.find('[data-test="o-tooltip-content"] > span');
+ expect(contentSpan.exists()).toBe(true);
+ expect(contentSpan.classes()).not.toContain("inline-flex");
+ });
+
+ it("applies inline-flex on the content wrapper when a shortcut is present", () => {
+ const wrapper = mountTooltip(
+ { content: "Save", open: true, shortcut: "ctrl+s" },
+ { default: () => h("button", "Hover") },
+ );
+ const contentSpan = wrapper.find('[data-test="o-tooltip-content"] > span');
+ expect(contentSpan.classes()).toContain("inline-flex");
+ });
+
it("applies contentClass to the tooltip bubble", () => {
const wrapper = mountTooltip(
{ content: "Styled", open: true, contentClass: "my-custom-class" },
diff --git a/web/src/lib/overlay/Tooltip/OTooltip.vue b/web/src/lib/overlay/Tooltip/OTooltip.vue
index 51d5a37f3d..5deb6daff2 100644
--- a/web/src/lib/overlay/Tooltip/OTooltip.vue
+++ b/web/src/lib/overlay/Tooltip/OTooltip.vue
@@ -152,7 +152,7 @@ const contentClasses = computed(() => [
:style="contentStyle"
:class="contentClasses"
>
-
+
{{ content }}
[
:style="contentStyle"
:class="contentClasses"
>
-
+
{{ content }}