@blockquote-web-components/blockquote-controller-context-meta 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -1,6 +1,102 @@
1
1
  ![Lit](https://img.shields.io/badge/lit-3.0.0-blue.svg)
2
2
 
3
- `BlockquoteControllerContextMeta` is a Lit Reactive Controller that encapsulates the controllers provided by
3
+ `BlockquoteControllerContextMeta` is a Lit Reactive Controller that encapsulates the controllers provided by [@lit/context](https://lit.dev/docs/data/context/)
4
+
5
+ **Features:**
6
+ - It enables a component to serve as both a provider and a consumer.
7
+ - It places the consumer after the first update to reduce the chance of a consumer in LightDOM requesting a context that currently lacks a provider.
8
+ - Create a context object using a global symbol (Symbol.for('my-context')).
9
+
10
+ <hr>
11
+
12
+ ### Demo
13
+
14
+ [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/oscarmarina/blockquote-web-components/tree/main/packages/controllers/blockquote-controller-context-meta)
15
+
16
+ ### Usage
17
+ - [Lit examples context-basics](https://lit.dev/playground/#sample=examples/context-basics)
18
+ ```js
19
+
20
+ import { html, LitElement, css } from 'lit';
21
+ import { BlockquoteControllerContextMeta } from '@blockquote-web-components/blockquote-controller-context-meta';
22
+
23
+ export class ProviderEl extends LitElement {
24
+ static styles = css`
25
+ slot {
26
+ display: block;
27
+ border: dashed 4px grey;
28
+ padding: 0px 10px;
29
+ }
30
+
31
+ :host {
32
+ display: block;
33
+ border: solid 4px gainsboro;
34
+ padding: 2px;
35
+ }
36
+
37
+ h3 {
38
+ margin-top: 0;
39
+ }
40
+ `;
41
+
42
+ static properties = {
43
+ data: {},
44
+ };
45
+
46
+ constructor() {
47
+ super();
48
+ this._provider = new BlockquoteControllerContextMeta(this, {
49
+ context: 'contextKey', // String used as key in Symbol.for when creating context with createContext(Symbol.for(context))
50
+ });
51
+
52
+ this.data = 'Initial';
53
+ }
54
+
55
+ // `data` will be provided to any consumer that is in the DOM tree below it.
56
+ set data(value) {
57
+ this._data = value;
58
+ this._provider.setValue(value);
59
+ }
60
+
61
+ get data() {
62
+ return this._data;
63
+ }
64
+
65
+ render() {
66
+ return html`
67
+ <h3>Provider's data: <code>${this.data}</code></h3>
68
+ <slot></slot>
69
+ `;
70
+ }
71
+ }
72
+ customElements.define('provider-el', ProviderEl);
73
+
74
+ export class ConsumerEl extends LitElement {
75
+ _consumer = new BlockquoteControllerContextMeta(this, {
76
+ context: 'contextKey', // String used as key in Symbol.for when creating context with createContext(Symbol.for(context))
77
+ callback: (v) => {
78
+ this.setAttribute('data-callback', v);
79
+ },
80
+ });
81
+
82
+
83
+ // `providedData` will be populated by the first ancestor element which
84
+ // provides a value for `context`.
85
+
86
+ get providedData() {
87
+ return this._consumer.value;
88
+ }
89
+
90
+ render() {
91
+ return html`<h3>Consumer data: <code>${this.providedData}</code></h3>
92
+ <hr />
93
+ <slot></slot>`;
94
+ }
95
+ }
96
+ customElements.define('consumer-el', ConsumerEl);
97
+ ```
98
+
99
+ <hr>
4
100
 
5
101
 
6
102
  ### `src/BlockquoteControllerContextMeta.js`:
@@ -53,11 +149,14 @@
53
149
 
54
150
  <hr>
55
151
 
56
- ### `src/BaseContextMetaElement.js`:
152
+ ![Lit](https://img.shields.io/badge/lit-3.0.0-blue.svg)
57
153
 
58
- `BaseContextMetaElement` leverages Lit's features and Context API capabilities to facilitate the creation of a component that can be used in place of a standard element, such as a `div`, thus simplifying the use of contexts.
154
+ `BaseContextMetaElement` is inspired by the concept of 'Customized Built-in Elements', focusing on extending native HTML elements like `div` using Lit's features and the Context API.
155
+ This approach simplifies the integration of context providers into a standard elements, enhancing functionality while preserving the core behavior of standard elements. **[All Structural Roles and Their HTML Equivalents](https://www.w3.org/WAI/ARIA/apg/practices/structural-roles/#allstructuralrolesandtheirhtmlequivalents)**
59
156
  > [Is it possible to make normal dom elements context providers?](https://github.com/lit/lit/discussions/4690)
60
157
 
158
+ <hr>
159
+
61
160
  ### Demo
62
161
 
63
162
  [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/oscarmarina/flow-element)
@@ -80,22 +179,26 @@ It incorporates functionality to handle context consumption and presentation as
80
179
  ];
81
180
  ```
82
181
 
83
- 2. The setConsumerContext method allows setting up a context consumer on the element. It creates a new BlockquoteControllerContextMeta if one does not already exist.
182
+ 2. The initOrGetContextProvider method allows setting up a context consumer on the element. It creates a new BlockquoteControllerContextMeta if one does not already exist.
84
183
  ```js
85
- setConsumerContext(cc = symbolContextMeta) {
86
- if (!this.controllerBaseContextMeta) {
87
- this.controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, {
88
- context: cc,
89
- });
184
+ initOrGetContextProvider(contextOrOptions = contextMetaSymbol) {
185
+ const ctx =
186
+ contextOrOptions?.context !== undefined
187
+ ? { ...contextOrOptions }
188
+ : { context: contextOrOptions };
189
+
190
+ if (!this.#controllerBaseContextMeta) {
191
+ this.#controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, ctx);
192
+ }
193
+ return this.#controllerBaseContextMeta;
90
194
  }
91
- }
92
195
  ```
93
196
 
94
197
  3. Set a default role of 'presentation' to ensure it behaves semantically like a non-interactive container.
95
198
  ```js
96
199
  connectedCallback() {
97
200
  super.connectedCallback?.();
98
- Object.assign(this, this.role ? {} : { role: 'presentation' });
201
+ Object.assign(this, { role: this.role ?? 'presentation' });
99
202
  }
100
203
  ```
101
204
 
@@ -117,12 +220,12 @@ To demonstrate the utility of BaseContextMetaElement, let's create a derived cla
117
220
  };
118
221
  ```
119
222
 
120
- 2. Set Context on Construction: The constructor calls setConsumerContext with a specific context, enabling the element to participate in the context API from its inception.
223
+ 2. Set Context on Construction: The constructor calls initOrGetContextProvider with a specific context, enabling the element to participate in the context API from its inception.
121
224
  ```js
122
225
  constructor() {
123
226
  super();
124
227
  this.surface = undefined;
125
- this.setConsumerContext(consumerContext);
228
+ this.flowController = this.initOrGetContextProvider(consumerContext);
126
229
  }
127
230
  ```
128
231
 
@@ -131,12 +234,11 @@ To demonstrate the utility of BaseContextMetaElement, let's create a derived cla
131
234
  willUpdate(props) {
132
235
  super.willUpdate?.(props);
133
236
  if (props.has('surface')) {
134
- this.controllerBaseContextMeta?.setValue(this.surface);
237
+ this.flowController?.setValue(this.surface);
135
238
  }
136
239
  }
137
240
  ```
138
241
 
139
- > __Important__: When extending BaseContextMetaElement, it is essential to use this.controllerBaseContextMeta.
140
242
 
141
243
  ### Usage Example:
142
244
  Here's how you might use the FlownElement in your HTML:
@@ -156,9 +258,19 @@ With this setup, FlownElement behaves like a [flow element](https://developer.mo
156
258
 
157
259
  ##### Methods
158
260
 
159
- | Name | Privacy | Description | Parameters | Return | Inherited From |
160
- | -------------------- | ------- | ------------------------------------------------------------------- | ------------ | ------ | -------------- |
161
- | `setConsumerContext` | | Initializes the context consumer controller if not already present. | `cc: string` | | |
261
+ | Name | Privacy | Description | Parameters | Return | Inherited From |
262
+ | -------------------------- | ------- | ------------------------------------------------------------ | ------------------------------------ | --------------------------------- | -------------- |
263
+ | `initOrGetContextProvider` | | Initializes or returns the existing context meta controller. | `contextOrOptions: string \| Object` | `BlockquoteControllerContextMeta` | |
264
+
265
+ <details><summary>Private API</summary>
266
+
267
+ ##### Fields
268
+
269
+ | Name | Privacy | Type | Default | Description | Inherited From |
270
+ | ---------------------------- | ------- | ---------------------------------------------- | ----------- | --------------------------------------- | -------------- |
271
+ | `#controllerBaseContextMeta` | private | `BlockquoteControllerContextMeta \| undefined` | `undefined` | Stores the context controller instance. | |
272
+
273
+ </details>
162
274
 
163
275
  <hr/>
164
276
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockquote-web-components/blockquote-controller-context-meta",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Webcomponent blockquote-controller-context-meta following open-wc recommendations",
5
5
  "keywords": [
6
6
  "lit",
@@ -97,11 +97,11 @@
97
97
  },
98
98
  "devDependencies": {
99
99
  "@blockquote-web-components/blockquote-base-common-dev-dependencies": "^1.9.1",
100
- "@blockquote-web-components/blockquote-base-embedded-webview": "^1.11.0"
100
+ "@blockquote-web-components/blockquote-base-embedded-webview": "^1.11.1"
101
101
  },
102
102
  "publishConfig": {
103
103
  "access": "public"
104
104
  },
105
105
  "customElements": "custom-elements.json",
106
- "gitHead": "469697a8884101a339360276153f36bd844a50b1"
106
+ "gitHead": "6fe48d5f8dc077b549d3c11ab3541a0a1fe84d58"
107
107
  }
@@ -4,9 +4,14 @@ import {
4
4
  contextMetaSymbol,
5
5
  } from './BlockquoteControllerContextMeta.js';
6
6
  /**
7
- * `BaseContextMetaElement` leverages Lit's features and Context API capabilities to facilitate the creation of a component that can be used in place of a standard element, such as a `div`, thus simplifying the use of contexts.
7
+ * ![Lit](https://img.shields.io/badge/lit-3.0.0-blue.svg)
8
+ *
9
+ * `BaseContextMetaElement` is inspired by the concept of 'Customized Built-in Elements', focusing on extending native HTML elements like `div` using Lit's features and the Context API.
10
+ * This approach simplifies the integration of context providers into a standard elements, enhancing functionality while preserving the core behavior of standard elements. **[All Structural Roles and Their HTML Equivalents](https://www.w3.org/WAI/ARIA/apg/practices/structural-roles/#allstructuralrolesandtheirhtmlequivalents)**
8
11
  * > [Is it possible to make normal dom elements context providers?](https://github.com/lit/lit/discussions/4690)
9
12
  *
13
+ * <hr>
14
+ *
10
15
  * ### Demo
11
16
  *
12
17
  * [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/oscarmarina/flow-element)
@@ -29,22 +34,26 @@ import {
29
34
  * ];
30
35
  * ```
31
36
  *
32
- * 2. The setConsumerContext method allows setting up a context consumer on the element. It creates a new BlockquoteControllerContextMeta if one does not already exist.
37
+ * 2. The initOrGetContextProvider method allows setting up a context consumer on the element. It creates a new BlockquoteControllerContextMeta if one does not already exist.
33
38
  * ```js
34
- * setConsumerContext(cc = symbolContextMeta) {
35
- * if (!this.controllerBaseContextMeta) {
36
- * this.controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, {
37
- * context: cc,
38
- * });
39
+ * initOrGetContextProvider(contextOrOptions = contextMetaSymbol) {
40
+ * const ctx =
41
+ * contextOrOptions?.context !== undefined
42
+ * ? { ...contextOrOptions }
43
+ * : { context: contextOrOptions };
44
+ *
45
+ * if (!this.#controllerBaseContextMeta) {
46
+ * this.#controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, ctx);
47
+ * }
48
+ * return this.#controllerBaseContextMeta;
39
49
  * }
40
- * }
41
50
  * ```
42
51
  *
43
52
  * 3. Set a default role of 'presentation' to ensure it behaves semantically like a non-interactive container.
44
53
  * ```js
45
54
  * connectedCallback() {
46
55
  * super.connectedCallback?.();
47
- * Object.assign(this, this.role ? {} : { role: 'presentation' });
56
+ * Object.assign(this, { role: this.role ?? 'presentation' });
48
57
  * }
49
58
  * ```
50
59
  *
@@ -66,12 +75,12 @@ import {
66
75
  * };
67
76
  * ```
68
77
  *
69
- * 2. Set Context on Construction: The constructor calls setConsumerContext with a specific context, enabling the element to participate in the context API from its inception.
78
+ * 2. Set Context on Construction: The constructor calls initOrGetContextProvider with a specific context, enabling the element to participate in the context API from its inception.
70
79
  * ```js
71
80
  * constructor() {
72
81
  * super();
73
82
  * this.surface = undefined;
74
- * this.setConsumerContext(consumerContext);
83
+ * this.flowController = this.initOrGetContextProvider(consumerContext);
75
84
  * }
76
85
  * ```
77
86
  *
@@ -80,12 +89,11 @@ import {
80
89
  * willUpdate(props) {
81
90
  * super.willUpdate?.(props);
82
91
  * if (props.has('surface')) {
83
- * this.controllerBaseContextMeta?.setValue(this.surface);
92
+ * this.flowController?.setValue(this.surface);
84
93
  * }
85
94
  * }
86
95
  * ```
87
96
  *
88
- * > __Important__: When extending BaseContextMetaElement, it is essential to use this.controllerBaseContextMeta.
89
97
  *
90
98
  * ### Usage Example:
91
99
  * Here's how you might use the FlownElement in your HTML:
@@ -99,6 +107,12 @@ import {
99
107
  * With this setup, FlownElement behaves like a [flow element](https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#flow_content) but provides the additional benefit of context management via Lit's context API, allowing you to seamlessly integrate context-sensitive behavior without altering the parent element hierarchy.
100
108
  */
101
109
  export class BaseContextMetaElement extends LitElement {
110
+ /**
111
+ * Stores the context controller instance.
112
+ * @type {BlockquoteControllerContextMeta | undefined}
113
+ */
114
+ #controllerBaseContextMeta = undefined;
115
+
102
116
  static styles = [
103
117
  css`
104
118
  :host {
@@ -112,20 +126,25 @@ export class BaseContextMetaElement extends LitElement {
112
126
  ];
113
127
 
114
128
  /**
115
- * Initializes the context consumer controller if not already present.
116
- * @param {string} [cc=contextMetaSymbol] - context name.
129
+ * Initializes or returns the existing context meta controller.
130
+ * @param {string | Object} [contextOrOptions=contextMetaSymbol] - context name.
131
+ * @returns {BlockquoteControllerContextMeta} The instance of the context meta.
117
132
  */
118
- setConsumerContext(cc = contextMetaSymbol) {
119
- if (!this.controllerBaseContextMeta) {
120
- this.controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, {
121
- context: cc,
122
- });
133
+ initOrGetContextProvider(contextOrOptions = contextMetaSymbol) {
134
+ const ctx =
135
+ contextOrOptions?.context !== undefined
136
+ ? { ...contextOrOptions }
137
+ : { context: contextOrOptions };
138
+
139
+ if (!this.#controllerBaseContextMeta) {
140
+ this.#controllerBaseContextMeta = new BlockquoteControllerContextMeta(this, ctx);
123
141
  }
142
+ return this.#controllerBaseContextMeta;
124
143
  }
125
144
 
126
145
  connectedCallback() {
127
146
  super.connectedCallback?.();
128
- Object.assign(this, this.role ? {} : { role: 'presentation' });
147
+ Object.assign(this, { role: this.role ?? 'presentation' });
129
148
  }
130
149
 
131
150
  render() {
@@ -4,7 +4,7 @@ export const contextMetaSymbol = 'context-meta-symbol';
4
4
  /**
5
5
  * ![Lit](https://img.shields.io/badge/lit-3.0.0-blue.svg)
6
6
  *
7
- * `BlockquoteControllerContextMeta` is a Lit Reactive Controller that encapsulates the controllers provided by @lit/context.
7
+ * `BlockquoteControllerContextMeta` is a Lit Reactive Controller that encapsulates the controllers provided by [@lit/context](https://lit.dev/docs/data/context/)
8
8
  *
9
9
  * **Features:**
10
10
  * - It enables a component to serve as both a provider and a consumer.