schlechtenburg/packages/layout/lib/edit.tsx

199 lines
4.9 KiB
TypeScript
Raw Normal View History

2020-05-20 14:21:08 +00:00
import {
2020-12-27 21:32:43 +00:00
defineComponent,
2020-05-20 14:21:08 +00:00
reactive,
2020-05-24 15:33:25 +00:00
computed,
watch,
2020-05-24 20:00:14 +00:00
PropType,
2020-12-27 21:32:43 +00:00
} from 'vue';
2020-05-20 14:21:08 +00:00
import {
model,
2020-05-27 15:06:14 +00:00
Block,
2020-05-27 13:57:57 +00:00
blockProps,
2020-12-30 13:34:23 +00:00
useActivation,
2020-05-25 18:07:34 +00:00
2020-12-30 13:34:23 +00:00
SbBlock,
SbButton,
SbToolbar,
SbBlockPlaceholder,
SbBlockOrdering,
} from '@schlechtenburg/core';
2020-05-25 18:07:34 +00:00
2020-05-24 20:00:14 +00:00
import {
LayoutData,
LayoutProps,
getDefaultData,
} from './util';
2020-05-20 14:21:08 +00:00
2020-05-24 20:00:14 +00:00
import './style.scss';
2020-05-20 14:21:08 +00:00
export default defineComponent({
2020-05-24 20:00:14 +00:00
name: 'sb-layout-edit',
2020-05-20 14:21:08 +00:00
model,
props: {
2020-05-24 15:33:25 +00:00
...blockProps,
2021-02-22 18:13:37 +00:00
onUpdate: { type: Function, default: () => {} },
2020-05-24 20:00:14 +00:00
data: {
type: (null as unknown) as PropType<LayoutData>,
default: getDefaultData,
},
2020-05-20 14:21:08 +00:00
},
2020-05-27 15:06:14 +00:00
setup(props: LayoutProps) {
2021-03-07 17:47:28 +00:00
const { activate } = useActivation(props.id);
2020-05-20 14:21:08 +00:00
2020-05-24 20:00:14 +00:00
const localData: LayoutData = reactive({
2020-05-24 15:33:25 +00:00
orientation: props.data.orientation,
children: [...props.data.children],
2020-05-20 14:21:08 +00:00
});
2020-05-24 15:33:25 +00:00
watch(() => props.data, () => {
localData.orientation = props.data.orientation;
localData.children = [...props.data.children];
2020-05-20 14:21:08 +00:00
});
2020-05-24 15:33:25 +00:00
const classes = computed(() => ({
2020-05-20 14:21:08 +00:00
'sb-layout': true,
[`sb-layout_${localData.orientation}`]: true,
2020-05-24 15:33:25 +00:00
}));
2020-05-20 14:21:08 +00:00
const toggleOrientation = () => {
2020-12-30 01:32:46 +00:00
console.log('toggle');
2021-02-22 18:13:37 +00:00
props.onUpdate({
2020-05-20 14:21:08 +00:00
orientation: localData.orientation === 'vertical' ? 'horizontal' : 'vertical',
});
};
2020-05-27 15:06:14 +00:00
const onChildUpdate = (child: Block, updated: Block) => {
2020-05-20 14:21:08 +00:00
const index = localData.children.indexOf(child);
2020-05-27 18:36:46 +00:00
if (index === -1) {
return;
}
2021-02-22 18:13:37 +00:00
props.onUpdate({
2020-05-20 14:21:08 +00:00
children: [
...localData.children.slice(0, index),
2020-05-24 15:33:25 +00:00
{
...child,
...updated,
},
2020-05-20 14:21:08 +00:00
...localData.children.slice(index + 1),
],
});
};
2020-05-27 15:06:14 +00:00
const appendBlock = (block: Block) => {
2020-05-27 18:36:46 +00:00
localData.children = [
...localData.children,
block,
];
2021-02-22 18:13:37 +00:00
props.onUpdate({ children: [...localData.children] });
2021-03-07 17:47:28 +00:00
activate(block.id);
2020-05-20 14:21:08 +00:00
};
2020-05-27 15:06:14 +00:00
const insertBlock = (index: number, block: Block) => {
2020-05-27 18:36:46 +00:00
localData.children = [
...localData.children.slice(0, index + 1),
block,
...localData.children.slice(index + 1),
];
2021-02-22 18:13:37 +00:00
props.onUpdate({ children: [...localData.children] });
2021-03-07 17:47:28 +00:00
activate(block.id);
2020-05-24 15:33:25 +00:00
};
2020-05-27 18:36:46 +00:00
const removeBlock = (index: number) => {
localData.children = [
...localData.children.slice(0, index),
...localData.children.slice(index + 1),
];
2021-02-22 18:13:37 +00:00
props.onUpdate({ children: [...localData.children] });
2020-05-27 18:36:46 +00:00
const newActiveIndex = Math.max(index - 1, 0);
2021-03-07 17:47:28 +00:00
activate(localData.children[newActiveIndex].id);
2020-05-27 18:36:46 +00:00
};
2021-02-22 18:13:37 +00:00
const activateBlock = (index: number) => {
const safeIndex =
Math.max(
Math.min(
localData.children.length - 1,
index,
),
0,
);
2021-03-07 17:47:28 +00:00
activate(localData.children[safeIndex].id);
2021-02-22 18:13:37 +00:00
};
const moveBackward = (index: number) => {
2020-05-28 20:16:35 +00:00
if (index === 0) {
return;
}
const curr = localData.children[index];
const prev = localData.children[index - 1];
localData.children = [
...localData.children.slice(0, index - 1),
curr,
prev,
...localData.children.slice(index + 1),
];
2021-02-22 18:13:37 +00:00
props.onUpdate({ children: [...localData.children] });
2020-05-28 20:16:35 +00:00
};
2021-02-22 18:13:37 +00:00
const moveForward = (index: number) => {
2020-05-28 20:16:35 +00:00
if (index === localData.children.length - 1) {
return;
}
const curr = localData.children[index];
const next = localData.children[index + 1];
localData.children = [
...localData.children.slice(0, index),
next,
curr,
...localData.children.slice(index + 2),
];
2021-02-22 18:13:37 +00:00
props.onUpdate({ children: [...localData.children] });
2020-05-28 20:16:35 +00:00
};
2020-05-25 21:10:21 +00:00
return () => (
<div class={classes.value}>
2020-12-30 01:32:46 +00:00
<SbToolbar>
2020-05-27 13:57:57 +00:00
<SbButton
2020-05-20 14:21:08 +00:00
type="button"
2020-12-30 01:32:46 +00:00
onClick={toggleOrientation}
2020-05-27 13:57:57 +00:00
>{localData.orientation}</SbButton>
2020-05-20 14:21:08 +00:00
</SbToolbar>
2020-05-25 21:10:21 +00:00
{...localData.children.map((child, index) => (
2020-05-24 15:33:25 +00:00
<SbBlock
2021-03-07 17:47:28 +00:00
{...{ key: child.id }}
2020-05-28 20:16:35 +00:00
data-order={index}
2020-05-24 15:33:25 +00:00
block={child}
2021-02-22 18:13:37 +00:00
onUpdate={(updated: Block) => onChildUpdate(child, updated)}
onRemoveSelf={() => removeBlock(index)}
onPrependBlock={(block: Block) => insertBlock(index - 1, block)}
onAppendBlock={(block: Block) => insertBlock(index, block)}
onActivatePrevious={(block: Block) => activateBlock(index - 1,)}
onActivateNext={(block: Block) => activateBlock(index + 1,)}
2020-12-30 01:32:46 +00:00
>
{{
'context-toolbar': () =>
<SbBlockOrdering
2021-02-22 18:13:37 +00:00
onMoveBackward={() => moveBackward(index)}
onMoveForward={() => moveForward(index)}
onRemove={() => removeBlock(index)}
2020-12-30 01:32:46 +00:00
sortable={props.sortable}
/>,
}}
</SbBlock>
2020-05-24 15:33:25 +00:00
))}
2020-12-30 01:32:46 +00:00
<SbBlockPlaceholder onInsertBlock={appendBlock} />
2020-05-24 15:33:25 +00:00
</div>
2020-05-20 14:21:08 +00:00
);
},
});