simple-module-pagebuilder 0.0.2__tar.gz → 0.0.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.
Files changed (209) hide show
  1. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/PKG-INFO +1 -1
  2. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/package.json +1 -1
  3. simple_module_pagebuilder-0.0.3/pagebuilder/components/blocks/Image.test.tsx +94 -0
  4. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Image.tsx +37 -3
  5. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/conversion/blocks-to-html.test.ts +24 -0
  6. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/conversion/blocks-to-html.ts +10 -2
  7. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/static/widgets-base.css +7 -0
  8. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/markdown.ts +8 -1
  9. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pyproject.toml +1 -1
  10. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/.gitignore +0 -0
  11. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/README.md +0 -0
  12. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/__init__.py +0 -0
  13. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/DiffSummary.tsx +0 -0
  14. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/ScheduledBadge.tsx +0 -0
  15. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/StatusBadge.tsx +0 -0
  16. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blockRegistry.test.ts +0 -0
  17. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blockRegistry.ts +0 -0
  18. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Button.tsx +0 -0
  19. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Columns.tsx +0 -0
  20. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Heading.tsx +0 -0
  21. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/MediaPicker.tsx +0 -0
  22. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Spacer.tsx +0 -0
  23. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/blocks/Text.tsx +0 -0
  24. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/editor/PageEditorToolbar.tsx +0 -0
  25. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/editor/RevisionHistoryPanel.tsx +0 -0
  26. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/editor/SchedulePanel.tsx +0 -0
  27. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/editor/SeoSettingsPanel.tsx +0 -0
  28. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/layoutPuckConfig.tsx +0 -0
  29. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/MediaFilters.tsx +0 -0
  30. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/MediaFolderSidebar.tsx +0 -0
  31. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/MediaGrid.tsx +0 -0
  32. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/MediaHeader.tsx +0 -0
  33. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/MediaUploadQueue.tsx +0 -0
  34. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/media/types.ts +0 -0
  35. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/migrateContent.test.ts +0 -0
  36. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/migrateContent.ts +0 -0
  37. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/puckConfig.test.tsx +0 -0
  38. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/puckConfig.tsx +0 -0
  39. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgetCatalog.test.tsx +0 -0
  40. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgetCatalog.ts +0 -0
  41. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/accent-text.tsx +0 -0
  42. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/disclosure-chevron.tsx +0 -0
  43. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/eyebrow-split-section.tsx +0 -0
  44. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/link-arrow.tsx +0 -0
  45. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/rich-text.tsx +0 -0
  46. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_internal/solid-icons.tsx +0 -0
  47. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/background-media.tsx +0 -0
  48. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/content-media.tsx +0 -0
  49. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/cta-button.tsx +0 -0
  50. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/empty-placeholder.tsx +0 -0
  51. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/eyebrow-text.tsx +0 -0
  52. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/heading.tsx +0 -0
  53. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/index.ts +0 -0
  54. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/mask.ts +0 -0
  55. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/section.tsx +0 -0
  56. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/social-icon.tsx +0 -0
  57. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/_shared/text-link.tsx +0 -0
  58. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/accordion-widget.tsx +0 -0
  59. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/alert-widget.tsx +0 -0
  60. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/app-store-badges-widget.tsx +0 -0
  61. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/article-cards-render.tsx +0 -0
  62. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/article-cards-widget.tsx +0 -0
  63. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/call-to-action-render.tsx +0 -0
  64. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/call-to-action-styles.ts +0 -0
  65. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/call-to-action-widget.tsx +0 -0
  66. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/carousel-widget.tsx +0 -0
  67. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/centered-hero-widget.tsx +0 -0
  68. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/colored-action-list-widget.tsx +0 -0
  69. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/column-widget.tsx +0 -0
  70. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/contact-cards-widget.tsx +0 -0
  71. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/contact-form-render.tsx +0 -0
  72. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/contact-form-widget.tsx +0 -0
  73. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/container-widget.tsx +0 -0
  74. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/definition-list-widget.tsx +0 -0
  75. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/divider-widget.tsx +0 -0
  76. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/eyebrow-section-widget.tsx +0 -0
  77. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/faq-render.tsx +0 -0
  78. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/faq-widget.tsx +0 -0
  79. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-card-widget.tsx +0 -0
  80. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-cards-render.tsx +0 -0
  81. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-cards-styles.ts +0 -0
  82. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-cards-widget.tsx +0 -0
  83. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-grid-widget.tsx +0 -0
  84. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/feature-showcase-widget.tsx +0 -0
  85. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/gallery-widget.tsx +0 -0
  86. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/grid-widget.tsx +0 -0
  87. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/hero-widget.tsx +0 -0
  88. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/html-widget.tsx +0 -0
  89. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/iframe-widget.tsx +0 -0
  90. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/leaderboard-widget.tsx +0 -0
  91. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/list-widget.tsx +0 -0
  92. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/logo-cloud-widget.tsx +0 -0
  93. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/markdown-widget.tsx +0 -0
  94. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/media-object-layout.ts +0 -0
  95. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/media-object-render.tsx +0 -0
  96. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/media-object-text.tsx +0 -0
  97. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/media-object-widget.tsx +0 -0
  98. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/newsletter-widget.tsx +0 -0
  99. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/page-header-widget.tsx +0 -0
  100. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/prose-section-widget.tsx +0 -0
  101. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/quote-widget.tsx +0 -0
  102. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/row-widget.tsx +0 -0
  103. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/section-intro-widget.tsx +0 -0
  104. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/signup-banner-widget.tsx +0 -0
  105. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/simple-action-list-widget.tsx +0 -0
  106. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/site-footer-widget.tsx +0 -0
  107. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/site-header-nav.tsx +0 -0
  108. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/site-header-widget.tsx +0 -0
  109. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/social-banner-widget.tsx +0 -0
  110. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/stats-widget.tsx +0 -0
  111. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/steps-widget.tsx +0 -0
  112. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/story-cards-widget.tsx +0 -0
  113. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/table-widget.tsx +0 -0
  114. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/tabs-widget.tsx +0 -0
  115. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/tags-widget.tsx +0 -0
  116. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/testimonial-widget.tsx +0 -0
  117. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/timeline-layout.ts +0 -0
  118. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/timeline-render.tsx +0 -0
  119. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/timeline-widget.tsx +0 -0
  120. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/under-construction-widget.tsx +0 -0
  121. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/video-widget.tsx +0 -0
  122. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/components/widgets/welcome-widget.tsx +0 -0
  123. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/contracts/__init__.py +0 -0
  124. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/contracts/events.py +0 -0
  125. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/contracts/schemas.py +0 -0
  126. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/conversion/index.ts +0 -0
  127. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/conversion/types.ts +0 -0
  128. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/deps.py +0 -0
  129. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/diff.py +0 -0
  130. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/__init__.py +0 -0
  131. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/__init__.py +0 -0
  132. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/_deps.py +0 -0
  133. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/layout.py +0 -0
  134. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/pages.py +0 -0
  135. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/revisions.py +0 -0
  136. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/uploads.py +0 -0
  137. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/api/workflow.py +0 -0
  138. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/seo.py +0 -0
  139. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/endpoints/views.py +0 -0
  140. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/checkbox-field.tsx +0 -0
  141. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/file-picker/file-gallery.tsx +0 -0
  142. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/file-picker/image-picker-field.tsx +0 -0
  143. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/file-picker/index.ts +0 -0
  144. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/file-picker/types.ts +0 -0
  145. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/index.ts +0 -0
  146. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/fields/media-adapter.ts +0 -0
  147. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/useAutosave.ts +0 -0
  148. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/useEditorForm.ts +0 -0
  149. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/useMediaUploads.ts +0 -0
  150. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/usePageRevisions.ts +0 -0
  151. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/usePageSchedule.ts +0 -0
  152. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/hooks/usePageWorkflow.ts +0 -0
  153. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/layout_service.py +0 -0
  154. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/media_images.py +0 -0
  155. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/media_queries.py +0 -0
  156. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/media_service.py +0 -0
  157. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/models.py +0 -0
  158. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/module.py +0 -0
  159. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/LayoutEditor.tsx +0 -0
  160. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/MediaLibrary.tsx +0 -0
  161. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/PageEditor.tsx +0 -0
  162. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/PageList.tsx +0 -0
  163. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/PendingReview.tsx +0 -0
  164. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/pages/PublicPage.tsx +0 -0
  165. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/permissions.py +0 -0
  166. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/py.typed +0 -0
  167. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/security.py +0 -0
  168. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/service/__init__.py +0 -0
  169. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/service/_common.py +0 -0
  170. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/service/_revisions.py +0 -0
  171. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/service/_workflow.py +0 -0
  172. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/services.py +0 -0
  173. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/settings.py +0 -0
  174. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/translation/apply.ts +0 -0
  175. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/translation/extract.ts +0 -0
  176. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/translation/index.ts +0 -0
  177. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/translation/translatable-fields.ts +0 -0
  178. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/translation/translation.test.ts +0 -0
  179. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/api.ts +0 -0
  180. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/datetime.ts +0 -0
  181. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/decorative-image.ts +0 -0
  182. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/editorSnapshot.ts +0 -0
  183. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/mediaApi.ts +0 -0
  184. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/mediaFormat.ts +0 -0
  185. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/pagesApi.ts +0 -0
  186. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/parse-list.ts +0 -0
  187. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/request.ts +0 -0
  188. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/slugify.ts +0 -0
  189. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/types.ts +0 -0
  190. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/pagebuilder/utils/widgetUtils.ts +0 -0
  191. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/conftest.py +0 -0
  192. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_approval_workflow.py +0 -0
  193. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_auth_gating.py +0 -0
  194. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_csrf.py +0 -0
  195. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_image_processing.py +0 -0
  196. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_media_security.py +0 -0
  197. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_module.py +0 -0
  198. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_pages_api.py +0 -0
  199. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_public_routes.py +0 -0
  200. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_public_view_headers.py +0 -0
  201. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_public_viewer.py +0 -0
  202. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_revision_notes_and_diff.py +0 -0
  203. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_revisions_api.py +0 -0
  204. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_scheduled_publish.py +0 -0
  205. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_seo_meta.py +0 -0
  206. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_site_layout.py +0 -0
  207. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_sitemap_robots.py +0 -0
  208. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tests/test_uploads_api.py +0 -0
  209. {simple_module_pagebuilder-0.0.2 → simple_module_pagebuilder-0.0.3}/tsconfig.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simple_module_pagebuilder
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Drag-and-drop visual page builder for simple_module apps
5
5
  Project-URL: Repository, https://github.com/antosubash/simple_module_python_modules
