@tamagui/static 1.0.1-beta.57 → 1.0.1-beta.61

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.
Files changed (46) hide show
  1. package/dist/cjs/extractor/createExtractor.js +18 -1
  2. package/dist/cjs/extractor/createExtractor.js.map +2 -2
  3. package/dist/cjs/extractor/extractToClassNames.js +1 -1
  4. package/dist/cjs/extractor/extractToClassNames.js.map +2 -2
  5. package/dist/cjs/patchReactNativeWeb.js +1 -1
  6. package/dist/cjs/patchReactNativeWeb.js.map +2 -2
  7. package/dist/esm/extractor/createExtractor.js +18 -1
  8. package/dist/esm/extractor/createExtractor.js.map +2 -2
  9. package/dist/esm/extractor/extractToClassNames.js +1 -1
  10. package/dist/esm/extractor/extractToClassNames.js.map +2 -2
  11. package/dist/esm/patchReactNativeWeb.js +1 -1
  12. package/dist/esm/patchReactNativeWeb.js.map +2 -2
  13. package/dist/jsx/extractor/createExtractor.js +18 -1
  14. package/dist/jsx/extractor/extractToClassNames.js +1 -1
  15. package/dist/jsx/patchReactNativeWeb.js +1 -1
  16. package/package.json +9 -7
  17. package/src/constants.ts +13 -0
  18. package/src/extractor/accessSafe.ts +18 -0
  19. package/src/extractor/babelParse.ts +27 -0
  20. package/src/extractor/buildClassName.ts +61 -0
  21. package/src/extractor/createEvaluator.ts +69 -0
  22. package/src/extractor/createExtractor.ts +1696 -0
  23. package/src/extractor/ensureImportingConcat.ts +39 -0
  24. package/src/extractor/evaluateAstNode.ts +121 -0
  25. package/src/extractor/extractHelpers.ts +119 -0
  26. package/src/extractor/extractMediaStyle.ts +190 -0
  27. package/src/extractor/extractToClassNames.ts +426 -0
  28. package/src/extractor/findTopmostFunction.ts +22 -0
  29. package/src/extractor/generatedUid.ts +43 -0
  30. package/src/extractor/getPrefixLogs.ts +6 -0
  31. package/src/extractor/getPropValueFromAttributes.ts +92 -0
  32. package/src/extractor/getSourceModule.ts +101 -0
  33. package/src/extractor/getStaticBindingsForScope.ts +183 -0
  34. package/src/extractor/hoistClassNames.ts +45 -0
  35. package/src/extractor/literalToAst.ts +84 -0
  36. package/src/extractor/loadTamagui.ts +139 -0
  37. package/src/extractor/logLines.ts +16 -0
  38. package/src/extractor/normalizeTernaries.ts +63 -0
  39. package/src/extractor/removeUnusedHooks.ts +76 -0
  40. package/src/extractor/timer.ts +18 -0
  41. package/src/extractor/validHTMLAttributes.ts +99 -0
  42. package/src/index.ts +9 -0
  43. package/src/patchReactNativeWeb.ts +165 -0
  44. package/src/types.ts +97 -0
  45. package/types/extractor/createExtractor.d.ts +14 -1
  46. package/types/extractor/createExtractor.d.ts.map +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/patchReactNativeWeb.ts"],
