@gridland/demo 0.2.50 → 0.2.52
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/chunk-4VNS5WPM.js +42 -0
- package/dist/chunk-DTDQ3HF4.js +494 -0
- package/dist/demo-names.json +1 -1
- package/dist/landing.js +164 -286
- package/dist/run.js +1583 -1176
- package/dist/token-M3ULGZTY.js +62 -0
- package/dist/token-util-FKUIR5UM.js +5 -0
- package/package.json +4 -4
package/dist/landing.js
CHANGED
|
@@ -52,33 +52,6 @@ function textStyle(opts) {
|
|
|
52
52
|
|
|
53
53
|
// ../ui/components/status-bar/status-bar.tsx
|
|
54
54
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
55
|
-
function StatusBar({ items, extra }) {
|
|
56
|
-
const theme = useTheme();
|
|
57
|
-
const parts = [];
|
|
58
|
-
if (extra !== void 0) {
|
|
59
|
-
parts.push(
|
|
60
|
-
/* @__PURE__ */ jsx3("span", { children: extra }, "extra")
|
|
61
|
-
);
|
|
62
|
-
parts.push(
|
|
63
|
-
/* @__PURE__ */ jsx3("span", { style: textStyle({ dim: true, fg: theme.placeholder }), children: " \u2502 " }, "pipe")
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
items.forEach((item, i) => {
|
|
67
|
-
if (i > 0) {
|
|
68
|
-
parts.push(/* @__PURE__ */ jsx3("span", { children: " " }, `gap-${i}`));
|
|
69
|
-
}
|
|
70
|
-
parts.push(
|
|
71
|
-
/* @__PURE__ */ jsx3("span", { style: textStyle({ bold: true, fg: theme.background, bg: theme.muted }), children: ` ${item.key} ` }, `key-${i}`)
|
|
72
|
-
);
|
|
73
|
-
parts.push(
|
|
74
|
-
/* @__PURE__ */ jsx3("span", { style: textStyle({ dim: true, fg: theme.placeholder }), children: ` ${item.label}` }, `label-${i}`)
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
if (parts.length === 0) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return /* @__PURE__ */ jsx3("text", { children: parts });
|
|
81
|
-
}
|
|
82
55
|
|
|
83
56
|
// ../ui/components/provider/provider.tsx
|
|
84
57
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
@@ -99,7 +72,7 @@ import { jsx as jsx6 } from "react/jsx-runtime";
|
|
|
99
72
|
import { useEffect, useState as useState2 } from "react";
|
|
100
73
|
import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
101
74
|
var VARIANTS = {
|
|
102
|
-
dots: { frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"], interval:
|
|
75
|
+
dots: { frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"], interval: 80 },
|
|
103
76
|
pulse: { frames: ["\xB7", "\u2219", "\u25CF", "\u2219", "\xB7", "\xB7", "\xB7"], interval: 180 },
|
|
104
77
|
meter: { frames: ["\u25B1\u25B1\u25B1", "\u25B0\u25B1\u25B1", "\u25B0\u25B0\u25B1", "\u25B0\u25B0\u25B0", "\u25B0\u25B0\u25B1", "\u25B0\u25B1\u25B1", "\u25B1\u25B1\u25B1"], interval: 143 },
|
|
105
78
|
bloom: { frames: ["\xB7", "\u2726", "\u2727", "\u2739", "\u273A", "\u274B", "\u2738", "\u2735", "\u2738", "\u274B", "\u273A", "\u2739", "\u2727", "\u2726", "\xB7", "\xB7"], interval: 100 },
|
|
@@ -124,8 +97,9 @@ import { useReducer as useReducer2, useMemo as useMemo2, useRef as useRef3 } fro
|
|
|
124
97
|
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
125
98
|
|
|
126
99
|
// ../ui/components/table/table.tsx
|
|
127
|
-
import { Fragment } from "react";
|
|
100
|
+
import { createContext as createContext3, useContext as useContext3, Children, isValidElement, Fragment } from "react";
|
|
128
101
|
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
102
|
+
var TableContext = createContext3(null);
|
|
129
103
|
|
|
130
104
|
// ../ui/components/gradient/gradient.tsx
|
|
131
105
|
import { Fragment as Fragment2, jsx as jsx13 } from "react/jsx-runtime";
|
|
@@ -194,59 +168,29 @@ function Gradient({ children, name, colors }) {
|
|
|
194
168
|
}
|
|
195
169
|
|
|
196
170
|
// ../ui/components/tab-bar/tab-bar.tsx
|
|
197
|
-
import { createContext as
|
|
171
|
+
import { createContext as createContext4, useContext as useContext4, useState as useState5, Children as Children2, isValidElement as isValidElement2 } from "react";
|
|
198
172
|
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
199
|
-
var TabsContext =
|
|
173
|
+
var TabsContext = createContext4(null);
|
|
200
174
|
|
|
201
175
|
// ../ui/components/modal/modal.tsx
|
|
202
176
|
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
203
|
-
function Modal({
|
|
204
|
-
children,
|
|
205
|
-
title,
|
|
206
|
-
borderColor,
|
|
207
|
-
borderStyle = "rounded",
|
|
208
|
-
onClose,
|
|
209
|
-
useKeyboard: useKeyboardProp
|
|
210
|
-
}) {
|
|
211
|
-
const theme = useTheme();
|
|
212
|
-
const useKeyboard = useKeyboardContext(useKeyboardProp);
|
|
213
|
-
const resolvedBorderColor = borderColor ?? theme.muted;
|
|
214
|
-
useKeyboard?.((event) => {
|
|
215
|
-
if (event.name === "escape" && onClose) {
|
|
216
|
-
onClose();
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
return /* @__PURE__ */ jsx15("box", { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx15(
|
|
220
|
-
"box",
|
|
221
|
-
{
|
|
222
|
-
flexDirection: "column",
|
|
223
|
-
flexGrow: 1,
|
|
224
|
-
border: true,
|
|
225
|
-
borderStyle,
|
|
226
|
-
borderColor: resolvedBorderColor,
|
|
227
|
-
children: title ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
228
|
-
/* @__PURE__ */ jsx15("box", { paddingX: 1, marginBottom: 1, children: /* @__PURE__ */ jsx15("text", { style: textStyle({ bold: true, fg: theme.primary }), children: title }) }),
|
|
229
|
-
children
|
|
230
|
-
] }) : children
|
|
231
|
-
}
|
|
232
|
-
) });
|
|
233
|
-
}
|
|
234
177
|
|
|
235
178
|
// ../ui/components/prompt-input/prompt-input.tsx
|
|
236
179
|
import {
|
|
237
180
|
useState as useState6,
|
|
238
181
|
useRef as useRef4,
|
|
239
182
|
useCallback as useCallback2,
|
|
183
|
+
useEffect as useEffect2,
|
|
240
184
|
useMemo as useMemo3,
|
|
241
|
-
createContext as
|
|
242
|
-
useContext as
|
|
185
|
+
createContext as createContext5,
|
|
186
|
+
useContext as useContext5
|
|
243
187
|
} from "react";
|
|
244
188
|
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
245
|
-
var PromptInputControllerCtx =
|
|
246
|
-
var useOptionalController = () =>
|
|
247
|
-
var PromptInputContext =
|
|
189
|
+
var PromptInputControllerCtx = createContext5(null);
|
|
190
|
+
var useOptionalController = () => useContext5(PromptInputControllerCtx);
|
|
191
|
+
var PromptInputContext = createContext5(null);
|
|
248
192
|
function usePromptInput() {
|
|
249
|
-
const ctx =
|
|
193
|
+
const ctx = useContext5(PromptInputContext);
|
|
250
194
|
if (!ctx) {
|
|
251
195
|
throw new Error("usePromptInput must be used within a <PromptInput> component");
|
|
252
196
|
}
|
|
@@ -268,9 +212,10 @@ function resolveStatusHintText(status, submittedText, streamingText, errorText,
|
|
|
268
212
|
if (status === "error") return errorText;
|
|
269
213
|
return disabledText;
|
|
270
214
|
}
|
|
215
|
+
var DIVIDER_LINE = "\u2500".repeat(500);
|
|
271
216
|
function PromptInputDivider() {
|
|
272
217
|
const { theme } = usePromptInput();
|
|
273
|
-
return /* @__PURE__ */ jsx16("text", { wrapMode: "none", children: /* @__PURE__ */ jsx16("span", { style: textStyle({ dim: true, fg: theme.muted }), children:
|
|
218
|
+
return /* @__PURE__ */ jsx16("text", { wrapMode: "none", marginLeft: -1, marginRight: -1, children: /* @__PURE__ */ jsx16("span", { style: textStyle({ dim: true, fg: theme.muted }), children: DIVIDER_LINE }) });
|
|
274
219
|
}
|
|
275
220
|
function PromptInputSuggestions() {
|
|
276
221
|
const { suggestions, sugIdx, maxSuggestions, theme } = usePromptInput();
|
|
@@ -344,11 +289,20 @@ function PromptInput({
|
|
|
344
289
|
enableHistory = true,
|
|
345
290
|
model,
|
|
346
291
|
showDividers = true,
|
|
292
|
+
autoFocus = false,
|
|
347
293
|
useKeyboard: useKeyboardProp,
|
|
348
294
|
children
|
|
349
295
|
}) {
|
|
350
296
|
const theme = useTheme();
|
|
351
297
|
const useKeyboard = useKeyboardContext(useKeyboardProp);
|
|
298
|
+
useEffect2(() => {
|
|
299
|
+
if (!autoFocus) return;
|
|
300
|
+
if (typeof document === "undefined") return;
|
|
301
|
+
const canvas = document.querySelector("canvas");
|
|
302
|
+
if (canvas && document.activeElement !== canvas) {
|
|
303
|
+
canvas.focus();
|
|
304
|
+
}
|
|
305
|
+
}, [autoFocus]);
|
|
352
306
|
const resolvedPromptColor = promptColor ?? theme.muted;
|
|
353
307
|
const disabled = status ? status === "submitted" || status === "streaming" : disabledProp;
|
|
354
308
|
const statusHintText = resolveStatusHintText(status, submittedText, streamingLabel, errorText, disabledText);
|
|
@@ -542,14 +496,16 @@ function PromptInput({
|
|
|
542
496
|
theme
|
|
543
497
|
};
|
|
544
498
|
if (children) {
|
|
545
|
-
return /* @__PURE__ */ jsx16(PromptInputContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsx16("box", { flexDirection: "column", children }) });
|
|
499
|
+
return /* @__PURE__ */ jsx16(PromptInputContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsx16("box", { flexDirection: "column", flexShrink: 0, children }) });
|
|
546
500
|
}
|
|
547
|
-
return /* @__PURE__ */ jsx16(PromptInputContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxs10("box", { flexDirection: "column", children: [
|
|
501
|
+
return /* @__PURE__ */ jsx16(PromptInputContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxs10("box", { flexDirection: "column", flexShrink: 0, children: [
|
|
548
502
|
showDividers && /* @__PURE__ */ jsx16(PromptInputDivider, {}),
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
503
|
+
/* @__PURE__ */ jsxs10("box", { flexDirection: "column", paddingX: 1, children: [
|
|
504
|
+
/* @__PURE__ */ jsx16(PromptInputSuggestions, {}),
|
|
505
|
+
/* @__PURE__ */ jsx16(PromptInputTextarea, {}),
|
|
506
|
+
/* @__PURE__ */ jsx16(PromptInputStatusText, {}),
|
|
507
|
+
/* @__PURE__ */ jsx16(PromptInputModel, {})
|
|
508
|
+
] }),
|
|
553
509
|
showDividers && /* @__PURE__ */ jsx16(PromptInputDivider, {})
|
|
554
510
|
] }) });
|
|
555
511
|
}
|
|
@@ -564,13 +520,13 @@ PromptInput.Model = PromptInputModel;
|
|
|
564
520
|
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
565
521
|
|
|
566
522
|
// ../ui/components/chain-of-thought/chain-of-thought.tsx
|
|
567
|
-
import { createContext as
|
|
523
|
+
import { createContext as createContext6, memo, useContext as useContext6, useEffect as useEffect3, useMemo as useMemo4, useState as useState7 } from "react";
|
|
568
524
|
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
569
525
|
var DOTS = ["\u25CB", "\u25D4", "\u25D1", "\u25D5", "\u25CF"];
|
|
570
526
|
var SPINNER_INTERVAL = 150;
|
|
571
|
-
var ChainOfThoughtContext =
|
|
527
|
+
var ChainOfThoughtContext = createContext6(null);
|
|
572
528
|
var useChainOfThought = () => {
|
|
573
|
-
const context =
|
|
529
|
+
const context = useContext6(ChainOfThoughtContext);
|
|
574
530
|
if (!context) {
|
|
575
531
|
throw new Error("ChainOfThought components must be used within <ChainOfThought>");
|
|
576
532
|
}
|
|
@@ -639,7 +595,7 @@ var ChainOfThoughtStep = memo(({
|
|
|
639
595
|
const color = getStepColor(status, theme);
|
|
640
596
|
const pipe = "\u2502";
|
|
641
597
|
const [frame, setFrame] = useState7(0);
|
|
642
|
-
|
|
598
|
+
useEffect3(() => {
|
|
643
599
|
if (!isActive) {
|
|
644
600
|
setFrame(0);
|
|
645
601
|
return;
|
|
@@ -668,11 +624,11 @@ ChainOfThoughtContent.displayName = "ChainOfThoughtContent";
|
|
|
668
624
|
ChainOfThoughtStep.displayName = "ChainOfThoughtStep";
|
|
669
625
|
|
|
670
626
|
// ../ui/components/message/message.tsx
|
|
671
|
-
import { createContext as
|
|
627
|
+
import { createContext as createContext7, useContext as useContext7 } from "react";
|
|
672
628
|
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
673
|
-
var MessageContext =
|
|
629
|
+
var MessageContext = createContext7(null);
|
|
674
630
|
function useMessage() {
|
|
675
|
-
const ctx =
|
|
631
|
+
const ctx = useContext7(MessageContext);
|
|
676
632
|
if (!ctx) throw new Error("useMessage must be used within <Message>");
|
|
677
633
|
return ctx;
|
|
678
634
|
}
|
|
@@ -681,23 +637,25 @@ function getBubbleColors(theme) {
|
|
|
681
637
|
return isDark ? { assistantBg: "#2a2a4a", userBg: "#2a3a3a" } : { assistantBg: "#F1F5F9", userBg: "#E2E8F0" };
|
|
682
638
|
}
|
|
683
639
|
var TOOL_STATE_ICONS = {
|
|
684
|
-
|
|
640
|
+
pending: "\u2022",
|
|
685
641
|
// •
|
|
686
|
-
|
|
642
|
+
running: "\u280B",
|
|
687
643
|
// ⠋
|
|
688
|
-
|
|
644
|
+
completed: "\u2713",
|
|
689
645
|
// ✓
|
|
646
|
+
error: "\u2715"
|
|
647
|
+
// ✕
|
|
690
648
|
};
|
|
691
649
|
function getToolStateColor(state, theme) {
|
|
692
650
|
switch (state) {
|
|
693
|
-
case "
|
|
651
|
+
case "pending":
|
|
694
652
|
return theme.muted;
|
|
695
|
-
case "
|
|
653
|
+
case "running":
|
|
696
654
|
return theme.warning;
|
|
697
|
-
case "
|
|
655
|
+
case "completed":
|
|
698
656
|
return theme.success;
|
|
699
|
-
|
|
700
|
-
return theme.
|
|
657
|
+
case "error":
|
|
658
|
+
return theme.error;
|
|
701
659
|
}
|
|
702
660
|
}
|
|
703
661
|
function MessageContent({ children }) {
|
|
@@ -722,51 +680,57 @@ function MessageText({ children, isLast = false }) {
|
|
|
722
680
|
isLast && isStreaming && /* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: streamingCursor })
|
|
723
681
|
] });
|
|
724
682
|
}
|
|
725
|
-
function MessageReasoning({
|
|
726
|
-
return /* @__PURE__ */ jsxs13(ChainOfThought, { defaultOpen:
|
|
727
|
-
/* @__PURE__ */ jsx19(ChainOfThoughtHeader, { duration
|
|
728
|
-
/* @__PURE__ */
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
683
|
+
function MessageReasoning({ duration, steps, collapsed = true, children }) {
|
|
684
|
+
return /* @__PURE__ */ jsxs13(ChainOfThought, { defaultOpen: !collapsed, children: [
|
|
685
|
+
/* @__PURE__ */ jsx19(ChainOfThoughtHeader, { duration }),
|
|
686
|
+
/* @__PURE__ */ jsxs13(ChainOfThoughtContent, { children: [
|
|
687
|
+
steps?.map((step, i) => /* @__PURE__ */ jsx19(
|
|
688
|
+
ChainOfThoughtStep,
|
|
689
|
+
{
|
|
690
|
+
label: step.label,
|
|
691
|
+
description: step.description,
|
|
692
|
+
status: step.status,
|
|
693
|
+
isLast: i === (steps?.length ?? 0) - 1,
|
|
694
|
+
children: step.output
|
|
695
|
+
},
|
|
696
|
+
i
|
|
697
|
+
)),
|
|
698
|
+
children
|
|
699
|
+
] })
|
|
739
700
|
] });
|
|
740
701
|
}
|
|
741
|
-
function
|
|
702
|
+
function MessageToolCall({ name, state = "pending", result, color }) {
|
|
742
703
|
const theme = useTheme();
|
|
743
704
|
const { backgroundColor, textColor } = useMessage();
|
|
744
|
-
const
|
|
745
|
-
const
|
|
746
|
-
const
|
|
747
|
-
const isActive = state === "partial-call" || state === "call";
|
|
705
|
+
const icon = TOOL_STATE_ICONS[state];
|
|
706
|
+
const stateColor = color ?? getToolStateColor(state, theme);
|
|
707
|
+
const isActive = state === "pending" || state === "running";
|
|
748
708
|
return /* @__PURE__ */ jsxs13("box", { flexDirection: "column", children: [
|
|
749
709
|
/* @__PURE__ */ jsxs13("text", { children: [
|
|
750
710
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: stateColor, bg: backgroundColor }), children: icon }),
|
|
751
711
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, bg: backgroundColor }), children: " " }),
|
|
752
|
-
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: stateColor, bold: isActive, bg: backgroundColor }), children:
|
|
712
|
+
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: stateColor, bold: isActive, bg: backgroundColor }), children: name }),
|
|
753
713
|
isActive && /* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: " ..." })
|
|
754
714
|
] }),
|
|
755
|
-
state === "
|
|
715
|
+
state === "completed" && result !== void 0 && /* @__PURE__ */ jsxs13("text", { children: [
|
|
756
716
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: " \u2514\u2500 " }),
|
|
757
717
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: String(result).slice(0, 120) })
|
|
718
|
+
] }),
|
|
719
|
+
state === "error" && result !== void 0 && /* @__PURE__ */ jsxs13("text", { children: [
|
|
720
|
+
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: theme.error, dim: true, bg: backgroundColor }), children: " \u2514\u2500 " }),
|
|
721
|
+
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: theme.error, dim: true, bg: backgroundColor }), children: String(result).slice(0, 120) })
|
|
758
722
|
] })
|
|
759
723
|
] });
|
|
760
724
|
}
|
|
761
|
-
function MessageSource({
|
|
725
|
+
function MessageSource({ title, url, index }) {
|
|
762
726
|
const theme = useTheme();
|
|
763
727
|
const { backgroundColor, textColor } = useMessage();
|
|
764
|
-
const
|
|
728
|
+
const displayTitle = title || url || "source";
|
|
765
729
|
return /* @__PURE__ */ jsxs13("text", { children: [
|
|
766
730
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: "[" }),
|
|
767
731
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: theme.accent, bg: backgroundColor }), children: String(index + 1) }),
|
|
768
732
|
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: textColor, dim: true, bg: backgroundColor }), children: "] " }),
|
|
769
|
-
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: theme.accent, bg: backgroundColor }), children:
|
|
733
|
+
/* @__PURE__ */ jsx19("span", { style: textStyle({ fg: theme.accent, bg: backgroundColor }), children: displayTitle })
|
|
770
734
|
] });
|
|
771
735
|
}
|
|
772
736
|
function MessageFooter({ model, timestamp }) {
|
|
@@ -802,7 +766,7 @@ function Message({
|
|
|
802
766
|
Message.Content = MessageContent;
|
|
803
767
|
Message.Text = MessageText;
|
|
804
768
|
Message.Reasoning = MessageReasoning;
|
|
805
|
-
Message.
|
|
769
|
+
Message.ToolCall = MessageToolCall;
|
|
806
770
|
Message.Source = MessageSource;
|
|
807
771
|
Message.Footer = MessageFooter;
|
|
808
772
|
|
|
@@ -828,64 +792,14 @@ function useBreakpoints() {
|
|
|
828
792
|
};
|
|
829
793
|
}
|
|
830
794
|
|
|
831
|
-
//
|
|
832
|
-
import {
|
|
795
|
+
// src/landing/landing-app.tsx
|
|
796
|
+
import { useMemo as useMemo7 } from "react";
|
|
833
797
|
|
|
834
|
-
//
|
|
798
|
+
// src/landing/install-box.tsx
|
|
835
799
|
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
836
|
-
function AboutModal({ onClose, useKeyboard }) {
|
|
837
|
-
const theme = useTheme();
|
|
838
|
-
return /* @__PURE__ */ jsx21(Modal, { title: "About Gridland", useKeyboard, onClose, children: /* @__PURE__ */ jsxs15("box", { paddingX: 1, flexDirection: "column", gap: 1, children: [
|
|
839
|
-
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "What is Gridland?" }),
|
|
840
|
-
/* @__PURE__ */ jsx21("text", { children: "Gridland renders terminal UIs to HTML5 Canvas with React." }),
|
|
841
|
-
/* @__PURE__ */ jsx21("text", { children: "No xterm.js. No terminal emulator. Just pixels." }),
|
|
842
|
-
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Features" }),
|
|
843
|
-
/* @__PURE__ */ jsxs15("text", { children: [
|
|
844
|
-
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
845
|
-
"\u2022",
|
|
846
|
-
" "
|
|
847
|
-
] }),
|
|
848
|
-
"Canvas-rendered TUI components"
|
|
849
|
-
] }),
|
|
850
|
-
/* @__PURE__ */ jsxs15("text", { children: [
|
|
851
|
-
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
852
|
-
"\u2022",
|
|
853
|
-
" "
|
|
854
|
-
] }),
|
|
855
|
-
"React reconciler with JSX"
|
|
856
|
-
] }),
|
|
857
|
-
/* @__PURE__ */ jsxs15("text", { children: [
|
|
858
|
-
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
859
|
-
"\u2022",
|
|
860
|
-
" "
|
|
861
|
-
] }),
|
|
862
|
-
"Yoga flexbox layout engine"
|
|
863
|
-
] }),
|
|
864
|
-
/* @__PURE__ */ jsxs15("text", { children: [
|
|
865
|
-
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
866
|
-
"\u2022",
|
|
867
|
-
" "
|
|
868
|
-
] }),
|
|
869
|
-
"Keyboard, mouse, and clipboard support"
|
|
870
|
-
] }),
|
|
871
|
-
/* @__PURE__ */ jsxs15("text", { children: [
|
|
872
|
-
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
873
|
-
"\u2022",
|
|
874
|
-
" "
|
|
875
|
-
] }),
|
|
876
|
-
"Next.js and Vite plugins"
|
|
877
|
-
] }),
|
|
878
|
-
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Tech Stack" }),
|
|
879
|
-
/* @__PURE__ */ jsx21("text", { children: "React + opentui engine + yoga-layout + HTML5 Canvas" }),
|
|
880
|
-
/* @__PURE__ */ jsx21("text", { style: textStyle({ dim: true }), children: "Press q to close" })
|
|
881
|
-
] }) });
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
// ../docs/components/landing/install-box.tsx
|
|
885
|
-
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
886
800
|
function InstallBox() {
|
|
887
801
|
const theme = useTheme();
|
|
888
|
-
return /* @__PURE__ */
|
|
802
|
+
return /* @__PURE__ */ jsx21(
|
|
889
803
|
"box",
|
|
890
804
|
{
|
|
891
805
|
border: true,
|
|
@@ -894,21 +808,21 @@ function InstallBox() {
|
|
|
894
808
|
paddingX: 1,
|
|
895
809
|
flexDirection: "column",
|
|
896
810
|
flexShrink: 0,
|
|
897
|
-
children: /* @__PURE__ */
|
|
898
|
-
/* @__PURE__ */
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
811
|
+
children: /* @__PURE__ */ jsxs15("text", { children: [
|
|
812
|
+
/* @__PURE__ */ jsx21("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
813
|
+
/* @__PURE__ */ jsx21("span", { style: textStyle({ bold: true }), children: "bun create " }),
|
|
814
|
+
/* @__PURE__ */ jsx21("span", { style: textStyle({ fg: theme.accent }), children: "gridland" })
|
|
901
815
|
] })
|
|
902
816
|
}
|
|
903
817
|
);
|
|
904
818
|
}
|
|
905
819
|
|
|
906
|
-
//
|
|
907
|
-
import { jsx as
|
|
820
|
+
// src/landing/links-box.tsx
|
|
821
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
908
822
|
var UNDERLINE3 = 1 << 3;
|
|
909
823
|
function LinksBox() {
|
|
910
824
|
const theme = useTheme();
|
|
911
|
-
return /* @__PURE__ */
|
|
825
|
+
return /* @__PURE__ */ jsx22(
|
|
912
826
|
"box",
|
|
913
827
|
{
|
|
914
828
|
border: true,
|
|
@@ -917,22 +831,22 @@ function LinksBox() {
|
|
|
917
831
|
paddingX: 1,
|
|
918
832
|
flexDirection: "column",
|
|
919
833
|
flexShrink: 0,
|
|
920
|
-
children: /* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
/* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
834
|
+
children: /* @__PURE__ */ jsxs16("text", { children: [
|
|
835
|
+
/* @__PURE__ */ jsx22("span", { children: "\u{1F431}" }),
|
|
836
|
+
/* @__PURE__ */ jsx22("a", { href: "https://github.com/thoughtfulllc/gridland", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " GitHub" }),
|
|
837
|
+
/* @__PURE__ */ jsx22("span", { children: " " }),
|
|
838
|
+
/* @__PURE__ */ jsx22("span", { children: "\u{1F4D6}" }),
|
|
839
|
+
/* @__PURE__ */ jsx22("a", { href: "https://gridland.io/docs", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " Docs" })
|
|
926
840
|
] })
|
|
927
841
|
}
|
|
928
842
|
);
|
|
929
843
|
}
|
|
930
844
|
|
|
931
|
-
//
|
|
932
|
-
import { useState as useState8, useEffect as
|
|
845
|
+
// src/landing/logo.tsx
|
|
846
|
+
import { useState as useState8, useEffect as useEffect4, useRef as useRef5, useMemo as useMemo5 } from "react";
|
|
933
847
|
import figlet from "figlet";
|
|
934
848
|
import ansiShadow from "figlet/importable-fonts/ANSI Shadow.js";
|
|
935
|
-
import { Fragment as Fragment7, jsx as
|
|
849
|
+
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
936
850
|
figlet.parseFont("ANSI Shadow", ansiShadow);
|
|
937
851
|
function makeArt(text) {
|
|
938
852
|
return figlet.textSync(text, { font: "ANSI Shadow" }).split("\n").filter((l) => l.trimEnd().length > 0).join("\n");
|
|
@@ -945,7 +859,7 @@ function useAnimation(duration = 1e3) {
|
|
|
945
859
|
const isBrowser = typeof document !== "undefined";
|
|
946
860
|
const [progress, setProgress] = useState8(isBrowser ? 0 : 1);
|
|
947
861
|
const startTime = useRef5(null);
|
|
948
|
-
|
|
862
|
+
useEffect4(() => {
|
|
949
863
|
if (!isBrowser) return;
|
|
950
864
|
let raf;
|
|
951
865
|
const tick = (time) => {
|
|
@@ -965,9 +879,9 @@ function RevealGradient({ children, revealCol }) {
|
|
|
965
879
|
const gradientColors = GRADIENTS.instagram;
|
|
966
880
|
const lines = children.split("\n");
|
|
967
881
|
const maxLength = Math.max(...lines.map((l) => l.length));
|
|
968
|
-
if (maxLength === 0) return /* @__PURE__ */
|
|
882
|
+
if (maxLength === 0) return /* @__PURE__ */ jsx23("text", { children });
|
|
969
883
|
const hexColors = useMemo5(() => generateGradient(gradientColors, maxLength), [maxLength]);
|
|
970
|
-
return /* @__PURE__ */
|
|
884
|
+
return /* @__PURE__ */ jsx23("box", { position: "relative", width: maxLength, height: lines.length, shouldFill: false, children: lines.map((line, lineIndex) => {
|
|
971
885
|
const runs = [];
|
|
972
886
|
let current = null;
|
|
973
887
|
for (let i = 0; i < line.length; i++) {
|
|
@@ -987,14 +901,14 @@ function RevealGradient({ children, revealCol }) {
|
|
|
987
901
|
}
|
|
988
902
|
}
|
|
989
903
|
if (current) runs.push(current);
|
|
990
|
-
return runs.map((run, runIndex) => /* @__PURE__ */
|
|
904
|
+
return runs.map((run, runIndex) => /* @__PURE__ */ jsx23(
|
|
991
905
|
"box",
|
|
992
906
|
{
|
|
993
907
|
position: "absolute",
|
|
994
908
|
top: lineIndex,
|
|
995
909
|
left: run.start,
|
|
996
910
|
shouldFill: false,
|
|
997
|
-
children: /* @__PURE__ */
|
|
911
|
+
children: /* @__PURE__ */ jsx23("text", { shouldFill: false, children: run.chars.map((char, ci) => /* @__PURE__ */ jsx23(
|
|
998
912
|
"span",
|
|
999
913
|
{
|
|
1000
914
|
style: { fg: hexColors[run.start + ci] },
|
|
@@ -1016,20 +930,20 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
1016
930
|
const maxWidth = compact ? 8 : narrow ? 40 : 62;
|
|
1017
931
|
const revealCol = Math.round(revealProgress * (maxWidth + 4)) - 2;
|
|
1018
932
|
const taglineOpacity = Math.max(0, Math.min(1, (progress - 0.7) / 0.3));
|
|
1019
|
-
const subtitle = /* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1021
|
-
/* @__PURE__ */
|
|
933
|
+
const subtitle = /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
934
|
+
/* @__PURE__ */ jsx23("text", { children: " " }),
|
|
935
|
+
/* @__PURE__ */ jsx23("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs17("text", { style: textStyle({ fg: "#d4b0e8" }), opacity: taglineOpacity, wrapMode: "word", textAlign: "center", width: "100%", shouldFill: false, children: [
|
|
1022
936
|
"A framework for building terminal apps, built on ",
|
|
1023
|
-
/* @__PURE__ */
|
|
937
|
+
/* @__PURE__ */ jsx23("a", { href: "https://opentui.com", style: { attributes: 72, fg: "#d4b0e8" }, children: "OpenTUI" }),
|
|
1024
938
|
" + React." + (mobile ? " " : "\n") + "(Gridland apps, like this website, work in the browser and terminal.)"
|
|
1025
939
|
] }) })
|
|
1026
940
|
] });
|
|
1027
941
|
if (!isBrowser) {
|
|
1028
942
|
const art = compact ? "gridland" : narrow ? gridArt + "\n" + landArt : fullArt;
|
|
1029
|
-
return /* @__PURE__ */
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
943
|
+
return /* @__PURE__ */ jsxs17("box", { flexDirection: "column", flexShrink: 0, width: "100%", alignItems: "center", shouldFill: false, children: [
|
|
944
|
+
/* @__PURE__ */ jsx23(Gradient, { name: "instagram", children: art }),
|
|
945
|
+
/* @__PURE__ */ jsx23("text", { children: " " }),
|
|
946
|
+
/* @__PURE__ */ jsx23("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs17("text", { style: textStyle({ fg: "#d4b0e8" }), shouldFill: false, children: [
|
|
1033
947
|
"A framework for building terminal apps, built on OpenTUI + React.",
|
|
1034
948
|
"\n",
|
|
1035
949
|
"(Gridland apps, like this website, work in the browser and terminal.)"
|
|
@@ -1037,31 +951,31 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
1037
951
|
] });
|
|
1038
952
|
}
|
|
1039
953
|
if (compact) {
|
|
1040
|
-
return /* @__PURE__ */
|
|
1041
|
-
/* @__PURE__ */
|
|
954
|
+
return /* @__PURE__ */ jsxs17("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
955
|
+
/* @__PURE__ */ jsx23("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx23("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx23(RevealGradient, { revealCol, children: "gridland" }) }) }),
|
|
1042
956
|
subtitle
|
|
1043
957
|
] });
|
|
1044
958
|
}
|
|
1045
959
|
if (narrow) {
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
960
|
+
return /* @__PURE__ */ jsxs17("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
961
|
+
/* @__PURE__ */ jsx23("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsxs17("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: [
|
|
962
|
+
/* @__PURE__ */ jsx23(RevealGradient, { revealCol, children: gridArt }),
|
|
963
|
+
/* @__PURE__ */ jsx23(RevealGradient, { revealCol, children: landArt })
|
|
1050
964
|
] }) }),
|
|
1051
965
|
subtitle
|
|
1052
966
|
] });
|
|
1053
967
|
}
|
|
1054
|
-
return /* @__PURE__ */
|
|
1055
|
-
/* @__PURE__ */
|
|
968
|
+
return /* @__PURE__ */ jsxs17("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
969
|
+
/* @__PURE__ */ jsx23("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx23("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx23(RevealGradient, { revealCol, children: fullArt }) }) }),
|
|
1056
970
|
subtitle
|
|
1057
971
|
] });
|
|
1058
972
|
}
|
|
1059
973
|
|
|
1060
|
-
//
|
|
974
|
+
// src/landing/matrix-background.tsx
|
|
1061
975
|
import { useMemo as useMemo6 } from "react";
|
|
1062
976
|
|
|
1063
|
-
//
|
|
1064
|
-
import { useState as useState9, useEffect as
|
|
977
|
+
// src/landing/use-matrix.ts
|
|
978
|
+
import { useState as useState9, useEffect as useEffect5, useRef as useRef6 } from "react";
|
|
1065
979
|
var CHARS = "abcdefghijklmnopqrstuvwxyz0123456789@#$%^&*(){}[]|;:<>,.?/~`";
|
|
1066
980
|
function randomChar() {
|
|
1067
981
|
return CHARS[Math.floor(Math.random() * CHARS.length)];
|
|
@@ -1104,7 +1018,7 @@ function useMatrix(width, height) {
|
|
|
1104
1018
|
columnsRef.current = columns;
|
|
1105
1019
|
return buildGrid(columns, width, height);
|
|
1106
1020
|
});
|
|
1107
|
-
|
|
1021
|
+
useEffect5(() => {
|
|
1108
1022
|
if (width < 2 || height < 2) return;
|
|
1109
1023
|
const id = setInterval(() => {
|
|
1110
1024
|
const columns = columnsRef.current;
|
|
@@ -1129,7 +1043,7 @@ function useMatrix(width, height) {
|
|
|
1129
1043
|
}, 80);
|
|
1130
1044
|
return () => clearInterval(id);
|
|
1131
1045
|
}, [width, height]);
|
|
1132
|
-
|
|
1046
|
+
useEffect5(() => {
|
|
1133
1047
|
columnsRef.current = Array.from(
|
|
1134
1048
|
{ length: width },
|
|
1135
1049
|
() => Math.random() < 0.5 ? createDrop(height, true) : null
|
|
@@ -1139,8 +1053,8 @@ function useMatrix(width, height) {
|
|
|
1139
1053
|
return state;
|
|
1140
1054
|
}
|
|
1141
1055
|
|
|
1142
|
-
//
|
|
1143
|
-
import { jsx as
|
|
1056
|
+
// src/landing/matrix-background.tsx
|
|
1057
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1144
1058
|
var MUTE_LEVELS = [0.12, 0.18, 0.24, 0.3, 0.38];
|
|
1145
1059
|
var BG = hexToRgb("#1a1a2e");
|
|
1146
1060
|
function buildMutedColors(baseHex) {
|
|
@@ -1167,15 +1081,15 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1167
1081
|
() => columnColors.map(buildMutedColors),
|
|
1168
1082
|
[columnColors]
|
|
1169
1083
|
);
|
|
1170
|
-
return /* @__PURE__ */
|
|
1084
|
+
return /* @__PURE__ */ jsx24("box", { flexDirection: "column", children: grid.map((row, y) => /* @__PURE__ */ jsx24("text", { children: row.map((cell, x) => {
|
|
1171
1085
|
const inClearRect = clearRect && y >= clearRect.top && y < clearRect.top + clearRect.height && x >= clearRect.left && x < clearRect.left + clearRect.width || clearRects && clearRects.some(
|
|
1172
1086
|
(r) => y >= r.top && y < r.top + r.height && x >= r.left && x < r.left + r.width
|
|
1173
1087
|
);
|
|
1174
1088
|
const mutedColors = columnMutedColors[x];
|
|
1175
1089
|
if (cell === " " || inClearRect || !mutedColors) {
|
|
1176
|
-
return /* @__PURE__ */
|
|
1090
|
+
return /* @__PURE__ */ jsx24("span", { children: " " }, x);
|
|
1177
1091
|
}
|
|
1178
|
-
return /* @__PURE__ */
|
|
1092
|
+
return /* @__PURE__ */ jsx24(
|
|
1179
1093
|
"span",
|
|
1180
1094
|
{
|
|
1181
1095
|
style: {
|
|
@@ -1188,84 +1102,48 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1188
1102
|
}) }, y)) });
|
|
1189
1103
|
}
|
|
1190
1104
|
|
|
1191
|
-
//
|
|
1192
|
-
import { jsx as
|
|
1193
|
-
var DEMO_RESPONSES = [
|
|
1194
|
-
"Gridland is a framework for building terminal apps with React. It works in both the browser and terminal!",
|
|
1195
|
-
"You can get started with `bun create gridland` to scaffold a new project.",
|
|
1196
|
-
"OpenTUI provides the layout primitives \u2014 flexbox, borders, text styling \u2014 while React handles the component model.",
|
|
1197
|
-
"Yes! Gridland apps are universal \u2014 the same code renders in a terminal emulator and in the browser.",
|
|
1198
|
-
"Check out the docs for examples of interactive components like inputs, selects, and tables."
|
|
1199
|
-
];
|
|
1105
|
+
// src/landing/landing-app.tsx
|
|
1106
|
+
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1200
1107
|
function LandingApp({ useKeyboard }) {
|
|
1201
1108
|
const theme = useTheme();
|
|
1202
1109
|
const { width, height, isNarrow, isTiny, isMobile } = useBreakpoints();
|
|
1203
|
-
const [showAbout, setShowAbout] = useState10(false);
|
|
1204
|
-
const [messages, setMessages] = useState10([]);
|
|
1205
|
-
const [chatStatus, setChatStatus] = useState10("ready");
|
|
1206
|
-
const responseIdx = useRef7(0);
|
|
1207
|
-
const handleChatSubmit = useCallback3(({ text }) => {
|
|
1208
|
-
const userMsg = { id: `u-${Date.now()}`, role: "user", content: text };
|
|
1209
|
-
setMessages((prev) => [...prev, userMsg]);
|
|
1210
|
-
setChatStatus("streaming");
|
|
1211
|
-
setTimeout(() => {
|
|
1212
|
-
const response = DEMO_RESPONSES[responseIdx.current % DEMO_RESPONSES.length];
|
|
1213
|
-
responseIdx.current += 1;
|
|
1214
|
-
const assistantMsg = { id: `a-${Date.now()}`, role: "assistant", content: response };
|
|
1215
|
-
setMessages((prev) => [...prev, assistantMsg]);
|
|
1216
|
-
setChatStatus("ready");
|
|
1217
|
-
}, 1200);
|
|
1218
|
-
}, []);
|
|
1219
|
-
useKeyboard((event) => {
|
|
1220
|
-
if (event.name === "a" && !showAbout) {
|
|
1221
|
-
setShowAbout(true);
|
|
1222
|
-
}
|
|
1223
|
-
if (event.name === "q" && showAbout) {
|
|
1224
|
-
setShowAbout(false);
|
|
1225
|
-
}
|
|
1226
|
-
});
|
|
1227
|
-
if (showAbout) {
|
|
1228
|
-
return /* @__PURE__ */ jsxs19("box", { flexDirection: "column", width: "100%", height: "100%", children: [
|
|
1229
|
-
/* @__PURE__ */ jsx26("box", { flexGrow: 1, children: /* @__PURE__ */ jsx26(AboutModal, { onClose: () => setShowAbout(false), useKeyboard }) }),
|
|
1230
|
-
/* @__PURE__ */ jsx26(StatusBar, { items: [{ key: "q", label: "close" }] })
|
|
1231
|
-
] });
|
|
1232
|
-
}
|
|
1233
1110
|
const isBrowser = typeof document !== "undefined";
|
|
1234
|
-
const
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
/* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1256
|
-
] }),
|
|
1257
|
-
/* @__PURE__ */
|
|
1258
|
-
|
|
1259
|
-
/* @__PURE__ */ jsx26("box", { flexShrink: 0, paddingX: 1, paddingBottom: 0, children: /* @__PURE__ */ jsx26(PromptInput, { splaceholder: "Ask about Gridland...", status: chatStatus, onSubmit: handleChatSubmit, useKeyboard }) })
|
|
1260
|
-
] })
|
|
1111
|
+
const { clearRect, installLinksClearRect } = useMemo7(() => {
|
|
1112
|
+
const logoHeight = isTiny ? 2 : isNarrow ? 13 : 7;
|
|
1113
|
+
const logoExtra = isBrowser ? 1 : 0;
|
|
1114
|
+
const gap = isMobile ? 0 : 1;
|
|
1115
|
+
const installLinksTop = 3 + logoHeight + logoExtra + gap;
|
|
1116
|
+
const installLinksHeight = 3;
|
|
1117
|
+
const boxTop = installLinksTop + installLinksHeight + gap + 1;
|
|
1118
|
+
const bh = height - boxTop - 1;
|
|
1119
|
+
return {
|
|
1120
|
+
clearRect: { top: boxTop, left: 1, width: width - 2, height: bh },
|
|
1121
|
+
installLinksClearRect: { top: installLinksTop, left: 1, width: width - 2, height: installLinksHeight }
|
|
1122
|
+
};
|
|
1123
|
+
}, [width, height, isTiny, isNarrow, isMobile, isBrowser]);
|
|
1124
|
+
return /* @__PURE__ */ jsxs18("box", { width: "100%", height: "100%", position: "relative", children: [
|
|
1125
|
+
/* @__PURE__ */ jsx25(MatrixBackground, { width, height, clearRect, clearRects: isBrowser ? void 0 : [installLinksClearRect] }),
|
|
1126
|
+
/* @__PURE__ */ jsx25("box", { position: "absolute", top: 0, left: 0, width, height, zIndex: 1, flexDirection: "column", shouldFill: false, children: /* @__PURE__ */ jsxs18("box", { flexGrow: 1, flexDirection: "column", paddingTop: 3, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, gap: isMobile ? 0 : 1, shouldFill: false, children: [
|
|
1127
|
+
/* @__PURE__ */ jsx25("box", { flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx25(Logo, { compact: isTiny, narrow: isNarrow, mobile: isMobile }) }),
|
|
1128
|
+
/* @__PURE__ */ jsxs18("box", { flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: isMobile ? 0 : 1, flexShrink: 0, shouldFill: false, children: [
|
|
1129
|
+
/* @__PURE__ */ jsx25("box", { border: true, borderStyle: "rounded", borderColor: theme.border, paddingX: 1, flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsxs18("text", { children: [
|
|
1130
|
+
/* @__PURE__ */ jsx25("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
1131
|
+
/* @__PURE__ */ jsx25("span", { style: textStyle({ bold: true }), children: "bunx " }),
|
|
1132
|
+
/* @__PURE__ */ jsx25("span", { style: textStyle({ fg: theme.accent }), children: "@gridland/demo landing" })
|
|
1133
|
+
] }) }),
|
|
1134
|
+
/* @__PURE__ */ jsx25(InstallBox, {}),
|
|
1135
|
+
/* @__PURE__ */ jsx25(LinksBox, {})
|
|
1261
1136
|
] }),
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
] })
|
|
1137
|
+
/* @__PURE__ */ jsx25("box", { flexGrow: 1, border: true, borderStyle: "rounded", borderColor: theme.border, flexDirection: "column", overflow: "hidden" })
|
|
1138
|
+
] }) })
|
|
1264
1139
|
] });
|
|
1265
1140
|
}
|
|
1266
1141
|
|
|
1267
|
-
//
|
|
1268
|
-
import { jsx as
|
|
1142
|
+
// src/landing/matrix-rain.tsx
|
|
1143
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1144
|
+
|
|
1145
|
+
// src/landing/about-modal.tsx
|
|
1146
|
+
import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1269
1147
|
export {
|
|
1270
1148
|
LandingApp
|
|
1271
1149
|
};
|