@picked/svelte 0.0.1-dev.1789541668638 → 0.0.1-dev.1793756239746
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/LICENSE +1 -0
- package/README.md +51 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/_virtual/_vite/preload-helper.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/experience/ExperienceHost.svelte +29 -13
- package/dist/experience/ExperienceSlot.svelte +21 -3
- package/dist/experience/ExperienceWrapper.svelte +23 -0
- package/dist/form/index.js +1 -1
- package/dist/hooks/action.d.ts +47 -18
- package/dist/hooks/action.js +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/step.d.ts +14 -0
- package/dist/hooks/step.js +1 -1
- package/dist/plugins/devtools/DevToolsExperience.svelte +545 -203
- package/dist/plugins/devtools/components/AdaptedToolHost.svelte +2 -2
- package/dist/plugins/devtools/constants.d.ts +5 -0
- package/dist/plugins/devtools/constants.js +1 -0
- package/dist/plugins/devtools/customTools.d.ts +42 -6
- package/dist/plugins/devtools/customTools.js +1 -1
- package/dist/plugins/devtools/derive/answer-display/answer-display.d.ts +112 -0
- package/dist/plugins/devtools/derive/answer-display/answer-display.js +1 -0
- package/dist/plugins/devtools/derive/answer-display/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/answer-display/index.js +1 -0
- package/dist/plugins/devtools/derive/answer-history/answer-history.d.ts +76 -0
- package/dist/plugins/devtools/derive/answer-history/answer-history.js +1 -0
- package/dist/plugins/devtools/derive/answer-history/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/answer-history/index.js +1 -0
- package/dist/plugins/devtools/derive/guide-sections/guide-sections.d.ts +67 -0
- package/dist/plugins/devtools/derive/guide-sections/guide-sections.js +1 -0
- package/dist/plugins/devtools/derive/guide-sections/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/guide-sections/index.js +1 -0
- package/dist/plugins/devtools/derive/index.d.ts +28 -0
- package/dist/plugins/devtools/derive/index.js +1 -0
- package/dist/plugins/devtools/derive/journey-outline/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/journey-outline/index.js +1 -0
- package/dist/plugins/devtools/derive/journey-outline/journey-outline.d.ts +86 -0
- package/dist/plugins/devtools/derive/journey-outline/journey-outline.js +1 -0
- package/dist/plugins/devtools/derive/journey-pick/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/journey-pick/index.js +1 -0
- package/dist/plugins/devtools/derive/journey-pick/journey-pick.d.ts +73 -0
- package/dist/plugins/devtools/derive/journey-pick/journey-pick.js +1 -0
- package/dist/plugins/devtools/derive/journey-timeline/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/journey-timeline/index.js +1 -0
- package/dist/plugins/devtools/derive/journey-timeline/journey-timeline.d.ts +70 -0
- package/dist/plugins/devtools/derive/journey-timeline/journey-timeline.js +1 -0
- package/dist/plugins/devtools/derive/journey-tree/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/journey-tree/index.js +1 -0
- package/dist/plugins/devtools/derive/journey-tree/journey-tree.d.ts +191 -0
- package/dist/plugins/devtools/derive/journey-tree/journey-tree.js +1 -0
- package/dist/plugins/devtools/derive/plain-language/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/plain-language/index.js +1 -0
- package/dist/plugins/devtools/derive/plain-language/plain-language.d.ts +73 -0
- package/dist/plugins/devtools/derive/plain-language/plain-language.js +1 -0
- package/dist/plugins/devtools/derive/plain-logic/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/plain-logic/index.js +1 -0
- package/dist/plugins/devtools/derive/plain-logic/plain-logic.d.ts +48 -0
- package/dist/plugins/devtools/derive/plain-logic/plain-logic.js +1 -0
- package/dist/plugins/devtools/derive/safety-posture/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/safety-posture/index.js +1 -0
- package/dist/plugins/devtools/derive/safety-posture/safety-posture.d.ts +43 -0
- package/dist/plugins/devtools/derive/safety-posture/safety-posture.js +1 -0
- package/dist/plugins/devtools/derive/visited-steps/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/visited-steps/index.js +1 -0
- package/dist/plugins/devtools/derive/visited-steps/visited-steps.d.ts +35 -0
- package/dist/plugins/devtools/derive/visited-steps/visited-steps.js +1 -0
- package/dist/plugins/devtools/derive/walk-route/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/walk-route/index.js +1 -0
- package/dist/plugins/devtools/derive/walk-route/walk-route.d.ts +22 -0
- package/dist/plugins/devtools/derive/walk-route/walk-route.js +1 -0
- package/dist/plugins/devtools/index.d.ts +5 -2
- package/dist/plugins/devtools/index.js +1 -1
- package/dist/plugins/devtools/launcher/Launcher.svelte +150 -0
- package/dist/plugins/devtools/launcher/launcher.d.ts +36 -0
- package/dist/plugins/devtools/launcher/launcher.js +1 -0
- package/dist/plugins/devtools/options.d.ts +106 -0
- package/dist/plugins/devtools/options.js +1 -0
- package/dist/plugins/devtools/plugin.d.ts +8 -8
- package/dist/plugins/devtools/plugin.js +1 -1
- package/dist/plugins/devtools/posture-context.d.ts +15 -0
- package/dist/plugins/devtools/posture-context.js +1 -0
- package/dist/plugins/devtools/review/answers/AnswersPanel.svelte +526 -0
- package/dist/plugins/devtools/review/guide/GuideLine.svelte +20 -0
- package/dist/plugins/devtools/review/guide/GuidePanel.svelte +133 -0
- package/dist/plugins/devtools/review/index.d.ts +6 -0
- package/dist/plugins/devtools/review/index.js +1 -0
- package/dist/plugins/devtools/review/journey/JourneyMap.svelte +1078 -0
- package/dist/plugins/devtools/review/journey/JourneyPanel.svelte +608 -0
- package/dist/plugins/devtools/review/journey/JourneyTimeline.svelte +756 -0
- package/dist/plugins/devtools/review/journey/TimelineMarker.svelte +59 -0
- package/dist/plugins/devtools/review/session/SessionPanel.svelte +214 -0
- package/dist/plugins/devtools/review/variations/VariationsPanel.svelte +279 -0
- package/dist/plugins/devtools/screens/config/ConfigScreen.svelte +6 -0
- package/dist/plugins/devtools/screens/custom-tools/CustomToolsScreen.svelte +3 -3
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +6 -0
- package/dist/plugins/devtools/session/index.d.ts +3 -0
- package/dist/plugins/devtools/session/index.js +1 -0
- package/dist/plugins/devtools/session/session.d.ts +90 -0
- package/dist/plugins/devtools/session/session.js +1 -0
- package/dist/plugins/devtools/session-access.d.ts +32 -0
- package/dist/plugins/devtools/session-access.js +1 -0
- package/dist/plugins/devtools/sidebar/Sidebar.svelte +105 -0
- package/dist/plugins/devtools/sidebar/SidebarRow.svelte +117 -0
- package/dist/plugins/devtools/sidebar/nav.d.ts +105 -0
- package/dist/plugins/devtools/sidebar/nav.js +1 -0
- package/dist/plugins/devtools/ui/actions/Button.svelte +10 -1
- package/dist/plugins/devtools/ui/actions/CopyButton.svelte +13 -1
- package/dist/plugins/devtools/ui/data/Badge.svelte +3 -2
- package/dist/plugins/devtools/ui/data/EmptyState.svelte +16 -1
- package/dist/plugins/devtools/ui/feedback/Banner.svelte +3 -2
- package/dist/plugins/framework/index.js +1 -1
- package/dist/render/browser.js +1 -1
- package/package.json +23 -12
- package/dist/form/__tests__/CreateFormHarness.svelte +0 -30
- package/dist/hooks/events.d.ts +0 -2
- package/dist/hooks/events.js +0 -1
- package/dist/vite-env.d.js +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Event, Store } from 'effector';
|
|
2
|
+
import type { AskedNode, AskedStep, HistoryEntry, HistoryEvent, InstanceLike, OpenOrderEvent, RouteEntry, Trails, VisitedEvent } from '../derive';
|
|
3
|
+
/** The event shapes read off the bus: every reducer's together. */
|
|
4
|
+
export type BusEvent = VisitedEvent & HistoryEvent & OpenOrderEvent;
|
|
5
|
+
/** An experience instance, as far as this model reads one. */
|
|
6
|
+
export interface SessionInstance extends InstanceLike {
|
|
7
|
+
goToStepByKey: (key: string) => unknown;
|
|
8
|
+
}
|
|
9
|
+
/** The slice of the `Picked` client this model reads, narrowed so tests can build it from units. */
|
|
10
|
+
export interface SessionClient {
|
|
11
|
+
eventBus: Event<BusEvent>;
|
|
12
|
+
responses: {
|
|
13
|
+
getAllStore: Store<Readonly<Record<string, unknown>>>;
|
|
14
|
+
};
|
|
15
|
+
steps: {
|
|
16
|
+
listStore: Store<readonly AskedStep[]>;
|
|
17
|
+
};
|
|
18
|
+
experiences: {
|
|
19
|
+
listStore: Store<readonly {
|
|
20
|
+
treeStore: Store<{
|
|
21
|
+
nodes: readonly AskedNode[];
|
|
22
|
+
}>;
|
|
23
|
+
}[]>;
|
|
24
|
+
};
|
|
25
|
+
experienceInstances: {
|
|
26
|
+
listStore: Store<readonly SessionInstance[]>;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** The host's say on what the session model reads. */
|
|
30
|
+
export interface SessionOptions {
|
|
31
|
+
/** Experience keys never picked as the journey: the devtools themselves, and any the host hides. */
|
|
32
|
+
exclude: ReadonlySet<string>;
|
|
33
|
+
/** Experience keys, topmost first, that win the journey pick whenever they are open. */
|
|
34
|
+
precedence: readonly string[];
|
|
35
|
+
/** Keys a screen carries only for its code; never an answer the reviewer gave. */
|
|
36
|
+
codeOwned: ReadonlySet<string>;
|
|
37
|
+
}
|
|
38
|
+
/** The journey in front of the reviewer, and where in it the visitor is. */
|
|
39
|
+
export interface JourneyView {
|
|
40
|
+
experienceKey: string;
|
|
41
|
+
experienceName: string;
|
|
42
|
+
stepKey: string | null;
|
|
43
|
+
stepName: string | null;
|
|
44
|
+
/**
|
|
45
|
+
* The engine is transiting a condition or action node, so the recorded step is the one just
|
|
46
|
+
* LEFT. Panels say so rather than naming a screen the visitor has already gone past.
|
|
47
|
+
*/
|
|
48
|
+
inTransit: boolean;
|
|
49
|
+
goToStepByKey: (key: string) => void;
|
|
50
|
+
}
|
|
51
|
+
/** The session model the review panels read. */
|
|
52
|
+
export interface SessionData {
|
|
53
|
+
/** Screens entered this session, per journey. */
|
|
54
|
+
trailsStore: Store<Trails>;
|
|
55
|
+
/** What the visitor answered, screen by screen. */
|
|
56
|
+
historyStore: Store<readonly HistoryEntry[]>;
|
|
57
|
+
/** Every screen moved on from, field-less ones too. */
|
|
58
|
+
routeStore: Store<readonly RouteEntry[]>;
|
|
59
|
+
/** Every field a journey's screens ask, minus the code-owned ones. */
|
|
60
|
+
askedStore: Store<ReadonlySet<string>>;
|
|
61
|
+
/** Instance ids in the order they opened, oldest first. */
|
|
62
|
+
openOrderStore: Store<readonly string[]>;
|
|
63
|
+
/** The journey in front, re-read as the visitor moves. */
|
|
64
|
+
journeyStore: Store<JourneyView | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Re-reads the journey now. The engine's transit through a condition or action moves no list
|
|
67
|
+
* and fires no `step_enter`, so a panel re-reads as it opens rather than show a stale position.
|
|
68
|
+
*/
|
|
69
|
+
refreshJourney: () => void;
|
|
70
|
+
/** Clears every unit this model made, leaving the SDK's own units working. */
|
|
71
|
+
destroy: () => void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Builds the session model over a client, inside one region.
|
|
75
|
+
*
|
|
76
|
+
* The current STEP lives in a store on the instance and moves without the instance list changing,
|
|
77
|
+
* which is why the bus is a clock for the journey too.
|
|
78
|
+
*
|
|
79
|
+
* @param {SessionClient} client - The Picked client, or any object with the same units.
|
|
80
|
+
* @param {SessionOptions} options - Which experiences to skip, which sit on top, and which keys are code-owned.
|
|
81
|
+
* @returns {SessionData} The stores the panels read, and the model's teardown.
|
|
82
|
+
* @example
|
|
83
|
+
* const session = createSessionData(client, {
|
|
84
|
+
* exclude: new Set(['devtools']),
|
|
85
|
+
* precedence: ['checkout-modal'],
|
|
86
|
+
* codeOwned: new Set(['quote_response']),
|
|
87
|
+
* })
|
|
88
|
+
* onDestroy(session.destroy)
|
|
89
|
+
*/
|
|
90
|
+
export declare function createSessionData(client: SessionClient, options: SessionOptions): SessionData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{askedFieldKeys as e}from"../derive/answer-display/answer-display.js";import{nextHistory as t}from"../derive/answer-history/answer-history.js";import{nextOpenOrder as n,pickJourney as r}from"../derive/journey-pick/journey-pick.js";import{nextTrails as i}from"../derive/visited-steps/visited-steps.js";import{nextRoute as a}from"../derive/walk-route/walk-route.js";import"../derive/index.js";import{clearNode as o,combine as s,createEvent as c,createNode as l,createStore as u,sample as d,withRegion as f}from"effector";var p=new Set([`step_enter`,`experience_open`,`experience_close`]);function m(m,h){let g=l(),_=[],v=(e,t)=>{let n=r(e,{exclude:h.exclude,precedence:h.precedence,openOrder:t});if(n===void 0)return null;let i=n.currentStepStore.getState(),a=n.currentNodeStore.getState();return{experienceKey:n.experienceKey,experienceName:n.experienceName,stepKey:i?.key??null,stepName:i?.name??null,inTransit:a!==null&&a.type!==`step`,goToStepByKey:e=>{n.goToStepByKey(e)}}};return{...f(g,()=>{let r=m.eventBus,o=u(new Map).on(r,i),l=u([]);d({clock:r,source:{history:l,responses:m.responses.getAllStore},fn:({history:e,responses:n},r)=>t(e,n,r,h.codeOwned),target:l});let f=u([]);d({clock:r,source:{route:f,responses:m.responses.getAllStore},fn:({route:e,responses:t},n)=>a(e,t,n,h.codeOwned),target:f});let g=c(),y=e=>e.map(e=>e.treeStore.getState().nodes),b=u(y(m.experiences.listStore.getState()));d({clock:[m.experiences.listStore,g],source:m.experiences.listStore,fn:y,target:b}),m.experiences.listStore.watch(e=>{for(let e of _)e.unsubscribe();_=e.map(e=>e.treeStore.updates.watch(g))});let x=s(m.steps.listStore,b,(t,n)=>e(t,n,h.codeOwned)),S=u([]).on(r,n),C=d({clock:r,filter:e=>p.has(e.type)}),w=c(),T=u(v(m.experienceInstances.listStore.getState(),S.getState()));return d({clock:[m.experienceInstances.listStore,S,C,w],source:{instances:m.experienceInstances.listStore,openOrder:S},fn:({instances:e,openOrder:t})=>v(e,t),target:T}),{trailsStore:o,historyStore:l,routeStore:f,askedStore:x,openOrderStore:S,journeyStore:T,refreshJourney:w}}),destroy:()=>{for(let e of _)e.unsubscribe();_=[],o(g)}}}export{m as createSessionData};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @file Hands the devtools session record and posture to custom tools, per client. */
|
|
2
|
+
import type { Picked } from '@picked/client';
|
|
3
|
+
import type { SafetyPosture } from './derive';
|
|
4
|
+
import type { SessionData } from './session';
|
|
5
|
+
/** What a custom tool can read about the session the devtools are recording. */
|
|
6
|
+
export interface DevtoolsSession {
|
|
7
|
+
/** The session record's stores: the trail, the answer history, the route, the open journey. */
|
|
8
|
+
session: Omit<SessionData, 'destroy'>;
|
|
9
|
+
/** What this session may do; a read-only session must not write. */
|
|
10
|
+
posture: SafetyPosture;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reads the session the devtools panel is recording for a client.
|
|
14
|
+
*
|
|
15
|
+
* @param {Pick<Picked, 'getPluginConfig'>} client - The client the devtools plugin is registered on.
|
|
16
|
+
* @returns {DevtoolsSession | null} The session and posture, or `null` before the devtools mount.
|
|
17
|
+
* @example
|
|
18
|
+
* const devtools = getDevtoolsSession(getPicked())
|
|
19
|
+
* const route = devtools?.session.routeStore.getState() ?? []
|
|
20
|
+
*/
|
|
21
|
+
export declare function getDevtoolsSession(client: Pick<Picked, 'getPluginConfig'>): DevtoolsSession | null;
|
|
22
|
+
/**
|
|
23
|
+
* Publishes the devtools session for a client until the returned release runs.
|
|
24
|
+
*
|
|
25
|
+
* @param {Pick<Picked, 'getPluginConfig'>} client - The client the session belongs to.
|
|
26
|
+
* @param {DevtoolsSession} value - The session and posture.
|
|
27
|
+
* @returns {() => void} Release: removes the session if it is still the one published.
|
|
28
|
+
* @example
|
|
29
|
+
* const release = provideDevtoolsSession(client, { session, posture })
|
|
30
|
+
* release()
|
|
31
|
+
*/
|
|
32
|
+
export declare function provideDevtoolsSession(client: Pick<Picked, 'getPluginConfig'>, value: DevtoolsSession): () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=new WeakMap;function t(t){return e.get(t)??null}function n(t,n){return e.set(t,n),()=>{e.get(t)===n&&e.delete(t)}}export{t as getDevtoolsSession,n as provideDevtoolsSession};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@paired-component apps/dashboard/src/shared/ui/navigation/sidebar-row-classes.ts
|
|
3
|
+
@design-parity A row mirrors the Dashboard sidebar row: 28px high, text-sm, rounded-md, a 10%
|
|
4
|
+
current-colour fill when selected and 5% on hover, a label that fades out instead of wrapping.
|
|
5
|
+
The Developer row mirrors the Dashboard's folding nav group (sidebar-nav-group.tsx).
|
|
6
|
+
-->
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
/** @file The devtools sidebar: the review tabs, then the folding Developer group. */
|
|
9
|
+
import { DEVELOPER_LABEL } from '../derive/plain-language'
|
|
10
|
+
import type { NavModel } from './nav'
|
|
11
|
+
import { nextFocusIndex } from './nav'
|
|
12
|
+
import SidebarRow from './SidebarRow.svelte'
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
nav: NavModel
|
|
16
|
+
/** The selected tab's id. */
|
|
17
|
+
selected: string
|
|
18
|
+
/** Whether the Developer group lists its screens. */
|
|
19
|
+
developerOpen: boolean
|
|
20
|
+
onSelect: (id: string) => void
|
|
21
|
+
onToggleDeveloper: () => void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { nav, selected, developerOpen, onSelect, onToggleDeveloper }: Props = $props()
|
|
25
|
+
|
|
26
|
+
let list: HTMLElement | undefined = $state()
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Moves focus between visible rows on Up, Down, Home and End.
|
|
30
|
+
*
|
|
31
|
+
* @param {KeyboardEvent} event - The key pressed inside the sidebar.
|
|
32
|
+
* @example onKeydown(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
|
33
|
+
*/
|
|
34
|
+
function onKeydown(event: KeyboardEvent): void {
|
|
35
|
+
if (list === undefined) return
|
|
36
|
+
const buttons = Array.from(list.querySelectorAll('button[data-nav-row]')).filter(
|
|
37
|
+
(node): node is HTMLButtonElement => node instanceof HTMLButtonElement,
|
|
38
|
+
)
|
|
39
|
+
const index = buttons.findIndex((button) => button === event.target)
|
|
40
|
+
if (index === -1) return
|
|
41
|
+
const next = nextFocusIndex(event.key, index, buttons.length)
|
|
42
|
+
if (next === null) return
|
|
43
|
+
event.preventDefault()
|
|
44
|
+
buttons[next]?.focus()
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<nav class="sidebar" aria-label="Devtools" data-testid="devtools-sidebar">
|
|
49
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
50
|
+
<ul bind:this={list} class="rows" onkeydown={onKeydown}>
|
|
51
|
+
{#each nav.primary as item (item.id)}
|
|
52
|
+
<SidebarRow
|
|
53
|
+
label={item.label}
|
|
54
|
+
testId="devtools-nav-{item.id}"
|
|
55
|
+
depth={0}
|
|
56
|
+
selected={selected === item.id}
|
|
57
|
+
onPress={() => onSelect(item.id)}
|
|
58
|
+
/>
|
|
59
|
+
{/each}
|
|
60
|
+
<li class="divider" role="presentation"></li>
|
|
61
|
+
<SidebarRow
|
|
62
|
+
label={DEVELOPER_LABEL}
|
|
63
|
+
testId="devtools-nav-developer"
|
|
64
|
+
depth={0}
|
|
65
|
+
expanded={developerOpen}
|
|
66
|
+
onPress={onToggleDeveloper}
|
|
67
|
+
/>
|
|
68
|
+
{#if developerOpen}
|
|
69
|
+
{#each nav.developer as item (item.id)}
|
|
70
|
+
<SidebarRow
|
|
71
|
+
label={item.label}
|
|
72
|
+
testId="devtools-nav-{item.id}"
|
|
73
|
+
depth={2}
|
|
74
|
+
selected={selected === item.id}
|
|
75
|
+
onPress={() => onSelect(item.id)}
|
|
76
|
+
/>
|
|
77
|
+
{/each}
|
|
78
|
+
{/if}
|
|
79
|
+
</ul>
|
|
80
|
+
</nav>
|
|
81
|
+
|
|
82
|
+
<style>
|
|
83
|
+
.sidebar {
|
|
84
|
+
height: 100%;
|
|
85
|
+
overflow-y: auto;
|
|
86
|
+
padding: var(--space-2);
|
|
87
|
+
background-color: var(--color-white);
|
|
88
|
+
color: var(--color-gray-900);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.rows {
|
|
92
|
+
list-style: none;
|
|
93
|
+
margin: 0;
|
|
94
|
+
padding: 0;
|
|
95
|
+
display: flex;
|
|
96
|
+
flex-direction: column;
|
|
97
|
+
gap: 1px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.divider {
|
|
101
|
+
height: 1px;
|
|
102
|
+
margin: var(--space-2) 0;
|
|
103
|
+
background-color: var(--color-gray-200);
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/** @file One row of the devtools sidebar: a tab, or the disclosure that folds the Developer group. */
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
label: string
|
|
6
|
+
testId: string
|
|
7
|
+
/** Indent depth: 0 for a top-level row, 2 for a screen inside the Developer group. */
|
|
8
|
+
depth: 0 | 2
|
|
9
|
+
onPress: () => void
|
|
10
|
+
/** A tab row: whether it is the selected tab. */
|
|
11
|
+
selected?: boolean
|
|
12
|
+
/** A disclosure row: whether its group is open. Renders the chevron. */
|
|
13
|
+
expanded?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { label, testId, depth, onPress, selected = false, expanded }: Props = $props()
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<li>
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
class="row depth-{depth}"
|
|
23
|
+
class:active={selected}
|
|
24
|
+
aria-current={selected ? 'page' : undefined}
|
|
25
|
+
aria-expanded={expanded}
|
|
26
|
+
data-nav-row
|
|
27
|
+
data-testid={testId}
|
|
28
|
+
onclick={onPress}
|
|
29
|
+
>
|
|
30
|
+
{#if expanded !== undefined}
|
|
31
|
+
<span class="icon" class:open={expanded} aria-hidden="true">
|
|
32
|
+
<svg width="12" height="12" viewBox="0 0 16 16" fill="none">
|
|
33
|
+
<path
|
|
34
|
+
d="M6 4l4 4-4 4"
|
|
35
|
+
stroke="currentColor"
|
|
36
|
+
stroke-width="1.5"
|
|
37
|
+
stroke-linecap="round"
|
|
38
|
+
stroke-linejoin="round"
|
|
39
|
+
/>
|
|
40
|
+
</svg>
|
|
41
|
+
</span>
|
|
42
|
+
{/if}
|
|
43
|
+
<span class="label">{label}</span>
|
|
44
|
+
</button>
|
|
45
|
+
</li>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
.row {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: var(--space-2);
|
|
52
|
+
width: 100%;
|
|
53
|
+
min-width: 0;
|
|
54
|
+
height: 28px;
|
|
55
|
+
padding: 0 var(--space-2);
|
|
56
|
+
border: 0;
|
|
57
|
+
border-radius: var(--radius-md);
|
|
58
|
+
background: none;
|
|
59
|
+
font: inherit;
|
|
60
|
+
font-size: var(--text-sm);
|
|
61
|
+
color: color-mix(in srgb, currentColor 80%, transparent);
|
|
62
|
+
text-align: left;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
transition:
|
|
65
|
+
background-color 0.15s ease,
|
|
66
|
+
color 0.15s ease;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.row.depth-2 {
|
|
70
|
+
padding-left: var(--space-5);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.row:hover {
|
|
74
|
+
color: var(--color-gray-900);
|
|
75
|
+
background-color: color-mix(in srgb, currentColor 5%, transparent);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.row.active {
|
|
79
|
+
color: var(--color-gray-900);
|
|
80
|
+
background-color: color-mix(in srgb, currentColor 10%, transparent);
|
|
81
|
+
font-weight: var(--font-medium);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.row:focus-visible {
|
|
85
|
+
outline: 2px solid currentColor;
|
|
86
|
+
outline-offset: -2px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.icon {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
width: 16px;
|
|
95
|
+
height: 16px;
|
|
96
|
+
transition: transform 0.15s ease;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.icon.open {
|
|
100
|
+
transform: rotate(90deg);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.label {
|
|
104
|
+
flex: 1;
|
|
105
|
+
min-width: 0;
|
|
106
|
+
overflow: hidden;
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@media (prefers-reduced-motion: reduce) {
|
|
112
|
+
.row,
|
|
113
|
+
.icon {
|
|
114
|
+
transition: none;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
</style>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/** @file The devtools sidebar's tab list, its remembered tab, and its keyboard moves. */
|
|
2
|
+
import type { StorageGetter } from '../launcher/launcher';
|
|
3
|
+
/** What a sidebar row opens: a review tab, a review-placed custom tool, or a developer screen. */
|
|
4
|
+
export type NavKind = 'review' | 'tool' | 'developer';
|
|
5
|
+
/** One row of the sidebar. */
|
|
6
|
+
export interface NavItem {
|
|
7
|
+
/** Unique across the whole sidebar. */
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
kind: NavKind;
|
|
11
|
+
}
|
|
12
|
+
/** The sidebar's rows: the top-level tabs, and the Developer group's screens. */
|
|
13
|
+
export interface NavModel {
|
|
14
|
+
primary: readonly NavItem[];
|
|
15
|
+
developer: readonly NavItem[];
|
|
16
|
+
}
|
|
17
|
+
/** `sessionStorage` key holding the selected tab's id. */
|
|
18
|
+
export declare const TAB_STORAGE_KEY = "picked-devtools-tab";
|
|
19
|
+
/** `sessionStorage` key holding `'true'` while the Developer group is open. */
|
|
20
|
+
export declare const DEVELOPER_OPEN_STORAGE_KEY = "picked-devtools-developer-open";
|
|
21
|
+
/** The tab a first open lands on, and where a vanished tab falls back to. */
|
|
22
|
+
export declare const DEFAULT_TAB = "guide";
|
|
23
|
+
/** The developer screens, in the order the Developer group lists them. */
|
|
24
|
+
export declare const DEVELOPER_SCREENS: readonly {
|
|
25
|
+
id: string;
|
|
26
|
+
label: string;
|
|
27
|
+
}[];
|
|
28
|
+
/**
|
|
29
|
+
* The sidebar id of a review-placed custom tool.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} toolId - The tool's registered id.
|
|
32
|
+
* @returns {string} Its tab id, prefixed so it never collides with a review tab.
|
|
33
|
+
* @example toolTabId('customers') // 'tool:customers'
|
|
34
|
+
*/
|
|
35
|
+
export declare function toolTabId(toolId: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* The sidebar id of a developer screen.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} screenId - The screen's id in {@link DEVELOPER_SCREENS}.
|
|
40
|
+
* @returns {string} Its tab id, prefixed so it never collides with a review tab.
|
|
41
|
+
* @example developerTabId('responses') // 'dev:responses'
|
|
42
|
+
*/
|
|
43
|
+
export declare function developerTabId(screenId: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Builds the sidebar's rows.
|
|
46
|
+
*
|
|
47
|
+
* @param {{ variations: boolean, tools: readonly { id: string, label: string }[] }} input - What this session lists.
|
|
48
|
+
* @param {boolean} input.variations - Whether the workspace publishes a feature, which lists Variations.
|
|
49
|
+
* @param {readonly { id: string, label: string }[]} input.tools - The review-placed custom tools, in registration order.
|
|
50
|
+
* @returns {NavModel} The top-level tabs and the Developer group's screens.
|
|
51
|
+
* @example buildNav({ variations: true, tools: [] })
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildNav(input: {
|
|
54
|
+
variations: boolean;
|
|
55
|
+
tools: readonly {
|
|
56
|
+
id: string;
|
|
57
|
+
label: string;
|
|
58
|
+
}[];
|
|
59
|
+
}): NavModel;
|
|
60
|
+
/**
|
|
61
|
+
* The tab to open: the stored one while it is listed, else How to use.
|
|
62
|
+
*
|
|
63
|
+
* @param {string | null} stored - The stored tab id.
|
|
64
|
+
* @param {NavModel} nav - The sidebar's rows.
|
|
65
|
+
* @returns {string} The tab id to select.
|
|
66
|
+
* @example resolveTab('journey', nav) // 'journey'
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveTab(stored: string | null, nav: NavModel): string;
|
|
69
|
+
/**
|
|
70
|
+
* Whether a tab sits inside the Developer group.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} tab - A tab id.
|
|
73
|
+
* @param {NavModel} nav - The sidebar's rows.
|
|
74
|
+
* @returns {boolean} `true` for a developer screen.
|
|
75
|
+
* @example isInDeveloper('dev:events', nav) // true
|
|
76
|
+
*/
|
|
77
|
+
export declare function isInDeveloper(tab: string, nav: NavModel): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Where a key moves focus among the sidebar's visible rows.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} key - The `KeyboardEvent.key`.
|
|
82
|
+
* @param {number} index - The focused row's index.
|
|
83
|
+
* @param {number} count - How many rows are visible.
|
|
84
|
+
* @returns {number | null} The row to focus, or `null` for a key the sidebar does not handle.
|
|
85
|
+
* @example nextFocusIndex('ArrowDown', 0, 3) // 1
|
|
86
|
+
*/
|
|
87
|
+
export declare function nextFocusIndex(key: string, index: number, count: number): number | null;
|
|
88
|
+
/**
|
|
89
|
+
* Reads a stored value.
|
|
90
|
+
*
|
|
91
|
+
* @param {StorageGetter} getStorage - Reads the storage to use.
|
|
92
|
+
* @param {string} key - The key to read.
|
|
93
|
+
* @returns {string | null} The value, or `null` when absent or when storage throws.
|
|
94
|
+
* @example readStored(() => window.sessionStorage, TAB_STORAGE_KEY)
|
|
95
|
+
*/
|
|
96
|
+
export declare function readStored(getStorage: StorageGetter, key: string): string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Stores a value. Does nothing where storage is denied.
|
|
99
|
+
*
|
|
100
|
+
* @param {StorageGetter} getStorage - Reads the storage to use.
|
|
101
|
+
* @param {string} key - The key to write.
|
|
102
|
+
* @param {string} value - The value to store.
|
|
103
|
+
* @example writeStored(() => window.sessionStorage, TAB_STORAGE_KEY, 'journey')
|
|
104
|
+
*/
|
|
105
|
+
export declare function writeStored(getStorage: StorageGetter, key: string, value: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{TAB_LABELS as e}from"../derive/plain-language/plain-language.js";var t=`picked-devtools-tab`,n=`picked-devtools-developer-open`,r=`guide`,i=[{id:`project`,label:`Project`},{id:`components`,label:`Components`},{id:`config`,label:`Config`},{id:`content`,label:`Content`},{id:`events`,label:`Events`},{id:`experience-instances`,label:`Experience Instances`},{id:`experiences`,label:`Experiences`},{id:`features`,label:`Features`},{id:`fields`,label:`Fields`},{id:`frameworks`,label:`Frameworks`},{id:`history`,label:`History`},{id:`identity`,label:`Identity`},{id:`predicates`,label:`Predicates`},{id:`responses`,label:`Responses`},{id:`custom-tools`,label:`Custom Tools`}];function a(e){return`tool:${e}`}function o(e){return`dev:${e}`}function s(t){let n=[{id:`guide`,label:e.guide,kind:`review`},{id:`session`,label:e.session,kind:`review`},{id:`answers`,label:e.answers,kind:`review`},{id:`journey`,label:e.journey,kind:`review`}];t.variations&&n.push({id:`variations`,label:e.variations,kind:`review`});let r=t.tools.map(e=>({id:a(e.id),label:e.label,kind:`tool`})),s=i.map(e=>({id:o(e.id),label:e.label,kind:`developer`}));return{primary:[...n,...r],developer:s}}function c(e,t){return e===null?r:[...t.primary,...t.developer].some(t=>t.id===e)?e:r}function l(e,t){return t.developer.some(t=>t.id===e)}function u(e,t,n){let r=Math.max(0,n-1);switch(e){case`ArrowDown`:return Math.min(t+1,r);case`ArrowUp`:return Math.max(t-1,0);case`Home`:return 0;case`End`:return r;default:return null}}function d(e,t){try{return e().getItem(t)}catch{return null}}function f(e,t,n){try{e().setItem(t,n)}catch{}}export{r as DEFAULT_TAB,n as DEVELOPER_OPEN_STORAGE_KEY,i as DEVELOPER_SCREENS,t as TAB_STORAGE_KEY,s as buildNav,o as developerTabId,l as isInDeveloper,u as nextFocusIndex,d as readStored,c as resolveTab,a as toolTabId,f as writeStored};
|
|
@@ -19,10 +19,13 @@
|
|
|
19
19
|
fullWidth?: boolean
|
|
20
20
|
href?: string
|
|
21
21
|
target?: string
|
|
22
|
+
/** Shown as the control's tooltip, such as why a disabled control is unavailable. */
|
|
23
|
+
title?: string
|
|
24
|
+
testId?: string
|
|
22
25
|
onclick?: (event: MouseEvent) => void
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
const {
|
|
26
29
|
children,
|
|
27
30
|
icon,
|
|
28
31
|
variant = 'primary',
|
|
@@ -33,6 +36,8 @@
|
|
|
33
36
|
fullWidth = false,
|
|
34
37
|
href,
|
|
35
38
|
target,
|
|
39
|
+
title,
|
|
40
|
+
testId,
|
|
36
41
|
onclick,
|
|
37
42
|
}: Props = $props()
|
|
38
43
|
|
|
@@ -49,6 +54,8 @@
|
|
|
49
54
|
rel={target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
50
55
|
aria-disabled={isDisabled || undefined}
|
|
51
56
|
tabindex={isDisabled ? -1 : undefined}
|
|
57
|
+
{title}
|
|
58
|
+
data-testid={testId}
|
|
52
59
|
onclick={isDisabled
|
|
53
60
|
? (e: MouseEvent) => e.preventDefault()
|
|
54
61
|
: onclick}
|
|
@@ -66,6 +73,8 @@
|
|
|
66
73
|
class:full-width={fullWidth}
|
|
67
74
|
{type}
|
|
68
75
|
disabled={isDisabled}
|
|
76
|
+
{title}
|
|
77
|
+
data-testid={testId}
|
|
69
78
|
{onclick}
|
|
70
79
|
>
|
|
71
80
|
{#if loading}
|
|
@@ -8,13 +8,23 @@
|
|
|
8
8
|
interface Props {
|
|
9
9
|
text: string
|
|
10
10
|
label?: string
|
|
11
|
+
/** Show `label` beside the icon, not only as its accessible name. */
|
|
12
|
+
showLabel?: boolean
|
|
13
|
+
testId?: string
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
const { text, label = 'Copy to clipboard', showLabel = false, testId }: Props = $props()
|
|
14
17
|
|
|
15
18
|
let copied = $state(false)
|
|
16
19
|
let timeoutId: ReturnType<typeof setTimeout> | undefined
|
|
17
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Copies the text to the clipboard and shows a tick for a moment.
|
|
23
|
+
*
|
|
24
|
+
* @returns {Promise<void>} Settles once the clipboard has answered.
|
|
25
|
+
* @example
|
|
26
|
+
* await handleCopy()
|
|
27
|
+
*/
|
|
18
28
|
async function handleCopy(): Promise<void> {
|
|
19
29
|
try {
|
|
20
30
|
await navigator.clipboard.writeText(text)
|
|
@@ -33,6 +43,7 @@
|
|
|
33
43
|
class="copy-button"
|
|
34
44
|
onclick={handleCopy}
|
|
35
45
|
aria-label={label}
|
|
46
|
+
data-testid={testId}
|
|
36
47
|
>
|
|
37
48
|
{#if copied}
|
|
38
49
|
<svg class="icon icon-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -44,6 +55,7 @@
|
|
|
44
55
|
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
45
56
|
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
46
57
|
</svg>
|
|
58
|
+
{#if showLabel}<span>{label}</span>{/if}
|
|
47
59
|
{/if}
|
|
48
60
|
</button>
|
|
49
61
|
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
children: Snippet
|
|
12
12
|
status?: 'default' | 'success' | 'warning' | 'error' | 'info'
|
|
13
13
|
size?: 'small' | 'medium'
|
|
14
|
+
testId?: string
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const { children, status = 'default', size = 'medium', testId }: Props = $props()
|
|
17
18
|
</script>
|
|
18
19
|
|
|
19
|
-
<span class="badge status-{status} size-{size}">
|
|
20
|
+
<span class="badge status-{status} size-{size}" data-testid={testId}>
|
|
20
21
|
{@render children()}
|
|
21
22
|
</span>
|
|
22
23
|
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
interface Props {
|
|
3
3
|
message: string
|
|
4
|
+
/** A second, smaller line: what would fill the empty space. */
|
|
5
|
+
hint?: string
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
const { message, hint }: Props = $props()
|
|
7
9
|
</script>
|
|
8
10
|
|
|
9
11
|
<div class="empty-state">
|
|
10
12
|
<p class="message">{message}</p>
|
|
13
|
+
{#if hint}
|
|
14
|
+
<p class="hint">{hint}</p>
|
|
15
|
+
{/if}
|
|
11
16
|
</div>
|
|
12
17
|
|
|
13
18
|
<style>
|
|
14
19
|
.empty-state {
|
|
15
20
|
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
16
22
|
align-items: center;
|
|
17
23
|
justify-content: center;
|
|
24
|
+
gap: var(--space-1);
|
|
18
25
|
padding: var(--space-8);
|
|
26
|
+
text-align: center;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
.message {
|
|
@@ -23,4 +31,11 @@
|
|
|
23
31
|
font-size: var(--text-sm);
|
|
24
32
|
margin: 0;
|
|
25
33
|
}
|
|
34
|
+
|
|
35
|
+
.hint {
|
|
36
|
+
max-width: 34ch;
|
|
37
|
+
color: var(--color-gray-500);
|
|
38
|
+
font-size: var(--text-xs);
|
|
39
|
+
margin: 0;
|
|
40
|
+
}
|
|
26
41
|
</style>
|
|
@@ -11,17 +11,18 @@
|
|
|
11
11
|
children: Snippet
|
|
12
12
|
status?: 'info' | 'success' | 'warning' | 'error'
|
|
13
13
|
title?: string
|
|
14
|
+
testId?: string
|
|
14
15
|
onDismiss?: () => void
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
const { children, status = 'info', title, testId, onDismiss }: Props = $props()
|
|
18
19
|
|
|
19
20
|
const bannerRole = $derived(
|
|
20
21
|
status === 'error' || status === 'warning' ? 'alert' : 'status',
|
|
21
22
|
)
|
|
22
23
|
</script>
|
|
23
24
|
|
|
24
|
-
<div class="banner status-{status}" role={bannerRole}>
|
|
25
|
+
<div class="banner status-{status}" role={bannerRole} data-testid={testId}>
|
|
25
26
|
<div class="banner-content">
|
|
26
27
|
{#if title}
|
|
27
28
|
<p class="banner-title">{title}</p>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export{svelteFrameworkPlugin}from"./plugin.js";
|
package/dist/render/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isValidAdaptedComponent as e}from"../component.js";import{CLIENT_CONTEXT_KEY as t,EXPERIENCE_CONTEXT_KEY as n}from"../context.js";import{mergeArrays as r}from"../utils/array.js";import{mount as i,unmount as a}from"svelte";import{isLazyLoader as o}from"@picked/client";import s from"../utils/ErrorBoundary.svelte";var c=new WeakMap;function l(e,r){return new Map([[t,e],[n,r]])}var u=async(t,n,a,u,d)=>{if(!e(n))throw Error(`The component is invalid.`);let f=r(n.style?.sheets,d.stylesheets),p=r(n.style?.css,d.css);f.length&&f.forEach(e=>{let n=document.createElement(`link`);n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n.setAttribute(`type`,`text/css`),n.setAttribute(`picked-injected`,`true`),t.appendChild(n)}),p.length&&p.forEach(e=>{let n=document.createElement(`style`);n.textContent=e,n.setAttribute(`type`,`text/css`),n.setAttribute(`picked-injected`,`true`),t.appendChild(n)});let m=e=>{let n=i(s,{target:t,props:{component:e,componentProps:{client:a,experience:u}},context:l(a,u)});c.set(t,n)};if(o(n.component)){let{default:e}=await n.component.load();m(e)
|
|
1
|
+
import{isValidAdaptedComponent as e}from"../component.js";import{CLIENT_CONTEXT_KEY as t,EXPERIENCE_CONTEXT_KEY as n}from"../context.js";import{mergeArrays as r}from"../utils/array.js";import{mount as i,unmount as a}from"svelte";import{isLazyLoader as o}from"@picked/client";import s from"../utils/ErrorBoundary.svelte";var c=new WeakMap;function l(e,r){return new Map([[t,e],[n,r]])}var u=async(t,n,a,u,d)=>{if(!e(n))throw Error(`The component is invalid.`);let f=r(n.style?.sheets,d.stylesheets),p=r(n.style?.css,d.css);f.length&&f.forEach(e=>{let n=document.createElement(`link`);n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n.setAttribute(`type`,`text/css`),n.setAttribute(`picked-injected`,`true`),t.appendChild(n)}),p.length&&p.forEach(e=>{let n=document.createElement(`style`);n.textContent=e,n.setAttribute(`type`,`text/css`),n.setAttribute(`picked-injected`,`true`),t.appendChild(n)});let m=e=>{let n=i(s,{target:t,props:{component:e,componentProps:{client:a,experience:u}},context:l(a,u)});c.set(t,n)};if(o(n.component)){let{default:e}=await n.component.load();m(e)}else if(n.component instanceof Promise){let{default:e}=await n.component;m(e)}else m(n.component)},d=e=>{let t=c.get(e);t&&(a(t),c.delete(e))};export{l as createContext,u as renderSvelteComponent,d as unRenderSvelteComponent};
|