@mbao01/common 0.2.2 → 0.2.3

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 (120) hide show
  1. package/dist/types/components/Dock/Dock.d.ts +8 -0
  2. package/dist/types/components/Dock/constants.d.ts +12 -0
  3. package/dist/types/components/Dock/index.d.ts +1 -0
  4. package/dist/types/components/Dock/types.d.ts +12 -0
  5. package/dist/types/components/Form/Input/Input.d.ts +5 -2
  6. package/dist/types/components/Form/Input/constants.d.ts +4 -0
  7. package/dist/types/components/Form/Input/types.d.ts +9 -2
  8. package/dist/types/components/Form/Radio/Radio.d.ts +1 -1
  9. package/dist/types/components/Form/Radio/types.d.ts +1 -1
  10. package/dist/types/components/Form/Range/Range.d.ts +1 -1
  11. package/dist/types/components/Form/Range/types.d.ts +1 -1
  12. package/dist/types/components/Form/Select/Select.d.ts +3 -0
  13. package/dist/types/components/Form/Select/constants.d.ts +4 -0
  14. package/dist/types/components/Form/Select/types.d.ts +10 -2
  15. package/dist/types/components/Form/Switch/Switch.d.ts +1 -1
  16. package/dist/types/components/Form/Switch/types.d.ts +1 -1
  17. package/dist/types/components/Form/TextField/TextField.d.ts +5 -1
  18. package/dist/types/components/Form/TextField/types.d.ts +1 -0
  19. package/dist/types/components/Form/Textarea/Textarea.d.ts +2 -0
  20. package/dist/types/components/Form/Textarea/constants.d.ts +1 -0
  21. package/dist/types/components/Form/Textarea/types.d.ts +7 -1
  22. package/dist/types/components/Form/Validator/Validator.d.ts +6 -0
  23. package/dist/types/components/Form/Validator/constants.d.ts +4 -0
  24. package/dist/types/components/Form/Validator/index.d.ts +1 -0
  25. package/dist/types/components/Form/Validator/types.d.ts +14 -0
  26. package/dist/types/components/Form/components/Fieldset/types.d.ts +1 -1
  27. package/dist/types/components/Form/index.d.ts +1 -0
  28. package/dist/types/components/Indicator/Indicator.d.ts +6 -0
  29. package/dist/types/components/Indicator/constants.d.ts +15 -0
  30. package/dist/types/components/Indicator/index.d.ts +1 -0
  31. package/dist/types/components/Indicator/types.d.ts +14 -0
  32. package/dist/types/components/Join/Join.d.ts +6 -0
  33. package/dist/types/components/Join/constants.d.ts +2 -0
  34. package/dist/types/components/Join/index.d.ts +1 -0
  35. package/dist/types/components/Join/types.d.ts +13 -0
  36. package/dist/types/components/Kbd/Kbd.d.ts +2 -0
  37. package/dist/types/components/Kbd/constants.d.ts +5 -0
  38. package/dist/types/components/Kbd/index.d.ts +1 -0
  39. package/dist/types/components/Kbd/types.d.ts +3 -0
  40. package/dist/types/components/List/List.d.ts +7 -0
  41. package/dist/types/components/List/constants.d.ts +5 -0
  42. package/dist/types/components/List/index.d.ts +1 -0
  43. package/dist/types/components/List/types.d.ts +6 -0
  44. package/dist/types/components/Resizable/Resizable.d.ts +24 -0
  45. package/dist/types/components/Resizable/constants.d.ts +6 -0
  46. package/dist/types/components/Resizable/index.d.ts +1 -0
  47. package/dist/types/components/Resizable/types.d.ts +7 -0
  48. package/dist/types/components/Sidebar/Sidebar.d.ts +5 -2
  49. package/dist/types/components/Stack/Stack.d.ts +2 -0
  50. package/dist/types/components/Stack/constants.d.ts +3 -0
  51. package/dist/types/components/Stack/index.d.ts +1 -0
  52. package/dist/types/components/Stack/types.d.ts +3 -0
  53. package/dist/types/components/Stat/Stat.d.ts +11 -0
  54. package/dist/types/components/Stat/constants.d.ts +11 -0
  55. package/dist/types/components/Stat/index.d.ts +1 -0
  56. package/dist/types/components/Stat/types.d.ts +10 -0
  57. package/dist/types/components/Status/Status.d.ts +2 -0
  58. package/dist/types/components/Status/constants.d.ts +5 -0
  59. package/dist/types/components/Status/index.d.ts +1 -0
  60. package/dist/types/components/Status/types.d.ts +3 -0
  61. package/dist/types/components/Text/types.d.ts +1 -1
  62. package/dist/types/index.d.ts +9 -0
  63. package/package.json +16 -14
  64. package/src/components/Dock/Dock.tsx +41 -0
  65. package/src/components/Dock/constants.ts +62 -0
  66. package/src/components/Dock/index.ts +1 -0
  67. package/src/components/Dock/types.ts +23 -0
  68. package/src/components/Form/Input/Input.tsx +71 -10
  69. package/src/components/Form/Input/constants.ts +17 -5
  70. package/src/components/Form/Input/types.ts +12 -4
  71. package/src/components/Form/Radio/types.ts +4 -1
  72. package/src/components/Form/Range/types.ts +4 -1
  73. package/src/components/Form/Select/Select.tsx +71 -10
  74. package/src/components/Form/Select/constants.ts +17 -0
  75. package/src/components/Form/Select/types.ts +11 -1
  76. package/src/components/Form/Switch/types.ts +4 -1
  77. package/src/components/Form/TextField/types.ts +1 -0
  78. package/src/components/Form/Textarea/Textarea.tsx +29 -3
  79. package/src/components/Form/Textarea/constants.ts +2 -0
  80. package/src/components/Form/Textarea/types.ts +9 -2
  81. package/src/components/Form/Validator/Validator.tsx +27 -0
  82. package/src/components/Form/Validator/constants.ts +18 -0
  83. package/src/components/Form/Validator/index.ts +1 -0
  84. package/src/components/Form/Validator/types.ts +30 -0
  85. package/src/components/Form/components/Fieldset/types.ts +1 -1
  86. package/src/components/Form/index.ts +1 -0
  87. package/src/components/Indicator/Indicator.tsx +46 -0
  88. package/src/components/Indicator/constants.ts +26 -0
  89. package/src/components/Indicator/index.ts +1 -0
  90. package/src/components/Indicator/types.ts +34 -0
  91. package/src/components/Join/Join.tsx +28 -0
  92. package/src/components/Join/constants.ts +5 -0
  93. package/src/components/Join/index.ts +1 -0
  94. package/src/components/Join/types.ts +29 -0
  95. package/src/components/Kbd/Kbd.tsx +7 -0
  96. package/src/components/Kbd/constants.ts +40 -0
  97. package/src/components/Kbd/index.ts +1 -0
  98. package/src/components/Kbd/types.ts +4 -0
  99. package/src/components/List/List.tsx +35 -0
  100. package/src/components/List/constants.ts +14 -0
  101. package/src/components/List/index.ts +1 -0
  102. package/src/components/List/types.ts +12 -0
  103. package/src/components/Resizable/Resizable.tsx +36 -0
  104. package/src/components/Resizable/constants.ts +22 -0
  105. package/src/components/Resizable/index.ts +1 -0
  106. package/src/components/Resizable/types.ts +13 -0
  107. package/src/components/Stack/Stack.tsx +11 -0
  108. package/src/components/Stack/constants.ts +12 -0
  109. package/src/components/Stack/index.ts +1 -0
  110. package/src/components/Stack/types.ts +5 -0
  111. package/src/components/Stat/Stat.tsx +55 -0
  112. package/src/components/Stat/constants.ts +33 -0
  113. package/src/components/Stat/index.ts +1 -0
  114. package/src/components/Stat/types.ts +31 -0
  115. package/src/components/Status/Status.tsx +7 -0
  116. package/src/components/Status/constants.ts +31 -0
  117. package/src/components/Status/index.ts +1 -0
  118. package/src/components/Status/types.ts +5 -0
  119. package/src/components/Text/types.ts +1 -1
  120. package/src/index.ts +9 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mbao01/common",
