@sequent-org/ifc-viewer 1.0.2-ci.4.0 → 1.0.3-ci.6.0

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
@@ -2,6 +2,8 @@
2
2
 
3
3
  IFC 3D model viewer component for web applications. Основан на Three.js и web-ifc для просмотра BIM моделей в браузере.
4
4
 
5
+ **✨ Полностью автономный пакет** - не требует внешних CSS фреймворков (Tailwind, Bootstrap и т.д.).
6
+
5
7
  ## 🚀 Установка
6
8
 
7
9
  ```bash
@@ -140,12 +142,20 @@ container.addEventListener('ifcviewer:disposed', (e) => {
140
142
 
141
143
  ## 🎨 Стили
142
144
 
143
- Стили подключаются автоматически при импорте пакета. Если нужно подключить стили отдельно:
145
+ **Стили подключаются автоматически** при импорте пакета и полностью **автономны** - не требуют Tailwind CSS, Bootstrap или других внешних фреймворков.
146
+
147
+ Если нужно подключить стили отдельно:
144
148
 
145
149
  ```javascript
146
150
  import '@sequent-org/ifc-viewer/style.css'
147
151
  ```
148
152
 
153
+ **Преимущества локальных стилей:**
154
+ - ✅ Полная автономность пакета
155
+ - ✅ Нет конфликтов с CSS фреймворками сайта
156
+ - ✅ Меньший размер bundle'а
157
+ - ✅ Быстрая загрузка без внешних зависимостей
158
+
149
159
  ## 🎛️ Функции верхней панели
150
160
 
151
161
  При включенной опции `showToolbar` доступны следующие инструменты:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sequent-org/ifc-viewer",
3
3
  "private": false,
4
- "version": "1.0.2-ci.4.0",
4
+ "version": "1.0.3-ci.6.0",
5
5
  "type": "module",
6
6
  "description": "IFC 3D model viewer component for web applications",
7
7
  "main": "src/index.js",
@@ -39,14 +39,9 @@
39
39
  "test:manual": "vite dev --open test.html"
40
40
  },
41
41
  "devDependencies": {
42
- "@tailwindcss/postcss": "^4.1.13",
43
- "autoprefixer": "^10.4.21",
44
- "postcss": "^8.5.6",
45
- "tailwindcss": "^4.1.13",
46
42
  "vite": "^7.1.2"
47
43
  },
48
44
  "dependencies": {
49
- "daisyui": "^5.1.12",
50
45
  "three": "^0.149.0",
51
46
  "web-ifc": "^0.0.39",
52
47
  "web-ifc-three": "^0.0.126"
package/src/IfcViewer.js CHANGED
@@ -342,8 +342,8 @@ export class IfcViewer {
342
342
  <!-- Основной контейнер просмотрщика -->
343
343
  <div id="ifcViewerMain" class="w-full flex-1 relative"></div>
344
344
 
345
- <!-- Боковая панель -->
346
- <div id="ifcSidebar" class="absolute left-0 top-0 h-full w-80 bg-base-200 shadow-lg transform -translate-x-full transition-transform duration-300 pointer-events-none z-40">
345
+ <!-- Боковая панель (временно скрыта) -->
346
+ <div id="ifcSidebar" class="absolute left-0 top-0 h-full w-80 bg-base-200 shadow-lg transform -translate-x-full transition-transform duration-300 pointer-events-none z-40" style="display: none;">
347
347
  <div class="flex flex-col h-full">
348
348
  <!-- Заголовок панели -->
349
349
  <div class="flex items-center justify-between p-4 border-b border-base-300">
@@ -371,11 +371,13 @@ export class IfcViewer {
371
371
  </div>
372
372
  </div>
373
373
 
374
- <!-- Панель управления -->
375
- <div id="ifcControls" class="absolute top-4 left-4 z-30" style="${this.options.showControls ? '' : 'display: none;'}">
376
- <!-- Кнопка панели (показываем если включен сайдбар) -->
377
- <button id="ifcSidebarToggle" class="btn btn-primary btn-sm mb-2">☰</button>
378
-
374
+ <!-- Кнопка сайдбара (временно скрыта) -->
375
+ <div id="ifcSidebarToggleContainer" class="absolute top-4 left-4 z-30" style="display: none;">
376
+ <button id="ifcSidebarToggle" class="btn btn-primary btn-sm">☰</button>
377
+ </div>
378
+
379
+ <!-- Панель управления (дополнительные кнопки) -->
380
+ <div id="ifcControls" class="absolute top-4 left-4 z-30" style="${this.options.showControls ? 'margin-top: 3rem;' : 'display: none;'}">
379
381
  <!-- Кнопка загрузки -->
380
382
  <button id="ifcUploadBtn" class="btn btn-secondary btn-sm">📁</button>
381
383
  <input type="file" id="ifcFileInput" accept=".ifc,.ifczip,.zip" style="display: none;">
@@ -587,16 +589,17 @@ export class IfcViewer {
587
589
  * @private
588
590
  */
589
591
  _setSidebarVisible(visible) {
590
- if (!this.elements.sidebar) return;
592
+ const sidebar = this.containerElement.querySelector('#ifcSidebar');
593
+ if (!sidebar) return;
591
594
 
592
595
  if (visible) {
593
- this.elements.sidebar.classList.remove('-translate-x-full');
594
- this.elements.sidebar.classList.add('translate-x-0');
595
- this.elements.sidebar.classList.remove('pointer-events-none');
596
+ sidebar.classList.remove('-translate-x-full');
597
+ sidebar.classList.add('translate-x-0');
598
+ sidebar.classList.remove('pointer-events-none');
596
599
  } else {
597
- this.elements.sidebar.classList.add('-translate-x-full');
598
- this.elements.sidebar.classList.remove('translate-x-0');
599
- this.elements.sidebar.classList.add('pointer-events-none');
600
+ sidebar.classList.add('-translate-x-full');
601
+ sidebar.classList.remove('translate-x-0');
602
+ sidebar.classList.add('pointer-events-none');
600
603
  }
601
604
  }
602
605
 
package/src/style.css CHANGED
@@ -1,2 +1,2 @@
1
- @import "tailwindcss";
2
- @plugin "daisyui";
1
+ /* Импорт локальных стилей для полной автономности пакета */
2
+ @import './styles-local.css';
@@ -0,0 +1,414 @@
1
+ /*
2
+ * Локальные стили для @sequent-org/ifc-viewer
3
+ * Заменяют Tailwind CSS + DaisyUI для полной автономности пакета
4
+ */
5
+
6
+ /* === RESET & BASE === */
7
+ * {
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ .ifc-viewer-container {
12
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
13
+ line-height: 1.5;
14
+ -webkit-text-size-adjust: 100%;
15
+ }
16
+
17
+ /* === CSS VARIABLES (THEME COLORS) === */
18
+ .ifc-viewer-container {
19
+ --color-primary: #3b82f6;
20
+ --color-primary-hover: #2563eb;
21
+ --color-secondary: #64748b;
22
+ --color-secondary-hover: #475569;
23
+ --color-neutral: #374151;
24
+ --color-neutral-content: #ffffff;
25
+ --color-base-100: #ffffff;
26
+ --color-base-200: #f9fafb;
27
+ --color-base-300: #e5e7eb;
28
+ --color-ghost: transparent;
29
+ --color-ghost-hover: #f3f4f6;
30
+ --border-radius: 0.5rem;
31
+ --shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
32
+ }
33
+
34
+ /* Dark theme */
35
+ .ifc-viewer-container[data-theme="dark"] {
36
+ --color-base-100: #1f2937;
37
+ --color-base-200: #374151;
38
+ --color-base-300: #4b5563;
39
+ --color-neutral: #6b7280;
40
+ --color-neutral-content: #ffffff;
41
+ --color-ghost-hover: #374151;
42
+ }
43
+
44
+ /* === LAYOUT UTILITIES === */
45
+ .flex { display: flex; }
46
+ .flex-col { flex-direction: column; }
47
+ .items-center { align-items: center; }
48
+ .justify-between { justify-content: space-between; }
49
+ .justify-center { justify-content: center; }
50
+ .gap-2 { gap: 0.5rem; }
51
+ .gap-4 { gap: 1rem; }
52
+ .w-full { width: 100%; }
53
+ .w-80 { width: 20rem; }
54
+ .w-12 { width: 3rem; }
55
+ .h-full { height: 100%; }
56
+ .flex-1 { flex: 1 1 0%; }
57
+
58
+ /* === POSITIONING === */
59
+ .absolute { position: absolute; }
60
+ .relative { position: relative; }
61
+ .fixed { position: fixed; }
62
+ .inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
63
+ .left-0 { left: 0; }
64
+ .top-0 { top: 0; }
65
+ .top-4 { top: 1rem; }
66
+ .left-4 { left: 1rem; }
67
+ .bottom-4 { bottom: 1rem; }
68
+ .right-4 { right: 1rem; }
69
+ .z-30 { z-index: 30; }
70
+ .z-40 { z-index: 40; }
71
+ .z-50 { z-index: 50; }
72
+
73
+ /* === SPACING === */
74
+ .p-2 { padding: 0.5rem; }
75
+ .p-4 { padding: 1rem; }
76
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
77
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
78
+ .mb-2 { margin-bottom: 0.5rem; }
79
+ .mt-2 { margin-top: 0.5rem; }
80
+
81
+ /* === BORDERS === */
82
+ .border-b { border-bottom-width: 1px; border-bottom-style: solid; }
83
+ .border-t { border-top-width: 1px; border-top-style: solid; }
84
+ .border-base-300 { border-color: var(--color-base-300); }
85
+
86
+ /* === COLORS === */
87
+ .bg-neutral { background-color: var(--color-neutral); }
88
+ .text-neutral-content { color: var(--color-neutral-content); }
89
+ .bg-base-100 { background-color: var(--color-base-100); }
90
+ .bg-base-200 { background-color: var(--color-base-200); }
91
+ .text-black { color: #000000; }
92
+ .bg-white { background-color: #ffffff; }
93
+
94
+ /* === TYPOGRAPHY === */
95
+ .text-lg { font-size: 1.125rem; line-height: 1.75rem; }
96
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
97
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
98
+ .text-center { text-align: center; }
99
+ .font-semibold { font-weight: 600; }
100
+ .font-medium { font-weight: 500; }
101
+ .opacity-70 { opacity: 0.7; }
102
+
103
+ /* === LAYOUT SPECIFIC === */
104
+ .shrink-0 { flex-shrink: 0; }
105
+ .overflow-auto { overflow: auto; }
106
+ .shadow-lg { box-shadow: var(--shadow); }
107
+ .transform { transform: translate(var(--tw-translate-x), var(--tw-translate-y)); }
108
+ .-translate-x-full { --tw-translate-x: -100%; }
109
+ .transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
110
+ .duration-300 { transition-duration: 300ms; }
111
+ .pointer-events-none { pointer-events: none; }
112
+
113
+ /* === NAVBAR COMPONENT === */
114
+ .navbar {
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: space-between;
118
+ width: 100%;
119
+ padding: 0.5rem 1rem;
120
+ min-height: 4rem;
121
+ background-color: var(--color-neutral);
122
+ color: var(--color-neutral-content);
123
+ }
124
+
125
+ .navbar-start {
126
+ display: flex;
127
+ align-items: center;
128
+ justify-content: flex-start;
129
+ flex: 1 1 0%;
130
+ }
131
+
132
+ .navbar-end {
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: flex-end;
136
+ flex: 1 1 0%;
137
+ }
138
+
139
+ /* === BUTTON COMPONENT === */
140
+ .btn {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ border-radius: var(--border-radius);
145
+ height: 3rem;
146
+ padding: 0 1rem;
147
+ min-height: 2.5rem;
148
+ font-size: 0.875rem;
149
+ font-weight: 600;
150
+ text-decoration: none;
151
+ border: 1px solid transparent;
152
+ cursor: pointer;
153
+ user-select: none;
154
+ transition-property: color, background-color, border-color;
155
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
156
+ transition-duration: 200ms;
157
+ background-color: var(--color-base-200);
158
+ color: var(--color-neutral);
159
+ }
160
+
161
+ .btn:hover {
162
+ background-color: var(--color-base-300);
163
+ }
164
+
165
+ .btn-sm {
166
+ height: 2rem;
167
+ min-height: 2rem;
168
+ padding: 0 0.75rem;
169
+ font-size: 0.75rem;
170
+ }
171
+
172
+ .btn-primary {
173
+ background-color: var(--color-primary);
174
+ color: white;
175
+ border-color: var(--color-primary);
176
+ }
177
+
178
+ .btn-primary:hover {
179
+ background-color: var(--color-primary-hover);
180
+ border-color: var(--color-primary-hover);
181
+ }
182
+
183
+ .btn-secondary {
184
+ background-color: var(--color-secondary);
185
+ color: white;
186
+ border-color: var(--color-secondary);
187
+ }
188
+
189
+ .btn-secondary:hover {
190
+ background-color: var(--color-secondary-hover);
191
+ border-color: var(--color-secondary-hover);
192
+ }
193
+
194
+ .btn-ghost {
195
+ background-color: var(--color-ghost);
196
+ border-color: var(--color-ghost);
197
+ }
198
+
199
+ .btn-ghost:hover {
200
+ background-color: var(--color-ghost-hover);
201
+ }
202
+
203
+ .btn-active {
204
+ background-color: var(--color-primary);
205
+ color: white;
206
+ border-color: var(--color-primary);
207
+ }
208
+
209
+ /* === JOIN COMPONENT (кнопки группой) === */
210
+ .join {
211
+ display: inline-flex;
212
+ align-items: stretch;
213
+ border-radius: var(--border-radius);
214
+ }
215
+
216
+ .join-item:not(:first-child) {
217
+ margin-left: -1px;
218
+ border-top-left-radius: 0;
219
+ border-bottom-left-radius: 0;
220
+ }
221
+
222
+ .join-item:not(:last-child) {
223
+ border-top-right-radius: 0;
224
+ border-bottom-right-radius: 0;
225
+ }
226
+
227
+ .join-item:first-child {
228
+ border-top-left-radius: var(--border-radius);
229
+ border-bottom-left-radius: var(--border-radius);
230
+ }
231
+
232
+ .join-item:last-child {
233
+ border-top-right-radius: var(--border-radius);
234
+ border-bottom-right-radius: var(--border-radius);
235
+ }
236
+
237
+ /* === LOADING SPINNER === */
238
+ .loading {
239
+ pointer-events: none;
240
+ display: inline-block;
241
+ }
242
+
243
+ .loading-spinner {
244
+ animation: loading-spin 1s linear infinite;
245
+ width: 1.25rem;
246
+ height: 1.25rem;
247
+ border-radius: 9999px;
248
+ border-width: 2px;
249
+ border-color: transparent;
250
+ border-top-color: currentColor;
251
+ border-left-color: currentColor;
252
+ }
253
+
254
+ .loading-lg {
255
+ width: 2.5rem;
256
+ height: 2.5rem;
257
+ border-width: 4px;
258
+ }
259
+
260
+ @keyframes loading-spin {
261
+ from {
262
+ transform: rotate(0deg);
263
+ }
264
+ to {
265
+ transform: rotate(360deg);
266
+ }
267
+ }
268
+
269
+ /* === TOGGLE (CHECKBOX) === */
270
+ .toggle {
271
+ appearance: none;
272
+ cursor: pointer;
273
+ border-radius: 9999px;
274
+ height: 1.5rem;
275
+ width: 3rem;
276
+ border-width: 1px;
277
+ border-color: var(--color-base-300);
278
+ background-color: var(--color-base-200);
279
+ transition-property: background, border-color;
280
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
281
+ transition-duration: 200ms;
282
+ position: relative;
283
+ }
284
+
285
+ .toggle::before {
286
+ content: '';
287
+ position: absolute;
288
+ left: 0;
289
+ top: 0;
290
+ height: 1.25rem;
291
+ width: 1.25rem;
292
+ border-radius: 9999px;
293
+ background-color: white;
294
+ border-width: 1px;
295
+ border-color: var(--color-base-300);
296
+ transition-property: transform;
297
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
298
+ transition-duration: 200ms;
299
+ }
300
+
301
+ .toggle:checked {
302
+ background-color: var(--color-primary);
303
+ border-color: var(--color-primary);
304
+ }
305
+
306
+ .toggle:checked::before {
307
+ transform: translateX(1.5rem);
308
+ border-color: var(--color-primary);
309
+ }
310
+
311
+ .toggle-primary:checked {
312
+ background-color: var(--color-primary);
313
+ border-color: var(--color-primary);
314
+ }
315
+
316
+ /* === LABEL === */
317
+ .label {
318
+ display: flex;
319
+ user-select: none;
320
+ align-items: center;
321
+ justify-content: space-between;
322
+ padding: 0.5rem 0.25rem;
323
+ }
324
+
325
+ .label-text {
326
+ font-size: 0.875rem;
327
+ line-height: 1.25rem;
328
+ }
329
+
330
+ .cursor-pointer {
331
+ cursor: pointer;
332
+ }
333
+
334
+ /* === RANGE INPUT === */
335
+ .range {
336
+ height: 1.5rem;
337
+ width: 100%;
338
+ cursor: pointer;
339
+ appearance: none;
340
+ border-radius: 9999px;
341
+ background: transparent;
342
+ }
343
+
344
+ .range:focus {
345
+ outline: none;
346
+ }
347
+
348
+ .range-sm {
349
+ height: 1rem;
350
+ }
351
+
352
+ .range::-webkit-slider-track {
353
+ height: 0.5rem;
354
+ background: var(--color-base-300);
355
+ border-radius: 9999px;
356
+ }
357
+
358
+ .range::-webkit-slider-thumb {
359
+ appearance: none;
360
+ height: 1.25rem;
361
+ width: 1.25rem;
362
+ border-radius: 9999px;
363
+ background: var(--color-primary);
364
+ cursor: pointer;
365
+ }
366
+
367
+ .range::-moz-range-track {
368
+ height: 0.5rem;
369
+ background: var(--color-base-300);
370
+ border-radius: 9999px;
371
+ border: none;
372
+ }
373
+
374
+ .range::-moz-range-thumb {
375
+ height: 1.25rem;
376
+ width: 1.25rem;
377
+ border-radius: 9999px;
378
+ background: var(--color-primary);
379
+ cursor: pointer;
380
+ border: none;
381
+ }
382
+
383
+ .range-sm::-webkit-slider-thumb {
384
+ height: 1rem;
385
+ width: 1rem;
386
+ }
387
+
388
+ .range-sm::-moz-range-thumb {
389
+ height: 1rem;
390
+ width: 1rem;
391
+ }
392
+
393
+ /* === TRANSFORMATIONS FOR SIDEBAR === */
394
+ .translate-x-0 {
395
+ --tw-translate-x: 0px;
396
+ transform: translateX(var(--tw-translate-x));
397
+ }
398
+
399
+ /* === RESPONSIVE & UTILITIES === */
400
+ .select-none {
401
+ user-select: none;
402
+ }
403
+
404
+ .hidden {
405
+ display: none;
406
+ }
407
+
408
+ /* === TEXT COLORS FOR TEST PAGE === */
409
+ .text-blue-600 { color: #2563eb; }
410
+ .text-green-600 { color: #16a34a; }
411
+ .text-red-600 { color: #dc2626; }
412
+ .text-orange-600 { color: #ea580c; }
413
+ .text-gray-600 { color: #4b5563; }
414
+ .text-gray-500 { color: #6b7280; }