@syntrologie/adapt-faq 0.0.0-semantically-released → 2.0.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0DxB;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;QAG1B,0CAA0C;;QAE1C,wBAAwB;;QAExB,gDAAgD;;QAEhD,qCAAqC;;;;;;;;;;;;;IAGvC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAExD,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAMtE;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB,qEAAqE;;IAErE,4CAA4C;;IAE5C,kBAAkB;;IAElB,4CAA4C;;;;YA7B1C,0CAA0C;;YAE1C,wBAAwB;;YAExB,gDAAgD;;YAEhD,qCAAqC;;;;;;;;;;;;;QAGvC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsBxD,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAMrD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAEhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAE9C"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -50,6 +50,71 @@ const DecisionStrategyZ = z.discriminatedUnion('type', [
50
50
  ExternalStrategyZ,
51
51
  ]);
52
52
  // ============================================================================
53
+ // Rich Answer Content Schemas
54
+ // ============================================================================
55
+ /** Schema for media assets embedded in enhanced markdown answers. */
56
+ const AssetZ = z.object({
57
+ id: z.string(),
58
+ type: z.enum(['image', 'video']),
59
+ src: z.string(),
60
+ alt: z.string().optional(),
61
+ width: z.number().optional(),
62
+ height: z.number().optional(),
63
+ });
64
+ /** Schema for rich HTML answer content. */
65
+ const RichHTMLAnswerZ = z.object({
66
+ type: z.literal('rich'),
67
+ html: z.string(),
68
+ });
69
+ /** Schema for enhanced markdown answer content with optional assets. */
70
+ const EnhancedMarkdownAnswerZ = z.object({
71
+ type: z.literal('markdown'),
72
+ content: z.string(),
73
+ assets: z.array(AssetZ).optional(),
74
+ });
75
+ /** Union of all FAQ answer types: plain string, rich HTML, or enhanced markdown. */
76
+ const FAQAnswerZ = z.union([z.string(), RichHTMLAnswerZ, EnhancedMarkdownAnswerZ]);
77
+ // ============================================================================
78
+ // Feedback Schemas
79
+ // ============================================================================
80
+ /** Schema for feedback widget configuration. */
81
+ const FeedbackConfigZ = z.object({
82
+ style: z.enum(['thumbs', 'rating']),
83
+ prompt: z.string().optional(),
84
+ });
85
+ /** Feedback can be a boolean (enable/disable) or a detailed config object. */
86
+ const FeedbackZ = z.union([z.boolean(), FeedbackConfigZ]);
87
+ // ============================================================================
88
+ // Ordering Schemas
89
+ // ============================================================================
90
+ /** Schema for segment-based ordering strategy. */
91
+ const SegmentOrderingZ = z.object({
92
+ type: z.literal('segment'),
93
+ segmentWeights: z.record(z.array(z.string())),
94
+ });
95
+ /** Ordering strategy: static order, priority-based, or segment-based. */
96
+ const OrderingStrategyZ = z.union([z.enum(['static', 'priority']), SegmentOrderingZ]);
97
+ // ============================================================================
98
+ // AI Answer Strategy Schema
99
+ // ============================================================================
100
+ /** Schema for AI-generated answer configuration. */
101
+ const AnswerStrategyZ = z.object({
102
+ endpoint: z.string().min(1),
103
+ context: z.array(z.string()).optional(),
104
+ cache: z.enum(['session', 'none']).optional(),
105
+ fallback: z.string().optional(),
106
+ });
107
+ // ============================================================================
108
+ // Injection Rule Schema
109
+ // ============================================================================
110
+ /** Schema for dynamic FAQ injection rules. */
111
+ const InjectionRuleZ = z.object({
112
+ trigger: DecisionStrategyZ,
113
+ items: z.array(z.lazy(() => FAQQuestionSchema)),
114
+ position: z.enum(['prepend', 'append']).optional(),
115
+ once: z.boolean().optional(),
116
+ });
117
+ // ============================================================================
53
118
  // FAQ Question Schema
54
119
  // ============================================================================
55
120
  /**
@@ -62,10 +127,14 @@ export const FAQQuestionSchema = z.object({
62
127
  id: z.string().min(1, 'ID is required'),
63
128
  /** The question text */
