@llumi/design-system 0.1.0 → 1.0.1

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.
@@ -1,7 +1,15 @@
1
+ import { ReferenceElement } from '@floating-ui/dom';
1
2
  import { PropertyValues } from 'lit';
2
3
  import { TailwindElement } from '../../shared/tailwind-element';
3
4
  export declare class LlumiCommentDialog extends TailwindElement {
4
5
  targetElement: HTMLElement | null;
6
+ /**
7
+ * Optional positioning reference that overrides `targetElement` — used for
8
+ * text-selection comments, where the dialog must anchor to the selected
9
+ * range's rect rather than the whole (potentially tall) selectable element.
10
+ * A floating-ui virtual element (`{ getBoundingClientRect() }`) is accepted.
11
+ */
12
+ anchor: ReferenceElement | null;
5
13
  value: string;
6
14
  private floating;
7
15
  private cleanup?;
@@ -2,16 +2,19 @@ import { CustomTarget } from './custom-target.utils';
2
2
  import { ReviewResult } from './review.type';
3
3
  /**
4
4
  * `<llumi-review>` — wraps light-DOM content for element- and text-selection
5
- * review comments. Both events carry a `ReviewResult` detail and are composed.
5
+ * review comments. Both events bubble and are composed.
6
6
  *
7
- * @fires llumi-review-change - On every edit (comment added/edited/deleted, or overall comment changed).
8
- * @fires llumi-review-submit - When the user clicks Submit / Approve.
7
+ * @attr {string} persist - When set to a non-empty value, persists the review draft to
8
+ * localStorage under that key and restores it on load. Read once on connect.
9
+ * @fires llumi-review-change - On every edit (comment added/edited/deleted, or overall comment changed). `detail` is a `ReviewResult`.
10
+ * @fires llumi-review-submit - When the user clicks Submit / Approve. `detail` is `{ result: ReviewResult, clearPersisted: () => void }`; call `clearPersisted()` after a confirmed server save to discard the persisted draft.
9
11
  */
10
12
  export declare class LlumiReview extends HTMLElement {
11
13
  static observedAttributes: string[];
12
14
  initialData?: ReviewResult;
13
15
  customTargets?: CustomTarget[];
14
16
  private actor;
17
+ private persistence;
15
18
  private manager;
16
19
  private rangeMap;
17
20
  private hoveredComment;
@@ -19,15 +22,22 @@ export declare class LlumiReview extends HTMLElement {
19
22
  private selectionComments;
20
23
  private bar;
21
24
  private commentDialog;
25
+ private commentDialogAnchorId;
22
26
  private overallDialog;
23
27
  private icons;
24
28
  private get shortcut();
25
29
  private get barPosition();
26
30
  private get defaultMode();
31
+ private get persistKey();
27
32
  connectedCallback(): void;
28
33
  disconnectedCallback(): void;
29
34
  attributeChangedCallback(): void;
30
- private emitResult;
35
+ private buildDetailResult;
36
+ private emitChange;
37
+ private emitSubmit;
38
+ /** Clears the persisted draft for this element. No-op when persistence is off. */
39
+ clearPersisted(): void;
40
+ private selectionAnchor;
31
41
  private mountChrome;
32
42
  private onIconClick;
33
43
  private syncFromSnapshot;
@@ -1,3 +1,4 @@
1
+ import { ReviewPersistence } from './review.persistence';
1
2
  import { ReviewComment, ReviewResult, SelectionRange } from './review.type';
2
3
  export interface HighlightCallbacks {
3
4
  activate: (commentedIds: Set<string>) => void;
@@ -16,6 +17,7 @@ type ReviewMachineContext = {
16
17
  shortcut: string;
17
18
  defaultMode: "idle" | "annotating";
18
19
  highlights: HighlightCallbacks;
20
+ persistence: ReviewPersistence;
19
21
  };
20
22
  type ReviewMachineEvents = {
21
23
  type: "TOGGLE";
@@ -61,6 +63,7 @@ type ReviewMachineInput = {
61
63
  initialData?: ReviewResult;
62
64
  defaultMode: "idle" | "annotating";
63
65
  highlights: HighlightCallbacks;
66
+ persistence: ReviewPersistence;
64
67
  };
65
68
  export declare function buildReviewResult(context: Pick<ReviewMachineContext, "comments" | "overallComment">): ReviewResult;
66
69
  export declare function createReviewMachine(): import('xstate').StateMachine<ReviewMachineContext, {
@@ -136,6 +139,9 @@ export declare function createReviewMachine(): import('xstate').StateMachine<Rev
136
139
  } | {
137
140
  type: "emitChanged";
138
141
  params: import('xstate').NonReducibleUnknown;
142
+ } | {
143
+ type: "persistSave";
144
+ params: unknown;
139
145
  } | {
140
146
  type: "emitSubmitted";
141
147
  params: import('xstate').NonReducibleUnknown;
@@ -0,0 +1,16 @@
1
+ import { ReviewResult } from './review.type';
2
+ /**
3
+ * Storage engine for `<llumi-review>` drafts. Injected into the review machine
4
+ * via input (mirrors `HighlightCallbacks`). All access is best-effort: it never
5
+ * throws into the component.
6
+ */
7
+ export interface ReviewPersistence {
8
+ /** Read + parse + validate. Returns undefined on miss or corruption. */
9
+ load(): ReviewResult | undefined;
10
+ /** Write JSON. An empty/`approved` result removes the key instead. */
11
+ save(result: ReviewResult): void;
12
+ /** Remove the stored draft. */
13
+ clear(): void;
14
+ }
15
+ export declare const noopPersistence: ReviewPersistence;
16
+ export declare function createReviewPersistence(key: string): ReviewPersistence;
@@ -18,6 +18,11 @@ export type ReviewResult = {
18
18
  comments: ReviewComment[];
19
19
  overallComment?: string;
20
20
  };
21
+ export interface ReviewSubmitDetail {
22
+ result: ReviewResult;
23
+ /** Clears the persisted draft for this element. No-op when persistence is off. */
24
+ clearPersisted: () => void;
25
+ }
21
26
  export type ReviewBarPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
22
27
  export type ReviewMode = "idle" | "commenting" | "editing";
23
28
  /**
package/package.json CHANGED
@@ -1,52 +1,51 @@
1
1
  {
2
- "name": "@llumi/design-system",
3
- "version": "0.1.0",
4
- "type": "module",
5
- "files": [
6
- "dist",
7
- "custom-elements.json"
8
- ],
9
- "sideEffects": [
10
- "**/*.css",
11
- "**/*.js",
12
- "**/*.mjs",
13
- "**/*.cjs"
14
- ],
15
- "exports": {
16
- "./review": {
17
- "types": "./dist/types/components/review/index.d.ts",
18
- "import": "./dist/review.mjs",
19
- "require": "./dist/review.cjs",
20
- "default": "./dist/review.mjs"
21
- },
22
- "./review.mjs": "./dist/review.mjs",
23
- "./review.cjs": "./dist/review.cjs",
24
- "./review.js": "./dist/review.js",
25
- "./review.css": "./dist/review.css",
26
- "./package.json": "./package.json"
27
- },
28
- "scripts": {
29
- "build": "vite build -c vite.lib.config.ts && vite build -c vite.umd.config.ts && cp src/components/review/review.css dist/review.css",
30
- "analyze": "cem analyze --config custom-elements-manifest.config.mjs",
31
- "test:browser": "vitest run",
32
- "prepack": "bun run build && bun run analyze"
33
- },
34
- "dependencies": {
35
- "@floating-ui/dom": "^1.6.13",
36
- "clsx": "^2.1.1",
37
- "lit": "^3.2.1",
38
- "tailwind-merge": "^3.0.2",
39
- "tinykeys": "^3.0.0",
40
- "xstate": "^5.28.0"
41
- },
42
- "devDependencies": {
43
- "@tailwindcss/vite": "^4.1.18",
44
- "@vitest/browser": "^3.0.0",
45
- "playwright": "^1.50.0",
46
- "tailwindcss": "^4.1.18",
47
- "vite": "^6.0.0",
48
- "vite-plugin-dts": "^4.5.0",
49
- "vitest": "^3.0.0"
50
- },
51
- "customElements": "custom-elements.json"
52
- }
2
+ "name": "@llumi/design-system",
3
+ "version": "1.0.1",
4
+ "type": "module",
5
+ "files": [
6
+ "dist",
7
+ "custom-elements.json"
8
+ ],
9
+ "sideEffects": [
10
+ "**/*.css",
11
+ "**/*.js",
12
+ "**/*.mjs",
13
+ "**/*.cjs"
14
+ ],
15
+ "exports": {
16
+ "./review": {
17
+ "types": "./dist/types/components/review/index.d.ts",
18
+ "import": "./dist/review.mjs",
19
+ "require": "./dist/review.cjs",
20
+ "default": "./dist/review.mjs"
21
+ },
22
+ "./review.mjs": "./dist/review.mjs",
23
+ "./review.cjs": "./dist/review.cjs",
24
+ "./review.js": "./dist/review.js",
25
+ "./review.css": "./dist/review.css",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "dependencies": {
29
+ "@floating-ui/dom": "^1.6.13",
30
+ "clsx": "^2.1.1",
31
+ "lit": "^3.2.1",
32
+ "tailwind-merge": "^3.0.2",
33
+ "tinykeys": "^3.0.0",
34
+ "xstate": "^5.28.0"
35
+ },
36
+ "devDependencies": {
37
+ "@tailwindcss/vite": "^4.1.18",
38
+ "@vitest/browser": "^3.0.0",
39
+ "playwright": "^1.50.0",
40
+ "tailwindcss": "^4.1.18",
41
+ "vite": "^6.0.0",
42
+ "vite-plugin-dts": "^4.5.0",
43
+ "vitest": "^3.0.0"
44
+ },
45
+ "customElements": "custom-elements.json",
46
+ "scripts": {
47
+ "build": "vite build -c vite.lib.config.ts && vite build -c vite.umd.config.ts && cp src/components/review/review.css dist/review.css",
48
+ "analyze": "cem analyze --config custom-elements-manifest.config.mjs",
49
+ "test:browser": "vitest run"
50
+ }
51
+ }