diff --git a/src/components/FieldGroupCheckbox/FieldGroupCheckbox.js b/src/components/FieldGroupCheckbox/FieldGroupCheckbox.js index 60310cad..9fff4927 100644 --- a/src/components/FieldGroupCheckbox/FieldGroupCheckbox.js +++ b/src/components/FieldGroupCheckbox/FieldGroupCheckbox.js @@ -1,3 +1,12 @@ +/* + * Renders a group of checkboxes that can be used to select + * multiple values from a set of options. + * + * The corresponding component when rendering the selected + * values is PropertyGroup. + * + */ + import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; diff --git a/src/components/PropertyGroup/PropertyGroup.css b/src/components/PropertyGroup/PropertyGroup.css new file mode 100644 index 00000000..8576fc2d --- /dev/null +++ b/src/components/PropertyGroup/PropertyGroup.css @@ -0,0 +1,84 @@ +@import '../../marketplace.css'; + +:root { + --lineHeight: 24px; + --lineThroughTop: calc(var(--lineHeight) - 7px); + --lineThroughBottom: calc(var(--lineHeight) - 6px); + --lineHeightMobile: 20px; + --lineThroughTopMobile: calc(var(--lineHeightMobile) - 5px); + --lineThroughBottomMobile: calc(var(--lineHeightMobile) - 4px); +} + +.root { + margin: 0; +} + +.twoColumns { + @media (--viewportMedium) { + column-count: 2; + } +} + +.item { + display: flex; + align-items: center; + padding: 2px 0; + + @media (--viewportMedium) { + padding: 4px 0; + } +} + +.checkIcon { + margin: 1px 8px -1px 0; +} + +.hidden { + visibility: hidden; +} + +.marketplaceFill { + fill: var(--marketplaceColor); +} + +.iconWrapper { + display: inline-flex; + align-items: center; +} + +.textWrapper { + display: inline-block; +} + +.selectedText, +.notSelectedText { + @apply --marketplaceBodyFontStyles; + line-height: var(--lineHeight); + margin: 0; +} + +.selectedText { + font-weight: var(--fontWeightSemiBold); +} + +.notSelectedText { + color: var(--matterColorNegative); + position: relative; + + /* line-through */ + background-image: linear-gradient( + transparent var(--lineThroughTopMobile), + var(--matterColorNegative) var(--lineThroughTopMobile), + var(--matterColorNegative) var(--lineThroughBottomMobile), + transparent var(--lineThroughBottomMobile) + ); + + @media (--viewportMedium) { + background-image: linear-gradient( + transparent var(--lineThroughTop), + var(--matterColorNegative) var(--lineThroughTop), + var(--matterColorNegative) var(--lineThroughBottom), + transparent var(--lineThroughBottom) + ); + } +} diff --git a/src/components/PropertyGroup/PropertyGroup.example.js b/src/components/PropertyGroup/PropertyGroup.example.js new file mode 100644 index 00000000..8a4bbfd8 --- /dev/null +++ b/src/components/PropertyGroup/PropertyGroup.example.js @@ -0,0 +1,23 @@ +import PropertyGroup from './PropertyGroup'; + +const exampleOptions = [ + { value: 'towels', text: 'Towels' }, + { value: 'bathroom', text: 'Bathroom' }, + { value: 'swimming', text: 'Swimming' }, + { value: 'own_drinks_allowed', text: 'Own drinks allowed' }, + { value: 'jacuzzi', text: 'Jacuzzi' }, + { value: 'audiovisual_entertainment', text: 'Audiovisual entertainment' }, + { value: 'barbeque', text: 'Barbeque' }, + { value: 'own_food_allowed', text: 'Own food allowed' }, +]; + +export const WithSomeSelected = { + component: PropertyGroup, + props: { + id: 'amenities', + options: exampleOptions, + selectedOptions: ['towels', 'bathroom', 'barbeque'], + twoColumns: true, + }, + group: 'misc', +}; diff --git a/src/components/PropertyGroup/PropertyGroup.js b/src/components/PropertyGroup/PropertyGroup.js new file mode 100644 index 00000000..4679b53b --- /dev/null +++ b/src/components/PropertyGroup/PropertyGroup.js @@ -0,0 +1,92 @@ +/* + * Renders a set of options with selected and non-selected values. + * + * The corresponding component when selecting the values is + * FieldGroupCheckbox. + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { includes } from 'lodash'; + +import css from './PropertyGroup.css'; + +const checkSelected = (options, selectedOptions) => { + return options.map(option => ({ + text: option.text, + value: option.value, + isSelected: includes(selectedOptions, option.value), + })); +}; + +const IconCheck = props => { + const isVisible = props.isVisible; + const classes = isVisible ? css.checkIcon : classNames(css.checkIcon, css.hidden); + + return ( + + ); +}; + +const Item = props => { + const { text, isSelected } = props; + const textClass = isSelected ? css.selectedText : css.notSelectedText; + return ( +