bitwrench 2.0.13 → 2.0.15

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.
Files changed (46) hide show
  1. package/README.md +4 -4
  2. package/dist/bitwrench-code-edit.cjs.js +46 -46
  3. package/dist/bitwrench-code-edit.cjs.min.js +16 -0
  4. package/dist/bitwrench-code-edit.es5.js +8 -8
  5. package/dist/bitwrench-code-edit.es5.min.js +2 -2
  6. package/dist/bitwrench-code-edit.esm.js +46 -46
  7. package/dist/bitwrench-code-edit.esm.min.js +2 -2
  8. package/dist/bitwrench-code-edit.umd.js +46 -46
  9. package/dist/bitwrench-code-edit.umd.min.js +2 -2
  10. package/dist/bitwrench-lean.cjs.js +5011 -3419
  11. package/dist/bitwrench-lean.cjs.min.js +35 -6
  12. package/dist/bitwrench-lean.es5.js +6218 -4272
  13. package/dist/bitwrench-lean.es5.min.js +32 -3
  14. package/dist/bitwrench-lean.esm.js +5011 -3419
  15. package/dist/bitwrench-lean.esm.min.js +35 -6
  16. package/dist/bitwrench-lean.umd.js +5011 -3419
  17. package/dist/bitwrench-lean.umd.min.js +35 -6
  18. package/dist/bitwrench.cjs.js +6966 -4662
  19. package/dist/bitwrench.cjs.min.js +38 -8
  20. package/dist/bitwrench.css +2453 -4784
  21. package/dist/bitwrench.es5.js +9592 -6813
  22. package/dist/bitwrench.es5.min.js +34 -5
  23. package/dist/bitwrench.esm.js +6966 -4662
  24. package/dist/bitwrench.esm.min.js +38 -8
  25. package/dist/bitwrench.min.css +1 -0
  26. package/dist/bitwrench.umd.js +6966 -4662
  27. package/dist/bitwrench.umd.min.js +38 -8
  28. package/dist/builds.json +89 -67
  29. package/dist/sri.json +28 -26
  30. package/package.json +7 -5
  31. package/readme.html +14 -14
  32. package/src/{bitwrench-components-v2.js → bitwrench-bccl.js} +1311 -600
  33. package/src/bitwrench-code-edit.js +45 -45
  34. package/src/bitwrench-color-utils.js +154 -27
  35. package/src/bitwrench-components-stub.js +4 -1
  36. package/src/bitwrench-file-ops.js +180 -0
  37. package/src/bitwrench-lean.js +2 -2
  38. package/src/bitwrench-styles.js +1468 -3494
  39. package/src/bitwrench-utils.js +458 -0
  40. package/src/bitwrench.js +1795 -1349
  41. package/src/cli/layout-default.js +18 -18
  42. package/src/generate-css.js +73 -53
  43. package/src/version.js +3 -3
  44. package/src/bitwrench-component-base.js +0 -736
  45. package/src/bitwrench-components-inline.js +0 -374
  46. package/src/bitwrench-components.js +0 -610
