Browse Source

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

gh-pages
Conor Mack 7 years ago
parent
commit
fa199bdacf
  1. 8
      packages/materialdesign-components/src/Checkbox/Checkbox.svelte
  2. 54
      packages/materialdesign-components/src/Common/ItemStore.js
  3. 43
      packages/materialdesign-components/src/List/List.svelte
  4. 57
      packages/materialdesign-components/src/List/ListItem.svelte
  5. 5
      packages/materialdesign-components/src/Radiobutton/Radiobutton.svelte
  6. 3
      packages/materialdesign-components/src/Test/props.js

8
packages/materialdesign-components/src/Checkbox/Checkbox.svelte

@ -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)
}
}
})

54
packages/materialdesign-components/src/Common/ItemStore.js

@ -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

43
packages/materialdesign-components/src/List/List.svelte

@ -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 = []
let selectedItemsStore
let role = "listbox"
//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
function createOrAcceptItemStore() {
let store = _bb.getContext("BBMD:list:selectItemStore")
if (!!store) {
selectedItemsStore = store
} else {
if (singleSelection) {
selectedItems = [item]
} else {
selectedItems = [...selectedItems, item]
}
selectedItemsStore = createItemsStore(() => onSelect($selectedItemsStore))
_bb.setContext("BBMD:list:selectItemStore", selectedItemsStore)
}
}
//See todo above
_bb.setContext("BBMD:list:selectItem", handleSelected)
let role = "listbox"
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))
}
}

57
packages/materialdesign-components/src/List/ListItem.svelte

@ -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 -->

5
packages/materialdesign-components/src/Radiobutton/Radiobutton.svelte

@ -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)
}
}
})

3
packages/materialdesign-components/src/Test/props.js

@ -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…
Cancel
Save