@gridland/demo 0.2.20 → 0.2.22
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/landing.js +180 -182
- package/dist/run.js +183 -185
- package/package.json +2 -1
package/dist/landing.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// ../docs/components/landing/landing-app.tsx
|
|
2
|
-
import { useState as useState10 } from "react";
|
|
3
|
-
|
|
4
1
|
// ../ui/components/theme/themes.ts
|
|
5
2
|
var darkTheme = {
|
|
6
3
|
primary: "#FF71CE",
|
|
@@ -317,6 +314,14 @@ function PromptInputStatusText() {
|
|
|
317
314
|
if (status !== "error") return null;
|
|
318
315
|
return /* @__PURE__ */ jsx16("text", { children: /* @__PURE__ */ jsx16("span", { style: textStyle({ fg: theme.error }), children: errorText }) });
|
|
319
316
|
}
|
|
317
|
+
function PromptInputModel() {
|
|
318
|
+
const { model, theme } = usePromptInput();
|
|
319
|
+
if (!model) return null;
|
|
320
|
+
return /* @__PURE__ */ jsxs10("text", { dim: true, color: theme.muted, children: [
|
|
321
|
+
"model: ",
|
|
322
|
+
model
|
|
323
|
+
] });
|
|
324
|
+
}
|
|
320
325
|
function PromptInput({
|
|
321
326
|
value: controlledValue,
|
|
322
327
|
defaultValue = "",
|
|
@@ -337,7 +342,8 @@ function PromptInput({
|
|
|
337
342
|
getSuggestions: customGetSuggestions,
|
|
338
343
|
maxSuggestions = 5,
|
|
339
344
|
enableHistory = true,
|
|
340
|
-
|
|
345
|
+
model,
|
|
346
|
+
showDividers = true,
|
|
341
347
|
useKeyboard: useKeyboardProp,
|
|
342
348
|
children
|
|
343
349
|
}) {
|
|
@@ -532,6 +538,7 @@ function PromptInput({
|
|
|
532
538
|
sugIdx,
|
|
533
539
|
maxSuggestions,
|
|
534
540
|
errorText,
|
|
541
|
+
model,
|
|
535
542
|
theme
|
|
536
543
|
};
|
|
537
544
|
if (children) {
|
|
@@ -542,6 +549,7 @@ function PromptInput({
|
|
|
542
549
|
/* @__PURE__ */ jsx16(PromptInputSuggestions, {}),
|
|
543
550
|
/* @__PURE__ */ jsx16(PromptInputTextarea, {}),
|
|
544
551
|
/* @__PURE__ */ jsx16(PromptInputStatusText, {}),
|
|
552
|
+
/* @__PURE__ */ jsx16(PromptInputModel, {}),
|
|
545
553
|
showDividers && /* @__PURE__ */ jsx16(PromptInputDivider, {})
|
|
546
554
|
] }) });
|
|
547
555
|
}
|
|
@@ -550,6 +558,7 @@ PromptInput.Suggestions = PromptInputSuggestions;
|
|
|
550
558
|
PromptInput.Submit = PromptInputSubmit;
|
|
551
559
|
PromptInput.Divider = PromptInputDivider;
|
|
552
560
|
PromptInput.StatusText = PromptInputStatusText;
|
|
561
|
+
PromptInput.Model = PromptInputModel;
|
|
553
562
|
|
|
554
563
|
// ../ui/components/chat/chat.tsx
|
|
555
564
|
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
@@ -778,7 +787,7 @@ Message.Footer = MessageFooter;
|
|
|
778
787
|
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
779
788
|
|
|
780
789
|
// ../ui/components/breakpoints/use-breakpoints.ts
|
|
781
|
-
import { useTerminalDimensions } from "@gridland/
|
|
790
|
+
import { useTerminalDimensions } from "@gridland/core";
|
|
782
791
|
var BREAKPOINTS = {
|
|
783
792
|
tiny: 40,
|
|
784
793
|
narrow: 60,
|
|
@@ -796,11 +805,111 @@ function useBreakpoints() {
|
|
|
796
805
|
};
|
|
797
806
|
}
|
|
798
807
|
|
|
808
|
+
// ../docs/components/landing/landing-app.tsx
|
|
809
|
+
import { useCallback as useCallback3, useRef as useRef8, useState as useState10 } from "react";
|
|
810
|
+
|
|
811
|
+
// ../docs/components/landing/about-modal.tsx
|
|
812
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
813
|
+
function AboutModal({ onClose, useKeyboard }) {
|
|
814
|
+
const theme = useTheme();
|
|
815
|
+
return /* @__PURE__ */ jsx21(Modal, { title: "About Gridland", useKeyboard, onClose, children: /* @__PURE__ */ jsxs15("box", { paddingX: 1, flexDirection: "column", gap: 1, children: [
|
|
816
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "What is Gridland?" }),
|
|
817
|
+
/* @__PURE__ */ jsx21("text", { children: "Gridland renders terminal UIs to HTML5 Canvas with React." }),
|
|
818
|
+
/* @__PURE__ */ jsx21("text", { children: "No xterm.js. No terminal emulator. Just pixels." }),
|
|
819
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Features" }),
|
|
820
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
821
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
822
|
+
"\u2022",
|
|
823
|
+
" "
|
|
824
|
+
] }),
|
|
825
|
+
"Canvas-rendered TUI components"
|
|
826
|
+
] }),
|
|
827
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
828
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
829
|
+
"\u2022",
|
|
830
|
+
" "
|
|
831
|
+
] }),
|
|
832
|
+
"React reconciler with JSX"
|
|
833
|
+
] }),
|
|
834
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
835
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
836
|
+
"\u2022",
|
|
837
|
+
" "
|
|
838
|
+
] }),
|
|
839
|
+
"Yoga flexbox layout engine"
|
|
840
|
+
] }),
|
|
841
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
842
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
843
|
+
"\u2022",
|
|
844
|
+
" "
|
|
845
|
+
] }),
|
|
846
|
+
"Keyboard, mouse, and clipboard support"
|
|
847
|
+
] }),
|
|
848
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
849
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
850
|
+
"\u2022",
|
|
851
|
+
" "
|
|
852
|
+
] }),
|
|
853
|
+
"Next.js and Vite plugins"
|
|
854
|
+
] }),
|
|
855
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Tech Stack" }),
|
|
856
|
+
/* @__PURE__ */ jsx21("text", { children: "React + opentui engine + yoga-layout + HTML5 Canvas" }),
|
|
857
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ dim: true }), children: "Press q to close" })
|
|
858
|
+
] }) });
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// ../docs/components/landing/install-box.tsx
|
|
862
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
863
|
+
function InstallBox() {
|
|
864
|
+
const theme = useTheme();
|
|
865
|
+
return /* @__PURE__ */ jsx22(
|
|
866
|
+
"box",
|
|
867
|
+
{
|
|
868
|
+
border: true,
|
|
869
|
+
borderStyle: "rounded",
|
|
870
|
+
borderColor: theme.border,
|
|
871
|
+
paddingX: 1,
|
|
872
|
+
flexDirection: "column",
|
|
873
|
+
flexShrink: 0,
|
|
874
|
+
children: /* @__PURE__ */ jsxs16("text", { children: [
|
|
875
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
876
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ bold: true }), children: "bun create " }),
|
|
877
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ fg: theme.accent }), children: "gridland" })
|
|
878
|
+
] })
|
|
879
|
+
}
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// ../docs/components/landing/links-box.tsx
|
|
884
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
885
|
+
var UNDERLINE3 = 1 << 3;
|
|
886
|
+
function LinksBox() {
|
|
887
|
+
const theme = useTheme();
|
|
888
|
+
return /* @__PURE__ */ jsx23(
|
|
889
|
+
"box",
|
|
890
|
+
{
|
|
891
|
+
border: true,
|
|
892
|
+
borderStyle: "rounded",
|
|
893
|
+
borderColor: theme.border,
|
|
894
|
+
paddingX: 1,
|
|
895
|
+
flexDirection: "column",
|
|
896
|
+
flexShrink: 0,
|
|
897
|
+
children: /* @__PURE__ */ jsxs17("text", { children: [
|
|
898
|
+
/* @__PURE__ */ jsx23("span", { children: "\u{1F431}" }),
|
|
899
|
+
/* @__PURE__ */ jsx23("a", { href: "https://github.com/cjroth/gridland", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " GitHub" }),
|
|
900
|
+
/* @__PURE__ */ jsx23("span", { children: " " }),
|
|
901
|
+
/* @__PURE__ */ jsx23("span", { children: "\u{1F4D6}" }),
|
|
902
|
+
/* @__PURE__ */ jsx23("a", { href: "/docs", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " Docs" })
|
|
903
|
+
] })
|
|
904
|
+
}
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
|
|
799
908
|
// ../docs/components/landing/logo.tsx
|
|
800
909
|
import { useState as useState8, useEffect as useEffect3, useRef as useRef6, useMemo as useMemo4 } from "react";
|
|
801
910
|
import figlet from "figlet";
|
|
802
911
|
import ansiShadow from "figlet/importable-fonts/ANSI Shadow.js";
|
|
803
|
-
import { Fragment as Fragment6, jsx as
|
|
912
|
+
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
804
913
|
figlet.parseFont("ANSI Shadow", ansiShadow);
|
|
805
914
|
function makeArt(text) {
|
|
806
915
|
return figlet.textSync(text, { font: "ANSI Shadow" }).split("\n").filter((l) => l.trimEnd().length > 0).join("\n");
|
|
@@ -833,9 +942,9 @@ function RevealGradient({ children, revealCol }) {
|
|
|
833
942
|
const gradientColors = GRADIENTS.instagram;
|
|
834
943
|
const lines = children.split("\n");
|
|
835
944
|
const maxLength = Math.max(...lines.map((l) => l.length));
|
|
836
|
-
if (maxLength === 0) return /* @__PURE__ */
|
|
945
|
+
if (maxLength === 0) return /* @__PURE__ */ jsx24("text", { children });
|
|
837
946
|
const hexColors = useMemo4(() => generateGradient(gradientColors, maxLength), [maxLength]);
|
|
838
|
-
return /* @__PURE__ */
|
|
947
|
+
return /* @__PURE__ */ jsx24("box", { position: "relative", width: maxLength, height: lines.length, shouldFill: false, children: lines.map((line, lineIndex) => {
|
|
839
948
|
const runs = [];
|
|
840
949
|
let current = null;
|
|
841
950
|
for (let i = 0; i < line.length; i++) {
|
|
@@ -855,14 +964,14 @@ function RevealGradient({ children, revealCol }) {
|
|
|
855
964
|
}
|
|
856
965
|
}
|
|
857
966
|
if (current) runs.push(current);
|
|
858
|
-
return runs.map((run, runIndex) => /* @__PURE__ */
|
|
967
|
+
return runs.map((run, runIndex) => /* @__PURE__ */ jsx24(
|
|
859
968
|
"box",
|
|
860
969
|
{
|
|
861
970
|
position: "absolute",
|
|
862
971
|
top: lineIndex,
|
|
863
972
|
left: run.start,
|
|
864
973
|
shouldFill: false,
|
|
865
|
-
children: /* @__PURE__ */
|
|
974
|
+
children: /* @__PURE__ */ jsx24("text", { shouldFill: false, children: run.chars.map((char, ci) => /* @__PURE__ */ jsx24(
|
|
866
975
|
"span",
|
|
867
976
|
{
|
|
868
977
|
style: { fg: hexColors[run.start + ci] },
|
|
@@ -884,20 +993,20 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
884
993
|
const maxWidth = compact ? 8 : narrow ? 40 : 62;
|
|
885
994
|
const revealCol = Math.round(revealProgress * (maxWidth + 4)) - 2;
|
|
886
995
|
const taglineOpacity = Math.max(0, Math.min(1, (progress - 0.7) / 0.3));
|
|
887
|
-
const subtitle = /* @__PURE__ */
|
|
888
|
-
/* @__PURE__ */
|
|
889
|
-
/* @__PURE__ */
|
|
996
|
+
const subtitle = /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
997
|
+
/* @__PURE__ */ jsx24("text", { children: " " }),
|
|
998
|
+
/* @__PURE__ */ jsx24("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs18("text", { style: textStyle({ fg: "#d4b0e8" }), opacity: taglineOpacity, wrapMode: "word", textAlign: "center", width: "100%", shouldFill: false, children: [
|
|
890
999
|
"A framework for building terminal apps, built on ",
|
|
891
|
-
/* @__PURE__ */
|
|
1000
|
+
/* @__PURE__ */ jsx24("a", { href: "https://opentui.com", style: { attributes: 72, fg: "#d4b0e8" }, children: "OpenTUI" }),
|
|
892
1001
|
" + React." + (mobile ? " " : "\n") + "(Gridland apps, like this website, work in the browser and terminal.)"
|
|
893
1002
|
] }) })
|
|
894
1003
|
] });
|
|
895
1004
|
if (!isBrowser) {
|
|
896
1005
|
const art = compact ? "gridland" : narrow ? gridArt + "\n" + landArt : fullArt;
|
|
897
|
-
return /* @__PURE__ */
|
|
898
|
-
/* @__PURE__ */
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
1006
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", alignItems: "center", children: [
|
|
1007
|
+
/* @__PURE__ */ jsx24(Gradient, { name: "instagram", children: art }),
|
|
1008
|
+
/* @__PURE__ */ jsx24("text", { children: " " }),
|
|
1009
|
+
/* @__PURE__ */ jsx24("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs18("text", { style: textStyle({ fg: "#d4b0e8" }), shouldFill: false, children: [
|
|
901
1010
|
"A framework for building terminal apps, built on OpenTUI + React.",
|
|
902
1011
|
"\n",
|
|
903
1012
|
"(Gridland apps, like this website, work in the browser and terminal.)"
|
|
@@ -905,73 +1014,26 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
905
1014
|
] });
|
|
906
1015
|
}
|
|
907
1016
|
if (compact) {
|
|
908
|
-
return /* @__PURE__ */
|
|
909
|
-
/* @__PURE__ */
|
|
1017
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1018
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx24("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: "gridland" }) }) }),
|
|
910
1019
|
subtitle
|
|
911
1020
|
] });
|
|
912
1021
|
}
|
|
913
1022
|
if (narrow) {
|
|
914
|
-
return /* @__PURE__ */
|
|
915
|
-
/* @__PURE__ */
|
|
916
|
-
/* @__PURE__ */
|
|
917
|
-
/* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1024
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsxs18("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: [
|
|
1025
|
+
/* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: gridArt }),
|
|
1026
|
+
/* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: landArt })
|
|
918
1027
|
] }) }),
|
|
919
1028
|
subtitle
|
|
920
1029
|
] });
|
|
921
1030
|
}
|
|
922
|
-
return /* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
1031
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1032
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx24("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: fullArt }) }) }),
|
|
924
1033
|
subtitle
|
|
925
1034
|
] });
|
|
926
1035
|
}
|
|
927
1036
|
|
|
928
|
-
// ../docs/components/landing/install-box.tsx
|
|
929
|
-
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
930
|
-
function InstallBox() {
|
|
931
|
-
const theme = useTheme();
|
|
932
|
-
return /* @__PURE__ */ jsx22(
|
|
933
|
-
"box",
|
|
934
|
-
{
|
|
935
|
-
border: true,
|
|
936
|
-
borderStyle: "rounded",
|
|
937
|
-
borderColor: theme.border,
|
|
938
|
-
paddingX: 1,
|
|
939
|
-
flexDirection: "column",
|
|
940
|
-
flexShrink: 0,
|
|
941
|
-
children: /* @__PURE__ */ jsxs16("text", { children: [
|
|
942
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
943
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ bold: true }), children: "bun create " }),
|
|
944
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ fg: theme.accent }), children: "gridland" })
|
|
945
|
-
] })
|
|
946
|
-
}
|
|
947
|
-
);
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
// ../docs/components/landing/links-box.tsx
|
|
951
|
-
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
952
|
-
var UNDERLINE3 = 1 << 3;
|
|
953
|
-
function LinksBox() {
|
|
954
|
-
const theme = useTheme();
|
|
955
|
-
return /* @__PURE__ */ jsx23(
|
|
956
|
-
"box",
|
|
957
|
-
{
|
|
958
|
-
border: true,
|
|
959
|
-
borderStyle: "rounded",
|
|
960
|
-
borderColor: theme.border,
|
|
961
|
-
paddingX: 1,
|
|
962
|
-
flexDirection: "column",
|
|
963
|
-
flexShrink: 0,
|
|
964
|
-
children: /* @__PURE__ */ jsxs17("text", { children: [
|
|
965
|
-
/* @__PURE__ */ jsx23("span", { children: "\u{1F431}" }),
|
|
966
|
-
/* @__PURE__ */ jsx23("a", { href: "https://github.com/cjroth/gridland", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " GitHub" }),
|
|
967
|
-
/* @__PURE__ */ jsx23("span", { children: " " }),
|
|
968
|
-
/* @__PURE__ */ jsx23("span", { children: "\u{1F4D6}" }),
|
|
969
|
-
/* @__PURE__ */ jsx23("a", { href: "/docs", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " Docs" })
|
|
970
|
-
] })
|
|
971
|
-
}
|
|
972
|
-
);
|
|
973
|
-
}
|
|
974
|
-
|
|
975
1037
|
// ../docs/components/landing/matrix-background.tsx
|
|
976
1038
|
import { useMemo as useMemo5 } from "react";
|
|
977
1039
|
|
|
@@ -1055,7 +1117,7 @@ function useMatrix(width, height) {
|
|
|
1055
1117
|
}
|
|
1056
1118
|
|
|
1057
1119
|
// ../docs/components/landing/matrix-background.tsx
|
|
1058
|
-
import { jsx as
|
|
1120
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1059
1121
|
var MUTE_LEVELS = [0.12, 0.18, 0.24, 0.3, 0.38];
|
|
1060
1122
|
var BG = hexToRgb("#1a1a2e");
|
|
1061
1123
|
function buildMutedColors(baseHex) {
|
|
@@ -1082,15 +1144,15 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1082
1144
|
() => columnColors.map(buildMutedColors),
|
|
1083
1145
|
[columnColors]
|
|
1084
1146
|
);
|
|
1085
|
-
return /* @__PURE__ */
|
|
1147
|
+
return /* @__PURE__ */ jsx25("box", { flexDirection: "column", children: grid.map((row, y) => /* @__PURE__ */ jsx25("text", { children: row.map((cell, x) => {
|
|
1086
1148
|
const inClearRect = clearRect && y >= clearRect.top && y < clearRect.top + clearRect.height && x >= clearRect.left && x < clearRect.left + clearRect.width || clearRects && clearRects.some(
|
|
1087
1149
|
(r) => y >= r.top && y < r.top + r.height && x >= r.left && x < r.left + r.width
|
|
1088
1150
|
);
|
|
1089
1151
|
const mutedColors = columnMutedColors[x];
|
|
1090
1152
|
if (cell === " " || inClearRect || !mutedColors) {
|
|
1091
|
-
return /* @__PURE__ */
|
|
1153
|
+
return /* @__PURE__ */ jsx25("span", { children: " " }, x);
|
|
1092
1154
|
}
|
|
1093
|
-
return /* @__PURE__ */
|
|
1155
|
+
return /* @__PURE__ */ jsx25(
|
|
1094
1156
|
"span",
|
|
1095
1157
|
{
|
|
1096
1158
|
style: {
|
|
@@ -1103,62 +1165,34 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1103
1165
|
}) }, y)) });
|
|
1104
1166
|
}
|
|
1105
1167
|
|
|
1106
|
-
// ../docs/components/landing/about-modal.tsx
|
|
1107
|
-
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1108
|
-
function AboutModal({ onClose, useKeyboard }) {
|
|
1109
|
-
const theme = useTheme();
|
|
1110
|
-
return /* @__PURE__ */ jsx25(Modal, { title: "About Gridland", useKeyboard, onClose, children: /* @__PURE__ */ jsxs18("box", { paddingX: 1, flexDirection: "column", gap: 1, children: [
|
|
1111
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "What is Gridland?" }),
|
|
1112
|
-
/* @__PURE__ */ jsx25("text", { children: "Gridland renders terminal UIs to HTML5 Canvas with React." }),
|
|
1113
|
-
/* @__PURE__ */ jsx25("text", { children: "No xterm.js. No terminal emulator. Just pixels." }),
|
|
1114
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Features" }),
|
|
1115
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1116
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1117
|
-
"\u2022",
|
|
1118
|
-
" "
|
|
1119
|
-
] }),
|
|
1120
|
-
"Canvas-rendered TUI components"
|
|
1121
|
-
] }),
|
|
1122
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1123
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1124
|
-
"\u2022",
|
|
1125
|
-
" "
|
|
1126
|
-
] }),
|
|
1127
|
-
"React reconciler with JSX"
|
|
1128
|
-
] }),
|
|
1129
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1130
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1131
|
-
"\u2022",
|
|
1132
|
-
" "
|
|
1133
|
-
] }),
|
|
1134
|
-
"Yoga flexbox layout engine"
|
|
1135
|
-
] }),
|
|
1136
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1137
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1138
|
-
"\u2022",
|
|
1139
|
-
" "
|
|
1140
|
-
] }),
|
|
1141
|
-
"Keyboard, mouse, and clipboard support"
|
|
1142
|
-
] }),
|
|
1143
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1144
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1145
|
-
"\u2022",
|
|
1146
|
-
" "
|
|
1147
|
-
] }),
|
|
1148
|
-
"Next.js and Vite plugins"
|
|
1149
|
-
] }),
|
|
1150
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Tech Stack" }),
|
|
1151
|
-
/* @__PURE__ */ jsx25("text", { children: "React + opentui engine + yoga-layout + HTML5 Canvas" }),
|
|
1152
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ dim: true }), children: "Press q to close" })
|
|
1153
|
-
] }) });
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
1168
|
// ../docs/components/landing/landing-app.tsx
|
|
1157
1169
|
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1170
|
+
var DEMO_RESPONSES = [
|
|
1171
|
+
"Gridland is a framework for building terminal apps with React. It works in both the browser and terminal!",
|
|
1172
|
+
"You can get started with `bun create gridland` to scaffold a new project.",
|
|
1173
|
+
"OpenTUI provides the layout primitives \u2014 flexbox, borders, text styling \u2014 while React handles the component model.",
|
|
1174
|
+
"Yes! Gridland apps are universal \u2014 the same code renders in a terminal emulator and in the browser.",
|
|
1175
|
+
"Check out the docs for examples of interactive components like inputs, selects, and tables."
|
|
1176
|
+
];
|
|
1158
1177
|
function LandingApp({ useKeyboard }) {
|
|
1159
1178
|
const theme = useTheme();
|
|
1160
1179
|
const { width, height, isNarrow, isTiny, isMobile } = useBreakpoints();
|
|
1161
1180
|
const [showAbout, setShowAbout] = useState10(false);
|
|
1181
|
+
const [messages, setMessages] = useState10([]);
|
|
1182
|
+
const [chatStatus, setChatStatus] = useState10("ready");
|
|
1183
|
+
const responseIdx = useRef8(0);
|
|
1184
|
+
const handleChatSubmit = useCallback3(({ text }) => {
|
|
1185
|
+
const userMsg = { id: `u-${Date.now()}`, role: "user", content: text };
|
|
1186
|
+
setMessages((prev) => [...prev, userMsg]);
|
|
1187
|
+
setChatStatus("streaming");
|
|
1188
|
+
setTimeout(() => {
|
|
1189
|
+
const response = DEMO_RESPONSES[responseIdx.current % DEMO_RESPONSES.length];
|
|
1190
|
+
responseIdx.current += 1;
|
|
1191
|
+
const assistantMsg = { id: `a-${Date.now()}`, role: "assistant", content: response };
|
|
1192
|
+
setMessages((prev) => [...prev, assistantMsg]);
|
|
1193
|
+
setChatStatus("ready");
|
|
1194
|
+
}, 1200);
|
|
1195
|
+
}, []);
|
|
1162
1196
|
useKeyboard((event) => {
|
|
1163
1197
|
if (event.name === "a" && !showAbout) {
|
|
1164
1198
|
setShowAbout(true);
|
|
@@ -1185,61 +1219,25 @@ function LandingApp({ useKeyboard }) {
|
|
|
1185
1219
|
const installLinksClearRect = { top: installLinksTop, left: 1, width: width - 2, height: installLinksHeight };
|
|
1186
1220
|
return /* @__PURE__ */ jsxs19("box", { width: "100%", height: "100%", position: "relative", children: [
|
|
1187
1221
|
/* @__PURE__ */ jsx26(MatrixBackground, { width, height, clearRect, clearRects: [installLinksClearRect] }),
|
|
1188
|
-
/* @__PURE__ */ jsxs19(
|
|
1189
|
-
"box",
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
borderStyle: "rounded",
|
|
1208
|
-
borderColor: theme.border,
|
|
1209
|
-
paddingX: 1,
|
|
1210
|
-
flexDirection: "column",
|
|
1211
|
-
flexShrink: 0,
|
|
1212
|
-
children: /* @__PURE__ */ jsxs19("text", { children: [
|
|
1213
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
1214
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ bold: true }), children: "bunx " }),
|
|
1215
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ fg: theme.accent }), children: "@gridland/demo landing" })
|
|
1216
|
-
] })
|
|
1217
|
-
}
|
|
1218
|
-
),
|
|
1219
|
-
/* @__PURE__ */ jsx26(InstallBox, {}),
|
|
1220
|
-
/* @__PURE__ */ jsx26(LinksBox, {})
|
|
1221
|
-
] }),
|
|
1222
|
-
/* @__PURE__ */ jsx26(
|
|
1223
|
-
"box",
|
|
1224
|
-
{
|
|
1225
|
-
flexGrow: 1,
|
|
1226
|
-
border: true,
|
|
1227
|
-
borderStyle: "rounded",
|
|
1228
|
-
borderColor: theme.border
|
|
1229
|
-
}
|
|
1230
|
-
)
|
|
1231
|
-
] }),
|
|
1232
|
-
/* @__PURE__ */ jsx26(
|
|
1233
|
-
StatusBar,
|
|
1234
|
-
{
|
|
1235
|
-
items: [
|
|
1236
|
-
{ key: "a", label: "about" }
|
|
1237
|
-
]
|
|
1238
|
-
}
|
|
1239
|
-
)
|
|
1240
|
-
]
|
|
1241
|
-
}
|
|
1242
|
-
)
|
|
1222
|
+
/* @__PURE__ */ jsxs19("box", { position: "absolute", top: 0, left: 0, width, height, zIndex: 1, flexDirection: "column", shouldFill: false, children: [
|
|
1223
|
+
/* @__PURE__ */ jsxs19("box", { flexGrow: 1, flexDirection: "column", paddingTop: 3, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, gap: isMobile ? 0 : 1, shouldFill: false, children: [
|
|
1224
|
+
/* @__PURE__ */ jsx26("box", { flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx26(Logo, { compact: isTiny, narrow: isNarrow, mobile: isMobile }) }),
|
|
1225
|
+
/* @__PURE__ */ jsxs19("box", { flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: isMobile ? 0 : 1, flexShrink: 0, shouldFill: false, children: [
|
|
1226
|
+
/* @__PURE__ */ jsx26("box", { border: true, borderStyle: "rounded", borderColor: theme.border, paddingX: 1, flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsxs19("text", { children: [
|
|
1227
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
1228
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ bold: true }), children: "bunx " }),
|
|
1229
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ fg: theme.accent }), children: "@gridland/demo landing" })
|
|
1230
|
+
] }) }),
|
|
1231
|
+
/* @__PURE__ */ jsx26(InstallBox, {}),
|
|
1232
|
+
/* @__PURE__ */ jsx26(LinksBox, {})
|
|
1233
|
+
] }),
|
|
1234
|
+
/* @__PURE__ */ jsxs19("box", { flexGrow: 1, border: true, borderStyle: "rounded", borderColor: theme.border, flexDirection: "column", overflow: "hidden", children: [
|
|
1235
|
+
/* @__PURE__ */ jsx26("box", { flexGrow: 1, flexDirection: "column", paddingX: 1, overflow: "hidden", children: messages.map((msg) => /* @__PURE__ */ jsx26(Message, { role: msg.role, children: /* @__PURE__ */ jsx26(Message.Content, { children: /* @__PURE__ */ jsx26(Message.Text, { children: msg.content }) }) }, msg.id)) }),
|
|
1236
|
+
/* @__PURE__ */ jsx26("box", { flexShrink: 0, paddingX: 1, paddingBottom: 0, children: /* @__PURE__ */ jsx26(PromptInput, { splaceholder: "Ask about Gridland...", status: chatStatus, onSubmit: handleChatSubmit, useKeyboard }) })
|
|
1237
|
+
] })
|
|
1238
|
+
] }),
|
|
1239
|
+
/* @__PURE__ */ jsx26(StatusBar, { items: [{ key: "a", label: "about" }] })
|
|
1240
|
+
] })
|
|
1243
1241
|
] });
|
|
1244
1242
|
}
|
|
1245
1243
|
|
package/dist/run.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createCliRenderer } from "@opentui/core";
|
|
|
3
3
|
import { createRoot, useKeyboard as useKeyboard2 } from "@opentui/react";
|
|
4
4
|
|
|
5
5
|
// ../ui/scripts/demo-apps.tsx
|
|
6
|
-
import { useState as useState11, useCallback as
|
|
6
|
+
import { useState as useState11, useCallback as useCallback4, useRef as useRef9, useEffect as useEffect5 } from "react";
|
|
7
7
|
import { useKeyboard } from "@opentui/react";
|
|
8
8
|
|
|
9
9
|
// ../ui/components/theme/themes.ts
|
|
@@ -1077,6 +1077,14 @@ function PromptInputStatusText() {
|
|
|
1077
1077
|
if (status !== "error") return null;
|
|
1078
1078
|
return /* @__PURE__ */ jsx16("text", { children: /* @__PURE__ */ jsx16("span", { style: textStyle({ fg: theme.error }), children: errorText }) });
|
|
1079
1079
|
}
|
|
1080
|
+
function PromptInputModel() {
|
|
1081
|
+
const { model, theme } = usePromptInput();
|
|
1082
|
+
if (!model) return null;
|
|
1083
|
+
return /* @__PURE__ */ jsxs10("text", { dim: true, color: theme.muted, children: [
|
|
1084
|
+
"model: ",
|
|
1085
|
+
model
|
|
1086
|
+
] });
|
|
1087
|
+
}
|
|
1080
1088
|
function PromptInput({
|
|
1081
1089
|
value: controlledValue,
|
|
1082
1090
|
defaultValue = "",
|
|
@@ -1097,7 +1105,8 @@ function PromptInput({
|
|
|
1097
1105
|
getSuggestions: customGetSuggestions,
|
|
1098
1106
|
maxSuggestions = 5,
|
|
1099
1107
|
enableHistory = true,
|
|
1100
|
-
|
|
1108
|
+
model,
|
|
1109
|
+
showDividers = true,
|
|
1101
1110
|
useKeyboard: useKeyboardProp,
|
|
1102
1111
|
children
|
|
1103
1112
|
}) {
|
|
@@ -1292,6 +1301,7 @@ function PromptInput({
|
|
|
1292
1301
|
sugIdx,
|
|
1293
1302
|
maxSuggestions,
|
|
1294
1303
|
errorText,
|
|
1304
|
+
model,
|
|
1295
1305
|
theme
|
|
1296
1306
|
};
|
|
1297
1307
|
if (children) {
|
|
@@ -1302,6 +1312,7 @@ function PromptInput({
|
|
|
1302
1312
|
/* @__PURE__ */ jsx16(PromptInputSuggestions, {}),
|
|
1303
1313
|
/* @__PURE__ */ jsx16(PromptInputTextarea, {}),
|
|
1304
1314
|
/* @__PURE__ */ jsx16(PromptInputStatusText, {}),
|
|
1315
|
+
/* @__PURE__ */ jsx16(PromptInputModel, {}),
|
|
1305
1316
|
showDividers && /* @__PURE__ */ jsx16(PromptInputDivider, {})
|
|
1306
1317
|
] }) });
|
|
1307
1318
|
}
|
|
@@ -1310,6 +1321,7 @@ PromptInput.Suggestions = PromptInputSuggestions;
|
|
|
1310
1321
|
PromptInput.Submit = PromptInputSubmit;
|
|
1311
1322
|
PromptInput.Divider = PromptInputDivider;
|
|
1312
1323
|
PromptInput.StatusText = PromptInputStatusText;
|
|
1324
|
+
PromptInput.Model = PromptInputModel;
|
|
1313
1325
|
|
|
1314
1326
|
// ../ui/components/chat/chat.tsx
|
|
1315
1327
|
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
@@ -1675,13 +1687,110 @@ function useBreakpoints() {
|
|
|
1675
1687
|
}
|
|
1676
1688
|
|
|
1677
1689
|
// ../docs/components/landing/landing-app.tsx
|
|
1678
|
-
import { useState as useState10 } from "react";
|
|
1690
|
+
import { useCallback as useCallback3, useRef as useRef8, useState as useState10 } from "react";
|
|
1691
|
+
|
|
1692
|
+
// ../docs/components/landing/about-modal.tsx
|
|
1693
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1694
|
+
function AboutModal({ onClose, useKeyboard: useKeyboard3 }) {
|
|
1695
|
+
const theme = useTheme();
|
|
1696
|
+
return /* @__PURE__ */ jsx21(Modal, { title: "About Gridland", useKeyboard: useKeyboard3, onClose, children: /* @__PURE__ */ jsxs15("box", { paddingX: 1, flexDirection: "column", gap: 1, children: [
|
|
1697
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "What is Gridland?" }),
|
|
1698
|
+
/* @__PURE__ */ jsx21("text", { children: "Gridland renders terminal UIs to HTML5 Canvas with React." }),
|
|
1699
|
+
/* @__PURE__ */ jsx21("text", { children: "No xterm.js. No terminal emulator. Just pixels." }),
|
|
1700
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Features" }),
|
|
1701
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
1702
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
1703
|
+
"\u2022",
|
|
1704
|
+
" "
|
|
1705
|
+
] }),
|
|
1706
|
+
"Canvas-rendered TUI components"
|
|
1707
|
+
] }),
|
|
1708
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
1709
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
1710
|
+
"\u2022",
|
|
1711
|
+
" "
|
|
1712
|
+
] }),
|
|
1713
|
+
"React reconciler with JSX"
|
|
1714
|
+
] }),
|
|
1715
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
1716
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
1717
|
+
"\u2022",
|
|
1718
|
+
" "
|
|
1719
|
+
] }),
|
|
1720
|
+
"Yoga flexbox layout engine"
|
|
1721
|
+
] }),
|
|
1722
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
1723
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
1724
|
+
"\u2022",
|
|
1725
|
+
" "
|
|
1726
|
+
] }),
|
|
1727
|
+
"Keyboard, mouse, and clipboard support"
|
|
1728
|
+
] }),
|
|
1729
|
+
/* @__PURE__ */ jsxs15("text", { children: [
|
|
1730
|
+
/* @__PURE__ */ jsxs15("span", { style: textStyle({ dim: true }), children: [
|
|
1731
|
+
"\u2022",
|
|
1732
|
+
" "
|
|
1733
|
+
] }),
|
|
1734
|
+
"Next.js and Vite plugins"
|
|
1735
|
+
] }),
|
|
1736
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Tech Stack" }),
|
|
1737
|
+
/* @__PURE__ */ jsx21("text", { children: "React + opentui engine + yoga-layout + HTML5 Canvas" }),
|
|
1738
|
+
/* @__PURE__ */ jsx21("text", { style: textStyle({ dim: true }), children: "Press q to close" })
|
|
1739
|
+
] }) });
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// ../docs/components/landing/install-box.tsx
|
|
1743
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1744
|
+
function InstallBox() {
|
|
1745
|
+
const theme = useTheme();
|
|
1746
|
+
return /* @__PURE__ */ jsx22(
|
|
1747
|
+
"box",
|
|
1748
|
+
{
|
|
1749
|
+
border: true,
|
|
1750
|
+
borderStyle: "rounded",
|
|
1751
|
+
borderColor: theme.border,
|
|
1752
|
+
paddingX: 1,
|
|
1753
|
+
flexDirection: "column",
|
|
1754
|
+
flexShrink: 0,
|
|
1755
|
+
children: /* @__PURE__ */ jsxs16("text", { children: [
|
|
1756
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
1757
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ bold: true }), children: "bun create " }),
|
|
1758
|
+
/* @__PURE__ */ jsx22("span", { style: textStyle({ fg: theme.accent }), children: "gridland" })
|
|
1759
|
+
] })
|
|
1760
|
+
}
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
// ../docs/components/landing/links-box.tsx
|
|
1765
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1766
|
+
var UNDERLINE3 = 1 << 3;
|
|
1767
|
+
function LinksBox() {
|
|
1768
|
+
const theme = useTheme();
|
|
1769
|
+
return /* @__PURE__ */ jsx23(
|
|
1770
|
+
"box",
|
|
1771
|
+
{
|
|
1772
|
+
border: true,
|
|
1773
|
+
borderStyle: "rounded",
|
|
1774
|
+
borderColor: theme.border,
|
|
1775
|
+
paddingX: 1,
|
|
1776
|
+
flexDirection: "column",
|
|
1777
|
+
flexShrink: 0,
|
|
1778
|
+
children: /* @__PURE__ */ jsxs17("text", { children: [
|
|
1779
|
+
/* @__PURE__ */ jsx23("span", { children: "\u{1F431}" }),
|
|
1780
|
+
/* @__PURE__ */ jsx23("a", { href: "https://github.com/cjroth/gridland", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " GitHub" }),
|
|
1781
|
+
/* @__PURE__ */ jsx23("span", { children: " " }),
|
|
1782
|
+
/* @__PURE__ */ jsx23("span", { children: "\u{1F4D6}" }),
|
|
1783
|
+
/* @__PURE__ */ jsx23("a", { href: "/docs", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " Docs" })
|
|
1784
|
+
] })
|
|
1785
|
+
}
|
|
1786
|
+
);
|
|
1787
|
+
}
|
|
1679
1788
|
|
|
1680
1789
|
// ../docs/components/landing/logo.tsx
|
|
1681
1790
|
import { useState as useState8, useEffect as useEffect3, useRef as useRef6, useMemo as useMemo4 } from "react";
|
|
1682
1791
|
import figlet from "figlet";
|
|
1683
1792
|
import ansiShadow from "figlet/importable-fonts/ANSI Shadow.js";
|
|
1684
|
-
import { Fragment as Fragment6, jsx as
|
|
1793
|
+
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1685
1794
|
figlet.parseFont("ANSI Shadow", ansiShadow);
|
|
1686
1795
|
function makeArt(text) {
|
|
1687
1796
|
return figlet.textSync(text, { font: "ANSI Shadow" }).split("\n").filter((l) => l.trimEnd().length > 0).join("\n");
|
|
@@ -1714,9 +1823,9 @@ function RevealGradient({ children, revealCol }) {
|
|
|
1714
1823
|
const gradientColors = GRADIENTS.instagram;
|
|
1715
1824
|
const lines = children.split("\n");
|
|
1716
1825
|
const maxLength = Math.max(...lines.map((l) => l.length));
|
|
1717
|
-
if (maxLength === 0) return /* @__PURE__ */
|
|
1826
|
+
if (maxLength === 0) return /* @__PURE__ */ jsx24("text", { children });
|
|
1718
1827
|
const hexColors = useMemo4(() => generateGradient(gradientColors, maxLength), [maxLength]);
|
|
1719
|
-
return /* @__PURE__ */
|
|
1828
|
+
return /* @__PURE__ */ jsx24("box", { position: "relative", width: maxLength, height: lines.length, shouldFill: false, children: lines.map((line, lineIndex) => {
|
|
1720
1829
|
const runs = [];
|
|
1721
1830
|
let current = null;
|
|
1722
1831
|
for (let i = 0; i < line.length; i++) {
|
|
@@ -1736,14 +1845,14 @@ function RevealGradient({ children, revealCol }) {
|
|
|
1736
1845
|
}
|
|
1737
1846
|
}
|
|
1738
1847
|
if (current) runs.push(current);
|
|
1739
|
-
return runs.map((run, runIndex) => /* @__PURE__ */
|
|
1848
|
+
return runs.map((run, runIndex) => /* @__PURE__ */ jsx24(
|
|
1740
1849
|
"box",
|
|
1741
1850
|
{
|
|
1742
1851
|
position: "absolute",
|
|
1743
1852
|
top: lineIndex,
|
|
1744
1853
|
left: run.start,
|
|
1745
1854
|
shouldFill: false,
|
|
1746
|
-
children: /* @__PURE__ */
|
|
1855
|
+
children: /* @__PURE__ */ jsx24("text", { shouldFill: false, children: run.chars.map((char, ci) => /* @__PURE__ */ jsx24(
|
|
1747
1856
|
"span",
|
|
1748
1857
|
{
|
|
1749
1858
|
style: { fg: hexColors[run.start + ci] },
|
|
@@ -1765,20 +1874,20 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
1765
1874
|
const maxWidth = compact ? 8 : narrow ? 40 : 62;
|
|
1766
1875
|
const revealCol = Math.round(revealProgress * (maxWidth + 4)) - 2;
|
|
1767
1876
|
const taglineOpacity = Math.max(0, Math.min(1, (progress - 0.7) / 0.3));
|
|
1768
|
-
const subtitle = /* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
1770
|
-
/* @__PURE__ */
|
|
1877
|
+
const subtitle = /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
1878
|
+
/* @__PURE__ */ jsx24("text", { children: " " }),
|
|
1879
|
+
/* @__PURE__ */ jsx24("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs18("text", { style: textStyle({ fg: "#d4b0e8" }), opacity: taglineOpacity, wrapMode: "word", textAlign: "center", width: "100%", shouldFill: false, children: [
|
|
1771
1880
|
"A framework for building terminal apps, built on ",
|
|
1772
|
-
/* @__PURE__ */
|
|
1881
|
+
/* @__PURE__ */ jsx24("a", { href: "https://opentui.com", style: { attributes: 72, fg: "#d4b0e8" }, children: "OpenTUI" }),
|
|
1773
1882
|
" + React." + (mobile ? " " : "\n") + "(Gridland apps, like this website, work in the browser and terminal.)"
|
|
1774
1883
|
] }) })
|
|
1775
1884
|
] });
|
|
1776
1885
|
if (!isBrowser) {
|
|
1777
1886
|
const art = compact ? "gridland" : narrow ? gridArt + "\n" + landArt : fullArt;
|
|
1778
|
-
return /* @__PURE__ */
|
|
1779
|
-
/* @__PURE__ */
|
|
1780
|
-
/* @__PURE__ */
|
|
1781
|
-
/* @__PURE__ */
|
|
1887
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", alignItems: "center", children: [
|
|
1888
|
+
/* @__PURE__ */ jsx24(Gradient, { name: "instagram", children: art }),
|
|
1889
|
+
/* @__PURE__ */ jsx24("text", { children: " " }),
|
|
1890
|
+
/* @__PURE__ */ jsx24("box", { flexDirection: "column", alignItems: "center", width: "100%", shouldFill: false, children: /* @__PURE__ */ jsxs18("text", { style: textStyle({ fg: "#d4b0e8" }), shouldFill: false, children: [
|
|
1782
1891
|
"A framework for building terminal apps, built on OpenTUI + React.",
|
|
1783
1892
|
"\n",
|
|
1784
1893
|
"(Gridland apps, like this website, work in the browser and terminal.)"
|
|
@@ -1786,73 +1895,26 @@ function Logo({ compact, narrow, mobile }) {
|
|
|
1786
1895
|
] });
|
|
1787
1896
|
}
|
|
1788
1897
|
if (compact) {
|
|
1789
|
-
return /* @__PURE__ */
|
|
1790
|
-
/* @__PURE__ */
|
|
1898
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1899
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx24("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: "gridland" }) }) }),
|
|
1791
1900
|
subtitle
|
|
1792
1901
|
] });
|
|
1793
1902
|
}
|
|
1794
1903
|
if (narrow) {
|
|
1795
|
-
return /* @__PURE__ */
|
|
1796
|
-
/* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1904
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1905
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsxs18("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: [
|
|
1906
|
+
/* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: gridArt }),
|
|
1907
|
+
/* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: landArt })
|
|
1799
1908
|
] }) }),
|
|
1800
1909
|
subtitle
|
|
1801
1910
|
] });
|
|
1802
1911
|
}
|
|
1803
|
-
return /* @__PURE__ */
|
|
1804
|
-
/* @__PURE__ */
|
|
1912
|
+
return /* @__PURE__ */ jsxs18("box", { flexDirection: "column", flexShrink: 0, width: "100%", shouldFill: false, children: [
|
|
1913
|
+
/* @__PURE__ */ jsx24("box", { height: artHeight, overflow: "hidden", position: "relative", width: "100%", flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx24("box", { position: "absolute", top: dropOffset, width: "100%", flexDirection: "column", alignItems: "center", shouldFill: false, children: /* @__PURE__ */ jsx24(RevealGradient, { revealCol, children: fullArt }) }) }),
|
|
1805
1914
|
subtitle
|
|
1806
1915
|
] });
|
|
1807
1916
|
}
|
|
1808
1917
|
|
|
1809
|
-
// ../docs/components/landing/install-box.tsx
|
|
1810
|
-
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1811
|
-
function InstallBox() {
|
|
1812
|
-
const theme = useTheme();
|
|
1813
|
-
return /* @__PURE__ */ jsx22(
|
|
1814
|
-
"box",
|
|
1815
|
-
{
|
|
1816
|
-
border: true,
|
|
1817
|
-
borderStyle: "rounded",
|
|
1818
|
-
borderColor: theme.border,
|
|
1819
|
-
paddingX: 1,
|
|
1820
|
-
flexDirection: "column",
|
|
1821
|
-
flexShrink: 0,
|
|
1822
|
-
children: /* @__PURE__ */ jsxs16("text", { children: [
|
|
1823
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
1824
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ bold: true }), children: "bun create " }),
|
|
1825
|
-
/* @__PURE__ */ jsx22("span", { style: textStyle({ fg: theme.accent }), children: "gridland" })
|
|
1826
|
-
] })
|
|
1827
|
-
}
|
|
1828
|
-
);
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
// ../docs/components/landing/links-box.tsx
|
|
1832
|
-
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1833
|
-
var UNDERLINE3 = 1 << 3;
|
|
1834
|
-
function LinksBox() {
|
|
1835
|
-
const theme = useTheme();
|
|
1836
|
-
return /* @__PURE__ */ jsx23(
|
|
1837
|
-
"box",
|
|
1838
|
-
{
|
|
1839
|
-
border: true,
|
|
1840
|
-
borderStyle: "rounded",
|
|
1841
|
-
borderColor: theme.border,
|
|
1842
|
-
paddingX: 1,
|
|
1843
|
-
flexDirection: "column",
|
|
1844
|
-
flexShrink: 0,
|
|
1845
|
-
children: /* @__PURE__ */ jsxs17("text", { children: [
|
|
1846
|
-
/* @__PURE__ */ jsx23("span", { children: "\u{1F431}" }),
|
|
1847
|
-
/* @__PURE__ */ jsx23("a", { href: "https://github.com/cjroth/gridland", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " GitHub" }),
|
|
1848
|
-
/* @__PURE__ */ jsx23("span", { children: " " }),
|
|
1849
|
-
/* @__PURE__ */ jsx23("span", { children: "\u{1F4D6}" }),
|
|
1850
|
-
/* @__PURE__ */ jsx23("a", { href: "/docs", style: { attributes: UNDERLINE3, fg: theme.accent }, children: " Docs" })
|
|
1851
|
-
] })
|
|
1852
|
-
}
|
|
1853
|
-
);
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
1918
|
// ../docs/components/landing/matrix-background.tsx
|
|
1857
1919
|
import { useMemo as useMemo5 } from "react";
|
|
1858
1920
|
|
|
@@ -1936,7 +1998,7 @@ function useMatrix(width, height) {
|
|
|
1936
1998
|
}
|
|
1937
1999
|
|
|
1938
2000
|
// ../docs/components/landing/matrix-background.tsx
|
|
1939
|
-
import { jsx as
|
|
2001
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1940
2002
|
var MUTE_LEVELS = [0.12, 0.18, 0.24, 0.3, 0.38];
|
|
1941
2003
|
var BG = hexToRgb("#1a1a2e");
|
|
1942
2004
|
function buildMutedColors(baseHex) {
|
|
@@ -1963,15 +2025,15 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1963
2025
|
() => columnColors.map(buildMutedColors),
|
|
1964
2026
|
[columnColors]
|
|
1965
2027
|
);
|
|
1966
|
-
return /* @__PURE__ */
|
|
2028
|
+
return /* @__PURE__ */ jsx25("box", { flexDirection: "column", children: grid.map((row, y) => /* @__PURE__ */ jsx25("text", { children: row.map((cell, x) => {
|
|
1967
2029
|
const inClearRect = clearRect && y >= clearRect.top && y < clearRect.top + clearRect.height && x >= clearRect.left && x < clearRect.left + clearRect.width || clearRects && clearRects.some(
|
|
1968
2030
|
(r) => y >= r.top && y < r.top + r.height && x >= r.left && x < r.left + r.width
|
|
1969
2031
|
);
|
|
1970
2032
|
const mutedColors = columnMutedColors[x];
|
|
1971
2033
|
if (cell === " " || inClearRect || !mutedColors) {
|
|
1972
|
-
return /* @__PURE__ */
|
|
2034
|
+
return /* @__PURE__ */ jsx25("span", { children: " " }, x);
|
|
1973
2035
|
}
|
|
1974
|
-
return /* @__PURE__ */
|
|
2036
|
+
return /* @__PURE__ */ jsx25(
|
|
1975
2037
|
"span",
|
|
1976
2038
|
{
|
|
1977
2039
|
style: {
|
|
@@ -1984,62 +2046,34 @@ function MatrixBackground({ width, height, clearRect, clearRects }) {
|
|
|
1984
2046
|
}) }, y)) });
|
|
1985
2047
|
}
|
|
1986
2048
|
|
|
1987
|
-
// ../docs/components/landing/about-modal.tsx
|
|
1988
|
-
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1989
|
-
function AboutModal({ onClose, useKeyboard: useKeyboard3 }) {
|
|
1990
|
-
const theme = useTheme();
|
|
1991
|
-
return /* @__PURE__ */ jsx25(Modal, { title: "About Gridland", useKeyboard: useKeyboard3, onClose, children: /* @__PURE__ */ jsxs18("box", { paddingX: 1, flexDirection: "column", gap: 1, children: [
|
|
1992
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "What is Gridland?" }),
|
|
1993
|
-
/* @__PURE__ */ jsx25("text", { children: "Gridland renders terminal UIs to HTML5 Canvas with React." }),
|
|
1994
|
-
/* @__PURE__ */ jsx25("text", { children: "No xterm.js. No terminal emulator. Just pixels." }),
|
|
1995
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Features" }),
|
|
1996
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
1997
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
1998
|
-
"\u2022",
|
|
1999
|
-
" "
|
|
2000
|
-
] }),
|
|
2001
|
-
"Canvas-rendered TUI components"
|
|
2002
|
-
] }),
|
|
2003
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
2004
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
2005
|
-
"\u2022",
|
|
2006
|
-
" "
|
|
2007
|
-
] }),
|
|
2008
|
-
"React reconciler with JSX"
|
|
2009
|
-
] }),
|
|
2010
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
2011
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
2012
|
-
"\u2022",
|
|
2013
|
-
" "
|
|
2014
|
-
] }),
|
|
2015
|
-
"Yoga flexbox layout engine"
|
|
2016
|
-
] }),
|
|
2017
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
2018
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
2019
|
-
"\u2022",
|
|
2020
|
-
" "
|
|
2021
|
-
] }),
|
|
2022
|
-
"Keyboard, mouse, and clipboard support"
|
|
2023
|
-
] }),
|
|
2024
|
-
/* @__PURE__ */ jsxs18("text", { children: [
|
|
2025
|
-
/* @__PURE__ */ jsxs18("span", { style: textStyle({ dim: true }), children: [
|
|
2026
|
-
"\u2022",
|
|
2027
|
-
" "
|
|
2028
|
-
] }),
|
|
2029
|
-
"Next.js and Vite plugins"
|
|
2030
|
-
] }),
|
|
2031
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ bold: true, fg: theme.accent }), children: "Tech Stack" }),
|
|
2032
|
-
/* @__PURE__ */ jsx25("text", { children: "React + opentui engine + yoga-layout + HTML5 Canvas" }),
|
|
2033
|
-
/* @__PURE__ */ jsx25("text", { style: textStyle({ dim: true }), children: "Press q to close" })
|
|
2034
|
-
] }) });
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
2049
|
// ../docs/components/landing/landing-app.tsx
|
|
2038
2050
|
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2051
|
+
var DEMO_RESPONSES = [
|
|
2052
|
+
"Gridland is a framework for building terminal apps with React. It works in both the browser and terminal!",
|
|
2053
|
+
"You can get started with `bun create gridland` to scaffold a new project.",
|
|
2054
|
+
"OpenTUI provides the layout primitives \u2014 flexbox, borders, text styling \u2014 while React handles the component model.",
|
|
2055
|
+
"Yes! Gridland apps are universal \u2014 the same code renders in a terminal emulator and in the browser.",
|
|
2056
|
+
"Check out the docs for examples of interactive components like inputs, selects, and tables."
|
|
2057
|
+
];
|
|
2039
2058
|
function LandingApp({ useKeyboard: useKeyboard3 }) {
|
|
2040
2059
|
const theme = useTheme();
|
|
2041
2060
|
const { width, height, isNarrow, isTiny, isMobile } = useBreakpoints();
|
|
2042
2061
|
const [showAbout, setShowAbout] = useState10(false);
|
|
2062
|
+
const [messages, setMessages] = useState10([]);
|
|
2063
|
+
const [chatStatus, setChatStatus] = useState10("ready");
|
|
2064
|
+
const responseIdx = useRef8(0);
|
|
2065
|
+
const handleChatSubmit = useCallback3(({ text }) => {
|
|
2066
|
+
const userMsg = { id: `u-${Date.now()}`, role: "user", content: text };
|
|
2067
|
+
setMessages((prev) => [...prev, userMsg]);
|
|
2068
|
+
setChatStatus("streaming");
|
|
2069
|
+
setTimeout(() => {
|
|
2070
|
+
const response = DEMO_RESPONSES[responseIdx.current % DEMO_RESPONSES.length];
|
|
2071
|
+
responseIdx.current += 1;
|
|
2072
|
+
const assistantMsg = { id: `a-${Date.now()}`, role: "assistant", content: response };
|
|
2073
|
+
setMessages((prev) => [...prev, assistantMsg]);
|
|
2074
|
+
setChatStatus("ready");
|
|
2075
|
+
}, 1200);
|
|
2076
|
+
}, []);
|
|
2043
2077
|
useKeyboard3((event) => {
|
|
2044
2078
|
if (event.name === "a" && !showAbout) {
|
|
2045
2079
|
setShowAbout(true);
|
|
@@ -2066,61 +2100,25 @@ function LandingApp({ useKeyboard: useKeyboard3 }) {
|
|
|
2066
2100
|
const installLinksClearRect = { top: installLinksTop, left: 1, width: width - 2, height: installLinksHeight };
|
|
2067
2101
|
return /* @__PURE__ */ jsxs19("box", { width: "100%", height: "100%", position: "relative", children: [
|
|
2068
2102
|
/* @__PURE__ */ jsx26(MatrixBackground, { width, height, clearRect, clearRects: [installLinksClearRect] }),
|
|
2069
|
-
/* @__PURE__ */ jsxs19(
|
|
2070
|
-
"box",
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
borderStyle: "rounded",
|
|
2089
|
-
borderColor: theme.border,
|
|
2090
|
-
paddingX: 1,
|
|
2091
|
-
flexDirection: "column",
|
|
2092
|
-
flexShrink: 0,
|
|
2093
|
-
children: /* @__PURE__ */ jsxs19("text", { children: [
|
|
2094
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
2095
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ bold: true }), children: "bunx " }),
|
|
2096
|
-
/* @__PURE__ */ jsx26("span", { style: textStyle({ fg: theme.accent }), children: "@gridland/demo landing" })
|
|
2097
|
-
] })
|
|
2098
|
-
}
|
|
2099
|
-
),
|
|
2100
|
-
/* @__PURE__ */ jsx26(InstallBox, {}),
|
|
2101
|
-
/* @__PURE__ */ jsx26(LinksBox, {})
|
|
2102
|
-
] }),
|
|
2103
|
-
/* @__PURE__ */ jsx26(
|
|
2104
|
-
"box",
|
|
2105
|
-
{
|
|
2106
|
-
flexGrow: 1,
|
|
2107
|
-
border: true,
|
|
2108
|
-
borderStyle: "rounded",
|
|
2109
|
-
borderColor: theme.border
|
|
2110
|
-
}
|
|
2111
|
-
)
|
|
2112
|
-
] }),
|
|
2113
|
-
/* @__PURE__ */ jsx26(
|
|
2114
|
-
StatusBar,
|
|
2115
|
-
{
|
|
2116
|
-
items: [
|
|
2117
|
-
{ key: "a", label: "about" }
|
|
2118
|
-
]
|
|
2119
|
-
}
|
|
2120
|
-
)
|
|
2121
|
-
]
|
|
2122
|
-
}
|
|
2123
|
-
)
|
|
2103
|
+
/* @__PURE__ */ jsxs19("box", { position: "absolute", top: 0, left: 0, width, height, zIndex: 1, flexDirection: "column", shouldFill: false, children: [
|
|
2104
|
+
/* @__PURE__ */ jsxs19("box", { flexGrow: 1, flexDirection: "column", paddingTop: 3, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, gap: isMobile ? 0 : 1, shouldFill: false, children: [
|
|
2105
|
+
/* @__PURE__ */ jsx26("box", { flexShrink: 0, shouldFill: false, children: /* @__PURE__ */ jsx26(Logo, { compact: isTiny, narrow: isNarrow, mobile: isMobile }) }),
|
|
2106
|
+
/* @__PURE__ */ jsxs19("box", { flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: isMobile ? 0 : 1, flexShrink: 0, shouldFill: false, children: [
|
|
2107
|
+
/* @__PURE__ */ jsx26("box", { border: true, borderStyle: "rounded", borderColor: theme.border, paddingX: 1, flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsxs19("text", { children: [
|
|
2108
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ dim: true }), children: "$ " }),
|
|
2109
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ bold: true }), children: "bunx " }),
|
|
2110
|
+
/* @__PURE__ */ jsx26("span", { style: textStyle({ fg: theme.accent }), children: "@gridland/demo landing" })
|
|
2111
|
+
] }) }),
|
|
2112
|
+
/* @__PURE__ */ jsx26(InstallBox, {}),
|
|
2113
|
+
/* @__PURE__ */ jsx26(LinksBox, {})
|
|
2114
|
+
] }),
|
|
2115
|
+
/* @__PURE__ */ jsxs19("box", { flexGrow: 1, border: true, borderStyle: "rounded", borderColor: theme.border, flexDirection: "column", overflow: "hidden", children: [
|
|
2116
|
+
/* @__PURE__ */ jsx26("box", { flexGrow: 1, flexDirection: "column", paddingX: 1, overflow: "hidden", children: messages.map((msg) => /* @__PURE__ */ jsx26(Message, { role: msg.role, children: /* @__PURE__ */ jsx26(Message.Content, { children: /* @__PURE__ */ jsx26(Message.Text, { children: msg.content }) }) }, msg.id)) }),
|
|
2117
|
+
/* @__PURE__ */ jsx26("box", { flexShrink: 0, paddingX: 1, paddingBottom: 0, children: /* @__PURE__ */ jsx26(PromptInput, { splaceholder: "Ask about Gridland...", status: chatStatus, onSubmit: handleChatSubmit, useKeyboard: useKeyboard3 }) })
|
|
2118
|
+
] })
|
|
2119
|
+
] }),
|
|
2120
|
+
/* @__PURE__ */ jsx26(StatusBar, { items: [{ key: "a", label: "about" }] })
|
|
2121
|
+
] })
|
|
2124
2122
|
] });
|
|
2125
2123
|
}
|
|
2126
2124
|
|
|
@@ -2485,7 +2483,7 @@ function TimelineApp() {
|
|
|
2485
2483
|
const [expanded, setExpanded] = useState11(true);
|
|
2486
2484
|
const [phase, setPhase] = useState11("running");
|
|
2487
2485
|
const [stepIndex, setStepIndex] = useState11(0);
|
|
2488
|
-
const timerRef =
|
|
2486
|
+
const timerRef = useRef9(null);
|
|
2489
2487
|
useKeyboard((event) => {
|
|
2490
2488
|
if (event.name === "E" && event.ctrl && event.shift) setExpanded((v) => !v);
|
|
2491
2489
|
if (event.name === "r") timelineRestart();
|
|
@@ -2552,7 +2550,7 @@ function MessageApp() {
|
|
|
2552
2550
|
const [phase, setPhase] = useState11("idle");
|
|
2553
2551
|
const [stepIndex, setStepIndex] = useState11(0);
|
|
2554
2552
|
const [streamedText, setStreamedText] = useState11("");
|
|
2555
|
-
const timerRef =
|
|
2553
|
+
const timerRef = useRef9(null);
|
|
2556
2554
|
useKeyboard((event) => {
|
|
2557
2555
|
if (event.name === "E" && event.ctrl && event.shift) setExpanded((v) => !v);
|
|
2558
2556
|
if (event.name === "r") bubbleRestart();
|
|
@@ -2644,8 +2642,8 @@ function ChatApp() {
|
|
|
2644
2642
|
const [isLoading, setIsLoading] = useState11(false);
|
|
2645
2643
|
const [streamingText, setStreamingText] = useState11("");
|
|
2646
2644
|
const [activeToolCalls, setActiveToolCalls] = useState11([]);
|
|
2647
|
-
const intervalRef =
|
|
2648
|
-
const handleSend =
|
|
2645
|
+
const intervalRef = useRef9(null);
|
|
2646
|
+
const handleSend = useCallback4((text) => {
|
|
2649
2647
|
const userMsg = { id: String(chatNextId++), role: "user", content: text };
|
|
2650
2648
|
setMessages((prev) => [...prev, userMsg]);
|
|
2651
2649
|
setIsLoading(true);
|
|
@@ -2676,7 +2674,7 @@ function ChatApp() {
|
|
|
2676
2674
|
}, 50);
|
|
2677
2675
|
}, 1400);
|
|
2678
2676
|
}, []);
|
|
2679
|
-
const handleCancel =
|
|
2677
|
+
const handleCancel = useCallback4(() => {
|
|
2680
2678
|
if (intervalRef.current) clearInterval(intervalRef.current);
|
|
2681
2679
|
setIsLoading(false);
|
|
2682
2680
|
setStreamingText("");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridland/demo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Run gridland component demos from anywhere",
|
|
6
6
|
"exports": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test": "bun test"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"@gridland/core": "^0.2.21",
|
|
23
24
|
"@opentui/core": "^0.1.86",
|
|
24
25
|
"@opentui/react": "^0.1.86",
|
|
25
26
|
"figlet": "^1.10.0",
|