@delacour/react-native-ui 0.4.0-alpha.20261020090817 → 0.4.0-alpha.20261020154302
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/package.json +66 -2
- package/src/components/animated-badge/AGENTS.md +132 -0
- package/src/components/animated-badge/animated-badge-content.tsx +58 -0
- package/src/components/animated-badge/animated-badge-glyph.tsx +118 -0
- package/src/components/animated-badge/animated-badge-measure.tsx +69 -0
- package/src/components/animated-badge/animated-badge.tsx +181 -0
- package/src/components/animated-badge/animated-badge.types.ts +28 -0
- package/src/components/animated-badge/animated-badge.variants.test.ts +290 -0
- package/src/components/animated-badge/animated-badge.variants.ts +213 -0
- package/src/components/animated-badge/index.ts +17 -0
- package/src/components/animated-badge/use-animated-badge-roll.ts +122 -0
- package/src/components/attachment/AGENTS.md +156 -0
- package/src/components/attachment/attachment-content.tsx +34 -0
- package/src/components/attachment/attachment-group.tsx +91 -0
- package/src/components/attachment/attachment-meta.tsx +34 -0
- package/src/components/attachment/attachment-name.tsx +41 -0
- package/src/components/attachment/attachment-preview.tsx +73 -0
- package/src/components/attachment/attachment-progress.tsx +60 -0
- package/src/components/attachment/attachment-remove.tsx +55 -0
- package/src/components/attachment/attachment-retry.tsx +54 -0
- package/src/components/attachment/attachment.context.tsx +121 -0
- package/src/components/attachment/attachment.tsx +468 -0
- package/src/components/attachment/attachment.types.ts +31 -0
- package/src/components/attachment/attachment.utils.test.ts +358 -0
- package/src/components/attachment/attachment.utils.ts +393 -0
- package/src/components/attachment/attachment.variants.test.ts +306 -0
- package/src/components/attachment/attachment.variants.ts +251 -0
- package/src/components/attachment/index.ts +59 -0
- package/src/components/avatar/AGENTS.md +5 -2
- package/src/components/avatar/avatar.variants.test.ts +7 -1
- package/src/components/avatar/avatar.variants.ts +10 -1
- package/src/components/breadcrumb/AGENTS.md +112 -0
- package/src/components/breadcrumb/breadcrumb-ellipsis.tsx +72 -0
- package/src/components/breadcrumb/breadcrumb-glyph.tsx +17 -0
- package/src/components/breadcrumb/breadcrumb-item.tsx +21 -0
- package/src/components/breadcrumb/breadcrumb-link.tsx +63 -0
- package/src/components/breadcrumb/breadcrumb-list.tsx +135 -0
- package/src/components/breadcrumb/breadcrumb-page.tsx +35 -0
- package/src/components/breadcrumb/breadcrumb-separator.tsx +63 -0
- package/src/components/breadcrumb/breadcrumb.context.tsx +61 -0
- package/src/components/breadcrumb/breadcrumb.tsx +94 -0
- package/src/components/breadcrumb/breadcrumb.types.ts +11 -0
- package/src/components/breadcrumb/breadcrumb.variants.test.ts +292 -0
- package/src/components/breadcrumb/breadcrumb.variants.ts +246 -0
- package/src/components/breadcrumb/index.ts +34 -0
- package/src/components/circular-text/AGENTS.md +160 -0
- package/src/components/circular-text/circular-text-ring.tsx +72 -0
- package/src/components/circular-text/circular-text-spin.ts +69 -0
- package/src/components/circular-text/circular-text.tsx +249 -0
- package/src/components/circular-text/circular-text.types.ts +53 -0
- package/src/components/circular-text/circular-text.variants.test.ts +347 -0
- package/src/components/circular-text/circular-text.variants.ts +271 -0
- package/src/components/circular-text/index.ts +19 -0
- package/src/components/color-picker/AGENTS.md +128 -0
- package/src/components/color-picker/color-picker-alpha.tsx +23 -0
- package/src/components/color-picker/color-picker-area.tsx +201 -0
- package/src/components/color-picker/color-picker-checkerboard.tsx +64 -0
- package/src/components/color-picker/color-picker-content.tsx +33 -0
- package/src/components/color-picker/color-picker-gradient.tsx +78 -0
- package/src/components/color-picker/color-picker-hue.tsx +16 -0
- package/src/components/color-picker/color-picker-input.tsx +140 -0
- package/src/components/color-picker/color-picker-preview.tsx +42 -0
- package/src/components/color-picker/color-picker-sheet.tsx +58 -0
- package/src/components/color-picker/color-picker-swatch.tsx +75 -0
- package/src/components/color-picker/color-picker-swatches.tsx +32 -0
- package/src/components/color-picker/color-picker-thumb.tsx +104 -0
- package/src/components/color-picker/color-picker-track.tsx +217 -0
- package/src/components/color-picker/color-picker-trigger.tsx +53 -0
- package/src/components/color-picker/color-picker.color.test.ts +366 -0
- package/src/components/color-picker/color-picker.color.ts +399 -0
- package/src/components/color-picker/color-picker.context.tsx +105 -0
- package/src/components/color-picker/color-picker.tsx +330 -0
- package/src/components/color-picker/color-picker.types.ts +22 -0
- package/src/components/color-picker/color-picker.variants.test.ts +253 -0
- package/src/components/color-picker/color-picker.variants.ts +256 -0
- package/src/components/color-picker/index.ts +49 -0
- package/src/components/combobox/AGENTS.md +139 -0
- package/src/components/combobox/combobox-chip-row.tsx +101 -0
- package/src/components/combobox/combobox-create-row.tsx +62 -0
- package/src/components/combobox/combobox-empty.tsx +36 -0
- package/src/components/combobox/combobox-group.tsx +19 -0
- package/src/components/combobox/combobox-item.tsx +28 -0
- package/src/components/combobox/combobox-trigger.tsx +213 -0
- package/src/components/combobox/combobox.collect.test.ts +65 -0
- package/src/components/combobox/combobox.collect.ts +66 -0
- package/src/components/combobox/combobox.context.tsx +106 -0
- package/src/components/combobox/combobox.filter.test.ts +312 -0
- package/src/components/combobox/combobox.filter.ts +291 -0
- package/src/components/combobox/combobox.tsx +643 -0
- package/src/components/combobox/combobox.types.ts +54 -0
- package/src/components/combobox/combobox.variants.test.ts +240 -0
- package/src/components/combobox/combobox.variants.ts +198 -0
- package/src/components/combobox/index.ts +48 -0
- package/src/components/compare/AGENTS.md +150 -0
- package/src/components/compare/compare-after.tsx +29 -0
- package/src/components/compare/compare-before.tsx +60 -0
- package/src/components/compare/compare-handle.tsx +138 -0
- package/src/components/compare/compare-label.tsx +58 -0
- package/src/components/compare/compare.context.tsx +97 -0
- package/src/components/compare/compare.tsx +464 -0
- package/src/components/compare/compare.types.ts +9 -0
- package/src/components/compare/compare.variants.test.ts +548 -0
- package/src/components/compare/compare.variants.ts +459 -0
- package/src/components/compare/index.ts +40 -0
- package/src/components/countdown/AGENTS.md +123 -0
- package/src/components/countdown/countdown-digit.tsx +51 -0
- package/src/components/countdown/countdown-segment.tsx +62 -0
- package/src/components/countdown/countdown.tsx +141 -0
- package/src/components/countdown/countdown.variants.test.ts +283 -0
- package/src/components/countdown/countdown.variants.ts +251 -0
- package/src/components/countdown/index.ts +28 -0
- package/src/components/countdown/use-countdown-clock.ts +80 -0
- package/src/components/date-picker/AGENTS.md +110 -0
- package/src/components/date-picker/date-picker-calendar.tsx +79 -0
- package/src/components/date-picker/date-picker-clear.tsx +33 -0
- package/src/components/date-picker/date-picker-content.tsx +67 -0
- package/src/components/date-picker/date-picker-done.tsx +31 -0
- package/src/components/date-picker/date-picker-icon.tsx +27 -0
- package/src/components/date-picker/date-picker-trigger.tsx +63 -0
- package/src/components/date-picker/date-picker-value.tsx +26 -0
- package/src/components/date-picker/date-picker.context.tsx +105 -0
- package/src/components/date-picker/date-picker.tsx +370 -0
- package/src/components/date-picker/date-picker.types.ts +99 -0
- package/src/components/date-picker/date-picker.variants.test.ts +326 -0
- package/src/components/date-picker/date-picker.variants.ts +304 -0
- package/src/components/date-picker/index.ts +46 -0
- package/src/components/date-time-picker/AGENTS.md +158 -0
- package/src/components/date-time-picker/date-time-picker-calendar.tsx +67 -0
- package/src/components/date-time-picker/date-time-picker-clear.tsx +33 -0
- package/src/components/date-time-picker/date-time-picker-content.tsx +155 -0
- package/src/components/date-time-picker/date-time-picker-done.tsx +34 -0
- package/src/components/date-time-picker/date-time-picker-icon.tsx +27 -0
- package/src/components/date-time-picker/date-time-picker-time.tsx +144 -0
- package/src/components/date-time-picker/date-time-picker-trigger.tsx +63 -0
- package/src/components/date-time-picker/date-time-picker-value.tsx +22 -0
- package/src/components/date-time-picker/date-time-picker.context.tsx +123 -0
- package/src/components/date-time-picker/date-time-picker.tsx +379 -0
- package/src/components/date-time-picker/date-time-picker.types.ts +94 -0
- package/src/components/date-time-picker/date-time-picker.value.test.ts +369 -0
- package/src/components/date-time-picker/date-time-picker.value.ts +321 -0
- package/src/components/date-time-picker/date-time-picker.variants.test.ts +187 -0
- package/src/components/date-time-picker/date-time-picker.variants.ts +145 -0
- package/src/components/date-time-picker/index.ts +61 -0
- package/src/components/direction/AGENTS.md +89 -0
- package/src/components/direction/direction.context.tsx +74 -0
- package/src/components/direction/direction.tsx +84 -0
- package/src/components/direction/direction.variants.test.ts +90 -0
- package/src/components/direction/direction.variants.ts +69 -0
- package/src/components/direction/index.ts +20 -0
- package/src/components/drawer/AGENTS.md +6 -7
- package/src/components/feedback/AGENTS.md +3 -5
- package/src/components/flip-card/AGENTS.md +149 -0
- package/src/components/flip-card/flip-card-back.tsx +22 -0
- package/src/components/flip-card/flip-card-face.tsx +78 -0
- package/src/components/flip-card/flip-card-front.tsx +14 -0
- package/src/components/flip-card/flip-card-trigger.tsx +58 -0
- package/src/components/flip-card/flip-card.context.tsx +81 -0
- package/src/components/flip-card/flip-card.tsx +453 -0
- package/src/components/flip-card/flip-card.types.ts +13 -0
- package/src/components/flip-card/flip-card.variants.test.ts +436 -0
- package/src/components/flip-card/flip-card.variants.ts +346 -0
- package/src/components/flip-card/index.ts +28 -0
- package/src/components/flow/AGENTS.md +127 -0
- package/src/components/flow/flow-background.tsx +85 -0
- package/src/components/flow/flow-connection-preview.tsx +55 -0
- package/src/components/flow/flow-controls.tsx +91 -0
- package/src/components/flow/flow-edge.tsx +174 -0
- package/src/components/flow/flow-geometry.test.ts +513 -0
- package/src/components/flow/flow-geometry.ts +504 -0
- package/src/components/flow/flow-group.tsx +168 -0
- package/src/components/flow/flow-handle.tsx +140 -0
- package/src/components/flow/flow-minimap.tsx +119 -0
- package/src/components/flow/flow-node.tsx +258 -0
- package/src/components/flow/flow-registry.ts +115 -0
- package/src/components/flow/flow-svg.ts +15 -0
- package/src/components/flow/flow.context.tsx +140 -0
- package/src/components/flow/flow.tsx +433 -0
- package/src/components/flow/flow.variants.test.ts +373 -0
- package/src/components/flow/flow.variants.ts +317 -0
- package/src/components/flow/index.ts +63 -0
- package/src/components/frame/AGENTS.md +103 -0
- package/src/components/frame/frame-action.tsx +46 -0
- package/src/components/frame/frame-description.tsx +12 -0
- package/src/components/frame/frame-dividers.tsx +41 -0
- package/src/components/frame/frame-footer.tsx +41 -0
- package/src/components/frame/frame-header.tsx +45 -0
- package/src/components/frame/frame-section.tsx +51 -0
- package/src/components/frame/frame-title.tsx +25 -0
- package/src/components/frame/frame-tray.tsx +59 -0
- package/src/components/frame/frame.context.tsx +81 -0
- package/src/components/frame/frame.tsx +104 -0
- package/src/components/frame/frame.types.ts +9 -0
- package/src/components/frame/frame.variants.test.ts +244 -0
- package/src/components/frame/frame.variants.ts +215 -0
- package/src/components/frame/index.ts +25 -0
- package/src/components/grid-item/AGENTS.md +139 -0
- package/src/components/grid-item/grid-item-actions.tsx +35 -0
- package/src/components/grid-item/grid-item-background.tsx +26 -0
- package/src/components/grid-item/grid-item-description.tsx +21 -0
- package/src/components/grid-item/grid-item-footer.tsx +14 -0
- package/src/components/grid-item/grid-item-group.tsx +188 -0
- package/src/components/grid-item/grid-item-media.tsx +30 -0
- package/src/components/grid-item/grid-item-title.tsx +23 -0
- package/src/components/grid-item/grid-item-value.tsx +24 -0
- package/src/components/grid-item/grid-item.context.tsx +155 -0
- package/src/components/grid-item/grid-item.layout.test.ts +289 -0
- package/src/components/grid-item/grid-item.layout.ts +190 -0
- package/src/components/grid-item/grid-item.tsx +208 -0
- package/src/components/grid-item/grid-item.types.ts +8 -0
- package/src/components/grid-item/grid-item.variants.test.ts +240 -0
- package/src/components/grid-item/grid-item.variants.ts +166 -0
- package/src/components/grid-item/index.ts +47 -0
- package/src/components/image-viewer/AGENTS.md +181 -0
- package/src/components/image-viewer/image-viewer-chrome.tsx +78 -0
- package/src/components/image-viewer/image-viewer-close.tsx +36 -0
- package/src/components/image-viewer/image-viewer-image.tsx +37 -0
- package/src/components/image-viewer/image-viewer-layer.tsx +629 -0
- package/src/components/image-viewer/image-viewer-page.tsx +190 -0
- package/src/components/image-viewer/image-viewer-trigger.tsx +188 -0
- package/src/components/image-viewer/image-viewer.context.tsx +114 -0
- package/src/components/image-viewer/image-viewer.tsx +306 -0
- package/src/components/image-viewer/image-viewer.types.ts +34 -0
- package/src/components/image-viewer/image-viewer.variants.test.ts +449 -0
- package/src/components/image-viewer/image-viewer.variants.ts +372 -0
- package/src/components/image-viewer/index.ts +54 -0
- package/src/components/input/AGENTS.md +51 -7
- package/src/components/input/index.ts +15 -1
- package/src/components/input/input-group-block.tsx +71 -0
- package/src/components/input/input-group-button.tsx +71 -0
- package/src/components/input/input-group-decorator.tsx +43 -8
- package/src/components/input/input-group-prefix.tsx +2 -2
- package/src/components/input/input-group-separator.tsx +37 -0
- package/src/components/input/input-group-suffix.tsx +2 -2
- package/src/components/input/input-group.tsx +96 -16
- package/src/components/input/input.context.tsx +32 -1
- package/src/components/input/input.tsx +12 -1
- package/src/components/input/input.types.ts +13 -0
- package/src/components/input/input.variants.test.ts +247 -3
- package/src/components/input/input.variants.ts +163 -8
- package/src/components/leaderboard/AGENTS.md +100 -0
- package/src/components/leaderboard/index.ts +35 -0
- package/src/components/leaderboard/leaderboard-empty.tsx +23 -0
- package/src/components/leaderboard/leaderboard-movement.tsx +46 -0
- package/src/components/leaderboard/leaderboard-podium-place.tsx +162 -0
- package/src/components/leaderboard/leaderboard-podium.tsx +72 -0
- package/src/components/leaderboard/leaderboard-row.tsx +78 -0
- package/src/components/leaderboard/leaderboard.context.tsx +46 -0
- package/src/components/leaderboard/leaderboard.tsx +161 -0
- package/src/components/leaderboard/leaderboard.types.ts +21 -0
- package/src/components/leaderboard/leaderboard.variants.test.ts +509 -0
- package/src/components/leaderboard/leaderboard.variants.ts +341 -0
- package/src/components/markdown-editor/AGENTS.md +144 -0
- package/src/components/markdown-editor/index.ts +58 -0
- package/src/components/markdown-editor/markdown-editor-action.tsx +74 -0
- package/src/components/markdown-editor/markdown-editor-input.tsx +82 -0
- package/src/components/markdown-editor/markdown-editor-preview.tsx +63 -0
- package/src/components/markdown-editor/markdown-editor-render.tsx +164 -0
- package/src/components/markdown-editor/markdown-editor-toolbar.tsx +106 -0
- package/src/components/markdown-editor/markdown-editor.commands.test.ts +464 -0
- package/src/components/markdown-editor/markdown-editor.commands.ts +729 -0
- package/src/components/markdown-editor/markdown-editor.context.tsx +103 -0
- package/src/components/markdown-editor/markdown-editor.parse.test.ts +257 -0
- package/src/components/markdown-editor/markdown-editor.parse.ts +434 -0
- package/src/components/markdown-editor/markdown-editor.tsx +330 -0
- package/src/components/markdown-editor/markdown-editor.types.ts +62 -0
- package/src/components/markdown-editor/markdown-editor.variants.test.ts +204 -0
- package/src/components/markdown-editor/markdown-editor.variants.ts +240 -0
- package/src/components/marker/AGENTS.md +119 -0
- package/src/components/marker/index.ts +16 -0
- package/src/components/marker/marker-content.tsx +46 -0
- package/src/components/marker/marker-icon.tsx +27 -0
- package/src/components/marker/marker-shimmer-clock.ts +60 -0
- package/src/components/marker/marker.context.tsx +82 -0
- package/src/components/marker/marker.tsx +192 -0
- package/src/components/marker/marker.variants.test.ts +187 -0
- package/src/components/marker/marker.variants.ts +121 -0
- package/src/components/marquee/AGENTS.md +147 -0
- package/src/components/marquee/index.ts +21 -0
- package/src/components/marquee/marquee-fade.tsx +62 -0
- package/src/components/marquee/marquee-group.tsx +38 -0
- package/src/components/marquee/marquee-scroller.tsx +29 -0
- package/src/components/marquee/marquee-track.tsx +167 -0
- package/src/components/marquee/marquee.context.tsx +42 -0
- package/src/components/marquee/marquee.tsx +142 -0
- package/src/components/marquee/marquee.types.ts +12 -0
- package/src/components/marquee/marquee.variants.test.ts +289 -0
- package/src/components/marquee/marquee.variants.ts +230 -0
- package/src/components/message/AGENTS.md +139 -0
- package/src/components/message/index.ts +46 -0
- package/src/components/message/message-actions.tsx +12 -0
- package/src/components/message/message-attachments.tsx +16 -0
- package/src/components/message/message-author.tsx +25 -0
- package/src/components/message/message-avatar.tsx +26 -0
- package/src/components/message/message-bubble.tsx +67 -0
- package/src/components/message/message-header.tsx +12 -0
- package/src/components/message/message-reactions.tsx +43 -0
- package/src/components/message/message-status.tsx +65 -0
- package/src/components/message/message-text.tsx +29 -0
- package/src/components/message/message-timestamp.tsx +23 -0
- package/src/components/message/message-typing.tsx +85 -0
- package/src/components/message/message.context.tsx +93 -0
- package/src/components/message/message.tsx +301 -0
- package/src/components/message/message.types.ts +24 -0
- package/src/components/message/message.utils.test.ts +307 -0
- package/src/components/message/message.utils.ts +329 -0
- package/src/components/message/message.variants.test.ts +329 -0
- package/src/components/message/message.variants.ts +240 -0
- package/src/components/message-scroller/AGENTS.md +132 -0
- package/src/components/message-scroller/index.ts +33 -0
- package/src/components/message-scroller/message-scroller-date-separator.tsx +40 -0
- package/src/components/message-scroller/message-scroller-jump-button.tsx +100 -0
- package/src/components/message-scroller/message-scroller-list.tsx +111 -0
- package/src/components/message-scroller/message-scroller-loading-older.tsx +38 -0
- package/src/components/message-scroller/message-scroller-unread-divider.tsx +43 -0
- package/src/components/message-scroller/message-scroller.context.tsx +130 -0
- package/src/components/message-scroller/message-scroller.tsx +249 -0
- package/src/components/message-scroller/message-scroller.types.ts +121 -0
- package/src/components/message-scroller/message-scroller.utils.test.ts +430 -0
- package/src/components/message-scroller/message-scroller.utils.ts +350 -0
- package/src/components/message-scroller/message-scroller.variants.test.ts +197 -0
- package/src/components/message-scroller/message-scroller.variants.ts +98 -0
- package/src/components/message-scroller/use-message-scroller-state.ts +241 -0
- package/src/components/number-input/AGENTS.md +156 -0
- package/src/components/number-input/index.ts +57 -0
- package/src/components/number-input/number-input-decrement.tsx +24 -0
- package/src/components/number-input/number-input-field.tsx +119 -0
- package/src/components/number-input/number-input-increment.tsx +24 -0
- package/src/components/number-input/number-input-stepper.tsx +147 -0
- package/src/components/number-input/number-input.context.tsx +114 -0
- package/src/components/number-input/number-input.format.test.ts +516 -0
- package/src/components/number-input/number-input.format.ts +512 -0
- package/src/components/number-input/number-input.tsx +376 -0
- package/src/components/number-input/number-input.types.ts +31 -0
- package/src/components/number-input/number-input.variants.test.ts +100 -0
- package/src/components/number-input/number-input.variants.ts +103 -0
- package/src/components/number-input/use-step-repeat.ts +55 -0
- package/src/components/otp-input/AGENTS.md +122 -0
- package/src/components/otp-input/index.ts +48 -0
- package/src/components/otp-input/otp-input-group.tsx +16 -0
- package/src/components/otp-input/otp-input-separator.tsx +16 -0
- package/src/components/otp-input/otp-input-slot.tsx +117 -0
- package/src/components/otp-input/otp-input.context.tsx +73 -0
- package/src/components/otp-input/otp-input.logic.test.ts +357 -0
- package/src/components/otp-input/otp-input.logic.ts +224 -0
- package/src/components/otp-input/otp-input.tsx +335 -0
- package/src/components/otp-input/otp-input.variants.test.ts +213 -0
- package/src/components/otp-input/otp-input.variants.ts +153 -0
- package/src/components/page-header/AGENTS.md +160 -0
- package/src/components/page-header/index.ts +41 -0
- package/src/components/page-header/page-header-actions.tsx +23 -0
- package/src/components/page-header/page-header-avatar.tsx +93 -0
- package/src/components/page-header/page-header-content.tsx +24 -0
- package/src/components/page-header/page-header-cover.tsx +177 -0
- package/src/components/page-header/page-header-description.tsx +33 -0
- package/src/components/page-header/page-header-meta.tsx +32 -0
- package/src/components/page-header/page-header-stat.tsx +68 -0
- package/src/components/page-header/page-header-stats.tsx +71 -0
- package/src/components/page-header/page-header-title.tsx +30 -0
- package/src/components/page-header/page-header.context.tsx +115 -0
- package/src/components/page-header/page-header.tsx +155 -0
- package/src/components/page-header/page-header.types.ts +8 -0
- package/src/components/page-header/page-header.utils.test.ts +131 -0
- package/src/components/page-header/page-header.utils.ts +118 -0
- package/src/components/page-header/page-header.variants.test.ts +287 -0
- package/src/components/page-header/page-header.variants.ts +290 -0
- package/src/components/pagination/AGENTS.md +127 -0
- package/src/components/pagination/index.ts +51 -0
- package/src/components/pagination/pagination-compact.tsx +56 -0
- package/src/components/pagination/pagination-control.tsx +92 -0
- package/src/components/pagination/pagination-ellipsis.tsx +60 -0
- package/src/components/pagination/pagination-item.tsx +79 -0
- package/src/components/pagination/pagination-next.tsx +10 -0
- package/src/components/pagination/pagination-previous.tsx +10 -0
- package/src/components/pagination/pagination-status.tsx +36 -0
- package/src/components/pagination/pagination-summary.tsx +16 -0
- package/src/components/pagination/pagination.context.tsx +78 -0
- package/src/components/pagination/pagination.tsx +238 -0
- package/src/components/pagination/pagination.types.ts +10 -0
- package/src/components/pagination/pagination.variants.test.ts +474 -0
- package/src/components/pagination/pagination.variants.ts +343 -0
- package/src/components/planner/AGENTS.md +180 -0
- package/src/components/planner/index.ts +72 -0
- package/src/components/planner/planner-action.tsx +16 -0
- package/src/components/planner/planner-dates.test.ts +287 -0
- package/src/components/planner/planner-dates.ts +206 -0
- package/src/components/planner/planner-day.tsx +271 -0
- package/src/components/planner/planner-details.tsx +75 -0
- package/src/components/planner/planner-footer.tsx +12 -0
- package/src/components/planner/planner-grid.tsx +139 -0
- package/src/components/planner/planner-header.tsx +17 -0
- package/src/components/planner/planner-legend.tsx +56 -0
- package/src/components/planner/planner-nav.tsx +55 -0
- package/src/components/planner/planner-scroller.tsx +116 -0
- package/src/components/planner/planner-summary.tsx +25 -0
- package/src/components/planner/planner-title.tsx +29 -0
- package/src/components/planner/planner-today.tsx +32 -0
- package/src/components/planner/planner-weekdays.tsx +34 -0
- package/src/components/planner/planner.context.tsx +108 -0
- package/src/components/planner/planner.tsx +289 -0
- package/src/components/planner/planner.types.ts +50 -0
- package/src/components/planner/planner.variants.test.ts +354 -0
- package/src/components/planner/planner.variants.ts +324 -0
- package/src/components/planner/use-planner-today.ts +51 -0
- package/src/components/post/AGENTS.md +130 -0
- package/src/components/post/index.ts +46 -0
- package/src/components/post/post-action.tsx +31 -0
- package/src/components/post/post-author.tsx +114 -0
- package/src/components/post/post-body.tsx +123 -0
- package/src/components/post/post-community.tsx +80 -0
- package/src/components/post/post-footer.tsx +16 -0
- package/src/components/post/post-header.tsx +18 -0
- package/src/components/post/post-media.tsx +170 -0
- package/src/components/post/post-stat-count.tsx +77 -0
- package/src/components/post/post-stat.tsx +126 -0
- package/src/components/post/post-title.tsx +20 -0
- package/src/components/post/post-votes.tsx +92 -0
- package/src/components/post/post.context.tsx +59 -0
- package/src/components/post/post.tsx +132 -0
- package/src/components/post/post.types.ts +8 -0
- package/src/components/post/post.utils.test.ts +277 -0
- package/src/components/post/post.utils.ts +268 -0
- package/src/components/post/post.variants.test.ts +328 -0
- package/src/components/post/post.variants.ts +325 -0
- package/src/components/pressable/AGENTS.md +7 -1
- package/src/components/pressable/pressable.tsx +9 -3
- package/src/components/pressable/pressable.variants.test.ts +44 -0
- package/src/components/pressable/pressable.variants.ts +33 -0
- package/src/components/qr-code/AGENTS.md +142 -0
- package/src/components/qr-code/index.ts +39 -0
- package/src/components/qr-code/qr-code-logo.tsx +40 -0
- package/src/components/qr-code/qr-code.constants.ts +58 -0
- package/src/components/qr-code/qr-code.context.tsx +37 -0
- package/src/components/qr-code/qr-code.encode.test.ts +237 -0
- package/src/components/qr-code/qr-code.encode.ts +290 -0
- package/src/components/qr-code/qr-code.fixtures.ts +450 -0
- package/src/components/qr-code/qr-code.format.test.ts +77 -0
- package/src/components/qr-code/qr-code.format.ts +68 -0
- package/src/components/qr-code/qr-code.gf.test.ts +96 -0
- package/src/components/qr-code/qr-code.gf.ts +77 -0
- package/src/components/qr-code/qr-code.logo.test.ts +109 -0
- package/src/components/qr-code/qr-code.logo.ts +175 -0
- package/src/components/qr-code/qr-code.mask.test.ts +157 -0
- package/src/components/qr-code/qr-code.mask.ts +135 -0
- package/src/components/qr-code/qr-code.matrix.test.ts +129 -0
- package/src/components/qr-code/qr-code.matrix.ts +151 -0
- package/src/components/qr-code/qr-code.path.test.ts +149 -0
- package/src/components/qr-code/qr-code.path.ts +209 -0
- package/src/components/qr-code/qr-code.tables.test.ts +142 -0
- package/src/components/qr-code/qr-code.tables.ts +148 -0
- package/src/components/qr-code/qr-code.test-helpers.ts +304 -0
- package/src/components/qr-code/qr-code.tsx +165 -0
- package/src/components/qr-code/qr-code.types.ts +44 -0
- package/src/components/qr-code/qr-code.variants.test.ts +161 -0
- package/src/components/qr-code/qr-code.variants.ts +155 -0
- package/src/components/qr-code/qr-code.warn.ts +8 -0
- package/src/components/qr-code/use-qr-code.ts +15 -0
- package/src/components/questionnaire/AGENTS.md +124 -0
- package/src/components/questionnaire/index.ts +75 -0
- package/src/components/questionnaire/questionnaire-back.tsx +41 -0
- package/src/components/questionnaire/questionnaire-control.tsx +324 -0
- package/src/components/questionnaire/questionnaire-footer.tsx +50 -0
- package/src/components/questionnaire/questionnaire-next.tsx +57 -0
- package/src/components/questionnaire/questionnaire-progress.tsx +91 -0
- package/src/components/questionnaire/questionnaire-question.tsx +143 -0
- package/src/components/questionnaire/questionnaire-skip.tsx +42 -0
- package/src/components/questionnaire/questionnaire-spacer.tsx +13 -0
- package/src/components/questionnaire/questionnaire-submit.tsx +57 -0
- package/src/components/questionnaire/questionnaire-title.tsx +21 -0
- package/src/components/questionnaire/questionnaire.context.tsx +117 -0
- package/src/components/questionnaire/questionnaire.logic.test.ts +836 -0
- package/src/components/questionnaire/questionnaire.logic.ts +760 -0
- package/src/components/questionnaire/questionnaire.tsx +370 -0
- package/src/components/questionnaire/questionnaire.types.ts +182 -0
- package/src/components/questionnaire/questionnaire.variants.test.ts +252 -0
- package/src/components/questionnaire/questionnaire.variants.ts +230 -0
- package/src/components/scroll-blur/AGENTS.md +112 -0
- package/src/components/scroll-blur/index.ts +20 -0
- package/src/components/scroll-blur/scroll-blur-band.tsx +108 -0
- package/src/components/scroll-blur/scroll-blur.context.tsx +31 -0
- package/src/components/scroll-blur/scroll-blur.tsx +106 -0
- package/src/components/scroll-blur/scroll-blur.types.ts +61 -0
- package/src/components/scroll-blur/scroll-blur.variants.test.ts +82 -0
- package/src/components/scroll-blur/scroll-blur.variants.ts +96 -0
- package/src/components/scroll-canvas/AGENTS.md +131 -0
- package/src/components/scroll-canvas/index.ts +24 -0
- package/src/components/scroll-canvas/scroll-canvas-image.tsx +81 -0
- package/src/components/scroll-canvas/scroll-canvas-sequence.tsx +95 -0
- package/src/components/scroll-canvas/scroll-canvas.tsx +111 -0
- package/src/components/scroll-canvas/scroll-canvas.types.ts +60 -0
- package/src/components/scroll-canvas/scroll-canvas.variants.test.ts +232 -0
- package/src/components/scroll-canvas/scroll-canvas.variants.ts +200 -0
- package/src/components/scroll-canvas/use-frame-progress.ts +131 -0
- package/src/components/scroll-fade/AGENTS.md +139 -0
- package/src/components/scroll-fade/index.ts +8 -0
- package/src/components/scroll-fade/scroll-fade-edge.tsx +73 -0
- package/src/components/scroll-fade/scroll-fade.tsx +127 -0
- package/src/components/scroll-fade/scroll-fade.variants.test.ts +50 -0
- package/src/components/scroll-fade/scroll-fade.variants.ts +41 -0
- package/src/components/scroll-header/AGENTS.md +169 -0
- package/src/components/scroll-header/index.ts +32 -0
- package/src/components/scroll-header/scroll-header-bar-surface.tsx +75 -0
- package/src/components/scroll-header/scroll-header-bar-title.tsx +49 -0
- package/src/components/scroll-header/scroll-header-bar.tsx +83 -0
- package/src/components/scroll-header/scroll-header-cover.tsx +73 -0
- package/src/components/scroll-header/scroll-header-flat-list.tsx +97 -0
- package/src/components/scroll-header/scroll-header-inset.tsx +20 -0
- package/src/components/scroll-header/scroll-header-large.tsx +67 -0
- package/src/components/scroll-header/scroll-header-root.tsx +201 -0
- package/src/components/scroll-header/scroll-header-scroll-view.tsx +56 -0
- package/src/components/scroll-header/scroll-header.context.tsx +27 -0
- package/src/components/scroll-header/scroll-header.tsx +70 -0
- package/src/components/scroll-header/scroll-header.types.ts +66 -0
- package/src/components/scroll-header/scroll-header.variants.test.ts +173 -0
- package/src/components/scroll-header/scroll-header.variants.ts +173 -0
- package/src/components/scroll-header/use-scroll-header-scroll-props.ts +57 -0
- package/src/components/scroll-text/AGENTS.md +116 -0
- package/src/components/scroll-text/index.ts +34 -0
- package/src/components/scroll-text/scroll-text-source.ts +105 -0
- package/src/components/scroll-text/scroll-text-unit.tsx +86 -0
- package/src/components/scroll-text/scroll-text.tsx +277 -0
- package/src/components/scroll-text/scroll-text.types.ts +36 -0
- package/src/components/scroll-text/scroll-text.variants.test.ts +525 -0
- package/src/components/scroll-text/scroll-text.variants.ts +451 -0
- package/src/components/search-bar/AGENTS.md +109 -0
- package/src/components/search-bar/index.ts +29 -0
- package/src/components/search-bar/search-bar-cancel-reveal.tsx +90 -0
- package/src/components/search-bar/search-bar-cancel.tsx +48 -0
- package/src/components/search-bar/search-bar-clear.tsx +46 -0
- package/src/components/search-bar/search-bar-tokens.tsx +58 -0
- package/src/components/search-bar/search-bar.context.tsx +80 -0
- package/src/components/search-bar/search-bar.debounce.test.ts +134 -0
- package/src/components/search-bar/search-bar.debounce.ts +76 -0
- package/src/components/search-bar/search-bar.responder.ts +14 -0
- package/src/components/search-bar/search-bar.tsx +403 -0
- package/src/components/search-bar/search-bar.types.ts +23 -0
- package/src/components/search-bar/search-bar.variants.test.ts +198 -0
- package/src/components/search-bar/search-bar.variants.ts +173 -0
- package/src/components/section-progress/AGENTS.md +134 -0
- package/src/components/section-progress/index.ts +37 -0
- package/src/components/section-progress/section-progress-item.tsx +70 -0
- package/src/components/section-progress/section-progress-panel.tsx +77 -0
- package/src/components/section-progress/section-progress-pill.tsx +61 -0
- package/src/components/section-progress/section-progress-ring.tsx +73 -0
- package/src/components/section-progress/section-progress.context.tsx +77 -0
- package/src/components/section-progress/section-progress.tsx +336 -0
- package/src/components/section-progress/section-progress.variants.test.ts +319 -0
- package/src/components/section-progress/section-progress.variants.ts +260 -0
- package/src/components/section-rail/AGENTS.md +103 -0
- package/src/components/section-rail/index.ts +38 -0
- package/src/components/section-rail/section-rail-bar.tsx +60 -0
- package/src/components/section-rail/section-rail-content.tsx +92 -0
- package/src/components/section-rail/section-rail-item.tsx +80 -0
- package/src/components/section-rail/section-rail-scrim.tsx +26 -0
- package/src/components/section-rail/section-rail-trigger.tsx +150 -0
- package/src/components/section-rail/section-rail.context.tsx +86 -0
- package/src/components/section-rail/section-rail.tsx +305 -0
- package/src/components/section-rail/section-rail.variants.test.ts +325 -0
- package/src/components/section-rail/section-rail.variants.ts +238 -0
- package/src/components/select/AGENTS.md +126 -0
- package/src/components/select/index.ts +46 -0
- package/src/components/select/select-group.tsx +20 -0
- package/src/components/select/select-item.tsx +30 -0
- package/src/components/select/select-option-row.tsx +154 -0
- package/src/components/select/select-trigger.tsx +161 -0
- package/src/components/select/select.collect.test.ts +80 -0
- package/src/components/select/select.collect.ts +74 -0
- package/src/components/select/select.context.tsx +88 -0
- package/src/components/select/select.tsx +396 -0
- package/src/components/select/select.types.ts +62 -0
- package/src/components/select/select.variants.test.ts +568 -0
- package/src/components/select/select.variants.ts +473 -0
- package/src/components/signature/AGENTS.md +114 -0
- package/src/components/signature/index.ts +58 -0
- package/src/components/signature/signature-action-button.tsx +63 -0
- package/src/components/signature/signature-alternative.tsx +44 -0
- package/src/components/signature/signature-clear.tsx +14 -0
- package/src/components/signature/signature-live-path.tsx +41 -0
- package/src/components/signature/signature-pad.tsx +223 -0
- package/src/components/signature/signature-path.tsx +56 -0
- package/src/components/signature/signature-redo.tsx +14 -0
- package/src/components/signature/signature-toolbar.tsx +28 -0
- package/src/components/signature/signature-undo.tsx +14 -0
- package/src/components/signature/signature.context.tsx +105 -0
- package/src/components/signature/signature.stroke.test.ts +413 -0
- package/src/components/signature/signature.stroke.ts +392 -0
- package/src/components/signature/signature.tsx +379 -0
- package/src/components/signature/signature.types.ts +65 -0
- package/src/components/signature/signature.variants.test.ts +245 -0
- package/src/components/signature/signature.variants.ts +229 -0
- package/src/components/sketch/AGENTS.md +245 -0
- package/src/components/sketch/index.ts +66 -0
- package/src/components/sketch/sketch-canvas.tsx +286 -0
- package/src/components/sketch/sketch-size.tsx +53 -0
- package/src/components/sketch/sketch-swatches.tsx +54 -0
- package/src/components/sketch/sketch-tool.tsx +104 -0
- package/src/components/sketch/sketch-toolbar.tsx +64 -0
- package/src/components/sketch/sketch-undo.tsx +41 -0
- package/src/components/sketch/sketch.context.tsx +103 -0
- package/src/components/sketch/sketch.paths.test.ts +359 -0
- package/src/components/sketch/sketch.paths.ts +324 -0
- package/src/components/sketch/sketch.skia.ts +88 -0
- package/src/components/sketch/sketch.tsx +410 -0
- package/src/components/sketch/sketch.types.ts +46 -0
- package/src/components/sketch/sketch.variants.test.ts +221 -0
- package/src/components/sketch/sketch.variants.ts +211 -0
- package/src/components/sortable/AGENTS.md +121 -0
- package/src/components/sortable/index.ts +39 -0
- package/src/components/sortable/sortable-handle.tsx +79 -0
- package/src/components/sortable/sortable-item.tsx +198 -0
- package/src/components/sortable/sortable.context.tsx +135 -0
- package/src/components/sortable/sortable.tsx +464 -0
- package/src/components/sortable/sortable.types.ts +25 -0
- package/src/components/sortable/sortable.variants.test.ts +402 -0
- package/src/components/sortable/sortable.variants.ts +335 -0
- package/src/components/sortable/use-sortable-drag-gesture.ts +54 -0
- package/src/components/split-view/AGENTS.md +193 -0
- package/src/components/split-view/index.ts +20 -0
- package/src/components/split-view/split-view-bottom.tsx +21 -0
- package/src/components/split-view/split-view-drag-area.tsx +223 -0
- package/src/components/split-view/split-view-handle.tsx +29 -0
- package/src/components/split-view/split-view-top.tsx +28 -0
- package/src/components/split-view/split-view.context.tsx +87 -0
- package/src/components/split-view/split-view.tsx +315 -0
- package/src/components/split-view/split-view.types.ts +10 -0
- package/src/components/split-view/split-view.variants.test.ts +380 -0
- package/src/components/split-view/split-view.variants.ts +326 -0
- package/src/components/splitter/AGENTS.md +194 -0
- package/src/components/splitter/index.ts +32 -0
- package/src/components/splitter/splitter-grip.tsx +30 -0
- package/src/components/splitter/splitter-handle.tsx +269 -0
- package/src/components/splitter/splitter-pane.tsx +70 -0
- package/src/components/splitter/splitter.context.tsx +123 -0
- package/src/components/splitter/splitter.math.test.ts +134 -0
- package/src/components/splitter/splitter.math.ts +113 -0
- package/src/components/splitter/splitter.tsx +341 -0
- package/src/components/splitter/splitter.types.ts +5 -0
- package/src/components/splitter/splitter.variants.test.ts +615 -0
- package/src/components/splitter/splitter.variants.ts +604 -0
- package/src/components/support/AGENTS.md +148 -0
- package/src/components/support/index.ts +58 -0
- package/src/components/support/support-agent.tsx +81 -0
- package/src/components/support/support-article.tsx +27 -0
- package/src/components/support/support-articles.tsx +21 -0
- package/src/components/support/support-channel.tsx +52 -0
- package/src/components/support/support-channels.tsx +21 -0
- package/src/components/support/support-conversation.tsx +74 -0
- package/src/components/support/support-conversations.tsx +21 -0
- package/src/components/support/support-handoff.tsx +51 -0
- package/src/components/support/support-header.tsx +33 -0
- package/src/components/support/support-note.tsx +54 -0
- package/src/components/support/support-replies.tsx +45 -0
- package/src/components/support/support-reply.tsx +41 -0
- package/src/components/support/support-resolution.tsx +37 -0
- package/src/components/support/support-section.tsx +38 -0
- package/src/components/support/support-status.tsx +49 -0
- package/src/components/support/support-ticket.tsx +37 -0
- package/src/components/support/support-topic.tsx +75 -0
- package/src/components/support/support-topics.tsx +76 -0
- package/src/components/support/support-typing.tsx +91 -0
- package/src/components/support/support.context.tsx +80 -0
- package/src/components/support/support.tsx +112 -0
- package/src/components/support/support.types.ts +24 -0
- package/src/components/support/support.utils.test.ts +214 -0
- package/src/components/support/support.utils.ts +206 -0
- package/src/components/support/support.variants.test.ts +198 -0
- package/src/components/support/support.variants.ts +124 -0
- package/src/components/table/AGENTS.md +125 -0
- package/src/components/table/index.ts +57 -0
- package/src/components/table/table-body.tsx +32 -0
- package/src/components/table/table-caption.tsx +16 -0
- package/src/components/table/table-cell.tsx +62 -0
- package/src/components/table/table-empty.tsx +29 -0
- package/src/components/table/table-footer.tsx +22 -0
- package/src/components/table/table-frame.tsx +47 -0
- package/src/components/table/table-head.tsx +99 -0
- package/src/components/table/table-header.tsx +24 -0
- package/src/components/table/table-row.tsx +145 -0
- package/src/components/table/table-scroll.tsx +129 -0
- package/src/components/table/table-section.tsx +26 -0
- package/src/components/table/table.context.tsx +126 -0
- package/src/components/table/table.tsx +174 -0
- package/src/components/table/table.types.ts +19 -0
- package/src/components/table/table.variants.test.ts +531 -0
- package/src/components/table/table.variants.ts +476 -0
- package/src/components/tag-input/AGENTS.md +131 -0
- package/src/components/tag-input/index.ts +39 -0
- package/src/components/tag-input/tag-input-chip.tsx +89 -0
- package/src/components/tag-input/tag-input-suffix.tsx +75 -0
- package/src/components/tag-input/tag-input.context.tsx +85 -0
- package/src/components/tag-input/tag-input.logic.test.ts +414 -0
- package/src/components/tag-input/tag-input.logic.ts +345 -0
- package/src/components/tag-input/tag-input.tsx +528 -0
- package/src/components/tag-input/tag-input.types.ts +47 -0
- package/src/components/tag-input/tag-input.variants.test.ts +233 -0
- package/src/components/tag-input/tag-input.variants.ts +136 -0
- package/src/components/text-animation/AGENTS.md +183 -0
- package/src/components/text-animation/index.ts +34 -0
- package/src/components/text-animation/text-animation-caret.tsx +67 -0
- package/src/components/text-animation/text-animation-clock.ts +75 -0
- package/src/components/text-animation/text-animation-counting.tsx +166 -0
- package/src/components/text-animation/text-animation-rolling.tsx +259 -0
- package/src/components/text-animation/text-animation-rotating.tsx +225 -0
- package/src/components/text-animation/text-animation-typing.tsx +309 -0
- package/src/components/text-animation/text-animation-unit.tsx +112 -0
- package/src/components/text-animation/text-animation.tsx +294 -0
- package/src/components/text-animation/text-animation.types.ts +19 -0
- package/src/components/text-animation/text-animation.variants.test.ts +532 -0
- package/src/components/text-animation/text-animation.variants.ts +577 -0
- package/src/components/textarea/AGENTS.md +7 -4
- package/src/components/textarea/textarea.tsx +21 -3
- package/src/components/textarea/textarea.variants.test.ts +35 -0
- package/src/components/textarea/textarea.variants.ts +25 -5
- package/src/components/theme-selector/AGENTS.md +107 -0
- package/src/components/theme-selector/index.ts +37 -0
- package/src/components/theme-selector/theme-selector-option.tsx +52 -0
- package/src/components/theme-selector/theme-selector.context.tsx +65 -0
- package/src/components/theme-selector/theme-selector.logic.test.ts +160 -0
- package/src/components/theme-selector/theme-selector.logic.ts +130 -0
- package/src/components/theme-selector/theme-selector.tsx +171 -0
- package/src/components/theme-selector/theme-selector.types.ts +8 -0
- package/src/components/theme-selector/theme-selector.variants.test.ts +86 -0
- package/src/components/theme-selector/theme-selector.variants.ts +85 -0
- package/src/components/theme-selector/use-theme-selection.ts +51 -0
- package/src/components/time-picker/AGENTS.md +153 -0
- package/src/components/time-picker/index.ts +78 -0
- package/src/components/time-picker/time-picker-clear.tsx +34 -0
- package/src/components/time-picker/time-picker-content.tsx +61 -0
- package/src/components/time-picker/time-picker-done.tsx +32 -0
- package/src/components/time-picker/time-picker-icon.tsx +29 -0
- package/src/components/time-picker/time-picker-trigger.tsx +65 -0
- package/src/components/time-picker/time-picker-value.tsx +33 -0
- package/src/components/time-picker/time-picker-wheel-column.tsx +247 -0
- package/src/components/time-picker/time-picker-wheel-slot.tsx +38 -0
- package/src/components/time-picker/time-picker-wheel.tsx +134 -0
- package/src/components/time-picker/time-picker.context.tsx +92 -0
- package/src/components/time-picker/time-picker.time.test.ts +337 -0
- package/src/components/time-picker/time-picker.time.ts +290 -0
- package/src/components/time-picker/time-picker.tsx +260 -0
- package/src/components/time-picker/time-picker.types.ts +82 -0
- package/src/components/time-picker/time-picker.variants.test.ts +324 -0
- package/src/components/time-picker/time-picker.variants.ts +320 -0
- package/src/components/timeline/AGENTS.md +150 -0
- package/src/components/timeline/index.ts +66 -0
- package/src/components/timeline/timeline-aside.tsx +34 -0
- package/src/components/timeline/timeline-content.tsx +24 -0
- package/src/components/timeline/timeline-date.tsx +20 -0
- package/src/components/timeline/timeline-description.tsx +20 -0
- package/src/components/timeline/timeline-header.tsx +17 -0
- package/src/components/timeline/timeline-indicator.tsx +65 -0
- package/src/components/timeline/timeline-item.tsx +174 -0
- package/src/components/timeline/timeline-list.tsx +155 -0
- package/src/components/timeline/timeline-masthead.tsx +39 -0
- package/src/components/timeline/timeline-meta.tsx +20 -0
- package/src/components/timeline/timeline-stat.tsx +34 -0
- package/src/components/timeline/timeline-stats.tsx +13 -0
- package/src/components/timeline/timeline-title.tsx +85 -0
- package/src/components/timeline/timeline-track.tsx +43 -0
- package/src/components/timeline/timeline-trailing.tsx +17 -0
- package/src/components/timeline/timeline.context.tsx +141 -0
- package/src/components/timeline/timeline.tsx +221 -0
- package/src/components/timeline/timeline.types.ts +39 -0
- package/src/components/timeline/timeline.variants.test.ts +392 -0
- package/src/components/timeline/timeline.variants.ts +473 -0
- package/src/components/timeline/use-timeline-reading-edge.ts +54 -0
- package/src/components/toast/AGENTS.md +6 -7
- package/src/components/tooltip/AGENTS.md +2 -4
- package/src/components/tour/AGENTS.md +128 -0
- package/src/components/tour/index.ts +54 -0
- package/src/components/tour/tour-card.tsx +155 -0
- package/src/components/tour/tour-mask.tsx +50 -0
- package/src/components/tour/tour-overlay.tsx +234 -0
- package/src/components/tour/tour-scrim.tsx +88 -0
- package/src/components/tour/tour-step.tsx +55 -0
- package/src/components/tour/tour.context.tsx +85 -0
- package/src/components/tour/tour.tsx +275 -0
- package/src/components/tour/tour.types.ts +34 -0
- package/src/components/tour/tour.variants.test.ts +479 -0
- package/src/components/tour/tour.variants.ts +439 -0
- package/src/components/tree/AGENTS.md +141 -0
- package/src/components/tree/index.ts +56 -0
- package/src/components/tree/tree-actions.tsx +18 -0
- package/src/components/tree/tree-group.tsx +61 -0
- package/src/components/tree/tree-icon.tsx +19 -0
- package/src/components/tree/tree-indicator.tsx +91 -0
- package/src/components/tree/tree-item.tsx +90 -0
- package/src/components/tree/tree-label.tsx +30 -0
- package/src/components/tree/tree-trigger.tsx +170 -0
- package/src/components/tree/tree.context.tsx +144 -0
- package/src/components/tree/tree.tsx +216 -0
- package/src/components/tree/tree.types.ts +10 -0
- package/src/components/tree/tree.variants.test.ts +373 -0
- package/src/components/tree/tree.variants.ts +317 -0
- package/src/expo/blur-layer.tsx +40 -0
- package/src/hooks/use-reduce-transparency.ts +34 -0
- package/src/hooks/use-scroll-source.tsx +4 -4
- package/src/lib/color.test.ts +35 -1
- package/src/lib/color.ts +40 -0
- package/src/styles/theme.css +16 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delacour/react-native-ui",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.20261020154302",
|
|
4
4
|
"description": "React Native UI components — Uniwind, Reanimated, Gesture Handler",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,9 +35,12 @@
|
|
|
35
35
|
"./styles/theme": "./src/styles/theme.css",
|
|
36
36
|
"./accordion": "./src/components/accordion/index.ts",
|
|
37
37
|
"./alert": "./src/components/alert/index.ts",
|
|
38
|
+
"./animated-badge": "./src/components/animated-badge/index.ts",
|
|
39
|
+
"./attachment": "./src/components/attachment/index.ts",
|
|
38
40
|
"./avatar": "./src/components/avatar/index.ts",
|
|
39
41
|
"./badge": "./src/components/badge/index.ts",
|
|
40
42
|
"./bottom-sheet": "./src/components/bottom-sheet/index.ts",
|
|
43
|
+
"./breadcrumb": "./src/components/breadcrumb/index.ts",
|
|
41
44
|
"./button": "./src/components/button/index.ts",
|
|
42
45
|
"./calendar": "./src/components/calendar/index.ts",
|
|
43
46
|
"./card": "./src/components/card/index.ts",
|
|
@@ -45,54 +48,106 @@
|
|
|
45
48
|
"./chart": "./src/components/chart/index.ts",
|
|
46
49
|
"./checkbox": "./src/components/checkbox/index.ts",
|
|
47
50
|
"./chip": "./src/components/chip/index.ts",
|
|
51
|
+
"./circular-text": "./src/components/circular-text/index.ts",
|
|
48
52
|
"./collapsible": "./src/components/collapsible/index.ts",
|
|
53
|
+
"./color-picker": "./src/components/color-picker/index.ts",
|
|
54
|
+
"./combobox": "./src/components/combobox/index.ts",
|
|
55
|
+
"./compare": "./src/components/compare/index.ts",
|
|
49
56
|
"./context-menu": "./src/components/context-menu/index.ts",
|
|
57
|
+
"./countdown": "./src/components/countdown/index.ts",
|
|
58
|
+
"./date-picker": "./src/components/date-picker/index.ts",
|
|
59
|
+
"./date-time-picker": "./src/components/date-time-picker/index.ts",
|
|
50
60
|
"./dialog": "./src/components/dialog/index.ts",
|
|
61
|
+
"./direction": "./src/components/direction/index.ts",
|
|
51
62
|
"./drawer": "./src/components/drawer/index.ts",
|
|
52
63
|
"./empty-state": "./src/components/empty-state/index.ts",
|
|
53
64
|
"./fab": "./src/components/fab/index.ts",
|
|
54
65
|
"./feedback": "./src/components/feedback/index.ts",
|
|
55
66
|
"./field": "./src/components/field/index.ts",
|
|
67
|
+
"./flip-card": "./src/components/flip-card/index.ts",
|
|
68
|
+
"./flow": "./src/components/flow/index.ts",
|
|
69
|
+
"./frame": "./src/components/frame/index.ts",
|
|
70
|
+
"./grid-item": "./src/components/grid-item/index.ts",
|
|
56
71
|
"./icon": "./src/components/icon/index.ts",
|
|
72
|
+
"./image-viewer": "./src/components/image-viewer/index.ts",
|
|
57
73
|
"./input": "./src/components/input/index.ts",
|
|
58
74
|
"./item": "./src/components/item/index.ts",
|
|
59
75
|
"./kpi": "./src/components/kpi/index.ts",
|
|
60
76
|
"./label": "./src/components/label/index.ts",
|
|
77
|
+
"./leaderboard": "./src/components/leaderboard/index.ts",
|
|
61
78
|
"./list-group": "./src/components/list-group/index.ts",
|
|
62
79
|
"./map": "./src/components/map/index.ts",
|
|
80
|
+
"./markdown-editor": "./src/components/markdown-editor/index.ts",
|
|
81
|
+
"./marker": "./src/components/marker/index.ts",
|
|
82
|
+
"./marquee": "./src/components/marquee/index.ts",
|
|
63
83
|
"./menu": "./src/components/menu/index.ts",
|
|
84
|
+
"./message": "./src/components/message/index.ts",
|
|
85
|
+
"./message-scroller": "./src/components/message-scroller/index.ts",
|
|
64
86
|
"./meter": "./src/components/meter/index.ts",
|
|
87
|
+
"./number-input": "./src/components/number-input/index.ts",
|
|
88
|
+
"./otp-input": "./src/components/otp-input/index.ts",
|
|
65
89
|
"./overlay": "./src/components/overlay/index.ts",
|
|
90
|
+
"./page-header": "./src/components/page-header/index.ts",
|
|
91
|
+
"./pagination": "./src/components/pagination/index.ts",
|
|
92
|
+
"./planner": "./src/components/planner/index.ts",
|
|
66
93
|
"./popover": "./src/components/popover/index.ts",
|
|
94
|
+
"./post": "./src/components/post/index.ts",
|
|
67
95
|
"./pressable": "./src/components/pressable/index.ts",
|
|
68
96
|
"./progress": "./src/components/progress/index.ts",
|
|
69
97
|
"./progress-button": "./src/components/progress-button/index.ts",
|
|
70
98
|
"./provider": "./src/components/provider/index.ts",
|
|
99
|
+
"./qr-code": "./src/components/qr-code/index.ts",
|
|
100
|
+
"./questionnaire": "./src/components/questionnaire/index.ts",
|
|
71
101
|
"./radio": "./src/components/radio/index.ts",
|
|
72
102
|
"./rating": "./src/components/rating/index.ts",
|
|
73
103
|
"./screen": "./src/components/screen/index.ts",
|
|
104
|
+
"./scroll-blur": "./src/components/scroll-blur/index.ts",
|
|
105
|
+
"./scroll-canvas": "./src/components/scroll-canvas/index.ts",
|
|
106
|
+
"./scroll-fade": "./src/components/scroll-fade/index.ts",
|
|
107
|
+
"./scroll-header": "./src/components/scroll-header/index.ts",
|
|
108
|
+
"./scroll-text": "./src/components/scroll-text/index.ts",
|
|
109
|
+
"./search-bar": "./src/components/search-bar/index.ts",
|
|
110
|
+
"./section-progress": "./src/components/section-progress/index.ts",
|
|
111
|
+
"./section-rail": "./src/components/section-rail/index.ts",
|
|
112
|
+
"./select": "./src/components/select/index.ts",
|
|
74
113
|
"./selection-mode": "./src/components/selection-mode/index.ts",
|
|
75
114
|
"./separator": "./src/components/separator/index.ts",
|
|
115
|
+
"./signature": "./src/components/signature/index.ts",
|
|
76
116
|
"./skeleton": "./src/components/skeleton/index.ts",
|
|
117
|
+
"./sketch": "./src/components/sketch/index.ts",
|
|
77
118
|
"./slide-button": "./src/components/slide-button/index.ts",
|
|
78
119
|
"./slider": "./src/components/slider/index.ts",
|
|
120
|
+
"./sortable": "./src/components/sortable/index.ts",
|
|
79
121
|
"./spinner": "./src/components/spinner/index.ts",
|
|
122
|
+
"./split-view": "./src/components/split-view/index.ts",
|
|
123
|
+
"./splitter": "./src/components/splitter/index.ts",
|
|
80
124
|
"./stack-card": "./src/components/stack-card/index.ts",
|
|
81
125
|
"./steps": "./src/components/steps/index.ts",
|
|
126
|
+
"./support": "./src/components/support/index.ts",
|
|
82
127
|
"./surface": "./src/components/surface/index.ts",
|
|
83
128
|
"./swipe": "./src/components/swipe/index.ts",
|
|
84
129
|
"./switch": "./src/components/switch/index.ts",
|
|
130
|
+
"./table": "./src/components/table/index.ts",
|
|
85
131
|
"./tabs": "./src/components/tabs/index.ts",
|
|
132
|
+
"./tag-input": "./src/components/tag-input/index.ts",
|
|
86
133
|
"./text": "./src/components/text/index.ts",
|
|
134
|
+
"./text-animation": "./src/components/text-animation/index.ts",
|
|
87
135
|
"./textarea": "./src/components/textarea/index.ts",
|
|
136
|
+
"./theme-selector": "./src/components/theme-selector/index.ts",
|
|
137
|
+
"./time-picker": "./src/components/time-picker/index.ts",
|
|
138
|
+
"./timeline": "./src/components/timeline/index.ts",
|
|
88
139
|
"./toast": "./src/components/toast/index.ts",
|
|
89
140
|
"./toggle-button": "./src/components/toggle-button/index.ts",
|
|
90
141
|
"./tooltip": "./src/components/tooltip/index.ts",
|
|
142
|
+
"./tour": "./src/components/tour/index.ts",
|
|
143
|
+
"./tree": "./src/components/tree/index.ts",
|
|
144
|
+
"./expo/blur-layer": "./src/expo/blur-layer.tsx",
|
|
91
145
|
"./expo/navigation-theme": "./src/expo/navigation-theme.tsx",
|
|
92
146
|
"./hooks/use-calm-motion": "./src/hooks/use-calm-motion.tsx",
|
|
93
147
|
"./hooks/use-controllable-state": "./src/hooks/use-controllable-state.ts",
|
|
94
148
|
"./hooks/use-keyboard-state-sync": "./src/hooks/use-keyboard-state-sync.tsx",
|
|
95
149
|
"./hooks/use-navigation-theme": "./src/hooks/use-navigation-theme.ts",
|
|
150
|
+
"./hooks/use-reduce-transparency": "./src/hooks/use-reduce-transparency.ts",
|
|
96
151
|
"./hooks/use-scroll-sections": "./src/hooks/use-scroll-sections.ts",
|
|
97
152
|
"./hooks/use-scroll-source": "./src/hooks/use-scroll-source.tsx",
|
|
98
153
|
"./hooks/use-theme-color": "./src/hooks/use-theme-color.ts",
|
|
@@ -123,11 +178,13 @@
|
|
|
123
178
|
"tailwind-variants": "^3.3.1"
|
|
124
179
|
},
|
|
125
180
|
"peerDependencies": {
|
|
181
|
+
"expo-blur": ">=15",
|
|
126
182
|
"@maplibre/maplibre-react-native": "^11.5.0",
|
|
127
183
|
"@central-icons-react-native/round-outlined-radius-1-stroke-1.5": "^1.1",
|
|
128
|
-
"@delacour/react-native-bottom-sheet": "0.2.0-alpha.
|
|
184
|
+
"@delacour/react-native-bottom-sheet": "0.2.0-alpha.20261020154302",
|
|
129
185
|
"@delacour/react-native-charts": ">=0.1.0",
|
|
130
186
|
"@legendapp/list": ">=3.3",
|
|
187
|
+
"@shopify/react-native-skia": ">=2",
|
|
131
188
|
"expo-linear-gradient": ">=15",
|
|
132
189
|
"expo-router": ">=57",
|
|
133
190
|
"react": ">=19",
|
|
@@ -145,6 +202,9 @@
|
|
|
145
202
|
"uniwind": "^1.11.0"
|
|
146
203
|
},
|
|
147
204
|
"peerDependenciesMeta": {
|
|
205
|
+
"expo-blur": {
|
|
206
|
+
"optional": true
|
|
207
|
+
},
|
|
148
208
|
"@maplibre/maplibre-react-native": {
|
|
149
209
|
"optional": true
|
|
150
210
|
},
|
|
@@ -157,6 +217,9 @@
|
|
|
157
217
|
"@legendapp/list": {
|
|
158
218
|
"optional": true
|
|
159
219
|
},
|
|
220
|
+
"@shopify/react-native-skia": {
|
|
221
|
+
"optional": true
|
|
222
|
+
},
|
|
160
223
|
"expo-router": {
|
|
161
224
|
"optional": true
|
|
162
225
|
},
|
|
@@ -168,6 +231,7 @@
|
|
|
168
231
|
}
|
|
169
232
|
},
|
|
170
233
|
"devDependencies": {
|
|
234
|
+
"expo-blur": "~58.0.5",
|
|
171
235
|
"@maplibre/maplibre-react-native": "^11.5.0",
|
|
172
236
|
"@delacour/biome-config": "workspace:*",
|
|
173
237
|
"@delacour/react-native-bottom-sheet": "workspace:*",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# AnimatedBadge
|
|
2
|
+
|
|
3
|
+
A status pill whose content moves when it changes: the old glyph and label roll
|
|
4
|
+
out, the new ones roll in, and the capsule springs to the new width. One paint,
|
|
5
|
+
one job, a small closed API.
|
|
6
|
+
|
|
7
|
+
`import { AnimatedBadge } from "@delacour/react-native-ui/animated-badge";`
|
|
8
|
+
|
|
9
|
+
## Files
|
|
10
|
+
|
|
11
|
+
| File | What it holds |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `index.ts` | → `@delacour/react-native-ui/animated-badge` (component, props, statuses, sizes, resolvers) |
|
|
14
|
+
| `animated-badge.tsx` | The root — builds the frame, owns the width spring and the layout transition |
|
|
15
|
+
| `animated-badge-content.tsx` | The moving glyph + label unit (internal leaf, `DelacourUI.AnimatedBadge.Content`) |
|
|
16
|
+
| `animated-badge-glyph.tsx` | Status → glyph map, the spinner for `loading`, the pulse (internal leaf, `…Glyph`) |
|
|
17
|
+
| `animated-badge-measure.tsx` | The invisible measurer that lays out the incoming content (internal leaf, `…Measure`) |
|
|
18
|
+
| `use-animated-badge-roll.ts` | The roll: holds the outgoing frame until it is off-screen, then lands the newest |
|
|
19
|
+
| `animated-badge.types.ts` | `AnimatedBadgeFrame`, shared by the root, the roll, the content and the measurer |
|
|
20
|
+
| `animated-badge.variants.ts` | Statuses, sizes, status → colour, constants, pure resolvers — no RN imports |
|
|
21
|
+
| `animated-badge.variants.test.ts` | Written first |
|
|
22
|
+
|
|
23
|
+
## Design
|
|
24
|
+
|
|
25
|
+
- **Not a `Badge`, and not a mode of one.** `Badge` is a static label with four
|
|
26
|
+
paints, six colours and composed content. This is one paint and one job — say a
|
|
27
|
+
status, and move when it changes. Folding a roll into `Badge` would put a
|
|
28
|
+
measurer and two springs under every tag in a list that never changes.
|
|
29
|
+
- **No compound parts.** The roll has to own the glyph and the label together as
|
|
30
|
+
one moving unit, so an `AnimatedBadge.Label` would only invite a child the roll
|
|
31
|
+
cannot see. A caller wanting composed content uses `Badge`.
|
|
32
|
+
- **No `onPress`.** A status pill reports; it has no action. The root is a plain
|
|
33
|
+
`Animated.View` with `accessibilityRole="text"`. A tappable status is a `Badge`
|
|
34
|
+
with `onPress`, which already brings `Pressable`, feedback and haptics.
|
|
35
|
+
- **One paint: `Badge`'s soft row, read rather than restated.**
|
|
36
|
+
`resolveAnimatedBadgeSlots` calls `badgeVariants({ variant: "soft", color, size })`
|
|
37
|
+
from `../badge/badge.variants` — a leaf, legal across folders (package rule 3);
|
|
38
|
+
never `../badge`. A test asserts the root, label and icon slots equal `Badge`'s
|
|
39
|
+
at every status and size, so the two sit level in a row. No ring: the soft
|
|
40
|
+
badge's reserved border stays transparent.
|
|
41
|
+
- **`status` maps to a `BadgeColor`, and `neutral` and `loading` share the
|
|
42
|
+
neutral fill.** `destructive`, never `danger`. Work in flight has no verdict
|
|
43
|
+
yet; the spinner already says it is moving. The glyph's colour is
|
|
44
|
+
`BADGE_FOREGROUND_TOKEN.soft[color]`, the token the label resolves to, pinned by
|
|
45
|
+
a test and checked against both themes.
|
|
46
|
+
- **Sizes are `sm` and `md` only.** A status pill sits in a list row, a header or
|
|
47
|
+
a sentence; `lg` is a banner's size, and that is `Alert`.
|
|
48
|
+
- **Glyphs match `Alert`'s** for the four statuses both have: `IconCircleInfo`,
|
|
49
|
+
`IconCircleCheck`, `IconExclamationTriangle` (warning) and
|
|
50
|
+
`IconExclamationCircle` (destructive) — triangle against circle, so the two
|
|
51
|
+
read apart without colour. `neutral` is a bare `IconCircle`. `loading` is a
|
|
52
|
+
`Spinner`, sized and coloured by the same `IconDefaultsProvider` as an icon.
|
|
53
|
+
- **A custom `icon` beats the status's glyph, `loading` included.** It is the
|
|
54
|
+
caller's explicit word. `showIcon={false}` draws nothing; the two are a
|
|
55
|
+
discriminated union so `icon` with `showIcon={false}` does not typecheck.
|
|
56
|
+
- **`icon` takes an `IconComponent`, not a node.** The badge renders it through
|
|
57
|
+
`<Icon>`, so its size and colour come from the badge — icons inherit, never
|
|
58
|
+
hand-sized.
|
|
59
|
+
- **The roll is one view, never two copies.** `useAnimatedBadgeRoll` holds the
|
|
60
|
+
frame on screen while the exit runs (`ROLL_OUT_MS`, toward `-ROLL_DISTANCE`,
|
|
61
|
+
fading out). The swap happens from the exit's completion callback via
|
|
62
|
+
`scheduleOnRN`, while the content is invisible; the enter springs in from
|
|
63
|
+
`+ROLL_DISTANCE` in a layout effect after that commit, so it never starts on the
|
|
64
|
+
outgoing word. Two overlapping copies double up mid-swap, which is the failure
|
|
65
|
+
this shape exists to prevent.
|
|
66
|
+
- **A change mid-roll retargets.** The exit continues from where it is, and
|
|
67
|
+
whichever frame is newest when it finishes lands — intermediates are skipped. A
|
|
68
|
+
change back to the frame still on screen returns it home instead of rolling.
|
|
69
|
+
The effect is keyed on the two keys, not on the frame object, so a parent
|
|
70
|
+
re-rendering mid-exit does not restart the exit's clock.
|
|
71
|
+
- **The capsule paints from the frame on screen**, not from the incoming props.
|
|
72
|
+
Its fill changes while the outgoing word is invisible, rather than under it, and
|
|
73
|
+
the outgoing word keeps its own colour on its way out.
|
|
74
|
+
- **The width spring measures the next content before it arrives.**
|
|
75
|
+
`AnimatedBadgeMeasure` is a copy of the capsule — the root's classes, the row,
|
|
76
|
+
the one-line label — on an absolutely positioned, transparent,
|
|
77
|
+
`pointerEvents="none"`, hidden-from-assistive-technology canvas. Its `onLayout`
|
|
78
|
+
drives the root's `width` with `withSpring`. The canvas is
|
|
79
|
+
`MEASURE_CANVAS_WIDTH` wide because Yoga caps an absolute child's available
|
|
80
|
+
width at its parent's: without it a narrow badge would wrap the next word and
|
|
81
|
+
report the wrapped width. The glyph is measured as a box of the icon step — a
|
|
82
|
+
spinner in the measurer would spin for nobody.
|
|
83
|
+
- **The first paint never jumps.** The root carries no width until the first
|
|
84
|
+
measure, and that first measure is set without a spring.
|
|
85
|
+
- **A text label is drawn on one line** (`numberOfLines={1}`) — the measurer lays
|
|
86
|
+
it out on one line too, so the measured width is the width drawn. A status is
|
|
87
|
+
a word or two; a sentence belongs in an `Alert`.
|
|
88
|
+
- **Padding, never a height** — `Badge`'s rule and reason: OS font scaling.
|
|
89
|
+
- **`animateLayout`** puts `LinearTransition.springify()` on the root, so the
|
|
90
|
+
badge springs to a new position when the layout around it moves. Inside
|
|
91
|
+
flowing text that would slide the badge across lines when the sentence
|
|
92
|
+
reflows, so `animateLayout={false}` turns it off.
|
|
93
|
+
- **Change detection is a string key.** `resolveAnimatedBadgeKey`:
|
|
94
|
+
`contentKey` wins (`status:contentKey`), then text children — a string, a
|
|
95
|
+
number, or an array of only those (`status:joined`) — then the status alone. A
|
|
96
|
+
non-text label therefore rolls only on a status change unless it is given a
|
|
97
|
+
`contentKey`. The same key across a re-render does nothing.
|
|
98
|
+
- **Reduce motion cuts over; calm motion stills only the pulse.**
|
|
99
|
+
`resolveAnimatedBadgeMotion` returns `{ roll, resize, layout, pulse }`. Under
|
|
100
|
+
`useReducedMotion()` the content swaps, the width is set, no layout transition
|
|
101
|
+
runs and nothing pulses. Under the app's `isMotionCalm` alone (E2E) the roll
|
|
102
|
+
and springs still run — they settle, which is all a test runner waits for —
|
|
103
|
+
and only the endless pulse holds still.
|
|
104
|
+
- **The pulse is on the glyph, not the capsule.** A swelling capsule pushes the
|
|
105
|
+
layout around it and reads as noise; a swelling glyph reads as breathing. It
|
|
106
|
+
defaults on for `loading`, and an explicit `pulse={false}` wins. Its repeat
|
|
107
|
+
sets `ReduceMotion.Never` and is gated one level up, exactly like
|
|
108
|
+
`useSkeletonClock` — under the default policy a `withRepeat(-1)` of a
|
|
109
|
+
zero-length timing spins forever.
|
|
110
|
+
- **Accessibility.** The root is `accessible`, `accessibilityRole="text"`,
|
|
111
|
+
labelled with the label text (a caller's `accessibilityLabel` wins) and
|
|
112
|
+
`accessibilityState.busy` while `loading`. The glyph is hidden — it duplicates
|
|
113
|
+
the word — and so is the measurer. With `announce` (default `true`) the root
|
|
114
|
+
is a polite live region on Android, and iOS calls
|
|
115
|
+
`AccessibilityInfo.announceForAccessibility` once the new content lands, never
|
|
116
|
+
on mount. Pass `announce={false}` in a list of fifty, where every row
|
|
117
|
+
announcing is noise.
|
|
118
|
+
|
|
119
|
+
## Where the spec and the icon set disagreed
|
|
120
|
+
|
|
121
|
+
- The usage examples name a sparkles glyph; Central has `IconSparkle`, singular.
|
|
122
|
+
The demos and docs use `IconSparkle`.
|
|
123
|
+
- The spec's file map has no measurer, roll hook or types file. Each exists
|
|
124
|
+
because the root, the content and the measurer all need the frame, and a part
|
|
125
|
+
must never import its own root (package rule 3).
|
|
126
|
+
- No demo carries `meta.capture` yet. A captured demo must have committed media
|
|
127
|
+
in `apps/web/src/previews/manifest.ts`, and that is written only by
|
|
128
|
+
`bun run previews` on a simulator, which this change did not run. The intended
|
|
129
|
+
set is `status-flow` (hero), `statuses`, `sizes`, `custom-icon` and
|
|
130
|
+
`inline-text`; `reduced-motion` stays uncaptured. Add `capture` to those five
|
|
131
|
+
in the same commit that photographs them, then add `<Preview>` heroes to the
|
|
132
|
+
docs page.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import Animated from "react-native-reanimated";
|
|
3
|
+
import { IconDefaultsProvider } from "../icon";
|
|
4
|
+
import { Text } from "../text";
|
|
5
|
+
import { TextClassProvider } from "../text/text.context";
|
|
6
|
+
import type { AnimatedBadgeAnimatedStyle, AnimatedBadgeFrame } from "./animated-badge.types";
|
|
7
|
+
import {
|
|
8
|
+
type AnimatedBadgeSize,
|
|
9
|
+
resolveAnimatedBadgeForeground,
|
|
10
|
+
resolveAnimatedBadgeSlots,
|
|
11
|
+
} from "./animated-badge.variants";
|
|
12
|
+
import { AnimatedBadgeGlyph } from "./animated-badge-glyph";
|
|
13
|
+
|
|
14
|
+
export type AnimatedBadgeContentProps = {
|
|
15
|
+
frame: AnimatedBadgeFrame;
|
|
16
|
+
size: AnimatedBadgeSize;
|
|
17
|
+
labelClassName: string | undefined;
|
|
18
|
+
/** The roll's offset and opacity, from `useAnimatedBadgeRoll`. */
|
|
19
|
+
rollStyle: AnimatedBadgeAnimatedStyle;
|
|
20
|
+
isPulsing: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The moving unit: glyph and label in one row, rolled as one view.
|
|
25
|
+
*
|
|
26
|
+
* Paints from the frame it is handed rather than from the root's props, so the
|
|
27
|
+
* outgoing word keeps its own colour until it has left. A text label is drawn
|
|
28
|
+
* on one line — the measurer lays the next one out on one line too, and the
|
|
29
|
+
* capsule springs to that width.
|
|
30
|
+
*/
|
|
31
|
+
export function AnimatedBadgeContent({
|
|
32
|
+
frame,
|
|
33
|
+
size,
|
|
34
|
+
labelClassName,
|
|
35
|
+
rollStyle,
|
|
36
|
+
isPulsing,
|
|
37
|
+
}: AnimatedBadgeContentProps): ReactElement {
|
|
38
|
+
const slots = resolveAnimatedBadgeSlots({ status: frame.status, size, labelClassName });
|
|
39
|
+
const iconDefaults = { className: slots.icon, color: resolveAnimatedBadgeForeground(frame.status) };
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<IconDefaultsProvider value={iconDefaults}>
|
|
43
|
+
<TextClassProvider value={slots.label}>
|
|
44
|
+
<Animated.View className={slots.content} style={rollStyle}>
|
|
45
|
+
<AnimatedBadgeGlyph icon={frame.icon} isPulsing={isPulsing} kind={frame.glyph} status={frame.status} />
|
|
46
|
+
{frame.text === undefined ? (
|
|
47
|
+
frame.label
|
|
48
|
+
) : (
|
|
49
|
+
<Text className={slots.label} numberOfLines={1}>
|
|
50
|
+
{frame.text}
|
|
51
|
+
</Text>
|
|
52
|
+
)}
|
|
53
|
+
</Animated.View>
|
|
54
|
+
</TextClassProvider>
|
|
55
|
+
</IconDefaultsProvider>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
AnimatedBadgeContent.displayName = "DelacourUI.AnimatedBadge.Content";
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type ReactElement, useEffect } from "react";
|
|
2
|
+
import Animated, {
|
|
3
|
+
cancelAnimation,
|
|
4
|
+
Easing,
|
|
5
|
+
ReduceMotion,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useSharedValue,
|
|
8
|
+
withRepeat,
|
|
9
|
+
withTiming,
|
|
10
|
+
} from "react-native-reanimated";
|
|
11
|
+
import {
|
|
12
|
+
IconCircle,
|
|
13
|
+
IconCircleCheck,
|
|
14
|
+
IconCircleInfo,
|
|
15
|
+
IconExclamationCircle,
|
|
16
|
+
IconExclamationTriangle,
|
|
17
|
+
} from "../../icons/central";
|
|
18
|
+
import { Icon, type IconComponent } from "../icon";
|
|
19
|
+
import { Spinner } from "../spinner";
|
|
20
|
+
import {
|
|
21
|
+
type AnimatedBadgeGlyphKind,
|
|
22
|
+
type AnimatedBadgeStatus,
|
|
23
|
+
PULSE_CYCLE_MS,
|
|
24
|
+
PULSE_MAX_SCALE,
|
|
25
|
+
PULSE_MIN_OPACITY,
|
|
26
|
+
} from "./animated-badge.variants";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The glyph each status draws when the caller names none.
|
|
30
|
+
*
|
|
31
|
+
* The four statuses `Alert` also has take `Alert`'s glyphs, so a warning reads
|
|
32
|
+
* the same in a badge as in a banner — and `warning` and `destructive` differ in
|
|
33
|
+
* shape as well as colour, a triangle against a circle, for anyone who cannot
|
|
34
|
+
* tell amber from red. `neutral` is a bare ring: a status with no verdict.
|
|
35
|
+
* `loading` is absent because it spins instead.
|
|
36
|
+
*
|
|
37
|
+
* Lives here rather than in `animated-badge.variants.ts` because the glyphs are
|
|
38
|
+
* React Native SVG components, and that file must stay importable from `bun test`.
|
|
39
|
+
*/
|
|
40
|
+
const STATUS_GLYPHS: Record<Exclude<AnimatedBadgeStatus, "loading">, IconComponent> = {
|
|
41
|
+
neutral: IconCircle,
|
|
42
|
+
info: IconCircleInfo,
|
|
43
|
+
success: IconCircleCheck,
|
|
44
|
+
warning: IconExclamationTriangle,
|
|
45
|
+
destructive: IconExclamationCircle,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The element for a resolved glyph kind. `loading` with no custom icon always
|
|
50
|
+
* spins, whichever kind it arrives with.
|
|
51
|
+
*/
|
|
52
|
+
function pickGlyph(
|
|
53
|
+
kind: "spinner" | "icon",
|
|
54
|
+
status: AnimatedBadgeStatus,
|
|
55
|
+
icon: IconComponent | undefined
|
|
56
|
+
): ReactElement {
|
|
57
|
+
if (kind === "icon" && icon) return <Icon icon={icon} />;
|
|
58
|
+
if (status === "loading") return <Spinner />;
|
|
59
|
+
return <Icon icon={icon ?? STATUS_GLYPHS[status]} />;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type AnimatedBadgeGlyphProps = {
|
|
63
|
+
kind: AnimatedBadgeGlyphKind;
|
|
64
|
+
status: AnimatedBadgeStatus;
|
|
65
|
+
icon: IconComponent | undefined;
|
|
66
|
+
/** Swell in a loop. Already resolved against calm and reduced motion. */
|
|
67
|
+
isPulsing: boolean;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The glyph leading the label: the caller's icon, the status's icon, or a
|
|
72
|
+
* spinner for `loading`. Size and colour come from the badge's
|
|
73
|
+
* `IconDefaultsProvider`, never from here.
|
|
74
|
+
*
|
|
75
|
+
* Hidden from assistive technology — it duplicates the word beside it, and the
|
|
76
|
+
* spinner would otherwise announce itself as a progress bar inside a label.
|
|
77
|
+
*
|
|
78
|
+
* The pulse is a 0 → 1 clock read through a cosine, the shape `Skeleton`'s pulse
|
|
79
|
+
* uses. Its timing sets `ReduceMotion.Never` because the gate is one level up,
|
|
80
|
+
* in `resolveAnimatedBadgeMotion`: under the default policy a `withRepeat(-1)`
|
|
81
|
+
* of a timing the OS has zeroed spins forever.
|
|
82
|
+
*/
|
|
83
|
+
export function AnimatedBadgeGlyph({ kind, status, icon, isPulsing }: AnimatedBadgeGlyphProps): ReactElement | null {
|
|
84
|
+
const clock = useSharedValue(0);
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!isPulsing) {
|
|
88
|
+
cancelAnimation(clock);
|
|
89
|
+
clock.value = 0;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
clock.value = 0;
|
|
94
|
+
clock.value = withRepeat(
|
|
95
|
+
withTiming(1, { duration: PULSE_CYCLE_MS, easing: Easing.linear, reduceMotion: ReduceMotion.Never }),
|
|
96
|
+
-1,
|
|
97
|
+
false
|
|
98
|
+
);
|
|
99
|
+
return () => cancelAnimation(clock);
|
|
100
|
+
}, [isPulsing, clock]);
|
|
101
|
+
|
|
102
|
+
const pulseStyle = useAnimatedStyle(() => {
|
|
103
|
+
const swell = (1 - Math.cos(clock.value * 2 * Math.PI)) / 2;
|
|
104
|
+
return {
|
|
105
|
+
opacity: 1 - (1 - PULSE_MIN_OPACITY) * swell,
|
|
106
|
+
transform: [{ scale: 1 + (PULSE_MAX_SCALE - 1) * swell }],
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (kind === "none") return null;
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<Animated.View accessibilityElementsHidden importantForAccessibility="no-hide-descendants" style={pulseStyle}>
|
|
114
|
+
{pickGlyph(kind, status, icon)}
|
|
115
|
+
</Animated.View>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
AnimatedBadgeGlyph.displayName = "DelacourUI.AnimatedBadge.Glyph";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { type LayoutChangeEvent, View } from "react-native";
|
|
3
|
+
import { Text } from "../text";
|
|
4
|
+
import { TextClassProvider } from "../text/text.context";
|
|
5
|
+
import type { AnimatedBadgeFrame } from "./animated-badge.types";
|
|
6
|
+
import { type AnimatedBadgeSize, MEASURE_CANVAS_WIDTH, resolveAnimatedBadgeSlots } from "./animated-badge.variants";
|
|
7
|
+
|
|
8
|
+
export type AnimatedBadgeMeasureProps = {
|
|
9
|
+
/** The incoming frame — the one the capsule is about to hold. */
|
|
10
|
+
frame: AnimatedBadgeFrame;
|
|
11
|
+
size: AnimatedBadgeSize;
|
|
12
|
+
className: string | undefined;
|
|
13
|
+
labelClassName: string | undefined;
|
|
14
|
+
/** Receives the capsule's width for {@link frame}, border and padding included. */
|
|
15
|
+
onMeasure: (width: number) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Lays out the incoming content, invisibly, so the capsule can spring to its
|
|
20
|
+
* width before it arrives.
|
|
21
|
+
*
|
|
22
|
+
* A copy of the capsule — the root's own classes, the same row, the same label
|
|
23
|
+
* on one line — on an absolutely positioned canvas wider than any label (see
|
|
24
|
+
* `MEASURE_CANVAS_WIDTH`). The glyph is a box of the icon step rather than the
|
|
25
|
+
* glyph itself: the footprint is all that is measured, and a spinner here would
|
|
26
|
+
* spin for nobody.
|
|
27
|
+
*
|
|
28
|
+
* Hidden from assistive technology, transparent and untouchable — it exists for
|
|
29
|
+
* its `onLayout` and nothing else.
|
|
30
|
+
*/
|
|
31
|
+
export function AnimatedBadgeMeasure({
|
|
32
|
+
frame,
|
|
33
|
+
size,
|
|
34
|
+
className,
|
|
35
|
+
labelClassName,
|
|
36
|
+
onMeasure,
|
|
37
|
+
}: AnimatedBadgeMeasureProps): ReactElement {
|
|
38
|
+
const slots = resolveAnimatedBadgeSlots({ status: frame.status, size, className, labelClassName });
|
|
39
|
+
|
|
40
|
+
const handleLayout = (event: LayoutChangeEvent): void => {
|
|
41
|
+
onMeasure(event.nativeEvent.layout.width);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View
|
|
46
|
+
accessibilityElementsHidden
|
|
47
|
+
className="absolute top-0 left-0 opacity-0"
|
|
48
|
+
importantForAccessibility="no-hide-descendants"
|
|
49
|
+
pointerEvents="none"
|
|
50
|
+
style={{ width: MEASURE_CANVAS_WIDTH }}
|
|
51
|
+
>
|
|
52
|
+
<TextClassProvider value={slots.label}>
|
|
53
|
+
<View className={slots.root} onLayout={handleLayout}>
|
|
54
|
+
<View className={slots.content}>
|
|
55
|
+
{frame.glyph === "none" ? null : <View className={slots.icon} />}
|
|
56
|
+
{frame.text === undefined ? (
|
|
57
|
+
frame.label
|
|
58
|
+
) : (
|
|
59
|
+
<Text className={slots.label} numberOfLines={1}>
|
|
60
|
+
{frame.text}
|
|
61
|
+
</Text>
|
|
62
|
+
)}
|
|
63
|
+
</View>
|
|
64
|
+
</View>
|
|
65
|
+
</TextClassProvider>
|
|
66
|
+
</View>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
AnimatedBadgeMeasure.displayName = "DelacourUI.AnimatedBadge.Measure";
|