@rettangoli/ui 0.1.24 → 0.1.26

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rettangoli/ui",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "A UI component library for building web interfaces.",
5
5
  "main": "dist/rettangoli-esm.min.js",
6
6
  "type": "module",
@@ -1,4 +1,3 @@
1
-
2
1
  const updateAttributes = ({ form, defaultValues = {}, refs }) => {
3
2
  const { fields = [] } = form;
4
3
  fields.forEach((field) => {
@@ -29,17 +28,43 @@ const updateAttributes = ({ form, defaultValues = {}, refs }) => {
29
28
  })
30
29
  }
31
30
 
31
+ const autoFocusFirstInput = (refs) => {
32
+ // Find first focusable field
33
+ for (const fieldKey in refs) {
34
+ if (fieldKey.startsWith('field-')) {
35
+ const fieldRef = refs[fieldKey];
36
+ if (fieldRef && fieldRef.elm) {
37
+ const element = fieldRef.elm;
38
+
39
+ if (element.focus) {
40
+ // Currently only available for input-text and input-textarea
41
+ element.focus();
42
+ return;
43
+ }
44
+ }
45
+ }
46
+ }
47
+ };
48
+
49
+
32
50
  export const handleBeforeMount = (deps) => {
33
51
  const { store, props } = deps;
34
52
  store.setFormValues(props.defaultValues);
35
53
  };
36
54
 
37
55
  export const handleAfterMount = (deps) => {
38
- const { props, getRefIds, render } = deps;
56
+ const { props, getRefIds, render, attrs } = deps;
39
57
  const { form = {}, defaultValues } = props;
40
58
  const refs = getRefIds();
41
59
  updateAttributes({ form, defaultValues, refs });
42
60
  render();
61
+
62
+ // Auto-focus first input field if autofocus attribute is set
63
+ if (attrs?.autofocus) {
64
+ setTimeout(() => {
65
+ autoFocusFirstInput(refs);
66
+ }, 50);
67
+ }
43
68
  };
44
69
 
45
70
  export const handleOnUpdate = (deps, payload) => {
@@ -257,3 +282,38 @@ export const handleTooltipMouseLeave = (deps) => {
257
282
  store.hideTooltip();
258
283
  render();
259
284
  };
285
+
286
+ export const handleKeyDown = (deps, payload) => {
287
+ const { store, dispatchEvent, props } = deps;
288
+ const event = payload._event;
289
+
290
+ // Handle Enter key to submit form
291
+ if (event.key === 'Enter' && !event.shiftKey) {
292
+ const target = event.target;
293
+ // Don't submit if we're in a textarea (native or custom component)
294
+ if (target.tagName === 'TEXTAREA' || target.tagName === 'RTGL-TEXTAREA') {
295
+ return;
296
+ }
297
+
298
+ event.preventDefault();
299
+
300
+ // Dispatch action-click event for the first button
301
+ const form = props.form || {};
302
+ const actions = form.actions || {};
303
+ const buttons = actions.buttons || [];
304
+
305
+ if (buttons.length > 0) {
306
+ const firstButtonId = buttons[0].id;
307
+ const formValues = store.selectFormValues();
308
+
309
+ dispatchEvent(
310
+ new CustomEvent("action-click", {
311
+ detail: {
312
+ actionId: firstButtonId,
313
+ formValues: formValues,
314
+ },
315
+ }),
316
+ );
317
+ }
318
+ }
319
+ };
@@ -258,6 +258,10 @@ propsSchema:
258
258
  - content
259
259
 
260
260
  refs:
261
+ form-container:
262
+ eventListeners:
263
+ keydown:
264
+ handler: handleKeyDown
261
265
  action-*:
262
266
  eventListeners:
263
267
  click:
@@ -272,6 +276,8 @@ refs:
272
276
  eventListeners:
273
277
  input-change:
274
278
  handler: handleInputChange
279
+ textarea-change:
280
+ handler: handleInputChange
275
281
  select-change:
276
282
  handler: handleSelectChange
277
283
  add-option-selected:
@@ -301,7 +307,7 @@ events:
301
307
  action-click: {}
302
308
 
303
309
  template:
304
- - rtgl-view w=f p=md g=lg ${containerAttrString}:
310
+ - rtgl-view#form-container w=f p=md g=lg ${containerAttrString}:
305
311
  - rtgl-view g=sm w=f:
306
312
  - $if title:
307
313
  - rtgl-text s=lg: ${title}
@@ -161,7 +161,7 @@ class RettangoliButtonElement extends HTMLElement {
161
161
  constructor() {
162
162
  super();
163
163
  RettangoliButtonElement.initializeStyleSheet();
164
- this.shadow = this.attachShadow({ mode: "closed" });
164
+ this.shadow = this.attachShadow({ mode: "open" });
165
165
  this.shadow.adoptedStyleSheets = [RettangoliButtonElement.styleSheet];
166
166
 
167
167
  // Create initial DOM structure
@@ -45,7 +45,7 @@ class RettangoliColorPickerElement extends HTMLElement {
45
45
  constructor() {
46
46
  super();
47
47
  RettangoliColorPickerElement.initializeStyleSheet();
48
- this.shadow = this.attachShadow({ mode: "closed" });
48
+ this.shadow = this.attachShadow({ mode: "open" });
49
49
  this.shadow.adoptedStyleSheets = [RettangoliColorPickerElement.styleSheet];
50
50
 
51
51
  // Initialize style tracking properties
@@ -63,7 +63,7 @@ class RettangoliImageElement extends HTMLElement {
63
63
  constructor() {
64
64
  super();
65
65
  RettangoliImageElement.initializeStyleSheet();
66
- this.shadow = this.attachShadow({ mode: "closed" });
66
+ this.shadow = this.attachShadow({ mode: "open" });
67
67
  this.shadow.adoptedStyleSheets = [RettangoliImageElement.styleSheet];
68
68
 
69
69
  // Create initial DOM structure
@@ -57,7 +57,7 @@ class RettangoliInputNumberElement extends HTMLElement {
57
57
  constructor() {
58
58
  super();
59
59
  RettangoliInputNumberElement.initializeStyleSheet();
60
- this.shadow = this.attachShadow({ mode: "closed" });
60
+ this.shadow = this.attachShadow({ mode: "open" });
61
61
  this.shadow.adoptedStyleSheets = [RettangoliInputNumberElement.styleSheet];
62
62
 
63
63
  // Initialize style tracking properties
@@ -57,7 +57,7 @@ class RettangoliInputElement extends HTMLElement {
57
57
  constructor() {
58
58
  super();
59
59
  RettangoliInputElement.initializeStyleSheet();
60
- this.shadow = this.attachShadow({ mode: "closed" });
60
+ this.shadow = this.attachShadow({ mode: "open" });
61
61
  this.shadow.adoptedStyleSheets = [RettangoliInputElement.styleSheet];
62
62
 
63
63
  // Initialize style tracking properties
@@ -76,7 +76,7 @@ class RettangoliSliderElement extends HTMLElement {
76
76
  constructor() {
77
77
  super();
78
78
  RettangoliSliderElement.initializeStyleSheet();
79
- this.shadow = this.attachShadow({ mode: "closed" });
79
+ this.shadow = this.attachShadow({ mode: "open" });
80
80
  this.shadow.adoptedStyleSheets = [RettangoliSliderElement.styleSheet];
81
81
 
82
82
  // Initialize style tracking properties
@@ -30,7 +30,7 @@ class RettangoliSvgElement extends HTMLElement {
30
30
  constructor() {
31
31
  super();
32
32
  RettangoliSvgElement.initializeStyleSheet();
33
- this.shadow = this.attachShadow({ mode: "closed" });
33
+ this.shadow = this.attachShadow({ mode: "open" });
34
34
  this.shadow.adoptedStyleSheets = [RettangoliSvgElement.styleSheet];
35
35
  }
36
36
 
@@ -53,7 +53,7 @@ class RettangoliTextElement extends HTMLElement {
53
53
  constructor() {
54
54
  super();
55
55
  RettangoliTextElement.initializeStyleSheet();
56
- this.shadow = this.attachShadow({ mode: "closed" });
56
+ this.shadow = this.attachShadow({ mode: "open" });
57
57
  this.shadow.adoptedStyleSheets = [RettangoliTextElement.styleSheet];
58
58
 
59
59
  // Create initial DOM structure
@@ -47,7 +47,7 @@ class RettangoliTextAreaElement extends HTMLElement {
47
47
  constructor() {
48
48
  super();
49
49
  RettangoliTextAreaElement.initializeStyleSheet();
50
- this.shadow = this.attachShadow({ mode: "closed" });
50
+ this.shadow = this.attachShadow({ mode: "open" });
51
51
  this.shadow.adoptedStyleSheets = [RettangoliTextAreaElement.styleSheet];
52
52
 
53
53
  // Initialize style tracking properties
@@ -115,6 +115,19 @@ class RettangoliTextAreaElement extends HTMLElement {
115
115
  this._updateTextareaAttributes();
116
116
  }
117
117
 
118
+ // Public methods to proxy focus and select to internal textarea
119
+ focus() {
120
+ if (this._textareaElement) {
121
+ this._textareaElement.focus();
122
+ }
123
+ }
124
+
125
+ select() {
126
+ if (this._textareaElement) {
127
+ this._textareaElement.select();
128
+ }
129
+ }
130
+
118
131
  attributeChangedCallback(name, oldValue, newValue) {
119
132
  if (name === 'value') {
120
133
  requestAnimationFrame((() => {
@@ -67,7 +67,7 @@ class RettangoliViewElement extends HTMLElement {
67
67
  constructor() {
68
68
  super();
69
69
  RettangoliViewElement.initializeStyleSheet();
70
- this.shadow = this.attachShadow({ mode: "closed" });
70
+ this.shadow = this.attachShadow({ mode: "open" });
71
71
  this.shadow.adoptedStyleSheets = [RettangoliViewElement.styleSheet];
72
72
 
73
73
  // Create initial DOM structure