@furystack/shades-common-components 12.3.0 → 12.5.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 (268) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/esm/components/app-bar-link.spec.js +16 -19
  3. package/esm/components/app-bar-link.spec.js.map +1 -1
  4. package/esm/components/app-bar.spec.js +6 -4
  5. package/esm/components/app-bar.spec.js.map +1 -1
  6. package/esm/components/avatar.spec.js +9 -9
  7. package/esm/components/avatar.spec.js.map +1 -1
  8. package/esm/components/breadcrumb.spec.js +2 -2
  9. package/esm/components/breadcrumb.spec.js.map +1 -1
  10. package/esm/components/button-group.d.ts +32 -0
  11. package/esm/components/button-group.d.ts.map +1 -1
  12. package/esm/components/button-group.js +26 -2
  13. package/esm/components/button-group.js.map +1 -1
  14. package/esm/components/button-group.spec.js +127 -11
  15. package/esm/components/button-group.spec.js.map +1 -1
  16. package/esm/components/button.spec.js +4 -4
  17. package/esm/components/button.spec.js.map +1 -1
  18. package/esm/components/cache-view.spec.js +2 -3
  19. package/esm/components/cache-view.spec.js.map +1 -1
  20. package/esm/components/carousel.spec.js +47 -47
  21. package/esm/components/carousel.spec.js.map +1 -1
  22. package/esm/components/circular-progress.spec.js +2 -2
  23. package/esm/components/command-palette/command-palette-input.spec.js +23 -19
  24. package/esm/components/command-palette/command-palette-input.spec.js.map +1 -1
  25. package/esm/components/command-palette/command-palette-suggestion-list.spec.js +27 -27
  26. package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -1
  27. package/esm/components/command-palette/index.spec.js +64 -51
  28. package/esm/components/command-palette/index.spec.js.map +1 -1
  29. package/esm/components/context-menu/context-menu.spec.js +33 -33
  30. package/esm/components/context-menu/context-menu.spec.js.map +1 -1
  31. package/esm/components/data-grid/body.spec.js +13 -13
  32. package/esm/components/data-grid/body.spec.js.map +1 -1
  33. package/esm/components/data-grid/data-grid-row.spec.js +8 -8
  34. package/esm/components/data-grid/data-grid-row.spec.js.map +1 -1
  35. package/esm/components/data-grid/data-grid.d.ts +40 -2
  36. package/esm/components/data-grid/data-grid.d.ts.map +1 -1
  37. package/esm/components/data-grid/data-grid.js +7 -10
  38. package/esm/components/data-grid/data-grid.js.map +1 -1
  39. package/esm/components/data-grid/data-grid.spec.js +71 -28
  40. package/esm/components/data-grid/data-grid.spec.js.map +1 -1
  41. package/esm/components/data-grid/filters/boolean-filter.d.ts +12 -0
  42. package/esm/components/data-grid/filters/boolean-filter.d.ts.map +1 -0
  43. package/esm/components/data-grid/filters/boolean-filter.js +27 -0
  44. package/esm/components/data-grid/filters/boolean-filter.js.map +1 -0
  45. package/esm/components/data-grid/filters/boolean-filter.spec.d.ts +2 -0
  46. package/esm/components/data-grid/filters/boolean-filter.spec.d.ts.map +1 -0
  47. package/esm/components/data-grid/filters/boolean-filter.spec.js +114 -0
  48. package/esm/components/data-grid/filters/boolean-filter.spec.js.map +1 -0
  49. package/esm/components/data-grid/filters/date-filter.d.ts +12 -0
  50. package/esm/components/data-grid/filters/date-filter.d.ts.map +1 -0
  51. package/esm/components/data-grid/filters/date-filter.js +109 -0
  52. package/esm/components/data-grid/filters/date-filter.js.map +1 -0
  53. package/esm/components/data-grid/filters/date-filter.spec.d.ts +2 -0
  54. package/esm/components/data-grid/filters/date-filter.spec.d.ts.map +1 -0
  55. package/esm/components/data-grid/filters/date-filter.spec.js +145 -0
  56. package/esm/components/data-grid/filters/date-filter.spec.js.map +1 -0
  57. package/esm/components/data-grid/filters/enum-filter.d.ts +16 -0
  58. package/esm/components/data-grid/filters/enum-filter.d.ts.map +1 -0
  59. package/esm/components/data-grid/filters/enum-filter.js +72 -0
  60. package/esm/components/data-grid/filters/enum-filter.js.map +1 -0
  61. package/esm/components/data-grid/filters/enum-filter.spec.d.ts +2 -0
  62. package/esm/components/data-grid/filters/enum-filter.spec.d.ts.map +1 -0
  63. package/esm/components/data-grid/filters/enum-filter.spec.js +136 -0
  64. package/esm/components/data-grid/filters/enum-filter.spec.js.map +1 -0
  65. package/esm/components/data-grid/filters/filter-dropdown.d.ts +6 -0
  66. package/esm/components/data-grid/filters/filter-dropdown.d.ts.map +1 -0
  67. package/esm/components/data-grid/filters/filter-dropdown.js +41 -0
  68. package/esm/components/data-grid/filters/filter-dropdown.js.map +1 -0
  69. package/esm/components/data-grid/filters/filter-dropdown.spec.d.ts +2 -0
  70. package/esm/components/data-grid/filters/filter-dropdown.spec.d.ts.map +1 -0
  71. package/esm/components/data-grid/filters/filter-dropdown.spec.js +69 -0
  72. package/esm/components/data-grid/filters/filter-dropdown.spec.js.map +1 -0
  73. package/esm/components/data-grid/filters/filter-styles.d.ts +24 -0
  74. package/esm/components/data-grid/filters/filter-styles.d.ts.map +1 -0
  75. package/esm/components/data-grid/filters/filter-styles.js +25 -0
  76. package/esm/components/data-grid/filters/filter-styles.js.map +1 -0
  77. package/esm/components/data-grid/filters/index.d.ts +7 -0
  78. package/esm/components/data-grid/filters/index.d.ts.map +1 -0
  79. package/esm/components/data-grid/filters/index.js +7 -0
  80. package/esm/components/data-grid/filters/index.js.map +1 -0
  81. package/esm/components/data-grid/filters/number-filter.d.ts +12 -0
  82. package/esm/components/data-grid/filters/number-filter.d.ts.map +1 -0
  83. package/esm/components/data-grid/filters/number-filter.js +65 -0
  84. package/esm/components/data-grid/filters/number-filter.js.map +1 -0
  85. package/esm/components/data-grid/filters/number-filter.spec.d.ts +2 -0
  86. package/esm/components/data-grid/filters/number-filter.spec.d.ts.map +1 -0
  87. package/esm/components/data-grid/filters/number-filter.spec.js +142 -0
  88. package/esm/components/data-grid/filters/number-filter.spec.js.map +1 -0
  89. package/esm/components/data-grid/filters/string-filter.d.ts +12 -0
  90. package/esm/components/data-grid/filters/string-filter.d.ts.map +1 -0
  91. package/esm/components/data-grid/filters/string-filter.js +63 -0
  92. package/esm/components/data-grid/filters/string-filter.js.map +1 -0
  93. package/esm/components/data-grid/filters/string-filter.spec.d.ts +2 -0
  94. package/esm/components/data-grid/filters/string-filter.spec.d.ts.map +1 -0
  95. package/esm/components/data-grid/filters/string-filter.spec.js +128 -0
  96. package/esm/components/data-grid/filters/string-filter.spec.js.map +1 -0
  97. package/esm/components/data-grid/footer.d.ts.map +1 -1
  98. package/esm/components/data-grid/footer.js +24 -9
  99. package/esm/components/data-grid/footer.js.map +1 -1
  100. package/esm/components/data-grid/footer.spec.js +38 -36
  101. package/esm/components/data-grid/footer.spec.js.map +1 -1
  102. package/esm/components/data-grid/header.d.ts +6 -9
  103. package/esm/components/data-grid/header.d.ts.map +1 -1
  104. package/esm/components/data-grid/header.js +51 -117
  105. package/esm/components/data-grid/header.js.map +1 -1
  106. package/esm/components/data-grid/header.spec.js +116 -187
  107. package/esm/components/data-grid/header.spec.js.map +1 -1
  108. package/esm/components/data-grid/index.d.ts +1 -0
  109. package/esm/components/data-grid/index.d.ts.map +1 -1
  110. package/esm/components/data-grid/index.js +1 -0
  111. package/esm/components/data-grid/index.js.map +1 -1
  112. package/esm/components/data-grid/selection-cell.spec.js +8 -8
  113. package/esm/components/data-grid/selection-cell.spec.js.map +1 -1
  114. package/esm/components/drawer/drawer-toggle-button.spec.js +22 -22
  115. package/esm/components/drawer/drawer-toggle-button.spec.js.map +1 -1
  116. package/esm/components/drawer/index.spec.js +36 -36
  117. package/esm/components/drawer/index.spec.js.map +1 -1
  118. package/esm/components/dropdown.spec.js +38 -30
  119. package/esm/components/dropdown.spec.js.map +1 -1
  120. package/esm/components/fab.spec.js +4 -4
  121. package/esm/components/fab.spec.js.map +1 -1
  122. package/esm/components/form.d.ts +5 -2
  123. package/esm/components/form.d.ts.map +1 -1
  124. package/esm/components/form.js +28 -6
  125. package/esm/components/form.js.map +1 -1
  126. package/esm/components/form.spec.js +227 -20
  127. package/esm/components/form.spec.js.map +1 -1
  128. package/esm/components/grid.spec.js +3 -3
  129. package/esm/components/grid.spec.js.map +1 -1
  130. package/esm/components/image.spec.js +55 -52
  131. package/esm/components/image.spec.js.map +1 -1
  132. package/esm/components/inputs/autocomplete.spec.js +7 -14
  133. package/esm/components/inputs/autocomplete.spec.js.map +1 -1
  134. package/esm/components/inputs/checkbox.spec.js +22 -22
  135. package/esm/components/inputs/checkbox.spec.js.map +1 -1
  136. package/esm/components/inputs/input-number.spec.js +47 -47
  137. package/esm/components/inputs/input-number.spec.js.map +1 -1
  138. package/esm/components/inputs/input.spec.js +53 -53
  139. package/esm/components/inputs/input.spec.js.map +1 -1
  140. package/esm/components/inputs/radio-group.spec.js +14 -14
  141. package/esm/components/inputs/radio-group.spec.js.map +1 -1
  142. package/esm/components/inputs/radio.spec.js +16 -16
  143. package/esm/components/inputs/radio.spec.js.map +1 -1
  144. package/esm/components/inputs/select.spec.js +74 -74
  145. package/esm/components/inputs/select.spec.js.map +1 -1
  146. package/esm/components/inputs/slider.spec.js +16 -16
  147. package/esm/components/inputs/slider.spec.js.map +1 -1
  148. package/esm/components/inputs/switch.spec.js +24 -24
  149. package/esm/components/inputs/switch.spec.js.map +1 -1
  150. package/esm/components/inputs/text-area.spec.js +17 -17
  151. package/esm/components/inputs/text-area.spec.js.map +1 -1
  152. package/esm/components/linear-progress.spec.js +2 -2
  153. package/esm/components/list/list.spec.js +36 -36
  154. package/esm/components/list/list.spec.js.map +1 -1
  155. package/esm/components/markdown/markdown-display.spec.js +15 -15
  156. package/esm/components/markdown/markdown-display.spec.js.map +1 -1
  157. package/esm/components/markdown/markdown-editor.spec.js +8 -8
  158. package/esm/components/markdown/markdown-editor.spec.js.map +1 -1
  159. package/esm/components/markdown/markdown-input.spec.js +17 -17
  160. package/esm/components/markdown/markdown-input.spec.js.map +1 -1
  161. package/esm/components/menu/menu.spec.js +28 -28
  162. package/esm/components/menu/menu.spec.js.map +1 -1
  163. package/esm/components/modal.spec.js +15 -18
  164. package/esm/components/modal.spec.js.map +1 -1
  165. package/esm/components/noty-list.spec.js +25 -23
  166. package/esm/components/noty-list.spec.js.map +1 -1
  167. package/esm/components/page-container/index.spec.js +16 -16
  168. package/esm/components/page-container/index.spec.js.map +1 -1
  169. package/esm/components/page-container/page-header.spec.js +16 -16
  170. package/esm/components/page-container/page-header.spec.js.map +1 -1
  171. package/esm/components/page-layout/index.spec.js +29 -29
  172. package/esm/components/page-layout/index.spec.js.map +1 -1
  173. package/esm/components/paper.spec.js +3 -3
  174. package/esm/components/paper.spec.js.map +1 -1
  175. package/esm/components/rating.spec.js +61 -61
  176. package/esm/components/rating.spec.js.map +1 -1
  177. package/esm/components/skeleton.spec.js +10 -6
  178. package/esm/components/skeleton.spec.js.map +1 -1
  179. package/esm/components/suggest/suggest-input.spec.js +4 -10
  180. package/esm/components/suggest/suggest-input.spec.js.map +1 -1
  181. package/esm/components/tabs.spec.js +30 -30
  182. package/esm/components/tabs.spec.js.map +1 -1
  183. package/esm/components/tree/tree.spec.js +27 -27
  184. package/esm/components/tree/tree.spec.js.map +1 -1
  185. package/esm/components/typography.spec.js +3 -3
  186. package/esm/components/typography.spec.js.map +1 -1
  187. package/esm/components/wizard/index.spec.js +5 -5
  188. package/esm/components/wizard/index.spec.js.map +1 -1
  189. package/esm/utils/promisify-animation.d.ts.map +1 -1
  190. package/esm/utils/promisify-animation.js +3 -0
  191. package/esm/utils/promisify-animation.js.map +1 -1
  192. package/package.json +2 -2
  193. package/src/components/app-bar-link.spec.tsx +16 -19
  194. package/src/components/app-bar.spec.tsx +6 -4
  195. package/src/components/avatar.spec.tsx +9 -9
  196. package/src/components/breadcrumb.spec.tsx +2 -2
  197. package/src/components/button-group.spec.tsx +155 -11
  198. package/src/components/button-group.tsx +49 -2
  199. package/src/components/button.spec.tsx +4 -4
  200. package/src/components/cache-view.spec.tsx +3 -3
  201. package/src/components/carousel.spec.tsx +47 -47
  202. package/src/components/circular-progress.spec.tsx +2 -2
  203. package/src/components/command-palette/command-palette-input.spec.tsx +23 -19
  204. package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +27 -27
  205. package/src/components/command-palette/index.spec.tsx +64 -51
  206. package/src/components/context-menu/context-menu.spec.tsx +33 -33
  207. package/src/components/data-grid/body.spec.tsx +13 -13
  208. package/src/components/data-grid/data-grid-row.spec.tsx +8 -8
  209. package/src/components/data-grid/data-grid.spec.tsx +106 -28
  210. package/src/components/data-grid/data-grid.tsx +44 -11
  211. package/src/components/data-grid/filters/boolean-filter.spec.tsx +142 -0
  212. package/src/components/data-grid/filters/boolean-filter.tsx +45 -0
  213. package/src/components/data-grid/filters/date-filter.spec.tsx +181 -0
  214. package/src/components/data-grid/filters/date-filter.tsx +162 -0
  215. package/src/components/data-grid/filters/enum-filter.spec.tsx +168 -0
  216. package/src/components/data-grid/filters/enum-filter.tsx +119 -0
  217. package/src/components/data-grid/filters/filter-dropdown.spec.tsx +89 -0
  218. package/src/components/data-grid/filters/filter-dropdown.tsx +60 -0
  219. package/src/components/data-grid/filters/filter-styles.ts +26 -0
  220. package/src/components/data-grid/filters/index.ts +6 -0
  221. package/src/components/data-grid/filters/number-filter.spec.tsx +174 -0
  222. package/src/components/data-grid/filters/number-filter.tsx +115 -0
  223. package/src/components/data-grid/filters/string-filter.spec.tsx +157 -0
  224. package/src/components/data-grid/filters/string-filter.tsx +112 -0
  225. package/src/components/data-grid/footer.spec.tsx +38 -36
  226. package/src/components/data-grid/footer.tsx +21 -8
  227. package/src/components/data-grid/header.spec.tsx +128 -212
  228. package/src/components/data-grid/header.tsx +95 -183
  229. package/src/components/data-grid/index.tsx +1 -0
  230. package/src/components/data-grid/selection-cell.spec.tsx +8 -8
  231. package/src/components/drawer/drawer-toggle-button.spec.tsx +22 -22
  232. package/src/components/drawer/index.spec.tsx +36 -36
  233. package/src/components/dropdown.spec.tsx +38 -30
  234. package/src/components/fab.spec.tsx +4 -4
  235. package/src/components/form.spec.tsx +329 -20
  236. package/src/components/form.tsx +31 -8
  237. package/src/components/grid.spec.tsx +3 -3
  238. package/src/components/image.spec.tsx +55 -52
  239. package/src/components/inputs/autocomplete.spec.tsx +7 -14
  240. package/src/components/inputs/checkbox.spec.tsx +22 -22
  241. package/src/components/inputs/input-number.spec.tsx +47 -47
  242. package/src/components/inputs/input.spec.tsx +53 -53
  243. package/src/components/inputs/radio-group.spec.tsx +14 -14
  244. package/src/components/inputs/radio.spec.tsx +16 -16
  245. package/src/components/inputs/select.spec.tsx +74 -74
  246. package/src/components/inputs/slider.spec.tsx +16 -16
  247. package/src/components/inputs/switch.spec.tsx +24 -24
  248. package/src/components/inputs/text-area.spec.tsx +17 -17
  249. package/src/components/linear-progress.spec.tsx +2 -2
  250. package/src/components/list/list.spec.tsx +36 -36
  251. package/src/components/markdown/markdown-display.spec.tsx +15 -15
  252. package/src/components/markdown/markdown-editor.spec.tsx +8 -8
  253. package/src/components/markdown/markdown-input.spec.tsx +17 -17
  254. package/src/components/menu/menu.spec.tsx +28 -28
  255. package/src/components/modal.spec.tsx +15 -18
  256. package/src/components/noty-list.spec.tsx +25 -23
  257. package/src/components/page-container/index.spec.tsx +16 -16
  258. package/src/components/page-container/page-header.spec.tsx +16 -16
  259. package/src/components/page-layout/index.spec.tsx +29 -29
  260. package/src/components/paper.spec.tsx +3 -3
  261. package/src/components/rating.spec.tsx +61 -61
  262. package/src/components/skeleton.spec.tsx +10 -6
  263. package/src/components/suggest/suggest-input.spec.tsx +4 -10
  264. package/src/components/tabs.spec.tsx +30 -30
  265. package/src/components/tree/tree.spec.tsx +27 -27
  266. package/src/components/typography.spec.tsx +3 -3
  267. package/src/components/wizard/index.spec.tsx +5 -5
  268. package/src/utils/promisify-animation.ts +3 -0
