@sikka/hawa 0.0.288 → 0.1.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 (40) hide show
  1. package/dist/styles.css +182 -89
  2. package/es/blocks/AuthForms/SignInBlock.d.ts +2 -0
  3. package/es/blocks/AuthForms/SignInForm.d.ts +1 -1
  4. package/es/blocks/AuthForms/index.d.ts +1 -0
  5. package/es/elements/Button.d.ts +12 -0
  6. package/es/elements/Card.d.ts +10 -0
  7. package/es/elements/Icons.d.ts +19 -0
  8. package/es/elements/Input.d.ts +5 -0
  9. package/es/elements/Label.d.ts +5 -0
  10. package/es/index.es.js +3 -3
  11. package/es/util.d.ts +2 -0
  12. package/lib/blocks/AuthForms/SignInBlock.d.ts +2 -0
  13. package/lib/blocks/AuthForms/SignInForm.d.ts +1 -1
  14. package/lib/blocks/AuthForms/index.d.ts +1 -0
  15. package/lib/elements/Button.d.ts +12 -0
  16. package/lib/elements/Card.d.ts +10 -0
  17. package/lib/elements/Icons.d.ts +19 -0
  18. package/lib/elements/Input.d.ts +5 -0
  19. package/lib/elements/Label.d.ts +5 -0
  20. package/lib/index.js +3 -3
  21. package/lib/util.d.ts +2 -0
  22. package/package.json +5 -2
  23. package/src/blocks/AuthForms/ResetPasswordForm.tsx +59 -49
  24. package/src/blocks/AuthForms/SignInBlock.tsx +60 -0
  25. package/src/blocks/AuthForms/SignInForm.tsx +139 -128
  26. package/src/blocks/AuthForms/SignUpForm.tsx +237 -225
  27. package/src/blocks/AuthForms/index.ts +8 -7
  28. package/src/elements/Button.tsx +77 -0
  29. package/src/elements/Card.tsx +87 -0
  30. package/src/elements/HawaLoading.tsx +4 -4
  31. package/src/elements/HawaTextField.tsx +9 -7
  32. package/src/elements/Icons.tsx +145 -0
  33. package/src/elements/Input.tsx +25 -0
  34. package/src/elements/Label.tsx +26 -0
  35. package/src/styles.css +182 -89
  36. package/src/tailwind.css +22 -22
  37. package/src/translations/ar.json +1 -0
  38. package/src/translations/en.json +1 -0
  39. package/src/util.ts +10 -4
  40. package/tailwind.config.js +39 -3
package/lib/util.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
1
3
  type Palette = {
2
4
  name: string;
3
5
  colors: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sikka/hawa",
3
- "version": "0.0.288",
3
+ "version": "0.1.1",
4
4
  "description": "SaaS Oriented UI Kit",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.es.js",
@@ -106,6 +106,8 @@
106
106
  },
107
107
  "dependencies": {
108
108
  "@radix-ui/react-dropdown-menu": "^2.0.5",
109
+ "@radix-ui/react-label": "^2.0.2",
110
+ "class-variance-authority": "^0.7.0",
109
111
  "clsx": "^1.2.1",
110
112
  "cmdk": "^0.2.0",
111
113
  "react": "^18.2.0",
@@ -114,7 +116,8 @@
114
116
  "react-icons": "^4.10.1",
115
117
  "react-select": "^5.3.2",
116
118
  "slate": "^0.94.1",
117
- "slate-react": "^0.97.1"
119
+ "slate-react": "^0.97.1",
120
+ "tailwind-merge": "^1.14.0"
118
121
  },
119
122
  "readme": "ERROR: No README data found!",
120
123
  "_id": "@sikka/hawa@0.0.285"
@@ -1,7 +1,14 @@
1
1
  import React, { FC } from "react"
2
2
  import { Controller, useForm } from "react-hook-form"
3
- import { HawaButton, HawaTextField } from "../../elements"
4
- import { HawaContainer } from "../../layout"
3
+ import { HawaTextField } from "../../elements"
4
+ import {
5
+ Card,
6
+ CardContent,
7
+ CardDescription,
8
+ CardHeader,
9
+ CardTitle,
10
+ } from "../../elements/Card"
11
+ import { Button } from "../../elements/Button"
5
12
 
