Commit 0ae77ce854723c6cb0d10cdf9f28bcf53f3fc587
-refactor styles, add ability for different grpah orientation, styling, improve README
mixmix committed on 8/20/2018, 5:13:07 AMParent: 6dc2c1a4ab70782adb3bd7e9c7dff831c072e153
Files changed
README.md | changed |
index.js | changed |
lib/styles-inject.js | changed |
lib/styles-write.js | changed |
lib/styles-compile.js | deleted |
lib/get-css.js | added |
lib/get-day.js | added |
lib/get-mcss.js | added |
styles/marama-day-name.mcss | deleted |
styles/day-label.mcss | added |
styles/marama-day-tile.mcss | deleted |
styles/day-tile.mcss | added |
styles/marama.mcss | deleted |
styles/index.mcss | added |
test/index.js | deleted |
test/index-classic-cal.js | added |
test/index-letnice.js | added |
day-label.js | added |
day-tile.js | added |
marama.jpg | added |
README.md | ||
---|---|---|
@@ -1,3 +1,60 @@ | ||
1 | 1 … | # Marama |
2 | 2 … | |
3 | -_from te reo maori: [marama](http://maoridictionary.co.nz/search?keywords=moon) - 1. moon, 2. month_ | |
3 … | +![](./marama.jpg) | |
4 … | + | |
5 … | +_From te reo maori: [marama](http://maoridictionary.co.nz/search?keywords=moon) - 1. moon, 2. month_ | |
6 … | + | |
7 … | +## Uasge | |
8 … | + | |
9 … | +```js | |
10 … | +var Marama = require('marama') | |
11 … | +require('marama/lib/styles-inject')() | |
12 … | + | |
13 … | +const marama = Marama({ | |
14 … | + events: [ | |
15 … | + { date: new Date(2018, 3, 4), data: { attending: false } }, | |
16 … | + { date: new Date(2018, 7, 21), data: { attending: true } } | |
17 … | + // NOTE Date has signatute (Year, monthIndex, day) | |
18 … | + ], | |
19 … | + range: { | |
20 … | + gte: new Date(2018, 7, 13), | |
21 … | + lt: new Date(2018, 7, 20) // range of highlighted dates | |
22 … | + }, | |
23 … | + styles: { | |
24 … | + tileRadius: 18, | |
25 … | + tileGap: 4 | |
26 … | + } | |
27 … | +}) | |
28 … | + | |
29 … | +document.body.appendChild(marama) | |
30 … | +``` | |
31 … | + | |
32 … | + | |
33 … | +## API | |
34 … | + | |
35 … | +Marama can take the following options: | |
36 … | + | |
37 … | +```js | |
38 … | +{ | |
39 … | + month, // month number (by common defn, e.g. 4 is April) | |
40 … | + events // (optional) an Array of form: [{ date: Date, data: { ... } }] | |
41 … | + year, // (optional) defaults to current year | |
42 … | + monthNames, // (optional) an Array of month names | |
43 … | + range, // (optional) an Object of form { gte: Date, lt: Date } to highlight | |
44 … | + setRange, // (optional) a callback which receives a range on clicks { gte, lt } | |
45 … | + styles, // (optional) Object, _see below_ | |
46 … | + today // (optional) a Date which can be used to over-ride the definition of today | |
47 … | +} | |
48 … | +``` | |
49 … | + | |
50 … | +The `styles` option can be used to change how Marama looks programmatically | |
51 … | + | |
52 … | +```js | |
53 … | +{ | |
54 … | + tileRadius, // (optional) Number, half-width of a day-tile, in px (default 6) | |
55 … | + tileGap, // (optional) Number, gap between day-tiles, in px (default: 1) | |
56 … | + dotRadius, // (optional) Number, radius of the 'attendance' dot in px (default: tileRadius/2) | |
57 … | + dotBorder, // (optional) Number, depth of outline on an event not attending (default: 1) | |
58 … | + weekFormat, // (optional) String(rows|columns), which direction weeks run in (default: rows) | |
59 … | +} | |
60 … | +``` |
index.js | |||
---|---|---|---|
@@ -1,130 +1,91 @@ | |||
1 | 1 … | const h = require('mutant/h') | |
2 … | +const DayTile = require('./day-tile') | ||
3 … | +const DayLabel = require('./day-label') | ||
4 … | +const getDay = require('./lib/get-day') | ||
2 | 5 … | ||
3 | 6 … | const MONTH_NAMES = [ 'Ja', 'Fe', 'Ma', 'Ap', 'Ma', 'Ju', 'Ju', 'Au', 'Se', 'Oc', 'No', 'De' ] | |
4 | 7 … | const DAYS = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ] | |
8 … | +const DEFAULT_FORMAT = 'rows' | ||
5 | 9 … | ||
6 | 10 … | module.exports = function Marama (opts = {}) { | |
7 | - const d = startOfDay() | ||
11 … | + const day = opts.today || startOfDay() | ||
8 | 12 … | const { | |
9 | - year = d.getFullYear(), | ||
10 | - month = d.getMonth() + 1, // month number (common defn) | ||
11 | - today = d, | ||
12 | 13 … | events = [], | |
14 … | + month = day.getMonth() + 1, // month number (common defn) | ||
15 … | + year = day.getFullYear(), | ||
16 … | + monthNames = MONTH_NAMES, | ||
13 | 17 … | range, | |
14 | 18 … | setRange = () => {}, | |
15 | - monthNames = MONTH_NAMES | ||
19 … | + styles = {}, | ||
20 … | + today = day | ||
16 | 21 … | } = opts | |
22 … | + if (opts.style) console.error('Marama: you have passed in **style** instead of styles!') | ||
17 | 23 … | ||
18 | 24 … | const monthIndex = month - 1 // month number (Date API defn) | |
19 | 25 … | const monthLength = new Date(year, monthIndex + 1, 0).getDate() | |
20 | 26 … | // NOTE Date takes month as a monthIndex i.e. april = 3 | |
21 | 27 … | // and day = 0 goes back a day | |
22 | 28 … | const days = Array(monthLength).fill().map((_, i) => i + 1) | |
29 … | + const dayOpts = { | ||
30 … | + events, | ||
31 … | + year, | ||
32 … | + monthIndex, | ||
33 … | + // day TBD | ||
34 … | + today, | ||
35 … | + offset: getDay(new Date(year, monthIndex, 1)) - 1, // how far into the week the month starts | ||
36 … | + weekFormat: getWeekFormat(styles), | ||
37 … | + range, | ||
38 … | + setRange | ||
39 … | + } | ||
23 | 40 … | ||
24 | - var weekday | ||
25 | - var week | ||
26 | - const offset = getDay(new Date(year, monthIndex, 1)) - 1 | ||
27 | - | ||
28 | 41 … | const setMonthRange = (ev) => { | |
29 | 42 … | setRange({ | |
30 | 43 … | gte: new Date(year, monthIndex, 1), | |
31 | 44 … | lt: new Date(year, monthIndex + 1, 1) | |
32 | 45 … | }) | |
33 | 46 … | } | |
34 | 47 … | ||
35 | 48 … | return h('Marama', [ | |
36 | - h('div.month-name', { 'ev-click': setMonthRange }, monthNames[monthIndex]), | ||
37 | - h('div.days', | ||
38 | - { | ||
39 | - style: { display: 'grid' } | ||
40 | - }, | ||
41 | - [ | ||
42 | - DAYS.map((day, i) => DayName(day, i)), | ||
43 | - days.map(Day) | ||
44 | - ] | ||
45 | - ) | ||
49 … | + // h('div.month-name', { 'ev-click': setMonthRange }, monthNames[monthIndex]), | ||
50 … | + h('div.days', { style: getStyles(styles) }, [ | ||
51 … | + DAYS.map((day, i) => DayLabel(day, i, dayOpts.weekFormat)), | ||
52 … | + days.map(day => { | ||
53 … | + dayOpts.day = day // note we're mutating this object (might save memory?) | ||
54 … | + return DayTile(dayOpts) | ||
55 … | + }) | ||
56 … | + ]) | ||
46 | 57 … | ]) | |
58 … | +} | ||
47 | 59 … | ||
48 | - function Day (day) { | ||
49 | - const date = new Date(year, monthIndex, day) | ||
50 | - const dateEnd = new Date(year, monthIndex, day + 1) | ||
51 | - weekday = getDay(date) | ||
52 | - week = Math.ceil((day + offset) / 7) | ||
60 … | +function getStyles (styles = {}) { | ||
61 … | + const { | ||
62 … | + tileRadius = 6, | ||
63 … | + tileGap = 1, | ||
64 … | + dotRadius, | ||
65 … | + dotBorder = 1 | ||
66 … | + } = styles | ||
67 … | + const format = getWeekFormat(styles) | ||
53 | 68 … | ||
54 | - const eventsOnDay = events.filter(e => { | ||
55 | - return e.date >= date && e.date < dateEnd | ||
56 | - }) | ||
57 | - | ||
58 | - const attending = eventsOnDay.some(e => { | ||
59 | - return e.data.attending | ||
60 | - }) | ||
61 | - | ||
62 | - const opts = { | ||
63 | - attributes: { | ||
64 | - 'title': `${year}-${month}-${day}`, | ||
65 | - 'data-date': `${year}-${month}-${day}` | ||
66 | - }, | ||
67 | - style: { | ||
68 | - 'grid-row': `${weekday} / ${weekday + 1}`, | ||
69 | - 'grid-column': `${week + 1} / ${week + 2}` | ||
70 | - // column moved by 1 to make space for labels | ||
71 | - }, | ||
72 | - classList: [ | ||
73 | - date < today ? '-past' : '-future', | ||
74 | - eventsOnDay.length ? '-events' : '', | ||
75 | - inRange(date) ? '-range' : '', | ||
76 | - attending ? '-attending' : '' | ||
77 | - ], | ||
78 | - 'ev-click': (ev) => { | ||
79 | - if (ev.shiftKey) { | ||
80 | - dateEnd >= range.lt | ||
81 | - ? setRange({ lt: dateEnd }) | ||
82 | - : setRange({ gte: date }) | ||
83 | - return | ||
84 | - } | ||
85 | - | ||
86 | - setRange({ | ||
87 | - gte: date, | ||
88 | - lt: dateEnd | ||
89 | - }) | ||
90 | - } | ||
91 | - } | ||
92 | - | ||
93 | - if (!eventsOnDay.length) return h('MaramaDayTile', opts) | ||
94 | - | ||
95 | - return h('MaramaDayTile', opts, [ | ||
96 | - // TODO add awareness of whether I'm going to events | ||
97 | - // TODO try a FontAwesome circle | ||
98 | - h('div.dot', [ | ||
99 | - // Math.random() > 0.3 ? h('div') : '' | ||
100 | - ]) | ||
101 | - ]) | ||
69 … | + const _styles = { | ||
70 … | + '--tile-radius': `${tileRadius}px`, | ||
71 … | + '--tile-gap': `${tileGap}px`, | ||
72 … | + '--dot-radius': `${dotRadius || Math.floor(tileRadius / 2)}px`, | ||
73 … | + '--dot-border': `${dotBorder}px`, | ||
74 … | + display: 'grid', | ||
75 … | + [`grid-template-${format}`]: '2 * calc(var(--tile-radius) + 2 * var(--tile-gap)) repeat(6, calc(2 * var(--tile-radius)))' | ||
102 | 76 … | } | |
103 | 77 … | ||
104 | - function inRange (date) { | ||
105 | - if (!range || (!range.gte && !range.lt)) return false | ||
106 | - return (date >= range.gte) && (date < range.lt) | ||
107 | - } | ||
78 … | + return _styles | ||
108 | 79 … | } | |
109 | 80 … | ||
110 | -function DayName (day, index) { | ||
111 | - return h('MaramaDayName', { | ||
112 | - style: { | ||
113 | - 'grid-row': `${index + 1} / ${index + 2}`, | ||
114 | - 'grid-column': '1 / 2' | ||
115 | - } | ||
116 | - }, day.substr(0, 1)) | ||
81 … | +function getWeekFormat (styles) { | ||
82 … | + if (styles.weekFormat && !['rows', 'columns'].includes(styles.weekFormat)) { | ||
83 … | + throw new Error('marama styles.weekFormat must be either "rows" or "columns"') | ||
84 … | + } | ||
85 … | + return styles.weekFormat || DEFAULT_FORMAT | ||
117 | 86 … | } | |
118 | 87 … | ||
119 | -function getDay (date) { | ||
120 | - const dayIndex = date.getDay() | ||
121 | - return dayIndex === 0 ? 7 : dayIndex | ||
122 | - | ||
123 | - // Weeks run 0...6 (Sun - Sat) | ||
124 | - // this shifts those days around by 1 | ||
125 | -} | ||
126 | - | ||
127 | 88 … | function startOfDay (d = new Date()) { | |
128 | 89 … | return new Date(d.getFullYear(), d.getMonth(), d.getDate()) | |
129 | 90 … | } | |
130 | 91 … |
lib/styles-inject.js | ||
---|---|---|
@@ -1,12 +1,8 @@ | ||
1 | 1 … | const { h } = require('mutant') |
2 | -const getCSS = require('./styles-compile') | |
2 … | +const getCSS = require('./get-css') | |
3 | 3 … | |
4 | 4 … | module.exports = () => { |
5 | - getCSS((err, css) => { | |
6 | - if (err) return console.error(err) | |
7 | - | |
8 | - document.head.appendChild( | |
9 | - h('style', { innerHTML: css }) | |
10 | - ) | |
11 | - }) | |
5 … | + document.head.appendChild( | |
6 … | + h('style', { innerHTML: getCSS() }) | |
7 … | + ) | |
12 | 8 … | } |
lib/styles-write.js | ||
---|---|---|
@@ -1,18 +1,14 @@ | ||
1 | 1 … | const getCSS = require('./styles-compile') |
2 | 2 … | const fs = require('fs') |
3 | 3 … | const { join } = require('path') |
4 | 4 … | |
5 | -function buildStyles () { | |
6 | - getCSS((err, css) => { | |
5 … | +function stylesWrite () { | |
6 … | + fs.writeFile(join(__dirname, '../marama.css'), getCSS(), (err, done) => { | |
7 | 7 … | if (err) throw err |
8 | - | |
9 | - fs.writeFile(join(__dirname, '../marama.css'), css, (err, done) => { | |
10 | - if (err) throw err | |
11 | - console.log('mcss built') | |
12 | - }) | |
8 … | + console.log('mcss built') | |
13 | 9 … | }) |
14 | 10 … | } |
15 | 11 … | |
16 | -module.exports = buildStyles | |
12 … | +module.exports = stylesWrite | |
17 | 13 … | |
18 | -if (!module.parent) buildStyles() | |
14 … | +if (!module.parent) stylesWrite() |
lib/styles-compile.js | ||
---|---|---|
@@ -1,20 +1,0 @@ | ||
1 | -const readDir = require('read-directory') | |
2 | -const compile = require('micro-css') | |
3 | -const { join } = require('path') | |
4 | - | |
5 | -module.exports = function compileStyles (cb) { | |
6 | - readDir(join(__dirname, '../styles'), (err, files) => { | |
7 | - if (err) return cb(err) | |
8 | - | |
9 | - const mcss = values(files).join('\n\n') | |
10 | - | |
11 | - console.log(compile(mcss)) | |
12 | - | |
13 | - cb(null, compile(mcss)) | |
14 | - }) | |
15 | -} | |
16 | - | |
17 | -function values (obj) { | |
18 | - return Object.keys(obj) | |
19 | - .map(key => obj[key]) | |
20 | -} |
lib/get-css.js | ||
---|---|---|
@@ -1,0 +1,6 @@ | ||
1 … | +const compile = require('micro-css') | |
2 … | +const getMCSS = require('./get-mcss') | |
3 … | + | |
4 … | +module.exports = function getCSS () { | |
5 … | + return compile(getMCSS()) | |
6 … | +} |
lib/get-day.js | ||
---|---|---|
@@ -1,0 +1,7 @@ | ||
1 … | +module.exports = function getDay (date) { | |
2 … | + const dayIndex = date.getDay() | |
3 … | + return dayIndex === 0 ? 7 : dayIndex | |
4 … | + | |
5 … | + // Weeks run 0...6 (Sun - Sat) | |
6 … | + // this shifts those days around by 1 | |
7 … | +} |
lib/get-mcss.js | ||
---|---|---|
@@ -1,0 +1,13 @@ | ||
1 … | +const readDir = require('read-directory') | |
2 … | +const { join } = require('path') | |
3 … | + | |
4 … | +module.exports = function getMcss (cb) { | |
5 … | + const collection = readDir.sync(join(__dirname, '../styles')) | |
6 … | + | |
7 … | + return values(collection).reverse().join('\n\n') | |
8 … | +} | |
9 … | + | |
10 … | +function values (obj) { | |
11 … | + return Object.keys(obj) | |
12 … | + .map(key => obj[key]) | |
13 … | +} |
styles/marama-day-name.mcss | ||
---|---|---|
@@ -1,13 +1,0 @@ | ||
1 | -MaramaDayName { | |
2 | - color: hsl(0, 0%, 40%) | |
3 | - font-family: arial | |
4 | - font-size: calc(2 * var(--day-radius) - 3px) | |
5 | - /* line-height: calc(2 * var(--day-radius) - 2px) */ | |
6 | - | |
7 | - width: calc(2 * var(--day-radius)) | |
8 | - height: calc(2 * var(--day-radius)) | |
9 | - | |
10 | - display: flex | |
11 | - align-items: center | |
12 | - justify-content: center | |
13 | -} |
styles/day-label.mcss | ||
---|---|---|
@@ -1,0 +1,12 @@ | ||
1 … | +MaramaDayLabel { | |
2 … | + color: hsl(0, 0%, 40%) | |
3 … | + font-family: arial | |
4 … | + font-size: calc(2 * var(--tile-radius) - 4px) | |
5 … | + | |
6 … | + width: calc(2 * var(--tile-radius)) | |
7 … | + height: calc(2 * var(--tile-radius)) | |
8 … | + | |
9 … | + display: flex | |
10 … | + align-items: center | |
11 … | + justify-content: center | |
12 … | +} |
styles/marama-day-tile.mcss | ||
---|---|---|
@@ -1,52 +1,0 @@ | ||
1 | -MaramaDayTile { | |
2 | - width: calc(2 * var(--day-radius)) | |
3 | - height: calc(2 * var(--day-radius)) | |
4 | - cursor: pointer | |
5 | - | |
6 | - border-radius: var(--day-border-radius) | |
7 | - | |
8 | - display: flex | |
9 | - justify-content: center | |
10 | - align-items: center | |
11 | - | |
12 | - -past { | |
13 | - background: hsl(0, 0%, 20%) | |
14 | - } | |
15 | - | |
16 | - -future { | |
17 | - background: hsl(0, 0%, 80%) | |
18 | - } | |
19 | - | |
20 | - -range { | |
21 | - background: deeppink | |
22 | - | |
23 | - -future { | |
24 | - background: deepskyblue | |
25 | - } | |
26 | - } | |
27 | - | |
28 | - -events { | |
29 | - /* border-radius: var(--day-radius) */ | |
30 | - /* background: hsla(277, 57%, 45%, 1) */ | |
31 | - | |
32 | - div.dot { | |
33 | - background: none | |
34 | - width: 4px | |
35 | - height: 4px | |
36 | - border: 1px solid #fff | |
37 | - border-radius: 8px | |
38 | - } | |
39 | - | |
40 | - -past { | |
41 | - } | |
42 | - | |
43 | - -attending { | |
44 | - div.dot { | |
45 | - background: #fff | |
46 | - width: 6px | |
47 | - height: 6px | |
48 | - border: none | |
49 | - } | |
50 | - } | |
51 | - } | |
52 | -} |
styles/day-tile.mcss | ||
---|---|---|
@@ -1,0 +1,46 @@ | ||
1 … | +MaramaDayTile { | |
2 … | + width: calc(2 * var(--tile-radius)) | |
3 … | + height: calc(2 * var(--tile-radius)) | |
4 … | + cursor: pointer | |
5 … | + | |
6 … | + border-radius: 2px | |
7 … | + | |
8 … | + display: flex | |
9 … | + justify-content: center | |
10 … | + align-items: center | |
11 … | + | |
12 … | + -past { | |
13 … | + background: hsl(0, 0%, 20%) | |
14 … | + } | |
15 … | + | |
16 … | + -future { | |
17 … | + background: hsl(0, 0%, 80%) | |
18 … | + } | |
19 … | + | |
20 … | + -range { | |
21 … | + background: deeppink | |
22 … | + | |
23 … | + -future { | |
24 … | + background: deepskyblue | |
25 … | + } | |
26 … | + } | |
27 … | + | |
28 … | + -events { | |
29 … | + div.dot { | |
30 … | + background: none | |
31 … | + width: calc(2 * var(--dot-radius) - 2 * var(--dot-border)) | |
32 … | + height: calc(2 * var(--dot-radius) - 2 * var(--dot-border)) | |
33 … | + border: var(--dot-border) solid #fff | |
34 … | + border-radius: calc(2 * var(--dot-radius)) | |
35 … | + } | |
36 … | + | |
37 … | + -attending { | |
38 … | + div.dot { | |
39 … | + background: #fff | |
40 … | + width: calc(2 * var(--dot-radius)) | |
41 … | + height: calc(2 * var(--dot-radius)) | |
42 … | + border: none | |
43 … | + } | |
44 … | + } | |
45 … | + } | |
46 … | +} |
styles/marama.mcss | ||
---|---|---|
@@ -1,24 +1,0 @@ | ||
1 | -Marama { | |
2 | - --day-radius: 6px | |
3 | - --day-border-radius: 2px | |
4 | - --day-gap: 1px | |
5 | - | |
6 | - width: calc(7 * 2 * var(--day-radius) + 6 * var(--day-gap)) | |
7 | - /* max of 6 weeks + day labels, with gaps between each */ | |
8 | - | |
9 | - div.month-name { | |
10 | - font-size: 20px | |
11 | - font-weight: bold | |
12 | - text-align: left | |
13 | - cursor: pointer | |
14 | - margin-bottom: 5px | |
15 | - } | |
16 | - | |
17 | - div.days { | |
18 | - grid-gap: var(--day-gap) | |
19 | - justify-content: start | |
20 | - align-content: start | |
21 | - | |
22 | - div.MaramaDay {} | |
23 | - } | |
24 | -} |
styles/index.mcss | ||
---|---|---|
@@ -1,0 +1,17 @@ | ||
1 … | +Marama { | |
2 … | + div.month-name { | |
3 … | + font-size: 20px | |
4 … | + font-weight: bold | |
5 … | + text-align: left | |
6 … | + cursor: pointer | |
7 … | + margin-bottom: 5px | |
8 … | + } | |
9 … | + | |
10 … | + div.days { | |
11 … | + grid-gap: var(--tile-gap) | |
12 … | + justify-content: start | |
13 … | + align-content: start | |
14 … | + | |
15 … | + div.MaramaDay {} | |
16 … | + } | |
17 … | +} |
test/index.js | ||
---|---|---|
@@ -1,18 +1,0 @@ | ||
1 | -// run this from the terminal using : | |
2 | -// npx electro test/index.js | |
3 | - | |
4 | -const { h } = require('mutant') | |
5 | - | |
6 | -const Marama = require('../') | |
7 | -require('../lib/styles-inject')() | |
8 | - | |
9 | -const page = h('div', | |
10 | - { | |
11 | - style: { | |
12 | - margin: '4rem' | |
13 | - } | |
14 | - }, | |
15 | - Marama() | |
16 | -) | |
17 | - | |
18 | -document.body.appendChild(page) |
test/index-classic-cal.js | ||
---|---|---|
@@ -1,0 +1,37 @@ | ||
1 … | +// run this from the terminal using : | |
2 … | +// npx electro test/index-classic-cal.js | |
3 … | + | |
4 … | +const { h } = require('mutant') | |
5 … | + | |
6 … | +const Marama = require('../') | |
7 … | +require('../lib/styles-inject')() | |
8 … | + | |
9 … | +const marama = Marama({ | |
10 … | + today: new Date(2018, 6, 12), | |
11 … | + events: [ | |
12 … | + { date: new Date(2018, 3, 4), data: { attending: true } }, | |
13 … | + { date: new Date(2018, 6, 5), data: { attending: true } }, | |
14 … | + { date: new Date(2018, 6, 7), data: { attending: false } }, | |
15 … | + { date: new Date(2018, 6, 17), data: { attending: true } }, | |
16 … | + { date: new Date(2018, 6, 21), data: { attending: false } }, | |
17 … | + { date: new Date(2018, 6, 27), data: { attending: true } } | |
18 … | + ], | |
19 … | + range: { | |
20 … | + gte: new Date(2018, 6, 9), | |
21 … | + lt: new Date(2018, 6, 23) | |
22 … | + }, | |
23 … | + styles: { | |
24 … | + weekFormat: 'rows', | |
25 … | + tileRadius: 18, | |
26 … | + tileGap: 4 | |
27 … | + } | |
28 … | +}) | |
29 … | + | |
30 … | +const page = h('div', | |
31 … | + { | |
32 … | + style: { margin: '3rem' } | |
33 … | + }, | |
34 … | + marama | |
35 … | +) | |
36 … | + | |
37 … | +document.body.appendChild(page) |
test/index-letnice.js | ||
---|---|---|
@@ -1,0 +1,32 @@ | ||
1 … | +// run this from the terminal using : | |
2 … | +// npx electro test/index-letnice.js | |
3 … | + | |
4 … | +const { h } = require('mutant') | |
5 … | + | |
6 … | +const Marama = require('../') | |
7 … | +require('../lib/styles-inject')() | |
8 … | + | |
9 … | +const marama = Marama({ | |
10 … | + today: new Date(2018, 7, 19), | |
11 … | + events: [ | |
12 … | + { date: new Date(2018, 3, 4), data: { attending: true } }, | |
13 … | + { date: new Date(2018, 7, 19), data: { attending: true } }, | |
14 … | + { date: new Date(2018, 7, 21), data: { attending: false } } | |
15 … | + ], | |
16 … | + range: { | |
17 … | + gte: new Date(2018, 7, 13), | |
18 … | + lt: new Date(2018, 7, 20) | |
19 … | + }, | |
20 … | + styles: { | |
21 … | + weekFormat: 'columns' | |
22 … | + } | |
23 … | +}) | |
24 … | + | |
25 … | +const page = h('div', | |
26 … | + { | |
27 … | + style: { margin: '3rem' } | |
28 … | + }, | |
29 … | + marama | |
30 … | +) | |
31 … | + | |
32 … | +document.body.appendChild(page) |
day-label.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 … | +const h = require('mutant/h') | |
2 … | + | |
3 … | +module.exports = function DayLabel (day, index, weekFormat) { | |
4 … | + const style = weekFormat === 'rows' | |
5 … | + ? { | |
6 … | + 'grid-row': '1 / 2', | |
7 … | + 'grid-column': `${index + 1} / ${index + 2}` | |
8 … | + } | |
9 … | + : { | |
10 … | + 'grid-row': `${index + 1} / ${index + 2}`, | |
11 … | + 'grid-column': '1 / 2' | |
12 … | + } | |
13 … | + | |
14 … | + return h('MaramaDayLabel', { style }, day.substr(0, 1)) | |
15 … | +} |
day-tile.js | ||
---|---|---|
@@ -1,0 +1,72 @@ | ||
1 … | +const h = require('mutant/h') | |
2 … | +const getDay = require('./lib/get-day') | |
3 … | + | |
4 … | +module.exports = function Day ({ today, year, monthIndex, day, offset, weekFormat, events, range, setRange }) { | |
5 … | + const date = new Date(year, monthIndex, day) | |
6 … | + const dateEnd = new Date(year, monthIndex, day + 1) | |
7 … | + const weekday = getDay(date) | |
8 … | + const week = Math.ceil((day + offset) / 7) | |
9 … | + | |
10 … | + const eventsOnDay = events.filter(e => { | |
11 … | + return e.date >= date && e.date < dateEnd | |
12 … | + }) | |
13 … | + | |
14 … | + const attending = eventsOnDay.some(e => { | |
15 … | + return e.data.attending | |
16 … | + }) | |
17 … | + | |
18 … | + const style = weekFormat === 'rows' | |
19 … | + ? { | |
20 … | + 'grid-row': `${week + 1} / ${week + 2}`, // new weeks on each col (leaving space for labels col) | |
21 … | + 'grid-column': `${weekday} / ${weekday + 1}` // new weekdays on each row | |
22 … | + // moved by 1 to make space for labels | |
23 … | + } | |
24 … | + : { | |
25 … | + 'grid-row': `${weekday} / ${weekday + 1}`, // new weekdays on each row | |
26 … | + 'grid-column': `${week + 1} / ${week + 2}` // new weeks on each col (leaving space for labels col) | |
27 … | + } | |
28 … | + | |
29 … | + const opts = { | |
30 … | + attributes: { | |
31 … | + 'title': `${year}-${monthIndex + 1}-${day}`, | |
32 … | + 'data-date': `${year}-${monthIndex + 1}-${day}` | |
33 … | + }, | |
34 … | + style, | |
35 … | + classList: [ | |
36 … | + date < today ? '-past' : '-future', | |
37 … | + eventsOnDay.length ? '-events' : '', | |
38 … | + inRange(range, date) ? '-range' : '', | |
39 … | + attending ? '-attending' : '' | |
40 … | + ], | |
41 … | + 'ev-click': handleRangeSetting | |
42 … | + } | |
43 … | + | |
44 … | + if (!eventsOnDay.length) return h('MaramaDayTile', opts) | |
45 … | + | |
46 … | + return h('MaramaDayTile', opts, [ | |
47 … | + // TODO add awareness of whether I'm going to events | |
48 … | + // TODO try a FontAwesome circle | |
49 … | + h('div.dot', [ | |
50 … | + // Math.random() > 0.3 ? h('div') : '' | |
51 … | + ]) | |
52 … | + ]) | |
53 … | + | |
54 … | + function handleRangeSetting (ev) { | |
55 … | + if (ev.shiftKey && range && range.lt) { | |
56 … | + dateEnd >= range.lt | |
57 … | + ? setRange({ lt: dateEnd }) | |
58 … | + : setRange({ gte: date }) | |
59 … | + return | |
60 … | + } | |
61 … | + | |
62 … | + setRange({ | |
63 … | + gte: date, | |
64 … | + lt: dateEnd | |
65 … | + }) | |
66 … | + } | |
67 … | +} | |
68 … | + | |
69 … | +function inRange (range, date) { | |
70 … | + if (!range || (!range.gte && !range.lt)) return false | |
71 … | + return (date >= range.gte) && (date < range.lt) | |
72 … | +} |
marama.jpg |
---|
Built with git-ssb-web