@edux-design/comments 0.1.4 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @edux-design/comments
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add mention-aware rich value snapshots, typed composer focus/value/submit controls and external-submit support while preserving the legacy editor element ref and callbacks. Align development with the supported Tiptap 3 peer API.
8
+
9
+ Correct controlled-value echo synchronization so rapid typing retains every character. Keep legacy mention fallbacks and model-visible serialization distinct; type existing Comment compound components and provide structural avatar props without relying on an unpublished dependency type.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+ - @edux-design/buttons@0.3.0
15
+
3
16
  ## 0.1.4
4
17
 
5
18
  ### Patch Changes
package/README.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  Structured comment block for discussion threads, with avatar, metadata, actions, and nested replies.
4
4
 
5
+ ## Token contract
6
+
7
+ Comments use the shared numeric and semantic tokens for reusable spacing and
8
+ colour contracts, including `gap-12`, `p-12`, `py-12`, and the existing focus
9
+ and text tokens. The composer keeps a 120px editor height, 20px editor inset,
10
+ 40px reply offset, and 220px mention-menu minimum width as explicit
11
+ component-owned geometry because the current theme has no matching declared
12
+ tokens; these values are documented one-offs rather than new semantic tokens.
13
+
14
+ The 12px composer padding uses the declared `py-12` token, and the 20px/40px
15
+ values are written explicitly (`pl-[20px]` and `mt-[40px]`) so they do not
16
+ depend on Tailwind's undeclared numeric fallback scale. Consumers should import
17
+ `@edux-design/tokens/theme` so shared utilities resolve consistently.
18
+
5
19
  ## Install
6
20
 
7
21
  ```bash
@@ -101,3 +115,7 @@ override the label if needed.
101
115
  </Comment.Actions>
102
116
  </Comment>
103
117
  ```
118
+
119
+ ## Additional components
120
+
121
+ [Composer values, focus and external submission](./docs/composer.md).
package/dist/index.d.mts CHANGED
@@ -1,53 +1,167 @@
1
- import * as react from 'react';
1
+ import React from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import * as _tiptap_core from '@tiptap/core';
3
4
 
4
- /**
5
- * @typedef {React.HTMLAttributes<HTMLDivElement> & {
6
- * author?: React.ReactNode,
7
- * timestamp?: React.ReactNode,
8
- * avatar?: React.ReactNode,
9
- * avatarName?: string,
10
- * avatarProps?: import("@edux-design/avatars").AvatarProps,
11
- * body?: React.ReactNode,
12
- * replies?: React.ReactNode,
13
- * variant?: "default" | "resolved",
14
- * resolved?: boolean,
15
- * onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void,
16
- * editable?: boolean,
17
- * children?: React.ReactNode,
18
- * }} CommentProps
19
- */
20
- /**
21
- * Flexible comment surface with optional avatar, metadata, actions, and replies.
22
- */
23
- declare const Comment: react.ForwardRefExoticComponent<react.RefAttributes<any>>;
5
+ /** Avatar fields accepted by the comments package's existing Avatar slots. */
6
+ type CommentAvatarProps$1 = React.HTMLAttributes<HTMLSpanElement> & React.ButtonHTMLAttributes<HTMLButtonElement> & {
7
+ name?: string;
8
+ initials?: string;
9
+ src?: string;
10
+ alt?: string;
11
+ size?: "small" | "medium" | "large";
12
+ online?: boolean;
13
+ backgroundColor?: string;
14
+ asButton?: boolean;
15
+ };
24
16
 
25
- /**
26
- * @typedef {React.FormHTMLAttributes<HTMLFormElement> & {
27
- * value?: string,
28
- * onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void,
29
- * onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void,
30
- * onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void,
31
- * placeholder?: string,
32
- * rows?: number,
33
- * disabled?: boolean,
34
- * isSubmitting?: boolean,
35
- * submitLabel?: string,
36
- * cancelLabel?: string,
37
- * avatar?: React.ReactNode,
38
- * avatarProps?: import("@edux-design/avatars").AvatarProps,
39
- * actions?: React.ReactNode,
40
- * children?: React.ReactNode,
41
- * }} CommentComposerProps
42
- */
43
- /**
44
- * Comment composer with avatar, textarea, and action buttons.
45
- */
46
- declare const CommentComposer: react.ForwardRefExoticComponent<react.RefAttributes<any>>;
17
+ declare function CommentMention({ peopleList, onQueryChange }: CommentMentionProps$1): react_jsx_runtime.JSX.Element;
18
+ type CommentMentionPerson$1 = {
19
+ id: string | number;
20
+ name: string;
21
+ handle: string;
22
+ avatarProps?: CommentAvatarProps$1;
23
+ };
24
+ type CommentMentionProps$1 = {
25
+ peopleList?: CommentMentionPerson$1[];
26
+ onQueryChange?: (query: string) => void;
27
+ placeholder?: string;
28
+ };
47
29
 