@@ -0,0 +1,112 @@
1
+ import { createComponent, Shade } from '@furystack/shades'
2
+ import type { ObservableValue } from '@furystack/utils'
3
+ import { Button } from '../../button.js'
4
+ import { SegmentedControl } from '../../button-group.js'
5
+ import { Icon } from '../../icons/icon.js'
6
+ import { close as closeIcon, search as searchIcon } from '../../icons/icon-definitions.js'
7
+ import type { FilterableFindOptions } from '../data-grid.js'
8
+ import { filterBaseCss, filterInputCss } from './filter-styles.js'
9
+
10
+ type StringOperator = '$regex' | '$startsWith' | '$endsWith' | '$eq'
11
+
12
+ const operatorLabels: Record<StringOperator, string> = {
13
+ $regex: 'Contains',
14
+ $startsWith: 'Starts with',
15
+ $endsWith: 'Ends with',
16
+ $eq: 'Equals',
17
+ }
18
+
19
+ export const StringFilter = Shade<{
20
+ field: string
21
+ findOptions: ObservableValue<FilterableFindOptions>
22
+ onClose: () => void
23
+ }>({
24
+ shadowDomName: 'data-grid-string-filter',
25
+ css: {
26
+ ...filterBaseCss,
27
+ '& input': filterInputCss,
28
+ },
29
+ render: ({ props, useObservable, useState }) => {
30
+ const [findOptions, setFindOptions] = useObservable('findOptions', props.findOptions)
31
+
32
+ const currentFilter = findOptions.filter?.[props.field] as Record<string, string> | undefined
33
+ const currentOperator: StringOperator = currentFilter
34
+ ? ((Object.keys(currentFilter).find((k) => k in operatorLabels) as StringOperator) ?? '$regex')
35
+ : '$regex'
36
+ const currentValue = currentFilter?.[currentOperator] ?? ''
37
+
38
+ const applyFilter = (operator: StringOperator, value: string) => {
39
+ const filter = { ...findOptions.filter }
40
+ if (!value) {
41
+ delete filter[props.field]
42
+ } else {
43
+ filter[props.field] = { [operator]: value }
44
+ }
45
+ setFindOptions({ ...findOptions, filter, skip: 0 })
46
+ props.onClose()
47
+ }
48
+
49
+ const clearFilter = () => {
50
+ const filter = { ...findOptions.filter }
51
+ delete filter[props.field]
52
+ setFindOptions({ ...findOptions, filter, skip: 0 })
53
+ props.onClose()
54
+ }
55
+
56
+ const [selectedOperator, setSelectedOperator] = useState<StringOperator>('selectedOperator', currentOperator)
57
+ let inputValue = currentValue
58
+
59
+ return (
60
+ <form
61
+ onsubmit={(ev: Event) => {
62
+ ev.preventDefault()
63
+ applyFilter(selectedOperator, inputValue)
64
+ }}
65
+ >
66
+ <div className="filter-row">
67
+ <SegmentedControl
68
+ size="small"
69
+ value={selectedOperator}
70
+ onValueChange={(v) => setSelectedOperator(v as StringOperator)}
71
+ options={(Object.keys(operatorLabels) as StringOperator[]).map((op) => ({
72
+ value: op,
73
+ label: operatorLabels[op],
74
+ }))}
75
+ />
76
+ </div>
77
+ <div className="filter-row">
78
+ <input
79
+ data-testid="string-filter-value"
80
+ type="text"
81
+ placeholder="Filter value..."
82
+ value={currentValue}
83
+ autofocus
84
+ oninput={(ev: Event) => {
85
+ inputValue = (ev.target as HTMLInputElement).value
86
+ }}
87
+ />
88
+ </div>
89
+ <div className="filter-actions">
90
+ <Button
91
+ type="button"
92
+ variant="outlined"
93
+ size="small"
94
+ onclick={clearFilter}
95
+ startIcon={<Icon icon={closeIcon} size={14} />}
96
+ >
97
+ Clear
98
+ </Button>
99
+ <Button
100
+ type="submit"
101
+ variant="outlined"
102
+ size="small"
103
+ color="primary"
104
+ startIcon={<Icon icon={searchIcon} size={14} />}
105
+ >
106
+ Apply
107
+ </Button>
108
+ </div>
109
+ </form>
110
+ )
111
+ },
112
+ })
@@ -1,7 +1,7 @@
1
1
  import type { FindOptions } from '@furystack/core'