4
- "sourcesContent": ["import path from 'path'\n\nimport * as fs from 'fs-extra'\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(dir: string = require.resolve('react-native-web')) {\n const rootDir = dir.replace(/\\/dist.*/, '')\n const modulePath = path.join(rootDir, 'dist', 'tamagui-exports.js')\n const cjsPath = path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js')\n const shouldPatchExports =\n fs.existsSync(modulePath) &&\n fs.readFileSync(modulePath, 'utf-8') === moduleExports &&\n fs.existsSync(cjsPath) &&\n fs.readFileSync(cjsPath, 'utf-8') === cjsExports\n if (!shouldPatchExports) {\n console.log(' | patch ' + path.relative(rootDir, modulePath))\n console.log(' | patch ' + path.relative(rootDir, cjsPath))\n fs.writeFileSync(modulePath, moduleExports)\n fs.writeFileSync(cjsPath, cjsExports)\n }\n\n // patch to allow className prop\n const patches = [\n {\n id: 'dom-props',\n filePath: ['modules', 'createDOMProps', 'index.js'],\n replacee: ` if (dataSet != null) {`,\n replacer: `\n if (props.dataSet && props.dataSet.className) {\n const { className, ...dataSetRest } = props.dataSet\n classList = className\n dataSet = dataSetRest\n }\n if (props.dataSet && props.dataSet.id) {\n domProps['id'] = props.dataSet.id\n }\n if (dataSet != null) {`,\n },\n {\n id: 'forward-props',\n filePath: ['modules', 'forwardedProps', 'index.js'],\n replacee: `dataSet: true,`,\n replacer: `id: true, dataSet: true,`,\n },\n ]\n\n for (const { filePath, replacee, replacer } of patches) {\n const files = [\n path.join(rootDir, 'dist', ...filePath),\n path.join(rootDir, 'dist', 'cjs', ...filePath),\n ]\n for (const file of files) {\n const contents = fs.readFileSync(file, 'utf-8')\n if (contents.includes(replacer)) {\n continue\n }\n if (!contents.includes(replacee)) {\n console.warn(\n `\u26A0\uFE0F Error: couldn't apply className patch! Maybe using incompatible react-native-web version.`,\n {\n replacee,\n contents,\n }\n )\n continue\n }\n console.log(' | patch ' + path.relative(rootDir, file))\n fs.writeFileSync(file, contents.replace(replacee, replacer))\n }\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;AAEA;AAQO,6BAA6B,MAA8B,qCAAqB;AACrF,QAAM,UAAU,IAAI,QAAQ,YAAY,EAAE;AAC1C,QAAM,aAAa,KAAK,KAAK,SAAS,QAAQ,oBAAoB;AAClE,QAAM,UAAU,KAAK,KAAK,SAAS,QAAQ,OAAO,oBAAoB;AACtE,QAAM,qBACJ,GAAG,WAAW,UAAU,KACxB,GAAG,aAAa,YAAY,OAAO,MAAM,iBACzC,GAAG,WAAW,OAAO,KACrB,GAAG,aAAa,SAAS,OAAO,MAAM;AACxC,MAAI,CAAC,oBAAoB;AACvB,YAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,UAAU,CAAC;AACjE,YAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,OAAO,CAAC;AAC9D,OAAG,cAAc,YAAY,aAAa;AAC1C,OAAG,cAAc,SAAS,UAAU;AAAA,EACtC;AAGA,QAAM,UAAU;AAAA,IACd;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,CAAC,WAAW,kBAAkB,UAAU;AAAA,MAClD,UAAU;AAAA,MACV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUZ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,CAAC,WAAW,kBAAkB,UAAU;AAAA,MAClD,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,aAAW,EAAE,UAAU,UAAU,cAAc,SAAS;AACtD,UAAM,QAAQ;AAAA,MACZ,KAAK,KAAK,SAAS,QAAQ,GAAG,QAAQ;AAAA,MACtC,KAAK,KAAK,SAAS,QAAQ,OAAO,GAAG,QAAQ;AAAA,IAC/C;AACA,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,GAAG,aAAa,MAAM,OAAO;AAC9C,UAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B;AAAA,MACF;AACA,UAAI,CAAC,SAAS,SAAS,QAAQ,GAAG;AAChC,gBAAQ,KACN,0GACA;AAAA,UACE;AAAA,UACA;AAAA,QACF,CACF;AACA;AAAA,MACF;AACA,cAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,IAAI,CAAC;AAC3D,SAAG,cAAc,MAAM,SAAS,QAAQ,UAAU,QAAQ,CAAC;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,cAAc,KAAK,KAAK,SAAS,QAAQ,UAAU;AACzD,QAAM,iBAAiB,GAAG,aAAa,aAAa,OAAO;AAC3D,MAAI,CAAC,eAAe,SAAS,qBAAqB,GAAG;AACnD,OAAG,cACD,aACA,GAAG,YAAY,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAO/B;AAAA,EACF;AACA,QAAM,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO,UAAU;AAC7D,QAAM,cAAc,GAAG,aAAa,UAAU,OAAO;AACrD,MAAI,CAAC,YAAY,SAAS,qBAAqB,GAAG;AAChD,OAAG,cACD,UACA,GAAG,YAAY,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,CAM5B;AAAA,EACF;AACF;AA9FgB;AAgGhB,qBAAqB,QAAgB;AACnC,SAAO,OAAO,QAAQ,iCAAiC,EAAE;AAC3D;AAFS;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 path from 'path'\n\nimport * as fs from 'fs-extra'\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(dir: string = require.resolve('react-native-web')) {\n const rootDir = dir.replace(/[\\/\\\\]dist.*/, '')\n const modulePath = path.join(rootDir, 'dist', 'tamagui-exports.js')\n const cjsPath = path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js')\n const shouldPatchExports =\n fs.existsSync(modulePath) &&\n fs.readFileSync(modulePath, 'utf-8') === moduleExports &&\n fs.existsSync(cjsPath) &&\n fs.readFileSync(cjsPath, 'utf-8') === cjsExports\n if (!shouldPatchExports) {\n console.log(' | patch ' + path.relative(rootDir, modulePath))\n console.log(' | patch ' + path.relative(rootDir, cjsPath))\n fs.writeFileSync(modulePath, moduleExports)\n fs.writeFileSync(cjsPath, cjsExports)\n }\n\n // patch to allow className prop\n const patches = [\n {\n id: 'dom-props',\n filePath: ['modules', 'createDOMProps', 'index.js'],\n replacee: ` if (dataSet != null) {`,\n replacer: `\n if (props.dataSet && props.dataSet.className) {\n const { className, ...dataSetRest } = props.dataSet\n classList = className\n dataSet = dataSetRest\n }\n if (props.dataSet && props.dataSet.id) {\n domProps['id'] = props.dataSet.id\n }\n if (dataSet != null) {`,\n },\n {\n id: 'forward-props',\n filePath: ['modules', 'forwardedProps', 'index.js'],\n replacee: `dataSet: true,`,\n replacer: `id: true, dataSet: true,`,\n },\n ]\n\n for (const { filePath, replacee, replacer } of patches) {\n const files = [\n path.join(rootDir, 'dist', ...filePath),\n path.join(rootDir, 'dist', 'cjs', ...filePath),\n ]\n for (const file of files) {\n const contents = fs.readFileSync(file, 'utf-8')\n if (contents.includes(replacer)) {\n continue\n }\n if (!contents.includes(replacee)) {\n console.warn(\n `\u26A0\uFE0F Error: couldn't apply className patch! Maybe using incompatible react-native-web version.`,\n {\n replacee,\n contents,\n }\n )\n continue\n }\n console.log(' | patch ' + path.relative(rootDir, file))\n fs.writeFileSync(file, contents.replace(replacee, replacer))\n }\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;AAEA;AAQO,6BAA6B,MAA8B,qCAAqB;AACrF,QAAM,UAAU,IAAI,QAAQ,gBAAgB,EAAE;AAC9C,QAAM,aAAa,KAAK,KAAK,SAAS,QAAQ,oBAAoB;AAClE,QAAM,UAAU,KAAK,KAAK,SAAS,QAAQ,OAAO,oBAAoB;AACtE,QAAM,qBACJ,GAAG,WAAW,UAAU,KACxB,GAAG,aAAa,YAAY,OAAO,MAAM,iBACzC,GAAG,WAAW,OAAO,KACrB,GAAG,aAAa,SAAS,OAAO,MAAM;AACxC,MAAI,CAAC,oBAAoB;AACvB,YAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,UAAU,CAAC;AACjE,YAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,OAAO,CAAC;AAC9D,OAAG,cAAc,YAAY,aAAa;AAC1C,OAAG,cAAc,SAAS,UAAU;AAAA,EACtC;AAGA,QAAM,UAAU;AAAA,IACd;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,CAAC,WAAW,kBAAkB,UAAU;AAAA,MAClD,UAAU;AAAA,MACV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUZ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,CAAC,WAAW,kBAAkB,UAAU;AAAA,MAClD,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,aAAW,EAAE,UAAU,UAAU,cAAc,SAAS;AACtD,UAAM,QAAQ;AAAA,MACZ,KAAK,KAAK,SAAS,QAAQ,GAAG,QAAQ;AAAA,MACtC,KAAK,KAAK,SAAS,QAAQ,OAAO,GAAG,QAAQ;AAAA,IAC/C;AACA,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,GAAG,aAAa,MAAM,OAAO;AAC9C,UAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B;AAAA,MACF;AACA,UAAI,CAAC,SAAS,SAAS,QAAQ,GAAG;AAChC,gBAAQ,KACN,0GACA;AAAA,UACE;AAAA,UACA;AAAA,QACF,CACF;AACA;AAAA,MACF;AACA,cAAQ,IAAI,mBAAmB,KAAK,SAAS,SAAS,IAAI,CAAC;AAC3D,SAAG,cAAc,MAAM,SAAS,QAAQ,UAAU,QAAQ,CAAC;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,cAAc,KAAK,KAAK,SAAS,QAAQ,UAAU;AACzD,QAAM,iBAAiB,GAAG,aAAa,aAAa,OAAO;AAC3D,MAAI,CAAC,eAAe,SAAS,qBAAqB,GAAG;AACnD,OAAG,cACD,aACA,GAAG,YAAY,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAO/B;AAAA,EACF;AACA,QAAM,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO,UAAU;AAC7D,QAAM,cAAc,GAAG,aAAa,UAAU,OAAO;AACrD,MAAI,CAAC,YAAY,SAAS,qBAAqB,GAAG;AAChD,OAAG,cACD,UACA,GAAG,YAAY,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,CAM5B;AAAA,EACF;AACF;AA9FgB;AAgGhB,qBAAqB,QAAgB;AACnC,SAAO,OAAO,QAAQ,iCAAiC,EAAE;AAC3D;AAFS;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
  }
