mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 08:56:46 -04:00
56de26fe22
This PR migrates the whole monorepo to use Tailwind v4: - Removed `@tailwindcss/container-queries` plugin since it's included by default in v4, - Bump all instances of Tailwind to v4. Made minimal changes to the shared config to remove non-supported features (`alpha` mentions), - Migrate all apps to be compatible with v4 configs, - Fix the `typography.css` import in 3 apps, - Add missing rules which were included by default in v3, - Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot of classes - Rename all misnamed classes according to https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all apps. --------- Co-authored-by: Jordi Enric <jordi.err@gmail.com>
227 lines
7.2 KiB
TypeScript
227 lines
7.2 KiB
TypeScript
'use client'
|
|
|
|
import { createContext, PropsWithChildren, useContext, useEffect, useState } from 'react'
|
|
import { AnchorProvider, Toc, TOCItems, TOCScrollArea, type AnchorProviderProps } from 'ui-patterns'
|
|
|
|
export default function MultiSelectDemo() {
|
|
return (
|
|
<TocAnchorsProvider>
|
|
<div
|
|
id="example-toc-single-demo"
|
|
className="p-4 md:p-8 grid md:grid-cols-4 gap-4 max-h-[600px] overflow-y-auto"
|
|
>
|
|
<div className="md:col-span-3">
|
|
<div className="prose max-w-none">
|
|
<h1>Getting Started with Cloud Computing</h1>
|
|
|
|
<h2 id="single-introduction">
|
|
Introduction
|
|
<a
|
|
href="#single-introduction"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h2>
|
|
<p>
|
|
Cloud computing has revolutionized how we build and deploy applications. This guide
|
|
will walk you through the fundamental concepts and best practices.
|
|
</p>
|
|
|
|
<h2 id="single-key-concepts">
|
|
Key Concepts
|
|
<a
|
|
href="#single-key-concepts"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h2>
|
|
<p>
|
|
Before diving deep into cloud services, it's important to understand the basic
|
|
building blocks that make cloud computing possible.
|
|
</p>
|
|
|
|
<h3 id="single-iaas">
|
|
Infrastructure as a Service (IaaS)
|
|
<a
|
|
href="#single-iaas"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h3>
|
|
<p>
|
|
IaaS provides virtualized computing resources over the internet. This includes virtual
|
|
machines, storage, and networking.
|
|
</p>
|
|
|
|
<h3 id="single-paas">
|
|
Platform as a Service (PaaS)
|
|
<a
|
|
href="#single-paas"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h3>
|
|
<p>
|
|
PaaS delivers a platform allowing customers to develop, run, and manage applications
|
|
without dealing with infrastructure.
|
|
</p>
|
|
|
|
<h2 id="single-best-practices">
|
|
Best Practices
|
|
<a
|
|
href="#single-best-practices"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h2>
|
|
<p>
|
|
Following cloud computing best practices ensures optimal performance, security, and
|
|
cost-effectiveness.
|
|
</p>
|
|
|
|
<h3 id="single-security">
|
|
Security Considerations
|
|
<a
|
|
href="#single-security"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h3>
|
|
<p>
|
|
Security should be your top priority when working with cloud services. Implement
|
|
proper authentication, encryption, and access controls.
|
|
</p>
|
|
|
|
<h3 id="single-cost-optimization">
|
|
Cost Optimization
|
|
<a
|
|
href="#single-cost-optimization"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h3>
|
|
<p>
|
|
Learn how to optimize your cloud spending through resource planning, monitoring, and
|
|
implementing cost-saving strategies.
|
|
</p>
|
|
|
|
<h2 id="single-conclusion">
|
|
Conclusion
|
|
<a
|
|
href="#single-conclusion"
|
|
aria-hidden="true"
|
|
className="ml-2 opacity-0 group-hover:opacity-100 transition"
|
|
>
|
|
<span aria-hidden="true">#</span>
|
|
</a>
|
|
</h2>
|
|
<p>
|
|
Cloud computing continues to evolve, offering new possibilities for businesses and
|
|
developers alike. Stay updated with the latest trends and best practices.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<TocComponent />
|
|
</div>
|
|
</TocAnchorsProvider>
|
|
)
|
|
}
|
|
|
|
const TocComponent = () => {
|
|
const { toc } = useTocAnchors()
|
|
|
|
return (
|
|
<Toc className="sticky top-0 border-l">
|
|
<h3 className="inline-flex items-center gap-1.5 font-mono text-xs uppercase text-foreground pl-[calc(1.5rem+6px)]">
|
|
On this page
|
|
</h3>
|
|
<TOCScrollArea className="ml-[-2px]">
|
|
<TOCItems items={toc} />
|
|
</TOCScrollArea>
|
|
</Toc>
|
|
)
|
|
}
|
|
|
|
interface TOCHeader {
|
|
id?: string
|
|
text: string
|
|
link: string
|
|
level: number
|
|
}
|
|
|
|
const TocAnchorsContext = createContext<AnchorProviderProps | undefined>(undefined)
|
|
|
|
const useTocAnchors = () => {
|
|
const context = useContext(TocAnchorsContext)
|
|
if (!context) {
|
|
throw new Error('useTocAnchors must be used within an TocAnchorsContext')
|
|
}
|
|
return context
|
|
}
|
|
|
|
const TocAnchorsProvider = ({ children }: PropsWithChildren) => {
|
|
const [tocList, setTocList] = useState<TOCHeader[]>([])
|
|
|
|
const toc = tocList.map((item) => ({
|
|
title: item.text,
|
|
url: item.link,
|
|
depth: item.level,
|
|
}))
|
|
|
|
useEffect(() => {
|
|
/**
|
|
* Because we're directly querying the DOM, needs the setTimeout so the DOM
|
|
* update will happen first.
|
|
*/
|
|
const timeoutHandle = setTimeout(() => {
|
|
const headings = Array.from(
|
|
document.querySelector('#example-toc-single-demo')?.querySelectorAll('h2, h3') ?? []
|
|
)
|
|
|
|
const newHeadings = headings
|
|
.filter((heading) => heading.id)
|
|
.map((heading) => {
|
|
const text = heading?.textContent?.replace('#', '')
|
|
const link = heading.querySelector('a')?.getAttribute('href')
|
|
if (!link) return null
|
|
|
|
const level = heading.tagName === 'H2' ? 2 : 3
|
|
|
|
return { text, link, level } as Partial<TOCHeader>
|
|
})
|
|
.filter((x): x is TOCHeader => !!x && !!x.text && !!x.link && !!x.level)
|
|
|
|
setTocList(newHeadings)
|
|
}, 100)
|
|
|
|
return () => clearTimeout(timeoutHandle)
|
|
/**
|
|
* window.location.href needed to recalculate toc when page changes,
|
|
* `useSubscribeTocRerender` above will trigger the rerender
|
|
*/
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [typeof window !== 'undefined' && window.location.href])
|
|
|
|
return (
|
|
<TocAnchorsContext.Provider value={{ toc }}>
|
|
<AnchorProvider toc={toc} single={true}>
|
|
{children}
|
|
</AnchorProvider>
|
|
</TocAnchorsContext.Provider>
|
|
)
|
|
}
|