dh_demo

DreamHanks demo project
git clone git://git.lair.cx/dh_demo
Log | Files | Refs | README

Field.module.scss (3928B)


      1 @use 'sass:math';
      2 @use 'core/colors';
      3 @use 'core/typography';
      4 
      5 $max-width: 25rem;
      6 $height: 3.5rem;
      7 $icon-size: 1.5rem;
      8 $field-gap: 1rem;
      9 $padding-without-icon: 1rem;
     10 $padding-with-icon: 0.75rem;
     11 $label-focused-scale: 0.8;
     12 $textarea-line-height: 1.5rem;
     13 
     14 .fields-wrapper {
     15   display: flex;
     16   flex-direction: column;
     17   align-items: flex-start;
     18   max-width: $max-width;
     19 
     20   @include colors.apply-themes using ($theme) {
     21     background-color: colors.get($theme, 'surface');
     22     color: colors.get($theme, 'on-surface');
     23   }
     24 
     25   &.is-horizontal {
     26     flex-direction: row;
     27     align-items: center;
     28     gap: 1rem;
     29     max-width: 100%;
     30   }
     31 }
     32 
     33 .field {
     34   display: flex;
     35   position: relative;
     36   border: 1px solid transparent;
     37   margin-bottom: 1rem;
     38   border-radius: 4px;
     39   background-color: inherit;
     40   box-shadow: 0 0 0 1px transparent;
     41   transition: all 200ms;
     42   align-self: stretch;
     43 
     44   .is-horizontal & {
     45     margin-bottom: 0;
     46     flex-grow: 1;
     47   }
     48 
     49   @include colors.apply-themes using ($theme) {
     50     color: colors.get($theme, 'on-surface');
     51     border-color: colors.get($theme, 'outline');
     52 
     53     &.is-disabled {
     54       color: rgba(colors.get($theme, 'on-surface'), 0.5);
     55       border-color: rgba(colors.get($theme, 'outline'), 0.5);
     56     }
     57 
     58     &.is-not-readonly.has-no-color:focus-within {
     59       border-color: colors.get($theme, 'primary');
     60       box-shadow: 0 0 0 1px colors.get($theme, 'primary');
     61     }
     62 
     63     @include colors.sets($theme) using ($key, $color, $color-on) {
     64       &.is-#{$key} {
     65         color: $color;
     66         border-color: $color;
     67 
     68         &:focus-within {
     69           box-shadow: 0 0 0 1px $color;
     70         }
     71       }
     72     }
     73   }
     74 }
     75 
     76 .input,
     77 .textarea {
     78   width: 100%;
     79   height: $height;
     80   border: 0;
     81   padding: 0 $padding-without-icon;
     82   color: inherit;
     83   background: transparent;
     84   outline: none;
     85 
     86   $input-padding-with-icon: $padding-with-icon + $icon-size + $field-gap;
     87 
     88   .field.has-icon-left & {
     89     padding-left: $input-padding-with-icon;
     90   }
     91 
     92   .field.has-icon-right & {
     93     padding-right: $input-padding-with-icon;
     94   }
     95 }
     96 
     97 .textarea {
     98   resize: none;
     99   line-height: $textarea-line-height;
    100   padding: math.div(($height - $textarea-line-height), 2) $padding-without-icon;
    101   overflow-y: hidden;
    102 }
    103 
    104 .label-background {
    105   $label-background-padding: math.div(0.25rem, $label-focused-scale);
    106 
    107   position: absolute;
    108   top: -3px;
    109   left: $padding-without-icon - $label-background-padding;
    110   height: 4px;
    111   padding: 0 $label-background-padding;
    112   line-height: 0;
    113   color: transparent;
    114   background-color: inherit;
    115   transform: translateX(-10%) scaleX(0);
    116   transition: 200ms transform ease-in-out;
    117 
    118   .field.is-not-readonly:focus-within &,
    119   .field.has-content & {
    120     transform: translateX(-10%) scaleX($label-focused-scale);
    121   }
    122 }
    123 
    124 .label {
    125   position: absolute;
    126   top: 50%;
    127   left: $padding-without-icon;
    128   pointer-events: none;
    129   transform-origin: left top;
    130   transform: translateY(-50%);
    131   transition: all 0.2s ease-in-out;
    132   z-index: 1;
    133 
    134   .field.has-icon-left & {
    135     left: $padding-with-icon;
    136   }
    137 
    138   .field.is-not-readonly:focus-within &,
    139   .field.has-content & {
    140     top: 0;
    141     transform: scale($label-focused-scale) translateY(-50%);
    142   }
    143 
    144   @include colors.apply-themes using ($theme) {
    145     color: colors.get($theme, 'on-surface-variant');
    146 
    147     .field.is-not-readonly.has-no-color:focus-within & {
    148       color: colors.get($theme, 'primary');
    149     }
    150 
    151     .field.is-disabled & {
    152       color: rgba(colors.get($theme, 'on-surface-variant'), 0.5);
    153     }
    154 
    155     @include colors.sets($theme) using ($key, $color, $color-on) {
    156       .is-#{$key} & {
    157         color: $color;
    158       }
    159     }
    160   }
    161 }
    162 
    163 .message {
    164   @include typography.apply('body-medium');
    165   margin-top: -0.75rem;
    166   margin-bottom: 1rem;
    167 
    168   @include colors.apply-themes using ($theme) {
    169     color: colors.get($theme, 'on-surface-variant');
    170 
    171     @include colors.sets($theme) using ($key, $color, $color-on) {
    172       .is-#{$key} & {
    173         color: $color;
    174       }
    175     }
    176   }
    177 }