dr-widget 0.2.0__tar.gz → 0.2.2__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.
Files changed (145) hide show
  1. {dr_widget-0.2.0 → dr_widget-0.2.2}/PKG-INFO +10 -28
  2. {dr_widget-0.2.0 → dr_widget-0.2.2}/README.md +9 -27
  3. {dr_widget-0.2.0 → dr_widget-0.2.2}/pyproject.toml +7 -2
  4. dr_widget-0.2.2/src/dr_widget/bundled/runtime/.gitignore +2 -0
  5. dr_widget-0.2.2/src/dr_widget/bundled/runtime/index.html +30 -0
  6. dr_widget-0.2.2/src/dr_widget/bundled/runtime/package.json +25 -0
  7. dr_widget-0.2.2/src/dr_widget/bundled/runtime/parity.html +30 -0
  8. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/components/Hello.tsx +8 -0
  9. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/components/PropsPanel.tsx +30 -0
  10. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/data-channel.ts +52 -0
  11. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/define-element.tsx +127 -0
  12. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/globals.d.ts +23 -0
  13. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/index.tsx +17 -0
  14. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/layout.ts +41 -0
  15. dr_widget-0.2.2/src/dr_widget/bundled/runtime/src/parse-props.ts +85 -0
  16. dr_widget-0.2.2/src/dr_widget/bundled/runtime/static/runtime.js +40 -0
  17. dr_widget-0.2.2/src/dr_widget/bundled/runtime/tsconfig.json +20 -0
  18. dr_widget-0.2.2/src/dr_widget/bundled/runtime/vite.config.js +24 -0
  19. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/inline/__init__.py +2 -1
  20. dr_widget-0.2.2/src/dr_widget/inline/runtime_loader.py +40 -0
  21. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/__init__.py +0 -0
  22. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/__init__.py +0 -0
  23. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/.gitignore +0 -0
  24. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/.vscode/extensions.json +0 -0
  25. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/README.md +0 -0
  26. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/__init__.py +0 -0
  27. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/components.json +0 -0
  28. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/index.html +0 -0
  29. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/jsrepo.json +0 -0
  30. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/package.json +0 -0
  31. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/postcss.config.js +0 -0
  32. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/public/fonts/Inter-roman.var.woff2 +0 -0
  33. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/public/vite.svg +0 -0
  34. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/App.svelte +0 -0
  35. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/ConfigFileManager.svelte +0 -0
  36. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/app.css +0 -0
  37. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/index.js +0 -0
  38. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/@test_state.json +0 -0
  39. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/Counter.svelte +0 -0
  40. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/BrowseConfigsPanel.svelte +0 -0
  41. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/ComplexJsonViewer.svelte +0 -0
  42. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/ConfigViewerPanel.svelte +0 -0
  43. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/LoadedConfigPreview.svelte +0 -0
  44. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/SaveConfigPanel.svelte +0 -0
  45. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/SelectedFileRow.svelte +0 -0
  46. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/SelectedFilesList.svelte +0 -0
  47. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/file-drop/SimpleJsonViewer.svelte +0 -0
  48. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/badge/badge.svelte +0 -0
  49. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/badge/index.ts +0 -0
  50. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/button/button.svelte +0 -0
  51. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/button/index.ts +0 -0
  52. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-action.svelte +0 -0
  53. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-content.svelte +0 -0
  54. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-description.svelte +0 -0
  55. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-footer.svelte +0 -0
  56. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-header.svelte +0 -0
  57. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card-title.svelte +0 -0
  58. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/card.svelte +0 -0
  59. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/card/index.ts +0 -0
  60. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-close.svelte +0 -0
  61. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-content.svelte +0 -0
  62. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-description.svelte +0 -0
  63. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-footer.svelte +0 -0
  64. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-header.svelte +0 -0
  65. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-overlay.svelte +0 -0
  66. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-title.svelte +0 -0
  67. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/dialog-trigger.svelte +0 -0
  68. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/dialog/index.ts +0 -0
  69. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-close.svelte +0 -0
  70. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-content.svelte +0 -0
  71. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-description.svelte +0 -0
  72. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-footer.svelte +0 -0
  73. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-header.svelte +0 -0
  74. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-nested.svelte +0 -0
  75. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-overlay.svelte +0 -0
  76. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-title.svelte +0 -0
  77. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer-trigger.svelte +0 -0
  78. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/drawer.svelte +0 -0
  79. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/drawer/index.ts +0 -0
  80. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty-content.svelte +0 -0
  81. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty-description.svelte +0 -0
  82. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty-header.svelte +0 -0
  83. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty-media.svelte +0 -0
  84. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty-title.svelte +0 -0
  85. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/empty.svelte +0 -0
  86. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/empty/index.ts +0 -0
  87. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-content.svelte +0 -0
  88. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-description.svelte +0 -0
  89. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-error.svelte +0 -0
  90. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-group.svelte +0 -0
  91. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-label.svelte +0 -0
  92. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-legend.svelte +0 -0
  93. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-separator.svelte +0 -0
  94. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-set.svelte +0 -0
  95. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field-title.svelte +0 -0
  96. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/field.svelte +0 -0
  97. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/field/index.ts +0 -0
  98. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/file-drop-zone/file-drop-zone.svelte +0 -0
  99. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/file-drop-zone/index.ts +0 -0
  100. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/file-drop-zone/types.ts +0 -0
  101. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/index.ts +0 -0
  102. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-actions.svelte +0 -0
  103. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-content.svelte +0 -0
  104. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-description.svelte +0 -0
  105. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-footer.svelte +0 -0
  106. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-group.svelte +0 -0
  107. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-header.svelte +0 -0
  108. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-media.svelte +0 -0
  109. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-separator.svelte +0 -0
  110. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item-title.svelte +0 -0
  111. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/item/item.svelte +0 -0
  112. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/label/index.ts +0 -0
  113. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/label/label.svelte +0 -0
  114. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/index.ts +0 -0
  115. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-content.svelte +0 -0
  116. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-description.svelte +0 -0
  117. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-footer.svelte +0 -0
  118. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-header.svelte +0 -0
  119. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-title.svelte +0 -0
  120. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal-trigger.svelte +0 -0
  121. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal.svelte +0 -0
  122. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/modal/modal.svelte.ts +0 -0
  123. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/separator/index.ts +0 -0
  124. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/separator/separator.svelte +0 -0
  125. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/tabs/index.ts +0 -0
  126. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/tabs/tabs-content.svelte +0 -0
  127. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/tabs/tabs-list.svelte +0 -0
  128. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/tabs/tabs-trigger.svelte +0 -0
  129. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/components/ui/tabs/tabs.svelte +0 -0
  130. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/hooks/use-file-bindings.ts +0 -0
  131. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/react/JsonTreeCanvas.tsx +0 -0
  132. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/utils/config-format.ts +0 -0
  133. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/utils/utils.ts +0 -0
  134. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/lib/utils.ts +0 -0
  135. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/src/main.js +0 -0
  136. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/static/fonts/Inter-roman.var.woff2 +0 -0
  137. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/static/index.js +0 -0
  138. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/static/style.css +0 -0
  139. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/static/vite.svg +0 -0
  140. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/svelte.config.js +0 -0
  141. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/tailwind.config.js +0 -0
  142. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/tsconfig.json +0 -0
  143. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/bundled/config_file_manager/vite.config.js +0 -0
  144. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/inline/active_html.py +0 -0
  145. {dr_widget-0.2.0 → dr_widget-0.2.2}/src/dr_widget/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dr-widget
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Widgets to use with marimo notebooks
5
5
  Author: Danielle Rothermel
