@sikka/hawa 0.0.266 → 0.0.268
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.
- package/.github/workflows/hawa-publish-push.yml +1 -0
- package/dist/styles.css +165 -15
- package/es/elements/DragDropImages.d.ts +2 -0
- package/es/elements/HawaRadio.d.ts +6 -0
- package/es/elements/HawaTable.d.ts +12 -2
- package/es/hooks/useTable.d.ts +1 -1
- package/es/index.es.js +3 -3
- package/es/layout/Banner.d.ts +14 -0
- package/es/layout/index.d.ts +1 -0
- package/lib/elements/DragDropImages.d.ts +2 -0
- package/lib/elements/HawaRadio.d.ts +6 -0
- package/lib/elements/HawaTable.d.ts +12 -2
- package/lib/hooks/useTable.d.ts +1 -1
- package/lib/index.js +3 -3
- package/lib/layout/Banner.d.ts +14 -0
- package/lib/layout/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/blocks/Misc/EmptyState.tsx +11 -2
- package/src/blocks/Misc/NoPermission.tsx +11 -2
- package/src/blocks/Pricing/ComparingPlans.tsx +11 -2
- package/src/blocks/Referral/ReferralAccount.tsx +22 -3
- package/src/blocks/Referral/ReferralSettlement.tsx +15 -3
- package/src/elements/DragDropImages.tsx +88 -58
- package/src/elements/HawaAlert.tsx +0 -1
- package/src/elements/HawaButton.tsx +11 -2
- package/src/elements/HawaRadio.tsx +154 -29
- package/src/elements/HawaTable.tsx +71 -13
- package/src/hooks/useTable.ts +129 -4
- package/src/layout/Banner.tsx +123 -0
- package/src/layout/HawaAppLayout.tsx +16 -3
- package/src/layout/HawaAppLayoutSimplified.tsx +29 -5
- package/src/layout/HawaSiteLayout.tsx +16 -3
- package/src/layout/index.ts +1 -0
- package/src/styles.css +165 -15
- package/src/tailwind.css +61 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
type BannerTypes = {
|
|
3
|
+
showBanner?: boolean;
|
|
4
|
+
direction?: "rtl" | "ltr";
|
|
5
|
+
logoURL?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
text?: string;
|
|
8
|
+
actionText?: string;
|
|
9
|
+
onActionClick?: () => void;
|
|
10
|
+
position?: "top" | "bottom";
|
|
11
|
+
design: "default" | "floating";
|
|
12
|
+
};
|
|
13
|
+
export declare const HawaBanner: FC<BannerTypes>;
|
|
14
|
+
export {};
|
package/lib/layout/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { FC } from "react"
|
|
2
2
|
import { HawaButton } from "../../elements"
|
|
3
3
|
import { HawaContainer } from "../../layout"
|
|
4
|
-
import { FaCheck } from "react-icons/fa"
|
|
5
4
|
|
|
6
5
|
type TEmptyState = {
|
|
7
6
|
variant?: "outlined" | "contained" | "neobrutalism"
|
|
@@ -21,7 +20,17 @@ export const EmptyState: FC<TEmptyState> = ({
|
|
|
21
20
|
<HawaContainer variant={variant} centered={true} maxWidth="small">
|
|
22
21
|
<div className="flex flex-col items-center justify-center text-center dark:text-white">
|
|
23
22
|
<div className="flex h-10 w-10 flex-col items-center justify-center rounded-3xl bg-buttonPrimary-300 text-6xl font-bold">
|
|
24
|
-
<
|
|
23
|
+
<svg
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
fill="white"
|
|
26
|
+
stroke-width="0"
|
|
27
|
+
viewBox="0 0 512 512"
|
|
28
|
+
height="0.35em"
|
|
29
|
+
width="0.35em"
|
|
30
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
31
|
+
>
|
|
32
|
+
<path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"></path>
|
|
33
|
+
</svg>
|
|
25
34
|
</div>
|
|
26
35
|
<div className="m-2 text-xl font-bold">
|
|
27
36
|
{texts?.youreCaughtUp ?? "You're all caught up"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { FC } from "react"
|
|
2
2
|
import { HawaContainer } from "../../layout"
|
|
3
|
-
import { FaLock } from "react-icons/fa"
|
|
4
3
|
|
|
5
4
|
type TNoPermission = {
|
|
6
5
|
variant?: "outlined" | "contained" | "neobrutalism"
|
|
@@ -18,7 +17,17 @@ export const NoPermission: FC<TNoPermission> = ({
|
|
|
18
17
|
<HawaContainer variant={variant} centered={true}>
|
|
19
18
|
<div className="flex flex-col items-center justify-center text-center dark:text-white">
|
|
20
19
|
<div className="flex h-10 w-10 flex-col items-center justify-center rounded-3xl bg-buttonPrimary-300 text-6xl font-bold">
|
|
21
|
-
<
|
|
20
|
+
<svg
|
|
21
|
+
stroke="currentColor"
|
|
22
|
+
fill="white"
|
|
23
|
+
stroke-width="0"
|
|
24
|
+
viewBox="0 0 448 512"
|
|
25
|
+
height="0.35em"
|
|
26
|
+
width="0.35em"
|
|
27
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
28
|
+
>
|
|
29
|
+
<path d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path>
|
|
30
|
+
</svg>
|
|
22
31
|
</div>
|
|
23
32
|
<div className="m-2 text-xl font-bold">
|
|
24
33
|
{texts?.title ?? "You don't have permission"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useState, FC } from "react"
|
|
2
|
-
import { BsExclamationCircleFill } from "react-icons/bs"
|
|
3
2
|
import { HawaTabs, HawaTooltip } from "../../elements"
|
|
4
3
|
|
|
5
4
|
const CheckMark = () => (
|
|
@@ -131,7 +130,17 @@ export const ComparingPlans: FC<ComparingPlansTypes> = (props) => {
|
|
|
131
130
|
position="top-right"
|
|
132
131
|
content={feature.description}
|
|
133
132
|
>
|
|
134
|
-
<
|
|
133
|
+
<svg
|
|
134
|
+
stroke="currentColor"
|
|
135
|
+
fill="currentColor"
|
|
136
|
+
stroke-width="0"
|
|
137
|
+
viewBox="0 0 16 16"
|
|
138
|
+
height="1em"
|
|
139
|
+
width="1em"
|
|
140
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
141
|
+
>
|
|
142
|
+
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"></path>
|
|
143
|
+
</svg>
|
|
135
144
|
</HawaTooltip>
|
|
136
145
|
)}
|
|
137
146
|
</div>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { FC } from "react"
|
|
2
|
-
import { FaClone } from "react-icons/fa"
|
|
3
2
|
import { HawaButton } from "../../elements"
|
|
4
3
|
import { HawaContainer } from "../../layout"
|
|
5
4
|
|
|
@@ -24,7 +23,17 @@ export const ReferralAccount: FC<ReferralAccount> = ({
|
|
|
24
23
|
onClick={() => navigator.clipboard.writeText(referralCode)}
|
|
25
24
|
>
|
|
26
25
|
<span className="bg-red flex items-center justify-center">
|
|
27
|
-
<
|
|
26
|
+
<svg
|
|
27
|
+
stroke="currentColor"
|
|
28
|
+
fill="currentColor"
|
|
29
|
+
stroke-width="0"
|
|
30
|
+
viewBox="0 0 512 512"
|
|
31
|
+
height="1em"
|
|
32
|
+
width="1em"
|
|
33
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
34
|
+
>
|
|
35
|
+
<path d="M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"></path>
|
|
36
|
+
</svg>{" "}
|
|
28
37
|
</span>
|
|
29
38
|
</HawaButton>
|
|
30
39
|
</div>
|
|
@@ -38,7 +47,17 @@ export const ReferralAccount: FC<ReferralAccount> = ({
|
|
|
38
47
|
onClick={() => navigator.clipboard.writeText(referralLink)}
|
|
39
48
|
>
|
|
40
49
|
<span className="bg-red flex items-center justify-center">
|
|
41
|
-
<
|
|
50
|
+
<svg
|
|
51
|
+
stroke="currentColor"
|
|
52
|
+
fill="currentColor"
|
|
53
|
+
stroke-width="0"
|
|
54
|
+
viewBox="0 0 512 512"
|
|
55
|
+
height="1em"
|
|
56
|
+
width="1em"
|
|
57
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
58
|
+
>
|
|
59
|
+
<path d="M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"></path>
|
|
60
|
+
</svg>{" "}
|
|
42
61
|
</span>
|
|
43
62
|
</HawaButton>
|
|
44
63
|
</div>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { FC } from "react"
|
|
2
|
-
import { FaTimes } from "react-icons/fa"
|
|
3
2
|
import {
|
|
4
3
|
HawaAlert,
|
|
5
4
|
HawaButton,
|
|
@@ -109,8 +108,21 @@ const SettlementAccountCard = (props) => (
|
|
|
109
108
|
)}
|
|
110
109
|
{/* {props.default && <HawaChip size="normal" label="Default" />} */}
|
|
111
110
|
{!props.default && <HawaButton size="small">Make Default</HawaButton>}
|
|
112
|
-
<HawaButton tooltip="Delete">
|
|
113
|
-
<FaTimes />
|
|
111
|
+
<HawaButton tooltip="Delete" size="small">
|
|
112
|
+
{/* <FaTimes /> */}
|
|
113
|
+
<svg
|
|
114
|
+
aria-hidden="true"
|
|
115
|
+
className="h-5 w-5"
|
|
116
|
+
fill="currentColor"
|
|
117
|
+
viewBox="0 0 20 20"
|
|
118
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
119
|
+
>
|
|
120
|
+
<path
|
|
121
|
+
fillRule="evenodd"
|
|
122
|
+
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
|
123
|
+
clipRule="evenodd"
|
|
124
|
+
></path>
|
|
125
|
+
</svg>
|
|
114
126
|
</HawaButton>
|
|
115
127
|
</div>
|
|
116
128
|
</div>
|
|
@@ -2,9 +2,10 @@ import React, { useEffect, useState } from "react"
|
|
|
2
2
|
import { useDropzone } from "react-dropzone"
|
|
3
3
|
import { HawaAlert } from "./HawaAlert"
|
|
4
4
|
import { HawaButton } from "./HawaButton"
|
|
5
|
-
import { TbDragDrop } from "react-icons/tb"
|
|
6
5
|
import clsx from "clsx"
|
|
6
|
+
|
|
7
7
|
//TODO: This element needs more improvements and testing
|
|
8
|
+
|
|
8
9
|
type DragDropImagesTypes = {
|
|
9
10
|
/** The text label above the component. Consistant with the other form input fields */
|
|
10
11
|
label?: string
|
|
@@ -26,6 +27,8 @@ type DragDropImagesTypes = {
|
|
|
26
27
|
maxFileSize: any
|
|
27
28
|
tooManyFiles: any
|
|
28
29
|
fileTooLarge: any
|
|
30
|
+
acceptedFileTypes: any
|
|
31
|
+
invalidFileType: any
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -46,7 +49,7 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
|
|
|
46
49
|
}) => {
|
|
47
50
|
const [cmp, setCmp] = useState(0)
|
|
48
51
|
const [max, setMax] = useState<any>(0)
|
|
49
|
-
|
|
52
|
+
|
|
50
53
|
const {
|
|
51
54
|
getRootProps,
|
|
52
55
|
getInputProps,
|
|
@@ -84,6 +87,12 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
|
|
|
84
87
|
acceptedFiles.splice(0, acceptedFiles.length)
|
|
85
88
|
setFiles([])
|
|
86
89
|
}
|
|
90
|
+
|
|
91
|
+
const clearAllFiles = () => {
|
|
92
|
+
acceptedFiles.length = 0
|
|
93
|
+
setFiles([])
|
|
94
|
+
}
|
|
95
|
+
|
|
87
96
|
useEffect(() => {
|
|
88
97
|
if (maxSize > 0) {
|
|
89
98
|
const k = 1024
|
|
@@ -96,16 +105,44 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
|
|
|
96
105
|
}
|
|
97
106
|
}, [maxSize])
|
|
98
107
|
const errs = fileRejections.map((rej, i) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
switch (rej.errors[0].code) {
|
|
109
|
+
case "file-too-large":
|
|
110
|
+
return (
|
|
111
|
+
<HawaAlert
|
|
112
|
+
text={rej.file.name}
|
|
113
|
+
title={texts.fileTooLarge}
|
|
114
|
+
severity="error"
|
|
115
|
+
/>
|
|
116
|
+
)
|
|
117
|
+
case "too-many-files":
|
|
118
|
+
return (
|
|
119
|
+
<HawaAlert
|
|
120
|
+
text={rej.file.name}
|
|
121
|
+
title={texts.tooManyFiles}
|
|
122
|
+
severity="error"
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
case "file-invalid-type":
|
|
126
|
+
return (
|
|
127
|
+
<HawaAlert
|
|
128
|
+
text={rej.file.name}
|
|
129
|
+
title={texts.invalidFileType}
|
|
130
|
+
severity="error"
|
|
131
|
+
/>
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
default:
|
|
135
|
+
return (
|
|
136
|
+
<HawaAlert
|
|
137
|
+
text={rej.file.name}
|
|
138
|
+
title={rej.errors[0].code}
|
|
139
|
+
severity="error"
|
|
140
|
+
/>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
106
143
|
})
|
|
107
144
|
const thumbs = files?.map((file: any, index: any) => (
|
|
108
|
-
<div className="relative
|
|
145
|
+
<div className="relative rounded">
|
|
109
146
|
<button
|
|
110
147
|
onClick={(e) => {
|
|
111
148
|
e.stopPropagation()
|
|
@@ -114,7 +151,7 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
|
|
|
114
151
|
onDeleteFile(file)
|
|
115
152
|
}}
|
|
116
153
|
type="button"
|
|
117
|
-
className="absolute left-0 ml-auto inline-flex items-center rounded rounded-bl-none rounded-tr-none bg-gray-900 p-1.5 text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
|
|
154
|
+
className="absolute left-0 ml-auto inline-flex items-center rounded-inner rounded-bl-none rounded-tr-none bg-gray-900 p-1.5 text-sm text-gray-400 transition-all hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
|
|
118
155
|
data-modal-toggle="defaultModal"
|
|
119
156
|
>
|
|
120
157
|
<svg
|
|
@@ -160,63 +197,56 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
|
|
|
160
197
|
</div>
|
|
161
198
|
)}
|
|
162
199
|
<div
|
|
163
|
-
{...getRootProps({})}
|
|
164
200
|
className={clsx(
|
|
165
201
|
"flex flex-col justify-center rounded border border-dashed border-black transition-all hover:bg-gray-100 ",
|
|
166
202
|
isDragActive ? "bg-layoutPrimary-500" : "bg-white"
|
|
167
203
|
)}
|
|
168
204
|
>
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
<
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
onClearFiles(acceptedFiles)
|
|
183
|
-
}}
|
|
205
|
+
<div {...getRootProps({})}>
|
|
206
|
+
<p {...getInputProps()} />
|
|
207
|
+
<div className="flex flex-col items-center justify-center gap-2 pt-4 text-center">
|
|
208
|
+
<svg
|
|
209
|
+
stroke="currentColor"
|
|
210
|
+
fill="none"
|
|
211
|
+
stroke-width="2"
|
|
212
|
+
viewBox="0 0 24 24"
|
|
213
|
+
stroke-linecap="round"
|
|
214
|
+
stroke-linejoin="round"
|
|
215
|
+
height="1.5em"
|
|
216
|
+
width="1.5em"
|
|
217
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
184
218
|
>
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
219
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
220
|
+
<path d="M19 11v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path>
|
|
221
|
+
<path d="M13 13l9 3l-4 2l-2 4l-3 -9"></path>
|
|
222
|
+
<path d="M3 3l0 .01"></path>
|
|
223
|
+
<path d="M7 3l0 .01"></path>
|
|
224
|
+
<path d="M11 3l0 .01"></path>
|
|
225
|
+
<path d="M15 3l0 .01"></path>
|
|
226
|
+
<path d="M3 7l0 .01"></path>
|
|
227
|
+
<path d="M3 11l0 .01"></path>
|
|
228
|
+
<path d="M3 15l0 .01"></path>
|
|
229
|
+
</svg>
|
|
230
|
+
{<texts.clickHereToUpload />}
|
|
231
|
+
</div>
|
|
232
|
+
<div className="pt-2 text-center text-xs">
|
|
233
|
+
{texts.acceptedFileTypes} {accept.split(",")}
|
|
234
|
+
</div>
|
|
235
|
+
<div className="pb-2 pt-1 text-center text-xs">
|
|
236
|
+
{texts.maxFileSize} {max}
|
|
237
|
+
</div>
|
|
188
238
|
</div>
|
|
189
|
-
{
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}}
|
|
197
|
-
className="rounded-lg border-red-500"
|
|
198
|
-
>
|
|
239
|
+
{acceptedFiles.length > 0 && (
|
|
240
|
+
<div className="flex justify-center rounded-lg p-2 ">
|
|
241
|
+
<HawaButton onClick={clearAllFiles}>Clear All</HawaButton>
|
|
242
|
+
</div>
|
|
243
|
+
)}
|
|
244
|
+
{acceptedFiles.length > 0 && thumbs && showPreview ? (
|
|
245
|
+
<aside className="flex flex-row flex-wrap justify-center gap-2 rounded-lg p-2">
|
|
199
246
|
{thumbs}
|
|
200
247
|
</aside>
|
|
201
248
|
) : null}
|
|
202
|
-
<div className="px-4">
|
|
203
|
-
{fileRejections[0]?.errors[0]?.code === "too-many-files" ? (
|
|
204
|
-
<HawaAlert
|
|
205
|
-
title={texts.errorUploading}
|
|
206
|
-
text={texts.tooManyFiles}
|
|
207
|
-
severity="error"
|
|
208
|
-
/>
|
|
209
|
-
) : fileRejections[0]?.errors[0]?.code === "file-too-large" ? (
|
|
210
|
-
<HawaAlert
|
|
211
|
-
title={texts.errorUploading}
|
|
212
|
-
text={texts.fileTooLarge}
|
|
213
|
-
severity="error"
|
|
214
|
-
/>
|
|
215
|
-
) : (
|
|
216
|
-
errs
|
|
217
|
-
)}
|
|
218
|
-
</div>
|
|
219
|
-
{}
|
|
249
|
+
<div className="px-4">{fileRejections[0]?.errors[0]?.code && errs}</div>
|
|
220
250
|
</div>
|
|
221
251
|
</div>
|
|
222
252
|
)
|
|
@@ -222,8 +222,17 @@ export const HawaButton: FC<ButtonProps> = ({
|
|
|
222
222
|
</button>
|
|
223
223
|
)}
|
|
224
224
|
{badge && (
|
|
225
|
-
<div
|
|
226
|
-
{
|
|
225
|
+
<div
|
|
226
|
+
className={clsx(
|
|
227
|
+
typeof badge === "boolean"
|
|
228
|
+
? "h-5 w-5"
|
|
229
|
+
: typeof badge === "string"
|
|
230
|
+
? "h-5 w-7"
|
|
231
|
+
: "h-6 w-6",
|
|
232
|
+
"absolute -right-2 select-none -top-2 inline-flex items-center justify-center rounded-full border-2 border-white bg-red-500 text-[9px] font-bold text-white dark:border-gray-900"
|
|
233
|
+
)}
|
|
234
|
+
>
|
|
235
|
+
{typeof badge === "number" && badge > 100 ? "+99" : badge}
|
|
227
236
|
</div>
|
|
228
237
|
)}
|
|
229
238
|
</div>
|
|
@@ -2,49 +2,174 @@ import React, { useState, FC } from "react"
|
|
|
2
2
|
import clsx from "clsx"
|
|
3
3
|
|
|
4
4
|
type RadioTypes = {
|
|
5
|
+
orientation?: "vertical" | "horizontal"
|
|
6
|
+
design?: "default" | "tabs" | "cards" | "bordered"
|
|
5
7
|
options?: [
|
|
6
8
|
{
|
|
7
9
|
value: any
|
|
8
10
|
label: any
|
|
11
|
+
disabled?: any
|
|
12
|
+
sublabel?: any
|
|
13
|
+
beforeIcon?: any
|
|
14
|
+
afterIcon?: any
|
|
9
15
|
}
|
|
10
16
|
]
|
|
11
17
|
onChangeTab?: any
|
|
12
18
|
defaultValue?: any
|
|
13
19
|
}
|
|
14
|
-
export const HawaRadio: FC<RadioTypes> = (
|
|
20
|
+
export const HawaRadio: FC<RadioTypes> = ({
|
|
21
|
+
design = "default",
|
|
22
|
+
orientation = "horizontal",
|
|
23
|
+
...props
|
|
24
|
+
}) => {
|
|
15
25
|
const [selectedOption, setSelectedOption] = useState(props.defaultValue)
|
|
16
26
|
let activeTabStyle =
|
|
17
27
|
"inline-block py-2 px-4 w-full text-white bg-buttonPrimary-500 rounded active"
|
|
18
28
|
let inactiveTabStyle =
|
|
19
29
|
"inline-block py-2 px-4 w-full bg-gray-100 rounded hover:text-gray-900 hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-white"
|
|
30
|
+
let orientationStyle = {
|
|
31
|
+
horizontal: "flex flex-row",
|
|
32
|
+
vertical: "flex flex-col",
|
|
33
|
+
}
|
|
34
|
+
switch (design) {
|
|
35
|
+
case "tabs":
|
|
36
|
+
return (
|
|
37
|
+
<div>
|
|
38
|
+
<ul
|
|
39
|
+
className={clsx(
|
|
40
|
+
props.options?.length > 2
|
|
41
|
+
? "flex-wrap xs:max-w-full xs:flex-nowrap"
|
|
42
|
+
: "",
|
|
43
|
+
" max-w-fit whitespace-nowrap rounded bg-gray-100 text-center text-sm font-medium text-gray-500 dark:text-gray-400",
|
|
44
|
+
orientationStyle[orientation]
|
|
45
|
+
)}
|
|
46
|
+
>
|
|
47
|
+
{props.options?.map((opt: any, o) => (
|
|
48
|
+
<li className="w-full" key={o}>
|
|
49
|
+
<button
|
|
50
|
+
aria-current="page"
|
|
51
|
+
onClick={() => {
|
|
52
|
+
setSelectedOption(opt.value)
|
|
53
|
+
props.onChangeTab(opt.value)
|
|
54
|
+
}}
|
|
55
|
+
className={
|
|
56
|
+
selectedOption === opt.value
|
|
57
|
+
? activeTabStyle
|
|
58
|
+
: inactiveTabStyle
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
{opt.label}
|
|
62
|
+
</button>
|
|
63
|
+
</li>
|
|
64
|
+
))}
|
|
65
|
+
</ul>
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
case "bordered":
|
|
69
|
+
return (
|
|
70
|
+
<div className={clsx(orientationStyle[orientation], "gap-4")}>
|
|
71
|
+
{props.options.map((opt, i) => (
|
|
72
|
+
<div className="rounded border border-gray-200 ">
|
|
73
|
+
<div
|
|
74
|
+
className="radio-item radio-item-bordered flex items-center transition-all"
|
|
75
|
+
key={i + 1}
|
|
76
|
+
>
|
|
77
|
+
<input
|
|
78
|
+
disabled={opt.disabled}
|
|
79
|
+
id={opt.value.toString()}
|
|
80
|
+
type="radio"
|
|
81
|
+
value={opt.value}
|
|
82
|
+
name="bordered-radio"
|
|
83
|
+
// className="h-4 w-4 border-gray-300 "
|
|
84
|
+
/>
|
|
85
|
+
<label
|
|
86
|
+
htmlFor={opt.value.toString()}
|
|
87
|
+
className={clsx(
|
|
88
|
+
"ml-2 w-full p-4 pl-3 text-sm font-medium",
|
|
89
|
+
opt.disabled ? "opacity-50" : "cursor-pointer text-gray-900"
|
|
90
|
+
)}
|
|
91
|
+
>
|
|
92
|
+
{opt.label}
|
|
93
|
+
</label>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
))}
|
|
97
|
+
</div>
|
|
98
|
+
)
|
|
99
|
+
case "cards":
|
|
100
|
+
return (
|
|
101
|
+
<ul className={clsx(orientationStyle[orientation], "gap-4")}>
|
|
102
|
+
{props.options?.map((opt: any, o) => (
|
|
103
|
+
<li>
|
|
104
|
+
<input
|
|
105
|
+
type="radio"
|
|
106
|
+
id={opt.value.toString()}
|
|
107
|
+
name="cards-radio"
|
|
108
|
+
value={opt.value.toString()}
|
|
109
|
+
className="peer hidden"
|
|
110
|
+
required
|
|
111
|
+
/>
|
|
112
|
+
<label
|
|
113
|
+
htmlFor={opt.value.toString()}
|
|
114
|
+
className="inline-flex h-full w-full cursor-pointer items-center justify-between rounded-lg border border-gray-200 bg-white p-5 text-gray-500 hover:bg-gray-100 hover:text-gray-600 peer-checked:border-blue-600 peer-checked:text-blue-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:peer-checked:text-blue-500"
|
|
115
|
+
>
|
|
116
|
+
<div className="block h-full w-full">
|
|
117
|
+
<div className="w-full text-lg font-semibold">
|
|
118
|
+
{opt.label}
|
|
119
|
+
</div>
|
|
120
|
+
<div className="w-full">{opt.sublabel}</div>
|
|
121
|
+
</div>
|
|
122
|
+
{/* <svg
|
|
123
|
+
className="ml-3 h-5 w-5 "
|
|
124
|
+
aria-hidden="true"
|
|
125
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
126
|
+
fill="none"
|
|
127
|
+
viewBox="0 0 14 10"
|
|
128
|
+
>
|
|
129
|
+
<path
|
|
130
|
+
stroke="currentColor"
|
|
131
|
+
stroke-linecap="round"
|
|
132
|
+
stroke-linejoin="round"
|
|
133
|
+
stroke-width="2"
|
|
134
|
+
d="M1 5h12m0 0L9 1m4 4L9 9"
|
|
135
|
+
/>
|
|
136
|
+
</svg> */}
|
|
137
|
+
</label>
|
|
138
|
+
</li>
|
|
139
|
+
))}
|
|
140
|
+
</ul>
|
|
141
|
+
)
|
|
20
142
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"flex max-w-fit flex-row whitespace-nowrap rounded bg-gray-100 text-center text-sm font-medium text-gray-500 dark:text-gray-400"
|
|
29
|
-
)}
|
|
30
|
-
>
|
|
31
|
-
{props.options?.map((opt: any, o) => (
|
|
32
|
-
<li className="w-full" key={o}>
|
|
33
|
-
<button
|
|
34
|
-
aria-current="page"
|
|
35
|
-
onClick={() => {
|
|
36
|
-
setSelectedOption(opt.value)
|
|
37
|
-
props.onChangeTab(opt.value)
|
|
38
|
-
}}
|
|
39
|
-
className={
|
|
40
|
-
selectedOption === opt.value ? activeTabStyle : inactiveTabStyle
|
|
41
|
-
}
|
|
143
|
+
default:
|
|
144
|
+
return (
|
|
145
|
+
<div className={orientationStyle[orientation]}>
|
|
146
|
+
{props.options.map((opt, i) => (
|
|
147
|
+
<div
|
|
148
|
+
className="radio-item radio-item-default mb-4 flex items-center transition-all"
|
|
149
|
+
key={i + 1}
|
|
42
150
|
>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
151
|
+
<input
|
|
152
|
+
disabled={opt.disabled}
|
|
153
|
+
id={opt.value.toString()}
|
|
154
|
+
type="radio"
|
|
155
|
+
value={opt.value}
|
|
156
|
+
name="default-radio"
|
|
157
|
+
// className="h-4 w-4 border-gray-300 "
|
|
158
|
+
/>
|
|
159
|
+
<label
|
|
160
|
+
htmlFor={opt.value.toString()}
|
|
161
|
+
className={clsx(
|
|
162
|
+
"ml-2 text-sm font-medium ",
|
|
163
|
+
opt.disabled
|
|
164
|
+
? "text-gray-400"
|
|
165
|
+
: "cursor-pointer text-gray-900"
|
|
166
|
+
)}
|
|
167
|
+
>
|
|
168
|
+
{opt.label}
|
|
169
|
+
</label>
|
|
170
|
+
</div>
|
|
171
|
+
))}
|
|
172
|
+
</div>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
50
175
|
}
|