Skip to content

Commit

Permalink
Add radix, fix thumbnails, add pattern export
Browse files Browse the repository at this point in the history
  • Loading branch information
dabbott committed Jan 22, 2024
1 parent 9ca9154 commit 61f98e1
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 142 deletions.
129 changes: 2 additions & 127 deletions packages/noya-compiler/src/astBuilders.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import { groupBy, unique } from '@noya-app/noya-utils';
import {
DesignSystemDefinition,
Theme,
component,
} from '@noya-design-system/protocol';
import { DSConfig } from 'noya-api';
import React, { CSSProperties, ReactNode } from 'react';
import { DesignSystemDefinition } from '@noya-design-system/protocol';
import React, { ReactNode } from 'react';
import ts from 'typescript';
import { clean } from './clean';
import {
SimpleElement,
SimpleElementTree,
buildNamespaceMap,
createPassthrough,
findElementNameAndSource,
isPassthrough,
isSimpleElement,
simpleElement,
} from './common';
import { print } from './print';
import { isSafeForJsxText, isValidPropertyKey } from './validate';

export function createJsxElement(
Expand Down Expand Up @@ -236,124 +228,7 @@ export function extractImports(
];
});
}
export function createLayoutSource({
DesignSystem,
_noya,
}: {
DesignSystem: DesignSystemDefinition;
_noya: { theme: Theme; dsConfig: DSConfig };
}): {
source: string;
} {
const cssImport = "import './globals.css'";

const defaultLayout = `${cssImport}
export default function RootLayout({ children }: React.PropsWithChildren<{}>) {
return children;
}
`;

const providerElement = DesignSystem.components[component.id.Provider]
? DesignSystem.components[component.id.Provider]({
theme: createPassthrough(ts.factory.createIdentifier('theme')),
children: createPassthrough(
ts.factory.createJsxExpression(
undefined,
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('props'),
ts.factory.createIdentifier('children'),
),
),
),
...(_noya && { _noya }),
})
: null;

const nextProviderElement = DesignSystem.components[component.id.NextProvider]
? DesignSystem.components[component.id.NextProvider]({
children: providerElement,
...(_noya && { _noya }),
})
: providerElement;

if (!nextProviderElement) return { source: defaultLayout };

const layoutElement = createSimpleElement(nextProviderElement, DesignSystem);

if (!layoutElement) return { source: defaultLayout };

const fonts = SimpleElementTree.reduce<string[]>(
layoutElement,
(result, node) => {
if (!isSimpleElement(node)) return result;

const style = node.props.style as CSSProperties | undefined;
const fontFamily = style?.fontFamily;

if (!fontFamily) return result;

delete style.fontFamily;

node.props.className = createPassthrough(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('font' + fontFamily),
ts.factory.createIdentifier('className'),
),
);

return [...result, fontFamily];
},
[],
);

const layoutComponentFunc = createReactComponentDeclaration(
'NextProvider',
createElementCode(layoutElement),
[
ts.factory.createParameterDeclaration(
undefined,
undefined,
ts.factory.createIdentifier('props'),
undefined,
// Type React.PropsWithChildren<{}>
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier('React.PropsWithChildren'),
[
// Empty object type
ts.factory.createTypeLiteralNode([]),
],
),
undefined,
),
],
);

const layoutImports = extractImports(layoutElement, DesignSystem);

const layoutSource = [
"'use client'",
[
cssImport,
"import React from 'react'",
print(layoutImports),
...(fonts.length > 0
? [`import { ${fonts.join(', ')} } from "next/font/google";`]
: []),
'import { theme } from "./theme"',
].join('\n'),
...fonts.map(
(font) => `const font${font} = ${font}({ subsets: ["latin"] })`,
),
print(layoutComponentFunc),
]
.map(clean)
.join('\n');