6
13
  type ResetPasswordType = {
7
14
  handleResetPassword: () => void
@@ -28,52 +35,55 @@ export const ResetPasswordForm: FC<ResetPasswordType> = (props) => {
28
35
  control,
29
36
  } = methods
30
37
  return (
31
- <HawaContainer>
32
- {!props.sent ? (
33
- <form onSubmit={handleSubmit(props.handleResetPassword)}>
34
- <Controller
35
- control={control}
36
- name="email"
37
- render={({ field }) => (
38
- <HawaTextField
39
- width="full"
40
- type="text"
41
- label={props.texts.emailLabel}
42
- helpertext={errors.email?.message}
43
- placeholder={props.texts.emailPlaceholder}
44
- {...field}
45
- value={field.value ?? ""}
46
- />
47
- )}
48
- rules={{
49
- required: props.texts.emailRequiredText,
50
- pattern: {
51
- value:
52
- /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
53
- message: props.texts.emailInvalidText,
54
- },
55
- }}
56
- />
57
- <div className=" pb-2 text-left text-sm dark:text-gray-300">
58
- {props.texts.dontHaveAccount ?? "Don't have an account? "}
59
- <span
60
- onClick={props.handleRouteToSignUp}
61
- className="cursor-pointer text-blue-600 dark:text-blue-400"
62
- >
63
- {props.texts.signUpText ?? "Sign Up"}
64
- </span>
65
- </div>
66
- <HawaButton
67
- color="primary"
68
- width="full"
69
- // type="submit"
70
- >
71
- {props.texts.resetPassword}
72
- </HawaButton>
73
- </form>
74
- ) : (
75
- <div className="text-center">{props.texts.emailSentText}</div>
76
- )}
77
- </HawaContainer>
38
+ <Card>
39
+ <CardHeader>
40
+ <CardTitle>Reset Password</CardTitle>
41
+ <CardDescription>
42
+ Enter your email to reset your account password
43
+ </CardDescription>
44
+ </CardHeader>
45
+ <CardContent>
46
+ {!props.sent ? (
47
+ <form onSubmit={handleSubmit(props.handleResetPassword)}>
48
+ <Controller
49
+ control={control}
50
+ name="email"
51
+ render={({ field }) => (
52
+ <HawaTextField
53
+ width="full"
54
+ type="text"
55
+ label={props.texts.emailLabel}
56
+ helpertext={errors.email?.message}
57
+ placeholder={props.texts.emailPlaceholder}
58
+ {...field}
59
+ value={field.value ?? ""}
60
+ />
61
+ )}
62
+ rules={{
63
+ required: props.texts.emailRequiredText,
64
+ pattern: {
65
+ value:
66
+ /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
67
+ message: props.texts.emailInvalidText,
68
+ },
69
+ }}
70
+ />
71
+ <div className=" pb-2 text-left text-sm dark:text-gray-300">
72
+ {props.texts.dontHaveAccount ?? "Don't have an account? "}
73
+ <span
74
+ onClick={props.handleRouteToSignUp}
75
+ className="cursor-pointer text-blue-600 dark:text-blue-400"
76
+ >
77
+ {props.texts.signUpText ?? "Sign Up"}
78
+ </span>
79
+ </div>
80
+
81
+ <Button className="w-full">{props.texts.resetPassword}</Button>
82
+ </form>
83
+ ) : (
84
+ <div className="text-center">{props.texts.emailSentText}</div>
85
+ )}
86
+ </CardContent>
87
+ </Card>
78
88
  )
79
89
  }