3
3
  "private": false,
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "type": "module",
6
6
  "author": "Ayomide Bakare",
7
7
  "license": "MIT",
@@ -97,14 +97,14 @@
97
97
  "class-variance-authority": "^0.7.1",
98
98
  "clsx": "^2.1.1",
99
99
  "cmdk": "^1.1.1",
100
- "daisyui": "^5.0.9",
101
100
  "date-fns": "^4.1.0",
102
101
  "embla-carousel-react": "^8.5.2",
103
- "lucide-react": "^0.486.0",
102
+ "lucide-react": "^0.487.0",
104
103
  "react-day-picker": "^9.6.4",
105
104
  "react-dropzone": "^14.3.8",
106
105
  "react-international-phone": "^4.5.0",
107
106
  "react-otp-input": "^3.1.1",
107
+ "react-resizable-panels": "^2.1.7",
108
108
  "sonner": "^2.0.3",
109
109
  "tailwind-merge": "^3.1.0",
110
110
  "timescape": "^0.7.1",
@@ -128,21 +128,22 @@
128
128
  "@storybook/react-vite": "^8.6.11",
129
129
  "@storybook/test": "^8.6.11",
130
130
  "@storybook/test-runner": "^0.22.0",
131
- "@tailwindcss/postcss": "^4.0.17",
132
- "@tailwindcss/vite": "^4.0.17",
131
+ "@tailwindcss/postcss": "^4.1.1",
132
+ "@tailwindcss/vite": "^4.1.1",
133
133
  "@testing-library/jest-dom": "^6.6.3",
