Skip to content

Commit

Permalink
Fix console errors and improve form validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps committed Sep 23, 2024
1 parent ce68cfb commit 6bc7eb5
Show file tree
Hide file tree
Showing 33 changed files with 363 additions and 206 deletions.
16 changes: 8 additions & 8 deletions browser/data-browser/src/chunks/MarkdownEditor/BubbleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function BubbleMenu(): React.JSX.Element {
<NodeSelectMenu />
<ToggleButton
title='Toggle bold'
active={!!editor.isActive('bold')}
$active={!!editor.isActive('bold') ?? undefined}
onClick={() => editor.chain().focus().toggleBold().run()}
disabled={!editor.can().chain().focus().toggleBold().run()}
type='button'
Expand All @@ -42,7 +42,7 @@ export function BubbleMenu(): React.JSX.Element {
</ToggleButton>
<ToggleButton
title='Toggle italic'
active={!!editor.isActive('italic')}
$active={!!editor.isActive('italic') ?? undefined}
onClick={() => editor.chain().focus().toggleItalic().run()}
disabled={!editor.can().chain().focus().toggleItalic().run()}
type='button'
Expand All @@ -51,7 +51,7 @@ export function BubbleMenu(): React.JSX.Element {
</ToggleButton>
<ToggleButton
title='Toggle strikethrough'
active={!!editor.isActive('strike')}
$active={!!editor.isActive('strike') ?? undefined}
onClick={() => editor.chain().focus().toggleStrike().run()}
disabled={!editor.can().chain().focus().toggleStrike().run()}
type='button'
Expand All @@ -60,7 +60,7 @@ export function BubbleMenu(): React.JSX.Element {
</ToggleButton>
<ToggleButton
title='Toggle blockquote'
active={!!editor.isActive('blockquote')}
$active={!!editor.isActive('blockquote') ?? undefined}
onClick={() => editor.chain().focus().toggleBlockquote().run()}
disabled={!editor.can().chain().focus().toggleBlockquote().run()}
type='button'
Expand All @@ -69,7 +69,7 @@ export function BubbleMenu(): React.JSX.Element {
</ToggleButton>
<ToggleButton
title='Toggle inline code'
active={!!editor.isActive('code')}
$active={!!editor.isActive('code') ?? undefined}
onClick={() => editor.chain().focus().toggleCode().run()}
disabled={!editor.can().chain().focus().toggleCode().run()}
type='button'
Expand All @@ -83,7 +83,7 @@ export function BubbleMenu(): React.JSX.Element {
Trigger={
<ToggleButton
as={RadixPopover.Trigger}
active={!!editor.isActive('link')}
$active={!!editor.isActive('link') ?? undefined}
disabled={!editor.can().chain().focus().toggleCode().run()}
type='button'
>
Expand All @@ -101,7 +101,7 @@ export function BubbleMenu(): React.JSX.Element {
const BubbleMenuInner = styled(Row)`
background-color: ${p => p.theme.colors.bg};
border-radius: ${p => p.theme.radius};
padding: ${p => p.theme.margin / 2}rem;
padding: ${p => p.theme.size(2)};
box-shadow: ${p => p.theme.boxShadowSoft};
@supports (backdrop-filter: blur(5px)) {
Expand All @@ -113,7 +113,7 @@ const BubbleMenuInner = styled(Row)`
const StyledPopover = styled(Popover)`
background-color: ${p => p.theme.colors.bg};
backdrop-filter: blur(5px);
padding: ${p => p.theme.margin}rem;
padding: ${p => p.theme.size()};
border-radius: ${p => p.theme.radius};
@supports (backdrop-filter: blur(5px)) {
Expand Down
10 changes: 5 additions & 5 deletions browser/data-browser/src/chunks/MarkdownEditor/ToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { styled } from 'styled-components';
import { transition } from '../../helpers/transition';

export const ToggleButton = styled.button<{ active: boolean }>`
export const ToggleButton = styled.button<{ $active: boolean }>`
display: flex;
align-items: center;
background-color: ${p => (p.active ? p.theme.colors.main : 'transparent')};
color: ${p => (p.active ? 'white' : p.theme.colors.textLight)};
background-color: ${p => (p.$active ? p.theme.colors.main : 'transparent')};
color: ${p => (p.$active ? 'white' : p.theme.colors.textLight)};
appearance: none;
border: none;
border-radius: ${p => p.theme.radius};
Expand All @@ -16,8 +16,8 @@ export const ToggleButton = styled.button<{ active: boolean }>`
&:not(:disabled) {
&:hover {
background-color: ${p =>
p.active ? p.theme.colors.mainDark : p.theme.colors.bg2};
color: ${p => (p.active ? 'white' : p.theme.colors.text)};
p.$active ? p.theme.colors.mainDark : p.theme.colors.bg2};
color: ${p => (p.$active ? 'white' : p.theme.colors.text)};
}
}
Expand Down
27 changes: 10 additions & 17 deletions browser/data-browser/src/components/AllPropsSimple.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@tomic/react';
import { useMemo } from 'react';
import { styled } from 'styled-components';
import { InlineFormattedResourceList } from './InlineFormattedResourceList';

export interface AllPropsSimpleProps {
resource: Resource;
Expand Down Expand Up @@ -37,11 +38,16 @@ function Row({ prop, val }: RowProps): JSX.Element {

const value = useMemo(() => {
if (dataType === datatypes.atomicUrl) {
return <Value val={val as string} />;
return <Value subject={val as string} />;
}

if (dataType === datatypes.resourceArray) {
return <ResourceArray val={val as string[]} />;
return (
<InlineFormattedResourceList
subjects={val as string[]}
RenderComp={Value}
/>
);
}

return <>{val as string}</>;
Expand All @@ -67,21 +73,8 @@ const List = styled.ul`
color: ${p => p.theme.colors.textLight};
`;

function ResourceArray({ val }: { val: string[] }): JSX.Element {
return (
<>
{val.map((v, i) => (
<>
<Value val={v} key={v} />
{i === val.length - 1 ? '' : ', '}
</>
))}
</>
);
}

function Value({ val }: { val: string }): JSX.Element {
const valueResource = useResource(val);
function Value({ subject }: { subject: string }): JSX.Element {
const valueResource = useResource(subject);
const [valueName] = useTitle(valueResource);

return <>{valueName}</>;
Expand Down
44 changes: 29 additions & 15 deletions browser/data-browser/src/components/ClassDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
import { properties, Resource, useArray } from '@tomic/react';
import React from 'react';
import { Resource, useResource } from '@tomic/react';
import { Detail } from './Detail';
import { getIconForClass } from '../views/FolderPage/iconMap';
import { InlineFormattedResourceList } from './InlineFormattedResourceList';

type Props = {
type ClassDetailProps = {
resource: Resource;
};

/** Renders the is-a Class for some resource */
export function ClassDetail({ resource }: Props): JSX.Element {
const [classes] = useArray(resource, properties.isA);
export const ClassDetail: React.FC<ClassDetailProps> = ({ resource }) => {
if (resource.getClasses().length === 0) {
return null;
}

return (
<>
{classes && (
<Detail>
<>
{'is a '}
{getIconForClass(classes[0])}
<InlineFormattedResourceList subjects={classes} />
</>
</Detail>
)}
</>
<Detail>
<InlineFormattedResourceList
subjects={resource.getClasses()}
RenderComp={ClassItem}
/>
</Detail>
);
};

interface ClassItemProps {
subject: string;
}

const ClassItem = ({ subject }: ClassItemProps): JSX.Element => {
const classResource = useResource(subject);
const Icon = getIconForClass(subject);

return (
<Detail>
<Icon />
{classResource.title}
</Detail>
);
};
6 changes: 3 additions & 3 deletions browser/data-browser/src/components/Collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function Collapse({

return (
<GridCollapser open={open} className={className}>
<InnerWrapper overflow={enableOverflow}>
<InnerWrapper $overflow={enableOverflow}>
{mountChildren && children}
</InnerWrapper>
</GridCollapser>
Expand All @@ -59,7 +59,7 @@ const GridCollapser = styled.div<GridCollapserProps>`
}
`;

const InnerWrapper = styled.div<{ overflow: boolean }>`
const InnerWrapper = styled.div<{ $overflow: boolean }>`
width: 100%;
overflow: ${({ overflow }) => (overflow ? 'visible' : 'hidden')};
overflow: ${({ $overflow }) => ($overflow ? 'visible' : 'hidden')};
`;
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/Detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { styled } from 'styled-components';
export const Detail = styled.div`
display: inline-flex;
align-items: center;
gap: 1ch;
gap: 0.5ch;
margin-right: 2rem;
`;

Expand Down
6 changes: 1 addition & 5 deletions browser/data-browser/src/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface ExternalLinkProps {
export function ExternalLink({
to,
children,
variant,
variant = ExternalLinkVariant.Plain,
}: React.PropsWithChildren<ExternalLinkProps>): JSX.Element {
const Comp =
variant === ExternalLinkVariant.Button
Expand All @@ -29,10 +29,6 @@ export function ExternalLink({
);
}

ExternalLink.defaultProps = {
variant: ExternalLinkVariant.Plain,
};

const ExternalLinkPlain = styled.a`
display: inline-flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,27 @@ export function InlineFormattedResourceList({
}: InlineFormattedResourceListProps): JSX.Element {
// There are rare cases where a resource array can locally have an undefined value, we filter these out to prevent the formatter from throwing an error.
const filteredSubjects = subjects.filter(subject => subject !== undefined);
const parts = formatter.formatToParts(filteredSubjects);

return (
<>
{formatter.formatToParts(filteredSubjects).map(({ type, value }) => {
{parts.map(({ type, value }, i) => {
if (type === 'literal') {
return value;
}

let key = value;

// If the value is repeated, we add a suffix to make it unique
if (parts.findIndex(p => p.value === value) !== i) {
key = `${value}-${i}`;
}

if (RenderComp) {
return <RenderComp subject={value} key={value} />;
return <RenderComp subject={value} key={key} />;
}

return <ResourceInline subject={value} key={value} />;
return <ResourceInline subject={value} key={key} />;
})}
</>
);
Expand Down
9 changes: 8 additions & 1 deletion browser/data-browser/src/components/datatypes/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ type Props = {
*/
maxLength?: number;
className?: string;
nestedInLink?: boolean;
};

const disableElementsInLink = ['a'];

/** Renders a markdown value */
const Markdown: FC<Props> = ({
text,
renderGFM = true,
maxLength,
className,
nestedInLink = false,
}) => {
const [collapsed, setCollapsed] = useState(true);

Expand All @@ -33,7 +37,10 @@ const Markdown: FC<Props> = ({

return (
<MarkdownWrapper className={className}>
<ReactMarkdown remarkPlugins={renderGFM ? [remarkGFM] : []}>
<ReactMarkdown
remarkPlugins={renderGFM ? [remarkGFM] : []}
disallowedElements={nestedInLink ? disableElementsInLink : undefined}
>
{collapsed ? truncateMarkdown(text, maxLength) : text}
</ReactMarkdown>
{text.length > maxLength && collapsed && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { useUpload } from '../../../hooks/useUpload';
import { VisuallyHidden } from '../../VisuallyHidden';
import { styled } from 'styled-components';
import { ClearType, FilePickerButton } from './FilePickerButton';
import {
useValidation,
checkForInitialRequiredValue,
} from '../formValidation/useValidation';
import { ErrMessage } from '../InputStyles';

/**
* Button that opens a dialog that lists all files in the drive and allows the user to upload a new file.
Expand All @@ -24,6 +29,10 @@ export function FilePicker({
validate: false,
commit: commit,
});
const { error, setError, setTouched } = useValidation(
checkForInitialRequiredValue(value, required),
);

const [show, setShow] = useState(false);
const [selectedSubject, setSelectedSubject] = useState<string | undefined>(
value,
Expand Down Expand Up @@ -64,7 +73,15 @@ export function FilePicker({
}
} else {
setValue(undefined);

if (required) {
setError('Required');
}

return;
}

setError(undefined);
}, [selectedSubject, selectedFile]);

return (
Expand All @@ -74,7 +91,7 @@ export function FilePicker({
<input
aria-hidden
type='text'
value={value ?? ''}
defaultValue={value ?? ''}
required={required}
disabled={disabled}
/>
Expand All @@ -83,7 +100,10 @@ export function FilePicker({
file={selectedFile}
subject={selectedSubject}
disabled={disabled}
onButtonClick={() => setShow(true)}
onButtonClick={() => {
setShow(true);
setTouched();
}}
onClear={clearType => {
if (clearType === ClearType.File) {
setSelectedFile(undefined);
Expand All @@ -99,6 +119,7 @@ export function FilePicker({
onResourcePicked={setSelectedSubject}
onNewFilePicked={setSelectedFile}
/>
{error && <ErrMessage>{error}</ErrMessage>}
</Wrapper>
);
}
Expand Down
Loading

0 comments on commit 6bc7eb5

Please sign in to comment.