Skip to content

Commit

Permalink
Merge pull request #6 from Travelopia/feature/multi-select
Browse files Browse the repository at this point in the history
Multi Select Component
  • Loading branch information
junaidbhura authored Nov 28, 2023
2 parents 7368b36 + c449145 commit 29a0a28
Show file tree
Hide file tree
Showing 17 changed files with 1,164 additions and 3 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@travelopia/web-components",
"version": "0.4.0",
"version": "0.5.0",
"description": "Accessible web components for the modern web",
"files": [
"dist"
Expand Down
123 changes: 123 additions & 0 deletions src/multi-select/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Multi Select

<table width="100%">
<tr>
<td align="left" width="70%">
<p>Built by the super talented team at <strong><a href="https://www.travelopia.com/work-with-us/">Travelopia</a></strong>.</p>
</td>
<td align="center" width="30%">
<img src="https://www.travelopia.com/wp-content/themes/travelopia/assets/svg/logo-travelopia-circle.svg" width="50" />
</td>
</tr>
</table>

## Sample Usage

This is a highly customizable multi-select component. Pick and choose subcomponents to use, and style as needed!

Example:

```js
// Import the component as needed:
import '@travelopia/web-components/dist/multi-select';
import '@travelopia/web-components/dist/multi-select/style.css';

// TypeScript usage:
import { TPMultiSelectElement } from '@travelopia/web-components';

...

const multiSelect: TPMultiSelectElement = document.querySelector( 'tp-multi-select' );
multiSelect.select( 'value' );
multiSelect.unSelect( 'value' );

const value = multiSelect.value;
```

```html
<!-- Variation 1 -->
<tp-multi-select name="names[]">
<tp-multi-select-field>
<tp-multi-select-placeholder>Select...</tp-multi-select-placeholder>
<tp-multi-select-status format="$total Selected"></tp-multi-select-status>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>

<!-- Variation 2 -->
<tp-multi-select name="names2[]" close-on-select="yes">
<tp-multi-select-field>
<tp-multi-select-pills></tp-multi-select-pills>
<tp-multi-select-search>
<input placeholder="Select...">
</tp-multi-select-search>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-select-all select-text="Select All" unselect-text="Un-Select All">Select All</tp-multi-select-select-all>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
<tp-multi-select-option value="jack" label="Jack">Jack</tp-multi-select-option>
<tp-multi-select-option value="jill" label="Jill">Jill</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>

<!-- Single Select -->
<tp-multi-select name="name" multiple="no" close-on-select="yes">
<tp-multi-select-field>
<tp-multi-select-placeholder>Select...</tp-multi-select-placeholder>
<tp-multi-select-status format="$value"></tp-multi-select-status>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-option value="" label="">Select...</tp-multi-select-option>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>
```

## Attributes

| Attribute | Required | Values | Notes |
|-----------------|----------|--------------------------|-------------------------------------------------------------------------------------|
| name | Yes | <name of the form field> | Whether the height of the slider changes depending on the content inside the slides |
| multiple | No | `yes`, `no` | Whether the field needs to be a single or mult-select form field. Yes by default |
| close-on-select | No | `yes` | Whether to close the options when a value is selected |

## Events

| Event | Notes |
|--------------|-----------------------------------------|
| open | When the options are opened |
| close | When the options are closed |
| change | When any value is selected or unselected |
| select | When a value is selected |
| select-all | When all values are selected |
| unselect | When a value is unselected |
| unselect-all | When all values are unselected |

## Methods

### `select`

Select a value.

### `unSelect`

Un-select a value.

### `selectAll`

Selects all values.

### `unSelectAll`

Un-select all values.
110 changes: 110 additions & 0 deletions src/multi-select/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Web Component: Multi Select</title>

<link rel="stylesheet" href="../../dist/multi-select/style.css" media="all">
<script type="module" src="../../dist/multi-select/index.js"></script>

<style>
* {
box-sizing: border-box;
}

main {
max-width: 400px;
margin: 0 auto;
}

tp-multi-select + tp-multi-select {
margin-top: 20px;
}

tp-multi-select-field {
width: 100%;
min-height: 30px;
border: 1px solid #000;
display: flex;
align-items: center;
padding: 5px;
}

tp-multi-select-options {
border: 1px solid #000;
}

tp-multi-select-select-all,
tp-multi-select-option {
cursor: pointer;
}

tp-multi-select-select-all {
border-bottom: 1px solid #000;
}

tp-multi-select-option + tp-multi-select-option {
border-top: 1px solid #000;
}

tp-multi-select-select-all[selected="yes"]::after,
tp-multi-select-option[selected="yes"]::after {
content: " ✓";
}

tp-multi-select-option[highlighted="yes"] {
background-color: #efefef;
}
</style>
</head>
<body>
<main>
<tp-multi-select name="names[]">
<tp-multi-select-field>
<tp-multi-select-placeholder>Select...</tp-multi-select-placeholder>
<tp-multi-select-status format="$total Selected"></tp-multi-select-status>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>

<tp-multi-select name="name" multiple="no" close-on-select="yes">
<tp-multi-select-field>
<tp-multi-select-placeholder>Select...</tp-multi-select-placeholder>
<tp-multi-select-status format="$value"></tp-multi-select-status>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-option value="" label="">Select...</tp-multi-select-option>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>

<tp-multi-select name="names2[]" close-on-select="yes">
<tp-multi-select-field>
<tp-multi-select-pills></tp-multi-select-pills>
<tp-multi-select-search>
<input placeholder="Select...">
</tp-multi-select-search>
</tp-multi-select-field>
<tp-multi-select-options>
<tp-multi-select-select-all select-text="Select All" unselect-text="Un-Select All">Select All</tp-multi-select-select-all>
<tp-multi-select-option value="priya" label="Priya">Priya</tp-multi-select-option>
<tp-multi-select-option value="varun" label="Varun">Varun</tp-multi-select-option>
<tp-multi-select-option value="john" label="John">John</tp-multi-select-option>
<tp-multi-select-option value="jane" label="Jane">Jane</tp-multi-select-option>
<tp-multi-select-option value="jack" label="Jack">Jack</tp-multi-select-option>
<tp-multi-select-option value="jill" label="Jill">Jill</tp-multi-select-option>
</tp-multi-select-options>
</tp-multi-select>
</main>
</body>
</html>
32 changes: 32 additions & 0 deletions src/multi-select/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Styles.
*/
import './style.scss';

/**
* Components.
*/
import { TPMultiSelectElement } from './tp-multi-select';
import { TPMultiSelectFieldElement } from './tp-multi-select-field';
import { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';
import { TPMultiSelectStatusElement } from './tp-multi-select-status';
import { TPMultiSelectOptionsElement } from './tp-multi-select-options';
import { TPMultiSelectOptionElement } from './tp-multi-select-option';
import { TPMultiSelectSearchElement } from './tp-multi-select-search';
import { TPMultiSelectPillElement } from './tp-multi-select-pill';
import { TPMultiSelectPillsElement } from './tp-multi-select-pills';
import { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';

/**
* Register Components.
*/
customElements.define( 'tp-multi-select', TPMultiSelectElement );
customElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );
customElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );
customElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );
customElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );
customElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );
customElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );
customElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );
customElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );
customElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );
71 changes: 71 additions & 0 deletions src/multi-select/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
tp-multi-select {
display: block;
position: relative;
user-select: none;

select {
visibility: hidden;
position: absolute;
}
}

tp-multi-select-field {
display: flex;
flex-wrap: wrap;
}

tp-multi-select-options {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: #fff;
z-index: 2;

tp-multi-select[open="yes"] & {
display: block;
}
}

tp-multi-select-option {
display: block;

&[hidden="yes"] {
display: none;
}
}

tp-multi-select-placeholder {
display: block;

tp-multi-select[selected="yes"] & {
display: none;
}
}

tp-multi-select-status {
display: none;

tp-multi-select[selected="yes"] & {
display: block;
}
}

tp-multi-select-search {

input {
box-sizing: border-box;
border: 0;
outline: none;
min-width: 3ch;
}
}

tp-multi-select-pills {
display: inline-block;
}

tp-multi-select-select-all {
display: block;
}
Loading

0 comments on commit 29a0a28

Please sign in to comment.