@n3rd-ai/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ import localFont from 'next/font/local'
2
+
3
+ export const jetbrainsMono = localFont({
4
+ src: [
5
+ {
6
+ path: '../fonts/JetBrainsMono-Regular.woff2',
7
+ weight: '400',
8
+ style: 'normal',
9
+ },
10
+ {
11
+ path: '../fonts/JetBrainsMono-Bold.woff2',
12
+ weight: '700',
13
+ style: 'normal',
14
+ },
15
+ ],
16
+ variable: '--n3rd-font',
17
+ display: 'swap',
18
+ fallback: ['Fira Code', 'Cascadia Code', 'SF Mono', 'Consolas', 'Courier New', 'monospace'],
19
+ })
20
+
21
+ export const N3rdFonts = jetbrainsMono
@@ -0,0 +1,23 @@
1
+ @import '../tokens.css';
2
+ @import '../reset.css';
3
+
4
+ :root {
5
+ --n3rd-accent-violet: #22c55e;
6
+ --n3rd-accent-purple: #22c55e;
7
+ --n3rd-accent-lavender: #4ade80;
8
+ --n3rd-accent-pink: #ef4444;
9
+ --n3rd-accent-rose: #f87171;
10
+ --n3rd-accent-cyan: #22c55e;
11
+ --n3rd-accent-aqua: #4ade80;
12
+
13
+ --n3rd-accent-primary: #22c55e;
14
+ --n3rd-accent-success: #4ade80;
15
+ --n3rd-accent-warning: #eab308;
16
+ --n3rd-accent-danger: #ef4444;
17
+ --n3rd-accent-info: #22c55e;
18
+
19
+ --n3rd-border-focus: #22c55e;
20
+
21
+ --n3rd-gradient: linear-gradient(90deg, #16a34a, #22c55e, #4ade80);
22
+ --n3rd-gradient-full: linear-gradient(90deg, #16a34a, #22c55e, #4ade80);
23
+ }
@@ -0,0 +1,21 @@
1
+ @import '../tokens.css';
2
+ @import '../reset.css';
3
+
4
+ :root {
5
+ --n3rd-bg-primary: #fafafa;
6
+ --n3rd-bg-secondary: #f0f0f0;
7
+ --n3rd-bg-tertiary: #e5e5e5;
8
+
9
+ --n3rd-text-primary: #1a1a1a;
10
+ --n3rd-text-secondary: #666666;
11
+ --n3rd-text-tertiary: #999999;
12
+
13
+ --n3rd-border-default: #cccccc;
14
+ --n3rd-border-focus: #7c3aed;
15
+ --n3rd-border-muted: #dddddd;
16
+ }
17
+
18
+ ::selection {
19
+ background: var(--n3rd-accent-purple);
20
+ color: #ffffff;
21
+ }
@@ -0,0 +1,23 @@
1
+ @import '../tokens.css';
2
+ @import '../reset.css';
3
+
4
+ :root {
5
+ --n3rd-accent-violet: #d97706;
6
+ --n3rd-accent-purple: #f59e0b;
7
+ --n3rd-accent-lavender: #fbbf24;
8
+ --n3rd-accent-pink: #ef4444;
9
+ --n3rd-accent-rose: #f87171;
10
+ --n3rd-accent-cyan: #f59e0b;
11
+ --n3rd-accent-aqua: #fbbf24;
12
+
13
+ --n3rd-accent-primary: #f59e0b;
14
+ --n3rd-accent-success: #fbbf24;
15
+ --n3rd-accent-warning: #f97316;
16
+ --n3rd-accent-danger: #ef4444;
17
+ --n3rd-accent-info: #f59e0b;
18
+
19
+ --n3rd-border-focus: #f59e0b;
20
+
21
+ --n3rd-gradient: linear-gradient(90deg, #d97706, #f59e0b, #fbbf24);
22
+ --n3rd-gradient-full: linear-gradient(90deg, #d97706, #f59e0b, #fbbf24);
23
+ }
@@ -0,0 +1,5 @@
1
+ @import '../tokens.css';
2
+ @import '../reset.css';
3
+
4
+ /* Unicorn theme — default. Violet -> pink -> cyan on black. */
5
+ /* All values are inherited from tokens.css — no overrides needed. */
@@ -0,0 +1,86 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ margin: 0;
6
+ padding: 0;
7
+ }
8
+
9
+ html {
10
+ font-size: 16px;
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ text-rendering: optimizeLegibility;
14
+ }
15
+
16
+ body {
17
+ font-family: var(--n3rd-font);
18
+ font-size: var(--n3rd-text-base);
19
+ line-height: var(--n3rd-line-height);
20
+ color: var(--n3rd-text-primary);
21
+ background-color: var(--n3rd-bg-primary);
22
+ min-height: 100vh;
23
+ }
24
+
25
+ h1,
26
+ h2,
27
+ h3,
28
+ h4,
29
+ h5,
30
+ h6 {
31
+ font-family: var(--n3rd-font);
32
+ font-weight: 700;
33
+ }
34
+
35
+ a {
36
+ color: var(--n3rd-accent-cyan);
37
+ text-decoration: none;
38
+ }
39
+
40
+ a:hover {
41
+ text-decoration: underline;
42
+ }
43
+
44
+ button {
45
+ font-family: var(--n3rd-font);
46
+ cursor: pointer;
47
+ border: none;
48
+ background: none;
49
+ color: inherit;
50
+ }
51
+
52
+ input,
53
+ textarea,
54
+ select {
55
+ font-family: var(--n3rd-font);
56
+ font-size: var(--n3rd-text-base);
57
+ color: var(--n3rd-text-primary);
58
+ background: transparent;
59
+ border: none;
60
+ outline: none;
61
+ }
62
+
63
+ code,
64
+ pre {
65
+ font-family: var(--n3rd-font);
66
+ }
67
+
68
+ ::selection {
69
+ background: var(--n3rd-accent-purple);
70
+ color: var(--n3rd-bg-primary);
71
+ }
72
+
73
+ :focus-visible {
74
+ outline: 1px solid var(--n3rd-border-focus);
75
+ outline-offset: 2px;
76
+ }
77
+
78
+ @media (prefers-reduced-motion: reduce) {
79
+ *,
80
+ *::before,
81
+ *::after {
82
+ animation-duration: 0.01ms !important;
83
+ animation-iteration-count: 1 !important;
84
+ transition-duration: 0.01ms !important;
85
+ }
86
+ }
@@ -0,0 +1,61 @@
1
+ :root {
2
+ /* typography */
3
+ --n3rd-font:
4
+ 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'SF Mono', 'Consolas', 'Courier New', monospace;
5
+ --n3rd-text-xs: 0.6875rem;
6
+ --n3rd-text-sm: 0.8125rem;
7
+ --n3rd-text-base: 0.875rem;
8
+ --n3rd-text-lg: 1rem;
9
+ --n3rd-text-xl: 1.25rem;
10
+ --n3rd-text-2xl: 1.5rem;
11
+ --n3rd-line-height: 1.6;
12
+
13
+ /* spacing */
14
+ --n3rd-space-1: 0.25rem;
15
+ --n3rd-space-2: 0.5rem;
16
+ --n3rd-space-3: 0.75rem;
17
+ --n3rd-space-4: 1rem;
18
+ --n3rd-space-6: 1.5rem;
19
+ --n3rd-space-8: 2rem;
20
+ --n3rd-space-12: 3rem;
21
+
22
+ /* surfaces */
23
+ --n3rd-bg-primary: #0a0a0a;
24
+ --n3rd-bg-secondary: #111111;
25
+ --n3rd-bg-tertiary: #1a1a1a;
26
+
27
+ /* text */
28
+ --n3rd-text-primary: #e0e0e0;
29
+ --n3rd-text-secondary: #888888;
30
+ --n3rd-text-tertiary: #555555;
31
+
32
+ /* borders */
33
+ --n3rd-border-default: #333333;
34
+ --n3rd-border-focus: #a855f7;
35
+ --n3rd-border-muted: #222222;
36
+
37
+ /* unicorn accent spectrum */
38
+ --n3rd-accent-violet: #7c3aed;
39
+ --n3rd-accent-purple: #a855f7;
40
+ --n3rd-accent-lavender: #c084fc;
41
+ --n3rd-accent-pink: #ec4899;
42
+ --n3rd-accent-rose: #f472b6;
43
+ --n3rd-accent-cyan: #06b6d4;
44
+ --n3rd-accent-aqua: #22d3ee;
45
+
46
+ /* semantic */
47
+ --n3rd-accent-primary: #a855f7;
48
+ --n3rd-accent-success: #22d3ee;
49
+ --n3rd-accent-warning: #f472b6;
50
+ --n3rd-accent-danger: #ec4899;
51
+ --n3rd-accent-info: #06b6d4;
52
+
53
+ /* gradients */
54
+ --n3rd-gradient: linear-gradient(90deg, #7c3aed, #a855f7, #ec4899);
55
+ --n3rd-gradient-full: linear-gradient(90deg, #7c3aed, #ec4899, #06b6d4);
56
+
57
+ /* animation durations */
58
+ --n3rd-cursor-blink: 530ms;
59
+ --n3rd-typewriter-speed: 50ms;
60
+ --n3rd-fade-duration: 200ms;
61
+ }
@@ -0,0 +1,15 @@
1
+ import { B as BorderStyle } from '../ascii-border-DpKIQMLP.js';
2
+
3
+ interface BoxOptions {
4
+ border?: BorderStyle;
5
+ title?: string;
6
+ padding?: number;
7
+ }
8
+ declare function drawBox(content: string, options?: BoxOptions): string;
9
+
10
+ interface FormatTableOptions {
11
+ border?: BorderStyle;
12
+ }
13
+ declare function formatTable(columns: string[], rows: string[][], options?: FormatTableOptions): string;
14
+
15
+ export { type BoxOptions, type FormatTableOptions, drawBox, formatTable };
@@ -0,0 +1,59 @@
1
+ import { getBorderChars } from '../chunk-CBVIEAN7.js';
2
+
3
+ // src/utils/box.ts
4
+ function drawBox(content, options = {}) {
5
+ const { border = "single", title, padding = 1 } = options;
6
+ const chars = getBorderChars(border);
7
+ if (!chars) return content;
8
+ const lines = content.split("\n");
9
+ const maxLen = Math.max(...lines.map((l) => l.length), title ? title.length + 2 : 0);
10
+ const innerWidth = maxLen + padding * 2;
11
+ const pad = " ".repeat(padding);
12
+ const emptyLine = chars.vertical + " ".repeat(innerWidth) + chars.vertical;
13
+ let top;
14
+ if (title) {
15
+ const titleStr = ` ${title} `;
16
+ const remaining = innerWidth - titleStr.length - 1;
17
+ top = chars.topLeft + chars.horizontal + titleStr + chars.horizontal.repeat(remaining) + chars.topRight;
18
+ } else {
19
+ top = chars.topLeft + chars.horizontal.repeat(innerWidth) + chars.topRight;
20
+ }
21
+ const bottom = chars.bottomLeft + chars.horizontal.repeat(innerWidth) + chars.bottomRight;
22
+ const body = lines.map((line) => {
23
+ const padded = pad + line + " ".repeat(maxLen - line.length) + pad;
24
+ return chars.vertical + padded + chars.vertical;
25
+ });
26
+ const paddingLines = Array(padding).fill(emptyLine);
27
+ return [top, ...paddingLines, ...body, ...paddingLines, bottom].join("\n");
28
+ }
29
+
30
+ // src/utils/table.ts
31
+ function formatTable(columns, rows, options = {}) {
32
+ const { border = "single" } = options;
33
+ const chars = getBorderChars(border);
34
+ if (!chars) {
35
+ return [columns.join(" "), ...rows.map((r) => r.join(" "))].join("\n");
36
+ }
37
+ const colWidths = columns.map((col, i) => {
38
+ let max = col.length;
39
+ for (const row of rows) {
40
+ if (row[i]) max = Math.max(max, row[i].length);
41
+ }
42
+ return max + 2;
43
+ });
44
+ const pad = (text, width) => ` ${text}${" ".repeat(Math.max(0, width - text.length - 1))}`;
45
+ const line = (left, mid, right, fill) => left + colWidths.map((w) => fill.repeat(w)).join(mid) + right;
46
+ const header = chars.vertical + columns.map((col, i) => pad(col, colWidths[i])).join(chars.vertical) + chars.vertical;
47
+ const dataRows = rows.map(
48
+ (row) => chars.vertical + row.map((cell, i) => pad(cell, colWidths[i])).join(chars.vertical) + chars.vertical
49
+ );
50
+ return [
51
+ line(chars.topLeft, chars.teeTop, chars.topRight, chars.horizontal),
52
+ header,
53
+ line(chars.teeLeft, chars.cross, chars.teeRight, chars.horizontal),
54
+ ...dataRows,
55
+ line(chars.bottomLeft, chars.teeBottom, chars.bottomRight, chars.horizontal)
56
+ ].join("\n");
57
+ }
58
+
59
+ export { drawBox, formatTable };
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@n3rd-ai/ui",
3
+ "version": "0.1.0",
4
+ "description": "Terminal-first UI framework for Next.js. ASCII everything. Zero images. Pure text.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./hooks": {
15
+ "types": "./dist/hooks/index.d.ts",
16
+ "import": "./dist/hooks/index.js"
17
+ },
18
+ "./utils": {
19
+ "types": "./dist/utils/index.d.ts",
20
+ "import": "./dist/utils/index.js"
21
+ },
22
+ "./theme/unicorn.css": "./dist/theme/presets/unicorn.css",
23
+ "./theme/classic.css": "./dist/theme/presets/classic.css",
24
+ "./theme/retro.css": "./dist/theme/presets/retro.css",
25
+ "./theme/paper.css": "./dist/theme/presets/paper.css",
26
+ "./theme/tokens.css": "./dist/theme/tokens.css",
27
+ "./theme/reset.css": "./dist/theme/reset.css"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE",
33
+ "CHANGELOG.md"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "dev": "tsup --watch",
38
+ "lint": "eslint src/",
39
+ "typecheck": "tsc --noEmit",
40
+ "format": "prettier --write .",
41
+ "format:check": "prettier --check .",
42
+ "test": "vitest run",
43
+ "test:ci": "vitest run --coverage",
44
+ "test:watch": "vitest",
45
+ "prepare": "husky",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "keywords": [
49
+ "terminal",
50
+ "ascii",
51
+ "ui",
52
+ "nextjs",
53
+ "react",
54
+ "components",
55
+ "monospace",
56
+ "tui",
57
+ "mcp"
58
+ ],
59
+ "author": "Superstellar LLC",
60
+ "license": "MIT",
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "https://github.com/SuperstellarLLC/n3rd-ai-ui"
64
+ },
65
+ "bugs": {
66
+ "url": "https://github.com/SuperstellarLLC/n3rd-ai-ui/issues"
67
+ },
68
+ "homepage": "https://n3rd.ai",
69
+ "publishConfig": {
70
+ "access": "public"
71
+ },
72
+ "engines": {
73
+ "node": ">=20"
74
+ },
75
+ "sideEffects": [
76
+ "**/*.css"
77
+ ],
78
+ "peerDependencies": {
79
+ "next": ">=14.0.0",
80
+ "react": ">=18.0.0",
81
+ "react-dom": ">=18.0.0"
82
+ },
83
+ "devDependencies": {
84
+ "@commitlint/cli": "^19.0.0",
85
+ "@commitlint/config-conventional": "^19.0.0",
86
+ "@eslint/js": "^9.0.0",
87
+ "@testing-library/jest-dom": "^6.4.0",
88
+ "@testing-library/react": "^15.0.0",
89
+ "@types/react": "^18.2.0",
90
+ "@types/react-dom": "^18.2.0",
91
+ "@vitest/coverage-v8": "^1.6.0",
92
+ "eslint": "^9.0.0",
93
+ "eslint-plugin-react": "^7.34.0",
94
+ "eslint-plugin-react-hooks": "^5.0.0",
95
+ "husky": "^9.0.0",
96
+ "jsdom": "^24.0.0",
97
+ "lint-staged": "^15.2.0",
98
+ "next": "^15.0.0",
99
+ "prettier": "^3.2.0",
100
+ "react": "^18.2.0",
101
+ "react-dom": "^18.2.0",
102
+ "size-limit": "^11.0.0",
103
+ "@size-limit/preset-small-lib": "^11.0.0",
104
+ "tsup": "^8.0.0",
105
+ "typescript": "^5.4.0",
106
+ "typescript-eslint": "^8.0.0",
107
+ "vitest": "^1.6.0"
108
+ }
109
+ }