@dooboostore/dom-render 1.0.102 → 1.0.103
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/DomRender.d.ts +21 -6
- package/DomRender.js +54 -23
- package/DomRenderProxy.d.ts +7 -3
- package/DomRenderProxy.js +120 -49
- package/README.MD +380 -65
- package/components/ComponentBase.d.ts +11 -9
- package/components/ComponentBase.js +41 -14
- package/components/ComponentSet.d.ts +2 -2
- package/components/appender/Appender.d.ts +2 -2
- package/components/checkbox/CheckBox.d.ts +4 -4
- package/components/choose/Choose.d.ts +4 -4
- package/components/choose/Choose.js +0 -16
- package/components/details/Details.d.ts +5 -5
- package/components/forOf/ForOf.d.ts +2 -2
- package/components/if/If.d.ts +2 -2
- package/components/index.d.ts +26 -24
- package/components/index.js +2 -1
- package/components/input/Input.d.ts +2 -2
- package/components/input/Input.js +27 -24
- package/components/promise/PromiseSwitch.d.ts +6 -6
- package/components/promise/PromiseSwitch.js +15 -0
- package/components/radio/Radio.d.ts +4 -4
- package/components/router/Route.d.ts +32 -0
- package/components/router/Route.js +116 -0
- package/components/select/Select.d.ts +3 -3
- package/components/select/Select.js +2 -2
- package/components/this/This.d.ts +9 -2
- package/components/this/This.js +24 -2
- package/components/timer/Timer.d.ts +2 -2
- package/configs/Config.d.ts +6 -1
- package/decorators/DomRenderNoProxy.d.ts +2 -0
- package/decorators/DomRenderNoProxy.js +15 -0
- package/dist/bundle.js +2 -0
- package/events/EventManager.d.ts +16 -4
- package/events/EventManager.js +320 -140
- package/index.d.ts +48 -1
- package/index.js +40 -0
- package/lifecycle/OnDestroyRender.d.ts +1 -1
- package/lifecycle/OnProxyDomRender.d.ts +1 -0
- package/lifecycle/OnProxyDomRender.js +1 -1
- package/operators/DrForOf.js +2 -1
- package/operators/DrIf.js +3 -2
- package/operators/DrTargetElement.js +2 -1
- package/operators/DrTargetElementIsElement.d.ts +0 -5
- package/operators/DrTargetElementIsElement.js +2 -1
- package/operators/DrThis.js +40 -11
- package/operators/OperatorExecuter.js +3 -1
- package/package.json +5 -4
- package/rawsets/Attrs.d.ts +2 -0
- package/rawsets/RawSet.d.ts +2 -2
- package/rawsets/RawSet.js +48 -33
- package/routers/HashRouter.d.ts +5 -4
- package/routers/HashRouter.js +8 -5
- package/routers/PathRouter.d.ts +5 -4
- package/routers/PathRouter.js +6 -4
- package/routers/Router.d.ts +22 -8
- package/routers/Router.js +44 -24
package/README.MD
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
DOM-RENDER
|
|
2
2
|
===
|
|
3
|
-
[](https://www.npmjs.com/package/dom-render) [](LICENSE.md)
|
|
3
|
+
[](https://www.npmjs.com/package/@dooboostore/dom-render) [](LICENSE.md)
|
|
4
4
|
* view template engine
|
|
5
5
|
* Dom control and reorder and render
|
|
6
6
|
* all internal variables are managed by proxy. (DomRenderProxy)
|
|
@@ -111,7 +111,7 @@ export class IndexComponent implements OnInitRender, OnDestroyRender, OnInit, On
|
|
|
111
111
|
```
|
|
112
112
|
```css
|
|
113
113
|
.#uuid# {
|
|
114
|
-
color:${@this@.color}
|
|
114
|
+
color:${@this@.color}$ ;
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
```css
|
|
@@ -394,6 +394,40 @@ export class MyComponent extends ComponentBase<{ 'title': string, 'show-icon': s
|
|
|
394
394
|
```
|
|
395
395
|
When attributes change, the `converter` function will be executed before the value is assigned to the property. For `showIcon`, the string `"true"` or `"false"` will be converted to a boolean. For `createdAt`, the date string will be converted to a `Date` object.
|
|
396
396
|
|
|
397
|
+
### Binding to Methods
|
|
398
|
+
|
|
399
|
+
The `@attribute` decorator can also be applied to methods. When the corresponding HTML attribute changes, the decorated method will be invoked with the new attribute value as its argument. This allows you to execute custom logic directly in response to attribute changes.
|
|
400
|
+
|
|
401
|
+
**Component (`MyComponent.ts`) - Method Example**
|
|
402
|
+
```typescript
|
|
403
|
+
import { ComponentBase, attribute } from '@dooboostore/dom-render';
|
|
404
|
+
|
|
405
|
+
export class MyComponent extends ComponentBase<{ 'data-value': string }> {
|
|
406
|
+
public receivedData: string = '';
|
|
407
|
+
|
|
408
|
+
@attribute({ name: 'data-value' })
|
|
409
|
+
onDataValueChange(newValue: string): void {
|
|
410
|
+
this.receivedData = `Method received: ${newValue}`;
|
|
411
|
+
console.log(this.receivedData);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Template (`index.html`) - Method Example**
|
|
417
|
+
```html
|
|
418
|
+
<my-component data-value="initial"></my-component>
|
|
419
|
+
|
|
420
|
+
<p>${@this@.receivedData}$</p>
|
|
421
|
+
|
|
422
|
+
<script>
|
|
423
|
+
setTimeout(() => {
|
|
424
|
+
const comp = document.querySelector('my-component');
|
|
425
|
+
comp.setAttribute('data-value', 'updated value');
|
|
426
|
+
}, 1000);
|
|
427
|
+
</script>
|
|
428
|
+
```
|
|
429
|
+
When `data-value` attribute changes, the `onDataValueChange` method will be called with the new value.
|
|
430
|
+
|
|
397
431
|
</details>
|
|
398
432
|
|
|
399
433
|
## Element Query with `@query` decorator
|
|
@@ -558,6 +592,49 @@ dr-value-link: <input type="text" dr-value-link="@this@.office.addr.street"> <br
|
|
|
558
592
|
```
|
|
559
593
|
</details>
|
|
560
594
|
|
|
595
|
+
## Element State Attributes
|
|
596
|
+
<details>
|
|
597
|
+
<summary>dr-checked, dr-selected, dr-readonly, dr-disabled<strong>🔻(click)</strong></summary>
|
|
598
|
+
|
|
599
|
+
These attributes allow you to bind boolean values directly to the `checked`, `selected`, `readonly`, and `disabled` properties of HTML elements.
|
|
600
|
+
|
|
601
|
+
* `dr-checked`: Binds the `checked` attribute of an input (checkbox/radio) to a boolean value.
|
|
602
|
+
* `dr-selected`: Binds the `selected` attribute of an option to a boolean value.
|
|
603
|
+
* `dr-readonly`: Binds the `readonly` attribute of an input to a boolean value.
|
|
604
|
+
* `dr-disabled`: Binds the `disabled` attribute of an input/button/etc. to a boolean value.
|
|
605
|
+
|
|
606
|
+
### Example
|
|
607
|
+
|
|
608
|
+
```html
|
|
609
|
+
<!-- Example for dr-checked -->
|
|
610
|
+
<input type="checkbox" dr-checked="@this@.isChecked">
|
|
611
|
+
<p>Checkbox is: ${@this@.isChecked}$</p>
|
|
612
|
+
|
|
613
|
+
<!-- Example for dr-selected -->
|
|
614
|
+
<select>
|
|
615
|
+
<option value="apple" dr-selected="@this@.isAppleSelected">Apple</option>
|
|
616
|
+
<option value="banana" dr-selected="@this@.isBananaSelected">Banana</option>
|
|
617
|
+
</select>
|
|
618
|
+
|
|
619
|
+
<!-- Example for dr-readonly -->
|
|
620
|
+
<input type="text" dr-readonly="@this@.isReadOnly" value="Some text">
|
|
621
|
+
|
|
622
|
+
<!-- Example for dr-disabled -->
|
|
623
|
+
<button dr-disabled="@this@.isDisabled">Click Me</button>
|
|
624
|
+
<input type="text" dr-disabled="@this@.isDisabled" value="Disabled input">
|
|
625
|
+
```
|
|
626
|
+
```typescript
|
|
627
|
+
class Data {
|
|
628
|
+
isChecked = true;
|
|
629
|
+
isAppleSelected = false;
|
|
630
|
+
isBananaSelected = true;
|
|
631
|
+
isReadOnly = false;
|
|
632
|
+
isDisabled = true;
|
|
633
|
+
}
|
|
634
|
+
// ... DomRender.run(new Data(), ...)
|
|
635
|
+
```
|
|
636
|
+
</details>
|
|
637
|
+
|
|
561
638
|
## dr-on-rendered-init
|
|
562
639
|
- rendered call
|
|
563
640
|
|
|
@@ -587,7 +664,7 @@ dr-value-link: <input type="text" dr-value-link="@this@.office.addr.street"> <br
|
|
|
587
664
|
<summary>dr-style<strong>🔻(click)</strong></summary>
|
|
588
665
|
|
|
589
666
|
```html
|
|
590
|
-
<div dr-style="{'background-image': 'url(\''+@this@.my?.image+'\')'}" >aa</div>
|
|
667
|
+
<div dr-style="{'background-image': 'url(\' '+@this@.my?.image+'\')'}" >aa</div>
|
|
591
668
|
<div dr-style="{fontSize: @this@.age + 'px'}"> style </div>
|
|
592
669
|
<div dr-style="{'font-size': '20px'}"> style</div>
|
|
593
670
|
<div dr-style="'font-size: ' + @this@.age +'px; margin: ' + @this@.age + 'px'"> style </div>
|
|
@@ -682,7 +759,6 @@ DomRender.run(data, document.querySelector('#app')!);
|
|
|
682
759
|
```
|
|
683
760
|
<!-- 💥 submit call -->
|
|
684
761
|
<!-- console: {name: 'name data', age: 'age data'} -->
|
|
685
|
-
```
|
|
686
762
|
</details>
|
|
687
763
|
|
|
688
764
|
<details>
|
|
@@ -721,7 +797,6 @@ class FormDataWithValidator {
|
|
|
721
797
|
const data = new FormDataWithValidator();
|
|
722
798
|
DomRender.run(data, document.querySelector('#app')!);
|
|
723
799
|
```
|
|
724
|
-
```
|
|
725
800
|
validator
|
|
726
801
|
- Validator (abstract)
|
|
727
802
|
- ValidatorArray (abstract)
|
|
@@ -762,88 +837,328 @@ validator
|
|
|
762
837
|
|
|
763
838
|
## Route
|
|
764
839
|
<details>
|
|
765
|
-
<summary>Route
|
|
840
|
+
<summary><strong>Route (click)</strong></summary>
|
|
841
|
+
|
|
842
|
+
Declarative routing is supported using the `dr-route-match` and `dr-route-regexp` components. This allows you to conditionally render parts of your UI based on the current URL path.
|
|
766
843
|
|
|
767
|
-
- [
|
|
844
|
+
- [Example](./examples/route)
|
|
845
|
+
|
|
846
|
+
### 1. Configuration
|
|
847
|
+
|
|
848
|
+
To enable routing, you must set the `routerType` in your `DomRender` configuration.
|
|
849
|
+
|
|
850
|
+
- `routerType`: Can be `'hash'`, `'path'`, or `'none'` (default).
|
|
768
851
|
|
|
769
|
-
* config routerType: 'hash' | 'path' | 'none' (default: 'none')
|
|
770
852
|
```typescript
|
|
771
|
-
//
|
|
772
|
-
|
|
773
|
-
|
|
853
|
+
// In your main setup file (e.g., index.ts)
|
|
854
|
+
import { DomRender, DomRenderRunConfig } from '@dooboostore/dom-render';
|
|
855
|
+
|
|
856
|
+
// ... your root object class (e.g., Index)
|
|
857
|
+
|
|
858
|
+
const config: DomRenderRunConfig<Index> = {
|
|
859
|
+
window: window,
|
|
860
|
+
routerType: 'path' // or 'hash'
|
|
774
861
|
};
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
const data = DomRender.run(new Data(), document.querySelector('#app')!, config);
|
|
862
|
+
|
|
863
|
+
const domRender = new DomRender({
|
|
864
|
+
rootObject: new Index(),
|
|
865
|
+
target: document.querySelector('#app')!,
|
|
866
|
+
config: config
|
|
867
|
+
}, {autoGo: '/'}); // autoGo navigates to the initial path
|
|
782
868
|
```
|
|
869
|
+
|
|
870
|
+
### 2. Template Usage
|
|
871
|
+
|
|
872
|
+
Use the `<dr-route-match>` and `<dr-route-regexp>` components in your HTML template to define which content appears for which route.
|
|
873
|
+
|
|
874
|
+
- **`<dr-route-match>`**: Renders its content when the path matches the `value` attribute. It supports simple paths and path parameters (e.g., `/{id}`).
|
|
875
|
+
- **`<dr-route-regexp>`**: Renders its content when the path matches the regular expression in the `value` attribute.
|
|
876
|
+
|
|
783
877
|
```html
|
|
878
|
+
<!-- index.html -->
|
|
784
879
|
<header>
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
<
|
|
789
|
-
<div>
|
|
790
|
-
<button dr-event-click="$router.go('/second', {secondata: 555})">second</button>
|
|
791
|
-
<button dr-event-click="$router.go('/second/5')">second/1</button>
|
|
792
|
-
<button dr-event-click="$router.go('/second/wow')">second/2</button>
|
|
793
|
-
</div>
|
|
794
|
-
<div><button dr-event-click="$router.go('/detail/25?name=zzz')">detail</button></div>
|
|
795
|
-
</div>
|
|
880
|
+
<!-- Navigation buttons -->
|
|
881
|
+
<button dr-event-click="$router?.go({path:'/'})">Main</button>
|
|
882
|
+
<button dr-event-click="$router?.go({path:'/second'})">Second</button>
|
|
883
|
+
<button dr-event-click="$router?.go({path:'/detail/42'})">Detail 42</button>
|
|
796
884
|
</header>
|
|
797
|
-
|
|
885
|
+
|
|
798
886
|
<main>
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
<
|
|
806
|
-
|
|
887
|
+
<!-- Content for the root path -->
|
|
888
|
+
<dr-route-match value="/">
|
|
889
|
+
<h1>Main Page</h1>
|
|
890
|
+
</dr-route-match>
|
|
891
|
+
|
|
892
|
+
<!-- Content for the /second path -->
|
|
893
|
+
<dr-route-match value="/second">
|
|
894
|
+
<h1>Second Page</h1>
|
|
895
|
+
</dr-route-match>
|
|
896
|
+
|
|
897
|
+
<!-- Content for a path with a numeric parameter -->
|
|
898
|
+
<dr-route-match value="/detail/{id:[0-9]+}">
|
|
899
|
+
<h1>Detail Page</h1>
|
|
900
|
+
<p>The router's pathData will contain the matched 'id'.</p>
|
|
901
|
+
</dr-route-match>
|
|
902
|
+
|
|
903
|
+
<!-- Content using a regular expression -->
|
|
904
|
+
<dr-route-regexp value="/second/[0-9]?$">
|
|
905
|
+
<p>This content appears for paths like /second/1, /second/2, etc.</p>
|
|
906
|
+
</dr-route-regexp>
|
|
807
907
|
</main>
|
|
808
|
-
<hr>
|
|
809
|
-
<footer>footer</footer>
|
|
810
908
|
```
|
|
909
|
+
|
|
910
|
+
The `$router` object is automatically available in your templates for navigation (`$router.go(...)`) and testing (`$router.test(...)`).
|
|
911
|
+
|
|
912
|
+
</details>
|
|
913
|
+
|
|
914
|
+
## Accessing the Root Object Proxy
|
|
915
|
+
|
|
916
|
+
After initializing `DomRender`, you can get a proxied reference to your `rootObject`. Any changes made to this proxy will be automatically detected and reflected in the DOM. This is useful for updating state from outside your component's methods, such as in `setTimeout` or in response to external events.
|
|
917
|
+
|
|
811
918
|
```typescript
|
|
812
|
-
|
|
813
|
-
|
|
919
|
+
import { DomRender } from '@dooboostore/dom-render';
|
|
920
|
+
|
|
921
|
+
class App {
|
|
922
|
+
message = 'Hello, World!';
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// 1. Initialize DomRender
|
|
926
|
+
const domRender = new DomRender({
|
|
927
|
+
rootObject: new App(),
|
|
928
|
+
target: document.querySelector('#app')!
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
// 2. Get the proxy to the rootObject
|
|
932
|
+
const data = domRender.rootObject;
|
|
933
|
+
|
|
934
|
+
// 3. Now you can modify the state from anywhere
|
|
935
|
+
setTimeout(() => {
|
|
936
|
+
// This change will automatically update the UI
|
|
937
|
+
data.message = 'Hello, DomRender!';
|
|
938
|
+
}, 2000);
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
```html
|
|
942
|
+
<!-- index.html -->
|
|
943
|
+
<div id="app">
|
|
944
|
+
${@this@.message}$
|
|
945
|
+
</div>
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
## Core Components
|
|
949
|
+
This section describes the built-in components provided by `dom-render`.
|
|
950
|
+
|
|
951
|
+
<details>
|
|
952
|
+
<summary><strong>ComponentBase & Decorators (<code>@attribute</code>, <code>@query</code>, <code>@event</code>)</strong>🔻(click)</summary>
|
|
953
|
+
|
|
954
|
+
`ComponentBase` is the foundation for creating custom components that can interact with the `dom-render` lifecycle and attributes. When you extend `ComponentBase`, you gain access to powerful decorators for linking your class to the template.
|
|
955
|
+
|
|
956
|
+
- **`@attribute`**: Binds a class property to an HTML attribute. It can automatically convert values and even bind to methods.
|
|
957
|
+
- **`@query`**: Injects DOM elements from your component's template into class properties or method arguments.
|
|
958
|
+
- **`@event`**: Binds a class method to a DOM event on an element within the template, handling listener cleanup automatically.
|
|
959
|
+
|
|
960
|
+
*For detailed examples of these decorators, please see their dedicated sections above in the documentation.*
|
|
814
961
|
|
|
815
|
-
|
|
816
|
-
|
|
962
|
+
</details>
|
|
963
|
+
|
|
964
|
+
<details>
|
|
965
|
+
<summary><strong>ComponentSet</strong>🔻(click)</summary>
|
|
966
|
+
|
|
967
|
+
`ComponentSet` is a wrapper class that pairs a component instance with its own template and styles. It's the primary mechanism for dynamically rendering and swapping components within a `dr-this` block.
|
|
968
|
+
|
|
969
|
+
### Usage
|
|
970
|
+
```typescript
|
|
971
|
+
import { ComponentSet } from '@dooboostore/dom-render';
|
|
972
|
+
|
|
973
|
+
// Define two simple components
|
|
974
|
+
class ComponentA { message = 'This is Component A'; }
|
|
975
|
+
class ComponentB { message = 'Now you see Component B'; }
|
|
976
|
+
|
|
977
|
+
class App {
|
|
978
|
+
// Create ComponentSet instances for each component
|
|
979
|
+
componentA = new ComponentSet(new ComponentA(), { template: '<h1>${@this@.message}$</h1>' });
|
|
980
|
+
componentB = new ComponentSet(new ComponentB(), { template: '<h2>${@this@.message}$</h2>' });
|
|
981
|
+
|
|
982
|
+
// This property will hold the currently active component
|
|
983
|
+
activeComponent: ComponentSet;
|
|
984
|
+
|
|
985
|
+
constructor() {
|
|
986
|
+
this.activeComponent = this.componentA;
|
|
817
987
|
}
|
|
988
|
+
|
|
989
|
+
showA() { this.activeComponent = this.componentA; }
|
|
990
|
+
showB() { this.activeComponent = this.componentB; }
|
|
818
991
|
}
|
|
819
992
|
```
|
|
993
|
+
|
|
994
|
+
```html
|
|
995
|
+
<!-- This div will dynamically render the component held by 'activeComponent' -->
|
|
996
|
+
<div dr-this="@this@.activeComponent"></div>
|
|
997
|
+
|
|
998
|
+
<button dr-event-click="@this@.showA()">Show Component A</button>
|
|
999
|
+
<button dr-event-click="@this@.showB()">Show Component B</button>
|
|
1000
|
+
```
|
|
1001
|
+
</details>
|
|
1002
|
+
|
|
1003
|
+
<details>
|
|
1004
|
+
<summary><strong><code>dr-this</code></strong>🔻(click)</summary>
|
|
1005
|
+
|
|
1006
|
+
The `dr-this` component is the target for rendering a `ComponentSet`. It dynamically renders the component instance and template defined in the `ComponentSet` object it's bound to.
|
|
1007
|
+
|
|
1008
|
+
See the `ComponentSet` example above for a practical demonstration.
|
|
1009
|
+
|
|
1010
|
+
</details>
|
|
1011
|
+
|
|
1012
|
+
<details>
|
|
1013
|
+
<summary><strong><code>dr-choose</code> / <code>dr-choose-when</code> / <code>dr-choose-other-wise</code></strong>🔻(click)</summary>
|
|
1014
|
+
|
|
1015
|
+
Provides a "switch-case" control flow for rendering blocks of HTML. It evaluates a data object and renders the first `dr-choose-when` block whose `test` condition returns true. If no `when` blocks match, the `dr-choose-other-wise` block is rendered.
|
|
1016
|
+
|
|
1017
|
+
### Usage
|
|
820
1018
|
```typescript
|
|
821
|
-
|
|
822
|
-
|
|
1019
|
+
class App {
|
|
1020
|
+
status: 'loading' | 'success' | 'error' = 'loading';
|
|
1021
|
+
}
|
|
1022
|
+
```
|
|
1023
|
+
```html
|
|
1024
|
+
<dr-choose data="${@this@.status}$">
|
|
1025
|
+
<dr-choose-when test="(status) => status === 'loading'">
|
|
1026
|
+
<p>Loading...</p>
|
|
1027
|
+
</dr-choose-when>
|
|
1028
|
+
<dr-choose-when test="(status) => status === 'success'">
|
|
1029
|
+
<p>Data loaded successfully!</p>
|
|
1030
|
+
</dr-choose-when>
|
|
1031
|
+
<dr-choose-other-wise>
|
|
1032
|
+
<p>An unknown error occurred.</p>
|
|
1033
|
+
</dr-choose-other-wise>
|
|
1034
|
+
</dr-choose>
|
|
1035
|
+
```
|
|
1036
|
+
</details>
|
|
823
1037
|
|
|
824
|
-
|
|
825
|
-
|
|
1038
|
+
<details>
|
|
1039
|
+
<summary><strong><code>dr-promise-switch</code></strong>🔻(click)</summary>
|
|
826
1040
|
|
|
827
|
-
|
|
828
|
-
console.log('routeData->', data);
|
|
829
|
-
}
|
|
1041
|
+
Declaratively handles the different states of a JavaScript `Promise`. It provides child components to render content for `pending`, `fulfilled`, and `rejected` states.
|
|
830
1042
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
1043
|
+
### Child Components
|
|
1044
|
+
- `<dr-promise-switch-pending>`: Shown while the promise is in flight.
|
|
1045
|
+
- `<dr-promise-switch-fulfilled>`: Shown when the promise resolves successfully. The resolved data is available inside via `#component#.data`.
|
|
1046
|
+
- `<dr-promise-switch-rejected>`: Shown when the promise is rejected. The error is available inside via `#component#.data`.
|
|
1047
|
+
- `<dr-promise-switch-default>`: Shown before the promise is triggered.
|
|
1048
|
+
|
|
1049
|
+
### Usage
|
|
1050
|
+
```typescript
|
|
1051
|
+
class App {
|
|
1052
|
+
userPromise = null;
|
|
1053
|
+
|
|
1054
|
+
fetchUser() {
|
|
1055
|
+
this.userPromise = fetch('/api/user').then(res => res.json());
|
|
1056
|
+
}
|
|
834
1057
|
}
|
|
835
1058
|
```
|
|
1059
|
+
```html
|
|
1060
|
+
<button dr-event-click="@this@.fetchUser()">Fetch User</button>
|
|
1061
|
+
|
|
1062
|
+
<dr-promise-switch data="${@this@.userPromise}$">
|
|
1063
|
+
<dr-promise-switch-pending>
|
|
1064
|
+
<p>Fetching user data...</p>
|
|
1065
|
+
</dr-promise-switch-pending>
|
|
1066
|
+
<dr-promise-switch-fulfilled>
|
|
1067
|
+
<p>Welcome, ${#component#.data.name}$!</p>
|
|
1068
|
+
</dr-promise-switch-fulfilled>
|
|
1069
|
+
<dr-promise-switch-rejected>
|
|
1070
|
+
<p>Failed to fetch user: ${#component#.data.message}$</p>
|
|
1071
|
+
</dr-promise-switch-rejected>
|
|
1072
|
+
</dr-promise-switch>
|
|
1073
|
+
```
|
|
1074
|
+
</details>
|
|
1075
|
+
|
|
1076
|
+
<details>
|
|
1077
|
+
<summary><strong><code>dr-checkbox</code></strong>🔻(click)</summary>
|
|
1078
|
+
|
|
1079
|
+
A wrapper for creating a custom, stylable checkbox. It uses child components to define the appearance for checked and unchecked states.
|
|
1080
|
+
|
|
1081
|
+
### Child Components
|
|
1082
|
+
- `<dr-checkbox-checked>`: Content to show when the box is checked.
|
|
1083
|
+
- `<dr-checkbox-unchecked>`: Content to show when the box is unchecked.
|
|
1084
|
+
|
|
1085
|
+
### Usage
|
|
1086
|
+
```typescript
|
|
1087
|
+
class App {
|
|
1088
|
+
agreed = false;
|
|
1089
|
+
}
|
|
1090
|
+
```
|
|
1091
|
+
```html
|
|
1092
|
+
<dr-checkbox name="terms" checked="${@this@.agreed}$" change="${(checked) => @this@.agreed = checked}$">
|
|
1093
|
+
<dr-checkbox-checked>
|
|
1094
|
+
<!-- Using FontAwesome icons as an example -->
|
|
1095
|
+
<i class="fas fa-check-square"></i> I agree to the terms.
|
|
1096
|
+
</dr-checkbox-checked>
|
|
1097
|
+
<dr-checkbox-unchecked>
|
|
1098
|
+
<i class="far fa-square"></i> I agree to the terms.
|
|
1099
|
+
</dr-checkbox-unchecked>
|
|
1100
|
+
</dr-checkbox>
|
|
1101
|
+
|
|
1102
|
+
<p>Agreed: ${@this@.agreed}$</p>
|
|
1103
|
+
```
|
|
1104
|
+
</details>
|
|
1105
|
+
|
|
1106
|
+
<details>
|
|
1107
|
+
<summary><strong><code>dr-details</code></strong>🔻(click)</summary>
|
|
1108
|
+
|
|
1109
|
+
An enhanced version of the native `<details>` element. It provides child components for the summary and body, and includes extra functionality like closing when the user clicks outside of it.
|
|
1110
|
+
|
|
1111
|
+
### Child Components
|
|
1112
|
+
- `<dr-details-summary>`: The clickable header of the details element.
|
|
1113
|
+
- `<dr-details-body>`: The collapsible content.
|
|
1114
|
+
- `<dr-details-form>`: A special body that is a form, with features like automatic reset on toggle.
|
|
1115
|
+
|
|
1116
|
+
### Usage
|
|
1117
|
+
```html
|
|
1118
|
+
<dr-details>
|
|
1119
|
+
<dr-details-summary>
|
|
1120
|
+
<h3>More Information</h3>
|
|
1121
|
+
</dr-details-summary>
|
|
1122
|
+
<dr-details-body>
|
|
1123
|
+
<p>Here is the hidden content that appears on click.</p>
|
|
1124
|
+
</dr-details-body>
|
|
1125
|
+
</dr-details>
|
|
1126
|
+
```
|
|
1127
|
+
</details>
|
|
836
1128
|
|
|
1129
|
+
<details>
|
|
1130
|
+
<summary><strong><code>dr-input</code></strong>🔻(click)</summary>
|
|
1131
|
+
|
|
1132
|
+
A custom input component that enhances a standard `<input>` with powerful features like debouncing and distinct value change detection. This is useful for performance-intensive tasks like live search.
|
|
1133
|
+
|
|
1134
|
+
### Attributes
|
|
1135
|
+
- `debounceTime`: (Optional) The time in milliseconds to wait after the user stops typing before firing the `input` event.
|
|
1136
|
+
- `distinct`: (Optional) If set to `true`, the `input` event will only fire if the new value is different from the previous one.
|
|
1137
|
+
- `input`: A callback function that receives the debounced/distinct value.
|
|
1138
|
+
|
|
1139
|
+
### Usage
|
|
837
1140
|
```typescript
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1141
|
+
class App {
|
|
1142
|
+
searchQuery = '';
|
|
1143
|
+
|
|
1144
|
+
handleSearch(query: string) {
|
|
1145
|
+
console.log('Searching for:', query);
|
|
1146
|
+
this.searchQuery = query;
|
|
1147
|
+
}
|
|
845
1148
|
}
|
|
846
1149
|
```
|
|
1150
|
+
```html
|
|
1151
|
+
<label>Search:</label>
|
|
1152
|
+
<dr-input
|
|
1153
|
+
type="text"
|
|
1154
|
+
class="search-input"
|
|
1155
|
+
debounceTime="300"
|
|
1156
|
+
distinct="true"
|
|
1157
|
+
input="${(value) => @this@.handleSearch(value)}$"
|
|
1158
|
+
></dr-input>
|
|
1159
|
+
|
|
1160
|
+
<p>Current query: ${@this@.searchQuery}$</p>
|
|
1161
|
+
```
|
|
847
1162
|
</details>
|
|
848
1163
|
|
|
849
1164
|
## Messenger (Data transmission)
|
|
@@ -908,7 +1223,7 @@ const rangeArray = new Range(100,55, 10).toArray();
|
|
|
908
1223
|
const appender = new Appender<number>([1, 2]);
|
|
909
1224
|
appender.push(3, 4)
|
|
910
1225
|
for (const data of appender) {
|
|
911
|
-
console.log('----appender item
|
|
1226
|
+
console.log('----appender item---', data);
|
|
912
1227
|
}
|
|
913
1228
|
```
|
|
914
1229
|
</details>
|
|
@@ -922,10 +1237,10 @@ for (const data of appender) {
|
|
|
922
1237
|
{
|
|
923
1238
|
name: 'dom-render'
|
|
924
1239
|
onBeforeReturnSet: (name: string, value: any, fullpath: string[]) => {
|
|
925
|
-
console.log('set name
|
|
1240
|
+
console.log('set name--', name, value, fullpath);
|
|
926
1241
|
}
|
|
927
1242
|
onBeforeReturnGet: (name: string, value: any, fullpath: string[]) => {
|
|
928
|
-
console.log('get name
|
|
1243
|
+
console.log('get name--', name, value, fullpath);
|
|
929
1244
|
}
|
|
930
1245
|
}
|
|
931
1246
|
```
|
|
@@ -1149,4 +1464,4 @@ lazy loading rollup config
|
|
|
1149
1464
|
|
|
1150
1465
|
# License
|
|
1151
1466
|
* MIT
|
|
1152
|
-
* visualkhh@gmail.com
|
|
1467
|
+
* visualkhh@gmail.com
|
|
@@ -8,27 +8,31 @@ import { OnInitRender } from '../lifecycle/OnInitRender';
|
|
|
8
8
|
import { OnDestroyRender, OnDestroyRenderParams } from '../lifecycle/OnDestroyRender';
|
|
9
9
|
import { OnDrThisUnBind } from '../lifecycle/dr-this/OnDrThisUnBind';
|
|
10
10
|
import { OnDrThisBind } from '../lifecycle/dr-this/OnDrThisBind';
|
|
11
|
-
import
|
|
11
|
+
import type { Render } from '../rawsets/Render';
|
|
12
12
|
export declare const ATTRIBUTE_METADATA_KEY: unique symbol;
|
|
13
13
|
export declare const QUERY_METADATA_KEY: unique symbol;
|
|
14
14
|
export declare const EVENT_METADATA_KEY: unique symbol;
|
|
15
15
|
export declare function attribute(options?: {
|
|
16
16
|
name?: string;
|
|
17
17
|
converter?: (value: string | null) => any;
|
|
18
|
-
}):
|
|
18
|
+
}): (target: object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => void;
|
|
19
19
|
export declare function query(selector: string): (target: object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => void;
|
|
20
20
|
export declare function event(options: {
|
|
21
21
|
query: string;
|
|
22
22
|
name: string;
|
|
23
23
|
}): MethodDecorator;
|
|
24
|
-
export
|
|
25
|
-
|
|
24
|
+
export type ComponentBaseConfig = {
|
|
25
|
+
onlyParentType?: ConstructorType<any>[] | ConstructorType<any>;
|
|
26
|
+
};
|
|
27
|
+
export declare class ComponentBase<T = any, C extends ComponentBaseConfig = ComponentBaseConfig> implements OnChangeAttrRender, OnCreateRenderData, OnCreatedThisChild, OnDrThisBind, OnDrThisUnBind, OnInitRender, OnDestroyRender {
|
|
28
|
+
private _config?;
|
|
26
29
|
private _rawSet?;
|
|
27
30
|
private _children;
|
|
28
31
|
private _render;
|
|
29
32
|
private _attribute?;
|
|
30
33
|
private _boundEventListeners;
|
|
31
|
-
get
|
|
34
|
+
get componentConfig(): C;
|
|
35
|
+
get render(): Render | undefined;
|
|
32
36
|
get rawSet(): RawSet | undefined;
|
|
33
37
|
private _queryElements;
|
|
34
38
|
private _cleanupEventListeners;
|
|
@@ -42,9 +46,7 @@ export declare abstract class ComponentBase<T> implements OnChangeAttrRender, On
|
|
|
42
46
|
getParentThis<P>(): P;
|
|
43
47
|
getChildren<C extends ConstructorType<any>>(type: C): InstanceType<C>[];
|
|
44
48
|
getChildren<C extends ConstructorType<any>[]>(types: C): InstanceType<C[number]>[];
|
|
45
|
-
constructor(
|
|
46
|
-
onlyParentType: ConstructorType<any>[] | ConstructorType<any>;
|
|
47
|
-
});
|
|
49
|
+
constructor(_config?: C);
|
|
48
50
|
private setRawSet;
|
|
49
51
|
setAttribute(attribute: T): void;
|
|
50
52
|
onCreatedThisChild(child: any, data: OnCreateRenderDataParams): void;
|
|
@@ -53,6 +55,6 @@ export declare abstract class ComponentBase<T> implements OnChangeAttrRender, On
|
|
|
53
55
|
onInitRender(param: any, rawSet: RawSet): void;
|
|
54
56
|
onDrThisBind(): void;
|
|
55
57
|
onDrThisUnBind(): void;
|
|
56
|
-
onDestroyRender(data
|
|
58
|
+
onDestroyRender(data?: OnDestroyRenderParams): void;
|
|
57
59
|
}
|
|
58
60
|
//# sourceMappingURL=ComponentBase.d.ts.map
|