kempo-ui 0.0.11 → 0.0.13

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 (47) hide show
  1. package/docs/components/accordion.html +122 -32
  2. package/docs/components/card.html +57 -41
  3. package/docs/components/collapsible.html +158 -36
  4. package/docs/components/content-slider.html +182 -35
  5. package/docs/components/dialog.html +79 -45
  6. package/docs/components/focus-capture.html +78 -40
  7. package/docs/components/hybrid-component.html +72 -34
  8. package/docs/components/icon.html +122 -41
  9. package/docs/components/import.html +39 -41
  10. package/docs/components/light-component.html +60 -35
  11. package/docs/components/persistant-collapsible.html +84 -38
  12. package/docs/components/photo-viewer.html +186 -37
  13. package/docs/components/resize.html +140 -38
  14. package/docs/components/shadow-component.html +53 -39
  15. package/docs/components/show-more.html +93 -40
  16. package/docs/components/side-menu.html +122 -38
  17. package/docs/components/sortable.html +94 -36
  18. package/docs/components/split.html +112 -39
  19. package/docs/components/table.html +269 -31
  20. package/docs/components/tableControls.html +54 -51
  21. package/docs/components/tableCustomFields.html +90 -51
  22. package/docs/components/tableFetchRecords.html +89 -49
  23. package/docs/components/tableFieldSortHide.html +52 -51
  24. package/docs/components/tablePagination.html +77 -51
  25. package/docs/components/tableRecordEditing.html +121 -51
  26. package/docs/components/tableRecordFiltering.html +63 -49
  27. package/docs/components/tableRecordHiding.html +56 -50
  28. package/docs/components/tableRecordSearching.html +52 -51
  29. package/docs/components/tableRecordSelection.html +53 -52
  30. package/docs/components/tableRowControls.html +56 -52
  31. package/docs/components/tableSorting.html +50 -51
  32. package/docs/components/tabs.html +147 -43
  33. package/docs/components/tags.html +72 -38
  34. package/docs/components/theme-switcher.html +86 -36
  35. package/docs/components/timestamp.html +44 -38
  36. package/docs/components/toast.html +25 -44
  37. package/docs/components/toggle.html +119 -39
  38. package/docs/components/tree.html +145 -39
  39. package/docs/dev.config.json +1 -1
  40. package/docs/index.html +209 -55
  41. package/docs/utils/debounce.html +31 -28
  42. package/docs/utils/drag.html +42 -28
  43. package/docs/utils/formatTimestamp.html +67 -28
  44. package/docs/utils/propConverters.html +80 -23
  45. package/docs/utils/toTitleCase.html +24 -28
  46. package/docs/utils/watchWindowSize.html +96 -5
  47. package/package.json +1 -1
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>watchWindowSize - Kempo UI</title>
6
+ <title>formatTimestamp - Kempo UI</title>
7
7
  <link rel="stylesheet" href="../kempo-vars.css" />
8
8
  <link rel="stylesheet" href="../kempo.min.css" />
9
9
  <link rel="stylesheet" href="../kempo-hljs.css" />
@@ -14,7 +14,7 @@
14
14
  <body>
15
15
  <k-import src="../nav.inc.html"></k-import>
16
16
  <main>
17
- <h1>watchWindowSize</h1>
17
+ <h1>formatTimestamp</h1>
18
18
 
19
19
  <details
20
20
  class="b r mb"
@@ -23,47 +23,86 @@
23
23
  <div class="m mt0 pl">
24
24
  <h6>Usage</h6>
25
25
  <a href="#basicUsage">Basic Usage</a><br />
26
- <a href="#functions">Functions</a><br />
26
+ <a href="#parameters">Parameters</a><br />
27
+ <a href="#formatTokens">Format Tokens</a><br />
27
28
  <a href="#examples">Examples</a><br />
28
29
  </div>
29
30
  </details>
30
31
 
31
32
  <h3>Description</h3>
32
- <p>The <code>watchWindowSize</code> utility provides a debounced way to monitor window resize events. It manages multiple handlers efficiently and automatically debounces resize events to improve performance.</p>
33
+ <p>The <code>formatTimestamp</code> utility function formats timestamps using custom format tokens or locale-specific formatting.</p>
33
34
 
34
35
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
35
- <p>Import and use the window size watching functions:</p>
36
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Window width:'</span>, width);<br />};<br /><br /><span class="hljs-comment">// Start watching</span><br /><span class="hljs-keyword">const</span> currentWidth = watchWindowSize(handler);<br /><br /><span class="hljs-comment">// Stop watching when done</span><br />unwatchWindowSize(handler);</code></pre>
36
+ <p>Import and use the formatTimestamp function to format dates:</p>
37
+ <pre><code class="hljs javascript">import formatTimestamp from './utils/formatTimestamp.js';
37
38
 
38
- <h3 id="functions"><a href="#functions" class="no-link">Functions</a></h3>
39
-
40
- <h5><code>watchWindowSize(handler)</code></h5>
41
- <p>Registers a handler function to be called when the window is resized.</p>
42
- <ul>
43
- <li><strong>handler:</strong> Function that receives the new window width</li>
44
- <li><strong>Returns:</strong> Current window width</li>
45
- </ul>
39
+ const timestamp = Date.now();
40
+ const formatted = formatTimestamp(timestamp, 'YYYY-MM-DD');
41
+ console.log(formatted); // "2025-09-19"</code></pre>
42
+
43
+ <h3 id="parameters"><a href="#parameters" class="no-link">Parameters</a></h3>
44
+ <h5><code>timestamp<i>: number|string</i></code></h5>
45
+ <p>The timestamp to format (milliseconds since epoch).</p>
46
+ <h5><code>format<i>: string</i></code> (optional)</h5>
47
+ <p>The format string using tokens. If not provided, uses locale-specific formatting.</p>
48
+ <h5><code>forceLocale<i>: string</i></code> (optional)</h5>
49
+ <p>The locale to use for formatting when no format is specified.</p>
46
50
 
