@syntrologie/runtime-sdk 2.4.0-canary.23 → 2.4.0-canary.25

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.
@@ -20,12 +20,13 @@ import {
20
20
  ScoreStrategyZ,
21
21
  SessionMetricConditionZ,
22
22
  StateEqualsConditionZ,
23
+ TriggerWhenZ,
23
24
  ViewportConditionZ,
24
25
  decisionSchemas,
25
26
  validateActivationConfig,
26
27
  validateCondition,
27
28
  validateStrategy
28
- } from "../chunk-P5G4KT2U.js";
29
+ } from "../chunk-BU4Z6PD7.js";
29
30
  export {
30
31
  ActivationConfigZ,
31
32
  AnchorVisibleConditionZ,
@@ -48,6 +49,7 @@ export {
48
49
  ScoreStrategyZ,
49
50
  SessionMetricConditionZ,
50
51
  StateEqualsConditionZ,
52
+ TriggerWhenZ,
51
53
  ViewportConditionZ,
52
54
  decisionSchemas,
53
55
  validateActivationConfig,
@@ -256,8 +256,8 @@ export interface RouteFilter {
256
256
  export interface ActivationConfig {
257
257
  /** Route-based filtering */
258
258
  routes?: RouteFilter;
259
- /** Decision strategy for conditional rendering */
260
- strategy?: DecisionStrategy<boolean>;
259
+ /** When true, tile is hidden if none of its props.actions[] have an active triggerWhen. Default: false. */
260
+ onlyIfPopulated?: boolean;
261
261
  }
262
262
  /**
263
263
  * Extended context for strategy evaluation.
package/dist/index.js CHANGED
@@ -100,7 +100,7 @@ import {
100
100
  validateAction,
101
101
  validateActions,
102
102
  widgetRegistry
103
- } from "./chunk-FFIHKDHW.js";
103
+ } from "./chunk-2WDY7YGN.js";
104
104
  import {
105
105
  AddClassZ,
106
106
  AnchorIdZ,
@@ -134,8 +134,8 @@ import {
134
134
  WaitZ,
135
135
  WidgetConfigZ,
136
136
  coreActionStepSchemas
137
- } from "./chunk-MCX3AKSH.js";
138
- import "./chunk-5SKKLUOS.js";
137
+ } from "./chunk-YZ27S3HX.js";
138
+ import "./chunk-7OZFA3CQ.js";
139
139
  import {
140
140
  ActivationConfigZ,
141
141
  AnchorVisibleConditionZ,
@@ -158,12 +158,13 @@ import {
158
158
  ScoreStrategyZ,
159
159
  SessionMetricConditionZ,
160
160
  StateEqualsConditionZ,
161
+ TriggerWhenZ,
161
162
  ViewportConditionZ,
162
163
  decisionSchemas,
163
164
  validateActivationConfig,
164
165
  validateCondition,
165
166
  validateStrategy
166
- } from "./chunk-P5G4KT2U.js";
167
+ } from "./chunk-BU4Z6PD7.js";
167
168
 
168
169
  // src/index.ts
169
170
  import React4 from "react";
@@ -659,7 +660,7 @@ function getFeedbackPrompt(feedbackConfig) {
659
660
  }
660
661
  var baseStyles = {
661
662
  container: {
662
- fontFamily: "system-ui, -apple-system, sans-serif",
663
+ fontFamily: "var(--sc-font-family, system-ui, -apple-system, sans-serif)",
663
664
  maxWidth: "800px",
664
665
  margin: "0 auto"
665
666
  },
@@ -672,7 +673,9 @@ var baseStyles = {
672
673
  borderRadius: "8px",
673
674
  fontSize: "14px",
674
675
  outline: "none",
675
- transition: "border-color 0.15s ease"
676
+ transition: "border-color 0.15s ease",
677
+ backgroundColor: "var(--sc-content-search-background)",
678
+ color: "var(--sc-content-search-color)"
676
679
  },
677
680
  accordion: {
678
681
  display: "flex",
@@ -698,8 +701,9 @@ var baseStyles = {
698
701
  transition: "background-color 0.15s ease"
699
702
  },
700
703
  chevron: {
701
- fontSize: "18px",
702
- transition: "transform 0.2s ease"
704
+ fontSize: "20px",
705
+ transition: "transform 0.2s ease",
706
+ color: "var(--sc-content-chevron-color, currentColor)"
703
707
  },
704
708
  answer: {
705
709
  padding: "var(--sc-content-body-padding, 0 16px 12px 16px)",
@@ -766,9 +770,7 @@ var themeStyles = {
766
770
  color: "inherit"
767
771
  },
768
772
  searchInput: {
769
- backgroundColor: slateGrey[12],
770
- border: `1px solid ${slateGrey[11]}`,
771
- color: slateGrey[1]
773
+ border: `1px solid ${slateGrey[11]}`
772
774
  },
773
775
  item: {
774
776
  backgroundColor: "var(--sc-content-background)",
@@ -807,9 +809,7 @@ var themeStyles = {
807
809
  color: "inherit"
808
810
  },
809
811
  searchInput: {
810
- backgroundColor: slateGrey[3],
811
- border: `1px solid ${slateGrey[5]}`,
812
- color: slateGrey[12]
812
+ border: `1px solid ${slateGrey[5]}`
813
813
  },
814
814
  item: {
815
815
  backgroundColor: "var(--sc-content-background)",
@@ -843,7 +843,7 @@ var themeStyles = {
843
843
  }
844
844
  }
845
845
  };
846
- function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
846
+ function FAQItem({ item, isExpanded, isHighlighted, isLast, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
847
847
  const [isHovered, setIsHovered] = useState2(false);
848
848
  const colors = themeStyles[theme];
849
849
  const { question, answer } = item.config;
@@ -854,7 +854,8 @@ function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackCon
854
854
  ...isHighlighted ? {
855
855
  boxShadow: "0 0 0 2px #6366f1, 0 0 12px rgba(99, 102, 241, 0.4)",
856
856
  transition: "box-shadow 0.3s ease"
857
- } : {}
857
+ } : {},
858
+ ...!isLast ? { borderBottom: "var(--sc-content-item-divider, none)" } : {}
858
859
  };
859
860
  const questionStyle = {
860
861
  ...baseStyles.question,
@@ -863,7 +864,7 @@ function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackCon
863
864
  };
864
865
  const chevronStyle = {
865
866
  ...baseStyles.chevron,
866
- transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)"
867
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
867
868
  };
868
869
  const answerStyle = {
869
870
  ...baseStyles.answer,
@@ -875,7 +876,7 @@ function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackCon
875
876
  ...baseStyles.feedback,
876
877
  ...colors.feedbackPrompt
877
878
  };
878
- return _jsxs2("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [_jsxs2("button", { type: "button", style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [_jsx2("span", { children: question }), _jsx2("span", { style: chevronStyle, children: "\u25BC" })] }), _jsxs2("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && _jsxs2("div", { style: feedbackStyle, children: [_jsx2("span", { children: getFeedbackPrompt(feedbackConfig) }), _jsx2("button", { type: "button", style: {
879
+ return _jsxs2("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [_jsxs2("button", { type: "button", style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [_jsx2("span", { children: question }), _jsx2("span", { style: chevronStyle, children: "\u203A" })] }), _jsxs2("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && _jsxs2("div", { style: feedbackStyle, children: [_jsx2("span", { children: getFeedbackPrompt(feedbackConfig) }), _jsx2("button", { type: "button", style: {
879
880
  ...baseStyles.feedbackButton,
880
881
  ...feedbackValue === "up" ? baseStyles.feedbackButtonSelected : {}
881
882
  }, "aria-label": "Thumbs up", onClick: () => onFeedback(item.config.id, question, "up"), children: "\u{1F44D}" }), _jsx2("button", { type: "button", style: {
@@ -1070,11 +1071,11 @@ function FAQWidget({ config, runtime: runtime7, instanceId }) {
1070
1071
  ...baseStyles.categoryHeader,
1071
1072
  ...themeStyles[resolvedTheme].categoryHeader
1072
1073
  };
1073
- const renderItems = (items) => items.map((q) => _jsx2(FAQItem, { item: q, isExpanded: expandedIds.has(q.config.id), isHighlighted: highlightId === q.config.id, onToggle: () => handleToggle(q.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q.config.id), onFeedback: handleFeedback }, q.config.id));
1074
+ const renderItems = (items) => items.map((q, index) => _jsx2(FAQItem, { item: q, isExpanded: expandedIds.has(q.config.id), isHighlighted: highlightId === q.config.id, isLast: index === items.length - 1, onToggle: () => handleToggle(q.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q.config.id), onFeedback: handleFeedback }, q.config.id));
1074
1075
  if (visibleQuestions.length === 0) {
1075
- return _jsx2("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: _jsx2("div", { style: emptyStateStyle, children: "No FAQ questions available." }) });
1076
+ return _jsx2("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: _jsx2("div", { style: emptyStateStyle, children: "You're all set for now! We'll surface answers here when they're relevant to what you're doing." }) });
1076
1077
  }
1077
- return _jsxs2("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: [config.searchable && _jsx2("div", { style: baseStyles.searchWrapper, children: _jsx2("input", { type: "text", placeholder: "Search questions...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: searchInputStyle }) }), _jsx2("div", { style: baseStyles.accordion, children: hasCategories ? Array.from(categoryGroups.entries()).map(([category, items]) => _jsxs2(React2.Fragment, { children: [category && _jsx2("div", { style: categoryHeaderStyle, "data-category-header": category, children: category }), renderItems(items)] }, category != null ? category : "__ungrouped")) : renderItems(filteredQuestions) }), config.searchable && filteredQuestions.length === 0 && searchQuery && _jsxs2("div", { style: { ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }, children: ['No questions found matching "', searchQuery, '"'] })] });
1078
+ return _jsxs2("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: [config.searchable && _jsxs2("div", { style: baseStyles.searchWrapper, children: [_jsx2("style", { children: `[data-adaptive-id="${instanceId}"] input::placeholder { color: var(--sc-content-search-color, inherit); opacity: 0.7; }` }), _jsx2("input", { type: "text", placeholder: "Search questions...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: searchInputStyle })] }), _jsx2("div", { style: baseStyles.accordion, children: hasCategories ? Array.from(categoryGroups.entries()).map(([category, items]) => _jsxs2(React2.Fragment, { children: [category && _jsx2("div", { style: categoryHeaderStyle, "data-category-header": category, children: category }), renderItems(items)] }, category != null ? category : "__ungrouped")) : renderItems(filteredQuestions) }), config.searchable && filteredQuestions.length === 0 && searchQuery && _jsxs2("div", { style: { ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }, children: ['No questions found matching "', searchQuery, '"'] })] });
1078
1079
  }
1079
1080
  var FAQMountableWidget = {
1080
1081
  mount(container, config) {
@@ -1132,7 +1133,8 @@ var runtime4 = {
1132
1133
  metadata: {
1133
1134
  name: "FAQ Accordion",
1134
1135
  description: "Collapsible Q&A accordion with search, categories, and feedback",
1135
- icon: "\u2753"
1136
+ icon: "\u2753",
1137
+ subtitle: "Curated just for you."
1136
1138
  }
1137
1139
  }
1138
1140
  ],
@@ -1504,7 +1506,7 @@ function NavWidget({ config, runtime: runtime7, instanceId }) {
1504
1506
  };
1505
1507
  const renderItems = (items) => items.map((tip, index) => _jsx3(NavTipItem, { item: tip, isExpanded: expandedIds.has(tip.config.id), isLast: index === items.length - 1, onToggle: () => handleToggle(tip.config.id), onNavigate: handleNavigate, theme: resolvedTheme }, tip.config.id));
1506
1508
  if (visibleTips.length === 0) {
1507
- return _jsx3("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: _jsx3("div", { style: emptyStateStyle, children: "No navigation tips available." }) });
1509
+ return _jsx3("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: _jsx3("div", { style: emptyStateStyle, children: "You're all set for now! We'll share helpful tips here when they're relevant to what you're doing." }) });
1508
1510
  }
1509
1511
  return _jsx3("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: _jsx3("div", { style: baseStyles2.accordion, children: hasCategories ? Array.from(categoryGroups.entries()).map(([category, items]) => _jsxs3(React3.Fragment, { children: [category && _jsx3("div", { style: categoryHeaderStyle, "data-category-header": category, children: category }), renderItems(items)] }, category != null ? category : "__ungrouped")) : renderItems(visibleTips) }) });
1510
1512
  }
@@ -1831,18 +1833,7 @@ function migrateV1ToV2(config) {
1831
1833
  if (config.tiles && Array.isArray(config.tiles)) {
1832
1834
  migrated.tiles = config.tiles.map((tile) => {
1833
1835
  const migratedTile = { ...tile };
1834
- if (tile.experiment && !tile.activation) {
1835
- const exp = tile.experiment;
1836
- if (exp.featureKey) {
1837
- migratedTile.activation = {
1838
- strategy: {
1839
- type: "external",
1840
- provider: "growthbook",
1841
- featureKey: exp.featureKey,
1842
- fallback: false
1843
- }
1844
- };
1845
- }
1836
+ if (tile.experiment) {
1846
1837
  delete migratedTile.experiment;
1847
1838
  }
1848
1839
  return migratedTile;
@@ -2150,6 +2141,7 @@ export {
2150
2141
  TooltipZ,
2151
2142
  TourStepForSchemaZ,
2152
2143
  TourZ,
2144
+ TriggerWhenZ,
2153
2145
  ViewportConditionZ,
2154
2146
  ViewportContextZ,
2155
2147
  WaitZ,