From 6a8b0210f8bdacd3ab623bc7f81272a3e8befc06 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 30 Sep 2025 14:47:32 -0600 Subject: [PATCH] Update MentionInput.stories.tsx --- .../MentionInput/MentionInput.stories.tsx | 163 +++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/ui/inputs/MentionInput/MentionInput.stories.tsx b/apps/web/src/components/ui/inputs/MentionInput/MentionInput.stories.tsx index b09be8cd5..8e62af0ed 100644 --- a/apps/web/src/components/ui/inputs/MentionInput/MentionInput.stories.tsx +++ b/apps/web/src/components/ui/inputs/MentionInput/MentionInput.stories.tsx @@ -1,9 +1,11 @@ import { faker } from '@faker-js/faker'; import type { Meta, StoryObj } from '@storybook/react-vite'; +import { useMemo, useRef, useState } from 'react'; import { fn } from 'storybook/test'; import { createMentionSuggestionExtension } from './createMentionSuggestionOption'; +import { defaultQueryMentionsFilter } from './defaultQueryMentionsFilter'; import { MentionInput } from './MentionInput'; -import type { MentionInputTriggerItem } from './MentionInput.types'; +import type { MentionInputRef, MentionInputTriggerItem } from './MentionInput.types'; const meta = { title: 'UI/Inputs/MentionInput', @@ -315,3 +317,162 @@ export const Default: Story = { }, }, }; + +export const DynamicItems: Story = { + args: { + mentions: [], + onChange: fn(), + }, + render: () => { + const [dynamicItems, setDynamicItems] = useState([ + { value: 'Initial Item 1', label: 'Initial Item 1' }, + { value: 'Initial Item 2', label: 'Initial Item 2' }, + ]); + const mentionInputRef = useRef(null); + + const addRandomItem = () => { + const randomNames = [ + 'Alice Johnson', + 'Bob Smith', + 'Charlie Brown', + 'Diana Prince', + 'Edward Norton', + 'Fiona Apple', + 'George Lucas', + 'Helen Hunt', + 'Ivan Drago', + 'Julia Roberts', + 'Kevin Hart', + 'Linda Carter', + ]; + + const randomName = randomNames[Math.floor(Math.random() * randomNames.length)]; + const randomId = Math.random().toString(36).substring(7); + + const newItem: MentionInputTriggerItem = { + value: `${randomName}-${randomId}`, + label: ( + +
+ {randomName.charAt(0)} +
+ {randomName} +
+ ), + pillLabel: randomName, + }; + + setDynamicItems((prev) => [...prev, newItem]); + }; + + const addMentionToInput = () => { + if (mentionInputRef.current && dynamicItems.length > 0) { + const randomItem = dynamicItems[Math.floor(Math.random() * dynamicItems.length)]; + // Only process if it's an actual item (not a separator or group) + if ('value' in randomItem && 'label' in randomItem) { + mentionInputRef.current.addMentionToInput({ + value: randomItem.value, + label: randomItem.label, + pillLabel: 'pillLabel' in randomItem ? randomItem.pillLabel : undefined, + trigger: '!', + }); + } + } + }; + + const clearItems = () => { + setDynamicItems([]); + }; + + const dynamicSuggestions = useMemo( + () => + createMentionSuggestionExtension({ + trigger: '!', + items: ({ query }) => { + // This function is called each time suggestions are needed, + // so it will always get the current dynamicItems state + console.log( + 'Getting dynamic items for query:', + query, + 'Current items:', + dynamicItems.length + ); + return defaultQueryMentionsFilter(query, dynamicItems); + }, + pillStyling: { + className: () => { + return 'bg-gradient-to-r from-purple-100 to-pink-100 border-purple-300 text-purple-700 hover:from-purple-200 hover:to-pink-200'; + }, + }, + popoverContent: (props) => { + return ( +
+

Dynamic Item

+

Value: {props.value}

+
+ ); + }, + }), + [dynamicItems] + ); + + return ( +
+ { + console.log('Input changed:', value); + }} + /> + +
+ + + + + +
+ +
+

+ Instructions: +

+
    +
  • Type "!" in the input to trigger the dynamic mention suggestions
  • +
  • Use "Add Random Item" to add new items to the mention list
  • +
  • Use "Insert Random Mention" to programmatically add a mention to the input
  • +
  • Watch how the mention count updates as you add/remove items
  • +
+
+
+ ); + }, + parameters: { + docs: { + description: { + story: + 'Interactive story demonstrating dynamic mention items. You can add items to the mention list dynamically and insert mentions programmatically using the component ref.', + }, + }, + }, +};