Skip to content

Commit db417c2

Browse files
committed
fix: make pug reconstruct bindings; add extra options to babel preset; implement reactive update of @media for web and RN
1 parent df668d1 commit db417c2

File tree

13 files changed

+149
-17
lines changed

13 files changed

+149
-17
lines changed

example/client.tsx

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ function App () {
99
const [count, setCount] = useState(0)
1010

1111
return pug`
12-
Div(gap=2 align='center')
12+
Div.root(gap=2 align='center')
1313
Span.title(h1) CSSX Demo Page
1414
Div(row gap=2 vAlign='center')
1515
Button.down(onPress=() => setCount(c => c - 1)) -1
1616
Span(bold) Count: #{count}
1717
Button.up(onPress=() => setCount(c => c + 1)) +1
18+
Div(full)
19+
MediaRuler
1820
`
1921
styl`
22+
.root
23+
height 100%
2024
.title
2125
color: purple
2226
.down
@@ -33,25 +37,28 @@ function App () {
3337
interface DivProps {
3438
children: React.ReactNode // The content to be displayed inside the div
3539
row?: boolean // Arrange children in a row; otherwise, in a column
40+
full?: boolean // Make the div take full available space
3641
gap?: number | string // The gap between children, in pixels or CSS units
3742
align?: 'left' | 'center' | 'right' // The alignment of children
3843
vAlign?: 'top' | 'center' | 'bottom' // The vertical alignment of children
3944
onPress?: () => void // The function to call when the div is pressed
4045
}
41-
function Div ({ children, row, gap, align, vAlign, onPress }: DivProps) {
46+
function Div ({ children, row, gap, align, vAlign, full, onPress }: DivProps) {
4247
const style: React.CSSProperties = {}
4348
if (gap) style.gap = typeof gap === 'number' ? gap + 'u' : gap
4449
if (align) Object.assign(style, getAlignStyle(align, row))
4550
if (vAlign) Object.assign(style, getVerticalAlignStyle(vAlign, row))
4651
return pug`
47-
div.root(part='root' styleName={row} style=style onClick=onPress)= children
52+
div.root(part='root' styleName={row, full} style=style onClick=onPress)= children
4853
`
4954
styl`
5055
.root
5156
display: flex
5257
flex-direction: column
5358
&.row
5459
flex-direction: row
60+
&.full
61+
flex: 1
5562
`
5663
}
5764

@@ -116,6 +123,42 @@ function Button ({ children, ...props }: ButtonProps) {
116123
`
117124
}
118125

126+
/**
127+
* Demo changing styles based on media queries. Changes width and background color based on screen width.
128+
*/
129+
function MediaRuler () {
130+
return pug`
131+
Div.root(part='root' align='center' vAlign='center')
132+
Span.text @media ruler - resize window and change count to see the color change
133+
`
134+
styl`
135+
.root
136+
height: 2u
137+
border-radius: 1u
138+
width: 100%
139+
background-color: red
140+
@media (min-width: 768px)
141+
max-width: 768px
142+
background-color: orange
143+
@media (min-width: 1024px)
144+
max-width: 1024px
145+
background-color: yellow
146+
@media (min-width: 1280px)
147+
max-width: 1280px
148+
background-color: green
149+
@media (min-width: 1536px)
150+
max-width: 1536px
151+
background-color: blue
152+
@media (min-width: 1920px)
153+
max-width: 1920px
154+
background-color: purple
155+
.text
156+
color: white
157+
font-family: monospace
158+
font-size: 1.5u
159+
`
160+
}
161+
119162
function getAlignStyle (align: string, row?: boolean) {
120163
const style: React.CSSProperties = {}
121164
if (row) {

packages/babel-plugin-react-pug/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ module.exports = function (babel) {
5454
$this.traverse(pugVisitor, state)
5555
// support calling sub-components in pug (like <Modal.Header />)
5656
$this.traverse(classnamesVisitor, state)
57+
// re-crawl to update scope bindings
58+
$this.scope.crawl()
5759
}
5860
}
5961
}

