@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/CHANGELOG.md +18 -0
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +84 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/SsmlEditor.tsx +8 -0
- package/src/components/VisualSsmlEditor.tsx +87 -2
- package/test/ui-components.test.tsx +28 -0
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__ */
|
|
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__ */
|
|
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
|
|
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(
|