@dolanske/vui 1.4.0 → 1.4.2

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 (214) hide show
  1. package/dist/components/Accordion/Accordion.vue.d.ts +48 -0
  2. package/dist/components/Accordion/AccordionGroup.vue.d.ts +21 -0
  3. package/dist/components/Alert/Alert.vue.d.ts +36 -0
  4. package/dist/components/Avatar/Avatar.vue.d.ts +25 -0
  5. package/dist/components/Badge/Badge.vue.d.ts +22 -0
  6. package/dist/components/Breadcrumbs/BreadcrumbItem.vue.d.ts +22 -0
  7. package/dist/components/Breadcrumbs/Breadcrumbs.vue.d.ts +18 -0
  8. package/dist/components/Button/Button.vue.d.ts +32 -0
  9. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts +22 -0
  10. package/dist/components/Calendar/Calendar.vue.d.ts +27 -0
  11. package/dist/components/Card/Card.vue.d.ts +26 -0
  12. package/dist/components/Checkbox/Checkbox.vue.d.ts +33 -0
  13. package/dist/components/CopyClipboard/CopyClipboard.vue.d.ts +46 -0
  14. package/dist/components/Divider/Divider.vue.d.ts +23 -0
  15. package/dist/components/Drawer/Drawer.vue.d.ts +53 -0
  16. package/dist/components/Dropdown/Dropdown.vue.d.ts +177 -0
  17. package/dist/components/Dropdown/DropdownItem.vue.d.ts +23 -0
  18. package/dist/components/Dropdown/DropdownTitle.vue.d.ts +21 -0
  19. package/dist/components/Flex/Flex.vue.d.ts +41 -0
  20. package/dist/components/Grid/Grid.vue.d.ts +35 -0
  21. package/dist/components/Input/Color.vue.d.ts +11 -0
  22. package/dist/components/Input/Counter.vue.d.ts +19 -0
  23. package/dist/components/Input/Dropzone.vue.d.ts +193 -0
  24. package/dist/components/Input/File.vue.d.ts +8 -0
  25. package/dist/components/Input/Input.vue.d.ts +56 -0
  26. package/dist/components/Input/Password.vue.d.ts +6 -0
  27. package/dist/components/Input/Textarea.vue.d.ts +31 -0
  28. package/dist/components/Kbd/Kbd.vue.d.ts +23 -0
  29. package/dist/components/Kbd/KbdGroup.vue.d.ts +19 -0
  30. package/dist/components/Modal/Confirm.vue.d.ts +43 -0
  31. package/dist/components/Modal/Modal.vue.d.ts +58 -0
  32. package/dist/components/OTP/OTP.vue.d.ts +44 -0
  33. package/dist/components/OTP/OTPItem.vue.d.ts +5 -0
  34. package/dist/components/Pagination/Pagination.vue.d.ts +46 -0
  35. package/dist/components/Pagination/pagination.d.ts +12 -0
  36. package/dist/components/Popout/Popout.vue.d.ts +36 -0
  37. package/dist/components/Progress/Progress.vue.d.ts +33 -0
  38. package/dist/components/Radio/Radio.vue.d.ts +29 -0
  39. package/dist/components/Radio/RadioGroup.vue.d.ts +27 -0
  40. package/dist/components/Select/Select.vue.d.ts +35 -0
  41. package/dist/components/Sheet/Sheet.vue.d.ts +47 -0
  42. package/dist/components/Sidebar/Sidebar.vue.d.ts +70 -0
  43. package/dist/components/Skeleton/Skeleton.vue.d.ts +8 -0
  44. package/dist/components/Spinner/Spinner.vue.d.ts +6 -0
  45. package/dist/components/Switch/Switch.vue.d.ts +28 -0
  46. package/dist/components/Table/Cell.vue.d.ts +22 -0
  47. package/dist/components/Table/Head.vue.d.ts +30 -0
  48. package/dist/components/Table/Root.vue.d.ts +41 -0
  49. package/dist/components/Table/SelectAll.vue.d.ts +2 -0
  50. package/dist/components/Table/SelectRow.vue.d.ts +6 -0
  51. package/dist/components/Table/index.d.ts +6 -0
  52. package/dist/components/Table/table.d.ts +68 -0
  53. package/dist/components/Tabs/Tab.vue.d.ts +22 -0
  54. package/dist/components/Tabs/Tabs.vue.d.ts +34 -0
  55. package/dist/components/Toast/Toasts.vue.d.ts +2 -0
  56. package/dist/components/Toast/toast.d.ts +287 -0
  57. package/dist/components/Tooltip/Tooltip.vue.d.ts +33 -0
  58. package/dist/fonts/GeistMono-Regular.ttf +0 -0
  59. package/dist/fonts/GeistMono-SemiBold.ttf +0 -0
  60. package/dist/fonts/Inter_18pt-Black.ttf +0 -0
  61. package/dist/fonts/Inter_18pt-Bold.ttf +0 -0
  62. package/dist/fonts/Inter_18pt-ExtraBold.ttf +0 -0
  63. package/dist/fonts/Inter_18pt-Light.ttf +0 -0
  64. package/dist/fonts/Inter_18pt-Medium.ttf +0 -0
  65. package/dist/fonts/Inter_18pt-Regular.ttf +0 -0
  66. package/dist/fonts/Inter_18pt-SemiBold.ttf +0 -0
  67. package/dist/index.d.ts +56 -0
  68. package/dist/internal/Backdrop/Backdrop.vue.d.ts +21 -0
  69. package/dist/shared/helpers.d.ts +34 -0
  70. package/dist/shared/slots.d.ts +20 -0
  71. package/dist/shared/theme.d.ts +3 -0
  72. package/dist/shared/types.d.ts +24 -0
  73. package/dist/vui.css +1 -0
  74. package/dist/vui.js +16215 -0
  75. package/package.json +1 -2
  76. package/src/App.vue +0 -103
  77. package/src/components/Accordion/Accordion.vue +0 -98
  78. package/src/components/Accordion/AccordionGroup.vue +0 -49
  79. package/src/components/Accordion/accordion.scss +0 -97
  80. package/src/components/Alert/Alert.vue +0 -59
  81. package/src/components/Alert/alert.scss +0 -162
  82. package/src/components/Avatar/Avatar.vue +0 -53
  83. package/src/components/Avatar/avatar.scss +0 -52
  84. package/src/components/Badge/Badge.vue +0 -21
  85. package/src/components/Badge/badge.scss +0 -210
  86. package/src/components/Breadcrumbs/BreadcrumbItem.vue +0 -26
  87. package/src/components/Breadcrumbs/Breadcrumbs.vue +0 -29
  88. package/src/components/Breadcrumbs/breadcrumbs.scss +0 -31
  89. package/src/components/Button/Button.vue +0 -86
  90. package/src/components/Button/button.scss +0 -292
  91. package/src/components/ButtonGroup/ButtonGroup.vue +0 -28
  92. package/src/components/ButtonGroup/button-group.scss +0 -51
  93. package/src/components/Calendar/Calendar.vue +0 -66
  94. package/src/components/Calendar/calendar.scss +0 -88
  95. package/src/components/Card/Card.vue +0 -48
  96. package/src/components/Card/card.scss +0 -55
  97. package/src/components/Checkbox/Checkbox.vue +0 -54
  98. package/src/components/Checkbox/checkbox.scss +0 -80
  99. package/src/components/CopyClipboard/CopyClipboard.vue +0 -98
  100. package/src/components/CopyClipboard/copy-clipboard.scss +0 -25
  101. package/src/components/Divider/Divider.vue +0 -38
  102. package/src/components/Divider/divider.scss +0 -37
  103. package/src/components/Drawer/Drawer.vue +0 -102
  104. package/src/components/Drawer/drawer.scss +0 -37
  105. package/src/components/Dropdown/Dropdown.vue +0 -120
  106. package/src/components/Dropdown/DropdownItem.vue +0 -33
  107. package/src/components/Dropdown/DropdownTitle.vue +0 -14
  108. package/src/components/Dropdown/dropdown-item.scss +0 -84
  109. package/src/components/Dropdown/dropdown.scss +0 -53
  110. package/src/components/Flex/Flex.vue +0 -113
  111. package/src/components/Grid/Grid.vue +0 -87
  112. package/src/components/Input/Color.vue +0 -26
  113. package/src/components/Input/Counter.vue +0 -66
  114. package/src/components/Input/Dropzone.vue +0 -65
  115. package/src/components/Input/File.vue +0 -15
  116. package/src/components/Input/Input.vue +0 -123
  117. package/src/components/Input/Password.vue +0 -35
  118. package/src/components/Input/Textarea.vue +0 -78
  119. package/src/components/Input/input.scss +0 -302
  120. package/src/components/Kbd/Kbd.vue +0 -48
  121. package/src/components/Kbd/KbdGroup.vue +0 -28
  122. package/src/components/Kbd/kbd.scss +0 -19
  123. package/src/components/Modal/Confirm.vue +0 -56
  124. package/src/components/Modal/Modal.vue +0 -103
  125. package/src/components/Modal/modal.scss +0 -54
  126. package/src/components/OTP/OTP.vue +0 -133
  127. package/src/components/OTP/OTPItem.vue +0 -37
  128. package/src/components/OTP/otp.scss +0 -84
  129. package/src/components/Pagination/Pagination.vue +0 -92
  130. package/src/components/Pagination/pagination.ts +0 -78
  131. package/src/components/Popout/Popout.vue +0 -73
  132. package/src/components/Popout/popout.scss +0 -16
  133. package/src/components/Progress/Progress.vue +0 -103
  134. package/src/components/Progress/progress.scss +0 -47
  135. package/src/components/Radio/Radio.vue +0 -38
  136. package/src/components/Radio/RadioGroup.vue +0 -34
  137. package/src/components/Radio/radio.scss +0 -78
  138. package/src/components/Select/Select.vue +0 -212
  139. package/src/components/Select/select.scss +0 -82
  140. package/src/components/Sheet/Sheet.vue +0 -106
  141. package/src/components/Sheet/sheet.scss +0 -71
  142. package/src/components/Sidebar/Sidebar.vue +0 -116
  143. package/src/components/Sidebar/sidebar.scss +0 -124
  144. package/src/components/Skeleton/Skeleton.vue +0 -43
  145. package/src/components/Skeleton/skeleton.scss +0 -14
  146. package/src/components/Spinner/Spinner.vue +0 -42
  147. package/src/components/Spinner/spinner.scss +0 -47
  148. package/src/components/Switch/Switch.vue +0 -31
  149. package/src/components/Switch/switch.scss +0 -93
  150. package/src/components/Table/Cell.vue +0 -23
  151. package/src/components/Table/Head.vue +0 -66
  152. package/src/components/Table/Root.vue +0 -66
  153. package/src/components/Table/SelectAll.vue +0 -23
  154. package/src/components/Table/SelectRow.vue +0 -30
  155. package/src/components/Table/index.ts +0 -7
  156. package/src/components/Table/table.scss +0 -155
  157. package/src/components/Table/table.ts +0 -248
  158. package/src/components/Tabs/Tab.vue +0 -25
  159. package/src/components/Tabs/Tabs.vue +0 -90
  160. package/src/components/Tabs/tabs.scss +0 -87
  161. package/src/components/Toast/Toasts.vue +0 -52
  162. package/src/components/Toast/toast.scss +0 -45
  163. package/src/components/Toast/toast.ts +0 -75
  164. package/src/components/Tooltip/Tooltip.vue +0 -78
  165. package/src/components/Tooltip/tooltip.scss +0 -5
  166. package/src/examples/ExampleAccordions.vue +0 -69
  167. package/src/examples/ExampleAlerts.vue +0 -78
  168. package/src/examples/ExampleAvatars.vue +0 -44
  169. package/src/examples/ExampleBadges.vue +0 -48
  170. package/src/examples/ExampleBreadcrumbs.vue +0 -46
  171. package/src/examples/ExampleButtons.vue +0 -148
  172. package/src/examples/ExampleCalendars.vue +0 -40
  173. package/src/examples/ExampleCards.vue +0 -94
  174. package/src/examples/ExampleCheckboxes.vue +0 -123
  175. package/src/examples/ExampleCopyClipboard.vue +0 -47
  176. package/src/examples/ExampleDividers.vue +0 -39
  177. package/src/examples/ExampleDrawers.vue +0 -67
  178. package/src/examples/ExampleDropdowns.vue +0 -114
  179. package/src/examples/ExampleFlexGrid.vue +0 -124
  180. package/src/examples/ExampleInputs.vue +0 -236
  181. package/src/examples/ExampleKBD.vue +0 -65
  182. package/src/examples/ExampleModals.vue +0 -143
  183. package/src/examples/ExamplePalette.vue +0 -165
  184. package/src/examples/ExamplePopouts.vue +0 -41
  185. package/src/examples/ExampleSheets.vue +0 -77
  186. package/src/examples/ExampleSidebars.vue +0 -276
  187. package/src/examples/ExampleSkeletons.vue +0 -26
  188. package/src/examples/ExampleSpinners.vue +0 -80
  189. package/src/examples/ExampleTables.vue +0 -359
  190. package/src/examples/ExampleTabs.vue +0 -142
  191. package/src/examples/ExampleToasts.vue +0 -96
  192. package/src/examples/ExampleTooltips.vue +0 -70
  193. package/src/examples/shared/ExampleColor.vue +0 -28
  194. package/src/index.ts +0 -116
  195. package/src/internal/Backdrop/Backdrop.vue +0 -22
  196. package/src/internal/Backdrop/backdrop.scss +0 -34
  197. package/src/main.ts +0 -5
  198. package/src/shared/helpers.ts +0 -124
  199. package/src/shared/slots.ts +0 -61
  200. package/src/shared/theme.ts +0 -22
  201. package/src/shared/types.ts +0 -29
  202. package/src/style/animation.scss +0 -50
  203. package/src/style/core.scss +0 -133
  204. package/src/style/fonts.scss +0 -73
  205. package/src/style/layout.scss +0 -179
  206. package/src/style/media-query.scss +0 -29
  207. package/src/style/reset.scss +0 -135
  208. package/src/style/text.scss +0 -137
  209. package/src/style/theme.scss +0 -195
  210. package/src/style/tooltip.scss +0 -146
  211. package/src/style/typography.scss +0 -435
  212. package/src/style/utils.scss +0 -36
  213. package/src/style.scss +0 -1
  214. package/src/vite-env.d.ts +0 -1
