@rovula/ui 0.0.8 → 0.0.10

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 (129) hide show
  1. package/dist/cjs/bundle.css +497 -4
  2. package/dist/cjs/bundle.js +1 -1
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/AlertDialog/Alert.stories.d.ts +20 -0
  5. package/dist/cjs/types/components/AlertDialog/AlertDialog.d.ts +20 -0
  6. package/dist/cjs/types/components/Button/Button.styles.d.ts +1 -1
  7. package/dist/cjs/types/components/Checkbox/Checkbox.d.ts +4 -0
  8. package/dist/cjs/types/components/Checkbox/Checkbox.stories.d.ts +308 -0
  9. package/dist/cjs/types/components/Dialog/Dialog.d.ts +19 -0
  10. package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +25 -0
  11. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +26 -0
  12. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
  13. package/dist/cjs/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
  14. package/dist/cjs/types/components/Input/Input.d.ts +5 -0
  15. package/dist/cjs/types/components/Input/Input.stories.d.ts +314 -0
  16. package/dist/cjs/types/components/Label/Label.d.ts +5 -0
  17. package/dist/cjs/types/components/Label/Label.stories.d.ts +286 -0
  18. package/dist/cjs/types/components/RadioGroup/RadioGroup.d.ts +5 -0
  19. package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +299 -0
  20. package/dist/cjs/types/components/Table/Datagrid.d.ts +11 -0
  21. package/dist/cjs/types/components/Table/Table.d.ts +10 -11
  22. package/dist/cjs/types/components/Table/Table.stories.d.ts +283 -0
  23. package/dist/cjs/types/components/Tabs/Tabs.d.ts +7 -5
  24. package/dist/cjs/types/components/Tabs/Tabs.stories.d.ts +49 -0
  25. package/dist/cjs/types/components/TextInput/TextInput.d.ts +3 -2
  26. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +2 -16
  27. package/dist/cjs/types/index.d.ts +8 -2
  28. package/dist/cjs/types/utils/cn.d.ts +2 -0
  29. package/dist/components/AlertDialog/Alert.stories.js +39 -0
  30. package/dist/components/AlertDialog/AlertDialog.js +73 -0
  31. package/dist/components/Button/Button.js +3 -3
  32. package/dist/components/Button/Button.styles.js +1 -1
  33. package/dist/components/Checkbox/Checkbox.js +37 -0
  34. package/dist/components/Checkbox/Checkbox.stories.js +49 -0
  35. package/dist/components/Dialog/Dialog.js +63 -0
  36. package/dist/components/Dialog/Dialog.stories.js +52 -0
  37. package/dist/components/Dropdown/Dropdown.js +58 -0
  38. package/dist/components/{Select/Select.stories.js → Dropdown/Dropdown.stories.js} +8 -11
  39. package/dist/components/Dropdown/Dropdown.styles.js +47 -0
  40. package/dist/components/Input/Input.js +31 -0
  41. package/dist/components/Input/Input.stories.js +37 -0
  42. package/dist/components/Label/Label.js +35 -0
  43. package/dist/components/Label/Label.stories.js +38 -0
  44. package/dist/components/RadioGroup/RadioGroup.js +41 -0
  45. package/dist/components/RadioGroup/RadioGroup.stories.js +44 -0
  46. package/dist/components/Table/Datagrid.js +6 -0
  47. package/dist/components/Table/Table.js +65 -5
  48. package/dist/components/Table/Table.stories.js +32 -0
  49. package/dist/components/Tabs/Tabs.js +10 -4
  50. package/dist/components/Tabs/Tabs.stories.js +60 -0
  51. package/dist/components/TextInput/TextInput.js +3 -3
  52. package/dist/esm/bundle.css +497 -4
  53. package/dist/esm/bundle.js +1 -1
  54. package/dist/esm/bundle.js.map +1 -1
  55. package/dist/esm/types/components/AlertDialog/Alert.stories.d.ts +20 -0
  56. package/dist/esm/types/components/AlertDialog/AlertDialog.d.ts +20 -0
  57. package/dist/esm/types/components/Button/Button.styles.d.ts +1 -1
  58. package/dist/esm/types/components/Checkbox/Checkbox.d.ts +4 -0
  59. package/dist/esm/types/components/Checkbox/Checkbox.stories.d.ts +308 -0
  60. package/dist/esm/types/components/Dialog/Dialog.d.ts +19 -0
  61. package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +25 -0
  62. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +26 -0
  63. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
  64. package/dist/esm/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
  65. package/dist/esm/types/components/Input/Input.d.ts +5 -0
  66. package/dist/esm/types/components/Input/Input.stories.d.ts +314 -0
  67. package/dist/esm/types/components/Label/Label.d.ts +5 -0
  68. package/dist/esm/types/components/Label/Label.stories.d.ts +286 -0
  69. package/dist/esm/types/components/RadioGroup/RadioGroup.d.ts +5 -0
  70. package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +299 -0
  71. package/dist/esm/types/components/Table/Datagrid.d.ts +11 -0
  72. package/dist/esm/types/components/Table/Table.d.ts +10 -11
  73. package/dist/esm/types/components/Table/Table.stories.d.ts +283 -0
  74. package/dist/esm/types/components/Tabs/Tabs.d.ts +7 -5
  75. package/dist/esm/types/components/Tabs/Tabs.stories.d.ts +49 -0
  76. package/dist/esm/types/components/TextInput/TextInput.d.ts +3 -2
  77. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +2 -16
  78. package/dist/esm/types/index.d.ts +8 -2
  79. package/dist/esm/types/utils/cn.d.ts +2 -0
  80. package/dist/index.d.ts +88 -30
  81. package/dist/index.js +8 -2
  82. package/dist/src/theme/global.css +598 -4
  83. package/dist/theme/global.css +57 -0
  84. package/dist/theme/main-preset.js +29 -1
  85. package/dist/theme/presets/colors.js +19 -0
  86. package/dist/utils/cn.js +9 -0
  87. package/package.json +9 -1
  88. package/src/components/AlertDialog/Alert.stories.tsx +67 -0
  89. package/src/components/AlertDialog/AlertDialog.tsx +142 -0
  90. package/src/components/Button/Button.styles.ts +1 -1
  91. package/src/components/Button/Button.tsx +4 -4
  92. package/src/components/Checkbox/Checkbox.stories.tsx +91 -0
  93. package/src/components/Checkbox/Checkbox.tsx +36 -0
  94. package/src/components/Dialog/Dialog.stories.tsx +118 -0
  95. package/src/components/Dialog/Dialog.tsx +119 -0
  96. package/src/components/{Select/Select.stories.tsx → Dropdown/Dropdown.stories.tsx} +11 -14
  97. package/src/components/Dropdown/Dropdown.styles.ts +54 -0
  98. package/src/components/Dropdown/Dropdown.tsx +151 -0
  99. package/src/components/Input/Input.stories.tsx +40 -0
  100. package/src/components/Input/Input.tsx +25 -0
  101. package/src/components/Label/Label.stories.tsx +45 -0
  102. package/src/components/Label/Label.tsx +26 -0
  103. package/src/components/RadioGroup/RadioGroup.stories.tsx +71 -0
  104. package/src/components/RadioGroup/RadioGroup.tsx +59 -0
  105. package/src/components/Table/Datagrid.tsx +36 -0
  106. package/src/components/Table/Table.stories.tsx +79 -0
  107. package/src/components/Table/Table.tsx +116 -35
  108. package/src/components/Tabs/Tabs.stories.tsx +75 -0
  109. package/src/components/Tabs/Tabs.tsx +39 -10
  110. package/src/components/TextInput/TextInput.tsx +11 -2
  111. package/src/index.ts +9 -2
  112. package/src/theme/global.css +57 -0
  113. package/src/theme/main-preset.js +29 -1
  114. package/src/theme/presets/colors.js +19 -0
  115. package/src/utils/cn.ts +6 -0
  116. package/dist/cjs/types/components/Select/Select copy.d.ts +0 -23
  117. package/dist/cjs/types/components/Select/Select.d.ts +0 -23
  118. package/dist/cjs/types/components/Select/Select.stories.d.ts +0 -348
  119. package/dist/cjs/types/components/Select/Select.styles.d.ts +0 -14
  120. package/dist/components/Select/Select copy.js +0 -42
  121. package/dist/components/Select/Select.js +0 -21
  122. package/dist/components/Select/Select.styles.js +0 -100
  123. package/dist/esm/types/components/Select/Select copy.d.ts +0 -23
  124. package/dist/esm/types/components/Select/Select.d.ts +0 -23
  125. package/dist/esm/types/components/Select/Select.stories.d.ts +0 -348
  126. package/dist/esm/types/components/Select/Select.styles.d.ts +0 -14
  127. package/src/components/Select/Select copy.tsx +0 -103
  128. package/src/components/Select/Select.styles.ts +0 -111
  129. package/src/components/Select/Select.tsx +0 -54
