@toheeb/base 2.0.1 → 3.0.0-alpha.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/src/index.js ADDED
@@ -0,0 +1,32 @@
1
+ import './index.css';
2
+ import { init_tabs } from "./components/tabs.js";
3
+ import { init_enclosure } from "./components/enclosure.js";
4
+ import * as utils from './utils.js';
5
+
6
+ const COMPONENT_REGISTRY = {
7
+ "data-base-tabs": init_tabs,
8
+ 'data-base-enclosure': init_enclosure,
9
+ }
10
+
11
+ export const base = {
12
+
13
+ utils: utils,
14
+ init_all(root = document) {
15
+ Object.entries(COMPONENT_REGISTRY).forEach(([selector, init_function]) => {
16
+ root.querySelectorAll(`[${selector}]`).forEach(el => {
17
+ if (el.dataset.baseEnhanced === 'true') return;
18
+
19
+ try {
20
+ init_function(el);
21
+ el.dataset.baseEnhanced = 'true';
22
+ } catch (e) {
23
+ console.error(e);
24
+ }
25
+ })
26
+ })
27
+ }
28
+ };
29
+
30
+ if (typeof window !== 'undefined') {
31
+ window.base = base;
32
+ }
@@ -0,0 +1,76 @@
1
+
2
+ // export function matchContainer(component, query, callback) {
3
+ // // query in rem for relativeness, but calculation in pixels for fine grain checks
4
+
5
+ // let matching = null;
6
+ // let matches = false;
7
+ // const range_query = query.replace(/\s+/g, '').match(/^([\d.]+)rem<=(width)<=([\d.]+)rem$/);
8
+ // const single_query = query.replace(/\s+/g, '').match(/^width(>=|<=)([\d.]+)rem$/);
9
+ // const root_font_size = parseFloat(window.getComputedStyle(document.documentElement).fontSize) || 16;
10
+
11
+ // const observer = new ResizeObserver((entries) => {
12
+
13
+ // for (let entry of entries) {
14
+ // const current_width = entry.contentBoxSize[0]
15
+ // ? entry.contentBoxSize[0].inlineSize
16
+ // : entry.contentRect.width;
17
+
18
+ // if (range_query) {
19
+ // const min_width = parseFloat(range_query[1]) * root_font_size;
20
+ // const max_width = parseFloat(range_query[3]) * root_font_size;
21
+
22
+ // matches = current_width >= min_width && current_width <= max_width;
23
+
24
+ // } else if (single_query) {
25
+ // const operator = single_query[1];
26
+ // const bound = parseFloat(single_query[2]) * root_font_size;
27
+
28
+ // matches = operator === '>=' ? current_width >= bound : current_width <= bound;
29
+
30
+ // } else {
31
+ // console.warn(`invalid query syntaxL "${query}"`);
32
+ // return;
33
+ // }
34
+
35
+ // if (matches !== matching) {
36
+ // matching = matches;
37
+ // callback({matches, current_width});
38
+ // }
39
+ // }
40
+ // });
41
+
42
+ // observer.observe(component);
43
+ // return () => observer.unobserve(element);
44
+ // }
45
+
46
+ export function matchContainer(element, remValue, callback) {
47
+ let wasMatching = null;
48
+
49
+ const observer = new ResizeObserver((entries) => {
50
+ // 1. Query the live computed pixel size of 1rem from the html root element
51
+ const rootFontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
52
+
53
+ // 2. Convert your target rem value into a relative pixel threshold
54
+ const pixelThreshold = remValue * rootFontSize;
55
+
56
+ for (let entry of entries) {
57
+ // 3. Read the current internal layout width of the container
58
+ const currentWidth = entry.contentBoxSize[0]
59
+ ? entry.contentBoxSize[0].inlineSize
60
+ : entry.contentRect.width;
61
+
62
+ // 4. Evaluate the match condition against the dynamic pixel line
63
+ const matches = currentWidth <= pixelThreshold;
64
+
65
+ // 5. Fire the callback only when the boolean state flips
66
+ if (matches !== wasMatching) {
67
+ wasMatching = matches;
68
+ callback({ matches, currentPixelThreshold: pixelThreshold });
69
+ }
70
+ }
71
+ });
72
+
73
+ observer.observe(element);
74
+ return () => observer.unobserve(element);
75
+
76
+ }
package/src/utils.js ADDED
@@ -0,0 +1,2 @@
1
+ export { matchContainer } from './utils/match-container.js';
2
+
package/vite.config.js ADDED
@@ -0,0 +1,34 @@
1
+ import { defineConfig } from 'vite'
2
+ import { resolve } from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import { Features } from 'lightningcss' // 1. Import the Feature flags from Lightning CSS
5
+
6
+ const __dirname = fileURLToPath(new URL('.', import.meta.url))
7
+
8
+ export default defineConfig({
9
+ css: {
10
+ lightningcss: {
11
+ // 2. Explicitly tell Lightning CSS NOT to transpile or alter light-dark() functions
12
+ exclude: Features.LightDark
13
+ }
14
+ },
15
+ build: {
16
+ emptyOutDir: true,
17
+ lib: {
18
+ entry: resolve(__dirname, 'src/index.js'),
19
+ name: '@toheeb/base',
20
+ fileName: 'base',
21
+ formats: ['es', 'umd']
22
+ },
23
+
24
+ // Enable Source Maps so you can trace minified bugs back to index.js / index.css
25
+ sourcemap: true,
26
+
27
+ rollupOptions: {
28
+ external: [],
29
+ output: {
30
+ globals: {}
31
+ }
32
+ }
33
+ }
34
+ })
package/base-settings.js DELETED
@@ -1,472 +0,0 @@
1
- class BaseSettings extends HTMLElement {
2
- constructor() {
3
- super();
4
- }
5
-
6
- connectedCallback() {
7
- this.innerHTML = `
8
- <dialog class="_bs">
9
- <main>
10
- <form id="base-form" method="dialog" novalidate>
11
- <p>
12
- <button type="submit">
13
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
14
- </button>
15
- </p>
16
- <p class="modes">
17
- <label>
18
- <input type="checkbox" id="base-mode-doc">
19
- <span>Doc Mode</span>
20
- </label>
21
- <label>
22
- <input type="checkbox" id="base-mode-indent">
23
- <span>Indent Mode</span>
24
- </label>
25
- </p>
26
- <p class="fields">
27
- <label>
28
- <span>Font Family</span>
29
- <input type="text" id="base-font-family" list="typefaces">
30
- <datalist id="typefaces">
31
- <option value="serif">Serif</option>
32
- <option value="cursive">Cursive</option>
33
- <option value="sans-serif">Sans Serif</option>
34
- <option value="system-ui">System UI</option>
35
- <option value="monospace">Monospace</option>
36
- </datalist>
37
-
38
- </label>
39
- <label>
40
- <span>Font Size</span>
41
- <input type="number" id="base-font-size" step=".0625">
42
- </label>
43
- <label>
44
- <span>Font Scale</span>
45
- <select id="base-font-scale">
46
- <option value="1.067">Minor Second</option>
47
- <option value="1.125">Major Second</option>
48
- <option value="1.2">Minor Third</option>
49
- <option value="1.25">Major Third</option>
50
- <option value="1.333">Perfect Fourth</option>
51
- <option value="1.414">Augmented Fourth</option>
52
- <option value="1.5">Perfect Fifth</option>
53
- <option value="1.618">Golden Ratio</option>
54
- </select>
55
- </label>
56
- </p>
57
- <p class="fields">
58
- <label>
59
- <span>Line Height</span>
60
- <input type="number" id="base-line-height" step=".0625">
61
- </label>
62
- <label>
63
- <span>Line Length</span>
64
- <input type="number" id="base-line-length">
65
- </label>
66
- <label>
67
- <span>Block Gap</span>
68
- <input type="number" id="base-block-gap" step=".0625">
69
- </label>
70
- </p>
71
- <p class="fields">
72
- <label>
73
- <span>Color Scheme</span>
74
- <select id="base-color-scheme">
75
- <option value="">Browser</option>
76
- <option value="light">Light</option>
77
- <option value="dark">Dark</option>
78
- </select>
79
- </label>
80
- <label>
81
- <span>Color Hue</span>
82
- <input type="number" id="base-color-hue" min="0" max="360" step="1">
83
- </label>
84
- </p>
85
- </form>
86
- </main>
87
- </dialog>
88
- <style>
89
- :where(._bs) {
90
- box-shadow:
91
- -0px -0px 1px oklch(from currentColor l c h / .01),
92
- -2px -2px 3px oklch(from currentColor l c h / .03),
93
- -4px -4px 7px oklch(from currentColor l c h / .05)
94
- ;
95
- margin: auto 0 0 auto;
96
- max-width: 20em;
97
- border: 1px solid;
98
- border-color: oklch(from currentColor l c h / .5);
99
- inset-block-end: 16px;
100
- inset-inline-end: 16px;
101
- border-radius: 1em;
102
- }
103
-
104
- @supports
105
- (color: oklch(0 0 0)) and
106
- (color: light-dark(#000, #fff))
107
- {
108
- :where(._bs) {
109
- background-color: light-dark(
110
- oklch(1 0.003 var(--base-color-hue)),
111
- oklch(0.22 .03 var(--base-color-hue))
112
- );
113
- }
114
- }
115
-
116
- :where(dialog::backdrop) {
117
- background: transparent;
118
- }
119
-
120
- :where(._bs button[type=submit]) {
121
- display: flex;
122
- justify-content: center;
123
- align-items: center;
124
- border: 0;
125
- margin: auto;
126
- padding: .25em;
127
- }
128
-
129
- :where(._bs form) {
130
- display: grid;
131
- width: 100%;
132
- gap: calc(.5 * var(--bbg));
133
- }
134
-
135
- :where(._bs p) {
136
- width: 100%;
137
- display: flex;
138
- flex-flow: row wrap;
139
- justify-content: space-between;
140
- gap: calc(.25 * var(--bbg)) calc(.75 * var(--bbg));
141
- }
142
-
143
- :where(._bs .modes) {
144
- margin-top: var(--bbg);
145
- }
146
-
147
- :where(._bs .fields label:not([hidden])) {
148
- display: grid;
149
- gap: .25em;
150
- flex: 1 1 calc(50% - calc(.75 * var(--bbg)));
151
- }
152
-
153
- :where(._bs .fields span) {
154
- font-size: calc(var(--bfs-075) * 1rem);
155
- }
156
-
157
- :where(._bs .fields input),
158
- :where(._bs .fields select)
159
- {
160
- width: 100%;
161
- }
162
- </style>
163
-
164
- `;
165
-
166
- document.addEventListener("click", e => {
167
- if (e.target.closest(".base-settings")) {
168
- this.querySelector("dialog").showModal();
169
- }
170
- })
171
-
172
- const doc_sheets = Array.from(document.styleSheets).filter(sheet => {
173
- if (sheet.ownerNode.closest(this.nodeName)) {
174
- return false;
175
- } else {
176
- return true;
177
- }
178
- })
179
-
180
-
181
- // onLoad
182
- {
183
-
184
- // Doc Mode
185
- {
186
- const has_base_sheet = doc_sheets.some(sheet => sheet.title?.toLowerCase()?.trim() == "base");
187
- const label_mode_doc = this.querySelector("#base-mode-doc").closest("label");
188
-
189
- if (has_base_sheet) {
190
- label_mode_doc.hidden = false;
191
- const has_other_sheet = doc_sheets.some(sheet => sheet.title?.toLowerCase()?.trim() != "base");
192
- const mode_doc = this.querySelector("#base-mode-doc");
193
-
194
- if (has_other_sheet) {
195
- mode_doc.checked = false;
196
- mode_doc.disabled = false;
197
- } else {
198
- mode_doc.checked = true;
199
- mode_doc.disabled = true;
200
- }
201
- } else {
202
- label_mode_doc.hidden = true;
203
- }
204
- }
205
-
206
-
207
- const root_styles = getComputedStyle(document.documentElement);
208
-
209
- // Indent Mode
210
- {
211
- const label_mode_indent = this.querySelector("#base-mode-indent").closest("label");
212
- const has_other_sheet = doc_sheets.some(sheet => sheet.title?.toLowerCase()?.trim() != "base");
213
- const mode_indent = root_styles.getPropertyValue("--base-mode-indent").trim();
214
-
215
- if (has_other_sheet) {
216
- label_mode_indent.hidden = true;
217
- this.querySelector("#base-mode-indent").checked = false;
218
- } else {
219
-
220
- if (mode_indent) {
221
- label_mode_indent.hidden = false;
222
- this.querySelector("#base-mode-indent").checked = parseInt(mode_indent) === 1;
223
- } else {
224
- label_mode_indent.hidden = true;
225
- }
226
- }
227
- }
228
-
229
-
230
- // Font Family
231
- {
232
- const font_family = root_styles.getPropertyValue("--base-font-family").trim();
233
- const font_family_toggle = root_styles.getPropertyValue("--base-font-family-toggle").trim();
234
- const label_font_family = this.querySelector("#base-font-family").closest("label");
235
-
236
- if (parseInt(font_family_toggle) == 0) {
237
- label_font_family.hidden = true;
238
- } else {
239
- label_font_family.hidden = false;
240
-
241
- const def_typefaces = ["serif", "sans-serif", "cursive", "system-ui", "monospace"];
242
-
243
- if (def_typefaces.includes(font_family.toLowerCase())) {
244
- } else {
245
- const option = document.createElement("option");
246
-
247
- option.value = font_family;
248
- option.textContent = font_family;
249
- this.querySelector("#base-font-family").append(option);
250
- }
251
-
252
- this.querySelector("#base-font-family").value = font_family;
253
-
254
- }
255
-
256
- }
257
-
258
- // Font Size
259
- {
260
- const font_size = root_styles.getPropertyValue("--base-font-size").trim();
261
- const font_size_toggle = root_styles.getPropertyValue("--base-font-size-toggle").trim();
262
- const label_font_size = this.querySelector("#base-font-size").closest("label");
263
- const positive_numbers = /^\d+\.?\d*$/;
264
-
265
- if (parseInt(font_size_toggle) == 0) {
266
- label_font_size.hidden = true;
267
- } else {
268
- if (positive_numbers.test(font_size)) {
269
- label_font_size.hidden = false;
270
- this.querySelector("#base-font-size").value = font_size;
271
- }
272
- }
273
- }
274
-
275
- // Font Scale
276
- {
277
- const font_scale = root_styles.getPropertyValue("--base-font-scale").trim();
278
- const font_scale_toggle = root_styles.getPropertyValue("--base-font-scale-toggle").trim();
279
- const label_font_scale = this.querySelector("#base-font-scale").closest("label");
280
-
281
- if (parseInt(font_scale_toggle) == 0) {
282
- label_font_scale.hidden = true;
283
- } else {
284
- label_font_scale.hidden = false;
285
-
286
- const scale_set = [1.067, 1.125, 1.2, 1.25, 1.333, 1.414, 1.5, 1.618];
287
-
288
- if (scale_set.includes(parseFloat(font_scale))) {
289
- } else {
290
- const option = document.createElement("option");
291
-
292
- option.value = font_scale;
293
- option.textContent = font_scale;
294
- this.querySelector("#base-font-scale").append(option);
295
- }
296
-
297
- this.querySelector("#base-font-scale").value = font_scale;
298
- }
299
-
300
- }
301
-
302
- // Line Height
303
- {
304
- const line_height = root_styles.getPropertyValue("--base-line-height").trim();
305
- const line_height_toggle = root_styles.getPropertyValue("--base-line-height-toggle").trim();
306
- const label_line_height = this.querySelector("#base-line-height").closest("label");
307
- const positive_numbers = /^\d*\.?\d*$/;
308
-
309
- if (parseInt(line_height_toggle) == 0) {
310
- label_line_height.hidden = true;
311
- } else {
312
- if (positive_numbers.test(line_height)) {
313
- label_line_height.hidden = false;
314
- this.querySelector("#base-line-height").value = line_height;
315
- }
316
- }
317
- }
318
-
319
- // Line Length
320
- {
321
- const line_length = root_styles.getPropertyValue("--base-line-length").trim();
322
- const line_length_toggle = root_styles.getPropertyValue("--base-line-length-toggle").trim();
323
- const label_line_length = this.querySelector("#base-line-length").closest("label");
324
-
325
- if (parseInt(line_length_toggle) == 0) {
326
- label_line_length.hidden = true;
327
- } else {
328
- if (parseFloat(line_length)) {
329
- label_line_length.hidden = false;
330
- this.querySelector("#base-line-length").value = parseFloat(line_length);
331
- }
332
- }
333
- }
334
-
335
- // Block Gap
336
- {
337
- const block_gap = root_styles.getPropertyValue("--base-block-gap").trim();
338
- const block_gap_toggle = root_styles.getPropertyValue("--base-block-gap-toggle").trim();
339
- const label_block_gap = this.querySelector("#base-block-gap").closest("label");
340
- const positive_numbers = /^\d*\.?\d*$/;
341
-
342
- if (parseInt(block_gap_toggle) == 0) {
343
- label_block_gap.hidden = true;
344
- } else {
345
- if (positive_numbers.test(block_gap)) {
346
- label_block_gap.hidden = false;
347
- this.querySelector("#base-block-gap").value = block_gap;
348
- }
349
- }
350
- }
351
-
352
- // Color Hue
353
- {
354
- const supports = CSS.supports('color', 'oklch(0 0 0)');
355
- const color_hue = root_styles.getPropertyValue("--base-color-hue").trim();
356
- const label_color_hue = this.querySelector("#base-color-hue").closest("label");
357
- const positive_numbers = /^\d+\.?\d*$/;
358
-
359
- if (supports && positive_numbers.test(color_hue)) {
360
- label_color_hue.hidden = false;
361
- this.querySelector("#base-color-hue").value = color_hue;
362
- } else {
363
- label_color_hue.hidden = true;
364
- }
365
- }
366
-
367
- // Color Scheme
368
- {
369
- const color_scheme = document.querySelector("meta[name=color-scheme]");
370
- const label_color_scheme = this.querySelector("#base-color-scheme").closest("label");
371
-
372
- if (color_scheme) {
373
- const content = color_scheme.content.split(" ");
374
- const node_color_scheme = this.querySelector("#base-color-scheme");
375
- const has_light = content.includes("light");
376
- const has_dark = content.includes("dark");
377
-
378
- if (has_light && has_dark) {
379
- node_color_scheme.value = "";
380
- label_color_scheme.hidden = false;
381
- } else {
382
- label_color_scheme.hidden = true;
383
- }
384
- } else {
385
- label_color_scheme.hidden = true;
386
- }
387
-
388
- }
389
- }
390
-
391
- // onChange
392
- {
393
- this.addEventListener("change", e => {
394
- const form = e.target;
395
- const root_style = document.documentElement.style;
396
-
397
- switch (form.id) {
398
-
399
- case "base-mode-doc":
400
-
401
- if (form.checked) {
402
-
403
- doc_sheets.forEach(sheet => {
404
- if (sheet.title?.toLowerCase().trim() == "base") {
405
- sheet.disabled = false;
406
- } else {
407
-
408
- // Store disabled to remember later
409
- if (sheet.disabled === true) {
410
- sheet.dataset.disabled = true;
411
- }
412
-
413
- sheet.disabled = true;
414
- }
415
- })
416
-
417
- } else {
418
- doc_sheets.forEach(sheet => {
419
- if (sheet.ownerNode.dataset.disabled) {
420
- sheet.removeAttribute("data-disabled");
421
- sheet.disabled = true;
422
- } else {
423
- sheet.disabled = false;
424
- }
425
- })
426
- }
427
-
428
- break;
429
-
430
- case "base-mode-indent":
431
- root_style.setProperty("--base-mode-indent", form.checked * 1);
432
- break;
433
-
434
- case "base-font-family":
435
- root_style.setProperty("--base-font-family", form.value);
436
- break;
437
-
438
- case "base-font-size":
439
- root_style.setProperty("--base-font-size", form.value);
440
- break;
441
-
442
- case "base-font-scale":
443
- root_style.setProperty("--base-font-scale", form.value);
444
- break;
445
-
446
- case "base-line-height":
447
- root_style.setProperty("--base-line-height", form.value);
448
- break;
449
-
450
- case "base-line-length":
451
- root_style.setProperty("--base-line-length", form.value + "rem");
452
- break;
453
-
454
- case "base-block-gap":
455
- root_style.setProperty("--base-block-gap", form.value);
456
- break;
457
-
458
- case "base-color-scheme":
459
- document.querySelector("meta[name=color-scheme]").content = form.value;
460
- break;
461
-
462
- case "base-color-hue":
463
- root_style.setProperty("--base-color-hue", form.value);
464
- break;
465
-
466
- }
467
- })
468
- }
469
- }
470
- }
471
-
472
- customElements.define("base-settings", BaseSettings);