18F/e-QIP-prototype

View on GitHub
src/views/Form/Form.scss

Summary

Maintainability
Test Coverage
label,
input,
textarea,
select {
  width: 100%;
  max-width: 64rem;
  margin-top: 0;
  color: $eapp-grey-dark;
}

input,
textarea,
select {
  border-radius: 3px;
}

textarea {
  resize: vertical;
}

button {
  &.link {
    background: #fff;
    color: $eapp-blue;
    text-decoration: underline;
    text-decoration-color: $eapp-blue;
    padding: 0;
    margin: 0;
  }
}

label {
  margin-bottom: .5rem;
}

/* bring in USWD validation classes and alter for our design */
input[type='text'],
textarea,
select {
  padding-right: 3rem;
  transition: border-color 0.4s, border-width 0.4s, background-position 0.4s;
}

input[type='checkbox'],
input[type='radio'] {
  position: absolute;
  margin-left: 0;
  width: 0;

  + label {
    position: relative;
    top: auto;
    left: auto;

    // This was hiding the time of day for telephone numbers.
    // z-index: -1;
  }
}

/* placeholder should be a light gray and italics */
::-webkit-input-placeholder {
  font-style: italic;
  color: $eapp-grey-placeholder;
}

::-ms-input-placeholder {
  font-style: italic;
  color: $eapp-grey-placeholder;
}

::-moz-placeholder {
  font-style: italic;
  color: $eapp-grey-placeholder;
  opacity: 1;
}

:-moz-placeholder {
  font-style: italic;
  color: $eapp-grey-placeholder;
  opacity: 1;
}

:focus {
  &::-webkit-input-placeholder {
    color: transparent;
  }
  &::-ms-input-placeholder {
    color: transparent;
  }
  &::-moz-placeholder {
    color: transparent;
  }
  &:-moz-placeholder {
    color: transparent;
  }
}

.usa-input-error {
  border: none;
  padding: 0;
  margin-top: 0;
  right: auto;

  /* prevent USWD standards from bolding labels on inputs with errors */
  label {
    font-weight: $eapp-book;
  }

  .usa-input-error-message {
    display: none;
  }

  input[type='text'],
  input[type='number'],
  input[type='email'],
  textarea,
  select {
    background: url('#{$asset-path}img/exclamation-point.svg') no-repeat right 0.7rem
      center / 1.7rem 100%;
    box-shadow: none;
    border-width: 2px;
    width: 100%;

    &.usa-input-success {
      box-shadow: none;
      background: url('#{$asset-path}img/exclamation-point.svg') no-repeat right 0.7rem
        center / 1.7rem 100%;
      border-width: 2px;
    }
  }

  .block > label {
    border: 2px solid $color-red-dark;
  }
}

input[type='text'],
input[type='number'],
input[type='email'],
textarea,
select {
  background-position: 100% center;

  &:focus {
    // box-shadow: 3px 1px 16px 22px 12px black;
  }

  &.usa-input-success {
    box-shadow: none;
    background: url('#{$asset-path}img/checkmark.svg') no-repeat right 0.7rem center /
      1.7rem 100%;
    border-width: 2px;
  }
}

select {
  background-position: right 1.3rem center;
  -webkit-appearance: none;
}

// Input sizing
.usa-small-input {
  width: 10rem;
}

.usa-medium-input {
  width: 30rem;
}

@media all and (max-width: 980px) {
  .usa-medium-input,
  .usa-small-input {
    width: 100%;
  }
}

// Block style radio and checkboxes

.blocks.option-list {
  display: flex;

  @media all and (max-width: 980px) {
    flex-flow: wrap;
  }

  &.option-list-vertical {
    flex-flow: wrap;
  }

  .block {
    width: 100%;
  }
}