6
6
  Author-email: Danielle Rothermel <danielle.rothermel@gmail.com>
@@ -22,35 +22,18 @@ The top-level `dr_widget` package is intentionally empty so importing from one t
22
22
 
23
23
  ## Quick Start
24
24
 
25
- ```bash
26
- # Install JS dependencies (root + workspace)
27
- bun install
28
-
29
- # Live-reload the Config File Manager widget in a browser
30
- bun run dev:config-file-manager
31
-
32
- # Produce the optimized bundle used by AnyWidget
33
- bun run build
34
-
35
- # Build the Python distributions (wheel + sdist)
36
- uv build
37
-
38
- # Launch the Marimo demo notebook
39
- marimo run notebooks/config_file_manager_widget.py
40
- ```
41
-
42
- Prerequisites: Bun ≥ 1.0, Node-compatible environment, Python ≥ 3.11 with `uv`, and Marimo ≥ 0.23.
25
+ See [Development Workflow](docs/development.md) for install, build, packaging, and
26
+ notebook commands.
43
27
 
44
28
  ## Repository Layout
45
29
 
46
30
  - `src/dr_widget/` – Python package with two widget tiers.
47
- - `inline/` – pure-Python AnyWidgets (e.g., `ActiveHtml`) with `_esm` as a string literal.
48
- - `bundled/config_file_manager/` – bundled widget workspace (Svelte source in `src/`, build output in `static/`).
49
- - `src/ConfigFileManager.svelte`orchestration layer wiring bindings into the panel components.
50
- - `src/lib/hooks/use-file-bindings.ts` – shared logic for syncing AnyWidget traitlets.
51
- - `src/lib/components/` – shadcn-style UI primitives and panels, including a config viewer card with both a tree view and graph view for JSON payloads.
31
+ - `inline/` – pure-Python AnyWidgets (e.g., `ActiveHtml`, `load_dr_runtime()`).
32
+ - `bundled/config_file_manager/` – Svelte widget workspace (source in `src/`, build output in `static/`).
33
+ - `bundled/runtime/`React custom-element runtime (`static/runtime.js`); proof element `<dr-hello>`.
52
34
  - `docs/` – additional reference material (architecture, development workflows).
