Skip to content
Merged
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
35 changes: 35 additions & 0 deletions docs/public/pascal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/homepage-features/inlay-hints.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions docs/src/assets/landing.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
:root {
--sl-font: Inter, var(--sl-font-system);
--vide-accent-hsl: 200, 100%, 50%;
--vide-accent: hsl(var(--vide-accent-hsl));
--vide-overlay: hsla(var(--vide-accent-hsl), 0.18);
Expand Down Expand Up @@ -28,6 +29,21 @@
color: var(--sl-color-gray-2);
}

.title-wrapper .site-title + ul {
min-width: max-content;
white-space: nowrap;
}

.title-wrapper .site-title + ul a {
white-space: nowrap;
}

@media (max-width: 57.999rem), (hover: none), (pointer: coarse) {
.title-wrapper .site-title + ul {
display: none;
}
}

[data-has-hero] .hero {
padding-block-start: clamp(3rem, 8vw, 7rem);
}
Expand Down Expand Up @@ -80,6 +96,29 @@
var(--sl-color-black);
}

.pascal-footer {
display: flex;
align-items: center;
justify-content: center;
gap: 0.25rem;
margin-top: 3rem;
color: #3f6fae;
font-size: 1rem;
font-weight: 600;
line-height: 1.4;
}

.pascal-footer img {
width: auto;
height: 1em;
}

.pascal-footer a,
.pascal-footer a:hover {
color: inherit;
text-decoration: none;
}