.block {
  display: inline-block;
  margin-right: 1rem;

  @media all and (max-width: 980px) {
    margin-right: 0;
  }

  label {
    padding: 1rem;
    border: 1px solid $color-primary-alt-light;
    border-radius: 4px;
    max-width: 46rem;
    background-color: $color-white;

    input {
      position: absolute;
    }

    &.usa-input-focus {
      outline: 2px dotted $color-gray-light;
      outline-offset: 3px;
    }

    &:hover {
      background-color: $color-gray-extra-lightest;
    }

    &.checked {
      background: $color-green-light;
      border-color: $color-green;
      color: $color-white;
    }

    &.checked.usa-input-focus,
    &.checked:focus,
    input [type='checkbox'].usa-input-focus,
    input [type='checkbox']:focus {
      outline: 2px dotted $color-gray-light;
      outline-offset: 3px;
    }

    // Configure buttons for handling text in decorative blocks
    > span {
      display: block;
      margin-left: 3rem;

      > div {

        > p {
          padding: 0;
          margin: 0;
        }
      }

      // If this is the first div AND not the last then it
      // has subtext associated to it and needs to be bumped
      // upwards.
      > div:not(:last-of-type) {
        top: 25%;
      }

      // All the div's (except the first) are treated as
      // subtext.
      > div:not(:first-of-type) {
        font-size: small;
        margin-top: -3rem;
      }
    }

    // Block style radio and checkboxes that are NOT toggles
    &.no-toggle {
      display: block;
      margin-bottom: 0;
      margin-right: 1.6rem;
      text-align: center;
      background: transparent;
      border: none;
      z-index: unset;

      > span {
        display: inline;
        margin-left: 0;
      }
    }

    &.no-toggle.checked,
    &.no-toggle:hover {
      color: inherit;
      border: none;
      background: transparent;
    }
  }

  svg path {
    fill: $eapp-grey-darker;
  }

  // Extended blocks are those with content within them such as images or long text.
  &.extended {
    min-width: 12rem;
    line-height: 1;

    i {
      display: none;
    }

    label {
      position: relative !important;
      margin-bottom: 3.3rem;
      height: 7.6rem;
      min-width: 12rem;
      cursor: pointer;
      overflow: visible;

      span {
        display: block;
        position: absolute;
        top: 8rem;
        left: 0;
        width: 100%;
        height: auto;
        line-height: 1.1;
        font-size: 1.7rem;
        color: $eapp-grey-dark;
      }

      .hair-icon,
      .eye-icon,
      .sex-icon,
      .relationship-icon,
      .military-service-icon,
      .attachment-icon {
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        transition: all 0.3s;
        border-radius: 0;

        svg,
        img {
          position: absolute;
          top: 1.4rem;
          left: 50%;
          height: 4.6rem;
          width: 4.6rem;
          margin-left: -2.3rem;
          transition: all 0.3s;
        }
      }

      &:hover .hair-icon,
      &.checked .hair-icon,
      &:hover .eye-icon,
      &.checked .eye-icon,
      &:hover .sex-icon,
      &.checked .sex-icon,
      &:hover .relationship-icon,
      &.checked .relationship-icon,
      &:hover .military-service-icon,
      &.checked .military-service-icon,
      &:hover .attachment-icon,
      &.checked .attachment-icon {
        border-radius: 50%;
        top: 1.4rem;
        left: 50%;
        width: 4.6rem;
        height: 4.6rem;
        background-color: $eapp-grey-light;
        margin-left: -2.3rem;

        svg,
        img {
          top: 0.8rem;
          height: 3rem;
          width: 3rem;
          margin-left: -1.5rem;
        }
      }
    }
  }

  &.disabled {
    label {
      cursor: inherit;
      background: $eapp-grey-light;

      &.usa-input-focus,
      &.checked,
      &:hover {
        color: $eapp-grey-dark;
        background: $eapp-grey-light;
      }
    }
  }
}

.usa-list-inline-justified .block {
  width: 100%;
}

.optional {
  color: $eapp-grey-darker;
  font-style: italic;
  font-family: $eapp-sans;
  font-weight: normal;
  font-size: 1.7rem;
  line-height: 1.6rem;
  padding-left: 0.5rem;
}

.required {
  // This allows the component to handle its own placement of requirement tokens.
  // A use case for this is `<Telephone />`. The field title does not have an required token,
  // but two labels within the component potentially do.
  &.override-required {
    .title:after,
    > label:after {
      content: none;
    }
  }
}