diff --git a/packages/filigran-ui/package.json b/packages/filigran-ui/package.json index d8cf011..17c4a53 100644 --- a/packages/filigran-ui/package.json +++ b/packages/filigran-ui/package.json @@ -53,6 +53,7 @@ "clsx": "2.1.1", "cmdk": "1.0.0", "lucide-react": "0.399.0", + "react-easy-sort": "1.6.0", "react-hook-form": "7.52.0", "tailwind-merge": "2.3.0", "tailwindcss-animate": "1.0.7", diff --git a/packages/filigran-ui/src/components/clients/index.ts b/packages/filigran-ui/src/components/clients/index.ts index 860fe93..54ac4a7 100644 --- a/packages/filigran-ui/src/components/clients/index.ts +++ b/packages/filigran-ui/src/components/clients/index.ts @@ -18,3 +18,4 @@ export * from './use-toast' export * from './toast' export * from './toaster' export * from './tabs' +export * from './tag-input/tag-input' diff --git a/packages/filigran-ui/src/components/clients/tag-input/autocomplete.tsx b/packages/filigran-ui/src/components/clients/tag-input/autocomplete.tsx new file mode 100644 index 0000000..f170c9a --- /dev/null +++ b/packages/filigran-ui/src/components/clients/tag-input/autocomplete.tsx @@ -0,0 +1,329 @@ +import React, {useCallback, useEffect, useRef, useState} from 'react' +import {type TagInputStyleClassesProps, type Tag as TagType} from './tag-input' +import {Popover, PopoverContent, PopoverTrigger} from '../popover' +import {cn} from '../../../lib/utils' +import {Button} from '../../servers/button' + +type AutocompleteProps = { + tags: TagType[] + setTags: React.Dispatch> + setInputValue: React.Dispatch> + setTagCount: React.Dispatch> + autocompleteOptions: TagType[] + maxTags?: number + onTagAdd?: (tag: string) => void + onTagRemove?: (tag: string) => void + allowDuplicates: boolean + children: React.ReactNode + inlineTags?: boolean + classStyleProps: TagInputStyleClassesProps['autoComplete'] + usePortal?: boolean +} + +export const Autocomplete: React.FC = ({ + tags, + setTags, + setInputValue, + setTagCount, + autocompleteOptions, + maxTags, + onTagAdd, + onTagRemove, + allowDuplicates, + inlineTags, + children, + classStyleProps, + usePortal, +}) => { + const triggerContainerRef = useRef(null) + const triggerRef = useRef(null) + const inputRef = useRef(null) + const popoverContentRef = useRef(null) + + const [popoverWidth, setPopoverWidth] = useState(0) + const [isPopoverOpen, setIsPopoverOpen] = useState(false) + const [inputFocused, setInputFocused] = useState(false) + const [popooverContentTop, setPopoverContentTop] = useState(0) + const [selectedIndex, setSelectedIndex] = useState(-1) + + // Dynamically calculate the top position for the popover content + useEffect(() => { + if (!triggerContainerRef.current || !triggerRef.current) return + setPopoverContentTop( + triggerContainerRef.current?.getBoundingClientRect().bottom - + triggerRef.current?.getBoundingClientRect().bottom + ) + }, [tags]) + + // Close the popover when clicking outside of it + useEffect(() => { + const handleOutsideClick = ( + event: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent + ) => { + if ( + isPopoverOpen && + triggerContainerRef.current && + popoverContentRef.current && + !triggerContainerRef.current.contains(event.target as Node) && + !popoverContentRef.current.contains(event.target as Node) + ) { + setIsPopoverOpen(false) + } + } + + document.addEventListener('mousedown', handleOutsideClick) + + return () => { + document.removeEventListener('mousedown', handleOutsideClick) + } + }, [isPopoverOpen]) + + const handleOpenChange = useCallback( + (open: boolean) => { + if (open && triggerContainerRef.current) { + const {width} = triggerContainerRef.current.getBoundingClientRect() + setPopoverWidth(width) + } + + if (open) { + inputRef.current?.focus() + setIsPopoverOpen(open) + } + }, + [inputFocused] + ) + + const handleInputFocus = ( + event: + | React.FocusEvent + | React.FocusEvent + ) => { + if (triggerContainerRef.current) { + const {width} = triggerContainerRef.current.getBoundingClientRect() + setPopoverWidth(width) + setIsPopoverOpen(true) + } + + // Only set inputFocused to true if the popover is already open. + // This will prevent the popover from opening due to an input focus if it was initially closed. + if (isPopoverOpen) { + setInputFocused(true) + } + + const userOnFocus = (children as React.ReactElement).props.onFocus + if (userOnFocus) userOnFocus(event) + } + + const handleInputBlur = ( + event: + | React.FocusEvent + | React.FocusEvent + ) => { + setInputFocused(false) + + // Allow the popover to close if no other interactions keep it open + if (!isPopoverOpen) { + setIsPopoverOpen(false) + } + + const userOnBlur = (children as React.ReactElement).props.onBlur + if (userOnBlur) userOnBlur(event) + } + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (!isPopoverOpen) return + + switch (event.key) { + case 'ArrowUp': + event.preventDefault() + setSelectedIndex((prevIndex) => + prevIndex <= 0 ? autocompleteOptions.length - 1 : prevIndex - 1 + ) + break + case 'ArrowDown': + event.preventDefault() + setSelectedIndex((prevIndex) => + prevIndex === autocompleteOptions.length - 1 ? 0 : prevIndex + 1 + ) + break + case 'Enter': + event.preventDefault() + if (selectedIndex !== -1) { + toggleTag(autocompleteOptions[selectedIndex]) + setSelectedIndex(-1) + } + break + } + } + + const toggleTag = (option: TagType) => { + // Check if the tag already exists in the array + const index = tags.findIndex((tag) => tag.text === option.text) + + if (index >= 0) { + // Tag exists, remove it + const newTags = tags.filter((_, i) => i !== index) + setTags(newTags) + setTagCount((prevCount) => prevCount - 1) + if (onTagRemove) { + onTagRemove(option.text) + } + } else { + // Tag doesn't exist, add it if allowed + if (!allowDuplicates && tags.some((tag) => tag.text === option.text)) { + // If duplicates aren't allowed and a tag with the same text exists, do nothing + return + } + + // Add the tag if it doesn't exceed max tags, if applicable + if (!maxTags || tags.length < maxTags) { + setTags([...tags, option]) + setTagCount((prevCount) => prevCount + 1) + setInputValue('') + if (onTagAdd) { + onTagAdd(option.text) + } + } + } + setSelectedIndex(-1) + } + + const childrenWithProps = React.cloneElement( + children as React.ReactElement, + { + onKeyDown: handleKeyDown, + onFocus: handleInputFocus, + onBlur: handleInputBlur, + ref: inputRef, + } + ) + + return ( +
+ +
+ {childrenWithProps} + + + +
+ +
+ {autocompleteOptions.length > 0 ? ( +
+ + Suggestions + +
+ {autocompleteOptions.map((option, index) => { + const isSelected = index === selectedIndex + return ( +
toggleTag(option)}> +
+ {option.text} + {tags.some((tag) => tag.text === option.text) && ( + + + + )} +
+
+ ) + })} +
+ ) : ( +
No results found.
+ )} +
+ + +
+ ) +} diff --git a/packages/filigran-ui/src/components/clients/tag-input/tag-input.tsx b/packages/filigran-ui/src/components/clients/tag-input/tag-input.tsx new file mode 100644 index 0000000..6c721bf --- /dev/null +++ b/packages/filigran-ui/src/components/clients/tag-input/tag-input.tsx @@ -0,0 +1,767 @@ +'use client' + +import React, {useMemo} from 'react' +import {type VariantProps} from 'class-variance-authority' +import {TagPopover} from './tag-popover' +import {TagList} from './tag-list' +import {tagVariants} from './tag' +import {Autocomplete} from './autocomplete' +import {cn, uuid} from '../../../lib/utils' +import {Button, Input} from '../../servers' + +export enum Delimiter { + Comma = ',', + Enter = 'Enter', +} + +type OmittedInputProps = Omit< + React.InputHTMLAttributes, + 'size' | 'value' +> + +export type Tag = { + id: string + text: string +} + +export interface TagInputStyleClassesProps { + inlineTagsContainer?: string + tagPopover?: { + popoverTrigger?: string + popoverContent?: string + } + tagList?: { + container?: string + sortableList?: string + } + autoComplete?: { + command?: string + popoverTrigger?: string + popoverContent?: string + commandList?: string + commandGroup?: string + commandItem?: string + } + tag?: { + body?: string + closeButton?: string + } + input?: string + clearAllButton?: string +} + +export interface TagInputProps + extends OmittedInputProps, + VariantProps { + placeholder?: string + tags: Tag[] + setTags: React.Dispatch> + enableAutocomplete?: boolean + autocompleteOptions?: Tag[] + maxTags?: number + minTags?: number + readOnly?: boolean + disabled?: boolean + onTagAdd?: (tag: string) => void + onTagRemove?: (tag: string) => void + allowDuplicates?: boolean + validateTag?: (tag: string) => boolean + delimiter?: Delimiter + showCount?: boolean + placeholderWhenFull?: string + sortTags?: boolean + delimiterList?: string[] + truncate?: number + minLength?: number + maxLength?: number + usePopoverForTags?: boolean + value?: string | number | readonly string[] | {id: string; text: string}[] + autocompleteFilter?: (option: string) => boolean + direction?: 'row' | 'column' + onInputChange?: (value: string) => void + customTagRenderer?: (tag: Tag, isActiveTag: boolean) => React.ReactNode + onFocus?: React.FocusEventHandler + onBlur?: React.FocusEventHandler + onTagClick?: (tag: Tag) => void + draggable?: boolean + inputFieldPosition?: 'bottom' | 'top' + clearAll?: boolean + onClearAll?: () => void + inputProps?: React.InputHTMLAttributes + restrictTagsToAutocompleteOptions?: boolean + inlineTags?: boolean + activeTagIndex: number | null + setActiveTagIndex: React.Dispatch> + styleClasses?: TagInputStyleClassesProps + usePortal?: boolean + addOnPaste?: boolean + addTagsOnBlur?: boolean + generateTagId?: () => string +} + +const TagInput = React.forwardRef( + (props, ref) => { + const { + id, + placeholder, + tags, + setTags, + variant, + enableAutocomplete, + autocompleteOptions, + maxTags, + delimiter = Delimiter.Comma, + onTagAdd, + onTagRemove, + allowDuplicates, + showCount, + validateTag, + placeholderWhenFull = 'Max tags reached', + sortTags, + delimiterList, + truncate, + minLength, + maxLength, + direction = 'row', + onInputChange, + customTagRenderer, + onFocus, + onBlur, + onTagClick, + draggable = false, + inputFieldPosition = 'bottom', + clearAll = false, + onClearAll, + usePopoverForTags = false, + inputProps = {}, + restrictTagsToAutocompleteOptions, + inlineTags = true, + addTagsOnBlur = false, + activeTagIndex, + setActiveTagIndex, + styleClasses = {}, + disabled = false, + usePortal = false, + addOnPaste = false, + generateTagId = uuid, + } = props + + const [inputValue, setInputValue] = React.useState('') + const [tagCount, setTagCount] = React.useState(Math.max(0, tags.length)) + const inputRef = React.useRef(null) + + if ( + (maxTags !== undefined && maxTags < 0) || + (props.minTags !== undefined && props.minTags < 0) + ) { + console.warn('maxTags and minTags cannot be less than 0') + // error + return null + } + + const handleInputChange = (e: React.ChangeEvent) => { + const newValue = e.target.value + if (addOnPaste && newValue.includes(delimiter)) { + const splitValues = newValue + .split(delimiter) + .map((v) => v.trim()) + .filter((v) => v) + splitValues.forEach((value) => { + if (!value) return // Skip empty strings from split + + const newTagText = value.trim() + + // Check if the tag is in the autocomplete options if restrictTagsToAutocomplete is true + if ( + restrictTagsToAutocompleteOptions && + !autocompleteOptions?.some((option) => option.text === newTagText) + ) { + console.warn('Tag not allowed as per autocomplete options') + return + } + + if (validateTag && !validateTag(newTagText)) { + console.warn('Invalid tag as per validateTag') + return + } + + if (minLength && newTagText.length < minLength) { + console.warn(`Tag "${newTagText}" is too short`) + return + } + + if (maxLength && newTagText.length > maxLength) { + console.warn(`Tag "${newTagText}" is too long`) + return + } + + const newTagId = generateTagId() + + // Add tag if duplicates are allowed or tag does not already exist + if (allowDuplicates || !tags.some((tag) => tag.text === newTagText)) { + if (maxTags === undefined || tags.length < maxTags) { + // Check for maxTags limit + const newTag = {id: newTagId, text: newTagText} + setTags((prevTags) => [...prevTags, newTag]) + onTagAdd?.(newTagText) + } else { + console.warn('Reached the maximum number of tags allowed') + } + } else { + console.warn(`Duplicate tag "${newTagText}" not added`) + } + }) + setInputValue('') + } else { + setInputValue(newValue) + } + onInputChange?.(newValue) + } + + const handleInputFocus = (event: React.FocusEvent) => { + setActiveTagIndex(null) // Reset active tag index when the input field gains focus + onFocus?.(event) + } + + const handleInputBlur = (event: React.FocusEvent) => { + if (addTagsOnBlur && inputValue.trim()) { + const newTagText = inputValue.trim() + + if (validateTag && !validateTag(newTagText)) { + return + } + + if (minLength && newTagText.length < minLength) { + console.warn('Tag is too short') + return + } + + if (maxLength && newTagText.length > maxLength) { + console.warn('Tag is too long') + return + } + + if ( + (allowDuplicates || !tags.some((tag) => tag.text === newTagText)) && + (maxTags === undefined || tags.length < maxTags) + ) { + const newTagId = generateTagId() + setTags([...tags, {id: newTagId, text: newTagText}]) + onTagAdd?.(newTagText) + setTagCount((prevTagCount) => prevTagCount + 1) + setInputValue('') + } + } + + onBlur?.(event) + } + + const handleKeyDown = (e: React.KeyboardEvent) => { + if ( + delimiterList + ? delimiterList.includes(e.key) + : e.key === delimiter || e.key === Delimiter.Enter + ) { + e.preventDefault() + const newTagText = inputValue.trim() + + // Check if the tag is in the autocomplete options if restrictTagsToAutocomplete is true + if ( + restrictTagsToAutocompleteOptions && + !autocompleteOptions?.some((option) => option.text === newTagText) + ) { + // error + return + } + + if (validateTag && !validateTag(newTagText)) { + return + } + + if (minLength && newTagText.length < minLength) { + console.warn('Tag is too short') + // error + return + } + + // Validate maxLength + if (maxLength && newTagText.length > maxLength) { + // error + console.warn('Tag is too long') + return + } + + const newTagId = generateTagId() + + if ( + newTagText && + (allowDuplicates || !tags.some((tag) => tag.text === newTagText)) && + (maxTags === undefined || tags.length < maxTags) + ) { + setTags([...tags, {id: newTagId, text: newTagText}]) + onTagAdd?.(newTagText) + setTagCount((prevTagCount) => prevTagCount + 1) + } + setInputValue('') + } else { + switch (e.key) { + case 'Delete': + if (activeTagIndex !== null) { + e.preventDefault() + const newTags = [...tags] + newTags.splice(activeTagIndex, 1) + setTags(newTags) + setActiveTagIndex((prev) => + newTags.length === 0 + ? null + : prev! >= newTags.length + ? newTags.length - 1 + : prev + ) + setTagCount((prevTagCount) => prevTagCount - 1) + onTagRemove?.(tags[activeTagIndex].text) + } + break + case 'Backspace': + console.log('Backspace', activeTagIndex) + if (activeTagIndex !== null) { + e.preventDefault() + const newTags = [...tags] + newTags.splice(activeTagIndex, 1) + setTags(newTags) + setActiveTagIndex((prev) => (prev! === 0 ? null : prev! - 1)) + setTagCount((prevTagCount) => prevTagCount - 1) + onTagRemove?.(tags[activeTagIndex].text) + } + break + case 'ArrowRight': + e.preventDefault() + if (activeTagIndex === null) { + setActiveTagIndex(0) + } else { + setActiveTagIndex((prev) => + prev! + 1 >= tags.length ? 0 : prev! + 1 + ) + } + break + case 'ArrowLeft': + e.preventDefault() + if (activeTagIndex === null) { + setActiveTagIndex(tags.length - 1) + } else { + setActiveTagIndex((prev) => + prev! === 0 ? tags.length - 1 : prev! - 1 + ) + } + break + case 'Home': + e.preventDefault() + setActiveTagIndex(0) + break + case 'End': + e.preventDefault() + setActiveTagIndex(tags.length - 1) + break + } + } + } + + const removeTag = (idToRemove: string) => { + setTags(tags.filter((tag) => tag.id !== idToRemove)) + onTagRemove?.(tags.find((tag) => tag.id === idToRemove)?.text || '') + setTagCount((prevTagCount) => prevTagCount - 1) + } + + const onSortEnd = (oldIndex: number, newIndex: number) => { + setTags((currentTags) => { + const newTags = [...currentTags] + const [removedTag] = newTags.splice(oldIndex, 1) + newTags.splice(newIndex, 0, removedTag) + + return newTags + }) + } + + const handleClearAll = () => { + if (!onClearAll) { + setActiveTagIndex(-1) + setTags([]) + return + } + onClearAll?.() + } + + // const filteredAutocompleteOptions = autocompleteFilter + // ? autocompleteOptions?.filter((option) => autocompleteFilter(option.text)) + // : autocompleteOptions; + const filteredAutocompleteOptions = useMemo(() => { + return (autocompleteOptions || []).filter((option) => + option.text + .toLowerCase() + .includes(inputValue ? inputValue.toLowerCase() : '') + ) + }, [inputValue, autocompleteOptions]) + + const displayedTags = sortTags ? [...tags].sort() : tags + + const truncatedTags = truncate + ? tags.map((tag) => ({ + id: tag.id, + text: + tag.text?.length > truncate + ? `${tag.text.substring(0, truncate)}...` + : tag.text, + })) + : displayedTags + + return ( +
0 ? 'gap-3' : ''} ${ + inputFieldPosition === 'bottom' + ? 'flex-col' + : inputFieldPosition === 'top' + ? 'flex-col-reverse' + : 'flex-row' + }`}> + {!usePopoverForTags && + (!inlineTags ? ( + + ) : ( + !enableAutocomplete && ( +
+
+ + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + className={cn( + 'h-5 w-fit flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0', + // className, + styleClasses?.input + )} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={ + enableAutocomplete ? 'autocomplete-options' : undefined + } + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + /> +
+
+ ) + ))} + {enableAutocomplete ? ( +
+ + {!usePopoverForTags ? ( + !inlineTags ? ( + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + className={cn( + 'h-5 w-fit flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0', + // className, + styleClasses?.input + )} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={ + enableAutocomplete ? 'autocomplete-options' : undefined + } + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + /> + ) : ( +
+ + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + className={cn( + 'h-5 w-fit flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0', + // className, + styleClasses?.input + )} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={ + enableAutocomplete ? 'autocomplete-options' : undefined + } + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + /> +
+ ) + ) : ( + + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + className={cn( + 'h-5 w-fit flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0', + // className, + styleClasses?.input + )} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={ + enableAutocomplete ? 'autocomplete-options' : undefined + } + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + /> + + )} +
+
+ ) : ( +
+ {!usePopoverForTags ? ( + !inlineTags ? ( + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + className={cn( + styleClasses?.input + // className + )} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={enableAutocomplete ? 'autocomplete-options' : undefined} + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + /> + ) : null + ) : ( + + = maxTags + ? placeholderWhenFull + : placeholder + } + value={inputValue} + onChange={handleInputChange} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onBlur={handleInputBlur} + {...inputProps} + autoComplete={enableAutocomplete ? 'on' : 'off'} + list={enableAutocomplete ? 'autocomplete-options' : undefined} + disabled={ + disabled || + (maxTags !== undefined && tags.length >= maxTags) + } + className={cn( + 'w-full border-0', + styleClasses?.input + // className + )} + /> + + )} +
+ )} + + {showCount && maxTags && ( +
+ + {`${tagCount}`}/{`${maxTags}`} + +
+ )} + {clearAll && ( + + )} +
+ ) + } +) + +TagInput.displayName = 'TagInput' + +export {TagInput} diff --git a/packages/filigran-ui/src/components/clients/tag-input/tag-list.tsx b/packages/filigran-ui/src/components/clients/tag-input/tag-list.tsx new file mode 100644 index 0000000..9f29b08 --- /dev/null +++ b/packages/filigran-ui/src/components/clients/tag-input/tag-list.tsx @@ -0,0 +1,176 @@ +import React from 'react' +import {type TagInputStyleClassesProps, type Tag as TagType} from './tag-input' +import {Tag, type TagProps} from './tag' +import SortableList, {SortableItem} from 'react-easy-sort' +import {cn} from '../../../lib/utils' + +export type TagListProps = { + tags: TagType[] + customTagRenderer?: (tag: TagType, isActiveTag: boolean) => React.ReactNode + direction?: TagProps['direction'] + onSortEnd: (oldIndex: number, newIndex: number) => void + className?: string + inlineTags?: boolean + activeTagIndex?: number | null + setActiveTagIndex?: (index: number | null) => void + classStyleProps: { + tagListClasses: TagInputStyleClassesProps['tagList'] + tagClasses: TagInputStyleClassesProps['tag'] + } + disabled?: boolean +} & Omit + +const DropTarget: React.FC = () => { + return
+} + +export const TagList: React.FC = ({ + tags, + customTagRenderer, + direction, + draggable, + onSortEnd, + className, + inlineTags, + activeTagIndex, + setActiveTagIndex, + classStyleProps, + disabled, + ...tagListProps +}) => { + const [draggedTagId, setDraggedTagId] = React.useState(null) + + const handleMouseDown = (id: string) => { + setDraggedTagId(id) + } + + const handleMouseUp = () => { + setDraggedTagId(null) + } + + return ( + <> + {!inlineTags ? ( +
+ {draggable ? ( + }> + {tags.map((tagObj, index) => ( + +
handleMouseDown(tagObj.id)} + onMouseLeave={handleMouseUp} + className={cn( + { + 'rounded-md border border-solid border-primary': + draggedTagId === tagObj.id, + }, + 'transition-all duration-200 ease-in-out' + )}> + {customTagRenderer ? ( + customTagRenderer(tagObj, index === activeTagIndex) + ) : ( + + )} +
+
+ ))} +
+ ) : ( + tags.map((tagObj, index) => + customTagRenderer ? ( + customTagRenderer(tagObj, index === activeTagIndex) + ) : ( + + ) + ) + )} +
+ ) : ( + <> + {draggable ? ( + }> + {tags.map((tagObj, index) => ( + +
handleMouseDown(tagObj.id)} + onMouseLeave={handleMouseUp} + className={cn( + { + 'rounded-md border border-solid border-primary': + draggedTagId === tagObj.id, + }, + 'transition-all duration-200 ease-in-out' + )}> + {customTagRenderer ? ( + customTagRenderer(tagObj, index === activeTagIndex) + ) : ( + + )} +
+
+ ))} +
+ ) : ( + tags.map((tagObj, index) => + customTagRenderer ? ( + customTagRenderer(tagObj, index === activeTagIndex) + ) : ( + + ) + ) + )} + + )} + + ) +} diff --git a/packages/filigran-ui/src/components/clients/tag-input/tag-popover.tsx b/packages/filigran-ui/src/components/clients/tag-input/tag-popover.tsx new file mode 100644 index 0000000..c667a84 --- /dev/null +++ b/packages/filigran-ui/src/components/clients/tag-input/tag-popover.tsx @@ -0,0 +1,200 @@ +import React, {useCallback, useEffect, useRef, useState} from 'react' +import {type TagInputStyleClassesProps, type Tag as TagType} from './tag-input' +import {TagList, type TagListProps} from './tag-list' +import {Popover, PopoverContent, PopoverTrigger} from '../popover' +import {Button} from '../../servers' +import {cn} from '../../../lib/utils' + +type TagPopoverProps = { + children: React.ReactNode + tags: TagType[] + customTagRenderer?: (tag: TagType, isActiveTag: boolean) => React.ReactNode + activeTagIndex?: number | null + setActiveTagIndex?: (index: number | null) => void + classStyleProps: { + popoverClasses: TagInputStyleClassesProps['tagPopover'] + tagListClasses: TagInputStyleClassesProps['tagList'] + tagClasses: TagInputStyleClassesProps['tag'] + } + disabled?: boolean + usePortal?: boolean +} & TagListProps + +export const TagPopover: React.FC = ({ + children, + tags, + customTagRenderer, + activeTagIndex, + setActiveTagIndex, + classStyleProps, + disabled, + usePortal, + ...tagProps +}) => { + const triggerContainerRef = useRef(null) + const triggerRef = useRef(null) + const popoverContentRef = useRef(null) + const inputRef = useRef(null) + + const [popoverWidth, setPopoverWidth] = useState(0) + const [isPopoverOpen, setIsPopoverOpen] = useState(false) + const [inputFocused, setInputFocused] = useState(false) + const [sideOffset, setSideOffset] = useState(0) + + useEffect(() => { + const handleResize = () => { + if (triggerContainerRef.current && triggerRef.current) { + setPopoverWidth(triggerContainerRef.current.offsetWidth) + setSideOffset( + triggerContainerRef.current.offsetWidth - + triggerRef?.current?.offsetWidth + ) + } + } + + handleResize() // Call on mount and layout changes + + window.addEventListener('resize', handleResize) // Adjust on window resize + return () => window.removeEventListener('resize', handleResize) + }, [triggerContainerRef, triggerRef]) + + // Close the popover when clicking outside of it + useEffect(() => { + const handleOutsideClick = ( + event: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent + ) => { + if ( + isPopoverOpen && + triggerContainerRef.current && + popoverContentRef.current && + !triggerContainerRef.current.contains(event.target as Node) && + !popoverContentRef.current.contains(event.target as Node) + ) { + setIsPopoverOpen(false) + } + } + + document.addEventListener('mousedown', handleOutsideClick) + + return () => { + document.removeEventListener('mousedown', handleOutsideClick) + } + }, [isPopoverOpen]) + + const handleOpenChange = useCallback( + (open: boolean) => { + if (open && triggerContainerRef.current) { + setPopoverWidth(triggerContainerRef.current.offsetWidth) + } + + if (open) { + inputRef.current?.focus() + setIsPopoverOpen(open) + } + }, + [inputFocused] + ) + + const handleInputFocus = ( + event: + | React.FocusEvent + | React.FocusEvent + ) => { + // Only set inputFocused to true if the popover is already open. + // This will prevent the popover from opening due to an input focus if it was initially closed. + if (isPopoverOpen) { + setInputFocused(true) + } + + const userOnFocus = (children as React.ReactElement).props.onFocus + if (userOnFocus) userOnFocus(event) + } + + const handleInputBlur = ( + event: + | React.FocusEvent + | React.FocusEvent + ) => { + setInputFocused(false) + + // Allow the popover to close if no other interactions keep it open + if (!isPopoverOpen) { + setIsPopoverOpen(false) + } + + const userOnBlur = (children as React.ReactElement).props.onBlur + if (userOnBlur) userOnBlur(event) + } + + return ( + +
+ {React.cloneElement(children as React.ReactElement, { + onFocus: handleInputFocus, + onBlur: handleInputBlur, + ref: inputRef, + })} + + + +
+ +
+

Entered Tags

+

+ These are the tags you've entered. +

+
+ +
+
+ ) +} diff --git a/packages/filigran-ui/src/components/clients/tag-input/tag.tsx b/packages/filigran-ui/src/components/clients/tag-input/tag.tsx new file mode 100644 index 0000000..9ee7370 --- /dev/null +++ b/packages/filigran-ui/src/components/clients/tag-input/tag.tsx @@ -0,0 +1,73 @@ +import React from 'react' +import { + type TagInputProps, + type TagInputStyleClassesProps, + type Tag as TagType, +} from './tag-input' + +import {cva} from 'class-variance-authority' +import {cn} from '../../../lib/utils' +import {Badge} from '../../servers' +import {XCircle} from 'lucide-react' + +export const tagVariants = cva('font-medium', { + variants: { + variant: { + default: 'text-primary', + secondary: 'text-secondary', + destructive: 'text-destructive', + inverted: 'inverted', + }, + }, + defaultVariants: { + variant: 'default', + }, +}) + +export type TagProps = { + tagObj: TagType + variant: TagInputProps['variant'] + onRemoveTag: (id: string) => void + isActiveTag?: boolean + tagClasses?: TagInputStyleClassesProps['tag'] + disabled?: boolean +} & Pick + +export const Tag: React.FC = ({ + tagObj, + direction, + draggable, + onTagClick, + onRemoveTag, + variant, + isActiveTag, + tagClasses, + disabled, +}) => { + return ( + onTagClick?.(tagObj)}> + {tagObj.text} + { + e.stopPropagation() // Prevent event from bubbling up to the tag span + onRemoveTag(tagObj.id) + }} + /> + + ) +} diff --git a/packages/filigran-ui/src/components/servers/multi-select.tsx b/packages/filigran-ui/src/components/servers/multi-select.tsx index 8f2260f..6c49ae2 100644 --- a/packages/filigran-ui/src/components/servers/multi-select.tsx +++ b/packages/filigran-ui/src/components/servers/multi-select.tsx @@ -20,7 +20,7 @@ const multiSelectVariants = cva('m-1', { variants: { variant: { default: - 'border-foreground/10 drop-shadow-md text-foreground bg-card hover:bg-card/80', + 'border-foreground/10 drop-shadow-md text-primary-foreground bg-primary hover:bg-primary/80', secondary: 'border-foreground/10 bg-secondary text-secondary-foreground hover:bg-secondary/80', destructive: diff --git a/packages/filigran-ui/src/lib/utils.ts b/packages/filigran-ui/src/lib/utils.ts index b841011..8a1a09b 100644 --- a/packages/filigran-ui/src/lib/utils.ts +++ b/packages/filigran-ui/src/lib/utils.ts @@ -18,3 +18,7 @@ export function fixedForwardRef( ): (props: P & RefAttributes) => ReactNode { return forwardRef(render) as any } + +export function uuid() { + return crypto.getRandomValues(new Uint32Array(1))[0].toString() +} diff --git a/projects/filigran-website/components/example/example-tag-input.tsx b/projects/filigran-website/components/example/example-tag-input.tsx new file mode 100644 index 0000000..2e159bf --- /dev/null +++ b/projects/filigran-website/components/example/example-tag-input.tsx @@ -0,0 +1,169 @@ +'use client' +import {z} from 'zod' +import {useForm} from 'react-hook-form' +import {zodResolver} from '@hookform/resolvers/zod' +import React, {useState} from 'react' +import {Button} from 'filigran-ui/servers' +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, + Tag, + TagInput, + toast, +} from 'filigran-ui/clients' + +const FormSchema = z.object({ + topics: z.array( + z.object({ + id: z.string(), + text: z.string(), + }) + ), +}) + +export const ExampleTagInput = () => { + const form = useForm>({ + resolver: zodResolver(FormSchema), + }) + + const autoCompleteTags = [ + { + id: '1307721023', + text: 'Sports', + }, + { + id: '3498601201', + text: 'Programming', + }, + { + id: '455992240', + text: 'Travel', + }, + ] + + const [tags, setTags] = useState([]) + const [activeTagIndex, setActiveTagIndex] = useState(null) + const {setValue} = form + + const [exampleTags, setExampleTags] = useState([]) + const [activeExampleTagIndex, setExampleActiveTagIndex] = useState< + number | null + >(null) + const {setValue: setExampleValue} = form + + function onSubmit(data: z.infer) { + toast({ + title: 'You submitted the following values:', + description: ( +
+          {JSON.stringify(data, null, 2)}
+        
+ ), + }) + } + + return ( + <> +

Basic use

+
+
+
+
+
+ + ( + + Topics + + { + setTags(newTags) + setValue('topics', newTags as [Tag, ...Tag[]]) + }} + /> + + + These are the topics that you're interested in. + + + + )} + /> + + + +
+
+
+
+

With autocomplete

+
+
+
+
+
+ + ( + + Topics + + { + setExampleTags(newTags) + setExampleValue( + 'topics', + newTags as [Tag, ...Tag[]] + ) + }} + /> + + + These are the topics that you're interested in. + + + + )} + /> + + + +
+
+
+
+ + ) +} diff --git a/projects/filigran-website/components/mdx-component.tsx b/projects/filigran-website/components/mdx-component.tsx index a3bc38d..25c011b 100644 --- a/projects/filigran-website/components/mdx-component.tsx +++ b/projects/filigran-website/components/mdx-component.tsx @@ -12,6 +12,7 @@ import {ExampleMultiSelect} from '@/components/example/example-multi-select' import {ExampleCombobox} from '@/components/example/example-combobox' import {ExampleToast} from '@/components/example/example-toast' import {ExampleSheet} from '@/components/example/example-sheet' +import {ExampleTagInput} from '@/components/example/example-tag-input' const options = { mdxOptions: { @@ -31,6 +32,7 @@ const components = { ExampleCombobox: ExampleCombobox, ExampleToast: ExampleToast, ExampleSheet: ExampleSheet, + ExampleTagInput: ExampleTagInput, } export async function CustomMDX(props: any) { diff --git a/projects/filigran-website/content/docs/components/tag-input.mdx b/projects/filigran-website/content/docs/components/tag-input.mdx new file mode 100644 index 0000000..3f65b23 --- /dev/null +++ b/projects/filigran-website/content/docs/components/tag-input.mdx @@ -0,0 +1,10 @@ +--- +title: Tabs +--- + +## Example + + + +## Docs +https://emblor.jaleelbennett.com/introduction diff --git a/yarn.lock b/yarn.lock index 8d753e9..9a48b3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,7 +33,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz" integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": +"@babel/core@^7.21.3": version "7.24.3" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz" integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== @@ -1046,7 +1046,7 @@ dependencies: tslib "^2.0.0" -"@dnd-kit/core@^6.1.0", "@dnd-kit/core@6.1.0": +"@dnd-kit/core@6.1.0": version "6.1.0" resolved "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz" integrity sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg== @@ -1095,6 +1095,116 @@ resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" @@ -1288,6 +1398,46 @@ dependencies: glob "10.3.10" +"@next/swc-darwin-arm64@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.4.tgz#da9f04c34a3d5f0b8401ed745768420e4a604036" + integrity sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg== + +"@next/swc-darwin-x64@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.4.tgz#46dedb29ec5503bf171a72a3ecb8aac6e738e9d6" + integrity sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg== + +"@next/swc-linux-arm64-gnu@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.4.tgz#c9697ab9eb422bd1d7ffd0eb0779cc2aefa9d4a1" + integrity sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ== + +"@next/swc-linux-arm64-musl@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.4.tgz#cbbceb2008571c743b5a310a488d2e166d200a75" + integrity sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A== + +"@next/swc-linux-x64-gnu@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.4.tgz#d79184223f857bacffb92f643cb2943a43632568" + integrity sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q== + +"@next/swc-linux-x64-musl@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.4.tgz#6b6c3e5ac02ca5e63394d280ec8ee607491902df" + integrity sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ== + +"@next/swc-win32-arm64-msvc@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.4.tgz#dbad3906e870dba84c5883d9d4c4838472e0697f" + integrity sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A== + +"@next/swc-win32-ia32-msvc@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.4.tgz#6074529b91ba49132922ce89a2e16d25d2ec235d" + integrity sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag== + "@next/swc-win32-x64-msvc@14.2.4": version "14.2.4" resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz" @@ -1301,7 +1451,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1857,6 +2007,76 @@ resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz" integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== +"@rollup/rollup-android-arm-eabi@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.2.tgz#fbf098f49d96a8cac9056f22f5fd80906ef3af85" + integrity sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g== + +"@rollup/rollup-android-arm64@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.2.tgz#0d2448251040fce19a98eee505dff5b3c8ec9b98" + integrity sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ== + +"@rollup/rollup-darwin-arm64@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.2.tgz#78db4d4da5b1b84c22adbe25c8a4961b3f22d3af" + integrity sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA== + +"@rollup/rollup-darwin-x64@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.2.tgz#fcc05af54379f8ee5c7e954987d4514c6fd0fb42" + integrity sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A== + +"@rollup/rollup-linux-arm-gnueabihf@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.2.tgz#2ce200efa1ef4a56ee2af7b453edc74a259d7d31" + integrity sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ== + +"@rollup/rollup-linux-arm64-gnu@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.2.tgz#5a24aac882bff9abfda3f45f6f1db2166c342a4a" + integrity sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ== + +"@rollup/rollup-linux-arm64-musl@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.2.tgz#f1fb4c6f961d3f3397231a99e621d199200e4ea9" + integrity sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.13.2.tgz#46b2463d94ac3af3e0f7a2947b695397bc13b755" + integrity sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ== + +"@rollup/rollup-linux-riscv64-gnu@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.2.tgz#47b932ee59a5395a3a341b0493e361d9e6032cf2" + integrity sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw== + +"@rollup/rollup-linux-s390x-gnu@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.2.tgz#8e14a1b3c3b9a4440c70a9c1ba12d32aa21f9712" + integrity sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg== + +"@rollup/rollup-linux-x64-gnu@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.2.tgz#270e939194b66df77bcb33dd9a5ddf7784bd7997" + integrity sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A== + +"@rollup/rollup-linux-x64-musl@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.2.tgz#e8dd0f3c2046acbda2934490b36552e856a3bc6a" + integrity sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA== + +"@rollup/rollup-win32-arm64-msvc@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.2.tgz#f8b65a4a7e7a6b383e7b14439129b2f474ff123c" + integrity sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA== + +"@rollup/rollup-win32-ia32-msvc@4.13.2": + version "4.13.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.2.tgz#bc1c5a4fbc4337d6cb15da80a4de95fd53ab3573" + integrity sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw== + "@rollup/rollup-win32-x64-msvc@4.13.2": version "4.13.2" resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.2.tgz" @@ -1937,7 +2157,7 @@ glob "^8.0.3" snake-case "^3.0.4" -"@svgr/core@*", "@svgr/core@8.1.0": +"@svgr/core@8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -2058,7 +2278,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@1.0.5": +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -2121,14 +2341,14 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz" integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== -"@types/react-dom@*", "@types/react-dom@18.3.0": +"@types/react-dom@18.3.0": version "18.3.0" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz" integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0", "@types/react@>=16", "@types/react@18.3.3": +"@types/react@*", "@types/react@18.3.3", "@types/react@>=16": version "18.3.3" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz" integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== @@ -2207,7 +2427,7 @@ acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.0.0, acorn@^8.8.2, acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -2308,6 +2528,11 @@ array-includes@^3.1.6, array-includes@^3.1.7: get-intrinsic "^1.2.4" is-string "^1.0.7" +array-move@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/array-move/-/array-move-3.0.1.tgz#179645cc0987b65953a4fc06b6df9045e4ba9618" + integrity sha512-H3Of6NIn2nNU1gsVDqDnYKY/LCdWvCMMOWifNGhKcVQgiZ6nOek39aESOvro6zmueP07exSl93YLvkN4fZOkSg== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" @@ -2499,7 +2724,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.22.2, browserslist@^4.23.0, "browserslist@>= 4.21.0": +browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -2638,16 +2863,16 @@ client-only@0.0.1: resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== -clsx@^2.0.0, clsx@2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" - integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== - clsx@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== +clsx@2.1.1, clsx@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + cmdk@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz" @@ -2670,16 +2895,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + comma-separated-tokens@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" @@ -2799,7 +3024,7 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -csstype@^3.0.2, csstype@^3.0.5, csstype@3.1.3: +csstype@3.1.3, csstype@^3.0.2, csstype@^3.0.5: version "3.1.3" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -3032,12 +3257,7 @@ entities@^2.0.0: resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.2.0: - version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -entities@^4.4.0: +entities@^4.2.0, entities@^4.4.0: version "4.5.0" resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== @@ -3165,7 +3385,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@^0.21.4, esbuild@>=0.17: +esbuild@^0.21.4: version "0.21.5" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz" integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== @@ -3258,7 +3478,7 @@ eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@*, eslint-plugin-import@^2.28.1: +eslint-plugin-import@^2.28.1: version "2.29.1" resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== @@ -3345,7 +3565,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.23.0 || ^8.0.0", eslint@8.57.0: +eslint@8.57.0: version "8.57.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== @@ -3527,67 +3747,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -"filigran-icon@file:C:\\Users\\Jean-PhilippeKha\\IdeaProjects\\monorepo\\packages\\filigran-icon": - version "0.8.1" - resolved "file:packages/filigran-icon" - -"filigran-ui@file:C:\\Users\\Jean-PhilippeKha\\IdeaProjects\\monorepo\\packages\\filigran-ui": - version "0.18.0" - resolved "file:packages/filigran-ui" - dependencies: - "@dnd-kit/core" "6.1.0" - "@dnd-kit/modifiers" "7.0.0" - "@dnd-kit/sortable" "8.0.0" - "@hookform/resolvers" "3.6.0" - "@radix-ui/react-accordion" "1.2.0" - "@radix-ui/react-alert-dialog" "1.1.1" - "@radix-ui/react-checkbox" "1.1.1" - "@radix-ui/react-dialog" "1.1.1" - "@radix-ui/react-dropdown-menu" "2.1.1" - "@radix-ui/react-label" "2.1.0" - "@radix-ui/react-popover" "1.1.1" - "@radix-ui/react-select" "2.1.1" - "@radix-ui/react-separator" "1.1.0" - "@radix-ui/react-slot" "1.1.0" - "@radix-ui/react-toast" "1.2.1" - "@tanstack/react-table" "8.19.2" - class-variance-authority "0.7.0" - clsx "2.1.1" - cmdk "1.0.0" - lucide-react "0.399.0" - react-hook-form "7.52.0" - tailwind-merge "2.3.0" - tailwindcss-animate "1.0.7" - zod "3.23.8" - -"filigran-website@file:C:\\Users\\Jean-PhilippeKha\\IdeaProjects\\monorepo\\projects\\filigran-website": - version "0.0.0" - resolved "file:projects/filigran-website" - dependencies: - "@faker-js/faker" "^8.4.1" - "@jsdevtools/rehype-toc" "3.0.2" - "@radix-ui/react-accordion" "1.2.0" - "@radix-ui/react-dropdown-menu" "2.1.1" - "@radix-ui/react-slot" "1.1.0" - "@radix-ui/react-tabs" "1.1.0" - class-variance-authority "0.7.0" - clsx "2.1.1" - lucide-react "0.399.0" - next "14.2.4" - next-mdx-remote "4.4.1" - next-themes "0.3.0" - react "18.3.1" - react-dom "18.3.1" - react-hook-form "^7.52.0" - react-live "4.1.7" - rehype-slug "6.0.0" - remark-gfm "3.0.0" - styled-components "6.1.11" - tailwind-merge "2.3.0" - tailwindcss-animate "1.0.7" - twind "0.16.19" - usehooks-ts "3.1.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -3642,6 +3801,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -3723,6 +3887,17 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob@10.3.10: + version "10.3.10" + resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^10.3.10: version "10.3.12" resolved "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz" @@ -3757,17 +3932,6 @@ glob@^8.0.3: minimatch "^5.0.1" once "^1.3.0" -glob@10.3.10: - version "10.3.10" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -5031,6 +5195,13 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -5052,13 +5223,6 @@ minimatch@^9.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -5074,16 +5238,16 @@ mri@^1.1.0: resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mz@^2.7.0: version "2.7.0" resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" @@ -5423,14 +5587,6 @@ postcss-nested@^6.0.1: dependencies: postcss-selector-parser "^6.0.11" -postcss-selector-parser@^6.0.11: - version "6.0.16" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz" - integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - postcss-selector-parser@6.0.10: version "6.0.10" resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" @@ -5439,20 +5595,19 @@ postcss-selector-parser@6.0.10: cssesc "^3.0.0" util-deprecate "^1.0.2" +postcss-selector-parser@^6.0.11: + version "6.0.16" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz" + integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8, postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.12, postcss@^8.4.21, postcss@^8.4.23, postcss@>=8.0.9, postcss@8.4.39: - version "8.4.39" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz" - integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.1" - source-map-js "^1.2.0" - postcss@8.4.31: version "8.4.31" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" @@ -5471,6 +5626,15 @@ postcss@8.4.38: picocolors "^1.0.0" source-map-js "^1.2.0" +postcss@8.4.39, postcss@^8.4.23: + version "8.4.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz" + integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -5481,16 +5645,16 @@ prettier-plugin-tailwindcss@0.6.5: resolved "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.5.tgz" integrity sha512-axfeOArc/RiGHjOIy9HytehlC0ZLeMaqY09mm8YCkMzznKiDkwFzOpBvtuhuv3xG5qB73+Mj7OCe2j/L1ryfuQ== +prettier@3.3.2: + version "3.3.2" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz" + integrity sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA== + prettier@^2.8.7: version "2.8.8" resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -prettier@^3.0, prettier@3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz" - integrity sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA== - prism-react-renderer@^2.0.6: version "2.3.1" resolved "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz" @@ -5523,14 +5687,6 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -"react-dom@^16.8 || ^17 || ^18", "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.8.0", react-dom@>=16.8, react-dom@>=16.8.0, "react-dom@>=16.x <=18.x", react-dom@>=18.0.0, react-dom@18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - react-dom@18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" @@ -5539,7 +5695,15 @@ react-dom@18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" -react-hook-form@^7.0.0, react-hook-form@^7.52.0, react-hook-form@7.52.0: +react-easy-sort@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/react-easy-sort/-/react-easy-sort-1.6.0.tgz#b40cce827913f0640c1b2e5438dd4d007e26db32" + integrity sha512-zd9Nn90wVlZPEwJrpqElN87sf9GZnFR1StfjgNQVbSpR5QTSzCHjEYK6REuwq49Ip+76KOMSln9tg/ST2KLelg== + dependencies: + array-move "^3.0.1" + tslib "2.0.1" + +react-hook-form@7.52.0, react-hook-form@^7.52.0: version "7.52.0" resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.0.tgz" integrity sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A== @@ -5597,14 +5761,7 @@ react-style-singleton@^2.2.1: invariant "^2.2.4" tslib "^2.0.0" -"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16.8.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16, react@>=16.0.0, react@>=16.8, react@>=16.8.0, "react@>=16.x <=18.x", react@>=18.0.0, react@18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -react@^18.3.1, react@18.3.1: +react@18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -5841,7 +5998,7 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -scheduler@^0.23.0, scheduler@^0.23.2: +scheduler@^0.23.2: version "0.23.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== @@ -5945,6 +6102,13 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + source-map@^0.6.0: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" @@ -5955,13 +6119,6 @@ source-map@^0.7.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== -source-map@0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - space-separated-tokens@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" @@ -5972,16 +6129,8 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6053,14 +6202,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -6195,7 +6337,7 @@ tailwindcss-scoped-preflight@3.3.0: resolved "https://registry.npmjs.org/tailwindcss-scoped-preflight/-/tailwindcss-scoped-preflight-3.3.0.tgz" integrity sha512-4UQLG5zAcOwo3Y+HYte6ZtIl6jisw9Bit9s8BYsmpnv+1fil8MIKfiWW+SYeQ+DMSLXxpYla1ar7BUXwlwhtjw== -tailwindcss@^3, "tailwindcss@>=3.0.0 || insiders", tailwindcss@3.4.4: +tailwindcss@3.4.4: version "3.4.4" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz" integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== @@ -6311,7 +6453,12 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@2.6.2: +tslib@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" + integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== + +tslib@2.6.2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: version "2.6.2" resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -6401,11 +6548,6 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript@^4.1.0, typescript@>=3.3.1, typescript@>=4.2.0, typescript@>=4.5.0, typescript@>=4.9.5: - version "5.4.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz" - integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== - typescript@5.5.2: version "5.5.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz"