Skip to content
Closed
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
658 changes: 658 additions & 0 deletions figma/figma.d.ts

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions figma/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@primer/components",
"id": "045995778738837860",
"api": "1.0.0",
"main": "dist/code.js",
"ui": "dist/ui.html"
}
6,327 changes: 6,327 additions & 0 deletions figma/package-lock.json

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions figma/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@primer/figma-components",
"version": "0.0.1",
"description": "Primer React components to Figma adapter",
"main": "./src/code.tsx",
"scripts": {
"webpack:watch": "webpack --watch",
"clean": "rm -rf dist/",
"build:js": "webpack",
"build": "npm run clean && npm run build:js"
},
"private": true,
"keywords": [
"react",
"react-figma",
"styled-components",
"figma",
"react-primitives"
],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/primer/components.git"
},
"author": "Macintosh Helper <github@macintoshhelper.com>",
"license": "ISC",
"dependencies": {
"chroma-js": "^2.1.0",
"react": "^16.9.0",
"react-figma": "0.0.57",
"react-primitives": "^0.8.1",
"styled-components": "^5.0.1",
"yoga-layout-prebuilt": "^1.9.3"
},
"devDependencies": {
"html-webpack-inline-source-plugin": "^0.0.10",
"html-webpack-plugin": "^3.2.0",
"react-figma-webpack-config": "0.0.5",
"ts-loader": "^6.0.4",
"typescript": "^3.5.3",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.7"
}
}
149 changes: 149 additions & 0 deletions figma/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import * as React from 'react';
import { Page, Frame } from 'react-figma';

// @ts-ignore
import styled, { ThemeProvider } from 'styled-components';
import { layout } from 'styled-system';

import Section from './components/Section';
import { Subtitle } from './components/Heading';

import Text from '../../src/Text';
import Flex from '../../src/Flex';
import Avatar from '../../src/Avatar';
import AvatarPair from '../../src/AvatarPair';
import Button from '../../src/Button';
import ButtonPrimary from '../../src/ButtonPrimary';
import ButtonDanger from '../../src/ButtonDanger';
import ButtonOutline from '../../src/ButtonOutline';

// import Text from '../../src/Text';
import theme from '../../src/theme';

const Artboard = styled(Frame)`
padding: 40px;
background-color: #ffffff;
padding-top: 40px;
padding-bottom: 40px;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
${layout}
`;

const Components = () => (
<Flex justifyContent="flex-start" flex={1} flexDirection="column">
<Text fontSize={40}>Components Style-guide</Text>
<Text>TODO:</Text>
</Flex>
)

// @ts-ignore
const GroupTitle = styled.Text`
font-family: 'SF Pro Text';
font-size: 24px;
font-weight: 600;
line-height: 24px;
margin-bottom: 22px;
`;

const styleguide = [{
name: 'Components',
type: 'components',
isCurrent: true,
data: {},
screens: [{
name: 'Components',
component: Components,
data: {},
}],
pages: [{
name: 'Avatar',
data: {},
sections: [{
title: 'Avatars',
description: 'Avatars are images used to represent users and organizations on GitHub. They typically are squares with rounded edges.',
data: {},
component: () => (
<>
<Subtitle mb={3}>Default example</Subtitle>
<Flex flexDirection="row">
<Avatar source="https://avatars.githubusercontent.com/primer" size={128} />
{/* AvatarPair: parent Frame doesn't resolve the sizing properly, and box-shadow is applied to wrong layer */}
{/* <AvatarPair my={4}>
<Avatar source="https://avatars.githubusercontent.com/primer" />
<Avatar source="https://avatars.githubusercontent.com/primer" />
</AvatarPair> */}
{/* AvatarStack: Need to replace <div className="AvatarItem-more AvatarItem" /> with an encapsulated component
<AvatarStack>
<img alt="Primer" src="https://avatars.githubusercontent.com/primer" />
<img alt="GitHub" src="https://avatars.githubusercontent.com/github" />
<img alt="Atom" src="https://avatars.githubusercontent.com/atom" />
<img alt="Desktop" src="https://avatars.githubusercontent.com/desktop" />
</AvatarStack>
*/}
</Flex>
</>
)
}]
}, {
name: 'Buttons',
sections: [{
title: 'Buttons',
description: 'Button is used for actions, like in forms, while Link is used for destinations, or moving from one page to another.',
data: {},
component: () => (
<>
<Subtitle mb={3}>Default examples</Subtitle>
<Flex flexDirection="row">
<Button>Button</Button>
<ButtonDanger>Button Danger</ButtonDanger>
<ButtonOutline>Button Outline</ButtonOutline>
<ButtonPrimary>Button Primary</ButtonPrimary>
</Flex>
</>
),
}]
}],
}]

