Skip to content

Commit c9cb075

Browse files
authored
fix(channels): retain mention styling and Quill guidance
Restore the production-safe mention presentation and the local Quill development skill from the source work. Context generation remains provided by the implementation already merged on main. Generated-By: PostHog Code Task-Id: 87a79e23-20c4-440b-818b-28154924ffbc
1 parent b35e918 commit c9cb075

5 files changed

Lines changed: 134 additions & 4 deletions

File tree

.claude/skills/quill-code/SKILL.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
name: quill-code
3+
description: Edit the @posthog/quill design system locally and consume the change in this repo (posthog-code) before it is published to npm. Use when changing quill components/primitives/tokens, when a quill change must be tested inside the Code app, or when the user mentions quill, the design system, the .local-quill tarball, or the @posthog/quill pnpm override.
4+
---
5+
6+
# quill-code
7+
8+
`@posthog/quill` is **not** in this repo. It is a published catalog dependency whose
9+
source lives in the main PostHog monorepo at `../posthog/packages/quill`. To test an
10+
unpublished quill change inside this repo (posthog-code), you build quill, pack it to a
11+
tarball, and point a pnpm `overrides` entry at that tarball. This is a **temporary
12+
local-dev** state — revert before merging (see below).
13+
14+
## Quill layout (where to edit)
15+
16+
`../posthog/packages/quill` is the **workspace** (`@posthog/quill-workspace`). It
17+
contains sub-packages, each a layer of the design system:
18+
19+
- `packages/primitives/src` — base components (Card, Badge, Button, Progress, …)
20+
- `packages/components/src` — composed components (DataTable, DateTimePicker, Metric)
21+
- `packages/blocks/src`**product-level blocks** (e.g. `ExperimentCard`). Add the
22+
file here and export it from `packages/blocks/src/index.ts`.
23+
- `packages/quill/src` — the **aggregate** that re-exports all layers as `@posthog/quill`.
24+
25+
A new export in any sub-package flows to `@posthog/quill` automatically on build.
26+
27+
## The loop (every quill change)
28+
29+
1. Edit/add the component in the right sub-package (above) and export it from that
30+
package's `src/index.ts`.
31+
2. Re-sync into this repo manually — build → pack → point the override → reinstall:
32+
33+
```bash
34+
QUILL_DIR="${QUILL_DIR:-../posthog/packages/quill/packages/quill}"
35+
36+
# a. Build the WHOLE quill workspace (two levels up from the aggregate), so the
37+
# sub-packages rebuild BEFORE the aggregate bundles them.
38+
( cd "$QUILL_DIR/../.." && pnpm build )
39+
40+
# b. Pack into .local-quill/ under a UNIQUE filename. pnpm pins a tarball by
41+
# integrity, so a stable name caches stale across re-syncs — drop old local
42+
# tarballs first, then rename the packed file to a unique local name.
43+
rm -f .local-quill/posthog-quill-local-*.tgz
44+
( cd "$QUILL_DIR" && npm pack --pack-destination "$(git rev-parse --show-toplevel)/.local-quill" )
45+
mv .local-quill/posthog-quill-[0-9]*.tgz ".local-quill/posthog-quill-local-$(git rev-parse --short HEAD)-$$.tgz"
46+
47+
# c. Point the override at the new tarball, then reinstall.
48+
# Edit pnpm-workspace.yaml so overrides['@posthog/quill'] = file:./.local-quill/<new file>
49+
pnpm install
50+
```
51+
52+
> Building only the aggregate (`packages/quill/packages/quill`) re-bundles the
53+
> sub-packages' **stale** `dist/`, so edits to primitives/components/blocks are
54+
> silently dropped. Always build at the workspace root.
55+
3. Verify in the Code app (`pnpm dev`, or the `test-electron-app` skill). Repeat from 1.
56+
57+
After every quill edit you **must** re-run the sync — the app consumes the tarball, not
58+
the quill source, so unsynced edits are invisible here.
59+
60+
If quill lives elsewhere, set `QUILL_DIR=/abs/path/to/posthog/packages/quill/packages/quill`.
61+
62+
## Why a tarball, not `link:`
63+
64+
`link:` symlinks into the mono's `node_modules` and drags in its **React 18** types,
65+
colliding with this repo's **React 19** (dual-React → broken typecheck +
66+
invalid-hook-call at runtime). The tarball is copied into this repo's store and deduped
67+
against React 19. The filename is **content-hashed** because pnpm pins a tarball by
68+
integrity, so a stable filename gets cached stale across re-syncs.
69+
70+
## The override (what the script rewrites)
71+
72+
In `pnpm-workspace.yaml`, under `overrides:`:
73+
74+
```yaml
75+
'@posthog/quill': file:./.local-quill/posthog-quill-local-<hash>.tgz
76+
```
77+
78+
There is also a permanent pin you should leave alone:
79+
80+
```yaml
81+
'@posthog/quill>@base-ui/react': ^1.3.0 # quill ships a broken catalog: dep; do not remove
82+
```
83+
84+
## Reverting (before merge)
85+
86+
The override is local-dev only. Once the quill change is published to npm:
87+
88+
1. Bump the catalog version in `pnpm-workspace.yaml` (`'@posthog/quill': 0.3.0-beta.x`)
89+
to the published version.
90+
2. Restore the override line to point back at the catalog, or remove the `file:` override.
91+
3. `pnpm install`.
92+
93+
Do not commit a `file:./.local-quill/...` override or the `.local-quill/` tarballs.

