@kubex/zinc 1.0.25 → 1.0.99

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 (199) hide show
  1. package/.claude/project.md +556 -0
  2. package/.github/workflows/js_build_and_deploy.yaml +9 -10
  3. package/dist/custom-elements.json +13575 -8856
  4. package/dist/vscode.html-custom-data.json +583 -48
  5. package/dist/web-types.json +1441 -181
  6. package/dist/zn.d.ts +1645 -660
  7. package/dist/zn.min.css +1 -1
  8. package/dist/zn.min.js +1412 -893
  9. package/docs/_utilities/code-previews.cjs +10 -1
  10. package/docs/assets/scripts/docs.js +42 -18
  11. package/docs/data/data-table.json +229 -66
  12. package/docs/data/empty.json +6 -0
  13. package/docs/data/products-table.json +41 -193
  14. package/docs/pages/components/action-bar.md +121 -6
  15. package/docs/pages/components/alert.md +118 -15
  16. package/docs/pages/components/animated-button.md +299 -0
  17. package/docs/pages/components/audio-select.md +534 -0
  18. package/docs/pages/components/bulk-actions.md +79 -5
  19. package/docs/pages/components/button-group.md +235 -27
  20. package/docs/pages/components/button.md +139 -1
  21. package/docs/pages/components/chart.md +365 -9
  22. package/docs/pages/components/checkbox.md +387 -58
  23. package/docs/pages/components/chip.md +253 -33
  24. package/docs/pages/components/collapsible.md +393 -46
  25. package/docs/pages/components/cols.md +152 -30
  26. package/docs/pages/components/confirm.md +182 -16
  27. package/docs/pages/components/copy-button.md +169 -6
  28. package/docs/pages/components/data-select.md +194 -15
  29. package/docs/pages/components/data-table-filter.md +96 -5
  30. package/docs/pages/components/data-table-search.md +451 -0
  31. package/docs/pages/components/data-table-sort.md +66 -5
  32. package/docs/pages/components/data-table.md +727 -66
  33. package/docs/pages/components/datepicker.md +402 -7
  34. package/docs/pages/components/defined-label.md +120 -5
  35. package/docs/pages/components/dialog.md +339 -59
  36. package/docs/pages/components/dropdown.md +366 -11
  37. package/docs/pages/components/editor.md +604 -7
  38. package/docs/pages/components/empty-state.md +315 -16
  39. package/docs/pages/components/expanding-action.md +212 -28
  40. package/docs/pages/components/file.md +421 -12
  41. package/docs/pages/components/filter-container.md +158 -5
  42. package/docs/pages/components/filter-wrapper.md +167 -6
  43. package/docs/pages/components/form-group.md +383 -6
  44. package/docs/pages/components/hover-container.md +237 -6
  45. package/docs/pages/components/icon-picker.md +121 -0
  46. package/docs/pages/components/icon.md +454 -48
  47. package/docs/pages/components/inline-edit.md +787 -19
  48. package/docs/pages/components/input-group.md +207 -13
  49. package/docs/pages/components/input.md +194 -0
  50. package/docs/pages/components/item.md +18 -0
  51. package/docs/pages/components/key-container.md +115 -0
  52. package/docs/pages/components/key.md +101 -0
  53. package/docs/pages/components/menu.md +512 -6
  54. package/docs/pages/components/note.md +239 -36
  55. package/docs/pages/components/opt-group.md +107 -0
  56. package/docs/pages/components/pagination.md +332 -6
  57. package/docs/pages/components/pane.md +222 -6
  58. package/docs/pages/components/panel.md +213 -26
  59. package/docs/pages/components/popup.md +1354 -6
  60. package/docs/pages/components/priority-list.md +233 -0
  61. package/docs/pages/components/progress-bar.md +387 -6
  62. package/docs/pages/components/radio-group.md +242 -5
  63. package/docs/pages/components/radio.md +474 -6
  64. package/docs/pages/components/rating.md +331 -7
  65. package/docs/pages/components/reveal.md +524 -6
  66. package/docs/pages/components/scroll-container.md +552 -6
  67. package/docs/pages/components/select.md +762 -160
  68. package/docs/pages/components/skeleton.md +473 -30
  69. package/docs/pages/components/slideout.md +261 -5
  70. package/docs/pages/components/sp.md +99 -41
  71. package/docs/pages/components/split-button.md +347 -9
  72. package/docs/pages/components/split-pane.md +445 -6
  73. package/docs/pages/components/stat.md +549 -9
  74. package/docs/pages/components/status-indicator.md +230 -1
  75. package/docs/pages/components/stepper.md +563 -6
  76. package/docs/pages/components/tabs.md +439 -13
  77. package/docs/pages/components/textarea.md +415 -17
  78. package/docs/pages/components/tile.md +385 -26
  79. package/docs/pages/components/toggle.md +424 -6
  80. package/docs/pages/components/tooltip.md +367 -0
  81. package/docs/pages/components/translation-group.md +210 -0
  82. package/docs/pages/components/translations.md +319 -19
  83. package/docs/pages/components/vertical-stepper.md +401 -8
  84. package/docs/pages/components/well.md +300 -3
  85. package/docs/pages/getting-started/form-controls.md +162 -0
  86. package/docs/pages/index.md +116 -15
  87. package/package.json +5 -6
  88. package/scss/_global-spacing.scss +4 -0
  89. package/scss/_root.scss +2 -2
  90. package/scss/boot.scss +19 -0
  91. package/scss/shared/layout.scss +5 -0
  92. package/scss/themes/_light.scss +3 -3
  93. package/src/components/alert/alert.scss +1 -0
  94. package/src/components/animated-button/README.md +306 -0
  95. package/src/components/animated-button/animated-button.component.ts +229 -0
  96. package/src/components/animated-button/animated-button.scss +228 -0
  97. package/src/components/animated-button/animated-button.test.ts +143 -0
  98. package/src/components/animated-button/index.ts +12 -0
  99. package/src/components/button/button.component.ts +5 -0
  100. package/src/components/button-group/button-group.component.ts +25 -13
  101. package/src/components/button-group/button-group.scss +6 -0
  102. package/src/components/checkbox/checkbox.component.ts +4 -0
  103. package/src/components/checkbox/checkbox.scss +7 -4
  104. package/src/components/checkbox-group/checkbox-group.scss +7 -0
  105. package/src/components/chip/chip.component.ts +7 -2
  106. package/src/components/chip/chip.scss +16 -2
  107. package/src/components/collapsible/collapsible.component.ts +27 -20
  108. package/src/components/cols/cols.component.ts +14 -2
  109. package/src/components/cols/cols.scss +6 -12
  110. package/src/components/confirm/confirm.component.ts +7 -0
  111. package/src/components/copy-button/copy-button.component.ts +12 -11
  112. package/src/components/data-select/data-select.component.ts +215 -44
  113. package/src/components/data-select/data-select.scss +66 -6
  114. package/src/components/data-select/providers/currency-data-provider.ts +20 -6
  115. package/src/components/data-select/providers/provider.ts +1 -0
  116. package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
  117. package/src/components/data-table/data-table.component.ts +81 -22
  118. package/src/components/data-table-search/data-table-search.component.ts +184 -0
  119. package/src/components/data-table-search/data-table-search.scss +17 -0
  120. package/src/components/data-table-search/data-table-search.test.ts +11 -0
  121. package/src/components/data-table-search/index.ts +12 -0
  122. package/src/components/datepicker/datepicker.component.ts +347 -13
  123. package/src/components/dialog/dialog.component.ts +1 -1
  124. package/src/components/empty-state/empty-state.scss +6 -1
  125. package/src/components/header/header.scss +3 -3
  126. package/src/components/icon/icon.component.ts +23 -1
  127. package/src/components/icon/icon.scss +23 -0
  128. package/src/components/icon-picker/brand-icons.ts +24 -0
  129. package/src/components/icon-picker/icon-picker.component.ts +407 -0
  130. package/src/components/icon-picker/icon-picker.scss +205 -0
  131. package/src/components/icon-picker/index.ts +12 -0
  132. package/src/components/icon-picker/line-icons.ts +612 -0
  133. package/src/components/icon-picker/material-icons.ts +14543 -0
  134. package/src/components/inline-edit/inline-edit.component.ts +190 -46
  135. package/src/components/inline-edit/inline-edit.scss +29 -0
  136. package/src/components/inline-edit/inline-edit.test.ts +314 -1
  137. package/src/components/input/input.component.ts +324 -5
  138. package/src/components/input/input.scss +87 -0
  139. package/src/components/input-group/input-group.component.ts +28 -7
  140. package/src/components/input-group/input-group.scss +48 -10
  141. package/src/components/item/item.component.ts +24 -3
  142. package/src/components/item/item.scss +18 -0
  143. package/src/components/key/index.ts +12 -0
  144. package/src/components/key/key.component.ts +47 -0
  145. package/src/components/key/key.scss +38 -0
  146. package/src/components/key-container/index.ts +12 -0
  147. package/src/components/key-container/key-container.component.ts +142 -0
  148. package/src/components/key-container/key-container.scss +33 -0
  149. package/src/components/menu-item/menu-item.component.ts +20 -0
  150. package/src/components/menu-item/menu-item.scss +69 -2
  151. package/src/components/navbar/navbar.component.ts +103 -11
  152. package/src/components/navbar/navbar.scss +6 -1
  153. package/src/components/opt-group/index.ts +12 -0
  154. package/src/components/opt-group/opt-group.component.ts +74 -0
  155. package/src/components/opt-group/opt-group.scss +37 -0
  156. package/src/components/opt-group/opt-group.test.ts +27 -0
  157. package/src/components/option/option.component.ts +1 -16
  158. package/src/components/option/option.scss +4 -0
  159. package/src/components/panel/panel.component.ts +10 -8
  160. package/src/components/panel/panel.scss +20 -0
  161. package/src/components/priority-list/index.ts +12 -0
  162. package/src/components/priority-list/priority-list.component.ts +611 -0
  163. package/src/components/priority-list/priority-list.scss +185 -0
  164. package/src/components/priority-list/priority-list.test.ts +139 -0
  165. package/src/components/progress-bar/progress-bar.component.ts +22 -16
  166. package/src/components/radio/radio.scss +10 -3
  167. package/src/components/select/select.component.ts +812 -72
  168. package/src/components/select/select.scss +108 -2
  169. package/src/components/select/select.test.ts +147 -2
  170. package/src/components/settings-container/settings-container.component.ts +44 -19
  171. package/src/components/settings-container/settings-container.scss +1 -1
  172. package/src/components/skeleton/skeleton.component.ts +6 -1
  173. package/src/components/slideout/slideout.scss +8 -3
  174. package/src/components/sp/sp.component.ts +3 -1
  175. package/src/components/sp/sp.scss +19 -0
  176. package/src/components/stepper/stepper.component.ts +16 -10
  177. package/src/components/textarea/textarea.scss +0 -4
  178. package/src/components/tile/tile.component.ts +12 -3
  179. package/src/components/tile/tile.scss +1 -1
  180. package/src/components/timer/timer.component.ts +15 -2
  181. package/src/components/toggle/toggle.component.ts +29 -26
  182. package/src/components/toggle/toggle.scss +13 -1
  183. package/src/components/translation-group/index.ts +12 -0
  184. package/src/components/translation-group/translation-group.component.ts +207 -0
  185. package/src/components/translation-group/translation-group.scss +8 -0
  186. package/src/components/translations/translations.component.ts +90 -44
  187. package/src/components/translations/translations.scss +4 -0
  188. package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
  189. package/src/events/events.ts +12 -7
  190. package/src/events/zn-language-change.ts +7 -0
  191. package/src/events/zn-purchase.ts +11 -0
  192. package/src/events/zn-redirect.ts +7 -0
  193. package/src/events/zn-reorder.ts +7 -0
  194. package/src/events/zn-search-change.ts +11 -0
  195. package/src/events/zn-submit.ts +1 -1
  196. package/src/form-control.scss +4 -0
  197. package/src/internal/form-navigation.ts +510 -0
  198. package/src/internal/form.ts +6 -0
  199. package/src/zinc.ts +91 -83
