Lightbox + documentation updates

This commit is contained in:
Elio Struyf
2021-09-09 10:02:51 +02:00
parent 11bb0fabcd
commit f79d382da5
22 changed files with 182 additions and 39 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 265 KiB

BIN
assets/v3.1.0/media.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

View File

@@ -2,37 +2,54 @@ import Link from 'next/link';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
export interface IHeroProps {}
export interface IHeroProps {
view: "left" | "right";
title: string;
description: string | JSX.Element;
imgSrc: string;
imgAlt: string;
link?: string;
linkText?: string;
className?: string;
}
export const Hero: React.FunctionComponent<IHeroProps> = (props: React.PropsWithChildren<IHeroProps>) => {
const { t: strings } = useTranslation();
export const Hero: React.FunctionComponent<IHeroProps> = ({view, title, description, imgSrc, imgAlt, link, linkText, className}: React.PropsWithChildren<IHeroProps>) => {
return (
<div className="px-4 sm:px-0 pt-8 py-12 sm:py-16 lg:relative lg:mx-auto lg:max-w-7xl lg:px-8 lg:grid lg:grid-cols-2 lg:grid-flow-col-dense lg:gap-24">
<div className="px-4 max-w-3xl mx-auto sm:px-6 lg:py-32 lg:max-w-none lg:mx-0 lg:px-0 lg:col-start-2">
<div>
<h2 className="text-3xl lg:text-3xl xl:text-4xl tracking-tight font-extrabold sm:leading-none">
{strings(`hero_title`)}
</h2>
<p className="my-6 text-base text-whisper-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
{strings(`hero_description`)}
</p>
<p className="my-6 text-base text-whisper-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
{strings(`hero_description_second`)}
</p>
<Link href={`/docs/getting-started`} >
<a className={`inline-block px-4 py-3 border border-transparent text-base font-medium shadow-sm text-white bg-teal-500 hover:bg-opacity-70 sm:px-8`}>
{strings(`hero_button_primary`)}
</a>
</Link>
<div className={`overflow-hidden lg:relative`}>
<div className={`${className || ""} px-4 sm:px-6 xl:px-0 py-12 sm:py-16 lg:relative lg:mx-auto lg:max-w-7xl lg:grid lg:grid-cols-2 lg:grid-flow-col-dense lg:gap-24`}>
<div className={`max-w-3xl mx-auto lg:py-32 lg:max-w-none lg:mx-0 lg:px-0 ${view === "left" ? `lg:col-start-2` : `lg:col-start-1`}`}>
<div>
<h2 className="text-3xl lg:text-3xl xl:text-4xl tracking-tight font-extrabold sm:leading-none">
{title}
</h2>
{
typeof description === 'string' ? (
<p className="my-6 text-base text-whisper-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
{description}
</p>
) : (
{...description}
)
}
{
link && linkText && (
<Link href={link} >
<a className={`inline-block px-4 py-3 border border-transparent text-base font-medium shadow-sm text-white bg-teal-500 hover:bg-opacity-70 sm:px-8`}>
{linkText}
</a>
</Link>
)
}
</div>
</div>
</div>
<div className="sm:mx-auto sm:max-w-3xl sm:px-6 lg:mx-0 lg:max-w-none mt-12 sm:mt-16 lg:mt-0 lg:col-start-1">
<div className="lg:pr-6 lg:-ml-16 lg:px-0 lg:m-0 lg:relative lg:h-full">
<img className="w-full rounded-xl lg:absolute lg:right-0 lg:h-full lg:w-auto lg:max-w-none"
src="/assets/dashboard.png"
alt="Front Matter CMS editor dashboard of your static site content" />
<div className={`sm:mx-auto sm:max-w-3xl sm:px-6 lg:px-0 lg:mx-0 lg:max-w-none mt-12 sm:mt-16 lg:mt-0 ${view === "left" ? `lg:col-start-1` : `lg:col-start-2`}`}>
<div className={`${view === "left" ? `lg:pr-6 lg:-ml-16` : `lg:pl-6 lg:-mr-16`} lg:px-0 lg:m-0 lg:relative lg:h-full`}>
<img className={`w-full rounded-xl lg:absolute lg:h-full lg:w-auto lg:max-w-none ${view === "left" ? `lg:right-0` : `lg:left-0`}`}
src={imgSrc}
alt={imgAlt} />
</div>
</div>
</div>
</div>

View File

@@ -8,7 +8,7 @@ export interface ILayoutProps {}
export const Layout: React.FunctionComponent<ILayoutProps> = (props: React.PropsWithChildren<ILayoutProps>) => {
return (
<div className={`flex flex-col h-screen`}>
<header className={`sticky top-0 z-50 bg-vulcan-500 bg-opacity-80 backdrop-blur-lg`}>
<header className={`lg:sticky lg:top-0 z-50 bg-vulcan-500 bg-opacity-80 backdrop-blur-lg`}>
<Navigation />
</header>

View File

@@ -2,6 +2,8 @@
## [3.1.0] - (Upcoming release)
- BETA version available at: [beta.frontmatter.codes](https://beta.frontmatter.codes)
- [#72](https://github.com/estruyf/vscode-front-matter/issues/72): Media view on the dashboard
- [#73](https://github.com/estruyf/vscode-front-matter/issues/73): List view option for the dashboard
- [#77](https://github.com/estruyf/vscode-front-matter/issues/77): Dashboard grouping pages functionality integrated
- [#81](https://github.com/estruyf/vscode-front-matter/issues/81): Optimizing the content folders to use a new setting to simplify configuration
@@ -9,6 +11,7 @@
- [#88](https://github.com/estruyf/vscode-front-matter/issues/88): Fix issue with search sorting
- [#89](https://github.com/estruyf/vscode-front-matter/issues/89): Clear filter, sorting, and grouping button added
- [#90](https://github.com/estruyf/vscode-front-matter/issues/90): Refactoring to use Recoil state management
- [#91](https://github.com/estruyf/vscode-front-matter/issues/91): Support image previews from content folders
## [3.0.2] - 2021-08-31

View File

@@ -9,25 +9,41 @@ weight: 3
# Dashboard
Managing your Markdown pages has never been easier in VS Code. With the Front Matter dashboard, you will be able to view all your pages and **search** through them, **filter**, **sort**, and much more.
Managing your Markdown pages/media has never been easier in VS Code. With the Front Matter dashboard, you will be able to view all your pages and media.
![Dashboard](/assets/dashboard.png)
On the contents view, you can **search**, **filter**, **sort** your pages and much more.
![Dashboard - Contents view](/assets/dashboard.png)
On the media view, you can quickly glance all the available media files in your project and perform quick actions like copying the relative path.
![Dashboard - Media view](/assets/media.png)
In order to start using the dashboard, you will have to let the extension know in which folder(s) it can find your pages. Be sure to follow our [getting started](/docs/getting-started) guide.
> **Important**: If your preview images are not loading, it might be that you need to configure the `publicFolder` where the extension can find them. For instance, in Hugo, this is the static folder. You can configure this by updating the `frontMatter.content.publicFolder` setting.
## Supported filters
## Contents view
### Supported filters
- Tag filter
- Category filter
- Content folder (when you have multiple registered)
## Supported sorting
### Supported sorting
- Last modified
- Filename (asc/desc)
## Media view
The media view has been created to make it easier to look at all media files available for your articles. When you click on an image, it will show a lightbox, so that it is easier to glance at small images.
![Dashboard - Media view - Lightbox](/assets/lightbox.png)
On the image card, there are actions like copying the relative path which you can then use in your article.
## Show on startup
If you want, you can check on the `Open on startup?` checkbox. This setting will allow the dashboard to automatically open when you launch the project in VS Code. It will only apply to the current project, not for all of them.

View File

@@ -20,6 +20,11 @@ export const strings = {
hero_description_second: "We at Front Matter believe that you should keep using what you like. For us, this is Visual Studio Code. Use the same editor you use to code, but with unique features to make it suitable for writing and managing your Markdown articles.",
hero_button_primary: "Get started",
// Hero media
hero_media_title: "Checking your media was never easier",
hero_media_description: "Quickly glance all your media files straight from within VS Code. You will be able to filter by your content folders, and perform quick media actions.",
hero_media_button_primary: "See what it can do",
// Testimonials
testimonials_title: "What others are saying",
testimonials_description: "We love Front Matter and we're excited to share it with the world.",

View File

@@ -1,10 +1,13 @@
import type { NextPage } from 'next';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Description, OtherMeta, Title } from '../components/Meta';
import { CTA, Features, Generators, Hero, Layout } from '../components/Page';
import { Extension } from '../constants/extension';
const Home: NextPage = () => {
const { t: strings } = useTranslation();
return (
<>
<Title value={Extension.home} />
@@ -16,7 +19,34 @@ const Home: NextPage = () => {
<Generators />
<Hero />
<Hero
view={"left"}
title={strings(`hero_title`)}
description={(
<>
<p className="my-6 text-base text-whisper-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
{strings(`hero_description`)}
</p>
<p className="my-6 text-base text-whisper-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
{strings(`hero_description_second`)}
</p>
</>
)}
imgSrc={"/assets/dashboard.png"}
imgAlt={"Front Matter CMS editor dashboard of your static site content"}
link={`/docs/getting-started`}
linkText={strings(`hero_button_primary`)} />
<Hero
view={"right"}
title={strings(`hero_media_title`)}
description={strings(`hero_media_description`)}
imgSrc={"/assets/media.png"}
imgAlt={"Front Matter CMS - media management was never easier in VS Code"}
link={`/docs/dashboard`}
linkText={strings(`hero_media_button_primary`)}
className={`-mt-12 sm:-mt-16`} />
<Features />
</Layout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 265 KiB

15
package-lock.json generated
View File

@@ -262,6 +262,15 @@
"fastq": "^1.6.0"
}
},
"@tailwindcss/forms": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.3.tgz",
"integrity": "sha512-U8Fi/gq4mSuaLyLtFISwuDYzPB73YzgozjxOIHsK6NXgg/IWD1FLaHbFlWmurAMyy98O+ao74ksdQefsquBV1Q==",
"dev": true,
"requires": {
"mini-svg-data-uri": "^1.2.3"
}
},
"@types/anymatch": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
@@ -3818,6 +3827,12 @@
}
}
},
"mini-svg-data-uri": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.3.3.tgz",
"integrity": "sha512-+fA2oRcR1dJI/7ITmeQJDrYWks0wodlOz0pAEhKYJ2IVc1z0AnwJUsKY2fzFmPAM3Jo9J0rBx8JAA9QQSJ5PuA==",
"dev": true
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",

View File

@@ -400,6 +400,7 @@
"@headlessui/react": "1.4.0",
"@heroicons/react": "1.0.4",
"@iarna/toml": "2.2.3",
"@tailwindcss/forms": "^0.3.3",
"@types/glob": "7.1.3",
"@types/js-yaml": "3.12.1",
"@types/lodash.uniqby": "4.7.6",

View File

@@ -2,10 +2,10 @@ import { Messenger } from '@estruyf/vscode/dist/client';
import { ClipboardCopyIcon } from '@heroicons/react/outline';
import { basename, dirname } from 'path';
import * as React from 'react';
import { useRecoilValue } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { MediaInfo } from '../../../models/MediaPaths';
import { DashboardMessage } from '../../DashboardMessage';
import { SettingsSelector } from '../../state';
import { LightboxAtom, SettingsSelector } from '../../state';
export interface IItemProps {
media: MediaInfo;
@@ -13,6 +13,7 @@ export interface IItemProps {
export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWithChildren<IItemProps>) => {
const settings = useRecoilValue(SettingsSelector);
const [ , setLightbox ] = useRecoilState(LightboxAtom);
const getFolder = () => {
if (settings?.wsFolder && media.fsPath) {
@@ -51,11 +52,15 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
}
};
const openLightbox = () => {
setLightbox(media.vsPath || "");
};
return (
<li className="relative bg-gray-50 dark:bg-vulcan-200 hover:shadow-xl dark:hover:bg-vulcan-100">
<div className="bg-white group block w-full aspect-w-10 aspect-h-7 overflow-hidden ">
<img src={media.vsPath} alt={basename(media.fsPath)} className="mx-auto object-cover pointer-events-none" />
</div>
<li className="group relative bg-gray-50 dark:bg-vulcan-200 hover:shadow-xl dark:hover:bg-vulcan-100">
<button className="bg-white block w-full aspect-w-10 aspect-h-7 overflow-hidden cursor-pointer" onClick={openLightbox}>
<img src={media.vsPath} alt={basename(media.fsPath)} className="mx-auto object-cover" />
</button>
<div className={`relative py-4 pl-4 pr-10`}>
<div className={`absolute top-4 right-4`}>
<button title={`Copy media path`}

View File

@@ -0,0 +1,26 @@
import { basename } from 'path';
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { LightboxAtom } from '../../state';
export interface ILightboxProps {}
export const Lightbox: React.FunctionComponent<ILightboxProps> = (props: React.PropsWithChildren<ILightboxProps>) => {
const [ lightbox, setLightbox ] = useRecoilState(LightboxAtom);
if (!lightbox) {
return null;
}
const hideLightbox = () => {
setLightbox(null);
};
return (
<div onClick={hideLightbox} className={`fixed top-0 left-0 right-0 bottom-0 w-full h-full flex flex-wrap items-center justify-center bg-white bg-opacity-50 z-50`}>
<div className={`w-full h-full flex flex-wrap items-center justify-center`}>
<img src={lightbox} alt={basename(lightbox)} className={`w-1/2 h-auto rounded-lg border border-vulcan-500 shadow-2xl`} />
</div>
</div>
);
};

View File

@@ -9,6 +9,7 @@ import { Header } from '../Header';
import { Spinner } from '../Spinner';
import { SponsorMsg } from '../SponsorMsg';
import { Item } from './Item';
import { Lightbox } from './Lightbox';
import { List } from './List';
export interface IMediaProps {}
@@ -58,6 +59,8 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
loading && ( <Spinner /> )
}
<Lightbox />
<SponsorMsg beta={settings?.beta} version={settings?.versionInfo} />
</div>
</main>

View File

@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const LightboxAtom = atom<string | null>({
key: 'LightboxAtom',
default: ""
});

View File

@@ -2,6 +2,7 @@ export * from './CategoryAtom';
export * from './DashboardViewAtom';
export * from './FolderAtom';
export * from './GroupingAtom';
export * from './LightboxAtom';
export * from './LoadingAtom';
export * from './MediaFoldersAtom';
export * from './MediaTotalAtom';

View File

@@ -16,4 +16,17 @@
@keyframes spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
[type=checkbox]:checked {
background-image: none;
}
[type=checkbox]:checked:after {
content: '\2713';
font-size: 14px;
position: absolute;
top: -1px;
left: 2px;
color: white;
}

View File

@@ -111,5 +111,7 @@ module.exports = {
variants: {
extend: {},
},
plugins: [],
plugins: [
require("@tailwindcss/forms")
],
}