@agentiffai/design 1.5.0 → 1.5.2

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/dist/index.d.cts CHANGED
@@ -664,6 +664,10 @@ interface PostPreviewCardProps {
664
664
  editContent?: string;
665
665
  /** Callback when content changes during editing */
666
666
  onContentChange?: (content: string) => void;
667
+ /** Current edited hashtags (controlled) */
668
+ editHashtags?: string[];
669
+ /** Callback when hashtags change */
670
+ onHashtagsChange?: (hashtags: string[]) => void;
667
671
  /** Show loading skeleton when content is being generated */
668
672
  isLoading?: boolean;
669
673
  /** Callback to change/add an image. When provided, image areas become clickable. */
@@ -687,6 +691,10 @@ interface PlatformCarouselProps {
687
691
  editContent?: string;
688
692
  /** Callback when edit content changes */
689
693
  onEditContentChange?: (content: string) => void;
694
+ /** Hashtags of the post being edited */
695
+ editHashtags?: string[];
696
+ /** Callback when edit hashtags change */
697
+ onEditHashtagsChange?: (hashtags: string[]) => void;
690
698
  /** Whether content is being loaded/generated */
691
699
  isLoading?: boolean;
692
700
  /** Callback when user requests to change/add an image for a post */
@@ -709,6 +717,10 @@ interface PlatformGridProps {
709
717
  editContent?: string;
710
718
  /** Callback when edit content changes */
711
719
  onEditContentChange?: (content: string) => void;
720
+ /** Hashtags of the post being edited */
721
+ editHashtags?: string[];
722
+ /** Callback when edit hashtags change */
723
+ onEditHashtagsChange?: (hashtags: string[]) => void;
712
724
  /** Whether content is being loaded/generated */
713
725
  isLoading?: boolean;
714
726
  /** Currently active/selected post index */
@@ -756,6 +768,10 @@ interface SocialMediaCanvasProps {
756
768
  editContent?: string;
757
769
  /** Callback when edit content changes */
758
770
  onEditContentChange?: (content: string) => void;
771
+ /** Hashtags of the post being edited */
772
+ editHashtags?: string[];
773
+ /** Callback when edit hashtags change */
774
+ onEditHashtagsChange?: (hashtags: string[]) => void;
759
775
  /** Whether content is being loaded/generated */
760
776
  isLoading?: boolean;
761
777
  /** Currently active post index (for grid mode) */
package/dist/index.d.ts CHANGED
@@ -664,6 +664,10 @@ interface PostPreviewCardProps {
664
664
  editContent?: string;
665
665
  /** Callback when content changes during editing */
666
666
  onContentChange?: (content: string) => void;
667
+ /** Current edited hashtags (controlled) */
668
+ editHashtags?: string[];
669
+ /** Callback when hashtags change */
670
+ onHashtagsChange?: (hashtags: string[]) => void;
667
671
  /** Show loading skeleton when content is being generated */
668
672
  isLoading?: boolean;
669
673
  /** Callback to change/add an image. When provided, image areas become clickable. */
@@ -687,6 +691,10 @@ interface PlatformCarouselProps {
687
691
  editContent?: string;
688
692
  /** Callback when edit content changes */
689
693
  onEditContentChange?: (content: string) => void;
694
+ /** Hashtags of the post being edited */
695
+ editHashtags?: string[];
696
+ /** Callback when edit hashtags change */
697
+ onEditHashtagsChange?: (hashtags: string[]) => void;
690
698
  /** Whether content is being loaded/generated */
691
699
  isLoading?: boolean;
692
700
  /** Callback when user requests to change/add an image for a post */
@@ -709,6 +717,10 @@ interface PlatformGridProps {
709
717
  editContent?: string;
710
718
  /** Callback when edit content changes */
711
719
  onEditContentChange?: (content: string) => void;
720
+ /** Hashtags of the post being edited */
721
+ editHashtags?: string[];
722
+ /** Callback when edit hashtags change */
723
+ onEditHashtagsChange?: (hashtags: string[]) => void;
712
724
  /** Whether content is being loaded/generated */
713
725
  isLoading?: boolean;
714
726
  /** Currently active/selected post index */
@@ -756,6 +768,10 @@ interface SocialMediaCanvasProps {
756
768
  editContent?: string;
757
769
  /** Callback when edit content changes */
758
770
  onEditContentChange?: (content: string) => void;
771
+ /** Hashtags of the post being edited */
772
+ editHashtags?: string[];
773
+ /** Callback when edit hashtags change */
774
+ onEditHashtagsChange?: (hashtags: string[]) => void;
759
775
  /** Whether content is being loaded/generated */
760
776
  isLoading?: boolean;
761
777
  /** Currently active post index (for grid mode) */
package/dist/index.js CHANGED
@@ -9937,13 +9937,17 @@ var PostPreviewCard = ({
9937
9937
  isEditing = false,
9938
9938
  editContent,
9939
9939
  onContentChange,
9940
+ editHashtags,
9941
+ onHashtagsChange,
9940
9942
  isLoading = false,
9941
9943
  onImageChange
9942
9944
  }) => {
9943
9945
  const platformConfig = PLATFORM_CONFIGS[post.platform] || PLATFORM_CONFIGS.x;
9944
9946
  const [imageError, setImageError] = useState(false);
9947
+ const [newHashtag, setNewHashtag] = useState("");
9945
9948
  const showSkeleton = isLoading && !post.content;
9946
9949
  const displayContent = isEditing && editContent !== void 0 ? editContent : post.editedContent || post.content;
9950
+ const displayHashtags = editHashtags !== void 0 ? editHashtags : post.hashtags;
9947
9951
  const currentCharCount = displayContent.length;
9948
9952
  const charPercentage = useMemo(
9949
9953
  () => getCharacterLimitPercentage(post.platform, currentCharCount),
@@ -9957,6 +9961,32 @@ var PostPreviewCard = ({
9957
9961
  const handleContentChange = (e) => {
9958
9962
  onContentChange?.(e.target.value);
9959
9963
  };
9964
+ const normalizeHashtag = (value) => value.trim().replace(/^#+/, "").replace(/[^\p{L}\p{N}_]/gu, "");
9965
+ const handleRemoveHashtag = (hashtagToRemove) => {
9966
+ const normalizedToRemove = normalizeHashtag(hashtagToRemove).toLowerCase();
9967
+ onHashtagsChange?.(
9968
+ displayHashtags.filter(
9969
+ (hashtag) => normalizeHashtag(hashtag).toLowerCase() !== normalizedToRemove
9970
+ )
9971
+ );
9972
+ };
9973
+ const handleAddHashtag = () => {
9974
+ const normalized = normalizeHashtag(newHashtag);
9975
+ if (!normalized) return;
9976
+ const exists = displayHashtags.some(
9977
+ (hashtag) => normalizeHashtag(hashtag).toLowerCase() === normalized.toLowerCase()
9978
+ );
9979
+ if (!exists) {
9980
+ onHashtagsChange?.([...displayHashtags, normalized]);
9981
+ }
9982
+ setNewHashtag("");
9983
+ };
9984
+ const handleNewHashtagKeyDown = (e) => {
9985
+ if (e.key === "Enter") {
9986
+ e.preventDefault();
9987
+ handleAddHashtag();
9988
+ }
9989
+ };
9960
9990
  return /* @__PURE__ */ jsxs(
9961
9991
  CardContainer,
9962
9992
  {
@@ -9986,10 +10016,45 @@ var PostPreviewCard = ({
9986
10016
  autoFocus: true
9987
10017
  }
9988
10018
  ) : /* @__PURE__ */ jsx(PostContent, { children: displayContent }),
9989
- !showSkeleton && post.hashtags.length > 0 && /* @__PURE__ */ jsx(HashtagsContainer, { children: post.hashtags.map((hashtag) => /* @__PURE__ */ jsxs(HashtagPill, { $platformColor: platformConfig.color, children: [
9990
- "#",
9991
- hashtag.replace(/^#/, "")
9992
- ] }, hashtag)) })
10019
+ !showSkeleton && (displayHashtags.length > 0 || onHashtagsChange) && /* @__PURE__ */ jsxs(HashtagsContainer, { children: [
10020
+ displayHashtags.map((hashtag) => /* @__PURE__ */ jsxs(HashtagPill, { $platformColor: platformConfig.color, children: [
10021
+ "#",
10022
+ hashtag.replace(/^#/, ""),
10023
+ onHashtagsChange && /* @__PURE__ */ jsx(
10024
+ RemoveHashtagButton,
10025
+ {
10026
+ type: "button",
10027
+ onClick: () => handleRemoveHashtag(hashtag),
10028
+ "aria-label": `Remove #${hashtag.replace(/^#/, "")}`,
10029
+ children: "\xD7"
10030
+ }
10031
+ )
10032
+ ] }, hashtag)),
10033
+ onHashtagsChange && /* @__PURE__ */ jsxs(HashtagEditor, { children: [
10034
+ /* @__PURE__ */ jsxs(HashtagInputWrapper, { children: [
10035
+ /* @__PURE__ */ jsx(HashPrefix, { children: "#" }),
10036
+ /* @__PURE__ */ jsx(
10037
+ HashtagInput,
10038
+ {
10039
+ value: newHashtag,
10040
+ onChange: (e) => setNewHashtag(e.target.value),
10041
+ onKeyDown: handleNewHashtagKeyDown,
10042
+ placeholder: "Add hashtag",
10043
+ "aria-label": "Add hashtag"
10044
+ }
10045
+ )
10046
+ ] }),
10047
+ /* @__PURE__ */ jsx(
10048
+ AddHashtagButton,
10049
+ {
10050
+ type: "button",
10051
+ onClick: handleAddHashtag,
10052
+ disabled: !normalizeHashtag(newHashtag),
10053
+ children: "Add"
10054
+ }
10055
+ )
10056
+ ] })
10057
+ ] })
9993
10058
  ] }),
9994
10059
  post.imageUrl && !imageError ? onImageChange ? /* @__PURE__ */ jsx(ImageChangeButton, { type: "button", onClick: onImageChange, "aria-label": "Change image", children: /* @__PURE__ */ jsxs(ImagePreviewContainer, { children: [
9995
10060
  /* @__PURE__ */ jsx(
@@ -10204,7 +10269,9 @@ var HashtagsContainer = styled58.div`
10204
10269
  gap: 6px;
10205
10270
  `;
10206
10271
  var HashtagPill = styled58.span`
10207
- display: inline-block;
10272
+ display: inline-flex;
10273
+ align-items: center;
10274
+ gap: 6px;
10208
10275
  padding: ${tokens.spacing.xs} 10px;
10209
10276
  border-radius: ${tokens.borderRadius.full};
10210
10277
  font-size: ${tokens.typography.fontSize.xs};
@@ -10220,6 +10287,99 @@ var HashtagPill = styled58.span`
10220
10287
  color: ${tokens.colors.primary};
10221
10288
  }
10222
10289
  `;
10290
+ var RemoveHashtagButton = styled58.button`
10291
+ width: 16px;
10292
+ height: 16px;
10293
+ display: inline-flex;
10294
+ align-items: center;
10295
+ justify-content: center;
10296
+ padding: 0;
10297
+ border: none;
10298
+ border-radius: ${tokens.borderRadius.full};
10299
+ background: ${tokens.colors.background.light};
10300
+ color: ${tokens.colors.text.secondary};
10301
+ cursor: pointer;
10302
+ font-size: 12px;
10303
+ line-height: 1;
10304
+ transition: all ${tokens.transitions.fast};
10305
+
10306
+ &:hover,
10307
+ &:focus-visible {
10308
+ background: ${tokens.colors.error};
10309
+ color: ${tokens.colors.text.primary};
10310
+ outline: none;
10311
+ }
10312
+ `;
10313
+ var HashtagEditor = styled58.div`
10314
+ display: inline-flex;
10315
+ align-items: center;
10316
+ gap: ${tokens.spacing.xs};
10317
+ min-width: min(100%, 190px);
10318
+ `;
10319
+ var HashtagInputWrapper = styled58.div`
10320
+ display: inline-flex;
10321
+ align-items: center;
10322
+ flex: 1;
10323
+ min-width: 0;
10324
+ padding: 0 ${tokens.spacing.sm};
10325
+ border: 1px solid ${tokens.colors.border.default};
10326
+ border-radius: ${tokens.borderRadius.full};
10327
+ background: ${tokens.colors.background.darker};
10328
+ transition: border-color ${tokens.transitions.fast}, box-shadow ${tokens.transitions.fast};
10329
+
10330
+ &:focus-within {
10331
+ border-color: ${tokens.colors.border.focus};
10332
+ box-shadow: 0 0 0 2px ${tokens.colors.primary}20;
10333
+ }
10334
+ `;
10335
+ var HashPrefix = styled58.span`
10336
+ color: ${tokens.colors.text.tertiary};
10337
+ font-size: ${tokens.typography.fontSize.xs};
10338
+ `;
10339
+ var HashtagInput = styled58.input`
10340
+ width: 100%;
10341
+ min-width: 0;
10342
+ height: 28px;
10343
+ padding: 0;
10344
+ border: none;
10345
+ background: transparent;
10346
+ color: ${tokens.colors.text.primary};
10347
+ font-size: ${tokens.typography.fontSize.xs};
10348
+ font-family: ${tokens.typography.fontFamily.primary};
10349
+
10350
+ &:focus {
10351
+ outline: none;
10352
+ }
10353
+
10354
+ &::placeholder {
10355
+ color: ${tokens.colors.text.tertiary};
10356
+ }
10357
+ `;
10358
+ var AddHashtagButton = styled58.button`
10359
+ height: 28px;
10360
+ padding: 0 ${tokens.spacing.sm};
10361
+ border: 1px solid ${tokens.colors.border.default};
10362
+ border-radius: ${tokens.borderRadius.full};
10363
+ background: ${tokens.colors.background.light};
10364
+ color: ${tokens.colors.text.primary};
10365
+ cursor: pointer;
10366
+ font-size: ${tokens.typography.fontSize.xs};
10367
+ font-weight: ${tokens.typography.fontWeight.semibold};
10368
+ transition: all ${tokens.transitions.fast};
10369
+
10370
+ &:hover:not(:disabled),
10371
+ &:focus-visible:not(:disabled) {
10372
+ background: ${tokens.colors.primary};
10373
+ border-color: ${tokens.colors.primary};
10374
+ color: ${tokens.colors.background.dark};
10375
+ outline: none;
10376
+ }
10377
+
10378
+ &:disabled {
10379
+ opacity: 0.45;
10380
+ cursor: not-allowed;
10381
+ }
10382
+ `;
10223
10383
  var ProgressBarContainer2 = styled58.div`
10224
10384
  margin-top: ${tokens.spacing.sm};
10225
10385
  `;
@@ -10365,6 +10525,8 @@ var PlatformCarousel = ({
10365
10525
  editingIndex,
10366
10526
  editContent,
10367
10527
  onEditContentChange,
10528
+ editHashtags,
10529
+ onEditHashtagsChange,
10368
10530
  isLoading = false,
10369
10531
  onImageChangeRequest
10370
10532
  }) => {
@@ -10418,14 +10580,18 @@ var PlatformCarousel = ({
10418
10580
  }) }),
10419
10581
  /* @__PURE__ */ jsx(ContentContainer2, { children: posts.map((post, index) => {
10420
10582
  const isEditing = editingIndex === index;
10421
- return /* @__PURE__ */ jsx(Slide, { $isActive: index === activeIndex, children: /* @__PURE__ */ jsx(
10583
+ const isActive = index === activeIndex;
10584
+ const canEditHashtags = isActive && !!onEditHashtagsChange;
10585
+ return /* @__PURE__ */ jsx(Slide, { $isActive: isActive, children: /* @__PURE__ */ jsx(
10422
10586
  PostPreviewCard,
10423
10587
  {
10424
10588
  post,
10425
- isActive: index === activeIndex,
10589
+ isActive,
10426
10590
  isEditing,
10427
10591
  editContent: isEditing ? editContent : void 0,
10428
10592
  onContentChange: isEditing ? onEditContentChange : void 0,
10593
+ editHashtags: canEditHashtags ? editHashtags : void 0,
10594
+ onHashtagsChange: canEditHashtags ? onEditHashtagsChange : void 0,
10429
10595
  isLoading,
10430
10596
  onImageChange: onImageChangeRequest ? () => onImageChangeRequest(index) : void 0
10431
10597
  }
@@ -10556,6 +10722,8 @@ var PlatformGrid = ({
10556
10722
  editingIndex,
10557
10723
  editContent,
10558
10724
  onEditContentChange,
10725
+ editHashtags,
10726
+ onEditHashtagsChange,
10559
10727
  isLoading = false,
10560
10728
  activeIndex = 0,
10561
10729
  onActiveChange,
@@ -10571,6 +10739,7 @@ var PlatformGrid = ({
10571
10739
  return /* @__PURE__ */ jsx(Grid, { "data-testid": "platform-grid", children: posts.map((post, index) => {
10572
10740
  const isEditing = editingIndex === index;
10573
10741
  const isActive = activeIndex === index;
10742
+ const canEditHashtags = isActive && !!onEditHashtagsChange;
10574
10743
  return /* @__PURE__ */ jsx(
10575
10744
  GridCell,
10576
10745
  {
@@ -10596,6 +10765,8 @@ var PlatformGrid = ({
10596
10765
  isEditing,
10597
10766
  editContent: isEditing ? editContent : void 0,
10598
10767
  onContentChange: isEditing ? onEditContentChange : void 0,
10768
+ editHashtags: canEditHashtags ? editHashtags : void 0,
10769
+ onHashtagsChange: canEditHashtags ? onEditHashtagsChange : void 0,
10599
10770
  isLoading,
10600
10771
  onImageChange: onImageChangeRequest ? () => onImageChangeRequest(index) : void 0
10601
10772
  }
@@ -10790,6 +10961,8 @@ var SocialMediaCanvas = ({
10790
10961
  editingIndex,
10791
10962
  editContent,
10792
10963
  onEditContentChange,
10964
+ editHashtags,
10965
+ onEditHashtagsChange,
10793
10966
  isLoading = false,
10794
10967
  activeIndex = 0,
10795
10968
  onImageChangeRequest
@@ -10849,6 +11022,8 @@ var SocialMediaCanvas = ({
10849
11022
  editingIndex,
10850
11023
  editContent,
10851
11024
  onEditContentChange,
11025
+ editHashtags,
11026
+ onEditHashtagsChange,
10852
11027
  isLoading,
10853
11028
  onImageChangeRequest
10854
11029
  }
@@ -10859,6 +11034,8 @@ var SocialMediaCanvas = ({
10859
11034
  editingIndex,
10860
11035
  editContent,
10861
11036
  onEditContentChange,
11037
+ editHashtags,
11038
+ onEditHashtagsChange,
10862
11039
  isLoading,
10863
11040
  activeIndex,
10864
11041
  onActiveChange: handleActiveChange,