64
129
  question: z.string().min(1, 'Question is required'),
65
- /** The answer text (supports basic markdown) */
66
- answer: z.string().min(1, 'Answer is required'),
130
+ /** The answer content (plain string, rich HTML, or enhanced markdown) */
131
+ answer: FAQAnswerZ,
67
132
  /** Optional category for grouping */
68
133
  category: z.string().optional(),
134
+ /** Optional priority for ordering */
135
+ priority: z.number().optional(),
136
+ /** Optional AI answer generation strategy */
137
+ answerStrategy: AnswerStrategyZ.optional(),
69
138
  }),
70
139
  /** Per-item activation strategy (null = always show) */
71
140
  showWhen: DecisionStrategyZ.nullable().optional(),
@@ -85,6 +154,56 @@ export const configSchema = z.object({
85
154
  theme: z.enum(['light', 'dark', 'auto']).default('auto'),
86
155
  /** FAQ questions (compositional actions) */
87
156
  actions: z.array(FAQQuestionSchema).default([]),
157
+ /** Feedback widget configuration */
158
+ feedback: FeedbackZ.optional(),
159
+ /** Question ordering strategy */
160
+ ordering: OrderingStrategyZ.optional(),
161
+ /** Dynamic FAQ injection rules */
162
+ injections: z.array(InjectionRuleZ).optional(),
163
+ });
164
+ // ============================================================================
165
+ // Executor Action Schemas
166
+ // ============================================================================
167
+ /**
168
+ * Schema for scrolling to a specific FAQ item.
169
+ * Requires either itemId or itemQuestion to identify the target.
170
+ */
171
+ export const ScrollToFaqSchema = z
172
+ .object({
173
+ kind: z.literal('faq:scroll_to'),
174
+ itemId: z.string().optional(),
175
+ itemQuestion: z.string().optional(),
176
+ expand: z.boolean().optional(),
177
+ behavior: z.enum(['smooth', 'instant', 'auto']).optional(),
178
+ })
179
+ .refine((data) => data.itemId || data.itemQuestion, {
180
+ message: 'Either itemId or itemQuestion is required',
181
+ });
182
+ /**
183
+ * Schema for toggling a FAQ item open/closed.
184
+ * Requires either itemId or itemQuestion to identify the target.
185
+ */
186
+ export const ToggleFaqItemSchema = z
187
+ .object({
188
+ kind: z.literal('faq:toggle_item'),
189
+ itemId: z.string().optional(),
190
+ itemQuestion: z.string().optional(),
191
+ state: z.enum(['open', 'closed', 'toggle']).default('toggle'),
192
+ })
193
+ .refine((data) => data.itemId || data.itemQuestion, {
194
+ message: 'Either itemId or itemQuestion is required',
195
+ });
196
+ /**
197
+ * Schema for updating FAQ items (add, remove, reorder, replace).
198
+ */
199
+ export const UpdateFaqSchema = z.object({
200
+ kind: z.literal('faq:update'),
201
+ operation: z.enum(['add', 'remove', 'reorder', 'replace']),
202
+ items: z.array(FAQQuestionSchema).optional(),
203
+ itemId: z.string().optional(),
204
+ order: z.array(z.string()).optional(),
205
+ position: z.enum(['prepend', 'append', 'before', 'after']).optional(),
206
+ anchorId: z.string().optional(),
88
207
  });
89
208
  // ============================================================================