@@ -1,20 +1,181 @@
1
1
  ---
2
2
  meta:
3
3
  title: Filter Wrapper
4
- description:
4
+ description: A wrapper component for filter inputs that automatically submits filter parameters to a parent data-table component. Provides a default submit button or allows custom submit controls.
5
5
  layout: component
6
6
  ---
7
7
 
8
8
  ```html:preview
9
- <zn-filter-wrapper></zn-filter-wrapper>
9
+ <zn-filter-wrapper>
10
+ <zn-input name="search" label="Search" placeholder="Enter search term"></zn-input>
11
+ </zn-filter-wrapper>
10
12
  ```
11
13
 
12
14
  ## Examples
13
15
 
14
- ### First Example
16
+ ### Basic Usage
15
17
 
16
- TODO
18
+ Wrap filter inputs to automatically submit to a parent data-table.
17
19
 
18
- ### Second Example
20
+ ```html:preview
21
+ <zn-filter-wrapper>
22
+ <zn-input name="search" label="Search" placeholder="Search items..."></zn-input>
23
+ </zn-filter-wrapper>
24
+ ```
25
+
26
+ ### Multiple Filter Inputs
27
+
28
+ Combine multiple input fields for complex filtering.
29
+
30
+ ```html:preview
31
+ <zn-filter-wrapper>
32
+ <div class="form-spacing">
33
+ <zn-input name="name" label="Name" placeholder="Filter by name"></zn-input>
34
+ <zn-input name="email" label="Email" placeholder="Filter by email"></zn-input>
35
+ </div>
36
+ </zn-filter-wrapper>
37
+ ```
38
+
39
+ ### With Select Dropdown
40
+
41
+ Use select components for dropdown filters.
42
+
43
+ ```html:preview
44
+ <zn-filter-wrapper>
45
+ <div class="form-spacing">
46
+ <zn-select name="status" label="Status">
47
+ <zn-option value="">All</zn-option>
48
+ <zn-option value="active">Active</zn-option>
49
+ <zn-option value="inactive">Inactive</zn-option>
50
+ <zn-option value="pending">Pending</zn-option>
51
+ </zn-select>
52
+ <zn-select name="role" label="Role">
53
+ <zn-option value="">All</zn-option>
54
+ <zn-option value="admin">Admin</zn-option>
55
+ <zn-option value="user">User</zn-option>
56
+ <zn-option value="guest">Guest</zn-option>
57
+ </zn-select>
58
+ </div>
59
+ </zn-filter-wrapper>
60
+ ```
61
+
62
+ ### With Data Select
63
+
64
+ Use data-select components for predefined options.
65
+
66
+ ```html:preview
67
+ <zn-filter-wrapper>
68
+ <div class="form-spacing">
69
+ <zn-data-select name="country" label="Country" provider="country"></zn-data-select>
70
+ <zn-data-select name="currency" label="Currency" provider="currency"></zn-data-select>
71
+ </div>
72
+ </zn-filter-wrapper>
73
+ ```
74
+
75
+ ### Custom Button Text
76
+
77
+ Change the default button text using the `button` attribute.
78
+
79
+ ```html:preview
80
+ <zn-filter-wrapper button="Apply Filters">
81
+ <zn-input name="search" label="Search" placeholder="Search..."></zn-input>
82
+ </zn-filter-wrapper>
83
+ ```
84
+
85
+ ### Custom Submit Button
86
+
87
+ Provide your own submit button by adding the `submit` attribute to a button.
88
+
89
+ ```html:preview
90
+ <zn-filter-wrapper>
91
+ <div class="form-spacing">
92
+ <zn-input name="query" label="Query" placeholder="Enter query"></zn-input>
93
+ <div style="display: flex; gap: 10px;">
94
+ <zn-button submit color="success">Apply</zn-button>
95
+ <zn-button color="secondary">Clear</zn-button>
96
+ </div>
97
+ </div>
98
+ </zn-filter-wrapper>
99
+ ```
19
100
 
