web-padawan / vanilla-colorful

A tiny color picker custom element for modern web apps (2.7 KB) 🎨
https://web-padawan.github.io/vanilla-colorful/
MIT License
784 stars 29 forks source link

[Feat] Update React example #108

Open SalahAdDin opened 3 weeks ago

SalahAdDin commented 3 weeks ago

We are using this library for creating a color picker popover in React. We followed the example but it gives some errors: image Types are wrong and the the event for changing the color does not work.

Our component is as follows:

const ColorPickerPopover = forwardRef<JSX.Element, ColorPickerPopoverProps>(
  ({ onExit, onRemove, color: currentColor, onChange }, ref) => {
    const [color, setColor] = useState(currentColor);

    return (
      <Popover
        source={ref}       
        placement="bottom"
        spacing="8"
      >
     <Flex alignItems="start" gap={1}>
          <Box>
            <hex-color-picker
              color={color}
              onEventColorChanged={(event) => setColor(event.detail.value)}
            />
          </Box>
        </Flex>
      </Popover>
    );
  }
);

export default ColorPickerPopover;

And we declare the types on custom.d.ts:

declare module "@strapi/design-system/*";
declare module "@strapi/design-system";
declare module "@strapi/icons";
declare module "@strapi/icons/*";
declare module "@strapi/helper-plugin";

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "hex-color-picker": {
        color: string;
        onEventColorChanged: (event: CustomEvent<{ value: string }>) => void;
      };
    }
  }
}

With the following tsconfig.js:

{
  "extends": "@strapi/typescript-utils/tsconfigs/admin",

  "compilerOptions": {
    "target": "ESNext",
    "strict": true
  },

  "include": ["admin", "custom.d.ts"],

  "exclude": [
    "node_modules/",
    "dist/",

    "server/",
    "**/*.test.ts"
  ]
}

Types work when you declare the types in the file itself, but it is not a good practice.


export default ColorPickerPopover;

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "hex-color-picker": {
        color: string;
        onEventColorChanged: (event: CustomEvent<{ value: string }>) => void;
      };
    }
  }
}

The function does not work cause the event name is wrong, and the color can be undefined. We haven't figured yet out what's the proper name for the event. Also, it seems it is not working cause we are not using jsx-native-events, and we don't want to use it cause it has been five years without any activity.

We can find the parameters from here.

As we don't want to use react-colorful cause it also is not maintained, it is heavier than vanilla and we were trying to solve this issue, although it was not 100% fixed, We tried another way: making the color picker a React component using @lit/react.

import { HexColorPicker } from "vanilla-colorful/hex-color-picker.js";

const ColorPicker = createComponent({
  react: React,
  tagName: "hex-color-picker",
  elementClass: HexColorPicker,
  events: {
    onEventColorChanged: "color-changed" as EventName<
      CustomEvent<{ value: string }>
    >,
  },
});

---

const ColorPickerPopover = forwardRef<JSX.Element, ColorPickerPopoverProps>(

            <ColorPicker
              color={color}
              onEventColorChanged={(event) => setColor(event.detail.value)}
            />
---

As you can see, we rightly gave the name we wanted to the custom event and now it works fine.

What do you think about updating the React example?