tabler / tabler-icons

A set of over 5400 free MIT-licensed high-quality SVG icons for you to use in your web projects.
https://tabler.io/icons
MIT License
17.84k stars 886 forks source link

3.0 breaking changes? #1035

Closed naughton closed 4 weeks ago

naughton commented 5 months ago

I was using TablerIconProps in 2.x in the following way:

const lookup = Record<string, (props: TablerIconProps) => JSX.Element) = {
   key: IconFoo,
   key2: IconBar, ...

In 3.0 TablerIconProps is has been renamed IconProps, but also because the icons are now a ForwardRefExoticComponent, they no longer match (props: IconProps) => JSX.Element...

Type 'ForwardRefExoticComponent<Omit<IconProps, "ref"> & RefAttributes<SVGSVGElement>>' is not assignable to type '(props: IconProps) => Element'.
  Type 'ReactNode' is not assignable to type 'Element'.
    Type 'undefined' is not assignable to type 'ReactElement<any, any>'

changing the type to (props: IconProps) => ReactNode solves the problem...

Should this have been documented in the release notes for 3.0?

Also, I think changing the name from TablerIconsProps to IconProps was a poor choice, since every other IconXXX export is an actual Icon... what if someone wanted to make an icon for properties and wanted to call it IconProps?

dandudzi commented 5 months ago

Same problem here. Until there are is no clear list of changes and how to upgrade to the new version I withhold with upgrading to the new version.

codecalm commented 5 months ago

@naughton @dandudzi those changes are non intentional, I'm working on w 3.0.1 with fixes

codecalm commented 5 months ago

@naughton @dandudzi i'm working on it in #1037, can you check it?

naughton commented 5 months ago

3.0.1 did not resolve the issue...

the type signature for icons is still react.ForwardRefExoticComponent<Omit<IconProps, "ref"> & react.RefAttributes<Icon>>

naughton commented 5 months ago

maybe you could export a type like this for a better "dx"?

import { ForwardRefExoticComponent, RefAttributes, FunctionComponent } from "react";

export type TablerIcon = ForwardRefExoticComponent<
  Omit<IconProps, "ref"> & RefAttributes<FunctionComponent<IconProps>>
>;
Darathor17 commented 5 months ago

@naughton did you made it work? IconProps for me it's stil not equivalent and a breaking change (that forces me to revert to 2.x)

codecalm commented 5 months ago

@Darathor17 Icon type has been exported in v3.0.2 version

Darathor17 commented 5 months ago

@Darathor17 Icon type has been exported in v3.0.2 version

Thx for your quick reply.

It's not ideal as I had to create a custom type

import { IconProps, Icon } from '@tabler/icons-react';
export type TablerIcon = React.ForwardRefExoticComponent<Omit<IconProps, "ref"> & React.RefAttributes<Icon>>

While it works, a simpler implementation would be welcome and a less breaking change in our build

codecalm commented 5 months ago

can you create PR with your proposition of final type?

naughton commented 5 months ago

https://github.com/tabler/tabler-icons/pull/1058

m42-k commented 5 months ago

I was using Tabler Icon this way in 2.4.7...

--- Usage
<PageIconHome size={iconSize} strokeWidth={IconStrokeWidth} />

-- Common
import {
TablerIconsProps
} from "@tabler/icons-react";

export const PageIconHome = (props: TablerIconsProps) => (
  <IconHome2 {...defaultIconProps} {...props} />
);

Now i'm using it this way in 3.1.0...

--- Usage
<PageIconHome size={iconSize} strokeWidth={IconStrokeWidth} />

-- Common
import {
  Icon,
  IconProps
} from "@tabler/icons-react";

interface TablerIconProps
  extends Partial<
    ForwardRefExoticComponent<
      Omit<IconProps, "ref"> & RefAttributes<Icon>
    >
  > {
  size?: string | number;
  stroke?: string | number;
  strokeWidth?: string | number;
  className?: string;
}

export const PageIconHome = (props: TablerIconProps) => (
  <IconHome2 {...defaultIconProps} {...props} />
  );

This is allowing us to create icon components and use them in multiple areas while only have a single Icon declared. We can also override the icon props as required for specific use cases.

From version 3, the implementation outside of the library is a lot more complex and seems unnecessary. I do agree with the comments in this thread. However, I don't think the type suggested quite fits our use case.

rommelmamedov commented 4 months ago

I've upgraded from version 2.47.0 to 3.2.0 and created this custom type to address backward compatibility issues.

import { IconProps } from '@tabler/icons-react';

export type TablerIconsProps = Partial<
  ForwardRefExoticComponent<Omit<IconProps, 'ref'> & RefAttributes<FunctionComponent<IconProps>>>
> & {
  className?: string;
  size?: string | number;
  stroke?: string | number;
  strokeWidth?: string | number;
  style?: CSSProperties;
};

I hope it's useful.

CHE1RON commented 3 months ago

Thanks @rommelmamedov, this is super helpful! 🤩

codecalm commented 3 months ago

@rommelmamedov can you create PR with this fix?

BG-Software-BG commented 4 weeks ago

@naughton @CHE1RON is this issue fixed in the newest versions of @tabler/icons-react?

naughton commented 4 weeks ago

I believe they merged my PR on April 30....

https://github.com/tabler/tabler-icons/pull/1058

CHE1RON commented 4 weeks ago

I'm good, thanks 😉