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
3 changes: 2 additions & 1 deletion examples/nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import './global.css'
import {BaseStyles, ThemeProvider} from '@primer/react'
import {ThemeProvider} from '@primer/styled-react'
import {BaseStyles} from '@primer/react'
import {StyledComponentsRegistry} from './registry'

export const metadata = {
Expand Down
23 changes: 21 additions & 2 deletions examples/nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import {Button} from '@primer/react'
'use client'

import {Box, Button, Stack} from '@primer/react'
import styled from 'styled-components'

const StyledDiv = styled.div(({theme}) => {
console.log({styledTheme: theme})

Check failure on line 7 in examples/nextjs/src/app/page.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
return {
padding: theme.space[5],
backgroundColor: theme.colors.btn.primary.bg,
}
})

export default function IndexPage() {
return <Button>Hello world</Button>
return (
<Stack direction="horizontal">
<Button variant="primary" sx={{padding: 5}}>
Hello world
</Button>
<Box sx={{padding: 5, backgroundColor: 'btn.primary.bg'}}>Hello world</Box>
<StyledDiv>Hello world</StyledDiv>
</Stack>
)
}
102 changes: 102 additions & 0 deletions packages/styled-react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,109 @@
extensions: ['.ts', '.tsx'],
babelHelpers: 'bundled',
}),

/**
* This custom rollup plugin allows us to preserve directives in source
* code, such as "use client", in order to support React Server Components.
*
* The source for this plugin is inspired by:
* https://github.com/Ephem/rollup-plugin-preserve-directives
*/
{
name: 'preserve-directives',
transform(code) {
const ast = this.parse(code)
if (ast.type !== 'Program' || !ast.body) {
return {
code,
ast,
map: null,
}
}

let hasClientDirective = false

for (const node of ast.body) {
if (!node) {
continue
}

if (node.type !== 'ExpressionStatement') {
continue
}

if (node.directive === 'use client') {
hasClientDirective = true
break
}
}

if (hasClientDirective) {
return {
code,
ast,
map: null,
meta: {
hasClientDirective: true,
},
}
}

return {
code,
ast,
map: null,
}
},
renderChunk: {
order: 'post',
handler(code, chunk, options) {
// If `preserveModules` is not set to true, we can't be sure if the client
// directive corresponds to the whole chunk or just a part of it.
if (!options.preserveModules) {
return undefined
}

let chunkHasClientDirective = false

for (const moduleId of Object.keys(chunk.modules)) {
const hasClientDirective = this.getModuleInfo(moduleId)?.meta?.hasClientDirective
if (hasClientDirective) {
chunkHasClientDirective = true
break
}
}

if (chunkHasClientDirective) {
const transformed = new MagicString(code)

Check failure on line 103 in packages/styled-react/rollup.config.js

View workflow job for this annotation

GitHub Actions / lint

'MagicString' is not defined
transformed.prepend(`"use client";\n`)
const sourcemap = transformed.generateMap({
includeContent: true,
})
return {
code: transformed.toString(),
map: sourcemap,
}
}

return null
},
},
},
],
onwarn(warning, defaultHandler) {
// Dependencies or modules may use "use client" as an indicator for React
// Server Components that this module should only be loaded on the client.
if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && warning.message.includes('use client')) {
return
}

if (warning.code === 'CIRCULAR_DEPENDENCY') {
throw warning
}

defaultHandler(warning)
},
output: {
dir: 'dist',
format: 'esm',
Expand Down
20 changes: 20 additions & 0 deletions packages/styled-react/src/components/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, {type PropsWithChildren} from 'react'
import {ThemeProvider as SCThemeProvider} from 'styled-components'
import {
ThemeProvider as PRCThemeProvider,
type ThemeProviderProps,
useTheme,
theme as fallbackTheme,
} from '@primer/react'

export const ThemeProvider = (props: PropsWithChildren<ThemeProviderProps>) => {
const {children, ...rest} = props
const {theme} = useTheme()

console.log({theme})

Check failure on line 14 in packages/styled-react/src/components/ThemeProvider.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
return (
<SCThemeProvider theme={theme || fallbackTheme}>
<PRCThemeProvider {...rest}>{children}</PRCThemeProvider>
</SCThemeProvider>
)
}
6 changes: 4 additions & 2 deletions packages/styled-react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

export {Box, type BoxProps} from './components/Box'
export {Button} from '@primer/react'
export {Details} from '@primer/react'
Expand All @@ -8,10 +10,10 @@ export {PageLayout} from '@primer/react'
export {Select} from '@primer/react'
export {Textarea} from '@primer/react'
export {TextInput} from '@primer/react'
export {type TextInputProps} from '@primer/react'
// export {type TextInputProps} from '@primer/react'

// theming depends on styled-components
export {ThemeProvider} from '@primer/react'
export {ThemeProvider} from './components/ThemeProvider'
export {merge} from '@primer/react'
export {theme} from '@primer/react'
export {themeGet} from '@primer/react'
Expand Down
Loading