bootstack 0.1.0__py3-none-any.whl

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 (471) hide show
  1. bootstack/__init__.py +157 -0
  2. bootstack/__main__.py +5 -0
  3. bootstack/_core/__init__.py +21 -0
  4. bootstack/_core/capabilities/__init__.py +45 -0
  5. bootstack/_core/capabilities/after.py +103 -0
  6. bootstack/_core/capabilities/bind.py +192 -0
  7. bootstack/_core/capabilities/bindtags.py +112 -0
  8. bootstack/_core/capabilities/busy.py +72 -0
  9. bootstack/_core/capabilities/clipboard.py +89 -0
  10. bootstack/_core/capabilities/focus.py +118 -0
  11. bootstack/_core/capabilities/grab.py +65 -0
  12. bootstack/_core/capabilities/grid.py +211 -0
  13. bootstack/_core/capabilities/localization.py +231 -0
  14. bootstack/_core/capabilities/pack.py +140 -0
  15. bootstack/_core/capabilities/place.py +113 -0
  16. bootstack/_core/capabilities/selection.py +136 -0
  17. bootstack/_core/capabilities/signals.py +244 -0
  18. bootstack/_core/capabilities/winfo.py +315 -0
  19. bootstack/_core/colorutils.py +234 -0
  20. bootstack/_core/exceptions.py +25 -0
  21. bootstack/_core/images.py +463 -0
  22. bootstack/_core/mixins/__init__.py +1 -0
  23. bootstack/_core/mixins/ttk_state.py +35 -0
  24. bootstack/_core/mixins/widget.py +132 -0
  25. bootstack/_core/paths.py +49 -0
  26. bootstack/_core/publisher.py +149 -0
  27. bootstack/_core/variables.py +62 -0
  28. bootstack/_runtime/__init__.py +3 -0
  29. bootstack/_runtime/app.py +930 -0
  30. bootstack/_runtime/base_window.py +945 -0
  31. bootstack/_runtime/events.py +399 -0
  32. bootstack/_runtime/shortcuts.py +496 -0
  33. bootstack/_runtime/tk_patch.py +43 -0
  34. bootstack/_runtime/toplevel.py +276 -0
  35. bootstack/_runtime/utility.py +457 -0
  36. bootstack/_runtime/visual_focus.py +240 -0
  37. bootstack/_runtime/window_utilities.py +1123 -0
  38. bootstack/assets/__init__.py +21 -0
  39. bootstack/assets/bootstack.ico +0 -0
  40. bootstack/assets/bootstack.png +0 -0
  41. bootstack/assets/elements/__init__.py +0 -0
  42. bootstack/assets/elements/badge-pill.png +0 -0
  43. bootstack/assets/elements/badge-square.png +0 -0
  44. bootstack/assets/elements/button-compact.png +0 -0
  45. bootstack/assets/elements/button-default.png +0 -0
  46. bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  47. bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  48. bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  49. bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  50. bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  51. bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  52. bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  53. bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  54. bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  55. bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  56. bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  57. bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  58. bootstack/assets/elements/card.png +0 -0
  59. bootstack/assets/elements/checkbox-checked.png +0 -0
  60. bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  61. bootstack/assets/elements/checkbox-unchecked.png +0 -0
  62. bootstack/assets/elements/field.png +0 -0
  63. bootstack/assets/elements/input-addon-compact.png +0 -0
  64. bootstack/assets/elements/input-addon-default.png +0 -0
  65. bootstack/assets/elements/input-compact.png +0 -0
  66. bootstack/assets/elements/input-default.png +0 -0
  67. bootstack/assets/elements/list-item-separated.png +0 -0
  68. bootstack/assets/elements/list-item.png +0 -0
  69. bootstack/assets/elements/listrow-compact.png +0 -0
  70. bootstack/assets/elements/listrow-default.png +0 -0
  71. bootstack/assets/elements/manifest.toml +361 -0
  72. bootstack/assets/elements/menu-item.png +0 -0
  73. bootstack/assets/elements/navitem-compact.png +0 -0
  74. bootstack/assets/elements/navitem-default.png +0 -0
  75. bootstack/assets/elements/progressbar-h-compact.png +0 -0
  76. bootstack/assets/elements/progressbar-h-default.png +0 -0
  77. bootstack/assets/elements/progressbar-v-compact.png +0 -0
  78. bootstack/assets/elements/progressbar-v-default.png +0 -0
  79. bootstack/assets/elements/radiobutton.png +0 -0
  80. bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  81. bootstack/assets/elements/scrollbar-vertical.png +0 -0
  82. bootstack/assets/elements/slider-handle.png +0 -0
  83. bootstack/assets/elements/slider-track-h.png +0 -0
  84. bootstack/assets/elements/slider-track-v.png +0 -0
  85. bootstack/assets/elements/switch-off.png +0 -0
  86. bootstack/assets/elements/switch-on.png +0 -0
  87. bootstack/assets/elements/tab-h.png +0 -0
  88. bootstack/assets/elements/tab-v.png +0 -0
  89. bootstack/assets/icons/bootstrap.ttf +0 -0
  90. bootstack/assets/icons/glyphmap.json +2080 -0
  91. bootstack/assets/icons/icon_metrics.json +12470 -0
  92. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  93. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +856 -0
  94. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  95. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +878 -0
  96. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  97. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +856 -0
  98. bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  99. bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +856 -0
  100. bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  101. bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +856 -0
  102. bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  103. bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +878 -0
  104. bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  105. bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +856 -0
  106. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  107. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +856 -0
  108. bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  109. bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +854 -0
  110. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  111. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +845 -0
  112. bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  113. bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +844 -0
  114. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  115. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +917 -0
  116. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  117. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +845 -0
  118. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  119. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +844 -0
  120. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  121. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +844 -0
  122. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  123. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +845 -0
  124. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  125. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +845 -0
  126. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  127. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +845 -0
  128. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  129. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +845 -0
  130. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  131. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +845 -0
  132. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  133. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +845 -0
  134. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  135. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +845 -0
  136. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  137. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +845 -0
  138. bootstack/cli/__init__.py +133 -0
  139. bootstack/cli/__main__.py +6 -0
  140. bootstack/cli/add.py +395 -0
  141. bootstack/cli/appicon.py +285 -0
  142. bootstack/cli/build.py +115 -0
  143. bootstack/cli/config.py +313 -0
  144. bootstack/cli/demo.py +564 -0
  145. bootstack/cli/dev.py +153 -0
  146. bootstack/cli/doctor.py +195 -0
  147. bootstack/cli/icons.py +98 -0
  148. bootstack/cli/promote.py +120 -0
  149. bootstack/cli/pyinstaller.py +268 -0
  150. bootstack/cli/run.py +95 -0
  151. bootstack/cli/start.py +117 -0
  152. bootstack/cli/templates/__init__.py +931 -0
  153. bootstack/clipboard.py +48 -0
  154. bootstack/constants.py +318 -0
  155. bootstack/data/README.md +615 -0
  156. bootstack/data/__init__.py +78 -0
  157. bootstack/data/_observable.py +276 -0
  158. bootstack/data/base.py +780 -0
  159. bootstack/data/file_source.py +367 -0
  160. bootstack/data/memory_source.py +450 -0
  161. bootstack/data/query.py +367 -0
  162. bootstack/data/readers.py +289 -0
  163. bootstack/data/sqlite_source.py +869 -0
  164. bootstack/data/types.py +354 -0
  165. bootstack/data/writers.py +232 -0
  166. bootstack/dev/__init__.py +36 -0
  167. bootstack/dev/_capture.py +141 -0
  168. bootstack/dev/_env.py +43 -0
  169. bootstack/dev/_registry.py +140 -0
  170. bootstack/dev/_reloader.py +351 -0
  171. bootstack/dev/_reset.py +50 -0
  172. bootstack/dev/_watcher.py +91 -0
  173. bootstack/dialogs/__init__.py +948 -0
  174. bootstack/dialogs/_impl/__init__.py +47 -0
  175. bootstack/dialogs/_impl/colorchooser.py +588 -0
  176. bootstack/dialogs/_impl/datedialog.py +450 -0
  177. bootstack/dialogs/_impl/dialog.py +594 -0
  178. bootstack/dialogs/_impl/filterdialog.py +358 -0
  179. bootstack/dialogs/_impl/fontdialog.py +364 -0
  180. bootstack/dialogs/_impl/formdialog.py +564 -0
  181. bootstack/dialogs/_impl/message.py +486 -0
  182. bootstack/dialogs/_impl/query.py +570 -0
  183. bootstack/errors.py +67 -0
  184. bootstack/events/__init__.py +111 -0
  185. bootstack/events/_event.py +135 -0
  186. bootstack/events/_payloads.py +539 -0
  187. bootstack/events/_subscription.py +38 -0
  188. bootstack/i18n/README.md +77 -0
  189. bootstack/i18n/__init__.py +23 -0
  190. bootstack/i18n/catalog.py +121 -0
  191. bootstack/i18n/intl_format.py +584 -0
  192. bootstack/i18n/msgcat.py +425 -0
  193. bootstack/i18n/specs.py +156 -0
  194. bootstack/images.py +563 -0
  195. bootstack/py.typed +1 -0
  196. bootstack/scheduling/__init__.py +11 -0
  197. bootstack/scheduling/_schedule.py +218 -0
  198. bootstack/shortcuts.py +21 -0
  199. bootstack/signals/README.md +98 -0
  200. bootstack/signals/__init__.py +10 -0
  201. bootstack/signals/integration.py +100 -0
  202. bootstack/signals/signal.py +353 -0
  203. bootstack/signals/types.py +6 -0
  204. bootstack/store.py +286 -0
  205. bootstack/streams/__init__.py +12 -0
  206. bootstack/streams/_stream.py +321 -0
  207. bootstack/style/__init__.py +38 -0
  208. bootstack/style/builders/__init__.py +51 -0
  209. bootstack/style/builders/badge.py +46 -0
  210. bootstack/style/builders/button.py +339 -0
  211. bootstack/style/builders/buttongroup.py +311 -0
  212. bootstack/style/builders/calendar.py +271 -0
  213. bootstack/style/builders/checkbutton.py +110 -0
  214. bootstack/style/builders/combobox.py +113 -0
  215. bootstack/style/builders/contextmenu.py +268 -0
  216. bootstack/style/builders/entry.py +82 -0
  217. bootstack/style/builders/expander.py +148 -0
  218. bootstack/style/builders/field.py +335 -0
  219. bootstack/style/builders/frame.py +50 -0
  220. bootstack/style/builders/label.py +28 -0
  221. bootstack/style/builders/labelframe.py +34 -0
  222. bootstack/style/builders/listview.py +369 -0
  223. bootstack/style/builders/menubar.py +91 -0
  224. bootstack/style/builders/menubutton.py +359 -0
  225. bootstack/style/builders/panedwindow.py +25 -0
  226. bootstack/style/builders/progressbar.py +67 -0
  227. bootstack/style/builders/radiobutton.py +99 -0
  228. bootstack/style/builders/scale.py +64 -0
  229. bootstack/style/builders/scrollbar.py +225 -0
  230. bootstack/style/builders/separator.py +49 -0
  231. bootstack/style/builders/sidenav.py +643 -0
  232. bootstack/style/builders/sizegrip.py +15 -0
  233. bootstack/style/builders/spinbox.py +119 -0
  234. bootstack/style/builders/switch.py +70 -0
  235. bootstack/style/builders/tabitem.py +204 -0
  236. bootstack/style/builders/togglegroup.py +294 -0
  237. bootstack/style/builders/toolbutton.py +275 -0
  238. bootstack/style/builders/tooltip.py +26 -0
  239. bootstack/style/builders/treeview.py +193 -0
  240. bootstack/style/builders/utils.py +455 -0
  241. bootstack/style/builders_tk/__init__.py +16 -0
  242. bootstack/style/builders_tk/defaults.py +229 -0
  243. bootstack/style/element.py +173 -0
  244. bootstack/style/fonts.py +123 -0
  245. bootstack/style/style.py +609 -0
  246. bootstack/style/style_builder_base.py +716 -0
  247. bootstack/style/style_builder_mixed.py +93 -0
  248. bootstack/style/style_builder_tk.py +109 -0
  249. bootstack/style/style_builder_ttk.py +353 -0
  250. bootstack/style/style_resolver.py +447 -0
  251. bootstack/style/theme.py +245 -0
  252. bootstack/style/theme_provider.py +471 -0
  253. bootstack/style/themes/__init__.py +128 -0
  254. bootstack/style/tk_patch.py +5 -0
  255. bootstack/style/token_maps.py +41 -0
  256. bootstack/style/types.py +32 -0
  257. bootstack/style/typography.py +523 -0
  258. bootstack/style/utility.py +746 -0
  259. bootstack/types.py +39 -0
  260. bootstack/validation/__init__.py +6 -0
  261. bootstack/validation/types.py +15 -0
  262. bootstack/validation/validation_result.py +17 -0
  263. bootstack/validation/validation_rules.py +205 -0
  264. bootstack/widgets/__init__.py +74 -0
  265. bootstack/widgets/_core/__init__.py +31 -0
  266. bootstack/widgets/_core/app_config.py +266 -0
  267. bootstack/widgets/_core/base.py +461 -0
  268. bootstack/widgets/_core/container.py +334 -0
  269. bootstack/widgets/_core/context.py +35 -0
  270. bootstack/widgets/_core/events.py +130 -0
  271. bootstack/widgets/_core/field_mixin.py +353 -0
  272. bootstack/widgets/_core/icon_image_props.py +72 -0
  273. bootstack/widgets/_core/image_binding.py +93 -0
  274. bootstack/widgets/_core/navmodel.py +345 -0
  275. bootstack/widgets/_core/options.py +210 -0
  276. bootstack/widgets/_core/selection_group.py +130 -0
  277. bootstack/widgets/_core/window_controls.py +96 -0
  278. bootstack/widgets/_core/window_menu.py +246 -0
  279. bootstack/widgets/_impl/__init__.py +1 -0
  280. bootstack/widgets/_impl/_internal/__init__.py +0 -0
  281. bootstack/widgets/_impl/_internal/wrapper_base.py +307 -0
  282. bootstack/widgets/_impl/_parts/__init__.py +11 -0
  283. bootstack/widgets/_impl/_parts/numberentry_part.py +385 -0
  284. bootstack/widgets/_impl/_parts/spinnerentry_part.py +434 -0
  285. bootstack/widgets/_impl/_parts/textentry_part.py +406 -0
  286. bootstack/widgets/_impl/composites/__init__.py +33 -0
  287. bootstack/widgets/_impl/composites/_dateutils.py +33 -0
  288. bootstack/widgets/_impl/composites/_image_fit.py +105 -0
  289. bootstack/widgets/_impl/composites/accordion.py +381 -0
  290. bootstack/widgets/_impl/composites/avatar.py +191 -0
  291. bootstack/widgets/_impl/composites/buttongroup.py +371 -0
  292. bootstack/widgets/_impl/composites/calendar.py +972 -0
  293. bootstack/widgets/_impl/composites/carousel.py +567 -0
  294. bootstack/widgets/_impl/composites/chart.py +882 -0
  295. bootstack/widgets/_impl/composites/compositeframe.py +298 -0
  296. bootstack/widgets/_impl/composites/contextmenu.py +1951 -0
  297. bootstack/widgets/_impl/composites/dateentry.py +404 -0
  298. bootstack/widgets/_impl/composites/dropdownbutton.py +325 -0
  299. bootstack/widgets/_impl/composites/expander.py +515 -0
  300. bootstack/widgets/_impl/composites/field.py +670 -0
  301. bootstack/widgets/_impl/composites/form.py +1066 -0
  302. bootstack/widgets/_impl/composites/gallery.py +551 -0
  303. bootstack/widgets/_impl/composites/list/__init__.py +15 -0
  304. bootstack/widgets/_impl/composites/list/listitem.py +802 -0
  305. bootstack/widgets/_impl/composites/list/listview.py +1433 -0
  306. bootstack/widgets/_impl/composites/menu/__init__.py +18 -0
  307. bootstack/widgets/_impl/composites/menu/model.py +358 -0
  308. bootstack/widgets/_impl/composites/menu/render_native.py +134 -0
  309. bootstack/widgets/_impl/composites/menu/render_themed.py +134 -0
  310. bootstack/widgets/_impl/composites/meter.py +860 -0
  311. bootstack/widgets/_impl/composites/numericentry.py +201 -0
  312. bootstack/widgets/_impl/composites/pagestack.py +395 -0
  313. bootstack/widgets/_impl/composites/passwordentry.py +142 -0
  314. bootstack/widgets/_impl/composites/pathentry.py +168 -0
  315. bootstack/widgets/_impl/composites/picture.py +289 -0
  316. bootstack/widgets/_impl/composites/radiogroup.py +511 -0
  317. bootstack/widgets/_impl/composites/scrolledtext.py +375 -0
  318. bootstack/widgets/_impl/composites/scrolledtext.pyi +186 -0
  319. bootstack/widgets/_impl/composites/scrollview.py +764 -0
  320. bootstack/widgets/_impl/composites/selectbox.py +1026 -0
  321. bootstack/widgets/_impl/composites/shell/__init__.py +40 -0
  322. bootstack/widgets/_impl/composites/shell/content_host.py +52 -0
  323. bootstack/widgets/_impl/composites/shell/layout.py +335 -0
  324. bootstack/widgets/_impl/composites/shell/nav_panel.py +345 -0
  325. bootstack/widgets/_impl/composites/shell/providers.py +558 -0
  326. bootstack/widgets/_impl/composites/shell/rail.py +117 -0
  327. bootstack/widgets/_impl/composites/shell/shell.py +581 -0
  328. bootstack/widgets/_impl/composites/shell/workspace.py +273 -0
  329. bootstack/widgets/_impl/composites/sidenav/__init__.py +16 -0
  330. bootstack/widgets/_impl/composites/sidenav/header.py +81 -0
  331. bootstack/widgets/_impl/composites/sidenav/separator.py +44 -0
  332. bootstack/widgets/_impl/composites/slider/__init__.py +7 -0
  333. bootstack/widgets/_impl/composites/slider/_shared.py +195 -0
  334. bootstack/widgets/_impl/composites/slider/rangeslider.py +982 -0
  335. bootstack/widgets/_impl/composites/slider/slider.py +851 -0
  336. bootstack/widgets/_impl/composites/spinnerentry.py +185 -0
  337. bootstack/widgets/_impl/composites/tableview/__init__.py +5 -0
  338. bootstack/widgets/_impl/composites/tableview/tableview.py +3388 -0
  339. bootstack/widgets/_impl/composites/tableview/types.py +169 -0
  340. bootstack/widgets/_impl/composites/tabs/__init__.py +23 -0
  341. bootstack/widgets/_impl/composites/tabs/tabitem.py +389 -0
  342. bootstack/widgets/_impl/composites/tabs/tabs.py +974 -0
  343. bootstack/widgets/_impl/composites/tabs/tabview.py +650 -0
  344. bootstack/widgets/_impl/composites/textarea/__init__.py +26 -0
  345. bootstack/widgets/_impl/composites/textarea/change.py +46 -0
  346. bootstack/widgets/_impl/composites/textarea/codeeditor.py +526 -0
  347. bootstack/widgets/_impl/composites/textarea/core.py +495 -0
  348. bootstack/widgets/_impl/composites/textarea/decoration.py +42 -0
  349. bootstack/widgets/_impl/composites/textarea/diff.py +127 -0
  350. bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +1 -0
  351. bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +138 -0
  352. bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +158 -0
  353. bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +138 -0
  354. bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +312 -0
  355. bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
  356. bootstack/widgets/_impl/composites/textarea/filter.py +171 -0
  357. bootstack/widgets/_impl/composites/textarea/search_overlay.py +459 -0
  358. bootstack/widgets/_impl/composites/textarea/sidebar.py +88 -0
  359. bootstack/widgets/_impl/composites/textarea/style_registry.py +178 -0
  360. bootstack/widgets/_impl/composites/textarea/textarea.py +606 -0
  361. bootstack/widgets/_impl/composites/textarea/undo.py +217 -0
  362. bootstack/widgets/_impl/composites/textentry.py +57 -0
  363. bootstack/widgets/_impl/composites/timeentry.py +176 -0
  364. bootstack/widgets/_impl/composites/toast.py +390 -0
  365. bootstack/widgets/_impl/composites/toast_stack.py +156 -0
  366. bootstack/widgets/_impl/composites/togglegroup.py +418 -0
  367. bootstack/widgets/_impl/composites/toolbar.py +608 -0
  368. bootstack/widgets/_impl/composites/tooltip.py +491 -0
  369. bootstack/widgets/_impl/composites/tree/__init__.py +7 -0
  370. bootstack/widgets/_impl/composites/tree/source_binding.py +136 -0
  371. bootstack/widgets/_impl/composites/tree/treeitem.py +393 -0
  372. bootstack/widgets/_impl/composites/tree/treenode.py +174 -0
  373. bootstack/widgets/_impl/composites/tree/treeview.py +841 -0
  374. bootstack/widgets/_impl/mixins/__init__.py +24 -0
  375. bootstack/widgets/_impl/mixins/configure_mixin.py +216 -0
  376. bootstack/widgets/_impl/mixins/entry_mixin.py +134 -0
  377. bootstack/widgets/_impl/mixins/font_mixin.py +368 -0
  378. bootstack/widgets/_impl/mixins/icon_mixin.py +61 -0
  379. bootstack/widgets/_impl/mixins/localization_mixin.py +253 -0
  380. bootstack/widgets/_impl/mixins/signal_mixin.py +268 -0
  381. bootstack/widgets/_impl/mixins/validation_mixin.py +226 -0
  382. bootstack/widgets/_impl/primitives/__init__.py +49 -0
  383. bootstack/widgets/_impl/primitives/_menubutton.py +107 -0
  384. bootstack/widgets/_impl/primitives/badge.py +45 -0
  385. bootstack/widgets/_impl/primitives/button.py +76 -0
  386. bootstack/widgets/_impl/primitives/card.py +45 -0
  387. bootstack/widgets/_impl/primitives/checkbutton.py +124 -0
  388. bootstack/widgets/_impl/primitives/checktoggle.py +62 -0
  389. bootstack/widgets/_impl/primitives/combobox.py +156 -0
  390. bootstack/widgets/_impl/primitives/entry.py +87 -0
  391. bootstack/widgets/_impl/primitives/flexframe.py +448 -0
  392. bootstack/widgets/_impl/primitives/frame.py +185 -0
  393. bootstack/widgets/_impl/primitives/gridframe.py +546 -0
  394. bootstack/widgets/_impl/primitives/label.py +84 -0
  395. bootstack/widgets/_impl/primitives/labelframe.py +54 -0
  396. bootstack/widgets/_impl/primitives/optionmenu.py +387 -0
  397. bootstack/widgets/_impl/primitives/packframe.py +227 -0
  398. bootstack/widgets/_impl/primitives/panedwindow.py +45 -0
  399. bootstack/widgets/_impl/primitives/progressbar.py +83 -0
  400. bootstack/widgets/_impl/primitives/radiobutton.py +115 -0
  401. bootstack/widgets/_impl/primitives/radiotoggle.py +54 -0
  402. bootstack/widgets/_impl/primitives/scrollbar.py +42 -0
  403. bootstack/widgets/_impl/primitives/separator.py +43 -0
  404. bootstack/widgets/_impl/primitives/sizegrip.py +33 -0
  405. bootstack/widgets/_impl/primitives/spinbox.py +95 -0
  406. bootstack/widgets/_impl/primitives/switch.py +44 -0
  407. bootstack/widgets/_impl/primitives/treeview.py +69 -0
  408. bootstack/widgets/app.py +371 -0
  409. bootstack/widgets/appshell.py +1179 -0
  410. bootstack/widgets/avatar.py +140 -0
  411. bootstack/widgets/boolean_controls.py +455 -0
  412. bootstack/widgets/button.py +224 -0
  413. bootstack/widgets/buttongroup.py +239 -0
  414. bootstack/widgets/calendar.py +195 -0
  415. bootstack/widgets/card.py +159 -0
  416. bootstack/widgets/carousel.py +241 -0
  417. bootstack/widgets/chart.py +302 -0
  418. bootstack/widgets/codeeditor.py +675 -0
  419. bootstack/widgets/contextmenu.py +371 -0
  420. bootstack/widgets/datatable.py +688 -0
  421. bootstack/widgets/datefield.py +395 -0
  422. bootstack/widgets/divider.py +60 -0
  423. bootstack/widgets/expander.py +579 -0
  424. bootstack/widgets/form.py +200 -0
  425. bootstack/widgets/gallery.py +250 -0
  426. bootstack/widgets/gauge.py +168 -0
  427. bootstack/widgets/grid.py +121 -0
  428. bootstack/widgets/groupbox.py +162 -0
  429. bootstack/widgets/label.py +229 -0
  430. bootstack/widgets/listview.py +354 -0
  431. bootstack/widgets/menubutton.py +419 -0
  432. bootstack/widgets/numberfield.py +431 -0
  433. bootstack/widgets/pagestack.py +345 -0
  434. bootstack/widgets/passwordfield.py +383 -0
  435. bootstack/widgets/pathfield.py +454 -0
  436. bootstack/widgets/picture.py +251 -0
  437. bootstack/widgets/progressbar.py +106 -0
  438. bootstack/widgets/radio_variants.py +271 -0
  439. bootstack/widgets/radiogroup.py +228 -0
  440. bootstack/widgets/scrollbar.py +64 -0
  441. bootstack/widgets/scrollview.py +186 -0
  442. bootstack/widgets/select.py +302 -0
  443. bootstack/widgets/selectbutton.py +182 -0
  444. bootstack/widgets/sidebar_toggle.py +130 -0
  445. bootstack/widgets/sizegrip.py +42 -0
  446. bootstack/widgets/slider.py +408 -0
  447. bootstack/widgets/spinbox.py +147 -0
  448. bootstack/widgets/spinnerfield.py +413 -0
  449. bootstack/widgets/splash.py +367 -0
  450. bootstack/widgets/splitview.py +482 -0
  451. bootstack/widgets/stacks.py +249 -0
  452. bootstack/widgets/statusbar.py +189 -0
  453. bootstack/widgets/tabs.py +425 -0
  454. bootstack/widgets/textarea.py +459 -0
  455. bootstack/widgets/textfield.py +410 -0
  456. bootstack/widgets/theme_toggle.py +92 -0
  457. bootstack/widgets/timefield.py +340 -0
  458. bootstack/widgets/toast.py +314 -0
  459. bootstack/widgets/togglegroup.py +231 -0
  460. bootstack/widgets/toolbar.py +347 -0
  461. bootstack/widgets/tooltip.py +94 -0
  462. bootstack/widgets/tree.py +648 -0
  463. bootstack/widgets/types.py +305 -0
  464. bootstack/widgets/window.py +307 -0
  465. bootstack-0.1.0.dist-info/METADATA +301 -0
  466. bootstack-0.1.0.dist-info/RECORD +471 -0
  467. bootstack-0.1.0.dist-info/WHEEL +5 -0
  468. bootstack-0.1.0.dist-info/entry_points.txt +2 -0
  469. bootstack-0.1.0.dist-info/licenses/LICENSE +21 -0
  470. bootstack-0.1.0.dist-info/licenses/NOTICE +10 -0
  471. bootstack-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,395 @@