const StyleGuide = () => (
<>
{styleguide.map(({
type, name, screens, data, pages,
}) => (
<>
<Page name={name} key={name}>
{screens.map(({ name: screenName, component: Component, data: compData }) => (
<Artboard width={600} name={screenName}>
<Component {...{ [type]: Object.assign({}, data, compData) }} />
</Artboard>
))}
</Page>
{pages && pages.map(page => (
<Page name={` ↳ ${page.name}`} key={`${name} / ${page.name}`}>
{/*page.component ? (
<Artboard width={600} name={page.name}>
<page.component {...{ [type]: Object.assign({}, data, page.data) }} />
</Artboard>
) :*/ (page.sections || []).map(({ title, description, component: Component, data: compData }) => (
<Artboard width={600} name={title}>
<Section title={title} description={description}>
<Component {...{ [type]: Object.assign({}, data, compData) }} />
</Section>
</Artboard>
))}
</Page>
))}
</>
))}
</>
);

export const App = () => {
return (
<ThemeProvider theme={theme}>
<StyleGuide />
</ThemeProvider>
);
};
11 changes: 11 additions & 0 deletions figma/src/code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import { render, subscribeOnMessages } from 'react-figma';
import { App } from './App';

figma.showUI(__html__, { visible: false });

figma.ui.onmessage = message => {
subscribeOnMessages(message);
};

render(<App />, figma.root);
31 changes: 31 additions & 0 deletions figma/src/components/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import styled from 'styled-components';
import { typography } from 'styled-system';

import BaseHeading from '../../../src/Heading';

export const Title = styled(BaseHeading)`

font-family: 'SF Pro Text';
font-size: 24px;
font-weight: 600;
line-height: 24px;
`;

// Title.defaultProps = {
// fontFamily: 'SF Pro Text',
// fontSize: 24,
// fontWeight: 600,
// lineHeight: 24,
// };

export const Subtitle = styled(Title)`
font-weight: 500;
font-size: 18;
line-height: 20;
`;

// Subtitle.defaultProps = {
// fontWeight: 500,
// fontSize: 20,
// lineHeight: 20,
// };
45 changes: 45 additions & 0 deletions figma/src/components/Section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from 'react';
import styled from 'styled-components';

import Box from '../../../src/Box';
import Flex from '../../../src/Flex';
import Text from '../../../src/Text';

import { Title } from './Heading';

const Line = styled(Box)``;
Line.defaultProps = {
width: 64,
height: 1,
bg: 'black',
borderWidth: 0,
}



interface SectionProps {
title: string,
description?: string,
children: React.ReactNode,
};

// TODO: Investigate why the maxWidth={520} is needed to prevent overlap, seems flex={1} isn't working?

const Section = ({ title, description, children }: SectionProps) => (
<Flex flex={1} maxWidth={520}>
<Box mb={40}>
<Title mb={1}>
{title}
</Title>
<Line bg="#ddd" width={520} />
{Boolean(description) && (
<Text fontSize={14} mt={20} style={{ maxWidth: 520 }}>
{description}
</Text>
)}
</Box>
{children}
</Flex>
);

export default Section;
38 changes: 38 additions & 0 deletions figma/src/styled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable import/first */
/* eslint-disable import/no-mutable-exports */
/* eslint-disable prettier/prettier */
import { Platform } from 'react-primitives';

let styled, ThemeProvider, css;

import styledW, { css as cssW, ThemeProvider as ThemeProviderW } from '../node_modules/styled-components';
import styledP, { css as cssP, ThemeProvider as ThemeProviderP } from '../node_modules/styled-components/primitives';

if (Platform.OS === 'figma') {
styled = styledP;
ThemeProvider = ThemeProviderP;
css = cssP;

styled.div = styled.View;
styled.button = styled.View;
styled.span = styled.Text;
styled.p = styled.Text;
styled.h1 = styled.Text;
styled.h2 = styled.Text;
styled.h3 = styled.Text;
styled.h4 = styled.Text;
styled.h5 = styled.Text;
styled.h6 = styled.Text;
styled.img = styled.Image;
} else {
styled = styledW;
ThemeProvider = ThemeProviderW;
css = cssW;

styled.View = styled.div;
styled.Text = styled.span;
}

export { ThemeProvider, css };

export default styled;
Empty file added figma/src/ui.html
Empty file.
8 changes: 8 additions & 0 deletions figma/src/ui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare type fetch = (input: RequestInfo, init?: RequestInit) => Promise<Response>;

import * as yoga from 'yoga-layout-prebuilt';
import { uiWorker } from 'react-figma';

onmessage = event => {
uiWorker({ yoga, fetch })(event);
};
8 changes: 8 additions & 0 deletions figma/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"jsx": "react"
}
}
28 changes: 28 additions & 0 deletions figma/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const path = require('path')
const configure = require('react-figma-webpack-config')

module.exports = configure({
module: {
rules: [
{
test: /\.(js|jsx)?$/,
use: {
loader: require.resolve('ts-loader'),
options: {
// this will disable any type checking for js/jsx files, but use TS to transform jsx
transpileOnly: true,
},
},
exclude: /node_modules/,
},
],
},
resolve: {
alias: {
react: path.resolve(__dirname, './node_modules/react/'),
'react-figma': path.resolve(__dirname, './node_modules/react-figma/'),
'styled-components': path.resolve(__dirname, './src/styled'),
'@primer/components': path.resolve(__dirname, '../dist/index.esm.js'),
},
},
})
Loading