134
134
  "@testing-library/react": "^16.2.0",
135
135
  "@testing-library/user-event": "^14.6.1",
136
136
  "@types/jest-image-snapshot": "^6.4.0",
137
- "@types/node": "^22.13.16",
138
- "@types/react": "^19.0.12",
139
- "@types/react-dom": "^19.0.4",
137
+ "@types/node": "^22.13.17",
138
+ "@types/react": "^19.1.0",
139
+ "@types/react-dom": "^19.1.1",
140
140
  "@typescript-eslint/eslint-plugin": "^8.29.0",
141
141
  "@typescript-eslint/parser": "^8.29.0",
142
142
  "@vitejs/plugin-react": "^4.3.4",
143
143
  "@vitest/coverage-v8": "^3.1.1",
144
144
  "@vitest/ui": "^3.1.1",
145
145
  "axe-playwright": "^2.1.0",
146
+ "daisyui": "^5.0.12",
146
147
  "eslint": "^9.23.0",
147
148
  "eslint-plugin-react": "^7.37.4",
148
149
  "eslint-plugin-react-hooks": "^5.2.0",
@@ -159,7 +160,7 @@
159
160
  "react-router-dom": "^7.4.1",
160
161
  "recharts": "^2.15.1",
161
162
  "storybook": "^8.6.11",
162
- "tailwindcss": "^4.0.17",
163
+ "tailwindcss": "^4.1.1",
163
164
  "typescript": "^5.8.2",
164
165
  "typescript-eslint": "^8.29.0",
165
166
  "vite": "^6.2.4",
@@ -167,10 +168,11 @@
167
168
  "vitest": "^3.1.1"
168
169
  },
169
170
  "peerDependencies": {
170
- "react": "^19.0.0",
171
- "react-dom": "^19.0.0",
172
- "recharts": "^2.15.0",
173
- "typescript": "^5.7.2"
171
+ "daisyui": "5",
172
+ "react": "19",
173
+ "react-dom": "19",
174
+ "recharts": "2",
175
+ "typescript": "5"
174
176
  },
175
- "gitHead": "aa3d3090fd645ac0a64b1ccb1fe9451037083674"
177
+ "gitHead": "906e26ed2a5aab0a3cdfc59f94e386d91cfbd0de"
176
178
  }
