改变按钮的位置

Change the position of the buttons

我有一个项目,在这个项目中我有一个界面,除了两个按钮外,还包含几个字段,第一个是“创建”,第二个是“取消”,如图所示最后的两个按钮,但我希​​望这两个按钮位于红色书写的区域

我该怎么做?

而且界面的文件比较大,所以我只放两个按钮的写法

main.js:

        <div className="p-16 sm:p-24 max-w-2xl ">
            <div className={tabValue !== 0 ? "hidden" : ""}>
              <ShippingTab />
            </div>
          </div>

shipping.js:

import React, { useState } from "react";
import InputAdornment from "@material-ui/core/InputAdornment";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import "date-fns";
import DateFnsUtils from "@date-io/date-fns";
import {
  KeyboardDatePicker,
  MuiPickersUtilsProvider,
  DatePicker,
} from "@material-ui/pickers";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import CloudUploadIcon from "@material-ui/icons/CloudUpload";
import { addInvoice } from "../../../store/invoiceSlice";
import { motion } from "framer-motion";
import { useDispatch } from "react-redux";
import "react-datepicker/dist/react-datepicker.css";
import Slide from "@material-ui/core/Slide";
import { useSnackbar } from "notistack";

const useStyles = makeStyles((theme) => ({
  root: {
    "& > *": {
      margin: theme.spacing(1),
    },
  },
  input: {
    display: "none",
  },
  button: {
    margin: theme.spacing(1),
    // padding: theme.spacing(4),
  },
}));