packages/ui/src/features/canvas/components/MentionComposer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Placeholder from "@tiptap/extension-placeholder";
1313
import { EditorContent, useEditor } from "@tiptap/react";
1414
import StarterKit from "@tiptap/starter-kit";
1515
import { type ReactNode, useEffect, useRef, useState } from "react";
16+
import "./mention-chip.css";
1617
import "./mention-composer.css";
1718

1819
interface MentionComposerProps {
@@ -31,7 +32,7 @@ interface MentionComposerProps {
3132
}
3233

3334
/** Styled like the chips MentionText renders on sent messages. */
34-
const MENTION_CHIP_CLASS = "rounded px-0.5 font-medium text-[var(--accent-11)]";
35+
const MENTION_CHIP_CLASS = "mention-chip";
3536

3637
// Padding lives on the editable element (not the input-group control) so a
3738
// click anywhere in the box focuses the editor.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Theme } from "@radix-ui/themes";
2+
import { render, screen } from "@testing-library/react";
3+
import { describe, expect, it } from "vitest";
4+
import { MentionText } from "./MentionText";
5+
6+
describe("MentionText", () => {
7+
it("uses the shared mention styles and emphasizes the current user", () => {
8+
render(
9+
<Theme>
10+
<MentionText
11+
content="@[Alice](alice@example.com) and @[Bob](bob@example.com)"
12+
currentUserEmail="bob@example.com"
13+
/>
14+
</Theme>,
15+
);
16+
17+
expect(screen.getByText("@Alice")).toHaveClass("mention-chip");
18+
expect(screen.getByText("@Alice")).not.toHaveClass("mention-chip--self");
19+
expect(screen.getByText("@Bob")).toHaveClass(
20+
"mention-chip",
21+
"mention-chip--self",
22+
);
23+
});
24+
});

packages/ui/src/features/canvas/components/MentionText.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { splitMentionSegments } from "@posthog/shared";
22
import { splitLinkSegments } from "@posthog/ui/features/canvas/utils/linkify";
33
import { Text } from "@radix-ui/themes";
44
import { Fragment, useMemo } from "react";
5+
import "./mention-chip.css";
56

67
type RenderSegment =
78
| { type: "text"; text: string }
@@ -11,8 +12,7 @@ type RenderSegment =
1112
// The plain (not-the-viewer) mention chip look, also used by surfaces that
1213
// render a mention-styled name without real mention semantics (e.g. the
1314
// channel feed's "started a new task" row).
14-
export const mentionChipClass =
15-
"rounded px-0.5 font-medium text-[var(--accent-11)]";
15+
export const mentionChipClass = "mention-chip";
1616

1717
/**
1818
* Thread message content with inline mention tokens rendered as highlighted
@@ -60,7 +60,7 @@ export function MentionText({
6060
key={key}
6161
className={
6262
selfEmail && segment.email.toLowerCase() === selfEmail
63-
? "rounded bg-[var(--accent-a4)] px-0.5 font-medium text-[var(--accent-12)]"
63+
? `${mentionChipClass} mention-chip--self`
6464
: mentionChipClass
6565
}
6666
title={segment.email}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.mention-chip {
2+
border-radius: var(--radius-1);
3+
background: color-mix(in oklab, var(--primary) 10%, transparent);
4+
color: color-mix(in oklab, var(--primary) 80%, transparent);
5+
font-weight: 500;
6+
padding-inline: 0.125rem;
7+
}
8+
9+
.mention-chip--self {
10+
background: color-mix(in oklab, var(--primary) 50%, transparent);
11+
color: var(--primary);
12+
}

0 commit comments

Comments
 (0)