eidotter 0.19.3 → 0.20.1
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 +133 -186
- package/dist/components/Brand/components/BrandLockup.d.ts +20 -0
- package/dist/components/Brand/components/Logo.d.ts +25 -0
- package/dist/components/Brand/components/Wordmark.d.ts +16 -0
- package/dist/components/Brand/components/index.d.ts +6 -0
- package/dist/components/Brand/index.d.ts +1 -0
- package/dist/components/CmdPalette/components/CmdPalette.d.ts +54 -0
- package/dist/components/CmdPalette/components/index.d.ts +2 -0
- package/dist/components/CmdPalette/index.d.ts +2 -0
- package/dist/components/DosFigure/components/DosFigure.d.ts +41 -0
- package/dist/components/DosFigure/components/index.d.ts +2 -0
- package/dist/components/DosFigure/index.d.ts +2 -0
- package/dist/components/InlineLink/components/InlineLink.d.ts +36 -0
- package/dist/components/InlineLink/components/index.d.ts +2 -0
- package/dist/components/InlineLink/index.d.ts +2 -0
- package/dist/eidotter.css +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.es.js +7200 -6958
- package/dist/index.umd.js +14 -14
- package/guidelines/README.md +5 -1
- package/package.json +10 -2
- package/src/styles/dos-utilities.css +197 -0
- package/src/styles/theme.amber-mono.css +1 -0
- package/src/styles/theme.cga-amber.css +1 -0
- package/src/styles/theme.cga-mode4-p0.css +1 -0
- package/src/styles/theme.cga-mode4-p1.css +1 -0
- package/src/styles/theme.cga-mode5.css +1 -0
- package/src/styles/tokens.css +1 -0
- package/tailwind.preset.cjs +1 -0
package/README.md
CHANGED
|
@@ -1,23 +1,42 @@
|
|
|
1
|
-
# eiDotter
|
|
1
|
+
# eiDotter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```
|
|
4
|
+
┌──────────────────────────────────────────────┐
|
|
5
|
+
│ C:\> EIDOTTER_ │
|
|
6
|
+
│ │
|
|
7
|
+
│ DOS terminal design system for React. │
|
|
8
|
+
│ Authentic CGA phosphor. WCAG AA. │
|
|
9
|
+
│ Tree-shakable. No CSS-in-JS runtime. │
|
|
10
|
+
└──────────────────────────────────────────────┘
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
[](https://www.npmjs.com/package/eidotter)
|
|
14
|
+
[](https://github.com/CinimoDY/eiDotter/actions/workflows/build.yml)
|
|
15
|
+
[](./LICENSE.md)
|
|
16
|
+
[](https://react.dev/)
|
|
17
|
+
|
|
18
|
+
**eiDotter** is a React component library that takes the DOS/CGA terminal aesthetic seriously: authentic 16-color palette, bitmap-accurate typography, phosphor glow physics, keyboard-first interactions. 36 components across forms, navigation, windowing, timelines, and terminal chrome — shipped as ES modules with a prebuilt stylesheet so consumers don't need Tailwind to use it.
|
|
19
|
+
|
|
20
|
+
→ **[Storybook](https://cinimody.github.io/eiDotter/)** · **[CHANGELOG](./CHANGELOG.md)** · **[Issues](https://github.com/CinimoDY/eiDotter/issues)** · **[npm](https://www.npmjs.com/package/eidotter)**
|
|
21
|
+
|
|
22
|
+
---
|
|
4
23
|
|
|
5
|
-
##
|
|
24
|
+
## Install
|
|
6
25
|
|
|
7
26
|
```bash
|
|
8
27
|
npm install eidotter
|
|
9
28
|
```
|
|
10
29
|
|
|
11
|
-
## Quick
|
|
30
|
+
## Quick start
|
|
12
31
|
|
|
13
32
|
```tsx
|
|
14
|
-
import { Terminal,
|
|
15
|
-
import 'eidotter/styles';
|
|
33
|
+
import { Terminal, Alert, Button } from 'eidotter';
|
|
34
|
+
import 'eidotter/styles';
|
|
16
35
|
|
|
17
36
|
function App() {
|
|
18
37
|
return (
|
|
19
38
|
<Terminal title="MY-APP.EXE">
|
|
20
|
-
<Alert
|
|
39
|
+
<Alert color="success" title="System Ready">
|
|
21
40
|
DOS interface loaded successfully.
|
|
22
41
|
</Alert>
|
|
23
42
|
<Button variant="primary">Execute</Button>
|
|
@@ -26,246 +45,174 @@ function App() {
|
|
|
26
45
|
}
|
|
27
46
|
```
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
### Basic (no Tailwind needed)
|
|
32
|
-
|
|
33
|
-
Import the styles. All component styling, fonts, and design tokens are pre-compiled — no build tools required.
|
|
34
|
-
|
|
35
|
-
```tsx
|
|
36
|
-
import 'eidotter/styles'; // Fonts, tokens, components, Tailwind utilities
|
|
48
|
+
A single CSS import pulls everything: font, tokens, component styles, and compiled Tailwind utilities. Tailwind is **not** required to use eiDotter — consume it as plain React + one stylesheet.
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
import 'eidotter/themes/amber-mono.css';
|
|
40
|
-
```
|
|
50
|
+
## Setup
|
|
41
51
|
|
|
42
|
-
|
|
52
|
+
### Styles
|
|
43
53
|
|
|
44
54
|
```tsx
|
|
45
|
-
import 'eidotter/
|
|
46
|
-
import 'eidotter/
|
|
47
|
-
import 'eidotter/
|
|
55
|
+
import 'eidotter/styles'; // Everything: font + tokens + components + utilities
|
|
56
|
+
import 'eidotter/themes/amber-mono.css'; // Optional: theme override
|
|
57
|
+
import 'eidotter/utilities'; // Optional: .dos-* typography classes for raw HTML
|
|
48
58
|
```
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Two fontFamily tokens are exported, with distinct intent:
|
|
60
|
+
Granular imports are still available (`eidotter/fonts.css`, `eidotter/tokens.css`) if you want to override the font or tokens independently.
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
- **`font-dos-fallback`** → `monospace` only — intentionally bare, as a **fail-loud diagnostic** utility for surfaces that want to surface font-loading failures explicitly. Compose `font-dos font-dos-fallback` when you want strict Flexi-or-nothing behavior.
|
|
62
|
+
### With Tailwind
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Use eidotter's design tokens as Tailwind utility classes in your own code.
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
npm install tailwindcss
|
|
63
|
-
```
|
|
64
|
+
If you already use Tailwind, register eiDotter's preset and drop the `eidotter/styles` import (the preset compiles utilities in your build):
|
|
64
65
|
|
|
65
66
|
```js
|
|
66
67
|
// tailwind.config.js
|
|
67
68
|
module.exports = {
|
|
68
69
|
presets: [require('eidotter/tailwind.preset')],
|
|
69
|
-
content: ['./src/**/*.{
|
|
70
|
+
content: ['./src/**/*.{ts,tsx,jsx}'],
|
|
70
71
|
};
|
|
71
72
|
```
|
|
72
73
|
|
|
73
74
|
```tsx
|
|
74
|
-
// Now use eidotter tokens as Tailwind classes
|
|
75
75
|
<div className="bg-dos-bg-primary text-dos-text-accent font-dos">
|
|
76
76
|
DOS terminal content
|
|
77
77
|
</div>
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
The preset auto-registers `tailwindcss-react-aria-components` and `tailwindcss-animate`
|
|
80
|
+
The preset auto-registers `tailwindcss-react-aria-components` and `tailwindcss-animate` if they resolve. Migrating from the pre-0.19.2 dual-preset split? See [CHANGELOG → 0.19.2](./CHANGELOG.md#0192--2026-04-18).
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
## Documentation
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
| | |
|
|
85
|
+
|---|---|
|
|
86
|
+
| **Live docs** | [Storybook](https://cinimody.github.io/eiDotter/) — every component with stories, controls, and source |
|
|
87
|
+
| **Design tokens** | `src/tokens/*.json` (DTCG format) → `tokens.css` via Style Dictionary |
|
|
88
|
+
| **Themes** | `amber-mono` (default), `cga-amber`, `cga-mode4-p0/p1`, `cga-mode5` |
|
|
89
|
+
| **Font** | [Flexi IBM VGA True v2](https://int10h.org/blog/2018/05/flexi-ibm-vga-scalable-truetype-font/) — aspect-corrected vector remake of the IBM VGA BIOS, CC BY-SA 4.0. Bitmap-authentic single-weight; all `fontWeight` tokens resolve to 400 |
|
|
90
|
+
| **Icons** | [pixelarticons](https://github.com/halfmage/pixelarticons) (MIT) — DOS pixel-art glyphs |
|
|
91
|
+
| **Accessibility** | WCAG AA, React Aria primitives under interactive components, `prefers-reduced-motion` + `prefers-contrast` honored throughout |
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
- presets: [require('eidotter/tailwind.preset.enhanced')]
|
|
88
|
-
+ presets: [require('eidotter/tailwind.preset')]
|
|
89
|
-
```
|
|
93
|
+
## Components
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
## Available Components (33)
|
|
94
|
-
|
|
95
|
-
| Component | Description |
|
|
96
|
-
|-----------|-------------|
|
|
97
|
-
| Accordion | Collapsible content sections (Section, AccordionFill) |
|
|
98
|
-
| Alert | Inline alert banner with featured icon, actions, and 6 color variants |
|
|
99
|
-
| Badge | Status indicators with variant support |
|
|
100
|
-
| Breadcrumb | Navigation path display |
|
|
101
|
-
| Button | DOS-style buttons (primary, secondary, ghost, link) |
|
|
102
|
-
| Card | Content container with variants (elevated, bordered, glow, interactive, minimal, callout) |
|
|
103
|
-
| ChatMessage | Chat message with role-based DOS styling and streaming cursor |
|
|
104
|
-
| ChatHistory | Scrollable message list with auto-scroll and `role="log"` |
|
|
105
|
-
| ChatInput | Multiline textarea with Enter-to-send |
|
|
106
|
-
| ChatContainer | Composes ChatHistory + ChatInput — place inside Terminal for DOS chat |
|
|
107
|
-
| Checkbox | DOS-style checkbox with `[X]` bracket indicator |
|
|
108
|
-
| CommandPrompt | Interactive command-line input with blinking cursor |
|
|
109
|
-
| FilterBar | Multi-select toggle group for faceted filtering |
|
|
110
|
-
| Footer | Site footer with legal links (Impressum + Datenschutz) |
|
|
111
|
-
| Header | Sticky site header composing branding + Nav — retro/modern variants |
|
|
112
|
-
| Icon | SVG icons backed by pixelarticons (MIT) — authentic DOS pixel art |
|
|
113
|
-
| InlineExpand | Inline disclosure widget for expanding text within prose |
|
|
114
|
-
| Input | Text input with DOS styling and error variant |
|
|
115
|
-
| Modal | Dialog overlay with title bar and close button |
|
|
116
|
-
| Nav | Responsive navigation with desktop/mobile variants |
|
|
117
|
-
| Notification | Toast popup with layered amber glow, auto-dismiss, and progress variant |
|
|
118
|
-
| Progress | DOS-style progress bar with block characters |
|
|
119
|
-
| RetroEffects | CRT effects (scanlines, noise, phosphor glow) |
|
|
120
|
-
| Separator | Horizontal/vertical divider |
|
|
121
|
-
| Stat | Key-value display for metrics and statistics |
|
|
122
|
-
| Switch | Toggle switch for on/off states |
|
|
123
|
-
| Tabs | Tabbed interface navigation |
|
|
124
|
-
| Tag | Interactive labels for tags, categories, and filter chips |
|
|
125
|
-
| Terminal | DOS window with title bar and content area |
|
|
126
|
-
| TextScramble | DOS text decode/scramble animation effect |
|
|
127
|
-
| TimelineContainer | Multi-zoom timeline with year/month/day/hour views |
|
|
128
|
-
| TimelineNode | Timeline/stepper axis markers with shapes and glow |
|
|
129
|
-
| Tokens | Design token reference display (Storybook only) |
|
|
130
|
-
|
|
131
|
-
## Component Examples
|
|
132
|
-
|
|
133
|
-
### Header
|
|
95
|
+
36 components across five families — [complete catalog in Storybook](https://cinimody.github.io/eiDotter/).
|
|
134
96
|
|
|
135
|
-
|
|
136
|
-
<Header
|
|
137
|
-
{/* or use children for custom branding */}
|
|
138
|
-
</Header>
|
|
139
|
-
```
|
|
97
|
+
<details>
|
|
98
|
+
<summary><strong>Windowing & shell</strong> — Terminal, Modal, CommandPrompt, CmdPalette, Header, Footer, Nav</summary>
|
|
140
99
|
|
|
141
|
-
|
|
100
|
+
| Component | Purpose |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `Terminal` | DOS window with title bar, minimize/maximize/close controls |
|
|
103
|
+
| `Modal` | Dialog overlay on React Aria primitives (ModalOverlay + Modal + Dialog) |
|
|
104
|
+
| `CommandPrompt` | Interactive command-line input with blinking cursor |
|
|
105
|
+
| `CmdPalette` | ⌘K overlay with scored search, keyboard nav, configurable hotkey |
|
|
106
|
+
| `Header` | Sticky site header (retro / modern variants), composes branding + Nav |
|
|
107
|
+
| `Footer` | Site footer with default legal links (Impressum + Datenschutz) |
|
|
108
|
+
| `Nav` | Responsive navigation with desktop + mobile variants |
|
|
142
109
|
|
|
143
|
-
|
|
144
|
-
<Terminal
|
|
145
|
-
title="PROGRAM.EXE"
|
|
146
|
-
size="medium"
|
|
147
|
-
closeable
|
|
148
|
-
onClose={() => console.log('closed')}
|
|
149
|
-
>
|
|
150
|
-
<p>Terminal content here</p>
|
|
151
|
-
</Terminal>
|
|
152
|
-
```
|
|
110
|
+
</details>
|
|
153
111
|
|
|
154
|
-
|
|
112
|
+
<details>
|
|
113
|
+
<summary><strong>Content surfaces</strong> — Card, Accordion, Alert, Badge, Tag, Notification, Stat, Progress, Separator, Breadcrumb</summary>
|
|
155
114
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
115
|
+
| Component | Purpose |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `Card` | Content container (elevated, bordered, glow, interactive, minimal, callout) |
|
|
118
|
+
| `Accordion` | Collapsible content sections (Section + AccordionFill) |
|
|
119
|
+
| `Alert` | Inline alert banner with featured icon, actions, 6 color variants |
|
|
120
|
+
| `Badge` | Status indicator chips |
|
|
121
|
+
| `Tag` | Interactive labels for tags, categories, filter chips |
|
|
122
|
+
| `Notification` | Toast popup with layered amber glow, auto-dismiss, progress variant |
|
|
123
|
+
| `Stat` | Key-value display for metrics |
|
|
124
|
+
| `Progress` | DOS-style progress bar with block characters |
|
|
125
|
+
| `Separator` | Horizontal / vertical divider |
|
|
126
|
+
| `Breadcrumb` | Navigation path display |
|
|
160
127
|
|
|
161
|
-
|
|
162
|
-
Processing...
|
|
163
|
-
</Button>
|
|
164
|
-
```
|
|
128
|
+
</details>
|
|
165
129
|
|
|
166
|
-
|
|
130
|
+
<details>
|
|
131
|
+
<summary><strong>Input</strong> — Button, Input, Checkbox, Switch, Tabs, FilterBar</summary>
|
|
167
132
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
```
|
|
133
|
+
| Component | Purpose |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `Button` | DOS-style buttons (primary, secondary, ghost, link) on React Aria `Button` |
|
|
136
|
+
| `Input` | Text input with error variant, React Aria `TextField` |
|
|
137
|
+
| `Checkbox` | `[X]`-bracket indicator, React Aria `Checkbox` |
|
|
138
|
+
| `Switch` | Toggle on/off, React Aria `Switch` |
|
|
139
|
+
| `Tabs` | Tabbed navigation on React Aria `TabList/Tab/TabPanel` |
|
|
140
|
+
| `FilterBar` | Multi-select toggle group for faceted filtering |
|
|
177
141
|
|
|
178
|
-
|
|
142
|
+
</details>
|
|
179
143
|
|
|
180
|
-
|
|
181
|
-
<
|
|
182
|
-
label="Filename"
|
|
183
|
-
placeholder="Enter filename..."
|
|
184
|
-
/>
|
|
185
|
-
|
|
186
|
-
<Input
|
|
187
|
-
variant="error"
|
|
188
|
-
errorMessage="File not found"
|
|
189
|
-
placeholder="Invalid path"
|
|
190
|
-
/>
|
|
191
|
-
```
|
|
144
|
+
<details>
|
|
145
|
+
<summary><strong>Chat & media</strong> — ChatMessage, ChatHistory, ChatInput, ChatContainer, DosFigure, Icon, InlineLink, InlineExpand</summary>
|
|
192
146
|
|
|
193
|
-
|
|
147
|
+
| Component | Purpose |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `ChatMessage` | Chat message with role-based DOS styling and streaming cursor |
|
|
150
|
+
| `ChatHistory` | Scrollable message list with auto-scroll + `role="log"` |
|
|
151
|
+
| `ChatInput` | Multiline textarea with Enter-to-send |
|
|
152
|
+
| `ChatContainer` | Composes ChatHistory + ChatInput — drop inside Terminal |
|
|
153
|
+
| `DosFigure` | Demoscene painted-screen media placeholder with scanline sweep |
|
|
154
|
+
| `Icon` | SVG icons backed by pixelarticons |
|
|
155
|
+
| `InlineLink` | In-flow anchor with dotted underline + `▸` / `↗` glyph |
|
|
156
|
+
| `InlineExpand` | Inline disclosure widget for prose |
|
|
194
157
|
|
|
195
|
-
|
|
196
|
-
<Checkbox label="Remember me" />
|
|
197
|
-
<Checkbox label="Accept terms" checked />
|
|
198
|
-
<Checkbox label="Select all" indeterminate />
|
|
199
|
-
```
|
|
158
|
+
</details>
|
|
200
159
|
|
|
201
|
-
|
|
160
|
+
<details>
|
|
161
|
+
<summary><strong>Time & effects</strong> — TimelineContainer, TimelineNode, TextScramble, RetroEffects, Tokens</summary>
|
|
202
162
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
163
|
+
| Component | Purpose |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `TimelineContainer` | Multi-zoom timeline (year / month / day / hour views) |
|
|
166
|
+
| `TimelineNode` | Axis markers with shape variants and glow |
|
|
167
|
+
| `TextScramble` | DOS text decode animation |
|
|
168
|
+
| `RetroEffects` | CRT scanlines, noise, phosphor glow |
|
|
169
|
+
| `Tokens` | Design-token reference display (Storybook only) |
|
|
210
170
|
|
|
211
|
-
|
|
171
|
+
</details>
|
|
212
172
|
|
|
213
|
-
|
|
173
|
+
## Design tokens
|
|
174
|
+
|
|
175
|
+
Authentic 16-color CGA palette plus amber/phosphor variants, exposed as CSS custom properties:
|
|
214
176
|
|
|
215
177
|
```css
|
|
216
|
-
--color-cga-amber: #FFB000;
|
|
178
|
+
--color-cga-amber: #FFB000; /* Primary accent */
|
|
217
179
|
--color-cga-amber-bright: #FDCA9F;
|
|
218
180
|
--color-cga-amber-dim: #9A5700;
|
|
219
|
-
--color-cga-black: #020003;
|
|
220
|
-
/*
|
|
181
|
+
--color-cga-black: #020003; /* Background */
|
|
182
|
+
/* …16-color CGA palette + semantic tokens */
|
|
221
183
|
```
|
|
222
184
|
|
|
223
|
-
|
|
185
|
+
Semantic tokens (`--color-semantic-*`) and Tailwind classes (`bg-dos-*`, `text-dos-*`, `border-dos-*`) are the preferred surface — the raw CGA names are primitives. Full reference in [`src/styles/tokens.css`](./src/styles/tokens.css) or in Storybook's Tokens page.
|
|
224
186
|
|
|
225
|
-
|
|
187
|
+
**Theming** is attribute-driven:
|
|
226
188
|
|
|
227
189
|
```html
|
|
228
|
-
<div data-theme="amber-mono">
|
|
229
|
-
<!-- Amber-on-black terminal aesthetic -->
|
|
230
|
-
</div>
|
|
190
|
+
<div data-theme="amber-mono">…</div>
|
|
231
191
|
```
|
|
232
192
|
|
|
233
|
-
Available themes: `amber-mono`, `cga-amber`, `cga-mode4-p0`, `cga-mode4-p1`, `cga-mode5`.
|
|
234
|
-
|
|
235
|
-
### Tailwind Token Classes
|
|
236
|
-
|
|
237
|
-
**CGA Colors:** `cga-black`, `cga-blue`, `cga-green`, `cga-cyan`, `cga-red`, `cga-magenta`, `cga-brown`, `cga-light-gray`, `cga-dark-gray`, `cga-bright-blue`, `cga-bright-green`, `cga-bright-cyan`, `cga-bright-red`, `cga-bright-magenta`, `cga-yellow`, `cga-white`, `cga-amber`, `cga-amber-bright`, `cga-amber-dim`
|
|
238
|
-
|
|
239
|
-
**Semantic Colors:** `dos-bg-primary`, `dos-bg-secondary`, `dos-text-primary`, `dos-text-accent`, `dos-border-default`, `dos-border-focus`, `dos-success`, `dos-warning`, `dos-error`, `dos-info`
|
|
240
|
-
|
|
241
|
-
**Typography:** `font-dos` (Flexi IBM VGA True v2), `text-dos-text-xs` through `text-dos-display-2xl`, `leading-dos-text-xs` through `leading-dos-display-2xl`
|
|
242
|
-
|
|
243
|
-
**Spacing:** 4px grid via design tokens
|
|
244
|
-
|
|
245
|
-
**Border Radius:** `rounded-dos-sm` (2px), `rounded-dos-base` (4px max)
|
|
246
|
-
|
|
247
193
|
## Development
|
|
248
194
|
|
|
249
195
|
```bash
|
|
250
|
-
npm install
|
|
251
|
-
npm run storybook
|
|
252
|
-
npm run build
|
|
253
|
-
npm run test
|
|
254
|
-
npm run lint
|
|
196
|
+
npm install
|
|
197
|
+
npm run storybook # Launch Storybook on :6006
|
|
198
|
+
npm run build # Production build (tsup + tsc)
|
|
199
|
+
npm run test # Jest + React Testing Library
|
|
200
|
+
npm run lint # ESLint
|
|
201
|
+
npm run build-tokens # Rebuild tokens from src/tokens/*.json
|
|
255
202
|
```
|
|
256
203
|
|
|
257
|
-
## Design
|
|
258
|
-
|
|
259
|
-
The DOS aesthetic represents values we've lost in modern software:
|
|
204
|
+
## Design notes
|
|
260
205
|
|
|
261
|
-
|
|
262
|
-
- **Clarity** - Information presented without distraction
|
|
263
|
-
- **Personal Sovereignty** - Your tools, your way
|
|
206
|
+
eiDotter commits to the constraints that other "DOS-inspired" systems relax:
|
|
264
207
|
|
|
265
|
-
|
|
208
|
+
- **16 colors, no more.** The palette is a historical fact, not a starting point. Extensions (amber, green, phosphor variants) are declared themes, not ad-hoc hex codes.
|
|
209
|
+
- **Single-weight typography.** Flexi IBM VGA True is a bitmap font; there's no bold. All `fontWeight` tokens resolve to `400` and `font-synthesis: none` blocks browser faux-bold. Emphasis comes from color, uppercase on labels, or inverse video — never weight.
|
|
210
|
+
- **Phosphor as physics, not decoration.** Warmup animations, glow layers, and scanline effects are wired into component states; consumers don't opt in per-component.
|
|
211
|
+
- **Keyboard-first.** React Aria powers every interactive component. Focus rings are loud amber on amber-dim. `prefers-reduced-motion` and `prefers-contrast` are honored across the board.
|
|
212
|
+
- **Tree-shakable, no CSS-in-JS.** Runtime deps are minimal and on-purpose: [React Aria](https://react-spectrum.adobe.com/react-aria/) + [pixelarticons](https://github.com/halfmage/pixelarticons), both MIT. Component CSS ships compiled; you pay no CSS-in-JS cost at runtime.
|
|
266
213
|
|
|
267
|
-
|
|
214
|
+
The aesthetic is a constraint the system holds itself to — not a theme that can be turned off.
|
|
268
215
|
|
|
269
216
|
## License
|
|
270
217
|
|
|
271
|
-
CC-BY-NC-4.0
|
|
218
|
+
[CC-BY-NC-4.0](./LICENSE.md) — Creative Commons Attribution-NonCommercial 4.0 International. Bundled third-party licenses (pixelarticons MIT, Flexi IBM VGA True CC BY-SA 4.0) attributed in `LICENSE.md`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
export interface BrandLockupProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** Logo size in pixels. Defaults to 32. */
|
|
5
|
+
logoSize?: number | string;
|
|
6
|
+
/** Render only the logo (no wordmark). */
|
|
7
|
+
iconOnly?: boolean;
|
|
8
|
+
/** Render only the wordmark (no logo). */
|
|
9
|
+
wordmarkOnly?: boolean;
|
|
10
|
+
/** Add amber phosphor glow on both logo + wordmark. Defaults to true. */
|
|
11
|
+
glow?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* eiDotter brand lockup — Logo + Wordmark composed horizontally.
|
|
15
|
+
*
|
|
16
|
+
* The canonical public-facing brand mark. Scales by setting the host's
|
|
17
|
+
* `font-size` (wordmark) and `logoSize` prop (icon). The two should stay
|
|
18
|
+
* proportional: roughly `logoSize ≈ font-size × 1.75`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const BrandLockup: React.ForwardRefExoticComponent<BrandLockupProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SVGProps } from 'react';
|
|
3
|
+
import './Brand.css';
|
|
4
|
+
export interface LogoProps extends Omit<SVGProps<SVGSVGElement>, 'viewBox' | 'children'> {
|
|
5
|
+
/** Icon size in pixels. Defaults to 32. Pass a number or CSS-valid string. */
|
|
6
|
+
size?: number | string;
|
|
7
|
+
/** Add the amber phosphor drop-shadow glow. Defaults to true. */
|
|
8
|
+
glow?: boolean;
|
|
9
|
+
/** Accessible label. Defaults to "eiDotter". Set to empty string for decorative use. */
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* eiDotter brand mark — V2 yolk (pure, no legs).
|
|
14
|
+
*
|
|
15
|
+
* The "payload" of the eiDotter identity — a bright CGA amber yolk with a soft
|
|
16
|
+
* highlight and specular, no shell or drip ornamentation. Scales cleanly from
|
|
17
|
+
* 16px (favicon) to hero sizes without the 1px shell outline collapsing into
|
|
18
|
+
* mush at small sizes.
|
|
19
|
+
*
|
|
20
|
+
* Fill colors are brand-locked (explicit amber hexes) rather than themed so the
|
|
21
|
+
* mark reads identically across themes. Consumers who need a non-amber treatment
|
|
22
|
+
* can override the SVG fills via the `style` prop or by recoloring the child
|
|
23
|
+
* `<circle>` elements through a CSS selector.
|
|
24
|
+
*/
|
|
25
|
+
export declare const Logo: React.ForwardRefExoticComponent<Omit<LogoProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import './Brand.css';
|
|
4
|
+
export interface WordmarkProps extends HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
/** Add the amber phosphor text-shadow glow. Defaults to true. */
|
|
6
|
+
glow?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* eiDotter wordmark — "eiDotter" with the "ei" prefix dimmed against the full-bright "Dotter".
|
|
10
|
+
*
|
|
11
|
+
* Uses the primary DOS font (Flexi IBM VGA True) and the amber phosphor palette.
|
|
12
|
+
* Sized via `font-size` on the host; the component does not set its own size by
|
|
13
|
+
* default so it inherits from the surrounding type scale. Wrap in a heading
|
|
14
|
+
* element if you need semantic weight.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Wordmark: React.ForwardRefExoticComponent<WordmarkProps & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './CmdPalette.css';
|
|
3
|
+
export interface CmdPaletteItem {
|
|
4
|
+
/** Stable identifier for React keys and `onSelect` lookups. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Primary label shown in the list. Uppercase recommended. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Optional secondary hint shown on the right (shortcut, type, etc.). */
|
|
9
|
+
hint?: React.ReactNode;
|
|
10
|
+
/** Additional keywords that contribute to search matching. */
|
|
11
|
+
keywords?: string[];
|
|
12
|
+
/** Optional type tag used for grouping/filtering by callers. */
|
|
13
|
+
type?: string;
|
|
14
|
+
/** Called when the item is activated via click or Enter. */
|
|
15
|
+
onSelect?: (item: CmdPaletteItem) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface CmdPaletteProps {
|
|
18
|
+
/** Controlled open state. */
|
|
19
|
+
open: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Called when the overlay requests open/close (Escape, backdrop click,
|
|
22
|
+
* item selection, hotkey toggle).
|
|
23
|
+
*/
|
|
24
|
+
onOpenChange: (open: boolean) => void;
|
|
25
|
+
/** Items to search. Pure data — parent owns the list. */
|
|
26
|
+
items: CmdPaletteItem[];
|
|
27
|
+
/** Input placeholder. */
|
|
28
|
+
placeholder?: string;
|
|
29
|
+
/** Global activation hotkey. `"mod+k"`, `"mod+shift+p"`, or `false` to disable. */
|
|
30
|
+
hotkey?: string | false;
|
|
31
|
+
/** Message shown when search matches nothing. */
|
|
32
|
+
emptyMessage?: React.ReactNode;
|
|
33
|
+
/** Footer hint row text / JSX. Pass `null` to hide. */
|
|
34
|
+
footerHint?: React.ReactNode;
|
|
35
|
+
/** Custom renderer for each row. Falls back to label + hint. */
|
|
36
|
+
renderItem?: (item: CmdPaletteItem, isSelected: boolean) => React.ReactNode;
|
|
37
|
+
/** Cap on filtered result rows. */
|
|
38
|
+
maxResults?: number;
|
|
39
|
+
/** Extra class names merged onto the dialog container. */
|
|
40
|
+
className?: string;
|
|
41
|
+
/** Accessible dialog label. */
|
|
42
|
+
'aria-label'?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* CmdPalette — ⌘K / Ctrl+K launcher overlay.
|
|
46
|
+
*
|
|
47
|
+
* Controlled component. Parent owns `open` and item list; CmdPalette handles
|
|
48
|
+
* search, keyboard navigation, focus management, and hotkey binding.
|
|
49
|
+
*
|
|
50
|
+
* Built on React Aria `ModalOverlay` + `Modal` + `Dialog` — same primitives
|
|
51
|
+
* as `<Modal>` — so focus trap, Esc-to-close, and backdrop dismissal are
|
|
52
|
+
* standard.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CmdPalette: React.ForwardRefExoticComponent<CmdPaletteProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './DosFigure.css';
|
|
3
|
+
export interface DosFigurePin {
|
|
4
|
+
/** Horizontal position as a percentage (0–100). */
|
|
5
|
+
x: number;
|
|
6
|
+
/** Vertical position as a percentage (0–100). */
|
|
7
|
+
y: number;
|
|
8
|
+
/** Pin label — short; renders next to the dot. */
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
export interface DosFigureProps {
|
|
12
|
+
/** Title shown in the top chrome strip. Uppercase recommended. */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Resolution tag rendered bottom-right (e.g. `"640×480"`). */
|
|
15
|
+
resolution?: string;
|
|
16
|
+
/** Subject content — ASCII, SVG, or anything you'd "paint the screen" with. */
|
|
17
|
+
subject: React.ReactNode;
|
|
18
|
+
/** Caption rendered beneath the frame via `<figcaption>`. */
|
|
19
|
+
caption?: React.ReactNode;
|
|
20
|
+
/** Optional annotation pins positioned as percentages over the subject. */
|
|
21
|
+
pins?: DosFigurePin[];
|
|
22
|
+
/** Disables the scanline-sweep animation. Defaults to true (enabled). */
|
|
23
|
+
animated?: boolean;
|
|
24
|
+
/** Accessible label when `subject` has no inherent semantics. */
|
|
25
|
+
'aria-label'?: string;
|
|
26
|
+
/** Extra class names merged onto the `<figure>` root. */
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* DosFigure — demoscene-style placeholder for media.
|
|
31
|
+
*
|
|
32
|
+
* Sierra / LucasArts / demoscene title cards painted the screen with a
|
|
33
|
+
* limited palette, dithering, and annotated frames. DosFigure recreates
|
|
34
|
+
* that aesthetic: amber chrome, scanline sweep, optional pins, and a
|
|
35
|
+
* resolution tag. Use as a lead-in for blog articles or as a placeholder
|
|
36
|
+
* where a photograph would otherwise go.
|
|
37
|
+
*
|
|
38
|
+
* Not intended as a replacement for semantic imagery — pass `aria-label`
|
|
39
|
+
* (or a `<figcaption>` via `caption`) so the figure is meaningful to AT.
|
|
40
|
+
*/
|
|
41
|
+
export declare const DosFigure: React.ForwardRefExoticComponent<DosFigureProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './InlineLink.css';
|
|
3
|
+
export interface InlineLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> {
|
|
4
|
+
/** Link text. */
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/** Target URL. */
|
|
7
|
+
href: string;
|
|
8
|
+
/**
|
|
9
|
+
* Render the trailing glyph (`▸` for internal, `↗` for `external`).
|
|
10
|
+
* Defaults to `true`. When `false`, no glyph renders regardless of the
|
|
11
|
+
* `external` prop.
|
|
12
|
+
*/
|
|
13
|
+
showGlyph?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* External link — adds `target="_blank"` and `rel="noopener noreferrer"`
|
|
16
|
+
* (safe tabnabbing defaults) and, when `showGlyph` is `true`, swaps the
|
|
17
|
+
* trailing glyph to `↗`. `showGlyph={false}` still suppresses the glyph.
|
|
18
|
+
*/
|
|
19
|
+
external?: boolean;
|
|
20
|
+
/** Extra class names merged onto the root anchor. */
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* In-flow navigational anchor. Distinct from `<InlineExpand>` — this is a
|
|
25
|
+
* destination, not a disclosure.
|
|
26
|
+
*
|
|
27
|
+
* Rest: dotted amber underline, trailing `▸`.
|
|
28
|
+
* Hover: phosphor inversion — amber background, dark foreground.
|
|
29
|
+
* Visited: dimmed amber (`--color-cga-amber-dim` → brown fallback).
|
|
30
|
+
* External: opens in a new tab safely, trailing glyph becomes `↗`.
|
|
31
|
+
*
|
|
32
|
+
* Consumer-passed `target="_blank"` is treated as implicit-external for
|
|
33
|
+
* `rel` safety — a `rel` is auto-applied if none is provided, preventing
|
|
34
|
+
* tabnabbing even when the caller doesn't explicitly set `external`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const InlineLink: React.ForwardRefExoticComponent<InlineLinkProps & React.RefAttributes<HTMLAnchorElement>>;
|