motion-ui-skill 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +637 -0
- package/SKILL.md +529 -0
- package/agents/openai.yaml +8 -0
- package/bin/index.mjs +242 -0
- package/bin/installer.mjs +457 -0
- package/bin/updater.mjs +207 -0
- package/catalog.json +8120 -0
- package/components/agents/agent-activity/activity-row.tsx +242 -0
- package/components/agents/agent-activity/index.tsx +287 -0
- package/components/agents/agent-activity/types.ts +106 -0
- package/components/agents/agent-code.tsx +171 -0
- package/components/agents/agent-disclosure.tsx +55 -0
- package/components/agents/ai-sidebar.tsx +981 -0
- package/components/agents/approval-card/index.tsx +467 -0
- package/components/agents/approval-card/types.ts +56 -0
- package/components/agents/chat-app.tsx +97 -0
- package/components/agents/citations.tsx +288 -0
- package/components/agents/code-block.tsx +202 -0
- package/components/agents/file-diff.tsx +288 -0
- package/components/agents/image-generation.tsx +388 -0
- package/components/agents/loading-states/agent-progress.tsx +105 -0
- package/components/agents/loading-states/index.ts +13 -0
- package/components/agents/loading-states/reasoning-text.tsx +224 -0
- package/components/agents/loading-states/thinking-shimmer.tsx +27 -0
- package/components/agents/message-bubble.tsx +369 -0
- package/components/agents/message-context.tsx +9 -0
- package/components/agents/message-scroller.tsx +487 -0
- package/components/agents/message.tsx +272 -0
- package/components/agents/prompt-input.tsx +327 -0
- package/components/agents/streaming-response.tsx +263 -0
- package/components/agents/todo-list.tsx +387 -0
- package/components/agents/tool-approval.tsx +276 -0
- package/components/agents/tool-result.tsx +352 -0
- package/components/app/icons.tsx +19 -0
- package/components/audio/music-player-card.tsx +146 -0
- package/components/audio/music-playlist-card.tsx +172 -0
- package/components/audio/now-playing-bar.tsx +116 -0
- package/components/background-gradient/arc-bands-background.tsx +54 -0
- package/components/background-gradient/aurora-background.tsx +49 -0
- package/components/background-gradient/cherry-petal-background.tsx +50 -0
- package/components/background-gradient/coral-glow-background.tsx +47 -0
- package/components/background-gradient/dark-arc-bands-background.tsx +52 -0
- package/components/background-gradient/dark-aurora-background.tsx +52 -0
- package/components/background-gradient/dark-carbon-spotlight-background.tsx +47 -0
- package/components/background-gradient/dark-ember-background.tsx +47 -0
- package/components/background-gradient/dark-ink-field-background.tsx +46 -0
- package/components/background-gradient/dark-midnight-mesh-background.tsx +61 -0
- package/components/background-gradient/dark-rose-noir-background.tsx +52 -0
- package/components/background-gradient/dark-teal-depth-background.tsx +52 -0
- package/components/background-gradient/frost-mesh-background.tsx +56 -0
- package/components/background-gradient/halftone-pop-background.tsx +52 -0
- package/components/background-gradient/honey-ember-background.tsx +47 -0
- package/components/background-gradient/ink-wash-background.tsx +49 -0
- package/components/background-gradient/linen-weave-background.tsx +47 -0
- package/components/background-gradient/mint-lagoon-background.tsx +47 -0
- package/components/background-gradient/paper-fold-background.tsx +52 -0
- package/components/background-gradient/rain-prism-background.tsx +52 -0
- package/components/background-gradient/sand-drift-background.tsx +47 -0
- package/components/background-gradient/soft-spotlight-background.tsx +47 -0
- package/components/background-gradient/sunrise-horizon-background.tsx +51 -0
- package/components/background-gradient/sunset-bloom-background.tsx +47 -0
- package/components/background-gradient/terrazzo-fragment-background.tsx +53 -0
- package/components/background-gradient/tropical-tide-background.tsx +47 -0
- package/components/background-pattern/diagonal-box-pattern.tsx +29 -0
- package/components/background-pattern/dot-grid-pattern.tsx +29 -0
- package/components/background-pattern/fine-grain-pattern.tsx +39 -0
- package/components/background-pattern/graph-paper-pattern.tsx +29 -0
- package/components/background-pattern/line-grid-pattern.tsx +39 -0
- package/components/background-pattern/reverse-diagonal-box-pattern.tsx +30 -0
- package/components/buttons/add-to-cart-button.tsx +190 -0
- package/components/buttons/bookmark-save-button.tsx +105 -0
- package/components/buttons/cinder-latch-button.tsx +80 -0
- package/components/buttons/copy-button.tsx +155 -0
- package/components/buttons/depth-outline-button.tsx +72 -0
- package/components/buttons/dimple-switch.tsx +114 -0
- package/components/buttons/download-button.tsx +186 -0
- package/components/buttons/follow-button.tsx +98 -0
- package/components/buttons/hold-to-delete-button.tsx +205 -0
- package/components/buttons/inset-button.tsx +82 -0
- package/components/buttons/like-button.tsx +135 -0
- package/components/buttons/linen-tab-button.tsx +92 -0
- package/components/buttons/prism-depth-button.tsx +90 -0
- package/components/buttons/quantity-stepper-button.tsx +104 -0
- package/components/buttons/segmented-toggle-button.tsx +134 -0
- package/components/buttons/sheen-pill-button.tsx +127 -0
- package/components/buttons/slate-chip-switch.tsx +94 -0
- package/components/buttons/slide-to-confirm-button.tsx +163 -0
- package/components/buttons/soft-pill-button.tsx +86 -0
- package/components/buttons/soft-ui-button.tsx +59 -0
- package/components/buttons/three-d-button.tsx +99 -0
- package/components/buttons/three-d-icon-button.tsx +88 -0
- package/components/calendar/booking-slot-calendar.tsx +315 -0
- package/components/calendar/date-range-picker-card.tsx +216 -0
- package/components/calendar/event-countdown-card.tsx +105 -0
- package/components/calendar/month-picker-calendar.tsx +183 -0
- package/components/calendar/week-strip-calendar.tsx +182 -0
- package/components/contact/copy-email.tsx +94 -0
- package/components/docks/Icons.tsx +222 -0
- package/components/docks/app-dock.tsx +111 -0
- package/components/docks/editor-tool-dock.tsx +113 -0
- package/components/docks/mac-dock.tsx +144 -0
- package/components/docks/presence-dock.tsx +178 -0
- package/components/docks/spotlight-bar.tsx +188 -0
- package/components/dropdowns/file-menu-dropdown.tsx +192 -0
- package/components/dropdowns/filter-sort-dropdown.tsx +189 -0
- package/components/dropdowns/kebab-actions-dropdown.tsx +195 -0
- package/components/dropdowns/notification-dropdown.tsx +235 -0
- package/components/dropdowns/share-menu-dropdown.tsx +197 -0
- package/components/dropdowns/user-menu-dropdown.tsx +251 -0
- package/components/dropdowns/workspace-switcher-dropdown.tsx +248 -0
- package/components/event/event-ticket-card.tsx +116 -0
- package/components/files/ink-stamp-document-card.tsx +88 -0
- package/components/files/stacked-folder-card.tsx +176 -0
- package/components/folder/folder-tab-card.tsx +123 -0
- package/components/forms/contact-form.tsx +417 -0
- package/components/forms/forgot-password-form.tsx +264 -0
- package/components/forms/login-form.tsx +342 -0
- package/components/forms/newsletter-form.tsx +212 -0
- package/components/forms/signup-form.tsx +487 -0
- package/components/frames/circle-cut-frame.tsx +198 -0
- package/components/frames/hard-shadow-polaroid-frame.tsx +158 -0
- package/components/frames/sticky-note-polaroid-frame.tsx +230 -0
- package/components/frames/transform-box-frame.tsx +287 -0
- package/components/frames/transform-plus-frame.tsx +308 -0
- package/components/gallery/film-strip-card.tsx +103 -0
- package/components/gallery/gallery-grid-card.tsx +106 -0
- package/components/gallery/gallery-wall-card.tsx +71 -0
- package/components/gallery/glass-overlay-image-card.tsx +156 -0
- package/components/gallery/museum-placard-card.tsx +105 -0
- package/components/gallery/photo-album-card.tsx +114 -0
- package/components/gallery/photo-contact-sheet-card.tsx +71 -0
- package/components/gallery/polaroid-image-card.tsx +81 -0
- package/components/gallery/slow-living-polaroid-card.tsx +88 -0
- package/components/gallery/stamp-postcard-card.tsx +78 -0
- package/components/inputs/checkbox-field-input.tsx +148 -0
- package/components/inputs/combobox-field-input.tsx +466 -0
- package/components/inputs/date-field-input.tsx +472 -0
- package/components/inputs/file-upload-field-input.tsx +578 -0
- package/components/inputs/floating-label-field-input.tsx +206 -0
- package/components/inputs/input-group-field.tsx +132 -0
- package/components/inputs/password-field-input.tsx +125 -0
- package/components/inputs/phone-field-input.tsx +157 -0
- package/components/inputs/radio-group-field-input.tsx +220 -0
- package/components/inputs/search-input.tsx +163 -0
- package/components/inputs/select-field-input.tsx +416 -0
- package/components/inputs/switch-field-input.tsx +179 -0
- package/components/inputs/text-field-input.tsx +89 -0
- package/components/inputs/textarea-field-input.tsx +152 -0
- package/components/loaders/apple-hello-loader.tsx +86 -0
- package/components/loaders/spin-loader.tsx +51 -0
- package/components/loaders/text-loader.tsx +148 -0
- package/components/mockups/apple-ipod-mockup-card.tsx +155 -0
- package/components/mockups/apple-watch-mockup-card.tsx +278 -0
- package/components/mockups/browser-mockup-card.tsx +109 -0
- package/components/mockups/laptop-mockup-card.tsx +118 -0
- package/components/mockups/phone-mockup-card.tsx +210 -0
- package/components/mockups/tablet-mockup-card.tsx +212 -0
- package/components/motion/action-sheet.tsx +218 -0
- package/components/motion/action-swap-roll.tsx +32 -0
- package/components/motion/action-swap.tsx +340 -0
- package/components/motion/adaptive-stepper.tsx +442 -0
- package/components/motion/animated-badge.tsx +213 -0
- package/components/motion/animated-number.tsx +50 -0
- package/components/motion/animated-sidebar.tsx +1174 -0
- package/components/motion/animated-toast-stack.tsx +503 -0
- package/components/motion/aspect-ratio.tsx +55 -0
- package/components/motion/attachment-upload.tsx +1080 -0
- package/components/motion/audio-player.tsx +266 -0
- package/components/motion/autocomplete.tsx +183 -0
- package/components/motion/availability-scheduler/copy-menu.tsx +119 -0
- package/components/motion/availability-scheduler/day-row.tsx +231 -0
- package/components/motion/availability-scheduler/icon-button.tsx +46 -0
- package/components/motion/availability-scheduler/index.tsx +154 -0
- package/components/motion/availability-scheduler/time-select.tsx +49 -0
- package/components/motion/availability-scheduler/types.ts +189 -0
- package/components/motion/avatar-group.tsx +154 -0
- package/components/motion/bloom-menu.tsx +216 -0
- package/components/motion/bottom-sheet.tsx +249 -0
- package/components/motion/bounce-sidebar.tsx +266 -0
- package/components/motion/bouncy-accordion.tsx +325 -0
- package/components/motion/breadcrumb.tsx +122 -0
- package/components/motion/button/base.tsx +189 -0
- package/components/motion/button/index.tsx +13 -0
- package/components/motion/button/magnetic.tsx +25 -0
- package/components/motion/button/metallic.tsx +100 -0
- package/components/motion/button/stateful.tsx +237 -0
- package/components/motion/card-folder.tsx +345 -0
- package/components/motion/card-resize.tsx +229 -0
- package/components/motion/cascader.tsx +279 -0
- package/components/motion/center-morph-modal.tsx +366 -0
- package/components/motion/checkbox.tsx +123 -0
- package/components/motion/chip.tsx +121 -0
- package/components/motion/chromatic-text-reveal.tsx +203 -0
- package/components/motion/collapsible.tsx +108 -0
- package/components/motion/color-picker.tsx +206 -0
- package/components/motion/combobox/content.tsx +163 -0
- package/components/motion/combobox/context.tsx +359 -0
- package/components/motion/combobox/list.tsx +222 -0
- package/components/motion/combobox/trigger.tsx +191 -0
- package/components/motion/combobox/use-active-option.ts +130 -0
- package/components/motion/combobox.tsx +33 -0
- package/components/motion/command-palette.tsx +381 -0
- package/components/motion/confetti.tsx +128 -0
- package/components/motion/context-menu.tsx +790 -0
- package/components/motion/copy-button.tsx +103 -0
- package/components/motion/cylinder-carousel.tsx +459 -0
- package/components/motion/date-range-picker.tsx +218 -0
- package/components/motion/digit-swap.tsx +125 -0
- package/components/motion/dock.tsx +113 -0
- package/components/motion/drawer.tsx +108 -0
- package/components/motion/dynamic-island.tsx +221 -0
- package/components/motion/error-shake.tsx +66 -0
- package/components/motion/event-calendar.tsx +224 -0
- package/components/motion/expandable-action-bar.tsx +412 -0
- package/components/motion/expandable-control.tsx +254 -0
- package/components/motion/expandable-tabs.tsx +444 -0
- package/components/motion/expanding-arrow-button.tsx +171 -0
- package/components/motion/feedback-widget.tsx +473 -0
- package/components/motion/file-tree.tsx +429 -0
- package/components/motion/file-upload.tsx +606 -0
- package/components/motion/filter-builder.tsx +283 -0
- package/components/motion/frame.tsx +116 -0
- package/components/motion/gantt.tsx +156 -0
- package/components/motion/glow-button.tsx +101 -0
- package/components/motion/haptic-pressable.tsx +107 -0
- package/components/motion/hold-action-button.tsx +279 -0
- package/components/motion/hover-card.tsx +118 -0
- package/components/motion/icon-stack.tsx +138 -0
- package/components/motion/infinite-masonry.tsx +349 -0
- package/components/motion/input.tsx +242 -0
- package/components/motion/kanban.tsx +255 -0
- package/components/motion/kbd.tsx +127 -0
- package/components/motion/knockout-bracket.tsx +909 -0
- package/components/motion/knockout-wheel.tsx +1112 -0
- package/components/motion/liquid.tsx +351 -0
- package/components/motion/loader.tsx +616 -0
- package/components/motion/magnet-dock.tsx +117 -0
- package/components/motion/magnetic.tsx +50 -0
- package/components/motion/marquee.tsx +66 -0
- package/components/motion/metric-card.tsx +116 -0
- package/components/motion/morphing-modal.tsx +160 -0
- package/components/motion/morphing-search.tsx +643 -0
- package/components/motion/morphing-tabs.tsx +940 -0
- package/components/motion/multi-select/content.tsx +164 -0
- package/components/motion/multi-select/context.tsx +381 -0
- package/components/motion/multi-select/index.tsx +33 -0
- package/components/motion/multi-select/list.tsx +239 -0
- package/components/motion/multi-select/trigger.tsx +262 -0
- package/components/motion/not-found/glitch.tsx +107 -0
- package/components/motion/not-found/index.tsx +11 -0
- package/components/motion/not-found/magnetic.tsx +57 -0
- package/components/motion/not-found/shared.tsx +96 -0
- package/components/motion/not-found/spotlight.tsx +86 -0
- package/components/motion/not-found/stacked.tsx +77 -0
- package/components/motion/not-found/terminal.tsx +83 -0
- package/components/motion/notification-stack.tsx +380 -0
- package/components/motion/number-field.tsx +178 -0
- package/components/motion/number-ticker.tsx +185 -0
- package/components/motion/otp-input.tsx +392 -0
- package/components/motion/overflow-actions.tsx +375 -0
- package/components/motion/page-transition.tsx +92 -0
- package/components/motion/pagination.tsx +163 -0
- package/components/motion/parallax.tsx +64 -0
- package/components/motion/password-input.tsx +165 -0
- package/components/motion/phone-input.tsx +181 -0
- package/components/motion/popover-morph.tsx +317 -0
- package/components/motion/popover-position.ts +86 -0
- package/components/motion/popover.tsx +694 -0
- package/components/motion/prediction-market.tsx +682 -0
- package/components/motion/preview-rail.tsx +390 -0
- package/components/motion/progress-ring.tsx +115 -0
- package/components/motion/project-folder.tsx +418 -0
- package/components/motion/pull-to-refresh.tsx +522 -0
- package/components/motion/radio.tsx +148 -0
- package/components/motion/range-slider.tsx +93 -0
- package/components/motion/rating.tsx +171 -0
- package/components/motion/reorder-grid.tsx +123 -0
- package/components/motion/resizable-panel.tsx +160 -0
- package/components/motion/scroll-progress.tsx +127 -0
- package/components/motion/scroll-reveal.tsx +60 -0
- package/components/motion/scroll-to.tsx +48 -0
- package/components/motion/segmented-control.tsx +130 -0
- package/components/motion/segmented-progress.tsx +128 -0
- package/components/motion/select.tsx +440 -0
- package/components/motion/shader-background.tsx +134 -0
- package/components/motion/shared-layout-bg.tsx +151 -0
- package/components/motion/signup-form.tsx +467 -0
- package/components/motion/slide-action-button.tsx +203 -0
- package/components/motion/smooth-scroll.tsx +264 -0
- package/components/motion/sortable-list.tsx +98 -0
- package/components/motion/speed-dial.tsx +144 -0
- package/components/motion/split-text.tsx +115 -0
- package/components/motion/spotlight-card.tsx +89 -0
- package/components/motion/stepper.tsx +127 -0
- package/components/motion/success-check.tsx +142 -0
- package/components/motion/swap/constants.ts +2 -0
- package/components/motion/swap/controls.tsx +201 -0
- package/components/motion/swap/data.ts +186 -0
- package/components/motion/swap/field.tsx +115 -0
- package/components/motion/swap/quote-row.tsx +46 -0
- package/components/motion/swap/token-badges.tsx +83 -0
- package/components/motion/swap/token-picker.tsx +219 -0
- package/components/motion/swap/types.ts +20 -0
- package/components/motion/swap/utils.ts +28 -0
- package/components/motion/swap.tsx +182 -0
- package/components/motion/swipeable-list.tsx +507 -0
- package/components/motion/switch.tsx +96 -0
- package/components/motion/table/editable-cell.tsx +22 -0
- package/components/motion/table/index.tsx +431 -0
- package/components/motion/table/row-handle.tsx +81 -0
- package/components/motion/table/skeleton-rows.tsx +39 -0
- package/components/motion/table/table-header.tsx +344 -0
- package/components/motion/table/table-menu.tsx +129 -0
- package/components/motion/table/types.ts +86 -0
- package/components/motion/table/use-column-reorder.ts +105 -0
- package/components/motion/table/use-column-resize.ts +81 -0
- package/components/motion/table/use-column-sort.ts +64 -0
- package/components/motion/table/use-row-selection.ts +59 -0
- package/components/motion/table/utils.ts +33 -0
- package/components/motion/tabs.tsx +207 -0
- package/components/motion/text-cascade.tsx +22 -0
- package/components/motion/text-reveal.tsx +143 -0
- package/components/motion/text-scramble.tsx +84 -0
- package/components/motion/text-shimmer.tsx +34 -0
- package/components/motion/text-swap.tsx +56 -0
- package/components/motion/theme-toggle.tsx +210 -0
- package/components/motion/tilt-card.tsx +68 -0
- package/components/motion/timeline.tsx +236 -0
- package/components/motion/toggle-group.tsx +128 -0
- package/components/motion/tooltip.tsx +297 -0
- package/components/motion/tree-view.tsx +200 -0
- package/components/motion/wallet-card/account-avatar.tsx +21 -0
- package/components/motion/wallet-card/account-switcher.tsx +199 -0
- package/components/motion/wallet-card/actions.tsx +59 -0
- package/components/motion/wallet-card/balance-delta.tsx +69 -0
- package/components/motion/wallet-card/constants.ts +18 -0
- package/components/motion/wallet-card/copy-button.tsx +58 -0
- package/components/motion/wallet-card/index.tsx +151 -0
- package/components/motion/wallet-card/search-bar.tsx +198 -0
- package/components/motion/wallet-card/types.ts +34 -0
- package/components/motion/wallet-card/utils.ts +9 -0
- package/components/motion/wheel-picker.tsx +610 -0
- package/components/notifications/apple-notification-banner.tsx +155 -0
- package/components/notifications/calendar-reminder-notification-banner.tsx +138 -0
- package/components/notifications/chat-bubble-notification-banner.tsx +136 -0
- package/components/notifications/delivery-notification-banner.tsx +126 -0
- package/components/notifications/deploy-notification-banner.tsx +140 -0
- package/components/notifications/email-notification-banner.tsx +148 -0
- package/components/notifications/incoming-call-notification-banner.tsx +144 -0
- package/components/notifications/payment-notification-banner.tsx +137 -0
- package/components/notifications/system-alert-banner.tsx +137 -0
- package/components/notifications/toast-notification-banner.tsx +130 -0
- package/components/others/progress-ring-card.tsx +217 -0
- package/components/others/stacked-cards-effect.tsx +62 -0
- package/components/others/terminal-log-card.tsx +107 -0
- package/components/others/thermal-receipt-card.tsx +132 -0
- package/components/others/weather-snapshot-card.tsx +124 -0
- package/components/otp/otp-boxed-input.tsx +482 -0
- package/components/otp/otp-underline-input.tsx +356 -0
- package/components/previews/agents/agent-activity.preview.tsx +136 -0
- package/components/previews/agents/ai-sidebar.preview.tsx +236 -0
- package/components/previews/agents/chat-app-usage.tsx +689 -0
- package/components/previews/agents/chat-app.preview.tsx +130 -0
- package/components/previews/agents/chat-preview.tsx +285 -0
- package/components/previews/agents/citations.preview.tsx +78 -0
- package/components/previews/agents/code-block.preview.tsx +67 -0
- package/components/previews/agents/file-diff.preview.tsx +64 -0
- package/components/previews/agents/image-generation.preview.tsx +117 -0
- package/components/previews/agents/message-bubble.preview.tsx +12 -0
- package/components/previews/agents/message-scroller.preview.tsx +70 -0
- package/components/previews/agents/message.preview.tsx +14 -0
- package/components/previews/agents/prompt-input.preview.tsx +145 -0
- package/components/previews/agents/streaming-response.preview.tsx +156 -0
- package/components/previews/agents/todo-list.preview.tsx +73 -0
- package/components/previews/agents/tool-approval.preview.tsx +80 -0
- package/components/previews/agents/use-tool-result-demo.ts +28 -0
- package/components/previews/blocks/availability-scheduler.preview.tsx +11 -0
- package/components/previews/blocks/bloom-menu.preview.tsx +11 -0
- package/components/previews/blocks/card-folder.preview.tsx +105 -0
- package/components/previews/blocks/command-palette.preview.tsx +40 -0
- package/components/previews/blocks/dynamic-island.preview.tsx +150 -0
- package/components/previews/blocks/expandable-action-bar.preview.tsx +136 -0
- package/components/previews/blocks/expandable-tabs.preview.tsx +136 -0
- package/components/previews/blocks/feedback-widget.preview.tsx +34 -0
- package/components/previews/blocks/file-upload.preview.tsx +175 -0
- package/components/previews/blocks/infinite-masonry.preview.tsx +145 -0
- package/components/previews/blocks/knockout-bracket.preview.tsx +43 -0
- package/components/previews/blocks/morphing-search.preview.tsx +59 -0
- package/components/previews/blocks/morphing-tabs.preview.tsx +91 -0
- package/components/previews/blocks/notification-stack.preview.tsx +39 -0
- package/components/previews/blocks/otp-input.preview.tsx +29 -0
- package/components/previews/blocks/overflow-actions.preview.tsx +51 -0
- package/components/previews/blocks/prediction-market.preview.tsx +41 -0
- package/components/previews/blocks/project-folder.preview.tsx +41 -0
- package/components/previews/blocks/signup-form.preview.tsx +36 -0
- package/components/previews/blocks/swap.preview.tsx +11 -0
- package/components/previews/blocks/swipeable-list.preview.tsx +149 -0
- package/components/previews/blocks/wallet-card.preview.tsx +36 -0
- package/components/previews/motion/action-swap.preview.tsx +82 -0
- package/components/previews/motion/adaptive-stepper.preview.tsx +20 -0
- package/components/previews/motion/animated-badge.preview.tsx +43 -0
- package/components/previews/motion/animated-sidebar.preview.tsx +269 -0
- package/components/previews/motion/animated-toast-stack.preview.tsx +151 -0
- package/components/previews/motion/bottom-sheet.preview.tsx +35 -0
- package/components/previews/motion/bounce-sidebar.preview.tsx +30 -0
- package/components/previews/motion/bouncy-accordion.preview.tsx +66 -0
- package/components/previews/motion/center-morph-modal.preview.tsx +75 -0
- package/components/previews/motion/checkbox.preview.tsx +26 -0
- package/components/previews/motion/combobox.preview.tsx +119 -0
- package/components/previews/motion/context-menu.preview.tsx +144 -0
- package/components/previews/motion/cylinder-carousel.preview.tsx +96 -0
- package/components/previews/motion/dock.preview.tsx +46 -0
- package/components/previews/motion/drawer.preview.tsx +46 -0
- package/components/previews/motion/expandable-control.preview.tsx +27 -0
- package/components/previews/motion/expanding-arrow-button.preview.tsx +11 -0
- package/components/previews/motion/file-tree.preview.tsx +67 -0
- package/components/previews/motion/input.preview.tsx +55 -0
- package/components/previews/motion/loader.preview.tsx +36 -0
- package/components/previews/motion/marquee.preview.tsx +22 -0
- package/components/previews/motion/morphing-modal.preview.tsx +184 -0
- package/components/previews/motion/multi-select.preview.tsx +73 -0
- package/components/previews/motion/number.preview.tsx +61 -0
- package/components/previews/motion/popover.preview.tsx +53 -0
- package/components/previews/motion/preview-rail.preview.tsx +108 -0
- package/components/previews/motion/pull-to-refresh.preview.tsx +117 -0
- package/components/previews/motion/radio.preview.tsx +17 -0
- package/components/previews/motion/range-slider.preview.tsx +19 -0
- package/components/previews/motion/select.preview.tsx +29 -0
- package/components/previews/motion/shader-background.preview.tsx +308 -0
- package/components/previews/motion/shared-layout-bg.preview.tsx +33 -0
- package/components/previews/motion/switch.preview.tsx +15 -0
- package/components/previews/motion/table.preview.tsx +140 -0
- package/components/previews/motion/tabs.preview.tsx +49 -0
- package/components/previews/motion/text-animation.preview.tsx +63 -0
- package/components/previews/motion/theme-toggle.preview.tsx +28 -0
- package/components/previews/motion/tilt-card.preview.tsx +15 -0
- package/components/previews/motion/tooltip.preview.tsx +34 -0
- package/components/previews/motion/wheel-picker.preview.tsx +91 -0
- package/components/pricing/retail-price-tag-card.tsx +104 -0
- package/components/pricing/toggle-pricing-cards.tsx +209 -0
- package/components/profile/contact-profile-card.tsx +100 -0
- package/components/profile/editorial-staff-profile-card.tsx +79 -0
- package/components/profile/team-member-profile-grid.tsx +159 -0
- package/components/profile/user-profile-card.tsx +125 -0
- package/components/resources/resource-links-panel.tsx +176 -0
- package/components/socials/discord-chat-card.tsx +157 -0
- package/components/socials/facebook-post-card.tsx +198 -0
- package/components/socials/github-contribution.tsx +716 -0
- package/components/socials/github-repo-card.tsx +111 -0
- package/components/socials/instagram-post-card.tsx +204 -0
- package/components/socials/linked-in-post-card.tsx +213 -0
- package/components/socials/linked-in-profile-card.tsx +173 -0
- package/components/socials/threads-post-card.tsx +162 -0
- package/components/socials/twitter-post-card.tsx +184 -0
- package/components/socials/twitter-profile-card.tsx +180 -0
- package/components/system/loaders/index.ts +1 -0
- package/components/system/loaders/page-loader-overlay.tsx +16 -0
- package/components/table/customers-table.tsx +146 -0
- package/components/table/orders-table.tsx +195 -0
- package/components/table/recent-transactions-table.tsx +125 -0
- package/components/table/tasks-table.tsx +163 -0
- package/components/table/team-members-table.tsx +155 -0
- package/components/table/users-select-table.tsx +184 -0
- package/components/text/cafe-menu-board-card.tsx +101 -0
- package/components/text/cinema-ticket-card.tsx +99 -0
- package/components/text/daily-motivation-card.tsx +80 -0
- package/components/text/denim-product-editorial-card.tsx +101 -0
- package/components/text/drop-cap-editorial-card.tsx +54 -0
- package/components/text/editorial-quote-card.tsx +98 -0
- package/components/text/journal-writing-card.tsx +131 -0
- package/components/text/keyboard-shortcuts-card.tsx +92 -0
- package/components/text/magazine-cover-card.tsx +109 -0
- package/components/text/notepad-card.tsx +95 -0
- package/components/travel/flight-boarding-card.tsx +177 -0
- package/components/travel/travel-postcard-card.tsx +96 -0
- package/components/underlines/annotated-text-showcase.tsx +37 -0
- package/components/underlines/annotated-text.tsx +471 -0
- package/components/users/credit-card-glass.tsx +113 -0
- package/components/users/team-member-card.tsx +50 -0
- package/components/users/testimonial-card.tsx +239 -0
- package/components/wallet/wallet-pass-card.tsx +220 -0
- package/components/widgets/analog-clock-widget.tsx +203 -0
- package/components/widgets/audio-recorder-widget.tsx +87 -0
- package/components/widgets/battery-face-widget.tsx +152 -0
- package/components/widgets/blob-profile.tsx +64 -0
- package/components/widgets/bluetooth-face-widget.tsx +125 -0
- package/components/widgets/compass-widget.tsx +296 -0
- package/components/widgets/daily-activity-calendar-widget.tsx +133 -0
- package/components/widgets/dnd-face-widget.tsx +129 -0
- package/components/widgets/electric-scooter-widget.tsx +88 -0
- package/components/widgets/flight-arrival-widget.tsx +76 -0
- package/components/widgets/focus-breath-widget.tsx +71 -0
- package/components/widgets/heart-rate-widget.tsx +93 -0
- package/components/widgets/hydration-widget.tsx +109 -0
- package/components/widgets/ios-calendar-widget.tsx +87 -0
- package/components/widgets/ios-digital-clock-widget.tsx +192 -0
- package/components/widgets/ios-earbuds-widget.tsx +120 -0
- package/components/widgets/ios-map-location-widget.tsx +133 -0
- package/components/widgets/minimal-agenda-widget.tsx +123 -0
- package/components/widgets/pomodoro-widget.tsx +155 -0
- package/components/widgets/recorder-face-widget.tsx +146 -0
- package/components/widgets/ride-pickup-widget.tsx +72 -0
- package/components/widgets/sleep-score-widget.tsx +107 -0
- package/components/widgets/step-count-widget.tsx +53 -0
- package/components/widgets/stopwatch-widget.tsx +176 -0
- package/components/widgets/torch-face-widget.tsx +128 -0
- package/components/widgets/voice-assistant-widget.tsx +103 -0
- package/components/widgets/wifi-toggle-widget.tsx +108 -0
- package/lib/cn.ts +1 -0
- package/lib/ease.ts +108 -0
- package/lib/favicon.ts +8 -0
- package/lib/hooks/use-dismiss.ts +120 -0
- package/lib/hooks/use-favicon.ts +39 -0
- package/lib/hooks/use-haptic.ts +44 -0
- package/lib/hooks/use-hover-capable.ts +23 -0
- package/lib/hooks/use-hover-gesture.ts +61 -0
- package/lib/hooks/use-in-view-animation.ts +35 -0
- package/lib/hooks/use-measure.ts +39 -0
- package/lib/hooks/use-on-open.ts +24 -0
- package/lib/hooks/use-row-cursor.ts +86 -0
- package/lib/hooks/use-slider.ts +176 -0
- package/lib/hooks/use-tap-gesture.ts +66 -0
- package/lib/hooks/use-touch-capable.ts +31 -0
- package/lib/presence-gate.tsx +52 -0
- package/lib/styles.ts +124 -0
- package/lib/text-shimmer.ts +21 -0
- package/lib/tick-sound.ts +151 -0
- package/lib/touch.ts +117 -0
- package/lib/utils.ts +6 -0
- package/package.json +49 -0
- package/references/agents/agent-activity.md +747 -0
- package/references/agents/ai-sidebar.md +293 -0
- package/references/agents/approval-card.md +233 -0
- package/references/agents/chat-app.md +184 -0
- package/references/agents/citations.md +159 -0
- package/references/agents/code-block.md +122 -0
- package/references/agents/file-diff.md +119 -0
- package/references/agents/image-generation.md +173 -0
- package/references/agents/loading-states.md +186 -0
- package/references/agents/message-bubble.md +274 -0
- package/references/agents/message-scroller.md +128 -0
- package/references/agents/message.md +162 -0
- package/references/agents/prompt-input.md +204 -0
- package/references/agents/streaming-response.md +216 -0
- package/references/agents/todo-list.md +123 -0
- package/references/agents/tool-approval.md +143 -0
- package/references/agents/tool-result.md +199 -0
- package/references/blocks/availability-scheduler.md +59 -0
- package/references/blocks/bloom-menu.md +56 -0
- package/references/blocks/card-folder.md +165 -0
- package/references/blocks/command-palette.md +89 -0
- package/references/blocks/dynamic-island.md +203 -0
- package/references/blocks/expandable-action-bar.md +191 -0
- package/references/blocks/expandable-tabs.md +184 -0
- package/references/blocks/feedback-widget.md +82 -0
- package/references/blocks/file-upload.md +406 -0
- package/references/blocks/infinite-masonry.md +211 -0
- package/references/blocks/knockout-bracket.md +161 -0
- package/references/blocks/morphing-search.md +113 -0
- package/references/blocks/morphing-tabs.md +143 -0
- package/references/blocks/not-found.md +228 -0
- package/references/blocks/notification-stack.md +92 -0
- package/references/blocks/otp-input.md +85 -0
- package/references/blocks/overflow-actions.md +105 -0
- package/references/blocks/prediction-market.md +97 -0
- package/references/blocks/project-folder.md +99 -0
- package/references/blocks/signup-form.md +92 -0
- package/references/blocks/swap.md +58 -0
- package/references/blocks/swipeable-list.md +202 -0
- package/references/blocks/wallet-card.md +97 -0
- package/references/codex-install.md +59 -0
- package/references/craft/3d-button.md +51 -0
- package/references/craft/3d-icon-button.md +51 -0
- package/references/craft/add-to-cart-button.md +52 -0
- package/references/craft/analog-clock-minimal.md +51 -0
- package/references/craft/analog-clock-numeric.md +51 -0
- package/references/craft/analog-clock-roman.md +51 -0
- package/references/craft/annotated-text.md +51 -0
- package/references/craft/app-dock.md +52 -0
- package/references/craft/apple-hello-loader.md +51 -0
- package/references/craft/apple-notification.md +53 -0
- package/references/craft/apple-watch.md +51 -0
- package/references/craft/arc-bands-background.md +51 -0
- package/references/craft/audio-recorder.md +52 -0
- package/references/craft/aurora-background.md +51 -0
- package/references/craft/battery-face.md +52 -0
- package/references/craft/blob-profile.md +53 -0
- package/references/craft/bluetooth-face.md +52 -0
- package/references/craft/booking-slot-calendar.md +52 -0
- package/references/craft/bookmark-save-button.md +52 -0
- package/references/craft/browser.md +51 -0
- package/references/craft/cafe-menu-board.md +52 -0
- package/references/craft/calendar-reminder-notification.md +52 -0
- package/references/craft/chat-bubble-notification.md +53 -0
- package/references/craft/checkbox-field-input.md +52 -0
- package/references/craft/cherry-petal-background.md +51 -0
- package/references/craft/cinder-latch-button.md +51 -0
- package/references/craft/cinema-ticket.md +52 -0
- package/references/craft/circle-cut-frame.md +51 -0
- package/references/craft/combobox-field-input.md +52 -0
- package/references/craft/compass.md +51 -0
- package/references/craft/contact-form.md +52 -0
- package/references/craft/contact-profile.md +52 -0
- package/references/craft/copy-email.md +53 -0
- package/references/craft/coral-glow-background.md +51 -0
- package/references/craft/craft-copy-button.md +52 -0
- package/references/craft/craft-signup-form.md +53 -0
- package/references/craft/credit-card-glass.md +51 -0
- package/references/craft/customers-table.md +52 -0
- package/references/craft/daily-activity-calendar.md +52 -0
- package/references/craft/daily-motivation.md +53 -0
- package/references/craft/dark-arc-bands-background.md +51 -0
- package/references/craft/dark-aurora-background.md +51 -0
- package/references/craft/dark-carbon-spotlight-background.md +51 -0
- package/references/craft/dark-ember-background.md +51 -0
- package/references/craft/dark-ink-field-background.md +51 -0
- package/references/craft/dark-midnight-mesh-background.md +51 -0
- package/references/craft/dark-rose-noir-background.md +51 -0
- package/references/craft/dark-teal-depth-background.md +51 -0
- package/references/craft/date-field-input.md +52 -0
- package/references/craft/date-range-picker-card.md +52 -0
- package/references/craft/delivery-notification.md +52 -0
- package/references/craft/denim-product-editorial.md +52 -0
- package/references/craft/deploy-notification.md +52 -0
- package/references/craft/depth-outline-button.md +51 -0
- package/references/craft/diagonal-box-pattern.md +51 -0
- package/references/craft/dimple-switch.md +51 -0
- package/references/craft/discord-chat.md +53 -0
- package/references/craft/dnd-face.md +52 -0
- package/references/craft/dot-grid-pattern.md +51 -0
- package/references/craft/download-button.md +52 -0
- package/references/craft/drop-cap-editorial.md +52 -0
- package/references/craft/editor-tool-dock.md +52 -0
- package/references/craft/editorial-quote.md +52 -0
- package/references/craft/editorial-staff-profile.md +51 -0
- package/references/craft/electric-scooter.md +53 -0
- package/references/craft/email-notification.md +53 -0
- package/references/craft/event-countdown-card.md +51 -0
- package/references/craft/event-ticket.md +53 -0
- package/references/craft/facebook-post.md +53 -0
- package/references/craft/file-menu.md +52 -0
- package/references/craft/file-upload-field-input.md +52 -0
- package/references/craft/film-strip.md +52 -0
- package/references/craft/filter-sort.md +52 -0
- package/references/craft/fine-grain-pattern.md +51 -0
- package/references/craft/flight-arrival.md +52 -0
- package/references/craft/flight-boarding.md +52 -0
- package/references/craft/floating-label-field-input.md +51 -0
- package/references/craft/focus-breath.md +51 -0
- package/references/craft/folder-tab-card.md +52 -0
- package/references/craft/follow-button.md +52 -0
- package/references/craft/forgot-password-form.md +53 -0
- package/references/craft/frost-mesh-background.md +51 -0
- package/references/craft/gallery-grid.md +53 -0
- package/references/craft/gallery-wall.md +52 -0
- package/references/craft/github-contribution.md +52 -0
- package/references/craft/github-repo.md +52 -0
- package/references/craft/glass-overlay-image.md +53 -0
- package/references/craft/graph-paper-pattern.md +51 -0
- package/references/craft/halftone-pop-background.md +51 -0
- package/references/craft/hard-shadow-polaroid-frame.md +51 -0
- package/references/craft/heart-rate.md +52 -0
- package/references/craft/hold-to-delete-button.md +52 -0
- package/references/craft/honey-ember-background.md +51 -0
- package/references/craft/hydration.md +51 -0
- package/references/craft/incoming-call-notification.md +53 -0
- package/references/craft/ink-stamp-document.md +52 -0
- package/references/craft/ink-wash-background.md +51 -0
- package/references/craft/input-group-field.md +51 -0
- package/references/craft/inset-button.md +51 -0
- package/references/craft/instagram-post.md +53 -0
- package/references/craft/ios-calendar-widget.md +51 -0
- package/references/craft/ios-digital-clock.md +51 -0
- package/references/craft/ios-earbuds.md +51 -0
- package/references/craft/ios-map-location.md +51 -0
- package/references/craft/ipad.md +51 -0
- package/references/craft/ipod.md +51 -0
- package/references/craft/journal-writing.md +52 -0
- package/references/craft/kebab-actions.md +52 -0
- package/references/craft/keyboard-shortcuts.md +52 -0
- package/references/craft/laptop.md +51 -0
- package/references/craft/like-button.md +52 -0
- package/references/craft/line-grid-pattern.md +51 -0
- package/references/craft/linen-tab-button.md +51 -0
- package/references/craft/linen-weave-background.md +51 -0
- package/references/craft/linked-in-post.md +53 -0
- package/references/craft/linked-in-profile.md +52 -0
- package/references/craft/login-form.md +53 -0
- package/references/craft/mac-dock.md +52 -0
- package/references/craft/magazine-cover.md +53 -0
- package/references/craft/minimal-agenda.md +52 -0
- package/references/craft/mint-lagoon-background.md +51 -0
- package/references/craft/month-picker-calendar.md +52 -0
- package/references/craft/museum-placard.md +51 -0
- package/references/craft/music-player.md +53 -0
- package/references/craft/music-playlist.md +53 -0
- package/references/craft/newsletter-form.md +52 -0
- package/references/craft/notepad.md +52 -0
- package/references/craft/notification.md +52 -0
- package/references/craft/now-playing-bar.md +53 -0
- package/references/craft/orders-table.md +52 -0
- package/references/craft/otp-boxed-input.md +52 -0
- package/references/craft/otp-underline-input.md +51 -0
- package/references/craft/page-loader-overlay.md +46 -0
- package/references/craft/paper-fold-background.md +51 -0
- package/references/craft/password-field-input.md +52 -0
- package/references/craft/payment-notification.md +52 -0
- package/references/craft/phone-field-input.md +51 -0
- package/references/craft/phone.md +51 -0
- package/references/craft/photo-album.md +52 -0
- package/references/craft/photo-contact-sheet.md +52 -0
- package/references/craft/polaroid-image.md +52 -0
- package/references/craft/pomodoro.md +52 -0
- package/references/craft/presence-dock.md +51 -0
- package/references/craft/prism-depth-button.md +51 -0
- package/references/craft/progress-ring-card.md +51 -0
- package/references/craft/quantity-stepper-button.md +52 -0
- package/references/craft/radio-group-field-input.md +51 -0
- package/references/craft/rain-prism-background.md +51 -0
- package/references/craft/recent-transactions-table.md +52 -0
- package/references/craft/recorder-face.md +52 -0
- package/references/craft/resource-links-panel.md +52 -0
- package/references/craft/retail-price-tag.md +51 -0
- package/references/craft/reverse-diagonal-box-pattern.md +51 -0
- package/references/craft/ride-pickup.md +53 -0
- package/references/craft/sand-drift-background.md +51 -0
- package/references/craft/search-input.md +52 -0
- package/references/craft/segmented-toggle-button.md +51 -0
- package/references/craft/select-field-input.md +52 -0
- package/references/craft/share-menu.md +52 -0
- package/references/craft/sheen-pill-button.md +51 -0
- package/references/craft/slate-chip-switch.md +51 -0
- package/references/craft/sleep-score.md +52 -0
- package/references/craft/slide-to-confirm-button.md +52 -0
- package/references/craft/slow-living-polaroid.md +52 -0
- package/references/craft/soft-pill-button.md +51 -0
- package/references/craft/soft-spotlight-background.md +51 -0
- package/references/craft/soft-ui-button.md +51 -0
- package/references/craft/spin-loader.md +52 -0
- package/references/craft/spotlight-bar.md +52 -0
- package/references/craft/stacked-cards-effect.md +52 -0
- package/references/craft/stacked-folder-card.md +52 -0
- package/references/craft/stamp-postcard.md +52 -0
- package/references/craft/step-count.md +51 -0
- package/references/craft/sticky-note-polaroid-frame.md +51 -0
- package/references/craft/stopwatch.md +52 -0
- package/references/craft/sunrise-horizon-background.md +51 -0
- package/references/craft/sunset-bloom-background.md +51 -0
- package/references/craft/switch-field-input.md +51 -0
- package/references/craft/system-alert.md +52 -0
- package/references/craft/tasks-table.md +53 -0
- package/references/craft/team-member-profile-grid.md +52 -0
- package/references/craft/team-member.md +53 -0
- package/references/craft/team-members-table.md +53 -0
- package/references/craft/terminal-log.md +52 -0
- package/references/craft/terrazzo-fragment-background.md +51 -0
- package/references/craft/testimonial.md +53 -0
- package/references/craft/text-field-input.md +51 -0
- package/references/craft/text-loader.md +51 -0
- package/references/craft/textarea-field-input.md +51 -0
- package/references/craft/thermal-receipt.md +52 -0
- package/references/craft/threads-post.md +53 -0
- package/references/craft/toast-notification.md +52 -0
- package/references/craft/toggle-pricing-cards.md +52 -0
- package/references/craft/torch-face.md +52 -0
- package/references/craft/transform-box-frame.md +51 -0
- package/references/craft/transform-plus-frame.md +51 -0
- package/references/craft/travel-postcard.md +53 -0
- package/references/craft/tropical-tide-background.md +51 -0
- package/references/craft/twitter-post.md +53 -0
- package/references/craft/twitter-profile.md +53 -0
- package/references/craft/user-menu.md +53 -0
- package/references/craft/user-profile.md +53 -0
- package/references/craft/users-select-table.md +53 -0
- package/references/craft/voice-assistant.md +52 -0
- package/references/craft/wallet-pass.md +52 -0
- package/references/craft/weather-snapshot.md +52 -0
- package/references/craft/week-strip-calendar.md +52 -0
- package/references/craft/wifi-toggle.md +52 -0
- package/references/craft/workspace-switcher.md +52 -0
- package/references/guides/baseline-ui-craft.md +61 -0
- package/references/guides/craft-surface-design-system.md +120 -0
- package/references/guides/design-system-checklist.md +98 -0
- package/references/guides/enterprise-dashboard-patterns.md +53 -0
- package/references/guides/interaction-transitions.md +71 -0
- package/references/guides/motion-engineering.md +137 -0
- package/references/guides/motion-patterns.md +106 -0
- package/references/guides/motion-performance.md +66 -0
- package/references/guides/style-presets.md +115 -0
- package/references/guides/universal-mobile-patterns.md +72 -0
- package/references/motion/action-sheet.md +98 -0
- package/references/motion/action-swap.md +339 -0
- package/references/motion/adaptive-stepper.md +95 -0
- package/references/motion/animated-badge.md +92 -0
- package/references/motion/animated-sidebar.md +446 -0
- package/references/motion/animated-toast-stack.md +214 -0
- package/references/motion/aspect-ratio.md +59 -0
- package/references/motion/audio-player.md +59 -0
- package/references/motion/autocomplete.md +69 -0
- package/references/motion/avatar-group.md +93 -0
- package/references/motion/bottom-sheet.md +85 -0
- package/references/motion/bounce-sidebar.md +80 -0
- package/references/motion/bouncy-accordion.md +115 -0
- package/references/motion/breadcrumb.md +62 -0
- package/references/motion/button.md +271 -0
- package/references/motion/card-resize.md +60 -0
- package/references/motion/cascader.md +99 -0
- package/references/motion/center-morph-modal.md +133 -0
- package/references/motion/checkbox.md +76 -0
- package/references/motion/chip.md +81 -0
- package/references/motion/collapsible.md +73 -0
- package/references/motion/color-picker.md +57 -0
- package/references/motion/combobox.md +247 -0
- package/references/motion/confetti.md +65 -0
- package/references/motion/context-menu.md +269 -0
- package/references/motion/copy-button.md +59 -0
- package/references/motion/cylinder-carousel.md +151 -0
- package/references/motion/date-range-picker.md +68 -0
- package/references/motion/dock.md +105 -0
- package/references/motion/drawer.md +94 -0
- package/references/motion/error-shake.md +85 -0
- package/references/motion/event-calendar.md +81 -0
- package/references/motion/expandable-control.md +89 -0
- package/references/motion/expanding-arrow-button.md +178 -0
- package/references/motion/file-tree.md +139 -0
- package/references/motion/filter-builder.md +106 -0
- package/references/motion/frame.md +61 -0
- package/references/motion/gantt.md +61 -0
- package/references/motion/glow-button.md +59 -0
- package/references/motion/haptic-pressable.md +64 -0
- package/references/motion/hover-card.md +86 -0
- package/references/motion/icon-stack.md +64 -0
- package/references/motion/input.md +108 -0
- package/references/motion/kanban.md +111 -0
- package/references/motion/kbd.md +66 -0
- package/references/motion/loader.md +82 -0
- package/references/motion/magnet-dock.md +64 -0
- package/references/motion/marquee.md +68 -0
- package/references/motion/metric-card.md +81 -0
- package/references/motion/morphing-modal.md +230 -0
- package/references/motion/multi-select.md +202 -0
- package/references/motion/number-field.md +70 -0
- package/references/motion/number.md +198 -0
- package/references/motion/page-transition.md +78 -0
- package/references/motion/pagination.md +64 -0
- package/references/motion/password-input.md +77 -0
- package/references/motion/phone-input.md +63 -0
- package/references/motion/popover.md +209 -0
- package/references/motion/preview-rail.md +165 -0
- package/references/motion/progress-ring.md +73 -0
- package/references/motion/pull-to-refresh.md +172 -0
- package/references/motion/radio.md +73 -0
- package/references/motion/range-slider.md +290 -0
- package/references/motion/rating.md +69 -0
- package/references/motion/reorder-grid.md +69 -0
- package/references/motion/resizable-panel.md +75 -0
- package/references/motion/scroll-animation.md +397 -0
- package/references/motion/segmented-control.md +68 -0
- package/references/motion/segmented-progress.md +70 -0
- package/references/motion/select.md +196 -0
- package/references/motion/shader-background.md +351 -0
- package/references/motion/shared-layout-bg.md +80 -0
- package/references/motion/sortable-list.md +62 -0
- package/references/motion/speed-dial.md +63 -0
- package/references/motion/split-text.md +62 -0
- package/references/motion/spotlight-card.md +67 -0
- package/references/motion/stepper.md +83 -0
- package/references/motion/success-check.md +67 -0
- package/references/motion/switch.md +62 -0
- package/references/motion/table.md +519 -0
- package/references/motion/tabs.md +116 -0
- package/references/motion/text-animation.md +285 -0
- package/references/motion/text-swap.md +64 -0
- package/references/motion/theme-toggle.md +82 -0
- package/references/motion/tilt-card.md +59 -0
- package/references/motion/timeline.md +85 -0
- package/references/motion/toggle-group.md +70 -0
- package/references/motion/tooltip.md +82 -0
- package/references/motion/tree-view.md +87 -0
- package/references/motion/wheel-picker.md +142 -0
- package/scripts/build_docs.py +557 -0
- package/scripts/install-component.py +232 -0
- package/scripts/test_release.py +119 -0
- package/scripts/updater.mjs +9 -0
- package/scripts/verify_skill.py +84 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useLayoutEffect, useRef, useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Where the keyboard or the pointer last moved to: the row's id, stamped with
|
|
7
|
+
* the query it was placed under.
|
|
8
|
+
*/
|
|
9
|
+
type RowCursor = { id: string; query: string };
|
|
10
|
+
|
|
11
|
+
/** The cursor's row, or -1 once the query has moved on or the row has left. */
|
|
12
|
+
function indexOfCursor(
|
|
13
|
+
rows: readonly { id: string }[],
|
|
14
|
+
query: string,
|
|
15
|
+
cursor: RowCursor | null,
|
|
16
|
+
) {
|
|
17
|
+
if (cursor === null || cursor.query !== query) return -1;
|
|
18
|
+
return rows.findIndex((row) => row.id === cursor.id);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The highlighted row of a list whose rows can change under it.
|
|
23
|
+
*
|
|
24
|
+
* Which row is highlighted is resolved during render, never in a passive
|
|
25
|
+
* effect: a passive effect runs after the commit, so a list that had just
|
|
26
|
+
* changed would carry an `aria-activedescendant` naming a row that has left it,
|
|
27
|
+
* and a key pressed in that window would commit the wrong row or nothing at
|
|
28
|
+
* all.
|
|
29
|
+
*
|
|
30
|
+
* The cursor holds the row's id, not its position. A position alone cannot tell
|
|
31
|
+
* a list that shrank from one that swapped its rows for a different set of the
|
|
32
|
+
* same length, and the second case is the one that silently hands Enter to a
|
|
33
|
+
* row the user never chose. A cursor whose row has left the list returns the
|
|
34
|
+
* highlight to the first row rather than to the nearest surviving one: the row
|
|
35
|
+
* the user aimed at is gone, and the first row is where a new query already
|
|
36
|
+
* puts the highlight.
|
|
37
|
+
*
|
|
38
|
+
* Pass the query the list is filtered by. The cursor is stamped with it and
|
|
39
|
+
* dropped when it changes, so a caller cannot forget to clear it — including a
|
|
40
|
+
* caller whose query arrives as a prop and so never runs its own handler. Rows
|
|
41
|
+
* that come back under a query that has moved on cannot revive it either.
|
|
42
|
+
* `moveTo(null)` is for deliberate resets, such as reopening the list.
|
|
43
|
+
*
|
|
44
|
+
* Both callbacks keep one identity for the life of the component, and read the
|
|
45
|
+
* rows and the query through a ref to do it. A caller will put them in an
|
|
46
|
+
* effect's dependencies — the exhaustive-deps rule makes it — and a `moveTo`
|
|
47
|
+
* rebuilt on every keystroke would re-run that effect on every keystroke.
|
|
48
|
+
*/
|
|
49
|
+
export function useRowCursor(rows: readonly { id: string }[], query: string) {
|
|
50
|
+
const [cursor, setCursor] = useState<RowCursor | null>(null);
|
|
51
|
+
// Written after commit, not during render: a render React discards or has not
|
|
52
|
+
// finished still runs the component body, and an event handler that read this
|
|
53
|
+
// in that window would stamp the cursor with a query the committed tree does
|
|
54
|
+
// not have.
|
|
55
|
+
const latest = useRef({ rows, query });
|
|
56
|
+
useLayoutEffect(() => {
|
|
57
|
+
latest.current = { rows, query };
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const cursorRow = indexOfCursor(rows, query, cursor);
|
|
61
|
+
// Cleared rather than ignored: React re-runs this render with the cursor
|
|
62
|
+
// already gone, so rows that come back cannot revive a highlight the user has
|
|
63
|
+
// stopped aiming at.
|
|
64
|
+
if (cursor !== null && cursorRow < 0) setCursor(null);
|
|
65
|
+
|
|
66
|
+
const moveTo = useCallback(
|
|
67
|
+
(id: string | null) =>
|
|
68
|
+
setCursor(id === null ? null : { id, query: latest.current.query }),
|
|
69
|
+
[],
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const moveActive = useCallback((direction: 1 | -1) => {
|
|
73
|
+
const { rows: live, query: liveQuery } = latest.current;
|
|
74
|
+
const last = live.length - 1;
|
|
75
|
+
if (last < 0) return;
|
|
76
|
+
// Steps from the row the cursor is really on, inside the update, so that
|
|
77
|
+
// two keys landing in one batch move two rows rather than one.
|
|
78
|
+
setCursor((current) => {
|
|
79
|
+
const at = Math.max(indexOfCursor(live, liveQuery, current), 0);
|
|
80
|
+
const next = Math.min(Math.max(at + direction, 0), last);
|
|
81
|
+
return { id: live[next].id, query: liveQuery };
|
|
82
|
+
});
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
return { activeIndex: cursorRow < 0 ? 0 : cursorRow, moveTo, moveActive };
|
|
86
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type KeyboardEvent, type PointerEvent, useCallback, useRef, useState } from "react";
|
|
4
|
+
import { capturePointer, releasePointer } from "@/lib/touch";
|
|
5
|
+
|
|
6
|
+
const clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));
|
|
7
|
+
|
|
8
|
+
/** Nearest legal value on [min, max] for the given step. max counts as a
|
|
9
|
+
* candidate when the step does not divide the range, so a pointer near the end
|
|
10
|
+
* does not snap back onto the last whole step. */
|
|
11
|
+
export function snapSliderValue(next: number, min: number, max: number, step: number): number {
|
|
12
|
+
// Neither case has a grid to walk. An empty range has exactly one legal
|
|
13
|
+
// point, and a non-positive step only needs a clamp, which also keeps the
|
|
14
|
+
// division below away from zero.
|
|
15
|
+
if (!(max > min)) return min;
|
|
16
|
+
if (!(step > 0)) return clamp(next, min, max);
|
|
17
|
+
const whole = Math.floor(Number(((max - min) / step).toFixed(6)));
|
|
18
|
+
const lastWhole = Number((min + whole * step).toFixed(6));
|
|
19
|
+
const toGrid = clamp(Math.round((next - min) / step) * step + min, min, lastWhole);
|
|
20
|
+
const snapped =
|
|
21
|
+
lastWhole < max && Math.abs(next - max) <= Math.abs(next - toGrid) ? max : toGrid;
|
|
22
|
+
return Number(snapped.toFixed(6));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface SliderOptions {
|
|
26
|
+
value?: number;
|
|
27
|
+
defaultValue?: number;
|
|
28
|
+
onValueChange?: (value: number) => void;
|
|
29
|
+
min?: number;
|
|
30
|
+
max?: number;
|
|
31
|
+
step?: number;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
"aria-label"?: string;
|
|
34
|
+
/** Announced instead of the raw number — pass one when the value carries a
|
|
35
|
+
* unit or a suffix ("72.5 kg", "35%"); a bare number needs no valueText. */
|
|
36
|
+
formatValueText?: (value: number) => string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Shared value + input plumbing for slider designs: controlled/uncontrolled
|
|
41
|
+
* value, step snapping, pointer-capture drag along a track and arrow-key
|
|
42
|
+
* control. Visuals and motion live in the component; this only owns the number.
|
|
43
|
+
*/
|
|
44
|
+
export function useSlider({
|
|
45
|
+
value,
|
|
46
|
+
defaultValue = 0,
|
|
47
|
+
onValueChange,
|
|
48
|
+
min = 0,
|
|
49
|
+
max = 100,
|
|
50
|
+
step = 1,
|
|
51
|
+
disabled = false,
|
|
52
|
+
"aria-label": ariaLabel,
|
|
53
|
+
formatValueText,
|
|
54
|
+
}: SliderOptions) {
|
|
55
|
+
const trackRef = useRef<HTMLDivElement>(null);
|
|
56
|
+
const sliderEl = useRef<HTMLElement | null>(null);
|
|
57
|
+
// The state drives visuals. Move reads this ref instead, so the first
|
|
58
|
+
// pointermove after pointerdown does not have to wait on a re-render.
|
|
59
|
+
const draggingRef = useRef(false);
|
|
60
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
61
|
+
const [dragging, setDragging] = useState(false);
|
|
62
|
+
const controlled = value !== undefined;
|
|
63
|
+
// Collapse inverted or empty ranges and non-positive steps here, so that
|
|
64
|
+
// percent, ticks and the keyboard maths never divide by zero or walk a
|
|
65
|
+
// NaN grid.
|
|
66
|
+
const lo = min;
|
|
67
|
+
const hi = max > min ? max : min;
|
|
68
|
+
const stride = step > 0 ? step : 1;
|
|
69
|
+
const current = clamp(controlled ? value : internal, lo, hi);
|
|
70
|
+
const percent = hi > lo ? ((current - lo) / (hi - lo)) * 100 : 0;
|
|
71
|
+
|
|
72
|
+
const commit = useCallback(
|
|
73
|
+
(next: number) => {
|
|
74
|
+
const clean = snapSliderValue(next, lo, hi, stride);
|
|
75
|
+
if (!controlled) setInternal(clean);
|
|
76
|
+
onValueChange?.(clean);
|
|
77
|
+
},
|
|
78
|
+
[controlled, onValueChange, lo, hi, stride],
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const commitFromX = useCallback(
|
|
82
|
+
(clientX: number) => {
|
|
83
|
+
const rect = trackRef.current?.getBoundingClientRect();
|
|
84
|
+
if (!rect || rect.width === 0) return;
|
|
85
|
+
const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);
|
|
86
|
+
commit(lo + ratio * (hi - lo));
|
|
87
|
+
},
|
|
88
|
+
[commit, lo, hi],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const onPointerDown = useCallback(
|
|
92
|
+
(event: PointerEvent<HTMLDivElement>) => {
|
|
93
|
+
if (disabled) return;
|
|
94
|
+
// Start the drag first: capture is a convenience, and a browser that
|
|
95
|
+
// refuses it — or a test DOM that has no pointer capture at all — must
|
|
96
|
+
// not take the drag down with it.
|
|
97
|
+
draggingRef.current = true;
|
|
98
|
+
setDragging(true);
|
|
99
|
+
capturePointer(event.currentTarget, event.pointerId);
|
|
100
|
+
// A click on the track should land keyboard focus on the handle.
|
|
101
|
+
sliderEl.current?.focus({ preventScroll: true });
|
|
102
|
+
commitFromX(event.clientX);
|
|
103
|
+
},
|
|
104
|
+
[disabled, commitFromX],
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const onPointerMove = useCallback(
|
|
108
|
+
(event: PointerEvent<HTMLDivElement>) => {
|
|
109
|
+
if (!draggingRef.current || disabled) return;
|
|
110
|
+
commitFromX(event.clientX);
|
|
111
|
+
},
|
|
112
|
+
[disabled, commitFromX],
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const endDrag = useCallback((event: PointerEvent<HTMLDivElement>) => {
|
|
116
|
+
releasePointer(event.currentTarget, event.pointerId);
|
|
117
|
+
draggingRef.current = false;
|
|
118
|
+
setDragging(false);
|
|
119
|
+
}, []);
|
|
120
|
+
|
|
121
|
+
const onKeyDown = useCallback(
|
|
122
|
+
(event: KeyboardEvent<HTMLElement>) => {
|
|
123
|
+
if (disabled) return;
|
|
124
|
+
const map: Record<string, number> = {
|
|
125
|
+
ArrowRight: current + stride,
|
|
126
|
+
ArrowUp: current + stride,
|
|
127
|
+
ArrowLeft: current - stride,
|
|
128
|
+
ArrowDown: current - stride,
|
|
129
|
+
PageUp: current + stride * 10,
|
|
130
|
+
PageDown: current - stride * 10,
|
|
131
|
+
Home: lo,
|
|
132
|
+
End: hi,
|
|
133
|
+
};
|
|
134
|
+
if (event.key in map) {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
commit(map[event.key]);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
[disabled, current, stride, lo, hi, commit],
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
current,
|
|
144
|
+
percent,
|
|
145
|
+
dragging,
|
|
146
|
+
min: lo,
|
|
147
|
+
max: hi,
|
|
148
|
+
step: stride,
|
|
149
|
+
commit,
|
|
150
|
+
/** Pointer handlers for the track element — drag anywhere on it. */
|
|
151
|
+
trackProps: {
|
|
152
|
+
ref: trackRef,
|
|
153
|
+
onPointerDown,
|
|
154
|
+
onPointerMove,
|
|
155
|
+
onPointerUp: endDrag,
|
|
156
|
+
onPointerCancel: endDrag,
|
|
157
|
+
onLostPointerCapture: endDrag,
|
|
158
|
+
},
|
|
159
|
+
/** ARIA + keyboard props for the focusable slider element. */
|
|
160
|
+
sliderProps: {
|
|
161
|
+
// Callback keeps the handle typed across button/div/motion hosts.
|
|
162
|
+
ref: (node: HTMLElement | null) => {
|
|
163
|
+
sliderEl.current = node;
|
|
164
|
+
},
|
|
165
|
+
role: "slider" as const,
|
|
166
|
+
tabIndex: disabled ? -1 : 0,
|
|
167
|
+
"aria-label": ariaLabel,
|
|
168
|
+
"aria-valuemin": lo,
|
|
169
|
+
"aria-valuemax": hi,
|
|
170
|
+
"aria-valuenow": current,
|
|
171
|
+
"aria-valuetext": formatValueText?.(current),
|
|
172
|
+
"aria-disabled": disabled || undefined,
|
|
173
|
+
onKeyDown,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo, useRef } from "react";
|
|
4
|
+
|
|
5
|
+
/** What a pointerdown recorded, read back by the click that ends its gesture. */
|
|
6
|
+
export interface TapRecord<S> {
|
|
7
|
+
/** Which input started the gesture. */
|
|
8
|
+
pointerType: string;
|
|
9
|
+
/** What the surface was showing when it started. */
|
|
10
|
+
state: S;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TapGesture<S> {
|
|
14
|
+
/** Record the gesture a pointerdown starts, with the state it starts in. */
|
|
15
|
+
start: (event: { pointerType: string }, state: S) => void;
|
|
16
|
+
/** Read the record and clear it. `null` when no pointer is behind this click. */
|
|
17
|
+
take: () => TapRecord<S> | null;
|
|
18
|
+
/** Drop the record: this gesture will never spend it on a click. */
|
|
19
|
+
drop: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The pointer gesture behind a click, recorded where the click cannot report
|
|
24
|
+
* it. A `click` carries no `pointerType` in the engines that matter, so the
|
|
25
|
+
* `pointerdown` before it is the only thing that says which input activated
|
|
26
|
+
* the control — and whether one did at all, since keyboard activation
|
|
27
|
+
* synthesizes a click with no pointer behind it.
|
|
28
|
+
*
|
|
29
|
+
* State goes in with the record because a click reports that no better: a
|
|
30
|
+
* browser that focuses a control on contact can open the very panel the tap
|
|
31
|
+
* was meant to open, and reading "is it open" at click time then undoes it.
|
|
32
|
+
* What the gesture started against is what it acts on.
|
|
33
|
+
*
|
|
34
|
+
* The record is spent by one click and dropped by everything else, because a
|
|
35
|
+
* record that outlives its gesture is worse than none:
|
|
36
|
+
*
|
|
37
|
+
* - A scroll or an OS gesture takes the touch away — `pointercancel`, no click
|
|
38
|
+
* ever — and the finger would sit in the record until some later click.
|
|
39
|
+
* - That later click is often `Enter` on a keyboard, which arrives with no
|
|
40
|
+
* pointerdown of its own and would inherit the abandoned finger. A keydown
|
|
41
|
+
* is the start of a keyboard activation and never part of a tap, so it drops
|
|
42
|
+
* the record too.
|
|
43
|
+
*
|
|
44
|
+
* Both ends have to be wired by the surface: `drop` on `onPointerCancel` and
|
|
45
|
+
* on `onKeyDown`.
|
|
46
|
+
*/
|
|
47
|
+
export function useTapGesture<S>(): TapGesture<S> {
|
|
48
|
+
const record = useRef<TapRecord<S> | null>(null);
|
|
49
|
+
|
|
50
|
+
return useMemo(
|
|
51
|
+
() => ({
|
|
52
|
+
start: (event, state) => {
|
|
53
|
+
record.current = { pointerType: event.pointerType, state };
|
|
54
|
+
},
|
|
55
|
+
take: () => {
|
|
56
|
+
const spent = record.current;
|
|
57
|
+
record.current = null;
|
|
58
|
+
return spent;
|
|
59
|
+
},
|
|
60
|
+
drop: () => {
|
|
61
|
+
record.current = null;
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
[],
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns true on devices that can be touched, whatever else they claim.
|
|
7
|
+
*
|
|
8
|
+
* This is not the inverse of `useHoverCapable`: iPadOS Safari browses
|
|
9
|
+
* desktop-class and answers `(hover: hover) and (pointer: fine)` with true
|
|
10
|
+
* while a finger is the only input there is, so anything that treats
|
|
11
|
+
* hover-capable as "no touch here" strands every iPad. Gate the *touch path*
|
|
12
|
+
* of an interaction on this hook and leave hover-only polish on
|
|
13
|
+
* `useHoverCapable`, so a component that opens on hover also opens on tap.
|
|
14
|
+
*/
|
|
15
|
+
export function useTouchCapable() {
|
|
16
|
+
const [canTouch, setCanTouch] = useState(false);
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (typeof window === "undefined") return;
|
|
20
|
+
const mq = window.matchMedia?.("(any-pointer: coarse)");
|
|
21
|
+
// iPadOS disguises its pointer media queries; maxTouchPoints it reports
|
|
22
|
+
// honestly, which is what makes it the standard iPad tell.
|
|
23
|
+
const update = () =>
|
|
24
|
+
setCanTouch(Boolean(mq?.matches) || navigator.maxTouchPoints > 0);
|
|
25
|
+
update();
|
|
26
|
+
mq?.addEventListener?.("change", update);
|
|
27
|
+
return () => mq?.removeEventListener?.("change", update);
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
return canTouch;
|
|
31
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useIsPresent } from "motion/react";
|
|
4
|
+
import type { ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
export interface PresenceGateRenderProps {
|
|
7
|
+
/**
|
|
8
|
+
* False from the render that starts the exit animation onward. An overlay
|
|
9
|
+
* kept in the tree by `AnimatePresence` is still the topmost thing on the
|
|
10
|
+
* page, so anything it decides from `open` alone stays true for the whole
|
|
11
|
+
* exit — this is the boolean that already knows the overlay is leaving.
|
|
12
|
+
*/
|
|
13
|
+
isPresent: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Spread onto every layer that takes pointer events while the overlay is
|
|
16
|
+
* open. Interaction releases in the same commit that starts the exit while
|
|
17
|
+
* the visual exit keeps playing: pointer events stop landing, and `inert`
|
|
18
|
+
* drops the subtree from focus order, from tab order and from the
|
|
19
|
+
* accessibility tree — an exiting dialog is not a dialog you can still type
|
|
20
|
+
* into. A layer that never takes pointer events (a wrapper that only centres
|
|
21
|
+
* the panel) takes `inert={!isPresent}` alone, so its own
|
|
22
|
+
* `pointer-events-none` is not overwritten.
|
|
23
|
+
*/
|
|
24
|
+
gate: {
|
|
25
|
+
inert: boolean;
|
|
26
|
+
style: { pointerEvents: "auto" | "none" };
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PresenceGateProps {
|
|
31
|
+
children: (props: PresenceGateRenderProps) => ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reads the presence of the subtree it renders and hands it down.
|
|
36
|
+
*
|
|
37
|
+
* `useIsPresent` only answers inside the `AnimatePresence` subtree, and the
|
|
38
|
+
* components that own an overlay render the `AnimatePresence` themselves, so
|
|
39
|
+
* the boolean has to be read one component further down: this is that
|
|
40
|
+
* component, and the render prop is how it reaches the layers.
|
|
41
|
+
*/
|
|
42
|
+
export function PresenceGate({ children }: PresenceGateProps) {
|
|
43
|
+
const isPresent = useIsPresent();
|
|
44
|
+
|
|
45
|
+
return children({
|
|
46
|
+
isPresent,
|
|
47
|
+
gate: {
|
|
48
|
+
inert: !isPresent,
|
|
49
|
+
style: { pointerEvents: isPresent ? "auto" : "none" },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
package/lib/styles.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Motion UI - Multi-Style Presets & Aesthetic Themes
|
|
3
|
+
*
|
|
4
|
+
* Provides canonical style presets across 6 distinct design aesthetics:
|
|
5
|
+
* - `minimal`: Clean, monochrome, flat surfaces, subtle borders (shadcn / Vercel style)
|
|
6
|
+
* - `origin`: High-craft, micro-elevation, fine inner border glows, dark luxury (Coss / Cal.com style)
|
|
7
|
+
* - `enterprise`: High information density, compact paddings, structured hierarchy (KeenThemes ReUI style)
|
|
8
|
+
* - `glow`: Luminous radial glows, metallic beam accents, dark ambient highlights (ibelick style)
|
|
9
|
+
* - `ios`: Fluid liquid curves, translucent backdrop blur, tactile bounce, haptics (Expo / Apple style)
|
|
10
|
+
* - `brutalist`: 2px/3px solid black borders, hard offset shadows, high contrast retro (Neo-brutalist style)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { SPRING_BOUNCE, SPRING_GENTLE, SPRING_PRESS, SPRING_SNAPPY, type SpringConfig } from "./ease";
|
|
14
|
+
|
|
15
|
+
export type StylePreset =
|
|
16
|
+
| "minimal"
|
|
17
|
+
| "origin"
|
|
18
|
+
| "enterprise"
|
|
19
|
+
| "glow"
|
|
20
|
+
| "ios"
|
|
21
|
+
| "brutalist";
|
|
22
|
+
|
|
23
|
+
export interface StyleTokens {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
card: string;
|
|
27
|
+
buttonPrimary: string;
|
|
28
|
+
buttonSecondary: string;
|
|
29
|
+
buttonGhost: string;
|
|
30
|
+
input: string;
|
|
31
|
+
badge: string;
|
|
32
|
+
panel: string;
|
|
33
|
+
radius: string;
|
|
34
|
+
spring: SpringConfig;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const STYLE_PRESETS: Record<StylePreset, StyleTokens> = {
|
|
38
|
+
minimal: {
|
|
39
|
+
name: "Minimal",
|
|
40
|
+
description: "Clean monochrome typography, flat card surfaces, crisp 1px borders, and zero-distraction layout.",
|
|
41
|
+
card: "rounded-xl border border-border bg-card text-card-foreground shadow-none",
|
|
42
|
+
buttonPrimary: "rounded-lg bg-foreground text-background font-medium hover:bg-foreground/90 transition-colors shadow-sm",
|
|
43
|
+
buttonSecondary: "rounded-lg border border-border bg-background text-foreground font-medium hover:bg-muted/60 transition-colors",
|
|
44
|
+
buttonGhost: "rounded-lg text-foreground hover:bg-muted font-medium transition-colors",
|
|
45
|
+
input: "rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:border-foreground focus:ring-1 focus:ring-foreground/20",
|
|
46
|
+
badge: "rounded-md border border-border bg-muted/50 px-2 py-0.5 text-xs font-medium text-foreground",
|
|
47
|
+
panel: "rounded-xl border border-border bg-card shadow-lg",
|
|
48
|
+
radius: "rounded-lg",
|
|
49
|
+
spring: SPRING_PRESS,
|
|
50
|
+
},
|
|
51
|
+
origin: {
|
|
52
|
+
name: "Origin (High-Craft)",
|
|
53
|
+
description: "Subtle gradients, micro-elevation, fine inner specular borders, refined typography, and precision focus rings.",
|
|
54
|
+
card: "rounded-2xl border border-border/70 bg-gradient-to-b from-card to-card/90 p-5 shadow-sm ring-1 ring-white/5 backdrop-blur-sm",
|
|
55
|
+
buttonPrimary: "rounded-xl bg-primary text-primary-foreground font-semibold shadow-[0_1px_2px_rgba(0,0,0,0.1),0_0_0_1px_rgba(255,255,255,0.1)_inset] hover:brightness-105 active:scale-[0.98] transition-all",
|
|
56
|
+
buttonSecondary: "rounded-xl border border-border/80 bg-card/80 text-foreground font-medium shadow-sm hover:bg-muted/70 active:scale-[0.98] transition-all",
|
|
57
|
+
buttonGhost: "rounded-xl text-muted-foreground hover:text-foreground hover:bg-muted/60 font-medium transition-all",
|
|
58
|
+
input: "rounded-xl border border-border/80 bg-card/70 px-3.5 py-2 text-sm text-foreground placeholder:text-muted-foreground/80 shadow-inner focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all",
|
|
59
|
+
badge: "rounded-full border border-primary/20 bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary shadow-[0_1px_2px_0_rgb(0_0_0_/_0.05)]",
|
|
60
|
+
panel: "rounded-2xl border border-border/80 bg-card/95 p-4 shadow-xl ring-1 ring-white/10 backdrop-blur-md",
|
|
61
|
+
radius: "rounded-xl",
|
|
62
|
+
spring: SPRING_SNAPPY,
|
|
63
|
+
},
|
|
64
|
+
enterprise: {
|
|
65
|
+
name: "Enterprise (Dense ReUI)",
|
|
66
|
+
description: "High data-density, compact spacing, clear semantic contrast, sharp geometry, and functional clarity.",
|
|
67
|
+
card: "rounded-lg border border-border bg-card p-4 shadow-[0_1px_2px_0_rgb(0_0_0_/_0.05)]",
|
|
68
|
+
buttonPrimary: "rounded-md bg-primary text-primary-foreground text-xs font-semibold px-3 py-1.5 hover:bg-primary/90 transition-colors",
|
|
69
|
+
buttonSecondary: "rounded-md border border-border bg-secondary text-secondary-foreground text-xs font-medium px-3 py-1.5 hover:bg-muted transition-colors",
|
|
70
|
+
buttonGhost: "rounded-md text-foreground text-xs hover:bg-muted px-2.5 py-1.5 transition-colors",
|
|
71
|
+
input: "rounded-md border border-border bg-background px-2.5 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:border-primary focus:ring-1 focus:ring-primary",
|
|
72
|
+
badge: "rounded border border-border bg-muted px-1.5 py-0.5 text-[11px] font-semibold text-foreground tracking-tight",
|
|
73
|
+
panel: "rounded-lg border border-border bg-card p-3 shadow-md",
|
|
74
|
+
radius: "rounded-md",
|
|
75
|
+
spring: SPRING_PRESS,
|
|
76
|
+
},
|
|
77
|
+
glow: {
|
|
78
|
+
name: "Luminous Glow",
|
|
79
|
+
description: "Deep dark canvases with radial gradient halos, spotlight cursor highlights, and cyan/purple border beams.",
|
|
80
|
+
card: "relative rounded-2xl border border-border/60 bg-gradient-to-b from-card/80 to-card/40 p-6 shadow-2xl backdrop-blur-xl overflow-hidden before:absolute before:inset-0 before:bg-[radial-gradient(circle_at_50%_0%,rgba(59,130,246,0.15),transparent_70%)]",
|
|
81
|
+
buttonPrimary: "rounded-xl bg-gradient-to-r from-blue-600 to-indigo-600 text-white font-medium shadow-[0_0_20px_rgba(79,70,229,0.4)] hover:shadow-[0_0_25px_rgba(79,70,229,0.6)] hover:brightness-110 active:scale-[0.98] transition-all",
|
|
82
|
+
buttonSecondary: "rounded-xl border border-blue-500/30 bg-card/60 text-foreground font-medium shadow-[0_0_15px_rgba(59,130,246,0.15)] hover:border-blue-500/50 hover:bg-card active:scale-[0.98] transition-all",
|
|
83
|
+
buttonGhost: "rounded-xl text-foreground/80 hover:text-white hover:bg-white/10 font-medium transition-colors",
|
|
84
|
+
input: "rounded-xl border border-border/80 bg-background/60 px-3.5 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 backdrop-blur-md shadow-[0_0_15px_rgba(59,130,246,0.1)]",
|
|
85
|
+
badge: "rounded-full border border-blue-500/40 bg-blue-500/10 px-3 py-0.5 text-xs font-medium text-blue-400 shadow-[0_0_10px_rgba(59,130,246,0.2)]",
|
|
86
|
+
panel: "rounded-2xl border border-border/60 bg-card/90 p-5 shadow-[0_0_40px_rgba(0,0,0,0.5)] backdrop-blur-2xl ring-1 ring-white/10",
|
|
87
|
+
radius: "rounded-2xl",
|
|
88
|
+
spring: SPRING_GENTLE,
|
|
89
|
+
},
|
|
90
|
+
ios: {
|
|
91
|
+
name: "iOS Liquid",
|
|
92
|
+
description: "Deep rounded squircle corners, translucent blurred glass surfaces, tactile spring bounce, and touch-first layout.",
|
|
93
|
+
card: "rounded-3xl border border-white/20 dark:border-white/10 bg-white/70 dark:bg-zinc-900/70 p-5 shadow-xl backdrop-blur-2xl",
|
|
94
|
+
buttonPrimary: "rounded-2xl bg-blue-500 text-white font-semibold py-2.5 px-4 shadow-md hover:bg-blue-600 active:scale-95 transition-transform",
|
|
95
|
+
buttonSecondary: "rounded-2xl bg-zinc-200/80 dark:bg-zinc-800/80 text-foreground font-semibold py-2.5 px-4 backdrop-blur-lg hover:bg-zinc-300 dark:hover:bg-zinc-700 active:scale-95 transition-transform",
|
|
96
|
+
buttonGhost: "rounded-2xl text-blue-500 font-semibold hover:bg-blue-500/10 px-3 py-2 transition-colors active:scale-95",
|
|
97
|
+
input: "rounded-2xl border border-black/5 dark:border-white/10 bg-zinc-100/80 dark:bg-zinc-800/80 px-4 py-3 text-sm text-foreground placeholder:text-muted-foreground backdrop-blur-xl focus:outline-none focus:ring-2 focus:ring-blue-500/40",
|
|
98
|
+
badge: "rounded-full bg-zinc-200 dark:bg-zinc-800 px-3 py-1 text-xs font-semibold text-foreground",
|
|
99
|
+
panel: "rounded-3xl border border-white/20 dark:border-white/10 bg-white/85 dark:bg-zinc-900/85 p-6 shadow-2xl backdrop-blur-3xl",
|
|
100
|
+
radius: "rounded-3xl",
|
|
101
|
+
spring: SPRING_BOUNCE,
|
|
102
|
+
},
|
|
103
|
+
brutalist: {
|
|
104
|
+
name: "Neo-Brutalist",
|
|
105
|
+
description: "Bold 2px black outlines, high-contrast flat fills, hard 4px offset drop-shadows, and assertive tactile press shifts.",
|
|
106
|
+
card: "rounded-none border-2 border-foreground bg-background p-5 shadow-[4px_4px_0px_0px_currentColor] text-foreground",
|
|
107
|
+
buttonPrimary: "rounded-none border-2 border-foreground bg-primary text-primary-foreground font-bold px-4 py-2 shadow-[3px_3px_0px_0px_currentColor] hover:translate-x-[1px] hover:translate-y-[1px] hover:shadow-[2px_2px_0px_0px_currentColor] active:translate-x-[3px] active:translate-y-[3px] active:shadow-none transition-all",
|
|
108
|
+
buttonSecondary: "rounded-none border-2 border-foreground bg-background text-foreground font-bold px-4 py-2 shadow-[3px_3px_0px_0px_currentColor] hover:translate-x-[1px] hover:translate-y-[1px] hover:shadow-[2px_2px_0px_0px_currentColor] active:translate-x-[3px] active:translate-y-[3px] active:shadow-none transition-all",
|
|
109
|
+
buttonGhost: "rounded-none text-foreground font-bold hover:bg-foreground hover:text-background px-3 py-2 transition-colors",
|
|
110
|
+
input: "rounded-none border-2 border-foreground bg-background px-3 py-2 text-sm font-medium text-foreground placeholder:text-muted-foreground shadow-[2px_2px_0px_0px_currentColor] focus:outline-none focus:shadow-[4px_4px_0px_0px_currentColor]",
|
|
111
|
+
badge: "rounded-none border-2 border-foreground bg-yellow-300 text-black px-2 py-0.5 text-xs font-black uppercase tracking-wider",
|
|
112
|
+
panel: "rounded-none border-[3px] border-foreground bg-background p-5 shadow-[6px_6px_0px_0px_currentColor]",
|
|
113
|
+
radius: "rounded-none",
|
|
114
|
+
spring: SPRING_PRESS,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Returns the StyleTokens object for the specified preset.
|
|
120
|
+
* Defaults to "origin" (high-craft) if unspecified.
|
|
121
|
+
*/
|
|
122
|
+
export function getStylePreset(preset?: StylePreset): StyleTokens {
|
|
123
|
+
return STYLE_PRESETS[preset || "origin"] || STYLE_PRESETS.origin;
|
|
124
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
// The reduced-motion rule travels with the component. app/globals.css calms CSS
|
|
4
|
+
// animation globally, but the registry bundles imports only, so an installed
|
|
5
|
+
// copy never receives that reset.
|
|
6
|
+
//
|
|
7
|
+
// `!important` because the sweep is an inline style, which outranks a plain rule
|
|
8
|
+
// in a media query. It selects a marker class carried by TEXT_SHIMMER_CLASS_NAME
|
|
9
|
+
// so it also reaches consumers that build their own span out of these exports.
|
|
10
|
+
export const TEXT_SHIMMER_KEYFRAMES =
|
|
11
|
+
"@keyframes motion-text-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}" +
|
|
12
|
+
"@media (prefers-reduced-motion: reduce){.motion-text-shimmer{animation:none !important}}";
|
|
13
|
+
|
|
14
|
+
export const TEXT_SHIMMER_CLASS_NAME =
|
|
15
|
+
"motion-text-shimmer bg-[length:200%_100%] bg-clip-text text-transparent bg-[linear-gradient(110deg,var(--muted-foreground)_30%,var(--foreground)_50%,var(--muted-foreground)_70%)]";
|
|
16
|
+
|
|
17
|
+
export function textShimmerStyle(duration: number): CSSProperties {
|
|
18
|
+
return {
|
|
19
|
+
animation: `motion-text-shimmer ${duration}s linear infinite`,
|
|
20
|
+
};
|
|
21
|
+
}
|