@adyen/bento-mcp 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +113 -0
  4. package/dist/assets/components/accordion/accordion.docs.mdx +77 -0
  5. package/dist/assets/components/accordion/accordion.stories.ts +1 -0
  6. package/dist/assets/components/accordion/accordion.vue +1 -0
  7. package/dist/assets/components/accordion/components/accordion-item.stories.ts +1 -0
  8. package/dist/assets/components/accordion/components/accordion-item.vue +1 -0
  9. package/dist/assets/components/action-bar/action-bar.docs.mdx +103 -0
  10. package/dist/assets/components/action-bar/action-bar.stories.ts +1 -0
  11. package/dist/assets/components/action-bar/action-bar.vue +1 -0
  12. package/dist/assets/components/alert/alert.docs.mdx +106 -0
  13. package/dist/assets/components/alert/alert.stories.ts +1 -0
  14. package/dist/assets/components/alert/alert.vue +1 -0
  15. package/dist/assets/components/avatar/avatar.docs.mdx +44 -0
  16. package/dist/assets/components/avatar/avatar.stories.ts +1 -0
  17. package/dist/assets/components/avatar/avatar.vue +1 -0
  18. package/dist/assets/components/avatar/components/avatar-image/avatar-image.vue +1 -0
  19. package/dist/assets/components/button/button.docs.mdx +137 -0
  20. package/dist/assets/components/button/button.stories.ts +1 -0
  21. package/dist/assets/components/button/button.vue +1 -0
  22. package/dist/assets/components/button/components/ai-button/ai-button.docs.mdx +40 -0
  23. package/dist/assets/components/button/components/ai-button/ai-button.stories.ts +1 -0
  24. package/dist/assets/components/button/components/ai-button/ai-button.vue +1 -0
  25. package/dist/assets/components/button/components/button-actions/button-actions.docs.mdx +169 -0
  26. package/dist/assets/components/button/components/button-actions/button-actions.stories.ts +1 -0
  27. package/dist/assets/components/button/components/button-actions/button-actions.vue +1 -0
  28. package/dist/assets/components/button/components/loading-button/loading-button.docs.mdx +106 -0
  29. package/dist/assets/components/button/components/loading-button/loading-button.stories.ts +1 -0
  30. package/dist/assets/components/button/components/loading-button/loading-button.vue +1 -0
  31. package/dist/assets/components/button/components/toggle-button/toggle-button.docs.mdx +81 -0
  32. package/dist/assets/components/button/components/toggle-button/toggle-button.stories.ts +1 -0
  33. package/dist/assets/components/button/components/toggle-button/toggle-button.vue +1 -0
  34. package/dist/assets/components/card/card.docs.mdx +166 -0
  35. package/dist/assets/components/card/card.stories.ts +1 -0
  36. package/dist/assets/components/card/card.vue +1 -0
  37. package/dist/assets/components/checkbox/checkbox.docs.mdx +116 -0
  38. package/dist/assets/components/checkbox/checkbox.stories.ts +1 -0
  39. package/dist/assets/components/checkbox/checkbox.vue +1 -0
  40. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.docs.mdx +134 -0
  41. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.stories.ts +1 -0
  42. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.vue +1 -0
  43. package/dist/assets/components/chip/chip.docs.mdx +51 -0
  44. package/dist/assets/components/chip/chip.stories.ts +1 -0
  45. package/dist/assets/components/chip/chip.vue +1 -0
  46. package/dist/assets/components/click-outside/click-outside.docs.mdx +30 -0
  47. package/dist/assets/components/click-outside/click-outside.stories.ts +1 -0
  48. package/dist/assets/components/code-snippet/code-snippet.docs.mdx +73 -0
  49. package/dist/assets/components/code-snippet/code-snippet.stories.ts +1 -0
  50. package/dist/assets/components/code-snippet/code-snippet.vue +1 -0
  51. package/dist/assets/components/country/country.docs.mdx +61 -0
  52. package/dist/assets/components/country/country.stories.ts +1 -0
  53. package/dist/assets/components/country/country.vue +1 -0
  54. package/dist/assets/components/currency/currency.docs.mdx +38 -0
  55. package/dist/assets/components/currency/currency.stories.ts +1 -0
  56. package/dist/assets/components/currency/currency.vue +1 -0
  57. package/dist/assets/components/dashed-underline/dashed-underline.docs.mdx +57 -0
  58. package/dist/assets/components/dashed-underline/dashed-underline.stories.ts +1 -0
  59. package/dist/assets/components/dashed-underline/dashed-underline.vue +1 -0
  60. package/dist/assets/components/data-grid/components/data-grid-cell/data-grid-cell.vue +1 -0
  61. package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.vue +1 -0
  62. package/dist/assets/components/data-grid/components/data-grid-columns/data-grid-columns.vue +1 -0
  63. package/dist/assets/components/data-grid/components/data-grid-config-settings/components/data-grid-config-settings-column-row/data-grid-config-settings-column-row.vue +1 -0
  64. package/dist/assets/components/data-grid/components/data-grid-config-settings/data-grid-config-settings.vue +1 -0
  65. package/dist/assets/components/data-grid/components/data-grid-lazy-load/data-grid-lazy-load.vue +1 -0
  66. package/dist/assets/components/data-grid/components/data-grid-row/data-grid-row.vue +1 -0
  67. package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.docs.mdx +61 -0
  68. package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.stories.ts +1 -0
  69. package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.vue +1 -0
  70. package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.docs.mdx +56 -0
  71. package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.stories.ts +1 -0
  72. package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.vue +1 -0
  73. package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.docs.mdx +48 -0
  74. package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.stories.ts +1 -0
  75. package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.vue +1 -0
  76. package/dist/assets/components/data-grid/data-grid.docs.mdx +951 -0
  77. package/dist/assets/components/data-grid/data-grid.stories.ts +1 -0
  78. package/dist/assets/components/data-grid/data-grid.vue +1 -0
  79. package/dist/assets/components/date/date.docs.mdx +49 -0
  80. package/dist/assets/components/date/date.stories.ts +1 -0
  81. package/dist/assets/components/date/date.vue +1 -0
  82. package/dist/assets/components/date-picker/date-picker.docs.mdx +69 -0
  83. package/dist/assets/components/date-picker/date-picker.stories.ts +1 -0
  84. package/dist/assets/components/date-picker/date-picker.vue +1 -0
  85. package/dist/assets/components/date-range-picker/components/date-range-picker-calendar/date-range-picker-calendar.vue +1 -0
  86. package/dist/assets/components/date-range-picker/date-range-picker.docs.mdx +168 -0
  87. package/dist/assets/components/date-range-picker/date-range-picker.stories.ts +1 -0
  88. package/dist/assets/components/date-range-picker/date-range-picker.vue +1 -0
  89. package/dist/assets/components/divider/divider.docs.mdx +27 -0
  90. package/dist/assets/components/divider/divider.stories.ts +1 -0
  91. package/dist/assets/components/divider/divider.vue +1 -0
  92. package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.vue +1 -0
  93. package/dist/assets/components/dropdown/components/dropdown-default-textbox/dropdown-default-textbox.vue +1 -0
  94. package/dist/assets/components/dropdown/components/dropdown-options-container/dropdown-options-container.vue +1 -0
  95. package/dist/assets/components/dropdown/components/dropdown-small-textbox/dropdown-small-textbox.vue +1 -0
  96. package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.stories.ts +1 -0
  97. package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.vue +1 -0
  98. package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.stories.ts +1 -0
  99. package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.vue +1 -0
  100. package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.stories.ts +1 -0
  101. package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.vue +1 -0
  102. package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.stories.ts +1 -0
  103. package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.vue +1 -0
  104. package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.stories.ts +1 -0
  105. package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.vue +1 -0
  106. package/dist/assets/components/dropdown/dropdown.docs.mdx +420 -0
  107. package/dist/assets/components/dropdown/dropdown.stories.ts +1 -0
  108. package/dist/assets/components/dropdown/dropdown.vue +1 -0
  109. package/dist/assets/components/empty-state/empty-state.docs.mdx +115 -0
  110. package/dist/assets/components/empty-state/empty-state.stories.ts +1 -0
  111. package/dist/assets/components/empty-state/empty-state.vue +1 -0
  112. package/dist/assets/components/file-uploader/components/file-uploader-file-card/components/file-uploader-file-card-animation/file-uploader-file-card-animation.vue +1 -0
  113. package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.stories.ts +1 -0
  114. package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.vue +1 -0
  115. package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.stories.ts +1 -0
  116. package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.vue +1 -0
  117. package/dist/assets/components/file-uploader/file-uploader.docs.mdx +117 -0
  118. package/dist/assets/components/file-uploader/file-uploader.stories.ts +1 -0
  119. package/dist/assets/components/file-uploader/file-uploader.vue +1 -0
  120. package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.stories.ts +1 -0
  121. package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.vue +1 -0
  122. package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-button/all-filters-modal-button.vue +1 -0
  123. package/dist/assets/components/filter-bar/components/base-filter/base-filter.docs.mdx +90 -0
  124. package/dist/assets/components/filter-bar/components/base-filter/base-filter.stories.ts +1 -0
  125. package/dist/assets/components/filter-bar/components/base-filter/base-filter.vue +1 -0
  126. package/dist/assets/components/filter-bar/components/base-filter-button/base-filter-button.vue +1 -0
  127. package/dist/assets/components/filter-bar/components/boolean-filter/boolean-filter.vue +1 -0
  128. package/dist/assets/components/filter-bar/components/checkbox-group-filter/checkbox-group-filter.stories.ts +1 -0
  129. package/dist/assets/components/filter-bar/components/checkbox-group-filter/checkbox-group-filter.vue +1 -0
  130. package/dist/assets/components/filter-bar/components/date-filter/date-filter.stories.ts +1 -0
  131. package/dist/assets/components/filter-bar/components/date-filter/date-filter.vue +1 -0
  132. package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.stories.ts +1 -0
  133. package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.vue +1 -0
  134. package/dist/assets/components/filter-bar/components/filter-bar-button/filter-bar-button.vue +1 -0
  135. package/dist/assets/components/filter-bar/components/filter-bar-button-group/filter-bar-button-group.vue +1 -0
  136. package/dist/assets/components/filter-bar/components/input-filter/input-filter.docs.mdx +18 -0
  137. package/dist/assets/components/filter-bar/components/input-filter/input-filter.stories.ts +1 -0
  138. package/dist/assets/components/filter-bar/components/input-filter/input-filter.vue +1 -0
  139. package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.docs.mdx +18 -0
  140. package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.stories.ts +1 -0
  141. package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.vue +1 -0
  142. package/dist/assets/components/filter-bar/components/radio-group-filter/radio-group-filter.stories.ts +1 -0
  143. package/dist/assets/components/filter-bar/components/radio-group-filter/radio-group-filter.vue +1 -0
  144. package/dist/assets/components/filter-bar/components/range-filter/range-filter.vue +1 -0
  145. package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-button/select-filter-button.vue +1 -0
  146. package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-dropdown/select-filter-dropdown.vue +1 -0
  147. package/dist/assets/components/filter-bar/components/select-filter/select-filter.stories.ts +1 -0
  148. package/dist/assets/components/filter-bar/components/select-filter/select-filter.vue +1 -0
  149. package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.stories.ts +1 -0
  150. package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.vue +1 -0
  151. package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.stories.ts +1 -0
  152. package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.vue +1 -0
  153. package/dist/assets/components/filter-bar/components/select-filter/variants/select-currency-filter/select-currency-filter.stories.ts +1 -0
  154. package/dist/assets/components/filter-bar/components/select-filter/variants/select-currency-filter/select-currency-filter.vue +1 -0
  155. package/dist/assets/components/filter-bar/components/select-filter/variants/select-payment-method-filter/select-payment-method-filter.stories.ts +1 -0
  156. package/dist/assets/components/filter-bar/components/select-filter/variants/select-payment-method-filter/select-payment-method-filter.vue +1 -0
  157. package/dist/assets/components/filter-bar/components/select-filter/variants/select-tag-filter/select-tag-filter.stories.ts +1 -0
  158. package/dist/assets/components/filter-bar/components/select-filter/variants/select-tag-filter/select-tag-filter.vue +1 -0
  159. package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.stories.ts +1 -0
  160. package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.vue +1 -0
  161. package/dist/assets/components/filter-bar/filter-bar.docs.mdx +1005 -0
  162. package/dist/assets/components/filter-bar/filter-bar.stories.ts +1 -0
  163. package/dist/assets/components/filter-bar/filter-bar.vue +1 -0
  164. package/dist/assets/components/focus-trap/focus-trap.docs.mdx +10 -0
  165. package/dist/assets/components/focus-trap/focus-trap.stories.ts +1 -0
  166. package/dist/assets/components/focus-trap/focus-trap.vue +1 -0
  167. package/dist/assets/components/form-layout/components/form-layout-field-tip/form-layout-field-tip.vue +1 -0
  168. package/dist/assets/components/form-layout/components/form-layout-group/form-layout-group.vue +1 -0
  169. package/dist/assets/components/form-layout/components/form-layout-title/form-layout-title.vue +1 -0
  170. package/dist/assets/components/form-layout/form-layout.docs.mdx +452 -0
  171. package/dist/assets/components/form-layout/form-layout.stories.ts +1 -0
  172. package/dist/assets/components/form-layout/form-layout.vue +1 -0
  173. package/dist/assets/components/header/header.docs.mdx +85 -0
  174. package/dist/assets/components/header/header.stories.ts +1 -0
  175. package/dist/assets/components/header/header.vue +1 -0
  176. package/dist/assets/components/header-with-views/components/header-with-views-all-views/header-with-views-all-views.vue +1 -0
  177. package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.vue +1 -0
  178. package/dist/assets/components/header-with-views/header-with-views.docs.mdx +103 -0
  179. package/dist/assets/components/header-with-views/header-with-views.stories.ts +1 -0
  180. package/dist/assets/components/header-with-views/header-with-views.vue +1 -0
  181. package/dist/assets/components/image/image.docs.mdx +34 -0
  182. package/dist/assets/components/image/image.stories.ts +1 -0
  183. package/dist/assets/components/image/image.vue +1 -0
  184. package/dist/assets/components/info-icon/info-icon.docs.mdx +57 -0
  185. package/dist/assets/components/info-icon/info-icon.stories.ts +1 -0
  186. package/dist/assets/components/info-icon/info-icon.vue +1 -0
  187. package/dist/assets/components/input-field/input-field.docs.mdx +141 -0
  188. package/dist/assets/components/input-field/input-field.stories.ts +1 -0
  189. package/dist/assets/components/input-field/input-field.vue +1 -0
  190. package/dist/assets/components/input-field-password/input-field-password.docs.mdx +292 -0
  191. package/dist/assets/components/input-field-password/input-field-password.stories.ts +1 -0
  192. package/dist/assets/components/input-field-password/input-field-password.vue +1 -0
  193. package/dist/assets/components/input-field-phone-number/input-field-phone-number.docs.mdx +72 -0
  194. package/dist/assets/components/input-field-phone-number/input-field-phone-number.stories.ts +1 -0
  195. package/dist/assets/components/input-field-phone-number/input-field-phone-number.vue +1 -0
  196. package/dist/assets/components/inspector/inspector.docs.mdx +118 -0
  197. package/dist/assets/components/inspector/inspector.stories.ts +1 -0
  198. package/dist/assets/components/inspector/inspector.vue +1 -0
  199. package/dist/assets/components/internal/base-button/base-button.vue +1 -0
  200. package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.stories.ts +1 -0
  201. package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.vue +1 -0
  202. package/dist/assets/components/internal/calendar/calendar.stories.ts +1 -0
  203. package/dist/assets/components/internal/calendar/calendar.vue +1 -0
  204. package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.stories.ts +1 -0
  205. package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.vue +1 -0
  206. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/__test__/calendar-month-day-stub.vue +1 -0
  207. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.stories.ts +1 -0
  208. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.vue +1 -0
  209. package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.vue +1 -0
  210. package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/__test__/calendar-year-month-stub.vue +1 -0
  211. package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.vue +1 -0
  212. package/dist/assets/components/internal/checkbox-input/checkbox-input.stories.ts +1 -0
  213. package/dist/assets/components/internal/checkbox-input/checkbox-input.vue +1 -0
  214. package/dist/assets/components/internal/controls-group/controls-group.vue +1 -0
  215. package/dist/assets/components/internal/copy/copy.docs.mdx +43 -0
  216. package/dist/assets/components/internal/copy/copy.stories.ts +1 -0
  217. package/dist/assets/components/internal/copy/copy.vue +1 -0
  218. package/dist/assets/components/internal/decorative-checkbox/decorative-checkbox.vue +1 -0
  219. package/dist/assets/components/internal/dialog-page/dialog-page.vue +1 -0
  220. package/dist/assets/components/internal/error-message/error-message.vue +1 -0
  221. package/dist/assets/components/internal/field-label/field-label.vue +1 -0
  222. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.docs.mdx +21 -0
  223. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.stories.ts +1 -0
  224. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.vue +1 -0
  225. package/dist/assets/components/internal/footer-actions/footer-actions.vue +1 -0
  226. package/dist/assets/components/internal/grid-layout/grid-layout.vue +1 -0
  227. package/dist/assets/components/internal/header-meta/header-meta.vue +1 -0
  228. package/dist/assets/components/internal/info-icon-with-popover/info-icon-with-popover.vue +1 -0
  229. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-category/listbox-multi-select-category.vue +1 -0
  230. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.vue +1 -0
  231. package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.vue +1 -0
  232. package/dist/assets/components/internal/listbox/components/listbox-option/listbox-option.vue +1 -0
  233. package/dist/assets/components/internal/listbox/components/listbox-option-tag/listbox-option-tag.vue +1 -0
  234. package/dist/assets/components/internal/listbox/components/listbox-single-select/components/listbox-single-select-category/listbox-single-select-category.vue +1 -0
  235. package/dist/assets/components/internal/listbox/components/listbox-single-select/listbox-single-select.vue +1 -0
  236. package/dist/assets/components/internal/listbox/components/listbox-single-select-option/listbox-single-select-option.vue +1 -0
  237. package/dist/assets/components/internal/listbox/listbox.stories.ts +1 -0
  238. package/dist/assets/components/internal/listbox/listbox.vue +1 -0
  239. package/dist/assets/components/internal/radio-input/radio-input.stories.ts +1 -0
  240. package/dist/assets/components/internal/radio-input/radio-input.vue +1 -0
  241. package/dist/assets/components/internal/teleport/teleport.vue +1 -0
  242. package/dist/assets/components/internal/tooltip/tooltip.test.vue +1 -0
  243. package/dist/assets/components/internal/tooltip/tooltip.vue +1 -0
  244. package/dist/assets/components/layout/components/layout-row/layout-row.stories.ts +1 -0
  245. package/dist/assets/components/layout/components/layout-row/layout-row.vue +1 -0
  246. package/dist/assets/components/layout/layout.docs.mdx +108 -0
  247. package/dist/assets/components/layout/layout.stories.ts +1 -0
  248. package/dist/assets/components/layout/layout.vue +1 -0
  249. package/dist/assets/components/link/link.docs.mdx +119 -0
  250. package/dist/assets/components/link/link.stories.ts +1 -0
  251. package/dist/assets/components/link/link.vue +1 -0
  252. package/dist/assets/components/loading-indicator/loading-indicator.docs.mdx +65 -0
  253. package/dist/assets/components/loading-indicator/loading-indicator.stories.ts +1 -0
  254. package/dist/assets/components/loading-indicator/loading-indicator.vue +1 -0
  255. package/dist/assets/components/menu/components/menu-item/menu-item.vue +1 -0
  256. package/dist/assets/components/menu/components/menu-item-list/menu-item-list.vue +1 -0
  257. package/dist/assets/components/menu/components/menu-list-container/menu-list-container.vue +1 -0
  258. package/dist/assets/components/menu/components/sub-menu-item-list/sub-menu-item-list.vue +1 -0
  259. package/dist/assets/components/menu/menu.docs.mdx +121 -0
  260. package/dist/assets/components/menu/menu.stories.ts +1 -0
  261. package/dist/assets/components/menu/menu.vue +1 -0
  262. package/dist/assets/components/modal/components/base-modal/base-modal.vue +1 -0
  263. package/dist/assets/components/modal/components/modal-default/modal-default.vue +1 -0
  264. package/dist/assets/components/modal/components/modal-dialog/modal-dialog.vue +1 -0
  265. package/dist/assets/components/modal/components/modal-page/modal-page.vue +1 -0
  266. package/dist/assets/components/modal/modal.docs.mdx +215 -0
  267. package/dist/assets/components/modal/modal.stories.ts +1 -0
  268. package/dist/assets/components/modal/modal.vue +1 -0
  269. package/dist/assets/components/modal-fullscreen/components/modal-fullscreen-page.vue +1 -0
  270. package/dist/assets/components/modal-fullscreen/modal-fullscreen.docs.mdx +217 -0
  271. package/dist/assets/components/modal-fullscreen/modal-fullscreen.stories.ts +1 -0
  272. package/dist/assets/components/modal-fullscreen/modal-fullscreen.vue +1 -0
  273. package/dist/assets/components/pagination/components/pagination-context/pagination-context.vue +1 -0
  274. package/dist/assets/components/pagination/components/pagination-controls/pagination-controls.vue +1 -0
  275. package/dist/assets/components/pagination/components/pagination-results-per-page/pagination-results-per-page.vue +1 -0
  276. package/dist/assets/components/pagination/pagination.docs.mdx +116 -0
  277. package/dist/assets/components/pagination/pagination.stories.ts +1 -0
  278. package/dist/assets/components/pagination/pagination.vue +1 -0
  279. package/dist/assets/components/payment-method/payment-method.docs.mdx +34 -0
  280. package/dist/assets/components/payment-method/payment-method.stories.ts +1 -0
  281. package/dist/assets/components/payment-method/payment-method.vue +1 -0
  282. package/dist/assets/components/popover/components/popover-dismiss-button/popover-dismiss-button.vue +1 -0
  283. package/dist/assets/components/popover/components/popover-image/popover-image.vue +1 -0
  284. package/dist/assets/components/popover/components/popover-title/popover-title.vue +1 -0
  285. package/dist/assets/components/popover/popover.docs.mdx +89 -0
  286. package/dist/assets/components/popover/popover.stories.ts +1 -0
  287. package/dist/assets/components/popover/popover.vue +1 -0
  288. package/dist/assets/components/popper-container/popper-container.docs.mdx +11 -0
  289. package/dist/assets/components/popper-container/popper-container.stories.ts +1 -0
  290. package/dist/assets/components/popper-container/popper-container.vue +1 -0
  291. package/dist/assets/components/promo-banner/promo-banner.docs.mdx +94 -0
  292. package/dist/assets/components/promo-banner/promo-banner.stories.ts +1 -0
  293. package/dist/assets/components/promo-banner/promo-banner.vue +1 -0
  294. package/dist/assets/components/radio-group/components/radio-button/radio-button.docs.mdx +76 -0
  295. package/dist/assets/components/radio-group/components/radio-button/radio-button.stories.ts +1 -0
  296. package/dist/assets/components/radio-group/components/radio-button/radio-button.vue +1 -0
  297. package/dist/assets/components/radio-group/radio-group.docs.mdx +154 -0
  298. package/dist/assets/components/radio-group/radio-group.stories.ts +1 -0
  299. package/dist/assets/components/radio-group/radio-group.vue +1 -0
  300. package/dist/assets/components/rich-text-editor/components/rich-text-editor-content-area/rich-text-editor-content-area.vue +1 -0
  301. package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-code-block/rich-text-editor-code-block.vue +1 -0
  302. package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-inline-code/rich-text-editor-inline-code.vue +1 -0
  303. package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-link/rich-text-editor-link.vue +1 -0
  304. package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-list-item/rich-text-editor-list-item.vue +1 -0
  305. package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-table/rich-text-editor-table.vue +1 -0
  306. package/dist/assets/components/rich-text-editor/rich-text-editor.docs.mdx +52 -0
  307. package/dist/assets/components/rich-text-editor/rich-text-editor.stories.ts +1 -0
  308. package/dist/assets/components/rich-text-editor/rich-text-editor.vue +1 -0
  309. package/dist/assets/components/search-bar/search-bar.docs.mdx +117 -0
  310. package/dist/assets/components/search-bar/search-bar.stories.ts +1 -0
  311. package/dist/assets/components/search-bar/search-bar.vue +1 -0
  312. package/dist/assets/components/secondary-nav/components/secondary-nav-category/secondary-nav-category.vue +1 -0
  313. package/dist/assets/components/secondary-nav/components/secondary-nav-item/secondary-nav-item.vue +1 -0
  314. package/dist/assets/components/secondary-nav/secondary-nav.docs.mdx +40 -0
  315. package/dist/assets/components/secondary-nav/secondary-nav.stories.ts +1 -0
  316. package/dist/assets/components/secondary-nav/secondary-nav.vue +1 -0
  317. package/dist/assets/components/segmented-control/components/segmented-control-button/segmented-control-button.vue +1 -0
  318. package/dist/assets/components/segmented-control/segmented-control.docs.mdx +90 -0
  319. package/dist/assets/components/segmented-control/segmented-control.stories.ts +1 -0
  320. package/dist/assets/components/segmented-control/segmented-control.vue +1 -0
  321. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.docs.mdx +119 -0
  322. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.stories.ts +1 -0
  323. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.vue +1 -0
  324. package/dist/assets/components/selection-card/selection-card.docs.mdx +108 -0
  325. package/dist/assets/components/selection-card/selection-card.stories.ts +1 -0
  326. package/dist/assets/components/selection-card/selection-card.vue +1 -0
  327. package/dist/assets/components/sidepanel/components/sidepanel-page.stories.ts +1 -0
  328. package/dist/assets/components/sidepanel/components/sidepanel-page.vue +1 -0
  329. package/dist/assets/components/sidepanel/sidepanel.docs.mdx +129 -0
  330. package/dist/assets/components/sidepanel/sidepanel.stories.ts +1 -0
  331. package/dist/assets/components/sidepanel/sidepanel.vue +1 -0
  332. package/dist/assets/components/status/status.docs.mdx +62 -0
  333. package/dist/assets/components/status/status.stories.ts +1 -0
  334. package/dist/assets/components/status/status.vue +1 -0
  335. package/dist/assets/components/stepper/components/step/step.stories.ts +1 -0
  336. package/dist/assets/components/stepper/components/step/step.vue +1 -0
  337. package/dist/assets/components/stepper/stepper.docs.mdx +127 -0
  338. package/dist/assets/components/stepper/stepper.stories.ts +1 -0
  339. package/dist/assets/components/stepper/stepper.vue +1 -0
  340. package/dist/assets/components/structured-list/components/structered-list-item/structured-list-item.stories.ts +1 -0
  341. package/dist/assets/components/structured-list/components/structered-list-item/structured-list-item.vue +1 -0
  342. package/dist/assets/components/structured-list/structured-list.docs.mdx +68 -0
  343. package/dist/assets/components/structured-list/structured-list.stories.ts +1 -0
  344. package/dist/assets/components/structured-list/structured-list.vue +1 -0
  345. package/dist/assets/components/summary-grid/components/summary-grid-item/summary-grid-item.vue +1 -0
  346. package/dist/assets/components/summary-grid/components/summary-grid-item-amount/summary-grid-item-amount.stories.ts +1 -0
  347. package/dist/assets/components/summary-grid/components/summary-grid-item-amount/summary-grid-item-amount.vue +1 -0
  348. package/dist/assets/components/summary-grid/components/summary-grid-item-custom/summary-grid-item-custom.stories.ts +1 -0
  349. package/dist/assets/components/summary-grid/components/summary-grid-item-custom/summary-grid-item-custom.vue +1 -0
  350. package/dist/assets/components/summary-grid/components/summary-grid-item-numeric/summary-grid-item-numeric.stories.ts +1 -0
  351. package/dist/assets/components/summary-grid/components/summary-grid-item-numeric/summary-grid-item-numeric.vue +1 -0
  352. package/dist/assets/components/summary-grid/components/summary-grid-item-percentage/summary-grid-item-percentage.stories.ts +1 -0
  353. package/dist/assets/components/summary-grid/components/summary-grid-item-percentage/summary-grid-item-percentage.vue +1 -0
  354. package/dist/assets/components/summary-grid/components/summary-grid-item-text/summary-grid-item-text.stories.ts +1 -0
  355. package/dist/assets/components/summary-grid/components/summary-grid-item-text/summary-grid-item-text.vue +1 -0
  356. package/dist/assets/components/summary-grid/summary-grid.docs.mdx +152 -0
  357. package/dist/assets/components/summary-grid/summary-grid.stories.ts +1 -0
  358. package/dist/assets/components/summary-grid/summary-grid.vue +1 -0
  359. package/dist/assets/components/tabs/components/tab.vue +1 -0
  360. package/dist/assets/components/tabs/tabs.docs.mdx +98 -0
  361. package/dist/assets/components/tabs/tabs.stories.ts +1 -0
  362. package/dist/assets/components/tabs/tabs.vue +1 -0
  363. package/dist/assets/components/tag/tag.docs.mdx +137 -0
  364. package/dist/assets/components/tag/tag.stories.ts +1 -0
  365. package/dist/assets/components/tag/tag.vue +1 -0
  366. package/dist/assets/components/textarea/textarea.docs.mdx +53 -0
  367. package/dist/assets/components/textarea/textarea.stories.ts +1 -0
  368. package/dist/assets/components/textarea/textarea.vue +1 -0
  369. package/dist/assets/components/timeline/components/timeline-item/timeline-item.stories.ts +1 -0
  370. package/dist/assets/components/timeline/components/timeline-item/timeline-item.vue +1 -0
  371. package/dist/assets/components/timeline/timeline.docs.mdx +131 -0
  372. package/dist/assets/components/timeline/timeline.stories.ts +1 -0
  373. package/dist/assets/components/timeline/timeline.vue +1 -0
  374. package/dist/assets/components/toast/components/toast-item/toast-item.vue +1 -0
  375. package/dist/assets/components/toast/components/toast-shadow-stack/toast-shadow-stack.vue +1 -0
  376. package/dist/assets/components/toast/toast.docs.mdx +151 -0
  377. package/dist/assets/components/toast/toast.stories.ts +1 -0
  378. package/dist/assets/components/toast/toast.vue +1 -0
  379. package/dist/assets/components/toggle/toggle.docs.mdx +81 -0
  380. package/dist/assets/components/toggle/toggle.stories.ts +1 -0
  381. package/dist/assets/components/toggle/toggle.vue +1 -0
  382. package/dist/assets/components/tutorial/components/tutorial-popover/components/tutorial-indicator/tutorial-indicator.vue +1 -0
  383. package/dist/assets/components/tutorial/components/tutorial-popover/tutorial-popover.vue +1 -0
  384. package/dist/assets/components/tutorial/tutorial.docs.mdx +85 -0
  385. package/dist/assets/components/tutorial/tutorial.stories.ts +1 -0
  386. package/dist/assets/components/tutorial/tutorial.vue +1 -0
  387. package/dist/assets/components/typography/typography.docs.mdx +124 -0
  388. package/dist/assets/components/typography/typography.stories.ts +1 -0
  389. package/dist/assets/components/typography/typography.vue +1 -0
  390. package/dist/assets/composables/use-bento-currency/use-bento-currency.docs.mdx +28 -0
  391. package/dist/assets/composables/use-bento-currency/use-bento-currency.stories.ts +1 -0
  392. package/dist/assets/composables/use-click-outside/use-click-outside.docs.mdx +10 -0
  393. package/dist/assets/composables/use-click-outside/use-click-outside.stories.ts +1 -0
  394. package/dist/assets/directives/highlight/highlight.docs.mdx +64 -0
  395. package/dist/assets/directives/highlight/highlight.stories.ts +1 -0
  396. package/dist/assets/directives/keyboard-navigation/keyboard-navigation.docs.mdx +41 -0
  397. package/dist/assets/directives/keyboard-navigation/keyboard-navigation.stories.ts +1 -0
  398. package/dist/assets/directives/tooltip/tooltip.docs.mdx +86 -0
  399. package/dist/assets/directives/tooltip/tooltip.stories.ts +1 -0
  400. package/dist/assets/index.ts +1 -0
  401. package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.stories.ts +1 -0
  402. package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.vue +1 -0
  403. package/dist/assets/templates/dashboard-template/dashboard-template.docs.mdx +148 -0
  404. package/dist/assets/templates/dashboard-template/dashboard-template.stories.ts +1 -0
  405. package/dist/assets/templates/dashboard-template/dashboard-template.vue +1 -0
  406. package/dist/assets/templates/data-grid-template/data-grid-template.docs.mdx +117 -0
  407. package/dist/assets/templates/data-grid-template/data-grid-template.stories.ts +1 -0
  408. package/dist/assets/templates/data-grid-template/data-grid-template.vue +1 -0
  409. package/dist/main.js +30031 -0
  410. package/package.json +45 -3
