testomatio-editor-blocks 0.4.11 → 0.4.12
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/package/editor/blocks/snippet.js +10 -7
- package/package/styles.css +35 -8
- package/package.json +1 -1
- package/src/editor/blocks/snippet.tsx +44 -31
- package/src/editor/styles.css +35 -8
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { createReactBlockSpec } from "@blocknote/react";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { useSnippetAutocomplete } from "../snippetAutocomplete";
|
|
5
|
-
function SnippetDropdown({ value, placeholder, suggestions, onSelect }) {
|
|
5
|
+
function SnippetDropdown({ value, placeholder, suggestions, selectedId, onSelect }) {
|
|
6
6
|
const [isOpen, setIsOpen] = useState(false);
|
|
7
7
|
const [search, setSearch] = useState("");
|
|
8
8
|
const containerRef = useRef(null);
|
|
@@ -34,11 +34,14 @@ function SnippetDropdown({ value, placeholder, suggestions, onSelect }) {
|
|
|
34
34
|
const handleSearchChange = useCallback((event) => {
|
|
35
35
|
setSearch(event.target.value);
|
|
36
36
|
}, []);
|
|
37
|
-
return (_jsxs("div", { className: "bn-snippet-dropdown", ref: containerRef, children: [_jsxs("button", { type: "button", className: "bn-snippet-dropdown__trigger", onClick: () => setIsOpen((prev) => !prev), children: [_jsx("span", { className: "bn-snippet-dropdown__text", children: value || placeholder }), _jsx("svg", { className: "bn-snippet-dropdown__chevron", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), isOpen && (_jsxs("div", { className: "bn-snippet-dropdown__panel", role: "listbox", children: [_jsxs("div", { className: "bn-snippet-dropdown__search", children: [_jsx("svg", { className: "bn-snippet-dropdown__search-icon", width: "
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
return (_jsxs("div", { className: "bn-snippet-dropdown", ref: containerRef, children: [_jsxs("button", { type: "button", className: "bn-snippet-dropdown__trigger", onClick: () => setIsOpen((prev) => !prev), children: [_jsx("span", { className: "bn-snippet-dropdown__text", children: value || placeholder }), _jsx("svg", { className: "bn-snippet-dropdown__chevron", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), isOpen && (_jsxs("div", { className: "bn-snippet-dropdown__panel", role: "listbox", children: [_jsx("div", { className: "bn-snippet-dropdown__search-wrapper", children: _jsxs("div", { className: "bn-snippet-dropdown__search", children: [_jsx("svg", { className: "bn-snippet-dropdown__search-icon", width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M12.917 11.667h-.659l-.233-.225a5.417 5.417 0 0 0 1.308-3.525 5.417 5.417 0 1 0-5.416 5.416 5.417 5.417 0 0 0 3.525-1.308l.225.233v.659l4.166 4.158 1.242-1.242-4.158-4.166Zm-5 0a3.745 3.745 0 0 1-3.75-3.75 3.745 3.745 0 0 1 3.75-3.75 3.745 3.745 0 0 1 3.75 3.75 3.745 3.745 0 0 1-3.75 3.75Z", fill: "currentColor" }) }), _jsx("input", { ref: searchRef, type: "text", className: "bn-snippet-dropdown__search-input", placeholder: "Search", value: search, onChange: handleSearchChange })] }) }), _jsxs("div", { className: "bn-snippet-dropdown__list", children: [filtered.map((suggestion) => {
|
|
38
|
+
const isSelected = suggestion.id === selectedId;
|
|
39
|
+
return (_jsxs("button", { type: "button", role: "option", "aria-selected": isSelected, className: `bn-snippet-dropdown__item${isSelected ? " bn-snippet-dropdown__item--selected" : ""}`, onMouseDown: (event) => {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
onSelect(suggestion);
|
|
42
|
+
setIsOpen(false);
|
|
43
|
+
}, tabIndex: -1, children: [_jsx("span", { className: "bn-snippet-dropdown__item-title", children: suggestion.title }), isSelected && (_jsx("svg", { className: "bn-snippet-dropdown__item-check", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17Z", fill: "currentColor" }) }))] }, suggestion.id));
|
|
44
|
+
}), filtered.length === 0 && (_jsx("div", { className: "bn-snippet-dropdown__empty", children: "No snippets found" }))] })] }))] }));
|
|
42
45
|
}
|
|
43
46
|
export const snippetBlock = createReactBlockSpec({
|
|
44
47
|
type: "snippet",
|
|
@@ -99,6 +102,6 @@ export const snippetBlock = createReactBlockSpec({
|
|
|
99
102
|
if (!hasSnippets) {
|
|
100
103
|
return (_jsx("div", { className: "bn-teststep bn-snippet", "data-block-id": block.id, children: _jsx("p", { className: "bn-snippet__empty", children: "No snippets in this project." }) }));
|
|
101
104
|
}
|
|
102
|
-
return (_jsxs("div", { className: "bn-teststep bn-snippet", "data-block-id": block.id, onFocus: handleFieldFocus, children: [_jsxs("div", { className: "bn-snippet__header", children: [_jsx("span", { className: "bn-snippet__label", children: "Snippet" }), _jsx(SnippetDropdown, { value: snippetTitle, placeholder: "Select Snippet", suggestions: snippetSuggestions, onSelect: handleSnippetSelect })] }), isSnippetSelected && (_jsx("div", { className: "bn-snippet__content",
|
|
105
|
+
return (_jsxs("div", { className: "bn-teststep bn-snippet", "data-block-id": block.id, onFocus: handleFieldFocus, children: [_jsxs("div", { className: "bn-snippet__header", children: [_jsx("span", { className: "bn-snippet__label", children: "Snippet" }), _jsx(SnippetDropdown, { value: snippetTitle, placeholder: "Select Snippet", suggestions: snippetSuggestions, selectedId: snippetId, onSelect: handleSnippetSelect })] }), isSnippetSelected && snippetData && (_jsx("div", { className: "bn-snippet__content", dangerouslySetInnerHTML: { __html: snippetData } }))] }));
|
|
103
106
|
},
|
|
104
107
|
});
|
package/package/styles.css
CHANGED
|
@@ -224,6 +224,10 @@ html.dark .bn-snippet-dropdown__panel {
|
|
|
224
224
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
html.dark .bn-snippet-dropdown__search-wrapper {
|
|
228
|
+
border-bottom-color: #404040;
|
|
229
|
+
}
|
|
230
|
+
|
|
227
231
|
html.dark .bn-snippet-dropdown__search {
|
|
228
232
|
border-color: #404040;
|
|
229
233
|
}
|
|
@@ -240,8 +244,12 @@ html.dark .bn-snippet-dropdown__search-input::placeholder {
|
|
|
240
244
|
color: #525252;
|
|
241
245
|
}
|
|
242
246
|
|
|
243
|
-
html.dark .bn-snippet-
|
|
244
|
-
|
|
247
|
+
html.dark .bn-snippet-dropdown__item--selected {
|
|
248
|
+
background: #333333;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
html.dark .bn-snippet-dropdown__item-check {
|
|
252
|
+
color: #fafafa;
|
|
245
253
|
}
|
|
246
254
|
|
|
247
255
|
html.dark .bn-snippet-dropdown__chevron {
|
|
@@ -609,7 +617,7 @@ html.dark .bn-step-image-preview__content {
|
|
|
609
617
|
position: absolute;
|
|
610
618
|
left: 0;
|
|
611
619
|
top: calc(100% + 4px);
|
|
612
|
-
width:
|
|
620
|
+
width: 280px;
|
|
613
621
|
background: white;
|
|
614
622
|
border: 1px solid #e5e5e5;
|
|
615
623
|
border-radius: 8px;
|
|
@@ -620,13 +628,17 @@ html.dark .bn-step-image-preview__content {
|
|
|
620
628
|
padding: 8px 0;
|
|
621
629
|
}
|
|
622
630
|
|
|
631
|
+
.bn-snippet-dropdown__search-wrapper {
|
|
632
|
+
padding: 4px 16px 12px;
|
|
633
|
+
border-bottom: 1px solid #e5e5e5;
|
|
634
|
+
}
|
|
635
|
+
|
|
623
636
|
.bn-snippet-dropdown__search {
|
|
624
637
|
display: flex;
|
|
625
638
|
align-items: center;
|
|
626
639
|
gap: 8px;
|
|
627
640
|
height: 32px;
|
|
628
641
|
padding: 0 12px;
|
|
629
|
-
margin: 0 16px 12px;
|
|
630
642
|
border: 1px solid #d4d4d4;
|
|
631
643
|
border-radius: 6px;
|
|
632
644
|
transition: border-color 120ms ease;
|
|
@@ -638,8 +650,8 @@ html.dark .bn-step-image-preview__content {
|
|
|
638
650
|
|
|
639
651
|
.bn-snippet-dropdown__search-icon {
|
|
640
652
|
flex-shrink: 0;
|
|
641
|
-
width:
|
|
642
|
-
height:
|
|
653
|
+
width: 20px;
|
|
654
|
+
height: 20px;
|
|
643
655
|
color: #a4a4a4;
|
|
644
656
|
}
|
|
645
657
|
|
|
@@ -663,7 +675,6 @@ html.dark .bn-step-image-preview__content {
|
|
|
663
675
|
.bn-snippet-dropdown__list {
|
|
664
676
|
max-height: 252px;
|
|
665
677
|
overflow-y: auto;
|
|
666
|
-
border-top: 1px solid #e5e5e5;
|
|
667
678
|
}
|
|
668
679
|
|
|
669
680
|
.bn-snippet-dropdown__item {
|
|
@@ -682,9 +693,25 @@ html.dark .bn-step-image-preview__content {
|
|
|
682
693
|
color: var(--text-primary);
|
|
683
694
|
text-align: left;
|
|
684
695
|
cursor: pointer;
|
|
685
|
-
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.bn-snippet-dropdown__item-title {
|
|
699
|
+
flex: 1;
|
|
700
|
+
min-width: 0;
|
|
686
701
|
overflow: hidden;
|
|
687
702
|
text-overflow: ellipsis;
|
|
703
|
+
white-space: nowrap;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.bn-snippet-dropdown__item-check {
|
|
707
|
+
flex-shrink: 0;
|
|
708
|
+
width: 16px;
|
|
709
|
+
height: 16px;
|
|
710
|
+
color: var(--text-primary);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.bn-snippet-dropdown__item--selected {
|
|
714
|
+
background: #fafafa;
|
|
688
715
|
}
|
|
689
716
|
|
|
690
717
|
.bn-snippet-dropdown__item:hover {
|
package/package.json
CHANGED
|
@@ -7,10 +7,11 @@ type SnippetDropdownProps = {
|
|
|
7
7
|
value: string;
|
|
8
8
|
placeholder: string;
|
|
9
9
|
suggestions: SnippetSuggestion[];
|
|
10
|
+
selectedId: string;
|
|
10
11
|
onSelect: (suggestion: SnippetSuggestion) => void;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
function SnippetDropdown({ value, placeholder, suggestions, onSelect }: SnippetDropdownProps) {
|
|
14
|
+
function SnippetDropdown({ value, placeholder, suggestions, selectedId, onSelect }: SnippetDropdownProps) {
|
|
14
15
|
const [isOpen, setIsOpen] = useState(false);
|
|
15
16
|
const [search, setSearch] = useState("");
|
|
16
17
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
@@ -61,36 +62,47 @@ function SnippetDropdown({ value, placeholder, suggestions, onSelect }: SnippetD
|
|
|
61
62
|
</button>
|
|
62
63
|
{isOpen && (
|
|
63
64
|
<div className="bn-snippet-dropdown__panel" role="listbox">
|
|
64
|
-
<div className="bn-snippet-dropdown__search">
|
|
65
|
-
<
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
<div className="bn-snippet-dropdown__search-wrapper">
|
|
66
|
+
<div className="bn-snippet-dropdown__search">
|
|
67
|
+
<svg className="bn-snippet-dropdown__search-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
68
|
+
<path d="M12.917 11.667h-.659l-.233-.225a5.417 5.417 0 0 0 1.308-3.525 5.417 5.417 0 1 0-5.416 5.416 5.417 5.417 0 0 0 3.525-1.308l.225.233v.659l4.166 4.158 1.242-1.242-4.158-4.166Zm-5 0a3.745 3.745 0 0 1-3.75-3.75 3.745 3.745 0 0 1 3.75-3.75 3.745 3.745 0 0 1 3.75 3.75 3.745 3.745 0 0 1-3.75 3.75Z" fill="currentColor"/>
|
|
69
|
+
</svg>
|
|
70
|
+
<input
|
|
71
|
+
ref={searchRef}
|
|
72
|
+
type="text"
|
|
73
|
+
className="bn-snippet-dropdown__search-input"
|
|
74
|
+
placeholder="Search"
|
|
75
|
+
value={search}
|
|
76
|
+
onChange={handleSearchChange}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
76
79
|
</div>
|
|
77
80
|
<div className="bn-snippet-dropdown__list">
|
|
78
|
-
{filtered.map((suggestion) =>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
{filtered.map((suggestion) => {
|
|
82
|
+
const isSelected = suggestion.id === selectedId;
|
|
83
|
+
return (
|
|
84
|
+
<button
|
|
85
|
+
type="button"
|
|
86
|
+
key={suggestion.id}
|
|
87
|
+
role="option"
|
|
88
|
+
aria-selected={isSelected}
|
|
89
|
+
className={`bn-snippet-dropdown__item${isSelected ? " bn-snippet-dropdown__item--selected" : ""}`}
|
|
90
|
+
onMouseDown={(event) => {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
onSelect(suggestion);
|
|
93
|
+
setIsOpen(false);
|
|
94
|
+
}}
|
|
95
|
+
tabIndex={-1}
|
|
96
|
+
>
|
|
97
|
+
<span className="bn-snippet-dropdown__item-title">{suggestion.title}</span>
|
|
98
|
+
{isSelected && (
|
|
99
|
+
<svg className="bn-snippet-dropdown__item-check" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
100
|
+
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17Z" fill="currentColor"/>
|
|
101
|
+
</svg>
|
|
102
|
+
)}
|
|
103
|
+
</button>
|
|
104
|
+
);
|
|
105
|
+
})}
|
|
94
106
|
{filtered.length === 0 && (
|
|
95
107
|
<div className="bn-snippet-dropdown__empty">No snippets found</div>
|
|
96
108
|
)}
|
|
@@ -178,11 +190,12 @@ export const snippetBlock = createReactBlockSpec(
|
|
|
178
190
|
value={snippetTitle}
|
|
179
191
|
placeholder="Select Snippet"
|
|
180
192
|
suggestions={snippetSuggestions}
|
|
193
|
+
selectedId={snippetId}
|
|
181
194
|
onSelect={handleSnippetSelect}
|
|
182
195
|
/>
|
|
183
196
|
</div>
|
|
184
|
-
{isSnippetSelected && (
|
|
185
|
-
<div className="bn-snippet__content"
|
|
197
|
+
{isSnippetSelected && snippetData && (
|
|
198
|
+
<div className="bn-snippet__content" dangerouslySetInnerHTML={{ __html: snippetData }} />
|
|
186
199
|
)}
|
|
187
200
|
</div>
|
|
188
201
|
);
|
package/src/editor/styles.css
CHANGED
|
@@ -224,6 +224,10 @@ html.dark .bn-snippet-dropdown__panel {
|
|
|
224
224
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
html.dark .bn-snippet-dropdown__search-wrapper {
|
|
228
|
+
border-bottom-color: #404040;
|
|
229
|
+
}
|
|
230
|
+
|
|
227
231
|
html.dark .bn-snippet-dropdown__search {
|
|
228
232
|
border-color: #404040;
|
|
229
233
|
}
|
|
@@ -240,8 +244,12 @@ html.dark .bn-snippet-dropdown__search-input::placeholder {
|
|
|
240
244
|
color: #525252;
|
|
241
245
|
}
|
|
242
246
|
|
|
243
|
-
html.dark .bn-snippet-
|
|
244
|
-
|
|
247
|
+
html.dark .bn-snippet-dropdown__item--selected {
|
|
248
|
+
background: #333333;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
html.dark .bn-snippet-dropdown__item-check {
|
|
252
|
+
color: #fafafa;
|
|
245
253
|
}
|
|
246
254
|
|
|
247
255
|
html.dark .bn-snippet-dropdown__chevron {
|
|
@@ -609,7 +617,7 @@ html.dark .bn-step-image-preview__content {
|
|
|
609
617
|
position: absolute;
|
|
610
618
|
left: 0;
|
|
611
619
|
top: calc(100% + 4px);
|
|
612
|
-
width:
|
|
620
|
+
width: 280px;
|
|
613
621
|
background: white;
|
|
614
622
|
border: 1px solid #e5e5e5;
|
|
615
623
|
border-radius: 8px;
|
|
@@ -620,13 +628,17 @@ html.dark .bn-step-image-preview__content {
|
|
|
620
628
|
padding: 8px 0;
|
|
621
629
|
}
|
|
622
630
|
|
|
631
|
+
.bn-snippet-dropdown__search-wrapper {
|
|
632
|
+
padding: 4px 16px 12px;
|
|
633
|
+
border-bottom: 1px solid #e5e5e5;
|
|
634
|
+
}
|
|
635
|
+
|
|
623
636
|
.bn-snippet-dropdown__search {
|
|
624
637
|
display: flex;
|
|
625
638
|
align-items: center;
|
|
626
639
|
gap: 8px;
|
|
627
640
|
height: 32px;
|
|
628
641
|
padding: 0 12px;
|
|
629
|
-
margin: 0 16px 12px;
|
|
630
642
|
border: 1px solid #d4d4d4;
|
|
631
643
|
border-radius: 6px;
|
|
632
644
|
transition: border-color 120ms ease;
|
|
@@ -638,8 +650,8 @@ html.dark .bn-step-image-preview__content {
|
|
|
638
650
|
|
|
639
651
|
.bn-snippet-dropdown__search-icon {
|
|
640
652
|
flex-shrink: 0;
|
|
641
|
-
width:
|
|
642
|
-
height:
|
|
653
|
+
width: 20px;
|
|
654
|
+
height: 20px;
|
|
643
655
|
color: #a4a4a4;
|
|
644
656
|
}
|
|
645
657
|
|
|
@@ -663,7 +675,6 @@ html.dark .bn-step-image-preview__content {
|
|
|
663
675
|
.bn-snippet-dropdown__list {
|
|
664
676
|
max-height: 252px;
|
|
665
677
|
overflow-y: auto;
|
|
666
|
-
border-top: 1px solid #e5e5e5;
|
|
667
678
|
}
|
|
668
679
|
|
|
669
680
|
.bn-snippet-dropdown__item {
|
|
@@ -682,9 +693,25 @@ html.dark .bn-step-image-preview__content {
|
|
|
682
693
|
color: var(--text-primary);
|
|
683
694
|
text-align: left;
|
|
684
695
|
cursor: pointer;
|
|
685
|
-
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.bn-snippet-dropdown__item-title {
|
|
699
|
+
flex: 1;
|
|
700
|
+
min-width: 0;
|
|
686
701
|
overflow: hidden;
|
|
687
702
|
text-overflow: ellipsis;
|
|
703
|
+
white-space: nowrap;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.bn-snippet-dropdown__item-check {
|
|
707
|
+
flex-shrink: 0;
|
|
708
|
+
width: 16px;
|
|
709
|
+
height: 16px;
|
|
710
|
+
color: var(--text-primary);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.bn-snippet-dropdown__item--selected {
|
|
714
|
+
background: #fafafa;
|
|
688
715
|
}
|
|
689
716
|
|
|
690
717
|
.bn-snippet-dropdown__item:hover {
|