diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts
index fd300ed5..b363b30f 100644
--- a/packages/ui/src/components/index.ts
+++ b/packages/ui/src/components/index.ts
@@ -23,6 +23,7 @@ export * from './label';
export * from './menu';
export * from './menubar';
export * from './navigation-menu';
+export * from './number-field';
export * from './pagination';
export * from './pin-input';
export * from './popover';
diff --git a/packages/ui/src/components/number-field/index.ts b/packages/ui/src/components/number-field/index.ts
new file mode 100644
index 00000000..c56b37ea
--- /dev/null
+++ b/packages/ui/src/components/number-field/index.ts
@@ -0,0 +1,9 @@
+import SNumberFieldDecrement from './number-field-decrement.vue';
+import SNumberFieldIncrement from './number-field-increment.vue';
+import SNumberFieldInput from './number-field-input.vue';
+import SNumberFieldRoot from './number-field-root.vue';
+import SNumberField from './number-field.vue';
+
+export { SNumberFieldDecrement, SNumberFieldIncrement, SNumberFieldInput, SNumberFieldRoot, SNumberField };
+
+export * from './types';
diff --git a/packages/ui/src/components/number-field/number-field-decrement.vue b/packages/ui/src/components/number-field/number-field-decrement.vue
new file mode 100644
index 00000000..78cec941
--- /dev/null
+++ b/packages/ui/src/components/number-field/number-field-decrement.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/ui/src/components/number-field/number-field-increment.vue b/packages/ui/src/components/number-field/number-field-increment.vue
new file mode 100644
index 00000000..e7756603
--- /dev/null
+++ b/packages/ui/src/components/number-field/number-field-increment.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/ui/src/components/number-field/number-field-input.vue b/packages/ui/src/components/number-field/number-field-input.vue
new file mode 100644
index 00000000..db72e15b
--- /dev/null
+++ b/packages/ui/src/components/number-field/number-field-input.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/packages/ui/src/components/number-field/number-field-root.vue b/packages/ui/src/components/number-field/number-field-root.vue
new file mode 100644
index 00000000..a2086ba5
--- /dev/null
+++ b/packages/ui/src/components/number-field/number-field-root.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/packages/ui/src/components/number-field/number-field.vue b/packages/ui/src/components/number-field/number-field.vue
new file mode 100644
index 00000000..5faed437
--- /dev/null
+++ b/packages/ui/src/components/number-field/number-field.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/ui/src/components/number-field/types.ts b/packages/ui/src/components/number-field/types.ts
new file mode 100644
index 00000000..1e829087
--- /dev/null
+++ b/packages/ui/src/components/number-field/types.ts
@@ -0,0 +1,43 @@
+import type {
+ ClassValue,
+ NumberFieldRootEmits,
+ NumberFieldDecrementProps as _NumberFieldDecrementProps,
+ NumberFieldIncrementProps as _NumberFieldIncrementProps,
+ NumberFieldInputProps as _NumberFieldInputProps,
+ NumberFieldRootProps as _NumberFieldRootProps
+} from '@soybean-ui/primitives';
+import type { NumberFieldSlots, ThemeSize } from '@soybean-ui/variants';
+
+export interface NumberFieldRootProps extends _NumberFieldRootProps {
+ size?: ThemeSize;
+}
+
+export interface NumberFieldInputProps extends _NumberFieldInputProps {
+ size?: ThemeSize;
+ center?: boolean;
+}
+
+export interface NumberFieldDecrementProps extends _NumberFieldDecrementProps {
+ size?: ThemeSize;
+ center?: boolean;
+ iconClass?: ClassValue;
+}
+
+export interface NumberFieldIncrementProps extends _NumberFieldIncrementProps {
+ size?: ThemeSize;
+ center?: boolean;
+ iconClass?: ClassValue;
+}
+
+export type NumberFieldUi = Partial>;
+
+export interface NumberFieldProps extends NumberFieldRootProps {
+ center?: boolean;
+ disabledDecrement?: boolean;
+ disabledIncrement?: boolean;
+ ui?: NumberFieldUi;
+}
+
+export type NumberFieldEmits = NumberFieldRootEmits;
+
+export type { NumberFieldRootEmits };
diff --git a/packages/variants/src/index.ts b/packages/variants/src/index.ts
index 30952a98..5f46b890 100644
--- a/packages/variants/src/index.ts
+++ b/packages/variants/src/index.ts
@@ -21,6 +21,7 @@ export * from './variants/label';
export * from './variants/menu';
export * from './variants/menubar';
export * from './variants/navigation-menu';
+export * from './variants/number-field';
export * from './variants/pagination';
export * from './variants/pin-input';
export * from './variants/popover';
diff --git a/packages/variants/src/variants/number-field.ts b/packages/variants/src/variants/number-field.ts
new file mode 100644
index 00000000..0becdd4d
--- /dev/null
+++ b/packages/variants/src/variants/number-field.ts
@@ -0,0 +1,119 @@
+// @unocss-include
+import { tv } from 'tailwind-variants';
+
+export const numberFieldVariants = tv({
+ slots: {
+ root: 'flex items-center w-full rounded-md border border-input bg-background focus-within:(border-input ring-2 ring-offset-2 ring-primary) disabled:(cursor-not-allowed opacity-50)',
+ decrement: `flex h-full shrink-0 items-center justify-center bg-transparent outline-none disabled:(cursor-not-allowed opacity-20)`,
+ decrementIcon: '',
+ increment: `flex h-full shrink-0 items-center justify-center bg-transparent outline-none disabled:(cursor-not-allowed opacity-20)`,
+ incrementIcon: '',
+ input: [
+ `h-full w-full grow bg-transparent`,
+ `placeholder:text-muted-foreground outline-none disabled:(cursor-not-allowed opacity-50)`
+ ]
+ },
+ variants: {
+ size: {
+ xs: {
+ decrement: 'p-1',
+ decrementIcon: 'text-xs',
+ increment: 'p-1',
+ incrementIcon: 'text-xs',
+ input: 'h-6 text-xs'
+ },
+ sm: {
+ decrement: 'p-1.25',
+ decrementIcon: 'text-sm',
+ increment: 'p-1.25',
+ incrementIcon: 'text-sm',
+ input: 'h-7 text-sm'
+ },
+ md: {
+ decrement: 'p-1.25',
+ decrementIcon: 'text-sm',
+ increment: 'p-1.25',
+ incrementIcon: 'text-sm',
+ input: 'h-8 text-sm'
+ },
+ lg: {
+ decrement: 'p-1.5',
+ decrementIcon: 'text-base',
+ increment: 'p-1.5',
+ incrementIcon: 'text-base',
+ input: 'h-9 text-base'
+ },
+ xl: {
+ decrement: 'p-1.5',
+ decrementIcon: 'text-lg',
+ increment: 'p-1.5',
+ incrementIcon: 'text-lg',
+ input: 'h-10 text-base'
+ },
+ xxl: {
+ decrement: 'p-2',
+ decrementIcon: 'text-xl',
+ increment: 'p-2',
+ incrementIcon: 'text-xl',
+ input: 'h-12 text-lg'
+ }
+ },
+ center: {
+ true: {
+ decrement: 'order-1',
+ input: 'text-center order-2',
+ increment: 'order-3'
+ }
+ }
+ },
+ compoundVariants: [
+ {
+ size: 'xs',
+ center: false,
+ class: {
+ input: 'pl-1.5'
+ }
+ },
+ {
+ size: 'sm',
+ center: false,
+ class: {
+ input: 'pl-2'
+ }
+ },
+ {
+ size: 'md',
+ center: false,
+ class: {
+ input: 'pl-2.5'
+ }
+ },
+ {
+ size: 'lg',
+ center: false,
+ class: {
+ input: 'pl-3'
+ }
+ },
+ {
+ size: 'xl',
+ center: false,
+ class: {
+ input: 'pl-3.5'
+ }
+ },
+ {
+ size: 'xxl',
+ center: false,
+ class: {
+ input: 'pl-4'
+ }
+ }
+ ],
+ defaultVariants: {
+ size: 'md',
+ center: false
+ }
+});
+
+export type NumberFieldSlots = keyof typeof numberFieldVariants.slots;
diff --git a/src/views/ui/index.vue b/src/views/ui/index.vue
index 3fad048d..83e0f628 100644
--- a/src/views/ui/index.vue
+++ b/src/views/ui/index.vue
@@ -29,6 +29,7 @@ import UiInput from './modules/input.vue';
import UiKeyboardKey from './modules/keyboard-key.vue';
import UiMenubar from './modules/menubar.vue';
import UiNavigationMenu from './modules/navigation-menu.vue';
+import UiNumberField from './modules/number-field.vue';
import UiPagination from './modules/pagination.vue';
import UiPinInput from './modules/pin-input.vue';
import UiPopover from './modules/popover.vue';
@@ -189,6 +190,11 @@ const tabs: TabConfig[] = [
label: 'NavigationMenu',
component: UiNavigationMenu
},
+ {
+ value: 'number-field',
+ label: 'NumberField',
+ component: UiNumberField
+ },
{
value: 'popover',
label: 'Popover',
diff --git a/src/views/ui/modules/number-field.vue b/src/views/ui/modules/number-field.vue
new file mode 100644
index 00000000..4babf8c3
--- /dev/null
+++ b/src/views/ui/modules/number-field.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
Size
+
+
Center
+
+
Disabled
+
+
Custom Icon
+
+
+
+
+
+
+
+
+
+