6
6
  Author-email: Anto Subash <antosubash@live.com>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simple-module-py/pagebuilder",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "private": true,
5
5
  "description": "Frontend assets for the PageBuilder module",
6
6
  "peerDependencies": {
@@ -0,0 +1,94 @@
1
+ import type { ReactElement } from 'react';
2
+ import { renderToStaticMarkup } from 'react-dom/server';
3
+ import { describe, expect, it } from 'vitest';
4
+
5
+ import { ImageBlock } from './Image';
6
+
7
+ // Puck passes its own `id`/`puck` props alongside the authored ones; the block
8
+ // reads none of them, so these tests supply the authored props alone.
9
+ const Image = ImageBlock.render as unknown as (props: Record<string, unknown>) => ReactElement;
10
+
11
+ const BASE = {
12
+ ...ImageBlock.defaultProps,
13
+ src: '/media/pagebuilder/atlas-map.jpg',
14
+ alt: 'The Global Canopy Atlas interactive map',
15
+ };
16
+
17
+ function html(props: Record<string, unknown> = {}): string {
18
+ return renderToStaticMarkup(<Image {...BASE} {...props} />);
19
+ }
20
+
21
+ describe('ImageBlock caption', () => {
22
+ it('offers a Caption field in the inspector', () => {
23
+ expect(ImageBlock.fields?.caption).toEqual({ type: 'text', label: 'Caption' });
24
+ });
25
+
26
+ it('defaults to no caption', () => {
27
+ expect(ImageBlock.defaultProps?.caption).toBe('');
28
+ });
29
+
30
+ it('renders the caption in a figcaption inside a figure', () => {
31
+ const markup = html({ caption: 'Image caption goes here, if CMS field is populated' });
32
+ expect(markup).toContain('<figure');
33
+ expect(markup).toContain('<figcaption');
34
+ expect(markup).toContain('Image caption goes here, if CMS field is populated');
35
+ });
36
+
37
+ it('takes the caption’s colour and metrics from the design pack', () => {
38
+ // A tenant restyles captions by overriding tokens, not by patching this
39
+ // block — same contract the widget set gives the rest of the page.
40
+ const markup = html({ caption: 'A caption' });
41
+ expect(markup).toContain('--pb-caption-color');
42
+ expect(markup).toContain('--pb-body-color');
43
+ expect(markup).toContain('--pb-caption-size');
44
+ });
45
+
46
+ it('keeps alt and caption separate', () => {
47
+ // alt is the accessible description, caption is visible prose; the two are
48
+ // rarely the same sentence, so neither may stand in for the other.
49
+ const markup = html({ alt: 'A map of the world', caption: 'Figure 1' });
50
+ expect(markup).toContain('alt="A map of the world"');
51
+ expect(markup).toContain('>Figure 1</figcaption>');
52
+ });
53
+
54
+ it('renders the caption as light markdown, like every other copy field', () => {
55
+ // Table, Carousel and CallToAction captions all go through renderRichText,
56
+ // so `**bold**` cannot mean one thing in one caption and another here.
57
+ expect(html({ caption: '**Figure 1** — the map' })).toContain('<strong');
58
+ });
59
+
60
+ it('escapes caption text rather than emitting it as markup', () => {
61
+ expect(html({ caption: '<b>bold</b>' })).not.toContain('<b>bold</b>');
62
+ });
63
+
64
+ it('emits a bare <img> when no caption is set', () => {
65
+ // Existing pages carry no caption prop at all — `undefined`, not `''`, is
66
+ // what Puck hands the block for them — and must render exactly as they did
67
+ // before the field existed.
68
+ const markup = html({ caption: undefined });
69
+ expect(markup).not.toContain('figure');
70
+ expect(markup.startsWith('<img')).toBe(true);
71
+ expect(markup).toContain('class="my-3"');
72
+ });
73
+
74
+ it('treats an empty or blank caption as no caption', () => {
75
+ // Whitespace-only would otherwise be truthy and render an empty caption
76
+ // box under the image.
77
+ const bare = html({ caption: undefined });
78
+ expect(html({ caption: '' })).toBe(bare);
79
+ expect(html({ caption: ' ' })).toBe(bare);
80
+ });
81
+
82
+ it('leaves the empty-src placeholder alone', () => {
83
+ const markup = html({ src: '', caption: 'A caption' });
84
+ expect(markup).toContain('No image selected');
85
+ expect(markup).not.toContain('figcaption');
86
+ });
87
+
88
+ it('still hides a decorative image from screen readers', () => {
89
+ const markup = html({ altKind: 'decorative', caption: 'A caption' });
90
+ expect(markup).toContain('alt=""');
91
+ expect(markup).toContain('aria-hidden="true"');
92
+ expect(markup).toContain('<figcaption');
93
+ });
94
+ });
@@ -6,6 +6,7 @@ import {
6
6
  lookupAsset,
7
7
  type MediaAssetRead,
8
8
  } from '../../utils/api';
9
+ import { renderRichText } from '../widgets/_internal/rich-text';
9
10
  import { MediaPicker } from './MediaPicker';
10
11
 
11
12
  type AltKind = 'meaningful' | 'decorative';
@@ -14,6 +15,10 @@ interface ImageProps {
14
15
  src: string;
15
16
  alt: string;
16
17
  altKind: AltKind;
18
+ /** Visible prose under the image, as light markdown. Distinct from `alt`,
19
+ * which describes the image to a screen reader — the two are rarely the
20
+ * same sentence. */
21
+ caption?: string;
17
22
  width: number | null;
18
23
  height: number | null;
19
24
  objectFit: 'cover' | 'contain' | 'fill';
@@ -21,6 +26,14 @@ interface ImageProps {
21
26
  sizes: string;
22
27
  }
23
28
 
29
+ // Captions read their look from the design pack the way the widget set does,
30
+ // so a tenant restyles them by overriding tokens instead of patching this
31
+ // block. `--pb-caption-color` falls through to the pack's body colour, which
32
+ // is what an unstyled pack (and widgets-base) already defines.
33
+ const CAPTION_CLASS =
34
+ 'mt-2 text-[length:var(--pb-caption-size,0.875rem)] leading-[var(--pb-body-leading,1.625)]';
35
+ const CAPTION_STYLE = { color: 'var(--pb-caption-color, var(--pb-body-color))' };
36
+
24
37
  function resolveSizes(srcset: string, sizes: string): string | undefined {
25
38
  if (sizes) return sizes;
26
39
  // Browsers assume 100vw when sizes is omitted but srcset is present;
@@ -50,6 +63,7 @@ export const ImageBlock: ComponentConfig<ImageProps> = {
50
63
  ],
51
64
  },
52
65
  alt: { type: 'text' },
66
+ caption: { type: 'text', label: 'Caption' },
53
67
  width: { type: 'number' },
54
68
  height: { type: 'number' },
55
69
  objectFit: {
@@ -67,6 +81,7 @@ export const ImageBlock: ComponentConfig<ImageProps> = {
67
81
  src: '',
68
82
  alt: '',
69
83
  altKind: 'meaningful',
84
+ caption: '',
70
85
  width: null,
71
86
  height: null,
72
87
  objectFit: 'cover',
@@ -96,7 +111,7 @@ export const ImageBlock: ComponentConfig<ImageProps> = {
96
111
  },
97
112
  };
98
113
  },
99
- render: ({ src, alt, altKind, width, height, objectFit, srcset, sizes }) => {
114
+ render: ({ src, alt, altKind, caption, width, height, objectFit, srcset, sizes }) => {
100
115
  if (!src) {
101
116
  return (
102
117
  <div className="my-3 p-6 border-2 border-dashed border-gray-300 rounded text-center text-gray-500 text-sm">
@@ -105,7 +120,11 @@ export const ImageBlock: ComponentConfig<ImageProps> = {
105
120
  );
106
121
  }
107
122
  const decorative = altKind === 'decorative';
108
- return (
123
+ // Trimmed, so a caption of nothing but spaces is no caption: it would
124
+ // otherwise render an empty <figcaption> box under the image. Same rule
125
+ // the translation extractor applies to every other copy field.
126
+ const hasCaption = Boolean(caption?.trim());
127
+ const image = (
109
128
  <img
110
129
  src={src}
111
130
  srcSet={srcset || undefined}
@@ -118,8 +137,23 @@ export const ImageBlock: ComponentConfig<ImageProps> = {
118
137
  loading="lazy"
119
138
  decoding="async"
120
139
  style={{ objectFit, maxWidth: '100%' }}
121
- className="my-3"
140
+ // Inside a <figure> the margin belongs to the figure, and `block`
141
+ // drops the inline descender gap above the caption. Uncaptioned
142
+ // images keep the exact markup they had before the field existed.
143
+ className={hasCaption ? 'block' : 'my-3'}
122
144
  />
123
145
  );
146
+ if (!hasCaption) return image;
147
+ return (
148
+ <figure className="my-3">
149
+ {image}
150
+ <figcaption className={CAPTION_CLASS} style={CAPTION_STYLE}>
151
+ {/* Light markdown, like every other copy field in the module — the
152
+ Table/Carousel/CallToAction captions all render this way, so
153
+ `**Figure 1**` can't work in one caption and not another. */}
154
+ {renderRichText(caption)}
155
+ </figcaption>
156
+ </figure>
157
+ );
124
158
  },
125
159
  };
@@ -58,6 +58,30 @@ describe('blocksToHtml', () => {
58
58
  ).toBe('<img src="/a.png" alt="" width="800" height="600">');
59
59
  });
60
60
 
61
+ it('carries an image caption across as a figure, so it is not lost silently', () => {
62
+ // The caption is authored copy. Emitting the bare <img> would drop it with
63
+ // no `lossyTypes` entry to warn the caller, because the block itself
64
+ // converts fine — the quiet loss this module exists to avoid.
65
+ expect(
66
+ blocksToHtml([b('Image', { src: '/a.png', alt: 'A map', caption: 'Figure 1' })]).html,
67
+ ).toBe('<figure><img src="/a.png" alt="A map"><figcaption>Figure 1</figcaption></figure>');
68
+ // Inline markdown, matching what the block renders, escaped as it goes.
69
+ expect(
70
+ blocksToHtml([b('Image', { src: '/a.png', alt: '', caption: '**Fig 1** <b>' })]).html,
71
+ ).toBe(
72
+ '<figure><img src="/a.png" alt=""><figcaption><strong>Fig 1</strong> &lt;b&gt;</figcaption></figure>',
73
+ );
74
+ });
75
+
76
+ it('emits a bare img for a missing or blank caption', () => {
77
+ expect(blocksToHtml([b('Image', { src: '/a.png', alt: '' })]).html).toBe(
78
+ '<img src="/a.png" alt="">',
79
+ );
80
+ expect(blocksToHtml([b('Image', { src: '/a.png', alt: '', caption: ' ' })]).html).toBe(
81
+ '<img src="/a.png" alt="">',
82
+ );
83
+ });
84
+
61
85
  it('treats Html as lossy unless raw markup is explicitly asked for', () => {
62
86
  // The Html widget renders its markup inside `<iframe sandbox>` because a
63
87
  // ContentEditor's input isn't fully trusted. This function's output has no
@@ -8,7 +8,7 @@
8
8
  * then say exactly what didn't come across.
9
9
  */
10
10
 
11
- import { escapeHtml, markdownToHtml } from '../utils/markdown';
11
+ import { escapeHtml, inlineMarkdownToHtml, markdownToHtml } from '../utils/markdown';
12
12
  import type { PuckBlock } from './types';
13
13
 
14
14
  export type BlocksToHtmlResult = { html: string; lossyTypes: string[] };
@@ -83,7 +83,15 @@ function blockToHtml(block: PuckBlock, options: BlocksToHtmlOptions): string | n
83
83
  const dims = ['width', 'height']
84
84
  .map((key) => (typeof props[key] === 'number' ? ` ${key}="${props[key]}"` : ''))
85
85
  .join('');
86
- return `<img src="${escapeHtml(props.src)}" alt="${escapeHtml(alt)}"${dims}>`;
86
+ const img = `<img src="${escapeHtml(props.src)}" alt="${escapeHtml(alt)}"${dims}>`;
87
+ // The caption is authored copy, not a rendering detail — dropping it
88
+ // here would lose it silently, and `lossyTypes` couldn't name it either
89
+ // because the rest of the block converts fine. Same `<figure>` shape the
90
+ // block renders, so an export reads the way the page does. Inline
91
+ // markdown, as the block treats it; the converter escapes as it goes.
92
+ const caption = typeof props.caption === 'string' ? props.caption.trim() : '';
93
+ if (!caption) return img;
94
+ return `<figure>${img}<figcaption>${inlineMarkdownToHtml(caption)}</figcaption></figure>`;
87
95
  }
88
96
 
89
97
  case 'Quote': {
@@ -36,6 +36,13 @@
36
36
  EYEBROW_CASE_STYLE's fallbacks in _shared/mask.ts, so removing them
37
37
  changes nothing for the sentence-case eyebrows and lets each call site
38
38
  state its own prior literal. Tenants still override via their design pack. */
39
+ /* Image-block captions. Deliberately NOT defaulted here, for the same
40
+ reason as the eyebrow tokens above: `--pb-caption-color` is read as
41
+ `var(--pb-caption-color, var(--pb-body-color))` and `--pb-caption-size`
42
+ as `var(--pb-caption-size, 0.875rem)`, and declaring either globally
43
+ would make the call site's own fallback unreachable. Listed here so a
44
+ pack author can find them — set them in the design pack to restyle
45
+ captions without touching the block. */
39
46
  /* Hero geometry (consumed by the Hero/PageHeader widgets). */
40
47
  --pb-hero-min-h: 560px;
41
48
  --pb-hero-logo-max-h: 14rem;
@@ -134,7 +134,14 @@ export function parseInlineTokens(text: string): InlineToken[] {
134
134
  return tokens;
135
135
  }
136
136
 
137
- function inlineMarkdownToHtml(text: string): string {
137
+ /**
138
+ * One line of inline markdown → HTML, with no block wrapper.
139
+ *
140
+ * Exported for the places that need the emphasis but must not gain a `<p>`:
141
+ * an image's `<figcaption>` is phrasing content the block renders inline, so
142
+ * `markdownToHtml` would wrap it in a paragraph the page never had.
143
+ */
144
+ export function inlineMarkdownToHtml(text: string): string {
138
145
  return parseInlineTokens(text)
139
146
  .map((token) => {
140
147
  const escaped = escapeHtml(token.content);
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "simple_module_pagebuilder"
3
- version = "0.0.2"
3
+ version = "0.0.3"
4
4
  description = "Drag-and-drop visual page builder for simple_module apps"
5
5
  readme = "README.md"
6
6
  license = "MIT"