Skip to content

Commit

Permalink
[#150] Updated Select styles to designs from 1.8 (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexSkrypnyk committed Jun 5, 2024
1 parent 665b8ad commit 8c392ed
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 48 deletions.
15 changes: 12 additions & 3 deletions components/00-base/_variables.components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ $ct-chip-dark-focus-outline-color: ct-color-dark('interaction-focus') !default;
//
$ct-input-border-radius: $ct-border-radius, 1 !default;
$ct-input-light-background-color: ct-color-light('background-light') !default;
$ct-input-light-border-color: ct-color-light('border-light') !default;
$ct-input-light-border-color: ct-color-light('border') !default;
$ct-input-light-color: ct-color-light('body') !default;
$ct-input-light-hover-border-color: ct-color-light('interaction-background') !default;
$ct-input-light-focus-background-color: ct-color-light('background-light') !default;
Expand Down Expand Up @@ -324,18 +324,27 @@ $ct-label-dark-required-color: ct-color-dark('error') !default;
//
// Select.
//
$ct-select-min-width: 100% !default;
$ct-select-height: ct-particle(6);
$ct-select-padding-horizontal: ct-spacing(2);
$ct-select-padding-vertical: ct-spacing();
$ct-select-icon-height: rem(28px);
$ct-select-width: rem(38px);
$ct-select-border-width: ct-particle(0.125);
$ct-select-light-background-color: ct-color-light('background-light') !default;
$ct-select-light-color: ct-color-light('body') !default;
$ct-select-light-hover-border-color: ct-color-light('border-light') !default;
$ct-select-light-hover-border-color: ct-color-light('interaction-hover-background') !default;
$ct-select-light-focus-border-color: ct-color-light('interaction-background') !default;
$ct-select-light-error-border-color: ct-color-light('error') !default;
$ct-select-light-option-background-color: $ct-select-light-background-color !default;
$ct-select-light-option-background-color: ct-color-light('background') !default;
$ct-select-light-icon: url("data:image/svg+xml,%3Csvg width='38' height='28' viewBox='0 0 38 28' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 0H0V28H1V0Z' fill='black' fill-opacity='0.6'/%3E%3Cpath d='M17.0916 13.1714L19 13.1666C19 13.1666 20.7334 13.1666 20.9083 13.1666C21.0831 13.1666 21.0831 13.1666 21.0831 13.1666L21.5 13.1714C21.5 13.1714 21.7189 13.1497 21.8204 13.1074C21.922 13.0651 22.0141 13.0031 22.0916 12.9249C22.1697 12.8475 22.2317 12.7553 22.274 12.6538C22.3163 12.5522 22.3381 12.4433 22.3381 12.3333C22.3381 12.2233 22.3163 12.1144 22.274 12.0128C22.2317 11.9113 22.1697 11.8191 22.0916 11.7416L19.5916 9.24162C19.5141 9.16351 19.422 9.10151 19.3204 9.05921C19.2189 9.0169 19.11 8.99512 19 8.99512C18.8899 8.99512 18.781 9.0169 18.6795 9.05921C18.5779 9.10151 18.4858 9.16351 18.4083 9.24162L15.9083 11.7416C15.7514 11.8985 15.6632 12.1114 15.6632 12.3333C15.6632 12.5552 15.7514 12.768 15.9083 12.9249C16.0652 13.0819 16.278 13.17 16.5 13.17C16.7219 13.17 17.0916 13.1714 17.0916 13.1714ZM20.9083 15.6666H19H17.0916C16.9165 15.6666 16.9165 15.6632 16.8202 15.6632C16.4998 15.6632 16.6098 15.6632 16.5 15.6632C16.3901 15.6632 16.2813 15.6848 16.1797 15.7269C16.0782 15.7689 15.986 15.8306 15.9083 15.9083C15.8306 15.986 15.769 16.0782 15.7269 16.1797C15.6849 16.2813 15.6632 16.3901 15.6632 16.4999C15.6632 16.6098 15.6849 16.7186 15.7269 16.8202C15.769 16.9217 15.8306 17.0139 15.9083 17.0916L18.4083 19.5916C18.4858 19.6697 18.5779 19.7317 18.6795 19.774C18.781 19.8163 18.8899 19.8381 19 19.8381C19.11 19.8381 19.2189 19.8163 19.3204 19.774C19.422 19.7317 19.5141 19.6697 19.5916 19.5916L22.0916 17.0916C22.2485 16.9347 22.3367 16.7219 22.3367 16.4999C22.3367 16.278 22.2485 16.0652 22.0916 15.9083C21.9347 15.7514 21.7219 15.6632 21.5 15.6632C21.278 15.6632 21.0831 15.6666 20.9083 15.6666Z' fill='black' fill-opacity='0.6'/%3E%3C/svg%3E%0A");
$ct-select-dark-background-color: ct-color-dark('background-light') !default;
$ct-select-dark-color: ct-color-dark('body') !default;
$ct-select-dark-hover-border-color: ct-color-dark('border-light') !default;
$ct-select-dark-focus-border-color: ct-color-dark('interaction-background') !default;
$ct-select-dark-error-border-color: ct-color-dark('error') !default;
$ct-select-dark-option-background-color: $ct-select-dark-background-color !default;
$ct-select-dark-icon: url("data:image/svg+xml,%3Csvg width='38' height='28' viewBox='0 0 38 28' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 0H0V28H1V0Z' fill='white' fill-opacity='0.9'/%3E%3Cpath d='M17.0916 13.1714L19 13.1666C19 13.1666 20.7334 13.1666 20.9083 13.1666C21.0831 13.1666 21.0831 13.1666 21.0831 13.1666L21.5 13.1714C21.5 13.1714 21.7189 13.1497 21.8204 13.1074C21.922 13.0651 22.0141 13.0031 22.0916 12.9249C22.1697 12.8475 22.2317 12.7553 22.274 12.6538C22.3163 12.5522 22.3381 12.4433 22.3381 12.3333C22.3381 12.2233 22.3163 12.1144 22.274 12.0128C22.2317 11.9113 22.1697 11.8191 22.0916 11.7416L19.5916 9.24162C19.5141 9.16351 19.422 9.10151 19.3204 9.05921C19.2189 9.0169 19.11 8.99512 19 8.99512C18.8899 8.99512 18.781 9.0169 18.6795 9.05921C18.5779 9.10151 18.4858 9.16351 18.4083 9.24162L15.9083 11.7416C15.7514 11.8985 15.6632 12.1114 15.6632 12.3333C15.6632 12.5552 15.7514 12.768 15.9083 12.9249C16.0652 13.0819 16.278 13.17 16.5 13.17C16.7219 13.17 17.0916 13.1714 17.0916 13.1714ZM20.9083 15.6666H19H17.0916C16.9165 15.6666 16.9165 15.6632 16.8202 15.6632C16.4998 15.6632 16.6098 15.6632 16.5 15.6632C16.3901 15.6632 16.2813 15.6848 16.1797 15.7269C16.0782 15.7689 15.986 15.8306 15.9083 15.9083C15.8306 15.986 15.769 16.0782 15.7269 16.1797C15.6849 16.2813 15.6632 16.3901 15.6632 16.4999C15.6632 16.6098 15.6849 16.7186 15.7269 16.8202C15.769 16.9217 15.8306 17.0139 15.9083 17.0916L18.4083 19.5916C18.4858 19.6697 18.5779 19.7317 18.6795 19.774C18.781 19.8163 18.8899 19.8381 19 19.8381C19.11 19.8381 19.2189 19.8163 19.3204 19.774C19.422 19.7317 19.5141 19.6697 19.5916 19.5916L22.0916 17.0916C22.2485 16.9347 22.3367 16.7219 22.3367 16.4999C22.3367 16.278 22.2485 16.0652 22.0916 15.9083C21.9347 15.7514 21.7219 15.6632 21.5 15.6632C21.278 15.6632 21.0831 15.6666 20.9083 15.6666Z' fill='white' fill-opacity='0.9'/%3E%3C/svg%3E%0A");

//
// Content Link.
Expand Down
14 changes: 8 additions & 6 deletions components/00-base/base.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,15 +311,17 @@ export const generateSelectItems = (count) => {
return items;
};

export const generateOptions = (numOfOptions, optionType = 'option') => {
export const generateSelectOptions = (count, type = 'option') => {
const options = [];
for (let i = 1; i <= numOfOptions; i++) {
for (let i = 1; i <= count; i++) {
const disabled = randomBool(0.8);
const option = {
type: optionType,
selected: false,
label: optionType === 'optgroup' ? `Group ${i}` : randomString(randomInt(3, 8)),
type,
is_selected: randomBool(0.8),
is_disabled: disabled,
label: (type === 'optgroup' ? `Group ${i}` : randomString(randomInt(3, 8))) + (disabled ? ' (disabled)' : ''),
value: randomString(randomInt(1, 8)),
options: optionType === 'optgroup' ? generateOptions(numOfOptions) : null,
options: type === 'optgroup' ? generateSelectOptions(count) : null,
};
options.push(option);
}
Expand Down
72 changes: 51 additions & 21 deletions components/01-atoms/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@

@include ct-typography('text-regular');

display: flex;
flex-direction: row;
align-items: center;
min-width: ct-particle(38);
height: ct-particle(6);
padding: 0.5em 3.5em 0.5em 1em;
background-position: calc(100% - 0.5rem), 100% 0;
background-size: 1.5em 1.5em;
appearance: none;
border-radius: $ct-border-radius;
border-width: $ct-select-border-width;
min-width: $ct-select-min-width;
height: $ct-select-height;
padding-top: $ct-select-padding-vertical;
padding-bottom: $ct-select-padding-vertical;
padding-left: $ct-select-padding-horizontal;
padding-right: $ct-select-padding-horizontal + $ct-select-width;

// Visually move icon off the edge by the width of the border.
background-position: calc(100% - $ct-select-border-width);
background-repeat: no-repeat;
background-size: $ct-select-width $ct-select-icon-height;

&[disabled] {
pointer-events: none;
Expand All @@ -24,11 +29,33 @@

&[multiple] {
height: inherit;
padding-left: $ct-select-padding-horizontal;
padding-right: $ct-select-padding-horizontal;
padding-top: $ct-select-padding-vertical * 2;
padding-bottom: $ct-select-padding-vertical * 2;

optgroup,
option {
margin-top: ct-spacing();

&:first-child {
margin-top: 0;
}
}

optgroup {
font-weight: bold;

option {
&:first-child {
margin-top: ct-spacing();
}
}
}
}

&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #000;
}

&:-webkit-scrollbar {
Expand All @@ -39,14 +66,19 @@
background-color: $ct-select-light-background-color;
border-color: $ct-input-light-border-color;
color: $ct-select-light-color;
background-image: $ct-select-light-icon;

&:hover {
// Here and below, we are using the box shadow in addition to the border
// to avoid the element from moving when the border is added.
border-color: $ct-select-light-hover-border-color;
box-shadow: 0 0 0 ct-particle(0.125) $ct-select-light-hover-border-color;
}

&:focus-visible {
border-color: $ct-select-light-focus-border-color;
box-shadow: 0 0 0 ct-particle(0.125) $ct-select-light-focus-border-color;
outline: none;
}

&.error,
Expand All @@ -55,12 +87,10 @@
box-shadow: 0 0 0 ct-particle(0.125) $ct-select-light-error-border-color;
}

&:-internal-list-box {
option {
&:checked {
background-color: $ct-select-light-option-background-color;
color: inherit;
}
option {
&:checked {
background-color: $ct-select-light-option-background-color;
color: inherit;
}
}

Expand All @@ -73,6 +103,7 @@
background-color: $ct-select-dark-background-color;
border-color: $ct-input-dark-border-color;
color: $ct-select-dark-color;
background-image: $ct-select-dark-icon;

&:hover {
border-color: $ct-select-dark-hover-border-color;
Expand All @@ -82,6 +113,7 @@
&:focus-visible {
border-color: $ct-select-dark-focus-border-color;
box-shadow: 0 0 0 ct-particle(0.125) $ct-select-dark-focus-border-color;
outline: none;
}

&.error,
Expand All @@ -90,12 +122,10 @@
box-shadow: 0 0 0 ct-particle(0.125) $ct-select-dark-error-border-color;
}

&:-internal-list-box {
option {
&:checked {
background-color: $ct-select-dark-option-background-color;
color: inherit;
}
option {
&:checked {
background-color: $ct-select-dark-option-background-color;
color: inherit;
}
}

Expand Down
22 changes: 13 additions & 9 deletions components/01-atoms/select/select.stories.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import CivicThemeSelect from './select.twig';
import { generateOptions, knobBoolean, knobRadios, knobText, randomInt, shouldRender } from '../../00-base/base.utils';
import { generateSelectOptions, knobBoolean, knobRadios, knobText, randomInt, shouldRender } from '../../00-base/base.utils';

export default {
title: 'Atoms/Select',
parameters: {
layout: 'centered',
wrapperSize: 'small',
wrapperIsContainer: true,
wrapperIsResizable: true,
},
};

Expand All @@ -17,16 +20,17 @@ export const Select = (props = {}) => {
Dark: 'dark',
},
'light',
props.theme,
props.knobTab,
),
is_multiple: knobBoolean('Is multiple', false, props.knobTab),
options: knobBoolean('With options', true, props.knobTab) ? generateOptions(randomInt(3, 5), (knobBoolean('Options have groups', false, props.knobTab) ? 'optgroup' : 'option')) : [],
is_required: knobBoolean('Required', false, props.knobTab),
disabled: knobBoolean('Disabled', false, props.knobTab),
has_error: knobBoolean('Has error', false, props.knobTab),
for: knobText('For', '', props.knobTab),
attributes: knobText('Additional attributes', '', props.knobTab),
modifier_class: knobText('Additional classes', '', props.knobTab),
is_multiple: knobBoolean('Is multiple', false, props.is_multiple, props.knobTab),
options: knobBoolean('With options', true, props.options, props.knobTab) ? generateSelectOptions(randomInt(3, 5), (knobBoolean('Options have groups', false, null, props.knobTab) ? 'optgroup' : 'option')) : [],
is_required: knobBoolean('Required', false, props.is_required, props.knobTab),
is_disabled: knobBoolean('Disabled', false, props.is_disabled, props.knobTab),
has_error: knobBoolean('Has error', false, props.has_error, props.knobTab),
for: knobText('For', '', props.for, props.knobTab),
attributes: knobText('Additional attributes', '', props.attributes, props.knobTab),
modifier_class: knobText('Additional classes', '', props.modifier_class, props.knobTab),
};

return shouldRender(props) ? CivicThemeSelect(knobs) : knobs;
Expand Down
19 changes: 10 additions & 9 deletions components/01-atoms/select/select.twig
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,43 @@
* - options: [array] Array of options (applies to optgroup type):
* - label: [string] Option label.
* - value: [string] Option value.
* - selected: [string] Flag whether option is selected.
* - is_selected: [string] Flag whether option is selected.
* - is_disabled: [string] Flag whether option is disabled.
* - is_required: [boolean] Required state.
* - disabled: [boolean] Disabled state.
* - is_disabled: [boolean] Disabled state.
* - has_error: [boolean] Error state.
* - for: [string] Which component this label belongs to.
* - attributes: [string] Additional attributes.
* - modifier_class: [string] Additional classes.
*/
#}

{% set required_class = is_required ? 'ct-input--required required' : '' %}
{% set error_class = has_error ? 'ct-input--error error' : '' %}
{% set required_class = is_required ? 'required' : '' %}
{% set error_class = has_error ? 'error' : '' %}
{% set theme_class = 'ct-theme-%s'|format(theme|default('light')) %}
{% set modifier_class = '%s %s %s %s'|format(theme_class, required_class, error_class, modifier_class|default('')) %}

{% if options is not empty %}
<select
class="ct-select ct-input__element {{ modifier_class }}"
class="ct-select {{ modifier_class }}"
{{ is_multiple ? 'multiple' }}
{{ disabled ? 'disabled' }}
{{ is_disabled ? 'disabled' }}
{{ is_required ? 'required' }}
{% if for is not empty %} for="{{ for }}" {% endif %}
{% if attributes is not empty %}{{ attributes|raw }}{% endif %}
>
{% for option in options %}
{% if option.type == 'optgroup' %}
<optgroup label="{{ option.label }}">
<optgroup label="{{ option.label }}" {{ option.is_disabled ? 'disabled' }}>
{% for sub_option in option.options %}
{% if sub_option.label is not empty %}
<option value="{{ sub_option.value|default('') }}" {{ sub_option.selected ? 'selected="selected"' }}>{{ sub_option.label }}</option>
<option value="{{ sub_option.value|default('') }}" {{ sub_option.is_selected ? 'selected="selected"' }} {{ sub_option.is_disabled ? 'disabled' }}>{{ sub_option.label }}</option>
{% endif %}
{% endfor %}
</optgroup>
{% elseif option.type == 'option' %}
{% if option.label is not empty %}
<option value="{{ option.value|default('') }}" {{ option.selected ? 'selected="selected"' }}>{{ option.label }}</option>
<option value="{{ option.value|default('') }}" {{ option.is_selected ? 'selected="selected"' }} {{ option.is_disabled ? 'disabled' }}>{{ option.label }}</option>
{% endif %}
{% endif %}
{% endfor %}
Expand Down

1 comment on commit 8c392ed

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.