47
- <h5><code>unwatchWindowSize(handler)</code></h5>
48
- <p>Unregisters a previously registered handler function.</p>
49
- <ul>
50
- <li><strong>handler:</strong> The same function reference that was registered</li>
51
- </ul>
51
+ <h3 id="formatTokens"><a href="#formatTokens" class="no-link">Format Tokens</a></h3>
52
+ <h5><code>YYYY</code></h5>
53
+ <p>4-digit year (e.g., 2025)</p>
54
+ <h5><code>YY</code></h5>
55
+ <p>2-digit year (e.g., 25)</p>
56
+ <h5><code>MM</code></h5>
57
+ <p>2-digit month (01-12)</p>
58
+ <h5><code>M</code></h5>
59
+ <p>1-digit month (1-12)</p>
60
+ <h5><code>DD</code></h5>
61
+ <p>2-digit day (01-31)</p>
62
+ <h5><code>D</code></h5>
63
+ <p>1-digit day (1-31)</p>
64
+ <h5><code>hh</code></h5>
65
+ <p>2-digit hour (00-23)</p>
66
+ <h5><code>h</code></h5>
67
+ <p>1-digit hour (0-23)</p>
68
+ <h5><code>mm</code></h5>
69
+ <p>2-digit minute (00-59)</p>
70
+ <h5><code>m</code></h5>
71
+ <p>1-digit minute (0-59)</p>
72
+ <h5><code>ss</code></h5>
73
+ <p>2-digit second (00-59)</p>
74
+ <h5><code>s</code></h5>
75
+ <p>1-digit second (0-59)</p>
76
+ <h5><code>iiii, iii, ii, i</code></h5>
77
+ <p>Milliseconds with different padding</p>
52
78
 
53
79
  <h3 id="examples"><a href="#examples" class="no-link">Examples</a></h3>
54
80
 
