@for-the-people-initiative/design-system 1.3.1

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 (342) hide show
  1. package/README.md +80 -0
  2. package/dist/css/theme-dark.css +7 -0
  3. package/dist/css/tokens.css +2315 -0
  4. package/dist/scss/_tokens.scss +2521 -0
  5. package/dist/ts/tokens.ts +2441 -0
  6. package/package.json +80 -0
  7. package/src/components/Accordion/Accordion.scss +118 -0
  8. package/src/components/Accordion/Accordion.vue +105 -0
  9. package/src/components/Accordion/AccordionTab.vue +79 -0
  10. package/src/components/Alert/Alert.scss +109 -0
  11. package/src/components/Alert/Alert.vue +79 -0
  12. package/src/components/AppBar/AppBar.scss +73 -0
  13. package/src/components/AppBar/AppBar.vue +49 -0
  14. package/src/components/AtmosphericBackground/AtmosphericBackground.vue +198 -0
  15. package/src/components/AutoComplete/AutoComplete.scss +282 -0
  16. package/src/components/AutoComplete/AutoComplete.vue +398 -0
  17. package/src/components/Avatar/Avatar.scss +191 -0
  18. package/src/components/Avatar/Avatar.vue +44 -0
  19. package/src/components/Badge/Badge.scss +84 -0
  20. package/src/components/Badge/Badge.vue +41 -0
  21. package/src/components/BlockUI/BlockUI.scss +85 -0
  22. package/src/components/BlockUI/BlockUI.vue +90 -0
  23. package/src/components/Breadcrumb/Breadcrumb.scss +84 -0
  24. package/src/components/Breadcrumb/Breadcrumb.vue +141 -0
  25. package/src/components/Button/Button.scss +254 -0
  26. package/src/components/Button/Button.vue +68 -0
  27. package/src/components/CTA/CTA.scss +92 -0
  28. package/src/components/CTA/CTA.vue +33 -0
  29. package/src/components/Calendar/Calendar.scss +330 -0
  30. package/src/components/Calendar/Calendar.vue +455 -0
  31. package/src/components/Card/Card.scss +66 -0
  32. package/src/components/Card/Card.vue +48 -0
  33. package/src/components/Carousel/Carousel.scss +121 -0
  34. package/src/components/Carousel/Carousel.vue +191 -0
  35. package/src/components/Chart/Chart.scss +109 -0
  36. package/src/components/Chart/Chart.vue +209 -0
  37. package/src/components/Checkbox/Checkbox.scss +148 -0
  38. package/src/components/Checkbox/Checkbox.vue +75 -0
  39. package/src/components/Chip/Chip.scss +83 -0
  40. package/src/components/Chip/Chip.vue +73 -0
  41. package/src/components/ColorPicker/ColorPicker.scss +244 -0
  42. package/src/components/ColorPicker/ColorPicker.vue +411 -0
  43. package/src/components/Column/Column.scss +87 -0
  44. package/src/components/Column/Column.vue +45 -0
  45. package/src/components/ColumnGroup/ColumnGroup.scss +41 -0
  46. package/src/components/ColumnGroup/ColumnGroup.vue +27 -0
  47. package/src/components/ColumnGroup/ColumnGroupRow.vue +18 -0
  48. package/src/components/CommandPalette/CommandPalette.scss +143 -0
  49. package/src/components/CommandPalette/CommandPalette.vue +165 -0
  50. package/src/components/ConfirmDialog/ConfirmDialog.scss +177 -0
  51. package/src/components/ConfirmDialog/ConfirmDialog.vue +162 -0
  52. package/src/components/ConfirmPopup/ConfirmPopup.scss +180 -0
  53. package/src/components/ConfirmPopup/ConfirmPopup.vue +185 -0
  54. package/src/components/ContextMenu/ContextMenu.scss +171 -0
  55. package/src/components/ContextMenu/ContextMenu.vue +383 -0
  56. package/src/components/DataTable/DataTable.scss +162 -0
  57. package/src/components/DataTable/DataTable.vue +225 -0
  58. package/src/components/DataView/DataView.scss +149 -0
  59. package/src/components/DataView/DataView.vue +172 -0
  60. package/src/components/DatePicker/DatePicker.scss +71 -0
  61. package/src/components/DatePicker/DatePicker.vue +121 -0
  62. package/src/components/Dialog/Dialog.scss +161 -0
  63. package/src/components/Dialog/Dialog.vue +245 -0
  64. package/src/components/Divider/Divider.scss +147 -0
  65. package/src/components/Divider/Divider.vue +49 -0
  66. package/src/components/Dock/Dock.scss +221 -0
  67. package/src/components/Dock/Dock.vue +107 -0
  68. package/src/components/Drawer/Drawer.scss +220 -0
  69. package/src/components/Drawer/Drawer.vue +137 -0
  70. package/src/components/Dropdown/Dropdown.scss +218 -0
  71. package/src/components/Dropdown/Dropdown.vue +313 -0
  72. package/src/components/Editor/Editor.scss +156 -0
  73. package/src/components/Editor/Editor.vue +253 -0
  74. package/src/components/FAQ/FAQ.scss +24 -0
  75. package/src/components/FAQ/FAQ.vue +28 -0
  76. package/src/components/FeatureGrid/FeatureGrid.scss +92 -0
  77. package/src/components/FeatureGrid/FeatureGrid.vue +39 -0
  78. package/src/components/FieldSet/FieldSet.scss +97 -0
  79. package/src/components/FieldSet/FieldSet.vue +70 -0
  80. package/src/components/FileUpload/FileUpload.scss +137 -0
  81. package/src/components/FileUpload/FileUpload.vue +183 -0
  82. package/src/components/Footer/Footer.scss +95 -0
  83. package/src/components/Footer/Footer.vue +59 -0
  84. package/src/components/Form/Form.scss +72 -0
  85. package/src/components/Form/Form.vue +30 -0
  86. package/src/components/Form/FormField.vue +42 -0
  87. package/src/components/Galleria/Galleria.scss +295 -0
  88. package/src/components/Galleria/Galleria.vue +274 -0
  89. package/src/components/Hero/Hero.scss +116 -0
  90. package/src/components/Hero/Hero.vue +57 -0
  91. package/src/components/Image/Image.scss +129 -0
  92. package/src/components/Image/Image.vue +117 -0
  93. package/src/components/ImageCompare/ImageCompare.scss +97 -0
  94. package/src/components/ImageCompare/ImageCompare.vue +66 -0
  95. package/src/components/InPlace/InPlace.scss +97 -0
  96. package/src/components/InPlace/InPlace.vue +107 -0
  97. package/src/components/InlineMessage/InlineMessage.scss +69 -0
  98. package/src/components/InlineMessage/InlineMessage.vue +47 -0
  99. package/src/components/InputChips/InputChips.scss +165 -0
  100. package/src/components/InputChips/InputChips.vue +169 -0
  101. package/src/components/InputGroup/InputGroup.scss +57 -0
  102. package/src/components/InputGroup/InputGroup.vue +22 -0
  103. package/src/components/InputGroupAddon/InputGroupAddon.scss +28 -0
  104. package/src/components/InputGroupAddon/InputGroupAddon.vue +22 -0
  105. package/src/components/InputIcon/InputIcon.scss +58 -0
  106. package/src/components/InputIcon/InputIcon.vue +28 -0
  107. package/src/components/InputMask/InputMask.scss +65 -0
  108. package/src/components/InputMask/InputMask.vue +268 -0
  109. package/src/components/InputNumber/InputNumber.scss +122 -0
  110. package/src/components/InputNumber/InputNumber.vue +150 -0
  111. package/src/components/InputOtp/InputOtp.scss +88 -0
  112. package/src/components/InputOtp/InputOtp.vue +230 -0
  113. package/src/components/InputSwitch/InputSwitch.scss +131 -0
  114. package/src/components/InputSwitch/InputSwitch.vue +49 -0
  115. package/src/components/InputText/InputText.scss +61 -0
  116. package/src/components/InputText/InputText.vue +71 -0
  117. package/src/components/Knob/Knob.scss +92 -0
  118. package/src/components/Knob/Knob.vue +252 -0
  119. package/src/components/ListBox/ListBox.scss +152 -0
  120. package/src/components/ListBox/ListBox.vue +198 -0
  121. package/src/components/LogoCloud/LogoCloud.scss +64 -0
  122. package/src/components/LogoCloud/LogoCloud.vue +35 -0
  123. package/src/components/MegaMenu/MegaMenu.scss +280 -0
  124. package/src/components/MegaMenu/MegaMenu.vue +218 -0
  125. package/src/components/Menu/Menu.scss +102 -0
  126. package/src/components/Menu/Menu.vue +221 -0
  127. package/src/components/MenuBar/MenuBar.scss +208 -0
  128. package/src/components/MenuBar/MenuBar.vue +306 -0
  129. package/src/components/Message/Message.scss +126 -0
  130. package/src/components/Message/Message.vue +99 -0
  131. package/src/components/MeterGroup/MeterGroup.scss +105 -0
  132. package/src/components/MeterGroup/MeterGroup.vue +73 -0
  133. package/src/components/MultiSelect/MultiSelect.scss +239 -0
  134. package/src/components/MultiSelect/MultiSelect.vue +296 -0
  135. package/src/components/OrderList/OrderList.scss +133 -0
  136. package/src/components/OrderList/OrderList.vue +267 -0
  137. package/src/components/OrganizationChart/OrganizationChart.scss +145 -0
  138. package/src/components/OrganizationChart/OrganizationChart.vue +220 -0
  139. package/src/components/OverlayPanel/OverlayPanel.scss +69 -0
  140. package/src/components/OverlayPanel/OverlayPanel.vue +180 -0
  141. package/src/components/Paginator/Paginator.scss +130 -0
  142. package/src/components/Paginator/Paginator.vue +212 -0
  143. package/src/components/Panel/Panel.scss +113 -0
  144. package/src/components/Panel/Panel.vue +89 -0
  145. package/src/components/PanelMenu/PanelMenu.scss +211 -0
  146. package/src/components/PanelMenu/PanelMenu.vue +295 -0
  147. package/src/components/ParticleBackground/ParticleBackground.vue +310 -0
  148. package/src/components/PickList/PickList.scss +126 -0
  149. package/src/components/PickList/PickList.vue +249 -0
  150. package/src/components/PopOver/PopOver.scss +112 -0
  151. package/src/components/PopOver/PopOver.vue +254 -0
  152. package/src/components/PricingTable/PricingCard.vue +33 -0
  153. package/src/components/PricingTable/PricingTable.scss +133 -0
  154. package/src/components/PricingTable/PricingTable.vue +21 -0
  155. package/src/components/ProgressBar/ProgressBar.scss +58 -0
  156. package/src/components/ProgressBar/ProgressBar.vue +48 -0
  157. package/src/components/ProgressSpinner/ProgressSpinner.scss +48 -0
  158. package/src/components/ProgressSpinner/ProgressSpinner.vue +53 -0
  159. package/src/components/RadioButton/RadioButton.scss +148 -0
  160. package/src/components/RadioButton/RadioButton.vue +52 -0
  161. package/src/components/Rating/Rating.scss +109 -0
  162. package/src/components/Rating/Rating.vue +136 -0
  163. package/src/components/Row/Row.scss +38 -0
  164. package/src/components/Row/Row.vue +30 -0
  165. package/src/components/ScrollPanel/ScrollPanel.scss +90 -0
  166. package/src/components/ScrollPanel/ScrollPanel.vue +284 -0
  167. package/src/components/ScrollTop/ScrollTop.scss +59 -0
  168. package/src/components/ScrollTop/ScrollTop.vue +99 -0
  169. package/src/components/Section/Section.scss +58 -0
  170. package/src/components/Section/Section.vue +39 -0
  171. package/src/components/Select/Select.scss +98 -0
  172. package/src/components/Select/Select.vue +92 -0
  173. package/src/components/SelectButton/SelectButton.scss +65 -0
  174. package/src/components/SelectButton/SelectButton.vue +144 -0
  175. package/src/components/Sidebar/Sidebar.scss +170 -0
  176. package/src/components/Sidebar/Sidebar.vue +137 -0
  177. package/src/components/Skeleton/Skeleton.scss +43 -0
  178. package/src/components/Skeleton/Skeleton.vue +57 -0
  179. package/src/components/Slider/Slider.scss +103 -0
  180. package/src/components/Slider/Slider.vue +65 -0
  181. package/src/components/SpeedDial/SpeedDial.scss +217 -0
  182. package/src/components/SpeedDial/SpeedDial.vue +196 -0
  183. package/src/components/SplitButton/SplitButton.scss +264 -0
  184. package/src/components/SplitButton/SplitButton.vue +172 -0
  185. package/src/components/Splitter/Splitter.scss +95 -0
  186. package/src/components/Splitter/Splitter.vue +191 -0
  187. package/src/components/Splitter/SplitterPanel.vue +125 -0
  188. package/src/components/Stats/Stats.scss +54 -0
  189. package/src/components/Stats/Stats.vue +28 -0
  190. package/src/components/Steps/Steps.scss +164 -0
  191. package/src/components/Steps/Steps.vue +100 -0
  192. package/src/components/TabMenu/TabMenu.scss +106 -0
  193. package/src/components/TabMenu/TabMenu.vue +174 -0
  194. package/src/components/Tabs/TabPanel.vue +41 -0
  195. package/src/components/Tabs/Tabs.scss +82 -0
  196. package/src/components/Tabs/Tabs.vue +162 -0
  197. package/src/components/Tag/Tag.scss +73 -0
  198. package/src/components/Tag/Tag.vue +37 -0
  199. package/src/components/Terminal/Terminal.scss +80 -0
  200. package/src/components/Terminal/Terminal.vue +113 -0
  201. package/src/components/Testimonial/Testimonial.scss +80 -0
  202. package/src/components/Testimonial/Testimonial.vue +29 -0
  203. package/src/components/Textarea/Textarea.scss +65 -0
  204. package/src/components/Textarea/Textarea.vue +101 -0
  205. package/src/components/TieredMenu/TieredMenu.scss +146 -0
  206. package/src/components/TieredMenu/TieredMenu.vue +270 -0
  207. package/src/components/TieredMenu/TieredMenuSub.vue +132 -0
  208. package/src/components/Timeline/Timeline.scss +190 -0
  209. package/src/components/Timeline/Timeline.vue +79 -0
  210. package/src/components/Toast/Toast.scss +284 -0
  211. package/src/components/Toast/Toast.vue +162 -0
  212. package/src/components/ToggleButton/ToggleButton.scss +99 -0
  213. package/src/components/ToggleButton/ToggleButton.vue +65 -0
  214. package/src/components/ToggleSwitch/ToggleSwitch.scss +68 -0
  215. package/src/components/ToggleSwitch/ToggleSwitch.vue +44 -0
  216. package/src/components/Toolbar/Toolbar.scss +37 -0
  217. package/src/components/Toolbar/Toolbar.vue +23 -0
  218. package/src/components/Tooltip/Tooltip.scss +114 -0
  219. package/src/components/Tooltip/Tooltip.vue +169 -0
  220. package/src/components/Tree/Tree.scss +164 -0
  221. package/src/components/Tree/Tree.vue +273 -0
  222. package/src/components/TreeSelect/TreeSelect.scss +238 -0
  223. package/src/components/TreeSelect/TreeSelect.vue +401 -0
  224. package/src/components/TreeTable/TreeTable.scss +172 -0
  225. package/src/components/TreeTable/TreeTable.vue +285 -0
  226. package/src/components/VirtualScroller/VirtualScroller.scss +107 -0
  227. package/src/components/VirtualScroller/VirtualScroller.vue +234 -0
  228. package/src/scss/fonts.scss +63 -0
  229. package/src/scss/mixins/accent-gradient.scss +43 -0
  230. package/src/scss/mixins/border.scss +28 -0
  231. package/src/scss/mixins/breakpoint.scss +80 -0
  232. package/src/scss/mixins/container.scss +33 -0
  233. package/src/scss/mixins/elevation.scss +43 -0
  234. package/src/scss/mixins/grid.scss +23 -0
  235. package/src/scss/mixins/levitation.scss +15 -0
  236. package/src/scss/mixins/list.scss +5 -0
  237. package/src/scss/mixins/surface-atmospheric.scss +93 -0
  238. package/src/scss/mixins/surface.scss +19 -0
  239. package/src/scss/mixins/typography.scss +91 -0
  240. package/src/scss/utility-classes/utility-classes-spacing.scss +34 -0
  241. package/src/scss/utility-classes/utility-classes-typography.scss +114 -0
  242. package/tokens/components/accordion.json +127 -0
  243. package/tokens/components/autocomplete.json +238 -0
  244. package/tokens/components/avatar.json +220 -0
  245. package/tokens/components/badge.json +119 -0
  246. package/tokens/components/block-ui.json +40 -0
  247. package/tokens/components/breadcrumb.json +57 -0
  248. package/tokens/components/button.json +395 -0
  249. package/tokens/components/calendar.json +260 -0
  250. package/tokens/components/card.json +157 -0
  251. package/tokens/components/carousel.json +154 -0
  252. package/tokens/components/chart.json +132 -0
  253. package/tokens/components/checkbox.json +130 -0
  254. package/tokens/components/chip.json +100 -0
  255. package/tokens/components/color-picker.json +196 -0
  256. package/tokens/components/column-group.json +45 -0
  257. package/tokens/components/column.json +109 -0
  258. package/tokens/components/confirm-dialog.json +141 -0
  259. package/tokens/components/confirm-popup.json +101 -0
  260. package/tokens/components/context-menu.json +168 -0
  261. package/tokens/components/data-table.json +157 -0
  262. package/tokens/components/data-view.json +172 -0
  263. package/tokens/components/dialog.json +151 -0
  264. package/tokens/components/divider.json +45 -0
  265. package/tokens/components/dock.json +173 -0
  266. package/tokens/components/drawer.json +163 -0
  267. package/tokens/components/dropdown.json +230 -0
  268. package/tokens/components/editor.json +170 -0
  269. package/tokens/components/field-set.json +115 -0
  270. package/tokens/components/file-upload.json +193 -0
  271. package/tokens/components/galleria.json +235 -0
  272. package/tokens/components/image-compare.json +74 -0
  273. package/tokens/components/image.json +71 -0
  274. package/tokens/components/in-place.json +100 -0
  275. package/tokens/components/inline-message.json +107 -0
  276. package/tokens/components/input-chips.json +187 -0
  277. package/tokens/components/input-group-addon.json +47 -0
  278. package/tokens/components/input-group.json +21 -0
  279. package/tokens/components/input-icon.json +38 -0
  280. package/tokens/components/input-mask.json +136 -0
  281. package/tokens/components/input-number.json +144 -0
  282. package/tokens/components/input-otp.json +138 -0
  283. package/tokens/components/input-switch.json +108 -0
  284. package/tokens/components/input-text.json +136 -0
  285. package/tokens/components/knob.json +119 -0
  286. package/tokens/components/listbox.json +166 -0
  287. package/tokens/components/mega-menu.json +283 -0
  288. package/tokens/components/menu.json +145 -0
  289. package/tokens/components/menubar.json +152 -0
  290. package/tokens/components/message.json +151 -0
  291. package/tokens/components/meter-group.json +108 -0
  292. package/tokens/components/multi-select.json +244 -0
  293. package/tokens/components/order-list.json +193 -0
  294. package/tokens/components/organization-chart.json +188 -0
  295. package/tokens/components/overlay-panel.json +94 -0
  296. package/tokens/components/paginator.json +186 -0
  297. package/tokens/components/panel.json +120 -0
  298. package/tokens/components/panelmenu.json +190 -0
  299. package/tokens/components/picklist.json +187 -0
  300. package/tokens/components/popover.json +65 -0
  301. package/tokens/components/progress-bar.json +33 -0
  302. package/tokens/components/progress-spinner.json +38 -0
  303. package/tokens/components/radio.json +125 -0
  304. package/tokens/components/rating.json +76 -0
  305. package/tokens/components/row.json +62 -0
  306. package/tokens/components/scroll-panel.json +69 -0
  307. package/tokens/components/scroll-top.json +84 -0
  308. package/tokens/components/select-button.json +145 -0
  309. package/tokens/components/select.json +190 -0
  310. package/tokens/components/sidebar.json +146 -0
  311. package/tokens/components/skeleton.json +26 -0
  312. package/tokens/components/slider.json +82 -0
  313. package/tokens/components/speed-dial.json +144 -0
  314. package/tokens/components/split-button.json +316 -0
  315. package/tokens/components/splitter.json +88 -0
  316. package/tokens/components/steps.json +154 -0
  317. package/tokens/components/tabmenu.json +103 -0
  318. package/tokens/components/tabs.json +97 -0
  319. package/tokens/components/tag.json +122 -0
  320. package/tokens/components/terminal.json +100 -0
  321. package/tokens/components/textarea.json +96 -0
  322. package/tokens/components/tieredmenu.json +142 -0
  323. package/tokens/components/timeline.json +129 -0
  324. package/tokens/components/toast.json +281 -0
  325. package/tokens/components/toggle-button.json +220 -0
  326. package/tokens/components/toggle-switch.json +95 -0
  327. package/tokens/components/toolbar.json +41 -0
  328. package/tokens/components/tooltip.json +60 -0
  329. package/tokens/components/tree-select.json +224 -0
  330. package/tokens/components/tree.json +153 -0
  331. package/tokens/components/treetable.json +155 -0
  332. package/tokens/components/virtualscroller.json +95 -0
  333. package/tokens/primitives/color.json +137 -0
  334. package/tokens/primitives/radius.json +12 -0
  335. package/tokens/primitives/shadow.json +29 -0
  336. package/tokens/primitives/spacing.json +15 -0
  337. package/tokens/semantics/color.json +81 -0
  338. package/tokens/semantics/radius.json +10 -0
  339. package/tokens/semantics/shadow.json +9 -0
  340. package/tokens/semantics/spacing.json +24 -0
  341. package/tokens/themes/dark.json +7 -0
  342. package/tokens/themes/light.json +7 -0