20
- TODO
101
+ ### Omit Empty Values
102
+
103
+ Use the `omit-empty` attribute on inputs to exclude them from the filter when empty.
104
+
105
+ ```html:preview
106
+ <zn-filter-wrapper>
107
+ <div class="form-spacing">
108
+ <zn-input name="required_field" label="Required Field"></zn-input>
109
+ <zn-input name="optional_field" label="Optional Field" omit-empty></zn-input>
110
+ </div>
111
+ </zn-filter-wrapper>
112
+ ```
113
+
114
+ ### Date Range Filter
115
+
116
+ Create a date range filter with multiple inputs.
117
+
118
+ ```html:preview
119
+ <zn-filter-wrapper>
120
+ <div class="form-spacing">
121
+ <zn-input name="start_date" label="Start Date" type="date"></zn-input>
122
+ <zn-input name="end_date" label="End Date" type="date"></zn-input>
123
+ </div>
124
+ </zn-filter-wrapper>
125
+ ```
126
+
127
+ ### Number Range Filter
128
+
129
+ Filter by number ranges.
130
+
131
+ ```html:preview
132
+ <zn-filter-wrapper>
133
+ <div class="form-spacing">
134
+ <zn-input name="min_price" label="Min Price" type="number" placeholder="0"></zn-input>
135
+ <zn-input name="max_price" label="Max Price" type="number" placeholder="1000"></zn-input>
136
+ </div>
137
+ </zn-filter-wrapper>
138
+ ```
139
+
140
+ ### Advanced Filter Form
141
+
142
+ A complete filter form with multiple field types.
143
+
144
+ ```html:preview
145
+ <zn-filter-wrapper button="Search">
146
+ <div class="form-spacing">
147
+ <zn-input name="keyword" label="Keyword" placeholder="Search keyword"></zn-input>
148
+
149
+ <zn-select name="category" label="Category">
150
+ <zn-option value="">All Categories</zn-option>
151
+ <zn-option value="electronics">Electronics</zn-option>
152
+ <zn-option value="clothing">Clothing</zn-option>
153
+ <zn-option value="books">Books</zn-option>
154
+ </zn-select>
155
+
156
+ <zn-cols layout="1,1">
157
+ <zn-input name="min_price" label="Min Price" type="number"></zn-input>
158
+ <zn-input name="max_price" label="Max Price" type="number"></zn-input>
159
+ </zn-cols>
160
+
161
+ <zn-select name="sort" label="Sort By">
162
+ <zn-option value="name">Name</zn-option>
163
+ <zn-option value="price">Price</zn-option>
164
+ <zn-option value="date">Date</zn-option>
165
+ </zn-select>
166
+ </div>
167
+ </zn-filter-wrapper>
168
+ ```
169
+
170
+ ### With Query Builder
171
+
172
+ Integrate with query builder for advanced filtering.
173
+
174
+ ```html:preview
175
+ <zn-filter-wrapper>
176
+ <zn-query-builder
177
+ name="filters"
178
+ filters="[{&quot;id&quot;:&quot;name&quot;,&quot;name&quot;:&quot;Name&quot;,&quot;operators&quot;:[&quot;eq&quot;]},{&quot;id&quot;:&quot;status&quot;,&quot;name&quot;:&quot;Status&quot;,&quot;options&quot;:{&quot;active&quot;:&quot;Active&quot;,&quot;inactive&quot;:&quot;Inactive&quot;},&quot;operators&quot;:[&quot;eq&quot;]}]">
179
+ </zn-query-builder>
180
+ </zn-filter-wrapper>
181
+ ```
@@ -1,22 +1,399 @@
1
1
  ---
