Skip to content

Commit 6e5fb4c

Browse files
committed
feat: interactive hex color pills and DD-MM-YYYY date support
1 parent d6d58ca commit 6e5fb4c

5 files changed

Lines changed: 75 additions & 11 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Summon it with a hotkey. Jot. Dismiss. It stays out of your way until you need i
1414
- **Lives in the background** — no dock icon, no window chrome. Press your hotkey, it appears on whatever screen your mouse is on. Click away, it vanishes.
1515
- **Reactive math & variables** — define `/var x = 10`, write `x * 3 =`, get `30`. Change the variable, everything updates. Works across notes with `/globvar`.
1616
- **Inline AI** — type `/ai <prompt>`, press enter, get the answer inserted directly into your note. No sidebar, no context switch.
17-
- **Auto-highlights hex colors, dates, and times**`#D97757` renders as a color pill. `2024-05-31` gets highlighted. Useful at a glance.
17+
- **Auto-highlights hex colors, dates, and times**`#D97757` renders as a color pill. `31-05-2024` gets highlighted. Useful at a glance.
1818
- **Interactive Checkboxes** — Type `/check` to create an interactive checkbox that strikes through text when clicked.
1919
- **Tasks & Reminders** — Type `/task` followed by `@ 1d2h` to set a due date. Press `Cmd+T` to open a unified Tasks view that tracks all your pending items and due times.
2020
- **Tags & folders**`!tagname` for tags, `/` in note titles for folders. Simple conventions, no UI overhead.

electron/main.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,13 @@ fs.writeFileSync(
137137
PaperCache automatically recognizes and highlights common formats so you can easily spot them in your notes.
138138
139139
## Colors
140-
Type any hex color, and it will be highlighted with a matching pill!
140+
Type any hex color, and it will be highlighted with a matching pill! You can click the small colored circle inside the pill to quickly copy the hex code to your clipboard.
141141
*Example use:* #D97757 or #3B82F6 or #10B981
142142
143143
## Dates & Times
144144
Dates and times are also highlighted to help you keep track of your schedule.
145145
*Example use:*
146-
Meeting on 2024-05-31 at 14:30.
146+
Meeting on 31-05-2024 at 14:30.
147147
148148
Next: [Tags](/file commands/tags.md)
149149
`,
@@ -177,7 +177,7 @@ If you want to set a deadline, just type \` @ \` followed by a time shorthand af
177177
*Example use:*
178178
/task Buy groceries @ 2h
179179
180-
PaperCache understands shorthands like \`2d\`, \`3h45m\`, \`tmrw\`, or even exact dates like \`2024-12-31 15:00\`.
180+
PaperCache understands shorthands like \`2d\`, \`3h45m\`, \`tmrw\`, or even exact dates like \`31-12-2024 15:00\`.
181181
Once you set a task, press \`Cmd+T\` (or \`Ctrl+T\`) to open the Tasks Page and see everything that's due!
182182
Overdue tasks will automatically highlight in red.
183183

src/App.css

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ body {
516516

517517
/* Format Pills */
518518
.cm-color-pill {
519-
display: inline-block;
519+
display: inline-flex;
520+
align-items: center;
520521
background-color: color-mix(in srgb, var(--pill-color) 15%, transparent);
521522
color: color-mix(in srgb, var(--pill-color) 80%, black);
522523
padding: 0px 6px;
@@ -528,6 +529,23 @@ body {
528529
border: 1px solid color-mix(in srgb, var(--pill-color) 30%, transparent);
529530
}
530531

532+
@keyframes color-pill-flash {
533+
0% {
534+
background-color: var(--pill-color);
535+
color: #fff;
536+
border-color: var(--pill-color);
537+
}
538+
100% {
539+
background-color: color-mix(in srgb, var(--pill-color) 15%, transparent);
540+
color: color-mix(in srgb, var(--pill-color) 80%, black);
541+
border-color: color-mix(in srgb, var(--pill-color) 30%, transparent);
542+
}
543+
}
544+
545+
.cm-color-pill.flash {
546+
animation: color-pill-flash 0.5s ease-out;
547+
}
548+
531549
.cm-color-highlight {
532550
color: color-mix(in srgb, var(--pill-color) 80%, black);
533551
background-color: color-mix(in srgb, var(--pill-color) 10%, transparent);

src/lib/editor/plugins.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
VariableWidget,
99
ReminderWidget,
1010
ContextWidget,
11+
ColorWidget,
1112
} from './widgets'
1213

1314
export const numberPlugin = ViewPlugin.fromClass(
@@ -244,10 +245,7 @@ export const hideMarkdownPlugin = ViewPlugin.fromClass(
244245
decos.push({
245246
from: start,
246247
to: end,
247-
deco: Decoration.mark({
248-
class: 'cm-color-pill',
249-
attributes: { style: `--pill-color: ${match[0]}` },
250-
}),
248+
deco: Decoration.replace({ widget: new ColorWidget(match[0]) }),
251249
})
252250
} else {
253251
decos.push({
@@ -261,8 +259,8 @@ export const hideMarkdownPlugin = ViewPlugin.fromClass(
261259
}
262260
}
263261

264-
// Date Formats (YYYY-MM-DD)
265-
const reDate = /\b\d{4}-\d{2}-\d{2}\b/g
262+
// Date Formats (YYYY-MM-DD or DD-MM-YYYY)
263+
const reDate = /\b(?:\d{4}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})\b/g
266264
while ((match = reDate.exec(text)) !== null) {
267265
const start = from + match.index
268266
const end = start + match[0].length

src/lib/editor/widgets.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,54 @@ export class VariableWidget extends WidgetType {
104104
}
105105
}
106106

107+
export class ColorWidget extends WidgetType {
108+
color: string
109+
constructor(color: string) {
110+
super()
111+
this.color = color
112+
}
113+
eq(other: ColorWidget) {
114+
return other.color === this.color
115+
}
116+
toDOM() {
117+
const span = document.createElement('span')
118+
span.className = 'cm-color-pill'
119+
span.style.setProperty('--pill-color', this.color)
120+
121+
const circle = document.createElement('span')
122+
circle.className = 'cm-color-circle'
123+
circle.style.backgroundColor = this.color
124+
circle.style.width = '10px'
125+
circle.style.height = '10px'
126+
circle.style.borderRadius = '50%'
127+
circle.style.display = 'inline-block'
128+
circle.style.marginRight = '4px'
129+
circle.style.cursor = 'pointer'
130+
circle.title = 'Copy hex code'
131+
132+
circle.onclick = (e) => {
133+
e.preventDefault()
134+
e.stopPropagation()
135+
navigator.clipboard.writeText(this.color)
136+
137+
span.classList.remove('flash')
138+
void span.offsetWidth // Trigger reflow to restart animation if clicked quickly
139+
span.classList.add('flash')
140+
141+
setTimeout(() => {
142+
span.classList.remove('flash')
143+
}, 500)
144+
}
145+
146+
const text = document.createTextNode(this.color)
147+
148+
span.appendChild(circle)
149+
span.appendChild(text)
150+
151+
return span
152+
}
153+
}
154+
107155
export class ReminderWidget extends WidgetType {
108156
checked: boolean
109157
overdue: boolean

0 commit comments

Comments
 (0)