SortableGroup
sortable lists nested in each other's items, with items moving between them.
usage
example
polecats
ben
darrel
father torque
vultures
suzi
maureen
cavefish
code
import { SortableGroup, SortableList } from 'charcell/react';
function GangList({ id, items }: { id: any; items: any }) {
return (
<SortableList id={id} items={items}>
{({ item }) => (
<div>
<span>{item.name}</span>
{item.children && (
<>
<div style={{ paddingInlineStart: '2ch' }}>
<GangList id={item.name} items={item.children} />
</div>
</>
)}
</div>
)}
</SortableList>
);
}
export function SortableGroupExample() {
return (
<SortableGroup>
<GangList
id="gangs"
items={[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]}
/>
</SortableGroup>
);
}▴
▾
<script setup lang="ts">
import { SortableGroup } from 'charcell/vue';
import GangList from './GangList.vue';
</script>
<template>
<SortableGroup>
<GangList
id="gangs"
:items="[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]"
/>
</SortableGroup>
</template>
<!-- GangList.vue -->
<script setup lang="ts">
import { SortableList } from 'charcell/vue';
defineProps(['id', 'items']);
</script>
<template>
<SortableList :id="id" :items="items"
><template #default="{ item }"
><div>
<span>{{ item.name }}</span
><template v-if="item.children"
><div style="padding-inline-start: 2ch">
<GangList :id="item.name" :items="item.children" /></div
></template></div></template
></SortableList>
</template>▴
▾
<script lang="ts">
import { SortableGroup, SortableList } from 'charcell/svelte';
</script>
{#snippet GangList({ id, items }: { id: any; items: any })}
<SortableList {id} {items}
>{#snippet children({ item })}<div>
<span>{item.name}</span>{#if item.children}<div
style="padding-inline-start: 2ch"
>
{@render GangList({ id: item.name, items: item.children })}
</div>{/if}
</div>{/snippet}</SortableList
>
{/snippet}
<SortableGroup>
{@render GangList({
id: 'gangs',
items: [
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{ name: 'vultures', children: [{ name: 'suzi' }, { name: 'maureen' }] },
{ name: 'cavefish', children: [] },
],
})}
</SortableGroup>▴
▾
<!-- component: SortableGroup (behavior not included) --><!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>polecats</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>ben</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>darrel</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>father torque</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>vultures</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>suzi</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>maureen</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>cavefish</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div
class="CharcellSortableList CharcellSortableList--empty"
role="list"
></div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component --><!-- /component -->▴
▾
import { SortableGroup, SortableList } from 'charcell/react';
function GangList({ id, items }: { id: any; items: any }) {
return (
<SortableList id={id} items={items}>
{({ item }) => (
<div>
<span>{item.name}</span>
{item.children && (
<>
<div style={{ paddingInlineStart: '2ch' }}>
<GangList id={item.name} items={item.children} />
</div>
</>
)}
</div>
)}
</SortableList>
);
}
export function SortableGroupExample() {
return (
<SortableGroup snap="row">
<GangList
id="gangs"
items={[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]}
/>
</SortableGroup>
);
}▴
▾
<script setup lang="ts">
import { SortableGroup } from 'charcell/vue';
import GangList from './GangList.vue';
</script>
<template>
<SortableGroup snap="row">
<GangList
id="gangs"
:items="[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]"
/>
</SortableGroup>
</template>
<!-- GangList.vue -->
<script setup lang="ts">
import { SortableList } from 'charcell/vue';
defineProps(['id', 'items']);
</script>
<template>
<SortableList :id="id" :items="items"
><template #default="{ item }"
><div>
<span>{{ item.name }}</span
><template v-if="item.children"
><div style="padding-inline-start: 2ch">
<GangList :id="item.name" :items="item.children" /></div
></template></div></template
></SortableList>
</template>▴
▾
<script lang="ts">
import { SortableGroup, SortableList } from 'charcell/svelte';
</script>
{#snippet GangList({ id, items }: { id: any; items: any })}
<SortableList {id} {items}
>{#snippet children({ item })}<div>
<span>{item.name}</span>{#if item.children}<div
style="padding-inline-start: 2ch"
>
{@render GangList({ id: item.name, items: item.children })}
</div>{/if}
</div>{/snippet}</SortableList
>
{/snippet}
<SortableGroup snap="row">
{@render GangList({
id: 'gangs',
items: [
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{ name: 'vultures', children: [{ name: 'suzi' }, { name: 'maureen' }] },
{ name: 'cavefish', children: [] },
],
})}
</SortableGroup>▴
▾
<!-- component: SortableGroup (behavior not included) --><!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>polecats</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>ben</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>darrel</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>father torque</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>vultures</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>suzi</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>maureen</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>cavefish</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div
class="CharcellSortableList CharcellSortableList--empty"
role="list"
></div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component --><!-- /component -->▴
▾
import { SortableGroup, SortableList } from 'charcell/react';
function GangList({ id, items }: { id: any; items: any }) {
return (
<SortableList id={id} items={items}>
{({ item }) => (
<div>
<span>{item.name}</span>
{item.children && (
<>
<div style={{ paddingInlineStart: '2ch' }}>
<GangList id={item.name} items={item.children} />
</div>
</>
)}
</div>
)}
</SortableList>
);
}
export function SortableGroupExample() {
return (
<SortableGroup snap="none">
<GangList
id="gangs"
items={[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]}
/>
</SortableGroup>
);
}▴
▾
<script setup lang="ts">
import { SortableGroup } from 'charcell/vue';
import GangList from './GangList.vue';
</script>
<template>
<SortableGroup snap="none">
<GangList
id="gangs"
:items="[
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{
name: 'vultures',
children: [{ name: 'suzi' }, { name: 'maureen' }],
},
{ name: 'cavefish', children: [] },
]"
/>
</SortableGroup>
</template>
<!-- GangList.vue -->
<script setup lang="ts">
import { SortableList } from 'charcell/vue';
defineProps(['id', 'items']);
</script>
<template>
<SortableList :id="id" :items="items"
><template #default="{ item }"
><div>
<span>{{ item.name }}</span
><template v-if="item.children"
><div style="padding-inline-start: 2ch">
<GangList :id="item.name" :items="item.children" /></div
></template></div></template
></SortableList>
</template>▴
▾
<script lang="ts">
import { SortableGroup, SortableList } from 'charcell/svelte';
</script>
{#snippet GangList({ id, items }: { id: any; items: any })}
<SortableList {id} {items}
>{#snippet children({ item })}<div>
<span>{item.name}</span>{#if item.children}<div
style="padding-inline-start: 2ch"
>
{@render GangList({ id: item.name, items: item.children })}
</div>{/if}
</div>{/snippet}</SortableList
>
{/snippet}
<SortableGroup snap="none">
{@render GangList({
id: 'gangs',
items: [
{
name: 'polecats',
children: [
{ name: 'ben' },
{ name: 'darrel' },
{ name: 'father torque' },
],
},
{ name: 'vultures', children: [{ name: 'suzi' }, { name: 'maureen' }] },
{ name: 'cavefish', children: [] },
],
})}
</SortableGroup>▴
▾
<!-- component: SortableGroup (behavior not included) --><!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>polecats</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>ben</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>darrel</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>father torque</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>vultures</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div class="CharcellSortableList" role="list">
<!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>suzi</span></div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div><span>maureen</span></div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component --><!-- component: SortableItemDriver (behavior not included) -->
<div class="CharcellSortableList__row" role="listitem">
<button class="CharcellSortableList__grip" type="button"></button>
<div class="CharcellSortableList__content">
<div>
<span>cavefish</span>
<div>
<!-- component: SortableListDriver (behavior not included) -->
<div
class="CharcellSortableList CharcellSortableList--empty"
role="list"
></div>
<!-- /component -->
</div>
</div>
</div>
</div>
<!-- /component -->
</div>
<!-- /component --><!-- /component -->▴
▾
as text
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
⠿ polecats ⠿ ben ⠿ darrel ⠿ father torque ⠿ vultures ⠿ suzi ⠿ maureen ⠿ cavefish
props
- onMove(move: SortableMove) => void
- Called with every move between or within the group's lists.
- translationsSortableListTranslations
- Every string the lists say (English defaults).
- snap'character' | 'row' | 'none'
- How a drag moves:
'character'(the default) in whole cells,'row'in whole rows down only,'none'freely.
slots
in react, the default slot is children and each named slot a prop of its name, a function where the slot hands values; in vue, a slot; in svelte, a snippet.
- default
- The lists, at any depth, and whatever surrounds them.
▴
▾