Skip to content

Commit bdd42f2

Browse files
committed
Control Dojo v1.1.0 — The 5.9 FP1 Compatibility Update
1 parent dc57293 commit bdd42f2

33 files changed

Lines changed: 3667 additions & 1958 deletions

CHANGELOG.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Changelog
2+
3+
All notable changes to Control Dojo will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.1.0] - The 5.9 Compatibility Update
9+
10+
### Added
11+
12+
#### Platform & Infrastructure
13+
- **K2 Five 5.9 FP1 Compatibility**: Full compatibility with K2 Five 5.9 FP1, fully tested and aligned with the latest K2 release
14+
- **Express v5 Upgrade**: Upgraded backend server to Express v5 for improved performance and modern features
15+
- **Flowbite v4 Integration**: Upgraded to Flowbite v4 for enhanced UI components and improved theme support
16+
- **Tailwind CSS v4**: Upgraded to Tailwind CSS v4 with new build tooling for better performance
17+
- **Validation Error Popup Component**: New dedicated ValidationErrorPopup component for design-time validation feedback in the Inspector
18+
19+
#### Documentation
20+
- **Accessibility Guide**: New comprehensive accessibility guide (`docs/Accessibility.md`) covering WCAG 2.1 Level AA standards, keyboard navigation, ARIA patterns, screen reader support, error handling, focus management, and complete implementation examples with best practices
21+
- **Manifest Configuration Guide**: Major enhancements including:
22+
- **Control Data Type Declaration**: Complete documentation for `datatypes` array that enables field binding and Change Control functionality in K2 Designer, with full list of 20+ supported data types (AutoGuid, Date, DateTime, Decimal, File, Guid, Hyperlink, Image, Label, Memo, MultiValue, Number, Text, Time, Xml, YesNo, etc.)
23+
- **Property Categories**: Documentation for grouping properties in K2 designer's property panel with custom category support
24+
- **Design-time Property Validation**: Complete guide for `validationpattern` and `validationmessage` fields that provide regex-based validation in K2 Designer (design-time only, not runtime)
25+
- **Int Property Type**: Documentation for new `int` property type with built-in 32-bit range validation and default error messages
26+
- **ControlExpression Support**: Documentation explaining how ControlExpression works (uses Value property, no separate get/set methods required)
27+
- **Escaping Rules**: Documentation for property metadata character escaping rules to prevent manifest parsing errors
28+
- **Standard Properties Guide**: Significant updates including:
29+
- **TabIndex Property**: Complete implementation patterns with code examples for keyboard navigation and tab order control
30+
- **ControlExpression Support**: Documentation explaining that ControlExpression uses Value property's getter/setter (no separate methods needed)
31+
- **Width Validation Rules**: Critical documentation about width property limitations (no "auto" support, validation requirements, valid/invalid formats, error messages)
32+
- **Complete Implementation Templates**: Updated templates showing all standard properties including TabIndex
33+
- **Form View Validation Guide**: Enhanced with design-time property validation section explaining the distinction between design-time validation (via manifest) and runtime validation (via Validate method)
34+
- **Data Binding Guide**: Added critical limitation documentation - K2 controls can only have one ListData property per control, with explanation of SMO binding restrictions
35+
- **Overview Guide**: Updated with accessibility section link, file upload/download control creation guidance, and updated Drag & Drop features list
36+
37+
#### Control Enhancements
38+
- **Drag & Drop**:
39+
- **File Download**: Added SmartObject file download support via a new action container.
40+
- **Icon-Only Mode**: New "ShowInformation" toggle for space-constrained layouts.
41+
- **Visual Overhaul**: Smoother drag animations and improved error state indicators.
42+
- **Arabic Calendar**: Added `TabIndex` support and enhanced keyboard navigation for better accessibility.
43+
- **Button List**: Added `MaxItems` property (int) with built-in design-time validation to limit item display.
44+
- **CAPTCHA Box**: Improved documentation regarding CORS handling and production deployment.
45+
46+
#### UI/UX Improvements
47+
- **Inspector Component**: Major refactoring and enhancements including TabIndex helper UI with increment/decrement buttons and value display, improved theme support, better validation feedback, and Flowbite integration
48+
- **Wizard Component**: Major updates and enhancements including design-time validation functionality, width auto limitation validation (blocks "auto" as initial value), data type support, int property type support with ValidationMessage, and improved validation feedback
49+
- **App Component**: Updates to main application component with improved navigation and theme support
50+
- **Documents Component**: Updates to documentation viewer with improved page navigation and document link handling
51+
- **Home Component**: Updates to home page with improved layout and content
52+
- **ValidationErrorPopup Component**: New component for design-time validation feedback with theme support
53+
- **File Generator**: Updates to control file generation utility with improved code generation
54+
- **Styles**: Updates to main CSS file with improved theming and Flowbite integration
55+
56+
### Changed
57+
58+
#### Platform
59+
- **Express v5 Upgrade**: Upgraded from Express v4 to Express v5 for improved performance and modern async/await support
60+
- **Flowbite v4 Upgrade**: Upgraded from Flowbite v3 to Flowbite v4 for enhanced UI components, improved theming, and better component integration
61+
- **Tailwind CSS v4**: Upgraded from Tailwind CSS v3 to v4 with new @tailwindcss/postcss and @tailwindcss/vite packages for better build performance
62+
- **Archiver Upgrade**: Upgraded archiver package for improved ZIP generation
63+
- **Vite Upgrade**: Updated to latest Vite version for improved build performance
64+
- **Package Updates**: Updated all dependencies to latest compatible versions for security and performance
65+
- **Build Configuration**: Updates to PostCSS and Vite configuration for optimized builds
66+
- **Base Control Script**: Updates to k2-base-control.js with code improvements
67+
68+
#### Documentation
69+
- **Standard Properties Guide**: Enhanced with TabIndex implementation details, ControlExpression documentation, and comprehensive width validation rules
70+
- **Manifest Configuration Guide**: Major updates with data types documentation, property categories, validation fields, int type documentation, and ControlExpression support
71+
- **Form View Validation Guide**: Enhanced with design-time property validation section explaining validationpattern and validationmessage
72+
- **Data Binding Guide**: Updated with ListData limitation documentation
73+
- **Overview Guide**: Updated with accessibility section and file upload/download guidance
74+
### Technical Notes
75+
76+
#### Breaking Changes
77+
- None
78+
79+
#### Migration
80+
- No manual migration steps required
81+
82+
#### Requirements
83+
- Node.js 14+ and a modern web browser
84+
85+
---
86+
87+
## [1.0.0] - First Public Release
88+
89+
### Added
90+
- Initial release of Control Dojo
91+
- Control Inspector for debugging existing controls
92+
- Control Wizard for creating new controls
93+
- Support for multiple control examples
94+
- ZIP generation for control packages

