@doan-labs/peek 1.0.0 → 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Doan Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -19,7 +19,66 @@ import { Peek } from '@doan-labs/peek'
19
19
  Use `animate` for blinking and expression transitions, and
20
20
  `gaze='pointer'` to follow the pointer. Animation respects reduced motion.
21
21
 
22
- ## Plain SVG, without React
22
+ ## Vue 3.5
23
+
24
+ The same component, with the same props and the same markup:
25
+
26
+ ```vue
27
+ <script setup>
28
+ import { Peek } from '@doan-labs/peek/vue'
29
+ </script>
30
+
31
+ <template>
32
+ <Peek name="Linh" :size="96" expression="happy" animate />
33
+ </template>
34
+ ```
35
+
36
+ ## Svelte 5
37
+
38
+ Needs Svelte 5.20 or newer. The component ships as source, so your bundler
39
+ compiles it:
40
+
41
+ ```svelte
42
+ <script>
43
+ import { Peek } from '@doan-labs/peek/svelte'
44
+ </script>
45
+
46
+ <Peek name="Linh" size={96} expression="happy" animate />
47
+ ```
48
+
49
+ In Vue and Svelte, use `class` and `style` in place of `className` and
50
+ `style`. Both entry points also export `toSvg`, `identify` and the option
51
+ lists, so neither needs React installed.
52
+
53
+ ## Accessories
54
+
55
+ Dress a face with three independent slots:
56
+
57
+ ```tsx
58
+ <Peek name='Linh' eyewear='glasses' headwear='bow' />
59
+ <Peek name='Linh' eyewear='sunglasses' headwear='sprout' />
60
+ <Peek name='Linh' headwear='cap' neckwear='tie' animate />
61
+ ```
62
+
63
+ Eyewear: `none`, `glasses`, `sunglasses`. Headwear: `none`, `bow`, `cap`,
64
+ `sprout`. Neckwear: `none`, `tie`. All default to `none` at `peek@1`, so
65
+ existing avatars stay unchanged. Slots combine and work with every
66
+ expression, gaze and frame. The same options work with `toSvg`.
67
+
68
+ ## Variants
69
+
70
+ Draw the same face another way. A variant never changes who it is:
71
+
72
+ ```tsx
73
+ <Peek name='Linh' variant='haze' />
74
+ <Peek name='Linh' variant='bloc' expression='angry' animate />
75
+ ```
76
+
77
+ `peek` (default), `haze` (the body in soft color) or `bloc` (flat
78
+ geometry: two tones, one bar, hard edges). Every variant draws every
79
+ expression, gaze and frame.
80
+
81
+ ## Plain SVG, without a framework
23
82
 
24
83
  The SVG and identity entry points have no runtime dependencies:
25
84
 
@@ -36,3 +95,7 @@ The same normalized name and options produce the same SVG every time.
36
95
 
