Skip to content

Commit

Permalink
feat: add react icons (#1710)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelAlev authored Feb 9, 2024
1 parent 0afb3bb commit 9d97ec1
Show file tree
Hide file tree
Showing 46 changed files with 652 additions and 213 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilly-ears-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frontify/fondue-icons": patch
---

Generate React components
6 changes: 6 additions & 0 deletions .github/workflows/docs-pull-requests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
- name: Install npm dependencies
run: pnpm i --frozen-lockfile

- name: Generate React icons
run: pnpm --stream --filter {packages/icons} build:generate-react-icons

- name: Contentlayer build
run: pnpm --stream --filter {docs} build:contentlayer

Expand Down Expand Up @@ -63,6 +66,9 @@ jobs:
- name: Install npm dependencies
run: pnpm i --frozen-lockfile

- name: Generate React icons
run: pnpm --stream --filter {packages/icons} build:generate-react-icons

- name: Contentlayer build
run: pnpm --stream --filter {docs} build:contentlayer

Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/fondue-pull-requests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ jobs:
- name: Install npm dependencies
run: pnpm i --frozen-lockfile

- name: Generate icons
- name: Generate (old) icons
run: pnpm --stream --filter {packages/fondue} generate:icons && pnpm --stream --filter {packages/fondue} generate:componentsEnum

- name: Generate React icons
run: pnpm --stream --filter {packages/icons} build:generate-react-icons

- name: Lint code
run: pnpm --stream --filter {packages/fondue} --filter {packages/components} --filter {packages/icons} lint

Expand Down Expand Up @@ -71,6 +74,9 @@ jobs:
- name: Generate icons
run: pnpm --stream --filter {packages/fondue} generate:icons && pnpm --stream --filter {packages/fondue} generate:componentsEnum

- name: Generate React icons
run: pnpm --stream --filter {packages/icons} build:generate-react-icons

- name: Typecheck code
run: pnpm --stream --filter {packages/fondue} --filter {packages/components} --filter {packages/icons} typecheck

Expand Down Expand Up @@ -118,6 +124,9 @@ jobs:
- name: Generate icons
run: pnpm --stream --filter {packages/fondue} generate:icons && pnpm --stream --filter {packages/fondue} generate:componentsEnum

- name: Generate React icons
run: pnpm --stream --filter {packages/icons} build:generate-react-icons

- name: Component Tests
run: pnpm run --stream --filter {packages/fondue} test --spec $(node ./.github/lib/cypress-matrix.mjs ${{ env.NUMBER_OF_RUNNERS }} ${{ matrix.containers }})

Expand Down
4 changes: 2 additions & 2 deletions docs/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"root": true,
"extends": ["@frontify/eslint-config-react", "plugin:jsx-a11y/recommended"],
"plugins": ["jsx-a11y", "notice"],
"extends": ["@frontify/eslint-config-react"],
"plugins": [ "notice"],
"settings": {
"react": {
"version": "detect",
Expand Down
40 changes: 1 addition & 39 deletions docs/contentlayer.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,11 @@ const Component = defineDocumentType(() => ({
},
}));

const Icon = defineDocumentType(() => ({
name: 'Icon',
filePathPattern: '**/*.mdx', // To be changed with the package path
contentType: 'mdx',
fields: {
title: { type: 'string', required: true },
},
computedFields: {
url: {
type: 'string',
resolve: (doc) => doc._raw.sourceFileDir.toLocaleLowerCase(),
},
route: {
type: 'string',
resolve: (doc) => doc._raw.sourceFileDir.toLocaleLowerCase().split('/').at(-1),
},
},
}));

const Token = defineDocumentType(() => ({
name: 'Token',
filePathPattern: '**/*.mdx', // To be changed with the package path
contentType: 'mdx',
fields: {
title: { type: 'string', required: true },
},
computedFields: {
url: {
type: 'string',
resolve: (doc) => doc._raw.sourceFileDir.toLocaleLowerCase(),
},
route: {
type: 'string',
resolve: (doc) => doc._raw.sourceFileDir.toLocaleLowerCase().split('/').at(-1),
},
},
}));

const sources: ReturnType<typeof makeSource> = makeSource({
contentDirPath: '.',
contentDirInclude: [FONDUE_COMPONENTS_PATH],
contentDirExclude: [...EXCLUDES, ...EXCLUDES.map((path) => `${FONDUE_COMPONENTS_PATH}/${path}`)],
documentTypes: [Component, Icon, Token],
documentTypes: [Component],
});

export default sources;
9 changes: 5 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
"dependencies": {
"@frontify/fondue": "workspace:^",
"@frontify/fondue-components": "workspace:^",
"@frontify/fondue-icons": "workspace:^",
"@frontify/fondue-tokens": "^3.4.0",
"@tailwindcss/forms": "^0.5.7",
"mdx-bundler": "^10.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vike": "^0.4.160",
"vike": "^0.4.161",
"vike-react": "^0.4.4"
},
"devDependencies": {
"@frontify/eslint-config-react": "0.17.0",
"@types/node": "^18.19.14",
"@types/node": "^18.19.15",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.18",
"@types/react-dom": "^18.2.19",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.17",
"concurrently": "^8.2.2",
Expand All @@ -42,6 +43,6 @@
"prettier": "^3.2.5",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
"vite": "^5.0.12"
"vite": "^5.1.1"
}
}
2 changes: 1 addition & 1 deletion docs/src/pages/+Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import fondueLogo from '../assets/images/fondue_logo.png';
export const Layout = ({ children }: { children: ReactNode }) => {
return (
<main className="tw-h-dvh tw-flex tw-flex-col">
<header className="tw-px-4 tw-flex tw-items-center tw-h-16">
<header className="tw-px-4 tw-flex tw-items-center tw-h-16 tw-min-h-[4rem]">
<a className="tw-p-1 tw-h-8" href="/">
<img className="tw-h-full tw-object-contain" src={fondueLogo} alt="Fondue Logo" />
</a>
Expand Down
8 changes: 1 addition & 7 deletions docs/src/pages/components/+Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ export const Layout = ({ children }: { children: ReactNode }) => {
</ul>
</nav>

<div className="tw-p-8 tw-w-full tw-flex tw-justify-center">
<div className="tw-max-w-[856px] tw-w-full">{children}</div>
</div>

<aside className="tw-p-8 2xl:tw-flex tw-hidden tw-flex-col tw-w-72 tw-shrink-0">
<span className="tw-text-lg tw-font-bold">Table of content</span>
</aside>
{children}
</div>
</RootLayout>
);
Expand Down
19 changes: 5 additions & 14 deletions docs/src/pages/components/+Page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { usePageContext } from 'vike-react/usePageContext';

import { MdxContent } from '../../components/MdxContent';

export const Page = () => {
const { data } = usePageContext();

if (!data) {
return <h1 className="tw-text-3xl tw-font-bold tw-mb-8">Components</h1>;
}

return (
<>
<h1 className="tw-text-3xl tw-font-bold tw-mb-8">{data.component.title}</h1>
<MdxContent data={data.component.body.code} />
</>
<div className="tw-p-8 tw-w-full tw-flex tw-justify-center">
<div className="tw-max-w-[856px] tw-w-full">
<h1 className="tw-text-3xl tw-font-bold">Components</h1>
</div>
</div>
);
};
7 changes: 0 additions & 7 deletions docs/src/pages/components/+onBeforePrerenderStart.ts

This file was deleted.

18 changes: 0 additions & 18 deletions docs/src/pages/components/+route.ts

This file was deleted.

27 changes: 27 additions & 0 deletions docs/src/pages/components/@componentId/+Page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { usePageContext } from 'vike-react/usePageContext';

import { MdxContent } from '../../../components/MdxContent';

export const Page = () => {
const { data } = usePageContext();

if (!data) {
return <h1 className="tw-text-3xl tw-font-bold tw-mb-8">Components</h1>;
}

return (
<>
<div className="tw-p-8 tw-w-full tw-flex tw-justify-center">
<div className="tw-max-w-[856px] tw-w-full">
<h1 className="tw-text-3xl tw-font-bold tw-mb-8">{data.component.title}</h1>
<MdxContent data={data.component.body.code} />
</div>
</div>
<aside className="tw-p-8 2xl:tw-flex tw-hidden tw-flex-col tw-w-72 tw-shrink-0">
<span className="tw-text-lg tw-font-bold">Table of content</span>
</aside>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ export type Data = Awaited<ReturnType<typeof data>>;
export const data = (pageContext: PageContextServer) => {
const { routeParams } = pageContext;

const component = allComponents.find((component) => {
return component.route === routeParams.pageUrl;
});
const component = allComponents.find((component) => component.route === routeParams.componentId);

if (!component) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { allComponents } from '#contentlayer/generated';

export const onBeforePrerenderStart = (): string[] => {
return allComponents.map((component) => `/components/${component.route}`);
};
17 changes: 17 additions & 0 deletions docs/src/pages/icons/+Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { type ReactNode } from 'react';

import { Layout as RootLayout } from '../+Layout';

export const Layout = ({ children }: { children: ReactNode }) => {
return (
<RootLayout>
<div className="tw-h-full tw-flex tw-w-full">
<div className="tw-p-8 tw-w-full tw-flex tw-justify-center">
<div className="tw-max-w-[856px] tw-w-full">{children}</div>
</div>
</div>
</RootLayout>
);
};
22 changes: 22 additions & 0 deletions docs/src/pages/icons/+Page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { icons } from '@frontify/fondue-icons';

import { kebabCase } from '../../utilities/kebabCase';

export const Page = () => {
return (
<div className="tw-p-8">
<h1 className="tw-text-3xl tw-font-bold">Icons</h1>

<div className="tw-mt-8 tw-gap-8 tw-grid tw-grid-cols-[repeat(auto-fill,minmax(56px,1fr))]">
{Object.keys(icons).map((icon) => {
const IconComponent = icons[icon as keyof typeof icons];

const iconPath = kebabCase(icon).replace(/^icon-/, '');

return (
<a
href={`/icons/${iconPath}`}
key={icon}
className="tw-inline-flex tw-items-center tw-justify-center tw-aspect-square tw-rounded tw-bg-box-neutral hover:tw-bg-box-neutral-hover active:tw-bg-box-neutral-pressed"
>
<IconComponent />
</a>
);
})}
</div>
</div>
);
};
31 changes: 31 additions & 0 deletions docs/src/pages/icons/@iconId/+Page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { icons } from '@frontify/fondue-icons';

import { kebabCase } from '../../../utilities/kebabCase';

export const Page = () => {
return (
<div className="tw-p-8">
<h1 className="tw-text-3xl tw-font-bold">Icons</h1>

<div className="tw-mt-8 tw-gap-8 tw-grid tw-grid-cols-[repeat(auto-fill,minmax(56px,1fr))]">
{Object.keys(icons).map((icon) => {
const IconComponent = icons[icon as keyof typeof icons];

const iconPath = kebabCase(icon).replace(/^icon-/, '');

return (
<a
href={`/icons/${iconPath}`}
key={icon}
className="tw-inline-flex tw-items-center tw-justify-center tw-aspect-square tw-rounded tw-bg-box-neutral hover:tw-bg-box-neutral-hover active:tw-bg-box-neutral-pressed"
>
<IconComponent />
</a>
);
})}
</div>
</div>
);
};
11 changes: 11 additions & 0 deletions docs/src/pages/icons/@iconId/+data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { type PageContextServer } from 'vike/types';

export type Data = Awaited<ReturnType<typeof data>>;

export const data = (pageContext: PageContextServer) => {
const { routeParams } = pageContext;

return { iconId: routeParams.iconId };
};
11 changes: 11 additions & 0 deletions docs/src/pages/icons/@iconId/+onBeforePrerenderStart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { icons } from '@frontify/fondue-icons';

import { kebabCase } from '../../../utilities/kebabCase';

export const onBeforePrerenderStart = () => {
const allIcons = Object.keys(icons);

return allIcons.map((icon) => `/icons/${kebabCase(icon).replace(/^icon-/, '')}`);
};
5 changes: 5 additions & 0 deletions docs/src/utilities/kebabCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

export const kebabCase = (value: string): string => {
return value.replaceAll(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
};
4 changes: 2 additions & 2 deletions packages/components/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"root": true,
"extends": ["@frontify/eslint-config-react", "plugin:jsx-a11y/recommended"],
"plugins": ["jsx-a11y", "notice"],
"extends": ["@frontify/eslint-config-react"],
"plugins": ["notice"],
"settings": {
"react": {
"version": "detect",
Expand Down
Loading

0 comments on commit 9d97ec1

Please sign in to comment.