bitwrench 2.0.14 → 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 (45) hide show
  1. package/dist/bitwrench-code-edit.cjs.js +46 -46
  2. package/dist/bitwrench-code-edit.cjs.min.js +16 -0
  3. package/dist/bitwrench-code-edit.es5.js +8 -8
  4. package/dist/bitwrench-code-edit.es5.min.js +2 -2
  5. package/dist/bitwrench-code-edit.esm.js +46 -46
  6. package/dist/bitwrench-code-edit.esm.min.js +2 -2
  7. package/dist/bitwrench-code-edit.umd.js +46 -46
  8. package/dist/bitwrench-code-edit.umd.min.js +2 -2
  9. package/dist/bitwrench-lean.cjs.js +4551 -3272
  10. package/dist/bitwrench-lean.cjs.min.js +35 -6
  11. package/dist/bitwrench-lean.es5.js +5747 -4414
  12. package/dist/bitwrench-lean.es5.min.js +32 -3
  13. package/dist/bitwrench-lean.esm.js +4551 -3272
  14. package/dist/bitwrench-lean.esm.min.js +35 -6
  15. package/dist/bitwrench-lean.umd.js +4551 -3272
  16. package/dist/bitwrench-lean.umd.min.js +35 -6
  17. package/dist/bitwrench.cjs.js +4739 -3720
  18. package/dist/bitwrench.cjs.min.js +38 -8
  19. package/dist/bitwrench.css +2253 -6041
  20. package/dist/bitwrench.es5.js +6234 -5130
  21. package/dist/bitwrench.es5.min.js +34 -5
  22. package/dist/bitwrench.esm.js +4739 -3720
  23. package/dist/bitwrench.esm.min.js +38 -8
  24. package/dist/bitwrench.min.css +1 -0
  25. package/dist/bitwrench.umd.js +4739 -3720
  26. package/dist/bitwrench.umd.min.js +38 -8
  27. package/dist/builds.json +89 -67
  28. package/dist/sri.json +28 -26
  29. package/package.json +7 -5
  30. package/readme.html +10 -10
  31. package/src/{bitwrench-components-v2.js → bitwrench-bccl.js} +396 -647
  32. package/src/bitwrench-code-edit.js +45 -45
  33. package/src/bitwrench-color-utils.js +25 -18
  34. package/src/bitwrench-components-stub.js +4 -1
  35. package/src/bitwrench-file-ops.js +180 -0
  36. package/src/bitwrench-lean.js +2 -2
  37. package/src/bitwrench-styles.js +1275 -4029
  38. package/src/bitwrench-utils.js +458 -0
  39. package/src/bitwrench.js +1686 -1293
  40. package/src/cli/layout-default.js +18 -18
  41. package/src/generate-css.js +73 -53
  42. package/src/version.js +3 -3
  43. package/src/bitwrench-component-base.js +0 -736
  44. package/src/bitwrench-components-inline.js +0 -374
  45. package/src/bitwrench-components.js +0 -610
@@ -14,53 +14,53 @@
14
14
  // -- CSS (injected once) ----------------------------------------------
15
15
  var _cssInjected = false;
16
16
  var CSS_TEXT =
