@neurodyn/room-viewer 0.0.33 → 0.1.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.
@@ -42,38 +42,198 @@ class RoomViewerDialogRenderer {
42
42
  }));
43
43
  }
44
44
  }
45
- function readTriggerProps(trigger, props = {}) {
45
+ function contract_attribute(name, parser, details) {
46
46
  return {
47
- disableClose: void 0 !== props.disableClose ? props.disableClose : 'true' === trigger.getAttribute('data-neurodyn-room-viewer-disable-close'),
48
- type: void 0 !== props.type ? props.type : trigger.getAttribute('data-neurodyn-room-viewer-type'),
49
- src: void 0 !== props.src ? props.src : trigger.getAttribute('data-neurodyn-room-viewer-src'),
50
- tinuuid: void 0 !== props.tinuuid ? props.tinuuid : trigger.getAttribute('data-neurodyn-room-viewer-tinuuid'),
51
- roomId: void 0 !== props.roomId ? props.roomId : trigger.getAttribute('data-neurodyn-room-viewer-room-id') ?? void 0,
52
- name: void 0 !== props.name ? props.name : trigger.getAttribute('data-neurodyn-room-viewer-name'),
53
- language: void 0 !== props.language ? props.language : trigger.getAttribute('data-neurodyn-room-viewer-language'),
54
- width: void 0 !== props.width ? props.width : readNumberAttribute(trigger, 'data-neurodyn-room-viewer-width'),
55
- height: void 0 !== props.height ? props.height : readNumberAttribute(trigger, 'data-neurodyn-room-viewer-height'),
56
- dimensionUnit: void 0 !== props.dimensionUnit ? props.dimensionUnit : readDimensionUnitAttribute(trigger, 'data-neurodyn-room-viewer-dimension-unit'),
57
- displayUnit: void 0 !== props.displayUnit ? props.displayUnit : readDisplayUnitAttribute(trigger, 'data-neurodyn-room-viewer-display-unit'),
58
- apiKey: void 0 !== props.apiKey ? props.apiKey : trigger.getAttribute('data-neurodyn-room-viewer-api-key'),
59
- source: void 0 !== props.source ? props.source : readSourceAttribute(trigger, 'data-neurodyn-room-viewer-source')
47
+ kind: 'attribute',
48
+ name,
49
+ parse: parser.parse,
50
+ values: parser.values,
51
+ ...details
60
52
  };
61
53
  }
62
- function readNumberAttribute(trigger, name) {
63
- const value = trigger.getAttribute(name);
64
- return value ? Number(value) : void 0;
54
+ function optionOnly(reason) {
55
+ return {
56
+ kind: 'option',
57
+ reason
58
+ };
65
59
  }
66
- function readDimensionUnitAttribute(trigger, name) {
67
- const value = trigger.getAttribute(name);
68
- return 'm' === value || 'cm' === value || 'in' === value ? value : void 0;
60
+ function defineTriggerContract() {
61
+ return (contract)=>contract;
69
62
  }
70
- function readDisplayUnitAttribute(trigger, name) {
71
- const value = trigger.getAttribute(name);
72
- return 'cm' === value || 'in' === value ? value : void 0;
63
+ function contract_attributeEntries(contract) {
64
+ return Object.entries(contract.fields).filter((entry)=>'attribute' === entry[1].kind);
73
65
  }
74
- function readSourceAttribute(trigger, name) {
66
+ function readRawAttribute(trigger, name, legacyNames = []) {
75
67
  const value = trigger.getAttribute(name);
76
- return 'default' === value || 'shopify' === value ? value : void 0;
68
+ if (0 === legacyNames.length || value?.trim()) return value;
69
+ for (const legacyName of legacyNames){
70
+ const legacyValue = trigger.getAttribute(legacyName);
71
+ if (legacyValue?.trim()) return legacyValue;
72
+ }
73
+ return value;
74
+ }
75
+ function readTriggerAttributes(trigger, contract, options = {}) {
76
+ const values = {};
77
+ for (const [key, field] of contract_attributeEntries(contract)){
78
+ const name = `${contract.prefix}${field.name}`;
79
+ const option = options[key];
80
+ if (void 0 !== option) {
81
+ values[key] = field.normalizesOptions ? field.parse(option, {
82
+ attribute: name
83
+ }) : option;
84
+ continue;
85
+ }
86
+ values[key] = field.parse(readRawAttribute(trigger, name, field.legacyNames), {
87
+ attribute: name
88
+ });
89
+ }
90
+ return values;
91
+ }
92
+ function parsers_text() {
93
+ return {
94
+ parse: (raw)=>raw ?? void 0
95
+ };
96
+ }
97
+ function number() {
98
+ return {
99
+ parse: (raw)=>raw ? Number(raw) : void 0
100
+ };
101
+ }
102
+ function flag() {
103
+ return {
104
+ parse: (raw)=>'true' === raw
105
+ };
106
+ }
107
+ function oneOf(values) {
108
+ return {
109
+ parse: (raw)=>values.includes(raw ?? '') ? raw : void 0,
110
+ values
111
+ };
112
+ }
113
+ function unchecked(values) {
114
+ return {
115
+ parse: (raw)=>raw ?? void 0,
116
+ values
117
+ };
118
+ }
119
+ function listOf() {
120
+ return (values)=>values;
121
+ }
122
+ const ROOM_VIEWER_TRIGGER_ATTRIBUTE = 'data-neurodyn-room-viewer-dialog';
123
+ const ROOM_VIEWER_RESOURCE_TYPES = listOf()([
124
+ 'wallart',
125
+ 'rugs',
126
+ 'flooring',
127
+ 'wall-panel'
128
+ ]);
129
+ const ROOM_VIEWER_DIMENSION_UNITS = listOf()([
130
+ 'm',
131
+ 'cm',
132
+ 'in'
133
+ ]);
134
+ const ROOM_VIEWER_DISPLAY_UNITS = listOf()([
135
+ 'cm',
136
+ 'in'
137
+ ]);
138
+ const ROOM_VIEWER_LANGUAGES = listOf()([
139
+ 'en',
140
+ 'ru'
141
+ ]);
142
+ const ROOM_VIEWER_SOURCES = listOf()([
143
+ 'default',
144
+ 'shopify'
145
+ ]);
146
+ const roomViewerContract = defineTriggerContract()({
147
+ prefix: 'data-neurodyn-room-viewer-',
148
+ markers: [
149
+ {
150
+ name: ROOM_VIEWER_TRIGGER_ATTRIBUTE,
151
+ description: 'Marks an element for the embed build.'
152
+ }
153
+ ],
154
+ fields: {
155
+ type: contract_attribute('type', unchecked(ROOM_VIEWER_RESOURCE_TYPES), {
156
+ required: true,
157
+ description: 'Resource type.'
158
+ }),
159
+ src: contract_attribute('src', parsers_text(), {
160
+ required: {
161
+ when: 'type',
162
+ is: [
163
+ 'wallart'
164
+ ]
165
+ },
166
+ description: 'Wall-art image URL.'
167
+ }),
168
+ tinuuid: contract_attribute('tinuuid', parsers_text(), {
169
+ required: {
170
+ when: 'type',
171
+ is: [
172
+ 'rugs',
173
+ 'flooring',
174
+ 'wall-panel'
175
+ ]
176
+ },
177
+ description: 'The object\'s tinuuid.'
178
+ }),
179
+ roomId: contract_attribute('room-id', parsers_text(), {
180
+ required: false,
181
+ description: 'Initial Room ID from the available catalog. Skips the initial interior chooser; unavailable Rooms open the chooser. Empty values do nothing.'
182
+ }),
183
+ name: contract_attribute('name', parsers_text(), {
184
+ required: true,
185
+ description: 'Title shown in the dialog header.'
186
+ }),
187
+ width: contract_attribute('width', number(), {
188
+ required: false,
189
+ description: 'Wall-art width. Used when `type` is `wallart`.'
190
+ }),
191
+ height: contract_attribute('height', number(), {
192
+ required: false,
193
+ description: 'Wall-art height. Used when `type` is `wallart`.'
194
+ }),
195
+ dimensionUnit: contract_attribute('dimension-unit', oneOf(ROOM_VIEWER_DIMENSION_UNITS), {
196
+ required: false,
197
+ defaultValue: '`m`',
198
+ description: 'Unit used by wall-art width and height.'
199
+ }),
200
+ displayUnit: contract_attribute('display-unit', oneOf(ROOM_VIEWER_DISPLAY_UNITS), {
201
+ required: false,
202
+ defaultValue: '`cm`',
203
+ description: 'Unit used to display UI measurements.'
204
+ }),
205
+ language: contract_attribute('language', oneOf(ROOM_VIEWER_LANGUAGES), {
206
+ required: false,
207
+ defaultValue: 'User locale',
208
+ description: 'UI language override.'
209
+ }),
210
+ apiKey: contract_attribute('api-key', parsers_text(), {
211
+ required: true,
212
+ description: 'Public API key sent as `x-api-key`. Not needed when `source` is `shopify`.'
213
+ }),
214
+ source: contract_attribute('source', oneOf(ROOM_VIEWER_SOURCES), {
215
+ required: false,
216
+ defaultValue: '`default`',
217
+ description: 'Backend source mode.'
218
+ }),
219
+ disableClose: contract_attribute('disable-close', flag(), {
220
+ required: false,
221
+ defaultValue: '`false`',
222
+ description: 'Set to `true` to hide close controls and prevent dismissal.'
223
+ }),
224
+ widgetSession: optionOnly('An existing Widget Session handed over by an embedding surface such as Shopify.'),
225
+ open: optionOnly('The embed build owns the open state.'),
226
+ defaultOpen: optionOnly('The embed build owns the open state.'),
227
+ onOpenChange: optionOnly('The embed build owns the open state.')
228
+ }
229
+ });
230
+ function readTriggerProps(trigger, props = {}) {
231
+ const values = readTriggerAttributes(trigger, roomViewerContract, props);
232
+ return {
233
+ ...values,
234
+ type: values.type,
235
+ name: values.name
236
+ };
77
237
  }
78
238
  class src_RoomViewerDialog {
79
239
  renderer = new RoomViewerDialogRenderer();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/room-viewer",
3
3
  "type": "module",
4
- "version": "0.0.33",
4
+ "version": "0.1.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -10,6 +10,11 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/room-viewer.js",
12
12
  "default": "./dist/room-viewer.js"
13
+ },
14
+ "./contract": {
15
+ "types": "./dist/contract.d.ts",
16
+ "import": "./dist/contract.js",
17
+ "default": "./dist/contract.js"
13
18
  }
14
19
  },
15
20
  "main": "./dist/room-viewer.js",
@@ -21,7 +26,7 @@
21
26
  "dependencies": {
22
27
  "react": "^19.2.0",
23
28
  "react-dom": "^19.2.0",
24
- "@neurodyn/react-room-viewer": "0.0.33"
29
+ "@neurodyn/react-room-viewer": "0.0.35"
25
30
  },
26
31
  "devDependencies": {
27
32
  "@google/model-viewer": "4.2.0",
@@ -56,7 +61,6 @@
56
61
  "react-i18next": "^16.3.5",
57
62
  "react-intersection-observer": "^10.0.0",
58
63
  "react-zoom-pan-pinch": "3.7.0",
59
- "swiper": "^12.1.0",
60
64
  "tailwind-merge": "3.4.0",
61
65
  "three": "^0.185.1",
62
66
  "typescript": "^5.9.3",
@@ -67,6 +71,9 @@
67
71
  "dev": "rslib build --watch",
68
72
  "build": "rslib build",
69
73
  "test": "vitest run",
74
+ "test:contract": "vitest run",
75
+ "typecheck": "tsc --noEmit",
76
+ "docs:generate": "vitest run --update src/contract.docs.test.ts",
70
77
  "lint": "eslint .",
71
78
  "lint:fix": "eslint . --fix",
72
79
  "rsdoctor": "RSDOCTOR=true rslib build"