@zakkster/lite-ui-fx 1.7.0 → 1.9.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/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # @zakkster/lite-ui-fx
2
- > Canvas-hijacked UI components with pluggable recipe system. 56 built-in recipes.
2
+ > Canvas-hijacked UI components with pluggable recipe system. 57 built-in recipes.
3
3
 
4
- VERSION 1.7.0
4
+ VERSION 1.9.0
5
5
 
6
6
  ## Install
7
7
  npm i @zakkster/lite-ui-fx
@@ -12,17 +12,19 @@ Canvas overlay (z-index:1) renders visuals via a recipe factory function.
12
12
  Recipe = { tick(), init?(), onHover?(), onClick?(), onToggle?(), onDrag?(), destroy?() }
13
13
 
14
14
  ## Import -- Controller
15
- import { mountUIFX, decorateUIFX, UIType } from '@zakkster/lite-ui-fx';
15
+ import { mountUIFX, decorateUIFX, mountUIFXGroup, UIType, GroupType } from '@zakkster/lite-ui-fx';
16
16
 
17
- ## Import -- Recipes (one ./recipes subpath, 56 total, tree-shakeable)
17
+ ## Import -- Recipes (one ./recipes subpath, 57 total, tree-shakeable)
18
18
  import { SwarmToggle, MagneticButton, SparkSlider } from '@zakkster/lite-ui-fx/recipes';
19
19
  import { PendulumToggle, HeartbeatButton, AuroraSlider } from '@zakkster/lite-ui-fx/recipes';
20
20
  import { VolumeKnob, WaterLevel, TimerCountdown } from '@zakkster/lite-ui-fx/recipes';
21
+ import { PillTabs, SegmentedSlide, RadioOrbit, BubbleRating } from '@zakkster/lite-ui-fx/recipes'; // U7 group recipes
21
22
 
22
23
  ## Import -- Recipe registry (data-driven pickers)
23
24
  import { RECIPES, RECIPE_META, RECIPE_NAMES, registerRecipe, mountRecipe } from '@zakkster/lite-ui-fx/recipes';
24
25
  // RECIPES id->factory (null-proto); RECIPE_META { id, name, type, family, themeable, motionSafe }; RECIPE_NAMES frozen.
25
26
  // mountRecipe(container, id, options?): resolves id fail-closed (did-you-mean), asserts META.type, mounts.
27
+ // Routes by type: a UIType -> mountUIFX; 'decorate' -> decorateUIFX; a group type -> mountUIFXGroup (needs items).
26
28
 
27
29
  ## Mount -- two modes
28
30
  // HIJACK (mountUIFX): creates a native element (opacity:0) inside `container` and
@@ -42,6 +44,26 @@ deco.destroy(); // removes ONLY the overlay + its listeners; host untouc
42
44
  // setValue/setChecked are HIJACK-ONLY: they throw in decorate mode (a decoration
43
45
  // reflects the host; it does not drive it).
44
46
 
47
+ ## Mount -- GROUP mode (U7): N native elements, one canvas, one recipe
48
+ // mountUIFXGroup: a grouped control -- radios in a fieldset, tabs in a tablist, a
49
+ // spinbutton, or a rating radiogroup -- sharing ONE canvas and one recipe. The
50
+ // native elements own selection + keyboard + a11y; the recipe reads state.index/
51
+ // state.count + the per-item geometry lanes. Additive: mountUIFX/decorateUIFX
52
+ // are untouched, and onSelect is a NINTH, group-only recipe hook.
53
+ const group = mountUIFXGroup(container, GroupType.RADIO, RadioOrbit, { items: ['A','B','C','D'], index: 0 });
54
+ group.els // the native elements (radios/tabs, or the single spinbutton)
55
+ group.state // read-only; state.index is the live selection
56
+ group.index // convenience getter over state.index
57
+ group.setIndex(i)// select item i in [0,count-1]: updates native + state, fires onSelect ONCE (no focus steal)
58
+ group.tick(dtMs) // driven mode only
59
+ group.destroy() // remove wrapper + listeners; idempotent
60
+ // GroupType.RADIO -> <fieldset role=radiogroup> + N <input type=radio>; native roving arrow keys
61
+ // GroupType.TABS -> <div role=tablist> + N <button role=tab>; APG roving tabindex + Left/Right/Home/End
62
+ // GroupType.STEPPER -> one <input type=number> spinbutton (count = steps); native Up/Down + typing
63
+ // GroupType.RATING -> radiogroup of N radios (rating semantics); native roving
64
+ // onSelect(index, state): recipe hook fired EXACTLY once per selection change.
65
+ // setValue/setChecked do not exist on a group -- selection is setIndex.
66
+
45
67
  ## Options (4th arg; unknown option or recipe-hook keys throw a did-you-mean -- fail closed)
46
68
  width, height, padding=40, label // geometry + accessible label
47
69
  value // slider start, number 0..1 (default 0.5); out-of-range or non-number throws
@@ -60,6 +82,10 @@ driven // U5 host clock: boolean; true = no ticker/RAF, the host calls instan
60
82
  // the host-clock keys ticker/driven (a decoration wants clock control too). The
61
83
  // hijack-only keys (width/height/value/checked/disabled/knobMode/announce/label)
62
84
  // throw in decorate mode -- geometry comes from the host, value is read from it.
