@ai-matrx/canvas 0.0.0-bootstrap.0 → 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,451 @@
1
+ @import "@ai-matrx/tap-target/styles.css";
2
+
3
+ /*
4
+ * @ai-matrx/canvas — structural CSS (C26).
5
+ *
6
+ * Every colour comes from a --mxc-* token. Hosts set the token VALUES (see
7
+ * tokens.css for the shipped defaults); this sheet never hardcodes a colour.
8
+ */
9
+
10
+ .mxc-column {
11
+ position: relative;
12
+ display: flex;
13
+ flex-direction: column;
14
+ width: var(--mxc-width, 640px);
15
+ height: 100%;
16
+ min-height: 0;
17
+ flex: none;
18
+ background: var(--mxc-bg);
19
+ color: var(--mxc-fg);
20
+ border-left: 1px solid var(--mxc-border);
21
+ /* The column owns the top edge of the window: no header sits above it. */
22
+ padding-top: var(--mxc-safe-top, 0px);
23
+ isolation: isolate;
24
+ }
25
+
26
+ .mxc-column[data-fullscreen] {
27
+ width: 100%;
28
+ border-left: 0;
29
+ }
30
+
31
+ .mxc-width-handle {
32
+ position: absolute;
33
+ top: 0;
34
+ bottom: 0;
35
+ left: -3px;
36
+ width: 6px;
37
+ cursor: col-resize;
38
+ z-index: 2;
39
+ touch-action: none;
40
+ }
41
+
42
+ .mxc-width-handle:hover,
43
+ .mxc-width-handle:focus-visible {
44
+ background: var(--mxc-accent-soft);
45
+ outline: none;
46
+ }
47
+
48
+ :root[data-mxc-resizing],
49
+ :root[data-mxc-resizing] * {
50
+ cursor: col-resize !important;
51
+ user-select: none !important;
52
+ }
53
+
54
+ .mxc-layout {
55
+ flex: 1 1 auto;
56
+ min-height: 0;
57
+ display: flex;
58
+ }
59
+
60
+ .mxc-split {
61
+ flex: 1 1 auto;
62
+ min-width: 0;
63
+ min-height: 0;
64
+ display: flex;
65
+ }
66
+
67
+ .mxc-split[data-orientation="vertical"] {
68
+ flex-direction: column;
69
+ }
70
+
71
+ .mxc-split-child {
72
+ min-width: 0;
73
+ min-height: 0;
74
+ display: flex;
75
+ }
76
+
77
+ .mxc-split-handle {
78
+ flex: none;
79
+ background: var(--mxc-border);
80
+ touch-action: none;
81
+ position: relative;
82
+ }
83
+
84
+ .mxc-split[data-orientation="horizontal"] > .mxc-split-handle {
85
+ width: 1px;
86
+ cursor: col-resize;
87
+ }
88
+
89
+ .mxc-split[data-orientation="vertical"] > .mxc-split-handle {
90
+ height: 1px;
91
+ cursor: row-resize;
92
+ }
93
+
94
+ /* A wide invisible grab area around the 1px line. */
95
+ .mxc-split-handle::after {
96
+ content: "";
97
+ position: absolute;
98
+ inset: -3px;
99
+ }
100
+
101
+ .mxc-split-handle:hover {
102
+ background: var(--mxc-accent);
103
+ }
104
+
105
+ .mxc-pane {
106
+ flex: 1 1 auto;
107
+ min-width: 0;
108
+ min-height: 0;
109
+ display: flex;
110
+ flex-direction: column;
111
+ background: var(--mxc-bg);
112
+ }
113
+
114
+ .mxc-pane[data-drop] {
115
+ box-shadow: inset 0 0 0 2px var(--mxc-accent);
116
+ }
117
+
118
+ .mxc-pane-header {
119
+ flex: none;
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 0.25rem;
123
+ height: var(--mxc-header-h, 2.75rem);
124
+ padding: 0 0.25rem 0 0.375rem;
125
+ border-bottom: 1px solid var(--mxc-border);
126
+ background: var(--mxc-header-bg);
127
+ }
128
+
129
+ .mxc-tabs {
130
+ flex: 1 1 auto;
131
+ min-width: 0;
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 0.125rem;
135
+ overflow-x: auto;
136
+ scrollbar-width: none;
137
+ }
138
+
139
+ .mxc-tabs::-webkit-scrollbar {
140
+ display: none;
141
+ }
142
+
143
+ .mxc-tab {
144
+ flex: none;
145
+ display: inline-flex;
146
+ align-items: center;
147
+ gap: 0.375rem;
148
+ max-width: 13rem;
149
+ height: 1.875rem;
150
+ padding: 0 0.25rem 0 0.5rem;
151
+ border-radius: 0.5rem;
152
+ font-size: 0.8125rem;
153
+ line-height: 1;
154
+ color: var(--mxc-muted);
155
+ cursor: pointer;
156
+ user-select: none;
157
+ }
158
+
159
+ .mxc-tab:hover {
160
+ background: var(--mxc-hover);
161
+ color: var(--mxc-fg);
162
+ }
163
+
164
+ .mxc-tab[data-active] {
165
+ background: var(--mxc-tab-active-bg);
166
+ color: var(--mxc-fg);
167
+ }
168
+
169
+ .mxc-pane:not([data-focused]) .mxc-tab[data-active] {
170
+ background: var(--mxc-hover);
171
+ }
172
+
173
+ .mxc-tab:focus-visible {
174
+ outline: 2px solid var(--mxc-accent);
175
+ outline-offset: -2px;
176
+ }
177
+
178
+ .mxc-tab-icon {
179
+ flex: none;
180
+ width: 0.875rem;
181
+ height: 0.875rem;
182
+ }
183
+
184
+ .mxc-tab-title {
185
+ min-width: 0;
186
+ overflow: hidden;
187
+ text-overflow: ellipsis;
188
+ white-space: nowrap;
189
+ }
190
+
191
+ .mxc-tab-close {
192
+ flex: none;
193
+ display: inline-flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ width: 1.25rem;
197
+ height: 1.25rem;
198
+ border: 0;
199
+ border-radius: 0.375rem;
200
+ background: transparent;
201
+ color: inherit;
202
+ opacity: 0;
203
+ cursor: pointer;
204
+ }
205
+
206
+ .mxc-tab:hover .mxc-tab-close,
207
+ .mxc-tab[data-active] .mxc-tab-close,
208
+ .mxc-tab-close:focus-visible {
209
+ opacity: 0.7;
210
+ }
211
+
212
+ .mxc-tab-close:hover {
213
+ opacity: 1;
214
+ background: var(--mxc-hover);
215
+ }
216
+
217
+ .mxc-pane-actions {
218
+ flex: none;
219
+ display: flex;
220
+ align-items: center;
221
+ }
222
+
223
+ .mxc-pane-body {
224
+ position: relative;
225
+ flex: 1 1 auto;
226
+ min-height: 0;
227
+ display: flex;
228
+ flex-direction: column;
229
+ }
230
+
231
+ .mxc-item {
232
+ flex: 1 1 auto;
233
+ min-height: 0;
234
+ display: flex;
235
+ flex-direction: column;
236
+ overflow: auto;
237
+ }
238
+
239
+ .mxc-item[hidden] {
240
+ display: none;
241
+ }
242
+
243
+ .mxc-loading {
244
+ flex: 1 1 auto;
245
+ background: linear-gradient(90deg, transparent, var(--mxc-hover), transparent);
246
+ background-size: 200% 100%;
247
+ animation: mxc-shimmer 1.4s ease-in-out infinite;
248
+ }
249
+
250
+ @keyframes mxc-shimmer {
251
+ from { background-position: 200% 0; }
252
+ to { background-position: -200% 0; }
253
+ }
254
+
255
+ .mxc-problem,
256
+ .mxc-empty {
257
+ margin: auto;
258
+ display: flex;
259
+ flex-direction: column;
260
+ align-items: center;
261
+ gap: 0.5rem;
262
+ padding: 1.5rem;
263
+ font-size: 0.875rem;
264
+ color: var(--mxc-muted);
265
+ text-align: center;
266
+ }
267
+
268
+ .mxc-problem p {
269
+ margin: 0;
270
+ }
271
+
272
+ .mxc-problem-actions {
273
+ display: flex;
274
+ gap: 0.5rem;
275
+ }
276
+
277
+ .mxc-text-button {
278
+ border: 1px solid var(--mxc-border);
279
+ border-radius: 0.5rem;
280
+ background: transparent;
281
+ color: var(--mxc-fg);
282
+ padding: 0.375rem 0.75rem;
283
+ font-size: 0.8125rem;
284
+ cursor: pointer;
285
+ }
286
+
287
+ .mxc-text-button:hover {
288
+ background: var(--mxc-hover);
289
+ }
290
+
291
+ .mxc-launcher {
292
+ margin: auto;
293
+ display: grid;
294
+ grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
295
+ gap: 0.5rem;
296
+ width: min(32rem, 100%);
297
+ padding: 1.5rem;
298
+ }
299
+
300
+ .mxc-launcher-item {
301
+ display: flex;
302
+ align-items: center;
303
+ gap: 0.5rem;
304
+ padding: 0.625rem 0.75rem;
305
+ border: 1px solid var(--mxc-border);
306
+ border-radius: 0.625rem;
307
+ background: transparent;
308
+ color: var(--mxc-fg);
309
+ font-size: 0.8125rem;
310
+ text-align: left;
311
+ cursor: pointer;
312
+ }
313
+
314
+ .mxc-launcher-item:hover {
315
+ background: var(--mxc-hover);
316
+ }
317
+
318
+ .mxc-launcher-icon {
319
+ flex: none;
320
+ width: 1rem;
321
+ height: 1rem;
322
+ color: var(--mxc-muted);
323
+ }
324
+
325
+ .mxc-menu {
326
+ z-index: var(--mxc-menu-z, 10000);
327
+ min-width: 11rem;
328
+ padding: 0.25rem;
329
+ border: 1px solid var(--mxc-border);
330
+ border-radius: 0.625rem;
331
+ background: var(--mxc-bg);
332
+ color: var(--mxc-fg);
333
+ box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.35);
334
+ font-size: 0.8125rem;
335
+ }
336
+
337
+ .mxc-menu-item {
338
+ display: flex;
339
+ align-items: center;
340
+ gap: 0.5rem;
341
+ padding: 0.4375rem 0.5rem;
342
+ border-radius: 0.375rem;
343
+ outline: none;
344
+ cursor: pointer;
345
+ user-select: none;
346
+ }
347
+
348
+ .mxc-menu-item[data-highlighted] {
349
+ background: var(--mxc-hover);
350
+ }
351
+
352
+ .mxc-menu-item[data-destructive] {
353
+ color: var(--mxc-danger);
354
+ }
355
+
356
+ .mxc-menu-item svg {
357
+ flex: none;
358
+ width: 1rem;
359
+ height: 1rem;
360
+ color: var(--mxc-muted);
361
+ }
362
+
363
+ .mxc-menu-separator {
364
+ height: 1px;
365
+ margin: 0.25rem 0;
366
+ background: var(--mxc-border);
367
+ }
368
+
369
+ .mxc-toggle {
370
+ position: relative;
371
+ display: inline-flex;
372
+ }
373
+
374
+ .mxc-toggle[data-open] {
375
+ color: var(--mxc-accent);
376
+ }
377
+
378
+ .mxc-toggle-badge {
379
+ position: absolute;
380
+ top: 0.125rem;
381
+ right: 0.125rem;
382
+ min-width: 1rem;
383
+ height: 1rem;
384
+ padding: 0 0.25rem;
385
+ border-radius: 999px;
386
+ background: var(--mxc-accent);
387
+ color: var(--mxc-accent-fg);
388
+ font-size: 0.625rem;
389
+ line-height: 1rem;
390
+ text-align: center;
391
+ pointer-events: none;
392
+ }
393
+
394
+ /* CanvasFrame — for hosts without their own shell. */
395
+ .mxc-frame {
396
+ display: flex;
397
+ width: 100%;
398
+ height: 100%;
399
+ min-height: 0;
400
+ }
401
+
402
+ .mxc-frame-main {
403
+ flex: 1 1 auto;
404
+ min-width: 0;
405
+ min-height: 0;
406
+ }
407
+
408
+ .mxc-frame-main[hidden] {
409
+ display: none;
410
+ }
411
+
412
+ /* Phone-only controls (hide the canvas without closing a single tab). */
413
+ .mxc-phone-only {
414
+ display: none !important;
415
+ }
416
+
417
+ /* Phones: the canvas is a full-screen layer over the app. */
418
+ @media (max-width: 767px) {
419
+ .mxc-phone-only {
420
+ display: inline-flex !important;
421
+ }
422
+
423
+ /* A phone canvas is already full screen. */
424
+ .mxc-desktop-only {
425
+ display: none !important;
426
+ }
427
+
428
+ .mxc-column {
429
+ position: fixed;
430
+ inset: 0;
431
+ z-index: var(--mxc-mobile-z, 60);
432
+ width: 100%;
433
+ border-left: 0;
434
+ padding-top: env(safe-area-inset-top, 0px);
435
+ padding-bottom: env(safe-area-inset-bottom, 0px);
436
+ }
437
+
438
+ .mxc-width-handle {
439
+ display: none;
440
+ }
441
+
442
+ .mxc-split[data-orientation="horizontal"] {
443
+ flex-direction: column;
444
+ }
445
+
446
+ .mxc-split[data-orientation="horizontal"] > .mxc-split-handle {
447
+ width: auto;
448
+ height: 1px;
449
+ cursor: row-resize;
450
+ }
451
+ }
@@ -0,0 +1,49 @@
1
+ /*
2
+ * @ai-matrx/canvas — DEFAULT token values (C26). Import this only in a host
3
+ * that has no theme of its own; a themed host maps the --mxc-* tokens to its
4
+ * own design tokens instead.
5
+ */
6
+
7
+ :root {
8
+ --mxc-bg: #ffffff;
9
+ --mxc-header-bg: #fafafa;
10
+ --mxc-fg: #18181b;
11
+ --mxc-muted: #71717a;
12
+ --mxc-border: #e4e4e7;
13
+ --mxc-hover: rgba(0, 0, 0, 0.05);
14
+ --mxc-tab-active-bg: rgba(0, 0, 0, 0.08);
15
+ --mxc-accent: #2563eb;
16
+ --mxc-accent-soft: rgba(37, 99, 235, 0.25);
17
+ --mxc-accent-fg: #ffffff;
18
+ --mxc-danger: #dc2626;
19
+ }
20
+
21
+ @media (prefers-color-scheme: dark) {
22
+ :root:not(.light) {
23
+ --mxc-bg: #1c1c1f;
24
+ --mxc-header-bg: #18181b;
25
+ --mxc-fg: #f4f4f5;
26
+ --mxc-muted: #a1a1aa;
27
+ --mxc-border: #3f3f46;
28
+ --mxc-hover: rgba(255, 255, 255, 0.06);
29
+ --mxc-tab-active-bg: rgba(255, 255, 255, 0.1);
30
+ --mxc-accent: #60a5fa;
31
+ --mxc-accent-soft: rgba(96, 165, 250, 0.3);
32
+ --mxc-accent-fg: #0b1220;
33
+ --mxc-danger: #f87171;
34
+ }
35
+ }
36
+
37
+ .dark {
38
+ --mxc-bg: #1c1c1f;
39
+ --mxc-header-bg: #18181b;
40
+ --mxc-fg: #f4f4f5;
41
+ --mxc-muted: #a1a1aa;
42
+ --mxc-border: #3f3f46;
43
+ --mxc-hover: rgba(255, 255, 255, 0.06);
44
+ --mxc-tab-active-bg: rgba(255, 255, 255, 0.1);
45
+ --mxc-accent: #60a5fa;
46
+ --mxc-accent-soft: rgba(96, 165, 250, 0.3);
47
+ --mxc-accent-fg: #0b1220;
48
+ --mxc-danger: #f87171;
49
+ }
package/package.json CHANGED
@@ -1,14 +1,93 @@
1
1
  {
2
2
  "name": "@ai-matrx/canvas",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Name reservation only. The functional Canvas release is being prepared; this bootstrap contains no implementation.",
3
+ "version": "0.1.0",
4
+ "description": "The AI Matrx canvas: a docked right-hand column with split panes, tabs, full screen, a kind registry, Redux-compatible state and persistence.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
5
9
  "license": "MIT",
6
- "files": [
7
- "README.md"
8
- ],
9
10
  "repository": {
10
11
  "type": "git",
11
12
  "url": "git+https://github.com/AI-Matrix-Engine/aidream.git",
12
13
  "directory": "apps/shared/canvas"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE",
19
+ "CHANGELOG.md"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "import": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/index.d.cts",
29
+ "default": "./dist/index.cjs"
30
+ }
31
+ },
32
+ "./react": {
33
+ "import": {
34
+ "types": "./dist/react.d.ts",
35
+ "default": "./dist/react.js"
36
+ },
37
+ "require": {
38
+ "types": "./dist/react.d.cts",
39
+ "default": "./dist/react.cjs"
40
+ }
41
+ },
42
+ "./styles.css": "./dist/styles.css",
43
+ "./tokens.css": "./dist/tokens.css",
44
+ "./package.json": "./package.json"
45
+ },
46
+ "dependencies": {
47
+ "@radix-ui/react-dropdown-menu": "latest",
48
+ "@ai-matrx/tap-target": "latest"
49
+ },
50
+ "peerDependencies": {
51
+ "react": ">=18.0.0",
52
+ "react-dom": ">=18.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "react": {
56
+ "optional": true
57
+ },
58
+ "react-dom": {
59
+ "optional": true
60
+ }
61
+ },
62
+ "devDependencies": {
63
+ "@arethetypeswrong/cli": "^0.18.5",
64
+ "@types/node": "^26.6.2",
65
+ "@types/react": "19.3.0",
66
+ "@types/react-dom": "19.3.0",
67
+ "jsdom": "^30.1.1",
68
+ "publint": "^0.3.24",
69
+ "react": "^19.3.0",
70
+ "react-dom": "^19.3.0",
71
+ "tsup": "^8.5.1",
72
+ "typescript": "^6.0.3",
73
+ "vitest": "^5.0.1"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public",
77
+ "registry": "https://registry.npmjs.org/"
78
+ },
79
+ "engines": {
80
+ "node": ">=20"
81
+ },
82
+ "sideEffects": [
83
+ "*.css"
84
+ ],
85
+ "scripts": {
86
+ "build": "pnpm clean && tsup",
87
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
88
+ "typecheck": "tsc -p tsconfig.json --noEmit",
89
+ "test": "vitest run",
90
+ "check:package": "pnpm build && node ../scripts/check-exports-agreement.mjs && publint && pnpm verify:tarball",
91
+ "verify:tarball": "node scripts/verify-tarball.mjs"
13
92
  }
14
- }
93
+ }