2
2
  meta:
3
3
  title: Form Group
4
- description:
4
+ description: Form groups organize and label multiple related form controls in a grid layout.
5
5
  layout: component
6
6
  ---
7
7
 
8
+ Form groups are used to organize multiple form controls under a shared label and help text. They provide a responsive grid layout that automatically adapts to different screen sizes, making it easy to create multi-column forms with consistent spacing and alignment.
9
+
8
10
  ```html:preview
9
- <zn-form-group></zn-form-group>
11
+ <zn-form-group label="Contact Information" help-text="Please provide your contact details">
12
+ <zn-input label="First Name" placeholder="Enter your first name"></zn-input>
13
+ <zn-input label="Last Name" placeholder="Enter your last name"></zn-input>
14
+ <zn-input label="Email" type="email" placeholder="your.email@example.com"></zn-input>
15
+ <zn-input label="Phone" type="tel" placeholder="(555) 123-4567"></zn-input>
16
+ </zn-form-group>
10
17
  ```
11
18
 
12
19
  ## Examples
13
20
 
14
- ### First Example
21
+ ### Basic Form Group
22
+
23
+ Use the `label` attribute to give the form group an accessible label. Form controls within the group are automatically laid out in a responsive grid that displays as a single column on mobile and up to 6 columns on larger screens.
24
+
25
+ ```html:preview
26
+ <zn-form-group label="User Details">
27
+ <zn-input label="Username" placeholder="username"></zn-input>
28
+ <zn-input label="Email" type="email" placeholder="email@example.com"></zn-input>
29
+ </zn-form-group>
30
+ ```
31
+
32
+ ### Help Text
33
+
34
+ Add descriptive help text to a form group with the `help-text` attribute. For help text that contains HTML, use the `help-text` slot instead. Help text appears below the label and provides guidance for the entire group of form controls.
35
+
36
+ ```html:preview
37
+ <zn-form-group label="Shipping Address" help-text="Enter the address where you want your order delivered">
38
+ <zn-input label="Street Address" placeholder="123 Main St"></zn-input>
39
+ <zn-input label="Apartment/Unit" placeholder="Apt 4B"></zn-input>
40
+ <zn-input label="City" placeholder="New York"></zn-input>
41
+ <zn-input label="Postal Code" placeholder="10001"></zn-input>
42
+ </zn-form-group>
43
+ <br />
44
+ <zn-form-group label="Billing Address">
45
+ <div slot="help-text">Enter the address associated with your <strong>payment method</strong></div>
46
+ <zn-input label="Street Address" placeholder="123 Main St"></zn-input>
47
+ <zn-input label="City" placeholder="New York"></zn-input>
48
+ </zn-form-group>
49
+ ```
50
+
51
+ ### Label with Tooltip
52
+
53
+ Use the `label-tooltip` attribute to add text that appears in a tooltip triggered by an info icon next to the label.
54
+
55
+ :::tip
56
+ **Usage:** Use a **label tooltip** to provide helpful but non-essential instructions or examples to guide people when filling in the form group. Use **help text** to communicate instructions or requirements for filling in the controls without errors.
57
+ :::
58
+
59
+ ```html:preview
60
+ <zn-form-group
61
+ label="Payment Details"
62
+ label-tooltip="Your payment information is encrypted and securely stored. We never share your financial data with third parties."
63
+ help-text="Enter your credit or debit card information">
64
+ <zn-input label="Cardholder Name" placeholder="Name on card"></zn-input>
65
+ <zn-input label="Card Number" placeholder="1234 5678 9012 3456"></zn-input>
66
+ <zn-input label="Expiry Date" placeholder="MM/YY" span="2"></zn-input>
67
+ <zn-input label="CVV" placeholder="123" span="2"></zn-input>
68
+ </zn-form-group>
69
+ ```
70
+
71
+ ### Using Label Slot
72
+
73
+ For labels that contain HTML or more complex content, use the `label` slot instead of the attribute.
74
+
75
+ ```html:preview
76
+ <zn-form-group help-text="Complete all required fields">
77
+ <span slot="label">
78
+ Account Settings <zn-chip variant="info" size="small">New</zn-chip>
79
+ </span>
80
+ <zn-input label="Display Name" placeholder="How should we address you?"></zn-input>
81
+ <zn-input label="Bio" placeholder="Tell us about yourself"></zn-input>
82
+ </zn-form-group>
83
+ ```
84
+
85
+ ### Controlling Column Spans
86
+
87
+ By default, all form controls within a form group span the full width (6 columns) on mobile and maintain that full width on larger screens. Use the `span` attribute on individual form controls to control how many columns they occupy on medium and larger screens.
88
+
89
+ The grid supports spans from 1 to 6 columns. Spans only take effect on screens at the `md` breakpoint and above (tablets and desktops). On smaller screens, all controls stack vertically at full width.
90
+
91
+ ```html:preview
92
+ <zn-form-group label="Product Information" help-text="Provide details about the product">
93
+ <zn-input label="Product Name" placeholder="Enter product name"></zn-input>
94
+ <zn-input label="SKU" placeholder="Product code" span="2"></zn-input>
95
+ <zn-input label="Price" type="currency" placeholder="0.00" span="2"></zn-input>
96
+ <zn-input label="Quantity" type="number" placeholder="0" span="2"></zn-input>
97
+ <zn-select label="Category" span="3">
98
+ <zn-option value="electronics">Electronics</zn-option>
99
+ <zn-option value="clothing">Clothing</zn-option>
100
+ <zn-option value="books">Books</zn-option>
101
+ </zn-select>
102
+ <zn-select label="Status" span="3">
103
+ <zn-option value="active">Active</zn-option>
104
+ <zn-option value="inactive">Inactive</zn-option>
105
+ </zn-select>
106
+ </zn-form-group>
107
+ ```
108
+
109
+ ### Two-Column Layout
110
+
111
+ Create a balanced two-column layout by giving each control a span of 3 columns.
112
+
113
+ ```html:preview
114
+ <zn-form-group label="Personal Information">
115
+ <zn-input label="First Name" placeholder="First name" span="3"></zn-input>
116
+ <zn-input label="Last Name" placeholder="Last name" span="3"></zn-input>
117
+ <zn-input label="Email" type="email" placeholder="email@example.com" span="3"></zn-input>
118
+ <zn-input label="Phone" type="tel" placeholder="(555) 123-4567" span="3"></zn-input>
119
+ <zn-datepicker label="Date of Birth" span="3"></zn-datepicker>
120
+ <zn-select label="Country" span="3">
121
+ <zn-option value="us">United States</zn-option>
122
+ <zn-option value="ca">Canada</zn-option>
123
+ <zn-option value="uk">United Kingdom</zn-option>
124
+ </zn-select>
125
+ </zn-form-group>
126
+ ```
127
+
128
+ ### Three-Column Layout
129
+
130
+ Create a three-column layout by giving each control a span of 2 columns.
131
+
132
+ ```html:preview
133
+ <zn-form-group label="Event Schedule" help-text="Set up the event timing">
134
+ <zn-datepicker label="Date" span="2"></zn-datepicker>
135
+ <zn-input label="Start Time" type="time" span="2"></zn-input>
136
+ <zn-input label="End Time" type="time" span="2"></zn-input>
137
+ <zn-input label="Duration (hours)" type="number" span="2"></zn-input>
138
+ <zn-select label="Time Zone" span="4">
139
+ <zn-option value="est">Eastern (EST)</zn-option>
140
+ <zn-option value="cst">Central (CST)</zn-option>
141
+ <zn-option value="mst">Mountain (MST)</zn-option>
142
+ <zn-option value="pst">Pacific (PST)</zn-option>
143
+ </zn-select>
144
+ </zn-form-group>
145
+ ```
146
+
147
+ ### Mixed Column Layouts
148
+
149
+ Combine different column spans to create flexible layouts that accommodate different types of inputs.
150
+
151
+ ```html:preview
152
+ <zn-form-group label="Address Details">
153
+ <zn-input label="Street Address" placeholder="123 Main Street"></zn-input>
154
+ <zn-input label="Apartment/Suite/Unit" placeholder="Apt 4B" span="2"></zn-input>
155
+ <zn-input label="City" placeholder="New York" span="2"></zn-input>
156
+ <zn-input label="State" placeholder="NY" span="1"></zn-input>
157
+ <zn-input label="ZIP Code" placeholder="10001" span="1"></zn-input>
158
+ <zn-select label="Country" span="3">
159
+ <zn-option value="us">United States</zn-option>
160
+ <zn-option value="ca">Canada</zn-option>
161
+ <zn-option value="mx">Mexico</zn-option>
162
+ </zn-select>
163
+ <zn-checkbox span="3">Set as default address</zn-checkbox>
164
+ </zn-form-group>
165
+ ```
166
+
167
+ ### Mixing Form Control Types
168
+
169
+ Form groups work with all Zinc form components including inputs, selects, textareas, datepickers, checkboxes, radios, and toggles.
15
170
 
