diff --git a/README.md b/README.md index 14a24e0f..81ffbcb6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Using Force UI as a dependency in package.json - ```json "dependencies": { - "@bsf/force-ui": "git+https://github.com/brainstormforce/force-ui#1.0.0" + "@bsf/force-ui": "git+https://github.com/brainstormforce/force-ui#1.2.2" } ``` diff --git a/changelog.txt b/changelog.txt index a19d72c3..62b39fe6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +Version 1.2.2 - 4th December, 2024 +- Improvement - Removed margin and added new props to the Line Chart component for customizability. + Version 1.2.1 - 25th November, 2024 - Improvement - Added new props to the Bar Chart component for customizability. - Improvement - Dropzone UAT improvements. diff --git a/package.json b/package.json index 96abec9b..28c9c5b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bsf/force-ui", - "version": "1.2.1", + "version": "1.2.2", "description": "Library of components for the BSF project", "main": "./dist/force-ui.js", "module": "./dist/force-ui.js", diff --git a/src/components/dropdown-menu/dropdown-menu.stories.tsx b/src/components/dropdown-menu/dropdown-menu.stories.tsx index b932ecf3..3e888d20 100644 --- a/src/components/dropdown-menu/dropdown-menu.stories.tsx +++ b/src/components/dropdown-menu/dropdown-menu.stories.tsx @@ -13,6 +13,7 @@ const meta: Meta = { 'DropdownMenu.List': DropdownMenu.List, 'DropdownMenu.Item': DropdownMenu.Item, 'DropdownMenu.Separator': DropdownMenu.Separator, + 'DropdownMenu.Portal': DropdownMenu.Portal, } as Record>, parameters: { layout: 'centered', @@ -34,15 +35,17 @@ export const ButtonTrigger: Story = ( args ) => ( - - - Menu Item 1 - Menu Item 2 - Menu Item 3 - Menu Item 4 - Menu Item 5 - - + + + + Menu Item 1 + Menu Item 2 + Menu Item 3 + Menu Item 4 + Menu Item 5 + + + ); @@ -52,15 +55,17 @@ export const AvatarTrigger: Story = ( args ) => ( John Open Menu - - - Menu Item 1 - Menu Item 2 - Menu Item 3 - Menu Item 4 - Menu Item 5 - - + + + + Menu Item 1 + Menu Item 2 + Menu Item 3 + Menu Item 4 + Menu Item 5 + + + ); @@ -70,14 +75,16 @@ export const IconTrigger: Story = ( args ) => ( Open Menu - - - Menu Item 1 - Menu Item 2 - Menu Item 3 - Menu Item 4 - Menu Item 5 - - + + + + Menu Item 1 + Menu Item 2 + Menu Item 3 + Menu Item 4 + Menu Item 5 + + + ); diff --git a/src/components/dropdown-menu/dropdown-menu.tsx b/src/components/dropdown-menu/dropdown-menu.tsx index 6cdcf2f3..b1c6b0cf 100644 --- a/src/components/dropdown-menu/dropdown-menu.tsx +++ b/src/components/dropdown-menu/dropdown-menu.tsx @@ -19,6 +19,8 @@ import { FloatingPortal, useInteractions, useTransitionStyles, + type UseFloatingReturn, + type UseInteractionsReturn, } from '@floating-ui/react'; import { callAll, cn } from '@/utilities/functions'; import Menu from '../menu-item/menu-item'; @@ -29,6 +31,7 @@ import { DropdownMenuListProps, DropdownMenuProps, DropdownMenuSeparatorProps, + DropdownPortalProps, HandleClose, } from './dropdown-types'; @@ -39,8 +42,6 @@ export const DropdownMenu = ( { placement = 'bottom', offset: offsetValue = 10, boundary = 'clippingAncestors', - dropdownPortalRoot, - dropdownPortalId, children, className, }: DropdownMenuProps ) => { @@ -81,7 +82,16 @@ export const DropdownMenu = ( { const handleClose = () => setIsOpen( false ); return ( - +
{ React.Children.map( children, ( child ) => { if ( @@ -101,35 +111,19 @@ export const DropdownMenu = ( { return null; } ) } - { isMounted && ( - -
- { React.Children.map( children, ( child ) => { - if ( - ( - child as ReactElement & { - type?: { displayName: string }; - } - )?.type?.displayName === - 'DropdownMenu.Content' - ) { - return child; - } - return null; - } ) } -
-
- ) } + { React.Children.map( children, ( child ) => { + if ( + React.isValidElement( child ) && + ( + child as ReactElement & { + type: { displayName: string }; + } + )?.type?.displayName === 'DropdownMenu.Portal' + ) { + return child; + } + return null; + } ) }
); @@ -137,13 +131,60 @@ export const DropdownMenu = ( { DropdownMenu.displayName = 'DropdownMenu'; +export const DropdownMenuPortal = ( { + children, + className, + root, + id, +}: DropdownPortalProps ) => { + const { refs, floatingStyles, getFloatingProps, isMounted, styles } = + useDropdownMenuContext() as { + refs: UseFloatingReturn['refs']; + floatingStyles: UseFloatingReturn['floatingStyles']; + getFloatingProps: UseInteractionsReturn['getFloatingProps']; + isMounted: boolean; + styles: React.CSSProperties; + }; + + return ( + isMounted && ( + +
+ { React.Children.map( children, ( child ) => { + if ( + ( + child as ReactElement & { + type?: { displayName: string }; + } + )?.type?.displayName === 'DropdownMenu.Content' + ) { + return child; + } + return null; + } ) } +
+
+ ) + ); +}; + +DropdownMenuPortal.displayName = 'DropdownMenu.Portal'; + export const DropdownMenuTrigger = React.forwardRef< HTMLDivElement, DropdownCommonProps ->( ( { children, className, ...props }, ref ) => { +>( ( { children, className, ...props }: DropdownCommonProps, ref ) => { if ( isValidElement( children ) ) { return React.cloneElement( children as React.ReactElement, { - className, + className: cn( className, children.props.className ), ref, ...props, } ); @@ -188,11 +229,11 @@ export const DropdownMenuList = ( props: DropdownMenuListProps ) => { DropdownMenuList.displayName = 'DropdownMenu.List'; -export const DropdownMenuItem: React.FC = ( { +export const DropdownMenuItem = ( { children, as: Tag = Menu.Item, ...props -} ) => { +}: DropdownMenuItemProps ) => { const { handleClose } = useDropdownMenuContext(); if ( ! children ) { @@ -232,5 +273,6 @@ DropdownMenu.Content = DropdownMenuContent; DropdownMenu.List = DropdownMenuList; DropdownMenu.Item = DropdownMenuItem; DropdownMenu.Separator = DropdownMenuSeparator; +DropdownMenu.Portal = DropdownMenuPortal; export default DropdownMenu; diff --git a/src/components/dropdown-menu/dropdown-types.ts b/src/components/dropdown-menu/dropdown-types.ts index 96603db1..753d2719 100644 --- a/src/components/dropdown-menu/dropdown-types.ts +++ b/src/components/dropdown-menu/dropdown-types.ts @@ -42,10 +42,6 @@ export interface DropdownMenuProps extends DropdownCommonProps { offset?: OffsetOptions; /** Defines the boundary of the dropdown menu. */ boundary?: Boundary; - /** Defines the trigger element of the dropdown menu. */ - dropdownPortalRoot?: FloatingPortalProps['root']; - /** Defines the trigger element of the dropdown menu. */ - dropdownPortalId?: FloatingPortalProps['id']; /** Additional class name */ className?: string; } @@ -61,6 +57,20 @@ export interface DropdownMenuItemProps { className?: string; } +export interface DropdownPortalProps extends DropdownCommonProps { + /** + * The ID of the portal where the dropdown will be rendered. + * @default undefined + */ + id?: FloatingPortalProps['id']; + + /** + * The root element where the dropdown will be rendered. + * @default undefined + */ + root?: FloatingPortalProps['root']; +} + export type DropdownMenuSeparatorProps = MenuSeparatorProps; export type DropdownMenuListProps = MenuListProps; diff --git a/src/components/line-chart/line-chart.tsx b/src/components/line-chart/line-chart.tsx index 1000ff2e..170a27fb 100644 --- a/src/components/line-chart/line-chart.tsx +++ b/src/components/line-chart/line-chart.tsx @@ -8,6 +8,7 @@ import { } from 'recharts'; import ChartTooltipContent from './chart-tooltip-content'; import Label from '../label'; +import type { CategoricalChartProps } from 'recharts/types/chart/generateCategoricalChart'; interface DataItem { [key: string]: number | string; @@ -70,6 +71,15 @@ interface LineChartProps { /** Determines whether dots are shown on each data point. */ withDots?: boolean; + + /** + * Line chart Wrapper props to apply additional props to the wrapper component. Ex. `margin`, or `onClick` etc. + * @see https://recharts.org/en-US/api/LineChart + */ + lineChartWrapperProps?: Omit< + CategoricalChartProps, + 'width' | 'height' | 'data' + >; } const LineChart = ( { @@ -91,6 +101,7 @@ const LineChart = ( { chartWidth = 350, chartHeight = 200, withDots = false, + lineChartWrapperProps, }: LineChartProps ) => { const defaultColors = [ { stroke: '#2563EB' }, { stroke: '#38BDF8' } ]; @@ -114,10 +125,10 @@ const LineChart = ( { return ( { showCartesianGrid && } { showXAxis && ( diff --git a/version.json b/version.json index 305f0d27..7fd3c879 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "force-ui": "1.2.1" + "force-ui": "1.2.2" }