CTkKanBan 1.0.0__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 (76) hide show
  1. ctkkanban-1.0.0/.gitattributes +18 -0
  2. ctkkanban-1.0.0/CHANGELOG.md +37 -0
  3. ctkkanban-1.0.0/CODE_OF_CONDUCT.md +14 -0
  4. ctkkanban-1.0.0/CONTRIBUTING.md +13 -0
  5. ctkkanban-1.0.0/CTkKanBan/__init__.py +10 -0
  6. ctkkanban-1.0.0/CTkKanBan.egg-info/PKG-INFO +193 -0
  7. ctkkanban-1.0.0/CTkKanBan.egg-info/SOURCES.txt +74 -0
  8. ctkkanban-1.0.0/CTkKanBan.egg-info/dependency_links.txt +1 -0
  9. ctkkanban-1.0.0/CTkKanBan.egg-info/requires.txt +38 -0
  10. ctkkanban-1.0.0/CTkKanBan.egg-info/top_level.txt +2 -0
  11. ctkkanban-1.0.0/LICENSE +21 -0
  12. ctkkanban-1.0.0/MANIFEST.in +14 -0
  13. ctkkanban-1.0.0/PKG-INFO +193 -0
  14. ctkkanban-1.0.0/README.md +128 -0
  15. ctkkanban-1.0.0/SECURITY.md +16 -0
  16. ctkkanban-1.0.0/ctk_kanban/__init__.py +86 -0
  17. ctkkanban-1.0.0/ctk_kanban/board.py +3554 -0
  18. ctkkanban-1.0.0/ctk_kanban/card.py +1072 -0
  19. ctkkanban-1.0.0/ctk_kanban/column.py +488 -0
  20. ctkkanban-1.0.0/ctk_kanban/contracts.py +181 -0
  21. ctkkanban-1.0.0/ctk_kanban/crud.py +638 -0
  22. ctkkanban-1.0.0/ctk_kanban/datasource.py +564 -0
  23. ctkkanban-1.0.0/ctk_kanban/dialogs.py +974 -0
  24. ctkkanban-1.0.0/ctk_kanban/drag.py +430 -0
  25. ctkkanban-1.0.0/ctk_kanban/events.py +31 -0
  26. ctkkanban-1.0.0/ctk_kanban/exceptions.py +29 -0
  27. ctkkanban-1.0.0/ctk_kanban/models.py +162 -0
  28. ctkkanban-1.0.0/ctk_kanban/py.typed +1 -0
  29. ctkkanban-1.0.0/ctk_kanban/query.py +132 -0
  30. ctkkanban-1.0.0/ctk_kanban/rendering.py +622 -0
  31. ctkkanban-1.0.0/ctk_kanban/sqlite.py +854 -0
  32. ctkkanban-1.0.0/ctk_kanban/themes.py +216 -0
  33. ctkkanban-1.0.0/ctk_kanban/toolbar.py +447 -0
  34. ctkkanban-1.0.0/ctk_kanban/utils.py +170 -0
  35. ctkkanban-1.0.0/ctk_kanban/validators.py +322 -0
  36. ctkkanban-1.0.0/ctk_kanban/version.py +3 -0
  37. ctkkanban-1.0.0/ctk_kanban/widgets.py +453 -0
  38. ctkkanban-1.0.0/docs/assests/favicon/about.txt +6 -0
  39. ctkkanban-1.0.0/docs/assests/favicon/android-chrome-192x192.png +0 -0
  40. ctkkanban-1.0.0/docs/assests/favicon/android-chrome-512x512.png +0 -0
  41. ctkkanban-1.0.0/docs/assests/favicon/apple-touch-icon.png +0 -0
  42. ctkkanban-1.0.0/docs/assests/favicon/favicon-16x16.png +0 -0
  43. ctkkanban-1.0.0/docs/assests/favicon/favicon-32x32.png +0 -0
  44. ctkkanban-1.0.0/docs/assests/favicon/favicon.ico +0 -0
  45. ctkkanban-1.0.0/docs/assests/favicon/site.webmanifest +1 -0
  46. ctkkanban-1.0.0/docs/database.md +213 -0
  47. ctkkanban-1.0.0/docs/index.html +3510 -0
  48. ctkkanban-1.0.0/docs/publishing.md +74 -0
  49. ctkkanban-1.0.0/docs/script.js +266 -0
  50. ctkkanban-1.0.0/docs/styles.css +901 -0
  51. ctkkanban-1.0.0/example_all_features.py +270 -0
  52. ctkkanban-1.0.0/example_sqlite.py +53 -0
  53. ctkkanban-1.0.0/pyproject.toml +154 -0
  54. ctkkanban-1.0.0/scripts/check_docs.py +232 -0
  55. ctkkanban-1.0.0/scripts/prepare_release.py +63 -0
  56. ctkkanban-1.0.0/scripts/run_actionlint.py +85 -0
  57. ctkkanban-1.0.0/scripts/smoke_install.py +80 -0
  58. ctkkanban-1.0.0/scripts/validate_dist.py +38 -0
  59. ctkkanban-1.0.0/scripts/verify_release.py +155 -0
  60. ctkkanban-1.0.0/setup.cfg +4 -0
  61. ctkkanban-1.0.0/tests/gui_test_app.py +6 -0
  62. ctkkanban-1.0.0/tests/test_board_integrity_regressions.py +212 -0
  63. ctkkanban-1.0.0/tests/test_card_creation_optimizations.py +129 -0
  64. ctkkanban-1.0.0/tests/test_card_form_modes.py +114 -0
  65. ctkkanban-1.0.0/tests/test_crud_datasource.py +369 -0
  66. ctkkanban-1.0.0/tests/test_database_persistence_api.py +98 -0
  67. ctkkanban-1.0.0/tests/test_drag_optimizations.py +121 -0
  68. ctkkanban-1.0.0/tests/test_full_efficiency_audit.py +229 -0
  69. ctkkanban-1.0.0/tests/test_inline_card_editing.py +931 -0
  70. ctkkanban-1.0.0/tests/test_new_usability_features.py +209 -0
  71. ctkkanban-1.0.0/tests/test_performance_regressions.py +43 -0
  72. ctkkanban-1.0.0/tests/test_persistence_correctness.py +688 -0
  73. ctkkanban-1.0.0/tests/test_release_validation.py +48 -0
  74. ctkkanban-1.0.0/tests/test_sqlite_datasource.py +191 -0
  75. ctkkanban-1.0.0/tests/test_style_customization.py +201 -0
  76. ctkkanban-1.0.0/tox.ini +49 -0
