@ssml-builder-js/ssml-editor-react 2.14.0 → 2.16.0

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/dist/index.mjs CHANGED
@@ -5038,6 +5038,40 @@ function VoiceCapabilityMatrix({
5038
5038
  ] })
5039
5039
  ] });
5040
5040
  }
5041
+ function diagnosticMatchesElement(diagnostic, element) {
5042
+ const name = elementLabel(element).toLowerCase().replace("expressas", "mstts:express-as");
5043
+ if (diagnostic.code === "azure-unsupported-style") return name === "mstts:express-as" || name === "express-as";
5044
+ if (diagnostic.code === "azure-unsupported-tag-for-voice") {
5045
+ return diagnostic.message.toLowerCase().includes(`<${name}>`) || diagnostic.message.toLowerCase().includes(`<${name.replace("mstts:", "")}>`);
5046
+ }
5047
+ if (diagnostic.code === "azure-locale-mismatch" || diagnostic.code === "azure-unsupported-model-for-voice")
5048
+ return name === "voice" || name === "mstts:turn";
5049
+ return false;
5050
+ }
5051
+ function elementWarnings(diagnostics, element) {
5052
+ return diagnostics.filter((diagnostic) => diagnosticMatchesElement(diagnostic, element));
5053
+ }
5054
+ function fieldWarnings(diagnostics, element, field) {
5055
+ return elementWarnings(diagnostics, element).filter((diagnostic) => {
5056
+ if (diagnostic.code === "azure-unsupported-style") return field.key === "style";
5057
+ return field.key === "name" || field.key === "voice";
5058
+ });
5059
+ }
5060
+ function WarningBadge({ messages }) {
5061
+ if (messages.length === 0) return null;
5062
+ return /* @__PURE__ */ jsx6(
5063
+ "span",
5064
+ {
5065
+ role: "status",
5066
+ "aria-label": messages.map((message) => message.message).join(" "),
5067
+ title: messages.map((message) => message.message).join(" "),
5068
+ "data-ssml-warning-badge": "",
5069
+ "data-testid": "ssml-editor-warning-badge",
5070
+ className: "ssml-editor-warning-badge",
5071
+ children: "\u26A0"
5072
+ }
5073
+ );
5074
+ }
5041
5075
  function DefaultVoiceSelector({
5042
5076
  value,
5043
5077
  voices,
@@ -5078,7 +5112,8 @@ function VisualElementInspector({
5078
5112
  voiceCatalog,
5079
5113
  voiceLocale,
5080
5114
  voiceRegion,
5081
- voiceStyle
5115
+ voiceStyle,
5116
+ diagnostics
5082
5117
  }) {
5083
5118
  if (customInspector) {
5084
5119
  return /* @__PURE__ */ jsx6(Fragment3, { children: customInspector({ document: document2, element, path, readOnly, onChange: commit, locale }) });
@@ -5090,7 +5125,11 @@ function VisualElementInspector({
5090
5125
  );
5091
5126
  const renderSelector = renderVoiceSelector ?? DefaultVoiceSelector;
5092
5127
  return /* @__PURE__ */ jsxs2("fieldset", { children: [
5093
- /* @__PURE__ */ jsx6("legend", { children: `<${elementLabel(element)}>` }),
5128
+ /* @__PURE__ */ jsxs2("legend", { children: [
5129
+ `<${elementLabel(element)}>`,
5130
+ " ",
5131
+ /* @__PURE__ */ jsx6(WarningBadge, { messages: elementWarnings(diagnostics, element) })
5132
+ ] }),
5094
5133
  fields.length === 0 ? /* @__PURE__ */ jsx6("p", { children: "This element is preserved in the visual tree. Edit its attributes in Code mode." }) : fields.map((field) => {
5095
5134
  const value = element[field.key];
5096
5135
  const inputValue = value === void 0 ? "" : String(value);
@@ -5130,6 +5169,7 @@ function VisualElementInspector({
5130
5169
  url: "\u97F3\u58F0\u5909\u63DB URL",
5131
5170
  profile: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB"
5132
5171
  }[field.key] ?? field.label : field.label,
5172
+ /* @__PURE__ */ jsx6(WarningBadge, { messages: fieldWarnings(diagnostics, element, field) }),
5133
5173
  field.key === "name" && elementLabel(element) === "voice" && voiceCatalog ? renderSelector({
5134
5174
  value: inputValue,
5135
5175
  voices: availableVoices,
@@ -5210,20 +5250,25 @@ function TreeNode({
5210
5250
  node,
5211
5251
  path,
5212
5252
  selectedPath,
5213
- onSelect
5253
+ onSelect,
5254
+ getWarnings
5214
5255
  }) {
5215
5256
  if (!isElement(node)) return null;
5216
5257
  const name = elementLabel(node);
5217
5258
  const isSelected = selectedPath?.join(".") === path.join(".");
5218
5259
  return /* @__PURE__ */ jsxs2("li", { children: [
5219
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path), children: `<${name}>` }),
5260
+ /* @__PURE__ */ jsxs2("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path), children: [
5261
+ `<${name}>`,
5262
+ /* @__PURE__ */ jsx6(WarningBadge, { messages: getWarnings(node) })
5263
+ ] }),
5220
5264
  (node.children ?? []).length > 0 && /* @__PURE__ */ jsx6("ul", { children: node.children?.map((child, index) => /* @__PURE__ */ jsx6(
5221
5265
  TreeNode,
5222
5266
  {
5223
5267
  node: child,
5224
5268
  path: [...path, index],
5225
5269
  selectedPath,
5226
- onSelect
5270
+ onSelect,
5271
+ getWarnings
5227
5272
  },
5228
5273
  `${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`
5229
5274
  )) })
@@ -5240,7 +5285,9 @@ function VisualSsmlEditor({
5240
5285
  voiceCatalog,
5241
5286
  voiceLocale,
5242
5287
  voiceRegion,
5243
- voiceStyle
5288
+ voiceStyle,
5289
+ voiceModel,
5290
+ model
5244
5291
  }) {
5245
5292
  const [selectedPath, setSelectedPath] = useState2(null);
5246
5293
  const [selection, setSelection] = useState2({ start: 0, end: 0 });
@@ -5248,7 +5295,27 @@ function VisualSsmlEditor({
5248
5295
  const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
5249
5296
  const selectedElement = selectedPath ? getNodeAtPath(document2.children ?? [], selectedPath) : void 0;
5250
5297
  const selectedCustomInspector = selectedElement && isElement(selectedElement) ? customInspectors?.[elementLabel(selectedElement)] ?? customInspectors?.[selectedElement.type] : void 0;
5251
- const diagnostics = useMemo(() => validateAzureSsml(buildSsml3(document2)), [document2]);
5298
+ const validationOptions = useMemo(
5299
+ () => ({
5300
+ model: voiceModel ?? model,
5301
+ customVoiceDefinitions: voiceCatalog?.map((voice) => ({
5302
+ name: voice.name,
5303
+ locale: voice.locale,
5304
+ regions: voice.regions ?? (voice.region ? [voice.region] : void 0),
5305
+ styles: voice.styles,
5306
+ supportedTags: voice.supportedTags,
5307
+ unsupportedTags: voice.unsupportedTags,
5308
+ models: voice.models,
5309
+ status: voice.status ?? (voice.preview ? "preview" : "ga")
5310
+ }))
5311
+ }),
5312
+ [model, voiceCatalog, voiceModel]
5313
+ );
5314
+ const diagnostics = useMemo(
5315
+ () => validateAzureSsml(buildSsml3(document2), validationOptions),
5316
+ [document2, validationOptions]
5317
+ );
5318
+ const getWarnings = (element) => elementWarnings(diagnostics, element);
5252
5319
  const commit = (nextDocument) => onChange?.(nextDocument);
5253
5320
  const applyWrapper = (tag, attributes) => {
5254
5321
  if (readOnly || !selectedLeaf) return;
@@ -5277,7 +5344,8 @@ function VisualSsmlEditor({
5277
5344
  node,
5278
5345
  path: [index],
5279
5346
  selectedPath,
5280
- onSelect: setSelectedPath
5347
+ onSelect: setSelectedPath,
5348
+ getWarnings
5281
5349
  },
5282
5350
  isElement(node) ? elementLabel(node) : JSON.stringify(node)
5283
5351
  )) })
@@ -5305,6 +5373,7 @@ function VisualSsmlEditor({
5305
5373
  /* @__PURE__ */ jsx6("legend", { children: localizedElementLabel(selectedElement, locale) }),
5306
5374
  /* @__PURE__ */ jsxs2("label", { htmlFor: "ssml-visual-turn-voice", children: [
5307
5375
  locale === "ja" ? "\u97F3\u58F0" : "Voice",
5376
+ /* @__PURE__ */ jsx6(WarningBadge, { messages: elementWarnings(diagnostics, selectedElement) }),
5308
5377
  voiceCatalog ? (renderVoiceSelector ?? DefaultVoiceSelector)({
5309
5378
  value: selectedElement.voice ?? "",
5310
5379
  voices: filteredVoices(voiceCatalog, voiceLocale, voiceRegion, voiceStyle),
@@ -5410,7 +5479,8 @@ function VisualSsmlEditor({
5410
5479
  voiceCatalog,
5411
5480
  voiceLocale,
5412
5481
  voiceRegion,
5413
- voiceStyle
5482
+ voiceStyle,
5483
+ diagnostics
5414
5484
  }
5415
5485
  ) : selectedLeaf ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
5416
5486
  /* @__PURE__ */ jsxs2("label", { children: [
@@ -6055,6 +6125,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
6055
6125
  voiceLocale,
6056
6126
  voiceRegion,
6057
6127
  voiceStyle,
6128
+ voiceModel,
6129
+ model,
6058
6130
  emotionStyles,
6059
6131
  className,
6060
6132
  style,
@@ -6503,7 +6575,9 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
6503
6575
  voiceCatalog,
6504
6576
  voiceLocale,
6505
6577
  voiceRegion,
6506
- voiceStyle
6578
+ voiceStyle,
6579
+ voiceModel,
6580
+ model
6507
6581
  }
6508
6582
  ) }) : /* @__PURE__ */ jsxs3("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight }, children: [
6509
6583
  /* @__PURE__ */ jsx7(