@kubex/zinc 1.0.113 → 1.0.115

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 (101) hide show
  1. package/.github/workflows/eleventy_build.yml +5 -5
  2. package/.github/workflows/js_build_and_deploy.yaml +1 -1
  3. package/dist/custom-elements.json +2422 -190
  4. package/dist/vscode.html-custom-data.json +86 -5
  5. package/dist/web-types.json +251 -9
  6. package/dist/zn.d.ts +518 -340
  7. package/dist/zn.min.css +1 -1
  8. package/dist/zn.min.js +960 -882
  9. package/docs/eleventy.config.cjs +4 -2
  10. package/docs/pages/components/header.md +13 -0
  11. package/docs/pages/components/inline-edit.md +20 -0
  12. package/docs/pages/components/item.md +12 -1
  13. package/docs/pages/components/page.md +149 -0
  14. package/docs/pages/components/progress-bar.md +16 -0
  15. package/docs/pages/components/select.md +25 -0
  16. package/docs/pages/components/split-pane.md +6 -7
  17. package/docs/pages/components/tabs.md +59 -9
  18. package/package.json +8 -5
  19. package/scripts/build.js +40 -19
  20. package/scss/_global-spacing.scss +12 -1
  21. package/scss/_root.scss +34 -2
  22. package/scss/mixins/_spacing-mixins.scss +1 -1
  23. package/scss/shared/layout.scss +15 -2
  24. package/scss/themes/_light.scss +1 -1
  25. package/src/components/absolute-container/absolute-container.component.ts +9 -25
  26. package/src/components/animated-button/animated-button.test.ts +8 -8
  27. package/src/components/button/button.component.ts +3 -1
  28. package/src/components/button/button.scss +5 -0
  29. package/src/components/button-menu/button-menu.component.ts +36 -21
  30. package/src/components/button-menu/button-menu.test.ts +55 -1
  31. package/src/components/chart/chart.component.ts +7 -7
  32. package/src/components/collapsible/collapsible.component.ts +7 -14
  33. package/src/components/cols/cols.scss +1 -1
  34. package/src/components/content-block/content-block.component.ts +11 -33
  35. package/src/components/data-select/data-select.component.ts +7 -11
  36. package/src/components/data-select/data-select.scss +1 -0
  37. package/src/components/data-table/data-table.component.ts +10 -14
  38. package/src/components/dialog/dialog.scss +4 -0
  39. package/src/components/editor/modules/toolbar/toolbar.component.ts +5 -9
  40. package/src/components/expanding-action/expanding-action.component.ts +37 -43
  41. package/src/components/form-group/form-group.component.ts +32 -27
  42. package/src/components/form-group/form-group.scss +1 -0
  43. package/src/components/header/header.component.ts +6 -5
  44. package/src/components/header/header.scss +28 -26
  45. package/src/components/inline-edit/inline-edit.component.ts +13 -1
  46. package/src/components/inline-edit/inline-edit.test.ts +50 -0
  47. package/src/components/input/input.test.ts +77 -0
  48. package/src/components/input-group/input-group.test.ts +2 -10
  49. package/src/components/item/item.component.ts +12 -6
  50. package/src/components/item/item.scss +1 -1
  51. package/src/components/item/item.test.ts +8 -0
  52. package/src/components/navbar/navbar.component.ts +222 -48
  53. package/src/components/navbar/navbar.scss +134 -21
  54. package/src/components/navbar/navbar.test.ts +114 -9
  55. package/src/components/option/option.scss +5 -7
  56. package/src/components/option/option.test.ts +30 -0
  57. package/src/components/page/index.ts +13 -0
  58. package/src/components/page/page.component.ts +406 -0
  59. package/src/components/page/page.scss +325 -0
  60. package/src/components/page/page.test.ts +397 -0
  61. package/src/components/page-nav/page-nav.scss +7 -5
  62. package/src/components/pane/pane.component.ts +2 -2
  63. package/src/components/pane/pane.scss +0 -1
  64. package/src/components/pane/pane.test.ts +31 -0
  65. package/src/components/panel/panel.scss +5 -16
  66. package/src/components/progress-bar/progress-bar.component.ts +5 -2
  67. package/src/components/progress-bar/progress-bar.scss +17 -1
  68. package/src/components/progress-bar/progress-bar.test.ts +12 -0
  69. package/src/components/scroll-container/scroll-container.component.ts +22 -21
  70. package/src/components/select/select.component.ts +243 -39
  71. package/src/components/select/select.scss +36 -5
  72. package/src/components/select/select.test.ts +533 -0
  73. package/src/components/settings-container/settings-container.component.ts +15 -19
  74. package/src/components/settings-container/settings-container.scss +8 -8
  75. package/src/components/sidebar/sidebar.component.ts +11 -11
  76. package/src/components/simple-chart/simple-chart.component.ts +6 -7
  77. package/src/components/sp/sp.scss +46 -15
  78. package/src/components/sp/sp.test.ts +15 -0
  79. package/src/components/split-pane/split-pane.component.ts +153 -26
  80. package/src/components/split-pane/split-pane.scss +89 -13
  81. package/src/components/split-pane/split-pane.test.ts +187 -0
  82. package/src/components/style/style.component.ts +8 -0
  83. package/src/components/tab/index.ts +13 -0
  84. package/src/components/tab/tab.component.ts +25 -0
  85. package/src/components/tab/tab.scss +7 -0
  86. package/src/components/table/table.component.ts +7 -2
  87. package/src/components/table/table.scss +1 -0
  88. package/src/components/tabs/tabs.component.ts +75 -70
  89. package/src/components/tabs/tabs.scss +1 -1
  90. package/src/components/textarea/textarea.component.ts +5 -8
  91. package/src/components/tile/tile.scss +2 -2
  92. package/src/components/translation-group/translation-group.component.ts +15 -14
  93. package/src/components/translations/translations.component.ts +18 -17
  94. package/src/components/translations/translations.scss +1 -0
  95. package/src/components/translations/translations.test.ts +3 -2
  96. package/src/internal/form.ts +234 -0
  97. package/src/internal/theme.ts +26 -46
  98. package/src/internal/zinc-element.ts +12 -7
  99. package/src/utilities/form.ts +1 -0
  100. package/src/wc.scss +1 -1
  101. package/src/zinc.ts +3 -0