48
- declare function CommentMention({ peopleList, onQueryChange, }: {
49
- peopleList?: any[];
50
- onQueryChange: any;
51
- }): react_jsx_runtime.JSX.Element;
30
+ declare const CommentComposer: React.ForwardRefExoticComponent<Omit<React.FormHTMLAttributes<HTMLFormElement>, "onChange" | "onSubmit"> & {
31
+ value?: string;
32
+ valueFormat?: "html" | "text";
33
+ richValue?: _tiptap_core.JSONContent;
34
+ onChange?: (event: {
35
+ target: {
36
+ value: string;
37
+ };
38
+ }) => void;
39
+ onValueChange?: (value: CommentComposerValue$1) => void;
40
+ onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
41
+ onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void;
42
+ composerRef?: React.Ref<CommentComposerHandle$1>;
43
+ editorLabel?: string;
44
+ editorAttributes?: Pick<React.HTMLAttributes<HTMLDivElement>, "id" | "aria-describedby" | "aria-invalid" | "aria-required">;
45
+ autoFocus?: boolean;
46
+ externalSubmit?: boolean;
47
+ submitOnModEnter?: boolean;
48
+ placeholder?: string;
49
+ rows?: number;
50
+ disabled?: boolean;
51
+ isSubmitting?: boolean;
52
+ submitLabel?: string;
53
+ submittingLabel?: string;
54
+ cancelLabel?: string;
55
+ avatar?: React.ReactNode;
56
+ avatarProps?: CommentAvatarProps$1;
57
+ actions?: React.ReactNode;
58
+ children?: React.ReactNode;
59
+ } & React.RefAttributes<HTMLDivElement>>;
60
+ type CommentComposerMentionValue$1 = {
61
+ id: string | number | null;
62
+ handle: string;
63
+ label: string;
64
+ };
65
+ type CommentComposerValue$1 = {
66
+ text: string;
67
+ legacyText: string;
68
+ html: string;
69
+ json: _tiptap_core.JSONContent;
70
+ mentions: CommentComposerMentionValue$1[];
71
+ isEmpty: boolean;
72
+ };
73
+ type CommentComposerHandle$1 = {
74
+ focus: (position?: "start" | "end" | "all" | number) => boolean;
75
+ clear: () => boolean;
76
+ getValue: () => CommentComposerValue$1 | null;
77
+ submit: () => void;
78
+ };
79
+ type CommentComposerProps$1 = Omit<React.FormHTMLAttributes<HTMLFormElement>, "onChange" | "onSubmit"> & {
80
+ value?: string;
81
+ valueFormat?: "html" | "text";
82
+ richValue?: _tiptap_core.JSONContent;
83
+ onChange?: (event: {
84
+ target: {
85
+ value: string;
86
+ };
87
+ }) => void;
88
+ onValueChange?: (value: CommentComposerValue$1) => void;
89
+ onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
90
+ onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void;
91
+ composerRef?: React.Ref<CommentComposerHandle$1>;
92
+ editorLabel?: string;
93
+ editorAttributes?: Pick<React.HTMLAttributes<HTMLDivElement>, "id" | "aria-describedby" | "aria-invalid" | "aria-required">;
94
+ autoFocus?: boolean;
95
+ externalSubmit?: boolean;
96
+ submitOnModEnter?: boolean;
97
+ placeholder?: string;
98
+ rows?: number;
99
+ disabled?: boolean;
100
+ isSubmitting?: boolean;
101
+ submitLabel?: string;
102
+ submittingLabel?: string;
103
+ cancelLabel?: string;
104
+ avatar?: React.ReactNode;
105
+ avatarProps?: CommentAvatarProps$1;
106
+ actions?: React.ReactNode;
107
+ children?: React.ReactNode;
108
+ };
52
109
 