@@ -0,0 +1,148 @@
1
+ import { Canvas, Meta } from '@storybook/blocks';
2
+ import * as DashboardTemplateStories from './dashboard-template.stories';
3
+ import * as DashboardSectionStories from './components/dashboard-section/dashboard-section.stories';
4
+
5
+ <Meta of={DashboardTemplateStories} />
6
+
7
+ # Dashboard Template
8
+
9
+ Dashboard template is to be used when visualizing data on pages such as data dashboards and reports.
10
+
11
+ <Canvas of={DashboardTemplateStories.Default} />
12
+
13
+ ## Use Cases
14
+
15
+ Use a DashboardTemplate:
16
+
17
+ - when you need to visualize data such as charts and breakdowns.
18
+
19
+ ## Overview of elements
20
+
21
+ ## Header
22
+
23
+ Page header holds the page title and a set of actions related to the dashboard. It can be configured to display a
24
+ tooltip and a timestamp when needed.
25
+
26
+ The header is passed to the Dashboard template as a prop, using all the same props as the `Header` component.
27
+
28
+ ## Tabs
29
+
30
+ Use tabs to navigate between different but related content within a page.
31
+
32
+ Tabs can be used above or below the filter bar depending on your use case:
33
+
34
+ - Use tabs above the filter bar when filters are related to one tab
35
+ - Use tabs below the filter bar when filters are related to all tabs
36
+
37
+ ### Tabs object
38
+
39
+ Tabs are passed to the Dashboard template as a prop, using all the same props as the `Tabs` component.
40
+
41
+ You can then pass the content to the respective tabs by using the template with the tab id, which is `tab-{index}`.
42
+
43
+ ### Sticky tabs
44
+
45
+ Tabs can be configured to stick to the top when scrolling so that they are always accessible and visible by using the
46
+ `stickyTabs` prop.
47
+
48
+ <Canvas of={DashboardTemplateStories.WithTabs} />
49
+
50
+ ## Filters
51
+
52
+ Use a filter bar when a user needs to filter the dashboard to a specific data story.
53
+
54
+ You can pass the `bento-filter` component to the `filters` slot, which will display above the tabs if they are present
55
+ on the page.
56
+
57
+ If you need to display the filters under the tabs, then it will be passed as part of the tab content slot.
58
+
59
+ ### Sticky filters
60
+
61
+ Filters can be configured to stick to the top when scrolling so that they are always accessible and visible by using the
62
+ `stickyFilters` prop. This will only work for filters passed into the `filters` slot.
63
+
64
+ ## Content
65
+
66
+ Content will be passed to the `default` slot, if you're using tabs, content will be inside the `tab-{index}` slots
67
+ instead.
68
+
69
+ These are the recommended elements to use inside the Dashboard template:
70
+
71
+ ### Summary grid
72
+
73
+ Use a summary grid to highlight key summary data points on your dashboard.
74
+
75
+ ### Dashboard section
76
+
77
+ Dashboard section is a child component of the dashboard template to help you render your data, with Lume charts or data
78
+ grids.
79
+
80
+ The component consists of a header, a slot to pass your data controls and slots for the data, you can display the
81
+ content in one `full-width` column, using the `default` slot, or two columns, passing the `content-col-1` and
82
+ `content-col-2` slots.
83
+
84
+ Additionally, the entire section can also be rendered in half-width, by passing the `halfWidth` prop.
85
+
86
+ #### Lume charts
87
+
88
+ Use Lume charts when you need to visualize data points.
89
+
90
+ Charts come in two sizes: one column (by using the `default` slot) or two columns (by using `content-col-1` and
91
+ `content-col-2` slots)
92
+
93
+ Choosing the right chart to display data can be overwhelming. For more information on what chart to use go to
94
+ [Lume](https://lume.is.adyen.com/).
95
+
96
+ <Canvas of={DashboardSectionStories.Graph} />
97
+
98
+ #### Data Grids
99
+
100
+ Use a data grid when you need to display set of data in a way that is easy to scan and analyze.
101
+
102
+ Data Grid should always be used with `full-width` column, so `half-width` or column layout should never be applied when
103
+ using data grids.
104
+
105
+ <Canvas of={DashboardSectionStories.DataGrid} />
106
+
107
+ #### Controls
108
+
109
+ Both charts and data grid can be paired with controls.
110
+
111
+ The amount of controls you can have is dependent on your usecase and user needs.
112
+
113
+ - **Dropdowns**: Use dropdowns when selecting a specific breakdown of the data set or filtering on specific data eg:
114
+ Breaking down the data set by payment methods, acquirer response etc or selecting a date range.
115
+ - **Segmented controls**: Use segmented controls when showing a different view of the same data set eg: Counts,
116
+ amounts and ratios or days, months and weeks.
117
+ - **Tabs**: Use tabs when switching to an entirely different data set eg: API and Webhooks
118
+
119
+ #### Two columns vs half-width
120
+
121
+ Dashboard section can be rendered to take the full width of the page or only half of the page.
122
+
123
+ There's two ways of rendering the content in half of the page:
124
+
125
+ - `content-col-1` and `content-col-2` slots
126
+ - `halfWidth` prop
127
+
128
+ ##### `content-col-1` and `content-col-2` slots
129
+
130
+ If you use the slots, you are rendering one single section, with one title and one set of controls that display two
131
+ different graphs.
132
+
133
+ <Canvas of={DashboardSectionStories.TwoColumns} />
134
+
135
+ ##### `halfWidth` prop
136
+
137
+ If you use `halfWidth` you are rendering the whole section as half of the page. That means that you have two sections
138
+ side-by-side, with different titles and controls.
139
+
140
+ **Don't use `halfWidth` in isolation. If you're passing `half-width` there should always be two
141
+ `bento-dashboard-sections` using the prop.**
142
+
143
+ <Canvas of={DashboardTemplateStories.HalfWidth} />
144
+
145
+ ## Resources
146
+
147
+ - [Figma link](https://www.figma.com/design/lJK6kNN3ClihuCl7ni7v1k/Bento---Templates?node-id=1966-48825&node-type=instance&m=dev)
148
+ - [Lume](https://lume.is.adyen.com/)
@@ -0,0 +1 @@
1
+ import { isVue2 } from 'vue-demi'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { BentoSummaryGrid, BentoSummaryGridItemAmount } from '@/components/summary-grid'; import { BentoDataGrid } from '@/components/data-grid'; import { type BentoDateRangeFilterOptions, BentoFilterBar, type BentoFilterBarModel, BentoFilterItemType, type BentoFilterValues, } from '@/components/filter-bar'; import { BentoDropdown } from '@/components/dropdown'; import { BentoSegmentedControl } from '@/components/segmented-control'; import { LumeLineChart } from '@adyen/lume'; import BentoDashboardTemplate from './dashboard-template.vue'; import BentoDashboardSection from './components/dashboard-section/dashboard-section.vue'; import InfoIcon from '@adyen/ui-assets-icons-16/vue/info'; import Settings from '@adyen/ui-assets-icons-16/vue/settings'; import Download from '@adyen/ui-assets-icons-16/vue/download'; import Share from '@adyen/ui-assets-icons-16/vue/share-2'; import { subDays } from 'date-fns'; import { type BentoDashboardTemplateHeader, type BentoDashboardTemplateTabs } from './dashboard-template.types'; import { type BentoListboxOptions } from '@/types/listbox'; const meta: Meta = { title: 'Dashboard template', component: BentoDashboardTemplate, parameters: { layout: 'fullscreen', }, }; export default meta; type Story = StoryObj<typeof BentoDashboardTemplate>; const HEADER_PROPS: BentoDashboardTemplateHeader = { title: 'Dashboard', lastUpdated: Date.now(), actions: [ { title: 'Glossary', variant: 'secondary', event: () => undefined, icon: InfoIcon }, { title: 'Settings', variant: 'secondary', event: () => undefined, icon: Settings }, { title: 'Download', variant: 'secondary', event: () => undefined, icon: Download }, { title: 'Share', variant: 'secondary', event: () => undefined, icon: Share }, ], infoIconTooltipText: 'Info', }; const TABS_ARGS: BentoDashboardTemplateTabs = { tabs: [{ title: 'Tab 1' }, { title: 'Tab 2' }], }; const HEADER_SECTION_PROPS: BentoDashboardTemplateHeader = { title: 'Section', infoIconTooltipText: 'Extra info about this section', }; const FILTERS_CONFIG: BentoFilterBarModel = [ { field: 'date-range', label: 'Date range', options: { allowTimeInput: true, numberOfMonths: 1, } as BentoDateRangeFilterOptions, type: BentoFilterItemType.DATE_RANGE, visible: true, }, { field: 'company', label: 'Company', options: { listboxItems: [ { label: 'Adyen', value: 'adyen' }, { label: 'Bento', value: 'bento' }, ], multiple: true, }, type: BentoFilterItemType.SELECT, visible: true, }, ]; const FILTER_VALUES: BentoFilterValues = [ { field: 'date-range', value: { startDate: subDays(new Date(), 7), endDate: new Date() }, }, { field: 'company', value: [], }, ]; const SEGMENTED_CONTROL_ITEMS = [ { label: 'Count', value: 'count' }, { label: 'Amount', value: 'amount' }, ]; const DROPDOWN_OPTIONS: BentoListboxOptions = [ { label: 'Monthly', value: 'monthly' }, { label: 'Yearly', value: 'yearly' }, ]; const LUME_DATA = { data: [ { label: 'Skyblue', color: 'skyblue', values: [10, 30, 20, 50, 40], }, { label: 'Green', color: 'green', values: [50, 60, 90, 30, 10], }, ], labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], options: { yAxisOptions: { gridLines: true, title: 'Y-label', }, }, }; const GRID_DATA = [ { id: 1, paymentMethods: 'Visa', amount: '1,234 USD', numeric: '54,213' }, { id: 2, paymentMethods: 'MasterCard', amount: '1,234 USD', numeric: '54,213' }, { id: 3, paymentMethods: 'iDeal', amount: '1,234 USD', numeric: '54,213' }, { id: 4, paymentMethods: 'Klarna', amount: '1,234 USD', numeric: '54,213' }, { id: 5, paymentMethods: 'Apple Pay', amount: '1,234 USD', numeric: '54,213' }, ]; const GRID_COLUMNS = [ { field: 'paymentMethods', label: 'Payment methods', minWidth: 300, mandatory: true }, { field: 'amount', label: 'Amount', numeric: true, minWidth: 300 }, { field: 'numeric', label: 'Numeric', numeric: true, minWidth: 300 }, ]; const DEFAULT_PROPS = { header: HEADER_PROPS, tabs: TABS_ARGS, stickyFilters: true, stickyTabs: true, }; const defaultCode = ` <template> <bento-dashboard-template :header="header" sticky-filters> <template #filters> <bento-filter-bar :config="filterConfig" :filter-values="filterValues" @update:filter-values="filterValues = $event" /> </template> <bento-summary-grid> <template #cell-1-1> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> <template #cell-1-2> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> <template #cell-1-3> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> </bento-summary-grid> <bento-dashboard-section :header="dashboardSectionHeader" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue1" @update:model-value="dropdownValue1 = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue1" @update:model-value="segmentedControlValue1 = $event"/> </template> <lume-line-chart v-bind="lumeData" /> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> <bento-dashboard-section :header="dashboardSectionHeader" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue2" @update:model-value="dropdownValue2 = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue2" @update:model-value="segmentedControlValue2 = $event"/> </template> <lume-line-chart v-bind="lumeData" /> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> <bento-dashboard-section :header="dashboardSectionHeader"> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> <bento-dashboard-section :header="dashboardSectionHeader"> <bento-data-grid :data="gridData" :columns="gridColumns" /> </bento-dashboard-section> </bento-dashboard-template> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoFilterBar, BentoFilterValues, BentoSummaryGrid, BentoSummaryGridItemAmount, BentoDropdown, BentoSegmentedControl, BentoDataGrid } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; import InfoIcon from '@adyen/ui-assets-icons-16/vue/info'; import Settings from '@adyen/ui-assets-icons-16/vue/settings'; import Download from '@adyen/ui-assets-icons-16/vue/download'; const header = { title: 'Dashboard', lastUpdated: Date.now(), actions: [ { title: 'Glossary', variant: 'secondary', event: () => {}, icon: InfoIcon }, { title: 'Settings', variant: 'secondary', event: () => {}, icon: Settings }, { title: 'Download', variant: 'secondary', event: () => {}, icon: Download }, { title: 'Share', variant: 'secondary', event: () => {}, icon: Share }, ], infoIconTooltipText: 'Info', }; const filterConfig = ${JSON.stringify(FILTERS_CONFIG, null, 4)}; const dashboardSectionHeader = ${JSON.stringify(HEADER_SECTION_PROPS, null, 4)}; const dropdownOptions = ${JSON.stringify(DROPDOWN_OPTIONS, null, 4)}; const segmentedControlItems = ${JSON.stringify(SEGMENTED_CONTROL_ITEMS, null, 4)}; const lumeData = ${JSON.stringify(LUME_DATA, null, 4)}; const filterValues = ref<BentoFilterValues>([ { field: 'date-range', value: { startDate: subDays(new Date(), 7), endDate: new Date() }, }, { field: 'company', value: [], }, ]); const gridData = ${JSON.stringify(GRID_DATA, null, 4)}; const gridColumns = ${JSON.stringify(GRID_COLUMNS, null, 4)}; const segmentedControlValue1 = ref('count'); const dropdownValue1 = ref('monthly'); const segmentedControlValue2 = ref('count'); const dropdownValue2 = ref('monthly'); </script> `; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardTemplate, BentoDashboardSection, BentoFilterBar, BentoSummaryGrid, BentoSummaryGridItemAmount, BentoDropdown, BentoSegmentedControl, BentoDataGrid, LumeLineChart, }, props: Object.keys(argTypes), template: ` <bento-dashboard-template v-bind="args"> <template #filters> <bento-filter-bar :config="FILTERS_CONFIG" :filter-values="filterValues" @update:filter-values="filterValues = $event" /> </template> <bento-summary-grid> <template #cell-1-1> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> <template #cell-1-2> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> <template #cell-1-3> <bento-summary-grid-item-amount title="Title" label="€ 220.00" /> </template> </bento-summary-grid> <bento-dashboard-section :header="HEADER_SECTION_PROPS" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue1" @update:model-value="dropdownValue1 = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue1" @update:model-value="segmentedControlValue1 = $event"/> </template> <lume-line-chart v-bind="LUME_DATA" /> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> <bento-dashboard-section :header="HEADER_SECTION_PROPS" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue2" @update:model-value="dropdownValue2 = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue2" @update:model-value="segmentedControlValue2 = $event"/> </template> <lume-line-chart v-bind="LUME_DATA" /> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> <bento-dashboard-section :header="HEADER_SECTION_PROPS"> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> <bento-dashboard-section :header="HEADER_SECTION_PROPS"> <bento-data-grid :data="GRID_DATA" :columns="GRID_COLUMNS" /> </bento-dashboard-section> </bento-dashboard-template> `, setup(props) { const args = isVue2 ? props : _args; const filterValues = ref<BentoFilterValues>(FILTER_VALUES); const segmentedControlValue1 = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue1 = ref(DROPDOWN_OPTIONS[0].value); const segmentedControlValue2 = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue2 = ref(DROPDOWN_OPTIONS[0].value); return { args, // Values filterValues, segmentedControlValue1, dropdownValue1, segmentedControlValue2, dropdownValue2, // Constants HEADER_SECTION_PROPS, FILTERS_CONFIG, DROPDOWN_OPTIONS, SEGMENTED_CONTROL_ITEMS, LUME_DATA, GRID_DATA, GRID_COLUMNS, }; }, }), args: DEFAULT_PROPS, parameters: storybookDocsParameter(defaultCode), }; const withTabsCode = ` <template> <bento-dashboard-template :header="header" :tabs="tabs" sticky-filters sticky-tabs> <template #filters> <bento-filter-bar :config="filterConfig" :filter-values="filterValues" @update:filter-values="filterValues = $event" /> </template> <template #tab-1> <bento-dashboard-section :header="dashboardSectionHeader"> <template #controls> <bento-dropdown :model-value="dropdownValue1" @update:model-value="dropdownValue1 = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue1" @update:model-value="segmentedControlValue1 = $event"/> </template> <template #content-col-1> <lume-line-chart v-bind="lumeData" /> <lume-line-chart v-bind="lumeData" /> </template> <template #content-col-2> <lume-line-chart v-bind="lumeData" /> <lume-line-chart v-bind="lumeData" /> </template> </bento-dashboard-section> </template> <template #tab-2> <bento-dashboard-section :header="dashboardSectionHeader"> <template #controls> <bento-dropdown :model-value="dropdownValue2" @update:model-value="dropdownValue2 = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue2" @update:model-value="segmentedControlValue2 = $event"/> </template> <template #content-col-1><lume-line-chart v-bind="lumeData" /></template> <template #content-col-2><lume-line-chart v-bind="lumeData" /></template> </bento-dashboard-section> </template> </bento-dashboard-template> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoFilterBar, BentoFilterValues, BentoDropdown, BentoSegmentedControl } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; import InfoIcon from '@adyen/ui-assets-icons-16/vue/info'; import Settings from '@adyen/ui-assets-icons-16/vue/settings'; import Download from '@adyen/ui-assets-icons-16/vue/download'; const header = { title: 'Dashboard', lastUpdated: Date.now(), actions: [ { title: 'Glossary', variant: 'secondary', event: () => {}, icon: InfoIcon }, { title: 'Settings', variant: 'secondary', event: () => {}, icon: Settings }, { title: 'Download', variant: 'secondary', event: () => {}, icon: Download }, { title: 'Share', variant: 'secondary', event: () => {}, icon: Share }, ], infoIconTooltipText: 'Info', }; const tabs = ${JSON.stringify(TABS_ARGS, null, 4)}; const filterConfig = ${JSON.stringify(FILTERS_CONFIG, null, 4)}; const dashboardSectionHeader = ${JSON.stringify(HEADER_SECTION_PROPS, null, 4)}; const dropdownOptions = ${JSON.stringify(DROPDOWN_OPTIONS, null, 4)}; const segmentedControlItems = ${JSON.stringify(SEGMENTED_CONTROL_ITEMS, null, 4)}; const lumeData = ${JSON.stringify(LUME_DATA, null, 4)}; const filterValues = ref<BentoFilterValues>([ { field: 'date-range', value: { startDate: subDays(new Date(), 7), endDate: new Date() }, }, { field: 'company', value: [], }, ]); const segmentedControlValue1 = ref('count'); const dropdownValue1 = ref('monthly'); const segmentedControlValue2 = ref('count'); const dropdownValue2 = ref('monthly'); </script> `; export const WithTabs: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardTemplate, BentoDashboardSection, BentoFilterBar, BentoDropdown, BentoSegmentedControl, LumeLineChart, }, props: Object.keys(argTypes), template: ` <bento-dashboard-template v-bind="args"> <template #filters> <bento-filter-bar :config="FILTERS_CONFIG" :filter-values="filterValues" @update:filter-values="filterValues = $event" /> </template> <template #tab-1> <bento-dashboard-section :header="HEADER_SECTION_PROPS"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <template #content-col-1> <lume-line-chart v-bind="LUME_DATA" /> <lume-line-chart v-bind="LUME_DATA" /> </template> <template #content-col-2> <lume-line-chart v-bind="LUME_DATA" /> <lume-line-chart v-bind="LUME_DATA" /> </template> </bento-dashboard-section> </template> <template #tab-2> <bento-dashboard-section :header="HEADER_SECTION_PROPS"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <template #content-col-1><lume-line-chart v-bind="LUME_DATA" /></template> <template #content-col-2><lume-line-chart v-bind="LUME_DATA" /></template> </bento-dashboard-section> </template> </bento-dashboard-template> `, setup(props) { const args = isVue2 ? props : _args; const filterValues = ref<BentoFilterValues>(FILTER_VALUES); const segmentedControlValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue = ref(DROPDOWN_OPTIONS[0].value); return { args, // Values filterValues, segmentedControlValue, dropdownValue, // Constants HEADER_SECTION_PROPS, FILTERS_CONFIG, SEGMENTED_CONTROL_ITEMS, DROPDOWN_OPTIONS, LUME_DATA, }; }, }), args: DEFAULT_PROPS, parameters: storybookDocsParameter(withTabsCode), }; const halfWidthCode = ` <template> <bento-dashboard-template :header="header"> <bento-dashboard-section :header="{ title: 'Section 1'}" half-width> <template #controls> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> <bento-dashboard-section :header="{ title: 'Section 2'}" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='dropdownOptions' /> </template> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> </bento-dashboard-template> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoDropdown, BentoSegmentedControl, } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; import InfoIcon from '@adyen/ui-assets-icons-16/vue/info'; import Settings from '@adyen/ui-assets-icons-16/vue/settings'; import Download from '@adyen/ui-assets-icons-16/vue/download'; const header = { title: 'Dashboard', lastUpdated: Date.now(), actions: [ { title: 'Glossary', variant: 'secondary', event: () => {}, icon: InfoIcon }, { title: 'Settings', variant: 'secondary', event: () => {}, icon: Settings }, { title: 'Download', variant: 'secondary', event: () => {}, icon: Download }, { title: 'Share', variant: 'secondary', event: () => {}, icon: Share }, ], infoIconTooltipText: 'Info', }; const dropdownOptions = ${JSON.stringify(DROPDOWN_OPTIONS, null, 4)}; const segmentedControlItems = ${JSON.stringify(SEGMENTED_CONTROL_ITEMS, null, 4)}; const lumeData = ${JSON.stringify(LUME_DATA, null, 4)}; const segmentedControlValue = ref('count'); const dropdownValue = ref('monthly'); </script> `; export const HalfWidth: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardTemplate, BentoDashboardSection, BentoDropdown, BentoSegmentedControl, LumeLineChart, }, props: Object.keys(argTypes), template: ` <bento-dashboard-template v-bind="args"> <bento-dashboard-section :header="{ title: 'Section 1' }" half-width> <template #controls> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> <bento-dashboard-section :header="{ title: 'Section 2' }" half-width> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='DROPDOWN_OPTIONS' /> </template> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> </bento-dashboard-template> `, setup(props) { const segmentedControlValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue = ref(DROPDOWN_OPTIONS[0].value); return { // Values args: isVue2 ? props : _args, segmentedControlValue, dropdownValue, // Contants LUME_DATA, SEGMENTED_CONTROL_ITEMS, DROPDOWN_OPTIONS, }; }, }), args: DEFAULT_PROPS, parameters: storybookDocsParameter(halfWidthCode), };
@@ -0,0 +1 @@
1
+ <template> <main class="b-dashboard-template"> <bento-header v-bind="header" variant="page" class="b-dashboard-template__header"> <template v-if="hasSlot('infoIconTooltipContent')" #infoIconTooltipContent> <slot name="infoIconTooltipContent" /> </template> </bento-header> <div class="b-dashboard-template__top-section" :class="dashboardTopSectionConditionalClasses"> <div v-if="hasSlot('filters')" ref="filtersRef" class="b-dashboard-template__filters" :class="dashboardFiltersConditionalClasses" data-testid="filters" > <slot name="filters" /> </div> <bento-tabs v-if="tabsSlots.length > 1" ref="tabsRef" :active-tab-index="tabs.activeTabIndex" :sticky="stickyTabs" :sticky-options="computedTabsOptions" data-testid="tabs" > <bento-tab v-for="(_item, index) in tabsSlots" :key="`tab-${index}`" :title="getTabTitle(index)"> <div class="b-dashboard-template__container b-dashboard-template__container--tabs"> <slot :name="`tab-${index + 1}`" /> </div> </bento-tab> </bento-tabs> <div v-else class="b-dashboard-template__container"> <slot /> </div> </div> </main> </template> <script setup lang="ts"> import { computed, onUnmounted, ref, useSlots, watch } from 'vue'; import { BentoHeader } from '@/components/header'; import { BentoTab, BentoTabs } from '@/components/tabs'; import { useWindowScroll } from '@vueuse/core'; import { observeSizeOfElement } from '@/utils/ts/resize'; import { useHasSlot } from '@/composables'; import type { BentoDashboardTemplateHeader, BentoDashboardTemplateTabs } from './dashboard-template.types'; const props = withDefaults( defineProps<{ /** * The header that goes to the top of the template */ header: BentoDashboardTemplateHeader; /** * All the tab properties that can be set on the inner tab components. * - tabs.activeTabIndex: the currently active tab index. * - tabs.tabs: an array of BentoTab props, the first item in the array will affect the `tab-1` slot and so on. */ tabs?: BentoDashboardTemplateTabs; /** * Renders the tabs with a sticky positioning */ stickyTabs?: boolean; /** * Renders the tabs with a sticky positioning */ stickyFilters?: boolean; }>(), { tabs: undefined, stickyTabs: false, stickyFilters: false, } ); const slots = useSlots(); const hasSlot = useHasSlot(slots); const tabsRef = ref<InstanceType<typeof BentoTabs>>(); const filtersRef = ref<HTMLDivElement>(null); const isFiltersPinned = ref(false); let filtersElementObserver: ResizeObserver | null = null; const tabsPosition = ref(0); const hasStickyFilters = computed(() => filtersRef.value && props.stickyFilters); const hasStickyTabs = computed(() => tabsRef.value && props.stickyTabs); const dashboardFiltersConditionalClasses = computed(() => ({ 'b-dashboard-template__filters--sticky': props.stickyFilters, 'b-dashboard-template__filters--show-border': hasStickyFilters.value && !hasStickyTabs.value && isFiltersPinned.value, })); const dashboardTopSectionConditionalClasses = computed(() => ({ 'b-dashboard-template__top-section--sticky': props.stickyTabs || props.stickyFilters, })); const tabsSlots = computed(() => Object.keys(slots).filter(el => el?.includes('tab-'))); const getTabTitle = (index: number) => props?.tabs.tabs?.[index]?.title ?? `Tab ${index + 1}`; const computedTabsOptions = computed(() => (tabsPosition.value ? { top: tabsPosition.value } : undefined)); const { y } = useWindowScroll(); watch( () => filtersRef.value, () => { if (!filtersElementObserver && filtersRef.value) { filtersElementObserver = observeSizeOfElement(filtersRef.value, () => { if (filtersRef.value && hasStickyTabs.value) { const filtersHeight = filtersRef.value.offsetHeight; tabsPosition.value = hasStickyFilters.value ? filtersHeight : 0; } }); } } ); watch( () => y.value, () => { if (hasStickyFilters.value) { isFiltersPinned.value = filtersRef.value?.getBoundingClientRect().top === 0; } } ); onUnmounted(() => { filtersElementObserver?.disconnect(); }); </script> <script lang="ts"> /** * Dashboard template is a full page template used to visualize data on pages such as data dashboards and reports. * * @example * import { BentoDashboardTemplate, BentoDashboardSection } from '@adyen/bento-vue2'; * * export default { * components: { BentoDashboardTemplate, BentoDashboardSection }, * template: ` * <bento-dashboard-template :header="{ title: 'Dashboard'}" :tabs="tabs: [{ title: 'Tab 1' }, { title: 'Tab 2' }]" sticky-tabs sticky-filters> * <template #tab-1> * <bento-dashboard-section :header="{ title: 'Section'}"> * <template #controls> * // Add your controls here * </template> * // Add your content here * </bento-dashboard-section> * </template> * <template #tab-2> * <bento-dashboard-section :header="{ title: 'Section'}"> * // Add your content here * </bento-dashboard-section> * </template> * </bento-dashboard-template> * ` * } */ export default {}; </script> <style lang="scss" scoped src="./dashboard-template.scss" />
@@ -0,0 +1,117 @@
1
+ import { Canvas, Meta } from '@storybook/blocks';
2
+ import * as DataGridTemplateStories from './data-grid-template.stories';
3
+
4
+ <Meta of={DataGridTemplateStories} />
5
+
6
+ # Data Grid Template
7
+
8
+ The data grid template is a restrictive, full-page data grid used to display information from a data set. This data grid
9
+ template shouldn't be confused with the data grid.
10
+
11
+ **Important:** since this is a full-page template, it is important that the container it's inserted in allows the
12
+ template to expand to full width and height. E.g. `html` and `body` need to be 100% height.
13
+
14
+ <Canvas of={DataGridTemplateStories.Default} />
15
+
16
+ ## Use Cases
17
+
18
+ You can use a `bento-data-grid-template` when your user needs:
19
+
20
+ - a clear overview of data
21
+ - a way of organizing and analyzing the data in their own way
22
+
23
+ ## Overview of elements
24
+
25
+ ### Header
26
+
27
+ The header provides a title and optional actions for the page. You can provide a header in two ways:
28
+
29
+ 1. **Using the `header` prop:** Pass a configuration object to the `header` prop. This will render a default
30
+ `<bento-header>` component. This is the simplest method and is suitable for most use cases.
31
+
32
+ 2. **Using the `#header` slot:** For more complex scenarios, such as when you need to use a different header component
33
+ like `<bento-header-with-views>`, you can use the `#header` slot. This will override the default header and give you
34
+ full control over the header's content and layout. The `header` prop is not required in this case.
35
+
36
+ Below is an example of using the `#header` slot to include a header with view-switching capabilities.
37
+
38
+ <Canvas of={DataGridTemplateStories.withHeaderWithViews} />
39
+
40
+ ### Additional content
41
+
42
+ Any additional content that needs to be displayed on the page can be passed via the `additionalContent` slot. This slot
43
+ will be rendered between the header and the tabs.
44
+
45
+ ### Tabs
46
+
47
+ When present, tabs are used to navigate between different data grids within a page. Note that each tab can contain one
48
+ data grid only.
49
+
50
+ The option to pass only one data grid to the `bento-data-grid-template` without rendering tabs is possible through the
51
+ `default` slot.
52
+
53
+ <Canvas of={DataGridTemplateStories.singularDataGrid} />
54
+
55
+ ### Inspector
56
+
57
+ The `bento-data-grid-template` features an integrated inspector panel for displaying detailed information. You can
58
+ configure and control its behavior by passing props through the main inspector object. The panel inherits most of its
59
+ functionality directly from the `bento-inspector` component.
60
+
61
+ For accessibility, the `bento-inspector` includes built-in focus management. It is designed to handle cases where the
62
+ element that triggers the inspector might be removed from the Document Object Model (DOM), such as with a `v-if`
63
+ condition. However, if this default behavior is not suitable for your specific use case and leads to unexpected focus
64
+ loss when the inspector closes, you can override it.
65
+
66
+ To ensure focus returns to a predictable and stable location, pass a focusable parent element (e.g.,
67
+ `[role="grid-cell"]`) to the pageFocusAnchor prop within the inspector object. This ensures that even if the original
68
+ trigger element is no longer visible, the user's focus returns to the correct context, preventing a disorienting
69
+ experience.
70
+
71
+ <Canvas of={DataGridTemplateStories.withInspector} />
72
+
73
+ ### Data grid
74
+
75
+ All rendered data grids are passed via slots and thus support all props and attributes already supported by the
76
+ `bento-data-grid`. For more information, consult the `bento-data-grid` documentation.
77
+
78
+ Every data grid in the `bento-data-grid-template` renders with a sticky pagination, whenever the pagination prop is
79
+ passed.
80
+
81
+ ## Variations
82
+
83
+ ### Sticky additional content
84
+
85
+ The additonal content in the `bento-data-grid-template` can be made sticky by passing the `sticky-additional-content`
86
+ property.
87
+
88
+ ### Sticky tabs
89
+
90
+ The `bento-data-grid-template` can be rendered with sticky tabs by passing the `sticky-tabs` property. These will sit
91
+ just above of the data grid sticky content.
92
+
93
+ ## Accessibility
94
+
95
+ The `beto-data-grid-template` is assigned a `main` landmark role and is complementary to the header component since this
96
+ latter one renders an `h1` tag containing the page title.
97
+
98
+ ### Keyboard interaction
99
+
100
+ All the sub-element parts of the data grid template are interactable with the keyboard and reachable through keyboard
101
+ navigation following the logical navigation flow of the page. A detailed list of keyboard interactions is provided in
102
+ the table below.
103
+
104
+ | Keyboard interaction | Output |
105
+ | -------------------- | ---------------------------------------------------- |
106
+ | `Tab` | Moves focus to the various sub-elements in the page. |
107
+ | `Arrow keys` | Navigate the items of a sub-element in the page. |
108
+
109
+ ### Roles, states and properties
110
+
111
+ | ARIA attribute | is automatic? | fallback used | manual override |
112
+ | --------------- | ------------------------------------------------------------------------- | ------------- | --------------- |
113
+ | `main` HTML tag | Yes, it is the outer tag wrapping the whole `data-grid-template` content. | - | - |
114
+
115
+ ## Resources
116
+
117
+ - [Figma link](https://www.figma.com/file/lJK6kNN3ClihuCl7ni7v1k/Bento---Templates?type=design&node-id=499-37908&mode=design&t=RR6YrceXtwOucsil-0)
@@ -0,0 +1 @@
1
+ import { BentoButton } from '@/components/button'; import { BentoCountry, BentoCountryCode } from '@/components/country'; import { type BentoColumn, BentoDataGrid, type BentoDatagridData } from '@/components/data-grid'; import { type BentoFilterBarModel, BentoFilterItemType, type BentoFilterValues } from '@/components/filter-bar'; import { BentoHeaderWithViews, type BentoHeaderWithViewsItem } from '@/components/header-with-views'; import { type BentoInspectorProps } from '@/components/inspector'; import { BentoStatus } from '@/components/status'; import { BentoSummaryGrid, BentoSummaryGridItemAmount, BentoSummaryGridItemCustom } from '@/components/summary-grid'; import { BentoTypography } from '@/components/typography'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { computed, onMounted, ref } from 'vue'; import { isVue2 } from 'vue-demi'; import DataGridTemplateWithHeaderWithViews from './__tests__/data-grid-template-with-header-with-views.vue?raw'; import './data-grid-template.stories.scss?module'; import { type BentoDataGridTemplateTabs } from './data-grid-template.types'; import BentoDataGridTemplate from './data-grid-template.vue'; const meta: Meta = { title: 'Data grid template', component: BentoDataGridTemplate, parameters: { layout: 'fullscreen', }, }; const HEADER_PROPS = { title: 'Payments', actions: [ { title: 'Primary action', event: () => undefined }, { title: 'Secondary action', event: () => undefined }, { title: 'Tetiary action', event: () => undefined }, ], infoIconTooltipText: 'Title Tooltip Text', }; const HEADER_PROPS_DOCS = { title: 'Payments', actions: [ { title: 'Primary action', event: () => undefined }, { title: 'Secondary action', event: () => undefined }, { title: 'Tetiary action', event: () => undefined }, ], infoIconTooltipText: 'Title Tooltip Text', }; const PAGINATION_DOCS = { description: 'datagrid navigation', hasNext: true, size: 10 }; const DEFAULT_COLUMNS: Array<BentoColumn> = [ { field: 'name', label: 'Name', minWidth: 300, mandatory: true }, { field: 'company', label: 'Reference', minWidth: 150 }, { field: 'payment', label: 'Payment', width: 200, minWidth: 150 }, ]; const DATA_GRID_1_DATA: BentoDatagridData = Array.from({ length: 50 }, (_, index) => ({ name: `Name ${index + 1}`, company: `Company ${index + 1}`, payment: `Payment ${index + 1}`, id: `${index + 1}`, })); const FILTERS: BentoFilterBarModel = [ { field: 'name', label: 'Name', type: BentoFilterItemType.INPUT, }, { field: 'company', label: 'Company', type: BentoFilterItemType.INPUT, }, ]; const FILTER_VALUES: BentoFilterValues = [ { field: 'company', value: 'Company 1', }, ]; const FILTERS_DOCS = `[ { field: 'name', label: 'Name', type: BentoFilterItemType.INPUT, }, { field: 'company', label: 'Company', type: BentoFilterItemType.INPUT, }, ]`; const FILTER_VALUES_DOCS = `[ { field: 'company', value: 'Company 1' }, ]`; const TABS_ARGS: BentoDataGridTemplateTabs = { tabs: [{ title: 'Data grid title 1' }, { title: 'Data grid title 2' }], }; const INSPECTOR_ARGS: BentoInspectorProps = { title: 'Title', size: 'large', isOpen: false, activePage: '', expandable: true, }; const DATA_GRID_1_ARGS = { data: DATA_GRID_1_DATA, columns: DEFAULT_COLUMNS, allowColumnDragAndDrop: false, pagination: {}, filterSearchTerm: '', highlightedRows: [DATA_GRID_1_DATA[0].id], selectable: true, selection: [DATA_GRID_1_DATA[2].id], }; const DATA_GRID_2_DATA: BentoDatagridData = Array.from({ length: 30 }, (_, index) => ({ name: `Name ${index + 1}`, company: `Company ${index + 1}`, payment: `Payment ${index + 1}`, })); const DATA_GRID_2_ARGS = { data: DATA_GRID_2_DATA, columns: DEFAULT_COLUMNS, allowColumnDragAndDrop: false, pagination: {}, }; export default meta; type Story = StoryObj<typeof BentoDataGridTemplate>; const defaultCode = ` <template> <bento-data-grid-template :header="header" :tabs="tabs" sticky-tabs> <template #tab-1> <bento-data-grid :columns="columns" :data="dataArray" :pagination.sync="pagination" @navigate="clickNavigate" /> </template> <template #tab-2> <bento-data-grid :columns="columns" :data="dataArray" :filter-search-term.sync="searchTerm" :filters="filtersConfig" :filter-values.sync="filterValues" :sort-by.sync="sortBy" /> </template> </bento-data-grid-template> </template> <script setup lang="ts"> import { BentoCountryCode, type BentoColumn, type BentoDatagridSortByColumn, type BentoDatagridDataItem, BentoDataGridTemplate, BentoDataGrid, type BentoDataGridTemplateHeader, type BentoDatagridPaginationProps, type BentoFilterBarModel, BentoFilterItemType, } from '@adyen/bento-vue2'; import messages from './messages.json'; const { t } = useI18n({ messages }); const header: BentoDataGridTemplateHeader = { title: 'Payments', actions: [ { title: 'Primary action', event: () => {} }, { title: 'Secondary action', event: () => {} }, { title: 'Tetiary action', event: () => {} }, ], infoIconTooltipText: 'Title Tooltip Text', }; const tabs: BentoDataGridTemplateTabs = { tabs: [{ title: 'Data grid title 1' }, { title: 'Data grid title 2' }], }; const columns = computed<BentoColumn[]>(() => [ { field: 'name', label: t('Name'), minWidth: 300, mandatory: true, frozen: true, autoWidth: true, sortable: true, }, { field: 'company', label: t('Reference') }, { field: 'payment', label: t('Payment'), width: 200, minWidth: 150 }, ]); const filtersConfig = computed<BentoFilterBarModel>(() => [ { field: 'company', label: t('Company'), type: BentoFilterItemType.INPUT, }, { field: 'countryCode', label: t('Country'), options: { listboxItems: [ { value: BentoCountryCode.NL, }, { value: BentoCountryCode.BE, }, ], variant: 'name', }, type: BentoFilterItemType.SELECT_COUNTRY, }, ]); // Watch this to keep track if the user filters data const filterValues = ref(); // Watch this to keep track if the user sorts data const sortBy = ref<BentoDatagridSortByColumn[]>([]); // Watch this to keep track if the user searches for data const searchTerm = ref(''); // Watch this to keep track if the user pages through the data const pagination = ref<BentoDatagridPaginationProps>({ description: 'datagrid 1 navigation', hasNext: true, size: 10 }); // This is a contrived example of the dataArray as this will normally be retried via an API const dataArray = ref<BentoDatagridDataItem[]>([ { id: '03c0a799-1ced-4017-aea3-0cebb0106335', name: 'Shepherd Kane', payment: 160405, company: 'VURBO', registered: '2023-06-30T13:56:09.498Z', tags: ['deserunt', 'et', 'esse'], reference: 'UnbQaUncf3eR1D8XUBqn_UnbQaUncf3eR1D8XUBqn_UnbQaUncf3eR1D8XUBqn', paymentStatus: 1, countryCode: BentoCountryCode.NL, }, { id: 'b6d4f1fd-b1f6-40a6-a443-f785c89604ef', name: 'Santos Palmer', payment: 163500, company: 'POLARAX', registered: '2023-04-28T13:11:09.498Z', tags: ['et', 'Lorem', 'sint'], reference: 'IxUZ9FsEPCZ9dFFPpI9C', paymentStatus: 2, countryCode: BentoCountryCode.BE, }, ]); </script> `; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoDataGrid, BentoDataGridTemplate, }, props: Object.keys(argTypes), template: ` <bento-data-grid-template v-bind="args"> <template #infoIconTooltipContent>Test</template> <template #tab-1><bento-data-grid v-bind="dataGrid1Props" :filters="filters" :filter-values.sync="filterValues" column-panel /></template> <template #tab-2><bento-data-grid v-bind="dataGrid2Props" /></template> <template #inspector-content>Hello</template> </bento-data-grid-template> `, setup(props) { const args = isVue2 ? props : _args; const filters = ref<BentoFilterBarModel>(args?.filters ?? FILTERS); const filterValues = ref<BentoFilterValues>(args?.filterValues ?? FILTER_VALUES); const dataGrid1Props = DATA_GRID_1_ARGS; const dataGrid2Props = DATA_GRID_2_ARGS; return { // Values args, dataGrid1Props, dataGrid2Props, filters, filterValues, }; }, }), args: { header: HEADER_PROPS, tabs: TABS_ARGS, inspector: INSPECTOR_ARGS, }, parameters: storybookDocsParameter(defaultCode), }; const additionalContentCode = ` <bento-data-grid-template :header="${JSON.stringify(HEADER_PROPS_DOCS)}" :tabs="${JSON.stringify( TABS_ARGS )}" sticky-tabs> <template #additionalContent> Your additional content/component here </template> <template #tab-1> <bento-data-grid :columns="${JSON.stringify(DEFAULT_COLUMNS)}" :data="dataArray" :pagination="${JSON.stringify(PAGINATION_DOCS)}" @navigate="clickNavigate" /> </template> <template #tab-2> <bento-data-grid :columns="${JSON.stringify(DEFAULT_COLUMNS)}" :data="dataArray" :filter-search-term.sync="searchTerm" :filters="${FILTERS_DOCS}" :filter-values.sync="${FILTER_VALUES_DOCS}" @filter-search-clear="onSearchCleared" @filter-search-input="onSearchInput" /> </template> </bento-data-grid-template> `; export const withAdditionalContent: Story = { render: (_args, { argTypes }) => ({ components: { BentoCountry, BentoDataGrid, BentoDataGridTemplate, BentoStatus, BentoSummaryGrid, BentoSummaryGridItemAmount, BentoSummaryGridItemCustom, }, props: Object.keys(argTypes), template: ` <bento-data-grid-template v-bind="args"> <template #additionalContent> <bento-summary-grid> <template #cell-1-1> <bento-summary-grid-item-custom title="Title" info-icon-tooltip-text="Text for icon" > <bento-status variant="green"> Status </bento-status> </bento-summary-grid-item-custom> </template> <template #cell-1-2> <bento-summary-grid-item-amount title="Title" label="€200.00" secondary-label="/ day" info-icon-tooltip-text="Text for icon" copy="Copy this to clipboard" /> </template> <template #cell-1-3> <bento-summary-grid-item-custom title="Title" info-icon-tooltip-text="Text for icon" > <bento-country :code="BentoCountryCode.NL" /> </bento-summary-grid-item-custom> </template> </bento-summary-grid> </template> <template #tab-1><bento-data-grid v-bind="dataGrid1Props" :filters="filters" :filter-values.sync="filterValues" /></template> <template #tab-2><bento-data-grid v-bind="dataGrid2Props" /></template> </bento-data-grid-template> `, setup(props) { const args = isVue2 ? props : _args; const filters = ref<BentoFilterBarModel>(args?.filters ?? FILTERS); const filterValues = ref<BentoFilterValues>(args?.filterValues ?? FILTER_VALUES); const dataGrid1Props = DATA_GRID_1_ARGS; const dataGrid2Props = DATA_GRID_2_ARGS; return { // Values args, dataGrid1Props, dataGrid2Props, filters, filterValues, // Enums BentoCountryCode, }; }, }), args: { header: HEADER_PROPS, tabs: TABS_ARGS, }, parameters: storybookDocsParameter(additionalContentCode), }; const singularDataGridCode = ` <bento-data-grid-template :header="${JSON.stringify(HEADER_PROPS)}" sticky-tabs> <bento-data-grid :columns="${JSON.stringify(DEFAULT_COLUMNS)}" :data="dataArray" :pagination="${JSON.stringify(PAGINATION_DOCS)}" @navigate="clickNavigate" :filter-search-term.sync="searchTerm" :filters="${FILTERS_DOCS}" :filter-values.sync="${FILTER_VALUES_DOCS}" @filter-search-clear="onSearchCleared" @filter-search-input="onSearchInput" /> </bento-data-grid-template> `; export const singularDataGrid: Story = { render: (_args, { argTypes }) => ({ components: { BentoDataGrid, BentoDataGridTemplate }, props: Object.keys(argTypes), template: ` <bento-data-grid-template v-bind="args"> <bento-data-grid v-bind="dataGridProps" :filters="filters" :filter-values.sync="filterValues" /> </bento-data-grid-template> `, setup(props) { const args = isVue2 ? props : _args; const filters = ref<BentoFilterBarModel>(args?.filters ?? FILTERS); const filterValues = ref<BentoFilterValues>(args?.filterValues ?? FILTER_VALUES); const dataGridProps = DATA_GRID_1_ARGS; return { // Values args, dataGridProps, filters, filterValues, }; }, }), args: { header: HEADER_PROPS, }, parameters: storybookDocsParameter(singularDataGridCode), }; const inspectorCode = ` <template> <bento-data-grid-template :header="header" :inspector="computedInspectorProps" @update:is-open:inspector="isInspectorOpen = $event" @update:active-page:inspector="inspectorActivePage = $event" > <template #default> <bento-data-grid :columns="columns" :data="dataArray" /> </template> <template #inspector-content> <div style="padding: 1rem;"> <bento-typography variant="title" el="h3"> Details for: {{ inspectorTitle }} </bento-typography> </div> </template> </bento-data-grid-template> </template> <script setup lang="ts"> import { ref, computed, onMounted } from 'vue'; import { BentoDataGridTemplate, BentoDataGrid, BentoTypography, } from '@adyen/bento-vue2'; import type { BentoDataGridTemplateHeader, BentoColumn, BentoDatagridDataItem } from '@adyen/bento-vue3'; const isInspectorOpen = ref(true); const inspectorTitle = ref('Shepherd Kane'); const inspectorActivePage = ref('id-1'); const pageFocusAnchorRef = ref<HTMLElement | null>(null); const dataArray = ref([ { id: '1', name: 'Shepherd Kane', company: 'Company 1', payment: 1604.05 }, { id: '2', name: 'Santos Palmer', company: 'Company 2', payment: 1635.00 }, ]); const openInspector = (item) => { inspectorTitle.value = item.name as string; isInspectorOpen.value = true; inspectorActivePage.value = item.id as string; const row = document.querySelector(\`[role="row"][aria-rowindex="\${item.rowIndex + 1}"]\`); pageFocusAnchorRef.value = row?.querySelector('[role="gridcell"]') as HTMLElement; }; const columns = computed<BentoColumn[]>(() => [ { field: 'name', label: 'Name', cellActions: [{ variant: 'open', event: openInspector }], }, { field: 'payment', label: 'Payment (€)', width: 200, }, ]); const header = ref<BentoDataGridTemplateHeader>({ title: 'Payments', infoIconTooltipText: 'Click the > icon on a row to open the inspector.', }); const computedInspectorProps = computed(() => ({ isOpen: isInspectorOpen.value, title: inspectorTitle.value, activePage: inspectorActivePage.value, pageFocusAnchor: pageFocusAnchorRef.value, })); <script> `; export const withInspector: Story = { render: (_args, { argTypes }) => ({ components: { BentoDataGrid, BentoDataGridTemplate, BentoTypography, BentoButton, }, props: Object.keys(argTypes), template: ` <bento-data-grid-template v-bind="args" :inspector="computedInspectorProps" @update:is-open:inspector="isInspectorOpen = $event" @update:active-page:inspector="inspectorActivePage = $event" > <template #default> <bento-data-grid v-bind="dataGridProps" :filters="dataGridFilters" :filter-values.sync="dataGridFilterValues" /> </template> <template #inspector-content> <bento-typography v-for="i in 10" :key="i" style="padding: 5px"> {{ inspectorContent }} </bento-typography> </template> </bento-data-grid-template> `, setup(props) { const args = isVue2 ? props : _args; const isInspectorOpen = ref(args.inspector.isOpen); const inspectorTitle = ref(args.inspector.title); const inspectorActivePage = ref(''); const dataGridFilters = ref<BentoFilterBarModel>(args?.filters ?? FILTERS); const dataGridFilterValues = ref<BentoFilterValues>(args?.filterValues ?? []); const inspectorContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; const cellWithActions = { ...DEFAULT_COLUMNS[0], cellActions: [{ variant: 'open', event: item => openInspector(item) }], } satisfies BentoColumn; const columnsWithActions: Array<BentoColumn> = [cellWithActions, ...DEFAULT_COLUMNS.slice(1, 2)]; const dataGridProps = { ...DATA_GRID_1_ARGS, columns: columnsWithActions }; const pageFocusAnchorRef = ref<HTMLElement | null>(null); // Find the element after the component has mounted in the browser onMounted(() => { pageFocusAnchorRef.value = document.body .querySelector('[role="row"][aria-rowindex="1"]') .querySelectorAll('[role="gridcell"]')[0] as HTMLElement; }); const openInspector = item => { inspectorTitle.value = item.name; isInspectorOpen.value = true; inspectorActivePage.value = item.name; pageFocusAnchorRef.value = document.body .querySelector(`[role="row"][aria-rowindex="${item.id}"]`) .querySelectorAll('[role="gridcell"]')[0] as HTMLElement; }; const computedInspectorProps = computed(() => ({ ...args.inspector, isOpen: isInspectorOpen.value, title: inspectorTitle.value, activePage: inspectorActivePage.value, pageFocusAnchor: pageFocusAnchorRef.value, })); return { args, dataGridProps, dataGridFilters, dataGridFilterValues, isInspectorOpen, inspectorActivePage, computedInspectorProps, inspectorContent, openInspector, }; }, }), args: { header: HEADER_PROPS, inspector: { title: DATA_GRID_1_DATA[0].name, isOpen: true, activePage: DATA_GRID_1_DATA[0].name, }, }, parameters: storybookDocsParameter(inspectorCode), }; export const withHeaderWithViews: Story = { render: (_args, { argTypes }) => ({ components: { BentoDataGrid, BentoDataGridTemplate, BentoHeaderWithViews, }, props: Object.keys(argTypes), template: ` <bento-data-grid-template v-bind="args"> <template #header> <bento-header-with-views :actions="headerActions" description="Description" title="Page Title" :hasChanges="false" skipUnsavedChangesText="Don’t show this message again" :views="headerViews" /> </template> <template #infoIconTooltipContent>Test</template> <template #tab-1><bento-data-grid v-bind="dataGrid1Props" :filters="filters" :filter-values.sync="filterValues" column-panel /></template> <template #tab-2><bento-data-grid v-bind="dataGrid2Props" /></template> <template #inspector-content>Hello</template> </bento-data-grid-template> `, setup(props) { const args = isVue2 ? props : _args; const filters = ref<BentoFilterBarModel>(args?.filters ?? FILTERS); const filterValues = ref<BentoFilterValues>(args?.filterValues ?? FILTER_VALUES); const dataGrid1Props = DATA_GRID_1_ARGS; const dataGrid2Props = DATA_GRID_2_ARGS; const headerViews: Array<BentoHeaderWithViewsItem> = [ { icon: 'stack', iconColor: 'primary', label: 'View 1', }, { icon: 'stack', iconColor: 'primary', label: 'View 2', }, ]; const headerActions = [ { title: 'Primary action', }, { title: 'Secondary action', }, ]; return { // Values args, dataGrid1Props, dataGrid2Props, filters, filterValues, headerActions, headerViews, }; }, }), args: { tabs: TABS_ARGS, inspector: INSPECTOR_ARGS, }, parameters: storybookDocsParameter(DataGridTemplateWithHeaderWithViews), };
@@ -0,0 +1 @@
1
+ <template> <main class="b-data-grid-template"> <bento-inspector v-bind="computedInspectorProps" ref="inspectorRef" v-on="inspectorEvents"> <template #page> <div class="b-data-grid-template__header"> <slot name="header"> <bento-header v-bind="header"> <template v-if="hasSlot('infoIconTooltipContent')" #infoIconTooltipContent> <slot name="infoIconTooltipContent" /> </template> </bento-header> </slot> </div> <div v-if="hasSlot('additionalContent')" ref="additionalContentRef" class="b-data-grid-template__additional-content" :class="additionalContentConditionalClasses" > <slot name="additionalContent" /> </div> <bento-tabs v-if="tabsSlots.length > 1" ref="tabsRef" :active-tab-index="tabs.activeTabIndex" :sticky="stickyTabs" :sticky-options="stickyAdditionalContent ? { top: computedStickyAdditionalContentHeight } : null" @update:active-tab-index="emitTabs" > <bento-tab v-for="(_item, index) in tabsSlots" :key="`tab-${index}`" :title="getTabTitle(index)"> <slot :name="`tab-${index + 1}`" /> </bento-tab> </bento-tabs> <slot v-else /> </template> <template #content> <slot name="inspector-content" /> </template> </bento-inspector> </main> </template> <script setup lang="ts"> import { BentoHeader } from '@/components/header'; import { BentoInspector } from '@/components/inspector'; import { BentoTab, BentoTabs } from '@/components/tabs'; import { useHasSlot } from '@/composables'; import { computed, type PropType, provide, type Ref, ref, toRef, type UnwrapRef, useSlots } from 'vue'; import { DATA_GRID_REGISTER_TEMPLATE_INJECTION_KEY } from './data-grid-template.keys'; import type { BentoDataGridTemplateDataGrid, BentoDataGridTemplateHeader, BentoDataGridTemplateInspector, BentoDataGridTemplateTabs, } from './data-grid-template.types'; const props = defineProps({ /** * The header that goes to the top of the template */ header: { type: Object as PropType<BentoDataGridTemplateHeader>, default: undefined, }, /** * All the tab properties that can be set on the inner tab components. * - tabs.activeTabIndex: the currenly active tab index. * - tabs.tabs: an array of BentoTab props, the first item in the array will affect the `tab-1` slot and so on. */ tabs: { type: Object as PropType<BentoDataGridTemplateTabs>, default: undefined, }, /** * Renders the additional content slot with a sticky positioning */ stickyAdditionalContent: { type: Boolean, default: false, }, /** * Renders the tabs with a sticky positioning */ stickyTabs: { type: Boolean, default: false, }, /** * All the inspector properties that can be set on the inner inspector component. */ inspector: { type: Object as PropType<BentoDataGridTemplateInspector>, default: undefined, }, }); const slots = useSlots(); const hasSlot = useHasSlot(slots); const emit = defineEmits<{ /** * Emits update event when activeTabIndex changes internally */ (e: 'update:tabs', value: BentoDataGridTemplateTabs): void; /** * Emits update event when the inspector's `isOpen` state changes */ (e: 'update:is-open:inspector', value: boolean): void; /** * Emits update event when the inspector's `activePage` changes */ (e: 'update:active-page:inspector', value: string): void; /** * Emits event when the inspector's expand button is clicked */ (e: 'expand:inspector', value: boolean): void; }>(); const tabsRef = ref(null); const additionalContentRef = ref(null); const inspectorRef = ref(null); const additionalContentConditionalClasses = computed(() => ({ 'b-data-grid-template__additional-content--sticky': props.stickyAdditionalContent, })); const computedInspectorProps = computed(() => ({ title: '', ...props.inspector, })); const computedStickyAdditionalContentHeight = computed(() => additionalContentRef?.value?.offsetHeight); const computedTabsRef = computed(() => tabsRef.value?.$refs?.tablistwrapper); const tabsSlots = computed(() => Object.keys(slots).filter(el => el?.includes('tab-'))); const inspectorEvents = computed(() => ({ 'update:is-open': (value: boolean) => emit('update:is-open:inspector', value), 'update:active-page': (value: string) => emit('update:active-page:inspector', value), expand: (value: boolean) => emit('expand:inspector', value), })); const emitTabs = (newActiveTabIndex: number) => { emit('update:tabs', { ...props.tabs, activeTabIndex: newActiveTabIndex }); }; const getTabTitle = (index: number) => props?.tabs.tabs?.[index]?.title ?? `Tab ${index + 1}`; const registerDatagridInDataGridTemplate: BentoDataGridTemplateDataGrid = () => { const isDataGridTemplate = true; const stickyTabs: Ref<boolean> = toRef(props, 'stickyTabs'); const stickyAdditionalContent: Ref<boolean> = toRef(props, 'stickyAdditionalContent'); const tabsRef: Ref<UnwrapRef<HTMLDivElement>> | null = computedTabsRef; const additionalContentSlotRef: Ref<UnwrapRef<HTMLDivElement>> | null = additionalContentRef; // return values to the Tab component return { isDataGridTemplate, stickyTabs, tabsRef, stickyAdditionalContent, additionalContentSlotRef, }; }; provide(DATA_GRID_REGISTER_TEMPLATE_INJECTION_KEY, registerDatagridInDataGridTemplate); </script> <script lang="ts"> /** * The data grid template is a restrictive, full-page data grid used to display information from a data set. * You can use this data grid template when your user needs a clear overview of data or a way of organizing and analyzing the data in their own way. * This data grid template shouldn’t be confused with the data grid. * * @example * import { BentoDataGridTemplate } from '@adyen/bento-vue2'; * * export default { * components: { BentoDataGridTemplate }, * template: ` * // If you want to display multiple data grids in the same page (they will be rendered in different tabs) * <bento-data-grid-template> * <template #tab-1><bento-data-grid v-bind="your-data-grid-args" title="Title for tab 1"/></template> * <template #tab-2><bento-data-grid v-bind="your-data-grid-args" title="Title for tab 2"/></template> * </bento-data-grid-template> * // Alternatively, if you only want to pass one data grid to your template: * <bento-data-grid-template> * <template #default><bento-data-grid v-bind="your-data-grid-args"/></template> * </bento-data-grid-template> * ` * } */ export default {}; </script> <style lang="scss" scoped src="./data-grid-template.scss" />