@twobirds/microcomponents 0.0.50 → 0.0.51

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.
Files changed (105) hide show
  1. package/dist/formValues.d.ts.map +1 -1
  2. package/dist/formValues.ts +17 -18
  3. package/dist/formvValues.min.js +1 -1
  4. package/dist/microcomponents.min.js +1 -1
  5. package/package.json +1 -1
  6. package/public/assets/search.js +1 -1
  7. package/public/classes/MC.DC.html +13 -13
  8. package/public/classes/MC.MC.html +7 -7
  9. package/public/classes/MC.McBase.html +4 -4
  10. package/public/classes/MC.McEvent.html +13 -13
  11. package/public/classes/formValues.FormValues.html +86 -0
  12. package/public/functions/MC.addListener.html +2 -1
  13. package/public/functions/{formValues.formValues.html → MC.autoload.html} +18 -17
  14. package/public/functions/MC.removeListener.html +2 -1
  15. package/public/functions/elements.defineCE.html +1 -1
  16. package/public/functions/elements.getCE.html +1 -1
  17. package/public/functions/observables.observe.html +3 -3
  18. package/public/functions/selectors._d.html +1 -1
  19. package/public/functions/selectors._t.html +1 -1
  20. package/public/interfaces/MC.HTMLMcElement.html +2 -2
  21. package/public/interfaces/selectors.DSelector.html +55 -55
  22. package/public/interfaces/selectors.TSelector.html +37 -37
  23. package/public/modules/MC.html +3 -1
  24. package/public/modules/elements.html +1 -1
  25. package/public/modules/formValues.html +4 -4
  26. package/public/modules/observables.html +1 -1
  27. package/public/modules/selectors.html +1 -1
  28. package/public/types/observables.Observable.html +1 -1
  29. package/public/types/selectors.selection.html +1 -1
  30. package/public/types/selectors.singleSelector.html +1 -1
  31. package/src/formValues.ts +17 -18
  32. package/public/3d.html +0 -42
  33. package/public/Grandparent.css +0 -13
  34. package/public/Grandparent.js +0 -338
  35. package/public/MC.js +0 -314
  36. package/public/MC.js.map +0 -1
  37. package/public/MC.min.js +0 -451
  38. package/public/McEvent.js +0 -71
  39. package/public/McEvent.js.map +0 -1
  40. package/public/MicroComponents.svg +0 -15
  41. package/public/TestForm.css +0 -47
  42. package/public/TestForm.html +0 -56
  43. package/public/TestForm.js +0 -56
  44. package/public/TestForm.json +0 -27
  45. package/public/Testform.js +0 -149
  46. package/public/autoloader.js +0 -53
  47. package/public/autoloader.js.map +0 -1
  48. package/public/documentation/MC.md +0 -470
  49. package/public/documentation/ajaxian-1.png +0 -0
  50. package/public/documentation/ajaxian-2.png +0 -0
  51. package/public/documentation/ajaxian-3.png +0 -0
  52. package/public/documentation/comparision.md +0 -0
  53. package/public/documentation/elements.md +0 -276
  54. package/public/documentation/functional_requirements.md +0 -8
  55. package/public/documentation/history.md +0 -436
  56. package/public/documentation/how_tos.md +0 -0
  57. package/public/documentation/introduction.md +0 -0
  58. package/public/documentation/magic.md +0 -29
  59. package/public/documentation/observe.md +0 -317
  60. package/public/documentation/proposal_draft.md +0 -37
  61. package/public/documentation/rnd0023-1.jpg +0 -0
  62. package/public/documentation/rnd0023-2.jpg +0 -0
  63. package/public/documentation/rnd0023-3.jpg +0 -0
  64. package/public/documentation/tB_react.md +0 -207
  65. package/public/documentation/usage.md +0 -142
  66. package/public/documentation/why.md +0 -25
  67. package/public/elements.js +0 -48
  68. package/public/elements.js.map +0 -1
  69. package/public/elements.min.js +0 -1
  70. package/public/fiddle/MicroComponents.svg +0 -15
  71. package/public/fiddle/fiddle.css +0 -0
  72. package/public/fiddle/fiddle.js +0 -0
  73. package/public/fiddle/index.html +0 -0
  74. package/public/formValues.js +0 -205
  75. package/public/formValues.js.map +0 -1
  76. package/public/formvValues.min.js +0 -1
  77. package/public/helpers.js +0 -113
  78. package/public/helpers.js.map +0 -1
  79. package/public/microcomponents.es3.js +0 -303
  80. package/public/microcomponents.es3.js.map +0 -1
  81. package/public/microcomponents.js +0 -9
  82. package/public/microcomponents.js.map +0 -1
  83. package/public/microcomponents.min.js +0 -1
  84. package/public/my-tag.css +0 -19
  85. package/public/observables.js +0 -251
  86. package/public/observables.js.map +0 -1
  87. package/public/observables.min.js +0 -1
  88. package/public/selectors.js +0 -971
  89. package/public/selectors.js.map +0 -1
  90. package/public/selectors.min.js +0 -1
  91. package/public/src/MC.ts +0 -478
  92. package/public/src/McEvent.ts +0 -96
  93. package/public/src/autoloader.ts +0 -98
  94. package/public/src/elements.ts +0 -76
  95. package/public/src/formValues.ts +0 -278
  96. package/public/src/helpers.ts +0 -149
  97. package/public/src/microcomponents.ts +0 -8
  98. package/public/src/observables.ts +0 -405
  99. package/public/src/selectors.ts +0 -1634
  100. package/public/src/test.ts +0 -177
  101. package/public/test/Grandparent.js +0 -1
  102. package/public/test/Testform.js +0 -1
  103. package/public/test.html +0 -27
  104. package/public/test.js +0 -78
  105. package/public/test.js.map +0 -1
