@adyen/bento-mcp 0.10.0 → 0.12.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 (429) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +24 -2
  3. package/SKILL.md +37 -7
  4. package/dist/assets/components/accordion/accordion.stories.ts +1 -1
  5. package/dist/assets/components/accordion/components/accordion-item.stories.ts +1 -1
  6. package/dist/assets/components/accordion/components/accordion-item.vue +1 -1
  7. package/dist/assets/components/action-bar/action-bar.docs.mdx +10 -3
  8. package/dist/assets/components/action-bar/action-bar.internal.types.ts +1 -0
  9. package/dist/assets/components/action-bar/action-bar.stories.ts +1 -1
  10. package/dist/assets/components/action-bar/action-bar.types.ts +1 -1
  11. package/dist/assets/components/action-bar/action-bar.vue +1 -1
  12. package/dist/assets/components/ai-tag/ai-tag.stories.ts +1 -1
  13. package/dist/assets/components/ai-tag/ai-tag.vue +1 -1
  14. package/dist/assets/components/alert/alert.stories.ts +1 -1
  15. package/dist/assets/components/alert/alert.types.ts +1 -1
  16. package/dist/assets/components/anchor-scroller/anchor-scroller.stories.ts +1 -1
  17. package/dist/assets/components/anchor-scroller/anchor-scroller.vue +1 -1
  18. package/dist/assets/components/avatar/avatar.internal.types.ts +1 -0
  19. package/dist/assets/components/avatar/avatar.stories.ts +1 -1
  20. package/dist/assets/components/avatar/avatar.types.ts +1 -1
  21. package/dist/assets/components/button/button.docs.mdx +4 -3
  22. package/dist/assets/components/button/button.stories.ts +1 -1
  23. package/dist/assets/components/button/button.types.ts +1 -1
  24. package/dist/assets/components/button/components/ai-button/ai-button.stories.ts +1 -1
  25. package/dist/assets/components/button/components/ai-button/ai-button.vue +1 -1
  26. package/dist/assets/components/button/components/button-actions/button-actions.docs.mdx +3 -0
  27. package/dist/assets/components/button/components/button-actions/button-actions.internal.types.ts +1 -0
  28. package/dist/assets/components/button/components/button-actions/button-actions.stories.ts +1 -1
  29. package/dist/assets/components/button/components/button-actions/button-actions.types.ts +1 -1
  30. package/dist/assets/components/button/components/button-actions/button-actions.vue +1 -1
  31. package/dist/assets/components/button/components/loading-button/loading-button.docs.mdx +26 -23
  32. package/dist/assets/components/button/components/loading-button/loading-button.stories.ts +1 -1
  33. package/dist/assets/components/button/components/loading-button/loading-button.vue +1 -1
  34. package/dist/assets/components/button/components/toggle-button/toggle-button.stories.ts +1 -1
  35. package/dist/assets/components/card/card.docs.mdx +18 -1
  36. package/dist/assets/components/card/card.stories.ts +1 -1
  37. package/dist/assets/components/card/card.types.ts +1 -1
  38. package/dist/assets/components/card/card.vue +1 -1
  39. package/dist/assets/components/checkbox/checkbox.stories.ts +1 -1
  40. package/dist/assets/components/checkbox/checkbox.types.ts +1 -1
  41. package/dist/assets/components/checkbox/checkbox.vue +1 -1
  42. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.docs.mdx +9 -14
  43. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.stories.ts +1 -1
  44. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.types.ts +1 -1
  45. package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.vue +1 -1
  46. package/dist/assets/components/chip/chip.stories.ts +1 -1
  47. package/dist/assets/components/chip/chip.vue +1 -1
  48. package/dist/assets/components/click-outside/click-outside.stories.ts +1 -1
  49. package/dist/assets/components/code-snippet/code-snippet.types.ts +1 -1
  50. package/dist/assets/components/code-snippet/code-snippet.vue +1 -1
  51. package/dist/assets/components/country/country.stories.ts +1 -1
  52. package/dist/assets/components/country/country.types.ts +1 -1
  53. package/dist/assets/components/country/country.vue +1 -1
  54. package/dist/assets/components/currency/currency.stories.ts +1 -1
  55. package/dist/assets/components/currency/currency.vue +1 -1
  56. package/dist/assets/components/dashed-underline/dashed-underline.stories.ts +1 -1
  57. package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.types.ts +1 -1
  58. package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.vue +1 -1
  59. package/dist/assets/components/data-grid/components/data-grid-config-settings/data-grid-config-settings.vue +1 -1
  60. package/dist/assets/components/data-grid/components/data-grid-row/data-grid-row.vue +1 -1
  61. package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.stories.ts +1 -1
  62. package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.stories.ts +1 -1
  63. package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.vue +1 -1
  64. package/dist/assets/components/data-grid/components/data-grid-tag-with-text-cell/data-grid-tag-with-text-cell.stories.ts +1 -1
  65. package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.stories.ts +1 -1
  66. package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.vue +1 -1
  67. package/dist/assets/components/data-grid/data-grid.docs.mdx +3 -60
  68. package/dist/assets/components/data-grid/data-grid.stories.ts +1 -1
  69. package/dist/assets/components/data-grid/data-grid.vue +1 -1
  70. package/dist/assets/components/date/date.stories.ts +1 -1
  71. package/dist/assets/components/date-picker/date-picker.stories.ts +1 -1
  72. package/dist/assets/components/date-picker/date-picker.types.ts +1 -1
  73. package/dist/assets/components/date-picker/date-picker.vue +1 -1
  74. package/dist/assets/components/date-range-picker/components/date-range-picker-calendar/date-range-picker-calendar.vue +1 -1
  75. package/dist/assets/components/date-range-picker/components/date-time-input/date-time-input.types.ts +1 -1
  76. package/dist/assets/components/date-range-picker/components/date-time-input/date-time-input.vue +1 -1
  77. package/dist/assets/components/date-range-picker/date-range-picker.docs.mdx +31 -6
  78. package/dist/assets/components/date-range-picker/date-range-picker.stories.ts +1 -1
  79. package/dist/assets/components/date-range-picker/date-range-picker.types.ts +1 -1
  80. package/dist/assets/components/date-range-picker/date-range-picker.vue +1 -1
  81. package/dist/assets/components/date-time-picker/date-time-picker.stories.ts +1 -1
  82. package/dist/assets/components/date-time-picker/date-time-picker.types.ts +1 -1
  83. package/dist/assets/components/divider/divider.internal.types.ts +1 -0
  84. package/dist/assets/components/divider/divider.stories.ts +1 -1
  85. package/dist/assets/components/divider/divider.types.ts +1 -1
  86. package/dist/assets/components/divider/divider.vue +1 -1
  87. package/dist/assets/components/draggable/components/draggable-handle/draggable-handle.stories.ts +1 -1
  88. package/dist/assets/components/draggable/draggable.stories.ts +1 -1
  89. package/dist/assets/components/draggable/draggable.vue +1 -1
  90. package/dist/assets/components/drawer/drawer.stories.ts +1 -1
  91. package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.internal.types.ts +1 -0
  92. package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.types.ts +1 -1
  93. package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.vue +1 -1
  94. package/dist/assets/components/dropdown/components/dropdown-default-textbox/dropdown-default-textbox.vue +1 -1
  95. package/dist/assets/components/dropdown/components/dropdown-options-container/dropdown-options-container.vue +1 -1
  96. package/dist/assets/components/dropdown/components/dropdown-small-textbox/dropdown-small-textbox.vue +1 -1
  97. package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.stories.ts +1 -1
  98. package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.types.ts +1 -1
  99. package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.vue +1 -1
  100. package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.stories.ts +1 -1
  101. package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.types.ts +1 -1
  102. package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.vue +1 -1
  103. package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.stories.ts +1 -1
  104. package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.types.ts +1 -1
  105. package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.vue +1 -1
  106. package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.stories.ts +1 -1
  107. package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.types.ts +1 -1
  108. package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.vue +1 -1
  109. package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.stories.ts +1 -1
  110. package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.types.ts +1 -1
  111. package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.vue +1 -1
  112. package/dist/assets/components/dropdown/dropdown.docs.mdx +4 -40
  113. package/dist/assets/components/dropdown/dropdown.internal.types.ts +1 -0
  114. package/dist/assets/components/dropdown/dropdown.stories.ts +1 -1
  115. package/dist/assets/components/dropdown/dropdown.types.ts +1 -1
  116. package/dist/assets/components/dropdown/dropdown.vue +1 -1
  117. package/dist/assets/components/empty-state/empty-state.stories.ts +1 -1
  118. package/dist/assets/components/empty-state/empty-state.types.ts +1 -1
  119. package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.stories.ts +1 -1
  120. package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.types.ts +1 -1
  121. package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.vue +1 -1
  122. package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.types.ts +1 -1
  123. package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.vue +1 -1
  124. package/dist/assets/components/file-uploader/file-uploader.internal.types.ts +1 -0
  125. package/dist/assets/components/file-uploader/file-uploader.stories.ts +1 -1
  126. package/dist/assets/components/file-uploader/file-uploader.types.ts +1 -1
  127. package/dist/assets/components/file-uploader/file-uploader.vue +1 -1
  128. package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.stories.ts +1 -1
  129. package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.types.ts +1 -1
  130. package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.vue +1 -1
  131. package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-filter-selection/all-filters-modal-filter-selection.types.ts +1 -0
  132. package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-filter-selection/all-filters-modal-filter-selection.vue +1 -0
  133. package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-selected-filter/all-filters-modal-selected-filter.vue +1 -0
  134. package/dist/assets/components/filter-bar/components/base-filter/base-filter.internal.types.ts +1 -0
  135. package/dist/assets/components/filter-bar/components/base-filter/base-filter.types.ts +1 -1
  136. package/dist/assets/components/filter-bar/components/base-filter/base-filter.vue +1 -1
  137. package/dist/assets/components/filter-bar/components/boolean-filter/boolean-filter.vue +1 -1
  138. package/dist/assets/components/filter-bar/components/date-filter/date-filter.vue +1 -1
  139. package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.vue +1 -1
  140. package/dist/assets/components/filter-bar/components/input-filter/input-filter.types.ts +1 -1
  141. package/dist/assets/components/filter-bar/components/input-filter/input-filter.vue +1 -1
  142. package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.stories.ts +1 -1
  143. package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.vue +1 -1
  144. package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-button/select-filter-button.vue +1 -1
  145. package/dist/assets/components/filter-bar/components/select-filter/select-filter.vue +1 -1
  146. package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.stories.ts +1 -1
  147. package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.stories.ts +1 -1
  148. package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.vue +1 -1
  149. package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.vue +1 -1
  150. package/dist/assets/components/filter-bar/filter-bar.docs.mdx +4 -62
  151. package/dist/assets/components/filter-bar/filter-bar.stories.ts +1 -1
  152. package/dist/assets/components/filter-bar/filter-bar.types.ts +1 -1
  153. package/dist/assets/components/filter-bar/filter-bar.vue +1 -1
  154. package/dist/assets/components/form-layout/form-layout.docs.mdx +0 -23
  155. package/dist/assets/components/form-layout/form-layout.stories.ts +1 -1
  156. package/dist/assets/components/header/header.stories.ts +1 -1
  157. package/dist/assets/components/header/header.types.ts +1 -1
  158. package/dist/assets/components/header/header.vue +1 -1
  159. package/dist/assets/components/header-with-views/components/header-with-views-all-views/header-with-views-all-views.vue +1 -1
  160. package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.types.ts +1 -1
  161. package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.vue +1 -1
  162. package/dist/assets/components/header-with-views/header-with-views.internal.types.ts +1 -0
  163. package/dist/assets/components/header-with-views/header-with-views.stories.ts +1 -1
  164. package/dist/assets/components/header-with-views/header-with-views.types.ts +1 -1
  165. package/dist/assets/components/header-with-views/header-with-views.vue +1 -1
  166. package/dist/assets/components/image/image.stories.ts +1 -1
  167. package/dist/assets/components/info-icon/info-icon.stories.ts +1 -1
  168. package/dist/assets/components/input-field/input-field.docs.mdx +1 -13
  169. package/dist/assets/components/input-field/input-field.stories.ts +1 -1
  170. package/dist/assets/components/input-field/input-field.types.ts +1 -1
  171. package/dist/assets/components/input-field/input-field.vue +1 -1
  172. package/dist/assets/components/input-field-password/input-field-password.internal.types.ts +1 -0
  173. package/dist/assets/components/input-field-password/input-field-password.stories.ts +1 -1
  174. package/dist/assets/components/input-field-password/input-field-password.types.ts +1 -1
  175. package/dist/assets/components/input-field-password/input-field-password.vue +1 -1
  176. package/dist/assets/components/input-field-phone-number/input-field-phone-number.stories.ts +1 -1
  177. package/dist/assets/components/input-field-phone-number/input-field-phone-number.types.ts +1 -1
  178. package/dist/assets/components/input-field-phone-number/input-field-phone-number.vue +1 -1
  179. package/dist/assets/components/input-time/input-time.docs.mdx +17 -0
  180. package/dist/assets/components/input-time/input-time.stories.ts +1 -1
  181. package/dist/assets/components/input-time/input-time.types.ts +1 -1
  182. package/dist/assets/components/input-time/input-time.vue +1 -1
  183. package/dist/assets/components/inspector/inspector.stories.ts +1 -1
  184. package/dist/assets/components/inspector/inspector.vue +1 -1
  185. package/dist/assets/components/layout/components/layout-row/layout-row.stories.ts +1 -1
  186. package/dist/assets/components/layout/components/layout-row/layout-row.vue +1 -1
  187. package/dist/assets/components/layout/layout.docs.mdx +10 -0
  188. package/dist/assets/components/layout/layout.internal.types.ts +1 -0
  189. package/dist/assets/components/layout/layout.stories.ts +1 -1
  190. package/dist/assets/components/layout/layout.types.ts +1 -1
  191. package/dist/assets/components/link/link.stories.ts +1 -1
  192. package/dist/assets/components/link/link.types.ts +1 -1
  193. package/dist/assets/components/link/link.vue +1 -1
  194. package/dist/assets/components/list/list.stories.ts +1 -1
  195. package/dist/assets/components/loading-indicator/loading-indicator.stories.ts +1 -1
  196. package/dist/assets/components/menu/components/menu-item/menu-item.types.ts +1 -1
  197. package/dist/assets/components/menu/components/menu-item/menu-item.vue +1 -1
  198. package/dist/assets/components/menu/components/menu-item-list/menu-item-list.vue +1 -1
  199. package/dist/assets/components/menu/components/sub-menu-item-list/sub-menu-item-list.vue +1 -1
  200. package/dist/assets/components/menu/menu.docs.mdx +17 -7
  201. package/dist/assets/components/menu/menu.stories.ts +1 -1
  202. package/dist/assets/components/menu/menu.types.ts +1 -1
  203. package/dist/assets/components/menu/menu.vue +1 -1
  204. package/dist/assets/components/modal/components/base-modal/base-modal.vue +1 -1
  205. package/dist/assets/components/modal/components/modal-page/modal-page.vue +1 -1
  206. package/dist/assets/components/modal/modal.internal.types.ts +1 -0
  207. package/dist/assets/components/modal/modal.stories.ts +1 -1
  208. package/dist/assets/components/modal/modal.types.ts +1 -1
  209. package/dist/assets/components/modal/modal.vue +1 -1
  210. package/dist/assets/components/modal-fullscreen/components/modal-fullscreen-page.vue +1 -1
  211. package/dist/assets/components/modal-fullscreen/modal-fullscreen.stories.ts +1 -1
  212. package/dist/assets/components/modal-fullscreen/modal-fullscreen.vue +1 -1
  213. package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.internal.types.ts +1 -0
  214. package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.types.ts +1 -1
  215. package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.vue +1 -1
  216. package/dist/assets/components/navigation-menu/components/navigation-menu-item/navigation-menu-item.vue +1 -1
  217. package/dist/assets/components/navigation-menu/navigation-menu.internal.types.ts +1 -0
  218. package/dist/assets/components/navigation-menu/navigation-menu.stories.ts +1 -1
  219. package/dist/assets/components/navigation-menu/navigation-menu.types.ts +1 -1
  220. package/dist/assets/components/navigation-menu/navigation-menu.vue +1 -1
  221. package/dist/assets/components/pagination/components/pagination-context/pagination-context.vue +1 -1
  222. package/dist/assets/components/pagination/components/pagination-results-per-page/pagination-results-per-page.vue +1 -1
  223. package/dist/assets/components/pagination/pagination.stories.ts +1 -1
  224. package/dist/assets/components/pagination/pagination.types.ts +1 -1
  225. package/dist/assets/components/pagination/pagination.vue +1 -1
  226. package/dist/assets/components/payment-method/payment-method.stories.ts +1 -1
  227. package/dist/assets/components/payment-method/payment-method.types.ts +1 -1
  228. package/dist/assets/components/popover/popover.docs.mdx +32 -9
  229. package/dist/assets/components/popover/popover.stories.ts +1 -1
  230. package/dist/assets/components/popover/popover.types.ts +1 -1
  231. package/dist/assets/components/popover/popover.vue +1 -1
  232. package/dist/assets/components/popper-container/popper-container.types.ts +1 -1
  233. package/dist/assets/components/popper-container/popper-container.vue +1 -1
  234. package/dist/assets/components/progress-bar/progress-bar.docs.mdx +102 -0
  235. package/dist/assets/components/progress-bar/progress-bar.stories.ts +1 -0
  236. package/dist/assets/components/progress-bar/progress-bar.types.ts +1 -0
  237. package/dist/assets/components/progress-bar/progress-bar.vue +1 -0
  238. package/dist/assets/components/promo-banner/promo-banner.stories.ts +1 -1
  239. package/dist/assets/components/promo-banner/promo-banner.types.ts +1 -1
  240. package/dist/assets/components/promo-banner/promo-banner.vue +1 -1
  241. package/dist/assets/components/radio-group/components/radio-button/radio-button.vue +1 -1
  242. package/dist/assets/components/radio-group/radio-group.docs.mdx +1 -6
  243. package/dist/assets/components/radio-group/radio-group.stories.ts +1 -1
  244. package/dist/assets/components/radio-group/radio-group.types.ts +1 -1
  245. package/dist/assets/components/radio-group/radio-group.vue +1 -1
  246. package/dist/assets/components/rich-text-editor/rich-text-editor.internal.types.ts +1 -0
  247. package/dist/assets/components/rich-text-editor/rich-text-editor.stories.ts +1 -1
  248. package/dist/assets/components/rich-text-editor/rich-text-editor.types.ts +1 -1
  249. package/dist/assets/components/rich-text-editor/rich-text-editor.vue +1 -1
  250. package/dist/assets/components/search-bar/search-bar.stories.ts +1 -1
  251. package/dist/assets/components/search-bar/search-bar.vue +1 -1
  252. package/dist/assets/components/secondary-nav/components/secondary-nav-item/secondary-nav-item.vue +1 -1
  253. package/dist/assets/components/secondary-nav/secondary-nav.stories.ts +1 -1
  254. package/dist/assets/components/secondary-nav/secondary-nav.vue +1 -1
  255. package/dist/assets/components/segmented-control/components/segmented-control-button/segmented-control-button.vue +1 -1
  256. package/dist/assets/components/segmented-control/segmented-control.stories.ts +1 -1
  257. package/dist/assets/components/segmented-control/segmented-control.types.ts +1 -1
  258. package/dist/assets/components/segmented-control/segmented-control.vue +1 -1
  259. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.docs.mdx +12 -13
  260. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.stories.ts +1 -1
  261. package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.vue +1 -1
  262. package/dist/assets/components/selection-card/selection-card.stories.ts +1 -1
  263. package/dist/assets/components/selection-card/selection-card.types.ts +1 -1
  264. package/dist/assets/components/selection-card/selection-card.vue +1 -1
  265. package/dist/assets/components/sidepanel/sidepanel.docs.mdx +1 -1
  266. package/dist/assets/components/sidepanel/sidepanel.stories.ts +1 -1
  267. package/dist/assets/components/sidepanel/sidepanel.vue +1 -1
  268. package/dist/assets/components/status/status.stories.ts +1 -1
  269. package/dist/assets/components/status/status.types.ts +1 -1
  270. package/dist/assets/components/stepper/components/step/step.vue +1 -1
  271. package/dist/assets/components/stepper/stepper.stories.ts +1 -1
  272. package/dist/assets/components/stepper/stepper.vue +1 -1
  273. package/dist/assets/components/structured-list/structured-list.stories.ts +1 -1
  274. package/dist/assets/components/structured-list/structured-list.vue +1 -1
  275. package/dist/assets/components/summary-grid/components/summary-grid-item/summary-grid-item.types.ts +1 -1
  276. package/dist/assets/components/summary-grid/summary-grid.stories.ts +1 -1
  277. package/dist/assets/components/summary-grid/summary-grid.types.ts +1 -1
  278. package/dist/assets/components/table-of-contents/components/table-of-contents-list/table-of-contents-list.vue +1 -1
  279. package/dist/assets/components/table-of-contents/table-of-contents.internal.types.ts +1 -0
  280. package/dist/assets/components/table-of-contents/table-of-contents.stories.ts +1 -1
  281. package/dist/assets/components/table-of-contents/table-of-contents.types.ts +1 -1
  282. package/dist/assets/components/table-of-contents/table-of-contents.vue +1 -1
  283. package/dist/assets/components/tabs/components/tab.internal.types.ts +1 -0
  284. package/dist/assets/components/tabs/components/tab.types.ts +1 -1
  285. package/dist/assets/components/tabs/components/tab.vue +1 -1
  286. package/dist/assets/components/tabs/tabs.stories.ts +1 -1
  287. package/dist/assets/components/tabs/tabs.vue +1 -1
  288. package/dist/assets/components/tag/tag.docs.mdx +1 -1
  289. package/dist/assets/components/tag/tag.stories.ts +1 -1
  290. package/dist/assets/components/tag/tag.types.ts +1 -1
  291. package/dist/assets/components/tag/tag.vue +1 -1
  292. package/dist/assets/components/textarea/textarea.docs.mdx +0 -7
  293. package/dist/assets/components/textarea/textarea.stories.ts +1 -1
  294. package/dist/assets/components/textarea/textarea.types.ts +1 -1
  295. package/dist/assets/components/textarea/textarea.vue +1 -1
  296. package/dist/assets/components/timeline/components/timeline-item/timeline-item.stories.ts +1 -1
  297. package/dist/assets/components/timeline/components/timeline-item/timeline-item.vue +1 -1
  298. package/dist/assets/components/timeline/timeline.docs.mdx +0 -10
  299. package/dist/assets/components/timeline/timeline.internal.types.ts +1 -0
  300. package/dist/assets/components/timeline/timeline.stories.ts +1 -1
  301. package/dist/assets/components/timeline/timeline.types.ts +1 -1
  302. package/dist/assets/components/timeline/timeline.vue +1 -1
  303. package/dist/assets/components/toast/components/toast-item/toast-item.vue +1 -1
  304. package/dist/assets/components/toggle/toggle.stories.ts +1 -1
  305. package/dist/assets/components/toggle/toggle.types.ts +1 -1
  306. package/dist/assets/components/toggle/toggle.vue +1 -1
  307. package/dist/assets/components/tutorial/tutorial.stories.ts +1 -1
  308. package/dist/assets/components/typography/typography.stories.ts +1 -1
  309. package/dist/assets/components/typography/typography.types.ts +1 -1
  310. package/dist/assets/components/typography/typography.vue +1 -1
  311. package/dist/assets/components.json +1 -0
  312. package/dist/assets/composables/use-bento-base-filter/index.ts +1 -0
  313. package/dist/assets/composables/use-bento-base-filter/use-bento-base-filter.ts +1 -0
  314. package/dist/assets/composables/use-bento-base-filter/utils/index.ts +1 -0
  315. package/dist/assets/composables/use-bento-base-filter/utils/utils.ts +1 -0
  316. package/dist/assets/composables/use-bento-currency/index.ts +1 -0
  317. package/dist/assets/composables/use-bento-currency/use-bento-currency.stories.ts +1 -1
  318. package/dist/assets/composables/use-bento-currency/use-bento-currency.ts +1 -0
  319. package/dist/assets/composables/use-bento-delayed-hover/index.ts +1 -0
  320. package/dist/assets/composables/use-bento-delayed-hover/use-bento-delayed-hover.stories.ts +1 -1
  321. package/dist/assets/composables/use-bento-delayed-hover/use-bento-delayed-hover.ts +1 -0
  322. package/dist/assets/composables/use-bento-theme/index.ts +1 -0
  323. package/dist/assets/composables/use-bento-theme/install.ts +1 -1
  324. package/dist/assets/composables/use-bento-theme/install.types.ts +1 -1
  325. package/dist/assets/composables/use-bento-theme/use-bento-theme.ts +1 -0
  326. package/dist/assets/composables/use-bento-toast-controller/index.ts +1 -0
  327. package/dist/assets/composables/use-bento-toast-controller/toast-stack.ts +1 -0
  328. package/dist/assets/composables/use-bento-toast-controller/use-bento-toast-controller.ts +1 -0
  329. package/dist/assets/composables/use-click-outside/index.ts +1 -0
  330. package/dist/assets/composables/use-click-outside/use-click-outside.stories.ts +1 -1
  331. package/dist/assets/composables/use-click-outside/use-click-outside.ts +1 -0
  332. package/dist/assets/composables/use-form-validate/index.ts +1 -0
  333. package/dist/assets/composables/use-form-validate/use-form.ts +1 -0
  334. package/dist/assets/composables/use-form-validate/use-form.types.ts +1 -1
  335. package/dist/assets/composables.json +9 -0
  336. package/dist/assets/deprecations.md +139 -243
  337. package/dist/assets/directives/highlight/highlight.stories.ts +1 -1
  338. package/dist/assets/directives/keyboard-navigation/keyboard-navigation.stories.ts +1 -1
  339. package/dist/assets/directives/tooltip/tooltip.internal.types.ts +1 -0
  340. package/dist/assets/directives/tooltip/tooltip.stories.ts +1 -1
  341. package/dist/assets/directives/tooltip/tooltip.types.ts +1 -1
  342. package/dist/assets/icons.json +1 -0
  343. package/dist/assets/index.ts +1 -1
  344. package/dist/assets/install.ts +1 -1
  345. package/dist/assets/tailwind/README.md +3 -3
  346. package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.stories.ts +1 -1
  347. package/dist/assets/templates/dashboard-template/dashboard-template.stories.ts +1 -1
  348. package/dist/assets/templates/data-grid-template/data-grid-template.stories.ts +1 -1
  349. package/dist/assets/usage.json +81 -80
  350. package/dist/assets/variables.css +152 -140
  351. package/dist/main.js +228 -34
  352. package/package.json +2 -2
  353. package/dist/assets/components/internal/base-button/base-button.types.ts +0 -1
  354. package/dist/assets/components/internal/base-button/base-button.vue +0 -1
  355. package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.stories.ts +0 -1
  356. package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.types.ts +0 -1
  357. package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.vue +0 -1
  358. package/dist/assets/components/internal/calendar/calendar.stories.ts +0 -1
  359. package/dist/assets/components/internal/calendar/calendar.types.ts +0 -1
  360. package/dist/assets/components/internal/calendar/calendar.vue +0 -1
  361. package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.stories.ts +0 -1
  362. package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.types.ts +0 -1
  363. package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.vue +0 -1
  364. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/__test__/calendar-month-day-stub.vue +0 -1
  365. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.stories.ts +0 -1
  366. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.types.ts +0 -1
  367. package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.vue +0 -1
  368. package/dist/assets/components/internal/calendar/components/calendar-month/composables/granular-min-max-date.types.ts +0 -1
  369. package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.types.ts +0 -1
  370. package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.vue +0 -1
  371. package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/__test__/calendar-year-month-stub.vue +0 -1
  372. package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.types.ts +0 -1
  373. package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.vue +0 -1
  374. package/dist/assets/components/internal/calendar/components/calendar-year-selector/calendar-year-selector.types.ts +0 -1
  375. package/dist/assets/components/internal/calendar/components/calendar-year-selector/calendar-year-selector.vue +0 -1
  376. package/dist/assets/components/internal/calendar/composables/use-granularity-adjustments.types.ts +0 -1
  377. package/dist/assets/components/internal/calendar/composables/use-range-pane.types.ts +0 -1
  378. package/dist/assets/components/internal/checkbox-input/checkbox-input.stories.ts +0 -1
  379. package/dist/assets/components/internal/checkbox-input/checkbox-input.types.ts +0 -1
  380. package/dist/assets/components/internal/checkbox-input/checkbox-input.vue +0 -1
  381. package/dist/assets/components/internal/controls-group/controls-group.vue +0 -1
  382. package/dist/assets/components/internal/copy/copy.docs.mdx +0 -43
  383. package/dist/assets/components/internal/copy/copy.stories.ts +0 -1
  384. package/dist/assets/components/internal/copy/copy.types.ts +0 -1
  385. package/dist/assets/components/internal/copy/copy.vue +0 -1
  386. package/dist/assets/components/internal/decorative-checkbox/decorative-checkbox.vue +0 -1
  387. package/dist/assets/components/internal/dialog-page/dialog-page.types.ts +0 -1
  388. package/dist/assets/components/internal/dialog-page/dialog-page.vue +0 -1
  389. package/dist/assets/components/internal/error-message/error-message.vue +0 -1
  390. package/dist/assets/components/internal/field-label/field-label.vue +0 -1
  391. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.docs.mdx +0 -21
  392. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.stories.ts +0 -1
  393. package/dist/assets/components/internal/fixed-scroller/fixed-scroller.vue +0 -1
  394. package/dist/assets/components/internal/footer-actions/footer-actions.vue +0 -1
  395. package/dist/assets/components/internal/grid-layout/grid-layout.types.ts +0 -1
  396. package/dist/assets/components/internal/grid-layout/grid-layout.vue +0 -1
  397. package/dist/assets/components/internal/header-meta/header-meta.types.ts +0 -1
  398. package/dist/assets/components/internal/header-meta/header-meta.vue +0 -1
  399. package/dist/assets/components/internal/info-icon-with-popover/info-icon-with-popover.vue +0 -1
  400. package/dist/assets/components/internal/listbox/components/listbox-lazy-load/listbox-lazy-load.types.ts +0 -1
  401. package/dist/assets/components/internal/listbox/components/listbox-lazy-load/listbox-lazy-load.vue +0 -1
  402. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-category/listbox-multi-select-category.types.ts +0 -1
  403. 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 +0 -1
  404. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-nested-lazy-load/listbox-multi-select-nested-lazy-load.types.ts +0 -1
  405. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-nested-lazy-load/listbox-multi-select-nested-lazy-load.vue +0 -1
  406. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.types.ts +0 -1
  407. package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.vue +0 -1
  408. package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.types.ts +0 -1
  409. package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.vue +0 -1
  410. package/dist/assets/components/internal/listbox/components/listbox-option/listbox-option.vue +0 -1
  411. package/dist/assets/components/internal/listbox/components/listbox-option-tag/listbox-option-tag.vue +0 -1
  412. package/dist/assets/components/internal/listbox/components/listbox-single-select/components/listbox-single-select-category/listbox-single-select-category.vue +0 -1
  413. package/dist/assets/components/internal/listbox/components/listbox-single-select/listbox-single-select.vue +0 -1
  414. package/dist/assets/components/internal/listbox/components/listbox-single-select-option/listbox-single-select-option.vue +0 -1
  415. package/dist/assets/components/internal/listbox/listbox.stories.ts +0 -1
  416. package/dist/assets/components/internal/listbox/listbox.types.ts +0 -1
  417. package/dist/assets/components/internal/listbox/listbox.vue +0 -1
  418. package/dist/assets/components/internal/radio-input/radio-input.stories.ts +0 -1
  419. package/dist/assets/components/internal/radio-input/radio-input.types.ts +0 -1
  420. package/dist/assets/components/internal/radio-input/radio-input.vue +0 -1
  421. package/dist/assets/components/internal/teleport/teleport.types.ts +0 -1
  422. package/dist/assets/components/internal/teleport/teleport.vue +0 -1
  423. package/dist/assets/components/internal/tooltip/tooltip.test.vue +0 -1
  424. package/dist/assets/components/internal/tooltip/tooltip.types.ts +0 -1
  425. package/dist/assets/components/internal/tooltip/tooltip.vue +0 -1
  426. package/dist/assets/composables/use-form-validate-zod-4/use-form.types.ts +0 -1
  427. package/dist/assets/composables/use-numeric-input/use-numeric-input.types.ts +0 -1
  428. package/dist/assets/composables/use-section-navigation-keyboard/use-section-navigation-keyboard.types.ts +0 -1
  429. package/dist/assets/composables/use-virtual-list/use-virtual-list.types.ts +0 -1