53
- - `notebooks/config_file_manager_widget.py` – Marimo notebook that exercises the Config File Manager widget.
35
+ - `notebooks/config_file_manager_widget.py` – Marimo notebook for the Config File Manager widget.
36
+ - `notebooks/runtime_hello_widget.py` – Marimo notebook for `load_dr_runtime()` + `<dr-hello>`.
54
37
 
55
38
  ## Documentation
56
39
 
@@ -61,8 +44,7 @@ Prerequisites: Bun ≥ 1.0, Node-compatible environment, Python ≥ 3.11 with `u
61
44
  ## Contributing
62
45
 
63
46
  1. Work inside a dedicated branch.
64
- 2. Run `bun run build`, `npx svelte-check`, and `uv build` before opening a PR.
65
- 3. Update the notebook and docs when you add or change widget behaviour.
66
- 4. Follow the commit and PR practices outlined in `AGENTS.md`.
47
+ 2. Follow [docs/development.md](docs/development.md) and [AGENTS.md](AGENTS.md) before opening a PR.
48
+ 3. Update notebooks and docs when you add or change widget behaviour.
67
49
 
68
50
  Please open an issue if you hit build problems or want to discuss new widgets.
@@ -9,35 +9,18 @@ The top-level `dr_widget` package is intentionally empty so importing from one t
9
9
 
10
10
  ## Quick Start
11
11
 
12
- ```bash
13
- # Install JS dependencies (root + workspace)
14
- bun install
15
-
16
- # Live-reload the Config File Manager widget in a browser
17
- bun run dev:config-file-manager
18
-
19
- # Produce the optimized bundle used by AnyWidget
20
- bun run build
21
-
22
- # Build the Python distributions (wheel + sdist)
23
- uv build
24
-
25
- # Launch the Marimo demo notebook
26
- marimo run notebooks/config_file_manager_widget.py
27
- ```
28
-
29
- Prerequisites: Bun ≥ 1.0, Node-compatible environment, Python ≥ 3.11 with `uv`, and Marimo ≥ 0.23.
12
+ See [Development Workflow](docs/development.md) for install, build, packaging, and
13
+ notebook commands.
30
14
 
31
15
  ## Repository Layout
32
16
 
33
17
  - `src/dr_widget/` – Python package with two widget tiers.
34
- - `inline/` – pure-Python AnyWidgets (e.g., `ActiveHtml`) with `_esm` as a string literal.
35
- - `bundled/config_file_manager/` – bundled widget workspace (Svelte source in `src/`, build output in `static/`).
36
- - `src/ConfigFileManager.svelte`orchestration layer wiring bindings into the panel components.
37
- - `src/lib/hooks/use-file-bindings.ts` – shared logic for syncing AnyWidget traitlets.
38
- - `src/lib/components/` – shadcn-style UI primitives and panels, including a config viewer card with both a tree view and graph view for JSON payloads.
18
+ - `inline/` – pure-Python AnyWidgets (e.g., `ActiveHtml`, `load_dr_runtime()`).
19
+ - `bundled/config_file_manager/` – Svelte widget workspace (source in `src/`, build output in `static/`).
20
+ - `bundled/runtime/`React custom-element runtime (`static/runtime.js`); proof element `<dr-hello>`.
39
21
  - `docs/` – additional reference material (architecture, development workflows).
40
- - `notebooks/config_file_manager_widget.py` – Marimo notebook that exercises the Config File Manager widget.
22
+ - `notebooks/config_file_manager_widget.py` – Marimo notebook for the Config File Manager widget.
23
+ - `notebooks/runtime_hello_widget.py` – Marimo notebook for `load_dr_runtime()` + `<dr-hello>`.
41
24
 
42
25
  ## Documentation
43
26
 
@@ -48,8 +31,7 @@ Prerequisites: Bun ≥ 1.0, Node-compatible environment, Python ≥ 3.11 with `u
48
31
  ## Contributing
