@waysnx/ui-core 0.1.1

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.
@@ -0,0 +1,291 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React, { ButtonHTMLAttributes, ReactNode, InputHTMLAttributes, TextareaHTMLAttributes, SelectHTMLAttributes } from 'react';
3
+
4
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
5
+ children: ReactNode;
6
+ variant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost';
7
+ }
8
+ declare function Button({ children, variant, className, ...p }: ButtonProps): react_jsx_runtime.JSX.Element;
9
+
10
+ interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
11
+ label?: string;
12
+ error?: string;
13
+ hint?: string;
14
+ showPasswordToggle?: boolean;
15
+ }
16
+ declare function Input({ label, error, hint, id, type, showPasswordToggle, value, onChange, ...r }: InputProps): react_jsx_runtime.JSX.Element;
17
+
18
+ interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
19
+ label?: string;
20
+ error?: string;
21
+ }
22
+ declare function Textarea({ label, error, id, ...r }: TextareaProps): react_jsx_runtime.JSX.Element;
23
+
24
+ interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
25
+ label?: string;
26
+ }
27
+ declare function Checkbox({ label, ...r }: CheckboxProps): react_jsx_runtime.JSX.Element;
28
+
29
+ interface RadioProps extends InputHTMLAttributes<HTMLInputElement> {
30
+ label?: string;
31
+ }
32
+ declare function Radio({ label, ...r }: RadioProps): react_jsx_runtime.JSX.Element;
33
+
34
+ interface SwitchProps extends InputHTMLAttributes<HTMLInputElement> {
35
+ label?: string;
36
+ }
37
+ declare function Switch({ label, ...r }: SwitchProps): react_jsx_runtime.JSX.Element;
38
+
39
+ interface SelectOption {
40
+ label: string;
41
+ value: string;
42
+ }
43
+ interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'multiple' | 'onChange'> {
44
+ label?: string;
45
+ options: SelectOption[];
46
+ multiple?: boolean;
47
+ showSelectAll?: boolean;
48
+ value?: string | string[];
49
+ onChange?: (value: string | string[]) => void;
50
+ }
51
+ declare function Select({ label, options, multiple, showSelectAll, value, onChange, ...r }: SelectProps): react_jsx_runtime.JSX.Element;
52
+
53
+ interface AutocompleteOption {
54
+ label: string;
55
+ value: string;
56
+ }
57
+ interface AutocompleteProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'onSelect'> {
58
+ options: AutocompleteOption[];
59
+ value?: string;
60
+ onChange?: (value: string) => void;
61
+ onSelect?: (option: AutocompleteOption | null) => void;
62
+ placeholder?: string;
63
+ label?: string;
64
+ error?: string;
65
+ hint?: string;
66
+ disabled?: boolean;
67
+ noOptionsText?: string;
68
+ minChars?: number;
69
+ id?: string;
70
+ }
71
+ declare function Autocomplete({ options, value, onChange, onSelect, placeholder, label, error, hint, disabled, noOptionsText, minChars, id, ...rest }: AutocompleteProps): react_jsx_runtime.JSX.Element;
72
+
73
+ interface DatePickerProps {
74
+ value?: Date | null;
75
+ onChange?: (date: Date | null) => void;
76
+ label?: string;
77
+ placeholder?: string;
78
+ error?: string;
79
+ hint?: string;
80
+ disabled?: boolean;
81
+ minDate?: Date;
82
+ maxDate?: Date;
83
+ dateFormat?: string;
84
+ showTimeSelect?: boolean;
85
+ id?: string;
86
+ className?: string;
87
+ }
88
+ declare function DatePicker({ value, onChange, label, placeholder, error, hint, disabled, minDate, maxDate, dateFormat, showTimeSelect, id, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
89
+
90
+ interface DateRangePickerProps {
91
+ startDate?: Date | null;
92
+ endDate?: Date | null;
93
+ onChange?: (dates: [Date | null, Date | null]) => void;
94
+ label?: string;
95
+ placeholder?: string;
96
+ error?: string;
97
+ hint?: string;
98
+ disabled?: boolean;
99
+ minDate?: Date;
100
+ maxDate?: Date;
101
+ dateFormat?: string;
102
+ id?: string;
103
+ className?: string;
104
+ }
105
+ declare function DateRangePicker({ startDate, endDate, onChange, label, placeholder, error, hint, disabled, minDate, maxDate, dateFormat, id, className, }: DateRangePickerProps): react_jsx_runtime.JSX.Element;
106
+
107
+ interface DateTimePickerProps {
108
+ value?: Date | null;
109
+ onChange?: (date: Date | null) => void;
110
+ label?: string;
111
+ placeholder?: string;
112
+ error?: string;
113
+ hint?: string;
114
+ disabled?: boolean;
115
+ minDate?: Date;
116
+ maxDate?: Date;
117
+ dateFormat?: string;
118
+ timeIntervals?: number;
119
+ id?: string;
120
+ className?: string;
121
+ }
122
+ declare function DateTimePicker({ value, onChange, label, placeholder, error, hint, disabled, minDate, maxDate, dateFormat, timeIntervals, id, className, }: DateTimePickerProps): react_jsx_runtime.JSX.Element;
123
+
124
+ interface TimePickerProps {
125
+ value?: Date | null;
126
+ onChange?: (date: Date | null) => void;
127
+ label?: string;
128
+ placeholder?: string;
129
+ error?: string;
130
+ hint?: string;
131
+ disabled?: boolean;
132
+ timeIntervals?: number;
133
+ timeFormat?: string;
134
+ id?: string;
135
+ className?: string;
136
+ }
137
+ declare function TimePicker({ value, onChange, label, placeholder, error, hint, disabled, timeIntervals, timeFormat, id, className, }: TimePickerProps): react_jsx_runtime.JSX.Element;
138
+
139
+ interface FileUploadProps {
140
+ label?: string;
141
+ accept?: string;
142
+ multiple?: boolean;
143
+ maxSize?: number;
144
+ onChange?: (files: File[]) => void;
145
+ onError?: (error: string) => void;
146
+ hint?: string;
147
+ error?: string;
148
+ disabled?: boolean;
149
+ id?: string;
150
+ className?: string;
151
+ }
152
+ declare function FileUpload({ label, accept, multiple, maxSize, onChange, onError, hint, error, disabled, id, className, }: FileUploadProps): react_jsx_runtime.JSX.Element;
153
+
154
+ interface HtmlEditorProps {
155
+ label?: string;
156
+ value?: string;
157
+ onChange?: (value: string) => void;
158
+ placeholder?: string;
159
+ hint?: string;
160
+ error?: string;
161
+ disabled?: boolean;
162
+ minHeight?: number;
163
+ toolbar?: ('bold' | 'italic' | 'underline' | 'link' | 'ul' | 'ol' | 'h1' | 'h2')[];
164
+ id?: string;
165
+ className?: string;
166
+ }
167
+ declare function HtmlEditor({ label, value, onChange, placeholder, hint, error, disabled, minHeight, toolbar, id, className, }: HtmlEditorProps): react_jsx_runtime.JSX.Element;
168
+
169
+ interface HtmlContentProps {
170
+ content: string;
171
+ className?: string;
172
+ }
173
+ declare function HtmlContent({ content, className }: HtmlContentProps): react_jsx_runtime.JSX.Element;
174
+
175
+ interface HiddenProps {
176
+ name: string;
177
+ value?: string;
178
+ }
179
+ declare function Hidden({ name, value }: HiddenProps): react_jsx_runtime.JSX.Element;
180
+
181
+ interface LinkProps {
182
+ label: string;
183
+ href?: string;
184
+ onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
185
+ prependText?: string;
186
+ appendText?: string;
187
+ target?: '_blank' | '_self' | '_parent' | '_top';
188
+ className?: string;
189
+ disabled?: boolean;
190
+ }
191
+ declare function Link({ label, href, onClick, prependText, appendText, target, className, disabled, }: LinkProps): react_jsx_runtime.JSX.Element;
192
+
193
+ interface TreeNode {
194
+ value: string | number;
195
+ name: string;
196
+ checked?: boolean;
197
+ options?: TreeNode[];
198
+ }
199
+ interface TreeProps {
200
+ data: TreeNode[];
201
+ onChange?: (data: TreeNode[]) => void;
202
+ label?: string;
203
+ className?: string;
204
+ }
205
+ declare function Tree({ data, onChange, label, className }: TreeProps): react_jsx_runtime.JSX.Element;
206
+
207
+ interface SliderProps {
208
+ label?: string;
209
+ value?: number;
210
+ onChange?: (value: number) => void;
211
+ min?: number;
212
+ max?: number;
213
+ step?: number;
214
+ hint?: string;
215
+ className?: string;
216
+ showValue?: boolean;
217
+ }
218
+ declare function Slider({ label, value, onChange, min, max, step, hint, className, showValue, }: SliderProps): react_jsx_runtime.JSX.Element;
219
+
220
+ interface DividerProps {
221
+ vertical?: boolean;
222
+ }
223
+ declare function Divider({ vertical }: DividerProps): react_jsx_runtime.JSX.Element;
224
+
225
+ interface SpinnerProps {
226
+ size?: number;
227
+ }
228
+ declare function Spinner({ size }: SpinnerProps): react_jsx_runtime.JSX.Element;
229
+
230
+ interface AlertProps {
231
+ type?: 'info' | 'success' | 'warning' | 'error';
232
+ children: React.ReactNode;
233
+ }
234
+ declare function Alert({ type, children }: AlertProps): react_jsx_runtime.JSX.Element;
235
+
236
+ interface StackProps {
237
+ direction?: 'vertical' | 'horizontal';
238
+ gap?: number;
239
+ children: React.ReactNode;
240
+ }
241
+ declare function Stack({ direction, gap, children }: StackProps): react_jsx_runtime.JSX.Element;
242
+
243
+ declare function useDebounce<T>(v: T): T;
244
+
245
+ interface JSONSchemaProperty {
246
+ type: string;
247
+ title?: string;
248
+ description?: string;
249
+ enum?: string[];
250
+ format?: string;
251
+ minLength?: number;
252
+ maxLength?: number;
253
+ minimum?: number;
254
+ maximum?: number;
255
+ pattern?: string;
256
+ required?: boolean;
257
+ default?: any;
258
+ items?: JSONSchemaProperty;
259
+ properties?: Record<string, JSONSchemaProperty>;
260
+ contentMediaType?: string;
261
+ 'x-component'?: 'tree' | 'link' | 'htmlEditor' | 'dateRange' | 'hidden' | 'button' | 'multiselect' | 'checkbox' | 'checkbox-group';
262
+ 'x-data'?: any;
263
+ 'x-button-variant'?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost';
264
+ 'x-button-type'?: 'submit' | 'button' | 'reset';
265
+ 'x-button-action'?: string;
266
+ 'x-placeholder'?: string;
267
+ }
268
+ interface JSONSchema {
269
+ type: 'object';
270
+ properties: Record<string, JSONSchemaProperty>;
271
+ required?: string[];
272
+ }
273
+ interface FormFieldConfig {
274
+ name: string;
275
+ label: string;
276
+ component: React.ReactElement;
277
+ required: boolean;
278
+ useFormFieldLabel: boolean;
279
+ validation?: {
280
+ minLength?: number;
281
+ maxLength?: number;
282
+ min?: number;
283
+ max?: number;
284
+ pattern?: string;
285
+ };
286
+ }
287
+ declare function schemaToFormFields(schema: JSONSchema, formData?: Record<string, any>, onChange?: (name: string, value: any) => void): FormFieldConfig[];
288
+
289
+ declare function warn(c: boolean, m: string): void;
290
+
291
+ export { Alert, type AlertProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Button, type ButtonProps, Checkbox, type CheckboxProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, DateTimePicker, type DateTimePickerProps, Divider, type DividerProps, FileUpload, type FileUploadProps, Hidden, type HiddenProps, HtmlContent, type HtmlContentProps, HtmlEditor, type HtmlEditorProps, Input, type InputProps, type JSONSchema, type JSONSchemaProperty, Link, type LinkProps, Radio, type RadioProps, Select, type SelectOption, type SelectProps, Slider, type SliderProps, Spinner, type SpinnerProps, Stack, type StackProps, Switch, type SwitchProps, Textarea, type TextareaProps, TimePicker, type TimePickerProps, Tree, type TreeNode, type TreeProps, schemaToFormFields, useDebounce, warn };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import {jsx,jsxs}from'react/jsx-runtime';import {useState,useRef,useEffect}from'react';import qe from'react-datepicker';import'react-datepicker/dist/react-datepicker.css';import ye from'dompurify';function pe({children:i,variant:t="primary",className:n,...m}){let e=`wx-button ${`wx-button--${t}`} ${n||""}`.trim();return jsx("button",{className:e,...m,children:i})}function T(i,t){!i&&process.env.NODE_ENV!=="production"&&console.warn("[WaysNX UI]",t);}function O({label:i,error:t,hint:n,id:m,type:l,showPasswordToggle:e,value:r,onChange:p,...a}){T(!!(i||a["aria-label"]),"Input needs label");let c=m||`wx-input-${Math.random().toString(36).slice(2)}`,[u,v]=useState(false),d=e!==false&&l==="password";return jsxs("div",{className:"wx-input-wrapper",children:[i&&jsx("label",{htmlFor:c,children:i}),jsxs("div",{className:"wx-input-container",children:[jsx("input",{id:c,className:`wx-input ${t?"wx-input-error":""}`,type:d&&u?"text":l,value:r,onChange:p,...a}),d&&jsx("button",{type:"button",className:"wx-input-icon",onClick:()=>v(!u),tabIndex:-1,children:u?"\u{1F441}\uFE0F":"\u{1F441}\uFE0F\u200D\u{1F5E8}\uFE0F"})]}),n&&!t&&jsx("div",{className:"wx-input-hint",children:n}),t&&jsx("div",{className:"wx-input-error-text",children:t})]})}function de({label:i,error:t,id:n,...m}){T(!!(i||m["aria-label"]),"Textarea needs label");let l=n||`wx-textarea-${Math.random().toString(36).slice(2)}`;return jsxs("div",{className:"wx-textarea-wrapper",children:[i&&jsx("label",{htmlFor:l,children:i}),jsx("textarea",{id:l,className:`wx-textarea ${t?"wx-textarea-error":""}`,...m}),t&&jsx("div",{className:"wx-textarea-error-text",children:t})]})}function Y({label:i,...t}){return jsxs("label",{className:"wx-checkbox-wrapper",children:[jsx("input",{type:"checkbox",className:"wx-checkbox",...t}),i]})}function xe({label:i,...t}){return jsxs("label",{className:"wx-radio-wrapper",children:[jsx("input",{type:"radio",className:"wx-radio",...t}),i]})}function me({label:i,...t}){return jsxs("label",{className:"wx-switch-wrapper",children:[jsx("input",{type:"checkbox",className:"wx-switch",...t}),jsx("span",{className:"wx-switch-slider"}),i&&jsx("span",{children:i})]})}function Q({label:i,options:t,multiple:n,showSelectAll:m,value:l,onChange:e,...r}){let[p,a]=useState(Array.isArray(l)?l:l?[l]:[]),[c,u]=useState(false),v=useRef(null);useEffect(()=>{let x=k=>{v.current&&!v.current.contains(k.target)&&u(false);};return document.addEventListener("mousedown",x),()=>document.removeEventListener("mousedown",x)},[]);let s=x=>{e?.(x.target.value);},d=x=>{let k=p.includes(x)?p.filter(L=>L!==x):[...p,x];a(k),e?.(k);},f=()=>{let x=t.map(L=>L.value),k=p.length===t.length?[]:x;a(k),e?.(k);},o=()=>p.length===0?"Select...":p.length===t.length?"All Selected":`${p.length} selected`;return n?jsxs("div",{className:"wx-select-wrapper",ref:v,children:[i&&jsx("label",{children:i}),jsxs("div",{className:"wx-select-multi",onClick:()=>u(!c),children:[jsx("span",{children:o()}),jsx("span",{className:"wx-select-arrow",children:"\u25BC"})]}),c&&jsxs("div",{className:"wx-select-dropdown",children:[m&&jsxs("label",{className:"wx-select-option wx-select-all-option",children:[jsx("input",{type:"checkbox",checked:p.length===t.length,onChange:f}),jsx("span",{children:"Select All"})]}),t.map(x=>jsxs("label",{className:"wx-select-option",children:[jsx("input",{type:"checkbox",checked:p.includes(x.value),onChange:()=>d(x.value)}),jsx("span",{children:x.label})]},x.value))]})]}):jsxs("div",{className:"wx-select-wrapper",children:[i&&jsx("label",{children:i}),jsx("select",{className:"wx-select",value:l,onChange:s,...r,children:t.map(x=>jsx("option",{value:x.value,children:x.label},x.value))})]})}function fe({options:i,value:t="",onChange:n,onSelect:m,placeholder:l,label:e,error:r,hint:p,disabled:a=false,noOptionsText:c="No options",minChars:u=0,id:v,...s}){T(!!(e||s["aria-label"]),"Autocomplete needs label");let[d,f]=useState(t),[o,x]=useState(false),[k,L]=useState(-1),y=useRef(null),N=useRef(null),I=useRef(null),A=v||`wx-autocomplete-${Math.random().toString(36).slice(2)}`,J=`${A}-listbox`,F=d.length>=u?i.filter(b=>b.label.toLowerCase().includes(d.toLowerCase())):[],$=o&&!a&&d.length>=u,g=F.length>0,z=b=>{let h=b.target.value;f(h),x(true),L(-1),n?.(h);},P=b=>{f(b.label),x(false),L(-1),n?.(b.label),m?.(b),y.current?.focus();},C=b=>{if(!$){b.key==="ArrowDown"&&x(true);return}switch(b.key){case "ArrowDown":b.preventDefault(),L(h=>h<F.length-1?h+1:h);break;case "ArrowUp":b.preventDefault(),L(h=>h>0?h-1:-1);break;case "Enter":b.preventDefault(),k>=0&&F[k]&&P(F[k]);break;case "Escape":b.preventDefault(),x(false),L(-1);break;case "Tab":x(false);break}};return useEffect(()=>{k>=0&&N.current&&N.current.children[k]?.scrollIntoView({block:"nearest"});},[k]),useEffect(()=>{let b=h=>{I.current&&!I.current.contains(h.target)&&x(false);};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[]),useEffect(()=>{f(t);},[t]),jsxs("div",{className:"wx-autocomplete-wrapper",ref:I,children:[e&&jsx("label",{htmlFor:A,className:"wx-autocomplete-label",children:e}),jsx("input",{ref:y,id:A,type:"text",className:`wx-autocomplete-input ${r?"wx-autocomplete-input-error":""}`,value:d,onChange:z,onKeyDown:C,onFocus:()=>x(true),placeholder:l,disabled:a,role:"combobox","aria-autocomplete":"list","aria-expanded":$,"aria-controls":J,"aria-activedescendant":k>=0?`${A}-option-${k}`:void 0,...s}),$&&jsx("ul",{ref:N,id:J,className:"wx-autocomplete-dropdown",role:"listbox",style:{listStyleType:"none",paddingLeft:0},children:g?F.map((b,h)=>jsx("li",{id:`${A}-option-${h}`,className:`wx-autocomplete-option ${h===k?"wx-autocomplete-option-highlighted":""}`,role:"option","aria-selected":h===k,onClick:()=>P(b),onMouseEnter:()=>L(h),children:b.label},b.value)):jsx("li",{className:"wx-autocomplete-no-options",children:c})}),p&&!r&&jsx("div",{className:"wx-autocomplete-hint",children:p}),r&&jsx("div",{className:"wx-autocomplete-error-text",children:r})]})}function we({value:i,onChange:t,label:n,placeholder:m="Select date",error:l,hint:e,disabled:r=false,minDate:p,maxDate:a,dateFormat:c="MM/dd/yyyy",showTimeSelect:u=false,id:v,className:s}){T(!!n,"DatePicker needs label");let d=v||`wx-datepicker-${Math.random().toString(36).slice(2)}`;return jsxs("div",{className:"wx-datepicker-wrapper",children:[n&&jsx("label",{htmlFor:d,className:"wx-datepicker-label",children:n}),jsxs("div",{className:"wx-datepicker-input-wrapper",children:[jsx(qe,{id:d,selected:i,onChange:t,placeholderText:m,disabled:r,minDate:p,maxDate:a,dateFormat:c,showTimeSelect:u,className:`wx-datepicker-input ${l?"wx-datepicker-input-error":""} ${s||""}`,popperPlacement:"bottom-start",wrapperClassName:"wx-datepicker-react-wrapper"}),jsxs("svg",{className:"wx-datepicker-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("rect",{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"}),jsx("line",{x1:"16",y1:"2",x2:"16",y2:"6"}),jsx("line",{x1:"8",y1:"2",x2:"8",y2:"6"}),jsx("line",{x1:"3",y1:"10",x2:"21",y2:"10"})]})]}),e&&!l&&jsx("div",{className:"wx-datepicker-hint",children:e}),l&&jsx("div",{className:"wx-datepicker-error-text",children:l})]})}function ge({startDate:i,endDate:t,onChange:n,label:m,placeholder:l="Select date range",error:e,hint:r,disabled:p=false,minDate:a,maxDate:c,dateFormat:u="MM/dd/yyyy",id:v,className:s}){T(!!m,"DateRangePicker needs label");let d=v||`wx-daterangepicker-${Math.random().toString(36).slice(2)}`;return jsxs("div",{className:"wx-daterangepicker-wrapper",children:[m&&jsx("label",{htmlFor:d,className:"wx-daterangepicker-label",children:m}),jsxs("div",{className:"wx-daterangepicker-input-wrapper",children:[jsx(qe,{id:d,selectsRange:true,startDate:i,endDate:t,onChange:n,placeholderText:l,disabled:p,minDate:a,maxDate:c,dateFormat:u,className:`wx-daterangepicker-input ${e?"wx-daterangepicker-input-error":""} ${s||""}`,popperPlacement:"bottom-start",wrapperClassName:"wx-daterangepicker-react-wrapper"}),jsxs("svg",{className:"wx-daterangepicker-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("rect",{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"}),jsx("line",{x1:"16",y1:"2",x2:"16",y2:"6"}),jsx("line",{x1:"8",y1:"2",x2:"8",y2:"6"}),jsx("line",{x1:"3",y1:"10",x2:"21",y2:"10"})]})]}),r&&!e&&jsx("div",{className:"wx-daterangepicker-hint",children:r}),e&&jsx("div",{className:"wx-daterangepicker-error-text",children:e})]})}function he({value:i,onChange:t,label:n,placeholder:m="Select date and time",error:l,hint:e,disabled:r=false,minDate:p,maxDate:a,dateFormat:c="MM/dd/yyyy h:mm aa",timeIntervals:u=15,id:v,className:s}){T(!!n,"DateTimePicker needs label");let d=v||`wx-datetimepicker-${Math.random().toString(36).slice(2)}`;return jsxs("div",{className:"wx-datetimepicker-wrapper",children:[n&&jsx("label",{htmlFor:d,className:"wx-datetimepicker-label",children:n}),jsxs("div",{className:"wx-datetimepicker-input-wrapper",children:[jsx(qe,{id:d,selected:i,onChange:t,placeholderText:m,disabled:r,minDate:p,maxDate:a,dateFormat:c,showTimeSelect:true,timeIntervals:u,className:`wx-datetimepicker-input ${l?"wx-datetimepicker-input-error":""} ${s||""}`,popperPlacement:"bottom-start",wrapperClassName:"wx-datetimepicker-react-wrapper"}),jsxs("svg",{className:"wx-datetimepicker-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("rect",{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"}),jsx("line",{x1:"16",y1:"2",x2:"16",y2:"6"}),jsx("line",{x1:"8",y1:"2",x2:"8",y2:"6"}),jsx("line",{x1:"3",y1:"10",x2:"21",y2:"10"}),jsx("circle",{cx:"12",cy:"15",r:"2"})]})]}),e&&!l&&jsx("div",{className:"wx-datetimepicker-hint",children:e}),l&&jsx("div",{className:"wx-datetimepicker-error-text",children:l})]})}function be({value:i,onChange:t,label:n,placeholder:m="Select time",error:l,hint:e,disabled:r=false,timeIntervals:p=15,timeFormat:a="h:mm aa",id:c,className:u}){T(!!n,"TimePicker needs label");let v=c||`wx-timepicker-${Math.random().toString(36).slice(2)}`;return jsxs("div",{className:"wx-timepicker-wrapper",children:[n&&jsx("label",{htmlFor:v,className:"wx-timepicker-label",children:n}),jsxs("div",{className:"wx-timepicker-input-wrapper",children:[jsx(qe,{id:v,selected:i,onChange:t,placeholderText:m,disabled:r,showTimeSelect:true,showTimeSelectOnly:true,timeIntervals:p,timeCaption:"Time",dateFormat:a,className:`wx-timepicker-input ${l?"wx-timepicker-input-error":""} ${u||""}`,popperPlacement:"bottom-start",wrapperClassName:"wx-timepicker-react-wrapper"}),jsxs("svg",{className:"wx-timepicker-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("circle",{cx:"12",cy:"12",r:"10"}),jsx("polyline",{points:"12 6 12 12 16 14"})]})]}),e&&!l&&jsx("div",{className:"wx-timepicker-hint",children:e}),l&&jsx("div",{className:"wx-timepicker-error-text",children:l})]})}function ke({label:i,accept:t,multiple:n=false,maxSize:m,onChange:l,onError:e,hint:r,error:p,disabled:a=false,id:c,className:u}){T(!!i,"FileUpload needs label");let[v,s]=useState(false),[d,f]=useState([]),o=useRef(null),x=c||`wx-fileupload-${Math.random().toString(36).slice(2)}`,k=g=>{if(m&&g.size>m)return `File "${g.name}" exceeds maximum size of ${$(m)}`;if(t){let z=t.split(",").map(h=>h.trim()),P="."+g.name.split(".").pop()?.toLowerCase(),C=g.type;if(!z.some(h=>h.startsWith(".")?P===h.toLowerCase():h.endsWith("/*")?C.startsWith(h.replace("/*","")):C===h))return `File "${g.name}" type not accepted`}return null},L=g=>{if(!g||g.length===0)return;let z=Array.from(g),P=[],C="";for(let h of z){let se=k(h);if(se){C=se;break}P.push(h);}if(C){e?.(C);return}let b=n?[...d,...P]:P;f(b),l?.(b);},y=g=>{g.preventDefault(),s(false),!a&&L(g.dataTransfer.files);},N=g=>{g.preventDefault(),a||s(true);},I=()=>{s(false);},A=()=>{a||o.current?.click();},J=g=>{L(g.target.files);},F=g=>{let z=d.filter((P,C)=>C!==g);f(z),l?.(z);},$=g=>{if(g===0)return "0 Bytes";let z=1024,P=["Bytes","KB","MB","GB"],C=Math.floor(Math.log(g)/Math.log(z));return Math.round(g/Math.pow(z,C)*100)/100+" "+P[C]};return jsxs("div",{className:`wx-fileupload-wrapper ${u||""}`,children:[i&&jsx("label",{htmlFor:x,className:"wx-fileupload-label",children:i}),jsxs("div",{className:`wx-fileupload-dropzone ${v?"wx-fileupload-dropzone-dragging":""} ${p?"wx-fileupload-dropzone-error":""} ${a?"wx-fileupload-dropzone-disabled":""}`,onDrop:y,onDragOver:N,onDragLeave:I,onClick:A,children:[jsx("input",{ref:o,id:x,type:"file",accept:t,multiple:n,onChange:J,disabled:a,className:"wx-fileupload-input"}),jsx("svg",{className:"wx-fileupload-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"})}),jsxs("div",{className:"wx-fileupload-text",children:[jsx("span",{className:"wx-fileupload-text-primary",children:"Drop files here or click to browse"}),t&&jsxs("span",{className:"wx-fileupload-text-secondary",children:["Accepted: ",t]}),m&&jsxs("span",{className:"wx-fileupload-text-secondary",children:["Max size: ",$(m)]})]})]}),d.length>0&&jsx("div",{className:"wx-fileupload-list",children:d.map((g,z)=>jsxs("div",{className:"wx-fileupload-item",children:[jsxs("div",{className:"wx-fileupload-item-info",children:[jsx("span",{className:"wx-fileupload-item-name",children:g.name}),jsx("span",{className:"wx-fileupload-item-size",children:$(g.size)})]}),!a&&jsx("button",{type:"button",onClick:P=>{P.stopPropagation(),F(z);},className:"wx-fileupload-item-remove","aria-label":"Remove file",children:"\xD7"})]},z))}),r&&!p&&jsx("div",{className:"wx-fileupload-hint",children:r}),p&&jsx("div",{className:"wx-fileupload-error-text",children:p})]})}function ne({label:i,value:t="",onChange:n,placeholder:m="Start typing...",hint:l,error:e,disabled:r=false,minHeight:p=150,toolbar:a=["bold","italic","underline","link","ul","ol","h1","h2"],id:c,className:u}){T(!!i,"HtmlEditor needs label");let[v,s]=useState(false),d=useRef(null),f=c||`wx-htmleditor-${Math.random().toString(36).slice(2)}`;useEffect(()=>{if(d.current&&d.current.innerHTML!==t){let y=ye.sanitize(t,{ALLOWED_TAGS:["p","br","strong","em","u","a","ul","ol","li","h1","h2"],ALLOWED_ATTR:["href"]});d.current.innerHTML=y;}},[t]);let o=(y,N)=>{document.execCommand(y,false,N),d.current?.focus();},x=y=>{let N=y.currentTarget.innerHTML,I=ye.sanitize(N,{ALLOWED_TAGS:["p","br","strong","em","u","a","ul","ol","li","h1","h2"],ALLOWED_ATTR:["href"]});n?.(I);},L={bold:{label:"B",command:"bold",title:"Bold",style:{fontWeight:"bold"}},italic:{label:"I",command:"italic",title:"Italic",style:{fontStyle:"italic"}},underline:{label:"U",command:"underline",title:"Underline",style:{textDecoration:"underline"}},link:{label:"\u{1F517}",command:"createLink",title:"Insert Link",onClick:()=>{let y=prompt("Enter URL:");y&&o("createLink",y);}},ul:{label:"\u2022 List",command:"insertUnorderedList",title:"Bullet List"},ol:{label:"1. List",command:"insertOrderedList",title:"Numbered List"},h1:{label:"H1",command:"formatBlock",value:"h1",title:"Heading 1"},h2:{label:"H2",command:"formatBlock",value:"h2",title:"Heading 2"}};return jsxs("div",{className:`wx-htmleditor-wrapper ${u||""}`,children:[i&&jsx("label",{htmlFor:f,className:"wx-htmleditor-label",children:i}),jsxs("div",{className:`wx-htmleditor-container ${v?"wx-htmleditor-container-focused":""} ${e?"wx-htmleditor-container-error":""} ${r?"wx-htmleditor-container-disabled":""}`,children:[jsx("div",{className:"wx-htmleditor-toolbar",children:a.map(y=>{let N=L[y];return N?jsx("button",{type:"button",className:"wx-htmleditor-toolbar-btn",onClick:()=>{N.onClick?N.onClick():o(N.command,N.value);},title:N.title,disabled:r,style:N.style,children:N.label},y):null})}),jsx("div",{ref:d,id:f,contentEditable:!r,onInput:x,onFocus:()=>s(true),onBlur:()=>s(false),className:"wx-htmleditor-content",style:{minHeight:`${p}px`},"data-placeholder":m,dir:"ltr",suppressContentEditableWarning:true})]}),l&&!e&&jsx("div",{className:"wx-htmleditor-hint",children:l}),e&&jsx("div",{className:"wx-htmleditor-error-text",children:e})]})}function Io({content:i,className:t}){let n=ye.sanitize(i,{ALLOWED_TAGS:["p","br","strong","em","u","a","ul","ol","li","h1","h2","h3","h4","h5","h6","blockquote","code","pre","span","div"],ALLOWED_ATTR:["href","target","rel","class"]});return jsx("div",{className:`wx-html-content ${t||""}`,dangerouslySetInnerHTML:{__html:n}})}function Te({name:i,value:t}){return jsx("input",{type:"hidden",name:i,value:t||""})}function Le({label:i,href:t="javascript:void(0)",onClick:n,prependText:m,appendText:l,target:e,className:r,disabled:p=false}){return jsxs("div",{className:"wx-link-wrapper",children:[m&&jsx("span",{className:"wx-link-prepend",children:m}),jsx("a",{href:p?void 0:t,onClick:c=>{if(p){c.preventDefault();return}n?.(c);},target:e,className:`wx-link ${p?"wx-link-disabled":""} ${r||""}`,"aria-disabled":p,children:i}),l&&jsx("span",{className:"wx-link-append",children:l})]})}function Pe({node:i,level:t,onToggle:n,isLast:m}){let[l,e]=useState(true),r=i.options&&i.options.length>0,p=a=>{n(i.value,a.target.checked);};return jsxs("div",{className:"wx-tree-node",children:[jsxs("div",{className:"wx-tree-node-content",children:[jsx("input",{type:"checkbox",checked:i.checked||false,onChange:p,className:"wx-tree-checkbox"}),jsx("span",{className:"wx-tree-label",children:i.name})]}),r&&l&&jsx("ul",{className:`wx-tree-children ${m?"wx-tree-last-level":""}`,children:i.options.map((a,c)=>jsx("li",{children:jsx(Pe,{node:a,level:t+1,onToggle:n,isLast:!a.options||a.options.length===0})},a.value))})]})}function Ce({data:i,onChange:t,label:n,className:m}){let[l,e]=useState(i),r=(a,c)=>{let u=d=>d.map(f=>{if(f.value===a){let o={...f,checked:c};return o.options&&(o.options=v(o.options,c)),o}return f.options?{...f,options:u(f.options)}:f}),v=(d,f)=>d.map(o=>({...o,checked:f,options:o.options?v(o.options,f):void 0})),s=u(l);e(s),t?.(s);},p=a=>!a.options||a.options.length===0?false:a.options.every(c=>!c.options||c.options.length===0);return jsxs("div",{className:`wx-tree-wrapper ${m||""}`,children:[n&&jsx("div",{className:"wx-tree-label-header",children:n}),jsx("ul",{className:"wx-tree",children:l.map(a=>jsx("li",{children:jsx(Pe,{node:a,level:0,onToggle:r,isLast:p(a)})},a.value))})]})}function De({label:i,value:t=0,onChange:n,min:m=0,max:l=100,step:e=1,hint:r,className:p,showValue:a=true}){return jsxs("div",{className:`wx-slider-container ${p||""}`,children:[i&&jsx("label",{className:"wx-slider-label",children:i}),jsxs("div",{className:"wx-slider-wrapper",children:[jsx("input",{type:"range",className:"wx-slider",value:t,onChange:c=>n?.(Number(c.target.value)),min:m,max:l,step:e}),a&&jsx("div",{className:"wx-slider-value",children:t.toLocaleString()})]}),r&&jsx("div",{className:"wx-slider-hint",children:r})]})}function mi({vertical:i}){return jsx("div",{className:`wx-divider ${i?"wx-divider-vertical":""}`})}function hi({size:i=24}){return jsx("div",{className:"wx-spinner",style:{width:i,height:i}})}function Ni({type:i="info",children:t}){return jsx("div",{className:`wx-alert wx-alert-${i}`,children:t})}function Ci({direction:i="vertical",gap:t=8,children:n}){return jsx("div",{style:{display:"flex",flexDirection:i==="vertical"?"column":"row",gap:t},children:n})}function Ei(i){return i}function ji(i,t={},n=()=>{}){let m=[],l=i.required||[];return Object.entries(i.properties).forEach(([e,r])=>{let p=r.title||e.charAt(0).toUpperCase()+e.slice(1).replace(/_/g," "),a=l.includes(e),c=r.description,u=r["x-placeholder"],v={minLength:r.minLength,maxLength:r.maxLength,min:r.minimum,max:r.maximum,pattern:r.pattern},s,d=true,f=r["x-component"];if(f==="hidden")s=jsx(Te,{name:e}),d=false;else if(f==="button")s=jsx(pe,{type:r["x-button-type"]||"button",variant:r["x-button-variant"]||"primary",onClick:()=>console.log(r["x-button-action"]||`${e} clicked`),children:p}),d=false;else if(f==="tree")s=jsx(Ce,{data:r["x-data"]||[],onChange:o=>n(e,o)});else if(f==="link")s=jsx(Le,{label:p,onClick:()=>{}}),d=false;else if(f==="htmlEditor")s=jsx(ne,{hint:c,value:t[e],onChange:o=>n(e,o)});else if(f==="dateRange"){let o=t[e]||[null,null];s=jsx(ge,{hint:c,startDate:o[0],endDate:o[1],onChange:x=>n(e,x)});}else if(r.enum)f==="multiselect"?s=jsx(Q,{options:r.enum.map(o=>({label:o,value:o})),multiple:true,showSelectAll:true,required:a,value:t[e],onChange:o=>n(e,o)}):r.enum.length>4?s=jsx(Q,{options:r.enum.map(o=>({label:o,value:o})),required:a,value:t[e],onChange:o=>n(e,o)}):(s=jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:r.enum.map(o=>jsx(xe,{name:e,label:o,required:a,checked:t[e]===o,onChange:()=>n(e,o)},o))}),d=false);else if(r.type==="boolean")f==="checkbox"?(s=jsx(Y,{label:p,checked:t[e],onChange:o=>n(e,o.target.checked)}),d=false):(s=jsx(me,{label:p,checked:t[e],onChange:o=>n(e,o)}),d=false);else if(r.type==="string")r.format==="date"?s=jsx(we,{hint:c,value:t[e],onChange:o=>n(e,o)}):r.format==="date-time"?s=jsx(he,{hint:c,value:t[e],onChange:o=>n(e,o)}):r.format==="time"?s=jsx(be,{hint:c,value:t[e],onChange:o=>n(e,o)}):r.format==="email"?s=jsx(O,{type:"email",hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u}):r.format==="uri"||r.format==="url"?s=jsx(O,{type:"url",hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u}):r.format==="password"?s=jsx(O,{type:"password",hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u}):r.contentMediaType==="text/html"?s=jsx(ne,{hint:c,value:t[e],onChange:o=>n(e,o)}):r.format==="binary"||r.contentMediaType?.startsWith("image/")||r.contentMediaType?.startsWith("application/")?s=jsx(ke,{hint:c,onChange:o=>n(e,o)}):r.maxLength&&r.maxLength>200?s=jsx(de,{required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u}):s=jsx(O,{hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u});else if(r.type==="number"||r.type==="integer")r.minimum!==void 0&&r.maximum!==void 0?s=jsx(De,{value:t[e]||r.minimum,onChange:o=>n(e,o),min:r.minimum,max:r.maximum,hint:c}):s=jsx(O,{type:"number",hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u});else if(r.type==="array")if(f==="checkbox-group"&&r.items?.enum){let o=t[e]||[];s=jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(150px, 1fr))",gap:"12px"},children:r.items.enum.map(x=>jsx(Y,{label:x,checked:o.includes(x),onChange:k=>{let L=k.target.checked?[...o,x]:o.filter(y=>y!==x);n(e,L);}},x))}),d=true;}else {let o=r["x-data"]||[];s=jsx(fe,{options:o,value:t[e],onChange:x=>n(e,x)});}else s=jsx(O,{hint:c,required:a,value:t[e],onChange:o=>n(e,o.target.value),placeholder:u});m.push({name:e,label:p,component:s,required:a,useFormFieldLabel:d,validation:v});}),m}export{Ni as Alert,fe as Autocomplete,pe as Button,Y as Checkbox,we as DatePicker,ge as DateRangePicker,he as DateTimePicker,mi as Divider,ke as FileUpload,Te as Hidden,Io as HtmlContent,ne as HtmlEditor,O as Input,Le as Link,xe as Radio,Q as Select,De as Slider,hi as Spinner,Ci as Stack,me as Switch,de as Textarea,be as TimePicker,Ce as Tree,ji as schemaToFormFields,Ei as useDebounce,T as warn};
@@ -0,0 +1 @@
1
+ *{box-sizing:border-box;}
@@ -0,0 +1,22 @@
1
+
2
+ @import "../components/Button/Button.css";
3
+ @import "../components/Input/Input.css";
4
+ @import "../components/Textarea/Textarea.css";
5
+ @import "../components/Checkbox/Checkbox.css";
6
+ @import "../components/Radio/Radio.css";
7
+ @import "../components/Switch/Switch.css";
8
+ @import "../components/Select/Select.css";
9
+ @import "../components/Autocomplete/Autocomplete.css";
10
+ @import "../components/DatePicker/DatePicker.css";
11
+ @import "../components/DateRangePicker/DateRangePicker.css";
12
+ @import "../components/DateTimePicker/DateTimePicker.css";
13
+ @import "../components/TimePicker/TimePicker.css";
14
+ @import "../components/FileUpload/FileUpload.css";
15
+ @import "../components/HtmlEditor/HtmlEditor.css";
16
+ @import "../components/HtmlContent/HtmlContent.css";
17
+ @import "../components/Link/Link.css";
18
+ @import "../components/Tree/Tree.css";
19
+ @import "../components/Slider/Slider.css";
20
+ @import "../components/Divider/Divider.css";
21
+ @import "../components/Spinner/Spinner.css";
22
+ @import "../components/Alert/Alert.css";
@@ -0,0 +1,9 @@
1
+ :root {
2
+ --wx-color-primary: #f19924;
3
+ --wx-color-primary-hover: #e08916;
4
+ --wx-color-destructive: #dc2626;
5
+ --wx-color-destructive-hover: #b91c1c;
6
+ --wx-color-text: #333;
7
+ --wx-color-border: #ddd;
8
+ --wx-color-bg-subtle: #f5f5f5;
9
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@waysnx/ui-core",
3
+ "version": "0.1.1",
4
+ "description": "Core UI components for WaysNX - includes inputs, buttons, date pickers, and form controls",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "keywords": [
14
+ "react",
15
+ "ui",
16
+ "components",
17
+ "waysnx",
18
+ "forms",
19
+ "datepicker",
20
+ "autocomplete"
21
+ ],
22
+ "author": "WaysNX Technologies",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/waysnx/waysnx-ui-kit.git",
27
+ "directory": "ui-core"
28
+ },
29
+ "peerDependencies": {
30
+ "react": ">=18",
31
+ "react-datepicker": "^8.0.0",
32
+ "react-dom": ">=18"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^25.0.3",
36
+ "@types/react": "^19.2.7",
37
+ "@types/react-datepicker": "^7.0.0",
38
+ "@types/react-dom": "^19.2.3",
39
+ "copyfiles": "^2.4.1",
40
+ "tsup": "^8.5.1",
41
+ "typescript": "^5.9.3"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup && npm run copy-css",
45
+ "copy-css": "copyfiles -u 1 \"src/**/*.css\" dist"
46
+ },
47
+ "dependencies": {
48
+ "@types/dompurify": "^3.0.5",
49
+ "dompurify": "^3.3.1"
50
+ }
51
+ }