@ansiversa/components 0.0.128 → 0.0.130

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": "@ansiversa/components",
3
- "version": "0.0.128",
3
+ "version": "0.0.130",
4
4
  "description": "Shared UI components and layouts for the Ansiversa ecosystem",
5
5
  "type": "module",
6
6
  "exports": {
@@ -2,6 +2,7 @@
2
2
  interface Props {
3
3
  featureKey: string;
4
4
  value: string;
5
+ valueSourceSelector?: string;
5
6
  minChars?: number;
6
7
  maxChars?: number;
7
8
  label?: string;
@@ -13,6 +14,7 @@ interface Props {
13
14
  const {
14
15
  featureKey,
15
16
  value,
17
+ valueSourceSelector,
16
18
  minChars = 30,
17
19
  maxChars = 1500,
18
20
  label = "AI",
@@ -31,6 +33,7 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
31
33
  {...rest}
32
34
  x-data={`avAiAssist(${JSON.stringify({
33
35
  featureKey,
36
+ valueSourceSelector: valueSourceSelector ?? null,
34
37
  minChars,
35
38
  maxChars,
36
39
  label,
@@ -56,9 +59,17 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
56
59
  <div class="av-ai-assist-overlay" @click.self="closeModal()" @keydown.escape.window="closeModal()">
57
60
  <div class="av-ai-assist-modal" role="dialog" aria-modal="true" aria-label="AI suggestions">
58
61
  <div class="av-auth-stack-sm">
59
- <div class="av-row-between">
62
+ <div class="av-ai-assist-modal-header">
60
63
  <h3 class="av-card-heading av-m-0">AI Suggestions</h3>
61
- <button type="button" class="av-btn-ghost av-btn-sm" @click.prevent="closeModal()">Close</button>
64
+ <button
65
+ type="button"
66
+ class="av-btn-ghost av-btn-sm av-ai-assist-close"
67
+ @click.prevent="closeModal()"
68
+ aria-label="Close AI suggestions"
69
+ title="Close"
70
+ >
71
+ <span aria-hidden="true">X</span>
72
+ </button>
62
73
  </div>
63
74
 
64
75
  <template x-if="loading">
@@ -97,6 +108,10 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
97
108
  if (typeof window !== "undefined" && !window.avAiAssist) {
98
109
  window.avAiAssist = (config) => ({
99
110
  featureKey: config.featureKey,
111
+ valueSourceSelector:
112
+ typeof config.valueSourceSelector === "string" && config.valueSourceSelector.trim()
113
+ ? config.valueSourceSelector.trim()
114
+ : null,
100
115
  minChars: Number(config.minChars ?? 30),
101
116
  maxChars: Number(config.maxChars ?? 1500),
102
117
  label: typeof config.label === "string" && config.label ? config.label : "AI",
@@ -109,8 +124,17 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
109
124
  suggestions: [],
110
125
  copiedIndex: null,
111
126
  observer: null,
127
+ sourceElement: null,
112
128
 
113
129
  init() {
130
+ if (this.valueSourceSelector) {
131
+ this.sourceElement = document.querySelector(this.valueSourceSelector);
132
+ if (this.sourceElement) {
133
+ this.sourceElement.addEventListener("input", () => this.syncValue());
134
+ this.sourceElement.addEventListener("change", () => this.syncValue());
135
+ }
136
+ }
137
+
114
138
  this.syncValue();
115
139
 
116
140
  if (typeof MutationObserver !== "undefined") {
@@ -136,6 +160,11 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
136
160
  },
137
161
 
138
162
  syncValue() {
163
+ if (this.sourceElement && typeof this.sourceElement.value === "string") {
164
+ this.value = this.sourceElement.value;
165
+ return;
166
+ }
167
+
139
168
  const nextValue = this.$el.getAttribute("data-value") ?? "";
140
169
  this.value = String(nextValue);
141
170
  },
@@ -283,6 +312,21 @@ const componentId = `av-ai-assist-${Math.random().toString(36).slice(2, 10)}`;
283
312
  padding: 1rem;
284
313
  }
285
314
 
315
+ .av-ai-assist-modal-header {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: space-between;
319
+ flex-wrap: nowrap;
320
+ gap: 0.75rem;
321
+ }
322
+
323
+ .av-ai-assist-close {
324
+ margin-left: auto;
325
+ flex-shrink: 0;
326
+ min-width: 2.25rem;
327
+ justify-content: center;
328
+ }
329
+
286
330
  .av-ai-assist-suggestion {
287
331
  display: grid;
288
332
  gap: 0.75rem;