53
- export { Comment, CommentComposer, CommentMention };
110
+ declare const Comment: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
111
+ author?: React.ReactNode;
112
+ timestamp?: React.ReactNode;
113
+ avatar?: React.ReactNode;
114
+ avatarName?: string;
115
+ avatarProps?: CommentAvatarProps$1;
116
+ body?: React.ReactNode;
117
+ replies?: React.ReactNode;
118
+ variant?: "default" | "resolved";
119
+ resolved?: boolean;
120
+ onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void;
121
+ editable?: boolean;
122
+ children?: React.ReactNode;
123
+ } & React.RefAttributes<HTMLDivElement>> & {
124
+ Actions: {
125
+ ({ children, className, ...props }: React.ComponentPropsWithRef<"div">): react_jsx_runtime.JSX.Element;
126
+ displayName: string;
127
+ };
128
+ Reply: {
129
+ ({ className, ...props }: React.ComponentPropsWithRef<"button">): react_jsx_runtime.JSX.Element;
130
+ displayName: string;
131
+ };
132
+ Edit: {
133
+ ({ className, ...props }: React.ComponentPropsWithRef<"button">): react_jsx_runtime.JSX.Element;
134
+ displayName: string;
135
+ };
136
+ Resolve: {
137
+ ({ className, disabled, onClick, label, ...props }: React.ComponentPropsWithRef<"button"> & {
138
+ label?: React.ReactNode;
139
+ }): react_jsx_runtime.JSX.Element;
140
+ displayName: string;
141
+ };
142
+ };
143
+ type CommentProps$1 = React.HTMLAttributes<HTMLDivElement> & {
144
+ author?: React.ReactNode;
145
+ timestamp?: React.ReactNode;
146
+ avatar?: React.ReactNode;
147
+ avatarName?: string;
148
+ avatarProps?: CommentAvatarProps$1;
149
+ body?: React.ReactNode;
150
+ replies?: React.ReactNode;
151
+ variant?: "default" | "resolved";
152
+ resolved?: boolean;
153
+ onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void;
154
+ editable?: boolean;
155
+ children?: React.ReactNode;
156
+ };
157
+
158
+ type CommentProps = CommentProps$1;
159
+ type CommentComposerProps = CommentComposerProps$1;
160
+ type CommentComposerHandle = CommentComposerHandle$1;
161
+ type CommentComposerValue = CommentComposerValue$1;
162
+ type CommentComposerMentionValue = CommentComposerMentionValue$1;
163
+ type CommentMentionProps = CommentMentionProps$1;
164
+ type CommentMentionPerson = CommentMentionPerson$1;
165
+ type CommentAvatarProps = CommentAvatarProps$1;
166
+
167
+ export { Comment, type CommentAvatarProps, CommentComposer, type CommentComposerHandle, type CommentComposerMentionValue, type CommentComposerProps, type CommentComposerValue, CommentMention, type CommentMentionPerson, type CommentMentionProps, type CommentProps };
package/dist/index.d.ts CHANGED
@@ -1,53 +1,167 @@
1
- import * as react from 'react';
1
+ import React from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import * as _tiptap_core from '@tiptap/core';
3
4
 
4
- /**
5
- * @typedef {React.HTMLAttributes<HTMLDivElement> & {
6
- * author?: React.ReactNode,
7
- * timestamp?: React.ReactNode,
8
- * avatar?: React.ReactNode,
9
- * avatarName?: string,
10
- * avatarProps?: import("@edux-design/avatars").AvatarProps,
11
- * body?: React.ReactNode,
12
- * replies?: React.ReactNode,
13
- * variant?: "default" | "resolved",
14
- * resolved?: boolean,
15
- * onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void,
16
- * editable?: boolean,
17
- * children?: React.ReactNode,
18
- * }} CommentProps
19
- */
20
- /**
21
- * Flexible comment surface with optional avatar, metadata, actions, and replies.
22
- */
23
- declare const Comment: react.ForwardRefExoticComponent<react.RefAttributes<any>>;
5
+ /** Avatar fields accepted by the comments package's existing Avatar slots. */
6
+ type CommentAvatarProps$1 = React.HTMLAttributes<HTMLSpanElement> & React.ButtonHTMLAttributes<HTMLButtonElement> & {
7
+ name?: string;
8
+ initials?: string;
9
+ src?: string;
10
+ alt?: string;
11
+ size?: "small" | "medium" | "large";
12
+ online?: boolean;
13
+ backgroundColor?: string;
14
+ asButton?: boolean;
15
+ };
24
16
 