@@ -93,12 +93,14 @@ module.exports = function (eleventyConfig)
93
93
  //
94
94
  eleventyConfig.addFilter('markdown', content =>
95
95
  {
96
- return zincFlavoredMarkdown.render(content);
96
+ // CEM members (events, slots, CSS props/parts, animations) may have no description, in which case
97
+ // `content` is undefined. markdown-it calls .replace on its input and would throw, so coerce to ''.
98
+ return typeof content === 'string' ? zincFlavoredMarkdown.render(content) : '';
97
99
  });
98
100
 
99
101
  eleventyConfig.addFilter('markdownInline', content =>
100
102
  {
101
- return zincFlavoredMarkdown.renderInline(content);
103
+ return typeof content === 'string' ? zincFlavoredMarkdown.renderInline(content) : '';
102
104
  });
103
105
 
104
106
  // Trims whitespace and pipes from the start and end of a string. Useful for CEM types, which can be pipe-delimited.
@@ -20,8 +20,21 @@ layout: component
20
20
  </div>
21
21
  ```
22
22
 
23
+ The breadcrumb slot renders inline with the page title — each slotted link is followed by a `>` separator and the `caption` becomes the final, unlinked item in the trail. Set `hide-breadcrumb` to suppress the trail and show only the title.
24
+
23
25
  ## Examples
24
26
 
27
+ ### Hide breadcrumb
28
+
29
+ ```html:preview
30
+ <div style="background-color: #f5f5f5; padding: 20px;">
31
+ <zn-header caption="John Jones" hide-breadcrumb>
32
+ <a href="#" slot="breadcrumb">Dashboard</a>
33
+ <a href="#" slot="breadcrumb">Another</a>
34
+ </zn-header>
35
+ </div>
36
+ ```
37
+
25
38
  ### Simple Header
26
39
 
27
40
  ```html:preview
@@ -151,6 +151,26 @@ Add the `search` attribute to enable filtering on select inputs. Users can type
151
151
  </div>
152
152
  ```
153
153
 
154
+ ### Free Text Select
155
+
156
+ Add the `free-text` attribute to let users enter values that aren't in the options list (see [`zn-select`](/components/select#free-text-entry)). `free-text` implies a select input, so you don't need `input-type="select"`. Combine it with `multiple` for a tag-style editor.
157
+
158
+ ```html:preview
159
+ <div class="form-spacing">
160
+ <zn-inline-edit name="status" value="active" free-text>
161
+ <zn-option value="active">Active</zn-option>
162
+ <zn-option value="inactive">Inactive</zn-option>
163
+ <zn-option value="pending">Pending</zn-option>
164
+ </zn-inline-edit>
165
+
166
+ <zn-inline-edit name="tags" free-text multiple value="urgent backend">
167
+ <zn-option value="urgent">Urgent</zn-option>
168
+ <zn-option value="backend">Backend</zn-option>
169
+ <zn-option value="frontend">Frontend</zn-option>
170
+ </zn-inline-edit>
171
+ </div>
172
+ ```
173
+
154
174
  ### Data Select with Provider
155
175
 
156
176
  Use the `provider` attribute to integrate with data select providers like countries, currencies, or colors.
@@ -37,6 +37,18 @@ layout: component
37
37
  </zn-item>
38
38
  ```
39
39
 
40
+ ### Right Aligned Content
41
+
42
+ Use `align-end` to right align the content value.
43
+
44
+ ```html:preview
45
+ <zn-sp divide no-gap>
46
+ <zn-item caption="Subtotal" align-end>$120.00</zn-item>
47
+ <zn-item caption="Tax" align-end>$24.00</zn-item>
48
+ <zn-item caption="Total" align-end>$144.00</zn-item>
49
+ </zn-sp>
50
+ ```
51
+
40
52
  ### Icons
41
53
 
42
54
  ```html:preview
@@ -93,4 +105,3 @@ Example of multiple actions in a description item.
93
105
 
94
106
  </zn-item>
95
107
  ```
96
-
@@ -0,0 +1,149 @@
1
+ ---
2
+ meta:
3
+ title: Page
4
+ description: Pages combine a header with tabbed content.
5
+ layout: component
6
+ ---
7
+
8
+ ```html:preview
9
+ <zn-page caption="Page Title" summary="Page Summary">
10
+ <zn-button slot="actions" type="primary" size="small" href="/ui">UI Examples</zn-button>
11
+
12
+ <zn-tab caption="Overview">
13
+ Overview Content
14
+ </zn-tab>
15
+
16
+ <zn-tab caption="Tab One">
17
+ Tab One Content
18
+ </zn-tab>
19
+
20
+ <zn-tab caption="Tab Two" id="tab-2">
21
+ Tab Two Content
22
+ </zn-tab>
23
+
24
+ <zn-tab caption="Dynamic Tab" uri="/tab-three"></zn-tab>
25
+ </zn-page>
26
+ ```
27
+
28
+ ## Examples
29
+
30
+ ### Header Actions
31
+
32
+ Use `slot="actions"` to place controls in the page header action area.
33
+
34
+ ```html:preview
35
+ <zn-page caption="Customers" summary="Manage active customers">
36
+ <zn-button slot="actions" color="secondary" size="small">Export</zn-button>
37
+ <zn-button slot="actions" color="primary" size="small">New Customer</zn-button>
38
+
39
+ <zn-tab caption="Overview">
40
+ Customer overview content
41
+ </zn-tab>
42
+
43
+ <zn-tab caption="Active">
44
+ Active customer content
45
+ </zn-tab>
46
+
47
+ <zn-tab caption="Archived">
48
+ Archived customer content
49
+ </zn-tab>
50
+ </zn-page>
51
+ ```
52
+
53
+ ### Header Metadata
54
+
55
+ `zn-page` supports the same header metadata attributes as `zn-header`: `full-location`, `entity-id`, `entity-id-show`, `previous-path`, and `previous-target`.
56
+
57
+ ```html:preview
58
+ <zn-page
59
+ caption="Customer Comms"
60
+ summary="This is a description about the purpose of this page."
61
+ full-location="/customers/comms"
62
+ entity-id="customer-comms"
63
+ previous-path="/customers">
64
+ <zn-tab caption="Overview">
65
+ Overview content
66
+ </zn-tab>
67
+ </zn-page>
68
+ ```
69
+
70
+ ### Breadcrumbs
71
+
72
+ Breadcrumb links can be passed with `slot="breadcrumb"` and will be forwarded to the underlying header.
73
+
74
+ ```html:preview
75
+ <zn-page caption="Account Settings" summary="Configure account preferences">
76
+ <a href="#" slot="breadcrumb">Accounts</a>
77
+ <a href="#" slot="breadcrumb">Acme Inc</a>
78
+
79
+ <zn-tab caption="Profile">
80
+ Profile content
81
+ </zn-tab>
82
+
83
+ <zn-tab caption="Security">
84
+ Security content
85
+ </zn-tab>
86
+ </zn-page>
87
+ ```
88
+
89
+ ### Overview Content
90
+
91
+ Use a normal `zn-tab` for overview content. An Overview tab without an explicit `id` uses the default empty tab id. `zn-page` leaves tab elements in the page light DOM and projects them into internal tab panels, so scoped styles from the original DOM context continue to apply.
92
+ Tabs render in the order they appear in the page by default. Tabs with an empty id are shown first. Set `priority` on `zn-tab` to order the remaining tabs without changing their DOM position.
93
+
94
+ ```html:preview
95
+ <zn-page caption="Project" summary="Current project status">
96
+ <zn-tab caption="Overview">
97
+ <zn-note open>
98
+ This summary appears in the Overview tab.
99
+ </zn-note>
100
+ </zn-tab>
101
+
102
+ <zn-tab caption="Activity">
103
+ Activity content
104
+ </zn-tab>
105
+
106
+ <zn-tab caption="Files">
107
+ Files content
108
+ </zn-tab>
109
+ </zn-page>
110
+ ```
111
+
112
+ ### Tab Priority
113
+
114
+ Use `priority` to control tab order. Lower numbers appear first after the empty-id overview tab.
115
+
116
+ ```html:preview
117
+ <zn-page caption="Ordered Page" summary="Priority controls the navigation order">
118
+ <zn-tab caption="Later">
119
+ Later content
120
+ </zn-tab>
121
+
122
+ <zn-tab caption="Second" priority="20">
123
+ Second content
124
+ </zn-tab>
125
+
126
+ <zn-tab caption="Overview">
127
+ Overview content
128
+ </zn-tab>
129
+
130
+ <zn-tab caption="First" priority="10">
131
+ First content
132
+ </zn-tab>
133
+ </zn-page>
134
+ ```
135
+
136
+ ### Dynamic Tabs
137
+
138
+ Set `uri` on `zn-tab` to create a dynamic tab. The generated navigation item receives `tab-uri`.
139
+
140
+ ```html:preview
141
+ <zn-page caption="Reports" summary="Load reports on demand">
142
+ <zn-tab caption="Overview">
143
+ Report overview content
144
+ </zn-tab>
145
+
146
+ <zn-tab caption="Revenue" uri="/reports/revenue"></zn-tab>
147
+ <zn-tab caption="Usage" uri="/reports/usage"></zn-tab>
148
+ </zn-page>
149
+ ```
@@ -25,6 +25,22 @@ A basic progress bar displays the completion percentage using the `value` attrib
25
25
  <zn-progress-bar value="100"></zn-progress-bar>
26
26
  ```
27
27
 
28
+ ### Color Options
29
+
30
+ Use the `color` attribute to set the progress fill color. Supported options are `current`, `info`, `danger`, `success`, and `warning`.
31
+
32
+ ```html:preview
33
+ <zn-progress-bar color="current" value="40"></zn-progress-bar>
34
+ <br />
35
+ <zn-progress-bar color="info" value="50"></zn-progress-bar>
36
+ <br />
37
+ <zn-progress-bar color="danger" value="60"></zn-progress-bar>
38
+ <br />
39
+ <zn-progress-bar color="success" value="70"></zn-progress-bar>
40
+ <br />
41
+ <zn-progress-bar color="warning" value="80"></zn-progress-bar>
42
+ ```
43
+
28
44
  ### With Caption
29
45
 
30
46
  Use the `caption` attribute to add a label above the progress bar. This helps identify what the progress bar represents.
@@ -185,6 +185,31 @@ Combine `search` with `multiple` to allow users to search and select multiple op
185
185
  </zn-select>
186
186
  ```
187
187
 
188
+ ### Free Text Entry
189
+
190
+ Use the `free-text` attribute to let users enter values that aren't in the options list. `free-text` implies the editable, filtering input behavior of `search`, so users can both filter existing options and add their own. When the typed text doesn't match an existing option, an **Add "…"** row appears at the top of the listbox; committing it (by pressing <kbd>Enter</kbd>, clicking the Add row, or blurring the field) adds the value as a selection. A committed value becomes both the option's value and its label.
191
+
192
+ If the typed text exactly matches an existing option (by label or value, case-insensitive), the Add row is suppressed and the existing option is selected instead — so no duplicates are created.
193
+
194
+ ```html:preview
195
+ <zn-select label="Add tags" free-text placeholder="Type a tag and press Enter">
196
+ <zn-option value="bug">Bug</zn-option>
197
+ <zn-option value="feature">Feature</zn-option>
198
+ <zn-option value="chore">Chore</zn-option>
199
+ </zn-select>
200
+ ```
201
+
202
+ ### Free Text with Multiple Selection
203
+
204
+ Combine `free-text` with `multiple` to build a tag-style input. Each committed value is added as a tag and the input stays open so users can keep entering values. Removing a tag whose value was entered as free text deletes it entirely.
205
+
206
+ ```html:preview
207
+ <zn-select label="Recipients" free-text multiple clearable placeholder="Add email addresses...">
208
+ <zn-option value="support@example.com">support@example.com</zn-option>
209
+ <zn-option value="sales@example.com">sales@example.com</zn-option>
210
+ </zn-select>
211
+ ```
212
+
188
213
  ### Remote Search
189
214
 
190
215
  When `search` and `data-uri` are used together, typing in the select sends debounced requests to the server instead of filtering locally. The search term is appended as a query parameter (default `q`). Use `search-param` to customise the parameter name, `search-debounce` to control the delay, and `max-results` to cap displayed results.
@@ -67,15 +67,15 @@ Use the `pixels` attribute to switch from percentage-based sizing to pixel-based
67
67
 
68
68
  ### Min and Max Size
69
69
 
70
- Use `min-size` and `max-size` to constrain how much users can resize the primary pane. These values match the unit type (percentage or pixels).
70
+ Use `min-size` and `max-size` to constrain how much users can resize the primary pane. Use `min-secondary-size` to keep the secondary pane above a minimum size. These values match the unit type (percentage or pixels).
71
71
 
72
72
  ```html:preview
73
- <zn-split-pane min-size="20" max-size="80" style="height: 300px;">
73
+ <zn-split-pane min-size="20" max-size="80" min-secondary-size="30" style="height: 300px;">
74
74
  <div slot="primary" style="padding: 20px; background: #f5f5f5;">
75
- <p>Primary pane can be resized between 20% and 80%</p>
75
+ <p>Primary pane can be resized between 20% and 70%</p>
76
76
  </div>
77
77
  <div slot="secondary" style="padding: 20px;">
78
- <p>Secondary pane adjusts accordingly</p>
78
+ <p>Secondary pane stays at least 30%</p>
79
79
  </div>
80
80
  </zn-split-pane>
81
81
  ```
@@ -83,12 +83,12 @@ Use `min-size` and `max-size` to constrain how much users can resize the primary
83
83
  With pixel sizing:
84
84
 
85
85
  ```html:preview
86
- <zn-split-pane pixels min-size="150" max-size="400" initial-size="250" style="height: 300px;">
86
+ <zn-split-pane pixels min-size="150" max-size="400" min-secondary-size="200" initial-size="250" style="height: 300px;">
87
87
  <div slot="primary" style="padding: 20px; background: #f5f5f5;">
88
88
  <p>Primary pane can be resized between 150px and 400px</p>
89
89
  </div>
90
90
  <div slot="secondary" style="padding: 20px;">
91
- <p>Secondary pane fills remaining space</p>
91
+ <p>Secondary pane stays at least 200px wide</p>
92
92
  </div>
93
93
  </zn-split-pane>
94
94
  ```
@@ -458,4 +458,3 @@ The split pane exposes CSS variables for advanced customization.
458
458
  </div>
459
459
  </zn-split-pane>
460
460
  ```
461
-
@@ -28,7 +28,9 @@ layout: component
28
28
 
29
29
  ### Basic Tabs
30
30
 
31
- The tabs component works by connecting tab navigation elements (typically in a `zn-navbar` in the `top` slot) with content panels. Each panel is identified by an `id` attribute, and navigation items use a `tab` attribute to reference those IDs.
31
+ The tabs component works by connecting tab navigation elements (typically in a `zn-navbar` in the `top` slot) with
32
+ content panels. Each panel is identified by an `id` attribute, and navigation items use a `tab` attribute to reference
33
+ those IDs.
32
34
 
33
35
  ```html:preview
34
36
  <zn-tabs flush>
@@ -52,6 +54,46 @@ The tabs component works by connecting tab navigation elements (typically in a `
52
54
  </zn-tabs>
53
55
  ```
54
56
 
57
+ ### Overflow
58
+
59
+ When there are more tabs than can fit in the available space, the component will automatically show an overflow menu.
60
+ This allows users to access all tabs even on smaller screens.
61
+
62
+ ```html:preview
63
+ <zn-tabs flush>
64
+ <zn-navbar slot="top">
65
+ <li tab="">Tab 1</li>
66
+ <li tab="tab2">Lorem IPsum dolor sit amet. Lorem Ipsum Dolor sit Amet</li>
67
+ <li tab="tab3">Tab 3</li>
68
+ <li tab="tab4">Tab 4</li>
69
+ <li tab="tab5">This is Tab 5</li>
70
+ <li tab="tab6">This is Tab 6</li>
71
+ <li tab="tab7">This is Tab 7</li>
72
+ </zn-navbar>
73
+ <zn-sp id="">
74
+ <p>Content for Tab 1.</p>
75
+ </zn-sp>
76
+ <zn-sp id="tab2">
77
+ <p>Content for Tab 2.</p>
78
+ </zn-sp>
79
+ <zn-sp id="tab3">
80
+ <p>Content for Tab 3.</p>
81
+ </zn-sp>
82
+ <zn-sp id="tab4">
83
+ <p>Content for Tab 4.</p>
84
+ </zn-sp>
85
+ <zn-sp id="tab5">
86
+ <p>Content for Tab 5.</p>
87
+ </zn-sp>
88
+ <zn-sp id="tab6">
89
+ <p>Content for Tab 6.</p>
90
+ </zn-sp>
91
+ <zn-sp id="tab7">
92
+ <p>Content for Tab 7.</p>
93
+ </zn-sp>
94
+ </zn-tabs>
95
+ ```
96
+
55
97
  ### With Caption and Description
56
98
 
57
99
  Use the `caption` and `description` attributes to add a header to your tabs component.
@@ -103,7 +145,8 @@ Remove the `caption` attribute for a cleaner layout when a header is not needed.
103
145
 
104
146
  ### Dynamic Tabs with URI Loading
105
147
 
106
- Use the `tab-uri` attribute to load content dynamically from a URL when a tab is clicked. The component will automatically fetch and display the content.
148
+ Use the `tab-uri` attribute to load content dynamically from a URL when a tab is clicked. The component will
149
+ automatically fetch and display the content.
107
150
 
108
151
  ```html:preview
109
152
  <zn-tabs flush no-prefetch>
@@ -117,7 +160,8 @@ Use the `tab-uri` attribute to load content dynamically from a URL when a tab is
117
160
 
118
161
  ### Prefetching
119
162
 
120
- By default, tabs with `tab-uri` will prefetch content on hover. Use the `no-prefetch` attribute to disable this behavior and only load content when clicked.
163
+ By default, tabs with `tab-uri` will prefetch content on hover. Use the `no-prefetch` attribute to disable this behavior
164
+ and only load content when clicked.
121
165
 
122
166
  ```html:preview
123
167
  <zn-tabs flush no-prefetch>
@@ -156,7 +200,8 @@ Use the `active` attribute to specify which tab should be active by default.
156
200
 
157
201
  ### Storage Persistence
158
202
 
159
- Use `store-key` to persist the active tab selection across page reloads. By default, uses session storage with a 5-minute TTL. Use `local-storage` for persistent storage beyond the session.
203
+ Use `store-key` to persist the active tab selection across page reloads. By default, uses session storage with a
204
+ 5-minute TTL. Use `local-storage` for persistent storage beyond the session.
160
205
 
161
206
  ```html:preview
162
207
  <zn-tabs flush store-key="my-tabs">
@@ -182,7 +227,8 @@ Use `store-key` to persist the active tab selection across page reloads. By defa
182
227
 
183
228
  ### Local Storage
184
229
 
185
- Use `local-storage` with `store-key` to persist tabs across browser sessions. Control expiration with `store-ttl` (in seconds).
230
+ Use `local-storage` with `store-key` to persist tabs across browser sessions. Control expiration with `store-ttl` (in
231
+ seconds).
186
232
 
187
233
  ```html:preview
188
234
  <zn-tabs flush store-key="persistent-tabs" local-storage store-ttl="86400">
@@ -268,10 +314,12 @@ Use the `full-width` attribute to make tab content expand to fill the available
268
314
 
269
315
  ### Split Pane Layout
270
316
 
271
- Use the `split` attribute with a pixel value to create a split pane layout with resizable sections. Control minimum and maximum sizes with `split-min` and `split-max`.
317
+ Use the `split` attribute with a pixel value to create a split pane layout with resizable sections. Control minimum and
318
+ maximum primary sizes with `split-min` and `split-max`, and keep the secondary pane above a minimum width with
319
+ `split-min-secondary`.
272
320
 
273
321
  ```html:preview
274
- <zn-tabs split="300" split-min="200" split-max="600">
322
+ <zn-tabs split="300" split-min="200" split-max="600" split-min-secondary="320">
275
323
  <zn-navbar slot="left">
276
324
  <li tab="">Navigation</li>
277
325
  <li tab="menu2">Menu 2</li>
@@ -344,7 +392,8 @@ The tabs component provides multiple slots for flexible layouts.
344
392
 
345
393
  ### Actions Slot
346
394
 
347
- Use the `actions` slot to add action buttons that appear in the header. Elements can be conditionally shown based on the active tab using `ref-tab`.
395
+ Use the `actions` slot to add action buttons that appear in the header. Elements can be conditionally shown based on the
396
+ active tab using `ref-tab`.
348
397
 
349
398
  ```html:preview
350
399
  <zn-tabs caption="Document Editor">
@@ -418,7 +467,8 @@ Access tab methods programmatically to switch tabs, navigate, or refresh content
418
467
 
419
468
  ### Tab Refresh
420
469
 
421
- Triple-clicking an active tab or using the refresh parameter will reload dynamic content. Hold Alt while clicking to force a refresh.
470
+ Triple-clicking an active tab or using the refresh parameter will reload dynamic content. Hold Alt while clicking to
471
+ force a refresh.
422
472
 
423
473
  ```html:preview
424
474
  <zn-tabs flush>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubex/zinc",
3
- "version": "1.0.113",
3
+ "version": "1.0.115",
4
4
  "description": "A collection of web components for building web applications based off of @shoelace-style/Shoelace",
5
5
  "keywords": [
6
6
  "web components",
@@ -28,6 +28,7 @@
28
28
  "unpkg": "dist/zinc.min.js",
29
29
  "scripts": {
30
30
  "build": "node scripts/build.js",
31
+ "build:docs": "node scripts/build.js --with-docs",
31
32
  "build:vite": "vite build",
32
33
  "check-updates": "npx npm-check-updates --interactive --format group",
33
34
  "create": "plop --plopfile scripts/plop/plopfile.js",
@@ -37,19 +38,21 @@
37
38
  "test": "npx playwright install --with-deps && web-test-runner --group default",
38
39
  "test:component": "npx playwright install --with-deps && web-test-runner -- --watch --group",
39
40
  "test:watch": "npx playwright install --with-deps && web-test-runner --watch --group default",
40
- "watch": "node scripts/build.js --serve"
41
+ "watch": "node scripts/build.js --serve",
42
+ "watch:docs": "node scripts/build.js --serve --with-docs"
41
43
  },
42
44
  "dependencies": {
43
45
  "@emoji-mart/data": "^1.2.1",
44
46
  "@floating-ui/dom": "^1.6.13",
45
47
  "@lit-labs/observers": "^2.0.4",
48
+ "@lit-labs/signals": "^0.3.0",
46
49
  "@lit/task": "^1.0.1",
47
50
  "@shoelace-style/localize": "^3.2.1",
48
51
  "air-datepicker": "^3.5.3",
49
52
  "composed-offset-position": "^0.0.6",
50
53
  "echarts": "^6.0.0",
51
54
  "emoji-mart": "^5.6.0",
52
- "lit": "^2.7.6",
55
+ "lit": "^3.3.3",
53
56
  "marked": "^18.0.2",
54
57
  "quill": "^2.0.3"
55
58
  },
@@ -115,9 +118,9 @@
115
118
  "strip-css-comments": "^5.0.0",
116
119
  "tailwindcss": "^3.4.17",
117
120
  "tslib": "^2.8.1",
118
- "typescript": "^5.3.3",
121
+ "typescript": "5.8.3",
119
122
  "user-agent-data-types": "^0.4.2"
120
123
  },
121
- "customElements": "./dist/custom-elements.json",
124
+ "customElements": "dist/custom-elements.json",
122
125
  "web-types": "./dist/web-types.json"
123
126
  }
package/scripts/build.js CHANGED
@@ -21,7 +21,10 @@ const postCss = postCSS([
21
21
  minify()
22
22
  ]);
23
23
 
24
- const {serve} = commandLineArgs([{name: 'serve', type: Boolean}]);
24
+ const {serve, 'with-docs': withDocs} = commandLineArgs([
25
+ {name: 'serve', type: Boolean},
26
+ {name: 'with-docs', type: Boolean}
27
+ ]);
25
28
  const outDir = 'dist';
26
29
  const siteDir = '_site';
27
30
  const spinner = ora({hideCursor: false}).start();
@@ -256,13 +259,16 @@ if(serve)
256
259
  {
257
260
  let result;
258
261
 
259
- // Spin up Eleventy and Wait for the search index to appear before proceeding. The search index is generated during
260
- // eleventy.after, so it appears after the docs are fully published. This is kinda hacky, but here we are.
261
- // Kick off the Eleventy dev server with --watch and --incremental
262
- await nextTask('Building the docs', async () =>
262
+ if(withDocs)
263
263
  {
264
- result = await buildTheDocs(true);
265
- });
264
+ // Spin up Eleventy and Wait for the search index to appear before proceeding. The search index is generated during
265
+ // eleventy.after, so it appears after the docs are fully published. This is kinda hacky, but here we are.
266
+ // Kick off the Eleventy dev server with --watch and --incremental
267
+ await nextTask('Building the docs', async () =>
268
+ {
269
+ result = await buildTheDocs(true);
270
+ });
271
+ }
266
272
 
267
273
  const bs = browserSync.create();
268
274
  const port = await getPort({port: portNumbers(4000, 4999)});
@@ -275,31 +281,43 @@ if(serve)
275
281
  notify: false,
276
282
  single: false,
277
283
  ghostMode: false,
278
- server: {
284
+ open: withDocs,
285
+ ui: withDocs ? undefined : false,
286
+ server: withDocs ? {
279
287
  baseDir: siteDir,
280
288
  routes: {
281
289
  '/dist': outDir
282
290
  }
283
- }
291
+ } : false
284
292
  };
285
293
 
286
294
  // Launch BrowserSync
287
295
  bs.init(bsConfig, () =>
288
296
  {
289
- const url = `http://localhost:${port}`;
290
- console.log(chalk.cyan(`\nšŸš€ Server running at ${url}`));
297
+ if(withDocs)
298
+ {
299
+ const url = `http://localhost:${port}`;
300
+ console.log(chalk.cyan(`\nšŸš€ Server running at ${url}`));
301
+ }
302
+ else
303
+ {
304
+ console.log(chalk.cyan('\nšŸ‘€ Watching source files (run with --with-docs for the docs server)'));
305
+ }
291
306
 
292
307
  // log deferred output
293
- if(result.output.length > 0)
308
+ if(result && result.output.length > 0)
294
309
  {
295
310
  console.log('\n' + result.output.join('\n'));
296
311
  }
297
312
 
298
313
  // Log output that comes later on
299
- result.child.stdout.on('data', data =>
314
+ if(result)
300
315
  {
301
- console.log(data.toString());
302
- });
316
+ result.child.stdout.on('data', data =>
317
+ {
318
+ console.log(data.toString());
319
+ });
320
+ }
303
321
  });
