bootstack 0.1.0a6__tar.gz → 0.1.0a7__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 (432) hide show
  1. {bootstack-0.1.0a6/src/bootstack.egg-info → bootstack-0.1.0a7}/PKG-INFO +2 -2
  2. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/README.md +1 -1
  3. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/pyproject.toml +2 -2
  4. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/__init__.py +2 -2
  5. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/__init__.py +2 -1
  6. bootstack-0.1.0a7/src/bootstack/api/menu.py +7 -0
  7. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/localization/intl_format.py +4 -4
  8. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/datedialog.py +38 -12
  9. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/dialog.py +9 -9
  10. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/filterdialog.py +12 -12
  11. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/menu.py +89 -136
  12. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/field.py +14 -8
  13. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/typography.py +6 -6
  14. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/appshell.py +47 -16
  15. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/calendar.py +1 -1
  16. bootstack-0.1.0a7/src/bootstack/widgets/composites/dateentry.py +434 -0
  17. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/dropdownbutton.py +1 -3
  18. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/field.py +22 -12
  19. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrollview.py +19 -10
  20. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/selectbox.py +11 -4
  21. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/view.py +6 -15
  22. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/tableview.py +2 -2
  23. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/textentry.py +5 -8
  24. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/timeentry.py +8 -1
  25. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/toolbar.py +1 -1
  26. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/textentry_part.py +2 -0
  27. {bootstack-0.1.0a6 → bootstack-0.1.0a7/src/bootstack.egg-info}/PKG-INFO +2 -2
  28. bootstack-0.1.0a6/src/bootstack/api/menu.py +0 -7
  29. bootstack-0.1.0a6/src/bootstack/widgets/composites/dateentry.py +0 -261
  30. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/LICENSE +0 -0
  31. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/MANIFEST.in +0 -0
  32. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/NOTICE +0 -0
  33. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/setup.cfg +0 -0
  34. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/__main__.py +0 -0
  35. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/app.py +0 -0
  36. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/constants.py +0 -0
  37. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/data.py +0 -0
  38. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/dialogs.py +0 -0
  39. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/i18n.py +0 -0
  40. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/localization.py +0 -0
  41. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/style.py +0 -0
  42. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/utils.py +0 -0
  43. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/api/widgets.py +0 -0
  44. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/__init__.py +0 -0
  45. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-dark.ico +0 -0
  46. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-light.ico +0 -0
  47. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-transparent.png +0 -0
  48. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack.ico +0 -0
  49. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack.png +0 -0
  50. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/__init__.py +0 -0
  51. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/badge-pill.png +0 -0
  52. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/badge-square.png +0 -0
  53. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/border.png +0 -0
  54. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-compact.png +0 -0
  55. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-default.png +0 -0
  56. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
  57. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
  58. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
  59. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
  60. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
  61. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
  62. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
  63. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
  64. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
  65. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
  66. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
  67. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
  68. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  69. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  70. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  71. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/field.png +0 -0
  72. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-after-compact.png +0 -0
  73. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-after-default.png +0 -0
  74. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-before-compact.png +0 -0
  75. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-before-default.png +0 -0
  76. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-compact.png +0 -0
  77. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-default.png +0 -0
  78. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  79. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/list-item.png +0 -0
  80. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/manifest.toml +0 -0
  81. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/menu-item.png +0 -0
  82. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-button-compact.png +0 -0
  83. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-button-default.png +0 -0
  84. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-icon-button-compact.png +0 -0
  85. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-icon-button-default.png +0 -0
  86. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-client-border.png +0 -0
  87. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-active.png +0 -0
  88. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-bar.png +0 -0
  89. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-normal.png +0 -0
  90. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-pill.png +0 -0
  91. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
  92. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-solid.png +0 -0
  93. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-thin.png +0 -0
  94. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
  95. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/radio-selected.png +0 -0
  96. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/radio-unselected.png +0 -0
  97. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  98. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  99. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-handle-focus.png +0 -0
  100. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-handle.png +0 -0
  101. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-track-horizontal.png +0 -0
  102. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-track-vertical.png +0 -0
  103. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/switch-off.png +0 -0
  104. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/switch-on.png +0 -0
  105. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
  106. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-bar-vertical.png +0 -0
  107. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-pill.png +0 -0
  108. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  109. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  110. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  111. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  112. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  113. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  114. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  115. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  116. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  117. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  118. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  119. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  120. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  121. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  122. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  123. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  124. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  125. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  126. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  127. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  128. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  129. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  130. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  131. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  132. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  133. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  134. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  135. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  136. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  137. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  138. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  139. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  140. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  141. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  142. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  143. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  144. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  145. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  146. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  147. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  148. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  149. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  150. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  151. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  152. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  153. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/__init__.py +0 -0
  154. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/amber-dark.json +0 -0
  155. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/amber-light.json +0 -0
  156. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/aurora-dark.json +0 -0
  157. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/aurora-light.json +0 -0
  158. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/bootstrap-dark.json +0 -0
  159. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/bootstrap-light.json +0 -0
  160. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/classic-dark.json +0 -0
  161. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/classic-light.json +0 -0
  162. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/docs-dark.json +0 -0
  163. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/docs-light.json +0 -0
  164. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/forest-dark.json +0 -0
  165. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/forest-light.json +0 -0
  166. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/ocean-dark.json +0 -0
  167. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/ocean-light.json +0 -0
  168. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/rose-dark.json +0 -0
  169. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/themes/rose-light.json +0 -0
  170. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/__init__.py +0 -0
  171. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/badge-default.png +0 -0
  172. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/badge-pill.png +0 -0
  173. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/border.png +0 -0
  174. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
  175. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
  176. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
  177. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-after.png +0 -0
  178. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-before.png +0 -0
  179. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-center.png +0 -0
  180. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button.png +0 -0
  181. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-checked.png +0 -0
  182. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
  183. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-unchecked.png +0 -0
  184. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/field.png +0 -0
  185. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/icon-button.png +0 -0
  186. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-inner.png +0 -0
  187. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-prefix.png +0 -0
  188. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-suffix.png +0 -0
  189. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input.png +0 -0
  190. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/list-item-focus.png +0 -0
  191. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/list-item-separated.png +0 -0
  192. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/menu-item-separated.png +0 -0
  193. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-client-border.png +0 -0
  194. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-pill-active.png +0 -0
  195. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
  196. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-active.png +0 -0
  197. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-border.png +0 -0
  198. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-normal.png +0 -0
  199. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-underline.png +0 -0
  200. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
  201. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
  202. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
  203. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
  204. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
  205. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-trough-vertical.png +0 -0
  206. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/radio-selected.png +0 -0
  207. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/radio-unselected.png +0 -0
  208. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
  209. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
  210. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/separator-horizontal.png +0 -0
  211. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/separator-vertical.png +0 -0
  212. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-handle-focus.png +0 -0
  213. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-handle.png +0 -0
  214. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-track-horizontal.png +0 -0
  215. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-track-vertical.png +0 -0
  216. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/switch-off.png +0 -0
  217. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/switch-on.png +0 -0
  218. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
  219. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
  220. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-pill.png +0 -0
  221. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/__init__.py +0 -0
  222. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/__main__.py +0 -0
  223. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/add.py +0 -0
  224. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/build.py +0 -0
  225. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/config.py +0 -0
  226. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/demo.py +0 -0
  227. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/doctor.py +0 -0
  228. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/icons.py +0 -0
  229. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/list_cmd.py +0 -0
  230. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/promote.py +0 -0
  231. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/pyinstaller.py +0 -0
  232. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/run.py +0 -0
  233. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/start.py +0 -0
  234. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/cli/templates/__init__.py +0 -0
  235. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/constants.py +0 -0
  236. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/__init__.py +0 -0
  237. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/__init__.py +0 -0
  238. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/after.py +0 -0
  239. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/bind.py +0 -0
  240. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/bindtags.py +0 -0
  241. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/busy.py +0 -0
  242. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/clipboard.py +0 -0
  243. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/focus.py +0 -0
  244. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/grab.py +0 -0
  245. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/grid.py +0 -0
  246. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/localization.py +0 -0
  247. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/pack.py +0 -0
  248. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/place.py +0 -0
  249. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/selection.py +0 -0
  250. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/signals.py +0 -0
  251. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/winfo.py +0 -0
  252. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/colorutils.py +0 -0
  253. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/exceptions.py +0 -0
  254. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/images.py +0 -0
  255. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/localization/README.md +0 -0
  256. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/localization/__init__.py +0 -0
  257. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/localization/msgcat.py +0 -0
  258. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/localization/specs.py +0 -0
  259. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/mixins/__init__.py +0 -0
  260. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/mixins/ttk_state.py +0 -0
  261. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/mixins/widget.py +0 -0
  262. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/publisher.py +0 -0
  263. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/signals/README.md +0 -0
  264. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/signals/__init__.py +0 -0
  265. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/signals/integration.py +0 -0
  266. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/signals/signal.py +0 -0
  267. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/signals/types.py +0 -0
  268. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/validation/__init__.py +0 -0
  269. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/validation/types.py +0 -0
  270. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/validation/validation_result.py +0 -0
  271. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/validation/validation_rules.py +0 -0
  272. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/core/variables.py +0 -0
  273. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/README.md +0 -0
  274. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/__init__.py +0 -0
  275. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/base.py +0 -0
  276. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/file_source.py +0 -0
  277. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/memory_source.py +0 -0
  278. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/sqlite_source.py +0 -0
  279. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/datasource/types.py +0 -0
  280. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/__init__.py +0 -0
  281. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/colorchooser.py +0 -0
  282. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/colordropper.py +0 -0
  283. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/fontdialog.py +0 -0
  284. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/formdialog.py +0 -0
  285. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/message.py +0 -0
  286. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/dialogs/query.py +0 -0
  287. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/py.typed +0 -0
  288. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/__init__.py +0 -0
  289. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/app.py +0 -0
  290. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/base_window.py +0 -0
  291. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/events.py +0 -0
  292. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/shortcuts.py +0 -0
  293. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/tk_patch.py +0 -0
  294. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/toplevel.py +0 -0
  295. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/utility.py +0 -0
  296. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/visual_focus.py +0 -0
  297. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/runtime/window_utilities.py +0 -0
  298. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/__init__.py +0 -0
  299. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle.py +0 -0
  300. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_base.py +0 -0
  301. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_mixed.py +0 -0
  302. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_tk.py +0 -0
  303. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_ttk.py +0 -0
  304. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/__init__.py +0 -0
  305. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/badge.py +0 -0
  306. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/button.py +0 -0
  307. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/buttongroup.py +0 -0
  308. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/calendar.py +0 -0
  309. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/checkbutton.py +0 -0
  310. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/combobox.py +0 -0
  311. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/contextmenu.py +0 -0
  312. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/entry.py +0 -0
  313. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/expander.py +0 -0
  314. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/frame.py +0 -0
  315. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/label.py +0 -0
  316. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/labelframe.py +0 -0
  317. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/listview.py +0 -0
  318. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/menubar.py +0 -0
  319. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/menubutton.py +0 -0
  320. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/notebook.py +0 -0
  321. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/panedwindow.py +0 -0
  322. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/progressbar.py +0 -0
  323. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/radiobutton.py +0 -0
  324. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/scale.py +0 -0
  325. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/scrollbar.py +0 -0
  326. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/separator.py +0 -0
  327. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/sidenav.py +0 -0
  328. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/sizegrip.py +0 -0
  329. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/spinbox.py +0 -0
  330. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/switch.py +0 -0
  331. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/tabitem.py +0 -0
  332. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/toolbutton.py +0 -0
  333. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/tooltip.py +0 -0
  334. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/treeview.py +0 -0
  335. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders/utils.py +0 -0
  336. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders_tk/__init__.py +0 -0
  337. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/builders_tk/defaults.py +0 -0
  338. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/element.py +0 -0
  339. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/style.py +0 -0
  340. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/theme_provider.py +0 -0
  341. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/tk_patch.py +0 -0
  342. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/token_maps.py +0 -0
  343. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/types.py +0 -0
  344. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/style/utility.py +0 -0
  345. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/themes/__init__.py +0 -0
  346. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/themes/standard.py +0 -0
  347. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/themes/user.py +0 -0
  348. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/__init__.py +0 -0
  349. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/__init__.py +0 -0
  350. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/accordion.py +0 -0
  351. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/buttongroup.py +0 -0
  352. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/compositeframe.py +0 -0
  353. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/contextmenu.py +0 -0
  354. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/expander.py +0 -0
  355. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/floodgauge.py +0 -0
  356. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/form.py +0 -0
  357. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/labeledscale.py +0 -0
  358. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/__init__.py +0 -0
  359. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/listitem.py +0 -0
  360. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/listview.py +0 -0
  361. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/menubar.py +0 -0
  362. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/meter.py +0 -0
  363. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/numericentry.py +0 -0
  364. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/pagestack.py +0 -0
  365. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/passwordentry.py +0 -0
  366. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/pathentry.py +0 -0
  367. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/radiogroup.py +0 -0
  368. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrolledtext.py +0 -0
  369. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrolledtext.pyi +0 -0
  370. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/__init__.py +0 -0
  371. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/group.py +0 -0
  372. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/header.py +0 -0
  373. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/item.py +0 -0
  374. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/separator.py +0 -0
  375. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/spinnerentry.py +0 -0
  376. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/__init__.py +0 -0
  377. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/types.py +0 -0
  378. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/__init__.py +0 -0
  379. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabitem.py +0 -0
  380. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabs.py +0 -0
  381. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabview.py +0 -0
  382. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/toast.py +0 -0
  383. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/togglegroup.py +0 -0
  384. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tooltip.py +0 -0
  385. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/internal/__init__.py +0 -0
  386. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/internal/wrapper_base.py +0 -0
  387. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/__init__.py +0 -0
  388. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/configure_mixin.py +0 -0
  389. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/entry_mixin.py +0 -0
  390. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/font_mixin.py +0 -0
  391. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/icon_mixin.py +0 -0
  392. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/localization_mixin.py +0 -0
  393. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/signal_mixin.py +0 -0
  394. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/validation_mixin.py +0 -0
  395. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/__init__.py +0 -0
  396. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/numberentry_part.py +0 -0
  397. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/spinnerentry_part.py +0 -0
  398. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/__init__.py +0 -0
  399. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/badge.py +0 -0
  400. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/button.py +0 -0
  401. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/card.py +0 -0
  402. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/checkbutton.py +0 -0
  403. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/checktoggle.py +0 -0
  404. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/combobox.py +0 -0
  405. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/entry.py +0 -0
  406. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/frame.py +0 -0
  407. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/gridframe.py +0 -0
  408. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/label.py +0 -0
  409. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/labelframe.py +0 -0
  410. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/menubutton.py +0 -0
  411. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/notebook.py +0 -0
  412. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/optionmenu.py +0 -0
  413. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/packframe.py +0 -0
  414. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/panedwindow.py +0 -0
  415. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/progressbar.py +0 -0
  416. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/radiobutton.py +0 -0
  417. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/radiotoggle.py +0 -0
  418. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/scale.py +0 -0
  419. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/scrollbar.py +0 -0
  420. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/separator.py +0 -0
  421. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/sizegrip.py +0 -0
  422. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/spinbox.py +0 -0
  423. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/switch.py +0 -0
  424. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/treeview.py +0 -0
  425. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack/widgets/types.py +0 -0
  426. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack.egg-info/SOURCES.txt +0 -0
  427. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack.egg-info/dependency_links.txt +0 -0
  428. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack.egg-info/entry_points.txt +0 -0
  429. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack.egg-info/requires.txt +0 -0
  430. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/src/bootstack.egg-info/top_level.txt +0 -0
  431. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/tests/test_togglegroup.py +0 -0
  432. {bootstack-0.1.0a6 → bootstack-0.1.0a7}/tests/test_variables.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.1.0a6
