@ankhorage/zora 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/components/form/Form.d.ts +4 -0
  3. package/dist/components/form/Form.d.ts.map +1 -0
  4. package/dist/components/form/Form.js +27 -0
  5. package/dist/components/form/Form.js.map +1 -0
  6. package/dist/components/form/FormActions.d.ts +4 -0
  7. package/dist/components/form/FormActions.d.ts.map +1 -0
  8. package/dist/components/form/FormActions.js +12 -0
  9. package/dist/components/form/FormActions.js.map +1 -0
  10. package/dist/components/form/FormError.d.ts +4 -0
  11. package/dist/components/form/FormError.d.ts.map +1 -0
  12. package/dist/components/form/FormError.js +14 -0
  13. package/dist/components/form/FormError.js.map +1 -0
  14. package/dist/components/form/FormField.d.ts +4 -0
  15. package/dist/components/form/FormField.d.ts.map +1 -0
  16. package/dist/components/form/FormField.js +74 -0
  17. package/dist/components/form/FormField.js.map +1 -0
  18. package/dist/components/form/index.d.ts +8 -0
  19. package/dist/components/form/index.d.ts.map +1 -0
  20. package/dist/components/form/index.js +7 -0
  21. package/dist/components/form/index.js.map +1 -0
  22. package/dist/components/form/types.d.ts +107 -0
  23. package/dist/components/form/types.d.ts.map +1 -0
  24. package/dist/components/form/types.js +2 -0
  25. package/dist/components/form/types.js.map +1 -0
  26. package/dist/components/form/useFormController.d.ts +3 -0
  27. package/dist/components/form/useFormController.d.ts.map +1 -0
  28. package/dist/components/form/useFormController.js +62 -0
  29. package/dist/components/form/useFormController.js.map +1 -0
  30. package/dist/components/form/validation.d.ts +6 -0
  31. package/dist/components/form/validation.d.ts.map +1 -0
  32. package/dist/components/form/validation.js +52 -0
  33. package/dist/components/form/validation.js.map +1 -0
  34. package/dist/index.d.ts +4 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +2 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/patterns/auth/ForgotPasswordForm.d.ts +4 -0
  39. package/dist/patterns/auth/ForgotPasswordForm.d.ts.map +1 -0
  40. package/dist/patterns/auth/ForgotPasswordForm.js +31 -0
  41. package/dist/patterns/auth/ForgotPasswordForm.js.map +1 -0
  42. package/dist/patterns/auth/OtpForm.d.ts +4 -0
  43. package/dist/patterns/auth/OtpForm.d.ts.map +1 -0
  44. package/dist/patterns/auth/OtpForm.js +30 -0
  45. package/dist/patterns/auth/OtpForm.js.map +1 -0
  46. package/dist/patterns/auth/SignInForm.d.ts +4 -0
  47. package/dist/patterns/auth/SignInForm.d.ts.map +1 -0
  48. package/dist/patterns/auth/SignInForm.js +45 -0
  49. package/dist/patterns/auth/SignInForm.js.map +1 -0
  50. package/dist/patterns/auth/SignUpForm.d.ts +4 -0
  51. package/dist/patterns/auth/SignUpForm.d.ts.map +1 -0
  52. package/dist/patterns/auth/SignUpForm.js +37 -0
  53. package/dist/patterns/auth/SignUpForm.js.map +1 -0
  54. package/dist/patterns/auth/index.d.ts +6 -0
  55. package/dist/patterns/auth/index.d.ts.map +1 -0
  56. package/dist/patterns/auth/index.js +5 -0
  57. package/dist/patterns/auth/index.js.map +1 -0
  58. package/dist/patterns/auth/types.d.ts +57 -0
  59. package/dist/patterns/auth/types.d.ts.map +1 -0
  60. package/dist/patterns/auth/types.js +2 -0
  61. package/dist/patterns/auth/types.js.map +1 -0
  62. package/dist/patterns/auth/utils.d.ts +8 -0
  63. package/dist/patterns/auth/utils.d.ts.map +1 -0
  64. package/dist/patterns/auth/utils.js +51 -0
  65. package/dist/patterns/auth/utils.js.map +1 -0
  66. package/package.json +2 -2
  67. package/src/components/form/Form.tsx +61 -0
  68. package/src/components/form/FormActions.tsx +23 -0
  69. package/src/components/form/FormError.tsx +20 -0
  70. package/src/components/form/FormField.tsx +128 -0
  71. package/src/components/form/index.ts +24 -0
  72. package/src/components/form/types.ts +115 -0
  73. package/src/components/form/useFormController.ts +105 -0
  74. package/src/components/form/validation.test.ts +79 -0
  75. package/src/components/form/validation.ts +83 -0
  76. package/src/index.ts +43 -2
  77. package/src/patterns/auth/ForgotPasswordForm.tsx +84 -0
  78. package/src/patterns/auth/OtpForm.tsx +80 -0
  79. package/src/patterns/auth/SignInForm.tsx +111 -0
  80. package/src/patterns/auth/SignUpForm.tsx +76 -0
  81. package/src/patterns/auth/index.ts +17 -0
  82. package/src/patterns/auth/types.ts +67 -0
  83. package/src/patterns/auth/utils.ts +80 -0
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { Button } from './components/button';
3
3
  export { Card } from './components/card';
4
4
  export { Checkbox, CheckboxGroup } from './components/checkbox';
5
5
  export { Drawer } from './components/drawer';
6
+ export { Form, FormActions, FormError, FormField, hasRequiredRule, useFormController, validateField, validateFields, validateValue, } from './components/form';
6
7
  export { Icon } from './components/icon';
7
8
  export { IconButton } from './components/icon-button';
8
9
  export { Input } from './components/input';
@@ -20,11 +21,11 @@ export { PageSection } from './layout/page-section';
20
21
  export { SettingsLayout } from './layout/settings-layout';
21
22
  export { SidebarLayout } from './layout/sidebar-layout';
22
23
  export { TopbarLayout } from './layout/topbar-layout';
24
+ export { ForgotPasswordForm, OtpForm, SignInForm, SignUpForm } from './patterns/auth';
23
25
  export { CollectionEditor } from './patterns/collection-editor';
24
26
  export { ConfirmDialog } from './patterns/confirm-dialog';
25
27
  export { DisclosureSection } from './patterns/disclosure-section';
26
28
  export { EmptyState } from './patterns/empty-state';
27
- export { FormField } from './patterns/form-field';
28
29
  export { InspectorField } from './patterns/inspector-field';
29
30
  export { Notice } from './patterns/notice';