49
32
 
50
33
  1. Work inside a dedicated branch.
51
- 2. Run `bun run build`, `npx svelte-check`, and `uv build` before opening a PR.
52
- 3. Update the notebook and docs when you add or change widget behaviour.
53
- 4. Follow the commit and PR practices outlined in `AGENTS.md`.
34
+ 2. Follow [docs/development.md](docs/development.md) and [AGENTS.md](AGENTS.md) before opening a PR.
35
+ 3. Update notebooks and docs when you add or change widget behaviour.
54
36
 
55
37
  Please open an issue if you hit build problems or want to discuss new widgets.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dr-widget"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "Widgets to use with marimo notebooks"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -19,10 +19,15 @@ requires = ["uv_build>=0.9.7,<0.10.0"]
19
19
  build-backend = "uv_build"
20
20
 
21
21
  [tool.uv.build-backend]
22
- source-include = ["src/dr_widget/bundled/config_file_manager/static/**"]
22
+ source-include = [
23
+ "src/dr_widget/bundled/config_file_manager/static/**",
24
+ "src/dr_widget/bundled/runtime/static/**",
25
+ ]
23
26
  source-exclude = [
24
27
  "src/dr_widget/bundled/config_file_manager/node_modules",
25
28
  "src/dr_widget/bundled/config_file_manager/node_modules/**",
29
+ "src/dr_widget/bundled/runtime/node_modules",
30
+ "src/dr_widget/bundled/runtime/node_modules/**",
26
31
  ]
27
32
 
28
33
  [dependency-groups]
