@refraktor/core 0.0.1 → 0.0.3

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 (290) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/build/components/breadcrumbs/breadcrumbs.d.ts +4 -0
  3. package/build/components/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  4. package/build/components/breadcrumbs/breadcrumbs.js +64 -0
  5. package/build/components/breadcrumbs/breadcrumbs.styles.d.ts +12 -0
  6. package/build/components/breadcrumbs/breadcrumbs.styles.d.ts.map +1 -0
  7. package/build/components/breadcrumbs/breadcrumbs.styles.js +43 -0
  8. package/build/components/breadcrumbs/breadcrumbs.test.d.ts +2 -0
  9. package/build/components/breadcrumbs/breadcrumbs.test.d.ts.map +1 -0
  10. package/build/components/breadcrumbs/breadcrumbs.test.js +72 -0
  11. package/build/components/breadcrumbs/breadcrumbs.types.d.ts +56 -0
  12. package/build/components/breadcrumbs/breadcrumbs.types.d.ts.map +1 -0
  13. package/build/components/breadcrumbs/breadcrumbs.types.js +1 -0
  14. package/build/components/breadcrumbs/breadcrumbs.utils.d.ts +10 -0
  15. package/build/components/breadcrumbs/breadcrumbs.utils.d.ts.map +1 -0
  16. package/build/components/breadcrumbs/breadcrumbs.utils.js +36 -0
  17. package/build/components/breadcrumbs/index.d.ts +3 -0
  18. package/build/components/breadcrumbs/index.d.ts.map +1 -0
  19. package/build/components/breadcrumbs/index.js +1 -0
  20. package/build/components/drawer/drawer-close/drawer-close.d.ts +4 -0
  21. package/build/components/drawer/drawer-close/drawer-close.d.ts.map +1 -0
  22. package/build/components/drawer/drawer-close/drawer-close.js +19 -0
  23. package/build/components/drawer/drawer-close/index.d.ts +2 -0
  24. package/build/components/drawer/drawer-close/index.d.ts.map +1 -0
  25. package/build/components/drawer/drawer-close/index.js +1 -0
  26. package/build/components/drawer/drawer-content/drawer-content.d.ts +4 -0
  27. package/build/components/drawer/drawer-content/drawer-content.d.ts.map +1 -0
  28. package/build/components/drawer/drawer-content/drawer-content.js +41 -0
  29. package/build/components/drawer/drawer-content/index.d.ts +2 -0
  30. package/build/components/drawer/drawer-content/index.d.ts.map +1 -0
  31. package/build/components/drawer/drawer-content/index.js +1 -0
  32. package/build/components/drawer/drawer-header/drawer-header.d.ts +4 -0
  33. package/build/components/drawer/drawer-header/drawer-header.d.ts.map +1 -0
  34. package/build/components/drawer/drawer-header/drawer-header.js +13 -0
  35. package/build/components/drawer/drawer-header/index.d.ts +2 -0
  36. package/build/components/drawer/drawer-header/index.d.ts.map +1 -0
  37. package/build/components/drawer/drawer-header/index.js +1 -0
  38. package/build/components/drawer/drawer-overlay/drawer-overlay.d.ts +4 -0
  39. package/build/components/drawer/drawer-overlay/drawer-overlay.d.ts.map +1 -0
  40. package/build/components/drawer/drawer-overlay/drawer-overlay.js +31 -0
  41. package/build/components/drawer/drawer-overlay/index.d.ts +2 -0
  42. package/build/components/drawer/drawer-overlay/index.d.ts.map +1 -0
  43. package/build/components/drawer/drawer-overlay/index.js +1 -0
  44. package/build/components/drawer/drawer-root/drawer-root.d.ts +4 -0
  45. package/build/components/drawer/drawer-root/drawer-root.d.ts.map +1 -0
  46. package/build/components/drawer/drawer-root/drawer-root.js +50 -0
  47. package/build/components/drawer/drawer-root/index.d.ts +2 -0
  48. package/build/components/drawer/drawer-root/index.d.ts.map +1 -0
  49. package/build/components/drawer/drawer-root/index.js +1 -0
  50. package/build/components/drawer/drawer.context.d.ts +23 -0
  51. package/build/components/drawer/drawer.context.d.ts.map +1 -0
  52. package/build/components/drawer/drawer.context.js +2 -0
  53. package/build/components/drawer/drawer.d.ts +4 -0
  54. package/build/components/drawer/drawer.d.ts.map +1 -0
  55. package/build/components/drawer/drawer.js +19 -0
  56. package/build/components/drawer/drawer.styles.d.ts +6 -0
  57. package/build/components/drawer/drawer.styles.d.ts.map +1 -0
  58. package/build/components/drawer/drawer.styles.js +21 -0
  59. package/build/components/drawer/drawer.test.d.ts +2 -0
  60. package/build/components/drawer/drawer.test.d.ts.map +1 -0
  61. package/build/components/drawer/drawer.test.js +70 -0
  62. package/build/components/drawer/drawer.types.d.ts +116 -0
  63. package/build/components/drawer/drawer.types.d.ts.map +1 -0
  64. package/build/components/drawer/drawer.types.js +1 -0
  65. package/build/components/drawer/index.d.ts +8 -0
  66. package/build/components/drawer/index.d.ts.map +1 -0
  67. package/build/components/drawer/index.js +6 -0
  68. package/build/components/drawer/use-drawer.d.ts +17 -0
  69. package/build/components/drawer/use-drawer.d.ts.map +1 -0
  70. package/build/components/drawer/use-drawer.js +61 -0
  71. package/build/components/index.d.ts +4 -0
  72. package/build/components/index.d.ts.map +1 -1
  73. package/build/components/index.js +4 -0
  74. package/build/components/menu/menu-dropdown/menu-dropdown.d.ts.map +1 -1
  75. package/build/components/menu/menu-dropdown/menu-dropdown.js +3 -2
  76. package/build/components/menu/menu-sub-dropdown/menu-sub-dropdown.d.ts.map +1 -1
  77. package/build/components/menu/menu-sub-dropdown/menu-sub-dropdown.js +2 -1
  78. package/build/components/menu/use-menu.d.ts.map +1 -1
  79. package/build/components/menu/use-menu.js +2 -1
  80. package/build/components/modal/modal-close/modal-close.d.ts.map +1 -1
  81. package/build/components/modal/modal-close/modal-close.js +1 -1
  82. package/build/components/modal/modal-content/modal-content.d.ts.map +1 -1
  83. package/build/components/modal/modal-content/modal-content.js +1 -1
  84. package/build/components/modal/modal-header/modal-header.d.ts.map +1 -1
  85. package/build/components/modal/modal-header/modal-header.js +1 -1
  86. package/build/components/modal/modal-overlay/modal-overlay.d.ts.map +1 -1
  87. package/build/components/modal/modal-overlay/modal-overlay.js +10 -2
  88. package/build/components/modal/modal.test.js +16 -0
  89. package/build/components/modal/modal.types.d.ts +4 -0
  90. package/build/components/modal/modal.types.d.ts.map +1 -1
  91. package/build/components/number-input/number-input.d.ts.map +1 -1
  92. package/build/components/number-input/number-input.js +22 -15
  93. package/build/components/number-input/number-input.test.d.ts +2 -0
  94. package/build/components/number-input/number-input.test.d.ts.map +1 -0
  95. package/build/components/number-input/number-input.test.js +14 -0
  96. package/build/components/number-input/number-input.types.d.ts +2 -2
  97. package/build/components/number-input/number-input.types.d.ts.map +1 -1
  98. package/build/components/popover/popover-dropdown/popover-dropdown.d.ts.map +1 -1
  99. package/build/components/popover/popover-dropdown/popover-dropdown.js +2 -1
  100. package/build/components/popover/use-popover.d.ts.map +1 -1
  101. package/build/components/popover/use-popover.js +2 -1
  102. package/build/components/portal/portal.js +1 -1
  103. package/build/components/segmented-control/index.d.ts +3 -0
  104. package/build/components/segmented-control/index.d.ts.map +1 -0
  105. package/build/components/segmented-control/index.js +1 -0
  106. package/build/components/segmented-control/segmented-control.d.ts +4 -0
  107. package/build/components/segmented-control/segmented-control.d.ts.map +1 -0
  108. package/build/components/segmented-control/segmented-control.js +113 -0
  109. package/build/components/segmented-control/segmented-control.styles.d.ts +9 -0
  110. package/build/components/segmented-control/segmented-control.styles.d.ts.map +1 -0
  111. package/build/components/segmented-control/segmented-control.styles.js +28 -0
  112. package/build/components/segmented-control/segmented-control.test.d.ts +2 -0
  113. package/build/components/segmented-control/segmented-control.test.d.ts.map +1 -0
  114. package/build/components/segmented-control/segmented-control.test.js +81 -0
  115. package/build/components/segmented-control/segmented-control.types.d.ts +49 -0
  116. package/build/components/segmented-control/segmented-control.types.d.ts.map +1 -0
  117. package/build/components/segmented-control/segmented-control.types.js +1 -0
  118. package/build/components/select/select-dropdown/select-dropdown.d.ts.map +1 -1
  119. package/build/components/select/select-dropdown/select-dropdown.js +3 -2
  120. package/build/components/select/select-item/select-item.d.ts.map +1 -1
  121. package/build/components/select/select-item/select-item.js +1 -1
  122. package/build/components/select/select-root/select-root.d.ts.map +1 -1
  123. package/build/components/select/select-root/select-root.js +36 -6
  124. package/build/components/select/select-trigger/select-trigger.d.ts.map +1 -1
  125. package/build/components/select/select-trigger/select-trigger.js +1 -1
  126. package/build/components/select/select.context.d.ts +2 -0
  127. package/build/components/select/select.context.d.ts.map +1 -1
  128. package/build/components/select/select.test.js +17 -0
  129. package/build/components/select/select.types.d.ts +10 -0
  130. package/build/components/select/select.types.d.ts.map +1 -1
  131. package/build/components/select/use-select.d.ts.map +1 -1
  132. package/build/components/select/use-select.js +2 -1
  133. package/build/components/split-pane/index.d.ts +3 -0
  134. package/build/components/split-pane/index.d.ts.map +1 -0
  135. package/build/components/split-pane/index.js +1 -0
  136. package/build/components/split-pane/split-pane.d.ts +4 -0
  137. package/build/components/split-pane/split-pane.d.ts.map +1 -0
  138. package/build/components/split-pane/split-pane.js +201 -0
  139. package/build/components/split-pane/split-pane.styles.d.ts +3 -0
  140. package/build/components/split-pane/split-pane.styles.d.ts.map +1 -0
  141. package/build/components/split-pane/split-pane.styles.js +8 -0
  142. package/build/components/split-pane/split-pane.test.d.ts +2 -0
  143. package/build/components/split-pane/split-pane.test.d.ts.map +1 -0
  144. package/build/components/split-pane/split-pane.test.js +105 -0
  145. package/build/components/split-pane/split-pane.types.d.ts +51 -0
  146. package/build/components/split-pane/split-pane.types.d.ts.map +1 -0
  147. package/build/components/split-pane/split-pane.types.js +1 -0
  148. package/build/components/switch/switch.js +1 -1
  149. package/build/components/table/index.d.ts +9 -0
  150. package/build/components/table/index.d.ts.map +1 -0
  151. package/build/components/table/index.js +7 -0
  152. package/build/components/table/table-body/index.d.ts +2 -0
  153. package/build/components/table/table-body/index.d.ts.map +1 -0
  154. package/build/components/table/table-body/index.js +1 -0
  155. package/build/components/table/table-body/table-body.d.ts +4 -0
  156. package/build/components/table/table-body/table-body.d.ts.map +1 -0
  157. package/build/components/table/table-body/table-body.js +17 -0
  158. package/build/components/table/table-caption/index.d.ts +2 -0
  159. package/build/components/table/table-caption/index.d.ts.map +1 -0
  160. package/build/components/table/table-caption/index.js +1 -0
  161. package/build/components/table/table-caption/table-caption.d.ts +4 -0
  162. package/build/components/table/table-caption/table-caption.d.ts.map +1 -0
  163. package/build/components/table/table-caption/table-caption.js +13 -0
  164. package/build/components/table/table-cell/index.d.ts +2 -0
  165. package/build/components/table/table-cell/index.d.ts.map +1 -0
  166. package/build/components/table/table-cell/index.js +1 -0
  167. package/build/components/table/table-cell/table-cell.d.ts +4 -0
  168. package/build/components/table/table-cell/table-cell.d.ts.map +1 -0
  169. package/build/components/table/table-cell/table-cell.js +13 -0
  170. package/build/components/table/table-head/index.d.ts +2 -0
  171. package/build/components/table/table-head/index.d.ts.map +1 -0
  172. package/build/components/table/table-head/index.js +1 -0
  173. package/build/components/table/table-head/table-head.d.ts +4 -0
  174. package/build/components/table/table-head/table-head.d.ts.map +1 -0
  175. package/build/components/table/table-head/table-head.js +11 -0
  176. package/build/components/table/table-header-cell/index.d.ts +2 -0
  177. package/build/components/table/table-header-cell/index.d.ts.map +1 -0
  178. package/build/components/table/table-header-cell/index.js +1 -0
  179. package/build/components/table/table-header-cell/table-header-cell.d.ts +4 -0
  180. package/build/components/table/table-header-cell/table-header-cell.d.ts.map +1 -0
  181. package/build/components/table/table-header-cell/table-header-cell.js +13 -0
  182. package/build/components/table/table-row/index.d.ts +2 -0
  183. package/build/components/table/table-row/index.d.ts.map +1 -0
  184. package/build/components/table/table-row/index.js +1 -0
  185. package/build/components/table/table-row/table-row.d.ts +4 -0
  186. package/build/components/table/table-row/table-row.d.ts.map +1 -0
  187. package/build/components/table/table-row/table-row.js +11 -0
  188. package/build/components/table/table.context.d.ts +16 -0
  189. package/build/components/table/table.context.d.ts.map +1 -0
  190. package/build/components/table/table.context.js +2 -0
  191. package/build/components/table/table.d.ts +4 -0
  192. package/build/components/table/table.d.ts.map +1 -0
  193. package/build/components/table/table.js +46 -0
  194. package/build/components/table/table.styles.d.ts +16 -0
  195. package/build/components/table/table.styles.d.ts.map +1 -0
  196. package/build/components/table/table.styles.js +39 -0
  197. package/build/components/table/table.test.d.ts +2 -0
  198. package/build/components/table/table.test.d.ts.map +1 -0
  199. package/build/components/table/table.test.js +59 -0
  200. package/build/components/table/table.types.d.ts +113 -0
  201. package/build/components/table/table.types.d.ts.map +1 -0
  202. package/build/components/table/table.types.js +1 -0
  203. package/build/components/tabs/tabs-tab/tabs-tab.d.ts.map +1 -1
  204. package/build/components/tabs/tabs-tab/tabs-tab.js +0 -6
  205. package/build/components/tooltip/tooltip.d.ts.map +1 -1
  206. package/build/components/tooltip/tooltip.js +7 -3
  207. package/build/components/tooltip/use-tooltip.d.ts.map +1 -1
  208. package/build/components/tooltip/use-tooltip.js +2 -1
  209. package/build/components/transition/transition.d.ts.map +1 -1
  210. package/build/components/transition/transition.js +16 -12
  211. package/build/style.css +1 -1
  212. package/package.json +2 -2
  213. package/src/components/breadcrumbs/breadcrumbs.styles.ts +55 -0
  214. package/src/components/breadcrumbs/breadcrumbs.test.tsx +136 -0
  215. package/src/components/breadcrumbs/breadcrumbs.tsx +199 -0
  216. package/src/components/breadcrumbs/breadcrumbs.types.ts +78 -0
  217. package/src/components/breadcrumbs/breadcrumbs.utils.ts +70 -0
  218. package/src/components/breadcrumbs/index.ts +6 -0
  219. package/src/components/drawer/drawer-close/drawer-close.tsx +43 -0
  220. package/src/components/drawer/drawer-close/index.ts +1 -0
  221. package/src/components/drawer/drawer-content/drawer-content.tsx +98 -0
  222. package/src/components/drawer/drawer-content/index.ts +1 -0
  223. package/src/components/drawer/drawer-header/drawer-header.tsx +40 -0
  224. package/src/components/drawer/drawer-header/index.ts +1 -0
  225. package/src/components/drawer/drawer-overlay/drawer-overlay.tsx +86 -0
  226. package/src/components/drawer/drawer-overlay/index.ts +1 -0
  227. package/src/components/drawer/drawer-root/drawer-root.tsx +94 -0
  228. package/src/components/drawer/drawer-root/index.ts +1 -0
  229. package/src/components/drawer/drawer.context.ts +25 -0
  230. package/src/components/drawer/drawer.styles.ts +32 -0
  231. package/src/components/drawer/drawer.test.tsx +166 -0
  232. package/src/components/drawer/drawer.tsx +30 -0
  233. package/src/components/drawer/drawer.types.ts +158 -0
  234. package/src/components/drawer/index.ts +16 -0
  235. package/src/components/drawer/use-drawer.ts +101 -0
  236. package/src/components/index.ts +10 -6
  237. package/src/components/menu/menu-dropdown/menu-dropdown.tsx +4 -3
  238. package/src/components/menu/menu-sub-dropdown/menu-sub-dropdown.tsx +2 -0
  239. package/src/components/menu/use-menu.ts +2 -1
  240. package/src/components/modal/modal-close/modal-close.tsx +1 -5
  241. package/src/components/modal/modal-content/modal-content.tsx +3 -4
  242. package/src/components/modal/modal-header/modal-header.tsx +4 -2
  243. package/src/components/modal/modal-overlay/modal-overlay.tsx +66 -44
  244. package/src/components/modal/modal.test.tsx +124 -88
  245. package/src/components/modal/modal.types.ts +6 -0
  246. package/src/components/modal/use-modal.ts +101 -101
  247. package/src/components/number-input/number-input.test.tsx +22 -0
  248. package/src/components/number-input/number-input.tsx +79 -51
  249. package/src/components/number-input/number-input.types.ts +8 -8
  250. package/src/components/popover/popover-dropdown/popover-dropdown.tsx +2 -0
  251. package/src/components/popover/use-popover.ts +2 -1
  252. package/src/components/portal/portal.tsx +1 -1
  253. package/src/components/segmented-control/index.ts +6 -0
  254. package/src/components/segmented-control/segmented-control.styles.ts +37 -0
  255. package/src/components/segmented-control/segmented-control.test.tsx +152 -0
  256. package/src/components/segmented-control/segmented-control.tsx +245 -0
  257. package/src/components/segmented-control/segmented-control.types.ts +75 -0
  258. package/src/components/select/select-dropdown/select-dropdown.tsx +4 -3
  259. package/src/components/select/select-item/select-item.tsx +1 -2
  260. package/src/components/select/select-root/select-root.tsx +87 -11
  261. package/src/components/select/select-trigger/select-trigger.tsx +2 -0
  262. package/src/components/select/select.context.ts +2 -0
  263. package/src/components/select/select.test.tsx +35 -0
  264. package/src/components/select/select.types.ts +15 -0
  265. package/src/components/select/use-select.ts +2 -1
  266. package/src/components/switch/switch.tsx +1 -1
  267. package/src/components/table/index.ts +24 -0
  268. package/src/components/table/table-body/index.ts +1 -0
  269. package/src/components/table/table-body/table-body.tsx +37 -0
  270. package/src/components/table/table-caption/index.ts +1 -0
  271. package/src/components/table/table-caption/table-caption.tsx +32 -0
  272. package/src/components/table/table-cell/index.ts +1 -0
  273. package/src/components/table/table-cell/table-cell.tsx +33 -0
  274. package/src/components/table/table-head/index.ts +1 -0
  275. package/src/components/table/table-head/table-head.tsx +29 -0
  276. package/src/components/table/table-header-cell/index.ts +1 -0
  277. package/src/components/table/table-header-cell/table-header-cell.tsx +33 -0
  278. package/src/components/table/table-row/index.ts +1 -0
  279. package/src/components/table/table-row/table-row.tsx +30 -0
  280. package/src/components/table/table.context.ts +18 -0
  281. package/src/components/table/table.styles.ts +62 -0
  282. package/src/components/table/table.test.tsx +145 -0
  283. package/src/components/table/table.tsx +91 -0
  284. package/src/components/table/table.types.ts +145 -0
  285. package/src/components/tabs/tabs-tab/tabs-tab.tsx +0 -8
  286. package/src/components/tooltip/tooltip.tsx +7 -1
  287. package/src/components/tooltip/use-tooltip.ts +2 -1
  288. package/src/components/transition/transition.tsx +18 -14
  289. package/src/style.css +0 -1
  290. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,75 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from "react";
