Testing list items by passing down a event handler through context for selecting items

This commit is contained in:
Conor Mack 2020-02-27 10:03:49 +00:00
parent 62e562c1f1
commit d88d377f5f
7 changed files with 92 additions and 70 deletions

View File

@ -1,5 +1,5 @@
<script> <script>
import { onMount, onDestroy, getContext } from "svelte" import { onMount, onDestroy } from "svelte"
import Formfield from "../Common/Formfield.svelte" import Formfield from "../Common/Formfield.svelte"
import { fieldStore } from "../Common/FormfieldStore.js" import { fieldStore } from "../Common/FormfieldStore.js"
import ClassBuilder from "../ClassBuilder.js" import ClassBuilder from "../ClassBuilder.js"
@ -7,6 +7,8 @@
export let onClick = item => {} export let onClick = item => {}
export let _bb
export let id = "" export let id = ""
export let label = "" export let label = ""
export let disabled = false export let disabled = false
@ -16,16 +18,18 @@
let instance = null let instance = null
let checkbox = null let checkbox = null
let context = null
let context = 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") {
let fieldStore = getContext("BBMD:field-element") //TODO: Fix this connected to Formfield context issue
fieldStore.setInput(instance) // let fieldStore = _bb.getContext("BBMD:field-element")
// fieldStore.setInput(instance)
} }
} }
}) })

View File

@ -3,13 +3,14 @@
import ClassBuilder from "../ClassBuilder.js" import ClassBuilder from "../ClassBuilder.js"
import { fieldStore } from "./FormfieldStore.js" import { fieldStore } from "./FormfieldStore.js"
import { MDCFormField } from "@material/form-field" import { MDCFormField } from "@material/form-field"
import { onMount, onDestroy, setContext } from "svelte" import { onMount, onDestroy } from "svelte"
const cb = new ClassBuilder("form-field") const cb = new ClassBuilder("form-field")
let store let store
const unsubscribe = fieldStore.subscribe(s => (store = s)) const unsubscribe = fieldStore.subscribe(s => (store = s))
export let _bb
export let id = "" export let id = ""
export let label = "" export let label = ""
export let alignEnd = false export let alignEnd = false
@ -23,7 +24,8 @@
onMount(() => { onMount(() => {
if (!!formField) fieldStore.set(new MDCFormField(formField)) if (!!formField) fieldStore.set(new MDCFormField(formField))
setContext("BBMD:field-element", fieldStore) //TODO: Fix this, _bb is coming back undefined
// _bb.setContext("BBMD:field-element", fieldStore)
}) })
onDestroy(unsubscribe) onDestroy(unsubscribe)

View File

@ -13,19 +13,40 @@
export let onSelect = selectedItems => {} export let onSelect = selectedItems => {}
export let variant = "one-line"
//items: [{text: string | {primary: string, secondary: string}, value: any, selected: bool}...n]
export let items = []
export let singleSelection = false export let singleSelection = false
export let variant = "two-line"
export let inputElement = null 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 role = "listbox" let role = "listbox"
onMount(() => { onMount(() => {
_bb.setContext("BBMD:list:props", { inputElement, variant })
if (!!list) { if (!!list) {
instance = new MDCList(list) instance = new MDCList(list)
instance.singleSelection = singleSelection instance.singleSelection = singleSelection
instance.listElements.map(element => new MDCRipple(element)) if (!inputElement) {
instance.listElements.map(element => new MDCRipple(element))
}
} }
let context = getContext("BBMD:list:context") let context = getContext("BBMD:list:context")
@ -39,28 +60,6 @@
} }
}) })
function handleSelectedItem(item) {
if (!item.disabled) {
if (singleSelection || inputElement === "radiobutton") {
items.forEach(i => {
if (i.selected) i.selected = false
})
}
let idx = items.indexOf(item)
if (!!item.selected) {
items[idx].selected = !item.selected
} else {
items[idx].selected = true
}
onSelect(items.filter(item => item.selected))
}
}
$: useDoubleLine =
variant == "two-line" &&
items.every(i => typeof i.text == "object" && "primary" in i.text)
$: list && _bb.attachChildren(list) $: list && _bb.attachChildren(list)
$: modifiers = { variant } $: modifiers = { variant }

View File

