diff --git a/docs/source/_static/css/interactive-widget.css b/docs/source/_static/css/interactive-widget.css index e58c1f6f8..41cd58e7c 100644 --- a/docs/source/_static/css/interactive-widget.css +++ b/docs/source/_static/css/interactive-widget.css @@ -9,6 +9,11 @@ background-color: var(--color-code-background); min-height: 75px; } + +.widget-container > div { + width: 100%; +} + .center-content { display: flex; align-items: center; diff --git a/docs/source/_static/custom.js b/docs/source/_static/custom.js index 6b5c941fd..59ec18302 100644 --- a/docs/source/_static/custom.js +++ b/docs/source/_static/custom.js @@ -1900,8 +1900,6 @@ function mountWidgetExample( const mountEl = document.getElementById(mountID); - console.log(useActivateButton); - if (!useActivateButton) { mountLayoutWithWebSocket( mountEl, diff --git a/docs/source/custom_js/package-lock.json b/docs/source/custom_js/package-lock.json index 07f59cc9b..b7da66ac6 100644 --- a/docs/source/custom_js/package-lock.json +++ b/docs/source/custom_js/package-lock.json @@ -19,7 +19,7 @@ } }, "../../../src/client/packages/idom-client-react": { - "version": "0.9.1", + "version": "0.9.2", "license": "MIT", "dependencies": { "fast-json-patch": "^3.0.0-1", @@ -35,59 +35,28 @@ "react-dom": ">=16" } }, - "../../../src/idom/client/packages/idom-client-react": { - "version": "0.8.3", - "extraneous": true, - "license": "MIT", - "dependencies": { - "fast-json-patch": "^3.0.0-1", - "htm": "^3.0.3" - }, - "devDependencies": { - "jsdom": "16.3.0", - "prettier": "^2.2.1", - "uvu": "^0.5.1" - }, - "peerDependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" - } - }, - "../../src/idom/client/packages/idom-client-react": { - "extraneous": true - }, - "../src/idom/client/package/idom-client-react": { - "extraneous": true - }, - "../src/idom/client/packages/idom-client-react": { - "extraneous": true - }, "node_modules/@types/estree": { "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", - "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/resolve": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/builtin-modules": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -97,35 +66,18 @@ }, "node_modules/estree-walker": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "license": "MIT" }, "node_modules/function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.1" }, @@ -139,9 +91,8 @@ }, "node_modules/is-core-module": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, + "license": "MIT", "dependencies": { "has": "^1.0.3" }, @@ -151,39 +102,34 @@ }, "node_modules/is-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-reference": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/magic-string": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, + "license": "MIT", "dependencies": { "sourcemap-codec": "^1.4.4" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prettier": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -193,9 +139,8 @@ }, "node_modules/resolve": { "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -206,9 +151,8 @@ }, "node_modules/rollup": { "version": "2.52.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.1.tgz", - "integrity": "sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w==", "dev": true, + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -221,10 +165,8 @@ }, "node_modules/rollup-plugin-commonjs": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", "dev": true, + "license": "MIT", "dependencies": { "estree-walker": "^0.6.1", "is-reference": "^1.1.2", @@ -238,10 +180,8 @@ }, "node_modules/rollup-plugin-node-resolve": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.", "dev": true, + "license": "MIT", "dependencies": { "@types/resolve": "0.0.8", "builtin-modules": "^3.1.0", @@ -255,10 +195,8 @@ }, "node_modules/rollup-plugin-replace": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz", - "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==", - "deprecated": "This module has moved and is now available at @rollup/plugin-replace. Please update your dependencies. This version is no longer maintained.", "dev": true, + "license": "MIT", "dependencies": { "magic-string": "^0.25.2", "rollup-pluginutils": "^2.6.0" @@ -266,37 +204,29 @@ }, "node_modules/rollup-pluginutils": { "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, + "license": "MIT", "dependencies": { "estree-walker": "^0.6.1" } }, "node_modules/sourcemap-codec": { "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true + "dev": true, + "license": "MIT" } }, "dependencies": { "@types/estree": { "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", - "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", "dev": true }, "@types/node": { "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", "dev": true }, "@types/resolve": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, "requires": { "@types/node": "*" @@ -304,33 +234,18 @@ }, "builtin-modules": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, "estree-walker": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -348,8 +263,6 @@ }, "is-core-module": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" @@ -357,14 +270,10 @@ }, "is-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, "is-reference": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "requires": { "@types/estree": "*" @@ -372,8 +281,6 @@ }, "magic-string": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, "requires": { "sourcemap-codec": "^1.4.4" @@ -381,20 +288,14 @@ }, "path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "prettier": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", "dev": true }, "resolve": { "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { "is-core-module": "^2.2.0", @@ -403,8 +304,6 @@ }, "rollup": { "version": "2.52.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.1.tgz", - "integrity": "sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -412,8 +311,6 @@ }, "rollup-plugin-commonjs": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", "dev": true, "requires": { "estree-walker": "^0.6.1", @@ -425,8 +322,6 @@ }, "rollup-plugin-node-resolve": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", "dev": true, "requires": { "@types/resolve": "0.0.8", @@ -438,8 +333,6 @@ }, "rollup-plugin-replace": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz", - "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==", "dev": true, "requires": { "magic-string": "^0.25.2", @@ -448,8 +341,6 @@ }, "rollup-pluginutils": { "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, "requires": { "estree-walker": "^0.6.1" @@ -457,8 +348,6 @@ }, "sourcemap-codec": { "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true } } diff --git a/docs/source/custom_js/src/index.js b/docs/source/custom_js/src/index.js index 255dfcfcb..048354735 100644 --- a/docs/source/custom_js/src/index.js +++ b/docs/source/custom_js/src/index.js @@ -17,8 +17,6 @@ export function mountWidgetExample( const mountEl = document.getElementById(mountID); - console.log(useActivateButton); - if (!useActivateButton) { mountLayoutWithWebSocket( mountEl, diff --git a/docs/source/examples/pigeon_maps.py b/docs/source/examples/pigeon_maps.py new file mode 100644 index 000000000..ab0157f73 --- /dev/null +++ b/docs/source/examples/pigeon_maps.py @@ -0,0 +1,49 @@ +import idom + + +pigeon_maps = idom.web.module_from_template("react", "pigeon-maps", fallback="⌛") +Map, Marker = idom.web.export(pigeon_maps, ["Map", "Marker"]) + + +@idom.component +def MapWithMarkers(): + marker_anchor, add_marker_anchor, remove_marker_anchor = use_set() + + markers = list( + map( + lambda anchor: Marker( + { + "anchor": anchor, + "onClick": lambda: remove_marker_anchor(anchor), + }, + key=str(anchor), + ), + marker_anchor, + ) + ) + + return Map( + { + "defaultCenter": (37.774, -122.419), + "defaultZoom": 12, + "height": "300px", + "metaWheelZoom": True, + "onClick": lambda event: add_marker_anchor(tuple(event["latLng"])), + }, + markers, + ) + + +def use_set(initial_value=None): + values, set_values = idom.hooks.use_state(initial_value or set()) + + def add_value(lat_lon): + set_values(values.union({lat_lon})) + + def remove_value(lat_lon): + set_values(values.difference({lat_lon})) + + return values, add_value, remove_value + + +idom.run(MapWithMarkers) diff --git a/docs/source/examples/snake_game.py b/docs/source/examples/snake_game.py index 313ff4a83..4a5736fe4 100644 --- a/docs/source/examples/snake_game.py +++ b/docs/source/examples/snake_game.py @@ -26,11 +26,21 @@ def GameView(): ) if game_state == GameState.won: - return idom.html.div(idom.html.h1("You won!"), start_button) + menu = idom.html.div(idom.html.h3("You won!"), start_button) elif game_state == GameState.lost: - return idom.html.div(idom.html.h1("You lost"), start_button) + menu = idom.html.div(idom.html.h3("You lost"), start_button) else: - return idom.html.div(idom.html.h1("Click to play"), start_button) + menu = idom.html.div(idom.html.h3("Click to play"), start_button) + + menu_style = idom.html.style( + """ + .snake-game-menu h3 { + margin-top: 0px !important; + } + """ + ) + + return idom.html.div({"className": "snake-game-menu"}, menu_style, menu) class Direction(enum.Enum): @@ -52,6 +62,7 @@ def GameLoop(grid_size, block_scale, set_game_state): grid = create_grid(grid_size, block_scale) + @idom.event(prevent_default=True) def on_direction_change(event): if hasattr(Direction, event["key"]): maybe_new_direction = Direction[event["key"]].value diff --git a/docs/source/examples/todo.py b/docs/source/examples/todo.py index 4c967d2e0..8368d05ec 100644 --- a/docs/source/examples/todo.py +++ b/docs/source/examples/todo.py @@ -23,7 +23,11 @@ async def remove_task(event, index=index): task_input = idom.html.input({"onKeyDown": add_new_task}) task_table = idom.html.table(tasks) - return idom.html.div(task_input, task_table) + return idom.html.div( + idom.html.p("press enter to add a task:"), + task_input, + task_table, + ) idom.run(Todo) diff --git a/docs/source/index.rst b/docs/source/index.rst index 71fac6790..f41e1c6a4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -60,17 +60,17 @@ A package for building responsive user interfaces in pure Python. .. grid-item-card:: - .. interactive-widget:: click_count + .. interactive-widget:: pigeon_maps :no-activate-button: .. grid-item-card:: - .. interactive-widget:: material_ui_button_on_click + .. interactive-widget:: snake_game :no-activate-button: .. grid-item-card:: - .. interactive-widget:: matplotlib_plot + .. interactive-widget:: slideshow :no-activate-button: .. grid-item-card:: @@ -78,6 +78,11 @@ A package for building responsive user interfaces in pure Python. .. interactive-widget:: audio_player :no-activate-button: + .. grid-item-card:: + + .. interactive-widget:: todo + :no-activate-button: + .. grid-item:: .. grid:: 1 1 1 1 @@ -85,15 +90,17 @@ A package for building responsive user interfaces in pure Python. .. grid-item-card:: - .. interactive-widget:: material_ui_switch + .. interactive-widget:: simple_dashboard :no-activate-button: + + .. grid-item-card:: - .. interactive-widget:: simple_dashboard + .. interactive-widget:: matplotlib_plot :no-activate-button: .. grid-item-card:: - .. interactive-widget:: slideshow + .. interactive-widget:: material_ui_button_on_click :no-activate-button: diff --git a/src/idom/web/module.py b/src/idom/web/module.py index 6164437b2..7d25152b5 100644 --- a/src/idom/web/module.py +++ b/src/idom/web/module.py @@ -125,7 +125,7 @@ def module_from_template( if not template_file.exists(): raise ValueError(f"No template for {template_file_name!r} exists") - target_file = _web_module_path(package_name) + target_file = _web_module_path(package_name, "from-template") if not target_file.exists(): target_file.parent.mkdir(parents=True, exist_ok=True) target_file.write_text( @@ -133,7 +133,7 @@ def module_from_template( ) return WebModule( - source=package_name + module_name_suffix(package_name), + source="from-template/" + package_name + module_name_suffix(package_name), source_type=NAME_SOURCE, default_fallback=fallback, file=target_file, @@ -291,7 +291,10 @@ def _make_export( ) -def _web_module_path(name: str) -> Path: +def _web_module_path(name: str, prefix: str = "") -> Path: name += module_name_suffix(name) - path = IDOM_WED_MODULES_DIR.current.joinpath(*name.split("/")) + directory = IDOM_WED_MODULES_DIR.current + if prefix: + directory /= prefix + path = directory.joinpath(*name.split("/")) return path.with_suffix(path.suffix) diff --git a/src/idom/web/templates/react.js b/src/idom/web/templates/react.js index 1b20ef622..6bbc66f73 100644 --- a/src/idom/web/templates/react.js +++ b/src/idom/web/templates/react.js @@ -1,8 +1,14 @@ export * from "$CDN/$PACKAGE"; +import * as ThisImportSource from "$CDN/$PACKAGE"; import * as React from "$CDN/react"; import * as ReactDOM from "$CDN/react-dom"; -import { LayoutConfigContext, elementChildren } from "$CDN/idom-client-react"; +import { + LayoutConfigContext, + Element, + elementAttributes, + elementChildren, +} from "$CDN/idom-client-react"; export function bind(node, config) { return { @@ -16,8 +22,47 @@ function createElement(config, component, props, children) { return React.createElement( LayoutConfigContext.Provider, { value: config }, - React.createElement( - component, props, ...elementChildren(children) - ) - ) + React.createElement(component, props, ...createChildren(children, config)) + ); +} + +function createChildren(children, config) { + if (!children) { + return []; + } + return children.map((child) => { + if (typeof child == "string") { + return child; + } else if (child.importSource) { + return createElementFromThisImportSource(child, config); + } else { + return React.createElement(Element, { model: child }); + } + }); +} + +function createElementFromThisImportSource(model, config) { + const Component = ThisImportSource[model.tagName]; + if (!Component) { + console.error( + `Cannot create ${model.tagName} from different import source ` + + `${model.importSource.source} (type: ${model.importSource.sourceType})` + ); + } + return React.createElement( + Component, + elementAttributes(model, (event) => { + event.data = event.data.filter(value => { + try { + JSON.stringify(value); + } catch (err) { + console.error(`Failed to serialize some event data for ${model.tagName}`) + return false; + } + return true; + }) + config.sendEvent(event); + }), + ...createChildren(model.children, config) + ); }