25
- /**
26
- * @typedef {React.FormHTMLAttributes<HTMLFormElement> & {
27
- * value?: string,
28
- * onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void,
29
- * onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void,
30
- * onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void,
31
- * placeholder?: string,
32
- * rows?: number,
33
- * disabled?: boolean,
34
- * isSubmitting?: boolean,
35
- * submitLabel?: string,
36
- * cancelLabel?: string,
37
- * avatar?: React.ReactNode,
38
- * avatarProps?: import("@edux-design/avatars").AvatarProps,
39
- * actions?: React.ReactNode,
40
- * children?: React.ReactNode,
41
- * }} CommentComposerProps
42
- */
43
- /**
44
- * Comment composer with avatar, textarea, and action buttons.
45
- */
46
- declare const CommentComposer: react.ForwardRefExoticComponent<react.RefAttributes<any>>;
17
+ declare function CommentMention({ peopleList, onQueryChange }: CommentMentionProps$1): react_jsx_runtime.JSX.Element;
18
+ type CommentMentionPerson$1 = {
19
+ id: string | number;
20
+ name: string;
21
+ handle: string;
22
+ avatarProps?: CommentAvatarProps$1;
23
+ };
24
+ type CommentMentionProps$1 = {
25
+ peopleList?: CommentMentionPerson$1[];
26
+ onQueryChange?: (query: string) => void;
27
+ placeholder?: string;
28
+ };
47
29
 
48
- declare function CommentMention({ peopleList, onQueryChange, }: {
49
- peopleList?: any[];
50
- onQueryChange: any;
51
- }): react_jsx_runtime.JSX.Element;
30
+ declare const CommentComposer: React.ForwardRefExoticComponent<Omit<React.FormHTMLAttributes<HTMLFormElement>, "onChange" | "onSubmit"> & {
31
+ value?: string;
32
+ valueFormat?: "html" | "text";
33
+ richValue?: _tiptap_core.JSONContent;
34
+ onChange?: (event: {
35
+ target: {
36
+ value: string;
37
+ };
38
+ }) => void;
39
+ onValueChange?: (value: CommentComposerValue$1) => void;
40
+ onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
41
+ onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void;
42
+ composerRef?: React.Ref<CommentComposerHandle$1>;
43
+ editorLabel?: string;
44
+ editorAttributes?: Pick<React.HTMLAttributes<HTMLDivElement>, "id" | "aria-describedby" | "aria-invalid" | "aria-required">;
45
+ autoFocus?: boolean;
46
+ externalSubmit?: boolean;
47
+ submitOnModEnter?: boolean;
48
+ placeholder?: string;
49
+ rows?: number;
50
+ disabled?: boolean;
51
+ isSubmitting?: boolean;
52
+ submitLabel?: string;
53
+ submittingLabel?: string;
54
+ cancelLabel?: string;
55
+ avatar?: React.ReactNode;
56
+ avatarProps?: CommentAvatarProps$1;
57
+ actions?: React.ReactNode;
58
+ children?: React.ReactNode;
59
+ } & React.RefAttributes<HTMLDivElement>>;
60
+ type CommentComposerMentionValue$1 = {
61
+ id: string | number | null;
62
+ handle: string;
63
+ label: string;
64
+ };
65
+ type CommentComposerValue$1 = {
66
+ text: string;
67
+ legacyText: string;
68
+ html: string;
69
+ json: _tiptap_core.JSONContent;
70
+ mentions: CommentComposerMentionValue$1[];
71
+ isEmpty: boolean;
72
+ };
73
+ type CommentComposerHandle$1 = {
74
+ focus: (position?: "start" | "end" | "all" | number) => boolean;
75
+ clear: () => boolean;
76
+ getValue: () => CommentComposerValue$1 | null;
77
+ submit: () => void;
78
+ };
79
+ type CommentComposerProps$1 = Omit<React.FormHTMLAttributes<HTMLFormElement>, "onChange" | "onSubmit"> & {
80
+ value?: string;
81
+ valueFormat?: "html" | "text";
82
+ richValue?: _tiptap_core.JSONContent;
83
+ onChange?: (event: {
84
+ target: {
85
+ value: string;
86
+ };
87
+ }) => void;
88
+ onValueChange?: (value: CommentComposerValue$1) => void;
89
+ onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
90
+ onCancel?: (event: React.MouseEvent<HTMLButtonElement>) => void;
91
+ composerRef?: React.Ref<CommentComposerHandle$1>;
92
+ editorLabel?: string;
93
+ editorAttributes?: Pick<React.HTMLAttributes<HTMLDivElement>, "id" | "aria-describedby" | "aria-invalid" | "aria-required">;
94
+ autoFocus?: boolean;
95
+ externalSubmit?: boolean;
96
+ submitOnModEnter?: boolean;
97
+ placeholder?: string;
98
+ rows?: number;
99
+ disabled?: boolean;
100
+ isSubmitting?: boolean;
101
+ submitLabel?: string;
102
+ submittingLabel?: string;
103
+ cancelLabel?: string;
104
+ avatar?: React.ReactNode;
105
+ avatarProps?: CommentAvatarProps$1;
106
+ actions?: React.ReactNode;
107
+ children?: React.ReactNode;
108
+ };
52
109
 
