Browse Source

Add blog post example

Add use case for using react-refractor independently.
pull/1/head
TheoryOfNekomata 1 year ago
parent
commit
85d8b13301
9 changed files with 195 additions and 116 deletions
  1. +5
    -0
      packages/web-kitchensink-reactnext/react-refractor.d.ts
  2. +2
    -2
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/TextFilePreview/index.tsx
  3. +1
    -1
      packages/web-kitchensink-reactnext/src/components/DefaultLayout/index.tsx
  4. +1
    -1
      packages/web-kitchensink-reactnext/src/packages/react-binary-data-canvas/index.tsx
  5. +0
    -66
      packages/web-kitchensink-reactnext/src/packages/react-prism/index.tsx
  6. +84
    -0
      packages/web-kitchensink-reactnext/src/packages/react-refractor/index.tsx
  7. +7
    -1
      packages/web-kitchensink-reactnext/src/pages/_app.tsx
  8. +51
    -0
      packages/web-kitchensink-reactnext/src/pages/examples/blog-post/index.tsx
  9. +44
    -45
      packages/web-kitchensink-reactnext/src/styles/globals.css

+ 5
- 0
packages/web-kitchensink-reactnext/react-refractor.d.ts View File

@@ -0,0 +1,5 @@
declare module 'react-refractor/all' {
import { Props } from 'react-refractor';

export default function Refractor(props: Props): JSX.Element;
}

+ 2
- 2
packages/web-kitchensink-reactnext/src/categories/blob/react/components/TextFilePreview/index.tsx View File

@@ -4,7 +4,7 @@ import {useFileMetadata, useFileUrl} from '@/categories/blob/react';
import {augmentTextFile, getMimeTypeDescription} from '@/utils/blob';
import clsx from 'clsx';
import {KeyValueTable} from '@/categories/information/react';
import {Prism} from '@modal-soft/react-prism';
import {Refractor} from '../../../../../packages/react-refractor';

type TextFilePreviewDerivedComponent = HTMLDivElement;

@@ -55,7 +55,7 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent,
className="w-full h-full select-none overflow-hidden text-xs"
ref={forwardedRef}
>
<Prism
<Refractor
code={fileWithMetadata.metadata.contents}
language={fileWithMetadata.metadata.scheme}
lineNumbers={Boolean(fileWithMetadata.metadata.scheme)}


+ 1
- 1
packages/web-kitchensink-reactnext/src/components/DefaultLayout/index.tsx View File

