Skip to content
Closed

test #8763

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Breadboard

> [!WARNING]
> **Deprecation Notice (November 2026):** Breadboard and Project Opal are graduating out of Google Labs and will be sunset on **November 17, 2026**.
>
> - **Hosted Services:** Web access via [opal.google.com](http://opal.google.com), [breadboard-ai.web.app](https://breadboard-ai.web.app), and backend execution services will turn off on November 17, 2026.
> - **User Files:** Saved workflow files are stored in JSON format inside your personal Google Drive (`My Drive > Opal`). We recommend copying any prompt text you wish to keep before November 17, or downloading the JSON files from Drive anytime after to view in any plain text editor.
> - **Where to Build Next:** Try [**Skills in Gemini**](https://blog.google/products-and-platforms/products/gemini/automate-tasks-with-skills/) for chat automations, or [**Google AI Studio**](https://aistudio.google.com) for advanced model prompting and multi-step workflows.
> - **Repository Status:** This repository will be placed in read-only / archived mode on November 17, 2026.
> - For full details, please see the [**Opal FAQ**](https://developers.google.com/opal/faq).

**A library for prototyping generative AI applications.**

![Stability](https://img.shields.io/badge/stability-wip-green) [![Discord](https://img.shields.io/discord/1138546999872999556?logo=discord)](https://discord.gg/breadboard)
Expand Down
168 changes: 162 additions & 6 deletions packages/visual-editor/public/styles/shell.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,127 @@
--sys-color--body-background-dark: #131314;
}

iframe#opal-app {
body {
display: flex;
flex-direction: column;
height: 100vh;
height: 100dvh;
width: 100vw;
height: 100vh; /* fallback */
height: 100dvh; /* account for iOS URL bar dynamic height */
overflow: hidden;
margin: 0;
padding: 0;
font-family: "Google Sans", Roboto, Arial, sans-serif;
}

.turndown-banner {
display: flex;
align-items: center;
gap: 16px;
padding: 12px 24px;
background-color: #f0f4f9;
color: #1f1f1f;
border-bottom: 1px solid #e0e2ec;
font-size: 14px;
line-height: 20px;
z-index: 100;
box-sizing: border-box;
flex-shrink: 0;
}

.turndown-banner[hidden] {
display: none !important;
}

.banner-leading-icon {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
color: #0b57d0;
}

.banner-leading-icon .info-icon {
width: 20px;
height: 20px;
}

.banner-content {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 6px;
flex: 1 1 auto;
}

.banner-title {
font-weight: 600;
color: #1f1f1f;
}

.banner-description {
font-weight: 400;
color: #444746;
}

.banner-actions {
display: flex;
align-items: center;
gap: 12px;
flex-shrink: 0;
}

.banner-action-link {
color: #0b57d0;
font-weight: 500;
text-decoration: none;
border-radius: 4px;
padding: 4px 8px;
transition: background-color 0.2s ease;
}

.banner-action-link:hover {
background-color: rgba(11, 87, 208, 0.08);
text-decoration: underline;
}

.banner-action-link:focus-visible {
outline: 2px solid #0b57d0;
outline-offset: 2px;
}

.banner-dismiss-button {
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 50%;
color: #444746;
transition: background-color 0.2s ease, color 0.2s ease;
}

.banner-dismiss-button:hover {
background-color: rgba(0, 0, 0, 0.06);
color: #1f1f1f;
}

.banner-dismiss-button:focus-visible {
outline: 2px solid #0b57d0;
outline-offset: 2px;
}

.banner-dismiss-button .close-icon {
width: 18px;
height: 18px;
}

iframe#opal-app {
flex: 1 1 auto;
min-height: 0;
width: 100%;
border: none;
position: fixed;
top: 0;
left: 0;
background: var(--sys-color--body-background-light);
}

Expand Down Expand Up @@ -67,6 +180,49 @@ iframe[src^="https://drive"]
}

@media (prefers-color-scheme: dark) {
.turndown-banner {
background-color: #1e1f20;
color: #e3e3e3;
border-bottom-color: #444746;
}

.banner-leading-icon {
color: #a8c7fa;
}

.banner-title {
color: #e3e3e3;
}

.banner-description {
color: #c4c7c5;
}

.banner-action-link {
color: #a8c7fa;
}

.banner-action-link:hover {
background-color: rgba(168, 199, 250, 0.08);
}

.banner-action-link:focus-visible {
outline-color: #a8c7fa;
}

.banner-dismiss-button {
color: #c4c7c5;
}

.banner-dismiss-button:hover {
background-color: rgba(255, 255, 255, 0.08);
color: #e3e3e3;
}

.banner-dismiss-button:focus-visible {
outline-color: #a8c7fa;
}

iframe#opal-app {
background: var(--sys-color--body-background-dark);
}
Expand Down
31 changes: 31 additions & 0 deletions packages/visual-editor/shell/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,37 @@
/>
</head>
<body>
<div class="turndown-banner" id="turndown-banner" role="region" aria-label="Product graduation notice">
<div class="banner-leading-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" class="info-icon">
<path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288T13 8q0-.425-.288-.713T12 7q-.425 0-.713.288T11 8q0 .425.288.713T12 9zm0 13q-2.075 0-3.9-.788t-3.175-2.137q-1.35-1.35-2.137-3.175T2 12q0-2.075.788-3.9t2.137-3.175q1.35-1.35 3.175-2.137T12 2q2.075 0 3.9.788t3.175 2.137q1.35 1.35 2.138 3.175T22 12q0 2.075-.788 3.9t-2.137 3.175q-1.35 1.35-3.175 2.138T12 22zm0-2q3.35 0 5.675-2.325T20 12q0-3.35-2.325-5.675T12 4Q8.65 4 6.325 6.325T4 12q0 3.35 2.325 5.675T12 20zm0-8z"/>
</svg>
</div>
<div class="banner-content">
<span class="banner-title">Opal is graduating out of Labs on November 17, 2026.</span>
<span class="banner-description">Workflow data is still in your Drive under My Drive &gt; Opal.</span>
</div>
<div class="banner-actions">
<a
class="banner-action-link"
href="https://developers.google.com/opal/faq"
target="_blank"
rel="noopener noreferrer"
>
Learn more
</a>
<button
type="button"
class="banner-dismiss-button"
id="banner-dismiss-button"
aria-label="Dismiss banner"
>
<svg viewBox="0 0 24 24" class="close-icon" aria-hidden="true">
<path fill="currentColor" d="m12 13.4-4.9 4.9q-.275.275-.7.275t-.7-.275q-.275-.275-.275-.7t.275-.7l4.9-4.9-4.9-4.9q-.275-.275-.275-.7t.275-.7q.275-.275.7-.275t.7.275l4.9 4.9 4.9-4.9q.275-.275.7-.275t.7.275q.275.275.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7q-.275.275-.7.275t-.7-.275L12 13.4Z"/>
</svg>
</button>
</div>
</div>
<iframe
id="opal-app"
sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-modals allow-storage-access-by-user-activation allow-downloads allow-top-navigation"
Expand Down
25 changes: 25 additions & 0 deletions packages/visual-editor/src/shell/opal-shell-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,33 @@ function setupCookieBar(): {
// Shell initialization
// ---------------------------------------------------------------------------

initializeTurndownBanner();
initializeOpalShellGuest();

function initializeTurndownBanner() {
const banner = document.getElementById("turndown-banner");
const dismissBtn = document.getElementById("banner-dismiss-button");
if (!banner) return;

const params = new URLSearchParams(window.location.search);
const isEmbeddedInGemini =
CLIENT_DEPLOYMENT_CONFIG.SHELL_PREFIX === "/_gemini" ||
params.get("share_surface") === "gemini";

if (
isEmbeddedInGemini ||
params.get("turndown_banner") === "false" ||
params.get("opal_turndown_banner") === "false"
) {
banner.hidden = true;
return;
}

dismissBtn?.addEventListener("click", () => {
banner.hidden = true;
});
}

async function initializeOpalShellGuest() {
const guestOrigin = CLIENT_DEPLOYMENT_CONFIG.SHELL_GUEST_ORIGIN;
if (!guestOrigin || guestOrigin === "*") {
Expand Down
Loading