17
- '.bw-ce{background:#1e293b;border-radius:6px;border:1px solid rgba(255,255,255,0.08);overflow:auto}' +
18
- '.bw-ce pre{margin:0;padding:0}' +
19
- '.bw-ce code{font-family:"SF Mono",Monaco,"Cascadia Code",Consolas,monospace;font-size:0.875rem;line-height:1.6;color:#e2e8f0;outline:none;white-space:pre-wrap;display:block;padding:0.75rem 1rem}' +
20
- '.bw-ce code:empty::before{content:"\\200b"}' +
21
- '.bw-ce .bw-ce-keyword{color:#c792ea}' +
22
- '.bw-ce .bw-ce-string{color:#c3e88d}' +
23
- '.bw-ce .bw-ce-comment{color:#546e7a;font-style:italic}' +
24
- '.bw-ce .bw-ce-number{color:#f78c6c}' +
25
- '.bw-ce .bw-ce-operator{color:#89ddff}' +
26
- '.bw-ce .bw-ce-punctuation{color:#89ddff}' +
27
- '.bw-ce .bw-ce-property{color:#82aaff}' +
28
- '.bw-ce .bw-ce-function{color:#82aaff}' +
29
- '.bw-ce .bw-ce-tag{color:#f07178}' +
30
- '.bw-ce .bw-ce-attr-name{color:#ffcb6b}' +
31
- '.bw-ce .bw-ce-attr-value{color:#c3e88d}' +
32
- '.bw-ce .bw-ce-selector{color:#c792ea}' +
33
- '.bw-ce .bw-ce-css-prop{color:#82aaff}' +
34
- '.bw-ce .bw-ce-css-value{color:#f78c6c}' +
35
- '.bw-ce .bw-ce-at-rule{color:#c792ea;font-style:italic}' +
36
- '.bw-ce .bw-ce-color{color:#f78c6c}' +
37
- '.bw-ce .bw-ce-template-interp{color:#89ddff}' +
17
+ '.bw_ce{background:#1e293b;border-radius:6px;border:1px solid rgba(255,255,255,0.08);overflow:auto}' +
18
+ '.bw_ce pre{margin:0;padding:0}' +
19
+ '.bw_ce code{font-family:"SF Mono",Monaco,"Cascadia Code",Consolas,monospace;font-size:0.875rem;line-height:1.6;color:#e2e8f0;outline:none;white-space:pre-wrap;display:block;padding:0.75rem 1rem}' +
20
+ '.bw_ce code:empty::before{content:"\\200b"}' +
21
+ '.bw_ce .bw_ce_keyword{color:#c792ea}' +
22
+ '.bw_ce .bw_ce_string{color:#c3e88d}' +
23
+ '.bw_ce .bw_ce_comment{color:#546e7a;font-style:italic}' +
24
+ '.bw_ce .bw_ce_number{color:#f78c6c}' +
25
+ '.bw_ce .bw_ce_operator{color:#89ddff}' +
26
+ '.bw_ce .bw_ce_punctuation{color:#89ddff}' +
27
+ '.bw_ce .bw_ce_property{color:#82aaff}' +
28
+ '.bw_ce .bw_ce_function{color:#82aaff}' +
29
+ '.bw_ce .bw_ce_tag{color:#f07178}' +
30
+ '.bw_ce .bw_ce_attr_name{color:#ffcb6b}' +
31
+ '.bw_ce .bw_ce_attr_value{color:#c3e88d}' +
32
+ '.bw_ce .bw_ce_selector{color:#c792ea}' +
33
+ '.bw_ce .bw_ce_css_prop{color:#82aaff}' +
34
+ '.bw_ce .bw_ce_css_value{color:#f78c6c}' +
35
+ '.bw_ce .bw_ce_at_rule{color:#c792ea;font-style:italic}' +
36
+ '.bw_ce .bw_ce_color{color:#f78c6c}' +
37
+ '.bw_ce .bw_ce_template_interp{color:#89ddff}' +
38
38
  // Light theme
