willba-component-library 0.4.0 → 0.4.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/README.md CHANGED
@@ -55,72 +55,62 @@ See [FilterBar props](#filterbar-props) for all available props. TypeScript type
55
55
 
56
56
  ## Use as a script tag (WordPress, plain HTML, anywhere)
57
57
 
58
- Drop one HTML tag and one script tag onto any page:
58
+ Two lines. Set `domain` to the host that serves the filter bar config — the element fetches it on mount and renders.
59
59
 
60
60
  ```html
61
- <willba-filter-bar id="will-filter-bar"></willba-filter-bar>
61
+ <willba-filter-bar
62
+ domain="customer.willba.store"
63
+ mode="dark"
64
+ ></willba-filter-bar>
65
+ <script src="https://cdn.jsdelivr.net/npm/willba-component-library@0.4.1/lib/embed.umd.js"></script>
66
+ ```
62
67
 
63
- <script src="https://cdn.jsdelivr.net/npm/willba-component-library@0.4.0/lib/embed.umd.js"></script>
68
+ The element auto-fetches `https://{domain}/api/services/filter-bar-config?locale=...` and renders inside an isolated Shadow DOM. React, ReactDOM, i18n, and all CSS are bundled inside the script — nothing on the host page can interfere with it, and it cannot interfere with the host page.
64
69
 
65
- <script>
66
- document.getElementById('will-filter-bar').props = {
67
- redirectUrl: 'https://store.vendor.willba.app/',
68
- language: 'en',
69
- mode: 'dark',
70
- tabs: [{ label: 'Rooms', path: '/rooms', default: true, order: 1 }],
71
- ageCategories: [{ id: '1', name: 'Adults', minVal: 1, sortOrder: 1 }],
72
- locations: { multiSelect: false, data: [{ id: 1, label: 'Helsinki' }] },
73
- }
74
- </script>
75
- ```
70
+ ### Available HTML attributes
76
71
 
77
- The custom element mounts inside an isolated Shadow DOM. React, ReactDOM, i18n, and all CSS are bundled inside the script — nothing on the host page can interfere with it, and it cannot interfere with the host page.
72
+ | Attribute | Purpose | Default |
73
+ | ----------------- | ----------------------------------------------------------------------------- | ------------------------------------ |
74
+ | `domain` | Host that serves the filter bar config API. Triggers auto-fetch when present. | (none — element waits for `.props=`) |
75
+ | `mode` | `"dark"` or `"light"`. | (whatever the API returns) |
76
+ | `language` | `"en"` or `"fi"`. | `navigator.language` |
77
+ | `fallback-locale` | Locale to use if `navigator.language` is unavailable. | `"fi"` |
78
+ | `redirect-url` | URL to redirect to after submit. | `https://{domain}` |
78
79
 
79
- ### Passing props
80
+ Protocol is auto-detected: `http://` for `localhost` / `127.0.0.1` hosts, `https://` everywhere else.
80
81
 
81
- Use the `.props` setter to pass any prop the React component accepts. Re-assigning `.props` re-renders the element. Setting `.props` before the element upgrades is safe — the value is buffered and applied automatically.
82
+ ### Configuration precedence
82
83
 
83
- ```js
84
- const el = document.getElementById('will-filter-bar')
85
- el.props = { ...el.props, language: 'fi' } // switch language at runtime
84
+ When multiple sources set the same prop, the higher one wins:
85
+
86
+ ```
87
+ API response → HTML attributes → el.props (programmatic)
88
+ (lowest) (highest)
86
89
  ```
87
90
 
88
- ### Loading config from an API
91
+ So a customer's API can ship sensible defaults, and a single embed can override `mode` or `language` per page without touching the API.
92
+
93
+ ### Programmatic control (advanced)
89
94
 
90
- Common pattern when the snippet sits on a customer site and the prop config lives on a backend:
95
+ For full programmatic control including complex props like `tabs`, `locations`, `ageCategories`, `palette` that don't fit in HTML attributes — set `.props` directly:
91
96
 
92
97
  ```html
93
- <willba-filter-bar id="will-filter-bar"></willba-filter-bar>
94
- <script src="https://cdn.jsdelivr.net/npm/willba-component-library@0.4.0/lib/embed.umd.js"></script>
98
+ <willba-filter-bar id="fb"></willba-filter-bar>
99
+ <script src="https://cdn.jsdelivr.net/npm/willba-component-library@0.4.1/lib/embed.umd.js"></script>
95
100
  <script>
96
- ;(async () => {
97
- try {
98
- const domain = 'customer.willba.store'
99
- const locale = (navigator.language || 'fi').split('-')[0]
100
- const res = await fetch(
101
- `https://${domain}/api/services/filter-bar-config?locale=${locale}`,
102
- {
103
- headers: { Accept: 'application/json' },
104
- signal: AbortSignal.timeout(10000),
105
- }
106
- )
107
- if (!res.ok) return
108
-
109
- const { filterBarConfig } = await res.json()
110
- if (!filterBarConfig) return
111
-
112
- document.getElementById('will-filter-bar').props = {
113
- ...filterBarConfig,
114
- redirectUrl: `https://${domain}`,
115
- mode: 'dark',
116
- }
117
- } catch (error) {
118
- console.error('Failed to render filter bar:', error)
119
- }
120
- })()
101
+ document.getElementById('fb').props = {
102
+ redirectUrl: 'https://store.vendor.willba.app/',
103
+ language: 'en',
104
+ mode: 'dark',
105
+ tabs: [{ label: 'Rooms', path: '/rooms', default: true, order: 1 }],
106
+ ageCategories: [{ id: '1', name: 'Adults', minVal: 1, sortOrder: 1 }],
107
+ locations: { multiSelect: false, data: [{ id: 1, label: 'Helsinki' }] },
108
+ }
121
109
  </script>
122
110
  ```
123
111
 
112
+ Re-assigning `.props` re-renders the element. Setting `.props` before the element upgrades is safe — the value is buffered and applied automatically. To merge with existing props instead of replacing, spread first: `el.props = { ...el.props, language: 'fi' }`.
113
+
124
114
  ## FilterBar props
125
115
 
126
116
  | Name | Value | Description |
package/lib/embed.d.ts CHANGED
@@ -13,6 +13,9 @@ declare abstract class WillbaElement<P extends object> extends HTMLElement {
13
13
  private _render;
14
14
  }
15
15
  export declare class WillbaFilterBarElement extends WillbaElement<FilterBarTypes> {
16
+ private _autoFetchTriggered;
16
17
  protected renderReact(props: Partial<FilterBarTypes>): React.JSX.Element;
18
+ connectedCallback(): void;
19
+ private _loadConfigFromApi;
17
20
  }
18
21
  export {};