anentrypoint-design 0.0.121 → 0.0.124
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/README.md +253 -253
- package/app-shell.css +931 -594
- package/colors_and_type.css +226 -226
- package/community.css +817 -1222
- package/dist/247420.css +2202 -2084
- package/dist/247420.js +13 -13
- package/package.json +80 -80
- package/src/bootstrap.js +25 -25
- package/src/components/chat.js +199 -199
- package/src/components/community.js +190 -208
- package/src/components/content.js +269 -269
- package/src/components/editor-primitives.js +100 -0
- package/src/components/files-modals.js +107 -107
- package/src/components/files.js +118 -118
- package/src/components/freddie/helpers.js +50 -50
- package/src/components/freddie.js +33 -33
- package/src/components/shell.js +117 -117
- package/src/components/theme-toggle.js +70 -70
- package/src/components.js +59 -57
- package/src/debug.js +30 -30
- package/src/deck-stage.js +21 -21
- package/src/highlight.js +65 -32
- package/src/index.js +86 -86
- package/src/kits/os/about-app.js +52 -52
- package/src/kits/os/app-panes.css +152 -152
- package/src/kits/os/browser-app.js +58 -58
- package/src/kits/os/files-app.js +44 -44
- package/src/kits/os/freddie/helpers.js +59 -59
- package/src/kits/os/freddie/pages-chat.js +143 -143
- package/src/kits/os/freddie/pages-core.js +101 -101
- package/src/kits/os/freddie/pages-os.js +51 -51
- package/src/kits/os/freddie/pages-tools.js +183 -183
- package/src/kits/os/freddie/routes.js +24 -24
- package/src/kits/os/freddie-dashboard.css +51 -51
- package/src/kits/os/freddie-dashboard.js +101 -101
- package/src/kits/os/icons.js +17 -17
- package/src/kits/os/index.js +17 -17
- package/src/kits/os/launcher.css +61 -61
- package/src/kits/os/launcher.js +79 -79
- package/src/kits/os/monitor-app.js +34 -34
- package/src/kits/os/shell.js +214 -214
- package/src/kits/os/terminal-app.js +45 -45
- package/src/kits/os/theme.css +450 -450
- package/src/kits/os/validate.css +19 -19
- package/src/kits/os/validator-app.js +55 -55
- package/src/kits/os/wm.css +115 -115
- package/src/kits/os/wm.js +111 -111
- package/src/markdown.js +39 -39
- package/src/motion.js +35 -35
- package/src/page-html.js +196 -196
- package/src/styles.js +25 -25
- package/src/theme.js +99 -99
- package/src/web-components/ds-chat.js +116 -116
- package/dist/.nojekyll +0 -0
- package/dist/app-shell.css +0 -594
- package/dist/colors_and_type.css +0 -197
- package/dist/favicon.svg +0 -1
- package/dist/index.html +0 -308
- package/dist/preview/buttons.html +0 -28
- package/dist/preview/colors-core.html +0 -45
- package/dist/preview/colors-lore.html +0 -28
- package/dist/preview/colors-semantic.html +0 -34
- package/dist/preview/dateline.html +0 -19
- package/dist/preview/dropzone.html +0 -30
- package/dist/preview/file-grid.html +0 -19
- package/dist/preview/file-row.html +0 -20
- package/dist/preview/file-toolbar.html +0 -40
- package/dist/preview/file-viewer.html +0 -31
- package/dist/preview/header.html +0 -24
- package/dist/preview/icons-unicode.html +0 -26
- package/dist/preview/index-row.html +0 -25
- package/dist/preview/inputs.html +0 -22
- package/dist/preview/manifesto.html +0 -52
- package/dist/preview/motion-default.js +0 -106
- package/dist/preview/rules.html +0 -16
- package/dist/preview/spacing.html +0 -18
- package/dist/preview/stamps-lore.html +0 -20
- package/dist/preview/stamps.html +0 -14
- package/dist/preview/theme-ink.html +0 -15
- package/dist/preview/type-display.html +0 -16
- package/dist/preview/type-mono.html +0 -15
- package/dist/preview/type-prose.html +0 -11
- package/dist/preview/type-scale.html +0 -20
- package/dist/preview/wordmarks.html +0 -28
- package/dist/robots.txt +0 -8
- package/dist/site/content/globals/navigation.yaml +0 -5
- package/dist/site/content/globals/site.yaml +0 -16
- package/dist/site/content/pages/freddie.yaml +0 -88
- package/dist/site/content/pages/home.yaml +0 -190
- package/dist/site/theme.mjs +0 -368
- package/dist/sitemap.xml +0 -31
- package/dist/slides/deck-stage-overlay.js +0 -63
- package/dist/slides/deck-stage-state.js +0 -81
- package/dist/slides/deck-stage-style.js +0 -117
- package/dist/slides/deck-stage.js +0 -159
- package/dist/slides/index.html +0 -276
- package/dist/src/bootstrap.js +0 -25
- package/dist/src/components/chat.js +0 -199
- package/dist/src/components/community.js +0 -167
- package/dist/src/components/content.js +0 -213
- package/dist/src/components/files-modals.js +0 -107
- package/dist/src/components/files.js +0 -118
- package/dist/src/components/freddie/helpers.js +0 -50
- package/dist/src/components/freddie.js +0 -33
- package/dist/src/components/shell.js +0 -117
- package/dist/src/components/theme-toggle.js +0 -70
- package/dist/src/components.js +0 -52
- package/dist/src/debug.js +0 -30
- package/dist/src/deck-stage.js +0 -21
- package/dist/src/highlight.js +0 -32
- package/dist/src/index.js +0 -86
- package/dist/src/kits/os/about-app.js +0 -52
- package/dist/src/kits/os/app-panes.css +0 -152
- package/dist/src/kits/os/browser-app.js +0 -58
- package/dist/src/kits/os/files-app.js +0 -44
- package/dist/src/kits/os/freddie/helpers.js +0 -59
- package/dist/src/kits/os/freddie/pages-chat.js +0 -143
- package/dist/src/kits/os/freddie/pages-core.js +0 -101
- package/dist/src/kits/os/freddie/pages-os.js +0 -51
- package/dist/src/kits/os/freddie/pages-tools.js +0 -183
- package/dist/src/kits/os/freddie/routes.js +0 -24
- package/dist/src/kits/os/freddie-dashboard.css +0 -51
- package/dist/src/kits/os/freddie-dashboard.js +0 -101
- package/dist/src/kits/os/icons.js +0 -17
- package/dist/src/kits/os/index.js +0 -5
- package/dist/src/kits/os/launcher.css +0 -61
- package/dist/src/kits/os/launcher.js +0 -79
- package/dist/src/kits/os/monitor-app.js +0 -34
- package/dist/src/kits/os/shell.js +0 -214
- package/dist/src/kits/os/terminal-app.js +0 -45
- package/dist/src/kits/os/theme.css +0 -412
- package/dist/src/kits/os/validate.css +0 -19
- package/dist/src/kits/os/validator-app.js +0 -55
- package/dist/src/kits/os/wm.css +0 -115
- package/dist/src/kits/os/wm.js +0 -111
- package/dist/src/markdown.js +0 -39
- package/dist/src/motion.js +0 -35
- package/dist/src/page-html.js +0 -196
- package/dist/src/styles.js +0 -25
- package/dist/src/theme.js +0 -99
- package/dist/src/web-components/ds-chat.js +0 -45
- package/dist/ui_kits/aicat/README.md +0 -7
- package/dist/ui_kits/aicat/app.js +0 -156
- package/dist/ui_kits/aicat/index.html +0 -26
- package/dist/ui_kits/aicat/sample-square.png +0 -0
- package/dist/ui_kits/aicat/sample-svg.svg +0 -1
- package/dist/ui_kits/aicat/sample.pdf +0 -32
- package/dist/ui_kits/blog/README.md +0 -3
- package/dist/ui_kits/blog/index.html +0 -90
- package/dist/ui_kits/chat/README.md +0 -5
- package/dist/ui_kits/chat/app.js +0 -110
- package/dist/ui_kits/chat/index.html +0 -26
- package/dist/ui_kits/chat/sample-square.png +0 -0
- package/dist/ui_kits/chat/sample-svg.svg +0 -1
- package/dist/ui_kits/chat/sample.pdf +0 -32
- package/dist/ui_kits/community/app.js +0 -134
- package/dist/ui_kits/community/index.html +0 -24
- package/dist/ui_kits/dashboard/app.js +0 -92
- package/dist/ui_kits/dashboard/index.html +0 -26
- package/dist/ui_kits/docs/README.md +0 -3
- package/dist/ui_kits/docs/index.html +0 -123
- package/dist/ui_kits/error_404/app.js +0 -56
- package/dist/ui_kits/error_404/index.html +0 -26
- package/dist/ui_kits/file_browser/README.md +0 -48
- package/dist/ui_kits/file_browser/app.js +0 -231
- package/dist/ui_kits/file_browser/index.html +0 -33
- package/dist/ui_kits/gallery/app.js +0 -121
- package/dist/ui_kits/gallery/index.html +0 -26
- package/dist/ui_kits/homepage/README.md +0 -7
- package/dist/ui_kits/homepage/app.js +0 -167
- package/dist/ui_kits/homepage/index.html +0 -46
- package/dist/ui_kits/project_page/README.md +0 -3
- package/dist/ui_kits/project_page/app.js +0 -154
- package/dist/ui_kits/project_page/index.html +0 -45
- package/dist/ui_kits/search/app.js +0 -107
- package/dist/ui_kits/search/index.html +0 -26
- package/dist/ui_kits/settings/app.js +0 -133
- package/dist/ui_kits/settings/index.html +0 -26
- package/dist/ui_kits/signin/app.js +0 -115
- package/dist/ui_kits/signin/index.html +0 -26
- package/dist/ui_kits/slide_deck/app.js +0 -174
- package/dist/ui_kits/slide_deck/index.html +0 -26
- package/dist/ui_kits/system_primer/app.js +0 -152
- package/dist/ui_kits/system_primer/index.html +0 -26
- package/dist/ui_kits/terminal/app.js +0 -150
- package/dist/ui_kits/terminal/index.html +0 -26
- package/dist/vendor/webjsx/applyDiff.js +0 -182
- package/dist/vendor/webjsx/attributes.js +0 -154
- package/dist/vendor/webjsx/constants.js +0 -4
- package/dist/vendor/webjsx/createDOMElement.js +0 -52
- package/dist/vendor/webjsx/createElement.js +0 -75
- package/dist/vendor/webjsx/elementTags.js +0 -115
- package/dist/vendor/webjsx/factory.js +0 -6
- package/dist/vendor/webjsx/index.js +0 -6
- package/dist/vendor/webjsx/jsx-dev-runtime.js +0 -2
- package/dist/vendor/webjsx/jsx-runtime.js +0 -30
- package/dist/vendor/webjsx/jsx.js +0 -2
- package/dist/vendor/webjsx/package.json +0 -39
- package/dist/vendor/webjsx/renderSuspension.js +0 -25
- package/dist/vendor/webjsx/types.js +0 -5
- package/dist/vendor/webjsx/utils.js +0 -84
- package/src/components/overlays.js +0 -151
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import * as webjsx from 'webjsx';
|
|
2
|
-
import { AICat, AICatPortrait, ChatComposer, Topbar, Crumb, Status, Side, AppShell, Panel, Heading, Lede, Chip } from 'ds/components.js';
|
|
3
|
-
import { mountKit } from 'ds/bootstrap.js';
|
|
4
|
-
import 'ds/index.js';
|
|
5
|
-
const h = webjsx.createElement;
|
|
6
|
-
|
|
7
|
-
const FACES = {
|
|
8
|
-
idle: ` /\\_/\\\n( o.o )\n > ^ <`,
|
|
9
|
-
happy: ` /\\_/\\\n( ^.^ )\n > ~ <`,
|
|
10
|
-
think: ` /\\_/\\\n( -.- )\n > ? <`,
|
|
11
|
-
pounce: ` /\\_/\\\n( O.O )\n > ! <`
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const PRESETS = [
|
|
15
|
-
{ q: 'show me a small react component', k: 'code-react' },
|
|
16
|
-
{ q: 'show python prime sieve', k: 'code-py' },
|
|
17
|
-
{ q: 'explain prefers-reduced-motion', k: 'md-rm' },
|
|
18
|
-
{ q: 'send the v0.0.27 token sheet', k: 'pdf' },
|
|
19
|
-
{ q: 'paste the mascot art', k: 'image' },
|
|
20
|
-
{ q: 'link the design repo', k: 'link' },
|
|
21
|
-
{ q: 'attach a config file', k: 'file' },
|
|
22
|
-
{ q: 'tell me a joke about garbage collection', k: 'text' }
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
const REPLIES = {
|
|
26
|
-
'code-react': () => ({ parts: [
|
|
27
|
-
{ kind: 'text', text: 'sure — here\'s a tiny one:' },
|
|
28
|
-
{ kind: 'code', lang: 'jsx', filename: 'Greet.jsx',
|
|
29
|
-
code: 'export function Greet({ name }) {\n return <p>hi, {name} =^.^=</p>;\n}\n\nexport default Greet;' }
|
|
30
|
-
] }),
|
|
31
|
-
'code-py': () => ({ parts: [
|
|
32
|
-
{ kind: 'text', text: 'classic sieve, no imports:' },
|
|
33
|
-
{ kind: 'code', lang: 'python', filename: 'sieve.py',
|
|
34
|
-
code: 'def primes(n):\n sieve = [True] * (n + 1)\n sieve[0] = sieve[1] = False\n for i in range(2, int(n ** 0.5) + 1):\n if sieve[i]:\n for j in range(i * i, n + 1, i):\n sieve[j] = False\n return [i for i, p in enumerate(sieve) if p]\n\nprint(primes(50))' }
|
|
35
|
-
] }),
|
|
36
|
-
'md-rm': () => ({ parts: [{ kind: 'md', text: '## prefers-reduced-motion\n\nmedia query that signals the user wants less animation. honour it:\n\n- short-circuit fade-ins\n- drop big translates\n- keep opacity-only if anything\n\n```css\n@media (prefers-reduced-motion: reduce) {\n * { animation-duration: 0ms !important; }\n}\n```\n\n> opt out of motion, not out of feedback.' }] }),
|
|
37
|
-
pdf: () => ({ parts: [
|
|
38
|
-
{ kind: 'text', text: 'here you go — `tokens-v0.0.27.pdf`:' },
|
|
39
|
-
{ kind: 'pdf', src: './sample.pdf', name: 'tokens-v0.0.27.pdf', size: 782 }
|
|
40
|
-
] }),
|
|
41
|
-
image: () => ({ parts: [
|
|
42
|
-
{ kind: 'text', text: 'mascot, fresh from the loom:' },
|
|
43
|
-
{ kind: 'image', src: './sample-svg.svg', alt: '247420 mascot', caption: 'mascot · svg · favicon-derived' }
|
|
44
|
-
] }),
|
|
45
|
-
link: () => ({ parts: [
|
|
46
|
-
{ kind: 'link', href: 'https://github.com/AnEntrypoint/design', host: 'github.com',
|
|
47
|
-
title: 'AnEntrypoint/design',
|
|
48
|
-
desc: 'design system for 247420 — layered surfaces, mono labels, pill radii.',
|
|
49
|
-
thumb: './sample-square.png' }
|
|
50
|
-
] }),
|
|
51
|
-
file: () => ({ parts: [
|
|
52
|
-
{ kind: 'text', text: 'config attached — drop it in `~/.config/aicat/config.json`.' },
|
|
53
|
-
{ kind: 'file', src: './sample.pdf', name: 'aicat.config.json', size: 412, kindLabel: 'JSON' }
|
|
54
|
-
] }),
|
|
55
|
-
text: () => ({ parts: [{ kind: 'text', text: 'a generational gc walks into a bar. the bartender says, *you again?* gc says, **don\'t worry, I\'ll be young forever.**' }] })
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
function classifyAndReply(text) {
|
|
59
|
-
const t = text.toLowerCase();
|
|
60
|
-
const map = [
|
|
61
|
-
[/python|sieve|prime/, 'code-py'],
|
|
62
|
-
[/code|react|component|function|jsx/, 'code-react'],
|
|
63
|
-
[/reduced.motion|animat|motion/, 'md-rm'],
|
|
64
|
-
[/pdf|token sheet|spec/, 'pdf'],
|
|
65
|
-
[/image|mascot|picture|art/, 'image'],
|
|
66
|
-
[/link|repo|github/, 'link'],
|
|
67
|
-
[/file|config|attach/, 'file']
|
|
68
|
-
];
|
|
69
|
-
for (const [re, k] of map) if (re.test(t)) return REPLIES[k]();
|
|
70
|
-
return REPLIES.text();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const state = {
|
|
74
|
-
draft: '', thinking: false, mood: 'idle',
|
|
75
|
-
messages: [
|
|
76
|
-
{ who: 'them', name: 'aicat', text: 'hi. I am **aicat**. I read fast and I knock things off shelves.', time: '·' },
|
|
77
|
-
{ who: 'them', name: 'aicat', parts: [{ kind: 'md', text: 'try one of these:\n\n- ask for `code` (react/python — pick a flavour)\n- ask for the **token pdf** or the **mascot image**\n- ask me to attach a *config file*\n- or just chat — I respond in markdown.' }], time: '·' }
|
|
78
|
-
]
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const root = document.getElementById('root');
|
|
82
|
-
function timeNow() { const d = new Date(); return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0'); }
|
|
83
|
-
|
|
84
|
-
function send(text) {
|
|
85
|
-
state.messages = [...state.messages, { who: 'you', avatar: 'u', time: timeNow(), receipt: 'delivered', parts: [{ kind: 'text', text }] }];
|
|
86
|
-
state.draft = '';
|
|
87
|
-
state.thinking = true;
|
|
88
|
-
state.mood = 'think';
|
|
89
|
-
kit.render();
|
|
90
|
-
setTimeout(() => {
|
|
91
|
-
state.thinking = false;
|
|
92
|
-
state.mood = 'happy';
|
|
93
|
-
const reply = classifyAndReply(text);
|
|
94
|
-
state.messages = state.messages.map((m) => m.who === 'you' ? { ...m, receipt: 'read' } : m);
|
|
95
|
-
state.messages = [...state.messages, { who: 'them', name: 'aicat', time: timeNow(), ...reply }];
|
|
96
|
-
kit.render();
|
|
97
|
-
setTimeout(() => { state.mood = 'idle'; kit.render(); }, 1400);
|
|
98
|
-
}, 1100);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function App() {
|
|
102
|
-
return AppShell({
|
|
103
|
-
topbar: Topbar({ brand: '247420', leaf: 'aicat', items: [['index', '../../'], ['chat', '../chat/'], ['source ↗', 'https://github.com/AnEntrypoint/design']] }),
|
|
104
|
-
crumb: Crumb({ trail: ['247420', 'kits'], leaf: 'aicat' }),
|
|
105
|
-
side: Side({
|
|
106
|
-
sections: [
|
|
107
|
-
{ group: 'session', items: [
|
|
108
|
-
{ glyph: '◆', label: 'new chat', key: 'new', onClick: (e) => { e.preventDefault(); state.messages = state.messages.slice(0, 2); kit.render(); } },
|
|
109
|
-
{ glyph: '◇', label: 'history', count: 7, key: 'h' }
|
|
110
|
-
] },
|
|
111
|
-
{ group: 'try', items: PRESETS.map((p, i) => ({
|
|
112
|
-
glyph: '·', label: p.q.length > 22 ? p.q.slice(0, 22) + '…' : p.q, key: 'p' + i,
|
|
113
|
-
onClick: (e) => { e.preventDefault(); send(p.q); }
|
|
114
|
-
})) }
|
|
115
|
-
]
|
|
116
|
-
}),
|
|
117
|
-
main: [
|
|
118
|
-
h('div', { class: 'ds-section' },
|
|
119
|
-
Heading({ level: 1, children: 'aicat' }),
|
|
120
|
-
Lede({ children: 'an ai assistant with a cat persona. she replies in text, code (highlighted), markdown, images, pdfs, file attachments, or link cards — depending on what you ask.' }),
|
|
121
|
-
AICatPortrait({
|
|
122
|
-
name: 'aicat',
|
|
123
|
-
status: state.thinking ? 'thinking…' : (state.mood === 'happy' ? 'online · purring' : 'online · idle'),
|
|
124
|
-
face: FACES[state.mood] || FACES.idle
|
|
125
|
-
}),
|
|
126
|
-
AICat({
|
|
127
|
-
name: 'aicat',
|
|
128
|
-
status: state.thinking ? 'thinking…' : 'online · purring',
|
|
129
|
-
messages: state.messages, thinking: state.thinking,
|
|
130
|
-
composer: ChatComposer({
|
|
131
|
-
value: state.draft,
|
|
132
|
-
placeholder: 'ask aicat anything…',
|
|
133
|
-
disabled: state.thinking,
|
|
134
|
-
onInput: (v) => { state.draft = v; kit.render(); },
|
|
135
|
-
onSend: send
|
|
136
|
-
})
|
|
137
|
-
}),
|
|
138
|
-
Panel({
|
|
139
|
-
title: 'about this kit',
|
|
140
|
-
children: h('div', { class: 'ds-pattern-notes' },
|
|
141
|
-
h('p', {}, '· portrait swaps with mood — ', Chip({ tone: 'dim', children: 'idle' }), ' ', Chip({ tone: 'dim', children: 'think' }), ' ', Chip({ tone: 'accent', children: 'happy' }), '.'),
|
|
142
|
-
h('p', {}, '· thinking-state appends a typing bubble, disables the composer, blocks pre-emptive multi-sends.'),
|
|
143
|
-
h('p', {}, '· classifier in ', h('code', {}, 'classifyAndReply()'), ' is deterministic — wire it to your model, replies stay shaped as ', h('code', {}, '{parts:[…]}'), '.')
|
|
144
|
-
)
|
|
145
|
-
})
|
|
146
|
-
)
|
|
147
|
-
],
|
|
148
|
-
status: Status({
|
|
149
|
-
left: ['aicat', '• ' + state.messages.length + ' turns', state.thinking ? '• thinking' : '• idle'],
|
|
150
|
-
right: ['247420 / mmxxvi']
|
|
151
|
-
})
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const kit = mountKit({ root, view: App, screen: '07 AICat' });
|
|
156
|
-
window.__aicat = { state, render: kit.render, send };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en" data-theme="auto" class="ds-247420"><head>
|
|
3
|
-
<meta charset="utf-8">
|
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
5
|
-
<meta name="theme-color" content="#247420" media="(prefers-color-scheme: light)">
|
|
6
|
-
<meta name="theme-color" content="#3A9A34" media="(prefers-color-scheme: dark)">
|
|
7
|
-
<meta name="color-scheme" content="light dark">
|
|
8
|
-
<title>aicat / 247420</title>
|
|
9
|
-
<meta name="description" content="aicat ui kit — ai assistant chat with cat persona, ascii portrait, thinking dots.">
|
|
10
|
-
<link rel="canonical" href="https://anentrypoint.github.io/design/ui_kits/aicat/">
|
|
11
|
-
<link rel="icon" type="image/svg+xml" href="../../favicon.svg">
|
|
12
|
-
<link rel="stylesheet" href="../../colors_and_type.css">
|
|
13
|
-
<link rel="stylesheet" href="../../app-shell.css">
|
|
14
|
-
<script type="importmap">
|
|
15
|
-
{ "imports": {
|
|
16
|
-
"webjsx": "../../vendor/webjsx/index.js",
|
|
17
|
-
"webjsx/": "../../vendor/webjsx/",
|
|
18
|
-
"webjsx/jsx-runtime": "../../vendor/webjsx/jsx-runtime.js",
|
|
19
|
-
"ds/": "../../src/"
|
|
20
|
-
} }
|
|
21
|
-
</script>
|
|
22
|
-
</head>
|
|
23
|
-
<body data-screen-label="07 AICat">
|
|
24
|
-
<div id="root"></div>
|
|
25
|
-
<script type="module" src="./app.js"></script>
|
|
26
|
-
</body></html>
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#247420"/><text x="16" y="22" font-family="'JetBrains Mono',ui-monospace,monospace" font-size="14" font-weight="700" fill="#EFE9DD" text-anchor="middle">24</text></svg>
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
%PDF-1.4
|
|
2
|
-
1 0 obj
|
|
3
|
-
<< /Type /Catalog /Pages 2 0 R >>
|
|
4
|
-
endobj
|
|
5
|
-
2 0 obj
|
|
6
|
-
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
|
7
|
-
endobj
|
|
8
|
-
3 0 obj
|
|
9
|
-
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 360 220] /Resources << /Font << /F1 5 0 R >> >> /Contents 4 0 R >>
|
|
10
|
-
endobj
|
|
11
|
-
4 0 obj
|
|
12
|
-
<< /Length 238 >>
|
|
13
|
-
stream
|
|
14
|
-
BT /F1 18 Tf 36 180 Td (design tokens) Tj 0 -28 Td /F1 12 Tf (anentrypoint-design v0.0.26) Tj 0 -22 Td (panel-0 panel-1 panel-2 accent) Tj 0 -22 Td (zero-border, pill radii, mono labels) Tj 0 -38 Td /F1 10 Tf (sample pdf attachment) Tj ET
|
|
15
|
-
endstream
|
|
16
|
-
endobj
|
|
17
|
-
5 0 obj
|
|
18
|
-
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
|
|
19
|
-
endobj
|
|
20
|
-
xref
|
|
21
|
-
0 6
|
|
22
|
-
0000000000 65535 f
|
|
23
|
-
0000000009 00000 n
|
|
24
|
-
0000000058 00000 n
|
|
25
|
-
0000000115 00000 n
|
|
26
|
-
0000000241 00000 n
|
|
27
|
-
0000000530 00000 n
|
|
28
|
-
trailer
|
|
29
|
-
<< /Size 6 /Root 1 0 R >>
|
|
30
|
-
startxref
|
|
31
|
-
600
|
|
32
|
-
%%EOF
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en" data-theme="auto" class="ds-247420"><head>
|
|
3
|
-
<meta charset="utf-8">
|
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
5
|
-
<meta name="theme-color" content="#247420" media="(prefers-color-scheme: light)">
|
|
6
|
-
<meta name="theme-color" content="#3A9A34" media="(prefers-color-scheme: dark)">
|
|
7
|
-
<meta name="color-scheme" content="light dark">
|
|
8
|
-
<title>writing / 247420</title>
|
|
9
|
-
<meta name="description" content="long-form writing template — editorial type on layered panels.">
|
|
10
|
-
<meta name="author" content="247420 / AnEntrypoint">
|
|
11
|
-
<meta name="keywords" content="247420, anentrypoint, design system, webjsx, rippleui, creative collective">
|
|
12
|
-
<link rel="canonical" href="https://anentrypoint.github.io/design/ui_kits/blog/">
|
|
13
|
-
<link rel="icon" type="image/svg+xml" href="../../favicon.svg">
|
|
14
|
-
<meta property="og:type" content="website">
|
|
15
|
-
<meta property="og:title" content="writing / 247420">
|
|
16
|
-
<meta property="og:description" content="long-form writing template — editorial type on layered panels.">
|
|
17
|
-
<meta property="og:url" content="https://anentrypoint.github.io/design/ui_kits/blog/">
|
|
18
|
-
<meta property="og:site_name" content="247420 / design">
|
|
19
|
-
<meta property="og:image" content="https://anentrypoint.github.io/design/og-card.png">
|
|
20
|
-
<meta property="og:image:width" content="1200">
|
|
21
|
-
<meta property="og:image:height" content="630">
|
|
22
|
-
<meta property="og:image:alt" content="247420 design system">
|
|
23
|
-
<meta property="og:locale" content="en_US">
|
|
24
|
-
<meta name="twitter:card" content="summary_large_image">
|
|
25
|
-
<meta name="twitter:title" content="writing / 247420">
|
|
26
|
-
<meta name="twitter:description" content="long-form writing template — editorial type on layered panels.">
|
|
27
|
-
<meta name="twitter:image" content="https://anentrypoint.github.io/design/og-card.png">
|
|
28
|
-
<meta name="twitter:site" content="@AnEntrypoint">
|
|
29
|
-
<meta name="robots" content="index, follow">
|
|
30
|
-
<link rel="stylesheet" href="../../colors_and_type.css">
|
|
31
|
-
<link rel="stylesheet" href="../../app-shell.css">
|
|
32
|
-
<style>
|
|
33
|
-
.post-meta{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:24px;font-family:var(--ff-mono);font-size:14px;text-transform:uppercase;letter-spacing:0.08em;color:var(--panel-text-2);}
|
|
34
|
-
.post-meta .sep{color:var(--panel-text-3);}
|
|
35
|
-
blockquote{margin:20px 0;padding:12px 18px;background:var(--panel-1);border-radius:8px;font-size:15px;color:var(--panel-text);line-height:1.55;max-width:62ch;}
|
|
36
|
-
blockquote::before{content:'“';color:var(--panel-accent);font-family:var(--ff-display);font-size:28px;margin-right:6px;line-height:0;vertical-align:-4px;}
|
|
37
|
-
.post-body p{font-size:15px;line-height:1.7;max-width:62ch;color:var(--panel-text);}
|
|
38
|
-
.post-body a{color:var(--panel-accent);}
|
|
39
|
-
</style>
|
|
40
|
-
|
|
41
|
-
</head>
|
|
42
|
-
<body data-screen-label="04 Blog">
|
|
43
|
-
<div class="app">
|
|
44
|
-
<header class="app-topbar">
|
|
45
|
-
<span class="brand">247420<span class="slash"> / </span>writing</span>
|
|
46
|
-
<nav>
|
|
47
|
-
<a href="../homepage/">← homepage</a>
|
|
48
|
-
<a href="#" class="active">lore</a>
|
|
49
|
-
<a href="#">gm</a>
|
|
50
|
-
<a href="#">manifesto</a>
|
|
51
|
-
<a href="#">notes</a>
|
|
52
|
-
</nav>
|
|
53
|
-
</header>
|
|
54
|
-
<div class="app-crumb">
|
|
55
|
-
<span>247420</span><span class="sep">›</span>
|
|
56
|
-
<span>writing</span><span class="sep">›</span>
|
|
57
|
-
<span>lore</span><span class="sep">›</span>
|
|
58
|
-
<span class="leaf">we-were-here-first.md</span>
|
|
59
|
-
</div>
|
|
60
|
-
<div class="app-body no-side">
|
|
61
|
-
<main class="app-main narrow centered">
|
|
62
|
-
<div class="post-meta">
|
|
63
|
-
<span>§ lore</span><span class="sep">·</span>
|
|
64
|
-
<span>apr 14 2026</span><span class="sep">·</span>
|
|
65
|
-
<span>8 min read</span><span class="sep">·</span>
|
|
66
|
-
<span><span class="chip accent">draft</span></span>
|
|
67
|
-
</div>
|
|
68
|
-
<h1>we were here first</h1>
|
|
69
|
-
<p class="lede">a short & slightly smug history of the creative department of the internet.</p>
|
|
70
|
-
<div class="post-body ds-prose">
|
|
71
|
-
<p>there's a particular feeling — you know the one — of watching something you made five years ago get repackaged, re-skinned, and re-announced as if it were new. the web is a very long memory with a very short attention span, and 247420 has been, quietly, <em>around</em> for most of it.</p>
|
|
72
|
-
<p>this isn't a victory lap. it's a map. because if you're showing up to the party now, you should at least know who set the table.</p>
|
|
73
|
-
<blockquote>we don't know which ideas become the future. we just know most of them come from the same few rooms.</blockquote>
|
|
74
|
-
<p>the rooms have moved — from irc to forums to discord to whatever-this-is-now — but the pattern is consistent. a handful of people, each a little too weird to hold a normal job, trading prototypes at 2am, throwing away 90% of them, shipping the 10% that's too strange to ignore. that's the collective. that's always been the collective. <a href="#">adaptogen</a>, <code>gm</code>, zellous, <a href="#">the long list of things you've never heard of</a> — all came out of the same 2am.</p>
|
|
75
|
-
<h2>so what's the actual point</h2>
|
|
76
|
-
<p>the point is: stop asking permission. ship the rough draft. document honestly. humor is load-bearing. and if you're reading this thinking "that's obvious" — good. you're home.</p>
|
|
77
|
-
<p class="ds-prose-endnote">§ end. reply by opening a pr. <a href="#">source ↗</a></p>
|
|
78
|
-
</div>
|
|
79
|
-
</main>
|
|
80
|
-
</div>
|
|
81
|
-
<footer class="app-status">
|
|
82
|
-
<span class="item">main</span>
|
|
83
|
-
<span class="item">• markdown</span>
|
|
84
|
-
<span class="item">• 8 min</span>
|
|
85
|
-
<span class="spread"></span>
|
|
86
|
-
<span class="item">apr 14 2026</span>
|
|
87
|
-
<span class="item">• draft</span>
|
|
88
|
-
</footer>
|
|
89
|
-
</div>
|
|
90
|
-
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Chat UI Kit
|
|
2
|
-
|
|
3
|
-
Message thread + composer. Tonal pill bubbles, monospace timestamps, accent-filled own-side, sidebar of rooms/DMs.
|
|
4
|
-
|
|
5
|
-
Components used: `Chat`, `ChatComposer`, `ChatMessage`, plus the shell primitives (`AppShell`, `Topbar`, `Crumb`, `Side`, `Status`, `Panel`).
|
package/dist/ui_kits/chat/app.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import * as webjsx from 'webjsx';
|
|
2
|
-
import { Chat, ChatComposer, Topbar, Crumb, Status, Side, AppShell, Panel } from 'ds/components.js';
|
|
3
|
-
import { mountKit } from 'ds/bootstrap.js';
|
|
4
|
-
import 'ds/index.js';
|
|
5
|
-
const h = webjsx.createElement;
|
|
6
|
-
|
|
7
|
-
const seed = [
|
|
8
|
-
{ who: 'them', avatar: 'jr', name: 'jordan', time: '14:02',
|
|
9
|
-
parts: [{ kind: 'text', text: 'pushed v0.0.27, theme cleanup looks clean now. see the **release notes** in [the changelog](https://github.com/AnEntrypoint/design/releases).' }],
|
|
10
|
-
reactions: [{ emoji: '🎉', count: 3, you: true }, { emoji: '👀', count: 1 }] },
|
|
11
|
-
{ who: 'them', avatar: 'mk', name: 'mai', time: '14:03',
|
|
12
|
-
parts: [{ kind: 'text', text: 'nice. body-hide trick on first paint? share the diff?' }] },
|
|
13
|
-
{ who: 'you', avatar: 'me', time: '14:04', receipt: 'read',
|
|
14
|
-
parts: [
|
|
15
|
-
{ kind: 'text', text: 'yeah — just hide `body` until styles+fonts+first paint ready. no flash.' },
|
|
16
|
-
{ kind: 'code', lang: 'css', filename: 'theme.css',
|
|
17
|
-
code: 'html { visibility: hidden; }\nhtml.ready { visibility: visible; }\n\n@media (prefers-reduced-motion: reduce) {\n * { animation-duration: 0ms !important; }\n}' }
|
|
18
|
-
] },
|
|
19
|
-
{ who: 'them', avatar: 'jr', name: 'jordan', time: '14:05',
|
|
20
|
-
parts: [{ kind: 'md', text: '## review notes\n\nlooks solid. couple things:\n\n- short timeout fallback in case fonts hang\n- announce the `ready` class via `requestIdleCallback`\n- keep no-js fallback to `visibility: visible`\n\n> "ship the rough draft" — but not the broken one.\n\nwill review the rest tonight.' }],
|
|
21
|
-
reactions: [{ emoji: '✅', count: 2, you: true }] },
|
|
22
|
-
{ who: 'them', avatar: 'mk', name: 'mai', time: '14:08',
|
|
23
|
-
parts: [{ kind: 'image', src: './sample-svg.svg', alt: 'design system mascot', caption: 'spot the new mascot — final ✨' }] },
|
|
24
|
-
{ who: 'you', avatar: 'me', time: '14:10', receipt: 'read',
|
|
25
|
-
parts: [
|
|
26
|
-
{ kind: 'text', text: 'attaching the v0.0.27 token sheet for review:' },
|
|
27
|
-
{ kind: 'pdf', src: './sample.pdf', name: 'tokens-v0.0.27.pdf', size: 782 }
|
|
28
|
-
] },
|
|
29
|
-
{ who: 'them', avatar: 'jr', name: 'jordan', time: '14:12',
|
|
30
|
-
parts: [{ kind: 'link', href: 'https://github.com/AnEntrypoint/design', host: 'github.com',
|
|
31
|
-
title: 'AnEntrypoint/design — design system for 247420',
|
|
32
|
-
desc: 'a coherent visual paradigm — layered surfaces, monospace labels, loud content inside quiet chrome.',
|
|
33
|
-
thumb: './sample-square.png' }] },
|
|
34
|
-
{ who: 'them', avatar: 'mk', name: 'mai', time: '14:14',
|
|
35
|
-
parts: [{ kind: 'file', src: './sample.pdf', name: 'meeting-notes-2026-05-01.pdf', size: 782 }],
|
|
36
|
-
reactions: [{ emoji: '📌', count: 1 }] }
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const state = { draft: '', room: 'general', messages: seed.slice() };
|
|
40
|
-
const rooms = [
|
|
41
|
-
{ glyph: '#', label: 'general', count: 12, key: 'general' },
|
|
42
|
-
{ glyph: '#', label: 'design', count: 4, key: 'design' },
|
|
43
|
-
{ glyph: '#', label: 'releases', count: 1, key: 'releases' },
|
|
44
|
-
{ glyph: '#', label: 'lore', count: 0, key: 'lore' }
|
|
45
|
-
];
|
|
46
|
-
const dms = [
|
|
47
|
-
{ glyph: '·', label: 'jordan', key: 'jr' },
|
|
48
|
-
{ glyph: '·', label: 'mai', key: 'mk' },
|
|
49
|
-
{ glyph: '·', label: 'aicat', key: 'aicat' }
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
const root = document.getElementById('root');
|
|
53
|
-
function timeNow() { const d = new Date(); return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0'); }
|
|
54
|
-
|
|
55
|
-
function send(text) {
|
|
56
|
-
state.messages = [...state.messages, {
|
|
57
|
-
who: 'you', avatar: 'me', time: timeNow(), receipt: 'delivered',
|
|
58
|
-
parts: [{ kind: 'text', text }]
|
|
59
|
-
}];
|
|
60
|
-
state.draft = '';
|
|
61
|
-
kit.render();
|
|
62
|
-
setTimeout(() => {
|
|
63
|
-
state.messages = [...state.messages, {
|
|
64
|
-
who: 'them', avatar: 'jr', name: 'jordan', time: timeNow(),
|
|
65
|
-
parts: [{ kind: 'text', text: 'noted. *' + text.split(' ').slice(0, 6).join(' ') + '…*' }]
|
|
66
|
-
}];
|
|
67
|
-
state.messages = state.messages.map((m) => m.who === 'you' ? { ...m, receipt: 'read' } : m);
|
|
68
|
-
kit.render();
|
|
69
|
-
}, 1100);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function App() {
|
|
73
|
-
return AppShell({
|
|
74
|
-
topbar: Topbar({ brand: '247420', leaf: 'chat', items: [['index', '../../'], ['aicat', '../aicat/'], ['source ↗', 'https://github.com/AnEntrypoint/design']] }),
|
|
75
|
-
crumb: Crumb({ trail: ['247420', 'kits'], leaf: 'chat' }),
|
|
76
|
-
side: Side({
|
|
77
|
-
sections: [
|
|
78
|
-
{ group: 'rooms', items: rooms.map(r => ({ ...r, active: state.room === r.key, onClick: (e) => { e.preventDefault(); state.room = r.key; kit.render(); } })) },
|
|
79
|
-
{ group: 'direct', items: dms.map(r => ({ ...r, active: state.room === r.key, onClick: (e) => { e.preventDefault(); state.room = r.key; kit.render(); } })) }
|
|
80
|
-
]
|
|
81
|
-
}),
|
|
82
|
-
main: [
|
|
83
|
-
h('div', { class: 'ds-section' },
|
|
84
|
-
h('h1', {}, '# ' + state.room),
|
|
85
|
-
h('p', { class: 'lede' }, 'thread of messages with rich attachments — text, code (prism-highlighted), image, pdf, file, link, markdown (marked + DOMPurify), reactions, read-receipts.'),
|
|
86
|
-
Chat({
|
|
87
|
-
title: state.room, sub: 'public', messages: state.messages,
|
|
88
|
-
composer: ChatComposer({
|
|
89
|
-
value: state.draft,
|
|
90
|
-
placeholder: 'message #' + state.room + '…',
|
|
91
|
-
onInput: (v) => { state.draft = v; kit.render(); },
|
|
92
|
-
onSend: send
|
|
93
|
-
})
|
|
94
|
-
}),
|
|
95
|
-
Panel({
|
|
96
|
-
title: 'pattern notes',
|
|
97
|
-
children: h('div', { class: 'ds-pattern-notes' },
|
|
98
|
-
h('p', {}, '· bubble corner-cut on the originating side (4–6px) gives directional read without arrows.'),
|
|
99
|
-
h('p', {}, '· own messages take the accent fill so the eye lands on what you said last; ✓ delivered, ✓✓ read.'),
|
|
100
|
-
h('p', {}, '· markdown is parsed by ', h('code', {}, 'marked'), ' and sanitized by ', h('code', {}, 'DOMPurify'), '; code blocks lit by ', h('code', {}, 'prism.js'), '.')
|
|
101
|
-
)
|
|
102
|
-
})
|
|
103
|
-
)
|
|
104
|
-
],
|
|
105
|
-
status: Status({ left: ['main', '• ' + state.messages.length + ' messages', '• ' + rooms.length + ' rooms'], right: ['247420 / mmxxvi'] })
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const kit = mountKit({ root, view: App, screen: '06 Chat' });
|
|
110
|
-
window.__chat = { state, render: kit.render };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en" class="ds-247420"><head>
|
|
3
|
-
<meta charset="utf-8">
|
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
5
|
-
<meta name="theme-color" content="#247420" media="(prefers-color-scheme: light)">
|
|
6
|
-
<meta name="theme-color" content="#3A9A34" media="(prefers-color-scheme: dark)">
|
|
7
|
-
<meta name="color-scheme" content="light dark">
|
|
8
|
-
<title>chat / 247420</title>
|
|
9
|
-
<meta name="description" content="chat ui kit — message thread + composer, tonal pill bubbles, monospace meta.">
|
|
10
|
-
<link rel="canonical" href="https://anentrypoint.github.io/design/ui_kits/chat/">
|
|
11
|
-
<link rel="icon" type="image/svg+xml" href="../../favicon.svg">
|
|
12
|
-
<link rel="stylesheet" href="../../colors_and_type.css">
|
|
13
|
-
<link rel="stylesheet" href="../../app-shell.css">
|
|
14
|
-
<script type="importmap">
|
|
15
|
-
{ "imports": {
|
|
16
|
-
"webjsx": "../../vendor/webjsx/index.js",
|
|
17
|
-
"webjsx/": "../../vendor/webjsx/",
|
|
18
|
-
"webjsx/jsx-runtime": "../../vendor/webjsx/jsx-runtime.js",
|
|
19
|
-
"ds/": "../../src/"
|
|
20
|
-
} }
|
|
21
|
-
</script>
|
|
22
|
-
</head>
|
|
23
|
-
<body data-screen-label="06 Chat">
|
|
24
|
-
<div id="root"></div>
|
|
25
|
-
<script type="module" src="./app.js"></script>
|
|
26
|
-
</body></html>
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#247420"/><text x="16" y="22" font-family="'JetBrains Mono',ui-monospace,monospace" font-size="14" font-weight="700" fill="#EFE9DD" text-anchor="middle">24</text></svg>
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
%PDF-1.4
|
|
2
|
-
1 0 obj
|
|
3
|
-
<< /Type /Catalog /Pages 2 0 R >>
|
|
4
|
-
endobj
|
|
5
|
-
2 0 obj
|
|
6
|
-
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
|
7
|
-
endobj
|
|
8
|
-
3 0 obj
|
|
9
|
-
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 360 220] /Resources << /Font << /F1 5 0 R >> >> /Contents 4 0 R >>
|
|
10
|
-
endobj
|
|
11
|
-
4 0 obj
|
|
12
|
-
<< /Length 238 >>
|
|
13
|
-
stream
|
|
14
|
-
BT /F1 18 Tf 36 180 Td (design tokens) Tj 0 -28 Td /F1 12 Tf (anentrypoint-design v0.0.26) Tj 0 -22 Td (panel-0 panel-1 panel-2 accent) Tj 0 -22 Td (zero-border, pill radii, mono labels) Tj 0 -38 Td /F1 10 Tf (sample pdf attachment) Tj ET
|
|
15
|
-
endstream
|
|
16
|
-
endobj
|
|
17
|
-
5 0 obj
|
|
18
|
-
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
|
|
19
|
-
endobj
|
|
20
|
-
xref
|
|
21
|
-
0 6
|
|
22
|
-
0000000000 65535 f
|
|
23
|
-
0000000009 00000 n
|
|
24
|
-
0000000058 00000 n
|
|
25
|
-
0000000115 00000 n
|
|
26
|
-
0000000241 00000 n
|
|
27
|
-
0000000530 00000 n
|
|
28
|
-
trailer
|
|
29
|
-
<< /Size 6 /Root 1 0 R >>
|
|
30
|
-
startxref
|
|
31
|
-
600
|
|
32
|
-
%%EOF
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import * as webjsx from 'webjsx';
|
|
2
|
-
import { Topbar, Crumb, Status } from 'ds/components.js';
|
|
3
|
-
import {
|
|
4
|
-
CommunityShell, ServerRail, ChannelSidebar,
|
|
5
|
-
MemberList, ChatHeader, VoiceStrip
|
|
6
|
-
} from 'ds/components.js';
|
|
7
|
-
import { mountKit } from 'ds/bootstrap.js';
|
|
8
|
-
import 'ds/index.js';
|
|
9
|
-
const h = webjsx.createElement;
|
|
10
|
-
|
|
11
|
-
const servers = [
|
|
12
|
-
{ id: 's1', name: '247420', active: true },
|
|
13
|
-
{ id: 's2', name: 'design lab' },
|
|
14
|
-
{ id: 's3', name: 'zellous' },
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const categories = [
|
|
18
|
-
{ id: 'cat-general', name: 'GENERAL', position: 0 },
|
|
19
|
-
{ id: 'cat-design', name: 'DESIGN', position: 1 },
|
|
20
|
-
{ id: 'cat-voice', name: 'VOICE CHANNELS', position: 2 },
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const channels = [
|
|
24
|
-
{ id: 'ch1', name: 'welcome', categoryId: 'cat-general', type: 'text', position: 0 },
|
|
25
|
-
{ id: 'ch2', name: 'announcements', categoryId: 'cat-general', type: 'text', position: 1 },
|
|
26
|
-
{ id: 'ch3', name: 'general', categoryId: 'cat-general', type: 'text', position: 2 },
|
|
27
|
-
{ id: 'ch4', name: 'tokens', categoryId: 'cat-design', type: 'text', position: 0 },
|
|
28
|
-
{ id: 'ch5', name: 'components', categoryId: 'cat-design', type: 'text', position: 1 },
|
|
29
|
-
{ id: 'ch6', name: 'lounge', categoryId: 'cat-voice', type: 'voice', position: 0 },
|
|
30
|
-
{ id: 'ch7', name: 'standup', categoryId: 'cat-voice', type: 'voice', position: 1 },
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
const members = [
|
|
34
|
-
{ label: 'online — 3', members: [
|
|
35
|
-
{ identity: 'jordan', name: 'jordan', status: 'online', color: '#3F8A4A' },
|
|
36
|
-
{ identity: 'mai', name: 'mai', status: 'online', color: '#6B3A78' },
|
|
37
|
-
{ identity: 'aicat', name: 'aicat', status: 'online', color: '#F07AA8' },
|
|
38
|
-
]},
|
|
39
|
-
{ label: 'offline — 2', members: [
|
|
40
|
-
{ identity: 'river', name: 'river', status: 'offline' },
|
|
41
|
-
{ identity: 'sage', name: 'sage', status: 'offline' },
|
|
42
|
-
]},
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
const state = {
|
|
46
|
-
activeServer: 's1',
|
|
47
|
-
activeChannel: channels[2],
|
|
48
|
-
collapsedCats: new Set(),
|
|
49
|
-
memberListOpen: false,
|
|
50
|
-
voiceOpen: false,
|
|
51
|
-
muted: false,
|
|
52
|
-
deafened: false,
|
|
53
|
-
messages: [
|
|
54
|
-
{ id: 1, author: 'jordan', color: '#3F8A4A', time: '14:02', text: 'shipped the community shell component. check it out.' },
|
|
55
|
-
{ id: 2, author: 'mai', color: '#6B3A78', time: '14:03', text: 'looks clean. does it handle collapsed cats?' },
|
|
56
|
-
{ id: 3, author: 'aicat', color: '#F07AA8', time: '14:04', text: 'yes — click any category header.' },
|
|
57
|
-
]
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const root = document.getElementById('root');
|
|
61
|
-
|
|
62
|
-
function App() {
|
|
63
|
-
const ch = state.activeChannel;
|
|
64
|
-
const chatContent = h('div', { class: 'ds-community-main' },
|
|
65
|
-
ChatHeader({
|
|
66
|
-
icon: ch.type === 'voice' ? '🔊' : '#',
|
|
67
|
-
name: ch.name,
|
|
68
|
-
topic: ch.type === 'text' ? 'community shell demo — click channels to switch' : null,
|
|
69
|
-
toolbar: [
|
|
70
|
-
h('button', { class: 'btn btn-ghost', onclick: () => { state.memberListOpen = !state.memberListOpen; kit.render(); } },
|
|
71
|
-
state.memberListOpen ? '✕ members' : '◑ members')
|
|
72
|
-
]
|
|
73
|
-
}),
|
|
74
|
-
h('div', { class: 'ds-community-messages' },
|
|
75
|
-
...state.messages.map(m => h('div', { class: 'ds-community-msg', key: String(m.id) },
|
|
76
|
-
h('div', { class: 'ds-community-avatar', style: `background:${m.color || 'var(--panel-3)'}` }, m.author[0].toUpperCase()),
|
|
77
|
-
h('div', { class: 'ds-community-msg-body' },
|
|
78
|
-
h('span', { class: 'ds-community-msg-name', style: `color:${m.color || 'var(--fg)'}` }, m.author),
|
|
79
|
-
h('span', { class: 'ds-community-msg-time' }, m.time),
|
|
80
|
-
h('p', { class: 'ds-community-msg-text' }, m.text)
|
|
81
|
-
)
|
|
82
|
-
))
|
|
83
|
-
)
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
return h('div', { class: 'ds-community-page' },
|
|
87
|
-
Topbar({ brand: '247420', leaf: 'community', items: [['index', '../../'], ['chat', '../chat/'], ['source ↗', 'https://github.com/AnEntrypoint/design']] }),
|
|
88
|
-
CommunityShell({
|
|
89
|
-
serverRailProps: {
|
|
90
|
-
servers,
|
|
91
|
-
activeId: state.activeServer,
|
|
92
|
-
onSelect: (id) => { state.activeServer = id; kit.render(); }
|
|
93
|
-
},
|
|
94
|
-
sidebarProps: {
|
|
95
|
-
serverName: servers.find(s => s.id === state.activeServer)?.name || '247420',
|
|
96
|
-
channels,
|
|
97
|
-
categories,
|
|
98
|
-
activeId: state.activeChannel.id,
|
|
99
|
-
collapsedCats: state.collapsedCats,
|
|
100
|
-
onChannelClick: (ch) => { state.activeChannel = ch; kit.render(); },
|
|
101
|
-
onCategoryToggle: (id) => {
|
|
102
|
-
state.collapsedCats.has(id) ? state.collapsedCats.delete(id) : state.collapsedCats.add(id);
|
|
103
|
-
kit.render();
|
|
104
|
-
},
|
|
105
|
-
userPanelProps: {
|
|
106
|
-
name: 'you',
|
|
107
|
-
tag: '◰',
|
|
108
|
-
color: '#247420',
|
|
109
|
-
muted: state.muted,
|
|
110
|
-
deafened: state.deafened,
|
|
111
|
-
onMute: () => { state.muted = !state.muted; kit.render(); },
|
|
112
|
-
onDeafen: () => { state.deafened = !state.deafened; kit.render(); },
|
|
113
|
-
onSettings: () => {}
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
children: chatContent,
|
|
117
|
-
memberListProps: { categories: members, open: state.memberListOpen },
|
|
118
|
-
voiceStripProps: state.voiceOpen ? {
|
|
119
|
-
channelName: 'lounge',
|
|
120
|
-
status: 'connected',
|
|
121
|
-
muted: state.muted,
|
|
122
|
-
deafened: state.deafened,
|
|
123
|
-
onMute: () => { state.muted = !state.muted; kit.render(); },
|
|
124
|
-
onDeafen: () => { state.deafened = !state.deafened; kit.render(); },
|
|
125
|
-
onLeave: () => { state.voiceOpen = false; kit.render(); },
|
|
126
|
-
open: true
|
|
127
|
-
} : null
|
|
128
|
-
}),
|
|
129
|
-
Status({ left: ['community', '• ' + channels.length + ' channels', '• ' + servers.length + ' servers'], right: ['247420 / mmxxvi'] })
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const kit = mountKit({ root, view: App, screen: '07 Community' });
|
|
134
|
-
window.__community = { state, render: kit.render };
|