39
- '.bw-ce-light.bw-ce{background:#fafafa;border-color:#d8d8d8}' +
40
- '.bw-ce-light.bw-ce code{color:#1a1a1a}' +
41
- '.bw-ce-light.bw-ce .bw-ce-keyword{color:#7c3aed}' +
42
- '.bw-ce-light.bw-ce .bw-ce-string{color:#16a34a}' +
43
- '.bw-ce-light.bw-ce .bw-ce-comment{color:#9ca3af;font-style:italic}' +
44
- '.bw-ce-light.bw-ce .bw-ce-number{color:#ea580c}' +
45
- '.bw-ce-light.bw-ce .bw-ce-operator{color:#0891b2}' +
46
- '.bw-ce-light.bw-ce .bw-ce-punctuation{color:#6b7280}' +
47
- '.bw-ce-light.bw-ce .bw-ce-property{color:#2563eb}' +
48
- '.bw-ce-light.bw-ce .bw-ce-function{color:#2563eb}' +
49
- '.bw-ce-light.bw-ce .bw-ce-tag{color:#dc2626}' +
50
- '.bw-ce-light.bw-ce .bw-ce-attr-name{color:#d97706}' +
51
- '.bw-ce-light.bw-ce .bw-ce-attr-value{color:#16a34a}' +
52
- '.bw-ce-light.bw-ce .bw-ce-selector{color:#7c3aed}' +
53
- '.bw-ce-light.bw-ce .bw-ce-css-prop{color:#2563eb}' +
54
- '.bw-ce-light.bw-ce .bw-ce-css-value{color:#ea580c}' +
55
- '.bw-ce-light.bw-ce .bw-ce-at-rule{color:#7c3aed}' +
56
- '.bw-ce-light.bw-ce .bw-ce-color{color:#ea580c}' +
57
- '.bw-ce-light.bw-ce .bw-ce-template-interp{color:#0891b2}';
39
+ '.bw_ce_light.bw_ce{background:#fafafa;border-color:#d8d8d8}' +
40
+ '.bw_ce_light.bw_ce code{color:#1a1a1a}' +
41
+ '.bw_ce_light.bw_ce .bw_ce_keyword{color:#7c3aed}' +
42
+ '.bw_ce_light.bw_ce .bw_ce_string{color:#16a34a}' +
43
+ '.bw_ce_light.bw_ce .bw_ce_comment{color:#9ca3af;font-style:italic}' +
44
+ '.bw_ce_light.bw_ce .bw_ce_number{color:#ea580c}' +
45
+ '.bw_ce_light.bw_ce .bw_ce_operator{color:#0891b2}' +
46
+ '.bw_ce_light.bw_ce .bw_ce_punctuation{color:#6b7280}' +
47
+ '.bw_ce_light.bw_ce .bw_ce_property{color:#2563eb}' +
48
+ '.bw_ce_light.bw_ce .bw_ce_function{color:#2563eb}' +
49
+ '.bw_ce_light.bw_ce .bw_ce_tag{color:#dc2626}' +
50
+ '.bw_ce_light.bw_ce .bw_ce_attr_name{color:#d97706}' +
51
+ '.bw_ce_light.bw_ce .bw_ce_attr_value{color:#16a34a}' +
52
+ '.bw_ce_light.bw_ce .bw_ce_selector{color:#7c3aed}' +
53
+ '.bw_ce_light.bw_ce .bw_ce_css_prop{color:#2563eb}' +
54
+ '.bw_ce_light.bw_ce .bw_ce_css_value{color:#ea580c}' +
55
+ '.bw_ce_light.bw_ce .bw_ce_at_rule{color:#7c3aed}' +
56
+ '.bw_ce_light.bw_ce .bw_ce_color{color:#ea580c}' +
57
+ '.bw_ce_light.bw_ce .bw_ce_template_interp{color:#0891b2}';
58
58
 
59
59
  function ensureCSS(bw) {
60
60
  if (_cssInjected) return;
61
61
  _cssInjected = true;
62
62
  if (bw && bw.injectCSS) {
63
- bw.injectCSS(CSS_TEXT, { id: 'bw-code-edit-styles' });
63
+ bw.injectCSS(CSS_TEXT, { id: 'bw_code_edit_styles' });
64
64
  }
65
65
  }
66
66
 
@@ -483,7 +483,7 @@ function tokensToTACO(tokArr) {
483
483
  if (tok.type === 'plain') {
484
484
  result.push(tok.text);
485
485
  } else {
486
- result.push({ t: 'span', a: { class: 'bw-ce-' + tok.type }, c: tok.text });
486
+ result.push({ t: 'span', a: { class: 'bw_ce_' + tok.type }, c: tok.text });
487
487
  }
488
488
  }
489
489
  return result;
