@picked/svelte 0.0.1-dev.1772073931707 → 0.0.1-dev.1772085077346
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/_virtual/preload-helper.js +1 -0
- package/dist/component.d.ts +3 -3
- package/dist/form/index.d.ts +16 -2
- package/dist/form/index.js +1 -1
- package/dist/hooks/field.d.ts +0 -5
- package/dist/hooks/step.d.ts +8 -8
- package/dist/hooks/step.js +1 -1
- package/dist/plugins/devtools/DevToolsExperience.svelte +173 -25
- package/dist/plugins/devtools/PickedIcon.svelte +19 -0
- package/dist/plugins/devtools/components/ExperienceInstanceListItem.svelte +1 -1
- package/dist/plugins/devtools/components/ExperienceInstancesTable.svelte +14 -10
- package/dist/plugins/devtools/plugin.d.ts +12 -4
- package/dist/plugins/devtools/plugin.js +1 -1
- package/dist/plugins/devtools/screens/components/ComponentsListScreen.svelte +17 -13
- package/dist/plugins/devtools/screens/events/EventsTable.svelte +24 -20
- package/dist/plugins/devtools/screens/experience-instances/ExperienceInstancesListScreen.svelte +1 -3
- package/dist/plugins/devtools/screens/experiences/ExperienceDetailsScreen.svelte +29 -25
- package/dist/plugins/devtools/screens/experiences/ExperienceExperienceInstancesListScreen.svelte +1 -3
- package/dist/plugins/devtools/screens/experiences/ExperienceTreeScreen.svelte +2 -2
- package/dist/plugins/devtools/screens/features/FeaturesListScreen.svelte +11 -9
- package/dist/plugins/devtools/screens/frameworks/FrameworksListScreen.svelte +16 -12
- package/dist/plugins/devtools/screens/history/HistoryEntriesTable.svelte +14 -10
- package/dist/plugins/devtools/screens/predicates/PredicatesListScreen.svelte +16 -12
- package/dist/plugins/devtools/screens/project/ProjectScreen.svelte +47 -1
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +9 -10
- package/dist/plugins/devtools/screens/responses/ResponsesTable.svelte +26 -24
- package/dist/plugins/devtools/ui/actions/Button.svelte +4 -0
- package/dist/plugins/devtools/ui/data/DataTable.svelte +13 -3
- package/dist/render/browser.js +1 -1
- package/dist/render/server.js +1 -1
- package/package.json +2 -2
- package/dist/form/build-responses.d.ts +0 -13
- package/dist/form/build-responses.js +0 -1
- package/dist/form/create-field-evaluator.d.ts +0 -17
- package/dist/form/create-field-evaluator.js +0 -1
- package/dist/form/create-field-validation.d.ts +0 -41
- package/dist/form/create-field-validation.js +0 -1
- package/dist/form/create-form.js +0 -1
- package/dist/form/create-form.svelte.d.ts +0 -41
- package/dist/form/create-form.svelte.js +0 -1
- package/dist/form/create-submit-pipeline.js +0 -1
- package/dist/form/create-submit-pipeline.svelte.d.ts +0 -53
- package/dist/form/create-submit-pipeline.svelte.js +0 -1
- package/dist/form/get-form.d.ts +0 -16
- package/dist/form/get-form.js +0 -1
- package/dist/plugins/devtools/experience.d.ts +0 -1
- package/dist/plugins/devtools/experience.js +0 -1
- package/dist/plugins/devtools/ui/tokens.css.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const p="modulepreload",v=function(l){return"/"+l},u={},y=function(d,c,E){let i=Promise.resolve();if(c&&c.length>0){let f=function(e){return Promise.all(e.map(o=>Promise.resolve(o).then(s=>({status:"fulfilled",value:s}),s=>({status:"rejected",reason:s}))))};document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");i=f(c.map(e=>{if(e=v(e),e in u)return;u[e]=!0;const o=e.endsWith(".css"),s=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${s}`))return;const n=document.createElement("link");if(n.rel=o?"stylesheet":p,o||(n.as="script"),n.crossOrigin="",n.href=e,t&&n.setAttribute("nonce",t),document.head.appendChild(n),o)return new Promise((m,h)=>{n.addEventListener("load",m),n.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${e}`)))})}))}function a(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return i.then(r=>{for(const t of r||[])t.status==="rejected"&&a(t.reason);return d().catch(a)})};export{y as __vitePreload};
|
package/dist/component.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { AdaptedComponent, AdaptedComponentStyle } from '@picked/client';
|
|
1
|
+
import { AdaptedComponent, AdaptedComponentStyle, LazyComponentLoader } from '@picked/client';
|
|
2
2
|
import { Component } from 'svelte';
|
|
3
3
|
export type ComponentWithProps = Component<any>;
|
|
4
4
|
export declare const adaptSvelteComponent: (component: ComponentWithProps | Promise<{
|
|
5
5
|
default: ComponentWithProps;
|
|
6
|
-
}>, style?: AdaptedComponentStyle) => AdaptedComponent<"svelte", ComponentWithProps | Promise<{
|
|
6
|
+
}> | LazyComponentLoader<ComponentWithProps>, style?: AdaptedComponentStyle) => AdaptedComponent<"svelte", ComponentWithProps | Promise<{
|
|
7
7
|
default: ComponentWithProps;
|
|
8
|
-
}>>;
|
|
8
|
+
}> | LazyComponentLoader<ComponentWithProps>>;
|
|
9
9
|
export declare const isValidAdaptedComponent: (component: AdaptedComponent<string, unknown>) => component is AdaptedComponent<"svelte", ComponentWithProps>;
|
package/dist/form/index.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { ValidationError } from '@picked/client';
|
|
2
|
+
interface GetFormOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
onSuccess?: () => void | Promise<void>;
|
|
6
|
+
onError?: (errors: ValidationError[]) => void | Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
type SubmitEventWithCurrentTarget = SubmitEvent & {
|
|
9
|
+
currentTarget: EventTarget & HTMLFormElement;
|
|
10
|
+
};
|
|
11
|
+
export declare function getForm({ id: formId, title, onError, onSuccess }: GetFormOptions): {
|
|
12
|
+
form: {
|
|
13
|
+
onsubmit: import('effector').EventCallable<SubmitEventWithCurrentTarget>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export {};
|
package/dist/form/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{createEvent as _,createEffect as m,attach as v,sample as y,split as k}from"effector";import{getPicked as D,getExperience as F}from"../hooks/client.js";import"@picked/client";import{getStep as B}from"../hooks/step.js";import"svelte";import"svelte/store";import"@picked/analytics";function z({id:f,title:l,onError:b,onSuccess:g}){const a=D(),x=B(),i=F(),{currentStepStore:u}=i,d=_(),h=m(r=>a.responses.commit(r)),E=v({source:{step:u},effect:m(({step:r})=>{a.eventBus({type:"form_submit_success",form:{id:f,title:l},experience:i,step:r??void 0}),g?.()})}),S=v({source:{step:u},mapParams:(r,o)=>({step:o.step,errors:r.errors}),effect:m(({step:r,errors:o})=>{a.eventBus({type:"form_submit_error",form:{id:f,title:l},exception:{reason:o},experience:i,step:r??void 0}),o.forEach(c=>{a.eventBus({type:"field_validation_error",exception:{reason:[c]},experience:i,step:r??void 0})}),b?.(o)})});return y({clock:d,source:{step:u},fn:({step:r})=>({formId:f,title:l,step:r}),target:m(({formId:r,title:o,step:c})=>{a.eventBus({type:"form_submit",form:{id:r,title:o},experience:i,step:c??void 0})})}),y({clock:d,source:{fields:a.fields.listStore,stepFields:x.fields,step:u},fn:({stepFields:r},o)=>{o.preventDefault();const c=new FormData(o.currentTarget),A=Array.from(c.entries()),p={data:{},push(t){const s=t.questionId,e=this.data[s];e?Array.isArray(e)&&Array.isArray(t.value)?Array.isArray(e)&&Array.isArray(t.value)&&(typeof e[0]=="string"?this.data[s]=[...e,...t.value].map(String):typeof e[0]=="number"?this.data[s]=[...e,...t.value].map(Number):typeof e[0]=="boolean"?this.data[s]=[...e,...t.value].map(n=>!!n):this.data[s]=t.value):this.data[s]=t.value:this.data[s]=t.value}};return r.forEach(t=>{let s=A.filter(([e])=>e===t.id);s.length===0&&(s=[[t.id,""]]),s.forEach(([,e])=>{const n=t.id;if(e===""){p.push({questionId:n,value:null});return}switch(t.type){case"text":p.push({questionId:n,value:t.multiple?[String(e)]:String(e)});break;case"number":p.push({questionId:n,value:t.multiple?[Number(e)]:Number(e)});break;case"boolean":p.push({questionId:n,value:t.multiple?[e==="true"]:e==="true"});break}})}),p.data},target:h}),k({source:h.doneData,match:{hasErrors:({errors:r})=>r.length>0},cases:{hasErrors:S,__:E}}),{form:{onsubmit:d}}}export{z as getForm};
|
package/dist/hooks/field.d.ts
CHANGED
|
@@ -4,9 +4,4 @@ export interface GetFieldResponse {
|
|
|
4
4
|
value: Store<FieldValue>;
|
|
5
5
|
field: Store<Field | null>;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
8
|
-
* @deprecated Field options and status are now available directly on the Field object
|
|
9
|
-
* from the step fields store. Use `field.options`, `field.status`, and `field.error`
|
|
10
|
-
* instead of accessing them through this hook.
|
|
11
|
-
*/
|
|
12
7
|
export declare function getField(id: string): GetFieldResponse;
|
package/dist/hooks/step.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Store } from 'effector';
|
|
2
|
-
import { ExperienceStep } from '@picked/client';
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { ExperienceStep, Field, Response } from '@picked/client';
|
|
3
|
+
type FieldWithValue = Field & {
|
|
4
|
+
value: Response | undefined;
|
|
5
|
+
};
|
|
6
|
+
export interface StepContext {
|
|
5
7
|
step: Store<ExperienceStep>;
|
|
6
|
-
|
|
7
|
-
fields: Store<FormField[]>;
|
|
8
|
-
isActive: Store<boolean>;
|
|
9
|
-
/** @deprecated Use `isActive` instead */
|
|
8
|
+
fields: Store<FieldWithValue[]>;
|
|
10
9
|
isActiveStep: Store<boolean>;
|
|
11
10
|
}
|
|
12
|
-
export declare function setStepContext(stepId: string): StepContext;
|
|
13
11
|
export declare function getStep(): StepContext;
|
|
12
|
+
export declare function setStepContext(stepId: string): StepContext;
|
|
13
|
+
export {};
|
package/dist/hooks/step.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getContext as
|
|
1
|
+
import{getContext as v,setContext as x}from"svelte";import{createStore as E,combine as a,attach as h,createEffect as w,sample as c}from"effector";import{getStepFields as A}from"@picked/client";import{STEP_CONTEXT_KEY as l}from"../context.js";import{getStepRouter as C}from"../router/context.js";import{getExperience as F,getPicked as T}from"./client.js";function K(){return v(l)}function N(i){const u=F(),o=T(),{activeStep:S}=C(),s=S.map(e=>e?.id===i),p=u.treeStore.map(e=>{const t=e.steps.find(r=>r.id===i);if(!t)throw new Error(`Step with id "${i}" not found in the experience tree.`);return t}),f=E([]),d=a({fields:f,responses:o.responses.listStore},({fields:e,responses:t})=>e.map(r=>{const m=t.find(g=>g.fieldId===r.id)?.value;return{...r,value:m}})),n=h({source:a({step:p,fields:o.fields.listStore}),effect:w(async({step:{fieldIds:e},fields:t})=>await A(o,t.filter(r=>e.includes(r.id))))});return c({source:{isActiveStep:s},filter:({isActiveStep:e})=>e,target:n}),c({clock:o.responses.listStore,source:{isActiveStep:s},filter:({isActiveStep:e})=>e,target:n}),c({source:n.doneData,target:f}),x(l,{step:p,fields:d,isActiveStep:s})}export{K as getStep,N as setStepContext};
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
the change in the paired React component to maintain visual and behavioral parity.
|
|
7
7
|
-->
|
|
8
8
|
<script lang="ts">
|
|
9
|
-
import { getExperience } from '../../hooks'
|
|
10
|
-
import { Button } from './ui'
|
|
11
|
-
import PickedLogo from './PickedLogo.svelte'
|
|
9
|
+
import { getExperience, getPicked } from '../../hooks'
|
|
10
|
+
import { Button, Heading, Stack } from './ui'
|
|
12
11
|
import Tabs from './components/Tabs.svelte'
|
|
13
12
|
import ExperiencesListScreen from './screens/experiences/ExperiencesListScreen.svelte'
|
|
14
13
|
import ExperienceInstancesListScreen from './screens/experience-instances/ExperienceInstancesListScreen.svelte'
|
|
@@ -20,8 +19,12 @@
|
|
|
20
19
|
import ResponsesListScreen from './screens/responses/ResponsesListScreen.svelte'
|
|
21
20
|
import FeaturesListScreen from './screens/features/FeaturesListScreen.svelte'
|
|
22
21
|
import EventsListScreen from './screens/events/EventsListScreen.svelte'
|
|
22
|
+
import PickedIcon from './PickedIcon.svelte'
|
|
23
23
|
|
|
24
24
|
const experience = getExperience()
|
|
25
|
+
const client = getPicked()
|
|
26
|
+
|
|
27
|
+
const dashboardProjectUrl = `${client.dashboardUrl}/p/${client.projectId}`
|
|
25
28
|
|
|
26
29
|
const tabs = [
|
|
27
30
|
{
|
|
@@ -101,10 +104,15 @@
|
|
|
101
104
|
<div class="container">
|
|
102
105
|
<header class="toolbar" id="devtools-header">
|
|
103
106
|
<div class="toolbar-left">
|
|
104
|
-
<
|
|
107
|
+
<Stack direction="horizontal" gap="small" >
|
|
108
|
+
<PickedIcon height={25} width={25}/>
|
|
109
|
+
<Heading size="small">Developer Tools</Heading>
|
|
110
|
+
</Stack>
|
|
105
111
|
</div>
|
|
106
112
|
<div class="toolbar-center"></div>
|
|
107
113
|
<div class="toolbar-right">
|
|
114
|
+
<Button variant="ghost" size="small" href={client.documentationSiteUrl} target="_blank">Docs</Button>
|
|
115
|
+
<Button variant="ghost" size="small" href={dashboardProjectUrl} target="_blank">Dashboard</Button>
|
|
108
116
|
<Button variant="ghost" size="small" onclick={() => experience.close()}>Close</Button>
|
|
109
117
|
</div>
|
|
110
118
|
</header>
|
|
@@ -118,9 +126,9 @@
|
|
|
118
126
|
class="floating-button"
|
|
119
127
|
onclick={() => experience.open()}
|
|
120
128
|
aria-label="Open Picked Devtools"
|
|
121
|
-
title="Open Picked Devtools
|
|
129
|
+
title="Open Picked Devtools"
|
|
122
130
|
>
|
|
123
|
-
<
|
|
131
|
+
<PickedIcon height={25} width={25}/>
|
|
124
132
|
</button>
|
|
125
133
|
{/if}
|
|
126
134
|
|
|
@@ -131,6 +139,80 @@
|
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
.devtools {
|
|
142
|
+
/* Colors — match Tailwind's default palette exactly */
|
|
143
|
+
--color-blue-500: #3b82f6;
|
|
144
|
+
--color-blue-600: #2563eb;
|
|
145
|
+
--color-blue-700: #1d4ed8;
|
|
146
|
+
--color-blue-800: #1e40af;
|
|
147
|
+
--color-gray-50: #f9fafb;
|
|
148
|
+
--color-gray-100: #f3f4f6;
|
|
149
|
+
--color-gray-200: #e5e7eb;
|
|
150
|
+
--color-gray-300: #d1d5db;
|
|
151
|
+
--color-gray-500: #6b7280;
|
|
152
|
+
--color-gray-600: #4b5563;
|
|
153
|
+
--color-gray-700: #374151;
|
|
154
|
+
--color-gray-900: #111827;
|
|
155
|
+
--color-red-500: #ef4444;
|
|
156
|
+
--color-red-600: #dc2626;
|
|
157
|
+
--color-red-700: #b91c1c;
|
|
158
|
+
--color-red-800: #991b1b;
|
|
159
|
+
--color-green-100: #dcfce7;
|
|
160
|
+
--color-green-700: #15803d;
|
|
161
|
+
--color-green-800: #166534;
|
|
162
|
+
--color-yellow-100: #fef9c3;
|
|
163
|
+
--color-yellow-700: #a16207;
|
|
164
|
+
--color-yellow-800: #854d0e;
|
|
165
|
+
--color-white: #ffffff;
|
|
166
|
+
--color-black: #000000;
|
|
167
|
+
|
|
168
|
+
/* Typography — match Tailwind's type scale */
|
|
169
|
+
--text-xs: 0.75rem;
|
|
170
|
+
--text-sm: 0.875rem;
|
|
171
|
+
--text-base: 1rem;
|
|
172
|
+
--text-lg: 1.125rem;
|
|
173
|
+
--text-xl: 1.25rem;
|
|
174
|
+
--text-2xl: 1.5rem;
|
|
175
|
+
--font-normal: 400;
|
|
176
|
+
--font-medium: 500;
|
|
177
|
+
--font-semibold: 600;
|
|
178
|
+
|
|
179
|
+
/* Spacing — match Tailwind's spacing scale */
|
|
180
|
+
--space-0: 0;
|
|
181
|
+
--space-0-5: 0.125rem;
|
|
182
|
+
--space-1: 0.25rem;
|
|
183
|
+
--space-1-5: 0.375rem;
|
|
184
|
+
--space-2: 0.5rem;
|
|
185
|
+
--space-2-5: 0.625rem;
|
|
186
|
+
--space-3: 0.75rem;
|
|
187
|
+
--space-4: 1rem;
|
|
188
|
+
--space-5: 1.25rem;
|
|
189
|
+
--space-6: 1.5rem;
|
|
190
|
+
--space-8: 2rem;
|
|
191
|
+
|
|
192
|
+
/* Radii */
|
|
193
|
+
--radius-sm: 0.125rem;
|
|
194
|
+
--radius-md: 0.375rem;
|
|
195
|
+
--radius-lg: 0.5rem;
|
|
196
|
+
--radius-xl: 0.75rem;
|
|
197
|
+
--radius-full: 9999px;
|
|
198
|
+
|
|
199
|
+
/* Shadows */
|
|
200
|
+
--shadow-card: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
|
201
|
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
|
|
202
|
+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
|
|
203
|
+
|
|
204
|
+
/* Focus ring — matches dashboard's ring-2 ring-blue-500 ring-offset-2 */
|
|
205
|
+
--ring-color: var(--color-blue-500);
|
|
206
|
+
--ring-width: 2px;
|
|
207
|
+
--ring-offset: 2px;
|
|
208
|
+
|
|
209
|
+
/* Base typography reset */
|
|
210
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
|
211
|
+
'Helvetica Neue', Arial, sans-serif;
|
|
212
|
+
font-size: var(--text-sm);
|
|
213
|
+
line-height: 1.5;
|
|
214
|
+
color: var(--color-gray-900);
|
|
215
|
+
|
|
134
216
|
position: fixed;
|
|
135
217
|
inset: 0;
|
|
136
218
|
z-index: 999999999;
|
|
@@ -184,6 +266,7 @@
|
|
|
184
266
|
.toolbar-right {
|
|
185
267
|
display: flex;
|
|
186
268
|
align-items: center;
|
|
269
|
+
gap: var(--space-1);
|
|
187
270
|
}
|
|
188
271
|
|
|
189
272
|
.main {
|
|
@@ -214,36 +297,101 @@
|
|
|
214
297
|
background-color: var(--color-gray-50);
|
|
215
298
|
}
|
|
216
299
|
|
|
300
|
+
.devtools :global(th:first-child),
|
|
301
|
+
.devtools :global(td:first-child) {
|
|
302
|
+
padding-left: var(--space-4);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.devtools :global(th:last-child),
|
|
306
|
+
.devtools :global(td:last-child) {
|
|
307
|
+
padding-right: var(--space-4);
|
|
308
|
+
}
|
|
309
|
+
|
|
217
310
|
.floating-button {
|
|
218
311
|
position: fixed;
|
|
219
|
-
bottom:
|
|
312
|
+
bottom: 1rem;
|
|
220
313
|
right: 1.5rem;
|
|
221
|
-
|
|
222
|
-
height: 4.5rem;
|
|
223
|
-
border-radius: var(--radius-full);
|
|
314
|
+
border-radius: 6px;
|
|
224
315
|
background-color: var(--color-white);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
display: flex;
|
|
228
|
-
align-items: center;
|
|
229
|
-
justify-content: center;
|
|
316
|
+
display: grid;
|
|
317
|
+
place-items: center;
|
|
230
318
|
cursor: pointer;
|
|
231
319
|
z-index: 999999;
|
|
232
|
-
|
|
233
|
-
padding:
|
|
320
|
+
border: 0 transparent;
|
|
321
|
+
padding: 6px;
|
|
322
|
+
box-shadow: 2px 2px 4px #00000029;
|
|
323
|
+
|
|
324
|
+
&:hover {
|
|
325
|
+
background-color: #f5f5f5;
|
|
326
|
+
}
|
|
234
327
|
}
|
|
235
328
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
329
|
+
/** Compact inline form elements for use within table cells */
|
|
330
|
+
.devtools :global(.inline-select),
|
|
331
|
+
.devtools :global(.inline-input) {
|
|
332
|
+
font-size: var(--text-xs);
|
|
333
|
+
padding: var(--space-0-5) var(--space-1);
|
|
334
|
+
border: 1px solid var(--color-gray-300);
|
|
335
|
+
border-radius: var(--radius-sm);
|
|
336
|
+
font-family: inherit;
|
|
239
337
|
}
|
|
240
338
|
|
|
241
|
-
.
|
|
242
|
-
|
|
339
|
+
.devtools :global(.inline-input) {
|
|
340
|
+
width: 100%;
|
|
243
341
|
}
|
|
244
342
|
|
|
245
|
-
.
|
|
246
|
-
|
|
247
|
-
|
|
343
|
+
.devtools :global(.inline-select:focus),
|
|
344
|
+
.devtools :global(.inline-input:focus) {
|
|
345
|
+
outline: none;
|
|
346
|
+
box-shadow: 0 0 0 var(--ring-width) var(--ring-color);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** Textarea elements within devtools */
|
|
350
|
+
.devtools :global(textarea) {
|
|
351
|
+
width: 100%;
|
|
352
|
+
min-height: 60px;
|
|
353
|
+
font-family: monospace;
|
|
354
|
+
font-size: var(--text-xs);
|
|
355
|
+
padding: var(--space-1);
|
|
356
|
+
border: 1px solid var(--color-gray-300);
|
|
357
|
+
border-radius: var(--radius-md);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.devtools :global(textarea:focus) {
|
|
361
|
+
outline: none;
|
|
362
|
+
box-shadow: 0 0 0 var(--ring-width) var(--ring-color);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** Event detail panel styling */
|
|
366
|
+
.devtools :global(.details-cell) {
|
|
367
|
+
background-color: var(--color-gray-50);
|
|
368
|
+
padding: var(--space-4);
|
|
369
|
+
border-left: 3px solid var(--color-blue-500);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** Expand/collapse icon for table rows */
|
|
373
|
+
.devtools :global(.expand-icon) {
|
|
374
|
+
margin-right: var(--space-2);
|
|
375
|
+
display: inline-block;
|
|
376
|
+
width: 12px;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/** Clickable table rows (e.g., expandable event rows) */
|
|
380
|
+
.devtools :global(.event-row) {
|
|
381
|
+
cursor: pointer;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Centered checkbox cell in tables */
|
|
385
|
+
.devtools :global(.include-cell) {
|
|
386
|
+
text-align: center;
|
|
387
|
+
width: 2.5rem;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** Inline option label for checkbox/radio lists in table cells */
|
|
391
|
+
.devtools :global(.option-label) {
|
|
392
|
+
display: flex;
|
|
393
|
+
align-items: center;
|
|
394
|
+
gap: var(--space-2);
|
|
395
|
+
cursor: pointer;
|
|
248
396
|
}
|
|
249
397
|
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- PickedIcon.svelte -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
export let width = 48
|
|
4
|
+
export let height = 48
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<svg {width} {height} viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
8
|
+
<g opacity="0.5">
|
|
9
|
+
<ellipse opacity="0.8" cx="32.5807" cy="7.38424" rx="6.29832" ry="6.29832" fill="#01AD7A"/>
|
|
10
|
+
<circle opacity="0.6" cx="31.4947" cy="8.47015" r="6.29832" fill="#01AD7A"/>
|
|
11
|
+
<ellipse opacity="0.4" cx="30.4088" cy="9.55607" rx="6.29832" ry="6.29832" fill="#01AD7A"/>
|
|
12
|
+
<ellipse opacity="0.2" cx="29.3229" cy="10.642" rx="6.29832" ry="6.29832" fill="#01AD7A"/>
|
|
13
|
+
<circle opacity="0.1" cx="28.237" cy="11.7279" r="6.29832" fill="#01AD7A"/>
|
|
14
|
+
</g>
|
|
15
|
+
<ellipse cx="33.6664" cy="6.29832" rx="6.29832" ry="6.29832" fill="#00CD90"/>
|
|
16
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5997 16.1802C14.5788 16.1802 16.1832 14.5758 16.1832 12.5967C16.1832 10.6175 14.5788 9.01315 12.5997 9.01315C10.6206 9.01315 9.01617 10.6175 9.01617 12.5967C9.01617 14.5758 10.6206 16.1802 12.5997 16.1802ZM12.5997 18.895C16.0782 18.895 18.898 16.0751 18.898 12.5967C18.898 9.11821 16.0782 6.29836 12.5997 6.29836C9.12123 6.29836 6.30138 9.11821 6.30138 12.5967C6.30138 16.0751 9.12123 18.895 12.5997 18.895Z" fill="#1549FF"/>
|
|
17
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5997 30.9486C14.5788 30.9486 16.1832 29.3442 16.1832 27.3651C16.1832 25.386 14.5788 23.7816 12.5997 23.7816C10.6206 23.7816 9.01617 25.386 9.01617 27.3651C9.01617 29.3442 10.6206 30.9486 12.5997 30.9486ZM12.5997 33.6634C16.0782 33.6634 18.898 30.8436 18.898 27.3651C18.898 23.8866 16.0782 21.0668 12.5997 21.0668C9.12123 21.0668 6.30138 23.8866 6.30138 27.3651C6.30138 30.8436 9.12123 33.6634 12.5997 33.6634Z" fill="#1549FF"/>
|
|
18
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.3683 30.9486C29.3474 30.9486 30.9518 29.3442 30.9518 27.3651C30.9518 25.386 29.3474 23.7816 27.3683 23.7816C25.3891 23.7816 23.7847 25.386 23.7847 27.3651C23.7847 29.3442 25.3891 30.9486 27.3683 30.9486ZM27.3683 33.6634C30.8467 33.6634 33.6666 30.8436 33.6666 27.3651C33.6666 23.8866 30.8467 21.0668 27.3683 21.0668C23.8898 21.0668 21.0699 23.8866 21.0699 27.3651C21.0699 30.8436 23.8898 33.6634 27.3683 33.6634Z" fill="#1549FF"/>
|
|
19
|
+
</svg>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<td>{$currentNode?.id || ''}</td>
|
|
21
21
|
<td>{$currentNode?.type || ''}</td>
|
|
22
22
|
<td>{$currentStep?.id || ''}</td>
|
|
23
|
-
<td>{$currentStep?.
|
|
23
|
+
<td>{$currentStep?.title || ''}</td>
|
|
24
24
|
<td>{totalNextStepNodes}</td>
|
|
25
25
|
<td>{$stepsToOrigin[0]} - {$stepsToOrigin[1]}</td>
|
|
26
26
|
<td>{$stepsToLeaf[0]} - {$stepsToLeaf[1]}</td>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceInstance } from '@picked/client'
|
|
3
3
|
import ExperienceInstanceListItem from './ExperienceInstanceListItem.svelte'
|
|
4
|
-
import { DataTable, EmptyState } from '../ui'
|
|
4
|
+
import { Card, DataTable, EmptyState, Stack } from '../ui'
|
|
5
5
|
|
|
6
6
|
export let experienceInstances: ExperienceInstance[]
|
|
7
7
|
|
|
@@ -18,12 +18,16 @@
|
|
|
18
18
|
]
|
|
19
19
|
</script>
|
|
20
20
|
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
<Stack padding="medium">
|
|
22
|
+
<Card sectioned>
|
|
23
|
+
<DataTable columns={columns} rows={experienceInstances}>
|
|
24
|
+
{#snippet row(item)}
|
|
25
|
+
{@const experienceInstance = item}
|
|
26
|
+
<ExperienceInstanceListItem {experienceInstance} />
|
|
27
|
+
{/snippet}
|
|
28
|
+
{#snippet empty()}
|
|
29
|
+
<EmptyState message="No experience instances" />
|
|
30
|
+
{/snippet}
|
|
31
|
+
</DataTable>
|
|
32
|
+
</Card>
|
|
33
|
+
</Stack>
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { Plugin } from '@picked/client';
|
|
2
|
+
export interface SvelteDevtoolsPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* When `true`, the devtools experience launches automatically on page load.
|
|
5
|
+
* When `false`, devtools can only be opened via the Picked Chrome extension.
|
|
6
|
+
*
|
|
7
|
+
* @default false
|
|
8
|
+
*/
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* with the client's experience data.
|
|
12
|
+
* Registers the devtools experience for on-demand loading via the Chrome DevTools extension.
|
|
13
|
+
* The devtools component is lazily loaded — it is never included in the initial bundle.
|
|
6
14
|
*/
|
|
7
|
-
export declare const svelteDevtoolsPlugin: () => Plugin[];
|
|
15
|
+
export declare const svelteDevtoolsPlugin: (options?: SvelteDevtoolsPluginOptions) => Plugin[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{__vitePreload as t}from"../../_virtual/preload-helper.js";import{lazyComponent as n}from"@picked/client";import{createExperience as r,createExperiencePlugin as i}from"@picked/client/plugins/create-experience";import{adaptSvelteComponent as l}from"../../component.js";const d=o=>{const e=r({id:"devtools",name:"Picked Devtools",condition:o?.enabled??!1,initializeOpen:!1,targets:[{selector:"body",placement:"append"}],component:l(n(()=>t(()=>import("./DevToolsExperience.svelte"),[])))});return e.addStep({label:"Tools"}),[i({experiences:[e]})]};export{d as svelteDevtoolsPlugin};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getPicked } from '../../../../hooks'
|
|
3
|
-
import { DataTable, EmptyState } from '../../ui'
|
|
3
|
+
import { Card, DataTable, EmptyState, Stack } from '../../ui'
|
|
4
4
|
|
|
5
5
|
const client = getPicked()
|
|
6
6
|
|
|
@@ -12,15 +12,19 @@
|
|
|
12
12
|
]
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
<Stack padding="medium">
|
|
16
|
+
<Card sectioned>
|
|
17
|
+
<DataTable columns={columns} rows={$components}>
|
|
18
|
+
{#snippet row(item)}
|
|
19
|
+
{@const component = item}
|
|
20
|
+
<tr>
|
|
21
|
+
<td>{component.name}</td>
|
|
22
|
+
<td>{component.component.frameworkName}</td>
|
|
23
|
+
</tr>
|
|
24
|
+
{/snippet}
|
|
25
|
+
{#snippet empty()}
|
|
26
|
+
<EmptyState message="No components" />
|
|
27
|
+
{/snippet}
|
|
28
|
+
</DataTable>
|
|
29
|
+
</Card>
|
|
30
|
+
</Stack>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { combine, createStore, createEvent, sample } from 'effector'
|
|
3
3
|
import { getPicked } from '../../../../hooks'
|
|
4
4
|
import EventListItem from './EventListItem.svelte'
|
|
5
|
-
import { DataTable, EmptyState } from '../../ui'
|
|
5
|
+
import { Card, DataTable, EmptyState, Stack } from '../../ui'
|
|
6
6
|
import type { EventHistoryEntry } from '@picked/client'
|
|
7
7
|
|
|
8
8
|
const { events } = getPicked()
|
|
@@ -51,22 +51,26 @@
|
|
|
51
51
|
}
|
|
52
52
|
</script>
|
|
53
53
|
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
<Stack padding="medium">
|
|
55
|
+
<Card sectioned>
|
|
56
|
+
<DataTable
|
|
57
|
+
columns={columns}
|
|
58
|
+
rows={$sortedEvents}
|
|
59
|
+
sortKey="time"
|
|
60
|
+
sortDirection={$sortDirectionStore}
|
|
61
|
+
onSort={handleSort}
|
|
62
|
+
>
|
|
63
|
+
{#snippet row(item)}
|
|
64
|
+
{@const event = item}
|
|
65
|
+
<EventListItem
|
|
66
|
+
{event}
|
|
67
|
+
isExpanded={expandedRowIds.has(event.id)}
|
|
68
|
+
onToggle={() => toggleRow(event.id)}
|
|
69
|
+
/>
|
|
70
|
+
{/snippet}
|
|
71
|
+
{#snippet empty()}
|
|
72
|
+
<EmptyState message="No events yet. Interact with the page to see events." />
|
|
73
|
+
{/snippet}
|
|
74
|
+
</DataTable>
|
|
75
|
+
</Card>
|
|
76
|
+
</Stack>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceStore } from '@picked/client'
|
|
3
3
|
import { getPicked } from '../../../../hooks'
|
|
4
|
-
import { Button, Text, CodeBlock, Stack } from '../../ui'
|
|
4
|
+
import { Button, Card, Text, CodeBlock, Stack } from '../../ui'
|
|
5
5
|
|
|
6
6
|
const client = getPicked()
|
|
7
7
|
export let experience: ExperienceStore
|
|
@@ -10,34 +10,38 @@
|
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<Stack direction="vertical" gap="medium" padding="medium">
|
|
13
|
-
<
|
|
13
|
+
<Stack direction="horizontal" gap="small">
|
|
14
14
|
<Button variant="primary" size="small" onclick={() => client.launchExperienceById(experience.id)}>
|
|
15
15
|
Launch experience
|
|
16
16
|
</Button>
|
|
17
|
-
</
|
|
17
|
+
</Stack>
|
|
18
18
|
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
<Card sectioned>
|
|
20
|
+
<Stack direction="vertical" gap="medium" padding="medium">
|
|
21
|
+
<div>
|
|
22
|
+
<Text weight="semibold">Type</Text>
|
|
23
|
+
<Text>{$config.type}</Text>
|
|
24
|
+
</div>
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
<div>
|
|
27
|
+
<Text weight="semibold">Target selectors</Text>
|
|
28
|
+
<ul>
|
|
29
|
+
{#if $config.targetSelectors.length > 0}
|
|
30
|
+
{#each $config.targetSelectors as selector (selector)}
|
|
31
|
+
<li>
|
|
32
|
+
<CodeBlock code="{selector.selector} || {selector.placement}" />
|
|
33
|
+
</li>
|
|
34
|
+
{/each}
|
|
35
|
+
{:else}
|
|
36
|
+
<li><Text color="subdued">(none)</Text></li>
|
|
37
|
+
{/if}
|
|
38
|
+
</ul>
|
|
39
|
+
</div>
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
<div>
|
|
42
|
+
<Text weight="semibold">Decision logic</Text>
|
|
43
|
+
<CodeBlock code={JSON.stringify($config.decisionLogic, null, 2)} />
|
|
44
|
+
</div>
|
|
45
|
+
</Stack>
|
|
46
|
+
</Card>
|
|
43
47
|
</Stack>
|
package/dist/plugins/devtools/screens/experiences/ExperienceExperienceInstancesListScreen.svelte
CHANGED
|
@@ -10,6 +10,4 @@
|
|
|
10
10
|
$: experienceInstances = client.experienceInstances.getByExperienceId(experience.id)
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<
|
|
14
|
-
<ExperienceInstancesTable experienceInstances={$experienceInstances} />
|
|
15
|
-
</div>
|
|
13
|
+
<ExperienceInstancesTable experienceInstances={$experienceInstances} />
|