@workday/canvas-kit-react 10.0.0-alpha.540-next.0 → 10.0.0-alpha.546-next.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 (219) hide show
  1. package/collection/index.ts +1 -0
  2. package/collection/lib/useBaseListModel.tsx +3 -3
  3. package/collection/lib/useListItemRegister.tsx +1 -1
  4. package/collection/lib/useListRenderItem.tsx +2 -2
  5. package/combobox/index.ts +11 -4
  6. package/combobox/lib/Combobox.tsx +1 -1
  7. package/combobox/lib/ComboboxCard.tsx +1 -1
  8. package/combobox/lib/ComboboxInput.tsx +2 -90
  9. package/combobox/lib/ComboboxMenu.tsx +4 -3
  10. package/combobox/lib/ComboboxMenuItem.tsx +9 -8
  11. package/combobox/lib/ComboboxMenuList.tsx +1 -1
  12. package/combobox/lib/ComboboxPopper.tsx +20 -0
  13. package/combobox/lib/hooks/index.ts +9 -0
  14. package/combobox/lib/hooks/useComboboxInput.ts +88 -0
  15. package/combobox/lib/hooks/useComboboxKeyboardTypeAhead.ts +127 -0
  16. package/combobox/lib/hooks/useComboboxListKeyboardHandler.ts +23 -0
  17. package/combobox/lib/{useComboboxModel.tsx → hooks/useComboboxModel.tsx} +6 -2
  18. package/combobox/lib/hooks/useComboboxMoveCursorToSelected.tsx +27 -0
  19. package/combobox/lib/hooks/useComboboxResetCursorToSelected.tsx +18 -0
  20. package/combobox/lib/hooks/useSetPopupWidth.ts +16 -0
  21. package/common/lib/utils/components.ts +284 -274
  22. package/common/lib/utils/models.ts +67 -84
  23. package/dist/commonjs/collection/index.d.ts +1 -0
  24. package/dist/commonjs/collection/index.d.ts.map +1 -1
  25. package/dist/commonjs/collection/index.js +3 -1
  26. package/dist/commonjs/collection/lib/useBaseListModel.d.ts +1 -1
  27. package/dist/commonjs/collection/lib/useBaseListModel.d.ts.map +1 -1
  28. package/dist/commonjs/collection/lib/useBaseListModel.js +2 -2
  29. package/dist/commonjs/collection/lib/useListItemRegister.js +2 -2
  30. package/dist/commonjs/collection/lib/useListRenderItem.js +2 -2
  31. package/dist/commonjs/combobox/index.d.ts +1 -4
  32. package/dist/commonjs/combobox/index.d.ts.map +1 -1
  33. package/dist/commonjs/combobox/index.js +11 -9
  34. package/dist/commonjs/combobox/lib/Combobox.d.ts +9 -3
  35. package/dist/commonjs/combobox/lib/Combobox.d.ts.map +1 -1
  36. package/dist/commonjs/combobox/lib/Combobox.js +2 -2
  37. package/dist/commonjs/combobox/lib/ComboboxCard.js +3 -3
  38. package/dist/commonjs/combobox/lib/ComboboxInput.d.ts +1 -106
  39. package/dist/commonjs/combobox/lib/ComboboxInput.d.ts.map +1 -1
  40. package/dist/commonjs/combobox/lib/ComboboxInput.js +4 -71
  41. package/dist/commonjs/combobox/lib/ComboboxMenu.d.ts +9 -3
  42. package/dist/commonjs/combobox/lib/ComboboxMenu.d.ts.map +1 -1
  43. package/dist/commonjs/combobox/lib/ComboboxMenu.js +5 -4
  44. package/dist/commonjs/combobox/lib/ComboboxMenuItem.d.ts +7 -1
  45. package/dist/commonjs/combobox/lib/ComboboxMenuItem.d.ts.map +1 -1
  46. package/dist/commonjs/combobox/lib/ComboboxMenuItem.js +7 -7
  47. package/dist/commonjs/combobox/lib/ComboboxMenuList.js +2 -2
  48. package/dist/commonjs/combobox/lib/ComboboxPopper.d.ts +97 -0
  49. package/dist/commonjs/combobox/lib/ComboboxPopper.d.ts.map +1 -0
  50. package/dist/commonjs/{select/lib/SelectOption.js → combobox/lib/ComboboxPopper.js} +12 -8
  51. package/dist/commonjs/combobox/lib/hooks/index.d.ts +10 -0
  52. package/dist/commonjs/combobox/lib/hooks/index.d.ts.map +1 -0
  53. package/dist/commonjs/combobox/lib/hooks/index.js +21 -0
  54. package/dist/commonjs/combobox/lib/hooks/useComboboxInput.d.ts +107 -0
  55. package/dist/commonjs/combobox/lib/hooks/useComboboxInput.d.ts.map +1 -0
  56. package/dist/commonjs/combobox/lib/hooks/useComboboxInput.js +74 -0
  57. package/dist/{es6/combobox/lib → commonjs/combobox/lib/hooks}/useComboboxInputOpenWithArrowKeys.d.ts +6 -6
  58. package/dist/commonjs/combobox/lib/hooks/useComboboxInputOpenWithArrowKeys.d.ts.map +1 -0
  59. package/dist/commonjs/combobox/lib/hooks/useComboboxKeyboardTypeAhead.d.ts +101 -0
  60. package/dist/commonjs/combobox/lib/hooks/useComboboxKeyboardTypeAhead.d.ts.map +1 -0
  61. package/dist/commonjs/combobox/lib/hooks/useComboboxKeyboardTypeAhead.js +109 -0
  62. package/dist/commonjs/combobox/lib/hooks/useComboboxListKeyboardHandler.d.ts +84 -0
  63. package/dist/commonjs/combobox/lib/hooks/useComboboxListKeyboardHandler.d.ts.map +1 -0
  64. package/dist/commonjs/combobox/lib/hooks/useComboboxListKeyboardHandler.js +22 -0
  65. package/dist/commonjs/combobox/lib/hooks/useComboboxLoader.d.ts.map +1 -0
  66. package/dist/commonjs/combobox/lib/{useComboboxModel.d.ts → hooks/useComboboxModel.d.ts} +196 -196
  67. package/dist/commonjs/combobox/lib/hooks/useComboboxModel.d.ts.map +1 -0
  68. package/dist/commonjs/combobox/lib/{useComboboxModel.js → hooks/useComboboxModel.js} +3 -2
  69. package/dist/commonjs/combobox/lib/hooks/useComboboxMoveCursorToSelected.d.ts +82 -0
  70. package/dist/commonjs/combobox/lib/hooks/useComboboxMoveCursorToSelected.d.ts.map +1 -0
  71. package/dist/commonjs/combobox/lib/hooks/useComboboxMoveCursorToSelected.js +33 -0
  72. package/dist/commonjs/combobox/lib/hooks/useComboboxResetCursorToSelected.d.ts +82 -0
  73. package/dist/commonjs/combobox/lib/hooks/useComboboxResetCursorToSelected.d.ts.map +1 -0
  74. package/dist/commonjs/combobox/lib/hooks/useComboboxResetCursorToSelected.js +23 -0
  75. package/dist/commonjs/combobox/lib/hooks/useSetPopupWidth.d.ts +82 -0
  76. package/dist/commonjs/combobox/lib/hooks/useSetPopupWidth.d.ts.map +1 -0
  77. package/dist/commonjs/combobox/lib/hooks/useSetPopupWidth.js +22 -0
  78. package/dist/commonjs/common/lib/utils/components.d.ts.map +1 -1
  79. package/dist/commonjs/common/lib/utils/models.d.ts +4 -4
  80. package/dist/commonjs/common/lib/utils/models.d.ts.map +1 -1
  81. package/dist/commonjs/common/lib/utils/models.js +7 -8
  82. package/dist/commonjs/form-field/lib/FormField.d.ts.map +1 -1
  83. package/dist/commonjs/form-field/lib/FormField.js +3 -2
  84. package/dist/commonjs/menu/lib/MenuPopper.d.ts.map +1 -1
  85. package/dist/commonjs/menu/lib/MenuPopper.js +10 -1
  86. package/dist/commonjs/popup/lib/PopupPopper.d.ts.map +1 -1
  87. package/dist/commonjs/popup/lib/PopupPopper.js +10 -1
  88. package/dist/commonjs/select/index.d.ts +1 -1
  89. package/dist/commonjs/select/index.d.ts.map +1 -1
  90. package/dist/commonjs/select/index.js +1 -1
  91. package/dist/commonjs/select/lib/Select.d.ts +2634 -18
  92. package/dist/commonjs/select/lib/Select.d.ts.map +1 -1
  93. package/dist/commonjs/select/lib/Select.js +141 -84
  94. package/dist/commonjs/select/lib/hooks/index.d.ts +4 -0
  95. package/dist/commonjs/select/lib/hooks/index.d.ts.map +1 -0
  96. package/dist/commonjs/select/lib/hooks/index.js +15 -0
  97. package/dist/commonjs/select/lib/hooks/useSelectCard.d.ts +83 -0
  98. package/dist/commonjs/select/lib/hooks/useSelectCard.d.ts.map +1 -0
  99. package/dist/commonjs/select/lib/hooks/useSelectCard.js +13 -0
  100. package/dist/commonjs/select/lib/hooks/useSelectInput.d.ts +112 -0
  101. package/dist/commonjs/select/lib/hooks/useSelectInput.d.ts.map +1 -0
  102. package/dist/commonjs/select/lib/hooks/useSelectInput.js +49 -0
  103. package/dist/commonjs/select/lib/hooks/useSelectModel.d.ts +1779 -0
  104. package/dist/commonjs/select/lib/hooks/useSelectModel.d.ts.map +1 -0
  105. package/dist/commonjs/select/lib/hooks/useSelectModel.js +32 -0
  106. package/dist/es6/collection/index.d.ts +1 -0
  107. package/dist/es6/collection/index.d.ts.map +1 -1
  108. package/dist/es6/collection/index.js +1 -0
  109. package/dist/es6/collection/lib/useBaseListModel.d.ts +1 -1
  110. package/dist/es6/collection/lib/useBaseListModel.d.ts.map +1 -1
  111. package/dist/es6/collection/lib/useBaseListModel.js +2 -2
  112. package/dist/es6/collection/lib/useListItemRegister.js +2 -2
  113. package/dist/es6/collection/lib/useListRenderItem.js +2 -2
  114. package/dist/es6/combobox/index.d.ts +1 -4
  115. package/dist/es6/combobox/index.d.ts.map +1 -1
  116. package/dist/es6/combobox/index.js +1 -4
  117. package/dist/es6/combobox/lib/Combobox.d.ts +9 -3
  118. package/dist/es6/combobox/lib/Combobox.d.ts.map +1 -1
  119. package/dist/es6/combobox/lib/Combobox.js +1 -1
  120. package/dist/es6/combobox/lib/ComboboxCard.js +1 -1
  121. package/dist/es6/combobox/lib/ComboboxInput.d.ts +1 -106
  122. package/dist/es6/combobox/lib/ComboboxInput.d.ts.map +1 -1
  123. package/dist/es6/combobox/lib/ComboboxInput.js +2 -69
  124. package/dist/es6/combobox/lib/ComboboxMenu.d.ts +9 -3
  125. package/dist/es6/combobox/lib/ComboboxMenu.d.ts.map +1 -1
  126. package/dist/es6/combobox/lib/ComboboxMenu.js +4 -3
  127. package/dist/es6/combobox/lib/ComboboxMenuItem.d.ts +7 -1
  128. package/dist/es6/combobox/lib/ComboboxMenuItem.d.ts.map +1 -1
  129. package/dist/es6/combobox/lib/ComboboxMenuItem.js +7 -7
  130. package/dist/es6/combobox/lib/ComboboxMenuList.js +1 -1
  131. package/dist/es6/combobox/lib/ComboboxPopper.d.ts +97 -0
  132. package/dist/es6/combobox/lib/ComboboxPopper.d.ts.map +1 -0
  133. package/dist/es6/combobox/lib/ComboboxPopper.js +12 -0
  134. package/dist/es6/combobox/lib/hooks/index.d.ts +10 -0
  135. package/dist/es6/combobox/lib/hooks/index.d.ts.map +1 -0
  136. package/dist/es6/combobox/lib/hooks/index.js +9 -0
  137. package/dist/es6/combobox/lib/hooks/useComboboxInput.d.ts +107 -0
  138. package/dist/es6/combobox/lib/hooks/useComboboxInput.d.ts.map +1 -0
  139. package/dist/es6/combobox/lib/hooks/useComboboxInput.js +68 -0
  140. package/dist/{commonjs/combobox/lib → es6/combobox/lib/hooks}/useComboboxInputOpenWithArrowKeys.d.ts +6 -6
  141. package/dist/es6/combobox/lib/hooks/useComboboxInputOpenWithArrowKeys.d.ts.map +1 -0
  142. package/dist/es6/combobox/lib/hooks/useComboboxKeyboardTypeAhead.d.ts +101 -0
  143. package/dist/es6/combobox/lib/hooks/useComboboxKeyboardTypeAhead.d.ts.map +1 -0
  144. package/dist/es6/combobox/lib/hooks/useComboboxKeyboardTypeAhead.js +103 -0
  145. package/dist/es6/combobox/lib/hooks/useComboboxListKeyboardHandler.d.ts +84 -0
  146. package/dist/es6/combobox/lib/hooks/useComboboxListKeyboardHandler.d.ts.map +1 -0
  147. package/dist/es6/combobox/lib/hooks/useComboboxListKeyboardHandler.js +19 -0
  148. package/dist/es6/combobox/lib/hooks/useComboboxLoader.d.ts.map +1 -0
  149. package/dist/es6/combobox/lib/{useComboboxModel.d.ts → hooks/useComboboxModel.d.ts} +196 -196
  150. package/dist/es6/combobox/lib/hooks/useComboboxModel.d.ts.map +1 -0
  151. package/dist/es6/combobox/lib/{useComboboxModel.js → hooks/useComboboxModel.js} +3 -2
  152. package/dist/es6/combobox/lib/hooks/useComboboxMoveCursorToSelected.d.ts +82 -0
  153. package/dist/es6/combobox/lib/hooks/useComboboxMoveCursorToSelected.d.ts.map +1 -0
  154. package/dist/es6/combobox/lib/hooks/useComboboxMoveCursorToSelected.js +27 -0
  155. package/dist/es6/combobox/lib/hooks/useComboboxResetCursorToSelected.d.ts +82 -0
  156. package/dist/es6/combobox/lib/hooks/useComboboxResetCursorToSelected.d.ts.map +1 -0
  157. package/dist/es6/combobox/lib/hooks/useComboboxResetCursorToSelected.js +17 -0
  158. package/dist/es6/combobox/lib/hooks/useSetPopupWidth.d.ts +82 -0
  159. package/dist/es6/combobox/lib/hooks/useSetPopupWidth.d.ts.map +1 -0
  160. package/dist/es6/combobox/lib/hooks/useSetPopupWidth.js +16 -0
  161. package/dist/es6/common/lib/utils/components.d.ts.map +1 -1
  162. package/dist/es6/common/lib/utils/models.d.ts +4 -4
  163. package/dist/es6/common/lib/utils/models.d.ts.map +1 -1
  164. package/dist/es6/common/lib/utils/models.js +7 -8
  165. package/dist/es6/form-field/lib/FormField.d.ts.map +1 -1
  166. package/dist/es6/form-field/lib/FormField.js +3 -2
  167. package/dist/es6/menu/lib/MenuPopper.d.ts.map +1 -1
  168. package/dist/es6/menu/lib/MenuPopper.js +10 -1
  169. package/dist/es6/popup/lib/PopupPopper.d.ts.map +1 -1
  170. package/dist/es6/popup/lib/PopupPopper.js +10 -1
  171. package/dist/es6/select/index.d.ts +1 -1
  172. package/dist/es6/select/index.d.ts.map +1 -1
  173. package/dist/es6/select/index.js +1 -1
  174. package/dist/es6/select/lib/Select.d.ts +2634 -18
  175. package/dist/es6/select/lib/Select.d.ts.map +1 -1
  176. package/dist/es6/select/lib/Select.js +139 -66
  177. package/dist/es6/select/lib/hooks/index.d.ts +4 -0
  178. package/dist/es6/select/lib/hooks/index.d.ts.map +1 -0
  179. package/dist/es6/select/lib/hooks/index.js +3 -0
  180. package/dist/es6/select/lib/hooks/useSelectCard.d.ts +83 -0
  181. package/dist/es6/select/lib/hooks/useSelectCard.d.ts.map +1 -0
  182. package/dist/es6/select/lib/hooks/useSelectCard.js +10 -0
  183. package/dist/es6/select/lib/hooks/useSelectInput.d.ts +112 -0
  184. package/dist/es6/select/lib/hooks/useSelectInput.d.ts.map +1 -0
  185. package/dist/es6/select/lib/hooks/useSelectInput.js +46 -0
  186. package/dist/es6/select/lib/hooks/useSelectModel.d.ts +1779 -0
  187. package/dist/es6/select/lib/hooks/useSelectModel.d.ts.map +1 -0
  188. package/dist/es6/select/lib/hooks/useSelectModel.js +29 -0
  189. package/form-field/lib/FormField.tsx +8 -2
  190. package/menu/lib/MenuPopper.tsx +14 -1
  191. package/package.json +4 -4
  192. package/popup/lib/Popper.tsx +1 -1
  193. package/popup/lib/PopupPopper.tsx +17 -1
  194. package/select/index.ts +1 -1
  195. package/select/lib/Select.tsx +175 -111
  196. package/select/lib/hooks/index.ts +3 -0
  197. package/select/lib/hooks/useSelectCard.ts +11 -0
  198. package/select/lib/hooks/useSelectInput.ts +74 -0
  199. package/select/lib/hooks/useSelectModel.tsx +30 -0
  200. package/dist/commonjs/combobox/lib/useComboboxInputOpenWithArrowKeys.d.ts.map +0 -1
  201. package/dist/commonjs/combobox/lib/useComboboxLoader.d.ts.map +0 -1
  202. package/dist/commonjs/combobox/lib/useComboboxModel.d.ts.map +0 -1
  203. package/dist/commonjs/select/lib/SelectOption.d.ts +0 -20
  204. package/dist/commonjs/select/lib/SelectOption.d.ts.map +0 -1
  205. package/dist/es6/combobox/lib/useComboboxInputOpenWithArrowKeys.d.ts.map +0 -1
  206. package/dist/es6/combobox/lib/useComboboxLoader.d.ts.map +0 -1
  207. package/dist/es6/combobox/lib/useComboboxModel.d.ts.map +0 -1
  208. package/dist/es6/select/lib/SelectOption.d.ts +0 -20
  209. package/dist/es6/select/lib/SelectOption.d.ts.map +0 -1
  210. package/dist/es6/select/lib/SelectOption.js +0 -7
  211. package/select/lib/SelectOption.tsx +0 -33
  212. /package/combobox/lib/{useComboboxInputOpenWithArrowKeys.ts → hooks/useComboboxInputOpenWithArrowKeys.ts} +0 -0
  213. /package/combobox/lib/{useComboboxLoader.ts → hooks/useComboboxLoader.ts} +0 -0
  214. /package/dist/commonjs/combobox/lib/{useComboboxInputOpenWithArrowKeys.js → hooks/useComboboxInputOpenWithArrowKeys.js} +0 -0
  215. /package/dist/commonjs/combobox/lib/{useComboboxLoader.d.ts → hooks/useComboboxLoader.d.ts} +0 -0
  216. /package/dist/commonjs/combobox/lib/{useComboboxLoader.js → hooks/useComboboxLoader.js} +0 -0
  217. /package/dist/es6/combobox/lib/{useComboboxInputOpenWithArrowKeys.js → hooks/useComboboxInputOpenWithArrowKeys.js} +0 -0
  218. /package/dist/es6/combobox/lib/{useComboboxLoader.d.ts → hooks/useComboboxLoader.d.ts} +0 -0
  219. /package/dist/es6/combobox/lib/{useComboboxLoader.js → hooks/useComboboxLoader.js} +0 -0
