@tamagui/static 1.0.0-alpha.3 → 1.0.0-alpha.7

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.3",
3
+ "version": "1.0.0-alpha.7",
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
  ],
@@ -52,10 +53,10 @@
52
53
  "@dish/babel-preset": "^0.0.6",
53
54
  "@expo/match-media": "^0.1.0",
54
55
  "@tamagui/build": "^1.0.0-alpha.2",
55
- "@tamagui/core": "^1.0.0-alpha.2",
56
- "@tamagui/core-node": "^1.0.0-alpha.2",
56
+ "@tamagui/core": "^1.0.0-alpha.7",
57
+ "@tamagui/core-node": "^1.0.0-alpha.5",
57
58
  "@tamagui/fake-react-native": "^1.0.0-alpha.2",
58
- "@tamagui/helpers": "^1.0.0-alpha.2",
59
+ "@tamagui/helpers": "^1.0.0-alpha.5",
59
60
  "babel-literal-to-ast": "^2.1.0",
60
61
  "esbuild": "^0.13.12",
61
62
  "esbuild-register": "^3.1.2",
@@ -63,10 +64,10 @@
63
64
  "fs-extra": "^9.0.0",
64
65
  "invariant": "^2.2.4",
65
66
  "lodash": "^4.17.20",
66
- "tamagui": "^1.0.0-alpha.3"
67
+ "tamagui": "^1.0.0-alpha.7"
67
68
  },
68
69
  "peerDependencies": {
69
70
  "react-native-web": "*"
70
71
  },
71
- "gitHead": "79c58dff688caa316a82d9ee0c684bc50d5fbe4f"
72
+ "gitHead": "13694a98d31535846699004532630788177537e9"
72
73
  }
@@ -51,6 +51,7 @@ export function createExtractor() {
51
51
  })
52
52
 
53
53
  let loadedTamaguiConfig: TamaguiInternalConfig
54
+ let hasLogged = false
54
55
 