90
209
  // Validation Helpers
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Adaptive FAQ - Shared Widget State Store
3
+ *
4
+ * Lightweight reactive store that executors and the widget both read/write.
5
+ * Implements an observer pattern so UI components can subscribe to changes.
6
+ */
7
+ import type { FAQQuestionAction, FAQWidgetState, FeedbackValue } from './types';
8
+ type Listener = (state: FAQWidgetState) => void;
9
+ type Unsubscribe = () => void;
10
+ export interface FAQStore {
11
+ /** Return a snapshot of the current state. */
12
+ getState(): FAQWidgetState;
13
+ expand(itemId: string): void;
14
+ collapse(itemId: string): void;
15
+ toggle(itemId: string): void;
16
+ addItems(items: FAQQuestionAction[], position: 'prepend' | 'append'): void;
17
+ removeItem(itemId: string): void;
18
+ reorderItems(order: string[]): void;
19
+ replaceItems(items: FAQQuestionAction[]): void;
20
+ setFeedback(itemId: string, value: FeedbackValue): void;
21
+ setSearchQuery(query: string): void;
22
+ toggleCategory(category: string): void;
23
+ findByQuestion(text: string): FAQQuestionAction | null;
24
+ subscribe(listener: Listener): Unsubscribe;
25
+ }
26
+ export declare function createFAQStore(initialItems: FAQQuestionAction[]): FAQStore;
27
+ export {};
28
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMhF,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAChD,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAM9B,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,QAAQ,IAAI,cAAc,CAAC;IAG3B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAG7B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAG/C,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAGxD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAGpC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAAC;IAGvD,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;CAC5C;AAMD,wBAAgB,cAAc,CAAC,YAAY,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CA6I1E"}
package/dist/state.js ADDED
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Adaptive FAQ - Shared Widget State Store
3
+ *
4
+ * Lightweight reactive store that executors and the widget both read/write.
5
+ * Implements an observer pattern so UI components can subscribe to changes.
6
+ */
7
+ // ============================================================================
8
+ // Factory
9
+ // ============================================================================
10
+ export function createFAQStore(initialItems) {
11
+ // Internal mutable state ---------------------------------------------------
12
+ let state = {
13
+ expandedItems: new Set(),
14
+ items: [...initialItems],
15
+ searchQuery: '',
16
+ collapsedCategories: new Set(),
17
+ feedbackState: new Map(),
18
+ };
19
+ const listeners = new Set();
20
+ // Notify all subscribers with the current state snapshot -------------------
21
+ function notify() {
22
+ for (const listener of listeners) {
23
+ listener(state);
24
+ }
25
+ }
26
+ // Helpers to produce new state objects (immutable from the outside) --------
27
+ function setState(patch) {
28
+ state = { ...state, ...patch };
29
+ notify();
30
+ }
31
+ // --- Public API -----------------------------------------------------------
32
+ function getState() {
33
+ return state;
34
+ }
35
+ function expand(itemId) {
36
+ const next = new Set(state.expandedItems);
37
+ next.add(itemId);
38
+ setState({ expandedItems: next });
39
+ }
40
+ function collapse(itemId) {
41
+ const next = new Set(state.expandedItems);
42
+ next.delete(itemId);
43
+ setState({ expandedItems: next });
44
+ }
45
+ function toggle(itemId) {
46
+ if (state.expandedItems.has(itemId)) {
47
+ collapse(itemId);
48
+ }
49
+ else {
50
+ expand(itemId);
51
+ }
52
+ }
53
+ function addItems(items, position) {
54
+ const next = position === 'prepend' ? [...items, ...state.items] : [...state.items, ...items];
55
+ setState({ items: next });
56
+ }
57
+ function removeItem(itemId) {
58
+ setState({
59
+ items: state.items.filter((i) => i.config.id !== itemId),
60
+ });
61
+ }
62
+ function reorderItems(order) {
63
+ const orderSet = new Set(order);
64
+ const itemMap = new Map(state.items.map((i) => [i.config.id, i]));
65
+ // Place items in the specified order first
66
+ const ordered = [];
67
+ for (const id of order) {
68
+ const item = itemMap.get(id);
69
+ if (item) {
70
+ ordered.push(item);
71
+ }
72
+ }
73
+ // Append any items that were not listed in the order array
74
+ for (const item of state.items) {
75
+ if (!orderSet.has(item.config.id)) {
76
+ ordered.push(item);
77
+ }
78
+ }
79
+ setState({ items: ordered });
80
+ }
81
+ function replaceItems(items) {
82
+ setState({ items: [...items] });
83
+ }
84
+ function setFeedback(itemId, value) {
85
+ const next = new Map(state.feedbackState);
86
+ next.set(itemId, value);
87
+ setState({ feedbackState: next });
88
+ }
89
+ function setSearchQuery(query) {
90
+ setState({ searchQuery: query });
91
+ }
92
+ function toggleCategory(category) {
93
+ const next = new Set(state.collapsedCategories);
94
+ if (next.has(category)) {
95
+ next.delete(category);
96
+ }
97
+ else {
98
+ next.add(category);
99
+ }
100
+ setState({ collapsedCategories: next });
101
+ }
102
+ function findByQuestion(text) {
103
+ const needle = text.toLowerCase();
104
+ for (const item of state.items) {
105
+ if (item.config.question.toLowerCase().includes(needle)) {
106
+ return item;
107
+ }
108
+ }
109
+ return null;
110
+ }
111
+ function subscribe(listener) {
112
+ listeners.add(listener);
113
+ return () => {
114
+ listeners.delete(listener);
115
+ };
116
+ }
117
+ return {
118
+ getState,
119
+ expand,
120
+ collapse,
121
+ toggle,
122
+ addItems,
123
+ removeItem,
124
+ reorderItems,
125
+ replaceItems,
126
+ setFeedback,
127
+ setSearchQuery,
128
+ toggleCategory,
129
+ findByQuestion,
130
+ subscribe,
131
+ };
132
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Human-readable summary generation for FAQ items.
3
+ * Pure functions — no DOM access, just string formatting.
4
+ */
5
+ import type { FAQQuestionAction, DecisionStrategy } from './types';
6
+ /**
7
+ * Parse a showWhen strategy into a human-readable trigger description.
8
+ */
9
+ export declare function describeTrigger(showWhen?: DecisionStrategy<boolean> | null): string;
10
+ /**
11
+ * Generate a one-liner summary for an FAQ item.
12
+ */
13
+ export declare function summarizeFAQItem(item: FAQQuestionAction): string;
14
+ //# sourceMappingURL=summarize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAa,gBAAgB,EAAgB,MAAM,SAAS,CAAC;AA6B5F;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,CAuBnF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAIhE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Human-readable summary generation for FAQ items.
3
+ * Pure functions — no DOM access, just string formatting.
4
+ */
5
+ const MAX_Q_LEN = 50;
6
+ const MAX_A_LEN = 40;
7
+ function truncate(text, max) {
8
+ if (text.length <= max)
9
+ return text;
10
+ return `${text.slice(0, max).trimEnd()}...`;
11
+ }
12
+ function stripHtml(html) {
13
+ return html.replace(/<[^>]*>/g, '').trim();
14
+ }
15
+ function getAnswerPreview(answer) {
16
+ if (typeof answer === 'string')
17
+ return answer;
18
+ if (answer.type === 'rich')
19
+ return stripHtml(answer.html);
20
+ return answer.content.replace(/[*_#`]/g, '').trim();
21
+ }
22
+ function isRuleStrategy(s) {
23
+ return (typeof s === 'object' &&
24
+ s !== null &&
25
+ s.type === 'rules' &&
26
+ Array.isArray(s.rules));
27
+ }
28
+ /**
29
+ * Parse a showWhen strategy into a human-readable trigger description.
30
+ */
31
+ export function describeTrigger(showWhen) {
32
+ if (!showWhen)
33
+ return 'All pages';
34
+ if (!isRuleStrategy(showWhen))
35
+ return 'All pages';
36
+ const pages = [];
37
+ const anchors = [];
38
+ for (const rule of showWhen.rules) {
39
+ for (const condition of rule.conditions) {
40
+ if (condition.type === 'page_url' && typeof condition.url === 'string') {
41
+ pages.push(condition.url);
42
+ }
43
+ if (condition.type === 'anchor_visible' && typeof condition.anchorId === 'string') {
44
+ anchors.push(condition.anchorId);
45
+ }
46
+ }
47
+ }
48
+ const parts = [];
49
+ if (pages.length > 0)
50
+ parts.push(pages[0]);
51
+ if (anchors.length > 0)
52
+ parts.push(anchors[0]);
53
+ return parts.length > 0 ? parts.join(' \u00b7 ') : 'All pages';
54
+ }
55
+ /**
56
+ * Generate a one-liner summary for an FAQ item.
57
+ */
58
+ export function summarizeFAQItem(item) {
59
+ const q = truncate(item.config.question, MAX_Q_LEN);
60
+ const a = truncate(getAnswerPreview(item.config.answer), MAX_A_LEN);
61
+ return `Q: "${q}" \u2014 ${a}`;
62
+ }
package/dist/types.d.ts CHANGED
@@ -38,82 +38,124 @@ export interface ExternalStrategy<T = unknown> {
38
38
  default: T;
39
39
  timeoutMs?: number;
40
40
  }
41
- /**
42
- * Single FAQ question configuration.
43
- * This is a "compositional action" - it's not executed, but rendered by the parent.
44
- */
41
+ export interface Asset {
42
+ id: string;
43
+ type: 'image' | 'video';
44
+ src: string;
45
+ alt?: string;
46
+ width?: number;
47
+ height?: number;
48
+ }
49
+ export interface RichHTMLAnswer {
50
+ type: 'rich';
51
+ html: string;
52
+ }
53
+ export interface EnhancedMarkdownAnswer {
54
+ type: 'markdown';
55
+ content: string;
56
+ assets?: Asset[];
57
+ }
58
+ export type FAQAnswer = string | RichHTMLAnswer | EnhancedMarkdownAnswer;
59
+ export interface AnswerStrategy {
60
+ endpoint: string;
61
+ context?: string[];
62
+ cache?: 'session' | 'none';
63
+ fallback?: string;
64
+ }
65
+ export interface FeedbackConfig {
66
+ style: 'thumbs' | 'rating';
67
+ prompt?: string;
68
+ }
69
+ export type FeedbackValue = 'up' | 'down' | number;
70
+ export interface SegmentOrdering {
71
+ type: 'segment';
72
+ segmentWeights: Record<string, string[]>;
73
+ }
74
+ export type OrderingStrategy = 'static' | 'priority' | SegmentOrdering;
75
+ export interface InjectionRule {
76
+ trigger: DecisionStrategy<boolean>;
77
+ items: FAQQuestionAction[];
78
+ position?: 'prepend' | 'append';
79
+ once?: boolean;
80
+ }
45
81
  export interface FAQQuestionAction {
46
- /** Action kind identifier */
47
82
  kind: 'faq:question';
48
- /** Question configuration */
49
83
  config: {
50
- /** Unique identifier for this question */
51
84
  id: string;
52
- /** The question text */
53
85
  question: string;
54
- /** The answer text (supports basic markdown) */
55
- answer: string;
56
- /** Optional category for grouping */
86
+ answer: FAQAnswer;
57
87
  category?: string;
88
+ priority?: number;
89
+ answerStrategy?: AnswerStrategy;
58
90
  };
59
- /** Optional per-item activation strategy */
60
91
  showWhen?: DecisionStrategy<boolean> | null;
92
+ rationale?: {
93
+ why: string;
94
+ confidence?: number;
95
+ };
61
96
  }
62
- /**
63
- * Expand behavior for the accordion.
64
- */
65
97
  export type ExpandBehavior = 'single' | 'multiple';
66
- /**
67
- * Theme for the FAQ widget.
68
- */
69
98
  export type FAQTheme = 'light' | 'dark' | 'auto';
70
- /**
71
- * Full configuration for the adaptive-faq widget.
72
- */
73
99
  export interface FAQConfig {
74
- /** Whether only one or multiple questions can be expanded at once */
75
100
  expandBehavior: ExpandBehavior;
76
- /** Whether to show a search/filter input */
77
101
  searchable: boolean;
78
- /** Color theme */
79
102
  theme: FAQTheme;
80
- /** FAQ questions (compositional actions) */
81
103
  actions: FAQQuestionAction[];
104
+ feedback?: boolean | FeedbackConfig;
105
+ ordering?: OrderingStrategy;
106
+ injections?: InjectionRule[];
82
107
  }
83
- /**
84
- * Runtime services passed to the widget.
85
- */
86
- export interface FAQWidgetRuntime {
87
- /** Synchronously evaluate a decision strategy */
88
- evaluateSync: <T>(strategy: DecisionStrategy<T>) => {
89
- value: T;
90
- isFallback: boolean;
91
- };
92
- /** Context manager for subscribing to changes */
93
- context: {
94
- subscribe: (callback: () => void) => () => void;
95
- };
96
- /** Event bus for publishing interactions */
97
- events: {
98
- publish: (name: string, props?: Record<string, unknown>) => void;
99
- };
100
- /** Scoped state store */
101
- state?: {
102
- get: (key: string) => unknown;
103
- set: (key: string, value: unknown) => void;
104
- };
108
+ export interface ScrollToFaqAction {
109
+ kind: 'faq:scroll_to';
110
+ itemId?: string;
111
+ itemQuestion?: string;
112
+ expand?: boolean;
113
+ behavior?: 'smooth' | 'instant' | 'auto';
114
+ }
115
+ export interface ToggleFaqItemAction {
116
+ kind: 'faq:toggle_item';
117
+ itemId?: string;
118
+ itemQuestion?: string;
119
+ state?: 'open' | 'closed' | 'toggle';
120
+ }
121
+ export interface UpdateFaqAction {
122
+ kind: 'faq:update';
123
+ operation: 'add' | 'remove' | 'reorder' | 'replace';
124
+ items?: FAQQuestionAction[];
125
+ itemId?: string;
126
+ order?: string[];
127
+ position?: 'prepend' | 'append' | 'before' | 'after';
128
+ anchorId?: string;
129
+ }
130
+ export interface FAQWidgetState {
131
+ expandedItems: Set<string>;
132
+ items: FAQQuestionAction[];
133
+ searchQuery: string;
134
+ collapsedCategories: Set<string>;
135
+ feedbackState: Map<string, FeedbackValue>;
105
136
  }
137
+ export type ExecutorCleanup = () => void;
138
+ export type ExecutorUpdate = (action: unknown) => Promise<void>;
139
+ export interface ExecutorResult {
140
+ cleanup: ExecutorCleanup;
141
+ updateFn?: ExecutorUpdate;
142
+ }
143
+ export interface ExecutorContext {
144
+ overlayRoot: HTMLElement;
145
+ resolveAnchor: (anchorId: string) => HTMLElement | null;
146
+ generateId: () => string;
147
+ publishEvent: (name: string, props?: Record<string, unknown>) => void;
148
+ adaptiveId?: string;
149
+ }
150
+ export type ActionExecutor<T> = (action: T, context: ExecutorContext) => Promise<ExecutorResult>;
151
+ export declare const ACTION_NAMESPACE = "faq";
106
152
  /**
107
- * Props passed to the FAQWidget component.
153
+ * Returns true if the action belongs to this adaptive package.
154
+ * Uses prefix matching so new kinds (e.g. faq:category) are automatically included.
108
155
  */
109
- export interface FAQWidgetProps {
110
- /** Widget configuration */
111
- config: FAQConfig;
112
- /** Runtime services */
113
- runtime: FAQWidgetRuntime;
114
- /** Instance ID for telemetry */
115
- instanceId: string;
116
- }
156
+ export declare function isOwnAction(action: {
157
+ kind: string;
158
+ }): boolean;
117
159
  export interface EditorPanelProps {
118
160
  config: Record<string, unknown>;
119
161
  onChange: (config: Record<string, unknown>) => void;
@@ -122,6 +164,17 @@ export interface EditorPanelProps {
122
164
  navigateHome: () => Promise<boolean>;
123
165
  save: () => Promise<void>;
124
166
  publish: (captureScreenshot?: boolean) => Promise<void>;
167
+ navigateTo: (route: string) => Promise<void>;
168
+ highlightElement: (selector: string) => void;
169
+ clearHighlight: () => void;
170
+ getCurrentRoute: () => string;
171
+ previewConfig: (config: Record<string, unknown>) => void;
172
+ /** Flat action index to open in edit mode (from accordion navigation). */
173
+ initialEditKey?: string;
174
+ /** Open the editor in create mode. */
175
+ initialCreate?: boolean;
176
+ /** Clear the initial navigation state (call after consuming). */
177
+ clearInitialState?: () => void;
125
178
  };
126
179
  platformClient?: unknown;
127
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -4,4 +4,14 @@
4
4
  * Type definitions for the FAQ accordion adaptive.
5
5
  * Demonstrates compositional action pattern with per-item showWhen.
6
6
  */
7
- export {};
7
+ // ============================================================================
8
+ // Action Namespace
9
+ // ============================================================================
10
+ export const ACTION_NAMESPACE = 'faq';
11
+ /**
12
+ * Returns true if the action belongs to this adaptive package.
13
+ * Uses prefix matching so new kinds (e.g. faq:category) are automatically included.
14
+ */
15
+ export function isOwnAction(action) {
16
+ return action.kind.startsWith(`${ACTION_NAMESPACE}:`);
17
+ }