3
+ Version: 0.1.0a7
4
4
  Summary: A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT
@@ -150,7 +150,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
150
150
 
151
151
  ## Features
152
152
 
153
- - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, frameless windows with custom chrome
153
+ - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, undecorated windows with custom chrome
154
154
  - **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
155
155
  - **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
156
156
  - **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
@@ -116,7 +116,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
116
116
 
117
117
  ## Features
118
118
 
119
- - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, frameless windows with custom chrome
119
+ - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, undecorated windows with custom chrome
120
120
  - **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
121
121
  - **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
122
122
  - **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bootstack"
7
- version = "0.1.0a6"
7
+ version = "0.1.0a7"
8
8
  description = "A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -82,7 +82,7 @@ where = ["src"]
82
82
  ]
83
83
 
84
84
  [tool.bumpversion]
85
- current_version = "0.1.0a6"
85
+ current_version = "0.1.0a7"
86
86
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
87
87
  serialize = [
88
88
  "{major}.{minor}.{patch}{pre}{pre_n}",
@@ -45,7 +45,7 @@ from ttkbootstrap_icons_bs import BootstrapIcon # noqa: E402
45
45
  # (see constants.py which re-exports from core.constants)
46
46
 
47
47
  if TYPE_CHECKING:
48
- from bootstack.api.menu import MenuManager, create_menu
48
+ from bootstack.api.menu import MenuManager, create_menu, create_menu_items
49
49
  from bootstack.api.app import App, AppShell, App as Window, Toplevel, AppSettings, get_app_settings, get_current_app, Shortcuts, Shortcut, get_shortcuts
50
50
  from bootstack.api.style import (
51
51
  Font,
@@ -157,7 +157,7 @@ _MODULE_EXPORTS = {
157
157
  # Application & Windows (includes menu and shortcuts)
158
158
  "bootstack.api.app": [
159
159
  "App", "AppShell", "Toplevel", "Window", "AppSettings", "get_app_settings", "get_current_app",
160
- "MenuManager", "create_menu",
160
+ "MenuManager", "create_menu", "create_menu_items",
161
161
  "Shortcuts", "Shortcut", "get_shortcuts",
162
162
  ],
163
163
  # Style & Theming
@@ -64,7 +64,7 @@ from bootstack.api.widgets import (
64
64
  )
65
65
  from bootstack.runtime.app import App, App as Window
66
66
  from bootstack.runtime.toplevel import Toplevel
67
- from bootstack.runtime.menu import MenuManager, create_menu
67
+ from bootstack.runtime.menu import MenuManager, create_menu, create_menu_items
68
68
 
69
69
  __all__ = [
70
70
  "BootstrapIcon",
@@ -122,6 +122,7 @@ __all__ = [
122
122
  "get_theme_provider",
123
123
  "get_theme_color",
124
124
  "create_menu",
125
+ "create_menu_items",
125
126
  "TK_WIDGETS",
126
127
  "TTK_WIDGETS",
127
128
  ]
@@ -0,0 +1,7 @@
1
+ """Public menu-related API surface."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from bootstack.runtime.menu import MenuManager, create_menu, create_menu_items
6
+
7
+ __all__ = ["MenuManager", "create_menu", "create_menu_items"]
@@ -429,8 +429,8 @@ class IntlFormatter:
429
429
  opt = self._normalize_date_spec(spec)
430
430
  typ = opt["type"]
431
431
  if typ == "custom": return format_time(t, format=opt["pattern"], locale=self.locale)
432
- if typ == "longTime": return format_time(t, "long", self.locale)
433
- if typ == "shortTime": return format_time(t, "short", self.locale)
432
+ if typ == "longTime": return format_time(t, "long", locale=self.locale)
433
+ if typ == "shortTime": return format_time(t, "short", locale=self.locale)
434
434
  if typ == "hour": return format_time(t, "H", self.locale)
435
435
  if typ == "minute": return format_time(t, "m", self.locale)
436
436
  if typ == "second": return format_time(t, "s", self.locale)
@@ -451,8 +451,8 @@ class IntlFormatter:
451
451
  if typ == "shortDateShortTime": return format_datetime(dt, "short", self.locale)
452
452
  if typ == "longDate": return format_date(dt.date(), "long", self.locale)
453
453
  if typ == "shortDate": return format_date(dt.date(), "short", self.locale)
454
- if typ == "longTime": return format_time(dt.time(), "long", self.locale)
455
- if typ == "shortTime": return format_time(dt.time(), "short", self.locale)
454
+ if typ == "longTime": return format_time(dt.time(), "long", locale=self.locale)
455
+ if typ == "shortTime": return format_time(dt.time(), "short", locale=self.locale)
456
456
  if typ == "monthAndDay": return format_date(dt.date(), "MMMM d", self.locale)
457
457
  if typ == "monthAndYear": return format_date(dt.date(), "MMMM y", self.locale)
458
458
  if typ == "quarterAndYear": return format_date(dt.date(), "QQQ y", self.locale)
@@ -202,13 +202,16 @@ class DateDialog:
202
202
  show_week_numbers: bool = False,
203
203
  hide_window_chrome: bool = False,
204
204
  close_on_click_outside: bool = False,
205
+ selection_mode: Literal["single", "range"] = "single",
206
+ start_date: Optional[date | datetime | str] = None,
207
+ end_date: Optional[date | datetime | str] = None,
205
208
  ) -> None:
206
209
  """Create a date selection dialog.
207
210
 
208
211
  Args:
209
212
  master: Parent widget; positions dialog relative to it when set.
210
213
  title: Dialog window title text.
211
- initial_date: Initial date shown; defaults to `date.today()`.
214
+ initial_date: Initial date shown in single mode; defaults to `date.today()`.
212
215
  first_weekday: First weekday index (0=Monday, 6=Sunday).
213
216
  accent: Calendar accent token (e.g., `primary`, `secondary`).
214
217
  disabled_dates: Iterable of dates to disable selection.
@@ -221,6 +224,11 @@ class DateDialog:
221
224
  decorations using override-redirect.
222
225
  close_on_click_outside: When True, closes the dialog when focus
223
226
  moves outside (popover mode).
227
+ selection_mode: `'single'` for a single date (default) or `'range'`
228
+ for a start/end date range. In range mode `result` is a
229
+ `tuple[date, date]` rather than a `date`.
230
+ start_date: Initial range start date (range mode only).
231
+ end_date: Initial range end date (range mode only).
224
232
  """
225
233
  self._master = master
226
234
  self._first_weekday = first_weekday
@@ -233,6 +241,9 @@ class DateDialog:
233
241
  self._show_week_numbers = show_week_numbers
234
242
  self._hide_window_chrome = hide_window_chrome
235
243
  self._close_on_click_outside = close_on_click_outside
244
+ self._selection_mode = selection_mode
245
+ self._start_date = start_date
246
+ self._end_date = end_date
236
247
 
237
248
  self._picker: Optional[_DialogCalendar] = None
238
249
 
@@ -253,7 +264,9 @@ class DateDialog:
253
264
 
254
265
  self._picker = _DialogCalendar(
255
266
  master=container,
256
- start_date=self._initial_date,
267
+ selection_mode=self._selection_mode,
268
+ start_date=self._start_date if self._selection_mode == "range" else self._initial_date,
269
+ end_date=self._end_date if self._selection_mode == "range" else None,
257
270
  first_weekday=self._first_weekday,
258
271
  accent=self._accent,
259
272
  disabled_dates=self._disabled_dates,
@@ -275,16 +288,29 @@ class DateDialog:
275
288
  return
276
289
 
277
290
  payload = getattr(event, "data", None)
278
- selected = None
279
- if isinstance(payload, dict):
280
- selected = payload.get("date") or payload.get("result")
281
291
 
282
- selected = selected or self._picker.get()
283
- if selected is None:
284
- return
292
+ if self._selection_mode == "range":
293
+ range_data = None
294
+ if isinstance(payload, dict):
295
+ range_data = payload.get("range")
296
+ if range_data is None:
297
+ range_data = self._picker.get_range()
298
+ start, end = range_data if range_data else (None, None)
299
+ # Wait for both dates before confirming
300
+ if start is None or end is None:
301
+ return
302
+ result: date | Tuple[date, date] = (start, end)
303
+ else:
304
+ selected = None
305
+ if isinstance(payload, dict):
306
+ selected = payload.get("date") or payload.get("result")
307
+ selected = selected or self._picker.get()
308
+ if selected is None:
309
+ return
310
+ result = selected
285
311
 
286
- self._dialog.result = selected
287
- self._emit_result(selected, confirmed=True)
312
+ self._dialog.result = result
313
+ self._emit_result(result, confirmed=True)
288
314
  if self._dialog.toplevel:
289
315
  top = self._dialog.toplevel
290
316
  try:
@@ -354,8 +380,8 @@ class DateDialog:
354
380
  )
355
381
 
356
382
  @property
357
- def result(self) -> Optional[date]:
358
- """The selected date, or None if cancelled."""
383
+ def result(self) -> Optional[Union[date, Tuple[date, date]]]:
384
+ """The selected date (single mode) or ``(start, end)`` tuple (range mode), or None if cancelled."""
359
385
  return self._dialog.result
360
386
 
361
387
  def on_result(self, callback: Callable[[date], None]) -> Optional[str]:
@@ -130,7 +130,7 @@ class Dialog:
130
130
  its parent (via `transient`). Falls back to plain modal
131
131
  behavior on Windows/Linux where there's no equivalent.
132
132
  Defaults to "modal".
133
- frameless: If True, removes window decorations (title bar, borders) and adds
133
+ undecorated: If True, removes window decorations (title bar, borders) and adds
134
134
  a solid border frame around the dialog content. Useful for dropdown-style
135
135
  menus or popover UIs. Defaults to False.
136
136
  window_style: Windows-only pywinstyles effect. Options include
@@ -151,7 +151,7 @@ class Dialog:
151
151
  resizable: tuple[bool, bool] | None = (False, False),
152
152
  alert: bool = False,
153
153
  mode: DialogMode = "modal",
154
- frameless: bool = False,
154
+ undecorated: bool = False,
155
155
  window_style: str | None = None,
156
156
  ):
157
157
  import tkinter
@@ -166,7 +166,7 @@ class Dialog:
166
166
  self._resizable = resizable
167
167
  self._alert = alert
168
168
  self._mode = mode
169
- self._frameless = frameless
169
+ self._undecorated = undecorated
170
170
  self._window_style = window_style
171
171
 
172
172
  self._toplevel: Toplevel | None = None
@@ -316,17 +316,17 @@ class Dialog:
316
316
  if self._resizable is not None:
317
317
  self._toplevel.resizable(*self._resizable)
318
318
 
319
- if self._frameless:
319
+ if self._undecorated:
320
320
  self._toplevel.overrideredirect(True)
321
321
  self._border_frame = bs.Frame(self._toplevel, show_border=True, padding=2)
322
322
  self._border_frame.pack(fill='both', expand=True)
323
323
 
324
324
  def _build_content(self):
325
- parent = self._border_frame if self._frameless else self._toplevel
326
- padding = 2 if self._frameless else 0
325
+ parent = self._border_frame if self._undecorated else self._toplevel
326
+ padding = 2 if self._undecorated else 0
327
327
  self._content = bs.Frame(parent, padding=padding)
328
328
 
329
- if self._frameless:
329
+ if self._undecorated:
330
330
  self._content.pack(fill="both", side="top", expand=False)
331
331
  else:
332
332
  self._content.pack(fill="both", side="top", expand=True)
@@ -335,8 +335,8 @@ class Dialog:
335
335
  self._content_builder(self._content)
336
336
 
337
337
  def _build_footer(self):
338
- parent = self._border_frame if self._frameless else self._toplevel
339
- footer_padding = 6 if self._frameless else 4
338
+ parent = self._border_frame if self._undecorated else self._toplevel
339
+ footer_padding = 6 if self._undecorated else 4
340
340
 
341
341
  if self._footer_builder:
342
342
  self._footer = bs.Frame(parent, padding=footer_padding)
@@ -2,7 +2,7 @@
2
2
 
3
3
  This module provides a multi-select dialog with optional search and select-all
4
4
  functionality. Items can be displayed with checkboxes, and the dialog supports
5
- both standard and frameless (borderless) display modes.
5
+ both standard and undecorated (custom-chrome) display modes.
6
6
  """
7
7
 
8
8
  from tkinter import Widget
@@ -194,7 +194,7 @@ class FilterDialog(ttk.Frame):
194
194
  items: list[str | dict[str, Any]] = None,
195
195
  enable_search: bool = False,
196
196
  enable_select_all: bool = False,
197
- frameless: bool = False
197
+ undecorated: bool = False
198
198
  ):
199
199
  """Initialize the FilterDialog.
200
200
 
@@ -207,7 +207,7 @@ class FilterDialog(ttk.Frame):
207
207
  - selected (bool): Initial selection state (defaults to False)
208
208
  enable_search: If True, includes a search box to filter items by text.
209
209
  enable_select_all: If True, includes a "Select All" checkbox.
210
- frameless: If True, removes window decorations and displays with a
210
+ undecorated: If True, removes window decorations and displays with a
211
211
  border frame. Enables dismiss-on-outside-click behavior.
212
212
  """
213
213
  super().__init__(master)
@@ -216,7 +216,7 @@ class FilterDialog(ttk.Frame):
216
216
  self._items = items or []
217
217
  self._enable_search = enable_search
218
218
  self._enable_select_all = enable_select_all
219
- self._frameless = frameless
219
+ self._undecorated = undecorated
220
220
  self._content: FilterDialogContent | None = None
221
221
  self._dialog: Dialog | None = None
222
222
  self.result: list[Any] | None = None
@@ -229,12 +229,12 @@ class FilterDialog(ttk.Frame):
229
229
  enable_select_all=self._enable_select_all,
230
230
  items=self._items
231
231
  )
232
- padding = 0 if self._frameless else 10
232
+ padding = 0 if self._undecorated else 10
233
233
  self._content.pack(fill='both', expand=True, padx=padding, pady=padding)
234
234
 
235
- # Setup dismiss-on-click for frameless after dialog is built
236
- if self._frameless:
237
- parent.after(10, self._setup_frameless_dismiss)
235
+ # Setup dismiss-on-click for undecorated after dialog is built
236
+ if self._undecorated:
237
+ parent.after(10, self._setup_undecorated_dismiss)
238
238
 
239
239
  def _on_ok(self, dialog: Dialog):
240
240
  """Save selected items to result when OK button is clicked."""
@@ -278,9 +278,9 @@ class FilterDialog(ttk.Frame):
278
278
  except:
279
279
  pass
280
280
 
281
- def _setup_frameless_dismiss(self):
282
- """Setup dismiss-on-outside-click for frameless dialogs."""
283
- if self._frameless and self._dialog and self._dialog.toplevel:
281
+ def _setup_undecorated_dismiss(self):
282
+ """Setup dismiss-on-outside-click for undecorated dialogs."""
283
+ if self._undecorated and self._dialog and self._dialog.toplevel:
284
284
  # Bind to root window to catch all clicks
285
285
  root = self._dialog.toplevel.winfo_toplevel()
286
286
  while root.master:
@@ -343,7 +343,7 @@ class FilterDialog(ttk.Frame):
343
343
  maxsize=(250, 380),
344
344
  resizable=(False, True),
345
345
  mode="modal",
346
- frameless=self._frameless
346
+ undecorated=self._undecorated
347
347
  )
348
348
 
349
349
  self._dialog.show(
@@ -245,19 +245,18 @@ class MenuManager:
245
245
  """Create a menu from a list of item dictionaries.
246
246
 
247
247
  Args:
248
- parent: The parent widget (Window, Toplevel, or Menu).
248
+ parent: The parent widget (Window, Toplevel, or Menu). Used as the
249
+ Tk parent for the created ``tk.Menu``; the menu is NOT
250
+ automatically attached to the parent — the caller decides
251
+ (e.g. ``widget['menu'] = m`` or ``MenuButton(menu=m)``).
249
252
  items: List of menu item dictionaries defining the menu structure.
250
253
 
251
254
  Returns:
252
255
  The created Menu object.
253
256
  """
254
- menubar = None
255
-
256
- # If parent is a window, create the menubar first
257
257
  if not isinstance(parent, tk.Menu):
258
- menubar = tk.Menu(parent, tearoff=0)
259
- parent['menu'] = menubar
260
- parent = menubar # Now work with the menubar
258
+ menu_root = tk.Menu(parent, tearoff=0)
259
+ parent = menu_root
261
260
 
262
261
  for options in items:
263
262
  options = options.copy()
@@ -305,7 +304,7 @@ class MenuManager:
305
304
  # Add all sub-items to this menu
306
305
  self._add_menu_items(menu, sub_items)
307
306
 
308
- return parent if isinstance(parent, tk.Menu) else menubar
307
+ return parent
309
308
 
310
309
  def _add_menu_items(self, menu: tk.Menu, items: list[dict]):
311
310
  """Add items to a menu with icon support and theme tracking."""
@@ -363,148 +362,102 @@ class MenuManager:
363
362
  self.menu_items[item_id] = (menu, index, icon_name, icon_size)
364
363
 
365
364
 
366
- def create_menu(parent: Any, items: list[dict]) -> tk.Menu:
365
+ def create_menu_items(items: list[dict], menu: tk.Menu = None) -> tk.Menu:
366
+ """Add flat or mixed items to a menu with icon and theme support.
367
+
368
+ Populates *menu* declaratively — flat commands, separators, and nested
369
+ cascades are all supported. Icons and theme-color updates are handled
370
+ automatically via ``MenuManager``.
371
+
372
+ Args:
373
+ items: List of item dicts. Supported keys: ``label``, ``icon``,
374
+ ``command``, ``type`` (``'command'``, ``'checkbutton'``,
375
+ ``'radiobutton'``, ``'separator'``), ``variable``, ``value``,
376
+ ``shortcut``, ``accelerator``, ``items`` (nested cascade).
377
+ menu: ``tk.Menu`` to populate. If ``None``, a new ``tk.Menu`` is
378
+ created under the current app (``get_current_app()``). For a
379
+ secondary window or dialog, pass a ``bs.Menu(dialog, tearoff=0)``
380
+ explicitly so icon tracking stays on the correct window.
381
+
382
+ Returns:
383
+ The populated ``tk.Menu``.
384
+
385
+ Example::
386
+
387
+ bs.MenuButton(app, text="File", menu=bs.create_menu_items(items)).pack()
388
+ """
389
+ if menu is None:
390
+ from bootstack.runtime.app import get_current_app
391
+ menu = tk.Menu(get_current_app(), tearoff=0)
392
+ root = menu.winfo_toplevel() if hasattr(menu, 'winfo_toplevel') else menu
393
+ if not hasattr(root, '_menu_manager'):
394
+ root._menu_manager = MenuManager(root)
395
+ root._menu_manager._add_menu_items(menu, items)
396
+ return menu
397
+
398
+
399
+ def create_menu(items: list[dict], parent: Any = None) -> tk.Menu:
367
400
  """Create a menu with icon and theme support.
368
401
 
369
- This is a convenience function that creates or retrieves a MenuManager
370
- for the parent window and uses it to build a menu from a declarative
371
- structure. The resulting menu automatically updates icon colors when
372
- the theme changes.
373
-
374
- Each menu item is defined by a dictionary that can contain:
375
- - **label** (str): The text displayed for the menu item
376
- - **icon** (str or dict): Icon specification. Can be a string icon
377
- name (e.g., "folder2-open") or a dict with 'name' and 'size' keys
378
- (e.g., {"name": "folder2-open", "size": 20})
379
- - **items** (list): List of submenu items for cascade menus
380
- - **command** (callable): Callback function executed when clicked
381
- - **type** (str): Menu item type - 'command', 'checkbutton',
382
- 'radiobutton', or 'separator'
383
- - **variable** (Variable): Tkinter variable for checkbutton/radiobutton
384
- - **value** (Any): Value for radiobutton items
385
- - **name** (str): Optional Tcl widget name for the cascade. On macOS
386
- three names trigger system-native menu integration: `'apple'`
387
- gives you the application menu (Tk auto-fills it with About,
388
- Hide, Hide Others, Show All, Quit; any items you add appear
389
- before the system items), `'window'` gets auto-populated with
390
- open Toplevels, and `'help'` enables system Help search.
391
- Ignored on Win/Linux.
392
- - **shortcut** (str): Platform-aware accelerator. Accepts a
393
- registered shortcut key (e.g. `'save'` if you've called
394
- `Shortcuts.register('save', 'Mod+S', save_file)`) or a
395
- modifier pattern like `'Mod+S'`, `'Ctrl+Shift+N'`, `'F5'`.
396
- Renders as `⌘S` on macOS and `Ctrl+S` on Win/Linux.
397
- For the actual keypress binding, register the shortcut and call
398
- `Shortcuts.bind_to(app)` — that's the canonical pathway.
399
- - **accelerator** (str): Legacy literal display string passed
400
- straight through to `tk.Menu` (e.g. `'Ctrl+S'`). No platform
401
- translation. Prefer `shortcut` for new code. If both are
402
- provided, `accelerator` wins.
403
- - Any other valid Tkinter menu item options (underline, etc.)
402
+ Builds a ``tk.Menu`` populated with cascade entries from *items*. Icons
403
+ and theme-color updates are handled automatically via ``MenuManager``.
404
+
405
+ The returned menu is not attached to anything — pass it to a
406
+ ``MenuButton``, assign it as a window menubar, or use it however you like.
407
+
408
+ Each top-level dict in *items* becomes a cascade (submenu group). Items
409
+ inside ``"items"`` are the actual commands. Supported keys per dict:
410
+
411
+ - **label** (str): Display text (message tokens are auto-translated).
412
+ - **icon** (str or dict): Bootstrap icon name, e.g. ``"folder2-open"``,
413
+ or ``{"name": "folder2-open", "size": 18}`` for a custom size.
414
+ - **items** (list): Nested sub-items creates a cascade.
415
+ - **command** (callable): Callback for ``'command'`` items.
416
+ - **type** (str): ``'command'`` (default), ``'checkbutton'``,
417
+ ``'radiobutton'``, or ``'separator'``.
418
+ - **variable** (Variable): Tk variable for checkbutton / radiobutton.
419
+ - **value**: Value for radiobutton items.
420
+ - **shortcut** (str): Platform-aware accelerator, e.g. ``'Mod+S'``.
421
+ Renders as ``⌘S`` on macOS and ``Ctrl+S`` on Win/Linux.
422
+ - **accelerator** (str): Literal accelerator string (legacy, no
423
+ platform translation). Prefer ``shortcut`` for new code.
424
+ - **name** (str): Tcl widget name for the cascade. On macOS, ``'apple'``,
425
+ ``'window'``, and ``'help'`` trigger system-native menu integration.
404
426
 
405
427
  Args:
406
- parent: The parent widget (Window, Toplevel, or Menu). If a Window
407
- or Toplevel is provided, the menu becomes the window's menubar.
408
- If a Menu is provided, items are added to that menu.
409
- items: List of dictionaries defining the menu structure. Each
410
- dictionary represents a menu item with its configuration.
428
+ items: List of dicts defining the cascade structure.
429
+ parent: Tk parent for the created ``tk.Menu`` and the window whose
430
+ ``MenuManager`` tracks icon theme updates. Defaults to the
431
+ current app (``get_current_app()``). Pass a specific
432
+ ``Toplevel`` or dialog when building a menu for a secondary
433
+ window so icon tracking stays on the correct window.
411
434
 
412
435
  Returns:
413
- The created Menu object. For window menubars, this is the menubar
414
- itself. For menus attached to other widgets, this is the menu.
436
+ The created ``tk.Menu``.
415
437
 
416
438
  Examples:
417
- Basic menubar with icons:
418
- ```python
419
- import bootstack as bs
420
-
421
- app = bs.App()
422
-
423
- menu_items = [
424
- {
425
- "label": "File",
426
- "items": [
427
- {"label": "New", "icon": "file-plus", "command": new_file},
428
- {"label": "Open", "icon": "folder2-open", "command": open_file},
429
- {"type": "separator"},
430
- {"label": "Exit", "icon": "x-circle", "command": app.quit}
431
- ]
432
- },
433
- {
434
- "label": "Edit",
435
- "items": [
436
- {"label": "Undo", "icon": "arrow-counterclockwise"},
437
- {"label": "Redo", "icon": "arrow-clockwise"}
438
- ]
439
- }
440
- ]
439
+ MenuButton (single-window app — parent optional)::
441
440
 
442
- bs.create_menu(app, menu_items)
443
- app.mainloop()
444
- ```
445
-
446
- Nested submenus with custom icon sizes:
447
- ```python
448
- menu_items = [
449
- {
450
- "label": "File",
451
- "items": [
452
- {
453
- "label": "Recent",
454
- "icon": {"name": "clock-history", "size": 18},
455
- "items": [
456
- {"label": "Document 1.txt"},
457
- {"label": "Document 2.txt"}
458
- ]
459
- }
460
- ]
461
- }
462
- ]
463
- ```
464
-
465
- Menu with checkbuttons and radiobuttons:
466
- ```python
467
- view_var = bs.BooleanVar(value=True)
468
- theme_var = bs.StringVar(value="light")
469
-
470
- menu_items = [
471
- {
472
- "label": "View",
473
- "items": [
474
- {
475
- "label": "Show Toolbar",
476
- "type": "checkbutton",
477
- "variable": view_var
478
- }
479
- ]
480
- },
481
- {
482
- "label": "Theme",
483
- "items": [
484
- {
485
- "label": "Light",
486
- "type": "radiobutton",
487
- "variable": theme_var,
488
- "value": "light"
489
- },
490
- {
491
- "label": "Dark",
492
- "type": "radiobutton",
493
- "variable": theme_var,
494
- "value": "dark"
495
- }
496
- ]
497
- }
498
- ]
499
- ```
441
+ bs.MenuButton(app, text="Menu", menu=bs.create_menu(items)).pack()
442
+
443
+ Window menubar::
444
+
445
+ app['menu'] = bs.create_menu(items)
446
+
447
+ Menu for a dialog (pass the Toplevel explicitly)::
448
+
449
+ dlg = bs.Toplevel(app)
450
+ bs.MenuButton(dlg, text="Menu", menu=bs.create_menu(items, parent=dlg)).pack()
500
451
  """
501
- # Get or create MenuManager for this window
502
- root = parent.winfo_toplevel() if hasattr(parent, 'winfo_toplevel') else parent
452
+ if parent is None:
453
+ from bootstack.runtime.app import get_current_app
454
+ parent = get_current_app()
503
455
 
456
+ root = parent.winfo_toplevel() if hasattr(parent, 'winfo_toplevel') else parent
504
457
  if not hasattr(root, '_menu_manager'):
505
458
  root._menu_manager = MenuManager(root)
506
459
 
507
460
  return root._menu_manager.create_menu(parent, items)
508
461
 
509
462
 
510
- __all__ = ['create_menu']
463
+ __all__ = ['create_menu', 'create_menu_items']