@syntrologie/adapt-faq 2.1.0 → 2.2.0-canary.2

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.
@@ -7,7 +7,7 @@
7
7
  * Demonstrates the compositional action pattern where child actions
8
8
  * (faq:question) serve as configuration data for the parent widget.
9
9
  */
10
- import type { FAQConfig, DecisionStrategy } from './types';
10
+ import type { DecisionStrategy, FAQConfig } from './types';
11
11
  export interface FAQWidgetRuntime {
12
12
  evaluateSync: <T>(strategy: DecisionStrategy<T>) => {
13
13
  value: T;
@@ -1 +1 @@
1
- {"version":3,"file":"FAQWidget.d.ts","sourceRoot":"","sources":["../src/FAQWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAEV,SAAS,EAIT,gBAAgB,EACjB,MAAM,SAAS,CAAC;AA0CjB,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IACtF,OAAO,EAAE;QAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;KAAE,CAAC;IAC7D,MAAM,EAAE;QACN,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACjE,SAAS,CAAC,EAAE,CACV,gBAAgB,EACZ;YAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,GAC7D,CAAC,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,CAAC,EACpF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,KAC3F,MAAM,IAAI,CAAC;QAChB,SAAS,CAAC,EAAE,CACV,MAAM,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,EAClD,KAAK,CAAC,EAAE,MAAM,KACX,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3E,CAAC;IACF,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAC;IACtF,4DAA4D;IAC5D,WAAW,CAAC,EAAE;QACZ,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;QAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,KAAK,IAAI,CAAC;KACrE,CAAC;CACH;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AA4SD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,cAAc,2CA2UxE;AAMD;;GAEG;AACH,eAAO,MAAM,kBAAkB;qBAEhB,WAAW,WACb,SAAS,GAAG;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CAiD3E,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"FAQWidget.d.ts","sourceRoot":"","sources":["../src/FAQWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EACV,gBAAgB,EAEhB,SAAS,EAIV,MAAM,SAAS,CAAC;AA2CjB,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IACtF,OAAO,EAAE;QAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;KAAE,CAAC;IAC7D,MAAM,EAAE;QACN,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACjE,SAAS,CAAC,EAAE,CACV,gBAAgB,EACZ;YAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,GAC7D,CAAC,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,CAAC,EACpF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,KAC3F,MAAM,IAAI,CAAC;QAChB,SAAS,CAAC,EAAE,CACV,MAAM,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,EAClD,KAAK,CAAC,EAAE,MAAM,KACX,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3E,CAAC;IACF,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAC;IACtF,4DAA4D;IAC5D,WAAW,CAAC,EAAE;QACZ,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;QAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,KAAK,IAAI,CAAC;KACrE,CAAC;CACH;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AA+SD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,cAAc,2CA2UxE;AAMD;;GAEG;AACH,eAAO,MAAM,kBAAkB;qBAEhB,WAAW,WACb,SAAS,GAAG;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CAiD3E,CAAC;AAEF,eAAe,SAAS,CAAC"}
package/dist/FAQWidget.js CHANGED
@@ -8,8 +8,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  * Demonstrates the compositional action pattern where child actions
9
9
  * (faq:question) serve as configuration data for the parent widget.
10
10
  */
11
- import { base, slateGrey, purple } from '@syntro/design-system/tokens';
12
- import React, { useEffect, useReducer, useMemo, useCallback, useState } from 'react';
11
+ import { base, purple, slateGrey } from '@syntro/design-system/tokens';
12
+ import React, { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
13
13
  import { createRoot } from 'react-dom/client';
14
14
  // ============================================================================
15
15
  // Helpers
@@ -28,6 +28,7 @@ function renderAnswer(answer) {
28
28
  return _jsx("p", { style: { margin: 0 }, children: answer });
29
29
  }
30
30
  if (answer.type === 'rich') {
31
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: content is pre-sanitized by backend — FAQAnswer.html is CMS/config content, not user-controlled input
31
32
  return _jsx("div", { style: { margin: 0 }, dangerouslySetInnerHTML: { __html: answer.html } });
32
33
  }
33
34
  // markdown — render content as text (full markdown rendering is a future enhancement)
@@ -263,10 +264,10 @@ function FAQItem({ item, isExpanded, onToggle, theme, feedbackConfig, feedbackVa
263
264
  ...baseStyles.feedback,
264
265
  ...colors.feedbackPrompt,
265
266
  };
266
- return (_jsxs("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [_jsxs("button", { style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [_jsx("span", { children: question }), _jsx("span", { style: chevronStyle, children: '\u25BC' })] }), _jsxs("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && (_jsxs("div", { style: feedbackStyle, children: [_jsx("span", { children: getFeedbackPrompt(feedbackConfig) }), _jsx("button", { style: {
267
+ return (_jsxs("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [_jsxs("button", { type: "button", style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [_jsx("span", { children: question }), _jsx("span", { style: chevronStyle, children: '\u25BC' })] }), _jsxs("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && (_jsxs("div", { style: feedbackStyle, children: [_jsx("span", { children: getFeedbackPrompt(feedbackConfig) }), _jsx("button", { type: "button", style: {
267
268
  ...baseStyles.feedbackButton,
268
269
  ...(feedbackValue === 'up' ? baseStyles.feedbackButtonSelected : {}),
269
- }, "aria-label": "Thumbs up", onClick: () => onFeedback(item.config.id, question, 'up'), children: '\uD83D\uDC4D' }), _jsx("button", { style: {
270
+ }, "aria-label": "Thumbs up", onClick: () => onFeedback(item.config.id, question, 'up'), children: '\uD83D\uDC4D' }), _jsx("button", { type: "button", style: {
270
271
  ...baseStyles.feedbackButton,
271
272
  ...(feedbackValue === 'down' ? baseStyles.feedbackButtonSelected : {}),
272
273
  }, "aria-label": "Thumbs down", onClick: () => onFeedback(item.config.id, question, 'down'), children: '\uD83D\uDC4E' })] }))] })] }));
@@ -391,6 +392,7 @@ export function FAQWidget({ config, runtime, instanceId }) {
391
392
  return unsubscribe;
392
393
  }, [runtime]);
393
394
  // Filter visible questions based on per-item showWhen
395
+ // biome-ignore lint/correctness/useExhaustiveDependencies: renderTick is intentionally included to force re-evaluation when the runtime's mutable context changes (subscribed above via forceUpdate)
394
396
  const visibleQuestions = useMemo(() => config.actions.filter((q) => {
395
397
  // No showWhen = always visible
396
398
  if (!q.showWhen)
@@ -398,9 +400,7 @@ export function FAQWidget({ config, runtime, instanceId }) {
398
400
  // Evaluate the decision strategy
399
401
  const result = runtime.evaluateSync(q.showWhen);
400
402
  return result.value;
401
- }),
402
- // eslint-disable-next-line react-hooks/exhaustive-deps
403
- [config.actions, runtime, renderTick]);
403
+ }), [config.actions, runtime, renderTick]);
404
404
  // NOTE: faq:question_revealed is now published by useNotifyWatcher in
405
405
  // ShadowCanvasOverlay (always mounted), so it fires even with drawer closed.
406
406
  // Apply priority ordering
package/dist/cdn.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,UAAU,CAAC;AAIlD;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;2BAwD2ynB,CAAC;8BAA8B,CAAC;;;;;;;;;QAhD51nB;;;;WAIG;8BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;+BAqBtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;CAQjD,CAAC;AAaF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,UAAU,CAAC;AAIlD;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;2BAwDgqoB,CAAC;8BAA8B,CAAC;;;;;;;;;QAhDjtoB;;;;WAIG;8BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;+BAqBtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;CAQjD,CAAC;AAaF,eAAe,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,OAAO,EAKL,KAAK,gBAAgB,EAEtB,MAAM,SAAS,CAAC;AAiLjB,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAkUvE;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAIvB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;CAGlB,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,OAAO,EACL,KAAK,gBAAgB,EAMtB,MAAM,SAAS,CAAC;AAiLjB,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAsWvE;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAIvB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;CAGlB,CAAC;AAEF,eAAe,SAAS,CAAC"}
package/dist/editor.js CHANGED
@@ -6,9 +6,9 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  * Displays a scannable list of Q&A cards with trigger, rationale,
7
7
  * and inline editing. Includes detection badges and hover-to-highlight.
8
8
  */
9
- import { EditorLayout, EditorHeader, EditorBody, EditorFooter, EditorCard, DetectionBadge, DismissedSection, GroupHeader, BeforeAfterToggle, EditorInput, EditorTextarea, EditBackButton, EmptyState, ConditionStatusLine, useShowWhenStatus, } from '@syntrologie/shared-editor-ui';
10
- import React, { useState, useCallback, useEffect, useRef } from 'react';
11
- import { summarizeFAQItem, describeTrigger } from './summarize';
9
+ import { ConditionStatusLine, DetectionBadge, DismissedSection, EditorBody, EditorCard, EditorFooter, EditorHeader, EditorInput, EditorLayout, EditorTextarea, EmptyState, GroupHeader, TriggerJourney, useShowWhenStatus, } from '@syntrologie/shared-editor-ui';
10
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
11
+ import { describeTrigger, summarizeFAQItem } from './summarize';
12
12
  import { isOwnAction, } from './types';
13
13
  function isRuleStrategy(s) {
14
14
  return (typeof s === 'object' &&
@@ -135,12 +135,29 @@ export function FAQEditor({ config, onChange, editor }) {
135
135
  const typedConfig = config;
136
136
  const [dismissedKeys, setDismissedKeys] = useState(() => editor.getDismissedKeys?.() ?? new Set());
137
137
  const [editingKey, setEditingKey] = useState(null);
138
- const [previewMode, setPreviewMode] = useState('after');
138
+ const [_previewMode, setPreviewMode] = useState('after');
139
139
  const [_hoveredKey, setHoveredKey] = useState(null);
140
140
  // Sync dismissed keys back to navigation context on every change
141
141
  useEffect(() => {
142
142
  editor.setDismissedKeys?.(dismissedKeys);
143
143
  }, [dismissedKeys, editor]);
144
+ // React to global before/after toggle from the panel
145
+ // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitted — adding config/typedConfig/previewConfig would cause infinite re-renders since previewConfig triggers state updates
146
+ useEffect(() => {
147
+ const mode = editor.previewMode;
148
+ if (!mode)
149
+ return;
150
+ if (mode === 'before') {
151
+ // Remove all FAQ items — push a config with every item filtered out
152
+ const allKeys = new Set(flattenItems(typedConfig).map((item) => item.key));
153
+ const empty = filterConfig(typedConfig, allKeys);
154
+ editor.previewConfig(empty);
155
+ }
156
+ else {
157
+ // Restore the full config
158
+ editor.previewConfig(config);
159
+ }
160
+ }, [editor.previewMode]);
144
161
  // If navigated here with an editKey, jump directly to that item's edit view
145
162
  const initialConsumed = useRef(false);
146
163
  useEffect(() => {
@@ -159,7 +176,7 @@ export function FAQEditor({ config, onChange, editor }) {
159
176
  const detectionMap = useDetection(allItems, editor.getCurrentRoute);
160
177
  const foundCount = activeItems.filter((item) => detectionMap.get(item.key)?.found).length;
161
178
  // Live showWhen status for condition diagnostics
162
- const showWhenItems = React.useMemo(() => allItems.map((item) => ({
179
+ const showWhenItems = useMemo(() => allItems.map((item) => ({
163
180
  id: item.key,
164
181
  showWhen: item.question.showWhen,
165
182
  })), [allItems]);
@@ -198,7 +215,12 @@ export function FAQEditor({ config, onChange, editor }) {
198
215
  editor.previewConfig(config);
199
216
  editor.clearHighlight();
200
217
  }, [editor, config]);
201
- const handleBeforeAfter = useCallback((mode) => {
218
+ // Register back handler in panel header when editing
219
+ useEffect(() => {
220
+ editor.setBackHandler?.(editingKey !== null ? handleBackToList : null);
221
+ return () => editor.setBackHandler?.(null);
222
+ }, [editingKey, handleBackToList, editor]);
223
+ const _handleBeforeAfter = useCallback((mode) => {
202
224
  setPreviewMode(mode);
203
225
  if (mode === 'before') {
204
226
  const filtered = filterConfig(typedConfig, new Set([editingKey]));
@@ -242,26 +264,29 @@ export function FAQEditor({ config, onChange, editor }) {
242
264
  if (!q)
243
265
  return null;
244
266
  const item = allItems.find((it) => it.key === String(index));
245
- return (_jsxs("div", { className: "se-py-1", children: [item && item.trigger !== 'All pages' && (_jsxs("div", { "data-trigger": true, className: "se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1", onClick: () => handleTriggerClick(item), children: [_jsx("span", { children: '\u{1f4cd}' }), _jsx("span", { children: item.trigger })] })), _jsx(EditorInput, { label: "Question", value: q.config.question, onChange: (e) => handleFieldChange(index, 'question', e.target.value) }), _jsx(EditorTextarea, { label: "Answer", value: getAnswerText(q.config.answer), onChange: (e) => handleFieldChange(index, 'answer', e.target.value) }), _jsx(EditorInput, { label: "Category", value: q.config.category || '', onChange: (e) => handleFieldChange(index, 'category', e.target.value || undefined), placeholder: "e.g., Billing, Account" }), _jsxs("div", { children: [_jsx("label", { className: "se-text-[11px] se-font-semibold se-text-slate-grey-7 se-mb-1 se-block", children: "AI Rationale" }), _jsx("div", { className: "se-p-2 se-rounded se-border se-border-dashed se-border-white/15 se-bg-white/[0.02] se-text-slate-grey-8 se-text-xs se-mb-2", children: q.rationale ? q.rationale.why : 'N/A' })] })] }));
267
+ return (_jsxs("div", { className: "se-py-1", children: [item && item.trigger !== 'All pages' && (_jsxs("button", { type: "button", "data-trigger": true, className: "se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1 se-border-none se-bg-transparent se-p-0 se-text-left", onClick: () => handleTriggerClick(item), children: [_jsx("span", { children: '\u{1f4cd}' }), _jsx("span", { children: item.trigger })] })), _jsx(EditorInput, { label: "Question", value: q.config.question, onChange: (e) => handleFieldChange(index, 'question', e.target.value) }), _jsx(EditorTextarea, { label: "Answer", value: getAnswerText(q.config.answer), onChange: (e) => handleFieldChange(index, 'answer', e.target.value) }), _jsx(EditorInput, { label: "Category", value: q.config.category || '', onChange: (e) => handleFieldChange(index, 'category', e.target.value || undefined), placeholder: "e.g., Billing, Account" }), _jsxs("div", { children: [_jsx("span", { className: "se-text-[11px] se-font-semibold se-text-slate-grey-7 se-mb-1 se-block", children: "AI Rationale" }), _jsx("div", { className: "se-p-2 se-rounded se-border se-border-dashed se-border-white/15 se-bg-white/[0.02] se-text-slate-grey-8 se-text-xs se-mb-2", children: q.rationale ? q.rationale.why : 'N/A' })] }), _jsx(TriggerJourney, { status: showWhenStatuses.get(String(index)) ?? null })] }));
246
268
  };
247
269
  return (_jsxs(EditorLayout, { children: [_jsx(EditorHeader, { title: "Review Questions", subtitle: `${totalQuestions} question${totalQuestions !== 1 ? 's' : ''}${totalQuestions > 0 ? ` (${foundCount} found on this page)` : ''}`, onBack: () => editor.navigateHome() }), _jsx(EditorBody, { children: editingKey !== null ? (
248
270
  /* ---- Edit mode ---- */
249
271
  (() => {
250
272
  const editIndex = Number(editingKey);
251
273
  const editItem = allItems.find((it) => it.key === editingKey);
252
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "se-flex se-items-center se-gap-2 se-mb-3 se-text-[13px] se-font-semibold se-text-slate-grey-10", children: [_jsx("span", { children: '\u2753' }), _jsx("span", { children: editItem?.summary })] }), _jsx(BeforeAfterToggle, { mode: previewMode, onToggle: handleBeforeAfter }), renderEditFields(editIndex), _jsx(EditBackButton, { onClick: handleBackToList })] }));
274
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "se-flex se-items-center se-gap-2 se-mb-3 se-text-[13px] se-font-semibold se-text-slate-grey-10", children: [_jsx("span", { children: '\u2753' }), _jsx("span", { children: editItem?.summary })] }), renderEditFields(editIndex)] }));
253
275
  })()) : (
254
276
  /* ---- List mode ---- */
255
277
  _jsxs(_Fragment, { children: [allItems.length === 0 && _jsx(EmptyState, { message: "No FAQ questions configured." }), activeItems.length > 0 && (_jsxs(_Fragment, { children: [_jsx(GroupHeader, { label: "FAQ", count: activeItems.length }), activeItems.map((item) => {
256
278
  const detection = detectionMap.get(item.key);
257
- return (_jsxs(EditorCard, { itemKey: item.key, onMouseEnter: () => handleCardHover(item), onMouseLeave: handleCardLeave, children: [item.trigger !== 'All pages' && (_jsxs("div", { "data-trigger": true, className: "se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1", onClick: (e) => {
279
+ return (_jsxs(EditorCard, { itemKey: item.key, onClick: () => handleCardBodyClick(item), onMouseEnter: () => handleCardHover(item), onMouseLeave: handleCardLeave, children: [item.trigger !== 'All pages' && (_jsxs("button", { type: "button", "data-trigger": true, className: "se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1 se-border-none se-bg-transparent se-p-0 se-text-left", onClick: (e) => {
258
280
  e.stopPropagation();
259
281
  handleTriggerClick(item);
260
- }, children: [_jsx("span", { children: '\u{1f4cd}' }), _jsx("span", { children: item.trigger })] })), _jsxs("div", { "data-card-body": true, className: "se-flex se-items-center se-gap-2 se-cursor-pointer", onClick: () => handleCardBodyClick(item), children: [_jsx(DetectionBadge, { found: detection?.found ?? false }), _jsx("span", { className: "se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap", children: item.summary }), _jsx("button", { className: "se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-slate-grey-7 se-text-sm se-cursor-pointer se-shrink-0 se-leading-none", onClick: (e) => {
282
+ }, children: [_jsx("span", { children: '\u{1f4cd}' }), _jsx("span", { children: item.trigger })] })), _jsxs("div", { "data-card-body": true, role: "button", tabIndex: 0, className: "se-flex se-items-center se-gap-2 se-cursor-pointer", onClick: () => handleCardBodyClick(item), onKeyDown: (e) => {
283
+ if (e.key === 'Enter' || e.key === ' ')
284
+ handleCardBodyClick(item);
285
+ }, children: [_jsx(DetectionBadge, { found: detection?.found ?? false }), _jsx("span", { className: "se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap", children: item.summary }), _jsx("button", { type: "button", className: "se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-slate-grey-7 se-text-sm se-cursor-pointer se-shrink-0 se-leading-none", onClick: (e) => {
261
286
  e.stopPropagation();
262
287
  handleDismiss(item.key);
263
288
  }, title: "Dismiss this question", children: "\u00D7" })] }), _jsxs("div", { className: "se-text-[10px] se-text-slate-grey-7 se-mt-1", children: ["WHY: ", item.rationale ? item.rationale.why : 'N/A'] }), _jsx(ConditionStatusLine, { status: showWhenStatuses.get(item.key) ?? null })] }, item.key));
264
- })] })), dismissedItems.length > 0 && (_jsx(DismissedSection, { count: dismissedItems.length, children: dismissedItems.map((item) => (_jsxs("div", { className: "se-flex se-items-center se-gap-2 se-py-1.5 se-px-2.5 se-rounded-md se-border se-border-white/[0.03] se-bg-transparent se-mb-0.5 se-cursor-pointer se-text-xs se-text-slate-grey-6 se-opacity-60", children: [_jsx("span", { className: "se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap se-line-through", children: item.summary }), _jsx("button", { className: "se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-blue-5 se-text-[11px] se-cursor-pointer se-shrink-0 se-leading-none", onClick: (e) => {
289
+ })] })), dismissedItems.length > 0 && (_jsx(DismissedSection, { count: dismissedItems.length, children: dismissedItems.map((item) => (_jsxs("div", { className: "se-flex se-items-center se-gap-2 se-py-1.5 se-px-2.5 se-rounded-md se-border se-border-white/[0.03] se-bg-transparent se-mb-0.5 se-cursor-pointer se-text-xs se-text-slate-grey-6 se-opacity-60", children: [_jsx("span", { className: "se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap se-line-through", children: item.summary }), _jsx("button", { type: "button", className: "se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-blue-5 se-text-[11px] se-cursor-pointer se-shrink-0 se-leading-none", onClick: (e) => {
265
290
  e.stopPropagation();
266
291
  handleRestore(item.key);
267
292
  }, children: "Restore" })] }, item.key))) }))] })) }), _jsx(EditorFooter, { onSave: () => editor.save(), onPublish: handlePublish })] }));
@@ -7,7 +7,7 @@
7
7
  * - executeUpdateFaq: add, remove, reorder, or replace FAQ items
8
8
  */
9
9
  import type { FAQStore } from './state';
10
- import type { ScrollToFaqAction, ToggleFaqItemAction, UpdateFaqAction, ExecutorResult, ExecutorContext } from './types';
10
+ import type { ExecutorContext, ExecutorResult, ScrollToFaqAction, ToggleFaqItemAction, UpdateFaqAction } from './types';
11
11
  /**
12
12
  * Scroll to a FAQ item in the DOM and optionally expand it.
13
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../src/executors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,eAAe,EAEhB,MAAM,SAAS,CAAC;AA4BjB;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAyBzB;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAgCzB;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CA0CzB;AAMD;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;EAItB,CAAC"}
1
+ {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../src/executors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EAChB,MAAM,SAAS,CAAC;AA4BjB;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAyBzB;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CA+BzB;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CA0CzB;AAMD;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;EAItB,CAAC"}
package/dist/executors.js CHANGED
@@ -78,7 +78,6 @@ export async function executeToggleFaqItem(action, context, store) {
78
78
  store.collapse(id);
79
79
  newState = 'closed';
80
80
  break;
81
- case 'toggle':
82
81
  default: {
83
82
  const wasExpanded = store.getState().expandedItems.has(id);
84
83
  store.toggle(id);
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAOlB;;OAEG;;;;;;;;;;;IAGH;;OAEG;;;;;uBAe2npB,CAAC;0BAA8B,CAAC;;;;;;;;;CAH/ppB,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAOlB;;OAEG;;;;;;;;;;;IAGH;;OAEG;;;;;uBAeg/pB,CAAC;0BAA8B,CAAC;;;;;;;;;CAHphqB,CAAC;AAEF,eAAe,OAAO,CAAC"}