53
- export { Comment, CommentComposer, CommentMention };
110
+ declare const Comment: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
111
+ author?: React.ReactNode;
112
+ timestamp?: React.ReactNode;
113
+ avatar?: React.ReactNode;
114
+ avatarName?: string;
115
+ avatarProps?: CommentAvatarProps$1;
116
+ body?: React.ReactNode;
117
+ replies?: React.ReactNode;
118
+ variant?: "default" | "resolved";
119
+ resolved?: boolean;
120
+ onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void;
121
+ editable?: boolean;
122
+ children?: React.ReactNode;
123
+ } & React.RefAttributes<HTMLDivElement>> & {
124
+ Actions: {
125
+ ({ children, className, ...props }: React.ComponentPropsWithRef<"div">): react_jsx_runtime.JSX.Element;
126
+ displayName: string;
127
+ };
128
+ Reply: {
129
+ ({ className, ...props }: React.ComponentPropsWithRef<"button">): react_jsx_runtime.JSX.Element;
130
+ displayName: string;
131
+ };
132
+ Edit: {
133
+ ({ className, ...props }: React.ComponentPropsWithRef<"button">): react_jsx_runtime.JSX.Element;
134
+ displayName: string;
135
+ };
136
+ Resolve: {
137
+ ({ className, disabled, onClick, label, ...props }: React.ComponentPropsWithRef<"button"> & {
138
+ label?: React.ReactNode;
139
+ }): react_jsx_runtime.JSX.Element;
140
+ displayName: string;
141
+ };
142
+ };
143
+ type CommentProps$1 = React.HTMLAttributes<HTMLDivElement> & {
144
+ author?: React.ReactNode;
145
+ timestamp?: React.ReactNode;
146
+ avatar?: React.ReactNode;
147
+ avatarName?: string;
148
+ avatarProps?: CommentAvatarProps$1;
149
+ body?: React.ReactNode;
150
+ replies?: React.ReactNode;
151
+ variant?: "default" | "resolved";
152
+ resolved?: boolean;
153
+ onResolve?: (event: React.MouseEvent<HTMLButtonElement>) => void;
154
+ editable?: boolean;
155
+ children?: React.ReactNode;
156
+ };
157
+
158
+ type CommentProps = CommentProps$1;
159
+ type CommentComposerProps = CommentComposerProps$1;
160
+ type CommentComposerHandle = CommentComposerHandle$1;
161
+ type CommentComposerValue = CommentComposerValue$1;
162
+ type CommentComposerMentionValue = CommentComposerMentionValue$1;
163
+ type CommentMentionProps = CommentMentionProps$1;
164
+ type CommentMentionPerson = CommentMentionPerson$1;
165
+ type CommentAvatarProps = CommentAvatarProps$1;
166
+
167
+ export { Comment, type CommentAvatarProps, CommentComposer, type CommentComposerHandle, type CommentComposerMentionValue, type CommentComposerProps, type CommentComposerValue, CommentMention, type CommentMentionPerson, type CommentMentionProps, type CommentProps };