feat(showcase): moldura de navegador, um video por vez e video ampliado nos cards
- cards com moldura de navegador (endereco real) e brilho na cor do site no card que toca - um video por vez: o do card sob o mouse/foco, ou o mais perto do centro da tela; nada baixa antes de tocar, e um botao pausa os videos que se mexem sozinhos - janela ampliada em <dialog> nativo: troca computador/celular mantendo o ponto do site, capitulos clicaveis, controles proprios, setas entre projetos e foco devolvido ao fechar - dados e capitulos de cada projeto em lib/project-showcase.ts (substitui project-videos.ts) Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
60dc2f1878
commit
a1a1e91135
18 files changed
+3564
-155
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import type { CSSProperties, ReactNode } from "react";
|
||||
|
||||
/** Endereço mostrado na barra: o do site publicado, ou o do código quando não há demonstração. */
|
||||
export function displayUrl(project: {
|
||||
demoUrl?: string | null;
|
||||
githubUrl?: string | null;
|
||||
}): { text: string; secure: boolean } | null {
|
||||
for (const raw of [project.demoUrl, project.githubUrl]) {
|
||||
if (!raw) continue;
|
||||
try {
|
||||
const url = new URL(raw);
|
||||
const path = url.pathname === "/" ? "" : url.pathname.replace(/\/$/, "");
|
||||
return {
|
||||
text: `${url.host.replace(/^www\./, "")}${path}`,
|
||||
secure: url.protocol === "https:",
|
||||
};
|
||||
} catch {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Janela de navegador em volta da captura: três pontos, barra com o endereço real e a tela.
|
||||
* A barra é decoração (aria-hidden); o endereço também aparece como texto no próprio card.
|
||||
*/
|
||||
export function BrowserFrame({
|
||||
url,
|
||||
children,
|
||||
className = "",
|
||||
style,
|
||||
}: {
|
||||
url: { text: string; secure: boolean } | null;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}) {
|
||||
return (
|
||||
<div className={`ds-bframe ${className}`.trim()} style={style}>
|
||||
<div className="ds-bframe-bar" aria-hidden="true">
|
||||
<span className="ds-bframe-dots">
|
||||
<i />
|
||||
<i />
|
||||
<i />
|
||||
</span>
|
||||
<span className="ds-bframe-url">
|
||||
{url?.secure && (
|
||||
<svg
|
||||
viewBox="0 0 12 12"
|
||||
width="10"
|
||||
height="10"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.4"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect x="2.5" y="5.5" width="7" height="5" />
|
||||
<path d="M4 5.5V4a2 2 0 0 1 4 0v1.5" />
|
||||
</svg>
|
||||
)}
|
||||
<span>{url?.text ?? "pré-visualização"}</span>
|
||||
</span>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user