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 instance = null
|
||||||
let checkbox = null
|
let checkbox = null
|
||||||
let context = null
|
let context = _bb.getContext("BBMD:input:context")
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
context = _bb.getContext("BBMD:input:context")
|
|
||||||
|
|
||||||
if (!!checkbox) {
|
if (!!checkbox) {
|
||||||
instance = new MDCCheckbox(checkbox)
|
instance = new MDCCheckbox(checkbox)
|
||||||
instance.indeterminate = indeterminate
|
instance.indeterminate = indeterminate
|
||||||
if (context !== "list-item") {
|
if (context !== "list-item") {
|
||||||
//TODO: Fix this connected to Formfield context issue
|
//TODO: Fix this connected to Formfield context issue
|
||||||
// let fieldStore = _bb.getContext("BBMD:field-element")
|
let fieldStore = _bb.getContext("BBMD:field-element")
|
||||||
// fieldStore.setInput(instance)
|
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>
|
<script>
|
||||||
import { onMount, getContext } from "svelte"
|
import { onMount, getContext, setContext } from "svelte"
|
||||||
import { MDCList } from "@material/list"
|
import { MDCList } from "@material/list"
|
||||||
|
import createItemsStore from "../Common/ItemStore.js"
|
||||||
import { MDCRipple } from "@material/ripple"
|
import { MDCRipple } from "@material/ripple"
|
||||||
import ListItem from "./ListItem.svelte"
|
import ListItem from "./ListItem.svelte"
|
||||||
import ClassBuilder from "../ClassBuilder.js"
|
import ClassBuilder from "../ClassBuilder.js"
|
||||||
|
|
||||||
|
let selectedItems
|
||||||
|
|
||||||
export let _bb
|
export let _bb
|
||||||
const cb = new ClassBuilder("list", ["one-line"])
|
const cb = new ClassBuilder("list", ["one-line"])
|
||||||
|
|
||||||
|
@ -17,34 +20,32 @@
|
||||||
export let variant = "two-line"
|
export let variant = "two-line"
|
||||||
export let inputElement = null
|
export let inputElement = null
|
||||||
|
|
||||||
let selectedItems = []
|
let selectedItemsStore
|
||||||
|
|
||||||
//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 role = "listbox"
|
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(() => {
|
onMount(() => {
|
||||||
_bb.setContext("BBMD:list:props", { inputElement, variant })
|
createOrAcceptItemStore()
|
||||||
|
|
||||||
|
_bb.setContext("BBMD:list:props", {
|
||||||
|
inputElement,
|
||||||
|
variant,
|
||||||
|
singleSelection,
|
||||||
|
})
|
||||||
if (!!list) {
|
if (!!list) {
|
||||||
|
if (!inputElement) {
|
||||||
instance = new MDCList(list)
|
instance = new MDCList(list)
|
||||||
instance.singleSelection = singleSelection
|
instance.singleSelection = singleSelection
|
||||||
if (!inputElement) {
|
|
||||||
instance.listElements.map(element => new MDCRipple(element))
|
instance.listElements.map(element => new MDCRipple(element))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { onMount, getContext } from "svelte"
|
||||||
import { Radiobutton } from "../Radiobutton"
|
import { Radiobutton } from "../Radiobutton"
|
||||||
import { Checkbox } from "../Checkbox"
|
import { Checkbox } from "../Checkbox"
|
||||||
import ClassBuilder from "../ClassBuilder.js"
|
import ClassBuilder from "../ClassBuilder.js"
|
||||||
|
@ -12,6 +12,8 @@
|
||||||
let _id
|
let _id
|
||||||
let listProps = null
|
let listProps = null
|
||||||
|
|
||||||
|
let selectedItems
|
||||||
|
|
||||||
export let _bb
|
export let _bb
|
||||||
|
|
||||||
export let value = null
|
export let value = null
|
||||||
|
@ -25,24 +27,11 @@
|
||||||
|
|
||||||
let role = "option"
|
let role = "option"
|
||||||
|
|
||||||
function handleClick() {
|
|
||||||
if (!disabled) {
|
|
||||||
const selectItem = _bb.getContext("BBMD:list:selectItem")
|
|
||||||
selected = !selected
|
|
||||||
selectItem({
|
|
||||||
_id,
|
|
||||||
value,
|
|
||||||
text,
|
|
||||||
secondaryText,
|
|
||||||
selected,
|
|
||||||
disabled,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
_id = shortid.generate()
|
_id = shortid.generate()
|
||||||
|
|
||||||
|
selectedItems = _bb.getContext("BBMD:list:selectItemStore")
|
||||||
|
|
||||||
listProps = _bb.getContext("BBMD:list:props")
|
listProps = _bb.getContext("BBMD:list:props")
|
||||||
|
|
||||||
let context = _bb.getContext("BBMD:list:context")
|
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) {
|
$: if (listProps && !!listProps.inputElement) {
|
||||||
_bb.setContext("BBMD:input:context", "list-item")
|
_bb.setContext("BBMD:input:context", "list-item")
|
||||||
}
|
}
|
||||||
|
|
||||||
$: shouldSel = selected && !listProps
|
$: isSelected =
|
||||||
$: console.log("Should Select", selected)
|
$selectedItems && selectedItems.getItemIdx($selectedItems, _id) > -1
|
||||||
|
|
||||||
$: modifiers = {
|
$: modifiers = {
|
||||||
selected: selected && (!listProps || !listProps.inputElement),
|
selected: isSelected && (!listProps || !listProps.inputElement),
|
||||||
disabled,
|
disabled,
|
||||||
}
|
}
|
||||||
$: props = { modifiers }
|
$: props = { modifiers }
|
||||||
|
@ -84,9 +99,9 @@
|
||||||
|
|
||||||
{#if listProps}
|
{#if listProps}
|
||||||
{#if listProps.inputElement === 'radiobutton'}
|
{#if listProps.inputElement === 'radiobutton'}
|
||||||
<Radiobutton checked={selected} {disabled} {_bb} />
|
<Radiobutton checked={isSelected} {disabled} {_bb} />
|
||||||
{:else if listProps.inputElement === 'checkbox'}
|
{:else if listProps.inputElement === 'checkbox'}
|
||||||
<Checkbox checked={selected} {disabled} {_bb} />
|
<Checkbox checked={isSelected} {disabled} {_bb} />
|
||||||
{/if}
|
{/if}
|
||||||
{:else if trailingIcon}
|
{:else if trailingIcon}
|
||||||
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient -->
|
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient -->
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
if (!!radiobtn) {
|
if (!!radiobtn) {
|
||||||
instance = new MDCRadio(radiobtn)
|
instance = new MDCRadio(radiobtn)
|
||||||
if (context !== "list-item") {
|
if (context !== "list-item") {
|
||||||
//TODO: Fix this connected to Formfield context issue, _bb not binding properly
|
let fieldStore = _bb.getContext("BBMD:field-element")
|
||||||
// let fieldStore = _bb.getContext("BBMD:field-element")
|
fieldStore.setInput(instance)
|
||||||
// fieldStore.setInput(instance)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -118,8 +118,7 @@ export const props = {
|
||||||
List: {
|
List: {
|
||||||
_component: "@budibase/materialdesign-components/List",
|
_component: "@budibase/materialdesign-components/List",
|
||||||
variant: "two-line",
|
variant: "two-line",
|
||||||
inputElement: "radiobutton",
|
singleSelection: false,
|
||||||
singleSelection: true,
|
|
||||||
onSelect: selected => console.log(selected),
|
onSelect: selected => console.log(selected),
|
||||||
_children: [
|
_children: [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue