@tekton-ui/ui 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1137 -0
- package/dist/index.d.mts +719 -0
- package/dist/index.mjs +3511 -0
- package/dist/src/components/alert-dialog.d.ts +21 -0
- package/dist/src/components/alert-dialog.d.ts.map +1 -0
- package/dist/src/components/alert-dialog.js +26 -0
- package/dist/src/components/alert-dialog.js.map +1 -0
- package/dist/src/components/alert-dialog.stories.d.ts +22 -0
- package/dist/src/components/alert-dialog.stories.d.ts.map +1 -0
- package/dist/src/components/alert-dialog.stories.js +22 -0
- package/dist/src/components/alert-dialog.stories.js.map +1 -0
- package/dist/src/components/avatar.d.ts +7 -0
- package/dist/src/components/avatar.d.ts.map +1 -0
- package/dist/src/components/avatar.js +12 -0
- package/dist/src/components/avatar.js.map +1 -0
- package/dist/src/components/avatar.stories.d.ts +38 -0
- package/dist/src/components/avatar.stories.d.ts.map +1 -0
- package/dist/src/components/avatar.stories.js +33 -0
- package/dist/src/components/avatar.stories.js.map +1 -0
- package/dist/src/components/badge.d.ts +10 -0
- package/dist/src/components/badge.d.ts.map +1 -0
- package/dist/src/components/badge.js +21 -0
- package/dist/src/components/badge.js.map +1 -0
- package/dist/src/components/badge.stories.d.ts +73 -0
- package/dist/src/components/badge.stories.d.ts.map +1 -0
- package/dist/src/components/badge.stories.js +60 -0
- package/dist/src/components/badge.stories.js.map +1 -0
- package/dist/src/components/breadcrumb.d.ts +27 -0
- package/dist/src/components/breadcrumb.d.ts.map +1 -0
- package/dist/src/components/breadcrumb.js +60 -0
- package/dist/src/components/breadcrumb.js.map +1 -0
- package/dist/src/components/breadcrumb.stories.d.ts +49 -0
- package/dist/src/components/breadcrumb.stories.d.ts.map +1 -0
- package/dist/src/components/breadcrumb.stories.js +43 -0
- package/dist/src/components/breadcrumb.stories.js.map +1 -0
- package/dist/src/components/button.d.ts +12 -0
- package/dist/src/components/button.d.ts.map +1 -0
- package/dist/src/components/button.js +34 -0
- package/dist/src/components/button.js.map +1 -0
- package/dist/src/components/button.stories.d.ts +134 -0
- package/dist/src/components/button.stories.d.ts.map +1 -0
- package/dist/src/components/button.stories.js +101 -0
- package/dist/src/components/button.stories.js.map +1 -0
- package/dist/src/components/calendar.d.ts +8 -0
- package/dist/src/components/calendar.d.ts.map +1 -0
- package/dist/src/components/calendar.js +39 -0
- package/dist/src/components/calendar.js.map +1 -0
- package/dist/src/components/calendar.stories.d.ts +46 -0
- package/dist/src/components/calendar.stories.d.ts.map +1 -0
- package/dist/src/components/calendar.stories.js +88 -0
- package/dist/src/components/calendar.stories.js.map +1 -0
- package/dist/src/components/card.d.ts +9 -0
- package/dist/src/components/card.d.ts.map +1 -0
- package/dist/src/components/card.js +17 -0
- package/dist/src/components/card.js.map +1 -0
- package/dist/src/components/card.stories.d.ts +46 -0
- package/dist/src/components/card.stories.d.ts.map +1 -0
- package/dist/src/components/card.stories.js +40 -0
- package/dist/src/components/card.stories.js.map +1 -0
- package/dist/src/components/checkbox.d.ts +5 -0
- package/dist/src/components/checkbox.d.ts.map +1 -0
- package/dist/src/components/checkbox.js +9 -0
- package/dist/src/components/checkbox.js.map +1 -0
- package/dist/src/components/checkbox.stories.d.ts +50 -0
- package/dist/src/components/checkbox.stories.d.ts.map +1 -0
- package/dist/src/components/checkbox.stories.js +48 -0
- package/dist/src/components/checkbox.stories.js.map +1 -0
- package/dist/src/components/command.d.ts +81 -0
- package/dist/src/components/command.d.ts.map +1 -0
- package/dist/src/components/command.js +27 -0
- package/dist/src/components/command.js.map +1 -0
- package/dist/src/components/command.stories.d.ts +34 -0
- package/dist/src/components/command.stories.d.ts.map +1 -0
- package/dist/src/components/command.stories.js +44 -0
- package/dist/src/components/command.stories.js.map +1 -0
- package/dist/src/components/dialog.d.ts +20 -0
- package/dist/src/components/dialog.d.ts.map +1 -0
- package/dist/src/components/dialog.js +23 -0
- package/dist/src/components/dialog.js.map +1 -0
- package/dist/src/components/dialog.stories.d.ts +38 -0
- package/dist/src/components/dialog.stories.d.ts.map +1 -0
- package/dist/src/components/dialog.stories.js +36 -0
- package/dist/src/components/dialog.stories.js.map +1 -0
- package/dist/src/components/dropdown-menu.d.ts +28 -0
- package/dist/src/components/dropdown-menu.d.ts.map +1 -0
- package/dist/src/components/dropdown-menu.js +33 -0
- package/dist/src/components/dropdown-menu.js.map +1 -0
- package/dist/src/components/dropdown-menu.stories.d.ts +30 -0
- package/dist/src/components/dropdown-menu.stories.d.ts.map +1 -0
- package/dist/src/components/dropdown-menu.stories.js +37 -0
- package/dist/src/components/dropdown-menu.stories.js.map +1 -0
- package/dist/src/components/form.d.ts +24 -0
- package/dist/src/components/form.d.ts.map +1 -0
- package/dist/src/components/form.js +62 -0
- package/dist/src/components/form.js.map +1 -0
- package/dist/src/components/form.stories.d.ts +34 -0
- package/dist/src/components/form.stories.d.ts.map +1 -0
- package/dist/src/components/form.stories.js +132 -0
- package/dist/src/components/form.stories.js.map +1 -0
- package/dist/src/components/input.d.ts +5 -0
- package/dist/src/components/input.d.ts.map +1 -0
- package/dist/src/components/input.js +9 -0
- package/dist/src/components/input.js.map +1 -0
- package/dist/src/components/input.stories.d.ts +101 -0
- package/dist/src/components/input.stories.d.ts.map +1 -0
- package/dist/src/components/input.stories.js +79 -0
- package/dist/src/components/input.stories.js.map +1 -0
- package/dist/src/components/label.d.ts +6 -0
- package/dist/src/components/label.d.ts.map +1 -0
- package/dist/src/components/label.js +10 -0
- package/dist/src/components/label.js.map +1 -0
- package/dist/src/components/label.stories.d.ts +34 -0
- package/dist/src/components/label.stories.d.ts.map +1 -0
- package/dist/src/components/label.stories.js +32 -0
- package/dist/src/components/label.stories.js.map +1 -0
- package/dist/src/components/navigation-menu.d.ts +13 -0
- package/dist/src/components/navigation-menu.d.ts.map +1 -0
- package/dist/src/components/navigation-menu.js +22 -0
- package/dist/src/components/navigation-menu.js.map +1 -0
- package/dist/src/components/navigation-menu.stories.d.ts +26 -0
- package/dist/src/components/navigation-menu.stories.d.ts.map +1 -0
- package/dist/src/components/navigation-menu.stories.js +30 -0
- package/dist/src/components/navigation-menu.stories.js.map +1 -0
- package/dist/src/components/popover.d.ts +7 -0
- package/dist/src/components/popover.d.ts.map +1 -0
- package/dist/src/components/popover.js +10 -0
- package/dist/src/components/popover.js.map +1 -0
- package/dist/src/components/popover.stories.d.ts +22 -0
- package/dist/src/components/popover.stories.d.ts.map +1 -0
- package/dist/src/components/popover.stories.js +24 -0
- package/dist/src/components/popover.stories.js.map +1 -0
- package/dist/src/components/progress.d.ts +5 -0
- package/dist/src/components/progress.d.ts.map +1 -0
- package/dist/src/components/progress.js +8 -0
- package/dist/src/components/progress.js.map +1 -0
- package/dist/src/components/progress.stories.d.ts +44 -0
- package/dist/src/components/progress.stories.d.ts.map +1 -0
- package/dist/src/components/progress.stories.js +63 -0
- package/dist/src/components/progress.stories.js.map +1 -0
- package/dist/src/components/radio-group.d.ts +6 -0
- package/dist/src/components/radio-group.d.ts.map +1 -0
- package/dist/src/components/radio-group.js +15 -0
- package/dist/src/components/radio-group.js.map +1 -0
- package/dist/src/components/radio-group.stories.d.ts +34 -0
- package/dist/src/components/radio-group.stories.d.ts.map +1 -0
- package/dist/src/components/radio-group.stories.js +31 -0
- package/dist/src/components/radio-group.stories.js.map +1 -0
- package/dist/src/components/scroll-area.d.ts +6 -0
- package/dist/src/components/scroll-area.d.ts.map +1 -0
- package/dist/src/components/scroll-area.js +10 -0
- package/dist/src/components/scroll-area.js.map +1 -0
- package/dist/src/components/scroll-area.stories.d.ts +46 -0
- package/dist/src/components/scroll-area.stories.d.ts.map +1 -0
- package/dist/src/components/scroll-area.stories.js +44 -0
- package/dist/src/components/scroll-area.stories.js.map +1 -0
- package/dist/src/components/select.d.ts +14 -0
- package/dist/src/components/select.d.ts.map +1 -0
- package/dist/src/components/select.js +26 -0
- package/dist/src/components/select.js.map +1 -0
- package/dist/src/components/select.stories.d.ts +42 -0
- package/dist/src/components/select.stories.d.ts.map +1 -0
- package/dist/src/components/select.stories.js +37 -0
- package/dist/src/components/select.stories.js.map +1 -0
- package/dist/src/components/separator.d.ts +5 -0
- package/dist/src/components/separator.d.ts.map +1 -0
- package/dist/src/components/separator.js +8 -0
- package/dist/src/components/separator.js.map +1 -0
- package/dist/src/components/separator.stories.d.ts +47 -0
- package/dist/src/components/separator.stories.d.ts.map +1 -0
- package/dist/src/components/separator.stories.js +41 -0
- package/dist/src/components/separator.stories.js.map +1 -0
- package/dist/src/components/sheet.d.ts +26 -0
- package/dist/src/components/sheet.d.ts.map +1 -0
- package/dist/src/components/sheet.js +37 -0
- package/dist/src/components/sheet.js.map +1 -0
- package/dist/src/components/sheet.stories.d.ts +18 -0
- package/dist/src/components/sheet.stories.d.ts.map +1 -0
- package/dist/src/components/sheet.stories.js +21 -0
- package/dist/src/components/sheet.stories.js.map +1 -0
- package/dist/src/components/sidebar.d.ts +40 -0
- package/dist/src/components/sidebar.d.ts.map +1 -0
- package/dist/src/components/sidebar.js +101 -0
- package/dist/src/components/sidebar.js.map +1 -0
- package/dist/src/components/sidebar.stories.d.ts +55 -0
- package/dist/src/components/sidebar.stories.d.ts.map +1 -0
- package/dist/src/components/sidebar.stories.js +51 -0
- package/dist/src/components/sidebar.stories.js.map +1 -0
- package/dist/src/components/skeleton.d.ts +3 -0
- package/dist/src/components/skeleton.d.ts.map +1 -0
- package/dist/src/components/skeleton.js +7 -0
- package/dist/src/components/skeleton.js.map +1 -0
- package/dist/src/components/skeleton.stories.d.ts +50 -0
- package/dist/src/components/skeleton.stories.d.ts.map +1 -0
- package/dist/src/components/skeleton.stories.js +42 -0
- package/dist/src/components/skeleton.stories.js.map +1 -0
- package/dist/src/components/switch.d.ts +5 -0
- package/dist/src/components/switch.d.ts.map +1 -0
- package/dist/src/components/switch.js +8 -0
- package/dist/src/components/switch.js.map +1 -0
- package/dist/src/components/switch.stories.d.ts +50 -0
- package/dist/src/components/switch.stories.d.ts.map +1 -0
- package/dist/src/components/switch.stories.js +48 -0
- package/dist/src/components/switch.stories.js.map +1 -0
- package/dist/src/components/table.d.ts +11 -0
- package/dist/src/components/table.d.ts.map +1 -0
- package/dist/src/components/table.js +21 -0
- package/dist/src/components/table.js.map +1 -0
- package/dist/src/components/table.stories.d.ts +26 -0
- package/dist/src/components/table.stories.d.ts.map +1 -0
- package/dist/src/components/table.stories.js +26 -0
- package/dist/src/components/table.stories.js.map +1 -0
- package/dist/src/components/tabs.d.ts +8 -0
- package/dist/src/components/tabs.d.ts.map +1 -0
- package/dist/src/components/tabs.js +13 -0
- package/dist/src/components/tabs.js.map +1 -0
- package/dist/src/components/tabs.stories.d.ts +22 -0
- package/dist/src/components/tabs.stories.d.ts.map +1 -0
- package/dist/src/components/tabs.stories.js +25 -0
- package/dist/src/components/tabs.stories.js.map +1 -0
- package/dist/src/components/textarea.d.ts +5 -0
- package/dist/src/components/textarea.d.ts.map +1 -0
- package/dist/src/components/textarea.js +9 -0
- package/dist/src/components/textarea.js.map +1 -0
- package/dist/src/components/textarea.stories.d.ts +64 -0
- package/dist/src/components/textarea.stories.d.ts.map +1 -0
- package/dist/src/components/textarea.stories.js +60 -0
- package/dist/src/components/textarea.stories.js.map +1 -0
- package/dist/src/components/toast.d.ts +16 -0
- package/dist/src/components/toast.d.ts.map +1 -0
- package/dist/src/components/toast.js +34 -0
- package/dist/src/components/toast.js.map +1 -0
- package/dist/src/components/toast.stories.d.ts +22 -0
- package/dist/src/components/toast.stories.d.ts.map +1 -0
- package/dist/src/components/toast.stories.js +32 -0
- package/dist/src/components/toast.stories.js.map +1 -0
- package/dist/src/components/tooltip.d.ts +8 -0
- package/dist/src/components/tooltip.d.ts.map +1 -0
- package/dist/src/components/tooltip.js +11 -0
- package/dist/src/components/tooltip.js.map +1 -0
- package/dist/src/components/tooltip.stories.d.ts +26 -0
- package/dist/src/components/tooltip.stories.d.ts.map +1 -0
- package/dist/src/components/tooltip.stories.js +25 -0
- package/dist/src/components/tooltip.stories.js.map +1 -0
- package/dist/src/index.d.ts +45 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +36 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/motion.d.ts +99 -0
- package/dist/src/lib/motion.d.ts.map +1 -0
- package/dist/src/lib/motion.js +88 -0
- package/dist/src/lib/motion.js.map +1 -0
- package/dist/src/lib/theme-loader.d.ts +69 -0
- package/dist/src/lib/theme-loader.d.ts.map +1 -0
- package/dist/src/lib/theme-loader.js +113 -0
- package/dist/src/lib/theme-loader.js.map +1 -0
- package/dist/src/lib/tokens.d.ts +50 -0
- package/dist/src/lib/tokens.d.ts.map +1 -0
- package/dist/src/lib/tokens.js +53 -0
- package/dist/src/lib/tokens.js.map +1 -0
- package/dist/src/lib/utils.d.ts +3 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/src/lib/utils.js +6 -0
- package/dist/src/lib/utils.js.map +1 -0
- package/dist/src/templates/auth/forgot-password.d.ts +4 -0
- package/dist/src/templates/auth/forgot-password.d.ts.map +1 -0
- package/dist/src/templates/auth/forgot-password.js +47 -0
- package/dist/src/templates/auth/forgot-password.js.map +1 -0
- package/dist/src/templates/auth/forgot-password.stories.d.ts +14 -0
- package/dist/src/templates/auth/forgot-password.stories.d.ts.map +1 -0
- package/dist/src/templates/auth/forgot-password.stories.js +14 -0
- package/dist/src/templates/auth/forgot-password.stories.js.map +1 -0
- package/dist/src/templates/auth/login.d.ts +4 -0
- package/dist/src/templates/auth/login.d.ts.map +1 -0
- package/dist/src/templates/auth/login.js +50 -0
- package/dist/src/templates/auth/login.js.map +1 -0
- package/dist/src/templates/auth/login.stories.d.ts +95 -0
- package/dist/src/templates/auth/login.stories.d.ts.map +1 -0
- package/dist/src/templates/auth/login.stories.js +77 -0
- package/dist/src/templates/auth/login.stories.js.map +1 -0
- package/dist/src/templates/auth/signup.d.ts +4 -0
- package/dist/src/templates/auth/signup.d.ts.map +1 -0
- package/dist/src/templates/auth/signup.js +49 -0
- package/dist/src/templates/auth/signup.js.map +1 -0
- package/dist/src/templates/auth/signup.stories.d.ts +18 -0
- package/dist/src/templates/auth/signup.stories.d.ts.map +1 -0
- package/dist/src/templates/auth/signup.stories.js +21 -0
- package/dist/src/templates/auth/signup.stories.js.map +1 -0
- package/dist/src/templates/auth/verification.d.ts +4 -0
- package/dist/src/templates/auth/verification.d.ts.map +1 -0
- package/dist/src/templates/auth/verification.js +47 -0
- package/dist/src/templates/auth/verification.js.map +1 -0
- package/dist/src/templates/auth/verification.stories.d.ts +19 -0
- package/dist/src/templates/auth/verification.stories.d.ts.map +1 -0
- package/dist/src/templates/auth/verification.stories.js +19 -0
- package/dist/src/templates/auth/verification.stories.js.map +1 -0
- package/dist/src/templates/core/landing.d.ts +4 -0
- package/dist/src/templates/core/landing.d.ts.map +1 -0
- package/dist/src/templates/core/landing.js +44 -0
- package/dist/src/templates/core/landing.js.map +1 -0
- package/dist/src/templates/core/landing.stories.d.ts +14 -0
- package/dist/src/templates/core/landing.stories.d.ts.map +1 -0
- package/dist/src/templates/core/landing.stories.js +14 -0
- package/dist/src/templates/core/landing.stories.js.map +1 -0
- package/dist/src/templates/core/preferences.d.ts +4 -0
- package/dist/src/templates/core/preferences.d.ts.map +1 -0
- package/dist/src/templates/core/preferences.js +51 -0
- package/dist/src/templates/core/preferences.js.map +1 -0
- package/dist/src/templates/core/preferences.stories.d.ts +14 -0
- package/dist/src/templates/core/preferences.stories.d.ts.map +1 -0
- package/dist/src/templates/core/preferences.stories.js +14 -0
- package/dist/src/templates/core/preferences.stories.js.map +1 -0
- package/dist/src/templates/core/profile.d.ts +4 -0
- package/dist/src/templates/core/profile.d.ts.map +1 -0
- package/dist/src/templates/core/profile.js +49 -0
- package/dist/src/templates/core/profile.js.map +1 -0
- package/dist/src/templates/core/profile.stories.d.ts +19 -0
- package/dist/src/templates/core/profile.stories.d.ts.map +1 -0
- package/dist/src/templates/core/profile.stories.js +19 -0
- package/dist/src/templates/core/profile.stories.js.map +1 -0
- package/dist/src/templates/dashboard/overview.d.ts +4 -0
- package/dist/src/templates/dashboard/overview.d.ts.map +1 -0
- package/dist/src/templates/dashboard/overview.js +65 -0
- package/dist/src/templates/dashboard/overview.js.map +1 -0
- package/dist/src/templates/dashboard/overview.stories.d.ts +55 -0
- package/dist/src/templates/dashboard/overview.stories.d.ts.map +1 -0
- package/dist/src/templates/dashboard/overview.stories.js +51 -0
- package/dist/src/templates/dashboard/overview.stories.js.map +1 -0
- package/dist/src/templates/feedback/confirmation.d.ts +4 -0
- package/dist/src/templates/feedback/confirmation.d.ts.map +1 -0
- package/dist/src/templates/feedback/confirmation.js +47 -0
- package/dist/src/templates/feedback/confirmation.js.map +1 -0
- package/dist/src/templates/feedback/confirmation.stories.d.ts +14 -0
- package/dist/src/templates/feedback/confirmation.stories.d.ts.map +1 -0
- package/dist/src/templates/feedback/confirmation.stories.js +14 -0
- package/dist/src/templates/feedback/confirmation.stories.js.map +1 -0
- package/dist/src/templates/feedback/empty.d.ts +4 -0
- package/dist/src/templates/feedback/empty.d.ts.map +1 -0
- package/dist/src/templates/feedback/empty.js +45 -0
- package/dist/src/templates/feedback/empty.js.map +1 -0
- package/dist/src/templates/feedback/empty.stories.d.ts +14 -0
- package/dist/src/templates/feedback/empty.stories.d.ts.map +1 -0
- package/dist/src/templates/feedback/empty.stories.js +14 -0
- package/dist/src/templates/feedback/empty.stories.js.map +1 -0
- package/dist/src/templates/feedback/error.d.ts +4 -0
- package/dist/src/templates/feedback/error.d.ts.map +1 -0
- package/dist/src/templates/feedback/error.js +45 -0
- package/dist/src/templates/feedback/error.js.map +1 -0
- package/dist/src/templates/feedback/error.stories.d.ts +14 -0
- package/dist/src/templates/feedback/error.stories.d.ts.map +1 -0
- package/dist/src/templates/feedback/error.stories.js +14 -0
- package/dist/src/templates/feedback/error.stories.js.map +1 -0
- package/dist/src/templates/feedback/loading.d.ts +4 -0
- package/dist/src/templates/feedback/loading.d.ts.map +1 -0
- package/dist/src/templates/feedback/loading.js +42 -0
- package/dist/src/templates/feedback/loading.js.map +1 -0
- package/dist/src/templates/feedback/loading.stories.d.ts +14 -0
- package/dist/src/templates/feedback/loading.stories.d.ts.map +1 -0
- package/dist/src/templates/feedback/loading.stories.js +14 -0
- package/dist/src/templates/feedback/loading.stories.js.map +1 -0
- package/dist/src/templates/feedback/success.d.ts +4 -0
- package/dist/src/templates/feedback/success.d.ts.map +1 -0
- package/dist/src/templates/feedback/success.js +45 -0
- package/dist/src/templates/feedback/success.js.map +1 -0
- package/dist/src/templates/feedback/success.stories.d.ts +14 -0
- package/dist/src/templates/feedback/success.stories.d.ts.map +1 -0
- package/dist/src/templates/feedback/success.stories.js +14 -0
- package/dist/src/templates/feedback/success.stories.js.map +1 -0
- package/dist/src/templates/index.d.ts +16 -0
- package/dist/src/templates/index.d.ts.map +1 -0
- package/dist/src/templates/index.js +45 -0
- package/dist/src/templates/index.js.map +1 -0
- package/dist/src/templates/registry.d.ts +23 -0
- package/dist/src/templates/registry.d.ts.map +1 -0
- package/dist/src/templates/registry.js +90 -0
- package/dist/src/templates/registry.js.map +1 -0
- package/dist/src/templates/types.d.ts +78 -0
- package/dist/src/templates/types.d.ts.map +1 -0
- package/dist/src/templates/types.js +23 -0
- package/dist/src/templates/types.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +117 -0
- package/styles/globals.css +191 -0
- package/styles/tokens.css +303 -0
package/README.md
ADDED
|
@@ -0,0 +1,1137 @@
|
|
|
1
|
+
# @tekton/ui
|
|
2
|
+
|
|
3
|
+
Tekton UI Reference Component Library - High-quality, accessible React components with CSS Variables theming.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
@tekton/ui provides 20 production-ready components + 13 screen templates built with:
|
|
8
|
+
|
|
9
|
+
- **Screen Templates (NEW)**: 13 full-page layouts for rapid development
|
|
10
|
+
- **React 19** - Latest React features with Server Components support
|
|
11
|
+
- **TypeScript 5.7+** - Full type safety with strict mode
|
|
12
|
+
- **Radix UI v1.0+** - Accessible headless primitives
|
|
13
|
+
- **CSS Variables** - 3-layer architecture (Atomic → Semantic → Component)
|
|
14
|
+
- **WCAG 2.1 AA** - Fully accessible
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @tekton/ui
|
|
20
|
+
# or
|
|
21
|
+
npm install @tekton/ui
|
|
22
|
+
# or
|
|
23
|
+
yarn add @tekton/ui
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Import Components
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { Button, Input, Card } from '@tekton/ui';
|
|
32
|
+
import '@tekton/ui/styles';
|
|
33
|
+
|
|
34
|
+
export default function App() {
|
|
35
|
+
return (
|
|
36
|
+
<Card>
|
|
37
|
+
<CardHeader>
|
|
38
|
+
<CardTitle>Welcome to Tekton UI</CardTitle>
|
|
39
|
+
<CardDescription>Build accessible UIs faster</CardDescription>
|
|
40
|
+
</CardHeader>
|
|
41
|
+
<CardContent>
|
|
42
|
+
<Input placeholder="Enter your email..." />
|
|
43
|
+
</CardContent>
|
|
44
|
+
<CardFooter>
|
|
45
|
+
<Button variant="primary">Get Started</Button>
|
|
46
|
+
</CardFooter>
|
|
47
|
+
</Card>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### CSS Variables Theming
|
|
53
|
+
|
|
54
|
+
Import the CSS Variables template and customize:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
@import '@tekton/ui/styles';
|
|
58
|
+
|
|
59
|
+
:root {
|
|
60
|
+
/* Button Tokens */
|
|
61
|
+
--button-primary-background: #3b82f6;
|
|
62
|
+
--button-primary-foreground: white;
|
|
63
|
+
|
|
64
|
+
/* Input Tokens */
|
|
65
|
+
--input-border: #d1d5db;
|
|
66
|
+
--input-background: white;
|
|
67
|
+
|
|
68
|
+
/* Card Tokens */
|
|
69
|
+
--card-background: white;
|
|
70
|
+
--card-border: #e5e7eb;
|
|
71
|
+
|
|
72
|
+
/* ... customize 100+ other tokens */
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Components
|
|
77
|
+
|
|
78
|
+
### Primitive Components (14)
|
|
79
|
+
|
|
80
|
+
Core UI building blocks with single responsibility:
|
|
81
|
+
|
|
82
|
+
- **Button** - Interactive button with loading states and variants (default, primary, secondary, destructive, outline, ghost, link)
|
|
83
|
+
- **Input** - Text input with error states and type support (text, email, password, number)
|
|
84
|
+
- **Checkbox** - Checkbox with indeterminate support and form integration
|
|
85
|
+
- **RadioGroup** - Radio button groups with keyboard navigation
|
|
86
|
+
- **Switch** - Toggle switch with checked/unchecked states
|
|
87
|
+
- **Slider** - Range slider with min/max/step configuration
|
|
88
|
+
- **Text** - Polymorphic text component with size variants
|
|
89
|
+
- **Heading** - Hierarchical headings (h1-h6) with level prop
|
|
90
|
+
- **Badge** - Status badges (default, primary, secondary, destructive, outline)
|
|
91
|
+
- **Avatar** - User avatars with image/fallback support
|
|
92
|
+
- **Progress** - Progress bar with value 0-100
|
|
93
|
+
- **Link** - Navigation links (default, muted, underline variants)
|
|
94
|
+
- **Image** - Image component with alt text and optional object-fit
|
|
95
|
+
- **List** - Polymorphic list component (ul/ol)
|
|
96
|
+
|
|
97
|
+
### Composed Components (6)
|
|
98
|
+
|
|
99
|
+
Complex components built from primitives:
|
|
100
|
+
|
|
101
|
+
- **Card** - Card container with header/content/footer structure
|
|
102
|
+
- **Form** - Form with validation context and error handling
|
|
103
|
+
- **Modal** - Dialog/modal overlay with Portal rendering
|
|
104
|
+
- **Dropdown** - Dropdown menu with keyboard navigation
|
|
105
|
+
- **Tabs** - Tabbed navigation with automatic ARIA labels
|
|
106
|
+
- **Table** - Data table with semantic HTML structure
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Component Examples
|
|
111
|
+
|
|
112
|
+
### Button
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { Button } from '@tekton/ui';
|
|
116
|
+
|
|
117
|
+
// Variants
|
|
118
|
+
<Button variant="default">Default</Button>
|
|
119
|
+
<Button variant="primary">Primary</Button>
|
|
120
|
+
<Button variant="secondary">Secondary</Button>
|
|
121
|
+
<Button variant="destructive">Delete</Button>
|
|
122
|
+
<Button variant="outline">Outline</Button>
|
|
123
|
+
<Button variant="ghost">Ghost</Button>
|
|
124
|
+
<Button variant="link">Link</Button>
|
|
125
|
+
|
|
126
|
+
// Sizes
|
|
127
|
+
<Button size="sm">Small</Button>
|
|
128
|
+
<Button size="md">Medium</Button>
|
|
129
|
+
<Button size="lg">Large</Button>
|
|
130
|
+
|
|
131
|
+
// States
|
|
132
|
+
<Button loading>Loading...</Button>
|
|
133
|
+
<Button disabled>Disabled</Button>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Props:**
|
|
137
|
+
|
|
138
|
+
- `variant`: `"default" | "primary" | "secondary" | "destructive" | "outline" | "ghost" | "link"`
|
|
139
|
+
- `size`: `"sm" | "md" | "lg"`
|
|
140
|
+
- `loading`: `boolean`
|
|
141
|
+
- All native `<button>` props
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Input
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { Input } from '@tekton/ui';
|
|
149
|
+
|
|
150
|
+
// Basic usage
|
|
151
|
+
<Input type="text" placeholder="Enter text..." />
|
|
152
|
+
<Input type="email" placeholder="Email address" />
|
|
153
|
+
<Input type="password" placeholder="Password" />
|
|
154
|
+
|
|
155
|
+
// With error state
|
|
156
|
+
<Input type="text" aria-invalid="true" />
|
|
157
|
+
|
|
158
|
+
// Disabled
|
|
159
|
+
<Input disabled placeholder="Disabled input" />
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Props:**
|
|
163
|
+
|
|
164
|
+
- `type`: `"text" | "email" | "password" | "number" | "search" | "tel" | "url"`
|
|
165
|
+
- All native `<input>` props
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### Card
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@tekton/ui';
|
|
173
|
+
|
|
174
|
+
<Card>
|
|
175
|
+
<CardHeader>
|
|
176
|
+
<CardTitle>Card Title</CardTitle>
|
|
177
|
+
<CardDescription>Card description or subtitle</CardDescription>
|
|
178
|
+
</CardHeader>
|
|
179
|
+
<CardContent>
|
|
180
|
+
<p>Main content goes here</p>
|
|
181
|
+
</CardContent>
|
|
182
|
+
<CardFooter>
|
|
183
|
+
<Button>Action</Button>
|
|
184
|
+
</CardFooter>
|
|
185
|
+
</Card>;
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### Form
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { Form, FormField, FormLabel, FormControl, FormDescription, FormMessage } from '@tekton/ui';
|
|
194
|
+
import { Input } from '@tekton/ui';
|
|
195
|
+
|
|
196
|
+
<Form
|
|
197
|
+
onSubmit={e => {
|
|
198
|
+
e.preventDefault(); /* handle submit */
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
<FormField name="email">
|
|
202
|
+
<FormLabel htmlFor="email">Email</FormLabel>
|
|
203
|
+
<FormControl>
|
|
204
|
+
<Input id="email" type="email" />
|
|
205
|
+
</FormControl>
|
|
206
|
+
<FormDescription>We'll never share your email.</FormDescription>
|
|
207
|
+
<FormMessage name="email">Invalid email address</FormMessage>
|
|
208
|
+
</FormField>
|
|
209
|
+
</Form>;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### Modal (Dialog)
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
import {
|
|
218
|
+
Modal,
|
|
219
|
+
ModalTrigger,
|
|
220
|
+
ModalContent,
|
|
221
|
+
ModalHeader,
|
|
222
|
+
ModalTitle,
|
|
223
|
+
ModalDescription,
|
|
224
|
+
ModalFooter,
|
|
225
|
+
ModalClose,
|
|
226
|
+
} from '@tekton/ui';
|
|
227
|
+
import { Button } from '@tekton/ui';
|
|
228
|
+
|
|
229
|
+
<Modal>
|
|
230
|
+
<ModalTrigger asChild>
|
|
231
|
+
<Button>Open Modal</Button>
|
|
232
|
+
</ModalTrigger>
|
|
233
|
+
<ModalContent>
|
|
234
|
+
<ModalHeader>
|
|
235
|
+
<ModalTitle>Modal Title</ModalTitle>
|
|
236
|
+
<ModalDescription>Modal description text</ModalDescription>
|
|
237
|
+
</ModalHeader>
|
|
238
|
+
<div>Modal body content</div>
|
|
239
|
+
<ModalFooter>
|
|
240
|
+
<ModalClose asChild>
|
|
241
|
+
<Button variant="outline">Cancel</Button>
|
|
242
|
+
</ModalClose>
|
|
243
|
+
<Button variant="primary">Confirm</Button>
|
|
244
|
+
</ModalFooter>
|
|
245
|
+
</ModalContent>
|
|
246
|
+
</Modal>;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
### Dropdown Menu
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
import {
|
|
255
|
+
Dropdown,
|
|
256
|
+
DropdownTrigger,
|
|
257
|
+
DropdownContent,
|
|
258
|
+
DropdownItem,
|
|
259
|
+
DropdownSeparator,
|
|
260
|
+
} from '@tekton/ui';
|
|
261
|
+
import { Button } from '@tekton/ui';
|
|
262
|
+
|
|
263
|
+
<Dropdown>
|
|
264
|
+
<DropdownTrigger asChild>
|
|
265
|
+
<Button>Open Menu</Button>
|
|
266
|
+
</DropdownTrigger>
|
|
267
|
+
<DropdownContent>
|
|
268
|
+
<DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>
|
|
269
|
+
<DropdownItem onClick={() => console.log('Duplicate')}>Duplicate</DropdownItem>
|
|
270
|
+
<DropdownSeparator />
|
|
271
|
+
<DropdownItem disabled>Disabled Item</DropdownItem>
|
|
272
|
+
<DropdownItem onClick={() => console.log('Delete')}>Delete</DropdownItem>
|
|
273
|
+
</DropdownContent>
|
|
274
|
+
</Dropdown>;
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Tabs
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@tekton/ui';
|
|
283
|
+
|
|
284
|
+
<Tabs defaultValue="tab1">
|
|
285
|
+
<TabsList>
|
|
286
|
+
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
|
|
287
|
+
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
|
|
288
|
+
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
|
|
289
|
+
</TabsList>
|
|
290
|
+
<TabsContent value="tab1">
|
|
291
|
+
<p>Content for Tab 1</p>
|
|
292
|
+
</TabsContent>
|
|
293
|
+
<TabsContent value="tab2">
|
|
294
|
+
<p>Content for Tab 2</p>
|
|
295
|
+
</TabsContent>
|
|
296
|
+
<TabsContent value="tab3">
|
|
297
|
+
<p>Content for Tab 3</p>
|
|
298
|
+
</TabsContent>
|
|
299
|
+
</Tabs>;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
### Checkbox
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
import { Checkbox } from '@tekton/ui';
|
|
308
|
+
|
|
309
|
+
// Basic checkbox
|
|
310
|
+
<label>
|
|
311
|
+
<Checkbox id="terms" />
|
|
312
|
+
Accept terms and conditions
|
|
313
|
+
</label>
|
|
314
|
+
|
|
315
|
+
// Indeterminate state
|
|
316
|
+
<Checkbox checked="indeterminate" />
|
|
317
|
+
|
|
318
|
+
// Disabled
|
|
319
|
+
<Checkbox disabled />
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Props:**
|
|
323
|
+
|
|
324
|
+
- `checked`: `boolean | "indeterminate"`
|
|
325
|
+
- `onCheckedChange`: `(checked: boolean | "indeterminate") => void`
|
|
326
|
+
- All Radix UI Checkbox props
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### RadioGroup
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { RadioGroup, RadioGroupItem } from '@tekton/ui';
|
|
334
|
+
|
|
335
|
+
<RadioGroup defaultValue="option1">
|
|
336
|
+
<div>
|
|
337
|
+
<RadioGroupItem value="option1" id="opt1" />
|
|
338
|
+
<label htmlFor="opt1">Option 1</label>
|
|
339
|
+
</div>
|
|
340
|
+
<div>
|
|
341
|
+
<RadioGroupItem value="option2" id="opt2" />
|
|
342
|
+
<label htmlFor="opt2">Option 2</label>
|
|
343
|
+
</div>
|
|
344
|
+
<div>
|
|
345
|
+
<RadioGroupItem value="option3" id="opt3" />
|
|
346
|
+
<label htmlFor="opt3">Option 3</label>
|
|
347
|
+
</div>
|
|
348
|
+
</RadioGroup>;
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
### Switch
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
import { Switch } from '@tekton/ui';
|
|
357
|
+
|
|
358
|
+
<label>
|
|
359
|
+
<Switch id="notifications" />
|
|
360
|
+
Enable notifications
|
|
361
|
+
</label>
|
|
362
|
+
|
|
363
|
+
<Switch checked onCheckedChange={(checked) => console.log(checked)} />
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Props:**
|
|
367
|
+
|
|
368
|
+
- `checked`: `boolean`
|
|
369
|
+
- `onCheckedChange`: `(checked: boolean) => void`
|
|
370
|
+
- All Radix UI Switch props
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
### Slider
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import { Slider } from '@tekton/ui';
|
|
378
|
+
|
|
379
|
+
// Basic slider
|
|
380
|
+
<label htmlFor="volume" id="volume-label">Volume</label>
|
|
381
|
+
<Slider
|
|
382
|
+
id="volume"
|
|
383
|
+
defaultValue={[50]}
|
|
384
|
+
min={0}
|
|
385
|
+
max={100}
|
|
386
|
+
step={1}
|
|
387
|
+
aria-labelledby="volume-label"
|
|
388
|
+
/>
|
|
389
|
+
|
|
390
|
+
// Range slider
|
|
391
|
+
<Slider defaultValue={[25, 75]} min={0} max={100} />
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Props:**
|
|
395
|
+
|
|
396
|
+
- `defaultValue`: `number[]`
|
|
397
|
+
- `min`: `number`
|
|
398
|
+
- `max`: `number`
|
|
399
|
+
- `step`: `number`
|
|
400
|
+
- All Radix UI Slider props
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
### Progress
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
import { Progress } from '@tekton/ui';
|
|
408
|
+
|
|
409
|
+
<Progress value={50} aria-label="Upload progress" />
|
|
410
|
+
<Progress value={75} aria-label="Loading" />
|
|
411
|
+
<Progress value={100} aria-label="Complete" />
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Props:**
|
|
415
|
+
|
|
416
|
+
- `value`: `number` (0-100)
|
|
417
|
+
- All Radix UI Progress props
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### Avatar
|
|
422
|
+
|
|
423
|
+
```tsx
|
|
424
|
+
import { Avatar, AvatarImage, AvatarFallback } from '@tekton/ui';
|
|
425
|
+
|
|
426
|
+
<Avatar>
|
|
427
|
+
<AvatarImage src="https://example.com/avatar.jpg" alt="John Doe" />
|
|
428
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
429
|
+
</Avatar>;
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
### Badge
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
import { Badge } from '@tekton/ui';
|
|
438
|
+
|
|
439
|
+
<Badge variant="default">Default</Badge>
|
|
440
|
+
<Badge variant="primary">Primary</Badge>
|
|
441
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
442
|
+
<Badge variant="destructive">Error</Badge>
|
|
443
|
+
<Badge variant="outline">Outline</Badge>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Props:**
|
|
447
|
+
|
|
448
|
+
- `variant`: `"default" | "primary" | "secondary" | "destructive" | "outline"`
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
### Text
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
import { Text } from '@tekton/ui';
|
|
456
|
+
|
|
457
|
+
// Sizes
|
|
458
|
+
<Text size="xs">Extra small text</Text>
|
|
459
|
+
<Text size="sm">Small text</Text>
|
|
460
|
+
<Text size="md">Medium text</Text>
|
|
461
|
+
<Text size="lg">Large text</Text>
|
|
462
|
+
|
|
463
|
+
// Polymorphic rendering
|
|
464
|
+
<Text as="p">Paragraph</Text>
|
|
465
|
+
<Text as="span">Inline text</Text>
|
|
466
|
+
<Text as="div">Block text</Text>
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Props:**
|
|
470
|
+
|
|
471
|
+
- `as`: `"p" | "span" | "div" | "label"`
|
|
472
|
+
- `size`: `"xs" | "sm" | "md" | "lg"`
|
|
473
|
+
- `variant`: `"default" | "muted"`
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### Heading
|
|
478
|
+
|
|
479
|
+
```tsx
|
|
480
|
+
import { Heading } from '@tekton/ui';
|
|
481
|
+
|
|
482
|
+
<Heading level={1}>Heading 1</Heading>
|
|
483
|
+
<Heading level={2}>Heading 2</Heading>
|
|
484
|
+
<Heading level={3}>Heading 3</Heading>
|
|
485
|
+
<Heading level={4}>Heading 4</Heading>
|
|
486
|
+
<Heading level={5}>Heading 5</Heading>
|
|
487
|
+
<Heading level={6}>Heading 6</Heading>
|
|
488
|
+
|
|
489
|
+
// Sizes
|
|
490
|
+
<Heading level={1} size="sm">Small H1</Heading>
|
|
491
|
+
<Heading level={2} size="lg">Large H2</Heading>
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Props:**
|
|
495
|
+
|
|
496
|
+
- `level`: `1 | 2 | 3 | 4 | 5 | 6`
|
|
497
|
+
- `size`: `"sm" | "md" | "lg"`
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
### Link
|
|
502
|
+
|
|
503
|
+
```tsx
|
|
504
|
+
import { Link } from '@tekton/ui';
|
|
505
|
+
|
|
506
|
+
<Link href="/home" variant="default">Default Link</Link>
|
|
507
|
+
<Link href="/about" variant="muted">Muted Link</Link>
|
|
508
|
+
<Link href="/contact" variant="underline">Underlined Link</Link>
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Props:**
|
|
512
|
+
|
|
513
|
+
- `href`: `string`
|
|
514
|
+
- `variant`: `"default" | "muted" | "underline"`
|
|
515
|
+
- All native `<a>` props
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
### List
|
|
520
|
+
|
|
521
|
+
```tsx
|
|
522
|
+
import { List, ListItem } from '@tekton/ui';
|
|
523
|
+
|
|
524
|
+
// Unordered list
|
|
525
|
+
<List as="ul">
|
|
526
|
+
<ListItem>Item 1</ListItem>
|
|
527
|
+
<ListItem>Item 2</ListItem>
|
|
528
|
+
<ListItem>Item 3</ListItem>
|
|
529
|
+
</List>
|
|
530
|
+
|
|
531
|
+
// Ordered list
|
|
532
|
+
<List as="ol">
|
|
533
|
+
<ListItem>First item</ListItem>
|
|
534
|
+
<ListItem>Second item</ListItem>
|
|
535
|
+
<ListItem>Third item</ListItem>
|
|
536
|
+
</List>
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Props:**
|
|
540
|
+
|
|
541
|
+
- `as`: `"ul" | "ol"`
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
### Image
|
|
546
|
+
|
|
547
|
+
```tsx
|
|
548
|
+
import { Image } from '@tekton/ui';
|
|
549
|
+
|
|
550
|
+
<Image
|
|
551
|
+
src="https://example.com/image.jpg"
|
|
552
|
+
alt="Description of image"
|
|
553
|
+
/>
|
|
554
|
+
|
|
555
|
+
<Image
|
|
556
|
+
src="https://example.com/image.jpg"
|
|
557
|
+
alt="Cover image"
|
|
558
|
+
className="object-cover w-full h-64"
|
|
559
|
+
/>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
**Props:**
|
|
563
|
+
|
|
564
|
+
- `src`: `string`
|
|
565
|
+
- `alt`: `string` (required for accessibility)
|
|
566
|
+
- All native `<img>` props
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
### Table
|
|
571
|
+
|
|
572
|
+
```tsx
|
|
573
|
+
import {
|
|
574
|
+
Table,
|
|
575
|
+
TableHeader,
|
|
576
|
+
TableBody,
|
|
577
|
+
TableFooter,
|
|
578
|
+
TableRow,
|
|
579
|
+
TableHead,
|
|
580
|
+
TableCell,
|
|
581
|
+
TableCaption,
|
|
582
|
+
} from '@tekton/ui';
|
|
583
|
+
|
|
584
|
+
<Table>
|
|
585
|
+
<TableCaption>List of users</TableCaption>
|
|
586
|
+
<TableHeader>
|
|
587
|
+
<TableRow>
|
|
588
|
+
<TableHead>Name</TableHead>
|
|
589
|
+
<TableHead>Email</TableHead>
|
|
590
|
+
<TableHead>Role</TableHead>
|
|
591
|
+
</TableRow>
|
|
592
|
+
</TableHeader>
|
|
593
|
+
<TableBody>
|
|
594
|
+
<TableRow>
|
|
595
|
+
<TableCell>John Doe</TableCell>
|
|
596
|
+
<TableCell>john@example.com</TableCell>
|
|
597
|
+
<TableCell>Admin</TableCell>
|
|
598
|
+
</TableRow>
|
|
599
|
+
<TableRow>
|
|
600
|
+
<TableCell>Jane Smith</TableCell>
|
|
601
|
+
<TableCell>jane@example.com</TableCell>
|
|
602
|
+
<TableCell>User</TableCell>
|
|
603
|
+
</TableRow>
|
|
604
|
+
</TableBody>
|
|
605
|
+
<TableFooter>
|
|
606
|
+
<TableRow>
|
|
607
|
+
<TableCell colSpan={3}>Total: 2 users</TableCell>
|
|
608
|
+
</TableRow>
|
|
609
|
+
</TableFooter>
|
|
610
|
+
</Table>;
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## Features
|
|
616
|
+
|
|
617
|
+
### CSS Variables First
|
|
618
|
+
|
|
619
|
+
All themeable properties use CSS Variables:
|
|
620
|
+
|
|
621
|
+
```tsx
|
|
622
|
+
<Button variant="primary">
|
|
623
|
+
{/* Uses --button-primary-background and --button-primary-foreground */}
|
|
624
|
+
</Button>
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Type-Safe Variants
|
|
628
|
+
|
|
629
|
+
Powered by class-variance-authority:
|
|
630
|
+
|
|
631
|
+
```tsx
|
|
632
|
+
<Button variant="secondary" size="lg" loading>
|
|
633
|
+
Click me
|
|
634
|
+
</Button>
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Accessibility Built-In
|
|
638
|
+
|
|
639
|
+
- **WCAG 2.1 AA compliant** - All components pass axe-core validation
|
|
640
|
+
- **Proper ARIA attributes** - Screen reader friendly
|
|
641
|
+
- **Keyboard navigation** - Full keyboard support (Tab, Arrow keys, Enter, Escape)
|
|
642
|
+
- **Focus management** - Visible focus indicators and proper focus trapping
|
|
643
|
+
|
|
644
|
+
### Zero Config Setup
|
|
645
|
+
|
|
646
|
+
Works out of the box with sensible defaults:
|
|
647
|
+
|
|
648
|
+
```tsx
|
|
649
|
+
import { Button } from '@tekton/ui';
|
|
650
|
+
|
|
651
|
+
<Button>Just works</Button>;
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## Screen Templates (Phase 3)
|
|
657
|
+
|
|
658
|
+
**New in Phase 3**: 13 Screen Templates for rapid full-screen composition.
|
|
659
|
+
|
|
660
|
+
### Overview
|
|
661
|
+
|
|
662
|
+
Screen Templates provide pre-built, theme-aware full-screen layouts that combine multiple components into cohesive user experiences. Each template is registered in a centralized `TemplateRegistry` for easy discovery and reuse.
|
|
663
|
+
|
|
664
|
+
**Features:**
|
|
665
|
+
|
|
666
|
+
- **13 Pre-built Layouts**: Auth (4), Core (3), Feedback (5), Dashboard (1)
|
|
667
|
+
- **Theme-Aware**: Automatically adapts to active theme via CSS Variables
|
|
668
|
+
- **AI-Friendly**: Clear customization boundaries for AI agents
|
|
669
|
+
- **Type-Safe**: Full TypeScript support with ScreenTemplate interface
|
|
670
|
+
- **Responsive**: Desktop, Tablet, Mobile layouts
|
|
671
|
+
|
|
672
|
+
### Quick Start
|
|
673
|
+
|
|
674
|
+
```tsx
|
|
675
|
+
import { templateRegistry } from '@tekton/ui/templates';
|
|
676
|
+
|
|
677
|
+
// Get all templates
|
|
678
|
+
const allTemplates = templateRegistry.getAll(); // 13 templates
|
|
679
|
+
|
|
680
|
+
// Get by category
|
|
681
|
+
const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
|
|
682
|
+
|
|
683
|
+
// Get specific template
|
|
684
|
+
const loginTemplate = templateRegistry.get('auth.login');
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Available Templates (13)
|
|
688
|
+
|
|
689
|
+
#### Auth Templates (4)
|
|
690
|
+
|
|
691
|
+
```tsx
|
|
692
|
+
import {
|
|
693
|
+
LoginTemplate,
|
|
694
|
+
SignupTemplate,
|
|
695
|
+
ForgotPasswordTemplate,
|
|
696
|
+
VerificationTemplate
|
|
697
|
+
} from '@tekton/ui/templates/auth';
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
- **LoginTemplate** (`auth.login`) - Centered login card with email/password
|
|
701
|
+
- **SignupTemplate** (`auth.signup`) - Registration form with terms acceptance
|
|
702
|
+
- **ForgotPasswordTemplate** (`auth.forgot-password`) - Password reset flow
|
|
703
|
+
- **VerificationTemplate** (`auth.verification`) - Email verification confirmation
|
|
704
|
+
|
|
705
|
+
#### Core Templates (3)
|
|
706
|
+
|
|
707
|
+
```tsx
|
|
708
|
+
import {
|
|
709
|
+
LandingTemplate,
|
|
710
|
+
PreferencesTemplate,
|
|
711
|
+
ProfileTemplate
|
|
712
|
+
} from '@tekton/ui/templates/core';
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
- **LandingTemplate** (`home.landing`) - Full-width landing page with CTA
|
|
716
|
+
- **PreferencesTemplate** (`settings.preferences`) - Sidebar settings layout
|
|
717
|
+
- **ProfileTemplate** (`account.profile`) - User profile with avatar editing
|
|
718
|
+
|
|
719
|
+
#### Feedback Templates (5)
|
|
720
|
+
|
|
721
|
+
```tsx
|
|
722
|
+
import {
|
|
723
|
+
LoadingTemplate,
|
|
724
|
+
ErrorTemplate,
|
|
725
|
+
EmptyTemplate,
|
|
726
|
+
ConfirmationTemplate,
|
|
727
|
+
SuccessTemplate
|
|
728
|
+
} from '@tekton/ui/templates/feedback';
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
- **LoadingTemplate** (`feedback.loading`) - Loading skeleton state
|
|
732
|
+
- **ErrorTemplate** (`feedback.error`) - Error state with retry button
|
|
733
|
+
- **EmptyTemplate** (`feedback.empty`) - Empty state with CTA
|
|
734
|
+
- **ConfirmationTemplate** (`feedback.confirmation`) - Dialog confirmation
|
|
735
|
+
- **SuccessTemplate** (`feedback.success`) - Success message with next steps
|
|
736
|
+
|
|
737
|
+
#### Dashboard Template (1)
|
|
738
|
+
|
|
739
|
+
```tsx
|
|
740
|
+
import { DashboardTemplate } from '@tekton/ui/templates/dashboard';
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
- **DashboardTemplate** (`dashboard.overview`) - Dashboard layout with sidebar
|
|
744
|
+
|
|
745
|
+
### Template Features
|
|
746
|
+
|
|
747
|
+
- **Type-Safe**: Full TypeScript support with `ScreenTemplate` interface
|
|
748
|
+
- **AI-Friendly**: Clear customization boundaries (`slots`, `texts`, `options`)
|
|
749
|
+
- **Theme-Aware**: CSS Variables for automatic theme adaptation
|
|
750
|
+
- **Responsive**: Breakpoint-based layouts (Desktop 1024px+, Tablet 768-1024px, Mobile <768px)
|
|
751
|
+
- **Accessible**: WCAG 2.1 AA compliance (validation in progress)
|
|
752
|
+
|
|
753
|
+
### TemplateRegistry API
|
|
754
|
+
|
|
755
|
+
The `TemplateRegistry` provides centralized template management:
|
|
756
|
+
|
|
757
|
+
```tsx
|
|
758
|
+
import { templateRegistry } from '@tekton/ui/templates/registry';
|
|
759
|
+
|
|
760
|
+
// Get all templates
|
|
761
|
+
const allTemplates = templateRegistry.getAll(); // 13 templates
|
|
762
|
+
|
|
763
|
+
// Get templates by category
|
|
764
|
+
const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
|
|
765
|
+
|
|
766
|
+
// Get specific template
|
|
767
|
+
const loginTemplate = templateRegistry.get('auth.login');
|
|
768
|
+
|
|
769
|
+
// Find by required components
|
|
770
|
+
const formsTemplates = templateRegistry.findByRequiredComponents(['Button', 'Input', 'Form']);
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
**Design Reference**: All templates follow [Claude.ai Design Philosophy](../../.moai/specs/SPEC-UI-002/reference-guide.md) - clarity, accessibility, universality.
|
|
774
|
+
|
|
775
|
+
### Phase 3 Status
|
|
776
|
+
|
|
777
|
+
**Completed (2026-02-01):**
|
|
778
|
+
|
|
779
|
+
- ✅ Template type system (`ScreenTemplate`, `TemplateRegistry`)
|
|
780
|
+
- ✅ 13 templates implemented (Auth 4, Core 3, Feedback 5, Dashboard 1)
|
|
781
|
+
- ✅ Template registry with category filtering
|
|
782
|
+
- ✅ Storybook stories for all templates
|
|
783
|
+
- ✅ SPEC TAG annotations (TAG-UI002-001 ~ 035)
|
|
784
|
+
- ⚠️ Test coverage: 17.26% (improvement planned)
|
|
785
|
+
|
|
786
|
+
**Next Steps:**
|
|
787
|
+
|
|
788
|
+
- Test coverage to 85%+
|
|
789
|
+
- Accessibility validation (axe-core, WCAG 2.1 AA)
|
|
790
|
+
- Additional template variants
|
|
791
|
+
- Template preview gallery in Storybook
|
|
792
|
+
|
|
793
|
+
---
|
|
794
|
+
|
|
795
|
+
## CSS Variables Reference
|
|
796
|
+
|
|
797
|
+
@tekton/ui uses a 3-layer CSS Variables architecture:
|
|
798
|
+
|
|
799
|
+
### Layer 1: Atomic Tokens
|
|
800
|
+
|
|
801
|
+
```css
|
|
802
|
+
--color-primary: #3b82f6;
|
|
803
|
+
--color-destructive: #ef4444;
|
|
804
|
+
--spacing-sm: 0.5rem;
|
|
805
|
+
--radius-md: 0.375rem;
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Layer 2: Semantic Tokens
|
|
809
|
+
|
|
810
|
+
```css
|
|
811
|
+
--text-primary: var(--color-primary);
|
|
812
|
+
--bg-destructive: var(--color-destructive);
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Layer 3: Component Tokens
|
|
816
|
+
|
|
817
|
+
**Button Tokens:**
|
|
818
|
+
|
|
819
|
+
```css
|
|
820
|
+
--button-default-background
|
|
821
|
+
--button-default-foreground
|
|
822
|
+
--button-primary-background
|
|
823
|
+
--button-primary-foreground
|
|
824
|
+
--button-secondary-background
|
|
825
|
+
--button-secondary-foreground
|
|
826
|
+
--button-destructive-background
|
|
827
|
+
--button-destructive-foreground
|
|
828
|
+
--button-outline-border
|
|
829
|
+
--button-outline-foreground
|
|
830
|
+
--button-ghost-hover-background
|
|
831
|
+
--button-link-foreground
|
|
832
|
+
--button-disabled-opacity
|
|
833
|
+
--button-focus-ring
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
**Input Tokens:**
|
|
837
|
+
|
|
838
|
+
```css
|
|
839
|
+
--input-background
|
|
840
|
+
--input-foreground
|
|
841
|
+
--input-border
|
|
842
|
+
--input-placeholder
|
|
843
|
+
--input-focus-ring
|
|
844
|
+
--input-disabled-background
|
|
845
|
+
--input-disabled-foreground
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
**Card Tokens:**
|
|
849
|
+
|
|
850
|
+
```css
|
|
851
|
+
--card-background
|
|
852
|
+
--card-foreground
|
|
853
|
+
--card-border
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Modal Tokens:**
|
|
857
|
+
|
|
858
|
+
```css
|
|
859
|
+
--modal-background
|
|
860
|
+
--modal-border
|
|
861
|
+
--modal-overlay-background
|
|
862
|
+
--modal-title-foreground
|
|
863
|
+
--modal-description-foreground
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
**Form Tokens:**
|
|
867
|
+
|
|
868
|
+
```css
|
|
869
|
+
--form-label-foreground
|
|
870
|
+
--form-message-destructive
|
|
871
|
+
--form-description-foreground
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
**Other Component Tokens:**
|
|
875
|
+
|
|
876
|
+
- Badge: `--badge-*-background`, `--badge-*-foreground`, `--badge-*-border`
|
|
877
|
+
- Dropdown: `--dropdown-*-background`, `--dropdown-item-*`
|
|
878
|
+
- Tabs: `--tabs-*-background`, `--tabs-trigger-*`
|
|
879
|
+
- Table: `--table-*-background`, `--table-border`
|
|
880
|
+
- Progress: `--progress-background`, `--progress-indicator-background`
|
|
881
|
+
- Slider: `--slider-track-background`, `--slider-thumb-*`
|
|
882
|
+
- Avatar: `--avatar-background`, `--avatar-foreground`
|
|
883
|
+
|
|
884
|
+
### Custom Theme Example
|
|
885
|
+
|
|
886
|
+
```css
|
|
887
|
+
/* dark-theme.css */
|
|
888
|
+
@import '@tekton/ui/styles';
|
|
889
|
+
|
|
890
|
+
:root {
|
|
891
|
+
/* Atomic Layer */
|
|
892
|
+
--color-primary: #60a5fa;
|
|
893
|
+
--color-background: #1f2937;
|
|
894
|
+
--color-foreground: #f9fafb;
|
|
895
|
+
|
|
896
|
+
/* Button Layer */
|
|
897
|
+
--button-primary-background: var(--color-primary);
|
|
898
|
+
--button-primary-foreground: #000000;
|
|
899
|
+
--button-default-background: #374151;
|
|
900
|
+
--button-default-foreground: var(--color-foreground);
|
|
901
|
+
|
|
902
|
+
/* Input Layer */
|
|
903
|
+
--input-background: #374151;
|
|
904
|
+
--input-foreground: var(--color-foreground);
|
|
905
|
+
--input-border: #4b5563;
|
|
906
|
+
|
|
907
|
+
/* Card Layer */
|
|
908
|
+
--card-background: #374151;
|
|
909
|
+
--card-foreground: var(--color-foreground);
|
|
910
|
+
--card-border: #4b5563;
|
|
911
|
+
}
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
---
|
|
915
|
+
|
|
916
|
+
## Development
|
|
917
|
+
|
|
918
|
+
### Setup
|
|
919
|
+
|
|
920
|
+
```bash
|
|
921
|
+
# Clone repository
|
|
922
|
+
git clone https://github.com/your-org/tekton.git
|
|
923
|
+
cd tekton/packages/ui
|
|
924
|
+
|
|
925
|
+
# Install dependencies (requires pnpm)
|
|
926
|
+
pnpm install
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
### Scripts
|
|
930
|
+
|
|
931
|
+
```bash
|
|
932
|
+
# Run tests
|
|
933
|
+
pnpm test
|
|
934
|
+
|
|
935
|
+
# Run tests with coverage (target: ≥90%)
|
|
936
|
+
pnpm test:coverage
|
|
937
|
+
|
|
938
|
+
# Run tests in watch mode
|
|
939
|
+
pnpm test:watch
|
|
940
|
+
|
|
941
|
+
# Type check (TypeScript 5.7+ strict mode)
|
|
942
|
+
pnpm type-check
|
|
943
|
+
|
|
944
|
+
# Lint (ESLint 9)
|
|
945
|
+
pnpm lint
|
|
946
|
+
|
|
947
|
+
# Build (outputs to dist/)
|
|
948
|
+
pnpm build
|
|
949
|
+
|
|
950
|
+
# Clean build artifacts
|
|
951
|
+
pnpm clean
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### Project Structure
|
|
955
|
+
|
|
956
|
+
```
|
|
957
|
+
packages/ui/
|
|
958
|
+
├── src/
|
|
959
|
+
│ ├── primitives/ # 14 primitive components
|
|
960
|
+
│ │ ├── button.tsx
|
|
961
|
+
│ │ ├── input.tsx
|
|
962
|
+
│ │ ├── checkbox.tsx
|
|
963
|
+
│ │ └── ...
|
|
964
|
+
│ ├── components/ # 6 composed components
|
|
965
|
+
│ │ ├── card.tsx
|
|
966
|
+
│ │ ├── form.tsx
|
|
967
|
+
│ │ ├── modal.tsx
|
|
968
|
+
│ │ └── ...
|
|
969
|
+
│ ├── lib/
|
|
970
|
+
│ │ └── utils.ts # cn() utility
|
|
971
|
+
│ └── index.ts # Main export
|
|
972
|
+
├── __tests__/
|
|
973
|
+
│ ├── primitives/ # Primitive tests
|
|
974
|
+
│ ├── components/ # Component tests
|
|
975
|
+
│ ├── lib/ # Utility tests
|
|
976
|
+
│ └── accessibility.test.tsx # WCAG compliance
|
|
977
|
+
├── vitest.config.ts
|
|
978
|
+
├── tsconfig.json
|
|
979
|
+
└── package.json
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
---
|
|
983
|
+
|
|
984
|
+
## Testing
|
|
985
|
+
|
|
986
|
+
All 20 components include comprehensive test coverage:
|
|
987
|
+
|
|
988
|
+
### Test Coverage (98.93%)
|
|
989
|
+
|
|
990
|
+
- **Statement Coverage**: 98.93%
|
|
991
|
+
- **Branch Coverage**: 95.52%
|
|
992
|
+
- **Function Coverage**: 100%
|
|
993
|
+
- **Line Coverage**: 98.93%
|
|
994
|
+
|
|
995
|
+
### Test Categories
|
|
996
|
+
|
|
997
|
+
**Unit Tests (Vitest + Testing Library)**
|
|
998
|
+
|
|
999
|
+
- Component rendering
|
|
1000
|
+
- Props validation
|
|
1001
|
+
- Variant behavior
|
|
1002
|
+
- State management
|
|
1003
|
+
- Event handling
|
|
1004
|
+
|
|
1005
|
+
**Accessibility Tests (vitest-axe)**
|
|
1006
|
+
|
|
1007
|
+
- WCAG 2.1 AA compliance
|
|
1008
|
+
- ARIA attributes
|
|
1009
|
+
- Semantic HTML
|
|
1010
|
+
- Color contrast (disabled in jsdom)
|
|
1011
|
+
|
|
1012
|
+
**Keyboard Navigation Tests**
|
|
1013
|
+
|
|
1014
|
+
- Tab navigation
|
|
1015
|
+
- Arrow key navigation (RadioGroup, Tabs, Slider)
|
|
1016
|
+
- Enter/Space activation
|
|
1017
|
+
- Escape key handling (Modal, Dropdown)
|
|
1018
|
+
|
|
1019
|
+
**User Interaction Tests (userEvent)**
|
|
1020
|
+
|
|
1021
|
+
- Click events
|
|
1022
|
+
- Form submissions
|
|
1023
|
+
- Input changes
|
|
1024
|
+
- Focus management
|
|
1025
|
+
|
|
1026
|
+
### Running Tests
|
|
1027
|
+
|
|
1028
|
+
```bash
|
|
1029
|
+
# All tests
|
|
1030
|
+
pnpm test
|
|
1031
|
+
|
|
1032
|
+
# Specific file
|
|
1033
|
+
pnpm vitest run __tests__/primitives/button.test.tsx
|
|
1034
|
+
|
|
1035
|
+
# Watch mode
|
|
1036
|
+
pnpm test:watch
|
|
1037
|
+
|
|
1038
|
+
# Coverage report
|
|
1039
|
+
pnpm test:coverage
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
## Browser Support
|
|
1045
|
+
|
|
1046
|
+
- Chrome (latest)
|
|
1047
|
+
- Firefox (latest)
|
|
1048
|
+
- Safari (latest)
|
|
1049
|
+
- Edge (latest)
|
|
1050
|
+
|
|
1051
|
+
**Note**: Internet Explorer is not supported.
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
## TypeScript Support
|
|
1056
|
+
|
|
1057
|
+
All components are fully typed with TypeScript 5.7+:
|
|
1058
|
+
|
|
1059
|
+
```tsx
|
|
1060
|
+
import { Button, ButtonProps } from '@tekton/ui';
|
|
1061
|
+
|
|
1062
|
+
// Type-safe props
|
|
1063
|
+
const MyButton: React.FC<ButtonProps> = props => {
|
|
1064
|
+
return <Button {...props} />;
|
|
1065
|
+
};
|
|
1066
|
+
|
|
1067
|
+
// Type inference
|
|
1068
|
+
<Button
|
|
1069
|
+
variant="primary" // ✓ Valid
|
|
1070
|
+
variant="invalid" // ✗ TypeScript error
|
|
1071
|
+
size="lg" // ✓ Valid
|
|
1072
|
+
onClick={e => {
|
|
1073
|
+
// e is typed as MouseEvent<HTMLButtonElement>
|
|
1074
|
+
console.log(e.currentTarget);
|
|
1075
|
+
}}
|
|
1076
|
+
/>;
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
---
|
|
1080
|
+
|
|
1081
|
+
## Contributing
|
|
1082
|
+
|
|
1083
|
+
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
|
|
1084
|
+
|
|
1085
|
+
### Development Workflow
|
|
1086
|
+
|
|
1087
|
+
1. Fork the repository
|
|
1088
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
1089
|
+
3. Make your changes
|
|
1090
|
+
4. Run tests (`pnpm test`)
|
|
1091
|
+
5. Run type check (`pnpm type-check`)
|
|
1092
|
+
6. Run linter (`pnpm lint`)
|
|
1093
|
+
7. Commit changes (`git commit -m 'Add amazing feature'`)
|
|
1094
|
+
8. Push to branch (`git push origin feature/amazing-feature`)
|
|
1095
|
+
9. Open a Pull Request
|
|
1096
|
+
|
|
1097
|
+
### Code Quality Standards
|
|
1098
|
+
|
|
1099
|
+
- **Test Coverage**: ≥90% (currently 98.93%)
|
|
1100
|
+
- **TypeScript**: Strict mode, no `any` types
|
|
1101
|
+
- **Accessibility**: WCAG 2.1 AA compliant
|
|
1102
|
+
- **ESLint**: Zero warnings/errors
|
|
1103
|
+
- **Documentation**: All public APIs documented
|
|
1104
|
+
|
|
1105
|
+
---
|
|
1106
|
+
|
|
1107
|
+
## License
|
|
1108
|
+
|
|
1109
|
+
MIT License - see [LICENSE](./LICENSE) for details
|
|
1110
|
+
|
|
1111
|
+
---
|
|
1112
|
+
|
|
1113
|
+
## Links
|
|
1114
|
+
|
|
1115
|
+
- **Documentation**: [Tekton UI Guide](https://github.com/tektoncd/tekton)
|
|
1116
|
+
- **Radix UI**: [https://www.radix-ui.com/](https://www.radix-ui.com/)
|
|
1117
|
+
- **WCAG 2.1**: [https://www.w3.org/WAI/WCAG21/quickref/](https://www.w3.org/WAI/WCAG21/quickref/)
|
|
1118
|
+
- **React 19**: [https://react.dev/](https://react.dev/)
|
|
1119
|
+
- **TypeScript**: [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1123
|
+
## Acknowledgments
|
|
1124
|
+
|
|
1125
|
+
Built with:
|
|
1126
|
+
|
|
1127
|
+
- [React 19](https://react.dev/) - UI library
|
|
1128
|
+
- [Radix UI](https://www.radix-ui.com/) - Accessible primitives
|
|
1129
|
+
- [class-variance-authority](https://cva.style/docs) - Variant management
|
|
1130
|
+
- [Vitest](https://vitest.dev/) - Testing framework
|
|
1131
|
+
- [axe-core](https://github.com/dequelabs/axe-core) - Accessibility testing
|
|
1132
|
+
|
|
1133
|
+
---
|
|
1134
|
+
|
|
1135
|
+
**Version**: 1.0.0
|
|
1136
|
+
**Last Updated**: 2026-01-26
|
|
1137
|
+
**Maintained by**: Tekton Team
|