Every row is a door: pressing it joins the channel. A closed room cannot be entered, so its row asks for access instead — the verb is on the row, and it does not change under the pointer.
<.channel_list_panel
id="channel-list"
channels={@channels}
on_search="filter_channels"
on_join="join_channel"
on_knock="knock_channel"
/>
Channel list showing the 'Searching...' state while fetching channels.