Fluent UI Input components overlap footer component border

38 Views Asked by At

I have a form component that uses Fluent UI v9 for styling. For some reason my form inputs (located in the drawer body) overlap the footer border (located in the drawer footer) when scrolling but I am not sure why. I also observed the switch control components do not have this effect on the footer border.

Form body Fluent ui Input controls overlapping form footer border Form body Fluent ui Switch controls do not overlap form footer border

//FORM BODY
const useStyles = makeStyles({
  root: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'flex-start',
    ...shorthands.gap('12px'),
    marginTop: '20px',
    marginBottom: '40px',
    paddingBottom: '24px',
    paddingLeft: '20px',
    ...shorthands.overflow('auto'),
    borderLeftWidth: '1.5px',
    borderLeftStyle: 'solid',
    borderLeftColor: '#954ac7',
    borderBottomStyle: 'none',
    borderBottomWidth: 'none',
    borderBottomColor: 'none',  
  },
  filterContainer: {
    ...commonStyles.filterContainer,
    width: '500px',
  },
  label: commonStyles.label,
});

type Props = {
  formMode: FormMode;
};

function NewEventForm({ formMode }: Props) {
  const [selectedEvent] = useAtom(selectedEventAtom);
  console.log(selectedEvent);
  const classNames = useStyles();
  const [isExternal, setIsExternal] = useState(false);
  const [isAllDay, setIsAllDay] = useState(false);
  const [isRecurring, setIsRecurring] = useState(false);
  const [isCle, setIsCle] = useState(false);
   
  const eventStartTime = selectedEvent?.start ? new Date(selectedEvent.start) : undefined;
  const formattedTime = eventStartTime ? eventStartTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }) : undefined;
  
  return (
    <DrawerBody>
      <div className={classNames.root}>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Event name</Label>
          <Input
            placeholder='Event Name'
            value={selectedEvent?.title || ''}
            {...(formMode === 'preview' ? {
              disabled: true,
              defaultValue: selectedEvent?.title
          } : formMode === 'edit' ? {defaultValue: selectedEvent?.title} : '')}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Internal/External</Label>
          <Switch
            label={isExternal ? 'External' : 'Internal'}
            onChange={() => setIsExternal(!isExternal)}
            value={selectedEvent?.externalOrInternal || ''}
            {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.externalOrInternal })}
          />
        </div>
        {isExternal ? (
          <div className={classNames.filterContainer}>
            <Label className={classNames.label}>Location (External)</Label>
            <Input
              required placeholder="Enter location"
              value={selectedEvent?.location || ''}
              {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.location })}
            />
          </div>
        ) : (
          <div className={classNames.filterContainer}>
            <Label className={classNames.label}>Location (Internal)</Label>
            <Dropdown
              placeholder="Select location"
              value={selectedEvent?.location || ''}
              {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.location })}
            >
              {INTERNAL_LOCATIONS.map((location) => (
                <Option key={location} value={location}>
                  {location}
                </Option>
              ))}
            </Dropdown>
          </div>
        )}
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Event date</Label>
          <DatePicker
            placeholder="Select date" required
            value={selectedEvent?.start || null}
            {...(formMode === 'preview' && { 
              disabled: true, 
              defaultValue: selectedEvent?.start
            })}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Event time</Label>
          <TimePicker
            placeholder="Select time" required hourCycle="h12"
            value={formattedTime || ''}
            {...(formMode === 'preview' && { 
              disabled: true, 
              defaultValue: formattedTime
            })}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Time Zone</Label>
          <Dropdown
            placeholder="Select time zone"
            value={selectedEvent?.eventTimeZone || ''}
            {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.eventTimeZone })}
          >
            {TIME_ZONES.map((tz) => (
              <Option key={tz} value={tz}>
                {tz}
              </Option>
            ))}
          </Dropdown>
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Description</Label>
          <Textarea
            placeholder="Edit description"
            value={selectedEvent?.description || ''}
            {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.description })}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>CLE</Label>
          <Switch
            label={isCle ? 'Yes' : 'No'}
            onChange={() => setIsCle(!isCle)}
            {...(formMode === 'preview' && {
              disabled: true,
              label: selectedEvent?.cle ? 'Yes' : 'No',
              defaultChecked: selectedEvent?.cle
            })}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>All day</Label>
          <Switch
            label={isAllDay ? 'Yes' : 'No'}
            onChange={() => setIsAllDay(!isAllDay)}
            {...(formMode === 'preview' && {
              disabled: true,
              label: selectedEvent?.allDay ? 'Yes' : 'No',
              defaultChecked: selectedEvent?.allDay
            })}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Recurring</Label>
          <Switch
            label={isRecurring ? 'Yes' : 'No'}
            onChange={() => setIsRecurring(!isRecurring)}
          />
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Category</Label>
          <Combobox
            placeholder="Choose category" 
            required 
            freeform
            value={selectedEvent?.category || ''}
            {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.category })}
          >
            {CATEGORIES.map((category) => (
              <Option key={category} value={category}>
                {category}
              </Option>
            ))}
          </Combobox>
        </div>
        <div className={classNames.filterContainer}>
          <Label className={classNames.label}>Event Type</Label>
          <Combobox
            placeholder="Choose event type" 
            required 
            freeform
            value={selectedEvent?.eventType || ''}
            {...(formMode === 'preview' && { disabled: true, defaultValue: selectedEvent?.eventType })}
          >
            {EVENT_TYPES.map((eventType) => (
              <Option key={eventType} value={eventType}>
                {eventType}
              </Option>
            ))}
          </Combobox>
        </div>
      </div>
    </DrawerBody>
  );
}


// FORM FOOTER
const useStyles = makeStyles({
    button: {
        marginTop: '24px',
        backgroundColor: '#5c3380',
        ...shorthands.border('2px', 'solid', '#5c3380'),
        ":hover": { 
            backgroundColor: '#954ac7',
            ...shorthands.border('2px', 'solid', '#954ac7'),
        }
    },
    buttonSecondary: {
        marginTop: '24px',
        backgroundColor: '#ffffff',
        color: '#000000',
        fontWeight: 'bold',
        ...shorthands.border('2px', 'solid', '#000000'),
        ":hover": { color: '#7b7b7e' },
    },
    footer:{
        borderTopWidth: '1px',
        borderTopStyle: 'solid',
        borderTopColor: '#000000',
        marginTop: '20px',
    }
});

function Footer({ handleClose }: Props) {
    const classNames = useStyles();
    const [formMode, setFormMode] = useAtom(formModeAtom);
    const [, setSelectedEvent] = useAtom(selectedEventAtom);

    return (
        <DrawerFooter className={classNames.footer}>
            <Button
                className={classNames.button}
                appearance="primary"
                onClick={() => { 
                    const newFormMode = formMode === 'preview' ? 'edit' : 'new';
                    newFormMode === 'edit' && console.log('Edit') || newFormMode === 'new' && console.log('Submit'); 
                    formMode === 'edit' && setSelectedEvent(null);       
                    setFormMode(newFormMode);   
                    newFormMode === 'new' && handleClose();         
                }}
            >
                {formMode === 'preview' ? 'Edit' : 'Submit'}
            </Button>
            <Button
                className={classNames.buttonSecondary}
                appearance="secondary"
                onClick={() => { handleClose() }}
            >
                Cancel
            </Button>
        </DrawerFooter>
    );
}

export default Footer;
0

There are 0 best solutions below