silvery 0.19.2 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/Text-BRf-59j2.mjs +237 -0
- package/dist/Text-BRf-59j2.mjs.map +1 -0
- package/dist/ag-BeFC4S2N.mjs +8727 -0
- package/dist/ag-BeFC4S2N.mjs.map +1 -0
- package/dist/{animation-Cn64yepo.mjs → animation-N8MFybTk.mjs} +2 -2
- package/dist/animation-N8MFybTk.mjs.map +1 -0
- package/dist/{ansi-CLOitHKx.mjs → ansi-C6Qs1Wn2.mjs} +1 -1
- package/dist/{ansi-CLOitHKx.mjs.map → ansi-C6Qs1Wn2.mjs.map} +1 -1
- package/dist/{ansi-Cc33mW54.d.mts → ansi-CBkam1ty.d.mts} +1 -1
- package/dist/{ansi-Cc33mW54.d.mts.map → ansi-CBkam1ty.d.mts.map} +1 -1
- package/dist/ansi-OYRLxxZQ.mjs +10669 -0
- package/dist/ansi-OYRLxxZQ.mjs.map +1 -0
- package/dist/bound-term-BumfuXXW.d.mts +4902 -0
- package/dist/bound-term-BumfuXXW.d.mts.map +1 -0
- package/dist/{chunk-Vs_PY4HZ.mjs → chunk-hT5z_Zn9.mjs} +1 -3
- package/dist/cli-DG6zsfsS.mjs +4 -0
- package/dist/context-BU5LkkIy.mjs.map +1 -1
- package/dist/{devtools-DxkSLXDA.mjs → devtools-9zfhpFyG.mjs} +3 -3
- package/dist/{devtools-DxkSLXDA.mjs.map → devtools-9zfhpFyG.mjs.map} +1 -1
- package/dist/devtools-nmPUmYU_.mjs +2 -0
- package/dist/easing-B0oZKDki.d.mts +24 -0
- package/dist/easing-B0oZKDki.d.mts.map +1 -0
- package/dist/{eta-Bb3RH3wh.mjs → eta-DGOuC8yU.mjs} +5 -1
- package/dist/{eta-Bb3RH3wh.mjs.map → eta-DGOuC8yU.mjs.map} +1 -1
- package/dist/flexily-zero-adapter-CEJOcbNp.mjs +306 -0
- package/dist/flexily-zero-adapter-CEJOcbNp.mjs.map +1 -0
- package/dist/{flexily-zero-adapter-CMxXhdOL.mjs → flexily-zero-adapter-D6hcFgrH.mjs} +1 -1
- package/dist/image-1nRyKa60.mjs +5960 -0
- package/dist/image-1nRyKa60.mjs.map +1 -0
- package/dist/{index-D3saHouR.d.mts → index-2E1jYgak.d.mts} +1057 -1133
- package/dist/index-2E1jYgak.d.mts.map +1 -0
- package/dist/index-Bi4Jdz5g.d.mts +453 -0
- package/dist/index-Bi4Jdz5g.d.mts.map +1 -0
- package/dist/index-Dg1YaeJb.d.mts +336 -0
- package/dist/index-Dg1YaeJb.d.mts.map +1 -0
- package/dist/{index-BXslOebb.d.mts → index-DnuadDNL.d.mts} +5750 -4158
- package/dist/index-DnuadDNL.d.mts.map +1 -0
- package/dist/index.d.mts +8 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +16 -12
- package/dist/index.mjs.map +1 -1
- package/dist/layout-engine-Ca_nbtfL.mjs +67 -0
- package/dist/layout-engine-Ca_nbtfL.mjs.map +1 -0
- package/dist/{layout-engine-B6Cdz1yZ.mjs → layout-engine-CgsoBRIn.mjs} +1 -1
- package/dist/layout-signals-Dch2EiCy.mjs +1111 -0
- package/dist/layout-signals-Dch2EiCy.mjs.map +1 -0
- package/dist/mouse-events-hnbJZRwK.mjs +1071 -0
- package/dist/mouse-events-hnbJZRwK.mjs.map +1 -0
- package/dist/{multi-progress-DAQC7eap.d.mts → multi-progress-Bg4ngK80.d.mts} +2 -2
- package/dist/{multi-progress-DAQC7eap.d.mts.map → multi-progress-Bg4ngK80.d.mts.map} +1 -1
- package/dist/{multi-progress-Bq9Oi_WI.mjs → multi-progress-CaXTuL9G.mjs} +3 -3
- package/dist/{multi-progress-Bq9Oi_WI.mjs.map → multi-progress-CaXTuL9G.mjs.map} +1 -1
- package/dist/{node-BeWlnCPY.mjs → node-BiFu8I9Y.mjs} +4 -4
- package/dist/node-BiFu8I9Y.mjs.map +1 -0
- package/dist/progress-B_UPy6zk.mjs +675 -0
- package/dist/progress-B_UPy6zk.mjs.map +1 -0
- package/dist/{progress-bar-CXE5Qfkd.mjs → progress-bar-DmIMPdL0.mjs} +4 -4
- package/dist/{progress-bar-CXE5Qfkd.mjs.map → progress-bar-DmIMPdL0.mjs.map} +1 -1
- package/dist/reconciler-NBDSEm8k.mjs +2178 -0
- package/dist/reconciler-NBDSEm8k.mjs.map +1 -0
- package/dist/render-string-B4h4SmK7.mjs +211 -0
- package/dist/render-string-B4h4SmK7.mjs.map +1 -0
- package/dist/{render-string-CDCeYkS3.mjs → render-string-BntLj7Xq.mjs} +1 -1
- package/dist/runtime.d.mts +3 -2
- package/dist/runtime.mjs +3 -3
- package/dist/{src-B5GjfG7g.mjs → schemes-DYt2ushj.mjs} +23 -1812
- package/dist/schemes-DYt2ushj.mjs.map +1 -0
- package/dist/{spinner-CGo34vyR.d.mts → spinner-CLgzJ_QF.d.mts} +2 -2
- package/dist/{spinner-CGo34vyR.d.mts.map → spinner-CLgzJ_QF.d.mts.map} +1 -1
- package/dist/{spinner-CeOmcuw_.mjs → spinner-Py8_-hn9.mjs} +23 -8
- package/dist/spinner-Py8_-hn9.mjs.map +1 -0
- package/dist/src-B9S_woYc.mjs +25024 -0
- package/dist/src-B9S_woYc.mjs.map +1 -0
- package/dist/src-CbhWmUnF.mjs +3928 -0
- package/dist/src-CbhWmUnF.mjs.map +1 -0
- package/dist/src-Dvq-s8iD.mjs +939 -0
- package/dist/src-Dvq-s8iD.mjs.map +1 -0
- package/dist/src-Oe6x5PrS.mjs +4621 -0
- package/dist/src-Oe6x5PrS.mjs.map +1 -0
- package/dist/{types-Bk2yw9Qj.mjs → src-WeA_J4BV.mjs} +34 -94
- package/dist/src-WeA_J4BV.mjs.map +1 -0
- package/dist/steps-DYrzCUCK.d.mts +202 -0
- package/dist/steps-DYrzCUCK.d.mts.map +1 -0
- package/dist/svg-DhxQkz-O.mjs +255 -0
- package/dist/svg-DhxQkz-O.mjs.map +1 -0
- package/dist/svg-Hk7lIl4F.d.mts +82 -0
- package/dist/svg-Hk7lIl4F.d.mts.map +1 -0
- package/dist/term.d.mts +3 -0
- package/dist/term.mjs +4 -0
- package/dist/theme.d.mts +95 -2
- package/dist/theme.d.mts.map +1 -0
- package/dist/theme.mjs +4 -3
- package/dist/{types-BH_v3iMT.d.mts → types-Bx-XZNbE.d.mts} +2 -15
- package/dist/types-Bx-XZNbE.d.mts.map +1 -0
- package/dist/ui/animation.d.mts +2 -1
- package/dist/ui/animation.mjs +1 -1
- package/dist/ui/ansi.d.mts +1 -1
- package/dist/ui/ansi.mjs +1 -1
- package/dist/ui/cli.d.mts +3 -3
- package/dist/ui/cli.mjs +5 -5
- package/dist/ui/display.d.mts +1 -1
- package/dist/ui/display.mjs.map +1 -1
- package/dist/ui/image.d.mts +2 -2
- package/dist/ui/image.mjs +2 -2
- package/dist/ui/input.d.mts +1 -1
- package/dist/ui/input.mjs.map +1 -1
- package/dist/ui/progress.d.mts +5 -249
- package/dist/ui/progress.mjs +5 -858
- package/dist/ui/react.d.mts +1 -1
- package/dist/ui/react.mjs +2 -2
- package/dist/ui/react.mjs.map +1 -1
- package/dist/ui/recording-chrome-react.d.mts +21 -0
- package/dist/ui/recording-chrome-react.d.mts.map +1 -0
- package/dist/ui/recording-chrome-react.mjs +105 -0
- package/dist/ui/recording-chrome-react.mjs.map +1 -0
- package/dist/ui/recording-chrome.d.mts +2 -0
- package/dist/ui/recording-chrome.mjs +2 -0
- package/dist/ui/utils.mjs +1 -1
- package/dist/ui/wrappers.d.mts +3 -3
- package/dist/ui/wrappers.mjs +2 -2
- package/dist/ui.d.mts +7 -6
- package/dist/ui.mjs +8 -7
- package/dist/{useLatest-Bg2x4bfP.d.mts → useLatest-DC8i7guK.d.mts} +5 -25
- package/dist/useLatest-DC8i7guK.d.mts.map +1 -0
- package/dist/useLayout-BKsQl2Or.mjs +424 -0
- package/dist/useLayout-BKsQl2Or.mjs.map +1 -0
- package/dist/{with-text-input-CRfoiFFG.d.mts → with-text-input-DG4f7JII.d.mts} +4 -55
- package/dist/with-text-input-DG4f7JII.d.mts.map +1 -0
- package/dist/wrapper-D7gNSsgf.mjs +3589 -0
- package/dist/wrapper-D7gNSsgf.mjs.map +1 -0
- package/dist/{wrappers-UTADQkSY.mjs → wrappers-CypAzrMO.mjs} +19 -161
- package/dist/wrappers-CypAzrMO.mjs.map +1 -0
- package/dist/yoga-adapter-1ex8r0ws.mjs +2 -0
- package/dist/{yoga-adapter-8oRGRw8V.mjs → yoga-adapter-SsEIqMc1.mjs} +28 -2
- package/dist/yoga-adapter-SsEIqMc1.mjs.map +1 -0
- package/package.json +63 -12
- package/dist/animation-Cn64yepo.mjs.map +0 -1
- package/dist/cli-BKp0YtBD.mjs +0 -4
- package/dist/devtools-9QY4teqI.mjs +0 -2
- package/dist/flexily-zero-adapter-BlQa46nr.mjs +0 -3385
- package/dist/flexily-zero-adapter-BlQa46nr.mjs.map +0 -1
- package/dist/image-CTII5QWI.mjs +0 -477
- package/dist/image-CTII5QWI.mjs.map +0 -1
- package/dist/index-BXslOebb.d.mts.map +0 -1
- package/dist/index-BnA7mNpo.d.mts +0 -175
- package/dist/index-BnA7mNpo.d.mts.map +0 -1
- package/dist/index-D3saHouR.d.mts.map +0 -1
- package/dist/layout-engine-ClUgv6jB.mjs +0 -50
- package/dist/layout-engine-ClUgv6jB.mjs.map +0 -1
- package/dist/node-BeWlnCPY.mjs.map +0 -1
- package/dist/reconciler-Cwgm8hRR.mjs +0 -8459
- package/dist/reconciler-Cwgm8hRR.mjs.map +0 -1
- package/dist/render-string-Darrg7ku.mjs +0 -5529
- package/dist/render-string-Darrg7ku.mjs.map +0 -1
- package/dist/spinner-CeOmcuw_.mjs.map +0 -1
- package/dist/src-B5GjfG7g.mjs.map +0 -1
- package/dist/src-CChwjk0Z.mjs +0 -738
- package/dist/src-CChwjk0Z.mjs.map +0 -1
- package/dist/src-CF-6UN01.mjs +0 -19434
- package/dist/src-CF-6UN01.mjs.map +0 -1
- package/dist/src-NCKb8kE5.mjs +0 -2660
- package/dist/src-NCKb8kE5.mjs.map +0 -1
- package/dist/types-BH_v3iMT.d.mts.map +0 -1
- package/dist/types-Bk2yw9Qj.mjs.map +0 -1
- package/dist/ui/progress.d.mts.map +0 -1
- package/dist/ui/progress.mjs.map +0 -1
- package/dist/useLatest-Bg2x4bfP.d.mts.map +0 -1
- package/dist/with-text-input-CRfoiFFG.d.mts.map +0 -1
- package/dist/wrappers-UTADQkSY.mjs.map +0 -1
- package/dist/yoga-adapter-8oRGRw8V.mjs.map +0 -1
- package/dist/yoga-adapter-D_CcxSt5.mjs +0 -2
package/dist/ui/react.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as TaskStatus, l as SpinnerProps, m as TaskProps, n as ProgressBarProps, u as SpinnerStyle } from "../types-
|
|
1
|
+
import { g as TaskStatus, l as SpinnerProps, m as TaskProps, n as ProgressBarProps, u as SpinnerStyle } from "../types-Bx-XZNbE.mjs";
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
4
|
//#region packages/ag-react/src/ui/react/Spinner.d.ts
|
package/dist/ui/react.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as SPINNER_INTERVALS, t as SPINNER_FRAMES } from "../spinner-
|
|
2
|
-
import { a as getETA } from "../eta-
|
|
1
|
+
import { n as SPINNER_INTERVALS, t as SPINNER_FRAMES } from "../spinner-Py8_-hn9.mjs";
|
|
2
|
+
import { a as getETA } from "../eta-DGOuC8yU.mjs";
|
|
3
3
|
import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region packages/ag-react/src/ui/react/Spinner.tsx
|
package/dist/ui/react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.mjs","names":[],"sources":["../../packages/ag-react/src/ui/react/Spinner.tsx","../../packages/ag-react/src/ui/react/ProgressBar.tsx","../../packages/ag-react/src/ui/react/Tasks.tsx","../../packages/ag-react/src/ui/react/context.tsx"],"sourcesContent":["/**\n * React Spinner component for silvery/Ink TUI apps\n */\n\nimport React, { useState, useEffect } from \"react\"\nimport type { SpinnerProps, SpinnerStyle } from \"../types.js\"\nimport { SPINNER_FRAMES, SPINNER_INTERVALS } from \"../cli/spinner\"\n\n/**\n * Animated spinner component for React TUI apps\n *\n * @example\n * ```tsx\n * import { Spinner } from \"./index\";\n *\n * function LoadingView() {\n * return <Spinner label=\"Loading...\" />;\n * }\n *\n * // With style\n * <Spinner label=\"Processing...\" style=\"arc\" color=\"yellow\" />\n * ```\n */\nexport function Spinner({\n label,\n style = \"dots\",\n color = \"cyan\",\n}: SpinnerProps): React.ReactElement {\n const [frameIndex, setFrameIndex] = useState(0)\n const frames = SPINNER_FRAMES[style]\n const interval = SPINNER_INTERVALS[style]\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrameIndex((i) => (i + 1) % frames.length)\n }, interval)\n\n return () => clearInterval(timer)\n }, [frames.length, interval])\n\n const frame = frames[frameIndex]\n\n // Note: In a real silvery app, you'd use <Text color={color}> etc.\n // This is a generic React component that can be styled by the consumer\n return (\n <span data-progressx-spinner data-color={color}>\n {frame}\n {label && <span> {label}</span>}\n </span>\n )\n}\n\n/**\n * Hook for using spinner state in custom components\n *\n * @example\n * ```tsx\n * function CustomSpinner() {\n * const frame = useSpinnerFrame(\"dots\");\n * return <Text color=\"cyan\">{frame}</Text>;\n * }\n * ```\n */\nexport function useSpinnerFrame(style: SpinnerStyle = \"dots\"): string {\n const [frameIndex, setFrameIndex] = useState(0)\n const frames = SPINNER_FRAMES[style]\n const interval = SPINNER_INTERVALS[style]\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrameIndex((i) => (i + 1) % frames.length)\n }, interval)\n\n return () => clearInterval(timer)\n }, [frames.length, interval])\n\n return frames[frameIndex]!\n}\n","/**\n * React ProgressBar component for silvery/Ink TUI apps\n */\n\nimport React, { useState, useEffect, useRef } from \"react\"\nimport type { ProgressBarProps } from \"../types.js\"\nimport { getETA, DEFAULT_ETA_BUFFER_SIZE, type ETASample } from \"../utils/eta\"\n\n/**\n * Progress bar component for React TUI apps\n *\n * @example\n * ```tsx\n * import { ProgressBar } from \"./index\";\n *\n * function DownloadProgress({ current, total }) {\n * return (\n * <ProgressBar\n * value={current}\n * total={total}\n * showPercentage\n * showETA\n * />\n * );\n * }\n * ```\n */\nexport function ProgressBar({\n value,\n total,\n width = 40,\n showPercentage = true,\n showETA = false,\n label,\n color = \"cyan\",\n}: ProgressBarProps): React.ReactElement {\n // ETA calculation state\n const [eta, setEta] = useState<string>(\"--:--\")\n const etaBuffer = useRef<ETASample[]>([])\n\n // Update ETA buffer when value changes\n useEffect(() => {\n const now = Date.now()\n etaBuffer.current.push({ time: now, value })\n\n if (etaBuffer.current.length > DEFAULT_ETA_BUFFER_SIZE) {\n etaBuffer.current.shift()\n }\n\n // Calculate ETA using shared utility\n const result = getETA(etaBuffer.current, value, total)\n setEta(result.formatted)\n }, [value, total])\n\n const percent = total > 0 ? value / total : 0\n const percentDisplay = `${Math.round(percent * 100)}%`\n\n const filledWidth = Math.round(width * percent)\n const emptyWidth = width - filledWidth\n\n const bar = \"█\".repeat(filledWidth) + \"░\".repeat(emptyWidth)\n\n // Build the display parts\n const parts: string[] = []\n\n if (label) {\n parts.push(label)\n }\n\n parts.push(`[${bar}]`)\n\n if (showPercentage) {\n parts.push(percentDisplay.padStart(4))\n }\n\n if (showETA) {\n parts.push(`ETA: ${eta}`)\n }\n\n return (\n <span data-progressx-bar data-color={color} data-percent={percent}>\n {parts.join(\" \")}\n </span>\n )\n}\n\n/**\n * Hook for progress bar state management\n *\n * @example\n * ```tsx\n * function MyProgress() {\n * const { value, total, update, increment, eta, percent } = useProgressBar(100);\n *\n * useEffect(() => {\n * const timer = setInterval(() => increment(), 100);\n * return () => clearInterval(timer);\n * }, []);\n *\n * return <Text>{percent}% - ETA: {eta}</Text>;\n * }\n * ```\n */\nexport function useProgressBar(initialTotal: number) {\n const [value, setValue] = useState(0)\n const [total, setTotal] = useState(initialTotal)\n const etaBuffer = useRef<ETASample[]>([])\n const [eta, setEta] = useState<string>(\"--:--\")\n\n const update = (newValue: number) => {\n setValue(newValue)\n\n // Update ETA buffer\n const now = Date.now()\n etaBuffer.current.push({ time: now, value: newValue })\n if (etaBuffer.current.length > DEFAULT_ETA_BUFFER_SIZE) {\n etaBuffer.current.shift()\n }\n\n // Calculate ETA using shared utility\n const result = getETA(etaBuffer.current, newValue, total)\n setEta(result.formatted)\n }\n\n const increment = (amount = 1) => update(value + amount)\n\n const reset = (newTotal?: number) => {\n setValue(0)\n if (newTotal !== undefined) setTotal(newTotal)\n etaBuffer.current = []\n setEta(\"--:--\")\n }\n\n const percent = total > 0 ? Math.round((value / total) * 100) : 0\n\n return {\n value,\n total,\n percent,\n eta,\n update,\n increment,\n reset,\n setTotal,\n }\n}\n","/**\n * React Tasks component - listr2-style task list for TUI apps\n */\n\nimport React from \"react\"\nimport type { TaskProps, TaskStatus } from \"../types.js\"\nimport { useSpinnerFrame } from \"./Spinner\"\n\n/** Status icons for tasks */\nconst STATUS_ICONS: Record<TaskStatus, string> = {\n pending: \"○\",\n running: \"\", // Will use spinner\n completed: \"✔\",\n failed: \"✖\",\n skipped: \"⊘\",\n}\n\n/** Status colors */\nconst STATUS_COLORS: Record<TaskStatus, string> = {\n pending: \"gray\",\n running: \"cyan\",\n completed: \"green\",\n failed: \"red\",\n skipped: \"yellow\",\n}\n\n/**\n * Single task component\n *\n * @example\n * ```tsx\n * <Task title=\"Downloading files\" status=\"running\">\n * <ProgressBar value={50} total={100} />\n * </Task>\n * ```\n */\nexport function Task({ title, status, children }: TaskProps): React.ReactElement {\n const spinnerFrame = useSpinnerFrame(\"dots\")\n const icon = status === \"running\" ? spinnerFrame : STATUS_ICONS[status]\n const color = STATUS_COLORS[status]\n\n return (\n <div data-progressx-task data-status={status} data-color={color}>\n <span data-icon>{icon}</span>\n <span data-title> {title}</span>\n {children != null ? <div data-children>{children as React.ReactNode}</div> : null}\n </div>\n )\n}\n\n/**\n * Container for multiple tasks\n *\n * @example\n * ```tsx\n * <Tasks>\n * <Task title=\"Scanning files\" status=\"completed\" />\n * <Task title=\"Processing\" status=\"running\">\n * <ProgressBar value={current} total={total} />\n * </Task>\n * <Task title=\"Cleanup\" status=\"pending\" />\n * </Tasks>\n * ```\n */\nexport function Tasks({ children }: { children: React.ReactNode }): React.ReactElement {\n return <div data-progressx-tasks>{children}</div>\n}\n\n/**\n * Hook for managing task state\n *\n * @example\n * ```tsx\n * function MyTasks() {\n * const { tasks, start, complete, fail, updateProgress } = useTasks([\n * { id: 'scan', title: 'Scanning' },\n * { id: 'process', title: 'Processing' },\n * ]);\n *\n * useEffect(() => {\n * start('scan');\n * doScan().then(() => {\n * complete('scan');\n * start('process');\n * });\n * }, []);\n *\n * return (\n * <Tasks>\n * {tasks.map(t => <Task key={t.id} title={t.title} status={t.status} />)}\n * </Tasks>\n * );\n * }\n * ```\n */\nexport function useTasks(initialTasks: Array<{ id: string; title: string }>) {\n const [tasks, setTasks] = React.useState<\n Array<{\n id: string\n title: string\n status: TaskStatus\n progress?: { current: number; total: number }\n }>\n >(\n initialTasks.map((t) => ({\n ...t,\n status: \"pending\" as TaskStatus,\n })),\n )\n\n const updateTask = (\n id: string,\n updates: Partial<{\n status: TaskStatus\n title: string\n progress: { current: number; total: number }\n }>,\n ) => {\n setTasks((prev) => prev.map((t) => (t.id === id ? { ...t, ...updates } : t)))\n }\n\n const start = (id: string) => updateTask(id, { status: \"running\" })\n const complete = (id: string, title?: string) =>\n updateTask(id, { status: \"completed\", ...(title && { title }) })\n const fail = (id: string, title?: string) =>\n updateTask(id, { status: \"failed\", ...(title && { title }) })\n const skip = (id: string, title?: string) =>\n updateTask(id, { status: \"skipped\", ...(title && { title }) })\n const updateProgress = (id: string, progress: { current: number; total: number }) =>\n updateTask(id, { progress })\n\n const getTask = (id: string) => tasks.find((t) => t.id === id)\n const allCompleted = tasks.every((t) => t.status === \"completed\" || t.status === \"skipped\")\n const hasFailed = tasks.some((t) => t.status === \"failed\")\n\n return {\n tasks,\n start,\n complete,\n fail,\n skip,\n updateProgress,\n updateTask,\n getTask,\n allCompleted,\n hasFailed,\n }\n}\n","/**\n * React context for progress state management\n */\n\nimport React, { createContext, useContext, useState, useCallback } from \"react\"\nimport type { SpinnerStyle } from \"../types.js\"\nimport { Spinner } from \"./Spinner\"\n\n/** Progress context state */\ninterface ProgressContextState {\n /** Currently showing a spinner */\n isLoading: boolean\n /** Loading message */\n loadingText: string\n /** Spinner style */\n spinnerStyle: SpinnerStyle\n\n /** Show a spinner with message */\n showSpinner: (text: string, style?: SpinnerStyle) => void\n /** Hide the spinner */\n hideSpinner: () => void\n\n /** Progress bar state */\n progress: { current: number; total: number } | null\n /** Update progress */\n updateProgress: (current: number, total?: number) => void\n /** Clear progress */\n clearProgress: () => void\n}\n\nconst ProgressContext = createContext<ProgressContextState | null>(null)\n\n/**\n * Progress context provider\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ProgressProvider>\n * <MyApp />\n * </ProgressProvider>\n * );\n * }\n *\n * function DeepComponent() {\n * const { showSpinner, hideSpinner } = useProgress();\n *\n * const handleLoad = async () => {\n * showSpinner(\"Loading...\");\n * await loadData();\n * hideSpinner();\n * };\n * }\n * ```\n */\nexport function ProgressProvider({ children }: { children: React.ReactNode }): React.ReactElement {\n const [isLoading, setIsLoading] = useState(false)\n const [loadingText, setLoadingText] = useState(\"\")\n const [spinnerStyle, setSpinnerStyle] = useState<SpinnerStyle>(\"dots\")\n const [progress, setProgress] = useState<{\n current: number\n total: number\n } | null>(null)\n\n const showSpinner = useCallback((text: string, style: SpinnerStyle = \"dots\") => {\n setLoadingText(text)\n setSpinnerStyle(style)\n setIsLoading(true)\n }, [])\n\n const hideSpinner = useCallback(() => {\n setIsLoading(false)\n setLoadingText(\"\")\n }, [])\n\n const updateProgress = useCallback((current: number, total?: number) => {\n setProgress((prev) => ({\n current,\n total: total ?? prev?.total ?? 100,\n }))\n }, [])\n\n const clearProgress = useCallback(() => {\n setProgress(null)\n }, [])\n\n const value: ProgressContextState = {\n isLoading,\n loadingText,\n spinnerStyle,\n showSpinner,\n hideSpinner,\n progress,\n updateProgress,\n clearProgress,\n }\n\n return <ProgressContext.Provider value={value}>{children}</ProgressContext.Provider>\n}\n\n/**\n * Hook to access progress context\n *\n * @example\n * ```tsx\n * function LoadingOverlay() {\n * const { isLoading, loadingText, spinnerStyle } = useProgress();\n *\n * if (!isLoading) return null;\n *\n * return <Spinner label={loadingText} style={spinnerStyle} />;\n * }\n * ```\n */\nexport function useProgress(): ProgressContextState {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error(\"useProgress must be used within a ProgressProvider\")\n }\n\n return context\n}\n\n/**\n * Component that renders spinner when loading\n *\n * @example\n * ```tsx\n * <ProgressProvider>\n * <ProgressIndicator />\n * <MainContent />\n * </ProgressProvider>\n * ```\n */\nexport function ProgressIndicator(): React.ReactElement | null {\n const { isLoading, loadingText, spinnerStyle } = useProgress()\n\n if (!isLoading) {\n return null\n }\n\n return <Spinner label={loadingText} style={spinnerStyle} />\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.mjs","names":[],"sources":["../../packages/ag-react/src/ui/react/Spinner.tsx","../../packages/ag-react/src/ui/react/ProgressBar.tsx","../../packages/ag-react/src/ui/react/Tasks.tsx","../../packages/ag-react/src/ui/react/context.tsx"],"sourcesContent":["/**\n * React Spinner component for silvery/Ink TUI apps\n */\n\nimport React, { useState, useEffect } from \"react\"\nimport type { SpinnerProps, SpinnerStyle } from \"../types.js\"\nimport { SPINNER_FRAMES, SPINNER_INTERVALS } from \"../cli/spinner\"\n\n/**\n * Animated spinner component for React TUI apps\n *\n * @example\n * ```tsx\n * import { Spinner } from \"./index\";\n *\n * function LoadingView() {\n * return <Spinner label=\"Loading...\" />;\n * }\n *\n * // With style\n * <Spinner label=\"Processing...\" style=\"arc\" color=\"yellow\" />\n * ```\n */\nexport function Spinner({\n label,\n style = \"dots\",\n color = \"cyan\",\n}: SpinnerProps): React.ReactElement {\n const [frameIndex, setFrameIndex] = useState(0)\n const frames = SPINNER_FRAMES[style]\n const interval = SPINNER_INTERVALS[style]\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrameIndex((i) => (i + 1) % frames.length)\n }, interval)\n\n return () => clearInterval(timer)\n }, [frames.length, interval])\n\n const frame = frames[frameIndex]\n\n // Note: In a real silvery app, you'd use <Text color={color}> etc.\n // This is a generic React component that can be styled by the consumer\n return (\n <span data-progressx-spinner data-color={color}>\n {frame}\n {label && <span> {label}</span>}\n </span>\n )\n}\n\n/**\n * Hook for using spinner state in custom components\n *\n * @example\n * ```tsx\n * function CustomSpinner() {\n * const frame = useSpinnerFrame(\"dots\");\n * return <Text color=\"cyan\">{frame}</Text>;\n * }\n * ```\n */\nexport function useSpinnerFrame(style: SpinnerStyle = \"dots\"): string {\n const [frameIndex, setFrameIndex] = useState(0)\n const frames = SPINNER_FRAMES[style]\n const interval = SPINNER_INTERVALS[style]\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrameIndex((i) => (i + 1) % frames.length)\n }, interval)\n\n return () => clearInterval(timer)\n }, [frames.length, interval])\n\n return frames[frameIndex]!\n}\n","/**\n * React ProgressBar component for silvery/Ink TUI apps\n */\n\nimport React, { useState, useEffect, useRef } from \"react\"\nimport type { ProgressBarProps } from \"../types.js\"\nimport { getETA, DEFAULT_ETA_BUFFER_SIZE, type ETASample } from \"../utils/eta\"\n\n/**\n * Progress bar component for React TUI apps\n *\n * @example\n * ```tsx\n * import { ProgressBar } from \"./index\";\n *\n * function DownloadProgress({ current, total }) {\n * return (\n * <ProgressBar\n * value={current}\n * total={total}\n * showPercentage\n * showETA\n * />\n * );\n * }\n * ```\n */\nexport function ProgressBar({\n value,\n total,\n width = 40,\n showPercentage = true,\n showETA = false,\n label,\n color = \"cyan\",\n}: ProgressBarProps): React.ReactElement {\n // ETA calculation state\n const [eta, setEta] = useState<string>(\"--:--\")\n const etaBuffer = useRef<ETASample[]>([])\n\n // Update ETA buffer when value changes\n useEffect(() => {\n const now = Date.now()\n etaBuffer.current.push({ time: now, value })\n\n if (etaBuffer.current.length > DEFAULT_ETA_BUFFER_SIZE) {\n etaBuffer.current.shift()\n }\n\n // Calculate ETA using shared utility\n const result = getETA(etaBuffer.current, value, total)\n setEta(result.formatted)\n }, [value, total])\n\n const percent = total > 0 ? value / total : 0\n const percentDisplay = `${Math.round(percent * 100)}%`\n\n const filledWidth = Math.round(width * percent)\n const emptyWidth = width - filledWidth\n\n const bar = \"█\".repeat(filledWidth) + \"░\".repeat(emptyWidth)\n\n // Build the display parts\n const parts: string[] = []\n\n if (label) {\n parts.push(label)\n }\n\n parts.push(`[${bar}]`)\n\n if (showPercentage) {\n parts.push(percentDisplay.padStart(4))\n }\n\n if (showETA) {\n parts.push(`ETA: ${eta}`)\n }\n\n return (\n <span data-progressx-bar data-color={color} data-percent={percent}>\n {parts.join(\" \")}\n </span>\n )\n}\n\n/**\n * Hook for progress bar state management\n *\n * @example\n * ```tsx\n * function MyProgress() {\n * const { value, total, update, increment, eta, percent } = useProgressBar(100);\n *\n * useEffect(() => {\n * const timer = setInterval(() => increment(), 100);\n * return () => clearInterval(timer);\n * }, []);\n *\n * return <Text>{percent}% - ETA: {eta}</Text>;\n * }\n * ```\n */\nexport function useProgressBar(initialTotal: number) {\n const [value, setValue] = useState(0)\n const [total, setTotal] = useState(initialTotal)\n const etaBuffer = useRef<ETASample[]>([])\n const [eta, setEta] = useState<string>(\"--:--\")\n\n const update = (newValue: number) => {\n setValue(newValue)\n\n // Update ETA buffer\n const now = Date.now()\n etaBuffer.current.push({ time: now, value: newValue })\n if (etaBuffer.current.length > DEFAULT_ETA_BUFFER_SIZE) {\n etaBuffer.current.shift()\n }\n\n // Calculate ETA using shared utility\n const result = getETA(etaBuffer.current, newValue, total)\n setEta(result.formatted)\n }\n\n const increment = (amount = 1) => update(value + amount)\n\n const reset = (newTotal?: number) => {\n setValue(0)\n if (newTotal !== undefined) setTotal(newTotal)\n etaBuffer.current = []\n setEta(\"--:--\")\n }\n\n const percent = total > 0 ? Math.round((value / total) * 100) : 0\n\n return {\n value,\n total,\n percent,\n eta,\n update,\n increment,\n reset,\n setTotal,\n }\n}\n","/**\n * React Tasks component - listr2-style task list for TUI apps\n */\n\nimport React from \"react\"\nimport type { TaskProps, TaskStatus } from \"../types.js\"\nimport { useSpinnerFrame } from \"./Spinner\"\n\n/** Status icons for tasks */\nconst STATUS_ICONS: Record<TaskStatus, string> = {\n pending: \"○\",\n running: \"\", // Will use spinner\n completed: \"✔\",\n failed: \"✖\",\n skipped: \"⊘\",\n}\n\n/** Status colors */\nconst STATUS_COLORS: Record<TaskStatus, string> = {\n pending: \"gray\",\n running: \"cyan\",\n completed: \"green\",\n failed: \"red\",\n skipped: \"yellow\",\n}\n\n/**\n * Single task component\n *\n * @example\n * ```tsx\n * <Task title=\"Downloading files\" status=\"running\">\n * <ProgressBar value={50} total={100} />\n * </Task>\n * ```\n */\nexport function Task({ title, status, children }: TaskProps): React.ReactElement {\n const spinnerFrame = useSpinnerFrame(\"dots\")\n const icon = status === \"running\" ? spinnerFrame : STATUS_ICONS[status]\n const color = STATUS_COLORS[status]\n\n return (\n <div data-progressx-task data-status={status} data-color={color}>\n <span data-icon>{icon}</span>\n <span data-title> {title}</span>\n {children != null ? <div data-children>{children as React.ReactNode}</div> : null}\n </div>\n )\n}\n\n/**\n * Container for multiple tasks\n *\n * @example\n * ```tsx\n * <Tasks>\n * <Task title=\"Scanning files\" status=\"completed\" />\n * <Task title=\"Processing\" status=\"running\">\n * <ProgressBar value={current} total={total} />\n * </Task>\n * <Task title=\"Cleanup\" status=\"pending\" />\n * </Tasks>\n * ```\n */\nexport function Tasks({ children }: { children: React.ReactNode }): React.ReactElement {\n return <div data-progressx-tasks>{children}</div>\n}\n\n/**\n * Hook for managing task state\n *\n * @example\n * ```tsx\n * function MyTasks() {\n * const { tasks, start, complete, fail, updateProgress } = useTasks([\n * { id: 'scan', title: 'Scanning' },\n * { id: 'process', title: 'Processing' },\n * ]);\n *\n * useEffect(() => {\n * start('scan');\n * doScan().then(() => {\n * complete('scan');\n * start('process');\n * });\n * }, []);\n *\n * return (\n * <Tasks>\n * {tasks.map(t => <Task key={t.id} title={t.title} status={t.status} />)}\n * </Tasks>\n * );\n * }\n * ```\n */\nexport function useTasks(initialTasks: Array<{ id: string; title: string }>) {\n const [tasks, setTasks] = React.useState<\n Array<{\n id: string\n title: string\n status: TaskStatus\n progress?: { current: number; total: number }\n }>\n >(\n initialTasks.map((t) => ({\n ...t,\n status: \"pending\" as TaskStatus,\n })),\n )\n\n const updateTask = (\n id: string,\n updates: Partial<{\n status: TaskStatus\n title: string\n progress: { current: number; total: number }\n }>,\n ) => {\n setTasks((prev) => prev.map((t) => (t.id === id ? { ...t, ...updates } : t)))\n }\n\n const start = (id: string) => updateTask(id, { status: \"running\" })\n const complete = (id: string, title?: string) =>\n updateTask(id, { status: \"completed\", ...(title && { title }) })\n const fail = (id: string, title?: string) =>\n updateTask(id, { status: \"failed\", ...(title && { title }) })\n const skip = (id: string, title?: string) =>\n updateTask(id, { status: \"skipped\", ...(title && { title }) })\n const updateProgress = (id: string, progress: { current: number; total: number }) =>\n updateTask(id, { progress })\n\n const getTask = (id: string) => tasks.find((t) => t.id === id)\n const allCompleted = tasks.every((t) => t.status === \"completed\" || t.status === \"skipped\")\n const hasFailed = tasks.some((t) => t.status === \"failed\")\n\n return {\n tasks,\n start,\n complete,\n fail,\n skip,\n updateProgress,\n updateTask,\n getTask,\n allCompleted,\n hasFailed,\n }\n}\n","/**\n * React context for progress state management\n */\n\nimport React, { createContext, useContext, useState, useCallback } from \"react\"\nimport type { SpinnerStyle } from \"../types.js\"\nimport { Spinner } from \"./Spinner\"\n\n/** Progress context state */\ninterface ProgressContextState {\n /** Currently showing a spinner */\n isLoading: boolean\n /** Loading message */\n loadingText: string\n /** Spinner style */\n spinnerStyle: SpinnerStyle\n\n /** Show a spinner with message */\n showSpinner: (text: string, style?: SpinnerStyle) => void\n /** Hide the spinner */\n hideSpinner: () => void\n\n /** Progress bar state */\n progress: { current: number; total: number } | null\n /** Update progress */\n updateProgress: (current: number, total?: number) => void\n /** Clear progress */\n clearProgress: () => void\n}\n\nconst ProgressContext = createContext<ProgressContextState | null>(null)\n\n/**\n * Progress context provider\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ProgressProvider>\n * <MyApp />\n * </ProgressProvider>\n * );\n * }\n *\n * function DeepComponent() {\n * const { showSpinner, hideSpinner } = useProgress();\n *\n * const handleLoad = async () => {\n * showSpinner(\"Loading...\");\n * await loadData();\n * hideSpinner();\n * };\n * }\n * ```\n */\nexport function ProgressProvider({ children }: { children: React.ReactNode }): React.ReactElement {\n const [isLoading, setIsLoading] = useState(false)\n const [loadingText, setLoadingText] = useState(\"\")\n const [spinnerStyle, setSpinnerStyle] = useState<SpinnerStyle>(\"dots\")\n const [progress, setProgress] = useState<{\n current: number\n total: number\n } | null>(null)\n\n const showSpinner = useCallback((text: string, style: SpinnerStyle = \"dots\") => {\n setLoadingText(text)\n setSpinnerStyle(style)\n setIsLoading(true)\n }, [])\n\n const hideSpinner = useCallback(() => {\n setIsLoading(false)\n setLoadingText(\"\")\n }, [])\n\n const updateProgress = useCallback((current: number, total?: number) => {\n setProgress((prev) => ({\n current,\n total: total ?? prev?.total ?? 100,\n }))\n }, [])\n\n const clearProgress = useCallback(() => {\n setProgress(null)\n }, [])\n\n const value: ProgressContextState = {\n isLoading,\n loadingText,\n spinnerStyle,\n showSpinner,\n hideSpinner,\n progress,\n updateProgress,\n clearProgress,\n }\n\n return <ProgressContext.Provider value={value}>{children}</ProgressContext.Provider>\n}\n\n/**\n * Hook to access progress context\n *\n * @example\n * ```tsx\n * function LoadingOverlay() {\n * const { isLoading, loadingText, spinnerStyle } = useProgress();\n *\n * if (!isLoading) return null;\n *\n * return <Spinner label={loadingText} style={spinnerStyle} />;\n * }\n * ```\n */\nexport function useProgress(): ProgressContextState {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error(\"useProgress must be used within a ProgressProvider\")\n }\n\n return context\n}\n\n/**\n * Component that renders spinner when loading\n *\n * @example\n * ```tsx\n * <ProgressProvider>\n * <ProgressIndicator />\n * <MainContent />\n * </ProgressProvider>\n * ```\n */\nexport function ProgressIndicator(): React.ReactElement | null {\n const { isLoading, loadingText, spinnerStyle } = useProgress()\n\n if (!isLoading) {\n return null\n }\n\n return <Spinner label={loadingText} style={spinnerStyle} />\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,QAAQ,EACtB,OACA,QAAQ,QACR,QAAQ,UAC2B;CACnC,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAC/C,MAAM,SAAS,eAAe;CAC9B,MAAM,WAAW,kBAAkB;AAEnC,iBAAgB;EACd,MAAM,QAAQ,kBAAkB;AAC9B,kBAAe,OAAO,IAAI,KAAK,OAAO,OAAO;KAC5C,SAAS;AAEZ,eAAa,cAAc,MAAM;IAChC,CAAC,OAAO,QAAQ,SAAS,CAAC;CAE7B,MAAM,QAAQ,OAAO;AAIrB,QACE,qBAAC,QAAD;EAAM,0BAAA;EAAuB,cAAY;YAAzC,CACG,OACA,SAAS,qBAAC,QAAD,EAAA,UAAA,CAAM,KAAE,MAAa,EAAA,CAAA,CAC1B;;;;;;;;;;;;;;AAeX,SAAgB,gBAAgB,QAAsB,QAAgB;CACpE,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAC/C,MAAM,SAAS,eAAe;CAC9B,MAAM,WAAW,kBAAkB;AAEnC,iBAAgB;EACd,MAAM,QAAQ,kBAAkB;AAC9B,kBAAe,OAAO,IAAI,KAAK,OAAO,OAAO;KAC5C,SAAS;AAEZ,eAAa,cAAc,MAAM;IAChC,CAAC,OAAO,QAAQ,SAAS,CAAC;AAE7B,QAAO,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;ACjDhB,SAAgB,YAAY,EAC1B,OACA,OACA,QAAQ,IACR,iBAAiB,MACjB,UAAU,OACV,OACA,QAAQ,UAC+B;CAEvC,MAAM,CAAC,KAAK,UAAU,SAAiB,QAAQ;CAC/C,MAAM,YAAY,OAAoB,EAAE,CAAC;AAGzC,iBAAgB;EACd,MAAM,MAAM,KAAK,KAAK;AACtB,YAAU,QAAQ,KAAK;GAAE,MAAM;GAAK;GAAO,CAAC;AAE5C,MAAI,UAAU,QAAQ,SAAA,GACpB,WAAU,QAAQ,OAAO;AAK3B,SADe,OAAO,UAAU,SAAS,OAAO,MACnC,CAAC,UAAU;IACvB,CAAC,OAAO,MAAM,CAAC;CAElB,MAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ;CAC5C,MAAM,iBAAiB,GAAG,KAAK,MAAM,UAAU,IAAI,CAAC;CAEpD,MAAM,cAAc,KAAK,MAAM,QAAQ,QAAQ;CAC/C,MAAM,aAAa,QAAQ;CAE3B,MAAM,MAAM,IAAI,OAAO,YAAY,GAAG,IAAI,OAAO,WAAW;CAG5D,MAAM,QAAkB,EAAE;AAE1B,KAAI,MACF,OAAM,KAAK,MAAM;AAGnB,OAAM,KAAK,IAAI,IAAI,GAAG;AAEtB,KAAI,eACF,OAAM,KAAK,eAAe,SAAS,EAAE,CAAC;AAGxC,KAAI,QACF,OAAM,KAAK,QAAQ,MAAM;AAG3B,QACE,oBAAC,QAAD;EAAM,sBAAA;EAAmB,cAAY;EAAO,gBAAc;YACvD,MAAM,KAAK,IAAI;EACX,CAAA;;;;;;;;;;;;;;;;;;;AAqBX,SAAgB,eAAe,cAAsB;CACnD,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,CAAC,OAAO,YAAY,SAAS,aAAa;CAChD,MAAM,YAAY,OAAoB,EAAE,CAAC;CACzC,MAAM,CAAC,KAAK,UAAU,SAAiB,QAAQ;CAE/C,MAAM,UAAU,aAAqB;AACnC,WAAS,SAAS;EAGlB,MAAM,MAAM,KAAK,KAAK;AACtB,YAAU,QAAQ,KAAK;GAAE,MAAM;GAAK,OAAO;GAAU,CAAC;AACtD,MAAI,UAAU,QAAQ,SAAA,GACpB,WAAU,QAAQ,OAAO;AAK3B,SADe,OAAO,UAAU,SAAS,UAAU,MACtC,CAAC,UAAU;;CAG1B,MAAM,aAAa,SAAS,MAAM,OAAO,QAAQ,OAAO;CAExD,MAAM,SAAS,aAAsB;AACnC,WAAS,EAAE;AACX,MAAI,aAAa,KAAA,EAAW,UAAS,SAAS;AAC9C,YAAU,UAAU,EAAE;AACtB,SAAO,QAAQ;;AAKjB,QAAO;EACL;EACA;EACA,SALc,QAAQ,IAAI,KAAK,MAAO,QAAQ,QAAS,IAAI,GAAG;EAM9D;EACA;EACA;EACA;EACA;EACD;;;;;;;;ACvIH,MAAM,eAA2C;CAC/C,SAAS;CACT,SAAS;CACT,WAAW;CACX,QAAQ;CACR,SAAS;CACV;;AAGD,MAAM,gBAA4C;CAChD,SAAS;CACT,SAAS;CACT,WAAW;CACX,QAAQ;CACR,SAAS;CACV;;;;;;;;;;;AAYD,SAAgB,KAAK,EAAE,OAAO,QAAQ,YAA2C;CAC/E,MAAM,eAAe,gBAAgB,OAAO;CAC5C,MAAM,OAAO,WAAW,YAAY,eAAe,aAAa;CAChE,MAAM,QAAQ,cAAc;AAE5B,QACE,qBAAC,OAAD;EAAK,uBAAA;EAAoB,eAAa;EAAQ,cAAY;YAA1D;GACE,oBAAC,QAAD;IAAM,aAAA;cAAW;IAAY,CAAA;GAC7B,qBAAC,QAAD;IAAM,cAAA;cAAN,CAAiB,KAAE,MAAa;;GAC/B,YAAY,OAAO,oBAAC,OAAD;IAAK,iBAAA;IAAe;IAAkC,CAAA,GAAG;GACzE;;;;;;;;;;;;;;;;;AAkBV,SAAgB,MAAM,EAAE,YAA+D;AACrF,QAAO,oBAAC,OAAD;EAAK,wBAAA;EAAsB;EAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BnD,SAAgB,SAAS,cAAoD;CAC3E,MAAM,CAAC,OAAO,YAAY,MAAM,SAQ9B,aAAa,KAAK,OAAO;EACvB,GAAG;EACH,QAAQ;EACT,EAAE,CACJ;CAED,MAAM,cACJ,IACA,YAKG;AACH,YAAU,SAAS,KAAK,KAAK,MAAO,EAAE,OAAO,KAAK;GAAE,GAAG;GAAG,GAAG;GAAS,GAAG,EAAG,CAAC;;CAG/E,MAAM,SAAS,OAAe,WAAW,IAAI,EAAE,QAAQ,WAAW,CAAC;CACnE,MAAM,YAAY,IAAY,UAC5B,WAAW,IAAI;EAAE,QAAQ;EAAa,GAAI,SAAS,EAAE,OAAO;EAAG,CAAC;CAClE,MAAM,QAAQ,IAAY,UACxB,WAAW,IAAI;EAAE,QAAQ;EAAU,GAAI,SAAS,EAAE,OAAO;EAAG,CAAC;CAC/D,MAAM,QAAQ,IAAY,UACxB,WAAW,IAAI;EAAE,QAAQ;EAAW,GAAI,SAAS,EAAE,OAAO;EAAG,CAAC;CAChE,MAAM,kBAAkB,IAAY,aAClC,WAAW,IAAI,EAAE,UAAU,CAAC;CAE9B,MAAM,WAAW,OAAe,MAAM,MAAM,MAAM,EAAE,OAAO,GAAG;AAI9D,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAZmB,MAAM,OAAO,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,UAYnE;EACZ,WAZgB,MAAM,MAAM,MAAM,EAAE,WAAW,SAYtC;EACV;;;;;;;ACpHH,MAAM,kBAAkB,cAA2C,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;AA0BxE,SAAgB,iBAAiB,EAAE,YAA+D;CAChG,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,aAAa,kBAAkB,SAAS,GAAG;CAClD,MAAM,CAAC,cAAc,mBAAmB,SAAuB,OAAO;CACtE,MAAM,CAAC,UAAU,eAAe,SAGtB,KAAK;CAwBf,MAAM,QAA8B;EAClC;EACA;EACA;EACA,aA1BkB,aAAa,MAAc,QAAsB,WAAW;AAC9E,kBAAe,KAAK;AACpB,mBAAgB,MAAM;AACtB,gBAAa,KAAK;KACjB,EAAE,CAsBQ;EACX,aArBkB,kBAAkB;AACpC,gBAAa,MAAM;AACnB,kBAAe,GAAG;KACjB,EAAE,CAkBQ;EACX;EACA,gBAlBqB,aAAa,SAAiB,UAAmB;AACtE,gBAAa,UAAU;IACrB;IACA,OAAO,SAAS,MAAM,SAAS;IAChC,EAAE;KACF,EAAE,CAaW;EACd,eAZoB,kBAAkB;AACtC,eAAY,KAAK;KAChB,EAAE,CAUU;EACd;AAED,QAAO,oBAAC,gBAAgB,UAAjB;EAAiC;EAAQ;EAAoC,CAAA;;;;;;;;;;;;;;;;AAiBtF,SAAgB,cAAoC;CAClD,MAAM,UAAU,WAAW,gBAAgB;AAE3C,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,qDAAqD;AAGvE,QAAO;;;;;;;;;;;;;AAcT,SAAgB,oBAA+C;CAC7D,MAAM,EAAE,WAAW,aAAa,iBAAiB,aAAa;AAE9D,KAAI,CAAC,UACH,QAAO;AAGT,QAAO,oBAAC,SAAD;EAAS,OAAO;EAAa,OAAO;EAAgB,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { a as RecordingChromeAlignment, d as RecordingChromeSpec, f as RecordingChromeStyle } from "../svg-Hk7lIl4F.mjs";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
//#region packages/ag-react/src/ui/recording-chrome/RecordingChrome.d.ts
|
|
5
|
+
interface RecordingChromeStatus {
|
|
6
|
+
elapsed: string;
|
|
7
|
+
blinkOn?: boolean;
|
|
8
|
+
stopHint?: string;
|
|
9
|
+
}
|
|
10
|
+
interface RecordingChromeProps {
|
|
11
|
+
chrome?: RecordingChromeStyle;
|
|
12
|
+
spec?: RecordingChromeSpec;
|
|
13
|
+
alignment?: RecordingChromeAlignment;
|
|
14
|
+
title?: string;
|
|
15
|
+
status?: RecordingChromeStatus | false;
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare function RecordingChrome(props: RecordingChromeProps): React.ReactElement;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { RecordingChrome as unstable_RecordingChrome, type RecordingChromeProps as unstable_RecordingChromeProps, type RecordingChromeStatus as unstable_RecordingChromeStatus };
|
|
21
|
+
//# sourceMappingURL=recording-chrome-react.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-chrome-react.d.mts","names":[],"sources":["../../packages/ag-react/src/ui/recording-chrome/RecordingChrome.tsx"],"mappings":";;;;UAUiB,qBAAA;EACf,OAAA;EACA,OAAA;EACA,QAAA;AAAA;AAAA,UAGe,oBAAA;EACf,MAAA,GAAS,oBAAA;EACT,IAAA,GAAO,mBAAA;EACP,SAAA,GAAY,wBAAA;EACZ,KAAA;EACA,MAAA,GAAS,qBAAA;EACT,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,iBAsDF,eAAA,CAAgB,KAAA,EAAO,oBAAA,GAAuB,KAAA,CAAM,YAAA"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { a as Box, t as Text } from "../Text-BRf-59j2.mjs";
|
|
2
|
+
import { r as composeRecordingChromeSpec } from "../svg-DhxQkz-O.mjs";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region packages/ag-react/src/ui/recording-chrome/RecordingChrome.tsx
|
|
6
|
+
function StatusLine(props) {
|
|
7
|
+
const { elapsed, blinkOn = true, stopHint = "Ctrl+D to stop" } = props.status;
|
|
8
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
9
|
+
flexDirection: "row",
|
|
10
|
+
children: [
|
|
11
|
+
/* @__PURE__ */ jsx(Text, {
|
|
12
|
+
color: blinkOn ? "red" : void 0,
|
|
13
|
+
children: blinkOn ? "●" : " "
|
|
14
|
+
}),
|
|
15
|
+
/* @__PURE__ */ jsx(Text, { children: ` REC ${elapsed} ` }),
|
|
16
|
+
/* @__PURE__ */ jsx(Text, {
|
|
17
|
+
color: "$fg-muted",
|
|
18
|
+
children: `· ${stopHint}`
|
|
19
|
+
})
|
|
20
|
+
]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function TitleBar(props) {
|
|
24
|
+
const { spec } = props;
|
|
25
|
+
const titleBar = spec.live.titleBar;
|
|
26
|
+
if (titleBar === null) return null;
|
|
27
|
+
if (titleBar.controlsSide === "right") return /* @__PURE__ */ jsxs(Box, {
|
|
28
|
+
flexDirection: "row",
|
|
29
|
+
paddingX: 1,
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsx(Text, {
|
|
32
|
+
bold: true,
|
|
33
|
+
children: spec.title
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ jsx(Box, { flexGrow: 1 }),
|
|
36
|
+
titleBar.controls.map((control, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [index > 0 && /* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Text, {
|
|
37
|
+
color: control.color,
|
|
38
|
+
children: control.glyph
|
|
39
|
+
})] }, `${control.glyph}-${index}`))
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
43
|
+
flexDirection: "row",
|
|
44
|
+
paddingX: 1,
|
|
45
|
+
children: [
|
|
46
|
+
titleBar.controls.map((control, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [index > 0 && /* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Text, {
|
|
47
|
+
color: control.color,
|
|
48
|
+
children: control.glyph
|
|
49
|
+
})] }, `${control.glyph}-${index}`)),
|
|
50
|
+
titleBar.separator && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
51
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
52
|
+
/* @__PURE__ */ jsx(Text, {
|
|
53
|
+
color: "$fg-muted",
|
|
54
|
+
children: titleBar.separator
|
|
55
|
+
}),
|
|
56
|
+
/* @__PURE__ */ jsx(Text, { children: " " })
|
|
57
|
+
] }),
|
|
58
|
+
/* @__PURE__ */ jsx(Text, {
|
|
59
|
+
bold: true,
|
|
60
|
+
children: spec.title
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function RecordingChrome(props) {
|
|
66
|
+
const spec = props.spec ?? composeRecordingChromeSpec({
|
|
67
|
+
style: props.chrome,
|
|
68
|
+
title: props.title,
|
|
69
|
+
alignment: props.alignment
|
|
70
|
+
});
|
|
71
|
+
const alignItems = spec.alignment === "left" ? "flex-start" : "center";
|
|
72
|
+
const status = props.status === false ? null : /* @__PURE__ */ jsx(StatusLine, { status: props.status ?? { elapsed: "0:00" } });
|
|
73
|
+
const rootProps = {
|
|
74
|
+
flexDirection: "column",
|
|
75
|
+
justifyContent: "center",
|
|
76
|
+
alignItems,
|
|
77
|
+
width: "100%",
|
|
78
|
+
height: "100%",
|
|
79
|
+
backgroundColor: "$bg"
|
|
80
|
+
};
|
|
81
|
+
if (spec.live.borderStyle === "none") return /* @__PURE__ */ jsxs(Box, {
|
|
82
|
+
...rootProps,
|
|
83
|
+
children: [
|
|
84
|
+
status,
|
|
85
|
+
status && /* @__PURE__ */ jsx(Box, {}),
|
|
86
|
+
props.children
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
90
|
+
...rootProps,
|
|
91
|
+
children: [
|
|
92
|
+
status,
|
|
93
|
+
status && /* @__PURE__ */ jsx(Box, {}),
|
|
94
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
95
|
+
borderStyle: spec.live.borderStyle,
|
|
96
|
+
flexDirection: "column",
|
|
97
|
+
children: [/* @__PURE__ */ jsx(TitleBar, { spec }), props.children]
|
|
98
|
+
})
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { RecordingChrome as unstable_RecordingChrome };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=recording-chrome-react.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-chrome-react.mjs","names":[],"sources":["../../packages/ag-react/src/ui/recording-chrome/RecordingChrome.tsx"],"sourcesContent":["import React from \"react\"\nimport { Box } from \"../../components/Box\"\nimport { Text } from \"../../components/Text\"\nimport {\n composeRecordingChromeSpec,\n type RecordingChromeAlignment,\n type RecordingChromeSpec,\n type RecordingChromeStyle,\n} from \"./spec\"\n\nexport interface RecordingChromeStatus {\n elapsed: string\n blinkOn?: boolean\n stopHint?: string\n}\n\nexport interface RecordingChromeProps {\n chrome?: RecordingChromeStyle\n spec?: RecordingChromeSpec\n alignment?: RecordingChromeAlignment\n title?: string\n status?: RecordingChromeStatus | false\n children: React.ReactNode\n}\n\nfunction StatusLine(props: { status: RecordingChromeStatus }): React.ReactElement {\n const { elapsed, blinkOn = true, stopHint = \"Ctrl+D to stop\" } = props.status\n return (\n <Box flexDirection=\"row\">\n <Text color={blinkOn ? \"red\" : undefined}>{blinkOn ? \"●\" : \" \"}</Text>\n <Text>{` REC ${elapsed} `}</Text>\n <Text color=\"$fg-muted\">{`· ${stopHint}`}</Text>\n </Box>\n )\n}\n\nfunction TitleBar(props: { spec: RecordingChromeSpec }): React.ReactElement | null {\n const { spec } = props\n const titleBar = spec.live.titleBar\n if (titleBar === null) return null\n\n if (titleBar.controlsSide === \"right\") {\n return (\n <Box flexDirection=\"row\" paddingX={1}>\n <Text bold>{spec.title}</Text>\n <Box flexGrow={1} />\n {titleBar.controls.map((control, index) => (\n <React.Fragment key={`${control.glyph}-${index}`}>\n {index > 0 && <Text>{\" \"}</Text>}\n <Text color={control.color}>{control.glyph}</Text>\n </React.Fragment>\n ))}\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\" paddingX={1}>\n {titleBar.controls.map((control, index) => (\n <React.Fragment key={`${control.glyph}-${index}`}>\n {index > 0 && <Text> </Text>}\n <Text color={control.color}>{control.glyph}</Text>\n </React.Fragment>\n ))}\n {titleBar.separator && (\n <>\n <Text>{\" \"}</Text>\n <Text color=\"$fg-muted\">{titleBar.separator}</Text>\n <Text>{\" \"}</Text>\n </>\n )}\n <Text bold>{spec.title}</Text>\n </Box>\n )\n}\n\nexport function RecordingChrome(props: RecordingChromeProps): React.ReactElement {\n const spec =\n props.spec ??\n composeRecordingChromeSpec({\n style: props.chrome,\n title: props.title,\n alignment: props.alignment,\n })\n\n const alignItems = spec.alignment === \"left\" ? (\"flex-start\" as const) : (\"center\" as const)\n const status =\n props.status === false ? null : <StatusLine status={props.status ?? { elapsed: \"0:00\" }} />\n\n const rootProps = {\n flexDirection: \"column\" as const,\n justifyContent: \"center\" as const,\n alignItems,\n width: \"100%\" as const,\n height: \"100%\" as const,\n backgroundColor: \"$bg\",\n }\n\n if (spec.live.borderStyle === \"none\") {\n return (\n <Box {...rootProps}>\n {status}\n {status && <Box />}\n {props.children}\n </Box>\n )\n }\n\n return (\n <Box {...rootProps}>\n {status}\n {status && <Box />}\n <Box borderStyle={spec.live.borderStyle} flexDirection=\"column\">\n <TitleBar spec={spec} />\n {props.children}\n </Box>\n </Box>\n )\n}\n"],"mappings":";;;;;AAyBA,SAAS,WAAW,OAA8D;CAChF,MAAM,EAAE,SAAS,UAAU,MAAM,WAAW,qBAAqB,MAAM;AACvE,QACE,qBAAC,KAAD;EAAK,eAAc;YAAnB;GACE,oBAAC,MAAD;IAAM,OAAO,UAAU,QAAQ,KAAA;cAAY,UAAU,MAAM;IAAW,CAAA;GACtE,oBAAC,MAAD,EAAA,UAAO,QAAQ,QAAQ,KAAW,CAAA;GAClC,oBAAC,MAAD;IAAM,OAAM;cAAa,KAAK;IAAkB,CAAA;GAC5C;;;AAIV,SAAS,SAAS,OAAiE;CACjF,MAAM,EAAE,SAAS;CACjB,MAAM,WAAW,KAAK,KAAK;AAC3B,KAAI,aAAa,KAAM,QAAO;AAE9B,KAAI,SAAS,iBAAiB,QAC5B,QACE,qBAAC,KAAD;EAAK,eAAc;EAAM,UAAU;YAAnC;GACE,oBAAC,MAAD;IAAM,MAAA;cAAM,KAAK;IAAa,CAAA;GAC9B,oBAAC,KAAD,EAAK,UAAU,GAAK,CAAA;GACnB,SAAS,SAAS,KAAK,SAAS,UAC/B,qBAAC,MAAM,UAAP,EAAA,UAAA,CACG,QAAQ,KAAK,oBAAC,MAAD,EAAA,UAAO,MAAY,CAAA,EACjC,oBAAC,MAAD;IAAM,OAAO,QAAQ;cAAQ,QAAQ;IAAa,CAAA,CACnC,EAAA,EAHI,GAAG,QAAQ,MAAM,GAAG,QAGxB,CACjB;GACE;;AAIV,QACE,qBAAC,KAAD;EAAK,eAAc;EAAM,UAAU;YAAnC;GACG,SAAS,SAAS,KAAK,SAAS,UAC/B,qBAAC,MAAM,UAAP,EAAA,UAAA,CACG,QAAQ,KAAK,oBAAC,MAAD,EAAA,UAAM,KAAQ,CAAA,EAC5B,oBAAC,MAAD;IAAM,OAAO,QAAQ;cAAQ,QAAQ;IAAa,CAAA,CACnC,EAAA,EAHI,GAAG,QAAQ,MAAM,GAAG,QAGxB,CACjB;GACD,SAAS,aACR,qBAAA,UAAA,EAAA,UAAA;IACE,oBAAC,MAAD,EAAA,UAAO,MAAY,CAAA;IACnB,oBAAC,MAAD;KAAM,OAAM;eAAa,SAAS;KAAiB,CAAA;IACnD,oBAAC,MAAD,EAAA,UAAO,MAAY,CAAA;IAClB,EAAA,CAAA;GAEL,oBAAC,MAAD;IAAM,MAAA;cAAM,KAAK;IAAa,CAAA;GAC1B;;;AAIV,SAAgB,gBAAgB,OAAiD;CAC/E,MAAM,OACJ,MAAM,QACN,2BAA2B;EACzB,OAAO,MAAM;EACb,OAAO,MAAM;EACb,WAAW,MAAM;EAClB,CAAC;CAEJ,MAAM,aAAa,KAAK,cAAc,SAAU,eAA0B;CAC1E,MAAM,SACJ,MAAM,WAAW,QAAQ,OAAO,oBAAC,YAAD,EAAY,QAAQ,MAAM,UAAU,EAAE,SAAS,QAAQ,EAAI,CAAA;CAE7F,MAAM,YAAY;EAChB,eAAe;EACf,gBAAgB;EAChB;EACA,OAAO;EACP,QAAQ;EACR,iBAAiB;EAClB;AAED,KAAI,KAAK,KAAK,gBAAgB,OAC5B,QACE,qBAAC,KAAD;EAAK,GAAI;YAAT;GACG;GACA,UAAU,oBAAC,KAAD,EAAO,CAAA;GACjB,MAAM;GACH;;AAIV,QACE,qBAAC,KAAD;EAAK,GAAI;YAAT;GACG;GACA,UAAU,oBAAC,KAAD,EAAO,CAAA;GAClB,qBAAC,KAAD;IAAK,aAAa,KAAK,KAAK;IAAa,eAAc;cAAvD,CACE,oBAAC,UAAD,EAAgB,MAAQ,CAAA,EACvB,MAAM,SACH;;GACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as composeRecordingChromeSpec, a as RecordingChromeAlignment, b as recordingChromeSvgContentOffset, c as RecordingChromeControlSide, d as RecordingChromeSpec, f as RecordingChromeStyle, g as RecordingChromeTitleBarSpec, h as RecordingChromeSvgWindowBar, i as RECORDING_CHROME_STYLES, l as RecordingChromeLiveSpec, m as RecordingChromeSvgOptions, n as composeRecordingChromeSvg, o as RecordingChromeBorderStyle, p as RecordingChromeSvgLayout, r as ComposeRecordingChromeSpecOptions, s as RecordingChromeControl, t as ComposeRecordingChromeSvgOptions, u as RecordingChromeOverhead, v as recordingChromeOverhead, x as recordingChromeSvgLayout, y as recordingChromeSpecToSvgOptions } from "../svg-Hk7lIl4F.mjs";
|
|
2
|
+
export { type ComposeRecordingChromeSpecOptions as unstable_ComposeRecordingChromeSpecOptions, type ComposeRecordingChromeSvgOptions as unstable_ComposeRecordingChromeSvgOptions, RECORDING_CHROME_STYLES as unstable_RECORDING_CHROME_STYLES, type RecordingChromeAlignment as unstable_RecordingChromeAlignment, type RecordingChromeBorderStyle as unstable_RecordingChromeBorderStyle, type RecordingChromeControl as unstable_RecordingChromeControl, type RecordingChromeControlSide as unstable_RecordingChromeControlSide, type RecordingChromeLiveSpec as unstable_RecordingChromeLiveSpec, type RecordingChromeOverhead as unstable_RecordingChromeOverhead, type RecordingChromeSpec as unstable_RecordingChromeSpec, type RecordingChromeStyle as unstable_RecordingChromeStyle, type RecordingChromeSvgLayout as unstable_RecordingChromeSvgLayout, type RecordingChromeSvgOptions as unstable_RecordingChromeSvgOptions, type RecordingChromeSvgWindowBar as unstable_RecordingChromeSvgWindowBar, type RecordingChromeTitleBarSpec as unstable_RecordingChromeTitleBarSpec, composeRecordingChromeSpec as unstable_composeRecordingChromeSpec, composeRecordingChromeSvg as unstable_composeRecordingChromeSvg, recordingChromeOverhead as unstable_recordingChromeOverhead, recordingChromeSpecToSvgOptions as unstable_recordingChromeSpecToSvgOptions, recordingChromeSvgContentOffset as unstable_recordingChromeSvgContentOffset, recordingChromeSvgLayout as unstable_recordingChromeSvgLayout };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as recordingChromeSpecToSvgOptions, i as recordingChromeOverhead, n as RECORDING_CHROME_STYLES, o as recordingChromeSvgContentOffset, r as composeRecordingChromeSpec, s as recordingChromeSvgLayout, t as composeRecordingChromeSvg } from "../svg-DhxQkz-O.mjs";
|
|
2
|
+
export { RECORDING_CHROME_STYLES as unstable_RECORDING_CHROME_STYLES, composeRecordingChromeSpec as unstable_composeRecordingChromeSpec, composeRecordingChromeSvg as unstable_composeRecordingChromeSvg, recordingChromeOverhead as unstable_recordingChromeOverhead, recordingChromeSpecToSvgOptions as unstable_recordingChromeSpecToSvgOptions, recordingChromeSvgContentOffset as unstable_recordingChromeSvgContentOffset, recordingChromeSvgLayout as unstable_recordingChromeSvgLayout };
|
package/dist/ui/utils.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as getETA, i as formatETA, n as calculateETA, r as createETATracker, t as DEFAULT_ETA_BUFFER_SIZE } from "../eta-
|
|
1
|
+
import { a as getETA, i as formatETA, n as calculateETA, r as createETATracker, t as DEFAULT_ETA_BUFFER_SIZE } from "../eta-DGOuC8yU.mjs";
|
|
2
2
|
export { DEFAULT_ETA_BUFFER_SIZE, calculateETA, createETATracker, formatETA, getETA };
|
package/dist/ui/wrappers.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { _ as TextInputOptions, a as ProgressInfo, r as ProgressCallback } from "../types-
|
|
2
|
-
import { a as waitForEvent, c as wrapGenerator,
|
|
3
|
-
export { ProgressCallback, ProgressInfo, TextInputOptions, attachSpinner,
|
|
1
|
+
import { _ as TextInputOptions, a as ProgressInfo, r as ProgressCallback } from "../types-Bx-XZNbE.mjs";
|
|
2
|
+
import { a as waitForEvent, c as wrapGenerator, i as withSelect, l as attachSpinner, n as withTextInput, o as wrapEmitter, r as createSelect, s as withIterableProgress, t as createTextInput, u as withSpinner } from "../with-text-input-DG4f7JII.mjs";
|
|
3
|
+
export { ProgressCallback, ProgressInfo, TextInputOptions, attachSpinner, createSelect, createTextInput, waitForEvent, withIterableProgress, withSelect, withSpinner, withTextInput, wrapEmitter, wrapGenerator };
|
package/dist/ui/wrappers.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as waitForEvent, c as wrapGenerator,
|
|
2
|
-
export { attachSpinner,
|
|
1
|
+
import { a as waitForEvent, c as wrapGenerator, i as withSelect, l as attachSpinner, n as withTextInput, o as wrapEmitter, r as createSelect, s as withIterableProgress, t as createTextInput, u as withSpinner } from "../wrappers-CypAzrMO.mjs";
|
|
2
|
+
export { attachSpinner, createSelect, createTextInput, waitForEvent, withIterableProgress, withSelect, withSpinner, withTextInput, wrapEmitter, wrapGenerator };
|
package/dist/ui.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { _ as TextInputOptions, a as ProgressInfo, b as
|
|
2
|
-
import { i as createSpinner, n as SPINNER_FRAMES, r as Spinner, t as CallableSpinner } from "./spinner-
|
|
3
|
-
import { n as TaskHandle, r as ProgressBar, t as MultiProgress } from "./multi-progress-
|
|
4
|
-
import { a as CURSOR_RESTORE, c as CURSOR_TO_START, d as getTerminalWidth, f as isTTY, h as writeLine, i as CURSOR_HIDE, l as cursorDown, m as write, n as CLEAR_LINE_END, o as CURSOR_SAVE, p as withCursor, r as CLEAR_SCREEN, s as CURSOR_SHOW, t as CLEAR_LINE, u as cursorUp } from "./ansi-
|
|
5
|
-
import { a as waitForEvent, c as wrapGenerator,
|
|
6
|
-
|
|
1
|
+
import { _ as TextInputOptions, a as ProgressInfo, b as WithSpinnerOptions, c as SpinnerOptions, d as StepProgress, f as TableColumn, g as TaskStatus, h as TaskState, i as ProgressGenerator, l as SpinnerProps, m as TaskProps, n as ProgressBarProps, o as SelectOption, p as TableProps, r as ProgressCallback, s as SelectProps, t as ProgressBarOptions, u as SpinnerStyle, v as TextInputProps, y as WithSelectOptions } from "./types-Bx-XZNbE.mjs";
|
|
2
|
+
import { i as createSpinner, n as SPINNER_FRAMES, r as Spinner, t as CallableSpinner } from "./spinner-CLgzJ_QF.mjs";
|
|
3
|
+
import { n as TaskHandle, r as ProgressBar, t as MultiProgress } from "./multi-progress-Bg4ngK80.mjs";
|
|
4
|
+
import { a as CURSOR_RESTORE, c as CURSOR_TO_START, d as getTerminalWidth, f as isTTY, h as writeLine, i as CURSOR_HIDE, l as cursorDown, m as write, n as CLEAR_LINE_END, o as CURSOR_SAVE, p as withCursor, r as CLEAR_SCREEN, s as CURSOR_SHOW, t as CLEAR_LINE, u as cursorUp } from "./ansi-CBkam1ty.mjs";
|
|
5
|
+
import { a as waitForEvent, c as wrapGenerator, i as withSelect, l as attachSpinner, n as withTextInput, o as wrapEmitter, r as createSelect, s as withIterableProgress, t as createTextInput, u as withSpinner } from "./with-text-input-DG4f7JII.mjs";
|
|
6
|
+
import { a as StepContext, c as StepsDef, i as StepsRunner, n as StepBuilder, o as step, r as steps, s as StepNode, t as ExecuteOptions } from "./steps-DYrzCUCK.mjs";
|
|
7
|
+
export { CLEAR_LINE, CLEAR_LINE_END, CLEAR_SCREEN, CURSOR_HIDE, CURSOR_RESTORE, CURSOR_SAVE, CURSOR_SHOW, CURSOR_TO_START, CallableSpinner, ExecuteOptions, MultiProgress, ProgressBar, ProgressBarOptions, ProgressBarProps, ProgressCallback, ProgressGenerator, ProgressInfo, SPINNER_FRAMES, SelectOption, SelectProps, Spinner, SpinnerOptions, SpinnerProps, SpinnerStyle, StepBuilder, StepContext, StepNode, StepProgress, StepsDef, StepsRunner, TableColumn, TableProps, TaskHandle, TaskProps, TaskState, TaskStatus, TextInputOptions, TextInputProps, WithSelectOptions, WithSpinnerOptions, attachSpinner, createSelect, createSpinner, createTextInput, cursorDown, cursorUp, getTerminalWidth, isTTY, step, steps, waitForEvent, withCursor, withIterableProgress, withSelect, withSpinner, withTextInput, wrapEmitter, wrapGenerator, write, writeLine };
|
package/dist/ui.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { i as createSpinner, r as Spinner, t as SPINNER_FRAMES } from "./spinner-
|
|
2
|
-
import { a as CURSOR_RESTORE, c as CURSOR_TO_START, d as getTerminalWidth, f as isTTY, h as writeLine, i as CURSOR_HIDE, l as cursorDown, m as write, n as CLEAR_LINE_END, o as CURSOR_SAVE, p as withCursor, r as CLEAR_SCREEN, s as CURSOR_SHOW, t as CLEAR_LINE, u as cursorUp } from "./ansi-
|
|
3
|
-
import { t as ProgressBar } from "./progress-bar-
|
|
4
|
-
import { t as MultiProgress } from "./multi-progress-
|
|
5
|
-
import "./cli-
|
|
6
|
-
import { a as waitForEvent, c as wrapGenerator,
|
|
7
|
-
|
|
1
|
+
import { i as createSpinner, r as Spinner, t as SPINNER_FRAMES } from "./spinner-Py8_-hn9.mjs";
|
|
2
|
+
import { a as CURSOR_RESTORE, c as CURSOR_TO_START, d as getTerminalWidth, f as isTTY, h as writeLine, i as CURSOR_HIDE, l as cursorDown, m as write, n as CLEAR_LINE_END, o as CURSOR_SAVE, p as withCursor, r as CLEAR_SCREEN, s as CURSOR_SHOW, t as CLEAR_LINE, u as cursorUp } from "./ansi-C6Qs1Wn2.mjs";
|
|
3
|
+
import { t as ProgressBar } from "./progress-bar-DmIMPdL0.mjs";
|
|
4
|
+
import { t as MultiProgress } from "./multi-progress-CaXTuL9G.mjs";
|
|
5
|
+
import "./cli-DG6zsfsS.mjs";
|
|
6
|
+
import { a as waitForEvent, c as wrapGenerator, i as withSelect, l as attachSpinner, n as withTextInput, o as wrapEmitter, r as createSelect, s as withIterableProgress, t as createTextInput, u as withSpinner } from "./wrappers-CypAzrMO.mjs";
|
|
7
|
+
import { n as step, t as steps } from "./progress-B_UPy6zk.mjs";
|
|
8
|
+
export { CLEAR_LINE, CLEAR_LINE_END, CLEAR_SCREEN, CURSOR_HIDE, CURSOR_RESTORE, CURSOR_SAVE, CURSOR_SHOW, CURSOR_TO_START, MultiProgress, ProgressBar, SPINNER_FRAMES, Spinner, attachSpinner, createSelect, createSpinner, createTextInput, cursorDown, cursorUp, getTerminalWidth, isTTY, step, steps, waitForEvent, withCursor, withIterableProgress, withSelect, withSpinner, withTextInput, wrapEmitter, wrapGenerator, write, writeLine };
|
|
@@ -1,25 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Easing Functions
|
|
4
|
-
*
|
|
5
|
-
* Maps time progress (0-1) to value progress (0-1) for smooth animations.
|
|
6
|
-
* Includes common presets and a resolver for name-or-function usage.
|
|
7
|
-
*/
|
|
8
|
-
/** Easing function: maps time progress (0-1) to value progress (0-1) */
|
|
9
|
-
type EasingFn = (t: number) => number;
|
|
10
|
-
declare const easings: {
|
|
11
|
-
readonly linear: (t: number) => number;
|
|
12
|
-
readonly ease: (t: number) => number;
|
|
13
|
-
readonly easeIn: (t: number) => number;
|
|
14
|
-
readonly easeOut: (t: number) => number;
|
|
15
|
-
readonly easeInOut: (t: number) => number;
|
|
16
|
-
readonly easeInCubic: (t: number) => number;
|
|
17
|
-
readonly easeOutCubic: (t: number) => number;
|
|
18
|
-
};
|
|
19
|
-
type EasingName = keyof typeof easings;
|
|
20
|
-
/** Resolve an easing — accepts a name string or a custom function. */
|
|
21
|
-
declare function resolveEasing(easing: EasingName | EasingFn): EasingFn;
|
|
22
|
-
//#endregion
|
|
1
|
+
import { n as EasingName, t as EasingFn } from "./easing-B0oZKDki.mjs";
|
|
2
|
+
|
|
23
3
|
//#region packages/ag-react/src/ui/animation/useAnimation.d.ts
|
|
24
4
|
interface UseAnimationOptions {
|
|
25
5
|
/** Duration in milliseconds */
|
|
@@ -48,7 +28,7 @@ interface UseAnimationResult {
|
|
|
48
28
|
* ```tsx
|
|
49
29
|
* function FadeIn({ children }) {
|
|
50
30
|
* const { value } = useAnimation({ duration: 300, easing: "easeOut" })
|
|
51
|
-
* return <Text
|
|
31
|
+
* return <Text color={value < 1 ? "$muted" : undefined}>{children}</Text>
|
|
52
32
|
* }
|
|
53
33
|
* ```
|
|
54
34
|
*/
|
|
@@ -150,5 +130,5 @@ declare function useLatest<T>(value: T): {
|
|
|
150
130
|
readonly current: T;
|
|
151
131
|
};
|
|
152
132
|
//#endregion
|
|
153
|
-
export { useTransition as a, useAnimation as c,
|
|
154
|
-
//# sourceMappingURL=useLatest-
|
|
133
|
+
export { useTransition as a, useAnimation as c, UseTransitionOptions as i, useTimeout as n, UseAnimationOptions as o, useInterval as r, UseAnimationResult as s, useLatest as t };
|
|
134
|
+
//# sourceMappingURL=useLatest-DC8i7guK.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLatest-DC8i7guK.d.mts","names":[],"sources":["../packages/ag-react/src/ui/animation/useAnimation.ts","../packages/ag-react/src/ui/animation/useTransition.ts","../packages/ag-react/src/ui/animation/useInterval.ts","../packages/ag-react/src/ui/animation/useTimeout.ts","../packages/ag-react/src/ui/animation/useLatest.ts"],"mappings":";;;UAeiB,mBAAA;EAIN;EAFT,QAAA;EAIA;EAFA,MAAA,GAAS,UAAA,GAAa,QAAA;EAMtB;EAJA,KAAA;EAIO;EAFP,UAAA;EAKiC;EAHjC,OAAA;AAAA;AAAA,UAGe,kBAAA;EAIf;EAFA,KAAA;EAIK;EAFL,WAAA;EA2Bc;EAzBd,KAAA;AAAA;;;;;;;;;;ACnBF;;iBD4CgB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,kBAAA;;;UC5C3C,oBAAA;EDIN;ECFT,QAAA;EDIA;ECFA,MAAA,GAAS,UAAA,GAAa,QAAA;AAAA;;;ADSxB;;;;;;;;;AA+BA;;;;iBCXgB,aAAA,CAAc,WAAA,UAAqB,OAAA,GAAU,oBAAA;;;;;;ADjC7D;;;;;;;;;;;;;iBEQgB,WAAA,CAAY,QAAA,cAAsB,EAAA,UAAY,OAAA;;;;;;AFR9D;;;;;;;;;;;;;AAaA;;;iBGFgB,UAAA,CACd,QAAA,cACA,EAAA,UACA,OAAA;EACG,KAAA;EAAmB,KAAA;AAAA;;;;;;AHfxB;;;;;;;;;;;;;AAaA;;;;;;;iBIEgB,SAAA,GAAA,CAAa,KAAA,EAAO,CAAA;EAAA,SAAe,OAAA,EAAS,CAAA;AAAA"}
|