reflex-components-plotly 0.9.2__tar.gz → 0.9.3__tar.gz

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.
@@ -1,5 +1,10 @@
1
1
  **/.DS_Store
2
2
  **/*.pyc
3
+ **/__pycache__/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ **/.ruff_cache/
7
+ .mypy_cache/
3
8
  assets/external/*
4
9
  dist/*
5
10
  examples/
@@ -21,4 +26,7 @@ reflex.db
21
26
  node_modules
22
27
  package-lock.json
23
28
  *.pyi
24
- .pre-commit-config.yaml
29
+ .pre-commit-config.yaml
30
+ .claude/.worktrees
31
+ .claude/settings.local.json
32
+ CLAUDE.local.md
@@ -0,0 +1,5 @@
1
+ ## v0.9.3 (2026-06-25)
2
+
3
+ ### Features
4
+
5
+ - `rx.plotly` (and its dist variants like `rx.plotly.basic`) now accept a `locale` prop to localize Plotly's number/date formatting and modebar labels. The matching locale data from `plotly.js-locales` is resolved and merged into the chart config at render time, so per-chart locales work without any manual setup. ([#6428](https://github.com/reflex-dev/reflex/issues/6428))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex-components-plotly
3
- Version: 0.9.2
3
+ Version: 0.9.3
4
4
  Summary: Reflex plotly components.
5
5
  Author-email: Khaleel Al-Adhami <khaleel@reflex.dev>
6
6
  Maintainer-email: Khaleel Al-Adhami <khaleel@reflex.dev>
File without changes
@@ -90,6 +90,10 @@ class Plotly(NoSSRComponent):
90
90
 
91
91
  config: Var[dict] = field(doc="The config of the graph.")
92
92
 
93
+ locale: Var[str] = field(
94
+ doc="The locale code used for Plotly formatting and modebar labels."
95
+ )
96
+
93
97
  use_resize_handler: Var[bool] = field(
94
98
  default=LiteralVar.create(True),
95
99
  doc="If true, the graph will resize when the window is resized.",
@@ -175,16 +179,23 @@ class Plotly(NoSSRComponent):
175
179
  doc="Fired when a hovered element is no longer hovered."
176
180
  )
177
181
 
178
- def add_imports(self) -> dict[str, str]:
182
+ def add_imports(self) -> ImportDict:
179
183
  """Add imports for the plotly component.
180
184
 
181
185
  Returns:
182
186
  The imports for the plotly component.
183
187
  """
184
- return {
188
+ imports: ImportDict = {
185
189
  # For merging plotly data/layout/templates.
186
- "mergician@v2.0.2": "mergician"
190
+ "mergician@v2.0.2": "mergician",
187
191
  }
192
+ if self.locale is not None:
193
+ # For locale dictionaries injected into plot config.locales.
194
+ imports["plotly.js-locales@3.5.0"] = ImportVar(
195
+ tag="plotlyLocales",
196
+ is_default=True,
197
+ )
198
+ return imports
188
199
 
189
200
  def add_custom_code(self) -> list[str]:
190
201
  """Add custom codes for processing the plotly points data.
@@ -192,7 +203,7 @@ class Plotly(NoSSRComponent):
192
203
  Returns:
193
204
  Custom code snippets for the module level.
194
205
  """
195
- return [
206
+ codes = [
196
207
  "const removeUndefined = (obj) => {Object.keys(obj).forEach(key => obj[key] === undefined && delete obj[key]); return obj}",
197
208
  """
198
209
  const extractPoints = (points) => {
@@ -224,6 +235,45 @@ const extractPoints = (points) => {
224
235
  }
225
236
  """,
226
237
  ]
238
+ if self.locale is not None:
239
+ codes.append("""
240
+ const _rxResolvePlotlyLocaleData = (plotlyLocales, locale) => {
241
+ if (locale === undefined || locale === null) return null;
242
+ const localeString = String(locale).trim();
243
+ if (localeString === "") return null;
244
+
245
+ const normalizedLocale = localeString.toLowerCase().replace(/_/g, "-");
246
+ const localesObject = plotlyLocales?.default ?? plotlyLocales;
247
+ if (!localesObject || typeof localesObject !== "object") return null;
248
+
249
+ return (
250
+ localesObject[normalizedLocale] ??
251
+ localesObject[normalizedLocale.split("-")[0]] ??
252
+ null
253
+ );
254
+ }
255
+
256
+ const _rxGetPlotlyLocaleConfig = (config, locale, plotlyLocales) => {
257
+ const localeData = _rxResolvePlotlyLocaleData(plotlyLocales, locale);
258
+ if (!localeData) {
259
+ if (locale === undefined || locale === null || String(locale).trim() === "") {
260
+ return config;
261
+ }
262
+ return { ...config, locale: String(locale) };
263
+ }
264
+
265
+ const localeName = localeData?.name ?? String(locale);
266
+ return {
267
+ ...config,
268
+ locale: localeName,
269
+ locales: {
270
+ ...(config?.locales ?? {}),
271
+ [localeName]: localeData,
272
+ },
273
+ };
274
+ }
275
+ """)
276
+ return codes
227
277
 
228
278
  @classmethod
229
279
  def create(cls, *children, **props) -> Component:
@@ -251,7 +301,7 @@ const extractPoints = (points) => {
251
301
 
252
302
  def _exclude_props(self) -> set[str]:
253
303
  # These props are handled specially in the _render function
254
- return {"data", "layout", "template"}
304
+ return {"data", "layout", "template", "locale"}
255
305
 
256
306
  def _render(self):
257
307
  tag = super()._render()
@@ -285,6 +335,16 @@ const extractPoints = (points) => {
285
335
  Var(_js_expr=str(figure)),
286
336
  ]
287
337
  )
338
+ if self.locale is not None:
339
+ config = self.config if self.config is not None else LiteralVar.create({})
340
+ tag = tag.set(
341
+ props={
342
+ **tag.props,
343
+ "config": Var(
344
+ _js_expr=f"_rxGetPlotlyLocaleConfig({config!s},{self.locale!s},plotlyLocales)"
345
+ ),
346
+ },
347
+ )
288
348
  return tag
289
349
 
290
350
 
@@ -327,7 +387,7 @@ class PlotlyBasic(Plotly):
327
387
 
328
388
  lib_dependencies: list[str] = ["plotly.js-basic-dist-min@3.5.1"]
329
389
 
330
- def add_imports(self) -> ImportDict | list[ImportDict]:
390
+ def add_imports(self) -> ImportDict:
331
391
  """Add imports for the plotly basic component.
332
392
 
333
393
  Returns:
@@ -353,7 +413,7 @@ class PlotlyCartesian(Plotly):
353
413
 
354
414
  lib_dependencies: list[str] = ["plotly.js-cartesian-dist-min@3.5.1"]
355
415
 
356
- def add_imports(self) -> ImportDict | list[ImportDict]:
416
+ def add_imports(self) -> ImportDict:
357
417
  """Add imports for the plotly cartesian component.
358
418
 
359
419
  Returns:
@@ -379,7 +439,7 @@ class PlotlyGeo(Plotly):
379
439
 
380
440
  lib_dependencies: list[str] = ["plotly.js-geo-dist-min@3.5.1"]
381
441
 
382
- def add_imports(self) -> ImportDict | list[ImportDict]:
442
+ def add_imports(self) -> ImportDict:
383
443
  """Add imports for the plotly geo component.
384
444
 
385
445
  Returns:
@@ -405,7 +465,7 @@ class PlotlyGl3d(Plotly):
405
465
 
406
466
  lib_dependencies: list[str] = ["plotly.js-gl3d-dist-min@3.5.1"]
407
467
 
408
- def add_imports(self) -> ImportDict | list[ImportDict]:
468
+ def add_imports(self) -> ImportDict:
409
469
  """Add imports for the plotly 3d component.
410
470
 
411
471
  Returns:
@@ -431,7 +491,7 @@ class PlotlyGl2d(Plotly):
431
491
 
432
492
  lib_dependencies: list[str] = ["plotly.js-gl2d-dist-min@3.5.1"]
433
493
 
434
- def add_imports(self) -> ImportDict | list[ImportDict]:
494
+ def add_imports(self) -> ImportDict:
435
495
  """Add imports for the plotly 2d component.
436
496
 
437
497
  Returns:
@@ -457,7 +517,7 @@ class PlotlyMapbox(Plotly):
457
517
 
458
518
  lib_dependencies: list[str] = ["plotly.js-mapbox-dist-min@3.5.1"]
459
519
 
460
- def add_imports(self) -> ImportDict | list[ImportDict]:
520
+ def add_imports(self) -> ImportDict:
461
521
  """Add imports for the plotly mapbox component.
462
522
 
463
523
  Returns:
@@ -483,7 +543,7 @@ class PlotlyFinance(Plotly):
483
543
 
484
544
  lib_dependencies: list[str] = ["plotly.js-finance-dist-min@3.5.1"]
485
545
 
486
- def add_imports(self) -> ImportDict | list[ImportDict]:
546
+ def add_imports(self) -> ImportDict:
487
547
  """Add imports for the plotly finance component.
488
548
 
489
549
  Returns:
@@ -509,7 +569,7 @@ class PlotlyStrict(Plotly):
509
569
 
510
570
  lib_dependencies: list[str] = ["plotly.js-strict-dist-min@3.5.1"]
511
571
 
512
- def add_imports(self) -> ImportDict | list[ImportDict]:
572
+ def add_imports(self) -> ImportDict:
513
573
  """Add imports for the plotly strict component.
514
574
 
515
575
  Returns:
@@ -47,7 +47,7 @@ class Point(TypedDict):
47
47
  bbox: BBox | None
48
48
 
49
49
  class Plotly(NoSSRComponent):
50
- def add_imports(self) -> dict[str, str]: ...
50
+ def add_imports(self) -> ImportDict: ...
51
51
  def add_custom_code(self) -> list[str]: ...
52
52
  @classmethod
53
53
  def create(
@@ -57,6 +57,7 @@ class Plotly(NoSSRComponent):
57
57
  layout: Var[dict] | dict | None = None,
58
58
  template: Any | Var[Any] | None = None,
59
59
  config: Var[dict] | dict | None = None,
60
+ locale: Var[str] | str | None = None,
60
61
  use_resize_handler: Var[bool] | bool | None = None,
61
62
  style: Sequence[Mapping[str, Any]]
62
63
  | Mapping[str, Any]
@@ -112,6 +113,7 @@ class Plotly(NoSSRComponent):
112
113
  layout: The layout of the graph.
113
114
  template: The template for visual appearance of the graph.
114
115
  config: The config of the graph.
116
+ locale: The locale code used for Plotly formatting and modebar labels.
115
117
  use_resize_handler: If true, the graph will resize when the window is resized.
116
118
  style: The style of the component.
117
119
  key: A unique key for the component.
@@ -164,7 +166,7 @@ CREATE_PLOTLY_COMPONENT: ImportDict
164
166
  def dynamic_plotly_import(name: str, package: str) -> str: ...
165
167
 
166
168
  class PlotlyBasic(Plotly):
167
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
169
+ def add_imports(self) -> ImportDict: ...
168
170
  @classmethod
169
171
  def create(
170
172
  cls,
@@ -173,6 +175,7 @@ class PlotlyBasic(Plotly):
173
175
  layout: Var[dict] | dict | None = None,
174
176
  template: Any | Var[Any] | None = None,
175
177
  config: Var[dict] | dict | None = None,
178
+ locale: Var[str] | str | None = None,
176
179
  use_resize_handler: Var[bool] | bool | None = None,
177
180
  style: Sequence[Mapping[str, Any]]
178
181
  | Mapping[str, Any]
@@ -228,6 +231,7 @@ class PlotlyBasic(Plotly):
228
231
  layout: The layout of the graph.
229
232
  template: The template for visual appearance of the graph.
230
233
  config: The config of the graph.
234
+ locale: The locale code used for Plotly formatting and modebar labels.
231
235
  use_resize_handler: If true, the graph will resize when the window is resized.
232
236
  style: The style of the component.
233
237
  key: A unique key for the component.
@@ -276,7 +280,7 @@ class PlotlyBasic(Plotly):
276
280
  """
277
281
 
278
282
  class PlotlyCartesian(Plotly):
279
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
283
+ def add_imports(self) -> ImportDict: ...
280
284
  @classmethod
281
285
  def create(
282
286
  cls,
@@ -285,6 +289,7 @@ class PlotlyCartesian(Plotly):
285
289
  layout: Var[dict] | dict | None = None,
286
290
  template: Any | Var[Any] | None = None,
287
291
  config: Var[dict] | dict | None = None,
292
+ locale: Var[str] | str | None = None,
288
293
  use_resize_handler: Var[bool] | bool | None = None,
289
294
  style: Sequence[Mapping[str, Any]]
290
295
  | Mapping[str, Any]
@@ -340,6 +345,7 @@ class PlotlyCartesian(Plotly):
340
345
  layout: The layout of the graph.
341
346
  template: The template for visual appearance of the graph.
342
347
  config: The config of the graph.
348
+ locale: The locale code used for Plotly formatting and modebar labels.
343
349
  use_resize_handler: If true, the graph will resize when the window is resized.
344
350
  style: The style of the component.
345
351
  key: A unique key for the component.
@@ -388,7 +394,7 @@ class PlotlyCartesian(Plotly):
388
394
  """
389
395
 
390
396
  class PlotlyGeo(Plotly):
391
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
397
+ def add_imports(self) -> ImportDict: ...
392
398
  @classmethod
393
399
  def create(
394
400
  cls,
@@ -397,6 +403,7 @@ class PlotlyGeo(Plotly):
397
403
  layout: Var[dict] | dict | None = None,
398
404
  template: Any | Var[Any] | None = None,
399
405
  config: Var[dict] | dict | None = None,
406
+ locale: Var[str] | str | None = None,
400
407
  use_resize_handler: Var[bool] | bool | None = None,
401
408
  style: Sequence[Mapping[str, Any]]
402
409
  | Mapping[str, Any]
@@ -452,6 +459,7 @@ class PlotlyGeo(Plotly):
452
459
  layout: The layout of the graph.
453
460
  template: The template for visual appearance of the graph.
454
461
  config: The config of the graph.
462
+ locale: The locale code used for Plotly formatting and modebar labels.
455
463
  use_resize_handler: If true, the graph will resize when the window is resized.
456
464
  style: The style of the component.
457
465
  key: A unique key for the component.
@@ -500,7 +508,7 @@ class PlotlyGeo(Plotly):
500
508
  """
501
509
 
502
510
  class PlotlyGl3d(Plotly):
503
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
511
+ def add_imports(self) -> ImportDict: ...
504
512
  @classmethod
505
513
  def create(
506
514
  cls,
@@ -509,6 +517,7 @@ class PlotlyGl3d(Plotly):
509
517
  layout: Var[dict] | dict | None = None,
510
518
  template: Any | Var[Any] | None = None,
511
519
  config: Var[dict] | dict | None = None,
520
+ locale: Var[str] | str | None = None,
512
521
  use_resize_handler: Var[bool] | bool | None = None,
513
522
  style: Sequence[Mapping[str, Any]]
514
523
  | Mapping[str, Any]
@@ -564,6 +573,7 @@ class PlotlyGl3d(Plotly):
564
573
  layout: The layout of the graph.
565
574
  template: The template for visual appearance of the graph.
566
575
  config: The config of the graph.
576
+ locale: The locale code used for Plotly formatting and modebar labels.
567
577
  use_resize_handler: If true, the graph will resize when the window is resized.
568
578
  style: The style of the component.
569
579
  key: A unique key for the component.
@@ -612,7 +622,7 @@ class PlotlyGl3d(Plotly):
612
622
  """
613
623
 
614
624
  class PlotlyGl2d(Plotly):
615
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
625
+ def add_imports(self) -> ImportDict: ...
616
626
  @classmethod
617
627
  def create(
618
628
  cls,
@@ -621,6 +631,7 @@ class PlotlyGl2d(Plotly):
621
631
  layout: Var[dict] | dict | None = None,
622
632
  template: Any | Var[Any] | None = None,
623
633
  config: Var[dict] | dict | None = None,
634
+ locale: Var[str] | str | None = None,
624
635
  use_resize_handler: Var[bool] | bool | None = None,
625
636
  style: Sequence[Mapping[str, Any]]
626
637
  | Mapping[str, Any]
@@ -676,6 +687,7 @@ class PlotlyGl2d(Plotly):
676
687
  layout: The layout of the graph.
677
688
  template: The template for visual appearance of the graph.
678
689
  config: The config of the graph.
690
+ locale: The locale code used for Plotly formatting and modebar labels.
679
691
  use_resize_handler: If true, the graph will resize when the window is resized.
680
692
  style: The style of the component.
681
693
  key: A unique key for the component.
@@ -724,7 +736,7 @@ class PlotlyGl2d(Plotly):
724
736
  """
725
737
 
726
738
  class PlotlyMapbox(Plotly):
727
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
739
+ def add_imports(self) -> ImportDict: ...
728
740
  @classmethod
729
741
  def create(
730
742
  cls,
@@ -733,6 +745,7 @@ class PlotlyMapbox(Plotly):
733
745
  layout: Var[dict] | dict | None = None,
734
746
  template: Any | Var[Any] | None = None,
735
747
  config: Var[dict] | dict | None = None,
748
+ locale: Var[str] | str | None = None,
736
749
  use_resize_handler: Var[bool] | bool | None = None,
737
750
  style: Sequence[Mapping[str, Any]]
738
751
  | Mapping[str, Any]
@@ -788,6 +801,7 @@ class PlotlyMapbox(Plotly):
788
801
  layout: The layout of the graph.
789
802
  template: The template for visual appearance of the graph.
790
803
  config: The config of the graph.
804
+ locale: The locale code used for Plotly formatting and modebar labels.
791
805
  use_resize_handler: If true, the graph will resize when the window is resized.
792
806
  style: The style of the component.
793
807
  key: A unique key for the component.
@@ -836,7 +850,7 @@ class PlotlyMapbox(Plotly):
836
850
  """
837
851
 
838
852
  class PlotlyFinance(Plotly):
839
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
853
+ def add_imports(self) -> ImportDict: ...
840
854
  @classmethod
841
855
  def create(
842
856
  cls,
@@ -845,6 +859,7 @@ class PlotlyFinance(Plotly):
845
859
  layout: Var[dict] | dict | None = None,
846
860
  template: Any | Var[Any] | None = None,
847
861
  config: Var[dict] | dict | None = None,
862
+ locale: Var[str] | str | None = None,
848
863
  use_resize_handler: Var[bool] | bool | None = None,
849
864
  style: Sequence[Mapping[str, Any]]
850
865
  | Mapping[str, Any]
@@ -900,6 +915,7 @@ class PlotlyFinance(Plotly):
900
915
  layout: The layout of the graph.
901
916
  template: The template for visual appearance of the graph.
902
917
  config: The config of the graph.
918
+ locale: The locale code used for Plotly formatting and modebar labels.
903
919
  use_resize_handler: If true, the graph will resize when the window is resized.
904
920
  style: The style of the component.
905
921
  key: A unique key for the component.
@@ -948,7 +964,7 @@ class PlotlyFinance(Plotly):
948
964
  """
949
965
 
950
966
  class PlotlyStrict(Plotly):
951
- def add_imports(self) -> ImportDict | list[ImportDict]: ...
967
+ def add_imports(self) -> ImportDict: ...
952
968
  @classmethod
953
969
  def create(
954
970
  cls,
@@ -957,6 +973,7 @@ class PlotlyStrict(Plotly):
957
973
  layout: Var[dict] | dict | None = None,
958
974
  template: Any | Var[Any] | None = None,
959
975
  config: Var[dict] | dict | None = None,
976
+ locale: Var[str] | str | None = None,
960
977
  use_resize_handler: Var[bool] | bool | None = None,
961
978
  style: Sequence[Mapping[str, Any]]
962
979
  | Mapping[str, Any]
@@ -1012,6 +1029,7 @@ class PlotlyStrict(Plotly):
1012
1029
  layout: The layout of the graph.
1013
1030
  template: The template for visual appearance of the graph.
1014
1031
  config: The config of the graph.
1032
+ locale: The locale code used for Plotly formatting and modebar labels.
1015
1033
  use_resize_handler: If true, the graph will resize when the window is resized.
1016
1034
  style: The style of the component.
1017
1035
  key: A unique key for the component.