Initial checkin

This commit is contained in:
CheddarCrisp 2020-02-01 12:16:09 -05:00
parent 260fdfc0a2
commit aace75679a
12 changed files with 5726 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules/

View file

@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

52
dist/index.html vendored Normal file
View file

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<title>NCounter</title>
<style>
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
button {
background: 0;
border: 0;
}
.dialog {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.25);
z-index: 12;
pointer-events: none;
}
.dialog-content {
background-color: #E0E0E0;
pointer-events: all;
width: 250px;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
padding: 5px;
display: flex;
flex-wrap: wrap;
}
</style>
</head>
<body>
<script src="index.js"></script>
</body>
</html>

1
dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

5364
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

20
package.json Normal file
View file

@ -0,0 +1,20 @@
{
"name": "ncounter",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack-dev-server --open"
},
"author": "",
"license": "MIT",
"devDependencies": {
"svelte": "^3.4.1",
"svelte-loader": "^2.13.4",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.4.1"
}
}

3
src/index.js Normal file
View file

@ -0,0 +1,3 @@
import App from './ncounter/App.svelte';
new App({ target: document.body });

110
src/ncounter/App.svelte Normal file
View file

@ -0,0 +1,110 @@
<div class="app">
{#each counters as counter}
<Counter counter={ counter } on:save={() => { save(counter); } }></Counter>
{/each}
</div>
<button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
{#if showAddDialog}
<div class="dialog">
<div class="dialog-content">
<label>Name: <input type="text" bind:value={newCounter.title} use:focus/></label>
<label>Initial Value: <input type="number" bind:value={newCounter.value} /></label>
<label>Target: <input type="number" bind:value={newCounter.max} /></label>
<label>Click counter: <input type="checkbox" bind:value={newCounter.isClickCounter} /></label>
<button on:click={ () => { showAddDialog = false; } }>Cancel</button>
<button class="ok" on:click={ addCounter }>OK</button>
</div>
</div>
{/if}
<script>
import Counter from './Counter.svelte';
let showAddDialog = false;
let newCounter = null;
let counters = [
{
title: 'Test 1',
value: 0
},
{
title: 'Test 2',
value: 10
},
{
title: 'Max Test',
value: 0,
max: 100
},
{
title: 'Click Test',
value: 0,
isClickCounter: true
}
];
function focus(node){
node.focus();
}
function save(counter){
alert('Save ' + counter.title);
}
function showAdd(){
newCounter = {
title: '',
value: 0,
isClickCounter: false
}
console.log({ newCounter });
showAddDialog = true;
}
function addCounter(){
counters = [...counters, newCounter];
showAddDialog = false;
}
</script>
<style>
.add {
position: fixed;
bottom: 15px;
right: 15px;
background-color: #90C090;
border-radius: 50%;
width: 40px;
height: 40px;
color: white;
}
.dialog-content > label {
display: flex;
width: 100%;
margin-bottom: 5px;
}
.dialog-content > label > input {
margin-left: auto;
}
.ok {
margin-left: auto;
}
.dialog-content button {
padding: 10px;
font-size: 14px;
font-weight: 600;
}
.app {
margin-bottom: 60px;
}
</style>

112
src/ncounter/Counter.svelte Normal file
View file

@ -0,0 +1,112 @@
<div class="counter" on:click="{ clickCount }">
<header>{ counter.title }</header>
<span class="value">{ counter.value }</span>
{#if counter.max}
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
{/if}
<div class="controls">
{#if !counter.isClickCounter}
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
{/if}
<button class="reset" on:click={ reset }><i class="material-icons">undo</i></button>
<button on:click={ save }><i class="material-icons">save</i></button>
</div>
{#if showIncrement}
<div class="dialog">
<div class="dialog-content">
<input class="increment-value" type="number" bind:value={ incrementValue } use:focus />
<button on:click={ () => { showIncrement = false; } }>Cancel</button>
<button class="ok" on:click={ increment }>OK</button>
</div>
</div>
{/if}
</div>
<script>
import MyProgress from './MyProgress.svelte';
import { tick } from 'svelte';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let counter;
let incrementValue;
let showIncrement;
function focus(node){
node.focus();
}
function increment(){
counter.value += incrementValue;
showIncrement = false;
incrementValue = null;
}
function reset(e){
e.stopPropagation();
if(confirm(`Reset ${counter.title}?`))
counter.value = 0;
}
function save(e) {
e.stopPropagation();
dispatch('save');
counter.value = 0;
}
function clickCount() {
if(!counter.isClickCounter)
return;
counter.value++;
}
</script>
<style>
.counter{
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
margin-bottom: 12px;
display: flex;
flex-direction: column;
padding: 5px;
}
.controls {
display: flex;
}
.reset {
margin-left: auto;
}
header {
font-size: 22px;
font-weight: 600;
margin: 0 0 5px 0;
}
.value {
font-size: 18px;
font-weight: 500;
margin-left: 0;
}
.increment-value {
width: 100%;
margin: 5px 0;
}
.ok {
margin-left: auto;
}
.dialog-content button {
padding: 10px;
font-size: 14px;
font-weight: 600;
}
</style>

View file

@ -0,0 +1,40 @@
<div class="progress-bar">
<span class="progress" {style}></span>
<span class="text">{value} / {max}</span>
</div>
<script>
export let value;
export let max;
$: style = `width: ${(Math.min(1, value / max) * 100)}%`;
</script>
<style>
.progress-bar {
width: 100%;
margin: 3px 0;
background-color: #F0F0F0;
border: 1px solid black;
height: 20px;
position: relative;
}
.progress-bar > .progress {
display: block;
background-color: #C0CFC0;
height: 100%;
}
.progress-bar > .text {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: center;
}
</style>

0
src/ncounter/store.js Normal file
View file

22
webpack.config.js Normal file
View file

@ -0,0 +1,22 @@
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist')
},
devServer: {
contentBase: './dist'
},
module: {
rules: [
{
test: /\.svelte$/,
exclude: /node_modules/,
loader: 'svelte-loader'
}
]
},
devtool: 'inline-source-map'
}