hive-react-kit 0.5.1 → 0.5.4

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 CHANGED
@@ -65,6 +65,10 @@ import type { Video, Comment, Wallet as WalletType } from 'hive-react-kit/types'
65
65
  - **CommunityMembers** - Community members list
66
66
  - **CommunityTeam** - Community team members
67
67
 
68
+ ### Composer Components
69
+
70
+ - **PostComposer** - Rich markdown composer with live preview (@snapie/renderer), image/audio/video upload, paste & drag-drop, GIF search, emoji picker (500+, 9 categories), template picker, code blocks with copy, and @ mention. See [PostComposer docs](docs/PostComposer.md)
71
+
68
72
  ### Modal Components
69
73
 
70
74
  - **CommentsModal** - Comments display modal
@@ -94,6 +98,8 @@ import { UserDetailProfile } from 'hive-react-kit';
94
98
  ecencyToken="your-ecency-token"
95
99
  threeSpeakApiKey="your-3speak-api-key"
96
100
  giphyApiKey="your-giphy-api-key"
101
+ templateToken="your-jwt-token"
102
+ templateApiBaseUrl="https://your-api.com/data/templates"
97
103
  onBack={() => navigate(-1)}
98
104
  onFollow={(user) => console.log("Follow:", user)}
99
105
  onUnfollow={(user) => console.log("Unfollow:", user)}
@@ -118,9 +124,11 @@ import { UserDetailProfile } from 'hive-react-kit';
118
124
  | `showBackButton` | `boolean` | `false` | Show back arrow in header |
119
125
  | `onBack` | `() => void` | - | Callback when back button is clicked |
120
126
  | `tabShown` | `TabType[]` | all tabs | Controls which tabs are visible and their order. Only listed tabs are shown. First tab is the default active tab. If omitted, all 12 tabs are shown in default order |
121
- | `ecencyToken` | `string` | `undefined` | Ecency image hosting token. Enables image upload and video thumbnail upload in the comment composer. When not provided, the image upload button is hidden |
122
- | `threeSpeakApiKey` | `string` | `undefined` | 3Speak API key. Enables audio recording/upload and video upload in the comment composer. When not provided, audio and video buttons are hidden |
123
- | `giphyApiKey` | `string` | `undefined` | GIPHY API key. Enables GIF search in the comment composer. When not provided, the GIF button is hidden |
127
+ | `ecencyToken` | `string` | `undefined` | Ecency image hosting token. Enables image upload, video thumbnail upload, and paste/drag-drop image upload. Hidden when not provided |
128
+ | `threeSpeakApiKey` | `string` | `undefined` | 3Speak API key. Enables audio recording/upload and video upload (TUS protocol). Hidden when not provided |
129
+ | `giphyApiKey` | `string` | `undefined` | GIPHY API key. Enables GIF search. Hidden when not provided |
130
+ | `templateToken` | `string` | `undefined` | HReplier API JWT token. Enables template picker. Hidden when not provided |
131
+ | `templateApiBaseUrl` | `string` | `https://hreplier-api...` | Custom template API endpoint. Override when self-hosting |
124
132
 
125
133
  **Social Action Callbacks**
126
134
 
package/dist/build.css CHANGED
@@ -82,6 +82,7 @@
82
82
  --color-gray-700: oklch(37.3% 0.034 259.733);
83
83
  --color-gray-800: oklch(27.8% 0.033 256.848);
84
84
  --color-gray-900: oklch(21% 0.034 264.665);
85
+ --color-gray-950: oklch(13% 0.028 261.692);
85
86
  --color-black: #000;
86
87
  --color-white: #fff;
87
88
  --spacing: 0.25rem;
@@ -386,6 +387,9 @@
386
387
  .left-2 {
387
388
  left: calc(var(--spacing) * 2);
388
389
  }
390
+ .left-2\.5 {
391
+ left: calc(var(--spacing) * 2.5);
392
+ }
389
393
  .left-3 {
390
394
  left: calc(var(--spacing) * 3);
391
395
  }
@@ -449,6 +453,9 @@
449
453
  .m-2 {
450
454
  margin: calc(var(--spacing) * 2);
451
455
  }
456
+ .mx-1 {
457
+ margin-inline: calc(var(--spacing) * 1);
458
+ }
452
459
  .mx-2 {
453
460
  margin-inline: calc(var(--spacing) * 2);
454
461
  }
@@ -656,6 +663,9 @@
656
663
  .h-\[90vh\] {
657
664
  height: 90vh;
658
665
  }
