@rovula/ui 0.0.9 → 0.0.11

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 (135) hide show
  1. package/dist/cjs/bundle.css +443 -3
  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.d.ts +14 -3
  7. package/dist/cjs/types/components/Button/Button.styles.d.ts +1 -1
  8. package/dist/cjs/types/components/Button/Buttons.stories.d.ts +8 -6
  9. package/dist/cjs/types/components/Checkbox/Checkbox.d.ts +4 -0
  10. package/dist/cjs/types/components/Checkbox/Checkbox.stories.d.ts +308 -0
  11. package/dist/cjs/types/components/DataTable/DataTable.d.ts +14 -0
  12. package/dist/cjs/types/components/DataTable/DataTable.stories.d.ts +19 -0
  13. package/dist/cjs/types/components/Dialog/Dialog.d.ts +19 -0
  14. package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +25 -0
  15. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +29 -3
  16. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
  17. package/dist/cjs/types/components/Input/Input.d.ts +5 -0
  18. package/dist/cjs/types/components/Input/Input.stories.d.ts +314 -0
  19. package/dist/cjs/types/components/Label/Label.d.ts +5 -0
  20. package/dist/cjs/types/components/Label/Label.stories.d.ts +286 -0
  21. package/dist/cjs/types/components/RadioGroup/RadioGroup.d.ts +5 -0
  22. package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +299 -0
  23. package/dist/cjs/types/components/Table/Datagrid.d.ts +11 -0
  24. package/dist/cjs/types/components/Table/Table.d.ts +10 -11
  25. package/dist/cjs/types/components/Table/Table.stories.d.ts +283 -0
  26. package/dist/cjs/types/components/Tabs/Tabs.d.ts +7 -5
  27. package/dist/cjs/types/components/Tabs/Tabs.stories.d.ts +49 -0
  28. package/dist/cjs/types/components/Text/Text.d.ts +3 -3
  29. package/dist/cjs/types/components/Text/Text.stories.d.ts +3 -9
  30. package/dist/cjs/types/components/TextInput/TextInput.d.ts +20 -2
  31. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +28 -1
  32. package/dist/cjs/types/components/ui/table.d.ts +10 -0
  33. package/dist/cjs/types/index.d.ts +10 -1
  34. package/dist/cjs/types/utils/cn.d.ts +2 -0
  35. package/dist/components/AlertDialog/Alert.stories.js +39 -0
  36. package/dist/components/AlertDialog/AlertDialog.js +73 -0
  37. package/dist/components/Button/Button.js +6 -5
  38. package/dist/components/Button/Button.styles.js +1 -1
  39. package/dist/components/Checkbox/Checkbox.js +37 -0
  40. package/dist/components/Checkbox/Checkbox.stories.js +49 -0
  41. package/dist/components/DataTable/DataTable.js +32 -0
  42. package/dist/components/DataTable/DataTable.stories.js +66 -0
  43. package/dist/components/Dialog/Dialog.js +63 -0
  44. package/dist/components/Dialog/Dialog.stories.js +52 -0
  45. package/dist/components/Dropdown/Dropdown.js +15 -5
  46. package/dist/components/Dropdown/Dropdown.stories.js +48 -0
  47. package/dist/components/Input/Input.js +31 -0
  48. package/dist/components/Input/Input.stories.js +37 -0
  49. package/dist/components/Label/Label.js +35 -0
  50. package/dist/components/Label/Label.stories.js +38 -0
  51. package/dist/components/RadioGroup/RadioGroup.js +41 -0
  52. package/dist/components/RadioGroup/RadioGroup.stories.js +44 -0
  53. package/dist/components/Table/Datagrid.js +6 -0
  54. package/dist/components/Table/Table.js +65 -5
  55. package/dist/components/Table/Table.stories.js +32 -0
  56. package/dist/components/Tabs/Tabs.js +10 -4
  57. package/dist/components/Tabs/Tabs.stories.js +60 -0
  58. package/dist/components/Text/Text.js +3 -2
  59. package/dist/components/TextInput/TextInput.js +5 -7
  60. package/dist/components/TextInput/TextInput.stories.js +22 -0
  61. package/dist/components/ui/table.js +66 -0
  62. package/dist/esm/bundle.css +443 -3
  63. package/dist/esm/bundle.js +1 -1
  64. package/dist/esm/bundle.js.map +1 -1
  65. package/dist/esm/types/components/AlertDialog/Alert.stories.d.ts +20 -0
  66. package/dist/esm/types/components/AlertDialog/AlertDialog.d.ts +20 -0
  67. package/dist/esm/types/components/Button/Button.d.ts +14 -3
  68. package/dist/esm/types/components/Button/Button.styles.d.ts +1 -1
  69. package/dist/esm/types/components/Button/Buttons.stories.d.ts +8 -6
  70. package/dist/esm/types/components/Checkbox/Checkbox.d.ts +4 -0
  71. package/dist/esm/types/components/Checkbox/Checkbox.stories.d.ts +308 -0
  72. package/dist/esm/types/components/DataTable/DataTable.d.ts +14 -0
  73. package/dist/esm/types/components/DataTable/DataTable.stories.d.ts +19 -0
  74. package/dist/esm/types/components/Dialog/Dialog.d.ts +19 -0
  75. package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +25 -0
  76. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +29 -3
  77. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
  78. package/dist/esm/types/components/Input/Input.d.ts +5 -0
  79. package/dist/esm/types/components/Input/Input.stories.d.ts +314 -0
  80. package/dist/esm/types/components/Label/Label.d.ts +5 -0
  81. package/dist/esm/types/components/Label/Label.stories.d.ts +286 -0
  82. package/dist/esm/types/components/RadioGroup/RadioGroup.d.ts +5 -0
  83. package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +299 -0
  84. package/dist/esm/types/components/Table/Datagrid.d.ts +11 -0
  85. package/dist/esm/types/components/Table/Table.d.ts +10 -11
  86. package/dist/esm/types/components/Table/Table.stories.d.ts +283 -0
  87. package/dist/esm/types/components/Tabs/Tabs.d.ts +7 -5
  88. package/dist/esm/types/components/Tabs/Tabs.stories.d.ts +49 -0
  89. package/dist/esm/types/components/Text/Text.d.ts +3 -3
  90. package/dist/esm/types/components/Text/Text.stories.d.ts +3 -9
  91. package/dist/esm/types/components/TextInput/TextInput.d.ts +20 -2
  92. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +28 -1
  93. package/dist/esm/types/components/ui/table.d.ts +10 -0
  94. package/dist/esm/types/index.d.ts +10 -1
  95. package/dist/esm/types/utils/cn.d.ts +2 -0
  96. package/dist/index.d.ts +139 -31
  97. package/dist/index.js +7 -1
  98. package/dist/src/theme/global.css +529 -3
  99. package/dist/theme/global.css +57 -0
  100. package/dist/theme/main-preset.js +29 -1
  101. package/dist/theme/presets/colors.js +19 -0
  102. package/dist/utils/cn.js +9 -0
  103. package/package.json +10 -1
  104. package/src/components/AlertDialog/Alert.stories.tsx +67 -0
  105. package/src/components/AlertDialog/AlertDialog.tsx +142 -0
  106. package/src/components/Button/Button.styles.ts +1 -1
  107. package/src/components/Button/Button.tsx +49 -41
  108. package/src/components/Checkbox/Checkbox.stories.tsx +91 -0
  109. package/src/components/Checkbox/Checkbox.tsx +36 -0
  110. package/src/components/DataTable/DataTable.stories.tsx +76 -0
  111. package/src/components/DataTable/DataTable.tsx +105 -0
  112. package/src/components/Dialog/Dialog.stories.tsx +118 -0
  113. package/src/components/Dialog/Dialog.tsx +119 -0
  114. package/src/components/Dropdown/Dropdown.stories.tsx +87 -3
  115. package/src/components/Dropdown/Dropdown.tsx +147 -109
  116. package/src/components/Input/Input.stories.tsx +40 -0
  117. package/src/components/Input/Input.tsx +25 -0
  118. package/src/components/Label/Label.stories.tsx +45 -0
  119. package/src/components/Label/Label.tsx +26 -0
  120. package/src/components/RadioGroup/RadioGroup.stories.tsx +71 -0
  121. package/src/components/RadioGroup/RadioGroup.tsx +59 -0
  122. package/src/components/Table/Datagrid.tsx +36 -0
  123. package/src/components/Table/Table.stories.tsx +79 -0
  124. package/src/components/Table/Table.tsx +116 -35
  125. package/src/components/Tabs/Tabs.stories.tsx +75 -0
  126. package/src/components/Tabs/Tabs.tsx +39 -10
  127. package/src/components/Text/Text.tsx +21 -19
  128. package/src/components/TextInput/TextInput.stories.tsx +46 -1
  129. package/src/components/TextInput/TextInput.tsx +7 -7
  130. package/src/components/ui/table.tsx +117 -0
  131. package/src/index.ts +13 -1
  132. package/src/theme/global.css +57 -0
  133. package/src/theme/main-preset.js +29 -1
  134. package/src/theme/presets/colors.js +19 -0
  135. package/src/utils/cn.ts +6 -0