@@ -0,0 +1,119 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
5
+
6
+ import { XMarkIcon } from "@heroicons/react/16/solid";
7
+ import { cn } from "@/utils/cn";
8
+
9
+ const Dialog = DialogPrimitive.Root;
10
+
11
+ const DialogTrigger = DialogPrimitive.Trigger;
12
+
13
+ const DialogPortal = DialogPrimitive.Portal;
14
+
15
+ const DialogClose = DialogPrimitive.Close;
16
+
17
+ const DialogOverlay = React.forwardRef<
18
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
19
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
20
+ >(({ className, ...props }, ref) => (
21
+ <DialogPrimitive.Overlay
22
+ ref={ref}
23
+ className={cn(
24
+ "fixed inset-0 z-50 bg-popup-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25
+ className
26
+ )}
27
+ {...props}
28
+ />
29
+ ));
30
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
31
+
32
+ const DialogContent = React.forwardRef<
33
+ React.ElementRef<typeof DialogPrimitive.Content>,
34
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
35
+ >(({ className, children, ...props }, ref) => (
36
+ <DialogPortal>
37
+ <DialogOverlay />
38
+ <DialogPrimitive.Content
39
+ ref={ref}
40
+ className={cn(
41
+ "fixed text-textcolor-grey-dark left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-[var(--popup-rounded)]",
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ {children}
47
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
48
+ <XMarkIcon className="h-4 w-4" />
49
+ <span className="sr-only">Close</span>
50
+ </DialogPrimitive.Close>
51
+ </DialogPrimitive.Content>
52
+ </DialogPortal>
53
+ ));
54
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
55
+
56
+ const DialogHeader = ({
57
+ className,
58
+ ...props
59
+ }: React.HTMLAttributes<HTMLDivElement>) => (
60
+ <div
61
+ className={cn(
62
+ "flex flex-col space-y-2 text-center sm:text-left",
63
+ className
64
+ )}
65
+ {...props}
66
+ />
67
+ );
68
+ DialogHeader.displayName = "DialogHeader";
69
+
70
+ const DialogFooter = ({
71
+ className,
72
+ ...props
73
+ }: React.HTMLAttributes<HTMLDivElement>) => (
74
+ <div
75
+ className={cn(
76
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ );
82
+ DialogFooter.displayName = "DialogFooter";
83
+
84
+ const DialogTitle = React.forwardRef<
85
+ React.ElementRef<typeof DialogPrimitive.Title>,
86
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
87
+ >(({ className, ...props }, ref) => (
88
+ <DialogPrimitive.Title
89
+ ref={ref}
90
+ className={cn("typography-h5 tracking-tight", className)}
91
+ {...props}
92
+ />
93
+ ));
94
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
95
+
96
+ const DialogDescription = React.forwardRef<
97
+ React.ElementRef<typeof DialogPrimitive.Description>,
98
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
99
+ >(({ className, ...props }, ref) => (
100
+ <DialogPrimitive.Description
101
+ ref={ref}
102
+ className={cn("text-sm", className)}
103
+ {...props}
104
+ />
105
+ ));
106
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
107
+
108
+ export {
109
+ Dialog,
110
+ DialogPortal,
111
+ DialogOverlay,
112
+ DialogClose,
113
+ DialogTrigger,
114
+ DialogContent,
115
+ DialogHeader,
116
+ DialogFooter,
117
+ DialogTitle,
118
+ DialogDescription,
119
+ };
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
2
  import type { Meta, StoryObj } from "@storybook/react";
3
- import Select from "./Select";
3
+ import Dropdown from "./Dropdown";
4
4
 
5
5
  // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
6
6
  const meta = {
7
- title: "Components/Select",
8
- component: Select,
7
+ title: "Components/Dropdown",
8
+ component: Dropdown,
9
9
  tags: ["autodocs"],
10
10
  parameters: {
11
11
  // More on how to position stories at: https://storybook.js.org/docs/7.0/react/configure/story-layout
@@ -18,21 +18,18 @@ const meta = {
18
18
  </div>
19
19
  ),
20
20
  ],
21
- } satisfies Meta<typeof Select>;
21
+ } satisfies Meta<typeof Dropdown>;
22
22
 
23
23
  export default meta;
24
24
 
25
- const options = [
26
- { value: "option1", label: "Option 1" },
27
- { value: "option2", label: "Option 2" },
28
- { value: "option3", label: "Option 3" },
29
- { value: "option4", label: "Option 4" },
30
- ];
25
+ const options = new Array(100).fill("").map((__, index) => ({
26
+ value: `option${index + 1}`,
27
+ label: `Option ${index + 1}`,
28
+ }));
31
29
 
32
30
  export const Default = {
33
31
  args: {
34
32
  label: "Choose an option:",
35
- // value: "",
36
33
  fullwidth: true,
37
34
  options,
38
35
  },
@@ -43,9 +40,9 @@ export const Default = {
43
40
  };
44
41
  return (
45
42
  <div className="flex flex-row gap-4 w-full">
46
- <Select id="1" size="lg" options={options} {...args} />
47
- <Select id="2" size="md" options={options} {...args} />
48
- <Select id="3" size="sm" options={options} {...args} />
43
+ <Dropdown id="1" size="lg" options={options} {...args} />
44
+ <Dropdown id="2" size="md" options={options} {...args} />
45
+ <Dropdown id="3" size="sm" options={options} {...args} />
49
46
  </div>
50
47
  );
51
48
  },
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import { cva } from "class-variance-authority";
3
+
4
+ export const iconWrapperVariant = cva(
5
+ ["absolute inset-y-0 right-0 flex items-center justify-center"],
6
+ {
7
+ variants: {
8
+ size: {
9
+ sm: "mr-2",
10
+ md: "mr-3",
11
+ lg: "mr-4",
12
+ },
13
+ },
14
+ defaultVariants: {
15
+ size: "md",
16
+ },
17
+ }
18
+ );
19
+
20
+ export const dropdownIconVariant = cva(["transition-all"], {
21
+ variants: {
22
+ size: {
23
+ sm: "size-[14px]",
24
+ md: "size-5",
25
+ lg: "size-6",
26
+ },
27
+ disabled: {
28
+ true: "fill-input-text-disabled",
29
+ false: "fill-input-text",
30
+ },
31
+ isFocus: {
32
+ true: "fill-input-text-active rotate-180",
33
+ false: "",
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ size: "md",
38
+ disabled: false,
39
+ isFocus: false,
40
+ },
41
+ });
42
+
43
+ export const customInputVariant = cva([], {
44
+ variants: {
45
+ size: {
46
+ sm: "pe-[30px]",
47
+ md: "pe-[40px]",
48
+ lg: "pe-[48px]",
49
+ },
50
+ },
51
+ defaultVariants: {
52
+ size: "md",
53
+ },
54
+ });
@@ -0,0 +1,151 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
2
+
3
+ import TextInput, { InputProps } from "../TextInput/TextInput";
4
+ import {
5
+ customInputVariant,
6
+ dropdownIconVariant,
7
+ iconWrapperVariant,
8
+ } from "./Dropdown.styles";
9
+
10
+ import { ChevronDownIcon } from "@heroicons/react/16/solid";
11
+
12
+ type Options = {
13
+ value: string;
14
+ label: string;
15
+ };
16
+
17
+ type DropdownProps = {
18
+ id?: string;
19
+ label?: string;
20
+ size?: "sm" | "md" | "lg";
21
+ rounded?: "none" | "normal" | "full";
22
+ variant?: "flat" | "outline" | "underline";
23
+ helperText?: string;
24
+ errorMessage?: string;
25
+ filterMode?: boolean;
26
+ fullwidth?: boolean;
27
+ disabled?: boolean;
28
+ error?: boolean;
29
+ required?: boolean;
30
+ className?: string;
31
+ options: Options[];
32
+ value?: Options;
33
+ onChangeText?: InputProps["onChange"];
34
+ onSelect?: (value: Options) => void;
35
+ } & Omit<InputProps, "value">;
36
+
37
+ const Dropdown = ({
38
+ id,
39
+ options,
40
+ value,
41
+ label,
42
+ size = "md",
43
+ rounded = "normal",
44
+ variant = "outline",
45
+ helperText,
46
+ errorMessage,
47
+ fullwidth = true,
48
+ disabled = false,
49
+ error = false,
50
+ filterMode = false,
51
+ required = true,
52
+ onChangeText,
53
+ onSelect,
54
+ ...props
55
+ }: DropdownProps) => {
56
+ const _id = id || `${label}-select`;
57
+
58
+ const [isFocused, setIsFocused] = useState(false);
59
+ const [selectedOption, setSelectedOption] = useState<
60
+ Options | null | undefined
61
+ >(null);
62
+ const [textValue, setTextValue] = useState("");
63
+
64
+ useEffect(() => {
65
+ if (value && !selectedOption) {
66
+ setSelectedOption(value);
67
+ }
68
+ }, [value, selectedOption]);
69
+
70
+ const handleOnChangeText = useCallback(
71
+ (event: React.ChangeEvent<HTMLInputElement>) => {
72
+ onChangeText?.(event);
73
+ setTextValue(event.target.value);
74
+ },
75
+ [onChangeText]
76
+ );
77
+
78
+ const handleOptionClick = useCallback(
79
+ (option: Options) => {
80
+ setSelectedOption(option);
81
+ setTextValue(option.label);
82
+ onSelect?.(option);
83
+ },
84
+ [onSelect]
85
+ );
86
+
87
+ const optionsFiltered = useMemo(() => {
88
+ return options.filter(
89
+ (option) =>
90
+ !filterMode ||
91
+ option.label?.toLowerCase().includes(textValue?.toLowerCase())
92
+ );
93
+ }, [options, filterMode, textValue]);
94
+
95
+ const renderOptions = () => (
96
+ <ul className="absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-md z-10 max-h-60 overflow-y-auto">
97
+ {optionsFiltered.map((option) => (
98
+ <li
99
+ key={option.value}
100
+ onMouseDown={() => handleOptionClick(option)}
101
+ className={`px-4 py-2 hover:bg-gray-100 cursor-pointer ${
102
+ selectedOption?.value === option.value ? " bg-gray-200" : ""
103
+ }`}
104
+ >
105
+ {option.label}
106
+ </li>
107
+ ))}
108
+ {optionsFiltered.length === 0 && (
109
+ <li className="px-4 py-14 text-center text-input-text">Not found</li>
110
+ )}
111
+ </ul>
112
+ );
113
+
114
+ return (
115
+ <div className={`relative ${fullwidth ? "w-full" : ""}`}>
116
+ <TextInput
117
+ {...props}
118
+ readOnly={!filterMode}
119
+ value={textValue}
120
+ onChange={handleOnChangeText}
121
+ label={label}
122
+ placeholder=" "
123
+ type="text"
124
+ rounded={rounded}
125
+ variant={variant}
126
+ helperText={helperText}
127
+ errorMessage={errorMessage}
128
+ fullwidth={fullwidth}
129
+ error={error}
130
+ required={required}
131
+ id={_id}
132
+ disabled={disabled}
133
+ hasClearIcon={false}
134
+ size={size}
135
+ className={customInputVariant({ size })}
136
+ onFocus={() => setIsFocused(true)}
137
+ onBlur={() => setIsFocused(false)}
138
+ endIcon={
139
+ <div className={iconWrapperVariant({ size })}>
140
+ <ChevronDownIcon
141
+ className={dropdownIconVariant({ size, isFocus: isFocused })}
142
+ />
143
+ </div>
144
+ }
145
+ />
146
+ {isFocused && renderOptions()}
147
+ </div>
148
+ );
149
+ };
150
+
151
+ export default Dropdown;
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Input } from "./Input";
4
+
5
+ const meta = {
6
+ title: "Components/Input",
7
+ component: Input,
8
+ tags: ["autodocs"],
9
+ parameters: {
10
+ layout: "fullscreen",
11
+ },
12
+ decorators: [
13
+ (Story) => (
14
+ <div className="p-5 flex w-full">
15
+ <Story />
16
+ </div>
17
+ ),
18
+ ],
19
+ } satisfies Meta<typeof Input>;
20
+
21
+ export default meta;
22
+
23
+ export const Default = {
24
+ args: {
25
+ // label: "Lorem Ipsum",
26
+ // value: "Lorem Ipsum",
27
+ // fullwidth: true,
28
+ },
29
+ render: (args) => {
30
+ console.log("args ", args);
31
+ const props: typeof args = {
32
+ ...args,
33
+ };
34
+ return (
35
+ <div className="flex flex-row gap-4 w-full">
36
+ <Input type="email" placeholder="Email" />
37
+ </div>
38
+ );
39
+ },
40
+ } satisfies StoryObj;
@@ -0,0 +1,25 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/utils/cn";
4
+
5
+ export interface InputProps
6
+ extends React.InputHTMLAttributes<HTMLInputElement> {}
7
+
8
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
9
+ ({ className, type, ...props }, ref) => {
10
+ return (
11
+ <input
12
+ type={type}
13
+ className={cn(
14
+ "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
16
+ )}
17
+ ref={ref}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+ );
23
+ Input.displayName = "Input";
24
+
25
+ export { Input };
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+
4
+ import { Checkbox } from "../Checkbox/Checkbox";
5
+ import { Label } from "./Label";
6
+
7
+ const meta = {
8
+ title: "Components/Label",
9
+ component: Label,
10
+ tags: ["autodocs"],
11
+ parameters: {
12
+ layout: "fullscreen",
13
+ },
14
+ decorators: [
15
+ (Story) => (
16
+ <div className="p-5 flex w-full">
17
+ <Story />
18
+ </div>
19
+ ),
20
+ ],
21
+ } satisfies Meta<typeof Label>;
22
+
23
+ export default meta;
24
+
25
+ export const Default = {
26
+ args: {
27
+ // label: "Lorem Ipsum",
28
+ // value: "Lorem Ipsum",
29
+ // fullwidth: true,
30
+ },
31
+ render: (args) => {
32
+ console.log("args ", args);
33
+ const props: typeof args = {
34
+ ...args,
35
+ };
36
+ return (
37
+ <div className="flex flex-row gap-4 w-full">
38
+ <div className="flex items-center space-x-2">
39
+ <Checkbox id="terms" />
40
+ <Label htmlFor="terms">Accept terms and conditions</Label>
41
+ </div>
42
+ </div>
43
+ );
44
+ },
45
+ } satisfies StoryObj;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as LabelPrimitive from "@radix-ui/react-label";
5
+ import { cva, type VariantProps } from "class-variance-authority";
6
+
7
+ import { cn } from "@/utils/cn";
8
+
9
+ const labelVariants = cva(
10
+ "typography-label1 peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11
+ );
12
+
13
+ const Label = React.forwardRef<
14
+ React.ElementRef<typeof LabelPrimitive.Root>,
15
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
16
+ VariantProps<typeof labelVariants>
17
+ >(({ className, ...props }, ref) => (
18
+ <LabelPrimitive.Root
19
+ ref={ref}
20
+ className={cn(labelVariants(), className)}
21
+ {...props}
22
+ />
23
+ ));
24
+ Label.displayName = LabelPrimitive.Root.displayName;
25
+
26
+ export { Label };
@@ -0,0 +1,71 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { RadioGroup, RadioGroupItem } from "./RadioGroup";
4
+ import { Label } from "../Label/Label";
5
+ const meta = {
6
+ title: "Components/RadioGroup",
7
+ component: RadioGroup,
8
+ tags: ["autodocs"],
9
+ parameters: {
10
+ layout: "fullscreen",
11
+ },
12
+ decorators: [
13
+ (Story) => (
14
+ <div className="p-5 flex w-full">
15
+ <Story />
16
+ </div>
17
+ ),
18
+ ],
19
+ } satisfies Meta<typeof RadioGroup>;
20
+
21
+ export default meta;
22
+
23
+ export const Default = {
24
+ args: {
25
+ disabled: false,
26
+ },
27
+ render: (args) => {
28
+ const props: typeof args = {
29
+ ...args,
30
+ };
31
+ return (
32
+ <div className="flex flex-row gap-4 w-full">
33
+ <RadioGroup defaultValue="option-one" {...props}>
34
+ <div className="flex items-center space-x-2">
35
+ <RadioGroupItem value="option-one" id="option-one" />
36
+ <Label htmlFor="option-one">Option One</Label>
37
+ </div>
38
+ <div className="flex items-center space-x-2">
39
+ <RadioGroupItem value="option-two" id="option-two" />
40
+ <Label htmlFor="option-two">Option Two</Label>
41
+ </div>
42
+ </RadioGroup>
43
+ </div>
44
+ );
45
+ },
46
+ } satisfies StoryObj;
47
+
48
+ export const Diabled = {
49
+ args: {
50
+ disabled: true,
51
+ },
52
+ render: (args) => {
53
+ const props: typeof args = {
54
+ ...args,
55
+ };
56
+ return (
57
+ <div className="flex items-center space-x-2">
58
+ <RadioGroup defaultValue="option-one" disabled>
59
+ <div className="flex items-center space-x-2">
60
+ <RadioGroupItem value="option-one" id="option-one" />
61
+ <Label htmlFor="option-one">Option One</Label>
62
+ </div>
63
+ <div className="flex items-center space-x-2">
64
+ <RadioGroupItem value="option-two" id="option-two" />
65
+ <Label htmlFor="option-two">Option Two</Label>
66
+ </div>
67
+ </RadioGroup>
68
+ </div>
69
+ );
70
+ },
71
+ } satisfies StoryObj;
@@ -0,0 +1,59 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5
+
6
+ import { cn } from "@/utils/cn";
7
+
8
+ const RadioGroup = React.forwardRef<
9
+ React.ElementRef<typeof RadioGroupPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
11
+ >(({ className, ...props }, ref) => {
12
+ return (
13
+ <RadioGroupPrimitive.Root
14
+ className={cn("grid gap-2", className)}
15
+ {...props}
16
+ ref={ref}
17
+ />
18
+ );
19
+ });
20
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
21
+
22
+ const RadioGroupItem = React.forwardRef<
23
+ React.ElementRef<typeof RadioGroupPrimitive.Item>,
24
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
25
+ >(({ className, ...props }, ref) => {
26
+ return (
27
+ <RadioGroupPrimitive.Item
28
+ ref={ref}
29
+ className={cn(
30
+ "aspect-square h-4 w-4 rounded-full border text-primary disabled:fill-secondary-110 ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:border-secondary-110",
31
+ {
32
+ "border-primary-30 data-[state=checked]:border-primary":
33
+ !props.disabled,
34
+ "border-secondary-110 data-disabled:border-secondary-110 text-secondary-110 fill-secondary-110":
35
+ props.disabled,
36
+ },
37
+ className
38
+ )}
39
+ {...props}
40
+ >
41
+ <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
42
+ {/* <div className="bg-primary size-2.5 rounded-full" /> */}
43
+ <svg
44
+ width="10"
45
+ height="10"
46
+ viewBox="0 0 10 10"
47
+ fill="none"
48
+ xmlns="http://www.w3.org/2000/svg"
49
+ className="fill-current text-current"
50
+ >
51
+ <circle cx="5" cy="5" r="5" fill="current" />
52
+ </svg>
53
+ </RadioGroupPrimitive.Indicator>
54
+ </RadioGroupPrimitive.Item>
55
+ );
56
+ });
57
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
58
+
59
+ export { RadioGroup, RadioGroupItem };
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+
3
+ interface Column {
4
+ header: string;
5
+ accessor: string;
6
+ }
7
+
8
+ interface TableProps {
9
+ columns: Column[];
10
+ data: Record<string, any>[];
11
+ }
12
+
13
+ const Table: React.FC<TableProps> = ({ columns, data }) => {
14
+ return (
15
+ <table className="table">
16
+ <thead>
17
+ <tr>
18
+ {columns.map((column, index) => (
19
+ <th key={index}>{column.header}</th>
20
+ ))}
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ {data.map((row, rowIndex) => (
25
+ <tr key={rowIndex}>
26
+ {columns.map((column, colIndex) => (
27
+ <td key={colIndex}>{row[column.accessor]}</td>
28
+ ))}
29
+ </tr>
30
+ ))}
31
+ </tbody>
32
+ </table>
33
+ );
34
+ };
35
+
36
+ export default Table;