@@ -0,0 +1,2 @@
1
+ node_modules
2
+ *.local
@@ -0,0 +1,30 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>dr-hello runtime demo</title>
7
+ </head>
8
+ <body>
9
+ <h1>dr_widget runtime demo</h1>
10
+ <p>
11
+ <dr-hello id="hello" name="World"></dr-hello>
12
+ </p>
13
+ <label>
14
+ Name
15
+ <input id="name-input" type="text" value="World" />
16
+ </label>
17
+ <button id="apply-name" type="button">Apply name attribute</button>
18
+
19
+ <script type="module" src="/src/index.tsx"></script>
20
+ <script type="module">
21
+ const hello = document.getElementById('hello');
22
+ const input = document.getElementById('name-input');
23
+ const button = document.getElementById('apply-name');
24
+
25
+ button.addEventListener('click', () => {
26
+ hello.setAttribute('name', input.value);
27
+ });
28
+ </script>
29
+ </body>
30
+ </html>
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@dr-widget/runtime",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "vite build",
8
+ "dev": "vite dev",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "react": "18.2.0",
13
+ "react-dom": "18.2.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/bun": "latest",
17
+ "@types/react": "18.2.74",
18
+ "@types/react-dom": "18.2.25",
19
+ "@vitejs/plugin-react-swc": "3.7.0",
20
+ "vite": "^5.4.11"
21
+ },
22
+ "peerDependencies": {
23
+ "typescript": "^5.9.3"
24
+ }
25
+ }
@@ -0,0 +1,30 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>dr-hello built runtime parity</title>
7
+ </head>
8
+ <body>
9
+ <h1>Built runtime parity</h1>
10
+ <p>
11
+ <dr-hello id="hello" name="World"></dr-hello>
12
+ </p>
13
+ <label>
14
+ Name
15
+ <input id="name-input" type="text" value="World" />
16
+ </label>
17
+ <button id="apply-name" type="button">Apply name attribute</button>
18
+
19
+ <script src="./static/runtime.js"></script>
20
+ <script>
21
+ const hello = document.getElementById('hello');
22
+ const input = document.getElementById('name-input');
23
+ const button = document.getElementById('apply-name');
24
+
25
+ button.addEventListener('click', () => {
26
+ hello.setAttribute('name', input.value);
27
+ });
28
+ </script>
29
+ </body>
30
+ </html>
@@ -0,0 +1,8 @@
1
+ type HelloProps = {
2
+ name?: string;
3
+ };
4
+
5
+ export function Hello({ name }: HelloProps) {
6
+ const label = name?.trim() || 'World';
7
+ return <span>Hello, {label}!</span>;
8
+ }
@@ -0,0 +1,30 @@
1
+ type PropsPanelProps = {
2
+ title?: string;
3
+ items?: string[];
4
+ __dataRef?: string;
5
+ };
6
+
7
+ export function PropsPanel({ title, items }: PropsPanelProps) {
8
+ const heading =
9
+ typeof title === 'string' && title.trim().length > 0
10
+ ? title.trim()
11
+ : 'Props panel';
12
+ const rows = Array.isArray(items)
13
+ ? items.filter((item): item is string => typeof item === 'string')
14
+ : [];
15
+
16
+ return (
17
+ <div>
18
+ <strong>{heading}</strong>
19
+ {rows.length > 0 ? (
20
+ <ul>
21
+ {rows.map((item) => (
22
+ <li key={item}>{item}</li>
23
+ ))}
24
+ </ul>
25
+ ) : (
26
+ <p>No items.</p>
27
+ )}
28
+ </div>
29
+ );
30
+ }
@@ -0,0 +1,52 @@
1
+ export type DataChannelListener = (payload: unknown) => void;
2
+
3
+ export type DataChannel = {
4
+ set: (id: string, payload: unknown) => void;
5
+ get: (id: string) => unknown;
6
+ delete: (id: string) => void;
7
+ subscribe: (id: string, listener: DataChannelListener) => () => void;
8
+ };
9
+
10
+ export function createDataChannel(): DataChannel {
11
+ const payloads = new Map<string, unknown>();
12
+ const listeners = new Map<string, Set<DataChannelListener>>();
13
+
14
+ function notify(id: string, payload: unknown): void {
15
+ const subs = listeners.get(id);
16
+ if (!subs) {
17
+ return;
18
+ }
19
+ for (const listener of subs) {
20
+ listener(payload);
21
+ }
22
+ }
23
+
24
+ return {
25
+ set(id, payload) {
26
+ payloads.set(id, payload);
27
+ notify(id, payload);
28
+ },
29
+ get(id) {
30
+ return payloads.get(id);
31
+ },
32
+ delete(id) {
33
+ payloads.delete(id);
34
+ notify(id, undefined);
35
+ },
36
+ subscribe(id, listener) {
37
+ let subs = listeners.get(id);
38
+ if (!subs) {
39
+ subs = new Set();
40
+ listeners.set(id, subs);
41
+ }
42
+ subs.add(listener);
43
+ const currentSubs = subs;
44
+ return () => {
45
+ currentSubs.delete(listener);
46
+ if (currentSubs.size === 0 && listeners.get(id) === currentSubs) {
47
+ listeners.delete(id);
48
+ }
49
+ };
50
+ },
51
+ };
52
+ }
@@ -0,0 +1,127 @@
1
+ import {
2
+ createRoot,
3
+ type ComponentType,
4
+ type Root,
5
+ } from 'react-dom/client';
6
+
7
+ import type { DataChannel } from './data-channel';
8
+ import {
9
+ DEFAULT_DATA_REF_ATTRIBUTE,
10
+ DEFAULT_PROPS_ATTRIBUTE,
11
+ parseElementProps,
12
+ readDataRef,
13
+ type ParsePropsOptions,
14
+ } from './parse-props';
15
+
16
+ export type DrElementOptions<P extends Record<string, unknown>> =
17
+ ParsePropsOptions & {
18
+ parseProps?: (
19
+ element: HTMLElement,
20
+ dataChannel: DataChannel,
21
+ ) => P;
22
+ };
23
+
24
+ function isOptions<P extends Record<string, unknown>>(
25
+ value: readonly string[] | DrElementOptions<P>,
26
+ ): value is DrElementOptions<P> {
27
+ return !Array.isArray(value);
28
+ }
29
+
30
+ function resolveOptions<P extends Record<string, unknown>>(
31
+ observedAttributesOrOptions: readonly string[] | DrElementOptions<P>,
32
+ ): DrElementOptions<P> {
33
+ if (isOptions(observedAttributesOrOptions)) {
34
+ return observedAttributesOrOptions;
35
+ }
36
+ return { observedAttributes: observedAttributesOrOptions };
37
+ }
38
+
39
+ export function defineDrElement<P extends Record<string, unknown>>(
40
+ tag: string,
41
+ Component: ComponentType<P>,
42
+ observedAttributesOrOptions: readonly string[] | DrElementOptions<P>,
43
+ dataChannel: DataChannel,
44
+ ): void {
45
+ if (customElements.get(tag)) {
46
+ return;
47
+ }
48
+
49
+ const options = resolveOptions(observedAttributesOrOptions);
50
+ const propsAttribute = options.propsAttribute ?? DEFAULT_PROPS_ATTRIBUTE;
51
+ const dataRefAttribute = options.dataRefAttribute ?? DEFAULT_DATA_REF_ATTRIBUTE;
52
+
53
+ const readProps = (element: HTMLElement): P => {
54
+ if (options.parseProps) {
55
+ return options.parseProps(element, dataChannel);
56
+ }
57
+ return parseElementProps(element, dataChannel, options) as P;
58
+ };
59
+
60
+ class DrElement extends HTMLElement {
61
+ static get observedAttributes() {
62
+ const attrs = new Set<string>(options.observedAttributes ?? []);
63
+ attrs.add(propsAttribute);
64
+ attrs.add(dataRefAttribute);
65
+ return [...attrs];
66
+ }
67
+
68
+ #root: Root | null = null;
69
+ #unsubscribeData: (() => void) | null = null;
70
+
71
+ connectedCallback() {
72
+ this.#root = createRoot(this);
73
+ this.#bindDataChannel();
74
+ this.#render();
75
+ }
76
+
77
+ attributeChangedCallback(
78
+ name: string,
79
+ oldValue: string | null,
80
+ newValue: string | null,
81
+ ) {
82
+ if (oldValue === newValue) {
83
+ return;
84
+ }
85
+ if (!this.isConnected) {
86
+ return;
87
+ }
88
+ if (name === dataRefAttribute) {
89
+ this.#bindDataChannel();
90
+ }
91
+ this.#render();
92
+ }
93
+
94
+ disconnectedCallback() {
95
+ this.#unsubscribeData?.();
96
+ this.#unsubscribeData = null;
97
+ this.#root?.unmount();
98
+ this.#root = null;
99
+ }
100
+
101
+ #bindDataChannel() {
102
+ this.#unsubscribeData?.();
103
+ this.#unsubscribeData = null;
104
+
105
+ const dataRef = readDataRef(this, dataRefAttribute);
106
+ if (!dataRef) {
107
+ return;
108
+ }
109
+
110
+ this.#unsubscribeData = dataChannel.subscribe(dataRef, () => {
111
+ this.#render();
112
+ });
113
+ }
114
+
115
+ #render() {
116
+ if (!this.#root) {
117
+ return;
118
+ }
119
+ this.#root.render(<Component {...readProps(this)} />);
120
+ }
121
+ }
122
+
123
+ customElements.define(tag, DrElement);
124
+ }
125
+
126
+ export { whenLayoutReady } from './layout';
127
+ export type { LayoutReadyCallback } from './layout';
@@ -0,0 +1,23 @@
1
+ import type { ComponentType } from 'react';
2
+
3
+ import type { DataChannel } from './data-channel';
4
+ import type { DrElementOptions } from './define-element';
5
+
6
+ export type DrRuntime = {
7
+ defineDrElement: <P extends Record<string, unknown>>(
8
+ tag: string,
9
+ Component: ComponentType<P>,
10
+ observedAttributesOrOptions: readonly string[] | DrElementOptions<P>,
11
+ ) => void;
12
+ data: DataChannel;
13
+ version: string;
14
+ };
15
+
16
+ declare global {
17
+ interface Window {
18
+ __drRuntime?: DrRuntime;
19
+ __drRuntimeLoaded?: boolean;
20
+ }
21
+ }
22
+
23
+ export {};
@@ -0,0 +1,17 @@
1
+ import { Hello } from './components/Hello';
2
+ import { PropsPanel } from './components/PropsPanel';
3
+ import { createDataChannel } from './data-channel';
4
+ import { defineDrElement } from './define-element';
5
+
6
+ const RUNTIME_VERSION = '0.2.0';
7
+ const dataChannel = createDataChannel();
8
+
9
+ defineDrElement('dr-hello', Hello, ['name'], dataChannel);
10
+ defineDrElement('dr-props-panel', PropsPanel, [], dataChannel);
11
+
12
+ window.__drRuntime = {
13
+ defineDrElement: (tag, Component, observedAttributesOrOptions) =>
14
+ defineDrElement(tag, Component, observedAttributesOrOptions, dataChannel),
15
+ data: dataChannel,
16
+ version: RUNTIME_VERSION,
17
+ };
@@ -0,0 +1,41 @@
1
+ export type LayoutReadyCallback = (element: HTMLElement) => void;
2
+
3
+ /**
4
+ * Run `callback` once the element has non-zero layout dimensions.
5
+ *
6
+ * Design rule 2: never read geometry in `connectedCallback` — layout may not
7
+ * be ready yet. Prefer this helper (rAF + ResizeObserver) for sizing work.
8
+ */
9
+ export function whenLayoutReady(
10
+ element: HTMLElement,
11
+ callback: LayoutReadyCallback,
12
+ ): () => void {
13
+ let cancelled = false;
14
+ let completed = false;
15
+ let observer: ResizeObserver | null = null;
16
+
17
+ const run = () => {
18
+ if (cancelled || completed) {
19
+ return;
20
+ }
21
+ if (element.clientWidth > 0 || element.clientHeight > 0) {
22
+ completed = true;
23
+ callback(element);
24
+ observer?.disconnect();
25
+ observer = null;
26
+ return;
27
+ }
28
+ requestAnimationFrame(run);
29
+ };
30
+
31
+ observer = new ResizeObserver(() => {
32
+ run();
33
+ });
34
+ observer.observe(element);
35
+ requestAnimationFrame(run);
36
+
37
+ return () => {
38
+ cancelled = true;
39
+ observer?.disconnect();
40
+ };
41
+ }
@@ -0,0 +1,85 @@
1
+ import type { DataChannel } from './data-channel';
2
+
3
+ export const DEFAULT_PROPS_ATTRIBUTE = 'data-props';
4
+ export const DEFAULT_DATA_REF_ATTRIBUTE = 'data-ref';
5
+
6
+ export type ParsePropsOptions = {
7
+ observedAttributes?: readonly string[];
8
+ propsAttribute?: string;
9
+ dataRefAttribute?: string;
10
+ };
11
+
12
+ export type ParsedProps = Record<string, unknown>;
13
+
14
+ function parseJsonAttribute(
15
+ element: HTMLElement,
16
+ attributeName: string,
17
+ ): ParsedProps | undefined {
18
+ const raw = element.getAttribute(attributeName);
19
+ if (raw === null) {
20
+ return undefined;
21
+ }
22
+ try {
23
+ const parsed: unknown = JSON.parse(raw);
24
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
25
+ return parsed as ParsedProps;
26
+ }
27
+ } catch {
28
+ console.warn(
29
+ `[dr-runtime] Invalid JSON in ${attributeName} on <${element.tagName.toLowerCase()}>`,
30
+ );
31
+ }
32
+ return undefined;
33
+ }
34
+
35
+ function mergeChannelPayload(
36
+ props: ParsedProps,
37
+ payload: unknown,
38
+ ): ParsedProps {
39
+ if (payload === undefined) {
40
+ return props;
41
+ }
42
+ if (
43
+ typeof payload === 'object' &&
44
+ payload !== null &&
45
+ !Array.isArray(payload)
46
+ ) {
47
+ return { ...props, ...(payload as ParsedProps) };
48
+ }
49
+ return { ...props, data: payload };
50
+ }
51
+
52
+ export function parseElementProps(
53
+ element: HTMLElement,
54
+ dataChannel: DataChannel,
55
+ options: ParsePropsOptions = {},
56
+ ): ParsedProps {
57
+ const props: ParsedProps = {};
58
+ const observedAttributes = options.observedAttributes ?? [];
59
+
60
+ for (const name of observedAttributes) {
61
+ props[name] = element.getAttribute(name) ?? undefined;
62
+ }
63
+
64
+ const propsAttribute = options.propsAttribute ?? DEFAULT_PROPS_ATTRIBUTE;
65
+ const jsonProps = parseJsonAttribute(element, propsAttribute);
66
+ if (jsonProps) {
67
+ Object.assign(props, jsonProps);
68
+ }
69
+
70
+ const dataRefAttribute = options.dataRefAttribute ?? DEFAULT_DATA_REF_ATTRIBUTE;
71
+ const dataRef = element.getAttribute(dataRefAttribute);
72
+ if (dataRef) {
73
+ props.__dataRef = dataRef;
74
+ return mergeChannelPayload(props, dataChannel.get(dataRef));
75
+ }
76
+
77
+ return props;
78
+ }
79
+
80
+ export function readDataRef(
81
+ element: HTMLElement,
82
+ dataRefAttribute: string = DEFAULT_DATA_REF_ATTRIBUTE,
83
+ ): string | undefined {
84
+ return element.getAttribute(dataRefAttribute) ?? undefined;
85
+ }