javascript - Anpassad kryssruta utlöser inte onChange


Jag har skrivit en anpassad kryssruta med TypeScript och styled-components, koden ser ut som följer

import React, { FC } from "react";
import styled from "styled-components";
import { Box, BoxProps } from "../Box";
import { Flex } from "../Flex";
import { Text } from "../Text";
import {
  BackgroundProps,
  BorderProps,
  ColorProps,
  FlexboxProps,
  GridProps,
  LayoutProps,
  PositionProps,
  ShadowProps,
  SpaceProps,
  TypographyProps,
  background,
  border,
  color,
  flexbox,
  grid,
  layout,
  position,
  shadow,
  space,
  typography,
} from "styled-system";

export interface CheckBoxProps
  extends BackgroundProps,
    BorderProps,
    ColorProps,
    FlexboxProps,
    GridProps,
    LayoutProps,
    PositionProps,
    ShadowProps,
    SpaceProps,
    TypographyProps,
    Omit<React.HTMLProps<HTMLInputElement>, "color" | "height" | "size" | "width" | "as" | "ref"> {
  [key: string]: any;
  className?: string;
  label?: string;
  letterSpacing?: string;
  indeterminate?: boolean;
}

const StyledCheckBox = styled.input<CheckBoxProps>`
  position: absolute;
  opacity: 0.5;
  cursor: pointer;
`;

const _Box = styled(Box)<BoxProps>`
  positionL absolute;
  top: 0;
  left: 0;
  height: inherit;
  width: inherit;
  cursor: pointer;
  border: ${({ theme }) => `2px solid ${theme.colors.neutral[70]}`};
  border-radius: 4px;
  display: inline-block;

  &:hover{
    border: ${({ theme }) => `2px solid ${theme.colors.blue[400]}`};
  }

  &::after{
    content: "";
    position: absolute;
    right: 0;
    left: 0;
    top: 0;
    bottom: 2px;
    margin: auto;
    width: 5px;
    height: 10px;
    border: solid ${({ theme }) => `${theme.colors.neutral[0]}`};
    border-width: 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(36deg);
  }
`;

const CheckboxContainer = styled(Box)<CheckBoxProps>`
  position: relative;

  & ${StyledCheckBox}:checked ~ ${_Box} {
    background-color: ${({ theme }) => `${theme.colors.blue[400]}`};
    border: ${({ theme }) => `2px solid ${theme.colors.blue[500]}`};
  }

  & ${StyledCheckBox}:checked ~ ${_Box}::after {
    display: block;
  }

  & ${StyledCheckBox}.intermediate:checked ~ ${_Box}::after {
    display: block;
    content: "";
    position: absolute;
    right: 0;
    left: 0;
    top: 0;
    bottom: 2px;
    margin: auto;
    border: solid ${({ theme }) => `${theme.colors.neutral[0]}`};
    border-width: 0px 2px 0px 0px;
    transform: rotate(90deg);
  }
  & ${StyledCheckBox}[disabled] ~ ${_Box}::after {
    border-color: ${({ theme }) => `${theme.colors.neutral[60]}`};
  }

  & ${StyledCheckBox}.intermediate[disabled] ~ ${_Box}::after {
    border-color: ${({ theme }) => `${theme.colors.neutral[60]}`};
  }
  & ${StyledCheckBox}[disabled] ~ ${_Box} {
    cursor: default;
    background-color: ${({ theme }) => `${theme.colors.neutral[30]}`};
    border: ${({ theme }) => `2px solid ${theme.colors.neutral[60]}`};
  }
  ${space}
  ${color}
  ${layout}
  ${background}
  ${position}
  ${grid}
  ${border}
  ${flexbox}
  ${shadow}
  ${typography}
`;

export const Checkbox: FC<CheckBoxProps> = ({ onChange, label, disabled, letterSpacing, ...props }) => (
  <Flex alignItems={"center"} gridGap={"8px"}>
    <CheckboxContainer width={18} height={18} marginTop={"2px"} {...props}>
      <StyledCheckBox
        disabled={disabled}
        {...props}
        type="checkbox"
        checked={props.checked}
        onChange={onChange}
        className={props.indeterminate ? "intermediate" : ""}
      />
      <_Box as="span"></_Box>
    </CheckboxContainer>
    {label && (
      <Text
        as="span"
        sizeVariant="h5"
        letterSpacing={letterSpacing}
        cursor={disabled ? "not-allowed" : "default"}
        colorVariant={disabled ? "disable" : "default"}
      >
        {label}
      </Text>
    )}
  </Flex>
);

Och vi använder storybook för att visualisera komponenten, koden ser ut som följer

import { Checkbox } from "./Checkbox";
import React from "react";
import type { StoryObj } from "@storybook/react";

export default {
  title: "Checkbox",
  component: Checkbox,
  argTypes: {
    checked: {
      name: "checked",
      type: { name: "checked", required: true },
      defaultValue: false,
      description: "Set state for check box",
      control: "boolean",
    },
    indeterminate: {
      name: "indeterminate",
      type: { name: "indeterminate", required: false },
      defaultValue: false,
      description: "Set indeterminate state for check box",
      control: "boolean",
    },
    disabled: {
      name: "disabled",
      type: { name: "disabled", required: false },
      defaultValue: false,
      description: "Set disabled state for check box",
      control: "boolean",
    },
    onChange: {
      name: "onChange",
      type: { name: "onChange", required: true },
      defaultValue: "() => {}",
      description: "Set onChange for check box",
      action: "clicked",
    },
    id: {
      name: "id",
      type: { name: "id", required: true },
      defaultValue: "",
      description: "Set id for check box",
      control: "text",
    },
    name: {
      name: "name",
      type: { name: "name", required: false },
      defaultValue: "",
      description: "Set name for check box",
      control: "text",
    },
    className: {
      name: "className",
      type: { name: "className", required: true },
      defaultValue: "",
      description: "Set className for check box",
      control: "text",
    },
  },
};

type Story = StoryObj<typeof Checkbox>;

const CheckBoxTemplate: Story = {
  render: (args) => {
    return (
      <Checkbox
        {...args}
        onChange={function (): void {
          console.log("not implemented");
        }}
      />
    );
  },
};

export const Default = {
  ...CheckBoxTemplate,
  args: {
    checked: true,
    disabled: false,
    className: "",
    label: "",
    onChange: {
      action: "clicked",
    },
  },
};

export const Intermediate = {
  ...CheckBoxTemplate,
  args: {
    checked: true,
    disabled: false,
    label: "Checkbox",
    indeterminate: true,
  },
};

När man klickar på kryssrutan i storybook skrivs inte konsolloggen ('not implemented') ut eftersom onChange-funktionen inte triggas. Kan någon vänligen hjälpa mig här. Tack på förhand.