Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/desktop",
"productName": "ZenNotes",
"version": "2.54.0",
"version": "2.54.1",
"description": "ZenNotes desktop shell",
"private": true,
"main": "./out/main/index.js",
Expand Down
2 changes: 1 addition & 1 deletion apps/share-viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/share-viewer",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"description": "Read-only renderer for publicly shared ZenNotes, embedded by the zennotes.org website",
"homepage": "https://zennotes.org",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/web",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"description": "ZenNotes web client for self-hosted and hosted deployments",
"homepage": "https://zennotes.org",
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zennotes-monorepo",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"description": "ZenNotes monorepo for desktop, web, and self-hosted server builds",
"packageManager": "npm@10.9.2",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/app-core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/app-core",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"exports": {
"./main": "./src/main.tsx",
Expand Down
13 changes: 12 additions & 1 deletion packages/app-core/src/components/SearchCreateForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ export function SearchCreateForm({
variant="ghost"
size="sm"
className="text-xs"
// Same reason as the footer: a blur here commits the typed tag
// as a chip, and a chips row that wraps moves this button.
onMouseDown={(e) => e.preventDefault()}
onClick={() => onOpenExisting(collision.note)}
>
Open it <kbd className="rounded bg-paper-200 px-1 text-ink-500">Shift+↵</kbd>
Expand Down Expand Up @@ -484,7 +487,15 @@ export function SearchCreateForm({
<kbd className="rounded bg-paper-200 px-1">esc</kbd> back
</span>
</div>
<div className="flex items-center gap-2">
<div
className="flex items-center gap-2"
// The buttons act on click and never need focus. Taking it on
// mousedown would blur the field, unmount the folder or tag list
// under the fields and move this footer before mouseup, so the
// click never fired: the first Create with a tag still typed was
// lost. `create()` counts that text, the way Enter does.
onMouseDown={(e) => e.preventDefault()}
>
<Button variant="secondary" size="sm" onClick={onBack}>
Back
</Button>
Expand Down
56 changes: 56 additions & 0 deletions packages/app-core/src/components/SearchPalette.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,62 @@ describe('SearchPalette: the create row opens a New note form', () => {
expect(createAndOpen).toHaveBeenCalledWith('inbox', '', { title: 'Runbook', tags: ['oncall'] })
})

// A browser moves focus to a pressed button as mousedown's default action,
// unless the event is cancelled; jsdom leaves that step to the test. The
// blur used to unmount the list under the fields and move the footer
// before mouseup, so the click never fired and the first Create was lost.
const press = async (button: HTMLElement, focusedField: HTMLInputElement): Promise<void> => {
await act(async () => {
const uncancelled = button.dispatchEvent(
new MouseEvent('mousedown', { bubbles: true, cancelable: true })
)
if (uncancelled) focusedField.blur()
await Promise.resolve()
})
}

it('pressing the mouse on Create keeps the Tags field focused, so the click lands and the typed tag counts', async () => {
type(search(), 'Runbook')
await key(search(), 'Enter', { shiftKey: true })
focus(field('tags'))
type(field('tags'), 'oncall')
expect(formRows('tag')).toEqual(['oncall'])

await press(createButton(), field('tags'))
expect(document.activeElement).toBe(field('tags'))
expect(formRows('tag')).toEqual(['oncall'])
expect(chipTags()).toEqual([])

await act(async () => {
createButton().click()
await Promise.resolve()
})
expect(createAndOpen).toHaveBeenCalledWith('inbox', '', { title: 'Runbook', tags: ['oncall'] })
})

it('pressing the mouse on Back keeps the folder list until the click', async () => {
type(search(), 'Runbook')
await key(search(), 'Enter', { shiftKey: true })
focus(field('folder'))
expect(formRows('folder')).toEqual(['', 'projects', 'projects/ideas', 'quick', 'archive', 'archive/old'])

const back = [...document.querySelectorAll<HTMLButtonElement>('button')].find(
(b) => b.textContent === 'Back'
)
if (!back) throw new Error('Back button not rendered')
await press(back, field('folder'))
expect(document.activeElement).toBe(field('folder'))
expect(formRows('folder')).toHaveLength(6)

await act(async () => {
back.click()
await Promise.resolve()
})
expect(form()).toBeNull()
expect(search().value).toBe('Runbook')
expect(createAndOpen).not.toHaveBeenCalled()
})

it('Ctrl+Enter or Cmd+Enter creates from any field', async () => {
type(search(), 'Runbook')
await key(search(), 'Enter', { shiftKey: true })
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-contract/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/bridge-contract",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"exports": {
"./bridge": "./src/bridge.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/shared-domain/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/shared-domain",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"exports": {
"./*": "./src/*.ts"
Expand Down
2 changes: 1 addition & 1 deletion packages/shared-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/shared-ui",
"private": true,
"version": "2.54.0",
"version": "2.54.1",
"type": "module",
"exports": {
".": "./src/index.ts"
Expand Down
Loading