terminal-element 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Akinori Hoshina
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # terminal-element
2
+
3
+ ![demo](https://github.com/user-attachments/assets/7e96e50f-ca82-4bd5-a5e2-0a215ae30b12)
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![codecov](https://codecov.io/gh/spider-hand/terminal-element/graph/badge.svg?token=3TNWF0ZMDS)](https://codecov.io/gh/spider-hand/terminal-element) ![Lit](https://img.shields.io/badge/lit-%23324FFF.svg?&logo=lit&logoColor=white)
6
+
7
+ A Web Component for rendering terminal-style previews - works with any framework (React, Vue, Angular, Svelte, etc.)
8
+
9
+ ## Demo
10
+
11
+ 📗 [Storybook](https://main--69c3d55e127974ed658d1728.chromatic.com)
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ npm install terminal-element
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```html
22
+ <terminal-element></terminal-element>
23
+ ```
24
+
25
+ ## Props
26
+
27
+ | Name | Type | Required | Default | Description |
28
+ | ------------------ | ------------------- | -------- | --------- | ---------------------------------------------------- |
29
+ | width | `string` | No | `"600px"` | Width of the terminal |
30
+ | height | `string` | No | `"360px"` | Height of the terminal |
31
+ | theme | `"light" \| "dark"` | No | `"dark"` | Theme of the terminal |
32
+ | currentDirectory | `string` | No | `""` | Current directory displayed in header |
33
+ | prompt | `string` | No | `"$"` | Prompt symbol |
34
+ | content | `Line[]` | No | `[]` | Content to display (see [Line](#line) section) |
35
+ | animated | `boolean` | No | `false` | Enable typing animation |
36
+ | typingSpeed | `number` | No | `100` | Typing speed in ms per character |
37
+ | loop | `boolean` | No | `false` | Enable infinite loop animation |
38
+ | delayAfterComplete | `number` | No | `2000` | Delay after animation completes before clearing (ms) |
39
+ | delayBeforeRestart | `number` | No | `1000` | Delay showing empty screen before restart (ms) |
40
+
41
+ ### Line
42
+
43
+ The `content` prop accepts an array of `Line` objects. There are two types:
44
+
45
+ **InputLine** - Displays a command with prompt:
46
+
47
+ ```typescript
48
+ type InputLine = {
49
+ type: "input";
50
+ text: string;
51
+ };
52
+ ```
53
+
54
+ **OutputLine** - Displays output text (with optional delay for animation):
55
+
56
+ ```typescript
57
+ // Simple text output
58
+ type OutputLineText = {
59
+ type: "output";
60
+ text: string;
61
+ delay?: number; // Delay in ms before showing this line (animation only)
62
+ };
63
+
64
+ // Colored segments output
65
+ type OutputLineSegments = {
66
+ type: "output";
67
+ segments: Segment[];
68
+ delay?: number;
69
+ };
70
+
71
+ type Segment = {
72
+ text: string;
73
+ color?: AnsiColorType; // "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" and their "-bright" variants
74
+ bg?: AnsiColorType;
75
+ };
76
+ ```
77
+
78
+ **Example:**
79
+
80
+ ```javascript
81
+ content = [
82
+ { type: "input", text: "npm install" },
83
+ { type: "output", text: "" },
84
+ { type: "output", text: "added 50 packages in 2s", delay: 500 },
85
+ {
86
+ type: "output",
87
+ segments: [
88
+ { text: "✓", color: "green" },
89
+ { text: " Done!" },
90
+ ],
91
+ },
92
+ ];
93
+ ```
94
+
95
+ ## Styling
96
+
97
+ | Variable | Default |
98
+ | ------------------------------------------- | ---------------------------------- |
99
+ | `--terminal-element-font-size` | `14px` |
100
+ | `--terminal-element-box-shadow` | `rgb(0 0 0 / 56%) 0 22px 70px 4px` |
101
+ | `--terminal-element-border-color` | `#070707` |
102
+ | `--terminal-element-header-bg` | `#323232` |
103
+ | `--terminal-element-header-border` | `#6a6a6a` |
104
+ | `--terminal-element-header-border-bottom` | `#6a6a6a` |
105
+ | `--terminal-element-header-directory-color` | `#afafb4` |
106
+ | `--terminal-element-body-bg` | `#101317` |
107
+ | `--terminal-element-body-border` | `#606060` |
108
+ | `--terminal-element-body-content-color` | `#d4d4d4` |
109
+ | `--terminal-element-caret-color` | `#fff` |
110
+ | `--terminal-element-ansi-black` | `#14191e` |
111
+ | `--terminal-element-ansi-black-bright` | `#676767` |
112
+ | `--terminal-element-ansi-red` | `#b43c29` |
113
+ | `--terminal-element-ansi-red-bright` | `#dc7974` |
114
+ | `--terminal-element-ansi-green` | `#00c200` |
115
+ | `--terminal-element-ansi-green-bright` | `#57e690` |
116
+ | `--terminal-element-ansi-yellow` | `#c7c400` |
117
+ | `--terminal-element-ansi-yellow-bright` | `#ece100` |
118
+ | `--terminal-element-ansi-blue` | `#2743c7` |
119
+ | `--terminal-element-ansi-blue-bright` | `#a6aaf1` |
120
+ | `--terminal-element-ansi-magenta` | `#bf3fbd` |
121
+ | `--terminal-element-ansi-magenta-bright` | `#e07de0` |
122
+ | `--terminal-element-ansi-cyan` | `#00c5c7` |
123
+ | `--terminal-element-ansi-cyan-bright` | `#5ffdff` |
124
+ | `--terminal-element-ansi-white` | `#c7c7c7` |
125
+ | `--terminal-element-ansi-white-bright` | `#feffff` |
126
+
127
+ ## Contributing
128
+
129
+ - Bug fix PRs are always welcome.
130
+ - UI changes or new features should not be submitted without prior discussion. Please open an issue first to propose and discuss them.
131
+
132
+ Thanks for your understanding and contributions.
133
+
134
+ ## License
135
+
136
+ [MIT](./LICENSE)
@@ -0,0 +1,293 @@
1
+ import { LitElement as p, css as b, html as r } from "lit";
2
+ import { customElement as _, property as a, state as c } from "lit/decorators.js";
3
+ function i(s, e, t, l) {
4
+ var m = arguments.length, o = m < 3 ? e : l === null ? l = Object.getOwnPropertyDescriptor(e, t) : l, d;
5
+ if (typeof Reflect == "object" && typeof Reflect.decorate == "function") o = Reflect.decorate(s, e, t, l);
6
+ else for (var h = s.length - 1; h >= 0; h--) (d = s[h]) && (o = (m < 3 ? d(o) : m > 3 ? d(e, t, o) : d(e, t)) || o);
7
+ return m > 3 && o && Object.defineProperty(e, t, o), o;
8
+ }
9
+ var n = class extends p {
10
+ constructor(...e) {
11
+ super(...e), this.width = "600px", this.height = "360px", this.theme = "dark", this.currentDirectory = "", this.prompt = "$", this.content = [], this.animated = !1, this.typingSpeed = 100, this.loop = !1, this.delayAfterComplete = 4e3, this.delayBeforeRestart = 1e3, this._currentLineIndex = 0, this._currentCharInLine = 0, this._isAnimating = !1, this._isWaitingToRestart = !1, this._animationTimer = null;
12
+ }
13
+ static {
14
+ this.styles = b`
15
+ :host {
16
+ display: block;
17
+ width: fit-content;
18
+ height: fit-content;
19
+
20
+ --terminal-element-font-size: 14px;
21
+ --terminal-element-box-shadow: rgb(0 0 0 / 56%) 0 22px 70px 4px;
22
+
23
+ /** UI colors */
24
+ --terminal-element-border-color: #070707;
25
+ --terminal-element-header-bg: #323232;
26
+ --terminal-element-header-border: #6a6a6a;
27
+ --terminal-element-header-border-bottom: #6a6a6a;
28
+ --terminal-element-header-directory-color: #afafb4;
29
+ --terminal-element-body-bg: #101317;
30
+ --terminal-element-body-border: #606060;
31
+ --terminal-element-body-content-color: #d4d4d4;
32
+ --terminal-element-caret-color: #fff;
33
+
34
+ /** ANSI colors */
35
+ --terminal-element-ansi-black: #14191e;
36
+ --terminal-element-ansi-black-bright: #676767;
37
+ --terminal-element-ansi-red: #b43c29;
38
+ --terminal-element-ansi-red-bright: #dc7974;
39
+ --terminal-element-ansi-green: #00c200;
40
+ --terminal-element-ansi-green-bright: #57e690;
41
+ --terminal-element-ansi-yellow: #c7c400;
42
+ --terminal-element-ansi-yellow-bright: #ece100;
43
+ --terminal-element-ansi-blue: #2743c7;
44
+ --terminal-element-ansi-blue-bright: #a6aaf1;
45
+ --terminal-element-ansi-magenta: #bf3fbd;
46
+ --terminal-element-ansi-magenta-bright: #e07de0;
47
+ --terminal-element-ansi-cyan: #00c5c7;
48
+ --terminal-element-ansi-cyan-bright: #5ffdff;
49
+ --terminal-element-ansi-white: #c7c7c7;
50
+ --terminal-element-ansi-white-bright: #feffff;
51
+ }
52
+
53
+ :host([theme="light"]) {
54
+ /** UI colors */
55
+ --terminal-element-border-color: #cdcdcd;
56
+ --terminal-element-header-bg: #f4f4f8;
57
+ --terminal-element-header-border: #f1f1f4;
58
+ --terminal-element-header-border-bottom: #dfdfdf;
59
+ --terminal-element-header-directory-color: #393939;
60
+ --terminal-element-body-bg: #fff;
61
+ --terminal-element-body-border: transparent;
62
+ --terminal-element-body-content-color: #0c0c0c;
63
+ --terminal-element-caret-color: #808080;
64
+
65
+ /** ANSI colors */
66
+ --terminal-element-ansi-black: #000;
67
+ --terminal-element-ansi-black-bright: #808080;
68
+ --terminal-element-ansi-red: #900;
69
+ --terminal-element-ansi-red-bright: #e60000;
70
+ --terminal-element-ansi-green: #00a600;
71
+ --terminal-element-ansi-green-bright: #00d900;
72
+ --terminal-element-ansi-yellow: #990;
73
+ --terminal-element-ansi-yellow-bright: #e6e600;
74
+ --terminal-element-ansi-blue: #0000b2;
75
+ --terminal-element-ansi-blue-bright: #00f;
76
+ --terminal-element-ansi-magenta: #b200b2;
77
+ --terminal-element-ansi-magenta-bright: #e600e6;
78
+ --terminal-element-ansi-cyan: #00a6b2;
79
+ --terminal-element-ansi-cyan-bright: #00e6e6;
80
+ --terminal-element-ansi-white: #bfbfbf;
81
+ --terminal-element-ansi-white-bright: #e6e6e6;
82
+ }
83
+
84
+ * {
85
+ box-sizing: border-box;
86
+ margin: 0;
87
+ }
88
+
89
+ .terminal-element {
90
+ display: flex;
91
+ flex-direction: column;
92
+ overflow: hidden;
93
+ border: 1px solid var(--terminal-element-border-color);
94
+ border-radius: 10px;
95
+ box-shadow: var(--terminal-element-box-shadow);
96
+ }
97
+
98
+ .terminal-element__header {
99
+ position: relative;
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
+ height: 28px;
104
+ padding: 0 16px;
105
+ background-color: var(--terminal-element-header-bg);
106
+ border-top: 1px solid var(--terminal-element-header-border);
107
+ border-right: 1px solid var(--terminal-element-header-border);
108
+ border-bottom: 1px solid var(--terminal-element-header-border-bottom);
109
+ border-left: 1px solid var(--terminal-element-header-border);
110
+ }
111
+
112
+ .terminal-element__header-controls {
113
+ position: absolute;
114
+ left: 8px;
115
+ display: flex;
116
+ flex-direction: row;
117
+ gap: 8px;
118
+ }
119
+
120
+ .terminal-element__header-button {
121
+ width: 12px;
122
+ height: 12px;
123
+ border-radius: 999px;
124
+ }
125
+
126
+ .terminal-element__header-button--red {
127
+ background-color: #fb4646;
128
+ }
129
+
130
+ .terminal-element__header-button--yellow {
131
+ background-color: #fcae24;
132
+ }
133
+
134
+ .terminal-element__header-button--green {
135
+ background-color: #28c132;
136
+ }
137
+
138
+ .terminal-element__header-directory {
139
+ font-size: 12px;
140
+ font-weight: 600;
141
+ color: var(--terminal-element-header-directory-color);
142
+ }
143
+
144
+ .terminal-element__body {
145
+ flex: 1;
146
+ padding: 4px;
147
+ background-color: var(--terminal-element-body-bg);
148
+ border-right: solid 1px var(--terminal-element-body-border);
149
+ border-bottom: solid 1px var(--terminal-element-body-border);
150
+ border-left: solid 1px var(--terminal-element-body-border);
151
+ }
152
+
153
+ .terminal-element__body-content {
154
+ font-family: monospace;
155
+ font-size: var(--terminal-element-font-size);
156
+ font-weight: 400;
157
+ color: var(--terminal-element-body-content-color);
158
+ }
159
+
160
+ .terminal-element__body-line {
161
+ word-break: break-all;
162
+ white-space: pre-wrap;
163
+ }
164
+
165
+ .terminal-element__body-caret {
166
+ display: inline-block;
167
+ width: 8px;
168
+ height: var(--terminal-element-font-size);
169
+ vertical-align: bottom;
170
+ background-color: var(--terminal-element-caret-color);
171
+ }
172
+ `;
173
+ }
174
+ connectedCallback() {
175
+ super.connectedCallback(), this.animated && this._startAnimation();
176
+ }
177
+ disconnectedCallback() {
178
+ super.disconnectedCallback(), this._stopAnimation();
179
+ }
180
+ updated(e) {
181
+ super.updated(e), e.has("content") && this.animated && e.get("content") !== void 0 && (this._stopAnimation(), this._startAnimation());
182
+ }
183
+ _startAnimation() {
184
+ this._currentLineIndex = 0, this._currentCharInLine = 0, this._isAnimating = !0, this._isWaitingToRestart = !1, this._processCurrentLine();
185
+ }
186
+ _processCurrentLine() {
187
+ if (this._currentLineIndex >= this.content.length) {
188
+ this.loop ? this._animationTimer = setTimeout(() => {
189
+ this._isWaitingToRestart = !0, this.requestUpdate(), this._animationTimer = setTimeout(() => {
190
+ this._startAnimation();
191
+ }, this.delayBeforeRestart);
192
+ }, this.delayAfterComplete) : this._isAnimating = !1;
193
+ return;
194
+ }
195
+ const e = this.content[this._currentLineIndex];
196
+ if (e.type === "input") this._tickInputLine();
197
+ else {
198
+ const t = ("delay" in e ? e.delay : 0) ?? 0;
199
+ t > 0 ? this._animationTimer = setTimeout(() => {
200
+ this._moveToNextLine();
201
+ }, t) : this._moveToNextLine();
202
+ }
203
+ }
204
+ _tickInputLine() {
205
+ const e = this.content[this._currentLineIndex];
206
+ if (e.type !== "input") return;
207
+ const t = e.text.length;
208
+ this._currentCharInLine < t ? (this._currentCharInLine++, this._animationTimer = setTimeout(() => this._tickInputLine(), this.typingSpeed)) : this._moveToNextLine();
209
+ }
210
+ _moveToNextLine() {
211
+ this._currentLineIndex++, this._currentCharInLine = 0, this._processCurrentLine();
212
+ }
213
+ _stopAnimation() {
214
+ this._animationTimer !== null && (clearTimeout(this._animationTimer), this._animationTimer = null), this._isAnimating = !1, this._isWaitingToRestart = !1;
215
+ }
216
+ _renderContent() {
217
+ return this.animated ? this._isWaitingToRestart ? null : !this._isAnimating && this._currentLineIndex >= this.content.length ? this._renderFullContent() : this._renderPartialContent() : this._renderFullContent();
218
+ }
219
+ _renderFullContent() {
220
+ return this.content.map((e) => e.type === "input" ? r`<div class="terminal-element__body-line"><span>${this.prompt}&nbsp;</span><span class="terminal-element__body-segment">${e.text}</span></div>` : "text" in e ? r`<div class="terminal-element__body-line">${e.text !== "" ? e.text : r`&nbsp;`}</div>` : r`<div class="terminal-element__body-line">${e.segments.length === 0 ? r`&nbsp;` : e.segments.map((t) => r`<span style="color: ${t.color ? `var(--terminal-element-ansi-${t.color})` : "inherit"}; background-color: ${t.bg ? `var(--terminal-element-ansi-${t.bg})` : "inherit"};">${t.text}</span>`)}</div>`);
221
+ }
222
+ _renderPartialContent() {
223
+ const e = [];
224
+ for (let t = 0; t < this.content.length; t++) {
225
+ const l = this.content[t];
226
+ t < this._currentLineIndex ? e.push(this._renderFullLine(l)) : t === this._currentLineIndex && l.type === "input" && e.push(this._renderPartialInputLine(l));
227
+ }
228
+ return e;
229
+ }
230
+ _renderFullLine(e) {
231
+ return e.type === "input" ? r`<div class="terminal-element__body-line"><span>${this.prompt}&nbsp;</span><span class="terminal-element__body-segment">${e.text}</span></div>` : "text" in e ? r`<div class="terminal-element__body-line">${e.text !== "" ? e.text : r`&nbsp;`}</div>` : r`<div class="terminal-element__body-line">${e.segments.length === 0 ? r`&nbsp;` : e.segments.map((t) => r`<span style="color: ${t.color ? `var(--terminal-element-ansi-${t.color})` : "inherit"}; background-color: ${t.bg ? `var(--terminal-element-ansi-${t.bg})` : "inherit"};">${t.text}</span>`)}</div>`;
232
+ }
233
+ _renderPartialInputLine(e) {
234
+ const t = e.text.slice(0, this._currentCharInLine);
235
+ return r`<div class="terminal-element__body-line"><span>${this.prompt}&nbsp;</span><span class="terminal-element__body-segment">${t}</span><span class="terminal-element__body-caret"></span></div>`;
236
+ }
237
+ render() {
238
+ return r`
239
+ <div
240
+ class="terminal-element"
241
+ style="width: ${this.width}; height: ${this.height};"
242
+ data-testid="terminal-element"
243
+ >
244
+ <div class="terminal-element__header">
245
+ <div class="terminal-element__header-controls">
246
+ <div
247
+ class="terminal-element__header-button terminal-element__header-button--red"
248
+ ></div>
249
+ <div
250
+ class="terminal-element__header-button terminal-element__header-button--yellow"
251
+ ></div>
252
+ <div
253
+ class="terminal-element__header-button terminal-element__header-button--green"
254
+ ></div>
255
+ </div>
256
+ <div
257
+ class="terminal-element__header-directory"
258
+ data-testid="current-directory"
259
+ >
260
+ ${this.currentDirectory}
261
+ </div>
262
+ </div>
263
+ <div class="terminal-element__body">
264
+ <div class="terminal-element__body-content" data-testid="content">
265
+ ${this._renderContent()}
266
+ </div>
267
+ </div>
268
+ </div>
269
+ `;
270
+ }
271
+ };
272
+ i([a({ type: String })], n.prototype, "width", void 0);
273
+ i([a({ type: String })], n.prototype, "height", void 0);
274
+ i([a({
275
+ type: String,
276
+ reflect: !0
277
+ })], n.prototype, "theme", void 0);
278
+ i([a({ type: String })], n.prototype, "currentDirectory", void 0);
279
+ i([a({ type: String })], n.prototype, "prompt", void 0);
280
+ i([a({ type: Array })], n.prototype, "content", void 0);
281
+ i([a({ type: Boolean })], n.prototype, "animated", void 0);
282
+ i([a({ type: Number })], n.prototype, "typingSpeed", void 0);
283
+ i([a({ type: Boolean })], n.prototype, "loop", void 0);
284
+ i([a({ type: Number })], n.prototype, "delayAfterComplete", void 0);
285
+ i([a({ type: Number })], n.prototype, "delayBeforeRestart", void 0);
286
+ i([c()], n.prototype, "_currentLineIndex", void 0);
287
+ i([c()], n.prototype, "_currentCharInLine", void 0);
288
+ i([c()], n.prototype, "_isAnimating", void 0);
289
+ i([c()], n.prototype, "_isWaitingToRestart", void 0);
290
+ n = i([_("terminal-element")], n);
291
+ export {
292
+ n as TerminalElement
293
+ };
@@ -0,0 +1,76 @@
1
+ import { LitElement } from "lit";
2
+ import type { PropertyValues } from "lit";
3
+ export type ThemeType = "light" | "dark";
4
+ export type AnsiColorType = "black" | "black-bright" | "red" | "red-bright" | "green" | "green-bright" | "yellow" | "yellow-bright" | "blue" | "blue-bright" | "magenta" | "magenta-bright" | "cyan" | "cyan-bright" | "white" | "white-bright";
5
+ export type Segment = {
6
+ text: string;
7
+ color?: AnsiColorType;
8
+ bg?: AnsiColorType;
9
+ };
10
+ export type InputLine = {
11
+ type: "input";
12
+ text: string;
13
+ };
14
+ export type OutputLineText = {
15
+ type: "output";
16
+ text: string;
17
+ delay?: number;
18
+ };
19
+ export type OutputLineSegments = {
20
+ type: "output";
21
+ segments: Segment[];
22
+ delay?: number;
23
+ };
24
+ export type Line = InputLine | OutputLineText | OutputLineSegments;
25
+ export interface TerminalElementProps {
26
+ width?: string;
27
+ height?: string;
28
+ theme?: ThemeType;
29
+ currentDirectory?: string;
30
+ prompt?: string;
31
+ content?: Line[];
32
+ animated?: boolean;
33
+ typingSpeed?: number;
34
+ loop?: boolean;
35
+ delayAfterComplete?: number;
36
+ delayBeforeRestart?: number;
37
+ }
38
+ export declare class TerminalElement extends LitElement {
39
+ width: string;
40
+ height: string;
41
+ theme: ThemeType;
42
+ currentDirectory: string;
43
+ prompt: string;
44
+ content: Line[];
45
+ animated: boolean;
46
+ typingSpeed: number;
47
+ loop: boolean;
48
+ delayAfterComplete: number;
49
+ delayBeforeRestart: number;
50
+ private _currentLineIndex;
51
+ private _currentCharInLine;
52
+ private _isAnimating;
53
+ private _isWaitingToRestart;
54
+ private _animationTimer;
55
+ static styles: import("lit").CSSResult;
56
+ connectedCallback(): void;
57
+ disconnectedCallback(): void;
58
+ protected updated(changedProperties: PropertyValues): void;
59
+ private _startAnimation;
60
+ private _processCurrentLine;
61
+ private _tickInputLine;
62
+ private _moveToNextLine;
63
+ private _stopAnimation;
64
+ private _renderContent;
65
+ private _renderFullContent;
66
+ private _renderPartialContent;
67
+ private _renderFullLine;
68
+ private _renderPartialInputLine;
69
+ render(): import("lit").TemplateResult<1>;
70
+ }
71
+ declare global {
72
+ interface HTMLElementTagNameMap {
73
+ "terminal-element": TerminalElement;
74
+ }
75
+ }
76
+ //# sourceMappingURL=terminal-element.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-element.d.ts","sourceRoot":"","sources":["../../src/terminal-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAG1C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzC,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,cAAc,GACd,KAAK,GACL,YAAY,GACZ,OAAO,GACP,cAAc,GACd,QAAQ,GACR,eAAe,GACf,MAAM,GACN,aAAa,GACb,SAAS,GACT,gBAAgB,GAChB,MAAM,GACN,aAAa,GACb,OAAO,GACP,cAAc,CAAC;AAEnB,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,EAAE,CAAC,EAAE,aAAa,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qBACa,eAAgB,SAAQ,UAAU;IACjB,KAAK,SAAW;IAChB,MAAM,SAAW;IACF,KAAK,EAAE,SAAS,CAAU;IACzC,gBAAgB,SAAM;IACtB,MAAM,SAAO;IACd,OAAO,EAAE,IAAI,EAAE,CAAM;IACnB,QAAQ,UAAS;IAClB,WAAW,SAAO;IACjB,IAAI,UAAS;IACd,kBAAkB,SAAQ;IAC1B,kBAAkB,SAAQ;IAE7C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAAS;IAE7C,OAAO,CAAC,eAAe,CAAuB;IAE9C,MAAM,CAAC,MAAM,0BA8JX;IAEF,iBAAiB;IAOjB,oBAAoB;IAKpB,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,cAAc;IAcnD,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,uBAAuB;IAM/B,MAAM;CAkCP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,eAAe,CAAC;KACrC;CACF"}
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "terminal-element",
3
+ "version": "1.0.0",
4
+ "description": "A Web Component for rendering terminal-style previews",
5
+ "type": "module",
6
+ "main": "dist/terminal-element.es.js",
7
+ "module": "dist/terminal-element.es.js",
8
+ "types": "dist/types/terminal-element.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types/terminal-element.d.ts",
12
+ "import": "./dist/terminal-element.es.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/spider-hand/terminal-element.git"
23
+ },
24
+ "keywords": [
25
+ "terminal",
26
+ "cli",
27
+ "web-component",
28
+ "webcomponent",
29
+ "lit"
30
+ ],
31
+ "author": "Akinori Hoshina <creative.spider.hand@gmail.com>",
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/spider-hand/terminal-element/issues"
35
+ },
36
+ "homepage": "https://github.com/spider-hand/terminal-element#readme",
37
+ "peerDependencies": {
38
+ "lit": "^3.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@chromatic-com/storybook": "^5.0.2",
42
+ "@eslint/css": "^1.0.0",
43
+ "@eslint/js": "^10.0.1",
44
+ "@storybook/addon-a11y": "^10.3.1",
45
+ "@storybook/addon-docs": "^10.3.1",
46
+ "@storybook/addon-vitest": "^10.3.1",
47
+ "@storybook/web-components-vite": "^10.3.1",
48
+ "@vitest/browser-playwright": "^4.1.0",
49
+ "@vitest/coverage-v8": "^4.1.0",
50
+ "chromatic": "^16.0.0",
51
+ "eslint": "^10.1.0",
52
+ "eslint-config-prettier": "^10.1.8",
53
+ "eslint-plugin-lit": "^2.2.1",
54
+ "eslint-plugin-storybook": "^10.3.1",
55
+ "globals": "^17.4.0",
56
+ "husky": "^9.1.7",
57
+ "lint-staged": "^16.4.0",
58
+ "lit": "^3.3.2",
59
+ "playwright": "^1.58.2",
60
+ "postcss-lit": "^1.4.1",
61
+ "prettier": "^3.8.1",
62
+ "storybook": "^10.3.1",
63
+ "stylelint": "^17.5.0",
64
+ "stylelint-config-recess-order": "^7.7.0",
65
+ "stylelint-config-standard": "^40.0.0",
66
+ "typescript": "~5.9.3",
67
+ "typescript-eslint": "^8.57.1",
68
+ "vite": "^8.0.1",
69
+ "vitest": "^4.1.0",
70
+ "vitest-browser-lit": "^1.0.1"
71
+ },
72
+ "lint-staged": {
73
+ "*.{js,ts}": [
74
+ "eslint --fix",
75
+ "prettier --write"
76
+ ],
77
+ "*.ts": "stylelint --fix"
78
+ },
79
+ "scripts": {
80
+ "dev": "vite",
81
+ "build": "vite build",
82
+ "build:types": "tsc -p tsconfig.build.types.json",
83
+ "build:all": "pnpm run build && pnpm run build:types",
84
+ "preview": "vite preview",
85
+ "lint": "eslint --fix",
86
+ "format": "prettier --write .",
87
+ "storybook": "storybook dev -p 6006",
88
+ "build-storybook": "storybook build",
89
+ "test": "vitest --config=vitest.browser.config.ts",
90
+ "test:coverage": "vitest run --config=vitest.browser.config.ts --coverage"
91
+ }
92
+ }