この記事を見ていて、
便利そうなので、自分も付箋アプリ作ってみようと思いました。
Codexに、
「付箋アプリ作ってほしい」
とだけ入力してみたら、
こんなのができた。

参考にしたブログと、Codexへの命令は、ほぼ似たような、1行だけなのに、
すこし違う付箋アプリができた。(!)
(背景の色だけでなくボタンも、機能も違うのでは)
フォルダの中には、
htmlが1つとreadmeが作成されていた。
htmlソースコードを見ると、素のjavascriptで書かれている。
function visible(){return notes.filter(n=>(view==='archive'?n.archived:!n.archived&&(view!=='pinned'||n.pinned))&&(!filter||n.color===filter)&&(!query||(n.title+' '+n.body).toLocaleLowerCase().includes(query)))}
function counts(){$('#all-count').textContent=notes.filter(n=>!n.archived).length;$('#pin-count').textContent=notes.filter(n=>!n.archived&&n.pinned).length;$('#archive-count').textContent=notes.filter(n=>n.archived).length;$('#visible-count').textContent=visible().length+' 枚の付箋'}
function act(n,fn){fn();n.updated=Date.now();save();render()}
function btn(label,text,fn){const b=document.createElement('button');b.type='button';b.title=label;b.setAttribute('aria-label',label);b.textContent=text;b.onclick=fn;return b}
readmeはこんな感じ。
# ふせん帖
ブラウザで使える付箋アプリです。付箋の追加・編集・色分け・移動・検索・ピン留め・アーカイブができます。
## 使い方
- `outputs` 内の使いたいHTMLファイルをブラウザで開きます。サーバーやインストールは不要で、オフラインでも使えます。
- 「新しい付箋」で追加し、タイトルと本文を直接編集します。付箋の上部をドラッグすると移動できます。
- 左下の「バックアップを書き出す」「バックアップを読み込む」で、JSONファイルとして保存・復元できます。細い画面では ↗ と ↙ のボタンです。
## データの保存
付箋はブラウザ内のlocalStorageに自動保存され、通常はブラウザを閉じても残ります。端末間では同期されません。
ブラウザのデータ削除やシークレットモードの終了で消える場合があります。ブラウザやHTMLファイルの場所を変えると、以前のデータが表示されない場合もあるため、大切なメモはバックアップを書き出してください。読み込みは既存の付箋を残して追加します。
## 開発用ファイル
`work` 内に編集用ソース、`outputs` 内に配布用HTMLがあります。変更時は `AGENTS.md` を参照してください。
jsonでのバックアップの保存まで考慮していてよく考えられている。
同じアプリを、react版や、vue版でも作ってもらった。
ソースを見てみると、vueは読み慣れているので、reactよりはまだマシだが、
それでも、改行なし、インデントなしで見にくい。。。。
こんな感じ。
vue
function remove(n){allowSave=true;const i=notes.value.findIndex(x=>x.id===n.id);notes.value.splice(i,1);notify('付箋を削除しました',()=>{if(!notes.value.some(x=>x.id===n.id))notes.value.splice(i,0,n)})}
function archive(n){const before=n.archived;change(n,{archived:!before});notify(before?'ボードに戻しました':'アーカイブしました',()=>change(n,{archived:before}))}
function undoLast(){if(undo){allowSave=true;undo();undo=null;toast.value=null}}
function startDrag(e,n){if(e.button!==0||e.target.closest('button'))return;e.preventDefault();allowSave=true;front.value=n.id;moving.value=n.id;drag={id:n.id,x:n.x,y:n.y,sx:e.clientX,sy:e.clientY};e.currentTarget.setPointerCapture(e.pointerId)}
function moveDrag(e,n){if(drag?.id!==n.id)return;n.x=Math.max(0,drag.x+e.clientX-drag.sx);n.y=Math.max(0,drag.y+e.clientY-drag.sy)}
function stopDrag(){drag=null;moving.value=null}
「読みにくいので、見やすく直して」
というと、改行とインデントを付けたものが生成された。
vue
function remove(n) {
allowSave = true;
const i = notes.value.findIndex((x) => x.id === n.id);
notes.value.splice(i, 1);
notify("付箋を削除しました", () => {
if (!notes.value.some((x) => x.id === n.id)) notes.value.splice(i, 0, n);
});
}
function archive(n) {
const before = n.archived;
change(n, { archived: !before });
notify(before ? "ボードに戻しました" : "アーカイブしました", () =>
change(n, { archived: before }),
);
}
function undoLast() {
if (undo) {
allowSave = true;
undo();
undo = null;
toast.value = null;
}
}
function startDrag(e, n) {
if (e.button !== 0 || e.target.closest("button")) return;
e.preventDefault();
allowSave = true;
front.value = n.id;
moving.value = n.id;
drag = { id: n.id, x: n.x, y: n.y, sx: e.clientX, sy: e.clientY };
e.currentTarget.setPointerCapture(e.pointerId);
}
react版も、「読みやすくして」と、修正してみたけれど、
そもそもreactのコード読み慣れてないので、
一気に大量にコード出てきたら追うの大変だ。