Merge pull request #129 from Conor-Mack/feature/md-list-children

Changing list to use Children for items
This commit is contained in:
Conor_Mack 2020-02-25 14:57:42 +00:00 committed by GitHub
commit 2a06c70900
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 89 deletions

View File

@ -1,79 +1,71 @@
<script> <script>
import { onMount, getContext } from "svelte"; import { onMount, getContext } from "svelte"
import { MDCList } from "@material/list"; import { MDCList } from "@material/list"
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"
const cb = new ClassBuilder("list", ["one-line"]); export let _bb
const cb = new ClassBuilder("list", ["one-line"])
let list = null; let list = null
let instance = null; let instance = null
export let onSelect = selectedItems => {}; export let onSelect = selectedItems => {}
export let variant = "one-line"; export let variant = "one-line"
//items: [{text: string | {primary: string, secondary: string}, value: any, selected: bool}...n] //items: [{text: string | {primary: string, secondary: string}, value: any, selected: bool}...n]
export let items = []; export let items = []
export let singleSelection = false; export let singleSelection = false
export let inputElement = null; export let inputElement = null
let role = "listbox"; let role = "listbox"
onMount(() => { onMount(() => {
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)); instance.listElements.map(element => new MDCRipple(element))
} }
let context = getContext("BBMD:list:context"); let context = getContext("BBMD:list:context")
if (context === "menu") { if (context === "menu") {
role = "menu"; role = "menu"
} }
return () => { return () => {
instance && instance.destroy(); instance && instance.destroy()
instance = null; instance = null
}; }
}); })
function handleSelectedItem(item) { function handleSelectedItem(item) {
if (!item.disabled) { if (!item.disabled) {
if (singleSelection || inputElement === "radiobutton") { if (singleSelection || inputElement === "radiobutton") {
items.forEach(i => { items.forEach(i => {
if (i.selected) i.selected = false; if (i.selected) i.selected = false
}); })
} }
let idx = items.indexOf(item); let idx = items.indexOf(item)
if (!!item.selected) { if (!!item.selected) {
items[idx].selected = !item.selected; items[idx].selected = !item.selected
} else { } else {
items[idx].selected = true; items[idx].selected = true
} }
onSelect(items.filter(item => item.selected)); onSelect(items.filter(item => item.selected))
} }
} }
$: useDoubleLine = $: useDoubleLine =
variant == "two-line" && variant == "two-line" &&
items.every(i => typeof i.text == "object" && "primary" in i.text); items.every(i => typeof i.text == "object" && "primary" in i.text)
$: modifiers = { variant }; $: list && _bb.attachChildren(list)
$: props = { modifiers };
$: listClass = cb.build({ props }); $: modifiers = { variant }
$: props = { modifiers }
$: listClass = cb.build({ props })
</script> </script>
<ul class={listClass} {role}> <ul bind:this={list} class={listClass} {role} />
{#each items as item, i}
<ListItem
{item}
{useDoubleLine}
{inputElement}
onClick={() => handleSelectedItem(item)} />
{#if item.divider}
<li role="separator" class="mdc-list-divider" />
{/if}
{/each}
</ul>

View File

@ -1,71 +1,73 @@
<script> <script>
import { onMount, getContext } 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"
const cb = new ClassBuilder("list-item"); const cb = new ClassBuilder("list-item")
export let onClick = item => {}; export let onClick = item => {}
export let item = null; export let text = ""
export let useDoubleLine = false; export let secondaryText = ""
export let inputElement = null; //radiobutton or checkbox export let variant = "two-line"
export let inputElement = null
export let leadingIcon = ""
export let trailingIcon = ""
export let selected = false
export let disabled = false
let role = "option"; let role = "option"
onMount(() => { onMount(() => {
let context = getContext("BBMD:list:context"); let context = getContext("BBMD:list:context")
if (context === "menu") { if (context === "menu") {
role = "menuitem"; role = "menuitem"
} }
}); })
$: if (!!inputElement) { $: if (!!inputElement) {
setContext("BBMD:input:context", "list-item"); setContext("BBMD:input:context", "list-item")
} }
$: modifiers = { $: modifiers = {
selected: !inputElement ? item.selected : null, selected,
disabled: item.disabled disabled,
}; }
$: props = { modifiers }; $: props = { modifiers }
$: listItemClass = cb.build({ props }); $: listItemClass = cb.build({ props })
$: useSecondaryText = $: useTwoLine = variant === "two-line" && !!secondaryText
typeof item.text === "object" && "secondary" in item.text;
</script> </script>
<li <li
class={listItemClass} class={listItemClass}
role="option" role="option"
aria-selected={item.selected} aria-selected={selected}
tabindex="0" tabindex="0"
on:click={onClick}> on:click={onClick}>
{#if item.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">
{item.leadingIcon} {leadingIcon}
</span> </span>
{/if} {/if}
<span class={cb.elem`text`}> <span class={cb.elem`text`}>
{#if useDoubleLine} {#if useTwoLine}
<span class={cb.elem`primary-text`}>{item.text.primary}</span> <span class={cb.elem`primary-text`}>{text}</span>
{#if useSecondaryText} <span class={cb.elem`secondary-text`}>{secondaryText}</span>
<span class={cb.elem`secondary-text`}>{item.text.secondary}</span> {:else}{text}{/if}
{/if}
{:else}{item.text}{/if}
</span> </span>
{#if inputElement} {#if inputElement}
{#if inputElement === 'radiobutton'} {#if inputElement === 'radiobutton'}
<Radiobutton checked={item.selected} disabled={item.disabled} /> <Radiobutton checked={selected} {disabled} />
{:else if inputElement === 'checkbox'} {:else if inputElement === 'checkbox'}
<Checkbox checked={item.selected} disabled={item.disabled} /> <Checkbox checked={selected} {disabled} />
{/if} {/if}
{:else if item.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 -->
<span class="mdc-list-item__meta material-icons" aria-hidden="true"> <span class="mdc-list-item__meta material-icons" aria-hidden="true">
{item.trailingIcon} {trailingIcon}
</span> </span>
{/if} {/if}
</li> </li>

View File

@ -1,2 +1,3 @@
import "./_style.scss"; import "./_style.scss"
export { default as List } from "./List.svelte"; export { default as List } from "./List.svelte"
export { default as ListItem } from "./ListItem.svelte"

View File

@ -15,6 +15,7 @@
Datatable, Datatable,
CustomersIndexTable, CustomersIndexTable,
List, List,
Icon,
} = props } = props
let currentComponent let currentComponent
@ -35,6 +36,7 @@
Checkboxgroup, Checkboxgroup,
Radiobutton, Radiobutton,
Radiobuttongroup, Radiobuttongroup,
Icon,
Datatable, Datatable,
CustomersIndexTable, CustomersIndexTable,
List, List,

View File

@ -117,22 +117,39 @@ 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",
_children: [], _children: [
variant: "two-line",
singleSelection: true,
items: [
{ {
text: { primary: "Curry", secondary: "Chicken or Beef" }, _component: "@budibase/materialdesign-components/ListItem",
_children: [],
variant: "two-line",
singleSelection: true,
text: "Curry",
secondaryText: "Chicken or Beef",
value: 0, value: 0,
divider: true, divider: true,
}, },
{ {
text: { primary: "Pastie", secondary: "Bap with Mayo" }, _component: "@budibase/materialdesign-components/ListItem",
_children: [],
variant: "two-line",
singleSelection: true,
text: "Pastie",
secondaryText: "Bap with Mayo",
value: 1, value: 1,
disabled: true, disabled: true,
}, },
{ text: { primary: "Fish", secondary: "Salmon or Cod" }, value: 2 }, {
_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), onSelect: selected => console.log(selected),
}, },
} }

View File

@ -16,4 +16,4 @@ export {
} from "./Datatable" } from "./Datatable"
export { default as indexDatatable } from "./Templates/indexDatatable" export { default as indexDatatable } from "./Templates/indexDatatable"
export { default as recordForm } from "./Templates/recordForm" export { default as recordForm } from "./Templates/recordForm"
export { List } from "./List" export { List, ListItem } from "./List"