666
+ .h-\[400px\] {
667
+ height: 400px;
668
+ }
659
669
  .h-auto {
660
670
  height: auto;
661
671
  }
@@ -671,9 +681,6 @@
671
681
  .max-h-20 {
672
682
  max-height: calc(var(--spacing) * 20);
673
683
  }
674
- .max-h-60 {
675
- max-height: calc(var(--spacing) * 60);
676
- }
677
684
  .max-h-64 {
678
685
  max-height: calc(var(--spacing) * 64);
679
686
  }
@@ -707,6 +714,9 @@
707
714
  .max-h-screen {
708
715
  max-height: 100vh;
709
716
  }
717
+ .min-h-0 {
718
+ min-height: calc(var(--spacing) * 0);
719
+ }
710
720
  .min-h-\[60px\] {
711
721
  min-height: 60px;
712
722
  }
@@ -812,6 +822,9 @@
812
822
  .w-full {
813
823
  width: 100%;
814
824
  }
825
+ .w-px {
826
+ width: 1px;
827
+ }
815
828
  .max-w-2xl {
816
829
  max-width: var(--container-2xl);
817
830
  }
@@ -1173,6 +1186,10 @@
1173
1186
  border-left-style: var(--tw-border-style);
1174
1187
  border-left-width: 4px;
1175
1188
  }
1189
+ .border-dashed {
1190
+ --tw-border-style: dashed;
1191
+ border-style: dashed;
1192
+ }
1176
1193
  .border-amber-700\/40 {
1177
1194
  border-color: color-mix(in srgb, oklch(55.5% 0.163 48.998) 40%, transparent);
1178
1195
  @supports (color: color-mix(in lab, red, red)) {
@@ -1335,15 +1352,33 @@
1335
1352
  .bg-blue-600 {
1336
1353
  background-color: var(--color-blue-600);
1337
1354
  }
1355
+ .bg-blue-600\/20 {
1356
+ background-color: color-mix(in srgb, oklch(54.6% 0.245 262.881) 20%, transparent);
1357
+ @supports (color: color-mix(in lab, red, red)) {
1358
+ background-color: color-mix(in oklab, var(--color-blue-600) 20%, transparent);
1359
+ }
1360
+ }
1338
1361
  .bg-blue-900 {
1339
1362
  background-color: var(--color-blue-900);
1340
1363
  }
1364
+ .bg-blue-900\/10 {
1365
+ background-color: color-mix(in srgb, oklch(37.9% 0.146 265.522) 10%, transparent);
1366
+ @supports (color: color-mix(in lab, red, red)) {
1367
+ background-color: color-mix(in oklab, var(--color-blue-900) 10%, transparent);
1368
+ }
1369
+ }
1341
1370
  .bg-blue-900\/20 {
1342
1371
  background-color: color-mix(in srgb, oklch(37.9% 0.146 265.522) 20%, transparent);
1343
1372
  @supports (color: color-mix(in lab, red, red)) {
1344
1373
  background-color: color-mix(in oklab, var(--color-blue-900) 20%, transparent);
1345
1374
  }
1346
1375
  }
1376
+ .bg-blue-900\/30 {
1377
+ background-color: color-mix(in srgb, oklch(37.9% 0.146 265.522) 30%, transparent);
1378
+ @supports (color: color-mix(in lab, red, red)) {
1379
+ background-color: color-mix(in oklab, var(--color-blue-900) 30%, transparent);
1380
+ }
1381
+ }
1347
1382
  .bg-blue-900\/40 {
1348
1383
  background-color: color-mix(in srgb, oklch(37.9% 0.146 265.522) 40%, transparent);
1349
1384
  @supports (color: color-mix(in lab, red, red)) {
@@ -1392,6 +1427,12 @@
1392
1427
  .bg-gray-800 {
1393
1428
  background-color: var(--color-gray-800);
1394
1429
  }
1430
+ .bg-gray-800\/50 {
1431
+ background-color: color-mix(in srgb, oklch(27.8% 0.033 256.848) 50%, transparent);
1432
+ @supports (color: color-mix(in lab, red, red)) {
1433
+ background-color: color-mix(in oklab, var(--color-gray-800) 50%, transparent);
1434
+ }
1435
+ }
1395
1436
  .bg-gray-800\/95 {
1396
1437
  background-color: color-mix(in srgb, oklch(27.8% 0.033 256.848) 95%, transparent);
1397
1438
  @supports (color: color-mix(in lab, red, red)) {
@@ -1413,6 +1454,9 @@
1413
1454
  background-color: color-mix(in oklab, var(--color-gray-900) 80%, transparent);
1414
1455
  }
1415
1456
  }
1457
+ .bg-gray-950 {
1458
+ background-color: var(--color-gray-950);
1459
+ }
1416
1460
  .bg-green-100 {
1417
1461
  background-color: var(--color-green-100);
1418
1462
  }
@@ -1718,6 +1762,9 @@
1718
1762
  .pr-10 {
1719
1763
  padding-right: calc(var(--spacing) * 10);
1720
1764
  }
1765
+ .pb-1 {
1766
+ padding-bottom: calc(var(--spacing) * 1);
1767
+ }
1721
1768
  .pb-2 {
1722
1769
  padding-bottom: calc(var(--spacing) * 2);
1723
1770
  }
@@ -1742,6 +1789,9 @@
1742
1789
  .pl-6 {
1743
1790
  padding-left: calc(var(--spacing) * 6);
1744
1791
  }
1792
+ .pl-8 {
1793
+ padding-left: calc(var(--spacing) * 8);
1794
+ }
1745
1795
  .pl-10 {
1746
1796
  padding-left: calc(var(--spacing) * 10);
1747
1797
  }
@@ -2002,6 +2052,9 @@
2002
2052
  .capitalize {
2003
2053
  text-transform: capitalize;
2004
2054
  }
2055
+ .normal-case {
2056
+ text-transform: none;
2057
+ }
2005
2058
  .uppercase {
2006
2059
  text-transform: uppercase;
2007
2060
  }
@@ -2057,6 +2110,10 @@
2057
2110
  --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2058
2111
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2059
2112
  }
2113
+ .ring-1 {
2114
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2115
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2116
+ }
2060
2117
  .ring-2 {
2061
2118
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2062
2119
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -2067,6 +2124,9 @@
2067
2124
  --tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 10%, transparent) var(--tw-shadow-alpha), transparent);
2068
2125
  }
2069
2126
  }
2127
+ .ring-blue-500 {
2128
+ --tw-ring-color: var(--color-blue-500);
2129
+ }
2070
2130
  .ring-gray-200 {
2071
2131
  --tw-ring-color: var(--color-gray-200);
2072
2132
  }
@@ -2167,6 +2227,13 @@
2167
2227
  }
2168
2228
  }
2169
2229
  }
2230
+ .group-hover\:text-blue-400 {
2231
+ &:is(:where(.group):hover *) {
2232
+ @media (hover: hover) {
2233
+ color: var(--color-blue-400);
2234
+ }
2235
+ }
2236
+ }
2170
2237
  .group-hover\:opacity-30 {
2171
2238
  &:is(:where(.group):hover *) {
2172
2239
  @media (hover: hover) {
@@ -2603,6 +2670,12 @@
2603
2670
  border-color: var(--color-blue-500);
2604
2671
  }
2605
2672
  }
2673
+ .focus\:ring-1 {
2674
+ &:focus {
2675
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2676
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2677
+ }
2678
+ }
2606
2679
  .focus\:ring-2 {
2607
2680
  &:focus {
2608
2681
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
@@ -3029,6 +3102,11 @@
3029
3102
  padding: calc(var(--spacing) * 6);
3030
3103
  }
3031
3104
  }
3105
+ .md\:p-8 {
3106
+ @media (width >= 48rem) {
3107
+ padding: calc(var(--spacing) * 8);
3108
+ }
3109
+ }
3032
3110
  .md\:px-6 {
3033
3111
  @media (width >= 48rem) {
3034
3112
  padding-inline: calc(var(--spacing) * 6);
@@ -36,6 +36,10 @@ export interface PostActionButtonProps {
36
36
  threeSpeakApiKey?: string;
37
37
  /** GIPHY API key — enables GIF search in comment composer */
38
38
  giphyApiKey?: string;
39
+ /** HReplier API token — enables template picker in comment composer */
40
+ templateToken?: string;
41
+ /** Custom template API endpoint */
42
+ templateApiBaseUrl?: string;
39
43
  }
40
- export declare function PostActionButton({ author, permlink, currentUser: currentUserProp, hiveValue, hiveIconUrl, payoutTooltip, initialVotes, initialCommentsCount, onUpvote, onSubmitComment, onComments, onReblog, onShare, onTip, onReport, onClickCommentUpvote, ecencyToken, threeSpeakApiKey, giphyApiKey, }: PostActionButtonProps): import("react/jsx-runtime").JSX.Element;
44
+ export declare function PostActionButton({ author, permlink, currentUser: currentUserProp, hiveValue, hiveIconUrl, payoutTooltip, initialVotes, initialCommentsCount, onUpvote, onSubmitComment, onComments, onReblog, onShare, onTip, onReport, onClickCommentUpvote, ecencyToken, threeSpeakApiKey, giphyApiKey, templateToken, templateApiBaseUrl, }: PostActionButtonProps): import("react/jsx-runtime").JSX.Element;
41
45
  export default PostActionButton;
@@ -1,16 +1,20 @@
1
- export interface AddCommentInputProps {
1
+ export interface PostComposerProps {
2
2
  onSubmit: (body: string) => void;
3
- onCancel: () => void;
3
+ onCancel?: () => void;
4
4
  currentUser?: string;
5
5
  placeholder?: string;
6
6
  parentAuthor?: string;
7
7
  parentPermlink?: string;
8
- /** Ecency image hosting token — enables image and video thumbnail upload */
8
+ /** Ecency image hosting token — enables image/video thumbnail upload and paste/drag upload */
9
9
  ecencyToken?: string;
10
- /** 3Speak API key — enables audio and video upload. Falls back to demo key if not provided. */
10
+ /** 3Speak API key — enables audio and video upload */
11
11
  threeSpeakApiKey?: string;
12
12
  /** GIPHY API key — enables GIF search */
13
13
  giphyApiKey?: string;
14
+ /** HReplier API token — enables template picker */
15
+ templateToken?: string;
16
+ /** Custom template API endpoint (defaults to https://hreplier-api.sagarkothari88.one/data/templates) */
17
+ templateApiBaseUrl?: string;
14
18
  /** Hide individual toolbar features */
15
19
  hideBold?: boolean;
16
20
  hideItalic?: boolean;
@@ -20,6 +24,37 @@ export interface AddCommentInputProps {
20
24
  hideVideo?: boolean;
21
25
  hideEmoji?: boolean;
22
26
  hideGif?: boolean;
27
+ hideCode?: boolean;
28
+ hideMention?: boolean;
29
+ hideTemplate?: boolean;
30
+ hidePreview?: boolean;
31
+ /** Show cancel button (default true) */
32
+ showCancel?: boolean;
33
+ /** Submit button label (default "Post") */
34
+ submitLabel?: string;
35
+ /** Title text above composer (optional) */
36
+ title?: string;
37
+ /** Enable preview by default (default false) */
38
+ defaultPreviewOn?: boolean;
39
+ /** Controlled mode: external value */
40
+ value?: string;
41
+ /** Controlled mode: called when body changes */
42
+ onChange?: (value: string) => void;
43
+ /** Disable the entire composer */
44
+ disabled?: boolean;
45
+ /** Hide the built-in submit button and keyboard hint footer (default false). Use when providing external submit buttons */
46
+ hideSubmitArea?: boolean;
47
+ /** Hide the avatar and username header (default false) */
48
+ hideUserHeader?: boolean;
49
+ /** Custom background color for the composer container (e.g. "#262b30", "transparent") */
50
+ bgColor?: string;
51
+ /** Custom border color for the composer container (e.g. "#3a424a", "transparent") */
52
+ borderColor?: string;
23
53
  }
24
- declare const AddCommentInput: ({ onSubmit, onCancel, currentUser, placeholder, parentAuthor, parentPermlink, ecencyToken, threeSpeakApiKey, giphyApiKey, hideBold, hideItalic, hideLink, hideImage, hideAudio, hideVideo, hideEmoji, hideGif, }: AddCommentInputProps) => import("react/jsx-runtime").JSX.Element;
54
+ /** @deprecated Use PostComposerProps instead */
55
+ export type AddCommentInputProps = PostComposerProps;
56
+ declare const PostComposer: ({ onSubmit, onCancel, currentUser, placeholder, parentAuthor, parentPermlink, ecencyToken, threeSpeakApiKey, giphyApiKey, templateToken, templateApiBaseUrl, hideBold, hideItalic, hideLink, hideImage, hideAudio, hideVideo, hideEmoji, hideGif, hideCode, hideMention, hideTemplate, hidePreview, showCancel, submitLabel, title, defaultPreviewOn, value, onChange, disabled, hideSubmitArea, hideUserHeader, bgColor, borderColor, }: PostComposerProps) => import("react/jsx-runtime").JSX.Element;
57
+ /** @deprecated Use PostComposer instead */
58
+ declare const AddCommentInput: ({ onSubmit, onCancel, currentUser, placeholder, parentAuthor, parentPermlink, ecencyToken, threeSpeakApiKey, giphyApiKey, templateToken, templateApiBaseUrl, hideBold, hideItalic, hideLink, hideImage, hideAudio, hideVideo, hideEmoji, hideGif, hideCode, hideMention, hideTemplate, hidePreview, showCancel, submitLabel, title, defaultPreviewOn, value, onChange, disabled, hideSubmitArea, hideUserHeader, bgColor, borderColor, }: PostComposerProps) => import("react/jsx-runtime").JSX.Element;
59
+ export { PostComposer };
25
60
  export default AddCommentInput;
@@ -17,6 +17,10 @@ interface CommentsModalProps {
17
17
  threeSpeakApiKey?: string;
18
18
  /** GIPHY API key — enables GIF search in comment composer */
19
19
  giphyApiKey?: string;
20
+ /** HReplier API token — enables template picker in comment composer */
21
+ templateToken?: string;
22
+ /** Custom template API endpoint */
23
+ templateApiBaseUrl?: string;
20
24
  }
21
- declare const CommentsModal: ({ author, permlink, onClose, currentUser, token, onClickCommentUpvote, onClickCommentReply, onClickUpvoteButton, onSubmitComment, ecencyToken, threeSpeakApiKey, giphyApiKey }: CommentsModalProps) => import("react/jsx-runtime").JSX.Element;
25
+ declare const CommentsModal: ({ author, permlink, onClose, currentUser, token, onClickCommentUpvote, onClickCommentReply, onClickUpvoteButton, onSubmitComment, ecencyToken, threeSpeakApiKey, giphyApiKey, templateToken, templateApiBaseUrl }: CommentsModalProps) => import("react/jsx-runtime").JSX.Element;
22
26
  export default CommentsModal;
@@ -7,6 +7,8 @@ interface ReplyModalProps {
7
7
  ecencyToken?: string;
8
8
  threeSpeakApiKey?: string;
9
9
  giphyApiKey?: string;
10
+ templateToken?: string;
11
+ templateApiBaseUrl?: string;
10
12
  }
11
- declare const ReplyModal: ({ parentAuthor, parentPermlink, onClose, onCommentSubmitted, currentUser, ecencyToken, threeSpeakApiKey, giphyApiKey, }: ReplyModalProps) => import("react/jsx-runtime").JSX.Element;
13
+ declare const ReplyModal: ({ parentAuthor, parentPermlink, onClose, onCommentSubmitted, currentUser, ecencyToken, threeSpeakApiKey, giphyApiKey, templateToken, templateApiBaseUrl, }: ReplyModalProps) => import("react/jsx-runtime").JSX.Element;
12
14
  export default ReplyModal;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { TemplateModel } from '../../services/templateService';
3
+ export interface TemplatePickerProps {
4
+ isOpen: boolean;
5
+ onClose: () => void;
6
+ onSelectTemplate: (template: string) => void;
7
+ templates: TemplateModel[];
8
+ /** If provided, {{author}} in templates is replaced with this value */
9
+ authorFromUrl?: string;
10
+ }
11
+ declare const TemplatePicker: React.FC<TemplatePickerProps>;
12
+ export default TemplatePicker;
@@ -8,3 +8,5 @@ export { default as GiphyPicker } from './GiphyPicker';
8
8
  export type { GiphyPickerProps } from './GiphyPicker';
9
9
  export { default as EmojiPicker } from './EmojiPicker';
10
10
  export type { EmojiPickerProps } from './EmojiPicker';
11
+ export { default as TemplatePicker } from './TemplatePicker';
12
+ export type { TemplatePickerProps } from './TemplatePicker';
@@ -18,6 +18,10 @@ export interface UserDetailProfileProps {
18
18
  threeSpeakApiKey?: string;
19
19
  /** GIPHY API key — enables GIF search in comment composer */
20
20
  giphyApiKey?: string;
21
+ /** HReplier API token — enables template picker in comment composer */
22
+ templateToken?: string;
23
+ /** Custom template API endpoint (defaults to https://hreplier-api.sagarkothari88.one/data/templates) */
24
+ templateApiBaseUrl?: string;
21
25
  onFollow?: (username: string) => void | Promise<void>;
22
26
  onUnfollow?: (username: string) => void | Promise<void>;
23
27
  onIgnoreAuthor?: (username: string) => void | Promise<void>;