From 52bc10de6ce6bfdcb15dfdbc3775850620c9c23e Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 01:37:29 +0000 Subject: [PATCH 1/2] Remove all Medusa-related components and references - Removed packages/medusa-forms/ package entirely - Removed apps/docs/src/medusa-forms/ Storybook stories - Updated apps/docs/package.json to remove @lambdacurry/medusa-forms dependency - Cleaned up TypeScript path mappings in apps/docs/tsconfig.json - Removed Medusa aliases from apps/docs/vite.config.mjs - Simplified apps/docs/src/main.css to remove Medusa UI imports and tokens - Updated yarn.lock to remove unused Medusa dependencies All Medusa components have been successfully migrated to the separate medusa-forms repository. --- apps/docs/package.json | 1 - apps/docs/src/main.css | 679 +-- .../ControlledCheckbox.stories.tsx | 396 -- .../ControlledCurrencyInput.stories.tsx | 272 -- .../ControlledDatePicker.stories.tsx | 273 -- .../medusa-forms/ControlledInput.stories.tsx | 40 - .../medusa-forms/ControlledSelect.stories.tsx | 482 -- .../ControlledTextArea.stories.tsx | 413 -- .../FormIntegrationExamples.stories.tsx | 673 --- apps/docs/tsconfig.json | 4 +- apps/docs/vite.config.mjs | 2 - packages/medusa-forms/package.json | 74 - .../src/controlled/ControlledCheckbox.tsx | 47 - .../controlled/ControlledCurrencyInput.tsx | 42 - .../src/controlled/ControlledDatePicker.tsx | 30 - .../src/controlled/ControlledInput.tsx | 51 - .../src/controlled/ControlledSelect.tsx | 71 - .../src/controlled/ControlledTextArea.tsx | 29 - packages/medusa-forms/src/controlled/index.ts | 6 - packages/medusa-forms/src/index.ts | 2 - packages/medusa-forms/src/ui/Button.tsx | 12 - packages/medusa-forms/src/ui/ColorInput.tsx | 35 - .../medusa-forms/src/ui/CurrencyInput.tsx | 14 - packages/medusa-forms/src/ui/DatePicker.tsx | 14 - packages/medusa-forms/src/ui/Error.tsx | 63 - .../medusa-forms/src/ui/FieldCheckbox.tsx | 60 - packages/medusa-forms/src/ui/FieldGroup.tsx | 6 - packages/medusa-forms/src/ui/FieldWrapper.tsx | 31 - packages/medusa-forms/src/ui/FileUpload.tsx | 115 - packages/medusa-forms/src/ui/Input.tsx | 14 - packages/medusa-forms/src/ui/Label.tsx | 27 - packages/medusa-forms/src/ui/Select.tsx | 32 - packages/medusa-forms/src/ui/TextArea.tsx | 14 - packages/medusa-forms/src/ui/index.ts | 13 - packages/medusa-forms/src/ui/types.d.ts | 128 - packages/medusa-forms/tsconfig.json | 23 - packages/medusa-forms/vite.config.ts | 94 - yarn.lock | 4051 ++--------------- 38 files changed, 444 insertions(+), 7889 deletions(-) delete mode 100644 apps/docs/src/medusa-forms/ControlledCheckbox.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/ControlledCurrencyInput.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/ControlledDatePicker.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/ControlledInput.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/ControlledSelect.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/ControlledTextArea.stories.tsx delete mode 100644 apps/docs/src/medusa-forms/FormIntegrationExamples.stories.tsx delete mode 100644 packages/medusa-forms/package.json delete mode 100644 packages/medusa-forms/src/controlled/ControlledCheckbox.tsx delete mode 100644 packages/medusa-forms/src/controlled/ControlledCurrencyInput.tsx delete mode 100644 packages/medusa-forms/src/controlled/ControlledDatePicker.tsx delete mode 100644 packages/medusa-forms/src/controlled/ControlledInput.tsx delete mode 100644 packages/medusa-forms/src/controlled/ControlledSelect.tsx delete mode 100644 packages/medusa-forms/src/controlled/ControlledTextArea.tsx delete mode 100644 packages/medusa-forms/src/controlled/index.ts delete mode 100644 packages/medusa-forms/src/index.ts delete mode 100644 packages/medusa-forms/src/ui/Button.tsx delete mode 100644 packages/medusa-forms/src/ui/ColorInput.tsx delete mode 100644 packages/medusa-forms/src/ui/CurrencyInput.tsx delete mode 100644 packages/medusa-forms/src/ui/DatePicker.tsx delete mode 100644 packages/medusa-forms/src/ui/Error.tsx delete mode 100644 packages/medusa-forms/src/ui/FieldCheckbox.tsx delete mode 100644 packages/medusa-forms/src/ui/FieldGroup.tsx delete mode 100644 packages/medusa-forms/src/ui/FieldWrapper.tsx delete mode 100644 packages/medusa-forms/src/ui/FileUpload.tsx delete mode 100644 packages/medusa-forms/src/ui/Input.tsx delete mode 100644 packages/medusa-forms/src/ui/Label.tsx delete mode 100644 packages/medusa-forms/src/ui/Select.tsx delete mode 100644 packages/medusa-forms/src/ui/TextArea.tsx delete mode 100644 packages/medusa-forms/src/ui/index.ts delete mode 100644 packages/medusa-forms/src/ui/types.d.ts delete mode 100644 packages/medusa-forms/tsconfig.json delete mode 100644 packages/medusa-forms/vite.config.ts diff --git a/apps/docs/package.json b/apps/docs/package.json index 528e69b0..a53f7e40 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -14,7 +14,6 @@ "@hookform/error-message": "^2.0.0", "@hookform/resolvers": "^3.9.1", "@lambdacurry/forms": "*", - "@lambdacurry/medusa-forms": "*", "@storybook/addon-links": "^9.0.1", "@storybook/react-vite": "^9.0.1", "react": "^19.0.0", diff --git a/apps/docs/src/main.css b/apps/docs/src/main.css index c1325f75..c89465a2 100644 --- a/apps/docs/src/main.css +++ b/apps/docs/src/main.css @@ -1,7 +1,5 @@ @import 'tailwindcss'; @source "../../../packages/components"; -@source "../../../packages/medusa-forms"; -@source "../../../node_modules/@medusajs/ui"; :root { --background: hsl(0 0% 100%); @@ -34,691 +32,48 @@ --ring: hsl(215 20.2% 65.1%); --radius: 0.5rem; - - /* Medusa UI Light Mode Tokens */ - --tag-neutral-border: rgba(228, 228, 231, 1); - --tag-neutral-icon: rgba(161, 161, 170, 1); - --bg-switch-off-hover: rgba(212, 212, 216, 1); - --border-menu-bot: rgba(255, 255, 255, 1); - --border-menu-top: rgba(228, 228, 231, 1); - --bg-subtle-hover: rgba(244, 244, 245, 1); - --contrast-fg-primary: rgba(255, 255, 255, 0.88); - --bg-switch-off: rgba(228, 228, 231, 1); - --contrast-bg-base-pressed: rgba(63, 63, 70, 1); - --bg-field-component-hover: rgba(250, 250, 250, 1); - --bg-base-pressed: rgba(228, 228, 231, 1); - --tag-neutral-text: rgba(82, 82, 91, 1); - --tag-red-text: rgba(159, 18, 57, 1); - --contrast-bg-base: rgba(24, 24, 27, 1); - --border-strong: rgba(212, 212, 216, 1); - --contrast-border-base: rgba(255, 255, 255, 0.15); - --bg-field: rgba(250, 250, 250, 1); - --tag-blue-text: rgba(30, 64, 175, 1); - --button-inverted-pressed: rgba(82, 82, 91, 1); - --border-interactive: rgba(59, 130, 246, 1); - --bg-base-hover: rgba(244, 244, 245, 1); - --contrast-bg-subtle: rgba(39, 39, 42, 1); - --bg-highlight: rgba(239, 246, 255, 1); - --contrast-fg-secondary: rgba(255, 255, 255, 0.56); - --tag-red-bg: rgba(255, 228, 230, 1); - --button-transparent: rgba(255, 255, 255, 0); - --button-danger-pressed: rgba(159, 18, 57, 1); - --fg-on-color: rgba(255, 255, 255, 1); - --button-inverted-hover: rgba(63, 63, 70, 1); - --bg-field-component: rgba(255, 255, 255, 1); - --tag-orange-text: rgba(154, 52, 18, 1); - --tag-green-icon: rgba(16, 185, 129, 1); - --border-base: rgba(228, 228, 231, 1); - --bg-base: rgba(255, 255, 255, 1); - --tag-orange-border: rgba(254, 215, 170, 1); - --tag-red-border: rgba(254, 205, 211, 1); - --tag-green-border: rgba(167, 243, 208, 1); - --tag-green-text: rgba(6, 95, 70, 1); - --button-neutral: rgba(255, 255, 255, 1); - --tag-blue-border: rgba(191, 219, 254, 1); - --fg-interactive-hover: rgba(37, 99, 235, 1); - --tag-orange-icon: rgba(249, 115, 22, 1); - --button-neutral-hover: rgba(244, 244, 245, 1); - --fg-interactive: rgba(59, 130, 246, 1); - --bg-component-pressed: rgba(228, 228, 231, 1); - --tag-purple-bg: rgba(237, 233, 254, 1); - --contrast-bg-base-hover: rgba(39, 39, 42, 1); - --bg-component: rgba(250, 250, 250, 1); - --bg-subtle: rgba(250, 250, 250, 1); - --tag-purple-text: rgba(91, 33, 182, 1); - --contrast-border-bot: rgba(255, 255, 255, 0.1); - --button-inverted: rgba(39, 39, 42, 1); - --tag-red-icon: rgba(244, 63, 94, 1); - --button-transparent-hover: rgba(244, 244, 245, 1); - --button-neutral-pressed: rgba(228, 228, 231, 1); - --tag-purple-icon: rgba(167, 139, 250, 1); - --bg-field-hover: rgba(244, 244, 245, 1); - --fg-on-inverted: rgba(255, 255, 255, 1); - --bg-interactive: rgba(59, 130, 246, 1); - --border-danger: rgba(190, 18, 60, 1); - --button-transparent-pressed: rgba(228, 228, 231, 1); - --tag-purple-border: rgba(221, 214, 254, 1); - --bg-highlight-hover: rgba(219, 234, 254, 1); - --border-error: rgba(225, 29, 72, 1); - --button-danger: rgba(225, 29, 72, 1); - --tag-blue-bg: rgba(219, 234, 254, 1); - --border-transparent: rgba(255, 255, 255, 0); - --button-danger-hover: rgba(190, 18, 60, 1); - --bg-subtle-pressed: rgba(228, 228, 231, 1); - --fg-error: rgba(225, 29, 72, 1); - --bg-component-hover: rgba(244, 244, 245, 1); - --bg-disabled: rgba(244, 244, 245, 1); - --tag-blue-icon: rgba(96, 165, 250, 1); - --fg-subtle: rgba(82, 82, 91, 1); - --tag-orange-bg-hover: rgba(254, 215, 170, 1); - --tag-green-bg-hover: rgba(167, 243, 208, 1); - --tag-red-bg-hover: rgba(254, 205, 211, 1); - --tag-purple-bg-hover: rgba(221, 214, 254, 1); - --tag-neutral-bg-hover: rgba(228, 228, 231, 1); - --tag-blue-bg-hover: rgba(191, 219, 254, 1); - --tag-green-bg: rgba(209, 250, 229, 1); - --tag-neutral-bg: rgba(244, 244, 245, 1); - --tag-orange-bg: rgba(255, 237, 213, 1); - --fg-base: rgba(24, 24, 27, 1); - --contrast-border-top: rgba(24, 24, 27, 1); - --bg-overlay: rgba(24, 24, 27, 0.4); - --fg-disabled: rgba(161, 161, 170, 1); - --fg-muted: rgba(113, 113, 122, 1); - --alpha-400: rgba(24, 24, 27, 0.24); - --alpha-250: rgba(24, 24, 27, 0.1); } .dark { - /* Original dark mode tokens */ --background: hsl(224 71% 4%); --foreground: hsl(213 31% 91%); + --muted: hsl(223 47% 11%); --muted-foreground: hsl(215.4 16.3% 56.9%); + --accent: hsl(216 34% 17%); --accent-foreground: hsl(210 40% 98%); + --popover: hsl(224 71% 4%); --popover-foreground: hsl(215 20.2% 65.1%); + --border: hsl(216 34% 17%); --input: hsl(216 34% 17%); + --card: hsl(224 71% 4%); --card-foreground: hsl(213 31% 91%); + --primary: hsl(210 40% 98%); --primary-foreground: hsl(222.2 47.4% 1.2%); - --secondary: hsl(222.2 47.4% 11.2%); + + --secondary: hsl(222.2 84% 4.9%); --secondary-foreground: hsl(210 40% 98%); + --destructive: hsl(0 63% 31%); --destructive-foreground: hsl(210 40% 98%); - --ring: hsl(216 34% 17%); - --radius: 0.5rem; - - /* Medusa UI Dark Mode Tokens */ - --button-danger-pressed: rgba(225, 29, 72, 1); - --bg-base-pressed: rgba(63, 63, 70, 1); - --bg-component-hover: rgba(255, 255, 255, 0.1); - --border-interactive: rgba(96, 165, 250, 1); - --button-neutral: rgba(255, 255, 255, 0.04); - --tag-orange-border: rgba(124, 45, 18, 1); - --tag-blue-text: rgba(147, 197, 253, 1); - --bg-highlight: rgba(23, 37, 84, 1); - --tag-neutral-icon: rgba(113, 113, 122, 1); - --bg-switch-off-hover: rgba(82, 82, 91, 1); - --fg-on-color: rgba(255, 255, 255, 1); - --button-inverted-pressed: rgba(161, 161, 170, 1); - --fg-interactive-hover: rgba(147, 197, 253, 1); - --fg-error: rgba(251, 113, 133, 1); - --bg-switch-off: rgba(63, 63, 70, 1); - --border-strong: rgba(255, 255, 255, 0.16); - --border-error: rgba(251, 113, 133, 1); - --fg-subtle: rgba(161, 161, 170, 1); - --bg-highlight-hover: rgba(30, 58, 138, 1); - --button-inverted: rgba(82, 82, 91, 1); - --tag-orange-text: rgba(253, 186, 116, 1); - --fg-base: rgba(244, 244, 245, 1); - --fg-disabled: rgba(82, 82, 91, 1); - --button-danger: rgba(159, 18, 57, 1); - --tag-neutral-border: rgba(255, 255, 255, 0.06); - --tag-blue-border: rgba(30, 58, 138, 1); - --tag-neutral-text: rgba(212, 212, 216, 1); - --tag-purple-border: rgba(91, 33, 182, 1); - --tag-green-text: rgba(52, 211, 153, 1); - --button-inverted-hover: rgba(113, 113, 122, 1); - --bg-component-pressed: rgba(255, 255, 255, 0.16); - --contrast-border-bot: rgba(255, 255, 255, 0.08); - --tag-blue-icon: rgba(96, 165, 250, 1); - --bg-field: rgba(255, 255, 255, 0.04); - --tag-neutral-bg: rgba(255, 255, 255, 0.08); - --tag-green-border: rgba(6, 78, 59, 1); - --tag-red-icon: rgba(251, 113, 133, 1); - --tag-red-text: rgba(253, 164, 175, 1); - --tag-purple-icon: rgba(167, 139, 250, 1); - --bg-interactive: rgba(96, 165, 250, 1); - --bg-field-hover: rgba(255, 255, 255, 0.08); - --border-transparent: rgba(255, 255, 255, 0); - --tag-orange-icon: rgba(251, 146, 60, 1); - --tag-purple-bg: rgba(46, 16, 101, 1); - --bg-base-hover: rgba(39, 39, 42, 1); - --tag-blue-bg: rgba(23, 37, 84, 1); - --tag-green-bg: rgba(2, 44, 34, 1); - --tag-purple-text: rgba(196, 181, 253, 1); - --tag-red-border: rgba(136, 19, 55, 1); - --border-danger: rgba(190, 18, 60, 1); - --tag-green-icon: rgba(16, 185, 129, 1); - --tag-red-bg: rgba(76, 5, 25, 1); - --fg-interactive: rgba(96, 165, 250, 1); - --tag-orange-bg: rgba(67, 20, 7, 1); - --button-danger-hover: rgba(190, 18, 60, 1); - --bg-component: rgba(39, 39, 42, 1); - --bg-disabled: rgba(39, 39, 42, 1); - --button-transparent: rgba(255, 255, 255, 0); - --border-menu-bot: rgba(255, 255, 255, 0.08); - --tag-purple-bg-hover: rgba(91, 33, 182, 1); - --tag-orange-bg-hover: rgba(124, 45, 18, 1); - --tag-blue-bg-hover: rgba(30, 58, 138, 1); - --tag-red-bg-hover: rgba(136, 19, 55, 1); - --tag-green-bg-hover: rgba(6, 78, 59, 1); - --border-menu-top: rgba(33, 33, 36, 1); - --bg-base: rgba(33, 33, 36, 1); - --contrast-border-top: rgba(33, 33, 36, 1); - --bg-field-component: rgba(33, 33, 36, 1); - --bg-subtle-hover: rgba(33, 33, 36, 1); - --bg-subtle: rgba(24, 24, 27, 1); - --fg-on-inverted: rgba(24, 24, 27, 1); - --bg-overlay: rgba(24, 24, 27, 0.72); - --button-transparent-hover: rgba(255, 255, 255, 0.08); - --contrast-fg-secondary: rgba(255, 255, 255, 0.56); - --contrast-border-base: rgba(255, 255, 255, 0.16); - --contrast-bg-base-pressed: rgba(82, 82, 91, 1); - --button-neutral-pressed: rgba(255, 255, 255, 0.12); - --border-base: rgba(255, 255, 255, 0.08); - --contrast-fg-primary: rgba(255, 255, 255, 0.88); - --button-neutral-hover: rgba(255, 255, 255, 0.08); - --contrast-bg-base: rgba(39, 39, 42, 1); - --tag-neutral-bg-hover: rgba(255, 255, 255, 0.12); - --contrast-bg-subtle: rgba(255, 255, 255, 0.04); - --contrast-bg-base-hover: rgba(63, 63, 70, 1); - --bg-field-component-hover: rgba(39, 39, 42, 1); - --bg-subtle-pressed: rgba(39, 39, 42, 1); - --button-transparent-pressed: rgba(255, 255, 255, 0.12); - --fg-muted: rgba(113, 113, 122, 1); - --alpha-400: rgba(255, 255, 255, 0.24); - --alpha-250: rgba(255, 255, 255, 0.1); - - /* Medusa UI Dark Mode Shadow Effects */ - --borders-interactive-with-shadow: 0px 1px 2px 0px rgba(219, 234, 254, 0.5), 0px 0px 0px 1px rgba(96, 165, 250, 1); - --details-contrast-on-bg-interactive: 0px 1px 2px 0px rgba(30, 58, 138, 0.6); - --details-switch-handle: 0px 0px 2px 1px rgba(255, 255, 255, 1) inset, 0px 1px 0px 0px rgba(255, 255, 255, 1) inset, - 0px 0px 0px 0.5px rgba(0, 0, 0, 0.16), 0px 5px 4px 0px rgba(0, 0, 0, 0.1), 0px 3px 3px 0px rgba(0, 0, 0, 0.1), - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.1); - --borders-interactive-with-active: 0px 0px 0px 1px rgba(96, 165, 250, 1), 0px 0px 0px 4px rgba(59, 130, 246, 0.25); - --borders-focus: 0px 0px 0px 1px rgba(24, 24, 27, 1), 0px 0px 0px 3px rgba(96, 165, 250, 0.8); - --borders-interactive-with-focus: 0px 1px 2px 0px rgba(219, 234, 254, 0.5), 0px 0px 0px 1px rgba(96, 165, 250, 1), - 0px 0px 0px 2px rgba(24, 24, 27, 1), 0px 0px 0px 4px rgba(96, 165, 250, 0.8); - --details-switch-background-focus: 0px 0px 0px 1px rgba(24, 24, 27, 1), 0px 0px 0px 3px rgba(96, 165, 250, 0.8), - 0px 1px 1px 0px rgba(0, 0, 0, 0.1) inset, 0px 2px 4px 0px rgba(0, 0, 0, 0.1) inset, - 0px 0px 0px 0.75px rgba(255, 255, 255, 0.12) inset, 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset; - --buttons-danger: 0px -1px 0px 0px rgba(255, 255, 255, 0.16), 0px 0px 0px 1px rgba(255, 255, 255, 0.12), - 0px 0px 0px 1px rgba(159, 18, 57, 1), 0px 0px 1px 1.5px rgba(0, 0, 0, 0.24), 0px 2px 2px 0px rgba(0, 0, 0, 0.24); - --buttons-danger-focus: 0px -1px 0px 0px rgba(255, 255, 255, 0.16), 0px 0px 0px 1px rgba(255, 255, 255, 0.12), - 0px 0px 0px 1px rgba(159, 18, 57, 1), 0px 0px 0px 2px rgba(24, 24, 27, 1), 0px 0px 0px 4px rgba(96, 165, 250, 0.8); - --details-switch-background: 0px 1px 1px 0px rgba(0, 0, 0, 0.1) inset, 0px 2px 4px 0px rgba(0, 0, 0, 0.1) inset, - 0px 0px 0px 0.75px rgba(255, 255, 255, 0.12) inset, 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset; - --buttons-inverted-focus: 0px -1px 0px 0px rgba(255, 255, 255, 0.12), 0px 0px 0px 1px rgba(255, 255, 255, 0.12), - 0px 0px 0px 1px rgba(82, 82, 91, 1), 0px 0px 0px 2px rgba(24, 24, 27, 1), 0px 0px 0px 4px rgba(96, 165, 250, 0.8); - --elevation-flyout: 0px -1px 0px 0px rgba(255, 255, 255, 0.04), 0px 0px 0px 1px rgba(255, 255, 255, 0.1), - 0px 4px 8px 0px rgba(0, 0, 0, 0.32), 0px 8px 16px 0px rgba(0, 0, 0, 0.32); - --borders-error: 0px 0px 0px 1px rgba(244, 63, 94, 1), 0px 0px 0px 3px rgba(225, 29, 72, 0.25); - --buttons-inverted: 0px -1px 0px 0px rgba(255, 255, 255, 0.12), 0px 0px 0px 1px rgba(255, 255, 255, 0.1), - 0px 0px 0px 1px rgba(82, 82, 91, 1), 0px 0px 1px 1.5px rgba(0, 0, 0, 0.24), 0px 2px 2px 0px rgba(0, 0, 0, 0.24); - --borders-base: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 0px 1px 1.5px rgba(0, 0, 0, 0.24), 0px 2px 2px 0px rgba(0, 0, 0, 0.24); - --elevation-card-hover: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 1px 4px 0px rgba(0, 0, 0, 0.48), 0px 2px 8px 0px rgba(0, 0, 0, 0.48); - --elevation-card-rest: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 1px 2px 0px rgba(0, 0, 0, 0.32), 0px 2px 4px 0px rgba(0, 0, 0, 0.32); - --buttons-neutral: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 0px 1px 1.5px rgba(0, 0, 0, 0.24), 0px 2px 2px 0px rgba(0, 0, 0, 0.24); - --elevation-code-block: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 1px 2px 0px rgba(0, 0, 0, 0.32), 0px 2px 4px 0px rgba(0, 0, 0, 0.32); - --buttons-neutral-focus: 0px -1px 0px 0px rgba(255, 255, 255, 0.06), 0px 0px 0px 1px rgba(255, 255, 255, 0.06), - 0px 0px 0px 1px rgba(39, 39, 42, 1), 0px 0px 0px 2px rgba(24, 24, 27, 1), 0px 0px 0px 4px rgba(96, 165, 250, 0.8); - --elevation-modal: 0px 0px 0px 1px rgba(24, 24, 27, 1) inset, 0px 0px 0px 1.5px rgba(255, 255, 255, 0.06) inset, - 0px -1px 0px 0px rgba(255, 255, 255, 0.04), 0px 0px 0px 1px rgba(255, 255, 255, 0.1), - 0px 4px 8px 0px rgba(0, 0, 0, 0.32), 0px 8px 16px 0px rgba(0, 0, 0, 0.32); - --elevation-commandbar: 0px 0px 0px 0.75px rgba(24, 24, 27, 1) inset, - 0px 0px 0px 1.25px rgba(255, 255, 255, 0.1) inset, 0px 4px 8px 0px rgba(0, 0, 0, 0.32), - 0px 8px 16px 0px rgba(0, 0, 0, 0.32); - --elevation-tooltip: 0px -1px 0px 0px rgba(255, 255, 255, 0.04), 0px 2px 4px 0px rgba(0, 0, 0, 0.32), - 0px 0px 0px 1px rgba(255, 255, 255, 0.1), 0px 4px 8px 0px rgba(0, 0, 0, 0.32); -} - -@theme inline { - /* Original color mappings */ - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); - --color-ring: var(--ring); - - /* Medusa UI Color Mappings */ - --color-ui-tag-neutral-border: var(--tag-neutral-border); - --color-ui-tag-neutral-icon: var(--tag-neutral-icon); - --color-ui-tag-neutral-text: var(--tag-neutral-text); - --color-ui-tag-neutral-bg: var(--tag-neutral-bg); - --color-ui-tag-neutral-bg-hover: var(--tag-neutral-bg-hover); - --color-ui-tag-red-text: var(--tag-red-text); - --color-ui-tag-red-bg: var(--tag-red-bg); - --color-ui-tag-red-bg-hover: var(--tag-red-bg-hover); - --color-ui-tag-red-border: var(--tag-red-border); - --color-ui-tag-red-icon: var(--tag-red-icon); - --color-ui-tag-blue-text: var(--tag-blue-text); - --color-ui-tag-blue-border: var(--tag-blue-border); - --color-ui-tag-blue-bg: var(--tag-blue-bg); - --color-ui-tag-blue-bg-hover: var(--tag-blue-bg-hover); - --color-ui-tag-blue-icon: var(--tag-blue-icon); - --color-ui-tag-orange-text: var(--tag-orange-text); - --color-ui-tag-orange-border: var(--tag-orange-border); - --color-ui-tag-orange-icon: var(--tag-orange-icon); - --color-ui-tag-orange-bg: var(--tag-orange-bg); - --color-ui-tag-orange-bg-hover: var(--tag-orange-bg-hover); - --color-ui-tag-green-icon: var(--tag-green-icon); - --color-ui-tag-green-border: var(--tag-green-border); - --color-ui-tag-green-text: var(--tag-green-text); - --color-ui-tag-green-bg: var(--tag-green-bg); - --color-ui-tag-green-bg-hover: var(--tag-green-bg-hover); - --color-ui-tag-purple-bg: var(--tag-purple-bg); - --color-ui-tag-purple-bg-hover: var(--tag-purple-bg-hover); - --color-ui-tag-purple-text: var(--tag-purple-text); - --color-ui-tag-purple-icon: var(--tag-purple-icon); - --color-ui-tag-purple-border: var(--tag-purple-border); - --color-ui-bg-switch-off: var(--bg-switch-off); - --color-ui-bg-switch-off-hover: var(--bg-switch-off-hover); - --color-ui-bg-subtle: var(--bg-subtle); - --color-ui-bg-subtle-hover: var(--bg-subtle-hover); - --color-ui-bg-subtle-pressed: var(--bg-subtle-pressed); - --color-ui-bg-field: var(--bg-field); - --color-ui-bg-field-hover: var(--bg-field-hover); - --color-ui-bg-field-component: var(--bg-field-component); - --color-ui-bg-field-component-hover: var(--bg-field-component-hover); - --color-ui-bg-base: var(--bg-base); - --color-ui-bg-base-hover: var(--bg-base-hover); - --color-ui-bg-base-pressed: var(--bg-base-pressed); - --color-ui-bg-highlight: var(--bg-highlight); - --color-ui-bg-highlight-hover: var(--bg-highlight-hover); - --color-ui-bg-component: var(--bg-component); - --color-ui-bg-component-hover: var(--bg-component-hover); - --color-ui-bg-component-pressed: var(--bg-component-pressed); - --color-ui-bg-interactive: var(--bg-interactive); - --color-ui-bg-disabled: var(--bg-disabled); - --color-ui-bg-overlay: var(--bg-overlay); - --color-ui-border-menu-bot: var(--border-menu-bot); - --color-ui-border-menu-top: var(--border-menu-top); - --color-ui-border-strong: var(--border-strong); - --color-ui-border-interactive: var(--border-interactive); - --color-ui-border-base: var(--border-base); - --color-ui-border-danger: var(--border-danger); - --color-ui-border-error: var(--border-error); - --color-ui-border-transparent: var(--border-transparent); - --color-ui-contrast-fg-primary: var(--contrast-fg-primary); - --color-ui-contrast-fg-secondary: var(--contrast-fg-secondary); - --color-ui-contrast-bg-base: var(--contrast-bg-base); - --color-ui-contrast-bg-base-hover: var(--contrast-bg-base-hover); - --color-ui-contrast-bg-base-pressed: var(--contrast-bg-base-pressed); - --color-ui-contrast-bg-subtle: var(--contrast-bg-subtle); - --color-ui-contrast-border-base: var(--contrast-border-base); - --color-ui-contrast-border-bot: var(--contrast-border-bot); - --color-ui-contrast-border-top: var(--contrast-border-top); - --color-ui-button-inverted: var(--button-inverted); - --color-ui-button-inverted-hover: var(--button-inverted-hover); - --color-ui-button-inverted-pressed: var(--button-inverted-pressed); - --color-ui-button-transparent: var(--button-transparent); - --color-ui-button-transparent-hover: var(--button-transparent-hover); - --color-ui-button-transparent-pressed: var(--button-transparent-pressed); - --color-ui-button-danger: var(--button-danger); - --color-ui-button-danger-hover: var(--button-danger-hover); - --color-ui-button-danger-pressed: var(--button-danger-pressed); - --color-ui-button-neutral: var(--button-neutral); - --color-ui-button-neutral-hover: var(--button-neutral-hover); - --color-ui-button-neutral-pressed: var(--button-neutral-pressed); - --color-ui-fg-on-color: var(--fg-on-color); - --color-ui-fg-on-inverted: var(--fg-on-inverted); - --color-ui-fg-interactive: var(--fg-interactive); - --color-ui-fg-interactive-hover: var(--fg-interactive-hover); - --color-ui-fg-error: var(--fg-error); - --color-ui-fg-subtle: var(--fg-subtle); - --color-ui-fg-base: var(--fg-base); - --color-ui-fg-disabled: var(--fg-disabled); - --color-ui-fg-muted: var(--fg-muted); - --color-ui-alpha-250: var(--alpha-250); - --color-ui-alpha-400: var(--alpha-400); - - /* Medusa UI Shadow Effects */ - --shadow-borders-interactive-with-active: 0px 0px 0px 1px rgba(59, 130, 246, 1), - 0px 0px 0px 4px rgba(59, 130, 246, 0.2); - --shadow-buttons-danger-focus: 0px 0.75px 0px 0px rgba(255, 255, 255, 0.2) inset, - 0px 1px 2px 0px rgba(190, 18, 60, 0.4), 0px 0px 0px 1px rgba(190, 18, 60, 1), 0px 0px 0px 2px rgba(255, 255, 255, 1), - 0px 0px 0px 4px rgba(59, 130, 246, 0.6); - --shadow-details-contrast-on-bg-interactive: 0px 1px 2px 0px rgba(30, 58, 138, 0.6); - --shadow-borders-interactive-with-focus: 0px 1px 2px 0px rgba(30, 58, 138, 0.5), 0px 0px 0px 1px rgba(59, 130, 246, 1), - 0px 0px 0px 2px rgba(255, 255, 255, 1), 0px 0px 0px 4px rgba(59, 130, 246, 0.6); - --shadow-borders-error: 0px 0px 0px 1px rgba(225, 29, 72, 1), 0px 0px 0px 3px rgba(225, 29, 72, 0.15); - --shadow-borders-focus: 0px 0px 0px 1px rgba(255, 255, 255, 1), 0px 0px 0px 3px rgba(59, 130, 246, 0.6); - --shadow-borders-interactive-with-shadow: 0px 1px 2px 0px rgba(30, 58, 138, 0.5), - 0px 0px 0px 1px rgba(59, 130, 246, 1); - --shadow-buttons-danger: 0px 0.75px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 2px 0px rgba(190, 18, 60, 0.4), - 0px 0px 0px 1px rgba(190, 18, 60, 1); - --shadow-buttons-inverted-focus: 0px 0.75px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 2px 0px rgba(0, 0, 0, 0.4), - 0px 0px 0px 1px rgba(24, 24, 27, 1), 0px 0px 0px 2px rgba(255, 255, 255, 1), 0px 0px 0px 4px rgba(59, 130, 246, 0.6); - --shadow-elevation-card-hover: 0px 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 1px 2px -1px rgba(0, 0, 0, 0.08), - 0px 2px 8px 0px rgba(0, 0, 0, 0.1); - --shadow-details-switch-handle: 0px 0px 2px 1px rgba(255, 255, 255, 1) inset, - 0px 1px 0px 0px rgba(255, 255, 255, 1) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.02), - 0px 5px 4px 0px rgba(0, 0, 0, 0.02), 0px 3px 3px 0px rgba(0, 0, 0, 0.04), 0px 1px 2px 0px rgba(0, 0, 0, 0.12), - 0px 0px 1px 0px rgba(0, 0, 0, 0.08); - --shadow-buttons-neutral: 0px 1px 2px 0px rgba(0, 0, 0, 0.12), 0px 0px 0px 1px rgba(0, 0, 0, 0.08); - --shadow-borders-base: 0px 1px 2px 0px rgba(0, 0, 0, 0.12), 0px 0px 0px 1px rgba(0, 0, 0, 0.08); - --shadow-elevation-card-rest: 0px 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 1px 2px -1px rgba(0, 0, 0, 0.08), - 0px 2px 4px 0px rgba(0, 0, 0, 0.04); - --shadow-buttons-neutral-focus: 0px 1px 2px 0px rgba(0, 0, 0, 0.12), 0px 0px 0px 1px rgba(0, 0, 0, 0.08), - 0px 0px 0px 2px rgba(255, 255, 255, 1), 0px 0px 0px 4px rgba(59, 130, 246, 0.6); - --shadow-details-switch-background-focus: 0px 0px 0px 1px rgba(255, 255, 255, 1), - 0px 0px 0px 3px rgba(59, 130, 246, 0.6), 0px 1px 1px 0px rgba(0, 0, 0, 0.04) inset, - 0px 2px 4px 0px rgba(0, 0, 0, 0.04) inset, 0px 0px 0px 0.75px rgba(0, 0, 0, 0.06) inset, - 0px 0px 8px 0px rgba(0, 0, 0, 0.02) inset, 0px 2px 4px 0px rgba(0, 0, 0, 0.04); - --shadow-details-switch-background: 0px 1px 1px 0px rgba(0, 0, 0, 0.04) inset, - 0px 2px 4px 0px rgba(0, 0, 0, 0.04) inset, 0px 0px 0px 0.75px rgba(0, 0, 0, 0.06) inset, - 0px 0px 8px 0px rgba(0, 0, 0, 0.02) inset, 0px 2px 4px 0px rgba(0, 0, 0, 0.04); - --shadow-elevation-flyout: 0px 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 4px 8px 0px rgba(0, 0, 0, 0.08), - 0px 8px 16px 0px rgba(0, 0, 0, 0.08); - --shadow-elevation-tooltip: 0px 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 2px 4px 0px rgba(0, 0, 0, 0.08), - 0px 4px 8px 0px rgba(0, 0, 0, 0.08); - --shadow-elevation-modal: 0px 0px 0px 1px rgba(255, 255, 255, 1) inset, - 0px 0px 0px 1.5px rgba(228, 228, 231, 0.6) inset, 0px 0px 0px 1px rgba(0, 0, 0, 0.08), - 0px 8px 16px 0px rgba(0, 0, 0, 0.08), 0px 16px 32px 0px rgba(0, 0, 0, 0.08); - --shadow-elevation-code-block: 0px 0px 0px 1px rgba(24, 24, 27, 1) inset, - 0px 0px 0px 1.5px rgba(255, 255, 255, 0.2) inset; - --shadow-buttons-inverted: 0px 0.75px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 2px 0px rgba(0, 0, 0, 0.4), - 0px 0px 0px 1px rgba(24, 24, 27, 1); - --shadow-elevation-commandbar: 0px 0px 0px 0.75px rgba(39, 39, 42, 1) inset, - 0px 0px 0px 1.25px rgba(255, 255, 255, 0.3) inset, 0px 8px 16px 0px rgba(0, 0, 0, 0.08), - 0px 16px 32px 0px rgba(0, 0, 0, 0.08); -} - -@layer base { - * { - @apply border-[var(--color-border)]; - } - body { - @apply bg-[var(--color-background)] text-[var(--color-foreground)]; - } -} - -/* Medusa UI Typography Classes */ -.h1-webs { - font-size: 4rem; - line-height: 4.400000095367432rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h2-webs { - font-size: 3.5rem; - line-height: 3.8500001430511475rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h3-webs { - font-size: 2.5rem; - line-height: 2.75rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h4-webs { - font-size: 1.5rem; - line-height: 1.875rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h1-core { - font-size: 1.125rem; - line-height: 1.75rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h2-core { - font-size: 1rem; - line-height: 1.5rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h3-core { - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h1-docs { - font-size: 1.5rem; - line-height: 1.875rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h2-docs { - font-size: 1.125rem; - line-height: 1.6875rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.h3-docs { - font-size: 1rem; - line-height: 1.5rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-xlarge { - font-size: 1.125rem; - line-height: 1.6875rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-xlarge-plus { - font-size: 1.125rem; - line-height: 1.6875rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-large { - font-size: 1rem; - line-height: 1.5rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-large-plus { - font-size: 1rem; - line-height: 1.5rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-medium { - font-size: 0.875rem; - line-height: 1.3125rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-medium-plus { - font-size: 0.875rem; - line-height: 1.3125rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-small { - font-size: 0.8125rem; - line-height: 1.21875rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} -.txt-small-plus { - font-size: 0.8125rem; - line-height: 1.21875rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-xsmall { - font-size: 0.75rem; - line-height: 1.125rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-xsmall-plus { - font-size: 0.75rem; - line-height: 1.125rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-xlarge { - font-size: 1.125rem; - line-height: 1.25rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-xlarge-plus { - font-size: 1.125rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-large { - font-size: 1rem; - line-height: 1.25rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-large-plus { - font-size: 1rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-medium { - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-medium-plus { - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-small { - font-size: 0.8125rem; - line-height: 1.25rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} - -.txt-compact-small-plus { - font-size: 0.8125rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} + --ring: hsl(216 34% 17%); -.txt-compact-xsmall { - font-size: 0.75rem; - line-height: 1.25rem; - font-weight: 400; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --radius: 0.5rem; } -.txt-compact-xsmall-plus { - font-size: 0.75rem; - line-height: 1.25rem; - font-weight: 500; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; +* { + border-color: hsl(var(--border)); } -.code-body { - font-size: 0.75rem; - line-height: 1.125rem; - font-weight: 400; - font-family: 'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', - monospace; +body { + background-color: hsl(var(--background)); + color: hsl(var(--foreground)); + font-feature-settings: "rlig" 1, "calt" 1; } -.code-label { - font-size: 0.75rem; - line-height: 0.9375rem; - font-weight: 500; - font-family: 'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', - monospace; -} diff --git a/apps/docs/src/medusa-forms/ControlledCheckbox.stories.tsx b/apps/docs/src/medusa-forms/ControlledCheckbox.stories.tsx deleted file mode 100644 index e75df06c..00000000 --- a/apps/docs/src/medusa-forms/ControlledCheckbox.stories.tsx +++ /dev/null @@ -1,396 +0,0 @@ -import { ControlledCheckbox } from '@lambdacurry/medusa-forms/controlled/ControlledCheckbox'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import React from 'react'; -import { FormProvider, useForm } from 'react-hook-form'; - -const meta = { - title: 'Medusa Forms/Controlled Checkbox', - component: ControlledCheckbox, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// Basic Usage Story -const BasicCheckboxForm = () => { - const form = useForm({ - defaultValues: { - acceptTerms: false, - }, - }); - - return ( - -
- -
- Current value: {form.watch('acceptTerms') ? 'true' : 'false'} -
-
-
- ); -}; - -export const BasicUsage: Story = { - render: () => , -}; - -// Default Checked State Story -const DefaultCheckedForm = () => { - const form = useForm({ - defaultValues: { - newsletter: true, - }, - }); - - return ( - -
- -
- Current value: {form.watch('newsletter') ? 'true' : 'false'} -
-
-
- ); -}; - -export const DefaultChecked: Story = { - render: () => , -}; - -// Default Unchecked State Story -const DefaultUncheckedForm = () => { - const form = useForm({ - defaultValues: { - marketing: false, - }, - }); - - return ( - -
- -
- Current value: {form.watch('marketing') ? 'true' : 'false'} -
-
-
- ); -}; - -export const DefaultUnchecked: Story = { - render: () => , -}; - -// Required Field Validation Story -const RequiredValidationForm = () => { - const form = useForm({ - defaultValues: { - requiredField: false, - }, - mode: 'onChange', - }); - - const onSubmit = (data: any) => { - console.log('Form submitted:', data); - }; - - return ( - -
- -
- Form valid: {form.formState.isValid ? 'Yes' : 'No'} -
- - -
- ); -}; - -export const RequiredValidation: Story = { - render: () => , -}; - -// Custom Validation Message Story -const CustomValidationForm = () => { - const form = useForm({ - defaultValues: { - agreement: false, - }, - mode: 'onChange', - }); - - return ( - -
- value === true || 'You must agree to the privacy policy' - }} - /> -
- Has errors: {form.formState.errors.agreement ? 'Yes' : 'No'} -
- {form.formState.errors.agreement && ( -
- Error: {form.formState.errors.agreement.message} -
- )} -
-
- ); -}; - -export const CustomValidationMessage: Story = { - render: () => , -}; - -// Error State Display Story -const ErrorStateForm = () => { - const form = useForm({ - defaultValues: { - errorField: false, - }, - }); - - // Manually trigger an error for demonstration - React.useEffect(() => { - form.setError('errorField', { - type: 'manual', - message: 'This is an example error message' - }); - }, [form]); - - return ( - -
- -
- This checkbox demonstrates the error state styling -
-
-
- ); -}; - -export const ErrorState: Story = { - render: () => , -}; - -// Disabled State Story -const DisabledStateForm = () => { - const form = useForm({ - defaultValues: { - disabledUnchecked: false, - disabledChecked: true, - }, - }); - - return ( - -
- - -
- These checkboxes are disabled and cannot be interacted with -
-
-
- ); -}; - -export const DisabledState: Story = { - render: () => , -}; - -// Multiple Checkboxes with State Management Story -const MultipleCheckboxesForm = () => { - const form = useForm({ - defaultValues: { - option1: false, - option2: true, - option3: false, - selectAll: false, - }, - }); - - const watchedValues = form.watch(['option1', 'option2', 'option3']); - const allSelected = watchedValues.every(Boolean); - const someSelected = watchedValues.some(Boolean); - - React.useEffect(() => { - form.setValue('selectAll', allSelected); - }, [allSelected, form]); - - const handleSelectAll = (checked: boolean) => { - form.setValue('option1', checked); - form.setValue('option2', checked); - form.setValue('option3', checked); - form.setValue('selectAll', checked); - }; - - return ( - -
- -
- - - -
-
- Selected: {watchedValues.filter(Boolean).length} of {watchedValues.length} -
-
-
- ); -}; - -export const MultipleCheckboxes: Story = { - render: () => , -}; - -// Form Integration Example Story -const CompleteFormExampleComponent = () => { - const form = useForm({ - defaultValues: { - username: '', - email: '', - acceptTerms: false, - newsletter: false, - marketing: false, - }, - mode: 'onChange', - }); - - const onSubmit = (data: any) => { - alert(`Form submitted with data: ${JSON.stringify(data, null, 2)}`); - }; - - return ( - -
-
- - -
- -
- - -
- -
- - - -
- -
- - -
- -
- Form valid: {form.formState.isValid ? 'Yes' : 'No'} -
-
-
- ); -}; - -export const CompleteFormExample: Story = { - render: () => , -}; diff --git a/apps/docs/src/medusa-forms/ControlledCurrencyInput.stories.tsx b/apps/docs/src/medusa-forms/ControlledCurrencyInput.stories.tsx deleted file mode 100644 index 36f027d9..00000000 --- a/apps/docs/src/medusa-forms/ControlledCurrencyInput.stories.tsx +++ /dev/null @@ -1,272 +0,0 @@ -import { zodResolver } from '@hookform/resolvers/zod'; -import { ControlledCurrencyInput } from '@lambdacurry/medusa-forms/controlled/ControlledCurrencyInput'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { FormProvider, useForm } from 'react-hook-form'; -import { z } from 'zod'; - -const meta = { - title: 'Medusa Forms/Controlled Currency Input', - component: ControlledCurrencyInput, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], - args: { - symbol: '$', - code: 'usd', - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -interface CurrencyFormData { - price: string; -} - -// Base wrapper component for stories -const CurrencyInputWithHookForm = ({ - currency = 'USD', - symbol = '$', - code = 'usd', - schema, - defaultValues = { price: '' }, - ...props -}: { - currency?: string; - symbol?: string; - code?: string; - schema?: z.ZodSchema; - defaultValues?: CurrencyFormData; - [key: string]: unknown; -}) => { - const form = useForm({ - resolver: schema ? zodResolver(schema) : undefined, - defaultValues, - }); - - return ( - -
- -
-
- ); -}; - -// 1. Different Currency Symbols -export const USDCurrency: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => , -}; - -export const EURCurrency: Story = { - args: { - name: 'price', - symbol: '€', - code: 'eur', - }, - render: (args) => , -}; - -export const GBPCurrency: Story = { - args: { - name: 'price', - symbol: '£', - code: 'gbp', - }, - render: (args) => , -}; - -// 2. Validation with Min/Max Values -const minValidationSchema = z.object({ - price: z.string().refine((val) => { - const num = Number.parseFloat(val); - return !Number.isNaN(num) && num >= 10; - }, 'Minimum price is $10'), -}); - -export const MinimumValueValidation: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => ( - - ), -}; - -const maxValidationSchema = z.object({ - price: z.string().refine((val) => { - const num = Number.parseFloat(val); - return !Number.isNaN(num) && num <= 1000; - }, 'Maximum price is $1000'), -}); - -export const MaximumValueValidation: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => ( - - ), -}; - -const rangeValidationSchema = z.object({ - price: z.string().refine((val) => { - const num = Number.parseFloat(val); - return !Number.isNaN(num) && num >= 50 && num <= 500; - }, 'Price must be between $50 and $500'), -}); - -export const RangeValidation: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => ( - - ), -}; - -// 3. Error Handling and Validation Messages -const requiredSchema = z.object({ - price: z - .string() - .min(1, 'Price is required') - .refine((val) => { - const num = Number.parseFloat(val); - return !Number.isNaN(num) && num > 0; - }, 'Price must be greater than 0'), -}); - -export const RequiredFieldValidation: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => ( - - ), -}; - -const customValidationSchema = z.object({ - price: z.string().refine((val) => { - const num = Number.parseFloat(val); - return !Number.isNaN(num) && num >= 1 && num <= 100; - }, 'Custom error: Price must be between $1 and $100'), -}); - -export const CustomValidationMessage: Story = { - args: { - name: 'price', - symbol: '$', - code: 'usd', - }, - render: (args) => ( - - ), -}; - -// 4. Different Currency Codes -export const JPYCurrency: Story = { - args: { - name: 'price', - symbol: '¥', - code: 'jpy', - }, - render: (args) => ( - - ), -}; - -export const CADCurrency: Story = { - args: { - name: 'price', - symbol: 'C$', - code: 'cad', - }, - render: (args) => ( - - ), -}; - -export const AUDCurrency: Story = { - args: { - name: 'price', - symbol: 'A$', - code: 'aud', - }, - render: (args) => ( - - ), -}; diff --git a/apps/docs/src/medusa-forms/ControlledDatePicker.stories.tsx b/apps/docs/src/medusa-forms/ControlledDatePicker.stories.tsx deleted file mode 100644 index e027610d..00000000 --- a/apps/docs/src/medusa-forms/ControlledDatePicker.stories.tsx +++ /dev/null @@ -1,273 +0,0 @@ -import { ControlledDatePicker } from '@lambdacurry/medusa-forms/controlled/ControlledDatePicker'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { FormProvider, useForm } from 'react-hook-form'; - -const meta = { - title: 'Medusa Forms/Controlled Date Picker', - component: ControlledDatePicker, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// 1. Basic Date Selection -const BasicDateSelectionComponent = () => { - const form = useForm({ - defaultValues: { - birthDate: '', - }, - }); - - return ( - -
- -
-
- ); -}; - -export const BasicDateSelection: Story = { - args: { - name: 'birthDate', - label: 'Birth Date', - placeholder: 'Select your birth date', - }, - render: () => , -}; - -// 2. Required Field Validation -const RequiredFieldValidationComponent = () => { - const form = useForm({ - defaultValues: { - requiredDate: '', - }, - }); - - const onSubmit = (data: unknown) => { - console.log('Form submitted:', data); - }; - - return ( - -
- - - {form.formState.errors.requiredDate && ( -

{form.formState.errors.requiredDate.message}

- )} - -
- ); -}; - -export const RequiredFieldValidation: Story = { - args: { - name: 'requiredDate', - label: 'Required Date', - placeholder: 'This field is required', - }, - render: () => , -}; - -// 3. Date Format Variations -const DateFormatVariationsComponent = () => { - const form = useForm({ - defaultValues: { - usFormat: '', - euroFormat: '', - isoFormat: '', - }, - }); - - return ( - -
- - - -
-
- ); -}; - -export const DateFormatVariations: Story = { - args: { - name: 'usFormat', - label: 'US Format (MM/DD/YYYY)', - placeholder: 'MM/DD/YYYY', - }, - render: () => , -}; - -// 4. Disabled Dates -const DisabledDatesComponent = () => { - const form = useForm({ - defaultValues: { - noPastDates: '', - noFutureDates: '', - specificDisabled: '', - }, - }); - - const today = new Date(); - const oneWeekAgo = new Date(); - oneWeekAgo.setDate(today.getDate() - 7); - const oneWeekFromNow = new Date(); - oneWeekFromNow.setDate(today.getDate() + 7); - - return ( - -
- - - -
-
- ); -}; - -export const DisabledDates: Story = { - args: { - name: 'noPastDates', - label: 'No Past Dates', - placeholder: 'Future dates only', - }, - render: () => , -}; - -// 5. Min/Max Date Constraints -const MinMaxDateConstraintsComponent = () => { - const form = useForm({ - defaultValues: { - constrainedDate: '', - businessDays: '', - ageRestricted: '', - }, - }); - - const today = new Date(); - const minDate = new Date(); - minDate.setDate(today.getDate() + 1); // Tomorrow - const maxDate = new Date(); - maxDate.setDate(today.getDate() + 30); // 30 days from now - - const eighteenYearsAgo = new Date(); - eighteenYearsAgo.setFullYear(today.getFullYear() - 18); - const hundredYearsAgo = new Date(); - hundredYearsAgo.setFullYear(today.getFullYear() - 100); - - return ( - -
- { - if (!value) return true; - const selectedDate = new Date(value); - if (selectedDate < minDate) return 'Date must be tomorrow or later'; - if (selectedDate > maxDate) return 'Date must be within 30 days'; - return true; - }, - }} - /> - { - const day = date.getDay(); - return day !== 0 && day !== 6; // Exclude Sunday (0) and Saturday (6) - }} - /> - { - if (!value) return true; - const selectedDate = new Date(value); - const age = today.getFullYear() - selectedDate.getFullYear(); - const monthDiff = today.getMonth() - selectedDate.getMonth(); - const dayDiff = today.getDate() - selectedDate.getDate(); - - let calculatedAge = age; - if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) { - calculatedAge--; - } - - return calculatedAge >= 18 || 'Must be 18 years or older'; - }, - }} - /> - {form.formState.errors.constrainedDate && ( -

{form.formState.errors.constrainedDate.message}

- )} - {form.formState.errors.ageRestricted && ( -

{form.formState.errors.ageRestricted.message}

- )} -
-
- ); -}; - -export const MinMaxDateConstraints: Story = { - args: { - name: 'constrainedDate', - label: 'Date Range (Tomorrow to 30 days)', - placeholder: 'Select within range', - }, - render: () => , -}; diff --git a/apps/docs/src/medusa-forms/ControlledInput.stories.tsx b/apps/docs/src/medusa-forms/ControlledInput.stories.tsx deleted file mode 100644 index 66d163e1..00000000 --- a/apps/docs/src/medusa-forms/ControlledInput.stories.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { ControlledInput } from '@lambdacurry/medusa-forms/controlled/ControlledInput'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { FormProvider, useForm } from 'react-hook-form'; - -const meta = { - title: 'Medusa Forms/Controlled Input', - component: ControlledInput, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -const ControlledInputWithHookForm = () => { - const form = useForm({ - defaultValues: { - username: '', - }, - }); - - return ( - -
- -
-
- ); -}; - -export const WithReactHookForm: Story = { - args: { - name: 'username', - label: 'Username', - placeholder: 'Enter your username', - }, - render: () => , -}; diff --git a/apps/docs/src/medusa-forms/ControlledSelect.stories.tsx b/apps/docs/src/medusa-forms/ControlledSelect.stories.tsx deleted file mode 100644 index 6f0cd935..00000000 --- a/apps/docs/src/medusa-forms/ControlledSelect.stories.tsx +++ /dev/null @@ -1,482 +0,0 @@ -import { ControlledSelect } from '@lambdacurry/medusa-forms/controlled/ControlledSelect'; -import { Button } from '@lambdacurry/medusa-forms/ui/Button'; -import { Select } from '@lambdacurry/medusa-forms/ui/Select'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { useEffect, useState } from 'react'; -import { FormProvider, useForm } from 'react-hook-form'; - -const meta = { - title: 'Medusa Forms/Controlled Select', - component: ControlledSelect, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// Sample options for stories -const countryOptions = [ - { label: 'United States', value: 'us' }, - { label: 'Canada', value: 'ca' }, - { label: 'United Kingdom', value: 'uk' }, - { label: 'Germany', value: 'de' }, - { label: 'France', value: 'fr' }, - { label: 'Japan', value: 'jp' }, - { label: 'Australia', value: 'au' }, -]; - -const categoryOptions = [ - { label: 'Electronics', value: 'electronics' }, - { label: 'Clothing', value: 'clothing' }, - { label: 'Books', value: 'books' }, - { label: 'Home & Garden', value: 'home-garden' }, - { label: 'Sports', value: 'sports' }, -]; - -// 1. Basic Single Select -export const BasicSingleSelect: Story = { - args: { - name: 'country', - label: 'Country', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - country: '', - }, - }); - - return ( - -
- -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 2. Single Select with Default Value -export const WithDefaultValue: Story = { - args: { - name: 'country', - label: 'Country (with default)', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - country: 'us', - }, - }); - - return ( - -
- -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 3. Required Field Validation -export const SelectRequiredValidation: Story = { - args: { - name: 'requiredCountry', - label: 'Country (Required)', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - requiredCountry: '', - }, - }); - - const onSubmit = (data: unknown) => { - alert(`Form submitted with: ${JSON.stringify(data)}`); - }; - - return ( - -
- -
- - {form.formState.errors.requiredCountry && ( -
{form.formState.errors.requiredCountry.message}
- )} -
-
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
- -
- ); - }, -}; - -// 4. Loading States -export const LoadingState: Story = { - args: { - name: 'country', - label: 'Country (Loading State)', - options: countryOptions, - }, - render: () => { - const [isLoading, setIsLoading] = useState(false); - const form = useForm({ - defaultValues: { - country: '', - }, - }); - - const toggleLoading = () => { - setIsLoading(!isLoading); - }; - - return ( - -
- -
- -
-
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
- Loading: {isLoading.toString()} -
-
-
- ); - }, -}; - -// Plan options with custom rendering data -const planOptions = [ - { - value: 'premium', - label: 'Premium Plan', - icon: '⭐', - iconColor: 'text-yellow-500', - price: '$29/mo', - }, - { - value: 'standard', - label: 'Standard Plan', - icon: '💎', - iconColor: 'text-blue-500', - price: '$19/mo', - }, - { - value: 'basic', - label: 'Basic Plan', - icon: '🌱', - iconColor: 'text-green-500', - price: '$9/mo', - }, -] as const; - -// Reusable component for plan option rendering -const PlanOption = ({ - icon, - iconColor, - label, - price, -}: { icon: string; iconColor: string; label: string; price: string }) => ( -
- {icon} - {label} - ({price}) -
-); - -// 5. Custom Option Rendering (using children) -export const CustomOptionRendering: Story = { - args: { - name: 'customSelect', - label: 'Custom Options', - options: planOptions.map(({ value, label }) => ({ value, label })), - }, - render: () => { - const form = useForm({ - defaultValues: { - customSelect: '', - }, - }); - - const currentValue = form.watch('customSelect'); - const selectedPlan = planOptions.find((plan) => plan.value === currentValue); - - return ( - -
- - - - {selectedPlan ? ( - - ) : ( - Select a plan... - )} - - - - {planOptions.map((plan) => ( - - - - ))} - - -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 6. Disabled State -export const SelectDisabledState: Story = { - args: { - name: 'disabledSelect', - label: 'Disabled Select', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - disabledSelect: 'us', - }, - }); - - return ( - -
- -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 7. Error State -export const SelectErrorState: Story = { - args: { - name: 'errorSelect', - label: 'Select with Error', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - errorSelect: '', - }, - }); - - // Manually set an error for demonstration - use useEffect to avoid infinite re-renders - useEffect(() => { - form.setError('errorSelect', { - type: 'manual', - message: 'This field has an error', - }); - }, [form]); - - return ( - -
- - {form.formState.errors.errorSelect && ( -
{form.formState.errors.errorSelect.message}
- )} -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 8. Small Size Variant -export const SmallSize: Story = { - args: { - name: 'smallSelect', - label: 'Small Size Select', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - smallSelect: '', - }, - }); - - return ( - -
- -
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; - -// 9. Complex Form Integration -export const ComplexFormIntegration: Story = { - args: { - name: 'country', - label: 'Country', - options: countryOptions, - }, - render: () => { - const form = useForm({ - defaultValues: { - country: '', - category: '', - plan: '', - priority: '', - }, - }); - - const onSubmit = (data: unknown) => { - alert(`Complete form submitted: ${JSON.stringify(data, null, 2)}`); - }; - - return ( - -
- - - - - - - - -
- - - -
- -
- Form Values: -
{JSON.stringify(form.watch(), null, 2)}
-
- -
- Form Errors: -
{JSON.stringify(form.formState.errors, null, 2)}
-
- -
- ); - }, -}; - -// 10. Interactive Demo with onChange Handler -export const InteractiveDemo: Story = { - args: { - name: 'interactiveSelect', - label: 'Interactive Select', - options: countryOptions, - }, - render: () => { - const [selectedValue, setSelectedValue] = useState(''); - const form = useForm({ - defaultValues: { - interactiveSelect: '', - }, - }); - - const handleSelectChange = (value: unknown) => { - setSelectedValue(value as string); - console.log('Select value changed:', value); - }; - - return ( - -
- -
- External State Value: {selectedValue || 'None'} -
-
- Form Value: {JSON.stringify(form.watch(), null, 2)} -
-
-
- ); - }, -}; diff --git a/apps/docs/src/medusa-forms/ControlledTextArea.stories.tsx b/apps/docs/src/medusa-forms/ControlledTextArea.stories.tsx deleted file mode 100644 index a4282e25..00000000 --- a/apps/docs/src/medusa-forms/ControlledTextArea.stories.tsx +++ /dev/null @@ -1,413 +0,0 @@ -import { zodResolver } from '@hookform/resolvers/zod'; -import { ControlledInput } from '@lambdacurry/medusa-forms/controlled/ControlledInput'; -import { ControlledTextArea } from '@lambdacurry/medusa-forms/controlled/ControlledTextArea'; -import { Button } from '@medusajs/ui'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { FormProvider, useForm } from 'react-hook-form'; -import { z } from 'zod'; - -const meta = { - title: 'Medusa Forms/Controlled Text Area', - component: ControlledTextArea, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// Basic Usage Story -const BasicUsageForm = () => { - const form = useForm({ - defaultValues: { - description: '', - }, - }); - - return ( - -
- -
-
- ); -}; - -export const BasicUsage: Story = { - args: { - name: 'description', - label: 'Description', - placeholder: 'Enter your description here...', - rows: 4, - }, - render: () => , - parameters: { - docs: { - description: { - story: 'A basic textarea with react-hook-form integration for multi-line text input.', - }, - }, - }, -}; - -// Character Limits Story -const CharacterLimitsSchema = z.object({ - bio: z.string().max(150, 'Bio must be 150 characters or less'), -}); - -const CharacterLimitsForm = () => { - const form = useForm({ - resolver: zodResolver(CharacterLimitsSchema), - defaultValues: { - bio: '', - }, - }); - - const bioValue = form.watch('bio'); - const characterCount = bioValue?.length || 0; - const maxLength = 150; - - return ( - -
- -
- {characterCount}/{maxLength} characters -
-
-
- ); -}; - -export const CharacterLimits: Story = { - args: { - name: 'bio', - label: 'Bio', - placeholder: 'Tell us about yourself...', - rows: 4, - maxLength: 150, - }, - render: () => , - parameters: { - docs: { - description: { - story: 'Textarea with character count validation, counter display, and limit enforcement.', - }, - }, - }, -}; - -// Required Field Validation Story -const RequiredFieldSchema = z.object({ - feedback: z.string().min(1, 'Feedback is required').min(10, 'Feedback must be at least 10 characters'), -}); - -const RequiredFieldForm = () => { - const form = useForm({ - resolver: zodResolver(RequiredFieldSchema), - defaultValues: { - feedback: '', - }, - }); - - const onSubmit = (data: unknown) => { - console.log('Form submitted:', data); - }; - - return ( - -
- - - -
- ); -}; - -export const RequiredFieldValidation: Story = { - args: { - name: 'feedback', - label: 'Feedback', - placeholder: 'Please provide your feedback...', - rows: 5, - }, - render: () => , - parameters: { - docs: { - description: { - story: 'Required field validation with error state display and custom validation messages.', - }, - }, - }, -}; - -// Auto-resize Functionality Story -const AutoResizeForm = () => { - const form = useForm({ - defaultValues: { - content: '', - }, - }); - - return ( - -
- { - const target = e.target as HTMLTextAreaElement; - target.style.height = 'auto'; - target.style.height = `${Math.min(target.scrollHeight, 200)}px`; - }} - /> -
- This textarea automatically adjusts its height based on content (min: 60px, max: 200px) -
-
-
- ); -}; - -export const AutoResizeFunctionality: Story = { - args: { - name: 'content', - label: 'Auto-resize Content', - placeholder: 'Start typing and watch the textarea grow...', - rows: 2, - }, - render: () => , - parameters: { - docs: { - description: { - story: 'Dynamic height adjustment with content-based resizing and min/max height constraints.', - }, - }, - }, -}; - -// Validation Error States Story -const ValidationErrorSchema = z.object({ - message: z - .string() - .min(1, 'Message is required') - .min(20, 'Message must be at least 20 characters') - .max(500, 'Message must be less than 500 characters') - .refine((val) => !val.includes('spam'), 'Message cannot contain spam'), -}); - -const ValidationErrorForm = () => { - const form = useForm({ - resolver: zodResolver(ValidationErrorSchema), - defaultValues: { - message: '', - }, - mode: 'onChange', // Validate on change for immediate feedback - }); - - const onSubmit = (data: unknown) => { - console.log('Form submitted:', data); - }; - - const hasError = !!form.formState.errors.message; - const messageValue = form.watch('message'); - - return ( - -
-
- !value.includes('spam') || 'Message cannot contain spam', - }} - /> -
-
- {form.formState.errors.message && ( - {form.formState.errors.message.message} - )} -
-
{messageValue?.length || 0}/500
-
-
- -
-

