@tamagui/static 1.0.0-alpha.4 → 1.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,8 +4,24 @@ import * as fs from "fs";
4
4
  import path from "path";
5
5
  function patchReactNativeWeb() {
6
6
  const rootDir = require.resolve("react-native-web").replace(/\/dist.*/, "");
7
- fs.writeFileSync(path.join(rootDir, "dist", "tamagui-exports.js"), moduleExports);
8
- fs.writeFileSync(path.join(rootDir, "dist", "cjs", "tamagui-exports.js"), cjsExports);
7
+ const modulePath = path.join(rootDir, "dist", "tamagui-exports.js");
8
+ const cjsPath = path.join(rootDir, "dist", "cjs", "tamagui-exports.js");
9
+ const isEqual = (() => {
10
+ let res = false;
11
+ try {
12
+ res = fs.readFileSync(modulePath, "utf-8") === moduleExports && fs.readFileSync(cjsPath, "utf-8") == cjsExports;
13
+ } catch {
14
+ res = false;
15
+ }
16
+ return res;
17
+ })();
18
+ if (!isEqual) {
19
+ console.log("\u{1F95A} Tamagui patching react-native-web to share atomic styling primitives");
20
+ console.log(" > adding", modulePath);
21
+ console.log(" > adding", cjsPath);
22
+ fs.writeFileSync(modulePath, moduleExports);
23
+ fs.writeFileSync(cjsPath, cjsExports);
24
+ }
9
25
  const moduleEntry = path.join(rootDir, "dist", "index.js");
10
26
  const moduleEntrySrc = fs.readFileSync(moduleEntry, "utf-8");
11
27
  if (!moduleEntrySrc.includes("// tamagui-patch-v4")) {
@@ -26,7 +42,6 @@ export const TamaguiExports = TExports
26
42
  exports.TamaguiExports = _interopRequireDefault(require("./tamagui-exports"));
27
43
  // tamagui-patch-end
28
44
  `);
29
- console.log(`Tamagui patched react-native-web`);
30
45
  }
31
46
  }
32
47
  __name(patchReactNativeWeb, "patchReactNativeWeb");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/patchReactNativeWeb.ts"],
4
- "sourcesContent": ["import * as fs from 'fs'\nimport path from 'path'\n\n// were patching react-native-web so we can use some internal methods\n// we do it this way because we need to rely on webpack or bundler config to determine cjs vs esm\n// so we can't just require it all directly\n// would be nice in the future to be able to eject from react-native-web entirely optionally\n\n// keep it sync\nexport function patchReactNativeWeb() {\n const rootDir = require.resolve('react-native-web').replace(/\\/dist.*/, '')\n\n // write our export files\n fs.writeFileSync(path.join(rootDir, 'dist', 'tamagui-exports.js'), moduleExports)\n fs.writeFileSync(path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js'), cjsExports)\n\n // if entry files not patched, patch them:\n const moduleEntry = path.join(rootDir, 'dist', 'index.js')\n const moduleEntrySrc = fs.readFileSync(moduleEntry, 'utf-8')\n if (!moduleEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n moduleEntry,\n `${removePatch(moduleEntrySrc)}\n\n// tamagui-patch-v4\nimport * as TExports from './tamagui-exports'\nexport const TamaguiExports = TExports\n// tamagui-patch-end\n`\n )\n }\n const cjsEntry = path.join(rootDir, 'dist', 'cjs', 'index.js')\n const cjsEntrySrc = fs.readFileSync(cjsEntry, 'utf-8')\n if (!cjsEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n cjsEntry,\n `${removePatch(cjsEntrySrc)}\n\n// tamagui-patch-v4\nexports.TamaguiExports = _interopRequireDefault(require(\"./tamagui-exports\"));\n// tamagui-patch-end\n`\n )\n\n console.log(`Tamagui patched react-native-web`)\n }\n}\n\nfunction removePatch(source: string) {\n return source.replace(/\\/\\/ tamagui-patch([.\\s\\S]*)/g, '')\n}\n\n// view exports/View.ts\nconst forwardedPropsObj = `{\n ...fwdProps.defaultProps,\n ...fwdProps.accessibilityProps,\n ...fwdProps.clickProps,\n ...fwdProps.focusProps,\n ...fwdProps.keyboardProps,\n ...fwdProps.mouseProps,\n ...fwdProps.touchProps,\n ...fwdProps.styleProps,\n href: true,\n lang: true,\n onScroll: true,\n onWheel: true,\n pointerEvents: true\n}\n`\n\nconst moduleExports = `\nexport { atomic } from './exports/StyleSheet/compile'\nexport { default as createCompileableStyle } from './exports/StyleSheet/createCompileableStyle'\nexport { default as createReactDOMStyle } from './exports/StyleSheet/createReactDOMStyle'\nexport { default as i18Style } from './exports/StyleSheet/i18nStyle'\nexport { default as createDOMProps } from './modules/createDOMProps'\nexport { default as AccessibilityUtil } from './modules/AccessibilityUtil'\nexport { default as createElement } from './exports/createElement'\nexport { default as css } from './exports/StyleSheet/css'\nexport { default as TextAncestorContext } from './exports/Text/TextAncestorContext'\nexport { default as pick } from './modules/pick'\nexport { default as useElementLayout } from './modules/useElementLayout'\nexport { default as useMergeRefs } from './modules/useMergeRefs'\nexport { default as usePlatformMethods } from './modules/usePlatformMethods'\nexport { default as useResponderEvents } from './modules/useResponderEvents'\nimport * as fwdProps from './modules/forwardedProps'\nexport const forwardedProps = ${forwardedPropsObj}\n`\n\nconst cjsExports = `\nexports.atomic = require('./exports/StyleSheet/compile').atomic\nexports.createCompileableStyle = require('./exports/StyleSheet/createCompileableStyle')\nexports.createReactDOMStyle = require('./exports/StyleSheet/createReactDOMStyle')\nexports.i18Style = require('./exports/StyleSheet/i18nStyle')\nexports.createDOMProps = require('./modules/createDOMProps')\nexports.AccessibilityUtil = require('./modules/AccessibilityUtil')\nexports.createElement = require('./exports/createElement')\nexports.css = require('./exports/StyleSheet/css')\nexports.TextAncestorContext = require('./exports/Text/TextAncestorContext')\nexports.pick = require('./modules/pick')\nexports.useElementLayout = require('./modules/useElementLayout')\nexports.useMergeRefs = require('./modules/useMergeRefs')\nexports.usePlatformMethods = require('./modules/usePlatformMethods')\nexports.useResponderEvents = require('./modules/useResponderEvents')\nconst fwdProps = require('./modules/forwardedProps')\nexports.forwardedProps = ${forwardedPropsObj}\n`\n"],
5
- "mappings": ";;AAAA;AACA;AAQO,+BAA+B;AACpC,QAAM,UAAU,AAAgB,oCAAoB,QAAQ,YAAY;AAGxE,KAAG,cAAc,KAAK,KAAK,SAAS,QAAQ,uBAAuB;AACnE,KAAG,cAAc,KAAK,KAAK,SAAS,QAAQ,OAAO,uBAAuB;AAG1E,QAAM,cAAc,KAAK,KAAK,SAAS,QAAQ;AAC/C,QAAM,iBAAiB,GAAG,aAAa,aAAa;AACpD,MAAI,CAAC,eAAe,SAAS,wBAAwB;AACnD,OAAG,cACD,aACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASnB,QAAM,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO;AACnD,QAAM,cAAc,GAAG,aAAa,UAAU;AAC9C,MAAI,CAAC,YAAY,SAAS,wBAAwB;AAChD,OAAG,cACD,UACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAQjB,YAAQ,IAAI;AAAA;AAAA;AAnCA;AAuChB,qBAAqB,QAAgB;AACnC,SAAO,OAAO,QAAQ,iCAAiC;AAAA;AADhD;AAKT,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB1B,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAgBU;AAAA;AAGhC,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAgBQ;AAAA;",
4
+ "sourcesContent": ["import * as fs from 'fs'\nimport path from 'path'\n\n// were patching react-native-web so we can use some internal methods\n// we do it this way because we need to rely on webpack or bundler config to determine cjs vs esm\n// so we can't just require it all directly\n// would be nice in the future to be able to eject from react-native-web entirely optionally\n\n// keep it sync\nexport function patchReactNativeWeb() {\n const rootDir = require.resolve('react-native-web').replace(/\\/dist.*/, '')\n const modulePath = path.join(rootDir, 'dist', 'tamagui-exports.js')\n const cjsPath = path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js')\n\n const isEqual = (() => {\n let res = false\n try {\n res =\n fs.readFileSync(modulePath, 'utf-8') === moduleExports &&\n fs.readFileSync(cjsPath, 'utf-8') == cjsExports\n } catch {\n res = false\n }\n return res\n })()\n\n if (!isEqual) {\n console.log('\uD83E\uDD5A Tamagui patching react-native-web to share atomic styling primitives')\n console.log(' > adding', modulePath)\n console.log(' > adding', cjsPath)\n fs.writeFileSync(modulePath, moduleExports)\n fs.writeFileSync(cjsPath, cjsExports)\n }\n\n // if entry files not patched, patch them:\n const moduleEntry = path.join(rootDir, 'dist', 'index.js')\n const moduleEntrySrc = fs.readFileSync(moduleEntry, 'utf-8')\n if (!moduleEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n moduleEntry,\n `${removePatch(moduleEntrySrc)}\n\n// tamagui-patch-v4\nimport * as TExports from './tamagui-exports'\nexport const TamaguiExports = TExports\n// tamagui-patch-end\n`\n )\n }\n const cjsEntry = path.join(rootDir, 'dist', 'cjs', 'index.js')\n const cjsEntrySrc = fs.readFileSync(cjsEntry, 'utf-8')\n if (!cjsEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n cjsEntry,\n `${removePatch(cjsEntrySrc)}\n\n// tamagui-patch-v4\nexports.TamaguiExports = _interopRequireDefault(require(\"./tamagui-exports\"));\n// tamagui-patch-end\n`\n )\n }\n}\n\nfunction removePatch(source: string) {\n return source.replace(/\\/\\/ tamagui-patch([.\\s\\S]*)/g, '')\n}\n\n// view exports/View.ts\nconst forwardedPropsObj = `{\n ...fwdProps.defaultProps,\n ...fwdProps.accessibilityProps,\n ...fwdProps.clickProps,\n ...fwdProps.focusProps,\n ...fwdProps.keyboardProps,\n ...fwdProps.mouseProps,\n ...fwdProps.touchProps,\n ...fwdProps.styleProps,\n href: true,\n lang: true,\n onScroll: true,\n onWheel: true,\n pointerEvents: true\n}\n`\n\nconst moduleExports = `\nexport { atomic } from './exports/StyleSheet/compile'\nexport { default as createCompileableStyle } from './exports/StyleSheet/createCompileableStyle'\nexport { default as createReactDOMStyle } from './exports/StyleSheet/createReactDOMStyle'\nexport { default as i18Style } from './exports/StyleSheet/i18nStyle'\nexport { default as createDOMProps } from './modules/createDOMProps'\nexport { default as AccessibilityUtil } from './modules/AccessibilityUtil'\nexport { default as createElement } from './exports/createElement'\nexport { default as css } from './exports/StyleSheet/css'\nexport { default as TextAncestorContext } from './exports/Text/TextAncestorContext'\nexport { default as pick } from './modules/pick'\nexport { default as useElementLayout } from './modules/useElementLayout'\nexport { default as useMergeRefs } from './modules/useMergeRefs'\nexport { default as usePlatformMethods } from './modules/usePlatformMethods'\nexport { default as useResponderEvents } from './modules/useResponderEvents'\nimport * as fwdProps from './modules/forwardedProps'\nexport const forwardedProps = ${forwardedPropsObj}\n`\n\nconst cjsExports = `\nexports.atomic = require('./exports/StyleSheet/compile').atomic\nexports.createCompileableStyle = require('./exports/StyleSheet/createCompileableStyle')\nexports.createReactDOMStyle = require('./exports/StyleSheet/createReactDOMStyle')\nexports.i18Style = require('./exports/StyleSheet/i18nStyle')\nexports.createDOMProps = require('./modules/createDOMProps')\nexports.AccessibilityUtil = require('./modules/AccessibilityUtil')\nexports.createElement = require('./exports/createElement')\nexports.css = require('./exports/StyleSheet/css')\nexports.TextAncestorContext = require('./exports/Text/TextAncestorContext')\nexports.pick = require('./modules/pick')\nexports.useElementLayout = require('./modules/useElementLayout')\nexports.useMergeRefs = require('./modules/useMergeRefs')\nexports.usePlatformMethods = require('./modules/usePlatformMethods')\nexports.useResponderEvents = require('./modules/useResponderEvents')\nconst fwdProps = require('./modules/forwardedProps')\nexports.forwardedProps = ${forwardedPropsObj}\n`\n"],
5
+ "mappings": ";;AAAA;AACA;AAQO,+BAA+B;AACpC,QAAM,UAAU,AAAgB,oCAAoB,QAAQ,YAAY;AACxE,QAAM,aAAa,KAAK,KAAK,SAAS,QAAQ;AAC9C,QAAM,UAAU,KAAK,KAAK,SAAS,QAAQ,OAAO;AAElD,QAAM,UAAW,OAAM;AACrB,QAAI,MAAM;AACV,QAAI;AACF,YACE,GAAG,aAAa,YAAY,aAAa,iBACzC,GAAG,aAAa,SAAS,YAAY;AAAA,YACvC;AACA,YAAM;AAAA;AAER,WAAO;AAAA;AAGT,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI;AACZ,YAAQ,IAAI,eAAe;AAC3B,YAAQ,IAAI,eAAe;AAC3B,OAAG,cAAc,YAAY;AAC7B,OAAG,cAAc,SAAS;AAAA;AAI5B,QAAM,cAAc,KAAK,KAAK,SAAS,QAAQ;AAC/C,QAAM,iBAAiB,GAAG,aAAa,aAAa;AACpD,MAAI,CAAC,eAAe,SAAS,wBAAwB;AACnD,OAAG,cACD,aACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASnB,QAAM,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO;AACnD,QAAM,cAAc,GAAG,aAAa,UAAU;AAC9C,MAAI,CAAC,YAAY,SAAS,wBAAwB;AAChD,OAAG,cACD,UACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA7CL;AAuDhB,qBAAqB,QAAgB;AACnC,SAAO,OAAO,QAAQ,iCAAiC;AAAA;AADhD;AAKT,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB1B,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAgBU;AAAA;AAGhC,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAgBQ;AAAA;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@tamagui/static",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.8",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
7
7
  "typings": "types.d.ts",
8
8
  "files": [
9
+ "types.d.ts",
9
10
  "dist",
10
11
  "src"
11
12
  ],
@@ -34,6 +35,7 @@
34
35
  "@types/webpack": "^4.41.26",
35
36
  "babel-loader": "^8.2.2",
36
37
  "css-loader": "^5.2.4",
38
+ "esbuild-loader": "^2.16.0",
37
39
  "jest": "^27.3.1",
38
40
  "loader-utils": "^2.0.0",
39
41
  "react": "*",
@@ -51,11 +53,11 @@
51
53
  "@babel/traverse": "^7.15.4",
52
54
  "@dish/babel-preset": "^0.0.6",
53
55
  "@expo/match-media": "^0.1.0",
54
- "@tamagui/build": "^1.0.0-alpha.2",
55
- "@tamagui/core": "^1.0.0-alpha.4",
56
- "@tamagui/core-node": "^1.0.0-alpha.2",
56
+ "@tamagui/build": "^1.0.0-alpha.8",
57
+ "@tamagui/core": "^1.0.0-alpha.8",
58
+ "@tamagui/core-node": "^1.0.0-alpha.8",
57
59
  "@tamagui/fake-react-native": "^1.0.0-alpha.2",
58
- "@tamagui/helpers": "^1.0.0-alpha.2",
60
+ "@tamagui/helpers": "^1.0.0-alpha.8",
59
61
  "babel-literal-to-ast": "^2.1.0",
60
62
  "esbuild": "^0.13.12",
61
63
  "esbuild-register": "^3.1.2",
@@ -63,10 +65,10 @@
63
65
  "fs-extra": "^9.0.0",
64
66
  "invariant": "^2.2.4",
65
67
  "lodash": "^4.17.20",
66
- "tamagui": "^1.0.0-alpha.4"
68
+ "tamagui": "^1.0.0-alpha.8"
67
69
  },
68
70
  "peerDependencies": {
69
71
  "react-native-web": "*"
70
72
  },
71
- "gitHead": "3e3b5401f9daea70cf9a99782d325f58357ca681"
73
+ "gitHead": "ecb0afe6782276b1f2ece90320fd2748f2f05c93"
72
74
  }