@@ -1,317 +0,0 @@
1
- Okay, I understand. You want me to modify the code examples within the Markdown documentation so that they demonstrate how to use the observe() functionality inside a microcomponent's constructor (specifically, an MC constructor). I'll also keep the output as a JavaScript variable assignment (let md = "...";).
2
-
3
- Here's the updated version of the code, with the examples adapted to be used within an MC constructor:
4
- JavaScript
5
-
6
- let md = `# Observable Properties Functionality (`observe()`)
7
-
8
- This document explains the `observe()` functionality, a utility for making properties of JavaScript objects observable. When an observable property's value changes, registered callback functions are automatically notified, enabling reactive data binding and UI updates.
9
-
10
- ## Table of Contents
11
-
12
- - [Core Concept](#core-concept)
13
- - [Function Signature](#function-signature)
14
- - [How it Works](#how-it-works)
15
- - [Key Features](#key-features)
16
- - [Usage](#usage)
17
- - [Making Properties Observable (within MC Constructor)](#making-properties-observable-within-mc-constructor)
18
- - [Registering Observers (`observe()` method on Observable) (within MC Constructor)](#registering-observers-observe-method-on-observable-within-mc-constructor)
19
- - [Binding Observable Objects to the DOM (`bind()` method on Observable Object) (within MC Constructor)](#binding-observable-objects-to-the-dom-bind-method-on-observable-object-within-mc-constructor)
20
- - [Manually Notifying Observers (`notify()` method on Observable) (within MC Constructor)](#manually-notifying-observers-notify-method-on-observable-within-mc-constructor)
21
- - [Examples of Useful Usage (within MC Constructor)](#examples-of-useful-usage-within-mc-constructor)
22
- - [Simple Data Binding (within MC Constructor)](#simple-data-binding-within-mc-constructor)
23
- - [Automatic UI Updates in Web Components (within MC Constructor)](#automatic-ui-updates-in-web-components-within-mc-constructor)
24
- - [Centralized State Management (within MC Constructor)](#centralized-state-management-within-mc-constructor)
25
- - [Form Input Synchronization (within MC Constructor)](#form-input-synchronization-within-mc-constructor)
26
- - [Considerations](#considerations)
27
- - [Performance](#performance)
28
- - [Deep Object Observation](#deep-object-observation)
29
- - [Type Changes](#type-changes)
30
- - [Related Concepts](#related-concepts)
31
-
32
- ## <a name="core-concept"></a>Core Concept
33
-
34
- The `observe()` function transforms specified properties of a JavaScript object into "observable" properties. This means that changes to these properties can be intercepted, and registered listeners (callbacks) can be automatically invoked to react to these changes. This pattern is fundamental for implementing reactive programming paradigms, where UI or other parts of an application automatically update in response to data modifications.
35
-
36
- ## <a name="function-signature"></a>Function Signature
37
-
38
- ```
39
- observe(target: LooseObject, propertyName?: string): LooseObject
40
- ```
41
-
42
- - `target: LooseObject`: The JavaScript object whose properties you want to make observable. `LooseObject` is likely a type definition for a generic object (e.g., `{ [key: string]: any }`).
43
- - `propertyName?: string`: An optional string specifying a single property of the `target` object to make observable. If this argument is omitted, the function attempts to make all own properties of the `target` observable.
44
- - `returns: LooseObject`: The original `target` object, now with the specified (or all) properties made observable.
45
-
46
- ## <a name="how-it-works"></a>How it Works
47
-
48
- The `observe()` function achieves observability by:
49
-
50
- 1. **Redefining Properties:** It uses `Object.defineProperty` to redefine the getter and setter of the `target` property (or properties).
51
- 2. **Creating an `Observable` Wrapper:** For each observable property, it creates an instance of a dynamically generated `Observable` class that extends the original constructor of the property's value (e.g., `String`, `Number`, `Object`, `Array`). This wrapper holds the actual value and manages a list of observer callbacks.
52
- 3. **Intercepting Access (Getter):** When an observable property is accessed, the getter returns the `Observable` wrapper instance. For observable objects, it also sets up a debounced function to check for deep changes within the object at a later point.
53
- 4. **Intercepting Modification (Setter):** When an observable property is assigned a new value, the setter:
54
- - Checks if the type of the new value is compatible with the old value.
55
- - Creates a new `Observable` wrapper with the new value.
56
- - Notifies all registered observer callbacks associated with that property (or the entire observable object, depending on how observation is set up).
57
- 5. **Managing Callbacks:** Each `Observable` wrapper maintains a list of callback functions registered through its `observe()` method. These callbacks are invoked when the observable's value changes.
58
- 6. **DOM Binding (`bind()`):** For observable objects, the `bind()` method facilitates automatic synchronization with placeholders in the DOM using the `Placeholders` DOM Component.
59
-
60
- ## <a name="key-features"></a>Key Features
61
-
62
- - Selective Observability: You can choose to make specific properties observable or observe all properties of an object.
63
- - Type Checking: The setter attempts to prevent changing the data type of an observable property.
64
- - Callback Mechanism: Allows registering multiple functions to be notified of changes.
65
- - DOM Binding Integration: Provides a `bind()` method for observable objects to automatically update DOM elements containing placeholders.
66
- - Debounced Deep Change Detection: For observable objects, changes within the object are detected using a debounced deep equality check to optimize performance.
67
-
68
- ## <a name="usage"></a>Usage
69
-
70
- ### <a name="making-properties-observable-within-mc-constructor"></a>Making Properties Observable (within MC Constructor)
71
-
72
- To make properties of an object observable within an MC constructor, call the `observe()` function with the object as the `target`. You can optionally specify a `propertyName` to observe only a single property.
73
-
74
- ```javascript
75
- import { observe } from './observables.js'; // Assuming your observe() function is in this file
76
- import { MC } from './MC.js'; // Import your MC class
77
-
78
- class MyComponent extends MC {
79
- constructor(target) {
80
- super(target);
81
-
82
- this.myData = {
83
- name: 'Initial Name',
84
- count: 0,
85
- settings: {
86
- theme: 'light',
87
- },
88
- };
89
-
90
- observe(this.myData); // Make all properties of this.myData observable
91
-
92
- this.myData.name = 'Updated Name'; // Observers of this.myData.name will be notified
93
- this.myData.count++; // Observers of this.myData.count will be notified
94
- this.myData.settings.theme = 'dark'; // Observers of this.myData.settings will be notified
95
- }
96
- }
97
- ```
98
-
99
- ```javascript
100
- import { observe } from './observables.js';
101
- import { MC } from './MC.js';
102
-
103
- class MyConfigComponent extends MC {
104
- constructor(target) {
105
- super(target);
106
-
107
- this.config = {
108
- apiKey: 'your_api_key',
109
- isEnabled: true,
110
- };
111
-
112
- observe(this.config, 'apiKey'); // Only make the apiKey property observable
113
-
114
- this.config.apiKey = 'new_api_key'; // Observers of this.config.apiKey will be notified
115
- this.config.isEnabled = false; // Observers of this.config.isEnabled will NOT be directly notified by observe()
116
- }
117
- }
118
- ```
119
-
120
- ### <a name="registering-observers-observe-method-on-observable-within-mc-constructor"></a>Registering Observers (`observe()` method on Observable) (within MC Constructor)
121
-
122
- When a property becomes observable, its getter will return an `Observable` wrapper. This wrapper has an `observe()` method to register callback functions that will be executed when the observable's value changes.
123
-
124
- ```javascript
125
- import { observe } from './observables.js';
126
- import { MC } from './MC.js';
127
-
128
- class MyStateComponent extends MC {
129
- constructor(target) {
130
- super(target);
131
-
132
- this.state = {
133
- message: 'Hello',
134
- };
135
- observe(this.state);
136
-
137
- this.state.message.observe((newValue) => {
138
- console.log('Message changed to:', newValue);
139
- });
140
-
141
- this.state.message = 'World'; // Output: Message changed to: World
142
- }
143
- }
144
- ```
145
-
146
- ### <a name="binding-observable-objects-to-the-dom-bind-method-on-observable-object-within-mc-constructor"></a>Binding Observable Objects to the DOM (`bind()` method on Observable Object) (within MC Constructor)
147
-
148
- If an observable property's value is an object, it will have a `bind()` method. This method allows you to automatically connect the observable object's properties to placeholders (`{propertyName}`) within a specified DOM element (or its descendants). This relies on the `Placeholders` DOM Component.
149
-
150
- ```javascript
151
- import { observe } from './observables.js';
152
- import { MC } from './MC.js';
153
-
154
- class MyUserDataComponent extends MC {
155
- constructor(target) {
156
- super(target);
157
-
158
- this.userData = {
159
- firstName: 'John',
160
- lastName: 'Doe',
161
- };
162
- observe(this.userData);
163
-
164
- this.outputElement = document.getElementById('output'); // Assuming you have an element with id="output"
165
- this.userData.bind(this.outputElement);
166
-
167
- this.outputElement.innerHTML = `
168
- <p>First Name: {firstName}</p>
169
- <p>Last Name: {lastName}</p>
170
- `;
171
-
172
- this.userData.firstName = 'Jane'; // The text content of the first <p> will automatically update
173
- }
174
- }
175
- ```
176
-
177
- ### <a name="manually-notifying-observers-notify-method-on-observable-within-mc-constructor"></a>Manually Notifying Observers (`notify()` method on Observable) (within MC Constructor)
178
-
179
- The `Observable` wrapper also has a `notify()` method that you can call manually to force the registered observers to be executed. This can be useful in specific scenarios where changes might not be directly detected by the setter (though the debounced deep check for objects aims to handle this).
180
-
181
- ```javascript
182
- import { observe } from './observables.js';
183
- import { MC } from './MC.js';
184
-
185
- class MyDataItemsComponent extends MC {
186
- constructor(target) {
187
- super(target);
188
-
189
- this.data = {
190
- items: [],
191
- };
192
- observe(this.data);
193
-
194
- this.data.items.observe(() => {
195
- console.log('Items array changed:', this.data.items);
196
- });
197
-
198
- // Directly modifying the array might not always trigger the setter
199
- this.data.items.push('new item');
200
- this.data.items.notify(); // Manually trigger the observers
201
- }
202
- }
203
- ```
204
-
205
- ## <a name="examples-of-useful-usage-within-mc-constructor"></a>Examples of Useful Usage (within MC Constructor)
206
-
207
- ### <a name="simple-data-binding-within-mc-constructor"></a>Simple Data Binding (within MC Constructor)
208
-
209
- Observables are excellent for simple data binding scenarios where you want to keep different parts of your application synchronized with a piece of data.
210
-
211
- ```javascript
212
- import { observe } from './observables.js';
213
- import { MC } from './MC.js';
214
-
215
- class MyInputComponent extends MC {
216
- constructor(target) {
217
- super(target);
218
-
219
- this.viewModel = {
220
- inputValue: '',
221
- };
222
- observe(this.viewModel);
223
-
224
- this.inputElement = document.getElementById('myInput'); // Assuming you have an input with id="myInput"
225
- this.outputSpan = document.getElementById('outputValue'); // Assuming you have a span with id="outputValue"
226
-
227
- this.inputElement.addEventListener('input', (event) => {
228
- this.viewModel.inputValue = event.target.value;
229
- });
230
-
231
- this.viewModel.inputValue.observe((newValue) => {
232
- this.outputSpan.textContent = newValue;
233
- });
234
- }
235
- }
236
- ```
237
-
238
- ### <a name="automatic-ui-updates-in-web-components-within-mc-constructor"></a>Automatic UI Updates in Web Components (within MC Constructor)
239
-
240
- As demonstrated in the `my-tag` example, observables can be used to automatically update the template of a web component when its internal data changes, leading to reactive and dynamic UIs.
241
-
242
- ### <a name="centralized-state-management-within-mc-constructor"></a>Centralized State Management (within MC Constructor)
243
-
244
- Observables can form the basis of a simple state management system. By making the application's state an observable object, different components can observe relevant parts of the state and automatically update when those parts change.
245
-
246
- ```javascript
247
- import { observe } from './observables.js';
248
- import { MC } from './MC.js';
249
-
250
- class MyAppStateComponent extends MC {
251
- constructor(target) {
252
- super(target);
253
-
254
- this.appState = {
255
- user: null,
256
- isLoading: false,
257
- errorMessage: null,
258
- };
259
- observe(this.appState);
260
-
261
- // Component A observes the user
262
- this.appState.user.observe((user) => {
263
- if (user) {
264
- console.log('User logged in:', user.name);
265
- // Update UI to show user info
266
- } else {
267
- console.log('User logged out');
268
- // Update UI to reflect logged out state
269
- }
270
- });
271
-
272
- // Component B observes the loading state
273
- this.appState.isLoading.observe((loading) => {
274
- if (loading) {
275
- console.log('Loading...');
276
- // Show loading indicator
277
- } else {
278
- console.log('Loading complete.');
279
- // Hide loading indicator
280
- }
281
- });
282
-
283
- // Actions can update the state
284
- this.loginUser = (username, password) => {
285
- this.appState.isLoading = true;
286
- // ... perform login logic ...
287
- setTimeout(() => {
288
- this.appState.user = { name: username };
289
- this.appState.isLoading = false;
290
- }, 1000);
291
- };
292
-
293
- this.loginUser('john.doe', 'password');
294
- }
295
- }
296
- ```
297
-
298
- ## <a name="considerations"></a>Considerations
299
-
300
- ### <a name="performance"></a>Performance
301
-
302
- While observables provide a convenient way to handle data changes, be mindful of performance, especially with deeply nested objects or a large number of observers. Excessive notifications and deep equality checks can potentially impact performance.
303
-
304
- ### <a name="deep-object-observation"></a>Deep Object Observation
305
-
306
- The provided `observe()` implementation includes a debounced deep equality check for object properties. However, for very complex or frequently changing nested objects, you might consider more optimized deep observation techniques if performance becomes an issue.
307
-
308
- ### <a name="type-changes"></a>Type Changes
309
-
310
- The setter in the `observe()` function attempts to prevent changing the data type of an observable property. Be aware of this limitation when working with observable data.
311
-
312
- ## <a name="related-concepts"></a>Related Concepts
313
-
314
- - Reactive Programming: A programming paradigm centered around the propagation of change.
315
- - Data Binding: The process of synchronizing data between different parts of an application, often between the model and the view.
316
- - DOM Components: Reusable units of behavior associated with DOM elements, as provided by the Microcomponent Framework.
317
- - Placeholders: Dynamic markers within HTML that can be automatically updated with data.
@@ -1,37 +0,0 @@
1
- ### RFC Proposal to WHATWG
2
-
3
- **Title:** Proposal for a **Micro Component Interface** in the DOM
4
-
5
- **Abstract:**
6
-
7
- This proposal introduces a standardized interface for managing micro components within HTML elements, enhancing modularity and reusability in web development.
8
-
9
- **Introduction:**
10
-
11
- Microcomponents provide a way to encapsulate functionality and state within a target DOM element. This proposal outlines methods for adding, removing, and querying micro components.
12
-
13
- **Proposed API:**
14
-
15
- - **Static Methods:**
16
- - `MC.add( target, key, element)`: Attach a top level micro component to an HTMLElement.
17
- - `MC.remove( target, key )`: Detach a top level micro component from an HTMLElement.
18
- - `MC.siblings( target )`: get top level micro components from an HTMLElement.
19
-
20
- - **Instance Methods:**
21
- - `add( key, element )`: Attach a private Micro Component to a Micro Component.
22
- - `remove( key )`: Detach a private Micro Component from a Micro Component.
23
- - `siblings(search?)`: Retrieve sibling micro components.
24
- - `parent(search?)`: Get parent top level micro components.
25
- - `parents(search?)`: Get all ancestor top level micro components.
26
- - `children(search?)`: Retrieve child top level micro components.
27
- - `descendants(search?)`: Get all descendant top level micro components.
28
-
29
- **Use Cases:**
30
- 1. Modular web applications.
31
- 2. Enhancing component-based architecture.
32
-
33
- **Conclusion:**
34
- Implementing this interface will streamline microcomponent management, fostering cleaner code and improved performance.
35
-
36
- **References:**
37
- - [Microcomponents Repository](https://gitlab.com/twoBirds/microcomponents) for a polyfill implementation and usage examples.
Binary file
Binary file
Binary file
@@ -1,207 +0,0 @@
1
- # Discussing React Prop Drilling with ChatGPT
2
-
3
- This is an interesting read where I wanted ChatGPT to come up with a Micro Component solution for a React problem.
4
-
5
- To be honest, I knew MCs can solve it. But I wanted to know what ChatGPT can make of it. Spoiler: it got remarkably close on the first try. The second try was spot on.
6
-
7
- Please mind I have a trained session with a backlog. So you wont get the same answers.
8
-
9
- ***( Cut outs and comments are in parentheses...)***
10
-
11
- ## Start Session
12
-
13
- Me:
14
- **Do you remember our chat regarding Micro Components vs. existing frameworks?**
15
-
16
- ChatGPT:
17
-
18
- Yes, I remember our discussion! We talked about your approach to microcomponents as distinct from established frameworks, with a focus on smaller, modular, data-driven components that are stored in a hash attached to DOM elements (specifically in a _tb property in twoBirds or _mc for microcomponents). Your system emphasizes manual wiring, observability, and ease of interaction across components, making it different from React, Vue, or other component libraries that depend heavily on virtual DOMs, JSX, or hooks.
19
-
20
- Your components follow principles of separation of concerns and DRY by keeping interactions modular but flexible, and they use observables to trigger functions in other components, which can be linked in chains. Your approach allows a component-based design that integrates deeply into the DOM without the overhead of larger frameworks. And while existing frameworks typically follow a top-down data flow, your system allows bi-directional, observable properties that automatically update the DOM when data changes.
21
-
22
- Would you like to revisit any specific aspect, or compare further?
23
-
24
-
25
- ## React
26
-
27
- Me:
28
- **There was something about React specifically?**
29
-
30
-
31
- ChatGPT:
32
-
33
- (...)
34
-
35
- ### Manual Wiring vs. React’s Context and Hooks:
36
- React uses Context and hooks (like useState and useEffect) to manage data flow and lifecycle.
37
-
38
- Your approach leans on manual wiring for connecting data across microcomponents, avoiding the abstraction of hooks and allowing direct, observable-driven updates. This can make the flow of data more transparent and easier to trace in complex applications, whereas hooks can sometimes add complexity or obscurity when trying to understand data dependencies.
39
-
40
- ### Component Reusability and Scaling:
41
- Both React and Micro Components support component-based architecture.
42
-
43
- However, Micro Components allows multiple microcomponents on a single DOM element, and each microcomponent is responsible for specific tasks, making scaling in large applications more modular and straightforward. React encourages separation at the component level, whereas Micro Components does so at the microcomponent level, with direct chaining possible between components.
44
-
45
- (...)
46
-
47
- Each of these aspects underlines Micro Components’ focus on minimalism, modularity, and developer control. These are different from React's abstraction and tooling-heavy approach, making your framework potentially more transparent and lightweight for specific use cases.
48
-
49
- Would you like to dive into any of these differences in more detail?
50
-
51
-
52
- ## Prop Drilling
53
-
54
- Me:
55
- **In general there was a problem regarding carrying properties from a component close to the root of the document to a component that is much deeper into the DOM tree, do you remember that?**
56
-
57
- ChatGPT:
58
-
59
- Yes, I remember!
60
-
61
- We discussed the challenges in carrying properties or state from a root-level component down to deeply nested components. In React, this kind of deep property sharing can become cumbersome and often requires additional tools or patterns, such as:
62
-
63
- ### Prop Drilling:
64
- React requires passing data through each level of components in the tree via props, a process known as prop drilling. This can lead to complex and hard-to-manage code, especially when the data isn’t relevant to every component in the chain.
65
-
66
- (...)
67
-
68
- In contrast, your Micro Components microcomponents have an alternative approach that makes it easier to pass properties throughout the DOM tree:
69
-
70
- ### Direct Microcomponent Selectors:
71
- Micro Components includes selector methods (like .parents() and .descendants()) that allow components to access any microcomponent within the tree without explicit data passing. This capability enables deeply nested components to retrieve properties from higher-level components directly, bypassing the need to route data through intermediary components.
72
-
73
- (...)
74
-
75
- ### Manual Wiring for Control:
76
-
77
- **Because Micro Components rely on manual wiring, you can set up specific connections between components as needed.** This gives you fine-grained control over where and how data flows through the app without involving a top-level state or intermediary components, making it more scalable for larger apps without the need for a Context API or state library.
78
-
79
- (...)
80
-
81
- This structure offers a highly flexible, context-free solution for deep property sharing, making it an efficient alternative to prop drilling or global state libraries in many scenarios. Would you like more details on how Micro Components selectors work with observables to achieve this?
82
-
83
-
84
- ## Generate Code
85
-
86
- Me:
87
- **Can you give an example of 2 react components that interact with each other using micro components? Give me the code of both components, using microomponents to exchange data**
88
-
89
- ***( it took some further hinting, but in the end ChatGPT came up with this: )***
90
-
91
-
92
- ChatGPT:
93
-
94
- Here's the updated code:
95
- Parent Micro Component
96
-
97
- This component will receive a target DOM node and set a value that propagates down to its descendants:
98
-
99
- ```javascript
100
- import { MC } from '@twobirds/microcomponents';
101
-
102
- // Parent Micro Component
103
- class ParentMC extends MC {
104
- constructor(targetNode) {
105
- super(targetNode); // Receive and pass the target DOM node to the MC constructor
106
- }
107
-
108
- set value(newValue) {
109
- // Send value to all descendants named "targetMC"
110
- this.descendants("targetMC").forEach(descendant => descendant.data = newValue);
111
- }
112
- }
113
- ```
114
-
115
- Child Micro Component
116
-
117
- This component has a data setter that updates the internal React state in each child:
118
-
119
- ```javascript
120
- import { MC } from '@twobirds/microcomponents';
121
-
122
- // Child Micro Component
123
- class ChildMC extends MC {
124
- constructor(targetNode, setReactState) {
125
- super(targetNode); // Receive the target DOM node to be managed by MC
126
- this.setReactState = setReactState;
127
- }
128
-
129
- set data(newValue) {
130
- this.setReactState(newValue); // Update React state when data is set
131
- }
132
- }
133
- ```
134
-
135
- React Components Using Micro Components
136
-
137
- The following React setup attaches ParentMC and ChildMC to their respective DOM elements, using the parent DOM node to instantiate the micro components.
138
- Parent Component
139
-
140
- The parent component attaches an instance of ParentMC to the DOM node and sets its value based on inputValue.
141
-
142
- ```javascript
143
-
144
- import React, { useState, useRef, useEffect } from 'react';
145
- import { MC } from '@twobirds/microcomponents';
146
- import { ParentMC } from '@myCompany/ParentMC';
147
-
148
- const ParentComponent = () => {
149
- const [inputValue, setInputValue] = useState("");
150
- const parentRef = useRef(null);
151
- const parentMC = new ParentMC( parentRef );
152
- const sender = MC.add(parentRef.current, 'parentMC', parentMC);
153
-
154
- useEffect(() => {
155
- // Update value in ParentMC whenever inputValue changes
156
- parentMC.value = inputValue;
157
- }, [inputValue]);
158
-
159
- return (
160
- <div ref={parentRef}>
161
- <input
162
- type="text"
163
- value={inputValue}
164
- onChange={(e) => setInputValue( e.target.value )}
165
- placeholder="Type to send data to children"
166
- />
167
- <ChildComponent />
168
- </div>
169
- );
170
- };
171
- ```
172
-
173
- Child Component
174
-
175
- The child component attaches an instance of ChildMC, which updates its state whenever data is set.
176
-
177
- ```javascript
178
- import React, { useState, useRef } from 'react';
179
- import { MC } from '@twobirds/microcomponents';
180
- import { ChildMC } from '@myCompany/ChildMC';
181
-
182
-
183
- const ChildComponent = () => {
184
- const [childData, setChildData] = useState("");
185
- const childRef = useRef(null);
186
- const childMC = new ChildMC( childRef, setChildData );
187
- const receiver = MC.add(childRef.current, 'childMC', childMC);
188
-
189
- return (
190
- <div ref={childRef}>
191
- <h3>Received Data:</h3>
192
- <p>childData</p>
193
- </div>
194
- );
195
- };
196
- ```
197
-
198
- ***( ... I cannot tell about the react part, but the micro coomponent code is spot on. Like WLAN on the DOM :-) )***
199
-
200
-
201
- **ChatGPT can produce errors. Check the information.**
202
-
203
- ## ... yes I do :-)
204
-
205
- ***( ... but it was right on the money in the end. I love AI, albeit with a healthy grain of sceptic salt. )***
206
-
207
- ***( ... and I asked about MCs and Angular likewise, and it directly pointed me to a NG module problem that can also be solved. It even came up with sample code. )***