inconel 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ayhan Yanbul
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,217 @@
1
+
2
+ # inconel
3
+
4
+
5
+ Accessible, type-safe and customizable React UI components.
6
+
7
+ Inconel is structured as a publishable component library. React stays a peer
8
+ dependency, components are tree-shakeable, TypeScript declarations are
9
+ included, and styles can be customized through CSS variables.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install inconel
15
+ ```
16
+
17
+ Import the library styles once in the application entry:
18
+
19
+ ```tsx
20
+ import 'inconel/styles.css'
21
+ ```
22
+
23
+ ## Components
24
+
25
+ ### Select
26
+
27
+ ```tsx
28
+ import { Select, type OptionValue } from 'inconel'
29
+
30
+ interface City {
31
+ id: number
32
+ name: string
33
+ countryCode: string
34
+ }
35
+
36
+ const [cityId, setCityId] = useState<OptionValue | null>(null)
37
+
38
+ <Select
39
+ name="cityId"
40
+ label="City"
41
+ options={cities}
42
+ optionLabel="name"
43
+ optionValue="id"
44
+ value={cityId}
45
+ isClearable
46
+ isRequired
47
+ menuPortalTarget={
48
+ typeof document !== 'undefined' ? document.body : null
49
+ }
50
+ onChange={(nextValue, selectedCity) => {
51
+ setCityId(nextValue)
52
+ }}
53
+ />
54
+ ```
55
+
56
+ `optionLabel` and `optionValue` also accept functions:
57
+
58
+ ```tsx
59
+ <Select
60
+ optionLabel={(city) => `${city.name} (${city.countryCode})`}
61
+ optionValue={(city) => city.id}
62
+ getOptionSearchText={(city) => `${city.name} ${city.countryCode}`}
63
+ // ...
64
+ />
65
+ ```
66
+
67
+ Async loading supports debounce and request cancellation:
68
+
69
+ ```tsx
70
+ <Select
71
+ options={[]}
72
+ loadOptions={async (query, signal) => {
73
+ const response = await fetch(`/api/cities?q=${query}`, { signal })
74
+ return response.json()
75
+ }}
76
+ loadOptionsDebounceMs={300}
77
+ optionLabel="name"
78
+ optionValue="id"
79
+ // ...
80
+ />
81
+ ```
82
+
83
+ Large lists are automatically virtualized at `virtualizationThreshold`.
84
+ Virtualization can also be forced with the `virtualize` prop.
85
+
86
+ ### Input
87
+
88
+ ```tsx
89
+ import { Input, type InputPayload } from 'inconel'
90
+
91
+ <Input
92
+ name="email"
93
+ label="Email"
94
+ type="email"
95
+ hint="We will never share your email."
96
+ placeholder="name@example.com"
97
+ fullWidth
98
+ />
99
+ ```
100
+
101
+ Input additionally supports locale-aware number, currency and percentage
102
+ formatting, phone masks, validation, rounding, debounce, limits, clearable and
103
+ read-only states:
104
+
105
+ ```tsx
106
+ const [amount, setAmount] = useState<number | null>(null)
107
+
108
+ <Input
109
+ label="Amount"
110
+ type="currency"
111
+ value={amount}
112
+ locale="en-US"
113
+ currency="USD"
114
+ decimalScale={2}
115
+ min={0}
116
+ max={100_000}
117
+ roundOnBlur
118
+ roundMode="round"
119
+ isClearable
120
+ clearButtonLabel="Clear amount"
121
+ validationMessages={{
122
+ required: 'Amount is required.',
123
+ invalidNumber: 'Enter a valid amount.',
124
+ minNumber: 'Amount must be at least {min}.',
125
+ maxNumber: 'Amount must be at most {max}.',
126
+ }}
127
+ onChange={({ rawValue }: InputPayload) => {
128
+ setAmount(typeof rawValue === 'number' ? rawValue : null)
129
+ }}
130
+ />
131
+
132
+ <Input
133
+ label="Phone"
134
+ type="phone"
135
+ mask="(XXX) XXX XX XX"
136
+ limit={10}
137
+ required
138
+ validationMessages={{
139
+ required: 'Phone number is required.',
140
+ invalidPhone: 'Enter a valid phone number.',
141
+ }}
142
+ />
143
+ ```
144
+
145
+ Event callbacks receive an `InputPayload` containing `rawValue`,
146
+ `formattedValue`, validation state, the last character/key and the event type.
147
+ Inconel does not contain default user-facing validation copy. Applications
148
+ provide localized messages through `validationMessages`.
149
+
150
+ ### Textarea
151
+
152
+ ```tsx
153
+ import { Textarea } from 'inconel'
154
+
155
+ <Textarea
156
+ name="message"
157
+ label="Message"
158
+ rows={5}
159
+ resize="vertical"
160
+ fullWidth
161
+ />
162
+ ```
163
+
164
+ ## Theming
165
+
166
+ Override Inconel design tokens in your application:
167
+
168
+ ```css
169
+ :root {
170
+ --inconel-color-primary: #7c3aed;
171
+ --inconel-color-primary-hover: #6d28d9;
172
+ --inconel-radius-md: 10px;
173
+ --inconel-font-family: Inter, sans-serif;
174
+ }
175
+ ```
176
+
177
+ Select additionally supports part-based `classNames` and `styles` props.
178
+
179
+ ## Select ref API
180
+
181
+ ```tsx
182
+ const selectRef = useRef<SelectHandle>(null)
183
+
184
+ selectRef.current?.focus()
185
+ selectRef.current?.blur()
186
+ selectRef.current?.clear()
187
+ ```
188
+
189
+ ## Development
190
+
191
+ ```bash
192
+ npm install
193
+ npm run dev
194
+ npm test
195
+ npm run lint
196
+ npm run build
197
+ npm run build:playground
198
+ npm run pack:check
199
+ ```
200
+
201
+ The playground is intentionally separate from the package entry. Only
202
+ `dist`, `README.md`, and `LICENSE` are included in the published package.
203
+
204
+ ## Publishing
205
+
206
+ 1. Update `version` in `package.json`.
207
+ 2. Run `npm run prepublishOnly`.
208
+ 3. Inspect the package with `npm run pack:check`.
209
+ 4. Sign in with `npm login`.
210
+ 5. Publish with `npm publish`.
211
+
212
+ The unscoped `inconel` package name must be available on npm. If it is not,
213
+ use a scoped name such as `@ayhanyanbul/inconel`.
214
+
215
+ ## License
216
+
217
+ MIT © Ayhan Yanbul
@@ -0,0 +1,13 @@
1
+ import { ReactNode } from 'react';
2
+ export interface FieldFeedbackContentProps {
3
+ hint?: ReactNode;
4
+ errorMessage?: ReactNode;
5
+ }
6
+ export interface FieldFeedbackProps extends FieldFeedbackContentProps {
7
+ hintId: string;
8
+ errorId: string;
9
+ className?: string;
10
+ }
11
+ declare function FieldFeedback({ hint, errorMessage, hintId, errorId, className, }: FieldFeedbackProps): import("react").JSX.Element | null;
12
+ export default FieldFeedback;
13
+ //# sourceMappingURL=FieldFeedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldFeedback.d.ts","sourceRoot":"","sources":["../../../src/components/FieldFeedback/FieldFeedback.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,YAAY,CAAC,EAAE,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,kBAAmB,SAAQ,yBAAyB;IACnE,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,aAAa,CAAC,EACrB,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,GACV,EAAE,kBAAkB,sCA6BpB;AAED,eAAe,aAAa,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default as FieldFeedback } from './FieldFeedback';
2
+ export type { FieldFeedbackContentProps, FieldFeedbackProps, } from './FieldFeedback';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FieldFeedback/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,YAAY,EACV,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { FocusEvent, InputHTMLAttributes, KeyboardEvent, MouseEvent, ReactNode } from 'react';
2
+ import { FieldFeedbackContentProps } from '../FieldFeedback/FieldFeedback';
3
+ export type InputType = 'text' | 'number' | 'currency' | 'percent' | 'phone' | 'email' | 'password';
4
+ export type InputRoundMode = 'ceil' | 'floor' | 'round';
5
+ export type InputValue = string | number | null;
6
+ export type InputEventType = 'change' | 'blur' | 'focus' | 'keydown' | 'mouseenter' | 'mouseleave' | 'clear';
7
+ export interface InputPayload {
8
+ rawValue: InputValue;
9
+ formattedValue: string;
10
+ error: boolean;
11
+ char: string | null;
12
+ eventType: InputEventType;
13
+ }
14
+ export interface InputValidationMessages {
15
+ required?: string;
16
+ invalidNumber?: string;
17
+ minNumber?: string;
18
+ maxNumber?: string;
19
+ minLength?: string;
20
+ maxLength?: string;
21
+ invalidPhone?: string;
22
+ invalidEmail?: string;
23
+ }
24
+ type NativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onMouseEnter' | 'onMouseLeave' | 'min' | 'max' | 'size' | 'readOnly'>;
25
+ export interface InputProps extends NativeInputProps, FieldFeedbackContentProps {
26
+ label?: string;
27
+ startAdornment?: ReactNode;
28
+ endAdornment?: ReactNode;
29
+ fullWidth?: boolean;
30
+ inputClassName?: string;
31
+ labelClassName?: string;
32
+ value?: InputValue;
33
+ defaultValue?: InputValue;
34
+ onChange?: (payload: InputPayload) => void;
35
+ onBlur?: (payload: InputPayload, event: FocusEvent<HTMLInputElement>) => void;
36
+ onFocus?: (payload: InputPayload, event: FocusEvent<HTMLInputElement>) => void;
37
+ onKeyDown?: (payload: InputPayload, event: KeyboardEvent<HTMLInputElement>) => void;
38
+ onMouseEnter?: (payload: InputPayload, event: MouseEvent<HTMLInputElement>) => void;
39
+ onMouseLeave?: (payload: InputPayload, event: MouseEvent<HTMLInputElement>) => void;
40
+ type?: InputType;
41
+ locale?: string;
42
+ currency?: string;
43
+ decimalScale?: number;
44
+ roundMode?: InputRoundMode;
45
+ roundOnBlur?: boolean;
46
+ min?: number;
47
+ max?: number;
48
+ allowNegative?: boolean;
49
+ debounceMs?: number;
50
+ validateOnSubmit?: boolean;
51
+ validationMessages?: InputValidationMessages;
52
+ mask?: string;
53
+ limit?: number;
54
+ isClearable?: boolean;
55
+ readOnly?: boolean;
56
+ clearButtonLabel?: string;
57
+ readOnlyEmptyValue?: ReactNode;
58
+ }
59
+ declare const Input: import('react').ForwardRefExoticComponent<InputProps & import('react').RefAttributes<HTMLInputElement>>;
60
+ export default Input;
61
+ //# sourceMappingURL=Input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/Input/Input.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const FORMATTED_INPUT_TYPES: readonly ["number", "currency", "percent"];
2
+ export declare const LENGTH_VALIDATED_INPUT_TYPES: readonly ["text", "email", "password"];
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/components/Input/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,4CAIxB,CAAA;AAEV,eAAO,MAAM,4BAA4B,wCAI/B,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default as Input } from './Input';
2
+ export type { InputEventType, InputPayload, InputProps, InputRoundMode, InputType, InputValidationMessages, InputValue, } from './Input';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAA;AAC1C,YAAY,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,UAAU,GACX,MAAM,SAAS,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { InputRoundMode, InputType, InputValidationMessages, InputValue } from './Input';
2
+ export interface InputValidationOptions {
3
+ required: boolean;
4
+ type: InputType;
5
+ min?: number;
6
+ max?: number;
7
+ mask?: string;
8
+ messages: InputValidationMessages;
9
+ }
10
+ export declare function isFormattedInputType(type: InputType): boolean;
11
+ export declare function isLengthValidatedInputType(type: InputType): boolean;
12
+ export declare function getInputSeparators(locale: string): {
13
+ group: string;
14
+ decimal: string;
15
+ };
16
+ export declare function parseInputNumber(value: string, locale: string): number | null;
17
+ export declare function roundInputNumber(value: number, scale: number, mode: InputRoundMode): number;
18
+ export declare function applyInputMask(value: InputValue, mask: string): string;
19
+ export declare function formatInputValue(value: InputValue, type: InputType, locale: string, decimalScale: number, currency: string, mask?: string): string;
20
+ export declare function validateInputValue(candidate: InputValue, { required, type, min, max, mask, messages, }: InputValidationOptions): string | null;
21
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/Input/utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,UAAU,EACX,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,uBAAuB,CAAA;CAClC;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,WAEnD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,WAEzD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM;;;EAMhD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM7E;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,cAAc,UAQrB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,UAe7D;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,UAkBd;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,UAAU,EACrB,EACE,QAAQ,EACR,IAAI,EACJ,GAAG,EACH,GAAG,EACH,IAAI,EACJ,QAAQ,GACT,EAAE,sBAAsB,iBA8C1B"}
@@ -0,0 +1,53 @@
1
+ import { CSSProperties, ForwardedRef, ReactNode } from 'react';
2
+ import { FieldFeedbackContentProps } from '../FieldFeedback/FieldFeedback';
3
+ export type OptionValue = string | number;
4
+ export interface SelectHandle {
5
+ focus: () => void;
6
+ blur: () => void;
7
+ clear: () => void;
8
+ }
9
+ type SelectPart = 'root' | 'label' | 'control' | 'input' | 'clearButton' | 'toggleButton' | 'menu' | 'option' | 'message';
10
+ export type SelectClassNames = Partial<Record<SelectPart, string>>;
11
+ export type SelectStyles = Partial<Record<SelectPart, CSSProperties>>;
12
+ export interface SelectProps<T extends object> extends FieldFeedbackContentProps {
13
+ id?: string;
14
+ name?: string;
15
+ label: string;
16
+ options: T[];
17
+ value: OptionValue | null;
18
+ onChange: (value: OptionValue | null, option: T | null) => void;
19
+ optionLabel: keyof T | ((option: T) => ReactNode);
20
+ optionValue: keyof T | ((option: T) => OptionValue);
21
+ getOptionSearchText?: (option: T) => string;
22
+ isOptionDisabled?: (option: T) => boolean;
23
+ placeholder?: string;
24
+ isClearable?: boolean;
25
+ isDisabled?: boolean;
26
+ isReadOnly?: boolean;
27
+ isRequired?: boolean;
28
+ isLoading?: boolean;
29
+ loadOptions?: (inputValue: string, signal: AbortSignal) => Promise<T[]>;
30
+ loadOptionsDebounceMs?: number;
31
+ asyncErrorMessage?: ReactNode;
32
+ loadingMessage?: ReactNode;
33
+ noOptionsMessage?: ReactNode;
34
+ clearButtonLabel?: string;
35
+ openMenuButtonLabel?: string;
36
+ closeMenuButtonLabel?: string;
37
+ searchLocale?: string;
38
+ menuPortalTarget?: HTMLElement | null;
39
+ virtualize?: boolean;
40
+ virtualizationThreshold?: number;
41
+ optionHeight?: number;
42
+ className?: string;
43
+ classNames?: SelectClassNames;
44
+ styles?: SelectStyles;
45
+ onInputChange?: (value: string) => void;
46
+ onMenuOpen?: () => void;
47
+ onMenuClose?: () => void;
48
+ }
49
+ declare const Select: <T extends object>(props: SelectProps<T> & {
50
+ ref?: ForwardedRef<SelectHandle>;
51
+ }) => ReactNode;
52
+ export default Select;
53
+ //# sourceMappingURL=Select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { default as Select } from './Select';
2
+ export type { OptionValue, SelectClassNames, SelectHandle, SelectProps, SelectStyles, } from './Select';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Select/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAC5C,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,UAAU,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { TextareaHTMLAttributes } from 'react';
2
+ import { FieldFeedbackContentProps } from '../FieldFeedback/FieldFeedback';
3
+ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement>, FieldFeedbackContentProps {
4
+ label?: string;
5
+ fullWidth?: boolean;
6
+ resize?: 'none' | 'vertical' | 'horizontal' | 'both';
7
+ }
8
+ declare const Textarea: import('react').ForwardRefExoticComponent<TextareaProps & import('react').RefAttributes<HTMLTextAreaElement>>;
9
+ export default Textarea;
10
+ //# sourceMappingURL=Textarea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../../../src/components/Textarea/Textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAA;AAGd,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAE/E,MAAM,WAAW,aACf,SAAQ,sBAAsB,CAAC,mBAAmB,CAAC,EACjD,yBAAyB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAA;CACrD;AAED,QAAA,MAAM,QAAQ,+GAqEb,CAAA;AAED,eAAe,QAAQ,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default as Textarea } from './Textarea';
2
+ export type { TextareaProps } from './Textarea';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Textarea/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from './FieldFeedback';
2
+ export * from './Input';
3
+ export * from './Select';
4
+ export * from './Textarea';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA"}
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),o=require("react"),te=require("@floating-ui/react"),Ye=require("@tanstack/react-virtual"),Ke=require("react-dom");function Ne({hint:t,errorMessage:u,hintId:s,errorId:l,className:c}){return u?r.jsx("p",{id:l,className:["inconel-field-feedback","is-error",c??""].join(" "),role:"alert",children:u}):t?r.jsx("p",{id:s,className:["inconel-field-feedback","is-hint",c??""].join(" "),children:t}):null}const Oe=["number","currency","percent"],Xe=["text","email","password"];function re(t){return Oe.some(u=>u===t)}function Ce(t){return Xe.some(u=>u===t)}function Me(t){const u=new Intl.NumberFormat(t).formatToParts(1000.1);return{group:u.find(s=>s.type==="group")?.value??".",decimal:u.find(s=>s.type==="decimal")?.value??","}}function Ge(t,u){if(!t||t==="-")return null;const{group:s,decimal:l}=Me(u),c=t.split(s).join("").replace(l,"."),f=Number(c);return Number.isNaN(f)?null:f}function We(t,u,s){const l=10**u;return s==="ceil"?Math.ceil(t*l)/l:s==="round"?Math.round(t*l)/l:t>=0?Math.floor(t*l)/l:Math.ceil(t*l)/l}function De(t,u){const s=String(t??"").replace(/\D/g,"");let l=0,c="";for(const f of u)if(f==="X"){if(l>=s.length)break;c+=s[l++]}else l<s.length&&(c+=f);return c}function ze(t,u,s,l,c,f){return t==null||t===""?"":u==="phone"&&f?De(t,f):!re(u)||typeof t!="number"||Number.isNaN(t)?String(t):new Intl.NumberFormat(s,{style:u==="currency"?"currency":u==="percent"?"percent":"decimal",currency:u==="currency"?c:void 0,minimumFractionDigits:l,maximumFractionDigits:l}).format(t)}function Je(t,{required:u,type:s,min:l,max:c,mask:f,messages:m}){if(u&&(t==null||t===""))return m.required??null;if(t==null||t==="")return null;if(s==="email"&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(t)))return m.invalidEmail??null;if(s==="phone"){const y=String(t).replace(/\D/g,""),k=f?(f.match(/X/g)??[]).length:y.startsWith("0")?11:10;if(y.length!==k)return m.invalidPhone??null}if(Ce(s)){if(typeof l=="number"&&String(t).length<l)return m.minLength?.replace("{min}",String(l))??null;if(typeof c=="number"&&String(t).length>c)return m.maxLength?.replace("{max}",String(c))??null}if(re(s)){if(typeof t!="number"||Number.isNaN(t))return m.invalidNumber??null;if(typeof l=="number"&&t<l)return m.minNumber?.replace("{min}",String(l))??null;if(typeof c=="number"&&t>c)return m.maxNumber?.replace("{max}",String(c))??null}return null}const Qe=o.forwardRef(function({id:u,label:s,hint:l,errorMessage:c,startAdornment:f,endAdornment:m,fullWidth:y=!1,inputClassName:k,labelClassName:B,className:K,required:z,disabled:g,value:T,defaultValue:C="",onChange:V,onBlur:v,onFocus:R,onKeyDown:O,onMouseEnter:X,onMouseLeave:Se,type:h="text",locale:H="tr-TR",currency:G="TRY",decimalScale:W=0,roundMode:ve="floor",roundOnBlur:ie=!1,min:M,max:le,allowNegative:ce=!1,debounceMs:ue=0,validateOnSubmit:ae=!1,validationMessages:j,mask:a,limit:$,isClearable:Ee=!1,readOnly:fe=!1,clearButtonLabel:de,readOnlyEmptyValue:ke=null,autoComplete:F="off","aria-describedby":pe,...he},me){const ge=o.useId(),U=u??`inconel-input-${ge.replace(/:/g,"")}`,q=`${U}-hint`,J=`${U}-error`,d=T!==void 0,[be,D]=o.useState(C),b=d?T:be,[x,I]=o.useState(""),[Te,xe]=o.useState(!1),[Ve,Q]=o.useState(null),L=o.useRef(null),je=j??{},w=c??Ve,P=n=>Je(n,{required:!!z,type:h,min:M,max:le,mask:a,messages:je}),Y=o.useMemo(()=>ze(b,h,H,W,G,a),[b,G,W,H,a,h]),E=(n,p,N=null)=>({rawValue:n,formattedValue:ze(n,h,H,W,G,a),error:!!P(n),char:N,eventType:p}),A=(n,p=!1)=>{d||D(n.rawValue),L.current&&clearTimeout(L.current),V&&(p||ue<=0?V(n):L.current=setTimeout(()=>V(n),ue))};o.useEffect(()=>()=>{L.current&&clearTimeout(L.current)},[]),o.useEffect(()=>{ae&&Q(P(b))},[ae]);const Z=n=>{if(h==="phone"&&a)return n.replace(/\D/g,"");if(re(h)){const p=Ge(n,H);return p===null?n===""?null:n:ce?p:Math.abs(p)}return n},oe=n=>{const p=n.replace(/\D/g,"");if($&&(re(h)||h==="phone")&&p.length>$||$&&Ce(h)&&n.length>$)return;const N=Z(n);typeof N=="number"&&(typeof M=="number"&&N<M||typeof le=="number"&&N>le)||(I(h==="phone"&&a?De(N,a):n),A(E(N,"change",n.slice(-1)||null)))},$e=[pe,l&&!w?q:void 0,w?J:void 0].filter(Boolean).join(" ")||void 0;return fe?r.jsxs("div",{className:["inconel-field",y?"inconel-field--full-width":"",K??""].join(" "),children:[s&&r.jsx("span",{className:["inconel-field__label",B??""].join(" "),children:s}),r.jsx("div",{className:"inconel-input-readonly","aria-label":s,children:Y||ke})]}):r.jsxs("div",{className:["inconel-field",y?"inconel-field--full-width":"",K??""].join(" "),children:[s&&r.jsxs("label",{className:["inconel-field__label",B??""].join(" "),htmlFor:U,children:[s,z&&r.jsx("span",{className:"inconel-field__required","aria-hidden":"true",children:" *"})]}),r.jsxs("div",{className:["inconel-input-control",w?"is-invalid":"",g?"is-disabled":""].join(" "),children:[f&&r.jsx("span",{className:"inconel-input-adornment","aria-hidden":"true",children:f}),r.jsx("input",{...he,ref:me,id:U,type:h==="password"||h==="email"?h:"text",inputMode:re(h)?"decimal":h==="phone"?"tel":void 0,value:Te?x:Y,required:z,disabled:g,autoComplete:F,"aria-invalid":!!w,"aria-describedby":$e,className:["inconel-input",k??""].join(" "),onChange:n=>oe(n.target.value),onFocus:n=>{if(g)return;xe(!0);const p=h==="phone"&&a?De(b,a):re(h)?String(b??"").replace(".",Me(H).decimal):String(b??"");I(p),R?.(E(b,"focus"),n)},onBlur:n=>{xe(!1),L.current&&clearTimeout(L.current);let p=Z(x);typeof p=="number"&&(p=We(p,W,ie?ve:"floor")),Q(P(p));const N=E(p,"blur");A(N,!0),v?.(N,n)},onKeyDown:n=>{!ce&&(n.key==="-"||n.key==="Subtract")&&n.preventDefault(),O?.(E(b,"keydown",n.key),n)},onMouseEnter:n=>X?.(E(b,"mouseenter"),n),onMouseLeave:n=>Se?.(E(b,"mouseleave"),n)}),Ee&&!g&&Y&&de&&r.jsx("button",{type:"button",className:"inconel-input-clear","aria-label":de,onClick:()=>{I(""),Q(P(null)),A(E(null,"clear"),!0)},children:"×"}),m&&r.jsx("span",{className:"inconel-input-adornment","aria-hidden":"true",children:m})]}),r.jsx(Ne,{hint:l,errorMessage:w,hintId:q,errorId:J})]})});function _(...t){return t.filter(Boolean).join(" ")}function Ze({id:t,name:u,label:s,options:l,value:c,onChange:f,optionLabel:m,optionValue:y,getOptionSearchText:k,isOptionDisabled:B=()=>!1,placeholder:K,isClearable:z=!1,isDisabled:g=!1,isReadOnly:T=!1,isRequired:C=!1,isLoading:V=!1,loadOptions:v,loadOptionsDebounceMs:R=250,hint:O,errorMessage:X,asyncErrorMessage:Se,loadingMessage:h,noOptionsMessage:H,clearButtonLabel:G,openMenuButtonLabel:W,closeMenuButtonLabel:ve,searchLocale:ie,menuPortalTarget:M,virtualize:le=!1,virtualizationThreshold:ce=100,optionHeight:ue=44,className:ae,classNames:j={},styles:a={},onInputChange:$,onMenuOpen:Ee,onMenuClose:fe},de){const ke=o.useId(),F=t??`inconel-select-${ke.replace(/:/g,"")}`,pe=`${F}-label`,he=`${F}-listbox`,me=`${F}-message`,ge=`${F}-hint`,U=o.useRef(null),q=o.useRef(null),J=o.useRef(null),[d,be]=o.useState(!1),[D,b]=o.useState(""),[x,I]=o.useState(0),[Te,xe]=o.useState(null),[Ve,Q]=o.useState(!1),[L,je]=o.useState(!1);o.useEffect(()=>{if(!v)return;const e=new AbortController,i=window.setTimeout(async()=>{Q(!0),je(!1);try{const S=await v(D,e.signal);e.signal.aborted||xe(S)}catch{e.signal.aborted||je(!0)}finally{e.signal.aborted||Q(!1)}},R);return()=>{window.clearTimeout(i),e.abort()}},[D,v,R]);const w=v?Te??l:l,P=V||Ve,Y=o.useCallback(e=>typeof m=="function"?m(e):String(e[m]),[m]),E=o.useCallback(e=>{if(k)return k(e);const i=Y(e);return typeof i=="string"||typeof i=="number"?String(i):""},[Y,k]),A=o.useCallback(e=>{const i=typeof y=="function"?y(e):e[y];if(typeof i!="string"&&typeof i!="number")throw new TypeError("optionValue must resolve to a string or number.");return i},[y]),Z=o.useMemo(()=>{const e=new Set;return w.map(A).filter(i=>e.has(i)?!0:(e.add(i),!1))},[w,A]);o.useEffect(()=>{Z.length&&console.warn(`Duplicate optionValue found in Select "${s}":`,Z)},[Z,s]);const oe=[...l,...w].find(e=>A(e)===c),$e=oe?E(oe):"",n=o.useMemo(()=>{const e=D.trim().toLocaleLowerCase(ie);return!e||v?w:w.filter(i=>E(i).toLocaleLowerCase(ie).includes(e))},[w,E,D,v,ie]),{refs:p,floatingStyles:N}=te.useFloating({open:d,placement:"bottom-start",strategy:M?"fixed":"absolute",whileElementsMounted:te.autoUpdate,middleware:[te.offset(8),te.flip({padding:12}),te.shift({padding:12}),te.size({padding:12,apply({availableHeight:e,rects:i,elements:S}){Object.assign(S.floating.style,{maxHeight:`${Math.min(230,e)}px`,width:`${i.reference.width}px`})}})]}),ye=le||n.length>=ce,Ie=Ye.useVirtualizer({count:n.length,getScrollElement:()=>J.current,estimateSize:()=>ue,overscan:5,enabled:ye&&d}),ee=o.useCallback(()=>{be(!1),b(""),$?.(""),fe?.()},[$,fe]),se=()=>{g||T||(d||Ee?.(),be(!0))},we=o.useCallback(()=>{g||T||(f(null,null),b(""),I(0),$?.(""),q.current?.focus())},[g,T,f,$]);o.useImperativeHandle(de,()=>({focus:()=>q.current?.focus(),blur:()=>q.current?.blur(),clear:we}),[we]),o.useEffect(()=>{const e=i=>{const S=i.target;!U.current?.contains(S)&&!J.current?.contains(S)&&ee()};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[ee]),o.useEffect(()=>{x>=n.length&&I(0)},[x,n.length]),o.useEffect(()=>{ye&&d&&n[x]&&Ie.scrollToIndex(x,{align:"auto"})},[x,n,d,ye,Ie]);const Le=e=>{B(e)||(f(A(e),e),ee(),q.current?.focus())},qe=e=>{if(!n.length)return;let i=x;do i=(i+e+n.length)%n.length;while(B(n[i])&&i!==x);I(i)},Fe=(e=!1)=>{const i=n.map((S,ne)=>({option:S,index:ne}));return e&&i.reverse(),i.find(({option:S})=>!B(S))?.index??0},Pe=e=>{if(e.key==="Backspace"&&!D&&c!==null&&z){e.preventDefault(),we();return}if(e.key==="ArrowDown"||e.key==="ArrowUp")e.preventDefault(),d?qe(e.key==="ArrowDown"?1:-1):(se(),I(Fe(e.key==="ArrowUp")));else if(e.key==="Home"&&d)e.preventDefault(),I(Fe());else if(e.key==="End"&&d)e.preventDefault(),I(Fe(!0));else if(e.key==="Enter"&&d){e.preventDefault();const i=n[x];i&&Le(i)}else e.key==="Escape"&&d?(e.preventDefault(),ee()):e.key==="Tab"&&ee()},Ae=(e,i,S)=>{const ne=A(e),_e=B(e);return r.jsxs("div",{id:`${F}-option-${i}`,role:"option","aria-selected":ne===c,"aria-disabled":_e,"aria-posinset":i+1,"aria-setsize":n.length,className:_("inconel-select-option",i===x&&"is-active",ne===c&&"is-selected",_e&&"is-disabled",j.option),style:{...S,...a.option},onMouseEnter:()=>I(i),onMouseDown:Ue=>Ue.preventDefault(),onClick:()=>Le(e),children:[r.jsx("span",{children:Y(e)}),ne===c&&r.jsx("span",{"aria-hidden":"true",children:"✓"})]},ne)},Re=P?r.jsxs("div",{role:"status",className:_("inconel-select-message",j.message),style:a.message,children:[r.jsx("span",{className:"inconel-select-spinner","aria-hidden":"true"}),h]}):L?r.jsx("div",{role:"alert",className:_("inconel-select-message inconel-select-message-error",j.message),style:a.message,children:Se}):n.length===0?r.jsx("div",{className:_("inconel-select-message",j.message),style:a.message,children:H}):ye?r.jsx("div",{role:"presentation",className:"inconel-select-virtual-content",style:{height:Ie.getTotalSize()},children:Ie.getVirtualItems().map(e=>Ae(n[e.index],e.index,{position:"absolute",top:0,left:0,width:"100%",height:e.size,transform:`translateY(${e.start}px)`}))}):n.map((e,i)=>Ae(e,i)),Be=d?r.jsx("div",{ref:e=>{J.current=e,p.setFloating(e)},id:he,role:"listbox","aria-labelledby":pe,className:_("inconel-select-menu",M&&"inconel-select-menu-portal",j.menu),style:{...N,...a.menu},children:Re}):null,He=X?me:O?ge:void 0;return r.jsxs("div",{ref:U,className:_("inconel-select-field",ae,j.root),style:a.root,children:[r.jsxs("label",{id:pe,htmlFor:F,className:j.label,style:a.label,children:[s,C&&r.jsx("span",{"aria-hidden":"true",children:" *"})]}),r.jsxs("div",{ref:p.setReference,className:_("inconel-select-control",d&&"is-open",g&&"is-disabled",!!X&&"has-error",j.control),style:a.control,children:[r.jsx("input",{ref:q,id:F,role:"combobox","aria-expanded":d,"aria-controls":he,"aria-autocomplete":"list","aria-activedescendant":d&&n[x]?`${F}-option-${x}`:void 0,"aria-describedby":He,"aria-invalid":!!X,"aria-required":C,"aria-busy":P,required:C,disabled:g,readOnly:T,autoComplete:"off",placeholder:K,value:D||$e,className:j.input,style:a.input,onChange:e=>{b(e.target.value),I(0),$?.(e.target.value),se()},onClick:se,onFocus:e=>{se(),oe&&!D&&e.currentTarget.select()},onKeyDown:Pe}),P&&r.jsx("span",{className:"inconel-select-spinner","aria-hidden":"true"}),z&&c!==null&&!g&&!T&&G&&r.jsx("button",{type:"button",className:_("inconel-select-clear",j.clearButton),style:a.clearButton,"aria-label":G,onClick:we,children:"×"}),r.jsx("button",{type:"button",className:_("inconel-select-toggle",j.toggleButton),style:a.toggleButton,"aria-label":d?ve:W,"aria-expanded":d,disabled:g,tabIndex:-1,onClick:()=>d?ee():se(),children:r.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 20 20",width:"20",height:"20",fill:"none",children:r.jsx("path",{d:"m5 7.5 5 5 5-5",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),u&&r.jsx("input",{type:"hidden",name:u,value:c??"",required:C}),r.jsx(Ne,{hint:O,errorMessage:X,hintId:ge,errorId:me}),M&&Be?Ke.createPortal(Be,M):Be]})}const en=o.forwardRef(Ze),nn=o.forwardRef(function({id:u,label:s,hint:l,errorMessage:c,fullWidth:f=!1,resize:m="vertical",className:y,required:k,disabled:B,"aria-describedby":K,style:z,...g},T){const C=o.useId(),V=u??`inconel-textarea-${C.replace(/:/g,"")}`,v=`${V}-hint`,R=`${V}-error`,O=[K,l&&!c?v:void 0,c?R:void 0].filter(Boolean).join(" ")||void 0;return r.jsxs("div",{className:["inconel-field",f?"inconel-field--full-width":"",y??""].join(" "),children:[s&&r.jsxs("label",{className:"inconel-field__label",htmlFor:V,children:[s,k&&r.jsx("span",{"aria-hidden":"true",children:" *"})]}),r.jsx("textarea",{...g,ref:T,id:V,required:k,disabled:B,"aria-invalid":!!c,"aria-describedby":O,className:["inconel-textarea",c?"is-invalid":""].join(" "),style:{...z,resize:m}}),r.jsx(Ne,{hint:l,errorMessage:c,hintId:v,errorId:R})]})});exports.FieldFeedback=Ne;exports.Input=Qe;exports.Select=en;exports.Textarea=nn;
2
+ //# sourceMappingURL=index.cjs.map