@@ -0,0 +1,60 @@
1
+ "use client"
2
+
3
+ import { Icons } from "../../elements/Icons"
4
+ import { Button } from "../../elements/Button"
5
+ import {
6
+ Card,
7
+ CardContent,
8
+ CardDescription,
9
+ CardFooter,
10
+ CardHeader,
11
+ CardTitle,
12
+ } from "../../elements/Card"
13
+ import { Input } from "../../elements/Input"
14
+ import { Label } from "../../elements/Label"
15
+
16
+ export function SignInBlock() {
17
+ return (
18
+ <Card>
19
+ <CardHeader className="space-y-1">
20
+ <CardTitle className="text-2xl">Create an account</CardTitle>
21
+ <CardDescription>
22
+ Enter your email below to create your account
23
+ </CardDescription>
24
+ </CardHeader>
25
+ <CardContent className="grid gap-4">
26
+ <div className="grid grid-cols-2 gap-6">
27
+ <Button variant="outline">
28
+ <Icons.gitHub className="mr-2 h-4 w-4" />
29
+ Github
30
+ </Button>
31
+ <Button variant="outline">
32
+ <Icons.google className="mr-2 h-4 w-4" />
33
+ Google
34
+ </Button>
35
+ </div>
36
+ <div className="relative">
37
+ <div className="absolute inset-0 flex items-center">
38
+ <span className="w-full border-t" />
39
+ </div>
40
+ <div className="relative flex justify-center text-xs uppercase">
41
+ <span className="bg-background px-2 text-muted-foreground">
42
+ Or continue with
43
+ </span>
44
+ </div>
45
+ </div>
46
+ <div className="grid gap-2">
47
+ <Label htmlFor="email">Email</Label>
48
+ <Input id="email" type="email" placeholder="m@example.com" />
49
+ </div>
50
+ <div className="grid gap-2">
51
+ <Label htmlFor="password">Password</Label>
52
+ <Input id="password" type="password" />
53
+ </div>
54
+ </CardContent>
55
+ <CardFooter>
56
+ <Button className="w-full">Create account</Button>
57
+ </CardFooter>
58
+ </Card>
59
+ )
60
+ }
@@ -8,6 +8,11 @@ import {
8
8
  } from "../../elements"
9
9
  import { Controller, useForm } from "react-hook-form"
10
10
  import { HawaContainer } from "../../layout"
11
+ import { Button } from "../../elements/Button"
12
+ import { FaGithub, FaGoogle } from "react-icons/fa"
13
+ import { Card, CardContent, CardFooter, CardHeader } from "../../elements/Card"
14
+ import { Icons } from "../../elements/Icons"
15
+ import clsx from "clsx"
11
16
 
