@immediately-run/omnibox 0.3.0 → 0.4.0
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/dist/Omnibox.cjs +14 -18
- package/dist/Omnibox.cjs.map +1 -1
- package/dist/Omnibox.d.cts +9 -1
- package/dist/Omnibox.d.ts +9 -1
- package/dist/Omnibox.js +10 -18
- package/dist/Omnibox.js.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/omniboxStyles.cjs +3 -0
- package/dist/omniboxStyles.cjs.map +1 -1
- package/dist/omniboxStyles.js +3 -0
- package/dist/omniboxStyles.js.map +1 -1
- package/package.json +1 -1
package/dist/Omnibox.cjs
CHANGED
|
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var Omnibox_exports = {};
|
|
20
20
|
__export(Omnibox_exports, {
|
|
21
|
+
RUN_LABEL: () => RUN_LABEL,
|
|
21
22
|
default: () => Omnibox_default
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(Omnibox_exports);
|
|
@@ -31,6 +32,7 @@ var import_omniboxStyles = require("./omniboxStyles");
|
|
|
31
32
|
var import_launch = require("./launch");
|
|
32
33
|
var import_platformLink = require("@immediately-run/sdk/platformLink");
|
|
33
34
|
var import_omniboxFocus = require("./omniboxFocus");
|
|
35
|
+
const RUN_LABEL = "Run";
|
|
34
36
|
(0, import_omniboxStyles.ensureOmniboxStyles)();
|
|
35
37
|
function useMediaQuery(query) {
|
|
36
38
|
const [matches, setMatches] = (0, import_react.useState)(
|
|
@@ -147,31 +149,21 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
147
149
|
[panelOpen, options, highlight, runnable, listId]
|
|
148
150
|
);
|
|
149
151
|
const chip = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-chip", "aria-hidden": Object.keys(import_launch.PROVIDERS).length === 1 || void 0, children: Object.keys(import_launch.PROVIDERS).length === 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-chip-label", children: "github" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { className: "omnibox-chip-select", "aria-label": "Provider", children: Object.keys(import_launch.PROVIDERS).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p, children: p }, p)) }) });
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
path: runPath,
|
|
156
|
-
"aria-label": "Run",
|
|
157
|
-
children: [
|
|
158
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-label", children: "Run" }),
|
|
159
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
160
|
-
]
|
|
161
|
-
}
|
|
162
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
152
|
+
const runLabel = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
153
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-label", children: RUN_LABEL }),
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
155
|
+
] });
|
|
156
|
+
const run = runPath !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_platformLink.PlatformLink, { id: `${listId}-run`, className: "omnibox-run", path: runPath, "aria-label": RUN_LABEL, children: runLabel }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
163
157
|
"button",
|
|
164
158
|
{
|
|
165
159
|
id: `${listId}-run`,
|
|
166
160
|
type: "button",
|
|
167
161
|
className: "omnibox-run",
|
|
162
|
+
"aria-label": RUN_LABEL,
|
|
168
163
|
"aria-disabled": "true",
|
|
169
164
|
"aria-describedby": `${helperId} ${noticeId}`,
|
|
170
165
|
onClick: (e) => e.preventDefault(),
|
|
171
|
-
children:
|
|
172
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-label", children: "Run" }),
|
|
173
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
174
|
-
]
|
|
166
|
+
children: runLabel
|
|
175
167
|
}
|
|
176
168
|
);
|
|
177
169
|
const field = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `omnibox omnibox--${variant}`, children: [
|
|
@@ -212,7 +204,7 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
212
204
|
path: locationRow.presentPath,
|
|
213
205
|
children: [
|
|
214
206
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-option-name", children: locationRow.display }),
|
|
215
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-option-action", children:
|
|
207
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "omnibox-option-action", children: RUN_LABEL })
|
|
216
208
|
]
|
|
217
209
|
}
|
|
218
210
|
) }),
|
|
@@ -286,4 +278,8 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
286
278
|
] });
|
|
287
279
|
}
|
|
288
280
|
var Omnibox_default = Omnibox;
|
|
281
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
282
|
+
0 && (module.exports = {
|
|
283
|
+
RUN_LABEL
|
|
284
|
+
});
|
|
289
285
|
//# sourceMappingURL=Omnibox.cjs.map
|
package/dist/Omnibox.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Omnibox.tsx"],"sourcesContent":["import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react';\nimport { ensureOmniboxStyles } from './omniboxStyles';\nimport { parseLaunch, PROVIDERS, type Launch } from './launch';\nimport { PlatformLink } from '@immediately-run/sdk/platformLink';\nimport { focusHeroOmnibox, registerOmniboxFocus } from './omniboxFocus';\nimport type { OmniboxVariant } from './omniboxFocus';\n\n// Module scope, so the rules are present before the first render — the same moment the\n// old `import './omnibox.css'` took effect.\n//\n// It is EAGER for anyone who loads the package entry, and that is worth saying plainly:\n// `index.ts` re-exports `Omnibox`, and the CJS build has no tree-shaking, so\n// `dist/index.cjs` carries an unconditional `require(\"./Omnibox\")` — a consumer importing\n// only `parseLaunch` or `focusOmnibox` still injects the stylesheet. Exactly what the CSS\n// import did, so nothing regressed; it just is not the free lunch an earlier draft of\n// this comment claimed.\nensureOmniboxStyles();\n\n// The omnibox (R3-512; FRONT_DOOR_IA §5) — the front door's primary control. It\n// does W1 (run a repo by URL or tuple) and W2 (find an app) in one place, as a\n// WAI-ARIA list-autocomplete combobox with three result groups of ONE action per\n// row. Run and Open rows render through `PlatformLink`, which resolves the\n// host-space href and escapes the frame: a platform route navigates the HOST\n// document, and a root-relative href inside the sandboxed frame would resolve\n// against the sandbox origin and land nowhere.\n//\n// The package owns the component and the launch grammar; it owns NO data. The\n// app-directory and docs hit sources are injected per app (`hits`), because the\n// package cannot depend on a consumer's records (R3-530).\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(query).matches\n : false,\n );\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mq = window.matchMedia(query);\n const onChange = () => setMatches(mq.matches);\n onChange();\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [query]);\n return matches;\n}\n\n/* ── the hit vocabulary a consumer's sources speak ──────────────────────── */\n\nexport interface AppHit {\n key: string;\n name: string;\n category: string;\n blurb: string;\n /** The repository the row opens — an org repo under immediately-run. */\n repo: string;\n /** The PLATFORM path the row opens, e.g. `/present/github/immediately-run/todo/main/files/src/App.tsx`.\n * Supplied by the consumer's `apps` source beside its own route builder, so the\n * package carries no second spelling of any route family. Rendered through\n * `PlatformLink` (host-space href, frame-escaping). */\n path: string;\n /** Opaque to the package: a consumer's `renderChip` reads it back. */\n provenance?: unknown;\n}\n\nexport interface DocHit {\n key: string;\n title: string;\n lead: string;\n /** A real href — copy-link, middle-click and open-in-new-tab all resolve it. */\n href: string;\n /** The app-space route behind `href`, when the consumer renders the row through\n * its own in-app link (`renderDoc`). Opaque to the package. */\n to?: string;\n}\n\n/** The data seams. Absent sources simply yield no rows of their kind; an omnibox\n * with no `hits` at all is the launch grammar only (what the Home app renders). */\nexport interface OmniboxHitSources {\n /** Candidate app hits for a query; the package ranks, filters and orders them. */\n apps?: (query: string) => AppHit[];\n /** Matched doc hits for a query, best-first, capped by the source. */\n docs?: (query: string) => DocHit[];\n}\n\n/* ── ranking ────────────────────────────────────────────────────────────── */\n\n/** name-prefix > name-substring > repo > blurb > category (FRONT_DOOR_IA §5.3).\n * Internal: the ranking is the package's policy, not part of the surface. */\nfunction appScore(hit: AppHit, q: string): number {\n if (hit.name.toLowerCase().startsWith(q)) return 4;\n if (hit.name.toLowerCase().includes(q)) return 3;\n if (hit.repo.toLowerCase().includes(q)) return 2;\n if (hit.blurb.toLowerCase().includes(q)) return 1;\n if (hit.category.toLowerCase().includes(q)) return 0;\n return -1;\n}\n\n/* ── the component ──────────────────────────────────────────────────────── */\n\n/** What a `renderDoc` anchor must spread: the combobox's option identity and state. */\nexport interface DocAnchorProps {\n id: string;\n className: string;\n role: 'option';\n 'aria-selected': boolean;\n}\n\nexport interface OmniboxProps {\n variant: OmniboxVariant;\n /** Nav variant only: true while the hero omnibox is mounted (`/`), so the\n * nav field renders as the shortcut that focuses it. Derived by the caller\n * from the route — render-time data, not an effect. */\n heroShortcut?: boolean;\n /** App-directory and docs hit sources. Absent → the launch grammar only. */\n hits?: OmniboxHitSources;\n /** Renders the app row's trailing chip (e.g. a provenance chip). The chip is a\n * site component with site data types, so the package renders what it is given. */\n renderChip?: (hit: AppHit) => ReactNode;\n /** Renders a doc ROW. `anchorProps` carries the combobox contract (the option's\n * id, class, role and aria-selected) — spread them onto the anchor you render so\n * the arrow-key highlight and the Enter walk keep working. The fallback is a\n * plain `<a href>` — its href is real and resolvable, but on-host a plain click\n * navigates the sandboxed FRAME to the target instead of routing the app, so a\n * consumer with an in-app link (the landing page's SiteLink) should supply this. */\n renderDoc?: (hit: DocHit, anchorProps: DocAnchorProps) => ReactNode;\n}\n\nfunction Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc }: OmniboxProps) {\n const isMobile = useMediaQuery('(max-width: 720px)');\n const [query, setQuery] = useState('');\n const [highlight, setHighlight] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n const inputId = `${listId}-input`;\n const helperId = useId();\n const noticeId = useId();\n // A source that throws is degraded, not fatal: that query's group stays empty\n // and the location row still renders. The source is called again on the next\n // keystroke — a transient throw recovers silently; only the LOG is once.\n const warnedSources = useRef<Set<keyof OmniboxHitSources>>(new Set());\n const callSource = useCallback(\n function callSource<K extends keyof OmniboxHitSources>(\n kind: K,\n source: OmniboxHitSources[K],\n q: string,\n ): ReturnType<NonNullable<OmniboxHitSources[K]>> | [] {\n try {\n return source!(q) as ReturnType<NonNullable<OmniboxHitSources[K]>>;\n } catch (error) {\n if (!warnedSources.current.has(kind)) {\n warnedSources.current.add(kind);\n console.warn(`omnibox: the \"${String(kind)}\" hit source threw; its rows are empty for this query`, error);\n }\n return [];\n }\n },\n [],\n );\n\n const parsed: Launch = useMemo(() => parseLaunch(query), [query]);\n const runnable = parsed.kind === 'location' || parsed.kind === 'platform-url';\n const runPath =\n parsed.kind === 'location'\n ? parsed.presentPath\n : parsed.kind === 'platform-url'\n ? parsed.path\n : undefined;\n\n const panelOpen = query.trim() !== '';\n\n // Adjusting state during render (the sanctioned pattern): the highlight must\n // not survive the option set changing under it, and an effect would cascade.\n const [prevQuery, setPrevQuery] = useState(query);\n if (prevQuery !== query) {\n setPrevQuery(query);\n setHighlight(-1);\n }\n\n // Unknown provider → the notice replaces the helper line's text and is\n // announced through the live region.\n const notice =\n parsed.kind === 'unknown-provider'\n ? `${parsed.provider.charAt(0).toUpperCase()}${parsed.provider.slice(1)} is not supported yet. GitHub works today.`\n : '';\n\n const helper =\n variant === 'new' ? 'the repo you just created' : 'Accepts provider:namespace/repository@ref · GitHub is the first provider';\n\n const appHits = useMemo(() => {\n if (!panelOpen || !hits?.apps) return [];\n const q = query.trim().toLowerCase();\n return callSource('apps', hits.apps, q)\n .map((hit) => ({ hit, score: appScore(hit, q) }))\n .filter(({ score }) => score >= 0)\n .sort((a, b) => b.score - a.score)\n .map(({ hit }) => hit);\n }, [panelOpen, query, hits, callSource]);\n\n const docHits = useMemo(() => {\n if (!panelOpen || !hits?.docs) return [];\n return callSource('docs', hits.docs, query.trim().toLowerCase());\n }, [panelOpen, query, hits, callSource]);\n\n const locationRow = parsed.kind === 'location' ? parsed : undefined;\n const hasResults = Boolean(locationRow) || appHits.length > 0 || docHits.length > 0;\n\n // Flattened options, in group order — the arrow-key walk and the highlight id\n // both read this list.\n const options = useMemo(() => {\n const list: { id: string; label: string }[] = [];\n if (locationRow) list.push({ id: `${listId}-opt-location`, label: locationRow.display });\n for (const hit of appHits) list.push({ id: `${listId}-opt-${hit.key}`, label: hit.name });\n for (const hit of docHits) list.push({ id: `${listId}-opt-doc-${hit.key}`, label: hit.title });\n return list;\n }, [locationRow, appHits, docHits, listId]);\n\n // Register with the focus registry (⌘K, the nav shortcut and the \"paste a repo\"\n // CTAs all land here). `reveal` is what lets those CTAs scroll this field into\n // view without any component querying for its CSS class.\n useEffect(\n () =>\n registerOmniboxFocus(variant, {\n focus: () => inputRef.current?.focus(),\n reveal: () => outerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }),\n }),\n [variant],\n );\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n if (!panelOpen || options.length === 0) return;\n e.preventDefault();\n setHighlight((h) => {\n if (h === -1) return e.key === 'ArrowDown' ? 0 : options.length - 1;\n return (h + (e.key === 'ArrowDown' ? 1 : -1) + options.length) % options.length;\n });\n return;\n }\n if (e.key === 'Enter') {\n if (highlight >= 0 && highlight < options.length) {\n e.preventDefault();\n document.getElementById(options[highlight].id)?.click();\n return;\n }\n if (runnable) {\n e.preventDefault();\n document.getElementById(`${listId}-run`)?.click();\n }\n return;\n }\n if (e.key === 'Escape') {\n // Close the panel, then clear the highlight, then blur — in that order.\n setQuery('');\n setHighlight(-1);\n inputRef.current?.blur();\n }\n },\n [panelOpen, options, highlight, runnable, listId],\n );\n\n const chip = (\n <span className=\"omnibox-chip\" aria-hidden={Object.keys(PROVIDERS).length === 1 || undefined}>\n {Object.keys(PROVIDERS).length === 1 ? (\n // One provider: a static label with no caret — NOT a dropdown of\n // providers that do not exist.\n <span className=\"omnibox-chip-label\">github</span>\n ) : (\n <select className=\"omnibox-chip-select\" aria-label=\"Provider\">\n {Object.keys(PROVIDERS).map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n )}\n </span>\n );\n\n const run = runPath !== undefined ? (\n <PlatformLink\n id={`${listId}-run`}\n className=\"omnibox-run\"\n path={runPath}\n aria-label=\"Run\"\n >\n <span className=\"omnibox-run-label\">Run</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </PlatformLink>\n ) : (\n <button\n id={`${listId}-run`}\n type=\"button\"\n className=\"omnibox-run\"\n aria-disabled=\"true\"\n aria-describedby={`${helperId} ${noticeId}`}\n onClick={(e) => e.preventDefault()}\n >\n <span className=\"omnibox-run-label\">Run</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </button>\n );\n\n const field = (\n <div className={`omnibox omnibox--${variant}`}>\n <div className=\"omnibox-row\">\n {chip}\n <input\n ref={inputRef}\n id={inputId}\n className=\"omnibox-input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={panelOpen}\n aria-controls={panelOpen ? listId : undefined}\n aria-activedescendant={highlight >= 0 ? options[highlight]?.id : undefined}\n aria-describedby={`${helperId} ${noticeId}`}\n aria-invalid={notice ? true : undefined}\n placeholder={isMobile ? 'Paste a repo or an app name' : 'owner/repo@branch, a GitHub URL, or an app name'}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n />\n {run}\n </div>\n <p className=\"omnibox-helper\" id={helperId}>\n {notice || helper}\n </p>\n {/* The live region announces the notice; empty in the common case. */}\n <p className=\"omnibox-visually-hidden\" id={noticeId} aria-live=\"polite\">\n {notice}\n </p>\n {panelOpen && (\n <div className=\"omnibox-panel\" id={listId} role=\"listbox\" aria-label=\"Results\">\n {hasResults ? (\n <>\n {locationRow && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Run from source\">\n <PlatformLink\n id={`${listId}-opt-location`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === 0}\n path={locationRow.presentPath}\n >\n <span className=\"omnibox-option-name\">{locationRow.display}</span>\n <span className=\"omnibox-option-action\">Run</span>\n </PlatformLink>\n </div>\n )}\n {appHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Apps in the directory\">\n {appHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-${hit.key}`);\n return (\n <PlatformLink\n key={hit.key}\n id={`${listId}-opt-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n path={hit.path}\n >\n <span className=\"omnibox-option-name\">{hit.name}</span>\n <span className=\"omnibox-option-cat\">{hit.category}</span>\n <span className=\"omnibox-option-blurb\">{hit.blurb}</span>\n {renderChip?.(hit)}\n </PlatformLink>\n );\n })}\n </div>\n )}\n {docHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Docs and tutorials\">\n {docHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-doc-${hit.key}`);\n const anchorProps: DocAnchorProps = {\n id: `${listId}-opt-doc-${hit.key}`,\n className: 'omnibox-option',\n role: 'option',\n 'aria-selected': highlight === idx,\n };\n if (renderDoc) {\n return <Fragment key={hit.key}>{renderDoc(hit, anchorProps)}</Fragment>;\n }\n return (\n <a\n key={hit.key}\n id={`${listId}-opt-doc-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n href={hit.href}\n >\n <span className=\"omnibox-option-name\">{hit.title}</span>\n <span className=\"omnibox-option-blurb\">{hit.lead}</span>\n </a>\n );\n })}\n </div>\n )}\n </>\n ) : (\n <div className=\"omnibox-empty\">Nothing matched. Try an app name, or paste a repo.</div>\n )}\n </div>\n )}\n </div>\n );\n\n // The nav variant collapses to a shortcut button while the hero omnibox is\n // mounted (on `/`): activating it focuses the hero field. On every other\n // route the field expands in place.\n if (variant === 'nav' && heroShortcut) {\n return (\n <button\n type=\"button\"\n className=\"omnibox-nav-button\"\n onClick={() => focusHeroOmnibox()}\n aria-label=\"Search apps and docs, or paste a repo\"\n >\n <span className=\"omnibox-nav-button-label\">Search</span>\n <span className=\"kbd\">⌘K</span>\n </button>\n );\n }\n\n return (\n <div className={`omnibox-outer omnibox-outer--${variant}`} ref={outerRef}>\n <label className=\"omnibox-visually-hidden\" htmlFor={inputId}>\n Paste a repo, or search apps and docs\n </label>\n {field}\n </div>\n );\n}\n\nexport default Omnibox;\n"],"mappings":"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","names":["callSource"]}
|
|
1
|
+
{"version":3,"sources":["../src/Omnibox.tsx"],"sourcesContent":["import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react';\nimport { ensureOmniboxStyles } from './omniboxStyles';\nimport { parseLaunch, PROVIDERS, type Launch } from './launch';\nimport { PlatformLink } from '@immediately-run/sdk/platformLink';\nimport { focusHeroOmnibox, registerOmniboxFocus } from './omniboxFocus';\nimport type { OmniboxVariant } from './omniboxFocus';\n\n/**\n * The submit control's name — the one place the word lives.\n *\n * Exported so the test can assert the rendered name against this constant rather than\n * against a string typed a second time in the test, which would pass just as happily if\n * both drifted together.\n */\nexport const RUN_LABEL = 'Run';\n\n// Module scope, so the rules are present before the first render — the same moment the\n// old `import './omnibox.css'` took effect.\n//\n// It is EAGER for anyone who loads the package entry, and that is worth saying plainly:\n// `index.ts` re-exports `Omnibox`, and the CJS build has no tree-shaking, so\n// `dist/index.cjs` carries an unconditional `require(\"./Omnibox\")` — a consumer importing\n// only `parseLaunch` or `focusOmnibox` still injects the stylesheet. Exactly what the CSS\n// import did, so nothing regressed; it just is not the free lunch an earlier draft of\n// this comment claimed.\nensureOmniboxStyles();\n\n// The omnibox (R3-512; FRONT_DOOR_IA §5) — the front door's primary control. It\n// does W1 (run a repo by URL or tuple) and W2 (find an app) in one place, as a\n// WAI-ARIA list-autocomplete combobox with three result groups of ONE action per\n// row. Run and Open rows render through `PlatformLink`, which resolves the\n// host-space href and escapes the frame: a platform route navigates the HOST\n// document, and a root-relative href inside the sandboxed frame would resolve\n// against the sandbox origin and land nowhere.\n//\n// The package owns the component and the launch grammar; it owns NO data. The\n// app-directory and docs hit sources are injected per app (`hits`), because the\n// package cannot depend on a consumer's records (R3-530).\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(query).matches\n : false,\n );\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mq = window.matchMedia(query);\n const onChange = () => setMatches(mq.matches);\n onChange();\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [query]);\n return matches;\n}\n\n/* ── the hit vocabulary a consumer's sources speak ──────────────────────── */\n\nexport interface AppHit {\n key: string;\n name: string;\n category: string;\n blurb: string;\n /** The repository the row opens — an org repo under immediately-run. */\n repo: string;\n /** The PLATFORM path the row opens, e.g. `/present/github/immediately-run/todo/main/files/src/App.tsx`.\n * Supplied by the consumer's `apps` source beside its own route builder, so the\n * package carries no second spelling of any route family. Rendered through\n * `PlatformLink` (host-space href, frame-escaping). */\n path: string;\n /** Opaque to the package: a consumer's `renderChip` reads it back. */\n provenance?: unknown;\n}\n\nexport interface DocHit {\n key: string;\n title: string;\n lead: string;\n /** A real href — copy-link, middle-click and open-in-new-tab all resolve it. */\n href: string;\n /** The app-space route behind `href`, when the consumer renders the row through\n * its own in-app link (`renderDoc`). Opaque to the package. */\n to?: string;\n}\n\n/** The data seams. Absent sources simply yield no rows of their kind; an omnibox\n * with no `hits` at all is the launch grammar only (what the Home app renders). */\nexport interface OmniboxHitSources {\n /** Candidate app hits for a query; the package ranks, filters and orders them. */\n apps?: (query: string) => AppHit[];\n /** Matched doc hits for a query, best-first, capped by the source. */\n docs?: (query: string) => DocHit[];\n}\n\n/* ── ranking ────────────────────────────────────────────────────────────── */\n\n/** name-prefix > name-substring > repo > blurb > category (FRONT_DOOR_IA §5.3).\n * Internal: the ranking is the package's policy, not part of the surface. */\nfunction appScore(hit: AppHit, q: string): number {\n if (hit.name.toLowerCase().startsWith(q)) return 4;\n if (hit.name.toLowerCase().includes(q)) return 3;\n if (hit.repo.toLowerCase().includes(q)) return 2;\n if (hit.blurb.toLowerCase().includes(q)) return 1;\n if (hit.category.toLowerCase().includes(q)) return 0;\n return -1;\n}\n\n/* ── the component ──────────────────────────────────────────────────────── */\n\n/** What a `renderDoc` anchor must spread: the combobox's option identity and state. */\nexport interface DocAnchorProps {\n id: string;\n className: string;\n role: 'option';\n 'aria-selected': boolean;\n}\n\nexport interface OmniboxProps {\n variant: OmniboxVariant;\n /** Nav variant only: true while the hero omnibox is mounted (`/`), so the\n * nav field renders as the shortcut that focuses it. Derived by the caller\n * from the route — render-time data, not an effect. */\n heroShortcut?: boolean;\n /** App-directory and docs hit sources. Absent → the launch grammar only. */\n hits?: OmniboxHitSources;\n /** Renders the app row's trailing chip (e.g. a provenance chip). The chip is a\n * site component with site data types, so the package renders what it is given. */\n renderChip?: (hit: AppHit) => ReactNode;\n /** Renders a doc ROW. `anchorProps` carries the combobox contract (the option's\n * id, class, role and aria-selected) — spread them onto the anchor you render so\n * the arrow-key highlight and the Enter walk keep working. The fallback is a\n * plain `<a href>` — its href is real and resolvable, but on-host a plain click\n * navigates the sandboxed FRAME to the target instead of routing the app, so a\n * consumer with an in-app link (the landing page's SiteLink) should supply this. */\n renderDoc?: (hit: DocHit, anchorProps: DocAnchorProps) => ReactNode;\n}\n\nfunction Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc }: OmniboxProps) {\n const isMobile = useMediaQuery('(max-width: 720px)');\n const [query, setQuery] = useState('');\n const [highlight, setHighlight] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n const inputId = `${listId}-input`;\n const helperId = useId();\n const noticeId = useId();\n // A source that throws is degraded, not fatal: that query's group stays empty\n // and the location row still renders. The source is called again on the next\n // keystroke — a transient throw recovers silently; only the LOG is once.\n const warnedSources = useRef<Set<keyof OmniboxHitSources>>(new Set());\n const callSource = useCallback(\n function callSource<K extends keyof OmniboxHitSources>(\n kind: K,\n source: OmniboxHitSources[K],\n q: string,\n ): ReturnType<NonNullable<OmniboxHitSources[K]>> | [] {\n try {\n return source!(q) as ReturnType<NonNullable<OmniboxHitSources[K]>>;\n } catch (error) {\n if (!warnedSources.current.has(kind)) {\n warnedSources.current.add(kind);\n console.warn(`omnibox: the \"${String(kind)}\" hit source threw; its rows are empty for this query`, error);\n }\n return [];\n }\n },\n [],\n );\n\n const parsed: Launch = useMemo(() => parseLaunch(query), [query]);\n const runnable = parsed.kind === 'location' || parsed.kind === 'platform-url';\n const runPath =\n parsed.kind === 'location'\n ? parsed.presentPath\n : parsed.kind === 'platform-url'\n ? parsed.path\n : undefined;\n\n const panelOpen = query.trim() !== '';\n\n // Adjusting state during render (the sanctioned pattern): the highlight must\n // not survive the option set changing under it, and an effect would cascade.\n const [prevQuery, setPrevQuery] = useState(query);\n if (prevQuery !== query) {\n setPrevQuery(query);\n setHighlight(-1);\n }\n\n // Unknown provider → the notice replaces the helper line's text and is\n // announced through the live region.\n const notice =\n parsed.kind === 'unknown-provider'\n ? `${parsed.provider.charAt(0).toUpperCase()}${parsed.provider.slice(1)} is not supported yet. GitHub works today.`\n : '';\n\n const helper =\n variant === 'new' ? 'the repo you just created' : 'Accepts provider:namespace/repository@ref · GitHub is the first provider';\n\n const appHits = useMemo(() => {\n if (!panelOpen || !hits?.apps) return [];\n const q = query.trim().toLowerCase();\n return callSource('apps', hits.apps, q)\n .map((hit) => ({ hit, score: appScore(hit, q) }))\n .filter(({ score }) => score >= 0)\n .sort((a, b) => b.score - a.score)\n .map(({ hit }) => hit);\n }, [panelOpen, query, hits, callSource]);\n\n const docHits = useMemo(() => {\n if (!panelOpen || !hits?.docs) return [];\n return callSource('docs', hits.docs, query.trim().toLowerCase());\n }, [panelOpen, query, hits, callSource]);\n\n const locationRow = parsed.kind === 'location' ? parsed : undefined;\n const hasResults = Boolean(locationRow) || appHits.length > 0 || docHits.length > 0;\n\n // Flattened options, in group order — the arrow-key walk and the highlight id\n // both read this list.\n const options = useMemo(() => {\n const list: { id: string; label: string }[] = [];\n if (locationRow) list.push({ id: `${listId}-opt-location`, label: locationRow.display });\n for (const hit of appHits) list.push({ id: `${listId}-opt-${hit.key}`, label: hit.name });\n for (const hit of docHits) list.push({ id: `${listId}-opt-doc-${hit.key}`, label: hit.title });\n return list;\n }, [locationRow, appHits, docHits, listId]);\n\n // Register with the focus registry (⌘K, the nav shortcut and the \"paste a repo\"\n // CTAs all land here). `reveal` is what lets those CTAs scroll this field into\n // view without any component querying for its CSS class.\n useEffect(\n () =>\n registerOmniboxFocus(variant, {\n focus: () => inputRef.current?.focus(),\n reveal: () => outerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }),\n }),\n [variant],\n );\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n if (!panelOpen || options.length === 0) return;\n e.preventDefault();\n setHighlight((h) => {\n if (h === -1) return e.key === 'ArrowDown' ? 0 : options.length - 1;\n return (h + (e.key === 'ArrowDown' ? 1 : -1) + options.length) % options.length;\n });\n return;\n }\n if (e.key === 'Enter') {\n if (highlight >= 0 && highlight < options.length) {\n e.preventDefault();\n document.getElementById(options[highlight].id)?.click();\n return;\n }\n if (runnable) {\n e.preventDefault();\n document.getElementById(`${listId}-run`)?.click();\n }\n return;\n }\n if (e.key === 'Escape') {\n // Close the panel, then clear the highlight, then blur — in that order.\n setQuery('');\n setHighlight(-1);\n inputRef.current?.blur();\n }\n },\n [panelOpen, options, highlight, runnable, listId],\n );\n\n const chip = (\n <span className=\"omnibox-chip\" aria-hidden={Object.keys(PROVIDERS).length === 1 || undefined}>\n {Object.keys(PROVIDERS).length === 1 ? (\n // One provider: a static label with no caret — NOT a dropdown of\n // providers that do not exist.\n <span className=\"omnibox-chip-label\">github</span>\n ) : (\n <select className=\"omnibox-chip-select\" aria-label=\"Provider\">\n {Object.keys(PROVIDERS).map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n )}\n </span>\n );\n\n // The submit control's visible label and its accessible name come from ONE constant.\n // At <=720px `.omnibox-run-label` is `display: none` (omnibox.css) and the arrow beside it\n // is `aria-hidden`, so name-from-content disappears entirely at mobile widths and the\n // `aria-label` is the only name left. Deriving both from the same string is what stops a\n // copy change renaming the button for sighted users while leaving screen-reader users on\n // the old word — or, as shipped before R3-570, on no word at all.\n const runLabel = (\n <>\n <span className=\"omnibox-run-label\">{RUN_LABEL}</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </>\n );\n\n const run = runPath !== undefined ? (\n <PlatformLink id={`${listId}-run`} className=\"omnibox-run\" path={runPath} aria-label={RUN_LABEL}>\n {runLabel}\n </PlatformLink>\n ) : (\n <button\n id={`${listId}-run`}\n type=\"button\"\n className=\"omnibox-run\"\n aria-label={RUN_LABEL}\n aria-disabled=\"true\"\n aria-describedby={`${helperId} ${noticeId}`}\n onClick={(e) => e.preventDefault()}\n >\n {runLabel}\n </button>\n );\n\n const field = (\n <div className={`omnibox omnibox--${variant}`}>\n <div className=\"omnibox-row\">\n {chip}\n <input\n ref={inputRef}\n id={inputId}\n className=\"omnibox-input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={panelOpen}\n aria-controls={panelOpen ? listId : undefined}\n aria-activedescendant={highlight >= 0 ? options[highlight]?.id : undefined}\n aria-describedby={`${helperId} ${noticeId}`}\n aria-invalid={notice ? true : undefined}\n placeholder={isMobile ? 'Paste a repo or an app name' : 'owner/repo@branch, a GitHub URL, or an app name'}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n />\n {run}\n </div>\n <p className=\"omnibox-helper\" id={helperId}>\n {notice || helper}\n </p>\n {/* The live region announces the notice; empty in the common case. */}\n <p className=\"omnibox-visually-hidden\" id={noticeId} aria-live=\"polite\">\n {notice}\n </p>\n {panelOpen && (\n <div className=\"omnibox-panel\" id={listId} role=\"listbox\" aria-label=\"Results\">\n {hasResults ? (\n <>\n {locationRow && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Run from source\">\n <PlatformLink\n id={`${listId}-opt-location`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === 0}\n path={locationRow.presentPath}\n >\n <span className=\"omnibox-option-name\">{locationRow.display}</span>\n <span className=\"omnibox-option-action\">{RUN_LABEL}</span>\n </PlatformLink>\n </div>\n )}\n {appHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Apps in the directory\">\n {appHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-${hit.key}`);\n return (\n <PlatformLink\n key={hit.key}\n id={`${listId}-opt-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n path={hit.path}\n >\n <span className=\"omnibox-option-name\">{hit.name}</span>\n <span className=\"omnibox-option-cat\">{hit.category}</span>\n <span className=\"omnibox-option-blurb\">{hit.blurb}</span>\n {renderChip?.(hit)}\n </PlatformLink>\n );\n })}\n </div>\n )}\n {docHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Docs and tutorials\">\n {docHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-doc-${hit.key}`);\n const anchorProps: DocAnchorProps = {\n id: `${listId}-opt-doc-${hit.key}`,\n className: 'omnibox-option',\n role: 'option',\n 'aria-selected': highlight === idx,\n };\n if (renderDoc) {\n return <Fragment key={hit.key}>{renderDoc(hit, anchorProps)}</Fragment>;\n }\n return (\n <a\n key={hit.key}\n id={`${listId}-opt-doc-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n href={hit.href}\n >\n <span className=\"omnibox-option-name\">{hit.title}</span>\n <span className=\"omnibox-option-blurb\">{hit.lead}</span>\n </a>\n );\n })}\n </div>\n )}\n </>\n ) : (\n <div className=\"omnibox-empty\">Nothing matched. Try an app name, or paste a repo.</div>\n )}\n </div>\n )}\n </div>\n );\n\n // The nav variant collapses to a shortcut button while the hero omnibox is\n // mounted (on `/`): activating it focuses the hero field. On every other\n // route the field expands in place.\n if (variant === 'nav' && heroShortcut) {\n return (\n <button\n type=\"button\"\n className=\"omnibox-nav-button\"\n onClick={() => focusHeroOmnibox()}\n aria-label=\"Search apps and docs, or paste a repo\"\n >\n <span className=\"omnibox-nav-button-label\">Search</span>\n <span className=\"kbd\">⌘K</span>\n </button>\n );\n }\n\n return (\n <div className={`omnibox-outer omnibox-outer--${variant}`} ref={outerRef}>\n <label className=\"omnibox-visually-hidden\" htmlFor={inputId}>\n Paste a repo, or search apps and docs\n </label>\n {field}\n </div>\n );\n}\n\nexport default Omnibox;\n"],"mappings":"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","names":["callSource"]}
|
package/dist/Omnibox.d.cts
CHANGED
|
@@ -2,6 +2,14 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { OmniboxVariant } from './omniboxFocus.cjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The submit control's name — the one place the word lives.
|
|
7
|
+
*
|
|
8
|
+
* Exported so the test can assert the rendered name against this constant rather than
|
|
9
|
+
* against a string typed a second time in the test, which would pass just as happily if
|
|
10
|
+
* both drifted together.
|
|
11
|
+
*/
|
|
12
|
+
declare const RUN_LABEL = "Run";
|
|
5
13
|
interface AppHit {
|
|
6
14
|
key: string;
|
|
7
15
|
name: string;
|
|
@@ -63,4 +71,4 @@ interface OmniboxProps {
|
|
|
63
71
|
}
|
|
64
72
|
declare function Omnibox({ variant, heroShortcut, hits, renderChip, renderDoc }: OmniboxProps): react.JSX.Element;
|
|
65
73
|
|
|
66
|
-
export { type AppHit, type DocAnchorProps, type DocHit, type OmniboxHitSources, type OmniboxProps, Omnibox as default };
|
|
74
|
+
export { type AppHit, type DocAnchorProps, type DocHit, type OmniboxHitSources, type OmniboxProps, RUN_LABEL, Omnibox as default };
|
package/dist/Omnibox.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { OmniboxVariant } from './omniboxFocus.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The submit control's name — the one place the word lives.
|
|
7
|
+
*
|
|
8
|
+
* Exported so the test can assert the rendered name against this constant rather than
|
|
9
|
+
* against a string typed a second time in the test, which would pass just as happily if
|
|
10
|
+
* both drifted together.
|
|
11
|
+
*/
|
|
12
|
+
declare const RUN_LABEL = "Run";
|
|
5
13
|
interface AppHit {
|
|
6
14
|
key: string;
|
|
7
15
|
name: string;
|
|
@@ -63,4 +71,4 @@ interface OmniboxProps {
|
|
|
63
71
|
}
|
|
64
72
|
declare function Omnibox({ variant, heroShortcut, hits, renderChip, renderDoc }: OmniboxProps): react.JSX.Element;
|
|
65
73
|
|
|
66
|
-
export { type AppHit, type DocAnchorProps, type DocHit, type OmniboxHitSources, type OmniboxProps, Omnibox as default };
|
|
74
|
+
export { type AppHit, type DocAnchorProps, type DocHit, type OmniboxHitSources, type OmniboxProps, RUN_LABEL, Omnibox as default };
|
package/dist/Omnibox.js
CHANGED
|
@@ -4,6 +4,7 @@ import { ensureOmniboxStyles } from "./omniboxStyles";
|
|
|
4
4
|
import { parseLaunch, PROVIDERS } from "./launch";
|
|
5
5
|
import { PlatformLink } from "@immediately-run/sdk/platformLink";
|
|
6
6
|
import { focusHeroOmnibox, registerOmniboxFocus } from "./omniboxFocus";
|
|
7
|
+
const RUN_LABEL = "Run";
|
|
7
8
|
ensureOmniboxStyles();
|
|
8
9
|
function useMediaQuery(query) {
|
|
9
10
|
const [matches, setMatches] = useState(
|
|
@@ -124,31 +125,21 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
124
125
|
// providers that do not exist.
|
|
125
126
|
/* @__PURE__ */ jsx("span", { className: "omnibox-chip-label", children: "github" })
|
|
126
127
|
) : /* @__PURE__ */ jsx("select", { className: "omnibox-chip-select", "aria-label": "Provider", children: Object.keys(PROVIDERS).map((p) => /* @__PURE__ */ jsx("option", { value: p, children: p }, p)) }) });
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
path: runPath,
|
|
133
|
-
"aria-label": "Run",
|
|
134
|
-
children: [
|
|
135
|
-
/* @__PURE__ */ jsx("span", { className: "omnibox-run-label", children: "Run" }),
|
|
136
|
-
/* @__PURE__ */ jsx("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
137
|
-
]
|
|
138
|
-
}
|
|
139
|
-
) : /* @__PURE__ */ jsxs(
|
|
128
|
+
const runLabel = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
129
|
+
/* @__PURE__ */ jsx("span", { className: "omnibox-run-label", children: RUN_LABEL }),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
131
|
+
] });
|
|
132
|
+
const run = runPath !== void 0 ? /* @__PURE__ */ jsx(PlatformLink, { id: `${listId}-run`, className: "omnibox-run", path: runPath, "aria-label": RUN_LABEL, children: runLabel }) : /* @__PURE__ */ jsx(
|
|
140
133
|
"button",
|
|
141
134
|
{
|
|
142
135
|
id: `${listId}-run`,
|
|
143
136
|
type: "button",
|
|
144
137
|
className: "omnibox-run",
|
|
138
|
+
"aria-label": RUN_LABEL,
|
|
145
139
|
"aria-disabled": "true",
|
|
146
140
|
"aria-describedby": `${helperId} ${noticeId}`,
|
|
147
141
|
onClick: (e) => e.preventDefault(),
|
|
148
|
-
children:
|
|
149
|
-
/* @__PURE__ */ jsx("span", { className: "omnibox-run-label", children: "Run" }),
|
|
150
|
-
/* @__PURE__ */ jsx("span", { className: "omnibox-run-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
151
|
-
]
|
|
142
|
+
children: runLabel
|
|
152
143
|
}
|
|
153
144
|
);
|
|
154
145
|
const field = /* @__PURE__ */ jsxs("div", { className: `omnibox omnibox--${variant}`, children: [
|
|
@@ -189,7 +180,7 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
189
180
|
path: locationRow.presentPath,
|
|
190
181
|
children: [
|
|
191
182
|
/* @__PURE__ */ jsx("span", { className: "omnibox-option-name", children: locationRow.display }),
|
|
192
|
-
/* @__PURE__ */ jsx("span", { className: "omnibox-option-action", children:
|
|
183
|
+
/* @__PURE__ */ jsx("span", { className: "omnibox-option-action", children: RUN_LABEL })
|
|
193
184
|
]
|
|
194
185
|
}
|
|
195
186
|
) }),
|
|
@@ -264,6 +255,7 @@ function Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc })
|
|
|
264
255
|
}
|
|
265
256
|
var Omnibox_default = Omnibox;
|
|
266
257
|
export {
|
|
258
|
+
RUN_LABEL,
|
|
267
259
|
Omnibox_default as default
|
|
268
260
|
};
|
|
269
261
|
//# sourceMappingURL=Omnibox.js.map
|
package/dist/Omnibox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Omnibox.tsx"],"sourcesContent":["import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react';\nimport { ensureOmniboxStyles } from './omniboxStyles';\nimport { parseLaunch, PROVIDERS, type Launch } from './launch';\nimport { PlatformLink } from '@immediately-run/sdk/platformLink';\nimport { focusHeroOmnibox, registerOmniboxFocus } from './omniboxFocus';\nimport type { OmniboxVariant } from './omniboxFocus';\n\n// Module scope, so the rules are present before the first render — the same moment the\n// old `import './omnibox.css'` took effect.\n//\n// It is EAGER for anyone who loads the package entry, and that is worth saying plainly:\n// `index.ts` re-exports `Omnibox`, and the CJS build has no tree-shaking, so\n// `dist/index.cjs` carries an unconditional `require(\"./Omnibox\")` — a consumer importing\n// only `parseLaunch` or `focusOmnibox` still injects the stylesheet. Exactly what the CSS\n// import did, so nothing regressed; it just is not the free lunch an earlier draft of\n// this comment claimed.\nensureOmniboxStyles();\n\n// The omnibox (R3-512; FRONT_DOOR_IA §5) — the front door's primary control. It\n// does W1 (run a repo by URL or tuple) and W2 (find an app) in one place, as a\n// WAI-ARIA list-autocomplete combobox with three result groups of ONE action per\n// row. Run and Open rows render through `PlatformLink`, which resolves the\n// host-space href and escapes the frame: a platform route navigates the HOST\n// document, and a root-relative href inside the sandboxed frame would resolve\n// against the sandbox origin and land nowhere.\n//\n// The package owns the component and the launch grammar; it owns NO data. The\n// app-directory and docs hit sources are injected per app (`hits`), because the\n// package cannot depend on a consumer's records (R3-530).\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(query).matches\n : false,\n );\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mq = window.matchMedia(query);\n const onChange = () => setMatches(mq.matches);\n onChange();\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [query]);\n return matches;\n}\n\n/* ── the hit vocabulary a consumer's sources speak ──────────────────────── */\n\nexport interface AppHit {\n key: string;\n name: string;\n category: string;\n blurb: string;\n /** The repository the row opens — an org repo under immediately-run. */\n repo: string;\n /** The PLATFORM path the row opens, e.g. `/present/github/immediately-run/todo/main/files/src/App.tsx`.\n * Supplied by the consumer's `apps` source beside its own route builder, so the\n * package carries no second spelling of any route family. Rendered through\n * `PlatformLink` (host-space href, frame-escaping). */\n path: string;\n /** Opaque to the package: a consumer's `renderChip` reads it back. */\n provenance?: unknown;\n}\n\nexport interface DocHit {\n key: string;\n title: string;\n lead: string;\n /** A real href — copy-link, middle-click and open-in-new-tab all resolve it. */\n href: string;\n /** The app-space route behind `href`, when the consumer renders the row through\n * its own in-app link (`renderDoc`). Opaque to the package. */\n to?: string;\n}\n\n/** The data seams. Absent sources simply yield no rows of their kind; an omnibox\n * with no `hits` at all is the launch grammar only (what the Home app renders). */\nexport interface OmniboxHitSources {\n /** Candidate app hits for a query; the package ranks, filters and orders them. */\n apps?: (query: string) => AppHit[];\n /** Matched doc hits for a query, best-first, capped by the source. */\n docs?: (query: string) => DocHit[];\n}\n\n/* ── ranking ────────────────────────────────────────────────────────────── */\n\n/** name-prefix > name-substring > repo > blurb > category (FRONT_DOOR_IA §5.3).\n * Internal: the ranking is the package's policy, not part of the surface. */\nfunction appScore(hit: AppHit, q: string): number {\n if (hit.name.toLowerCase().startsWith(q)) return 4;\n if (hit.name.toLowerCase().includes(q)) return 3;\n if (hit.repo.toLowerCase().includes(q)) return 2;\n if (hit.blurb.toLowerCase().includes(q)) return 1;\n if (hit.category.toLowerCase().includes(q)) return 0;\n return -1;\n}\n\n/* ── the component ──────────────────────────────────────────────────────── */\n\n/** What a `renderDoc` anchor must spread: the combobox's option identity and state. */\nexport interface DocAnchorProps {\n id: string;\n className: string;\n role: 'option';\n 'aria-selected': boolean;\n}\n\nexport interface OmniboxProps {\n variant: OmniboxVariant;\n /** Nav variant only: true while the hero omnibox is mounted (`/`), so the\n * nav field renders as the shortcut that focuses it. Derived by the caller\n * from the route — render-time data, not an effect. */\n heroShortcut?: boolean;\n /** App-directory and docs hit sources. Absent → the launch grammar only. */\n hits?: OmniboxHitSources;\n /** Renders the app row's trailing chip (e.g. a provenance chip). The chip is a\n * site component with site data types, so the package renders what it is given. */\n renderChip?: (hit: AppHit) => ReactNode;\n /** Renders a doc ROW. `anchorProps` carries the combobox contract (the option's\n * id, class, role and aria-selected) — spread them onto the anchor you render so\n * the arrow-key highlight and the Enter walk keep working. The fallback is a\n * plain `<a href>` — its href is real and resolvable, but on-host a plain click\n * navigates the sandboxed FRAME to the target instead of routing the app, so a\n * consumer with an in-app link (the landing page's SiteLink) should supply this. */\n renderDoc?: (hit: DocHit, anchorProps: DocAnchorProps) => ReactNode;\n}\n\nfunction Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc }: OmniboxProps) {\n const isMobile = useMediaQuery('(max-width: 720px)');\n const [query, setQuery] = useState('');\n const [highlight, setHighlight] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n const inputId = `${listId}-input`;\n const helperId = useId();\n const noticeId = useId();\n // A source that throws is degraded, not fatal: that query's group stays empty\n // and the location row still renders. The source is called again on the next\n // keystroke — a transient throw recovers silently; only the LOG is once.\n const warnedSources = useRef<Set<keyof OmniboxHitSources>>(new Set());\n const callSource = useCallback(\n function callSource<K extends keyof OmniboxHitSources>(\n kind: K,\n source: OmniboxHitSources[K],\n q: string,\n ): ReturnType<NonNullable<OmniboxHitSources[K]>> | [] {\n try {\n return source!(q) as ReturnType<NonNullable<OmniboxHitSources[K]>>;\n } catch (error) {\n if (!warnedSources.current.has(kind)) {\n warnedSources.current.add(kind);\n console.warn(`omnibox: the \"${String(kind)}\" hit source threw; its rows are empty for this query`, error);\n }\n return [];\n }\n },\n [],\n );\n\n const parsed: Launch = useMemo(() => parseLaunch(query), [query]);\n const runnable = parsed.kind === 'location' || parsed.kind === 'platform-url';\n const runPath =\n parsed.kind === 'location'\n ? parsed.presentPath\n : parsed.kind === 'platform-url'\n ? parsed.path\n : undefined;\n\n const panelOpen = query.trim() !== '';\n\n // Adjusting state during render (the sanctioned pattern): the highlight must\n // not survive the option set changing under it, and an effect would cascade.\n const [prevQuery, setPrevQuery] = useState(query);\n if (prevQuery !== query) {\n setPrevQuery(query);\n setHighlight(-1);\n }\n\n // Unknown provider → the notice replaces the helper line's text and is\n // announced through the live region.\n const notice =\n parsed.kind === 'unknown-provider'\n ? `${parsed.provider.charAt(0).toUpperCase()}${parsed.provider.slice(1)} is not supported yet. GitHub works today.`\n : '';\n\n const helper =\n variant === 'new' ? 'the repo you just created' : 'Accepts provider:namespace/repository@ref · GitHub is the first provider';\n\n const appHits = useMemo(() => {\n if (!panelOpen || !hits?.apps) return [];\n const q = query.trim().toLowerCase();\n return callSource('apps', hits.apps, q)\n .map((hit) => ({ hit, score: appScore(hit, q) }))\n .filter(({ score }) => score >= 0)\n .sort((a, b) => b.score - a.score)\n .map(({ hit }) => hit);\n }, [panelOpen, query, hits, callSource]);\n\n const docHits = useMemo(() => {\n if (!panelOpen || !hits?.docs) return [];\n return callSource('docs', hits.docs, query.trim().toLowerCase());\n }, [panelOpen, query, hits, callSource]);\n\n const locationRow = parsed.kind === 'location' ? parsed : undefined;\n const hasResults = Boolean(locationRow) || appHits.length > 0 || docHits.length > 0;\n\n // Flattened options, in group order — the arrow-key walk and the highlight id\n // both read this list.\n const options = useMemo(() => {\n const list: { id: string; label: string }[] = [];\n if (locationRow) list.push({ id: `${listId}-opt-location`, label: locationRow.display });\n for (const hit of appHits) list.push({ id: `${listId}-opt-${hit.key}`, label: hit.name });\n for (const hit of docHits) list.push({ id: `${listId}-opt-doc-${hit.key}`, label: hit.title });\n return list;\n }, [locationRow, appHits, docHits, listId]);\n\n // Register with the focus registry (⌘K, the nav shortcut and the \"paste a repo\"\n // CTAs all land here). `reveal` is what lets those CTAs scroll this field into\n // view without any component querying for its CSS class.\n useEffect(\n () =>\n registerOmniboxFocus(variant, {\n focus: () => inputRef.current?.focus(),\n reveal: () => outerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }),\n }),\n [variant],\n );\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n if (!panelOpen || options.length === 0) return;\n e.preventDefault();\n setHighlight((h) => {\n if (h === -1) return e.key === 'ArrowDown' ? 0 : options.length - 1;\n return (h + (e.key === 'ArrowDown' ? 1 : -1) + options.length) % options.length;\n });\n return;\n }\n if (e.key === 'Enter') {\n if (highlight >= 0 && highlight < options.length) {\n e.preventDefault();\n document.getElementById(options[highlight].id)?.click();\n return;\n }\n if (runnable) {\n e.preventDefault();\n document.getElementById(`${listId}-run`)?.click();\n }\n return;\n }\n if (e.key === 'Escape') {\n // Close the panel, then clear the highlight, then blur — in that order.\n setQuery('');\n setHighlight(-1);\n inputRef.current?.blur();\n }\n },\n [panelOpen, options, highlight, runnable, listId],\n );\n\n const chip = (\n <span className=\"omnibox-chip\" aria-hidden={Object.keys(PROVIDERS).length === 1 || undefined}>\n {Object.keys(PROVIDERS).length === 1 ? (\n // One provider: a static label with no caret — NOT a dropdown of\n // providers that do not exist.\n <span className=\"omnibox-chip-label\">github</span>\n ) : (\n <select className=\"omnibox-chip-select\" aria-label=\"Provider\">\n {Object.keys(PROVIDERS).map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n )}\n </span>\n );\n\n const run = runPath !== undefined ? (\n <PlatformLink\n id={`${listId}-run`}\n className=\"omnibox-run\"\n path={runPath}\n aria-label=\"Run\"\n >\n <span className=\"omnibox-run-label\">Run</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </PlatformLink>\n ) : (\n <button\n id={`${listId}-run`}\n type=\"button\"\n className=\"omnibox-run\"\n aria-disabled=\"true\"\n aria-describedby={`${helperId} ${noticeId}`}\n onClick={(e) => e.preventDefault()}\n >\n <span className=\"omnibox-run-label\">Run</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </button>\n );\n\n const field = (\n <div className={`omnibox omnibox--${variant}`}>\n <div className=\"omnibox-row\">\n {chip}\n <input\n ref={inputRef}\n id={inputId}\n className=\"omnibox-input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={panelOpen}\n aria-controls={panelOpen ? listId : undefined}\n aria-activedescendant={highlight >= 0 ? options[highlight]?.id : undefined}\n aria-describedby={`${helperId} ${noticeId}`}\n aria-invalid={notice ? true : undefined}\n placeholder={isMobile ? 'Paste a repo or an app name' : 'owner/repo@branch, a GitHub URL, or an app name'}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n />\n {run}\n </div>\n <p className=\"omnibox-helper\" id={helperId}>\n {notice || helper}\n </p>\n {/* The live region announces the notice; empty in the common case. */}\n <p className=\"omnibox-visually-hidden\" id={noticeId} aria-live=\"polite\">\n {notice}\n </p>\n {panelOpen && (\n <div className=\"omnibox-panel\" id={listId} role=\"listbox\" aria-label=\"Results\">\n {hasResults ? (\n <>\n {locationRow && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Run from source\">\n <PlatformLink\n id={`${listId}-opt-location`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === 0}\n path={locationRow.presentPath}\n >\n <span className=\"omnibox-option-name\">{locationRow.display}</span>\n <span className=\"omnibox-option-action\">Run</span>\n </PlatformLink>\n </div>\n )}\n {appHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Apps in the directory\">\n {appHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-${hit.key}`);\n return (\n <PlatformLink\n key={hit.key}\n id={`${listId}-opt-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n path={hit.path}\n >\n <span className=\"omnibox-option-name\">{hit.name}</span>\n <span className=\"omnibox-option-cat\">{hit.category}</span>\n <span className=\"omnibox-option-blurb\">{hit.blurb}</span>\n {renderChip?.(hit)}\n </PlatformLink>\n );\n })}\n </div>\n )}\n {docHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Docs and tutorials\">\n {docHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-doc-${hit.key}`);\n const anchorProps: DocAnchorProps = {\n id: `${listId}-opt-doc-${hit.key}`,\n className: 'omnibox-option',\n role: 'option',\n 'aria-selected': highlight === idx,\n };\n if (renderDoc) {\n return <Fragment key={hit.key}>{renderDoc(hit, anchorProps)}</Fragment>;\n }\n return (\n <a\n key={hit.key}\n id={`${listId}-opt-doc-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n href={hit.href}\n >\n <span className=\"omnibox-option-name\">{hit.title}</span>\n <span className=\"omnibox-option-blurb\">{hit.lead}</span>\n </a>\n );\n })}\n </div>\n )}\n </>\n ) : (\n <div className=\"omnibox-empty\">Nothing matched. Try an app name, or paste a repo.</div>\n )}\n </div>\n )}\n </div>\n );\n\n // The nav variant collapses to a shortcut button while the hero omnibox is\n // mounted (on `/`): activating it focuses the hero field. On every other\n // route the field expands in place.\n if (variant === 'nav' && heroShortcut) {\n return (\n <button\n type=\"button\"\n className=\"omnibox-nav-button\"\n onClick={() => focusHeroOmnibox()}\n aria-label=\"Search apps and docs, or paste a repo\"\n >\n <span className=\"omnibox-nav-button-label\">Search</span>\n <span className=\"kbd\">⌘K</span>\n </button>\n );\n }\n\n return (\n <div className={`omnibox-outer omnibox-outer--${variant}`} ref={outerRef}>\n <label className=\"omnibox-visually-hidden\" htmlFor={inputId}>\n Paste a repo, or search apps and docs\n </label>\n {field}\n </div>\n );\n}\n\nexport default Omnibox;\n"],"mappings":"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","names":["Fragment","callSource"]}
|
|
1
|
+
{"version":3,"sources":["../src/Omnibox.tsx"],"sourcesContent":["import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react';\nimport { ensureOmniboxStyles } from './omniboxStyles';\nimport { parseLaunch, PROVIDERS, type Launch } from './launch';\nimport { PlatformLink } from '@immediately-run/sdk/platformLink';\nimport { focusHeroOmnibox, registerOmniboxFocus } from './omniboxFocus';\nimport type { OmniboxVariant } from './omniboxFocus';\n\n/**\n * The submit control's name — the one place the word lives.\n *\n * Exported so the test can assert the rendered name against this constant rather than\n * against a string typed a second time in the test, which would pass just as happily if\n * both drifted together.\n */\nexport const RUN_LABEL = 'Run';\n\n// Module scope, so the rules are present before the first render — the same moment the\n// old `import './omnibox.css'` took effect.\n//\n// It is EAGER for anyone who loads the package entry, and that is worth saying plainly:\n// `index.ts` re-exports `Omnibox`, and the CJS build has no tree-shaking, so\n// `dist/index.cjs` carries an unconditional `require(\"./Omnibox\")` — a consumer importing\n// only `parseLaunch` or `focusOmnibox` still injects the stylesheet. Exactly what the CSS\n// import did, so nothing regressed; it just is not the free lunch an earlier draft of\n// this comment claimed.\nensureOmniboxStyles();\n\n// The omnibox (R3-512; FRONT_DOOR_IA §5) — the front door's primary control. It\n// does W1 (run a repo by URL or tuple) and W2 (find an app) in one place, as a\n// WAI-ARIA list-autocomplete combobox with three result groups of ONE action per\n// row. Run and Open rows render through `PlatformLink`, which resolves the\n// host-space href and escapes the frame: a platform route navigates the HOST\n// document, and a root-relative href inside the sandboxed frame would resolve\n// against the sandbox origin and land nowhere.\n//\n// The package owns the component and the launch grammar; it owns NO data. The\n// app-directory and docs hit sources are injected per app (`hits`), because the\n// package cannot depend on a consumer's records (R3-530).\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(query).matches\n : false,\n );\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mq = window.matchMedia(query);\n const onChange = () => setMatches(mq.matches);\n onChange();\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, [query]);\n return matches;\n}\n\n/* ── the hit vocabulary a consumer's sources speak ──────────────────────── */\n\nexport interface AppHit {\n key: string;\n name: string;\n category: string;\n blurb: string;\n /** The repository the row opens — an org repo under immediately-run. */\n repo: string;\n /** The PLATFORM path the row opens, e.g. `/present/github/immediately-run/todo/main/files/src/App.tsx`.\n * Supplied by the consumer's `apps` source beside its own route builder, so the\n * package carries no second spelling of any route family. Rendered through\n * `PlatformLink` (host-space href, frame-escaping). */\n path: string;\n /** Opaque to the package: a consumer's `renderChip` reads it back. */\n provenance?: unknown;\n}\n\nexport interface DocHit {\n key: string;\n title: string;\n lead: string;\n /** A real href — copy-link, middle-click and open-in-new-tab all resolve it. */\n href: string;\n /** The app-space route behind `href`, when the consumer renders the row through\n * its own in-app link (`renderDoc`). Opaque to the package. */\n to?: string;\n}\n\n/** The data seams. Absent sources simply yield no rows of their kind; an omnibox\n * with no `hits` at all is the launch grammar only (what the Home app renders). */\nexport interface OmniboxHitSources {\n /** Candidate app hits for a query; the package ranks, filters and orders them. */\n apps?: (query: string) => AppHit[];\n /** Matched doc hits for a query, best-first, capped by the source. */\n docs?: (query: string) => DocHit[];\n}\n\n/* ── ranking ────────────────────────────────────────────────────────────── */\n\n/** name-prefix > name-substring > repo > blurb > category (FRONT_DOOR_IA §5.3).\n * Internal: the ranking is the package's policy, not part of the surface. */\nfunction appScore(hit: AppHit, q: string): number {\n if (hit.name.toLowerCase().startsWith(q)) return 4;\n if (hit.name.toLowerCase().includes(q)) return 3;\n if (hit.repo.toLowerCase().includes(q)) return 2;\n if (hit.blurb.toLowerCase().includes(q)) return 1;\n if (hit.category.toLowerCase().includes(q)) return 0;\n return -1;\n}\n\n/* ── the component ──────────────────────────────────────────────────────── */\n\n/** What a `renderDoc` anchor must spread: the combobox's option identity and state. */\nexport interface DocAnchorProps {\n id: string;\n className: string;\n role: 'option';\n 'aria-selected': boolean;\n}\n\nexport interface OmniboxProps {\n variant: OmniboxVariant;\n /** Nav variant only: true while the hero omnibox is mounted (`/`), so the\n * nav field renders as the shortcut that focuses it. Derived by the caller\n * from the route — render-time data, not an effect. */\n heroShortcut?: boolean;\n /** App-directory and docs hit sources. Absent → the launch grammar only. */\n hits?: OmniboxHitSources;\n /** Renders the app row's trailing chip (e.g. a provenance chip). The chip is a\n * site component with site data types, so the package renders what it is given. */\n renderChip?: (hit: AppHit) => ReactNode;\n /** Renders a doc ROW. `anchorProps` carries the combobox contract (the option's\n * id, class, role and aria-selected) — spread them onto the anchor you render so\n * the arrow-key highlight and the Enter walk keep working. The fallback is a\n * plain `<a href>` — its href is real and resolvable, but on-host a plain click\n * navigates the sandboxed FRAME to the target instead of routing the app, so a\n * consumer with an in-app link (the landing page's SiteLink) should supply this. */\n renderDoc?: (hit: DocHit, anchorProps: DocAnchorProps) => ReactNode;\n}\n\nfunction Omnibox({ variant, heroShortcut = false, hits, renderChip, renderDoc }: OmniboxProps) {\n const isMobile = useMediaQuery('(max-width: 720px)');\n const [query, setQuery] = useState('');\n const [highlight, setHighlight] = useState(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n const inputId = `${listId}-input`;\n const helperId = useId();\n const noticeId = useId();\n // A source that throws is degraded, not fatal: that query's group stays empty\n // and the location row still renders. The source is called again on the next\n // keystroke — a transient throw recovers silently; only the LOG is once.\n const warnedSources = useRef<Set<keyof OmniboxHitSources>>(new Set());\n const callSource = useCallback(\n function callSource<K extends keyof OmniboxHitSources>(\n kind: K,\n source: OmniboxHitSources[K],\n q: string,\n ): ReturnType<NonNullable<OmniboxHitSources[K]>> | [] {\n try {\n return source!(q) as ReturnType<NonNullable<OmniboxHitSources[K]>>;\n } catch (error) {\n if (!warnedSources.current.has(kind)) {\n warnedSources.current.add(kind);\n console.warn(`omnibox: the \"${String(kind)}\" hit source threw; its rows are empty for this query`, error);\n }\n return [];\n }\n },\n [],\n );\n\n const parsed: Launch = useMemo(() => parseLaunch(query), [query]);\n const runnable = parsed.kind === 'location' || parsed.kind === 'platform-url';\n const runPath =\n parsed.kind === 'location'\n ? parsed.presentPath\n : parsed.kind === 'platform-url'\n ? parsed.path\n : undefined;\n\n const panelOpen = query.trim() !== '';\n\n // Adjusting state during render (the sanctioned pattern): the highlight must\n // not survive the option set changing under it, and an effect would cascade.\n const [prevQuery, setPrevQuery] = useState(query);\n if (prevQuery !== query) {\n setPrevQuery(query);\n setHighlight(-1);\n }\n\n // Unknown provider → the notice replaces the helper line's text and is\n // announced through the live region.\n const notice =\n parsed.kind === 'unknown-provider'\n ? `${parsed.provider.charAt(0).toUpperCase()}${parsed.provider.slice(1)} is not supported yet. GitHub works today.`\n : '';\n\n const helper =\n variant === 'new' ? 'the repo you just created' : 'Accepts provider:namespace/repository@ref · GitHub is the first provider';\n\n const appHits = useMemo(() => {\n if (!panelOpen || !hits?.apps) return [];\n const q = query.trim().toLowerCase();\n return callSource('apps', hits.apps, q)\n .map((hit) => ({ hit, score: appScore(hit, q) }))\n .filter(({ score }) => score >= 0)\n .sort((a, b) => b.score - a.score)\n .map(({ hit }) => hit);\n }, [panelOpen, query, hits, callSource]);\n\n const docHits = useMemo(() => {\n if (!panelOpen || !hits?.docs) return [];\n return callSource('docs', hits.docs, query.trim().toLowerCase());\n }, [panelOpen, query, hits, callSource]);\n\n const locationRow = parsed.kind === 'location' ? parsed : undefined;\n const hasResults = Boolean(locationRow) || appHits.length > 0 || docHits.length > 0;\n\n // Flattened options, in group order — the arrow-key walk and the highlight id\n // both read this list.\n const options = useMemo(() => {\n const list: { id: string; label: string }[] = [];\n if (locationRow) list.push({ id: `${listId}-opt-location`, label: locationRow.display });\n for (const hit of appHits) list.push({ id: `${listId}-opt-${hit.key}`, label: hit.name });\n for (const hit of docHits) list.push({ id: `${listId}-opt-doc-${hit.key}`, label: hit.title });\n return list;\n }, [locationRow, appHits, docHits, listId]);\n\n // Register with the focus registry (⌘K, the nav shortcut and the \"paste a repo\"\n // CTAs all land here). `reveal` is what lets those CTAs scroll this field into\n // view without any component querying for its CSS class.\n useEffect(\n () =>\n registerOmniboxFocus(variant, {\n focus: () => inputRef.current?.focus(),\n reveal: () => outerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }),\n }),\n [variant],\n );\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n if (!panelOpen || options.length === 0) return;\n e.preventDefault();\n setHighlight((h) => {\n if (h === -1) return e.key === 'ArrowDown' ? 0 : options.length - 1;\n return (h + (e.key === 'ArrowDown' ? 1 : -1) + options.length) % options.length;\n });\n return;\n }\n if (e.key === 'Enter') {\n if (highlight >= 0 && highlight < options.length) {\n e.preventDefault();\n document.getElementById(options[highlight].id)?.click();\n return;\n }\n if (runnable) {\n e.preventDefault();\n document.getElementById(`${listId}-run`)?.click();\n }\n return;\n }\n if (e.key === 'Escape') {\n // Close the panel, then clear the highlight, then blur — in that order.\n setQuery('');\n setHighlight(-1);\n inputRef.current?.blur();\n }\n },\n [panelOpen, options, highlight, runnable, listId],\n );\n\n const chip = (\n <span className=\"omnibox-chip\" aria-hidden={Object.keys(PROVIDERS).length === 1 || undefined}>\n {Object.keys(PROVIDERS).length === 1 ? (\n // One provider: a static label with no caret — NOT a dropdown of\n // providers that do not exist.\n <span className=\"omnibox-chip-label\">github</span>\n ) : (\n <select className=\"omnibox-chip-select\" aria-label=\"Provider\">\n {Object.keys(PROVIDERS).map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n )}\n </span>\n );\n\n // The submit control's visible label and its accessible name come from ONE constant.\n // At <=720px `.omnibox-run-label` is `display: none` (omnibox.css) and the arrow beside it\n // is `aria-hidden`, so name-from-content disappears entirely at mobile widths and the\n // `aria-label` is the only name left. Deriving both from the same string is what stops a\n // copy change renaming the button for sighted users while leaving screen-reader users on\n // the old word — or, as shipped before R3-570, on no word at all.\n const runLabel = (\n <>\n <span className=\"omnibox-run-label\">{RUN_LABEL}</span>\n <span className=\"omnibox-run-arrow\" aria-hidden=\"true\">\n →\n </span>\n </>\n );\n\n const run = runPath !== undefined ? (\n <PlatformLink id={`${listId}-run`} className=\"omnibox-run\" path={runPath} aria-label={RUN_LABEL}>\n {runLabel}\n </PlatformLink>\n ) : (\n <button\n id={`${listId}-run`}\n type=\"button\"\n className=\"omnibox-run\"\n aria-label={RUN_LABEL}\n aria-disabled=\"true\"\n aria-describedby={`${helperId} ${noticeId}`}\n onClick={(e) => e.preventDefault()}\n >\n {runLabel}\n </button>\n );\n\n const field = (\n <div className={`omnibox omnibox--${variant}`}>\n <div className=\"omnibox-row\">\n {chip}\n <input\n ref={inputRef}\n id={inputId}\n className=\"omnibox-input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={panelOpen}\n aria-controls={panelOpen ? listId : undefined}\n aria-activedescendant={highlight >= 0 ? options[highlight]?.id : undefined}\n aria-describedby={`${helperId} ${noticeId}`}\n aria-invalid={notice ? true : undefined}\n placeholder={isMobile ? 'Paste a repo or an app name' : 'owner/repo@branch, a GitHub URL, or an app name'}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n />\n {run}\n </div>\n <p className=\"omnibox-helper\" id={helperId}>\n {notice || helper}\n </p>\n {/* The live region announces the notice; empty in the common case. */}\n <p className=\"omnibox-visually-hidden\" id={noticeId} aria-live=\"polite\">\n {notice}\n </p>\n {panelOpen && (\n <div className=\"omnibox-panel\" id={listId} role=\"listbox\" aria-label=\"Results\">\n {hasResults ? (\n <>\n {locationRow && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Run from source\">\n <PlatformLink\n id={`${listId}-opt-location`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === 0}\n path={locationRow.presentPath}\n >\n <span className=\"omnibox-option-name\">{locationRow.display}</span>\n <span className=\"omnibox-option-action\">{RUN_LABEL}</span>\n </PlatformLink>\n </div>\n )}\n {appHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Apps in the directory\">\n {appHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-${hit.key}`);\n return (\n <PlatformLink\n key={hit.key}\n id={`${listId}-opt-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n path={hit.path}\n >\n <span className=\"omnibox-option-name\">{hit.name}</span>\n <span className=\"omnibox-option-cat\">{hit.category}</span>\n <span className=\"omnibox-option-blurb\">{hit.blurb}</span>\n {renderChip?.(hit)}\n </PlatformLink>\n );\n })}\n </div>\n )}\n {docHits.length > 0 && (\n <div className=\"omnibox-group\" role=\"group\" aria-label=\"Docs and tutorials\">\n {docHits.map((hit) => {\n const idx = options.findIndex((o) => o.id === `${listId}-opt-doc-${hit.key}`);\n const anchorProps: DocAnchorProps = {\n id: `${listId}-opt-doc-${hit.key}`,\n className: 'omnibox-option',\n role: 'option',\n 'aria-selected': highlight === idx,\n };\n if (renderDoc) {\n return <Fragment key={hit.key}>{renderDoc(hit, anchorProps)}</Fragment>;\n }\n return (\n <a\n key={hit.key}\n id={`${listId}-opt-doc-${hit.key}`}\n className=\"omnibox-option\"\n role=\"option\"\n aria-selected={highlight === idx}\n href={hit.href}\n >\n <span className=\"omnibox-option-name\">{hit.title}</span>\n <span className=\"omnibox-option-blurb\">{hit.lead}</span>\n </a>\n );\n })}\n </div>\n )}\n </>\n ) : (\n <div className=\"omnibox-empty\">Nothing matched. Try an app name, or paste a repo.</div>\n )}\n </div>\n )}\n </div>\n );\n\n // The nav variant collapses to a shortcut button while the hero omnibox is\n // mounted (on `/`): activating it focuses the hero field. On every other\n // route the field expands in place.\n if (variant === 'nav' && heroShortcut) {\n return (\n <button\n type=\"button\"\n className=\"omnibox-nav-button\"\n onClick={() => focusHeroOmnibox()}\n aria-label=\"Search apps and docs, or paste a repo\"\n >\n <span className=\"omnibox-nav-button-label\">Search</span>\n <span className=\"kbd\">⌘K</span>\n </button>\n );\n }\n\n return (\n <div className={`omnibox-outer omnibox-outer--${variant}`} ref={outerRef}>\n <label className=\"omnibox-visually-hidden\" htmlFor={inputId}>\n Paste a repo, or search apps and docs\n </label>\n {field}\n </div>\n );\n}\n\nexport default Omnibox;\n"],"mappings":"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","names":["Fragment","callSource"]}
|
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var index_exports = {};
|
|
|
30
30
|
__export(index_exports, {
|
|
31
31
|
Omnibox: () => import_Omnibox.default,
|
|
32
32
|
PROVIDERS: () => import_launch.PROVIDERS,
|
|
33
|
+
RUN_LABEL: () => import_Omnibox.RUN_LABEL,
|
|
33
34
|
focusHeroOmnibox: () => import_omniboxFocus.focusHeroOmnibox,
|
|
34
35
|
focusOmnibox: () => import_omniboxFocus.focusOmnibox,
|
|
35
36
|
parseLaunch: () => import_launch.parseLaunch,
|
|
@@ -44,6 +45,7 @@ var import_omniboxFocus = require("./omniboxFocus");
|
|
|
44
45
|
0 && (module.exports = {
|
|
45
46
|
Omnibox,
|
|
46
47
|
PROVIDERS,
|
|
48
|
+
RUN_LABEL,
|
|
47
49
|
focusHeroOmnibox,
|
|
48
50
|
focusOmnibox,
|
|
49
51
|
parseLaunch,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { default as Omnibox } from './Omnibox';\nexport type { OmniboxProps, OmniboxHitSources, AppHit, DocHit, DocAnchorProps } from './Omnibox';\nexport { parseLaunch, PROVIDERS } from './launch';\nexport type { Launch } from './launch';\nexport { focusHeroOmnibox, revealHeroOmnibox, focusOmnibox, registerOmniboxFocus } from './omniboxFocus';\nexport type { OmniboxVariant, OmniboxHandle } from './omniboxFocus';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { default as Omnibox, RUN_LABEL } from './Omnibox';\nexport type { OmniboxProps, OmniboxHitSources, AppHit, DocHit, DocAnchorProps } from './Omnibox';\nexport { parseLaunch, PROVIDERS } from './launch';\nexport type { Launch } from './launch';\nexport { focusHeroOmnibox, revealHeroOmnibox, focusOmnibox, registerOmniboxFocus } from './omniboxFocus';\nexport type { OmniboxVariant, OmniboxHandle } from './omniboxFocus';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA8C;AAE9C,oBAAuC;AAEvC,0BAAwF;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AppHit, DocAnchorProps, DocHit, default as Omnibox, OmniboxHitSources, OmniboxProps } from './Omnibox.cjs';
|
|
1
|
+
export { AppHit, DocAnchorProps, DocHit, default as Omnibox, OmniboxHitSources, OmniboxProps, RUN_LABEL } from './Omnibox.cjs';
|
|
2
2
|
export { Launch, PROVIDERS, parseLaunch } from './launch.cjs';
|
|
3
3
|
export { OmniboxHandle, OmniboxVariant, focusHeroOmnibox, focusOmnibox, registerOmniboxFocus, revealHeroOmnibox } from './omniboxFocus.cjs';
|
|
4
4
|
import 'react';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AppHit, DocAnchorProps, DocHit, default as Omnibox, OmniboxHitSources, OmniboxProps } from './Omnibox.js';
|
|
1
|
+
export { AppHit, DocAnchorProps, DocHit, default as Omnibox, OmniboxHitSources, OmniboxProps, RUN_LABEL } from './Omnibox.js';
|
|
2
2
|
export { Launch, PROVIDERS, parseLaunch } from './launch.js';
|
|
3
3
|
export { OmniboxHandle, OmniboxVariant, focusHeroOmnibox, focusOmnibox, registerOmniboxFocus, revealHeroOmnibox } from './omniboxFocus.js';
|
|
4
4
|
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { default as default2 } from "./Omnibox";
|
|
1
|
+
import { default as default2, RUN_LABEL } from "./Omnibox";
|
|
2
2
|
import { parseLaunch, PROVIDERS } from "./launch";
|
|
3
3
|
import { focusHeroOmnibox, revealHeroOmnibox, focusOmnibox, registerOmniboxFocus } from "./omniboxFocus";
|
|
4
4
|
export {
|
|
5
5
|
default2 as Omnibox,
|
|
6
6
|
PROVIDERS,
|
|
7
|
+
RUN_LABEL,
|
|
7
8
|
focusHeroOmnibox,
|
|
8
9
|
focusOmnibox,
|
|
9
10
|
parseLaunch,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { default as Omnibox } from './Omnibox';\nexport type { OmniboxProps, OmniboxHitSources, AppHit, DocHit, DocAnchorProps } from './Omnibox';\nexport { parseLaunch, PROVIDERS } from './launch';\nexport type { Launch } from './launch';\nexport { focusHeroOmnibox, revealHeroOmnibox, focusOmnibox, registerOmniboxFocus } from './omniboxFocus';\nexport type { OmniboxVariant, OmniboxHandle } from './omniboxFocus';\n"],"mappings":"AAAA,SAAoB,WAAXA,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { default as Omnibox, RUN_LABEL } from './Omnibox';\nexport type { OmniboxProps, OmniboxHitSources, AppHit, DocHit, DocAnchorProps } from './Omnibox';\nexport { parseLaunch, PROVIDERS } from './launch';\nexport type { Launch } from './launch';\nexport { focusHeroOmnibox, revealHeroOmnibox, focusOmnibox, registerOmniboxFocus } from './omniboxFocus';\nexport type { OmniboxVariant, OmniboxHandle } from './omniboxFocus';\n"],"mappings":"AAAA,SAAoB,WAAXA,UAAoB,iBAAiB;AAE9C,SAAS,aAAa,iBAAiB;AAEvC,SAAS,kBAAkB,mBAAmB,cAAc,4BAA4B;","names":["default"]}
|
package/dist/omniboxStyles.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(omniboxStyles_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(omniboxStyles_exports);
|
|
24
24
|
var import_omniboxStyles = require("./omniboxStyles.generated");
|
|
25
25
|
const STYLE_ID = "immediately-run-omnibox-css";
|
|
26
|
+
let warned = false;
|
|
26
27
|
function ensureOmniboxStyles() {
|
|
27
28
|
try {
|
|
28
29
|
if (typeof document === "undefined") return;
|
|
@@ -32,6 +33,8 @@ function ensureOmniboxStyles() {
|
|
|
32
33
|
style.textContent = import_omniboxStyles.OMNIBOX_CSS;
|
|
33
34
|
(document.head ?? document.documentElement).appendChild(style);
|
|
34
35
|
} catch (err) {
|
|
36
|
+
if (warned) return;
|
|
37
|
+
warned = true;
|
|
35
38
|
try {
|
|
36
39
|
console.warn("[omnibox] could not inject the stylesheet; rendering unstyled.", err);
|
|
37
40
|
} catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/omniboxStyles.ts"],"sourcesContent":["// Injecting the omnibox's stylesheet from JS, once per document.\n//\n// WHY NOT `import './omnibox.css'`. That is what the package shipped until 2026-09-08,\n// and on immediately.run it took down the front door. The sandbox bundler followed the\n// specifier out of the resolved package, fetched the stylesheet, and evaluated it as\n// JAVASCRIPT: `SyntaxError: Unexpected token '.'` on the first selector, the whole app\n// dead behind it, prod and local alike. An app's OWN `.css` import works there; a\n// dependency's did not, and this package cannot make a consumer's bundler grow a CSS\n// loader. JS is the one thing every consumer can execute, so the styles ship as JS.\n//\n// `dist/omnibox.css` is still published and still exported at `./omnibox.css`, for a\n// consumer that would rather own the cascade — importing it as well is harmless (the\n// rules are identical and idempotent), it just is not required any more.\nimport { OMNIBOX_CSS } from './omniboxStyles.generated';\n\n/** Marks the injected element, and makes a second injection a no-op. */\nconst STYLE_ID = 'immediately-run-omnibox-css';\n\n/**\n * Ensure the omnibox stylesheet is in `document`. Idempotent, and safe to call from\n * render: it writes nothing when the element is already there.\n *\n * Deliberately defensive rather than clever:\n * - **no `document` is not an error.** SSR and any non-DOM renderer simply get no\n * styles rather than a crash on import, and this module is imported at module scope.\n * - **a throwing DOM is not an error either.** Some embeddings forbid injecting a\n * style element; an unstyled combobox is a bad outcome, a dead app is a worse one,\n * and the caller has no way to recover from either.\n * - the element carries an `id`, so a second copy of this package on the page (a\n * version skew in one consumer's tree) styles the DOM once, not twice.\n */\nexport function ensureOmniboxStyles(): void {\n try {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = OMNIBOX_CSS;\n (document.head ?? document.documentElement).appendChild(style);\n } catch (err) {\n // Unstyled beats dead — but silent beats neither. Three different failures land here\n // (no `head` or `documentElement`, an embedding that refuses `createElement('style')`,\n // a refused `textContent` assignment) and without this they are indistinguishable\n // from \"the styles are fine\", which is how an unstyled combobox goes unreported.\n // `console.warn` and not `throw`: the caller can recover from neither outcome.\n try {\n console.warn('[omnibox] could not inject the stylesheet; rendering unstyled.', err);\n } catch {\n /* a console that throws must not be the thing that breaks the render. */\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,2BAA4B;AAG5B,MAAM,WAAW;
|
|
1
|
+
{"version":3,"sources":["../src/omniboxStyles.ts"],"sourcesContent":["// Injecting the omnibox's stylesheet from JS, once per document.\n//\n// WHY NOT `import './omnibox.css'`. That is what the package shipped until 2026-09-08,\n// and on immediately.run it took down the front door. The sandbox bundler followed the\n// specifier out of the resolved package, fetched the stylesheet, and evaluated it as\n// JAVASCRIPT: `SyntaxError: Unexpected token '.'` on the first selector, the whole app\n// dead behind it, prod and local alike. An app's OWN `.css` import works there; a\n// dependency's did not, and this package cannot make a consumer's bundler grow a CSS\n// loader. JS is the one thing every consumer can execute, so the styles ship as JS.\n//\n// `dist/omnibox.css` is still published and still exported at `./omnibox.css`, for a\n// consumer that would rather own the cascade — importing it as well is harmless (the\n// rules are identical and idempotent), it just is not required any more.\nimport { OMNIBOX_CSS } from './omniboxStyles.generated';\n\n/** Marks the injected element, and makes a second injection a no-op. */\nconst STYLE_ID = 'immediately-run-omnibox-css';\n\n/** The diagnostic below is once per document, not once per call. In the failure path the\n * element is never created, so the `getElementById` guard never engages and every call\n * re-enters the catch — and this function is documented as safe to call from render, so\n * in the very embedding the fallback exists for that is one warning per render. */\nlet warned = false;\n\n/**\n * Ensure the omnibox stylesheet is in `document`. Idempotent, and safe to call from\n * render: it writes nothing when the element is already there.\n *\n * Deliberately defensive rather than clever:\n * - **no `document` is not an error.** SSR and any non-DOM renderer simply get no\n * styles rather than a crash on import, and this module is imported at module scope.\n * - **a throwing DOM is not an error either.** Some embeddings forbid injecting a\n * style element; an unstyled combobox is a bad outcome, a dead app is a worse one,\n * and the caller has no way to recover from either.\n * - the element carries an `id`, so a second copy of this package on the page (a\n * version skew in one consumer's tree) styles the DOM once, not twice.\n */\nexport function ensureOmniboxStyles(): void {\n try {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = OMNIBOX_CSS;\n (document.head ?? document.documentElement).appendChild(style);\n } catch (err) {\n // Unstyled beats dead — but silent beats neither. Three different failures land here\n // (no `head` or `documentElement`, an embedding that refuses `createElement('style')`,\n // a refused `textContent` assignment) and without this they are indistinguishable\n // from \"the styles are fine\", which is how an unstyled combobox goes unreported.\n // `console.warn` and not `throw`: the caller can recover from neither outcome.\n if (warned) return;\n warned = true;\n try {\n console.warn('[omnibox] could not inject the stylesheet; rendering unstyled.', err);\n } catch {\n /* a console that throws must not be the thing that breaks the render. */\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,2BAA4B;AAG5B,MAAM,WAAW;AAMjB,IAAI,SAAS;AAeN,SAAS,sBAA4B;AAC1C,MAAI;AACF,QAAI,OAAO,aAAa,YAAa;AACrC,QAAI,SAAS,eAAe,QAAQ,EAAG;AACvC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,KAAK;AACX,UAAM,cAAc;AACpB,KAAC,SAAS,QAAQ,SAAS,iBAAiB,YAAY,KAAK;AAAA,EAC/D,SAAS,KAAK;AAMZ,QAAI,OAAQ;AACZ,aAAS;AACT,QAAI;AACF,cAAQ,KAAK,kEAAkE,GAAG;AAAA,IACpF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
|
package/dist/omniboxStyles.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OMNIBOX_CSS } from "./omniboxStyles.generated";
|
|
2
2
|
const STYLE_ID = "immediately-run-omnibox-css";
|
|
3
|
+
let warned = false;
|
|
3
4
|
function ensureOmniboxStyles() {
|
|
4
5
|
try {
|
|
5
6
|
if (typeof document === "undefined") return;
|
|
@@ -9,6 +10,8 @@ function ensureOmniboxStyles() {
|
|
|
9
10
|
style.textContent = OMNIBOX_CSS;
|
|
10
11
|
(document.head ?? document.documentElement).appendChild(style);
|
|
11
12
|
} catch (err) {
|
|
13
|
+
if (warned) return;
|
|
14
|
+
warned = true;
|
|
12
15
|
try {
|
|
13
16
|
console.warn("[omnibox] could not inject the stylesheet; rendering unstyled.", err);
|
|
14
17
|
} catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/omniboxStyles.ts"],"sourcesContent":["// Injecting the omnibox's stylesheet from JS, once per document.\n//\n// WHY NOT `import './omnibox.css'`. That is what the package shipped until 2026-09-08,\n// and on immediately.run it took down the front door. The sandbox bundler followed the\n// specifier out of the resolved package, fetched the stylesheet, and evaluated it as\n// JAVASCRIPT: `SyntaxError: Unexpected token '.'` on the first selector, the whole app\n// dead behind it, prod and local alike. An app's OWN `.css` import works there; a\n// dependency's did not, and this package cannot make a consumer's bundler grow a CSS\n// loader. JS is the one thing every consumer can execute, so the styles ship as JS.\n//\n// `dist/omnibox.css` is still published and still exported at `./omnibox.css`, for a\n// consumer that would rather own the cascade — importing it as well is harmless (the\n// rules are identical and idempotent), it just is not required any more.\nimport { OMNIBOX_CSS } from './omniboxStyles.generated';\n\n/** Marks the injected element, and makes a second injection a no-op. */\nconst STYLE_ID = 'immediately-run-omnibox-css';\n\n/**\n * Ensure the omnibox stylesheet is in `document`. Idempotent, and safe to call from\n * render: it writes nothing when the element is already there.\n *\n * Deliberately defensive rather than clever:\n * - **no `document` is not an error.** SSR and any non-DOM renderer simply get no\n * styles rather than a crash on import, and this module is imported at module scope.\n * - **a throwing DOM is not an error either.** Some embeddings forbid injecting a\n * style element; an unstyled combobox is a bad outcome, a dead app is a worse one,\n * and the caller has no way to recover from either.\n * - the element carries an `id`, so a second copy of this package on the page (a\n * version skew in one consumer's tree) styles the DOM once, not twice.\n */\nexport function ensureOmniboxStyles(): void {\n try {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = OMNIBOX_CSS;\n (document.head ?? document.documentElement).appendChild(style);\n } catch (err) {\n // Unstyled beats dead — but silent beats neither. Three different failures land here\n // (no `head` or `documentElement`, an embedding that refuses `createElement('style')`,\n // a refused `textContent` assignment) and without this they are indistinguishable\n // from \"the styles are fine\", which is how an unstyled combobox goes unreported.\n // `console.warn` and not `throw`: the caller can recover from neither outcome.\n try {\n console.warn('[omnibox] could not inject the stylesheet; rendering unstyled.', err);\n } catch {\n /* a console that throws must not be the thing that breaks the render. */\n }\n }\n}\n"],"mappings":"AAaA,SAAS,mBAAmB;AAG5B,MAAM,WAAW;
|
|
1
|
+
{"version":3,"sources":["../src/omniboxStyles.ts"],"sourcesContent":["// Injecting the omnibox's stylesheet from JS, once per document.\n//\n// WHY NOT `import './omnibox.css'`. That is what the package shipped until 2026-09-08,\n// and on immediately.run it took down the front door. The sandbox bundler followed the\n// specifier out of the resolved package, fetched the stylesheet, and evaluated it as\n// JAVASCRIPT: `SyntaxError: Unexpected token '.'` on the first selector, the whole app\n// dead behind it, prod and local alike. An app's OWN `.css` import works there; a\n// dependency's did not, and this package cannot make a consumer's bundler grow a CSS\n// loader. JS is the one thing every consumer can execute, so the styles ship as JS.\n//\n// `dist/omnibox.css` is still published and still exported at `./omnibox.css`, for a\n// consumer that would rather own the cascade — importing it as well is harmless (the\n// rules are identical and idempotent), it just is not required any more.\nimport { OMNIBOX_CSS } from './omniboxStyles.generated';\n\n/** Marks the injected element, and makes a second injection a no-op. */\nconst STYLE_ID = 'immediately-run-omnibox-css';\n\n/** The diagnostic below is once per document, not once per call. In the failure path the\n * element is never created, so the `getElementById` guard never engages and every call\n * re-enters the catch — and this function is documented as safe to call from render, so\n * in the very embedding the fallback exists for that is one warning per render. */\nlet warned = false;\n\n/**\n * Ensure the omnibox stylesheet is in `document`. Idempotent, and safe to call from\n * render: it writes nothing when the element is already there.\n *\n * Deliberately defensive rather than clever:\n * - **no `document` is not an error.** SSR and any non-DOM renderer simply get no\n * styles rather than a crash on import, and this module is imported at module scope.\n * - **a throwing DOM is not an error either.** Some embeddings forbid injecting a\n * style element; an unstyled combobox is a bad outcome, a dead app is a worse one,\n * and the caller has no way to recover from either.\n * - the element carries an `id`, so a second copy of this package on the page (a\n * version skew in one consumer's tree) styles the DOM once, not twice.\n */\nexport function ensureOmniboxStyles(): void {\n try {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = OMNIBOX_CSS;\n (document.head ?? document.documentElement).appendChild(style);\n } catch (err) {\n // Unstyled beats dead — but silent beats neither. Three different failures land here\n // (no `head` or `documentElement`, an embedding that refuses `createElement('style')`,\n // a refused `textContent` assignment) and without this they are indistinguishable\n // from \"the styles are fine\", which is how an unstyled combobox goes unreported.\n // `console.warn` and not `throw`: the caller can recover from neither outcome.\n if (warned) return;\n warned = true;\n try {\n console.warn('[omnibox] could not inject the stylesheet; rendering unstyled.', err);\n } catch {\n /* a console that throws must not be the thing that breaks the render. */\n }\n }\n}\n"],"mappings":"AAaA,SAAS,mBAAmB;AAG5B,MAAM,WAAW;AAMjB,IAAI,SAAS;AAeN,SAAS,sBAA4B;AAC1C,MAAI;AACF,QAAI,OAAO,aAAa,YAAa;AACrC,QAAI,SAAS,eAAe,QAAQ,EAAG;AACvC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,KAAK;AACX,UAAM,cAAc;AACpB,KAAC,SAAS,QAAQ,SAAS,iBAAiB,YAAY,KAAK;AAAA,EAC/D,SAAS,KAAK;AAMZ,QAAI,OAAQ;AACZ,aAAS;AACT,QAAI;AACF,cAAQ,KAAK,kEAAkE,GAAG;AAAA,IACpF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immediately-run/omnibox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The front door's omnibox: one list-autocomplete combobox that runs a repo by URL or tuple and searches a consumer's app directory and docs (the launch grammar always; the hit sources injected). Shared by landing-page and the Home app so there is one component and one grammar (R3-512, R3-530).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|