Metadata-Version: 2.4
Name: CTkKanBan
Version: 1.0.0
Summary: A configurable, database-ready Kanban board for CustomTkinter
Author-email: Harry Gomm <Harry-g25@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Harry-g25/CTkKanBan
Project-URL: Documentation, https://harry-g25.github.io/CTkKanBan/
Project-URL: Changelog, https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/Harry-g25/CTkKanBan/issues
Project-URL: Source, https://github.com/Harry-g25/CTkKanBan
Keywords: customtkinter,kanban,desktop,sqlite,database,gui
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: customtkinter<7,>=5.2.2
Requires-Dist: tzdata>=2025.2; platform_system == "Windows"
Provides-Extra: test
Requires-Dist: coverage[toml]>=7.6; extra == "test"
Requires-Dist: pytest>=8.3; extra == "test"
Requires-Dist: pytest-cov>=6; extra == "test"
Provides-Extra: quality
Requires-Dist: mypy>=1.14; extra == "quality"
Requires-Dist: ruff>=0.9; extra == "quality"
Requires-Dist: yamllint>=1.35; extra == "quality"
Requires-Dist: zizmor>=1.7; extra == "quality"
Provides-Extra: release
Requires-Dist: build>=1.2; extra == "release"
Requires-Dist: check-wheel-contents>=0.6; extra == "release"
Requires-Dist: packaging>=24; extra == "release"
Requires-Dist: pyroma>=4.2; extra == "release"
Requires-Dist: twine>=6; extra == "release"
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: check-wheel-contents>=0.6; extra == "dev"
Requires-Dist: coverage[toml]>=7.6; extra == "dev"
Requires-Dist: mypy>=1.14; extra == "dev"
Requires-Dist: packaging>=24; extra == "dev"
Requires-Dist: pip-audit>=2.7; extra == "dev"
Requires-Dist: pyroma>=4.2; extra == "dev"
Requires-Dist: pytest>=8.3; extra == "dev"
Requires-Dist: pytest-cov>=6; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Requires-Dist: tox>=4.23; extra == "dev"
Requires-Dist: twine>=6; extra == "dev"
Requires-Dist: yamllint>=1.35; extra == "dev"
Requires-Dist: zizmor>=1.7; extra == "dev"
Dynamic: license-file

# CTkKanban

[![CI](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml)
[![CodeQL](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml/badge.svg)](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml)
[![PyPI](https://img.shields.io/pypi/v/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
[![Python](https://img.shields.io/pypi/pyversions/CTkKanBan.svg)](https://pypi.org/project/CTkKanBan/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/Harry-g25/CTkKanBan/blob/main/LICENSE)

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.

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`.

## Install

```bash
python -m pip install CTkKanBan
```

## In-memory board

```python
import customtkinter as ctk
import CTkKanBan

board_class = CTkKanBan.CTkKanbanBoard

app = ctk.CTk()
board = board_class(
    app,
    columns=[{"id": "todo", "title": "To Do"}, {"id": "done", "title": "Done"}],
    cards=[{"id": 1, "column": "todo", "title": "Try CTkKanban"}],
    completed_columns=["done"],
)
board.pack(fill="both", expand=True)
app.mainloop()
```

## Inline card editing

Inline editing is enabled by default. Click any value rendered on a card—including an empty
`show_on_card` field—to edit it without opening a dialog. Press Enter or click the check button to
save, click away to autosave, or press Escape to cancel. Text areas use Ctrl+Enter to save so Enter
can still insert a new line.

Edits use the same validation, callbacks, undo history, filtering, sorting, and persistence path as
`update_card()`. Read-only and hidden fields are never editable. To keep the earlier popup/side-panel
interaction, configure `enable_inline_card_editing=False`; `open_edit_card_form(card_id)` also remains
available for an explicit full-card form.

```python
board = CTkKanbanBoard(
    app,
    columns=columns,
    cards=cards,
    fields=fields,
    enable_inline_card_editing=True,
)

# Keyboard-free or application-driven activation is also available.
board.start_inline_card_edit(card_id=1, field_key="priority")
```

Automatic field hit targets are available with the default card renderer. Applications using a
custom `card_renderer` retain the full-card edit flow and can build their own editing controls.

## SQLite board

```python
import customtkinter as ctk
from ctk_kanban import CTkKanbanBoard, SQLiteKanbanDataSource

app = ctk.CTk()
source = SQLiteKanbanDataSource("kanban.db")
source.seed_board("work", [{"id": "todo", "title": "To Do"}], [])

board = CTkKanbanBoard(
    app,
    data_source=source,
    board_id="work",
    auto_load=True,
    server_side_query=True,
    poll_interval_ms=2000,
)
board.pack(fill="both", expand=True)
app.mainloop()
```

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.

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.

For an existing SQL, document, key-value, ORM, or API-backed repository, use
`CRUDKanbanDataSource` instead of implementing the full adapter contract:

```python
from ctk_kanban import CRUDKanbanDataSource

source = CRUDKanbanDataSource(
    read=repository.read_board,
    create=repository.create,
    update=repository.update,
    delete=repository.delete,
    transaction=repository.transaction,  # Optional
)
```

The four callbacks receive either `"card"` or `"column"`, the board ID, the record or ID, and a
`CRUDContext`. The bridge translates moves, reorders, renames, batching, paging, search, filters, and
canonical generated IDs. This keeps database-specific connection and query code in your application.

Use only one durable writer: configure either `data_source` or the legacy `on_data_changed` callback, never both.

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.

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.

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.

## Development

```bash
python -m pip install -e ".[dev]"
tox -e lint,type,py314,ctk-min,ctk-current,package
```

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.

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/).
