global image component (#27410)

* global ui Image component

* migrate docs images to new global component

* use Image component in www mdx components

* update Image description

* remove redundant props

* better ZoomContent types

* remove ThemeImage

* remove ZommableImg component

* add use client to Image component
This commit is contained in:
Francesco Sansalvadore
2024-07-03 13:02:13 +02:00
committed by GitHub
parent 0dbb5e5225
commit efc5ee6ec4
52 changed files with 763 additions and 890 deletions

View File

@@ -4,10 +4,9 @@
// Basic UI things
import Link from 'next/link'
import { Accordion, Admonition, Alert, Button, CodeBlock, markdownComponents } from 'ui'
import { Accordion, Admonition, Alert, Button, CodeBlock, Image, markdownComponents } from 'ui'
import { GlassPanel } from 'ui-patterns/GlassPanel'
import { IconPanel } from 'ui-patterns/IconPanel'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import { TabPanel, Tabs } from '~/components/Tabs'
// Common components
@@ -143,7 +142,7 @@ const components = {
IconMenuStorage,
IconMenuSwift,
IconPanel,
Image: (props: any) => <ThemeImage fill className="object-contain" {...props} />,
Image: (props: any) => <Image fill className="object-contain" {...props} />,
JwtGenerator,
KotlinProjectSetup,
Link,

View File

@@ -120,15 +120,14 @@ It is possible to upload more vectors to a single table if Memory allows it (for
</Admonition>
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/hnsw-dims--light.png',
dark: '/docs/img/ai/instance-type/hnsw-dims--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/hnsw-dims--light.png',
dark: '/docs/img/ai/instance-type/hnsw-dims--dark.png',
}}
zoomable
/>
## IVFFlat
@@ -255,15 +254,14 @@ For 1,000,000 vectors 40 probes results to accuracy of 0.98. Note that exact val
</TabPanel>
</Tabs>
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/size-to-rps--light.png',
dark: '/docs/img/ai/going-prod/size-to-rps--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/size-to-rps--light.png',
dark: '/docs/img/ai/going-prod/size-to-rps--dark.png',
}}
zoomable
/>
<Admonition type="note">
@@ -292,27 +290,27 @@ You can increase the Requests per Second by increasing `m` and `ef_construction`
>
<TabPanel id="hnsw" label="HNSW">
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--dark.png',
}}
zoomable
/>
</TabPanel>
<TabPanel id="ivfflat" label="IVFFlat">
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/lists-for-1m--light.png',
dark: '/docs/img/ai/instance-type/lists-for-1m--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/lists-for-1m--light.png',
dark: '/docs/img/ai/instance-type/lists-for-1m--dark.png',
}}
zoomable
/>
</TabPanel>
</Tabs>
@@ -322,15 +320,15 @@ Check out more tips and the complete step-by-step guide in [Going to Production
We follow techniques outlined in the [ANN Benchmarks](https://github.com/erikbern/ann-benchmarks) methodology. A Python test runner is responsible for uploading the data, creating the index, and running the queries. The pgvector engine is implemented using [vecs](https://github.com/supabase/vecs), a Python client for pgvector.
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/vecs-benchmark--light.png',
dark: '/docs/img/ai/instance-type/vecs-benchmark--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/instance-type/vecs-benchmark--light.png',
dark: '/docs/img/ai/instance-type/vecs-benchmark--dark.png',
}}
className="max-h-[650px]"
zoomable
/>
Each test is run for a minimum of 30-40 minutes. They include a series of experiments executed at different concurrency levels to measure the engine's performance under different load types. The results are then averaged.

View File

@@ -14,15 +14,14 @@ For small workloads, it's typical to store your data in a single database.
If you've used [Vecs](/docs/guides/ai/vecs-python-client) to create 3 different collections, you can expose collections to your web or mobile application using [views](/docs/guides/database/tables#views):
<div>
<Image
alt="single database"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--single-database--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--single-database--dark.png',
}}
/>
</div>
<Image
alt="single database"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--single-database--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--single-database--dark.png',
}}
zoomable
/>
For example, with 3 collections, called `docs`, `posts`, and `images`, we could expose the "docs" inside the public schema like this:
@@ -50,15 +49,14 @@ const { data, error } = await supabase
As you move into production, we recommend splitting your collections into separate projects. This is because it allows your vector stores to scale independently of your production data. Vectors typically grow faster than operational data, and they have different resource requirements. Running them on separate databases removes the single-point-of-failure.
<div>
<Image
alt="With secondaries"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--with-secondaries--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--with-secondaries--dark.png',
}}
/>
</div>
<Image
alt="With secondaries"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--with-secondaries--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--with-secondaries--dark.png',
}}
zoomable
/>
You can use as many secondary databases as you need to manage your collections. With this architecture, you have 2 options for accessing collections within your application:
@@ -134,12 +132,11 @@ const { data, error } = await supabase
This diagram provides an example architecture that allows you to access the collections either with our client libraries or using Vecs. You can add as many secondary databases as you need (in this example we only show one):
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--multi-database--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--multi-database--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/scaling/engineering-for-scale--multi-database--light.png',
dark: '/docs/img/ai/scaling/engineering-for-scale--multi-database--dark.png',
}}
zoomable
/>

View File

@@ -32,11 +32,12 @@ We'll be saving the Postgres documentation in Postgres, and ChatGPT will be retr
<Image
alt="diagram reference"
className="!m-0"
className="max-h-[600px]"
src={{
light: '/docs/img/ai/chatgpt-plugins/chatgpt-plugin-scheme--light.png',
dark: '/docs/img/ai/chatgpt-plugins/chatgpt-plugin-scheme--dark.png',
}}
zoomable
/>
### Step 1: Fork the ChatGPT Retrieval Plugin repository

View File

