@vrixton/pixel-pet 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,8 +75,9 @@ Call `pet.current?.hush()` to close the current message right away, for example
|
|
|
75
75
|
| `spriteSrc` | `string` | none | A URL for your own sprite sheet. It takes priority over `variant`. |
|
|
76
76
|
| `color` | `string` | `'#FDDBA0'` | The pet's main color, used for its name and for the border of neutral speech bubbles. |
|
|
77
77
|
| `label` | `string` | `petName` | The accessible name of the pet's button. |
|
|
78
|
+
| `mode` | `'live' \| 'showcase'` | `'live'` | Use `'showcase'` for a pet on display, such as in a pet picker: it only idles, falls asleep, and says its name when clicked. |
|
|
78
79
|
| `walk` | `boolean` | `true` | Set it to `false` to keep the pet in place. |
|
|
79
|
-
| `messages` | `PetMessages` | English messages | Replaces the text shown for each emotion. |
|
|
80
|
+
| `messages` | `PetMessages` | English messages | Replaces the text shown for each emotion and the showcase greeting. |
|
|
80
81
|
| `dialogStyle` | `DialogStyleProps` | none | Styles for every bubble. |
|
|
81
82
|
| `emotionDialogStyles` | `Partial<Record<PetEmotion, DialogStyleProps>>` | none | Styles for the bubble of a single emotion. |
|
|
82
83
|
| `onClick` | `(event) => void` | none | Called when the user clicks or taps the pet. Call `event.preventDefault()` inside it to skip the pet's own reaction. |
|
|
@@ -111,6 +112,7 @@ Messages can be plain strings with two markers, so they fit in translation files
|
|
|
111
112
|
happy: '{name} está **feliz**.',
|
|
112
113
|
angry: '{name} está **abrumado**.',
|
|
113
114
|
curious: '{name} tiene mucha **curiosidad**.',
|
|
115
|
+
greeting: '¡Hola, soy {name}!',
|
|
114
116
|
}}
|
|
115
117
|
/>
|
|
116
118
|
```
|
|
@@ -144,6 +146,8 @@ A sheet passed through `spriteSrc` has to follow the same layout as the bundled
|
|
|
144
146
|
|
|
145
147
|
The pet wanders on its own, sometimes walking and sometimes standing, and turns around at the edges of the container. Every 30 seconds it may switch to a random mood for 5 seconds; hovering over it or focusing it with the keyboard shows what it's feeling. Clicking it shows its last mood for three seconds, and clicking it more than five times in ten seconds makes it angry. After a click, the bubble stays hidden while the pointer rests on the pet; moving the pointer away and back shows it again. After two minutes without mouse, touch, keyboard, or scroll wheel activity on the page, it falls asleep, and any activity wakes it up.
|
|
146
148
|
|
|
149
|
+
With `mode="showcase"`, the pet stays in place playing its idle animation, with no random moods and no bubble on hover. Clicking it shows `messages.greeting`, or "Hi, I'm {name}!" by default, for three seconds, without getting angry however many times it is clicked. It still falls asleep after two minutes without activity, and `say()` and `hush()` keep working.
|
|
150
|
+
|
|
147
151
|
The pet is a real button, so it can be reached with the keyboard, has a visible focus outline, and is announced with its name. When the user prefers reduced motion, it stays still, its animation pauses, and the bubble appears without its pop-in effect.
|
|
148
152
|
|
|
149
153
|
## Development
|
package/dist/index.d.mts
CHANGED
|
@@ -11,7 +11,8 @@ interface DialogStyleProps {
|
|
|
11
11
|
type PetEmotion = 'happy' | 'angry' | 'curious';
|
|
12
12
|
type PetAction = 'idle' | 'walk' | 'sleep';
|
|
13
13
|
type PetVariant = 'cat' | 'dog' | 'axolotl' | 'parakeet' | 'hamster';
|
|
14
|
-
type
|
|
14
|
+
type PetMode = 'live' | 'showcase';
|
|
15
|
+
type PetMessages = Partial<Record<PetEmotion | 'greeting', React.ReactNode>>;
|
|
15
16
|
interface PetSayOptions {
|
|
16
17
|
emotion?: PetEmotion;
|
|
17
18
|
duration?: number;
|
|
@@ -26,6 +27,7 @@ interface PixelPetProps {
|
|
|
26
27
|
spriteSrc?: string;
|
|
27
28
|
color?: string;
|
|
28
29
|
label?: string;
|
|
30
|
+
mode?: PetMode;
|
|
29
31
|
walk?: boolean;
|
|
30
32
|
messages?: PetMessages;
|
|
31
33
|
dialogStyle?: DialogStyleProps;
|
|
@@ -35,4 +37,4 @@ interface PixelPetProps {
|
|
|
35
37
|
}
|
|
36
38
|
declare const PixelPet: React.FC<PixelPetProps>;
|
|
37
39
|
|
|
38
|
-
export { type DialogStyleProps, type PetAction, type PetEmotion, type PetMessages, type PetSayOptions, type PetVariant, PixelPet, type PixelPetHandle, type PixelPetProps };
|
|
40
|
+
export { type DialogStyleProps, type PetAction, type PetEmotion, type PetMessages, type PetMode, type PetSayOptions, type PetVariant, PixelPet, type PixelPetHandle, type PixelPetProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ interface DialogStyleProps {
|
|
|
11
11
|
type PetEmotion = 'happy' | 'angry' | 'curious';
|
|
12
12
|
type PetAction = 'idle' | 'walk' | 'sleep';
|
|
13
13
|
type PetVariant = 'cat' | 'dog' | 'axolotl' | 'parakeet' | 'hamster';
|
|
14
|
-
type
|
|
14
|
+
type PetMode = 'live' | 'showcase';
|
|
15
|
+
type PetMessages = Partial<Record<PetEmotion | 'greeting', React.ReactNode>>;
|
|
15
16
|
interface PetSayOptions {
|
|
16
17
|
emotion?: PetEmotion;
|
|
17
18
|
duration?: number;
|
|
@@ -26,6 +27,7 @@ interface PixelPetProps {
|
|
|
26
27
|
spriteSrc?: string;
|
|
27
28
|
color?: string;
|
|
28
29
|
label?: string;
|
|
30
|
+
mode?: PetMode;
|
|
29
31
|
walk?: boolean;
|
|
30
32
|
messages?: PetMessages;
|
|
31
33
|
dialogStyle?: DialogStyleProps;
|
|
@@ -35,4 +37,4 @@ interface PixelPetProps {
|
|
|
35
37
|
}
|
|
36
38
|
declare const PixelPet: React.FC<PixelPetProps>;
|
|
37
39
|
|
|
38
|
-
export { type DialogStyleProps, type PetAction, type PetEmotion, type PetMessages, type PetSayOptions, type PetVariant, PixelPet, type PixelPetHandle, type PixelPetProps };
|
|
40
|
+
export { type DialogStyleProps, type PetAction, type PetEmotion, type PetMessages, type PetMode, type PetSayOptions, type PetVariant, PixelPet, type PixelPetHandle, type PixelPetProps };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
"use strict";var
|
|
2
|
+
"use strict";var q=Object.defineProperty;var Ae=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Fe=Object.prototype.hasOwnProperty;var Ne=(i,s)=>{for(var u in s)q(i,u,{get:s[u],enumerable:!0})},We=(i,s,u,y)=>{if(s&&typeof s=="object"||typeof s=="function")for(let d of Le(s))!Fe.call(i,d)&&d!==u&&q(i,d,{get:()=>s[d],enumerable:!(y=Ae(s,d))||y.enumerable});return i};var He=i=>We(q({},"__esModule",{value:!0}),i);var Qe={};Ne(Qe,{PixelPet:()=>qe});module.exports=He(Qe);var t=require("react");var c=require("react/jsx-runtime"),se=["pointermove","pointerdown","keydown","wheel"],pe="(prefers-reduced-motion: reduce)",Q=4,Oe=240,ae=5e3,j=3e3,Be=/(\{name\}|\*\*[^*]+\*\*|__[^_]+__)/,J={happy:"{name} is feeling **happy**!",angry:"{name} is feeling **overwhelmed**!",curious:"{name} is very **curious**"},Ue="Hi, I'm {name}!",le=65,ce=100,$e=.04,Ge=100,Xe=i=>{if(typeof window.matchMedia!="function")return()=>{};let s=window.matchMedia(pe);return s.addEventListener("change",i),()=>s.removeEventListener("change",i)},ze=()=>typeof window.matchMedia=="function"&&window.matchMedia(pe).matches,Ve=()=>(0,t.useSyncExternalStore)(Xe,ze,()=>!1),Ye={happy:{backgroundColor:"#1e1c06eb",borderColor:"#ffeb3b"},angry:{backgroundColor:"#210908eb",borderColor:"#F04037"},curious:{backgroundColor:"#1f341deb",borderColor:"#8BE383"}},Ke={backgroundColor:"#05080ceb",borderColor:"var(--pixel-pet-color, #FDDBA0)"},qe=({petName:i="Static",variant:s="cat",spriteSrc:u,color:y,label:d,mode:ue="live",walk:de=!0,messages:S,dialogStyle:x={},emotionDialogStyles:fe={},onClick:me,ref:ge})=>{let[a,p]=(0,t.useState)("idle"),xe=Ve(),E=ue==="showcase",T=de&&!xe&&!E,H=(0,t.useRef)(null),D=(0,t.useRef)(null),Z=(0,t.useRef)(null),[O,he]=(0,t.useState)(null),[R,I]=(0,t.useState)(null),[be,ee]=(0,t.useState)(!1),[ye,te]=(0,t.useState)(!1),[Ee,oe]=(0,t.useState)(!1),[Te,ne]=(0,t.useState)(!1),[f,Re]=(0,t.useState)(null),k=(0,t.useRef)(ce),[B,ke]=(0,t.useState)(0),[U,Pe]=(0,t.useState)("right"),_=(e,n)=>typeof e!="string"?e:e.split(Be).map((o,r)=>r%2===0?o:o==="{name}"||o.startsWith("__")?(0,c.jsx)("span",{className:"pixel-pet-highlight-pet",children:o==="{name}"?i:o.slice(2,-2)},r):(0,c.jsx)("span",{className:`pixel-pet-highlight-${n??"pet"}`,children:o.slice(2,-2)},r)),ve={happy:_(S?.happy??J.happy,"happy"),angry:_(S?.angry??J.angry,"angry"),curious:_(S?.curious??J.curious,"curious")},re=(0,t.useRef)(a),A=(0,t.useRef)(null),P=(0,t.useRef)(!1),L=(0,t.useRef)(!1),l=(0,t.useRef)(null),ie=(0,t.useRef)("happy"),$=(0,t.useRef)([]),v=(0,t.useRef)(null),M=(0,t.useRef)(!1),w=(0,t.useRef)(null),F=(0,t.useRef)(ae),G=(e,n=!1)=>{a==="sleep"&&p("idle"),ie.current=e,I(e),oe(n),l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{L.current||I(null)},5e3)},h=e=>{M.current=e!==null,Re(e)},N=()=>{w.current&&clearTimeout(w.current)},X=e=>{N(),e!==1/0&&(w.current=setTimeout(()=>h(null),e))};(0,t.useImperativeHandle)(ge,()=>({say:(e,n={})=>{p(o=>o==="sleep"?"idle":o),h({message:e,emotion:n.emotion??null}),F.current=n.duration??ae,X(F.current)},hush:()=>{N(),h(null)}}),[]),(0,t.useEffect)(()=>{let e,n=()=>{p(o=>o==="sleep"?"idle":o),clearTimeout(e),e=setTimeout(()=>{I(null),h(null),p("sleep")},12e4)};return se.forEach(o=>{window.addEventListener(o,n,{passive:!0})}),n(),()=>{clearTimeout(e),se.forEach(o=>{window.removeEventListener(o,n)})}},[]),(0,t.useEffect)(()=>{re.current=a},[a]),(0,t.useEffect)(()=>{if(E)return;let e=setInterval(()=>{if(re.current==="sleep"||M.current)return;let n=["happy","angry","curious"],o=n[Math.floor(Math.random()*n.length)];G(o)},3e4);return()=>{clearInterval(e)}},[E]),(0,t.useEffect)(()=>()=>{l.current&&clearTimeout(l.current),w.current&&clearTimeout(w.current),v.current&&clearTimeout(v.current)},[]),(0,t.useEffect)(()=>{if(!(a==="sleep"||!T)){if(a==="walk"){let e=Math.floor(Math.random()*175001)+5e3;A.current=setTimeout(()=>{p("idle"),P.current=!0,setTimeout(()=>{P.current=!1},3e4)},e)}else{let e=()=>{if(!P.current&&Math.random()>.4){p("walk");return}A.current=setTimeout(e,5e3)};e()}return()=>{A.current&&clearTimeout(A.current)}}},[a,T]);let z=e=>{k.current=e,D.current&&(D.current.style.transform=`translateX(${e}px)`)};(0,t.useEffect)(()=>{if(a!=="walk"||R!==null||f!==null||!T)return;let e=0,n=B-le;if(n<=e)return;let o=0,r=null,g=C=>{let Y=r===null?0:Math.min(C-r,Ge);r=C;let b=k.current+(U==="right"?1:-1)*$e*Y;if(b<=e||b>=n){if(Math.random()>.5){p("idle"),P.current=!0,setTimeout(()=>{P.current=!1},3e4);return}z(b<=e?e+2:n-2),Pe(K=>K==="right"?"left":"right");return}z(b),o=requestAnimationFrame(g)};return o=requestAnimationFrame(g),()=>cancelAnimationFrame(o)},[a,R,f,U,T,B]),(0,t.useEffect)(()=>{let e=H.current;if(!e)return;let n=r=>{ke(r),z(Math.max(Math.min(k.current,r-le),0))};if(n(e.clientWidth),typeof ResizeObserver>"u")return;let o=new ResizeObserver(([r])=>{r&&n(r.contentRect.width)});return o.observe(e),()=>o.disconnect()},[]);let Me=e=>{if(me?.(e),e.defaultPrevented)return;let n=Date.now();if(a==="sleep"&&p("idle"),E){h({message:S?.greeting??Ue,emotion:null}),F.current=j,X(j);return}M.current&&(N(),h(null)),L.current=!1,ne(!0),v.current&&clearTimeout(v.current),v.current=setTimeout(()=>oe(!1),j);let o=[...$.current,n].filter(r=>n-r<=1e4);$.current=o,o.length>5?($.current=[],G("angry",!0)):G(ie.current,!0)},we=()=>{ee(!0),M.current&&N(),R&&(L.current=!0,l.current&&clearTimeout(l.current))},Ce=()=>{ee(!1),ne(!1),M.current&&X(F.current),R&&(L.current=!1,l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{I(null)},5e3))},W=f!==null&&a!=="sleep",m=a==="sleep"?null:W?f.emotion:E?null:R,V=W||m!==null&&(be&&!Te||ye||Ee);(0,t.useLayoutEffect)(()=>{let e=H.current,n=D.current,o=Z.current;if(!V||!e||!n||!o)return;let r=e.clientWidth,g=Math.max(Math.min(Oe,r-Q*2),0),C=Math.min(o.offsetWidth,g),Y=k.current+n.offsetWidth/2,b=Q,K=r-Q-C,Ie=Y-C/2,_e=Math.max(Math.min(Ie,K),b);he({left:_e-k.current,maxWidth:g})},[V,m,f,B]);let Se=()=>m?`pixel-pet-state-${m}`:(!T||W)&&a==="walk"?"pixel-pet-state-idle":`pixel-pet-state-${a}`,De=e=>{let n=e?Ye[e]:Ke,o=e&&fe[e]||{},r=o.backgroundColor||x.backgroundColor||n.backgroundColor,g=o.borderColor||x.borderColor||n.borderColor;return{backgroundColor:r,color:o.textColor||x.textColor||"#ffffff",border:`${o.borderWidth||x.borderWidth||"1px"} solid ${g}`,borderRadius:o.borderRadius||x.borderRadius||"0",fontFamily:o.fontFamily||x.fontFamily||"monospace"}};return(0,c.jsx)("div",{className:"pixel-pet",ref:H,style:y?{"--pixel-pet-color":y}:void 0,children:(0,c.jsxs)("div",{ref:D,className:"pixel-pet-container",style:{transform:`translateX(${ce}px)`},onMouseEnter:we,onMouseLeave:Ce,children:[(0,c.jsx)("div",{className:"pixel-pet-status",role:"status",children:V&&(0,c.jsx)("div",{ref:Z,className:"pixel-pet-dialog",style:{...De(m),...O&&{left:O.left,maxWidth:O.maxWidth}},children:W?_(f.message,f.emotion):m&&ve[m]})}),(0,c.jsx)("button",{type:"button","aria-label":(d??i).split("{name}").join(i),className:`pixel-pet-sprite pixel-pet-${s} ${Se()} ${U==="left"?"pixel-pet-flip-x":""}`,style:u?{backgroundImage:`url("${u}")`}:void 0,onClick:Me,onFocus:e=>te(e.currentTarget.matches(":focus-visible")),onBlur:()=>te(!1)})]})})};0&&(module.exports={PixelPet});
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{useState as a,useEffect as d,useImperativeHandle as
|
|
2
|
+
import{useState as a,useEffect as d,useImperativeHandle as Le,useLayoutEffect as Fe,useRef as r,useSyncExternalStore as Ne}from"react";import{jsx as h,jsxs as Ye}from"react/jsx-runtime";var se=["pointermove","pointerdown","keydown","wheel"],pe="(prefers-reduced-motion: reduce)",K=4,We=240,ae=5e3,q=3e3,He=/(\{name\}|\*\*[^*]+\*\*|__[^_]+__)/,Q={happy:"{name} is feeling **happy**!",angry:"{name} is feeling **overwhelmed**!",curious:"{name} is very **curious**"},Oe="Hi, I'm {name}!",le=65,ce=100,Be=.04,Ue=100,$e=f=>{if(typeof window.matchMedia!="function")return()=>{};let w=window.matchMedia(pe);return w.addEventListener("change",f),()=>w.removeEventListener("change",f)},Ge=()=>typeof window.matchMedia=="function"&&window.matchMedia(pe).matches,Xe=()=>Ne($e,Ge,()=>!1),ze={happy:{backgroundColor:"#1e1c06eb",borderColor:"#ffeb3b"},angry:{backgroundColor:"#210908eb",borderColor:"#F04037"},curious:{backgroundColor:"#1f341deb",borderColor:"#8BE383"}},Ve={backgroundColor:"#05080ceb",borderColor:"var(--pixel-pet-color, #FDDBA0)"},et=({petName:f="Static",variant:w="cat",spriteSrc:j,color:J,label:ue,mode:de="live",walk:fe=!0,messages:C,dialogStyle:m={},emotionDialogStyles:me={},onClick:ge,ref:xe})=>{let[i,l]=a("idle"),he=Xe(),b=de==="showcase",y=fe&&!he&&!b,W=r(null),S=r(null),Z=r(null),[H,be]=a(null),[E,D]=a(null),[ye,ee]=a(!1),[Ee,te]=a(!1),[Te,oe]=a(!1),[Re,ne]=a(!1),[c,ke]=a(null),T=r(ce),[O,Pe]=a(0),[B,ve]=a("right"),I=(e,o)=>typeof e!="string"?e:e.split(He).map((t,n)=>n%2===0?t:t==="{name}"||t.startsWith("__")?h("span",{className:"pixel-pet-highlight-pet",children:t==="{name}"?f:t.slice(2,-2)},n):h("span",{className:`pixel-pet-highlight-${o??"pet"}`,children:t.slice(2,-2)},n)),Me={happy:I(C?.happy??Q.happy,"happy"),angry:I(C?.angry??Q.angry,"angry"),curious:I(C?.curious??Q.curious,"curious")},re=r(i),_=r(null),R=r(!1),A=r(!1),s=r(null),ie=r("happy"),U=r([]),k=r(null),P=r(!1),v=r(null),L=r(ae),$=(e,o=!1)=>{i==="sleep"&&l("idle"),ie.current=e,D(e),oe(o),s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{A.current||D(null)},5e3)},g=e=>{P.current=e!==null,ke(e)},F=()=>{v.current&&clearTimeout(v.current)},G=e=>{F(),e!==1/0&&(v.current=setTimeout(()=>g(null),e))};Le(xe,()=>({say:(e,o={})=>{l(t=>t==="sleep"?"idle":t),g({message:e,emotion:o.emotion??null}),L.current=o.duration??ae,G(L.current)},hush:()=>{F(),g(null)}}),[]),d(()=>{let e,o=()=>{l(t=>t==="sleep"?"idle":t),clearTimeout(e),e=setTimeout(()=>{D(null),g(null),l("sleep")},12e4)};return se.forEach(t=>{window.addEventListener(t,o,{passive:!0})}),o(),()=>{clearTimeout(e),se.forEach(t=>{window.removeEventListener(t,o)})}},[]),d(()=>{re.current=i},[i]),d(()=>{if(b)return;let e=setInterval(()=>{if(re.current==="sleep"||P.current)return;let o=["happy","angry","curious"],t=o[Math.floor(Math.random()*o.length)];$(t)},3e4);return()=>{clearInterval(e)}},[b]),d(()=>()=>{s.current&&clearTimeout(s.current),v.current&&clearTimeout(v.current),k.current&&clearTimeout(k.current)},[]),d(()=>{if(!(i==="sleep"||!y)){if(i==="walk"){let e=Math.floor(Math.random()*175001)+5e3;_.current=setTimeout(()=>{l("idle"),R.current=!0,setTimeout(()=>{R.current=!1},3e4)},e)}else{let e=()=>{if(!R.current&&Math.random()>.4){l("walk");return}_.current=setTimeout(e,5e3)};e()}return()=>{_.current&&clearTimeout(_.current)}}},[i,y]);let X=e=>{T.current=e,S.current&&(S.current.style.transform=`translateX(${e}px)`)};d(()=>{if(i!=="walk"||E!==null||c!==null||!y)return;let e=0,o=O-le;if(o<=e)return;let t=0,n=null,u=M=>{let V=n===null?0:Math.min(M-n,Ue);n=M;let x=T.current+(B==="right"?1:-1)*Be*V;if(x<=e||x>=o){if(Math.random()>.5){l("idle"),R.current=!0,setTimeout(()=>{R.current=!1},3e4);return}X(x<=e?e+2:o-2),ve(Y=>Y==="right"?"left":"right");return}X(x),t=requestAnimationFrame(u)};return t=requestAnimationFrame(u),()=>cancelAnimationFrame(t)},[i,E,c,B,y,O]),d(()=>{let e=W.current;if(!e)return;let o=n=>{Pe(n),X(Math.max(Math.min(T.current,n-le),0))};if(o(e.clientWidth),typeof ResizeObserver>"u")return;let t=new ResizeObserver(([n])=>{n&&o(n.contentRect.width)});return t.observe(e),()=>t.disconnect()},[]);let we=e=>{if(ge?.(e),e.defaultPrevented)return;let o=Date.now();if(i==="sleep"&&l("idle"),b){g({message:C?.greeting??Oe,emotion:null}),L.current=q,G(q);return}P.current&&(F(),g(null)),A.current=!1,ne(!0),k.current&&clearTimeout(k.current),k.current=setTimeout(()=>oe(!1),q);let t=[...U.current,o].filter(n=>o-n<=1e4);U.current=t,t.length>5?(U.current=[],$("angry",!0)):$(ie.current,!0)},Ce=()=>{ee(!0),P.current&&F(),E&&(A.current=!0,s.current&&clearTimeout(s.current))},Se=()=>{ee(!1),ne(!1),P.current&&G(L.current),E&&(A.current=!1,s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{D(null)},5e3))},N=c!==null&&i!=="sleep",p=i==="sleep"?null:N?c.emotion:b?null:E,z=N||p!==null&&(ye&&!Re||Ee||Te);Fe(()=>{let e=W.current,o=S.current,t=Z.current;if(!z||!e||!o||!t)return;let n=e.clientWidth,u=Math.max(Math.min(We,n-K*2),0),M=Math.min(t.offsetWidth,u),V=T.current+o.offsetWidth/2,x=K,Y=n-K-M,_e=V-M/2,Ae=Math.max(Math.min(_e,Y),x);be({left:Ae-T.current,maxWidth:u})},[z,p,c,O]);let De=()=>p?`pixel-pet-state-${p}`:(!y||N)&&i==="walk"?"pixel-pet-state-idle":`pixel-pet-state-${i}`,Ie=e=>{let o=e?ze[e]:Ve,t=e&&me[e]||{},n=t.backgroundColor||m.backgroundColor||o.backgroundColor,u=t.borderColor||m.borderColor||o.borderColor;return{backgroundColor:n,color:t.textColor||m.textColor||"#ffffff",border:`${t.borderWidth||m.borderWidth||"1px"} solid ${u}`,borderRadius:t.borderRadius||m.borderRadius||"0",fontFamily:t.fontFamily||m.fontFamily||"monospace"}};return h("div",{className:"pixel-pet",ref:W,style:J?{"--pixel-pet-color":J}:void 0,children:Ye("div",{ref:S,className:"pixel-pet-container",style:{transform:`translateX(${ce}px)`},onMouseEnter:Ce,onMouseLeave:Se,children:[h("div",{className:"pixel-pet-status",role:"status",children:z&&h("div",{ref:Z,className:"pixel-pet-dialog",style:{...Ie(p),...H&&{left:H.left,maxWidth:H.maxWidth}},children:N?I(c.message,c.emotion):p&&Me[p]})}),h("button",{type:"button","aria-label":(ue??f).split("{name}").join(f),className:`pixel-pet-sprite pixel-pet-${w} ${De()} ${B==="left"?"pixel-pet-flip-x":""}`,style:j?{backgroundImage:`url("${j}")`}:void 0,onClick:we,onFocus:e=>te(e.currentTarget.matches(":focus-visible")),onBlur:()=>te(!1)})]})})};export{et as PixelPet};
|
package/package.json
CHANGED