30
31
  export { Panel } from './patterns/panel';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,cAAc,SAAS,CAAC","sourcesContent":["export type { BadgeProps } from './components/badge';\nexport { Badge } from './components/badge';\nexport type { ButtonProps } from './components/button';\nexport { Button } from './components/button';\nexport type { CardProps } from './components/card';\nexport { Card } from './components/card';\nexport type { CheckboxGroupOption, CheckboxGroupProps, CheckboxProps } from './components/checkbox';\nexport { Checkbox, CheckboxGroup } from './components/checkbox';\nexport type { DrawerProps } from './components/drawer';\nexport { Drawer } from './components/drawer';\nexport type { IconProps } from './components/icon';\nexport { Icon } from './components/icon';\nexport type { IconButtonProps } from './components/icon-button';\nexport { IconButton } from './components/icon-button';\nexport type { InputProps } from './components/input';\nexport { Input } from './components/input';\nexport type { ModalProps } from './components/modal';\nexport { Modal } from './components/modal';\nexport type { RadioGroupOption, RadioGroupProps, RadioProps } from './components/radio';\nexport { Radio, RadioGroup } from './components/radio';\nexport type { SelectOption, SelectProps } from './components/select';\nexport { Select } from './components/select';\nexport type { TabItem, TabsProps } from './components/tabs';\nexport { Tabs } from './components/tabs';\nexport type { TextareaProps } from './components/textarea';\nexport { Textarea } from './components/textarea';\nexport type { ToolbarActionProps, ToolbarProps } from './components/toolbar';\nexport { Toolbar, ToolbarAction } from './components/toolbar';\nexport type { AppShellProps } from './layout/app-shell';\nexport { AppShell } from './layout/app-shell';\nexport type { AuthLayoutProps } from './layout/auth-layout';\nexport { AuthLayout } from './layout/auth-layout';\nexport type { PageProps } from './layout/page';\nexport { Page } from './layout/page';\nexport type { PageHeaderProps } from './layout/page-header';\nexport { PageHeader } from './layout/page-header';\nexport type { PageSectionProps } from './layout/page-section';\nexport { PageSection } from './layout/page-section';\nexport type { SettingsLayoutProps } from './layout/settings-layout';\nexport { SettingsLayout } from './layout/settings-layout';\nexport type { SidebarLayoutProps } from './layout/sidebar-layout';\nexport { SidebarLayout } from './layout/sidebar-layout';\nexport type { TopbarLayoutProps } from './layout/topbar-layout';\nexport { TopbarLayout } from './layout/topbar-layout';\nexport type {\n CollectionEditorProps,\n CollectionEditorRenderItemProps,\n} from './patterns/collection-editor';\nexport { CollectionEditor } from './patterns/collection-editor';\nexport type { ConfirmDialogProps } from './patterns/confirm-dialog';\nexport { ConfirmDialog } from './patterns/confirm-dialog';\nexport type { DisclosureSectionProps } from './patterns/disclosure-section';\nexport { DisclosureSection } from './patterns/disclosure-section';\nexport type { EmptyStateAction, EmptyStateProps } from './patterns/empty-state';\nexport { EmptyState } from './patterns/empty-state';\nexport type { FormFieldProps } from './patterns/form-field';\nexport { FormField } from './patterns/form-field';\nexport type { InspectorFieldProps } from './patterns/inspector-field';\nexport { InspectorField } from './patterns/inspector-field';\nexport type { NoticeProps } from './patterns/notice';\nexport { Notice } from './patterns/notice';\nexport type { PanelProps } from './patterns/panel';\nexport { Panel } from './patterns/panel';\nexport type { ResponsivePanelProps } from './patterns/responsive-panel';\nexport { ResponsivePanel } from './patterns/responsive-panel';\nexport type { SectionHeaderProps } from './patterns/section-header';\nexport { SectionHeader } from './patterns/section-header';\nexport type { SettingsRowProps } from './patterns/settings-row';\nexport { SettingsRow } from './patterns/settings-row';\nexport type { SwitchFieldProps } from './patterns/switch-field';\nexport { SwitchField } from './patterns/switch-field';\nexport type { PaletteItemProps, TileGridProps } from './patterns/tile-grid';\nexport { PaletteItem, TileGrid } from './patterns/tile-grid';\nexport type { TreeItemNode, TreeItemRenderProps, TreeViewProps } from './patterns/tree-view';\nexport { TreeItem, TreeView } from './patterns/tree-view';\nexport * from './theme';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAmB7C,OAAO,EACL,IAAI,EACJ,WAAW,EACX,SAAS,EACT,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AActD,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,cAAc,SAAS,CAAC","sourcesContent":["export type { BadgeProps } from './components/badge';\nexport { Badge } from './components/badge';\nexport type { ButtonProps } from './components/button';\nexport { Button } from './components/button';\nexport type { CardProps } from './components/card';\nexport { Card } from './components/card';\nexport type { CheckboxGroupOption, CheckboxGroupProps, CheckboxProps } from './components/checkbox';\nexport { Checkbox, CheckboxGroup } from './components/checkbox';\nexport type { DrawerProps } from './components/drawer';\nexport { Drawer } from './components/drawer';\nexport type {\n FormActionsProps,\n FormErrorProps,\n FormErrors,\n FormFieldConfig,\n FormFieldControlProps,\n FormFieldInputType,\n FormFieldProps,\n FormFieldValue,\n FormFieldWrapperProps,\n FormProps,\n FormValidationErrors,\n FormValidationResult,\n FormValues,\n UseFormControllerOptions,\n UseFormControllerResult,\n ValidationRule,\n} from './components/form';\nexport {\n Form,\n FormActions,\n FormError,\n FormField,\n hasRequiredRule,\n useFormController,\n validateField,\n validateFields,\n validateValue,\n} from './components/form';\nexport type { IconProps } from './components/icon';\nexport { Icon } from './components/icon';\nexport type { IconButtonProps } from './components/icon-button';\nexport { IconButton } from './components/icon-button';\nexport type { InputProps } from './components/input';\nexport { Input } from './components/input';\nexport type { ModalProps } from './components/modal';\nexport { Modal } from './components/modal';\nexport type { RadioGroupOption, RadioGroupProps, RadioProps } from './components/radio';\nexport { Radio, RadioGroup } from './components/radio';\nexport type { SelectOption, SelectProps } from './components/select';\nexport { Select } from './components/select';\nexport type { TabItem, TabsProps } from './components/tabs';\nexport { Tabs } from './components/tabs';\nexport type { TextareaProps } from './components/textarea';\nexport { Textarea } from './components/textarea';\nexport type { ToolbarActionProps, ToolbarProps } from './components/toolbar';\nexport { Toolbar, ToolbarAction } from './components/toolbar';\nexport type { AppShellProps } from './layout/app-shell';\nexport { AppShell } from './layout/app-shell';\nexport type { AuthLayoutProps } from './layout/auth-layout';\nexport { AuthLayout } from './layout/auth-layout';\nexport type { PageProps } from './layout/page';\nexport { Page } from './layout/page';\nexport type { PageHeaderProps } from './layout/page-header';\nexport { PageHeader } from './layout/page-header';\nexport type { PageSectionProps } from './layout/page-section';\nexport { PageSection } from './layout/page-section';\nexport type { SettingsLayoutProps } from './layout/settings-layout';\nexport { SettingsLayout } from './layout/settings-layout';\nexport type { SidebarLayoutProps } from './layout/sidebar-layout';\nexport { SidebarLayout } from './layout/sidebar-layout';\nexport type { TopbarLayoutProps } from './layout/topbar-layout';\nexport { TopbarLayout } from './layout/topbar-layout';\nexport type {\n AuthFormBaseProps,\n AuthIdentifierKind,\n ForgotPasswordFormProps,\n ForgotPasswordFormValues,\n OtpFormProps,\n OtpFormValues,\n SignInFormProps,\n SignInFormValues,\n SignUpFormField,\n SignUpFormProps,\n SignUpFormValues,\n} from './patterns/auth';\nexport { ForgotPasswordForm, OtpForm, SignInForm, SignUpForm } from './patterns/auth';\nexport type {\n CollectionEditorProps,\n CollectionEditorRenderItemProps,\n} from './patterns/collection-editor';\nexport { CollectionEditor } from './patterns/collection-editor';\nexport type { ConfirmDialogProps } from './patterns/confirm-dialog';\nexport { ConfirmDialog } from './patterns/confirm-dialog';\nexport type { DisclosureSectionProps } from './patterns/disclosure-section';\nexport { DisclosureSection } from './patterns/disclosure-section';\nexport type { EmptyStateAction, EmptyStateProps } from './patterns/empty-state';\nexport { EmptyState } from './patterns/empty-state';\nexport type { InspectorFieldProps } from './patterns/inspector-field';\nexport { InspectorField } from './patterns/inspector-field';\nexport type { NoticeProps } from './patterns/notice';\nexport { Notice } from './patterns/notice';\nexport type { PanelProps } from './patterns/panel';\nexport { Panel } from './patterns/panel';\nexport type { ResponsivePanelProps } from './patterns/responsive-panel';\nexport { ResponsivePanel } from './patterns/responsive-panel';\nexport type { SectionHeaderProps } from './patterns/section-header';\nexport { SectionHeader } from './patterns/section-header';\nexport type { SettingsRowProps } from './patterns/settings-row';\nexport { SettingsRow } from './patterns/settings-row';\nexport type { SwitchFieldProps } from './patterns/switch-field';\nexport { SwitchField } from './patterns/switch-field';\nexport type { PaletteItemProps, TileGridProps } from './patterns/tile-grid';\nexport { PaletteItem, TileGrid } from './patterns/tile-grid';\nexport type { TreeItemNode, TreeItemRenderProps, TreeViewProps } from './patterns/tree-view';\nexport { TreeItem, TreeView } from './patterns/tree-view';\nexport * from './theme';\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ForgotPasswordFormProps } from './types';