@@ -51,9 +51,10 @@ export function createExtractor() {
51
51
  })
52
52
 
53
53
  let loadedTamaguiConfig: TamaguiInternalConfig
54
+ let hasLogged = false
54
55
 
55
56
  return {
56
- getTamaguiConfig() {
57
+ getTamagui() {
57
58
  return loadedTamaguiConfig
58
59
  },
59
60
  parse: (
@@ -66,7 +67,9 @@ export function createExtractor() {
66
67
  sourcePath = '',
67
68
  onExtractTag,
68
69
  getFlattenedNode,
69
- onDidFlatten,
70
+ disableExtraction,
71
+ disableExtractInlineMedia,
72
+ disableDebugAttr,
70
73
  ...props
71
74
  }: ExtractorParseProps
72
75
  ) => {
@@ -87,12 +90,6 @@ export function createExtractor() {
87
90
  loadedTamaguiConfig = tamaguiConfig
88
91
 
89
92
  const defaultTheme = tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]]
90
-
91
- // TODO this can be passed in / set based on if source changed
92
- // const shouldReCheckTheme = false //Date.now() - hasParsedFileLast > 600
93
- // hasParsedFileLast = Date.now()
94
-
95
- let doesUseValidImport = false
96
93
  const body = fileOrPath.type === 'Program' ? fileOrPath.get('body') : fileOrPath.program.body
97
94
 
98
95
  /**
@@ -102,12 +99,15 @@ export function createExtractor() {
102
99
  isInsideTamagui(sourcePath) && importStr[0] === '.'
103
100
 
104
101
  const validComponents: { [key: string]: any } = Object.keys(components)
105
- .filter((key) => !!components[key]?.staticConfig)
102
+ // check if uppercase to avoid hitting media query proxy before init
103
+ .filter((key) => key[0].toUpperCase() === key[0] && !!components[key]?.staticConfig)
106
104
  .reduce((obj, name) => {
107
105
  obj[name] = components[name]
108
106
  return obj
109
107
  }, {})
110
108
 
109
+ let doesUseValidImport = false
110
+
111
111
  for (const bodyPath of body) {
112
112
  if (bodyPath.type !== 'ImportDeclaration') continue
113
113
  const node = ('node' in bodyPath ? bodyPath.node : bodyPath) as any
@@ -148,6 +148,12 @@ export function createExtractor() {
148
148
  */
149
149
  let programPath: NodePath<t.Program>
150
150
 
151
+ const res = {
152
+ flattened: 0,
153
+ optimized: 0,
154
+ modified: 0,
155
+ }
156
+
151
157
  callTraverse({
152
158
  Program: {
153
159
  enter(path) {
@@ -186,8 +192,41 @@ export function createExtractor() {
186
192
  return
187
193
  }
188
194
 
189
- const { staticConfig } = component
190
195
  const originalNodeName = node.name.name
196
+
197
+ if (shouldPrintDebug) {
198
+ console.log(`\n<${originalNodeName} />`)
199
+ }
200
+
201
+ const filePath = sourcePath.replace(process.cwd(), '.')
202
+ const lineNumbers = node.loc
203
+ ? node.loc.start.line +
204
+ (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : '')
205
+ : ''
206
+
207
+ // add data-is
208
+ if (shouldAddDebugProp && !disableDebugAttr) {
209
+ const preName = componentName ? `${componentName}:` : ''
210
+ res.modified++
211
+ node.attributes.unshift(
212
+ t.jsxAttribute(
213
+ t.jsxIdentifier('data-is'),
214
+ t.stringLiteral(
215
+ ` ${preName}${node.name.name} ${filePath.replace('./', '')}:${lineNumbers} `
216
+ )
217
+ )
218
+ )
219
+ }
220
+
221
+ if (disableExtraction) {
222
+ if (!hasLogged) {
223
+ console.log('🥚 Tamagui disableExtraction set: no CSS or optimizations will be run')
224
+ hasLogged = true
225
+ }
226
+ return
227
+ }
228
+
229
+ const { staticConfig } = component
191
230
  const isTextView = staticConfig.isText || false
192
231
  const validStyles = staticConfig?.validStyles ?? {}
193
232
 
@@ -224,10 +263,6 @@ export function createExtractor() {
224
263
  return res
225
264
  }
226
265
 
227
- if (shouldPrintDebug) {
228
- console.log(`\n<${originalNodeName} />`)
229
- }
230
-
231
266
  // Generate scope object at this level
232
267
  const staticNamespace = getStaticBindingsForScope(
233
268
  traversePath.scope,
@@ -542,6 +577,11 @@ export function createExtractor() {
542
577
 
543
578
  // shorthand media queries
544
579
  if (name[0] === '$' && t.isJSXExpressionContainer(attribute?.value)) {
580
+ // allow disabling this extraction
581
+ if (disableExtractInlineMedia) {
582
+ return attr
583
+ }
584
+
545
585
  const shortname = name.slice(1)
546
586
  if (mediaQueryConfig[shortname]) {
547
587
  const expression = attribute.value.expression
@@ -593,8 +633,8 @@ export function createExtractor() {
593
633
  // if value can be evaluated, extract it and filter it out
594
634
  const styleValue = attemptEvalSafe(value)
595
635
 
596
- // we never flatten if a prop isn't a valid static attribute
597
- // but we need to make sure its post-prop mapping
636
+ // never flatten if a prop isn't a valid static attribute
637
+ // only post prop-mapping
598
638
  if (!isStaticAttributeName(name)) {
599
639
  let keys = [name]
600
640
  if (staticConfig.propMapper) {
@@ -624,6 +664,8 @@ export function createExtractor() {
624
664
  return {
625
665
  type: 'style',
626
666
  value: { [name]: styleValue },
667
+ name,
668
+ attr: path.node,
627
669
  }
628
670
  }
629
671
 
@@ -775,12 +817,6 @@ export function createExtractor() {
775
817
  modifiedComponents.add(parentFn)
776
818
  }
777
819
 
778
- const filePath = sourcePath.replace(process.cwd(), '.')
779
- const lineNumbers = node.loc
780
- ? node.loc.start.line +
781
- (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : '')
782
- : ''
783
-
784
820
  // combine ternaries
785
821
  let ternaries: Ternary[] = []
786
822
  attrs = attrs
@@ -870,29 +906,27 @@ export function createExtractor() {
870
906
  if (cur.type === 'style') {
871
907
  // TODO need to loop over initial props not just style props
872
908
  for (const key in cur.value) {
873
- const shouldInsertNull =
874
- !!(
875
- staticConfig.ensureOverriddenProp?.[key] // || staticConfig.defaultProps?.[key]
876
- )
909
+ const shouldEnsureOverridden = !!staticConfig.ensureOverriddenProp?.[key]
877
910
  const isSetInAttrsAlready = attrs.some(
878
911
  (x) =>
879
912
  x.type === 'attr' &&
880
913
  x.value.type === 'JSXAttribute' &&
881
914
  x.value.name.name === key
882
915
  )
883
- const shouldInsertNullOverride = shouldInsertNull && !isSetInAttrsAlready
884
- // if (shouldPrintDebug) {
885
- // // prettier-ignore
886
- // console.log('what is', key, { shouldInsertNullOverride, shouldInsertNull, isSetInAttrsAlready })
887
- // }
888
- if (shouldInsertNullOverride) {
889
- acc.push({
890
- type: 'attr',
891
- value: t.jsxAttribute(
892
- t.jsxIdentifier(key),
893
- t.jsxExpressionContainer(t.nullLiteral())
894
- ),
895
- })
916
+
917
+ if (!isSetInAttrsAlready) {
918
+ const isVariant = !!staticConfig.variants?.[cur.name || '']
919
+ if (isVariant || shouldEnsureOverridden) {
920
+ acc.push({
921
+ type: 'attr',
922
+ value:
923
+ cur.attr ||
924
+ t.jsxAttribute(
925
+ t.jsxIdentifier(key),
926
+ t.jsxExpressionContainer(t.nullLiteral())
927
+ ),
928
+ })
929
+ }
896
930
  }
897
931
  }
898
932
  }
@@ -1051,21 +1085,6 @@ export function createExtractor() {
1051
1085
  console.log(' - attrs (after): ', attrs.map(attrStr).join(', '))
1052
1086
  }
1053
1087
 
1054
- // add data-is
1055
- if (shouldAddDebugProp) {
1056
- const preName = componentName ? `${componentName}:` : ''
1057
- // unshift so spreads/nesting overwrite
1058
- attrs.unshift({
1059
- type: 'attr',
1060
- value: t.jsxAttribute(
1061
- t.jsxIdentifier('data-is'),
1062
- t.stringLiteral(
1063
- ` ${preName}${node.name.name} ${filePath.replace('./', '')}:${lineNumbers} `
1064
- )
1065
- ),
1066
- })
1067
- }
1068
-
1069
1088
  if (shouldFlatten) {
1070
1089
  // DO FLATTEN
1071
1090
  if (shouldPrintDebug) {
@@ -1073,7 +1092,7 @@ export function createExtractor() {
1073
1092
  }
1074
1093
  isFlattened = true
1075
1094
  node.name.name = flatNode
1076
- onDidFlatten?.()
1095
+ res.flattened++
1077
1096
  if (closingElement) {
1078
1097
  closingElement.name.name = flatNode
1079
1098
  }
@@ -1085,6 +1104,8 @@ export function createExtractor() {
1085
1104
  console.log(' - attrs (end): ', attrs.map(attrStr).join(', '))
1086
1105
  }
1087
1106
 
1107
+ res.optimized++
1108
+
1088
1109
  onExtractTag({
1089
1110
  attrs,
1090
1111
  node,
@@ -1111,6 +1132,8 @@ export function createExtractor() {
1111
1132
  removeUnusedHooks(comp, shouldPrintDebug)
1112
1133
  }
1113
1134
  }
1135
+
1136
+ return res
1114
1137
  },
1115
1138
  }
1116
1139
  }
@@ -79,17 +79,11 @@ export function extractToClassNames({
79
79
  const cssMap = new Map<string, { css: string; commentTexts: string[] }>()
80
80
  const existingHoists: { [key: string]: t.Identifier } = {}
81
81
 
82
- let flattened = 0
83
- let optimized = 0
84
-
85
- extractor.parse(ast, {
82
+ const res = extractor.parse(ast, {
86
83
  sourcePath,
87
84
  shouldPrintDebug,
88
85
  ...options,
89
86
  getFlattenedNode: ({ tag }) => tag,
90
- onDidFlatten() {
91
- flattened++
92
- },
93
87
  onExtractTag: ({
94
88
  attrs,
95
89
  node,
@@ -100,8 +94,6 @@ export function extractToClassNames({
100
94
  lineNumbers,
101
95
  programPath,
102
96
  }) => {
103
- optimized++
104
-
105
97
  let finalClassNames: ClassNameObject[] = []
106
98
  let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []
107
99
  let finalStyles: StyleObject[] = []
@@ -190,7 +182,7 @@ export function extractToClassNames({
190
182
  const mediaExtraction = extractMediaStyle(
191
183
  attr.value,
192
184
  jsxPath,
193
- extractor.getTamaguiConfig(),
185
+ extractor.getTamagui(),
194
186
  sourcePath,
195
187
  lastMediaImportance,
196
188
  shouldPrintDebug
@@ -276,15 +268,12 @@ export function extractToClassNames({
276
268
  },
277
269
  })
278
270
 
279
- if (!optimized) {
271
+ if (!res || !res.modified) {
280
272
  return null
281
273
  }
282
274
 
283
275
  const styles = Array.from(cssMap.values())
284
- .map((x) => {
285
- // remove comments
286
- return x.css //shouldInternalDedupe ? x.css : `${x.commentTexts.join('\n')}\n${x.css}`
287
- })
276
+ .map((x) => x.css)
288
277
  .join('\n')
289
278
  .trim()
290
279
 
@@ -325,7 +314,7 @@ export function extractToClassNames({
325
314
  const memUsed =
326
315
  Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10
327
316
  // prettier-ignore
328
- console.log(` 🥚 ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms ׁ· ${`${optimized}`.padStart(4)} optimized · ${flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)
317
+ console.log(` 🥚 ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms ׁ· ${`${res.optimized}`.padStart(4)} optimized · ${res.flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)
329
318
  }
330
319
 
331
320
  return {
@@ -9,10 +9,28 @@ import path from 'path'
9
9
  // keep it sync
10
10
  export function patchReactNativeWeb() {
11
11
  const rootDir = require.resolve('react-native-web').replace(/\/dist.*/, '')
12
+ const modulePath = path.join(rootDir, 'dist', 'tamagui-exports.js')
13
+ const cjsPath = path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js')
12
14
 
13
- // write our export files
14
- fs.writeFileSync(path.join(rootDir, 'dist', 'tamagui-exports.js'), moduleExports)
15
- fs.writeFileSync(path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js'), cjsExports)
15
+ const isEqual = (() => {
16
+ let res = false
17
+ try {
18
+ res =
19
+ fs.readFileSync(modulePath, 'utf-8') === moduleExports &&
20
+ fs.readFileSync(cjsPath, 'utf-8') == cjsExports
21
+ } catch {
22
+ res = false
23
+ }
24
+ return res
25
+ })()
26
+
27
+ if (!isEqual) {
28
+ console.log('🥚 Tamagui patching react-native-web to share atomic styling primitives')
29
+ console.log(' > adding', modulePath)
30
+ console.log(' > adding', cjsPath)
31
+ fs.writeFileSync(modulePath, moduleExports)
32
+ fs.writeFileSync(cjsPath, cjsExports)
33
+ }
16
34
 
17
35
  // if entry files not patched, patch them:
18
36
  const moduleEntry = path.join(rootDir, 'dist', 'index.js')
@@ -41,8 +59,6 @@ exports.TamaguiExports = _interopRequireDefault(require("./tamagui-exports"));
41
59
  // tamagui-patch-end
42
60
  `
43
61
  )
44
-
45
- console.log(`Tamagui patched react-native-web`)
46
62
  }
47
63
  }
48
64
 
package/src/types.ts CHANGED
@@ -15,6 +15,8 @@ export interface TamaguiOptions {
15
15
  evaluateVars?: boolean
16
16
  importsWhitelist?: string[]
17
17
  disableExtraction?: boolean
18
+ disableDebugAttr?: boolean
19
+ disableExtractInlineMedia?: boolean
18
20
  exclude?: RegExp
19
21
  logTimings?: boolean
20
22
 
@@ -30,9 +32,17 @@ export type ExtractedAttrAttr = {
30
32
  value: t.JSXAttribute | t.JSXSpreadAttribute
31
33
  }
32
34
 
33
- export type ExtractedAttrStyle = { type: 'style'; value: Object }
35
+ export type ExtractedAttrStyle = {
36
+ type: 'style'
37
+ value: Object
38
+ attr?: t.JSXAttribute | t.JSXSpreadAttribute
39
+ name?: string
40
+ }
34
41
 
35
- export type ExtractedAttr = ExtractedAttrAttr | { type: 'ternary'; value: Ternary } | ExtractedAttrStyle
42
+ export type ExtractedAttr =
43
+ | ExtractedAttrAttr
44
+ | { type: 'ternary'; value: Ternary }
45
+ | ExtractedAttrStyle
36
46
 
37
47
  export type ExtractTagProps = {
38
48
  attrs: ExtractedAttr[]
@@ -51,7 +61,6 @@ export type ExtractorParseProps = TamaguiOptions & {
51
61
  shouldPrintDebug?: boolean
52
62
  onExtractTag: (props: ExtractTagProps) => void
53
63
  getFlattenedNode: (props: { isTextView: boolean; tag: string }) => string
54
- onDidFlatten?: () => void
55
64
  }
56
65
 
57
66
  export interface Ternary {