kempo-ui 0.3.5 → 0.3.7

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 (146) hide show
  1. package/AGENTS.md +2 -1
  2. package/dist/components/Aside.js +1 -1
  3. package/dist/components/Main.js +1 -1
  4. package/docs/components/accordion.html +240 -8
  5. package/docs/components/aside-items.html +13 -9
  6. package/docs/components/aside-menu.html +13 -9
  7. package/docs/components/aside-push.html +11 -6
  8. package/docs/components/aside.html +289 -115
  9. package/docs/components/card.html +238 -7
  10. package/docs/components/color-picker.html +245 -14
  11. package/docs/components/content-slider.html +240 -8
  12. package/docs/components/context.html +241 -7
  13. package/docs/components/dialog.html +238 -7
  14. package/docs/components/dropdown.html +238 -7
  15. package/docs/components/filter-list.html +239 -10
  16. package/docs/components/focus-capture.html +241 -10
  17. package/docs/components/html-editor.html +266 -35
  18. package/docs/components/hybrid-component.html +238 -6
  19. package/docs/components/icon.html +239 -9
  20. package/docs/components/import.html +239 -8
  21. package/docs/components/light-component.html +239 -7
  22. package/docs/components/nav.html +240 -8
  23. package/docs/components/photo-viewer.html +239 -9
  24. package/docs/components/resize.html +240 -9
  25. package/docs/components/shadow-component.html +239 -7
  26. package/docs/components/show-more.html +237 -8
  27. package/docs/components/sortable.html +239 -8
  28. package/docs/components/spinner.html +237 -6
  29. package/docs/components/split.html +241 -10
  30. package/docs/components/table.html +241 -11
  31. package/docs/components/tableControls.html +240 -7
  32. package/docs/components/tableCustomFields.html +241 -8
  33. package/docs/components/tableFetchRecords.html +239 -7
  34. package/docs/components/tableFieldSortHide.html +239 -7
  35. package/docs/components/tablePagination.html +246 -13
  36. package/docs/components/tablePlaceholder.html +241 -8
  37. package/docs/components/tableRecordEditing.html +241 -8
  38. package/docs/components/tableRecordFiltering.html +239 -7
  39. package/docs/components/tableRecordHiding.html +241 -9
  40. package/docs/components/tableRecordSearching.html +239 -7
  41. package/docs/components/tableRecordSelection.html +240 -7
  42. package/docs/components/tableRowControls.html +241 -8
  43. package/docs/components/tableServerSync.html +245 -11
  44. package/docs/components/tableSorting.html +239 -7
  45. package/docs/components/tabs.html +240 -7
  46. package/docs/components/tags.html +239 -7
  47. package/docs/components/theme-select.html +239 -7
  48. package/docs/components/theme-switcher.html +240 -8
  49. package/docs/components/timestamp.html +239 -8
  50. package/docs/components/toast.html +240 -8
  51. package/docs/components/toggle.html +240 -9
  52. package/docs/components/tree.html +239 -8
  53. package/docs/index.html +244 -6
  54. package/docs/prod.config.json +0 -4
  55. package/docs/src/components/Aside.js +1 -1
  56. package/docs/src/components/Main.js +1 -1
  57. package/docs/utils/context.html +237 -6
  58. package/docs/utils/cookie.html +251 -21
  59. package/docs/utils/debounce.html +236 -5
  60. package/docs/utils/drag.html +236 -5
  61. package/docs/utils/elevation.html +238 -6
  62. package/docs/utils/formatTimestamp.html +239 -9
  63. package/docs/utils/object.html +236 -5
  64. package/docs/utils/propConverters.html +233 -3
  65. package/docs/utils/string.html +236 -5
  66. package/docs/utils/theme.html +237 -6
  67. package/docs/utils/toTitleCase.html +239 -9
  68. package/docs/utils/type.html +236 -5
  69. package/docs/utils/wait.html +236 -5
  70. package/docs-src/.config.js +16 -0
  71. package/docs-src/bare.template.html +16 -0
  72. package/docs-src/components/accordion.page.html +201 -0
  73. package/docs-src/components/aside-items.page.html +36 -0
  74. package/docs-src/components/aside-menu.page.html +36 -0
  75. package/docs-src/components/aside-push.page.html +20 -0
  76. package/docs-src/components/aside.page.html +494 -0
  77. package/docs-src/components/card.page.html +78 -0
  78. package/docs-src/components/color-picker.page.html +559 -0
  79. package/docs-src/components/content-slider.page.html +266 -0
  80. package/docs-src/components/context.page.html +214 -0
  81. package/docs-src/components/dialog.page.html +365 -0
  82. package/docs-src/components/dropdown.page.html +300 -0
  83. package/docs-src/components/filter-list.page.html +117 -0
  84. package/docs-src/components/focus-capture.page.html +97 -0
  85. package/docs-src/components/html-editor.page.html +423 -0
  86. package/docs-src/components/hybrid-component.page.html +96 -0
  87. package/docs-src/components/icon.page.html +208 -0
  88. package/docs-src/components/import.page.html +76 -0
  89. package/docs-src/components/light-component.page.html +99 -0
  90. package/docs-src/components/nav.page.html +106 -0
  91. package/docs-src/components/photo-viewer.page.html +253 -0
  92. package/docs-src/components/resize.page.html +161 -0
  93. package/docs-src/components/shadow-component.page.html +84 -0
  94. package/docs-src/components/show-more.page.html +113 -0
  95. package/docs-src/components/sortable.page.html +117 -0
  96. package/docs-src/components/spinner.page.html +197 -0
  97. package/docs-src/components/split.page.html +195 -0
  98. package/docs-src/components/table.page.html +283 -0
  99. package/docs-src/components/tableControls.page.html +64 -0
  100. package/docs-src/components/tableCustomFields.page.html +124 -0
  101. package/docs-src/components/tableFetchRecords.page.html +95 -0
  102. package/docs-src/components/tableFieldSortHide.page.html +56 -0
  103. package/docs-src/components/tablePagination.page.html +85 -0
  104. package/docs-src/components/tablePlaceholder.page.html +73 -0
  105. package/docs-src/components/tableRecordEditing.page.html +161 -0
  106. package/docs-src/components/tableRecordFiltering.page.html +69 -0
  107. package/docs-src/components/tableRecordHiding.page.html +65 -0
  108. package/docs-src/components/tableRecordSearching.page.html +56 -0
  109. package/docs-src/components/tableRecordSelection.page.html +60 -0
  110. package/docs-src/components/tableRowControls.page.html +62 -0
  111. package/docs-src/components/tableServerSync.page.html +129 -0
  112. package/docs-src/components/tableSorting.page.html +54 -0
  113. package/docs-src/components/tabs.page.html +201 -0
  114. package/docs-src/components/tags.page.html +157 -0
  115. package/docs-src/components/theme-select.page.html +106 -0
  116. package/docs-src/components/theme-switcher.page.html +122 -0
  117. package/docs-src/components/timestamp.page.html +109 -0
  118. package/docs-src/components/toast.page.html +338 -0
  119. package/docs-src/components/toggle.page.html +177 -0
  120. package/docs-src/components/tree.page.html +356 -0
  121. package/docs-src/default.template.html +28 -0
  122. package/docs-src/index.page.html +312 -0
  123. package/docs-src/nav.fragment.html +228 -0
  124. package/docs-src/utils/context.page.html +143 -0
  125. package/docs-src/utils/cookie.page.html +128 -0
  126. package/docs-src/utils/debounce.page.html +42 -0
  127. package/docs-src/utils/drag.page.html +64 -0
  128. package/docs-src/utils/elevation.page.html +144 -0
  129. package/docs-src/utils/formatTimestamp.page.html +76 -0
  130. package/docs-src/utils/object.page.html +76 -0
  131. package/docs-src/utils/propConverters.page.html +73 -0
  132. package/docs-src/utils/string.page.html +66 -0
  133. package/docs-src/utils/theme.page.html +136 -0
  134. package/docs-src/utils/toTitleCase.page.html +52 -0
  135. package/docs-src/utils/type.page.html +31 -0
  136. package/docs-src/utils/wait.page.html +31 -0
  137. package/package.json +4 -4
  138. package/scripts/build.js +5 -0
  139. package/scripts/docs.js +5 -52
  140. package/src/components/Aside.js +12 -1
  141. package/src/components/Main.js +1 -1
  142. package/tests/components/Aside.browser-test.js +75 -0
  143. package/docs/dev.config.json +0 -20
  144. package/docs/nav-1.inc.html +0 -168
  145. package/docs/nav.inc.html +0 -168
  146. package/docs/nav.inc.js +0 -70
