@startinblox/boilerplate 4.2.2 → 4.3.1

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/.gitlab-ci.yml CHANGED
@@ -14,7 +14,7 @@ default:
14
14
 
15
15
  stages:
16
16
  - prepare
17
- # - test
17
+ - test
18
18
  - publish
19
19
 
20
20
  prepare:
@@ -31,23 +31,22 @@ prepare:
31
31
  paths:
32
32
  - dist
33
33
  expire_in: 1 day
34
- # tags:
35
- # - test
34
+ tags:
35
+ - test
36
36
 
37
- # Temp: https://github.com/cypress-io/cypress/issues/31882
38
- # test:
39
- # stage: test
40
- # image:
41
- # name: cypress/included:14.2.0
42
- # entrypoint: [""]
43
- # before_script:
44
- # - npm ci --cache .npm --prefer-offline
45
- # script:
46
- # - npm run cy:run
47
- # except:
48
- # - tags
49
- # tags:
50
- # - test
37
+ test:
38
+ stage: test
39
+ image:
40
+ name: cypress/included:15.5.0
41
+ entrypoint: [""]
42
+ before_script:
43
+ - npm ci --cache .npm --prefer-offline
44
+ script:
45
+ - npm run cy:run
46
+ except:
47
+ - tags
48
+ tags:
49
+ - test
51
50
 
52
51
  publish:
53
52
  stage: publish
@@ -7,6 +7,10 @@ const config: StorybookConfig = {
7
7
  framework: {
8
8
  name: "@storybook/web-components-vite",
9
9
  options: {},
10
+ },
11
+
12
+ core: {
13
+ disableTelemetry: true,
10
14
  }
11
15
  };
12
16
 
