This guide captures the Knack Toolkit Library (KTL) architecture and conventions. Use it alongside CLAUDE.md when making updates.
- KTL is created with
function Ktl($, appInfo)and stored aswindow.ktl. - The constructor returns the existing instance if already initialized.
- Versioning is stored in globals (
window.APP_KTL_VERSIONS,window.APP_ROOT_NAME).
- Each subsystem is attached on
thisusing IIFEs that return an object. - Example pattern:
this.core = (function () { return { myFn() { /* ... */ } }; })();
- Existing modules include (non-exhaustive):
ktl.core,ktl.fields,ktl.views,ktl.scenes,ktl.storage,ktl.log,ktl.bulkOps,ktl.userPrefs,ktl.sysInfo.
- Use
constfor file-level constants (e.g.,TEN_SECONDS_DELAY). - Shared constants live in
ktl.const. - Keyword parsing uses
window.ktlKeywordsand underscores (_keyword) for features.
- Never use
alert(). - Use
ktl.core.selectOption()for alerts and confirmations.ktl.core.selectOption('Operation completed', 'OK'); const result = await ktl.core.selectOption('Are you sure?', 'Yes,No');
- New code should use vanilla JS (
querySelector,addEventListener,fetch, etc.). - Convert to vanilla JS when explicitly asked or when doing a large refactor.
- Keep jQuery in these cases:
- Knack event hooks (
knack-view-render,knack-scene-render, etc.) - Chosen event bindings (
.chosen()/.on('change', ...)) - Existing functions already written in jQuery (keep consistency within the function)
- Knack event hooks (
- Use
camelCasefor functions/variables;UPPER_SNAKE_CASEfor constants. - Prefer
const/letovervarin new code. - Avoid new globals; attach generic utilities under an existing
ktl.*module.
- Always look for existing helpers in
ktl.core,ktl.views,ktl.fields,ktl.log, etc. - If a new function is broadly useful, add it to the appropriate existing module rather than creating a new global function.
- Use the
ktlprefix for all new classes (.ktlHidden,.ktlDenseGrid, etc.). - Dynamic variants follow the pattern
[class^="ktlHidden_"]or[class*=" ktlHidden_"]. - Keep Knack-native class names (e.g.,
.kn-radio,.kn-checkbox) untouched.
- Global spacing variables live in
:root(e.g.,--ktlButtonSpacing). - Prefer adding new reusable values to
:rootinstead of hard-coding.
- Follow existing section headers and comment style in
KTL.css. - Group feature-specific styles together and keep them close to related features.
- Keywords are underscore-prefixed (
_ar,_ts,_cfv) and are parsed from view titles/descriptions. - Use the existing keyword parsing helpers in
ktl.core. - If adding keywords, ensure they follow the underscore format and update relevant docs.
- Reuse first: Check for existing helpers before writing new logic.
- Extend modules: Add reusable functions to
ktl.core(or the most relevant module). - Avoid new globals: Keep functionality encapsulated within the KTL instance.
- Large refactors: Convert to vanilla JS except for Knack events and chosen events.
CLAUDE.md: alert replacement and JS style rules.KTL.js: module layout, keyword parsing, Knack event handling patterns.KTL.css: prefix conventions, spacing variables, feature grouping.KTL_Defaults.js: configuration patterns and defaults (when adding new settings).
- Before changing an existing feature, check
Docs/for a related doc (for exampleKTL_API.md). - If a related doc exists, update it in the same change so behavior and options remain accurate.
- If no related doc exists, create one only when the feature/change is complex (multi-step behavior, non-obvious API contracts, advanced configuration, or cross-module impact).
- Do not create docs for small/simple changes; keep those in code comments or commit messages.
- When adding a new complex-feature doc, place it under
Docs/and use a clear feature-based filename.
These guidelines are intended to keep changes consistent with the existing KTL codebase and reduce risk when extending shared functionality.