@ghchinoy/lit-audio-ui 0.4.3 → 0.4.5
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 +40 -109
- package/dist/components/atoms/ui-message-bubble.js +95 -0
- package/dist/components/atoms/ui-speech-record-button.js +2 -3
- package/dist/components/atoms/ui-typing-dot.js +54 -0
- package/dist/components/molecules/ui-chat-item.js +112 -0
- package/dist/components/molecules/ui-chat-list.js +71 -0
- package/dist/components/molecules/ui-showcase-card.js +14 -9
- package/dist/components/molecules/ui-speech-preview.js +1 -2
- package/dist/components/molecules/ui-typing-indicator.js +43 -0
- package/dist/components/providers/ui-speech-provider.js +1 -0
- package/dist/index.js +23 -18
- package/dist/scream-audio-ui.umd.js +244 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,56 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
A lightweight, framework-agnostic Web Components library for high-performance audio visualization and control, built natively for the browser using [Lit](https://lit.dev/).
|
|
4
4
|
|
|
5
|
-
Take a look at the [
|
|
5
|
+
Take a look at the [interactive gallery and documentation](https://ghchinoy.github.io/scream-ui/) to see the components in action.
|
|
6
6
|
|
|
7
7
|
## Why Lit Web Components?
|
|
8
8
|
|
|
9
|
-
When building complex, high-frequency audio visualizers (like real-time canvas waveforms), performance and bundle size are critical.
|
|
10
|
-
|
|
11
|
-
By leveraging **Lit** and native Web Components, this library offers distinct advantages:
|
|
9
|
+
When building complex, high-frequency audio visualizers (like real-time canvas waveforms), performance and bundle size are critical. By leveraging **Lit** and native Web Components, this library offers distinct advantages:
|
|
12
10
|
|
|
13
11
|
* **Microscopic Footprint:** No massive framework runtimes. Lit simply provides lightweight, reactive syntactic sugar over standard browser APIs.
|
|
14
|
-
* **Blazing Fast Canvas & Audio:** Direct DOM access means no Virtual DOM bottlenecks when piping 60fps
|
|
15
|
-
* **Framework Agnostic:**
|
|
16
|
-
* **
|
|
17
|
-
* **Atomic Composition:** Powered by `@lit/context`, the complex monolithic audio players are broken down into atomic, highly composable state machines.
|
|
18
|
-
|
|
12
|
+
* **Blazing Fast Canvas & Audio:** Direct DOM access means no Virtual DOM bottlenecks when piping 60fps data directly into `<canvas>` elements.
|
|
13
|
+
* **Framework Agnostic:** Compiles to standard HTML tags. Drop these into React, Vue, Angular, Svelte, or vanilla HTML with zero friction.
|
|
14
|
+
* **Atomic Design:** Organized into **Atoms, Molecules, Organisms, and Providers** for maximum reusability.
|
|
19
15
|
|
|
20
16
|
## How to Use (For AI Agents)
|
|
21
17
|
|
|
22
|
-
If you are an AI coding agent integrating this library into an application, please refer to the [AGENT_SKILL.md](
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## How to Use the Lit Components (For Users)
|
|
26
|
-
|
|
27
|
-
As a Web Components library, you can use these elements directly in your HTML or inside any frontend framework.
|
|
18
|
+
If you are an AI coding agent integrating this library into an application, please refer to the [AGENT_SKILL.md](https://github.com/ghchinoy/scream-ui/blob/main/packages/lit-audio-ui/AGENT_SKILL.md) for specialized integration protocols, state management patterns, and "Zero-JS" branding guidelines.
|
|
28
19
|
|
|
20
|
+
## How to Use (For Users)
|
|
29
21
|
|
|
30
22
|
### 1. Installation
|
|
31
|
-
Install the package via npm:
|
|
32
23
|
```bash
|
|
33
24
|
npm install @ghchinoy/lit-audio-ui
|
|
34
25
|
```
|
|
35
26
|
|
|
36
|
-
### 2.
|
|
37
|
-
For a zero-install experience, you can use the library directly from a CDN like [esm.run](https://esm.run/):
|
|
38
|
-
```html
|
|
39
|
-
<script type="module" src="https://esm.run/@ghchinoy/lit-audio-ui"></script>
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 3. Import the Library (Bundlers)
|
|
43
|
-
Import the components into your JavaScript/TypeScript entry point:
|
|
27
|
+
### 2. Import the Library
|
|
44
28
|
```javascript
|
|
45
29
|
// Import the entire library
|
|
46
30
|
import '@ghchinoy/lit-audio-ui';
|
|
47
31
|
|
|
48
|
-
// Or import specific
|
|
49
|
-
import '@ghchinoy/lit-audio-ui/
|
|
50
|
-
import '@ghchinoy/lit-audio-ui/
|
|
32
|
+
// Or import specific categories for better tree-shaking
|
|
33
|
+
import '@ghchinoy/lit-audio-ui/atoms/ui-audio-play-button.js';
|
|
34
|
+
import '@ghchinoy/lit-audio-ui/molecules/ui-live-waveform.js';
|
|
51
35
|
```
|
|
52
36
|
|
|
53
|
-
###
|
|
54
|
-
Once imported,
|
|
37
|
+
### 3. Use in HTML
|
|
38
|
+
Once imported, custom elements are registered and used like standard HTML tags:
|
|
55
39
|
|
|
56
40
|
```html
|
|
57
41
|
<!-- Example: A voice recording button -->
|
|
@@ -61,98 +45,45 @@ Once imported, the custom elements are registered with the browser and can be us
|
|
|
61
45
|
<ui-live-waveform .analyserNode="${myAudioAnalyser}"></ui-live-waveform>
|
|
62
46
|
```
|
|
63
47
|
|
|
64
|
-
### 5. Theming (Material Design 3)
|
|
65
|
-
These components are deeply theme-aware and utilize Material Design 3 design tokens. To customize their colors (or support light/dark modes), simply define the CSS variables in your stylesheet:
|
|
66
|
-
|
|
67
|
-
```css
|
|
68
|
-
:root {
|
|
69
|
-
--md-sys-color-primary: #0066cc;
|
|
70
|
-
--md-sys-color-on-primary: #ffffff;
|
|
71
|
-
--md-sys-color-surface-container: #f3f3f3;
|
|
72
|
-
/* ...other MD3 tokens */
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.dark {
|
|
76
|
-
--md-sys-color-primary: #a8c7fa;
|
|
77
|
-
--md-sys-color-on-primary: #003062;
|
|
78
|
-
--md-sys-color-surface-container: #212121;
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
48
|
## Available Components
|
|
83
49
|
|
|
84
|
-
|
|
50
|
+
### 🧪 Atoms (Primitives)
|
|
51
|
+
* **`<ui-audio-play-button>`**: Context-aware play/pause toggle.
|
|
52
|
+
* **`<ui-audio-next-button>` / `<ui-audio-prev-button>`**: Playlist navigation buttons.
|
|
53
|
+
* **`<ui-audio-progress-slider>`**: Reactive scrubber for playback.
|
|
54
|
+
* **`<ui-audio-time-display>`**: Flexible time visualizer (elapsed, remaining, combined).
|
|
55
|
+
* **`<ui-speech-record-button>`**: Atomic trigger for recording context.
|
|
56
|
+
* **`<ui-shimmering-text>`**: Pure CSS text loading effect.
|
|
85
57
|
|
|
86
|
-
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* 🎭 **`<ui-voice-picker>`**: A searchable dropdown menu (combobox) that handles rendering complex persona objects, including real-time audio previews injected directly into the menu items.
|
|
95
|
-
* 🗣️ **Atomic Speech Architecture**: Use `<ui-speech-provider>`, `<ui-speech-record-button>`, `<ui-speech-preview>`, and `<ui-speech-cancel-button>` to build custom recording UIs (like the Smart Textarea) with built-in state management and visualization.
|
|
58
|
+
### 🧬 Molecules (Functional Units)
|
|
59
|
+
* **`<ui-live-waveform>`**: Real-time visualizer for an active `AudioContext`.
|
|
60
|
+
* **`<ui-spectrum-visualizer>`**: Traditional frequency-bar spectrum.
|
|
61
|
+
* **`<ui-orb>`**: 3D WebGL (Three.js) agent visualizer.
|
|
62
|
+
* **`<ui-3d-flip>`**: Layout utility for 3D card-flipping interactions.
|
|
63
|
+
* **`<ui-playlist>`**: Reactive list component for queue management.
|
|
64
|
+
* **`<ui-mic-selector>`**: Hardware enumeration and permission handler.
|
|
65
|
+
* **`<ui-voice-picker>`**: Searchable persona selector with audio previews.
|
|
96
66
|
|
|
67
|
+
### 🧩 Providers (State)
|
|
68
|
+
* **`<ui-audio-provider>`**: Headless state machine for playback and playlists.
|
|
69
|
+
* **`<ui-speech-provider>`**: Headless lifecycle manager for voice recording (Auto, Simulation, or Manual mode).
|
|
97
70
|
|
|
98
|
-
##
|
|
71
|
+
## Theming (Material Design 3)
|
|
99
72
|
|
|
100
|
-
|
|
73
|
+
Customize colors and typography via standard CSS variables:
|
|
101
74
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
1. **Clone & Install**
|
|
109
|
-
```bash
|
|
110
|
-
git clone <repository-url>
|
|
111
|
-
cd packages/lit-audio-ui
|
|
112
|
-
npm install
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
2. **Start the Dev Server**
|
|
116
|
-
This will start a local Vite development server. It serves the `index.html` file, which acts as our component workbench and functional test bed.
|
|
117
|
-
```bash
|
|
118
|
-
npm run dev
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
3. **Code Structure**
|
|
122
|
-
- `/packages/lit-audio-ui/src/components/`: This is where the Lit elements (`.ts`) live. Each component should be self-contained with its scoped CSS (`static styles`).
|
|
123
|
-
- `/packages/lit-audio-ui/src/utils/`: Shared utilities, such as the `AudioContext` and FFT math ported from the original ElevenLabs React repository.
|
|
124
|
-
- `/packages/lit-audio-ui/demo/index.html`: The development workbench. Whenever you create a new component or port a feature, add a demo block here.
|
|
125
|
-
- `/packages/lit-audio-ui/demo/demo-layouts.ts`: Complex composite examples and layout logic used in the workbench.
|
|
126
|
-
|
|
127
|
-
### Building for Production
|
|
128
|
-
To compile the TypeScript and bundle the library for distribution:
|
|
129
|
-
```bash
|
|
130
|
-
cd packages/lit-audio-ui
|
|
131
|
-
npm run build
|
|
132
|
-
```
|
|
133
|
-
This generates the optimized assets in the `/dist` folder.
|
|
134
|
-
|
|
135
|
-
### Linting
|
|
136
|
-
We use `google/gts` (Google TypeScript Style) and the `eslint-plugin-lit` ruleset to enforce code quality and Lit best practices.
|
|
137
|
-
```bash
|
|
138
|
-
cd packages/lit-audio-ui
|
|
139
|
-
npm run lint
|
|
140
|
-
npm run fix
|
|
75
|
+
```css
|
|
76
|
+
:root {
|
|
77
|
+
--md-sys-color-primary: #0066cc;
|
|
78
|
+
--ui-speech-record-color: #ff4444; /* Custom branding */
|
|
79
|
+
--ui-speech-preview-font-size: 18px;
|
|
80
|
+
}
|
|
141
81
|
```
|
|
142
82
|
|
|
143
83
|
## Acknowledgements
|
|
144
84
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
We are incredibly grateful for their contribution to the open-source community. Their original repository provided the foundational audio mathematics, canvas drawing logic, and WebGL shader configurations that make these visualizers look buttery smooth. While their library focuses heavily on the React ecosystem, this project reimagines those beautiful designs as standard, universal browser APIs.
|
|
85
|
+
Deeply inspired by the beautiful, open-source audio components built by **[ElevenLabs](https://elevenlabs.io/)** (`@elevenlabs/ui`). This project reimplement those designs as standard, universal browser APIs.
|
|
148
86
|
|
|
149
87
|
# License
|
|
150
88
|
|
|
151
89
|
Apache 2.0; see [`LICENSE`](LICENSE) for details.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
# Disclaimer
|
|
155
|
-
|
|
156
|
-
This project is not an official Google project. It is not supported by
|
|
157
|
-
Google and Google specifically disclaims all warranties as to its quality,
|
|
158
|
-
merchantability, or fitness for a particular purpose.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
|
+
import { LitElement as t, css as n, html as r } from "lit";
|
|
3
|
+
import { customElement as i, property as a } from "lit/decorators.js";
|
|
4
|
+
/**
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
var o = class extends t {
|
|
20
|
+
constructor(...e) {
|
|
21
|
+
super(...e), this.variant = "contained", this.direction = "inbound";
|
|
22
|
+
}
|
|
23
|
+
static {
|
|
24
|
+
this.styles = n`
|
|
25
|
+
:host {
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
max-width: 85%;
|
|
28
|
+
font-family: inherit;
|
|
29
|
+
color-scheme: light dark;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.bubble {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: 8px;
|
|
36
|
+
padding: 14px 18px;
|
|
37
|
+
font-size: 0.95rem;
|
|
38
|
+
line-height: 1.5;
|
|
39
|
+
box-sizing: border-box;
|
|
40
|
+
transition: background-color 0.2s, color 0.2s;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Variant: Contained */
|
|
44
|
+
:host([variant='contained']) .bubble {
|
|
45
|
+
border-radius: 16px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:host([variant='contained'][direction='inbound']) .bubble {
|
|
49
|
+
background: var(
|
|
50
|
+
--ui-message-bubble-inbound-bg,
|
|
51
|
+
var(--md-sys-color-surface-container-high, #e2e2e2)
|
|
52
|
+
);
|
|
53
|
+
color: var(--md-sys-color-on-surface);
|
|
54
|
+
border-bottom-left-radius: 4px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:host([variant='contained'][direction='outbound']) .bubble {
|
|
58
|
+
background: var(
|
|
59
|
+
--ui-message-bubble-outbound-bg,
|
|
60
|
+
var(--md-sys-color-primary, #0066cc)
|
|
61
|
+
);
|
|
62
|
+
color: var(--md-sys-color-on-primary, #ffffff);
|
|
63
|
+
border-bottom-right-radius: 4px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Variant: Flat */
|
|
67
|
+
:host([variant='flat']) .bubble {
|
|
68
|
+
padding: 8px 0;
|
|
69
|
+
background: transparent;
|
|
70
|
+
color: var(--md-sys-color-on-surface);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
:host([variant='flat'][direction='outbound']) .bubble {
|
|
74
|
+
padding: 12px 16px;
|
|
75
|
+
background: var(--md-sys-color-surface-container-highest);
|
|
76
|
+
border-radius: 12px;
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
render() {
|
|
81
|
+
return r`
|
|
82
|
+
<div class="bubble">
|
|
83
|
+
<slot></slot>
|
|
84
|
+
</div>
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
e([a({
|
|
89
|
+
type: String,
|
|
90
|
+
reflect: !0
|
|
91
|
+
})], o.prototype, "variant", void 0), e([a({
|
|
92
|
+
type: String,
|
|
93
|
+
reflect: !0
|
|
94
|
+
})], o.prototype, "direction", void 0), o = e([i("ui-message-bubble")], o);
|
|
95
|
+
export { o as UiMessageBubble };
|
|
@@ -59,12 +59,11 @@ var c = class extends r {
|
|
|
59
59
|
`;
|
|
60
60
|
}
|
|
61
61
|
render() {
|
|
62
|
-
|
|
63
|
-
let { state: e } = this._context, t = e === "recording", n = e === "processing" || e === "connecting", r = "mic";
|
|
62
|
+
let e = this._context?.state || "idle", t = e === "recording", n = e === "processing" || e === "connecting", r = "mic";
|
|
64
63
|
return t && (r = "stop"), n && (r = "hourglass_empty"), e === "success" && (r = "check"), e === "error" && (r = "error"), a`
|
|
65
64
|
<md-filled-icon-button
|
|
66
65
|
class="${e}"
|
|
67
|
-
?disabled=${n}
|
|
66
|
+
?disabled=${n || !this._context}
|
|
68
67
|
@click=${this._handleClick}
|
|
69
68
|
>
|
|
70
69
|
<md-icon>${r}</md-icon>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
|
+
import { LitElement as t, css as n, html as r } from "lit";
|
|
3
|
+
import { customElement as i, property as a } from "lit/decorators.js";
|
|
4
|
+
/**
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
var o = class extends t {
|
|
20
|
+
constructor(...e) {
|
|
21
|
+
super(...e), this.delay = "0s";
|
|
22
|
+
}
|
|
23
|
+
static {
|
|
24
|
+
this.styles = n`
|
|
25
|
+
:host {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
}
|
|
28
|
+
.dot {
|
|
29
|
+
width: 6px;
|
|
30
|
+
height: 6px;
|
|
31
|
+
border-radius: 50%;
|
|
32
|
+
background: var(--ui-typing-dot-color, currentColor);
|
|
33
|
+
animation: pulse 1.2s infinite ease-in-out;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes pulse {
|
|
37
|
+
0%,
|
|
38
|
+
100% {
|
|
39
|
+
transform: scale(0.8);
|
|
40
|
+
opacity: 0.4;
|
|
41
|
+
}
|
|
42
|
+
50% {
|
|
43
|
+
transform: scale(1.2);
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
render() {
|
|
50
|
+
return r`<div class="dot" style="animation-delay: ${this.delay}"></div>`;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
e([a({ type: String })], o.prototype, "delay", void 0), o = e([i("ui-typing-dot")], o);
|
|
54
|
+
export { o as UiTypingDot };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
|
+
import "../atoms/ui-message-bubble.js";
|
|
3
|
+
import { LitElement as t, css as n, html as r } from "lit";
|
|
4
|
+
import { customElement as i, property as a } from "lit/decorators.js";
|
|
5
|
+
import { classMap as o } from "lit/directives/class-map.js";
|
|
6
|
+
/**
|
|
7
|
+
* Copyright 2026 Google LLC
|
|
8
|
+
*
|
|
9
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
* you may not use this file except in compliance with the License.
|
|
11
|
+
* You may obtain a copy of the License at
|
|
12
|
+
*
|
|
13
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
*
|
|
15
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
* See the License for the specific language governing permissions and
|
|
19
|
+
* limitations under the License.
|
|
20
|
+
*/
|
|
21
|
+
var s = class extends t {
|
|
22
|
+
constructor(...e) {
|
|
23
|
+
super(...e), this.direction = "inbound", this.variant = "contained";
|
|
24
|
+
}
|
|
25
|
+
static {
|
|
26
|
+
this.styles = n`
|
|
27
|
+
:host {
|
|
28
|
+
display: flex;
|
|
29
|
+
width: 100%;
|
|
30
|
+
margin-bottom: 1rem;
|
|
31
|
+
font-family: inherit;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.item-container {
|
|
35
|
+
display: flex;
|
|
36
|
+
gap: 12px;
|
|
37
|
+
width: 100%;
|
|
38
|
+
align-items: flex-end;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.item-container.inbound {
|
|
42
|
+
justify-content: flex-start;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.item-container.outbound {
|
|
46
|
+
flex-direction: row-reverse;
|
|
47
|
+
justify-content: flex-start; /* This correctly pushes to the right because of row-reverse */
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.avatar-slot {
|
|
51
|
+
width: 32px;
|
|
52
|
+
height: 32px;
|
|
53
|
+
flex-shrink: 0;
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Hide avatar slot if no children are present */
|
|
60
|
+
.avatar-slot:not(:has(*)) {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.content-wrapper {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
gap: 4px;
|
|
68
|
+
max-width: 80%;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.item-container.inbound .content-wrapper {
|
|
72
|
+
align-items: flex-start;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.item-container.outbound .content-wrapper {
|
|
76
|
+
align-items: flex-end;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.meta-slot {
|
|
80
|
+
font-size: 0.7rem;
|
|
81
|
+
font-weight: 500;
|
|
82
|
+
opacity: 0.6;
|
|
83
|
+
padding: 0 4px;
|
|
84
|
+
display: flex;
|
|
85
|
+
gap: 8px;
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
render() {
|
|
90
|
+
return r`
|
|
91
|
+
<div class=${o({
|
|
92
|
+
"item-container": !0,
|
|
93
|
+
[this.direction]: !0
|
|
94
|
+
})}>
|
|
95
|
+
<div class="avatar-slot">
|
|
96
|
+
<slot name="avatar"></slot>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div class="content-wrapper">
|
|
100
|
+
<ui-message-bubble .direction=${this.direction} .variant=${this.variant}>
|
|
101
|
+
<slot></slot>
|
|
102
|
+
</ui-message-bubble>
|
|
103
|
+
<div class="meta-slot">
|
|
104
|
+
<slot name="meta"></slot>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
`;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
e([a({ type: String })], s.prototype, "direction", void 0), e([a({ type: String })], s.prototype, "variant", void 0), s = e([i("ui-chat-item")], s);
|
|
112
|
+
export { s as UiChatItem };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
|
+
import { LitElement as t, css as n, html as r } from "lit";
|
|
3
|
+
import { customElement as i, query as a } from "lit/decorators.js";
|
|
4
|
+
/**
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
var o = class extends t {
|
|
20
|
+
static {
|
|
21
|
+
this.styles = n`
|
|
22
|
+
:host {
|
|
23
|
+
display: block;
|
|
24
|
+
height: 100%;
|
|
25
|
+
width: 100%;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.scroll-container {
|
|
30
|
+
height: 100%;
|
|
31
|
+
width: 100%;
|
|
32
|
+
overflow-y: auto;
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
padding: 1rem;
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
scroll-behavior: smooth;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Scrollbar Styling */
|
|
41
|
+
.scroll-container::-webkit-scrollbar {
|
|
42
|
+
width: 6px;
|
|
43
|
+
}
|
|
44
|
+
.scroll-container::-webkit-scrollbar-track {
|
|
45
|
+
background: transparent;
|
|
46
|
+
}
|
|
47
|
+
.scroll-container::-webkit-scrollbar-thumb {
|
|
48
|
+
background: var(--md-sys-color-outline-variant);
|
|
49
|
+
border-radius: 10px;
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
updated(e) {
|
|
54
|
+
super.updated(e), this.scrollToBottom();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Imperatively scroll to the most recent message.
|
|
58
|
+
*/
|
|
59
|
+
scrollToBottom() {
|
|
60
|
+
this._container && (this._container.scrollTop = this._container.scrollHeight);
|
|
61
|
+
}
|
|
62
|
+
render() {
|
|
63
|
+
return r`
|
|
64
|
+
<div class="scroll-container">
|
|
65
|
+
<slot @slotchange=${this.scrollToBottom}></slot>
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
e([a(".scroll-container")], o.prototype, "_container", void 0), o = e([i("ui-chat-list")], o);
|
|
71
|
+
export { o as UiChatList };
|
|
@@ -77,11 +77,15 @@ var o = class extends t {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
.preview-panel {
|
|
80
|
-
display:
|
|
80
|
+
display: block; /* Keep in DOM for script access */
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
.preview-panel
|
|
84
|
-
|
|
83
|
+
:host([mode='code']) .preview-panel {
|
|
84
|
+
position: absolute;
|
|
85
|
+
visibility: hidden;
|
|
86
|
+
pointer-events: none;
|
|
87
|
+
height: 0;
|
|
88
|
+
overflow: hidden;
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
.code-panel {
|
|
@@ -98,7 +102,7 @@ var o = class extends t {
|
|
|
98
102
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
.code-panel
|
|
105
|
+
:host([mode='code']) .code-panel {
|
|
102
106
|
display: block;
|
|
103
107
|
}
|
|
104
108
|
`;
|
|
@@ -126,16 +130,17 @@ var o = class extends t {
|
|
|
126
130
|
</div>
|
|
127
131
|
|
|
128
132
|
<div class="content-area">
|
|
129
|
-
<div class="preview-panel
|
|
133
|
+
<div class="preview-panel">
|
|
130
134
|
<slot></slot>
|
|
131
135
|
</div>
|
|
132
136
|
|
|
133
|
-
<pre
|
|
134
|
-
class="code-panel ${this.mode === "code" ? "active" : ""}"
|
|
135
|
-
><code><slot name="code"></slot></code></pre>
|
|
137
|
+
<pre class="code-panel"><code><slot name="code"></slot></code></pre>
|
|
136
138
|
</div>
|
|
137
139
|
`;
|
|
138
140
|
}
|
|
139
141
|
};
|
|
140
|
-
e([a({ type: String })], o.prototype, "title", void 0), e([a({ type: String })], o.prototype, "description", void 0), e([a({
|
|
142
|
+
e([a({ type: String })], o.prototype, "title", void 0), e([a({ type: String })], o.prototype, "description", void 0), e([a({
|
|
143
|
+
type: String,
|
|
144
|
+
reflect: !0
|
|
145
|
+
})], o.prototype, "mode", void 0), o = e([i("ui-showcase-card")], o);
|
|
141
146
|
export { o as UiShowcaseCard };
|
|
@@ -53,8 +53,7 @@ var c = class extends r {
|
|
|
53
53
|
`;
|
|
54
54
|
}
|
|
55
55
|
render() {
|
|
56
|
-
|
|
57
|
-
let { state: e, transcript: t, partialTranscript: n, analyserNode: r } = this._context, i = e === "recording", o = e === "processing" || e === "connecting";
|
|
56
|
+
let { state: e = "idle", transcript: t = "", partialTranscript: n = "", analyserNode: r = void 0 } = this._context || {}, i = e === "recording", o = e === "processing" || e === "connecting";
|
|
58
57
|
return a`
|
|
59
58
|
${!i && !o && !(t || n) ? a`<span class="placeholder">${this.placeholder}</span>` : a`<span class="transcript">${n || t}</span>`}
|
|
60
59
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
|
+
import "../atoms/ui-typing-dot.js";
|
|
3
|
+
import { LitElement as t, css as n, html as r } from "lit";
|
|
4
|
+
import { customElement as i } from "lit/decorators.js";
|
|
5
|
+
/**
|
|
6
|
+
* Copyright 2026 Google LLC
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
* you may not use this file except in compliance with the License.
|
|
10
|
+
* You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
var a = class extends t {
|
|
21
|
+
static {
|
|
22
|
+
this.styles = n`
|
|
23
|
+
:host {
|
|
24
|
+
display: inline-flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: 4px;
|
|
27
|
+
padding: 8px 12px;
|
|
28
|
+
background: var(--md-sys-color-surface-container-low);
|
|
29
|
+
border-radius: 12px;
|
|
30
|
+
border-bottom-left-radius: 4px;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
render() {
|
|
35
|
+
return r`
|
|
36
|
+
<ui-typing-dot delay="0s"></ui-typing-dot>
|
|
37
|
+
<ui-typing-dot delay="0.2s"></ui-typing-dot>
|
|
38
|
+
<ui-typing-dot delay="0.4s"></ui-typing-dot>
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
a = e([i("ui-typing-indicator")], a);
|
|
43
|
+
export { a as UiTypingIndicator };
|