2
2
  import { Injector } from '@furystack/inject'
3
- import { createComponent, initializeShadeRoot } from '@furystack/shades'
4
- import { ObservableValue, sleepAsync, usingAsync } from '@furystack/utils'
3
+ import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
4
+ import { ObservableValue, usingAsync } from '@furystack/utils'
5
5
  import { afterEach, beforeEach, describe, expect, it } from 'vitest'
6
6
  import { CollectionService } from '../../services/collection-service.js'
7
7
  import { DataGridFooter, dataGridItemsPerPage } from './footer.js'
@@ -42,7 +42,7 @@ describe('DataGridFooter', () => {
42
42
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
43
43
  })
44
44
 
45
- await sleepAsync(50)
45
+ await flushUpdates()
46
46
 
47
47
  const footer = document.querySelector('shade-data-grid-footer')
48
48
  expect(footer).not.toBeNull()
@@ -61,7 +61,7 @@ describe('DataGridFooter', () => {
61
61
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
62
62
  })
63
63
 
64
- await sleepAsync(50)
64
+ await flushUpdates()
65
65
 
66
66
  const footer = document.querySelector('shade-data-grid-footer')
67
67
  const selects = footer?.querySelectorAll('select')
@@ -82,13 +82,13 @@ describe('DataGridFooter', () => {
82
82
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
83
83
  })
