Skip to content

Commit 172c5da

Browse files
authored
Merge branch 'main' into enum
2 parents 382fa99 + 6d33bec commit 172c5da

File tree

180 files changed

+3339
-1112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+3339
-1112
lines changed

.eslintrc.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module.exports = {
33
es2021: true,
44
node: true,
55
browser: true,
6-
"cypress/globals": true
6+
'cypress/globals': true,
77
},
88
settings: {
99
react: {
@@ -34,7 +34,10 @@ module.exports = {
3434

3535
'react/jsx-curly-spacing': ['error', { when: 'never', children: true }],
3636
indent: ['error', 2, { SwitchCase: 1 }],
37-
'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],
37+
'linebreak-style': [
38+
'error',
39+
process.platform === 'win32' ? 'windows' : 'unix',
40+
],
3841
quotes: ['error', 'single'],
3942

4043
'jsx-quotes': ['error', 'prefer-single'],

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
run: yarn run test:coverage:all
6565

6666
- name: Upload coverage report to Codecov
67-
uses: codecov/codecov-action@v5.1.2
67+
uses: codecov/codecov-action@v5.3.1
6868
with:
6969
token: ${{ secrets.CODECOV_TOKEN }}
7070
name: ${{ env.CODECOV_UNIQUE_NAME }}

components/Card.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import Link from 'next/link';
33
import TextTruncate from 'react-text-truncate';
4+
import Image from 'next/image';
45
export interface CardProps {
56
title: string;
67
body: string;
@@ -36,8 +37,11 @@ const CardBody = ({
3637
<div className='group relative h-full w-full rounded-lg border border-gray-200 bg-white p-6 px-12 shadow-3xl dark:shadow-2xl dark:shadow-slate-900 transition-colors ease-in-out hover:bg-slate-100 dark:bg-slate-800 hover:dark:bg-slate-900/30'>
3738
<div className='flex justify-center '>
3839
{image && (
39-
<img
40+
<Image
4041
src={image}
42+
alt={title}
43+
width={384}
44+
height={128}
4145
className='h-32 p-2 object-contain'
4246
data-test='card-image'
4347
/>
@@ -46,9 +50,11 @@ const CardBody = ({
4650
<div className='flex flex-row items-start mb-6'>
4751
{icon && (
4852
<span className='mr-6 flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-lg border bg-blue-200 px-3 text-gray-900 dark:text-white'>
49-
<img
53+
<Image
5054
src={icon}
5155
alt={title}
56+
width={56}
57+
height={56}
5258
className='h-full w-full'
5359
data-test='card-icon'
5460
/>

components/DarkModeToggle.tsx

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useTheme } from 'next-themes';
2-
import { useEffect, useState } from 'react';
2+
import { useEffect, useRef, useState } from 'react';
33
import React from 'react';
4+
import Image from 'next/image';
45

56
function ListItem({
67
children,
@@ -34,6 +35,7 @@ export default function DarkModeToggle() {
3435
const [activeThemeIcon, setActiveThemeIcon] = useState(
3536
'/icons/theme-switch.svg',
3637
);
38+
3739
useEffect(() => {
3840
switch (theme) {
3941
case 'system':
@@ -45,14 +47,36 @@ export default function DarkModeToggle() {
4547
}
4648
}, [theme, resolvedTheme]);
4749

50+
const dropdownRef = useRef<HTMLDivElement>(null);
51+
52+
useEffect(() => {
53+
const handleClickOutside = (event: MouseEvent) => {
54+
if (
55+
dropdownRef.current &&
56+
!dropdownRef.current.contains(event.target as Node)
57+
) {
58+
setShowSelect(false);
59+
}
60+
};
61+
62+
document.addEventListener('mousedown', handleClickOutside);
63+
64+
return () => {
65+
document.removeEventListener('mousedown', handleClickOutside);
66+
};
67+
}, []);
68+
4869
return (
49-
<div className='relative w-10 h-10 dark-mode-toggle-container'>
70+
<div
71+
ref={dropdownRef}
72+
className='relative w-10 h-10 dark-mode-toggle-container'
73+
>
5074
<button
5175
onClick={() => setShowSelect(!showSelect)}
5276
className='dark-mode-toggle rounded-md dark:hover:bg-gray-700 p-1.5 hover:bg-gray-100 transition duration-150 '
5377
data-test='dark-mode-toggle'
5478
>
55-
<img
79+
<Image
5680
src={activeThemeIcon}
5781
alt='Dark Mode'
5882
width={25}
@@ -65,19 +89,18 @@ export default function DarkModeToggle() {
6589
/>
6690
</button>
6791
<div
68-
className='absolute right-0 p-2 bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 z-10 w-max'
69-
style={{ display: showSelect ? 'block' : 'none' }}
70-
onMouseLeave={() => {
71-
setShowSelect(false);
72-
}}
92+
onMouseLeave={() => setShowSelect(false)}
93+
className={`absolute right-0 p-2 bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 z-10 w-max ${
94+
showSelect ? 'block' : 'hidden'
95+
}`}
7396
tabIndex={0}
7497
data-test='theme-dropdown'
7598
>
7699
<ListItem
77100
onClick={() => setTheme('system')}
78101
data-test='select-system-theme'
79102
>
80-
<img
103+
<Image
81104
src={'/icons/theme-switch.svg'}
82105
alt='System theme'
83106
width={18}
@@ -90,9 +113,9 @@ export default function DarkModeToggle() {
90113
onClick={() => setTheme('light')}
91114
data-test='select-light-theme'
92115
>
93-
<img
116+
<Image
94117
src={'/icons/sun.svg'}
95-
alt='System theme'
118+
alt='Light theme'
96119
width={18}
97120
height={18}
98121
style={{ filter: isDarkMode ? 'invert(1)' : 'invert(0)' }}
@@ -103,9 +126,9 @@ export default function DarkModeToggle() {
103126
onClick={() => setTheme('dark')}
104127
data-test='select-dark-theme'
105128
>
106-
<img
129+
<Image
107130
src={'/icons/moon.svg'}
108-
alt='System theme'
131+
alt='Dark theme'
109132
width={18}
110133
height={18}
111134
style={{ filter: isDarkMode ? 'invert(1)' : 'invert(0)' }}

components/DocsHelp.tsx

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,34 @@ import React, { FormEvent, useRef, useState } from 'react';
33
import extractPathWithoutFragment from '~/lib/extractPathWithoutFragment';
44

55
interface DocsHelpProps {
6-
markdownFile?: string;
6+
fileRenderType?: '_indexmd' | 'indexmd' | 'tsx' | '_md' | string;
7+
showEditOption?: boolean;
78
}
8-
9-
export function DocsHelp({ markdownFile }: DocsHelpProps) {
9+
export function DocsHelp({
10+
fileRenderType,
11+
showEditOption = true,
12+
}: DocsHelpProps) {
1013
const router = useRouter();
11-
const path = encodeURIComponent(router.pathname);
1214
const [isFormOpen, setIsFormOpen] = useState(false);
1315
const [feedbackStatus, setFeedbackStatus] = useState('');
1416
const [isSubmitting, setIsSubmitting] = useState(false);
1517
const [error, setError] = useState('');
1618
const feedbackFormRef = useRef<HTMLFormElement>(null);
17-
19+
let gitredirect = '';
20+
if (
21+
typeof fileRenderType === 'string' &&
22+
fileRenderType.startsWith('https://')
23+
) {
24+
gitredirect = fileRenderType;
25+
} else if (fileRenderType === 'tsx') {
26+
gitredirect = `https://github.com/json-schema-org/website/blob/main/pages${extractPathWithoutFragment(router.asPath) + '/index.page.tsx'}`;
27+
} else if (fileRenderType === '_indexmd') {
28+
gitredirect = `https://github.com/json-schema-org/website/blob/main/pages${extractPathWithoutFragment(router.asPath) + '/_index.md'}`;
29+
} else if (fileRenderType === 'indexmd') {
30+
gitredirect = `https://github.com/json-schema-org/website/blob/main/pages${extractPathWithoutFragment(router.asPath) + '/index.md'}`;
31+
} else {
32+
gitredirect = `https://github.com/json-schema-org/website/blob/main/pages${extractPathWithoutFragment(router.asPath) + '.md'}`;
33+
}
1834
async function createFeedbackHandler(event: FormEvent) {
1935
event.preventDefault();
2036
const formData = new FormData(feedbackFormRef.current!);
@@ -296,28 +312,30 @@ export function DocsHelp({ markdownFile }: DocsHelpProps) {
296312
type of contribution!
297313
</p>
298314
</div>
299-
<div className='my-4 text-[14px]'>
300-
<a
301-
target='_blank'
302-
rel='noreferrer'
303-
className='px-[16px] py-[8px] cursor-pointer border-solid border-[#aaaaaa] border rounded-md hover:bg-gray-200 dark:hover:bg-gray-600'
304-
href={`https://github.com/json-schema-org/website/blob/main/pages${markdownFile ? (markdownFile === '_indexPage' ? extractPathWithoutFragment(router.asPath) + '/_index.md' : extractPathWithoutFragment(router.asPath) + '.md') : `/${path}/index.page.tsx`}`}
305-
data-test='edit-on-github-link'
306-
>
307-
<svg
308-
className='inline-block select-none align-text-bottom mr-1'
309-
aria-hidden='true'
310-
role='img'
311-
viewBox='0 0 16 16'
312-
width='16'
313-
height='16'
314-
fill='currentColor'
315+
{showEditOption && (
316+
<div className='my-4 text-[14px]'>
317+
<a
318+
target='_blank'
319+
rel='noreferrer'
320+
className='px-[16px] py-[8px] cursor-pointer border-solid border-[#aaaaaa] border rounded-md hover:bg-gray-200 dark:hover:bg-gray-600'
321+
href={gitredirect} // Ensure gitredirect is defined
322+
data-test='edit-on-github-link'
315323
>
316-
<path d='M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z' />
317-
</svg>
318-
Edit this page on Github
319-
</a>
320-
</div>
324+
<svg
325+
className='inline-block select-none align-text-bottom mr-1'
326+
aria-hidden='true'
327+
role='img'
328+
viewBox='0 0 16 16'
329+
width='16'
330+
height='16'
331+
fill='currentColor'
332+
>
333+
<path d='M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z' />
334+
</svg>
335+
Edit this page on Github
336+
</a>
337+
</div>
338+
)}
321339
<div className='my-2 text-[14px]'>
322340
<a
323341
target='_blank'

components/GettingStarted.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { atomOneDark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
33
import Highlight from 'react-syntax-highlighter';
44
import JSZip from 'jszip';
55
import { saveAs } from 'file-saver';
6+
import Image from 'next/image';
67

78
async function fetchData() {
89
const response = await fetch('/data/getting-started-examples.json');
@@ -237,9 +238,19 @@ const GettingStarted = () => {
237238
<p>{details[0]}</p>
238239

239240
{details[1] ? (
240-
<img src='/icons/green-tick.svg' alt='green tick' />
241+
<Image
242+
src='/icons/green-tick.svg'
243+
alt='green tick'
244+
width={24}
245+
height={24}
246+
/>
241247
) : (
242-
<img src='/icons/red-cross.svg' alt='red cross' />
248+
<Image
249+
src='/icons/red-cross.svg'
250+
alt='red cross'
251+
width={24}
252+
height={24}
253+
/>
243254
)}
244255
</div>
245256
</div>

components/JsonEditor.tsx

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import getPartsOfJson, { SyntaxPart } from '~/lib/getPartsOfJson';
66
import jsonSchemaReferences from './jsonSchemaLinks';
77
import { useRouter } from 'next/router';
88
import { FullMarkdownContext } from '~/context';
9+
import Image from 'next/image';
910
import getScopesOfParsedJsonSchema, {
1011
JsonSchemaPathWithScope,
1112
JsonSchemaScope,
@@ -294,31 +295,45 @@ export default function JsonEditor({ initialCode }: { initialCode: string }) {
294295
}}
295296
data-test='copy-clipboard-button'
296297
>
297-
<img
298+
<Image
298299
src='/icons/copy.svg'
300+
alt='Copy icon'
299301
title='Copy to clipboard'
302+
width={20}
303+
height={20}
300304
className={`opacity-50 hover:opacity-90 duration-150 ${copied ? 'hidden' : ''}`}
301-
></img>
302-
<img
305+
/>
306+
<Image
303307
src='/icons/copied.svg'
308+
alt='Copied icon'
309+
width={20}
310+
height={20}
304311
title='Copied!'
305312
className={copied ? '' : 'hidden'}
306-
></img>
313+
/>
307314
</div>
308315
<div
309316
className='flex flex-row items-center text-white h-6 font-sans bg-white/20 text-xs px-3 rounded-bl-lg font-semibold'
310317
data-test='check-json-schema'
311318
>
312319
{isJsonSchema ? (
313320
<>
314-
<img src='/logo-white.svg' className='h-4 mr-1.5' /> schema
321+
<Image
322+
src='/logo-white.svg'
323+
alt=' logo-white'
324+
width={16}
325+
height={16}
326+
className=' mr-1.5'
327+
/>{' '}
328+
schema
315329
</>
316330
) : (
317331
<>data</>
318332
)}
319333
</div>
320334
</div>
321335
<Editable
336+
className='overflow-x-auto'
322337
data-test='json-editor'
323338
onCopy={(e) => {
324339
e.preventDefault();
@@ -363,7 +378,6 @@ export default function JsonEditor({ initialCode }: { initialCode: string }) {
363378
(jsonPathsWithJsonScope) => jsonPathsWithJsonScope.jsonPath,
364379
)
365380
.includes(leaf.syntaxPart?.parentJsonPath);
366-
// console.log('jsonPathsWithJsonScope', jsonPathsWithJsonScope, leaf, leaf.syntaxPart?.parentJsonPath)
367381
if (
368382
isJsonScope &&
369383
jsonSchemaReferences.objectProperty[leaf.text]
@@ -410,7 +424,7 @@ export default function JsonEditor({ initialCode }: { initialCode: string }) {
410424
if (!link) return;
411425
router.push(link);
412426
}}
413-
className={classnames('pb-2', textStyles)}
427+
className={classnames('pb-2', textStyles, 'whitespace-pre')}
414428
title={leaf.syntaxPart?.type}
415429
{...attributes}
416430
>
@@ -451,7 +465,13 @@ export default function JsonEditor({ initialCode }: { initialCode: string }) {
451465
className='text-white px-4 py-3 font-sans flex flex-row justify-end items-center bg-red-500/30 text-sm'
452466
data-test='not-compliant-to-schema'
453467
>
454-
<img src='/icons/x-mark.svg' className='h-4 w-4 mr-2' />
468+
<Image
469+
src='/icons/x-mark.svg'
470+
alt='Error icon'
471+
width={16}
472+
height={16}
473+
className=' mr-2'
474+
/>
455475
not compliant to schema
456476
</div>
457477
)}
@@ -460,7 +480,13 @@ export default function JsonEditor({ initialCode }: { initialCode: string }) {
460480
className='text-white px-4 py-3 font-sans flex flex-row justify-end items-center bg-slate-500/30 text-sm'
461481
data-test='compliant-to-schema'
462482
>
463-
<img src='/icons/checkmark.svg' className='h-5 w-5 mr-2' />
483+
<Image
484+
src='/icons/checkmark.svg'
485+
alt='Checkmark icon'
486+
width={20}
487+
height={20}
488+
className='mr-2'
489+
/>
464490
compliant to schema
465491
</div>
466492
)}

0 commit comments

Comments
 (0)