85
+ // mountUIFXGroup (U7) options: items(string[] >=2, REQUIRED -- length is the item/
86
+ // step count), index(integer initial selection, default 0), label, width, height,
87
+ // padding, disabled, seed, colors, theme, text, font, ticker, driven. The hijack-
88
+ // only keys (value/checked/knobMode/announce) throw -- a group uses index, not value.
63
89
 
64
90
  ## Host clock (U5) -- three mutually-exclusive modes, both mount modes
65
91
  // default (neither option): the shared ref-counted ticker -- one RAF for all
@@ -82,6 +108,14 @@ UIType.KNOB -> <input type="range"> -> state.val, arrows native + knobMode p
82
108
  (decorate) -> NO native element created; a canvas AROUND a live host (decorateUIFX). Not a UIType --
83
109
  RECIPE_META.type 'decorate' routes mountRecipe to decorateUIFX. State: focused + text + valid.
84
110
 
111
+ ## Group Types (U7) -- N native elements + one canvas (mountUIFXGroup)
112
+ GroupType.RADIO -> <fieldset role=radiogroup> + N <input type=radio>; native roving; state.index/count
113
+ GroupType.TABS -> <div role=tablist> + N <button role=tab>; APG roving tabindex + arrows/Home/End
114
+ GroupType.STEPPER -> one <input type=number> spinbutton (count = steps); native Up/Down + typing
115
+ GroupType.RATING -> radiogroup of N radios (rating semantics); native roving
116
+ // Not UITypes: RECIPE_META.type 'radio'|'tabs'|'stepper'|'rating' routes mountRecipe to mountUIFXGroup.
117
+ // onSelect(index, state) is the ninth, group-only recipe hook (mountUIFX/decorateUIFX reject it).
118
+
85
119
  ## State Object (provided to tick every frame)
86
120
  { hover, active, focused, toggled, indeterminate, disabled, val, w, h, padding, dpr,
87
121
  reducedMotion, budget }
@@ -90,8 +124,12 @@ UIType.KNOB -> <input type="range"> -> state.val, arrows native + knobMode p
90
124
  // budget (U5): 0..1 frame budget, 1 at ~60fps, lower as frames lengthen; budget-aware
91
125
  // recipes shed work (particles/glow) when it drops.
92
126
  // decorate mode also adds: text (host value string), valid (host validity boolean).
127
+ // GROUP mode (U7) is a SUPERSET of this state PLUS: index (selected 0..count-1),
128
+ // count, hoverIndex (item under pointer, -1 none), labels (string[] items),
129
+ // itemX/itemY/itemW/itemH (Float32Array per-item geometry lanes, read by index).
130
+ // The scalar value fields (val/toggled/indeterminate) are neutral for a group.
93
131
 
94
- ## 56 Built-in Recipes
132
+ ## 57 Built-in Recipes
95
133
 
96
134
  ### Vol. 1 -- 10 recipes
97
135
  Toggles: SwarmToggle, LiquidToggle, NeonPulseToggle
@@ -125,6 +163,15 @@ Form feedback (decorateUIFX): FocusHalo, ErrorShake, SuccessBloom
125
163
  // Re-homed to decorate mode (type 'decorate'): PasswordStrength (reads the live
126
164
  // input's text), TypewriterField (an underline that grows with the typed text).
127
165
 
166
+ ### U7 -- grouped controls (mountUIFXGroup: N native elements + one canvas)
167
+ Tabs (GroupType.TABS): PillTabs, SegmentedSlide (new in U7)
168
+ Radio (GroupType.RADIO): RadioOrbit
169
+ Stepper (GroupType.STEPPER): Stepper
170
+ Rating (GroupType.RATING): BubbleRating
171
+ // PillTabs/Stepper/RadioOrbit/BubbleRating RE-HOME from their vol.3 single-element
172
+ // fakes to real group types, so their native arrow-key selection is now correct;
173
+ // SegmentedSlide is new. Selection is state.index; onSelect(index, state) fires once.
174
+
128
175
  ## Writing Custom Recipes
129
176
  See UIFX-RECIPE-GUIDE.md (included in package).
130
177
 
@@ -162,3 +209,12 @@ See UIFX-RECIPE-GUIDE.md (included in package).
162
209
  offset box and removed on destroy (host byte-identical, additive-only). State is
163
210
  wired from the host's own events (state.text/state.valid at event time). It is the
164
211
  second mount mode + the surface the enrichment decorations build on.
212
+ - U7 grouped controls (mountUIFXGroup): the THIRD mount mode -- N native elements +
213
+ one canvas + one recipe. RADIO/RATING = a fieldset radiogroup of N radios (native
214
+ roving); TABS = a role=tablist of N role=tab buttons (hand-written APG roving
215
+ tabindex + arrows/Home/End); STEPPER = one <input type=number> spinbutton. The
216
+ recipe reads state.index/count + itemX/itemY/itemW/itemH geometry lanes; onSelect
217
+ (index, state) is the ninth, group-only hook, fired once per change; setIndex(i)
218
+ selects programmatically (fires onSelect once, no focus steal). Additive: the
219
+ single-element API is byte-identical; the four vol.3 fakes (PillTabs/Stepper/
220
+ RadioOrbit/BubbleRating) re-home to real group types, SegmentedSlide is new.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zakkster/lite-ui-fx",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Canvas-hijacked UI components with a pluggable recipe system. 50 built-in recipes across toggles, buttons, sliders, knobs, loaders, checkboxes, counters, and ratings.",
5
5
  "author": "Zahary Shinikchiev <shinikchiev@yahoo.com>",
6
6
  "license": "MIT",