Introducing a new "Post Type" Composer actions dropdown

Composer redesign behind enable_new_composer_actions

This introduces a redesigned composer experience and ships it behind a new alpha upcoming-change. With the flag off (default), nothing visibly changes. Admins can opt in via the upcoming-changes admin page.

What changes when the flag is on

  • Unified actions dropdown. The legacy SelectKit composer-actions dropdown is replaced by a new Glimmer/DMenu component (composer-actions-new.gjs). It still surfaces all the same mode-switch rows (reply to topic, reply as new topic, create PM, etc.) with clearer labels and icons.

  • Toggles live with the actions. Whisper / no-bump / unlist now render as <DToggleSwitch> items at the bottom of that same dropdown — no separate combo-button menu. Toggle state survives mode switches (e.g. toggle whisper on → switch from reply-to-topic to reply-to-post → still whispering).

  • Whisper indicator pill. A small button to the right of the dropdown trigger shows current whisper state in two visual variants: --public (tertiary color, eye icon, “Reply will be visible”) and --whispering (primary-medium / primary-very-low background, eye-slash icon, “Whispering”). Clicking it toggles whisper — same code path as the toggle inside the dropdown, so the two stay in sync. The trigger icon itself also swaps to far-eye-slash when whispering.

  • Editing UX. When editing a post the dropdown collapses to a static, caret-less label (pencil icon + “Edit post”). The “Add edit reason” button that used to live elsewhere in the composer chrome is folded into this static trigger as a clickable “Describe your edit” button; clicking it swaps the label for a text input bound to composer.editReason and focuses it.

    • editing
  • Composer chrome. The .action-title text/span is removed — the dropdown trigger itself shows the current mode.

  • Post/Topic Links will now only appear when necessary. A topic link will render when navigating away from the topic, and the post link will render when scrolled away from the post / navigating away.

Plugin author notes

The new component is not a SelectKit subclass, so the old extension APIs do not reach it. To support both flag states in this alpha phase, plugins should register both APIs:

Old API (works on old component only) New API (works on new component only)
api.modifySelectKit("composer-actions").appendContent(...) api.registerValueTransformer("composer-actions-content", ({ value, context }) => { value.push(...); return value; })
api.modifyClass("component:composer-actions", { fooSelected(options, model) { ... } }) api.registerBehaviorTransformer("composer-actions-on-select", ({ context, next }) => { if (context.actionId === "foo") { ...; return; } next(); })

Row shape ({ name, description, icon, id }) is identical in both. The behavior transformer receives { actionId, options, model } in its context.

:double_exclamation_mark: Plugins that only register the old hooks will silently disappear from the composer the moment an admin enables the flag. Plugins that only register the new transformers will be invisible while the flag is off (the default for everyone on merge).

References:

  • discourse-post-voting/extend-composer-actions.js — worked example of dual registration (in core)

  • discourse-staff-alias — separate PR adds dual registration there

  • transformers.js — the two new transformer names

Rollout notes

  • Flag status is alpha — opt-in for internal testing.

  • Plugins that integrate with composer actions should add dual registration before this is promoted to beta/stable.

  • Tests cover both states: existing acceptance/system specs cover flag-off; sibling *-new-test.js files cover flag-on (plus the new-component DOM selectors for the unified dropdown, toggle items, whisper indicator, and split-label spans).

20 Likes

The “topic link” is rendering with html code in addition to the topic title…

That can’t be right

Fixed here → FIX: Do not render fancyTitle link in composer header by jordanvidrine · Pull Request #40500 · discourse/discourse · GitHub

4 Likes

Would it be possible to not display the “Toggle post voting” option if the selected category type is not Ideas, or the category settings haven’t enabled the post voting feature? : ))

5 Likes

That makes sense to me, I think it might be a regression? Or was that always the case, do you know @jordan.vidrine ?

1 Like

This was always the case, the post voting plugin is sitewide rather than scoped by category. The category level settings for it are only about setting the default, rather than restricting it from being used.

We’re in a little bit of a transition state with the post voting plugin… I think we’ll need to figure out a migration to avoid breaking more general use of it before restricting to specific categories, just because the “ideas” type is a fairly new concept.

2 Likes

The good news is that in the meantime we have to hooks to allow this in a theme component… this works in an initializer to only show the toggle in an ideas category:

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
    name: "hide-post-voting-toggle",
    after: "extend-composer-actions", 

    initialize() {
      withPluginApi((api) => {
        api.registerValueTransformer(
          "composer-actions-content",
          ({ value, context }) => {
            const category = context.composerModel?.category;
    
            if (!category?.isType("ideas")) {
              return value.filter((item) => item.id !== "togglePostVoting");
            }
    
            return value;
          }
        );
      });
    }
};

8 Likes

On my tablet the dropdown is hidden behind the composer.

1 Like

Hello @Moin, thank you for bringing this to our attention.

I haven’t been able to reproduce the issue on my end using Chromium, Firefox, or Safari, and unfortunately, the attached video isn’t playing for me.

To help us diagnose and track this down, could you provide a few more details?

  • Operating System: (e.g., Android, iOS, Windows, macOS, Linux)

  • Browser & Version: (e.g., Chrome 125, Safari 17)

  • Discourse Version: You can find this in your Admin Dashboard, or by following this guide on Meta.

One thing you can try right now:

Test the behavior in Safe Mode by adding /safe-mode to the end of your site’s URL (e.g., https://discourse.example.com/safe-mode).

  • If the issue disappears: One of your site’s customizations (plugins, themes, or components) is likely causing a conflict.

  • If the issue persists: It’s a core bug, and the browser/device details you provide above will help us pinpoint and fix it.

Thank you for your persistence, it is appreciated, and please let us know if there are any questions about the info I’ve shared here.

2 Likes

As you can see in the video above (I uploaded it again - not sure why it was broken today) I had enabled safe mode.

The current version is 2a08d5d (It was different when I wrote the report). I can also repro here - I only chose my forum because admins have more options so the hidden menu was better visible. On Meta it’s barely visible. Most of the time it seems the button wouldn’t work at all

I am using a Samsung Galaxy Tab S9 FE (Android 16) with Firefox


I have just checked Chrome - it seems to be the same:

Usually this kind of issues are because my tablet has “desktop-size” but is touch. Similar to the problems here or here

2 Likes

Thank you, this context is helpful.

I do not have an Android touch tablet, but I can reproduce the issue in Firefox reliably by using the emulated touch button.

Provisionally, it can be solved with this styling rule:

.composer-toggles-menu-content, .composer-actions-dropdown {
    z-index: 1100;
}

I will update Discourse with this intended fix and notify when the changes are merged. *Update: Changes are merged, you will see the fix in your next deployment running version d82dc7c or newer.

Again, thank you for reporting the issue.

3 Likes

Thanks!

Side note: since edits on the last post no longer bump the topic an edit doesn’t work well as a notification. One of your colleagues once said that one should just post separate updates instead. It’s interesting that you guys often don’t do that yourselves.