foldkit 0.52.0 → 0.54.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/devtools/overlay-styles.d.ts +1 -1
- package/dist/devtools/overlay-styles.d.ts.map +1 -1
- package/dist/devtools/overlay-styles.js +80 -0
- package/dist/devtools/overlay.d.ts.map +1 -1
- package/dist/devtools/overlay.js +166 -32
- package/dist/test/internal.d.ts +5 -3
- package/dist/test/internal.d.ts.map +1 -1
- package/dist/test/internal.js +35 -3
- package/dist/test/query.d.ts.map +1 -1
- package/dist/test/query.js +9 -2
- package/dist/test/scene.d.ts +3 -3
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +4 -33
- package/dist/test/story.d.ts +3 -3
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +4 -33
- package/dist/ui/combobox/multi.d.ts +35 -35
- package/dist/ui/combobox/shared.d.ts +23 -23
- package/dist/ui/combobox/single.d.ts +35 -35
- package/dist/ui/dragAndDrop/index.d.ts +2 -2
- package/dist/ui/listbox/multi.d.ts +34 -34
- package/dist/ui/listbox/shared.d.ts +25 -25
- package/dist/ui/listbox/single.d.ts +34 -34
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const overlayStyles = ":host {\n position: relative;\n z-index: 2147483647;\n\n --dt-bg: #1e1e2e;\n --dt-surface-selected: #282839;\n --dt-border: #45475a;\n --dt-text: #cdd6f4;\n --dt-text-muted: #9399b2;\n --dt-accent: #cba6f7;\n --dt-live: #a6e3a1;\n --dt-paused: #fab387;\n --dt-json-string: #a6e3a1;\n --dt-json-number: #89b4fa;\n --dt-json-boolean: #fab387;\n --dt-json-null: #9399b2;\n --dt-json-key: #89dceb;\n --dt-json-tag: #cba6f7;\n --dt-json-preview: #9399b2;\n --dt-json-arrow: #9399b2;\n --dt-tree-hover: #313244;\n --dt-diff-changed: #74c7ec;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\nbutton {\n font: inherit;\n color: inherit;\n}\nul {\n list-style: none;\n}\n\n.fixed {\n position: fixed;\n}\n.flex {\n display: flex;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.inline-block {\n display: inline-block;\n}\n.gap-0\\.5 {\n gap: 2px;\n}\n.gap-1\\.5 {\n gap: 6px;\n}\n.gap-2 {\n gap: 8px;\n}\n.gap-px {\n gap: 1px;\n}\n.px-1 {\n padding-left: 4px;\n padding-right: 4px;\n}\n.px-2 {\n padding-left: 8px;\n padding-right: 8px;\n}\n.px-2\\.5 {\n padding-left: 10px;\n padding-right: 10px;\n}\n.p-3 {\n padding: 12px;\n}\n.px-3 {\n padding-left: 12px;\n padding-right: 12px;\n}\n.py-0\\.5 {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pt-1 {\n padding-top: 4px;\n}\n.pl-1 {\n padding-left: 4px;\n}\n.py-1 {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.py-1\\.5 {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.py-2 {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.py-px {\n padding-top: 1px;\n padding-bottom: 1px;\n}\n.w-1\\.5 {\n width: 6px;\n}\n.h-1\\.5 {\n height: 6px;\n}\n.w-3 {\n width: 12px;\n}\n.w-5 {\n width: 20px;\n}\n.h-5 {\n height: 20px;\n}\n.w-14 {\n width: 56px;\n}\n.h-14 {\n height: 56px;\n}\n.min-w-0 {\n min-width: 0;\n}\n.min-w-5 {\n min-width: 20px;\n}\n.min-h-0 {\n min-height: 0;\n}\n/* Badge positions \u2014 flush against side edge */\n.dt-pos-br {\n bottom: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-bl {\n bottom: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.dt-pos-tr {\n top: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-tl {\n top: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overscroll-none {\n overscroll-behavior: none;\n}\n\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.rounded {\n border-radius: 4px;\n}\n.rounded-lg {\n border-radius: 8px;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.border {\n border-width: 1px;\n border-style: solid;\n border-color: var(--dt-border);\n}\n.border-b {\n border-bottom: 1px solid var(--dt-border);\n}\n.border-t {\n border-top: 1px solid var(--dt-border);\n}\n.border-r {\n border-right: 1px solid var(--dt-border);\n}\n.border-l {\n border-left: 1px solid var(--dt-border);\n}\n.border-none {\n border: none;\n}\n.selected {\n background-color: var(--dt-surface-selected);\n}\n.dt-row:hover:not(.selected) {\n background-color: var(--dt-tree-hover);\n}\n.dt-header-button:hover {\n color: var(--dt-text);\n}\n.dt-resume-button:hover {\n opacity: 0.7;\n}\n.dt-tab-button {\n position: relative;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n outline: none;\n flex: 1;\n}\n.dt-tab-button:last-child {\n border-right: none;\n}\n.dt-tab-active {\n background-color: var(--dt-surface-selected);\n}\n.dt-tab-button:not(.dt-tab-active):hover {\n color: var(--dt-text);\n background-color: rgba(49, 50, 68, 0.3);\n}\n.font-sans {\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n sans-serif;\n}\n.font-mono {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.text-xs {\n font-size: 12px;\n}\n.text-2xs {\n font-size: 10px;\n}\n.text-sm {\n font-size: 11px;\n}\n.text-base {\n font-size: 13px;\n}\n.text-md {\n font-size: 15px;\n}\n.text-lg {\n font-size: 20px;\n}\n.text-xl {\n font-size: 26px;\n}\n.italic {\n font-style: italic;\n}\n.text-right {\n text-align: right;\n}\n.tracking-wide {\n letter-spacing: 0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.leading-none {\n line-height: 1;\n}\n.leading-snug {\n line-height: 1.35;\n}\n.bg-dt-bg {\n background-color: var(--dt-bg);\n}\n.bg-dt-live {\n background-color: var(--dt-live);\n}\n.bg-transparent {\n background-color: transparent;\n}\n.text-dt {\n color: var(--dt-text);\n}\n.text-dt-bg {\n color: var(--dt-bg);\n}\n.text-dt-muted {\n color: var(--dt-text-muted);\n}\n.text-dt-accent {\n color: var(--dt-accent);\n}\n.text-dt-live {\n color: var(--dt-live);\n}\n.text-dt-paused {\n color: var(--dt-paused);\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.outline-none {\n outline: none;\n}\n.transition-colors {\n transition-property: color, background-color, border-color;\n transition-duration: 100ms;\n transition-timing-function: ease;\n}\n\n/* Panel */\n.dt-panel {\n width: 360px;\n height: 480px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n z-index: 99998;\n}\n/* Panel positions */\n.dt-panel-br {\n bottom: 16px;\n right: 28px;\n}\n.dt-panel-bl {\n bottom: 16px;\n left: 28px;\n}\n.dt-panel-tr {\n top: 16px;\n right: 28px;\n}\n.dt-panel-tl {\n top: 16px;\n left: 28px;\n}\n.dt-panel-wide {\n width: 720px;\n}\n.dt-message-pane {\n width: 320px;\n flex-shrink: 0;\n}\n.dt-badge {\n z-index: 99999;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);\n transition: background-color 150ms ease;\n border: 1px solid var(--dt-border);\n}\n.dt-badge-accent:hover {\n background-color: #252538;\n}\n.dt-badge-paused {\n background-color: var(--dt-paused);\n color: var(--dt-bg);\n border: none;\n}\n.dt-badge-paused:hover {\n background-color: #e0a070;\n}\n.dt-badge.dt-pos-br,\n.dt-badge.dt-pos-tr {\n border-right: none;\n}\n.dt-badge.dt-pos-bl,\n.dt-badge.dt-pos-tl {\n border-left: none;\n}\n\n/* JSON tree */\n.tree-row {\n position: relative;\n white-space: nowrap;\n line-height: 18px;\n padding-right: 8px;\n}\n.tree-row-expandable:hover {\n background-color: var(--dt-tree-hover);\n}\n.inspector-tree {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.json-key {\n color: var(--dt-json-key);\n}\n.json-string {\n color: var(--dt-json-string);\n}\n.json-number {\n color: var(--dt-json-number);\n}\n.json-boolean {\n color: var(--dt-json-boolean);\n}\n.json-null {\n color: var(--dt-json-null);\n}\n.json-tag {\n color: var(--dt-json-tag);\n margin-right: 4px;\n}\n.json-preview {\n color: var(--dt-json-preview);\n}\n.json-arrow {\n color: var(--dt-json-arrow);\n width: 10px;\n height: 10px;\n user-select: none;\n}\n\n/* Diff */\n.diff-changed {\n background-color: rgba(116, 199, 236, 0.06);\n}\n.diff-dot {\n position: absolute;\n left: 3px;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n}\n.diff-dot-inline {\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n flex-shrink: 0;\n}\n.dot-column {\n width: 5px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.pause-column {\n width: 8px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.dt-pause-icon {\n width: 8px;\n height: 8px;\n color: var(--dt-paused);\n}\n\n/* Interaction blocker \u2014 covers the app while time-travelling */\n.dt-interaction-blocker {\n position: fixed;\n inset: 0;\n z-index: 99997;\n cursor: not-allowed;\n}\n\n/* Mobile */\n@media (max-width: 767px) {\n .dt-panel {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n border: none;\n }\n .dt-panel-wide {\n width: 100%;\n }\n .dt-content {\n flex-direction: column;\n }\n .dt-message-pane {\n width: 100%;\n max-height: 40%;\n border-bottom: 1px solid var(--dt-border);\n }\n .message-list > :last-child {\n border-bottom: none;\n }\n .dt-inspector-pane {\n border-left: none;\n }\n}\n";
|
|
1
|
+
declare const overlayStyles = ":host {\n position: relative;\n z-index: 2147483647;\n\n --dt-bg: #1e1e2e;\n --dt-surface-selected: #282839;\n --dt-border: #45475a;\n --dt-text: #cdd6f4;\n --dt-text-muted: #9399b2;\n --dt-accent: #cba6f7;\n --dt-live: #a6e3a1;\n --dt-paused: #fab387;\n --dt-json-string: #a6e3a1;\n --dt-json-number: #89b4fa;\n --dt-json-boolean: #fab387;\n --dt-json-null: #9399b2;\n --dt-json-key: #89dceb;\n --dt-json-tag: #cba6f7;\n --dt-json-preview: #9399b2;\n --dt-json-arrow: #9399b2;\n --dt-tree-hover: #313244;\n --dt-diff-changed: #74c7ec;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\nbutton {\n font: inherit;\n color: inherit;\n}\nul {\n list-style: none;\n}\n\n.fixed {\n position: fixed;\n}\n.flex {\n display: flex;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.inline-block {\n display: inline-block;\n}\n.gap-0\\.5 {\n gap: 2px;\n}\n.gap-1\\.5 {\n gap: 6px;\n}\n.gap-2 {\n gap: 8px;\n}\n.gap-px {\n gap: 1px;\n}\n.px-1 {\n padding-left: 4px;\n padding-right: 4px;\n}\n.px-2 {\n padding-left: 8px;\n padding-right: 8px;\n}\n.px-2\\.5 {\n padding-left: 10px;\n padding-right: 10px;\n}\n.p-3 {\n padding: 12px;\n}\n.px-3 {\n padding-left: 12px;\n padding-right: 12px;\n}\n.py-0\\.5 {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pt-1 {\n padding-top: 4px;\n}\n.pl-1 {\n padding-left: 4px;\n}\n.py-1 {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.py-1\\.5 {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.py-2 {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.py-px {\n padding-top: 1px;\n padding-bottom: 1px;\n}\n.w-1\\.5 {\n width: 6px;\n}\n.h-1\\.5 {\n height: 6px;\n}\n.w-3 {\n width: 12px;\n}\n.w-5 {\n width: 20px;\n}\n.h-5 {\n height: 20px;\n}\n.w-14 {\n width: 56px;\n}\n.h-14 {\n height: 56px;\n}\n.min-w-0 {\n min-width: 0;\n}\n.min-w-5 {\n min-width: 20px;\n}\n.min-h-0 {\n min-height: 0;\n}\n/* Badge positions \u2014 flush against side edge */\n.dt-pos-br {\n bottom: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-bl {\n bottom: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.dt-pos-tr {\n top: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-tl {\n top: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overscroll-none {\n overscroll-behavior: none;\n}\n\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.rounded {\n border-radius: 4px;\n}\n.rounded-lg {\n border-radius: 8px;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.border {\n border-width: 1px;\n border-style: solid;\n border-color: var(--dt-border);\n}\n.border-b {\n border-bottom: 1px solid var(--dt-border);\n}\n.border-t {\n border-top: 1px solid var(--dt-border);\n}\n.border-r {\n border-right: 1px solid var(--dt-border);\n}\n.border-l {\n border-left: 1px solid var(--dt-border);\n}\n.border-none {\n border: none;\n}\n.selected {\n background-color: var(--dt-surface-selected);\n}\n.dt-row:hover:not(.selected) {\n background-color: var(--dt-tree-hover);\n}\n.dt-header-button:hover {\n color: var(--dt-text);\n}\n.dt-resume-button:hover {\n opacity: 0.7;\n}\n.dt-filter-wrapper {\n position: relative;\n flex-shrink: 0;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: transparent;\n border: none;\n color: var(--dt-text-muted);\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n}\n.dt-filter-button:hover {\n color: var(--dt-text);\n background-color: var(--dt-tree-hover);\n}\n.dt-filter-button:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-filter-button[data-open] {\n color: var(--dt-text);\n background-color: var(--dt-surface-selected);\n}\n.dt-filter-button[data-open] .json-arrow {\n transform: rotate(180deg);\n}\n.dt-filter-items {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background-color: var(--dt-bg);\n border-top: none;\n border-bottom: 1px solid var(--dt-border);\n z-index: 10;\n max-height: 200px;\n overflow-y: auto;\n outline: none;\n}\n.dt-filter-item {\n padding: 6px 12px;\n color: var(--dt-text-muted);\n cursor: pointer;\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-item:last-child {\n border-bottom: none;\n}\n.dt-filter-item[data-active] {\n background-color: var(--dt-tree-hover);\n color: var(--dt-text);\n}\n.dt-filter-item[data-selected] {\n color: var(--dt-accent);\n}\n.dt-filter-check {\n width: 12px;\n height: 12px;\n visibility: hidden;\n}\n.dt-filter-item[data-selected] .dt-filter-check {\n visibility: visible;\n color: var(--dt-accent);\n}\n.dt-filter-backdrop {\n position: fixed;\n inset: 0;\n}\n.dt-tab-button {\n position: relative;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n outline: none;\n flex: 1;\n}\n.dt-tab-button:last-child {\n border-right: none;\n}\n.dt-tab-active {\n background-color: var(--dt-surface-selected);\n}\n.dt-tab-button:not(.dt-tab-active):hover {\n color: var(--dt-text);\n background-color: rgba(49, 50, 68, 0.3);\n}\n.font-sans {\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n sans-serif;\n}\n.font-mono {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.text-xs {\n font-size: 12px;\n}\n.text-2xs {\n font-size: 10px;\n}\n.text-sm {\n font-size: 11px;\n}\n.text-base {\n font-size: 13px;\n}\n.text-md {\n font-size: 15px;\n}\n.text-lg {\n font-size: 20px;\n}\n.text-xl {\n font-size: 26px;\n}\n.italic {\n font-style: italic;\n}\n.text-right {\n text-align: right;\n}\n.tracking-wide {\n letter-spacing: 0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.leading-none {\n line-height: 1;\n}\n.leading-snug {\n line-height: 1.35;\n}\n.bg-dt-bg {\n background-color: var(--dt-bg);\n}\n.bg-dt-live {\n background-color: var(--dt-live);\n}\n.bg-transparent {\n background-color: transparent;\n}\n.text-dt {\n color: var(--dt-text);\n}\n.text-dt-bg {\n color: var(--dt-bg);\n}\n.text-dt-muted {\n color: var(--dt-text-muted);\n}\n.text-dt-accent {\n color: var(--dt-accent);\n}\n.text-dt-live {\n color: var(--dt-live);\n}\n.text-dt-paused {\n color: var(--dt-paused);\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.outline-none {\n outline: none;\n}\n.transition-colors {\n transition-property: color, background-color, border-color;\n transition-duration: 100ms;\n transition-timing-function: ease;\n}\n\n/* Panel */\n.dt-panel {\n width: 360px;\n height: 480px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n z-index: 99998;\n}\n/* Panel positions */\n.dt-panel-br {\n bottom: 16px;\n right: 28px;\n}\n.dt-panel-bl {\n bottom: 16px;\n left: 28px;\n}\n.dt-panel-tr {\n top: 16px;\n right: 28px;\n}\n.dt-panel-tl {\n top: 16px;\n left: 28px;\n}\n.dt-panel-wide {\n width: 720px;\n}\n.dt-message-pane {\n width: 320px;\n flex-shrink: 0;\n}\n.dt-badge {\n z-index: 99999;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);\n transition: background-color 150ms ease;\n border: 1px solid var(--dt-border);\n}\n.dt-badge-accent:hover {\n background-color: #252538;\n}\n.dt-badge-paused {\n background-color: var(--dt-paused);\n color: var(--dt-bg);\n border: none;\n}\n.dt-badge-paused:hover {\n background-color: #e0a070;\n}\n.dt-badge.dt-pos-br,\n.dt-badge.dt-pos-tr {\n border-right: none;\n}\n.dt-badge.dt-pos-bl,\n.dt-badge.dt-pos-tl {\n border-left: none;\n}\n\n/* JSON tree */\n.tree-row {\n position: relative;\n white-space: nowrap;\n line-height: 18px;\n padding-right: 8px;\n}\n.tree-row-expandable:hover {\n background-color: var(--dt-tree-hover);\n}\n.inspector-tree {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.json-key {\n color: var(--dt-json-key);\n}\n.json-string {\n color: var(--dt-json-string);\n}\n.json-number {\n color: var(--dt-json-number);\n}\n.json-boolean {\n color: var(--dt-json-boolean);\n}\n.json-null {\n color: var(--dt-json-null);\n}\n.json-tag {\n color: var(--dt-json-tag);\n margin-right: 4px;\n}\n.json-preview {\n color: var(--dt-json-preview);\n}\n.json-arrow {\n color: var(--dt-json-arrow);\n width: 10px;\n height: 10px;\n user-select: none;\n}\n\n/* Diff */\n.diff-changed {\n background-color: rgba(116, 199, 236, 0.06);\n}\n.diff-dot {\n position: absolute;\n left: 3px;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n}\n.diff-dot-inline {\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n flex-shrink: 0;\n}\n.dot-column {\n width: 5px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.pause-column {\n width: 8px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.dt-pause-icon {\n width: 8px;\n height: 8px;\n color: var(--dt-paused);\n}\n\n/* Interaction blocker \u2014 covers the app while time-travelling */\n.dt-interaction-blocker {\n position: fixed;\n inset: 0;\n z-index: 99997;\n cursor: not-allowed;\n}\n\n/* Mobile */\n@media (max-width: 767px) {\n .dt-panel {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n border: none;\n }\n .dt-panel-wide {\n width: 100%;\n }\n .dt-content {\n flex-direction: column;\n }\n .dt-message-pane {\n width: 100%;\n max-height: 40%;\n border-bottom: 1px solid var(--dt-border);\n }\n .message-list > :last-child {\n border-bottom: none;\n }\n .dt-inspector-pane {\n border-left: none;\n }\n}\n";
|
|
2
2
|
export { overlayStyles };
|
|
3
3
|
//# sourceMappingURL=overlay-styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay-styles.d.ts","sourceRoot":"","sources":["../../src/devtools/overlay-styles.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"overlay-styles.d.ts","sourceRoot":"","sources":["../../src/devtools/overlay-styles.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,aAAa,kvUA6lBlB,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -231,6 +231,86 @@ ul {
|
|
|
231
231
|
.dt-resume-button:hover {
|
|
232
232
|
opacity: 0.7;
|
|
233
233
|
}
|
|
234
|
+
.dt-filter-wrapper {
|
|
235
|
+
position: relative;
|
|
236
|
+
flex-shrink: 0;
|
|
237
|
+
border-bottom: 1px solid var(--dt-border);
|
|
238
|
+
}
|
|
239
|
+
.dt-filter-button {
|
|
240
|
+
width: 100%;
|
|
241
|
+
display: flex;
|
|
242
|
+
align-items: center;
|
|
243
|
+
justify-content: space-between;
|
|
244
|
+
padding: 6px 12px;
|
|
245
|
+
background: transparent;
|
|
246
|
+
border: none;
|
|
247
|
+
color: var(--dt-text-muted);
|
|
248
|
+
font-family:
|
|
249
|
+
ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
250
|
+
font-size: 13px;
|
|
251
|
+
cursor: pointer;
|
|
252
|
+
text-align: left;
|
|
253
|
+
}
|
|
254
|
+
.dt-filter-button:hover {
|
|
255
|
+
color: var(--dt-text);
|
|
256
|
+
background-color: var(--dt-tree-hover);
|
|
257
|
+
}
|
|
258
|
+
.dt-filter-button:focus-visible {
|
|
259
|
+
outline: 1px solid var(--dt-accent);
|
|
260
|
+
outline-offset: -1px;
|
|
261
|
+
}
|
|
262
|
+
.dt-filter-button[data-open] {
|
|
263
|
+
color: var(--dt-text);
|
|
264
|
+
background-color: var(--dt-surface-selected);
|
|
265
|
+
}
|
|
266
|
+
.dt-filter-button[data-open] .json-arrow {
|
|
267
|
+
transform: rotate(180deg);
|
|
268
|
+
}
|
|
269
|
+
.dt-filter-items {
|
|
270
|
+
position: absolute;
|
|
271
|
+
top: 100%;
|
|
272
|
+
left: 0;
|
|
273
|
+
right: 0;
|
|
274
|
+
background-color: var(--dt-bg);
|
|
275
|
+
border-top: none;
|
|
276
|
+
border-bottom: 1px solid var(--dt-border);
|
|
277
|
+
z-index: 10;
|
|
278
|
+
max-height: 200px;
|
|
279
|
+
overflow-y: auto;
|
|
280
|
+
outline: none;
|
|
281
|
+
}
|
|
282
|
+
.dt-filter-item {
|
|
283
|
+
padding: 6px 12px;
|
|
284
|
+
color: var(--dt-text-muted);
|
|
285
|
+
cursor: pointer;
|
|
286
|
+
font-family:
|
|
287
|
+
ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
288
|
+
font-size: 13px;
|
|
289
|
+
border-bottom: 1px solid var(--dt-border);
|
|
290
|
+
}
|
|
291
|
+
.dt-filter-item:last-child {
|
|
292
|
+
border-bottom: none;
|
|
293
|
+
}
|
|
294
|
+
.dt-filter-item[data-active] {
|
|
295
|
+
background-color: var(--dt-tree-hover);
|
|
296
|
+
color: var(--dt-text);
|
|
297
|
+
}
|
|
298
|
+
.dt-filter-item[data-selected] {
|
|
299
|
+
color: var(--dt-accent);
|
|
300
|
+
}
|
|
301
|
+
.dt-filter-check {
|
|
302
|
+
width: 12px;
|
|
303
|
+
height: 12px;
|
|
304
|
+
visibility: hidden;
|
|
305
|
+
}
|
|
306
|
+
.dt-filter-item[data-selected] .dt-filter-check {
|
|
307
|
+
visibility: visible;
|
|
308
|
+
color: var(--dt-accent);
|
|
309
|
+
}
|
|
310
|
+
.dt-filter-backdrop {
|
|
311
|
+
position: fixed;
|
|
312
|
+
inset: 0;
|
|
313
|
+
}
|
|
234
314
|
.dt-tab-button {
|
|
235
315
|
position: relative;
|
|
236
316
|
background: transparent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devtools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,MAAM,
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devtools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,MAAM,EAGN,OAAO,EAGP,MAAM,EASP,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,YAAY,CAAA;AAKrC,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAOxE,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,SAAS,CAAA;AAmNhB,eAAO,MAAM,MAAM;;EAA0C,CAAA;AAC7D,eAAO,MAAM,YAAY;;;;;;EAGxB,CAAA;AACD,eAAO,MAAM,aAAa;;;;;;EAGzB,CAAA;AACD,eAAO,MAAM,MAAM;;EAA4C,CAAA;AAC/D,eAAO,MAAM,KAAK;;EAA0C,CAAA;AAC5D,eAAO,MAAM,UAAU;;EAA6C,CAAA;AACpE,eAAO,MAAM,YAAY;;EAAiD,CAAA;AAC1E,eAAO,MAAM,WAAW;;EAA+C,CAAA;AA2xCvE,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,sCAkDhC,CAAA"}
|
package/dist/devtools/overlay.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
-
import { Array as Array_, Effect, HashSet, Match as M, Number as Number_, Option, Predicate, Record, Schema as S, Stream, String as String_, SubscriptionRef, pipe, } from 'effect';
|
|
2
|
+
import { Array as Array_, Effect, Equal, Function, HashSet, Match as M, Number as Number_, Option, Order, Predicate, Record, Schema as S, Stream, String as String_, SubscriptionRef, pipe, } from 'effect';
|
|
3
3
|
import * as Command from '../command';
|
|
4
4
|
import { OptionExt } from '../effectExtensions';
|
|
5
5
|
import { createKeyedLazy, html } from '../html';
|
|
@@ -8,17 +8,20 @@ import { makeProgram } from '../runtime/runtime';
|
|
|
8
8
|
import { makeSubscriptions } from '../runtime/subscription';
|
|
9
9
|
import { evo } from '../struct';
|
|
10
10
|
import { lockScroll, unlockScroll } from '../task/scrollLock';
|
|
11
|
+
import * as Listbox from '../ui/listbox/public';
|
|
11
12
|
import * as Tabs from '../ui/tabs';
|
|
12
13
|
import { overlayStyles } from './overlay-styles';
|
|
13
|
-
import { INIT_INDEX } from './store';
|
|
14
|
+
import { INIT_INDEX, } from './store';
|
|
14
15
|
// MODEL
|
|
15
16
|
const DisplayEntry = S.Struct({
|
|
16
17
|
tag: S.String,
|
|
18
|
+
maybeInnerTag: S.OptionFromSelf(S.String),
|
|
17
19
|
commandNames: S.Array(S.String),
|
|
18
20
|
timestamp: S.Number,
|
|
19
21
|
isModelChanged: S.Boolean,
|
|
20
22
|
});
|
|
21
23
|
const INSPECTOR_TABS_ID = 'dt-inspector';
|
|
24
|
+
const SUBMODEL_FILTER_ID = 'dt-submodel-filter';
|
|
22
25
|
const InspectorTabsModel = S.Struct({
|
|
23
26
|
id: S.String,
|
|
24
27
|
activeIndex: S.Number,
|
|
@@ -37,6 +40,9 @@ const Model = S.Struct({
|
|
|
37
40
|
isFollowingLatest: S.Boolean,
|
|
38
41
|
maybeInspectedModel: S.OptionFromSelf(S.Unknown),
|
|
39
42
|
maybeInspectedMessage: S.OptionFromSelf(S.Unknown),
|
|
43
|
+
submodelTags: S.Array(S.String),
|
|
44
|
+
maybeSubmodelFilter: S.OptionFromSelf(S.String),
|
|
45
|
+
submodelFilterListbox: Listbox.Model,
|
|
40
46
|
expandedPaths: S.HashSetFromSelf(S.String),
|
|
41
47
|
changedPaths: S.HashSetFromSelf(S.String),
|
|
42
48
|
affectedPaths: S.HashSetFromSelf(S.String),
|
|
@@ -82,20 +88,35 @@ const ReceivedStoreUpdate = m('ReceivedStoreUpdate', {
|
|
|
82
88
|
isPaused: S.Boolean,
|
|
83
89
|
pausedAtIndex: S.Number,
|
|
84
90
|
});
|
|
85
|
-
const
|
|
91
|
+
const GotSubmodelFilterMessage = m('GotSubmodelFilterMessage', {
|
|
92
|
+
message: Listbox.Message,
|
|
93
|
+
});
|
|
94
|
+
const SelectedSubmodelFilter = m('SelectedSubmodelFilter', {
|
|
95
|
+
tag: S.String,
|
|
96
|
+
});
|
|
97
|
+
const Message = S.Union(ClickedToggle, ClickedRow, ClickedResume, ClickedClear, ClickedFollowLatest, CompletedJump, CompletedResume, CompletedClear, LockedScroll, UnlockedScroll, ScrolledToTop, CrossedMobileBreakpoint, ReceivedInspectedState, ToggledTreeNode, GotInspectorTabsMessage, ReceivedStoreUpdate, GotSubmodelFilterMessage, SelectedSubmodelFilter);
|
|
86
98
|
// HELPERS
|
|
87
99
|
const MILLIS_PER_SECOND = 1000;
|
|
88
100
|
const MOBILE_BREAKPOINT = 767;
|
|
89
101
|
const MOBILE_BREAKPOINT_QUERY = `(max-width: ${MOBILE_BREAKPOINT}px)`;
|
|
90
102
|
const TREE_INDENT_PX = 12;
|
|
91
103
|
const MAX_PREVIEW_KEYS = 3;
|
|
104
|
+
const ALL_MESSAGES_VALUE = '';
|
|
92
105
|
const formatTimeDelta = (deltaMs) => M.value(deltaMs).pipe(M.when(0, () => '0ms'), M.when(Number_.lessThan(MILLIS_PER_SECOND), ms => `+${Math.round(ms)}ms`), M.orElse(ms => `+${(ms / MILLIS_PER_SECOND).toFixed(1)}s`));
|
|
93
106
|
const MESSAGE_LIST_SELECTOR = '.message-list';
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
const computeSubmodelTags = (entries) => pipe(entries, Array_.filterMap(entry => entry.maybeInnerTag.pipe(Option.as(entry.tag))), Array_.dedupe, Array_.sort(Order.string));
|
|
108
|
+
const GOT_MESSAGE_PATTERN = /^Got.+Message$/;
|
|
109
|
+
const extractInnerTag = (entry) => pipe(entry.tag, String_.search(GOT_MESSAGE_PATTERN), Option.flatMap(() => {
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
111
|
+
const inner = entry.message?.['message'];
|
|
112
|
+
return pipe(inner, Option.liftPredicate(isTagged), Option.map(({ _tag }) => _tag));
|
|
113
|
+
}));
|
|
114
|
+
const toDisplayEntries = ({ entries }) => Array_.map(entries, entry => ({
|
|
115
|
+
tag: entry.tag,
|
|
116
|
+
maybeInnerTag: extractInnerTag(entry),
|
|
117
|
+
commandNames: entry.commandNames,
|
|
118
|
+
timestamp: entry.timestamp,
|
|
119
|
+
isModelChanged: entry.isModelChanged,
|
|
99
120
|
}));
|
|
100
121
|
const toDisplayState = (state) => ({
|
|
101
122
|
entries: toDisplayEntries(state),
|
|
@@ -104,7 +125,7 @@ const toDisplayState = (state) => ({
|
|
|
104
125
|
isPaused: state.isPaused,
|
|
105
126
|
pausedAtIndex: state.pausedAtIndex,
|
|
106
127
|
});
|
|
107
|
-
const isExpandable = (value) => Predicate.
|
|
128
|
+
const isExpandable = (value) => Predicate.isObject(value);
|
|
108
129
|
const Tagged = S.Struct({ _tag: S.String });
|
|
109
130
|
const isTagged = S.is(Tagged);
|
|
110
131
|
const objectPreview = (value) => pipe(value, Record.keys, Array_.filter(key => key !== '_tag'), Array_.match({
|
|
@@ -196,6 +217,7 @@ const makeUpdate = (store, shadow, mode) => {
|
|
|
196
217
|
evo(model, {
|
|
197
218
|
selectedIndex: () => INIT_INDEX,
|
|
198
219
|
isFollowingLatest: () => true,
|
|
220
|
+
maybeSubmodelFilter: () => Option.none(),
|
|
199
221
|
expandedPaths: () => HashSet.empty(),
|
|
200
222
|
changedPaths: () => HashSet.empty(),
|
|
201
223
|
affectedPaths: () => HashSet.empty(),
|
|
@@ -250,6 +272,8 @@ const makeUpdate = (store, shadow, mode) => {
|
|
|
250
272
|
onEmpty: () => INIT_INDEX,
|
|
251
273
|
onNonEmpty: () => startIndex + entries.length - 1,
|
|
252
274
|
});
|
|
275
|
+
const nextSubmodelTags = computeSubmodelTags(entries);
|
|
276
|
+
const isFilterStale = Option.exists(model.maybeSubmodelFilter, filterTag => !Array_.contains(nextSubmodelTags, filterTag));
|
|
253
277
|
return [
|
|
254
278
|
evo(model, {
|
|
255
279
|
entries: () => entries,
|
|
@@ -257,11 +281,37 @@ const makeUpdate = (store, shadow, mode) => {
|
|
|
257
281
|
startIndex: () => startIndex,
|
|
258
282
|
isPaused: () => isPaused,
|
|
259
283
|
pausedAtIndex: () => pausedAtIndex,
|
|
284
|
+
submodelTags: () => nextSubmodelTags,
|
|
285
|
+
maybeSubmodelFilter: current => isFilterStale ? Option.none() : current,
|
|
286
|
+
submodelFilterListbox: current => isFilterStale
|
|
287
|
+
? evo(current, {
|
|
288
|
+
maybeSelectedItem: () => Option.some(ALL_MESSAGES_VALUE),
|
|
289
|
+
})
|
|
290
|
+
: current,
|
|
260
291
|
selectedIndex: current => shouldFollowLatest ? latestIndex : current,
|
|
261
292
|
}),
|
|
262
293
|
shouldFollowLatest ? [scrollToTop, inspectLatest] : [],
|
|
263
294
|
];
|
|
264
295
|
},
|
|
296
|
+
GotSubmodelFilterMessage: ({ message: listboxMessage }) => {
|
|
297
|
+
const [nextListboxModel, listboxCommands] = Listbox.update(model.submodelFilterListbox, listboxMessage);
|
|
298
|
+
return [
|
|
299
|
+
evo(model, {
|
|
300
|
+
submodelFilterListbox: () => nextListboxModel,
|
|
301
|
+
}),
|
|
302
|
+
listboxCommands.map(Command.mapEffect(Effect.map(innerMessage => GotSubmodelFilterMessage({ message: innerMessage })))),
|
|
303
|
+
];
|
|
304
|
+
},
|
|
305
|
+
SelectedSubmodelFilter: ({ tag }) => {
|
|
306
|
+
const [nextListbox, listboxCommands] = Listbox.selectItem(model.submodelFilterListbox, tag);
|
|
307
|
+
return [
|
|
308
|
+
evo(model, {
|
|
309
|
+
maybeSubmodelFilter: () => Option.liftPredicate(tag, String_.isNonEmpty),
|
|
310
|
+
submodelFilterListbox: () => nextListbox,
|
|
311
|
+
}),
|
|
312
|
+
listboxCommands.map(Command.mapEffect(Effect.map(innerMessage => GotSubmodelFilterMessage({ message: innerMessage })))),
|
|
313
|
+
];
|
|
314
|
+
},
|
|
265
315
|
}), M.tag('CompletedJump', 'CompletedResume', 'CompletedClear', 'LockedScroll', 'UnlockedScroll', 'ScrolledToTop', () => [model, []]), M.exhaustive);
|
|
266
316
|
};
|
|
267
317
|
// SUBSCRIPTION
|
|
@@ -467,16 +517,27 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
467
517
|
Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
|
|
468
518
|
], ['init — no Message']);
|
|
469
519
|
const modelTabContent = (model, inspectedModel) => treeView(inspectedModel, 'root', model.expandedPaths, model.changedPaths, model.affectedPaths, Option.none(), true);
|
|
520
|
+
const unwrapIfFiltered = (message, model) => {
|
|
521
|
+
if (Option.isNone(model.maybeSubmodelFilter)) {
|
|
522
|
+
return message;
|
|
523
|
+
}
|
|
524
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
525
|
+
const inner = message?.['message'];
|
|
526
|
+
return isTagged(inner) ? inner : message;
|
|
527
|
+
};
|
|
470
528
|
const messageTabContent = (model) => Option.match(model.maybeInspectedMessage, {
|
|
471
529
|
onNone: () => noMessageView,
|
|
472
|
-
onSome:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
530
|
+
onSome: rawMessage => {
|
|
531
|
+
const message = unwrapIfFiltered(rawMessage, model);
|
|
532
|
+
return div([Class('flex flex-col flex-1 min-h-0 min-w-0')], [
|
|
533
|
+
div([
|
|
534
|
+
Class('px-2 py-1 border-b text-2xs text-dt-muted font-mono shrink-0'),
|
|
535
|
+
], [inspectedTimestamp(model)]),
|
|
536
|
+
div([Class('flex flex-col flex-1 min-h-0 min-w-0 pt-1 pl-1')], [
|
|
537
|
+
treeView(message, 'root', model.expandedPaths, HashSet.empty(), HashSet.empty(), Option.none(), false),
|
|
538
|
+
]),
|
|
539
|
+
]);
|
|
540
|
+
},
|
|
480
541
|
});
|
|
481
542
|
const selectedCommandNames = (model) => {
|
|
482
543
|
const selectedIndex = M.value(mode).pipe(M.when('TimeTravel', () => model.isPaused ? model.pausedAtIndex : INIT_INDEX), M.when('Inspect', () => model.selectedIndex), M.exhaustive);
|
|
@@ -552,30 +613,80 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
552
613
|
const actionButtonClass = 'dt-resume-button bg-transparent border-none text-dt-live cursor-pointer text-base font-mono font-medium';
|
|
553
614
|
const statusClass = 'text-base font-mono';
|
|
554
615
|
const clearHistoryButton = button([Class(headerButtonClass), OnClick(ClickedClear())], ['Clear history']);
|
|
616
|
+
const submodelLabel = (tag) => pipe(tag, String_.replace(/^Got/, ''), String_.replace(/Message$/, ''));
|
|
617
|
+
const CHECK_ICON = 'M4.5 12.75l6 6 9-13.5';
|
|
618
|
+
const checkIconView = svg([
|
|
619
|
+
AriaHidden(true),
|
|
620
|
+
Class('dt-filter-check shrink-0'),
|
|
621
|
+
Xmlns('http://www.w3.org/2000/svg'),
|
|
622
|
+
Fill('none'),
|
|
623
|
+
ViewBox('0 0 24 24'),
|
|
624
|
+
StrokeWidth('2'),
|
|
625
|
+
Stroke('currentColor'),
|
|
626
|
+
], [
|
|
627
|
+
path([D(CHECK_ICON), StrokeLinecap('round'), StrokeLinejoin('round')], []),
|
|
628
|
+
]);
|
|
629
|
+
const filterItemLabel = (item) => String_.isNonEmpty(item) ? submodelLabel(item) : 'All Messages';
|
|
630
|
+
const submodelFilterView = (model) => {
|
|
631
|
+
const buttonLabel = Option.match(model.maybeSubmodelFilter, {
|
|
632
|
+
onNone: () => 'All Messages',
|
|
633
|
+
onSome: submodelLabel,
|
|
634
|
+
});
|
|
635
|
+
return Listbox.view({
|
|
636
|
+
model: model.submodelFilterListbox,
|
|
637
|
+
toParentMessage: message => GotSubmodelFilterMessage({ message }),
|
|
638
|
+
onSelectedItem: tag => SelectedSubmodelFilter({ tag }),
|
|
639
|
+
items: [ALL_MESSAGES_VALUE, ...model.submodelTags],
|
|
640
|
+
itemToConfig: item => ({
|
|
641
|
+
className: 'dt-filter-item',
|
|
642
|
+
content: div([Class('flex items-center gap-2')], [checkIconView, span([], [filterItemLabel(item)])]),
|
|
643
|
+
}),
|
|
644
|
+
buttonContent: span([Class('flex flex-1 items-center justify-between')], [
|
|
645
|
+
span([], [buttonLabel]),
|
|
646
|
+
svg([
|
|
647
|
+
AriaHidden(true),
|
|
648
|
+
Class('json-arrow shrink-0'),
|
|
649
|
+
Xmlns('http://www.w3.org/2000/svg'),
|
|
650
|
+
Fill('none'),
|
|
651
|
+
ViewBox('0 0 24 24'),
|
|
652
|
+
StrokeWidth('2'),
|
|
653
|
+
Stroke('currentColor'),
|
|
654
|
+
], [
|
|
655
|
+
path([
|
|
656
|
+
D(CHEVRON_DOWN),
|
|
657
|
+
StrokeLinecap('round'),
|
|
658
|
+
StrokeLinejoin('round'),
|
|
659
|
+
], []),
|
|
660
|
+
]),
|
|
661
|
+
]),
|
|
662
|
+
buttonClassName: 'dt-filter-button',
|
|
663
|
+
itemsClassName: 'dt-filter-items',
|
|
664
|
+
className: 'dt-filter-wrapper',
|
|
665
|
+
backdropClassName: 'dt-filter-backdrop',
|
|
666
|
+
});
|
|
667
|
+
};
|
|
555
668
|
const headerView = (model) => {
|
|
556
|
-
const { status,
|
|
669
|
+
const { status, maybeAction } = M.value(mode).pipe(M.withReturnType(), M.when('TimeTravel', () => model.isPaused
|
|
557
670
|
? {
|
|
558
671
|
status: span([Class(`${statusClass} text-dt-paused`)], [
|
|
559
672
|
model.pausedAtIndex === INIT_INDEX
|
|
560
673
|
? 'Paused (init)'
|
|
561
674
|
: `Paused (${model.pausedAtIndex + 1})`,
|
|
562
675
|
]),
|
|
563
|
-
|
|
676
|
+
maybeAction: Option.some(button([Class(actionButtonClass), OnClick(ClickedResume())], ['Resume →'])),
|
|
564
677
|
}
|
|
565
678
|
: {
|
|
566
679
|
status: span([Class(`${statusClass} text-dt-live font-medium`)], ['Live']),
|
|
567
|
-
|
|
680
|
+
maybeAction: Option.none(),
|
|
568
681
|
}), M.when('Inspect', () => ({
|
|
569
682
|
status: span([Class(`${statusClass} text-dt-accent`)], [
|
|
570
683
|
model.selectedIndex === INIT_INDEX
|
|
571
684
|
? 'Inspecting (init)'
|
|
572
685
|
: `Inspecting (${model.selectedIndex + 1})`,
|
|
573
686
|
]),
|
|
574
|
-
|
|
575
|
-
? div([], [])
|
|
576
|
-
: button([Class(actionButtonClass), OnClick(ClickedFollowLatest())], ['Follow Latest →']),
|
|
687
|
+
maybeAction: OptionExt.when(!model.isFollowingLatest, button([Class(actionButtonClass), OnClick(ClickedFollowLatest())], ['Follow Latest →'])),
|
|
577
688
|
})), M.exhaustive);
|
|
578
|
-
return header([Class(headerClass)], [status,
|
|
689
|
+
return header([Class(headerClass)], [status, ...Option.toArray(maybeAction), clearHistoryButton]);
|
|
579
690
|
};
|
|
580
691
|
const initRowView = (isSelected, isPausedHere) => keyed('li')('init', [
|
|
581
692
|
Class(clsx(ROW_BASE, { selected: isSelected })),
|
|
@@ -623,12 +734,21 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
623
734
|
: model.startIndex + model.entries.length - 1;
|
|
624
735
|
const selectedIndex = M.value(mode).pipe(M.when('TimeTravel', () => model.isPaused ? model.pausedAtIndex : lastIndex), M.when('Inspect', () => model.selectedIndex), M.exhaustive);
|
|
625
736
|
const isInitSelected = selectedIndex === INIT_INDEX;
|
|
626
|
-
const
|
|
627
|
-
|
|
737
|
+
const isFiltered = Option.isSome(model.maybeSubmodelFilter);
|
|
738
|
+
const indexedEntries = pipe(model.entries, Array_.map((entry, arrayIndex) => ({
|
|
739
|
+
entry,
|
|
740
|
+
absoluteIndex: model.startIndex + arrayIndex,
|
|
741
|
+
})), isFiltered
|
|
742
|
+
? Array_.filter(({ entry }) => Option.exists(model.maybeSubmodelFilter, Equal.equals(entry.tag)))
|
|
743
|
+
: Function.identity);
|
|
744
|
+
const messageRows = pipe(indexedEntries, Array_.map(({ entry, absoluteIndex }) => {
|
|
628
745
|
const isSelected = selectedIndex === absoluteIndex;
|
|
629
746
|
const isPausedHere = model.isPaused && model.pausedAtIndex === absoluteIndex;
|
|
747
|
+
const displayTag = isFiltered
|
|
748
|
+
? Option.getOrElse(entry.maybeInnerTag, () => entry.tag)
|
|
749
|
+
: entry.tag;
|
|
630
750
|
return lazyMessageRow(String(absoluteIndex), messageRowView, [
|
|
631
|
-
|
|
751
|
+
displayTag,
|
|
632
752
|
absoluteIndex,
|
|
633
753
|
isSelected,
|
|
634
754
|
isPausedHere,
|
|
@@ -636,10 +756,12 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
636
756
|
entry.isModelChanged,
|
|
637
757
|
]);
|
|
638
758
|
}), Array_.reverse);
|
|
639
|
-
return ul([Class('message-list flex-1 overflow-y-auto min-h-0 overscroll-none')],
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
759
|
+
return ul([Class('message-list flex-1 overflow-y-auto min-h-0 overscroll-none')], isFiltered
|
|
760
|
+
? messageRows
|
|
761
|
+
: [
|
|
762
|
+
...messageRows,
|
|
763
|
+
initRowView(isInitSelected, model.isPaused && model.pausedAtIndex === INIT_INDEX),
|
|
764
|
+
]);
|
|
643
765
|
};
|
|
644
766
|
// PANEL
|
|
645
767
|
const panelView = (model) => keyed('div')('dt-panel', [
|
|
@@ -650,7 +772,13 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
650
772
|
], [banner])).pipe(Option.toArray),
|
|
651
773
|
headerView(model),
|
|
652
774
|
div([Class('flex flex-1 min-h-0 dt-content')], [
|
|
653
|
-
div([Class('flex flex-col min-h-0 dt-message-pane')], [
|
|
775
|
+
div([Class('flex flex-col min-h-0 dt-message-pane')], [
|
|
776
|
+
...Array_.match(model.submodelTags, {
|
|
777
|
+
onEmpty: () => [],
|
|
778
|
+
onNonEmpty: () => [submodelFilterView(model)],
|
|
779
|
+
}),
|
|
780
|
+
messageListView(model),
|
|
781
|
+
]),
|
|
654
782
|
inspectorPaneView(model),
|
|
655
783
|
]),
|
|
656
784
|
]);
|
|
@@ -694,6 +822,12 @@ export const createOverlay = (store, position, mode, maybeBanner) => Effect.gen(
|
|
|
694
822
|
...flags,
|
|
695
823
|
selectedIndex: INIT_INDEX,
|
|
696
824
|
isFollowingLatest: true,
|
|
825
|
+
submodelTags: computeSubmodelTags(flags.entries),
|
|
826
|
+
maybeSubmodelFilter: Option.none(),
|
|
827
|
+
submodelFilterListbox: Listbox.init({
|
|
828
|
+
id: SUBMODEL_FILTER_ID,
|
|
829
|
+
selectedItem: ALL_MESSAGES_VALUE,
|
|
830
|
+
}),
|
|
697
831
|
maybeInspectedModel: Option.none(),
|
|
698
832
|
maybeInspectedMessage: Option.none(),
|
|
699
833
|
expandedPaths: HashSet.empty(),
|
package/dist/test/internal.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ export type AnyCommand = Readonly<{
|
|
|
4
4
|
name: string;
|
|
5
5
|
}>;
|
|
6
6
|
type UpdateResult<Model, OutMessage> = readonly [Model, ReadonlyArray<AnyCommand>] | readonly [Model, ReadonlyArray<AnyCommand>, OutMessage];
|
|
7
|
-
/** A Command definition
|
|
8
|
-
export type
|
|
9
|
-
CommandDefinition<
|
|
7
|
+
/** A Command definition with the result Message to resolve it with. */
|
|
8
|
+
export type Resolver<ResultMessage = unknown> = readonly [CommandDefinition<string, ResultMessage>, ResultMessage] | readonly [
|
|
9
|
+
CommandDefinition<string, ResultMessage>,
|
|
10
10
|
ResultMessage,
|
|
11
11
|
(message: ResultMessage) => unknown
|
|
12
12
|
];
|
|
@@ -21,6 +21,8 @@ export type BaseInternal<Model, Message, OutMessage = undefined> = Readonly<{
|
|
|
21
21
|
}>;
|
|
22
22
|
/** Resolves a single command by name and feeds its result through update. */
|
|
23
23
|
export declare const resolveByName: <Model, Message>(internal: BaseInternal<Model, Message, unknown>, commandName: string, resolverMessage: Message) => BaseInternal<Model, Message, unknown> | undefined;
|
|
24
|
+
/** Resolves all listed Commands, cascading through any Commands produced by the result. */
|
|
25
|
+
export declare const resolveAllInternal: <Model, Message, OutMessage>(internal: BaseInternal<Model, Message, OutMessage>, resolvers: ReadonlyArray<Resolver>) => BaseInternal<Model, Message, OutMessage>;
|
|
24
26
|
/** Throws if any of the given definitions are missing from the pending Commands. */
|
|
25
27
|
export declare const assertHasCommands: (commands: ReadonlyArray<AnyCommand>, definitions: ReadonlyArray<CommandDefinition<string, unknown>>) => void;
|
|
26
28
|
/** Throws if the pending Commands don't match the given definitions exactly (order-independent). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/test/internal.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEnD,KAAK,YAAY,CAAC,KAAK,EAAE,UAAU,IAC/B,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,GAC3C,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;AAE3D,
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/test/internal.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEnD,KAAK,YAAY,CAAC,KAAK,EAAE,UAAU,IAC/B,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,GAC3C,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;AAE3D,uEAAuE;AACvE,MAAM,MAAM,QAAQ,CAAC,aAAa,GAAG,OAAO,IACxC,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,GAClE,SAAS;IACP,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC;IACxC,aAAa;IACb,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO;CACpC,CAAA;AAEL,6EAA6E;AAC7E,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,IAAI,QAAQ,CAAC;IAC1E,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAC7E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC,CAAC,CAAA;AAEF,6EAA6E;AAC7E,eAAO,MAAM,aAAa,GAAI,KAAK,EAAE,OAAO,EAC1C,UAAU,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAC/C,aAAa,MAAM,EACnB,iBAAiB,OAAO,KACvB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,SAyBxC,CAAA;AAIH,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB,GAAI,KAAK,EAAE,OAAO,EAAE,UAAU,EAC3D,UAAU,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAClD,WAAW,aAAa,CAAC,QAAQ,CAAC,KACjC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CA+CzC,CAAA;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,GAC5B,UAAU,aAAa,CAAC,UAAU,CAAC,EACnC,aAAa,aAAa,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7D,IAwBF,CAAA;AAED,oGAAoG;AACpG,eAAO,MAAM,mBAAmB,GAC9B,UAAU,aAAa,CAAC,UAAU,CAAC,EACnC,aAAa,aAAa,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7D,IA6BF,CAAA;AAED,gDAAgD;AAChD,eAAO,MAAM,kBAAkB,GAC7B,UAAU,aAAa,CAAC,UAAU,CAAC,KAClC,IASF,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,0BAA0B,GACrC,UAAU,aAAa,CAAC,UAAU,CAAC,EACnC,SAAS,MAAM,KACd,IAcF,CAAA;AAED,wDAAwD;AACxD,eAAO,MAAM,yBAAyB,GACpC,UAAU,aAAa,CAAC,UAAU,CAAC,KAClC,IAcF,CAAA"}
|
package/dist/test/internal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array, Equivalence, Option, Order, pipe } from 'effect';
|
|
1
|
+
import { Array, Equivalence, Option, Order, Predicate, pipe } from 'effect';
|
|
2
2
|
/** Resolves a single command by name and feeds its result through update. */
|
|
3
3
|
export const resolveByName = (internal, commandName, resolverMessage) => pipe(internal.commands, Array.findFirstIndex(({ name }) => name === commandName), Option.match({
|
|
4
4
|
onNone: () => undefined,
|
|
@@ -17,6 +17,38 @@ export const resolveByName = (internal, commandName, resolverMessage) => pipe(in
|
|
|
17
17
|
};
|
|
18
18
|
},
|
|
19
19
|
}));
|
|
20
|
+
const MAX_CASCADE_DEPTH = 100;
|
|
21
|
+
/** Resolves all listed Commands, cascading through any Commands produced by the result. */
|
|
22
|
+
export const resolveAllInternal = (internal, resolvers) => {
|
|
23
|
+
const resolverMap = {};
|
|
24
|
+
for (const resolver of resolvers) {
|
|
25
|
+
const [definition, resultMessage] = resolver;
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
27
|
+
resolverMap[definition.name] = (resolver.length === 3 ? resolver[2](resultMessage) : resultMessage);
|
|
28
|
+
}
|
|
29
|
+
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
30
|
+
let current = {
|
|
31
|
+
...internal,
|
|
32
|
+
resolvers: { ...internal.resolvers, ...resolverMap },
|
|
33
|
+
};
|
|
34
|
+
for (let depth = 0; depth < MAX_CASCADE_DEPTH; depth++) {
|
|
35
|
+
const resolvable = current.commands.find(({ name }) => name in current.resolvers);
|
|
36
|
+
if (Predicate.isUndefined(resolvable)) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
const next = resolveByName(current, resolvable.name, current.resolvers[resolvable.name]);
|
|
40
|
+
if (Predicate.isUndefined(next)) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
current = next;
|
|
44
|
+
if (depth === MAX_CASCADE_DEPTH - 1) {
|
|
45
|
+
throw new Error('resolveAll hit the maximum cascade depth (100). ' +
|
|
46
|
+
'This usually means Commands are producing Commands in an infinite cycle.');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return current;
|
|
50
|
+
/* eslint-enable @typescript-eslint/consistent-type-assertions */
|
|
51
|
+
};
|
|
20
52
|
/** Throws if any of the given definitions are missing from the pending Commands. */
|
|
21
53
|
export const assertHasCommands = (commands, definitions) => {
|
|
22
54
|
const pendingNames = Array.map(commands, ({ name }) => name);
|
|
@@ -55,7 +87,7 @@ export const assertNoUnresolvedCommands = (commands, context) => {
|
|
|
55
87
|
throw new Error(`I found unresolved Commands ${context}:\n\n${names}\n\n` +
|
|
56
88
|
'Resolve all Commands before sending the next Message.\n' +
|
|
57
89
|
'Use resolve(Definition, ResultMessage) for each one,\n' +
|
|
58
|
-
'or resolveAll(...
|
|
90
|
+
'or resolveAll(...resolvers) to resolve them all at once.');
|
|
59
91
|
}
|
|
60
92
|
};
|
|
61
93
|
/** Throws when Commands remain at the end of a test. */
|
|
@@ -65,6 +97,6 @@ export const assertAllCommandsResolved = (commands) => {
|
|
|
65
97
|
throw new Error(`I found Commands without resolvers:\n\n${names}\n\n` +
|
|
66
98
|
'Every Command produced by update needs to be resolved.\n' +
|
|
67
99
|
'Use resolve(Definition, ResultMessage) for each one,\n' +
|
|
68
|
-
'or resolveAll(...
|
|
100
|
+
'or resolveAll(...resolvers) to resolve them all at once.');
|
|
69
101
|
}
|
|
70
102
|
};
|
package/dist/test/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/test/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,MAAM,EAMP,MAAM,QAAQ,CAAA;AAIf,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC,KAAK,SAAS,GAAG,OAAO,GAAG,YAAY,CAAA;AAEvC,KAAK,gBAAgB,GAAG,QAAQ,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5B,IAAI,EAAE,SAAS,CAAA;CAChB,CAAC,CAAA;AAEF,KAAK,cAAc,GAAG,QAAQ,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1B,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACzB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC9B,UAAU,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;CAC5C,CAAC,CAAA;AAEF,KAAK,QAAQ,GAAG,aAAa,CAAC,cAAc,CAAC,CAAA;AAmI7C,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,QAc7C,CAAA;AAqCD;;kEAEkE;AAClE,eAAO,MAAM,WAAW,GACtB,MAAM,KAAK,EACX,QAAQ,KAAK,KACZ,aAAa,CAAC,KAAK,CAiBrB,CAAA;AAyND;kFACkF;AAClF,eAAO,MAAM,cAAc,GACxB,MAAM,KAAK,MACX,OAAO,KAAK,KAAG,MASb,CAAA;AAEL;sEACsE;AACtE,eAAO,MAAM,qBAAqB,GAC/B,MAAM,KAAK,MACX,OAAO,KAAK,KAAG,MAab,CAAA;AA6BL,uDAAuD;AACvD,eAAO,MAAM,IAAI,EAAE;IACjB,CAAC,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC3D,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;CAKhE,CAAA;AAED,kDAAkD;AAClD,eAAO,MAAM,OAAO,EAAE;IACpB,CAAC,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAC3D,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC,CAAA;CAGhE,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,MAU1C,CAAA;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/test/query.ts"],"names":[],"mappings":"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"}
|
package/dist/test/query.js
CHANGED
|
@@ -184,6 +184,9 @@ export const textContent = (vnode) => {
|
|
|
184
184
|
return vnode.text;
|
|
185
185
|
return pipe(vnode.children ?? [], Array.map(child => Predicate.isString(child) ? child : textContent(child)), Array.join(''));
|
|
186
186
|
};
|
|
187
|
+
const hasDirectTextNodeMatch = (node, target) => Array.some(node.children ?? [], child => Predicate.isString(child)
|
|
188
|
+
? child === target
|
|
189
|
+
: !isElement(child) && textContent(child) === target);
|
|
187
190
|
const attrImpl = (vnode, name) => {
|
|
188
191
|
if (name === 'class') {
|
|
189
192
|
return pipe(vnode.data?.class, Option.fromNullable, Option.map(flow(Record.toEntries, Array.filter(([, isActive]) => isActive), Array.map(([className]) => className), Array.join(' '))), Option.filter(String_.isNonEmpty));
|
|
@@ -271,7 +274,9 @@ export const getByText = (target, options) => (html) => {
|
|
|
271
274
|
const exact = options?.exact !== false;
|
|
272
275
|
const textMatches = (node) => {
|
|
273
276
|
const nodeText = textContent(node);
|
|
274
|
-
return exact
|
|
277
|
+
return exact
|
|
278
|
+
? nodeText === target || hasDirectTextNodeMatch(node, target)
|
|
279
|
+
: String_.includes(target)(nodeText);
|
|
275
280
|
};
|
|
276
281
|
return pipe(allNodesIn(html), Array.filter(node => isElement(node) && textMatches(node)), Array.findFirst(match => !Array.some(Array.filter(collectDescendants(match), isElement), textMatches)));
|
|
277
282
|
};
|
|
@@ -311,7 +316,9 @@ export const getAllByText = (target, options) => (html) => {
|
|
|
311
316
|
if (!isElement(node))
|
|
312
317
|
return false;
|
|
313
318
|
const nodeText = textContent(node);
|
|
314
|
-
return exact
|
|
319
|
+
return exact
|
|
320
|
+
? nodeText === target || hasDirectTextNodeMatch(node, target)
|
|
321
|
+
: String_.includes(target)(nodeText);
|
|
315
322
|
});
|
|
316
323
|
};
|
|
317
324
|
/** Finds all elements with the given placeholder attribute. */
|