55
56
  return {
56
57
  getTamaguiConfig() {
@@ -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,
@@ -541,7 +576,12 @@ export function createExtractor() {
541
576
  }
542
577
 
543
578
  // shorthand media queries
544
- if (name[0] === '$' && t.isJSXExpressionContainer(attribute?.value)) {
579
+ if (
580
+ name[0] === '$' &&
581
+ t.isJSXExpressionContainer(attribute?.value) &&
582
+ // allow disabling this extraction
583
+ !disableExtractInlineMedia
584
+ ) {
545
585
  const shortname = name.slice(1)
546
586
  if (mediaQueryConfig[shortname]) {
547
587
  const expression = attribute.value.expression
@@ -775,12 +815,6 @@ export function createExtractor() {
775
815
  modifiedComponents.add(parentFn)
776
816
  }
777
817
 
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
818
  // combine ternaries
785
819
  let ternaries: Ternary[] = []
786
820
  attrs = attrs
@@ -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[] = []
@@ -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
 
@@ -32,7 +34,10 @@ export type ExtractedAttrAttr = {
32
34
 
33
35
  export type ExtractedAttrStyle = { type: 'style'; value: Object }
34
36
 
35
- export type ExtractedAttr = ExtractedAttrAttr | { type: 'ternary'; value: Ternary } | ExtractedAttrStyle
37
+ export type ExtractedAttr =
38
+ | ExtractedAttrAttr
39
+ | { type: 'ternary'; value: Ternary }
40
+ | ExtractedAttrStyle
36
41
 
37
42
  export type ExtractTagProps = {
38
43
  attrs: ExtractedAttr[]
@@ -51,7 +56,6 @@ export type ExtractorParseProps = TamaguiOptions & {
51
56
  shouldPrintDebug?: boolean
52
57
  onExtractTag: (props: ExtractTagProps) => void
53
58
  getFlattenedNode: (props: { isTextView: boolean; tag: string }) => string
54
- onDidFlatten?: () => void
55
59
  }
56
60
 
57
61
  export interface Ternary {
package/types.d.ts ADDED
@@ -0,0 +1,217 @@
1
+ // Generated by dts-bundle-generator v5.9.0
2
+
3
+ /// <reference types="babel__traverse" />
4
+ /// <reference types="node" />
5
+
6
+ import * as t from '@babel/types';
7
+
8
+ export interface TamaguiOptions {
9
+ components: string[];
10
+ config?: string;
11
+ evaluateVars?: boolean;
12
+ importsWhitelist?: string[];
13
+ disableExtraction?: boolean;
14
+ disableDebugAttr?: boolean;
15
+ disableExtractInlineMedia?: boolean;
16
+ exclude?: RegExp;
17
+ logTimings?: boolean;
18
+ cssPath?: string;
19
+ cssData?: any;
20
+ deoptProps?: Set<string>;
21
+ excludeProps?: string[];
22
+ }
23
+ export declare type ExtractedAttrAttr = {
24
+ type: "attr";
25
+ value: t.JSXAttribute | t.JSXSpreadAttribute;
26
+ };
27
+ export declare type ExtractedAttrStyle = {
28
+ type: "style";
29
+ value: Object;
30
+ };
31
+ export declare type ExtractedAttr = ExtractedAttrAttr | {
32
+ type: "ternary";
33
+ value: Ternary;
34
+ } | ExtractedAttrStyle;
35
+ export declare type ExtractTagProps = {
36
+ attrs: ExtractedAttr[];
37
+ node: t.JSXOpeningElement;
38
+ attemptEval: (exprNode: t.Node, evalFn?: ((node: t.Node) => any) | undefined) => any;
39
+ jsxPath: NodePath<t.JSXElement>;
40
+ programPath: NodePath<t.Program>;
41
+ originalNodeName: string;
42
+ lineNumbers: string;
43
+ filePath: string;
44
+ isFlattened: boolean;
45
+ };
46
+ export declare type ExtractorParseProps = TamaguiOptions & {
47
+ sourcePath?: string;
48
+ shouldPrintDebug?: boolean;
49
+ onExtractTag: (props: ExtractTagProps) => void;
50
+ getFlattenedNode: (props: {
51
+ isTextView: boolean;
52
+ tag: string;
53
+ }) => string;
54
+ };
55
+ export interface Ternary {
56
+ test: t.Expression;
57
+ inlineMediaQuery?: string;
58
+ remove: Function;
59
+ consequent: Object | null;
60
+ alternate: Object | null;
61
+ }
62
+ declare class Variable {
63
+ name: string;
64
+ val: string | number;
65
+ variable: string | number;
66
+ constructor({ val, name }: VariableIn);
67
+ toString(): string | number;
68
+ }
69
+ export declare type VariableIn = {
70
+ val: string | number;
71
+ name: string;
72
+ };
73
+ export declare type ThemeProviderProps = {
74
+ themes: any;
75
+ defaultTheme: string;
76
+ disableRootThemeClass?: boolean;
77
+ children?: any;
78
+ };
79
+ export interface CreateTokens<Val extends number | string | Variable = number | string | Variable> {
80
+ font: {
81
+ [key: string]: GenericFont;
82
+ };
83
+ color: {
84
+ [key: string]: Val;
85
+ };
86
+ space: {
87
+ [key: string]: Val;
88
+ };
89
+ size: {
90
+ [key: string]: Val;
91
+ };
92
+ radius: {
93
+ [key: string]: Val;
94
+ };
95
+ zIndex: {
96
+ [key: string]: Val;
97
+ };
98
+ }
99
+ export declare type GenericTokens = CreateTokens;
100
+ export declare type GenericThemes = {
101
+ [key: string]: {
102
+ bg: string | Variable;
103
+ bg2: string | Variable;
104
+ bg3: string | Variable;
105
+ bg4: string | Variable;
106
+ color: string | Variable;
107
+ color2: string | Variable;
108
+ color3: string | Variable;
109
+ color4: string | Variable;
110
+ borderColor: string | Variable;
111
+ borderColor2: string | Variable;
112
+ shadowColor: string | Variable;
113
+ shadowColor2: string | Variable;
114
+ };
115
+ };
116
+ export declare type GenericShorthands = {};
117
+ export declare type GenericMedia<K extends string = string> = {
118
+ [key in K]: {
119
+ [key: string]: number | string;
120
+ };
121
+ };
122
+ export declare type CreateTamaguiConfig<A extends GenericTokens, B extends GenericThemes, C extends GenericShorthands, D extends GenericMedia> = Partial<Pick<ThemeProviderProps, "defaultTheme" | "disableRootThemeClass">> & {
123
+ tokens: A;
124
+ themes: B;
125
+ shorthands: C;
126
+ media: D;
127
+ };
128
+ export declare type TamaguiInternalConfig<A extends GenericTokens = GenericTokens, B extends GenericThemes = GenericThemes, C extends GenericShorthands = GenericShorthands, D extends GenericMedia = GenericMedia> = CreateTamaguiConfig<A, B, C, D> & {
129
+ Provider: (props: TamaguiProviderProps) => any;
130
+ themeParsed: {
131
+ [key: string]: Variable;
132
+ };
133
+ tokensParsed: CreateTokens<Variable>;
134
+ themeConfig: any;
135
+ getCSS: () => string;
136
+ parsed: boolean;
137
+ };
138
+ export declare type GenericFont = {
139
+ size: {
140
+ [key: string | number]: number | Variable;
141
+ };
142
+ lineHeight: {
143
+ [key: string | number]: number | Variable;
144
+ };
145
+ letterSpacing: {
146
+ [key: string | number]: number | Variable;
147
+ };
148
+ weight: {
149
+ [key: string | number]: string | Variable;
150
+ };
151
+ family: string | Variable;
152
+ };
153
+ export declare type TamaguiProviderProps = Partial<Omit<ThemeProviderProps, "children">> & {
154
+ initialWindowMetrics?: any;
155
+ fallback?: any;
156
+ children?: any;
157
+ };
158
+ export declare type Extractor = ReturnType<typeof createExtractor>;
159
+ export declare function createExtractor(): {
160
+ getTamaguiConfig(): TamaguiInternalConfig<import("@tamagui/core").CreateTokens<string | number | import("@tamagui/core").Variable>, {
161
+ [key: string]: {
162
+ bg: string | import("@tamagui/core").Variable;
163
+ bg2: string | import("@tamagui/core").Variable;
164
+ bg3: string | import("@tamagui/core").Variable;
165
+ bg4: string | import("@tamagui/core").Variable;
166
+ color: string | import("@tamagui/core").Variable;
167
+ color2: string | import("@tamagui/core").Variable;
168
+ color3: string | import("@tamagui/core").Variable;
169
+ color4: string | import("@tamagui/core").Variable;
170
+ borderColor: string | import("@tamagui/core").Variable;
171
+ borderColor2: string | import("@tamagui/core").Variable;
172
+ shadowColor: string | import("@tamagui/core").Variable;
173
+ shadowColor2: string | import("@tamagui/core").Variable;
174
+ };
175
+ }, {}, {
176
+ [x: string]: {
177
+ [key: string]: string | number;
178
+ };
179
+ }>;
180
+ parse: (fileOrPath: NodePath<t.Program> | t.File, { config, importsWhitelist, evaluateVars, shouldPrintDebug, sourcePath, onExtractTag, getFlattenedNode, disableExtraction, disableExtractInlineMedia, disableDebugAttr, ...props }: ExtractorParseProps) => {
181
+ flattened: number;
182
+ optimized: number;
183
+ modified: number;
184
+ } | null;
185
+ };
186
+ export declare function literalToAst(literal: any): t.Expression;
187
+ export declare const CSS_FILE_NAME = "__snack.css";
188
+ export declare const MEDIA_SEP = "_";
189
+ export declare const cacheDir: any;
190
+ export declare const CONCAT_CLASSNAME_IMPORT = "concatClassName";
191
+ export declare function extractToClassNames({ loader, extractor, source, sourcePath, options, shouldPrintDebug, threaded, cssPath, }: {
192
+ loader: any;
193
+ extractor: Extractor;
194
+ source: string | Buffer;
195
+ sourcePath: string;
196
+ options: TamaguiOptions;
197
+ shouldPrintDebug: boolean;
198
+ cssPath: string;
199
+ threaded?: boolean;
200
+ }): null | {
201
+ js: string | Buffer;
202
+ styles: string;
203
+ stylesPath?: string;
204
+ ast: t.File;
205
+ map: any;
206
+ };
207
+ export declare function isPresent<T extends Object>(input: null | void | undefined | T): input is T;
208
+ export declare function isSimpleSpread(node: t.JSXSpreadAttribute): boolean;
209
+ export declare const attrStr: (attr: ExtractedAttr) => string | t.JSXIdentifier;
210
+ export declare const objToStr: (obj: any) => any;
211
+ export declare const ternaryStr: (x: Ternary) => string;
212
+ export declare function findComponentName(scope: any): string | undefined;
213
+ export declare function isValidThemeHook(jsxPath: NodePath<t.JSXElement>, n: t.MemberExpression, sourcePath: string): boolean;
214
+ export declare const isInsideTamagui: (srcName: string) => boolean;
215
+ export declare function patchReactNativeWeb(): void;
216
+
217
+ export {};