@ -1,17 +1,23 @@
<script> <script>
import { onMount, getContext } from "svelte" import { onMount } 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"
import shortid from "shortid"
const cb = new ClassBuilder("list-item") const cb = new ClassBuilder("list-item")
export let onClick = item => {} export let onClick = item => {}
let _id
let listProps = null
export let _bb
export let value = null
export let text = "" export let text = ""
export let secondaryText = "" export let secondaryText = ""
export let variant = "two-line"
export let inputElement = null
export let leadingIcon = "" export let leadingIcon = ""
export let trailingIcon = "" export let trailingIcon = ""
export let selected = false export let selected = false
@ -19,33 +25,51 @@
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(() => {
let context = getContext("BBMD:list:context") _id = shortid.generate()
listProps = _bb.getContext("BBMD:list:props")
let context = _bb.getContext("BBMD:list:context")
if (context === "menu") { if (context === "menu") {
role = "menuitem" role = "menuitem"
} }
}) })
$: if (!!inputElement) { $: if (listProps && !!listProps.inputElement) {
setContext("BBMD:input:context", "list-item") _bb.setContext("BBMD:input:context", "list-item")
} }
$: shouldSel = selected && !listProps
$: console.log("Should Select", selected)
$: modifiers = { $: modifiers = {
selected, selected: selected && (!listProps || !listProps.inputElement),
disabled, disabled,
} }
$: props = { modifiers } $: props = { modifiers }
$: listItemClass = cb.build({ props }) $: listItemClass = cb.build({ props })
$: useTwoLine = variant === "two-line" && !!secondaryText $: useTwoLine =
listProps && listProps.variant === "two-line" && !!secondaryText
</script> </script>
<li <li class={listItemClass} role="option" tabindex="0" on:click={handleClick}>
class={listItemClass}
role="option"
aria-selected={selected}
tabindex="0"
on:click={onClick}>
{#if leadingIcon} {#if leadingIcon}
<span class="mdc-list-item__graphic material-icons" aria-hidden="true"> <span class="mdc-list-item__graphic material-icons" aria-hidden="true">
{leadingIcon} {leadingIcon}
@ -58,11 +82,11 @@
{:else}{text}{/if} {:else}{text}{/if}
</span> </span>
{#if inputElement} {#if listProps}
{#if inputElement === 'radiobutton'} {#if listProps.inputElement === 'radiobutton'}
<Radiobutton checked={selected} {disabled} /> <Radiobutton checked={selected} {disabled} {_bb} />
{:else if inputElement === 'checkbox'} {:else if listProps.inputElement === 'checkbox'}
<Checkbox checked={selected} {disabled} /> <Checkbox checked={selected} {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 -->

View File

@ -1,10 +1,11 @@
<script> <script>
import { onMount, onDestroy, getContext } from "svelte" import { onMount, onDestroy } from "svelte"
import Formfield from "../Common/Formfield.svelte" import Formfield from "../Common/Formfield.svelte"
import ClassBuilder from "../ClassBuilder.js" import ClassBuilder from "../ClassBuilder.js"
import { MDCRadio } from "@material/radio" import { MDCRadio } from "@material/radio"
export let onClick = item => {} export let onClick = item => {}
export let _bb
export let id = "" export let id = ""
export let label = "" export let label = ""
@ -16,14 +17,15 @@
let instance = null let instance = null
let radiobtn = null let radiobtn = null
let context = getContext("BBMD:input:context") let context = _bb.getContext("BBMD:input:context")
onMount(() => { onMount(() => {
if (!!radiobtn) { if (!!radiobtn) {
instance = new MDCRadio(radiobtn) instance = new MDCRadio(radiobtn)
if (context !== "list-item") { if (context !== "list-item") {
let fieldStore = getContext("BBMD:field-element") //TODO: Fix this connected to Formfield context issue, _bb not binding properly
fieldStore.setInput(instance) // let fieldStore = _bb.getContext("BBMD:field-element")
// fieldStore.setInput(instance)
} }
} }
}) })

View File

@ -32,10 +32,6 @@
Button, Button,
BodyBoundToStore, BodyBoundToStore,
Textfield, Textfield,
Checkbox,
Checkboxgroup,
Radiobutton,
Radiobuttongroup,
Icon, Icon,
Datatable, Datatable,
CustomersIndexTable, CustomersIndexTable,

View File

@ -117,12 +117,14 @@ export const props = {
CustomersIndexTable: indexDatatable(templateOptions)[0].props, CustomersIndexTable: indexDatatable(templateOptions)[0].props,
List: { List: {
_component: "@budibase/materialdesign-components/List", _component: "@budibase/materialdesign-components/List",
variant: "two-line",
inputElement: "radiobutton",
singleSelection: true,
onSelect: selected => console.log(selected),
_children: [ _children: [
{ {
_component: "@budibase/materialdesign-components/ListItem", _component: "@budibase/materialdesign-components/ListItem",
_children: [], _children: [],
variant: "two-line",
singleSelection: true,
text: "Curry", text: "Curry",
secondaryText: "Chicken or Beef", secondaryText: "Chicken or Beef",
value: 0, value: 0,
@ -131,8 +133,6 @@ export const props = {
{ {
_component: "@budibase/materialdesign-components/ListItem", _component: "@budibase/materialdesign-components/ListItem",
_children: [], _children: [],
variant: "two-line",
singleSelection: true,
text: "Pastie", text: "Pastie",
secondaryText: "Bap with Mayo", secondaryText: "Bap with Mayo",
value: 1, value: 1,
@ -141,15 +141,10 @@ export const props = {
{ {
_component: "@budibase/materialdesign-components/ListItem", _component: "@budibase/materialdesign-components/ListItem",
_children: [], _children: [],
variant: "two-line",
singleSelection: true,
text: "Fish", text: "Fish",
secondaryText: "Salmon or Cod", secondaryText: "Salmon or Cod",
value: 2, value: 2,
}, },
], ]
variant: "two-line",
singleSelection: true,
onSelect: selected => console.log(selected),
}, },
} }