55
- <h4>Responsive Component</h4>
56
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">LitElement</span> </span>{<br /> <span class="hljs-keyword">constructor</span>() {<br /> <span class="hljs-keyword">super</span>();<br /> <span class="hljs-keyword">this</span>.isMobile = <span class="hljs-literal">false</span>;<br /> <span class="hljs-keyword">this</span>.resizeHandler = <span class="hljs-keyword">this</span>.handleResize.bind(<span class="hljs-keyword">this</span>);<br /> }<br /><br /> connectedCallback() {<br /> <span class="hljs-keyword">super</span>.connectedCallback();<br /> <span class="hljs-keyword">const</span> currentWidth = watchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> <span class="hljs-keyword">this</span>.handleResize(currentWidth);<br /> }<br /><br /> disconnectedCallback() {<br /> <span class="hljs-keyword">super</span>.disconnectedCallback();<br /> unwatchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> }<br /><br /> handleResize(width) {<br /> <span class="hljs-keyword">this</span>.isMobile = width &lt; <span class="hljs-number">768</span>;<br /> <span class="hljs-keyword">this</span>.requestUpdate();<br /> }<br /><br /> render() {<br /> <span class="hljs-keyword">return</span> html`<span class="xml"><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"</span></span></span><span class="hljs-subst">${<span class="hljs-keyword">this</span>.isMobile ? <span class="hljs-string">'mobile'</span> : <span class="hljs-string">'desktop'</span>}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span><br /> Content adapts to screen size<br /> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> `</span>;<br /> }<br />}</code></pre>
81
+ <h4>Date Formats</h4>
82
+ <pre><code class="hljs javascript">const timestamp = 1633024800000;
83
+
84
+ formatTimestamp(timestamp, 'YYYY-MM-DD'); // "2021-10-01"
85
+ formatTimestamp(timestamp, 'MM/DD/YYYY'); // "10/01/2021"
86
+ formatTimestamp(timestamp, 'DD-MM-YY'); // "01-10-21"</code></pre>
87
+
88
+ <h4>Time Formats</h4>
89
+ <pre><code class="hljs javascript">formatTimestamp(timestamp, 'hh:mm:ss'); // "00:00:00"
90
+ formatTimestamp(timestamp, 'h:mm'); // "0:00"
91
+ formatTimestamp(timestamp, 'hh:mm:ss.iii'); // "00:00:00.000"</code></pre>
92
+
93
+ <h4>Combined Formats</h4>
94
+ <pre><code class="hljs javascript">formatTimestamp(timestamp, 'YYYY-MM-DD hh:mm:ss');
95
+ // "2021-10-01 00:00:00"
57
96
 
58
- <h4>Multiple Handlers</h4>
59
- <pre><code class="hljs javascript"><span class="hljs-comment">// Handler for navigation</span><br /><span class="hljs-keyword">const</span> navHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> nav = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.navigation'</span>);<br /> nav.classList.toggle(<span class="hljs-string">'mobile'</span>, width &lt; <span class="hljs-number">1024</span>);<br />};<br /><br /><span class="hljs-comment">// Handler for sidebar</span><br /><span class="hljs-keyword">const</span> sidebarHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> sidebar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.sidebar'</span>);<br /> sidebar.style.display = width &lt; <span class="hljs-number">768</span> ? <span class="hljs-string">'none'</span> : <span class="hljs-string">'block'</span>;<br />};<br /><br /><span class="hljs-comment">// Both handlers will be called on resize</span><br />watchWindowSize(navHandler);<br />watchWindowSize(sidebarHandler);<br /><br /><span class="hljs-comment">// Clean up when needed</span><br />unwatchWindowSize(navHandler);<br />unwatchWindowSize(sidebarHandler);</code></pre>
97
+ formatTimestamp(timestamp, 'MM/DD/YY at h:mm');
98
+ // "10/01/21 at 0:00"</code></pre>
60
99
 
61
- <h4>Breakpoint Detection</h4>
62
- <pre><code class="hljs javascript"><span class="hljs-keyword">const</span> breakpoints = {<br /> <span class="hljs-attr">mobile</span>: <span class="hljs-number">768</span>,<br /> <span class="hljs-attr">tablet</span>: <span class="hljs-number">1024</span>,<br /> <span class="hljs-attr">desktop</span>: <span class="hljs-number">1200</span><br />};<br /><br /><span class="hljs-keyword">const</span> breakpointHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">let</span> currentBreakpoint = <span class="hljs-string">'mobile'</span>;<br /> <br /> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.desktop) {<br /> currentBreakpoint = <span class="hljs-string">'desktop'</span>;<br /> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.tablet) {<br /> currentBreakpoint = <span class="hljs-string">'tablet'</span>;<br /> }<br /> <br /> <span class="hljs-built_in">document</span>.body.setAttribute(<span class="hljs-string">'data-breakpoint'</span>, currentBreakpoint);<br /> <br /> <span class="hljs-comment">// Dispatch custom event</span><br /> <span class="hljs-built_in">window</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'breakpointchange'</span>, {<br /> <span class="hljs-attr">detail</span>: { width, <span class="hljs-attr">breakpoint</span>: currentBreakpoint }<br /> }));<br />};<br /><br />watchWindowSize(breakpointHandler);</code></pre>
100
+ <h4>Locale Formatting</h4>
101
+ <pre><code class="hljs javascript">// Uses browser locale when no format specified
102
+ formatTimestamp(timestamp); // "10/1/2021, 12:00:00 AM"
63
103
 
64
- <h4>Performance Benefits</h4>
65
- <p>The utility automatically debounces resize events, so you don't need to worry about performance:</p>
66
- <pre><code class="hljs javascript"><span class="hljs-comment">// This handler will only be called after resize events stop</span><br /><span class="hljs-keyword">const</span> expensiveHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-comment">// Expensive DOM calculations or API calls</span><br /> recalculateLayout();<br /> updateCharts();<br /> reflow();<br />};<br /><br />watchWindowSize(expensiveHandler); <span class="hljs-comment">// Automatically debounced</span></code></pre>
104
+ // Force specific locale
105
+ formatTimestamp(timestamp, null, 'de-DE'); // German formatting</code></pre>
67
106
 
68
107
  </main>
69
108
  <div style="height:33vh"></div>
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>watchWindowSize - Kempo UI</title>
6
+ <title>propConverters - Kempo UI</title>
7
7
  <link rel="stylesheet" href="../kempo-vars.css" />
8
8
  <link rel="stylesheet" href="../kempo.min.css" />
9
9
  <link rel="stylesheet" href="../kempo-hljs.css" />
@@ -14,7 +14,7 @@
14
14
  <body>
15
15
  <k-import src="../nav.inc.html"></k-import>
16
16
  <main>
17
- <h1>watchWindowSize</h1>
17
+ <h1>propConverters</h1>
18
18
 
19
19
  <details
20
20
  class="b r mb"
@@ -23,47 +23,104 @@
23
23
  <div class="m mt0 pl">
24
24
  <h6>Usage</h6>
25
25
  <a href="#basicUsage">Basic Usage</a><br />
26
- <a href="#functions">Functions</a><br />
26
+ <a href="#boolTrueFalse">boolTrueFalse</a><br />
27
+ <a href="#boolExists">boolExists</a><br />
27
28
  <a href="#examples">Examples</a><br />
28
29
  </div>
29
30
  </details>
30
31
 
31
32
  <h3>Description</h3>
32
- <p>The <code>watchWindowSize</code> utility provides a debounced way to monitor window resize events. It manages multiple handlers efficiently and automatically debounces resize events to improve performance.</p>
33
+ <p>The <code>propConverters</code> module provides Lit Element property converters for handling boolean attributes in web components. These converters manage the conversion between JavaScript boolean values and HTML attribute strings.</p>
33
34
 
34
35
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
35
- <p>Import and use the window size watching functions:</p>
36
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Window width:'</span>, width);<br />};<br /><br /><span class="hljs-comment">// Start watching</span><br /><span class="hljs-keyword">const</span> currentWidth = watchWindowSize(handler);<br /><br /><span class="hljs-comment">// Stop watching when done</span><br />unwatchWindowSize(handler);</code></pre>
36
+ <p>Import and use the converters in your Lit Element component properties:</p>
37
+ <pre><code class="hljs javascript">import { boolTrueFalse, boolExists } from './utils/propConverters.js';
37
38
 
38
- <h3 id="functions"><a href="#functions" class="no-link">Functions</a></h3>
39
+ static properties = {
40
+ enabled: { type: Boolean, reflect: true, converter: boolTrueFalse },
41
+ visible: { type: Boolean, reflect: true, converter: boolExists }
42
+ };</code></pre>
43
+
44
+ <h3 id="boolTrueFalse"><a href="#boolTrueFalse" class="no-link">boolTrueFalse</a></h3>
45
+ <p>Converts between boolean values and explicit "true"/"false" string attributes.</p>
39
46
 
40
- <h5><code>watchWindowSize(handler)</code></h5>
41
- <p>Registers a handler function to be called when the window is resized.</p>
47
+ <h4>Behavior</h4>
42
48
  <ul>
43
- <li><strong>handler:</strong> Function that receives the new window width</li>
44
- <li><strong>Returns:</strong> Current window width</li>
49
+ <li><strong>fromAttribute:</strong> "true" true, "false" false, null → undefined</li>
50
+ <li><strong>toAttribute:</strong> true "true", false → "false"</li>
45
51
  </ul>
46
52
 
47
- <h5><code>unwatchWindowSize(handler)</code></h5>
48
- <p>Unregisters a previously registered handler function.</p>
53
+ <h4>HTML Usage</h4>
54
+ <pre><code class="hljs xml">&lt;my-component enabled="true"&gt;&lt;/my-component&gt;
55
+ &lt;my-component enabled="false"&gt;&lt;/my-component&gt;</code></pre>
56
+
57
+ <h3 id="boolExists"><a href="#boolExists" class="no-link">boolExists</a></h3>
58
+ <p>Converts between boolean values and attribute presence/absence.</p>
59
+
60
+ <h4>Behavior</h4>
49
61
  <ul>
50
- <li><strong>handler:</strong> The same function reference that was registered</li>
62
+ <li><strong>fromAttribute:</strong> attribute present true, attribute absent → false</li>
63
+ <li><strong>toAttribute:</strong> true → "", false → null (removes attribute)</li>
51
64
  </ul>
52
65
 
66
+ <h4>HTML Usage</h4>
67
+ <pre><code class="hljs xml">&lt;my-component visible&gt;&lt;/my-component&gt; &lt;!-- visible = true --&gt;
68
+ &lt;my-component&gt;&lt;/my-component&gt; &lt;!-- visible = false --&gt;</code></pre>
69
+
53
70
  <h3 id="examples"><a href="#examples" class="no-link">Examples</a></h3>
54
71
 
55
- <h4>Responsive Component</h4>
56
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">LitElement</span> </span>{<br /> <span class="hljs-keyword">constructor</span>() {<br /> <span class="hljs-keyword">super</span>();<br /> <span class="hljs-keyword">this</span>.isMobile = <span class="hljs-literal">false</span>;<br /> <span class="hljs-keyword">this</span>.resizeHandler = <span class="hljs-keyword">this</span>.handleResize.bind(<span class="hljs-keyword">this</span>);<br /> }<br /><br /> connectedCallback() {<br /> <span class="hljs-keyword">super</span>.connectedCallback();<br /> <span class="hljs-keyword">const</span> currentWidth = watchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> <span class="hljs-keyword">this</span>.handleResize(currentWidth);<br /> }<br /><br /> disconnectedCallback() {<br /> <span class="hljs-keyword">super</span>.disconnectedCallback();<br /> unwatchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> }<br /><br /> handleResize(width) {<br /> <span class="hljs-keyword">this</span>.isMobile = width &lt; <span class="hljs-number">768</span>;<br /> <span class="hljs-keyword">this</span>.requestUpdate();<br /> }<br /><br /> render() {<br /> <span class="hljs-keyword">return</span> html`<span class="xml"><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"</span></span></span><span class="hljs-subst">${<span class="hljs-keyword">this</span>.isMobile ? <span class="hljs-string">'mobile'</span> : <span class="hljs-string">'desktop'</span>}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span><br /> Content adapts to screen size<br /> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> `</span>;<br /> }<br />}</code></pre>
72
+ <h4>Component with Both Converters</h4>
73
+ <pre><code class="hljs javascript">import { LitElement, html } from 'lit';
74
+ import { boolTrueFalse, boolExists } from './utils/propConverters.js';
75
+
76
+ class MyComponent extends LitElement {
77
+ static properties = {
78
+ autoplay: { type: Boolean, reflect: true, converter: boolTrueFalse },
79
+ hidden: { type: Boolean, reflect: true, converter: boolExists },
80
+ loop: { type: Boolean, reflect: true, converter: boolTrueFalse }
81
+ };
82
+
83
+ constructor() {
84
+ super();
85
+ this.autoplay = false;
86
+ this.hidden = false;
87
+ this.loop = false;
88
+ }
89
+
90
+ render() {
91
+ return html`
92
+ &lt;div ?hidden="${this.hidden}"&gt;
93
+ Content ${this.autoplay ? 'with' : 'without'} autoplay
94
+ ${this.loop ? '(looping)' : ''}
95
+ &lt;/div&gt;
96
+ `;
97
+ }
98
+ }</code></pre>
57
99
 