Controls/Arabic Calendar/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ The K2 Arabic Calendar control is designed specifically for Arabic-speaking user
4242
| **Width** | Number | `""` | Number or string with unit | Control width |
4343
| **IsVisible** | Boolean | `true` | `true`, `false` | Control visibility |
4444
| **IsEnabled** | Boolean | `true` | `true`, `false` | Control interactivity |
45+
| **TabIndex** | String | `"0"` | Any string | Tab order for keyboard navigation |
4546

4647
### Core Properties
4748

@@ -161,6 +162,15 @@ The K2 Arabic Calendar control is designed specifically for Arabic-speaking user
161162
control.IsEnabled = false; // Disable control
162163
```
163164

165+
#### TabIndex
166+
- **Type**: String
167+
- **Default**: `"0"`
168+
- **Description**: Tab order index for keyboard navigation
169+
- **Usage**:
170+
```javascript
171+
control.TabIndex = "1"; // Set tab order
172+
```
173+
164174
## Events
165175

166176
### Quick Reference
@@ -171,6 +181,7 @@ The K2 Arabic Calendar control is designed specifically for Arabic-speaking user
171181
| **Focus** | Control receives focus | None | Yes |
172182
| **Blur** | Control loses focus | None | Yes |
173183
| **ValidationError** | Invalid date input | `{ message: string, value: string }` | Yes |
184+
| **Rendered** | Control finishes initial rendering | None | Yes |
174185

175186
### Event Details
176187

Controls/Arabic Calendar/designtime_logic.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,20 @@ if (!window.customElements.get('arabic-calendar')) {
9090
safeRaisePropertyChanged(this, 'IsReadOnly');
9191
}
9292

93+
get TabIndex() { return this._tabIndex; }
94+
set TabIndex(val) {
95+
this._tabIndex = val || "0";
96+
if (this._hasRendered && this.input && this.input.length > 0) {
97+
this.input[0].setAttribute("tabindex", this._tabIndex);
98+
}
99+
safeRaisePropertyChanged(this, 'TabIndex');
100+
}
101+
93102
// Simplified template for designtime preview only (no popup or interactivity)
94103
_TEMPLATE = `
95104
<div class="container empty">
96105
<div class="input-wrap">
97-
<input type="text" class="date-input" placeholder="اضغط الزر لاختيار التاريخ" readonly aria-haspopup="dialog" aria-expanded="false" aria-controls="k2-cal-popup"/>
106+
<input type="text" class="date-input" tabindex="${this._tabIndex}" placeholder="اضغط الزر لاختيار التاريخ" readonly aria-haspopup="dialog" aria-expanded="false" aria-controls="k2-cal-popup"/>
98107
<span class="floating-watermark">اضغط الزر لاختيار التاريخ</span>
99108
<div class="icon-background"></div>
100109
</div>
@@ -115,6 +124,7 @@ if (!window.customElements.get('arabic-calendar')) {
115124
_isVisible = true;
116125
_isEnabled = true;
117126
_isReadOnly = false;
127+
_tabIndex = "0";
118128

119129
constructor() { super(); }
120130

@@ -334,6 +344,7 @@ if (!window.customElements.get('arabic-calendar')) {
334344
this.IsVisible = this._isVisible;
335345
this.IsEnabled = this._isEnabled;
336346
this.IsReadOnly = this._isReadOnly;
347+
this.TabIndex = this._tabIndex;
337348
if (this._value) this.container.classList.remove('empty');
338349
else this.container.classList.add('empty');
339350

Controls/Arabic Calendar/manifest.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
"displayName": "Arabic Calendar",
1818
"tagName": "arabic-calendar",
1919
"valuePropertyID": "Value",
20+
"datatypes": ["DateTime", "Date"],
2021
"supports": [
2122
"Value",
2223
"Width",
2324
"IsVisible",
2425
"IsEnabled",
25-
"IsReadOnly"
26+
"IsReadOnly",
27+
"TabIndex",
28+
"ControlExpression"
2629
],
2730
"events": [
2831
{

Controls/Arabic Calendar/runtime_logic.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,22 @@ if (!window.customElements.get('arabic-calendar')) {
119119
this.setAttribute('dateformat', val);
120120
safeRaisePropertyChanged(this, 'DateFormat');
121121
}
122+
123+
get TabIndex() { return this._tabIndex; }
124+
set TabIndex(val) {
125+
this._tabIndex = val || "0";
126+
if (this._hasRendered && this.input && this.input.length > 0) {
127+
this.input[0].setAttribute("tabindex", this._tabIndex);
128+
}
129+
safeRaisePropertyChanged(this, 'TabIndex');
130+
}
122131

123132

124133
// Template without styles (CSS is external)
125134
_TEMPLATE = `
126135
<div class="container empty">
127136
<div class="input-wrap">
128-
<input type="text" class="date-input" aria-haspopup="dialog" aria-expanded="false" aria-controls="k2-cal-popup"/>
137+
<input type="text" class="date-input" tabindex="${this._tabIndex}" aria-haspopup="dialog" aria-expanded="false" aria-controls="k2-cal-popup"/>
129138
<span class="floating-watermark">اضغط الزر لاختيار التاريخ</span>
130139
<div class="icon-background"></div>
131140
</div>
@@ -170,6 +179,7 @@ if (!window.customElements.get('arabic-calendar')) {
170179
_isValid = true;
171180
_logPrefix = '[arabic-calendar]';
172181
_isProgrammaticValue = false; // Flag to track programmatically set values
182+
_tabIndex = "0";
173183

174184
// Picker state management
175185
_currentView = 'days'; // 'days', 'months', 'years'
@@ -222,6 +232,7 @@ if (!window.customElements.get('arabic-calendar')) {
222232
this.Width = this._width;
223233
this.IsVisible = this._isVisible;
224234
this.IsEnabled = this._isEnabled;
235+
this.TabIndex = this._tabIndex;
225236
if (this._value && this._value.trim() !== '') {
226237
this.container.classList.remove('empty');
227238
// Hide watermark when there's a value

Controls/Button List/README.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Button List/
4646
|----------|------|---------|-------------|
4747
| **Value** | String | `null` | The value of the currently selected button. Updates automatically when a button is clicked. |
4848
| **List** | ListData | `[]` | Array of button items. Each item should have `display`, `value`, and optionally `icon` fields. Supports both static JSON and SmartObject binding. |
49-
| **MaxItems** | String | `"0"` | Maximum number of items to display (0 = unlimited). Accepts numeric values as strings. |
49+
| **MaxItems** | Int | `0` | Maximum number of items to display (0 = unlimited). Uses `int` type with built-in range validation plus a custom regex to enforce zero or positive integers. |
5050
| **ButtonLayout** | String | `"horizontal"` | Layout mode: `"horizontal"`, `"vertical"`, or `"grid"` |
5151
| **ButtonSize** | String | `"medium"` | Button size: `"small"`, `"medium"`, or `"large"` |
5252
| **ButtonStyle** | String | `"normal"` | Button style matching K2 button control styles: `"normal"`, `"main"`, `"quiet"`, or `"destructive"` |
@@ -78,20 +78,27 @@ All properties support the following fields:
7878
|-------|------|----------|-------------|
7979
| `id` | String | Yes | Unique property identifier (used in code) |
8080
| `friendlyname` | String | Yes | Human-readable name shown in property panel |
81-
| `type` | String | Yes | Property data type: `"string"`, `"bool"`, `"text"`, `"listdata"` |
81+
| `type` | String | Yes | Property data type: `"string"`, `"bool"`, `"int"`, `"text"`, `"listdata"` |
8282
| `initialvalue` | String | Yes | Default value for the property |
8383
| `refreshdisplay` | String | Yes | Whether changes trigger display refresh (`"true"` or `"false"`) |
8484
| `changesdisplay` | Boolean | Yes | Whether changes affect visual appearance |
8585
| `inputlength` | String | No | Maximum input length for string properties |
8686
| `description` | String | No | Property description/tooltip shown in designer |
8787
| `category` | String | No | Property category for grouping (e.g., `"Detail"` for data properties) |
8888

89+
### Design-time validation
90+
91+
- `MaxItems` now uses the new `int` property type. The default `int` validation blocks non-numeric values and values outside the 32-bit range.
92+
- Custom validation is configured with `validationpattern` and `validationmessage`. For `MaxItems`, the pattern `^0$|^[1-9]\\d*$` enforces zero or positive integers and the message `Must be zero or a positive integer.` is displayed when validation fails.
93+
- If you set only a pattern or only a message, the missing piece falls back to the default `int` behavior.
94+
8995
## Events
9096

9197
| Event | Description |
9298
|-------|-------------|
9399
| **OnChanged** (friendly name: "Changed") | Fired when a button is clicked and the Value property changes. Contains the new value, old value, and selected item. **Use this event to transfer the selected value to other controls.** |
94-
| **OnButtonClick** (friendly name: "Button Clicked") | Fired when any button is clicked. Contains the button item details (display, value, index) and previous selection state. |
100+
| **OnButtonClick** (friendly name: "Clicked") | Fired when any button is clicked. Contains the button item details (display, value, index) and previous selection state. |
101+
| **Rendered** | Fired when the control finishes initial rendering. Indicates the control is ready for interaction. |
95102

96103
## List Data Structure
97104

@@ -148,10 +155,32 @@ When binding to a SmartObject:
148155
| Method | Description | Parameters | Return Type |
149156
|--------|-------------|------------|-------------|
150157
| **clearSelection** | Clears the current selection | None | None |
151-
| **selectById** | Selects a button by its ID (value property) | `id` (String) | None |
152-
| **selectByText** | Selects a button by its display text | `text` (String) | None |
158+
| **selectById** | Selects a button by its ID (value property). Also accepts `selectByValue` as an alias. | `id` (String) - The value property of the button to select | None |
159+
| **selectByText** | Selects a button by its display text. Also accepts `selectByIndex` as an alias (for backward compatibility, but now selects by text, not index). | `text` (String) - The display text of the button to select | None |
153160
| **refresh** | Forces a re-render of the control | None | None |
154161

162+
### Method Execution via K2 Rules
163+
164+
Methods can be called via K2 rules using the `execute` method:
165+
166+
```javascript
167+
// Clear selection
168+
control.execute({ methodName: "clearSelection" });
169+
170+
// Select by ID/value
171+
control.execute({ methodName: "selectById", value: "1" });
172+
// or
173+
control.execute({ methodName: "selectByValue", value: "1" });
174+
175+
// Select by text
176+
control.execute({ methodName: "selectByText", text: "Home" });
177+
// or (backward compatibility)
178+
control.execute({ methodName: "selectByIndex", index: "Home" });
179+
180+
// Refresh
181+
control.execute({ methodName: "refresh" });
182+
```
183+
155184
### Method Examples
156185

157186
```javascript

Controls/Button List/manifest.json

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"displayName": "Button List",
88
"tagName": "button-list",
99
"description": "A flexible button list control that displays a collection of interactive buttons with customizable styling, layout options, and icon support. Supports both static data and SmartObject binding for dynamic content.",
10+
"datatypes": ["Text"],
1011
"supports": [
11-
"lo",
1212
"Width",
1313
"Height",
1414
"Value",
@@ -40,23 +40,16 @@
4040
"initialvalue": "55px",
4141
"changesdisplay": true
4242
},
43-
{
44-
"id": "List",
45-
"refreshdisplay": "true",
46-
"friendlyname": "List Items",
47-
"type": "listdata",
48-
"category": "Detail",
49-
"initialvalue": "[{\"display\": \"Item 1\", \"value\": \"1\"},{\"display\": \"Item 2\",\"value\": \"2\"}]"
50-
},
5143
{
5244
"id": "MaxItems",
5345
"refreshdisplay": "true",
5446
"friendlyname": "Max Items",
55-
"type": "string",
56-
"inputlength": "50",
57-
"initialvalue": "0",
47+
"type": "int",
48+
"initialvalue": 0,
49+
"validationpattern": "^0$|^[1-9]\\d*$",
50+
"validationmessage": "Must be zero or a positive integer.",
5851
"changesdisplay": true,
59-
"description": "Maximum number of items to display (0 = unlimited). Accepts numeric values as strings."
52+
"description": "Maximum number of items to display (0 = unlimited). Uses int type with default and custom validation."
6053
},
6154
{
6255
"id": "ButtonLayout",

Controls/CAPTCHA Box/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ A customizable CAPTCHA box for Control Dojo that provides bot protection using o
3434
| `ErrorMessage` | String | `""` | Message shown on verification failure (localized) |
3535
| `AutoRefresh` | Boolean | `true` | Whether to automatically refresh CAPTCHA on verification failure |
3636
| `Theme` | String | `"light"` | Visual theme (`"light"` or `"dark"`) |
37+
| `Tooltip` | String | `""` | Custom tooltip text for the input field (programmatic access only) |
38+
| `TabIndex` | String | `"0"` | Tab order index for keyboard navigation (programmatic access only) |
39+
| `AccessibilityText` | String | `""` | Accessibility text for screen readers (programmatic access only) |
40+
| `ControlStyle` | String | `""` | Control style template (programmatic access only) |
41+
| `Enabled` | String | `"true"` | Legacy property for enabled state (programmatic access only, use `IsEnabled` instead) |
42+
| `ReadOnly` | String | `"false"` | Legacy property for read-only state (programmatic access only, use `IsReadOnly` instead) |
43+
| `Format` | String | `""` | Format property (programmatic access only) |
3744

3845
### Standard K2 Control Properties
3946

@@ -55,6 +62,7 @@ A customizable CAPTCHA box for Control Dojo that provides bot protection using o
5562
| `OnEnter` | Fired when the user presses Enter in the input field |
5663
| `Verified` | Fired when CAPTCHA verification is successful |
5764
| `VerificationFailed` | Fired when CAPTCHA verification fails |
65+
| `Rendered` | Fired when the control finishes initial rendering |
5866

5967
## Methods
6068

Controls/CAPTCHA Box/manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"displayName": "CAPTCHA Box",
2020
"tagName": "captcha-control",
2121
"valuePropertyID": "CaptchaResponse",
22+
"datatypes": ["Text"],
2223
"supports": [
2324
"Value",
2425
"Width",

0 commit comments

Comments
 (0)