forked from tsai/budibase
committed by
GitHub
6 changed files with 103 additions and 89 deletions
@ -1,79 +1,71 @@ |
|||
<script> |
|||
import { onMount, getContext } from "svelte"; |
|||
import { MDCList } from "@material/list"; |
|||
import { MDCRipple } from "@material/ripple"; |
|||
import ListItem from "./ListItem.svelte"; |
|||
import ClassBuilder from "../ClassBuilder.js"; |
|||
import { onMount, getContext } from "svelte" |
|||
import { MDCList } from "@material/list" |
|||
import { MDCRipple } from "@material/ripple" |
|||
import ListItem from "./ListItem.svelte" |
|||
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 instance = null; |
|||
let list = 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] |
|||
export let items = []; |
|||
export let singleSelection = false; |
|||
export let inputElement = null; |
|||
export let items = [] |
|||
export let singleSelection = false |
|||
export let inputElement = null |
|||
|
|||
let role = "listbox"; |
|||
let role = "listbox" |
|||
|
|||
onMount(() => { |
|||
if (!!list) { |
|||
instance = new MDCList(list); |
|||
instance.singleSelection = singleSelection; |
|||
instance.listElements.map(element => new MDCRipple(element)); |
|||
instance = new MDCList(list) |
|||
instance.singleSelection = singleSelection |
|||
instance.listElements.map(element => new MDCRipple(element)) |
|||
} |
|||
|
|||
let context = getContext("BBMD:list:context"); |
|||
let context = getContext("BBMD:list:context") |
|||
if (context === "menu") { |
|||
role = "menu"; |
|||
role = "menu" |
|||
} |
|||
|
|||
return () => { |
|||
instance && instance.destroy(); |
|||
instance = null; |
|||
}; |
|||
}); |
|||
instance && instance.destroy() |
|||
instance = null |
|||
} |
|||
}) |
|||
|
|||
function handleSelectedItem(item) { |
|||
if (!item.disabled) { |
|||
if (singleSelection || inputElement === "radiobutton") { |
|||
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) { |
|||
items[idx].selected = !item.selected; |
|||
items[idx].selected = !item.selected |
|||
} else { |
|||
items[idx].selected = true; |
|||
items[idx].selected = true |
|||
} |
|||
onSelect(items.filter(item => item.selected)); |
|||
onSelect(items.filter(item => item.selected)) |
|||
} |
|||
} |
|||
|
|||
$: useDoubleLine = |
|||
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) |
|||
|
|||
$: list && _bb.attachChildren(list) |
|||
|
|||
$: modifiers = { variant }; |
|||
$: props = { modifiers }; |
|||
$: listClass = cb.build({ props }); |
|||
$: modifiers = { variant } |
|||
$: props = { modifiers } |
|||
$: listClass = cb.build({ props }) |
|||
</script> |
|||
|
|||
<ul 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> |
|||
<ul bind:this={list} class={listClass} {role} /> |
|||
|
|||
@ -1,71 +1,73 @@ |
|||
<script> |
|||
import { onMount, getContext } from "svelte"; |
|||
import { Radiobutton } from "../Radiobutton"; |
|||
import { Checkbox } from "../Checkbox"; |
|||
import ClassBuilder from "../ClassBuilder.js"; |
|||
import { onMount, getContext } from "svelte" |
|||
import { Radiobutton } from "../Radiobutton" |
|||
import { Checkbox } from "../Checkbox" |
|||
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 useDoubleLine = false; |
|||
export let inputElement = null; //radiobutton or checkbox |
|||
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 |
|||
export let disabled = false |
|||
|
|||
let role = "option"; |
|||
let role = "option" |
|||
|
|||
onMount(() => { |
|||
let context = getContext("BBMD:list:context"); |
|||
let context = getContext("BBMD:list:context") |
|||
if (context === "menu") { |
|||
role = "menuitem"; |
|||
role = "menuitem" |
|||
} |
|||
}); |
|||
}) |
|||
|
|||
$: if (!!inputElement) { |
|||
setContext("BBMD:input:context", "list-item"); |
|||
setContext("BBMD:input:context", "list-item") |
|||
} |
|||
|
|||
$: modifiers = { |
|||
selected: !inputElement ? item.selected : null, |
|||
disabled: item.disabled |
|||
}; |
|||
$: props = { modifiers }; |
|||
$: listItemClass = cb.build({ props }); |
|||
selected, |
|||
disabled, |
|||
} |
|||
$: props = { modifiers } |
|||
$: listItemClass = cb.build({ props }) |
|||
|
|||
$: useSecondaryText = |
|||
typeof item.text === "object" && "secondary" in item.text; |
|||
$: useTwoLine = variant === "two-line" && !!secondaryText |
|||
</script> |
|||
|
|||
<li |
|||
class={listItemClass} |
|||
role="option" |
|||
aria-selected={item.selected} |
|||
aria-selected={selected} |
|||
tabindex="0" |
|||
on:click={onClick}> |
|||
{#if item.leadingIcon} |
|||
{#if leadingIcon} |
|||
<span class="mdc-list-item__graphic material-icons" aria-hidden="true"> |
|||
{item.leadingIcon} |
|||
{leadingIcon} |
|||
</span> |
|||
{/if} |
|||
<span class={cb.elem`text`}> |
|||
{#if useDoubleLine} |
|||
<span class={cb.elem`primary-text`}>{item.text.primary}</span> |
|||
{#if useSecondaryText} |
|||
<span class={cb.elem`secondary-text`}>{item.text.secondary}</span> |
|||
{/if} |
|||
{:else}{item.text}{/if} |
|||
{#if useTwoLine} |
|||
<span class={cb.elem`primary-text`}>{text}</span> |
|||
<span class={cb.elem`secondary-text`}>{secondaryText}</span> |
|||
{:else}{text}{/if} |
|||
</span> |
|||
|
|||
{#if inputElement} |
|||
{#if inputElement === 'radiobutton'} |
|||
<Radiobutton checked={item.selected} disabled={item.disabled} /> |
|||
<Radiobutton checked={selected} {disabled} /> |
|||
{:else if inputElement === 'checkbox'} |
|||
<Checkbox checked={item.selected} disabled={item.disabled} /> |
|||
<Checkbox checked={selected} {disabled} /> |
|||
{/if} |
|||
{:else if item.trailingIcon} |
|||
{:else if trailingIcon} |
|||
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient --> |
|||
<span class="mdc-list-item__meta material-icons" aria-hidden="true"> |
|||
{item.trailingIcon} |
|||
{trailingIcon} |
|||
</span> |
|||
{/if} |
|||
</li> |
|||
|
|||
@ -1,2 +1,3 @@ |
|||
import "./_style.scss"; |
|||
export { default as List } from "./List.svelte"; |
|||
import "./_style.scss" |
|||
export { default as List } from "./List.svelte" |
|||
export { default as ListItem } from "./ListItem.svelte" |
|||
|
|||
Loading…
Reference in new issue