84
84
 
85
- await sleepAsync(50)
85
+ await flushUpdates()
86
86
 
87
87
  const footer = document.querySelector('shade-data-grid-footer')
88
88
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
89
89
  const itemsPerPageSelect = selects.find((s) => {
90
- const parent = s.parentElement
91
- return parent?.textContent?.includes('items per page')
90
+ const parent = s.closest('.pager-section')
91
+ return parent?.textContent?.includes('Rows per page')
92
92
  })
93
93
 
94
94
  expect(itemsPerPageSelect).toBeDefined()
@@ -109,11 +109,11 @@ describe('DataGridFooter', () => {
109
109
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
110
110
  })
111
111
 
112
- await sleepAsync(50)
112
+ await flushUpdates()
113
113
 
114
114
  const footer = document.querySelector('shade-data-grid-footer')
115
115
  const pager = footer?.querySelector('.pager')
116
- expect(pager?.textContent).toContain('Goto page')
116
+ expect(pager?.textContent).toContain('Page')
117
117
  })
118
118
  })
119
119
 
@@ -129,11 +129,13 @@ describe('DataGridFooter', () => {
129
129
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
130
130
  })
131
131
 
132
- await sleepAsync(50)
132
+ await flushUpdates()
133
133
 
134
134
  const footer = document.querySelector('shade-data-grid-footer')