3
+ export declare function ForgotPasswordForm({ identifiers, identifierLabel, signInLabel, loading, disabled, error, submitLabel, onSubmit, onSignIn, testID, }: ForgotPasswordFormProps): React.JSX.Element;
4
+ //# sourceMappingURL=ForgotPasswordForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgotPasswordForm.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/ForgotPasswordForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAWvD,wBAAgB,kBAAkB,CAAC,EACjC,WAAgC,EAChC,eAAe,EACf,WAAuB,EACvB,OAAe,EACf,QAAgB,EAChB,KAAK,EACL,WAAyB,EACzB,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,uBAAuB,qBAwDzB"}
@@ -0,0 +1,31 @@
1
+ import { Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+ import { Button } from '../../components/button';
4
+ import { Form } from '../../components/form';
5
+ import { defaultIdentifiers, normalizeIdentifierKind, resolveIdentifierLabel, resolveIdentifierRules, resolveIdentifierType, } from './utils';
6
+ export function ForgotPasswordForm({ identifiers = defaultIdentifiers, identifierLabel, signInLabel = 'Sign in', loading = false, disabled = false, error, submitLabel = 'Send code', onSubmit, onSignIn, testID, }) {
7
+ const [values, setValues] = React.useState({
8
+ identifier: '',
9
+ });
10
+ const fields = React.useMemo(() => [
11
+ {
12
+ name: 'identifier',
13
+ label: identifierLabel ?? resolveIdentifierLabel(identifiers),
14
+ type: resolveIdentifierType(identifiers),
15
+ autoCapitalize: 'none',
16
+ rules: resolveIdentifierRules(identifiers),
17
+ },
18
+ ], [identifierLabel, identifiers]);
19
+ const handleSubmit = React.useCallback((formValues) => onSubmit({
20
+ identifier: formValues.identifier.trim(),
21
+ identifierKind: normalizeIdentifierKind(formValues.identifier, identifiers),
22
+ }), [identifiers, onSubmit]);
23
+ return (<Form actions={onSignIn ? (<Stack direction="row" gap="s" wrap="wrap">
24
+ <Button disabled={disabled || loading} emphasis="ghost" onPress={() => {
25
+ void onSignIn();
26
+ }} size="s" tone="neutral">
27
+ {signInLabel}
28
+ </Button>
29
+ </Stack>) : undefined} disabled={disabled} error={error} fields={fields} loading={loading} onChange={setValues} onSubmit={handleSubmit} submitLabel={submitLabel} testID={testID} values={values}/>);
30
+ }
31
+ //# sourceMappingURL=ForgotPasswordForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgotPasswordForm.js","sourceRoot":"","sources":["../../../src/patterns/auth/ForgotPasswordForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAyC,MAAM,uBAAuB,CAAC;AAEpF,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,MAAM,UAAU,kBAAkB,CAAC,EACjC,WAAW,GAAG,kBAAkB,EAChC,eAAe,EACf,WAAW,GAAG,SAAS,EACvB,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,WAAW,GAAG,WAAW,EACzB,QAAQ,EACR,QAAQ,EACR,MAAM,GACkB;IACxB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAsC;QAC9E,UAAU,EAAE,EAAE;KACf,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC;QACJ;YACE,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,eAAe,IAAI,sBAAsB,CAAC,WAAW,CAAC;YAC7D,IAAI,EAAE,qBAAqB,CAAC,WAAW,CAAC;YACxC,cAAc,EAAE,MAAM;YACtB,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC;SAC3C;KACF,EACD,CAAC,eAAe,EAAE,WAAW,CAAC,CAC/B,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,UAA+C,EAAE,EAAE,CAClD,QAAQ,CAAC;QACP,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE;QACxC,cAAc,EAAE,uBAAuB,CAAC,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC;KAC5E,CAAC,EACJ,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxB,CAAC;IAEF,OAAO,CACL,CAAC,IAAI,CACH,OAAO,CAAC,CACN,QAAQ,CAAC,CAAC,CAAC,CACT,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CACxC;YAAA,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAC9B,QAAQ,CAAC,OAAO,CAChB,OAAO,CAAC,CAAC,GAAG,EAAE;gBACZ,KAAK,QAAQ,EAAE,CAAC;YAClB,CAAC,CAAC,CACF,IAAI,CAAC,GAAG,CACR,IAAI,CAAC,SAAS,CAEd;cAAA,CAAC,WAAW,CACd;YAAA,EAAE,MAAM,CACV;UAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,SACN,CAAC,CACD,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,SAAS,CAAC,CACpB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,EACf,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Button } from '../../components/button';\nimport { Form, type FormFieldConfig, type FormValues } from '../../components/form';\nimport type { ForgotPasswordFormProps } from './types';\nimport {\n defaultIdentifiers,\n normalizeIdentifierKind,\n resolveIdentifierLabel,\n resolveIdentifierRules,\n resolveIdentifierType,\n} from './utils';\n\ntype ForgotPasswordFieldName = 'identifier';\n\nexport function ForgotPasswordForm({\n identifiers = defaultIdentifiers,\n identifierLabel,\n signInLabel = 'Sign in',\n loading = false,\n disabled = false,\n error,\n submitLabel = 'Send code',\n onSubmit,\n onSignIn,\n testID,\n}: ForgotPasswordFormProps) {\n const [values, setValues] = React.useState<FormValues<ForgotPasswordFieldName>>({\n identifier: '',\n });\n const fields = React.useMemo<readonly FormFieldConfig<ForgotPasswordFieldName>[]>(\n () => [\n {\n name: 'identifier',\n label: identifierLabel ?? resolveIdentifierLabel(identifiers),\n type: resolveIdentifierType(identifiers),\n autoCapitalize: 'none',\n rules: resolveIdentifierRules(identifiers),\n },\n ],\n [identifierLabel, identifiers],\n );\n\n const handleSubmit = React.useCallback(\n (formValues: FormValues<ForgotPasswordFieldName>) =>\n onSubmit({\n identifier: formValues.identifier.trim(),\n identifierKind: normalizeIdentifierKind(formValues.identifier, identifiers),\n }),\n [identifiers, onSubmit],\n );\n\n return (\n <Form\n actions={\n onSignIn ? (\n <Stack direction=\"row\" gap=\"s\" wrap=\"wrap\">\n <Button\n disabled={disabled || loading}\n emphasis=\"ghost\"\n onPress={() => {\n void onSignIn();\n }}\n size=\"s\"\n tone=\"neutral\"\n >\n {signInLabel}\n </Button>\n </Stack>\n ) : undefined\n }\n disabled={disabled}\n error={error}\n fields={fields}\n loading={loading}\n onChange={setValues}\n onSubmit={handleSubmit}\n submitLabel={submitLabel}\n testID={testID}\n values={values}\n />\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { OtpFormProps } from './types';
3
+ export declare function OtpForm({ length, otpLabel, resendLabel, resendDisabled, resendLoading, loading, disabled, error, submitLabel, onSubmit, onResend, testID, }: OtpFormProps): React.JSX.Element;
4
+ //# sourceMappingURL=OtpForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpForm.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/OtpForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,wBAAgB,OAAO,CAAC,EACtB,MAAU,EACV,QAAiB,EACjB,WAA2B,EAC3B,cAAsB,EACtB,aAAqB,EACrB,OAAe,EACf,QAAgB,EAChB,KAAK,EACL,WAA2B,EAC3B,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,YAAY,qBAyDd"}
@@ -0,0 +1,30 @@
1
+ import { Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+ import { Button } from '../../components/button';
4
+ import { Form } from '../../components/form';
5
+ export function OtpForm({ length = 6, otpLabel = 'Code', resendLabel = 'Resend code', resendDisabled = false, resendLoading = false, loading = false, disabled = false, error, submitLabel = 'Verify code', onSubmit, onResend, testID, }) {
6
+ const resolvedLength = Math.max(1, length);
7
+ const [values, setValues] = React.useState({
8
+ otp: '',
9
+ });
10
+ const fields = React.useMemo(() => [
11
+ {
12
+ name: 'otp',
13
+ label: otpLabel,
14
+ type: 'otp',
15
+ maxLength: resolvedLength,
16
+ rules: [{ kind: 'required' }, { kind: 'minLength', value: resolvedLength }],
17
+ },
18
+ ], [otpLabel, resolvedLength]);
19
+ const handleSubmit = React.useCallback((formValues) => onSubmit({
20
+ otp: formValues.otp.trim(),
21
+ }), [onSubmit]);
22
+ return (<Form actions={onResend ? (<Stack direction="row" gap="s" wrap="wrap">
23
+ <Button disabled={disabled || loading || resendDisabled} emphasis="ghost" loading={resendLoading} onPress={() => {
24
+ void onResend();
25
+ }} size="s" tone="neutral">
26
+ {resendLabel}
27
+ </Button>
28
+ </Stack>) : undefined} disabled={disabled} error={error} fields={fields} loading={loading} onChange={setValues} onSubmit={handleSubmit} submitLabel={submitLabel} testID={testID} values={values}/>);
29
+ }
30
+ //# sourceMappingURL=OtpForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpForm.js","sourceRoot":"","sources":["../../../src/patterns/auth/OtpForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAyC,MAAM,uBAAuB,CAAC;AAKpF,MAAM,UAAU,OAAO,CAAC,EACtB,MAAM,GAAG,CAAC,EACV,QAAQ,GAAG,MAAM,EACjB,WAAW,GAAG,aAAa,EAC3B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,KAAK,EACrB,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,WAAW,GAAG,aAAa,EAC3B,QAAQ,EACR,QAAQ,EACR,MAAM,GACO;IACb,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAA2B;QACnE,GAAG,EAAE,EAAE;KACR,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC;QACJ;YACE,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,KAAK;YACX,SAAS,EAAE,cAAc;YACzB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;SAC5E;KACF,EACD,CAAC,QAAQ,EAAE,cAAc,CAAC,CAC3B,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,UAAoC,EAAE,EAAE,CACvC,QAAQ,CAAC;QACP,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE;KAC3B,CAAC,EACJ,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,OAAO,CACL,CAAC,IAAI,CACH,OAAO,CAAC,CACN,QAAQ,CAAC,CAAC,CAAC,CACT,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CACxC;YAAA,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,QAAQ,IAAI,OAAO,IAAI,cAAc,CAAC,CAChD,QAAQ,CAAC,OAAO,CAChB,OAAO,CAAC,CAAC,aAAa,CAAC,CACvB,OAAO,CAAC,CAAC,GAAG,EAAE;gBACZ,KAAK,QAAQ,EAAE,CAAC;YAClB,CAAC,CAAC,CACF,IAAI,CAAC,GAAG,CACR,IAAI,CAAC,SAAS,CAEd;cAAA,CAAC,WAAW,CACd;YAAA,EAAE,MAAM,CACV;UAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,SACN,CAAC,CACD,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,SAAS,CAAC,CACpB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,EACf,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Button } from '../../components/button';\nimport { Form, type FormFieldConfig, type FormValues } from '../../components/form';\nimport type { OtpFormProps } from './types';\n\ntype OtpFieldName = 'otp';\n\nexport function OtpForm({\n length = 6,\n otpLabel = 'Code',\n resendLabel = 'Resend code',\n resendDisabled = false,\n resendLoading = false,\n loading = false,\n disabled = false,\n error,\n submitLabel = 'Verify code',\n onSubmit,\n onResend,\n testID,\n}: OtpFormProps) {\n const resolvedLength = Math.max(1, length);\n const [values, setValues] = React.useState<FormValues<OtpFieldName>>({\n otp: '',\n });\n const fields = React.useMemo<readonly FormFieldConfig<OtpFieldName>[]>(\n () => [\n {\n name: 'otp',\n label: otpLabel,\n type: 'otp',\n maxLength: resolvedLength,\n rules: [{ kind: 'required' }, { kind: 'minLength', value: resolvedLength }],\n },\n ],\n [otpLabel, resolvedLength],\n );\n\n const handleSubmit = React.useCallback(\n (formValues: FormValues<OtpFieldName>) =>\n onSubmit({\n otp: formValues.otp.trim(),\n }),\n [onSubmit],\n );\n\n return (\n <Form\n actions={\n onResend ? (\n <Stack direction=\"row\" gap=\"s\" wrap=\"wrap\">\n <Button\n disabled={disabled || loading || resendDisabled}\n emphasis=\"ghost\"\n loading={resendLoading}\n onPress={() => {\n void onResend();\n }}\n size=\"s\"\n tone=\"neutral\"\n >\n {resendLabel}\n </Button>\n </Stack>\n ) : undefined\n }\n disabled={disabled}\n error={error}\n fields={fields}\n loading={loading}\n onChange={setValues}\n onSubmit={handleSubmit}\n submitLabel={submitLabel}\n testID={testID}\n values={values}\n />\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { SignInFormProps } from './types';
3
+ export declare function SignInForm({ identifiers, identifierLabel, secretLabel, forgotPasswordLabel, signUpLabel, loading, disabled, error, submitLabel, onSubmit, onForgotPassword, onSignUp, testID, }: SignInFormProps): React.JSX.Element;
4
+ //# sourceMappingURL=SignInForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignInForm.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/SignInForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAW/C,wBAAgB,UAAU,CAAC,EACzB,WAAgC,EAChC,eAAe,EACf,WAAwB,EACxB,mBAAuC,EACvC,WAAuB,EACvB,OAAe,EACf,QAAgB,EAChB,KAAK,EACL,WAAuB,EACvB,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,MAAM,GACP,EAAE,eAAe,qBAgFjB"}
@@ -0,0 +1,45 @@
1
+ import { Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+ import { Button } from '../../components/button';
4
+ import { Form } from '../../components/form';
5
+ import { defaultIdentifiers, normalizeIdentifierKind, resolveIdentifierLabel, resolveIdentifierRules, resolveIdentifierType, } from './utils';
6
+ export function SignInForm({ identifiers = defaultIdentifiers, identifierLabel, secretLabel = 'Password', forgotPasswordLabel = 'Forgot password', signUpLabel = 'Sign up', loading = false, disabled = false, error, submitLabel = 'Sign in', onSubmit, onForgotPassword, onSignUp, testID, }) {
7
+ const [values, setValues] = React.useState({
8
+ identifier: '',
9
+ secret: '',
10
+ });
11
+ const hasActions = Boolean(onForgotPassword ?? onSignUp);
12
+ const fields = React.useMemo(() => [
13
+ {
14
+ name: 'identifier',
15
+ label: identifierLabel ?? resolveIdentifierLabel(identifiers),
16
+ type: resolveIdentifierType(identifiers),
17
+ autoCapitalize: 'none',
18
+ rules: resolveIdentifierRules(identifiers),
19
+ },
20
+ {
21
+ name: 'secret',
22
+ label: secretLabel,
23
+ type: 'password',
24
+ rules: [{ kind: 'required' }],
25
+ },
26
+ ], [identifierLabel, identifiers, secretLabel]);
27
+ const handleSubmit = React.useCallback((formValues) => onSubmit({
28
+ identifier: formValues.identifier.trim(),
29
+ identifierKind: normalizeIdentifierKind(formValues.identifier, identifiers),
30
+ secret: formValues.secret,
31
+ }), [identifiers, onSubmit]);
32
+ return (<Form actions={hasActions ? (<Stack direction="row" gap="s" wrap="wrap">
33
+ {onForgotPassword ? (<Button disabled={disabled || loading} emphasis="ghost" onPress={() => {
34
+ void onForgotPassword();
35
+ }} size="s" tone="neutral">
36
+ {forgotPasswordLabel}
37
+ </Button>) : null}
38
+ {onSignUp ? (<Button disabled={disabled || loading} emphasis="ghost" onPress={() => {
39
+ void onSignUp();
40
+ }} size="s" tone="neutral">
41
+ {signUpLabel}
42
+ </Button>) : null}
43
+ </Stack>) : undefined} disabled={disabled} error={error} fields={fields} loading={loading} onChange={setValues} onSubmit={handleSubmit} submitLabel={submitLabel} testID={testID} values={values}/>);
44
+ }
45
+ //# sourceMappingURL=SignInForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignInForm.js","sourceRoot":"","sources":["../../../src/patterns/auth/SignInForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAyC,MAAM,uBAAuB,CAAC;AAEpF,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,MAAM,UAAU,UAAU,CAAC,EACzB,WAAW,GAAG,kBAAkB,EAChC,eAAe,EACf,WAAW,GAAG,UAAU,EACxB,mBAAmB,GAAG,iBAAiB,EACvC,WAAW,GAAG,SAAS,EACvB,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,WAAW,GAAG,SAAS,EACvB,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,MAAM,GACU;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAA8B;QACtE,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,IAAI,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC;QACJ;YACE,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,eAAe,IAAI,sBAAsB,CAAC,WAAW,CAAC;YAC7D,IAAI,EAAE,qBAAqB,CAAC,WAAW,CAAC;YACxC,cAAc,EAAE,MAAM;YACtB,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC;SAC3C;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;SAC9B;KACF,EACD,CAAC,eAAe,EAAE,WAAW,EAAE,WAAW,CAAC,CAC5C,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,UAAuC,EAAE,EAAE,CAC1C,QAAQ,CAAC;QACP,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE;QACxC,cAAc,EAAE,uBAAuB,CAAC,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC;QAC3E,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC,EACJ,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxB,CAAC;IAEF,OAAO,CACL,CAAC,IAAI,CACH,OAAO,CAAC,CACN,UAAU,CAAC,CAAC,CAAC,CACX,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CACxC;YAAA,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAClB,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAC9B,QAAQ,CAAC,OAAO,CAChB,OAAO,CAAC,CAAC,GAAG,EAAE;oBACZ,KAAK,gBAAgB,EAAE,CAAC;gBAC1B,CAAC,CAAC,CACF,IAAI,CAAC,GAAG,CACR,IAAI,CAAC,SAAS,CAEd;gBAAA,CAAC,mBAAmB,CACtB;cAAA,EAAE,MAAM,CAAC,CACV,CAAC,CAAC,CAAC,IAAI,CACR;YAAA,CAAC,QAAQ,CAAC,CAAC,CAAC,CACV,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAC9B,QAAQ,CAAC,OAAO,CAChB,OAAO,CAAC,CAAC,GAAG,EAAE;oBACZ,KAAK,QAAQ,EAAE,CAAC;gBAClB,CAAC,CAAC,CACF,IAAI,CAAC,GAAG,CACR,IAAI,CAAC,SAAS,CAEd;gBAAA,CAAC,WAAW,CACd;cAAA,EAAE,MAAM,CAAC,CACV,CAAC,CAAC,CAAC,IAAI,CACV;UAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,SACN,CAAC,CACD,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,SAAS,CAAC,CACpB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,EACf,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Button } from '../../components/button';\nimport { Form, type FormFieldConfig, type FormValues } from '../../components/form';\nimport type { SignInFormProps } from './types';\nimport {\n defaultIdentifiers,\n normalizeIdentifierKind,\n resolveIdentifierLabel,\n resolveIdentifierRules,\n resolveIdentifierType,\n} from './utils';\n\ntype SignInFieldName = 'identifier' | 'secret';\n\nexport function SignInForm({\n identifiers = defaultIdentifiers,\n identifierLabel,\n secretLabel = 'Password',\n forgotPasswordLabel = 'Forgot password',\n signUpLabel = 'Sign up',\n loading = false,\n disabled = false,\n error,\n submitLabel = 'Sign in',\n onSubmit,\n onForgotPassword,\n onSignUp,\n testID,\n}: SignInFormProps) {\n const [values, setValues] = React.useState<FormValues<SignInFieldName>>({\n identifier: '',\n secret: '',\n });\n const hasActions = Boolean(onForgotPassword ?? onSignUp);\n const fields = React.useMemo<readonly FormFieldConfig<SignInFieldName>[]>(\n () => [\n {\n name: 'identifier',\n label: identifierLabel ?? resolveIdentifierLabel(identifiers),\n type: resolveIdentifierType(identifiers),\n autoCapitalize: 'none',\n rules: resolveIdentifierRules(identifiers),\n },\n {\n name: 'secret',\n label: secretLabel,\n type: 'password',\n rules: [{ kind: 'required' }],\n },\n ],\n [identifierLabel, identifiers, secretLabel],\n );\n\n const handleSubmit = React.useCallback(\n (formValues: FormValues<SignInFieldName>) =>\n onSubmit({\n identifier: formValues.identifier.trim(),\n identifierKind: normalizeIdentifierKind(formValues.identifier, identifiers),\n secret: formValues.secret,\n }),\n [identifiers, onSubmit],\n );\n\n return (\n <Form\n actions={\n hasActions ? (\n <Stack direction=\"row\" gap=\"s\" wrap=\"wrap\">\n {onForgotPassword ? (\n <Button\n disabled={disabled || loading}\n emphasis=\"ghost\"\n onPress={() => {\n void onForgotPassword();\n }}\n size=\"s\"\n tone=\"neutral\"\n >\n {forgotPasswordLabel}\n </Button>\n ) : null}\n {onSignUp ? (\n <Button\n disabled={disabled || loading}\n emphasis=\"ghost\"\n onPress={() => {\n void onSignUp();\n }}\n size=\"s\"\n tone=\"neutral\"\n >\n {signUpLabel}\n </Button>\n ) : null}\n </Stack>\n ) : undefined\n }\n disabled={disabled}\n error={error}\n fields={fields}\n loading={loading}\n onChange={setValues}\n onSubmit={handleSubmit}\n submitLabel={submitLabel}\n testID={testID}\n values={values}\n />\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { SignUpFormProps } from './types';
3
+ export declare function SignUpForm({ fields, signInLabel, loading, disabled, error, submitLabel, onSubmit, onSignIn, testID, }: SignUpFormProps): React.JSX.Element;
4
+ //# sourceMappingURL=SignUpForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignUpForm.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/SignUpForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2B/C,wBAAgB,UAAU,CAAC,EACzB,MAA4B,EAC5B,WAAuB,EACvB,OAAe,EACf,QAAgB,EAChB,KAAK,EACL,WAAuB,EACvB,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,eAAe,qBAiCjB"}
@@ -0,0 +1,37 @@
1
+ import { Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+ import { Button } from '../../components/button';
4
+ import { Form } from '../../components/form';
5
+ const defaultSignUpFields = [
6
+ {
7
+ name: 'email',
8
+ label: 'Email',
9
+ type: 'email',
10
+ autoCapitalize: 'none',
11
+ rules: [{ kind: 'required' }, { kind: 'email' }],
12
+ },
13
+ {
14
+ name: 'password',
15
+ label: 'Password',
16
+ type: 'password',
17
+ rules: [{ kind: 'required' }, { kind: 'minLength', value: 8 }],
18
+ },
19
+ ];
20
+ function createValues(fields) {
21
+ const values = fields.reduce((nextValues, field) => {
22
+ nextValues[field.name] = '';
23
+ return nextValues;
24
+ }, {});
25
+ return values;
26
+ }
27
+ export function SignUpForm({ fields = defaultSignUpFields, signInLabel = 'Sign in', loading = false, disabled = false, error, submitLabel = 'Sign up', onSubmit, onSignIn, testID, }) {
28
+ const [values, setValues] = React.useState(() => createValues(fields));
29
+ return (<Form actions={onSignIn ? (<Stack direction="row" gap="s" wrap="wrap">
30
+ <Button disabled={disabled || loading} emphasis="ghost" onPress={() => {
31
+ void onSignIn();
32
+ }} size="s" tone="neutral">
33
+ {signInLabel}
34
+ </Button>
35
+ </Stack>) : undefined} disabled={disabled} error={error} fields={fields} loading={loading} onChange={setValues} onSubmit={onSubmit} submitLabel={submitLabel} testID={testID} values={values}/>);
36
+ }
37
+ //# sourceMappingURL=SignUpForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignUpForm.js","sourceRoot":"","sources":["../../../src/patterns/auth/SignUpForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAyC,MAAM,uBAAuB,CAAC;AAGpF,MAAM,mBAAmB,GAAG;IAC1B;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,OAAO;QACb,cAAc,EAAE,MAAM;QACtB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KACjD;IACD;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;KAC/D;CAC4C,CAAC;AAEhD,SAAS,YAAY,CAAC,MAAkC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAyB,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;QACzE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,GAAG,mBAAmB,EAC5B,WAAW,GAAG,SAAS,EACvB,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,WAAW,GAAG,SAAS,EACvB,QAAQ,EACR,QAAQ,EACR,MAAM,GACU;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAa,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnF,OAAO,CACL,CAAC,IAAI,CACH,OAAO,CAAC,CACN,QAAQ,CAAC,CAAC,CAAC,CACT,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CACxC;YAAA,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAC9B,QAAQ,CAAC,OAAO,CAChB,OAAO,CAAC,CAAC,GAAG,EAAE;gBACZ,KAAK,QAAQ,EAAE,CAAC;YAClB,CAAC,CAAC,CACF,IAAI,CAAC,GAAG,CACR,IAAI,CAAC,SAAS,CAEd;cAAA,CAAC,WAAW,CACd;YAAA,EAAE,MAAM,CACV;UAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,SACN,CAAC,CACD,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,SAAS,CAAC,CACpB,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,EACf,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Button } from '../../components/button';\nimport { Form, type FormFieldConfig, type FormValues } from '../../components/form';\nimport type { SignUpFormProps } from './types';\n\nconst defaultSignUpFields = [\n {\n name: 'email',\n label: 'Email',\n type: 'email',\n autoCapitalize: 'none',\n rules: [{ kind: 'required' }, { kind: 'email' }],\n },\n {\n name: 'password',\n label: 'Password',\n type: 'password',\n rules: [{ kind: 'required' }, { kind: 'minLength', value: 8 }],\n },\n] as const satisfies readonly FormFieldConfig[];\n\nfunction createValues(fields: readonly FormFieldConfig[]): FormValues {\n const values = fields.reduce<Record<string, string>>((nextValues, field) => {\n nextValues[field.name] = '';\n return nextValues;\n }, {});\n\n return values;\n}\n\nexport function SignUpForm({\n fields = defaultSignUpFields,\n signInLabel = 'Sign in',\n loading = false,\n disabled = false,\n error,\n submitLabel = 'Sign up',\n onSubmit,\n onSignIn,\n testID,\n}: SignUpFormProps) {\n const [values, setValues] = React.useState<FormValues>(() => createValues(fields));\n\n return (\n <Form\n actions={\n onSignIn ? (\n <Stack direction=\"row\" gap=\"s\" wrap=\"wrap\">\n <Button\n disabled={disabled || loading}\n emphasis=\"ghost\"\n onPress={() => {\n void onSignIn();\n }}\n size=\"s\"\n tone=\"neutral\"\n >\n {signInLabel}\n </Button>\n </Stack>\n ) : undefined\n }\n disabled={disabled}\n error={error}\n fields={fields}\n loading={loading}\n onChange={setValues}\n onSubmit={onSubmit}\n submitLabel={submitLabel}\n testID={testID}\n values={values}\n />\n );\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { ForgotPasswordForm } from './ForgotPasswordForm';
2
+ export { OtpForm } from './OtpForm';
3
+ export { SignInForm } from './SignInForm';
4
+ export { SignUpForm } from './SignUpForm';
5
+ export type { AuthFormBaseProps, AuthIdentifierKind, ForgotPasswordFormProps, ForgotPasswordFormValues, OtpFormProps, OtpFormValues, SignInFormProps, SignInFormValues, SignUpFormField, SignUpFormProps, SignUpFormValues, } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { ForgotPasswordForm } from './ForgotPasswordForm';
2
+ export { OtpForm } from './OtpForm';
3
+ export { SignInForm } from './SignInForm';
4
+ export { SignUpForm } from './SignUpForm';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export { ForgotPasswordForm } from './ForgotPasswordForm';\nexport { OtpForm } from './OtpForm';\nexport { SignInForm } from './SignInForm';\nexport { SignUpForm } from './SignUpForm';\nexport type {\n AuthFormBaseProps,\n AuthIdentifierKind,\n ForgotPasswordFormProps,\n ForgotPasswordFormValues,\n OtpFormProps,\n OtpFormValues,\n SignInFormProps,\n SignInFormValues,\n SignUpFormField,\n SignUpFormProps,\n SignUpFormValues,\n} from './types';\n"]}
@@ -0,0 +1,57 @@
1
+ import type React from 'react';
2
+ import type { FormFieldConfig, FormValues } from '../../components/form';
3
+ export type AuthIdentifierKind = 'email' | 'phone' | 'username';
4
+ export interface AuthFormBaseProps {
5
+ loading?: boolean;
6
+ disabled?: boolean;
7
+ error?: React.ReactNode;
8
+ submitLabel?: React.ReactNode;
9
+ testID?: string;
10
+ }
11
+ export interface SignInFormValues {
12
+ identifier: string;
13
+ identifierKind: AuthIdentifierKind;
14
+ secret: string;
15
+ }
16
+ export interface SignInFormProps extends AuthFormBaseProps {
17
+ identifiers?: readonly AuthIdentifierKind[];
18
+ identifierLabel?: React.ReactNode;
19
+ secretLabel?: React.ReactNode;
20
+ forgotPasswordLabel?: React.ReactNode;
21
+ signUpLabel?: React.ReactNode;
22
+ onSubmit: (values: SignInFormValues) => void | Promise<void>;
23
+ onForgotPassword?: () => void | Promise<void>;
24
+ onSignUp?: () => void | Promise<void>;
25
+ }
26
+ export type SignUpFormValues = FormValues;
27
+ export type SignUpFormField = FormFieldConfig;
28
+ export interface SignUpFormProps extends AuthFormBaseProps {
29
+ fields?: readonly SignUpFormField[];
30
+ signInLabel?: React.ReactNode;
31
+ onSubmit: (values: SignUpFormValues) => void | Promise<void>;
32
+ onSignIn?: () => void | Promise<void>;
33
+ }
34
+ export interface ForgotPasswordFormValues {
35
+ identifier: string;
36
+ identifierKind: AuthIdentifierKind;
37
+ }
38
+ export interface ForgotPasswordFormProps extends AuthFormBaseProps {
39
+ identifiers?: readonly AuthIdentifierKind[];
40
+ identifierLabel?: React.ReactNode;
41
+ signInLabel?: React.ReactNode;
42
+ onSubmit: (values: ForgotPasswordFormValues) => void | Promise<void>;
43
+ onSignIn?: () => void | Promise<void>;
44
+ }
45
+ export interface OtpFormValues {
46
+ otp: string;
47
+ }
48
+ export interface OtpFormProps extends AuthFormBaseProps {
49
+ length?: number;
50
+ otpLabel?: React.ReactNode;
51
+ resendLabel?: React.ReactNode;
52
+ resendDisabled?: boolean;
53
+ resendLoading?: boolean;
54
+ onSubmit: (values: OtpFormValues) => void | Promise<void>;
55
+ onResend?: () => void | Promise<void>;
56
+ }
57
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { FormFieldConfig, FormValues } from '../../components/form';\n\nexport type AuthIdentifierKind = 'email' | 'phone' | 'username';\n\nexport interface AuthFormBaseProps {\n loading?: boolean;\n disabled?: boolean;\n error?: React.ReactNode;\n submitLabel?: React.ReactNode;\n testID?: string;\n}\n\nexport interface SignInFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n secret: string;\n}\n\nexport interface SignInFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n secretLabel?: React.ReactNode;\n forgotPasswordLabel?: React.ReactNode;\n signUpLabel?: React.ReactNode;\n onSubmit: (values: SignInFormValues) => void | Promise<void>;\n onForgotPassword?: () => void | Promise<void>;\n onSignUp?: () => void | Promise<void>;\n}\n\nexport type SignUpFormValues = FormValues;\nexport type SignUpFormField = FormFieldConfig;\n\nexport interface SignUpFormProps extends AuthFormBaseProps {\n fields?: readonly SignUpFormField[];\n signInLabel?: React.ReactNode;\n onSubmit: (values: SignUpFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface ForgotPasswordFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n}\n\nexport interface ForgotPasswordFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n signInLabel?: React.ReactNode;\n onSubmit: (values: ForgotPasswordFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface OtpFormValues {\n otp: string;\n}\n\nexport interface OtpFormProps extends AuthFormBaseProps {\n length?: number;\n otpLabel?: React.ReactNode;\n resendLabel?: React.ReactNode;\n resendDisabled?: boolean;\n resendLoading?: boolean;\n onSubmit: (values: OtpFormValues) => void | Promise<void>;\n onResend?: () => void | Promise<void>;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { FormFieldConfig, ValidationRule } from '../../components/form';
2
+ import type { AuthIdentifierKind } from './types';
3
+ export declare const defaultIdentifiers: readonly ["email"];
4
+ export declare function resolveIdentifierLabel(identifiers: readonly AuthIdentifierKind[]): string;
5
+ export declare function resolveIdentifierType(identifiers: readonly AuthIdentifierKind[]): FormFieldConfig['type'];
6
+ export declare function resolveIdentifierRules(identifiers: readonly AuthIdentifierKind[]): readonly ValidationRule[];
7
+ export declare function normalizeIdentifierKind(identifier: string, identifiers: readonly AuthIdentifierKind[]): AuthIdentifierKind;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,eAAO,MAAM,kBAAkB,oBAA6D,CAAC;AAe7F,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,GAAG,MAAM,CAMzF;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACzC,eAAe,CAAC,MAAM,CAAC,CAgBzB;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACzC,SAAS,cAAc,EAAE,CAM3B;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACzC,kBAAkB,CAoBpB"}
@@ -0,0 +1,51 @@
1
+ export const defaultIdentifiers = ['email'];
2
+ const identifierLabels = {
3
+ email: 'Email',
4
+ phone: 'Phone',
5
+ username: 'Username',
6
+ };
7
+ function includesIdentifier(identifiers, identifier) {
8
+ return identifiers.includes(identifier);
9
+ }
10
+ export function resolveIdentifierLabel(identifiers) {
11
+ if (identifiers.length === 1) {
12
+ return identifierLabels[identifiers[0] ?? 'email'];
13
+ }
14
+ return identifiers.map((identifier) => identifierLabels[identifier]).join(', or ');
15
+ }
16
+ export function resolveIdentifierType(identifiers) {
17
+ if (identifiers.length !== 1) {
18
+ return 'text';
19
+ }
20
+ const [identifier] = identifiers;
21
+ if (identifier === 'email') {
22
+ return 'email';
23
+ }
24
+ if (identifier === 'phone') {
25
+ return 'tel';
26
+ }
27
+ return 'text';
28
+ }
29
+ export function resolveIdentifierRules(identifiers) {
30
+ if (identifiers.length === 1 && identifiers[0] === 'email') {
31
+ return [{ kind: 'required' }, { kind: 'email' }];
32
+ }
33
+ return [{ kind: 'required' }];
34
+ }
35
+ export function normalizeIdentifierKind(identifier, identifiers) {
36
+ const normalizedIdentifier = identifier.trim();
37
+ if (identifiers.length === 1) {
38
+ return identifiers[0] ?? 'email';
39
+ }
40
+ if (includesIdentifier(identifiers, 'email') && normalizedIdentifier.includes('@')) {
41
+ return 'email';
42
+ }
43
+ if (includesIdentifier(identifiers, 'phone') && /^[+()\d\s.-]+$/.test(normalizedIdentifier)) {
44
+ return 'phone';
45
+ }
46
+ if (includesIdentifier(identifiers, 'username')) {
47
+ return 'username';
48
+ }
49
+ return identifiers[0] ?? 'email';
50
+ }
51
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/patterns/auth/utils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAkD,CAAC;AAE7F,MAAM,gBAAgB,GAAuC;IAC3D,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;CACrB,CAAC;AAEF,SAAS,kBAAkB,CACzB,WAA0C,EAC1C,UAA8B;IAE9B,OAAO,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAA0C;IAC/E,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,WAA0C;IAE1C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC;IAEjC,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,WAA0C;IAE1C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC3D,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,WAA0C;IAE1C,MAAM,oBAAoB,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAE/C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACnC,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC5F,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;QAChD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;AACnC,CAAC","sourcesContent":["import type { FormFieldConfig, ValidationRule } from '../../components/form';\nimport type { AuthIdentifierKind } from './types';\n\nexport const defaultIdentifiers = ['email'] as const satisfies readonly AuthIdentifierKind[];\n\nconst identifierLabels: Record<AuthIdentifierKind, string> = {\n email: 'Email',\n phone: 'Phone',\n username: 'Username',\n};\n\nfunction includesIdentifier(\n identifiers: readonly AuthIdentifierKind[],\n identifier: AuthIdentifierKind,\n): boolean {\n return identifiers.includes(identifier);\n}\n\nexport function resolveIdentifierLabel(identifiers: readonly AuthIdentifierKind[]): string {\n if (identifiers.length === 1) {\n return identifierLabels[identifiers[0] ?? 'email'];\n }\n\n return identifiers.map((identifier) => identifierLabels[identifier]).join(', or ');\n}\n\nexport function resolveIdentifierType(\n identifiers: readonly AuthIdentifierKind[],\n): FormFieldConfig['type'] {\n if (identifiers.length !== 1) {\n return 'text';\n }\n\n const [identifier] = identifiers;\n\n if (identifier === 'email') {\n return 'email';\n }\n\n if (identifier === 'phone') {\n return 'tel';\n }\n\n return 'text';\n}\n\nexport function resolveIdentifierRules(\n identifiers: readonly AuthIdentifierKind[],\n): readonly ValidationRule[] {\n if (identifiers.length === 1 && identifiers[0] === 'email') {\n return [{ kind: 'required' }, { kind: 'email' }];\n }\n\n return [{ kind: 'required' }];\n}\n\nexport function normalizeIdentifierKind(\n identifier: string,\n identifiers: readonly AuthIdentifierKind[],\n): AuthIdentifierKind {\n const normalizedIdentifier = identifier.trim();\n\n if (identifiers.length === 1) {\n return identifiers[0] ?? 'email';\n }\n\n if (includesIdentifier(identifiers, 'email') && normalizedIdentifier.includes('@')) {\n return 'email';\n }\n\n if (includesIdentifier(identifiers, 'phone') && /^[+()\\d\\s.-]+$/.test(normalizedIdentifier)) {\n return 'phone';\n }\n\n if (includesIdentifier(identifiers, 'username')) {\n return 'username';\n }\n\n return identifiers[0] ?? 'email';\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "0.5.3",
4
+ "version": "0.6.1",
5
5
  "description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
6
6
  "homepage": "https://github.com/ankhorage/zora#readme",
7
7
  "bugs": {
@@ -43,7 +43,7 @@
43
43
  }
44
44
  },
45
45
  "dependencies": {
46
- "@ankhorage/surface": "^0.1.10"
46
+ "@ankhorage/surface": "^0.1.11"
47
47
  },
48
48
  "files": [
49
49
  "dist",
@@ -0,0 +1,61 @@
1
+ import { Box, Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import { FormActions } from './FormActions';
5
+ import { FormError } from './FormError';
6
+ import { FormField } from './FormField';
7
+ import type { FormProps } from './types';
8
+ import { useFormController } from './useFormController';
9
+
10
+ export function Form<TName extends string = string>({
11
+ fields,
12
+ values,
13
+ onChange,
14
+ onSubmit,
15
+ errors,
16
+ error,
17
+ loading = false,
18
+ disabled = false,
19
+ submitLabel = 'Submit',
20
+ actions,
21
+ footer,
22
+ validateOnChange = false,
23
+ testID,
24
+ }: FormProps<TName>) {
25
+ const controller = useFormController({
26
+ fields,
27
+ values,
28
+ errors,
29
+ onChange,
30
+ onSubmit,
31
+ validateOnChange,
32
+ });
33
+
34
+ return (
35
+ <Stack gap="m" testID={testID}>
36
+ <FormError error={error} />
37
+ {fields.map((field) => (
38
+ <FormField
39
+ key={field.name}
40
+ disabled={disabled}
41
+ error={controller.errors[field.name]}
42
+ field={field}
43
+ loading={loading}
44
+ onChange={controller.setFieldValue}
45
+ value={values[field.name]}
46
+ />
47
+ ))}
48
+ <FormActions
49
+ disabled={disabled}
50
+ loading={loading}
51
+ onSubmit={() => {
52
+ void controller.handleSubmit();
53
+ }}
54
+ submitLabel={submitLabel}
55
+ >
56
+ {actions}
57
+ </FormActions>
58
+ {footer ? <Box>{footer}</Box> : null}
59
+ </Stack>
60
+ );
61
+ }
@@ -0,0 +1,23 @@
1
+ import { Box, Stack } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import { Button } from '../button';
5
+ import type { FormActionsProps } from './types';
6
+
7
+ export function FormActions({
8
+ submitLabel = 'Submit',
9
+ loading = false,
10
+ disabled = false,
11
+ onSubmit,
12
+ children,
13
+ testID,
14
+ }: FormActionsProps) {
15
+ return (
16
+ <Stack gap="s" testID={testID}>
17
+ <Button disabled={disabled} fullWidth loading={loading} onPress={onSubmit}>
18
+ {submitLabel}
19
+ </Button>
20
+ {children ? <Box>{children}</Box> : null}
21
+ </Stack>
22
+ );
23
+ }
@@ -0,0 +1,20 @@
1
+ import { Box, Text, useTheme } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import type { FormErrorProps } from './types';
5
+
6
+ export function FormError({ error, testID }: FormErrorProps) {
7
+ const { theme } = useTheme();
8
+
9
+ if (!error) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <Box borderColor={theme.colors.error} borderWidth={1} p="s" radius="m" testID={testID}>
15
+ <Text color={theme.colors.error} variant="bodySmall">
16
+ {error}
17
+ </Text>
18
+ </Box>
19
+ );
20
+ }