@@ -0,0 +1,356 @@
1
+ <page pageName="Tree" title="Tree - Components - Kempo Docs - A Web Components Solution">
2
+ <content>
3
+ <k-accordion persistent-id="toc" class="b r mb">
4
+ <k-accordion-header for-panel="toc-panel">Table of Contents</k-accordion-header>
5
+ <k-accordion-panel name="toc-panel">
6
+ <div class="m ">
7
+ <h6>Examples</h6>
8
+ <a href="#basicUsage">Basic Usage</a><br />
9
+ <a href="#depthControl">Controlling Initial Depth</a><br />
10
+ <a href="#customNodes">Custom Node Types</a><br />
11
+ <a href="#directoryExample">Directory Example</a><br />
12
+
13
+ <h6 class="mt"><a href="jsRef" class="no-link">JavaScript Reference</a></h6>
14
+ <a href="#constructor">Constructor</a><br />
15
+ <a href="#requirements">Requirements</a><br />
16
+ <a href="#properties">Properties</a><br />
17
+ <a href="#methods">Methods</a><br />
18
+ </div>
19
+ </k-accordion-panel>
20
+ </k-accordion>
21
+
22
+ <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
23
+ <p>Create a tree using the <code>k-tree</code> component. Set your data by setting the <code>data</code> property.
24
+ </p>
25
+ <div class="row -mx mb">
26
+ <div class="col d-span-6 m-span-12 px">
27
+ <pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">k-tree</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;myTree&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-tree</span>&gt;</span>
28
+ <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;module&quot;</span>&gt;</span><span class="language-javascript">
29
+ <span class="hljs-keyword">import</span> <span class="hljs-title class_">Tree</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/components/Tree.js&#x27;</span>;
30
+ <span class="hljs-keyword">const</span> tree = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;myTree&#x27;</span>);
31
+ tree.<span class="hljs-property">data</span> = {
32
+ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;John Doe&#x27;</span>,
33
+ <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>,
34
+ <span class="hljs-attr">active</span>: <span class="hljs-literal">true</span>,
35
+ <span class="hljs-attr">hobbies</span>: [<span class="hljs-string">&#x27;reading&#x27;</span>, <span class="hljs-string">&#x27;coding&#x27;</span>],
36
+ <span class="hljs-attr">address</span>: {
37
+ <span class="hljs-attr">street</span>: <span class="hljs-string">&#x27;123 Main St&#x27;</span>,
38
+ <span class="hljs-attr">city</span>: <span class="hljs-string">&#x27;New York&#x27;</span>
39
+ }
40
+ };
41
+ </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
42
+ </div>
43
+ <div class="col d-span-6 m-span-12 px">
44
+ <k-tree id="myTree"></k-tree>
45
+ <script type="module">
46
+ import Tree from '{{pathToRoot}}src/components/Tree.js';
47
+ const tree = document.getElementById('myTree');
48
+ tree.data = {
49
+ name: 'John Doe',
50
+ age: 30,
51
+ active: true,
52
+ hobbies: ['reading', 'coding'],
53
+ address: {
54
+ street: '123 Main St',
55
+ city: 'New York'
56
+ }
57
+ };
58
+ </script>
59
+ </div>
60
+ </div>
61
+
62
+ <h3 id="depthControl"><a href="#depthControl" class="no-link">Controlling Initial Depth</a></h3>
63
+ <p>Use the <code>depth</code> attribute to control how many levels of branches are open by default. This example
64
+ shows depth set to <code>2</code>:</p>
65
+ <div class="row -mx mb">
66
+ <div class="col d-span-6 m-span-12 px">
67
+ <pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">k-tree</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;depthTree&quot;</span> <span class="hljs-attr">depth</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-tree</span>&gt;</span>
68
+ <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;module&quot;</span>&gt;</span><span class="language-javascript">
69
+ <span class="hljs-keyword">import</span> <span class="hljs-title class_">Tree</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/components/Tree.js&#x27;</span>;
70
+ <span class="hljs-keyword">const</span> tree = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;depthTree&#x27;</span>);
71
+ tree.<span class="hljs-property">data</span> = {
72
+ <span class="hljs-attr">company</span>: <span class="hljs-string">&#x27;Tech Corp&#x27;</span>,
73
+ <span class="hljs-attr">departments</span>: {
74
+ <span class="hljs-attr">engineering</span>: {
75
+ <span class="hljs-attr">frontend</span>: [<span class="hljs-string">&#x27;Alice&#x27;</span>, <span class="hljs-string">&#x27;Bob&#x27;</span>],
76
+ <span class="hljs-attr">backend</span>: [<span class="hljs-string">&#x27;Charlie&#x27;</span>, <span class="hljs-string">&#x27;Diana&#x27;</span>]
77
+ },
78
+ <span class="hljs-attr">sales</span>: {
79
+ <span class="hljs-attr">team</span>: [<span class="hljs-string">&#x27;Eve&#x27;</span>, <span class="hljs-string">&#x27;Frank&#x27;</span>]
80
+ }
81
+ }
82
+ };
83
+ </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
84
+ </div>
85
+ <div class="col d-span-6 m-span-12 px">
86
+ <k-tree id="depthTree" depth="2"></k-tree>
87
+ <script type="module">
88
+ import Tree from '{{pathToRoot}}src/components/Tree.js';
89
+ const tree = document.getElementById('depthTree');
90
+ tree.data = {
91
+ company: 'Tech Corp',
92
+ departments: {
93
+ engineering: {
94
+ frontend: ['Alice', 'Bob'],
95
+ backend: ['Charlie', 'Diana']
96
+ },
97
+ sales: {
98
+ team: ['Eve', 'Frank']
99
+ }
100
+ }
101
+ };
102
+ </script>
103
+ </div>
104
+ </div>
105
+
106
+ <h3 id="customNodes"><a href="#customNodes" class="no-link">Custom Node Types</a></h3>
107
+ <p>You can define custom node types to handle specific data. Create a class that extends
108
+ <code>TreeNode</code>, implement a <code>static detect</code> method, and override <code>renderLabel()</code>
109
+ and/or <code>getChildren()</code>, then register it with <code>Tree.addNode()</code>.</p>
110
+ <div class="row -mx mb">
111
+ <div class="col d-span-6 m-span-12 px">
112
+ <pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">k-tree</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;customTree&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-tree</span>&gt;</span>
113
+ <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;module&quot;</span>&gt;</span><span class="language-javascript">
114
+ <span class="hljs-keyword">import</span> <span class="hljs-title class_">Tree</span>, { <span class="hljs-title class_">TreeNode</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/components/Tree.js&#x27;</span>;
115
+ <span class="hljs-keyword">import</span> { html } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/lit-all.min.js&#x27;</span>;
116
+
117
+ <span class="hljs-keyword">class</span> <span class="hljs-title class_">DateNode</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">TreeNode</span> {
118
+ <span class="hljs-title function_">renderLabel</span>(<span class="hljs-params"></span>){
119
+ <span class="hljs-keyword">const</span> { month, day, year } = <span class="hljs-variable language_">this</span>.<span class="hljs-property">value</span>;
120
+ <span class="hljs-keyword">return</span> html`<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tc-warning&quot;</span>&gt;</span>📅 </span><span class="hljs-subst">${month}</span><span class="language-xml">/</span><span class="hljs-subst">${day}</span><span class="language-xml">/</span><span class="hljs-subst">${year}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>`</span>;
121
+ }
122
+
123
+ <span class="hljs-title function_">getChildren</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }
124
+
125
+ <span class="hljs-keyword">static</span> detect = <span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> {
126
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">&#x27;object&#x27;</span>
127
+ &amp;&amp; value !== <span class="hljs-literal">null</span>
128
+ &amp;&amp; <span class="hljs-string">&#x27;month&#x27;</span> <span class="hljs-keyword">in</span> value
129
+ &amp;&amp; <span class="hljs-string">&#x27;day&#x27;</span> <span class="hljs-keyword">in</span> value
130
+ &amp;&amp; <span class="hljs-string">&#x27;year&#x27;</span> <span class="hljs-keyword">in</span> value;
131
+ };
132
+ }
133
+
134
+ <span class="hljs-title class_">Tree</span>.<span class="hljs-title function_">addNode</span>(<span class="hljs-title class_">DateNode</span>);
135
+
136
+ <span class="hljs-keyword">const</span> tree = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;customTree&#x27;</span>);
137
+ tree.<span class="hljs-property">data</span> = {
138
+ <span class="hljs-attr">event</span>: <span class="hljs-string">&#x27;Tech Conference 2025&#x27;</span>,
139
+ <span class="hljs-attr">startDate</span>: { <span class="hljs-attr">month</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">day</span>: <span class="hljs-number">15</span>, <span class="hljs-attr">year</span>: <span class="hljs-number">2025</span> },
140
+ <span class="hljs-attr">endDate</span>: { <span class="hljs-attr">month</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">day</span>: <span class="hljs-number">17</span>, <span class="hljs-attr">year</span>: <span class="hljs-number">2025</span> },
141
+ <span class="hljs-attr">location</span>: <span class="hljs-string">&#x27;San Francisco&#x27;</span>,
142
+ <span class="hljs-attr">attendees</span>: <span class="hljs-number">250</span>
143
+ };
144
+ </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
145
+ </div>
146
+ <div class="col d-span-6 m-span-12 px">
147
+ <k-tree id="customTree"></k-tree>
148
+ <script type="module">
149
+ import Tree, { TreeNode } from '{{pathToRoot}}src/components/Tree.js';
150
+ import { html } from '{{pathToRoot}}src/lit-all.min.js';
151
+ class DateNode extends TreeNode {
152
+ renderLabel(){
153
+ const { month, day, year } = this.value;
154
+ return html`<span class="tc-warning">📅 ${month}/${day}/${year}</span>`;
155
+ }
156
+ getChildren(){ return null; }
157
+ static detect = value => {
158
+ return typeof value === 'object'
159
+ && value !== null
160
+ && 'month' in value
161
+ && 'day' in value
162
+ && 'year' in value;
163
+ };
164
+ }
165
+ Tree.addNode(DateNode);
166
+ const tree = document.getElementById('customTree');
167
+ tree.data = {
168
+ event: 'Tech Conference 2025',
169
+ startDate: { month: 10, day: 15, year: 2025 },
170
+ endDate: { month: 10, day: 17, year: 2025 },
171
+ location: 'San Francisco',
172
+ attendees: 250
173
+ };
174
+ </script>
175
+ </div>
176
+ </div>
177
+
178
+ <h3 id="directoryExample"><a href="#directoryExample" class="no-link">Directory Example</a></h3>
179
+ <p>This example uses the
180
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_API" target="_blank">File System Access API</a>.
181
+ <code>FileHandleNode</code> and <code>DirHandleNode</code> detect
182
+ <code>FileSystemFileHandle</code> and <code>FileSystemDirectoryHandle</code> directly —
183
+ no data transformation needed. <code>DirHandleNode</code> loads its children asynchronously
184
+ using a reactive internal property, so the tree populates lazily as nodes are opened.</p>
185
+ <div class="row -mx mb">
186
+ <div class="col d-span-6 m-span-12 px">
187
+ <pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;browseBtn&quot;</span>&gt;</span>Browse Directory<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
188
+ <span class="hljs-tag">&lt;<span class="hljs-name">k-tree</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;dirTree&quot;</span> <span class="hljs-attr">depth</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-tree</span>&gt;</span>
189
+ <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;module&quot;</span>&gt;</span><span class="language-javascript">
190
+ <span class="hljs-keyword">import</span> <span class="hljs-title class_">Tree</span>, { <span class="hljs-title class_">TreeNode</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/components/Tree.js&#x27;</span>;
191
+ <span class="hljs-keyword">import</span> { html } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;/src/lit-all.min.js&#x27;</span>;
192
+
193
+ <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileHandleNode</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">TreeNode</span> {
194
+ <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>){
195
+ <span class="hljs-keyword">const</span> ext = <span class="hljs-variable language_">this</span>.<span class="hljs-property">value</span>.<span class="hljs-property">name</span>.<span class="hljs-title function_">split</span>(<span class="hljs-string">&#x27;.&#x27;</span>).<span class="hljs-title function_">pop</span>().<span class="hljs-title function_">toLowerCase</span>();
196
+ <span class="hljs-keyword">const</span> iconName = { <span class="hljs-attr">js</span>: <span class="hljs-string">&#x27;code&#x27;</span>, <span class="hljs-attr">html</span>: <span class="hljs-string">&#x27;code_blocks&#x27;</span>, <span class="hljs-attr">css</span>: <span class="hljs-string">&#x27;code&#x27;</span>,
197
+ <span class="hljs-attr">json</span>: <span class="hljs-string">&#x27;file-text&#x27;</span>, <span class="hljs-attr">md</span>: <span class="hljs-string">&#x27;file-text&#x27;</span> }[ext] ?? <span class="hljs-string">&#x27;file&#x27;</span>;
198
+ <span class="hljs-keyword">return</span> html`<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;d-b&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">k-icon</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;</span></span></span><span class="hljs-subst">${iconName}</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-icon</span>&gt;</span> </span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.value.name}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>`</span>;
199
+ }
200
+ <span class="hljs-title function_">getChildren</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }
201
+ <span class="hljs-keyword">static</span> detect = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">FileSystemFileHandle</span>;
202
+ }
203
+
204
+ <span class="hljs-keyword">class</span> <span class="hljs-title class_">DirHandleNode</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">TreeNode</span> {
205
+ <span class="hljs-keyword">static</span> properties = { ...<span class="hljs-title class_">TreeNode</span>.<span class="hljs-property">properties</span>, <span class="hljs-attr">entries</span>: { <span class="hljs-attr">state</span>: <span class="hljs-literal">true</span> } };
206
+
207
+ <span class="hljs-title function_">connectedCallback</span>(<span class="hljs-params"></span>){
208
+ <span class="hljs-variable language_">super</span>.<span class="hljs-title function_">connectedCallback</span>();
209
+ (<span class="hljs-title function_">async</span> () =&gt; {
210
+ <span class="hljs-keyword">const</span> entries = [];
211
+ <span class="hljs-keyword">for</span> <span class="hljs-title function_">await</span>(<span class="hljs-keyword">const</span> [name, handle] <span class="hljs-keyword">of</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">value</span>.<span class="hljs-title function_">entries</span>())
212
+ entries.<span class="hljs-title function_">push</span>([name, handle]);
213
+ <span class="hljs-variable language_">this</span>.<span class="hljs-property">entries</span> = entries;
214
+ })();
215
+ }
216
+
217
+ <span class="hljs-title function_">getChildren</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">entries</span> ?? []; }
218
+ <span class="hljs-title function_">renderIcon</span>(<span class="hljs-params"></span>){
219
+ <span class="hljs-keyword">return</span> html`<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-icon</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;</span></span></span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.opened ? <span class="hljs-string">&#x27;folder-open&#x27;</span> : <span class="hljs-string">&#x27;folder&#x27;</span>}</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-icon</span>&gt;</span>`</span>;
220
+ }
221
+ <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>){
222
+ <span class="hljs-keyword">const</span> children = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getChildren</span>();
223
+ <span class="hljs-keyword">return</span> html`<span class="language-xml">
224
+ <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
225
+ <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;branch-label no-btn&quot;</span> @<span class="hljs-attr">click</span>=</span></span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.toggle}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">aria-expanded</span>=<span class="hljs-string">&quot;</span></span></span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.opened}</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span>
226
+ </span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.renderIcon()}</span><span class="language-xml"> </span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.value.name}</span><span class="language-xml">
227
+ <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
228
+ </span><span class="hljs-subst">${<span class="hljs-variable language_">this</span>.opened ? html`<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;pl&quot;</span>&gt;</span></span><span class="hljs-subst">${children.map(([k, v]) =&gt; Tree.renderValue(v, k, <span class="hljs-variable language_">this</span>.depth + <span class="hljs-number">1</span>, <span class="hljs-variable language_">this</span>.maxDepth))}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>`</span> : <span class="hljs-string">&#x27;&#x27;</span>}</span><span class="language-xml">
229
+ <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
230
+ `</span>;
231
+ }
232
+ <span class="hljs-keyword">static</span> detect = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">FileSystemDirectoryHandle</span>;
233
+ }
234
+
235
+ <span class="hljs-title class_">Tree</span>.<span class="hljs-title function_">addNode</span>(<span class="hljs-title class_">FileHandleNode</span>, <span class="hljs-title class_">DirHandleNode</span>);
236
+
237
+ <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;browseBtn&#x27;</span>).<span class="hljs-property">onclick</span> = <span class="hljs-title function_">async</span> () =&gt; {
238
+ <span class="hljs-keyword">const</span> handle = <span class="hljs-keyword">await</span> <span class="hljs-title function_">showDirectoryPicker</span>();
239
+ <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;dirTree&#x27;</span>).<span class="hljs-property">data</span> = handle;
240
+ };
241
+ </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
242
+ </div>
243
+ <div class="col d-span-6 m-span-12 px">
244
+ <button id="browseBtn" class="btn">Browse Directory</button>
245
+ <k-tree id="dirTree" depth="1"></k-tree>
246
+ <script type="module">
247
+ import Tree, { TreeNode } from '{{pathToRoot}}src/components/Tree.js';
248
+ import { html } from '{{pathToRoot}}src/lit-all.min.js';
249
+
250
+ class FileHandleNode extends TreeNode {
251
+ render(){
252
+ const ext = this.value.name.split('.').pop().toLowerCase();
253
+ const iconName = { js: 'code', html: 'code_blocks', css: 'code',
254
+ json: 'file-text', md: 'file-text' }[ext] ?? 'file';
255
+ return html`<span class="d-b"><k-icon name="${iconName}"></k-icon> ${this.value.name}</span>`;
256
+ }
257
+ getChildren(){ return null; }
258
+ static detect = v => v instanceof FileSystemFileHandle;
259
+ }
260
+
261
+ class DirHandleNode extends TreeNode {
262
+ static properties = { ...TreeNode.properties, entries: { state: true } };
263
+
264
+ connectedCallback(){
265
+ super.connectedCallback();
266
+ (async () => {
267
+ const entries = [];
268
+ for await(const [name, handle] of this.value.entries())
269
+ entries.push([name, handle]);
270
+ this.entries = entries;
271
+ })();
272
+ }
273
+
274
+ getChildren(){ return this.entries ?? []; }
275
+ renderIcon(){
276
+ return html`<k-icon name="${this.opened ? 'folder-open' : 'folder'}"></k-icon>`;
277
+ }
278
+ render(){
279
+ const children = this.getChildren();
280
+ return html`
281
+ <div>
282
+ <button class="branch-label no-btn" @click=${this.toggle} aria-expanded="${this.opened}">
283
+ ${this.renderIcon()} ${this.value.name}
284
+ </button>
285
+ ${this.opened ? html`<div class="pl">${children.map(([k, v]) => Tree.renderValue(v, k, this.depth + 1, this.maxDepth))}</div>` : ''}
286
+ </div>
287
+ `;
288
+ }
289
+ static detect = v => v instanceof FileSystemDirectoryHandle;
290
+ }
291
+
292
+ Tree.addNode(FileHandleNode, DirHandleNode);
293
+
294
+ document.getElementById('browseBtn').onclick = async () => {
295
+ const handle = await showDirectoryPicker();
296
+ document.getElementById('dirTree').data = handle;
297
+ };
298
+ </script>
299
+ </div>
300
+ </div>
301
+
302
+ <h2 id="jsRef"><a href="jsRef" class="no-link">JavaScript Reference</a></h2>
303
+
304
+ <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
305
+ <h6>Extends <a href="./shadow-component.html">ShadowComponent</a></h6>
306
+ <h5><code>new Tree()</code></h5>
307
+ <p>Creates a new Tree component instance.</p>
308
+
309
+ <h3 id="requirements"><a href="#requirements" class="no-link">Requirements</a></h3>
310
+ <ul>
311
+ <li><a href="./shadow-component.html">ShadowComponent</a></li>
312
+ <li>lit-all.min.js</li>
313
+ </ul>
314
+
315
+ <h3 id="properties"><a href="#properties" class="no-link">Properties</a></h3>
316
+ <h4><code>data</code> <span class="tc-muted small">Object | Array</span></h4>
317
+ <p>The data to display in the tree. Can be any JavaScript object or array. Nested objects and arrays will be
318
+ rendered as collapsible branches.</p>
319
+
320
+ <h4><code>depth</code> <span class="tc-muted small">Number</span> <span class="tc-muted small">default: 0</span>
321
+ </h4>
322
+ <p>The number of branch levels that should be open by default. A value of <code>0</code> means all branches are
323
+ closed, <code>1</code> means the first level is open, <code>2</code> means the first two levels are open, etc.
324
+ This property is reflected as an attribute.</p>
325
+
326
+ <h4><code>editable</code> <span class="tc-muted small">Boolean</span></h4>
327
+ <p>Whether the tree should be editable. <em>Note: This feature is not yet implemented.</em></p>
328
+
329
+ <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
330
+
331
+ <h4><code>Tree.addNode(...nodeClasses)</code> <span class="tc-muted small">Static</span></h4>
332
+ <p>Register one or more custom node classes. Node classes should extend <code>TreeNode</code> and implement:</p>
333
+ <ul>
334
+ <li><code>static detect(value)</code> &mdash; Returns <code>true</code> if this node type should handle the given value</li>
335
+ <li><code>renderLabel()</code> &mdash; Returns a Lit template for the node's label (optional override)</li>
336
+ <li><code>getChildren()</code> &mdash; Returns <code>null</code> for leaf behavior, or an array of <code>[key, value]</code> pairs to render children (optional override)</li>
337
+ <li><code>renderIcon()</code> &mdash; Returns a Lit template for the branch toggle icon (optional override)</li>
338
+ </ul>
339
+ <p>Nodes are checked in order of registration (most recently added first).</p>
340
+
341
+ <p>The Tree component comes with built-in node types for JavaScript primitives:</p>
342
+ <ul>
343
+ <li><strong>StringNode</strong> &mdash; Renders strings in green with quotes</li>
344
+ <li><strong>NumberNode</strong> &mdash; Renders numbers in blue</li>
345
+ <li><strong>BooleanNode</strong> &mdash; Renders <code>true</code> in green, <code>false</code> in red</li>
346
+ <li><strong>NullNode</strong> &mdash; Renders <code>null</code> in muted gray</li>
347
+ <li><strong>UndefinedNode</strong> &mdash; Renders <code>undefined</code> in muted gray</li>
348
+ </ul>
349
+ <p>Objects and arrays that don't match any registered node type are rendered as collapsible branches using the default <code>TreeNode</code> behavior.</p>
350
+ </content>
351
+ <content location="scripts">
352
+ <script type="module" src="{{pathToRoot}}src/components/Tree.js"></script>
353
+ <script type="module" src="{{pathToRoot}}src/components/Accordion.js"></script>
354
+ <script type="module" src="{{pathToRoot}}src/components/Card.js"></script>
355
+ </content>
356
+ </page>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{title}}</title>
7
+ <link rel="icon" type="image/png" sizes="48x48" href="{{pathToRoot}}media/icon48.png">
8
+ <link rel="manifest" href="{{pathToRoot}}manifest.json" />
9
+ <link rel="stylesheet" href="{{pathToRoot}}kempo-vars.css" />
10
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kempo-css@2/dist/kempo.min.css" />
11
+ <link rel="stylesheet" href="{{pathToRoot}}kempo-hljs.css" />
12
+ <link rel="stylesheet" href="{{pathToRoot}}styles.css" />
13
+ <script>window.litDisableBundleWarning = true;</script>
14
+ <location name="head" />
15
+ </head>
16
+ <body>
17
+ <fragment name="nav" />
18
+ <location name="header">
19
+ <h1 class="ta-center">{{pageName}}</h1>
20
+ </location>
21
+ <k-main>
22
+ <location />
23
+ </k-main>
24
+ <div style="height:33vh"></div>
25
+ <script type="module" src="{{pathToRoot}}src/components/Main.js"></script>
26
+ <location name="scripts" />
27
+ </body>
28
+ </html>