Testing list items by passing down a event handler through context for selecting items
This commit is contained in:
parent
e862675956
commit
47c34e2395
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { onMount, onDestroy, getContext } from "svelte"
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import Formfield from "../Common/Formfield.svelte"
|
||||
import { fieldStore } from "../Common/FormfieldStore.js"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
|
@ -7,6 +7,8 @@
|
|||
|
||||
export let onClick = item => {}
|
||||
|
||||
export let _bb
|
||||
|
||||
export let id = ""
|
||||
export let label = ""
|
||||
export let disabled = false
|
||||
|
@ -16,16 +18,18 @@
|
|||
|
||||
let instance = null
|
||||
let checkbox = null
|
||||
|
||||
let context = getContext("BBMD:input:context")
|
||||
let context = null
|
||||
|
||||
onMount(() => {
|
||||
context = _bb.getContext("BBMD:input:context")
|
||||
|
||||
if (!!checkbox) {
|
||||
instance = new MDCCheckbox(checkbox)
|
||||
instance.indeterminate = indeterminate
|
||||
if (context !== "list-item") {
|
||||
let fieldStore = getContext("BBMD:field-element")
|
||||
fieldStore.setInput(instance)
|
||||
//TODO: Fix this connected to Formfield context issue
|
||||
// let fieldStore = _bb.getContext("BBMD:field-element")
|
||||
// fieldStore.setInput(instance)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
import ClassBuilder from "../ClassBuilder.js"
|
||||
import { fieldStore } from "./FormfieldStore.js"
|
||||
import { MDCFormField } from "@material/form-field"
|
||||
import { onMount, onDestroy, setContext } from "svelte"
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
|
||||
const cb = new ClassBuilder("form-field")
|
||||
|
||||
let store
|
||||
const unsubscribe = fieldStore.subscribe(s => (store = s))
|
||||
|
||||
export let _bb
|
||||
export let id = ""
|
||||
export let label = ""
|
||||
export let alignEnd = false
|
||||
|
@ -23,7 +24,8 @@
|
|||
|
||||
onMount(() => {
|
||||
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)
|
||||
|
|
|
@ -13,20 +13,41 @@
|
|||
|
||||
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 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 role = "listbox"
|
||||
|
||||
onMount(() => {
|
||||
_bb.setContext("BBMD:list:props", { inputElement, variant })
|
||||
if (!!list) {
|
||||
instance = new MDCList(list)
|
||||
instance.singleSelection = singleSelection
|
||||
if (!inputElement) {
|
||||
instance.listElements.map(element => new MDCRipple(element))
|
||||
}
|
||||
}
|
||||
|
||||
let context = getContext("BBMD:list:context")
|
||||
if (context === "menu") {
|
||||
|
@ -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)
|
||||
|
||||
$: modifiers = { variant }
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
<script>
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { onMount } from "svelte"
|
||||
import { Radiobutton } from "../Radiobutton"
|
||||
import { Checkbox } from "../Checkbox"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
import shortid from "shortid"
|
||||
|
||||
const cb = new ClassBuilder("list-item")
|
||||
|
||||
export let onClick = item => {}
|
||||
|
||||
let _id
|
||||
let listProps = null
|
||||
|
||||
export let _bb
|
||||
|
||||
export let value = null
|
||||
export let text = ""
|
||||
export let secondaryText = ""
|
||||
export let variant = "two-line"
|
||||
export let inputElement = null
|
||||
|
||||
export let leadingIcon = ""
|
||||
export let trailingIcon = ""
|
||||
export let selected = false
|
||||
|
@ -19,33 +25,51 @@
|
|||
|
||||
let role = "option"
|
||||
|
||||
function handleClick() {
|
||||
if (!disabled) {
|
||||
const selectItem = _bb.getContext("BBMD:list:selectItem")
|
||||
selected = !selected
|
||||
selectItem({
|
||||
_id,
|
||||
value,
|
||||
text,
|
||||
secondaryText,
|
||||
selected,
|
||||
disabled,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
role = "menuitem"
|
||||
}
|
||||
})
|
||||
|
||||
$: if (!!inputElement) {
|
||||
setContext("BBMD:input:context", "list-item")
|
||||
$: if (listProps && !!listProps.inputElement) {
|
||||
_bb.setContext("BBMD:input:context", "list-item")
|
||||
}
|
||||
|
||||
$: shouldSel = selected && !listProps
|
||||
$: console.log("Should Select", selected)
|
||||
|
||||
$: modifiers = {
|
||||
selected,
|
||||
selected: selected && (!listProps || !listProps.inputElement),
|
||||
disabled,
|
||||
}
|
||||
$: props = { modifiers }
|
||||
$: listItemClass = cb.build({ props })
|
||||
|
||||
$: useTwoLine = variant === "two-line" && !!secondaryText
|
||||
$: useTwoLine =
|
||||
listProps && listProps.variant === "two-line" && !!secondaryText
|
||||
</script>
|
||||
|
||||
<li
|
||||
class={listItemClass}
|
||||
role="option"
|
||||
aria-selected={selected}
|
||||
tabindex="0"
|
||||
on:click={onClick}>
|
||||
<li class={listItemClass} role="option" tabindex="0" on:click={handleClick}>
|
||||
{#if leadingIcon}
|
||||
<span class="mdc-list-item__graphic material-icons" aria-hidden="true">
|
||||
{leadingIcon}
|
||||
|
@ -58,11 +82,11 @@
|
|||
{:else}{text}{/if}
|
||||
</span>
|
||||
|
||||
{#if inputElement}
|
||||
{#if inputElement === 'radiobutton'}
|
||||
<Radiobutton checked={selected} {disabled} />
|
||||
{:else if inputElement === 'checkbox'}
|
||||
<Checkbox checked={selected} {disabled} />
|
||||
{#if listProps}
|
||||
{#if listProps.inputElement === 'radiobutton'}
|
||||
<Radiobutton checked={selected} {disabled} {_bb} />
|
||||
{:else if listProps.inputElement === 'checkbox'}
|
||||
<Checkbox checked={selected} {disabled} {_bb} />
|
||||
{/if}
|
||||
{:else if trailingIcon}
|
||||
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient -->
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<script>
|
||||
import { onMount, onDestroy, getContext } from "svelte"
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import Formfield from "../Common/Formfield.svelte"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
import { MDCRadio } from "@material/radio"
|
||||
|
||||
export let onClick = item => {}
|
||||
export let _bb
|
||||
|
||||
export let id = ""
|
||||
export let label = ""
|
||||
|
@ -16,14 +17,15 @@
|
|||
let instance = null
|
||||
let radiobtn = null
|
||||
|
||||
let context = getContext("BBMD:input:context")
|
||||
let context = _bb.getContext("BBMD:input:context")
|
||||
|
||||
onMount(() => {
|
||||
if (!!radiobtn) {
|
||||
instance = new MDCRadio(radiobtn)
|
||||
if (context !== "list-item") {
|
||||
let fieldStore = getContext("BBMD:field-element")
|
||||
fieldStore.setInput(instance)
|
||||
//TODO: Fix this connected to Formfield context issue, _bb not binding properly
|
||||
// let fieldStore = _bb.getContext("BBMD:field-element")
|
||||
// fieldStore.setInput(instance)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -32,10 +32,6 @@
|
|||
Button,
|
||||
BodyBoundToStore,
|
||||
Textfield,
|
||||
Checkbox,
|
||||
Checkboxgroup,
|
||||
Radiobutton,
|
||||
Radiobuttongroup,
|
||||
Icon,
|
||||
Datatable,
|
||||
CustomersIndexTable,
|
||||
|
|
|
@ -117,12 +117,14 @@ export const props = {
|
|||
CustomersIndexTable: indexDatatable(templateOptions)[0].props,
|
||||
List: {
|
||||
_component: "@budibase/materialdesign-components/List",
|
||||
variant: "two-line",
|
||||
inputElement: "radiobutton",
|
||||
singleSelection: true,
|
||||
onSelect: selected => console.log(selected),
|
||||
_children: [
|
||||
{
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
text: "Curry",
|
||||
secondaryText: "Chicken or Beef",
|
||||
value: 0,
|
||||
|
@ -131,8 +133,6 @@ export const props = {
|
|||
{
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
text: "Pastie",
|
||||
secondaryText: "Bap with Mayo",
|
||||
value: 1,
|
||||
|
@ -141,15 +141,10 @@ export const props = {
|
|||
{
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
text: "Fish",
|
||||
secondaryText: "Salmon or Cod",
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
onSelect: selected => console.log(selected),
|
||||
]
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue