@stacksjs/components 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +477 -0
- package/dist/Accordion-x2gjedap.stx +108 -0
- package/dist/Audio-0fk6p9tn.stx +50 -0
- package/dist/Avatar-5m0v0s4x.stx +88 -0
- package/dist/Badge-ynes82vv.stx +70 -0
- package/dist/Breadcrumb-h9n427sk.stx +79 -0
- package/dist/Button-7xtrzn14.stx +89 -0
- package/dist/Calendar-egvx1pma.stx +232 -0
- package/dist/Card-r9w7vy1a.stx +74 -0
- package/dist/Checkbox-m8v46pmx.stx +92 -0
- package/dist/Checkout-vcnnr176.stx +39 -0
- package/dist/CodeBlock-mwex82cm.stx +57 -0
- package/dist/Combobox-npb08vkp.stx +13 -0
- package/dist/ComboboxButton-vcdyq4zw.stx +13 -0
- package/dist/ComboboxInput-c9d2p02m.stx +25 -0
- package/dist/ComboboxOption-7d0h9ash.stx +52 -0
- package/dist/ComboboxOptions-4dtqc0qa.stx +12 -0
- package/dist/CommandPalette-ah00bf8v.stx +39 -0
- package/dist/CommandPaletteItem-2yx0gvtj.stx +32 -0
- package/dist/DefaultPaymentMethod-emw5fg8s.stx +62 -0
- package/dist/Dialog-1w4rz7x0.stx +19 -0
- package/dist/DialogBackdrop-qbm3y5ab.stx +9 -0
- package/dist/DialogDescription-01w5j74b.stx +11 -0
- package/dist/DialogPanel-brsszrrs.stx +16 -0
- package/dist/DialogTitle-3rxhwg21.stx +11 -0
- package/dist/Drawer-yfaz8q7f.stx +137 -0
- package/dist/Dropdown-ng7nx556.stx +24 -0
- package/dist/DropdownButton-vc4zpyrb.stx +23 -0
- package/dist/DropdownItem-z491y23c.stx +43 -0
- package/dist/DropdownItems-7ykf29sj.stx +18 -0
- package/dist/EmailInput-bfshpj92.stx +41 -0
- package/dist/Footer-xdaf02nr.stx +66 -0
- package/dist/Form-z4f7w6r1.stx +209 -0
- package/dist/Hero-9vvp7pxf.stx +25 -0
- package/dist/Image-ktk0451c.stx +197 -0
- package/dist/Installation-33bj4rm7.stx +39 -0
- package/dist/Listbox-xcejcmyc.stx +14 -0
- package/dist/ListboxButton-nx5kmw19.stx +17 -0
- package/dist/ListboxLabel-aky8a73n.stx +11 -0
- package/dist/ListboxOption-6h4hsdz5.stx +57 -0
- package/dist/ListboxOptions-2sacdtm5.stx +16 -0
- package/dist/Login-s2jkvd9y.stx +163 -0
- package/dist/Navigator-tqqdgdkw.stx +138 -0
- package/dist/Notification-sry8egea.stx +71 -0
- package/dist/NumberInput-zm93ddfw.stx +138 -0
- package/dist/Pagination-yza9v4qw.stx +183 -0
- package/dist/PasswordInput-4xnndp5y.stx +155 -0
- package/dist/PaymentMethods-jxba6kek.stx +113 -0
- package/dist/Popover-scbqatjq.stx +24 -0
- package/dist/PopoverButton-rbxhzj4k.stx +23 -0
- package/dist/PopoverPanel-9ng1rm6e.stx +23 -0
- package/dist/Portal-j111yvqp.stx +74 -0
- package/dist/Progress-gbmw3akr.stx +142 -0
- package/dist/Radio-1n9qamv1.stx +81 -0
- package/dist/RadioGroup-12dw2vhk.stx +13 -0
- package/dist/RadioGroupDescription-bjm3mdht.stx +11 -0
- package/dist/RadioGroupLabel-aky8a73n.stx +11 -0
- package/dist/RadioGroupOption-9pcxgwmd.stx +51 -0
- package/dist/SearchInput-g240e2nq.stx +63 -0
- package/dist/Select-p9f94b20.stx +89 -0
- package/dist/Sidebar-gwxw8q38.stx +288 -0
- package/dist/SidebarFooter-887kxret.stx +95 -0
- package/dist/SidebarHeader-qjeyx0hv.stx +100 -0
- package/dist/SidebarItem-4dpwtmb4.stx +118 -0
- package/dist/SidebarSection-kh92fk4m.stx +108 -0
- package/dist/Signup-3nxq5zag.stx +161 -0
- package/dist/Skeleton-g0nx1njm.stx +48 -0
- package/dist/Spinner-w4zj58xp.stx +109 -0
- package/dist/Stepper-rwc5actp.stx +17 -0
- package/dist/StepperStep-h0k657nm.stx +53 -0
- package/dist/SubscriptionCheckout-4cbxdg7w.stx +353 -0
- package/dist/Switch-kjq8qd2p.stx +74 -0
- package/dist/Table-59j9qwp0.stx +14 -0
- package/dist/TableBody-reka2gwv.stx +10 -0
- package/dist/TableCell-j7nh4sgr.stx +10 -0
- package/dist/TableHead-ecbrwpqm.stx +10 -0
- package/dist/TableHeader-jn2shwsv.stx +13 -0
- package/dist/TableRow-xz8rrxhc.stx +11 -0
- package/dist/Tabs-kb6ex6m7.stx +145 -0
- package/dist/Teleport-819cg9zm.stx +101 -0
- package/dist/TextInput-zx9kgr79.stx +146 -0
- package/dist/Textarea-5xvmrb0z.stx +119 -0
- package/dist/Tooltip-5ehqsy49.stx +76 -0
- package/dist/Transition-2j39s044.stx +174 -0
- package/dist/TwoFactorChallenge-2q4gg89m.stx +125 -0
- package/dist/Video-6aq4shh4.stx +45 -0
- package/dist/VirtualList-weh5qtm1.stx +83 -0
- package/dist/VirtualTable-59a1eskc.stx +113 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/composables/index.d.ts +4 -0
- package/dist/composables/index.js +3 -0
- package/dist/composables/useCopyCode.d.ts +19 -0
- package/dist/composables/useDarkMode.d.ts +25 -0
- package/dist/composables/useSEO.d.ts +36 -0
- package/dist/composables/utilities/index.d.ts +5 -0
- package/dist/composables/utilities/useClickOutside.d.ts +28 -0
- package/dist/composables/utilities/useFocusTrap.d.ts +34 -0
- package/dist/composables/utilities/useKeyboard.d.ts +55 -0
- package/dist/composables/utilities/useLocalStorage.d.ts +33 -0
- package/dist/composables/utilities/useMediaQuery.d.ts +64 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +19 -0
- package/dist/ui/accordion/index.d.ts +12 -0
- package/dist/ui/audio/index.d.ts +12 -0
- package/dist/ui/auth/index.d.ts +29 -0
- package/dist/ui/avatar/index.d.ts +11 -0
- package/dist/ui/badge/index.d.ts +9 -0
- package/dist/ui/breadcrumb/index.d.ts +13 -0
- package/dist/ui/button/index.d.ts +45 -0
- package/dist/ui/calendar/index.d.ts +13 -0
- package/dist/ui/card/index.d.ts +12 -0
- package/dist/ui/checkbox/index.d.ts +15 -0
- package/dist/ui/combobox/index.d.ts +35 -0
- package/dist/ui/command-palette/index.d.ts +13 -0
- package/dist/ui/dialog/index.d.ts +27 -0
- package/dist/ui/drawer/index.d.ts +8 -0
- package/dist/ui/dropdown/index.d.ts +25 -0
- package/dist/ui/form/index.d.ts +48 -0
- package/dist/ui/image/index.d.ts +21 -0
- package/dist/ui/input/index.d.ts +73 -0
- package/dist/ui/listbox/index.d.ts +34 -0
- package/dist/ui/navigator/index.d.ts +18 -0
- package/dist/ui/notification/index.d.ts +11 -0
- package/dist/ui/pagination/index.d.ts +10 -0
- package/dist/ui/payment/index.d.ts +53 -0
- package/dist/ui/popover/index.d.ts +19 -0
- package/dist/ui/portal/index.d.ts +5 -0
- package/dist/ui/progress/index.d.ts +11 -0
- package/dist/ui/radio/index.d.ts +14 -0
- package/dist/ui/radio-group/index.d.ts +26 -0
- package/dist/ui/select/index.d.ts +19 -0
- package/dist/ui/sidebar/index.d.ts +129 -0
- package/dist/ui/skeleton/index.d.ts +10 -0
- package/dist/ui/spinner/index.d.ts +8 -0
- package/dist/ui/stepper/index.d.ts +17 -0
- package/dist/ui/storage/index.d.ts +40 -0
- package/dist/ui/switch/index.d.ts +9 -0
- package/dist/ui/table/index.d.ts +29 -0
- package/dist/ui/tabs/index.d.ts +14 -0
- package/dist/ui/teleport/index.d.ts +6 -0
- package/dist/ui/textarea/index.d.ts +19 -0
- package/dist/ui/tooltip/index.d.ts +9 -0
- package/dist/ui/transition/index.d.ts +24 -0
- package/dist/ui/video/index.d.ts +15 -0
- package/dist/ui/virtual-list/index.d.ts +9 -0
- package/dist/ui/virtual-table/index.d.ts +19 -0
- package/dist/utils/accessibility.d.ts +285 -0
- package/dist/utils/animation/easing.d.ts +112 -0
- package/dist/utils/animation/helpers.d.ts +119 -0
- package/dist/utils/animation/index.d.ts +3 -0
- package/dist/utils/animation/keyframes.d.ts +334 -0
- package/dist/utils/error-handling.d.ts +182 -0
- package/dist/utils/highlighter.d.ts +27 -0
- package/dist/utils/highlighter.js +2 -0
- package/dist/utils/i18n.d.ts +245 -0
- package/dist/utils/keep-alive.d.ts +171 -0
- package/dist/utils/lazy-loading.d.ts +174 -0
- package/dist/utils/prop-validation.d.ts +106 -0
- package/dist/utils/theme.d.ts +234 -0
- package/package.json +69 -0
- package/src/components/CodeBlock.stx +57 -0
- package/src/components/Footer.stx +66 -0
- package/src/components/Hero.stx +25 -0
- package/src/components/Installation.stx +39 -0
- package/src/components/index.ts +4 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/useCopyCode.ts +73 -0
- package/src/composables/useDarkMode.ts +100 -0
- package/src/composables/useSEO.ts +229 -0
- package/src/composables/utilities/index.ts +7 -0
- package/src/composables/utilities/useClickOutside.ts +72 -0
- package/src/composables/utilities/useFocusTrap.ts +159 -0
- package/src/composables/utilities/useKeyboard.ts +124 -0
- package/src/composables/utilities/useLocalStorage.ts +132 -0
- package/src/composables/utilities/useMediaQuery.ts +118 -0
- package/src/index.ts +99 -0
- package/src/stx.d.ts +4 -0
- package/src/ui/accordion/Accordion.stx +108 -0
- package/src/ui/accordion/index.ts +14 -0
- package/src/ui/audio/Audio.stx +50 -0
- package/src/ui/audio/README.md +42 -0
- package/src/ui/audio/index.ts +13 -0
- package/src/ui/auth/Login.stx +163 -0
- package/src/ui/auth/README.md +145 -0
- package/src/ui/auth/Signup.stx +161 -0
- package/src/ui/auth/TwoFactorChallenge.stx +125 -0
- package/src/ui/auth/index.ts +32 -0
- package/src/ui/avatar/Avatar.stx +88 -0
- package/src/ui/avatar/index.ts +12 -0
- package/src/ui/badge/Badge.stx +70 -0
- package/src/ui/badge/index.ts +10 -0
- package/src/ui/breadcrumb/Breadcrumb.stx +79 -0
- package/src/ui/breadcrumb/index.ts +15 -0
- package/src/ui/button/Button.stx +89 -0
- package/src/ui/button/README.md +100 -0
- package/src/ui/button/index.ts +85 -0
- package/src/ui/calendar/Calendar.stx +232 -0
- package/src/ui/calendar/README.md +254 -0
- package/src/ui/calendar/index.ts +14 -0
- package/src/ui/card/Card.stx +74 -0
- package/src/ui/card/index.ts +13 -0
- package/src/ui/checkbox/Checkbox.stx +92 -0
- package/src/ui/checkbox/index.ts +16 -0
- package/src/ui/combobox/Combobox.stx +13 -0
- package/src/ui/combobox/ComboboxButton.stx +13 -0
- package/src/ui/combobox/ComboboxInput.stx +25 -0
- package/src/ui/combobox/ComboboxOption.stx +52 -0
- package/src/ui/combobox/ComboboxOptions.stx +12 -0
- package/src/ui/combobox/README.md +154 -0
- package/src/ui/combobox/index.ts +40 -0
- package/src/ui/command-palette/CommandPalette.stx +39 -0
- package/src/ui/command-palette/CommandPaletteItem.stx +32 -0
- package/src/ui/command-palette/README.md +42 -0
- package/src/ui/command-palette/index.ts +15 -0
- package/src/ui/dialog/Dialog.stx +19 -0
- package/src/ui/dialog/DialogBackdrop.stx +9 -0
- package/src/ui/dialog/DialogDescription.stx +11 -0
- package/src/ui/dialog/DialogPanel.stx +16 -0
- package/src/ui/dialog/DialogTitle.stx +11 -0
- package/src/ui/dialog/README.md +133 -0
- package/src/ui/dialog/index.ts +32 -0
- package/src/ui/drawer/Drawer.stx +137 -0
- package/src/ui/drawer/README.md +110 -0
- package/src/ui/drawer/index.ts +9 -0
- package/src/ui/dropdown/Dropdown.stx +24 -0
- package/src/ui/dropdown/DropdownButton.stx +23 -0
- package/src/ui/dropdown/DropdownItem.stx +43 -0
- package/src/ui/dropdown/DropdownItems.stx +18 -0
- package/src/ui/dropdown/README.md +142 -0
- package/src/ui/dropdown/index.ts +29 -0
- package/src/ui/form/Form.stx +209 -0
- package/src/ui/form/index.ts +67 -0
- package/src/ui/heatmap/Heatmap.stx +315 -0
- package/src/ui/image/Image.stx +197 -0
- package/src/ui/image/README.md +171 -0
- package/src/ui/image/index.ts +22 -0
- package/src/ui/input/EmailInput.stx +41 -0
- package/src/ui/input/NumberInput.stx +138 -0
- package/src/ui/input/PasswordInput.stx +155 -0
- package/src/ui/input/SearchInput.stx +63 -0
- package/src/ui/input/TextInput.stx +146 -0
- package/src/ui/input/index.ts +180 -0
- package/src/ui/listbox/Listbox.stx +14 -0
- package/src/ui/listbox/ListboxButton.stx +17 -0
- package/src/ui/listbox/ListboxLabel.stx +11 -0
- package/src/ui/listbox/ListboxOption.stx +57 -0
- package/src/ui/listbox/ListboxOptions.stx +16 -0
- package/src/ui/listbox/README.md +143 -0
- package/src/ui/listbox/index.ts +39 -0
- package/src/ui/navigator/Navigator.stx +138 -0
- package/src/ui/navigator/README.md +352 -0
- package/src/ui/navigator/index.ts +20 -0
- package/src/ui/notification/Notification.stx +71 -0
- package/src/ui/notification/README.md +118 -0
- package/src/ui/notification/index.ts +12 -0
- package/src/ui/pagination/Pagination.stx +183 -0
- package/src/ui/pagination/index.ts +11 -0
- package/src/ui/payment/Checkout.stx +39 -0
- package/src/ui/payment/DefaultPaymentMethod.stx +62 -0
- package/src/ui/payment/PaymentMethods.stx +113 -0
- package/src/ui/payment/README.md +427 -0
- package/src/ui/payment/SubscriptionCheckout.stx +353 -0
- package/src/ui/payment/index.ts +59 -0
- package/src/ui/popover/Popover.stx +24 -0
- package/src/ui/popover/PopoverButton.stx +23 -0
- package/src/ui/popover/PopoverPanel.stx +23 -0
- package/src/ui/popover/README.md +95 -0
- package/src/ui/popover/index.ts +22 -0
- package/src/ui/portal/Portal.stx +74 -0
- package/src/ui/portal/index.ts +6 -0
- package/src/ui/progress/Progress.stx +142 -0
- package/src/ui/progress/index.ts +12 -0
- package/src/ui/radio/Radio.stx +81 -0
- package/src/ui/radio/index.ts +15 -0
- package/src/ui/radio-group/README.md +145 -0
- package/src/ui/radio-group/RadioGroup.stx +13 -0
- package/src/ui/radio-group/RadioGroupDescription.stx +11 -0
- package/src/ui/radio-group/RadioGroupLabel.stx +11 -0
- package/src/ui/radio-group/RadioGroupOption.stx +51 -0
- package/src/ui/radio-group/index.ts +30 -0
- package/src/ui/select/README.md +204 -0
- package/src/ui/select/Select.stx +89 -0
- package/src/ui/select/index.ts +21 -0
- package/src/ui/sidebar/Sidebar.stx +288 -0
- package/src/ui/sidebar/SidebarFooter.stx +95 -0
- package/src/ui/sidebar/SidebarHeader.stx +100 -0
- package/src/ui/sidebar/SidebarItem.stx +118 -0
- package/src/ui/sidebar/SidebarSection.stx +108 -0
- package/src/ui/sidebar/index.ts +175 -0
- package/src/ui/skeleton/Skeleton.stx +48 -0
- package/src/ui/skeleton/index.ts +11 -0
- package/src/ui/spinner/Spinner.stx +109 -0
- package/src/ui/spinner/index.ts +9 -0
- package/src/ui/stepper/README.md +36 -0
- package/src/ui/stepper/Stepper.stx +17 -0
- package/src/ui/stepper/StepperStep.stx +53 -0
- package/src/ui/stepper/index.ts +19 -0
- package/src/ui/storage/README.md +193 -0
- package/src/ui/storage/index.ts +347 -0
- package/src/ui/switch/README.md +133 -0
- package/src/ui/switch/Switch.stx +74 -0
- package/src/ui/switch/index.ts +10 -0
- package/src/ui/table/README.md +39 -0
- package/src/ui/table/Table.stx +14 -0
- package/src/ui/table/TableBody.stx +10 -0
- package/src/ui/table/TableCell.stx +10 -0
- package/src/ui/table/TableHead.stx +10 -0
- package/src/ui/table/TableHeader.stx +13 -0
- package/src/ui/table/TableRow.stx +11 -0
- package/src/ui/table/index.ts +35 -0
- package/src/ui/tabs/Tabs.stx +145 -0
- package/src/ui/tabs/index.ts +16 -0
- package/src/ui/teleport/Teleport.stx +101 -0
- package/src/ui/teleport/index.ts +7 -0
- package/src/ui/textarea/Textarea.stx +119 -0
- package/src/ui/textarea/index.ts +20 -0
- package/src/ui/tooltip/Tooltip.stx +76 -0
- package/src/ui/tooltip/index.ts +10 -0
- package/src/ui/transition/README.md +30 -0
- package/src/ui/transition/Transition.stx +174 -0
- package/src/ui/transition/index.ts +25 -0
- package/src/ui/video/README.md +48 -0
- package/src/ui/video/Video.stx +45 -0
- package/src/ui/video/index.ts +16 -0
- package/src/ui/virtual-list/VirtualList.stx +83 -0
- package/src/ui/virtual-list/index.ts +10 -0
- package/src/ui/virtual-table/VirtualTable.stx +113 -0
- package/src/ui/virtual-table/index.ts +21 -0
- package/src/utils/PROP_VALIDATION.md +458 -0
- package/src/utils/THEME_SYSTEM.md +702 -0
- package/src/utils/accessibility.ts +841 -0
- package/src/utils/animation/easing.ts +368 -0
- package/src/utils/animation/helpers.ts +223 -0
- package/src/utils/animation/index.ts +5 -0
- package/src/utils/animation/keyframes.ts +230 -0
- package/src/utils/error-handling.ts +473 -0
- package/src/utils/highlighter.ts +93 -0
- package/src/utils/i18n.ts +634 -0
- package/src/utils/keep-alive.ts +818 -0
- package/src/utils/lazy-loading.ts +530 -0
- package/src/utils/prop-validation.ts +478 -0
- package/src/utils/theme.ts +626 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Payment Components
|
|
2
|
+
|
|
3
|
+
Comprehensive payment components for Stripe integration, including payment method management and checkout flows.
|
|
4
|
+
|
|
5
|
+
## Component Syntax
|
|
6
|
+
|
|
7
|
+
stx supports multiple ways to use components:
|
|
8
|
+
|
|
9
|
+
### 1. @component Directive with Object Shorthand (Recommended)
|
|
10
|
+
```stx
|
|
11
|
+
@component('Checkout', {
|
|
12
|
+
products,
|
|
13
|
+
stripePublicKey,
|
|
14
|
+
apiUrl
|
|
15
|
+
})
|
|
16
|
+
@endcomponent
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2. @component Directive with Full Props
|
|
20
|
+
```stx
|
|
21
|
+
@component('Checkout', {
|
|
22
|
+
products: products,
|
|
23
|
+
stripePublicKey: stripePublicKey,
|
|
24
|
+
apiUrl: apiUrl
|
|
25
|
+
})
|
|
26
|
+
@endcomponent
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 3. PascalCase Component Tags (Vue-like)
|
|
30
|
+
```stx
|
|
31
|
+
<Checkout
|
|
32
|
+
:products="products"
|
|
33
|
+
:stripePublicKey="stripePublicKey"
|
|
34
|
+
:apiUrl="apiUrl"
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 4. PascalCase with Static Values
|
|
39
|
+
```stx
|
|
40
|
+
<Checkout
|
|
41
|
+
products="[]"
|
|
42
|
+
stripePublicKey="pk_test_..."
|
|
43
|
+
apiUrl="https://api.example.com"
|
|
44
|
+
/>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
All syntaxes are equivalent and can be used interchangeably based on your preference.
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bun add @stacksjs/components
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Components
|
|
56
|
+
|
|
57
|
+
### Checkout
|
|
58
|
+
Main checkout wrapper component that supports both subscription and one-time payment modes.
|
|
59
|
+
|
|
60
|
+
### SubscriptionCheckout
|
|
61
|
+
Full subscription checkout flow with Stripe Elements integration.
|
|
62
|
+
|
|
63
|
+
### PaymentMethods
|
|
64
|
+
Display and manage a list of saved payment methods with delete and set-default actions.
|
|
65
|
+
|
|
66
|
+
### DefaultPaymentMethod
|
|
67
|
+
Display the default payment method with a badge.
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
### Checkout Component (Recommended)
|
|
72
|
+
|
|
73
|
+
**Using @component directive with object shorthand:**
|
|
74
|
+
|
|
75
|
+
```stx
|
|
76
|
+
<script>
|
|
77
|
+
export const products = [
|
|
78
|
+
{
|
|
79
|
+
id: 1,
|
|
80
|
+
name: 'Premium Subscription',
|
|
81
|
+
price: 99900, // $999.00 in cents
|
|
82
|
+
images: '/images/subscription.jpg',
|
|
83
|
+
quantity: 1
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
export const mode = 'subscription'
|
|
88
|
+
export const stripePublicKey = 'pk_test_...'
|
|
89
|
+
export const apiUrl = 'https://api.example.com'
|
|
90
|
+
export const redirectUrl = '/thank-you'
|
|
91
|
+
export const shipping = 4500
|
|
92
|
+
export const taxes = 552
|
|
93
|
+
|
|
94
|
+
export const onSubmit = (result) => {
|
|
95
|
+
if (result.success) {
|
|
96
|
+
console.log('Payment successful!')
|
|
97
|
+
window.location.href = redirectUrl
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const onRemoveProduct = (productId) => {
|
|
102
|
+
console.log('Remove product:', productId)
|
|
103
|
+
// Update cart state
|
|
104
|
+
}
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
@component('Checkout', {
|
|
108
|
+
products,
|
|
109
|
+
mode,
|
|
110
|
+
stripePublicKey,
|
|
111
|
+
apiUrl,
|
|
112
|
+
redirectUrl,
|
|
113
|
+
shipping,
|
|
114
|
+
taxes,
|
|
115
|
+
onSubmit,
|
|
116
|
+
onRemoveProduct
|
|
117
|
+
})
|
|
118
|
+
@endcomponent
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Or using Vue-like PascalCase syntax:**
|
|
122
|
+
|
|
123
|
+
```stx
|
|
124
|
+
<script>
|
|
125
|
+
export const products = [...]
|
|
126
|
+
export const stripePublicKey = 'pk_test_...'
|
|
127
|
+
export const apiUrl = 'https://api.example.com'
|
|
128
|
+
// ... other exports
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<Checkout
|
|
132
|
+
:products="products"
|
|
133
|
+
mode="subscription"
|
|
134
|
+
:stripePublicKey="stripePublicKey"
|
|
135
|
+
:apiUrl="apiUrl"
|
|
136
|
+
redirectUrl="/thank-you"
|
|
137
|
+
:shipping="4500"
|
|
138
|
+
:taxes="552"
|
|
139
|
+
:onSubmit="onSubmit"
|
|
140
|
+
:onRemoveProduct="onRemoveProduct"
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### PaymentMethods Component
|
|
145
|
+
|
|
146
|
+
```stx
|
|
147
|
+
<script>
|
|
148
|
+
export const methods = [
|
|
149
|
+
{
|
|
150
|
+
id: 1,
|
|
151
|
+
brand: 'Visa',
|
|
152
|
+
last_four: '4242',
|
|
153
|
+
exp_month: 12,
|
|
154
|
+
exp_year: 2025
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 2,
|
|
158
|
+
brand: 'Mastercard',
|
|
159
|
+
last_four: '5555',
|
|
160
|
+
exp_month: 6,
|
|
161
|
+
exp_year: 2026
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
export const handleDelete = (id) => {
|
|
166
|
+
console.log('Delete payment method:', id)
|
|
167
|
+
// Call your API to delete
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export const handleMakeDefault = (id) => {
|
|
171
|
+
console.log('Make default:', id)
|
|
172
|
+
// Call your API to set as default
|
|
173
|
+
}
|
|
174
|
+
</script>
|
|
175
|
+
|
|
176
|
+
@component('PaymentMethods', {
|
|
177
|
+
paymentMethods: methods,
|
|
178
|
+
onDeletePaymentMethod: handleDelete,
|
|
179
|
+
onMakeDefault: handleMakeDefault,
|
|
180
|
+
isLoading: false
|
|
181
|
+
})
|
|
182
|
+
@endcomponent
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### DefaultPaymentMethod Component
|
|
186
|
+
|
|
187
|
+
```stx
|
|
188
|
+
<script>
|
|
189
|
+
export const defaultMethod = {
|
|
190
|
+
id: 1,
|
|
191
|
+
brand: 'Visa',
|
|
192
|
+
last_four: '4242',
|
|
193
|
+
exp_month: 12,
|
|
194
|
+
exp_year: 2025
|
|
195
|
+
}
|
|
196
|
+
</script>
|
|
197
|
+
|
|
198
|
+
@component('DefaultPaymentMethod', {
|
|
199
|
+
paymentMethod: defaultMethod,
|
|
200
|
+
isLoading: false
|
|
201
|
+
})
|
|
202
|
+
@endcomponent
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### SubscriptionCheckout Component
|
|
206
|
+
|
|
207
|
+
```stx
|
|
208
|
+
<script>
|
|
209
|
+
export const cartProducts = [
|
|
210
|
+
{
|
|
211
|
+
id: 1,
|
|
212
|
+
name: 'Premium Subscription',
|
|
213
|
+
price: 99900, // $999.00 in cents
|
|
214
|
+
images: '/images/subscription.jpg',
|
|
215
|
+
quantity: 1
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
export const handleCheckoutComplete = (result) => {
|
|
220
|
+
if (result.success) {
|
|
221
|
+
console.log('Payment successful!')
|
|
222
|
+
// Redirect to success page
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
</script>
|
|
226
|
+
|
|
227
|
+
@component('SubscriptionCheckout', {
|
|
228
|
+
products: cartProducts,
|
|
229
|
+
stripePublicKey: 'pk_test_...',
|
|
230
|
+
apiUrl: 'https://api.example.com/payments',
|
|
231
|
+
shipping: 4500, // $45.00 in cents
|
|
232
|
+
taxes: 552, // $5.52 in cents
|
|
233
|
+
onSubmit: handleCheckoutComplete
|
|
234
|
+
})
|
|
235
|
+
@endcomponent
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Props
|
|
239
|
+
|
|
240
|
+
### Checkout Props
|
|
241
|
+
|
|
242
|
+
| Prop | Type | Default | Description |
|
|
243
|
+
|------|------|---------|-------------|
|
|
244
|
+
| `products` | `Product[]` | `[]` | Products in cart |
|
|
245
|
+
| `mode` | `'subscription' \| 'one-time'` | `'subscription'` | Payment mode |
|
|
246
|
+
| `stripePublicKey` | `string` | - | Stripe publishable key (required) |
|
|
247
|
+
| `apiUrl` | `string` | - | Base API URL (required) |
|
|
248
|
+
| `redirectUrl` | `string` | `''` | Redirect URL after payment |
|
|
249
|
+
| `onSubmit` | `function` | - | Callback when payment completes |
|
|
250
|
+
| `onRemoveProduct` | `function` | - | Callback when product removed from cart |
|
|
251
|
+
| `shipping` | `number` | `0` | Shipping cost in cents |
|
|
252
|
+
| `taxes` | `number` | `0` | Tax amount in cents |
|
|
253
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
254
|
+
|
|
255
|
+
### PaymentMethods Props
|
|
256
|
+
|
|
257
|
+
| Prop | Type | Default | Description |
|
|
258
|
+
|------|------|---------|-------------|
|
|
259
|
+
| `paymentMethods` | `PaymentMethod[]` | `[]` | Array of payment methods |
|
|
260
|
+
| `onDeletePaymentMethod` | `function` | - | Callback when delete clicked |
|
|
261
|
+
| `onMakeDefault` | `function` | - | Callback when make default clicked |
|
|
262
|
+
| `isLoading` | `boolean` | `false` | Show loading state |
|
|
263
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
264
|
+
|
|
265
|
+
### DefaultPaymentMethod Props
|
|
266
|
+
|
|
267
|
+
| Prop | Type | Default | Description |
|
|
268
|
+
|------|------|---------|-------------|
|
|
269
|
+
| `paymentMethod` | `PaymentMethod \| null` | - | Default payment method or null |
|
|
270
|
+
| `isLoading` | `boolean` | `false` | Show loading state |
|
|
271
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
272
|
+
|
|
273
|
+
### SubscriptionCheckout Props
|
|
274
|
+
|
|
275
|
+
| Prop | Type | Default | Description |
|
|
276
|
+
|------|------|---------|-------------|
|
|
277
|
+
| `products` | `Product[]` | `[]` | Products in cart |
|
|
278
|
+
| `stripePublicKey` | `string` | - | Stripe publishable key (required) |
|
|
279
|
+
| `apiUrl` | `string` | - | Base API URL (required) |
|
|
280
|
+
| `onSubmit` | `function` | - | Callback when payment completes |
|
|
281
|
+
| `onRemoveProduct` | `function` | - | Callback when product removed from cart |
|
|
282
|
+
| `shipping` | `number` | `0` | Shipping cost in cents |
|
|
283
|
+
| `taxes` | `number` | `0` | Tax amount in cents |
|
|
284
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
285
|
+
|
|
286
|
+
## TypeScript Interfaces
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
interface PaymentMethod {
|
|
290
|
+
id: string | number
|
|
291
|
+
brand: string
|
|
292
|
+
last_four: string
|
|
293
|
+
exp_month: number
|
|
294
|
+
exp_year: number
|
|
295
|
+
is_default?: boolean
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
interface Product {
|
|
299
|
+
id: string | number
|
|
300
|
+
name: string
|
|
301
|
+
price: number // in cents
|
|
302
|
+
images?: string
|
|
303
|
+
quantity?: number
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Backend API Requirements
|
|
308
|
+
|
|
309
|
+
### Create Subscription Endpoint
|
|
310
|
+
|
|
311
|
+
Your `apiUrl` should implement a `POST /stripe/create-subscription` endpoint:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// Example Express.js endpoint
|
|
315
|
+
app.post('/stripe/create-subscription', async (req, res) => {
|
|
316
|
+
const { amount, quantity } = req.body
|
|
317
|
+
|
|
318
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
319
|
+
amount: amount,
|
|
320
|
+
currency: 'usd',
|
|
321
|
+
automatic_payment_methods: {
|
|
322
|
+
enabled: true,
|
|
323
|
+
},
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
res.json({
|
|
327
|
+
client_secret: paymentIntent.client_secret,
|
|
328
|
+
})
|
|
329
|
+
})
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Note**: The endpoint path must be `{apiUrl}/stripe/create-subscription` to match the component's expectations.
|
|
333
|
+
|
|
334
|
+
## Features
|
|
335
|
+
|
|
336
|
+
- **Stripe Elements** - Integrated Stripe payment form
|
|
337
|
+
- **Payment Management** - View, delete, set default payment methods
|
|
338
|
+
- **Dark Mode** - Full dark mode support
|
|
339
|
+
- **Loading States** - Skeleton loaders while fetching data
|
|
340
|
+
- **Empty States** - Friendly messages when no payment methods
|
|
341
|
+
- **Responsive** - Mobile-friendly layouts
|
|
342
|
+
- **Accessible** - Proper ARIA labels and keyboard navigation
|
|
343
|
+
- **Confirmation** - Delete confirmation dialogs
|
|
344
|
+
- **Error Handling** - Graceful error messages
|
|
345
|
+
- **Modern ES Modules** - Clean export syntax
|
|
346
|
+
- **Headwind Styling** - Utility-first CSS classes
|
|
347
|
+
|
|
348
|
+
## Stripe.js Integration
|
|
349
|
+
|
|
350
|
+
The `SubscriptionCheckout` component automatically loads Stripe.js from the CDN. Make sure you have a valid Stripe account and publishable key.
|
|
351
|
+
|
|
352
|
+
### Test Cards
|
|
353
|
+
|
|
354
|
+
Use these test cards in development:
|
|
355
|
+
|
|
356
|
+
- **Success**: `4242 4242 4242 4242`
|
|
357
|
+
- **Decline**: `4000 0000 0000 0002`
|
|
358
|
+
- **Requires 3DS**: `4000 0027 6000 3184`
|
|
359
|
+
|
|
360
|
+
Use any future expiration date and any 3-digit CVC.
|
|
361
|
+
|
|
362
|
+
## Example: Full Payment Flow
|
|
363
|
+
|
|
364
|
+
```stx
|
|
365
|
+
<script>
|
|
366
|
+
// Fetch payment methods
|
|
367
|
+
export const paymentMethods = await fetch('/api/payment-methods').then(r => r.json())
|
|
368
|
+
|
|
369
|
+
// Fetch default payment method
|
|
370
|
+
export const defaultMethod = paymentMethods.find(m => m.is_default)
|
|
371
|
+
|
|
372
|
+
// Cart products
|
|
373
|
+
export const cart = [
|
|
374
|
+
{ id: 1, name: 'Product 1', price: 5000, quantity: 2 },
|
|
375
|
+
{ id: 2, name: 'Product 2', price: 3000, quantity: 1 },
|
|
376
|
+
]
|
|
377
|
+
|
|
378
|
+
export const handleDelete = async (id) => {
|
|
379
|
+
await fetch(`/api/payment-methods/${id}`, { method: 'DELETE' })
|
|
380
|
+
// Refetch payment methods
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export const handleMakeDefault = async (id) => {
|
|
384
|
+
await fetch(`/api/payment-methods/${id}/default`, { method: 'POST' })
|
|
385
|
+
// Refetch payment methods
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export const handleCheckout = (result) => {
|
|
389
|
+
if (result.success) {
|
|
390
|
+
window.location.href = '/thank-you'
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
</script>
|
|
394
|
+
|
|
395
|
+
<!-- Default Payment Method -->
|
|
396
|
+
@component('DefaultPaymentMethod', {
|
|
397
|
+
paymentMethod: defaultMethod
|
|
398
|
+
})
|
|
399
|
+
@endcomponent
|
|
400
|
+
|
|
401
|
+
<!-- All Payment Methods -->
|
|
402
|
+
@component('PaymentMethods', {
|
|
403
|
+
paymentMethods: paymentMethods,
|
|
404
|
+
onDeletePaymentMethod: handleDelete,
|
|
405
|
+
onMakeDefault: handleMakeDefault
|
|
406
|
+
})
|
|
407
|
+
@endcomponent
|
|
408
|
+
|
|
409
|
+
<!-- Checkout Form -->
|
|
410
|
+
@component('SubscriptionCheckout', {
|
|
411
|
+
products: cart,
|
|
412
|
+
stripePublicKey: 'pk_test_...',
|
|
413
|
+
apiUrl: 'https://api.example.com/payments',
|
|
414
|
+
shipping: 1000,
|
|
415
|
+
taxes: 800,
|
|
416
|
+
onSubmit: handleCheckout
|
|
417
|
+
})
|
|
418
|
+
@endcomponent
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Security Notes
|
|
422
|
+
|
|
423
|
+
- **Never** expose your Stripe secret key in client code
|
|
424
|
+
- Always validate payment amounts on the server
|
|
425
|
+
- Use HTTPS in production
|
|
426
|
+
- Implement proper authentication for payment management endpoints
|
|
427
|
+
- Verify webhook signatures from Stripe
|