58
- <h4>Multiple Handlers</h4>
59
- <pre><code class="hljs javascript"><span class="hljs-comment">// Handler for navigation</span><br /><span class="hljs-keyword">const</span> navHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> nav = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.navigation'</span>);<br /> nav.classList.toggle(<span class="hljs-string">'mobile'</span>, width &lt; <span class="hljs-number">1024</span>);<br />};<br /><br /><span class="hljs-comment">// Handler for sidebar</span><br /><span class="hljs-keyword">const</span> sidebarHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> sidebar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.sidebar'</span>);<br /> sidebar.style.display = width &lt; <span class="hljs-number">768</span> ? <span class="hljs-string">'none'</span> : <span class="hljs-string">'block'</span>;<br />};<br /><br /><span class="hljs-comment">// Both handlers will be called on resize</span><br />watchWindowSize(navHandler);<br />watchWindowSize(sidebarHandler);<br /><br /><span class="hljs-comment">// Clean up when needed</span><br />unwatchWindowSize(navHandler);<br />unwatchWindowSize(sidebarHandler);</code></pre>
100
+ <h4>HTML Usage Examples</h4>
101
+ <pre><code class="hljs xml">&lt;!-- Using boolTrueFalse converter --&gt;
102
+ &lt;my-component autoplay="true" loop="false"&gt;&lt;/my-component&gt;
60
103
 
61
- <h4>Breakpoint Detection</h4>
62
- <pre><code class="hljs javascript"><span class="hljs-keyword">const</span> breakpoints = {<br /> <span class="hljs-attr">mobile</span>: <span class="hljs-number">768</span>,<br /> <span class="hljs-attr">tablet</span>: <span class="hljs-number">1024</span>,<br /> <span class="hljs-attr">desktop</span>: <span class="hljs-number">1200</span><br />};<br /><br /><span class="hljs-keyword">const</span> breakpointHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">let</span> currentBreakpoint = <span class="hljs-string">'mobile'</span>;<br /> <br /> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.desktop) {<br /> currentBreakpoint = <span class="hljs-string">'desktop'</span>;<br /> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.tablet) {<br /> currentBreakpoint = <span class="hljs-string">'tablet'</span>;<br /> }<br /> <br /> <span class="hljs-built_in">document</span>.body.setAttribute(<span class="hljs-string">'data-breakpoint'</span>, currentBreakpoint);<br /> <br /> <span class="hljs-comment">// Dispatch custom event</span><br /> <span class="hljs-built_in">window</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'breakpointchange'</span>, {<br /> <span class="hljs-attr">detail</span>: { width, <span class="hljs-attr">breakpoint</span>: currentBreakpoint }<br /> }));<br />};<br /><br />watchWindowSize(breakpointHandler);</code></pre>
104
+ &lt;!-- Using boolExists converter --&gt;
105
+ &lt;my-component hidden&gt;&lt;/my-component&gt;
63
106
 
64
- <h4>Performance Benefits</h4>
65
- <p>The utility automatically debounces resize events, so you don't need to worry about performance:</p>
66
- <pre><code class="hljs javascript"><span class="hljs-comment">// This handler will only be called after resize events stop</span><br /><span class="hljs-keyword">const</span> expensiveHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-comment">// Expensive DOM calculations or API calls</span><br /> recalculateLayout();<br /> updateCharts();<br /> reflow();<br />};<br /><br />watchWindowSize(expensiveHandler); <span class="hljs-comment">// Automatically debounced</span></code></pre>
107
+ &lt;!-- Combined usage --&gt;
108
+ &lt;my-component autoplay="true" loop="true" hidden&gt;&lt;/my-component&gt;</code></pre>
109
+
110
+ <h4>When to Use Each Converter</h4>
111
+ <p><strong>Use boolTrueFalse when:</strong></p>
112
+ <ul>
113
+ <li>You need explicit true/false values in HTML</li>
114
+ <li>The attribute value is important for clarity</li>
115
+ <li>Working with form controls or interactive elements</li>
116
+ </ul>
117
+
118
+ <p><strong>Use boolExists when:</strong></p>
119
+ <ul>
120
+ <li>Following HTML standards (like hidden, disabled attributes)</li>
121
+ <li>The presence of the attribute is what matters</li>
122
+ <li>Creating more semantic HTML</li>
123
+ </ul>
67
124
 
68
125
  </main>
69
126
  <div style="height:33vh"></div>
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>watchWindowSize - Kempo UI</title>
6
+ <title>toTitleCase - Kempo UI</title>
7
7
  <link rel="stylesheet" href="../kempo-vars.css" />
8
8
  <link rel="stylesheet" href="../kempo.min.css" />
9
9
  <link rel="stylesheet" href="../kempo-hljs.css" />
@@ -14,7 +14,7 @@
14
14
  <body>
15
15
  <k-import src="../nav.inc.html"></k-import>
16
16
  <main>
17
- <h1>watchWindowSize</h1>
17
+ <h1>toTitleCase</h1>
18
18
 
19
19
  <details
20
20
  class="b r mb"
@@ -23,47 +23,43 @@
23
23
  <div class="m mt0 pl">
24
24
  <h6>Usage</h6>
25
25
  <a href="#basicUsage">Basic Usage</a><br />
26
- <a href="#functions">Functions</a><br />
26
+ <a href="#parameters">Parameters</a><br />
27
+ <a href="#returnValue">Return Value</a><br />
27
28
  <a href="#examples">Examples</a><br />
28
29
  </div>
29
30
  </details>
30
31
 
31
32
  <h3>Description</h3>
32
- <p>The <code>watchWindowSize</code> utility provides a debounced way to monitor window resize events. It manages multiple handlers efficiently and automatically debounces resize events to improve performance.</p>
33
+ <p>The <code>toTitleCase</code> utility function converts strings to title case format. It handles camelCase, snake_case, kebab-case, and regular text, converting them into properly capitalized title case with spaces between words.</p>
33
34
 
34
35
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
35
- <p>Import and use the window size watching functions:</p>
36
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Window width:'</span>, width);<br />};<br /><br /><span class="hljs-comment">// Start watching</span><br /><span class="hljs-keyword">const</span> currentWidth = watchWindowSize(handler);<br /><br /><span class="hljs-comment">// Stop watching when done</span><br />unwatchWindowSize(handler);</code></pre>
36
+ <p>Import and use the toTitleCase function to convert strings to title case:</p>
37
+ <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> toTitleCase <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/toTitleCase.js'</span>;<br /><br /><span class="hljs-keyword">const</span> result = <span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'helloWorld'</span>);<br /><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(result); <span class="hljs-comment">// "Hello World"</span></code></pre>
37
38
 
38
- <h3 id="functions"><a href="#functions" class="no-link">Functions</a></h3>
39
-
40
- <h5><code>watchWindowSize(handler)</code></h5>
41
- <p>Registers a handler function to be called when the window is resized.</p>
42
- <ul>
43
- <li><strong>handler:</strong> Function that receives the new window width</li>
44
- <li><strong>Returns:</strong> Current window width</li>
45
- </ul>
39
+ <h3 id="parameters"><a href="#parameters" class="no-link">Parameters</a></h3>
40
+ <h5><code>str<i>: string</i></code></h5>
41
+ <p>The string to convert to title case. Can be in any format (camelCase, snake_case, kebab-case, or regular text).</p>
46
42
 
47
- <h5><code>unwatchWindowSize(handler)</code></h5>
48
- <p>Unregisters a previously registered handler function.</p>
49
- <ul>
50
- <li><strong>handler:</strong> The same function reference that was registered</li>
51
- </ul>
43
+ <h3 id="returnValue"><a href="#returnValue" class="no-link">Return Value</a></h3>
44
+ <h5><code><i>string</i></code></h5>
45
+ <p>The input string converted to title case with proper spacing and capitalization.</p>
52
46
 
53
47
  <h3 id="examples"><a href="#examples" class="no-link">Examples</a></h3>
54
48
 
55
- <h4>Responsive Component</h4>
56
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">LitElement</span> </span>{<br /> <span class="hljs-keyword">constructor</span>() {<br /> <span class="hljs-keyword">super</span>();<br /> <span class="hljs-keyword">this</span>.isMobile = <span class="hljs-literal">false</span>;<br /> <span class="hljs-keyword">this</span>.resizeHandler = <span class="hljs-keyword">this</span>.handleResize.bind(<span class="hljs-keyword">this</span>);<br /> }<br /><br /> connectedCallback() {<br /> <span class="hljs-keyword">super</span>.connectedCallback();<br /> <span class="hljs-keyword">const</span> currentWidth = watchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> <span class="hljs-keyword">this</span>.handleResize(currentWidth);<br /> }<br /><br /> disconnectedCallback() {<br /> <span class="hljs-keyword">super</span>.disconnectedCallback();<br /> unwatchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> }<br /><br /> handleResize(width) {<br /> <span class="hljs-keyword">this</span>.isMobile = width &lt; <span class="hljs-number">768</span>;<br /> <span class="hljs-keyword">this</span>.requestUpdate();<br /> }<br /><br /> render() {<br /> <span class="hljs-keyword">return</span> html`<span class="xml"><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"</span></span></span><span class="hljs-subst">${<span class="hljs-keyword">this</span>.isMobile ? <span class="hljs-string">'mobile'</span> : <span class="hljs-string">'desktop'</span>}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span><br /> Content adapts to screen size<br /> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> `</span>;<br /> }<br />}</code></pre>
49
+ <h4>Converting camelCase</h4>
50
+ <pre><code class="hljs javascript"><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'firstName'</span>); <span class="hljs-comment">// "First Name"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'customerAddress'</span>); <span class="hljs-comment">// "Customer Address"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'userId'</span>); <span class="hljs-comment">// "User Id"</span></code></pre>
51
+
52
+ <h4>Converting snake_case</h4>
53
+ <pre><code class="hljs javascript"><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'first_name'</span>); <span class="hljs-comment">// "First Name"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'customer_address'</span>); <span class="hljs-comment">// "Customer Address"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'user_id'</span>); <span class="hljs-comment">// "User Id"</span></code></pre>
57
54
 
58
- <h4>Multiple Handlers</h4>
59
- <pre><code class="hljs javascript"><span class="hljs-comment">// Handler for navigation</span><br /><span class="hljs-keyword">const</span> navHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> nav = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.navigation'</span>);<br /> nav.classList.toggle(<span class="hljs-string">'mobile'</span>, width &lt; <span class="hljs-number">1024</span>);<br />};<br /><br /><span class="hljs-comment">// Handler for sidebar</span><br /><span class="hljs-keyword">const</span> sidebarHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> sidebar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.sidebar'</span>);<br /> sidebar.style.display = width &lt; <span class="hljs-number">768</span> ? <span class="hljs-string">'none'</span> : <span class="hljs-string">'block'</span>;<br />};<br /><br /><span class="hljs-comment">// Both handlers will be called on resize</span><br />watchWindowSize(navHandler);<br />watchWindowSize(sidebarHandler);<br /><br /><span class="hljs-comment">// Clean up when needed</span><br />unwatchWindowSize(navHandler);<br />unwatchWindowSize(sidebarHandler);</code></pre>
55
+ <h4>Converting kebab-case</h4>
56
+ <pre><code class="hljs javascript"><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'first-name'</span>); <span class="hljs-comment">// "First Name"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'customer-address'</span>); <span class="hljs-comment">// "Customer Address"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'user-id'</span>); <span class="hljs-comment">// "User Id"</span></code></pre>
60
57
 
61
- <h4>Breakpoint Detection</h4>
62
- <pre><code class="hljs javascript"><span class="hljs-keyword">const</span> breakpoints = {<br /> <span class="hljs-attr">mobile</span>: <span class="hljs-number">768</span>,<br /> <span class="hljs-attr">tablet</span>: <span class="hljs-number">1024</span>,<br /> <span class="hljs-attr">desktop</span>: <span class="hljs-number">1200</span><br />};<br /><br /><span class="hljs-keyword">const</span> breakpointHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">let</span> currentBreakpoint = <span class="hljs-string">'mobile'</span>;<br /> <br /> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.desktop) {<br /> currentBreakpoint = <span class="hljs-string">'desktop'</span>;<br /> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.tablet) {<br /> currentBreakpoint = <span class="hljs-string">'tablet'</span>;<br /> }<br /> <br /> <span class="hljs-built_in">document</span>.body.setAttribute(<span class="hljs-string">'data-breakpoint'</span>, currentBreakpoint);<br /> <br /> <span class="hljs-comment">// Dispatch custom event</span><br /> <span class="hljs-built_in">window</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'breakpointchange'</span>, {<br /> <span class="hljs-attr">detail</span>: { width, <span class="hljs-attr">breakpoint</span>: currentBreakpoint }<br /> }));<br />};<br /><br />watchWindowSize(breakpointHandler);</code></pre>
58
+ <h4>Converting regular text</h4>
59
+ <pre><code class="hljs javascript"><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'hello world'</span>); <span class="hljs-comment">// "Hello World"</span><br /><span class="hljs-title function_">toTitleCase</span>(<span class="hljs-string">'the quick brown fox'</span>); <span class="hljs-comment">// "The Quick Brown Fox"</span></code></pre>
63
60
 
64
- <h4>Performance Benefits</h4>
65
- <p>The utility automatically debounces resize events, so you don't need to worry about performance:</p>
66
- <pre><code class="hljs javascript"><span class="hljs-comment">// This handler will only be called after resize events stop</span><br /><span class="hljs-keyword">const</span> expensiveHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-comment">// Expensive DOM calculations or API calls</span><br /> recalculateLayout();<br /> updateCharts();<br /> reflow();<br />};<br /><br />watchWindowSize(expensiveHandler); <span class="hljs-comment">// Automatically debounced</span></code></pre>
61
+ <h4>Practical Use Case: Table Column Headers</h4>
62
+ <pre><code class="hljs javascript"><span class="hljs-keyword">const</span> columns = [<span class="hljs-string">'firstName'</span>, <span class="hljs-string">'lastName'</span>, <span class="hljs-string">'emailAddress'</span>];<br /><br /><span class="hljs-keyword">const</span> headers = columns.<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">col</span> =&gt;</span> <span class="hljs-title function_">toTitleCase</span>(col));<br /><span class="hljs-comment">// ["First Name", "Last Name", "Email Address"]</span></code></pre>
67
63
 
68
64
  </main>
69
65
  <div style="height:33vh"></div>
@@ -33,7 +33,17 @@
33
33
 
34
34
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
35
35
  <p>Import and use the window size watching functions:</p>
36
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Window width:'</span>, width);<br />};<br /><br /><span class="hljs-comment">// Start watching</span><br /><span class="hljs-keyword">const</span> currentWidth = watchWindowSize(handler);<br /><br /><span class="hljs-comment">// Stop watching when done</span><br />unwatchWindowSize(handler);</code></pre>
36
+ <pre><code class="hljs javascript">import { watchWindowSize, unwatchWindowSize } from './utils/watchWindowSize.js';
37
+
38
+ const handler = (width) => {
39
+ console.log('Window width:', width);
40
+ };
41
+
42
+ // Start watching
43
+ const currentWidth = watchWindowSize(handler);
44
+
45
+ // Stop watching when done
46
+ unwatchWindowSize(handler);</code></pre>
37
47
 
38
48
  <h3 id="functions"><a href="#functions" class="no-link">Functions</a></h3>
39
49
 
@@ -53,17 +63,98 @@
53
63
  <h3 id="examples"><a href="#examples" class="no-link">Examples</a></h3>
54
64
 
55
65
  <h4>Responsive Component</h4>
56
- <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { watchWindowSize, unwatchWindowSize } <span class="hljs-keyword">from</span> <span class="hljs-string">'./utils/watchWindowSize.js'</span>;<br /><br /><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">LitElement</span> </span>{<br /> <span class="hljs-keyword">constructor</span>() {<br /> <span class="hljs-keyword">super</span>();<br /> <span class="hljs-keyword">this</span>.isMobile = <span class="hljs-literal">false</span>;<br /> <span class="hljs-keyword">this</span>.resizeHandler = <span class="hljs-keyword">this</span>.handleResize.bind(<span class="hljs-keyword">this</span>);<br /> }<br /><br /> connectedCallback() {<br /> <span class="hljs-keyword">super</span>.connectedCallback();<br /> <span class="hljs-keyword">const</span> currentWidth = watchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> <span class="hljs-keyword">this</span>.handleResize(currentWidth);<br /> }<br /><br /> disconnectedCallback() {<br /> <span class="hljs-keyword">super</span>.disconnectedCallback();<br /> unwatchWindowSize(<span class="hljs-keyword">this</span>.resizeHandler);<br /> }<br /><br /> handleResize(width) {<br /> <span class="hljs-keyword">this</span>.isMobile = width &lt; <span class="hljs-number">768</span>;<br /> <span class="hljs-keyword">this</span>.requestUpdate();<br /> }<br /><br /> render() {<br /> <span class="hljs-keyword">return</span> html`<span class="xml"><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"</span></span></span><span class="hljs-subst">${<span class="hljs-keyword">this</span>.isMobile ? <span class="hljs-string">'mobile'</span> : <span class="hljs-string">'desktop'</span>}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span><br /> Content adapts to screen size<br /> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> `</span>;<br /> }<br />}</code></pre>
66
+ <pre><code class="hljs javascript">import { watchWindowSize, unwatchWindowSize } from './utils/watchWindowSize.js';
67
+
68
+ class ResponsiveComponent extends LitElement {
69
+ constructor() {
70
+ super();
71
+ this.isMobile = false;
72
+ this.resizeHandler = this.handleResize.bind(this);
73
+ }
74
+
75
+ connectedCallback() {
76
+ super.connectedCallback();
77
+ const currentWidth = watchWindowSize(this.resizeHandler);
78
+ this.handleResize(currentWidth);
79
+ }
80
+
81
+ disconnectedCallback() {
82
+ super.disconnectedCallback();
83
+ unwatchWindowSize(this.resizeHandler);
84
+ }
85
+
86
+ handleResize(width) {
87
+ this.isMobile = width < 768;
88
+ this.requestUpdate();
89
+ }
90
+
91
+ render() {
92
+ return html`
93
+ &lt;div class="${this.isMobile ? 'mobile' : 'desktop'}"&gt;
94
+ Content adapts to screen size
95
+ &lt;/div&gt;
96
+ `;
97
+ }
98
+ }</code></pre>
57
99
 
