Home > front end >  Style dynamically generated buttons
Style dynamically generated buttons

Time:04-03

I am trying to style buttons that are being dynamically generated. I have created a component that generates the buttons dynamically.

const TIMER_PRESETS: Record<string, number> = {
  FIFTHTEENSEC: 15,
  THIRTYSEC: 30,
  FORTYFIVESEC: 45,
  TWOMIN: 120,
  THREEMIN: 180,
  FOURMIN: 240,
};

const TimerPresetsWrapper = styled("div")`
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;

  .button {
    background: white;
    width: 56px;
    height: 42px;
    border: 2px solid #bbbbb;
    color: #fffff;
    box-sizing: border-box;
    border-radius: 12px;

    :&hover  {
      background: ${HOVER_COLORS.LIGHT_GRAY};
    }
  }
`;

export default function TimerPresets(props: {
  onClick: (e: number) => void;
  style?: Record<string, string>;
}): React.ReactElement {
  return (
    <TimerPresetsWrapper>
      {Object.values(TIMER_PRESETS).map((preset: number, index: number) => {
        return (
          <div>
            <Button onClick={() => props.onClick(preset)} className="button">
              <Typography>{getDisplayableTime(preset)}</Typography>
            </Button>
          </div>
        );
      })}
    </TimerPresetsWrapper>
  );
}

This generates the different presets that I am looking for. The issue is when I call this into by model this is how it appears

enter image description here

I have tried putting this into a stack within my main component but to no luck here is the main component code.

  function renderTargetTimeWindow() {
    return (
      <Modal
        open={showTargetTimeWindow}
        onClose={hideTargetTimeWindow}
        aria-labelledby="simple-modal-title"
        aria-describedby="simple-modal-description"
      >
        <div className={recorderClasses.targetTimeWindow}>
          <CloseIcon
            onClick={hideTargetTimeWindow}
            className={recorderClasses.windowCloseButton}
          />

          <Typography className={recorderClasses.targetTimeWindowTitle}>
            Specify the your recording Time
          </Typography>
          
          <Typography className={recorderClasses.targetTimeSelectionUnit}>
            minutes
          </Typography> */}
          <Stack
            spacing={4}
            direction="column"
            alignItems="center"
            height="100%"
          >
            <div className="justify-content-center">
              <TimerPresets
                style={{ right: "16px", top: "164px" }}
                onClick={handlePrestButtonClicked}
              />
            </div>
          </Stack>

          {/* TODO: Add a seconds option */}
          <Button
            className={recorderClasses.targetTimeCancelButton}
            onClick={handleTargetTimeCancelButtonClicked}
          >
            <Typography
              className={recorderClasses.targetTimeCancelButtonTypography}
            >
              Cancel
            </Typography>
          </Button>
          <Button
            className={recorderClasses.targetTimeDoneButton}
            onClick={handleTargetTimeDoneButtonClicked}
          >
            <Typography
              className={recorderClasses.targetTimeDoneButtonTypography}
            >
              Done
            </Typography>
          </Button>
        </div>
      </Modal>

What I am trying to do is to style it like this enter image description here

CodePudding user response:

Try to use grid display instead of flex

Refactored Code:

const TimerPresetsWrapper = styled("div")`
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  column-gap: 50px;

  .button {
    background: white;
    width: 56px;
    height: 42px;
    border: 2px solid #bbbbb;
    color: #fffff;
    box-sizing: border-box;
    border-radius: 12px;

    :&hover  {
      background: ${HOVER_COLORS.LIGHT_GRAY};
    }
  }
`;

you could also remove stack and just retain the div (add flex property to div to center content)

<div className="flex justify-content-center">
  <TimerPresets
    style={{ right: "16px", top: "164px" }}
    onClick={handlePrestButtonClicked}
  />
</div>

Lastly, add/adjust paddings in your component to achieve the style you've mentioned. Hope that helped brother.

  • Related