37
96
  See the [documentation](https://peek.doan-labs.com/docs) for options,
38
97
  expressions, identity axes and versioned styles.
98
+
99
+ ## License
100
+
101
+ [MIT](./LICENSE) © Doan Labs
package/dist/bloc.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { type Node, type Parts } from './draw.js';
2
+ export declare function blocParts({ who, pose, o, defs, g }: Parts): [Node[], Node[]];
package/dist/core.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type { Frame, Gaze, Node } from './draw.js';
2
+ /** Low level: the drawing tree that toSvg and <Peek> both render. */
3
+ export { draw } from './draw.js';
4
+ export type { Axes, Identity, Persona } from './identity.js';
5
+ export { AXES, identify, LISTS, tidy } from './identity.js';
6
+ export type { PeekOptions } from './svg.js';
7
+ export { settle, toSvg } from './svg.js';
8
+ export type { AccessorySlot, Axis, Brows, Channel, Cheeks, Color, Expression, Eyes, Eyewear, Face, Headwear, Mouth, Neckwear, Trait, Variant, } from './tables.js';
9
+ export { ACCESSORIES, BLOC, COLORS, EXPRESSIONS, FACES, GROUPS, HAZE, LATEST, PARTS, VARIANTS, VERSIONS, WHEEL, } from './tables.js';
package/dist/draw.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { Axes, Persona } from './identity.js';
2
- import { type Channels, type Expression, type FaceGeom } from './tables.js';
1
+ import { type Axes, type Persona } from './identity.js';
2
+ import { type Channel, type Channels, type Expression, type FaceGeom, type Variant } from './tables.js';
3
3
  export type Node = {
4
4
  tag: string;
5
5
  key: string;
@@ -30,13 +30,18 @@ export type DrawOptions = {
30
30
  title: string | false;
31
31
  /** Keep invisible nodes so an animator can write into them. */
32
32
  live?: boolean;
33
+ /** How the face is drawn. Default 'peek'. */
34
+ variant?: Variant;
33
35
  };
36
+ /** `key`, the tidied name, seeds Haze's blobs; without it, it hazes as ''. */
34
37
  export type Drawable = Axes & {
35
38
  persona: Persona;
39
+ key?: string;
36
40
  };
37
41
  export declare const VB: readonly [-30, -30, 400, 400];
38
42
  export declare const clamp: (v: number, a: number, b: number) => number;
39
43
  export declare const smooth: (a: number, b: number, v: number) => number;
44
+ export declare const f2: (v: number) => string;
40
45
  /** Where a face rests: the body offset, the eye line, one altitude unit. */
41
46
  export declare function frameOf(face: FaceGeom): {
42
47
  baseY: number;
@@ -66,4 +71,21 @@ export declare function ringWalk(sh: FaceGeom): {
66
71
  rest: number;
67
72
  min: number;
68
73
  };
74
+ type Attrs = Record<string, string | number | false | undefined>;
75
+ export declare function n(tag: string, key: string, attrs: Attrs, children?: Node[]): {
76
+ tag: string;
77
+ key: string;
78
+ attrs: Record<string, string>;
79
+ children: Node[];
80
+ };
69
81
  export declare function draw(who: Drawable, pose: Pose, o: DrawOptions): Node;
82
+ /** What a variant draws from: the defs it may add to, and the pose reader. */
83
+ export type Parts = {
84
+ who: Drawable;
85
+ pose: Pose;
86
+ o: DrawOptions;
87
+ defs: Node[];
88
+ /** A channel with the persona applied. */
89
+ g: (c: Channel) => number;
90
+ };
91
+ export {};
@@ -1,4 +1,4 @@
1
- import { type Axis, type Brows, type Cheeks, type Color, type Eyes, type Face, type Mouth, type Trait } from './tables.js';
1
+ import { type Axis, type Brows, type Cheeks, type Color, type Eyes, type Eyewear, type Face, type Headwear, type Mouth, type Neckwear, type Trait } from './tables.js';
2
2
  export declare const STYLE = "peek";
3
3
  export declare const tidy: (s: string) => string;
4
4
  /** FNV-1a over the UTF-8 bytes. */
@@ -34,6 +34,9 @@ export type Axes = {
34
34
  mouth: Mouth;
35
35
  cheeks: Cheeks;
36
36
  trait: Trait;
37
+ eyewear: Eyewear;
38
+ headwear: Headwear;
39
+ neckwear: Neckwear;
37
40
  };
38
41
  export type Identity = Axes & {
39
42
  /** The tidied name. */
package/dist/identity.js CHANGED
@@ -116,8 +116,24 @@ var PARTS = {
116
116
  cheeks: ["oval", "dots", "lines"],
117
117
  trait: ["square", "fin", "ring", "dot", "peak"]
118
118
  };
119
+ var ACCESSORIES = {
120
+ eyewear: ["none", "glasses", "sunglasses"],
121
+ headwear: ["none", "bow", "cap", "sprout"],
122
+ neckwear: ["none", "tie"]
123
+ };
119
124
  var VERSIONS = {
120
- 1: { face: 4, color: 7, eyes: 3, brows: 4, mouth: 4, cheeks: 3, trait: 5 }
125
+ 1: {
126
+ face: 4,
127
+ color: 7,
128
+ eyes: 3,
129
+ brows: 4,
130
+ mouth: 4,
131
+ cheeks: 3,
132
+ trait: 5,
133
+ eyewear: 1,
134
+ headwear: 1,
135
+ neckwear: 1
136
+ }
121
137
  };
122
138
  var LATEST = 1;
123
139
  var BASE = {
@@ -339,7 +355,8 @@ function mulberry32(a) {
339
355
  var LISTS = {
340
356
  face: Object.keys(FACES),
341
357
  color: Object.keys(COLORS),
342
- ...PARTS
358
+ ...PARTS,
359
+ ...ACCESSORIES
343
360
  };
344
361
  var AXES = Object.keys(LISTS);
345
362
  function seed(name, axis, version = LATEST) {
@@ -383,6 +400,9 @@ function identify(name, { version = LATEST } = {}) {
383
400
  mouth: pick("mouth"),
384
401
  cheeks: pick("cheeks"),
385
402
  trait: pick("trait"),
403
+ eyewear: pick("eyewear"),
404
+ headwear: pick("headwear"),
405
+ neckwear: pick("neckwear"),
386
406
  persona
387
407
  };
388
408
  }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,3 @@
1
- export type { Frame, Gaze } from './draw.js';
2
- export type { Axes, Identity, Persona } from './identity.js';
3
- export { AXES, identify, LISTS, tidy } from './identity.js';
1
+ export * from './core.js';
4
2
  export type { PeekProps } from './peek.js';
5
3
  export { Peek } from './peek.js';
6
- export type { PeekOptions } from './svg.js';
7
- export { toSvg } from './svg.js';
8
- export type { Axis, Brows, Channel, Cheeks, Color, Expression, Eyes, Face, Mouth, Trait, } from './tables.js';
9
- export { COLORS, EXPRESSIONS, FACES, GROUPS, LATEST, PARTS, VERSIONS, } from './tables.js';