@@ -0,0 +1,41 @@
1
+ import type { DockButtonProps, DockIconProps, DockLabelProps, DockProps } from "./types";
2
+ import { cn } from "../../utilities";
3
+ import {
4
+ getDockButtonClasses,
5
+ getDockClasses,
6
+ getDockIconClasses,
7
+ getDockLabelClasses,
8
+ } from "./constants";
9
+
10
+ const Dock = ({ size, variant, outline, children, className, ...props }: DockProps) => (
11
+ <div className={cn(getDockClasses({ size, variant, outline }), className)} {...props}>
12
+ {children}
13
+ </div>
14
+ );
15
+
16
+ const DockButton = ({ active, children, className, ...props }: DockButtonProps) => (
17
+ <button className={cn(getDockButtonClasses({ active }), className)} {...props}>
18
+ {children}
19
+ </button>
20
+ );
21
+
22
+ const DockLabel = ({ className, children, ...props }: DockLabelProps) => (
23
+ <span className={cn(getDockLabelClasses(), className)} {...props}>
24
+ {children}
25
+ </span>
26
+ );
27
+
28
+ const DockIcon = ({ icon, size, className, children, ...props }: DockIconProps) => {
29
+ const Icon = icon;
30
+ return (
31
+ <Icon className={cn(getDockIconClasses({ size }), className)} {...props}>
32
+ {children}
33
+ </Icon>
34
+ );
35
+ };
36
+
37
+ Dock.Button = DockButton;
38
+ Dock.Label = DockLabel;
39
+ Dock.Icon = DockIcon;
40
+
41
+ export { Dock };
@@ -0,0 +1,62 @@
1
+ import { cva } from "../../libs";
2
+
3
+ export const getDockClasses = cva("dock", {
4
+ variants: {
5
+ size: {
6
+ xs: "dock-xs",
7
+ sm: "dock-sm",
8
+ md: "dock-md",
9
+ lg: "dock-lg",
10
+ xl: "dock-xl",
11
+ },
12
+ variant: {
13
+ accent: "bg-accent text-accent-content border-accent",
14
+ default: "bg-default text-default-content border-default",
15
+ error: "bg-error text-error-content border-error",
16
+ ghost: "bg-ghost text-ghost-content border-transparent",
17
+ info: "bg-info text-info-content border-info",
18
+ neutral: "bg-neutral text-neutral-content border-neutral",
19
+ primary: "bg-primary text-primary-content border-primary",
20
+ secondary: "bg-secondary text-secondary-content border-secondary",
21
+ success: "bg-success text-success-content border-success",
22
+ warning: "bg-warning text-warning-content border-warning",
23
+ },
24
+ outline: {
25
+ true: "border bg-default",
26
+ },
27
+ },
28
+ compoundVariants: [
29
+ { outline: true, variant: "accent", className: "text-accent" },
30
+ { outline: true, variant: "default", className: "text-default" },
31
+ { outline: true, variant: "error", className: "text-error" },
32
+ { outline: true, variant: "ghost", className: "text-ghost" },
33
+ { outline: true, variant: "info", className: "text-info" },
34
+ { outline: true, variant: "neutral", className: "text-neutral" },
35
+ { outline: true, variant: "primary", className: "text-primary" },
36
+ { outline: true, variant: "secondary", className: "text-secondary" },
37
+ { outline: true, variant: "success", className: "text-success" },
38
+ { outline: true, variant: "warning", className: "text-warning" },
39
+ ],
40
+ });
41
+
42
+ export const getDockButtonClasses = cva("", {
43
+ variants: {
44
+ active: {
45
+ true: "dock-active",
46
+ },
47
+ },
48
+ });
49
+
50
+ export const getDockIconClasses = cva("", {
51
+ variants: {
52
+ size: {
53
+ xs: "size-3",
54
+ sm: "size-4",
55
+ md: "size-5",
56
+ lg: "size-6",
57
+ xl: "size-6",
58
+ },
59
+ },
60
+ });
61
+
62
+ export const getDockLabelClasses = cva("dock-label");
@@ -0,0 +1 @@
1
+ export { Dock } from "./Dock";
@@ -0,0 +1,23 @@
1
+ import type { LucideProps } from "lucide-react";
2
+ import React from "react";
3
+ import { type VariantProps } from "../../libs";
4
+ import {
5
+ getDockButtonClasses,
6
+ getDockClasses,
7
+ getDockIconClasses,
8
+ getDockLabelClasses,
9
+ } from "./constants";
10
+
11
+ export type DockProps = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof getDockClasses>;
12
+
13
+ export type DockButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
14
+ VariantProps<typeof getDockButtonClasses>;
15
+
16
+ export type DockLabelProps = React.HTMLAttributes<HTMLSpanElement> &
17
+ VariantProps<typeof getDockLabelClasses>;
18
+
19
+ type P = Omit<LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>;
20
+ export type DockIconProps = P &
21
+ VariantProps<typeof getDockIconClasses> & {
22
+ icon: React.ForwardRefExoticComponent<P>;
23
+ };
@@ -1,16 +1,77 @@
1
1
  import React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import type { InputLabelProps, InputProps } from "./types";
