react-store-input 0.1.1 → 0.1.3

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.
@@ -118,14 +118,58 @@ function useStore(initialState) {
118
118
  };
119
119
  }
120
120
 
121
+ // src/use_store_component.tsx
122
+ var import_react7 = require("react");
123
+ var import_react8 = __toESM(require("react"));
124
+
121
125
  // src/use_store_input.tsx
122
126
  var import_react6 = require("react");
123
- var import_react7 = __toESM(require("react"));
127
+ var import_date_fns = require("date-fns");
124
128
 
125
- // src/use_store_input_props.tsx
129
+ // src/use_store_controller.tsx
126
130
  var import_react5 = require("react");
127
- var import_date_fns = require("date-fns");
128
- function useStoreInputProps(store, props) {
131
+ function useStoreController(store, props) {
132
+ const ref = (0, import_react5.useRef)(null);
133
+ const dispatchKey = (0, import_react5.useId)();
134
+ (0, import_react5.useEffect)(() => {
135
+ const element = ref.current;
136
+ if (!element) {
137
+ return;
138
+ }
139
+ if (typeof props.ref === "function") {
140
+ props.ref(element);
141
+ } else if (props.ref) {
142
+ props.ref.current = element;
143
+ }
144
+ }, []);
145
+ useSubscribe(store, (state, key) => {
146
+ if (key === dispatchKey) {
147
+ return;
148
+ }
149
+ if (!ref.current) return;
150
+ props.onSubscribe(state, ref.current);
151
+ });
152
+ const onChange = () => {
153
+ store.dispatch(
154
+ (state) => {
155
+ const element = ref.current;
156
+ if (!element) return;
157
+ props.onDispatch(state, element);
158
+ },
159
+ {
160
+ key: dispatchKey
161
+ }
162
+ );
163
+ };
164
+ return {
165
+ dispatchKey,
166
+ ref,
167
+ onChange
168
+ };
169
+ }
170
+
171
+ // src/use_store_input.tsx
172
+ function useStoreInput(store, props) {
129
173
  const toInputValue = (value) => {
130
174
  if (value === void 0 || value === null) {
131
175
  return "";
@@ -147,7 +191,7 @@ function useStoreInputProps(store, props) {
147
191
  if (props.type === "checkbox" || props.type === "radio") {
148
192
  return void 0;
149
193
  }
150
- return toInputValue(store.state[props.name]);
194
+ return toInputValue(props.getter(store.state));
151
195
  };
152
196
  const toInputChecked = (value) => {
153
197
  if (props.type === "radio") {
@@ -162,103 +206,91 @@ function useStoreInputProps(store, props) {
162
206
  if (props.type !== "checkbox" && props.type !== "radio") {
163
207
  return void 0;
164
208
  }
165
- return toInputChecked(store.state[props.name]);
209
+ return toInputChecked(props.getter(store.state));
166
210
  };
167
- function useSubscriptionRef() {
168
- const ref2 = (0, import_react5.useRef)(null);
169
- (0, import_react5.useEffect)(() => {
170
- const input = ref2.current;
171
- if (!input) {
172
- return;
173
- }
174
- if (typeof props.ref === "function") {
175
- props.ref(input);
176
- } else if (props.ref) {
177
- props.ref.current = input;
178
- }
179
- return store.subscribe((state, key) => {
180
- if (key === dispatchKey) {
181
- return;
182
- }
183
- if (props.type === "checkbox" || props.type === "radio") {
184
- const checked = toInputChecked(state[props.name]);
185
- if (input.checked === checked) {
186
- return;
187
- }
188
- input.checked = checked;
189
- } else {
190
- const value = toInputValue(state[props.name]);
191
- if (input.value === value) {
192
- return;
193
- }
194
- input.value = value;
195
- }
196
- const event = new Event("input", { bubbles: true });
197
- input.dispatchEvent(event);
198
- });
199
- }, []);
200
- return ref2;
201
- }
202
211
  function toStateValue(value) {
203
- if (typeof store.state[props.name] === "number") {
212
+ const selected = props.getter(store.state);
213
+ if (typeof selected === "number") {
204
214
  return Number(value);
205
215
  }
206
- if (store.state[props.name] instanceof Date) {
216
+ if (selected instanceof Date) {
207
217
  return new Date(value);
208
218
  }
209
219
  return value;
210
220
  }
211
- function createChangeEventHandler() {
212
- return (e) => {
213
- const target = e.target;
214
- if (props.type === "checkbox") {
215
- store.dispatch(
216
- (state) => {
217
- state[props.name] = target.checked;
218
- },
219
- {
220
- key: dispatchKey
221
- }
222
- );
221
+ const inputProps = useStoreController(store, {
222
+ ref: props.ref,
223
+ onSubscribe: (state, element) => {
224
+ if ("checked" in element && (props.type === "checkbox" || props.type === "radio")) {
225
+ const checked = toInputChecked(props.getter(state));
226
+ if (element.checked === checked) {
227
+ return;
228
+ }
229
+ element.checked = checked;
223
230
  } else {
224
- store.dispatch(
225
- (state) => {
226
- state[props.name] = toStateValue(target.value);
227
- },
228
- {
229
- key: dispatchKey
230
- }
231
- );
231
+ const value = toInputValue(props.getter(state));
232
+ if (element.value === value) {
233
+ return;
234
+ }
235
+ element.value = value;
232
236
  }
233
- props.onChange?.(e);
234
- };
235
- }
236
- const dispatchKey = (0, import_react5.useId)();
237
- const ref = useSubscriptionRef();
238
- const name = String(props.name);
239
- const defaultValue = getDefaultValue();
240
- const defaultChecked = getDefaultChecked();
241
- const onChange = createChangeEventHandler();
237
+ const event = new Event("input", { bubbles: true });
238
+ element.dispatchEvent(event);
239
+ },
240
+ onDispatch: (state, element) => {
241
+ if ("checked" in element && props.type === "checkbox") {
242
+ props.setter(state, element.checked);
243
+ } else {
244
+ props.setter(state, toStateValue(element.value));
245
+ }
246
+ }
247
+ });
242
248
  return {
243
- key: dispatchKey,
244
- ref,
245
- name,
246
- defaultValue,
247
- defaultChecked,
248
- onChange
249
+ ref: inputProps.ref,
250
+ dispatchKey: inputProps.dispatchKey,
251
+ defaultValue: getDefaultValue(),
252
+ defaultChecked: getDefaultChecked(),
253
+ onChange: (event) => {
254
+ inputProps.onChange();
255
+ props.onChange?.(event);
256
+ }
249
257
  };
250
258
  }
251
259
 
252
- // src/use_store_input.tsx
253
- function useStoreInput(store) {
254
- const input = (0, import_react6.useCallback)(function Component(props) {
255
- return /* @__PURE__ */ import_react7.default.createElement(Input, { store, ...props });
260
+ // src/use_store_input_with_name.tsx
261
+ function useStoreInputWithName(store, props) {
262
+ const inputProps = useStoreInput(store, {
263
+ ...props,
264
+ getter: (state) => {
265
+ if (props.getter) {
266
+ return props.getter(state);
267
+ }
268
+ return state[props.name];
269
+ },
270
+ setter: (state, value) => {
271
+ if (props.setter) {
272
+ props.setter(state, value);
273
+ return;
274
+ }
275
+ state[props.name] = value;
276
+ }
277
+ });
278
+ return {
279
+ ...inputProps,
280
+ name: "name" in props ? String(props.name) : void 0
281
+ };
282
+ }
283
+
284
+ // src/use_store_component.tsx
285
+ function useStoreComponent(store) {
286
+ const input = (0, import_react7.useCallback)(function Component(props) {
287
+ return /* @__PURE__ */ import_react8.default.createElement(Input, { store, ...props });
256
288
  }, []);
257
- const select = (0, import_react6.useCallback)(function Component(props) {
258
- return /* @__PURE__ */ import_react7.default.createElement(Select, { store, ...props });
289
+ const select = (0, import_react7.useCallback)(function Component(props) {
290
+ return /* @__PURE__ */ import_react8.default.createElement(Select, { store, ...props });
259
291
  }, []);
260
- const textarea = (0, import_react6.useCallback)(function Component(props) {
261
- return /* @__PURE__ */ import_react7.default.createElement(Textarea, { store, ...props });
292
+ const textarea = (0, import_react7.useCallback)(function Component(props) {
293
+ return /* @__PURE__ */ import_react8.default.createElement(Textarea, { store, ...props });
262
294
  }, []);
263
295
  return {
264
296
  input,
@@ -270,28 +302,28 @@ function Input({
270
302
  store,
271
303
  ...props
272
304
  }) {
273
- const storeProps = useStoreInputProps(store, props);
274
- return /* @__PURE__ */ import_react7.default.createElement("input", { ...props, ...storeProps });
305
+ const storeProps = useStoreInputWithName(store, props);
306
+ return /* @__PURE__ */ import_react8.default.createElement("input", { ...props, ...storeProps });
275
307
  }
276
308
  function Select({
277
309
  store,
278
310
  ...props
279
311
  }) {
280
- const storeProps = useStoreInputProps(store, props);
281
- return /* @__PURE__ */ import_react7.default.createElement("select", { ...props, ...storeProps });
312
+ const storeProps = useStoreInputWithName(store, props);
313
+ return /* @__PURE__ */ import_react8.default.createElement("select", { ...props, ...storeProps });
282
314
  }
283
315
  function Textarea({
284
316
  store,
285
317
  ...props
286
318
  }) {
287
- const storeProps = useStoreInputProps(store, props);
288
- return /* @__PURE__ */ import_react7.default.createElement("textarea", { ...props, ...storeProps });
319
+ const storeProps = useStoreInputWithName(store, props);
320
+ return /* @__PURE__ */ import_react8.default.createElement("textarea", { ...props, ...storeProps });
289
321
  }
290
322
 
291
323
  // src/use_form_store.tsx
292
324
  function useFormStore(initialState) {
293
325
  const store = useStore(initialState);
294
- const storeInput = useStoreInput(store);
326
+ const storeComponent = useStoreComponent(store);
295
327
  return {
296
328
  get state() {
297
329
  return store.state;
@@ -299,7 +331,7 @@ function useFormStore(initialState) {
299
331
  dispatch: store.dispatch,
300
332
  subscribe: store.subscribe,
301
333
  render: createRenderWithStore(store),
302
- ...storeInput
334
+ ...storeComponent
303
335
  };
304
336
  }
305
337
  // Annotate the CommonJS export names for ESM import in node:
@@ -82,20 +82,60 @@ function useStore(initialState) {
82
82
  };
83
83
  }
84
84
 
85
- // src/use_store_input.tsx
85
+ // src/use_store_component.tsx
86
86
  import {
87
87
  useCallback
88
88
  } from "react";
89
89
  import React2 from "react";
90
90
 
91
- // src/use_store_input_props.tsx
92
- import {
93
- useEffect as useEffect2,
94
- useId,
95
- useRef as useRef2
96
- } from "react";
91
+ // src/use_store_input.tsx
92
+ import "react";
97
93
  import { format } from "date-fns";
98
- function useStoreInputProps(store, props) {
94
+
95
+ // src/use_store_controller.tsx
96
+ import { useEffect as useEffect2, useId, useRef as useRef2 } from "react";
97
+ function useStoreController(store, props) {
98
+ const ref = useRef2(null);
99
+ const dispatchKey = useId();
100
+ useEffect2(() => {
101
+ const element = ref.current;
102
+ if (!element) {
103
+ return;
104
+ }
105
+ if (typeof props.ref === "function") {
106
+ props.ref(element);
107
+ } else if (props.ref) {
108
+ props.ref.current = element;
109
+ }
110
+ }, []);
111
+ useSubscribe(store, (state, key) => {
112
+ if (key === dispatchKey) {
113
+ return;
114
+ }
115
+ if (!ref.current) return;
116
+ props.onSubscribe(state, ref.current);
117
+ });
118
+ const onChange = () => {
119
+ store.dispatch(
120
+ (state) => {
121
+ const element = ref.current;
122
+ if (!element) return;
123
+ props.onDispatch(state, element);
124
+ },
125
+ {
126
+ key: dispatchKey
127
+ }
128
+ );
129
+ };
130
+ return {
131
+ dispatchKey,
132
+ ref,
133
+ onChange
134
+ };
135
+ }
136
+
137
+ // src/use_store_input.tsx
138
+ function useStoreInput(store, props) {
99
139
  const toInputValue = (value) => {
100
140
  if (value === void 0 || value === null) {
101
141
  return "";
@@ -117,7 +157,7 @@ function useStoreInputProps(store, props) {
117
157
  if (props.type === "checkbox" || props.type === "radio") {
118
158
  return void 0;
119
159
  }
120
- return toInputValue(store.state[props.name]);
160
+ return toInputValue(props.getter(store.state));
121
161
  };
122
162
  const toInputChecked = (value) => {
123
163
  if (props.type === "radio") {
@@ -132,95 +172,83 @@ function useStoreInputProps(store, props) {
132
172
  if (props.type !== "checkbox" && props.type !== "radio") {
133
173
  return void 0;
134
174
  }
135
- return toInputChecked(store.state[props.name]);
175
+ return toInputChecked(props.getter(store.state));
136
176
  };
137
- function useSubscriptionRef() {
138
- const ref2 = useRef2(null);
139
- useEffect2(() => {
140
- const input = ref2.current;
141
- if (!input) {
142
- return;
143
- }
144
- if (typeof props.ref === "function") {
145
- props.ref(input);
146
- } else if (props.ref) {
147
- props.ref.current = input;
148
- }
149
- return store.subscribe((state, key) => {
150
- if (key === dispatchKey) {
151
- return;
152
- }
153
- if (props.type === "checkbox" || props.type === "radio") {
154
- const checked = toInputChecked(state[props.name]);
155
- if (input.checked === checked) {
156
- return;
157
- }
158
- input.checked = checked;
159
- } else {
160
- const value = toInputValue(state[props.name]);
161
- if (input.value === value) {
162
- return;
163
- }
164
- input.value = value;
165
- }
166
- const event = new Event("input", { bubbles: true });
167
- input.dispatchEvent(event);
168
- });
169
- }, []);
170
- return ref2;
171
- }
172
177
  function toStateValue(value) {
173
- if (typeof store.state[props.name] === "number") {
178
+ const selected = props.getter(store.state);
179
+ if (typeof selected === "number") {
174
180
  return Number(value);
175
181
  }
176
- if (store.state[props.name] instanceof Date) {
182
+ if (selected instanceof Date) {
177
183
  return new Date(value);
178
184
  }
179
185
  return value;
180
186
  }
181
- function createChangeEventHandler() {
182
- return (e) => {
183
- const target = e.target;
184
- if (props.type === "checkbox") {
185
- store.dispatch(
186
- (state) => {
187
- state[props.name] = target.checked;
188
- },
189
- {
190
- key: dispatchKey
191
- }
192
- );
187
+ const inputProps = useStoreController(store, {
188
+ ref: props.ref,
189
+ onSubscribe: (state, element) => {
190
+ if ("checked" in element && (props.type === "checkbox" || props.type === "radio")) {
191
+ const checked = toInputChecked(props.getter(state));
192
+ if (element.checked === checked) {
193
+ return;
194
+ }
195
+ element.checked = checked;
193
196
  } else {
194
- store.dispatch(
195
- (state) => {
196
- state[props.name] = toStateValue(target.value);
197
- },
198
- {
199
- key: dispatchKey
200
- }
201
- );
197
+ const value = toInputValue(props.getter(state));
198
+ if (element.value === value) {
199
+ return;
200
+ }
201
+ element.value = value;
202
202
  }
203
- props.onChange?.(e);
204
- };
205
- }
206
- const dispatchKey = useId();
207
- const ref = useSubscriptionRef();
208
- const name = String(props.name);
209
- const defaultValue = getDefaultValue();
210
- const defaultChecked = getDefaultChecked();
211
- const onChange = createChangeEventHandler();
203
+ const event = new Event("input", { bubbles: true });
204
+ element.dispatchEvent(event);
205
+ },
206
+ onDispatch: (state, element) => {
207
+ if ("checked" in element && props.type === "checkbox") {
208
+ props.setter(state, element.checked);
209
+ } else {
210
+ props.setter(state, toStateValue(element.value));
211
+ }
212
+ }
213
+ });
212
214
  return {
213
- key: dispatchKey,
214
- ref,
215
- name,
216
- defaultValue,
217
- defaultChecked,
218
- onChange
215
+ ref: inputProps.ref,
216
+ dispatchKey: inputProps.dispatchKey,
217
+ defaultValue: getDefaultValue(),
218
+ defaultChecked: getDefaultChecked(),
219
+ onChange: (event) => {
220
+ inputProps.onChange();
221
+ props.onChange?.(event);
222
+ }
219
223
  };
220
224
  }
221
225
 
222
- // src/use_store_input.tsx
223
- function useStoreInput(store) {
226
+ // src/use_store_input_with_name.tsx
227
+ function useStoreInputWithName(store, props) {
228
+ const inputProps = useStoreInput(store, {
229
+ ...props,
230
+ getter: (state) => {
231
+ if (props.getter) {
232
+ return props.getter(state);
233
+ }
234
+ return state[props.name];
235
+ },
236
+ setter: (state, value) => {
237
+ if (props.setter) {
238
+ props.setter(state, value);
239
+ return;
240
+ }
241
+ state[props.name] = value;
242
+ }
243
+ });
244
+ return {
245
+ ...inputProps,
246
+ name: "name" in props ? String(props.name) : void 0
247
+ };
248
+ }
249
+
250
+ // src/use_store_component.tsx
251
+ function useStoreComponent(store) {
224
252
  const input = useCallback(function Component(props) {
225
253
  return /* @__PURE__ */ React2.createElement(Input, { store, ...props });
226
254
  }, []);
@@ -240,28 +268,28 @@ function Input({
240
268
  store,
241
269
  ...props
242
270
  }) {
243
- const storeProps = useStoreInputProps(store, props);
271
+ const storeProps = useStoreInputWithName(store, props);
244
272
  return /* @__PURE__ */ React2.createElement("input", { ...props, ...storeProps });
245
273
  }
246
274
  function Select({
247
275
  store,
248
276
  ...props
249
277
  }) {
250
- const storeProps = useStoreInputProps(store, props);
278
+ const storeProps = useStoreInputWithName(store, props);
251
279
  return /* @__PURE__ */ React2.createElement("select", { ...props, ...storeProps });
252
280
  }
253
281
  function Textarea({
254
282
  store,
255
283
  ...props
256
284
  }) {
257
- const storeProps = useStoreInputProps(store, props);
285
+ const storeProps = useStoreInputWithName(store, props);
258
286
  return /* @__PURE__ */ React2.createElement("textarea", { ...props, ...storeProps });
259
287
  }
260
288
 
261
289
  // src/use_form_store.tsx
262
290
  function useFormStore(initialState) {
263
291
  const store = useStore(initialState);
264
- const storeInput = useStoreInput(store);
292
+ const storeComponent = useStoreComponent(store);
265
293
  return {
266
294
  get state() {
267
295
  return store.state;
@@ -269,7 +297,7 @@ function useFormStore(initialState) {
269
297
  dispatch: store.dispatch,
270
298
  subscribe: store.subscribe,
271
299
  render: createRenderWithStore(store),
272
- ...storeInput
300
+ ...storeComponent
273
301
  };
274
302
  }
275
303
  export {
@@ -0,0 +1,21 @@
1
+ import React__default, { DetailedHTMLProps, InputHTMLAttributes } from 'react';
2
+ import { Store } from './use_store.mjs';
3
+
4
+ type StoreComponentProps<TInputElement, TState> = Omit<DetailedHTMLProps<InputHTMLAttributes<TInputElement>, TInputElement>, "name"> & {
5
+ name?: keyof TState;
6
+ getter?: (state: TState) => unknown;
7
+ setter?: (state: TState, value: unknown) => void;
8
+ };
9
+ declare function useStoreComponent<TState>(store: Store<TState>): {
10
+ input: React__default.FC<StoreComponentProps<HTMLInputElement, TState>>;
11
+ select: React__default.FC<StoreComponentProps<HTMLSelectElement, TState>>;
12
+ textarea: React__default.FC<StoreComponentProps<HTMLTextAreaElement, TState>>;
13
+ };
14
+ type StoreComponentPropsWithStore<TElement extends HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, TState> = StoreComponentProps<TElement, TState> & {
15
+ store: Store<TState>;
16
+ };
17
+ declare function Input<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLInputElement, TState>): React__default.JSX.Element;
18
+ declare function Select<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLSelectElement, TState>): React__default.JSX.Element;
19
+ declare function Textarea<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLTextAreaElement, TState>): React__default.JSX.Element;
20
+
21
+ export { Input, Select, type StoreComponentProps, type StoreComponentPropsWithStore, Textarea, useStoreComponent };
@@ -0,0 +1,21 @@
1
+ import React__default, { DetailedHTMLProps, InputHTMLAttributes } from 'react';
2
+ import { Store } from './use_store.js';
3
+
4
+ type StoreComponentProps<TInputElement, TState> = Omit<DetailedHTMLProps<InputHTMLAttributes<TInputElement>, TInputElement>, "name"> & {
5
+ name?: keyof TState;
6
+ getter?: (state: TState) => unknown;
7
+ setter?: (state: TState, value: unknown) => void;
8
+ };
9
+ declare function useStoreComponent<TState>(store: Store<TState>): {
10
+ input: React__default.FC<StoreComponentProps<HTMLInputElement, TState>>;
11
+ select: React__default.FC<StoreComponentProps<HTMLSelectElement, TState>>;
12
+ textarea: React__default.FC<StoreComponentProps<HTMLTextAreaElement, TState>>;
13
+ };
14
+ type StoreComponentPropsWithStore<TElement extends HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, TState> = StoreComponentProps<TElement, TState> & {
15
+ store: Store<TState>;
16
+ };
17
+ declare function Input<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLInputElement, TState>): React__default.JSX.Element;
18
+ declare function Select<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLSelectElement, TState>): React__default.JSX.Element;
19
+ declare function Textarea<TState>({ store, ...props }: StoreComponentPropsWithStore<HTMLTextAreaElement, TState>): React__default.JSX.Element;
20
+
21
+ export { Input, Select, type StoreComponentProps, type StoreComponentPropsWithStore, Textarea, useStoreComponent };