@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
@@ -8,7 +8,10 @@ import {
8
8
  HawaSelect,
9
9
  } from "../../elements"
10
10
  import { Controller, FormProvider, useForm } from "react-hook-form"
11
- import { HawaContainer } from "../../layout/HawaContainer"
11
+ import { Card, CardContent, CardFooter } from "../../elements/Card"
12
+ import { Button } from "../../elements/Button"
13
+ import { Icons } from "../../elements/Icons"
14
+ import clsx from "clsx"
12
15
 
13
16
  type SignUpFormTypes = {
14
17
  direction?: "rtl" | "ltr"
@@ -72,259 +75,268 @@ export const SignUpForm: FC<SignUpFormTypes> = (props) => {
72
75
  } = methods
73
76
 
74
77
  return (
75
- <HawaContainer direction={props.direction}>
76
- <div>
77
- {props.showError && (
78
- <HawaAlert
79
- title={props.errorTitle}
80
- text={props.errorText}
81
- severity="error"
82
- />
83
- )}
84
- <FormProvider {...methods}>
85
- <form onSubmit={handleSubmit((e) => props.handleSignUp(e))}>
86
- <div>
87
- {props.signUpFields.map((fld, i) => {
88
- if (fld === "fullname") {
89
- return (
90
- <Controller
91
- key={i}
92
- control={control}
93
- name="fullName"
94
- render={({ field }) => (
95
- <HawaTextField
96
- width="full"
97
- type="text"
98
- label={props.texts.fullNameLabel}
99
- placeholder={props.texts.fullNamePlaceholder}
100
- helpertext={errors.fullName?.message}
101
- onChange={field.onChange}
102
- value={field.value ?? ""}
103
- />
104
- )}
105
- rules={{
106
- required: props.texts.fullNameRequiredText,
107
- }}
108
- />
109
- )
110
- }
111
- if (fld === "email") {
112
- return (
113
- <Controller
114
- control={control}
115
- name="email"
116
- render={({ field }) => (
117
- <HawaTextField
118
- width="full"
119
- type="text"
120
- autoComplete="email"
121
- label={props.texts.emailLabel}
122
- helpertext={errors.email?.message}
123
- placeholder={props.texts.emailPlaceholder}
124
- onChange={field.onChange}
125
- value={field.value ?? ""}
126
- />
127
- )}
128
- rules={{
129
- required: props.texts.emailRequiredText,
130
- pattern: {
131
- value:
132
- /^(([^<>()[\]\\.,;:\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,}))$/,
133
- message: props.texts.emailInvalidText,
134
- },
135
- }}
136
- />
137
- )
138
- }
139
- if (fld === "username") {
140
- return (
141
- <Controller
142
- control={control}
143
- name="username"
144
- render={({ field }) => (
145
- <HawaTextField
146
- width="full"
147
- type="text"
148
- autoComplete="username"
149
- label={props.texts.usernameLabel}
150
- helpertext={errors.username?.message}
151
- placeholder={props.texts.usernamePlaceholder}
152
- onChange={field.onChange}
153
- value={field.value ?? ""}
154
- />
155
- )}
156
- rules={{
157
- required: props.texts.usernameRequired,
158
- }}
159
- />
160
- )
161
- }
162
- })}
163
- </div>
164
- <Controller
165
- control={control}
166
- name="password"
167
- render={({ field }) => (
168
- <HawaTextField
169
- width="full"
170
- type="password"
171
- autoComplete="new-password"
172
- // defaultValue={field.value ?? ""}
173
- label={props.texts.passwordLabel}
174
- placeholder={props.texts.passwordPlaceholder}
175
- helpertext={errors.password?.message}
176
- onChange={field.onChange}
177
- value={field.value ?? ""}
178
- />
179
- )}
180
- rules={{ required: props.texts.passwordRequiredText }}
181
- />
182
- <Controller
183
- control={control}
184
- name="confirm_password"
185
- render={({ field }) => (
186
- <HawaTextField
187
- width="full"
188
- type="password"
189
- autoComplete="new-password"
190
- // defaultValue={field.value ?? ""}
191
- label={props.texts.confirmPasswordLabel}
192
- placeholder={props.texts.confirmPasswordPlaceholder}
193
- helpertext={errors.confirm_password?.message}
194
- onChange={field.onChange}
195
- value={field.value ?? ""}
196
- />
197
- )}
198
- rules={{ required: props.texts.passwordRequiredText }}
78
+ <Card dir={props.direction}>
79
+ <CardContent headless>
80
+ <div>
81
+ {props.showError && (
82
+ <HawaAlert
83
+ title={props.errorTitle}
84
+ text={props.errorText}
85
+ severity="error"
199
86
  />
200
- {props.showRefCode && (
87
+ )}
88
+ <FormProvider {...methods}>
89
+ <form onSubmit={handleSubmit((e) => props.handleSignUp(e))}>
90
+ <div>
91
+ {props.signUpFields.map((fld, i) => {
92
+ if (fld === "fullname") {
93
+ return (
94
+ <Controller
95
+ key={i}
96
+ control={control}
97
+ name="fullName"
98
+ render={({ field }) => (
99
+ <HawaTextField
100
+ width="full"
101
+ type="text"
102
+ label={props.texts.fullNameLabel}
103
+ placeholder={props.texts.fullNamePlaceholder}
104
+ helpertext={errors.fullName?.message}
105
+ onChange={field.onChange}
106
+ value={field.value ?? ""}
107
+ />
108
+ )}
109
+ rules={{
110
+ required: props.texts.fullNameRequiredText,
111
+ }}
112
+ />
113
+ )
114
+ }
115
+ if (fld === "email") {
116
+ return (
117
+ <Controller
118
+ control={control}
119
+ name="email"
120
+ render={({ field }) => (
121
+ <HawaTextField
122
+ width="full"
123
+ type="text"
124
+ autoComplete="email"
125
+ label={props.texts.emailLabel}
126
+ helpertext={errors.email?.message}
127
+ placeholder={props.texts.emailPlaceholder}
128
+ onChange={field.onChange}
129
+ value={field.value ?? ""}
130
+ />
131
+ )}
132
+ rules={{
133
+ required: props.texts.emailRequiredText,
134
+ pattern: {
135
+ value:
136
+ /^(([^<>()[\]\\.,;:\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,}))$/,
137
+ message: props.texts.emailInvalidText,
138
+ },
139
+ }}
140
+ />
141
+ )
142
+ }
143
+ if (fld === "username") {
144
+ return (
145
+ <Controller
146
+ control={control}
147
+ name="username"
148
+ render={({ field }) => (
149
+ <HawaTextField
150
+ width="full"
151
+ type="text"
152
+ autoComplete="username"
153
+ label={props.texts.usernameLabel}
154
+ helpertext={errors.username?.message}
155
+ placeholder={props.texts.usernamePlaceholder}
156
+ onChange={field.onChange}
157
+ value={field.value ?? ""}
158
+ />
159
+ )}
160
+ rules={{
161
+ required: props.texts.usernameRequired,
162
+ }}
163
+ />
164
+ )
165
+ }
166
+ })}
167
+ </div>
201
168
  <Controller
202
169
  control={control}
203
- name="refCode"
170
+ name="password"
204
171
  render={({ field }) => (
205
172
  <HawaTextField
206
173
  width="full"
207
- type="text"
208
- defaultValue={field.value ?? ""}
209
- label={props.texts.refCode}
174
+ type="password"
175
+ autoComplete="new-password"
176
+ // defaultValue={field.value ?? ""}
177
+ label={props.texts.passwordLabel}
210
178
  placeholder={props.texts.passwordPlaceholder}
211
179
  helpertext={errors.password?.message}
180
+ onChange={field.onChange}
212
181
  value={field.value ?? ""}
182
+ />
183
+ )}
184
+ rules={{ required: props.texts.passwordRequiredText }}
185
+ />
186
+ <Controller
187
+ control={control}
188
+ name="confirm_password"
189
+ render={({ field }) => (
190
+ <HawaTextField
191
+ width="full"
192
+ type="password"
193
+ autoComplete="new-password"
194
+ // defaultValue={field.value ?? ""}
195
+ label={props.texts.confirmPasswordLabel}
196
+ placeholder={props.texts.confirmPasswordPlaceholder}
197
+ helpertext={errors.confirm_password?.message}
213
198
  onChange={field.onChange}
199
+ value={field.value ?? ""}
214
200
  />
215
201
  )}
202
+ rules={{ required: props.texts.passwordRequiredText }}
216
203
  />
217
- )}
218
- {props.showUserSource && (
219
- <div>
204
+ {props.showRefCode && (
220
205
  <Controller
221
206
  control={control}
222
- name="reference"
207
+ name="refCode"
223
208
  render={({ field }) => (
224
- <HawaSelect
225
- label="How did you learn about us?"
226
- isCreatable={false}
227
- isMulti={false ?? false}
228
- isSearchable={false}
229
- isClearable={false ?? false}
230
- options={[
231
- { value: "friend", label: "From a friend" },
232
- { value: "ad", label: "Advertisement" },
233
- { value: "other", label: "Other" },
234
- ]}
235
- onChange={(e: any) => {
236
- field.onChange(e.value)
237
- }}
209
+ <HawaTextField
210
+ width="full"
211
+ type="text"
212
+ defaultValue={field.value ?? ""}
213
+ label={props.texts.refCode}
214
+ placeholder={props.texts.passwordPlaceholder}
215
+ helpertext={errors.password?.message}
216
+ value={field.value ?? ""}
217
+ onChange={field.onChange}
238
218
  />
239
219
  )}
240
220
  />
241
- </div>
242
- )}
243
- {props.showTermsOption && (
244
- <Controller
245
- control={control}
246
- name="terms_accepted"
247
- render={({ field }) => (
248
- <HawaCheckbox
249
- id="terms_accepted"
250
- helperText={errors.terms_accepted?.message}
251
- onChange={(e) => field.onChange(e)}
252
- label={
253
- <span>
254
- {props.texts.iAcceptText}{" "}
255
- <a
256
- onClick={props.handleRouteToTOS}
257
- className="cursor-pointer text-blue-800"
258
- >
259
- {props.texts.termsText}
260
- </a>
261
- </span>
262
- }
263
- />
264
- )}
265
- rules={{ required: props.texts.termsRequiredText }}
266
- />
267
- )}
268
- {props.showNewsletterOption && (
269
- <Controller
270
- control={control}
271
- name="newsletter_accepted"
272
- render={({ field }) => (
273
- <HawaCheckbox
274
- id="newsletter_accepted"
275
- label={props.texts.subscribeToNewsletter}
276
- onChange={field.onChange}
221
+ )}
222
+ {props.showUserSource && (
223
+ <div>
224
+ <Controller
225
+ control={control}
226
+ name="reference"
227
+ render={({ field }) => (
228
+ <HawaSelect
229
+ label="How did you learn about us?"
230
+ isCreatable={false}
231
+ isMulti={false ?? false}
232
+ isSearchable={false}
233
+ isClearable={false ?? false}
234
+ options={[
235
+ { value: "friend", label: "From a friend" },
236
+ { value: "ad", label: "Advertisement" },
237
+ { value: "other", label: "Other" },
238
+ ]}
239
+ onChange={(e: any) => {
240
+ field.onChange(e.value)
241
+ }}
242
+ />
243
+ )}
277
244
  />
278
- )}
279
- />
280
- )}
281
- <HawaButton
282
- isLoading={props.isLoading}
283
- color="primary"
284
- width="full"
245
+ </div>
246
+ )}
247
+ {props.showTermsOption && (
248
+ <Controller
249
+ control={control}
250
+ name="terms_accepted"
251
+ render={({ field }) => (
252
+ <HawaCheckbox
253
+ id="terms_accepted"
254
+ helperText={errors.terms_accepted?.message}
255
+ onChange={(e) => field.onChange(e)}
256
+ label={
257
+ <span>
258
+ {props.texts.iAcceptText}{" "}
259
+ <a
260
+ onClick={props.handleRouteToTOS}
261
+ className="cursor-pointer text-blue-800"
262
+ >
263
+ {props.texts.termsText}
264
+ </a>
265
+ </span>
266
+ }
267
+ />
268
+ )}
269
+ rules={{ required: props.texts.termsRequiredText }}
270
+ />
271
+ )}
272
+ {props.showNewsletterOption && (
273
+ <Controller
274
+ control={control}
275
+ name="newsletter_accepted"
276
+ render={({ field }) => (
277
+ <HawaCheckbox
278
+ id="newsletter_accepted"
279
+ label={props.texts.subscribeToNewsletter}
280
+ onChange={field.onChange}
281
+ />
282
+ )}
283
+ />
284
+ )}
285
+
286
+ <Button className="w-full" isLoading={props.isLoading}>
287
+ {props.texts.signUpText}
288
+ </Button>
289
+ </form>
290
+ </FormProvider>
291
+ <div className="flex flex-row items-center justify-center gap-1 p-3 text-center text-sm font-semibold dark:text-white">
292
+ <span>{props.texts.existingUserText}</span>
293
+ <span
294
+ onClick={props.handleRouteToSignIn}
295
+ className="cursor-pointer text-blue-600"
285
296
  >
286
- {props.texts.signUpText}
287
- </HawaButton>
288
- </form>
289
- </FormProvider>
290
- <div className="flex flex-row items-center justify-center gap-1 p-3 text-center text-sm font-semibold dark:text-white">
291
- <span>{props.texts.existingUserText}</span>
292
- <span
293
- onClick={props.handleRouteToSignIn}
294
- className="cursor-pointer text-blue-600"
295
- >
296
- {props.texts.signInText}
297
- </span>
297
+ {props.texts.signInText}
298
+ </span>
299
+ </div>
298
300
  </div>
299
- </div>
301
+ </CardContent>
302
+
300
303
  {props.viaGithub || props.viaGoogle || props.viaTwitter ? (
301
- <div style={{ display: "flex", flexDirection: "column" }}>
304
+ <CardFooter className="grid grid-cols-1 gap-2 ">
302
305
  {props.viaGoogle && (
303
- <HawaLogoButton
304
- logo="google"
305
- direction={props.direction}
306
- buttonText={props.texts.signUpViaGoogleLabel}
307
- onClick={props.handleGoogleSignUp}
308
- />
306
+ <Button variant="outline" onClick={props.handleGoogleSignUp}>
307
+ <Icons.google
308
+ className={clsx(
309
+ "h-4 w-4",
310
+ props.direction === "rtl" ? "ml-2" : "mr-2"
311
+ )}
312
+ />
313
+ {props.texts.signUpViaGoogleLabel}
314
+ </Button>
309
315
  )}
310
316
  {props.viaGithub && (
311
- <HawaLogoButton
312
- logo="github"
313
- direction={props.direction}
314
- buttonText={props.texts.signUpViaGithubLabel}
315
- onClick={props.handleGithubSignUp}
316
- />
317
+ <Button variant="outline" onClick={props.handleGithubSignUp}>
318
+ <Icons.gitHub
319
+ className={clsx(
320
+ "h-4 w-4",
321
+ props.direction === "rtl" ? "ml-2" : "mr-2"
322
+ )}
323
+ />
324
+ {props.texts.signUpViaGithubLabel}
325
+ </Button>
317
326
  )}
318
327
  {props.viaTwitter && (
319
- <HawaLogoButton
320
- logo="twitter"
321
- direction={props.direction}
322
- buttonText={props.texts.signUpViaTwitterLabel}
323
- onClick={props.handleTwitterSignUp}
324
- />
328
+ <Button variant="outline" onClick={props.handleTwitterSignUp}>
329
+ <Icons.twitter
330
+ className={clsx(
331
+ "h-4 w-4",
332
+ props.direction === "rtl" ? "ml-2" : "mr-2"
333
+ )}
334
+ />
335
+ {props.texts.signUpViaTwitterLabel}
336
+ </Button>
325
337
  )}
326
- </div>
338
+ </CardFooter>
327
339
  ) : null}
328
- </HawaContainer>
340
+ </Card>
329
341
  )
330
342
  }
@@ -1,7 +1,8 @@
1
- export * from "./AppLanding";
2
- export * from "./SignInPhone";
3
- export * from "./SignInForm";
4
- export * from "./SignUpForm";
5
- export * from "./NewPasswordForm";
6
- export * from "./ResetPasswordForm";
7
- export * from "./CodeConfirmation";
1
+ export * from "./AppLanding"
2
+ export * from "./SignInPhone"
3
+ export * from "./SignInForm"
4
+ export * from "./SignInBlock"
5
+ export * from "./SignUpForm"
6
+ export * from "./NewPasswordForm"
7
+ export * from "./ResetPasswordForm"
8
+ export * from "./CodeConfirmation"
@@ -0,0 +1,77 @@
1
+ import * as React from "react"
2
+ // import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "../util"
6
+ import { HawaLoading } from "./HawaLoading"
7
+
8
+ const buttonVariants = cva(
9
+ "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
14
+ destructive:
15
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
16
+ outline:
17
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
18
+ secondary:
19
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
20
+ ghost: "hover:bg-accent hover:text-accent-foreground",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ default: "h-10 px-4 py-2",
25
+ sm: "h-9 rounded-md px-3",
26
+ lg: "h-11 rounded-md px-8",
27
+ icon: "h-10 w-10",
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: "default",
32
+ size: "default",
33
+ },
34
+ }
35
+ )
36
+
37
+ export interface ButtonProps
38
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39
+ VariantProps<typeof buttonVariants> {
40
+ asChild?: boolean
41
+ isLoading?: boolean
42
+ }
43
+
44
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
45
+ (
46
+ {
47
+ className,
48
+ variant,
49
+ size,
50
+ asChild = false,
51
+ isLoading,
52
+ children,
53
+ ...props
54
+ },
55
+ ref
56
+ ) => {
57
+ // const Comp = asChild ? Slot : "button"
58
+ const Comp = "button"
59
+ return (
60
+ <Comp
61
+ className={cn(buttonVariants({ variant, size, className }))}
62
+ ref={ref}
63
+ {...props}
64
+ >
65
+ {isLoading ? (
66
+ // Replace with your loading icon component
67
+ <HawaLoading design="dots-pulse" size="button" />
68
+ ) : (
69
+ children
70
+ )}
71
+ </Comp>
72
+ )
73
+ }
74
+ )
75
+ Button.displayName = "Button"
76
+
77
+ export { Button, buttonVariants }