2
4
  import { cn } from "../../../utilities";
3
- import { getInputClasses } from "./constants";
4
- import { type InputProps } from "./types";
5
+ import { getFloatingLabelClasses, getInputClasses, getInputLabelClasses } from "./constants";
6
+
7
+ const InputLabel = ({ floating, children, ...props }: InputLabelProps) => {
8
+ const SlotChild = ["string", "number", "boolean", "undefined"].includes(typeof children) ? (
9
+ <span>{children}</span>
10
+ ) : (
11
+ children
12
+ );
13
+
14
+ return (
15
+ <Slot className={cn(getInputLabelClasses({ floating }))} {...props}>
16
+ {SlotChild}
17
+ </Slot>
18
+ );
19
+ };
5
20
 
6
21
  export const Input = React.forwardRef<HTMLInputElement, InputProps>(
7
- ({ size, variant, wide, outline, className, type, ...props }: InputProps, ref) => (
8
- <input
9
- ref={ref}
10
- type={type}
11
- className={cn(getInputClasses({ type, size, wide, variant, outline }), className)}
12
- {...props}
13
- />
14
- )
22
+ (
23
+ {
24
+ id,
25
+ size,
26
+ label,
27
+ labelPosition = "start",
28
+ variant,
29
+ wide,
30
+ outline,
31
+ className,
32
+ type,
33
+ ...props
34
+ }: InputProps,
35
+ ref
36
+ ) => {
37
+ if (label) {
38
+ if (labelPosition === "floating") {
39
+ return (
40
+ <label htmlFor={id} className={getFloatingLabelClasses()}>
41
+ <InputLabel floating>{label}</InputLabel>
42
+ <input
43
+ id={id}
44
+ ref={ref}
45
+ type={type}
46
+ className={cn(getInputClasses({ type, size, wide, variant, outline }), className)}
47
+ {...props}
48
+ />
49
+ </label>
50
+ );
51
+ }
52
+
53
+ return (
54
+ <label
55
+ htmlFor={id}
56
+ className={cn(getInputClasses({ type, size, wide, variant, outline }), className)}
57
+ >
58
+ {labelPosition === "start" && <InputLabel>{label}</InputLabel>}
59
+ <input id={id} ref={ref} type={type} {...props} />
60
+ {labelPosition === "end" && <InputLabel>{label}</InputLabel>}
61
+ </label>
62
+ );
63
+ }
64
+
65
+ return (
66
+ <input
67
+ id={id}
68
+ ref={ref}
69
+ type={type}
70
+ className={cn(getInputClasses({ type, size, wide, variant, outline }), className)}
71
+ {...props}
72
+ />
73
+ );
74
+ }
15
75
  );
76
+
16
77
  Input.displayName = "Input";
@@ -35,11 +35,6 @@ export const getInputClasses = cva("input rounded-md transition-all duration-100
35
35
  size: undefined,
36
36
  className: "min-h-fit h-10",
37
37
  },
38
- {
39
- variant: undefined,
40
- outline: true,
41
- className: "border-neutral-content",
42
- },
43
38
  {
44
39
  variant: "default",
45
40
  outline: true,
@@ -47,3 +42,20 @@ export const getInputClasses = cva("input rounded-md transition-all duration-100
47
42
  },
48
43
  ],
49
44
  });
45
+
46
+ export const getFloatingLabelClasses = cva("floating-label");
47
+
48
+ export const getInputLabelClasses = cva("", {
49
+ variants: {
50
+ floating: {
51
+ true: "",
52
+ false: "label",
53
+ },
54
+ },
55
+ compoundVariants: [
56
+ {
57
+ floating: undefined,
58
+ className: "label",
59
+ },
60
+ ],
61
+ });
@@ -1,5 +1,13 @@
1
- import { type VariantProps } from "../../../libs";
2
- import { getInputClasses } from "./constants";
1
+ import type { ReactNode } from "react";
2
+ import type { VariantProps } from "../../../libs";
3
+ import { getInputClasses, getInputLabelClasses } from "./constants";
3
4
 