1
+ from __future__ import annotations
2
+
3
+ import tkinter
4
+ from datetime import date
5
+ from typing import overload, Any, Callable, Iterable, Literal, TYPE_CHECKING
6
+
7
+ from bootstack.widgets._impl.composites.dateentry import DateEntry as _InternalDateEntry
8
+ from bootstack.widgets._core.base import PublicWidgetBase, adapt_handler
9
+ from bootstack.widgets._core.events import resolve_event, register_widget_events
10
+ from bootstack.widgets._core.field_mixin import FieldAddonMixin, ValueSignalMixin
11
+ from bootstack.events import ChangeEvent, Subscription, ValidationEvent
12
+ from bootstack.streams import Stream
13
+ from bootstack.widgets.textfield import _INNER_ENTRY_SEQUENCES
14
+ from bootstack.widgets.types import AccentToken, Event, WidgetDensity
15
+
16
+ if TYPE_CHECKING:
17
+ from bootstack.signals import Signal
18
+
19
+ _DATEFIELD_EVENTS: dict[str, str] = {
20
+ "change": "<<Change>>",
21
+ "validate": "<<Validate>>",
22
+ "valid": "<<Valid>>",
23
+ "invalid": "<<Invalid>>",
24
+ "submit": "<Return>",
25
+ "focus": "<FocusIn>",
26
+ "blur": "<FocusOut>",
27
+ }
28
+
29
+
30
+ class DateField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
31
+ """A date input field with an optional calendar picker button.
32
+
33
+ In `'single'` mode `value` returns a `date`; in `'range'` mode it returns
34
+ a `(start, end)` tuple of dates.
35
+
36
+ Args:
37
+ value: Initial date value — a `date` object or an ISO string
38
+ (`'YYYY-MM-DD'`). `None` for an empty field.
39
+ value_format: Format applied to the displayed date — a named preset
40
+ (e.g. `'shortDate'`, `'longDate'`) or a custom pattern (e.g.
41
+ `'dd.MM.yy'`). Default `'longDate'`. See
42
+ :ref:`format specs <value-formats>`.
43
+ label: Label displayed above the field.
44
+ message: Hint text displayed below the field.
45
+ signal: Reactive `Signal` two-way bound to the field's `date` value (not
46
+ its text). When given, it seeds the initial value. This is the usual
47
+ way to bind a date field.
48
+ show_picker_button: Show the calendar icon button. Default `True`.
49
+ picker_title: Title of the picker dialog.
50
+ picker_first_weekday: First day of week in the picker (0=Mon … 6=Sun).
51
+ Default `6` (Sunday).
52
+ selection_mode: Single date or a start/end range. In range mode the
53
+ entry is read-only and dates must be selected via the picker.
54
+ Default `'single'`.
55
+ range_start: Pre-selected range start date (range mode only).
56
+ range_end: Pre-selected range end date (range mode only).
57
+ min_date: Earliest selectable date.
58
+ max_date: Latest selectable date.
59
+ disabled_dates: Dates that cannot be selected.
60
+ required: Mark field as required; blocks empty submission.
61
+ disabled: If `True`, field is non-interactive.
62
+ read_only: If `True`, value is visible but not editable.
63
+ accent: Accent color applied to the focus ring. Default `'primary'`.
64
+ density: Widget density.
65
+ parent: Override the context-stack parent.
66
+ **kwargs: Layout placement options applied by the parent container —
67
+ `fill`, `expand`, `anchor`, `margin`, `row`, `column`, `sticky`.
68
+ See :doc:`/tasks/layout`.
69
+ """
70
+
71
+ _VALIDATION_KIND = "date"
72
+
73
+ def __init__(
74
+ self,
75
+ value: str | date | None = None,
76
+ *,
77
+ signal: "Signal | None" = None,
78
+ value_format: str = "longDate",
79
+ label: str | None = None,
80
+ message: str | None = None,
81
+ show_picker_button: bool = True,
82
+ picker_title: str | None = None,
83
+ picker_first_weekday: int = 6,
84
+ selection_mode: Literal["single", "range"] = "single",
85
+ range_start: date | str | None = None,
86
+ range_end: date | str | None = None,
87
+ min_date: date | str | None = None,
88
+ max_date: date | str | None = None,
89
+ disabled_dates: Iterable[date | str] | None = None,
90
+ required: bool = False,
91
+ disabled: bool = False,
92
+ read_only: bool = False,
93
+ accent: AccentToken | str | None = None,
94
+ density: WidgetDensity | None = None,
95
+ parent: Any = None,
96
+ **kwargs: Any,
97
+ ) -> None:
98
+ self._parent = self._resolve_parent(parent)
99
+ layout_kw = self._split_layout_kwargs(kwargs)
100
+ if "textsignal" in kwargs:
101
+ raise TypeError(
102
+ "DateField does not accept 'textsignal=' — a date field binds its "
103
+ "date value. Use signal= with a date-typed Signal "
104
+ "(e.g. Signal(date.today()))."
105
+ )
106
+
107
+ tk_master = self._parent._child_master() if self._parent else None
108
+
109
+ internal_kwargs: dict[str, Any] = {
110
+ "value_format": value_format,
111
+ "show_picker_button": show_picker_button,
112
+ "picker_first_weekday": picker_first_weekday,
113
+ "selection_mode": selection_mode,
114
+ }
115
+ if value is not None:
116
+ internal_kwargs["value"] = value
117
+ if label is not None:
118
+ internal_kwargs["label"] = label
119
+ if message is not None:
120
+ internal_kwargs["message"] = message
121
+ if picker_title is not None:
122
+ internal_kwargs["picker_title"] = picker_title
123
+ if range_start is not None:
124
+ internal_kwargs["start_date"] = range_start
125
+ if range_end is not None:
126
+ internal_kwargs["end_date"] = range_end
127
+ if min_date is not None:
128
+ internal_kwargs["min_date"] = min_date
129
+ if max_date is not None:
130
+ internal_kwargs["max_date"] = max_date
131
+ if disabled_dates is not None:
132
+ internal_kwargs["disabled_dates"] = disabled_dates
133
+ if required:
134
+ internal_kwargs["required"] = True
135
+ if disabled:
136
+ internal_kwargs["state"] = "disabled"
137
+ elif read_only:
138
+ internal_kwargs["state"] = "readonly"
139
+ if accent is not None:
140
+ internal_kwargs["accent"] = accent
141
+ if density is not None:
142
+ internal_kwargs["density"] = density
143
+
144
+ self._internal = _InternalDateEntry(tk_master, **internal_kwargs)
145
+ self._attach_to_parent(layout_kw)
146
+
147
+ if signal is not None:
148
+ self._bind_value_signal(signal)
149
+
150
+ # ----- Event routing -----
151
+
152
+ def _entry_widget(self) -> tkinter.Misc:
153
+ return self._internal._entry
154
+
155
+ @overload
156
+ def on(self, event: str) -> Stream: ...
157
+ @overload
158
+ def on(self, event: str, handler: Callable[[Event], Any]) -> Subscription: ...
159
+ def on(self, event: str, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
160
+ """Register a callback for an event by name.
161
+
162
+ A generic, string-keyed escape hatch — prefer the typed `on_*`
163
+ shorthands (e.g. `on_change`), which carry the precise payload type.
164
+ Called with no handler, returns a composable `Stream`; with a handler,
165
+ binds it and returns a `Subscription`.
166
+
167
+ Args:
168
+ event: Event name (for example `'change'` or `'focus'`).
169
+ handler: Called with the event payload. Omit to get a composable
170
+ :class:`~bootstack.streams.Stream` instead.
171
+
172
+ Returns:
173
+ A cancellable :class:`~bootstack.events.Subscription` when a handler
174
+ is given, otherwise a :class:`~bootstack.streams.Stream`.
175
+ """
176
+ sequence = resolve_event(self, str(event))
177
+ widget = self._entry_widget() if sequence in _INNER_ENTRY_SEQUENCES else self._internal
178
+ if handler is None:
179
+ from bootstack.streams import Stream as _Stream
180
+ def _source(h):
181
+ _w = self._entry_widget() if sequence in _INNER_ENTRY_SEQUENCES else self._internal
182
+ _bid = _w.bind(sequence, adapt_handler(h), add="+")
183
+ return Subscription(_w, sequence, _bid)
184
+ return _Stream(self._internal, _source=_source)
185
+ bind_id = widget.bind(sequence, adapt_handler(handler), add="+")
186
+ return Subscription(widget, sequence, bind_id)
187
+
188
+ # ----- Properties -----
189
+
190
+ @property
191
+ def picker_button(self):
192
+ """The calendar picker button widget, or `None` if hidden."""
193
+ return self._internal.addons.get('date-picker')
194
+
195
+ @property
196
+ def value(self) -> "date | tuple[date, date] | None":
197
+ """Selected date, or `(start, end)` tuple in range mode."""
198
+ return self._internal.value
199
+
200
+ @value.setter
201
+ def value(self, v: "date | str | None") -> None:
202
+ self._internal.value = v
203
+ self._sync_value_set(self._internal.value)
204
+
205
+ @property
206
+ def disabled(self) -> bool:
207
+ """Whether the field is disabled (non-interactive and greyed out)."""
208
+ return str(self._entry_widget().cget("state")) == "disabled"
209
+
210
+ @disabled.setter
211
+ def disabled(self, v: bool) -> None:
212
+ self._internal.configure(state="disabled" if v else "normal")
213
+
214
+ @property
215
+ def read_only(self) -> bool:
216
+ """Whether the field is read-only (selectable but not editable)."""
217
+ return str(self._entry_widget().cget("state")) == "readonly"
218
+
219
+ @read_only.setter
220
+ def read_only(self, v: bool) -> None:
221
+ self._internal.configure(state="readonly" if v else "normal")
222
+
223
+ # ----- Date constraints -----
224
+
225
+ @property
226
+ def min_date(self) -> date | None:
227
+ """Earliest selectable date. Assigning takes effect the next time the picker opens."""
228
+ return self._internal._coerce_date(self._internal._min_date)
229
+
230
+ @min_date.setter
231
+ def min_date(self, value: date | str | None) -> None:
232
+ self._internal.set_min_date(value)
233
+
234
+ @property
235
+ def max_date(self) -> date | None:
236
+ """Latest selectable date. Assigning takes effect the next time the picker opens."""
237
+ return self._internal._coerce_date(self._internal._max_date)
238
+
239
+ @max_date.setter
240
+ def max_date(self, value: date | str | None) -> None:
241
+ self._internal.set_max_date(value)
242
+
243
+ @property
244
+ def disabled_dates(self) -> tuple[date, ...]:
245
+ """Dates disabled in the picker. Assigning a new iterable takes effect the next time it opens."""
246
+ raw = self._internal._disabled_dates or []
247
+ coerce = self._internal._coerce_date
248
+ return tuple(sorted(d for d in (coerce(x) for x in raw) if d is not None))
249
+
250
+ @disabled_dates.setter
251
+ def disabled_dates(self, value: Iterable[date | str] | None) -> None:
252
+ self._internal.set_disabled_dates(value)
253
+
254
+ # ----- Methods -----
255
+
256
+ def validate(self) -> bool:
257
+ """Run validation rules against the current value.
258
+
259
+ Returns:
260
+ `True` if all rules pass, `False` otherwise.
261
+ """
262
+ entry = self._internal._entry
263
+ return entry.validate(entry._get_validation_value(), trigger="manual")
264
+
265
+ def focus(self) -> None:
266
+ """Give keyboard focus to this field."""
267
+ self._entry_widget().focus_set()
268
+
269
+ def clear(self) -> None:
270
+ """Clear the field, setting the value to `None`."""
271
+ self._internal.value = None
272
+
273
+ # ----- Event shorthands -----
274
+
275
+ @overload
276
+ def on_change(self) -> Stream: ...
277
+ @overload
278
+ def on_change(self, handler: Callable[[ChangeEvent], Any]) -> Subscription: ...
279
+ def on_change(self, handler: Callable[[ChangeEvent], Any] | None = None) -> Stream | Subscription:
280
+ """Register a callback fired when the selected date changes.
281
+
282
+ Args:
283
+ handler: Called with a :class:`~bootstack.events.ChangeEvent`. Omit to
284
+ get a composable :class:`~bootstack.streams.Stream` instead.
285
+
286
+ Returns:
287
+ A cancellable :class:`~bootstack.events.Subscription` when a
288
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
289
+ """
290
+ return self.on("change", handler)
291
+
292
+ @overload
293
+ def on_submit(self) -> Stream: ...
294
+ @overload
295
+ def on_submit(self, handler: Callable[[Event], Any]) -> Subscription: ...
296
+ def on_submit(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
297
+ """Register a callback fired when the user presses Return to confirm input.
298
+
299
+ Args:
300
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
301
+ get a composable :class:`~bootstack.streams.Stream` instead.
302
+
303
+ Returns:
304
+ A cancellable :class:`~bootstack.events.Subscription` when a
305
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
306
+ """
307
+ return self.on("submit", handler)
308
+
309
+ @overload
310
+ def on_valid(self) -> Stream: ...
311
+ @overload
312
+ def on_valid(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
313
+ def on_valid(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
314
+ """Register a callback fired when validation passes.
315
+
316
+ Args:
317
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
318
+ get a composable :class:`~bootstack.streams.Stream` instead.
319
+
320
+ Returns:
321
+ A cancellable :class:`~bootstack.events.Subscription` when a
322
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
323
+ """
324
+ return self.on("valid", handler)
325
+
326
+ @overload
327
+ def on_invalid(self) -> Stream: ...
328
+ @overload
329
+ def on_invalid(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
330
+ def on_invalid(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
331
+ """Register a callback fired when validation fails.
332
+
333
+ Args:
334
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
335
+ get a composable :class:`~bootstack.streams.Stream` instead.
336
+
337
+ Returns:
338
+ A cancellable :class:`~bootstack.events.Subscription` when a
339
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
340
+ """
341
+ return self.on("invalid", handler)
342
+
343
+ @overload
344
+ def on_validate(self) -> Stream: ...
345
+ @overload
346
+ def on_validate(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
347
+ def on_validate(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
348
+ """Register a callback fired when a validation check runs.
349
+
350
+ Args:
351
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
352
+ get a composable :class:`~bootstack.streams.Stream` instead.
353
+
354
+ Returns:
355
+ A cancellable :class:`~bootstack.events.Subscription` when a
356
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
357
+ """
358
+ return self.on("validate", handler)
359
+
360
+ @overload
361
+ def on_focus(self) -> Stream: ...
362
+ @overload
363
+ def on_focus(self, handler: Callable[[Event], Any]) -> Subscription: ...
364
+ def on_focus(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
365
+ """Register a callback fired when the field gains keyboard focus.
366
+
367
+ Args:
368
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
369
+ get a composable :class:`~bootstack.streams.Stream` instead.
370
+
371
+ Returns:
372
+ A cancellable :class:`~bootstack.events.Subscription` when a
373
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
374
+ """
375
+ return self.on("focus", handler)
376
+
377
+ @overload
378
+ def on_blur(self) -> Stream: ...
379
+ @overload
380
+ def on_blur(self, handler: Callable[[Event], Any]) -> Subscription: ...
381
+ def on_blur(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
382
+ """Register a callback fired when the field loses keyboard focus.
383
+
384
+ Args:
385
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
386
+ get a composable :class:`~bootstack.streams.Stream` instead.
387
+
388
+ Returns:
389
+ A cancellable :class:`~bootstack.events.Subscription` when a
390
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
391
+ """
392
+ return self.on("blur", handler)
393
+
394
+
395
+ register_widget_events(DateField, _DATEFIELD_EVENTS)
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from bootstack.widgets._impl.primitives.separator import Separator as _InternalSeparator
6
+ from bootstack.widgets._core.base import PublicWidgetBase
7
+ from bootstack.widgets._core.events import register_widget_events
8
+ from bootstack.widgets.types import AccentToken, Orient
9
+
10
+
11
+ class Divider(PublicWidgetBase):
12
+ """A horizontal or vertical dividing line.
13
+
14
+ Renders a thin themed line that can be used to visually divide sections
15
+ of a layout. The line color inherits from the active surface by default
16
+ and can be overridden with an accent token. (For invisible flexible space
17
+ between items, use :class:`Spacer <bootstack.Spacer>` instead.)
18
+
19
+ Args:
20
+ orient: Direction of the line. Defaults to `'horizontal'`.
21
+ accent: Color intent token applied to the line. When omitted, the
22
+ line color is derived from the active surface.
23
+ thickness: Line thickness in pixels. Defaults to the theme value
24
+ (typically 1 px).
25
+ length: Fixed length in pixels. When omitted the line stretches to
26
+ fill the available space along its axis.
27
+ parent: Override the context-stack parent widget.
28
+ **kwargs: Layout placement options applied by the parent container —
29
+ `grow`, `horizontal`, `vertical`, `margin`, `row`, `column`.
30
+ See :doc:`/tasks/layout`.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ orient: Orient | str = "horizontal",
36
+ *,
37
+ accent: AccentToken | str | None = None,
38
+ thickness: int | None = None,
39
+ length: int | None = None,
40
+ parent: Any = None,
41
+ **kwargs: Any,
42
+ ) -> None:
43
+ self._parent = self._resolve_parent(parent)
44
+ layout_kw = self._split_layout_kwargs(kwargs)
45
+
46
+ tk_master = self._parent._child_master() if self._parent else None
47
+
48
+ internal_kwargs: dict[str, Any] = {"orient": orient}
49
+ if accent is not None:
50
+ internal_kwargs["accent"] = accent
51
+ if thickness is not None:
52
+ internal_kwargs["thickness"] = thickness
53
+ if length is not None:
54
+ internal_kwargs["length"] = length
55
+
56
+ self._internal = _InternalSeparator(tk_master, **internal_kwargs)
57
+ self._attach_to_parent(layout_kw)
58
+
59
+
60
+ register_widget_events(Divider, {})