Skip to content

Instantly share code, notes, and snippets.

@tmikeschu
Created November 24, 2019 19:22
Show Gist options
  • Save tmikeschu/8e5d2124ea6e6bc40fbc30217883f6e3 to your computer and use it in GitHub Desktop.
Save tmikeschu/8e5d2124ea6e6bc40fbc30217883f6e3 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
function createUUID() {
var dt = new Date().getTime();
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (dt + Math.random() * 16) % 16 | 0;
dt = Math.floor(dt / 16);
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
});
return uuid;
}
const makeNote = (order, id = createUUID()) => {
return {
[id]: {
id,
order,
text: "",
children: new Set(),
},
};
};
const fetchMachine = Machine({
id: "nested-notes",
initial: "idle",
context: {
notes: Object.assign({}, makeNote(1)),
editingNote: null,
},
states: {
idle: {
on: {
CLICK: [
{
target: "editingWithChildren",
actions: "setEditingNote",
cond: (context, event) => context.notes[event.data.noteId].children.size > 0,
},
{
target: "editing",
actions: "setEditingNote",
},
],
},
},
editingWithChildren: {
on: {
ENTER: {
target: "editing",
actions: ["addChildNote"],
},
TEXT_CHANGE_EVENT: {
target: "editing",
actions: ["updateText"],
},
CLICK: {
target: "editing",
actions: "setEditingNote",
},
},
},
editing: {
on: {
ENTER: {
target: "editing",
actions: ["newNote"],
},
TEXT_CHANGE_EVENT: {
target: "editing",
actions: ["updateText"],
},
CLICK: {
target: "editing",
actions: "setEditingNote",
},
TAB: {
target: "editingWithChildren",
actions: ["addChildNote"],
},
},
},
},
}, {
actions: {
newNote: assign({
notes: (context, event) => {
const newNote = makeNote(Object.keys(context.notes).length + 1, event.data.noteId);
return Object.assign(Object.assign({}, context.notes), newNote);
},
}),
addChildNote: assign({
notes: (context, event) => {
const parentNote = context.notes[event.data.parentId];
const newNote = makeNote(parentNote.children.size + 1, event.data.noteId);
const children = new Set(parentNote.children);
children.add(Object.keys(newNote)[0]);
return Object.assign(Object.assign(Object.assign({}, context.notes), { [event.data.parentId]: Object.assign(Object.assign({}, parentNote), { children }) }), newNote);
},
}),
setEditingNote: assign({
editingNote: (context, event) => event.data.noteId,
}),
updateText: assign({
notes: (context, event) => {
const note = context.notes[event.data.noteId];
note.text = event.data.text;
return Object.assign(Object.assign({}, context.notes), { [note.id]: note });
},
}),
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment