Skip to content

add chat component and claude ui-max-pro skill - #53

Open
maks5554371 wants to merge 2 commits into
jetrockets:mainfrom
maks5554371:feature/chat
Open

add chat component and claude ui-max-pro skill#53
maks5554371 wants to merge 2 commits into
jetrockets:mainfrom
maks5554371:feature/chat

Conversation

@maks5554371

@maks5554371 maks5554371 commented Jun 22, 2026

Copy link
Copy Markdown

Introduces a composable Ui::Chat component to the UI library. The component covers a message feed with bubbles, avatars, author/timestamp, a typing indicator, and an input footer - plus auto-scroll and a Turbo Streams integration point for realtime updates.

Component API

<%= ui.chat stream: [@room, :messages] do %>
  <%= ui.chat_messages id: dom_id(@room, :messages) do %>
    <%= ui.chat_message position: :start do %>
      <%= ui.avatar user: message.user %>
      <%= ui.chat_bubble do %>
        <%= ui.chat_author message.user.full_name %>
        <%= message.body %>
        <%= ui.chat_time message.created_at.strftime("%H:%M") %>
      <% end %>
    <% end %>
    <%= ui.chat_message position: :end do %>
      <%= ui.chat_bubble variant: :primary do %>How are you?<% end %>
    <% end %>
    <%= ui.chat_typing %>
  <% end %>
  <%= ui.chat_footer do %> … message form … <% end %>
<% end %>

Subcomponents
chat, chat_messages, chat_message (position: :start/:end), chat_bubble (variant: :default/:primary/:muted), chat_author, chat_time, chat_typing, chat_footer.

Interactivity (chat_controller.js)

Auto-scroll to the latest message via MutationObserver, respecting manual scroll-up (only auto-scrolls when the user is pinned to the bottom).

Enter to send (Shift+Enter for a newline) via the send action on the message form.

Textarea auto-grow is wired through the existing textarea-autogrow controller.

Realtime
The stream: option renders turbo_stream_from, and chat_messages exposes a stable DOM id as the broadcast target - so a model can broadcast_append_to new messages and they appear live (with auto-scroll). No backend/ActionCable is added here; the component only provides the integration points, documented in the component docs.

Documentation
Full docs at /ui/components/chat via component.yml (props, slots, examples), a docs view, route, breadcrumb, sidebar link, and a controller action

Tooling: ui-ux-pro-max Claude skill
Also bundles a Claude Code skill under .claude/skills/ui-ux-pro-max/ - a UI/UX design knowledge base (styles, palettes, font pairings, stack-specific guidelines) with helper scripts, used to assist component design and review within the repo.

@solilin
solilin self-requested a review June 22, 2026 20:36
Comment thread app/components/ui/chat/component.rb Outdated
@@ -0,0 +1,27 @@
class Ui::Chat::Component < ApplicationComponent
def initialize(stream: nil, **options)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename it ro streams, and it should be an Array [] by default


def attrs
data_attributes = ({ controller: "chat" }).deep_merge(@options.fetch(:data, {}))
@options.merge(data: data_attributes)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data_attributes is for data, but there could be other attributes also, for example, class, id, ...

Let's merge data attributes separately.

Comment thread app/components/ui/chat/component.css Outdated
@apply flex items-end gap-2 max-w-[85%];
}

.chat__message--start {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.block_name {}
.block_name__element_name {}
.block_name__element_name-mod {}

}
}

scrollToBottom() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems, that is should be a private - #scrollToBottom

- Rename `stream:` to `streams:` with an empty Array default
- Extract data attributes merging into a separate `data_attributes` method
- Follow the BEM modifier convention (`block__element-mod`)
- Make `scrollToBottom` private in the Stimulus controller
- Format the controller with StandardJS
- Stop tracking local AI assistant tooling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants