Files: ca2790e4654757e6f97c0d5cff97163c1865af61 / example / 2_doodle.js
3102 bytesRaw
1 | // run this from the terminal using : |
2 | // npx electro example/2_doodle.js |
3 | |
4 | const { h, Struct, Array: MutantArray, computed } = require('mutant') |
5 | const Marama = require('../') |
6 | |
7 | const state = Struct({ |
8 | month: new Date().getMonth() + 1, |
9 | events: MutantArray([]) |
10 | }) |
11 | |
12 | const page = h('div.page', [ |
13 | h('div.picker', [ |
14 | h('div.month-picker', [ |
15 | h('button', { 'ev-click': () => setMonth(-1) }, '<'), |
16 | monthName(state.month), |
17 | h('button', { 'ev-click': () => setMonth(+1) }, '>') |
18 | ]), |
19 | computed(state, ({ month, events }) => { |
20 | return Marama({ |
21 | month, |
22 | events, |
23 | onSelect, |
24 | styles: { |
25 | weekFormat: 'rows', |
26 | showNumbers: true, |
27 | tileRadius: 16, |
28 | tileGap: 8 |
29 | } |
30 | }) |
31 | }) |
32 | ]), |
33 | h('div.dates', [ |
34 | computed(state.events, events => { |
35 | return events |
36 | .sort((a, b) => a.date - b.date) |
37 | .map(e => h('div.date', e.date.toDateString())) |
38 | }) |
39 | ]) |
40 | ]) |
41 | |
42 | function setMonth (d) { |
43 | state.month.set(state.month() + d) |
44 | } |
45 | |
46 | function monthName (month) { |
47 | const MONTHS = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] |
48 | |
49 | return computed(state.month, m => { |
50 | var monthIndex = m - 1 |
51 | while (monthIndex < 0) { monthIndex += 12 } |
52 | return MONTHS[(monthIndex) % 12] |
53 | }) |
54 | } |
55 | |
56 | function onSelect ({ gte, lt, events }) { |
57 | if (!events.length) addEmptyEvent() |
58 | else clearDay() |
59 | |
60 | function addEmptyEvent () { |
61 | state.events.push({ |
62 | date: gte, |
63 | data: {attending: true} |
64 | }) |
65 | } |
66 | function clearDay () { |
67 | const filteredEvents = state.events().filter(e => !events.includes(e)) |
68 | state.events.set(filteredEvents) |
69 | } |
70 | } |
71 | |
72 | document.body.appendChild(page) |
73 | |
74 | |
75 | // styles |
76 | |
77 | require('../lib/styles-inject')() |
78 | const compile = require('micro-css') |
79 | |
80 | const css = compile(` |
81 | |
82 | div.page { |
83 | display: grid |
84 | grid-template-columns: auto 1fr |
85 | grid-gap: 2rem |
86 | |
87 | margin: 3rem |
88 | |
89 | div.picker { |
90 | div.month-picker { |
91 | font-family: sans |
92 | display: flex |
93 | justify-content: space-between |
94 | align-items: center |
95 | |
96 | margin-bottom: 1rem |
97 | |
98 | button { |
99 | background: none |
100 | border: none |
101 | cursor: pointer |
102 | font-size: 1.5rem |
103 | } |
104 | } |
105 | } |
106 | |
107 | div.dates { |
108 | div.date { |
109 | background: rebeccapurple |
110 | color: #fff |
111 | font-family: sans |
112 | font-weight: 600 |
113 | |
114 | padding: .5rem |
115 | margin-bottom: .5rem |
116 | } |
117 | } |
118 | } |
119 | |
120 | MaramaDayTile { |
121 | border-radius: 4rem |
122 | border: 1px solid hsl(0, 0%, 100%) |
123 | |
124 | -past { |
125 | cursor: initial |
126 | background: none |
127 | color: hsl(0, 0%, 60%) |
128 | |
129 | -events { |
130 | border: 1px solid hsl(0, 0%, 40%) |
131 | |
132 | -attending { |
133 | background: hsl(0, 0%, 40%) |
134 | color: #fff |
135 | } |
136 | } |
137 | } |
138 | |
139 | -future { |
140 | background: none |
141 | |
142 | -events { |
143 | border: 1px solid deepskyblue |
144 | color: deepskyblue |
145 | |
146 | -attending { |
147 | background: deepskyblue |
148 | color: #fff |
149 | } |
150 | } |
151 | } |
152 | |
153 | -range { |
154 | background: deeppink |
155 | |
156 | -future { |
157 | background: deepskyblue |
158 | } |
159 | } |
160 | } |
161 | |
162 | MaramaDayLabel { |
163 | font-size: 1rem |
164 | } |
165 | |
166 | `) |
167 | |
168 | document.head.appendChild( |
169 | h('style', { innerHTML: css }) |
170 | ) |
171 |
Built with git-ssb-web