@media (min-width: 72rem) {
:root {
--vide-toc-width: 14rem;
Expand Down
208 changes: 163 additions & 45 deletions docs/src/components/HomepageComparisonTable.astro
Original file line number Diff line number Diff line change
@@ -1,83 +1,135 @@
---
import type {
ComparisonColumn,
ComparisonFeatureKey,
ComparisonFeatureValue,
ComparisonProduct,
} from '../data/homepage';

type FeatureStatus = 'yes' | 'partial' | 'no';

interface FeatureColumn {
key: ComparisonFeatureKey;
type FeatureStatusMeta = {
className: string;
label: string;
}
symbol: string;
};
type FeatureCell = {
status: FeatureStatusMeta;
tooltip?: string;
isBeta: boolean;
};

interface Props {
columns: readonly FeatureColumn[];
columns: readonly (ComparisonColumn & { key: ComparisonFeatureKey })[];
products: readonly ComparisonProduct[];
}

const { columns, products } = Astro.props as Props;

const statusMap: Record<FeatureStatus, { className: string; label: string; symbol: string }> = {
const statusMap: Record<FeatureStatus, FeatureStatusMeta> = {
yes: { className: 'vide-comparison-table__true', label: 'Yes', symbol: '✓' },
partial: { className: 'vide-comparison-table__partial', label: 'Partial', symbol: '△' },
no: { className: 'vide-comparison-table__false', label: 'No', symbol: '✕' },
};

const getStatus = (value: ComparisonFeatureValue): FeatureStatus => {
if (value === 'partial') return 'partial';
if (typeof value === 'string') return 'partial';
return value ? 'yes' : 'no';
};

const getPartialReason = (value: ComparisonFeatureValue) => {
if (typeof value !== 'string' || value === 'partial') return undefined;
return value;
};

const getFeatureCell = (product: ComparisonProduct, key: ComparisonFeatureKey): FeatureCell => {
const value = product.features[key];
return {
status: statusMap[getStatus(value)],
tooltip: getPartialReason(value),
isBeta: product.betaFeatureKeys?.includes(key) ?? false,
};
};
---

<table class="vide-comparison-table">
<thead>
<tr>
<th></th>
<div class="vide-comparison-table-wrap">
<table class="vide-comparison-table">
<thead>
<tr>
<th></th>
{
products.map((product) => (
<th>
<strong class:list={{ 'vide-comparison-table__brand': product.highlighted }}>
{product.name}
</strong>
<br />
<span class="vide-comparison-table__meta">{product.meta}</span>
</th>
))
}
</tr>
</thead>
<tbody>
{
products.map((product) => (
<th>
<strong class:list={{ 'vide-comparison-table__brand': product.highlighted }}>
{product.name}
</strong>
<br />
<span class="vide-comparison-table__meta">{product.meta}</span>
</th>
columns.map((column) => (
<tr>
<th scope="row">
{column.href ? (
<a class="vide-comparison-table__feature-link" href={column.href}>
{column.label}
</a>
) : (
column.label
)}
</th>
{products.map((product) => {
const cell = getFeatureCell(product, column.key);
const tooltipId = cell.tooltip
? `comparison-tooltip-${product.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}-${column.key}`
: undefined;
return (
<td>
<span
class:list={{
[cell.status.className]: true,
'vide-comparison-table__with-tooltip': Boolean(cell.tooltip),
}}
aria-label={cell.status.label}
aria-describedby={tooltipId}
tabindex={cell.tooltip ? 0 : undefined}
>
{cell.status.symbol}
{cell.isBeta && <span class="vide-comparison-table__beta">BETA</span>}
{cell.tooltip && (
<span id={tooltipId} class="vide-comparison-table__tooltip" role="tooltip">
{cell.tooltip}
</span>
)}
</span>
</td>
);
})}
</tr>
))
}
</tr>
</thead>
<tbody>
{
columns.map((column) => (
<tr>
<th scope="row">{column.label}</th>
{products.map((product) => {
const status = statusMap[getStatus(product.features[column.key])];
const isBeta = product.betaFeatureKeys?.includes(column.key);
return (
<td>
<span class={status.className} aria-label={status.label}>
{status.symbol}
{isBeta && <span class="vide-comparison-table__beta">BETA</span>}
</span>
</td>
);
})}
</tr>
))
}
</tbody>
</table>
</tbody>
</table>
</div>

<style>
.vide-comparison-table-wrap {
width: 100%;
margin: 1rem auto 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}

.vide-comparison-table {
display: table;
width: 100%;
min-width: 100%;
min-width: 42rem;
table-layout: fixed;
margin: 1rem auto 0;
margin: 0;
border-collapse: collapse;
border-spacing: 0;
overflow: hidden;
Expand Down Expand Up @@ -110,6 +162,21 @@ const getStatus = (value: ComparisonFeatureValue): FeatureStatus => {
font-size: 1.22rem;
font-weight: 700;
line-height: 1.15;
white-space: nowrap;
}

.vide-comparison-table__feature-link {
color: inherit;
text-decoration: underline;
text-decoration-color: color-mix(in srgb, var(--vide-accent) 65%, transparent);
text-underline-offset: 0.16em;
transition: color 0.16s ease, text-decoration-color 0.16s ease;
}

.vide-comparison-table__feature-link:hover,
.vide-comparison-table__feature-link:focus-visible {
color: var(--vide-accent);
text-decoration-color: currentColor;
}

.vide-comparison-table__brand {
Expand Down Expand Up @@ -164,4 +231,55 @@ const getStatus = (value: ComparisonFeatureValue): FeatureStatus => {
line-height: 1;
letter-spacing: 0;
}

.vide-comparison-table__with-tooltip {
cursor: help;
}

.vide-comparison-table__with-tooltip:focus-visible {
outline: 2px solid color-mix(in srgb, var(--vide-accent) 70%, white);
outline-offset: 0.18rem;
}

.vide-comparison-table__tooltip {
position: absolute;
bottom: calc(100% + 0.55rem);
left: 50%;
z-index: 1;
width: max-content;
max-width: min(16rem, 80vw);
padding: 0.45rem 0.6rem;
border-radius: 0.45rem;
background: rgba(15, 23, 42, 0.96);
color: #fff;
font-size: 0.78rem;
font-weight: 500;
line-height: 1.35;
text-align: left;
text-decoration: none;
text-shadow: none;
-webkit-text-fill-color: #fff;
white-space: normal;
opacity: 0;
pointer-events: none;
transform: translateX(-50%) translateY(0.2rem);
transition: opacity 0.16s ease, transform 0.16s ease;
}

.vide-comparison-table__tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
border-width: 0.35rem;
border-style: solid;
border-color: rgba(15, 23, 42, 0.96) transparent transparent;
transform: translateX(-50%);
}

.vide-comparison-table__with-tooltip:hover .vide-comparison-table__tooltip,
.vide-comparison-table__with-tooltip:focus-visible .vide-comparison-table__tooltip {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
</style>
13 changes: 3 additions & 10 deletions docs/src/components/HomepageCta.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { homepageCtaActions } from '../data/homepage';
---

<section class="vide-cta">
<h2>立刻体验</h2>
<p>直接打开文档快速上手,或者先去 Playground 里实际试一遍补全、跳转和诊断体验。</p>
<div class="sl-flex actions vide-cta__actions">
{
homepageCtaActions.map((action) => (
Expand All @@ -19,18 +17,13 @@ import { homepageCtaActions } from '../data/homepage';

<style>
.vide-cta {
margin-block: 3rem 1rem;
}

.vide-cta p {
max-width: 42rem;
color: var(--sl-color-gray-2);
margin-block: 6rem 4rem;
}

.vide-cta__actions {
gap: 1rem;
margin-top: 1.25rem;
justify-content: flex-start;
flex-wrap: wrap;
justify-content: center;
}
Comment thread
roife marked this conversation as resolved.

.vide-cta__actions :global(.sl-link-button.primary) {
Expand Down
Loading
Loading