Skip to content

Commit

Permalink
feat(select): add multiple option to limel-select, replacing limel-…
Browse files Browse the repository at this point in the history
…multi-select

fix #203
  • Loading branch information
adrianschmidt committed Apr 1, 2019
1 parent 13f7f49 commit 1f7fd41
Show file tree
Hide file tree
Showing 12 changed files with 443 additions and 186 deletions.
13 changes: 0 additions & 13 deletions src/components/multi-select/multi-select.mdx

This file was deleted.

26 changes: 26 additions & 0 deletions src/components/select-multiple/select-multiple.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import '../../style/variables';

@import '@lime-material-16px/form-field/mdc-form-field';
@import '@lime-material-16px/checkbox/mdc-checkbox';
@import "@lime-material-16px/floating-label/mdc-floating-label";

.multi-select {
position: relative;
}

.multi-select-label {
padding-left: pxToRem(15);
}

.mdc-form-field {
display: flex;
}

.mdc-checkbox {
@include mdc-checkbox-ink-color(primary);
@include mdc-checkbox-container-colors(secondary, on-primary, secondary, on-primary);
}

limel-collapsible-section {
--body-max-height: 70vh;
}
147 changes: 147 additions & 0 deletions src/components/select-multiple/select-multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { MDCCheckbox } from '@lime-material-16px/checkbox';
import { MDCFormField } from '@lime-material-16px/form-field';
import {
Component,
Element,
Event,
EventEmitter,
Prop,
State,
} from '@stencil/core';
import { Option } from '../../interface';
import { createRandomString } from '../../util/random-string';