@@ -64,9 +64,8 @@ export type PropsWithoutAs<P, ElementType extends React.ElementType> = P &
64
64
  * JSX.IntrinsicElements['button'] // React.ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement>
65
65
  * ExtractHTMLAttributes<JSX.IntrinsicElements['button']> // React.HTMLButtonAttributes<HTMLButtonElement>
66
66
  */
67
- type ExtractHTMLAttributes<
68
- T extends React.DetailedHTMLProps<any, any>
69
- > = T extends React.DetailedHTMLProps<infer P, any> ? P : T;
67
+ type ExtractHTMLAttributes<T extends React.DetailedHTMLProps<any, any>> =
68
+ T extends React.DetailedHTMLProps<infer P, any> ? P : T;
70
69
 
71
70
  /**
72
71
  * Extract props from any component that was created using `createComponent`. It will return the
@@ -233,61 +232,65 @@ function defaultGetElemProps(input: any) {
233
232
  return input;
234
233
  }
235
234
 
236
- export const createContainer = <
237
- E extends
238
- | keyof JSX.IntrinsicElements
239
- | React.ComponentType
240
- | ElementComponentM<any, any, any>
241
- | undefined = undefined
242
- >(
243
- as?: E
244
- ) => <
245
- TModelHook extends ((config: any) => Model<any, any>) & {
246
- Context?: React.Context<any>;
247
- } & {defaultConfig?: Record<string, any>},
248
- TDefaultContext extends Model<any, any>,
249
- TElemPropsHook,
250
- SubComponents = {}
251
- >({
252
- displayName,
253
- modelHook,
254
- elemPropsHook,
255
- defaultContext,
256
- subComponents,
257
- }: {
258
- displayName?: string;
259
- modelHook: TModelHook;
260
- elemPropsHook?: TElemPropsHook;
261
- defaultContext?: TDefaultContext;
262
- subComponents?: SubComponents;
263
- }) => {
264
- assert(
265
- modelHook.Context,
266
- 'createContainer only works on models with context. Please use `createModelHook` to create the `modelHook`'
267
- );
268
- const Context = modelHook.Context;
269
-
270
- return <Props>(
271
- Component: (
272
- props: CompoundProps<Props, TElemPropsHook, E>,
273
- Element: E extends undefined ? never : E,
274
- model: TModelHook extends (config: infer TConfig) => infer TModel ? TModel : never
275
- ) => JSX.Element | null
276
- ): (TModelHook extends (config: infer TConfig) => infer TModel
277
- ? E extends undefined
278
- ? ComponentM<Props & TConfig, TModel>
279
- : ElementComponentM<
280
- // E is not `undefined` here, but Typescript thinks it could be, so we add another `undefined`
281
- // check and cast to a `React.FC` to match a valid signature for `ElementComponent`.
282
- // `React.FC` was chosen as the simplest valid interface.
283
- E extends undefined ? React.FC : E,
284
- Props & TConfig,
285
- TModel
286
- >
287
- : never) &
288
- SubComponents => {
289
- const ReturnedComponent = React.forwardRef<E, Props & {as?: React.ElementType} & {model?: any}>(
290
- ({as: asOverride, model, ...props}, ref) => {
235
+ export const createContainer =
236
+ <
237
+ E extends
238
+ | keyof JSX.IntrinsicElements
239
+ | React.ComponentType
240
+ | ElementComponentM<any, any, any>
241
+ | undefined = undefined
242
+ >(
243
+ as?: E
244
+ ) =>
245
+ <
246
+ TModelHook extends ((config: any) => Model<any, any>) & {
247
+ Context?: React.Context<any>;
248
+ } & {defaultConfig?: Record<string, any>},
249
+ TDefaultContext extends Model<any, any>,
250
+ TElemPropsHook,
251
+ SubComponents = {}
252
+ >({
253
+ displayName,
254
+ modelHook,
255
+ elemPropsHook,
256
+ defaultContext,
257
+ subComponents,
258
+ }: {
259
+ displayName?: string;
260
+ modelHook: TModelHook;
261
+ elemPropsHook?: TElemPropsHook;
262
+ defaultContext?: TDefaultContext;
263
+ subComponents?: SubComponents;
264
+ }) => {
265
+ assert(
266
+ modelHook.Context,
267
+ 'createContainer only works on models with context. Please use `createModelHook` to create the `modelHook`'
268
+ );
269
+ const Context = modelHook.Context;
270
+
271
+ return <Props>(
272
+ Component: (
273
+ props: CompoundProps<Props, TElemPropsHook, E>,
274
+ Element: E extends undefined ? never : E,
275
+ model: TModelHook extends (config: infer TConfig) => infer TModel ? TModel : never
276
+ ) => JSX.Element | null
277
+ ): (TModelHook extends (config: infer TConfig) => infer TModel
278
+ ? E extends undefined
279
+ ? ComponentM<Props & TConfig, TModel>
280
+ : ElementComponentM<
281
+ // E is not `undefined` here, but Typescript thinks it could be, so we add another `undefined`
282
+ // check and cast to a `React.FC` to match a valid signature for `ElementComponent`.
283
+ // `React.FC` was chosen as the simplest valid interface.
284
+ E extends undefined ? React.FC : E,
285
+ Props & TConfig,
286
+ TModel
287
+ >
288
+ : never) &
289
+ SubComponents => {
290
+ const ReturnedComponent = React.forwardRef<
291
+ E,
292
+ Props & {as?: React.ElementType} & {model?: any}
293
+ >(({as: asOverride, model, ...props}, ref) => {
291
294
  const localModel = useDefaultModel(model, props, modelHook, asOverride);
292
295
  const elemProps = ((modelHook as any).getElemProps || defaultGetElemProps)(props);
293
296
  const finalElemProps = elemPropsHook
@@ -311,39 +314,40 @@ export const createContainer = <
311
314
  localModel
312
315
  )
313
316
  );
314
- }
315
- );
316
-
317
- Object.keys(subComponents || {}).forEach(key => {
318
- // `ReturnedComponent` is a `React.ForwardRefExoticComponent` which has no additional keys so
319
- // we'll cast to `Record<string, any>` for assignment. Note the lack of type checking
320
- // properties. Take care when changing the runtime of this function.
321
- (ReturnedComponent as Record<string, any>)[key] = (subComponents as Record<string, any>)[key];
322
- // Add a displayName if one isn't already created. This prevents us from having to add
323
- // `displayName` to subcomponents if a container component has a `displayName`
324
- if (displayName && !(subComponents as Record<string, any>)[key].displayName) {
325
- (subComponents as Record<string, any>)[key].displayName = `${displayName}.${key}`;
326
- }
327
- });
328
- ReturnedComponent.displayName = displayName;
329
- (ReturnedComponent as any).__hasModel = true;
317
+ });
330
318
 
331
- // The `any`s are here because `ElementComponent` takes care of the `as` type and the
332
- // `ReturnComponent` type is overridden
333
- (ReturnedComponent as any).as = memoize(
334
- (as: any) =>
335
- createContainer(as)({displayName, subComponents, modelHook, elemPropsHook})(
336
- Component as any
337
- ),
338
- as => as
339
- );
319
+ Object.keys(subComponents || {}).forEach(key => {
320
+ // `ReturnedComponent` is a `React.ForwardRefExoticComponent` which has no additional keys so
321
+ // we'll cast to `Record<string, any>` for assignment. Note the lack of type checking
322
+ // properties. Take care when changing the runtime of this function.
323
+ (ReturnedComponent as Record<string, any>)[key] = (subComponents as Record<string, any>)[
324
+ key
325
+ ];
326
+ // Add a displayName if one isn't already created. This prevents us from having to add
327
+ // `displayName` to subcomponents if a container component has a `displayName`
328
+ if (displayName && !(subComponents as Record<string, any>)[key].displayName) {
329
+ (subComponents as Record<string, any>)[key].displayName = `${displayName}.${key}`;
330
+ }
331
+ });
332
+ ReturnedComponent.displayName = displayName;
333
+ (ReturnedComponent as any).__hasModel = true;
334
+
335
+ // The `any`s are here because `ElementComponent` takes care of the `as` type and the
336
+ // `ReturnComponent` type is overridden
337
+ (ReturnedComponent as any).as = memoize(
338
+ (as: any) =>
339
+ createContainer(as)({displayName, subComponents, modelHook, elemPropsHook})(
340
+ Component as any
341
+ ),
342
+ as => as
343
+ );
340
344
 
341
- // Cast as `any`. We have already specified the return type. Be careful making changes to this
342
- // file due to this `any` `ReturnedComponent` is a `React.ForwardRefExoticComponent`, but we want
343
- // it to be either an `Component` or `ElementComponent`
344
- return ReturnedComponent as any;
345
+ // Cast as `any`. We have already specified the return type. Be careful making changes to this
346
+ // file due to this `any` `ReturnedComponent` is a `React.ForwardRefExoticComponent`, but we want
347
+ // it to be either an `Component` or `ElementComponent`
348
+ return ReturnedComponent as any;
349
+ };
345
350
  };
346
- };
347
351
 
348
352
  /**
349
353
  * If elemProps returns `null` for a prop, that prop is to be removed from the prop
@@ -370,76 +374,179 @@ type CompoundProps<Props, TElemPropsHook, E> = Props &
370
374
  children?: React.ReactNode;
371
375
  });
372
376
 
373
- export const createSubcomponent = <
374
- E extends
375
- | keyof JSX.IntrinsicElements
376
- | React.ComponentType
377
- | ElementComponentM<any, any, any>
378
- | undefined = undefined
379
- >(
380
- as?: E
381
- ) => <
382
- TElemPropsHook, // normally we'd put a constraint here, but doing so causes the `infer` below to fail to infer the return props
383
- TModelHook extends ((config: any) => Model<any, any>) & {Context?: React.Context<any>},
384
- SubComponents = {}
385
- >({
386
- displayName,
387
- modelHook,
388
- elemPropsHook,
389
- subComponents,
390
- }: {
391
- /** @deprecated ⚠️ `displayName` has been deprecated and will be removed in a future major version. You no longer need to use `displayName`. A `displayName` will be automatically added if it belongs to a container. */
392
- displayName?: string;
393
- modelHook: TModelHook;
394
- elemPropsHook?: TElemPropsHook;
395
- subComponents?: SubComponents;
396
- }) => {
397
- assert(
398
- modelHook.Context,
399
- 'createSubcomponent only works on models with context. Please use `createModelHook` to create the `modelHook`'
400
- );
401
-
402
- return <Props = {}>(
403
- Component: (
404
- props: CompoundProps<Props, TElemPropsHook, E>,
405
- Element: E extends undefined ? never : E,
406
- model: TModelHook extends (...args: any[]) => infer TModel ? TModel : never
407
- ) => JSX.Element | null
408
- ): (TModelHook extends (...args: any[]) => infer TModel
409
- ? ElementComponentM<
377
+ export const createSubcomponent =
378
+ <
379
+ E extends
380
+ | keyof JSX.IntrinsicElements
381
+ | React.ComponentType
382
+ | ElementComponentM<any, any, any>
383
+ | undefined = undefined
384
+ >(
385
+ as?: E
386
+ ) =>
387
+ <
388
+ TElemPropsHook, // normally we'd put a constraint here, but doing so causes the `infer` below to fail to infer the return props
389
+ TModelHook extends ((config: any) => Model<any, any>) & {Context?: React.Context<any>},
390
+ SubComponents = {}
391
+ >({
392
+ displayName,
393
+ modelHook,
394
+ elemPropsHook,
395
+ subComponents,
396
+ }: {
397
+ /** @deprecated ⚠️ `displayName` has been deprecated and will be removed in a future major version. You no longer need to use `displayName`. A `displayName` will be automatically added if it belongs to a container. */
398
+ displayName?: string;
399
+ modelHook: TModelHook;
400
+ elemPropsHook?: TElemPropsHook;
401
+ subComponents?: SubComponents;
402
+ }) => {
403
+ assert(
404
+ modelHook.Context,
405
+ 'createSubcomponent only works on models with context. Please use `createModelHook` to create the `modelHook`'
406
+ );
407
+
408
+ return <Props = {}>(
409
+ Component: (
410
+ props: CompoundProps<Props, TElemPropsHook, E>,
411
+ Element: E extends undefined ? never : E,
412
+ model: TModelHook extends (...args: any[]) => infer TModel ? TModel : never
413
+ ) => JSX.Element | null
414
+ ): (TModelHook extends (...args: any[]) => infer TModel
415
+ ? ElementComponentM<
416
+ // E is not `undefined` here, but Typescript thinks it could be, so we add another `undefined`
417
+ // check and cast to a `React.FC` to match a valid signature for `ElementComponent`.
418
+ // `React.FC` was chosen as the simplest valid interface.
419
+ E extends undefined ? React.FC : E,
420
+ Props,
421
+ TModel
422
+ >
423
+ : never) &
424
+ SubComponents => {
425
+ const ReturnedComponent = React.forwardRef<
426
+ E,
427
+ Props & {as?: React.ElementType} & {model?: any; elemPropsHook?: (...args: any) => any}
428
+ >(({as: asOverride, model, elemPropsHook: additionalPropsHook, ...props}, ref) => {
429
+ const localModel = useModelContext(modelHook.Context!, model, asOverride);
430
+ // maybeModelProps reattached the `model` prop if the passed model is incompatible with the
431
+ // modelHook's context. This fixes issues when using the `as` prop on model element components
432
+ // that both have a model
433
+ const maybeModelProps =
434
+ model && localModel !== model ? {...props, model, ref} : {...props, ref};
435
+
436
+ const elemProps = elemPropsHook
437
+ ? (elemPropsHook as any)(localModel, maybeModelProps, ref)
438
+ : maybeModelProps;
439
+
440
+ return Component(
441
+ additionalPropsHook ? additionalPropsHook(localModel, elemProps, ref) : elemProps,
442
+ // Cast to `any` to avoid: "ts(2345): Type 'undefined' is not assignable to type 'E extends
443
+ // undefined ? never : E'" I'm not sure I can actually cast to this conditional type and it
444
+ // doesn't actually matter, so cast to `any` it is.
445
+ (asOverride || as) as any,
446
+ localModel
447
+ );
448
+ });
449
+
450
+ Object.keys(subComponents || {}).forEach(key => {
451
+ // `ReturnedComponent` is a `React.ForwardRefExoticComponent` which has no additional keys so
452
+ // we'll cast to `Record<string, any>` for assignment. Note the lack of type checking
453
+ // properties. Take care when changing the runtime of this function.
454
+ (ReturnedComponent as Record<string, any>)[key] = (subComponents as Record<string, any>)[
455
+ key
456
+ ];
457
+ });
458
+
459
+ if (displayName) {
460
+ ReturnedComponent.displayName = displayName;
461
+ }
462
+ (ReturnedComponent as any).__hasModel = true;
463
+
464
+ // The `any`s are here because `ElementComponent` takes care of the `as` type and the
465
+ // `ReturnComponent` type is overridden
466
+ (ReturnedComponent as any).as = memoize(
467
+ (as: any) =>
468
+ createSubcomponent(as)({displayName, subComponents, modelHook, elemPropsHook})(
469
+ Component as any
470
+ ),
471
+ as => as
472
+ );
473
+
474
+ // Cast as `any`. We have already specified the return type. Be careful making changes to this
475
+ // file due to this `any` `ReturnedComponent` is a `React.ForwardRefExoticComponent`, but we want
476
+ // it to be either an `Component` or `ElementComponent`
477
+ return ReturnedComponent as any;
478
+ };
479
+ };
480
+
481
+ /**
482
+ * Factory function that creates components to be exported. It enforces React ref forwarding, `as`
483
+ * prop, display name, and sub-components, and handles proper typing without much boiler plate. The
484
+ * return type is `Component<element, Props>` which looks like `Component<'div', Props>` which is a
485
+ * clean interface that tells you the default element that is used.
486
+ */
487
+ export const createComponent =
488
+ <
489
+ E extends
490
+ | keyof JSX.IntrinsicElements
491
+ | React.ComponentType
492
+ | ElementComponent<any, any>
493
+ | undefined = undefined
494
+ >(
495
+ as?: E
496
+ ) =>
497
+ <P, SubComponents = {}>({
498
+ displayName,
499
+ Component,
500
+ subComponents,
501
+ }: {
502
+ /** This is what the component will look like in the React dev tools. Encouraged to more easily
503
+ * understand the component tree */
504
+ displayName?: string;
505
+ /** The component function. The function looks like:
506
+ * @example
507
+ * Component: ({children}, ref, Element) {
508
+ * // `Element` is what's passed to the `as` of your component. If no `as` was defined, it
509
+ * // will be the default element. It will be 'div' or even a another Component!
510
+ * return (
511
+ * <Element ref={ref}>{children}</Element>
512
+ * )
513
+ * }
514
+ *
515
+ * @example
516
+ * Component: ({children}, ref, Element) {
517
+ * // `Element` can be passed via `as` to the next component
518
+ * return (
519
+ * <AnotherElement as={Element} ref={ref}>{children}</AnotherElement>
520
+ * )
521
+ * }
522
+ */
523
+ Component: RefForwardingComponent<E, P>;
524
+ /**
525
+ * Used in container components
526
+ */
527
+ subComponents?: SubComponents;
528
+ }): (E extends undefined
529
+ ? Component<P>
530
+ : ElementComponent<
410
531
  // E is not `undefined` here, but Typescript thinks it could be, so we add another `undefined`
411
532
  // check and cast to a `React.FC` to match a valid signature for `ElementComponent`.
412
533
  // `React.FC` was chosen as the simplest valid interface.
413
534
  E extends undefined ? React.FC : E,
414
- Props,
415
- TModel
416
- >
417
- : never) &
535
+ P
536
+ >) &
418
537
  SubComponents => {
419
- const ReturnedComponent = React.forwardRef<
420
- E,
421
- Props & {as?: React.ElementType} & {model?: any; elemPropsHook?: (...args: any) => any}
422
- >(({as: asOverride, model, elemPropsHook: additionalPropsHook, ...props}, ref) => {
423
- const localModel = useModelContext(modelHook.Context!, model, asOverride);
424
- // maybeModelProps reattached the `model` prop if the passed model is incompatible with the
425
- // modelHook's context. This fixes issues when using the `as` prop on model element components
426
- // that both have a model
427
- const maybeModelProps =
428
- model && localModel !== model ? {...props, model, ref} : {...props, ref};
429
-
430
- const elemProps = elemPropsHook
431
- ? (elemPropsHook as any)(localModel, maybeModelProps, ref)
432
- : maybeModelProps;
433
-
434
- return Component(
435
- additionalPropsHook ? additionalPropsHook(localModel, elemProps, ref) : elemProps,
436
- // Cast to `any` to avoid: "ts(2345): Type 'undefined' is not assignable to type 'E extends
437
- // undefined ? never : E'" I'm not sure I can actually cast to this conditional type and it
438
- // doesn't actually matter, so cast to `any` it is.
439
- (asOverride || as) as any,
440
- localModel
441
- );
442
- });
538
+ const ReturnedComponent = React.forwardRef<E, P & {as?: React.ElementType}>(
539
+ ({as: asOverride, ...props}, ref) => {
540
+ return Component(
541
+ props as P,
542
+ ref as ExtractRef<E>,
543
+ // Cast to `any` to avoid: "ts(2345): Type 'undefined' is not assignable to type 'E extends
544
+ // undefined ? never : E'" I'm not sure I can actually cast to this conditional type and it
545
+ // doesn't actually matter, so cast to `any` it is.
546
+ (asOverride || as) as any
547
+ );
548
+ }
549
+ );
443
550
 
444
551
  Object.keys(subComponents || {}).forEach(key => {
445
552
  // `ReturnedComponent` is a `React.ForwardRefExoticComponent` which has no additional keys so
@@ -447,19 +554,12 @@ export const createSubcomponent = <
447
554
  // properties. Take care when changing the runtime of this function.
448
555
  (ReturnedComponent as Record<string, any>)[key] = (subComponents as Record<string, any>)[key];
449
556
  });
450
-
451
- if (displayName) {
452
- ReturnedComponent.displayName = displayName;
453
- }
454
- (ReturnedComponent as any).__hasModel = true;
557
+ ReturnedComponent.displayName = displayName;
455
558
 
456
559
  // The `any`s are here because `ElementComponent` takes care of the `as` type and the
457
560
  // `ReturnComponent` type is overridden
458
561
  (ReturnedComponent as any).as = memoize(
459
- (as: any) =>
460
- createSubcomponent(as)({displayName, subComponents, modelHook, elemPropsHook})(
461
- Component as any
462
- ),
562
+ (as: any) => createComponent(as)({displayName, Component, subComponents}),
463
563
  as => as
464
564
  );
465
565
 
@@ -468,96 +568,6 @@ export const createSubcomponent = <
468
568
  // it to be either an `Component` or `ElementComponent`
469
569
  return ReturnedComponent as any;
470
570
  };
471
- };
472
-
473
- /**
474
- * Factory function that creates components to be exported. It enforces React ref forwarding, `as`
475
- * prop, display name, and sub-components, and handles proper typing without much boiler plate. The
476
- * return type is `Component<element, Props>` which looks like `Component<'div', Props>` which is a
477
- * clean interface that tells you the default element that is used.
478
- */
479
- export const createComponent = <
480
- E extends
481
- | keyof JSX.IntrinsicElements
482
- | React.ComponentType
483
- | ElementComponent<any, any>
484
- | undefined = undefined
485
- >(
486
- as?: E
487
- ) => <P, SubComponents = {}>({
488
- displayName,
489
- Component,
490
- subComponents,
491
- }: {
492
- /** This is what the component will look like in the React dev tools. Encouraged to more easily
493
- * understand the component tree */
494
- displayName?: string;
495
- /** The component function. The function looks like:
496
- * @example
497
- * Component: ({children}, ref, Element) {
498
- * // `Element` is what's passed to the `as` of your component. If no `as` was defined, it
499
- * // will be the default element. It will be 'div' or even a another Component!
500
- * return (
501
- * <Element ref={ref}>{children}</Element>
502
- * )
503
- * }
504
- *
505
- * @example
506
- * Component: ({children}, ref, Element) {
507
- * // `Element` can be passed via `as` to the next component
508
- * return (
509
- * <AnotherElement as={Element} ref={ref}>{children}</AnotherElement>
510
- * )
511
- * }
512
- */
513
- Component: RefForwardingComponent<E, P>;
514
- /**
515
- * Used in container components
516
- */
517
- subComponents?: SubComponents;
518
- }): (E extends undefined
519
- ? Component<P>
520
- : ElementComponent<
521
- // E is not `undefined` here, but Typescript thinks it could be, so we add another `undefined`
522
- // check and cast to a `React.FC` to match a valid signature for `ElementComponent`.
523
- // `React.FC` was chosen as the simplest valid interface.
524
- E extends undefined ? React.FC : E,
525
- P
526
- >) &
527
- SubComponents => {
528
- const ReturnedComponent = React.forwardRef<E, P & {as?: React.ElementType}>(
529
- ({as: asOverride, ...props}, ref) => {
530
- return Component(
531
- props as P,
532
- ref as ExtractRef<E>,
533
- // Cast to `any` to avoid: "ts(2345): Type 'undefined' is not assignable to type 'E extends
534
- // undefined ? never : E'" I'm not sure I can actually cast to this conditional type and it
535
- // doesn't actually matter, so cast to `any` it is.
536
- (asOverride || as) as any
537
- );
538
- }
539
- );
540
-
541
- Object.keys(subComponents || {}).forEach(key => {
542
- // `ReturnedComponent` is a `React.ForwardRefExoticComponent` which has no additional keys so
543
- // we'll cast to `Record<string, any>` for assignment. Note the lack of type checking
544
- // properties. Take care when changing the runtime of this function.
545
- (ReturnedComponent as Record<string, any>)[key] = (subComponents as Record<string, any>)[key];
546
- });
547
- ReturnedComponent.displayName = displayName;
548
-
549
- // The `any`s are here because `ElementComponent` takes care of the `as` type and the
550
- // `ReturnComponent` type is overridden
551
- (ReturnedComponent as any).as = memoize(
552
- (as: any) => createComponent(as)({displayName, Component, subComponents}),
553
- as => as
554
- );
555
-
556
- // Cast as `any`. We have already specified the return type. Be careful making changes to this
557
- // file due to this `any` `ReturnedComponent` is a `React.ForwardRefExoticComponent`, but we want
558
- // it to be either an `Component` or `ElementComponent`
559
- return ReturnedComponent as any;
560
- };
561
571
 
