@carlesandres/house 0.4.4 → 0.4.6

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.
@@ -82,21 +82,20 @@ export type TokenName = keyof ThemeTokens
82
82
  export type ResolvedTheme = Readonly<Record<TokenName, HexColor>>
83
83
 
84
84
  /**
85
- * The flat color object consumed by Browser/HelpOverlay/index. Keeps the
86
- * existing names (`background`, `surface`, `text`, `syntax`, …) so the
87
- * UI files don't all have to change. Values come from
88
- * `colors.ts`'s adapter, which maps `ResolvedTheme` → this shape.
85
+ * The flat color object consumed by Browser/HelpOverlay/index. Uses the
86
+ * OpenCode-aligned UI token names directly (`background`, `backgroundPanel`,
87
+ * `backgroundElement`, `borderSubtle`, `primary`, `secondary`, …). Values
88
+ * come from `colors.ts`'s adapter, which maps `ResolvedTheme` → this shape.
89
89
  */
90
90
  export interface ColorPalette {
91
91
  readonly background: string
92
- readonly surface: string
92
+ readonly backgroundPanel: string
93
+ readonly backgroundElement: string
93
94
  readonly text: string
94
- readonly textStrong: string
95
95
  readonly textMuted: string
96
96
  readonly border: string
97
97
  readonly borderActive: string
98
- readonly selectedBg: string
99
- readonly selectedBgInactive: string
98
+ readonly borderSubtle: string
100
99
  readonly selectedListItemText: string
101
100
  readonly primary: string
102
101
  readonly secondary: string
package/src/tips.ts ADDED
@@ -0,0 +1,93 @@
1
+ import type { BrowserCtx } from "./keymap/browser.ts"
2
+ import type { KeyBinding } from "./keymap/keymap.ts"
3
+ import { displayKey } from "./keymap/displayKey.ts"
4
+
5
+ export interface TipLine {
6
+ readonly id: string
7
+ readonly text: string
8
+ }
9
+
10
+ interface TipDefinition {
11
+ readonly id: string
12
+ readonly bindingId?: string
13
+ readonly render: (parts: { readonly key: string | null }) => string
14
+ readonly when?: (ctx: BrowserCtx) => boolean
15
+ }
16
+
17
+ const tipDefinitions: readonly TipDefinition[] = [
18
+ {
19
+ id: "filter.start",
20
+ bindingId: "filter.open",
21
+ render: ({ key }) => `Press ${key ?? "/"} to start filtering files by path.`,
22
+ when: (ctx) => ctx.filterQuery.length === 0 && !ctx.filterOpen,
23
+ },
24
+ {
25
+ id: "filter.resume",
26
+ bindingId: "filter.open",
27
+ render: ({ key }) => `Press ${key ?? "/"} to reopen the current filter and keep refining it.`,
28
+ when: (ctx) => ctx.filterQuery.length > 0 && !ctx.filterOpen,
29
+ },
30
+ {
31
+ id: "filter.commit",
32
+ bindingId: "filter.open",
33
+ render: () => "Press Enter in the filter to open the selected match in the reader.",
34
+ when: (ctx) => ctx.filterQuery.length === 0,
35
+ },
36
+ {
37
+ id: "filter.clear",
38
+ bindingId: "filter.clearOrOpen",
39
+ render: ({ key }) => `Press ${key ?? "ctrl+\\"} to clear the current filter and start over.`,
40
+ when: (ctx) => ctx.filterQuery.length > 0,
41
+ },
42
+ {
43
+ id: "filtered-navigation",
44
+ render: () => "Use [ and ] to move through files while the current filter stays applied.",
45
+ when: (ctx) => ctx.filterQuery.length > 0,
46
+ },
47
+ {
48
+ id: "focus.toggle",
49
+ bindingId: "focus.toggle",
50
+ render: ({ key }) => `Press ${key ?? "tab"} to switch between the sidebar and reader.`,
51
+ },
52
+ {
53
+ id: "sidebar.toggle",
54
+ bindingId: "sidebar.toggle",
55
+ render: ({ key }) =>
56
+ `Press ${key ?? "s"} to hide or show the sidebar without losing your place.`,
57
+ },
58
+ {
59
+ id: "help.open",
60
+ bindingId: "help.toggle",
61
+ render: ({ key }) => `Press ${key ?? "?"} to open the full keyboard help at any time.`,
62
+ },
63
+ ]
64
+
65
+ const firstKeyByBindingId = <C>(bindings: readonly KeyBinding<C>[]): ReadonlyMap<string, string> =>
66
+ new Map(
67
+ bindings.flatMap((binding) => {
68
+ const firstKey = binding.keys[0]
69
+ return firstKey ? [[binding.id, displayKey(firstKey)] as const] : []
70
+ }),
71
+ )
72
+
73
+ export const buildReaderEmptyStateTips = (
74
+ bindings: readonly KeyBinding<BrowserCtx>[],
75
+ ctx: BrowserCtx,
76
+ ): readonly TipLine[] => {
77
+ const keyByBindingId = firstKeyByBindingId(bindings)
78
+
79
+ return tipDefinitions
80
+ .filter((tip) => !tip.when || tip.when(ctx))
81
+ .map((tip) => ({
82
+ id: tip.id,
83
+ text: `Tip: ${tip.render({ key: tip.bindingId ? (keyByBindingId.get(tip.bindingId) ?? null) : null })}`,
84
+ }))
85
+ }
86
+
87
+ export const pickTipByRotation = (
88
+ tips: readonly TipLine[],
89
+ rotationIndex: number,
90
+ ): TipLine | null => {
91
+ if (tips.length === 0) return null
92
+ return tips[((rotationIndex % tips.length) + tips.length) % tips.length] ?? null
93
+ }