return {
source: layoutSource,
};
}
export function createSimpleElement(
originalElement: React.ReactNode,
DesignSystem: DesignSystemDefinition,
Expand Down
139 changes: 136 additions & 3 deletions packages/noya-compiler/src/compileDesignSystem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { tailwindColors } from '@noya-app/noya-tailwind';
import { Theme } from '@noya-design-system/protocol';
import {
DesignSystemDefinition,
Theme,
component,
transform,
} from '@noya-design-system/protocol';
import { DSConfig } from 'noya-api';
import {
FindComponent,
NoyaComponent,
Expand All @@ -8,12 +14,11 @@ import {
createResolvedNode,
renderResolvedNode,
} from 'noya-component';
import React, { ReactElement } from 'react';
import React, { CSSProperties, ReactElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import ts from 'typescript';
import {
createElementCode,
createLayoutSource,
createReactComponentDeclaration,
createSimpleElement,
extractImports,
Expand All @@ -25,6 +30,7 @@ import {
createPassthrough,
getComponentNameIdentifier,
isPassthrough,
isSimpleElement,
sortFiles,
} from './common';
import { generateThemeFile } from './compileTheme';
Expand All @@ -44,6 +50,7 @@ export type ExportMap = Partial<Record<ExportType, Record<string, string>>>;

export type CompileDesignSystemConfiguration = ResolvedCompilerConfiguration & {
includeTailwindBase: boolean;
spreadTheme: boolean;
exportTypes: ExportType[];
};

Expand Down Expand Up @@ -173,6 +180,7 @@ export function compileDesignSystem(

const layoutSource = createLayoutSource({
DesignSystem,
spreadTheme: configuration.spreadTheme,
_noya: createNoyaDSRenderingContext({
theme,
dsConfig: configuration.ds.config,
Expand Down Expand Up @@ -442,3 +450,128 @@ function createExport({

return exportMap;
}

export function createLayoutSource({
DesignSystem,
_noya,
spreadTheme,
}: {
DesignSystem: DesignSystemDefinition;
_noya: { theme: Theme; dsConfig: DSConfig };
spreadTheme: boolean;
}): {
source: string;
} {
const cssImport = "import './globals.css'";

const defaultLayout = `${cssImport}
export default function RootLayout({ children }: React.PropsWithChildren<{}>) {
return children;
}
`;

const providerElement = DesignSystem.components[component.id.Provider]
? DesignSystem.components[component.id.Provider]({
theme: createPassthrough(
spreadTheme
? transform({ theme: _noya.theme }, DesignSystem.themeTransformer)
: ts.factory.createIdentifier('theme'),
),
children: createPassthrough(
ts.factory.createJsxExpression(
undefined,
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('props'),
ts.factory.createIdentifier('children'),
),
),
),
...(_noya && { _noya }),
})
: null;

const nextProviderElement = DesignSystem.components[component.id.NextProvider]
? DesignSystem.components[component.id.NextProvider]({
children: providerElement,
...(_noya && { _noya }),
})
: providerElement;

if (!nextProviderElement) return { source: defaultLayout };

const layoutElement = createSimpleElement(nextProviderElement, DesignSystem);

if (!layoutElement) return { source: defaultLayout };

const fonts = SimpleElementTree.reduce<string[]>(
layoutElement,
(result, node) => {
if (!isSimpleElement(node)) return result;

const style = node.props.style as CSSProperties | undefined;
const fontFamily = style?.fontFamily;

if (!fontFamily) return result;

delete style.fontFamily;

node.props.className = createPassthrough(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('font' + fontFamily),
ts.factory.createIdentifier('className'),
),
);

return [...result, fontFamily];
},
[],
);

const layoutComponentFunc = createReactComponentDeclaration(
'NextProvider',
createElementCode(layoutElement),
[
ts.factory.createParameterDeclaration(
undefined,
undefined,
ts.factory.createIdentifier('props'),
undefined,
// Type React.PropsWithChildren<{}>
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier('React.PropsWithChildren'),
[
// Empty object type
ts.factory.createTypeLiteralNode([]),
],
),
undefined,
),
],
);

const layoutImports = extractImports(layoutElement, DesignSystem);

const layoutSource = [
"'use client'",
[
cssImport,
"import React from 'react'",
print(layoutImports),
...(fonts.length > 0
? [`import { ${fonts.join(', ')} } from "next/font/google";`]
: []),
...(spreadTheme ? [] : ['import { theme } from "./theme"']),
].join('\n'),
...fonts.map(
(font) => `const font${font} = ${font}({ subsets: ["latin"] })`,
),
print(layoutComponentFunc),
]
.map(clean)
.join('\n');

return {
source: layoutSource,
};
}
3 changes: 2 additions & 1 deletion packages/noya-compiler/src/compileProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export function compile(configuration: CompilerConfiguration) {
designSystemDefinition:
configuration.resolvedDefinitions[libraryName],
includeTailwindBase: libraryName === 'vanilla',
spreadTheme: libraryName.endsWith('radix'),
exportTypes:
libraryName === 'vanilla'
? [
Expand All @@ -73,7 +74,7 @@ export function compile(configuration: CompilerConfiguration) {
'react-css-modules',
'react-tailwind',
]
: libraryName.endsWith('chakra')
: libraryName.endsWith('chakra') || libraryName.endsWith('radix')
? ['react']
: ['react-css', 'react-tailwind'],
});
Expand Down
13 changes: 6 additions & 7 deletions packages/noya-module-loader/src/ThumbnailDesignSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ function getTheme(props: any) {
* This returns the wrapper span around the string child
*/
function getStringChild(props: any): ReactElement | undefined {
if (
props.children &&
Array.isArray(props.children) &&
props.children.length === 1 &&
props.children[0].key === 'editable-span'
) {
return props.children[0];
if (props.children && React.Children.count(props.children) === 1) {
const child = React.Children.only(props.children);

if (child.key === 'editable-span') {
return child;
}
}

return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const designSystems = {
'@noya-design-system/mui': 'Material Design',
'@noya-design-system/antd': 'Ant Design',
'@noya-design-system/chakra': 'Chakra UI',
'@noya-design-system/radix': 'Radix Themes',
};

export function DesignSystemPicker() {
Expand Down
Loading

0 comments on commit 61f98e1

Please sign in to comment.