AB#131731 chat-components: layout variant mechanism (webchat + c26)#242
Closed
AB#131731 chat-components: layout variant mechanism (webchat + c26)#242
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n types Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…slots Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…erer parity tests Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Extracted BaseLayoutProps, MatchedPlugins, and MessageFocusTarget to src/layouts/shared/. Unified focus-target id prefix so the existing moveFocusToMessageFocusTarget util works under c26. Moved layouts up to src/layouts/. Replaced :global(.user) with [data-source="user"]. Dropped narration comments and redundant narrowing ternaries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ayouts barrel Plugin CSS (ChatBubble.module.css, File.module.css) targets `article:global(.bot|.user|.agent)` for bubble backgrounds and user-side file alignment. Simplification pass dropped the bare source class on C26Layout's article, regressing those styles under layout="c26". Restore it. Also route Message.tsx through the src/layouts barrel and expose BaseLayoutProps from it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… asymmetric corners, token-via-UCL fallback) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
Major testing surface: rendering on this branch does not introduce any dom tree change when compared against latest library release. Should be an automated scenario rendering both and doing strict comparison. Criterion yet to define, indentation change is OK. |
…on token parameterization Pre-landing of structural wiring for c26 visual theme pass: - Rename C26Layout.content → .bubble with role-aware fills - Parameterize ActionButton/ActionButtons with --cc-button-* and --cc-buttons-* tokens - Add action-button token defaults in theme.css c26 block Token values for the glass variant + shadow + role-differentiated max-width land in follow-up commits per design-artifacts/plans/2026-04-22-chat-components-c26-visual-theme-plan.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- User bubble fallback: neutral-50 → primary-25 (faint lavender so both bubbles share the purple family on white MFE) - Avatar: 36px → 40px (matches UCL size-10) - Add --cc-bubble-max-width-bot/-user (role-differentiated: min(80%,480px) / min(70%,320px)) and --cc-bubble-box-shadow (UCL shadow-sm) - Replace action-button tokens with glass variant (translucent white 18%, white text, faint border, blur 4px) + new --cc-button-border / -hover-border / -backdrop-filter tokens - Temporary --cc-bubble-max-width alias to bot cap; removed in Task 2 when C26Layout.module.css:115 is rewritten Extends test/theme-c26.spec.ts with 6 new assertions (uses existing c26Block var from beforeAll). 155/155 tests pass. Spec: alu-resources/design-artifacts/specs/2026-04-22-chat-components-c26-visual-theme-spec.md Plan: alu-resources/design-artifacts/plans/2026-04-22-chat-components-c26-visual-theme-plan.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… c26 bubbles C26Layout.module.css (outer c26 .bubble, visible surface): - Add box-shadow: var(--cc-bubble-box-shadow) - Replace base .bubble max-width with role-scoped rules: - .article:not([data-source=user]) .bubble → bot cap - .article[data-source=user] .bubble → user cap theme.css: - Drop the temporary --cc-bubble-max-width alias added in Task 1 - Add c26-scoped .chat-bubble role-diff max-width rules alongside the asymmetric-corner rules (inner ChatBubble rendered by Text plugin would otherwise fall back to 295px default inside c26) Tests: - Flip theme-c26 alias assertion back to not.toMatch - Add C26Layout.spec.tsx CSS-file regex assertions for box-shadow + role-scoped max-width (tightened with [^}]*? to not cross block boundaries) - Add theme-c26 assertions for the scoped .chat-bubble max-width rules Known follow-up: C26Layout's outer .bubble nests plugin-internal .chat-bubble. Both currently carry bg/border/padding/max-width, which double up visually. Dedup in a later phase; both caps kept in sync via the role-scoped rules above. 159/159 tests pass. Spec: alu-resources/design-artifacts/specs/2026-04-22-chat-components-c26-visual-theme-spec.md Plan: alu-resources/design-artifacts/plans/2026-04-22-chat-components-c26-visual-theme-plan.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Flip .avatar align-items: flex-start → flex-end and align-self: start → end so the avatar sits at the bubble's bottom edge. The asymmetric bubble corner (bottom-left straight for bot/agent, bottom-right straight for user) now visually points at the avatar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n-backdrop-filter in ActionButton Add token reads for the glass-variant properties Task 1 defined: - border: var(--cc-button-border, none) on base rule - backdrop-filter: var(--cc-button-backdrop-filter, none) on base - border: var(--cc-button-hover-border, var(--cc-button-border, none)) on hover/focus (chains through so webchat stays borderless) Webchat :root does not set these tokens; all three reads resolve to `none`, keeping webchat buttons byte-identical. In c26 scope the tokens light up (1px solid rgba(255,255,255,0.25) border, blur(4px) filter). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t release
Renders every supported <Message> variant (core layouts + all demo-page
tabs) against the branch's built dist/ and the latest published
@cognigy/chat-components, and asserts the normalized DOM matches. Guards
against silent regressions in the default webchat layout consumers
depend on.
Runs as its own GitHub Action ("DOM Compatibility") so a break shows as
a distinct PR check. The baseline is resolved at CI time via `npm view`
so we never drift against a stale pin. Excluded from the default `npm
test` because it requires a dist/ build and the dynamically-installed
alias.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
db91b9d to
b901373
Compare
…y button polish Nested-bubble dedup: - Neutralize plugin-internal .chat-bubble in c26 scope (bg transparent, border/padding/max-width/radius/shadow zeroed). Outer C26Layout .bubble owns chrome. - Move asymmetric-corner tail (bot: bottom-left, user: bottom-right) from .chat-bubble to outer .bubble via role-scoped selectors. - Bump override specificity to (0,3,0) via [data-layout="c26"][data-source] to beat article:global(.bot) .bubble (0,2,1) from ChatBubble.module.css. Quick-reply button polish: - Parameterize TextWithButtons.module.css .buttons (it had its own hardcoded align-items/margin-top/max-width that overrode ActionButtons.module.css tokens; now reads --cc-buttons-*). - Split ul.buttons margin-block into margin-block-start (token) + margin-block-end (0) so the c26 margin-top token is not zeroed by the higher-specificity ul.buttons rule. - Parameterize ul.buttons li with --cc-button-flex + --cc-button-min-width so flex:1 1 0 + min-width:0 propagates through the LI wrapper, yielding equal-width buttons. - Add --cc-button-width (100%) so buttons fill their LI. - Consolidate button flex shorthand into a single --cc-button-flex token. - Add --cc-buttons-align-items (stretch in c26). - Tune token defaults for c26: button min-height 1.75rem (Tailwind h-7 28px — UCL spacing scale jumps 24→32, no native 28), min-width 0, buttons-gap 0.375rem (6px), buttons-margin-top --space-2 (8px, matches bubble bottom padding so text→buttons == buttons→bubble-bottom). Tests: +3 new CSS-file-regex assertions. 161/161 pass. Build clean. Webchat untouched — all new tokens fall back to existing hardcoded values at :root. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ibility workflow - eslint.config.js: add a `**/*.mjs` block declaring `globals.node`. Flat config ignores legacy `/* eslint-env node */` directives, so without this `console`/`process` in our install script tripped `no-undef` under CodeQL's ESLint pass (local `npm run lint` only scans .ts/.tsx so it missed this). - scripts/install-dom-compat-baseline.mjs: drop the stale `/* eslint-env node */` comment that no longer does anything. - .github/workflows/dom-compat.yml: drop the single-value matrix. With a matrix GitHub appends "(22.x)" to the PR-check title, which reads as if "22.x" were the release being compared against. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ble shrink-to-fit Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`npx prettier --check .` on CI flagged three whitespace issues in test/layouts/dom-compat.spec.tsx (arrow-body / call-args that fit on a single line). Ran `prettier --write` on the file to fix. No semantic changes; 29/29 dom-compat tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tiles + nav + bullets + no-image) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Cognigy/chat-components into feature/131731-layout-variant-mechanism
…ate :is() + :has() predicates + fix dead declarations) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Abandoning layout variant approach. Starting fresh — c26 will be theme-only. |
8 tasks
kwinto
added a commit
that referenced
this pull request
Apr 28, 2026
…ssage types Pulls in every demo tab the spec previously skipped behind the "requires widgetSettings.config injection" excuse and renames the fixture helper to drop the layout-PR vestige. Coverage growth: 28 → 40 cases (12 new). Each new case was verified end-to-end by reintroducing the perturbation experiment from commit 0f2fed4 (sentinel attribute on `<article>`) — all 40/40 cases now fail under that perturbation, confirming none of the additions is a vacuous empty-vs-empty pass. New cases (each cited from test/demo.tsx): - Adaptive Cards [1] and [2] (was just [0]). - Default Preview x2 — exercises the `enableDefaultPreview` branch. Both fixtures encode "RENDER OK" in `_defaultPreview` and "RENDER WRONG" in `_webchat`, so a regression that flipped channel selection fails the comparison. - xApp Buttons x2 — quick-reply pill (`_default._quickReplies` + `_webchat.quick_replies` with `content_type: "openXApp"`) and template button (`attachment.template_type: "button"` with `type: "openXApp"`). - HTML Sanitization x3 — default tags, `customAllowedHtmlTags: ["p", "strong"]`, and `disableHtmlContentSanitization: true`. Default-config case is already covered by `bot text message`. - Markdown text + borderless text — exercises the `renderMarkdown` and `disableBotOutputBorder` branches inside Text.tsx. - Collated bot follow-up with `prevMessage` — header-suppression path through the matcher's collation rules. Mechanical changes: - `Case` type gains optional `prevMessage`; `assertSameDom` forwards it to both renders symmetrically. - Per-tab widget configs (`defaultPreviewConfig`, `customAllowedTagsConfig`, `sanitizationDisabledConfig`, `renderMarkdownConfig`, `disableBorderConfig`) extracted as named constants rather than inlined per case. - Spec docstring updated to drop the now-obsolete skip list — only "UI Components" (not Message-rendered) and "Streaming messages" (animationState changes DOM over time) remain genuinely out of reach. File rename: `test/fixtures/layout-messages.ts` → `test/fixtures/messages.ts`. The "layout-" prefix was a vestige of the closed PR #242 layout-variant work and read oddly here. New fixtures live alongside the existing source-variant + plugin-payload exports in the renamed file. Verification: tsc --noEmit clean, lint clean, `npm run test` 121/121, `npm run test:dom-compat` 40/40, perturbation experiment 40/40 fail. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
<Message layout="webchat" | "c26">prop (default"webchat"— backward compatible).<Message>body toWebchatLayout; adds newC26Layoutwith optional label + avatar injection slots.theme.cssvia:is([data-layout="c26"])scope. New c26-only internal tokens:--cc-avatar-size,--cc-label-color,--cc-label-icon-size,--cc-font-family.MessagePropswithneversentinels rejects c26-only props (label,avatar) on webchat callers at compile time.Scope
Mechanism only. Detailed c26 styling and Figma-derived token values land in a follow-up PR. Fallbacks marked
/* PLACEHOLDER */intheme.css.Spec:
alu-resources/design-artifacts/specs/2026-04-20-chat-components-layout-variant-spec.mdPlan:
alu-resources/design-artifacts/plans/2026-04-20-chat-components-layout-variant-plan.mdCommits
d4487d6test: webchat layout regression baseline (6 tests)f45b3f7refactor: extract WebchatLayout from Message (mechanical)b9d2d94feat: layout prop + discriminated union types (+ 3 runtime + 4 compile-time TS contract tests)de95389feat: c26 token layer in theme.css via:is([data-layout="c26"])(+ 6 tests)b63cb60feat: C26Layout with label and avatar slots (+ 8 structural tests)dda62fbtest: fullscreen escape + gallery/quick-replies parity (+ 5 tests)Test plan
npm run test— 149/149 pass (18 files)npm run build— dist builds clean;dist/index.d.tsexportsMessageLayout,C26Labelnpm run lint— cleannpx tsc --noEmit— clean<Message layout="c26">into an IP MFE scenario (follow-up PR)Out of scope (follow-up)
cognigy/microfrontends/interaction-panel— separate PRMessageProviderwrap — latent bug documented; current test injects context-free plugin as workaround--cc-text-dark/--cc-text-lightbare-ident fallback bug in:root🤖 Generated with Claude Code