Skip to content

Commit 9db708e

Browse files
committed
feat: added demo board
1 parent 606d6a5 commit 9db708e

11 files changed

+661
-600
lines changed

dist/kasper.js

+7-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/kasper.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

live/css/style.css

+74-65
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
--background: rgba(0, 0, 0, 0.5);
44
--short-padding: 10px;
55
--radius: 10px;
6+
--text: #f0f0f0;
67
}
78
html,
89
body {
@@ -16,15 +17,15 @@ html {
1617
font-family: "IBM Plex Sans", sans-serif;
1718
font-weight: 300;
1819
font-style: normal;
19-
color: #f0f0f0;
20+
color: var(--text);
2021
background-image: url("../img/bg.jpg");
2122
background-position: center center;
2223
background-size: cover;
2324
background-color: #9d3cae;
2425
line-height: 1.25;
2526
}
2627

27-
kasper {
28+
kasper-app {
2829
display: block;
2930
height: 100%;
3031
overflow: hidden;
@@ -40,6 +41,7 @@ nav {
4041
}
4142

4243
main {
44+
position: relative;
4345
padding: var(--short-padding);
4446
display: grid;
4547
grid-gap: 10px;
@@ -50,6 +52,33 @@ main {
5052
align-items: start;
5153
}
5254

55+
button,
56+
textarea {
57+
background-color: var(--background);
58+
color: var(--text);
59+
border: none;
60+
border-radius: var(--radius);
61+
padding: var(--short-padding);
62+
cursor: pointer;
63+
font-size: 16px;
64+
}
65+
66+
textarea {
67+
height: 120px;
68+
}
69+
70+
button:hover {
71+
background-color: black;
72+
}
73+
74+
.fixed {
75+
position: absolute;
76+
inset: 0;
77+
display: flex;
78+
justify-content: center;
79+
align-items: center;
80+
}
81+
5382
.column {
5483
background-color: var(--background);
5584
border-radius: var(--radius);
@@ -78,6 +107,9 @@ main {
78107
border-radius: var(--radius);
79108
padding: var(--short-padding);
80109
}
110+
.card[dragged="true"]:hover {
111+
background-color: black;
112+
}
81113

82114
.column > .title {
83115
background: black;
@@ -86,70 +118,62 @@ main {
86118
border-top-right-radius: var(--radius);
87119
}
88120

89-
HTML CSS JSResult Skip Results Iframe
90-
/* Absolute Center Spinner */
91-
.loading {
92-
position: fixed;
93-
z-index: 999;
94-
height: 2em;
95-
width: 2em;
96-
overflow: visible;
97-
margin: auto;
98-
top: 0;
99-
left: 0;
100-
bottom: 0;
101-
right: 0;
121+
.tags {
122+
display: flex;
123+
gap: 10px;
124+
padding-bottom: 10px;
125+
}
126+
127+
.tags > .tag {
128+
width: 30px;
129+
height: 10px;
130+
border-radius: var(--radius);
131+
}
132+
133+
.tag.red {
134+
background-color: rgba(255, 0, 0, 0.5);
135+
}
136+
137+
.tag.blue {
138+
background-color: rgba(0, 0, 255, 0.5);
139+
}
140+
141+
.tag.yellow {
142+
background-color: rgba(255, 255, 0, 0.5);
143+
}
144+
145+
.tag.green {
146+
background-color: rgba(0, 255, 0, 0.5);
147+
}
148+
149+
.tag.gray {
150+
background-color: rgba(255, 255, 255, 0.5);
102151
}
103152

104-
/* Transparent Overlay */
105153
.loading:before {
106154
content: "";
107155
display: block;
108-
position: fixed;
109-
top: 0;
110-
left: 0;
111-
width: 100%;
112-
height: 100%;
156+
position: absolute;
157+
inset: 0;
113158
background-color: rgba(0, 0, 0, 0.3);
114159
}
115160

116-
/* :not(:required) hides these rules from IE9 and below */
117-
.loading:not(:required) {
118-
/* hide "loading..." text */
119-
font: 0/0 a;
120-
color: transparent;
121-
text-shadow: none;
122-
background-color: transparent;
123-
border: 0;
124-
}
125-
126-
.loading:not(:required):after {
161+
.loading:after {
127162
content: "";
128163
display: block;
129164
font-size: 10px;
130-
width: 1em;
131-
height: 1em;
165+
width: 5px;
166+
height: 5px;
132167
margin-top: -0.5em;
133168
-webkit-animation: spinner 1500ms infinite linear;
134-
-moz-animation: spinner 1500ms infinite linear;
135-
-ms-animation: spinner 1500ms infinite linear;
136-
-o-animation: spinner 1500ms infinite linear;
137169
animation: spinner 1500ms infinite linear;
138170
border-radius: 0.5em;
139-
-webkit-box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0,
140-
rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0,
141-
rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.5) -1.5em 0 0 0,
142-
rgba(0, 0, 0, 0.5) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0,
143-
rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0;
144-
box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0,
145-
rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0,
146-
rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) -1.5em 0 0 0,
147-
rgba(0, 0, 0, 0.75) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0,
148-
rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0;
171+
box-shadow: var(--text) 1.5em 0 0 0, var(--text) 1.1em 1.1em 0 0,
172+
var(--text) 0 1.5em 0 0, var(--text) -1.1em 1.1em 0 0,
173+
var(--text) -1.5em 0 0 0, var(--text) -1.1em -1.1em 0 0,
174+
var(--text) 0 -1.5em 0 0, var(--text) 1.1em -1.1em 0 0;
149175
}
150176

151-
/* Animation */
152-
153177
@-webkit-keyframes spinner {
154178
0% {
155179
transform: rotate(0deg);
@@ -158,22 +182,7 @@ HTML CSS JSResult Skip Results Iframe
158182
transform: rotate(360deg);
159183
}
160184
}
161-
@-moz-keyframes spinner {
162-
0% {
163-
transform: rotate(0deg);
164-
}
165-
100% {
166-
transform: rotate(360deg);
167-
}
168-
}
169-
@-o-keyframes spinner {
170-
0% {
171-
transform: rotate(0deg);
172-
}
173-
100% {
174-
transform: rotate(360deg);
175-
}
176-
}
185+
177186
@keyframes spinner {
178187
0% {
179188
transform: rotate(0deg);

live/demo.html

+66-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="utf-8" />
55
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6-
<title>Blog with KasperJs</title>
6+
<title>KasperJS Kanban</title>
77
<meta name="viewport" content="width=device-width, initial-scale=1" />
88
<link
99
rel="stylesheet"
@@ -16,44 +16,96 @@
1616
rel="stylesheet"
1717
/>
1818
<link rel="stylesheet" type="text/css" href="./css/style.css" />
19-
<script src="../dist/kasper.js"></script>
19+
<script src="./js/todos.js"></script>
20+
<script src="../dist/kasper.min.js"></script>
2021
</head>
2122
<body>
2223
<template>
2324
<nav>KasperJS Kanban</nav>
2425
<main>
25-
<div class="column" @each="const category of categories.value">
26-
<div class="title">{{category.title}}</div>
27-
<div class="todos">
28-
<div class="card" @each="const todo of todos.value[category.name]">
29-
<div class="tags">
30-
<void @each="const tag of todo.tags">
31-
<div class="{{tag}}">{{tag}}</div>
32-
</void>
26+
<void @if="loading.value">
27+
<div class="fixed">
28+
<div class="loading"></div>
29+
</div>
30+
</void>
31+
<void @else>
32+
<div class="column" @each="category of categories.value">
33+
<div class="title">{{category.title}}</div>
34+
<div
35+
class="todos"
36+
@on:dragover="onDragover($event)"
37+
@on:drop="onDrop(category.name, $event)"
38+
>
39+
<div
40+
class="card"
41+
draggable="true"
42+
data-todo-id="{{todo.id}}"
43+
@each="todo of todos.value[category.name]"
44+
@on:dragstart="onDragStart(todo.id, category.name, $event)"
45+
>
46+
<div class="tags">
47+
<div @each="tag of todo.tags" class="tag {{tag}}"></div>
48+
</div>
49+
<div>{{todo.task}}</div>
3350
</div>
34-
<div>{{todo.task}}</div>
51+
<button type="button" @on:click="onAddCard()">
52+
+ Add a card
53+
</button>
3554
</div>
3655
</div>
37-
</div>
56+
</void>
3857
</main>
3958
</template>
59+
<kasper-app></kasper-app>
4060
<script>
4161
async function fetchTodos() {
42-
const res = await fetch("./js/todos.json");
43-
return await res.json();
62+
return new Promise((resolve) => {
63+
setTimeout(() => {
64+
resolve(TODOS);
65+
}, 500);
66+
});
4467
}
4568

4669
class TodoApp extends Component {
4770
loading = $state(true);
4871
todos = $state({});
4972
categories = $state([]);
73+
editing = $state(null);
5074

5175
$onInit = async () => {
5276
const data = await fetchTodos();
5377
this.todos.set(data.todos);
5478
this.categories.set(data.categories);
5579
this.loading.set(false);
5680
};
81+
82+
onAddCard = () => {
83+
alert("TODO");
84+
};
85+
86+
onDragStart = (todoId, category, event) => {
87+
event.dataTransfer.dropEffect = "move";
88+
event.dataTransfer.setData(
89+
"text/plain",
90+
JSON.stringify({ todoId, category })
91+
);
92+
event.srcElement.setAttribute("dragged", true);
93+
};
94+
95+
onDragover = (event) => {
96+
event.preventDefault();
97+
};
98+
99+
onDrop = (newCategory, event) => {
100+
event.preventDefault();
101+
const data = event.dataTransfer.getData("text/plain");
102+
const { todoId, category } = JSON.parse(data);
103+
const todos = this.todos.value;
104+
const todo = todos[category].find((t) => t.id === todoId);
105+
todos[category] = todos[category].filter((t) => t.id !== todo.id);
106+
todos[newCategory] = [...todos[newCategory], todo];
107+
this.todos.set(todos);
108+
};
57109
}
58110

59111
Kasper(TodoApp);

0 commit comments

Comments
 (0)