Skip to content

Commit 1a78802

Browse files
committed
feat(api): enhance getFlagsFromActions and setActions with options for default action selection and close behavior; add overlay helper functions
1 parent 5d8f4f5 commit 1a78802

File tree

4 files changed

+126
-5
lines changed

4 files changed

+126
-5
lines changed

src/api/kit.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,10 @@ function sortArrayByIndex(arr) {
821821
return sortedArr
822822
}
823823

824-
export let getFlagsFromActions = (actions: PromptConfig['actions']) => {
824+
export let getFlagsFromActions = (
825+
actions: PromptConfig['actions'],
826+
options: { defaultActionsId?: string; defaultClose?: boolean } = {},
827+
) => {
825828
let flags: FlagsObject = {}
826829
let indices = new Set()
827830
for (let a of actions as Action[]) {
@@ -831,7 +834,15 @@ export let getFlagsFromActions = (actions: PromptConfig['actions']) => {
831834
}
832835
let groups = new Set()
833836
if (Array.isArray(actions)) {
834-
const sortedActions = sortArrayByIndex(actions)
837+
let sortedActions = sortArrayByIndex(actions)
838+
// Optional: preselect a default by moving it to the front without changing explicit indices
839+
if (options?.defaultActionsId) {
840+
const i = sortedActions.findIndex((a: any) => (a?.flag || a?.name) === options.defaultActionsId)
841+
if (i > 0) {
842+
const [def] = sortedActions.splice(i, 1)
843+
sortedActions.unshift(def)
844+
}
845+
}
835846
for (let i = 0; i < sortedActions.length; i++) {
836847
let action = sortedActions[i]
837848
if (typeof action === 'string') {
@@ -847,7 +858,8 @@ export let getFlagsFromActions = (actions: PromptConfig['actions']) => {
847858
let flagAction = {
848859
flag: action.flag || action.name,
849860
index: i,
850-
close: true,
861+
// Default close behavior is true (legacy). Allow override via options or per-action.
862+
close: typeof options?.defaultClose === 'boolean' ? options.defaultClose : true,
851863
...action,
852864
hasAction: !!action?.onAction,
853865
bar: action?.visible ? 'right' : ''
@@ -861,8 +873,14 @@ export let getFlagsFromActions = (actions: PromptConfig['actions']) => {
861873
return flags
862874
}
863875

864-
global.setActions = async (actions: Action[], options = {}) => {
865-
let flags = getFlagsFromActions(actions)
876+
global.setActions = async (
877+
actions: Action[],
878+
options: { name?: string; placeholder?: string; active?: string; defaultActionsId?: string; defaultClose?: boolean } = {},
879+
) => {
880+
const flags = getFlagsFromActions(actions, {
881+
defaultActionsId: options?.defaultActionsId,
882+
defaultClose: options?.defaultClose,
883+
})
866884
await setFlags(flags, options)
867885
}
868886

@@ -878,6 +896,20 @@ global.setFlagValue = (value: any) => {
878896
return global.sendWait(Channel.SET_FLAG_VALUE, value)
879897
}
880898

899+
// Overlay-aligned helpers (non-breaking wrappers)
900+
global.openActionsOverlay = async (opts: { source?: 'choice' | 'input' | 'ui' | 'editor'; flag?: string } = {}) => {
901+
// OPEN_ACTIONS triggers overlay visibility in renderer (via main mapping to SET_FLAG_VALUE 'action')
902+
await global.openActions()
903+
if (typeof opts.flag === 'string' && opts.flag.length > 0) {
904+
// Set payload after opening for better parity with renderer’s split of visibility vs payload
905+
await global.setFlagValue(opts.flag)
906+
}
907+
}
908+
909+
global.closeActionsOverlay = async () => {
910+
await global.closeActions()
911+
}
912+
881913
global.hide = async (hideOptions = {}) => {
882914
await global.sendWait(Channel.HIDE_APP, hideOptions)
883915
if (process.env.KIT_HIDE_DELAY) {

src/editor/types/kit-editor.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ declare module "@johnlindquist/kit" {
366366
name?: string
367367
placeholder?: string
368368
active?: string
369+
/**
370+
* Optional: preselect an action in the overlay by id (flag or name).
371+
*/
372+
defaultActionsId?: string
373+
/**
374+
* Optional: default close behavior for actions (legacy default: true).
375+
* Set false to keep overlay open unless an action explicitly sets close: true.
376+
*/
377+
defaultClose?: boolean
369378
}
370379

371380
export type Action = {
@@ -10912,6 +10921,13 @@ declare module "@johnlindquist/kit" {
1091210921
var setActions: ActionsFn
1091310922
var openActions: () => Promise<void>
1091410923
var closeActions: () => Promise<void>
10924+
/**
10925+
* Open the actions overlay with optional payload.
10926+
* Visibility is separate from payload; when `flag` is provided it will be set after opening.
10927+
*/
10928+
var openActionsOverlay: (opts?: { source?: 'choice' | 'input' | 'ui' | 'editor'; flag?: string }) => Promise<void>
10929+
/** Close the actions overlay. */
10930+
var closeActionsOverlay: () => Promise<void>
1091510931
var setFlagValue: (value: any) => Promise<void>
1091610932
var prepFlags: PrepFlags
1091710933

src/types/core.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,15 @@ export type ActionsConfig = {
353353
name?: string
354354
placeholder?: string
355355
active?: string
356+
/**
357+
* Optional: preselect a
358+
*/
359+
defaultActionsId?: strin
360+
/**
361+
* Optional: default clo
362+
* Set false to keep ove
363+
*/
364+
defaultClose?: boolean
356365
}
357366

358367
export type Action = {

test-sdk/overlay-helpers.test.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import test from 'ava'
2+
import path from 'node:path'
3+
import { pathToFileURL } from 'node:url'
4+
5+
// Helper to import from built .kit output
6+
const importKit = async (...parts) => {
7+
const base = process.env.KIT
8+
if (!base) throw new Error('KIT env var not set for tests')
9+
const fileUrl = pathToFileURL(path.resolve(base, ...parts)).href
10+
return await import(fileUrl)
11+
}
12+
13+
test.serial('openActionsOverlay calls openActions then setFlagValue when flag provided', async (t) => {
14+
// Ensure kit globals are available
15+
await importKit('api', 'kit.js')
16+
17+
const calls = []
18+
global.openActions = async () => calls.push({ fn: 'openActions' })
19+
global.setFlagValue = async (v) => calls.push({ fn: 'setFlagValue', v })
20+
21+
await global.openActionsOverlay({ source: 'editor', flag: 'abc' })
22+
23+
t.deepEqual(calls, [
24+
{ fn: 'openActions' },
25+
{ fn: 'setFlagValue', v: 'abc' },
26+
])
27+
})
28+
29+
test.serial('closeActionsOverlay calls closeActions', async (t) => {
30+
await importKit('api', 'kit.js')
31+
32+
let closed = false
33+
global.closeActions = async () => { closed = true }
34+
35+
await global.closeActionsOverlay()
36+
t.true(closed)
37+
})
38+
39+
test.serial('setActions honors defaultActionsId and defaultClose=false', async (t) => {
40+
await importKit('api', 'kit.js')
41+
42+
let sent = null
43+
global.sendWait = async (channel, payload) => {
44+
if (channel === (await importKit('core', 'enum.js')).Channel.SET_FLAGS) {
45+
sent = payload
46+
}
47+
}
48+
49+
const actions = [
50+
{ name: 'Second', flag: 'second', onAction: () => {} },
51+
{ name: 'First', flag: 'first', onAction: () => {} },
52+
]
53+
54+
await global.setActions(actions, { defaultActionsId: 'first', defaultClose: false })
55+
56+
t.truthy(sent)
57+
const { flags } = sent
58+
// default action should be index 0
59+
t.is(flags.first.index, 0)
60+
// defaultClose=false should apply unless overridden
61+
t.is(flags.first.close, false)
62+
t.is(flags.second.close, false)
63+
})
64+

0 commit comments

Comments
 (0)