Updated way of handling selected items by using writable store and context

This commit is contained in:
Conor Mack 2020-02-27 15:45:28 +00:00
parent d88d377f5f
commit fa199bdacf
6 changed files with 120 additions and 54 deletions

View File

@ -18,18 +18,16 @@
let instance = null
let checkbox = null
let context = null
let context = _bb.getContext("BBMD:input:context")
onMount(() => {
context = _bb.getContext("BBMD:input:context")
if (!!checkbox) {
instance = new MDCCheckbox(checkbox)
instance.indeterminate = indeterminate
if (context !== "list-item") {
//TODO: Fix this connected to Formfield context issue
// let fieldStore = _bb.getContext("BBMD:field-element")
// fieldStore.setInput(instance)
let fieldStore = _bb.getContext("BBMD:field-element")
fieldStore.setInput(instance)
}
}
})

View File

@ -0,0 +1,54 @@
import { writable } from "svelte/store";
function createItemsStore(componentOnSelect) {
const { subscribe, set, update } = writable([]);
function addItem(item) {
update(items => {
return [...items, item]
})
if (componentOnSelect) {
componentOnSelect();
}
}
function addSingleItem(item) {
set([item])
if (componentOnSelect) {
componentOnSelect();
}
}
function removeItem(itemId) {
update(items => {
let index = getItemIdx(items, itemId)
items.splice(index, 1);
return items;
})
if (componentOnSelect) {
componentOnSelect();
}
}
function clearItems() {
set([]);
if (componentOnSelect) {
componentOnSelect();
}
}
function getItemIdx(items, itemId) {
return items.findIndex(i => i._id === itemId);
}
return {
subscribe,
addItem,
addSingleItem,
removeItem,
clearItems,
getItemIdx
}
}
export default createItemsStore

View File

@ -1,10 +1,13 @@
<script>
import { onMount, getContext } from "svelte"
import { onMount, getContext, setContext } from "svelte"
import { MDCList } from "@material/list"
import createItemsStore from "../Common/ItemStore.js"
import { MDCRipple } from "@material/ripple"
import ListItem from "./ListItem.svelte"
import ClassBuilder from "../ClassBuilder.js"
let selectedItems
export let _bb
const cb = new ClassBuilder("list", ["one-line"])
@ -17,34 +20,32 @@
export let variant = "two-line"
export let inputElement = null
let selectedItems = []
//TODO: Try managing selected list items with a store that is passed into context. This way can check within the component whether list item is selected to not selecteds instead of managing from internal state which is not feasible
function handleSelected(item) {
let idx = selectedItems.findIndex(i => i._id === item._id)
if (idx > -1) {
selectedItems.splice(idx, 1)
selectedItems = selectedItems
} else {
if (singleSelection) {
selectedItems = [item]
} else {
selectedItems = [...selectedItems, item]
}
}
}
//See todo above
_bb.setContext("BBMD:list:selectItem", handleSelected)
let selectedItemsStore
let role = "listbox"
function createOrAcceptItemStore() {
let store = _bb.getContext("BBMD:list:selectItemStore")
if (!!store) {
selectedItemsStore = store
} else {
selectedItemsStore = createItemsStore(() => onSelect($selectedItemsStore))
_bb.setContext("BBMD:list:selectItemStore", selectedItemsStore)
}
}
onMount(() => {
_bb.setContext("BBMD:list:props", { inputElement, variant })
createOrAcceptItemStore()
_bb.setContext("BBMD:list:props", {
inputElement,
variant,
singleSelection,
})
if (!!list) {
instance = new MDCList(list)
instance.singleSelection = singleSelection
if (!inputElement) {
instance = new MDCList(list)
instance.singleSelection = singleSelection
instance.listElements.map(element => new MDCRipple(element))
}
}

View File

@ -1,5 +1,5 @@
<script>
import { onMount } from "svelte"
import { onMount, getContext } from "svelte"
import { Radiobutton } from "../Radiobutton"
import { Checkbox } from "../Checkbox"
import ClassBuilder from "../ClassBuilder.js"
@ -12,6 +12,8 @@
let _id
let listProps = null
let selectedItems
export let _bb
export let value = null
@ -25,24 +27,11 @@
let role = "option"
function handleClick() {
if (!disabled) {
const selectItem = _bb.getContext("BBMD:list:selectItem")
selected = !selected
selectItem({
_id,
value,
text,
secondaryText,
selected,
disabled,
})
}
}
onMount(() => {
_id = shortid.generate()
selectedItems = _bb.getContext("BBMD:list:selectItemStore")
listProps = _bb.getContext("BBMD:list:props")
let context = _bb.getContext("BBMD:list:context")
@ -51,15 +40,41 @@
}
})
function handleClick() {
let item = {
_id,
value,
text,
secondaryText,
selected,
disabled,
}
if (!disabled) {
if (
listProps.singleSelection ||
listProps.inputElement === "radiobutton"
) {
selectedItems.addSingleItem(item)
} else {
let idx = selectedItems.getItemIdx($selectedItems, _id)
if (idx > -1) {
selectedItems.removeItem(_id)
} else {
selectedItems.addItem(item)
}
}
}
}
$: if (listProps && !!listProps.inputElement) {
_bb.setContext("BBMD:input:context", "list-item")
}
$: shouldSel = selected && !listProps
$: console.log("Should Select", selected)
$: isSelected =
$selectedItems && selectedItems.getItemIdx($selectedItems, _id) > -1
$: modifiers = {
selected: selected && (!listProps || !listProps.inputElement),
selected: isSelected && (!listProps || !listProps.inputElement),
disabled,
}
$: props = { modifiers }
@ -84,9 +99,9 @@
{#if listProps}
{#if listProps.inputElement === 'radiobutton'}
<Radiobutton checked={selected} {disabled} {_bb} />
<Radiobutton checked={isSelected} {disabled} {_bb} />
{:else if listProps.inputElement === 'checkbox'}
<Checkbox checked={selected} {disabled} {_bb} />
<Checkbox checked={isSelected} {disabled} {_bb} />
{/if}
{:else if trailingIcon}
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient -->

View File

@ -23,9 +23,8 @@
if (!!radiobtn) {
instance = new MDCRadio(radiobtn)
if (context !== "list-item") {
//TODO: Fix this connected to Formfield context issue, _bb not binding properly
// let fieldStore = _bb.getContext("BBMD:field-element")
// fieldStore.setInput(instance)
let fieldStore = _bb.getContext("BBMD:field-element")
fieldStore.setInput(instance)
}
}
})

View File

@ -118,8 +118,7 @@ export const props = {
List: {
_component: "@budibase/materialdesign-components/List",
variant: "two-line",
inputElement: "radiobutton",
singleSelection: true,
singleSelection: false,
onSelect: selected => console.log(selected),
_children: [
{