58
100
  <h4>Multiple Handlers</h4>
59
- <pre><code class="hljs javascript"><span class="hljs-comment">// Handler for navigation</span><br /><span class="hljs-keyword">const</span> navHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> nav = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.navigation'</span>);<br /> nav.classList.toggle(<span class="hljs-string">'mobile'</span>, width &lt; <span class="hljs-number">1024</span>);<br />};<br /><br /><span class="hljs-comment">// Handler for sidebar</span><br /><span class="hljs-keyword">const</span> sidebarHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> sidebar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.sidebar'</span>);<br /> sidebar.style.display = width &lt; <span class="hljs-number">768</span> ? <span class="hljs-string">'none'</span> : <span class="hljs-string">'block'</span>;<br />};<br /><br /><span class="hljs-comment">// Both handlers will be called on resize</span><br />watchWindowSize(navHandler);<br />watchWindowSize(sidebarHandler);<br /><br /><span class="hljs-comment">// Clean up when needed</span><br />unwatchWindowSize(navHandler);<br />unwatchWindowSize(sidebarHandler);</code></pre>
101
+ <pre><code class="hljs javascript">// Handler for navigation
102
+ const navHandler = (width) => {
103
+ const nav = document.querySelector('.navigation');
104
+ nav.classList.toggle('mobile', width < 1024);
105
+ };
106
+
107
+ // Handler for sidebar
108
+ const sidebarHandler = (width) => {
109
+ const sidebar = document.querySelector('.sidebar');
110
+ sidebar.style.display = width < 768 ? 'none' : 'block';
111
+ };
112
+
113
+ // Both handlers will be called on resize
114
+ watchWindowSize(navHandler);
115
+ watchWindowSize(sidebarHandler);
116
+
117
+ // Clean up when needed
118
+ unwatchWindowSize(navHandler);
119
+ unwatchWindowSize(sidebarHandler);</code></pre>
60
120
 
