diff options
Diffstat (limited to 'app/assets/stylesheets/components')
| -rw-r--r-- | app/assets/stylesheets/components/_accordion.scss | 116 | ||||
| -rw-r--r-- | app/assets/stylesheets/components/_card.scss | 36 | ||||
| -rw-r--r-- | app/assets/stylesheets/components/_dropdown.scss | 214 | ||||
| -rw-r--r-- | app/assets/stylesheets/components/_modal.scss | 168 | ||||
| -rw-r--r-- | app/assets/stylesheets/components/_nav.scss | 141 | ||||
| -rw-r--r-- | app/assets/stylesheets/components/_progress.scss | 89 | 
6 files changed, 764 insertions, 0 deletions
| diff --git a/app/assets/stylesheets/components/_accordion.scss b/app/assets/stylesheets/components/_accordion.scss new file mode 100644 index 0000000..59b2c65 --- /dev/null +++ b/app/assets/stylesheets/components/_accordion.scss @@ -0,0 +1,116 @@ +/** + * Accordion (<details>) + */ + +details { +  display: block; +  margin-bottom: var(--spacing); +  padding-bottom: var(--spacing); +  border-bottom: var(--border-width) solid var(--accordion-border-color); + +  summary { +    line-height: 1rem; +    list-style-type: none; +    cursor: pointer; + +    &:not([role]) { +      color: var(--accordion-close-summary-color); +    } + +    @if $enable-transitions { +      transition: color var(--transition); +    } + +    // Reset marker +    &::-webkit-details-marker { +      display: none; +    } + +    &::marker { +      display: none; +    } + +    &::-moz-list-bullet { +      list-style-type: none; +    } + +    // Marker +    &::after { +      display: block; +      width: 1rem; +      height: 1rem; +      margin-inline-start: calc(var(--spacing, 1rem) * 0.5); +      float: right; +      transform: rotate(-90deg); +      background-image: var(--icon-chevron); +      background-position: right center; +      background-size: 1rem auto; +      background-repeat: no-repeat; +      content: ""; + +      @if $enable-transitions { +        transition: transform var(--transition); +      } +    } + +    &:focus { +      outline: none; + +      &:not([role="button"]) { +        color: var(--accordion-active-summary-color); +      } +    } + +    // Type button +    &[role="button"] { +      width: 100%; +      text-align: left; + +      // Marker +      &::after { +        height: calc(1rem * var(--line-height, 1.5)); +        background-image: var(--icon-chevron-button); +      } + +      @if $enable-classes { +        // .contrast +        &:not(.outline).contrast { +          // Marker +          &::after { +            background-image: var(--icon-chevron-button-inverse); +          } +        } +      } +    } +  } + +  // Open +  &[open] { +    > summary { +      margin-bottom: calc(var(--spacing)); + +      &:not([role]) { +        &:not(:focus) { +          color: var(--accordion-open-summary-color); +        } +      } + +      &::after { +        transform: rotate(0); +      } +    } +  } +} + +[dir="rtl"] { +  details { +    summary { +      text-align: right; + +      &::after { +        float: left; +        background-position: left center; +      } +    } +  } +} diff --git a/app/assets/stylesheets/components/_card.scss b/app/assets/stylesheets/components/_card.scss new file mode 100644 index 0000000..924415e --- /dev/null +++ b/app/assets/stylesheets/components/_card.scss @@ -0,0 +1,36 @@ +/** + * Card (<article>) + */ + +article { +  margin: var(--block-spacing-vertical) 0; +  padding: var(--block-spacing-vertical) var(--block-spacing-horizontal); +  border-radius: var(--border-radius); +  background: var(--card-background-color); +  box-shadow: var(--card-box-shadow); + +  > header, +  > footer { +    margin-right: calc(var(--block-spacing-horizontal) * -1); +    margin-left: calc(var(--block-spacing-horizontal) * -1); +    padding: calc(var(--block-spacing-vertical) * 0.66) +      var(--block-spacing-horizontal); +    background-color: var(--card-sectionning-background-color); +  } + +  > header { +    margin-top: calc(var(--block-spacing-vertical) * -1); +    margin-bottom: var(--block-spacing-vertical); +    border-bottom: var(--border-width) solid var(--card-border-color); +    border-top-right-radius: var(--border-radius); +    border-top-left-radius: var(--border-radius); +  } + +  > footer { +    margin-top: var(--block-spacing-vertical); +    margin-bottom: calc(var(--block-spacing-vertical) * -1); +    border-top: var(--border-width) solid var(--card-border-color); +    border-bottom-right-radius: var(--border-radius); +    border-bottom-left-radius: var(--border-radius); +  } +} diff --git a/app/assets/stylesheets/components/_dropdown.scss b/app/assets/stylesheets/components/_dropdown.scss new file mode 100644 index 0000000..a16e6d2 --- /dev/null +++ b/app/assets/stylesheets/components/_dropdown.scss @@ -0,0 +1,214 @@ +/** + * Dropdown ([role="list"]) + */ + +// Menu +details[role="list"], +li[role="list"] { +  position: relative; +} + +details[role="list"] summary + ul, +li[role="list"] > ul { +  display: flex; +  z-index: 99; +  position: absolute; +  top: auto; +  right: 0; +  left: 0; +  flex-direction: column; +  margin: 0; +  padding: 0; +  border: var(--border-width) solid var(--dropdown-border-color); +  border-radius: var(--border-radius); +  border-top-right-radius: 0; +  border-top-left-radius: 0; +  background-color: var(--dropdown-background-color); +  box-shadow: var(--card-box-shadow); +  color: var(--dropdown-color); +  white-space: nowrap; + +  li { +    width: 100%; +    margin-bottom: 0; +    padding: calc(var(--form-element-spacing-vertical) * 0.5) +      var(--form-element-spacing-horizontal); +    list-style: none; + +    &:first-of-type { +      margin-top: calc(var(--form-element-spacing-vertical) * 0.5); +    } + +    &:last-of-type { +      margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5); +    } + +    a { +      display: block; +      margin: calc(var(--form-element-spacing-vertical) * -0.5) +        calc(var(--form-element-spacing-horizontal) * -1); +      padding: calc(var(--form-element-spacing-vertical) * 0.5) +        var(--form-element-spacing-horizontal); +      overflow: hidden; +      color: var(--dropdown-color); +      text-decoration: none; +      text-overflow: ellipsis; + +      &:hover { +        background-color: var(--dropdown-hover-background-color); +      } +    } +  } +} + +// Marker +details[role="list"] summary, +li[role="list"] > a { +  &::after { +    display: block; +    width: 1rem; +    height: calc(1rem * var(--line-height, 1.5)); +    margin-inline-start: 0.5rem; +    float: right; +    transform: rotate(0deg); +    background-image: var(--icon-chevron); +    background-position: right center; +    background-size: 1rem auto; +    background-repeat: no-repeat; +    content: ""; +  } +} + +// Global dropdown only +details[role="list"] { +  padding: 0; +  border-bottom: none; + +  // Style <summary> as <select> +  summary { +    margin-bottom: 0; + +    &:not([role]) { +      height: calc( +        1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + +          var(--border-width) * 2 +      ); +      padding: var(--form-element-spacing-vertical) +        var(--form-element-spacing-horizontal); +      border: var(--border-width) solid var(--form-element-border-color); +      border-radius: var(--border-radius); +      background-color: var(--form-element-background-color); +      color: var(--form-element-placeholder-color); +      line-height: inherit; +      cursor: pointer; + +      @if $enable-transitions { +        transition: background-color var(--transition), +          border-color var(--transition), color var(--transition), +          box-shadow var(--transition); +      } + +      &:active, +      &:focus { +        border-color: var(--form-element-active-border-color); +        background-color: var(--form-element-active-background-color); +      } + +      &:focus { +        box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color); +      } +    } +  } + +  // Close for details[role="list"] +  &[open] summary { +    border-bottom-right-radius: 0; +    border-bottom-left-radius: 0; + +    &::before { +      display: block; +      z-index: 1; +      position: fixed; +      top: 0; +      right: 0; +      bottom: 0; +      left: 0; +      background: none; +      content: ""; +      cursor: default; +    } +  } +} + +// All Dropdowns inside <nav> +nav details[role="list"] summary, +nav li[role="list"] a { +  display: flex; +  direction: ltr; +} + +nav details[role="list"] summary + ul, +nav li[role="list"] > ul { +  min-width: fit-content; +  border-radius: var(--border-radius); + +  li a { +    border-radius: 0; +  } +} + +// Dropdowns inside <nav> as nested <details> +nav details[role="list"] { +  summary, +  summary:not([role]) { +    height: auto; +    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal); +  } + +  &[open] summary { +    border-radius: var(--border-radius); +  } + +  summary + ul { +    margin-top: var(--outline-width); +    margin-inline-start: 0; +  } + +  summary[role="link"] { +    margin-bottom: calc(var(--nav-link-spacing-vertical) * -1); +    line-height: var(--line-height); + +    + ul { +      margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width)); +      margin-inline-start: calc(var(--nav-link-spacing-horizontal) * -1); +    } +  } +} + +// Dropdowns inside a <nav> without using <details> +li[role="list"] { +  // Open on hover (for mobile) +  // or on active/focus (for keyboard navigation) +  &:hover > ul, +  a:active ~ ul, +  a:focus ~ ul { +    display: flex; +  } + +  > ul { +    display: none; +    margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width)); +    margin-inline-start: calc( +      var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal) +    ); +  } + +  > a::after { +    background-image: var(--icon-chevron); +  } +} + +label > details[role="list"] { +  margin-top: calc(var(--spacing) * .25); +  margin-bottom: var(--spacing); +} diff --git a/app/assets/stylesheets/components/_modal.scss b/app/assets/stylesheets/components/_modal.scss new file mode 100644 index 0000000..af5cb16 --- /dev/null +++ b/app/assets/stylesheets/components/_modal.scss @@ -0,0 +1,168 @@ +/** + * Modal (<dialog>) + */ + +:root { +  --scrollbar-width: 0px; +} + +dialog { +  display: flex; +  z-index: 999; +  position: fixed; +  top: 0; +  right: 0; +  bottom: 0; +  left: 0; +  align-items: center; +  justify-content: center; +  width: inherit; +  min-width: 100%; +  height: inherit; +  min-height: 100%; +  padding: var(--spacing); +  border: 0; +  backdrop-filter: var(--modal-overlay-backdrop-filter); +  background-color: var(--modal-overlay-background-color); +  color: var(--color); + +  // Content +  article { +    $close-selector: if($enable-classes, ".close", "a[rel='prev']"); +    max-height: calc(100vh - var(--spacing) * 2); +    overflow: auto; + +    @if map-get($breakpoints, "sm") { +      @media (min-width: map-get($breakpoints, "sm")) { +        max-width: map-get($viewports, "sm"); +      } +    } + +    @if map-get($breakpoints, "md") { +      @media (min-width: map-get($breakpoints, "md")) { +        max-width: map-get($viewports, "md"); +      } +    } + +    > header, +    > footer { +      padding: calc(var(--block-spacing-vertical) * 0.5) +        var(--block-spacing-horizontal); +    } + +    > header { +      #{$close-selector} { +        margin: 0; +        margin-left: var(--spacing); +        float: right; +      } +    } + +    > footer { +      text-align: right; + +      [role="button"] { +        margin-bottom: 0; + +        &:not(:first-of-type) { +          margin-left: calc(var(--spacing) * 0.5); +        } +      } +    } + +    p { +      &:last-of-type { +        margin: 0; +      } +    } + +    // Close icon +    #{$close-selector} { +      display: block; +      width: 1rem; +      height: 1rem; +      margin-top: calc(var(--block-spacing-vertical) * -0.5); +      margin-bottom: var(--typography-spacing-vertical); +      margin-left: auto; +      background-image: var(--icon-close); +      background-position: center; +      background-size: auto 1rem; +      background-repeat: no-repeat; +      opacity: 0.5; + +      @if $enable-transitions { +        transition: opacity var(--transition); +      } + +      &:is([aria-current], :hover, :active, :focus) { +        opacity: 1; +      } +    } +  } + +  // Closed state +  &:not([open]), +  &[open="false"] { +    display: none; +  } +} + +// Utilities +@if $enable-classes { +  .modal-is-open { +    padding-right: var(--scrollbar-width, 0px); +    overflow: hidden; +    pointer-events: none; +    touch-action: none; + +    dialog { +      pointer-events: auto; +    } +  } +} + +// Animations +@if ($enable-classes and $enable-transitions) { +  $animation-duration: 0.2s; + +  :where(.modal-is-opening, .modal-is-closing) { +    dialog, +    dialog > article { +      animation-duration: $animation-duration; +      animation-timing-function: ease-in-out; +      animation-fill-mode: both; +    } + +    dialog { +      animation-duration: ($animation-duration * 4); +      animation-name: modal-overlay ; + +      > article { +        animation-delay: $animation-duration; +        animation-name: modal; +      } +    } +  } + +  .modal-is-closing { +    dialog, +    dialog > article { +      animation-delay: 0s; +      animation-direction: reverse; +    } +  } + +  @keyframes modal-overlay { +    from { +      backdrop-filter: none; +      background-color: transparent; +    } +  } + +  @keyframes modal { +    from { +      transform: translateY(-100%); +      opacity: 0; +    } +  } +} diff --git a/app/assets/stylesheets/components/_nav.scss b/app/assets/stylesheets/components/_nav.scss new file mode 100644 index 0000000..06fdd22 --- /dev/null +++ b/app/assets/stylesheets/components/_nav.scss @@ -0,0 +1,141 @@ +/** + * Nav + */ + +// Reboot based on : +// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css + +// Prevent VoiceOver from ignoring list semantics in Safari (opinionated) +:where(nav li)::before { +  float: left; +  content: "\200B"; +} + +// Pico +// –––––––––––––––––––– + +// Horizontal Nav +nav, +nav ul { +  display: flex; +} + +nav { +  justify-content: space-between; + +  ol, +  ul { +    align-items: center; +    margin-bottom: 0; +    padding: 0; +    list-style: none; + +    &:first-of-type { +      margin-left: calc(var(--nav-element-spacing-horizontal) * -1); +    } +    &:last-of-type { +      margin-right: calc(var(--nav-element-spacing-horizontal) * -1); +    } +  } + +  li { +    display: inline-block; +    margin: 0; +    padding: var(--nav-element-spacing-vertical) +      var(--nav-element-spacing-horizontal); + +    // Minimal support for buttons and forms elements +    > * { +      --spacing: 0; +    } +  } + +  :where(a, [role="link"]) { +    display: inline-block; +    margin: calc(var(--nav-link-spacing-vertical) * -1) +      calc(var(--nav-link-spacing-horizontal) * -1); +    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal); +    border-radius: var(--border-radius); +    text-decoration: none; + +    &:is([aria-current], :hover, :active, :focus) { +      text-decoration: none; +    } +  } + +  // Breadcrumb +  &[aria-label="breadcrumb"] { +    align-items: center; +    justify-content: start; + +    & ul li { +      &:not(:first-child) { +        margin-inline-start: var(--nav-link-spacing-horizontal); +      } + +      &:not(:last-child) { +        ::after { +          position: absolute; +          width: calc(var(--nav-link-spacing-horizontal) * 2); +          margin-inline-start: calc(var(--nav-link-spacing-horizontal) / 2); +          content: "/"; +          color: var(--muted-color); +          text-align: center; +        } +      } +    } + +    & a[aria-current] { +      background-color: transparent; +      color: inherit; +      text-decoration: none; +      pointer-events: none; +    } +  } + +  // Minimal support for role="button" +  [role="button"] { +    margin-right: inherit; +    margin-left: inherit; +    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal); +  } +} + +// Vertical Nav +aside { +  nav, +  ol, +  ul, +  li { +    display: block; +  } + +  li { +    padding: calc(var(--nav-element-spacing-vertical) * 0.5) +      var(--nav-element-spacing-horizontal); + +    a { +      display: block; +    } + +    // Minimal support for links as buttons +    [role="button"] { +      margin: inherit; +    } +  } +} + +// Breadcrumb RTL +[dir="rtl"] { +  nav { +    &[aria-label="breadcrumb"] { +      & ul li { +        &:not(:last-child) { +          ::after { +            content: "\\"; +          } +        } +      } +    } +  } +} diff --git a/app/assets/stylesheets/components/_progress.scss b/app/assets/stylesheets/components/_progress.scss new file mode 100644 index 0000000..d62ddc0 --- /dev/null +++ b/app/assets/stylesheets/components/_progress.scss @@ -0,0 +1,89 @@ +/** + * Progress + */ + +// Reboot based on : +// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css +// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css +// –––––––––––––––––––– + +// 1. Add the correct display in Edge 18- and IE +// 2. Add the correct vertical alignment in Chrome, Edge, and Firefox +progress { +  display: inline-block; // 1 +  vertical-align: baseline; // 2 +} + +// Pico +// –––––––––––––––––––– + +progress { +  // Reset the default appearance +  -webkit-appearance: none; +  -moz-appearance: none; + +  // Styles +  display: inline-block; +  appearance: none; +  width: 100%; +  height: 0.5rem; +  margin-bottom: calc(var(--spacing) * 0.5); +  overflow: hidden; + +  // Remove Firefox and Opera border +  border: 0; +  border-radius: var(--border-radius); +  background-color: var(--progress-background-color); + +  // IE10 uses `color` to set the bar background-color +  color: var(--progress-color); + +  &::-webkit-progress-bar { +    border-radius: var(--border-radius); +    background: none; +  } +  &[value]::-webkit-progress-value { +    background-color: var(--progress-color); +  } +  &::-moz-progress-bar { +    background-color: var(--progress-color); +  } + +  // Indeterminate state +  @media (prefers-reduced-motion: no-preference) { +    &:indeterminate { +      background: var(--progress-background-color) +        linear-gradient( +          to right, +          var(--progress-color) 30%, +          var(--progress-background-color) 30% +        ) +        top left / 150% 150% no-repeat; +      animation: progress-indeterminate  1s linear infinite; + +      &[value]::-webkit-progress-value { +        background-color: transparent; +      } +      &::-moz-progress-bar { +        background-color: transparent; +      } +    } +  } +} + +[dir="rtl"] { +  @media (prefers-reduced-motion: no-preference) { +    progress:indeterminate { +      animation-direction: reverse; +    } +  } +} + +@keyframes progress-indeterminate { +  0% { +    background-position: 200% 0; +  } +  100% { +    background-position: -200% 0; +  } +} |