@@ -21,16 +21,6 @@ separate components.
21
21
 
22
22
  ## Variations
23
23
 
24
- ### Variant (deprecated)
25
-
26
- > ⚠️ **Deprecation Notice**: Timeline item variants are deprecated and will be removed in release **2.0.0**. Use
27
- > [`status` modifier](#status) instead.
28
-
29
- There are three variants for the Timeline items: `Default`, `Success` and `Critical`.
30
-
31
- Use `Success` and `Critical` item variants sparingly - only when it's necessary to grab user's attention, for example,
32
- when the timeline is used for troubleshooting. Otherwise stick to the default styling.
33
-
34
24
  ### Links
35
25
 
36
26
  It’s possible to add links to either title or description of a timeline item. To make the timeline item title render as
@@ -0,0 +1 @@
1
+ import { type Ref } from 'vue'; import { type BentoTimelineEntry, type BentoTimelineItemTitle } from './timeline.types'; /** * @deprecated Since v3.0.0. Do not use. */ export type BentoTimelineRegisterEntry = (props: { title?: string | BentoTimelineItemTitle; description?: string; date: Date | number; }) => { timelineEntries: Ref<Array<BentoTimelineEntry>>; index: number; unregisterTimelineEntry: () => void }; export type BentoInternalTimelineRegisterEntry = ( entry: BentoTimelineEntry ) => { timelineEntries: Ref<Array<BentoTimelineEntry>>; unregisterTimelineEntry: () => void };
@@ -1 +1 @@
1
- import type { Meta, StoryObj } from '@storybook/vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { onMounted, ref } from 'vue'; import { isVue2 } from 'vue-demi'; import BentoTimeline from './timeline.vue'; import BentoTimelineItem from './components/timeline-item/timeline-item.vue'; import { BentoTimelineGapUnit, BentoTimelineShowMorePlacement } from './timeline.types'; import TimelineDynamicAddition from './__tests__/timeline-dynamic-add-stub.vue?raw'; import TimelineDefaultExample from './__tests__/timeline-default-example.vue?raw'; import { BentoDateFormat } from '@/components/date/date.types'; import BentoLink from '@/components/link/link.vue'; import BentoButton from '@/components/button/button.vue'; const meta: Meta = { title: 'Timeline', component: BentoTimeline, argTypes: { // Slots default: { name: 'default', type: { name: 'string', required: false }, description: 'BentoTimelineItem components', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, }, }; export default meta; type Story = StoryObj<typeof BentoTimeline>; const DEFAULT_PROPS = { timegapLimit: { unit: BentoTimelineGapUnit.DAY, amount: 15 }, showMore: { limit: 3, placement: BentoTimelineShowMorePlacement.AFTER_FIRST }, }; const DEFAULT_ITEM_PROPS = { timestamp: { date: new Date(), value: 'AuthorName', format: BentoDateFormat.FULL_DATE_EXACT_TIME_WITHOUT_PERIOD, }, dataList: [ { label: 'Label', value: 'Value' }, { label: 'Label', value: 'Value' }, ], description: 'Space to put some description about this milestone', }; const { description: _, ...DEFAULT_PROPS_WITHOUT_DESCRIPTION } = DEFAULT_ITEM_PROPS; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone5" /> <bento-timeline-item v-bind="milestone4" /> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2" /> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone5 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 5', status: 'green', }; const milestone4 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 4', timestamp: { date: new Date().setDate(-2), value: 'AuthorName', }, }; const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 3', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'red', }; const milestone2 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'BookingDate', description: { popoverText: 'date of booking', }, }, additionalTimestamp: { date: new Date().setDate(-15), value: 'ValueDate', description: { tooltipText: 'date of value', }, }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, milestone4, milestone5, }; }, }), args: { ...DEFAULT_PROPS, }, parameters: storybookDocsParameter(TimelineDefaultExample), }; export const WithLinks: Story = { render: (_args, { argTypes }) => ({ components: { BentoLink, BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2"> A description with <bento-link to="/">a link</bento-link> </bento-timeline-item> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: { title: 'Milestone 3', to: '/', }, timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'green', }; const milestone2 = { ...DEFAULT_PROPS_WITHOUT_DESCRIPTION, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-15), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, }; }, }), args: { ...DEFAULT_PROPS, }, }; const withNotesCode = ` <template> <bento-timeline v-bind="args" @add-timeline-note="addNote"> <bento-timeline-item v-for="item in timelineItems" v-bind="item" /> </bento-timeline> </template> <script setup> const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const timelineItems = ref(); onMounted(() => { timelineItems.value = [milestone3, milestone2, milestone1]; }); const addNote = e => { timelineItems.value.unshift(e); }; return { args: isVue2 ? props : _args, timelineItems, addNote, }; </script> `; export const WithNotes: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2" /> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, }; }, }), args: { ...DEFAULT_PROPS, showMore: null, }, parameters: storybookDocsParameter(withNotesCode), }; const addNoteCode = ` <template> <bento-timeline v-bind="args" add-note @add-timeline-note="addNote"> <bento-timeline-item v-for="item in timelineItems" v-bind="item" /> </bento-timeline> </template> <script setup> const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const timelineItems = ref(); onMounted(() => { timelineItems.value = [milestone3, milestone2, milestone1]; }); const addNote = e => { timelineItems.value.unshift(e); }; return { timelineItems, addNote, }; </script> `; export const AddNote: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args" add-note @add-timeline-note="addNote"> <bento-timeline-item v-for="item in timelineItems" v-bind="item" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const timelineItems = ref(); onMounted(() => { timelineItems.value = [milestone3, milestone2, milestone1]; }); const addNote = e => { const newNote = { ...e, timestamp: { ...e.timestamp, value: 'AuthorName' } }; timelineItems.value.unshift(newNote); }; return { args: isVue2 ? props : _args, timelineItems, addNote, }; }, }), args: { ...DEFAULT_PROPS, showMore: null, addNotes: true, }, parameters: storybookDocsParameter(addNoteCode), }; export const DynamicItemAddition: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <div style="display: flex; flex-direction: row; align-items: flex-start; gap: 16px;"> <bento-button @click="addItem">Add timeline item</bento-button> <bento-timeline v-if="timelineEntries"> <bento-timeline-item v-for="entry in timelineEntries" :key="entry.title" v-bind="entry" /> </bento-timeline> </div> `, setup(props) { const timelineEntries = ref([]); let index = 0; const addItem = () => { if (index < 5) { timelineEntries.value.unshift(milestones[index]); index++; } }; const milestone5 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 5', status: 'green', }; const milestone4 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 4', timestamp: { date: new Date().setDate(-2), value: 'AuthorName', }, }; const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 3', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'red', }; const milestone2 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-15), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const milestones = [milestone1, milestone2, milestone3, milestone4, milestone5]; return { args: isVue2 ? props : _args, timelineEntries, addItem, }; }, }), args: { ...DEFAULT_PROPS, }, parameters: storybookDocsParameter(TimelineDynamicAddition), };
1
+ import type { Meta, StoryObj } from '@storybook/vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { onMounted, ref } from 'vue'; import { isVue2 } from 'vue-demi'; import BentoTimeline from './timeline.vue'; import BentoTimelineItem from './components/timeline-item/timeline-item.vue'; import { BentoTimelineGapUnit, BentoTimelineShowMorePlacement } from './timeline.types'; const TimelineAddNoteExample = "<template>\n <bento-timeline add-note :timegap-limit=\"timegapLimit\" @add-timeline-note=\"addNote\">\n <bento-timeline-item v-for=\"item in timelineItems\" :key=\"item.timestamp.date.valueOf()\" v-bind=\"item\" />\n </bento-timeline>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import {\n BentoTimeline,\n BentoTimelineGapUnit,\n BentoTimelineItem,\n type BentoTimelineItemProps,\n } from '@adyen/bento-vue2';\n\n const timegapLimit = { unit: BentoTimelineGapUnit.DAY, amount: 15 };\n const defaultItemProps = {\n timestamp: {\n date: new Date('2024-03-15T10:00:00Z'),\n value: 'AuthorName',\n },\n dataList: [\n { label: 'Label', value: 'Value' },\n { label: 'Label', value: 'Value' },\n ],\n description: 'Space to put some description about this milestone',\n };\n\n const timelineItems = ref<Array<BentoTimelineItemProps>>([\n {\n ...defaultItemProps,\n title: 'Milestone 2',\n timestamp: {\n date: new Date('2024-03-11T10:00:00Z'),\n value: 'AuthorName',\n },\n additionalTimestamp: {\n date: new Date('2024-03-10T10:00:00Z'),\n value: 'AuthorName',\n },\n },\n {\n type: 'note',\n description:\n 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',\n timestamp: {\n date: new Date('2024-03-01T10:00:00Z'),\n value: 'AuthorName',\n },\n },\n {\n ...defaultItemProps,\n title: 'Milestone 1',\n timestamp: {\n date: new Date('2023-10-17T10:00:00Z'),\n value: 'AuthorName',\n },\n tag: {\n label: 'Tag1',\n },\n },\n ]);\n\n const addNote = (note: BentoTimelineItemProps) => {\n timelineItems.value.unshift({\n ...note,\n timestamp: {\n ...note.timestamp,\n date: new Date('2024-03-16T10:00:00Z'),\n value: 'AuthorName',\n },\n });\n };\n</script>\n"; const TimelineDynamicAddition = "<template>\n <div>\n <bento-timeline>\n <bento-timeline-item v-for=\"event in timelineEntries\" :key=\"event.title\" v-bind=\"event\" />\n </bento-timeline>\n <bento-button @click=\"addEntry\">Add timeline item</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import BentoTimeline from '../timeline.vue';\n import BentoTimelineItem from '../components/timeline-item/timeline-item.vue';\n import { BentoButton } from '@/components/button';\n\n const timelineEntries = ref([]);\n const milestones = [\n { title: 'Milestone 1', timestamp: { date: new Date(2023, 0, 1) } },\n { title: 'Milestone 2', timestamp: { date: new Date(2023, 1, 1) } },\n { title: 'Milestone 3', timestamp: { date: new Date(2023, 2, 1) } },\n ];\n let milestoneIndex = 0;\n\n const addEntry = () => {\n if (milestoneIndex < milestones.length) {\n timelineEntries.value.unshift(milestones[milestoneIndex]);\n milestoneIndex++;\n }\n };\n</script>\n"; const TimelineDefaultExample = "<template>\n <bento-timeline v-bind=\"timelineProps\">\n <bento-timeline-item v-bind=\"milestone5\" />\n <bento-timeline-item v-bind=\"milestone4\" />\n <bento-timeline-item v-bind=\"milestone3\" />\n <bento-timeline-item v-bind=\"milestone2\" />\n <bento-timeline-item v-bind=\"milestone1\" />\n </bento-timeline>\n</template>\n\n<script lang=\"ts\" setup>\n import {\n BentoTimeline,\n BentoTimelineGapUnit,\n BentoTimelineItem,\n BentoTimelineShowMorePlacement,\n } from '@adyen/bento-vue2';\n\n const timelineProps = {\n timegapLimit: { unit: BentoTimelineGapUnit.DAY, amount: 15 },\n showMore: { limit: 3, placement: BentoTimelineShowMorePlacement.AFTER_FIRST },\n };\n\n const DEFAULT_ITEM_PROPS = {\n timestamp: {\n date: new Date('2024-03-15T10:00:00Z'),\n value: 'AuthorName',\n },\n dataList: [\n { label: 'Label', value: 'Value' },\n { label: 'Label', value: 'Value' },\n ],\n description: 'Space to put some description about this milestone',\n };\n\n const milestone5 = {\n ...DEFAULT_ITEM_PROPS,\n title: 'Milestone 5',\n status: 'green',\n };\n\n const milestone4 = {\n ...DEFAULT_ITEM_PROPS,\n title: 'Milestone 4',\n timestamp: {\n ...DEFAULT_ITEM_PROPS.timestamp,\n date: new Date('2024-03-13T10:00:00Z'),\n value: 'AuthorName',\n },\n };\n\n const milestone3 = {\n ...DEFAULT_ITEM_PROPS,\n title: 'Milestone 3',\n timestamp: {\n ...DEFAULT_ITEM_PROPS.timestamp,\n date: new Date('2024-03-11T10:00:00Z'),\n value: 'AuthorName',\n },\n status: 'red',\n };\n\n const milestone2 = {\n ...DEFAULT_ITEM_PROPS,\n title: 'Milestone 2',\n timestamp: {\n ...DEFAULT_ITEM_PROPS.timestamp,\n date: new Date('2024-03-01T10:00:00Z'),\n value: 'BookingDate',\n description: {\n popoverText: 'date of booking',\n },\n },\n additionalTimestamp: {\n date: new Date('2024-02-29T10:00:00Z'),\n value: 'ValueDate',\n description: {\n tooltipText: 'date of value',\n },\n },\n };\n\n const milestone1 = {\n ...DEFAULT_ITEM_PROPS,\n title: 'Milestone 1',\n timestamp: {\n ...DEFAULT_ITEM_PROPS.timestamp,\n date: new Date('2023-10-17T10:00:00Z'),\n value: 'AuthorName',\n },\n tag: {\n label: 'Tag1',\n },\n };\n</script>\n"; const TimelineWithNotesExample = "<template>\n <bento-timeline :timegap-limit=\"timegapLimit\">\n <bento-timeline-item v-for=\"item in timelineItems\" :key=\"item.timestamp.date.valueOf()\" v-bind=\"item\" />\n </bento-timeline>\n</template>\n\n<script setup lang=\"ts\">\n import {\n BentoTimeline,\n BentoTimelineGapUnit,\n BentoTimelineItem,\n type BentoTimelineItemProps,\n } from '@adyen/bento-vue2';\n\n const timegapLimit = { unit: BentoTimelineGapUnit.DAY, amount: 15 };\n const defaultItemProps = {\n timestamp: {\n date: new Date('2024-03-15T10:00:00Z'),\n value: 'AuthorName',\n },\n dataList: [\n { label: 'Label', value: 'Value' },\n { label: 'Label', value: 'Value' },\n ],\n description: 'Space to put some description about this milestone',\n };\n\n const timelineItems: Array<BentoTimelineItemProps> = [\n {\n ...defaultItemProps,\n title: 'Milestone 2',\n timestamp: {\n date: new Date('2024-03-11T10:00:00Z'),\n value: 'AuthorName',\n },\n additionalTimestamp: {\n date: new Date('2024-03-10T10:00:00Z'),\n value: 'AuthorName',\n },\n },\n {\n type: 'note',\n description:\n 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',\n timestamp: {\n date: new Date('2024-03-01T10:00:00Z'),\n value: 'AuthorName',\n },\n },\n {\n ...defaultItemProps,\n title: 'Milestone 1',\n timestamp: {\n date: new Date('2023-10-17T10:00:00Z'),\n value: 'AuthorName',\n },\n tag: {\n label: 'Tag1',\n },\n },\n ];\n</script>\n"; import { BentoDateFormat } from '@/components/date/date.types'; import BentoLink from '@/components/link/link.vue'; import BentoButton from '@/components/button/button.vue'; const meta: Meta = { title: 'Timeline', component: BentoTimeline, argTypes: { // Slots default: { name: 'default', type: { name: 'string', required: false }, description: 'BentoTimelineItem components', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, }, }; export default meta; type Story = StoryObj<typeof BentoTimeline>; const DEFAULT_PROPS = { timegapLimit: { unit: BentoTimelineGapUnit.DAY, amount: 15 }, showMore: { limit: 3, placement: BentoTimelineShowMorePlacement.AFTER_FIRST }, }; const DEFAULT_ITEM_PROPS = { timestamp: { date: new Date(), value: 'AuthorName', format: BentoDateFormat.FULL_DATE_EXACT_TIME_WITHOUT_PERIOD, }, dataList: [ { label: 'Label', value: 'Value' }, { label: 'Label', value: 'Value' }, ], description: 'Space to put some description about this milestone', }; const { description: _, ...DEFAULT_PROPS_WITHOUT_DESCRIPTION } = DEFAULT_ITEM_PROPS; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone5" /> <bento-timeline-item v-bind="milestone4" /> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2" /> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone5 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 5', status: 'green', }; const milestone4 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 4', timestamp: { date: new Date().setDate(-2), value: 'AuthorName', }, }; const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 3', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'red', }; const milestone2 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'BookingDate', description: { popoverText: 'date of booking', }, }, additionalTimestamp: { date: new Date().setDate(-15), value: 'ValueDate', description: { tooltipText: 'date of value', }, }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, milestone4, milestone5, }; }, }), args: { ...DEFAULT_PROPS, }, parameters: storybookDocsParameter(TimelineDefaultExample), }; export const WithLinks: Story = { render: (_args, { argTypes }) => ({ components: { BentoLink, BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2"> A description with <bento-link to="/">a link</bento-link> </bento-timeline-item> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: { title: 'Milestone 3', to: '/', }, timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'green', }; const milestone2 = { ...DEFAULT_PROPS_WITHOUT_DESCRIPTION, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-15), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, }; }, }), args: { ...DEFAULT_PROPS, }, }; export const WithNotes: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args"> <bento-timeline-item v-bind="milestone3" /> <bento-timeline-item v-bind="milestone2" /> <bento-timeline-item v-bind="milestone1" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; return { args: isVue2 ? props : _args, milestone1, milestone2, milestone3, }; }, }), args: { ...DEFAULT_PROPS, showMore: null, }, parameters: storybookDocsParameter(TimelineWithNotesExample), }; export const AddNote: Story = { render: (_args, { argTypes }) => ({ components: { BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <bento-timeline v-bind="args" add-note @add-timeline-note="addNote"> <bento-timeline-item v-for="item in timelineItems" v-bind="item" /> </bento-timeline> `, setup(props) { const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-5), value: 'AuthorName', }, }; const milestone2 = { type: 'note', description: 'Milestone Note. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const timelineItems = ref(); onMounted(() => { timelineItems.value = [milestone3, milestone2, milestone1]; }); const addNote = e => { const newNote = { ...e, timestamp: { ...e.timestamp, value: 'AuthorName' } }; timelineItems.value.unshift(newNote); }; return { args: isVue2 ? props : _args, timelineItems, addNote, }; }, }), args: { ...DEFAULT_PROPS, showMore: null, addNote: true, }, parameters: storybookDocsParameter(TimelineAddNoteExample), }; export const DynamicItemAddition: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoTimeline, BentoTimelineItem }, props: Object.keys(argTypes), template: ` <div style="display: flex; flex-direction: row; align-items: flex-start; gap: 16px;"> <bento-button @click="addItem">Add timeline item</bento-button> <bento-timeline v-if="timelineEntries"> <bento-timeline-item v-for="entry in timelineEntries" :key="entry.title" v-bind="entry" /> </bento-timeline> </div> `, setup(props) { const timelineEntries = ref([]); let index = 0; const addItem = () => { if (index < 5) { timelineEntries.value.unshift(milestones[index]); index++; } }; const milestone5 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 5', status: 'green', }; const milestone4 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 4', timestamp: { date: new Date().setDate(-2), value: 'AuthorName', }, }; const milestone3 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 3', timestamp: { date: new Date().setDate(-4), value: 'AuthorName', }, status: 'red', }; const milestone2 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 2', timestamp: { date: new Date().setDate(-14), value: 'AuthorName', }, additionalTimestamp: { date: new Date().setDate(-15), value: 'AuthorName', }, }; const milestone1 = { ...DEFAULT_ITEM_PROPS, title: 'Milestone 1', timestamp: { date: new Date().setDate(-150), value: 'AuthorName', }, tag: { label: 'Tag1', }, }; const milestones = [milestone1, milestone2, milestone3, milestone4, milestone5]; return { args: isVue2 ? props : _args, timelineEntries, addItem, }; }, }), args: { ...DEFAULT_PROPS, }, parameters: storybookDocsParameter(TimelineDynamicAddition), };
@@ -1 +1 @@
1
- import { type BentoDashedUnderlineProps } from '@/components/dashed-underline/dashed-underline.types'; import { type BentoDateFormat } from '@/components/date/date.types'; import { type BentoTag } from '@/components/tag'; import { type Ref } from 'vue'; import type { RouterLinkProps } from 'vue-router/types/router.d.ts'; export enum BentoTimelineShowMorePlacement { BOTTOM = 'bottom', AFTER_FIRST = 'after-first', BEFORE_LAST = 'before-last', } export interface BentoTimelineShowMoreObject { limit: number; placement?: BentoTimelineShowMorePlacement; } export enum BentoTimelineGapUnit { SECOND = 'second', MINUTE = 'minute', HOUR = 'hour', DAY = 'day', MONTH = 'month', YEAR = 'year', } export interface BentoTimelineGapObject { amount: number; unit: BentoTimelineGapUnit; } /** * @deprecated Since v2.0.0. Do not use. Use the `status` prop instead. */ export enum BentoTimelineItemVariant { DEFAULT = 'SquareSmallIcon', SUCCESS = 'CheckedCircleIcon', CRITICAL = 'CrossCircleIcon', } export enum BentoTimelineStatus { BLACK = 'black', BLUE = 'blue', GREEN = 'green', GREY = 'grey', ORANGE = 'orange', RED = 'red', YELLOW = 'yellow', } export interface BentoTimelineItemTitle extends RouterLinkProps { /** * Link label. */ title: string; /** * Set the rendered link to a regular external anchor link. */ external?: boolean; /** * Sets the target of the rendered link. */ target?: string; // This has been added to allow users to add HTML and Aria attribute // eslint-disable-next-line @typescript-eslint/no-explicit-any [name: string]: any; } export interface BentoTimelineTimestamp { date: Date | number; format?: BentoDateFormat; value?: string; description?: BentoDashedUnderlineProps; } export interface BentoTimelineDataListObject { label: string; value: string; } export type BentoTimelineDataList = Array<BentoTimelineDataListObject>; export type BentoTimelineTagProps = InstanceType<typeof BentoTag>['$props']; export interface BentoTimelineEntry { title?: string | BentoTimelineItemTitle; description?: string; date: Date | number; } /** * @deprecated Since v2.0.0. Do not use. */ export type BentoTimelineRegisterEntry = (props: { title?: string | BentoTimelineItemTitle; description?: string; date: Date | number; }) => { timelineEntries: Ref<Array<BentoTimelineEntry>>; index: number; unregisterTimelineEntry: () => void }; /** * @private */ export type BentoInternalTimelineRegisterEntry = ( entry: BentoTimelineEntry ) => { timelineEntries: Ref<Array<BentoTimelineEntry>>; unregisterTimelineEntry: () => void }; export interface BentoTimelineConfigData { showAll: Ref<boolean>; showMoreIndex: Ref<number>; hiddenItems: Ref<number>; visibleIndexes: Ref<Array<number>>; timegapLimit: Ref<BentoTimelineGapObject>; timelineEntries: Ref<Array<BentoTimelineEntry>>; } export interface BentoTimelineProps { /** * If set to true, gives the possibility to manually add notes to the timeline via a textarea */ addNote?: boolean; /** * Object that determines the max number of items to show without clicking the show more button * and where in the timeline is the show more button placed */ showMore?: BentoTimelineShowMoreObject; /** * Object that determines minimum amount of time for the automatic timegap indicator; * Define a unit (hour, day, month) and an amount (e.g. { amount: 7, unit: 'days' }). * If null, automatic timegap detection will be turned off */ timegapLimit?: BentoTimelineGapObject; } export interface BentoTimelineItemProps { /** * Additional timestamp of the event */ additionalTimestamp?: BentoTimelineTimestamp; /** * Relevant key-value pair data to display in the event */ dataList?: BentoTimelineDataList; /** * Description of the event */ description?: string; /** * Modifier that changes the color of the timeline icon * @values blue, black, green, grey, orange, red, yellow */ status?: string; /** * Tag props that will be passed down to inner tag component */ tag?: BentoTimelineTagProps; /** * Main timestamp of the event. Used for timegap detection. */ timestamp: BentoTimelineTimestamp; /** * Title of the event */ title?: BentoTimelineItemTitle | string; /** * Type of the timeline item. If set to 'note', it renders a note item in the timeline. Defaults to 'milestone'. * @values milestone, note */ type?: string; /** * Variant for the timeline item * @values DEFAULT, SUCCESS, CRITICAL * * @deprecated Since v2.0.0. Use `status` instead. */ variant?: BentoTimelineItemVariant | `${BentoTimelineItemVariant}`; }
1
+ import { type BentoDashedUnderlineProps } from '@/components/dashed-underline/dashed-underline.types'; import { type BentoDateFormat } from '@/components/date/date.types'; import { type BentoTag } from '@/components/tag'; import { type Ref } from 'vue'; import type { RouterLinkProps } from 'vue-router/types/router.d.ts'; export enum BentoTimelineShowMorePlacement { BOTTOM = 'bottom', AFTER_FIRST = 'after-first', BEFORE_LAST = 'before-last', } export interface BentoTimelineShowMoreObject { limit: number; placement?: BentoTimelineShowMorePlacement; } export enum BentoTimelineGapUnit { SECOND = 'second', MINUTE = 'minute', HOUR = 'hour', DAY = 'day', MONTH = 'month', YEAR = 'year', } export interface BentoTimelineGapObject { amount: number; unit: BentoTimelineGapUnit; } /** * @deprecated Since v3.0.0. Do not use. Use the `status` prop instead. */ export enum BentoTimelineItemVariant { DEFAULT = 'SquareSmallIcon', SUCCESS = 'CheckedCircleIcon', CRITICAL = 'CrossCircleIcon', } export enum BentoTimelineStatus { BLACK = 'black', BLUE = 'blue', GREEN = 'green', GREY = 'grey', ORANGE = 'orange', RED = 'red', YELLOW = 'yellow', } export interface BentoTimelineItemTitle extends RouterLinkProps { /** * Link label. */ title: string; /** * Set the rendered link to a regular external anchor link. */ external?: boolean; /** * Sets the target of the rendered link. */ target?: string; // This has been added to allow users to add HTML and Aria attribute // eslint-disable-next-line @typescript-eslint/no-explicit-any [name: string]: any; } export interface BentoTimelineTimestamp { date: Date | number; format?: BentoDateFormat; value?: string; description?: BentoDashedUnderlineProps; } export interface BentoTimelineDataListObject { label: string; value: string; } export type BentoTimelineDataList = Array<BentoTimelineDataListObject>; export type BentoTimelineTagProps = InstanceType<typeof BentoTag>['$props']; export interface BentoTimelineEntry { title?: string | BentoTimelineItemTitle; description?: string; date: Date | number; } export interface BentoTimelineConfigData { showAll: Ref<boolean>; showMoreIndex: Ref<number>; hiddenItems: Ref<number>; visibleIndexes: Ref<Array<number>>; timegapLimit: Ref<BentoTimelineGapObject>; timelineEntries: Ref<Array<BentoTimelineEntry>>; } export interface BentoTimelineProps { /** * If set to true, gives the possibility to manually add notes to the timeline via a textarea */ addNote?: boolean; /** * Object that determines the max number of items to show without clicking the show more button * and where in the timeline is the show more button placed */ showMore?: BentoTimelineShowMoreObject; /** * Object that determines minimum amount of time for the automatic timegap indicator; * Define a unit (hour, day, month) and an amount (e.g. { amount: 7, unit: 'days' }). * If null, automatic timegap detection will be turned off */ timegapLimit?: BentoTimelineGapObject; } export interface BentoTimelineItemProps { /** * Additional timestamp of the event */ additionalTimestamp?: BentoTimelineTimestamp; /** * Relevant key-value pair data to display in the event */ dataList?: BentoTimelineDataList; /** * Description of the event */ description?: string; /** * Modifier that changes the color of the timeline icon * @values blue, black, green, grey, orange, red, yellow */ status?: string; /** * Tag props that will be passed down to inner tag component */ tag?: BentoTimelineTagProps; /** * Main timestamp of the event. Used for timegap detection. */ timestamp: BentoTimelineTimestamp; /** * Title of the event */ title?: BentoTimelineItemTitle | string; /** * Type of the timeline item. If set to 'note', it renders a note item in the timeline. Defaults to 'milestone'. * @values milestone, note */ type?: string; }
@@ -1 +1 @@
1
- <template> <div class="b-timeline"> <div v-if="addNote" class="b-timeline__add-note-section"> <bento-button v-if="!showAddNoteTextArea" ref="addNoteButtonRef" variant="tertiary" @click="toggleAddNote" >{{ addNoteLabel }}</bento-button > <div v-if="showAddNoteTextArea"> <bento-textarea ref="addNoteTextareaRef" :label="addNoteLabel" :character-limit="150" resizable="vertical" @update:model-value="updateNoteContent" /> <bento-button-actions :actions="[ { title: addNoteLabel, event: addNoteToTimeline }, { title: cancelLabel, event: toggleAddNote }, ]" /> </div> </div> <ol class="b-timeline__items"> <slot /> </ol> </div> </template> <script setup lang="ts"> import { computed, defineComponent, nextTick, provide, ref, type Ref, toRefs, watch } from 'vue'; import { BentoButton, BentoButtonActions } from '@/components/button'; import { BentoTextarea } from '@/components/textarea'; import { type BentoInternalTimelineRegisterEntry, type BentoTimelineConfigData, type BentoTimelineEntry, type BentoTimelineProps, BentoTimelineShowMorePlacement, } from './timeline.types'; import { TIMELINE_CONFIG_INJECTION_KEY, TIMELINE_REGISTER_ENTRY_INJECTION_KEY } from './timeline.keys'; import messages from './messages.json'; import { useI18n } from '@/utils/ts/i18n'; type MessageSchema = (typeof messages)['en-US']; const props = withDefaults(defineProps<BentoTimelineProps>(), { addNote: false, showMore: null, timegapLimit: null, }); const emit = defineEmits(['add-timeline-note']); const { t } = useI18n<{ message: MessageSchema }>({ messages }); const addNoteLabel = computed(() => t('addNote') as string); const cancelLabel = computed(() => t('cancel') as string); const newNoteContent: Ref<string> = ref(); const updateNoteContent = (newTimelineNoteContent: string): void => { newNoteContent.value = newTimelineNoteContent; }; const addNoteTextareaRef: Ref<InstanceType<typeof BentoTextarea>> = ref(null); const addNoteButtonRef: Ref<InstanceType<typeof BentoButton>> = ref(null); const showAddNoteTextArea = ref(false); const toggleAddNote = async () => { showAddNoteTextArea.value = !showAddNoteTextArea.value; await nextTick(); if (showAddNoteTextArea.value) { (addNoteTextareaRef.value.$refs.textareaElement as HTMLTextAreaElement)?.focus(); } else { (addNoteButtonRef.value.$el as HTMLButtonElement)?.focus(); } }; const addNoteToTimeline = () => { emit('add-timeline-note', { description: newNoteContent.value, timestamp: { date: new Date() }, type: 'note', }); toggleAddNote(); }; const timelineEntries = ref<Array<BentoTimelineEntry>>([]); const hiddenItems = computed(() => props.showMore && timelineEntries.value.length > props.showMore.limit ? timelineEntries.value.length - props.showMore.limit : null ); const showAll = ref(false); const { timegapLimit } = toRefs(props); const timelineIndexes = computed(() => Array.from(timelineEntries.value.keys())); const visibleIndexes = computed(() => { if (!props.showMore) { return null; } if (props.showMore.placement === BentoTimelineShowMorePlacement.BEFORE_LAST) { return [ ...timelineIndexes.value.slice(0, props.showMore.limit - 1), timelineIndexes.value[timelineIndexes.value.length - 1], ]; } if (props.showMore.placement === BentoTimelineShowMorePlacement.AFTER_FIRST) { return [timelineIndexes.value[0], ...timelineIndexes.value.slice(-(props.showMore.limit - 1))]; } return timelineIndexes.value.slice(0, props.showMore.limit); }); const showMoreIndex = computed(() => { if (!props.showMore) { return null; } switch (props.showMore.placement) { case BentoTimelineShowMorePlacement.BEFORE_LAST: return props.showMore.limit - 2; case BentoTimelineShowMorePlacement.AFTER_FIRST: return 0; case BentoTimelineShowMorePlacement.BOTTOM: default: return props.showMore.limit - 1; } }); const sortEntries = () => { // Sorts timeline entries based on date in reverse chronological order (newest first). timelineEntries.value.sort((a, b) => { return new Date(b.date).getTime() - new Date(a.date).getTime(); }); }; const unregisterTimelineEntry = (entryToRemove: BentoTimelineEntry) => () => { const index = timelineEntries.value.indexOf(entryToRemove); // The index can be -1 if the entry has already been removed by a parent re-render. if (index > -1) { timelineEntries.value.splice(index, 1); } }; const registerTimelineEntry: BentoInternalTimelineRegisterEntry = entry => { timelineEntries.value.push(entry); return { timelineEntries, unregisterTimelineEntry: unregisterTimelineEntry(entry) }; }; watch( () => timelineEntries.value.length, () => sortEntries() ); const configData: BentoTimelineConfigData = { showAll, showMoreIndex, hiddenItems, visibleIndexes, timegapLimit, timelineEntries, }; // provide register timeline entry and config data timeline items provide(TIMELINE_REGISTER_ENTRY_INJECTION_KEY, registerTimelineEntry); provide(TIMELINE_CONFIG_INJECTION_KEY, configData); </script> <script lang="ts"> /** * Timeline displays a collection of events in a reverse chronological order (newest event is displayed on the top). * * @example * import { BentoDateFormat, BentoTimeline } from '@adyen/bento-vue2'; * * export default { * components: { BentoTimeline }, * template: ` * <bento-timeline> * <bento-timeline-item * title="Milestone 1" * :timestamp="{ date: new Date(), value: 'Created at' }" * :additional-timestamp="{ date: new Date(), value: 'Modified at' }" * description="Milestone description" * :tag="{ label: 'Tag'}" * /> * <bento-timeline-item * title="Milestone 2" * :timestamp="{ * date: new Date(), * value: 'Created at', * format: BentoDateFormat.FULL_DATE_EXACT_TIME_WITHOUT_PERIOD * }" * description="Milestone description" * :data-list="[ * { label: 'Label', value: 'Value' }, * { label: 'Label', value: 'Value' }, * ]" * /> * </bento-timeline> * ` * } */ export default defineComponent({ i18n: { messages }, name: 'bento-timeline', }); </script> <style lang="scss" scoped src="./timeline.scss" />
1
+ <template> <div class="b-timeline"> <div v-if="addNote" class="b-timeline__add-note-section"> <bento-button v-if="!showAddNoteTextArea" ref="addNoteButtonRef" variant="tertiary" @click="toggleAddNote" >{{ addNoteLabel }}</bento-button > <div v-if="showAddNoteTextArea"> <bento-textarea ref="addNoteTextareaRef" :label="addNoteLabel" :character-limit="150" resizable="vertical" @update:model-value="updateNoteContent" /> <bento-button-actions :actions="[ { title: addNoteLabel, event: addNoteToTimeline }, { title: cancelLabel, event: toggleAddNote }, ]" /> </div> </div> <ol class="b-timeline__items"> <slot /> </ol> </div> </template> <script setup lang="ts"> import { computed, defineComponent, nextTick, provide, ref, type Ref, toRefs, watch } from 'vue'; import { BentoButton, BentoButtonActions } from '@/components/button'; import { BentoTextarea } from '@/components/textarea'; import { type BentoInternalTimelineRegisterEntry } from './timeline.internal.types'; import { type BentoTimelineConfigData, type BentoTimelineEntry, type BentoTimelineProps, BentoTimelineShowMorePlacement, } from './timeline.types'; import { TIMELINE_CONFIG_INJECTION_KEY, TIMELINE_REGISTER_ENTRY_INJECTION_KEY } from './timeline.keys'; import messages from './messages.json'; import { useI18n } from '@/utils/ts/i18n'; type MessageSchema = (typeof messages)['en-US']; const props = withDefaults(defineProps<BentoTimelineProps>(), { addNote: false, showMore: null, timegapLimit: null, }); const emit = defineEmits(['add-timeline-note']); const { t } = useI18n<{ message: MessageSchema }>({ messages }); const addNoteLabel = computed(() => t('addNote') as string); const cancelLabel = computed(() => t('cancel') as string); const newNoteContent: Ref<string> = ref(); const updateNoteContent = (newTimelineNoteContent: string): void => { newNoteContent.value = newTimelineNoteContent; }; const addNoteTextareaRef: Ref<InstanceType<typeof BentoTextarea>> = ref(null); const addNoteButtonRef: Ref<InstanceType<typeof BentoButton>> = ref(null); const showAddNoteTextArea = ref(false); const toggleAddNote = async () => { showAddNoteTextArea.value = !showAddNoteTextArea.value; await nextTick(); if (showAddNoteTextArea.value) { (addNoteTextareaRef.value.$refs.textareaElement as HTMLTextAreaElement)?.focus(); } else { (addNoteButtonRef.value.$el as HTMLButtonElement)?.focus(); } }; const addNoteToTimeline = () => { emit('add-timeline-note', { description: newNoteContent.value, timestamp: { date: new Date() }, type: 'note', }); toggleAddNote(); }; const timelineEntries = ref<Array<BentoTimelineEntry>>([]); const hiddenItems = computed(() => props.showMore && timelineEntries.value.length > props.showMore.limit ? timelineEntries.value.length - props.showMore.limit : null ); const showAll = ref(false); const { timegapLimit } = toRefs(props); const timelineIndexes = computed(() => Array.from(timelineEntries.value.keys())); const visibleIndexes = computed(() => { if (!props.showMore) { return null; } if (props.showMore.placement === BentoTimelineShowMorePlacement.BEFORE_LAST) { return [ ...timelineIndexes.value.slice(0, props.showMore.limit - 1), timelineIndexes.value[timelineIndexes.value.length - 1], ]; } if (props.showMore.placement === BentoTimelineShowMorePlacement.AFTER_FIRST) { return [timelineIndexes.value[0], ...timelineIndexes.value.slice(-(props.showMore.limit - 1))]; } return timelineIndexes.value.slice(0, props.showMore.limit); }); const showMoreIndex = computed(() => { if (!props.showMore) { return null; } switch (props.showMore.placement) { case BentoTimelineShowMorePlacement.BEFORE_LAST: return props.showMore.limit - 2; case BentoTimelineShowMorePlacement.AFTER_FIRST: return 0; case BentoTimelineShowMorePlacement.BOTTOM: default: return props.showMore.limit - 1; } }); const sortEntries = () => { // Sorts timeline entries based on date in reverse chronological order (newest first). timelineEntries.value.sort((a, b) => { return new Date(b.date).getTime() - new Date(a.date).getTime(); }); }; const unregisterTimelineEntry = (entryToRemove: BentoTimelineEntry) => () => { const index = timelineEntries.value.indexOf(entryToRemove); // The index can be -1 if the entry has already been removed by a parent re-render. if (index > -1) { timelineEntries.value.splice(index, 1); } }; const registerTimelineEntry: BentoInternalTimelineRegisterEntry = entry => { timelineEntries.value.push(entry); return { timelineEntries, unregisterTimelineEntry: unregisterTimelineEntry(entry) }; }; watch( () => timelineEntries.value.length, () => sortEntries() ); const configData: BentoTimelineConfigData = { showAll, showMoreIndex, hiddenItems, visibleIndexes, timegapLimit, timelineEntries, }; // provide register timeline entry and config data timeline items provide(TIMELINE_REGISTER_ENTRY_INJECTION_KEY, registerTimelineEntry); provide(TIMELINE_CONFIG_INJECTION_KEY, configData); </script> <script lang="ts"> /** * Timeline displays a collection of events in a reverse chronological order (newest event is displayed on the top). * * @example * import { BentoDateFormat, BentoTimeline } from '@adyen/bento-vue2'; * * export default { * components: { BentoTimeline }, * template: ` * <bento-timeline> * <bento-timeline-item * title="Milestone 1" * :timestamp="{ date: new Date(), value: 'Created at' }" * :additional-timestamp="{ date: new Date(), value: 'Modified at' }" * description="Milestone description" * :tag="{ label: 'Tag'}" * /> * <bento-timeline-item * title="Milestone 2" * :timestamp="{ * date: new Date(), * value: 'Created at', * format: BentoDateFormat.FULL_DATE_EXACT_TIME_WITHOUT_PERIOD * }" * description="Milestone description" * :data-list="[ * { label: 'Label', value: 'Value' }, * { label: 'Label', value: 'Value' }, * ]" * /> * </bento-timeline> * ` * } */ export default defineComponent({ i18n: { messages }, name: 'bento-timeline', }); </script> <style lang="scss" scoped src="./timeline.scss" />
@@ -1 +1 @@
1
- <template> <div class="b-toast-item"> <output class="b-toast-item__text" role="status"> <bento-typography :title="toast.text" el="span" variant="body" strongest> {{ toast.text }} </bento-typography> </output> <bento-button v-if="toast.action" class="b-toast-item__btn" variant="tertiary" data-testid="toast-item-action-btn" @click="onAction" > {{ toast.action.text }} </bento-button> <bento-button class="b-toast-item__btn" variant="tertiary" data-testid="toast-item-close-btn" @click="toast.dismiss()" > <template #iconLeft> <cross-icon :svg-title="t('dismiss')" /> </template> </bento-button> </div> </template> <script setup lang="ts"> import { type PropType } from 'vue'; import CrossIcon from '@adyen/ui-assets-icons-16/vue/cross-small'; import { useI18n } from '@/utils/ts/i18n'; import { BentoButton } from '@/components/button'; import { BentoTypography } from '@/components/typography'; import type { BentoToastItem } from '@/composables'; import messages from './messages.json'; const props = defineProps({ toast: { type: Object as PropType<BentoToastItem>, required: true }, }); type MessageSchema = (typeof messages)['en-US']; const { t } = useI18n<{ message: MessageSchema }>({ messages }); const onAction = () => { if (typeof props.toast.action.handler === 'function') { props.toast.action.handler(); } props.toast.dismiss(); }; </script> <script lang="ts"> export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./toast-item.scss" />
1
+ <template> <div class="b-toast-item"> <output class="b-toast-item__text" role="status"> <bento-typography :title="toast.text" el="span" variant="body" strongest> {{ toast.text }} </bento-typography> </output> <bento-button v-if="toast.action" variant="tertiary" inverse data-testid="toast-item-action-btn" @click="onAction" > {{ toast.action.text }} </bento-button> <bento-button variant="tertiary" inverse data-testid="toast-item-close-btn" @click="toast.dismiss()"> <template #iconLeft> <cross-icon :svg-title="t('dismiss')" /> </template> </bento-button> </div> </template> <script setup lang="ts"> import { type PropType } from 'vue'; import CrossIcon from '@adyen/ui-assets-icons-16/vue/cross-small'; import { useI18n } from '@/utils/ts/i18n'; import { BentoButton } from '@/components/button'; import { BentoTypography } from '@/components/typography'; import type { BentoToastItem } from '@/composables'; import messages from './messages.json'; const props = defineProps({ toast: { type: Object as PropType<BentoToastItem>, required: true }, }); type MessageSchema = (typeof messages)['en-US']; const { t } = useI18n<{ message: MessageSchema }>({ messages }); const onAction = () => { if (typeof props.toast.action.handler === 'function') { props.toast.action.handler(); } props.toast.dismiss(); }; </script> <script lang="ts"> export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./toast-item.scss" />
@@ -1 +1 @@
1
- import { storybookDocsParameter } from '@/utils/ts/storybook'; import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import BentoToggle from './toggle.vue'; const TOGGLE_LABEL = 'Label'; const TOGGLE_DESCRIPTION = 'Description'; export default { title: 'Toggle', component: BentoToggle, argTypes: { default: { name: 'Default slot', description: 'Toggle label', defaultValue: '', table: { type: { summary: 'VNode[]' }, }, control: 'text', }, description: { name: 'Descriptive sub label slot', description: 'Toggle description', defaultValue: '', table: { type: { summary: 'VNode[]' }, }, control: 'text', }, input: { name: 'input', defaultValue: '', description: 'Input event handler.', table: { type: { summary: '($event) => void' }, }, control: { disable: true }, }, }, }; export const Default = (_args, { argTypes }) => ({ components: { BentoToggle }, props: Object.keys(argTypes), template: ` <bento-toggle v-bind="args" @input="clickedToggleAction"> {{args.default}} <template #description>{{args.description}}</template> </bento-toggle> `, setup(props) { return { clickedToggleAction: action('input'), args: isVue2 ? props : _args, }; }, }); Default.args = { default: TOGGLE_LABEL, description: TOGGLE_DESCRIPTION, disabled: false, }; const defaultCode = ` <bento-toggle @input="clickedToggleAction"> ${TOGGLE_LABEL} <template #description>${TOGGLE_DESCRIPTION}</template> </bento-toggle> `; Default.parameters = storybookDocsParameter(defaultCode); export const toggleOnly = (_args, { argTypes }) => ({ components: { BentoToggle }, props: Object.keys(argTypes), template: ` <bento-toggle v-bind="args" @input="clickedToggleAction" /> `, setup(props) { return { clickedToggleAction: action('input'), args: isVue2 ? props : _args, }; }, }); toggleOnly.args = { disabled: false, }; const toggleOnlyCode = ` <bento-toggle @input="clickedToggleAction" /> `; toggleOnly.parameters = storybookDocsParameter(toggleOnlyCode);
1
+ import { storybookDocsParameter } from '@/utils/ts/storybook'; import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import BentoToggle from './toggle.vue'; const ToggleDefaultExample = "<template>\n <bento-toggle @input=\"clickedToggleAction\">\n Label\n <template #description>Description</template>\n </bento-toggle>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoToggle } from '@adyen/bento-vue2';\n\n const clickedToggleAction = () => true;\n</script>\n"; const ToggleOnlyExample = "<template>\n <bento-toggle @input=\"clickedToggleAction\" />\n</template>\n\n<script setup lang=\"ts\">\n import { BentoToggle } from '@adyen/bento-vue2';\n\n const clickedToggleAction = () => true;\n</script>\n"; const TOGGLE_LABEL = 'Label'; const TOGGLE_DESCRIPTION = 'Description'; export default { title: 'Toggle', component: BentoToggle, argTypes: { default: { name: 'Default slot', description: 'Toggle label', defaultValue: '', table: { type: { summary: 'VNode[]' }, }, control: 'text', }, description: { name: 'Descriptive sub label slot', description: 'Toggle description', defaultValue: '', table: { type: { summary: 'VNode[]' }, }, control: 'text', }, input: { name: 'input', defaultValue: '', description: 'Input event handler.', table: { type: { summary: '($event) => void' }, }, control: { disable: true }, }, }, }; export const Default = (_args, { argTypes }) => ({ components: { BentoToggle }, props: Object.keys(argTypes), template: ` <bento-toggle v-bind="args" @input="clickedToggleAction"> {{args.default}} <template #description>{{args.description}}</template> </bento-toggle> `, setup(props) { return { clickedToggleAction: action('input'), args: isVue2 ? props : _args, }; }, }); Default.args = { default: TOGGLE_LABEL, description: TOGGLE_DESCRIPTION, disabled: false, }; Default.parameters = storybookDocsParameter(ToggleDefaultExample); export const toggleOnly = (_args, { argTypes }) => ({ components: { BentoToggle }, props: Object.keys(argTypes), template: ` <bento-toggle v-bind="args" @input="clickedToggleAction" /> `, setup(props) { return { clickedToggleAction: action('input'), args: isVue2 ? props : _args, }; }, }); toggleOnly.args = { disabled: false, }; toggleOnly.parameters = storybookDocsParameter(ToggleOnlyExample);
@@ -1 +1 @@
1
- export enum BentoTogglePropClass { LABEL_FIRST = 'label-first', } /** * @deprecated Since v2.0.0. Use string literal instead. */ export enum BentoToggleLabelPosition { BEFORE = 'before', AFTER = 'after', }
1
+ export enum BentoTogglePropClass { LABEL_FIRST = 'label-first', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoToggleLabelPosition { BEFORE = 'before', AFTER = 'after', }
@@ -1 +1 @@
1
- <template> <label class="b-toggle" :class="conditionalClasses" data-testid="label"> <input v-model="toggleInput" :aria-label="computedAriaLabel" :aria-describedby="computedDescription" :disabled="disabled" :aria-readonly="readonly" role="switch" class="b-toggle__input" type="checkbox" @change="$event => onChange($event)" @click="onClick" /> <span class="b-toggle__track" aria-hidden="true"> <span class="b-toggle__handle"> <checkmark-small v-if="toggleInput" /> </span> </span> <span v-if="hasSlot('default')" class="b-toggle__label-container"> <bento-typography v-if="hasSlot('default')" el="span" variant="body" data-testid="inner-label"> <slot></slot> </bento-typography> <bento-typography v-if="hasSlot('default') && hasSlot('description')" :id="descriptionId" el="span" variant="body" class="b-toggle__description" > <slot name="description" /> </bento-typography> </span> </label> </template> <script setup lang="ts"> import { computed, type PropType, ref, toRefs, useAttrs, useSlots, watch } from 'vue'; import CheckmarkSmall from '@adyen/ui-assets-icons-16/vue/checkmark-small'; import { BentoToggleLabelPosition, BentoTogglePropClass } from './toggle.types'; import { BentoTypography } from '@/components/typography'; import { generateUid } from '@/core/utils/ts'; import { useDefaultSlotValidator, useHasSlot } from '@/composables'; import { getSlotText } from '@/utils/ts/get-slot-text/get-slot-text'; import { useAriaLabel } from '@/utils/ts/aria-label'; const slots = useSlots(); const attrs = useAttrs(); const hasSlot = useHasSlot(slots); const props = defineProps({ /** * @deprecated Since v2.0.0. Use `aria-label` instead. * Accessible name for the toggle. It is strongly recommended to pass such value when the toggle is used without a label */ ariaLabel: { type: String, default: undefined, }, /** * Disable the toggle (optional) */ disabled: { type: Boolean, default: false, }, /** * Position of the label relative to the toggle (optional) * @values before, after */ labelPosition: { type: String as PropType<BentoToggleLabelPosition | `${BentoToggleLabelPosition}`>, default: BentoToggleLabelPosition.BEFORE, validator: (value: BentoToggleLabelPosition) => Object.values(BentoToggleLabelPosition).includes(value), }, /** * Setting this property to true will set the toggle to read only state. */ readonly: { type: Boolean, default: false, }, /** * Indicates if the switch is "on" or "off" */ value: { type: Boolean, default: false, }, }); const emit = defineEmits<{ (e: 'input', value: boolean): void; }>(); const toggleInput = ref(props.value); const descriptionId: string = generateUid('toggle-description'); useDefaultSlotValidator('bento-toggle', slots.default, slots.description); const labelSlot = computed((): string | null => (hasSlot('default') ? getSlotText(slots)('default') : null)); const ariaLabelAttribute = computed(() => attrs['aria-label'] as string); const { ariaLabel } = toRefs(props); const computedAriaLabel = useAriaLabel({ ariaLabel: ariaLabelAttribute.value, // TODO: take this line away when the aria-label props is removed label: ariaLabel, defaultFallback: labelSlot, }); const computedDescription = computed((): string | null => descriptionId ?? null); const conditionalClasses = computed((): { [key: string]: boolean } => ({ [`b-toggle--${BentoTogglePropClass.LABEL_FIRST}`]: props.labelPosition === BentoToggleLabelPosition.BEFORE, 'b-toggle--disabled': props.disabled, 'b-toggle--readonly': props.readonly, })); const onChange = (event: Event) => { emit('input', (event.target as HTMLInputElement).checked); }; // readonly attr doesn't work with checkbox, so we need to manually ignore the click instead const onClick = (event: Event) => { if (props.readonly) { event.preventDefault(); } }; watch( () => props.value, newValue => { toggleInput.value = newValue; } ); </script> <script lang="ts"> /** * A wrapper around the bento toggle, providing checkbox functionality with a knob-like toggle * * @usage * import { BentoToggle, BentoLabelPosition } from '@adyen/adl-vue2'; * * export default { * components: { BentoToggle }, * template: ` * <bento-toggle * :value="toggleValue"` * label-position="LabelPosition.BEFORE" * @input="optionalHandler($event)" * > * Label Text * </bento-toggle> * `, * } */ export default { name: 'bento-toggle', }; </script> <style lang="scss" scoped src="./toggle.scss" />
1
+ <template> <label class="b-toggle" :class="conditionalClasses" data-testid="label"> <input v-model="toggleInput" :aria-label="computedAriaLabel" :aria-describedby="computedDescription" :disabled="disabled" :aria-readonly="readonly" role="switch" class="b-toggle__input" type="checkbox" @change="$event => onChange($event)" @click="onClick" /> <span class="b-toggle__track" aria-hidden="true"> <span class="b-toggle__handle"> <checkmark-small v-if="toggleInput" /> </span> </span> <span v-if="hasSlot('default')" class="b-toggle__label-container"> <bento-typography v-if="hasSlot('default')" el="span" variant="body" data-testid="inner-label"> <slot></slot> </bento-typography> <bento-typography v-if="hasSlot('default') && hasSlot('description')" :id="descriptionId" el="span" variant="body" class="b-toggle__description" > <slot name="description" /> </bento-typography> </span> </label> </template> <script setup lang="ts"> import { computed, type PropType, ref, toRefs, useAttrs, useSlots, watch } from 'vue'; import CheckmarkSmall from '@adyen/ui-assets-icons-16/vue/checkmark-small'; import { BentoToggleLabelPosition, BentoTogglePropClass } from './toggle.types'; import { BentoTypography } from '@/components/typography'; import { generateUid } from '@/utils/ts/generate-uid'; import { useDefaultSlotValidator, useHasSlot } from '@/composables'; import { getSlotText } from '@/utils/ts/get-slot-text/get-slot-text'; import { useAriaLabel } from '@/utils/ts/aria-label'; const slots = useSlots(); const attrs = useAttrs(); const hasSlot = useHasSlot(slots); const props = defineProps({ /** * @deprecated Since v3.0.0. Use `aria-label` instead. * Accessible name for the toggle. It is strongly recommended to pass such value when the toggle is used without a label */ ariaLabel: { type: String, default: undefined, }, /** * Disable the toggle (optional) */ disabled: { type: Boolean, default: false, }, /** * Position of the label relative to the toggle (optional) * @values before, after */ labelPosition: { type: String as PropType<BentoToggleLabelPosition | `${BentoToggleLabelPosition}`>, default: BentoToggleLabelPosition.BEFORE, validator: (value: BentoToggleLabelPosition) => Object.values(BentoToggleLabelPosition).includes(value), }, /** * Setting this property to true will set the toggle to read only state. */ readonly: { type: Boolean, default: false, }, /** * Indicates if the switch is "on" or "off" */ value: { type: Boolean, default: false, }, }); const emit = defineEmits<{ (e: 'input', value: boolean): void; }>(); const toggleInput = ref(props.value); const descriptionId: string = generateUid('toggle-description'); useDefaultSlotValidator('bento-toggle', slots.default, slots.description); const labelSlot = computed((): string | null => (hasSlot('default') ? getSlotText(slots)('default') : null)); const ariaLabelAttribute = computed(() => attrs['aria-label'] as string); const { ariaLabel } = toRefs(props); const computedAriaLabel = useAriaLabel({ ariaLabel: ariaLabelAttribute.value, // TODO: take this line away when the aria-label props is removed label: ariaLabel, defaultFallback: labelSlot, }); const computedDescription = computed((): string | null => descriptionId ?? null); const conditionalClasses = computed((): { [key: string]: boolean } => ({ [`b-toggle--${BentoTogglePropClass.LABEL_FIRST}`]: props.labelPosition === BentoToggleLabelPosition.BEFORE, 'b-toggle--disabled': props.disabled, 'b-toggle--readonly': props.readonly, })); const onChange = (event: Event) => { emit('input', (event.target as HTMLInputElement).checked); }; // readonly attr doesn't work with checkbox, so we need to manually ignore the click instead const onClick = (event: Event) => { if (props.readonly) { event.preventDefault(); } }; watch( () => props.value, newValue => { toggleInput.value = newValue; } ); </script> <script lang="ts"> /** * A wrapper around the bento toggle, providing checkbox functionality with a knob-like toggle * * @usage * import { BentoToggle, BentoLabelPosition } from '@adyen/adl-vue2'; * * export default { * components: { BentoToggle }, * template: ` * <bento-toggle * :value="toggleValue"` * label-position="LabelPosition.BEFORE" * @input="optionalHandler($event)" * > * Label Text * </bento-toggle> * `, * } */ export default { name: 'bento-toggle', }; </script> <style lang="scss" scoped src="./toggle.scss" />
@@ -1 +1 @@
1
- import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoTutorial } from './index'; import BentoTutorialPopover from './components/tutorial-popover/tutorial-popover.vue'; import { BentoButton } from '@/components/button'; import { BentoTab, BentoTabs } from '@/components/tabs'; import { BentoTag } from '@/components/tag'; import { BentoImage } from '@/components/image'; import { BentoPaymentMethod } from '@/components/payment-method'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import type { BentoTutorialStep } from './tutorial.types'; import illustration from '@/components/empty-state/assets/small/2-generic-use.svg'; import { mockImage } from '../image/const'; import './tutorial.stories.scss?module'; import TutorialDefaultExample from './__tests__/tutorial-default-example.vue?raw'; const meta: Meta = { title: 'Tutorial', component: BentoTutorial, }; export default meta; type Story = StoryObj<typeof BentoTutorial>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoImage, BentoPaymentMethod, BentoTag, BentoTutorial, BentoTabs, BentoTab, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature1">Feature 1</bento-button> <bento-tag ref="feature2" label="Feature 2" variant="blue" /> <bento-image ref="feature3" src="${mockImage}" alt="Mock image" aspect-ratio="landscape" object-fit="cover" style="height: 48px" /> <bento-payment-method ref="feature4" type="ideal" label="Feature 4" /> <bento-tabs> <bento-tab title="Maria Ahlefeldt" :set-element-ref="setFeature5"> (16 January 1755 - 20 December 1810) was a Danish, (originally German), composer. She is known as the first female composer in Denmark. </bento-tab> </bento-tabs> </div> <bento-tutorial v-bind="args" :steps="steps" @update:index="onIndexUpdate" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const feature3 = ref(null); const feature4 = ref(null); const feature5 = ref(null); const setFeature5 = (el: Element) => { feature5.value = el; }; const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, }, { target: feature2, title: 'Feature 2', description: 'What a shiny feature - Feature 2!', action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'top-start', }, { target: feature3, title: 'Feature 3', description: 'Look at this <BentoImage> component. It is indeed, an image.', position: 'right-end', }, { target: feature4, title: 'Feature 4', description: "That's all folks!", action: { title: "What's this?", event: () => action("What's this?")(), }, position: 'bottom-end', }, { target: feature5, title: 'Feature 5', description: 'More of this feature', }, ]; const onIndexUpdate = (value: number) => action('update:index')(value); return { // Values args: isVue2 ? props : _args, steps, onIndexUpdate, // Refs feature1, feature2, feature3, feature4, setFeature5, }; }, }), parameters: storybookDocsParameter(TutorialDefaultExample), }; const singleCode = ` <template> <bento-button ref="targetElement1">Feature 1</bento-button> <bento-tutorial :steps="[ { target: targetElement1, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: AnyImageSource, alt: 'Welcome' }, } ]" /> </template> <script setup lang="ts"> import { ref } from 'vue' import { BentoButton, BentoTutorial } from '@adyen/bento-vue2' import AnyImageSource from '@/path/to/your/image.svg' const targetElement1 = ref(null) </script> `; export const Single: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoTutorial, BentoTutorialPopover, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature"> Exciting new feature </bento-button> </div> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature, }; }, }), parameters: storybookDocsParameter(singleCode), }; export const Inline: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography, BentoTutorial, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <bento-typography el="p"> Did you hear that? They've shut down the main reactor. We'll be destroyed for sure. This is madness! We're doomed! There'll be no escape for the Princess this time. What's that? Artoo! Artoo-Detoo, where are you? At last! Where have you been? They're heading in this direction. What are we going to do? We'll be sent to the spice mine of Kessel or smashed into who knows what! Wait a minute, where are you going? The Death Star plans are not in the main computer. Where are those transmissions you intercepted? What have you done with those plans? We intercepted no transmissions. </bento-typography> <bento-typography el="p"> I've lost Artoo! You may fire when ready. I have you now. What? Yahoo! Look out! You're all clear, kid. Now let's blow this thing and go home! Stand by to fire at Rebel base. Standing by. </bento-typography> <bento-typography el="p"> You must learn the ways of the <strong ref="feature1">Force</strong> if you're to come with me to Alderaan. Alderaan? I'm not going to Alderaan. I've got to go home. It's late, I'm in for it as it is. </bento-typography> <bento-typography el="p"> Look, a few minutes ago you said you didn't want to just wait here to be captured. Now all you want to do is stay. Marching into the detention area is not what I had in mind. But they're going to kill her! Better her than me. She's rich. </bento-typography> <bento-typography el="p"> You may fire when ready. What? You're far too trusting. Dantooine is too remote to make an effective demonstration. But don't worry. We will deal with your <strong ref="feature2">Rebel</strong> friends soon enough. </bento-typography> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'The Force', description: `The Force is what gives a Jedi his power. It's an energy field created by all living things. It surrounds us and penetrates us; it binds the galaxy together`, }, { target: feature2, title: 'Rebel Alliance', description: `The Alliance to Restore the Republic (2 BBY–4 ABY), commonly known as the Rebel Alliance, Alliance, and the Rebellion, was a resistance movement to oppose the rule of the Galactic Empire and to restore the Galactic Republic.`, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'bottom', }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature1, feature2, }; }, }), parameters: storybookDocsParameter(singleCode), };
1
+ import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoTutorial } from './index'; import BentoTutorialPopover from './components/tutorial-popover/tutorial-popover.vue'; import { BentoButton } from '@/components/button'; import { BentoTab, BentoTabs } from '@/components/tabs'; import { BentoTag } from '@/components/tag'; import { BentoImage } from '@/components/image'; import { BentoPaymentMethod } from '@/components/payment-method'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import type { BentoTutorialStep } from './tutorial.types'; import illustration from '@/components/empty-state/assets/small/2-generic-use.svg'; import { mockImage } from '../image/const'; import './tutorial.stories.scss?module'; const TutorialDefaultExample = "<template>\n <div class=\"b-container\">\n <div class=\"b-feature-row\">\n <bento-button ref=\"feature1\">Feature 1</bento-button>\n\n <bento-tag ref=\"feature2\" label=\"Feature 2\" variant=\"blue\" />\n\n <bento-image\n ref=\"feature3\"\n :src=\"mockImage\"\n alt=\"Mock image\"\n aspect-ratio=\"landscape\"\n object-fit=\"cover\"\n style=\"height: 48px\"\n />\n\n <bento-payment-method ref=\"feature4\" type=\"ideal\" label=\"Feature 4\" />\n\n <bento-tabs>\n <bento-tab title=\"Maria Ahlefeldt\" :set-element-ref=\"setFeature5\">\n (16 January 1755 - 20 December 1810) was a Danish, (originally German), composer. She is known as\n the first female composer in Denmark.\n </bento-tab>\n </bento-tabs>\n </div>\n\n <bento-tutorial :steps=\"steps\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import {\n BentoButton,\n BentoImage,\n BentoPaymentMethod,\n BentoTab,\n BentoTabs,\n BentoTag,\n BentoTutorial,\n type BentoTutorialStep,\n } from '@adyen/bento-vue2';\n import illustration from '@adyen/bento-vue2/assets/small/2-generic-use.svg';\n\n // replace this with your own image\n import { mockImage } from '../../image/const';\n\n const feature1 = ref(null);\n const feature2 = ref(null);\n const feature3 = ref(null);\n const feature4 = ref(null);\n const feature5 = ref(null);\n\n const setFeature5 = (el: Element) => {\n feature5.value = el;\n };\n\n const steps: Array<BentoTutorialStep> = [\n {\n target: feature1,\n title: 'Welcome!',\n description: 'This is a demo of a tutorial',\n image: {\n src: illustration,\n alt: 'Welcome',\n objectFit: 'cover',\n },\n },\n {\n target: feature2,\n title: 'Feature 2',\n description: 'What a shiny feature - Feature 2!',\n action: {\n title: 'Learn more',\n },\n position: 'top-start',\n },\n {\n target: feature3,\n title: 'Feature 3',\n description: 'Look at this <BentoImage> component. It is indeed, an image.',\n position: 'right-end',\n },\n {\n target: feature4,\n title: 'Feature 4',\n description: \"That's all folks!\",\n action: {\n title: \"What's this?\",\n },\n position: 'bottom-end',\n },\n {\n target: feature5,\n title: 'Feature 5',\n description: 'More of this feature',\n },\n ];\n</script>\n"; const TutorialInlineExample = "<template>\n <div class=\"b-container\">\n <bento-typography el=\"p\">\n Did you hear that? They've shut down the main reactor. We'll be destroyed for sure. This is madness! We're\n doomed! There'll be no escape for the Princess this time. What's that? Artoo! Artoo-Detoo, where are you? At\n last! Where have you been? They're heading in this direction. What are we going to do? We'll be sent to the\n spice mine of Kessel or smashed into who knows what! Wait a minute, where are you going? The Death Star\n plans are not in the main computer. Where are those transmissions you intercepted? What have you done with\n those plans? We intercepted no transmissions.\n </bento-typography>\n <bento-typography el=\"p\">\n I've lost Artoo! You may fire when ready. I have you now. What? Yahoo! Look out! You're all clear, kid. Now\n let's blow this thing and go home! Stand by to fire at Rebel base. Standing by.\n </bento-typography>\n <bento-typography el=\"p\">\n You must learn the ways of the <strong ref=\"feature1\">Force</strong> if you're to come with me to Alderaan.\n Alderaan? I'm not going to Alderaan. I've got to go home. It's late, I'm in for it as it is.\n </bento-typography>\n <bento-typography el=\"p\">\n Look, a few minutes ago you said you didn't want to just wait here to be captured. Now all you want to do is\n stay. Marching into the detention area is not what I had in mind. But they're going to kill her! Better her\n than me. She's rich.\n </bento-typography>\n <bento-typography el=\"p\">\n You may fire when ready. Dantooine is too remote for a demonstration. We will deal with your\n <strong ref=\"feature2\">Rebel</strong> friends soon enough.\n </bento-typography>\n\n <bento-tutorial :steps=\"steps\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoTutorial, type BentoTutorialStep, BentoTypography } from '@adyen/bento-vue2';\n\n const feature1 = ref(null);\n const feature2 = ref(null);\n\n const steps: Array<BentoTutorialStep> = [\n {\n target: feature1,\n title: 'The Force',\n description:\n `The Force is what gives a Jedi his power. It's an energy field created by all living things. ` +\n `It surrounds us and penetrates us; it binds the galaxy together`,\n },\n {\n target: feature2,\n title: 'Rebel Alliance',\n description:\n `The Alliance to Restore the Republic (2 BBY–4 ABY), commonly known as the Rebel Alliance, Alliance, ` +\n `and the Rebellion, was a resistance movement to oppose the rule of the Galactic Empire and to restore ` +\n `the Galactic Republic.`,\n action: {\n title: 'Learn more',\n },\n position: 'bottom',\n },\n ];\n</script>\n"; const TutorialSingleExample = "<template>\n <div class=\"b-container\">\n <div class=\"b-feature-row\">\n <bento-button ref=\"feature\">Exciting new feature</bento-button>\n </div>\n\n <bento-tutorial :steps=\"steps\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, BentoTutorial, type BentoTutorialStep } from '@adyen/bento-vue2';\n import illustration from '@adyen/bento-vue2/assets/small/2-generic-use.svg';\n\n const feature = ref(null);\n\n const steps: Array<BentoTutorialStep> = [\n {\n target: feature,\n title: 'Welcome!',\n description: 'This is a demo of a tutorial',\n image: {\n src: illustration,\n alt: 'Welcome',\n objectFit: 'cover',\n },\n action: {\n title: 'Learn more',\n },\n },\n ];\n</script>\n"; const meta: Meta = { title: 'Tutorial', component: BentoTutorial, }; export default meta; type Story = StoryObj<typeof BentoTutorial>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoImage, BentoPaymentMethod, BentoTag, BentoTutorial, BentoTabs, BentoTab, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature1">Feature 1</bento-button> <bento-tag ref="feature2" label="Feature 2" variant="blue" /> <bento-image ref="feature3" src="${mockImage}" alt="Mock image" aspect-ratio="landscape" object-fit="cover" style="height: 48px" /> <bento-payment-method ref="feature4" type="ideal" label="Feature 4" /> <bento-tabs> <bento-tab title="Maria Ahlefeldt" :set-element-ref="setFeature5"> (16 January 1755 - 20 December 1810) was a Danish, (originally German), composer. She is known as the first female composer in Denmark. </bento-tab> </bento-tabs> </div> <bento-tutorial v-bind="args" :steps="steps" @update:index="onIndexUpdate" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const feature3 = ref(null); const feature4 = ref(null); const feature5 = ref(null); const setFeature5 = (el: Element) => { feature5.value = el; }; const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, }, { target: feature2, title: 'Feature 2', description: 'What a shiny feature - Feature 2!', action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'top-start', }, { target: feature3, title: 'Feature 3', description: 'Look at this <BentoImage> component. It is indeed, an image.', position: 'right-end', }, { target: feature4, title: 'Feature 4', description: "That's all folks!", action: { title: "What's this?", event: () => action("What's this?")(), }, position: 'bottom-end', }, { target: feature5, title: 'Feature 5', description: 'More of this feature', }, ]; const onIndexUpdate = (value: number) => action('update:index')(value); return { // Values args: isVue2 ? props : _args, steps, onIndexUpdate, // Refs feature1, feature2, feature3, feature4, setFeature5, }; }, }), parameters: storybookDocsParameter(TutorialDefaultExample), }; export const Single: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoTutorial, BentoTutorialPopover, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature"> Exciting new feature </bento-button> </div> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature, }; }, }), parameters: storybookDocsParameter(TutorialSingleExample), }; export const Inline: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography, BentoTutorial, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <bento-typography el="p"> Did you hear that? They've shut down the main reactor. We'll be destroyed for sure. This is madness! We're doomed! There'll be no escape for the Princess this time. What's that? Artoo! Artoo-Detoo, where are you? At last! Where have you been? They're heading in this direction. What are we going to do? We'll be sent to the spice mine of Kessel or smashed into who knows what! Wait a minute, where are you going? The Death Star plans are not in the main computer. Where are those transmissions you intercepted? What have you done with those plans? We intercepted no transmissions. </bento-typography> <bento-typography el="p"> I've lost Artoo! You may fire when ready. I have you now. What? Yahoo! Look out! You're all clear, kid. Now let's blow this thing and go home! Stand by to fire at Rebel base. Standing by. </bento-typography> <bento-typography el="p"> You must learn the ways of the <strong ref="feature1">Force</strong> if you're to come with me to Alderaan. Alderaan? I'm not going to Alderaan. I've got to go home. It's late, I'm in for it as it is. </bento-typography> <bento-typography el="p"> Look, a few minutes ago you said you didn't want to just wait here to be captured. Now all you want to do is stay. Marching into the detention area is not what I had in mind. But they're going to kill her! Better her than me. She's rich. </bento-typography> <bento-typography el="p"> You may fire when ready. What? You're far too trusting. Dantooine is too remote to make an effective demonstration. But don't worry. We will deal with your <strong ref="feature2">Rebel</strong> friends soon enough. </bento-typography> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'The Force', description: `The Force is what gives a Jedi his power. It's an energy field created by all living things. It surrounds us and penetrates us; it binds the galaxy together`, }, { target: feature2, title: 'Rebel Alliance', description: `The Alliance to Restore the Republic (2 BBY–4 ABY), commonly known as the Rebel Alliance, Alliance, and the Rebellion, was a resistance movement to oppose the rule of the Galactic Empire and to restore the Galactic Republic.`, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'bottom', }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature1, feature2, }; }, }), parameters: storybookDocsParameter(TutorialInlineExample), };
@@ -1 +1 @@
1
- import BentoTypography from './typography.vue'; import { BentoTypographyElement, BentoTypographyVariant } from './typography.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { isVue2 } from 'vue-demi'; import type { Meta, StoryObj } from '@storybook/vue'; const meta: Meta = { title: 'Typography', component: BentoTypography, argTypes: { default: { name: 'default', defaultValue: '', description: 'typography text', table: { type: { summary: 'VNode[]' }, }, control: { type: 'text', }, }, el: { options: Object.values(BentoTypographyElement), mapping: BentoTypographyElement, control: { type: 'select', }, }, variant: { options: Object.values(BentoTypographyVariant), mapping: BentoTypographyVariant, control: { type: 'select', }, }, }, }; export default meta; type Story = StoryObj<typeof BentoTypography>; const SIZES_DISABLED_ARG_TYPES = { small: { table: { disable: true } }, medium: { table: { disable: true } }, large: { table: { disable: true } }, }; const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args"> {{args.default}} </bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), }; export const Caption: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, strongest: { table: { disable: true } }, }, args: { default: 'Caption text', variant: 'caption' }, parameters: storybookDocsParameter('<bento-typography variant="caption">Caption text</bento-typography>'), }; export const Body: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, stronger: { if: { arg: 'strongest', truthy: false } }, strongest: { if: { arg: 'stronger', truthy: false } }, }, args: { default: 'Body text', variant: 'body' }, parameters: storybookDocsParameter('<bento-typography :variant="body">Body text</bento-typography>'), }; export const Title: Story = { ...Default, argTypes: { variant: { table: { disable: true } }, stronger: { table: { disable: true } }, strongest: { table: { disable: true } }, wide: { table: { disable: true } }, medium: { if: { arg: 'large', truthy: false } }, large: { if: { arg: 'medium', truthy: false } }, }, args: { default: 'Title text', variant: 'title' }, parameters: storybookDocsParameter('<bento-typography :variant="title">Title text</bento-typography>'), }; const richTextTemplate = ` <h1>Heading 1</h1> <p><strong>Bento</strong> is a scalable <mark>design system</mark> that enables product teams within <em>Adyen</em> to create the <ins>best user experiences and interfaces</ins>, all built on <del>solid</del> principles like usability, consistency, and accessibility. </p> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ul> </ul> </ul> <blockquote>"Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility."</blockquote> <h2>Heading 2</h2> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ol> </ol> </ol> <pre> function welcomeBento() { console.log('Welcome to Bento design system') }</pre> <h3>Heading 3</h3> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <code>Inline code example</code> <h4>Heading 4</h4> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <table> <caption> Front-end web developer course 2021 </caption> <thead> <tr> <th scope="col">Person</th> <th scope="col">Most interest in</th> <th scope="col">Age</th> </tr> </thead> <tbody> <tr> <th scope="row">Chris</th> <td>HTML tables</td> <td>22</td> </tr> <tr> <th scope="row">Elizabeth</th> <td>Web accessibility</td> <td>45</td> </tr> <tr> <th scope="row">Sarah</th> <td>JavaScript frameworks</td> <td>29</td> </tr> <tr> <th scope="row">John</th> <td>Web performance</td> <td>36</td> </tr> </tbody> <tfoot> <tr> <th scope="row" colspan="2" align="right">Average age</th> <td>33</td> </tr> </tfoot> </table> <h5>Heading 5</h5> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <h6>Heading 6</h6> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> `; const richTextCode = ` <bento-typography el="div" rich-text>${richTextTemplate}</bento-typography> `; export const RichText: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args">${richTextTemplate}</bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), args: { el: 'div', richText: true }, parameters: storybookDocsParameter(richTextCode), };
1
+ import BentoTypography from './typography.vue'; import { BentoTypographyElement, BentoTypographyVariant } from './typography.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { isVue2 } from 'vue-demi'; import type { Meta, StoryObj } from '@storybook/vue'; const TypographyBodyExample = "<template>\n <bento-typography variant=\"body\">Body text</bento-typography>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoTypography } from '@adyen/bento-vue2';\n</script>\n"; const TypographyCaptionExample = "<template>\n <bento-typography variant=\"caption\">Caption text</bento-typography>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoTypography } from '@adyen/bento-vue2';\n</script>\n"; const TypographyRichTextExample = "<template>\n <bento-typography el=\"div\" rich-text>\n <h1>Heading 1</h1>\n <p>\n <strong>Bento</strong> is a scalable <mark>design system</mark> that enables product teams within\n <em>Adyen</em> to create the <ins>best user experiences and interfaces</ins>, all built on\n <del>solid</del> principles like usability, consistency, and accessibility.\n </p>\n <ul>\n <li>Item One</li>\n <li>Item Two</li>\n <li>\n <ul>\n <li>Item One</li>\n <li>Item Two</li>\n <li>\n <ul>\n <li>Item One</li>\n <li>Item Two</li>\n <li>Item Three</li>\n </ul>\n </li>\n </ul>\n </li>\n </ul>\n <blockquote>\n \"Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\"\n </blockquote>\n <h2>Heading 2</h2>\n <p>\n Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\n </p>\n <ol>\n <li>Item One</li>\n <li>Item Two</li>\n <li>\n <ol>\n <li>Item One</li>\n <li>Item Two</li>\n <li>\n <ol>\n <li>Item One</li>\n <li>Item Two</li>\n <li>Item Three</li>\n </ol>\n </li>\n </ol>\n </li>\n </ol>\n <pre>\nfunction welcomeBento() {\n console.log('Welcome to Bento design system')\n}</pre\n >\n <h3>Heading 3</h3>\n <p>\n Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\n </p>\n <code>Inline code example</code>\n <h4>Heading 4</h4>\n <p>\n Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\n </p>\n <table>\n <caption> Front-end web developer course 2021 </caption>\n <thead>\n <tr>\n <th scope=\"col\">Person</th>\n <th scope=\"col\">Most interest in</th>\n <th scope=\"col\">Age</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th scope=\"row\">Chris</th>\n <td>HTML tables</td>\n <td>22</td>\n </tr>\n <tr>\n <th scope=\"row\">Elizabeth</th>\n <td>Web accessibility</td>\n <td>45</td>\n </tr>\n <tr>\n <th scope=\"row\">Sarah</th>\n <td>JavaScript frameworks</td>\n <td>29</td>\n </tr>\n <tr>\n <th scope=\"row\">John</th>\n <td>Web performance</td>\n <td>36</td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <th scope=\"row\" colspan=\"2\" align=\"right\">Average age</th>\n <td>33</td>\n </tr>\n </tfoot>\n </table>\n <h5>Heading 5</h5>\n <p>\n Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\n </p>\n <h6>Heading 6</h6>\n <p>\n Bento is a scalable design system that enables product teams within Adyen to create the best user\n experiences and interfaces, all built on principles like usability, consistency, and accessibility.\n </p>\n </bento-typography>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoTypography } from '@adyen/bento-vue2';\n</script>\n"; const TypographyTitleExample = "<template>\n <bento-typography variant=\"title\">Title text</bento-typography>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoTypography } from '@adyen/bento-vue2';\n</script>\n"; const meta: Meta = { title: 'Typography', component: BentoTypography, argTypes: { default: { name: 'default', defaultValue: '', description: 'typography text', table: { type: { summary: 'VNode[]' }, }, control: { type: 'text', }, }, el: { options: Object.values(BentoTypographyElement), mapping: BentoTypographyElement, control: { type: 'select', }, }, variant: { options: Object.values(BentoTypographyVariant), mapping: BentoTypographyVariant, control: { type: 'select', }, }, }, }; export default meta; type Story = StoryObj<typeof BentoTypography>; const SIZES_DISABLED_ARG_TYPES = { small: { table: { disable: true } }, medium: { table: { disable: true } }, large: { table: { disable: true } }, }; const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args"> {{args.default}} </bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), }; export const Caption: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, strongest: { table: { disable: true } }, }, args: { default: 'Caption text', variant: 'caption' }, parameters: storybookDocsParameter(TypographyCaptionExample), }; export const Body: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, stronger: { if: { arg: 'strongest', truthy: false } }, strongest: { if: { arg: 'stronger', truthy: false } }, }, args: { default: 'Body text', variant: 'body' }, parameters: storybookDocsParameter(TypographyBodyExample), }; export const Title: Story = { ...Default, argTypes: { variant: { table: { disable: true } }, stronger: { table: { disable: true } }, strongest: { table: { disable: true } }, wide: { table: { disable: true } }, medium: { if: { arg: 'large', truthy: false } }, large: { if: { arg: 'medium', truthy: false } }, }, args: { default: 'Title text', variant: 'title' }, parameters: storybookDocsParameter(TypographyTitleExample), }; const richTextTemplate = ` <h1>Heading 1</h1> <p><strong>Bento</strong> is a scalable <mark>design system</mark> that enables product teams within <em>Adyen</em> to create the <ins>best user experiences and interfaces</ins>, all built on <del>solid</del> principles like usability, consistency, and accessibility. </p> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ul> </ul> </ul> <blockquote>"Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility."</blockquote> <h2>Heading 2</h2> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ol> </ol> </ol> <pre> function welcomeBento() { console.log('Welcome to Bento design system') }</pre> <h3>Heading 3</h3> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <code>Inline code example</code> <h4>Heading 4</h4> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <table> <caption> Front-end web developer course 2021 </caption> <thead> <tr> <th scope="col">Person</th> <th scope="col">Most interest in</th> <th scope="col">Age</th> </tr> </thead> <tbody> <tr> <th scope="row">Chris</th> <td>HTML tables</td> <td>22</td> </tr> <tr> <th scope="row">Elizabeth</th> <td>Web accessibility</td> <td>45</td> </tr> <tr> <th scope="row">Sarah</th> <td>JavaScript frameworks</td> <td>29</td> </tr> <tr> <th scope="row">John</th> <td>Web performance</td> <td>36</td> </tr> </tbody> <tfoot> <tr> <th scope="row" colspan="2" align="right">Average age</th> <td>33</td> </tr> </tfoot> </table> <h5>Heading 5</h5> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <h6>Heading 6</h6> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> `; export const RichText: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args">${richTextTemplate}</bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), args: { el: 'div', richText: true }, parameters: storybookDocsParameter(TypographyRichTextExample), };
@@ -1 +1 @@
1
- /** * @deprecated Since v2.0.0. Use string literal instead. */ export enum BentoTypographyVariant { CAPTION = 'caption', BODY = 'body', /** @deprecated Since v2.0.0. Use `TITLE` instead. */ SUBTITLE = 'subtitle', TITLE = 'title', } export enum BentoTypographyModifier { WIDE = 'wide', STRONGER = 'stronger', STRONGER_WIDE = 'stronger-wide', STRONGEST = 'strongest', STRONGEST_WIDE = 'strongest-wide', MEDIUM = 'm', LARGE = 'l', MOBILE = 'mobile', MONOSPACE = 'monospace', } /** * @deprecated Since v2.0.0. Use string literal instead. */ export enum BentoTypographyElement { H1 = 'h1', H2 = 'h2', H3 = 'h3', H4 = 'h4', H5 = 'h5', H6 = 'h6', DIV = 'div', PARAGRAPH = 'p', SPAN = 'span', } export interface BentoTypographyProps { /** * Sets the HTML DOM element. * @values h1, h2, h3, h4, h5, h6, div, p, span */ el?: BentoTypographyElement | `${BentoTypographyElement}`; /** * Adds the large class modifier. * Applicable to the Title variant. */ large?: boolean; /** * Adds the medium class modifier. * Applicable to the Title variant. */ medium?: boolean; /** * Changes the font family to monospace. * Applicable to all variants. */ monospace?: boolean; /** * Adds the rich-text modifier, which allows for the use of HTML tags inside typography. */ richText?: boolean; /** * Adds the stronger class modifier. * Applicable to Caption, Body and Subtitle variants. */ stronger?: boolean; /** * Adds the strongest class modifier. * Applicable to Caption, Body and Subtitle variants. */ strongest?: boolean; /** * Sets the type of typography variant. * @values caption, body, title. */ variant?: BentoTypographyVariant | `${BentoTypographyVariant}`; /** * Adds the medium class modifier. * Applicable to the Body variant. */ wide?: boolean; }
1
+ /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoTypographyVariant { CAPTION = 'caption', BODY = 'body', /** @deprecated Since v3.0.0. Use `TITLE` instead. */ SUBTITLE = 'subtitle', TITLE = 'title', } export enum BentoTypographyModifier { WIDE = 'wide', STRONGER = 'stronger', STRONGER_WIDE = 'stronger-wide', STRONGEST = 'strongest', STRONGEST_WIDE = 'strongest-wide', MEDIUM = 'm', LARGE = 'l', MOBILE = 'mobile', MONOSPACE = 'monospace', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoTypographyElement { H1 = 'h1', H2 = 'h2', H3 = 'h3', H4 = 'h4', H5 = 'h5', H6 = 'h6', DIV = 'div', PARAGRAPH = 'p', SPAN = 'span', } export interface BentoTypographyProps { /** * Sets the HTML DOM element. * @values h1, h2, h3, h4, h5, h6, div, p, span */ el?: BentoTypographyElement | `${BentoTypographyElement}`; /** * Adds the large class modifier. * Applicable to the Title variant. */ large?: boolean; /** * Adds the medium class modifier. * Applicable to the Title variant. */ medium?: boolean; /** * Changes the font family to monospace. * Applicable to all variants. */ monospace?: boolean; /** * Adds the rich-text modifier, which allows for the use of HTML tags inside typography. */ richText?: boolean; /** * Adds the stronger class modifier. * Applicable to Caption, Body and Subtitle variants. */ stronger?: boolean; /** * Adds the strongest class modifier. * Applicable to Caption, Body and Subtitle variants. */ strongest?: boolean; /** * Sets the type of typography variant. * @values caption, body, title. */ variant?: BentoTypographyVariant | `${BentoTypographyVariant}`; /** * Adds the medium class modifier. * Applicable to the Body variant. */ wide?: boolean; }
@@ -1 +1 @@
1
- <template> <component :is="el" class="b-typography" :class="conditionalClasses" data-testid="typography"> <slot /> </component> </template> <script setup lang="ts"> import { computed, onMounted } from 'vue'; import { deprecate } from '@/utils/ts/deprecate'; import { BentoTypographyElement, BentoTypographyModifier, type BentoTypographyProps, BentoTypographyVariant, } from './typography.types'; const props = withDefaults(defineProps<BentoTypographyProps>(), { el: BentoTypographyElement.PARAGRAPH, large: false, medium: false, monospace: false, stronger: false, strongest: false, variant: BentoTypographyVariant.BODY, wide: false, }); if (props.variant === BentoTypographyVariant.SUBTITLE) { deprecate( 'BentoTypography "subtitle" variant (BentoTypographyVariant.SUBTITLE)', `Use the "title" or "BentoTypographyVariant.TITLE" variant and (optionally) combine it with a size property. e.g. medium / large. <bento-typography :variant="BentoTypographyVariant.TITLE" medium>`, '2.0.0' ); } const conditionalClasses = computed(() => ({ // Rich text ['b-typography--rich-text']: props.richText, // Monospace [`b-typography--${BentoTypographyModifier.MONOSPACE}`]: props.monospace, // Caption [`b-typography--${BentoTypographyVariant.CAPTION}`]: props.variant === BentoTypographyVariant.CAPTION, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.CAPTION && props.wide, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.CAPTION && props.stronger, // Body [`b-typography--${BentoTypographyVariant.BODY}`]: props.variant === BentoTypographyVariant.BODY, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.BODY && props.wide, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.BODY && props.stronger, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGEST}`]: props.variant === BentoTypographyVariant.BODY && props.strongest, // Subtitle [`b-typography--${BentoTypographyVariant.SUBTITLE}`]: props.variant === BentoTypographyVariant.SUBTITLE, [`b-typography--${BentoTypographyVariant.SUBTITLE}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.SUBTITLE && props.stronger, // Title [`b-typography--${BentoTypographyVariant.TITLE}`]: props.variant === BentoTypographyVariant.TITLE && !props.medium && !props.large, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.MEDIUM}`]: props.variant === BentoTypographyVariant.TITLE && props.medium, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.LARGE}`]: props.variant === BentoTypographyVariant.TITLE && props.large, })); onMounted(() => { if (props.richText && props.el !== 'div') { throw new Error('Rich-text prop must be used with el="div" for correct HTML semantics'); } if (props.richText && props.variant === 'title') { throw new Error('Rich-text prop cannot be used with the title variant.'); } if (props.richText && props.variant === 'subtitle') { throw new Error('Rich-text prop cannot be used with the subtitle variant.'); } }); </script> <script lang="ts"> /** * The Typography component makes it easy to apply a default set of font weights, sizes and other text styles * easily to text. The variants and properties match with those found in Figma. * * For example, seeing text with the typography styling of * * @example * import { BentoTypography } from '@adyen/bento-vue2'; * * export default { * components: { BentoTypography }, * template: ` * <bento-typography> * ... text content * </bento-typography> * ` * } */ export default { name: 'bento-typography', inheritAttrs: true, }; </script> <style lang="scss" scoped src="./typography.scss" />
1
+ <template> <component :is="el" class="b-typography" :class="conditionalClasses" data-testid="typography"> <slot /> </component> </template> <script setup lang="ts"> import { computed, onMounted } from 'vue'; import { deprecate } from '@/utils/ts/deprecate'; import { BentoTypographyElement, BentoTypographyModifier, type BentoTypographyProps, BentoTypographyVariant, } from './typography.types'; const props = withDefaults(defineProps<BentoTypographyProps>(), { el: BentoTypographyElement.PARAGRAPH, large: false, medium: false, monospace: false, stronger: false, strongest: false, variant: BentoTypographyVariant.BODY, wide: false, }); if (props.variant === BentoTypographyVariant.SUBTITLE) { deprecate( 'BentoTypography "subtitle" variant (BentoTypographyVariant.SUBTITLE)', `Use the "title" or "BentoTypographyVariant.TITLE" variant and (optionally) combine it with a size property. e.g. medium / large. <bento-typography :variant="BentoTypographyVariant.TITLE" medium>`, '3.0.0' ); } const conditionalClasses = computed(() => ({ // Rich text ['b-typography--rich-text']: props.richText, // Monospace [`b-typography--${BentoTypographyModifier.MONOSPACE}`]: props.monospace, // Caption [`b-typography--${BentoTypographyVariant.CAPTION}`]: props.variant === BentoTypographyVariant.CAPTION, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.CAPTION && props.wide, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.CAPTION && props.stronger, // Body [`b-typography--${BentoTypographyVariant.BODY}`]: props.variant === BentoTypographyVariant.BODY, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.BODY && props.wide, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.BODY && props.stronger, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGEST}`]: props.variant === BentoTypographyVariant.BODY && props.strongest, // Subtitle [`b-typography--${BentoTypographyVariant.SUBTITLE}`]: props.variant === BentoTypographyVariant.SUBTITLE, [`b-typography--${BentoTypographyVariant.SUBTITLE}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.SUBTITLE && props.stronger, // Title [`b-typography--${BentoTypographyVariant.TITLE}`]: props.variant === BentoTypographyVariant.TITLE && !props.medium && !props.large, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.MEDIUM}`]: props.variant === BentoTypographyVariant.TITLE && props.medium, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.LARGE}`]: props.variant === BentoTypographyVariant.TITLE && props.large, })); onMounted(() => { if (props.richText && props.el !== 'div') { throw new Error('Rich-text prop must be used with el="div" for correct HTML semantics'); } if (props.richText && props.variant === 'title') { throw new Error('Rich-text prop cannot be used with the title variant.'); } if (props.richText && props.variant === 'subtitle') { throw new Error('Rich-text prop cannot be used with the subtitle variant.'); } }); </script> <script lang="ts"> /** * The Typography component makes it easy to apply a default set of font weights, sizes and other text styles * easily to text. The variants and properties match with those found in Figma. * * For example, seeing text with the typography styling of * * @example * import { BentoTypography } from '@adyen/bento-vue2'; * * export default { * components: { BentoTypography }, * template: ` * <bento-typography> * ... text content * </bento-typography> * ` * } */ export default { name: 'bento-typography', inheritAttrs: true, }; </script> <style lang="scss" scoped src="./typography.scss" />
@@ -74,6 +74,7 @@
74
74
  "pagination",
75
75
  "payment-method",
76
76
  "popover",
77
+ "progress-bar",
77
78
  "promo-banner",
78
79
  "radio-button",
79
80
  "radio-group",
@@ -0,0 +1 @@
1
+ export * from './use-bento-base-filter';
@@ -0,0 +1 @@
1
+ import { computed, onMounted, ref, watch } from 'vue'; import type { Ref } from 'vue'; import { copyStructure, deepCopy, isEqual, isValueEmpty } from './utils'; /** * A composable to wire the `bento-base-filter` component for the mandatory fields and events. * * @usage * ```vue * <template> * <bento-base-filter * :disable-apply-button="isApplyButtonDisabled" * :disable-secondary-button="isSecondaryButtonDisabled" * @ apply="updateFilter" * @ clear="clearFilter(updateFilter)" * @ open="openFilter" * @ reset="resetFilter(updateFilter)" * > * <!-- CONTENT HERE --> * </bento-base-filter> * </template> * <script> * import { ref } from 'vue' * import { useBentoBaseFilter, BentoBaseFilter, BentoBaseFilterProps } from '@adyen/bento-vue2' * * type CustomFilterValue = boolean * const props = defineProps<BentoBaseFilterProps<CustomFilterValue>>(); * * const { * // Values * internalFilterValue, * isSecondaryButtonDisabled, * isApplyButtonDisabled, * * // Methods * clearFilter, * resetFilter, * openFilter, * } = useBentoBaseFilter<CustomFilterValue>(toRef(props, 'value'), toRef(props, 'defaultValue')); * </script> * ``` * * @param appliedFilter The currently applied filter value. * @param defaultFilter The default filter value (if available). * @returns An object containing refs and functions: * - `internalFilterValue`: The temporary state of the filter before it's applied. * - `isSecondaryButtonDisabled`: `true` if the secondary (clear/reset) button should be disabled. * - `isApplyButtonDisabled`: `true` if the apply button should be disabled. * - `clearFilter`: Clears the filter to its initial or default state. * - `resetFilter`: Resets the filter to its default state. * - `openFilter`: Syncs the internal state with the applied filter. */ export function useBentoBaseFilter<T>(appliedFilter: Ref<T>, defaultFilter: Ref<T>) { /** * Handles the internal value. Kept in sync when the new value is applied */ const internalFilterValue = ref<T>(); const initialStructureOrValue = ref<T>(); onMounted(() => { /** * Copy initial structure as long as the value is not "undefined" */ if (appliedFilter.value != null) { initialStructureOrValue.value = copyStructure<T>(appliedFilter.value) as T; } }); watch( () => appliedFilter.value, newValue => { internalFilterValue.value = deepCopy<T>(newValue); }, { immediate: true } ); /** * Indicates if the filter has a value applied (active). * - inactive (`true`): `appliedFilter` is empty (`undefined`) or all of its properties are empty for object values */ const isFilterInactive = computed( () => isValueEmpty(appliedFilter.value) || isEqual<T>(appliedFilter.value, initialStructureOrValue.value) ); /** * Indicates if the secondary (clear/reset) button should be disabled. * - disabled (`true`): No filter value is applied or `appliedFilter` value is the same as the `defaultFilter` (persistent) value */ const isSecondaryButtonDisabled = computed(() => defaultFilter.value != null ? isEqual<T>(defaultFilter.value, appliedFilter.value) : isFilterInactive.value ); const isApplyButtonDisabled = computed(() => { const isValueUnchanged = isEqual<T>(internalFilterValue.value, appliedFilter.value); return isValueUnchanged || (isValueEmpty(internalFilterValue.value) && isFilterInactive.value); }); /** * Clears the non-persistent filters (not used in persistent filters). * * Receives a callback to execute additional tasks required when clearing a filter * * - `object`: Sets all properties to `undefined` * - non-`object`: Sets to `undefined` * @param callback Function to be called when clearing a filter */ function clearFilter(callback?: (newValue: T) => void) { internalFilterValue.value = deepCopy<T>(initialStructureOrValue.value); if (callback) { callback(internalFilterValue.value); } } /** * Resets the persistent filters (not used in non-persistent filters). * Sets the `internalFilterValue` * * Receives a callback to execute additional tasks required when resetting a filter. * @param callback Function to be called when resetting a filter */ function resetFilter(callback?: (newValue: T) => void) { internalFilterValue.value = deepCopy<T>(defaultFilter.value); if (callback) { callback(internalFilterValue.value); } } /** * Sets the value to what is applied when opening a filter. * @param callback Function to be called when opening a filter */ function openFilter(callback?: (newValue: T) => void) { // Reset value every time it opens internalFilterValue.value = deepCopy<T>(appliedFilter.value); if (callback) { callback(internalFilterValue.value); } } return { // Values internalFilterValue, isSecondaryButtonDisabled, isApplyButtonDisabled, // Methods clearFilter, resetFilter, openFilter, }; }
@@ -0,0 +1 @@
1
+ export * from './utils';
@@ -0,0 +1 @@
1
+ /** * Checks if a value is a plain object. * * @param value The value to check. * @returns Whether the value is a plain object. */ export const isPlainObject = (value: unknown) => { if (value === null || typeof value !== 'object') { return false; } return Object.prototype.toString.call(value) === '[object Object]'; }; /** * Checks if a value is an array. * * @param value The value to check. * @returns Whether the value is an array. */ export const isArray = <T>(value: T) => Array.isArray(value); /** * Checks if a value is empty. * If the value is an array, it checks if the array is empty or if all elements are empty strings. * If the value is not an array, it checks if the value is falsy. * * @param value The value to check. * @returns Whether the value is empty. */ export const isValueEmpty = <T>(value: T) => isArray(value) ? (value as []).length === 0 || (value as Array<T>).every(el => el === '') : !value; /** * Checks if two objects are deeply equal by comparing their JSON string representations. * * @param first The first value. * @param second The second value. * @returns Whether the values are equal. */ export const isEqual = <T>(first: T, second: T) => JSON.stringify(first) === JSON.stringify(second); /** * Creates a deep copy of a value. * Recursively copies an object or array to return the original value. * Otherwise, it returns the value as is. * * @param value The value to copy. * @returns The deep copied value or the original value if it's not a plain object or array. */ export const deepCopy = <T>(value: T) => { if (!isPlainObject(value)) { return value; } // If it's a Date, make a copy if (value instanceof Date) { return new Date(value.getTime()) as T; } // If it's an array, map over it and deep copy each item if (isArray(value)) { return value.map(item => deepCopy(item)) as T; } // If it's an object, iterate over its keys and deep copy each value return Object.keys(value).reduce((acc, key) => { acc[key] = deepCopy(value[key]); return acc; }, {}); }; /** * Copies the structure of a plain object, setting all values to `undefined`. * If the value is not a plain object, it returns `undefined`. * * @param value The object whose structure to copy. * @returns An object with the same keys as the input object but with all values set to `undefined`, or `undefined` if the input is not a plain object. */ export const copyStructure = <T>(value: T) => isPlainObject(value) ? Object.fromEntries(Object.keys(value).map(key => [key, undefined])) : undefined;
@@ -0,0 +1 @@
1
+ export * from './use-bento-currency';
@@ -1 +1 @@
1
- import { BentoInputField } from '@/components/input-field'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import { computed, ref } from 'vue'; import { useBentoCurrency } from './use-bento-currency'; import UseBentoCurrencyExample from './__tests__/use-bento-currency-example.vue?raw'; import { storybookDocsParameter } from '@/utils/ts/storybook'; const meta: Meta = { title: 'useBentoCurrency', }; export default meta; export const Default: StoryObj = { render: () => ({ components: { BentoInputField, BentoTypography }, template: ` <div> <bento-input-field v-model="input" label="Format Currency to BHD" /> <bento-typography>Formatted Currency: {{ formattedCurrency }}</bento-typography> </div> `, setup() { const input = ref('123456789'); const { formatCurrency } = useBentoCurrency(); const formattedCurrency = computed(() => { return formatCurrency(input.value, { currency: 'EUR' }); }); return { input, formattedCurrency, }; }, }), parameters: storybookDocsParameter(UseBentoCurrencyExample), };
1
+ import { BentoInputField } from '@/components/input-field'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import { computed, ref } from 'vue'; import { useBentoCurrency } from './use-bento-currency'; const UseBentoCurrencyExample = "<template>\n <div>\n <bento-input-field v-model=\"input\" />\n <bento-typography>Formatted Currency: {{ formattedCurrency }}</bento-typography>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { BentoInputField, BentoTypography } from '@adyen/bento-vue2';\n import { useBentoCurrency } from '../use-bento-currency';\n import { computed, ref } from 'vue';\n\n const input = ref('123456789');\n\n const { formatCurrency } = useBentoCurrency();\n\n const formattedCurrency = computed(() => {\n return formatCurrency(input.value, { currency: 'EUR' });\n });\n</script>\n"; import { storybookDocsParameter } from '@/utils/ts/storybook'; const meta: Meta = { title: 'useBentoCurrency', }; export default meta; export const Default: StoryObj = { render: () => ({ components: { BentoInputField, BentoTypography }, template: ` <div> <bento-input-field v-model="input" label="Format Currency to BHD" /> <bento-typography>Formatted Currency: {{ formattedCurrency }}</bento-typography> </div> `, setup() { const input = ref('123456789'); const { formatCurrency } = useBentoCurrency(); const formattedCurrency = computed(() => { return formatCurrency(input.value, { currency: 'EUR' }); }); return { input, formattedCurrency, }; }, }), parameters: storybookDocsParameter(UseBentoCurrencyExample), };
@@ -0,0 +1 @@
1
+ import { getMinorUnitDigits, getNonStandardCurrency, getNormalizedAmount } from '@/utils/ts/currency'; import { useI18n } from '@/utils/ts/i18n'; import { printDevelopmentWarning } from '@/utils/ts/print-development-warning'; import { type BentoCurrencyISOCode } from '../../components/currency/currency.types'; export interface UseBentoCurrencyFormatCurrencyOptions { currency?: `${BentoCurrencyISOCode}`; currencySign?: Intl.NumberFormatOptions['currencySign']; majorUnits?: boolean; } export interface UseBentoCurrencyParts { /** * The localized number portion of the formatted currency. */ currencyNumber: string; /** * The ISO currency code used for formatting. */ currencyCode: string; /** * The complete formatted currency string. */ formattedCurrency: string; } const DEFAULT_CURRENCY = 'USD'; /** * A composable that returns a fully formatted and localized currency string. * It enforces the format `[localized number][non-breaking space][ISO code]`. * * @remarks * The formatting process involves several steps: * 1. It safely resolves the input `value`, whether it's from a prop or a slot, into a valid number. * * 2. If `majorUnits` is false, it converts the amount from minor units to major units * (e.g., cents to dollars) by dividing by 10 to the power of the currency's * decimal places (the "exponent"). For example, `12345 / (10 ** 2)` becomes `123.45`. * * 3. It determines the correct number of decimal places, respecting any non-standard * currency exceptions. * * 4. It uses `vue-i18n` to format the number with the correct sign placement and decimal/thousand * separators for the current locale, then manually reconstructs the string to ensure * the ISO code is always at the end. * * @returns An object with a function to format the currency string. */ export function useBentoCurrency() { const { n } = useI18n(); const DEFAULT_CURRENCY_SIGN = 'standard'; /** * Resolves the shared formatting details used by currency string and currency parts formatters. * * @param amount The numeric value to be formatted. If `formatOptions.majorUnits` is `false` or undefined, * this value is treated as being in the currency's minor units (e.g., cents). * @param formatOptions An optional object containing options for currency formatting. * * @returns The localized number and ISO currency code. */ const getCurrencyFormatDetails = ( amount: string | number, formatOptions?: UseBentoCurrencyFormatCurrencyOptions ) => { const targetCurrency = formatOptions?.currency ?? DEFAULT_CURRENCY; // Parse and Fallback const parsedValue = Number(amount) || 0; if (isNaN(Number(amount))) { printDevelopmentWarning( 'The value provided is not a valid string with numbers or valid number. Falling back to 0.' ); } // Normalize Amount const normalizedAmount = formatOptions?.majorUnits ? parsedValue : getNormalizedAmount(parsedValue, targetCurrency); // Determine Precision const fractionDigits = getNonStandardCurrency(targetCurrency)?.exponent ?? getMinorUnitDigits(targetCurrency); // Format with Locale const localizedCurrencyString = n(normalizedAmount, { style: 'currency', currency: targetCurrency, currencySign: formatOptions?.currencySign ?? DEFAULT_CURRENCY_SIGN, currencyDisplay: 'code', minimumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits, }); // Enforce Standard Format: `[number][nbsp][code]` const isoCodeRegex = new RegExp(`\\s*${targetCurrency}\\s*`); const numberPart = localizedCurrencyString.replace(isoCodeRegex, ''); return { currencyNumber: numberPart, currencyCode: targetCurrency, }; }; /** * Formats a given amount into a localized currency string with a specific structure. * * This function ensures that the output format is always `[localized number][non-breaking space][ISO code]`, * providing a consistent and predictable currency representation across different locales. * * @param amount The numeric value to be formatted. If `formatOptions.majorUnits` is `false` or undefined, * this value is treated as being in the currency's minor units (e.g., cents). * @param formatOptions An optional object containing options for currency formatting. * - `currency`: The 3-letter ISO currency code (e.g., `'USD'`, `'EUR'`). Defaults to `'USD'`. * - `currencySign`: The currency sign to use. Can be `'standard'` or `'accounting'`. Defaults to `'standard'`. In `accounting` mode, negative values are typically wrapped in parentheses. * - `majorUnits`: Set to `true` if the `amount` is already in major units (e.g., dollars instead of cents). Defaults to `false`. * * @returns A fully formatted and localized currency string (e.g., "1,234.56 EUR"). */ const formatCurrency = (amount: string | number, formatOptions?: UseBentoCurrencyFormatCurrencyOptions): string => formatCurrencyParts(amount, formatOptions).formattedCurrency; /** * Formats a given amount into separate currency parts for consumers that need custom markup. * * This function reuses the shared currency formatting details to keep parsing, normalization, precision, locale formatting, * and final string construction aligned with the standard currency formatter. * * @param amount The numeric value to be formatted. If `formatOptions.majorUnits` is `false` or undefined, * this value is treated as being in the currency's minor units (e.g., cents). * @param formatOptions An optional object containing options for currency formatting. * * @returns The localized number, ISO currency code, and complete formatted currency string. */ const formatCurrencyParts = ( amount: string | number, formatOptions?: UseBentoCurrencyFormatCurrencyOptions ): UseBentoCurrencyParts => { const { currencyNumber, currencyCode } = getCurrencyFormatDetails(amount, formatOptions); return { currencyNumber, currencyCode, formattedCurrency: `${currencyNumber}\u00A0${currencyCode}`, }; }; return { formatCurrency, formatCurrencyParts, }; }
@@ -0,0 +1 @@
1
+ export * from './use-bento-delayed-hover';
@@ -1 +1 @@
1
- import type { Meta, StoryObj } from '@storybook/vue'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoLink } from '@/components/link'; import { BentoPopover } from '@/components/popover'; import { BentoTag } from '@/components/tag'; import { BentoTypography } from '@/components/typography'; import { useBentoDelayedHover } from './use-bento-delayed-hover'; import UseBentoDelayedHoverExample from './__tests__/use-bento-delayed-hover-example.vue?raw'; const meta: Meta = { title: 'useBentoDelayedHover', }; export default meta; export const Default: StoryObj = { render: () => ({ components: { BentoLink, BentoPopover, BentoTag, BentoTypography }, setup() { const triggerElement = ref(null); const { isOpen, open, close, hoverEvents } = useBentoDelayedHover(); return { isOpen, open, close, triggerElement, hoverEvents }; }, template: ` <div> <bento-tag ref="triggerElement" label="Hover over me" tabindex="0" :aria-expanded="isOpen.toString()" aria-controls="delayed-hover-popover" @mouseenter.native="open" @mouseleave.native="close" @focusin.native="open" @focusout.native="close" /> <span v-on="hoverEvents"> <bento-popover v-if="triggerElement" id="delayed-hover-popover" :open="isOpen" :target-element="triggerElement" role="tooltip" disable-focus-trap > <bento-typography el="span"> Add your text here <bento-link to="https://www.adyen.com/" external>Learn more here</bento-link> </bento-typography> </bento-popover> </span> </div> `, }), parameters: storybookDocsParameter(UseBentoDelayedHoverExample), };
1
+ import type { Meta, StoryObj } from '@storybook/vue'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoLink } from '@/components/link'; import { BentoPopover } from '@/components/popover'; import { BentoTag } from '@/components/tag'; import { BentoTypography } from '@/components/typography'; import { useBentoDelayedHover } from './use-bento-delayed-hover'; const UseBentoDelayedHoverExample = "<template>\n <div>\n <bento-tag\n ref=\"triggerElement\"\n label=\"Hover over me\"\n tabindex=\"0\"\n :aria-expanded=\"isOpen.toString()\"\n aria-controls=\"popover-id\"\n @mouseenter.native=\"open\"\n @mouseleave.native=\"close\"\n @focusin.native=\"open\"\n @focusout.native=\"close\"\n />\n\n <span v-on=\"hoverEvents\">\n <bento-popover\n v-if=\"triggerElement\"\n id=\"popover-id\"\n :open=\"isOpen\"\n position=\"bottom-start\"\n :target-element=\"triggerElement\"\n role=\"tooltip\"\n disable-focus-trap\n >\n <bento-typography el=\"span\">\n Add your text here\n <bento-link to=\"https://www.adyen.com/\" external>Learn more here</bento-link>\n </bento-typography>\n </bento-popover>\n </span>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\n import { BentoLink, BentoPopover, BentoTag, BentoTypography, useBentoDelayedHover } from '@adyen/bento-vue2';\n import { ref } from 'vue';\n\n const triggerElement = ref(null);\n const { isOpen, open, close, hoverEvents } = useBentoDelayedHover();\n</script>\n"; const meta: Meta = { title: 'useBentoDelayedHover', }; export default meta; export const Default: StoryObj = { render: () => ({ components: { BentoLink, BentoPopover, BentoTag, BentoTypography }, setup() { const triggerElement = ref(null); const { isOpen, open, close, hoverEvents } = useBentoDelayedHover(); return { isOpen, open, close, triggerElement, hoverEvents }; }, template: ` <div> <bento-tag ref="triggerElement" label="Hover over me" tabindex="0" :aria-expanded="isOpen.toString()" aria-controls="delayed-hover-popover" @mouseenter.native="open" @mouseleave.native="close" @focusin.native="open" @focusout.native="close" /> <span v-on="hoverEvents"> <bento-popover v-if="triggerElement" id="delayed-hover-popover" :open="isOpen" :target-element="triggerElement" role="tooltip" disable-focus-trap > <bento-typography el="span"> Add your text here <bento-link to="https://www.adyen.com/" external>Learn more here</bento-link> </bento-typography> </bento-popover> </span> </div> `, }), parameters: storybookDocsParameter(UseBentoDelayedHoverExample), };
@@ -0,0 +1 @@
1
+ import { useTimeoutFn } from '@vueuse/core'; import { ref } from 'vue'; const DEFAULT_CLOSING_DELAY_MS = 200; /** * A composable that provides the logic to open and close an element on hover and focus with a delay. * @param delay - Delay in milliseconds before closing the element after the cursor or focus * leaves the trigger. Prevents flickering when moving from the trigger to the content. * Defaults to 200. * @returns An object containing the `isOpen` ref, `open`/`close` helpers and a `hoverEvents` * object with the event handlers to bind on the trigger and, when the content is not a descendant * of the trigger, on a wrapper around the content. When using this with `BentoPopover`, pass * `disableFocusTrap` to prevent focus-trap behavior from interfering with delayed closing. */ export const useBentoDelayedHover = (delay: number = DEFAULT_CLOSING_DELAY_MS) => { const isOpen = ref(false); const { start: startClosingTimer, stop: stopClosingTimer } = useTimeoutFn( () => { isOpen.value = false; }, delay, { immediate: false } ); const open = () => { isOpen.value = true; stopClosingTimer(); }; const close = () => { startClosingTimer(); }; const hoverEvents = { mouseenter: open, mouseleave: close, focusin: open, focusout: close, }; return { isOpen, open, close, hoverEvents, }; };
@@ -0,0 +1 @@
1
+ export * from './use-bento-theme'; export * from './use-bento-theme.types';
@@ -1 +1 @@
1
- import { type App, isVue2, type Vue2 } from 'vue-demi'; import { useBentoThemeKey } from './use-bento-theme.types'; import { BentoTheme } from './install.types'; const getTheme = () => document.body.className.match(/b-\w+-theme/)?.[0] ?? ''; const getThemeForSystemPreference = () => { const preferredDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; if (preferredDarkMode) { return BentoTheme.BENTO_DARK; } return BentoTheme.BENTO_LIGHT; }; export const setTheme = (theme: BentoTheme) => { const currentTheme = getTheme(); const systemTheme = getThemeForSystemPreference(); const themeToSet = theme === BentoTheme.BENTO_SYSTEM ? systemTheme : theme; if (themeToSet === BentoTheme.BENTO_LIGHT || themeToSet === BentoTheme.BENTO) { document.documentElement.style.colorScheme = 'light'; } else if (themeToSet === BentoTheme.BENTO_DARK) { document.documentElement.style.colorScheme = 'dark'; } // if theme is different from current and it is not `BentoTheme.BENTO` if (currentTheme.length && currentTheme !== themeToSet) { document.body.classList.remove(currentTheme); } // if theme is not `BentoTheme.BENTO` if (themeToSet.length) { document.body.classList.add(themeToSet); } }; /** * This function is used to create and register global reactive state necessary for theme to operate. * @param {Vue} Vue A context application to register global state with. */ export default Vue => { const themeProvider = { getTheme, setTheme, }; if (isVue2) { // Add theme as a global property as there is no "app.provide" functionality in Vue2 // eslint-disable-next-line no-param-reassign -- this is an official way of setting up instance properties on Vue (Vue as typeof Vue2).prototype[useBentoThemeKey] = themeProvider; } else { (Vue as App).provide(useBentoThemeKey, themeProvider); } };
1
+ import { type App, isVue2, type Vue2 } from 'vue-demi'; import { useBentoThemeKey } from './use-bento-theme.types'; import { BentoTheme } from './install.types'; const getTheme = () => [...document.body.classList].find(cls => /^b-[\w-]+-theme$/.test(cls)) ?? ''; const getThemeForSystemPreference = () => { const preferredDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; if (preferredDarkMode) { return BentoTheme.BENTO_DARK; } return BentoTheme.BENTO_LIGHT; }; export const setTheme = (theme: BentoTheme) => { const currentTheme = getTheme(); const systemTheme = getThemeForSystemPreference(); const themeToSet = theme === BentoTheme.BENTO_SYSTEM ? systemTheme : theme; switch (themeToSet) { case BentoTheme.BENTO_LIGHT: case BentoTheme.BENTO_LARGE_LIGHT: case BentoTheme.BENTO: document.documentElement.style.colorScheme = 'light'; break; case BentoTheme.BENTO_DARK: case BentoTheme.BENTO_LARGE_DARK: document.documentElement.style.colorScheme = 'dark'; break; } // if theme is different from current and it is not `BentoTheme.BENTO` if (currentTheme.length && currentTheme !== themeToSet) { document.body.classList.remove(currentTheme); } // if theme is not `BentoTheme.BENTO` if (themeToSet.length) { document.body.classList.add(themeToSet); } }; /** * This function is used to create and register global reactive state necessary for theme to operate. * @param {Vue} Vue A context application to register global state with. */ export default Vue => { const themeProvider = { getTheme, setTheme, }; if (isVue2) { // Add theme as a global property as there is no "app.provide" functionality in Vue2 // eslint-disable-next-line no-param-reassign -- this is an official way of setting up instance properties on Vue (Vue as typeof Vue2).prototype[useBentoThemeKey] = themeProvider; } else { (Vue as App).provide(useBentoThemeKey, themeProvider); } };
@@ -1 +1 @@
1
- export enum BentoTheme { /** * @deprecated Since v2.0.0. Use `BENTO_LIGHT` instead. */ LEGACY = 'b-legacy-theme', STYLEGUIDE = 'b-styleguide-theme', /** * @deprecated Since v2.0.0. Use `BENTO_LIGHT` instead. */ BENTO = '', BENTO_LIGHT = 'b-light-theme', BENTO_DARK = 'b-dark-theme', BENTO_SYSTEM = 'b-system', }
1
+ export enum BentoTheme { /** * @deprecated Since v3.0.0. Use `BENTO_LIGHT` instead. */ LEGACY = 'b-legacy-theme', STYLEGUIDE = 'b-styleguide-theme', /** * @deprecated Since v3.0.0. Use `BENTO_LIGHT` instead. */ BENTO = '', BENTO_LIGHT = 'b-light-theme', BENTO_DARK = 'b-dark-theme', BENTO_SYSTEM = 'b-system', /** * Bento Large light theme */ BENTO_LARGE_LIGHT = 'b-large-light-theme', /** * Bento Large dark theme */ BENTO_LARGE_DARK = 'b-large-dark-theme', }
@@ -0,0 +1 @@
1
+ import { printDevelopmentWarning } from '@/utils/ts/print-development-warning'; import { getCurrentInstance, inject } from 'vue'; import { isVue2 } from 'vue-demi'; import { type UseBentoTheme, useBentoThemeKey } from './use-bento-theme.types'; /** * Composable that handles theming-related capabilities for the Bento component library. * Requires the use of `BentoPlugin`. * * @example * <script setup lang="ts"> * import { useBentoTheme, BentoTheme } from '@adyen/bento-vue2'; * * const { setTheme } = useBentoTheme(); * * setTheme(BentoTheme.BENTO_DARK) * </script> * * @returns {UseBentoTheme} An object with getter and setter method for the Bento theme. * @returns {Function} getTheme - Returns the current theme in the string form of BentoTheme enum. * @returns {Function} setTheme - Sets the theme of the Bento component library. * */ export function useBentoTheme(): UseBentoTheme { const bentoThemeController = isVue2 ? getCurrentInstance()?.proxy[useBentoThemeKey] : inject(useBentoThemeKey, null); if (!bentoThemeController) { printDevelopmentWarning('useBentoTheme does not work without Vue.use(BentoPlugin)'); // Return placeholder functions so client code won't break, but theme won't toggle return { getTheme: () => undefined, setTheme: () => undefined, }; } // Return a new object so unintentional reassigning its properties won't override a global state return { ...bentoThemeController }; }
@@ -0,0 +1 @@
1
+ export * from './use-bento-toast-controller'; export * from './use-bento-toast-controller.types';
@@ -0,0 +1 @@
1
+ import { computed, ref, type Ref } from 'vue'; import { generateUid } from '@/utils/ts/generate-uid'; import type { BentoToastItemsList, ToastStack } from './use-bento-toast-controller.types'; const dismissToast: (stack: Ref<BentoToastItemsList>, id: string) => void = (stack, id) => { const toastIndex = stack.value.findIndex(toast => toast.id === id); if (toastIndex !== -1) { stack.value.splice(toastIndex, 1); } }; export const toastStackInjectionKey = Symbol('toast-stack'); /** * This utility creates a global reactive state to add new toasts and keep track of them. * @returns {ToastStack} An object that contains reactive stack property with all add toasts and a function to add new toasts */ export const createToastStack: () => ToastStack = () => { const stack = ref<BentoToastItemsList>([]); const addToast = params => { const id = generateUid('toast'); const toast = { ...params, id, dismiss: () => dismissToast(stack, id), }; stack.value.unshift(toast); return { dismiss: () => dismissToast(stack, id), }; }; return { // Even though stack is a reactive property, its content suppose to be only changed from this module. // For this reason we return "stack" as readonly prop, but also return methods that can affect "stack" content. stack: computed(() => Object.freeze(Array.from(stack.value))), /** * A function that allows to add new toasts * @param {Object} params Toast parameters * @param {String} params.text A text to display inside the toast * @param {Object} [params.action] An object that defines action parameters for the toast * @param {String} params.action.text An action button text * @param {Function} params.action.handler A callback that would be called when action button is clicked * @return {Object} An object that includes "dismiss" function to programatically dismiss the toast */ addToast, }; };
@@ -0,0 +1 @@
1
+ import { getCurrentInstance, inject, readonly, ref } from 'vue'; import { isVue2 } from 'vue-demi'; import { printDevelopmentWarning } from '../../utils/ts/print-development-warning'; import { toastStackInjectionKey } from './toast-stack'; import { type UseBentoToastController } from './use-bento-toast-controller.types'; export function useBentoToastController(): UseBentoToastController { const toastStack = isVue2 ? getCurrentInstance()?.proxy[toastStackInjectionKey] : inject(toastStackInjectionKey, null); if (!toastStack) { printDevelopmentWarning('Toast does not work without Vue.use(BentoPlugin, { withToast: true })'); // Return placeholder functions so client code won't brake, but Toasts just won't show up return { stack: readonly(ref([])), addToast: () => ({ // eslint-disable-next-line @typescript-eslint/no-empty-function -- intentional empty function explained by the comment above dismiss: () => {}, }), }; } // Return a new object so unintentional reassigning its properties won't override a global state return { ...toastStack }; }
@@ -0,0 +1 @@
1
+ export * from './use-click-outside';
@@ -1 +1 @@
1
- import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { BentoTypography } from '@/components/typography'; import { BentoCard } from '@/components/card'; import { isVue2 } from 'vue-demi'; import { useClickOutside } from './use-click-outside'; const meta: Meta = { title: 'useClickOutside', argTypes: { // Values target: { description: 'Reference to an HTML element to which the listener will be attached to', table: { type: { summary: 'Ref<UnwrapRef<HTMLDivElement>>' } }, control: { disable: true }, }, handler: { description: 'Function that will be called when the listener gets triggered', table: { type: { summary: 'OnClickOutsideHandler' } }, control: { disable: true }, }, optons: { name: 'options', description: 'Options to be passed to the listener (optional)', table: { type: { summary: 'OnClickOutsideOptions' } }, control: { disable: true }, }, }, }; export default meta; // Default const DefaultCode = ` <template> <div> <div ref="clickOutsideRef"></div> <div ref="ignoredElementRef"></div> </div> </template> <script setup lang="ts"> import { useClickOutside } from '@adyen/bento-vue2' import { ref } from 'vue' const clickOutsideRef = ref<HTMLDivElement>(null) const ignoredElementRef = ref<HTMLDivElement>(null) const options: OnClickOutsideOptions = { ignore: [ignoredElementRef] } const clickedAction = () => { // Your action handler } useClickOutside(clickOutsideRef, clickedAction, options) </script>`; export const Default: StoryObj = { render: _args => ({ components: { BentoCard, BentoTypography }, template: ` <div> <div ref="clickOutsideRef"> <bento-card> {{args.title}} </bento-card> </div> <bento-typography>Total click outside events triggered: {{totalClickOutsideCount}} </bento-typography> </div> `, setup(props) { const clickOutsideRef = ref<HTMLDivElement>(null); const totalClickOutsideCount = ref(0); const clickedAction = () => { totalClickOutsideCount.value += 1; return action('trigger'); }; useClickOutside(clickOutsideRef, clickedAction); return { // Refs clickOutsideRef, // Values totalClickOutsideCount, args: isVue2 ? props : _args, }; }, }), parameters: storybookDocsParameter(DefaultCode), };
1
+ import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { BentoTypography } from '@/components/typography'; import { BentoCard } from '@/components/card'; import { isVue2 } from 'vue-demi'; import { useClickOutside } from './use-click-outside'; const UseClickOutsideDefaultExample = "<template>\n <div>\n <div ref=\"clickOutsideRef\">\n <bento-card />\n </div>\n <bento-typography>Total click outside events triggered: {{ totalClickOutsideCount }}</bento-typography>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoCard, BentoTypography, useClickOutside } from '@adyen/bento-vue2';\n\n const clickOutsideRef = ref<HTMLDivElement | null>(null);\n const totalClickOutsideCount = ref(0);\n\n const onClickOutside = () => {\n totalClickOutsideCount.value += 1;\n };\n\n useClickOutside(clickOutsideRef, onClickOutside);\n</script>\n"; const meta: Meta = { title: 'useClickOutside', argTypes: { // Values target: { description: 'Reference to an HTML element to which the listener will be attached to', table: { type: { summary: 'Ref<UnwrapRef<HTMLDivElement>>' } }, control: { disable: true }, }, handler: { description: 'Function that will be called when the listener gets triggered', table: { type: { summary: 'OnClickOutsideHandler' } }, control: { disable: true }, }, optons: { name: 'options', description: 'Options to be passed to the listener (optional)', table: { type: { summary: 'OnClickOutsideOptions' } }, control: { disable: true }, }, }, }; export default meta; export const Default: StoryObj = { render: _args => ({ components: { BentoCard, BentoTypography }, template: ` <div> <div ref="clickOutsideRef"> <bento-card> {{args.title}} </bento-card> </div> <bento-typography>Total click outside events triggered: {{totalClickOutsideCount}} </bento-typography> </div> `, setup(props) { const clickOutsideRef = ref<HTMLDivElement>(null); const totalClickOutsideCount = ref(0); const clickedAction = () => { totalClickOutsideCount.value += 1; return action('trigger'); }; useClickOutside(clickOutsideRef, clickedAction); return { // Refs clickOutsideRef, // Values totalClickOutsideCount, args: isVue2 ? props : _args, }; }, }), parameters: storybookDocsParameter(UseClickOutsideDefaultExample), };
@@ -0,0 +1 @@
1
+ import { onClickOutside } from '@/directives/click-outside/on-click-outside'; import { type OnClickOutsideHandler, type OnClickOutsideOptions } from '@/directives/click-outside/types'; import { type MaybeElementRef } from '@/types/elements'; import { onMounted, onUnmounted } from 'vue'; /** * Composable to listen for clicks outside of an element ref. * * @param {MaybeElementRef} target - HTML Element or "ref" to an Element on which the click outside listener will be attached to * @param {OnClickOutsideHandler} handler - Function that will be called when the listener gets triggered * @param {OnClickOutsideOptions} options - Options to be passed to the listener */ export const useClickOutside = <T extends OnClickOutsideOptions>( target: MaybeElementRef, handler: OnClickOutsideHandler, options: T = {} as T ) => { let onClickOutsideStop: () => void; onMounted(() => { onClickOutsideStop = onClickOutside(target, handler, options); }); onUnmounted(() => { if (onClickOutsideStop) { onClickOutsideStop(); onClickOutsideStop = null; } }); };
@@ -0,0 +1 @@
1
+ export * from './use-form'; export * from './use-form.types';
@@ -0,0 +1 @@
1
+ import { type Ref, ref, shallowRef } from 'vue'; import * as z from 'zod'; import type { ZodSchema } from 'zod'; import { type allKeys, type ErrorBag, type UseForm } from './use-form.types'; /** * Composable that transforms a Zod schema into a Typed Schema that can be used alongside with {@see useForm}. * * This is meant to simulate the behavior of {@link @vee-validate/zod} {@see https://vee-validate.logaretm.com/v4/integrations/zod-schema-validation}. * Function that transform Zod’s schemas into something that can be understood by vee-validate * * @deprecated Since v3.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. * * @param formSchema Zod schema to be transformed into a `vee-validate` schema * @returns Schema transformed */ export function toTypedSchema<T extends ZodSchema>(formSchema: T) { return formSchema; } /** * Finds and returns the initial values of each of the values defined in the schema so that they * can be transformed into a reactive element. * @param schema Zod validation schema containing the definitions of each value to be used in the form * @returns Object with the items defined in the schema and their (default) values * * @example * const validationSchema = toTypedSchema( * z.object({ * name: z * .string() * .min(3, { message: 'Name is required' }) * .startsWith('Jane') * .max(4, { message: 'Name cannot be longer than 4 characters' }) * .default('Joe'), * }) * ); * getInitialFormValues(validationSchema) * * Will return: * * { * name: 'Joe' * } * */ function getInitialFormValues<T extends ZodSchema>(schema: T): z.infer<typeof schema> { if (!!z && schema instanceof z.ZodObject) { return Object.fromEntries( Object.entries(schema.shape).map(([key, value]) => { if (!!z && value instanceof z.ZodDefault) { /* eslint-disable-next-line no-underscore-dangle */ return [key, value._def.defaultValue()]; } if (!!z && value instanceof z.ZodObject) { return [key, getInitialFormValues(value)]; } return [key, undefined]; }) ) as z.infer<typeof schema>; } /** * Zod's refine and superRefine use {@link z.ZodEffects} instead of {@link z.ZodSchema}. * We need to extract the schema from the {@link z.ZodEffects} structure. */ if (!!z && schema instanceof z.ZodEffects) { // eslint-disable-next-line no-underscore-dangle return getInitialFormValues(schema._def.schema); } return undefined; } /** * Constructs a path with dot paths for arrays to use brackets to be compatible with vee-validate path syntax * @param issue List of nested path elements * @returns Path with dots */ function normalizeFormPath(issue: z.ZodIssue) { return issue.path.join('.'); } /** * Composable that facilitates validating form data for Vue2 & Vue3 implementations with FormLayout * to ease the migration to Vue3. * * For Vue3 implementations use Vee-Validate. * * This provides a simplified version of Vee-Validate v4 implemented with Zod to validate a form schema. * It returns reactive values that can be used directly in form input elements with 'v-model' alongside * with functions to "reset" the data (sets values to default value) and a function to execute the * successful form validation process (through a callback). * * @deprecated Since v3.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. * * @param props Form configuration object * @param extends ZodSchema} props.validationSchema Zod typed validation schema * @returns response - Composable with reactive form values and errors, and functions to handle the reactive data * @returns response.errorBag Object with all the form values and an array of each one of the errors (if any) per value * @returns response.errors Object with all the form values and the first error found for that field (if any) * @returns response.values Object with all the form values and their current value * @returns response.handleReset Resets the form values to default (initial values) when it gets called * @returns response.submitForm Validates the data set in {response.values} and sets errors (if found) inside {response.errors} and {response.errorBag}. * When the validation is successful it calls the callback so the submit process can continue * * @example * const validationSchema = toTypedSchema( * z.object({ * name: z * .string() * .min(3, { message: 'Name is required' }) * .startsWith('Jane') * .max(4, { message: 'Name cannot be longer than 4 characters' }) * .default('Joe'), * }) * ); * * const { values, errors, errorBag, submitForm, handleReset } = useForm({ * validationSchema * }); * const handleSubmit = submitForm(() => { * // Send data to API here * }) * */ export function useForm<T extends ZodSchema>({ validationSchema, }: UseForm<T>): { errorBag: Ref<{ [P in allKeys<(typeof validationSchema)['_type']>]?: Array<string>; }>; errors: Ref<{ [P in allKeys<(typeof validationSchema)['_type']>]?: string; }>; values: Ref<(typeof validationSchema)['_type']>; handleReset: () => void; submitForm: (submitted: any) => () => void; } { // Errors per field const errors = shallowRef<z.infer<typeof validationSchema>>({}); // All errors per field const errorBag: Ref<ErrorBag<z.infer<typeof validationSchema>>> = ref({}); const values: Ref<z.TypeOf<T>> = ref(getInitialFormValues<T>(validationSchema)); const cleanErrors = () => { errors.value = {}; errorBag.value = {}; }; const resetForm = () => { cleanErrors(); values.value = getInitialFormValues<T>(validationSchema); }; const submitForm = submitted => () => { cleanErrors(); // Run validations on the form data through the schema const validSchema = validationSchema.safeParse(values.value); // Update errors if (!validSchema.success) { (validSchema as z.SafeParseError<T>).error.issues.forEach(error => { const path = normalizeFormPath(error); // Add the first occurrence of a field error to the "errors" object if (!errors.value[path]) { errors.value[path] = error.message; } // Add each error to the "errorBag" per field array if (!errorBag.value[path]) { errorBag.value[path] = [error.message]; } else { errorBag.value[path].push(error.message); } }); } else { submitted(values.value); } }; return { // Values errorBag, errors, values, // Methods handleReset: () => resetForm(), submitForm, }; }
@@ -1 +1 @@
1
- import type { typeToFlattenedError } from 'zod'; /** * Object of all the form field props with their respective list of errors * @deprecated Since v2.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export type ErrorBag<T> = typeToFlattenedError<T, string>['fieldErrors']; /** * Extracts all the keys from a type * @deprecated Since v2.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export type allKeys<T> = T extends any ? keyof T : never; /** * useForm composable configuration object * @deprecated Since v2.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export interface UseForm<T> { validationSchema: T; }
1
+ import type { typeToFlattenedError } from 'zod'; /** * Object of all the form field props with their respective list of errors * @deprecated Since v3.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export type ErrorBag<T> = typeToFlattenedError<T, string>['fieldErrors']; /** * Extracts all the keys from a type * @deprecated Since v3.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export type allKeys<T> = T extends any ? keyof T : never; /** * useForm composable configuration object * @deprecated Since v3.0.0. Use `@adyen/bento-vue2/use-form-v4' instead or migrate to Vue3 and use Vee-Validate instead. */ export interface UseForm<T> { validationSchema: T; }
@@ -0,0 +1,9 @@
1
+ [
2
+ "use-bento-base-filter",
3
+ "use-bento-currency",
4
+ "use-bento-theme",
5
+ "use-bento-toast-controller",
6
+ "use-click-outside",
7
+ "use-form-validate",
8
+ "use-bento-delayed-hover"
9
+ ]