svelte-material-ui
svelte-material-ui copied to clipboard
How to use chip component in an input field?
There is currently in "Input chips" section of the chip component page in the documentation: https://sveltematerialui.com/demo/chips
I assume this means that using the chips inside an input component such as the autocomplete or text field component is possible, e.g.
but the documentation doesn't seem to show how this is done and I am struggling to work out how to do this.
Is my understanding correct? and if so, could you provide some pointers as to how to do it? I don't mind creating a pull request improving the docs once I understand how it should actually be done.
<script lang="ts">
import TextField from '@smui/textfield'
import Chip, {Set, Text} from '@smui/chips'
let value = ''
let input: string[] = []
const handleSpacePress = (event: KeyboardEvent) => {
if(event.key === ' ' || event.code === 'Space' || event.code === 'space'){
if(input.includes(value.trim())){
alert(`${value} is already a chip`)
value = ''
return
}
input = [...input, value.trim()]
value = ''
}
}
const handleDelete = (event: KeyboardEvent) => {
if(event.key === 'Backspace'){
if(value === '')
input.pop()
input = input
}
}
</script>
<TextField bind:value on:keyup={handleSpacePress} on:keyup={handleDelete}>
<Set style="flex-wrap: nowrap !important;" chips={input} let:chip input>
<Chip {chip}>
<Text>{chip}</Text>
</Chip>
</Set>
</TextField>
I did find that I wasn't able to get the TrailingAction
to show an icon for some reason but I think that might be an issue on my part. TrailingAction
does work, but I was getting the word 'cancel' rather than the material icon.
Ok, got it working by making a custom component:
chips-input.svelte
<script lang="ts">
import TextField from '@smui/textfield';
import Chip, { Set, Text, TrailingAction } from '@smui/chips';
export let input: string[] = [];
export let name = '';
export let label = '';
export let placeholder = label;
let value = ' ';
const handleKey = (e: CustomEvent) => {
const event = e as unknown as KeyboardEvent;
// remove value with backspace
if (event.key === 'Backspace') {
if (value === '') input.pop();
}
// add value with enter, space, or comma
if (['Enter', ' ', ','].includes(event.key)) {
if (input.includes(value.trim())) {
value = '';
return;
}
if (event.key === ',') {
value = value.slice(0, -1);
}
input.push(value.trim());
value = '';
}
// save new value
input = input;
};
</script>
<TextField
input$name={name}
type="text"
variant="outlined"
class="text-size"
{placeholder}
{label}
bind:value
on:keyup={handleKey}
>
<Set class="set" chips={input} let:chip>
<Chip {chip}>
<Text>{chip}</Text>
<TrailingAction icon$class="material-icons white">close</TrailingAction>
</Chip>
</Set>
</TextField>
<style global>
.set {
flex-wrap: nowrap !important;
}
.white {
color: #fff;
}
</style>
my-form.svelte
<ChipsInput label="Tags" placeholder="Tags" bind:input={$form.tags} />
Hope this helps someone,
J
I think it is a bug with TrailingAction, so I just styled it color: white
.
J