@llumi/design-system 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -0
- package/custom-elements.json +996 -0
- package/dist/review.cjs +172 -0
- package/dist/review.css +98 -0
- package/dist/review.js +172 -0
- package/dist/review.mjs +1601 -0
- package/dist/types/components/review/comment-dialog.element.d.ts +21 -0
- package/dist/types/components/review/custom-target.utils.d.ts +16 -0
- package/dist/types/components/review/default-editor.element.d.ts +19 -0
- package/dist/types/components/review/highlight-manager.d.ts +21 -0
- package/dist/types/components/review/index.d.ts +8 -0
- package/dist/types/components/review/overall-comment-dialog.element.d.ts +22 -0
- package/dist/types/components/review/review-bar.element.d.ts +26 -0
- package/dist/types/components/review/review.element.d.ts +50 -0
- package/dist/types/components/review/review.machine.d.ts +228 -0
- package/dist/types/components/review/review.type.d.ts +32 -0
- package/dist/types/components/review/selection-comment-icons.element.d.ts +17 -0
- package/dist/types/components/review/selection-range.utils.d.ts +6 -0
- package/dist/types/components/review/sort-comments.utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/shared/cn.d.ts +2 -0
- package/dist/types/shared/icons.d.ts +7 -0
- package/dist/types/shared/tailwind-element.d.ts +4 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# @llumi/design-system
|
|
2
|
+
|
|
3
|
+
Framework-agnostic Web Components (built with [Lit](https://lit.dev)) for the llumi
|
|
4
|
+
review experience. Wrap any content in `<llumi-review>` and let users attach comments to
|
|
5
|
+
whole elements or to text selections, add an overall comment, and submit an approval or a
|
|
6
|
+
set of comments.
|
|
7
|
+
|
|
8
|
+
- **Hybrid DOM** — your content stays in the light DOM (so text selection, `Range`s, and
|
|
9
|
+
the CSS Custom Highlight API work normally); the review chrome (toolbar, dialogs) renders
|
|
10
|
+
in Shadow DOM with its styles encapsulated.
|
|
11
|
+
- **Drop-in** — works in plain HTML or any framework that can render custom elements.
|
|
12
|
+
- **Per-component** — each component is imported on its own (`@llumi/design-system/review`).
|
|
13
|
+
- **Three builds per component** — ESM (the default import), plus single-file UMD and IIFE
|
|
14
|
+
bundles for `<script>` / CDN use.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun add @llumi/design-system
|
|
20
|
+
# or: npm install @llumi/design-system
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`lit` is pulled in automatically as a dependency — no peer install required.
|
|
24
|
+
|
|
25
|
+
## Quick start (ESM)
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// Registers <llumi-review> and all of its chrome elements.
|
|
29
|
+
// The light-DOM highlight styles are injected automatically on first use —
|
|
30
|
+
// no separate CSS import is required.
|
|
31
|
+
import "@llumi/design-system/review";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<llumi-review default-mode="annotating" bar-position="bottom-center">
|
|
36
|
+
<article>
|
|
37
|
+
<h1 data-review-id="title">Project Proposal</h1>
|
|
38
|
+
<p data-review-selectable="intro">
|
|
39
|
+
Select any of this text to leave a comment on the selection…
|
|
40
|
+
</p>
|
|
41
|
+
</article>
|
|
42
|
+
</llumi-review>
|
|
43
|
+
|
|
44
|
+
<script type="module">
|
|
45
|
+
const review = document.querySelector("llumi-review");
|
|
46
|
+
review.addEventListener("llumi-review-submit", (e) => {
|
|
47
|
+
console.log(e.detail); // ReviewResult
|
|
48
|
+
});
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `<script>` tag (no bundler)
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<!-- unpkg / jsDelivr both resolve the IIFE subpath via the package `exports` field -->
|
|
56
|
+
<script src="https://unpkg.com/@llumi/design-system/review.js"></script>
|
|
57
|
+
<!-- jsDelivr can also take the explicit file path -->
|
|
58
|
+
<script src="https://cdn.jsdelivr.net/npm/@llumi/design-system/dist/review.js"></script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This single file bundles Lit, registers the `<llumi-review>` element, and exposes a `Llumi`
|
|
62
|
+
global. A `require()`-safe UMD/CJS build is also published at `@llumi/design-system/review.cjs`.
|
|
63
|
+
|
|
64
|
+
## Marking up content
|
|
65
|
+
|
|
66
|
+
Inside `<llumi-review>`, annotate the elements you want to be reviewable:
|
|
67
|
+
|
|
68
|
+
| Attribute | Meaning |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `data-review-id="<id>"` | A **whole-element** comment target. Clicking it (in annotate mode) opens a comment dialog and shows a badge when commented. |
|
|
71
|
+
| `data-review-selectable="<id>"` | A region whose **text can be selected** to leave a selection-scoped comment. |
|
|
72
|
+
|
|
73
|
+
An element may carry both attributes. The `<id>` values are yours; they are echoed back in
|
|
74
|
+
each comment's `targetId`.
|
|
75
|
+
|
|
76
|
+
## Component API
|
|
77
|
+
|
|
78
|
+
### Attributes
|
|
79
|
+
|
|
80
|
+
| Attribute | Type | Default | Description |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| `bar-position` | `top-left` \| `top-center` \| `top-right` \| `bottom-left` \| `bottom-center` \| `bottom-right` | `bottom-center` | Initial corner for the floating toolbar (which is also draggable). |
|
|
83
|
+
| `shortcut` | string ([tinykeys](https://github.com/jamiebuilds/tinykeys) syntax) | `$mod+Shift+M` | Keyboard shortcut that toggles annotate mode. |
|
|
84
|
+
| `default-mode` | `idle` \| `annotating` | `idle` | Whether annotate mode is on at mount. |
|
|
85
|
+
|
|
86
|
+
### Properties (set in JS — complex values)
|
|
87
|
+
|
|
88
|
+
| Property | Type | Description |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| `initialData` | `ReviewResult` | Pre-populate existing comments / overall comment. |
|
|
91
|
+
| `customTargets` | `CustomTarget[]` | Resolve comment targets from arbitrary selectors (advanced). |
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const review = document.querySelector("llumi-review");
|
|
95
|
+
review.initialData = {
|
|
96
|
+
status: "commented",
|
|
97
|
+
comments: [{ commentId: "c1", targetId: "title", content: "Tighten this", createdAt: new Date().toISOString() }],
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Events
|
|
102
|
+
|
|
103
|
+
Both are `CustomEvent<ReviewResult>` and bubble (composed):
|
|
104
|
+
|
|
105
|
+
| Event | Fires |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `llumi-review-change` | On every edit (comment added/edited/deleted, overall comment changed). |
|
|
108
|
+
| `llumi-review-submit` | When the user clicks Submit / Approve. |
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
type ReviewResult =
|
|
112
|
+
| { status: "approved" }
|
|
113
|
+
| { status: "commented"; comments: ReviewComment[]; overallComment?: string };
|
|
114
|
+
|
|
115
|
+
interface ReviewComment {
|
|
116
|
+
commentId: string;
|
|
117
|
+
targetId: string; // the data-review-id / data-review-selectable value
|
|
118
|
+
content: string;
|
|
119
|
+
createdAt: string; // ISO timestamp
|
|
120
|
+
selection?: { // present for text-selection comments
|
|
121
|
+
startOffset: number;
|
|
122
|
+
endOffset: number;
|
|
123
|
+
selectedText: string;
|
|
124
|
+
matchIndex: number;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Comments in the result are ordered by their position in the document.
|
|
130
|
+
|
|
131
|
+
### Keyboard shortcuts
|
|
132
|
+
|
|
133
|
+
| Keys | Action |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| `$mod+Shift+M` (configurable) | Toggle annotate mode |
|
|
136
|
+
| Hold `Alt` | Temporarily reveal all targets while held |
|
|
137
|
+
| `Escape` / `$mod+Enter` | Close the open dialog |
|
|
138
|
+
| `$mod+Shift+Backspace` | Delete the comment being edited |
|
|
139
|
+
|
|
140
|
+
(`$mod` is ⌘ on macOS, Ctrl elsewhere.)
|
|
141
|
+
|
|
142
|
+
## Custom comment editor
|
|
143
|
+
|
|
144
|
+
The default editor is an auto-growing textarea. To supply your own, slot an element into
|
|
145
|
+
the comment dialog's `editor` slot. Your element receives the current text via a `value`
|
|
146
|
+
property and must emit these `CustomEvent`s (bubbling + composed):
|
|
147
|
+
|
|
148
|
+
- `change` — `detail` is the new string value
|
|
149
|
+
- `cancel` — request to close the dialog
|
|
150
|
+
- `delete` — request to delete the comment
|
|
151
|
+
|
|
152
|
+
```html
|
|
153
|
+
<llumi-comment-dialog>
|
|
154
|
+
<my-rich-editor slot="editor"></my-rich-editor>
|
|
155
|
+
</llumi-comment-dialog>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Styling & customization
|
|
159
|
+
|
|
160
|
+
No CSS setup is required. The chrome (toolbar, dialogs) ships its Tailwind styles inside
|
|
161
|
+
each element's Shadow DOM, and the light-DOM highlight styles are injected into the
|
|
162
|
+
document automatically when a `<llumi-review>` connects.
|
|
163
|
+
|
|
164
|
+
To theme the highlight outlines, selection colors, and z-index, override these CSS custom
|
|
165
|
+
properties. Set them on `llumi-review` (or any ancestor of your content) so they reliably
|
|
166
|
+
override the injected defaults via inheritance:
|
|
167
|
+
|
|
168
|
+
```css
|
|
169
|
+
llumi-review {
|
|
170
|
+
/* whole-element outlines */
|
|
171
|
+
--review-highlight-commented-color: oklch(0.7 0 0 / 0.3);
|
|
172
|
+
--review-highlight-editing-color: oklch(0.6 0 0 / 0.7);
|
|
173
|
+
/* text-selection highlights */
|
|
174
|
+
--review-selection-commented-color: oklch(0.85 0.08 250 / 0.4);
|
|
175
|
+
--review-selection-editing-color: oklch(0.75 0.12 250 / 0.6);
|
|
176
|
+
--review-selection-hover-color: oklch(0.8 0.1 250 / 0.5);
|
|
177
|
+
/* stacking */
|
|
178
|
+
--review-z-index: 9998;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
All `--review-*` variables defined in the injected stylesheet are overridable this way.
|
|
183
|
+
|
|
184
|
+
## Package exports
|
|
185
|
+
|
|
186
|
+
| Specifier | Build |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `@llumi/design-system/review` | The review component — resolves to ESM on `import`, CJS on `require` (the default entry) |
|
|
189
|
+
| `@llumi/design-system/review.mjs` | ESM bundle (explicit) |
|
|
190
|
+
| `@llumi/design-system/review.cjs` | UMD / CJS bundle, `require()`-safe (Lit included) |
|
|
191
|
+
| `@llumi/design-system/review.js` | IIFE bundle, `Llumi` global (Lit included) |
|
|
192
|
+
| `@llumi/design-system/review.css` | Light-DOM highlight styles — optional; only needed to preload them (e.g. SSR / avoid a first-paint flash), since they're otherwise auto-injected |
|
|
193
|
+
|
|
194
|
+
## Known limitation
|
|
195
|
+
|
|
196
|
+
Selection highlights use the document-global CSS Custom Highlight API with fixed names, so
|
|
197
|
+
only one active `<llumi-review>` paints selection highlights on the page at a time (this
|
|
198
|
+
matches the original React component). Whole-element highlights and everything else work
|
|
199
|
+
with multiple instances.
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
bun install
|
|
205
|
+
bun run storybook # interactive dev/docs harness
|
|
206
|
+
bun test # logic tests (XState machine, utilities)
|
|
207
|
+
bun run test:browser # component/DOM tests (Vitest + Playwright)
|
|
208
|
+
bun run build # ESM + UMD + IIFE
|
|
209
|
+
bun run ci # full gate: lint, types, tests, manifest, build
|
|
210
|
+
```
|