@nomos-ui/form 0.0.7 → 0.0.9
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/dist/components/form-select.d.ts +56 -0
- package/dist/components/form-select.d.ts.map +1 -0
- package/dist/components/form-select.js +50 -0
- package/dist/components/form-select.js.map +1 -0
- package/dist/components/form-textarea.d.ts +44 -0
- package/dist/components/form-textarea.d.ts.map +1 -0
- package/dist/components/form-textarea.js +42 -0
- package/dist/components/form-textarea.js.map +1 -0
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +0 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/select.d.ts +7 -3
- package/dist/components/select.d.ts.map +1 -1
- package/dist/components/select.js +45 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/textarea.d.ts +69 -0
- package/dist/components/textarea.d.ts.map +1 -0
- package/dist/components/textarea.js +57 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/exports/index.d.ts +5 -2
- package/dist/exports/index.d.ts.map +1 -1
- package/dist/exports/index.js +7 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/utils/index.d.ts +3 -0
- package/dist/exports/utils/index.d.ts.map +1 -0
- package/dist/exports/utils/index.js +7 -0
- package/dist/exports/utils/index.js.map +1 -0
- package/dist/utils/helpers/form.helpers.d.ts +28 -0
- package/dist/utils/helpers/form.helpers.d.ts.map +1 -1
- package/dist/utils/helpers/form.helpers.js +67 -0
- package/dist/utils/helpers/form.helpers.js.map +1 -1
- package/package.json +17 -8
- package/dist/components/multiple-select.d.ts +0 -40
- package/dist/components/multiple-select.d.ts.map +0 -1
- package/dist/components/multiple-select.js +0 -57
- package/dist/components/multiple-select.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Control, FieldValues, Path, PathValue } from "react-hook-form";
|
|
2
|
+
import Select, { SelectOption } from "./select";
|
|
3
|
+
import React from "react";
|
|
4
|
+
/**
|
|
5
|
+
* Props for the `FormSelect` component with type-safe form integration
|
|
6
|
+
*/
|
|
7
|
+
export type FormSelectProps<TFieldValues extends FieldValues, T extends string = string> = {
|
|
8
|
+
/** React Hook Form control instance */
|
|
9
|
+
control: Control<TFieldValues>;
|
|
10
|
+
/** The name of the field (type-safe, must match form schema) */
|
|
11
|
+
name: Path<TFieldValues>;
|
|
12
|
+
/** Default value of the select (type-safe based on field) */
|
|
13
|
+
defaultValue?: PathValue<TFieldValues, Path<TFieldValues>>;
|
|
14
|
+
/** Select options */
|
|
15
|
+
options: SelectOption<T>[];
|
|
16
|
+
/** Enable multiple selection */
|
|
17
|
+
multiple?: boolean;
|
|
18
|
+
} & Omit<React.ComponentProps<typeof Select>, "value" | "onChange" | "control" | "options">;
|
|
19
|
+
/**
|
|
20
|
+
* A form select component that adds type-safe form functionality to the base Select component.
|
|
21
|
+
* Designed to integrate with React Hook Form with full TypeScript support.
|
|
22
|
+
*
|
|
23
|
+
* @component
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* type FormData = {
|
|
27
|
+
* country: string;
|
|
28
|
+
* hobbies: string[];
|
|
29
|
+
* };
|
|
30
|
+
*
|
|
31
|
+
* const { control } = useForm<FormData>();
|
|
32
|
+
*
|
|
33
|
+
* // Single select
|
|
34
|
+
* <FormSelect
|
|
35
|
+
* control={control}
|
|
36
|
+
* name="country"
|
|
37
|
+
* options={countryOptions}
|
|
38
|
+
* label="Country"
|
|
39
|
+
* placeholder="Select a country"
|
|
40
|
+
* required
|
|
41
|
+
* />
|
|
42
|
+
*
|
|
43
|
+
* // Multiple select
|
|
44
|
+
* <FormSelect
|
|
45
|
+
* control={control}
|
|
46
|
+
* name="hobbies"
|
|
47
|
+
* options={hobbyOptions}
|
|
48
|
+
* label="Hobbies"
|
|
49
|
+
* placeholder="Select hobbies"
|
|
50
|
+
* multiple
|
|
51
|
+
* required
|
|
52
|
+
* />
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export default function FormSelect<TFieldValues extends FieldValues, T extends string = string>({ control, name, defaultValue, required, multiple, options, ...props }: FormSelectProps<TFieldValues, T>): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
//# sourceMappingURL=form-select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-select.d.ts","sourceRoot":"","sources":["../../src/components/form-select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,WAAW,EACX,IAAI,EACJ,SAAS,EACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;GAEG;AACH,MAAM,MAAM,eAAe,CACzB,YAAY,SAAS,WAAW,EAChC,CAAC,SAAS,MAAM,GAAG,MAAM,IACvB;IACF,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,gEAAgE;IAChE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,qBAAqB;IACrB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,IAAI,CACN,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EACnC,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAC7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,YAAY,SAAS,WAAW,EAChC,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,EACA,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAe,EACf,QAAgB,EAChB,OAAO,EACP,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,YAAY,EAAE,CAAC,CAAC,2CAsBlC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = FormSelect;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
9
|
+
const select_1 = __importDefault(require("./select"));
|
|
10
|
+
const form_helpers_1 = require("../utils/helpers/form.helpers");
|
|
11
|
+
/**
|
|
12
|
+
* A form select component that adds type-safe form functionality to the base Select component.
|
|
13
|
+
* Designed to integrate with React Hook Form with full TypeScript support.
|
|
14
|
+
*
|
|
15
|
+
* @component
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* type FormData = {
|
|
19
|
+
* country: string;
|
|
20
|
+
* hobbies: string[];
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* const { control } = useForm<FormData>();
|
|
24
|
+
*
|
|
25
|
+
* // Single select
|
|
26
|
+
* <FormSelect
|
|
27
|
+
* control={control}
|
|
28
|
+
* name="country"
|
|
29
|
+
* options={countryOptions}
|
|
30
|
+
* label="Country"
|
|
31
|
+
* placeholder="Select a country"
|
|
32
|
+
* required
|
|
33
|
+
* />
|
|
34
|
+
*
|
|
35
|
+
* // Multiple select
|
|
36
|
+
* <FormSelect
|
|
37
|
+
* control={control}
|
|
38
|
+
* name="hobbies"
|
|
39
|
+
* options={hobbyOptions}
|
|
40
|
+
* label="Hobbies"
|
|
41
|
+
* placeholder="Select hobbies"
|
|
42
|
+
* multiple
|
|
43
|
+
* required
|
|
44
|
+
* />
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
function FormSelect({ control, name, defaultValue, required = true, multiple = false, options, ...props }) {
|
|
48
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "w-full", children: (0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, defaultValue: defaultValue, rules: { required: required ? "Required" : false }, render: ({ field: { onChange, value }, formState: { errors } }) => ((0, jsx_runtime_1.jsx)(select_1.default, { value: value ?? (multiple ? [] : ""), onChange: onChange, required: required, multiple: multiple, options: options, error: (0, form_helpers_1.getNestedErrorMessage)(errors || {}, name), ...props })) }) }));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=form-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-select.js","sourceRoot":"","sources":["../../src/components/form-select.tsx"],"names":[],"mappings":";;;;;AAqEA,6BAiCC;;AAtGD,qDAMyB;AACzB,sDAAgD;AAEhD,gEAAsE;AAwBtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,SAAwB,UAAU,CAGhC,EACA,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAQ,GAAG,IAAI,EACf,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,GAAG,KAAK,EACyB;IACjC,OAAO,CACL,gCAAK,SAAS,EAAC,QAAQ,YACrB,uBAAC,4BAAU,IACT,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,EAClD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CACjE,uBAAC,gBAAM,IACL,KAAK,EAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACpC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,IAAA,oCAAqB,EAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAW,KACtD,KAAK,GACT,CACH,GACD,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Control, FieldValues, Path, PathValue } from "react-hook-form";
|
|
2
|
+
import Textarea from "./textarea";
|
|
3
|
+
import React from "react";
|
|
4
|
+
/**
|
|
5
|
+
* Props for the `FormTextarea` component with type-safe form integration
|
|
6
|
+
*/
|
|
7
|
+
export type FormTextareaProps<TFieldValues extends FieldValues> = {
|
|
8
|
+
/** React Hook Form control instance */
|
|
9
|
+
control: Control<TFieldValues>;
|
|
10
|
+
/** The name of the field (type-safe, must match form schema) */
|
|
11
|
+
name: Path<TFieldValues>;
|
|
12
|
+
/** Default value of the textarea (type-safe based on field) */
|
|
13
|
+
defaultValue?: PathValue<TFieldValues, Path<TFieldValues>>;
|
|
14
|
+
} & Omit<React.ComponentProps<typeof Textarea>, "value" | "onChange" | "error" | "control">;
|
|
15
|
+
/**
|
|
16
|
+
* A form textarea component that adds type-safe form functionality to the base Textarea component.
|
|
17
|
+
* Designed to integrate with React Hook Form with full TypeScript support.
|
|
18
|
+
*
|
|
19
|
+
* @component
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* type FormData = {
|
|
23
|
+
* description: string;
|
|
24
|
+
* bio: string;
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* const { control } = useForm<FormData>();
|
|
28
|
+
*
|
|
29
|
+
* <FormTextarea
|
|
30
|
+
* control={control}
|
|
31
|
+
* name="description"
|
|
32
|
+
* defaultValue=""
|
|
33
|
+
* label="Description"
|
|
34
|
+
* placeholder="Enter description"
|
|
35
|
+
* required
|
|
36
|
+
* rows={6}
|
|
37
|
+
* maxLength={500}
|
|
38
|
+
* showCharCount
|
|
39
|
+
* tip="Provide a detailed description"
|
|
40
|
+
* />
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export default function FormTextarea<TFieldValues extends FieldValues>({ control, name, defaultValue, required, ...props }: FormTextareaProps<TFieldValues>): import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
//# sourceMappingURL=form-textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-textarea.d.ts","sourceRoot":"","sources":["../../src/components/form-textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,WAAW,EACX,IAAI,EACJ,SAAS,EACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,WAAW,IAAI;IAChE,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,gEAAgE;IAChE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;CAC5D,GAAG,IAAI,CACN,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,EACrC,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAC3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,YAAY,SAAS,WAAW,EAAE,EACrE,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAe,EACf,GAAG,KAAK,EACT,EAAE,iBAAiB,CAAC,YAAY,CAAC,2CAmBjC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = FormTextarea;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
9
|
+
const textarea_1 = __importDefault(require("./textarea"));
|
|
10
|
+
const form_helpers_1 = require("../utils/helpers/form.helpers");
|
|
11
|
+
/**
|
|
12
|
+
* A form textarea component that adds type-safe form functionality to the base Textarea component.
|
|
13
|
+
* Designed to integrate with React Hook Form with full TypeScript support.
|
|
14
|
+
*
|
|
15
|
+
* @component
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* type FormData = {
|
|
19
|
+
* description: string;
|
|
20
|
+
* bio: string;
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* const { control } = useForm<FormData>();
|
|
24
|
+
*
|
|
25
|
+
* <FormTextarea
|
|
26
|
+
* control={control}
|
|
27
|
+
* name="description"
|
|
28
|
+
* defaultValue=""
|
|
29
|
+
* label="Description"
|
|
30
|
+
* placeholder="Enter description"
|
|
31
|
+
* required
|
|
32
|
+
* rows={6}
|
|
33
|
+
* maxLength={500}
|
|
34
|
+
* showCharCount
|
|
35
|
+
* tip="Provide a detailed description"
|
|
36
|
+
* />
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function FormTextarea({ control, name, defaultValue, required = true, ...props }) {
|
|
40
|
+
return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, defaultValue: defaultValue, rules: { required: required ? "Required" : false }, render: ({ field: { onChange, value }, formState: { errors } }) => ((0, jsx_runtime_1.jsx)(textarea_1.default, { id: `form-textarea-${name}`, value: value ?? "", onChange: onChange, required: required, error: (0, form_helpers_1.getNestedErrorMessage)(errors || {}, name), ...props })) }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=form-textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-textarea.js","sourceRoot":"","sources":["../../src/components/form-textarea.tsx"],"names":[],"mappings":";;;;;AAsDA,+BAyBC;;AA/ED,qDAMyB;AACzB,0DAAkC;AAElC,gEAAsE;AAiBtE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAwB,YAAY,CAAmC,EACrE,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAQ,GAAG,IAAI,EACf,GAAG,KAAK,EACwB;IAChC,OAAO,CACL,uBAAC,4BAAU,IACT,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,EAClD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CACjE,uBAAC,kBAAQ,IACP,EAAE,EAAE,iBAAiB,IAAI,EAAE,EAC3B,KAAK,EAAE,KAAK,IAAI,EAAE,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,IAAA,oCAAqB,EAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,KAC5C,KAAK,GACT,CACH,GACD,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,MAAM,IAAI;IAC/B,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5E,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,gCAAgC;IAChC,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAC3B,MAAM,SAAS,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACjD,EACA,cAAc,EACd,SAAS,EACT,WAAW,EACX,KAAK,EACL,cAAc,EACd,IAAa,EACb,QAAgB,EAChB,IAAY,EACZ,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,gBAAwB,EACxB,GAAG,EACH,KAAK,EACL,uBAAuB,EACvB,GAAG,EACH,QAAQ,EACR,cAAc,EACd,GAAG,KAAK,EACT,EAAE,UAAU,CAAC,MAAM,CAAC,GACnB,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,2CAqI5E"}
|
package/dist/components/input.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,10 @@ export type SelectProps<T = string> = {
|
|
|
9
9
|
required?: boolean;
|
|
10
10
|
showRequiredSign?: boolean;
|
|
11
11
|
options: SelectOption<T>[];
|
|
12
|
-
value?: T;
|
|
13
|
-
onChange?: (value: T) => void;
|
|
12
|
+
value?: T | T[];
|
|
13
|
+
onChange?: (value: T | T[]) => void;
|
|
14
14
|
placeholder?: string;
|
|
15
|
+
multiple?: boolean;
|
|
15
16
|
labelProps?: {
|
|
16
17
|
className?: string;
|
|
17
18
|
};
|
|
@@ -30,9 +31,12 @@ export type SelectProps<T = string> = {
|
|
|
30
31
|
itemProps?: {
|
|
31
32
|
className?: string;
|
|
32
33
|
};
|
|
34
|
+
error?: string;
|
|
35
|
+
tip?: string;
|
|
33
36
|
};
|
|
34
37
|
/**
|
|
35
38
|
* Customizable select dropdown with smart positioning and flexible styling
|
|
39
|
+
* Supports both single and multiple selection
|
|
36
40
|
*/
|
|
37
|
-
export default function Select<T extends string = string>({ className, label, required, showRequiredSign, options, value, onChange, placeholder, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, }: SelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export default function Select<T extends string = string>({ className, label, required, showRequiredSign, options, value, onChange, placeholder, multiple, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, error, tip, }: SelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
38
42
|
//# sourceMappingURL=select.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,MAAM,IAAI;IACrC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,MAAM,IAAI;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,MAAM,IAAI;IACrC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,MAAM,IAAI;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,EACxD,SAAS,EACT,KAAK,EACL,QAAgB,EAChB,gBAAwB,EACxB,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAgB,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,EACT,KAAK,EACL,GAAG,GACJ,EAAE,WAAW,CAAC,CAAC,CAAC,2CAoKhB"}
|
|
@@ -7,8 +7,51 @@ const tailwind_merge_1 = require("tailwind-merge");
|
|
|
7
7
|
const lucide_react_1 = require("lucide-react");
|
|
8
8
|
/**
|
|
9
9
|
* Customizable select dropdown with smart positioning and flexible styling
|
|
10
|
+
* Supports both single and multiple selection
|
|
10
11
|
*/
|
|
11
|
-
function Select({ className, label, required = false, showRequiredSign = false, options, value, onChange, placeholder, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, }) {
|
|
12
|
-
|
|
12
|
+
function Select({ className, label, required = false, showRequiredSign = false, options, value, onChange, placeholder, multiple = false, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, error, tip, }) {
|
|
13
|
+
const handleValueChange = (newValue) => {
|
|
14
|
+
if (!multiple) {
|
|
15
|
+
onChange?.(newValue);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const currentValues = Array.isArray(value) ? value : [];
|
|
19
|
+
const isSelected = currentValues.includes(newValue);
|
|
20
|
+
if (isSelected) {
|
|
21
|
+
const filtered = currentValues.filter((v) => v !== newValue);
|
|
22
|
+
onChange?.(filtered);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
onChange?.([...currentValues, newValue]);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const handleRemoveTag = (valueToRemove) => {
|
|
29
|
+
if (!multiple || !Array.isArray(value))
|
|
30
|
+
return;
|
|
31
|
+
const filtered = value.filter((v) => v !== valueToRemove);
|
|
32
|
+
onChange?.(filtered);
|
|
33
|
+
};
|
|
34
|
+
const getSelectedLabels = () => {
|
|
35
|
+
if (!multiple || !Array.isArray(value))
|
|
36
|
+
return null;
|
|
37
|
+
return value
|
|
38
|
+
.map((v) => options.find((opt) => opt.value === v))
|
|
39
|
+
.filter(Boolean)
|
|
40
|
+
.map((opt) => ({
|
|
41
|
+
value: opt.value,
|
|
42
|
+
label: opt.label,
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
if (multiple) {
|
|
46
|
+
const selectedLabels = getSelectedLabels();
|
|
47
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tailwind_merge_1.twMerge)("gap-1 grid", className), children: [label && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-row items-center gap-1", children: [(0, jsx_runtime_1.jsx)("label", { className: (0, tailwind_merge_1.twMerge)("font-bold", labelProps?.className), children: label }), required && showRequiredSign && ((0, jsx_runtime_1.jsx)(lucide_react_1.AsteriskIcon, { size: 12, color: "red" }))] })), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: "", onValueChange: handleValueChange, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: (0, tailwind_merge_1.twMerge)("min-h-10", triggerProps?.className), children: (0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2 flex-1", children: selectedLabels && selectedLabels.length > 0 ? (selectedLabels.map((item) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 px-2 py-1 text-sm bg-blue-100 text-blue-800 rounded-md", onClick: (e) => e.stopPropagation(), children: [item.label, (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 14, className: "cursor-pointer hover:text-blue-600", onClick: (e) => {
|
|
48
|
+
e.stopPropagation();
|
|
49
|
+
handleRemoveTag(item.value);
|
|
50
|
+
} })] }, String(item.value))))) : ((0, jsx_runtime_1.jsx)("span", { className: (0, tailwind_merge_1.twMerge)("text-muted-foreground", valueProps?.className), children: placeholder })) }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { className: contentProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { className: groupProps?.className, children: options.map((option) => {
|
|
51
|
+
const isSelected = Array.isArray(value) && value.includes(option.value);
|
|
52
|
+
return ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, className: (0, tailwind_merge_1.twMerge)(isSelected && "bg-blue-50", itemProps?.className), children: option.label }, String(option.value)));
|
|
53
|
+
}) }) })] }), tip && !error && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-muted-foreground tip-message", children: tip })), error && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-destructive error-message", children: ["*", error] }))] }));
|
|
54
|
+
}
|
|
55
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tailwind_merge_1.twMerge)("gap-1 grid", className), children: [label && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-row items-center gap-1", children: [(0, jsx_runtime_1.jsx)("label", { className: (0, tailwind_merge_1.twMerge)("font-bold", labelProps?.className), children: label }), required && showRequiredSign && ((0, jsx_runtime_1.jsx)(lucide_react_1.AsteriskIcon, { size: 12, color: "red" }))] })), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: value, onValueChange: onChange, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: triggerProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: placeholder, className: valueProps?.className }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { className: contentProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { className: groupProps?.className, children: options.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, className: itemProps?.className, children: option.label }, String(option.value)))) }) })] }), tip && !error && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-muted-foreground tip-message", children: tip })), error && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-destructive error-message", children: ["*", error] }))] }));
|
|
13
56
|
}
|
|
14
57
|
//# sourceMappingURL=select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Props for the enhanced Textarea component
|
|
4
|
+
*/
|
|
5
|
+
export type TextareaProps<TValue extends string | null | undefined> = {
|
|
6
|
+
/** Additional class name for the textarea element */
|
|
7
|
+
textareaClassName?: string;
|
|
8
|
+
/** Additional class name for the container */
|
|
9
|
+
className?: string;
|
|
10
|
+
/** Placeholder text for the textarea */
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
/** Label text for the textarea */
|
|
13
|
+
label?: string;
|
|
14
|
+
/** Additional class name for the label */
|
|
15
|
+
labelClassName?: string;
|
|
16
|
+
/** Additional class name for the textarea container/wrapper */
|
|
17
|
+
textareaContainerClassName?: string;
|
|
18
|
+
/** Whether the textarea is disabled */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** Whether to trim textarea value before calling onChange */
|
|
21
|
+
trim?: boolean;
|
|
22
|
+
/** Current value of the textarea */
|
|
23
|
+
value?: TValue;
|
|
24
|
+
/** Callback fired when textarea value changes */
|
|
25
|
+
onChange?: (value: TValue, e?: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
26
|
+
/** Whether the field is required */
|
|
27
|
+
required?: boolean;
|
|
28
|
+
/** Whether to show an asterisk for required fields */
|
|
29
|
+
showRequiredSign?: boolean;
|
|
30
|
+
/** Tooltip text providing additional information */
|
|
31
|
+
tip?: string;
|
|
32
|
+
/** Error message to display */
|
|
33
|
+
error?: string;
|
|
34
|
+
/** Ref for the container div */
|
|
35
|
+
ref?: any;
|
|
36
|
+
/** Ref for the textarea element */
|
|
37
|
+
textareaRef?: any;
|
|
38
|
+
/** Number of visible text rows */
|
|
39
|
+
rows?: number;
|
|
40
|
+
/** Maximum character length */
|
|
41
|
+
maxLength?: number;
|
|
42
|
+
/** Whether to show character counter */
|
|
43
|
+
showCharCount?: boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* An enhanced textarea component with:
|
|
47
|
+
* - Label support with required indicators
|
|
48
|
+
* - Focus state management
|
|
49
|
+
* - Error state with validation
|
|
50
|
+
* - Character counter
|
|
51
|
+
* - Value trimming
|
|
52
|
+
* - Semantic color tokens from design system
|
|
53
|
+
*
|
|
54
|
+
* @component
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* <Textarea
|
|
58
|
+
* label="Description"
|
|
59
|
+
* required
|
|
60
|
+
* showRequiredSign
|
|
61
|
+
* maxLength={500}
|
|
62
|
+
* showCharCount
|
|
63
|
+
* value={description}
|
|
64
|
+
* onChange={(value) => setDescription(value)}
|
|
65
|
+
* />
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export default function Textarea<TValue extends string | null | undefined>({ textareaClassName, className, placeholder, label, labelClassName, disabled, trim, value, onChange, required, showRequiredSign, tip, error, textareaContainerClassName, ref, textareaRef, rows, maxLength, showCharCount, ...props }: TextareaProps<TValue> & Omit<React.ComponentProps<"textarea">, keyof TextareaProps<TValue>>): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
//# sourceMappingURL=textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,SAAS,IAAI;IACpE,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,mBAAmB,CAAC,KACvC,IAAI,CAAC;IACV,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,mCAAmC;IACnC,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,EACzE,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,KAAK,EACL,cAAc,EACd,QAAgB,EAChB,IAAY,EACZ,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,gBAAwB,EACxB,GAAG,EACH,KAAK,EACL,0BAA0B,EAC1B,GAAG,EACH,WAAW,EACX,IAAQ,EACR,SAAS,EACT,aAAqB,EACrB,GAAG,KAAK,EACT,EAAE,aAAa,CAAC,MAAM,CAAC,GACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC,2CA+FpE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.default = Textarea;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const lucide_react_1 = require("lucide-react");
|
|
8
|
+
const utils_1 = require("../utils/shadcn-ui/utils");
|
|
9
|
+
/**
|
|
10
|
+
* An enhanced textarea component with:
|
|
11
|
+
* - Label support with required indicators
|
|
12
|
+
* - Focus state management
|
|
13
|
+
* - Error state with validation
|
|
14
|
+
* - Character counter
|
|
15
|
+
* - Value trimming
|
|
16
|
+
* - Semantic color tokens from design system
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <Textarea
|
|
22
|
+
* label="Description"
|
|
23
|
+
* required
|
|
24
|
+
* showRequiredSign
|
|
25
|
+
* maxLength={500}
|
|
26
|
+
* showCharCount
|
|
27
|
+
* value={description}
|
|
28
|
+
* onChange={(value) => setDescription(value)}
|
|
29
|
+
* />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function Textarea({ textareaClassName, className, placeholder, label, labelClassName, disabled = false, trim = false, value, onChange, required = false, showRequiredSign = false, tip, error, textareaContainerClassName, ref, textareaRef, rows = 4, maxLength, showCharCount = false, ...props }) {
|
|
33
|
+
const [isFocused, setIsFocused] = (0, react_1.useState)(false);
|
|
34
|
+
function handleOnChange(val, e) {
|
|
35
|
+
if (disabled || !onChange)
|
|
36
|
+
return;
|
|
37
|
+
onChange((trim ? val.trim() : val), e);
|
|
38
|
+
}
|
|
39
|
+
const currentValue = (0, react_1.useMemo)(() => value || "", [value]);
|
|
40
|
+
const charCount = currentValue.toString().length;
|
|
41
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)("w-full space-y-1.5", className), ref: ref, children: [label && ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)("flex items-center gap-1", labelClassName), children: [(0, jsx_runtime_1.jsx)("label", { className: "text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: label }), required && showRequiredSign && ((0, jsx_runtime_1.jsx)(lucide_react_1.AsteriskIcon, { className: "h-3 w-3 text-destructive" }))] })), (0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)("relative flex w-full rounded-md border bg-transparent shadow-xs transition-[color,box-shadow]", isFocused && !error && "border-ring ring-[3px] ring-ring/50", error &&
|
|
42
|
+
"border-destructive ring-[3px] ring-destructive/20 dark:ring-destructive/40", !isFocused && !error && "border-textarea", disabled && "cursor-not-allowed opacity-50", textareaContainerClassName), children: (0, jsx_runtime_1.jsx)("textarea", { disabled: disabled, required: required, onBlur: (e) => {
|
|
43
|
+
props?.onBlur?.(e);
|
|
44
|
+
setIsFocused(false);
|
|
45
|
+
}, onFocus: (e) => {
|
|
46
|
+
props?.onFocus?.(e);
|
|
47
|
+
setIsFocused(true);
|
|
48
|
+
}, onChange: (e) => {
|
|
49
|
+
const value = e.currentTarget.value;
|
|
50
|
+
if (onChange) {
|
|
51
|
+
handleOnChange(value, e);
|
|
52
|
+
}
|
|
53
|
+
}, value: currentValue, placeholder: placeholder, rows: rows, maxLength: maxLength, className: (0, utils_1.cn)("w-full flex-1 bg-transparent px-3 py-2 text-base outline-none resize-y min-h-16", "disabled:cursor-not-allowed disabled:bg-transparent", "md:text-sm", "placeholder:text-muted-foreground", textareaClassName), ref: textareaRef, ...props }) }), (tip || showCharCount || error) && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-1", children: [tip && !error && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-muted-foreground", children: tip })), error && (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-destructive", children: ["*", error] })] }), showCharCount && maxLength && ((0, jsx_runtime_1.jsxs)("p", { className: (0, utils_1.cn)("text-xs tabular-nums", charCount > maxLength
|
|
54
|
+
? "text-destructive"
|
|
55
|
+
: "text-muted-foreground"), children: [charCount, "/", maxLength] }))] }))] }));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"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"}
|
package/dist/exports/index.d.ts
CHANGED
|
@@ -2,8 +2,11 @@ import Button from "../components/button";
|
|
|
2
2
|
import FormInput from "../components/form-input";
|
|
3
3
|
import Input from "../components/input";
|
|
4
4
|
import Select, { SelectOption, SelectProps } from "../components/select";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import FormSelect, { FormSelectProps } from "../components/form-select";
|
|
6
|
+
import Textarea from "../components/textarea";
|
|
7
|
+
import FormTextarea from "../components/form-textarea";
|
|
8
|
+
export { Button, FormInput, Input, Select, FormSelect, Textarea, FormTextarea };
|
|
9
|
+
export type { SelectOption, SelectProps, FormSelectProps };
|
|
7
10
|
export * from "../components/input";
|
|
8
11
|
export * from "../components/form-input";
|
|
9
12
|
export * from "../components/button";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,SAAS,MAAM,0BAA0B,CAAC;AACjD,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,SAAS,MAAM,0BAA0B,CAAC;AACjD,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,UAAU,EAAE,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AAC9C,OAAO,YAAY,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AAC3D,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC"}
|
package/dist/exports/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.Select = exports.Input = exports.FormInput = exports.Button = void 0;
|
|
20
|
+
exports.FormTextarea = exports.Textarea = exports.FormSelect = exports.Select = exports.Input = exports.FormInput = exports.Button = void 0;
|
|
21
21
|
const button_1 = __importDefault(require("../components/button"));
|
|
22
22
|
exports.Button = button_1.default;
|
|
23
23
|
const form_input_1 = __importDefault(require("../components/form-input"));
|
|
@@ -26,6 +26,12 @@ const input_1 = __importDefault(require("../components/input"));
|
|
|
26
26
|
exports.Input = input_1.default;
|
|
27
27
|
const select_1 = __importDefault(require("../components/select"));
|
|
28
28
|
exports.Select = select_1.default;
|
|
29
|
+
const form_select_1 = __importDefault(require("../components/form-select"));
|
|
30
|
+
exports.FormSelect = form_select_1.default;
|
|
31
|
+
const textarea_1 = __importDefault(require("../components/textarea"));
|
|
32
|
+
exports.Textarea = textarea_1.default;
|
|
33
|
+
const form_textarea_1 = __importDefault(require("../components/form-textarea"));
|
|
34
|
+
exports.FormTextarea = form_textarea_1.default;
|
|
29
35
|
__exportStar(require("../components/input"), exports);
|
|
30
36
|
__exportStar(require("../components/form-input"), exports);
|
|
31
37
|
__exportStar(require("../components/button"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kEAA0C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kEAA0C;AAQjC,iBARF,gBAAM,CAQE;AAPf,0EAAiD;AAOhC,oBAPV,oBAAS,CAOU;AAN1B,gEAAwC;AAMZ,gBANrB,eAAK,CAMqB;AALjC,kEAAyE;AAKtC,iBAL5B,gBAAM,CAK4B;AAJzC,4EAAwE;AAI7B,qBAJpC,qBAAU,CAIoC;AAHrD,sEAA8C;AAGS,mBAHhD,kBAAQ,CAGgD;AAF/D,gFAAuD;AAEU,uBAF1D,uBAAY,CAE0D;AAE7E,sDAAoC;AACpC,2DAAyC;AACzC,uDAAqC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/exports/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNestedErrorMessage = exports.objectToFormData = void 0;
|
|
4
|
+
const form_helpers_1 = require("../../utils/helpers/form.helpers");
|
|
5
|
+
Object.defineProperty(exports, "objectToFormData", { enumerable: true, get: function () { return form_helpers_1.objectToFormData; } });
|
|
6
|
+
Object.defineProperty(exports, "getNestedErrorMessage", { enumerable: true, get: function () { return form_helpers_1.getNestedErrorMessage; } });
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/exports/utils/index.ts"],"names":[],"mappings":";;;AAAA,mEAG0C;AAEjC,iGAJP,+BAAgB,OAIO;AAAE,sGAHzB,oCAAqB,OAGyB"}
|
|
@@ -1,2 +1,30 @@
|
|
|
1
1
|
export declare function getNestedErrorMessage(errors: Record<string, any>, path: string): any;
|
|
2
|
+
/**
|
|
3
|
+
* Converts a JSON object to FormData with support for nested objects, arrays, and files.
|
|
4
|
+
*
|
|
5
|
+
* @param {Record<string, any>} json - The JSON object to convert
|
|
6
|
+
* @param {FormData} [formData=new FormData()] - Optional existing FormData to append to
|
|
7
|
+
* @param {string} [parentKey=''] - Internal parameter for tracking nested keys
|
|
8
|
+
* @returns {FormData} The populated FormData object
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const data = {
|
|
12
|
+
* name: 'John',
|
|
13
|
+
* tags: ['js', 'react'],
|
|
14
|
+
* profile: {
|
|
15
|
+
* age: 30,
|
|
16
|
+
* address: {
|
|
17
|
+
* city: 'NYC'
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* };
|
|
21
|
+
* const formData = jsonToFormData(data);
|
|
22
|
+
* // Results in:
|
|
23
|
+
* // name: 'John'
|
|
24
|
+
* // tags[0]: 'js'
|
|
25
|
+
* // tags[1]: 'react'
|
|
26
|
+
* // profile[age]: 30
|
|
27
|
+
* // profile[address][city]: 'NYC'
|
|
28
|
+
*/
|
|
29
|
+
export declare function objectToFormData(obj: Record<string, any>, formData?: FormData, parentKey?: string): FormData;
|
|
2
30
|
//# sourceMappingURL=form.helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/form.helpers.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,EAAE,MAAM,OAWb"}
|
|
1
|
+
{"version":3,"file":"form.helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/form.helpers.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,EAAE,MAAM,OAWb;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACxB,QAAQ,GAAE,QAAyB,EACnC,SAAS,GAAE,MAAW,GACrB,QAAQ,CAsCV"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNestedErrorMessage = getNestedErrorMessage;
|
|
4
|
+
exports.objectToFormData = objectToFormData;
|
|
4
5
|
function getNestedErrorMessage(errors, path) {
|
|
5
6
|
const parts = path.split(".");
|
|
6
7
|
let current = errors;
|
|
@@ -11,4 +12,70 @@ function getNestedErrorMessage(errors, path) {
|
|
|
11
12
|
}
|
|
12
13
|
return current.message ? current.message : null;
|
|
13
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Converts a JSON object to FormData with support for nested objects, arrays, and files.
|
|
17
|
+
*
|
|
18
|
+
* @param {Record<string, any>} json - The JSON object to convert
|
|
19
|
+
* @param {FormData} [formData=new FormData()] - Optional existing FormData to append to
|
|
20
|
+
* @param {string} [parentKey=''] - Internal parameter for tracking nested keys
|
|
21
|
+
* @returns {FormData} The populated FormData object
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const data = {
|
|
25
|
+
* name: 'John',
|
|
26
|
+
* tags: ['js', 'react'],
|
|
27
|
+
* profile: {
|
|
28
|
+
* age: 30,
|
|
29
|
+
* address: {
|
|
30
|
+
* city: 'NYC'
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
* };
|
|
34
|
+
* const formData = jsonToFormData(data);
|
|
35
|
+
* // Results in:
|
|
36
|
+
* // name: 'John'
|
|
37
|
+
* // tags[0]: 'js'
|
|
38
|
+
* // tags[1]: 'react'
|
|
39
|
+
* // profile[age]: 30
|
|
40
|
+
* // profile[address][city]: 'NYC'
|
|
41
|
+
*/
|
|
42
|
+
function objectToFormData(obj, formData = new FormData(), parentKey = "") {
|
|
43
|
+
if (obj === null || obj === undefined)
|
|
44
|
+
return formData;
|
|
45
|
+
for (const key in obj) {
|
|
46
|
+
if (!obj.hasOwnProperty(key))
|
|
47
|
+
continue;
|
|
48
|
+
const value = obj[key];
|
|
49
|
+
const formKey = parentKey ? `${parentKey}[${key}]` : key;
|
|
50
|
+
if ((value instanceof File || value instanceof Blob) && value) {
|
|
51
|
+
formData.append(formKey, value);
|
|
52
|
+
}
|
|
53
|
+
else if (Array.isArray(value)) {
|
|
54
|
+
if (value.length === 0) {
|
|
55
|
+
formData.append(`${formKey}[]`, "");
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
value.forEach((item, index) => {
|
|
59
|
+
const arrayKey = `${formKey}[${index}]`;
|
|
60
|
+
if (typeof item === "object" &&
|
|
61
|
+
item !== null &&
|
|
62
|
+
!(item instanceof File) &&
|
|
63
|
+
!(item instanceof Blob)) {
|
|
64
|
+
objectToFormData({ [index]: item }, formData, formKey);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
formData.append(arrayKey, item);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (typeof value === "object" && value !== null) {
|
|
73
|
+
objectToFormData(value, formData, formKey);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
formData.append(formKey, value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return formData;
|
|
80
|
+
}
|
|
14
81
|
//# sourceMappingURL=form.helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.helpers.js","sourceRoot":"","sources":["../../../src/utils/helpers/form.helpers.ts"],"names":[],"mappings":";;AAAA,sDAaC;
|
|
1
|
+
{"version":3,"file":"form.helpers.js","sourceRoot":"","sources":["../../../src/utils/helpers/form.helpers.ts"],"names":[],"mappings":";;AAAA,sDAaC;AA6BD,4CA0CC;AApFD,SAAgB,qBAAqB,CACnC,MAA2B,EAC3B,IAAY;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE9B,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAgB,gBAAgB,CAC9B,GAAwB,EACxB,WAAqB,IAAI,QAAQ,EAAE,EACnC,YAAoB,EAAE;IAEtB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAEvD,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC;YAAE,SAAS;QAEvC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAEzD,IAAI,CAAC,KAAK,YAAY,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;YAC9D,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC5B,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,KAAK,GAAG,CAAC;oBAExC,IACE,OAAO,IAAI,KAAK,QAAQ;wBACxB,IAAI,KAAK,IAAI;wBACb,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC;wBACvB,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC,EACvB,CAAC;wBACD,gBAAgB,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;oBACzD,CAAC;yBAAM,CAAC;wBACN,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAClC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACvD,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomos-ui/form",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "The Shadcn library for building robust React forms",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/exports/index.js",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"import": "./dist/hooks/index.js"
|
|
16
16
|
},
|
|
17
17
|
"./utils": {
|
|
18
|
-
"types": "./dist/utils/index.d.ts",
|
|
19
|
-
"import": "./dist/utils/index.js"
|
|
18
|
+
"types": "./dist/exports/utils/index.d.ts",
|
|
19
|
+
"import": "./dist/exports/utils/index.js"
|
|
20
20
|
},
|
|
21
21
|
"./types": {
|
|
22
22
|
"types": "./dist/types/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"*": {
|
|
28
28
|
"components": ["./dist/components/index.d.ts"],
|
|
29
29
|
"hooks": ["./dist/hooks/index.d.ts"],
|
|
30
|
-
"utils": ["./dist/utils/index.d.ts"],
|
|
30
|
+
"utils": ["./dist/exports/utils/index.d.ts"],
|
|
31
31
|
"types": ["./dist/types/index.d.ts"]
|
|
32
32
|
}
|
|
33
33
|
},
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"clean": "rm -rf dist",
|
|
38
38
|
"lint": "eslint src --ext .ts,.tsx",
|
|
39
39
|
"type-check": "tsc --noEmit",
|
|
40
|
-
"test": "
|
|
41
|
-
"test:watch": "
|
|
42
|
-
"test:ui": "
|
|
43
|
-
"test:coverage": "
|
|
40
|
+
"test": "jest",
|
|
41
|
+
"test:watch": "jest --watch",
|
|
42
|
+
"test:ui": "jest --ui",
|
|
43
|
+
"test:coverage": "jest --coverage",
|
|
44
44
|
"prepublishOnly": "pnpm run build"
|
|
45
45
|
},
|
|
46
46
|
"keywords": [
|
|
@@ -85,6 +85,10 @@
|
|
|
85
85
|
"tailwind-merge": "^3.3.1"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
89
|
+
"@testing-library/react": "^16.3.0",
|
|
90
|
+
"@testing-library/user-event": "^14.6.1",
|
|
91
|
+
"@types/jest": "^30.0.0",
|
|
88
92
|
"@types/node": "^24.9.1",
|
|
89
93
|
"@types/react": "^19.2.2",
|
|
90
94
|
"@types/react-dom": "^19.2.0",
|
|
@@ -93,8 +97,13 @@
|
|
|
93
97
|
"eslint": "^8.56.0",
|
|
94
98
|
"eslint-plugin-react": "^7.33.2",
|
|
95
99
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
100
|
+
"identity-obj-proxy": "^3.0.0",
|
|
101
|
+
"jest": "^30.2.0",
|
|
102
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
103
|
+
"jsdom": "^27.2.0",
|
|
96
104
|
"tailwindcss": "^4.1.16",
|
|
97
105
|
"trash-cli": "^7.0.0",
|
|
106
|
+
"ts-jest": "^29.4.6",
|
|
98
107
|
"tsx": "^4.20.3",
|
|
99
108
|
"typescript": "^5.9.3",
|
|
100
109
|
"vitest": "^4.0.3"
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export type MultipleSelectOption<T = string> = {
|
|
3
|
-
value: T;
|
|
4
|
-
label: React.ReactNode;
|
|
5
|
-
};
|
|
6
|
-
export type SelectProps<T = string> = {
|
|
7
|
-
className?: string;
|
|
8
|
-
label?: string;
|
|
9
|
-
required?: boolean;
|
|
10
|
-
showRequiredSign?: boolean;
|
|
11
|
-
options: MultipleSelectOption<T>[];
|
|
12
|
-
value?: T | T[];
|
|
13
|
-
onChange?: (value: T | T[]) => void;
|
|
14
|
-
placeholder?: string;
|
|
15
|
-
multiple?: boolean;
|
|
16
|
-
labelProps?: {
|
|
17
|
-
className?: string;
|
|
18
|
-
};
|
|
19
|
-
triggerProps?: {
|
|
20
|
-
className?: string;
|
|
21
|
-
};
|
|
22
|
-
contentProps?: {
|
|
23
|
-
className?: string;
|
|
24
|
-
};
|
|
25
|
-
valueProps?: {
|
|
26
|
-
className?: string;
|
|
27
|
-
};
|
|
28
|
-
groupProps?: {
|
|
29
|
-
className?: string;
|
|
30
|
-
};
|
|
31
|
-
itemProps?: {
|
|
32
|
-
className?: string;
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Customizable select dropdown with smart positioning and flexible styling
|
|
37
|
-
* Supports both single and multiple selection
|
|
38
|
-
*/
|
|
39
|
-
export default function MultipleSelect<T extends string = string>({ className, label, required, showRequiredSign, options, value, onChange, placeholder, multiple, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, }: SelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
40
|
-
//# sourceMappingURL=multiple-select.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multiple-select.d.ts","sourceRoot":"","sources":["../../src/components/multiple-select.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,oBAAoB,CAAC,CAAC,GAAG,MAAM,IAAI;IAC7C,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,MAAM,IAAI;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,EAChE,SAAS,EACT,KAAK,EACL,QAAgB,EAChB,gBAAwB,EACxB,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAgB,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,GACV,EAAE,WAAW,CAAC,CAAC,CAAC,2CAsJhB"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = MultipleSelect;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const select_1 = require("./shadcn-ui/select");
|
|
6
|
-
const tailwind_merge_1 = require("tailwind-merge");
|
|
7
|
-
const lucide_react_1 = require("lucide-react");
|
|
8
|
-
/**
|
|
9
|
-
* Customizable select dropdown with smart positioning and flexible styling
|
|
10
|
-
* Supports both single and multiple selection
|
|
11
|
-
*/
|
|
12
|
-
function MultipleSelect({ className, label, required = false, showRequiredSign = false, options, value, onChange, placeholder, multiple = false, labelProps, triggerProps, contentProps, valueProps, groupProps, itemProps, }) {
|
|
13
|
-
const handleValueChange = (newValue) => {
|
|
14
|
-
if (!multiple) {
|
|
15
|
-
onChange?.(newValue);
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
const currentValues = Array.isArray(value) ? value : [];
|
|
19
|
-
const isSelected = currentValues.includes(newValue);
|
|
20
|
-
if (isSelected) {
|
|
21
|
-
const filtered = currentValues.filter((v) => v !== newValue);
|
|
22
|
-
onChange?.(filtered);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
onChange?.([...currentValues, newValue]);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const handleRemoveTag = (valueToRemove) => {
|
|
29
|
-
if (!multiple || !Array.isArray(value))
|
|
30
|
-
return;
|
|
31
|
-
const filtered = value.filter((v) => v !== valueToRemove);
|
|
32
|
-
onChange?.(filtered);
|
|
33
|
-
};
|
|
34
|
-
const getSelectedLabels = () => {
|
|
35
|
-
if (!multiple || !Array.isArray(value))
|
|
36
|
-
return null;
|
|
37
|
-
return value
|
|
38
|
-
.map((v) => options.find((opt) => opt.value === v))
|
|
39
|
-
.filter(Boolean)
|
|
40
|
-
.map((opt) => ({
|
|
41
|
-
value: opt.value,
|
|
42
|
-
label: opt.label,
|
|
43
|
-
}));
|
|
44
|
-
};
|
|
45
|
-
if (multiple) {
|
|
46
|
-
const selectedLabels = getSelectedLabels();
|
|
47
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tailwind_merge_1.twMerge)("gap-1 grid", className), children: [label && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-row items-center gap-1", children: [(0, jsx_runtime_1.jsx)("label", { className: (0, tailwind_merge_1.twMerge)("font-bold", labelProps?.className), children: label }), required && showRequiredSign && ((0, jsx_runtime_1.jsx)(lucide_react_1.AsteriskIcon, { size: 12, color: "red" }))] })), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: "", onValueChange: handleValueChange, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: (0, tailwind_merge_1.twMerge)("min-h-10", triggerProps?.className), children: (0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2 flex-1", children: selectedLabels && selectedLabels.length > 0 ? (selectedLabels.map((item) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 px-2 py-1 text-sm bg-blue-100 text-blue-800 rounded-md", onClick: (e) => e.stopPropagation(), children: [item.label, (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 14, className: "cursor-pointer hover:text-blue-600", onClick: (e) => {
|
|
48
|
-
e.stopPropagation();
|
|
49
|
-
handleRemoveTag(item.value);
|
|
50
|
-
} })] }, String(item.value))))) : ((0, jsx_runtime_1.jsx)("span", { className: (0, tailwind_merge_1.twMerge)("text-muted-foreground", valueProps?.className), children: placeholder })) }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { className: contentProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { className: groupProps?.className, children: options.map((option) => {
|
|
51
|
-
const isSelected = Array.isArray(value) && value.includes(option.value);
|
|
52
|
-
return ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, className: (0, tailwind_merge_1.twMerge)(isSelected && "bg-blue-50", itemProps?.className), children: option.label }, String(option.value)));
|
|
53
|
-
}) }) })] })] }));
|
|
54
|
-
}
|
|
55
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tailwind_merge_1.twMerge)("gap-1 grid", className), children: [label && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-row items-center gap-1", children: [(0, jsx_runtime_1.jsx)("label", { className: (0, tailwind_merge_1.twMerge)("font-bold", labelProps?.className), children: label }), required && showRequiredSign && ((0, jsx_runtime_1.jsx)(lucide_react_1.AsteriskIcon, { size: 12, color: "red" }))] })), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: value, onValueChange: onChange, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: triggerProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: placeholder, className: valueProps?.className }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { className: contentProps?.className, children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { className: groupProps?.className, children: options.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, className: itemProps?.className, children: option.label }, String(option.value)))) }) })] })] }));
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=multiple-select.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multiple-select.js","sourceRoot":"","sources":["../../src/components/multiple-select.tsx"],"names":[],"mappings":";;AAmDA,iCAsKC;;AAzND,+CAO4B;AAC5B,mDAAyC;AACzC,+CAA+C;AAsC/C;;;GAGG;AACH,SAAwB,cAAc,CAA4B,EAChE,SAAS,EACT,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,gBAAgB,GAAG,KAAK,EACxB,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,GACM;IACf,MAAM,iBAAiB,GAAG,CAAC,QAAW,EAAE,EAAE;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEpD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;YAC7D,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,QAAQ,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,aAAgB,EAAE,EAAE;QAC3C,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO;QAE/C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC;QAC1D,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpD,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;aAClD,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACb,KAAK,EAAE,GAAI,CAAC,KAAK;YACjB,KAAK,EAAE,GAAI,CAAC,KAAK;SAClB,CAAC,CAAC,CAAC;IACR,CAAC,CAAC;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;QAE3C,OAAO,CACL,iCAAK,SAAS,EAAE,IAAA,wBAAO,EAAC,YAAY,EAAE,SAAS,CAAC,aAC7C,KAAK,IAAI,CACR,iCAAK,SAAS,EAAC,kCAAkC,aAC/C,kCAAO,SAAS,EAAE,IAAA,wBAAO,EAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,YAC1D,KAAK,GACA,EACP,QAAQ,IAAI,gBAAgB,IAAI,CAC/B,uBAAC,2BAAY,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC,KAAK,GAAG,CACvC,IACG,CACP,EACD,wBAAC,eAAY,IAAC,KAAK,EAAC,EAAE,EAAC,aAAa,EAAE,iBAAiB,aACrD,uBAAC,sBAAa,IACZ,SAAS,EAAE,IAAA,wBAAO,EAAC,UAAU,EAAE,YAAY,EAAE,SAAS,CAAC,YAEvD,gCAAK,SAAS,EAAC,6BAA6B,YACzC,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC7C,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC3B,iCAEE,SAAS,EAAC,gFAAgF,EAC1F,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,aAElC,IAAI,CAAC,KAAK,EACX,uBAAC,gBAAC,IACA,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,oCAAoC,EAC9C,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gDACb,CAAC,CAAC,eAAe,EAAE,CAAC;gDACpB,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4CAC9B,CAAC,GACD,KAZG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAanB,CACP,CAAC,CACH,CAAC,CAAC,CAAC,CACF,iCACE,SAAS,EAAE,IAAA,wBAAO,EAChB,uBAAuB,EACvB,UAAU,EAAE,SAAS,CACtB,YAEA,WAAW,GACP,CACR,GACG,GACQ,EAChB,uBAAC,sBAAa,IAAC,SAAS,EAAE,YAAY,EAAE,SAAS,YAC/C,uBAAC,oBAAW,IAAC,SAAS,EAAE,UAAU,EAAE,SAAS,YAC1C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;oCACtB,MAAM,UAAU,GACd,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oCACvD,OAAO,CACL,uBAAC,mBAAU,IAET,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,SAAS,EAAE,IAAA,wBAAO,EAChB,UAAU,IAAI,YAAY,EAC1B,SAAS,EAAE,SAAS,CACrB,YAEA,MAAM,CAAC,KAAK,IAPR,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAQd,CACd,CAAC;gCACJ,CAAC,CAAC,GACU,GACA,IACH,IACX,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,iCAAK,SAAS,EAAE,IAAA,wBAAO,EAAC,YAAY,EAAE,SAAS,CAAC,aAC7C,KAAK,IAAI,CACR,iCAAK,SAAS,EAAC,kCAAkC,aAC/C,kCAAO,SAAS,EAAE,IAAA,wBAAO,EAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,YAC1D,KAAK,GACA,EACP,QAAQ,IAAI,gBAAgB,IAAI,CAC/B,uBAAC,2BAAY,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC,KAAK,GAAG,CACvC,IACG,CACP,EACD,wBAAC,eAAY,IACX,KAAK,EAAE,KAAU,EACjB,aAAa,EAAE,QAA8B,aAE7C,uBAAC,sBAAa,IAAC,SAAS,EAAE,YAAY,EAAE,SAAS,YAC/C,uBAAC,oBAAW,IACV,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,UAAU,EAAE,SAAS,GAChC,GACY,EAChB,uBAAC,sBAAa,IAAC,SAAS,EAAE,YAAY,EAAE,SAAS,YAC/C,uBAAC,oBAAW,IAAC,SAAS,EAAE,UAAU,EAAE,SAAS,YAC1C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,uBAAC,mBAAU,IAET,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,SAAS,EAAE,SAAS,EAAE,SAAS,YAE9B,MAAM,CAAC,KAAK,IAJR,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAKd,CACd,CAAC,GACU,GACA,IACH,IACX,CACP,CAAC;AACJ,CAAC"}
|