@@ -21,7 +21,7 @@ export const DefaultLayout: FC<DefaultLayoutProps> = ({
{
title
&& (
<meta name="display-title" className="block lowercase text-6xl font-headings container mx-auto px-4 font-thin" content={title} />
<meta name="display-title" className="block lowercase text-6xl font-headings container mx-auto px-4 font-thin leading-none" content={title} />
)
}
</Head>


+ 1
- 1
packages/web-kitchensink-reactnext/src/packages/react-binary-data-canvas/index.tsx View File

@@ -44,7 +44,7 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement,
return (
<div
className={clsx(
'binary-file-preview',
'react-binary-data-canvas',
className,
)}
style={{


+ 0
- 66
packages/web-kitchensink-reactnext/src/packages/react-prism/index.tsx View File

@@ -1,66 +0,0 @@
import * as React from 'react';
import Refractor from 'react-refractor/all';
import clsx from 'clsx';

type PrismDerivedElement = HTMLPreElement;

export interface PrismProps extends Omit<React.HTMLProps<PrismDerivedElement>, 'children'> {
code?: string;
language?: string;
lineNumbers?: boolean;
maxLineNumber?: number;
tabSize?: number;
}

export const Prism = React.forwardRef<PrismDerivedElement, PrismProps>(({
code,
language = 'plain',
lineNumbers = false,
maxLineNumber = Infinity,
tabSize = 2,
className,
style,
...etcProps
}, forwardedRef) => {
const [highlightedCode, setHighlightedCode] = React.useState<string>('');

if (!code) {
return null;
}

return (
<div
className={clsx(
'react-prism',
className,
)}
style={style}
>
{lineNumbers && (
<pre
style={{
textAlign: 'right',
}}
>
<code>
{new Array(maxLineNumber).fill(0).map((_, i) => (
<React.Fragment key={i}>
{i > 0 && '\n'}
{i + 1}
</React.Fragment>
))}
</code>
</pre>
)}
<Refractor
{...etcProps}
language={language}
value={code}
className="highlight"
/>
</div>
)
});

Prism.displayName = 'Prism';


+ 84
- 0
packages/web-kitchensink-reactnext/src/packages/react-refractor/index.tsx View File

@@ -0,0 +1,84 @@
import * as React from 'react';
import RefractorCore from 'react-refractor/all';
import clsx from 'clsx';

type PrismDerivedElement = HTMLDivElement;

export interface PrismProps extends Omit<React.HTMLProps<PrismDerivedElement>, 'children'> {
code?: string;
language?: string;
lineNumbers?: boolean;
tabSize?: number;
header?: boolean;
}

export const Refractor = React.forwardRef<PrismDerivedElement, PrismProps>(({
code = '',
language = 'plain',
lineNumbers = false,
tabSize = 2,
className,
style,
header = false,
...etcProps
}, forwardedRef) => {
return (
<div
className={clsx(
'react-refractor',
className,
)}
style={style}
ref={forwardedRef}
>
{header && (
<div className="flex items-center justify-between">
<div className="uppercase text-sm">
{language}
</div>
<form>
<button
type="submit"
name="action"
value="copyContents"
className="h-12 uppercase text-primary font-bold"
>
Copy
</button>
</form>
</div>
)}
<div
className="flex gap-2 items-start"
>
{lineNumbers && (
<pre
style={{
textAlign: 'right',
}}
>
<code>
{code.split('\n').map((_, i) => (
<React.Fragment key={i}>
{i > 0 && '\n'}
{i + 1}
</React.Fragment>
))}
</code>
</pre>
)}
<div className="flex-auto overflow-auto">
<RefractorCore
{...etcProps}
language={language}
value={code}
className="highlight"
/>
</div>
</div>
</div>
)
});

Refractor.displayName = 'Refractor';


+ 7
- 1
packages/web-kitchensink-reactnext/src/pages/_app.tsx View File

@@ -1,10 +1,16 @@
import '@/styles/globals.css'
import '@/styles/kitchen-sink.css'
import type { AppProps } from 'next/app'
import Head from 'next/head';

const App = ({ Component, pageProps }: AppProps) => {
return (
<Component {...pageProps} />
<>
<Head>
<meta name="viewport" content="initial-scale=1,minimum-scale=1,width=device-width,viewport-fit=cover" />
</Head>
<Component {...pageProps} />
</>
);
};



+ 51
- 0
packages/web-kitchensink-reactnext/src/pages/examples/blog-post/index.tsx View File

@@ -0,0 +1,51 @@
import {Refractor} from '@modal-soft/react-refractor';
import {NextPage} from 'next';

const BlogPostPage: NextPage = () => {
return (
<>
<div className="container mx-auto px-4">
<h1>
Using Refractor on your Next website
</h1>
<p>
Use <code>@modal-soft/react-refractor</code> as follows on your page:
</p>
</div>
<div className="bg-shade/20 overflow-auto pt-4 pb-8">
<div className="container mx-auto px-4">
<Refractor
lineNumbers
header
language="tsx"
code={`import {Refractor} from '@modal-soft/react-refractor';
import {NextPage} from 'next';

const BlogPostPage: NextPage = () => {
return (
<div className="container mx-auto px-4">
<Refractor
language="tsx"
code={\`
import {Refractor} from '@modal-soft/react-refractor';
\`}
/>
</div>
);
};

export default BlogPostPage;
`}
/>
</div>
</div>
<div className="container mx-auto px-4">
<p>
Easy as that!
</p>
</div>
</>
)
};

export default BlogPostPage;

+ 44
- 45
packages/web-kitchensink-reactnext/src/styles/globals.css View File

@@ -7,31 +7,31 @@
}

h1 {
@apply font-headings lowercase text-5xl font-thin;
@apply font-headings lowercase text-5xl font-thin leading-none my-8;
}

h2 {
@apply font-headings lowercase text-4xl font-light;
@apply font-headings lowercase text-4xl font-light leading-none my-8;
}

h3 {
@apply font-headings lowercase text-3xl;
@apply font-headings lowercase text-3xl leading-none my-8;
}

h4 {
@apply font-headings lowercase text-2xl;
@apply font-headings lowercase text-2xl leading-none my-8;
}

h5 {
@apply font-headings lowercase text-xl;
@apply font-headings lowercase text-xl leading-none my-8;
}

h6 {
@apply font-headings lowercase text-lg;
@apply font-headings lowercase text-lg leading-none my-8;
}

p {
margin: 2em 0;
@apply my-8;
}

small {
@@ -96,56 +96,55 @@
}
}

.react-prism {
display: flex;
gap: 0.5rem;
align-items: flex-start;
}

.react-prism pre {
.react-refractor pre {
overflow: visible;
padding: 0;
margin: 0;
line-height: 1.2;
}

.react-prism .token.number { color: rgb(var(--color-code-number)); }
.react-prism .token.keyword { color: rgb(var(--color-code-keyword)); }
.react-prism .token.type { color: rgb(var(--color-code-type)); }
.react-prism .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); }
.react-prism .token.function { color: rgb(var(--color-code-function)); }
.react-prism .token.parameter { color: rgb(var(--color-code-parameter)); }
.react-prism .token.property { color: rgb(var(--color-code-property)); }
.react-prism .token.string { color: rgb(var(--color-code-string)); }
.react-prism .token.variable { color: rgb(var(--color-code-variable)); }
.react-prism .token.regexp { color: rgb(var(--color-code-regexp)); }
.react-prism .token.url { color: rgb(var(--color-code-url)); }
.react-prism .token.global { color: rgb(var(--color-code-global)); }
.react-prism .token.comment { opacity: 0.5; }

.binary-file-preview pre {
.react-refractor .token.number { color: rgb(var(--color-code-number)); }
.react-refractor .token.keyword { color: rgb(var(--color-code-keyword)); }
.react-refractor .token.tag { color: rgb(var(--color-code-keyword)); }
.react-refractor .token.type { color: rgb(var(--color-code-type)); }
.react-refractor .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); }
.react-refractor .token.maybe-class-name { color: rgb(var(--color-code-function)); font-style: italic; }
.react-refractor .token.function { color: rgb(var(--color-code-function)); font-style: italic; }
.react-refractor .token.parameter { color: rgb(var(--color-code-parameter)); }
.react-refractor .token.property { color: rgb(var(--color-code-property)); }
.react-refractor .token.attr-name { color: rgb(var(--color-code-property)); font-style: italic; }
.react-refractor .token.string { color: rgb(var(--color-code-string)); }
.react-refractor .token.attr-value { color: rgb(var(--color-code-string)); }
.react-refractor .token.attr-value .attr-equals { color: rgb(var(--color-positive)); }
.react-refractor .token.variable { color: rgb(var(--color-code-variable)); }
.react-refractor .token.regexp { color: rgb(var(--color-code-regexp)); }
.react-refractor .token.url { color: rgb(var(--color-code-url)); }
.react-refractor .token.global { color: rgb(var(--color-code-global)); }
.react-refractor .token.comment { opacity: 0.5; }

.react-binary-data-canvas pre {
overflow: visible;
padding: 0;
margin: 0;
line-height: 1.2;
}

.binary-file-preview .x00 { color: rgb(var(--color-code-keyword)); }
.binary-file-preview .x10 { color: rgb(var(--color-code-global)); }
.binary-file-preview .x20 { color: rgb(var(--color-code-string)); }
.binary-file-preview .x30 { color: rgb(var(--color-code-number)); }
.binary-file-preview .x40 { color: rgb(var(--color-code-url)); }
.binary-file-preview .x50 { color: rgb(var(--color-code-type)); }
.binary-file-preview .x60 { color: rgb(var(--color-code-parameter)); }
.binary-file-preview .x70 { color: rgb(var(--color-code-property)); }
.binary-file-preview .x80 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-keyword)); }
.binary-file-preview .x90 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-global)); }
.binary-file-preview .xa0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-string)); }
.binary-file-preview .xb0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-number)); }
.binary-file-preview .xc0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-url)); }
.binary-file-preview .xd0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-type)); }
.binary-file-preview .xe0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-parameter)); }
.binary-file-preview .xf0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-property)); }
.react-binary-data-canvas .x00 { color: rgb(var(--color-code-keyword)); }
.react-binary-data-canvas .x10 { color: rgb(var(--color-code-global)); }
.react-binary-data-canvas .x20 { color: rgb(var(--color-code-string)); }
.react-binary-data-canvas .x30 { color: rgb(var(--color-code-number)); }
.react-binary-data-canvas .x40 { color: rgb(var(--color-code-url)); }
.react-binary-data-canvas .x50 { color: rgb(var(--color-code-type)); }
.react-binary-data-canvas .x60 { color: rgb(var(--color-code-parameter)); }
.react-binary-data-canvas .x70 { color: rgb(var(--color-code-property)); }
.react-binary-data-canvas .x80 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-keyword)); }
.react-binary-data-canvas .x90 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-global)); }
.react-binary-data-canvas .xa0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-string)); }
.react-binary-data-canvas .xb0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-number)); }
.react-binary-data-canvas .xc0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-url)); }
.react-binary-data-canvas .xd0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-type)); }
.react-binary-data-canvas .xe0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-parameter)); }
.react-binary-data-canvas .xf0 { color: rgb(var(--color-negative)); background-color: rgb(var(--color-code-property)); }

.focus\:outline-0:-moz-focusring {
outline: 0;


Loading…
Cancel
Save