From 3efdd8850c4cca2c980b54d2d8149a098349a840 Mon Sep 17 00:00:00 2001 From: Stouffi <765497+Stouffi@users.noreply.github.com> Date: Sat, 24 Sep 2022 09:08:50 +0200 Subject: [PATCH] [@mantine/core] Fix missing ref type in components with static parts (#2505) * [@mantine/core] Fix types for components that forward ref * [@mantine/core] Polish: remove ref prop where it should not appear HorizontalSectionProps and PrismProps should not contain ref in their props --- package.json | 2 +- src/mantine-carousel/src/Carousel.tsx | 1 + src/mantine-core/src/AppShell/Aside/Aside.tsx | 8 ++++++-- .../src/AppShell/HorizontalSection/HorizontalSection.tsx | 2 +- src/mantine-core/src/AppShell/Navbar/Navbar.tsx | 8 ++++++-- src/mantine-core/src/Checkbox/Checkbox.tsx | 3 ++- src/mantine-core/src/Chip/Chip.tsx | 8 ++++++-- src/mantine-core/src/Grid/Grid.test.tsx | 9 +++++++++ src/mantine-core/src/Grid/Grid.tsx | 4 ++-- src/mantine-core/src/List/List.tsx | 6 +++++- src/mantine-core/src/Radio/Radio.tsx | 8 ++++++-- src/mantine-core/src/ScrollArea/ScrollArea.tsx | 1 + src/mantine-core/src/Stepper/Stepper.tsx | 3 ++- src/mantine-core/src/Switch/Switch.tsx | 6 +++++- src/mantine-core/src/Tabs/Tabs.tsx | 1 + src/mantine-core/src/Timeline/Timeline.test.tsx | 6 ++++++ src/mantine-core/src/Timeline/Timeline.tsx | 3 ++- src/mantine-core/src/Tooltip/Tooltip.tsx | 1 + src/mantine-dropzone/src/Dropzone.tsx | 3 ++- src/mantine-prism/src/Prism/Prism.tsx | 2 +- src/mantine-prism/src/index.ts | 1 + src/mantine-utils/src/ForwardRefWithStaticComponents.ts | 8 ++++---- yarn.lock | 8 ++++---- 23 files changed, 75 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index ff2cbac265d..c5a007afbcd 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "new-github-release-url": "^1.0.0", "next": "^12.2.0", "open": "^8.2.0", - "prettier": "^2.4.1", + "prettier": "^2.7.1", "react-beautiful-dnd": "^13.1.0", "react-docgen-typescript": "2.1.0", "react-dom": "18.1.0", diff --git a/src/mantine-carousel/src/Carousel.tsx b/src/mantine-carousel/src/Carousel.tsx index 39ab41976e7..f5cf368fe8b 100644 --- a/src/mantine-carousel/src/Carousel.tsx +++ b/src/mantine-carousel/src/Carousel.tsx @@ -344,6 +344,7 @@ _Carousel.Slide = CarouselSlide; _Carousel.displayName = '@mantine/carousel/Carousel'; export const Carousel: ForwardRefWithStaticComponents< + HTMLDivElement, CarouselProps, { Slide: typeof CarouselSlide } > = _Carousel; diff --git a/src/mantine-core/src/AppShell/Aside/Aside.tsx b/src/mantine-core/src/AppShell/Aside/Aside.tsx index 59bce899bfe..cfdbd7dbf79 100644 --- a/src/mantine-core/src/AppShell/Aside/Aside.tsx +++ b/src/mantine-core/src/AppShell/Aside/Aside.tsx @@ -9,12 +9,16 @@ import { Section } from '../HorizontalSection/Section/Section'; export interface AsideProps extends HorizontalSectionSharedProps, - React.ComponentPropsWithRef<'nav'> { + React.ComponentPropsWithoutRef<'nav'> { /** Aside content */ children: React.ReactNode; } -type AsideComponent = ForwardRefWithStaticComponents; +type AsideComponent = ForwardRefWithStaticComponents< + HTMLElement, + AsideProps, + { Section: typeof Section } +>; const defaultProps: Partial = { fixed: false, diff --git a/src/mantine-core/src/AppShell/HorizontalSection/HorizontalSection.tsx b/src/mantine-core/src/AppShell/HorizontalSection/HorizontalSection.tsx index 8ee7a37137c..79560b2c347 100644 --- a/src/mantine-core/src/AppShell/HorizontalSection/HorizontalSection.tsx +++ b/src/mantine-core/src/AppShell/HorizontalSection/HorizontalSection.tsx @@ -39,7 +39,7 @@ export interface HorizontalSectionSharedProps extends DefaultProps { export interface HorizontalSectionProps extends HorizontalSectionSharedProps, - Omit, 'children'> { + Omit, 'children'> { section: 'navbar' | 'aside'; __staticSelector: string; } diff --git a/src/mantine-core/src/AppShell/Navbar/Navbar.tsx b/src/mantine-core/src/AppShell/Navbar/Navbar.tsx index 751ad6cfb2f..48371a1378d 100644 --- a/src/mantine-core/src/AppShell/Navbar/Navbar.tsx +++ b/src/mantine-core/src/AppShell/Navbar/Navbar.tsx @@ -9,12 +9,16 @@ import { Section } from '../HorizontalSection/Section/Section'; export interface NavbarProps extends HorizontalSectionSharedProps, - React.ComponentPropsWithRef<'nav'> { + React.ComponentPropsWithoutRef<'nav'> { /** Navbar content */ children: React.ReactNode; } -type NavbarComponent = ForwardRefWithStaticComponents; +type NavbarComponent = ForwardRefWithStaticComponents< + HTMLElement, + NavbarProps, + { Section: typeof Section } +>; const defaultProps: Partial = { fixed: false, diff --git a/src/mantine-core/src/Checkbox/Checkbox.tsx b/src/mantine-core/src/Checkbox/Checkbox.tsx index 7a62e7e06f9..ce3d29e6935 100644 --- a/src/mantine-core/src/Checkbox/Checkbox.tsx +++ b/src/mantine-core/src/Checkbox/Checkbox.tsx @@ -20,7 +20,7 @@ export type CheckboxStylesNames = Selectors; export interface CheckboxProps extends DefaultProps, - Omit, 'type' | 'size'> { + Omit, 'type' | 'size'> { /** Key of theme.colors */ color?: MantineColor; @@ -56,6 +56,7 @@ const defaultProps: Partial = { }; type CheckboxComponent = ForwardRefWithStaticComponents< + HTMLInputElement, CheckboxProps, { Group: typeof CheckboxGroup } >; diff --git a/src/mantine-core/src/Chip/Chip.tsx b/src/mantine-core/src/Chip/Chip.tsx index 951dcb40dd5..bbec06f1767 100644 --- a/src/mantine-core/src/Chip/Chip.tsx +++ b/src/mantine-core/src/Chip/Chip.tsx @@ -20,7 +20,7 @@ export type ChipStylesNames = Selectors; export interface ChipProps extends DefaultProps, - Omit, 'size' | 'onChange'> { + Omit, 'size' | 'onChange'> { /** Chip radius from theme or number to set value in px */ radius?: MantineNumberSize; @@ -62,7 +62,11 @@ const defaultProps: Partial = { variant: 'outline', }; -type ChipComponent = ForwardRefWithStaticComponents; +type ChipComponent = ForwardRefWithStaticComponents< + HTMLInputElement, + ChipProps, + { Group: typeof ChipGroup } +>; export const Chip: ChipComponent = forwardRef((props, ref) => { const { diff --git a/src/mantine-core/src/Grid/Grid.test.tsx b/src/mantine-core/src/Grid/Grid.test.tsx index a0032cd0f71..a6183fb51f1 100644 --- a/src/mantine-core/src/Grid/Grid.test.tsx +++ b/src/mantine-core/src/Grid/Grid.test.tsx @@ -26,6 +26,15 @@ describe('@mantine/core/Grid', () => { expect(Grid.Col).toBe(Col); }); + it('supports getting Grid ref', () => { + const ref = React.createRef(); + render( + + + + ); + expect(ref.current instanceof HTMLDivElement).toBe(true); + }); it('supports getting Col ref', () => { const ref = React.createRef(); render( diff --git a/src/mantine-core/src/Grid/Grid.tsx b/src/mantine-core/src/Grid/Grid.tsx index 4024c44be3c..1f41d75c794 100644 --- a/src/mantine-core/src/Grid/Grid.tsx +++ b/src/mantine-core/src/Grid/Grid.tsx @@ -6,7 +6,7 @@ import { Col } from './Col/Col'; import { GridProvider } from './Grid.context'; import useStyles from './Grid.styles'; -export interface GridProps extends DefaultProps, React.ComponentPropsWithRef<'div'> { +export interface GridProps extends DefaultProps, React.ComponentPropsWithoutRef<'div'> { /** components only */ children: React.ReactNode; @@ -26,7 +26,7 @@ export interface GridProps extends DefaultProps, React.ComponentPropsWithRef<'di columns?: number; } -type GridComponent = ForwardRefWithStaticComponents; +type GridComponent = ForwardRefWithStaticComponents; const defaultProps: Partial = { gutter: 'md', diff --git a/src/mantine-core/src/List/List.tsx b/src/mantine-core/src/List/List.tsx index 2815192c069..4a6e3118a00 100644 --- a/src/mantine-core/src/List/List.tsx +++ b/src/mantine-core/src/List/List.tsx @@ -42,7 +42,11 @@ export interface ListProps listStyleType?: React.CSSProperties['listStyleType']; } -type ListComponent = ForwardRefWithStaticComponents; +type ListComponent = ForwardRefWithStaticComponents< + HTMLUListElement, + ListProps, + { Item: typeof ListItem } +>; const defaultProps: Partial = { type: 'unordered', diff --git a/src/mantine-core/src/Radio/Radio.tsx b/src/mantine-core/src/Radio/Radio.tsx index d3b04621b64..ff6df714b1e 100644 --- a/src/mantine-core/src/Radio/Radio.tsx +++ b/src/mantine-core/src/Radio/Radio.tsx @@ -19,7 +19,7 @@ export type RadioStylesNames = Selectors; export interface RadioProps extends DefaultProps, - Omit, 'size'> { + Omit, 'size'> { /** Radio label */ label?: React.ReactNode; @@ -48,7 +48,11 @@ const defaultProps: Partial = { size: 'sm', }; -type RadioComponent = ForwardRefWithStaticComponents; +type RadioComponent = ForwardRefWithStaticComponents< + HTMLInputElement, + RadioProps, + { Group: typeof RadioGroup } +>; export const Radio: RadioComponent = forwardRef((props, ref) => { const { diff --git a/src/mantine-core/src/ScrollArea/ScrollArea.tsx b/src/mantine-core/src/ScrollArea/ScrollArea.tsx index 365bc6afbc3..1d23cbced33 100644 --- a/src/mantine-core/src/ScrollArea/ScrollArea.tsx +++ b/src/mantine-core/src/ScrollArea/ScrollArea.tsx @@ -164,6 +164,7 @@ _ScrollArea.displayName = '@mantine/core/ScrollArea'; _ScrollArea.Autosize = ScrollAreaAutosize; export const ScrollArea: ForwardRefWithStaticComponents< + HTMLDivElement, ScrollAreaProps, { Autosize: typeof ScrollAreaAutosize; diff --git a/src/mantine-core/src/Stepper/Stepper.tsx b/src/mantine-core/src/Stepper/Stepper.tsx index 30406e4284d..a9a3195e487 100644 --- a/src/mantine-core/src/Stepper/Stepper.tsx +++ b/src/mantine-core/src/Stepper/Stepper.tsx @@ -17,7 +17,7 @@ export type StepperStylesNames = Selectors | StepStylesNames; export interface StepperProps extends DefaultProps, - React.ComponentPropsWithRef<'div'> { + React.ComponentPropsWithoutRef<'div'> { /** components only */ children: React.ReactNode; @@ -59,6 +59,7 @@ export interface StepperProps } type StepperComponent = ForwardRefWithStaticComponents< + HTMLDivElement, StepperProps, { Step: typeof Step; diff --git a/src/mantine-core/src/Switch/Switch.tsx b/src/mantine-core/src/Switch/Switch.tsx index 0d4c87c098d..396b2512562 100644 --- a/src/mantine-core/src/Switch/Switch.tsx +++ b/src/mantine-core/src/Switch/Switch.tsx @@ -55,7 +55,11 @@ const defaultProps: Partial = { radius: 'xl', }; -type SwitchComponent = ForwardRefWithStaticComponents; +type SwitchComponent = ForwardRefWithStaticComponents< + HTMLInputElement, + SwitchProps, + { Group: typeof SwitchGroup } +>; export const Switch: SwitchComponent = forwardRef((props, ref) => { const { diff --git a/src/mantine-core/src/Tabs/Tabs.tsx b/src/mantine-core/src/Tabs/Tabs.tsx index 6f2c11f0653..3d69452ff8a 100644 --- a/src/mantine-core/src/Tabs/Tabs.tsx +++ b/src/mantine-core/src/Tabs/Tabs.tsx @@ -26,6 +26,7 @@ export interface TabsProps Omit, keyof TabsProviderProps> {} type TabsComponent = ForwardRefWithStaticComponents< + HTMLDivElement, TabsProps, { List: typeof TabsList; diff --git a/src/mantine-core/src/Timeline/Timeline.test.tsx b/src/mantine-core/src/Timeline/Timeline.test.tsx index dea706ba844..183ba96834c 100644 --- a/src/mantine-core/src/Timeline/Timeline.test.tsx +++ b/src/mantine-core/src/Timeline/Timeline.test.tsx @@ -39,6 +39,12 @@ describe('@mantine/core/Timeline', () => { ); }); + it('supports getting Timeline ref', () => { + const ref = React.createRef(); + render(); + expect(ref.current instanceof HTMLDivElement).toBe(true); + }); + it('exposes TimelineItem as Timeline.Item', () => { expect(Timeline.Item).toBe(TimelineItem); }); diff --git a/src/mantine-core/src/Timeline/Timeline.tsx b/src/mantine-core/src/Timeline/Timeline.tsx index 2e827a5fa34..ab727774f96 100644 --- a/src/mantine-core/src/Timeline/Timeline.tsx +++ b/src/mantine-core/src/Timeline/Timeline.tsx @@ -12,7 +12,7 @@ import { TimelineItem, TimelineItemStylesNames } from './TimelineItem/TimelineIt export interface TimelineProps extends DefaultProps, - React.ComponentPropsWithRef<'div'> { + React.ComponentPropsWithoutRef<'div'> { /** components only */ children: React.ReactNode; @@ -39,6 +39,7 @@ export interface TimelineProps } type TimelineComponent = ForwardRefWithStaticComponents< + HTMLDivElement, TimelineProps, { Item: typeof TimelineItem } >; diff --git a/src/mantine-core/src/Tooltip/Tooltip.tsx b/src/mantine-core/src/Tooltip/Tooltip.tsx index 153eb358050..9bb0cd1e559 100644 --- a/src/mantine-core/src/Tooltip/Tooltip.tsx +++ b/src/mantine-core/src/Tooltip/Tooltip.tsx @@ -183,6 +183,7 @@ _Tooltip.Floating = TooltipFloating; _Tooltip.displayName = '@mantine/core/Tooltip'; export const Tooltip: ForwardRefWithStaticComponents< + HTMLElement, TooltipProps, { Group: typeof TooltipGroup; Floating: typeof TooltipFloating } > = _Tooltip; diff --git a/src/mantine-dropzone/src/Dropzone.tsx b/src/mantine-dropzone/src/Dropzone.tsx index 8edecc8c684..feede24858a 100644 --- a/src/mantine-dropzone/src/Dropzone.tsx +++ b/src/mantine-dropzone/src/Dropzone.tsx @@ -19,7 +19,7 @@ export type DropzoneStylesNames = Selectors; export interface DropzoneProps extends DefaultProps, - Omit, 'onDrop'> { + Omit, 'onDrop'> { /** Padding from theme.spacing, or number to set padding in px */ padding?: MantineNumberSize; @@ -201,6 +201,7 @@ _Dropzone.Reject = DropzoneReject; _Dropzone.Idle = DropzoneIdle; export const Dropzone: ForwardRefWithStaticComponents< + HTMLDivElement, DropzoneProps, { Accept: typeof DropzoneAccept; diff --git a/src/mantine-prism/src/Prism/Prism.tsx b/src/mantine-prism/src/Prism/Prism.tsx index 61aa229f5b7..7ac62d85ac0 100644 --- a/src/mantine-prism/src/Prism/Prism.tsx +++ b/src/mantine-prism/src/Prism/Prism.tsx @@ -22,7 +22,7 @@ export type PrismStylesNames = Selectors; export interface PrismProps extends DefaultProps, - Omit, 'children'> { + Omit, 'children'> { /** Code which will be highlighted */ children: string; diff --git a/src/mantine-prism/src/index.ts b/src/mantine-prism/src/index.ts index f4808deba50..d2685381458 100644 --- a/src/mantine-prism/src/index.ts +++ b/src/mantine-prism/src/index.ts @@ -9,6 +9,7 @@ export type { PrismProps, PrismStylesNames } from './Prism/Prism'; export type { PrismStylesParams } from './Prism/Prism.styles'; type PrismComponent = ForwardRefWithStaticComponents< + HTMLDivElement, PrismProps, { Tabs: typeof PrismTabs; diff --git a/src/mantine-utils/src/ForwardRefWithStaticComponents.ts b/src/mantine-utils/src/ForwardRefWithStaticComponents.ts index c5c937d21e9..7636ffb8518 100644 --- a/src/mantine-utils/src/ForwardRefWithStaticComponents.ts +++ b/src/mantine-utils/src/ForwardRefWithStaticComponents.ts @@ -1,7 +1,7 @@ +import { forwardRef } from 'react'; + export type ForwardRefWithStaticComponents< + T, Props extends Record, Static extends Record -> = ((props: Props) => React.ReactElement) & - Static & { - displayName: string; - }; +> = ReturnType> & Static; diff --git a/yarn.lock b/yarn.lock index 67bcb13eba6..461025e38f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11378,10 +11378,10 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== -prettier@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== pretty-error@^2.1.1: version "2.1.2"