@Component({
tag: 'limel-select-multiple',
shadow: true,
styleUrl: 'select-multiple.scss',
})
export class SelectMultiple {
@Prop({ reflectToAttr: true })
public disabled = false;

@Prop({ reflectToAttr: true })
public label: string;

@Prop()
public value: Option[] = [];

@Prop()
public options: Option[] = [];

@Event()
private change: EventEmitter<Option[]>;

@Element()
private limelMultiSelect: HTMLElement;

@State()
private fieldId = createRandomString();

@State()
private mdcCheckboxes = [];

public componentDidLoad() {
const elements = Array.from(
this.limelMultiSelect.shadowRoot.querySelectorAll(
'.multi-select .mdc-form-field'
)
);

elements.forEach(element => {
const formField = new MDCFormField(element);
const checkbox = new MDCCheckbox(element.firstChild);
formField.input = checkbox;
this.mdcCheckboxes.push(checkbox);
});

this.onChange();
}

public render() {
return (
<div class="multi-select">
<limel-collapsible-section
header={
this.label +
': ' +
this.value
.map(option => {
return option.text;
})
.join(', ')
}
>
<div>
{this.options.map((option: Option, index: number) => {
return this.renderCheckbox(index, option);
})}
</div>
</limel-collapsible-section>
</div>
);
}

private renderCheckbox(index: number, option: Option) {
return (
<div class="mdc-form-field ">
<div
class={`
mdc-checkbox
${this.disabled ? 'mdc-checkbox--disabled' : ''}
`}
>
<input
type="checkbox"
class="mdc-checkbox__native-control"
id={this.fieldId + '_' + index.toString()}
value={option.value}
checked={!!this.isOptionChecked(option)}
disabled={this.disabled}
onChange={this.onChange}
/>
<div class="mdc-checkbox__background">
<svg
class="mdc-checkbox__checkmark"
viewBox="0 0 24 24"
>
<path
class="mdc-checkbox__checkmark-path"
fill="none"
d="M1.73,12.91 8.1,19.28 22.79,4.59"
/>
</svg>
<div class="mdc-checkbox__mixedmark" />
</div>
</div>
<label htmlFor={this.fieldId + '_' + index.toString()}>
{option.text}
</label>
</div>
);
}

private isOptionChecked(option: Option) {
return this.value.find(checkedOption => {
return checkedOption.value === option.value;
});
}

private onChange = (event?) => {
if (event) {
event.stopPropagation();
}

const checked = this.options.filter(option => {
const optionChecked = this.mdcCheckboxes.some(mdcCheckbox => {
return (
mdcCheckbox.checked && mdcCheckbox.value === option.value
);
});
if (optionChecked) {
return option;
}
});
this.change.emit(checked);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import { newE2EPage } from '@stencil/core/testing';
// Matchers (expect-methods) for E2EElement (v0.13.0-9):
// https://github.com/ionic-team/stencil/blob/a0250ffcbf5a2c657475a05052eac3a4690809d2/src/declarations/testing.ts#L5

describe('limel-select', () => {
describe('limel-select-single', () => {
let page;
describe('with a label', () => {
let limelSelect;
let label;
beforeEach(async () => {
page = await createPage(`
<limel-select label="Favourite Doctor"></limel-select>
<limel-select-single label="Favourite Doctor"></limel-select-single>
`);
limelSelect = await page.find('limel-select');
label = await page.find('limel-select>>>.mdc-floating-label');
limelSelect = await page.find('limel-select-single');
label = await page.find('limel-select-single>>>.mdc-floating-label');
});
it('displays the correct label', () => {
expect(label).toEqualText('Favourite Doctor');
Expand All @@ -43,11 +43,11 @@ describe('limel-select', () => {
let innerSelect;
beforeEach(async () => {
page = await createPage(`
<limel-select label="Favourite Doctor"></limel-select>
<limel-select-single label="Favourite Doctor"></limel-select-single>
`);
limelSelect = await page.find('limel-select');
mdcSelect = await page.find('limel-select>>>.mdc-select');
innerSelect = await page.find('limel-select>>>select');
limelSelect = await page.find('limel-select-single');
mdcSelect = await page.find('limel-select-single>>>.mdc-select');
innerSelect = await page.find('limel-select-single>>>select');
});
it('is enabled', () => {
expect(mdcSelect).not.toHaveClass('mdc-select--disabled');
Expand Down Expand Up @@ -80,11 +80,11 @@ describe('limel-select', () => {
let innerSelect;
beforeEach(async () => {
page = await createPage(`
<limel-select label="Favourite Doctor" disabled="false"></limel-select>
<limel-select-single label="Favourite Doctor" disabled="false"></limel-select-single>
`);
limelSelect = await page.find('limel-select');
mdcSelect = await page.find('limel-select>>>.mdc-select');
innerSelect = await page.find('limel-select>>>select');
limelSelect = await page.find('limel-select-single');
mdcSelect = await page.find('limel-select-single>>>.mdc-select');
innerSelect = await page.find('limel-select-single>>>select');
});
it('is enabled', () => {
expect(mdcSelect).not.toHaveClass('mdc-select--disabled');
Expand Down Expand Up @@ -117,11 +117,11 @@ describe('limel-select', () => {
let innerSelect;
beforeEach(async () => {
page = await createPage(`
<limel-select label="Favourite Doctor" disabled="true"></limel-select>
<limel-select-single label="Favourite Doctor" disabled="true"></limel-select-single>
`);
limelSelect = await page.find('limel-select');
mdcSelect = await page.find('limel-select>>>.mdc-select');
innerSelect = await page.find('limel-select>>>select');
limelSelect = await page.find('limel-select-single');
mdcSelect = await page.find('limel-select-single>>>.mdc-select');
innerSelect = await page.find('limel-select-single>>>select');
});
it('is disabled', () => {
expect(mdcSelect).toHaveClass('mdc-select--disabled');
Expand Down Expand Up @@ -160,9 +160,9 @@ describe('limel-select', () => {
<select-test-wrapper></select-test-wrapper>
`);
testWrapper = await page.find('select-test-wrapper');
limelSelect = await page.find('limel-select');
innerSelect = await page.find('limel-select>>>select');
label = await page.find('limel-select>>>.mdc-floating-label');
limelSelect = await page.find('limel-select-single');
innerSelect = await page.find('limel-select-single>>>select');
label = await page.find('limel-select-single>>>.mdc-floating-label');
});
it('has no options', async () => {
const child = await innerSelect.find('option');
Expand Down
File renamed without changes.
Loading

0 comments on commit 1f7fd41

Please sign in to comment.