@bind-ts/bind-core 0.0.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/dist/cjs/index.cjs +1 -0
- package/dist/esm/BindApi.d.ts +72 -0
- package/dist/esm/BindApi.d.ts.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +72 -0
- package/dist/esm/types.d.ts +5 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/package.json +47 -0
- package/src/BindApi.ts +120 -0
- package/src/index.ts +3 -0
- package/src/types.ts +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var u=Object.defineProperty;var l=(n,t,e)=>t in n?u(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var o=(n,t,e)=>l(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("@tanstack/store");class p{constructor(t){o(this,"options");o(this,"store");o(this,"setValue",t=>{var s,i;const e=this.store.state.value;this.store.setState(a=>({...a,value:t})),e!==t&&((i=(s=this.options.listeners)==null?void 0:s.onChange)==null||i.call(s,{value:t,bindApi:this}))});o(this,"update",t=>{this.options=t});o(this,"reset",t=>{var i,a;t!==void 0&&(this.options={...this.options,defaultValue:t});const e=this.store.state.value,s=this.options.defaultValue;this.store.setState(r=>({...r,value:s})),e!==s&&((a=(i=this.options.listeners)==null?void 0:i.onChange)==null||a.call(i,{value:s,bindApi:this}))});o(this,"mount",()=>()=>{});this.options=t,this.store=new h.Store({value:t.defaultValue,values:t.values})}get state(){return this.store.state}}exports.BindApi=p;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Store } from "@tanstack/store";
|
|
2
|
+
/**
|
|
3
|
+
* The state shape managed by BindApi
|
|
4
|
+
*/
|
|
5
|
+
export interface BindState<TValues extends readonly string[]> {
|
|
6
|
+
value: TValues[number];
|
|
7
|
+
values: TValues;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Listener callbacks for BindApi events
|
|
11
|
+
*/
|
|
12
|
+
export interface BindListeners<TValues extends readonly string[]> {
|
|
13
|
+
/**
|
|
14
|
+
* Called when the value changes via setValue or reset
|
|
15
|
+
*/
|
|
16
|
+
onChange?: (props: {
|
|
17
|
+
value: TValues[number];
|
|
18
|
+
bindApi: BindApi<TValues>;
|
|
19
|
+
}) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating a BindApi instance
|
|
23
|
+
*/
|
|
24
|
+
export interface BindOptions<TValues extends readonly string[]> {
|
|
25
|
+
defaultValue: TValues[number];
|
|
26
|
+
values: TValues;
|
|
27
|
+
listeners?: BindListeners<TValues>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A class representing the Bind API. It handles the logic and interactions
|
|
31
|
+
* with exclusive selection state (like tabs, accordions, multi-step forms).
|
|
32
|
+
*
|
|
33
|
+
* This is framework-agnostic - use with a framework adapter like `@bind/react`.
|
|
34
|
+
*/
|
|
35
|
+
export declare class BindApi<TValues extends readonly string[]> {
|
|
36
|
+
/**
|
|
37
|
+
* The options for the bind component
|
|
38
|
+
*/
|
|
39
|
+
options: BindOptions<TValues>;
|
|
40
|
+
/**
|
|
41
|
+
* The store managing the bind state
|
|
42
|
+
*/
|
|
43
|
+
store: Store<BindState<TValues>>;
|
|
44
|
+
/**
|
|
45
|
+
* Constructs a new `BindApi` instance with the given options.
|
|
46
|
+
*/
|
|
47
|
+
constructor(opts: BindOptions<TValues>);
|
|
48
|
+
/**
|
|
49
|
+
* Gets the current state
|
|
50
|
+
*/
|
|
51
|
+
get state(): BindState<TValues>;
|
|
52
|
+
/**
|
|
53
|
+
* Sets the active value. Must be arrow function for React spread compatibility.
|
|
54
|
+
*/
|
|
55
|
+
setValue: (value: TValues[number]) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Updates the options. Useful for syncing options from framework hooks.
|
|
58
|
+
*/
|
|
59
|
+
update: (opts: BindOptions<TValues>) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Resets the active value to the default value.
|
|
62
|
+
* Optionally accepts a new default value to set before resetting.
|
|
63
|
+
* Useful for "restart wizard" or "reset to new state" use cases.
|
|
64
|
+
*/
|
|
65
|
+
reset: (newDefault?: TValues[number]) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Mounts the bind component. Returns a cleanup function.
|
|
68
|
+
* Used by framework adapters for lifecycle management.
|
|
69
|
+
*/
|
|
70
|
+
mount: () => (() => void);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=BindApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BindApi.d.ts","sourceRoot":"","sources":["../../src/BindApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IAC3D,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IAC/D;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;CAClF;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IAC7D,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,qBAAa,OAAO,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IACrD;;OAEG;IACH,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjC;;OAEG;gBACS,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC;IAStC;;OAEG;IACH,IAAI,KAAK,IAAI,SAAS,CAAC,OAAO,CAAC,CAE9B;IAED;;OAEG;IACH,QAAQ,GAAI,OAAO,OAAO,CAAC,MAAM,CAAC,KAAG,IAAI,CASvC;IAEF;;OAEG;IACH,MAAM,GAAI,MAAM,WAAW,CAAC,OAAO,CAAC,KAAG,IAAI,CAEzC;IAEF;;;;OAIG;IACH,KAAK,GAAI,aAAa,OAAO,CAAC,MAAM,CAAC,KAAG,IAAI,CAgB1C;IAEF;;;OAGG;IACH,KAAK,QAAO,CAAC,MAAM,IAAI,CAAC,CAKtB;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var h = (n, t, s) => t in n ? u(n, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : n[t] = s;
|
|
3
|
+
var o = (n, t, s) => h(n, typeof t != "symbol" ? t + "" : t, s);
|
|
4
|
+
import { Store as l } from "@tanstack/store";
|
|
5
|
+
class v {
|
|
6
|
+
/**
|
|
7
|
+
* Constructs a new `BindApi` instance with the given options.
|
|
8
|
+
*/
|
|
9
|
+
constructor(t) {
|
|
10
|
+
/**
|
|
11
|
+
* The options for the bind component
|
|
12
|
+
*/
|
|
13
|
+
o(this, "options");
|
|
14
|
+
/**
|
|
15
|
+
* The store managing the bind state
|
|
16
|
+
*/
|
|
17
|
+
o(this, "store");
|
|
18
|
+
/**
|
|
19
|
+
* Sets the active value. Must be arrow function for React spread compatibility.
|
|
20
|
+
*/
|
|
21
|
+
o(this, "setValue", (t) => {
|
|
22
|
+
var e, i;
|
|
23
|
+
const s = this.store.state.value;
|
|
24
|
+
this.store.setState((a) => ({
|
|
25
|
+
...a,
|
|
26
|
+
value: t
|
|
27
|
+
})), s !== t && ((i = (e = this.options.listeners) == null ? void 0 : e.onChange) == null || i.call(e, { value: t, bindApi: this }));
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Updates the options. Useful for syncing options from framework hooks.
|
|
31
|
+
*/
|
|
32
|
+
o(this, "update", (t) => {
|
|
33
|
+
this.options = t;
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Resets the active value to the default value.
|
|
37
|
+
* Optionally accepts a new default value to set before resetting.
|
|
38
|
+
* Useful for "restart wizard" or "reset to new state" use cases.
|
|
39
|
+
*/
|
|
40
|
+
o(this, "reset", (t) => {
|
|
41
|
+
var i, a;
|
|
42
|
+
t !== void 0 && (this.options = {
|
|
43
|
+
...this.options,
|
|
44
|
+
defaultValue: t
|
|
45
|
+
});
|
|
46
|
+
const s = this.store.state.value, e = this.options.defaultValue;
|
|
47
|
+
this.store.setState((r) => ({
|
|
48
|
+
...r,
|
|
49
|
+
value: e
|
|
50
|
+
})), s !== e && ((a = (i = this.options.listeners) == null ? void 0 : i.onChange) == null || a.call(i, { value: e, bindApi: this }));
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Mounts the bind component. Returns a cleanup function.
|
|
54
|
+
* Used by framework adapters for lifecycle management.
|
|
55
|
+
*/
|
|
56
|
+
o(this, "mount", () => () => {
|
|
57
|
+
});
|
|
58
|
+
this.options = t, this.store = new l({
|
|
59
|
+
value: t.defaultValue,
|
|
60
|
+
values: t.values
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the current state
|
|
65
|
+
*/
|
|
66
|
+
get state() {
|
|
67
|
+
return this.store.state;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
v as BindApi
|
|
72
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,EAAE,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bind-ts/bind-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Type-safe, framework-agnostic state management for compound components",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"types": "dist/esm/index.d.ts",
|
|
9
|
+
"main": "dist/cjs/index.cjs",
|
|
10
|
+
"module": "dist/esm/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/esm/index.d.ts",
|
|
15
|
+
"default": "./dist/esm/index.js"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/cjs/index.d.cts",
|
|
19
|
+
"default": "./dist/cjs/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"src",
|
|
28
|
+
"!**/__tests__"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "vite build && tsc --emitDeclarationOnly --outDir dist/esm",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest",
|
|
34
|
+
"check-types": "tsc --noEmit"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@tanstack/store": "^0.7.7"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.9.2",
|
|
41
|
+
"vite": "^6.3.5",
|
|
42
|
+
"vitest": "^3.2.4"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/BindApi.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Store } from "@tanstack/store";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The state shape managed by BindApi
|
|
5
|
+
*/
|
|
6
|
+
export interface BindState<TValues extends readonly string[]> {
|
|
7
|
+
value: TValues[number];
|
|
8
|
+
values: TValues;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Listener callbacks for BindApi events
|
|
13
|
+
*/
|
|
14
|
+
export interface BindListeners<TValues extends readonly string[]> {
|
|
15
|
+
/**
|
|
16
|
+
* Called when the value changes via setValue or reset
|
|
17
|
+
*/
|
|
18
|
+
onChange?: (props: { value: TValues[number]; bindApi: BindApi<TValues> }) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating a BindApi instance
|
|
23
|
+
*/
|
|
24
|
+
export interface BindOptions<TValues extends readonly string[]> {
|
|
25
|
+
defaultValue: TValues[number];
|
|
26
|
+
values: TValues;
|
|
27
|
+
listeners?: BindListeners<TValues>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A class representing the Bind API. It handles the logic and interactions
|
|
32
|
+
* with exclusive selection state (like tabs, accordions, multi-step forms).
|
|
33
|
+
*
|
|
34
|
+
* This is framework-agnostic - use with a framework adapter like `@bind/react`.
|
|
35
|
+
*/
|
|
36
|
+
export class BindApi<TValues extends readonly string[]> {
|
|
37
|
+
/**
|
|
38
|
+
* The options for the bind component
|
|
39
|
+
*/
|
|
40
|
+
options: BindOptions<TValues>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The store managing the bind state
|
|
44
|
+
*/
|
|
45
|
+
store: Store<BindState<TValues>>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Constructs a new `BindApi` instance with the given options.
|
|
49
|
+
*/
|
|
50
|
+
constructor(opts: BindOptions<TValues>) {
|
|
51
|
+
this.options = opts;
|
|
52
|
+
|
|
53
|
+
this.store = new Store<BindState<TValues>>({
|
|
54
|
+
value: opts.defaultValue,
|
|
55
|
+
values: opts.values,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the current state
|
|
61
|
+
*/
|
|
62
|
+
get state(): BindState<TValues> {
|
|
63
|
+
return this.store.state;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sets the active value. Must be arrow function for React spread compatibility.
|
|
68
|
+
*/
|
|
69
|
+
setValue = (value: TValues[number]): void => {
|
|
70
|
+
const prevValue = this.store.state.value;
|
|
71
|
+
this.store.setState((prev) => ({
|
|
72
|
+
...prev,
|
|
73
|
+
value: value,
|
|
74
|
+
}));
|
|
75
|
+
if (prevValue !== value) {
|
|
76
|
+
this.options.listeners?.onChange?.({ value, bindApi: this });
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Updates the options. Useful for syncing options from framework hooks.
|
|
82
|
+
*/
|
|
83
|
+
update = (opts: BindOptions<TValues>): void => {
|
|
84
|
+
this.options = opts;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Resets the active value to the default value.
|
|
89
|
+
* Optionally accepts a new default value to set before resetting.
|
|
90
|
+
* Useful for "restart wizard" or "reset to new state" use cases.
|
|
91
|
+
*/
|
|
92
|
+
reset = (newDefault?: TValues[number]): void => {
|
|
93
|
+
if (newDefault !== undefined) {
|
|
94
|
+
this.options = {
|
|
95
|
+
...this.options,
|
|
96
|
+
defaultValue: newDefault,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const prevValue = this.store.state.value;
|
|
100
|
+
const nextValue = this.options.defaultValue;
|
|
101
|
+
this.store.setState((prev) => ({
|
|
102
|
+
...prev,
|
|
103
|
+
value: nextValue,
|
|
104
|
+
}));
|
|
105
|
+
if (prevValue !== nextValue) {
|
|
106
|
+
this.options.listeners?.onChange?.({ value: nextValue, bindApi: this });
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Mounts the bind component. Returns a cleanup function.
|
|
112
|
+
* Used by framework adapters for lifecycle management.
|
|
113
|
+
*/
|
|
114
|
+
mount = (): (() => void) => {
|
|
115
|
+
// Currently no setup needed, but provides hook for future functionality
|
|
116
|
+
return () => {
|
|
117
|
+
// Cleanup
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED