@startinblox/core 0.19.18 → 0.19.20

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 (3) hide show
  1. package/README.md +29 -29
  2. package/dist/index.js +71 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Getting started
2
2
 
3
- > Please before to start, check [our contribution guidelines](https://git.startinblox.com/documentation/doc/wikis/Contribution-guidelines):)
3
+ > Before you begin, please review [our contribution guidelines](https://git.startinblox.com/documentation/doc/wikis/Contribution-guidelines):)
4
4
 
5
- This documentation is for developers who would like to contribute to the core of the framework.
5
+ This documentation is intended for developers who wish to contribute to the core of the framework.
6
6
 
7
- **If you just want to use the framework, please refer to [the general documentation](https://docs.startinblox.com).**
7
+ **If you are looking to use the framework, please refer to [the general documentation](https://docs.startinblox.com).**
8
8
 
9
9
  ## Installation
10
10
  To start developing in `sib-core`, you need:
@@ -22,7 +22,7 @@ npm run serve
22
22
  You can now see examples at [http://127.0.0.1:3000](http://127.0.0.1:3000/).
23
23
 
24
24
  ## Adding new features
25
- To develop new features of `sib-core`, you can add an HTML example file in `/examples` and link it in `/index.html`.
25
+ To develop new features for `sib-core`, you can add an HTML example file in `/examples` directory and link it in `/index.html`.
26
26
  Don't forget to import the framework:
27
27
 
28
28
  ```html
@@ -31,7 +31,7 @@ Don't forget to import the framework:
31
31
  You can now write HTML using `sib-core` and test it in your browser.
32
32
 
33
33
 
34
- ## Test
34
+ ## Testing
35
35
  You can test the API by running:
36
36
  ```shell
37
37
  npm run test
@@ -49,7 +49,7 @@ Here is a simplified schema of how the API works to create a component:
49
49
  return 'string';
50
50
  }
51
51
  ```
52
- The static getter "name" return a string that will be used to register the component tag name or the mixin name. This getter is required.
52
+ The static `name` getter returns a string that will be used to register the component tag name or the mixin name. This getter is required.
53
53
 
54
54
  ## Install mixins
55
55
  ```js
@@ -58,7 +58,7 @@ The static getter "name" return a string that will be used to register the compo
58
58
  }
59
59
  ```
60
60
 
61
- The static getter "use" return an array of mixins to install. The mixin compositor install mixin recursively.
61
+ The static `use` getter return an array of mixins to install. The mixin compositor install mixin recursively.
62
62
 
63
63
  ## Declare attributes
64
64
  ```js
@@ -76,9 +76,9 @@ The static getter "use" return an array of mixins to install. The mixin composit
76
76
  }
77
77
  ```
78
78
 
79
- To declare an attribute, you should use the static getter "attributes". It should return an object. Each property will be bind with kebab case equivalent. Example: 'myProp' is bound to 'my-prop'. Each property should be an object with :
79
+ To declare an attribute, use the static `attributes` getter. It should return an object where each property will be bound with its kebab-case equivalent. Example: `myProp` is bound to `my-prop`. Each property should be an object with the following :
80
80
  - type
81
- - description: The js type of your attribute data
81
+ - description: The JavaScript type of your attribute data
82
82
  - required: false
83
83
  - default: String
84
84
  - default
@@ -86,15 +86,15 @@ To declare an attribute, you should use the static getter "attributes". It shoul
86
86
  - required: false
87
87
  - default: undefined
88
88
  - required
89
- - description: Is this attribute required, if true, throw an Error if not provided
89
+ - description: Indicates if this attribute required. If `true`, an error is thrown if not provided
90
90
  - required: false
91
91
  - default: false
92
92
  - callback
93
- - description: A function that will be invoke when the attribute changed. It receive 2 arguments : newValue, oldValue.
93
+ - description: A function invoked when the attribute changed. It receives 2 arguments : `newValue`, `oldValue`.
94
94
  - required: false
95
95
  - default: undefined
96
96
 
97
- The mixin compositor register all attribute recursively. The last declaration is keeped.
97
+ The mixin compositor registers all attribute recursively, keeping the last declaration.
98
98
 
99
99
  ## Declare initial state
100
100
  ```js
@@ -104,7 +104,8 @@ The mixin compositor register all attribute recursively. The last declaration is
104
104
  };
105
105
  }
106
106
  ```
107
- The static getter initialState should return an object that contains initial state of the component. The mixin compositor merge recursively the initial state. Last declaration is keeped.
107
+ The static `initialState`` getter should return an object containing the initial state of the component. The mixin compositor recursively merges the initial state, ensuring that the last declaration is preserved.
108
+
108
109
  Every property in the initial state could be watched by the component in order to provide reactivity.
109
110
 
110
111
 
@@ -119,7 +120,7 @@ Available hook:
119
120
  - attached
120
121
  - detached
121
122
 
122
- Each hook is a function. The mixin compositor *append* hooks. If a deeper mixin register a created hook, its function will be called before the current created hook.
123
+ Each hook is a function. The mixin compositor *appends* hooks. If a deeper mixin registers a created hook, its function will be called before the current created hook.
123
124
 
124
125
  ## Declare methods
125
126
  ```js
@@ -127,48 +128,47 @@ Each hook is a function. The mixin compositor *append* hooks. If a deeper mixin
127
128
  console.log('Hi!');
128
129
  }
129
130
  ```
130
- In order to declare methods, you just add a method to your mixin. The mixin compositor keep the last method declared.
131
+ To declare methods, simply add a method to your mixin. The mixin compositor retains the last declared method.
131
132
 
132
133
  # Core Architecture
133
- Here is a simplified schema of the organization and the responsibilities of the classes of the core:
134
+ Here is a simplified schema of the organization and the responsibilities of the classes of the core classes:
134
135
  ![core-architecture](./images-documentation/core-architecture.png)
135
136
 
136
137
  ## List post-processing
137
- A `solid-display` component is capable of showing a list of resources and applying different filters on this list to filter, sort, group... resources. Here is a schema of the order of these transformations:
138
+ A `solid-display` component can show a list of resources and apply various filters to sort, group, and otherwise transform these resources. Below is a schema illustrating the sequence of these transformations:
138
139
  ![list-post-processing](./images-documentation/list-post-processing.png)
139
140
 
140
141
  # Widgets API
141
- A widget is a small component responsible for a value. The widget is composed and built on demand when the developer ask for it.
142
- To do that, the name of the widget is splitted and analyzed to add the right mixins. Here is a schema of how it works:
142
+ A widget is a small component responsible for managing a value. Widgets are composed and built on demand when the developer requests them. The widget name is parsed and analyzed to add the appropriate mixins. Here is a schema showing how this process works:
143
143
 
144
144
  ![widget-api](./images-documentation/widget-api.png)
145
145
 
146
146
  ## Values
147
- Values are given to a widget through its `value` attribute. For the widgets defined by sib-core, it can have different types:
148
- - `string`: most common and encouraged use case
149
- - `boolean` (checkbox): is converted to string (`'true'` or `'false'`)
150
- - `number` (input number): is converted to string
151
- - `container` (multiple, multiple form): is converted to `@id` and resolved by the widget
147
+ Values are provided to a widget through its `value` attribute. For the widgets defined by sib-core, the value can have different types:
148
+ - `string`: This is the most common and encouraged use case
149
+ - `boolean` (checkbox): The value is converted to string (`'true'` or `'false'`)
150
+ - `number` (input number): The value is converted to a string
151
+ - `container` (multiple, multiple form): The value is converted to `@id` and resolved by the widget
152
152
 
153
- As custom widgets still use the old API, you can give them these types:
153
+ Custom widgets, which still use the old API, can accept the following types:
154
154
  - `string`
155
155
  - `resource` Proxy
156
156
  - `container` Proxy
157
157
 
158
- ### Get the values
159
- With the display widgets, you can get the value through its HTML attribute:
158
+ ### Getting Values
159
+ With display widgets, you can retrieve the value through its HTML attribute:
160
160
  ```js
161
161
  const value = widgetElement.getAttribute('value');
162
162
  // or thanks to the core API
163
163
  const value = widgetElement.component.value;
164
164
  ```
165
165
 
166
- In the form widgets, the value can be changed by the user. If you need to retrieve it, proceed like this:
166
+ For form widgets, where the value can be changed by the user, you can retrieve it as follows:
167
167
  ```js
168
168
  const value = widgetElement.component.getValue();
169
169
  ```
170
170
 
171
- Under the hood, the core finds elements which have a `data-holder` attribute, and get the value from their properties, instead of their attribute (where you would have the initial value of the widget).
171
+ Under the hood, the core locates elements with a `data-holder`` attribute and retrieves the value from their properties, rather than their attributes, which hold the initial value of the widget.
172
172
 
173
173
  A widget can have:
174
174
  - 1 `data-holder` element (simple inputs)
package/dist/index.js CHANGED
@@ -50921,6 +50921,9 @@ const RichtextMixin = {
50921
50921
  this.quill = null;
50922
50922
  this.listCallbacks.push(this.addCallback.bind(this));
50923
50923
  },
50924
+ getPlaceHolderValue() {
50925
+ return this.element.hasAttribute("placeholder") ? this.element.getAttribute("placeholder") : "";
50926
+ },
50924
50927
  addCallback(value, listCallbacks) {
50925
50928
  if (this.quill == null) {
50926
50929
  var toolbarOptions = [
@@ -50932,16 +50935,80 @@ const RichtextMixin = {
50932
50935
  ["clean"]
50933
50936
  ];
50934
50937
  const richtext = this.element.querySelector("[data-richtext]");
50935
- this.quill = new Quill(richtext, {
50936
- modules: { toolbar: toolbarOptions },
50937
- theme: "snow"
50938
- });
50938
+ this.quill = new Quill(
50939
+ richtext,
50940
+ {
50941
+ modules: { toolbar: toolbarOptions },
50942
+ placeholder: this.getPlaceHolderValue(),
50943
+ theme: "snow"
50944
+ }
50945
+ );
50939
50946
  }
50940
50947
  const ops = deltaMd.toDelta(this.value);
50941
50948
  this.quill.setContents(ops);
50949
+ if (this.isRequired()) {
50950
+ this.createHiddenRequiredInput();
50951
+ this.quill.on("text-change", this.onTextChange.bind(this));
50952
+ }
50942
50953
  const nextProcessor = listCallbacks.shift();
50943
50954
  if (nextProcessor)
50944
50955
  nextProcessor(value, listCallbacks);
50956
+ },
50957
+ isRequired() {
50958
+ return Array.from(this.element.attributes).some((attr) => attr.name === "required");
50959
+ },
50960
+ createHiddenRequiredInput() {
50961
+ const attributeName = this.getAttributeValue("name");
50962
+ this.hiddenInput = document.querySelector(`input[name="${attributeName + "-hidden"}"]`);
50963
+ if (!this.hiddenInput) {
50964
+ this.hiddenInput = this.createHiddenInput(attributeName + "-hidden");
50965
+ this.element.appendChild(this.hiddenInput);
50966
+ this.addInvalidEventListener();
50967
+ }
50968
+ this.hiddenInput.value = this.quill.getText();
50969
+ },
50970
+ createHiddenInput(attributeName) {
50971
+ const input = document.createElement("input");
50972
+ input.name = attributeName;
50973
+ input.setAttribute("required", "true");
50974
+ input.style.opacity = "0";
50975
+ input.style.position = "absolute";
50976
+ input.style.pointerEvents = "none";
50977
+ return input;
50978
+ },
50979
+ getAttributeValue(attributeName) {
50980
+ const attribute2 = Array.from(this.element.attributes).find((attr) => attr.name === attributeName);
50981
+ return attribute2 ? attribute2.value : "";
50982
+ },
50983
+ displayCustomErrorMessage(message) {
50984
+ const richtext = this.element.querySelector("[data-richtext]");
50985
+ if (richtext) {
50986
+ let errorMessageElement = richtext.querySelector(".required-error-message");
50987
+ if (!errorMessageElement) {
50988
+ errorMessageElement = document.createElement("div");
50989
+ errorMessageElement.className = "required-error-message";
50990
+ }
50991
+ richtext.appendChild(errorMessageElement);
50992
+ errorMessageElement.textContent = message;
50993
+ richtext.classList.add("error-border-richtext");
50994
+ }
50995
+ },
50996
+ addInvalidEventListener() {
50997
+ this.hiddenInput.addEventListener("invalid", (e) => {
50998
+ e.preventDefault();
50999
+ this.displayCustomErrorMessage("Please fill out this field.");
51000
+ });
51001
+ },
51002
+ onTextChange() {
51003
+ this.hiddenInput.value = this.quill.getText();
51004
+ this.removeErrorMessageAndStyling();
51005
+ },
51006
+ removeErrorMessageAndStyling() {
51007
+ const richtext = this.element.querySelector("[data-richtext]");
51008
+ let errorMessageElement = richtext.querySelector(".required-error-message");
51009
+ if (errorMessageElement)
51010
+ errorMessageElement.remove();
51011
+ richtext.classList.remove("error-border-richtext");
50945
51012
  }
50946
51013
  };
50947
51014
  const callbackDirectory = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startinblox/core",
3
- "version": "0.19.18",
3
+ "version": "0.19.20",
4
4
  "description": "This is a series of web component respecting both the web components standards and the Linked Data Platform convention.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",