@@ -28,15 +28,14 @@ On the other hand, if you need to scale your application, you will need to [crea
`pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
<div>
<Image
alt="dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute addon"
src={{
light: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--dark.png',
}}
/>
</div>
<Image
alt="dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute addon"
src={{
light: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--dark.png',
}}
zoomable
/>
## HNSW, understanding `ef_construction`, `ef_search`, and `m`
@@ -50,15 +49,14 @@ Search parameters:
- `ef_search` is the size of the dynamic list for the nearest neighbors (used during the search). Increasing `ef_search` will result in better accuracy, but it will also increase the time required to execute a query (40 is the default value).
<div>
<Image
alt="dbpedia embeddings comparing hnsw queries-per-second using different build parameters"
src={{
light: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--dark.png',
}}
/>
</div>
<Image
alt="dbpedia embeddings comparing hnsw queries-per-second using different build parameters"
src={{
light: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-hnsw-build-parameters--dark.png',
}}
zoomable
/>
## IVFFlat, understanding `probes` and `lists`
@@ -72,15 +70,14 @@ The values of lists and probes directly affect accuracy and queries per second (
You can find more examples of how `lists` and `probes` constants affect accuracy and QPS in [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blogpost.
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/lists-count--light.png',
dark: '/docs/img/ai/going-prod/lists-count--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/lists-count--light.png',
dark: '/docs/img/ai/going-prod/lists-count--dark.png',
}}
zoomable
/>
## Performance tips when using indexes
@@ -114,12 +111,11 @@ You can look at our [Choosing Compute Add-on](/docs/guides/ai/choosing-compute-a
Or take a look at our [pgvector 0.5.0 performance](https://supabase.com/blog/increase-performance-pgvector-hnsw) and [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blog posts to see what pgvector is capable of and how the above technique can be used to achieve the best results.
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/size-to-rps--light.png',
dark: '/docs/img/ai/going-prod/size-to-rps--dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/ai/going-prod/size-to-rps--light.png',
dark: '/docs/img/ai/going-prod/size-to-rps--dark.png',
}}
zoomable
/>

View File

@@ -52,15 +52,13 @@ The hierarchical aspect of HNSW builds off of the idea of skip lists.
Skip lists are multi-layer linked lists. The bottom layer is a regular linked list connecting an ordered sequence of elements. Each new layer above removes some elements from the underlying layer (based on a fixed probability), producing a sparser subsequence that “skips” over elements.
<div>
<Image
alt="visual of an example skip list"
src={{
light: '/docs/img/ai/vector-indexes/hnsw-indexes/skip-list--light.png',
dark: '/docs/img/ai/vector-indexes/hnsw-indexes/skip-list--dark.png',
}}
/>
</div>
<Image
alt="visual of an example skip list"
src={{
light: '/docs/img/ai/vector-indexes/hnsw-indexes/skip-list--light.png',
dark: '/docs/img/ai/vector-indexes/hnsw-indexes/skip-list--dark.png',
}}
/>
When searching for an element, the algorithm begins at the top layer and traverses its linked list horizontally. If the target element is found, the algorithm stops and returns it. Otherwise if the next element in the list is greater than the target (or `NULL`), the algorithm drops down to the next layer below. Since each layer below is less sparse than the layer above (with the bottom layer connecting all elements), the target will eventually be found. Skip lists offer O(log n) average complexity for both search and insertion/deletion.
@@ -68,9 +66,11 @@ When searching for an element, the algorithm begins at the top layer and travers
A navigable small world (NSW) is a special type of proximity graph that also includes long-range connections between nodes. These long-range connections support the “small world” property of the graph, meaning almost every node can be reached from any other node within a few hops. Without these additional long-range connections, many hops would be required to reach a far-away node.
<img
<Image
alt="visual of an example navigable small world graph"
src="/docs/img/ai/vector-indexes/hnsw-indexes/nsw.png"
className="max-h-[600px] mx-auto"
zoomable
/>
The “navigable” part of NSW specifically refers to the ability to logarithmically scale the greedy search algorithm on the graph, an algorithm that attempts to make only the locally optimal choice at each hop. Without this property, the graph may still be considered a small world with short paths between far-away nodes, but the greedy algorithm tends to miss them. Greedy search is ideal for NSW because it is quick to navigate and has low computational costs.

View File

@@ -15,6 +15,7 @@ This guide shows you how to set up your local Supabase development environment t
light: '/docs/img/local-dev-environment--light.svg',
dark: '/docs/img/local-dev-environment.svg',
}}
zoomable
/>
## Set up a local environment

View File

@@ -32,19 +32,16 @@ A "connection pool" is a system (external to Postgres) which manages Postgres co
When a client makes a request, the pooler "allocates" an available connection to the client. When the client transaction or session is completed the connection is returned to the pool and is free to be used by another client.
<figure>
<Image
className="hidden dark:block"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works.png"
/>
<Image
className="dark:hidden"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works--light.png"
/>
<figcaption>Connecting to the database directly vs using a Connection Pooler</figcaption>
</figure>
<Image
alt="New migration files trigger migrations on the preview instance."
src={{
dark: '/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works.png',
light:
'/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works--light.png',
}}
caption="Connecting to the database directly vs using a Connection Pooler"
zoomable
/>
Every Supabase project comes with a connection pooler for managing connections to your database. The pooler provides 2 important services:
@@ -195,15 +192,13 @@ You can obtain your connection info and Server root certificate from your applic
<StepHikeCompact.Code>
<Image
className="hidden dark:block"
alt="Register a new postgres server."
src="/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin.png?v=2"
/>
<Image
className="dark:hidden"
alt="Register a new postgres server."
src="/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin--light.png"
/>
src={{
dark: '/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin.png?v=2',
light:
'/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin--light.png',
}}
/>
</StepHikeCompact.Code>

View File

@@ -6,15 +6,14 @@ description: 'Organizing tables into partitions in Postgres.'
Table partitioning is a technique that allows you to divide a large table into smaller, more manageable parts called “partitions”.
<div>
<Image
alt="multi database"
src={{
light: '/docs/img/database/partitions-light.png',
dark: '/docs/img/database/partitions-dark.png',
}}
/>
</div>
<Image
alt="multi database"
src={{
light: '/docs/img/database/partitions-light.png',
dark: '/docs/img/database/partitions-dark.png',
}}
className="max-h-[400px] !mx-auto"
/>
Each partition contains a subset of the data based on a specified criteria, such as a range of values or a specific condition. Partitioning can significantly improve query performance and simplify data management for large datasets.

View File

@@ -24,19 +24,16 @@ Supabase Branching works with Git. You can test changes in a separate, temporary
You can run multiple Preview Branches for every Supabase project. Branches contain all the Supabase features with their own API credentials. Preview Environments pause automatically after <SharedData data="config">branching.inactivity_period_in_minutes</SharedData> minutes of inactivity. Note that `pg_cron` executions will be impacted by inactivity related pausing.
<figure className="max-w-[700px] mx-auto">
<Image
className="hidden dark:block"
alt="Each branch has a separate Supabase instance."
src="/docs/img/guides/platform/branching/github-workflow-without-branching.jpg?v=1"
/>
<Image
className="dark:hidden"
alt="Each branch has a separate Supabase instance."
src="/docs/img/guides/platform/branching/github-workflow-without-branching--light.jpg?v=1"
/>
<figcaption>Each Branch is a separate environment.</figcaption>
</figure>
<Image
zoomable
className="max-w-[700px] !mx-auto"
alt="Each branch has a separate Supabase instance."
caption="Each Branch is a separate environment."
src={{
dark: '/docs/img/guides/platform/branching/github-workflow-without-branching.jpg?v=1',
light: '/docs/img/guides/platform/branching/github-workflow-without-branching--light.jpg?v=1',
}}
/>
### Branching workflow
@@ -58,21 +55,16 @@ The Preview Branch is also seeded with sample data based on `./supabase/seed.sql
Supabase Branching follows the [Trunk Based Development](https://trunkbaseddevelopment.com/) workflow, with one main Production branch and multiple development branches:
<figure className="max-w-[700px] mx-auto">
<Image
className="hidden dark:block"
alt="Each GitHub branch can have its own Supabase preview branch."
src="/docs/img/guides/platform/branching/github-workflow.jpg?v=1"
/>
<Image
className="dark:hidden"
alt="Each GitHub branch can have its own Supabase preview branch."
src="/docs/img/guides/platform/branching/github-workflow--light.jpg?v=1"
/>
<figcaption>Each GitHub branch can have its own Supabase preview branch.</figcaption>
</figure>
<Image
zoomable
className="max-w-[700px] !mx-auto"
alt="Each GitHub branch can have its own Supabase preview branch."
caption="Each GitHub branch can have its own Supabase preview branch."
src={{
dark: '/docs/img/guides/platform/branching/github-workflow.jpg?v=1',
light: '/docs/img/guides/platform/branching/github-workflow--light.jpg?v=1',
}}
/>
### Production branch
@@ -84,21 +76,16 @@ After connecting your Supabase project to one of the supported [Git providers](#
The Git integration can read files from your Git provider, watching every commit and pull request. Each time a commit is pushed with new migrations in the `./supabase/migrations` directory, the migrations are run on the matching Supabase Preview environment:
<figure className="max-w-[700px] mx-auto">
<Image
className="hidden dark:block"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/platform/branching/github-workflow-commit-migration.jpg?v=1"
/>
<Image
className="dark:hidden"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/platform/branching/github-workflow-commit-migration--light.jpg?v=1"
/>
<figcaption>New migration files trigger migrations on the preview instance.</figcaption>
</figure>
<Image
zoomable
className="max-w-[700px] !mx-auto"
alt="New migration files trigger migrations on the preview instance."
caption="New migration files trigger migrations on the preview instance."
src={{
dark: '/docs/img/guides/platform/branching/github-workflow-commit-migration.jpg?v=1',
light: '/docs/img/guides/platform/branching/github-workflow-commit-migration--light.jpg?v=1',
}}
/>
### Data changes
@@ -517,11 +504,13 @@ When you open a pull request on GitHub, the Supabase integration automatically c
A comment is added to your PR with the deployment status of your preview branch. Statuses are shown separately for Database, Services, and APIs.
<figure className="max-w-[700px] mx-auto">
<Image src="/docs/img/guides/platform/branching/develop-your-app-open-pull-request-github.jpg?v=1" />
{/* prettier-ignore */}
<figcaption>Supabase GitHub integration will comment on your PR with the status of your Preview Branch, including whether migrations have successfully run.</figcaption>
</figure>
<Image
zoomable
className="max-w-[700px] !mx-auto"
alt="GitHub view of the deployment status of your preview branch"
caption="Supabase GitHub integration will comment on your PR with the status of your Preview Branch, including whether migrations have successfully run."
src="/docs/img/guides/platform/branching/develop-your-app-open-pull-request-github.jpg?v=1"
/>
Every time a new commit is pushed that changes the migration files in `./supabase/migrations`, the new migrations are run against the preview branch. You can check the status of these runs in the comment's Tasks table.
@@ -529,11 +518,13 @@ Every time a new commit is pushed that changes the migration files in `./supabas
We highly recommend turning on a 'required check' for the Supabase integration. You can do this from your GitHub repository settings. This prevents PRs from being merged when migration checks fail, and stops invalid migrations from being merged into your production branch.
<figure className="max-w-[700px] mx-auto">
<Image src="/docs/img/guides/platform/branching/github-required-check.jpg?v=1" />
{/* prettier-ignore */}
<figcaption>Check the "Require status checks to pass before merging" option.</figcaption>
</figure>
<Image
zoomable
className="max-w-[700px] !mx-auto"
alt='Check the "Require status checks to pass before merging" option.'
caption='Check the "Require status checks to pass before merging" option.'
src="/docs/img/guides/platform/branching/github-required-check.jpg?v=1"
/>
### Disable branching

View File

@@ -71,30 +71,27 @@ The 90-day window allows Supabase to introduce platform changes that may not be
During the 90-day restore window a paused project can be restored to the platform with a single button click from [Studio's dashboard page](https://supabase.com/dashboard/projects).
<div>
<Image
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-90-day.png"
/>
</div>
<Image
zoomable
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-90-day.png"
/>
After the 90-day restore window, you can download your project's backup file from the project dashboard. This backup is compatible with [pg_restore](https://www.postgresql.org/docs/current/app-pgrestore.html). You can extract your data from it, or attempt to manually restore the project.
<div>
<Image
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-dl-backup.png"
/>
</div>
<Image
zoomable
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-dl-backup.png"
/>
If you upgrade to a paid plan while your project is paused, any expired one-click restore options are reenabled. Since the backup was taken outside the backwards compatibility window, it may fail to restore. If you have a problem restoring your backup after upgrading, contact [Support](/support).
<div>
<Image
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-paid-tier.png"
/>
</div>
<Image
zoomable
alt="Project Paused: 90 Days Remaining"
src="/docs/img/guides/platform/paused-paid-tier.png"
/>
#### Disk sizing

View File

@@ -6,25 +6,25 @@ description: 'Transfer a project to another organization.'
With the introduction of [Organization-based Billing](/docs/guides/platform/org-based-billing), were adding the ability to freely transfer projects between different organizations. Head to your [projects' general settings](https://supabase.com/dashboard/project/_/settings/general) to initiate a project transfer.
<div>
<Image
alt="Project Transfer: General Settings"
src={{
light: '/docs/img/guides/platform/project-transfer-overview--light.png',
dark: '/docs/img/guides/platform/project-transfer-overview.png',
}}
/>
</div>
<Image
alt="Project Transfer: General Settings"
src={{
light: '/docs/img/guides/platform/project-transfer-overview--light.png',
dark: '/docs/img/guides/platform/project-transfer-overview.png',
}}
className="max-w-[600px] !mx-auto border rounded-md"
zoomable
/>
<div>
<Image
alt="Project Transfer: Confirmation Modal"
src={{
light: '/docs/img/guides/platform/project-transfer-modal--light.png',
dark: '/docs/img/guides/platform/project-transfer-modal.png',
}}
/>
</div>
<Image
alt="Project Transfer: Confirmation Modal"
src={{
light: '/docs/img/guides/platform/project-transfer-modal--light.png',
dark: '/docs/img/guides/platform/project-transfer-modal.png',
}}
className="max-w-[600px] !mx-auto"
zoomable
/>
Source organization - the organization the project currently belongs to
Target organization - the organization you want to move the project to

View File

@@ -10,21 +10,12 @@ Read Replicas are additional databases that are kept in sync with your Primary d
- **Improved latency:** For projects with a global user base, additional databases can be deployed closer to users to reduce latency.
- **Redundancy:** Read Replicas provide data redundancy.
<figure className="max-w-[700px] mx-auto">
<Image
className="hidden dark:block"
alt="Map view of all project databases"
src="/docs/img/guides/platform/read-replicas/map-view.png?v=1"
/>
<Image
className="dark:hidden"
alt="Map view of all project databases."
src="/docs/img/guides/platform/read-replicas/map-view.png?v=1"
/>
</figure>
<Image
alt="Map view of all project databases."
src="/docs/img/guides/platform/read-replicas/map-view.png?v=1"
containerClassName="max-w-[700px] !mx-auto"
zoomable
/>
## About Read Replicas
@@ -127,21 +118,12 @@ If you use a [custom domain](/docs/guides/platform/custom-domains), requests wil
In the SQL editor, you can choose if you want to run the query on a particular Read Replica.
<figure className="max-w-[700px] mx-auto">
<Image
className="hidden dark:block"
alt="SQL editor view."
src="/docs/img/guides/platform/read-replicas/sql-editor.png?v=1"
/>
<Image
className="dark:hidden"
alt="SQL editor view."
src="/docs/img/guides/platform/read-replicas/sql-editor.png?v=1"
/>
</figure>
<Image
alt="SQL editor view."
src="/docs/img/guides/platform/read-replicas/sql-editor.png?v=1"
containerClassName="max-w-[700px]"
zoomable
/>
### Logging
@@ -195,13 +177,13 @@ In this replication method, the Primary continuously buffers WAL changes to a lo
### File-based log shipping 🤝 streaming replication
<figure className="max-w-[700px] mx-auto">
<Image
alt="Map view of Primary and Read Replica databases"
src="/docs/img/guides/platform/read-replicas/streaming-replication-dark.png?v=1"
/>
<figcaption>Map view of Primary and Read Replica databases</figcaption>
</figure>
<Image
alt="Map view of Primary and Read Replica databases"
caption="Map view of Primary and Read Replica databases"
src="/docs/img/guides/platform/read-replicas/streaming-replication-dark.png?v=1"
containerClassName="max-w-[700px] mx-auto"
zoomable
/>
We bring these two methods together to achieve quick, stable, and reliable replication. Each method addresses the limitations of the other. Streaming replication minimizes replication lag, while file-based log shipping provides a fallback. For file-based log shipping, we use our existing Point In Time Recovery (PITR) infrastructure. We regularly archive files from the Primary using [WAL-G](https://github.com/wal-g/wal-g), an open source archival and restoration tool, and ship the WAL files to S3.

View File

@@ -278,3 +278,22 @@ article p code {
th code {
@apply text-nowrap;
}
/* Zoomable image */
[data-rmiz-modal]:focus,
[data-rmiz-modal-overlay]:focus {
outline: none !important;
}
[data-rmiz-modal-overlay],
[data-rmiz-modal-img] {
transition-timing-function: cubic-bezier(0.24, 0.25, 0.05, 1) !important;
}
[data-rmiz-modal-overlay='visible'] {
background-color: hsl(var(--background-default)) !important;
opacity: 0.8;
}
[data-rmiz-modal-img] {
image-rendering: high-quality;
}

View File

@@ -72,15 +72,13 @@ What specifically do we gain when we have fewer dimensions? Faster queries and l
Take a look at dot product for example:
<div>
<Img
alt="multi database"
src={{
light: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/dot-product-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/dot-product-dark.png',
}}
/>
</div>
<Img
alt="multi database"
src={{
light: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/dot-product-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/dot-product-dark.png',
}}
/>
Dot product is the product of each vector element pair summed together into a single result. Fewer dimensions in the vector means fewer calculations for every computed distance.
@@ -94,40 +92,34 @@ We compared the performance of `text-embedding-ada-002` from OpenAI (1536 dimens
We observed pgvector with `all-MiniLM-L6-v2` outperforming `text-embedding-ada-002` by 78% when holding the accuracy@10 constant at 0.99. This gap increases as you lower the accuracy. Postgres was using just 4GB of RAM with 384d vectors generated by `all-MiniLM-L6-v2` compared to 7.5GB with `text-embedding-ada-002`.
<div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-99-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-99-dark.png',
}}
/>
</div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-99-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-99-dark.png',
}}
/>
<div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-98-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-98-dark.png',
}}
/>
</div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-98-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-98-dark.png',
}}
/>
After that, we decided to try the recently published [gte-small](https://huggingface.co/thenlper/gte-small) (also 384 dimensions), and the results were even more astonishing. With `gte-small`, we could set `probes=10` to achieve the same level of `accuracy@10 = 0.99`. Consequently, we observed more than a 200% improvement in queries per second for pgvector with embeddings generated by `gte-small` compared to `all-MiniLM-L6-v2`.
<div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-gte-small-99-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-gte-small-99-dark.png',
}}
/>
</div>
<Img
alt="multi database"
src={{
light:
'/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-gte-small-99-light.png',
dark: '/images/blog/2023-08-03-fewer-dimensions-are-better-pgvector/performance-comparison-gte-small-99-dark.png',
}}
/>
## Choosing an embedding model

View File

@@ -64,7 +64,7 @@ if (sessionData.session) {
The database stores everything that happens in the app. We have 6 different tables to store everything from the questions to the answers that users leave for each question in a game. Each time the admin clicks the “Start Game” button of a quiz set from the host dashboard, a new game is created. The database is designed so that the same set of users can play games with the same quiz set multiple times. The full table definitions under `superbase/migrations` in the [GitHub repo](https://github.com/supabase-community/kahoot-alternative/tree/main/supabase/migrations).
![Database diagram](/images/blog/oss-kahoot-alternative/erd.png)
<Img src="/images/blog/oss-kahoot-alternative/erd.png" alt="Database diagram" />
### Realtime

View File

@@ -1,15 +1,14 @@
import { createClient } from '@supabase/supabase-js'
import { Button } from 'ui'
import { Button, Image } from 'ui'
import { useState } from 'react'
// Import Swiper React components
import { useRouter } from 'next/router'
import Image from 'next/image'
import NextImage from 'next/image'
import { ColorSwatchIcon, MenuIcon } from '@heroicons/react/outline'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { useTheme } from 'next-themes'
import { ThemeImage } from 'ui-patterns/ThemeImage'
function AuthWidgetSection() {
const supabase = createClient(
@@ -116,7 +115,7 @@ function AuthWidgetSection() {
</p>
<div className="mb-4 flex items-center space-x-2">
<div className="relative m-0 w-8 aspect-square flex items-center">
<Image
<NextImage
src={`${basePath}/images/product/auth/react-icon.svg`}
alt="react icon"
layout="fill"
@@ -207,7 +206,7 @@ function AuthWidgetSection() {
].join(' ')}
>
<div className="relative m-0 w-4 items-center justify-center text-red-900">
<ThemeImage
<Image
src={{
light: '/images/auth-ui/small--dark.svg',
dark: '/images/auth-ui/small--light.svg',
@@ -228,7 +227,7 @@ function AuthWidgetSection() {
].join(' ')}
>
<div className="relative m-0 w-4 items-center justify-center text-red-900">
<ThemeImage
<Image
src={{
light: '/images/auth-ui/medium--dark.svg',
dark: '/images/auth-ui/medium--light.svg',
@@ -249,7 +248,7 @@ function AuthWidgetSection() {
].join(' ')}
>
<div className="relative m-0 w-4 items-center justify-center flex text-red-900">
<ThemeImage
<Image
src={{
light: '/images/auth-ui/large--light.svg',
dark: '/images/auth-ui/large--dark.svg',

View File

@@ -10,11 +10,6 @@ export interface StepLink {
href: string
}
export interface ThemeImage {
dark?: string
light?: string
}
export interface StepProps {
title: string
icon?: string

View File

@@ -1,8 +1,7 @@
import React from 'react'
import Panel from '~/components/Panel'
import { Badge, Button, ButtonProps, IconCheck } from 'ui'
import { Badge, Button, ButtonProps, IconCheck, Image } from 'ui'
import Link from 'next/link'
import { ThemeImage } from 'ui-patterns'
export interface CardProps {
title: string
@@ -14,7 +13,7 @@ export interface CardProps {
target: HTMLAnchorElement['target']
type: ButtonProps['type']
}[]
image?: {
image: {
dark: string
light: string
}
@@ -54,7 +53,7 @@ const NewFeatureCard = (props: CardProps) => (
</div>
{props.image && (
<div className="hidden sm:flex lg:hidden xl:flex absolute object-bottom inset-0 left-auto items-center h-full aspect-[296/275]">
<ThemeImage
<Image
src={props.image}
alt={`database ${props.title}`}
width="296"

View File

@@ -1,18 +0,0 @@
import Zoom from 'react-medium-image-zoom'
import ZoomContent from './ZoomContent'
import { useBreakpoint } from 'common'
const ZoomableImg = ({ zoomable = true, children }: any) => {
const isMobile = useBreakpoint()
const Component = zoomable ? Zoom : 'span'
return (
<Component
{...(zoomable ? { ZoomContent: ZoomContent, zoomMargin: isMobile ? 20 : 80 } : undefined)}
>
{children}
</Component>
)
}
export default ZoomableImg

View File

@@ -1,8 +1,5 @@
import 'react-medium-image-zoom/dist/styles.css'
import { PropsWithChildren } from 'react'
import Image from 'next/image'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import NextImage from 'next/image'
import Avatar from '~/components/Avatar'
import CodeBlock from '~/components/CodeBlock/CodeBlock'
@@ -21,27 +18,16 @@ import {
Heading,
IconArrowUpRight,
IconTriangle,
Image,
} from 'ui'
import ImageFadeStack from '~/components/ImageFadeStack'
import ZoomableImg from '~/components/ZoomableImg/ZoomableImg'
import { type ImageProps } from 'ui/src/components/Image/Image'
// import all components used in blog articles here
// to do: move this into a helper/utils, it is used elsewhere
const ignoreClass = 'ignore-on-export'
const getCaptionAlign = (align?: 'left' | 'center' | 'right') => {
switch (align) {
case 'left':
return 'text-left'
case 'right':
return 'text-right'
case 'center':
default:
return 'text-center'
}
}
const LinkComponent = (props: PropsWithChildren<HTMLAnchorElement>) => (
<a
href={props.href}
@@ -104,37 +90,32 @@ export default function mdxComponents(type?: 'blog' | 'lp' | undefined) {
img: (props: any) => {
if (props.className !== ignoreClass) {
return (
<span className={['next-image--dynamic-fill'].join(' ')}>
<Image
{...props}
className={[type === 'blog' ? 'm-0 object-cover rounded-md border' : ''].join(' ')}
fill
loading="lazy"
/>
</span>
<Image
fill
className={cn(
'm-0 object-cover',
type === 'blog' ? 'rounded-md border' : '',
props.wide && 'wide',
props.className
)}
{...props}
/>
)
}
return <img {...props} />
},
Img: ({ zoomable = true, className, ...props }: any) => (
<figure className={cn('m-0', className)}>
<ZoomableImg zoomable={zoomable}>
<span
className={[
'next-image--dynamic-fill',
type === 'blog' ? 'rounded-md border' : '',
props.wide && 'wide',
].join(' ')}
>
<ThemeImage fill className="m-0 object-cover" {...props} />
</span>
</ZoomableImg>
{props.caption && (
<figcaption className={[getCaptionAlign(props.captionAlign)].join(' ')}>
{props.caption}
</figcaption>
Img: ({ zoomable = true, className, ...props }: ImageProps & { wide?: boolean }) => (
<Image
fill
className={cn(
'm-0 object-cover',
type === 'blog' ? 'rounded-md border' : '',
props.wide && 'wide',
className
)}
</figure>
zoomable={zoomable}
{...props}
/>
),
Link: LinkComponent,
code: (props: any) => <InlineCodeTag>{props.children}</InlineCodeTag>,

View File

@@ -54,7 +54,6 @@
"react-countdown": "^2.3.5",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.3",
"react-medium-image-zoom": "^5.1.8",
"react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.2.17",
"react-transition-group": "^4.4.1",

View File

@@ -1,9 +1,9 @@
import { Button, IconArrowUpRight, IconBriefcase, IconEye, IconLink, IconShield } from 'ui'
import { Button, IconArrowUpRight, IconBriefcase, IconEye, IconLink, IconShield, Image } from 'ui'
import ApiExamples from 'data/products/auth/auth-api-examples'
import AuthSqlRulesExamples from 'data/products/auth/auth-sql-rules-examples'
import Solutions from 'data/Solutions'
import { NextSeo } from 'next-seo'
import Image from 'next/image'
import NextImage from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
import AuthWidgetSection from '~/components/AuthWidget/AuthWidgetSection'
@@ -16,7 +16,6 @@ import APISection from '~/components/Sections/APISection'
import GithubExamples from '~/components/Sections/GithubExamples'
import ProductHeader from '~/components/Sections/ProductHeader'
import AuthProviders from '~/data/auth.json'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import ProductsNav from '~/components/Products/ProductsNav'
import { PRODUCT_NAMES } from 'shared-data/products'
@@ -60,7 +59,7 @@ function AuthPage() {
"Including PostgreSQL's policy engine, for fine-grained access rules.",
]}
image={[
<ThemeImage
<Image
src={{
light: `${basePath}/images/product/auth/header--light.png`,
dark: `${basePath}/images/product/auth/header--dark.png`,
@@ -96,7 +95,7 @@ function AuthPage() {
{AuthProviders.map((auth, i) => {
return (
<div className="flex w-fit items-center" key={i}>
<Image
<NextImage
src={`${basePath}/images/product/auth/${auth.name}-icon.svg`}
alt={`${auth.name} auth login icon`}
key={auth.name}

View File

@@ -3,11 +3,11 @@ import 'swiper/css'
import dynamic from 'next/dynamic'
import { NextSeo } from 'next-seo'
import Image from 'next/image'
import NextImage from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useState } from 'react'
import { Badge, Button, IconArrowUpRight, IconX, Tabs } from 'ui'
import { Badge, Button, IconArrowUpRight, IconX, Image, Tabs } from 'ui'
import { Swiper, SwiperSlide } from 'swiper/react'
// data
@@ -18,7 +18,6 @@ import ExtensionsExamplesData from 'data/products/database/extensions-examples'
import SqlViewCarouselData from 'data/products/database/sql-view-carousel.json'
import TableViewCarouselData from 'data/products/database/table-view-carousel.json'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import { TweetCard } from 'ui-patterns/TweetCard'
import ProductHeader from '~/components/Sections/ProductHeader'
import ProductsNav from '~/components/Products/ProductsNav'
@@ -85,10 +84,10 @@ function Database() {
"PostgreSQL is one of the world's most scalable databases.",
]}
image={[
<ThemeImage
<Image
src={{
light: `${basePath}/images/product/database/header--light-2.png`,
dark: `${basePath}/images/product/database/header--dark-2.png`,
light: `${basePath}/images/product/database/header--light-2.png`,
}}
alt="database header"
layout="responsive"
@@ -106,7 +105,7 @@ function Database() {
<ProductIcon icon={Solutions['database'].icon} />
<IconX />
<div className="flex w-fit items-center">
<Image
<NextImage
src={`${basePath}/images/product/database/postgresql-icon.svg`}
width={30}
height={30}

View File

@@ -1,4 +1,4 @@
import { Button, IconGrid, IconLayers, IconMenu } from 'ui'
import { Button, IconGrid, IconLayers, IconMenu, Image } from 'ui'
import ApiExamples from 'data/products/realtime/api-examples'
import AppExamples from 'data/products/realtime/app-examples'
import Solutions from 'data/Solutions'
@@ -14,7 +14,6 @@ import RealtimeStyles from './Realtime.module.css'
import ProductsNav from '~/components/Products/ProductsNav'
import 'swiper/css'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import { PRODUCT_NAMES } from 'shared-data/products'
const Cursor = ({ className = '', color = 'none' }) => {
@@ -194,7 +193,7 @@ function RealtimePage() {
return (
<>
<div className="flex flex-col gap-3">
<ThemeImage
<Image
alt={example.title}
src={{
light: `/images/realtime/example-apps/light/${example.img}?type=1`,

View File

@@ -1,4 +1,4 @@
import { Button, IconArrowUpRight, IconShuffle, IconWifi, IconX } from 'ui'
import { Button, IconArrowUpRight, IconShuffle, IconWifi, IconX, Image } from 'ui'
import ApiExamples from 'data/products/storage/api-examples'
import DashboardViewData from 'data/products/storage/dashboard-carousel.json'
import StoragePermissionsData from 'data/products/storage/permissions-examples'
@@ -16,7 +16,6 @@ import SectionContainer from '~/components/Layouts/SectionContainer'
import ProductIcon from '~/components/ProductIcon'
import APISection from '~/components/Sections/APISection'
import ProductHeader from '~/components/Sections/ProductHeader'
import { ThemeImage } from 'ui-patterns/ThemeImage'
import ProductsNav from '~/components/Products/ProductsNav'
import { PRODUCT_NAMES } from 'shared-data/products'
@@ -63,7 +62,7 @@ function StoragePage() {
'With custom policies and permissions that are familiar and easy to implement.',
]}
image={[
<ThemeImage
<Image
src={{
light: `${basePath}/images/product/storage/header--light.png`,
dark: `${basePath}/images/product/storage/header--dark.png`,

View File

@@ -5,35 +5,35 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Angelico de los Reyes at Supabase</description>
<language>en</language>
<lastBuildDate>Thu, 15 Dec 2022 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 15 Dec 2022 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-angelico_de_los_reyes-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-point-in-time-recovery</guid>
<title>Point in Time Recovery is now available for Pro projects</title>
<link>https://supabase.com/blog/postgres-point-in-time-recovery</link>
<description>We&apos;re making PITR available for more projects, with a new Dashboard UI that makes it simple to use.</description>
<pubDate>Thu, 15 Dec 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 15 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/continuous-postgresql-backup-walg</guid>
<title>Continuous PostgreSQL Backups using WAL-G</title>
<link>https://supabase.com/blog/continuous-postgresql-backup-walg</link>
<description>Have you ever wanted to restore your database&apos;s state to a particular moment in time? This post explains how, using WAL-G.</description>
<pubDate>Sat, 01 Aug 2020 16:00:00 GMT</pubDate>
<pubDate>Sat, 01 Aug 2020 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-templates</guid>
<title>What are PostgreSQL Templates?</title>
<link>https://supabase.com/blog/postgresql-templates</link>
<description>What are PostgreSQL templates and what are they used for?</description>
<pubDate>Wed, 08 Jul 2020 16:00:00 GMT</pubDate>
<pubDate>Wed, 08 Jul 2020 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-physical-logical-backups</guid>
<title>Physical vs Logical Backups in PostgreSQL</title>
<link>https://supabase.com/blog/postgresql-physical-logical-backups</link>
<description>What are physical and logical backups in Postgres?</description>
<pubDate>Mon, 06 Jul 2020 16:00:00 GMT</pubDate>
<pubDate>Mon, 06 Jul 2020 22:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,14 +5,14 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Ant Wilson at Supabase</description>
<language>en</language>
<lastBuildDate>Fri, 26 Feb 2021 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Fri, 26 Feb 2021 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-ant_wilson-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/cracking-postgres-interview</guid>
<title>Cracking PostgreSQL Interview Questions</title>
<link>https://supabase.com/blog/cracking-postgres-interview</link>
<description>Understand the top PostgreSQL Interview Questions</description>
<pubDate>Fri, 26 Feb 2021 16:00:00 GMT</pubDate>
<pubDate>Fri, 26 Feb 2021 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,14 +5,14 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Bo Lu at Supabase</description>
<language>en</language>
<lastBuildDate>Wed, 13 Dec 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Wed, 13 Dec 2023 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-bo_lu-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/supabase-wrappers-v02</guid>
<title>Supabase Wrappers v0.2: Query Pushdown &amp; Remote Subqueries</title>
<link>https://supabase.com/blog/supabase-wrappers-v02</link>
<description>Supabase Wrappers v0.2 brings more Wrappers, query pushdown, remote subquery, and more</description>
<pubDate>Wed, 13 Dec 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 13 Dec 2023 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,21 +5,21 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Mark Burggraf at Supabase</description>
<language>en</language>
<lastBuildDate>Wed, 23 Nov 2022 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Wed, 23 Nov 2022 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-burggraf-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/sql-or-nosql-both-with-postgresql</guid>
<title>SQL or NoSQL? Why not use both (with PostgreSQL)?</title>
<link>https://supabase.com/blog/sql-or-nosql-both-with-postgresql</link>
<description>How to turn Postgres into an easy-to-use NoSQL database that retains all the power of SQL</description>
<pubDate>Wed, 23 Nov 2022 16:00:00 GMT</pubDate>
<pubDate>Wed, 23 Nov 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgres-wasm</guid>
<title>Postgres WASM by Snaplet and Supabase</title>
<link>https://supabase.com/blog/postgres-wasm</link>
<description>We&apos;re open sourcing postgres-wasm, a PostgresQL server that runs inside a browser, with our friends at Snaplet.</description>
<pubDate>Sun, 02 Oct 2022 16:00:00 GMT</pubDate>
<pubDate>Sun, 02 Oct 2022 22:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,21 +5,21 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Egor Romanov at Supabase</description>
<language>en</language>
<lastBuildDate>Wed, 02 Aug 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Wed, 02 Aug 2023 22:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-egor_romanov-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</guid>
<title>pgvector: Fewer dimensions are better</title>
<link>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</link>
<description>Increase performance in pgvector by using embedding vectors with fewer dimensions</description>
<pubDate>Wed, 02 Aug 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 02 Aug 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pgvector-performance</guid>
<title>pgvector 0.4.0 performance</title>
<link>https://supabase.com/blog/pgvector-performance</link>
<description>There&apos;s been a lot of talk about pgvector performance lately, so we took some datasets and pushed pgvector to the limits to find out its strengths and limitations.</description>
<pubDate>Wed, 12 Jul 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 12 Jul 2023 22:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,14 +5,14 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Filipe Cabaço at Supabase</description>
<language>en</language>
<lastBuildDate>Mon, 08 Jan 2024 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Mon, 08 Jan 2024 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-filipe-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/elixir-clustering-using-postgres</guid>
<title>Elixir clustering using Postgres</title>
<link>https://supabase.com/blog/elixir-clustering-using-postgres</link>
<description>Learn about our approach to connecting multiple nodes in Elixir using Postgres</description>
<pubDate>Mon, 08 Jan 2024 16:00:00 GMT</pubDate>
<pubDate>Mon, 08 Jan 2024 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,28 +5,28 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Greg Richardson at Supabase</description>
<language>en</language>
<lastBuildDate>Tue, 05 Sep 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Tue, 05 Sep 2023 22:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-gregnr-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/increase-performance-pgvector-hnsw</guid>
<title>pgvector v0.5.0: Faster semantic search with HNSW indexes</title>
<link>https://supabase.com/blog/increase-performance-pgvector-hnsw</link>
<description>Increase performance in pgvector using HNSW indexes</description>
<pubDate>Tue, 05 Sep 2023 16:00:00 GMT</pubDate>
<pubDate>Tue, 05 Sep 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</guid>
<title>pgvector: Fewer dimensions are better</title>
<link>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</link>
<description>Increase performance in pgvector by using embedding vectors with fewer dimensions</description>
<pubDate>Wed, 02 Aug 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 02 Aug 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/openai-embeddings-postgres-vector</guid>
<title>Storing OpenAI embeddings in Postgres with pgvector</title>
<link>https://supabase.com/blog/openai-embeddings-postgres-vector</link>
<description>An example of how to build an AI-powered search engine using OpenAI&apos;s embeddings and PostgreSQL.</description>
<pubDate>Sun, 05 Feb 2023 16:00:00 GMT</pubDate>
<pubDate>Sun, 05 Feb 2023 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,7 +5,7 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Michel Pelletier at Supabase</description>
<language>en</language>
<lastBuildDate>Thu, 15 Dec 2022 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 15 Dec 2022 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-michel-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/vault-now-in-beta</guid>

View File

@@ -5,63 +5,63 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Oliver Rice at Supabase</description>
<language>en</language>
<lastBuildDate>Tue, 12 Dec 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Tue, 12 Dec 2023 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-oli_rice-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgrest-12</guid>
<title>PostgREST 12</title>
<link>https://supabase.com/blog/postgrest-12</link>
<description>PostgREST 12 is out and we take a look at some of the major new features like JWT Caching and Aggregate Functions</description>
<pubDate>Tue, 12 Dec 2023 16:00:00 GMT</pubDate>
<pubDate>Tue, 12 Dec 2023 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pg-graphql-postgres-functions</guid>
<title>pg_graphql: Postgres functions now supported</title>
<link>https://supabase.com/blog/pg-graphql-postgres-functions</link>
<description>pg_graphql now supports the most requested feature: Postgres functions a.k.a. User Defined Functions (UDFs)</description>
<pubDate>Mon, 11 Dec 2023 16:00:00 GMT</pubDate>
<pubDate>Mon, 11 Dec 2023 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</guid>
<title>pgvector: Fewer dimensions are better</title>
<link>https://supabase.com/blog/fewer-dimensions-are-better-pgvector</link>
<description>Increase performance in pgvector by using embedding vectors with fewer dimensions</description>
<pubDate>Wed, 02 Aug 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 02 Aug 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/whats-new-in-pg-graphql-v1-2</guid>
<title>What&apos;s New in pg_graphql v1.2</title>
<link>https://supabase.com/blog/whats-new-in-pg-graphql-v1-2</link>
<description>New Features in the v1.2 release of pg_graphql</description>
<pubDate>Thu, 20 Apr 2023 16:00:00 GMT</pubDate>
<pubDate>Thu, 20 Apr 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/type-constraints-in-65-lines-of-sql</guid>
<title>Type Constraints in 65 lines of SQL</title>
<link>https://supabase.com/blog/type-constraints-in-65-lines-of-sql</link>
<description>Creating validated data types in Postgres</description>
<pubDate>Thu, 16 Feb 2023 16:00:00 GMT</pubDate>
<pubDate>Thu, 16 Feb 2023 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pg-graphql-v1</guid>
<title>pg_graphql v1.0</title>
<link>https://supabase.com/blog/pg-graphql-v1</link>
<description>Announcing the v1.0 release of pg_graphql</description>
<pubDate>Thu, 15 Dec 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 15 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation</guid>
<title>pg_jsonschema: JSON Schema support for Postgres</title>
<link>https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation</link>
<description>Today we&apos;re releasing pg_jsonschema, a Postgres extension for JSON validation.</description>
<pubDate>Thu, 18 Aug 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 18 Aug 2022 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgres-audit</guid>
<title>Postgres Auditing in 150 lines of SQL</title>
<link>https://supabase.com/blog/postgres-audit</link>
<description>PostgreSQL has a robust set of features which we can leverage to create a generic auditing solution in 150 lines of SQL.</description>
<pubDate>Mon, 07 Mar 2022 16:00:00 GMT</pubDate>
<pubDate>Mon, 07 Mar 2022 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,42 +5,42 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Paul Copplestone at Supabase</description>
<language>en</language>
<lastBuildDate>Sun, 30 Apr 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Sun, 30 Apr 2023 22:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-paul_copplestone-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-pluggable-strorage</guid>
<title>Next steps for Postgres pluggable storage</title>
<link>https://supabase.com/blog/postgres-pluggable-strorage</link>
<description>Exploring history of Postgres pluggable storage and the possibility of landing it in the Postgres core.</description>
<pubDate>Sun, 30 Apr 2023 16:00:00 GMT</pubDate>
<pubDate>Sun, 30 Apr 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgres-crdt</guid>
<title>pg_crdt - an experimental CRDT extension for Postgres</title>
<link>https://supabase.com/blog/postgres-crdt</link>
<description>Embedding Yjs and Automerge into Postgres for collaborative applications.</description>
<pubDate>Fri, 09 Dec 2022 16:00:00 GMT</pubDate>
<pubDate>Fri, 09 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</guid>
<title>Partial data dumps using Postgres Row Level Security</title>
<link>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</link>
<description>Using RLS to create seed files for local PostgreSQL testing.</description>
<pubDate>Mon, 27 Jun 2022 16:00:00 GMT</pubDate>
<pubDate>Mon, 27 Jun 2022 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgres-as-a-cron-server</guid>
<title>Postgres as a CRON Server</title>
<link>https://supabase.com/blog/postgres-as-a-cron-server</link>
<description>Running repetitive tasks with your Postgres database.</description>
<pubDate>Thu, 04 Mar 2021 16:00:00 GMT</pubDate>
<pubDate>Thu, 04 Mar 2021 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-views</guid>
<title>Postgres Views</title>
<link>https://supabase.com/blog/postgresql-views</link>
<description>Creating and using a view in PostgreSQL.</description>
<pubDate>Tue, 17 Nov 2020 16:00:00 GMT</pubDate>
<pubDate>Tue, 17 Nov 2020 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -26,21 +26,21 @@
<title>pgvector 0.4.0 performance</title>
<link>https://supabase.com/blog/pgvector-performance</link>
<description>There&apos;s been a lot of talk about pgvector performance lately, so we took some datasets and pushed pgvector to the limits to find out its strengths and limitations.</description>
<pubDate>Wed, 12 Jul 2023 16:00:00 GMT</pubDate>
<pubDate>Wed, 12 Jul 2023 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/new-in-postgres-15</guid>
<title>What&apos;s new in Postgres 15?</title>
<link>https://supabase.com/blog/new-in-postgres-15</link>
<description>Describes the release of Postgres 15, new features and reasons to use it</description>
<pubDate>Thu, 15 Dec 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 15 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-commitfest</guid>
<title>What is PostgreSQL commitfest and how to contribute</title>
<link>https://supabase.com/blog/postgresql-commitfest</link>
<description>A time-tested method for contributing to the core Postgres code</description>
<pubDate>Wed, 26 Oct 2022 16:00:00 GMT</pubDate>
<pubDate>Wed, 26 Oct 2022 22:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,14 +5,14 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Philipp Steinrötter at Supabase</description>
<language>en</language>
<lastBuildDate>Thu, 07 Dec 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 07 Dec 2023 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-philipp-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-language-server-implementing-parser</guid>
<title>Postgres Language Server: implementing the Parser</title>
<link>https://supabase.com/blog/postgres-language-server-implementing-parser</link>
<description>A detailed analysis of our iterations to implement a Parser for Postgres</description>
<pubDate>Thu, 07 Dec 2023 16:00:00 GMT</pubDate>
<pubDate>Thu, 07 Dec 2023 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,21 +5,21 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Raminder Singh at Supabase</description>
<language>en</language>
<lastBuildDate>Wed, 10 Apr 2024 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Wed, 10 Apr 2024 22:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-raminder_singh-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-roles-and-privileges</guid>
<title>Postgres Roles and Privileges</title>
<link>https://supabase.com/blog/postgres-roles-and-privileges</link>
<description>A guide to Postgres roles and privileges</description>
<pubDate>Wed, 10 Apr 2024 16:00:00 GMT</pubDate>
<pubDate>Wed, 10 Apr 2024 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/how-pg-graphql-works</guid>
<title>How pg_graphql works</title>
<link>https://supabase.com/blog/how-pg-graphql-works</link>
<description>An insight into the internals of GraphQL in Postgres using pg_graphql, and how you can contribute.</description>
<pubDate>Tue, 23 Jan 2024 16:00:00 GMT</pubDate>
<pubDate>Tue, 23 Jan 2024 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,14 +5,14 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Stanislav Muzhyk at Supabase</description>
<language>en</language>
<lastBuildDate>Tue, 12 Dec 2023 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Tue, 12 Dec 2023 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-stas-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/supavisor-postgres-connection-pooler</guid>
<title>Supavisor 1.0: a scalable connection pooler for Postgres</title>
<link>https://supabase.com/blog/supavisor-postgres-connection-pooler</link>
<description>Supavisor is now used across all projects, providing a scalable and cloud-native Postgres connection pooler that can handle millions of connections</description>
<pubDate>Tue, 12 Dec 2023 16:00:00 GMT</pubDate>
<pubDate>Tue, 12 Dec 2023 23:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,21 +5,21 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Steve Chavez at Supabase</description>
<language>en</language>
<lastBuildDate>Thu, 15 Dec 2022 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 15 Dec 2022 23:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-steve_chavez-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgrest-11-prerelease</guid>
<title>PostgREST 11 pre-release</title>
<link>https://supabase.com/blog/postgrest-11-prerelease</link>
<description>Describes new features of PostgREST 11 pre-release</description>
<pubDate>Thu, 15 Dec 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 15 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/roles-postgres-hooks</guid>
<title>Protecting reserved roles with PostgreSQL Hooks</title>
<link>https://supabase.com/blog/roles-postgres-hooks</link>
<description>Using Postgres Hooks to protect functionality in your Postgres database.</description>
<pubDate>Thu, 01 Jul 2021 16:00:00 GMT</pubDate>
<pubDate>Thu, 01 Jul 2021 22:00:00 GMT</pubDate>
</item>
</channel>

View File

@@ -5,28 +5,28 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Victor at Supabase</description>
<language>en</language>
<lastBuildDate>Thu, 13 Oct 2022 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 13 Oct 2022 22:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-victor-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-full-text-search-vs-the-rest</guid>
<title>Postgres Full Text Search vs the rest</title>
<link>https://supabase.com/blog/postgres-full-text-search-vs-the-rest</link>
<description>Comparing one of the most popular Postgres features against alternatives</description>
<pubDate>Thu, 13 Oct 2022 16:00:00 GMT</pubDate>
<pubDate>Thu, 13 Oct 2022 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/choosing-a-postgres-primary-key</guid>
<title>Choosing a Postgres Primary Key</title>
<link>https://supabase.com/blog/choosing-a-postgres-primary-key</link>
<description>Turns out the question of which identifier to use as a Primary Key is complicated -- we&apos;re going to dive into some of the complexity and inherent trade-offs, and figure things out</description>
<pubDate>Wed, 07 Sep 2022 16:00:00 GMT</pubDate>
<pubDate>Wed, 07 Sep 2022 22:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/seen-by-in-postgresql</guid>
<title>Implementing &quot;seen by&quot; functionality with Postgres</title>
<link>https://supabase.com/blog/seen-by-in-postgresql</link>
<description>Different approaches for tracking visitor counts with PostgreSQL.</description>
<pubDate>Sun, 17 Jul 2022 16:00:00 GMT</pubDate>
<pubDate>Sun, 17 Jul 2022 22:00:00 GMT</pubDate>
</item>
</channel>

File diff suppressed because it is too large Load Diff

7
package-lock.json generated
View File

@@ -2405,7 +2405,6 @@
"react-countdown": "^2.3.5",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.3",
"react-medium-image-zoom": "^5.1.8",
"react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.2.17",
"react-transition-group": "^4.4.1",
@@ -34371,14 +34370,15 @@
"license": "MIT"
},
"node_modules/react-medium-image-zoom": {
"version": "5.1.8",
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/react-medium-image-zoom/-/react-medium-image-zoom-5.2.4.tgz",
"integrity": "sha512-XLu/fLqpbmhiDAGA6yie78tDv4kh8GxvS7kKQArSOvCvm5zvgItoh4h01NAAvnezQ60ovsTeedHiHG3eG9CcGg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/rpearce"
}
],
"license": "BSD-3-Clause",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
@@ -42875,6 +42875,7 @@
"react-hot-toast": "^2.4.1",
"react-intersection-observer": "^9.8.2",
"react-markdown": "^8.0.3",
"react-medium-image-zoom": "^5.2.4",
"react-resizable-panels": "^2.0.13",
"react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.2.17",

View File

@@ -1,36 +0,0 @@
'use client'
import { useTheme } from 'next-themes'
import Image from 'next/image'
import { useEffect, useState } from 'react'
import { cn } from 'ui'
export const ThemeImage = ({ src, ...props }: any) => {
const { resolvedTheme } = useTheme()
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
return (
<span className="next-image--dynamic-fill">
<Image
sizes="(max-width: 768px) 120vw, (max-width: 1200px) 100vw, 2000px"
{...props}
className={props.className}
src={
typeof src === 'string'
? src
: mounted && resolvedTheme?.includes('dark')
? src.dark
: src.light
}
/>
</span>
)
}

View File

@@ -9,7 +9,6 @@ export * from './GlassPanel'
export * from './IconPanel'
export * from './PrivacySettings'
export * from './SchemaTableNode'
export * from './ThemeImage'
export * from './ThemeToggle'
export * from './TweetCard'
export * from './InnerSideMenu'

View File

@@ -9,6 +9,7 @@ export * from './src/components/Button'
export * from './src/components/Icon'
export * from './src/components/Icon/IconContext'
export * from './src/components/Icon/IconBackground'
export * from './src/components/Image'
// DISPLAYS

View File

@@ -74,6 +74,7 @@
"react-hot-toast": "^2.4.1",
"react-intersection-observer": "^9.8.2",
"react-markdown": "^8.0.3",
"react-medium-image-zoom": "^5.2.4",
"react-resizable-panels": "^2.0.13",
"react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.2.17",

View File

@@ -1,21 +0,0 @@
.sbui-image {
}
.sbui-image-circle {
@apply rounded-full;
}
.sbui-image-normal {
}
.sbui-image-rounded {
@apply rounded
}
.sbui-image-responsive {
@apply w-full;
@apply h-auto;
}

View File

@@ -1,65 +0,0 @@
import React, { useState } from 'react'
import { Image } from '.'
export default {
title: 'General/Image',
component: Image,
}
export const Normal = (args: any) => {
return (
<>
<Image {...args} />
</>
)
}
export const Circle = (args: any) => {
return (
<>
<Image {...args} />
</>
)
}
export const Rounded = (args: any) => {
return (
<>
<Image {...args} />
</>
)
}
export const Responsive = (args: any) => {
return (
<>
<Image {...args} />
</>
)
}
Normal.args = {
active: true,
source: 'https://via.placeholder.com/300'
}
Circle.args = {
active: true,
type: 'circle',
source: 'https://via.placeholder.com/300'
}
Rounded.args = {
active: true,
type: 'rounded',
source: 'https://via.placeholder.com/300'
}
Responsive.args = {
active: true,
type: 'normal',
source: 'https://via.placeholder.com/300',
responsive: true
}

View File

@@ -1,33 +1,104 @@
import React from 'react'
// @ts-ignore
// import ImageStyles from './Image.module.css'
'use client'
interface Props {
source?: string
style?: React.CSSProperties
className?: string
type?: 'rounded' | 'circle'
alt?: string
responsive?: boolean
import 'react-medium-image-zoom/dist/styles.css'
import { useEffect, useState } from 'react'
import NextImage, { type ImageProps as NextImageProps } from 'next/image'
import { useTheme } from 'next-themes'
import { useBreakpoint } from 'common'
import { cn } from '../../lib/utils'
import Zoom from 'react-medium-image-zoom'
import ZoomContent from './ZoomContent'
export type CaptionAlign = 'left' | 'center' | 'right'
export interface StaticImageData {
src: string
height: number
width: number
blurDataURL?: string
blurWidth?: number
blurHeight?: number
}
export interface StaticRequire {
default: StaticImageData
}
export type StaticImport = StaticRequire | StaticImageData
export type SourceType =
| string
| {
dark: string | StaticImport
light: string | StaticImport
}
export interface ImageProps extends Omit<NextImageProps, 'src'> {
src: SourceType
zoomable?: boolean
caption?: string
captionAlign?: CaptionAlign
containerClassName?: string
}
/**
* @deprecated Use Next/Image instead
* An advanced Image component that extends next/image with:
* - src: prop can either be a string or an object with theme alternatives {dark: string, light: string}
* - zoomable: {boolean} (optional) to make the image zoomable on click
* - caption: {string} (optional) to add a figcaption
* - captionAlign: {'left' | 'center' | 'right'} (optional) to align the caption
* - containerClassName: {string} (optional) to style the parent <figure> container
*/
export default function Image({ source, style, className, type, alt, responsive }: Props) {
// let classes = [ImageStyles['sbui-image-normal']]
// classes.push(type === 'rounded' && ImageStyles['sbui-image-rounded'])
// classes.push(type === 'circle' && ImageStyles['sbui-image-circle'])
// if(responsive) classes.push(ImageStyles['sbui-image-responsive'])
// if (className) classes.push(className)
const Image = ({ src, alt = '', zoomable, ...props }: ImageProps) => {
const [mounted, setMounted] = useState(false)
const { resolvedTheme } = useTheme()
const isLessThanLgBreakpoint = useBreakpoint()
const Component = zoomable ? Zoom : 'span'
const sizes = zoomable
? '(max-width: 768px) 200vw, (max-width: 1200px) 120vw, 200vw'
: '(max-width: 768px) 100vw, (max-width: 1200px) 66vw, 33vw'
const source =
typeof src === 'string' ? src : resolvedTheme?.includes('dark') ? src.dark : src.light
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) return null
return (
<>
<img
// className={classes.join(' ')}
src={source}
style={style}
alt={alt}
/>
</>
<figure className={cn('next-image--dynamic-fill', props.containerClassName)}>
<Component
{...(zoomable
? { ZoomContent: ZoomContent, zoomMargin: isLessThanLgBreakpoint ? 20 : 80 }
: undefined)}
>
<NextImage
alt={alt}
src={source}
sizes={sizes}
className={props.className}
style={props.style}
{...props}
/>
</Component>
{props.caption && (
<figcaption className={cn(getCaptionAlign(props.captionAlign))}>{props.caption}</figcaption>
)}
</figure>
)
}
const getCaptionAlign = (align?: CaptionAlign) => {
switch (align) {
case 'left':
return 'text-left'
case 'right':
return 'text-right'
case 'center':
default:
return 'text-center'
}
}
export default Image

View File

@@ -1,14 +1,11 @@
const ZoomContent = ({
img,
}: //onUnzoom,
any) => {
const ZoomContent = ({ img }: { img: React.ReactElement | null }) => {
return (
<figure
className={`
className="
[&_img]:rounded-md
[&_img]:border
[&_img]:bg-surface-100
`}
[&_img]:bg-default
"
>
{img}
</figure>