@@ -537,13 +537,13 @@ function codeEditor(opts) {
537
537
  var lang = opts.lang || 'js';
538
538
  var height = opts.height || '180px';
539
539
  var readOnly = !!opts.readOnly;
540
- var className = 'bw-ce' + (opts.className ? ' ' + opts.className : '');
540
+ var className = 'bw_ce' + (opts.className ? ' ' + opts.className : '');
541
541
 
542
542
  var highlighted = highlight(code, lang);
543
543
 
544
544
  var codeAttrs = {
545
545
  spellcheck: 'false',
546
- class: 'bw-ce-code'
546
+ class: 'bw_ce_code'
547
547
  };
548
548
  if (!readOnly) {
549
549
  codeAttrs.contenteditable = 'true';
@@ -557,7 +557,7 @@ function codeEditor(opts) {
557
557
  ],
558
558
  o: {
559
559
  mounted: function(el) {
560
- var codeEl = el.querySelector('.bw-ce-code');
560
+ var codeEl = el.querySelector('.bw_ce_code');
561
561
  if (!codeEl) return;
562
562
 
563
563
  var currentCode = code;
@@ -6,9 +6,13 @@
6
6
  * bw.colorParse, bw.colorRgbToHsl, etc.
7
7
  *
8
8
  * @module bitwrench-color-utils
9
- * @license BSD-2-Clause
9
+ * @license BSD-2-Clause
10
+ * @copy Manu Chatterjee @deftio
10
11
  */
11
12
 
13
+ function _xs (x) {
14
+ return ('0' + x.toString(16)).slice(-2)
15
+ }
12
16
  /**
13
17
  * Clamp a value between min and max.
14
18
  * @param {number} val
@@ -200,10 +204,7 @@ export function hexToHsl(hex) {
200
204
  */
201
205
  export function hslToHex(hsl) {
202
206
  var rgb = colorHslToRgb(hsl[0], hsl[1], hsl[2], 255, true);
203
- return '#' +
204
- ('0' + rgb[0].toString(16)).slice(-2) +
205
- ('0' + rgb[1].toString(16)).slice(-2) +
206
- ('0' + rgb[2].toString(16)).slice(-2);
207
+ return '#' + _xs(rgb[0])+_xs(rgb[1])+_xs(rgb[2]);
207
208
  }
208
209
 
209
210
  /**
@@ -232,10 +233,7 @@ export function mixColor(hex1, hex2, ratio) {
232
233
  var r = Math.round(c1[0] + (c2[0] - c1[0]) * ratio);
233
234
  var g = Math.round(c1[1] + (c2[1] - c1[1]) * ratio);
234
235
  var b = Math.round(c1[2] + (c2[2] - c1[2]) * ratio);
235
- return '#' +
236
- ('0' + r.toString(16)).slice(-2) +
237
- ('0' + g.toString(16)).slice(-2) +
238
- ('0' + b.toString(16)).slice(-2);
236
+ return '#' + _xs(r) + _xs(g) + _xs(b);
239
237
  }
240
238
 
241
239
  /**
@@ -415,16 +413,25 @@ export function derivePalette(config) {
415
413
  var lightBase = config.light || hslToHex([h, 8, 97]);
416
414
  var darkBase = config.dark || hslToHex([h, 10, 13]);
417
415
 
416
+ // Background & surface tokens — default to light (white/near-white).
417
+ // Dark backgrounds require explicit config.background / config.surface.
418
+ // Primary/secondary colors are accents, not page backgrounds, so
419
+ // isLightPalette should NOT drive bg/surface defaults.
420
+ var bgBase = config.background || '#ffffff';
421
+ var surfBase = config.surface || '#f8f9fa';
422
+
418
423
  var palette = {
419
- primary: deriveShades(config.primary),
420
- secondary: deriveShades(config.secondary),
421
- tertiary: deriveShades(config.tertiary),
422
- success: deriveShades(successBase),
423
- danger: deriveShades(dangerBase),
424
- warning: deriveShades(warningBase),
425
- info: deriveShades(infoBase),
426
- light: deriveShades(lightBase),
427
- dark: deriveShades(darkBase)
424
+ primary: deriveShades(config.primary),
425
+ secondary: deriveShades(config.secondary),
426
+ tertiary: deriveShades(config.tertiary),
427
+ success: deriveShades(successBase),
428
+ danger: deriveShades(dangerBase),
429
+ warning: deriveShades(warningBase),
430
+ info: deriveShades(infoBase),
431
+ light: deriveShades(lightBase),
432
+ dark: deriveShades(darkBase),
433
+ background: bgBase,
434
+ surface: surfBase
428
435
  };
429
436
 
430
437
  return palette;
@@ -1,5 +1,8 @@
1
1
  /**
2
- * Empty stub for bitwrench-components-v2.js.
2
+ * Empty stub for bitwrench-bccl.js.
3
3
  * Used by the lean build to exclude all BCCL component code.
4
4
  */
5
5
  export const componentHandles = {};
6
+ export function variantClass() { return ''; }
7
+ export var BCCL = {};
8
+ export function make() { throw new Error('bw.make() requires the full bitwrench build (not lean)'); }
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Bitwrench v2 File I/O Functions
3
+ *
4
+ * Save/load files in both Node.js and browser environments.
5
+ * Node uses fs module, browser uses Blob/XHR/FileReader.
6
+ *
7
+ * Called via bindFileOps(bw) which attaches all functions to the bw namespace.
8
+ * This preserves the same public API (bw.saveClientFile, bw.loadClientFile, etc.)
9
+ * while keeping the implementation in a separate module.
10
+ *
11
+ * @module bitwrench-file-ops
12
+ * @license BSD-2-Clause
13
+ * @author M A Chatterjee <deftio [at] deftio [dot] com>
14
+ */
15
+
16
+ /**
17
+ * Attach all file I/O functions to the bitwrench namespace.
18
+ *
19
+ * @param {Object} bw - Bitwrench namespace object
20
+ */
21
+ export function bindFileOps(bw) {
22
+
23
+ /**
24
+ * Save data to a file. Works in both Node.js (fs.writeFile) and browser (download link).
25
+ *
26
+ * @param {string} fname - Filename to save as
27
+ * @param {*} data - Data to save (string or buffer)
28
+ * @category File I/O
29
+ */
30
+ bw.saveClientFile = function(fname, data) {
31
+ if (bw.isNodeJS()) {
32
+ bw._getFs().then(function(fs) {
33
+ if (!fs) { console.error('bw.saveClientFile: fs module not available'); return; }
34
+ fs.writeFile(fname, data, function(err) {
35
+ if (err) {
36
+ console.error("Error saving file:", err);
37
+ }
38
+ });
39
+ });
40
+ } else {
41
+ var blob = new Blob([data], { type: "application/octet-stream" });
42
+ var url = window.URL.createObjectURL(blob);
43
+ var a = bw.createDOM({
44
+ t: 'a',
45
+ a: {
46
+ href: url,
47
+ download: fname,
48
+ style: 'display: none'
49
+ }
50
+ });
51
+ document.body.appendChild(a);
52
+ a.click();
53
+ window.URL.revokeObjectURL(url);
54
+ document.body.removeChild(a);
55
+ }
56
+ };
57
+
58
+ /**
59
+ * Save data as a JSON file with pretty formatting.
60
+ *
61
+ * @param {string} fname - Filename to save as
62
+ * @param {*} data - Data to serialize as JSON
63
+ * @category File I/O
64
+ */
65
+ bw.saveClientJSON = function(fname, data) {
66
+ bw.saveClientFile(fname, JSON.stringify(data, null, 2));
67
+ };
68
+
69
+ /**
70
+ * Load a file by path (Node.js) or URL (browser via XHR).
71
+ *
72
+ * @param {string} fname - File path (Node) or URL (browser)
73
+ * @param {Function} callback - Called with (data, error). data is null on error.
74
+ * @param {Object} [options] - Options
75
+ * @param {string} [options.parser="raw"] - "raw" for string, "JSON" to auto-parse
76
+ * @returns {string} "BW_OK"
77
+ * @category File I/O
78
+ */
79
+ bw.loadClientFile = function(fname, callback, options) {
80
+ var opts = { parser: 'raw' };
81
+ if (options && options.parser) { opts.parser = options.parser; }
82
+ var parse = (opts.parser === 'JSON') ? JSON.parse : function(s) { return s; };
83
+
84
+ if (bw.isNodeJS()) {
85
+ bw._getFs().then(function(fs) {
86
+ if (!fs) { callback(null, new Error('fs module not available')); return; }
87
+ fs.readFile(fname, 'utf8', function(err, data) {
88
+ if (err) { callback(null, err); }
89
+ else {
90
+ try { callback(parse(data), null); }
91
+ catch (e) { callback(null, e); }
92
+ }
93
+ });
94
+ });
95
+ } else {
96
+ var x = new XMLHttpRequest();
97
+ x.open('GET', fname, true);
98
+ x.onreadystatechange = function() {
99
+ if (x.readyState === 4) {
100
+ if (x.status >= 200 && x.status < 300) {
101
+ try { callback(parse(x.responseText), null); }
102
+ catch (e) { callback(null, e); }
103
+ } else {
104
+ callback(null, new Error('HTTP ' + x.status + ': ' + fname));
105
+ }
106
+ }
107
+ };
108
+ x.send(null);
109
+ }
110
+ return 'BW_OK';
111
+ };
112
+
113
+ /**
114
+ * Load a JSON file by path (Node.js) or URL (browser).
115
+ *
116
+ * @param {string} fname - File path (Node) or URL (browser)
117
+ * @param {Function} callback - Called with (parsedData, error)
118
+ * @returns {string} "BW_OK"
119
+ * @category File I/O
120
+ */
121
+ bw.loadClientJSON = function(fname, callback) {
122
+ return bw.loadClientFile(fname, callback, { parser: 'JSON' });
123
+ };
124
+
125
+ /**
126
+ * Prompt user to pick a local file via file dialog (browser only).
127
+ *
128
+ * @param {Function} callback - Called with (data, filename, error)
129
+ * @param {Object} [options] - Options
130
+ * @param {string} [options.accept] - File type filter (e.g. ".json,.txt")
131
+ * @param {string} [options.parser="raw"] - "raw" for string, "JSON" to auto-parse
132
+ * @category File I/O
133
+ */
134
+ bw.loadLocalFile = function(callback, options) {
135
+ var opts = { parser: 'raw', accept: '' };
136
+ if (options) {
137
+ if (options.parser) { opts.parser = options.parser; }
138
+ if (options.accept) { opts.accept = options.accept; }
139
+ }
140
+ var parse = (opts.parser === 'JSON') ? JSON.parse : function(s) { return s; };
141
+
142
+ if (bw.isNodeJS()) {
143
+ callback(null, '', new Error('bw.loadLocalFile is browser-only. Use bw.loadClientFile() in Node.'));
144
+ return;
145
+ }
146
+
147
+ var input = bw.createDOM({
148
+ t: 'input',
149
+ a: {
150
+ type: 'file',
151
+ accept: opts.accept,
152
+ style: 'display: none'
153
+ }
154
+ });
155
+ input.addEventListener('change', function() {
156
+ var file = input.files[0];
157
+ if (!file) { callback(null, '', new Error('No file selected')); return; }
158
+ var reader = new FileReader();
159
+ reader.onload = function(e) {
160
+ try { callback(parse(e.target.result), file.name, null); }
161
+ catch (err) { callback(null, file.name, err); }
162
+ };
163
+ reader.onerror = function() { callback(null, file.name, reader.error); };
164
+ reader.readAsText(file);
165
+ input.remove();
166
+ });
167
+ document.body.appendChild(input);
168
+ input.click();
169
+ };
170
+
171
+ /**
172
+ * Prompt user to pick a local JSON file via file dialog (browser only).
173
+ *
174
+ * @param {Function} callback - Called with (parsedData, filename, error)
175
+ * @category File I/O
176
+ */
177
+ bw.loadLocalJSON = function(callback) {
178
+ bw.loadLocalFile(callback, { parser: 'JSON', accept: '.json' });
179
+ };
180
+ }
@@ -2,13 +2,13 @@
2
2
  * bitwrench-lean.js — Entry point for the lean build.
3
3
  *
4
4
  * This is identical to bitwrench.js but the Rollup config redirects
5
- * the bitwrench-components-v2.js import to an empty stub, so no
5
+ * the bitwrench-bccl.js import to an empty stub, so no
6
6
  * BCCL component code is included in the output.
7
7
  *
8
8
  * Includes: HTML/DOM generation, CSS generation, color utilities,
9
9
  * state management, pub/sub, file I/O, random/lorem,
10
10
  * cookies, URL params, logging, makeTable, makeDataTable.
11
- * Excludes: All make* component helpers from bitwrench-components-v2.js
11
+ * Excludes: All make* component helpers from bitwrench-bccl.js
12
12
  * (makeButton, makeCard, makeAlert, makeTabs, etc.)
13
13
  */
14
14
  export { default } from './bitwrench.js';