61
121
  <h4>Breakpoint Detection</h4>
62
- <pre><code class="hljs javascript"><span class="hljs-keyword">const</span> breakpoints = {<br /> <span class="hljs-attr">mobile</span>: <span class="hljs-number">768</span>,<br /> <span class="hljs-attr">tablet</span>: <span class="hljs-number">1024</span>,<br /> <span class="hljs-attr">desktop</span>: <span class="hljs-number">1200</span><br />};<br /><br /><span class="hljs-keyword">const</span> breakpointHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-keyword">let</span> currentBreakpoint = <span class="hljs-string">'mobile'</span>;<br /> <br /> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.desktop) {<br /> currentBreakpoint = <span class="hljs-string">'desktop'</span>;<br /> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (width &gt;= breakpoints.tablet) {<br /> currentBreakpoint = <span class="hljs-string">'tablet'</span>;<br /> }<br /> <br /> <span class="hljs-built_in">document</span>.body.setAttribute(<span class="hljs-string">'data-breakpoint'</span>, currentBreakpoint);<br /> <br /> <span class="hljs-comment">// Dispatch custom event</span><br /> <span class="hljs-built_in">window</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'breakpointchange'</span>, {<br /> <span class="hljs-attr">detail</span>: { width, <span class="hljs-attr">breakpoint</span>: currentBreakpoint }<br /> }));<br />};<br /><br />watchWindowSize(breakpointHandler);</code></pre>
122
+ <pre><code class="hljs javascript">const breakpoints = {
123
+ mobile: 768,
124
+ tablet: 1024,
125
+ desktop: 1200
126
+ };
127
+
128
+ const breakpointHandler = (width) => {
129
+ let currentBreakpoint = 'mobile';
130
+
131
+ if (width >= breakpoints.desktop) {
132
+ currentBreakpoint = 'desktop';
133
+ } else if (width >= breakpoints.tablet) {
134
+ currentBreakpoint = 'tablet';
135
+ }
136
+
137
+ document.body.setAttribute('data-breakpoint', currentBreakpoint);
138
+
139
+ // Dispatch custom event
140
+ window.dispatchEvent(new CustomEvent('breakpointchange', {
141
+ detail: { width, breakpoint: currentBreakpoint }
142
+ }));
143
+ };
144
+
145
+ watchWindowSize(breakpointHandler);</code></pre>
63
146
 
64
147
  <h4>Performance Benefits</h4>
65
148
  <p>The utility automatically debounces resize events, so you don't need to worry about performance:</p>
66
- <pre><code class="hljs javascript"><span class="hljs-comment">// This handler will only be called after resize events stop</span><br /><span class="hljs-keyword">const</span> expensiveHandler = <span class="hljs-function">(<span class="hljs-params">width</span>) =&gt;</span> {<br /> <span class="hljs-comment">// Expensive DOM calculations or API calls</span><br /> recalculateLayout();<br /> updateCharts();<br /> reflow();<br />};<br /><br />watchWindowSize(expensiveHandler); <span class="hljs-comment">// Automatically debounced</span></code></pre>
149
+ <pre><code class="hljs javascript">// This handler will only be called after resize events stop
150
+ const expensiveHandler = (width) => {
151
+ // Expensive DOM calculations or API calls
152
+ recalculateLayout();
153
+ updateCharts();
154
+ reflow();
155
+ };
156
+
157
+ watchWindowSize(expensiveHandler); // Automatically debounced</code></pre>
67
158
 
68
159
  </main>
69
160
  <div style="height:33vh"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kempo-ui",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "description": "A Lit based web-component library",
6
6
  "main": "index.js",