@neumorphism-ui/react 0.0.0-stage → 1.0.0-next.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 HungHD
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 CHANGED
@@ -1,3 +1,37 @@
1
- # Temporary Holding Version
1
+ # @neumorphism-ui/react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ React 18.3 and 19 wrappers for [neumorphism-ui](https://github.com/hunghdvn/neumorphism-ui):
4
+ `NeuButton`, `NeuSwitch`, `NeuTextField`, `NeuIcon`, `NeuIconButton`, `NeuButtonGroup`,
5
+ `NeuSurface`, `NeuDivider`, `NeuBadge`, `NeuAvatar` and `NeuSpinner`, generated from the element definitions. They set props
6
+ as element properties, forward refs to the real element, work controlled or uncontrolled like
7
+ React's `<input>`, and server-render declarative shadow roots, so they work with Next.js App Router
8
+ streaming. Pre-release.
9
+
10
+ ```sh
11
+ npm install @neumorphism-ui/react@next @neumorphism-ui/tokens@next
12
+ ```
13
+
14
+ ```tsx
15
+ import '@neumorphism-ui/tokens/neu.css';
16
+ import { NeuSwitch, NeuTextField } from '@neumorphism-ui/react';
17
+
18
+ <NeuTextField label="Email" value={email} onChange={(e) => setEmail((e.target as HTMLInputElement).value)} />;
19
+ <NeuSwitch name="notify" defaultChecked>Notifications</NeuSwitch>;
20
+ ```
21
+
22
+ ## Icon libraries
23
+
24
+ `NeuIcon` and `NeuIconButton` ship the built-in `system` icons. Register your own library with
25
+ `registerIconLibrary`, re-exported here from `@neumorphism-ui/elements` so you need no second import:
26
+
27
+ ```tsx
28
+ import { NeuIcon, registerIconLibrary } from '@neumorphism-ui/react';
29
+
30
+ registerIconLibrary('brand', { resolve: (name) => `/icons/${name}.svg` });
31
+
32
+ <NeuIcon library="brand" name="logo" label="Acme" />;
33
+ ```
34
+
35
+ `system` is reserved; registering a library with that name is ignored.
36
+
37
+ MIT licensed.
@@ -0,0 +1,15 @@
1
+ import { type ComponentDef } from '@neumorphism-ui/elements/ssr.js';
2
+ import * as React from 'react';
3
+ export type WrapperProps<K extends PropertyKey = never> = Omit<React.HTMLAttributes<HTMLElement>, K> & {
4
+ children?: React.ReactNode;
5
+ };
6
+ export interface WrapperConfig {
7
+ /** React prop name → DOM event name, e.g. { onChange: 'change' }. */
8
+ readonly events?: Readonly<Record<string, string>>;
9
+ }
10
+ interface ElementClass<E extends HTMLElement> {
11
+ readonly def: ComponentDef;
12
+ new (): E;
13
+ }
14
+ export declare function createComponent<P extends object, E extends HTMLElement>(elementClass: ElementClass<E>, config?: WrapperConfig): React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<E>>;
15
+ export {};
@@ -0,0 +1,147 @@
1
+ 'use client';
2
+ import { attributeName, coerceProperty, formDefaultProp, renderShadowContents, serializeAttribute, } from '@neumorphism-ui/elements/ssr.js';
3
+ import * as React from 'react';
4
+ const isServer = typeof window === 'undefined';
5
+ const useIsomorphicLayoutEffect = isServer ? React.useEffect : React.useLayoutEffect;
6
+ const needsClassAttribute = Number.parseInt(React.version, 10) < 19;
7
+ export function createComponent(elementClass, config = {}) {
8
+ const def = elementClass.def;
9
+ const events = config.events ?? {};
10
+ const valueProp = def.form?.valueProp;
11
+ const defaultProp = formDefaultProp(def);
12
+ const elementKeys = new Set(Object.keys(def.props));
13
+ if (defaultProp)
14
+ elementKeys.add(defaultProp);
15
+ const Wrapper = React.forwardRef(function NeuWrapper(props, forwardedRef) {
16
+ const elementRef = React.useRef(null);
17
+ const { children, ...rest } = props;
18
+ const host = {};
19
+ const element = {};
20
+ // Several props may share one DOM event (onInput and onChange on a text field); they run in
21
+ // the order of the wrapper's event map.
22
+ const handlers = {};
23
+ for (const [key, eventName] of Object.entries(events)) {
24
+ const value = rest[key];
25
+ if (typeof value === 'function')
26
+ (handlers[eventName] ??= []).push(value);
27
+ }
28
+ for (const [key, value] of Object.entries(rest)) {
29
+ if (Object.hasOwn(events, key))
30
+ continue;
31
+ if (elementKeys.has(key)) {
32
+ element[key] = value;
33
+ }
34
+ else {
35
+ host[key] = value;
36
+ }
37
+ }
38
+ if (needsClassAttribute && 'className' in host) {
39
+ host.class = host.className;
40
+ delete host.className;
41
+ }
42
+ const latest = React.useRef(element);
43
+ latest.current = element;
44
+ const handlersRef = React.useRef(handlers);
45
+ handlersRef.current = handlers;
46
+ const applied = React.useRef(new Set());
47
+ // Properties after every commit. Defaults go first so a controlled value set in the same pass wins.
48
+ useIsomorphicLayoutEffect(() => {
49
+ const node = elementRef.current;
50
+ if (!node)
51
+ return;
52
+ const absent = (key) => element[key] === undefined || (key === defaultProp && element[key] === null);
53
+ for (const key of applied.current) {
54
+ if (!absent(key))
55
+ continue;
56
+ if (key === defaultProp && valueProp) {
57
+ // The element's default setter would stringify undefined; drop the attribute instead.
58
+ node.removeAttribute(attributeName(valueProp, def.props[valueProp]));
59
+ }
60
+ else {
61
+ node[key] = undefined;
62
+ }
63
+ }
64
+ const next = new Set();
65
+ const keys = Object.keys(element).sort((a, b) => Number(b === defaultProp) - Number(a === defaultProp));
66
+ for (const key of keys) {
67
+ const value = element[key];
68
+ if (absent(key))
69
+ continue;
70
+ next.add(key);
71
+ if (node[key] !== value)
72
+ node[key] = value;
73
+ }
74
+ applied.current = next;
75
+ });
76
+ const eventNames = Object.keys(handlers).sort().join(' ');
77
+ useIsomorphicLayoutEffect(() => {
78
+ const node = elementRef.current;
79
+ if (!node)
80
+ return;
81
+ const names = new Set(eventNames === '' ? [] : eventNames.split(' '));
82
+ if (valueProp) {
83
+ names.add('input');
84
+ names.add('change');
85
+ }
86
+ const listener = (event) => {
87
+ if (event.target !== node)
88
+ return;
89
+ for (const handler of handlersRef.current[event.type] ?? [])
90
+ handler(event);
91
+ if (!valueProp)
92
+ return;
93
+ // Controlled: once React has had a chance to re-render, snap back to the prop.
94
+ queueMicrotask(() => {
95
+ const wanted = latest.current[valueProp];
96
+ const current = elementRef.current;
97
+ if (current && wanted !== undefined && current[valueProp] !== wanted) {
98
+ current[valueProp] = wanted;
99
+ }
100
+ });
101
+ };
102
+ for (const name of names)
103
+ node.addEventListener(name, listener);
104
+ return () => {
105
+ for (const name of names)
106
+ node.removeEventListener(name, listener);
107
+ };
108
+ }, [eventNames]);
109
+ const setRef = React.useCallback((node) => {
110
+ elementRef.current = node;
111
+ if (typeof forwardedRef === 'function')
112
+ forwardedRef(node);
113
+ else if (forwardedRef)
114
+ forwardedRef.current = node;
115
+ }, [forwardedRef]);
116
+ const serverAttributes = {};
117
+ let template = null;
118
+ if (isServer) {
119
+ for (const [key, decl] of Object.entries(def.props)) {
120
+ const raw = key === valueProp && element[key] === undefined && defaultProp
121
+ ? element[defaultProp]
122
+ : element[key];
123
+ if (raw === undefined)
124
+ continue;
125
+ const attribute = serializeAttribute(decl, coerceProperty(decl, raw));
126
+ if (attribute !== null)
127
+ serverAttributes[attributeName(key, decl)] = attribute;
128
+ }
129
+ const templateProps = {
130
+ shadowrootmode: 'open',
131
+ dangerouslySetInnerHTML: { __html: renderShadowContents(def, serverAttributes) },
132
+ };
133
+ if (def.delegatesFocus)
134
+ templateProps.shadowrootdelegatesfocus = '';
135
+ template = React.createElement('template', templateProps);
136
+ }
137
+ const hostProps = {
138
+ ...host,
139
+ ...serverAttributes,
140
+ ref: setRef,
141
+ suppressHydrationWarning: true,
142
+ };
143
+ return React.createElement(def.tag, hostProps, template, children);
144
+ });
145
+ Wrapper.displayName = def.tag;
146
+ return Wrapper;
147
+ }
@@ -0,0 +1,14 @@
1
+ import { NeuAvatar as NeuAvatarElement } from '@neumorphism-ui/elements/avatar.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuAvatarOwnProps {
4
+ src?: string;
5
+ label?: string;
6
+ initials?: string;
7
+ size?: 'sm' | 'md' | 'lg';
8
+ shape?: 'circle' | 'rounded';
9
+ }
10
+ export type NeuAvatarProps = WrapperProps<keyof NeuAvatarOwnProps> & NeuAvatarOwnProps;
11
+ export declare const NeuAvatar: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuAvatarOwnProps> & {
12
+ children?: import("react").ReactNode;
13
+ } & NeuAvatarOwnProps & import("react").RefAttributes<NeuAvatarElement>>;
14
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-avatar definition. Do not edit.
2
+ 'use client';
3
+ import { NeuAvatar as NeuAvatarElement } from '@neumorphism-ui/elements/avatar.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuAvatar = createComponent(NeuAvatarElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,11 @@
1
+ import { NeuBadge as NeuBadgeElement } from '@neumorphism-ui/elements/badge.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuBadgeOwnProps {
4
+ variant?: 'neutral' | 'accent' | 'success' | 'warning' | 'danger';
5
+ pill?: boolean;
6
+ }
7
+ export type NeuBadgeProps = WrapperProps<keyof NeuBadgeOwnProps> & NeuBadgeOwnProps;
8
+ export declare const NeuBadge: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuBadgeOwnProps> & {
9
+ children?: import("react").ReactNode;
10
+ } & NeuBadgeOwnProps & import("react").RefAttributes<NeuBadgeElement>>;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-badge definition. Do not edit.
2
+ 'use client';
3
+ import { NeuBadge as NeuBadgeElement } from '@neumorphism-ui/elements/badge.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuBadge = createComponent(NeuBadgeElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,11 @@
1
+ import { NeuButtonGroup as NeuButtonGroupElement } from '@neumorphism-ui/elements/button-group.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuButtonGroupOwnProps {
4
+ label?: string;
5
+ orientation?: 'horizontal' | 'vertical';
6
+ }
7
+ export type NeuButtonGroupProps = WrapperProps<keyof NeuButtonGroupOwnProps> & NeuButtonGroupOwnProps;
8
+ export declare const NeuButtonGroup: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuButtonGroupOwnProps> & {
9
+ children?: import("react").ReactNode;
10
+ } & NeuButtonGroupOwnProps & import("react").RefAttributes<NeuButtonGroupElement>>;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-button-group definition. Do not edit.
2
+ 'use client';
3
+ import { NeuButtonGroup as NeuButtonGroupElement } from '@neumorphism-ui/elements/button-group.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuButtonGroup = createComponent(NeuButtonGroupElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,14 @@
1
+ import { NeuButton as NeuButtonElement } from '@neumorphism-ui/elements/button.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuButtonOwnProps {
4
+ variant?: 'default' | 'primary' | 'flat';
5
+ size?: 'sm' | 'md' | 'lg';
6
+ disabled?: boolean;
7
+ loading?: boolean;
8
+ type?: 'button' | 'submit' | 'reset';
9
+ }
10
+ export type NeuButtonProps = WrapperProps<keyof NeuButtonOwnProps> & NeuButtonOwnProps;
11
+ export declare const NeuButton: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuButtonOwnProps> & {
12
+ children?: import("react").ReactNode;
13
+ } & NeuButtonOwnProps & import("react").RefAttributes<NeuButtonElement>>;
14
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-button definition. Do not edit.
2
+ 'use client';
3
+ import { NeuButton as NeuButtonElement } from '@neumorphism-ui/elements/button.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuButton = createComponent(NeuButtonElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,10 @@
1
+ import { NeuDivider as NeuDividerElement } from '@neumorphism-ui/elements/divider.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuDividerOwnProps {
4
+ orientation?: 'horizontal' | 'vertical';
5
+ }
6
+ export type NeuDividerProps = WrapperProps<keyof NeuDividerOwnProps> & NeuDividerOwnProps;
7
+ export declare const NeuDivider: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, "orientation"> & {
8
+ children?: import("react").ReactNode;
9
+ } & NeuDividerOwnProps & import("react").RefAttributes<NeuDividerElement>>;
10
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-divider definition. Do not edit.
2
+ 'use client';
3
+ import { NeuDivider as NeuDividerElement } from '@neumorphism-ui/elements/divider.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuDivider = createComponent(NeuDividerElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,17 @@
1
+ import { NeuIconButton as NeuIconButtonElement } from '@neumorphism-ui/elements/icon-button.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuIconButtonOwnProps {
4
+ icon?: string;
5
+ library?: string;
6
+ label?: string;
7
+ shape?: 'circle' | 'square';
8
+ variant?: 'default' | 'primary' | 'flat';
9
+ size?: 'sm' | 'md' | 'lg';
10
+ disabled?: boolean;
11
+ type?: 'button' | 'submit' | 'reset';
12
+ }
13
+ export type NeuIconButtonProps = WrapperProps<keyof NeuIconButtonOwnProps> & NeuIconButtonOwnProps;
14
+ export declare const NeuIconButton: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuIconButtonOwnProps> & {
15
+ children?: import("react").ReactNode;
16
+ } & NeuIconButtonOwnProps & import("react").RefAttributes<NeuIconButtonElement>>;
17
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-icon-button definition. Do not edit.
2
+ 'use client';
3
+ import { NeuIconButton as NeuIconButtonElement } from '@neumorphism-ui/elements/icon-button.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuIconButton = createComponent(NeuIconButtonElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,12 @@
1
+ import { NeuIcon as NeuIconElement } from '@neumorphism-ui/elements/icon.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuIconOwnProps {
4
+ name?: string;
5
+ library?: string;
6
+ label?: string;
7
+ }
8
+ export type NeuIconProps = WrapperProps<keyof NeuIconOwnProps> & NeuIconOwnProps;
9
+ export declare const NeuIcon: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuIconOwnProps> & {
10
+ children?: import("react").ReactNode;
11
+ } & NeuIconOwnProps & import("react").RefAttributes<NeuIconElement>>;
12
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-icon definition. Do not edit.
2
+ 'use client';
3
+ import { NeuIcon as NeuIconElement } from '@neumorphism-ui/elements/icon.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuIcon = createComponent(NeuIconElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,11 @@
1
+ export { NeuAvatar, type NeuAvatarProps } from './avatar.js';
2
+ export { NeuBadge, type NeuBadgeProps } from './badge.js';
3
+ export { NeuButton, type NeuButtonProps } from './button.js';
4
+ export { NeuButtonGroup, type NeuButtonGroupProps } from './button-group.js';
5
+ export { NeuDivider, type NeuDividerProps } from './divider.js';
6
+ export { NeuIcon, type NeuIconProps } from './icon.js';
7
+ export { NeuIconButton, type NeuIconButtonProps } from './icon-button.js';
8
+ export { NeuSpinner, type NeuSpinnerProps } from './spinner.js';
9
+ export { NeuSurface, type NeuSurfaceProps } from './surface.js';
10
+ export { NeuSwitch, type NeuSwitchProps } from './switch.js';
11
+ export { NeuTextField, type NeuTextFieldProps } from './text-field.js';
@@ -0,0 +1,12 @@
1
+ // Generated by tools/gen. Do not edit.
2
+ export { NeuAvatar } from './avatar.js';
3
+ export { NeuBadge } from './badge.js';
4
+ export { NeuButton } from './button.js';
5
+ export { NeuButtonGroup } from './button-group.js';
6
+ export { NeuDivider } from './divider.js';
7
+ export { NeuIcon } from './icon.js';
8
+ export { NeuIconButton } from './icon-button.js';
9
+ export { NeuSpinner } from './spinner.js';
10
+ export { NeuSurface } from './surface.js';
11
+ export { NeuSwitch } from './switch.js';
12
+ export { NeuTextField } from './text-field.js';
@@ -0,0 +1,11 @@
1
+ import { NeuSpinner as NeuSpinnerElement } from '@neumorphism-ui/elements/spinner.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuSpinnerOwnProps {
4
+ label?: string;
5
+ size?: 'sm' | 'md' | 'lg';
6
+ }
7
+ export type NeuSpinnerProps = WrapperProps<keyof NeuSpinnerOwnProps> & NeuSpinnerOwnProps;
8
+ export declare const NeuSpinner: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuSpinnerOwnProps> & {
9
+ children?: import("react").ReactNode;
10
+ } & NeuSpinnerOwnProps & import("react").RefAttributes<NeuSpinnerElement>>;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-spinner definition. Do not edit.
2
+ 'use client';
3
+ import { NeuSpinner as NeuSpinnerElement } from '@neumorphism-ui/elements/spinner.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuSpinner = createComponent(NeuSpinnerElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,13 @@
1
+ import { NeuSurface as NeuSurfaceElement } from '@neumorphism-ui/elements/surface.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuSurfaceOwnProps {
4
+ shape?: 'raised' | 'inset' | 'flat' | 'convex' | 'concave';
5
+ elevation?: 'sm' | 'md' | 'lg';
6
+ radius?: 'sm' | 'md' | 'lg' | 'full';
7
+ padding?: 'none' | 'sm' | 'md' | 'lg';
8
+ }
9
+ export type NeuSurfaceProps = WrapperProps<keyof NeuSurfaceOwnProps> & NeuSurfaceOwnProps;
10
+ export declare const NeuSurface: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuSurfaceOwnProps> & {
11
+ children?: import("react").ReactNode;
12
+ } & NeuSurfaceOwnProps & import("react").RefAttributes<NeuSurfaceElement>>;
13
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-surface definition. Do not edit.
2
+ 'use client';
3
+ import { NeuSurface as NeuSurfaceElement } from '@neumorphism-ui/elements/surface.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuSurface = createComponent(NeuSurfaceElement, {
6
+ events: {},
7
+ });
@@ -0,0 +1,18 @@
1
+ import { NeuSwitch as NeuSwitchElement } from '@neumorphism-ui/elements/switch.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuSwitchOwnProps {
4
+ checked?: boolean;
5
+ name?: string;
6
+ value?: string;
7
+ disabled?: boolean;
8
+ required?: boolean;
9
+ size?: 'sm' | 'md' | 'lg';
10
+ defaultChecked?: boolean;
11
+ onInput?: (event: Event) => void;
12
+ onChange?: (event: Event) => void;
13
+ }
14
+ export type NeuSwitchProps = WrapperProps<keyof NeuSwitchOwnProps> & NeuSwitchOwnProps;
15
+ export declare const NeuSwitch: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuSwitchOwnProps> & {
16
+ children?: import("react").ReactNode;
17
+ } & NeuSwitchOwnProps & import("react").RefAttributes<NeuSwitchElement>>;
18
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-switch definition. Do not edit.
2
+ 'use client';
3
+ import { NeuSwitch as NeuSwitchElement } from '@neumorphism-ui/elements/switch.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuSwitch = createComponent(NeuSwitchElement, {
6
+ events: { onInput: 'input', onChange: 'change' },
7
+ });
@@ -0,0 +1,29 @@
1
+ import { NeuTextField as NeuTextFieldElement } from '@neumorphism-ui/elements/text-field.js';
2
+ import { type WrapperProps } from '../create-component.js';
3
+ interface NeuTextFieldOwnProps {
4
+ type?: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url';
5
+ value?: string;
6
+ name?: string;
7
+ label?: string;
8
+ placeholder?: string;
9
+ helpText?: string;
10
+ errorText?: string;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ readOnly?: boolean;
14
+ minLength?: number;
15
+ maxLength?: number;
16
+ pattern?: string;
17
+ autocomplete?: string;
18
+ inputMode?: string;
19
+ enterKeyHint?: string;
20
+ size?: 'sm' | 'md' | 'lg';
21
+ defaultValue?: string;
22
+ onInput?: (event: Event) => void;
23
+ onChange?: (event: Event) => void;
24
+ }
25
+ export type NeuTextFieldProps = WrapperProps<keyof NeuTextFieldOwnProps> & NeuTextFieldOwnProps;
26
+ export declare const NeuTextField: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, keyof NeuTextFieldOwnProps> & {
27
+ children?: import("react").ReactNode;
28
+ } & NeuTextFieldOwnProps & import("react").RefAttributes<NeuTextFieldElement>>;
29
+ export {};
@@ -0,0 +1,7 @@
1
+ // Generated by tools/gen from the neu-text-field definition. Do not edit.
2
+ 'use client';
3
+ import { NeuTextField as NeuTextFieldElement } from '@neumorphism-ui/elements/text-field.js';
4
+ import { createComponent } from '../create-component.js';
5
+ export const NeuTextField = createComponent(NeuTextFieldElement, {
6
+ events: { onInput: 'input', onChange: 'input' },
7
+ });
@@ -0,0 +1,3 @@
1
+ export * from './generated/index.js';
2
+ export { createComponent, type WrapperConfig, type WrapperProps } from './create-component.js';
3
+ export { registerIconLibrary, type IconLibrary } from '@neumorphism-ui/elements/icons.js';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './generated/index.js';
2
+ export { createComponent } from './create-component.js';
3
+ // Hand-written, Node-safe: lets React apps register icon libraries without a second import path.
4
+ export { registerIconLibrary } from '@neumorphism-ui/elements/icons.js';
package/package.json CHANGED
@@ -1,6 +1,48 @@
1
1
  {
2
2
  "name": "@neumorphism-ui/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0-next.0",
4
+ "description": "React wrappers for neumorphism-ui",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/hunghdvn/neumorphism-ui.git",
10
+ "directory": "packages/react"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "sideEffects": false,
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "provenance": true
26
+ },
27
+ "dependencies": {
28
+ "@neumorphism-ui/elements": "1.0.0-next.0"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "^18.3 || ^19",
32
+ "react-dom": "^18.3 || ^19"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "19.3.0",
36
+ "@types/react-dom": "19.3.0",
37
+ "esbuild": "0.28.2",
38
+ "react": "19.3.0",
39
+ "react-dom": "19.3.0",
40
+ "react18": "npm:react@18.3.1",
41
+ "react-dom18": "npm:react-dom@18.3.1"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc -p tsconfig.build.json",
45
+ "test": "pnpm --filter @neumorphism-ui/elements build && vitest run && node scripts/ssr-react18.mjs",
46
+ "typecheck": "tsc -p tsconfig.json --noEmit"
47
+ }
6
48
  }