2
+ import { RefraktorRadius, RefraktorSize } from "../../theme";
3
+ import {
4
+ createClassNamesConfig,
5
+ createComponentConfig,
6
+ FactoryPayload
7
+ } from "../../utils";
8
+
9
+ export interface SegmentedControlItem {
10
+ /** Item value */
11
+ value: string;
12
+
13
+ /** Item label */
14
+ label: ReactNode;
15
+
16
+ /** Whether item is disabled */
17
+ disabled?: boolean;
18
+ }
19
+
20
+ export type SegmentedControlClassNames = {
21
+ root?: string;
22
+ control?: string;
23
+ label?: string;
24
+ };
25
+
26
+ export interface SegmentedControlProps extends Omit<
27
+ ComponentPropsWithoutRef<"div">,
28
+ "onChange"
29
+ > {
30
+ /** Items to render */
31
+ data: SegmentedControlItem[];
32
+
33
+ /** Selected value (controlled) */
34
+ value?: string;
35
+
36
+ /** Initial selected value (uncontrolled) */
37
+ defaultValue?: string;
38
+
39
+ /** Callback called when selected value changes */
40
+ onChange?: (value: string) => void;
41
+
42
+ /** The size of segmented control @default `md` */
43
+ size?: RefraktorSize;
44
+
45
+ /** The radius of segmented control @default `default` */
46
+ radius?: RefraktorRadius;
47
+
48
+ /** Whether segmented control should take full width @default `false` */
49
+ fullWidth?: boolean;
50
+
51
+ /** Whether segmented control is disabled @default `false` */
52
+ disabled?: boolean;
53
+
54
+ /** Hidden input name for forms */
55
+ name?: string;
56
+
57
+ /** Used for editing root class name */
58
+ className?: string;
59
+
60
+ /** Used for styling different parts of the component */
61
+ classNames?: SegmentedControlClassNames;
62
+ }
63
+
64
+ export interface SegmentedControlFactoryPayload extends FactoryPayload {
65
+ props: SegmentedControlProps;
66
+ ref: HTMLDivElement;
67
+ compound: {
68
+ configure: ReturnType<
69
+ typeof createComponentConfig<SegmentedControlProps>
70
+ >;
71
+ classNames: ReturnType<
72
+ typeof createClassNamesConfig<SegmentedControlClassNames>
73
+ >;
74
+ };
75
+ }
@@ -201,6 +201,7 @@ const SelectDropdown = factory<SelectDropdownFactoryPayload>(
201
201
  transition="fade"
202
202
  duration={150}
203
203
  mounted={select.select.opened}
204
+ style={{ position: "relative", zIndex: 1000 }}
204
205
  {...select.transitionProps}
205
206
  >
206
207
  <div
@@ -211,6 +212,7 @@ const SelectDropdown = factory<SelectDropdownFactoryPayload>(
211
212
  tabIndex={-1}
212
213
  style={{
213
214
  ...select.select.floatingStyles,
215
+ zIndex: 1000,
214
216
  width: referenceWidth,
215
217
  ...style
216
218
  }}
@@ -273,16 +275,15 @@ const SelectDropdown = factory<SelectDropdownFactoryPayload>(
273
275
  </Transition>
274
276
  );
275
277
 
276
- const wrappedContent = select.select.opened ? (
278
+ const wrappedContent = (
277
279
  <FloatingFocusManager
278
280
  context={select.select.context}
279
281
  modal={false}
280
282
  initialFocus={-1}
283
+ disabled={!select.select.opened}
281
284
  >
282
285
  {dropdownContent}
283
286
  </FloatingFocusManager>
284
- ) : (
285
- dropdownContent
286
287
  );
287
288
 
288
289
  return select.withinPortal ? (
@@ -92,10 +92,9 @@ const SelectItem = factory<SelectItemFactoryPayload>(
92
92
  aria-selected={isSelected}
93
93
  aria-disabled={disabled}
94
94
  className={cx(
95
- "w-full text-left p-1.5 text-sm rounded-none appearance-none border-none bg-transparent",
95
+ "w-full text-left p-1.5 text-xs rounded-none appearance-none border-none bg-transparent",
96
96
  "inline-flex items-center gap-2 outline-none transition-colors",
97
97
  "hover:bg-[var(--refraktor-bg-hover)] focus-visible:bg-[var(--refraktor-bg-hover)]",
98
- "data-[selected=true]:bg-[var(--refraktor-bg-hover)]",
99
98
  "data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none data-[disabled=true]:cursor-not-allowed",
100
99
  getRadius(select.radius),
101
100
  select.getStyles("item"),
@@ -1,9 +1,18 @@
1
1
  import { useId, useUncontrolled } from "@refraktor/utils";
2
- import { useCallback, useEffect, useRef } from "react";
2
+ import {
3
+ Children,
4
+ isValidElement,
5
+ useCallback,
6
+ useEffect,
7
+ useMemo,
8
+ useRef
9
+ } from "react";
10
+ import type { ReactNode } from "react";
3
11
  import { useTheme } from "../../../theme";
4
12
  import { factory, useClassNames, useProps } from "../../../utils";
5
13
  import {
6
14
  focusSelectItem,
15
+ getNodeTextValue,
7
16
  getNavigableSelectItems,
8
17
  SelectProvider,
9
18
  useSelectItemsRegistry
@@ -18,6 +27,7 @@ import type {
18
27
  SelectRootProps
19
28
  } from "../select.types";
20
29
  import { useSelect } from "../use-select";
30
+ import { InputWrapper } from "../../input/input-wrapper";
21
31
 
22
32
  const defaultProps = {
23
33
  positioning: {
@@ -37,11 +47,52 @@ const defaultProps = {
37
47
  closeOnEscape: true
38
48
  } satisfies Partial<SelectRootProps>;
39
49
 
50
+ function collectSelectItemLabels(node: ReactNode, labels: Map<string, string>) {
51
+ Children.forEach(node, (child) => {
52
+ if (!isValidElement(child)) {
53
+ return;
54
+ }
55
+
56
+ const typeDisplayName = (child.type as { displayName?: string })
57
+ .displayName;
58
+ const props = child.props as {
59
+ value?: string;
60
+ textValue?: string;
61
+ children?: ReactNode;
62
+ };
63
+
64
+ if (
65
+ typeDisplayName === "@refraktor/core/Select.Item" &&
66
+ typeof props.value === "string"
67
+ ) {
68
+ labels.set(
69
+ props.value,
70
+ getNodeTextValue(props.children, props.textValue) || props.value
71
+ );
72
+ }
73
+
74
+ if (props.children !== undefined && props.children !== null) {
75
+ collectSelectItemLabels(props.children, labels);
76
+ }
77
+ });
78
+ }
79
+
80
+ function getSelectItemLabels(node: ReactNode) {
81
+ const labels = new Map<string, string>();
82
+ collectSelectItemLabels(node, labels);
83
+ return labels;
84
+ }
85
+
40
86
  const SelectRoot = factory<SelectRootFactoryPayload>((_props, ref) => {
41
87
  const { cx } = useTheme();
42
88
  const {
43
89
  id,
44
90
  children,
91
+ label,
92
+ description,
93
+ error,
94
+ required,
95
+ withAsterisk,
45
96
  value,
46
97
  defaultValue,
47
98
  onChange,
@@ -74,6 +125,8 @@ const SelectRoot = factory<SelectRootFactoryPayload>((_props, ref) => {
74
125
  const _id = useId(id);
75
126
  const listId = `${_id}-listbox`;
76
127
  const triggerId = `${_id}-trigger`;
128
+ const hasWrapper = label || description || error;
129
+ const inferredLabels = useMemo(() => getSelectItemLabels(children), [children]);
77
130
 
78
131
  const [selectedValue, setSelectedValue] = useUncontrolled<string | null>({
79
132
  value,
@@ -153,8 +206,12 @@ const SelectRoot = factory<SelectRootFactoryPayload>((_props, ref) => {
153
206
  return "";
154
207
  }
155
208
 
156
- return labelsRef.current.get(selectedValue) ?? selectedValue;
157
- }, [selectedValue]);
209
+ return (
210
+ labelsRef.current.get(selectedValue) ??
211
+ inferredLabels.get(selectedValue) ??
212
+ selectedValue
213
+ );
214
+ }, [selectedValue, inferredLabels]);
158
215
 
159
216
  const focusFirstItem = useCallback(() => {
160
217
  const items = getNavigableSelectItems(getVisibleItems());
@@ -216,6 +273,8 @@ const SelectRoot = factory<SelectRootFactoryPayload>((_props, ref) => {
216
273
  searchPlaceholder,
217
274
  nothingFound,
218
275
  disabled: !!disabled,
276
+ error: !!error,
277
+ required: !!required,
219
278
  size,
220
279
  radius,
221
280
  variant,
@@ -238,16 +297,33 @@ const SelectRoot = factory<SelectRootFactoryPayload>((_props, ref) => {
238
297
  getStyles
239
298
  };
240
299
 
300
+ const content = (
301
+ <div
302
+ ref={ref}
303
+ id={_id}
304
+ className={cx("relative w-full", classes.root, className)}
305
+ {...props}
306
+ >
307
+ {children}
308
+ </div>
309
+ );
310
+
241
311
  return (
242
312
  <SelectProvider value={context}>
243
- <div
244
- ref={ref}
245
- id={_id}
246
- className={cx("relative w-full", classes.root, className)}
247
- {...props}
248
- >
249
- {children}
250
- </div>
313
+ {hasWrapper ? (
314
+ <InputWrapper
315
+ label={label}
316
+ description={description}
317
+ error={error}
318
+ required={required}
319
+ withAsterisk={withAsterisk}
320
+ inputId={triggerId}
321
+ >
322
+ {content}
323
+ </InputWrapper>
324
+ ) : (
325
+ content
326
+ )}
251
327
  </SelectProvider>
252
328
  );
253
329
  });
@@ -81,6 +81,8 @@ const SelectTrigger = factory<SelectTriggerFactoryPayload>(
81
81
  select.triggerInputRef.current = node;
82
82
  }}
83
83
  readOnly
84
+ required={select.required}
85
+ error={select.error}
84
86
  disabled={select.disabled}
85
87
  value={hasValue ? selectedLabel : ""}
86
88
  placeholder={hasValue ? undefined : placeholder ?? select.placeholder}
@@ -29,6 +29,8 @@ export interface SelectContextValue {
29
29
  searchPlaceholder: string;
30
30
  nothingFound: ReactNode;
31
31
  disabled: boolean;
32
+ error: boolean;
33
+ required: boolean;
32
34
  size: RefraktorSize;
33
35
  radius: RefraktorRadius;
34
36
  variant: InputVariant;
@@ -36,6 +36,20 @@ describe("@refraktor/core/Select", () => {
36
36
  });
37
37
  });
38
38
 
39
+ it("renders defaultValue label in trigger before opening", async () => {
40
+ await render(
41
+ <Select
42
+ defaultValue="apple"
43
+ data={[
44
+ { value: "apple", label: "Apple" },
45
+ { value: "orange", label: "Orange" }
46
+ ]}
47
+ />
48
+ );
49
+
50
+ expect(screen.getByRole("combobox")).toHaveValue("Apple");
51
+ });
52
+
39
53
  it("renders searchable input inside dropdown", async () => {
40
54
  const user = userEvent.setup();
41
55
 
@@ -152,4 +166,25 @@ describe("@refraktor/core/Select", () => {
152
166
  expect(onChange).toHaveBeenCalledWith("vue");
153
167
  expect(screen.getByRole("combobox")).toHaveValue("Vue");
154
168
  });
169
+
170
+ it("supports input wrapper props", async () => {
171
+ await render(
172
+ <Select
173
+ label="Framework"
174
+ description="Pick one option"
175
+ error="Selection is required"
176
+ transitionProps={transitionProps}
177
+ data={[
178
+ { value: "react", label: "React" },
179
+ { value: "vue", label: "Vue" }
180
+ ]}
181
+ />
182
+ );
183
+
184
+ const trigger = screen.getByLabelText("Framework");
185
+
186
+ expect(trigger).toHaveAttribute("aria-invalid", "true");
187
+ expect(screen.getByText("Pick one option")).toBeInTheDocument();
188
+ expect(screen.getByText("Selection is required")).toBeInTheDocument();
189
+ });
155
190
  });
@@ -82,6 +82,21 @@ export interface SelectRootProps
82
82
  /** Children containing select subcomponents */
83
83
  children: ReactNode;
84
84
 
85
+ /** Label text */
86
+ label?: ReactNode;
87
+
88
+ /** Description text */
89
+ description?: ReactNode;
90
+
91
+ /** Error message */
92
+ error?: ReactNode;
93
+
94
+ /** Whether the field is required */
95
+ required?: boolean;
96
+
97
+ /** Display an asterisk next to the label */
98
+ withAsterisk?: boolean;
99
+
85
100
  /** Selected value (controlled) */
86
101
  value?: string | null;
87
102
 
@@ -114,7 +114,8 @@ export function useSelect(options: UseSelectProps = {}): UseSelectReturn {
114
114
  open: isOpen,
115
115
  onOpenChange: setIsOpen,
116
116
  middleware,
117
- whileElementsMounted: autoUpdate
117
+ whileElementsMounted: autoUpdate,
118
+ strategy: "fixed"
118
119
  });
119
120
 
120
121
  const click = useClick(floating.context, {
@@ -100,7 +100,7 @@ const Switch = factory<SwitchFactoryPayload>((_props, ref) => {
100
100
  <span
101
101
  className={cx(
102
102
  "text-[var(--refraktor-text)]",
103
- labelPosition === "left" ? "mr-3" : "ml-3",
103
+ labelPosition === "left" ? "mr-2" : "ml-2",
104
104
  sizeClass.label,
105
105
  classes.label
106
106
  )}
@@ -0,0 +1,24 @@
1
+ export { default as Table } from "./table";
2
+ export { TableHead } from "./table-head";
3
+ export { TableBody } from "./table-body";
4
+ export { TableRow } from "./table-row";
5
+ export { TableHeaderCell } from "./table-header-cell";
6
+ export { TableCell } from "./table-cell";
7
+ export { TableCaption } from "./table-caption";
8
+ export type {
9
+ TableProps,
10
+ TableHeadProps,
11
+ TableBodyProps,
12
+ TableRowProps,
13
+ TableHeaderCellProps,
14
+ TableCellProps,
15
+ TableCaptionProps,
16
+ TableClassNames,
17
+ TableFactoryPayload,
18
+ TableHeadFactoryPayload,
19
+ TableBodyFactoryPayload,
20
+ TableRowFactoryPayload,
21
+ TableHeaderCellFactoryPayload,
22
+ TableCellFactoryPayload,
23
+ TableCaptionFactoryPayload
24
+ } from "./table.types";
@@ -0,0 +1 @@
1
+ export { default as TableBody } from "./table-body";
@@ -0,0 +1,37 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { getBodyStyles } from "../table.styles";
5
+ import { TableBodyFactoryPayload } from "../table.types";
6
+
7
+ const TableBody = factory<TableBodyFactoryPayload>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const { cx } = useTheme();
10
+ const {
11
+ striped,
12
+ highlightOnHover,
13
+ withRowBorders,
14
+ getStyles
15
+ } = useTableContext();
16
+
17
+ const bodyStyles = getBodyStyles({
18
+ striped,
19
+ highlightOnHover,
20
+ withRowBorders
21
+ });
22
+
23
+ return (
24
+ <tbody
25
+ ref={ref}
26
+ className={cx("align-top", bodyStyles, getStyles("body"), className)}
27
+ {...props}
28
+ >
29
+ {children}
30
+ </tbody>
31
+ );
32
+ }
33
+ );
34
+
35
+ TableBody.displayName = "@refraktor/core/Table.Body";
36
+
37
+ export default TableBody;
@@ -0,0 +1 @@
1
+ export { default as TableCaption } from "./table-caption";
@@ -0,0 +1,32 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { getSize } from "../table.styles";
5
+ import { TableCaptionFactoryPayload } from "../table.types";
6
+
7
+ const TableCaption = factory<TableCaptionFactoryPayload>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const { cx } = useTheme();
10
+ const { size, getStyles } = useTableContext();
11
+ const sizeStyles = getSize(size);
12
+
13
+ return (
14
+ <caption
15
+ ref={ref}
16
+ className={cx(
17
+ "caption-bottom mt-2 text-[var(--refraktor-text-secondary)]",
18
+ sizeStyles.caption,
19
+ getStyles("caption"),
20
+ className
21
+ )}
22
+ {...props}
23
+ >
24
+ {children}
25
+ </caption>
26
+ );
27
+ }
28
+ );
29
+
30
+ TableCaption.displayName = "@refraktor/core/Table.Caption";
31
+
32
+ export default TableCaption;
@@ -0,0 +1 @@
1
+ export { default as TableCell } from "./table-cell";
@@ -0,0 +1,33 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { getColumnBorder, getSize } from "../table.styles";
5
+ import { TableCellFactoryPayload } from "../table.types";
6
+
7
+ const TableCell = factory<TableCellFactoryPayload>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const { cx } = useTheme();
10
+ const { size, withColumnBorders, getStyles } = useTableContext();
11
+ const sizeStyles = getSize(size);
12
+
13
+ return (
14
+ <td
15
+ ref={ref}
16
+ className={cx(
17
+ "align-middle text-[var(--refraktor-text)]",
18
+ sizeStyles.cell,
19
+ getColumnBorder(withColumnBorders),
20
+ getStyles("cell"),
21
+ className
22
+ )}
23
+ {...props}
24
+ >
25
+ {children}
26
+ </td>
27
+ );
28
+ }
29
+ );
30
+
31
+ TableCell.displayName = "@refraktor/core/Table.Cell";
32
+
33
+ export default TableCell;
@@ -0,0 +1 @@
1
+ export { default as TableHead } from "./table-head";
@@ -0,0 +1,29 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { TableHeadFactoryPayload } from "../table.types";
5
+
6
+ const TableHead = factory<TableHeadFactoryPayload>(
7
+ ({ children, className, ...props }, ref) => {
8
+ const { cx } = useTheme();
9
+ const { getStyles } = useTableContext();
10
+
11
+ return (
12
+ <thead
13
+ ref={ref}
14
+ className={cx(
15
+ "border-b border-[var(--refraktor-border)] bg-[var(--refraktor-bg-subtle)]",
16
+ getStyles("head"),
17
+ className
18
+ )}
19
+ {...props}
20
+ >
21
+ {children}
22
+ </thead>
23
+ );
24
+ }
25
+ );
26
+
27
+ TableHead.displayName = "@refraktor/core/Table.Head";
28
+
29
+ export default TableHead;
@@ -0,0 +1 @@
1
+ export { default as TableHeaderCell } from "./table-header-cell";
@@ -0,0 +1,33 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { getColumnBorder, getSize } from "../table.styles";
5
+ import { TableHeaderCellFactoryPayload } from "../table.types";
6
+
7
+ const TableHeaderCell = factory<TableHeaderCellFactoryPayload>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const { cx } = useTheme();
10
+ const { size, withColumnBorders, getStyles } = useTableContext();
11
+ const sizeStyles = getSize(size);
12
+
13
+ return (
14
+ <th
15
+ ref={ref}
16
+ className={cx(
17
+ "text-left font-medium align-middle text-[var(--refraktor-text-secondary)]",
18
+ sizeStyles.headerCell,
19
+ getColumnBorder(withColumnBorders),
20
+ getStyles("headerCell"),
21
+ className
22
+ )}
23
+ {...props}
24
+ >
25
+ {children}
26
+ </th>
27
+ );
28
+ }
29
+ );
30
+
31
+ TableHeaderCell.displayName = "@refraktor/core/Table.HeaderCell";
32
+
33
+ export default TableHeaderCell;
@@ -0,0 +1 @@
1
+ export { default as TableRow } from "./table-row";
@@ -0,0 +1,30 @@
1
+ import { useTheme } from "../../../theme";
2
+ import { factory } from "../../../utils";
3
+ import { useTableContext } from "../table.context";
4
+ import { TableRowFactoryPayload } from "../table.types";
5
+
6
+ const TableRow = factory<TableRowFactoryPayload>(
7
+ ({ children, className, ...props }, ref) => {
8
+ const { cx } = useTheme();
9
+ const { highlightOnHover, getStyles } = useTableContext();
10
+
11
+ return (
12
+ <tr
13
+ ref={ref}
14
+ className={cx(
15
+ "align-middle",
16
+ highlightOnHover && "transition-colors",
17
+ getStyles("row"),
18
+ className
19
+ )}
20
+ {...props}
21
+ >
22
+ {children}
23
+ </tr>
24
+ );
25
+ }
26
+ );
27
+
28
+ TableRow.displayName = "@refraktor/core/Table.Row";
29
+
30
+ export default TableRow;
@@ -0,0 +1,18 @@
1
+ import { createSafeContext } from "@refraktor/utils";
2
+ import { RefraktorRadius, RefraktorSize } from "../../theme";
3
+ import { TableClassNames } from "./table.types";
4
+
5
+ export interface TableContextValue {
6
+ size: RefraktorSize;
7
+ radius: RefraktorRadius;
8
+ striped: boolean;
9
+ highlightOnHover: boolean;
10
+ withRowBorders: boolean;
11
+ withColumnBorders: boolean;
12
+ getStyles: (part: keyof TableClassNames) => string | undefined;
13
+ }
14
+
15
+ export const [TableProvider, useTableContext] =
16
+ createSafeContext<TableContextValue>(
17
+ "Table component was not found in tree. Make sure Table subcomponents are wrapped with Table."
18
+ );