@liveroom-tech/react-immersive 6.0.2 → 6.1.1
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/README.md +24 -0
- package/dist/AnimationsTab-NUJTEMZ5.mjs +1 -0
- package/dist/AnnotationsTab-OHRVWRKI.mjs +1 -0
- package/dist/CinematicTab-IJAY2BS6.mjs +1 -0
- package/dist/ConfigureTab-UQRRATCY.mjs +6 -0
- package/dist/RulesTab-YVBZGJZX.mjs +1 -0
- package/dist/SequencesTab-IC5LWQ6N.css +1 -0
- package/dist/SequencesTab-LWGOVQ6Y.mjs +1 -0
- package/dist/binding-builder.css +1 -1
- package/dist/binding-builder.d.mts +3 -3
- package/dist/binding-builder.d.ts +3 -3
- package/dist/binding-builder.js +76 -23
- package/dist/binding-builder.mjs +1 -1
- package/dist/chunk-37YITTIK.mjs +1 -0
- package/dist/chunk-5FLX45O5.mjs +2 -0
- package/dist/chunk-5PJ5MLKE.mjs +1 -0
- package/dist/chunk-644OGSQJ.mjs +83 -0
- package/dist/chunk-7JCFNZJM.mjs +1 -0
- package/dist/chunk-7OWHW66D.mjs +1 -0
- package/dist/chunk-AL6UIGWP.mjs +1 -0
- package/dist/chunk-BNKTI3CY.mjs +1 -0
- package/dist/chunk-CCBFMNAU.mjs +1 -0
- package/dist/chunk-DEFZEXTA.mjs +1 -0
- package/dist/chunk-E24EFHB5.mjs +1 -0
- package/dist/chunk-EV6THDXD.mjs +1 -0
- package/dist/chunk-F5QSXMME.mjs +1 -0
- package/dist/chunk-FGAJ2UT7.mjs +1 -0
- package/dist/chunk-FXV4CLAK.mjs +1 -0
- package/dist/chunk-GV4ZRXL6.mjs +1 -0
- package/dist/chunk-KNCABWVN.mjs +47 -0
- package/dist/chunk-LX3GXQNU.mjs +1 -0
- package/dist/chunk-MLT4JQAY.mjs +1 -0
- package/dist/chunk-OPDRK3GS.mjs +1 -0
- package/dist/chunk-Z2VQGUC2.mjs +3 -0
- package/dist/hosted.css +1 -1
- package/dist/hosted.d.mts +24 -6
- package/dist/hosted.d.ts +24 -6
- package/dist/hosted.js +75 -22
- package/dist/hosted.mjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.mts +66 -6
- package/dist/index.d.ts +66 -6
- package/dist/index.js +69 -21
- package/dist/index.mjs +1 -1
- package/dist/{modelFileResolver-Co7j1tdQ.d.mts → modelFileResolver-B8ADn9Nl.d.mts} +57 -7
- package/dist/{modelFileResolver-Co7j1tdQ.d.ts → modelFileResolver-B8ADn9Nl.d.ts} +57 -7
- package/dist/{modelViewerProps-BibuMND7.d.ts → modelViewerProps-BE4D56Ti.d.ts} +173 -3
- package/dist/{modelViewerProps-Ce4-wb57.d.mts → modelViewerProps-DBwh-fmu.d.mts} +173 -3
- package/dist/{publicProps-CP18d_mt.d.ts → publicProps-3LNTAskZ.d.ts} +1 -1
- package/dist/{publicProps-BaJHCDa_.d.mts → publicProps-Clr1nSE6.d.mts} +1 -1
- package/dist/simple-model-viewer.css +1 -1
- package/dist/simple-model-viewer.d.mts +25 -3
- package/dist/simple-model-viewer.d.ts +25 -3
- package/dist/simple-model-viewer.js +49 -3
- package/dist/simple-model-viewer.mjs +1 -1
- package/dist/utils.d.mts +47 -4
- package/dist/utils.d.ts +47 -4
- package/dist/utils.js +2 -2
- package/dist/utils.mjs +1 -1
- package/package.json +5 -1
- package/dist/chunk-33SUWPXC.mjs +0 -3
- package/dist/chunk-4JMJALRO.mjs +0 -2
- package/dist/chunk-EIBW7ZJE.mjs +0 -81
- package/dist/chunk-KFTJMFYF.mjs +0 -1
- package/dist/chunk-OTSCPJWF.mjs +0 -1
- package/dist/chunk-P2JZ5Z7I.mjs +0 -1
- package/dist/chunk-V7WZUWJ5.mjs +0 -1
package/README.md
CHANGED
|
@@ -104,6 +104,30 @@ Pure data helpers, including `defineObjectBindings`, `patchBindings`,
|
|
|
104
104
|
`patchSceneConfig`, and `selectBindings`, are available from the server-safe
|
|
105
105
|
`@liveroom-tech/react-immersive/utils` entry.
|
|
106
106
|
|
|
107
|
+
## Embed a hosted project without React
|
|
108
|
+
|
|
109
|
+
For Shopify, WordPress, Webflow, or plain HTML, open a hosted project's **Share**
|
|
110
|
+
menu, set **General access** to **Anyone with the link**, and choose **Copy embed
|
|
111
|
+
code**. Paste that iframe into an HTML/embed block. No npm package or license key
|
|
112
|
+
is needed on the parent page. The embed shows the saved viewer without editing
|
|
113
|
+
or collaboration controls; restricted projects cannot be embedded.
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<iframe
|
|
117
|
+
src="https://react-immersive.liveroom.dev/embed/projects/YOUR_PROJECT_ID"
|
|
118
|
+
title="Interactive 3D viewer"
|
|
119
|
+
width="100%"
|
|
120
|
+
height="600"
|
|
121
|
+
style="display:block;width:100%;height:600px;border:0;"
|
|
122
|
+
loading="lazy"
|
|
123
|
+
allow="fullscreen; xr-spatial-tracking"
|
|
124
|
+
allowfullscreen
|
|
125
|
+
></iframe>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
See [Embedding outside React](https://react-immersive.liveroom.dev/docs/embedding)
|
|
129
|
+
for platform instructions, sizing, updates, and access behavior.
|
|
130
|
+
|
|
107
131
|
## Find the API for your task
|
|
108
132
|
|
|
109
133
|
- [ModelViewer](https://react-immersive.liveroom.dev/docs/reference/model-viewer.md): props, bindings, materials, annotations, exports, XR, performance.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as w,f as C,k as M,l as k}from"./chunk-AL6UIGWP.mjs";import{c as S,h as A,i as P}from"./chunk-FGAJ2UT7.mjs";import"./chunk-JR557W27.mjs";import{useMemo as q,useState as D}from"react";import{ChevronRight as I,EyeOff as V,Pause as L,Play as G,Rewind as J,Square as K}from"lucide-react";import{Fragment as Y,jsx as n,jsxs as i}from"react/jsx-runtime";var Q={playing:"Playing",paused:"Paused",finished:"Finished"};function R(o){let r=Number.isFinite(o)&&o>0?o:0;if(r<60)return`${r.toFixed(1)}s`;let u=Math.floor(r/60),m=(r%60).toFixed(1).padStart(4,"0");return`${u}:${m}`}function W(o){return Number.isFinite(o)?Math.min(3,Math.max(.1,Number(o.toFixed(2)))):1}function X({config:o,onChange:r,clipDetails:u,active:m,play:b,pause:y,stop:h,setSpeed:x,seek:T}){let v=S(A().tier,"animationConfig"),[c,$]=D(!1),F=q(()=>new Map(u.map(e=>[e.sourceName,e.duration])),[u]),f=o.animations.clips.filter(e=>!e.hidden),d=o.animations.clips.filter(e=>e.hidden),N=(e,a=o.animations.autoplayClip)=>{r({...o,animations:{clips:e(o.animations.clips),autoplayClip:a}})},g=(e,a)=>{N(t=>t.map(l=>l.sourceName===e?a(l):l))},B=(e,a)=>{g(e,t=>({...t,loopMode:a}))},z=(e,a)=>{let t=W(a);g(e,l=>({...l,speed:t})),m.some(l=>l.clip===e)&&x(t,e)},O=(e,a)=>{g(e,t=>({...t,displayName:a}))},H=e=>{let a=o.animations.autoplayClip===e?null:e;r({...o,animations:{...o.animations,autoplayClip:a}})},E=e=>{N(a=>a.map(t=>t.sourceName===e?{...t,hidden:!0}:t),o.animations.autoplayClip===e?null:o.animations.autoplayClip),m.some(a=>a.clip===e)&&h(e)},U=e=>{N(a=>a.map(t=>t.sourceName===e?{...t,hidden:!1}:t))};return o.animations.clips.length===0?n(C,{title:"Clips",children:n("div",{className:"se-helperCard",children:"This model has no animation clips. Open one that does to set playback, names, and autoplay here."})}):i(C,{title:"Clips",children:[v?null:n(P,{requiredTier:"starter",feature:"Autoplay, looping, speed and clip names"}),f.length===0?n("p",{className:"se-listEmpty",children:"All clips are hidden. Show one below to use it again."}):n("div",{className:"se-animationList",children:f.map(e=>{let a=m.find(s=>s.clip===e.sourceName),t=a?.status==="playing",l=a?.time??0,p=F.get(e.sourceName)??0,_=a?Q[a.status]:"Ready";return i("article",{className:`se-clip ${a?"se-clip--active":""}`,children:[i("div",{className:"se-clipHeader",children:[n("input",{className:"se-clipName","aria-label":`Name of ${e.sourceName}`,title:e.sourceName,value:e.displayName,onChange:s=>O(e.sourceName,s.target.value),placeholder:e.sourceName}),o.animations.autoplayClip===e.sourceName?n("span",{className:"rui-chip",children:"Autoplay"}):null,n("span",{className:"rui-chip",children:_}),n("button",{type:"button",className:"se-iconButton",onClick:()=>E(e.sourceName),title:"Hide clip","aria-label":`Hide ${e.sourceName}`,children:n(V,{size:13})})]}),i("div",{className:"se-clipTransport",children:[n("button",{type:"button",className:"se-iconButton",onClick:()=>t&&!a?.reverse?y(e.sourceName):b(e.sourceName,{alongside:!0}),"aria-label":t&&!a?.reverse?"Pause":"Play",title:t&&!a?.reverse?"Pause":"Play",children:t&&!a?.reverse?n(L,{size:13}):n(G,{size:13})}),n("button",{type:"button",className:"se-iconButton",onClick:()=>t&&a?.reverse?y(e.sourceName):b(e.sourceName,{alongside:!0,reverse:!0}),"aria-label":t&&a?.reverse?"Pause":"Play backwards",title:t&&a?.reverse?"Pause":"Play backwards",children:t&&a?.reverse?n(L,{size:13}):n(J,{size:13})}),n("button",{type:"button",className:"se-iconButton",onClick:()=>h(e.sourceName),disabled:!a,"aria-label":"Stop",title:"Stop",children:n(K,{size:13})}),n("input",{className:"se-slider se-clipSeek",type:"range",min:0,max:Math.max(p,.001),step:.01,value:Math.min(l,p),disabled:!a||p<=0,onChange:s=>T(Number(s.target.value),e.sourceName),"aria-label":"Seek"}),i("code",{className:"se-clipTime",children:[R(Math.min(l,p))," / ",R(p)]})]}),v?i(Y,{children:[n(w,{label:"Loop",path:"sceneConfig.animations.clips[\u2026].loopMode",children:i("select",{className:"se-select",value:e.loopMode,onChange:s=>B(e.sourceName,s.target.value),children:[n("option",{value:"repeat",children:"Loop"}),n("option",{value:"once",children:"Play once"}),n("option",{value:"ping-pong",children:"Ping-pong"})]})}),n(M,{label:"Speed",path:"sceneConfig.animations.clips[\u2026].speed",value:e.speed,min:.1,max:3,step:.1,formatValue:s=>`${s.toFixed(2)}x`,onChange:s=>z(e.sourceName,s)}),n(k,{label:"Autoplay",path:"sceneConfig.animations.autoplayClip",checked:o.animations.autoplayClip===e.sourceName,onChange:()=>H(e.sourceName)})]}):null]},e.sourceName)})}),d.length>0?i("section",{className:"se-removedAnimations",children:[n("div",{className:"se-panelHeaderRow",children:i("button",{type:"button",className:"se-panelHeader","aria-expanded":c,onClick:()=>$(e=>!e),children:[n(I,{size:13,className:`se-panelChevron ${c?"se-panelChevron--open":""}`}),i("span",{className:"se-panelTitle",children:["Hidden clips (",d.length,")"]})]})}),c?n("div",{className:"rui-list",children:d.map(e=>i("div",{className:"rui-listRow",children:[i("span",{className:"rui-listRowMain",children:[n("span",{className:"rui-listRowTitle",children:e.displayName||e.sourceName}),n("code",{className:"rui-listRowMeta",children:e.sourceName})]}),n("button",{type:"button",className:"bb-button bb-button--small",onClick:()=>U(e.sourceName),children:"Show"})]},e.sourceName))}):null]}):null]})}export{X as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as f}from"./chunk-FXV4CLAK.mjs";import{b as u,c as L,d as M,e as c}from"./chunk-AL6UIGWP.mjs";import{a as k,e as B}from"./chunk-7OWHW66D.mjs";import"./chunk-JR557W27.mjs";import{useState as v}from"react";import{Eye as I,Pencil as E,Plus as V,Trash2 as G,X as P}from"lucide-react";import{Fragment as $,jsx as t,jsxs as o}from"react/jsx-runtime";function H({config:r,onChange:w,cameraState:N,onPreviewView:b}){let[a,n]=v(null),[h,y]=v(""),[C,R]=v(""),z=e=>{n(structuredClone(e)),y(e.minDistance?.toString()??""),R(e.maxDistance?.toString()??"")},p=h.trim()===""?void 0:Number(h),d=C.trim()===""?void 0:Number(C),g=[p,d].some(e=>e!==void 0&&(!Number.isFinite(e)||e<0))?"Distances must be non-negative numbers.":p!==void 0&&d!==void 0&&p>d?"Maximum distance must be at least the minimum.":a?.images?.some(e=>e.src.trim()&&!k(e.src))||a?.links?.some(e=>e.href.trim()&&!k(e.href))?"Use an HTTP(S) URL or a relative path for images and links.":null,T=()=>{if(!a?.title.trim()||g)return;let e={...a,title:a.title.trim(),category:a.category?.trim()||void 0,minDistance:p,maxDistance:d,images:a.images?.filter(i=>i.src.trim()).map(i=>({...i,src:i.src.trim()})),links:a.links?.filter(i=>i.href.trim()).map(i=>({...i,href:i.href.trim(),label:i.label.trim()||"Learn more"}))};w({...r,annotations:r.annotations.map(i=>i.id===a.id?e:i)}),n(null)},[D,m]=v(null),F=e=>{w({...r,annotations:r.annotations.filter(i=>i.id!==e).map((i,l)=>({...i,id:l+1}))}),n(null)},S=(e,i)=>a&&n({...a,images:a.images.map((l,s)=>s===e?{...l,...i}:l)}),A=(e,i)=>a&&n({...a,links:a.links.map((l,s)=>s===e?{...l,...i}:l)});return o("div",{className:"se-annotations",children:[t(M,{title:"Annotations",children:t("span",{className:"se-listHeaderHint",children:"Double-click the model to add"})}),D!==null?t(f,{title:"Delete this annotation?",onCancel:()=>m(null),footer:o($,{children:[t("button",{type:"button",className:"bb-dialogButton",onClick:()=>m(null),children:"Cancel"}),t("button",{type:"button",className:"bb-dialogButton bb-dialogButton--danger",autoFocus:!0,onClick:()=>{F(D),m(null)},children:"Delete"})]}),children:t("p",{children:"You can undo this."})}):null,r.annotations.length===0?t("p",{className:"se-listEmpty",children:"No annotations yet."}):t("div",{className:"rui-list",children:r.annotations.map(e=>o("div",{className:"rui-listRow",children:[t("span",{className:"rui-listRowIndex",children:e.id}),o("span",{className:"rui-listRowMain",children:[t("span",{className:"rui-listRowTitle",title:e.title,children:e.title}),e.description||e.category?.trim()?t("span",{className:"rui-listRowMeta",title:e.description,children:[e.category?.trim(),e.description].filter(Boolean).join(" \xB7 ")}):null]}),o("span",{className:"rui-listRowActions",children:[B(e.cameraView)&&t("button",{type:"button",className:"se-iconButton",disabled:!b,onClick:()=>b?.(e.cameraView),title:"Preview saved view","aria-label":`Preview saved view for ${e.title}`,children:t(I,{size:13,"aria-hidden":"true"})}),t("button",{type:"button",className:"se-iconButton",onClick:()=>z(e),title:"Edit annotation","aria-label":`Edit ${e.title}`,children:t(E,{size:13,"aria-hidden":"true"})}),t("button",{type:"button",className:"se-iconButton",onClick:()=>m(e.id),title:"Delete annotation","aria-label":`Delete ${e.title}`,children:t(G,{size:13,"aria-hidden":"true"})})]})]},e.id))}),a&&t(f,{title:"Edit annotation",onCancel:()=>n(null),footer:o($,{children:[t("button",{type:"button",className:"bb-dialogButton bb-dialogFooterStart",onClick:()=>{m(a.id),n(null)},children:"Delete"}),t("button",{type:"button",className:"bb-dialogButton",onClick:()=>n(null),children:"Cancel"}),t("button",{type:"button",className:"bb-dialogButton bb-dialogButton--primary",disabled:!a.title.trim()||!!g,onClick:T,children:"Save"})]}),children:o("div",{className:"rui-dialogRows",children:[t(u,{label:"Title",children:t("input",{className:"bb-input",autoFocus:!0,value:a.title,onChange:e=>n({...a,title:e.target.value})})}),t(u,{label:"Description",children:t("textarea",{className:"bb-textarea bb-textarea--short",rows:2,value:a.description,onChange:e=>n({...a,description:e.target.value})})}),t(u,{label:"Category",children:t("input",{className:"bb-input",value:a.category??"",placeholder:"Features",onChange:e=>n({...a,category:e.target.value})})}),t(u,{label:"Position",children:t("code",{className:"rui-readout",children:a.worldPosition.map(e=>e.toFixed(2)).join(", ")})}),o(c,{title:"Camera view",children:[t("p",{className:"rui-note",children:a.cameraView?"Tours fly to this view.":"Tours zoom in on the marker unless you capture a view."}),o(L,{children:[t("button",{type:"button",className:"bb-button",disabled:!N,onClick:()=>N&&n({...a,cameraView:structuredClone(N)}),children:"Capture"}),t("button",{type:"button",className:"bb-button",disabled:!a.cameraView||!b,onClick:()=>a.cameraView&&b?.(a.cameraView),children:"Preview"}),t("button",{type:"button",className:"bb-button",disabled:!a.cameraView,onClick:()=>n({...a,cameraView:void 0}),children:"Clear"})]})]}),t(c,{title:"Visible between",children:t(u,{label:"Distance",title:"In scene units. Leave blank to show the marker at any distance.",children:o("span",{className:"rui-pair",children:[t("input",{className:"bb-input",type:"number",min:"0",step:"any","aria-label":"Minimum distance",placeholder:"Min",value:h,onChange:e=>y(e.target.value)}),t("input",{className:"bb-input",type:"number",min:"0",step:"any","aria-label":"Maximum distance",placeholder:"Max",value:C,onChange:e=>R(e.target.value)})]})})}),t(c,{title:"Images",actions:t("button",{type:"button",className:"se-iconButton",title:"Add image","aria-label":"Add image",onClick:()=>n({...a,images:[...a.images??[],{src:"",alt:""}]}),children:t(V,{size:14})}),children:a.images?.map((e,i)=>o("div",{className:"rui-mediaRow",children:[t("input",{className:"bb-input","aria-label":`Image URL ${i+1}`,placeholder:"https://example.com/image.jpg",value:e.src,onChange:l=>S(i,{src:l.target.value})}),t("input",{className:"bb-input","aria-label":`Image description ${i+1}`,placeholder:"Description",value:e.alt??"",onChange:l=>S(i,{alt:l.target.value})}),t("button",{type:"button",className:"se-iconButton",title:"Remove image","aria-label":`Remove image ${i+1}`,onClick:()=>n({...a,images:a.images.filter((l,s)=>s!==i)}),children:t(P,{size:13})})]},i))}),t(c,{title:"Links",actions:t("button",{type:"button",className:"se-iconButton",title:"Add link","aria-label":"Add link",onClick:()=>n({...a,links:[...a.links??[],{href:"",label:""}]}),children:t(V,{size:14})}),children:a.links?.map((e,i)=>o("div",{className:"rui-mediaRow",children:[t("input",{className:"bb-input","aria-label":`Link URL ${i+1}`,placeholder:"https://example.com/details",value:e.href,onChange:l=>A(i,{href:l.target.value})}),t("input",{className:"bb-input","aria-label":`Link label ${i+1}`,placeholder:"Learn more",value:e.label,onChange:l=>A(i,{label:l.target.value})}),t("button",{type:"button",className:"se-iconButton",title:"Remove link","aria-label":`Remove link ${i+1}`,onClick:()=>n({...a,links:a.links.filter((l,s)=>s!==i)}),children:t(P,{size:13})})]},i))}),g?t("p",{className:"bb-note bb-note--error",role:"alert",children:g}):null]})})]})}export{H as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as A,d as h,k as C,l as d}from"./chunk-AL6UIGWP.mjs";import{a as N}from"./chunk-37YITTIK.mjs";import"./chunk-JR557W27.mjs";import{useState as T,useCallback as p}from"react";import{ArrowDown as M,ArrowUp as E,MapPin as F,Plus as L,Trash2 as B}from"lucide-react";import{jsx as n,jsxs as m}from"react/jsx-runtime";var I={enabled:!0,waypoints:[],loop:!0,autoPlay:!1},b=3.5;function U({config:g,onChange:w,cameraState:r,onPreviewWaypoint:f}){let i=g.cinematic??I,W=N(),{waypoints:o}=i,u=p((t,e)=>{if(t.length<2)return 0;let s=0;for(let a=0;a<t.length-1;a++){let c=t[a].segmentDuration??b;s+=c}return e&&t.length>1&&(s+=t[t.length-1].segmentDuration??b),Math.max(s,0)},[]),l=p(t=>{w({...g,cinematic:{...i,...t}})},[g,i,w]),R=p(()=>{if(!r)return;let t={position:[...r.position],target:[...r.target],...r.azimuthAngle!=null?{azimuthAngle:r.azimuthAngle}:{},...r.polarAngle!=null?{polarAngle:r.polarAngle}:{},segmentDuration:b},e=[...o,t],s=u(e,i.loop);l({waypoints:e,duration:s})},[r,o,i.loop,u,l]),k=p(t=>{let e=o.filter((a,c)=>c!==t),s=u(e,i.loop);l({waypoints:e,duration:s})},[o,i.loop,u,l]),v=p((t,e)=>{let s=t+e;if(s<0||s>=o.length)return;let a=[...o];[a[t],a[s]]=[a[s],a[t]];let c=u(a,i.loop);l({waypoints:a,duration:c})},[o,i.loop,u,l]),z=p((t,e)=>{let s=o.map((c,P)=>P===t?{...c,...e}:c),a=u(s,i.loop);l({waypoints:s,duration:a})},[o,i.loop,u,l]),[y,S]=T(!1),_=o.some(t=>t.segmentDuration!==void 0),$=p(t=>t>=o.length-1?b:o[t]?.segmentDuration??b,[o]),D=o.length>=2;return m("div",{className:"se-cinematic",children:[m("div",{className:"se-cinematicSettings",children:[n(h,{title:"Playback"}),n(d,{label:"Enabled",path:"sceneConfig.cinematic.enabled",checked:i.enabled,onChange:t=>l({enabled:t})}),n(d,{label:"Loop",path:"sceneConfig.cinematic.loop",checked:i.loop,onChange:t=>{l({loop:t,duration:u(o,t)})}}),n(d,{label:"Autoplay",path:"sceneConfig.cinematic.autoPlay",checked:i.autoPlay,onChange:t=>l({autoPlay:t})}),i.autoPlay&&W?n("p",{className:"rui-note",children:"Your device reduces motion, so this preview won't play on its own. Visitors without that setting will see it."}):null,n(d,{label:"Segment timing",checked:y,onChange:S}),!y&&D?n(C,{label:"Duration",path:"sceneConfig.cinematic.duration",value:i.duration??u(o,i.loop),min:4,max:120,step:1,formatValue:t=>`${t}s`,onChange:t=>l({duration:t})}):n(A,{label:"Total",children:n("code",{className:"rui-readout",children:D?`${(i.duration??u(o,i.loop)).toFixed(1)}s`:"Add at least 2 waypoints"})})]}),m("div",{className:"se-cinematicWaypoints",children:[n(h,{title:`Waypoints${o.length?` (${o.length})`:""}`,children:m("button",{type:"button",className:"bb-button bb-button--small",onClick:R,disabled:!r,title:"Capture the current camera view as a waypoint",children:[n(L,{size:13,"aria-hidden":"true"}),"Add from view"]})}),o.length===0?n("p",{className:"se-listEmpty",children:"Frame the model, then add it as a waypoint. The camera glides through them in order."}):n("div",{className:"rui-list",children:o.map((t,e)=>{let s=e===o.length-1;return m("div",{children:[m("div",{className:"rui-listRow",children:[n("span",{className:"rui-listRowIndex",children:e+1}),n("span",{className:"rui-listRowMain",children:n("code",{className:"rui-listRowCode",title:"Camera position",children:t.position.map(a=>a.toFixed(2)).join(", ")})}),m("span",{className:"rui-listRowActions rui-listRowActions--visible",children:[n("button",{type:"button",className:"se-iconButton",disabled:!f,onClick:()=>f?.(t),title:"Fly to this waypoint","aria-label":`Fly to waypoint ${e+1}`,children:n(F,{size:13})}),n("button",{type:"button",className:"se-iconButton",disabled:e===0,onClick:()=>v(e,-1),title:"Move up","aria-label":`Move waypoint ${e+1} up`,children:n(E,{size:13})}),n("button",{type:"button",className:"se-iconButton",disabled:s,onClick:()=>v(e,1),title:"Move down","aria-label":`Move waypoint ${e+1} down`,children:n(M,{size:13})}),n("button",{type:"button",className:"se-iconButton",onClick:()=>k(e),title:"Delete waypoint","aria-label":`Delete waypoint ${e+1}`,children:n(B,{size:13})})]})]}),y&&!s?n(C,{label:`${e+1} \u2192 ${e+2}`,path:"sceneConfig.cinematic.waypoints[\u2026].segmentDuration",value:$(e),min:1,max:20,step:.5,formatValue:a=>`${a.toFixed(1)}s`,onChange:a=>z(e,{segmentDuration:a})}):null]},`waypoint-${e}`)})})]})]})}export{U as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{b as B,d as X,g as q,l as Q,m as le,o as ce}from"./chunk-AL6UIGWP.mjs";import{c as Ne,e as ke,f as we,h as Oe,i as _}from"./chunk-FGAJ2UT7.mjs";import{d as re,e as fe,f as ve,m as ye,n as Ce}from"./chunk-7JCFNZJM.mjs";import"./chunk-GV4ZRXL6.mjs";import"./chunk-BNKTI3CY.mjs";import"./chunk-JR557W27.mjs";import{useEffect as ne,useState as T}from"react";import{ArrowDown as Me,ArrowUp as Be,Check as qe,ChevronRight as ze,Copy as De,Crosshair as Ee,EyeOff as je,MousePointerClick as Ue,Palette as Ke,Play as Le,Plus as pe,Trash2 as ee,X as Fe}from"lucide-react";import{Fragment as Z,jsx as t,jsxs as c}from"react/jsx-runtime";var Je=["list","chips","swatches"],de=["USD","EUR","GBP","SGD","AUD","CAD","INR","JPY"],We="https://shop.example.com/cart/add?sku={sku}&qty={quantity}";function te(o,n){let r=1;for(;n.includes(`${o}-${r}`);)r++;return`${o}-${r}`}function z(o,n,r){let a=o.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||n;return r.includes(a)?te(a,r):a}function Pe(o,n="New choice"){return{id:z(n,"choice",o),label:n,required:!0,defaultOptionId:"option-1",options:[{id:"option-1",label:"Option 1"},{id:"option-2",label:"Option 2"}]}}function oe(o,n){return o[n]?.label||n}function Ae(o){let n=o?.style?.material?.baseColor;return typeof n=="string"&&/^#[0-9a-f]{3,8}$/i.test(n)?n:"#888888"}function Se(o,n,r){let a=`${oe(o,n)} color`,h=Ae(o[n]);return{id:z(a,"color",r),label:a,required:!0,display:"swatches",defaultOptionId:"original",options:[{id:"original",label:"Original",swatch:h},{id:"color-2",label:"New color",swatch:"#2457c5",appearance:[{target:n,material:{baseColor:"#2457c5"}}]}]}}function Ie(o,n,r){let a=oe(o,n);return{id:z(a,"part",r),label:a,required:!0,display:"chips",defaultOptionId:"included",options:[{id:"included",label:"Included",appearance:[{target:n,visible:!0}]},{id:"not-included",label:"Not included",appearance:[{target:n,visible:!1}]}]}}function Ve(o){try{return new Intl.NumberFormat(void 0,{style:"currency",currency:o}).resolvedOptions().maximumFractionDigits??2}catch{return 2}}function He(o){return typeof o=="string"?`object:${o}`:Array.isArray(o)?`object:${o[0]??""}`:"group"in o?`group:${o.group}`:"tag"in o?`tag:${o.tag}`:"type"in o?`type:${o.type}`:""}function Ye(o){let n=o.indexOf(":"),r=o.slice(0,n),a=o.slice(n+1);return r==="group"?{group:a}:r==="tag"?{tag:a}:r==="type"?{type:a}:a}function _e(o){let n=Object.entries(o).filter(([,a])=>!a.removed),r=a=>[...new Set(a.filter(h=>!!h))].sort();return{groups:r(n.map(([,a])=>a.group)),tags:r(n.flatMap(([,a])=>a.tags??[])),objects:n.map(([a,h])=>({key:a,label:h.label||a}))}}function $({label:o,value:n,placeholder:r,onCommit:a,path:h}){let[w,v]=T(n);ne(()=>v(n),[n]);let N=()=>{w.trim()!==n&&a(w.trim())};return t(B,{label:o,path:h,children:t("input",{className:"se-textInput","aria-label":o,value:w,placeholder:r,onChange:m=>v(m.target.value),onBlur:N,onKeyDown:m=>{m.key==="Enter"&&N()}})})}function Te({label:o,valueMinor:n,currency:r,signed:a,onCommit:h,path:w}){let v=Ve(r),N=n===void 0?"":(n/10**v).toFixed(v),[m,M]=T(N);ne(()=>M(N),[N]);let O=()=>{if(m.trim()===N)return;let y=Number(m);if(!m.trim()||!Number.isFinite(y)||!a&&y<0){M(N),m.trim()||h(void 0);return}h(Math.round(y*10**v))};return t(B,{label:o,path:w,children:c("span",{className:"se-productMoney",children:[t("input",{className:"se-textInput","aria-label":o,inputMode:"decimal",value:m,placeholder:"0",onChange:y=>M(y.target.value),onBlur:O,onKeyDown:y=>{y.key==="Enter"&&O()}}),t("span",{children:r})]})})}function P({label:o,onClick:n,disabled:r,children:a}){return t("button",{type:"button",className:"se-iconButton","aria-label":o,title:o,disabled:r,onClick:n,children:a})}function ue(o,n,r){let a=[...o],[h]=a.splice(n,1);return a.splice(n+r,0,h),a}function Xe(o){return o.visible===!1?"hide":o.visible===!0?"show":"color"}function Qe({edit:o,bindings:n,selectedKey:r,onChange:a,onRemove:h}){let{groups:w,tags:v,objects:N}=_e(n),m=He(o.target),M=m.startsWith("group:")?w.includes(m.slice(6)):m.startsWith("tag:")?v.includes(m.slice(4)):m.startsWith("object:")?N.some(u=>u.key===m.slice(7)):!1,O=Xe(o),y=o.material?.baseColor;return c("div",{className:"se-productChange",children:[t(B,{label:"Part",children:c("span",{className:"se-productInline",children:[c("select",{className:"se-select","aria-label":"Part of the model",value:m,onChange:u=>a({...o,target:Ye(u.target.value)}),children:[M?null:t("option",{value:m,children:m||"Choose a part"}),t("optgroup",{label:"Objects",children:N.map(u=>t("option",{value:`object:${u.key}`,children:u.label},u.key))}),w.length?t("optgroup",{label:"Groups",children:w.map(u=>t("option",{value:`group:${u}`,children:u},u))}):null,v.length?t("optgroup",{label:"Tags",children:v.map(u=>t("option",{value:`tag:${u}`,children:u},u))}):null]}),r&&m!==`object:${r}`?t(P,{label:`Use the selected object: ${oe(n,r)}`,onClick:()=>a({...o,target:r}),children:t(Ee,{size:13})}):null,t(P,{label:"Remove this change",onClick:h,children:t(Fe,{size:13})})]})}),t(B,{label:"Does",children:c("select",{className:"se-select","aria-label":"What this does",value:O,onChange:u=>{let k=u.target.value;a(k==="color"?{target:o.target,material:{...o.material,baseColor:typeof y=="string"?y:"#888888"}}:{target:o.target,visible:k==="show"})},children:[t("option",{value:"color",children:"Changes its color"}),t("option",{value:"hide",children:"Hides it"}),t("option",{value:"show",children:"Shows it"})]})}),O==="color"?t(ce,{label:"Color",value:typeof y=="string"?y:"#888888",onChange:u=>a({...o,material:{...o.material,baseColor:u}})}):null]})}function Ze({group:o,option:n,index:r,definition:a,bindings:h,variantGroups:w,canSell:v,selectedKey:N,isStart:m,isShown:M,open:O,onToggleOpen:y,onSetStart:u,onChange:k,onRemove:E,onMove:j,onDuplicate:F}){let D=n.appearance??[],U=w.flatMap(p=>p.variants.map(R=>R.name)),K=N??Object.keys(h)[0]??"",x=[m?"customers start here":"",!D.length&&!n.variants?.length?"changes nothing":""].filter(Boolean).join(" \xB7 "),L=p=>{let R=n.appearance?.[0]?.material?.baseColor,S=p[0]?.material?.baseColor,I=n.swatch!==void 0&&n.swatch===R&&typeof S=="string";k({appearance:p.length?p:void 0,...I?{swatch:S}:{}})};return c("div",{className:`se-productOption ${O?"se-productOption--open":""} ${M?"se-productOption--shown":""}`,children:[t("div",{className:"se-productOptionHeader",children:c("button",{type:"button",className:"se-productOptionToggle","aria-expanded":O,title:"Edit this option and show it on the model",onClick:y,children:[t(ze,{size:12,"aria-hidden":"true",className:O?"se-productChevron--open":""}),n.swatch?t("span",{className:"se-productSwatch",style:{background:n.swatch},"aria-hidden":"true"}):null,t("span",{className:"se-productOptionName",children:n.label}),x?t("small",{children:x}):null]})}),O?c("div",{className:"se-productOptionBody",children:[t($,{label:"Name",value:n.label,onCommit:p=>{p&&k({label:p})}}),v&&a.pricing?t(Te,{label:"Price change",signed:!0,currency:a.pricing.currency,valueMinor:n.priceDeltaMinor,onCommit:p=>k({priceDeltaMinor:p})}):null,D.map((p,R)=>t(Qe,{edit:p,bindings:h,selectedKey:N,onChange:S=>L(D.map((I,C)=>C===R?S:I)),onRemove:()=>L(D.filter((S,I)=>I!==R))},R)),c("div",{className:"se-productActions",children:[c("button",{type:"button",className:"bb-button",disabled:!K,onClick:()=>L([...D,{target:K,material:{baseColor:Ae(h[K])}}]),children:[t(pe,{size:13,"aria-hidden":"true"})," ",D.length?"Change another part":"Change a part"]}),m?null:t("button",{type:"button",className:"bb-button",onClick:u,children:"Start here"})]}),c("details",{className:"se-productMore",children:[t("summary",{children:"More"}),t($,{label:"Description",value:n.description??"",placeholder:"Shown under the name",onCommit:p=>k({description:p||void 0})}),t(Q,{label:"Swatch",checked:!!n.swatch,onChange:p=>k({swatch:p?"#888888":void 0})}),n.swatch?t(ce,{label:"Swatch color",value:n.swatch,onChange:p=>k({swatch:p})}):null,U.length?t(B,{label:"Material variant",children:c("select",{className:"se-select","aria-label":"Material variant",value:n.variants?.[0]??"",onChange:p=>k({variants:p.target.value?[p.target.value]:void 0}),children:[t("option",{value:"",children:"None"}),U.map(p=>t("option",{value:p,children:p},p))]})}):null,v?t($,{label:"SKU",value:n.sku??"",placeholder:"Your stock code",onCommit:p=>k({sku:p||void 0})}):null,c("div",{className:"se-productActions",children:[t(P,{label:`Move ${n.label} up`,disabled:r===0,onClick:()=>j(-1),children:t(Be,{size:13})}),t(P,{label:`Move ${n.label} down`,disabled:r===o.options.length-1,onClick:()=>j(1),children:t(Me,{size:13})}),t(P,{label:`Duplicate ${n.label}`,onClick:F,children:t(De,{size:13})}),t(P,{label:`Delete ${n.label}`,disabled:o.options.length<=1,onClick:E,children:t(ee,{size:13})})]})]})]}):null]})}function Re(o,n){let r=o.groups.find(a=>a.id===n.groupId);return`${r?.label??n.groupId}: ${r?.options.find(a=>a.id===n.optionId)?.label??n.optionId}`}function $e({bindings:o,selectedKey:n,disabled:r,onColor:a,onVisibility:h}){return!n||!o[n]?c("p",{className:"se-productHint",children:[t(Ue,{size:14,"aria-hidden":"true"}),"Click a part of the model to let customers change it."]}):c("div",{className:"se-productStarter",children:[c("p",{children:["Let customers change ",t("strong",{children:oe(o,n)}),":"]}),c("div",{className:"se-productActions",children:[c("button",{type:"button",className:"bb-button",disabled:r,onClick:()=>a(n),children:[t(Ke,{size:13,"aria-hidden":"true"})," Its color"]}),c("button",{type:"button",className:"bb-button",disabled:r,onClick:()=>h(n),children:[t(je,{size:13,"aria-hidden":"true"})," Show or hide it"]})]})]})}function et({code:o}){let[n,r]=T(!1);return ne(()=>{if(!n)return;let a=setTimeout(()=>r(!1),2e3);return()=>clearTimeout(a)},[n]),c("div",{className:"se-productCode",children:[t("pre",{children:o}),t(P,{label:n?"Copied":"Copy code",onClick:()=>{navigator.clipboard.writeText(o).then(()=>r(!0)).catch(()=>{})},children:n?t(qe,{size:13}):t(De,{size:13})})]})}function tt({config:o,onChange:n,objectBindings:r,materialVariantGroups:a,selectedKey:h,previewSelections:w,onPreviewChange:v,onPreviewAsCustomer:N,publish:m,modelFileName:M}){let{tier:O}=Oe(),y=Ne(O,"productCommerce"),u=o.product,[k,E]=T(null),[j,F]=T(null),[D,U]=T({}),[K,x]=T(null),L=JSON.stringify(u?.definition??null),[p,R]=T("");ne(()=>{R(u?JSON.stringify(u.definition,null,2):"")},[L]);let S=(e,l=!1)=>D[e]??l,I=(e,l=!1)=>U(s=>({...s,[e]:!(s[e]??l)})),C=e=>{try{let l=re(e),s=Object.fromEntries(l.groups.map(d=>{let b=u?.selections[d.id];return[d.id,b===null||d.options.some(g=>g.id===b)?b??null:d.defaultOptionId??null]}));n({...o,product:{definition:l,selections:s}}),E(null)}catch(l){E(l instanceof Error?l.message:String(l))}},be=M.replace(/\.[a-z0-9]+$/i,"").replace(/[-_]+/g," ").trim()||"My product",J=e=>{let l={id:z(be,"product",[]),label:be,revision:"1",groups:e};n({...o,product:{definition:l,selections:fe(l)}})};if(!u)return c("div",{className:"se-productEmpty",children:[t("h3",{children:"Let customers customize this model"}),t("p",{children:"They pick from your options beside the model and watch it change, with a price and a button to buy."}),c("div",{className:"se-productExample","aria-hidden":"true",children:[t("span",{children:"Wood"}),t("i",{style:{background:"#b89063"}}),t("i",{className:"is-on",style:{background:"#453025"}}),t("i",{style:{background:"#d7c4a3"}}),t("span",{children:"Fabric"}),t("b",{children:"Linen"}),t("b",{className:"is-on",children:"Leather"}),t("em",{children:"$304.00"}),t("u",{children:"Buy"})]}),t($e,{bindings:r,selectedKey:h,onColor:e=>{let l=Se(r,e,[]);J([l]),x(`${l.id}/color-2`),v({[l.id]:"color-2"})},onVisibility:e=>J([Ie(r,e,[])])}),a.length?c("button",{type:"button",className:"bb-button",onClick:()=>{let e=[];J(a.map(l=>{let s=z(l.name??"","variants",e);e.push(s);let d=[],b=l.variants.map(f=>{let Y=z(f.label,"option",d);return d.push(Y),{id:Y,label:f.label,variants:[f.name],...f.swatch?.startsWith("#")?{swatch:f.swatch}:{}}}),g=b.every(f=>f.swatch)?"swatches":"list";return{id:s,label:l.name??"Variant",required:!0,defaultOptionId:b[0]?.id,display:g,options:b}}))},children:["Use this model's ",a.flatMap(e=>e.variants).length," material variants"]}):null,t("button",{type:"button",className:"se-productLink",onClick:()=>J([Pe([],"Finish")]),children:"Or start with a blank choice"})]});let i=u.definition,ie=i.groups.map(e=>e.id),xe=ke(O,"productGroups",i.groups.length),W=i.groups.flatMap(e=>e.options.map(l=>({groupId:e.id,optionId:l.id}))),G=e=>JSON.stringify([e.groupId,e.optionId]),me=e=>{let[l,s]=JSON.parse(e);return{groupId:l,optionId:s}},he=ve(i,u.selections),ge=Ce(i,r,a.length?a.flatMap(e=>e.variants.map(l=>l.name)):void 0),V=w??u.selections,se=e=>{let l=b=>e.some(g=>g.id===b.groupId&&g.options.some(f=>f.id===b.optionId)),s=(i.rules??[]).filter(b=>l(b.when)).map(b=>({...b,requires:b.requires?.filter(l),excludes:b.excludes?.filter(l)})).filter(b=>b.requires?.length||b.excludes?.length),d=b=>JSON.stringify(b.map(g=>[g.id,g.required,g.options.map(f=>f.id)]));C({...i,groups:e,rules:s,skus:d(e)===d(i.groups)?i.skus:void 0})},ae=(e,l)=>{se([...i.groups,e]),U(s=>({...s,[`group:${e.id}`]:!0})),l&&(x(`${e.id}/${l}`),v({...V,[e.id]:l}))},A=(e,l)=>se(i.groups.map(s=>s.id===e?{...s,...l}:s)),Ge=(e,l,s)=>A(e.id,{options:e.options.map(d=>d.id===l?{...d,...s}:d)}),H=(e,l)=>C({...i,rules:i.rules.map(s=>s.id===e?{...s,...l}:s)});return c("div",{className:"se-generalContent",children:[c("div",{className:"se-productTop",children:[t($,{label:"Product",path:"sceneConfig.product.definition.label",value:i.label,onCommit:e=>{e&&C({...i,label:e})}}),t("div",{className:"se-productActions",children:c("button",{type:"button",className:"bb-button bb-button--primary",onClick:N,children:[t(Le,{size:13,"aria-hidden":"true"})," Preview as a customer"]})})]}),ge.length?t("ul",{className:"se-productWarnings","aria-label":"Problems to fix",children:ge.map((e,l)=>t("li",{children:e.message},l))}):null,k?t("p",{className:"bb-note bb-note--error se-productError",role:"alert",children:k}):null,t(X,{title:"What customers can choose"}),i.groups.map(e=>{let l=u.selections[e.id]??null;return c(q,{title:e.label,open:S(`group:${e.id}`,i.groups.length===1),onToggle:()=>I(`group:${e.id}`,i.groups.length===1),trailing:c("small",{className:"se-productCount",children:[e.options.length," options"]}),children:[t("div",{className:"se-productOptions",children:e.options.map((s,d)=>{let b=`${e.id}/${s.id}`;return t(Ze,{group:e,option:s,index:d,definition:i,bindings:r,variantGroups:a,canSell:y,selectedKey:h,isStart:l===s.id,isShown:V[e.id]===s.id,open:K===b,onToggleOpen:()=>{x(g=>g===b?null:b),v({...V,[e.id]:s.id})},onSetStart:()=>{let g={...i,groups:i.groups.map(f=>f.id===e.id?{...f,defaultOptionId:s.id}:f)};n({...o,product:{definition:g,selections:{...u.selections,[e.id]:s.id}}})},onChange:g=>Ge(e,s.id,g),onMove:g=>A(e.id,{options:ue(e.options,d,g)}),onDuplicate:()=>{let g=e.options.map(Y=>Y.id),f=[...e.options];f.splice(d+1,0,{...structuredClone(s),id:te("option",g),label:`${s.label} copy`,sku:void 0}),A(e.id,{options:f})},onRemove:()=>{let g=e.options.filter(f=>f.id!==s.id);A(e.id,{options:g,defaultOptionId:e.defaultOptionId===s.id?e.required?g[0]?.id:void 0:e.defaultOptionId})}},s.id)})}),t("div",{className:"se-productActions",children:c("button",{type:"button",className:"bb-button",onClick:()=>{let s=te("option",e.options.map(b=>b.id)),d=e.display==="swatches";A(e.id,{options:[...e.options,{id:s,label:d?"New color":`Option ${e.options.length+1}`,...d?{swatch:"#888888"}:{}}]}),x(`${e.id}/${s}`),v({...V,[e.id]:s})},children:[t(pe,{size:13,"aria-hidden":"true"})," Add option"]})}),c("details",{className:"se-productMore",children:[t("summary",{children:"Choice settings"}),t($,{label:"Name",value:e.label,onCommit:s=>{s&&A(e.id,{label:s})}}),t(le,{label:"Show as",value:e.display??"list",options:Je,onChange:s=>A(e.id,{display:s})}),t(Q,{label:"Customers can skip it",checked:!e.required,onChange:s=>A(e.id,{required:!s,defaultOptionId:e.defaultOptionId??(s?void 0:e.options[0]?.id)})}),c("div",{className:"se-productActions",children:[t(P,{label:`Move ${e.label} up`,disabled:i.groups.indexOf(e)===0,onClick:()=>{let s=i.groups.indexOf(e);C({...i,groups:ue(i.groups,s,-1)})},children:t(Be,{size:13})}),t(P,{label:`Move ${e.label} down`,disabled:i.groups.indexOf(e)===i.groups.length-1,onClick:()=>{let s=i.groups.indexOf(e);C({...i,groups:ue(i.groups,s,1)})},children:t(Me,{size:13})}),t(P,{label:`Delete ${e.label}`,disabled:i.groups.length<=1,onClick:()=>se(i.groups.filter(s=>s.id!==e.id)),children:t(ee,{size:13})})]})]})]},e.id)}),xe?c("div",{className:"se-productAdd",children:[t($e,{bindings:r,selectedKey:h,onColor:e=>ae(Se(r,e,ie),"color-2"),onVisibility:e=>ae(Ie(r,e,ie))}),t("button",{type:"button",className:"se-productLink",onClick:()=>ae(Pe(ie)),children:"Or add a blank choice"})]}):t(_,{requiredTier:we("productGroups",i.groups.length),feature:"More choices"}),t(q,{title:"Prices and buying",open:S("selling"),onToggle:()=>I("selling"),children:y?c(Z,{children:[t(Q,{label:"Show a price",checked:!!i.pricing,onChange:e=>C({...i,pricing:e?{currency:"USD",basePriceMinor:0}:void 0})}),i.pricing?c(Z,{children:[t(le,{label:"Currency",path:"sceneConfig.product.definition.pricing.currency",value:i.pricing.currency,options:de.includes(i.pricing.currency)?de:[...de,i.pricing.currency],onChange:e=>C({...i,pricing:{...i.pricing,currency:e}})}),t(Te,{label:"Base price",path:"sceneConfig.product.definition.pricing.basePriceMinor",currency:i.pricing.currency,valueMinor:i.pricing.basePriceMinor,onCommit:e=>C({...i,pricing:{...i.pricing,basePriceMinor:e??0}})}),t("p",{className:"bb-note",children:"Open an option to add what it costs extra. This price is for show: always charge from your own store."})]}):null,t($,{label:"Buy link",path:"sceneConfig.product.definition.checkout.urlTemplate",placeholder:We,value:i.checkout?.urlTemplate??"",onCommit:e=>C({...i,checkout:e?{...i.checkout,urlTemplate:e}:void 0})}),i.checkout?t($,{label:"Button text",placeholder:"Buy now",value:i.checkout.label??"",onCommit:e=>C({...i,checkout:{...i.checkout,label:e||void 0}})}):null,c("p",{className:"bb-note",children:["Where the button goes. The link can include ","{sku}",", ","{quantity}",", ","{productId}"," and ","{selections}","."]})]}):t(_,{requiredTier:"starter",feature:"Prices and buy links"})}),t(q,{title:`Restrictions${i.rules?.length?` (${i.rules.length})`:""}`,open:S("rules"),onToggle:()=>I("rules"),children:y?c(Z,{children:[t("p",{className:"bb-note",children:"For combinations you don't sell. Customers see your message, and picking a blocked option changes the others to fit."}),i.rules?.map(e=>{let l=e.excludes?.length?"excludes":"requires",s=(e[l]??[])[0];return c("div",{className:"se-productRule",children:[t(B,{label:"When",children:t("select",{className:"se-select","aria-label":`Condition for ${e.id}`,value:G(e.when),onChange:d=>H(e.id,{when:me(d.target.value)}),children:W.map(d=>t("option",{value:G(d),children:Re(i,d)},G(d)))})}),t(B,{label:"Then",children:c("select",{className:"se-select","aria-label":`Kind of rule for ${e.id}`,value:l,onChange:d=>{let b=d.target.value;H(e.id,b==="requires"?{requires:e.excludes,excludes:void 0}:{excludes:e.requires,requires:void 0})},children:[t("option",{value:"requires",children:"Must have"}),t("option",{value:"excludes",children:"Can't have"})]})}),t(B,{label:"Option",children:t("select",{className:"se-select","aria-label":`Choice for ${e.id}`,value:s?G(s):"",onChange:d=>H(e.id,{[l]:[me(d.target.value)]}),children:W.filter(d=>d.groupId!==e.when.groupId).map(d=>t("option",{value:G(d),children:Re(i,d)},G(d)))})}),t($,{label:"Message",placeholder:"Shown when it's blocked",value:e.message??"",onCommit:d=>H(e.id,{message:d||void 0})}),t("div",{className:"se-productActions",children:t(P,{label:`Delete restriction ${e.id}`,onClick:()=>C({...i,rules:i.rules.filter(d=>d.id!==e.id)}),children:t(ee,{size:13})})})]},e.id)}),i.groups.length<2?t("p",{className:"bb-note",children:"Add a second choice to restrict combinations."}):t("div",{className:"se-productActions",children:c("button",{type:"button",className:"bb-button",onClick:()=>{let e=W[0],l=W.find(s=>s.groupId!==e.groupId);C({...i,rules:[...i.rules??[],{id:te("rule",(i.rules??[]).map(s=>s.id)),when:e,requires:[l]}]})},children:[t(pe,{size:13,"aria-hidden":"true"})," Add restriction"]})})]}):t(_,{requiredTier:"starter",feature:"Restrictions"})}),t(q,{title:"Publish",open:S("publish"),onToggle:()=>I("publish"),children:m?c("div",{className:"se-productPublish",children:[t("p",{className:"bb-note",children:"Customers can choose wherever this project is shared or embedded. Set access to Anyone with the link, then copy the embed code."}),m]}):c("div",{className:"se-productPublish",children:[c("p",{className:"bb-note",children:["Use ",t("strong",{children:"Export \u203A Scene settings"})," in the top bar, then show it with the options panel on:"]}),t(et,{code:`<ModelViewer
|
|
2
|
+
modelUrl="/model.glb"
|
|
3
|
+
licenseKey={licenseKey}
|
|
4
|
+
sceneConfig={sceneConfig}
|
|
5
|
+
productOptions
|
|
6
|
+
/>`})]})}),c(q,{title:"Advanced",open:S("advanced"),onToggle:()=>I("advanced"),children:[t($,{label:"Product ID",path:"sceneConfig.product.definition.id",value:i.id,onCommit:e=>{e&&C({...i,id:e})}}),t($,{label:"Revision",path:"sceneConfig.product.definition.revision",value:i.revision,onCommit:e=>{e&&C({...i,revision:e})}}),y?c(Z,{children:[t(X,{title:`SKU combinations (${i.skus?.length??0})`}),t("p",{className:"bb-note",children:"Once this list has entries, combinations not on it can't be bought."}),c("div",{className:"se-productActions",children:[t("button",{type:"button",className:"bb-button",onClick:()=>{try{let e=ye({...i,skus:void 0});F(e.length?`Generated ${e.length} ${e.length===1?"combination":"combinations"}.`:"Give each option an SKU first, under More."),e.length&&C({...i,skus:e})}catch(e){F(e instanceof Error?e.message:String(e))}},children:"Generate from option SKUs"}),i.skus?.length?t(P,{label:"Clear SKU combinations",onClick:()=>C({...i,skus:void 0}),children:t(ee,{size:13})}):null]}),j?t("p",{className:"bb-note",role:"status",children:j}):null,he.sku?c("p",{className:"bb-note",children:["Customers start on: ",he.sku]}):null]}):null,t(X,{title:"Definition JSON"}),t("p",{className:"bb-note",children:"For textures and anything else without a control. It's checked before it's applied."}),t("div",{className:"se-productJson",children:t("textarea",{className:"bb-textarea","aria-label":"Product definition JSON",rows:10,value:p,spellCheck:!1,onChange:e=>R(e.target.value)})}),c("div",{className:"se-productActions",children:[t("button",{type:"button",className:"bb-button",onClick:()=>{try{C(re(p))}catch(e){E(e instanceof Error?e.message:String(e))}},children:"Apply JSON"}),t("button",{type:"button",className:"bb-button",onClick:()=>{v(null),n({...o,product:void 0})},children:"Remove all of this"})]})]})]})}export{tt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as _}from"./chunk-E24EFHB5.mjs";import{c as F,d as D,k as L,n as z}from"./chunk-AL6UIGWP.mjs";import{a as P}from"./chunk-CCBFMNAU.mjs";import{b as K}from"./chunk-GV4ZRXL6.mjs";import"./chunk-JR557W27.mjs";import{useMemo as ee,useState as te}from"react";import{ArrowDown as ae,ArrowUp as ne,ChevronRight as le,Plus as G,Trash2 as se,X as U}from"lucide-react";import{Fragment as J,jsx as a,jsxs as r}from"react/jsx-runtime";var H={all:"All objects",group:"Group",tag:"Tag",type:"Type",object:"One object"},V={metric:"Metric",status:"Status",metadata:"Metadata"},oe={metric:"",stops:[[0,"#3b82f6"],[100,"#ef4444"]]};function ie(n){return n===void 0?"all":typeof n=="string"||Array.isArray(n)?"object":"group"in n?"group":"tag"in n?"tag":"type"}function w(n){return n===void 0?"":typeof n=="string"?n:Array.isArray(n)?n[0]??"":"group"in n?n.group:"tag"in n?n.tag:n.type}function W(n,s){if(n!=="all")return n==="object"?s:n==="group"?{group:s}:n==="tag"?{tag:s}:{type:s}}function re(n){return"metric"in n?"metric":"status"in n?"status":"metadata"}function X(n){return n==="metric"?{metric:""}:n==="status"?{status:["disabled"]}:{metadata:"",equals:""}}function ce(n){let s=n.trim();return s==="true"?!0:s==="false"?!1:s==="null"?null:s!==""&&Number.isFinite(Number(s))?Number(s):n}function I(n){return n.trim()===""||!Number.isFinite(Number(n))?void 0:Number(n)}function Q(n,s="",c=0){return typeof n!="object"||n===null||Array.isArray(n)?s?[s]:[]:c>2?s?[s]:[]:Object.entries(n).flatMap(([d,h])=>Q(h,s?`${s}.${d}`:d,c+1))}var j=n=>[...new Set(n.filter(s=>!!s))].sort((s,c)=>s.localeCompare(c));function y({label:n,children:s}){return r("label",{className:"se-field se-fieldInline",children:[a("span",{className:"se-fieldLabel",title:n,children:n}),s]})}function O({label:n,checked:s,color:c,onToggle:d,onColorChange:h}){return r("div",{className:"se-field se-fieldInline",children:[r("label",{className:"se-ruleLook",children:[a("input",{type:"checkbox",className:"se-checkbox",checked:s,onChange:T=>d(T.target.checked)}),n]}),s&&c!==void 0&&h?a(z,{label:n,value:c,onChange:h}):null]})}function ue({title:n,open:s,onToggle:c,actions:d,children:h}){return r("section",{className:"se-panel",children:[r("div",{className:"se-panelHeaderRow",children:[r("button",{type:"button",className:"se-panelHeader",onClick:c,"aria-expanded":s,children:[a(le,{size:13,className:`se-panelChevron ${s?"se-panelChevron--open":""}`}),a("span",{className:"se-panelTitle",children:n})]}),a("span",{className:"se-listHeaderActions",children:d})]}),s?a("div",{className:"se-panelBody",children:h}):null]})}function de({config:n,onChange:s,objectBindings:c}){let d=n.styleRules??[],[h,T]=te(d[0]?.id??null),b=ee(()=>{let t=Object.values(c);return{groups:j(t.map(i=>i.group)),tags:j(t.flatMap(i=>i.tags??[])),types:j(t.map(i=>i.type??"other")),objects:t.map(i=>({id:i.id,label:i.label||i.id})).sort((i,u)=>i.label.localeCompare(u.label)),metrics:j(t.flatMap(i=>Object.keys(i.metrics??{}))),metadata:j(t.flatMap(i=>Q(i.metadata)))}},[c]),A=t=>s({...n,styleRules:t}),v=(t,i)=>A(d.map(u=>u.id===t?i(u):u)),Y=()=>{let t=crypto.randomUUID();A([...d,{id:t,label:`Rule ${d.length+1}`,when:[{status:["disabled"]}],material:{baseColor:"#9ca3af"}}]),T(t)},$=(t,i)=>{let u=[...d],[m]=u.splice(t,1);u.splice(t+i,0,m),A(u)},Z=t=>{let i=t.target?K(c,t.target):Object.keys(c),u=t.when?Array.isArray(t.when)?t.when:[t.when]:[];return i.filter(m=>u.every(f=>P(c[m],f))).length};return r("div",{className:"se-rules",children:[a(D,{title:"Rules",children:r("button",{type:"button",className:"bb-button bb-button--small",onClick:Y,children:[a(G,{size:13,"aria-hidden":"true"})," Add rule"]})}),a("p",{className:"rui-note",children:"Restyle objects from their metrics, status, or metadata while the app runs. Later rules win."}),a("datalist",{id:"se-ruleMetrics",children:b.metrics.map(t=>a("option",{value:t},t))}),a("datalist",{id:"se-ruleMetadata",children:b.metadata.map(t=>a("option",{value:t},t))}),d.map((t,i)=>{let u=t.when?Array.isArray(t.when)?t.when:[t.when]:[],m=ie(t.target),f=t.material??{},S=t.pulse===!0?{}:t.pulse||void 0,q=t.target?K(c,t.target).length:Object.keys(c).length,M=e=>v(t.id,l=>({...l,when:e.length>0?e:void 0})),C=(e,l)=>M(u.map((p,o)=>o===e?l:p)),N=e=>v(t.id,l=>{let p={...l.material,...e};for(let o of Object.keys(p))p[o]===void 0&&delete p[o];return{...l,material:Object.keys(p).length>0?p:void 0}}),k=e=>v(t.id,l=>({...l,colorScale:e})),E=m==="group"?b.groups:m==="tag"?b.tags:m==="type"?b.types:[];return r(ue,{title:t.label||`Rule ${i+1}`,open:h===t.id,onToggle:()=>T(e=>e===t.id?null:t.id),actions:r(J,{children:[a("button",{type:"button",className:"se-iconButton",onClick:()=>$(i,-1),disabled:i===0,"aria-label":"Move rule up",title:"Move up",children:a(ne,{size:13})}),a("button",{type:"button",className:"se-iconButton",onClick:()=>$(i,1),disabled:i===d.length-1,"aria-label":"Move rule down",title:"Move down",children:a(ae,{size:13})}),a("button",{type:"button",className:"se-iconButton",onClick:()=>A(d.filter(e=>e.id!==t.id)),"aria-label":"Delete rule",title:"Delete rule",children:a(se,{size:13})})]}),children:[a(y,{label:"Name",children:a("input",{className:"se-textInput",value:t.label??"",placeholder:`Rule ${i+1}`,onChange:e=>v(t.id,l=>({...l,label:e.target.value}))})}),r("div",{className:"se-ruleGrid",children:[a(y,{label:"Applies to",children:a("select",{className:"se-select",value:m,onChange:e=>{let l=e.target.value,p=l==="object"?b.objects[0]?.id:l==="group"?b.groups[0]:l==="tag"?b.tags[0]:l==="type"?b.types[0]:"";v(t.id,o=>({...o,target:W(l,p??"")}))},children:Object.keys(H).map(e=>a("option",{value:e,children:H[e]},e))})}),m!=="all"?a(y,{label:H[m],children:r("select",{className:"se-select",value:w(t.target),onChange:e=>v(t.id,l=>({...l,target:W(m,e.target.value)})),children:[m==="object"?b.objects.map(e=>a("option",{value:e.id,children:e.label},e.id)):E.map(e=>a("option",{value:e,children:e},e)),(m==="object"?b.objects.some(e=>e.id===w(t.target)):E.includes(w(t.target)))?null:a("option",{value:w(t.target),children:w(t.target)||"None in this model"})]})}):null]}),a("div",{className:"rui-groupHeader",children:a("span",{children:"When"})}),u.length===0?a("p",{className:"rui-note",children:"Always applies."}):null,u.map((e,l)=>{let p=re(e);return r("div",{className:"se-ruleCondition",children:[r("div",{className:"se-ruleConditionHeader",children:[a("select",{className:"se-select","aria-label":"Condition type",value:p,onChange:o=>C(l,X(o.target.value)),children:Object.keys(V).map(o=>a("option",{value:o,children:V[o]},o))}),a("button",{type:"button",className:"se-iconButton","aria-label":"Remove condition",title:"Remove condition",onClick:()=>M(u.filter((o,g)=>g!==l)),children:a(U,{size:13})})]}),"metric"in e?r("div",{className:"se-ruleGrid se-ruleGrid--three",children:[a(y,{label:"Metric",children:a("input",{className:"se-textInput",list:"se-ruleMetrics",value:e.metric,placeholder:"temperature",onChange:o=>C(l,{...e,metric:o.target.value})})}),a(y,{label:"Above",children:a("input",{className:"se-numberInput",type:"number",value:e.above??"",placeholder:"any",onChange:o=>C(l,{...e,above:I(o.target.value)})})}),a(y,{label:"Below",children:a("input",{className:"se-numberInput",type:"number",value:e.below??"",placeholder:"any",onChange:o=>C(l,{...e,below:I(o.target.value)})})})]}):"status"in e?a("div",{className:"se-ruleStatuses",children:_.map(o=>{let g=[].concat(e.status).includes(o);return r("label",{className:"se-ruleStatus",children:[a("input",{type:"checkbox",className:"se-checkbox",checked:g,onChange:()=>{let R=[].concat(e.status),B=g?R.filter(x=>x!==o):[...R,o];C(l,{status:B})}}),o]},o)})}):r("div",{className:"se-ruleGrid",children:[a(y,{label:"Key",children:a("input",{className:"se-textInput",list:"se-ruleMetadata",value:e.metadata,placeholder:"alarm.state",onChange:o=>C(l,{...e,metadata:o.target.value})})}),a(y,{label:"Equals",children:a("input",{className:"se-textInput",value:e.equals===null?"null":String(e.equals),placeholder:"fault",onChange:o=>C(l,{...e,equals:ce(o.target.value)})})})]})]},l)}),a(F,{children:r("button",{type:"button",className:"bb-button",onClick:()=>M([...u,X("metric")]),children:[a(G,{size:13,"aria-hidden":"true"})," Add condition"]})}),a("div",{className:"rui-groupHeader",children:a("span",{children:"Look"})}),a(O,{label:"Color",checked:f.baseColor!==void 0,color:f.baseColor,onToggle:e=>N({baseColor:e?"#9ca3af":void 0}),onColorChange:e=>N({baseColor:e})}),a(O,{label:"Opacity",checked:f.opacity!==void 0,onToggle:e=>N({opacity:e?.4:void 0})}),f.opacity!==void 0?a(L,{label:"Opacity",value:f.opacity,min:0,max:1,step:.05,formatValue:e=>`${Math.round(e*100)}%`,onChange:e=>N({opacity:e})}):null,a(O,{label:"Glow",checked:f.emissive!==void 0,color:f.emissive,onToggle:e=>N({emissive:e?"#ff3b30":void 0,emissiveIntensity:e?f.emissiveIntensity??1:void 0}),onColorChange:e=>N({emissive:e})}),a(O,{label:"Color from a metric",checked:t.colorScale!==void 0,onToggle:e=>k(e?{...oe,metric:b.metrics[0]??""}:void 0)}),t.colorScale?r("div",{className:"se-ruleCondition",children:[r("div",{className:"se-ruleGrid",children:[a(y,{label:"Metric",children:a("input",{className:"se-textInput",list:"se-ruleMetrics",value:t.colorScale.metric,placeholder:"temperature",onChange:e=>k({...t.colorScale,metric:e.target.value})})}),a(y,{label:"Sets",children:r("select",{className:"se-select",value:t.colorScale.channel??"baseColor",onChange:e=>k({...t.colorScale,channel:e.target.value}),children:[a("option",{value:"baseColor",children:"Color"}),a("option",{value:"emissive",children:"Glow color"})]})})]}),t.colorScale.stops.map(([e,l],p)=>{let o=g=>k({...t.colorScale,stops:t.colorScale.stops.map((R,B)=>B===p?g:R)});return r("div",{className:"se-ruleStop",children:[a("input",{className:"se-numberInput",type:"number","aria-label":"Stop value",value:e,onChange:g=>o([I(g.target.value)??0,l])}),a(z,{label:`Color at ${e}`,value:l,onChange:g=>o([e,g])}),a("button",{type:"button",className:"se-iconButton","aria-label":"Remove stop",title:"Remove stop",disabled:t.colorScale.stops.length<=1,onClick:()=>k({...t.colorScale,stops:t.colorScale.stops.filter((g,R)=>R!==p)}),children:a(U,{size:13})})]},p)}),a(F,{children:r("button",{type:"button",className:"bb-button",onClick:()=>{let e=t.colorScale.stops,l=e[e.length-1];k({...t.colorScale,stops:[...e,[(l?.[0]??0)+10,l?.[1]??"#ffffff"]]})},children:[a(G,{size:13,"aria-hidden":"true"})," Add stop"]})})]}):null,a(O,{label:"Pulse",checked:S!==void 0,color:S?.color??"#ff3b30",onToggle:e=>v(t.id,l=>({...l,pulse:e?{color:"#ff3b30",speed:1}:void 0})),onColorChange:e=>v(t.id,l=>({...l,pulse:{...S,color:e}}))}),S?a(J,{children:a(L,{label:"Pulses per second",value:S.speed??1,min:.2,max:4,step:.1,formatValue:e=>e.toFixed(1),onChange:e=>v(t.id,l=>({...l,pulse:{...S,speed:e}}))})}):null,r("p",{className:"rui-note",children:["Matches ",Z(t)," of ",q," ",q===1?"object":"objects"," right now."]})]},t.id)})]})}export{de as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sq-editor{color:var(--ri-ui-text-2);padding:12px;font-size:12px}.sq-header,.sq-picker,.sq-inspectorTitle,.sq-settings{display:flex;align-items:center;gap:10px}.sq-header{justify-content:space-between;margin-bottom:16px}.sq-header h2{margin:0;font-size:13px}.sq-header p,.sq-hint{color:var(--ri-ui-text-2);font-size:11px;line-height:1.5}.sq-header p{margin:6px 0 0}.sq-picker .sq-field{flex:1;min-width:0}.sq-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px;min-width:0}.sq-field>span{font-size:11px;color:var(--ri-ui-text-2)}.sq-field input,.sq-field select{width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--ri-ui-line);border-radius:var(--ri-ui-radius-m);padding:8px;color:var(--ri-ui-text);background:var(--ri-ui-raised);font:inherit}.sq-field input:focus-visible,.sq-field select:focus-visible,.sq-editor button:focus-visible{outline:2px solid var(--ri-ui-accent);outline-offset:2px}.sq-settings{flex-wrap:wrap;align-items:center;margin:10px 0}.sq-settings .sq-field{width:105px;margin:0}.sq-check{display:flex;align-items:center;gap:6px;color:var(--ri-ui-text-2);font-size:11px}.sq-editor input[type=checkbox]{accent-color:var(--ri-ui-accent)}.sq-twoFields{display:grid;grid-template-columns:1fr 1fr;gap:10px}.sq-vector{border:0;padding:0;margin:10px 0;min-width:0}.sq-vector legend{color:var(--ri-ui-text-2);margin-bottom:8px}.sq-vector>div{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}.sq-color{flex-direction:row;align-items:center;gap:12px}.sq-color input{width:40px;height:32px;padding:3px}.sq-empty{padding:24px 12px;border:1px dashed var(--ri-ui-line-strong);border-radius:var(--ri-ui-radius-m);text-align:center;line-height:1.6;color:var(--ri-ui-text-2)}.sq-empty button{margin-top:8px}.sq-timeline{margin-top:16px;padding:10px;border:1px solid var(--ri-ui-line);border-radius:var(--ri-ui-radius-m);background:transparent}.sq-ruler{display:flex;justify-content:space-between;color:var(--ri-ui-text-2);font-size:11px;padding-bottom:10px;font-variant-numeric:tabular-nums}.sq-track{margin-bottom:10px;border-radius:var(--ri-ui-radius-s);padding:7px 8px;background:var(--ri-ui-hover);border:1px solid transparent}.sq-track--active{border-color:var(--ri-ui-accent);background:var(--ri-ui-accent-dim)}.sq-trackLabel{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.sq-trackLabel>button{min-width:0;border:0;padding:0;color:var(--ri-ui-text-2);background:none;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:inherit;cursor:pointer}.sq-trackLabel label{display:flex;gap:4px;align-items:center;font-size:11px;color:var(--ri-ui-text-2)}.sq-lane{position:relative;height:28px;margin:0 8px;background:repeating-linear-gradient(90deg,transparent,transparent calc(25% - 1px),rgba(148,163,184,.12) calc(25% - 1px),rgba(148,163,184,.12) 25%);border-bottom:1px solid var(--ri-ui-line)}.sq-key{position:absolute;top:8px;width:12px;height:12px;padding:0;border:1px solid var(--ri-ui-line-strong);background:var(--ri-ui-field);border-radius:2px;transform:translate(-50%) rotate(45deg);cursor:ew-resize;touch-action:none}.sq-key--active{background:var(--ri-ui-accent);border-color:var(--ri-ui-accent)}.sq-playhead{position:absolute;top:0;bottom:-1px;width:1px;background:var(--ri-ui-warning);pointer-events:none}.sq-addTrack,.sq-inspector{border-top:1px solid var(--ri-ui-line);padding-top:14px;margin-top:18px}.sq-editor h3{margin:0 0 12px;font-size:12px;font-weight:600}.sq-inspectorTitle{justify-content:space-between;margin-bottom:10px}.sq-inspectorTitle h3{margin:0}.sq-inspector>button{margin-bottom:16px}.sq-error{border:1px solid var(--ri-ui-warning);border-radius:var(--ri-ui-radius-m);padding:10px;color:var(--ri-ui-warning);background:var(--ri-ui-warning-dim);line-height:1.5}.sq-key{top:3px;width:22px;height:22px;border:0;background:transparent;transform:translate(-50%)}.sq-key:before{content:"";position:absolute;left:5px;top:5px;width:10px;height:10px;border:1px solid var(--ri-ui-line-strong);border-radius:2px;background:var(--ri-ui-field);transform:rotate(45deg)}.sq-key--active:before{background:var(--ri-ui-accent);border-color:var(--ri-ui-accent)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as ce}from"./chunk-AL6UIGWP.mjs";import{a as re,b as ne}from"./chunk-MLT4JQAY.mjs";import{e as U,f as se,h as oe,i as le}from"./chunk-FGAJ2UT7.mjs";import"./chunk-DEFZEXTA.mjs";import{a as ee,b as te,c as $,d as ae,e as L,g as ie}from"./chunk-LX3GXQNU.mjs";import"./chunk-OPDRK3GS.mjs";import"./chunk-JR557W27.mjs";import{useEffect as be,useMemo as Te,useRef as we,useState as S}from"react";import{Copy as je,DiamondPlus as Ie,Plus as _,ScanLine as Ee,Trash2 as G}from"lucide-react";import{useEffect as de,useState as pe}from"react";import{Fragment as ue,jsx as g,jsxs as T}from"react/jsx-runtime";function j({label:p,value:o,onChange:r,min:l,max:u,step:f=.1,disabled:q=!1}){let[y,d]=pe(String(Number(o.toFixed(5))));return de(()=>d(String(Number(o.toFixed(5)))),[o]),T("label",{className:"sq-field",children:[g("span",{children:p}),g("input",{type:"number","aria-label":p,value:y,step:f,min:l,max:u,disabled:q,onChange:m=>d(m.target.value),onBlur:()=>{let m=y.trim()?Number(y):NaN;Number.isFinite(m)&&(l===void 0||m>=l)&&(u===void 0||m<=u)&&m!==o&&r(m),d(String(Number(o.toFixed(5))))},onKeyDown:m=>{m.stopPropagation(),m.key==="Enter"&&m.currentTarget.blur(),m.key==="Escape"&&(m.preventDefault(),d(String(o)))}})]})}function X({label:p,value:o,onChange:r}){let[l,u]=pe(o);return de(()=>u(o),[o]),T("label",{className:"sq-field",children:[g("span",{children:p}),g("input",{"aria-label":p,value:l,maxLength:256,onChange:f=>u(f.target.value),onBlur:()=>{l.trim()&&l.trim()!==o?r(l.trim()):u(o)},onKeyDown:f=>{f.stopPropagation(),f.key==="Enter"&&f.currentTarget.blur()}})]})}function H({label:p,value:o,onChange:r,degrees:l=!1}){return T("fieldset",{className:"sq-vector",children:[T("legend",{children:[p,l?" (\xB0)":""]}),g("div",{children:o.map((u,f)=>g(j,{label:["X","Y","Z"][f],value:l?u*180/Math.PI:u,onChange:q=>r(o.map((y,d)=>f===d?l?q*Math.PI/180:q:y))},f))})]})}function me({target:p,value:o,onChange:r}){if(p.kind==="camera"){let l=o;return T(ue,{children:[g(H,{label:"Camera position",value:l.position,onChange:u=>r({...l,position:u})}),g(H,{label:"Camera target",value:l.target,onChange:u=>r({...l,target:u})}),T(ue,{children:[l.fov!==null&&g(j,{label:"FOV (\xB0)",min:1,max:179,value:l.fov,onChange:u=>r({...l,fov:u})}),g(j,{label:"Zoom",min:.001,value:l.zoom,onChange:u=>r({...l,zoom:u})})]})]})}return Array.isArray(o)?g(H,{label:p.kind==="object"?p.property[0].toUpperCase()+p.property.slice(1):"Value",value:o,degrees:p.kind==="object"&&p.property==="rotation",onChange:r}):typeof o=="boolean"?T("label",{className:"sq-check",children:[g("input",{type:"checkbox",checked:o,onChange:l=>r(l.target.checked)}),"Visible"]}):typeof o=="string"?T("label",{className:"sq-field sq-color",children:[g("span",{children:"Color"}),g("input",{type:"color","aria-label":"Keyframe color",value:o,onChange:l=>r(l.target.value)}),g("code",{children:o})]}):g(j,{label:p.kind==="clip"?"Clip time (s)":"Value",min:0,max:p.kind==="object"&&p.property!=="emissiveIntensity"?1:void 0,step:.01,value:o,onChange:r})}import{Fragment as fe,jsx as t,jsxs as s}from"react/jsx-runtime";var I=()=>crypto.randomUUID(),ge={position:"Position",rotation:"Rotation",scale:"Scale",visible:"Visibility",baseColor:"Color",emissive:"Emissive color",opacity:"Opacity",roughness:"Roughness",metalness:"Metalness",emissiveIntensity:"Emissive intensity"},Pe={linear:"Linear","ease-in":"Ease in","ease-out":"Ease out","ease-in-out":"Ease in / out",step:"Hold / step"};function Ae({config:p,onChange:o,controls:r,bindings:l,clipDetails:u}){let{tier:f}=oe(),q=re(r),y=Te(()=>{try{return{sequences:L(p.sequences??[]),error:""}}catch(e){return{sequences:[],error:e instanceof Error?e.message:"Invalid sequence data."}}},[p.sequences]),d=y.sequences,[Q,m]=S(null),[qe,N]=S(null),[ke,x]=S(null),[w,he]=S("object"),[ve,ye]=S(""),[V,xe]=S("position"),[Y,Se]=S(""),[Z,P]=S(""),[D,K]=S(null),A=we(null),i=d.find(e=>e.id===Q)??d[0],c=i?.tracks.find(e=>e.id===qe)??i?.tracks[0],h=c?.keyframes.find(e=>e.id===ke)??c?.keyframes[0],B=Object.values(l).filter((e,a,k)=>!e.removed&&k.findIndex(n=>n.modelObjectId===e.modelObjectId)===a),M=B.find(e=>e.modelObjectId===ve)??B[0],R=u.some(e=>e.sourceName===Y)?Y:u[0]?.sourceName;be(()=>{i&&r&&q.sequenceId!==i.id&&r.select(i.id)},[r,i?.id,q]),be(()=>()=>r?.stop(),[r]);let O=e=>{try{let a=L(e);o({...p,sequences:a}),P("")}catch(a){P(a instanceof Error?a.message:"Invalid sequence.")}},E=e=>O(d.map(a=>a.id===e.id?e:a)),z=e=>{i&&E({...i,tracks:i.tracks.map(a=>a.id===e.id?e:a)})},C=(e,a)=>{if(!i||!ae(a.value,e.target)){P("Use a valid value; scale components must be nonzero.");return}z(ie(e,{...a,time:Math.max(0,Math.min(i.duration,a.time))})),N(e.id),x(a.id),r?.pause(),r?.seek(a.time)},J=()=>{if(d.length>=64)return;let e={id:I(),name:`Sequence ${d.length+1}`,duration:5,loop:!1,autoPlay:!1,tracks:[]};O([...d,e]),m(e.id),N(null),x(null)},v=w==="camera"?{kind:"camera"}:w==="clip"?R?{kind:"clip",clip:R}:null:M?{kind:"object",objectId:M.modelObjectId,property:V}:null,F=!!v&&i?.tracks.some(e=>$(e.target)===$(v)),Ne=()=>{if(!i||!v||F)return;let e=r?.capture(v);if(e==null){P("That target is not ready. Wait for the model, or choose another object/clip.");return}let a=v.kind==="clip"?Math.min(i.duration,u.find(n=>n.sourceName===v.clip)?.duration??i.duration):structuredClone(e),k={id:I(),name:v.kind==="camera"?"Camera":v.kind==="clip"?v.clip:`${M?.label||M?.modelObjectId} \xB7 ${ge[V]}`,target:v,keyframes:[{id:I(),time:0,value:e,easing:V==="visible"&&w==="object"?"step":"ease-in-out"},{id:I(),time:i.duration,value:a}]};E({...i,tracks:[...i.tracks,k]}),N(k.id),x(k.keyframes[1].id),r?.seek(i.duration)},Ce=()=>{if(!c||!i||c.keyframes.length>=2048)return;let e=r?.capture(c.target);if(e==null){P("The selected target is unavailable.");return}let a={id:I(),time:Math.min(q.time,i.duration),value:e,easing:"ease-in-out"};C(c,a)};return s("section",{className:"sq-editor","aria-label":"Visual sequence authoring",children:[y.error&&t("p",{role:"alert",className:"sq-error",children:y.error}),U(f,"sequences",d.length)?null:t(le,{requiredTier:se("sequences",d.length),feature:"More sequences"}),i?s(fe,{children:[s("div",{className:"sq-toolbar",children:[t("select",{className:"se-select sq-toolbarPicker","aria-label":"Authored sequence",value:i.id,onChange:e=>{m(e.target.value),N(null),x(null),r?.select(e.target.value)},children:d.map(e=>t("option",{value:e.id,children:e.name},e.id))}),t("button",{type:"button",className:"se-iconButton",title:"Add sequence","aria-label":"Add sequence",disabled:d.length>=64||!U(f,"sequences",d.length),onClick:J,children:t(_,{size:14})}),t("button",{type:"button",className:"se-iconButton",title:"Duplicate sequence","aria-label":"Duplicate sequence",disabled:d.length>=64,onClick:()=>{let e={...structuredClone(i),id:I(),name:`${i.name} copy`.slice(0,256),autoPlay:!1};O([...d,e]),m(e.id)},children:t(je,{size:13})}),t("button",{type:"button",className:"se-iconButton",title:"Delete sequence","aria-label":"Delete sequence",onClick:()=>{r?.stop(),O(d.filter(e=>e.id!==i.id)),m(null)},children:t(G,{size:13})}),t("span",{className:"sq-toolbarDivider"}),t(X,{label:"Name",value:i.name,onChange:e=>E({...i,name:e})}),t(j,{label:"Duration",min:.1,max:3600,value:i.duration,onChange:e=>E({...i,duration:e,tracks:i.tracks.map(a=>({...a,keyframes:a.keyframes.map(k=>({...k,time:k.time/i.duration*e}))}))})}),s("label",{className:"sq-check",children:[t("input",{type:"checkbox",checked:i.loop,onChange:e=>E({...i,loop:e.target.checked})}),"Loop"]}),s("label",{className:"sq-check",children:[t("input",{type:"checkbox",checked:i.autoPlay,onChange:e=>O(d.map(a=>({...a,autoPlay:a.id===i.id?e.target.checked:!1})))}),"Autoplay"]})]}),s("div",{className:"sq-body",children:[s("div",{className:"sq-main",children:[t(ne,{controls:r,duration:i.duration,hasTracks:i.tracks.some(e=>!e.muted&&e.keyframes.length>0)}),s("div",{className:"sq-timeline","aria-label":"Sequence timeline",title:"Drag keys to retime. Arrow keys move 0.1s; Shift moves 0.01s. A key at the same time is replaced.",children:[s("div",{className:"sq-ruler",children:[t("span",{className:"sq-rulerTitle",children:"Tracks"}),t("div",{className:"sq-rulerScale",children:[0,.25,.5,.75,1].map(e=>s("span",{children:[(i.duration*e).toFixed(1),"s"]},e))})]}),!i.tracks.length&&t("p",{className:"sq-hint",children:"Add a track to create its start and end keyframes."}),i.tracks.map(e=>s("div",{className:`sq-track ${c?.id===e.id?"sq-track--active":""}`,children:[s("div",{className:"sq-trackLabel",children:[t("button",{type:"button",title:e.name,onClick:()=>{N(e.id),x(e.keyframes[0]?.id??null)},children:e.name}),s("label",{title:"Mute track",children:[t("input",{"aria-label":`Mute ${e.name}`,type:"checkbox",checked:!!e.muted,onChange:a=>z({...e,muted:a.target.checked})}),"Mute"]})]}),s("div",{className:"sq-lane",role:"group","aria-label":`${e.name} keyframes`,onDoubleClick:a=>{if(a.target!==a.currentTarget)return;let k=a.currentTarget.getBoundingClientRect(),n=Math.round(Math.max(0,Math.min(1,(a.clientX-k.left)/k.width))*i.duration*100)/100,b=r?.capture(e.target);b!=null&&C(e,{id:I(),time:n,value:b})},children:[t("span",{className:"sq-playhead",style:{left:`${q.time/i.duration*100}%`}}),e.keyframes.map(a=>{let k=D?.frameId===a.id&&D.trackId===e.id?D.time:a.time;return t("button",{type:"button",className:`sq-key ${h?.id===a.id&&c?.id===e.id?"sq-key--active":""}`,style:{left:`${k/i.duration*100}%`},"aria-label":`${e.name} keyframe at ${k.toFixed(2)} seconds`,"aria-pressed":h?.id===a.id&&c?.id===e.id,onClick:n=>{n.detail===0&&(N(e.id),x(a.id),r?.pause(),r?.seek(a.time))},onPointerDown:n=>{if(n.button!==0)return;n.preventDefault(),n.stopPropagation(),n.currentTarget.focus(),n.currentTarget.setPointerCapture(n.pointerId);let b=n.currentTarget.parentElement.getBoundingClientRect();A.current={track:e,frame:a,left:b.left,width:b.width,time:a.time},N(e.id),x(a.id),r?.pause(),r?.seek(a.time)},onPointerMove:n=>{let b=A.current;if(!b||b.frame.id!==a.id||b.track.id!==e.id)return;let W=n.shiftKey?.01:.1;b.time=Math.min(i.duration,Math.max(0,Math.round((n.clientX-b.left)/b.width*i.duration/W)*W)),K({trackId:e.id,frameId:a.id,time:b.time}),r?.seek(b.time)},onPointerUp:()=>{let n=A.current;n&&(n.time!==n.frame.time&&C(n.track,{...n.frame,time:n.time}),A.current=null,K(null))},onPointerCancel:()=>{A.current=null,K(null),r?.seek(a.time)},onKeyDown:n=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(n.key))return;n.preventDefault(),n.stopPropagation();let b=n.key==="Home"?0:n.key==="End"?i.duration:a.time+(n.key==="ArrowLeft"?-1:1)*(n.shiftKey?.01:.1);C(e,{...a,time:b})}},a.id)})]})]},e.id))]})]}),s("aside",{className:"sq-side",children:[s(ce,{title:"Add track",children:[s("label",{className:"sq-field",children:[t("span",{children:"Type"}),s("select",{"aria-label":"Track type",value:w,onChange:e=>he(e.target.value),children:[t("option",{value:"object",children:"Object"}),t("option",{value:"camera",children:"Camera"}),t("option",{value:"clip",children:"Animation clip"})]})]}),w==="object"&&s("label",{className:"sq-field",children:[t("span",{children:"Property"}),t("select",{"aria-label":"Track property",value:V,onChange:e=>xe(e.target.value),children:ee.map(e=>t("option",{value:e,children:ge[e]},e))})]}),w==="object"&&s("label",{className:"sq-field",children:[t("span",{children:"Object"}),t("select",{"aria-label":"Track object",value:M?.modelObjectId??"",onChange:e=>ye(e.target.value),children:B.map(e=>t("option",{value:e.modelObjectId,children:e.label||e.modelObjectId},e.modelObjectId))})]}),w==="clip"&&s("label",{className:"sq-field",children:[t("span",{children:"Clip"}),t("select",{"aria-label":"Track animation clip",value:R??"",onChange:e=>Se(e.target.value),children:u.map(e=>t("option",{value:e.sourceName,children:e.sourceName},e.sourceName))}),!u.length&&t("small",{children:"This model has no animation clips."})]}),t("div",{className:"rui-actions",children:s("button",{type:"button",className:"bb-button",onClick:Ne,disabled:!v||!q.ready||F||i.tracks.length>=128,children:[t(_,{size:13,"aria-hidden":"true"}),"Add track"]})}),F&&t("p",{className:"rui-note",children:"That property already has a track."})]}),c&&s("section",{className:"sq-inspector","aria-label":"Selected track and keyframe",children:[s("div",{className:"rui-groupHeader",children:[t("span",{children:"Selected track"}),t("button",{type:"button",className:"se-iconButton",title:"Delete track","aria-label":"Delete track",onClick:()=>{E({...i,tracks:i.tracks.filter(e=>e.id!==c.id)}),N(null),x(null)},children:t(G,{size:13})})]}),t(X,{label:"Name",value:c.name,onChange:e=>z({...c,name:e})}),t("div",{className:"rui-actions",children:s("button",{type:"button",className:"bb-button",disabled:!q.ready||c.keyframes.length>=2048,onClick:Ce,children:[t(Ie,{size:13,"aria-hidden":"true"}),"Add keyframe at playhead"]})}),h&&s(fe,{children:[s("div",{className:"rui-groupHeader",children:[t("span",{children:"Keyframe"}),t("button",{type:"button",className:"se-iconButton",title:"Delete keyframe","aria-label":"Delete keyframe",onClick:()=>{z({...c,keyframes:c.keyframes.filter(e=>e.id!==h.id)}),x(null)},children:t(G,{size:14})})]}),t(j,{label:"Time",min:0,max:i.duration,value:h.time,step:.01,onChange:e=>C(c,{...h,time:e})}),s("label",{className:"sq-field",children:[t("span",{children:"Easing"}),t("select",{"aria-label":"Keyframe easing",value:c.target.kind==="object"&&c.target.property==="visible"?"step":h.easing??"ease-in-out",disabled:c.target.kind==="object"&&c.target.property==="visible",onChange:e=>C(c,{...h,easing:e.target.value}),children:te.map(e=>t("option",{value:e,children:Pe[e]},e))})]}),t(me,{target:c.target,value:h.value,onChange:e=>C(c,{...h,value:e})}),t("div",{className:"rui-actions",children:s("button",{type:"button",className:"bb-button",disabled:!q.ready,onClick:()=>{let e=r?.capture(c.target);e!=null&&C(c,{...h,value:e})},children:[t(Ee,{size:13,"aria-hidden":"true"}),"Capture current value"]})})]})]})]})]})]}):s("div",{className:"sq-empty",children:[t("p",{children:"Add a sequence, then add tracks and capture keyframes on the timeline."}),s("button",{type:"button",className:"bb-button bb-button--primary",onClick:J,children:[t(_,{size:13,"aria-hidden":"true"}),"Create sequence"]})]}),(Z||q.issues.length>0)&&t("div",{role:"status",className:"sq-error",children:Z||q.issues.join(" ")})]})}export{Ae as default};
|