function ShippingTab(props) {
  const dispatch = useDispatch();
  const classes = useStyles();
  const [issueDate, setIssueDate] = useState(new Date());
  const [dueDate, setDueDate] = useState(new Date());
  const [netAmount, setNetAmount] = useState("");
  const [taxNumber, setTaxNumber] = useState("");
  const [grossAmount, setGrossAmount] = useState("");
  const [file, setFile] = useState(null);

  const { enqueueSnackbar, closeSnackbar } = useSnackbar();

  const handleUploadPDFFileMessageClick = () => {
    enqueueSnackbar(
      "PDF file has been uploaded successfully",
      { variant: "success" },
      {
        anchorOrigin: {
          vertical: "top",
          horizontal: "right",
        },
      },
      { TransitionComponent: Slide }
    );
  };

  const handleCreateInvoiceMessageClick = () => {
    enqueueSnackbar(
      "Invoice created successfully",
      { variant: "success" },
      {
        anchorOrigin: {
          vertical: "top",
          horizontal: "right",
        },
      },
      { TransitionComponent: Slide }
    );
  };
  const fileSelectedHandler = (event) => {
    console.log(event.target.files[0]);
    const file = event.target.files[0];

    if (event.target && file) {
      // formData.append("invoice", file);
      setFile(file);
    }
  };
  const uploadHandler = (event) => {
    const formData = new FormData();
    formData.append("grossAmount", grossAmount);
    formData.append("taxNumber", taxNumber);
    formData.append("netAmount", netAmount);
    formData.append("issueDate", issueDate);
    formData.append("dueDate", dueDate);
    formData.append("invoice", file);

    console.log(
      " invoice grossAmount,taxNumber,netAmount,",
      file,
      grossAmount,
      taxNumber,
      netAmount
    );
    console.log("dueDate,issueDate: ", dueDate, issueDate);
    // call api
    dispatch(addInvoice(formData));
  };

  const handleissueDateChange = (date) => {
    setIssueDate(date);
    console.log("date issssssssss: ", date);
    console.log("date issssssssss: ", issueDate);
  };

  const handleDueDateChange = (date) => {
    setDueDate(date);
  };

  const handleNetAmountChange = (event) => {
    setNetAmount(event.target.value);
  };

  const handleTaxAmountChange = (event) => {
    setTaxNumber(event.target.value);
  };

  const handleGrossAmountChange = (event) => {
    setGrossAmount(event.target.value);
  };
  return (
    <>
      <MuiPickersUtilsProvider utils={DateFnsUtils}>
        <div className="flex -mx-4">
          <KeyboardDatePicker
            inputVariant="outlined"
            className="mt-8 mb-16"
            margin="normal"
            id="date-picker-dialog"
            label="issue Date"
            format="MM/dd/yyyy"
            KeyboardButtonProps={{
              "aria-label": "change date",
            }}
            value={issueDate}
            onChange={handleissueDateChange}
          />

          <KeyboardDatePicker
            inputVariant="outlined"
            className="mt-8 mb-16 ml-6"
            margin="normal"
            id="date-picker-dialog"
            label="Due Date"
            format="MM/dd/yyyy"
            KeyboardButtonProps={{
              "aria-label": "change date",
            }}
            value={dueDate}
            onChange={handleDueDateChange}
          />
        </div>
      </MuiPickersUtilsProvider>
      <TextField
        className="mt-8 mb-16"
        label="Net Amount"
        id="extraShippingFee"
        variant="outlined"
        InputProps={{
          startAdornment: <InputAdornment position="start">$</InputAdornment>,
        }}
        value={netAmount}
        onChange={handleNetAmountChange}
        fullWidth
      />

      <TextField
        className="mt-8 mb-16"
        label="Tax Number"
        id="extraShippingFee"
        variant="outlined"
        InputProps={{
          startAdornment: <InputAdornment position="start">$</InputAdornment>,
        }}
        value={taxNumber}
        onChange={handleTaxAmountChange}
        fullWidth
      />

      <TextField
        className="mt-8 mb-16"
        label="Gross Amount"
        id="extraShippingFee"
        variant="outlined"
        InputProps={{
          startAdornment: <InputAdornment position="start">$</InputAdornment>,
        }}
        value={grossAmount}
        onChange={handleGrossAmountChange}
        fullWidth
      />

      <div className={classes.root}>
        <input
          accept="application/pdf"
          className={classes.input}
          id="contained-button-file"
          // multiple
          type="file"
          onChange={fileSelectedHandler}
        />
        <label htmlFor="contained-button-file">
          <Button
            variant="contained"
            color="primary"
            size="large"
            component="span"
            className={classes.button}
            startIcon={<CloudUploadIcon />}
          >
            {/* <Button variant="contained" color="primary" component="span"> */}{" "}
            Upload
          </Button>

          {/* </Button> */}
        </label>
      </div>

      <motion.div
        initial={{ opacity: 0, x: 20 }}
        animate={{ opacity: 1, x: 0, transition: { delay: 0.3 } }}
      >
        <Grid
          container
          direction="row-reverse"
          justifyContent="flex-start"
          alignItems="flex-end"
        >
          <Grid item>
            <Button
              className="whitespace-nowrap mx-4"
              variant="contained"
              color="secondary"
              // onClick={handleRemoveProduct}
            >
              Cancel
            </Button>
          </Grid>
          <Grid item>
            <Button
              className="whitespace-nowrap mx-4"
              variant="contained"
              color="secondary"
              // disabled={_.isEmpty(dirtyFields) || !isValid}

              onClick={(ev) => {
                uploadHandler();
                ev.stopPropagation();
                handleCreateInvoiceMessageClick(ev);
              }}
            >
              Create
            </Button>
          </Grid>
        </Grid>
      </motion.div>
    </>
  );
}

export default ShippingTab;

父元素是弹性元素,因此尝试 margin-top: auto; 子元素(按钮或其容器)

您可以使用 flexheight: 100% 将两个按钮对齐到左下角。

  1. motion.div 向上的两个按钮的所有父级,包括 htmlbody 需要具有 100% 高度。

  2. 包含按钮的gridmotion.div需要有flex-grow:1,这样它们就占据了各自容器中所有空闲的space .

html,
body {
  height: 100%;
}

div.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

section.red {
  background: red;
  padding: 5rem 0
}

section.blue {
  background: blue;
  padding: 5rem 0
}

section.green {
  background: green;
  flex-grow: 1;
  display: flex;
}

section.green>div {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

section.left {
  flex-grow: 1;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}

button {
  padding: 1rem 2rem;
}
<div class="container">
  <section class="red"></section>
  <section class="blue"></section>
  <section class="green">
    <div>
      <section class="right">
        <button>Right</button>
      </section>

      <section class="left">
        <button>One</button>
        <button>TWO</button>
      </section>
    </div>
  </section>
</div>


如果 ShippingTab 有太多父级,很难在其所有父级上设置 100% 高度。在这种情况下,您绝对可以将其放置在 body 或其最近的 relative 具有/可以具有 100% 高度的容器中。