@heyramzi/ui 0.0.0-stage → 1.53.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/COMPONENTS.md +133 -0
- package/README.md +136 -2
- package/package.json +217 -3
- package/scripts/lib/sync-core.mjs +113 -0
- package/scripts/relative-imports.mjs +39 -0
- package/scripts/sf-symbol.mjs +93 -0
- package/scripts/sync-shadcn.mjs +354 -0
- package/scripts/sync-transitions.mjs +146 -0
- package/scripts/validate-apple-symbol-exports.mjs +45 -0
- package/src/agents/agent-avatar.svelte +592 -0
- package/src/agents/agent-cast.svelte +197 -0
- package/src/agents/demo.svelte +125 -0
- package/src/agents/helpers.ts +58 -0
- package/src/agents/index.ts +11 -0
- package/src/agents/page-state.ts +70 -0
- package/src/agents/types.ts +74 -0
- package/src/agents/vendor/LICENSE +21 -0
- package/src/agents/vendor/color.ts +155 -0
- package/src/agents/vendor/draw.ts +840 -0
- package/src/agents/vendor/engine.ts +845 -0
- package/src/agents/vendor/mesh.ts +838 -0
- package/src/agents/vendor/plastic.ts +4958 -0
- package/src/agents/vendor/presets.ts +103 -0
- package/src/agents/vendor/shapes.ts +41 -0
- package/src/agents/vendor/ticker.ts +67 -0
- package/src/agents/vendor/types.ts +261 -0
- package/src/agents/vendor/wear.ts +1699 -0
- package/src/ai/ai-button/AiButton.svelte +86 -0
- package/src/ai/ai-button/index.ts +4 -0
- package/src/ai/confirmation/Confirmation.svelte +54 -0
- package/src/ai/confirmation/ConfirmationAccepted.svelte +23 -0
- package/src/ai/confirmation/ConfirmationAction.svelte +53 -0
- package/src/ai/confirmation/ConfirmationActions.svelte +24 -0
- package/src/ai/confirmation/ConfirmationFailed.svelte +23 -0
- package/src/ai/confirmation/ConfirmationRejected.svelte +23 -0
- package/src/ai/confirmation/ConfirmationRequest.svelte +25 -0
- package/src/ai/confirmation/ConfirmationTitle.svelte +25 -0
- package/src/ai/confirmation/confirmation-context.svelte.ts +22 -0
- package/src/ai/confirmation/index.ts +50 -0
- package/src/ai/generation-progress/GenerationProgress.svelte +354 -0
- package/src/ai/generation-progress/index.ts +7 -0
- package/src/ai/index.ts +111 -0
- package/src/ai/loading-state/PixelLoader.svelte +138 -0
- package/src/ai/loading-state/index.ts +5 -0
- package/src/ai/prompt-input/PromptInput.svelte +56 -0
- package/src/ai/prompt-input/PromptInputBody.svelte +19 -0
- package/src/ai/prompt-input/PromptInputSubmit.svelte +79 -0
- package/src/ai/prompt-input/PromptInputTextarea.svelte +74 -0
- package/src/ai/prompt-input/PromptInputToolbar.svelte +19 -0
- package/src/ai/prompt-input/index.ts +34 -0
- package/src/ai/reasoning/Reasoning.svelte +50 -0
- package/src/ai/reasoning/ReasoningContent.svelte +27 -0
- package/src/ai/reasoning/ReasoningTrigger.svelte +48 -0
- package/src/ai/reasoning/index.ts +22 -0
- package/src/ai/reasoning/reasoning-context.svelte.ts +20 -0
- package/src/ai/response/Response.css +32 -0
- package/src/ai/response/Response.svelte +130 -0
- package/src/ai/response/index.ts +5 -0
- package/src/ai/suggestion/Suggestion.svelte +43 -0
- package/src/ai/suggestion/Suggestions.svelte +25 -0
- package/src/ai/suggestion/index.ts +14 -0
- package/src/ai/thinking-dots/ThinkingDots.svelte +42 -0
- package/src/ai/thinking-dots/index.ts +5 -0
- package/src/ai/typing-dots/TypingDots.css +39 -0
- package/src/ai/typing-dots/TypingDots.svelte +27 -0
- package/src/ai/typing-dots/index.ts +10 -0
- package/src/ai/voice-waveform/VoiceWaveform.css +40 -0
- package/src/ai/voice-waveform/VoiceWaveform.svelte +46 -0
- package/src/ai/voice-waveform/index.ts +5 -0
- package/src/ambient.d.ts +4 -0
- package/src/animations/README.md +84 -0
- package/src/animations/avatar-group-hover.css +47 -0
- package/src/animations/card-tilt.css +74 -0
- package/src/animations/digit-pop-in.css +78 -0
- package/src/animations/dropdown.css +121 -0
- package/src/animations/index.css +23 -0
- package/src/animations/input-clear-dissolve.css +86 -0
- package/src/animations/input-shake.css +114 -0
- package/src/animations/learn-more-hover.css +48 -0
- package/src/animations/like-button.css +93 -0
- package/src/animations/modal.css +75 -0
- package/src/animations/page-side-by-side.css +63 -0
- package/src/animations/plus-menu-morph.css +97 -0
- package/src/animations/resize.css +20 -0
- package/src/animations/shimmer-text.css +72 -0
- package/src/animations/spinning-counter.css +52 -0
- package/src/animations/success-check.css +120 -0
- package/src/animations/text-swap.css +40 -0
- package/src/animations/text-swap.ts +40 -0
- package/src/animations/thinking-states.css +65 -0
- package/src/animations/upstream-coverage.test.ts +65 -0
- package/src/components/copy/clipboard.test.ts +206 -0
- package/src/components/copy/clipboard.ts +49 -0
- package/src/components/copy/copied.svelte.ts +39 -0
- package/src/components/copy/copy-button.svelte +175 -0
- package/src/components/copy/copy-button.test.ts +110 -0
- package/src/components/copy/index.ts +3 -0
- package/src/components/data-table/data-table.test.ts +134 -0
- package/src/components/data-table/data-table.ts +77 -0
- package/src/components/data-table/index.ts +20 -0
- package/src/components/data-table/infinite-scroll.svelte +69 -0
- package/src/components/data-table/pagination.svelte +62 -0
- package/src/components/data-table/row-arrow.svelte +28 -0
- package/src/components/data-table/row-context-menu.svelte +106 -0
- package/src/components/data-table/row-context-menu.test.ts +18 -0
- package/src/components/data-table/sortable-head.svelte +56 -0
- package/src/components/data-table/table-skeleton.svelte +83 -0
- package/src/components/hold-to-confirm/hold-to-confirm.svelte +232 -0
- package/src/components/hold-to-confirm/index.ts +1 -0
- package/src/components/icon/icon.svelte +23 -0
- package/src/components/icon/index.ts +1 -0
- package/src/components/language-flag/index.ts +1 -0
- package/src/components/language-flag/language-flag.svelte +60 -0
- package/src/components/list-page/detail-empty.svelte +50 -0
- package/src/components/list-page/detail-header.svelte +107 -0
- package/src/components/list-page/detail-panel.svelte +90 -0
- package/src/components/list-page/detail-row.svelte +36 -0
- package/src/components/list-page/detail-stack.svelte +33 -0
- package/src/components/list-page/empty-state.svelte +91 -0
- package/src/components/list-page/filter-item.svelte +49 -0
- package/src/components/list-page/filter-popover.svelte +88 -0
- package/src/components/list-page/filter-section.ts +12 -0
- package/src/components/list-page/grouped-list.svelte +116 -0
- package/src/components/list-page/index.ts +28 -0
- package/src/components/list-page/list-page-shell.svelte +195 -0
- package/src/components/list-page/list-table.ts +19 -0
- package/src/components/list-page/master-detail.svelte +206 -0
- package/src/components/list-page/master-detail.test.ts +37 -0
- package/src/components/list-page/notice-bar.svelte +68 -0
- package/src/components/list-page/prev-next.svelte +104 -0
- package/src/components/list-page/queue-rail.ts +25 -0
- package/src/components/list-page/rail-body.svelte +29 -0
- package/src/components/list-page/rail-empty.svelte +51 -0
- package/src/components/list-page/rail-head.svelte +49 -0
- package/src/components/list-page/rail-row.svelte +163 -0
- package/src/components/list-page/section-host.ts +24 -0
- package/src/components/list-page/section-label.svelte +39 -0
- package/src/components/list-page/step.test.ts +21 -0
- package/src/components/list-page/step.ts +10 -0
- package/src/components/list-page/toolbar-search.svelte +63 -0
- package/src/components/list-page/toolbar-trigger.ts +23 -0
- package/src/components/list-page/types.ts +1 -0
- package/src/components/locale-switch/index.ts +1 -0
- package/src/components/locale-switch/locale-switch.svelte +59 -0
- package/src/components/mark/index.ts +1 -0
- package/src/components/mark/mark.svelte +70 -0
- package/src/components/open-in/index.ts +6 -0
- package/src/components/open-in/open-in.svelte +106 -0
- package/src/components/picker/index.ts +4 -0
- package/src/components/picker/mark-picker.svelte +84 -0
- package/src/components/picker/picker.svelte +143 -0
- package/src/components/picker/trigger.ts +42 -0
- package/src/components/picker/types.ts +26 -0
- package/src/components/segmented/animated-tabs.svelte +175 -0
- package/src/components/segmented/collapse.test.ts +49 -0
- package/src/components/segmented/collapse.ts +39 -0
- package/src/components/segmented/index.ts +41 -0
- package/src/components/segmented/section-runs.svelte +79 -0
- package/src/components/segmented/segment.svelte +106 -0
- package/src/components/segmented/segmented-filter.svelte +125 -0
- package/src/components/segmented/segmented-nav.svelte +82 -0
- package/src/components/segmented/segmented-overflow.svelte +85 -0
- package/src/components/segmented/segmented-track.svelte +181 -0
- package/src/components/segmented/segmented.test.ts +20 -0
- package/src/components/segmented/segmented.ts +80 -0
- package/src/components/star-rating-input/index.ts +9 -0
- package/src/components/star-rating-input/star-rating-input.svelte +256 -0
- package/src/components/svg/index.ts +1 -0
- package/src/components/svg/svg.svelte +9 -0
- package/src/design/index.css +270 -0
- package/src/design/polish.css +159 -0
- package/src/effects/animated-beam/AnimatedBeam.svelte +132 -0
- package/src/effects/animated-beam/diagrams/BeamSvg.svelte +91 -0
- package/src/effects/animated-beam/index.ts +2 -0
- package/src/effects/animated-beam/path-calculator.svelte.ts +70 -0
- package/src/effects/animated-beam/types.ts +23 -0
- package/src/effects/border-beam/BorderBeam.svelte +223 -0
- package/src/effects/border-beam/css.test.ts +46 -0
- package/src/effects/border-beam/css.ts +574 -0
- package/src/effects/border-beam/presets.ts +699 -0
- package/src/effects/border-beam/register-properties.test.ts +74 -0
- package/src/effects/border-beam/register-properties.ts +73 -0
- package/src/effects/border-beam/types.ts +38 -0
- package/src/effects/image-comparison/ImageComparison.css +100 -0
- package/src/effects/image-comparison/ImageComparison.svelte +209 -0
- package/src/effects/image-comparison/compare.test.ts +17 -0
- package/src/effects/image-comparison/compare.ts +5 -0
- package/src/effects/image-reveal/ImageReveal.css +10 -0
- package/src/effects/image-reveal/ImageReveal.svelte +357 -0
- package/src/effects/image-reveal/index.ts +2 -0
- package/src/effects/image-reveal/types.ts +35 -0
- package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +338 -0
- package/src/effects/magic-card/MagicCard.css +47 -0
- package/src/effects/magic-card/MagicCard.svelte +57 -0
- package/src/effects/magnetic/magnetic.ts +81 -0
- package/src/effects/marquee/Marquee.css +78 -0
- package/src/effects/marquee/Marquee.svelte +160 -0
- package/src/effects/progressive-blur/ProgressiveBlur.css +9 -0
- package/src/effects/progressive-blur/ProgressiveBlur.svelte +63 -0
- package/src/effects/reveal/AnimatedGroup.svelte +101 -0
- package/src/effects/reveal/InView.svelte +77 -0
- package/src/effects/reveal/TextEffect.svelte +142 -0
- package/src/effects/reveal/index.ts +11 -0
- package/src/effects/reveal/observe.test.ts +60 -0
- package/src/effects/reveal/observe.ts +65 -0
- package/src/effects/reveal/reveal.css +141 -0
- package/src/effects/reveal/types.ts +32 -0
- package/src/effects/shader-gradient/ShaderGradient.svelte +227 -0
- package/src/effects/shader-gradient/color.ts +44 -0
- package/src/effects/shader-gradient/index.ts +5 -0
- package/src/effects/shader-gradient/renderer.ts +456 -0
- package/src/effects/shader-gradient/shaders.ts +324 -0
- package/src/effects/shader-gradient/types.ts +68 -0
- package/src/effects/spotlight/Spotlight.css +14 -0
- package/src/effects/spotlight/Spotlight.svelte +61 -0
- package/src/effects/theme-toggle/ThemeToggle.css +214 -0
- package/src/effects/theme-toggle/ThemeToggle.svelte +126 -0
- package/src/gallery.test.ts +52 -0
- package/src/icons/TradeIcon.svelte +16 -0
- package/src/icons/apple-symbol-exports.ts +135 -0
- package/src/icons/sf-symbols.ts +527 -0
- package/src/icons/trades.ts +89 -0
- package/src/index.ts +53 -0
- package/src/lib/arrive.ts +26 -0
- package/src/lib/icon-types.ts +17 -0
- package/src/lib/layout.ts +8 -0
- package/src/lib/panel.ts +21 -0
- package/src/lib/sliding-pill.ts +68 -0
- package/src/lib/theme-transition.ts +79 -0
- package/src/lib/tone.ts +48 -0
- package/src/shadcn/accordion/accordion-content.svelte +22 -0
- package/src/shadcn/accordion/accordion-item.svelte +17 -0
- package/src/shadcn/accordion/accordion-trigger.svelte +44 -0
- package/src/shadcn/accordion/accordion.svelte +19 -0
- package/src/shadcn/accordion/index.ts +16 -0
- package/src/shadcn/alert/alert-description.svelte +23 -0
- package/src/shadcn/alert/alert-title.svelte +20 -0
- package/src/shadcn/alert/alert.svelte +46 -0
- package/src/shadcn/alert/index.ts +14 -0
- package/src/shadcn/alert-dialog/alert-dialog-action.svelte +18 -0
- package/src/shadcn/alert-dialog/alert-dialog-cancel.svelte +18 -0
- package/src/shadcn/alert-dialog/alert-dialog-content.svelte +29 -0
- package/src/shadcn/alert-dialog/alert-dialog-description.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-footer.svelte +20 -0
- package/src/shadcn/alert-dialog/alert-dialog-header.svelte +20 -0
- package/src/shadcn/alert-dialog/alert-dialog-overlay.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-portal.svelte +7 -0
- package/src/shadcn/alert-dialog/alert-dialog-title.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-trigger.svelte +7 -0
- package/src/shadcn/alert-dialog/alert-dialog.svelte +7 -0
- package/src/shadcn/alert-dialog/index.ts +37 -0
- package/src/shadcn/attachment/attachment-action.svelte +23 -0
- package/src/shadcn/attachment/attachment-actions.svelte +23 -0
- package/src/shadcn/attachment/attachment-content.svelte +23 -0
- package/src/shadcn/attachment/attachment-description.svelte +23 -0
- package/src/shadcn/attachment/attachment-group.svelte +23 -0
- package/src/shadcn/attachment/attachment-media.svelte +44 -0
- package/src/shadcn/attachment/attachment-title.svelte +23 -0
- package/src/shadcn/attachment/attachment-trigger.svelte +29 -0
- package/src/shadcn/attachment/attachment.svelte +55 -0
- package/src/shadcn/attachment/index.ts +40 -0
- package/src/shadcn/avatar/avatar-badge.svelte +26 -0
- package/src/shadcn/avatar/avatar-fallback.svelte +20 -0
- package/src/shadcn/avatar/avatar-group-count.svelte +23 -0
- package/src/shadcn/avatar/avatar-group.svelte +23 -0
- package/src/shadcn/avatar/avatar-image.svelte +17 -0
- package/src/shadcn/avatar/avatar.svelte +26 -0
- package/src/shadcn/avatar/index.ts +22 -0
- package/src/shadcn/badge/badge.svelte +54 -0
- package/src/shadcn/badge/index.ts +2 -0
- package/src/shadcn/breadcrumb/breadcrumb-ellipsis.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-item.svelte +20 -0
- package/src/shadcn/breadcrumb/breadcrumb-link.svelte +31 -0
- package/src/shadcn/breadcrumb/breadcrumb-list.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-page.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-separator.svelte +27 -0
- package/src/shadcn/breadcrumb/breadcrumb.svelte +21 -0
- package/src/shadcn/breadcrumb/index.ts +25 -0
- package/src/shadcn/bubble/bubble-content.svelte +31 -0
- package/src/shadcn/bubble/bubble-group.svelte +20 -0
- package/src/shadcn/bubble/bubble-reactions.svelte +52 -0
- package/src/shadcn/bubble/bubble.svelte +58 -0
- package/src/shadcn/bubble/index.ts +25 -0
- package/src/shadcn/button/button.svelte +121 -0
- package/src/shadcn/button/index.ts +17 -0
- package/src/shadcn/calendar/calendar-caption.svelte +76 -0
- package/src/shadcn/calendar/calendar-cell.svelte +19 -0
- package/src/shadcn/calendar/calendar-day.svelte +35 -0
- package/src/shadcn/calendar/calendar-grid-body.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-head.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-row.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid.svelte +16 -0
- package/src/shadcn/calendar/calendar-head-cell.svelte +19 -0
- package/src/shadcn/calendar/calendar-header.svelte +19 -0
- package/src/shadcn/calendar/calendar-heading.svelte +16 -0
- package/src/shadcn/calendar/calendar-month-select.svelte +44 -0
- package/src/shadcn/calendar/calendar-month.svelte +15 -0
- package/src/shadcn/calendar/calendar-months.svelte +19 -0
- package/src/shadcn/calendar/calendar-nav.svelte +19 -0
- package/src/shadcn/calendar/calendar-next-button.svelte +31 -0
- package/src/shadcn/calendar/calendar-prev-button.svelte +31 -0
- package/src/shadcn/calendar/calendar-year-select.svelte +43 -0
- package/src/shadcn/calendar/calendar.svelte +124 -0
- package/src/shadcn/calendar/index.ts +40 -0
- package/src/shadcn/card/card-action.svelte +23 -0
- package/src/shadcn/card/card-content.svelte +20 -0
- package/src/shadcn/card/card-description.svelte +20 -0
- package/src/shadcn/card/card-footer.svelte +23 -0
- package/src/shadcn/card/card-header.svelte +23 -0
- package/src/shadcn/card/card-title.svelte +29 -0
- package/src/shadcn/card/card.svelte +25 -0
- package/src/shadcn/card/index.ts +25 -0
- package/src/shadcn/checkbox/checkbox.svelte +38 -0
- package/src/shadcn/checkbox/index.ts +6 -0
- package/src/shadcn/code-block/code-block-actions.svelte +23 -0
- package/src/shadcn/code-block/code-block-content.svelte +55 -0
- package/src/shadcn/code-block/code-block-copy-button.svelte +10 -0
- package/src/shadcn/code-block/code-block-footer.svelte +20 -0
- package/src/shadcn/code-block/code-block-header.svelte +23 -0
- package/src/shadcn/code-block/code-block-line.svelte +71 -0
- package/src/shadcn/code-block/code-block-title.svelte +23 -0
- package/src/shadcn/code-block/code-block.svelte +47 -0
- package/src/shadcn/code-block/index.ts +42 -0
- package/src/shadcn/collapsible/collapsible-content.svelte +7 -0
- package/src/shadcn/collapsible/collapsible-trigger.svelte +7 -0
- package/src/shadcn/collapsible/collapsible.svelte +11 -0
- package/src/shadcn/collapsible/index.ts +13 -0
- package/src/shadcn/command/command-dialog.svelte +66 -0
- package/src/shadcn/command/command-empty.svelte +17 -0
- package/src/shadcn/command/command-group.svelte +40 -0
- package/src/shadcn/command/command-input.svelte +64 -0
- package/src/shadcn/command/command-item.svelte +37 -0
- package/src/shadcn/command/command-link-item.svelte +20 -0
- package/src/shadcn/command/command-list.svelte +20 -0
- package/src/shadcn/command/command-loading.svelte +7 -0
- package/src/shadcn/command/command-separator.svelte +17 -0
- package/src/shadcn/command/command-shortcut.svelte +23 -0
- package/src/shadcn/command/command.svelte +28 -0
- package/src/shadcn/command/index.ts +40 -0
- package/src/shadcn/context-menu/context-menu-checkbox-item.svelte +41 -0
- package/src/shadcn/context-menu/context-menu-content.svelte +28 -0
- package/src/shadcn/context-menu/context-menu-group-heading.svelte +21 -0
- package/src/shadcn/context-menu/context-menu-group.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-item.svelte +27 -0
- package/src/shadcn/context-menu/context-menu-label.svelte +27 -0
- package/src/shadcn/context-menu/context-menu-portal.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-radio-group.svelte +16 -0
- package/src/shadcn/context-menu/context-menu-radio-item.svelte +35 -0
- package/src/shadcn/context-menu/context-menu-separator.svelte +17 -0
- package/src/shadcn/context-menu/context-menu-shortcut.svelte +23 -0
- package/src/shadcn/context-menu/context-menu-sub-content.svelte +25 -0
- package/src/shadcn/context-menu/context-menu-sub-trigger.svelte +29 -0
- package/src/shadcn/context-menu/context-menu-sub.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-trigger.svelte +17 -0
- package/src/shadcn/context-menu/context-menu.svelte +7 -0
- package/src/shadcn/context-menu/index.ts +52 -0
- package/src/shadcn/dialog/dialog-close.svelte +11 -0
- package/src/shadcn/dialog/dialog-content.svelte +57 -0
- package/src/shadcn/dialog/dialog-description.svelte +20 -0
- package/src/shadcn/dialog/dialog-footer.svelte +32 -0
- package/src/shadcn/dialog/dialog-header.svelte +20 -0
- package/src/shadcn/dialog/dialog-overlay.svelte +20 -0
- package/src/shadcn/dialog/dialog-portal.svelte +7 -0
- package/src/shadcn/dialog/dialog-title.svelte +17 -0
- package/src/shadcn/dialog/dialog-trigger.svelte +11 -0
- package/src/shadcn/dialog/dialog.svelte +7 -0
- package/src/shadcn/dialog/index.ts +34 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +31 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-item.svelte +29 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-label.svelte +27 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-item.svelte +34 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu.svelte +7 -0
- package/src/shadcn/dropdown-menu/index.ts +56 -0
- package/src/shadcn/dropdown-menu/menu-item.ts +43 -0
- package/src/shadcn/empty/empty-content.svelte +23 -0
- package/src/shadcn/empty/empty-description.svelte +23 -0
- package/src/shadcn/empty/empty-header.svelte +20 -0
- package/src/shadcn/empty/empty-media.svelte +41 -0
- package/src/shadcn/empty/empty-title.svelte +20 -0
- package/src/shadcn/empty/empty.svelte +23 -0
- package/src/shadcn/empty/index.ts +22 -0
- package/src/shadcn/field/field-content.svelte +20 -0
- package/src/shadcn/field/field-description.svelte +25 -0
- package/src/shadcn/field/field-error.svelte +58 -0
- package/src/shadcn/field/field-group.svelte +23 -0
- package/src/shadcn/field/field-label.svelte +26 -0
- package/src/shadcn/field/field-legend.svelte +29 -0
- package/src/shadcn/field/field-separator.svelte +35 -0
- package/src/shadcn/field/field-set.svelte +24 -0
- package/src/shadcn/field/field-title.svelte +23 -0
- package/src/shadcn/field/field.svelte +53 -0
- package/src/shadcn/field/index.ts +36 -0
- package/src/shadcn/field/simple-field.svelte +71 -0
- package/src/shadcn/field/simple-field.test.ts +47 -0
- package/src/shadcn/hooks/highlighter.ts +132 -0
- package/src/shadcn/hooks/is-mobile.svelte.ts +9 -0
- package/src/shadcn/hooks/use-highlighted-code.svelte.ts +98 -0
- package/src/shadcn/hover-card/hover-card-content.svelte +31 -0
- package/src/shadcn/hover-card/hover-card-portal.svelte +7 -0
- package/src/shadcn/hover-card/hover-card-trigger.svelte +7 -0
- package/src/shadcn/hover-card/hover-card.svelte +7 -0
- package/src/shadcn/hover-card/index.ts +15 -0
- package/src/shadcn/input/index.ts +9 -0
- package/src/shadcn/input/input.svelte +48 -0
- package/src/shadcn/input/secret-input.svelte +75 -0
- package/src/shadcn/input-otp/index.ts +15 -0
- package/src/shadcn/input-otp/input-otp-group.svelte +20 -0
- package/src/shadcn/input-otp/input-otp-separator.svelte +25 -0
- package/src/shadcn/input-otp/input-otp-slot.svelte +26 -0
- package/src/shadcn/input-otp/input-otp.svelte +22 -0
- package/src/shadcn/kbd/index.ts +10 -0
- package/src/shadcn/kbd/kbd-group.svelte +20 -0
- package/src/shadcn/kbd/kbd.svelte +23 -0
- package/src/shadcn/label/index.ts +7 -0
- package/src/shadcn/label/label.svelte +20 -0
- package/src/shadcn/marker/index.ts +15 -0
- package/src/shadcn/marker/marker-content.svelte +23 -0
- package/src/shadcn/marker/marker-icon.svelte +21 -0
- package/src/shadcn/marker/marker.svelte +52 -0
- package/src/shadcn/message/index.ts +22 -0
- package/src/shadcn/message/message-avatar.svelte +23 -0
- package/src/shadcn/message/message-content.svelte +23 -0
- package/src/shadcn/message/message-footer.svelte +23 -0
- package/src/shadcn/message/message-group.svelte +20 -0
- package/src/shadcn/message/message-header.svelte +23 -0
- package/src/shadcn/message/message.svelte +27 -0
- package/src/shadcn/message-scroller/index.ts +28 -0
- package/src/shadcn/message-scroller/message-scroller-button.svelte +52 -0
- package/src/shadcn/message-scroller/message-scroller-content.svelte +17 -0
- package/src/shadcn/message-scroller/message-scroller-item.svelte +22 -0
- package/src/shadcn/message-scroller/message-scroller-provider.svelte +7 -0
- package/src/shadcn/message-scroller/message-scroller-viewport.svelte +20 -0
- package/src/shadcn/message-scroller/message-scroller.svelte +20 -0
- package/src/shadcn/popover/index.ts +28 -0
- package/src/shadcn/popover/popover-close.svelte +7 -0
- package/src/shadcn/popover/popover-content.svelte +38 -0
- package/src/shadcn/popover/popover-description.svelte +20 -0
- package/src/shadcn/popover/popover-header.svelte +20 -0
- package/src/shadcn/popover/popover-portal.svelte +7 -0
- package/src/shadcn/popover/popover-title.svelte +15 -0
- package/src/shadcn/popover/popover-trigger.svelte +17 -0
- package/src/shadcn/popover/popover.svelte +7 -0
- package/src/shadcn/progress/index.ts +7 -0
- package/src/shadcn/progress/progress.svelte +30 -0
- package/src/shadcn/radio-group/index.ts +10 -0
- package/src/shadcn/radio-group/radio-group-item.svelte +32 -0
- package/src/shadcn/radio-group/radio-group.svelte +19 -0
- package/src/shadcn/scroll-area/index.ts +10 -0
- package/src/shadcn/scroll-area/scroll-area-scrollbar.svelte +30 -0
- package/src/shadcn/scroll-area/scroll-area.svelte +43 -0
- package/src/shadcn/select/index.ts +37 -0
- package/src/shadcn/select/select-content.svelte +45 -0
- package/src/shadcn/select/select-group-heading.svelte +21 -0
- package/src/shadcn/select/select-group.svelte +17 -0
- package/src/shadcn/select/select-item.svelte +38 -0
- package/src/shadcn/select/select-label.svelte +20 -0
- package/src/shadcn/select/select-portal.svelte +7 -0
- package/src/shadcn/select/select-scroll-down-button.svelte +23 -0
- package/src/shadcn/select/select-scroll-up-button.svelte +23 -0
- package/src/shadcn/select/select-separator.svelte +18 -0
- package/src/shadcn/select/select-trigger.svelte +33 -0
- package/src/shadcn/select/select.svelte +11 -0
- package/src/shadcn/separator/index.ts +7 -0
- package/src/shadcn/separator/separator.svelte +23 -0
- package/src/shadcn/sheet/index.ts +34 -0
- package/src/shadcn/sheet/sheet-close.svelte +7 -0
- package/src/shadcn/sheet/sheet-content.svelte +73 -0
- package/src/shadcn/sheet/sheet-description.svelte +17 -0
- package/src/shadcn/sheet/sheet-footer.svelte +20 -0
- package/src/shadcn/sheet/sheet-header.svelte +20 -0
- package/src/shadcn/sheet/sheet-overlay.svelte +20 -0
- package/src/shadcn/sheet/sheet-portal.svelte +7 -0
- package/src/shadcn/sheet/sheet-title.svelte +17 -0
- package/src/shadcn/sheet/sheet-trigger.svelte +7 -0
- package/src/shadcn/sheet/sheet.css +48 -0
- package/src/shadcn/sheet/sheet.svelte +7 -0
- package/src/shadcn/sidebar/constants.ts +6 -0
- package/src/shadcn/sidebar/context.svelte.ts +81 -0
- package/src/shadcn/sidebar/index.ts +75 -0
- package/src/shadcn/sidebar/sidebar-content.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-footer.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-action.svelte +33 -0
- package/src/shadcn/sidebar/sidebar-group-content.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-label.svelte +33 -0
- package/src/shadcn/sidebar/sidebar-group.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-header.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-input.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-inset.svelte +23 -0
- package/src/shadcn/sidebar/sidebar-menu-action.svelte +37 -0
- package/src/shadcn/sidebar/sidebar-menu-badge.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-menu-button.svelte +103 -0
- package/src/shadcn/sidebar/sidebar-menu-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-skeleton.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +39 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-sub.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-menu.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-provider.svelte +62 -0
- package/src/shadcn/sidebar/sidebar-rail.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-separator.svelte +19 -0
- package/src/shadcn/sidebar/sidebar-trigger.svelte +37 -0
- package/src/shadcn/sidebar/sidebar.svelte +109 -0
- package/src/shadcn/skeleton/index.ts +7 -0
- package/src/shadcn/skeleton/skeleton.svelte +17 -0
- package/src/shadcn/slider/index.ts +7 -0
- package/src/shadcn/slider/slider.svelte +52 -0
- package/src/shadcn/sonner/index.ts +1 -0
- package/src/shadcn/sonner/sonner.svelte +31 -0
- package/src/shadcn/spinner/index.ts +1 -0
- package/src/shadcn/spinner/spinner.svelte +26 -0
- package/src/shadcn/switch/index.ts +7 -0
- package/src/shadcn/switch/switch.svelte +31 -0
- package/src/shadcn/table/index.ts +28 -0
- package/src/shadcn/table/table-body.svelte +20 -0
- package/src/shadcn/table/table-caption.svelte +20 -0
- package/src/shadcn/table/table-cell.svelte +20 -0
- package/src/shadcn/table/table-footer.svelte +20 -0
- package/src/shadcn/table/table-head.svelte +23 -0
- package/src/shadcn/table/table-header.svelte +20 -0
- package/src/shadcn/table/table-row.svelte +23 -0
- package/src/shadcn/table/table.svelte +25 -0
- package/src/shadcn/tabs/index.ts +16 -0
- package/src/shadcn/tabs/tabs-content.svelte +17 -0
- package/src/shadcn/tabs/tabs-list.svelte +36 -0
- package/src/shadcn/tabs/tabs-trigger.svelte +20 -0
- package/src/shadcn/tabs/tabs.svelte +19 -0
- package/src/shadcn/textarea/index.ts +7 -0
- package/src/shadcn/textarea/textarea.svelte +23 -0
- package/src/shadcn/toggle/index.ts +13 -0
- package/src/shadcn/toggle/toggle.svelte +53 -0
- package/src/shadcn/toggle-group/index.ts +10 -0
- package/src/shadcn/toggle-group/toggle-group-item.svelte +35 -0
- package/src/shadcn/toggle-group/toggle-group.svelte +66 -0
- package/src/shadcn/tooltip/context.ts +16 -0
- package/src/shadcn/tooltip/index.ts +19 -0
- package/src/shadcn/tooltip/tooltip-content.svelte +38 -0
- package/src/shadcn/tooltip/tooltip-portal.svelte +7 -0
- package/src/shadcn/tooltip/tooltip-provider.svelte +16 -0
- package/src/shadcn/tooltip/tooltip-trigger.svelte +7 -0
- package/src/shadcn/tooltip/tooltip.svelte +19 -0
- package/src/shadcn/trace/index.ts +29 -0
- package/src/shadcn/trace/trace-collapsible-content.svelte +29 -0
- package/src/shadcn/trace/trace-collapsible-trigger.svelte +29 -0
- package/src/shadcn/trace/trace-collapsible.svelte +20 -0
- package/src/shadcn/trace/trace-description.svelte +20 -0
- package/src/shadcn/trace/trace-icon.svelte +24 -0
- package/src/shadcn/trace/trace-line.svelte +31 -0
- package/src/shadcn/trace/trace-title.svelte +20 -0
- package/src/shadcn/trace/trace.svelte +23 -0
- package/src/shadcn/utilities.css +549 -0
- package/src/test-setup.ts +34 -0
- package/src/tokens.css +993 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { cn } from "@heyramzi/utils";
|
|
7
|
+
|
|
8
|
+
// =========================
|
|
9
|
+
// TYPES
|
|
10
|
+
// =========================
|
|
11
|
+
type Props = {
|
|
12
|
+
// Answers three questions in one order: what is this, what state is it in,
|
|
13
|
+
// what can I do with it. Each queue page used to order them differently.
|
|
14
|
+
title: string;
|
|
15
|
+
// The state chip beside the title.
|
|
16
|
+
badge?: Snippet;
|
|
17
|
+
// A picture ahead of the title, like a video frame or a deck cover. Some
|
|
18
|
+
// records aren't recognisable from their title alone.
|
|
19
|
+
leading?: Snippet;
|
|
20
|
+
// Facts about the record, rendered as one dot-separated line under the
|
|
21
|
+
// title. Falsy entries drop out, so a caller can inline its conditionals.
|
|
22
|
+
meta?: Array<string | null | undefined | false>;
|
|
23
|
+
// A sentence under the meta line, when the record explains itself.
|
|
24
|
+
note?: string | null;
|
|
25
|
+
// What you can do to the record. Pinned right of the identity block, EXCEPT
|
|
26
|
+
// when a picture leads: see the note in the markup.
|
|
27
|
+
actions?: Snippet;
|
|
28
|
+
// The top-right control, a record's way out. Pass `undefined` when empty:
|
|
29
|
+
// an empty snippet is still truthy and reserves the corner.
|
|
30
|
+
corner?: Snippet;
|
|
31
|
+
// Hairline-separated rows below the identity block. Use `DetailRow`.
|
|
32
|
+
children?: Snippet;
|
|
33
|
+
class?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// =========================
|
|
37
|
+
// PROPS
|
|
38
|
+
// =========================
|
|
39
|
+
let { title, badge, leading, meta, note, actions, corner, children, class: className }: Props =
|
|
40
|
+
$props();
|
|
41
|
+
|
|
42
|
+
// =========================
|
|
43
|
+
// DERIVED
|
|
44
|
+
// =========================
|
|
45
|
+
let facts = $derived((meta ?? []).filter((item): item is string => Boolean(item)));
|
|
46
|
+
// Actions stack under the meta when something else claims the right edge:
|
|
47
|
+
// a picture, or the corner. Pinned beside a corner, they left the title
|
|
48
|
+
// a third of the row.
|
|
49
|
+
let stackActions = $derived(Boolean(leading || corner));
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<!-- =========================== -->
|
|
53
|
+
<!-- MARKUP -->
|
|
54
|
+
<!-- =========================== -->
|
|
55
|
+
<section class={cn("overflow-hidden rounded-xl border border-border bg-card", className)}>
|
|
56
|
+
<div class="flex flex-wrap items-start justify-between gap-x-4 gap-y-3 p-4">
|
|
57
|
+
{#if leading}
|
|
58
|
+
<div class="shrink-0">{@render leading()}</div>
|
|
59
|
+
{/if}
|
|
60
|
+
<div class="min-w-0 flow-root flex-1 basis-64">
|
|
61
|
+
<!-- The corner floats, so only the lines beside it give way. Reserved
|
|
62
|
+
across the whole row it took ~150px off every line and wrapped a
|
|
63
|
+
normal title to three. -->
|
|
64
|
+
{#if corner}
|
|
65
|
+
<div class="float-end ms-3">{@render corner()}</div>
|
|
66
|
+
{/if}
|
|
67
|
+
<!-- The badge sits inline in the h2 so it trails the last word. As a
|
|
68
|
+
flex sibling it wrapped to its own row on every two-line title. -->
|
|
69
|
+
<!-- No text-balance: it evens the lines out, so a two-line title stopped
|
|
70
|
+
short of the corner instead of running the full width. -->
|
|
71
|
+
<h2 class="min-w-0 font-heading text-lg font-semibold leading-snug tracking-tight">
|
|
72
|
+
{title}{#if badge}<span class="ms-2 inline-flex align-middle">{@render badge()}</span
|
|
73
|
+
>{/if}
|
|
74
|
+
</h2>
|
|
75
|
+
{#if facts.length > 0}
|
|
76
|
+
<!-- Each dot hangs off the fact it leads, so a wrapped line's dot stays
|
|
77
|
+
in the gutter. A standalone flex-item dot dangled on the line above. -->
|
|
78
|
+
<div class="mt-1 overflow-hidden">
|
|
79
|
+
<p class="-ms-3 flex flex-wrap items-center text-sm text-muted-foreground">
|
|
80
|
+
{#each facts as fact, i (i)}
|
|
81
|
+
<span
|
|
82
|
+
class="relative ps-3 before:absolute before:start-1 before:opacity-40 before:content-['·']"
|
|
83
|
+
>{fact}</span
|
|
84
|
+
>
|
|
85
|
+
{/each}
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
89
|
+
{#if note}
|
|
90
|
+
<p class="mt-1 text-sm text-muted-foreground">{note}</p>
|
|
91
|
+
{/if}
|
|
92
|
+
<!-- With a picture or a corner, actions sit in this column. Pinned right
|
|
93
|
+
they wrapped under the picture and read like its caption. -->
|
|
94
|
+
{#if actions && stackActions}
|
|
95
|
+
<div class="clear-both flex flex-wrap items-center gap-2 pt-3">
|
|
96
|
+
{@render actions()}
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
</div>
|
|
100
|
+
{#if actions && !stackActions}
|
|
101
|
+
<div class="flex flex-wrap items-center gap-2">{@render actions()}</div>
|
|
102
|
+
{/if}
|
|
103
|
+
</div>
|
|
104
|
+
{#if children}
|
|
105
|
+
{@render children()}
|
|
106
|
+
{/if}
|
|
107
|
+
</section>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import SectionLabel from "./section-label.svelte";
|
|
7
|
+
import { cn } from "@heyramzi/utils";
|
|
8
|
+
import { panelHeaderClass, panelShellClass } from "../../lib/panel.js";
|
|
9
|
+
import type { PhosphorIcon } from "../../lib/icon-types.js";
|
|
10
|
+
|
|
11
|
+
// =========================
|
|
12
|
+
// TYPES
|
|
13
|
+
// =========================
|
|
14
|
+
type Props = {
|
|
15
|
+
// One panel per idea in a detail pane. Hand-rolled copies drifted between
|
|
16
|
+
// 8px and 12px corners, so rounded-xl lives here once.
|
|
17
|
+
label?: string;
|
|
18
|
+
labelIcon?: PhosphorIcon;
|
|
19
|
+
// A mark the icon set does not carry (a platform logo), drawn ahead of the
|
|
20
|
+
// label at the same optical size.
|
|
21
|
+
labelLead?: Snippet;
|
|
22
|
+
// The right side of the header bar: a count, a hint, a button cluster.
|
|
23
|
+
actions?: Snippet;
|
|
24
|
+
// WHY: a panel whose body is a media grid or a full-bleed list supplies its
|
|
25
|
+
// own padding, so the shell must be able to step out of the way.
|
|
26
|
+
pad?: boolean;
|
|
27
|
+
// Takes the height the panels above it did not use, inside a `fill` stack.
|
|
28
|
+
// One panel per stack, and it is the one the reader works in.
|
|
29
|
+
grow?: boolean;
|
|
30
|
+
children: Snippet;
|
|
31
|
+
class?: string;
|
|
32
|
+
bodyClass?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// =========================
|
|
36
|
+
// PROPS
|
|
37
|
+
// =========================
|
|
38
|
+
let {
|
|
39
|
+
label,
|
|
40
|
+
labelIcon,
|
|
41
|
+
labelLead,
|
|
42
|
+
actions,
|
|
43
|
+
pad = true,
|
|
44
|
+
grow = false,
|
|
45
|
+
children,
|
|
46
|
+
class: className,
|
|
47
|
+
bodyClass,
|
|
48
|
+
}: Props = $props();
|
|
49
|
+
|
|
50
|
+
// =========================
|
|
51
|
+
// DERIVED
|
|
52
|
+
// =========================
|
|
53
|
+
let hasHeader = $derived(Boolean(label || labelLead || actions));
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<!-- =========================== -->
|
|
57
|
+
<!-- MARKUP -->
|
|
58
|
+
<!-- =========================== -->
|
|
59
|
+
<section
|
|
60
|
+
class={cn(
|
|
61
|
+
panelShellClass,
|
|
62
|
+
grow && "flex min-h-0 flex-1 flex-col",
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
{#if hasHeader}
|
|
67
|
+
<div
|
|
68
|
+
class={panelHeaderClass}
|
|
69
|
+
>
|
|
70
|
+
{#if label || labelLead}
|
|
71
|
+
<SectionLabel icon={labelIcon}>
|
|
72
|
+
{#if labelLead}
|
|
73
|
+
{@render labelLead()}
|
|
74
|
+
{/if}
|
|
75
|
+
{label}
|
|
76
|
+
</SectionLabel>
|
|
77
|
+
{:else}
|
|
78
|
+
<span></span>
|
|
79
|
+
{/if}
|
|
80
|
+
{#if actions}
|
|
81
|
+
<div class="flex min-w-0 flex-wrap items-center justify-end gap-2">
|
|
82
|
+
{@render actions()}
|
|
83
|
+
</div>
|
|
84
|
+
{/if}
|
|
85
|
+
</div>
|
|
86
|
+
{/if}
|
|
87
|
+
<div class={cn(pad && "p-4", grow && "flex min-h-0 flex-1 flex-col", bodyClass)}>
|
|
88
|
+
{@render children()}
|
|
89
|
+
</div>
|
|
90
|
+
</section>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { cn } from "@heyramzi/utils";
|
|
7
|
+
|
|
8
|
+
// =========================
|
|
9
|
+
// TYPES
|
|
10
|
+
// =========================
|
|
11
|
+
type Props = {
|
|
12
|
+
// A hairline band inside `DetailHeader` or `DetailPanel` for the record's
|
|
13
|
+
// own facts, so the page never nests cards inside cards.
|
|
14
|
+
muted?: boolean;
|
|
15
|
+
children: Snippet;
|
|
16
|
+
class?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// =========================
|
|
20
|
+
// PROPS
|
|
21
|
+
// =========================
|
|
22
|
+
let { muted = false, children, class: className }: Props = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<!-- =========================== -->
|
|
26
|
+
<!-- MARKUP -->
|
|
27
|
+
<!-- =========================== -->
|
|
28
|
+
<div
|
|
29
|
+
class={cn(
|
|
30
|
+
"border-t border-border px-4 py-3 text-sm leading-relaxed",
|
|
31
|
+
muted && "text-xs text-muted-foreground",
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{@render children()}
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { cn } from "@heyramzi/utils";
|
|
7
|
+
|
|
8
|
+
// =========================
|
|
9
|
+
// TYPES
|
|
10
|
+
// =========================
|
|
11
|
+
type Props = {
|
|
12
|
+
// A flat stack of panels at one gap. `xl:pr-1` keeps the top panel's
|
|
13
|
+
// corner clear of the shell's scrollbar.
|
|
14
|
+
|
|
15
|
+
// `fill` makes the stack at least as tall as its scroller, so a `grow`
|
|
16
|
+
// panel (like a writing box) takes the empty bottom third back.
|
|
17
|
+
fill?: boolean;
|
|
18
|
+
children: Snippet;
|
|
19
|
+
class?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// =========================
|
|
23
|
+
// PROPS
|
|
24
|
+
// =========================
|
|
25
|
+
let { fill = false, children, class: className }: Props = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<!-- =========================== -->
|
|
29
|
+
<!-- MARKUP -->
|
|
30
|
+
<!-- =========================== -->
|
|
31
|
+
<div class={cn("flex flex-col gap-4 xl:pr-1", fill && "min-h-full", className)}>
|
|
32
|
+
{@render children()}
|
|
33
|
+
</div>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { Button } from "../../shadcn/button/index.js";
|
|
6
|
+
import * as Empty from "../../shadcn/empty/index.js";
|
|
7
|
+
import type { PhosphorIcon, IconWeight } from "../../lib/icon-types.js";
|
|
8
|
+
|
|
9
|
+
// =========================
|
|
10
|
+
// TYPES
|
|
11
|
+
// =========================
|
|
12
|
+
interface Props {
|
|
13
|
+
icon?: PhosphorIcon;
|
|
14
|
+
iconWeight?: IconWeight;
|
|
15
|
+
title: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
actionLabel?: string;
|
|
18
|
+
actionHref?: string;
|
|
19
|
+
onAction?: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// =========================
|
|
23
|
+
// PROPS
|
|
24
|
+
// =========================
|
|
25
|
+
let {
|
|
26
|
+
icon: Icon,
|
|
27
|
+
iconWeight,
|
|
28
|
+
title,
|
|
29
|
+
description,
|
|
30
|
+
actionLabel,
|
|
31
|
+
actionHref,
|
|
32
|
+
onAction,
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<!-- =========================== -->
|
|
37
|
+
<!-- MARKUP -->
|
|
38
|
+
<!-- =========================== -->
|
|
39
|
+
<!-- The four parts arrive in reading order. The stagger is what says the page
|
|
40
|
+
finished loading and is simply empty. -->
|
|
41
|
+
<Empty.Root class="t-empty py-16">
|
|
42
|
+
<Empty.Header class="max-w-md">
|
|
43
|
+
{#if Icon}
|
|
44
|
+
<Empty.Media class="mb-4 size-16 rounded-2xl bg-brand-indigo/10 text-brand-indigo">
|
|
45
|
+
<Icon weight={iconWeight} class="size-8" />
|
|
46
|
+
</Empty.Media>
|
|
47
|
+
{/if}
|
|
48
|
+
<Empty.Title class="font-heading text-lg font-semibold">{title}</Empty.Title>
|
|
49
|
+
{#if description}
|
|
50
|
+
<Empty.Description>{description}</Empty.Description>
|
|
51
|
+
{/if}
|
|
52
|
+
</Empty.Header>
|
|
53
|
+
{#if actionLabel && (actionHref || onAction)}
|
|
54
|
+
<Empty.Content>
|
|
55
|
+
{#if actionHref}
|
|
56
|
+
<Button href={actionHref}>{actionLabel}</Button>
|
|
57
|
+
{:else}
|
|
58
|
+
<Button onclick={onAction}>{actionLabel}</Button>
|
|
59
|
+
{/if}
|
|
60
|
+
</Empty.Content>
|
|
61
|
+
{/if}
|
|
62
|
+
</Empty.Root>
|
|
63
|
+
|
|
64
|
+
<!-- =========================== -->
|
|
65
|
+
<!-- STYLE -->
|
|
66
|
+
<!-- =========================== -->
|
|
67
|
+
<style>
|
|
68
|
+
/* Never `:nth-child` here: one such rule makes every DOM insert on the page restyle its later siblings. */
|
|
69
|
+
:global(.t-empty) > :global(*) {
|
|
70
|
+
animation: t-empty-in var(--duration-very-slow) var(--ease-smooth-out) both;
|
|
71
|
+
animation-delay: calc((sibling-index() - 1) * var(--duration-stagger));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@keyframes -global-t-empty-in {
|
|
75
|
+
from {
|
|
76
|
+
opacity: 0;
|
|
77
|
+
transform: translateY(var(--distance-small));
|
|
78
|
+
}
|
|
79
|
+
to {
|
|
80
|
+
opacity: 1;
|
|
81
|
+
transform: none;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@media (prefers-reduced-motion: reduce) {
|
|
86
|
+
:global(.t-empty) > :global(*) {
|
|
87
|
+
animation-duration: 1ms;
|
|
88
|
+
animation-delay: 0ms;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { Checkbox } from "../../shadcn/checkbox/index.js";
|
|
7
|
+
import { Check } from "phosphor-svelte";
|
|
8
|
+
import { cn } from "@heyramzi/utils";
|
|
9
|
+
|
|
10
|
+
// =========================
|
|
11
|
+
// TYPES
|
|
12
|
+
// =========================
|
|
13
|
+
type Props = {
|
|
14
|
+
checked: boolean;
|
|
15
|
+
onclick: () => void;
|
|
16
|
+
variant?: "checkbox" | "radio";
|
|
17
|
+
children: Snippet;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// =========================
|
|
21
|
+
// PROPS
|
|
22
|
+
// =========================
|
|
23
|
+
let { checked, onclick, variant = "checkbox", children }: Props = $props();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<!-- =========================== -->
|
|
27
|
+
<!-- MARKUP -->
|
|
28
|
+
<!-- =========================== -->
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
class="flex items-center gap-2 rounded-lg px-2 py-1.5 text-sm transition-colors hover:bg-muted"
|
|
32
|
+
{onclick}
|
|
33
|
+
>
|
|
34
|
+
{#if variant === "radio"}
|
|
35
|
+
<span
|
|
36
|
+
class={cn(
|
|
37
|
+
"grid size-3.5 shrink-0 place-items-center rounded-full border transition-colors",
|
|
38
|
+
checked ? "border-primary bg-primary text-primary-foreground" : "border-border",
|
|
39
|
+
)}
|
|
40
|
+
>
|
|
41
|
+
{#if checked}
|
|
42
|
+
<Check class="size-2.5" weight="bold" />
|
|
43
|
+
{/if}
|
|
44
|
+
</span>
|
|
45
|
+
{:else}
|
|
46
|
+
<Checkbox {checked} />
|
|
47
|
+
{/if}
|
|
48
|
+
{@render children()}
|
|
49
|
+
</button>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import * as Popover from "../../shadcn/popover/index.js";
|
|
7
|
+
import { Funnel as FunnelIcon } from "phosphor-svelte";
|
|
8
|
+
import { cn } from "@heyramzi/utils";
|
|
9
|
+
import { Button } from "../../shadcn/button/index.js";
|
|
10
|
+
import { toolbarTriggerClass } from "./toolbar-trigger.js";
|
|
11
|
+
import type { PhosphorIcon } from "../../lib/icon-types.js";
|
|
12
|
+
|
|
13
|
+
// phosphor-svelte v2 (resolved here) and v3 (what consumers run) differ only in
|
|
14
|
+
// Component generics. The cast bridges that type-only gap.
|
|
15
|
+
const DefaultFunnelIcon = FunnelIcon as unknown as PhosphorIcon;
|
|
16
|
+
|
|
17
|
+
// =========================
|
|
18
|
+
// TYPES
|
|
19
|
+
// =========================
|
|
20
|
+
type Props = {
|
|
21
|
+
label: string;
|
|
22
|
+
icon?: PhosphorIcon;
|
|
23
|
+
count?: number;
|
|
24
|
+
active?: boolean;
|
|
25
|
+
onClear?: () => void;
|
|
26
|
+
align?: "start" | "center" | "end";
|
|
27
|
+
width?: `w-${string}`;
|
|
28
|
+
open?: boolean;
|
|
29
|
+
clearLabel?: string;
|
|
30
|
+
triggerClass?: string;
|
|
31
|
+
contentClass?: string;
|
|
32
|
+
children: Snippet;
|
|
33
|
+
trailing?: Snippet;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// =========================
|
|
37
|
+
// PROPS
|
|
38
|
+
// =========================
|
|
39
|
+
let {
|
|
40
|
+
label,
|
|
41
|
+
icon: IconComponent = DefaultFunnelIcon,
|
|
42
|
+
count = 0,
|
|
43
|
+
active,
|
|
44
|
+
onClear,
|
|
45
|
+
align = "start",
|
|
46
|
+
width = "w-52",
|
|
47
|
+
open = $bindable(false),
|
|
48
|
+
clearLabel = "Clear",
|
|
49
|
+
triggerClass,
|
|
50
|
+
contentClass,
|
|
51
|
+
children,
|
|
52
|
+
trailing,
|
|
53
|
+
}: Props = $props();
|
|
54
|
+
|
|
55
|
+
// =========================
|
|
56
|
+
// DERIVED
|
|
57
|
+
// =========================
|
|
58
|
+
let hasCount = $derived(count > 0);
|
|
59
|
+
let isActive = $derived(active ?? hasCount);
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<!-- =========================== -->
|
|
63
|
+
<!-- MARKUP -->
|
|
64
|
+
<!-- =========================== -->
|
|
65
|
+
<Popover.Root bind:open>
|
|
66
|
+
<Popover.Trigger class={toolbarTriggerClass({ active: isActive, className: triggerClass })}>
|
|
67
|
+
<IconComponent class="size-3.5" />
|
|
68
|
+
<span>{label}</span>
|
|
69
|
+
{#if trailing}
|
|
70
|
+
{@render trailing()}
|
|
71
|
+
{/if}
|
|
72
|
+
{#if hasCount}
|
|
73
|
+
<span
|
|
74
|
+
class="ml-0.5 inline-flex size-4 items-center justify-center rounded-full bg-brand-indigo/15 text-[10px] font-semibold text-brand-indigo dark:text-brand-indigo-light"
|
|
75
|
+
>
|
|
76
|
+
{count}
|
|
77
|
+
</span>
|
|
78
|
+
{/if}
|
|
79
|
+
</Popover.Trigger>
|
|
80
|
+
<Popover.Content class={cn("p-2", width, contentClass)} {align}>
|
|
81
|
+
{@render children()}
|
|
82
|
+
{#if onClear && hasCount}
|
|
83
|
+
<Button variant="ghost" size="sm" class="mt-2 w-full text-xs text-muted-foreground" onclick={onClear}>
|
|
84
|
+
{clearLabel}
|
|
85
|
+
</Button>
|
|
86
|
+
{/if}
|
|
87
|
+
</Popover.Content>
|
|
88
|
+
</Popover.Root>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { cn } from "@heyramzi/utils";
|
|
2
|
+
|
|
3
|
+
// The header for each control group in a toolbar popover, in one place so
|
|
4
|
+
// sections can't drift in size or weight.
|
|
5
|
+
|
|
6
|
+
// `first:` drops the leading header's top padding, since the popover pads itself.
|
|
7
|
+
export function filterSectionClass(className?: string): string {
|
|
8
|
+
return cn(
|
|
9
|
+
"px-2 pt-2 pb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground first:pt-1",
|
|
10
|
+
className,
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script lang="ts" generics="TGroup">
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { untrack, type Snippet } from "svelte";
|
|
6
|
+
import { SvelteSet } from "svelte/reactivity";
|
|
7
|
+
import { CaretDown } from "phosphor-svelte";
|
|
8
|
+
import { cn } from "@heyramzi/utils";
|
|
9
|
+
|
|
10
|
+
// =========================
|
|
11
|
+
// TYPES
|
|
12
|
+
// =========================
|
|
13
|
+
type Props = {
|
|
14
|
+
groups: TGroup[];
|
|
15
|
+
getKey: (group: TGroup) => string;
|
|
16
|
+
defaultCollapsed?: string[];
|
|
17
|
+
/** WHY: a page that drives its own keyboard cursor has to know which rows
|
|
18
|
+
are on screen, and the collapsed set is the only thing that says so. */
|
|
19
|
+
onCollapsedChange?: (keys: string[]) => void;
|
|
20
|
+
header: Snippet<[TGroup, { collapsed: boolean }]>;
|
|
21
|
+
/** Controls beside the header, outside its toggle button so a click on
|
|
22
|
+
one doesn't collapse the group. Shown on hover of the header row. */
|
|
23
|
+
actions?: Snippet<[TGroup]>;
|
|
24
|
+
rows: Snippet<[TGroup]>;
|
|
25
|
+
class?: string;
|
|
26
|
+
onGroupDragOver?: (e: DragEvent, group: TGroup) => void;
|
|
27
|
+
onGroupDragLeave?: (e: DragEvent) => void;
|
|
28
|
+
onGroupDrop?: (e: DragEvent, group: TGroup) => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// =========================
|
|
32
|
+
// PROPS
|
|
33
|
+
// =========================
|
|
34
|
+
let {
|
|
35
|
+
groups,
|
|
36
|
+
getKey,
|
|
37
|
+
defaultCollapsed = [],
|
|
38
|
+
onCollapsedChange,
|
|
39
|
+
header,
|
|
40
|
+
actions,
|
|
41
|
+
rows,
|
|
42
|
+
class: className,
|
|
43
|
+
onGroupDragOver,
|
|
44
|
+
onGroupDragLeave,
|
|
45
|
+
onGroupDrop,
|
|
46
|
+
}: Props = $props();
|
|
47
|
+
|
|
48
|
+
// =========================
|
|
49
|
+
// STATE
|
|
50
|
+
// =========================
|
|
51
|
+
const collapsed = new SvelteSet<string>(untrack(() => defaultCollapsed));
|
|
52
|
+
|
|
53
|
+
// =========================
|
|
54
|
+
// FUNCTIONS
|
|
55
|
+
// =========================
|
|
56
|
+
function toggle(key: string) {
|
|
57
|
+
if (collapsed.has(key)) {
|
|
58
|
+
collapsed.delete(key);
|
|
59
|
+
} else {
|
|
60
|
+
collapsed.add(key);
|
|
61
|
+
}
|
|
62
|
+
onCollapsedChange?.([...collapsed]);
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<!-- =========================== -->
|
|
67
|
+
<!-- MARKUP -->
|
|
68
|
+
<!-- =========================== -->
|
|
69
|
+
<div class={cn("flex w-full flex-col", className)}>
|
|
70
|
+
{#each groups as group, index (getKey(group))}
|
|
71
|
+
{@const key = getKey(group)}
|
|
72
|
+
{@const isCollapsed = collapsed.has(key)}
|
|
73
|
+
<div
|
|
74
|
+
class={cn(index > 0 && "mt-3 border-t border-border/50 pt-3")}
|
|
75
|
+
role={onGroupDragOver || onGroupDrop ? "group" : undefined}
|
|
76
|
+
ondragover={onGroupDragOver ? (e) => onGroupDragOver(e, group) : undefined}
|
|
77
|
+
ondragleave={onGroupDragLeave}
|
|
78
|
+
ondrop={onGroupDrop ? (e) => onGroupDrop(e, group) : undefined}
|
|
79
|
+
>
|
|
80
|
+
<div class="group/header flex items-center gap-1 rounded-lg transition-colors hover:bg-muted/60">
|
|
81
|
+
<button
|
|
82
|
+
type="button"
|
|
83
|
+
class="flex min-w-0 flex-1 cursor-pointer items-center gap-2.5 rounded-lg px-3 py-2 text-left"
|
|
84
|
+
onclick={() => toggle(key)}
|
|
85
|
+
aria-expanded={!isCollapsed}
|
|
86
|
+
>
|
|
87
|
+
<CaretDown
|
|
88
|
+
class={cn(
|
|
89
|
+
"size-3 shrink-0 text-muted-foreground/60 transition-transform duration-[var(--duration-fast)] ease-[var(--ease-smooth-out)]",
|
|
90
|
+
isCollapsed && "-rotate-90",
|
|
91
|
+
)}
|
|
92
|
+
weight="bold"
|
|
93
|
+
/>
|
|
94
|
+
{@render header(group, { collapsed: isCollapsed })}
|
|
95
|
+
</button>
|
|
96
|
+
{#if actions}
|
|
97
|
+
<div
|
|
98
|
+
class="flex shrink-0 items-center gap-1 pe-2 opacity-0 transition-opacity group-hover/header:opacity-100 focus-within:opacity-100 any-pointer-coarse:opacity-100"
|
|
99
|
+
>
|
|
100
|
+
{@render actions(group)}
|
|
101
|
+
</div>
|
|
102
|
+
{/if}
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{#if !isCollapsed}
|
|
106
|
+
<div>
|
|
107
|
+
{@render rows(group)}
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
</div>
|
|
111
|
+
{/each}
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<!-- No entrance motion. Four stacked animations made the last group of a
|
|
115
|
+
40-row board arrive two seconds late. Working surfaces don't animate in. -->
|
|
116
|
+
<!-- No `overflow: hidden` either: it clipped anything a row opened. -->
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { default as DetailEmpty } from "./detail-empty.svelte";
|
|
2
|
+
export { default as DetailHeader } from "./detail-header.svelte";
|
|
3
|
+
export { default as DetailPanel } from "./detail-panel.svelte";
|
|
4
|
+
export { default as DetailRow } from "./detail-row.svelte";
|
|
5
|
+
export { default as DetailStack } from "./detail-stack.svelte";
|
|
6
|
+
export { default as EmptyState } from "./empty-state.svelte";
|
|
7
|
+
export { default as FilterItem } from "./filter-item.svelte";
|
|
8
|
+
export { default as PrevNext } from "./prev-next.svelte";
|
|
9
|
+
export { stepTo } from "./step.js";
|
|
10
|
+
export { default as NoticeBar } from "./notice-bar.svelte";
|
|
11
|
+
export { default as RailBody } from "./rail-body.svelte";
|
|
12
|
+
export { default as RailEmpty } from "./rail-empty.svelte";
|
|
13
|
+
export { default as RailHead } from "./rail-head.svelte";
|
|
14
|
+
export { default as RailRow } from "./rail-row.svelte";
|
|
15
|
+
export { default as SectionLabel } from "./section-label.svelte";
|
|
16
|
+
export { queueRailClass, queueRailWidth } from "./queue-rail.js";
|
|
17
|
+
export { default as FilterPopover } from "./filter-popover.svelte";
|
|
18
|
+
export { filterSectionClass } from "./filter-section.js";
|
|
19
|
+
export { default as GroupedList } from "./grouped-list.svelte";
|
|
20
|
+
export { default as ListPageShell } from "./list-page-shell.svelte";
|
|
21
|
+
export { default as MasterDetail } from "./master-detail.svelte";
|
|
22
|
+
// The segmented control isn't re-exported here. Two import paths drifted, so
|
|
23
|
+
// its one home is `@heyramzi/ui/components/segmented`.
|
|
24
|
+
export { default as ToolbarSearch } from "./toolbar-search.svelte";
|
|
25
|
+
export { toolbarTriggerClass } from "./toolbar-trigger.js";
|
|
26
|
+
export { listTable } from "./list-table.js";
|
|
27
|
+
export type { ViewMode } from "./types.js";
|
|
28
|
+
export { getSectionHost, setSectionHost, type SectionHost } from "./section-host.js";
|