135
135
  const pager = footer?.querySelector('.pager')
136
- expect(pager?.textContent).not.toContain('Goto page')
136
+ const sections = Array.from(pager?.querySelectorAll('.pager-section') ?? [])
137
+ const pageSection = sections.find((s) => s.textContent?.includes('Page'))
138
+ expect(pageSection).toBeUndefined()
137
139
  })
138
140
  })
139
141
 
@@ -149,13 +151,13 @@ describe('DataGridFooter', () => {
149
151
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
150
152
  })
151
153
 
152
- await sleepAsync(50)
154
+ await flushUpdates()
153
155
 
154
156
  const footer = document.querySelector('shade-data-grid-footer')
155
157
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
156
158
  const pageSelect = selects.find((s) => {
157
- const parent = s.parentElement
158
- return parent?.textContent?.includes('Goto page')
159
+ const parent = s.closest('.pager-section')
160
+ return parent?.textContent?.includes('Page')
159
161
  })
160
162
 
161
163
  expect(pageSelect).toBeDefined()
@@ -176,13 +178,13 @@ describe('DataGridFooter', () => {
176
178
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
177
179
  })
178
180
 
179
- await sleepAsync(50)
181
+ await flushUpdates()
180
182
 
181
183
  const footer = document.querySelector('shade-data-grid-footer')