package/README.md CHANGED
@@ -2,48 +2,57 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- This repository provides a boilerplate for developing Startin'blox web components. It streamlines the creation and deployment of web components, whether used independently or integrated with the Startin'blox ecosystem, including Lit, Startin'blox Core, Startin'blox Store, Startin'blox Router, and Startin'blox Orbit. The primary objective is to enable developers to concentrate on web component logic by abstracting common complexities and providing out-of-the-box functionalities.
5
+ This repository provides a boilerplate for developing Startin'blox web components. It streamlines the creation and deployment of web components, whether used standalone or integrated within the Startin'blox ecosystem (Lit, Startin'blox Core, Store, Router, and Orbit). The primary objective is to enable developers to concentrate on web component logic by abstracting common complexities and providing essential functionalities out-of-the-box.
6
6
 
7
7
  ## Features
8
8
 
9
9
  This boilerplate includes:
10
10
 
11
- * **Localization:** Compatibility with platforms like Weblate, powered by [`@lit/localize`](https://www.npmjs.com/package/@lit/localize).
11
+ * **Localization:** Supports internationalization with platforms like Weblate, powered by [`@lit/localize`](https://www.npmjs.com/package/@lit/localize).
12
12
  * **Data Management:** A comprehensive wrapper around the Startin'blox Store for simplified property handling (RDF or named).
13
13
  * **Component Awareness:** Mechanisms to manage race conditions and inheritance across external components.
14
14
  * **Helper Utilities:** Functions for data reactivity, filtering, and sorting.
15
15
  * **Development Tools:**
16
- * **Storybook:** For component documentation and isolated development, reducing the need for a heavy local environment.
16
+ * **Storybook:** For isolated component development and documentation, reducing the need for a heavy local environment.
17
17
  * **Cypress:** For component testing.
18
18
  * **Unpluggin Icons:** Access to a vast library of icons from [Iconify](https://icon-sets.iconify.design/).
19
19
  * **Lit Integration:** Pre-made component classes to accelerate development.
20
- * **Vite-powered:** Typescript, SASS, PostCSS, Autoprefixer... Focus on your component logic, not the build process.
21
- * **BiomeJS:** For linting and formatting, preconfigured for Startin'blox JS styling, using the most [reasonable one](https://github.com/airbnb/javascript). Use [Biome](https://biomejs.dev/fr/) within your preferred editor.
20
+ * **Vite-powered:** Typescript, SASS, PostCSS and Autoprefixer, allowing you to focus on component logic rather than build configurations.
21
+ * **BiomeJS:** Preconfigured for Startin'blox JS styling, using the most [reasonable one](https://github.com/airbnb/javascript), for linting and formatting. Integrate [Biome](https://biomejs.dev/fr/) with your preferred editor.
22
22
 
23
- ## Getting started
23
+ ## Quick Start for Developers
24
24
 
25
- ### Creating a new components repository
25
+ This section guides you through setting up the local development environment and using the boilerplate to create and test web components.
26
26
 
27
- To initialize a new component repository from this boilerplate:
27
+ ### Local Development Setup
28
+
29
+ To get started with local development:
28
30
 
29
- 1. Clone this repository.
30
- 2. Rename the `origin` remote to `upstream`:
31
+ 1. **Clone the repository:**
31
32
 
32
33
  ```bash
33
- git remote rename origin upstream
34
+ git clone https://git.startinblox.com/components/your-component-name.git
35
+ cd your-component-name
34
36
  ```
35
37
 
36
- 3. Update the `name`, `description`, and `repository.url` fields in [`package.json`](package.json).
37
- 4. Commit the changes with a `major: Initial commit` message.
38
- 5. Create a new repository on [git.startinblox.com/components](https://git.startinblox.com/components/).
39
- 6. Add the new repository as the `origin` remote:
38
+ *Note: If you are starting a new project from this boilerplate, refer to the "Developping new components from the boilerplate" section below.*
39
+
40
+ 2. **Install dependencies:**
40
41
 
41
42
  ```bash
42
- git remote add origin https://git.startinblox.com/components/your-component-name.git
43
+ npm install
43
44
  ```
44
45
 
45
- 7. Configure Gitlab settings (branch protection rules, FF merge only, clone instead of fetch).
46
- 8. Push to `origin master`.
46
+ 3. **Run Storybook:**
47
+ Storybook is the primary development environment for isolated component development and documentation.
48
+
49
+ ```bash
50
+ npm run storybook
51
+ ```
52
+
53
+ This will open Storybook in your browser, typically at `http://localhost:6006`.
54
+
55
+ ### Using Your Components
47
56
 
48
57
  For production usage, components can be served via a CDN like JSDelivr or self-hosted.
49
58
 
@@ -60,18 +69,58 @@ For production usage, components can be served via a CDN like JSDelivr or self-h
60
69
  <!-- etc. -->
61
70
  ```
62
71
 
63
- ### Installation
72
+ ## Developping new components from the boilerplate
64
73
 
65
- To set up the local development environment with Storybook:
74
+ ### Creating a New Component Repository
66
75
 
67
- ```bash
68
- npm install
69
- npm run storybook
70
- ```
76
+ To initialize a new component repository from this boilerplate:
77
+
78
+ 1. **Clone this repository:**
79
+
80
+ ```bash
81
+ git clone https://git.startinblox.com/components/solid-boilerplate.git your-new-component-name
82
+ cd your-new-component-name
83
+ ```
71
84
 
72
- ## Development environment
85
+ 2. **Rename the `origin` remote to `upstream`:**
73
86
 
74
- This boilerplate is designed as a **library** for multiple web components and intentionally **does not include** a default `index.html` file.
87
+ ```bash
88
+ git remote rename origin upstream
89
+ ```
90
+
91
+ 3. **Update project details:**
92
+ Modify the `name`, `description`, and `repository.url` fields in [`package.json`](package.json) to reflect your new component.
93
+
94
+ 4. **Initial commit:**
95
+ Commit the changes with a `major: Initial commit` message.
96
+
97
+ 5. **Create a new repository:**
98
+ Create a new repository on [git.startinblox.com/components](https://git.startinblox.com/components/).
99
+
100
+ 6. **Add the new repository as the `origin` remote:**
101
+
102
+ ```bash
103
+ git remote add origin https://git.startinblox.com/components/your-component-name.git
104
+ ```
105
+
106
+ 7. **Configure Gitlab settings:**
107
+ Set up branch protection rules, enforce FF merge only, and configure cloning instead of fetching in your new repository's Gitlab settings.
108
+
109
+ 8. **Push to `origin master`:**
110
+
111
+ ```bash
112
+ git push -u origin master
113
+ ```
114
+
115
+ ## Important Considerations
116
+
117
+ This boilerplate is designed as a **library** for multiple web components and intentionally **does not include** a default `index.html` file. Developers should use Storybook for isolated component development.
118
+
119
+ * **Avoid Blind Copy-Pasting:** Do not simply copy files without understanding their purpose. This boilerplate includes specific configurations and integrations (e.g., Orbit, localization) that may not be relevant to all projects. Always review and adapt the code to your specific needs.
120
+ * **Understand Core Concepts:** Familiarize yourself with the "Core Concepts" section to understand how data management, component awareness, and helper utilities are implemented.
121
+ * **Orbit Integration:** The `import @src/initializer;` statement is **only required if your component will be integrated with Startin'blox Orbit**. If you are not using Orbit, you **do not need** this import.
122
+
123
+ ## Development Environment
75
124
 
76
125
  **Storybook** is the primary development environment for isolated component development and documentation. **Cypress** is integrated for component testing.
77
126
 
@@ -236,15 +285,13 @@ npm run build-storybook
236
285
  npm run build
237
286
  ```
238
287
 
239
- ## Orbit integration
288
+ ## Orbit Integration
240
289
 
241
290
  Components built with this boilerplate are designed to work seamlessly with Orbit without requiring specific configurations.
242
291
 
243
- To prevent potential race conditions, include `import @src/initializer;` at the top of your component's file, before the `@customElement` declaration.
244
-
245
- Application performance can be optimized by utilizing the `gatekeeper` method within your `OrbitComponent`'s render methods.
246
-
247
- Note that without a complete Orbit environment, interactions with external components (e.g., route management, component deduplication, global localization, conditional component display) may be limited.
292
+ * **Initializer:** To prevent potential race conditions when integrating with Orbit, include `import @src/initializer;` at the top of your component's file, before the `@customElement` declaration. **This import is only necessary if your component will be used within an Orbit environment.**
293
+ * **Performance Optimization:** Application performance can be optimized by utilizing the `gatekeeper` method within your `OrbitComponent`'s render methods.
294
+ * **Limitations without Orbit:** Without a complete Orbit environment, interactions with external components (e.g., route management, component deduplication, global localization, conditional component display) may be limited.
248
295
 
249
296
  ## Best practices
250
297
 
package/dist/index.js CHANGED
@@ -23,14 +23,14 @@ let Ct = class {
23
23
  }
24
24
  };
25
25
  const it = (s) => new Ct(typeof s == "string" ? s : s + "", void 0, st), rt = (s, ...t) => {
26
- const e = s.length === 1 ? s[0] : t.reduce((r, i, o) => r + ((n) => {
26
+ const e = s.length === 1 ? s[0] : t.reduce(((r, i, o) => r + ((n) => {
27
27
  if (n._$cssResult$ === !0) return n.cssText;
28
28
  if (typeof n == "number") return n;
29
29
  throw Error("Value passed to 'css' function must be a 'css' function result: " + n + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.");
30
- })(i) + s[o + 1], s[0]);
30
+ })(i) + s[o + 1]), s[0]);
31
31
  return new Ct(e, s, st);
32
32
  }, Vt = (s, t) => {
33
- if (et) s.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet);
33
+ if (et) s.adoptedStyleSheets = t.map(((e) => e instanceof CSSStyleSheet ? e : e.styleSheet));
34
34
  else for (const e of t) {
35
35
  const r = document.createElement("style"), i = N.litNonce;
36
36
  i !== void 0 && r.setAttribute("nonce", i), r.textContent = e.cssText, s.appendChild(r);
@@ -141,7 +141,7 @@ let E = class extends HTMLElement {
141
141
  super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev();
142
142
  }
143
143
  _$Ev() {
144
- this._$ES = new Promise((t) => this.enableUpdating = t), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t) => t(this));
144
+ this._$ES = new Promise(((t) => this.enableUpdating = t)), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach(((t) => t(this)));
145
145
  }
146
146
  addController(t) {
147
147
  (this._$EO ??= /* @__PURE__ */ new Set()).add(t), this.renderRoot !== void 0 && this.isConnected && t.hostConnected?.();
@@ -159,12 +159,12 @@ let E = class extends HTMLElement {
159
159
  return Vt(t, this.constructor.elementStyles), t;
160
160
  }
161
161
  connectedCallback() {
162
- this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((t) => t.hostConnected?.());
162
+ this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach(((t) => t.hostConnected?.()));
163
163
  }
164
164
  enableUpdating(t) {
165
165
  }
166
166
  disconnectedCallback() {
167
- this._$EO?.forEach((t) => t.hostDisconnected?.());
167
+ this._$EO?.forEach(((t) => t.hostDisconnected?.()));
168
168
  }
169
169
  attributeChangedCallback(t, e, r) {
170
170
  this._$AK(t, r);
@@ -180,7 +180,9 @@ let E = class extends HTMLElement {
180
180
  const r = this.constructor, i = r._$Eh.get(t);
181
181
  if (i !== void 0 && this._$Em !== i) {
182
182
  const o = r.getPropertyOptions(i), n = typeof o.converter == "function" ? { fromAttribute: o.converter } : o.converter?.fromAttribute !== void 0 ? o.converter : D;
183
- this._$Em = i, this[i] = n.fromAttribute(e, o.type) ?? this._$Ej?.get(i) ?? null, this._$Em = null;
183
+ this._$Em = i;
184
+ const h = n.fromAttribute(e, o.type);
185
+ this[i] = h ?? this._$Ej?.get(i) ?? h, this._$Em = null;
184
186
  }
185
187
  }
186
188
  requestUpdate(t, e, r) {
@@ -223,7 +225,7 @@ let E = class extends HTMLElement {
223
225
  let t = !1;
224
226
  const e = this._$AL;
225
227
  try {
226
- t = this.shouldUpdate(e), t ? (this.willUpdate(e), this._$EO?.forEach((r) => r.hostUpdate?.()), this.update(e)) : this._$EM();
228
+ t = this.shouldUpdate(e), t ? (this.willUpdate(e), this._$EO?.forEach(((r) => r.hostUpdate?.())), this.update(e)) : this._$EM();
227
229
  } catch (r) {
228
230
  throw t = !1, this._$EM(), r;
229
231
  }
@@ -232,7 +234,7 @@ let E = class extends HTMLElement {
232
234
  willUpdate(t) {
233
235
  }
234
236
  _$AE(t) {
235
- this._$EO?.forEach((e) => e.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);
237
+ this._$EO?.forEach(((e) => e.hostUpdated?.())), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);
236
238
  }
237
239
  _$EM() {
238
240
  this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1;
@@ -247,14 +249,14 @@ let E = class extends HTMLElement {
247
249
  return !0;
248
250
  }
249
251
  update(t) {
250
- this._$Eq &&= this._$Eq.forEach((e) => this._$ET(e, this[e])), this._$EM();
252
+ this._$Eq &&= this._$Eq.forEach(((e) => this._$ET(e, this[e]))), this._$EM();
251
253
  }
252
254
  updated(t) {
253
255
  }
254
256
  firstUpdated(t) {
255
257
  }
256
258
  };
257
- E.elementStyles = [], E.shadowRootOptions = { mode: "open" }, E[O("elementProperties")] = /* @__PURE__ */ new Map(), E[O("finalized")] = /* @__PURE__ */ new Map(), Gt?.({ ReactiveElement: E }), (B.reactiveElementVersions ??= []).push("2.1.0");
259
+ E.elementStyles = [], E.shadowRootOptions = { mode: "open" }, E[O("elementProperties")] = /* @__PURE__ */ new Map(), E[O("finalized")] = /* @__PURE__ */ new Map(), Gt?.({ ReactiveElement: E }), (B.reactiveElementVersions ??= []).push("2.1.1");
258
260
  /**
259
261
  * @license
260
262
  * Copyright 2017 Google LLC
@@ -400,7 +402,7 @@ class U {
400
402
  i < e.length && (this._$AR(r && r._$AB.nextSibling, i), e.length = i);
401
403
  }
402
404
  _$AR(t = this._$AA.nextSibling, e) {
403
- for (this._$AP?.(!1, !0, e); t && t !== this._$AB; ) {
405
+ for (this._$AP?.(!1, !0, e); t !== this._$AB; ) {
404
406
  const r = t.nextSibling;
405
407
  t.remove(), t = r;
406
408
  }
@@ -475,7 +477,7 @@ class ne {
475
477
  }
476
478
  }
477
479
  const ae = ot.litHtmlPolyfillSupport;
478
- ae?.(L, U), (ot.litHtmlVersions ??= []).push("3.3.0");
480
+ ae?.(L, U), (ot.litHtmlVersions ??= []).push("3.3.1");
479
481
  const he = (s, t, e) => {
480
482
  const r = e?.renderBefore ?? t;
481
483
  let i = r._$litPart$;
@@ -516,16 +518,16 @@ let S = class extends E {
516
518
  S._$litElement$ = !0, S.finalized = !0, at.litElementHydrateSupport?.({ LitElement: S });
517
519
  const le = at.litElementPolyfillSupport;
518
520
  le?.({ LitElement: S });
519
- (at.litElementVersions ??= []).push("4.2.0");
521
+ (at.litElementVersions ??= []).push("4.2.1");
520
522
  /**
521
523
  * @license
522
524
  * Copyright 2017 Google LLC
523
525
  * SPDX-License-Identifier: BSD-3-Clause
524
526
  */
525
527
  const ht = (s) => (t, e) => {
526
- e !== void 0 ? e.addInitializer(() => {
528
+ e !== void 0 ? e.addInitializer((() => {
527
529
  customElements.define(s, t);
528
- }) : customElements.define(s, t);
530
+ })) : customElements.define(s, t);
529
531
  };
530
532
  /**
531
533
  * @license
@@ -575,9 +577,9 @@ function xt(s) {
575
577
  const de = Symbol();
576
578
  class pe {
577
579
  get taskComplete() {
578
- return this.t || (this.i === 1 ? this.t = new Promise((t, e) => {
580
+ return this.t || (this.i === 1 ? this.t = new Promise(((t, e) => {
579
581
  this.o = t, this.h = e;
580
- }) : this.i === 3 ? this.t = Promise.reject(this.l) : this.t = Promise.resolve(this.u)), this.t;
582
+ })) : this.i === 3 ? this.t = Promise.reject(this.l) : this.t = Promise.resolve(this.u)), this.t;
581
583
  }
582
584
  constructor(t, e, r) {
583
585
  this.p = 0, this.i = 0, (this._ = t).addController(this);
@@ -602,7 +604,7 @@ class pe {
602
604
  }
603
605
  async run(t) {
604
606
  let e, r;
605
- t ??= this.T(), this.O = t, this.i === 1 ? this.q?.abort() : (this.t = void 0, this.o = void 0, this.h = void 0), this.i = 1, this.autoRun === "afterUpdate" ? queueMicrotask(() => this._.requestUpdate()) : this._.requestUpdate();
607
+ t ??= this.T(), this.O = t, this.i === 1 ? this.q?.abort() : (this.t = void 0, this.o = void 0, this.h = void 0), this.i = 1, this.autoRun === "afterUpdate" ? queueMicrotask((() => this._.requestUpdate())) : this._.requestUpdate();
606
608
  const i = ++this.p;
607
609
  this.q = new AbortController();
608
610
  let o = !1;
@@ -659,7 +661,7 @@ class pe {
659
661
  }
660
662
  }
661
663
  }
662
- const fe = (s, t) => s === t || s.length === t.length && s.every((e, r) => !W(e, t[r]));
664
+ const fe = (s, t) => s === t || s.length === t.length && s.every(((e, r) => !W(e, t[r])));
663
665
  !window.orbit && !"/".includes("cypress") && await new Promise((s) => {
664
666
  document.addEventListener("orbit-ready", () => {
665
667
  s(!0);
@@ -962,7 +964,7 @@ const Ce = (s, ...t) => ({
962
964
  * Copyright 2021 Google LLC
963
965
  * SPDX-License-Identifier: BSD-3-Clause
964
966
  */
965
- const Ut = (s) => Pe(s) ? Lt(s.strings, s.values) : s;
967
+ const Ut = ((s) => Pe(s) ? Lt(s.strings, s.values) : s);
966
968
  let ct = Ut, At = !1;
967
969
  function Re(s) {
968
970
  if (At)
@@ -1082,7 +1084,7 @@ function X(s) {
1082
1084
  let I = "", J, Nt, k, tt, Dt, m = new Ht();
1083
1085
  m.resolve();
1084
1086
  let H = 0;
1085
- const qe = (s) => (Re((t, e) => Ne(Dt, t, e)), I = Nt = s.sourceLocale, k = new Set(s.targetLocales), k.add(s.sourceLocale), tt = s.loadLocale, { getLocale: Ie, setLocale: ke }), Ie = () => I, ke = (s) => {
1087
+ const qe = (s) => (Re(((t, e) => Ne(Dt, t, e))), I = Nt = s.sourceLocale, k = new Set(s.targetLocales), k.add(s.sourceLocale), tt = s.loadLocale, { getLocale: Ie, setLocale: ke }), Ie = () => I, ke = (s) => {
1086
1088
  if (s === (J ?? I))
1087
1089
  return m.promise;
1088
1090
  if (!k || !tt)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startinblox/boilerplate",
3
- "version": "4.2.2",
3
+ "version": "4.3.1",
4
4
  "description": "Startin'blox Boilerplate",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -67,24 +67,24 @@
67
67
  ],
68
68
  "dependencies": {
69
69
  "@lit/localize": "^0.12.2",
70
- "@lit/task": "^1.0.2",
70
+ "@lit/task": "^1.0.3",
71
71
  "autoprefixer": "^10.4.21",
72
- "cssnano": "^7.0.7",
73
- "lit": "^3.3.0",
72
+ "cssnano": "^7.1.1",
73
+ "lit": "^3.3.1",
74
74
  "postcss": "^8.5.6",
75
- "postcss-preset-env": "^10.2.3",
75
+ "postcss-preset-env": "^10.4.0",
76
76
  "postcss-scss": "^4.0.9",
77
- "sass": "^1.89.2",
78
- "unplugin-icons": "^22.1.0",
79
- "vite": "^7.0.0"
77
+ "sass": "^1.93.2",
78
+ "unplugin-icons": "^22.5.0",
79
+ "vite": "^7.1.12"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@lit/localize-tools": "^0.8.0",
83
- "@storybook/addon-docs": "^9.0.13",
84
- "@storybook/web-components-vite": "^9.0.13",
85
- "cypress": "^14.5.0",
83
+ "@storybook/addon-docs": "^9.1.13",
84
+ "@storybook/web-components-vite": "^9.1.13",
85
+ "cypress": "^15.5.0",
86
86
  "cypress-ct-lit": "^1.0.0",
87
87
  "lorem-ipsum": "^2.0.8",
88
- "storybook": "^9.0.13"
88
+ "storybook": "^9.1.13"
89
89
  }
90
90
  }