@@ -1,93 +0,0 @@
1
- .vui-switch {
2
- --switch-size: 24px;
3
-
4
- &.checked {
5
- .vui-switch-icon .vui-switch-indicator {
6
- left: calc(100% - 24px);
7
- background-color: var(--color-text);
8
- }
9
-
10
- &.accent .vui-switch-icon .vui-switch-indicator {
11
- background-color: var(--color-accent);
12
- }
13
- }
14
-
15
- &.disabled {
16
- .vui-switch-icon {
17
- opacity: 0.5;
18
- cursor: not-allowed;
19
- }
20
-
21
- input + label .vui-switch-content {
22
- opacity: 0.5;
23
- cursor: not-allowed;
24
- }
25
- }
26
-
27
- .vui-switch-icon {
28
- width: 44px;
29
- height: var(--switch-size);
30
- border-radius: 22px;
31
- background-color: var(--color-bg-raised);
32
- position: relative;
33
- cursor: default;
34
-
35
- .vui-switch-indicator {
36
- display: block;
37
- position: absolute;
38
- left: 2px;
39
- top: 2px;
40
- width: 20px;
41
- height: 20px;
42
- border-radius: 100%;
43
- background-color: var(--color-text-lighter);
44
- transition: var(--transition);
45
- }
46
- }
47
-
48
- input {
49
- width: 1px;
50
- height: 1px;
51
- position: absolute;
52
- overflow: hidden;
53
- outline: none !important;
54
- opacity: 0;
55
-
56
- &:focus-visible + label .vui-switch-icon {
57
- outline: 2px solid var(--color-text);
58
- }
59
-
60
- & + label {
61
- display: grid;
62
- grid-template-columns: 44px 1fr;
63
- gap: 10px;
64
- font-size: var(--font-size-m);
65
- color: var(--color-text);
66
- user-select: none;
67
-
68
- .vui-switch-content {
69
- display: block;
70
-
71
- &:is(p) {
72
- height: var(--switch-size);
73
- line-height: var(--switch-size);
74
- font-size: var(--font-size-m);
75
- }
76
- }
77
- }
78
- }
79
- }
80
-
81
- :root.light {
82
- .vui-switch .vui-switch-icon .vui-switch-indicator {
83
- background-color: var(--color-bg-lowered);
84
- }
85
-
86
- .vui-switch.checked.accent .vui-switch-icon .vui-switch-indicator {
87
- background-color: var(--color-accent);
88
- }
89
-
90
- .vui-switch.checked .vui-switch-icon .vui-switch-indicator {
91
- background-color: var(--color-text);
92
- }
93
- }
@@ -1,23 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, useSlots, useTemplateRef } from 'vue'
3
-
4
- const slots = useSlots()
5
- const contextRef = useTemplateRef<HTMLTableCellElement>('context')
6
- const computedStyle = computed(() => {
7
- if (!slots.context || !window)
8
- return {}
9
- const width = contextRef.value?.getBoundingClientRect().width ?? 0
10
- return {
11
- paddingRight: `${width}px`,
12
- }
13
- })
14
- </script>
15
-
16
- <template>
17
- <td :style="computedStyle">
18
- <slot />
19
- <div v-if="$slots.context" ref="context" class="vui-cell-context">
20
- <slot name="context" />
21
- </div>
22
- </td>
23
- </template>
@@ -1,66 +0,0 @@
1
- <script setup lang="ts">
2
- import type { Header } from './table'
3
- import { computed } from 'vue'
4
- import Button from '../Button/Button.vue'
5
- import Tooltip from '../Tooltip/Tooltip.vue'
6
-
7
- interface Props {
8
- /**
9
- * Main header data. This can be empty in case we are just adding an empty
10
- * padder. It is recommended to just use <th> instead, but this shouldn't fail
11
- * anyway
12
- */
13
- header?: Header
14
- /**
15
- * Enable sorting on this column
16
- */
17
- sort?: boolean
18
- }
19
-
20
- const props = defineProps<Props>()
21
-
22
- const sortStateBind = computed(() => {
23
- if (!props.header)
24
- return
25
- switch (props.header.sortKey) {
26
- case 'asc': return {
27
- icon: 'ph:sort-ascending',
28
- tooltipText: 'Ascending',
29
- }
30
- case 'desc': return {
31
- icon: 'ph:sort-descending',
32
- tooltipText: 'Descending',
33
- }
34
- default: return {
35
- icon: 'ph:arrows-down-up',
36
- tooltipText: 'Sort column',
37
- }
38
- }
39
- })
40
- </script>
41
-
42
- <template>
43
- <th>
44
- <div v-if="props.header || $slots.default" class="vui-table-th-content">
45
- <slot>
46
- {{ props.header?.label }}
47
- </slot>
48
- <template v-if="props.sort && props.header">
49
- <Tooltip placement="top">
50
- <Button
51
- :icon="sortStateBind?.icon"
52
- class="vui-table-sort-button"
53
- size="s"
54
- :plain="!!!props.header.sortKey"
55
- square
56
- variant="gray"
57
- @click="props.header.sortToggle"
58
- />
59
- <template #tooltip>
60
- {{ sortStateBind?.tooltipText }}
61
- </template>
62
- </Tooltip>
63
- </template>
64
- </div>
65
- </th>
66
- </template>
@@ -1,66 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { TableSelectionProvide } from './table'
3
- import { inject } from 'vue'
4
- import { TableSelectionProvideSymbol } from './table'
5
- import './table.scss'
6
-
7
- interface Props {
8
- /**
9
- * Sets the `table-layout` property
10
- */
11
- fixed?: boolean
12
- /**
13
- * Table cells with content overflowing on new line will be cropped
14
- */
15
- nowrap?: boolean
16
- /**
17
- * Add a visual separator between each row
18
- */
19
- separateRows?: boolean
20
- /**
21
- * Add a visual separator between each cell
22
- */
23
- separateCells?: boolean
24
- /**
25
- * Wrap table with a border
26
- */
27
- outerBorder?: boolean
28
- }
29
-
30
- const {
31
- fixed,
32
- nowrap,
33
- separateRows = true,
34
- separateCells = false,
35
- outerBorder = true,
36
- } = defineProps<Props>()
37
- const selecting = inject(TableSelectionProvideSymbol) as TableSelectionProvide
38
- </script>
39
-
40
- <template>
41
- <div
42
- class="vui-table-container"
43
- :class="{
44
- fixed,
45
- nowrap,
46
- 'selecting': selecting.enabled,
47
- 'separated-rows': separateRows,
48
- 'separated-cells': separateCells,
49
- 'outer-border': outerBorder,
50
- }"
51
- >
52
- <table>
53
- <thead v-if="$slots.header">
54
- <tr>
55
- <slot name="header" />
56
- </tr>
57
- </thead>
58
- <tbody>
59
- <slot name="body" />
60
- </tbody>
61
- </table>
62
- <div v-if="$slots.pagination" class="vui-table-pagination-wrap">
63
- <slot name="pagination" />
64
- </div>
65
- </div>
66
- </template>
@@ -1,23 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { TableSelectionProvide } from './table'
3
- import { inject } from 'vue'
4
- import Button from '../Button/Button.vue'
5
- import { TableSelectionProvideSymbol } from './table'
6
-
7
- const {
8
- isSelectedAll,
9
- enabled,
10
- selectAllRows,
11
- } = inject(TableSelectionProvideSymbol) as TableSelectionProvide
12
- </script>
13
-
14
- <template>
15
- <th v-if="enabled" class="vui-table-interactive-cell" :class="{ selected: isSelectedAll }">
16
- <Button
17
- square
18
- plain
19
- :icon="isSelectedAll ? 'ph:check-square-fill' : 'ph:square'"
20
- @click="selectAllRows()"
21
- />
22
- </th>
23
- </template>
@@ -1,30 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { BaseRow, TableSelectionProvide } from './table'
3
- import { computed, inject } from 'vue'
4
- import { isObjectInSet } from '../../shared/helpers'
5
- import Button from '../Button/Button.vue'
6
- import { TableSelectionProvideSymbol } from './table'
7
-
8
- interface Props {
9
- row: BaseRow
10
- }
11
-
12
- const props = defineProps<Props>()
13
- const {
14
- enabled,
15
- selectRow,
16
- selectedRows,
17
- } = inject(TableSelectionProvideSymbol) as TableSelectionProvide
18
- const isSelected = computed(() => isObjectInSet(selectedRows.value, props.row))
19
- </script>
20
-
21
- <template>
22
- <td v-if="enabled" class="vui-table-interactive-cell" :class="{ selected: isSelected }">
23
- <Button
24
- square
25
- plain
26
- :icon="isSelected ? 'ph:check-square-fill' : 'ph:square'"
27
- @click="selectRow(props.row)"
28
- />
29
- </td>
30
- </template>
@@ -1,7 +0,0 @@
1
- import Cell from './Cell.vue'
2
- import Head from './Head.vue'
3
- import Root from './Root.vue'
4
- import SelectAll from './SelectAll.vue'
5
- import SelectRow from './SelectRow.vue'
6
-
7
- export { Cell, Head, Root, SelectAll, SelectRow }
@@ -1,155 +0,0 @@
1
- .vui-table-overflow {
2
- display: block;
3
- max-width: 100%;
4
- overflow-x: auto;
5
- overflow-y: visible;
6
- }
7
-
8
- .vui-table-container {
9
- display: block;
10
- width: 100%;
11
- border-radius: var(--border-radius-m);
12
-
13
- &.fixed table {
14
- table-layout: fixed;
15
- }
16
-
17
- &.outer-border {
18
- border: 1px solid var(--color-border);
19
- }
20
-
21
- &.nowrap table tr {
22
- td {
23
- white-space: nowrap;
24
- overflow: hidden;
25
- text-overflow: ellipsis;
26
- }
27
- }
28
-
29
- &.separated-rows table {
30
- th,
31
- td {
32
- border-bottom: 1px solid var(--color-border);
33
- }
34
- }
35
-
36
- &.separated-cells table {
37
- th,
38
- td {
39
- border-right: 1px solid var(--color-border);
40
-
41
- &:last-of-type {
42
- border-right: none;
43
- }
44
- }
45
- }
46
-
47
- table {
48
- width: 100%;
49
- border-collapse: collapse;
50
- text-indent: 0;
51
- border: none;
52
- overflow: unset;
53
-
54
- tr {
55
- border: none;
56
-
57
- &:first-child td {
58
- border-top: 0 !important;
59
- }
60
-
61
- &:has(.vui-table-interactive-cell.selected) {
62
- td {
63
- background-color: var(--color-bg-raised);
64
- }
65
- }
66
-
67
- &:last-child td {
68
- border-bottom: 0;
69
- }
70
- }
71
-
72
- th {
73
- border-top: 0 !important;
74
- }
75
-
76
- th,
77
- td {
78
- border: none;
79
- border-left: none !important;
80
- transition: var(--transition-fast);
81
- position: relative;
82
- z-index: var(--z-default);
83
-
84
- // Fixed width, only houses a checkbox component
85
- &.vui-table-interactive-cell {
86
- --checkbox-cell-width: calc(calc(var(--space-xs) * 2) + 32px);
87
- width: var(--checkbox-cell-width);
88
- min-width: var(--checkbox-cell-width);
89
- max-width: var(--checkbox-cell-width);
90
- height: auto;
91
- padding-inline: var(--space-xs);
92
- padding-block: 0;
93
- vertical-align: middle;
94
-
95
- &.selected .vui-button.icon .vui-button-slot svg path {
96
- color: var(--color-text) !important;
97
- }
98
-
99
- .vui-button {
100
- vertical-align: middle;
101
- display: inline-flex;
102
-
103
- &.icon .vui-button-slot svg {
104
- width: 22px !important;
105
- height: 22px !important;
106
-
107
- path {
108
- color: var(--color-text-light);
109
- }
110
- }
111
- }
112
- }
113
-
114
- .vui-cell-context {
115
- display: flex;
116
- align-items: center;
117
- justify-content: center;
118
- z-index: var(--z-active);
119
- position: absolute;
120
- inset: 0;
121
- padding: var(--space-xs);
122
- background-color: var(--color-bg);
123
- left: unset;
124
- }
125
- }
126
-
127
- th {
128
- .vui-table-th-content {
129
- color: var(--color-text);
130
- font-size: var(--font-size-xs);
131
- text-transform: uppercase;
132
- font-weight: var(--font-weight-semibold);
133
- display: flex;
134
- justify-content: flex-start;
135
- align-items: center;
136
- gap: var(--space-xs);
137
-
138
- .vui-table-sort-button:not(.active) svg path {
139
- color: var(--color-text-light);
140
- }
141
- }
142
- }
143
- }
144
-
145
- .vui-table-pagination-wrap {
146
- padding: var(--space-xs) var(--space-m);
147
- border-top: 1px solid var(--color-border);
148
- }
149
- }
150
-
151
- :root.light {
152
- .vui-table-container table tr:has(.vui-table-interactive-cell.selected) td {
153
- background-color: var(--color-bg-medium);
154
- }
155
- }
@@ -1,248 +0,0 @@
1
- import type { ComputedRef, InjectionKey, MaybeRefOrGetter, Ref } from 'vue'
2
- import type { DeepRequired } from '../../shared/types'
3
- import { computed, provide, readonly, ref, toValue } from 'vue'
4
- import { searchString } from '../../shared/helpers'
5
- import { paginate } from '../Pagination/pagination'
6
-
7
- export type BaseRow = Record<string, string | number>
8
-
9
- export interface TableSelectionProvide {
10
- selectedRows: Ref<Set<BaseRow>>
11
- selectRow: (row: BaseRow) => void
12
- selectAllRows: () => void
13
- enabled: ComputedRef<boolean>
14
- isSelectedAll: ComputedRef<boolean>
15
- }
16
-
17
- export const TableSelectionProvideSymbol = Symbol('select-row-provide') as InjectionKey<TableSelectionProvide>
18
-
19
- interface Sorting<K> {
20
- key?: K
21
- type: 'asc' | 'desc'
22
- }
23
-
24
- export interface Header {
25
- label: string
26
- sortToggle: () => void
27
- sortKey?: 'asc' | 'desc'
28
-
29
- }
30
-
31
- interface TableOptionsInput {
32
- pagination?: {
33
- enabled?: boolean
34
- perPage?: number
35
- maxPages?: number
36
- }
37
- select?: boolean
38
- }
39
-
40
- // eslint-disable-next-line ts/explicit-function-return-type
41
- export function defineTable<const Dataset extends any[]>(
42
- computedDataset: MaybeRefOrGetter<Dataset>,
43
- tableOptions?: TableOptionsInput,
44
- ) {
45
- const $data = computed(() => toValue(computedDataset))
46
-
47
- //
48
- // Reactive options + defaults
49
- const options = ref(Object.assign({
50
- pagination: {
51
- enabled: false,
52
- perPage: 10,
53
- maxPages: 3,
54
- },
55
- select: false,
56
- }, tableOptions) as DeepRequired<TableOptionsInput>)
57
-
58
- //
59
- // Pagination
60
- const currentPage = ref(1)
61
-
62
- const pagination = computed(() => paginate(
63
- $data.value.length,
64
- currentPage.value,
65
- options.value.pagination?.perPage,
66
- options.value.pagination?.maxPages,
67
- ))
68
-
69
- const canNextPage = computed(() => pagination.value.currentPage < pagination.value.endPage)
70
- const canPrevPage = computed(() => pagination.value.currentPage > pagination.value.startPage)
71
-
72
- /**
73
- * Sets the currently active data page. Please note that you provide the page
74
- * number, no its index. So this is 1-indexed input
75
- *
76
- * @param page Page number
77
- */
78
- const setPage = (page: number): void => {
79
- if ((page > currentPage.value && canNextPage.value)
80
- || (page < currentPage.value && canPrevPage.value)) {
81
- currentPage.value = page
82
- }
83
- }
84
-
85
- //
86
- // Sorting
87
-
88
- const sorting = ref<Sorting<Ref<keyof Dataset[number]>>>({
89
- key: undefined,
90
- type: 'asc',
91
- })
92
-
93
- const setSort = (key: keyof Dataset[number], type: 'asc' | 'desc' | 'toggle' = 'asc'): void => {
94
- sorting.value.key = key
95
- sorting.value.type = type === 'toggle'
96
- // Toggle between descending & ascending whenever the set sort fn is called
97
- ? sorting.value.type === 'asc' ? 'desc' : 'asc'
98
- : type
99
- }
100
-
101
- const clearSort = (): void => {
102
- sorting.value.key = undefined
103
- sorting.value.type = 'asc'
104
- }
105
-
106
- //
107
- // Searching
108
- const search = ref<string>()
109
-
110
- //
111
- // Dataset formatting
112
- const filteredRows = computed(() => {
113
- const searchValue = search.value
114
- let final = $data.value
115
-
116
- if (searchValue) {
117
- final = final.filter((row: Dataset[number]) => {
118
- const matches = Object
119
- .values(row)
120
- .map(row => `${row}`)
121
- return searchString(matches, searchValue)
122
- }) as Dataset
123
- }
124
-
125
- const key = sorting.value.key
126
-
127
- if (key) {
128
- // FIXME: change to `toSorted` when typescript is ok
129
- final = [...final].sort((a: Dataset[number], b: Dataset[number]) => {
130
- const aValue = a[key]
131
- const bValue = b[key]
132
- return sorting.value.type === 'asc'
133
- ? aValue > bValue ? 1 : -1
134
- : aValue > bValue ? -1 : 1
135
- }) as Dataset
136
- }
137
-
138
- return final
139
- })
140
-
141
- const headers = computed(() => Object
142
- .keys($data.value[0] || {})
143
- .map((key) => {
144
- return {
145
- label: key,
146
- sortKey: sorting.value.key === key && sorting.value.type,
147
- sortToggle: () => {
148
- // 3-way toggle asc -> desc -> turn off (reset to undefined)
149
- if (sorting.value.key === key) {
150
- switch (sorting.value.type) {
151
- case 'asc': {
152
- sorting.value.type = 'desc'
153
- break
154
- }
155
- case 'desc': {
156
- sorting.value.key = undefined
157
- sorting.value.key = 'asc'
158
- break
159
- }
160
- default: {
161
- sorting.value.key = key
162
- sorting.value.type = 'asc'
163
- break
164
- }
165
- }
166
- }
167
- else {
168
- setSort(key)
169
- }
170
- },
171
- } as Header
172
- }),
173
- )
174
-
175
- const rows = computed(() => {
176
- if (options.value.pagination?.enabled === true) {
177
- return filteredRows.value.slice(
178
- pagination.value.startIndex,
179
- pagination.value.endIndex + 1,
180
- ) as Dataset
181
- }
182
- return filteredRows.value as Dataset
183
- })
184
-
185
- //
186
- // Row selecting
187
- const selectedRows = ref<Set<BaseRow>>(new Set() as Set<BaseRow>)
188
- const selectingEnabled = computed(() => options.value.select)
189
-
190
- /**
191
- * Accepts either an existing index of a row within the dataset or the dataset
192
- * row itself. If the item is already selected, it will be deselected.
193
- *
194
- * @param row {Number | RowObject}
195
- */
196
- function selectRow(row: Dataset[number]): void {
197
- if (selectedRows.value.has(row)) {
198
- selectedRows.value.delete(row)
199
- }
200
- else {
201
- selectedRows.value.add(row)
202
- }
203
- }
204
-
205
- const isSelectedAll = computed(() => $data.value.length === selectedRows.value.size)
206
-
207
- function selectAllRows(): void {
208
- if (isSelectedAll.value) {
209
- // If the selected indexes have the same length as the data array, we can
210
- // assume all of them are selected. Therefore we toggle it by deselecting
211
- // all of them
212
- selectedRows.value = new Set()
213
- }
214
- else {
215
- const data = new Set<BaseRow>()
216
- for (const item of $data.value) {
217
- data.add(item)
218
- }
219
- selectedRows.value = new Set(data)
220
- }
221
- }
222
-
223
- provide(TableSelectionProvideSymbol, {
224
- selectedRows,
225
- selectRow,
226
- selectAllRows,
227
- enabled: selectingEnabled,
228
- isSelectedAll,
229
- })
230
-
231
- return {
232
- setSort,
233
- clearSort,
234
- search,
235
- rows: readonly(rows),
236
- allRows: readonly(filteredRows),
237
- selectedRows: readonly(selectedRows),
238
- headers: readonly(headers),
239
- pagination,
240
- canPrevPage,
241
- canNextPage,
242
- setPage,
243
- options,
244
- selectRow,
245
- selectAllRows,
246
- isSelectedAll,
247
- }
248
- }