@sikka/hawa 0.1.26 → 0.1.28

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sikka/hawa",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "SaaS Oriented UI Kit",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.es.js",
@@ -109,6 +109,7 @@
109
109
  "@radix-ui/react-dropdown-menu": "^2.0.5",
110
110
  "@radix-ui/react-label": "^2.0.2",
111
111
  "@radix-ui/react-popover": "^1.0.6",
112
+ "@radix-ui/react-separator": "^1.0.3",
112
113
  "@radix-ui/react-tabs": "^1.0.4",
113
114
  "@radix-ui/react-tooltip": "^1.0.6",
114
115
  "class-variance-authority": "^0.7.0",
@@ -1,5 +1,5 @@
1
1
  import React, { useState, FC } from "react"
2
- import { HawaTabs } from "../../elements"
2
+ import { HawaRadio } from "../../elements"
3
3
  import { Tooltip } from "../../elements/Tooltip"
4
4
 
5
5
  const CheckMark = () => (
@@ -65,29 +65,23 @@ type ComparingPlansTypes = {
65
65
  direction?: "rtl" | "ltr"
66
66
  }
67
67
  export const ComparingPlans: FC<ComparingPlansTypes> = (props) => {
68
- const [currentCurrency, setCurrentCurrency] = useState("SAR")
68
+ const [currentCurrency, setCurrentCurrency] = useState("sar")
69
69
  const [currentCycle, setCurrentCycle] = useState("month")
70
70
 
71
71
  return (
72
72
  <div id="detailed-pricing" className="w-full overflow-x-auto">
73
73
  <div className="mb-2 flex w-full justify-between">
74
- <HawaTabs
75
- pill
74
+ <HawaRadio
75
+ design="tabs"
76
76
  defaultValue={currentCycle}
77
77
  options={props.billingCycles}
78
- onChangeTab={(e: any) => {
79
- // setCurrentCycle(e.label)
80
- props.onCycleChange(e)
81
- }}
78
+ onChangeTab={(e: any) => props.onCycleChange(e)}
82
79
  />
83
- <HawaTabs
84
- pill
80
+ <HawaRadio
81
+ design="tabs"
85
82
  defaultValue={currentCurrency}
86
83
  options={props.currencies}
87
- onChangeTab={(e: any) => {
88
- // setCurrentCurrency(e.label)
89
- props.onCurrencyChange(e)
90
- }}
84
+ onChangeTab={(e: any) => props.onCurrencyChange(e)}
91
85
  />
92
86
  </div>
93
87
  <div className=" overflow-hidden rounded">
@@ -1,5 +1,5 @@
1
1
  import React, { FC } from "react"
2
- import { HawaPricingCard, HawaTabs } from "../../elements"
2
+ import { HawaPricingCard, HawaRadio } from "../../elements"
3
3
 
4
4
  type PricingPlansTypes = {
5
5
  plans: [
@@ -46,14 +46,14 @@ export const PricingPlans: FC<PricingPlansTypes> = (props) => {
46
46
  return (
47
47
  <div>
48
48
  <div className="mb-2 flex w-full justify-between">
49
- <HawaTabs
50
- pill
49
+ <HawaRadio
50
+ design="tabs"
51
51
  defaultValue={props.currentCycle}
52
52
  options={props.billingCycles}
53
53
  onChangeTab={(e: any) => props.onCycleChange(e)}
54
54
  />
55
- <HawaTabs
56
- pill
55
+ <HawaRadio
56
+ design="tabs"
57
57
  defaultValue={props.currentCurrency}
58
58
  options={props.currencies}
59
59
  onChangeTab={(e: any) => props.onCurrencyChange(e)}
@@ -1,5 +1,5 @@
1
1
  import React, { useState, FC } from "react"
2
- import clsx from "clsx"
2
+ import { cn } from "../util"
3
3
 
4
4
  // TODO: fix wrapping issue when small screen
5
5
 
@@ -62,13 +62,13 @@ export const HawaTabs: FC<TabsTypes> = ({
62
62
  return (
63
63
  <div
64
64
  dir={direction}
65
- className={clsx(
65
+ className={cn(
66
66
  containerStyle[orientation],
67
67
  props.options[selectedOption] ? "border-b-2" : "border-b-0"
68
68
  )}
69
69
  >
70
70
  <ul
71
- className={clsx(
71
+ className={cn(
72
72
  "w-full border-primary",
73
73
  marginBetween
74
74
  ? orientation === "vertical"
@@ -98,35 +98,33 @@ export const HawaTabs: FC<TabsTypes> = ({
98
98
  )}
99
99
  >
100
100
  {props.options?.map((opt: any, o) => (
101
- <li key={o}>
102
- <button
103
- aria-current="page"
104
- onClick={() => {
105
- setSelectedOption(opt.value)
106
- props?.onChangeTab(opt)
107
- }}
108
- className={clsx(
109
- "flex flex-row items-center gap-2 ",
110
- opt.value === selectedOption
111
- ? // props.options[selectedOption].value === opt.value
112
- [
113
- activeTabStyle[orientation],
114
- direction === "rtl" ? "rounded-r" : "rounded-l",
115
- ]
116
- : inactiveTabStyle[orientation],
117
- "w-full transition-all",
118
- pill
119
- ? "rounded"
120
- : orientation === "vertical"
121
- ? "rounded rounded-bl-none rounded-tl-none"
122
- : "rounded sm:rounded-b-none"
123
- // direction === "rtl" ? "bg-yellow-400" : "bg-yellow-400"
124
- )}
125
- >
126
- {opt.icon}
127
- {opt.label}
128
- </button>
129
- </li>
101
+ <button
102
+ key={o}
103
+ aria-current="page"
104
+ onClick={() => {
105
+ setSelectedOption(opt.value)
106
+ props?.onChangeTab(opt)
107
+ }}
108
+ className={cn(
109
+ opt.value === selectedOption
110
+ ? // props.options[selectedOption].value === opt.value
111
+ [
112
+ activeTabStyle[orientation],
113
+ direction === "rtl" ? "rounded-r" : "rounded-l",
114
+ ]
115
+ : inactiveTabStyle[orientation],
116
+ pill
117
+ ? "rounded"
118
+ : orientation === "vertical"
119
+ ? "rounded rounded-bl-none rounded-tl-none"
120
+ : "rounded sm:rounded-b-none",
121
+ // direction === "rtl" ? "bg-yellow-400" : "bg-yellow-400"
122
+ "flex w-fit flex-row items-center gap-2 transition-all "
123
+ )}
124
+ >
125
+ {opt.icon}
126
+ {opt.label}
127
+ </button>
130
128
  ))}
131
129
  </ul>
132
130
 
@@ -134,7 +132,7 @@ export const HawaTabs: FC<TabsTypes> = ({
134
132
  {props.options.map((tab, i) => (
135
133
  <div
136
134
  key={i}
137
- className={clsx(selectedOption === tab.value ? "" : "hidden")}
135
+ className={cn(selectedOption === tab.value ? "" : "hidden")}
138
136
  >
139
137
  {tab.content}
140
138
  </div>
@@ -1,6 +1,6 @@
1
1
  import React, { FC, PropsWithRef } from "react"
2
- import clsx from "clsx"
3
2
  import { Label } from "./Label"
3
+ import { cn } from "../util"
4
4
 
5
5
  // TODO: make icon based on direction
6
6
  // TODO: Preferebly use context to pass direction rtl | ltr
@@ -51,98 +51,40 @@ export const HawaTextField: FC<TextFieldTypes> = ({
51
51
  full: "w-full",
52
52
  }
53
53
 
54
- let defaultStyle = "flex max-h-fit flex-col justify-center gap-2"
54
+ let defaultStyle = "flex max-h-fit flex-col justify-center gap-1"
55
55
  let defaultInputStyle =
56
- "block w-full rounded border bg-background p-2 text-sm text-black dark:text-white focus:border-blue-500 focus:ring-blue-500"
56
+ "block w-full rounded border transition-all bg-background p-2 text-sm text-black dark:text-white focus:border-blue-500 focus:ring-blue-500"
57
57
  let previewInputStyle =
58
58
  "block w-full rounded bg-gray-50 p-2 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
59
59
  // "mb-0 block w-full rounded border border-gray-300 bg-gray-50 p-2 text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500",
60
60
 
61
61
  return (
62
- <div
63
- className={clsx(defaultStyle, marginStyles[margin], widthStyles[width])}
64
- >
65
- {props.label && (
66
- // <label
67
- // // htmlFor="first_name"
68
- // className="mb-2 block text-sm font-medium "
69
- // >
70
- // {props.label}
71
- // </label>
72
- <Label>{props.label}</Label>
73
- )}
74
- {preview ? (
75
- <>
76
- {props.multiline ? (
77
- <textarea
78
- id="message"
79
- rows={4}
80
- className={defaultInputStyle}
81
- onChange={props.onChange}
82
- type={props.type}
83
- aria-label={props.label}
84
- placeholder={props.placeholder}
85
- defaultValue={props.defaultValue}
86
- value={props.value}
87
- {...props}
88
- />
89
- ) : (
90
- <div className="relative">
91
- {props.icon && (
92
- <div className="absolute left-3 top-1/2 -translate-y-1/2">
93
- {props.icon}
94
- </div>
95
- )}
96
- <input
97
- {...props}
98
- disabled={preview}
99
- className={clsx(previewInputStyle, props.icon ? "pl-10" : "")}
100
- />
101
- {/* <div
102
- // {...props}
103
- className={clsx(previewInputStyle, props.icon ? "pl-10" : "")}
104
- >
105
- {props.value}
106
- </div> */}
107
- </div>
108
- )}
109
- </>
110
- ) : (
111
- <>
112
- {props.multiline ? (
113
- <textarea
114
- id="message"
115
- rows={4}
116
- className={defaultInputStyle}
117
- onChange={props.onChange}
118
- type={props.type}
119
- aria-label={props.label}
120
- placeholder={props.placeholder}
121
- defaultValue={props.defaultValue}
122
- value={props.value}
123
- {...props}
124
- />
125
- ) : (
126
- <div className="relative">
127
- {props.icon && (
128
- <div className="absolute left-3 top-1/2 -translate-y-1/2">
129
- {props.icon}
130
- </div>
131
- )}
132
- <input
133
- {...props}
134
- className={clsx(defaultInputStyle, props.icon ? "pl-10" : "")}
135
- />
62
+ <div className={cn(defaultStyle, marginStyles[margin], widthStyles[width])}>
63
+ {props.label && <Label>{props.label}</Label>}
64
+ <>
65
+ <div className="relative">
66
+ {props.icon && (
67
+ <div className="absolute left-3 top-1/2 -translate-y-1/2">
68
+ {props.icon}
136
69
  </div>
137
70
  )}
71
+ <input
72
+ {...props}
73
+ className={cn(
74
+ defaultInputStyle,
75
+ props.icon && "pl-10",
76
+ preview && "border-transparent px-0"
77
+ )}
78
+ disabled={preview}
79
+ />
80
+ </div>
138
81
 
139
- {props.helpertext ? (
140
- <p className="mb-0 mt-1 text-xs text-red-600 dark:text-red-500">
141
- {props.helpertext}
142
- </p>
143
- ) : null}
144
- </>
145
- )}
82
+ {props.helpertext ? (
83
+ <p className="mb-0 mt-1 text-xs text-red-600 dark:text-red-500">
84
+ {props.helpertext}
85
+ </p>
86
+ ) : null}
87
+ </>
146
88
  </div>
147
89
  )
148
90
  }
@@ -3,17 +3,22 @@ import * as React from "react"
3
3
  import { cn } from "../util"
4
4
 
5
5
  export interface InputProps
6
- extends React.InputHTMLAttributes<HTMLInputElement> {}
6
+ extends React.InputHTMLAttributes<HTMLInputElement> {
7
+ preview?: boolean
8
+ }
7
9
 
8
10
  const Input = React.forwardRef<HTMLInputElement, InputProps>(
9
- ({ className, type, ...props }, ref) => {
11
+ ({ className, preview, type, ...props }, ref) => {
10
12
  return (
11
13
  <input
12
14
  type={type}
13
15
  className={cn(
14
16
  "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
15
- className
17
+ className,
18
+ preview &&
19
+ " disabled:cursor-default disabled:opacity-100 border-opacity-25 "
16
20
  )}
21
+ disabled={preview}
17
22
  ref={ref}
18
23
  {...props}
19
24
  />
@@ -0,0 +1,29 @@
1
+ import * as React from "react"
2
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
3
+
4
+ import { cn } from "../util"
5
+
6
+ const Separator = React.forwardRef<
7
+ React.ElementRef<typeof SeparatorPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
9
+ >(
10
+ (
11
+ { className, orientation = "horizontal", decorative = true, ...props },
12
+ ref
13
+ ) => (
14
+ <SeparatorPrimitive.Root
15
+ ref={ref}
16
+ decorative={decorative}
17
+ orientation={orientation}
18
+ className={cn(
19
+ "shrink-0 bg-border",
20
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ )
27
+ Separator.displayName = SeparatorPrimitive.Root.displayName
28
+
29
+ export { Separator }
@@ -3,36 +3,80 @@ import * as TabsPrimitive from "@radix-ui/react-tabs"
3
3
 
4
4
  import { cn } from "../util"
5
5
 
6
- const Tabs = TabsPrimitive.Root
6
+ const TabsContext = React.createContext<{
7
+ orientation?: "vertical" | "horizontal"
8
+ }>({
9
+ orientation: "vertical", // default value
10
+ })
7
11
 
8
- const TabsList = React.forwardRef<
9
- React.ElementRef<typeof TabsPrimitive.List>,
10
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
11
- >(({ className, ...props }, ref) => (
12
- <TabsPrimitive.List
12
+ // const Tabs = TabsPrimitive.Root
13
+ type TabsRootProps = React.ComponentPropsWithoutRef<
14
+ typeof TabsPrimitive.Root
15
+ > & {
16
+ orientation?: "vertical" | "horizontal"
17
+ }
18
+
19
+ const Tabs = React.forwardRef<
20
+ React.ElementRef<typeof TabsPrimitive.Root>,
21
+ TabsRootProps
22
+ >(({ className, orientation, ...props }, ref) => (
23
+ <TabsPrimitive.Root
13
24
  ref={ref}
14
25
  className={cn(
15
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
16
- className
26
+ className,
27
+ "flex gap-2",
28
+ orientation === "horizontal" ? "flex-row" : "flex-col"
17
29
  )}
18
30
  {...props}
19
- />
31
+ >
32
+ <TabsContext.Provider value={{ orientation }}>
33
+ {props.children}
34
+ </TabsContext.Provider>
35
+ </TabsPrimitive.Root>
20
36
  ))
37
+ Tabs.displayName = TabsPrimitive.Root.displayName
38
+
39
+ // type TabsListProps = React.ComponentPropsWithoutRef<
40
+ // typeof TabsPrimitive.List
41
+ // > & {
42
+ // // orientation?: "vertical" | "horizontal"
43
+ // }
44
+
45
+ const TabsList = React.forwardRef<
46
+ React.ElementRef<typeof TabsPrimitive.List>,
47
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
48
+ >(({ className, ...props }, ref) => {
49
+ const { orientation } = React.useContext(TabsContext)
50
+
51
+ return (
52
+ <TabsPrimitive.List
53
+ ref={ref}
54
+ className={cn(
55
+ "flex w-fit flex-wrap items-center justify-start gap-1 rounded bg-muted p-1 text-muted-foreground ",
56
+ orientation === "horizontal" ? "flex-col" : "flex-row",
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ )
62
+ })
21
63
  TabsList.displayName = TabsPrimitive.List.displayName
22
64
 
23
65
  const TabsTrigger = React.forwardRef<
24
66
  React.ElementRef<typeof TabsPrimitive.Trigger>,
25
67
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
26
- >(({ className, ...props }, ref) => (
27
- <TabsPrimitive.Trigger
28
- ref={ref}
29
- className={cn(
30
- "inline-flex select-none items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm",
31
- className
32
- )}
33
- {...props}
34
- />
35
- ))
68
+ >(({ className, ...props }, ref) => {
69
+ return (
70
+ <TabsPrimitive.Trigger
71
+ ref={ref}
72
+ className={cn(
73
+ "inline-flex w-full flex-1 select-none items-center justify-center whitespace-nowrap rounded border px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm ",
74
+ className
75
+ )}
76
+ {...props}
77
+ />
78
+ )
79
+ })
36
80
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
37
81
 
38
82
  const TabsContent = React.forwardRef<
@@ -42,7 +86,7 @@ const TabsContent = React.forwardRef<
42
86
  <TabsPrimitive.Content
43
87
  ref={ref}
44
88
  className={cn(
45
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
89
+ "w-full ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
46
90
  className
47
91
  )}
48
92
  {...props}
@@ -1,21 +1,27 @@
1
1
  import * as React from "react"
2
2
 
3
3
  import { cn } from "../util"
4
+ import { Label } from "./Label"
4
5
 
5
6
  export interface TextareaProps
6
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
7
+ extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
8
+ label?: string
9
+ }
7
10
 
8
11
  const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
9
- ({ className, ...props }, ref) => {
12
+ ({ className, label, ...props }, ref) => {
10
13
  return (
11
- <textarea
12
- className={cn(
13
- "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
14
- className
15
- )}
16
- ref={ref}
17
- {...props}
18
- />
14
+ <>
15
+ {label && <Label htmlFor={props.id}>{label}</Label>}
16
+ <textarea
17
+ className={cn(
18
+ "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
19
+ className
20
+ )}
21
+ ref={ref}
22
+ {...props}
23
+ />
24
+ </>
19
25
  )
20
26
  }
21
27
  )
@@ -65,3 +65,5 @@ export * from "./InterfaceSettings"
65
65
  export * from "./DropdownMenu"
66
66
  export * from "./Popover"
67
67
  export * from "./Tabs"
68
+ export * from "./Textarea"
69
+ export * from "./Separator"
package/src/styles.css CHANGED
@@ -1235,6 +1235,9 @@ video {
1235
1235
  .w-\[190px\] {
1236
1236
  width: 190px;
1237
1237
  }
1238
+ .w-\[1px\] {
1239
+ width: 1px;
1240
+ }
1238
1241
  .w-\[25px\] {
1239
1242
  width: 25px;
1240
1243
  }
@@ -1548,9 +1551,6 @@ video {
1548
1551
  .gap-8 {
1549
1552
  gap: 2rem;
1550
1553
  }
1551
- .gap-9 {
1552
- gap: 2.25rem;
1553
- }
1554
1554
  .gap-\[2px\] {
1555
1555
  gap: 2px;
1556
1556
  }
@@ -1859,6 +1859,9 @@ video {
1859
1859
  .border-b-primary {
1860
1860
  border-bottom-color: hsl(var(--primary));
1861
1861
  }
1862
+ .border-opacity-25 {
1863
+ --tw-border-opacity: 0.25;
1864
+ }
1862
1865
  .bg-background {
1863
1866
  background-color: hsl(var(--background));
1864
1867
  }
@@ -1890,6 +1893,9 @@ video {
1890
1893
  --tw-bg-opacity: 1;
1891
1894
  background-color: rgb(59 130 246 / var(--tw-bg-opacity));
1892
1895
  }
1896
+ .bg-border {
1897
+ background-color: hsl(var(--border));
1898
+ }
1893
1899
  .bg-buttonPrimary-500 {
1894
1900
  background-color: hsl(var(--button-primary-500));
1895
1901
  }
@@ -2111,6 +2117,10 @@ video {
2111
2117
  .p-\[5px\] {
2112
2118
  padding: 5px;
2113
2119
  }
2120
+ .px-0 {
2121
+ padding-left: 0px;
2122
+ padding-right: 0px;
2123
+ }
2114
2124
  .px-1 {
2115
2125
  padding-left: 0.25rem;
2116
2126
  padding-right: 0.25rem;
@@ -3149,6 +3159,9 @@ body {
3149
3159
  .disabled\:pointer-events-none:disabled {
3150
3160
  pointer-events: none;
3151
3161
  }
3162
+ .disabled\:cursor-default:disabled {
3163
+ cursor: default;
3164
+ }
3152
3165
  .disabled\:cursor-not-allowed:disabled {
3153
3166
  cursor: not-allowed;
3154
3167
  }
@@ -3156,6 +3169,9 @@ body {
3156
3169
  --tw-bg-opacity: 1;
3157
3170
  background-color: rgb(229 231 235 / var(--tw-bg-opacity));
3158
3171
  }
3172
+ .disabled\:opacity-100:disabled {
3173
+ opacity: 1;
3174
+ }
3159
3175
  .disabled\:opacity-50:disabled {
3160
3176
  opacity: 0.5;
3161
3177
  }