- Validation Rules: -

-
    -
  • Required field
  • -
  • Minimum 20 characters
  • -
  • Maximum 500 characters
  • -
  • Cannot contain the word "spam"
  • -
-
- - -
-
- ); -}; - -export const ValidationErrorStates: Story = { - args: { - name: 'message', - label: 'Message', - placeholder: 'Enter your message (20-500 characters, no spam)...', - rows: 6, - }, - render: () => , - parameters: { - docs: { - description: { - story: 'Various error scenarios with error message display and field highlighting.', - }, - }, - }, -}; - -// Comprehensive Form Example -const ComprehensiveSchema = z.object({ - title: z.string().min(1, 'Title is required').max(100, 'Title must be less than 100 characters'), - description: z.string().min(1, 'Description is required').min(50, 'Description must be at least 50 characters'), - notes: z.string().optional(), -}); - -const ComprehensiveForm = () => { - const form = useForm({ - resolver: zodResolver(ComprehensiveSchema), - defaultValues: { - title: '', - description: '', - notes: '', - }, - mode: 'onChange', - }); - - const onSubmit = (data: unknown) => { - console.log('Comprehensive form submitted:', data); - }; - - return ( - -
-
- -
- -
- -
- -
- -
- -
- - -
- -
- Form Values: -
{JSON.stringify(form.watch(), null, 2)}
-
- - {form.formState.isSubmitted && form.formState.isValid && ( -
- Form submitted successfully! Check the console for the data. -
- )} -
-
- ); -}; - -export const ComprehensiveExample: Story = { - args: { - name: 'title', - label: 'Title', - placeholder: 'Enter a title...', - }, - render: () => , - parameters: { - docs: { - description: { - story: - 'A comprehensive form example showing multiple ControlledTextArea components with different validation rules and states.', - }, - }, - }, -}; diff --git a/apps/docs/src/medusa-forms/FormIntegrationExamples.stories.tsx b/apps/docs/src/medusa-forms/FormIntegrationExamples.stories.tsx deleted file mode 100644 index f167bd47..00000000 --- a/apps/docs/src/medusa-forms/FormIntegrationExamples.stories.tsx +++ /dev/null @@ -1,673 +0,0 @@ -import { ControlledCheckbox } from '@lambdacurry/medusa-forms/controlled/ControlledCheckbox'; -import { ControlledCurrencyInput } from '@lambdacurry/medusa-forms/controlled/ControlledCurrencyInput'; -import { ControlledDatePicker } from '@lambdacurry/medusa-forms/controlled/ControlledDatePicker'; -import { ControlledInput } from '@lambdacurry/medusa-forms/controlled/ControlledInput'; -import { ControlledSelect } from '@lambdacurry/medusa-forms/controlled/ControlledSelect'; -import { ControlledTextArea } from '@lambdacurry/medusa-forms/controlled/ControlledTextArea'; -import { Button } from '@medusajs/ui'; -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { useState } from 'react'; -import { FormProvider, useForm } from 'react-hook-form'; - -const meta = { - title: 'Medusa Forms/Form Integration Examples', - component: () => null, // No single component - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// Registration Form Types -interface RegistrationFormData { - firstName: string; - lastName: string; - email: string; - password: string; - confirmPassword: string; - dateOfBirth: Date | null; - country: string; - agreeToTerms: boolean; - subscribeNewsletter: boolean; -} - -// Product Creation Form Types -interface ProductFormData { - name: string; - description: string; - price: string; - category: string; - sku: string; - weight: string; - dimensions: string; - launchDate: Date | null; - isActive: boolean; - isFeatured: boolean; - tags: string; -} - -// Stories -export const CompleteRegistrationFormExample: Story = { - name: 'Complete Registration Form', - render: () => { - const [isSubmitting, setIsSubmitting] = useState(false); - const [submitResult, setSubmitResult] = useState(null); - - const form = useForm({ - defaultValues: { - firstName: '', - lastName: '', - email: '', - password: '', - confirmPassword: '', - dateOfBirth: null, - country: '', - agreeToTerms: false, - subscribeNewsletter: false, - }, - mode: 'onSubmit', - }); - - const { - handleSubmit, - watch, - formState: { errors, isValid }, - } = form; - const password = watch('password'); - - const onSubmit = async (data: RegistrationFormData) => { - setIsSubmitting(true); - setSubmitResult(null); - - // Simulate API call - await new Promise((resolve) => setTimeout(resolve, 2000)); - - setIsSubmitting(false); - setSubmitResult(`Registration successful for ${data.firstName} ${data.lastName}!`); - console.log('Registration data:', data); - }; - - const countryOptions = [ - { label: 'United States', value: 'US' }, - { label: 'Canada', value: 'CA' }, - { label: 'United Kingdom', value: 'UK' }, - { label: 'Germany', value: 'DE' }, - { label: 'France', value: 'FR' }, - { label: 'Australia', value: 'AU' }, - ]; - - return ( - -
-
-

Create Account

-

Join us today and get started

-
- -
- {/* Personal Information */} -
-

Personal Information

- -
- - - -
- - - - { - if (!value) return 'Date of birth is required'; - const age = new Date().getFullYear() - new Date(value).getFullYear(); - return age >= 18 || 'You must be at least 18 years old'; - }, - }} - /> - - -
- - {/* Account Security */} -
-