@@ -0,0 +1,18 @@
1
+ * text=auto
2
+
3
+ .gitattributes text eol=lf
4
+ .gitignore text eol=lf
5
+ MANIFEST.in text eol=lf
6
+ *.css text eol=lf
7
+ *.html text eol=lf
8
+ *.ini text eol=lf
9
+ *.js text eol=lf
10
+ *.json text eol=lf
11
+ *.md text eol=lf
12
+ *.py text eol=lf
13
+ *.toml text eol=lf
14
+ *.yaml text eol=lf
15
+ *.yml text eol=lf
16
+
17
+ *.ico binary
18
+ *.png binary
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ## 1.0.0 - 2026-07-24
6
+
7
+ - Added live, field-aware editing inside default cards, including empty-field placeholders, typed controls, keyboard save/cancel behavior, validation feedback, and persistence through the normal card update pipeline.
8
+ - Added `enable_inline_card_editing` and `start_inline_card_edit()` while retaining the explicit popup and side-panel form APIs for compatibility.
9
+ - Kept invalid inline edits from triggering release-driven host controls under CustomTkinter 6 while preserving CustomTkinter 5 behavior.
10
+
11
+ ## 0.3.0 - 2026-07-24
12
+
13
+ - Added `CRUDKanbanDataSource`, a four-callback bridge for connecting existing SQL, NoSQL, ORM, and API repositories without implementing the full persistence protocol.
14
+ - Hardened SQLite mutation replay, schema migration, conflict snapshots, batch rollback, identifier validation, and offline queue ordering.
15
+ - Fixed paged-board totals, offsets, undo/redo persistence, column rename handling, timestamp sorting, dirty-form replacement, and style snapshots.
16
+ - Expanded supported CustomTkinter releases through 6.x and strengthened source/wheel validation, compatibility testing, documentation checks, and release smoke tests.
17
+ - Added cross-platform CI for Python 3.10 through 3.14, branch coverage, dependency auditing, installed-wheel smoke tests, and package validation.
18
+ - Added CodeQL scanning, Dependabot, workflow security linting, GitHub Pages deployment, and repository contribution templates.
19
+ - Added trusted TestPyPI and PyPI publishing with protected environments, artifact attestations, checksums, and automated GitHub releases.
20
+ - Added local tox environments and release preparation, validation, and installed-package smoke-test scripts.
21
+
22
+ ## 0.2.0 - 2026-06-14
23
+
24
+ - Added typed mutation, result, conflict, query, paging, and load contracts.
25
+ - Added threaded data-source coordination, retries, offline queueing, polling, canonical IDs, and optimistic concurrency.
26
+ - Added a transactional SQLite adapter and runnable database example.
27
+ - Added sparse card ranking, atomic batches, undo/redo, immutable IDs, timestamps, and revisions.
28
+ - Added persistence status, filter chips, active sort and result summaries, search clearing and highlighting.
29
+ - Added responsive and adjustable columns, drag handles, WIP/lock indicators, and invalid-drop feedback.
30
+ - Added date picking, field-level validation, dirty-form protection, and normalized optional values.
31
+ - Redesigned the default light and dark appearance with layered surfaces, priority rails, metadata tiles, compact toolbar states, polished columns, and cohesive forms.
32
+ - Added visual-state regression coverage and light/dark/form showcase modes.
33
+ - Added integration, performance, reliability, and usability tests.
34
+
35
+ ## 0.1.0
36
+
37
+ - Initial configurable CustomTkinter Kanban board.
@@ -0,0 +1,14 @@
1
+ # Code of Conduct
2
+
3
+ ## Our standard
4
+
5
+ We want participation in CTkKanban to be welcoming, constructive, and safe. Be respectful, assume good intent while still discussing technical disagreements directly, and focus criticism on behavior and code rather than people.
6
+
7
+ Harassment, discrimination, threats, sexualized attention, deliberate intimidation, and publication of private information are not acceptable.
8
+
9
+ ## Enforcement
10
+
11
+ Report conduct concerns privately to the project maintainer through GitHub. The maintainer may edit or remove contributions, limit participation, or ban contributors when needed to protect the community. Reports will be handled as confidentially as practical.
12
+
13
+ This policy applies in project spaces and when someone is publicly representing the project.
14
+
@@ -0,0 +1,13 @@
1
+ # Contributing
2
+
3
+ 1. Create a virtual environment with Python 3.10 or newer.
4
+ 2. Install the project in editable mode: `python -m pip install -e ".[dev]"`.
5
+ 3. Keep public mutations database-neutral and operation-first.
6
+ 4. Add focused tests for behavior, rollback, thread boundaries, and widget identity.
7
+ 5. Run `tox -e lint,type,py314,package` before opening a change.
8
+
9
+ Tk widgets must only be touched by Tk's owning thread. Persistence adapters may block because the coordinator runs them on a dedicated worker.
10
+
11
+ Do not introduce a second persistence writer into a board. Use a `KanbanDataSource` or the legacy `on_data_changed` callback.
12
+
13
+ User-visible changes belong under `## Unreleased` in `CHANGELOG.md`. See [docs/publishing.md](docs/publishing.md) for TestPyPI and production release steps.
@@ -0,0 +1,10 @@
1
+ """Public compatibility import for the CTkKanBan distribution.
2
+
3
+ The implementation lives in :mod:`ctk_kanban`; this package preserves the
4
+ project's branded import spelling for applications that prefer ``import
5
+ CTkKanBan``.
6
+ """
7
+
8
+ from ctk_kanban import * # noqa: F401,F403
9
+ from ctk_kanban import __all__, __version__
10
+
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: CTkKanBan
3
+ Version: 1.0.0
4
+ Summary: A configurable, database-ready Kanban board for CustomTkinter
5
+ Author-email: Harry Gomm <Harry-g25@users.noreply.github.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Harry-g25/CTkKanBan
8
+ Project-URL: Documentation, https://harry-g25.github.io/CTkKanBan/
9
+ Project-URL: Changelog, https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/Harry-g25/CTkKanBan/issues
11
+ Project-URL: Source, https://github.com/Harry-g25/CTkKanBan
12
+ Keywords: customtkinter,kanban,desktop,sqlite,database,gui
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Win32 (MS Windows)
15
+ Classifier: Environment :: X11 Applications
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: Microsoft :: Windows
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: customtkinter<7,>=5.2.2
33
+ Requires-Dist: tzdata>=2025.2; platform_system == "Windows"
34
+ Provides-Extra: test
35
+ Requires-Dist: coverage[toml]>=7.6; extra == "test"
36
+ Requires-Dist: pytest>=8.3; extra == "test"
37
+ Requires-Dist: pytest-cov>=6; extra == "test"
38
+ Provides-Extra: quality
39
+ Requires-Dist: mypy>=1.14; extra == "quality"
40
+ Requires-Dist: ruff>=0.9; extra == "quality"
41
+ Requires-Dist: yamllint>=1.35; extra == "quality"
42
+ Requires-Dist: zizmor>=1.7; extra == "quality"
43
+ Provides-Extra: release
44
+ Requires-Dist: build>=1.2; extra == "release"
45
+ Requires-Dist: check-wheel-contents>=0.6; extra == "release"
46
+ Requires-Dist: packaging>=24; extra == "release"
47
+ Requires-Dist: pyroma>=4.2; extra == "release"
48
+ Requires-Dist: twine>=6; extra == "release"
49
+ Provides-Extra: dev
50
+ Requires-Dist: build>=1.2; extra == "dev"
51
+ Requires-Dist: check-wheel-contents>=0.6; extra == "dev"
52
+ Requires-Dist: coverage[toml]>=7.6; extra == "dev"
53
+ Requires-Dist: mypy>=1.14; extra == "dev"
54
+ Requires-Dist: packaging>=24; extra == "dev"
55
+ Requires-Dist: pip-audit>=2.7; extra == "dev"
56
+ Requires-Dist: pyroma>=4.2; extra == "dev"
57
+ Requires-Dist: pytest>=8.3; extra == "dev"
58
+ Requires-Dist: pytest-cov>=6; extra == "dev"
59
+ Requires-Dist: ruff>=0.9; extra == "dev"
60
+ Requires-Dist: tox>=4.23; extra == "dev"
61
+ Requires-Dist: twine>=6; extra == "dev"
62
+ Requires-Dist: yamllint>=1.35; extra == "dev"
63
+ Requires-Dist: zizmor>=1.7; extra == "dev"
64
+ Dynamic: license-file
65
+
66
+ # CTkKanban
67
+
68
+ [![CI](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml)
69
+ [![CodeQL](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml)
70
+ [![PyPI](https://img.shields.io/pypi/v/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
71
+ [![Python](https://img.shields.io/pypi/pyversions/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
72
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/Harry-g25/CTkKanBan/blob/main/LICENSE)
73
+
74
+ CTkKanban is a configurable Kanban widget for CustomTkinter desktop applications. It ships with a polished adaptive light/dark design, live inline card editing, generated forms, drag and drop, search, advanced filters, sorting, undo/redo, responsive columns, and database-backed operation.
75
+
76
+ The built-in design uses layered surfaces, priority-accented cards, responsive metadata tiles, column color rails, active filter treatments, and database status pills. Every visual token remains overridable through `style` or `theme`.
77
+
78
+ ## Install
79
+
80
+ ```bash
81
+ python -m pip install CTkKanBan
82
+ ```
83
+
84
+ ## In-memory board
85
+
86
+ ```python
87
+ import customtkinter as ctk
88
+ import CTkKanBan
89
+
90
+ board_class = CTkKanBan.CTkKanbanBoard
91
+
92
+ app = ctk.CTk()
93
+ board = board_class(
94
+ app,
95
+ columns=[{"id": "todo", "title": "To Do"}, {"id": "done", "title": "Done"}],
96
+ cards=[{"id": 1, "column": "todo", "title": "Try CTkKanban"}],
97
+ completed_columns=["done"],
98
+ )
99
+ board.pack(fill="both", expand=True)
100
+ app.mainloop()
101
+ ```
102
+
103
+ ## Inline card editing
104
+
105
+ Inline editing is enabled by default. Click any value rendered on a card—including an empty
106
+ `show_on_card` field—to edit it without opening a dialog. Press Enter or click the check button to
107
+ save, click away to autosave, or press Escape to cancel. Text areas use Ctrl+Enter to save so Enter
108
+ can still insert a new line.
109
+
110
+ Edits use the same validation, callbacks, undo history, filtering, sorting, and persistence path as
111
+ `update_card()`. Read-only and hidden fields are never editable. To keep the earlier popup/side-panel
112
+ interaction, configure `enable_inline_card_editing=False`; `open_edit_card_form(card_id)` also remains
113
+ available for an explicit full-card form.
114
+
115
+ ```python
116
+ board = CTkKanbanBoard(
117
+ app,
118
+ columns=columns,
119
+ cards=cards,
120
+ fields=fields,
121
+ enable_inline_card_editing=True,
122
+ )
123
+
124
+ # Keyboard-free or application-driven activation is also available.
125
+ board.start_inline_card_edit(card_id=1, field_key="priority")
126
+ ```
127
+
128
+ Automatic field hit targets are available with the default card renderer. Applications using a
129
+ custom `card_renderer` retain the full-card edit flow and can build their own editing controls.
130
+
131
+ ## SQLite board
132
+
133
+ ```python
134
+ import customtkinter as ctk
135
+ from ctk_kanban import CTkKanbanBoard, SQLiteKanbanDataSource
136
+
137
+ app = ctk.CTk()
138
+ source = SQLiteKanbanDataSource("kanban.db")
139
+ source.seed_board("work", [{"id": "todo", "title": "To Do"}], [])
140
+
141
+ board = CTkKanbanBoard(
142
+ app,
143
+ data_source=source,
144
+ board_id="work",
145
+ auto_load=True,
146
+ server_side_query=True,
147
+ poll_interval_ms=2000,
148
+ )
149
+ board.pack(fill="both", expand=True)
150
+ app.mainloop()
151
+ ```
152
+
153
+ Database work runs outside Tk's UI thread. Mutations carry event, transaction, actor, board, and expected-revision metadata. Adapters may return canonical records with generated IDs, timestamps, versions, and defaults. Failed network writes can be retried or held in the process-local offline queue until connectivity returns.
154
+
155
+ The built-in SQLite adapter provides transactional writes, optimistic revisions, atomic batches, server-side search/filter/sort, paging, change polling, generated IDs, and automatic timestamps. The board shows saving, saved, offline, conflict, and error states; duplicate submissions are blocked while a mutation is pending.
156
+
157
+ For an existing SQL, document, key-value, ORM, or API-backed repository, use
158
+ `CRUDKanbanDataSource` instead of implementing the full adapter contract:
159
+
160
+ ```python
161
+ from ctk_kanban import CRUDKanbanDataSource
162
+
163
+ source = CRUDKanbanDataSource(
164
+ read=repository.read_board,
165
+ create=repository.create,
166
+ update=repository.update,
167
+ delete=repository.delete,
168
+ transaction=repository.transaction, # Optional
169
+ )
170
+ ```
171
+
172
+ The four callbacks receive either `"card"` or `"column"`, the board ID, the record or ID, and a
173
+ `CRUDContext`. The bridge translates moves, reorders, renames, batching, paging, search, filters, and
174
+ canonical generated IDs. This keeps database-specific connection and query code in your application.
175
+
176
+ Use only one durable writer: configure either `data_source` or the legacy `on_data_changed` callback, never both.
177
+
178
+ See the [database integration guide](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/database.md) for the adapter contract, event shape, conflict policies, paging, polling, and a production integration checklist.
179
+
180
+ The example programs are included in the source repository and source distribution, not the installed wheel. From a [source checkout](https://github.com/Harry-g25/CTkKanBan), run `python example_all_features.py` for the UI showcase or `python example_sqlite.py` for the transactional database example.
181
+
182
+ Use `python example_all_features.py --light`, `--dark`, or `--form` to inspect specific appearance and form states. Add `--diagnose` to print the exact package path and version being rendered.
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ python -m pip install -e ".[dev]"
188
+ tox -e lint,type,py314,ctk-min,ctk-current,package
189
+ ```
190
+
191
+ CI tests Python 3.10 through 3.14 on Linux and the oldest/latest supported versions on Windows and macOS. It also checks branch coverage, installed-wheel behavior, SQLite persistence, dependency vulnerabilities, package metadata, and workflow security.
192
+
193
+ See the [changelog](https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md), [contribution guide](https://github.com/Harry-g25/CTkKanBan/blob/main/CONTRIBUTING.md), [publishing runbook](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/publishing.md), and [project documentation](https://harry-g25.github.io/CTkKanBan/).
@@ -0,0 +1,74 @@
1
+ .gitattributes
2
+ CHANGELOG.md
3
+ CODE_OF_CONDUCT.md
4
+ CONTRIBUTING.md
5
+ LICENSE
6
+ MANIFEST.in
7
+ README.md
8
+ SECURITY.md
9
+ example_all_features.py
10
+ example_sqlite.py
11
+ pyproject.toml
12
+ tox.ini
13
+ CTkKanBan/__init__.py
14
+ CTkKanBan.egg-info/PKG-INFO
15
+ CTkKanBan.egg-info/SOURCES.txt
16
+ CTkKanBan.egg-info/dependency_links.txt
17
+ CTkKanBan.egg-info/requires.txt
18
+ CTkKanBan.egg-info/top_level.txt
19
+ ctk_kanban/__init__.py
20
+ ctk_kanban/board.py
21
+ ctk_kanban/card.py
22
+ ctk_kanban/column.py
23
+ ctk_kanban/contracts.py
24
+ ctk_kanban/crud.py
25
+ ctk_kanban/datasource.py
26
+ ctk_kanban/dialogs.py
27
+ ctk_kanban/drag.py
28
+ ctk_kanban/events.py
29
+ ctk_kanban/exceptions.py
30
+ ctk_kanban/models.py
31
+ ctk_kanban/py.typed
32
+ ctk_kanban/query.py
33
+ ctk_kanban/rendering.py
34
+ ctk_kanban/sqlite.py
35
+ ctk_kanban/themes.py
36
+ ctk_kanban/toolbar.py
37
+ ctk_kanban/utils.py
38
+ ctk_kanban/validators.py
39
+ ctk_kanban/version.py
40
+ ctk_kanban/widgets.py
41
+ docs/database.md
42
+ docs/index.html
43
+ docs/publishing.md
44
+ docs/script.js
45
+ docs/styles.css
46
+ docs/assests/favicon/about.txt
47
+ docs/assests/favicon/android-chrome-192x192.png
48
+ docs/assests/favicon/android-chrome-512x512.png
49
+ docs/assests/favicon/apple-touch-icon.png
50
+ docs/assests/favicon/favicon-16x16.png
51
+ docs/assests/favicon/favicon-32x32.png
52
+ docs/assests/favicon/favicon.ico
53
+ docs/assests/favicon/site.webmanifest
54
+ scripts/check_docs.py
55
+ scripts/prepare_release.py
56
+ scripts/run_actionlint.py
57
+ scripts/smoke_install.py
58
+ scripts/validate_dist.py
59
+ scripts/verify_release.py
60
+ tests/gui_test_app.py
61
+ tests/test_board_integrity_regressions.py
62
+ tests/test_card_creation_optimizations.py
63
+ tests/test_card_form_modes.py
64
+ tests/test_crud_datasource.py
65
+ tests/test_database_persistence_api.py
66
+ tests/test_drag_optimizations.py
67
+ tests/test_full_efficiency_audit.py
68
+ tests/test_inline_card_editing.py
69
+ tests/test_new_usability_features.py
70
+ tests/test_performance_regressions.py
71
+ tests/test_persistence_correctness.py
72
+ tests/test_release_validation.py
73
+ tests/test_sqlite_datasource.py
74
+ tests/test_style_customization.py
@@ -0,0 +1,38 @@
1
+ customtkinter<7,>=5.2.2
2
+
3
+ [:platform_system == "Windows"]
4
+ tzdata>=2025.2
5
+
6
+ [dev]
7
+ build>=1.2
8
+ check-wheel-contents>=0.6
9
+ coverage[toml]>=7.6
10
+ mypy>=1.14
11
+ packaging>=24
12
+ pip-audit>=2.7
13
+ pyroma>=4.2
14
+ pytest>=8.3
15
+ pytest-cov>=6
16
+ ruff>=0.9
17
+ tox>=4.23
18
+ twine>=6
19
+ yamllint>=1.35
20
+ zizmor>=1.7
21
+
22
+ [quality]
23
+ mypy>=1.14
24
+ ruff>=0.9
25
+ yamllint>=1.35
26
+ zizmor>=1.7
27
+
28
+ [release]
29
+ build>=1.2
30
+ check-wheel-contents>=0.6
31
+ packaging>=24
32
+ pyroma>=4.2
33
+ twine>=6
34
+
35
+ [test]
36
+ coverage[toml]>=7.6
37
+ pytest>=8.3
38
+ pytest-cov>=6
@@ -0,0 +1,2 @@
1
+ CTkKanBan
2
+ ctk_kanban
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harry Gomm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ include .gitattributes
2
+ include CHANGELOG.md
3
+ include CODE_OF_CONDUCT.md
4
+ include CONTRIBUTING.md
5
+ include LICENSE
6
+ include README.md
7
+ include SECURITY.md
8
+ include example_all_features.py
9
+ include example_sqlite.py
10
+ include tests/gui_test_app.py
11
+ include tox.ini
12
+ recursive-include docs *
13
+ recursive-include scripts *.py
14
+ include ctk_kanban/py.typed
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: CTkKanBan
3
+ Version: 1.0.0
4
+ Summary: A configurable, database-ready Kanban board for CustomTkinter
5
+ Author-email: Harry Gomm <Harry-g25@users.noreply.github.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Harry-g25/CTkKanBan
8
+ Project-URL: Documentation, https://harry-g25.github.io/CTkKanBan/
9
+ Project-URL: Changelog, https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/Harry-g25/CTkKanBan/issues
11
+ Project-URL: Source, https://github.com/Harry-g25/CTkKanBan
12
+ Keywords: customtkinter,kanban,desktop,sqlite,database,gui
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Win32 (MS Windows)
15
+ Classifier: Environment :: X11 Applications
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: Microsoft :: Windows
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: customtkinter<7,>=5.2.2
33
+ Requires-Dist: tzdata>=2025.2; platform_system == "Windows"
34
+ Provides-Extra: test
35
+ Requires-Dist: coverage[toml]>=7.6; extra == "test"
36
+ Requires-Dist: pytest>=8.3; extra == "test"
37
+ Requires-Dist: pytest-cov>=6; extra == "test"
38
+ Provides-Extra: quality
39
+ Requires-Dist: mypy>=1.14; extra == "quality"
40
+ Requires-Dist: ruff>=0.9; extra == "quality"
41
+ Requires-Dist: yamllint>=1.35; extra == "quality"
42
+ Requires-Dist: zizmor>=1.7; extra == "quality"
43
+ Provides-Extra: release
44
+ Requires-Dist: build>=1.2; extra == "release"
45
+ Requires-Dist: check-wheel-contents>=0.6; extra == "release"
46
+ Requires-Dist: packaging>=24; extra == "release"
47
+ Requires-Dist: pyroma>=4.2; extra == "release"
48
+ Requires-Dist: twine>=6; extra == "release"
49
+ Provides-Extra: dev
50
+ Requires-Dist: build>=1.2; extra == "dev"
51
+ Requires-Dist: check-wheel-contents>=0.6; extra == "dev"
52
+ Requires-Dist: coverage[toml]>=7.6; extra == "dev"
53
+ Requires-Dist: mypy>=1.14; extra == "dev"
54
+ Requires-Dist: packaging>=24; extra == "dev"
55
+ Requires-Dist: pip-audit>=2.7; extra == "dev"
56
+ Requires-Dist: pyroma>=4.2; extra == "dev"
57
+ Requires-Dist: pytest>=8.3; extra == "dev"
58
+ Requires-Dist: pytest-cov>=6; extra == "dev"
59
+ Requires-Dist: ruff>=0.9; extra == "dev"
60
+ Requires-Dist: tox>=4.23; extra == "dev"
61
+ Requires-Dist: twine>=6; extra == "dev"
62
+ Requires-Dist: yamllint>=1.35; extra == "dev"
63
+ Requires-Dist: zizmor>=1.7; extra == "dev"
64
+ Dynamic: license-file
65
+
66
+ # CTkKanban
67
+
68
+ [![CI](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml)
69
+ [![CodeQL](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml)
70
+ [![PyPI](https://img.shields.io/pypi/v/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
71
+ [![Python](https://img.shields.io/pypi/pyversions/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
72
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/Harry-g25/CTkKanBan/blob/main/LICENSE)
73
+
74
+ CTkKanban is a configurable Kanban widget for CustomTkinter desktop applications. It ships with a polished adaptive light/dark design, live inline card editing, generated forms, drag and drop, search, advanced filters, sorting, undo/redo, responsive columns, and database-backed operation.
75
+
76
+ The built-in design uses layered surfaces, priority-accented cards, responsive metadata tiles, column color rails, active filter treatments, and database status pills. Every visual token remains overridable through `style` or `theme`.
77
+
78
+ ## Install
79
+
80
+ ```bash
81
+ python -m pip install CTkKanBan
82
+ ```
83
+
84
+ ## In-memory board
85
+
86
+ ```python
87
+ import customtkinter as ctk
88
+ import CTkKanBan
89
+
90
+ board_class = CTkKanBan.CTkKanbanBoard
91
+
92
+ app = ctk.CTk()
93
+ board = board_class(
94
+ app,
95
+ columns=[{"id": "todo", "title": "To Do"}, {"id": "done", "title": "Done"}],
96
+ cards=[{"id": 1, "column": "todo", "title": "Try CTkKanban"}],
97
+ completed_columns=["done"],
98
+ )
99
+ board.pack(fill="both", expand=True)
100
+ app.mainloop()
101
+ ```
102
+
103
+ ## Inline card editing
104
+
105
+ Inline editing is enabled by default. Click any value rendered on a card—including an empty
106
+ `show_on_card` field—to edit it without opening a dialog. Press Enter or click the check button to
107
+ save, click away to autosave, or press Escape to cancel. Text areas use Ctrl+Enter to save so Enter
108
+ can still insert a new line.
109
+
110
+ Edits use the same validation, callbacks, undo history, filtering, sorting, and persistence path as
111
+ `update_card()`. Read-only and hidden fields are never editable. To keep the earlier popup/side-panel
112
+ interaction, configure `enable_inline_card_editing=False`; `open_edit_card_form(card_id)` also remains
113
+ available for an explicit full-card form.
114
+
115
+ ```python
116
+ board = CTkKanbanBoard(
117
+ app,
118
+ columns=columns,
119
+ cards=cards,
120
+ fields=fields,
121
+ enable_inline_card_editing=True,
122
+ )
123
+
124
+ # Keyboard-free or application-driven activation is also available.
125
+ board.start_inline_card_edit(card_id=1, field_key="priority")
126
+ ```
127
+
128
+ Automatic field hit targets are available with the default card renderer. Applications using a
129
+ custom `card_renderer` retain the full-card edit flow and can build their own editing controls.
130
+
131
+ ## SQLite board
132
+
133
+ ```python
134
+ import customtkinter as ctk
135
+ from ctk_kanban import CTkKanbanBoard, SQLiteKanbanDataSource
136
+
137
+ app = ctk.CTk()
138
+ source = SQLiteKanbanDataSource("kanban.db")
139
+ source.seed_board("work", [{"id": "todo", "title": "To Do"}], [])
140
+
141
+ board = CTkKanbanBoard(
142
+ app,
143
+ data_source=source,
144
+ board_id="work",
145
+ auto_load=True,
146
+ server_side_query=True,
147
+ poll_interval_ms=2000,
148
+ )
149
+ board.pack(fill="both", expand=True)
150
+ app.mainloop()
151
+ ```
152
+
153
+ Database work runs outside Tk's UI thread. Mutations carry event, transaction, actor, board, and expected-revision metadata. Adapters may return canonical records with generated IDs, timestamps, versions, and defaults. Failed network writes can be retried or held in the process-local offline queue until connectivity returns.
154
+
155
+ The built-in SQLite adapter provides transactional writes, optimistic revisions, atomic batches, server-side search/filter/sort, paging, change polling, generated IDs, and automatic timestamps. The board shows saving, saved, offline, conflict, and error states; duplicate submissions are blocked while a mutation is pending.
156
+
157
+ For an existing SQL, document, key-value, ORM, or API-backed repository, use
158
+ `CRUDKanbanDataSource` instead of implementing the full adapter contract:
159
+
160
+ ```python
161
+ from ctk_kanban import CRUDKanbanDataSource
162
+
163
+ source = CRUDKanbanDataSource(
164
+ read=repository.read_board,
165
+ create=repository.create,
166
+ update=repository.update,
167
+ delete=repository.delete,
168
+ transaction=repository.transaction, # Optional
169
+ )
170
+ ```
171
+
172
+ The four callbacks receive either `"card"` or `"column"`, the board ID, the record or ID, and a
173
+ `CRUDContext`. The bridge translates moves, reorders, renames, batching, paging, search, filters, and
174
+ canonical generated IDs. This keeps database-specific connection and query code in your application.
175
+
176
+ Use only one durable writer: configure either `data_source` or the legacy `on_data_changed` callback, never both.
177
+
178
+ See the [database integration guide](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/database.md) for the adapter contract, event shape, conflict policies, paging, polling, and a production integration checklist.
179
+
180
+ The example programs are included in the source repository and source distribution, not the installed wheel. From a [source checkout](https://github.com/Harry-g25/CTkKanBan), run `python example_all_features.py` for the UI showcase or `python example_sqlite.py` for the transactional database example.
181
+
182
+ Use `python example_all_features.py --light`, `--dark`, or `--form` to inspect specific appearance and form states. Add `--diagnose` to print the exact package path and version being rendered.
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ python -m pip install -e ".[dev]"
188
+ tox -e lint,type,py314,ctk-min,ctk-current,package
189
+ ```
190
+
191
+ CI tests Python 3.10 through 3.14 on Linux and the oldest/latest supported versions on Windows and macOS. It also checks branch coverage, installed-wheel behavior, SQLite persistence, dependency vulnerabilities, package metadata, and workflow security.
192
+
193
+ See the [changelog](https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md), [contribution guide](https://github.com/Harry-g25/CTkKanBan/blob/main/CONTRIBUTING.md), [publishing runbook](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/publishing.md), and [project documentation](https://harry-g25.github.io/CTkKanBan/).