562
572
  /**
563
573
  * An `elemPropsHook` is a React hook that takes a model, ref, and elemProps and returns props and
@@ -588,30 +598,30 @@ export const createComponent = <
588
598
  * })
589
599
  * ```
590
600
  */
591
- export const createElemPropsHook = <TModelHook extends (config: any) => Model<any, any>>(
592
- modelHook: TModelHook
593
- ) => <PO extends {}, PI extends {}>(
594
- fn: (
595
- model: TModelHook extends (config: any) => infer TModel ? TModel : Model<any, any>,
596
- ref?: React.Ref<unknown>,
597
- elemProps?: PI
598
- ) => PO
599
- ): BehaviorHook<
600
- TModelHook extends (config: any) => infer TModel ? TModel : Model<any, any>,
601
- PO
602
- > => {
603
- return ((model, elemProps, ref) => {
604
- const props = mergeProps(fn(model, ref, elemProps || ({} as any)), elemProps || ({} as any));
605
- if (!props.hasOwnProperty('ref') && ref) {
606
- // This is the weird "incoming ref isn't in props, but outgoing ref is in props" thing
607
- props.ref = ref;
608
- }
609
- return props;
610
- }) as BehaviorHook<
601
+ export const createElemPropsHook =
602
+ <TModelHook extends (config: any) => Model<any, any>>(modelHook: TModelHook) =>
603
+ <PO extends {}, PI extends {}>(
604
+ fn: (
605
+ model: TModelHook extends (config: any) => infer TModel ? TModel : Model<any, any>,
606
+ ref?: React.Ref<unknown>,
607
+ elemProps?: PI
608
+ ) => PO
609
+ ): BehaviorHook<
611
610
  TModelHook extends (config: any) => infer TModel ? TModel : Model<any, any>,
612
611
  PO
613
- >;
614
- };
612
+ > => {
613
+ return ((model, elemProps, ref) => {
614
+ const props = mergeProps(fn(model, ref, elemProps || ({} as any)), elemProps || ({} as any));
615
+ if (!props.hasOwnProperty('ref') && ref) {
616
+ // This is the weird "incoming ref isn't in props, but outgoing ref is in props" thing
617
+ props.ref = ref;
618
+ }
619
+ return props;
620
+ }) as BehaviorHook<
621
+ TModelHook extends (config: any) => infer TModel ? TModel : Model<any, any>,
622
+ PO
623
+ >;
624
+ };
615
625
 
616
626
  /**
617
627
  * Factory function to crate a behavior hook with correct generic types. It takes a function that