@@ -97,7 +97,16 @@ function createExtractor() {
97
97
  }
98
98
  tm.mark("load-tamagui", shouldPrintDebug === "verbose");
99
99
  loadedTamaguiConfig = tamaguiConfig;
100
- const defaultTheme = proxyThemeVariables(tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]]);
100
+ const proxiedTheme = proxyThemeVariables(tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]]);
101
+ const themeAccessListeners = /* @__PURE__ */ new Set();
102
+ const defaultTheme = new Proxy(proxiedTheme, {
103
+ get(target2, key) {
104
+ if (key[0] === "$") {
105
+ themeAccessListeners.forEach((cb) => cb(String(key)));
106
+ }
107
+ return Reflect.get(target2, key);
108
+ }
109
+ });
101
110
  const body = fileOrPath.type === "Program" ? fileOrPath.get("body") : fileOrPath.program.body;
102
111
  const isInternalImport = /* @__PURE__ */ __name((importStr) => {
103
112
  return isInsideTamagui(sourcePath) && importStr[0] === ".";
@@ -832,6 +841,14 @@ function createExtractor() {
832
841
  const shouldWrapThme = allOtherPropsExtractable && !!themeVal;
833
842
  const canFlattenProps = inlined.size === 0 || shouldWrapThme || allOtherPropsExtractable;
834
843
  let shouldFlatten = !shouldDeopt && canFlattenProps && !hasSpread && staticConfig.neverFlatten !== true && (staticConfig.neverFlatten === "jsx" ? hasOnlyStringChildren : true);
844
+ if (disableExtractVariables) {
845
+ themeAccessListeners.add((key) => {
846
+ shouldFlatten = false;
847
+ if (shouldPrintDebug) {
848
+ console.log(" ! accessing theme key, avoid flatten", key);
849
+ }
850
+ });
851
+ }
835
852
  if (shouldPrintDebug) {
836
853
  console.log(" - flatten?", objToStr({ hasSpread, shouldDeopt, shouldFlatten, canFlattenProps, shouldWrapThme, allOtherPropsExtractable, hasOnlyStringChildren }));
837
854
  }
@@ -230,7 +230,7 @@ function extractToClassNames({
230
230
  node.attributes.push(t.jsxAttribute(t.jsxIdentifier("className"), t.jsxExpressionContainer(expr)));
231
231
  }
232
232
  const comment = util.format("/* %s:%s (%s) */", filePath, lineNumbers, originalNodeName);
233
- for (const { className, rules, identifier, value } of finalStyles) {
233
+ for (const { className, rules } of finalStyles) {
234
234
  if (cssMap.has(className)) {
235
235
  if (comment) {
236
236
  const val = cssMap.get(className);
@@ -3,7 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
  import path from "path";
4
4
  import * as fs from "fs-extra";
5
5
  function patchReactNativeWeb(dir = require.resolve("react-native-web")) {
6
- const rootDir = dir.replace(/\/dist.*/, "");
6
+ const rootDir = dir.replace(/[\/\\]dist.*/, "");
7
7
  const modulePath = path.join(rootDir, "dist", "tamagui-exports.js");
8
8
  const cjsPath = path.join(rootDir, "dist", "cjs", "tamagui-exports.js");
9
9
  const shouldPatchExports = fs.existsSync(modulePath) && fs.readFileSync(modulePath, "utf-8") === moduleExports && fs.existsSync(cjsPath) && fs.readFileSync(cjsPath, "utf-8") === cjsExports;
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@tamagui/static",
3
- "version": "1.0.1-beta.57",
3
+ "version": "1.0.1-beta.61",
4
4
  "source": "src/index.ts",
5
5
  "types": "./types/index.d.ts",
6
6
  "main": "dist/cjs",
7
7
  "module": "dist/esm",
8
8
  "module:jsx": "dist/jsx",
9
9
  "files": [
10
+ "src",
10
11
  "types",
11
12
  "dist"
12
13
  ],
@@ -16,6 +17,7 @@
16
17
  "clean": "tamagui-build clean",
17
18
  "clean:build": "tamagui-build clean:build",
18
19
  "test": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 jest --forceExit",
20
+ "test:babel": "yarn test tests/babel-test.tsx",
19
21
  "test:debug": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 DEBUG_FILE=extract-specs.tsx DEBUG=1 yarn test",
20
22
  "test:watch": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 yarn test --watch",
21
23
  "test:update-snapshots": "NODE_ENV=test jest --updateSnapshot"
@@ -34,11 +36,11 @@
34
36
  "@babel/parser": "^7.15.7",
35
37
  "@babel/traverse": "^7.15.4",
36
38
  "@expo/match-media": "^0.3.0",
37
- "@tamagui/build": "^1.0.1-beta.57",
38
- "@tamagui/core-node": "^1.0.1-beta.57",
39
- "@tamagui/fake-react-native": "^1.0.1-beta.57",
40
- "@tamagui/helpers": "^1.0.1-beta.57",
41
- "@tamagui/proxy-worm": "^1.0.1-beta.57",
39
+ "@tamagui/build": "^1.0.1-beta.61",
40
+ "@tamagui/core-node": "^1.0.1-beta.61",
41
+ "@tamagui/fake-react-native": "^1.0.1-beta.61",
42
+ "@tamagui/helpers": "^1.0.1-beta.61",
43
+ "@tamagui/proxy-worm": "^1.0.1-beta.61",
42
44
  "babel-literal-to-ast": "^2.1.0",
43
45
  "esbuild": "^0.14.36",
44
46
  "esbuild-register": "^3.3.2",
@@ -46,7 +48,7 @@
46
48
  "fs-extra": "^9.1.0",
47
49
  "invariant": "^2.2.4",
48
50
  "lodash": "^4.17.21",
49
- "tamagui": "^1.0.1-beta.57"
51
+ "tamagui": "^1.0.1-beta.61"
50
52
  },
51
53
  "devDependencies": {
52
54
  "@babel/plugin-syntax-typescript": "^7.14.5",
@@ -0,0 +1,13 @@
1
+ import findCacheDir from 'find-cache-dir'
2
+
3
+ export const CSS_FILE_NAME = '__snack.css'
4
+
5
+ // ENSURE THIS ISNT THE SAME AS THE SEPARATOR USED FOR STYLE KEYS
6
+ // SEE matching one in concatClassName
7
+ export const MEDIA_SEP = '_'
8
+
9
+ // ensure cache dir
10
+ export const cacheDir = findCacheDir({ name: 'tamagui', create: true })
11
+
12
+ export const FAILED_EVAL = Symbol('failed_style_eval')
13
+ export const CONCAT_CLASSNAME_IMPORT = 'concatClassName'
@@ -0,0 +1,18 @@
1
+ import * as t from '@babel/types'
2
+
3
+ // accessSafe wraps memberExpressions in object/null checks
4
+ // TODO: inject this as a function? this gets pretty repetitive
5
+ export function accessSafe(obj: t.Expression, member: string): t.LogicalExpression {
6
+ return t.logicalExpression(
7
+ '&&',
8
+ t.logicalExpression(
9
+ '&&',
10
+ // typeof obj === 'object
11
+ t.binaryExpression('===', t.unaryExpression('typeof', obj), t.stringLiteral('object')),
12
+ // obj !== null
13
+ t.binaryExpression('!==', obj, t.nullLiteral())
14
+ ),
15
+ // obj.member
16
+ t.memberExpression(obj, t.identifier(member), false)
17
+ )
18
+ }
@@ -0,0 +1,27 @@
1
+ import * as babelParser from '@babel/parser'
2
+
3
+ const plugins: babelParser.ParserPlugin[] = [
4
+ 'asyncGenerators',
5
+ 'classProperties',
6
+ 'dynamicImport',
7
+ 'functionBind',
8
+ 'jsx',
9
+ 'numericSeparator',
10
+ 'objectRestSpread',
11
+ 'optionalCatchBinding',
12
+ 'decorators-legacy',
13
+ 'typescript',
14
+ 'optionalChaining',
15
+ 'nullishCoalescingOperator',
16
+ ]
17
+
18
+ export const parserOptions: babelParser.ParserOptions = Object.freeze({
19
+ plugins,
20
+ sourceType: 'module',
21
+ })
22
+
23
+ const parser = babelParser.parse.bind(babelParser)
24
+
25
+ export function babelParse(code: string | Buffer): any {
26
+ return parser(code.toString(), parserOptions)
27
+ }
@@ -0,0 +1,61 @@
1
+ import * as t from '@babel/types'
2
+
3
+ import { ClassNameObject } from '../types'
4
+
5
+ export function buildClassName(
6
+ classNameObjects: ClassNameObject[]
7
+ ): t.Expression | t.StringLiteral | null {
8
+ return classNameObjects.reduce<t.Expression | null>((acc, val) => {
9
+ if (acc == null) {
10
+ if (
11
+ // pass conditional expressions through
12
+ t.isConditionalExpression(val) ||
13
+ // pass non-null literals through
14
+ t.isStringLiteral(val) ||
15
+ t.isNumericLiteral(val)
16
+ ) {
17
+ return val
18
+ }
19
+ return t.logicalExpression('||', val, t.stringLiteral(''))
20
+ }
21
+
22
+ let inner: t.Expression
23
+ if (t.isStringLiteral(val)) {
24
+ if (t.isStringLiteral(acc)) {
25
+ // join adjacent string literals
26
+ return t.stringLiteral(`${acc.value} ${val.value}`)
27
+ }
28
+ inner = t.stringLiteral(` ${val.value}`)
29
+ } else if (t.isLiteral(val)) {
30
+ inner = t.binaryExpression('+', t.stringLiteral(' '), val)
31
+ } else if (t.isConditionalExpression(val) || t.isBinaryExpression(val)) {
32
+ if (t.isStringLiteral(acc)) {
33
+ return t.binaryExpression('+', t.stringLiteral(`${acc.value} `), val)
34
+ }
35
+ inner = t.binaryExpression('+', t.stringLiteral(' '), val)
36
+ } else if (t.isIdentifier(val) || t.isMemberExpression(val)) {
37
+ // identifiers and member expressions make for reasonable ternaries
38
+ inner = t.conditionalExpression(
39
+ val,
40
+ t.binaryExpression('+', t.stringLiteral(' '), val),
41
+ t.stringLiteral('')
42
+ )
43
+ } else {
44
+ if (t.isStringLiteral(acc)) {
45
+ return t.binaryExpression(
46
+ '+',
47
+ t.stringLiteral(`${acc.value} `),
48
+ t.logicalExpression('||', val, t.stringLiteral(''))
49
+ )
50
+ }
51
+ // use a logical expression for more complex prop values
52
+ inner = t.binaryExpression(
53
+ '+',
54
+ t.stringLiteral(' '),
55
+ t.logicalExpression('||', val, t.stringLiteral(''))
56
+ )
57
+ }
58
+
59
+ return t.binaryExpression('+', acc, inner)
60
+ }, null)
61
+ }
@@ -0,0 +1,69 @@
1
+ import vm from 'vm'
2
+
3
+ import generate from '@babel/generator'
4
+ import { NodePath } from '@babel/traverse'
5
+ import * as t from '@babel/types'
6
+ import type { TamaguiConfig } from '@tamagui/core'
7
+ import { createCSSVariable } from '@tamagui/core-node'
8
+
9
+ import { FAILED_EVAL } from '../constants'
10
+ import { evaluateAstNode } from './evaluateAstNode'
11
+ import { isValidThemeHook } from './extractHelpers'
12
+
13
+ export function createEvaluator({
14
+ tamaguiConfig,
15
+ staticNamespace,
16
+ sourcePath,
17
+ traversePath,
18
+ shouldPrintDebug,
19
+ }: {
20
+ tamaguiConfig: TamaguiConfig
21
+ staticNamespace: Record<string, any>
22
+ sourcePath: string
23
+ traversePath: NodePath<t.JSXElement>
24
+ shouldPrintDebug: boolean | 'verbose'
25
+ }) {
26
+ // called when evaluateAstNode encounters a dynamic-looking prop
27
+ const evalFn = (n: t.Node) => {
28
+ // themes
29
+ if (
30
+ t.isMemberExpression(n) &&
31
+ t.isIdentifier(n.property) &&
32
+ isValidThemeHook(traversePath, n, sourcePath)
33
+ ) {
34
+ const key = n.property.name
35
+ if (shouldPrintDebug) {
36
+ console.log(' > found theme prop', key)
37
+ }
38
+ console.log('SHOULD FIND THEME (NESTED NOW)', key) // tamaguiConfig.themes)
39
+ // if (!themeKeys.has(key)) {
40
+ // throw new Error(` > accessing non-existent theme key: ${key}`)
41
+ // }
42
+ return createCSSVariable(key)
43
+ }
44
+ // variable
45
+ if (t.isIdentifier(n) && staticNamespace.hasOwnProperty(n.name)) {
46
+ return staticNamespace[n.name]
47
+ }
48
+ const evalContext = vm.createContext(staticNamespace)
49
+ const code = `(${generate(n as any).code})`
50
+ // if (shouldPrintDebug) {
51
+ // console.log('evaluating', { n, code, evalContext })
52
+ // }
53
+ return vm.runInContext(code, evalContext)
54
+ }
55
+
56
+ return (n: t.Node) => {
57
+ return evaluateAstNode(n, evalFn)
58
+ }
59
+ }
60
+
61
+ export function createSafeEvaluator(attemptEval: (n: t.Node) => any) {
62
+ return (n: t.Node) => {
63
+ try {
64
+ return attemptEval(n)
65
+ } catch (err) {
66
+ return FAILED_EVAL
67
+ }
68
+ }
69
+ }