packages/babel-plugin-rn-stylename-to-style/__tests__/index.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ pluginTester({
525525
'Options. Platform Web': {
526526
pluginOptions: {
527527
extensions: ['styl', 'css'],
528-
platform: 'web'
528+
reactType: 'web'
529529
},
530530
code: /* js */`
531531
import './index.styl'
@@ -539,7 +539,7 @@ pluginTester({
539539
'Options. Platform React Native': {
540540
pluginOptions: {
541541
extensions: ['styl', 'css'],
542-
platform: 'react-native'
542+
reactType: 'react-native'
543543
},
544544
code: /* js */`
545545
import './index.styl'
@@ -567,7 +567,7 @@ pluginTester({
567567
'Options. Platform React Native and Cache Teamplay': {
568568
pluginOptions: {
569569
extensions: ['styl', 'css'],
570-
platform: 'react-native',
570+
reactType: 'react-native',
571571
cache: 'teamplay'
572572
},
573573
code: /* js */`

packages/babel-plugin-rn-stylename-to-style/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const STYLE_REGEX = /(?:^s|S)tyle$/
1010
const ROOT_STYLE_PROP_NAME = 'style'
1111
const RUNTIME_PROCESS_NAME = 'cssx'
1212
const OPTIONS_CACHE = ['teamplay']
13-
const OPTIONS_PLATFORM = ['react-native', 'web']
13+
const OPTIONS_REACT_TYPES = ['react-native', 'web']
1414
const DEFAULT_MAGIC_IMPORTS = ['cssxjs', 'startupjs']
1515
const DEFAULT_OBSERVER_NAME = 'observer'
1616
const DEFAULT_OBSERVER_IMPORTS = ['teamplay', 'startupjs']
@@ -565,15 +565,15 @@ function getRuntimePath ($node, state, hasObserver) {
565565
// If observer() is used in this file then we force cache to 'teamplay'
566566
// TODO: this is a bit of a hack, think of a better way to do this
567567
if (!cache && hasObserver) cache = 'teamplay'
568-
const platform = state.opts.platform
569-
if (platform && !OPTIONS_PLATFORM.includes(platform)) {
568+
const reactType = state.opts.reactType
569+
if (reactType && !OPTIONS_REACT_TYPES.includes(reactType)) {
570570
throw $node.buildCodeFrameError(
571-
`Invalid platform option value: "${platform}". Supported values: ${OPTIONS_PLATFORM.join(', ')}`
571+
`Invalid reactType option value: "${reactType}". Supported values: ${OPTIONS_REACT_TYPES.join(', ')}`
572572
)
573573
}
574574
let runtimePath = RUNTIME_LIBRARY
575-
if (platform) {
576-
runtimePath += `/${platform}`
575+
if (reactType) {
576+
runtimePath += `/${reactType}`
577577
if (cache) {
578578
runtimePath += `-${cache}`
579579
}

packages/babel-preset-cssxjs/index.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
module.exports = (api, { platform } = {}) => {
1+
// platform - the actual platform (e.g. 'ios', 'android', 'web'). Default: 'web'.
2+
// On React Native this should be passed.
3+
// reactType - force the React target platform (e.g. 'react-native', 'web'). Default: undefined.
4+
// This shouldn't be needed in most cases since it will be automatically detected.
5+
// cache - force the CSS caching library instance (e.g. 'teamplay'). Default: undefined
6+
// This shouldn't be needed in most cases since it will be automatically detected.
7+
module.exports = (api, {
8+
platform,
9+
reactType,
10+
cache,
11+
transformPug = true,
12+
transformCss = true
13+
} = {}) => {
214
return {
315
overrides: [{
416
test: isJsxSource,
@@ -24,17 +36,19 @@ module.exports = (api, { platform } = {}) => {
2436
plugins: [
2537
// transform pug to jsx. This generates a bunch of new AST nodes
2638
// (it's important to do this first before any dead code elimination runs)
27-
[require('@cssxjs/babel-plugin-react-pug'), {
39+
transformPug && [require('@cssxjs/babel-plugin-react-pug'), {
2840
classAttribute: 'styleName'
2941
}],
3042
// inline CSS modules (styl`` in the same JSX file -- similar to how it is in Vue.js)
31-
[require('@cssxjs/babel-plugin-rn-stylename-inline'), {
43+
transformCss && [require('@cssxjs/babel-plugin-rn-stylename-inline'), {
3244
platform
3345
}],
3446
// CSS modules (separate .styl/.css file)
35-
[require('@cssxjs/babel-plugin-rn-stylename-to-style'), {
47+
transformCss && [require('@cssxjs/babel-plugin-rn-stylename-to-style'), {
3648
extensions: ['styl', 'css'],
37-
useImport: true
49+
useImport: true,
50+
reactType,
51+
cache
3852
}]
3953
].filter(Boolean)
4054
}]

packages/runtime/dimensions.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import { observable } from '@nx-js/observer-util'
22

3+
let dimensionsInitialized = false
4+
5+
export function setDimensionsInitialized (value) {
6+
dimensionsInitialized = value
7+
}
8+
9+
export function getDimensionsInitialized () {
10+
return dimensionsInitialized
11+
}
12+
313
export default observable({
414
width: 0
515
})

packages/runtime/entrypoints/react-native-teamplay.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { setPlatformHelpers } from '../platformHelpers/index.js'
33
import { process } from '../processCached.js'
44

55
setPlatformHelpers(platformHelpers)
6+
platformHelpers.initDimensionsUpdater()
67

78
export default process

packages/runtime/entrypoints/react-native.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { setPlatformHelpers } from '../platformHelpers/index.js'
33
import { process } from '../process.js'
44

55
setPlatformHelpers(platformHelpers)
6+
platformHelpers.initDimensionsUpdater()
67

78
export default process

packages/runtime/entrypoints/web-teamplay.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import * as platformHelpers from '../platformHelpers/web.js'
33
import { process } from '../processCached.js'
44

55
setPlatformHelpers(platformHelpers)
6+
platformHelpers.initDimensionsUpdater()
67

78
export default process

packages/runtime/entrypoints/web.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import * as platformHelpers from '../platformHelpers/web.js'
33
import { process } from '../process.js'
44

55
setPlatformHelpers(platformHelpers)
6+
platformHelpers.initDimensionsUpdater()
67

78
export default process

0 commit comments

Comments
 (0)