Updated way of handling selected items by using writable store and context
This commit is contained in:
parent
d88d377f5f
commit
fa199bdacf
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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: [
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue