Skip to content

Commit

Permalink
Merge pull request #1382 from matuzalemsteles/improvements-clay-multi…
Browse files Browse the repository at this point in the history
…-select

Fixes #1381 - Improvements clay multi select
  • Loading branch information
jbalsas authored Dec 18, 2018
2 parents 44b489b + 1a60380 commit 9e9e529
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 161 deletions.
9 changes: 6 additions & 3 deletions packages/clay-autocomplete/src/ClayAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class ClayAutocomplete extends ClayComponent {
const item = this.filteredItems[Number(index)];

return !this.emit({
data: item,
data: item.data,
name: 'itemSelected',
originalEvent: event,
});
Expand Down Expand Up @@ -155,6 +155,7 @@ class ClayAutocomplete extends ClayComponent {
data: {
value: this.refs.input.value,
key: event.key,
eventFromInput: event.delegateTarget.tagName === 'INPUT',
},
name: 'inputOnKeydown',
originalEvent: event,
Expand Down Expand Up @@ -268,9 +269,11 @@ ClayAutocomplete.STATE = {
* @instance
* @default (elem) => elem
* @memberof ClayAutocomplete
* @type {?(function|undefined)}
* @type {?(function|string)}
*/
extractData: Config.func(),
extractData: Config.oneOfType([Config.func(), Config.string()]).value(
elem => elem
),

/**
* List of filtered items for suggestion or autocomplete.
Expand Down
9 changes: 5 additions & 4 deletions packages/clay-autocomplete/src/__tests__/ClayAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ describe('ClayAutocomplete', function() {
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
data: {
value: 'foo',
eventFromInput: true,
key: 'o',
value: 'foo',
},
name: 'inputOnKeydown',
originalEvent: expect.any(Object),
Expand Down Expand Up @@ -205,7 +206,7 @@ describe('ClayAutocomplete', function() {
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.any(Object),
data: 'Bread',
name: 'itemSelected',
originalEvent: expect.any(Object),
})
Expand Down Expand Up @@ -238,7 +239,7 @@ describe('ClayAutocomplete', function() {
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.any(Object),
data: 'Bread',
name: 'itemSelected',
originalEvent: expect.any(Object),
})
Expand All @@ -262,7 +263,7 @@ describe('ClayAutocomplete', function() {

expect(spy).not.toHaveBeenCalledWith(
expect.objectContaining({
data: expect.any(Object),
data: 'Bread',
name: 'itemSelected',
originalEvent: expect.any(Object),
})
Expand Down
26 changes: 23 additions & 3 deletions packages/clay-data-provider/src/ClayDataProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ class ClayDataProvider extends ClayComponent {
}
}

/**
* Handles data mapping.
* @param {!(function|string)} param
* @param {!Array} data
* @protected
* @return {!(string|number)}
*/
_performCall(param, data) {
if (typeof param === 'function') {
return param(data);
}

if (typeof data === 'string') {
return data;
}

return data[param];
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -131,7 +150,7 @@ class ClayDataProvider extends ClayComponent {
/**
* Helper method to filter a list based on a string.
* @param {!string} query
* @param {?function} extract
* @param {?(function|string)} extract
* @public
* @return {Array} A list of items containing the corresponding characters
*/
Expand All @@ -142,15 +161,16 @@ class ClayDataProvider extends ClayComponent {

return this._dataSource
.reduce((prev, element, index) => {
let string = extract(element);
let string = this._performCall(extract, element);
let result = match(query, string);

if (result != null) {
prev[prev.length] = {
data: element,
index,
matches: result.values,
originalString: string,
score: result.score,
value: string,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ describe('ClayDataProvider', function() {

expect(filteredItem).toEqual([
{
data: 'Bread',
index: 0,
matches: [
{match: true, value: 'B'},
Expand All @@ -83,7 +84,7 @@ describe('ClayDataProvider', function() {
{match: true, value: 'a'},
{value: 'd'},
],
originalString: 'Bread',
value: 'Bread',
score: 26,
},
]);
Expand Down
68 changes: 10 additions & 58 deletions packages/clay-multi-select/demos/a11y.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,8 @@ <h2>Default State</h2>

<div class="row row-spacing">
<div class="col">
<h2>With autocomplete</h2>
<div id="autocomplete-block"></div>
</div>
</div>

<div class="row row-spacing">
<div class="col">
<h2>With autocomplete and interaction</h2>
<div id="interaction-block"></div>
<h2>With disabled autocomplete</h2>
<div id="disabled-autocomplete-block"></div>
</div>
</div>

Expand Down Expand Up @@ -89,73 +82,32 @@ <h2>With only data remote</h2>

// Default State
new metal.ClayMultiSelect({
data: dataSource,
dataSource,
helpText: 'You can use a comma to enter tags',
label: 'Tags',
selectedItems,
spritemap,
}, '#default-block');

// With autocomplete
// With disabled autocomplete
new metal.ClayMultiSelect({
data: dataSource,
dataSource: [],
enableAutocomplete: false,
helpText: 'You can use a comma to enter tags',
label: 'Tags',
selectedItems,
spritemap,
}, '#autocomplete-block');

// With autocomplete and interaction
new metal.ClayMultiSelect({
data: dataSource,
label: 'Tags',
selectedItems,
spritemap,
events: {
itemAdded: (event) => {
event.target.selectedItems.push({label: event.data.label, value: event.data.label});
addToSelectedItems(event);
},
itemRemoved: removeItem,
itemSelected: (event) => {
const label = event.data.originalString.toLowerCase();
if (event.target.selectedItems.find(item => item.value === label)) return;
event.target.selectedItems.push({label, value: label});
addToSelectedItems(event);
},
},
helpText: 'You can use a comma to enter tags',
}, '#interaction-block');
}, '#disabled-autocomplete-block');

// With only data remote
new metal.ClayMultiSelect({
data: 'https://api.pro.coinbase.com/currencies',
events: {
itemRemoved: removeItem,
itemSelected: (event) => {
const label = event.data.originalString.toLowerCase();
if (event.target.selectedItems.find(item => item.value === label)) return;
event.target.selectedItems.push({label, value: label});
addToSelectedItems(event);
},
},
extractData: (elem) => elem.name,
dataSource: 'https://api.pro.coinbase.com/currencies',
helpText: 'You can use a comma to enter tags',
label: 'Currencies',
labelLocator: 'name',
spritemap,
valueLocator: 'id',
}, '#selected-block');

function addToSelectedItems(event) {
event.target.selectedItems = event.target.selectedItems;
event.target.clearInput();
event.target.filteredItems = [];
}

function removeItem(event) {
event.target.selectedItems.splice(event.data.index, 1);
event.target.selectedItems = event.target.selectedItems;
}

</script>
</body>
</html>
64 changes: 8 additions & 56 deletions packages/clay-multi-select/demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,8 @@ <h2>Default State</h2>

<div class="row row-spacing">
<div class="col">
<h2>With autocomplete</h2>
<div id="autocomplete-block"></div>
</div>
</div>

<div class="row row-spacing">
<div class="col">
<h2>With autocomplete and interaction</h2>
<div id="interaction-block"></div>
<h2>With disabled autocomplete</h2>
<div id="disabled-autocomplete-block"></div>
</div>
</div>

Expand Down Expand Up @@ -96,66 +89,25 @@ <h2>With only data remote</h2>
spritemap,
}, '#default-block');

// With autocomplete
// With disabled autocomplete
new metal.ClayMultiSelect({
dataSource,
dataSource: [],
enableAutocomplete: false,
helpText: 'You can use a comma to enter tags',
label: 'Tags',
selectedItems,
spritemap,
}, '#autocomplete-block');

// With autocomplete and interaction
new metal.ClayMultiSelect({
dataSource,
label: 'Tags',
selectedItems,
spritemap,
events: {
itemAdded: (event) => {
event.target.selectedItems.push({label: event.data.label, value: event.data.label});
addToSelectedItems(event);
},
itemRemoved: removeItem,
itemSelected: (event) => {
const label = event.data.originalString.toLowerCase();
if (event.target.selectedItems.find(item => item.value === label)) return;
event.target.selectedItems.push({label, value: label});
addToSelectedItems(event);
},
},
helpText: 'You can use a comma to enter tags',
}, '#interaction-block');
}, '#disabled-autocomplete-block');

// With only data remote
new metal.ClayMultiSelect({
dataSource: 'https://api.pro.coinbase.com/currencies',
events: {
itemRemoved: removeItem,
itemSelected: (event) => {
const label = event.data.originalString.toLowerCase();
if (event.target.selectedItems.find(item => item.value === label)) return;
event.target.selectedItems.push({label, value: label});
addToSelectedItems(event);
},
},
extractData: (elem) => elem.name,
helpText: 'You can use a comma to enter tags',
label: 'Currencies',
labelLocator: 'name',
spritemap,
valueLocator: 'id',
}, '#selected-block');

function addToSelectedItems(event) {
event.target.selectedItems = event.target.selectedItems;
event.target.inputValue = '';
event.target.filteredItems = [];
}

function removeItem(event) {
event.target.selectedItems.splice(event.data.index, 1);
event.target.selectedItems = event.target.selectedItems;
}

</script>
</body>
</html>
Loading

0 comments on commit 9e9e529

Please sign in to comment.