Account Security

- - - - value === password || 'Passwords do not match', - }} - /> -
- - {/* Preferences */} -
-

Preferences

- - - - -
- - {/* Submit Section */} -
- - - {submitResult && ( -
- {submitResult} -
- )} - - {Object.keys(errors).length > 0 && ( -
- Please fix the errors above before submitting. -
- )} -
-
-
-
- ); - }, - parameters: { - docs: { - description: { - story: ` -A comprehensive registration form demonstrating multiple controlled components working together: - -**Features:** -- **Form Validation**: Real-time validation with react-hook-form -- **Multiple Input Types**: Text inputs, email, password, date picker, select, checkboxes -- **Complex Validation Rules**: Password strength, email format, age verification, password confirmation -- **Error Handling**: Individual field errors and form-level error summary -- **Submit States**: Loading states and success feedback -- **Responsive Layout**: Grid layouts and proper spacing - -**Components Used:** -- ControlledInput (text, email, password) -- ControlledDatePicker (date of birth with age validation) -- ControlledSelect (country selection) -- ControlledCheckbox (terms agreement, newsletter subscription) - -**Validation Scenarios:** -- Required fields -- Email format validation -- Password strength requirements -- Password confirmation matching -- Age verification (18+) -- Terms agreement requirement - `, - }, - }, - }, -}; - -export const ProductCreationFormExample: Story = { - name: 'Product Creation Form', - render: () => { - const [isSubmitting, setIsSubmitting] = useState(false); - const [submitResult, setSubmitResult] = useState(null); - - const form = useForm({ - defaultValues: { - name: '', - description: '', - price: '', - category: '', - sku: '', - weight: '', - dimensions: '', - launchDate: null, - isActive: true, - isFeatured: false, - tags: '', - }, - mode: 'onSubmit', - }); - - const { - handleSubmit, - formState: { errors, isValid }, - } = form; - - const onSubmit = async (data: ProductFormData) => { - setIsSubmitting(true); - setSubmitResult(null); - - // Simulate API call - await new Promise((resolve) => setTimeout(resolve, 2000)); - - setIsSubmitting(false); - setSubmitResult(`Product "${data.name}" created successfully!`); - console.log('Product data:', data); - }; - - const categoryOptions = [ - { label: 'Electronics', value: 'electronics' }, - { label: 'Clothing', value: 'clothing' }, - { label: 'Home & Garden', value: 'home-garden' }, - { label: 'Sports & Outdoors', value: 'sports-outdoors' }, - { label: 'Books', value: 'books' }, - { label: 'Toys & Games', value: 'toys-games' }, - ]; - - return ( - -
-
-

Create New Product

-

Add a new product to your catalog

-
- -
- {/* Basic Information */} -
-

Basic Information

- - - - - -
- - - -
-
- - {/* Pricing & Inventory */} -
-

Pricing & Inventory

- -
- { - const numValue = Number.parseFloat(value); - return (numValue > 0 && numValue <= 10000) || 'Price must be between $0.01 and $10,000'; - }, - }} - /> - - -
- - -
- - {/* Launch & Visibility */} -
-

Launch & Visibility

- - { - if (!value) return 'Launch date is required'; - const today = new Date(); - today.setHours(0, 0, 0, 0); - return new Date(value) >= today || 'Launch date cannot be in the past'; - }, - }} - /> - -
- - - -
- - { - if (!value) return true; // Tags are optional - const tags = value.split(',').map((tag) => tag.trim()); - return tags.length <= 10 || 'Maximum 10 tags allowed'; - }, - }} - /> -
- - {/* Submit Section */} -
-
- - - -
- - {submitResult && ( -
- {submitResult} -
- )} - - {Object.keys(errors).length > 0 && ( -
-

Please fix the following errors:

-
    - {Object.entries(errors).map(([field, error]) => ( -
  • - {field}: {error?.message} -
  • - ))} -
-
- )} -
-
-
-
- ); - }, - parameters: { - docs: { - description: { - story: ` -A comprehensive product creation form showcasing all controlled components in a real-world e-commerce context: - -**Features:** -- **Advanced Validation**: Complex business rules and data validation -- **Multiple Data Types**: Text, numbers, currency, dates, boolean flags -- **Rich Text Input**: Multi-line descriptions with character limits -- **Currency Handling**: Proper currency input with validation -- **Date Constraints**: Future date validation for launch dates -- **Dynamic Feedback**: Real-time validation and error reporting -- **Form Reset**: Ability to clear and reset the entire form - -**Components Used:** -- ControlledInput (text, number inputs with various validation rules) -- ControlledTextArea (product description, tags) -- ControlledCurrencyInput (pricing with currency formatting) -- ControlledSelect (category selection) -- ControlledDatePicker (launch date with future date validation) -- ControlledCheckbox (product status flags) - -**Complex Validation Examples:** -- SKU format validation (uppercase, numbers, hyphens only) -- Price range validation ($0.01 - $10,000) -- Dimensions format validation (L x W x H pattern) -- Future date validation for launch dates -- Tag count limits (max 10 tags) -- Character limits for descriptions - `, - }, - }, - }, -}; - -export const FormValidationShowcase: Story = { - name: 'Form Validation Showcase', - render: () => { - const form = useForm({ - defaultValues: { - requiredField: '', - emailField: '', - numberField: '', - dateField: null, - selectField: '', - checkboxField: false, - }, - mode: 'onSubmit', - }); - - return ( - -
-

Validation Examples

-

Try interacting with these fields to see validation in action

- - - - - - { - const num = Number.parseFloat(value); - return (num >= 10 && num <= 1000) || 'Amount must be between $10 and $1,000'; - }, - }} - /> - - { - if (!value) return 'Date is required'; - return new Date(value) > new Date() || 'Date must be in the future'; - }, - }} - /> - - - - - -
- -
-
-
- ); - }, - parameters: { - docs: { - description: { - story: ` -A focused demonstration of various validation scenarios across all controlled components: - -**Validation Types Demonstrated:** -- **Required Fields**: Basic required field validation -- **Format Validation**: Email pattern matching -- **Range Validation**: Currency amounts with min/max limits -- **Date Validation**: Future date constraints -- **Selection Validation**: Required dropdown selections -- **Boolean Validation**: Required checkbox agreements - -This example shows how each component handles validation states and error messages consistently. - `, - }, - }, - }, -}; diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 1d67de75..746bf907 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -5,9 +5,7 @@ "moduleResolution": "bundler", "paths": { "@lambdacurry/forms/*": ["../../packages/components/src/*"], - "@lambdacurry/forms/lib/*": ["../../packages/components/lib/*"], - "@lambdacurry/medusa-forms/*": ["../../packages/medusa-forms/src/*"], - "@lambdacurry/medusa-forms/lib/*": ["../../packages/medusa-forms/lib/*"] + "@lambdacurry/forms/lib/*": ["../../packages/components/lib/*"] } }, "include": ["lib", "src"], diff --git a/apps/docs/vite.config.mjs b/apps/docs/vite.config.mjs index ee3f022f..f713d151 100644 --- a/apps/docs/vite.config.mjs +++ b/apps/docs/vite.config.mjs @@ -12,8 +12,6 @@ export default defineConfig({ '@/lib/utils': path.resolve(__dirname, '../../packages/components/lib/utils'), '@lambdacurry/forms': path.resolve(__dirname, '../../packages/components/src'), '@lambdacurry/forms/lib': path.resolve(__dirname, '../../packages/components/lib'), - '@lambdacurry/medusa-forms': path.resolve(__dirname, '../../packages/medusa-forms/src'), - '@lambdacurry/medusa-forms/lib': path.resolve(__dirname, '../../packages/medusa-forms/lib'), }, }, plugins: [tailwindcss()], diff --git a/packages/medusa-forms/package.json b/packages/medusa-forms/package.json deleted file mode 100644 index 0a08a817..00000000 --- a/packages/medusa-forms/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "@lambdacurry/medusa-forms", - "version": "0.2.8", - "main": "./dist/cjs/index.cjs", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "files": [ - "dist" - ], - "exports": { - ".": { - "import": { - "types": "./dist/types/index.d.ts", - "default": "./dist/esm/index.js" - }, - "require": { - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.cjs" - } - }, - "./controlled": { - "import": { - "types": "./dist/types/controlled/index.d.ts", - "default": "./dist/esm/controlled/index.js" - }, - "require": { - "types": "./dist/types/controlled/index.d.ts", - "default": "./dist/cjs/controlled/index.cjs" - } - }, - "./ui": { - "import": { - "types": "./dist/types/ui/index.d.ts", - "default": "./dist/esm/ui/index.js" - }, - "require": { - "types": "./dist/types/ui/index.d.ts", - "default": "./dist/cjs/ui/index.cjs" - } - } - }, - "scripts": { - "prepublishOnly": "yarn run build", - "build": "vite build", - "lint": "biome check .", - "lint:fix": "biome check --apply .", - "type-check": "tsc --noEmit" - }, - "peerDependencies": { - "@medusajs/ui": "^4.0.0", - "react": "^18.3.0 || ^19.0.0", - "react-hook-form": "^7.49.0" - }, - "dependencies": { - "@hookform/error-message": "^2.0.1" - }, - "devDependencies": { - "@medusajs/ui": "^4.0.0", - "@types/glob": "^8.1.0", - "@types/react": "^19.0.0", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "@vitejs/plugin-react": "^4.3.4", - "autoprefixer": "^10.4.20", - "glob": "^11.0.0", - "react": "^19.0.0", - "react-hook-form": "^7.49.0", - "tailwindcss": "^4.0.0", - "typescript": "^5.7.2", - "vite": "^5.4.11", - "vite-plugin-dts": "^4.4.0", - "vite-tsconfig-paths": "^5.1.4" - } -} diff --git a/packages/medusa-forms/src/controlled/ControlledCheckbox.tsx b/packages/medusa-forms/src/controlled/ControlledCheckbox.tsx deleted file mode 100644 index aeee7ad1..00000000 --- a/packages/medusa-forms/src/controlled/ControlledCheckbox.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { - Controller, - type ControllerProps, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { FieldCheckbox, type FieldCheckboxProps } from '../ui/FieldCheckbox'; - -export type ControlledCheckboxProps = Omit & - Omit & { - name: Path; - rules?: Omit>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>; - }; - -export const ControlledCheckbox = ({ - name, - rules, - onChange, - ...props -}: ControlledCheckboxProps) => { - const { - control, - formState: { errors }, - } = useFormContext(); - - return ( - >, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>} - render={({ field }) => ( - { - if (onChange) onChange(checked); - field.onChange(checked); - }} - /> - )} - /> - ); -}; diff --git a/packages/medusa-forms/src/controlled/ControlledCurrencyInput.tsx b/packages/medusa-forms/src/controlled/ControlledCurrencyInput.tsx deleted file mode 100644 index 51317445..00000000 --- a/packages/medusa-forms/src/controlled/ControlledCurrencyInput.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import type * as React from 'react'; -import { - Controller, - type ControllerProps, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { CurrencyInput, type CurrencyInputProps } from '../ui/CurrencyInput'; - -export type ControlledCurrencyInputProps = CurrencyInputProps & - Omit & { - name: Path; - }; - -export const ControlledCurrencyInput = ({ - name, - rules, - ...props -}: ControlledCurrencyInputProps) => { - const { control } = useFormContext(); - - return ( - - control={control} - name={name} - rules={rules as Omit>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>} - render={({ field }) => { - return ( - ) => { - field.onChange(e.target.value.replace(/[^0-9.-]+/g, '')); - }} - /> - ); - }} - /> - ); -}; diff --git a/packages/medusa-forms/src/controlled/ControlledDatePicker.tsx b/packages/medusa-forms/src/controlled/ControlledDatePicker.tsx deleted file mode 100644 index 4a10e3ba..00000000 --- a/packages/medusa-forms/src/controlled/ControlledDatePicker.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { - Controller, - type ControllerProps, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { DatePickerInput, type DatePickerProps } from '../ui/DatePicker'; - -export type ControlledDatePickerProps = DatePickerProps & - Omit & { - name: Path; - }; - -export const ControlledDatePicker = ({ - name, - rules, - ...props -}: ControlledDatePickerProps) => { - const { control } = useFormContext(); - return ( - - control={control} - name={name} - rules={rules as Omit>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>} - render={({ field }) => } - /> - ); -}; diff --git a/packages/medusa-forms/src/controlled/ControlledInput.tsx b/packages/medusa-forms/src/controlled/ControlledInput.tsx deleted file mode 100644 index 6cd60240..00000000 --- a/packages/medusa-forms/src/controlled/ControlledInput.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import type { ComponentProps } from 'react'; -import { - Controller, - type ControllerProps, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { Input, type InputProps } from '../ui/Input'; - -export type ControlledInputProps = InputProps & - Omit & { - name: Path; - rules?: Omit>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>; - } & ComponentProps & - Omit, 'render'>; - -export const ControlledInput = ({ - name, - rules, - onChange, - ...props -}: ControlledInputProps) => { - const { - control, - formState: { errors }, - } = useFormContext(); - - return ( - >, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>} - render={({ field }) => ( - { - if (onChange) { - onChange(evt); - } - field.onChange(evt); - }} - /> - )} - /> - ); -}; diff --git a/packages/medusa-forms/src/controlled/ControlledSelect.tsx b/packages/medusa-forms/src/controlled/ControlledSelect.tsx deleted file mode 100644 index a3897d84..00000000 --- a/packages/medusa-forms/src/controlled/ControlledSelect.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import type * as React from 'react'; -import { - Controller, - type ControllerProps, - type FieldPathValue, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { Select, type SelectProps } from '../ui/Select'; - -export type ControlledSelectProps = SelectProps & - Omit & { - name: Path; - onBlur?: () => void; - onChange?: (value: unknown) => void; - } & ( - | { - options: { label: React.ReactNode; value: FieldPathValue> }[]; - children?: never; - } - | { - options?: never; - children: React.ReactNode; - } - ); - -export const ControlledSelect = ({ - name, - rules, - children, - options, - onChange, - onBlur, - ...props -}: ControlledSelectProps) => { - const { control } = useFormContext(); - return ( - - control={control} - name={name} - rules={rules as Omit>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'>} - render={({ field }) => { - const handleChange = (value: unknown) => { - if (typeof onChange === 'function') onChange(value); - field.onChange(value); - }; - - if (options) { - return ( - - ); - } - - return ; - }} - /> - ); -}; diff --git a/packages/medusa-forms/src/controlled/ControlledTextArea.tsx b/packages/medusa-forms/src/controlled/ControlledTextArea.tsx deleted file mode 100644 index 560c601d..00000000 --- a/packages/medusa-forms/src/controlled/ControlledTextArea.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import type * as React from 'react'; -import { - Controller, - type ControllerProps, - type FieldValues, - type Path, - type RegisterOptions, - useFormContext, -} from 'react-hook-form'; -import { TextArea, type TextAreaProps } from '../ui/TextArea'; - -export type ControlledTextAreaProps = TextAreaProps & - Omit & { - name: Path; - rules?: RegisterOptions>; - } & React.ComponentProps & - Omit, 'render'>; - -export const ControlledTextArea = ({ name, rules, ...props }: ControlledTextAreaProps) => { - const { control } = useFormContext(); - return ( - - control={control} - name={name} - rules={rules} - render={({ field }) =>