@@ -1,736 +0,0 @@
1
- /**
2
- * Bitwrench v2 Component System
3
- * Object-oriented components with state management, getters/setters, and lifecycle
4
- */
5
-
6
- /**
7
- * Base Component class - all components inherit from this
8
- */
9
- export class Component {
10
- constructor(props = {}) {
11
- // Unique ID for this component instance
12
- this._id = props.id || `bw-${Math.random().toString(36).substring(2, 11)}`;
13
-
14
- // Component state
15
- this._props = { ...props };
16
- this._state = {};
17
- this._children = [];
18
- this._parent = null;
19
- this._domElement = null;
20
- this._mounted = false;
21
-
22
- // Event handlers
23
- this._eventHandlers = new Map();
24
-
25
- // Initialize component
26
- this.initialize();
27
- }
28
-
29
- /**
30
- * Initialize component - override in subclasses
31
- */
32
- initialize() {
33
- // Override in subclasses
34
- }
35
-
36
- /**
37
- * Get component ID
38
- */
39
- get id() {
40
- return this._id;
41
- }
42
-
43
- /**
44
- * Get/set component properties
45
- */
46
- get props() {
47
- return { ...this._props };
48
- }
49
-
50
- setProp(key, value) {
51
- const oldValue = this._props[key];
52
- this._props[key] = value;
53
- this.onPropChange(key, value, oldValue);
54
- if (this._mounted) {
55
- this.update();
56
- }
57
- return this;
58
- }
59
-
60
- /**
61
- * Get/set component state
62
- */
63
- get state() {
64
- return { ...this._state };
65
- }
66
-
67
- setState(updates) {
68
- const oldState = { ...this._state };
69
- this._state = { ...this._state, ...updates };
70
- this.onStateChange(this._state, oldState);
71
- if (this._mounted) {
72
- this.update();
73
- }
74
- return this;
75
- }
76
-
77
- /**
78
- * Get DOM element reference
79
- */
80
- get domElement() {
81
- return this._domElement;
82
- }
83
-
84
- /**
85
- * Get parent component
86
- */
87
- get parent() {
88
- return this._parent;
89
- }
90
-
91
- /**
92
- * Get children components
93
- */
94
- get children() {
95
- return [...this._children];
96
- }
97
-
98
- /**
99
- * Add child component
100
- */
101
- addChild(child) {
102
- if (child instanceof Component) {
103
- child._parent = this;
104
- this._children.push(child);
105
- if (this._mounted) {
106
- this.update();
107
- }
108
- }
109
- return this;
110
- }
111
-
112
- /**
113
- * Remove child component
114
- */
115
- removeChild(child) {
116
- const index = this._children.indexOf(child);
117
- if (index > -1) {
118
- this._children.splice(index, 1);
119
- child._parent = null;
120
- if (this._mounted) {
121
- this.update();
122
- }
123
- }
124
- return this;
125
- }
126
-
127
- /**
128
- * Find child by ID
129
- */
130
- findChild(id) {
131
- for (const child of this._children) {
132
- if (child.id === id) return child;
133
- const found = child.findChild(id);
134
- if (found) return found;
135
- }
136
- return null;
137
- }
138
-
139
- /**
140
- * Add event listener
141
- */
142
- on(event, handler) {
143
- if (!this._eventHandlers.has(event)) {
144
- this._eventHandlers.set(event, []);
145
- }
146
- this._eventHandlers.get(event).push(handler);
147
-
148
- // If already mounted, attach to DOM
149
- if (this._mounted && this._domElement) {
150
- this._domElement.addEventListener(event, handler);
151
- }
152
-
153
- return this;
154
- }
155
-
156
- /**
157
- * Remove event listener
158
- */
159
- off(event, handler) {
160
- if (this._eventHandlers.has(event)) {
161
- const handlers = this._eventHandlers.get(event);
162
- const index = handlers.indexOf(handler);
163
- if (index > -1) {
164
- handlers.splice(index, 1);
165
- if (this._mounted && this._domElement) {
166
- this._domElement.removeEventListener(event, handler);
167
- }
168
- }
169
- }
170
- return this;
171
- }
172
-
173
- /**
174
- * Emit event
175
- */
176
- emit(event, data) {
177
- if (this._eventHandlers.has(event)) {
178
- const handlers = this._eventHandlers.get(event);
179
- handlers.forEach(handler => handler.call(this, data));
180
- }
181
-
182
- // Bubble up to parent
183
- if (this._parent) {
184
- this._parent.emit(`child:${event}`, { child: this, data });
185
- }
186
-
187
- return this;
188
- }
189
-
190
- /**
191
- * Render component to TACO format
192
- * Override this in subclasses
193
- */
194
- render() {
195
- return {
196
- t: 'div',
197
- a: { id: this._id, class: this.getClassName() },
198
- c: this._children.map(child => child.render())
199
- };
200
- }
201
-
202
- /**
203
- * Get component class name
204
- */
205
- getClassName() {
206
- return this._props.className || this._props.class || '';
207
- }
208
-
209
- /**
210
- * Mount component to DOM
211
- */
212
- mount(target) {
213
- // Get target element
214
- const targetEl = typeof target === 'string'
215
- ? document.querySelector(target)
216
- : target;
217
-
218
- if (!targetEl) {
219
- throw new Error(`Cannot mount to target: ${target}`);
220
- }
221
-
222
- // Render and create DOM
223
- const taco = this.render();
224
- this._domElement = window.bw.createDOM(taco);
225
-
226
- // Mount children first
227
- this._mountChildren();
228
-
229
- // Attach event handlers
230
- this._attachEventHandlers();
231
-
232
- // Append to target
233
- targetEl.appendChild(this._domElement);
234
-
235
- // Mark as mounted
236
- this._mounted = true;
237
-
238
- // Call lifecycle method
239
- this.onMount();
240
-
241
- return this;
242
- }
243
-
244
- /**
245
- * Update component in DOM
246
- */
247
- update() {
248
- if (!this._mounted || !this._domElement) return this;
249
-
250
- // Store current DOM element and parent
251
- const oldElement = this._domElement;
252
- const parentElement = oldElement.parentNode;
253
-
254
- // Render new TACO
255
- const taco = this.render();
256
- const newElement = window.bw.createDOM(taco);
257
-
258
- // Replace in DOM
259
- parentElement.replaceChild(newElement, oldElement);
260
- this._domElement = newElement;
261
-
262
- // Remount children
263
- this._mountChildren();
264
-
265
- // Reattach event handlers
266
- this._attachEventHandlers();
267
-
268
- // Call lifecycle method
269
- this.onUpdate();
270
-
271
- return this;
272
- }
273
-
274
- /**
275
- * Unmount component from DOM
276
- */
277
- unmount() {
278
- if (!this._mounted) return this;
279
-
280
- // Call lifecycle method
281
- this.onBeforeUnmount();
282
-
283
- // Unmount children
284
- this._children.forEach(child => child.unmount());
285
-
286
- // Remove from DOM
287
- if (this._domElement && this._domElement.parentNode) {
288
- this._domElement.parentNode.removeChild(this._domElement);
289
- }
290
-
291
- // Clean up
292
- this._domElement = null;
293
- this._mounted = false;
294
-
295
- // Call lifecycle method
296
- this.onUnmount();
297
-
298
- return this;
299
- }
300
-
301
- /**
302
- * Mount children components
303
- * @private
304
- */
305
- _mountChildren() {
306
- // Children should already be rendered in the TACO
307
- // Just need to update their references
308
- this._children.forEach((child, index) => {
309
- const childEl = this._domElement.children[index];
310
- if (childEl) {
311
- child._domElement = childEl;
312
- child._mounted = true;
313
- child._mountChildren();
314
- child._attachEventHandlers();
315
- child.onMount();
316
- }
317
- });
318
- }
319
-
320
- /**
321
- * Attach event handlers to DOM
322
- * @private
323
- */
324
- _attachEventHandlers() {
325
- if (!this._domElement) return;
326
-
327
- this._eventHandlers.forEach((handlers, event) => {
328
- handlers.forEach(handler => {
329
- this._domElement.addEventListener(event, handler);
330
- });
331
- });
332
- }
333
-
334
- /**
335
- * Lifecycle methods - override in subclasses
336
- */
337
- onPropChange(key, newValue, oldValue) {}
338
- onStateChange(newState, oldState) {}
339
- onMount() {}
340
- onUpdate() {}
341
- onBeforeUnmount() {}
342
- onUnmount() {}
343
-
344
- /**
345
- * Utility methods
346
- */
347
- show() {
348
- if (this._domElement) {
349
- this._domElement.style.display = '';
350
- }
351
- return this;
352
- }
353
-
354
- hide() {
355
- if (this._domElement) {
356
- this._domElement.style.display = 'none';
357
- }
358
- return this;
359
- }
360
-
361
- enable() {
362
- if (this._domElement) {
363
- this._domElement.disabled = false;
364
- }
365
- return this;
366
- }
367
-
368
- disable() {
369
- if (this._domElement) {
370
- this._domElement.disabled = true;
371
- }
372
- return this;
373
- }
374
-
375
- focus() {
376
- if (this._domElement && this._domElement.focus) {
377
- this._domElement.focus();
378
- }
379
- return this;
380
- }
381
-
382
- addClass(className) {
383
- if (this._domElement) {
384
- this._domElement.classList.add(className);
385
- }
386
- return this;
387
- }
388
-
389
- removeClass(className) {
390
- if (this._domElement) {
391
- this._domElement.classList.remove(className);
392
- }
393
- return this;
394
- }
395
-
396
- toggleClass(className) {
397
- if (this._domElement) {
398
- this._domElement.classList.toggle(className);
399
- }
400
- return this;
401
- }
402
-
403
- hasClass(className) {
404
- return this._domElement ? this._domElement.classList.contains(className) : false;
405
- }
406
-
407
- css(property, value) {
408
- if (this._domElement) {
409
- if (typeof property === 'object') {
410
- Object.assign(this._domElement.style, property);
411
- } else if (value !== undefined) {
412
- this._domElement.style[property] = value;
413
- } else {
414
- return this._domElement.style[property];
415
- }
416
- }
417
- return this;
418
- }
419
- }
420
-
421
- /**
422
- * Button Component
423
- */
424
- export class Button extends Component {
425
- initialize() {
426
- // Default props
427
- this._props = {
428
- text: 'Button',
429
- variant: 'primary',
430
- size: 'normal',
431
- disabled: false,
432
- ...this._props
433
- };
434
- }
435
-
436
- render() {
437
- const sizeClass = this._props.size === 'lg' ? 'btn-lg' :
438
- this._props.size === 'sm' ? 'btn-sm' : '';
439
-
440
- return {
441
- t: 'button',
442
- a: {
443
- id: this._id,
444
- class: `btn btn-${this._props.variant} ${sizeClass} ${this.getClassName()}`.trim(),
445
- disabled: this._props.disabled
446
- },
447
- c: this._props.text
448
- };
449
- }
450
-
451
- // Button-specific methods
452
- get text() {
453
- return this._props.text;
454
- }
455
-
456
- set text(value) {
457
- this.setProp('text', value);
458
- }
459
-
460
- get variant() {
461
- return this._props.variant;
462
- }
463
-
464
- set variant(value) {
465
- this.setProp('variant', value);
466
- }
467
-
468
- click() {
469
- if (this._domElement && !this._props.disabled) {
470
- this._domElement.click();
471
- }
472
- return this;
473
- }
474
- }
475
-
476
- /**
477
- * Input Component
478
- */
479
- export class Input extends Component {
480
- initialize() {
481
- this._props = {
482
- type: 'text',
483
- value: '',
484
- placeholder: '',
485
- disabled: false,
486
- readonly: false,
487
- ...this._props
488
- };
489
-
490
- // Track internal value
491
- this._value = this._props.value;
492
- }
493
-
494
- render() {
495
- return {
496
- t: 'input',
497
- a: {
498
- id: this._id,
499
- type: this._props.type,
500
- class: `form-control ${this.getClassName()}`.trim(),
501
- value: this._value,
502
- placeholder: this._props.placeholder,
503
- disabled: this._props.disabled,
504
- readonly: this._props.readonly
505
- }
506
- };
507
- }
508
-
509
- onMount() {
510
- // Sync value on input
511
- this.on('input', (e) => {
512
- this._value = e.target.value;
513
- this.emit('change', this._value);
514
- });
515
- }
516
-
517
- // Input-specific methods
518
- get value() {
519
- return this._domElement ? this._domElement.value : this._value;
520
- }
521
-
522
- set value(val) {
523
- this._value = val;
524
- if (this._domElement) {
525
- this._domElement.value = val;
526
- }
527
- }
528
-
529
- clear() {
530
- this.value = '';
531
- return this;
532
- }
533
-
534
- select() {
535
- if (this._domElement && this._domElement.select) {
536
- this._domElement.select();
537
- }
538
- return this;
539
- }
540
- }
541
-
542
- /**
543
- * Card Component
544
- */
545
- export class Card extends Component {
546
- initialize() {
547
- this._props = {
548
- title: '',
549
- text: '',
550
- footer: '',
551
- ...this._props
552
- };
553
- }
554
-
555
- render() {
556
- const children = [];
557
-
558
- if (this._props.title) {
559
- children.push({
560
- t: 'h5',
561
- a: { class: 'card-title' },
562
- c: this._props.title
563
- });
564
- }
565
-
566
- if (this._props.text) {
567
- children.push({
568
- t: 'p',
569
- a: { class: 'card-text' },
570
- c: this._props.text
571
- });
572
- }
573
-
574
- // Add child components
575
- children.push(...this._children.map(child => child.render()));
576
-
577
- const cardBody = {
578
- t: 'div',
579
- a: { class: 'card-body' },
580
- c: children
581
- };
582
-
583
- const cardChildren = [cardBody];
584
-
585
- if (this._props.footer) {
586
- cardChildren.push({
587
- t: 'div',
588
- a: { class: 'card-footer' },
589
- c: this._props.footer
590
- });
591
- }
592
-
593
- return {
594
- t: 'div',
595
- a: {
596
- id: this._id,
597
- class: `card ${this.getClassName()}`.trim()
598
- },
599
- c: cardChildren
600
- };
601
- }
602
-
603
- // Card-specific methods
604
- get title() {
605
- return this._props.title;
606
- }
607
-
608
- set title(value) {
609
- this.setProp('title', value);
610
- }
611
-
612
- get text() {
613
- return this._props.text;
614
- }
615
-
616
- set text(value) {
617
- this.setProp('text', value);
618
- }
619
- }
620
-
621
- /**
622
- * Container Component
623
- */
624
- export class Container extends Component {
625
- initialize() {
626
- this._props = {
627
- fluid: false,
628
- ...this._props
629
- };
630
- }
631
-
632
- render() {
633
- const containerClass = this._props.fluid ? 'container-fluid' : 'container';
634
-
635
- return {
636
- t: 'div',
637
- a: {
638
- id: this._id,
639
- class: `${containerClass} ${this.getClassName()}`.trim()
640
- },
641
- c: this._children.map(child => child.render())
642
- };
643
- }
644
- }
645
-
646
- /**
647
- * Progress Bar Component
648
- */
649
- export class ProgressBar extends Component {
650
- initialize() {
651
- this._props = {
652
- value: 0,
653
- max: 100,
654
- variant: 'primary',
655
- striped: false,
656
- animated: false,
657
- showLabel: false,
658
- ...this._props
659
- };
660
- }
661
-
662
- render() {
663
- const percentage = (this._props.value / this._props.max) * 100;
664
- const barClasses = [
665
- 'progress-bar',
666
- `bg-${this._props.variant}`,
667
- this._props.striped && 'progress-bar-striped',
668
- this._props.animated && 'progress-bar-animated'
669
- ].filter(Boolean).join(' ');
670
-
671
- return {
672
- t: 'div',
673
- a: {
674
- id: this._id,
675
- class: `progress ${this.getClassName()}`.trim()
676
- },
677
- c: {
678
- t: 'div',
679
- a: {
680
- class: barClasses,
681
- role: 'progressbar',
682
- style: `width: ${percentage}%`,
683
- 'aria-valuenow': this._props.value,
684
- 'aria-valuemin': 0,
685
- 'aria-valuemax': this._props.max
686
- },
687
- c: this._props.showLabel ? `${Math.round(percentage)}%` : ''
688
- }
689
- };
690
- }
691
-
692
- // Progress-specific methods
693
- get value() {
694
- return this._props.value;
695
- }
696
-
697
- set value(val) {
698
- this.setProp('value', Math.max(0, Math.min(val, this._props.max)));
699
- }
700
-
701
- get percentage() {
702
- return (this._props.value / this._props.max) * 100;
703
- }
704
-
705
- increment(amount = 1) {
706
- this.value = this._props.value + amount;
707
- return this;
708
- }
709
-
710
- decrement(amount = 1) {
711
- this.value = this._props.value - amount;
712
- return this;
713
- }
714
-
715
- reset() {
716
- this.value = 0;
717
- return this;
718
- }
719
-
720
- complete() {
721
- this.value = this._props.max;
722
- return this;
723
- }
724
- }
725
-
726
- /**
727
- * Export to global bw namespace
728
- */
729
- if (typeof window !== 'undefined' && window.bw) {
730
- window.bw.Component = Component;
731
- window.bw.Button = Button;
732
- window.bw.Input = Input;
733
- window.bw.Card = Card;
734
- window.bw.Container = Container;
735
- window.bw.ProgressBar = ProgressBar;
736
- }