4
- export type InputProps = Omit<React.HTMLProps<HTMLInputElement>, "size" | "ref"> &
5
- Omit<VariantProps<typeof getInputClasses>, "type">;
5
+ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "size" | "ref"> &
6
+ Omit<VariantProps<typeof getInputClasses>, "type"> & {
7
+ label?: ReactNode;
8
+ labelPosition?: "start" | "end" | "floating";
9
+ };
10
+
11
+ export type InputLabelProps = VariantProps<typeof getInputLabelClasses> & {
12
+ children: ReactNode;
13
+ };
@@ -1,5 +1,8 @@
1
1
  import { type VariantProps } from "../../../libs";
2
2
  import { getRadioClasses } from "./constants";
3
3
 
4
- export type RadioProps = Omit<React.HTMLProps<HTMLInputElement>, "size" | "ref" | "type"> &
4
+ export type RadioProps = Omit<
5
+ React.InputHTMLAttributes<HTMLInputElement>,
6
+ "size" | "ref" | "type"
7
+ > &
5
8
  VariantProps<typeof getRadioClasses>;
@@ -1,5 +1,8 @@
1
1
  import { type VariantProps } from "../../../libs";
2
2
  import { getRangeClasses } from "./constants";
3
3
 
4
- export type RangeProps = Omit<React.HTMLProps<HTMLInputElement>, "size" | "ref" | "type"> &
4
+ export type RangeProps = Omit<
5
+ React.InputHTMLAttributes<HTMLInputElement>,
6
+ "size" | "ref" | "type"
7
+ > &
5
8
  VariantProps<typeof getRangeClasses>;
@@ -2,10 +2,18 @@
2
2
 
3
3
  import * as React from "react";
4
4
  import * as SelectPrimitive from "@radix-ui/react-select";
5
+ import { Slot } from "@radix-ui/react-slot";
5
6
  import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
6
- import type { SelectContentProps, SelectItemProps, SelectTriggerProps } from "./types";
7
+ import type {
8
+ LabelForSelectProps,
9
+ SelectContentProps,
10
+ SelectItemProps,
11
+ SelectTriggerProps,
12
+ } from "./types";
7
13
  import { cn } from "../../../utilities";
8
14
  import {
15
+ getFloatingLabelClasses,
16
+ getLabelForSelectClasses,
9
17
  getSelectContentClasses,
10
18
  getSelectItemClasses,
11
19
  getSelectLabelClasses,
@@ -18,18 +26,71 @@ const Select = (props: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Roo
18
26
  <SelectPrimitive.Root {...props} />
19
27
  );
20
28
 
29
+ const LabelForSelect = ({ children, className, floating, ...props }: LabelForSelectProps) => {
30
+ const SlotChild = ["string", "number", "boolean", "undefined"].includes(typeof children) ? (
31
+ <span>{children}</span>
32
+ ) : (
33
+ children
34
+ );
35
+
36
+ return (
37
+ <Slot className={cn(getLabelForSelectClasses({ floating }), className)} {...props}>
38
+ {SlotChild}
39
+ </Slot>
40
+ );
41
+ };
42
+
21
43
  const SelectTrigger = React.forwardRef<
22
44
  React.ElementRef<typeof SelectPrimitive.Trigger>,
23
45
  SelectTriggerProps
24
- >(({ className, children, size, variant, outline, ...props }, ref) => (
25
- <SelectPrimitive.Trigger
26
- ref={ref}
27
- className={cn(getSelectTriggerClasses({ size, variant, outline }), className)}
28
- {...props}
29
- >
30
- {children}
31
- </SelectPrimitive.Trigger>
32
- ));
46
+ >(
47
+ (
48
+ { id, label, labelPosition = "start", className, children, size, variant, outline, ...props },
49
+ ref
50
+ ) => {
51
+ if (label) {
52
+ if (labelPosition === "floating") {
53
+ return (
54
+ <label htmlFor={id} className={getFloatingLabelClasses()}>
55
+ <LabelForSelect floating>{label}</LabelForSelect>
56
+ <SelectPrimitive.Trigger
57
+ id={id}
58
+ ref={ref}
59
+ className={cn(getSelectTriggerClasses({ size, variant, outline }), className)}
60
+ {...props}
61
+ >
62
+ {children}
63
+ </SelectPrimitive.Trigger>
64
+ </label>
65
+ );
66
+ }
67
+
68
+ return (
69
+ <label
70
+ htmlFor={id}
71
+ className={cn(getSelectTriggerClasses({ size, variant, outline }), className)}
72
+ >
73
+ {labelPosition === "start" && <LabelForSelect>{label}</LabelForSelect>}
74
+ <SelectPrimitive.Trigger id={id} ref={ref} {...props}>
75
+ {children}
76
+ </SelectPrimitive.Trigger>
77
+ {labelPosition === "end" && <LabelForSelect className="me-0!">{label}</LabelForSelect>}
78
+ </label>
79
+ );
80
+ }
81
+
82
+ return (
83
+ <SelectPrimitive.Trigger
84
+ id={id}
85
+ ref={ref}
86
+ className={cn(getSelectTriggerClasses({ size, variant, outline }), className)}
87
+ {...props}
88
+ >
89
+ {children}
90
+ </SelectPrimitive.Trigger>
91
+ );
92
+ }
93
+ );
33
94
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
34
95
 
35
96
  const SelectScrollUpButton = React.forwardRef<
@@ -103,3 +103,20 @@ export const getSelectViewportClasses = cva("p-1", {
103
103
  },
104
104
  },
105
105
  });
106
+
107
+ export const getFloatingLabelClasses = cva("floating-label");
108
+
109
+ export const getLabelForSelectClasses = cva("", {
110
+ variants: {
111
+ floating: {
112
+ true: "",
113
+ false: "label",
114
+ },
115
+ },
116
+ compoundVariants: [
117
+ {
118
+ floating: undefined,
119
+ className: "label",
120
+ },
121
+ ],
122
+ });
@@ -1,13 +1,18 @@
1
+ import { ReactNode } from "react";
1
2
  import * as SelectPrimitive from "@radix-ui/react-select";
2
3
  import { type VariantProps } from "../../../libs";
3
4
  import {
5
+ getLabelForSelectClasses,
4
6
  getSelectContentClasses,
5
7
  getSelectTriggerClasses,
6
8
  getSelectValueClasses,
7
9
  } from "./constants";
8
10
 
9
11
  export type SelectTriggerProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> &
10
- VariantProps<typeof getSelectTriggerClasses>;
12
+ VariantProps<typeof getSelectTriggerClasses> & {
13
+ label?: ReactNode;
14
+ labelPosition?: "start" | "end" | "floating";
15
+ };
11
16
 
12
17
  export type SelectItemProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> &
13
18
  VariantProps<typeof getSelectTriggerClasses>;
@@ -17,3 +22,8 @@ export type SelectContentProps = React.ComponentPropsWithoutRef<typeof SelectPri
17
22
 
18
23
  export type SelectValueProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value> &
19
24
  VariantProps<typeof getSelectValueClasses>;
25
+
26
+ export type LabelForSelectProps = VariantProps<typeof getLabelForSelectClasses> & {
27
+ children: ReactNode;
28
+ className?: string;
29
+ };
@@ -1,5 +1,8 @@
1
1
  import { type VariantProps } from "../../../libs";
2
2
  import { getSwitchClasses } from "./constants";
3
3
 
4
- export type SwitchProps = Omit<React.HTMLProps<HTMLInputElement>, "size" | "ref" | "type"> &
4
+ export type SwitchProps = Omit<
5
+ React.InputHTMLAttributes<HTMLInputElement>,
6
+ "size" | "ref" | "type"
7
+ > &
5
8
  VariantProps<typeof getSwitchClasses>;
@@ -3,5 +3,6 @@ import { type InputProps } from "../Input/types";
3
3
 
4
4
  export type TextFieldProps = InputProps & {
5
5
  info?: ReactNode;
6
+ label?: ReactNode;
6
7
  error?: string | string[] | null;
7
8
  };
@@ -1,12 +1,38 @@
1
1
  import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import type { TextareaLabelProps, TextareaProps } from "./types";
2
4
  import { cn } from "../../../utilities";
3
- import { getTextareaClasses } from "./constants";
4
- import { type TextareaProps } from "./types";
5
+ import { getFloatingLabelClasses, getTextareaClasses } from "./constants";
6
+
7
+ const TextareaLabel = ({ children, ...props }: TextareaLabelProps) => {
8
+ const SlotChild = ["string", "number", "boolean", "undefined"].includes(typeof children) ? (
9
+ <span>{children}</span>
10
+ ) : (
11
+ children
12
+ );
13
+
14
+ return <Slot {...props}>{SlotChild}</Slot>;
15
+ };
5
16
 
6
17
  const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
7
- ({ size, variant, wide, outline, className, ...props }, ref) => {
18
+ ({ id, label, size, variant, wide, outline, className, ...props }, ref) => {
19
+ if (label) {
20
+ return (
21
+ <label htmlFor={id} className={getFloatingLabelClasses()}>
22
+ <TextareaLabel>{label}</TextareaLabel>
23
+ <textarea
24
+ id={id}
25
+ ref={ref}
26
+ className={cn(getTextareaClasses({ size, wide, variant, outline }), className)}
27
+ {...props}
28
+ />
29
+ </label>
30
+ );
31
+ }
32
+
8
33
  return (
9
34
  <textarea
35
+ id={id}
10
36
  ref={ref}
11
37
  className={cn(getTextareaClasses({ size, wide, variant, outline }), className)}
12
38
  {...props}
@@ -48,3 +48,5 @@ export const getTextareaClasses = cva("textarea rounded-md transition-all durati
48
48
  },
49
49
  ],
50
50
  });
51
+
52
+ export const getFloatingLabelClasses = cva("floating-label");
@@ -1,8 +1,15 @@
1
- import { type VariantProps } from "../../../libs";
1
+ import type { ReactNode } from "react";
2
+ import type { VariantProps } from "../../../libs";
2
3
  import { getTextareaClasses } from "./constants";
3
4
 
4
5
  export type TextareaProps = Omit<
5
6
  React.TextareaHTMLAttributes<HTMLTextAreaElement>,
6
7
  "size" | "ref"
7
8
  > &
8
- VariantProps<typeof getTextareaClasses>;
9
+ VariantProps<typeof getTextareaClasses> & {
10
+ label?: ReactNode;
11
+ };
12
+
13
+ export type TextareaLabelProps = {
14
+ children: ReactNode;
15
+ };
@@ -0,0 +1,27 @@
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import type { As, ValidatorHintProps, ValidatorProps } from "./types";
3
+ import { cn } from "../../../utilities";
4
+ import { Text } from "../../Text";
5
+ import { getValidatorClasses, getValidatorHintClasses } from "./constants";
6
+
7
+ const Validator = <T extends As>({ as, children, className, ...props }: ValidatorProps<T>) => {
8
+ const SlotChild = as;
9
+
10
+ return (
11
+ <Slot className={cn(getValidatorClasses(), className)} {...props}>
12
+ <SlotChild>{children}</SlotChild>
13
+ </Slot>
14
+ );
15
+ };
16
+
17
+ const ValidatorHint = ({ className, children, visible, ...props }: ValidatorHintProps) => {
18
+ return (
19
+ <Text className={cn(getValidatorHintClasses({ visible }), className)} {...props}>
20
+ {children}
21
+ </Text>
22
+ );
23
+ };
24
+
25
+ Validator.Hint = ValidatorHint;
26
+
27
+ export { Validator };
@@ -0,0 +1,18 @@
1
+ import { cva } from "../../../libs";
2
+
3
+ export const getValidatorClasses = cva("border-color-[unset] validator");
4
+
5
+ export const getValidatorHintClasses = cva("validator-hint", {
6
+ variants: {
7
+ visible: {
8
+ true: "block",
9
+ false: "hidden",
10
+ },
11
+ },
12
+ compoundVariants: [
13
+ {
14
+ visible: undefined,
15
+ className: "hidden",
16
+ },
17
+ ],
18
+ });
@@ -0,0 +1 @@
1
+ export { Validator } from "./Validator";