@preset.nz/app-kit 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +4 -8
- package/src-ts/CommandToolbar.tsx +6 -3
- package/src-ts/commands.ts +6 -3
- package/src-ts/core.ts +6 -6
- package/src-ts/document.ts +4 -2
- package/src-ts/history.ts +1 -1
- package/src-ts/index.ts +3 -2
- package/src-ts/store.ts +1 -1
- package/src-ts/text.ts +13 -3
- package/src-ts/useMenuSync.ts +2 -3
package/README.md
CHANGED
|
@@ -96,4 +96,4 @@ In Vite, add `@preset.nz/app-kit` (with `react`, `react-dom`, `@tauri-apps/api`,
|
|
|
96
96
|
|
|
97
97
|
## Development
|
|
98
98
|
|
|
99
|
-
`just check` runs `cargo fmt --check`, clippy, `cargo test`, `tsc` and
|
|
99
|
+
`just check` runs `cargo fmt --check`, clippy, `cargo test`, `tsc` and Biome. MIT.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@preset.nz/app-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "The behaviour of a preset.nz desktop app: command table, menu sync, Undo and Redo titles, text-field undo routing and a selection store, over the preset-app-kit Rust crate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -22,19 +22,15 @@
|
|
|
22
22
|
"react": "^19"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@
|
|
25
|
+
"@biomejs/biome": "^2.5.15",
|
|
26
26
|
"@preset.nz/ux-kit": "^0.1.0",
|
|
27
27
|
"@tauri-apps/api": "^2.11.1",
|
|
28
28
|
"@types/react": "^19.2.17",
|
|
29
29
|
"@types/react-dom": "^19.2.3",
|
|
30
|
-
"
|
|
31
|
-
"eslint-plugin-react-hooks": "^7.1.1",
|
|
32
|
-
"eslint-plugin-react-refresh": "^0.5.3",
|
|
33
|
-
"globals": "^16.5.0",
|
|
30
|
+
"lefthook": "^2.1.17",
|
|
34
31
|
"react": "^19.2.7",
|
|
35
32
|
"react-dom": "^19.2.7",
|
|
36
|
-
"typescript": "~5.9.3"
|
|
37
|
-
"typescript-eslint": "^8.61.1"
|
|
33
|
+
"typescript": "~5.9.3"
|
|
38
34
|
},
|
|
39
35
|
"peerDependenciesMeta": {
|
|
40
36
|
"@preset.nz/ux-kit": {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { ComponentProps } from "react"
|
|
2
1
|
import { ToolbarItems } from "@preset.nz/ux-kit"
|
|
2
|
+
import type { ComponentProps } from "react"
|
|
3
3
|
|
|
4
4
|
import type { Command } from "./commands"
|
|
5
|
-
import {
|
|
5
|
+
import { type ToolbarLayout, toItems } from "./toolbar"
|
|
6
6
|
|
|
7
|
-
type Props = Omit<
|
|
7
|
+
type Props = Omit<
|
|
8
|
+
ComponentProps<typeof ToolbarItems>,
|
|
9
|
+
"groups" | "leading" | "trailing" | "onCommand"
|
|
10
|
+
> & {
|
|
8
11
|
commands: Command[]
|
|
9
12
|
layout: ToolbarLayout
|
|
10
13
|
/** From `useCommands`: runs the command the menu would. */
|
package/src-ts/commands.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useState, type ReactNode } from "react"
|
|
2
1
|
import { invoke } from "@tauri-apps/api/core"
|
|
2
|
+
import { type ReactNode, useCallback, useEffect, useMemo, useState } from "react"
|
|
3
3
|
|
|
4
|
-
import { redo, undo, useHistory
|
|
4
|
+
import { type HistoryState, redo, undo, useHistory } from "./history"
|
|
5
5
|
import { useTextUndo } from "./text"
|
|
6
6
|
import { useMenuSync } from "./useMenuSync"
|
|
7
7
|
|
|
@@ -133,6 +133,9 @@ export function useCommands(bindings: Record<string, Binding>) {
|
|
|
133
133
|
[commands],
|
|
134
134
|
)
|
|
135
135
|
/** A command's display shortcut, for anything that shows one (a panel header's tooltip). */
|
|
136
|
-
const shortcut = useCallback(
|
|
136
|
+
const shortcut = useCallback(
|
|
137
|
+
(id: string) => table?.find((s) => s.id === id)?.shortcut ?? undefined,
|
|
138
|
+
[table],
|
|
139
|
+
)
|
|
137
140
|
return { commands, run, shortcut, history }
|
|
138
141
|
}
|
package/src-ts/core.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// The menu half of app-kit: commands, history, text-field undo, selection and stores, with
|
|
2
2
|
// no dependency on ux-kit. `index.ts` adds the toolbar bridge on top.
|
|
3
3
|
export {
|
|
4
|
-
bindCommands,
|
|
5
|
-
useCommands,
|
|
6
|
-
useCommandTable,
|
|
7
4
|
type Binding,
|
|
5
|
+
bindCommands,
|
|
8
6
|
type Command,
|
|
9
7
|
type CommandSpec,
|
|
8
|
+
useCommands,
|
|
9
|
+
useCommandTable,
|
|
10
10
|
} from "./commands"
|
|
11
|
-
export { useDocument, useDocumentNotes
|
|
12
|
-
export { redo, undo, useHistory
|
|
11
|
+
export { type DocumentState, useDocument, useDocumentNotes } from "./document"
|
|
12
|
+
export { type HistoryState, redo, undo, useHistory } from "./history"
|
|
13
13
|
export { nativeContextMenu } from "./nativeContextMenu"
|
|
14
14
|
export {
|
|
15
15
|
createMultiSelection,
|
|
@@ -18,6 +18,6 @@ export {
|
|
|
18
18
|
type MultiSelection,
|
|
19
19
|
type Selection,
|
|
20
20
|
} from "./selection"
|
|
21
|
-
export { createStore,
|
|
21
|
+
export { createStore, type Store, useStore } from "./store"
|
|
22
22
|
export { blurField, isTextField, useTextFocus, useTextUndo } from "./text"
|
|
23
23
|
export { useMenuSync } from "./useMenuSync"
|
package/src-ts/document.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react"
|
|
2
1
|
import { invoke } from "@tauri-apps/api/core"
|
|
3
2
|
import { listen } from "@tauri-apps/api/event"
|
|
3
|
+
import { useEffect, useRef, useState } from "react"
|
|
4
4
|
|
|
5
5
|
/** The document as Rust reports it (`DocumentState`): from `app_kit_document`, pushed as `app-kit://document`. */
|
|
6
6
|
export interface DocumentState {
|
|
@@ -47,7 +47,9 @@ export function useDocumentNotes(onNote: (message: string) => void): void {
|
|
|
47
47
|
// while still mounted: taking them is once-only, so an unmounted effect (StrictMode mounts
|
|
48
48
|
// twice in dev) must leave them for the next.
|
|
49
49
|
un.then(() => (live ? invoke<string[]>("app_kit_document_note") : [])).then(
|
|
50
|
-
(held) =>
|
|
50
|
+
(held) => {
|
|
51
|
+
if (live) for (const m of held) handler.current(m)
|
|
52
|
+
},
|
|
51
53
|
() => {},
|
|
52
54
|
)
|
|
53
55
|
return () => {
|
package/src-ts/history.ts
CHANGED
package/src-ts/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Everything: the core plus the ux-kit toolbar bridge. Apps without ux-kit import
|
|
2
2
|
// "@preset.nz/app-kit/core" instead.
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
export { CommandToolbar } from "./CommandToolbar"
|
|
5
|
-
export
|
|
5
|
+
export * from "./core"
|
|
6
|
+
export { type ToolbarLayout, toItems } from "./toolbar"
|
package/src-ts/store.ts
CHANGED
package/src-ts/text.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { useEffect, useState } from "react"
|
|
2
1
|
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
|
2
|
+
import { useEffect, useState } from "react"
|
|
3
3
|
|
|
4
|
-
const TEXT_INPUT_TYPES = new Set([
|
|
4
|
+
const TEXT_INPUT_TYPES = new Set([
|
|
5
|
+
"",
|
|
6
|
+
"text",
|
|
7
|
+
"search",
|
|
8
|
+
"url",
|
|
9
|
+
"email",
|
|
10
|
+
"tel",
|
|
11
|
+
"password",
|
|
12
|
+
"number",
|
|
13
|
+
])
|
|
5
14
|
|
|
6
15
|
/** True for elements that have their own typing undo: text inputs, textareas, contenteditable. */
|
|
7
16
|
export function isTextField(el: EventTarget | Element | null): boolean {
|
|
8
17
|
if (!(el instanceof HTMLElement)) return false
|
|
9
18
|
if (el instanceof HTMLTextAreaElement) return !el.readOnly && !el.disabled
|
|
10
|
-
if (el instanceof HTMLInputElement)
|
|
19
|
+
if (el instanceof HTMLInputElement)
|
|
20
|
+
return TEXT_INPUT_TYPES.has(el.type) && !el.readOnly && !el.disabled
|
|
11
21
|
return el.isContentEditable
|
|
12
22
|
}
|
|
13
23
|
|
package/src-ts/useMenuSync.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react"
|
|
2
1
|
import { invoke } from "@tauri-apps/api/core"
|
|
3
2
|
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
|
3
|
+
import { useEffect, useRef } from "react"
|
|
4
4
|
|
|
5
5
|
import type { Command } from "./commands"
|
|
6
6
|
|
|
@@ -31,12 +31,11 @@ export function useMenuSync(commands: Command[], textFocus: boolean) {
|
|
|
31
31
|
}, [])
|
|
32
32
|
|
|
33
33
|
const key = JSON.stringify(commands.map((c) => [c.id, c.enabled, c.pressed])) + textFocus
|
|
34
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `key` stands for the commands' menu-relevant state (and textFocus); `latest` holds the commands themselves.
|
|
34
35
|
useEffect(() => {
|
|
35
36
|
const states = latest.current
|
|
36
37
|
.filter((c) => !RUST_GATED_IDS.has(c.id))
|
|
37
38
|
.map((c) => ({ id: c.id, enabled: c.enabled, checked: c.pressed }))
|
|
38
39
|
invoke("app_kit_menu_state", { states, textFocus }).catch(() => {})
|
|
39
|
-
// `key` stands for the commands' menu-relevant state; `latest` holds the commands.
|
|
40
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
40
|
}, [key])
|
|
42
41
|
}
|