182
184
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
183
185
  const pageSelect = selects.find((s) => {
184
- const parent = s.parentElement
185
- return parent?.textContent?.includes('Goto page')
186
+ const parent = s.closest('.pager-section')
187
+ return parent?.textContent?.includes('Page')
186
188
  })
187
189
 
188
190
  expect(pageSelect).toBeDefined()
@@ -190,7 +192,7 @@ describe('DataGridFooter', () => {
190
192
  pageSelect!.value = '2'
191
193
  pageSelect!.dispatchEvent(new Event('change', { bubbles: true }))
192
194
 
193
- await sleepAsync(50)
195
+ await flushUpdates()
194
196
 
195
197
  const updatedOptions = findOptions.getValue()
196
198
  expect(updatedOptions.skip).toBe(20)
@@ -209,13 +211,13 @@ describe('DataGridFooter', () => {
209
211
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
210
212
  })
211
213
 
212
- await sleepAsync(50)
214
+ await flushUpdates()
213
215
 
214
216
  const footer = document.querySelector('shade-data-grid-footer')
215
217
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
216
218
  const itemsPerPageSelect = selects.find((s) => {
217
- const parent = s.parentElement
218
- return parent?.textContent?.includes('items per page')
219
+ const parent = s.closest('.pager-section')
220
+ return parent?.textContent?.includes('Rows per page')
219
221
  })
220
222
 
221
223
  expect(itemsPerPageSelect).toBeDefined()
@@ -223,7 +225,7 @@ describe('DataGridFooter', () => {
223
225
  itemsPerPageSelect!.value = '25'
224
226
  itemsPerPageSelect!.dispatchEvent(new Event('change', { bubbles: true }))
225
227
 
226
- await sleepAsync(50)
228
+ await flushUpdates()
227
229
 
228
230
  const updatedOptions = findOptions.getValue()
229
231
  expect(updatedOptions.top).toBe(25)
@@ -242,13 +244,13 @@ describe('DataGridFooter', () => {
242
244
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
243
245
  })
244
246
 
245
- await sleepAsync(50)
247
+ await flushUpdates()
246
248
 
247
249
  const footer = document.querySelector('shade-data-grid-footer')
248
250
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
249
251
  const itemsPerPageSelect = selects.find((s) => {
250
- const parent = s.parentElement
251
- return parent?.textContent?.includes('items per page')
252
+ const parent = s.closest('.pager-section')
253
+ return parent?.textContent?.includes('Rows per page')
252
254
  })
253
255
 
254
256
  expect(itemsPerPageSelect).toBeDefined()
@@ -256,7 +258,7 @@ describe('DataGridFooter', () => {
256
258
  itemsPerPageSelect!.value = '25'
257
259
  itemsPerPageSelect!.dispatchEvent(new Event('change', { bubbles: true }))
258
260
 
259
- await sleepAsync(50)
261
+ await flushUpdates()
260
262
 
261
263
  const updatedOptions = findOptions.getValue()
262
264
  expect(updatedOptions.top).toBe(25)
@@ -276,13 +278,13 @@ describe('DataGridFooter', () => {
276
278
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
277
279
  })
278
280
 
279
- await sleepAsync(50)
281
+ await flushUpdates()
280
282
 
281
283
  const footer = document.querySelector('shade-data-grid-footer')
282
284
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
283
285
  const pageSelect = selects.find((s) => {
284
- const parent = s.parentElement
285
- return parent?.textContent?.includes('Goto page')
286
+ const parent = s.closest('.pager-section')
287
+ return parent?.textContent?.includes('Page')
286
288
  })
287
289
 
288
290
  expect(pageSelect).toBeDefined()
@@ -302,13 +304,13 @@ describe('DataGridFooter', () => {
302
304
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
303
305
  })
304
306
 
305
- await sleepAsync(50)
307
+ await flushUpdates()
306
308
 
307
309
  const footer = document.querySelector('shade-data-grid-footer')
308
310
  const selects = Array.from(footer?.querySelectorAll('select') ?? [])
309
311
  const itemsPerPageSelect = selects.find((s) => {
310
- const parent = s.parentElement
311
- return parent?.textContent?.includes('items per page')
312
+ const parent = s.closest('.pager-section')
313
+ return parent?.textContent?.includes('Rows per page')
312
314
  })
313
315
 
314
316
  expect(itemsPerPageSelect).toBeDefined()
@@ -328,22 +330,22 @@ describe('DataGridFooter', () => {
328
330
  jsxElement: <DataGridFooter service={service} findOptions={findOptions} />,
329
331
  })
330
332
 
331
- await sleepAsync(50)
333
+ await flushUpdates()
332
334
 
333
335
  let footer = document.querySelector('shade-data-grid-footer')
334
336
  let selects = Array.from(footer?.querySelectorAll('select') ?? [])
335
- let pageSelect = selects.find((s) => s.parentElement?.textContent?.includes('Goto page'))
337
+ let pageSelect = selects.find((s) => s.closest('.pager-section')?.textContent?.includes('Page'))
336
338
  let pageOptions = pageSelect?.querySelectorAll('option')
337
339
 
338
340
  expect(pageOptions?.length).toBe(5)
339
341
 
340
342
  service.data.setValue({ entries: [], count: 100 })
341
343
 
342
- await sleepAsync(50)
344
+ await flushUpdates()
343
345
 
344
346
  footer = document.querySelector('shade-data-grid-footer')
345
347
  selects = Array.from(footer?.querySelectorAll('select') ?? [])
346
- pageSelect = selects.find((s) => s.parentElement?.textContent?.includes('Goto page'))
348
+ pageSelect = selects.find((s) => s.closest('.pager-section')?.textContent?.includes('Page'))
347
349
  pageOptions = pageSelect?.querySelectorAll('option')
348
350
 
349
351
  expect(pageOptions?.length).toBe(10)
@@ -20,11 +20,24 @@ export const DataGridFooter: <T>(props: {
20
20
  bottom: '0',
21
21
  display: 'flex',
22
22
  justifyContent: 'flex-end',
23
- padding: '1em',
23
+ padding: '8px 12px',
24
24
  alignItems: 'center',
25
+ gap: '16px',
26
+ fontSize: cssVariableTheme.typography.fontSize.xs,
27
+ },
28
+ '& .pager-section': {
29
+ display: 'flex',
30
+ alignItems: 'center',
31
+ gap: '6px',
25
32
  },
26
33
  '& select': {
27
- margin: '0 1em',
34
+ padding: '4px 8px',
35
+ borderRadius: cssVariableTheme.shape.borderRadius.sm,
36
+ border: `1px solid ${cssVariableTheme.divider}`,
37
+ background: cssVariableTheme.background.default,
38
+ color: cssVariableTheme.text.primary,
39
+ fontSize: cssVariableTheme.typography.fontSize.xs,
40
+ cursor: 'pointer',
28
41
  },
29
42
  },
30
43
  render: ({ props, useObservable }) => {
@@ -48,8 +61,8 @@ export const DataGridFooter: <T>(props: {
48
61
  return (
49
62
  <div className="pager">
50
63
  {currentEntriesPerPage !== Infinity && (
51
- <div>
52
- Goto page
64
+ <div className="pager-section">
65
+ <span>Page</span>
53
66
  <select
54
67
  onchange={(ev) => {
55
68
  const value = parseInt((ev.target as HTMLInputElement).value, 10)
@@ -62,10 +75,11 @@ export const DataGridFooter: <T>(props: {
62
75
  </option>
63
76
  ))}
64
77
  </select>
78
+ <span>of {pages.length}</span>
65
79
  </div>
66
80
  )}
67
- <div>
68
- Show
81
+ <div className="pager-section">
82
+ <span>Rows per page</span>
69
83
  <select
70
84
  onchange={(ev) => {
71
85
  const value = parseInt((ev.currentTarget as HTMLInputElement).value, 10)
@@ -78,11 +92,10 @@ export const DataGridFooter: <T>(props: {
78
92
  >
79
93
  {dataGridItemsPerPage.map((no) => (
80
94
  <option value={no.toString()} selected={no === currentEntriesPerPage}>
81
- {no.toString()}
95
+ {no === Infinity ? 'All' : no.toString()}
82
96
  </option>
83
97
  ))}
84
98
  </select>
85
- items per page
86
99
  </div>
87
100
  </div>
88
101
  )