12
17
  export const SignInForm: FC<SignInFormTypes> = (props) => {
13
18
  const {
@@ -17,155 +22,161 @@ export const SignInForm: FC<SignInFormTypes> = (props) => {
17
22
  } = useForm()
18
23
 
19
24
  return (
20
- <HawaContainer direction={props.direction}>
21
- <form onSubmit={handleSubmit((e) => props.handleSignIn(e))}>
22
- {props.showError && (
23
- <HawaAlert
24
- title={props.errorTitle}
25
- text={props.errorText}
26
- severity="error"
27
- />
28
- )}
29
- {props.signInType === "email" ? (
30
- <Controller
31
- control={control}
32
- name="email"
33
- render={({ field }) => (
34
- <HawaTextField
35
- width="full"
36
- type="text"
37
- autoComplete="email"
38
- label={props.texts.emailLabel}
39
- helpertext={errors.email?.message}
40
- placeholder={props.texts.emailPlaceholder}
41
- value={field.value ?? ""}
42
- onChange={field.onChange}
43
- />
44
- )}
45
- rules={{
46
- required: props.texts.emailRequiredText,
47
- pattern: {
48
- value:
49
- /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
50
- message: props.texts.emailInvalidText,
51
- },
52
- }}
53
- />
54
- ) : props.signInType === "username" ? (
55
- <Controller
56
- control={control}
57
- name="username"
58
- render={({ field }) => {
59
- return (
60
- <HawaTextField
61
- width="full"
62
- type="text"
63
- autoComplete="username"
64
- label={props.texts.usernameLabel}
65
- helpertext={errors.username?.message}
66
- placeholder={props.texts.usernamePlaceholder}
67
- onChange={field.onChange}
68
- value={field.value ?? ""}
69
- />
70
- )
71
- }}
72
- rules={{
73
- required: props.texts.usernameRequired,
74
- }}
75
- />
76
- ) : (
77
- <Controller
78
- control={control}
79
- name="phone"
80
- render={({ field }) => <HawaPhoneInput label="Phone number" />}
81
- rules={{ required: props.texts.phoneRequiredText }}
82
- />
83
- )}
84
- {props.signInType !== "phone" && (
85
- <>
25
+ <Card dir={props.direction}>
26
+ <CardContent headless>
27
+ <form onSubmit={handleSubmit((e) => props.handleSignIn(e))}>
28
+ {props.showError && (
29
+ <HawaAlert
30
+ title={props.errorTitle}
31
+ text={props.errorText}
32
+ severity="error"
33
+ />
34
+ )}
35
+ {props.signInType === "email" ? (
86
36
  <Controller
87
37
  control={control}
88
- name="password"
38
+ name="email"
89
39
  render={({ field }) => (
90
40
  <HawaTextField
91
41
  width="full"
92
- autoComplete="current-password"
93
- type="password"
94
- label={props.texts.passwordLabel}
95
- placeholder={props.texts.passwordPlaceholder}
96
- helpertext={errors.password?.message}
97
- onChange={field.onChange}
42
+ type="text"
43
+ autoComplete="email"
44
+ label={props.texts.emailLabel}
45
+ helpertext={errors.email?.message}
46
+ placeholder={props.texts.emailPlaceholder}
98
47
  value={field.value ?? ""}
48
+ onChange={field.onChange}
99
49
  />
100
50
  )}
101
51
  rules={{
102
- required: props.texts.passwordRequiredText,
103
- minLength: 5,
52
+ required: props.texts.emailRequiredText,
53
+ pattern: {
54
+ value:
55
+ /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
56
+ message: props.texts.emailInvalidText,
57
+ },
104
58
  }}
105
59
  />
106
- {!props.withoutResetPassword && (
107
- <div
108
- onClick={props.handleForgotPassword}
109
- className="mb-3 w-fit cursor-pointer text-xs dark:text-gray-300"
110
- >
111
- {props.texts.forgotPasswordText}
112
- </div>
113
- )}
114
- </>
115
- )}
60
+ ) : props.signInType === "username" ? (
61
+ <Controller
62
+ control={control}
63
+ name="username"
64
+ render={({ field }) => {
65
+ return (
66
+ <HawaTextField
67
+ width="full"
68
+ type="text"
69
+ autoComplete="username"
70
+ label={props.texts.usernameLabel}
71
+ helpertext={errors.username?.message}
72
+ placeholder={props.texts.usernamePlaceholder}
73
+ onChange={field.onChange}
74
+ value={field.value ?? ""}
75
+ />
76
+ )
77
+ }}
78
+ rules={{
79
+ required: props.texts.usernameRequired,
80
+ }}
81
+ />
82
+ ) : (
83
+ <Controller
84
+ control={control}
85
+ name="phone"
86
+ render={({ field }) => <HawaPhoneInput label="Phone number" />}
87
+ rules={{ required: props.texts.phoneRequiredText }}
88
+ />
89
+ )}
90
+ {props.signInType !== "phone" && (
91
+ <>
92
+ <Controller
93
+ control={control}
94
+ name="password"
95
+ render={({ field }) => (
96
+ <HawaTextField
97
+ width="full"
98
+ autoComplete="current-password"
99
+ type="password"
100
+ label={props.texts.passwordLabel}
101
+ placeholder={props.texts.passwordPlaceholder}
102
+ helpertext={errors.password?.message}
103
+ onChange={field.onChange}
104
+ value={field.value ?? ""}
105
+ />
106
+ )}
107
+ rules={{
108
+ required: props.texts.passwordRequiredText,
109
+ minLength: 5,
110
+ }}
111
+ />
112
+ {!props.withoutResetPassword && (
113
+ <div
114
+ onClick={props.handleForgotPassword}
115
+ className="mb-3 w-fit cursor-pointer text-xs dark:text-gray-300"
116
+ >
117
+ {props.texts.forgotPasswordText}
118
+ </div>
119
+ )}
120
+ </>
121
+ )}
116
122
 
117
- <HawaButton
118
- isLoading={props.isLoading}
119
- variant="contained"
120
- color="primary"
121
- size="medium"
122
- width="full"
123
- >
124
- {props.texts.signInText}
125
- </HawaButton>
126
- {!props.withoutSignUp && (
127
- <div className="p-3 text-center text-sm font-semibold dark:text-gray-300">
128
- {props.texts.newUserText}{" "}
129
- <span
130
- onClick={props.handleRouteToSignUp}
131
- className="cursor-pointer text-blue-600 dark:text-blue-400"
132
- >
133
- {props.texts.signUpText}
134
- </span>
135
- </div>
136
- )}
137
- </form>
123
+
124
+ <Button className="w-full" isLoading={props.isLoading}>
125
+ {props.texts.signInText}
126
+ </Button>
127
+ {!props.withoutSignUp && (
128
+ <div className="p-3 text-center text-sm font-semibold dark:text-gray-300">
129
+ {props.texts.newUserText}{" "}
130
+ <span
131
+ onClick={props.handleRouteToSignUp}
132
+ className="cursor-pointer text-blue-600 dark:text-blue-400"
133
+ >
134
+ {props.texts.createAccount}
135
+ </span>
136
+ </div>
137
+ )}
138
+ </form>
139
+ </CardContent>
138
140
 
139
141
  {/* 3rd Party Sign Auth Buttons */}
140
142
  {props.viaGithub || props.viaGoogle || props.viaTwitter ? (
141
- <div className="flex flex-col ">
143
+ <CardFooter className="grid grid-cols-1 gap-2 ">
142
144
  {props.viaGoogle && (
143
- <HawaLogoButton
144
- logo="google"
145
- direction={props.direction}
146
- buttonText={props.texts.signInViaGoogleLabel}
147
- onClick={props.handleGoogleSignIn}
148
- />
145
+ <Button variant="outline" onClick={props.handleGoogleSignIn}>
146
+ <Icons.google
147
+ className={clsx(
148
+ "h-4 w-4",
149
+ props.direction === "rtl" ? "ml-2" : "mr-2"
150
+ )}
151
+ />
152
+ {props.texts.signInViaGoogleLabel}
153
+ </Button>
149
154
  )}
150
155
  {props.viaGithub && (
151
- <HawaLogoButton
152
- logo="github"
153
- direction={props.direction}
154
- buttonText={props.texts.signInViaGithubLabel}
155
- onClick={props.handleGithubSignIn}
156
- />
156
+ <Button variant="outline" onClick={props.handleGithubSignIn}>
157
+ <Icons.gitHub
158
+ className={clsx(
159
+ "h-4 w-4",
160
+ props.direction === "rtl" ? "ml-2" : "mr-2"
161
+ )}
162
+ />
163
+ {props.texts.signInViaGithubLabel}
164
+ </Button>
157
165
  )}
158
166
  {props.viaTwitter && (
159
- <HawaLogoButton
160
- logo="twitter"
161
- direction={props.direction}
162
- buttonText={props.texts.signInViaTwitterLabel}
163
- onClick={props.handleTwitterSignIn}
164
- />
167
+ <Button variant="outline" onClick={props.handleTwitterSignIn}>
168
+ <Icons.twitter
169
+ className={clsx(
170
+ "h-4 w-4",
171
+ props.direction === "rtl" ? "ml-2" : "mr-2"
172
+ )}
173
+ />
174
+ {props.texts.signInViaTwitterLabel}
175
+ </Button>
165
176
  )}
166
- </div>
177
+ </CardFooter>
167
178
  ) : null}
168
- </HawaContainer>
179
+ </Card>
169
180
  )
170
181
  }
171
182
 
@@ -189,7 +200,7 @@ type SignInFormTypes = {
189
200
  passwordRequiredText?: string
190
201
  forgotPasswordText?: string
191
202
  newUserText?: string
192
- signUpText?: string
203
+ createAccount?: string
193
204
  signInText?: string
194
205
  signInViaGoogleLabel?: string
195
206
  signInViaGithubLabel?: string