16
- TODO
171
+ ```html:preview
172
+ <zn-form-group label="Project Settings" help-text="Configure your project preferences">
173
+ <zn-input label="Project Name" placeholder="My Awesome Project" span="4"></zn-input>
174
+ <zn-select label="Priority" span="2">
175
+ <zn-option value="low">Low</zn-option>
176
+ <zn-option value="medium" selected>Medium</zn-option>
177
+ <zn-option value="high">High</zn-option>
178
+ </zn-select>
179
+ <zn-datepicker label="Start Date" span="3"></zn-datepicker>
180
+ <zn-datepicker label="End Date" span="3"></zn-datepicker>
181
+ <zn-textarea label="Description" placeholder="Describe your project..." rows="3"></zn-textarea>
182
+ <zn-radio-group label="Status" span="3">
183
+ <zn-radio value="planning">Planning</zn-radio>
184
+ <zn-radio value="active" checked>Active</zn-radio>
185
+ <zn-radio value="complete">Complete</zn-radio>
186
+ </zn-radio-group>
187
+ <zn-checkbox-group label="Features" span="3">
188
+ <zn-checkbox value="notifications">Email notifications</zn-checkbox>
189
+ <zn-checkbox value="reports">Weekly reports</zn-checkbox>
190
+ <zn-checkbox value="api">API access</zn-checkbox>
191
+ </zn-checkbox-group>
192
+ </zn-form-group>
193
+ ```
194
+
195
+ ### Nested Groups with Different Sections
196
+
197
+ Create complex forms by using multiple form groups to separate different sections of related information.
198
+
199
+ ```html:preview
200
+ <form>
201
+ <zn-form-group label="Account Information" help-text="Basic account details">
202
+ <zn-input label="Username" placeholder="username" span="3" required></zn-input>
203
+ <zn-input label="Email" type="email" placeholder="email@example.com" span="3" required></zn-input>
204
+ <zn-input label="Password" type="password" placeholder="••••••••" span="3" required></zn-input>
205
+ <zn-input label="Confirm Password" type="password" placeholder="••••••••" span="3" required></zn-input>
206
+ </zn-form-group>
207
+
208
+ <br />
209
+
210
+ <zn-form-group label="Personal Details" help-text="Tell us about yourself">
211
+ <zn-input label="First Name" placeholder="First name" span="3"></zn-input>
212
+ <zn-input label="Last Name" placeholder="Last name" span="3"></zn-input>
213
+ <zn-input label="Phone" type="tel" placeholder="(555) 123-4567" span="3"></zn-input>
214
+ <zn-datepicker label="Date of Birth" span="3"></zn-datepicker>
215
+ </zn-form-group>
216
+
217
+ <br />
218
+
219
+ <zn-form-group label="Preferences">
220
+ <zn-toggle name="newsletter" span="3">Subscribe to newsletter</zn-toggle>
221
+ <zn-toggle name="sms" span="3">Receive SMS updates</zn-toggle>
222
+ </zn-form-group>
223
+
224
+ <br />
225
+
226
+ <zn-button type="submit" variant="primary">Create Account</zn-button>
227
+ </form>
228
+ ```
229
+
230
+ ### Single-Column Layout
231
+
232
+ By default, without span attributes, all controls stack vertically in a single column, which works well for forms with long labels or complex inputs.
233
+
234
+ ```html:preview
235
+ <zn-form-group label="Application Form" help-text="Complete all fields to submit your application">
236
+ <zn-input label="Full Legal Name" placeholder="Enter your full name as it appears on government ID"></zn-input>
237
+ <zn-input label="Email Address" type="email" placeholder="your.email@example.com"></zn-input>
238
+ <zn-input label="Phone Number" type="tel" placeholder="Include country code"></zn-input>
239
+ <zn-textarea label="Cover Letter" placeholder="Tell us why you're a great fit for this position..." rows="4"></zn-textarea>
240
+ <zn-select label="How did you hear about us?">
241
+ <zn-option value="search">Search Engine</zn-option>
242
+ <zn-option value="social">Social Media</zn-option>
243
+ <zn-option value="referral">Friend or Colleague</zn-option>
244
+ <zn-option value="other">Other</zn-option>
245
+ </zn-select>
246
+ </zn-form-group>
247
+ ```
248
+
249
+ ### Validation Example
250
+
251
+ Form groups work seamlessly with form validation. Individual controls within the group can have their own validation rules.
252
+
253
+ ```html:preview
254
+ <form class="form-group-validation">
255
+ <zn-form-group label="Registration Form" help-text="All fields are required">
256
+ <zn-input
257
+ name="firstName"
258
+ label="First Name"
259
+ placeholder="First name"
260
+ span="3"
261
+ required>
262
+ </zn-input>
263
+ <zn-input
264
+ name="lastName"
265
+ label="Last Name"
266
+ placeholder="Last name"
267
+ span="3"
268
+ required>
269
+ </zn-input>
270
+ <zn-input
271
+ name="email"
272
+ label="Email"
273
+ type="email"
274
+ placeholder="email@example.com"
275
+ span="3"
276
+ required>
277
+ </zn-input>
278
+ <zn-input
279
+ name="phone"
280
+ label="Phone"
281
+ type="tel"
282
+ placeholder="(555) 123-4567"
283
+ span="3"
284
+ required>
285
+ </zn-input>
286
+ <zn-datepicker
287
+ name="birthdate"
288
+ label="Date of Birth"
289
+ span="3"
290
+ required>
291
+ </zn-datepicker>
292
+ <zn-select
293
+ name="country"
294
+ label="Country"
295
+ span="3"
296
+ required>
297
+ <zn-option value="us">United States</zn-option>
298
+ <zn-option value="ca">Canada</zn-option>
299
+ <zn-option value="uk">United Kingdom</zn-option>
300
+ </zn-select>
301
+ </zn-form-group>
302
+ <br />
303
+ <zn-button type="submit" variant="primary">Submit</zn-button>
304
+ <zn-button type="reset">Reset</zn-button>
305
+ </form>
17
306
 
18
- ### Second Example
307
+ <script type="module">
308
+ const form = document.querySelector('.form-group-validation');
19
309
 
20
- TODO
310
+ // Wait for controls to be defined before attaching form listeners
311
+ await Promise.all([
312
+ customElements.whenDefined('zn-button'),
313
+ customElements.whenDefined('zn-input'),
314
+ customElements.whenDefined('zn-datepicker'),
315
+ customElements.whenDefined('zn-select')
316
+ ]).then(() => {
317
+ form.addEventListener('submit', (e) => {
318
+ e.preventDefault();
319
+ const formData = new FormData(form);
320
+ const data = Object.fromEntries(formData);
321
+ alert('Form submitted successfully!\n\n' + JSON.stringify(data, null, 2));
322
+ });
323
+ });
324
+ </script>
325
+ ```
326
+
327
+ ### Responsive Behavior
328
+
329
+ Form groups are responsive by default. The grid layout automatically adapts based on screen size:
330
+
331
+ - **Small screens (mobile):** All controls stack vertically at full width, regardless of span attributes
332
+ - **Medium screens and up (tablets/desktops):** The span attributes take effect, creating the multi-column layout
333
+
334
+ This ensures forms remain usable on all devices without additional configuration.
335
+
336
+ ```html:preview
337
+ <zn-form-group
338
+ label="Responsive Layout Demo"
339
+ help-text="Resize your browser to see the layout adapt">
340
+ <zn-input label="Full width on mobile" span="6"></zn-input>
341
+ <zn-input label="Half width on desktop" span="3"></zn-input>
342
+ <zn-input label="Half width on desktop" span="3"></zn-input>
343
+ <zn-input label="One third on desktop" span="2"></zn-input>
344
+ <zn-input label="One third on desktop" span="2"></zn-input>
345
+ <zn-input label="One third on desktop" span="2"></zn-input>
346
+ </zn-form-group>
347
+ ```
348
+
349
+ ### Styling with CSS Parts
350
+
351
+ Form groups expose several CSS parts that can be styled to customize their appearance. This example demonstrates how to create custom layouts using CSS grid.
352
+
353
+ ```html:preview
354
+ <zn-form-group class="custom-form-group" label="Custom Styled Form Group" help-text="This form group has custom spacing and borders">
355
+ <zn-input label="Field 1" span="3"></zn-input>
356
+ <zn-input label="Field 2" span="3"></zn-input>
357
+ <zn-input label="Field 3" span="2"></zn-input>
358
+ <zn-input label="Field 4" span="2"></zn-input>
359
+ <zn-input label="Field 5" span="2"></zn-input>
360
+ </zn-form-group>
361
+
362
+ <style>
363
+ .custom-form-group::part(form-control) {
364
+ padding: var(--zn-spacing-large);
365
+ border: 2px solid var(--zn-color-primary-300);
366
+ border-radius: var(--zn-border-radius-medium);
367
+ background-color: var(--zn-color-primary-50);
368
+ }
369
+
370
+ .custom-form-group::part(form-control-label) {
371
+ color: var(--zn-color-primary-700);
372
+ }
373
+
374
+ .custom-form-group::part(form-control-help-text) {
375
+ color: var(--zn-color-primary-600);
376
+ }
377
+ </style>
378
+ ```
379
+
380
+ ### Accessibility
381
+
382
+ Form groups are built with accessibility in mind:
383
+
384
+ - The component uses a `<fieldset>` element to semantically group related form controls
385
+ - The `label` is associated with the fieldset using `aria-labelledby`
386
+ - Help text is associated with the fieldset using `aria-describedby`
387
+ - All form controls within the group maintain their individual labels and accessibility features
388
+
389
+ ```html:preview
390
+ <zn-form-group
391
+ label="Accessible Form Group"
392
+ help-text="Screen readers will announce the group label and help text"
393
+ label-tooltip="Additional context for sighted users">
394
+ <zn-input label="Name" placeholder="Your name" required></zn-input>
395
+ <zn-input label="Email" type="email" placeholder="your@email.com" required></zn-input>
396
+ </zn-form-group>
397
+ ```
21
398
 
22
399