diff --git a/@plotly/dash-generator-test-component-standard/base/__init__.py b/@plotly/dash-generator-test-component-standard/base/__init__.py
index c72087cde2..fb1bae5541 100644
--- a/@plotly/dash-generator-test-component-standard/base/__init__.py
+++ b/@plotly/dash-generator-test-component-standard/base/__init__.py
@@ -16,8 +16,21 @@
dict(
relative_package_path='dash_generator_test_component_standard.js',
namespace='dash_generator_test_component_standard'
+ ),
+ dict(
+ relative_package_path='godfather.ttf',
+ namespace='dash_generator_test_component_standard',
+ dynamic=True
+ )
+]
+
+_css_dist = [
+ dict(
+ relative_package_path='style.css',
+ namespace='dash_generator_test_component_standard'
)
]
for _component in __all__:
setattr(locals()[_component], '_js_dist', _js_dist)
+ setattr(locals()[_component], '_css_dist', _css_dist)
diff --git a/@plotly/dash-generator-test-component-standard/base/godfather.ttf b/@plotly/dash-generator-test-component-standard/base/godfather.ttf
new file mode 100644
index 0000000000..a97301daa0
Binary files /dev/null and b/@plotly/dash-generator-test-component-standard/base/godfather.ttf differ
diff --git a/@plotly/dash-generator-test-component-standard/base/style.css b/@plotly/dash-generator-test-component-standard/base/style.css
new file mode 100644
index 0000000000..f69de0e7ec
--- /dev/null
+++ b/@plotly/dash-generator-test-component-standard/base/style.css
@@ -0,0 +1,4 @@
+@font-face {
+ font-family: 'godfather';
+ src: url(./godfather.ttf) format('truetype');
+}
\ No newline at end of file
diff --git a/@plotly/dash-generator-test-component-standard/src/components/MyStandardComponent.js b/@plotly/dash-generator-test-component-standard/src/components/MyStandardComponent.js
index df9ab777b8..b9597fba71 100644
--- a/@plotly/dash-generator-test-component-standard/src/components/MyStandardComponent.js
+++ b/@plotly/dash-generator-test-component-standard/src/components/MyStandardComponent.js
@@ -4,7 +4,7 @@ import React from 'react';
/**
* MyComponent description
*/
-const MyStandardComponent = ({ id, value }) => (
{value}
);
+const MyStandardComponent = ({ id, style, value }) => ({value}
);
MyStandardComponent.propTypes = {
/**
@@ -12,6 +12,11 @@ MyStandardComponent.propTypes = {
*/
id: PropTypes.string,
+ /**
+ * The style
+ */
+ style: PropTypes.shape,
+
/**
* The value to display
*/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86e4be2efa..b7a012bff1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [UNRELEASED]
### Added
- [#1201](https://github.com/plotly/dash/pull/1201) New attribute `app.validation_layout` allows you to create a multi-page app without `suppress_callback_exceptions=True` or layout function tricks. Set this to a component layout containing the superset of all IDs on all pages in your app.
+- [#1078](https://github.com/plotly/dash/pull/1078) Permit usage of arbitrary file extensions for assets within component libraries
### Fixed
- [#1201](https://github.com/plotly/dash/pull/1201) Fixes [#1193](https://github.com/plotly/dash/issues/1193) - prior to Dash 1.11, you could use `flask.has_request_context() == False` inside an `app.layout` function to provide a special layout containing all IDs for validation purposes in a multi-page app. Dash 1.11 broke this when we moved most of this validation into the renderer. This change makes it work again.
@@ -72,7 +73,7 @@ These functions are particularly useful for apps deployed on Dash Enterprise whe
### Changed
- [#1035](https://github.com/plotly/dash/pull/1035) Simplify our build process.
-- [#1074](https://github.com/plotly/dash/pull/1045) Error messages when providing an incorrect property to a component have been improved: they now specify the component type, library, version, and ID (if available).
+- [#1074](https://github.com/plotly/dash/pull/1074) Error messages when providing an incorrect property to a component have been improved: they now specify the component type, library, version, and ID (if available).
### Fixed
- [#1037](https://github.com/plotly/dash/pull/1037) Fix no_update test to allow copies, such as those stored and retrieved from a cache.
diff --git a/dash/dash.py b/dash/dash.py
index a31fbc22c2..dd9f505973 100644
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -11,6 +11,7 @@
import threading
import re
import logging
+import mimetypes
from functools import wraps
@@ -45,6 +46,9 @@
from . import _validate
from . import _watch
+# Add explicit mapping for map files
+mimetypes.add_type("application/json", ".map", True)
+
_default_index = """
@@ -669,13 +673,8 @@ def serve_component_suites(self, package_name, fingerprinted_path):
_validate.validate_js_path(self.registered_paths, package_name, path_in_pkg)
- mimetype = (
- {
- "js": "application/javascript",
- "css": "text/css",
- "map": "application/json",
- }
- )[path_in_pkg.split(".")[-1]]
+ extension = "." + path_in_pkg.split(".")[-1]
+ mimetype = mimetypes.types_map.get(extension, "application/octet-stream")
package = sys.modules[package_name]
self.logger.debug(
diff --git a/dash/development/_r_components_generation.py b/dash/development/_r_components_generation.py
index 7ed2d52f88..577cc914e3 100644
--- a/dash/development/_r_components_generation.py
+++ b/dash/development/_r_components_generation.py
@@ -505,7 +505,7 @@ def write_js_metadata(pkg_data, project_shortname, has_wildcards):
for filename in filenames:
extension = os.path.splitext(filename)[1]
- if extension not in [".css", ".js", ".map"]:
+ if extension in [".py", ".pyc", ".json"]:
continue
target_dirname = os.path.join(
diff --git a/tests/integration/test_generation.py b/tests/integration/test_generation.py
index fe1fbf7ad1..518c7a0af7 100644
--- a/tests/integration/test_generation.py
+++ b/tests/integration/test_generation.py
@@ -1,7 +1,12 @@
from dash import Dash
+from dash.dependencies import Input, Output
+from dash.exceptions import PreventUpdate
+
from dash_generator_test_component_nested import MyNestedComponent
from dash_generator_test_component_standard import MyStandardComponent
-from dash_html_components import Div
+from dash_html_components import Button, Div
+
+from selenium.webdriver.support.ui import WebDriverWait
def test_gene001_simple_callback(dash_duo):
@@ -18,3 +23,39 @@ def test_gene001_simple_callback(dash_duo):
assert dash_duo.wait_for_element("#standard").text == "Standard"
assert dash_duo.wait_for_element("#nested").text == "Nested"
+
+ dash_duo.percy_snapshot(name="gene001-simple-callback")
+
+
+def test_gene002_arbitrary_resources(dash_duo):
+ app = Dash(__name__)
+
+ app.layout = Div([Button(id="btn"), Div(id="container")])
+
+ @app.callback(Output("container", "children"), [Input("btn", "n_clicks")])
+ def update_container(n_clicks):
+ if n_clicks is None:
+ raise PreventUpdate
+
+ return MyStandardComponent(
+ id="standard", value="Standard", style={"font-family": "godfather"}
+ )
+
+ dash_duo.start_server(app)
+
+ assert (
+ dash_duo.driver.execute_script("return document.fonts.check('1em godfather')")
+ is False
+ )
+
+ dash_duo.wait_for_element("#btn").click()
+ assert dash_duo.wait_for_element("#standard").text == "Standard"
+
+ WebDriverWait(dash_duo.driver, 10).until(
+ lambda _: dash_duo.driver.execute_script(
+ "return document.fonts.check('1em godfather')"
+ )
+ is True,
+ )
+
+ dash_duo.percy_snapshot(name="gene002-arbitrary-resource")