304
322
 
305
323
  // Rebuild and reload then source files change
@@ -351,15 +369,18 @@ if(serve)
351
369
  });
352
370
 
353
371
  // Reload without rebuilding when docs change
354
- bs.watch([`${siteDir}/**/*.*`]).on('change', () =>
372
+ if(withDocs)
355
373
  {
356
- bs.reload();
357
- });
374
+ bs.watch([`${siteDir}/**/*.*`]).on('change', () =>
375
+ {
376
+ bs.reload();
377
+ });
378
+ }
358
379
 
359
380
  }
360
381
 
361
382
  // Build for production
362
- if(!serve)
383
+ if(!serve && withDocs)
363
384
  {
364
385
  let result;
365
386
 
@@ -1,5 +1,9 @@
1
1
  @use "mixins";
2
2
 
3
+ .zn-gutter {
4
+ margin: 0 var(--zn-gutter);
5
+ }
6
+
3
7
  .zn-gap {
4
8
  @include mixins.gap();
5
9
  @include mixins.padding();
@@ -62,9 +66,16 @@
62
66
  }
63
67
 
64
68
  .form-spacing ~ .form-spacing {
65
- margin-top: var(--zn-spacing-medium);
69
+ margin-top: var(--zn-base-gap);
66
70
  }
67
71
 
72
+ zn-form-group ~ zn-form-group {
73
+ margin-top: var(--zn-base-gap);
74
+ padding-top: var(--zn-base-gap);
75
+ border-top: 1px solid rgb(var(--zn-border-color));
76
+ }
77
+
78
+
68
79
  .form-spacing > * {
69
80
  grid-column: span 6 / span 6;
70
81
  }