anentrypoint-design 0.0.29 → 0.0.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.29",
3
+ "version": "0.0.30",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -0,0 +1,105 @@
1
+ import * as webjsx from '../../vendor/webjsx/index.js';
2
+ import { Btn } from './shell.js';
3
+ import { fileGlyph, fmtFileSize } from './files.js';
4
+ const h = webjsx.createElement;
5
+
6
+ function Backdrop({ onClose, children, kind = '' } = {}) {
7
+ return h('div', {
8
+ class: 'ds-modal-backdrop',
9
+ onclick: (e) => { if (e.target === e.currentTarget && onClose) onClose(); }
10
+ },
11
+ h('div', { class: 'ds-modal' + (kind ? ' ds-modal-' + kind : '') }, ...(Array.isArray(children) ? children : [children]))
12
+ );
13
+ }
14
+
15
+ export function ConfirmDialog({ title = 'confirm', message, confirmLabel = 'confirm', cancelLabel = 'cancel', destructive, onConfirm, onCancel } = {}) {
16
+ return Backdrop({
17
+ onClose: onCancel,
18
+ kind: 'small',
19
+ children: [
20
+ h('div', { class: 'ds-modal-head' }, title),
21
+ h('div', { class: 'ds-modal-body' }, message || ''),
22
+ h('div', { class: 'ds-modal-actions' },
23
+ Btn({ onClick: onCancel, children: cancelLabel }),
24
+ h('button', {
25
+ class: destructive ? 'btn-stamp flame' : 'btn-stamp green',
26
+ onclick: onConfirm
27
+ }, confirmLabel)
28
+ )
29
+ ]
30
+ });
31
+ }
32
+
33
+ export function PromptDialog({ title = 'name', value = '', placeholder = '', confirmLabel = 'ok', cancelLabel = 'cancel', onConfirm, onCancel, onInput } = {}) {
34
+ return Backdrop({
35
+ onClose: onCancel,
36
+ kind: 'small',
37
+ children: [
38
+ h('div', { class: 'ds-modal-head' }, title),
39
+ h('div', { class: 'ds-modal-body' },
40
+ h('input', {
41
+ class: 'input ds-modal-input',
42
+ type: 'text',
43
+ value,
44
+ placeholder,
45
+ autofocus: true,
46
+ oninput: (e) => onInput && onInput(e.target.value),
47
+ onkeydown: (e) => {
48
+ if (e.key === 'Enter') { e.preventDefault(); onConfirm && onConfirm(e.target.value); }
49
+ if (e.key === 'Escape') { e.preventDefault(); onCancel && onCancel(); }
50
+ }
51
+ })
52
+ ),
53
+ h('div', { class: 'ds-modal-actions' },
54
+ Btn({ onClick: onCancel, children: cancelLabel }),
55
+ h('button', { class: 'btn-stamp green', onclick: () => onConfirm && onConfirm(value) }, confirmLabel)
56
+ )
57
+ ]
58
+ });
59
+ }
60
+
61
+ export function FilePreviewMedia({ src, type = 'other', name } = {}) {
62
+ if (type === 'image') return h('img', { class: 'ds-preview-media', src, alt: name || '' });
63
+ if (type === 'video') return h('video', { class: 'ds-preview-media', src, controls: true });
64
+ if (type === 'audio') return h('audio', { class: 'ds-preview-audio', src, controls: true });
65
+ return h('div', { class: 'ds-preview-fallback' },
66
+ h('span', { class: 'ds-preview-glyph' }, fileGlyph(type)),
67
+ h('span', {}, 'no inline preview for ' + (type || 'this file'))
68
+ );
69
+ }
70
+
71
+ export function FilePreviewCode({ content = '', lang } = {}) {
72
+ return h('pre', { class: 'ds-preview-code' + (lang ? ' lang-' + lang : '') },
73
+ h('code', { class: lang ? 'language-' + lang : '' }, content)
74
+ );
75
+ }
76
+
77
+ export function FilePreviewText({ content = '', truncated } = {}) {
78
+ return h('pre', { class: 'ds-preview-text' },
79
+ h('code', {}, content),
80
+ truncated ? h('div', { class: 'ds-preview-truncated' }, '… (truncated)') : null
81
+ );
82
+ }
83
+
84
+ export function FileViewer({ file, body, onClose, onAction } = {}) {
85
+ if (!file) return null;
86
+ const meta = [file.type, file.size != null ? fmtFileSize(file.size) : null, file.modified || null]
87
+ .filter(Boolean).join(' · ');
88
+ return Backdrop({
89
+ onClose,
90
+ kind: 'preview',
91
+ children: [
92
+ h('div', { class: 'ds-modal-head ds-preview-head', 'data-file-type': file.type || 'other' },
93
+ h('span', { class: 'ds-preview-name' }, file.name || ''),
94
+ h('span', { class: 'ds-preview-meta' }, meta),
95
+ h('span', { class: 'ds-preview-actions' },
96
+ onAction ? h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓') : null,
97
+ h('button', { class: 'ds-file-act', title: 'close', onclick: onClose }, '✕')
98
+ )
99
+ ),
100
+ h('div', { class: 'ds-preview-body', 'data-file-type': file.type || 'other' },
101
+ ...(Array.isArray(body) ? body : [body])
102
+ )
103
+ ]
104
+ });
105
+ }
@@ -0,0 +1,126 @@
1
+ import * as webjsx from '../../vendor/webjsx/index.js';
2
+ import { Btn, Glyph } from './shell.js';
3
+ const h = webjsx.createElement;
4
+
5
+ const FILE_TYPES = ['dir', 'image', 'video', 'audio', 'code', 'text', 'archive', 'document', 'symlink', 'other'];
6
+ const TYPE_GLYPH = {
7
+ dir: '▣', image: '◰', video: '▰', audio: '◎', code: '⌘',
8
+ text: '§', archive: '◐', document: '▢', symlink: '↗', other: '◌'
9
+ };
10
+
11
+ export function fileGlyph(type) {
12
+ return TYPE_GLYPH[type] || TYPE_GLYPH.other;
13
+ }
14
+
15
+ export function fmtFileSize(bytes) {
16
+ if (bytes == null || bytes === 0) return '—';
17
+ const u = ['B', 'KB', 'MB', 'GB', 'TB'];
18
+ let i = 0, n = bytes;
19
+ while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
20
+ return n.toFixed(i === 0 ? 0 : 1) + ' ' + u[i];
21
+ }
22
+
23
+ export function FileIcon({ type = 'other' } = {}) {
24
+ return h('span', { class: 'ds-file-icon', 'data-file-type': type }, fileGlyph(type));
25
+ }
26
+
27
+ export function FileRow({ name, type = 'other', size, modified, code, onOpen, onAction, active, key } = {}) {
28
+ const meta = [type === 'dir' ? null : fmtFileSize(size), modified || null].filter(Boolean).join(' · ');
29
+ return h('div', {
30
+ key,
31
+ class: 'ds-file-row row' + (active ? ' active' : ''),
32
+ 'data-file-type': type,
33
+ onclick: onOpen
34
+ },
35
+ code != null ? h('span', { class: 'code' }, code) : null,
36
+ FileIcon({ type }),
37
+ h('span', { class: 'title' }, name),
38
+ h('span', { class: 'ds-file-meta meta' }, meta || '—'),
39
+ onAction ? h('span', { class: 'ds-file-actions', onclick: (e) => e.stopPropagation() },
40
+ h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓'),
41
+ h('button', { class: 'ds-file-act', title: 'rename', onclick: () => onAction('rename') }, '✎'),
42
+ h('button', { class: 'ds-file-act ds-file-act-warn', title: 'delete', onclick: () => onAction('delete') }, '✕')
43
+ ) : null
44
+ );
45
+ }
46
+
47
+ export function FileGrid({ files = [], onOpen, onAction, emptyText = 'no files here yet' } = {}) {
48
+ if (!files.length) return EmptyState({ text: emptyText });
49
+ return h('div', { class: 'ds-file-grid' },
50
+ ...files.map((f, i) => FileRow({
51
+ key: f.path || f.name + i,
52
+ name: f.name,
53
+ type: f.type,
54
+ size: f.size,
55
+ modified: f.modified,
56
+ code: f.code,
57
+ active: f.active,
58
+ onOpen: onOpen ? () => onOpen(f) : null,
59
+ onAction: onAction ? (act) => onAction(act, f) : null
60
+ }))
61
+ );
62
+ }
63
+
64
+ export function FileToolbar({ left = [], right = [] } = {}) {
65
+ return h('div', { class: 'ds-file-toolbar' },
66
+ h('div', { class: 'ds-file-toolbar-left' }, ...left),
67
+ h('div', { class: 'ds-file-toolbar-right' }, ...right)
68
+ );
69
+ }
70
+
71
+ export function DropZone({ children, dragover, onDrop, onDragOver, onDragLeave, label = 'drop files here', onPick } = {}) {
72
+ return h('div', {
73
+ class: 'ds-dropzone' + (dragover ? ' dragover' : ''),
74
+ ondragover: (e) => { e.preventDefault(); onDragOver && onDragOver(e); },
75
+ ondragleave: (e) => { onDragLeave && onDragLeave(e); },
76
+ ondrop: (e) => { e.preventDefault(); onDrop && onDrop(e.dataTransfer.files); }
77
+ },
78
+ h('div', { class: 'ds-dropzone-inner' },
79
+ h('span', { class: 'ds-dropzone-glyph' }, '⇪'),
80
+ h('span', { class: 'ds-dropzone-label' }, label),
81
+ onPick ? Btn({ onClick: onPick, children: 'pick files' }) : null
82
+ ),
83
+ ...(Array.isArray(children) ? children : children ? [children] : [])
84
+ );
85
+ }
86
+
87
+ export function UploadProgress({ items = [] } = {}) {
88
+ if (!items.length) return null;
89
+ return h('div', { class: 'ds-upload-progress' },
90
+ ...items.map((it, i) => h('div', {
91
+ key: it.name + i,
92
+ class: 'ds-upload-item' + (it.done ? ' done' : '') + (it.error ? ' error' : '')
93
+ },
94
+ h('span', { class: 'ds-upload-name' }, it.name),
95
+ h('span', { class: 'ds-upload-bar' },
96
+ h('span', {
97
+ class: 'ds-upload-fill',
98
+ 'data-pct': String(Math.max(0, Math.min(100, it.pct || 0)))
99
+ })
100
+ ),
101
+ h('span', { class: 'ds-upload-pct' }, (it.error ? 'err' : (it.done ? 'ok' : (it.pct || 0) + '%')))
102
+ ))
103
+ );
104
+ }
105
+
106
+ export function EmptyState({ text = 'nothing here', glyph = '◌' } = {}) {
107
+ return h('div', { class: 'ds-file-empty' },
108
+ h('span', { class: 'ds-file-empty-glyph' }, glyph),
109
+ h('span', { class: 'ds-file-empty-text' }, text)
110
+ );
111
+ }
112
+
113
+ export function BreadcrumbPath({ segments = [], onNav, root = 'root' } = {}) {
114
+ const parts = [
115
+ h('button', { key: 'root', class: 'ds-crumb-seg', onclick: () => onNav && onNav(0) }, root)
116
+ ];
117
+ segments.forEach((seg, i) => {
118
+ parts.push(h('span', { key: 'sep' + i, class: 'ds-crumb-sep' }, '›'));
119
+ parts.push(h('button', {
120
+ key: 'seg' + i,
121
+ class: 'ds-crumb-seg' + (i === segments.length - 1 ? ' leaf' : ''),
122
+ onclick: () => onNav && onNav(i + 1)
123
+ }, seg));
124
+ });
125
+ return h('div', { class: 'ds-crumb-path' }, ...parts);
126
+ }
package/src/components.js CHANGED
@@ -19,3 +19,14 @@ export {
19
19
  ChatMessage, ChatComposer, Chat,
20
20
  AICAT_FACE, AICatPortrait, AICat
21
21
  } from './components/chat.js';
22
+
23
+ export {
24
+ fileGlyph, fmtFileSize,
25
+ FileIcon, FileRow, FileGrid, FileToolbar,
26
+ DropZone, UploadProgress, EmptyState, BreadcrumbPath
27
+ } from './components/files.js';
28
+
29
+ export {
30
+ ConfirmDialog, PromptDialog,
31
+ FilePreviewMedia, FilePreviewCode, FilePreviewText, FileViewer
32
+ } from './components/files-modals.js';