Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Link component override #1441

Merged
merged 5 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions components/Breadcrumb/src/BreadcrumbLink.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { AnchorHTMLAttributes } from 'react';
import { CustomLink } from '@gemeente-denhaag/link';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import { BasicLink } from '@gemeente-denhaag/link';
import clsx from 'clsx';
import './index.scss';

export interface BreadcrumbLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
Link?: CustomLink;
Link?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

export const BreadcrumbLink: React.FC<BreadcrumbLinkProps> = ({
className,
children,
Link = ({ children, ...props }) => <a {...props}>{children}</a>,
Link = BasicLink,
...props
}: BreadcrumbLinkProps) => {
const classNames = clsx('denhaag-breadcrumb__link', className);
Expand Down
5 changes: 2 additions & 3 deletions components/Breadcrumb/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import ResponsiveContent from '@gemeente-denhaag/responsive-content';
import { ChevronRightIcon, HouseIcon } from '@gemeente-denhaag/icons';
import { CustomLink } from '@gemeente-denhaag/link';
import { BreadcrumbNavigation } from './BreadcrumbNavigation';
import { BreadcrumbListItem } from './BreadcrumbListItem';
import { BreadcrumbList } from './BreadcrumbList';
Expand Down Expand Up @@ -29,7 +28,7 @@ export interface BreadcrumbProps {
/**
* Custom Link component used for single-page apps.
*/
Link?: CustomLink;
Link?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

export const Breadcrumb: React.FC<BreadcrumbProps> = ({ navigationPath, showHomeIcon, Link }: BreadcrumbProps) => {
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardProps extends HTMLAttributes<HTMLDivElement> {}

export const Card: React.FC<CardProps> = ({ className, ...props }) => {
export const Card = ({ className, ...props }: CardProps) => {
const classNames = clsx('denhaag-card', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
15 changes: 4 additions & 11 deletions components/Card/src/Card/CardAction.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import React, { AnchorHTMLAttributes } from 'react';
import { CustomLink } from '@gemeente-denhaag/link';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import BasicLink from '@gemeente-denhaag/link';
import clsx from 'clsx';
import '../index.scss';

export interface CardActionProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
Action?: CustomLink;
Action?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

const DefaultLink = ({ children, ...props }: AnchorHTMLAttributes<HTMLAnchorElement>) => <a {...props}>{children}</a>;

export const CardAction: React.FC<CardActionProps> = ({
className,
children,
Action = DefaultLink,
...props
}: CardActionProps) => {
export const CardAction = ({ className, children, Action = BasicLink, ...props }: CardActionProps) => {
const classNames = clsx('denhaag-card__action-link', className);

return (
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardActionsProps extends HTMLAttributes<HTMLDivElement> {}

export const CardActions: React.FC<CardActionsProps> = ({ className, ...props }) => {
export const CardActions = ({ className, ...props }: CardActionsProps) => {
const classNames = clsx('denhaag-card__actions', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardBackground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardBackgroundProps extends HTMLAttributes<HTMLDivElement> {}

export const CardBackground: React.FC<CardBackgroundProps> = ({ className, ...props }) => {
export const CardBackground = ({ className, ...props }: CardBackgroundProps) => {
const classNames = clsx('denhaag-card__background', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardContentProps extends HTMLAttributes<HTMLDivElement> {}

export const CardContent: React.FC<CardContentProps> = ({ className, ...props }) => {
export const CardContent = ({ className, ...props }: CardContentProps) => {
const classNames = clsx('denhaag-card__content', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardDate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import '../index.scss';

export interface CardDateProps extends TimeHTMLAttributes<HTMLTimeElement> {}

export const CardDate: React.FC<CardDateProps> = (props) => {
export const CardDate = ({ ...props }: CardDateProps) => {
return <time {...props}></time>;
};

Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardDateWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardDateWrapperProps extends HTMLAttributes<HTMLDivElement> {}

export const CardDateWrapper: React.FC<CardDateWrapperProps> = ({ className, ...props }) => {
export const CardDateWrapper = ({ className, ...props }: CardDateWrapperProps) => {
const classNames = clsx('denhaag-card__date-wrapper', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardTextWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardTextWrapperProps extends HTMLAttributes<HTMLDivElement> {}

export const CardTextWrapper: React.FC<CardTextWrapperProps> = ({ className, ...props }) => {
export const CardTextWrapper = ({ className, ...props }: CardTextWrapperProps) => {
const classNames = clsx('denhaag-card__text-wrapper', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
2 changes: 1 addition & 1 deletion components/Card/src/Card/CardWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx';

export interface CardWrapperProps extends HTMLAttributes<HTMLDivElement> {}

export const CardWrapper: React.FC<CardWrapperProps> = ({ className, ...props }) => {
export const CardWrapper = ({ className, ...props }: CardWrapperProps) => {
const classNames = clsx('denhaag-card__wrapper', className);
return <div className={classNames} {...props}></div>;
};
Expand Down
15 changes: 4 additions & 11 deletions components/Card/src/Card/CaseCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import { ArrowRightIcon } from '@gemeente-denhaag/icons';
import { CustomLink } from '@gemeente-denhaag/link';
import { BasicLink } from '@gemeente-denhaag/link';
import { Paragraph } from '@gemeente-denhaag/typography';
import clsx from 'clsx';
import '../index.scss';
Expand Down Expand Up @@ -43,20 +43,13 @@ export interface CaseCardProps {
/**
* Custom Link component used for single-page apps.
*/
Link?: CustomLink;
Link?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

/**
* Primary UI component for user interaction
*/
export const CaseCard: React.FC<CaseCardProps> = ({
title,
subTitle,
date,
href,
active = true,
Link,
}: CaseCardProps) => {
export const CaseCard = ({ title, subTitle, date, href, active = true, Link = BasicLink }: CaseCardProps) => {
const classNames = clsx('denhaag-case-card', !active && 'denhaag-case-card--archived');

return (
Expand Down
8 changes: 4 additions & 4 deletions components/Card/src/Card/SubjectCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import { ArrowRightIcon } from '@gemeente-denhaag/icons';
import { CustomLink } from '@gemeente-denhaag/link';
import { BasicLink } from '@gemeente-denhaag/link';
import { Paragraph } from '@gemeente-denhaag/typography';
import '../index.scss';
import Card from './Card';
Expand Down Expand Up @@ -35,13 +35,13 @@ export interface SubjectCardProps {
/**
* Custom Link component used for single-page apps.
*/
Link?: CustomLink;
Link?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

/**
* Primary UI component for user interaction
*/
export const SubjectCard: React.FC<SubjectCardProps> = ({ title, subTitle, date, href, Link }: SubjectCardProps) => {
export const SubjectCard = ({ title, subTitle, date, href, Link = BasicLink }: SubjectCardProps) => {
return (
<Card className="denhaag-subject-card">
<CardContent>
Expand Down
4 changes: 2 additions & 2 deletions components/Header/src/HeaderLogic.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { AnchorHTMLAttributes, useEffect, useRef, useState } from 'react';
import React, { AnchorHTMLAttributes, ComponentType, useEffect, useRef, useState } from 'react';
import HeaderLogo from '@gemeente-denhaag/header-logo';
import ResponsiveContent from '@gemeente-denhaag/responsive-content';
import Link from '@gemeente-denhaag/link';
Expand Down Expand Up @@ -49,7 +49,7 @@ interface MenuProps {
label: string;
authorisedLoginLabel?: string;
navigationGroups: Array<NavigationGroupProps>;
CustomLink?: (props: AnchorHTMLAttributes<HTMLAnchorElement>) => JSX.Element;
CustomLink?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

interface NavigationGroupProps {
Expand Down
7 changes: 7 additions & 0 deletions components/Link/src/BasicLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React, { AnchorHTMLAttributes } from 'react';

export const BasicLink = ({ children, ...props }: AnchorHTMLAttributes<HTMLAnchorElement>) => (
<a {...props}>{children}</a>
);

export default BasicLink;
5 changes: 0 additions & 5 deletions components/Link/src/CustomLink.tsx

This file was deleted.

118 changes: 10 additions & 108 deletions components/Link/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,124 +1,26 @@
import React from 'react';
import React, { AnchorHTMLAttributes, ComponentType } from 'react';
import { SvgIconProps } from '@gemeente-denhaag/icons';
import BasicLink from './BasicLink';
import clsx from 'clsx';

import './index.scss';

type OverrideProps<M, C extends React.ElementType> = M & Omit<React.ComponentPropsWithRef<C>, keyof M>;

interface OverridableComponent<M> {
<C extends React.ElementType>(
props: {
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
*/
component: C;
} & OverrideProps<M, C>,
): JSX.Element;
(props: M): JSX.Element;
}

export interface LinkProps {
/**
* The id attribute is used to specify a unique id for an HTML element.
*/
id?: string;
/**
* The contents of the component.
*/
children?: React.ReactNode;
/**
* Extend the styles of the component by adding new classes.
*/
className?: string;
/**
* The tab-index applied to the root element of the component.
*/
tabIndex?: number;
/**
* The URL that the hyperlink points to. Links are not restricted to HTTP-based
* URLs — they can use any URL scheme supported by browsers.
*
* [(See MDN Web Docs for details)](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-href)
*/
href?: string;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-hreflang)
*/
hrefLang?: string;

/**
* Icon to display at the start or the end of the link
*/
export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
icon?: React.ReactElement<SvgIconProps>;

/**
* If an `icon` is specified, should it be aligned on the left or the right?
*/
iconAlign?: 'start' | 'end';

/**
* Disables the link.
*/
disabled?: boolean;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download)
*/
download?: string | boolean;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-media)
*/
media?: string;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-ping)
*/
ping?: string;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-rel)
*/
rel?: string;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target)
*/
target?: React.HTMLAttributeAnchorTarget;

/**
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-type)
*/
type?: string;

/**
* ⚠️ Experimental.
* [See MDN Web Docs for details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-referrerpolicy)
*/
referrerPolicy?: React.HTMLAttributeReferrerPolicy;

/**
* Override base component
*/
component?: React.ElementType;
Link?: ComponentType<AnchorHTMLAttributes<HTMLAnchorElement>>;
}

/**
* An easily customizable anchor element.
* @param props The properties of a Link component.
* @constructor Constructs an instance of Link.
*/
export const Link: OverridableComponent<LinkProps> = ({
href,
id,
children = undefined,
export const Link = ({
disabled = false,
icon = undefined,
iconAlign = 'end',
tabIndex = 0,
children,
Link = BasicLink,
...props
}: LinkProps) => {
const rootClassNames = clsx(
Expand All @@ -137,14 +39,14 @@ export const Link: OverridableComponent<LinkProps> = ({
const iconWrapped = <span className={iconClassName}>{icon}</span>;

return (
<a id={id} href={href} tabIndex={disabled ? -1 : tabIndex} {...props} className={rootClassNames}>
<Link tabIndex={disabled ? -1 : tabIndex} {...props} className={rootClassNames}>
{icon !== undefined && iconAlign === 'start' ? iconWrapped : ''}
<span>{children}</span>
{icon !== undefined && iconAlign === 'end' ? iconWrapped : ''}
</a>
</Link>
);
};

export default Link;

export * from './CustomLink';
export * from './BasicLink';
Loading
Loading