@@ -1,4 +1,12 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from "react";
1
+ import React, {
2
+ Fragment,
3
+ ReactNode,
4
+ forwardRef,
5
+ useCallback,
6
+ useEffect,
7
+ useMemo,
8
+ useState,
9
+ } from "react";
2
10
 
3
11
  import TextInput, { InputProps } from "../TextInput/TextInput";
4
12
  import {
@@ -9,12 +17,20 @@ import {
9
17
 
10
18
  import { ChevronDownIcon } from "@heroicons/react/16/solid";
11
19
 
12
- type Options = {
20
+ type RenderLabelCallbackArg = {
13
21
  value: string;
14
22
  label: string;
23
+ handleOnClick: () => void;
24
+ className: string;
15
25
  };
16
26
 
17
- type DropdownProps = {
27
+ export type Options = {
28
+ value: string;
29
+ label: string;
30
+ renderLabel?: (config: RenderLabelCallbackArg) => ReactNode;
31
+ };
32
+
33
+ export type DropdownProps = {
18
34
  id?: string;
19
35
  label?: string;
20
36
  size?: "sm" | "md" | "lg";
@@ -34,118 +50,140 @@ type DropdownProps = {
34
50
  onSelect?: (value: Options) => void;
35
51
  } & Omit<InputProps, "value">;
36
52
 
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("");
53
+ const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
54
+ (
55
+ {
56
+ id,
57
+ options,
58
+ value,
59
+ label,
60
+ size = "md",
61
+ rounded = "normal",
62
+ variant = "outline",
63
+ helperText,
64
+ errorMessage,
65
+ fullwidth = true,
66
+ disabled = false,
67
+ error = false,
68
+ filterMode = false,
69
+ required = true,
70
+ onChangeText,
71
+ onSelect,
72
+ ...props
73
+ },
74
+ ref
75
+ ) => {
76
+ const _id = id || `${label}-select`;
63
77
 
64
- useEffect(() => {
65
- if (value && !selectedOption) {
66
- setSelectedOption(value);
67
- }
68
- }, [value, selectedOption]);
78
+ const [isFocused, setIsFocused] = useState(false);
79
+ const [selectedOption, setSelectedOption] = useState<
80
+ Options | null | undefined
81
+ >(null);
82
+ const [textValue, setTextValue] = useState("");
69
83
 
70
- const handleOnChangeText = useCallback(
71
- (event: React.ChangeEvent<HTMLInputElement>) => {
72
- onChangeText?.(event);
73
- setTextValue(event.target.value);
74
- },
75
- [onChangeText]
76
- );
84
+ useEffect(() => {
85
+ if (value && !selectedOption) {
86
+ setSelectedOption(value);
87
+ }
88
+ }, [value, selectedOption]);
77
89
 
78
- const handleOptionClick = useCallback(
79
- (option: Options) => {
80
- setSelectedOption(option);
81
- setTextValue(option.label);
82
- onSelect?.(option);
83
- },
84
- [onSelect]
85
- );
90
+ const handleOnChangeText = useCallback(
91
+ (event: React.ChangeEvent<HTMLInputElement>) => {
92
+ onChangeText?.(event);
93
+ setTextValue(event.target.value);
94
+ },
95
+ [onChangeText]
96
+ );
86
97
 
87
- const optionsFiltered = useMemo(() => {
88
- return options.filter(
89
- (option) =>
90
- !filterMode ||
91
- option.label?.toLowerCase().includes(textValue?.toLowerCase())
98
+ const handleOptionClick = useCallback(
99
+ (option: Options) => {
100
+ setSelectedOption(option);
101
+ setTextValue(option.label);
102
+ onSelect?.(option);
103
+ },
104
+ [onSelect]
92
105
  );
93
- }, [options, filterMode, textValue]);
94
106
 
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
- );
107
+ const optionsFiltered = useMemo(() => {
108
+ return options.filter(
109
+ (option) =>
110
+ !filterMode ||
111
+ option.label?.toLowerCase().includes(textValue?.toLowerCase())
112
+ );
113
+ }, [options, filterMode, textValue]);
113
114
 
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
- };
115
+ const renderOptions = () => (
116
+ <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">
117
+ {optionsFiltered.map((option) => {
118
+ if (option.renderLabel) {
119
+ return (
120
+ <Fragment key={option.value}>
121
+ {option.renderLabel({
122
+ value: option.value,
123
+ label: option.label,
124
+ handleOnClick: () => handleOptionClick(option),
125
+ className: `px-4 py-2 hover:bg-gray-100 cursor-pointer ${
126
+ selectedOption?.value === option.value ? " bg-gray-200" : ""
127
+ }`,
128
+ })}
129
+ </Fragment>
130
+ );
131
+ }
132
+ return (
133
+ <li
134
+ key={option.value}
135
+ onMouseDown={() => handleOptionClick(option)}
136
+ className={`px-4 py-2 hover:bg-gray-100 cursor-pointer ${
137
+ selectedOption?.value === option.value ? " bg-gray-200" : ""
138
+ }`}
139
+ >
140
+ {option.label}
141
+ </li>
142
+ );
143
+ })}
144
+ {optionsFiltered.length === 0 && (
145
+ <li className="px-4 py-14 text-center text-input-text">Not found</li>
146
+ )}
147
+ </ul>
148
+ );
149
+
150
+ return (
151
+ <div className={`relative ${fullwidth ? "w-full" : ""}`}>
152
+ <TextInput
153
+ {...props}
154
+ ref={ref}
155
+ readOnly={!filterMode}
156
+ value={textValue}
157
+ onChange={handleOnChangeText}
158
+ label={label}
159
+ placeholder=" "
160
+ type="text"
161
+ rounded={rounded}
162
+ variant={variant}
163
+ helperText={helperText}
164
+ errorMessage={errorMessage}
165
+ fullwidth={fullwidth}
166
+ error={error}
167
+ required={required}
168
+ id={_id}
169
+ disabled={disabled}
170
+ hasClearIcon={false}
171
+ size={size}
172
+ className={customInputVariant({ size })}
173
+ onFocus={() => setIsFocused(true)}
174
+ onBlur={() => setIsFocused(false)}
175
+ endIcon={
176
+ <div className={iconWrapperVariant({ size })}>
177
+ <ChevronDownIcon
178
+ className={dropdownIconVariant({ size, isFocus: isFocused })}
179
+ />
180
+ </div>
181
+ }
182
+ />
183
+ {isFocused && renderOptions()}
184
+ </div>
185
+ );
186
+ }
187
+ );
150
188
 
151
189
  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;
@@ -0,0 +1,79 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import {
4
+ Table,
5
+ TableBody,
6
+ TableCaption,
7
+ TableCell,
8
+ TableHead,
9
+ TableHeader,
10
+ TableRow,
11
+ } from "./Table";
12
+
13
+ const meta = {
14
+ title: "Components/Table",
15
+ component: Table,
16
+ tags: ["autodocs"],
17
+ parameters: {
18
+ layout: "fullscreen",
19
+ },
20
+ decorators: [
21
+ (Story) => (
22
+ <div className="p-5 flex w-full">
23
+ <Story />
24
+ </div>
25
+ ),
26
+ ],
27
+ } satisfies Meta<typeof Table>;
28
+
29
+ export default meta;
30
+
31
+ export const Default = {
32
+ args: {},
33
+ render: (args) => {
34
+ const props: typeof args = {
35
+ ...args,
36
+ };
37
+ return (
38
+ <div className="flex flex-row gap-4 w-full">
39
+ <Table>
40
+ <TableCaption>A list of your recent invoices.</TableCaption>
41
+ <TableHeader>
42
+ <TableRow>
43
+ <TableHead className="w-[100px]">Invoice</TableHead>
44
+ <TableHead>Status</TableHead>
45
+ <TableHead>Method</TableHead>
46
+ <TableHead className="text-right">Amount</TableHead>
47
+ </TableRow>
48
+ </TableHeader>
49
+ <TableBody>
50
+ <TableRow>
51
+ <TableCell className="font-medium">INV001</TableCell>
52
+ <TableCell>Paid</TableCell>
53
+ <TableCell>Credit Card</TableCell>
54
+ <TableCell className="text-right">$250.00</TableCell>
55
+ </TableRow>
56
+ <TableRow>
57
+ <TableCell className="font-medium">INV001</TableCell>
58
+ <TableCell>Paid</TableCell>
59
+ <TableCell>Credit Card</TableCell>
60
+ <TableCell className="text-right">$250.00</TableCell>
61
+ </TableRow>
62
+ <TableRow>
63
+ <TableCell className="font-medium">INV001</TableCell>
64
+ <TableCell>Paid</TableCell>
65
+ <TableCell>Credit Card</TableCell>
66
+ <TableCell className="text-right">$250.00</TableCell>
67
+ </TableRow>
68
+ <TableRow>
69
+ <TableCell className="font-medium">INV001</TableCell>
70
+ <TableCell>Paid</TableCell>
71
+ <TableCell>Credit Card</TableCell>
72
+ <TableCell className="text-right">$250.00</TableCell>
73
+ </TableRow>
74
+ </TableBody>
75
+ </Table>
76
+ </div>
77
+ );
78
+ },
79
+ } satisfies StoryObj;