@@ -0,0 +1,212 @@
1
+ <template>
2
+ <nav class="paginator" :class="additionalClasses" aria-label="Pagination">
3
+ <div v-if="showInfo" class="paginator__info">
4
+ {{ infoText }}
5
+ </div>
6
+
7
+ <div class="paginator__controls">
8
+ <!-- First page button -->
9
+ <button
10
+ type="button"
11
+ v-if="showFirstLast"
12
+ class="paginator__nav paginator__nav--first"
13
+ :disabled="isFirstPage"
14
+ :aria-disabled="isFirstPage"
15
+ aria-label="Go to first page"
16
+ @click="goToFirst"
17
+ >
18
+ <svg class="paginator__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
19
+ <polyline points="11 17 6 12 11 7" />
20
+ <polyline points="18 17 13 12 18 7" />
21
+ </svg>
22
+ </button>
23
+
24
+ <!-- Previous button -->
25
+ <button
26
+ type="button"
27
+ class="paginator__nav paginator__nav--prev"
28
+ :disabled="isFirstPage"
29
+ :aria-disabled="isFirstPage"
30
+ aria-label="Go to previous page"
31
+ @click="goToPrev"
32
+ >
33
+ <svg class="paginator__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
34
+ <polyline points="15 18 9 12 15 6" />
35
+ </svg>
36
+ </button>
37
+
38
+ <!-- Page numbers -->
39
+ <div class="paginator__pages">
40
+ <button
41
+ type="button"
42
+ v-for="page in visiblePages"
43
+ :key="page.value"
44
+ class="paginator__page"
45
+ :class="{ 'paginator__page--active': page.value === currentPage, 'paginator__page--ellipsis': page.isEllipsis }"
46
+ :disabled="page.isEllipsis"
47
+ :aria-current="page.value === currentPage ? 'page' : undefined"
48
+ :aria-label="page.isEllipsis ? undefined : `Go to page ${page.value}`"
49
+ @click="!page.isEllipsis && goToPage(page.value)"
50
+ >
51
+ {{ page.isEllipsis ? '...' : page.value }}
52
+ </button>
53
+ </div>
54
+
55
+ <!-- Next button -->
56
+ <button
57
+ type="button"
58
+ class="paginator__nav paginator__nav--next"
59
+ :disabled="isLastPage"
60
+ :aria-disabled="isLastPage"
61
+ aria-label="Go to next page"
62
+ @click="goToNext"
63
+ >
64
+ <svg class="paginator__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
65
+ <polyline points="9 18 15 12 9 6" />
66
+ </svg>
67
+ </button>
68
+
69
+ <!-- Last page button -->
70
+ <button
71
+ type="button"
72
+ v-if="showFirstLast"
73
+ class="paginator__nav paginator__nav--last"
74
+ :disabled="isLastPage"
75
+ :aria-disabled="isLastPage"
76
+ aria-label="Go to last page"
77
+ @click="goToLast"
78
+ >
79
+ <svg class="paginator__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
80
+ <polyline points="13 17 18 12 13 7" />
81
+ <polyline points="6 17 11 12 6 7" />
82
+ </svg>
83
+ </button>
84
+ </div>
85
+
86
+ <!-- Rows per page dropdown -->
87
+ <div v-if="rowsPerPageOptions && rowsPerPageOptions.length > 0" class="paginator__rows-per-page">
88
+ <label class="paginator__rows-label">Rows per page:</label>
89
+ <select
90
+ class="paginator__rows-select"
91
+ :value="rows"
92
+ @change="handleRowsChange"
93
+ >
94
+ <option v-for="option in rowsPerPageOptions" :key="option" :value="option">
95
+ {{ option }}
96
+ </option>
97
+ </select>
98
+ </div>
99
+ </nav>
100
+ </template>
101
+
102
+ <style src="./Paginator.scss"></style>
103
+
104
+ <script setup lang="ts">
105
+ import type { PaginatorProps, PaginatorEmits } from '../../types';
106
+ import { computed } from "vue";
107
+
108
+ defineOptions({ name: 'FtpPaginator' });
109
+
110
+ const props = withDefaults(defineProps<PaginatorProps>(), {
111
+ rows: 10,
112
+ first: 0,
113
+ rowsPerPageOptions: () => [],
114
+ pageLinkSize: 5,
115
+ showFirstLast: true,
116
+ showInfo: false,
117
+ });
118
+
119
+ const emit = defineEmits(["update:first", "update:rows", "page"]);
120
+
121
+ const totalPages = computed(() => Math.ceil(props.totalRecords / props.rows));
122
+
123
+ const currentPage = computed(() => Math.floor(props.first / props.rows) + 1);
124
+
125
+ const isFirstPage = computed(() => currentPage.value === 1);
126
+
127
+ const isLastPage = computed(() => currentPage.value === totalPages.value || totalPages.value === 0);
128
+
129
+ const infoText = computed(() => {
130
+ const start = props.first + 1;
131
+ const end = Math.min(props.first + props.rows, props.totalRecords);
132
+ return `${start}-${end} of ${props.totalRecords}`;
133
+ });
134
+
135
+ const visiblePages = computed(() => {
136
+ const pages = [];
137
+ const total = totalPages.value;
138
+ const current = currentPage.value;
139
+ const linkSize = props.pageLinkSize;
140
+
141
+ if (total <= linkSize) {
142
+ for (let i = 1; i <= total; i++) {
143
+ pages.push({ value: i, isEllipsis: false });
144
+ }
145
+ } else {
146
+ const half = Math.floor(linkSize / 2);
147
+ let start = Math.max(1, current - half);
148
+ let end = Math.min(total, start + linkSize - 1);
149
+
150
+ if (end - start < linkSize - 1) {
151
+ start = Math.max(1, end - linkSize + 1);
152
+ }
153
+
154
+ if (start > 1) {
155
+ pages.push({ value: 1, isEllipsis: false });
156
+ if (start > 2) {
157
+ pages.push({ value: "ellipsis-start", isEllipsis: true });
158
+ }
159
+ }
160
+
161
+ for (let i = start; i <= end; i++) {
162
+ if (i !== 1 && i !== total) {
163
+ pages.push({ value: i, isEllipsis: false });
164
+ }
165
+ }
166
+
167
+ if (end < total) {
168
+ if (end < total - 1) {
169
+ pages.push({ value: "ellipsis-end", isEllipsis: true });
170
+ }
171
+ pages.push({ value: total, isEllipsis: false });
172
+ }
173
+ }
174
+
175
+ return pages;
176
+ });
177
+
178
+ function goToPage(page: any) {
179
+ const newFirst = (page - 1) * props.rows;
180
+ emit("update:first", newFirst);
181
+ emit("page", { page, first: newFirst, rows: props.rows, pageCount: totalPages.value });
182
+ }
183
+
184
+ function goToFirst() {
185
+ goToPage(1);
186
+ }
187
+
188
+ function goToLast() {
189
+ goToPage(totalPages.value);
190
+ }
191
+
192
+ function goToPrev() {
193
+ if (currentPage.value > 1) {
194
+ goToPage(currentPage.value - 1);
195
+ }
196
+ }
197
+
198
+ function goToNext() {
199
+ if (currentPage.value < totalPages.value) {
200
+ goToPage(currentPage.value + 1);
201
+ }
202
+ }
203
+
204
+ function handleRowsChange(event: Event) {
205
+ const newRows = parseInt((event.target as HTMLSelectElement).value, 10);
206
+ emit("update:rows", newRows);
207
+ emit("update:first", 0);
208
+ emit("page", { page: 1, first: 0, rows: newRows, pageCount: Math.ceil(props.totalRecords / newRows) });
209
+ }
210
+
211
+ const additionalClasses = computed(() => [].filter(Boolean).join(" "));
212
+ </script>
@@ -0,0 +1,113 @@
1
+ @use "../../../dist/scss/tokens" as *;
2
+
3
+ $c: panel;
4
+
5
+ .#{$c} {
6
+ background-color: var(--panel-background, $panel-background);
7
+ border: var(--panel-border-width, $panel-border-width) solid var(--panel-border-color, $panel-border-color);
8
+ border-radius: var(--panel-radius, $panel-radius);
9
+ overflow: hidden;
10
+ }
11
+
12
+ // Header section
13
+ .#{$c}__header {
14
+ display: flex;
15
+ align-items: center;
16
+ gap: var(--inset-s, $inset-s);
17
+ padding: var(--panel-header-padding, $panel-header-padding);
18
+ background-color: var(--panel-header-background-default, $panel-header-background-default);
19
+ border-bottom: var(--panel-border-width, $panel-border-width) solid var(--panel-header-borderColor, $panel-header-borderColor);
20
+ }
21
+
22
+ .#{$c}__header--toggleable {
23
+ cursor: pointer;
24
+ user-select: none;
25
+ transition: background-color var(--panel-transition-duration, $panel-transition-duration) ease;
26
+
27
+ &:hover {
28
+ background-color: var(--panel-header-background-hover, $panel-header-background-hover);
29
+
30
+ .#{$c}__toggle-icon {
31
+ color: var(--panel-icon-color-hover, $panel-icon-color-hover);
32
+ }
33
+ }
34
+ }
35
+
36
+ .#{$c}__toggle {
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ width: var(--panel-icon-size, $panel-icon-size);
41
+ height: var(--panel-icon-size, $panel-icon-size);
42
+ padding: 0;
43
+ margin: 0;
44
+ border: none;
45
+ background: transparent;
46
+ cursor: pointer;
47
+ flex-shrink: 0;
48
+ }
49
+
50
+ .#{$c}__toggle-icon {
51
+ width: var(--panel-icon-size, $panel-icon-size);
52
+ height: var(--panel-icon-size, $panel-icon-size);
53
+ color: var(--panel-icon-color-default, $panel-icon-color-default);
54
+ transition: transform var(--panel-transition-duration, $panel-transition-duration) ease,
55
+ color var(--panel-transition-duration, $panel-transition-duration) ease;
56
+ transform: rotate(var(--panel-icon-rotation-expanded, $panel-icon-rotation-expanded));
57
+ }
58
+
59
+ .#{$c}__title {
60
+ flex: 1;
61
+ font-size: var(--panel-header-fontSize, $panel-header-fontSize);
62
+ font-weight: var(--panel-header-fontWeight, $panel-header-fontWeight);
63
+ color: var(--panel-header-color, $panel-header-color);
64
+ line-height: 1.4;
65
+ }
66
+
67
+ .#{$c}__icons {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: var(--inset-xs, $inset-xs);
71
+ margin-left: auto;
72
+ }
73
+
74
+ // Content section
75
+ .#{$c}__content-wrapper {
76
+ display: grid;
77
+ grid-template-rows: 1fr;
78
+ transition: grid-template-rows var(--panel-transition-duration, $panel-transition-duration) ease;
79
+ }
80
+
81
+ .#{$c}__content {
82
+ overflow: hidden;
83
+ padding: var(--panel-content-padding, $panel-content-padding);
84
+ background-color: var(--panel-content-background, $panel-content-background);
85
+ color: var(--panel-content-color, $panel-content-color);
86
+ }
87
+
88
+ // Footer section
89
+ .#{$c}__footer {
90
+ padding: var(--panel-content-padding, $panel-content-padding);
91
+ border-top: var(--panel-border-width, $panel-border-width) solid var(--panel-header-borderColor, $panel-header-borderColor);
92
+ background-color: var(--panel-header-background-default, $panel-header-background-default);
93
+ }
94
+
95
+ // Collapsed state
96
+ .#{$c}--collapsed {
97
+ .#{$c}__header {
98
+ border-bottom-color: transparent;
99
+ }
100
+
101
+ .#{$c}__toggle-icon {
102
+ transform: rotate(var(--panel-icon-rotation-collapsed, $panel-icon-rotation-collapsed));
103
+ }
104
+
105
+ .#{$c}__content-wrapper {
106
+ grid-template-rows: 0fr;
107
+ }
108
+
109
+ .#{$c}__content {
110
+ padding-top: 0;
111
+ padding-bottom: 0;
112
+ }
113
+ }
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <div class="panel" :class="additionalClasses">
3
+ <div
4
+ v-if="$slots.header || header"
5
+ class="panel__header"
6
+ :class="{ 'panel__header--toggleable': toggleable }"
7
+ @click="onHeaderClick"
8
+ >
9
+ <button
10
+ v-if="toggleable"
11
+ type="button"
12
+ class="panel__toggle"
13
+ :aria-expanded="!isCollapsed"
14
+ :aria-label="isCollapsed ? 'Expand panel' : 'Collapse panel'"
15
+ >
16
+ <svg
17
+ class="panel__toggle-icon"
18
+ viewBox="0 0 24 24"
19
+ fill="none"
20
+ stroke="currentColor"
21
+ stroke-width="2"
22
+ stroke-linecap="round"
23
+ stroke-linejoin="round"
24
+ >
25
+ <polyline points="6 9 12 15 18 9" />
26
+ </svg>
27
+ </button>
28
+ <slot name="header">
29
+ <span class="panel__title">{{ header }}</span>
30
+ </slot>
31
+ <div v-if="$slots.icons" class="panel__icons">
32
+ <slot name="icons" />
33
+ </div>
34
+ </div>
35
+
36
+ <div class="panel__content-wrapper">
37
+ <div class="panel__content">
38
+ <slot />
39
+ </div>
40
+ </div>
41
+
42
+ <div v-if="$slots.footer" class="panel__footer">
43
+ <slot name="footer" />
44
+ </div>
45
+ </div>
46
+ </template>
47
+
48
+ <style src="./Panel.scss"></style>
49
+
50
+ <script setup lang="ts">
51
+ import type { PanelProps, PanelEmits } from '../../types';
52
+ import { computed, ref, watch } from "vue";
53
+
54
+ defineOptions({ name: 'FtpPanel' });
55
+
56
+ const props = withDefaults(defineProps<PanelProps>(), {
57
+ header: "",
58
+ toggleable: false,
59
+ collapsed: false,
60
+ });
61
+
62
+ const emit = defineEmits(["update:collapsed", "toggle"]);
63
+
64
+ const isCollapsed = ref(props.collapsed);
65
+
66
+ watch(
67
+ () => props.collapsed,
68
+ (newVal) => {
69
+ isCollapsed.value = newVal;
70
+ }
71
+ );
72
+
73
+ const onHeaderClick = () => {
74
+ if (!props.toggleable) return;
75
+
76
+ isCollapsed.value = !isCollapsed.value;
77
+ emit("update:collapsed", isCollapsed.value);
78
+ emit("toggle", { collapsed: isCollapsed.value });
79
+ };
80
+
81
+ const additionalClasses = computed(() =>
82
+ [
83
+ props.toggleable && "panel--toggleable",
84
+ isCollapsed.value && "panel--collapsed",
85
+ ]
86
+ .filter(Boolean)
87
+ .join(" ")
88
+ );
89
+ </script>
@@ -0,0 +1,211 @@
1
+ @use "../../../dist/scss/tokens" as *;
2
+
3
+ $c: panelmenu;
4
+
5
+ .#{$c} {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: var(--panelmenu-gap, $panelmenu-gap);
9
+ width: 100%;
10
+ background-color: var(--panelmenu-background, $panelmenu-background);
11
+ border: var(--panelmenu-border-width, $panelmenu-border-width) solid var(--panelmenu-border-color, $panelmenu-border-color);
12
+ border-radius: var(--panelmenu-border-radius, $panelmenu-border-radius);
13
+ overflow: hidden;
14
+ }
15
+
16
+ .#{$c}__panel {
17
+ &:not(:last-child) {
18
+ border-bottom: var(--panelmenu-border-width, $panelmenu-border-width) solid var(--panelmenu-border-color, $panelmenu-border-color);
19
+ }
20
+ }
21
+
22
+ .#{$c}__header {
23
+ display: flex;
24
+ align-items: center;
25
+ width: 100%;
26
+ padding: var(--panelmenu-header-padding, $panelmenu-header-padding);
27
+ background-color: var(--panelmenu-header-background-default, $panelmenu-header-background-default);
28
+ color: var(--panelmenu-header-color-default, $panelmenu-header-color-default);
29
+ border: none;
30
+ font-family: inherit;
31
+ font-size: inherit;
32
+ font-weight: 500;
33
+ text-align: left;
34
+ cursor: pointer;
35
+ transition: background-color var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease,
36
+ color var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
37
+
38
+ &:hover:not(:disabled) {
39
+ background-color: var(--panelmenu-header-background-hover, $panelmenu-header-background-hover);
40
+ color: var(--panelmenu-header-color-hover, $panelmenu-header-color-hover);
41
+ }
42
+
43
+ &:focus {
44
+ outline: none;
45
+ }
46
+
47
+ &:focus-visible {
48
+ outline: 2px solid var(--panelmenu-item-color-active, $panelmenu-item-color-active);
49
+ outline-offset: -2px;
50
+ }
51
+
52
+ &:disabled {
53
+ cursor: not-allowed;
54
+ color: var(--panelmenu-header-color-disabled, $panelmenu-header-color-disabled);
55
+ }
56
+ }
57
+
58
+ .#{$c}__panel--expanded .#{$c}__header {
59
+ background-color: var(--panelmenu-header-background-active, $panelmenu-header-background-active);
60
+ }
61
+
62
+ .#{$c}__header-icon {
63
+ width: var(--panelmenu-icon-size, $panelmenu-icon-size);
64
+ height: var(--panelmenu-icon-size, $panelmenu-icon-size);
65
+ margin-right: var(--panelmenu-item-gap, $panelmenu-item-gap);
66
+ color: var(--panelmenu-icon-color-default, $panelmenu-icon-color-default);
67
+ flex-shrink: 0;
68
+ }
69
+
70
+ .#{$c}__header-text {
71
+ flex: 1;
72
+ }
73
+
74
+ .#{$c}__chevron {
75
+ width: var(--panelmenu-icon-size, $panelmenu-icon-size);
76
+ height: var(--panelmenu-icon-size, $panelmenu-icon-size);
77
+ color: var(--panelmenu-icon-color-default, $panelmenu-icon-color-default);
78
+ flex-shrink: 0;
79
+ transition: transform var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
80
+ transform: rotate(var(--panelmenu-icon-rotation-collapsed, $panelmenu-icon-rotation-collapsed));
81
+ }
82
+
83
+ .#{$c}__panel--expanded .#{$c}__chevron {
84
+ transform: rotate(var(--panelmenu-icon-rotation-expanded, $panelmenu-icon-rotation-expanded));
85
+ }
86
+
87
+ .#{$c}__content-wrapper {
88
+ display: grid;
89
+ grid-template-rows: 0fr;
90
+ transition: grid-template-rows var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
91
+ }
92
+
93
+ .#{$c}__panel--expanded .#{$c}__content-wrapper {
94
+ grid-template-rows: 1fr;
95
+ }
96
+
97
+ .#{$c}__content {
98
+ overflow: hidden;
99
+ background-color: var(--panelmenu-content-background, $panelmenu-content-background);
100
+ }
101
+
102
+ .#{$c}__list {
103
+ margin: 0;
104
+ padding: var(--panelmenu-content-padding, $panelmenu-content-padding);
105
+ list-style: none;
106
+ }
107
+
108
+ .#{$c}__item {
109
+ position: relative;
110
+ }
111
+
112
+ .#{$c}__link {
113
+ display: flex;
114
+ align-items: center;
115
+ width: 100%;
116
+ gap: var(--panelmenu-item-gap, $panelmenu-item-gap);
117
+ padding: var(--panelmenu-item-padding, $panelmenu-item-padding);
118
+ background-color: var(--panelmenu-item-background-default, $panelmenu-item-background-default);
119
+ color: var(--panelmenu-item-color-default, $panelmenu-item-color-default);
120
+ border: none;
121
+ text-decoration: none;
122
+ font-family: inherit;
123
+ font-size: inherit;
124
+ text-align: left;
125
+ cursor: pointer;
126
+ transition: background-color var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease,
127
+ color var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
128
+
129
+ &:hover:not(:disabled):not([aria-disabled="true"]) {
130
+ background-color: var(--panelmenu-item-background-hover, $panelmenu-item-background-hover);
131
+ color: var(--panelmenu-item-color-hover, $panelmenu-item-color-hover);
132
+ }
133
+
134
+ &:focus {
135
+ outline: none;
136
+ }
137
+
138
+ &:focus-visible {
139
+ outline: 2px solid var(--panelmenu-item-color-active, $panelmenu-item-color-active);
140
+ outline-offset: -2px;
141
+ }
142
+
143
+ &:disabled,
144
+ &[aria-disabled="true"] {
145
+ cursor: not-allowed;
146
+ color: var(--panelmenu-item-color-disabled, $panelmenu-item-color-disabled);
147
+ pointer-events: none;
148
+ }
149
+ }
150
+
151
+ .#{$c}__item--active > .#{$c}__link {
152
+ background-color: var(--panelmenu-item-background-active, $panelmenu-item-background-active);
153
+ color: var(--panelmenu-item-color-active, $panelmenu-item-color-active);
154
+ }
155
+
156
+ .#{$c}__item--disabled > .#{$c}__link {
157
+ cursor: not-allowed;
158
+ color: var(--panelmenu-item-color-disabled, $panelmenu-item-color-disabled);
159
+ pointer-events: none;
160
+ }
161
+
162
+ .#{$c}__icon {
163
+ width: var(--panelmenu-icon-size, $panelmenu-icon-size);
164
+ height: var(--panelmenu-icon-size, $panelmenu-icon-size);
165
+ color: var(--panelmenu-icon-color-default, $panelmenu-icon-color-default);
166
+ flex-shrink: 0;
167
+ }
168
+
169
+ .#{$c}__label {
170
+ flex: 1;
171
+ white-space: nowrap;
172
+ }
173
+
174
+ .#{$c}__submenu-chevron {
175
+ width: 12px;
176
+ height: 12px;
177
+ color: var(--panelmenu-icon-color-default, $panelmenu-icon-color-default);
178
+ flex-shrink: 0;
179
+ transition: transform var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
180
+ transform: rotate(var(--panelmenu-icon-rotation-collapsed, $panelmenu-icon-rotation-collapsed));
181
+ }
182
+
183
+ .#{$c}__item--expanded > .#{$c}__link .#{$c}__submenu-chevron {
184
+ transform: rotate(var(--panelmenu-icon-rotation-expanded, $panelmenu-icon-rotation-expanded));
185
+ }
186
+
187
+ // Submenu
188
+ .#{$c}__submenu {
189
+ display: grid;
190
+ grid-template-rows: 0fr;
191
+ margin: 0;
192
+ padding: 0;
193
+ list-style: none;
194
+ transition: grid-template-rows var(--panelmenu-transition-duration, $panelmenu-transition-duration) ease;
195
+ overflow: hidden;
196
+ }
197
+
198
+ .#{$c}__item--expanded > .#{$c}__submenu {
199
+ grid-template-rows: 1fr;
200
+ }
201
+
202
+ .#{$c}__item--nested > .#{$c}__link {
203
+ padding-left: calc(var(--panelmenu-item-padding, $panelmenu-item-padding) + var(--panelmenu-item-indent, $panelmenu-item-indent));
204
+ }
205
+
206
+ // Separator
207
+ .#{$c}__separator {
208
+ height: 1px;
209
+ margin: var(--panelmenu-separator-margin, $panelmenu-separator-margin) 0;
210
+ background-color: var(--panelmenu-separator-color, $panelmenu-separator-color);
211
+ }