@bitrise/bitkit-v2 0.3.475-beta.3014 → 0.3.476
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -6
- package/dist/atoms/DatePicker/DatePicker.js.map +1 -1
- package/dist/atoms/ImageCropper/ImageCropper.js.map +1 -1
- package/dist/components/BitkitActionMenu/BitkitActionMenu.js.map +1 -1
- package/dist/components/BitkitAvatar/BitkitAvatar.js.map +1 -1
- package/dist/components/BitkitButton/BitkitButton.js.map +1 -1
- package/dist/components/BitkitCalendar/BitkitCalendar.d.ts +0 -12
- package/dist/components/BitkitCalendar/BitkitCalendar.js +1 -7
- package/dist/components/BitkitCalendar/BitkitCalendar.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarContent.d.ts +1 -5
- package/dist/components/BitkitCalendar/components/CalendarContent.js +43 -60
- package/dist/components/BitkitCalendar/components/CalendarContent.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarMonth.d.ts +2 -4
- package/dist/components/BitkitCalendar/components/CalendarMonth.js +5 -15
- package/dist/components/BitkitCalendar/components/CalendarMonth.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarMonthSelect.d.ts +1 -2
- package/dist/components/BitkitCalendar/components/CalendarMonthSelect.js +2 -3
- package/dist/components/BitkitCalendar/components/CalendarMonthSelect.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarNextTrigger.d.ts +1 -3
- package/dist/components/BitkitCalendar/components/CalendarNextTrigger.js +3 -3
- package/dist/components/BitkitCalendar/components/CalendarNextTrigger.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.d.ts +1 -3
- package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.js +3 -3
- package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarSelect.d.ts +0 -1
- package/dist/components/BitkitCalendar/components/CalendarSelect.js +2 -4
- package/dist/components/BitkitCalendar/components/CalendarSelect.js.map +1 -1
- package/dist/components/BitkitCalendar/components/CalendarYearSelect.d.ts +1 -2
- package/dist/components/BitkitCalendar/components/CalendarYearSelect.js +2 -3
- package/dist/components/BitkitCalendar/components/CalendarYearSelect.js.map +1 -1
- package/dist/components/BitkitCollapsible/BitkitCollapsible.js.map +1 -1
- package/dist/components/BitkitColorButton/BitkitColorButton.js.map +1 -1
- package/dist/components/BitkitDatePicker/BitkitDatePicker.d.ts +0 -2
- package/dist/components/BitkitDatePicker/BitkitDatePicker.js +1 -2
- package/dist/components/BitkitDatePicker/BitkitDatePicker.js.map +1 -1
- package/dist/components/BitkitDialog/BitkitStepsDialog.js.map +1 -1
- package/dist/components/BitkitDialog/BitkitStepsDialogStep.js.map +1 -1
- package/dist/components/BitkitDialog/DialogBodyContext.js.map +1 -1
- package/dist/components/BitkitExpandableCard/BitkitExpandableCard.js.map +1 -1
- package/dist/components/BitkitFileInput/BitkitFileInput.js.map +1 -1
- package/dist/components/BitkitIconButton/BitkitIconButton.js.map +1 -1
- package/dist/components/BitkitLabeledData/BitkitLabeledData.js.map +1 -1
- package/dist/components/BitkitList/BitkitList.js.map +1 -1
- package/dist/components/BitkitMarkdown/BitkitMarkdown.js +1 -1
- package/dist/components/BitkitMarkdown/BitkitMarkdown.js.map +1 -1
- package/dist/components/BitkitMarkdownCard/BitkitMarkdownCard.js.map +1 -1
- package/dist/components/BitkitMultiselect/BitkitMultiselect.js.map +1 -1
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js +1 -1
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js.map +1 -1
- package/dist/components/BitkitOverflowContent/BitkitOverflowContent.js.map +1 -1
- package/dist/components/BitkitPageSidebar/BitkitPageSidebar.js.map +1 -1
- package/dist/components/BitkitPagination/BitkitPagination.js.map +1 -1
- package/dist/components/BitkitPaginationLoadMore/BitkitPaginationLoadMore.js.map +1 -1
- package/dist/components/BitkitPopover/BitkitPopover.js.map +1 -1
- package/dist/components/BitkitPromoBanner/BitkitPromoBanner.js.map +1 -1
- package/dist/components/BitkitSegmentedControl/BitkitSegmentedControl.js.map +1 -1
- package/dist/components/BitkitSelectMenu/BitkitSelectMenuAction.js.map +1 -1
- package/dist/components/BitkitSettingsCard/BitkitSettingsCard.js.map +1 -1
- package/dist/components/BitkitSplitButton/BitkitSplitButton.js.map +1 -1
- package/dist/components/BitkitStat/BitkitStat.js.map +1 -1
- package/dist/components/BitkitStepsCard/BitkitStepsCard.js.map +1 -1
- package/dist/components/BitkitTable/BitkitExpandableRow.js.map +1 -1
- package/dist/components/BitkitTable/BitkitRowActionsCell.js.map +1 -1
- package/dist/components/BitkitTable/BitkitSortableColumnHeader.js.map +1 -1
- package/dist/components/BitkitTabs/BitkitTabs.js.map +1 -1
- package/dist/components/BitkitToggletip/BitkitToggletip.js.map +1 -1
- package/dist/components/BitkitTour/BitkitTour.js.map +1 -1
- package/dist/components/BitkitTreeView/BitkitTreeView.js.map +1 -1
- package/dist/components/BitkitUISideNav/UISideNavLink.js.map +1 -1
- package/dist/components/common/NotificationContent.js.map +1 -1
- package/dist/components/index.d.ts +0 -6
- package/dist/icons/IconAbortCircle.js.map +1 -1
- package/dist/icons/IconAbortCircleFilled.js.map +1 -1
- package/dist/icons/IconAddons.js.map +1 -1
- package/dist/icons/IconAgent.js.map +1 -1
- package/dist/icons/IconAnchor.js.map +1 -1
- package/dist/icons/IconAndroid.js.map +1 -1
- package/dist/icons/IconApp.js.map +1 -1
- package/dist/icons/IconAppSettings.js.map +1 -1
- package/dist/icons/IconAppStore.js.map +1 -1
- package/dist/icons/IconAppStoreColor.js.map +1 -1
- package/dist/icons/IconApple.js.map +1 -1
- package/dist/icons/IconArchive.js.map +1 -1
- package/dist/icons/IconArchiveDelete.js.map +1 -1
- package/dist/icons/IconArchiveRestore.js.map +1 -1
- package/dist/icons/IconArrowBackAndDown.js.map +1 -1
- package/dist/icons/IconArrowBackAndUp.js.map +1 -1
- package/dist/icons/IconArrowDown.js.map +1 -1
- package/dist/icons/IconArrowForwardAndDown.js.map +1 -1
- package/dist/icons/IconArrowForwardAndUp.js.map +1 -1
- package/dist/icons/IconArrowLeft.js.map +1 -1
- package/dist/icons/IconArrowNortheast.js.map +1 -1
- package/dist/icons/IconArrowNorthwest.js.map +1 -1
- package/dist/icons/IconArrowRight.js.map +1 -1
- package/dist/icons/IconArrowUp.js.map +1 -1
- package/dist/icons/IconArrowsHorizontal.js.map +1 -1
- package/dist/icons/IconArrowsVertical.js.map +1 -1
- package/dist/icons/IconAutomation.js.map +1 -1
- package/dist/icons/IconAws.js.map +1 -1
- package/dist/icons/IconAwsColor.js.map +1 -1
- package/dist/icons/IconBadge3RdParty.js.map +1 -1
- package/dist/icons/IconBadgeBitrise.js.map +1 -1
- package/dist/icons/IconBadgeUpgrade.js.map +1 -1
- package/dist/icons/IconBadgeVersionOk.js.map +1 -1
- package/dist/icons/IconBazel.js.map +1 -1
- package/dist/icons/IconBell.js.map +1 -1
- package/dist/icons/IconBitbot.js.map +1 -1
- package/dist/icons/IconBitbotError.js.map +1 -1
- package/dist/icons/IconBitbucket.js.map +1 -1
- package/dist/icons/IconBitbucketColor.js.map +1 -1
- package/dist/icons/IconBitbucketNeutral.js.map +1 -1
- package/dist/icons/IconBitbucketWhite.js.map +1 -1
- package/dist/icons/IconBlockCircle.js.map +1 -1
- package/dist/icons/IconBook.js.map +1 -1
- package/dist/icons/IconBoxArrowDown.js.map +1 -1
- package/dist/icons/IconBoxDot.js.map +1 -1
- package/dist/icons/IconBoxLinesOverflow.js.map +1 -1
- package/dist/icons/IconBoxLinesWrap.js.map +1 -1
- package/dist/icons/IconBranch.js.map +1 -1
- package/dist/icons/IconBrowserstackColor.js.map +1 -1
- package/dist/icons/IconBug.js.map +1 -1
- package/dist/icons/IconBuild.js.map +1 -1
- package/dist/icons/IconBuildCache.js.map +1 -1
- package/dist/icons/IconBuildCacheFilled.js.map +1 -1
- package/dist/icons/IconBuildEnvSetup.js.map +1 -1
- package/dist/icons/IconBuildHub.js.map +1 -1
- package/dist/icons/IconBuildHubFilled.js.map +1 -1
- package/dist/icons/IconCalendar.js.map +1 -1
- package/dist/icons/IconChangePlan.js.map +1 -1
- package/dist/icons/IconChat.js.map +1 -1
- package/dist/icons/IconCheck.js.map +1 -1
- package/dist/icons/IconCheckCircle.js.map +1 -1
- package/dist/icons/IconCheckCircleFilled.js.map +1 -1
- package/dist/icons/IconChevronDown.js.map +1 -1
- package/dist/icons/IconChevronLeft.js.map +1 -1
- package/dist/icons/IconChevronRight.js.map +1 -1
- package/dist/icons/IconChevronUp.js.map +1 -1
- package/dist/icons/IconCi.js.map +1 -1
- package/dist/icons/IconCiFilled.js.map +1 -1
- package/dist/icons/IconCircle.js.map +1 -1
- package/dist/icons/IconCircleDashed.js.map +1 -1
- package/dist/icons/IconCircleHalfFilled.js.map +1 -1
- package/dist/icons/IconClaude.js.map +1 -1
- package/dist/icons/IconClaudeColor.js.map +1 -1
- package/dist/icons/IconClock.js.map +1 -1
- package/dist/icons/IconCode.js.map +1 -1
- package/dist/icons/IconCodePush.js.map +1 -1
- package/dist/icons/IconCodeSigning.js.map +1 -1
- package/dist/icons/IconCoffee.js.map +1 -1
- package/dist/icons/IconCommit.js.map +1 -1
- package/dist/icons/IconConfigure.js.map +1 -1
- package/dist/icons/IconConnectedAccounts.js.map +1 -1
- package/dist/icons/IconContainer.js.map +1 -1
- package/dist/icons/IconCopilot.js.map +1 -1
- package/dist/icons/IconCopy.js.map +1 -1
- package/dist/icons/IconCordova.js.map +1 -1
- package/dist/icons/IconCpu.js.map +1 -1
- package/dist/icons/IconCreditcard.js.map +1 -1
- package/dist/icons/IconCredits.js.map +1 -1
- package/dist/icons/IconCross.js.map +1 -1
- package/dist/icons/IconCrossCircle.js.map +1 -1
- package/dist/icons/IconCrossCircleFilled.js.map +1 -1
- package/dist/icons/IconCrown.js.map +1 -1
- package/dist/icons/IconCursor.js.map +1 -1
- package/dist/icons/IconCycle.js.map +1 -1
- package/dist/icons/IconDashboard.js.map +1 -1
- package/dist/icons/IconDashboardFilled.js.map +1 -1
- package/dist/icons/IconDeployment.js.map +1 -1
- package/dist/icons/IconDetails.js.map +1 -1
- package/dist/icons/IconDoc.js.map +1 -1
- package/dist/icons/IconDollar.js.map +1 -1
- package/dist/icons/IconDot.js.map +1 -1
- package/dist/icons/IconDotnet.js.map +1 -1
- package/dist/icons/IconDotnetColor.js.map +1 -1
- package/dist/icons/IconDotnetText.js.map +1 -1
- package/dist/icons/IconDotnetTextColor.js.map +1 -1
- package/dist/icons/IconDoubleCircle.js.map +1 -1
- package/dist/icons/IconDownload.js.map +1 -1
- package/dist/icons/IconDragHandle.js.map +1 -1
- package/dist/icons/IconEc2Ami.js.map +1 -1
- package/dist/icons/IconEnterprise.js.map +1 -1
- package/dist/icons/IconErrorCircle.js.map +1 -1
- package/dist/icons/IconErrorCircleFilled.js.map +1 -1
- package/dist/icons/IconExpand.js.map +1 -1
- package/dist/icons/IconExtraBuildCapacity.js.map +1 -1
- package/dist/icons/IconEye.js.map +1 -1
- package/dist/icons/IconEyeSlash.js.map +1 -1
- package/dist/icons/IconFastlane.js.map +1 -1
- package/dist/icons/IconFile.js.map +1 -1
- package/dist/icons/IconFileDoc.js.map +1 -1
- package/dist/icons/IconFilePdf.js.map +1 -1
- package/dist/icons/IconFilePlist.js.map +1 -1
- package/dist/icons/IconFileYml.js.map +1 -1
- package/dist/icons/IconFileZip.js.map +1 -1
- package/dist/icons/IconFilter.js.map +1 -1
- package/dist/icons/IconFlag.js.map +1 -1
- package/dist/icons/IconFlutter.js.map +1 -1
- package/dist/icons/IconFolder.js.map +1 -1
- package/dist/icons/IconFullscreen.js.map +1 -1
- package/dist/icons/IconFullscreenExit.js.map +1 -1
- package/dist/icons/IconGauge.js.map +1 -1
- package/dist/icons/IconGit.js.map +1 -1
- package/dist/icons/IconGithub.js.map +1 -1
- package/dist/icons/IconGitlab.js.map +1 -1
- package/dist/icons/IconGitlabColor.js.map +1 -1
- package/dist/icons/IconGitlabWhite.js.map +1 -1
- package/dist/icons/IconGlobe.js.map +1 -1
- package/dist/icons/IconGo.js.map +1 -1
- package/dist/icons/IconGoogleColor.js.map +1 -1
- package/dist/icons/IconGooglePlay.js.map +1 -1
- package/dist/icons/IconGooglePlayColor.js.map +1 -1
- package/dist/icons/IconGradle.js.map +1 -1
- package/dist/icons/IconGroup.js.map +1 -1
- package/dist/icons/IconHashtag.js.map +1 -1
- package/dist/icons/IconHeadset.js.map +1 -1
- package/dist/icons/IconHeart.js.map +1 -1
- package/dist/icons/IconHistory.js.map +1 -1
- package/dist/icons/IconHourglass.js.map +1 -1
- package/dist/icons/IconImage.js.map +1 -1
- package/dist/icons/IconInfoCircle.js.map +1 -1
- package/dist/icons/IconInfoCircleFilled.js.map +1 -1
- package/dist/icons/IconInsights.js.map +1 -1
- package/dist/icons/IconInsightsFilled.js.map +1 -1
- package/dist/icons/IconInstall.js.map +1 -1
- package/dist/icons/IconInteraction.js.map +1 -1
- package/dist/icons/IconInvoice.js.map +1 -1
- package/dist/icons/IconIonic.js.map +1 -1
- package/dist/icons/IconJapanese.js.map +1 -1
- package/dist/icons/IconJava.js.map +1 -1
- package/dist/icons/IconJavaColor.js.map +1 -1
- package/dist/icons/IconJavaDuke.js.map +1 -1
- package/dist/icons/IconJavaDukeColor.js.map +1 -1
- package/dist/icons/IconKey.js.map +1 -1
- package/dist/icons/IconKiroColor.js.map +1 -1
- package/dist/icons/IconKotlin.js.map +1 -1
- package/dist/icons/IconKotlinColor.js.map +1 -1
- package/dist/icons/IconKotlinWhite.js.map +1 -1
- package/dist/icons/IconLaptop.js.map +1 -1
- package/dist/icons/IconLaunchdarkly.js.map +1 -1
- package/dist/icons/IconLegacyApp.js.map +1 -1
- package/dist/icons/IconLightbulb.js.map +1 -1
- package/dist/icons/IconLink.js.map +1 -1
- package/dist/icons/IconLinux.js.map +1 -1
- package/dist/icons/IconLock.js.map +1 -1
- package/dist/icons/IconLockOpen.js.map +1 -1
- package/dist/icons/IconLogin.js.map +1 -1
- package/dist/icons/IconLogout.js.map +1 -1
- package/dist/icons/IconMacos.js.map +1 -1
- package/dist/icons/IconMagicWand.js.map +1 -1
- package/dist/icons/IconMagnifier.js.map +1 -1
- package/dist/icons/IconMail.js.map +1 -1
- package/dist/icons/IconMcp.js.map +1 -1
- package/dist/icons/IconMedal.js.map +1 -1
- package/dist/icons/IconMemory.js.map +1 -1
- package/dist/icons/IconMenuGrid.js.map +1 -1
- package/dist/icons/IconMenuHamburger.js.map +1 -1
- package/dist/icons/IconMessage.js.map +1 -1
- package/dist/icons/IconMessageAlert.js.map +1 -1
- package/dist/icons/IconMessageQuestion.js.map +1 -1
- package/dist/icons/IconMicrophone.js.map +1 -1
- package/dist/icons/IconMinus.js.map +1 -1
- package/dist/icons/IconMinusCircle.js.map +1 -1
- package/dist/icons/IconMinusCircleFilled.js.map +1 -1
- package/dist/icons/IconMobile.js.map +1 -1
- package/dist/icons/IconMobileLandscape.js.map +1 -1
- package/dist/icons/IconMonitorChart.js.map +1 -1
- package/dist/icons/IconMoreHorizontal.js.map +1 -1
- package/dist/icons/IconMoreVertical.js.map +1 -1
- package/dist/icons/IconNews.js.map +1 -1
- package/dist/icons/IconNextjs.js.map +1 -1
- package/dist/icons/IconNodejs.js.map +1 -1
- package/dist/icons/IconOpenInNew.js.map +1 -1
- package/dist/icons/IconOther.js.map +1 -1
- package/dist/icons/IconOutsideContributor.js.map +1 -1
- package/dist/icons/IconOverview.js.map +1 -1
- package/dist/icons/IconPause.js.map +1 -1
- package/dist/icons/IconPencil.js.map +1 -1
- package/dist/icons/IconPeople.js.map +1 -1
- package/dist/icons/IconPercent.js.map +1 -1
- package/dist/icons/IconPerson.js.map +1 -1
- package/dist/icons/IconPersonWithDesk.js.map +1 -1
- package/dist/icons/IconPin.js.map +1 -1
- package/dist/icons/IconPlay.js.map +1 -1
- package/dist/icons/IconPlus.js.map +1 -1
- package/dist/icons/IconPlusCircle.js.map +1 -1
- package/dist/icons/IconPlusCircleFilled.js.map +1 -1
- package/dist/icons/IconPower.js.map +1 -1
- package/dist/icons/IconProject.js.map +1 -1
- package/dist/icons/IconProjectSettings.js.map +1 -1
- package/dist/icons/IconPull.js.map +1 -1
- package/dist/icons/IconPush.js.map +1 -1
- package/dist/icons/IconPuzzle.js.map +1 -1
- package/dist/icons/IconPython.js.map +1 -1
- package/dist/icons/IconPythonColor.js.map +1 -1
- package/dist/icons/IconQuestionCircle.js.map +1 -1
- package/dist/icons/IconQuestionCircleFilled.js.map +1 -1
- package/dist/icons/IconReact.js.map +1 -1
- package/dist/icons/IconRefresh.js.map +1 -1
- package/dist/icons/IconRegex.js.map +1 -1
- package/dist/icons/IconRelease.js.map +1 -1
- package/dist/icons/IconReleaseFilled.js.map +1 -1
- package/dist/icons/IconRemoteAccess.js.map +1 -1
- package/dist/icons/IconReplace.js.map +1 -1
- package/dist/icons/IconResponsiveness.js.map +1 -1
- package/dist/icons/IconReviewerApproved.js.map +1 -1
- package/dist/icons/IconReviewerAssigned.js.map +1 -1
- package/dist/icons/IconReviewerRejected.js.map +1 -1
- package/dist/icons/IconRuby.js.map +1 -1
- package/dist/icons/IconRubyColor.js.map +1 -1
- package/dist/icons/IconSave.js.map +1 -1
- package/dist/icons/IconSecurityShield.js.map +1 -1
- package/dist/icons/IconSettings.js.map +1 -1
- package/dist/icons/IconSettingsFilled.js.map +1 -1
- package/dist/icons/IconShuffle.js.map +1 -1
- package/dist/icons/IconSiren.js.map +1 -1
- package/dist/icons/IconSkip.js.map +1 -1
- package/dist/icons/IconSkipCircle.js.map +1 -1
- package/dist/icons/IconSkipCircleFilled.js.map +1 -1
- package/dist/icons/IconSlack.js.map +1 -1
- package/dist/icons/IconSlackColor.js.map +1 -1
- package/dist/icons/IconSparkle.js.map +1 -1
- package/dist/icons/IconSparkleFilled.js.map +1 -1
- package/dist/icons/IconSpinnerOnDisabled.js.map +1 -1
- package/dist/icons/IconSpinnerPurple.js.map +1 -1
- package/dist/icons/IconSpinnerPurpleDouble.js.map +1 -1
- package/dist/icons/IconSpinnerWhite.js.map +1 -1
- package/dist/icons/IconStability.js.map +1 -1
- package/dist/icons/IconStack.js.map +1 -1
- package/dist/icons/IconStar.js.map +1 -1
- package/dist/icons/IconStep.js.map +1 -1
- package/dist/icons/IconStop.js.map +1 -1
- package/dist/icons/IconStopwatch.js.map +1 -1
- package/dist/icons/IconTabPlus.js.map +1 -1
- package/dist/icons/IconTag.js.map +1 -1
- package/dist/icons/IconTasks.js.map +1 -1
- package/dist/icons/IconTeams.js.map +1 -1
- package/dist/icons/IconTeamsColor.js.map +1 -1
- package/dist/icons/IconTemplateCode.js.map +1 -1
- package/dist/icons/IconTerminal.js.map +1 -1
- package/dist/icons/IconTerminalFilled.js.map +1 -1
- package/dist/icons/IconTestQuarantine.js.map +1 -1
- package/dist/icons/IconThemeDarkToggle.js.map +1 -1
- package/dist/icons/IconThumbDown.js.map +1 -1
- package/dist/icons/IconThumbUp.js.map +1 -1
- package/dist/icons/IconTools.js.map +1 -1
- package/dist/icons/IconTrash.js.map +1 -1
- package/dist/icons/IconTrigger.js.map +1 -1
- package/dist/icons/IconUbuntu.js.map +1 -1
- package/dist/icons/IconUbuntuColor.js.map +1 -1
- package/dist/icons/IconUnity3D.js.map +1 -1
- package/dist/icons/IconUnpin.js.map +1 -1
- package/dist/icons/IconUpload.js.map +1 -1
- package/dist/icons/IconValidateShield.js.map +1 -1
- package/dist/icons/IconVideo.js.map +1 -1
- package/dist/icons/IconVsCode.js.map +1 -1
- package/dist/icons/IconWarning.js.map +1 -1
- package/dist/icons/IconWarningYellow.js.map +1 -1
- package/dist/icons/IconWebUi.js.map +1 -1
- package/dist/icons/IconWebhooks.js.map +1 -1
- package/dist/icons/IconWindsurf.js.map +1 -1
- package/dist/icons/IconWorkflow.js.map +1 -1
- package/dist/icons/IconWorkflowFlow.js.map +1 -1
- package/dist/icons/IconXTwitter.js.map +1 -1
- package/dist/icons/IconXamarin.js.map +1 -1
- package/dist/icons/IconXcode.js.map +1 -1
- package/dist/main.js +7 -8
- package/dist/theme/recipes/Spinner.recipe.d.ts +4 -4
- package/dist/theme/recipes/Spinner.recipe.js +4 -4
- package/dist/theme/recipes/Spinner.recipe.js.map +1 -1
- package/dist/theme/recipes/index.d.ts +4 -4
- package/dist/theme/semantic-tokens/index.d.ts +5 -0
- package/dist/theme/semantic-tokens/semanticColors.d.ts +5 -0
- package/dist/theme/semantic-tokens/semanticColors.js +1 -0
- package/dist/theme/semantic-tokens/semanticColors.js.map +1 -1
- package/dist/theme/slot-recipes/Combobox.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/DatePicker.recipe.d.ts +0 -15
- package/dist/theme/slot-recipes/DatePicker.recipe.js +22 -72
- package/dist/theme/slot-recipes/DatePicker.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/DatePickerSelect.recipe.d.ts +0 -82
- package/dist/theme/slot-recipes/DatePickerSelect.recipe.js +10 -28
- package/dist/theme/slot-recipes/DatePickerSelect.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/Menu.recipe.js +1 -6
- package/dist/theme/slot-recipes/Menu.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/NoteCard.recipe.d.ts +1 -1
- package/dist/theme/slot-recipes/NoteCard.recipe.js +1 -1
- package/dist/theme/slot-recipes/NoteCard.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/PageFooter.recipe.d.ts +5 -3
- package/dist/theme/slot-recipes/PageFooter.recipe.js +5 -3
- package/dist/theme/slot-recipes/PageFooter.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/Tag.recipe.d.ts +1 -1
- package/dist/theme/slot-recipes/TextInput.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/index.d.ts +7 -159
- package/dist/theme/slot-recipes/index.js +0 -4
- package/dist/theme/slot-recipes/index.js.map +1 -1
- package/dist/theme/tokens/sizes.js.map +1 -1
- package/dist/theme/tokens/spacing.js.map +1 -1
- package/dist/utilities/BitkitPortalContext.js +2 -3
- package/dist/utilities/BitkitPortalContext.js.map +1 -1
- package/docs/v1-to-v2-migration-guide.md +1 -48
- package/package.json +10 -12
- package/dist/components/BitkitFilter/BitkitFilter.context.d.ts +0 -65
- package/dist/components/BitkitFilter/BitkitFilter.context.js +0 -82
- package/dist/components/BitkitFilter/BitkitFilter.context.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilter.d.ts +0 -55
- package/dist/components/BitkitFilter/BitkitFilter.js +0 -240
- package/dist/components/BitkitFilter/BitkitFilter.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilter.utils.d.ts +0 -18
- package/dist/components/BitkitFilter/BitkitFilter.utils.js +0 -42
- package/dist/components/BitkitFilter/BitkitFilter.utils.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilterAdd.d.ts +0 -18
- package/dist/components/BitkitFilter/BitkitFilterAdd.js +0 -188
- package/dist/components/BitkitFilter/BitkitFilterAdd.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilterDateRange.d.ts +0 -26
- package/dist/components/BitkitFilter/BitkitFilterDateRange.js +0 -118
- package/dist/components/BitkitFilter/BitkitFilterDateRange.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilterSearch.d.ts +0 -23
- package/dist/components/BitkitFilter/BitkitFilterSearch.js +0 -70
- package/dist/components/BitkitFilter/BitkitFilterSearch.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilterSelect.d.ts +0 -61
- package/dist/components/BitkitFilter/BitkitFilterSelect.js +0 -140
- package/dist/components/BitkitFilter/BitkitFilterSelect.js.map +0 -1
- package/dist/components/BitkitFilter/BitkitFilterSwitch.d.ts +0 -28
- package/dist/components/BitkitFilter/BitkitFilterSwitch.js +0 -87
- package/dist/components/BitkitFilter/BitkitFilterSwitch.js.map +0 -1
- package/dist/components/BitkitFilter/components/FilterChip.d.ts +0 -23
- package/dist/components/BitkitFilter/components/FilterChip.js +0 -64
- package/dist/components/BitkitFilter/components/FilterChip.js.map +0 -1
- package/dist/components/BitkitFilter/components/FilterField.d.ts +0 -15
- package/dist/components/BitkitFilter/components/FilterField.js +0 -58
- package/dist/components/BitkitFilter/components/FilterField.js.map +0 -1
- package/dist/components/BitkitFilter/components/FilterPanel.d.ts +0 -42
- package/dist/components/BitkitFilter/components/FilterPanel.js +0 -126
- package/dist/components/BitkitFilter/components/FilterPanel.js.map +0 -1
- package/dist/components/BitkitFilter/components/FilterSearchInput.d.ts +0 -15
- package/dist/components/BitkitFilter/components/FilterSearchInput.js +0 -41
- package/dist/components/BitkitFilter/components/FilterSearchInput.js.map +0 -1
- package/dist/components/BitkitFilter/components/FilterSelectForm.d.ts +0 -41
- package/dist/components/BitkitFilter/components/FilterSelectForm.js +0 -307
- package/dist/components/BitkitFilter/components/FilterSelectForm.js.map +0 -1
- package/dist/theme/slot-recipes/Filter.recipe.d.ts +0 -37
- package/dist/theme/slot-recipes/Filter.recipe.js +0 -636
- package/dist/theme/slot-recipes/Filter.recipe.js.map +0 -1
- package/dist/theme/slot-recipes/Listbox.recipe.d.ts +0 -22
- package/dist/theme/slot-recipes/Listbox.recipe.js +0 -92
- package/dist/theme/slot-recipes/Listbox.recipe.js.map +0 -1
|
@@ -3,14 +3,14 @@ import { useDatePickerContext } from "../../../atoms/DatePicker/DatePicker.js";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { IconButton } from "@chakra-ui/react";
|
|
5
5
|
//#region lib/components/BitkitCalendar/components/CalendarNextTrigger.tsx
|
|
6
|
-
var CalendarNextTrigger = (
|
|
6
|
+
var CalendarNextTrigger = () => {
|
|
7
7
|
const datePicker = useDatePickerContext();
|
|
8
8
|
return /* @__PURE__ */ jsx(IconButton, {
|
|
9
9
|
...datePicker.getNextTriggerProps(),
|
|
10
10
|
color: "button/secondary/text",
|
|
11
|
-
size:
|
|
11
|
+
size: "sm",
|
|
12
12
|
variant: "tertiary",
|
|
13
|
-
children: /* @__PURE__ */ jsx(IconChevronRight, { size:
|
|
13
|
+
children: /* @__PURE__ */ jsx(IconChevronRight, { size: "16" })
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarNextTrigger.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarNextTrigger.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { IconButton } from '@chakra-ui/react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { IconChevronRight } from '../../../main';\n\nconst CalendarNextTrigger = (
|
|
1
|
+
{"version":3,"file":"CalendarNextTrigger.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarNextTrigger.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { IconButton } from '@chakra-ui/react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { IconChevronRight } from '../../../main';\n\nconst CalendarNextTrigger = () => {\n const datePicker = useDatePickerContext();\n\n return (\n <IconButton {...datePicker.getNextTriggerProps()} color=\"button/secondary/text\" size=\"sm\" variant=\"tertiary\">\n <IconChevronRight size=\"16\" />\n </IconButton>\n );\n};\n\nexport default CalendarNextTrigger;\n"],"mappings":";;;;;AAMA,IAAM,4BAA4B;CAChC,MAAM,aAAa,qBAAqB;CAExC,OACE,oBAAC,YAAD;EAAY,GAAI,WAAW,oBAAoB;EAAG,OAAM;EAAwB,MAAK;EAAK,SAAQ;EAChG,UAAA,oBAAC,kBAAD,EAAkB,MAAK,KAAM,CAAA;CACnB,CAAA;AAEhB"}
|
|
@@ -3,14 +3,14 @@ import { useDatePickerContext } from "../../../atoms/DatePicker/DatePicker.js";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { IconButton } from "@chakra-ui/react";
|
|
5
5
|
//#region lib/components/BitkitCalendar/components/CalendarPrevTrigger.tsx
|
|
6
|
-
var CalendarPrevTrigger = (
|
|
6
|
+
var CalendarPrevTrigger = () => {
|
|
7
7
|
const datePicker = useDatePickerContext();
|
|
8
8
|
return /* @__PURE__ */ jsx(IconButton, {
|
|
9
9
|
...datePicker.getPrevTriggerProps(),
|
|
10
10
|
color: "button/secondary/text",
|
|
11
|
-
size:
|
|
11
|
+
size: "sm",
|
|
12
12
|
variant: "tertiary",
|
|
13
|
-
children: /* @__PURE__ */ jsx(IconChevronLeft, { size:
|
|
13
|
+
children: /* @__PURE__ */ jsx(IconChevronLeft, { size: "16" })
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarPrevTrigger.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarPrevTrigger.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { IconButton } from '@chakra-ui/react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { IconChevronLeft } from '../../../main';\n\nconst CalendarPrevTrigger = (
|
|
1
|
+
{"version":3,"file":"CalendarPrevTrigger.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarPrevTrigger.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { IconButton } from '@chakra-ui/react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { IconChevronLeft } from '../../../main';\n\nconst CalendarPrevTrigger = () => {\n const datePicker = useDatePickerContext();\n\n return (\n <IconButton {...datePicker.getPrevTriggerProps()} color=\"button/secondary/text\" size=\"sm\" variant=\"tertiary\">\n <IconChevronLeft size=\"16\" />\n </IconButton>\n );\n};\n\nexport default CalendarPrevTrigger;\n"],"mappings":";;;;;AAMA,IAAM,4BAA4B;CAChC,MAAM,aAAa,qBAAqB;CAExC,OACE,oBAAC,YAAD;EAAY,GAAI,WAAW,oBAAoB;EAAG,OAAM;EAAwB,MAAK;EAAK,SAAQ;EAChG,UAAA,oBAAC,iBAAD,EAAiB,MAAK,KAAM,CAAA;CAClB,CAAA;AAEhB"}
|
|
@@ -7,21 +7,19 @@ import { createListCollection } from "@chakra-ui/react/collection";
|
|
|
7
7
|
import { Select } from "@chakra-ui/react/select";
|
|
8
8
|
//#region lib/components/BitkitCalendar/components/CalendarSelect.tsx
|
|
9
9
|
var CalendarSelect = (props) => {
|
|
10
|
-
const { contentProps, controlProps, defaultValue,
|
|
10
|
+
const { contentProps, controlProps, defaultValue, items, onValueChange, value } = props;
|
|
11
11
|
const collection = createListCollection({
|
|
12
12
|
items,
|
|
13
13
|
groupBy: (item) => item.group || ""
|
|
14
14
|
});
|
|
15
|
-
const styles = useSlotRecipe({ key: "datePickerSelect" })(
|
|
15
|
+
const styles = useSlotRecipe({ key: "datePickerSelect" })();
|
|
16
16
|
return /* @__PURE__ */ jsxs(Select.Root, {
|
|
17
17
|
collection,
|
|
18
18
|
defaultValue,
|
|
19
|
-
minWidth: "0",
|
|
20
19
|
onValueChange,
|
|
21
20
|
size: "md",
|
|
22
21
|
value,
|
|
23
22
|
children: [/* @__PURE__ */ jsxs(Select.Control, {
|
|
24
|
-
maxWidth: "100%",
|
|
25
23
|
...controlProps,
|
|
26
24
|
children: [
|
|
27
25
|
/* @__PURE__ */ jsx(Select.HiddenSelect, {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarSelect.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarSelect.tsx"],"sourcesContent":["import { createListCollection } from '@chakra-ui/react/collection';\nimport { Portal } from '@chakra-ui/react/portal';\nimport {\n Select,\n type SelectContentProps,\n type SelectControlProps,\n type SelectRootProps,\n} from '@chakra-ui/react/select';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport AssetSelectChevron from '../../../utilities/AssetSelectChevron.tsx';\nimport BitkitSelectMenu from '../../BitkitSelectMenu/BitkitSelectMenu.tsx';\n\nexport interface BitkitSelectProps {\n controlProps?: SelectControlProps;\n contentProps?: SelectContentProps;\n defaultValue?: string[];\n
|
|
1
|
+
{"version":3,"file":"CalendarSelect.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarSelect.tsx"],"sourcesContent":["import { createListCollection } from '@chakra-ui/react/collection';\nimport { Portal } from '@chakra-ui/react/portal';\nimport {\n Select,\n type SelectContentProps,\n type SelectControlProps,\n type SelectRootProps,\n} from '@chakra-ui/react/select';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport AssetSelectChevron from '../../../utilities/AssetSelectChevron.tsx';\nimport BitkitSelectMenu from '../../BitkitSelectMenu/BitkitSelectMenu.tsx';\n\nexport interface BitkitSelectProps {\n controlProps?: SelectControlProps;\n contentProps?: SelectContentProps;\n defaultValue?: string[];\n items: Array<{ group?: string; value: string; label: string }>;\n onValueChange?: SelectRootProps['onValueChange'];\n value?: string[];\n}\n\nconst CalendarSelect = (props: BitkitSelectProps) => {\n const { contentProps, controlProps, defaultValue, items, onValueChange, value } = props;\n\n const collection = createListCollection({\n items,\n groupBy: (item) => item.group || '',\n });\n\n const recipe = useSlotRecipe({ key: 'datePickerSelect' });\n const styles = recipe();\n\n return (\n <Select.Root\n collection={collection}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n size=\"md\"\n value={value}\n >\n <Select.Control {...controlProps}>\n <Select.HiddenSelect />\n <Select.Trigger css={styles.trigger}>\n <Select.ValueText />\n </Select.Trigger>\n <Select.IndicatorGroup css={styles.indicatorGroup}>\n <Select.Indicator asChild css={styles.indicator}>\n <AssetSelectChevron width=\"20\" height=\"20\" />\n </Select.Indicator>\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <BitkitSelectMenu collection={collection} contentProps={contentProps} size=\"md\" />\n </Select.Positioner>\n </Portal>\n </Select.Root>\n );\n};\n\nCalendarSelect.displayName = 'CalendarSelect';\n\nexport default CalendarSelect;\n"],"mappings":";;;;;;;;AAsBA,IAAM,kBAAkB,UAA6B;CACnD,MAAM,EAAE,cAAc,cAAc,cAAc,OAAO,eAAe,UAAU;CAElF,MAAM,aAAa,qBAAqB;EACtC;EACA,UAAU,SAAS,KAAK,SAAS;CACnC,CAAC;CAGD,MAAM,SADS,cAAc,EAAE,KAAK,mBAAmB,CACxC,CAAA,CAAO;CAEtB,OACE,qBAAC,OAAO,MAAR;EACc;EACE;EACC;EACf,MAAK;EACE;EALT,UAAA,CAOE,qBAAC,OAAO,SAAR;GAAgB,GAAI;GAApB,UAAA;IACE,oBAAC,OAAO,cAAR,CAAsB,CAAA;IACtB,oBAAC,OAAO,SAAR;KAAgB,KAAK,OAAO;KAC1B,UAAA,oBAAC,OAAO,WAAR,CAAmB,CAAA;IACL,CAAA;IAChB,oBAAC,OAAO,gBAAR;KAAuB,KAAK,OAAO;KACjC,UAAA,oBAAC,OAAO,WAAR;MAAkB,SAAA;MAAQ,KAAK,OAAO;MACpC,UAAA,oBAAC,oBAAD;OAAoB,OAAM;OAAK,QAAO;MAAM,CAAA;KAC5B,CAAA;IACG,CAAA;GACT;EAChB,CAAA,GAAA,oBAAC,QAAD,EAAA,UACE,oBAAC,OAAO,YAAR,EAAA,UACE,oBAAC,kBAAD;GAA8B;GAA0B;GAAc,MAAK;EAAM,CAAA,EAChE,CAAA,EACb,CAAA,CACG;;AAEjB;AAEA,eAAe,cAAc"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CalendarDate } from '@internationalized/date';
|
|
2
2
|
type CalendarYearSelectProps = {
|
|
3
|
-
device?: 'desktop' | 'mobile';
|
|
4
3
|
min?: CalendarDate;
|
|
5
4
|
max?: CalendarDate;
|
|
6
5
|
monthOffset: number;
|
|
@@ -9,5 +8,5 @@ type CalendarYearSelectProps = {
|
|
|
9
8
|
to: number;
|
|
10
9
|
};
|
|
11
10
|
};
|
|
12
|
-
declare const CalendarYearSelect: ({
|
|
11
|
+
declare const CalendarYearSelect: ({ monthOffset, max, min, yearsRange }: CalendarYearSelectProps) => import('react').JSX.Element;
|
|
13
12
|
export default CalendarYearSelect;
|
|
@@ -4,7 +4,7 @@ import CalendarSelect from "./CalendarSelect.js";
|
|
|
4
4
|
import { useMemo } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region lib/components/BitkitCalendar/components/CalendarYearSelect.tsx
|
|
7
|
-
var CalendarYearSelect = ({
|
|
7
|
+
var CalendarYearSelect = ({ monthOffset, max, min, yearsRange }) => {
|
|
8
8
|
const datePicker = useDatePickerContext();
|
|
9
9
|
const firstDayOfMonth = datePicker.getOffset({ months: monthOffset }).visibleRange.start;
|
|
10
10
|
const handleYearChange = (details) => {
|
|
@@ -44,8 +44,7 @@ var CalendarYearSelect = ({ device, monthOffset, max, min, yearsRange }) => {
|
|
|
44
44
|
maxHeight: rem(312),
|
|
45
45
|
width: rem(108)
|
|
46
46
|
},
|
|
47
|
-
controlProps: { width: rem(
|
|
48
|
-
device,
|
|
47
|
+
controlProps: { width: rem(77) },
|
|
49
48
|
defaultValue: [(/* @__PURE__ */ new Date()).getFullYear().toString()],
|
|
50
49
|
items: years,
|
|
51
50
|
onValueChange: handleYearChange,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarYearSelect.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarYearSelect.tsx"],"sourcesContent":["import { type CalendarDate } from '@internationalized/date';\nimport { useMemo } from 'react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { rem } from '../../../theme/themeUtils';\nimport CalendarSelect from './CalendarSelect';\n\ntype CalendarYearSelectProps = {\n
|
|
1
|
+
{"version":3,"file":"CalendarYearSelect.js","names":[],"sources":["../../../../lib/components/BitkitCalendar/components/CalendarYearSelect.tsx"],"sourcesContent":["import { type CalendarDate } from '@internationalized/date';\nimport { useMemo } from 'react';\n\nimport { useDatePickerContext } from '../../../atoms/DatePicker/DatePicker';\nimport { rem } from '../../../theme/themeUtils';\nimport CalendarSelect from './CalendarSelect';\n\ntype CalendarYearSelectProps = {\n min?: CalendarDate;\n max?: CalendarDate;\n monthOffset: number;\n yearsRange?: {\n from: number;\n to: number;\n };\n};\n\nconst CalendarYearSelect = ({ monthOffset, max, min, yearsRange }: CalendarYearSelectProps) => {\n const datePicker = useDatePickerContext();\n\n const firstDayOfMonth = datePicker.getOffset({ months: monthOffset }).visibleRange.start;\n\n const handleYearChange = (details: { value: string[] }) => {\n const selectedYear = parseInt(details.value[0], 10);\n\n datePicker.focusYear(selectedYear);\n };\n\n // eslint-disable-next-line react-hooks/preserve-manual-memoization\n const years = useMemo(() => {\n const currentYear = new Date().getFullYear();\n\n let yearOptions = [];\n\n if (yearsRange?.from) {\n for (let year = yearsRange.from; year <= yearsRange.to; year++) {\n yearOptions.push({\n label: year.toString(),\n value: year.toString(),\n });\n }\n } else {\n yearOptions = [currentYear - 1, currentYear, currentYear + 1].map((year) => ({\n label: year.toString(),\n value: year.toString(),\n }));\n }\n\n if (min || max) {\n return yearOptions.filter((year) => {\n const yearNumber = parseInt(year.value, 10);\n\n const isBeforeMin = min && yearNumber < min.year;\n const isAfterMax = max && yearNumber > max.year;\n\n return !isBeforeMin && !isAfterMax;\n });\n }\n\n return yearOptions;\n }, [yearsRange?.from, yearsRange?.to, min, max]);\n\n return (\n <CalendarSelect\n contentProps={{\n maxHeight: rem(312),\n width: rem(108),\n }}\n controlProps={{\n width: rem(77),\n }}\n defaultValue={[new Date().getFullYear().toString()]}\n items={years}\n onValueChange={handleYearChange}\n value={[firstDayOfMonth.year.toString()]}\n />\n );\n};\n\nexport default CalendarYearSelect;\n"],"mappings":";;;;;;AAiBA,IAAM,sBAAsB,EAAE,aAAa,KAAK,KAAK,iBAA0C;CAC7F,MAAM,aAAa,qBAAqB;CAExC,MAAM,kBAAkB,WAAW,UAAU,EAAE,QAAQ,YAAY,CAAC,CAAC,CAAC,aAAa;CAEnF,MAAM,oBAAoB,YAAiC;EACzD,MAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,EAAE;EAElD,WAAW,UAAU,YAAY;CACnC;CAGA,MAAM,QAAQ,cAAc;EAC1B,MAAM,+BAAc,IAAI,KAAK,EAAA,CAAE,YAAY;EAE3C,IAAI,cAAc,CAAC;EAEnB,IAAI,YAAY,MACd,KAAK,IAAI,OAAO,WAAW,MAAM,QAAQ,WAAW,IAAI,QACtD,YAAY,KAAK;GACf,OAAO,KAAK,SAAS;GACrB,OAAO,KAAK,SAAS;EACvB,CAAC;OAGH,cAAc;GAAC,cAAc;GAAG;GAAa,cAAc;EAAC,CAAC,CAAC,KAAK,UAAU;GAC3E,OAAO,KAAK,SAAS;GACrB,OAAO,KAAK,SAAS;EACvB,EAAE;EAGJ,IAAI,OAAO,KACT,OAAO,YAAY,QAAQ,SAAS;GAClC,MAAM,aAAa,SAAS,KAAK,OAAO,EAAE;GAE1C,MAAM,cAAc,OAAO,aAAa,IAAI;GAC5C,MAAM,aAAa,OAAO,aAAa,IAAI;GAE3C,OAAO,CAAC,eAAe,CAAC;EAC1B,CAAC;EAGH,OAAO;CACT,GAAG;EAAC,YAAY;EAAM,YAAY;EAAI;EAAK;CAAG,CAAC;CAE/C,OACE,oBAAC,gBAAD;EACE,cAAc;GACZ,WAAW,IAAI,GAAG;GAClB,OAAO,IAAI,GAAG;EAChB;EACA,cAAc,EACZ,OAAO,IAAI,EAAE,EACf;EACA,cAAc,kBAAC,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,SAAS,CAAC;EAClD,OAAO;EACP,eAAe;EACf,OAAO,CAAC,gBAAgB,KAAK,SAAS,CAAC;CACxC,CAAA;AAEL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitCollapsible.js","names":[],"sources":["../../../lib/components/BitkitCollapsible/BitkitCollapsible.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Collapsible, type CollapsibleRootProps } from '@chakra-ui/react/collapsible';\nimport { useSafeLayoutEffect } from '@chakra-ui/react/hooks';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useRef, useState } from 'react';\n\n// TODO: Investigate using AssetSelectChevron instead of IconChevronDown/IconChevronUp\nimport { IconChevronDown, IconChevronUp } from '../../icons';\nimport BitkitLabel, { type BitkitLabelProps } from '../BitkitLabel/BitkitLabel';\n\ntype UncontrolledProps = {\n defaultOpen?: boolean;\n open?: never;\n onOpenChange?: never;\n};\n\ntype ControlledProps = {\n defaultOpen?: never;\n onOpenChange: (open: boolean) => void;\n open: boolean;\n};\n\nexport type BitkitCollapsibleProps = Omit<\n CollapsibleRootProps,\n 'collapsedHeight' | 'defaultOpen' | 'onOpenChange' | 'open'\n> & {\n children: ReactNode;\n closedLabel?: string;\n collapsedHeight?: string;\n label?: string;\n labelProps?: Omit<BitkitLabelProps, 'children'>;\n openLabel?: string;\n} & (UncontrolledProps | ControlledProps);\n\n// contentRef sits on an unclamped wrapper *inside* Collapsible.Content, not on Content itself: when\n// closed, Content's own box is pinned to collapsedHeight (max-height + overflow), so a ResizeObserver\n// on Content can't see content that grows without changing Content's own (clamped) box - e.g. an image\n// or async child rendering more after mount. scrollHeight still reports the wrapper's true height\n// either way, clamped or not, so the read doesn't change - only where we watch for changes does.\n// isOverflowing and collapsedHeight are the effect's only dependencies. isOverflowing: BitkitCollapsible\n// renders a different tree depending on it (see below), moving contentRef to a different DOM node each\n// time it flips, so the effect must re-attach then. children is deliberately not a dependency: the\n// wrapper being unclamped means the observer already sees every content-driven size change on its own.\nconst useIsContentOverflowing = (collapsedHeight: string) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const [isOverflowing, setIsOverflowing] = useState(true);\n\n useSafeLayoutEffect(() => {\n const contentEl = contentRef.current;\n const measureScope = contentEl?.parentElement;\n if (!contentEl || !measureScope) {\n return undefined;\n }\n\n // Appended as a sibling of contentEl (not document.body) so it inherits the same font-size and\n // CSS custom properties contentEl actually sees, resolving em/var(...) heights correctly - not\n // just px/rem, which don't depend on where in the tree they're resolved.\n const probe = document.createElement('div');\n probe.style.cssText = `position: absolute; visibility: hidden; pointer-events: none; height: ${collapsedHeight};`;\n measureScope.appendChild(probe);\n const collapsedHeightPx = probe.getBoundingClientRect().height;\n measureScope.removeChild(probe);\n\n const checkOverflow = () => setIsOverflowing(contentEl.scrollHeight > collapsedHeightPx);\n checkOverflow();\n\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const resizeObserver = new ResizeObserver(checkOverflow);\n resizeObserver.observe(contentEl);\n return () => resizeObserver.disconnect();\n }, [collapsedHeight, isOverflowing]);\n\n return { contentRef, isOverflowing };\n};\n\nconst BitkitCollapsible = forwardRef<HTMLDivElement, BitkitCollapsibleProps>((props, ref) => {\n const {\n children,\n closedLabel = 'Show less',\n collapsedHeight = '48px',\n collapsedWidth,\n css,\n defaultOpen,\n disabled,\n hideMode,\n ids,\n label,\n labelProps,\n lazyMount,\n onExitComplete,\n onOpenChange,\n open,\n openLabel = 'Show more',\n unmountOnExit,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'collapsible' });\n const styles = recipe();\n\n const { contentRef, isOverflowing } = useIsContentOverflowing(collapsedHeight);\n\n const handleOpenChange = onOpenChange ? (details: { open: boolean }) => onOpenChange(details.open) : undefined;\n\n // zag's closed-state styling (min/max-height clamp, the fade-out pseudo-element) is driven purely by\n // Collapsible.Root defaulting to \"closed\" - it doesn't know or care whether collapsedHeight would\n // ever actually clip anything. Passing collapsedHeight and hiding only the trigger still leaves\n // content that fits pinned to that height and faded, so when it doesn't overflow we skip\n // Collapsible.Root/Content entirely and render plain markup instead of fighting the closed-state\n // styling with overrides. Only styles.root applies here - it carries the inherited color/textStyle,\n // which is all a non-collapsing block needs; styles.content's overflow/position/fade rules are\n // collapse-only and would clip content (a focus ring, an absolutely-positioned child) that isn't\n // meant to be clipped. contentRef sits directly under styles.root rather than under a styles.content\n // box, so measureScope (its parent) is styles.root in this branch and styles.content in the\n // overflowing one below - both carry the same inherited font-size, since textStyle now lives on\n // root and cascades down, so collapsedHeight's em/var(...) units resolve the same way in either\n // branch. disabled/ids/collapsedWidth/onExitComplete/lazyMount/unmountOnExit/hideMode\n // are zag/Ark machine props with no meaning on plain markup, so they're destructured out above and\n // only forwarded to Collapsible.Root below - otherwise they'd reach the DOM as unknown attributes.\n //\n // isOverflowing starts true, so every mount (even of content that turns out to fit) renders through\n // this Collapsible.Root tree first and flips to the plain tree below once measured - a real\n // remount of children, since the two trees don't share a component type at that position. Same\n // going the other way on a runtime resize. Accepted tradeoff: measuring requires a real layout\n // pass, and we don't have the content's size before that first render.\n if (!isOverflowing) {\n return (\n <Box ref={ref} css={[styles.root, css]} {...rest}>\n {label && <BitkitLabel {...labelProps}>{label}</BitkitLabel>}\n <Box ref={contentRef}>{children}</Box>\n </Box>\n );\n }\n\n return (\n <Collapsible.Root\n ref={ref}\n collapsedHeight={collapsedHeight}\n collapsedWidth={collapsedWidth}\n css={[styles.root, css]}\n defaultOpen={defaultOpen}\n disabled={disabled}\n hideMode={hideMode}\n ids={ids}\n lazyMount={lazyMount}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n unmountOnExit={unmountOnExit}\n {...rest}\n >\n {label && <BitkitLabel {...labelProps}>{label}</BitkitLabel>}\n <Collapsible.Content css={styles.content}>\n <Box ref={contentRef}>{children}</Box>\n </Collapsible.Content>\n <Collapsible.Trigger css={styles.trigger}>\n <Collapsible.Context>\n {(api) => (\n <>\n {api.open ? closedLabel : openLabel}\n {api.open ? <IconChevronUp size=\"16\" /> : <IconChevronDown size=\"16\" />}\n </>\n )}\n </Collapsible.Context>\n </Collapsible.Trigger>\n </Collapsible.Root>\n );\n});\n\nBitkitCollapsible.displayName = 'BitkitCollapsible';\n\nexport default BitkitCollapsible;\n"],"mappings":";;;;;;;;;;AA2CA,IAAM,2BAA2B,oBAA4B;CAC3D,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,CAAC,eAAe,oBAAoB,SAAS,IAAI;CAEvD,0BAA0B;EACxB,MAAM,YAAY,WAAW;EAC7B,MAAM,eAAe,WAAW;EAChC,IAAI,CAAC,aAAa,CAAC,cACjB;EAMF,MAAM,QAAQ,SAAS,cAAc,KAAK;EAC1C,MAAM,MAAM,UAAU,yEAAyE,gBAAgB;EAC/G,aAAa,YAAY,KAAK;EAC9B,MAAM,oBAAoB,MAAM,sBAAsB,CAAC,CAAC;EACxD,aAAa,YAAY,KAAK;EAE9B,MAAM,sBAAsB,iBAAiB,UAAU,eAAe,iBAAiB;EACvF,cAAc;EAEd,IAAI,OAAO,mBAAmB,aAC5B;EAGF,MAAM,iBAAiB,IAAI,eAAe,aAAa;EACvD,eAAe,QAAQ,SAAS;EAChC,aAAa,eAAe,WAAW;CACzC,GAAG,CAAC,iBAAiB,aAAa,CAAC;CAEnC,OAAO;EAAE;EAAY;CAAc;AACrC;AAEA,IAAM,oBAAoB,YAAoD,OAAO,QAAQ;CAC3F,MAAM,EACJ,UACA,cAAc,aACd,kBAAkB,QAClB,gBACA,KACA,aACA,UACA,UACA,KACA,OACA,YACA,WACA,gBACA,cACA,MACA,YAAY,aACZ,eACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,cAAc,CACnC,CAAA,CAAO;CAEtB,MAAM,EAAE,YAAY,kBAAkB,wBAAwB,eAAe;CAE7E,MAAM,mBAAmB,gBAAgB,YAA+B,aAAa,QAAQ,IAAI,IAAI,KAAA;CAuBrG,IAAI,CAAC,eACH,OACE,qBAAC,KAAD;EAAU;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,GAAI;EAA5C,UAAA,CACG,SAAS,oBAAC,aAAD;GAAa,GAAI;GAAa,UAAA;EAAmB,CAAA,GAC3D,oBAAC,KAAD;GAAK,KAAK;GAAa;EAAc,CAAA,CAClC;;CAIT,OACE,qBAAC,YAAY,MAAb;EACO;EACY;EACD;EAChB,KAAK,CAAC,OAAO,MAAM,GAAG;EACT;EACH;EACA;EACL;EACM;EACK;EAChB,cAAc;EACR;EACS;EACf,GAAI;EAdN,UAAA;GAgBG,SAAS,oBAAC,aAAD;IAAa,GAAI;IAAa,UAAA;GAAmB,CAAA;GAC3D,oBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAC/B,UAAA,oBAAC,KAAD;KAAK,KAAK;KAAa;IAAc,CAAA;GAClB,CAAA;GACrB,oBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAC/B,UAAA,oBAAC,YAAY,SAAb,EAAA,WACI,QACA,
|
|
1
|
+
{"version":3,"file":"BitkitCollapsible.js","names":["_Fragment"],"sources":["../../../lib/components/BitkitCollapsible/BitkitCollapsible.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Collapsible, type CollapsibleRootProps } from '@chakra-ui/react/collapsible';\nimport { useSafeLayoutEffect } from '@chakra-ui/react/hooks';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useRef, useState } from 'react';\n\n// TODO: Investigate using AssetSelectChevron instead of IconChevronDown/IconChevronUp\nimport { IconChevronDown, IconChevronUp } from '../../icons';\nimport BitkitLabel, { type BitkitLabelProps } from '../BitkitLabel/BitkitLabel';\n\ntype UncontrolledProps = {\n defaultOpen?: boolean;\n open?: never;\n onOpenChange?: never;\n};\n\ntype ControlledProps = {\n defaultOpen?: never;\n onOpenChange: (open: boolean) => void;\n open: boolean;\n};\n\nexport type BitkitCollapsibleProps = Omit<\n CollapsibleRootProps,\n 'collapsedHeight' | 'defaultOpen' | 'onOpenChange' | 'open'\n> & {\n children: ReactNode;\n closedLabel?: string;\n collapsedHeight?: string;\n label?: string;\n labelProps?: Omit<BitkitLabelProps, 'children'>;\n openLabel?: string;\n} & (UncontrolledProps | ControlledProps);\n\n// contentRef sits on an unclamped wrapper *inside* Collapsible.Content, not on Content itself: when\n// closed, Content's own box is pinned to collapsedHeight (max-height + overflow), so a ResizeObserver\n// on Content can't see content that grows without changing Content's own (clamped) box - e.g. an image\n// or async child rendering more after mount. scrollHeight still reports the wrapper's true height\n// either way, clamped or not, so the read doesn't change - only where we watch for changes does.\n// isOverflowing and collapsedHeight are the effect's only dependencies. isOverflowing: BitkitCollapsible\n// renders a different tree depending on it (see below), moving contentRef to a different DOM node each\n// time it flips, so the effect must re-attach then. children is deliberately not a dependency: the\n// wrapper being unclamped means the observer already sees every content-driven size change on its own.\nconst useIsContentOverflowing = (collapsedHeight: string) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const [isOverflowing, setIsOverflowing] = useState(true);\n\n useSafeLayoutEffect(() => {\n const contentEl = contentRef.current;\n const measureScope = contentEl?.parentElement;\n if (!contentEl || !measureScope) {\n return undefined;\n }\n\n // Appended as a sibling of contentEl (not document.body) so it inherits the same font-size and\n // CSS custom properties contentEl actually sees, resolving em/var(...) heights correctly - not\n // just px/rem, which don't depend on where in the tree they're resolved.\n const probe = document.createElement('div');\n probe.style.cssText = `position: absolute; visibility: hidden; pointer-events: none; height: ${collapsedHeight};`;\n measureScope.appendChild(probe);\n const collapsedHeightPx = probe.getBoundingClientRect().height;\n measureScope.removeChild(probe);\n\n const checkOverflow = () => setIsOverflowing(contentEl.scrollHeight > collapsedHeightPx);\n checkOverflow();\n\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const resizeObserver = new ResizeObserver(checkOverflow);\n resizeObserver.observe(contentEl);\n return () => resizeObserver.disconnect();\n }, [collapsedHeight, isOverflowing]);\n\n return { contentRef, isOverflowing };\n};\n\nconst BitkitCollapsible = forwardRef<HTMLDivElement, BitkitCollapsibleProps>((props, ref) => {\n const {\n children,\n closedLabel = 'Show less',\n collapsedHeight = '48px',\n collapsedWidth,\n css,\n defaultOpen,\n disabled,\n hideMode,\n ids,\n label,\n labelProps,\n lazyMount,\n onExitComplete,\n onOpenChange,\n open,\n openLabel = 'Show more',\n unmountOnExit,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'collapsible' });\n const styles = recipe();\n\n const { contentRef, isOverflowing } = useIsContentOverflowing(collapsedHeight);\n\n const handleOpenChange = onOpenChange ? (details: { open: boolean }) => onOpenChange(details.open) : undefined;\n\n // zag's closed-state styling (min/max-height clamp, the fade-out pseudo-element) is driven purely by\n // Collapsible.Root defaulting to \"closed\" - it doesn't know or care whether collapsedHeight would\n // ever actually clip anything. Passing collapsedHeight and hiding only the trigger still leaves\n // content that fits pinned to that height and faded, so when it doesn't overflow we skip\n // Collapsible.Root/Content entirely and render plain markup instead of fighting the closed-state\n // styling with overrides. Only styles.root applies here - it carries the inherited color/textStyle,\n // which is all a non-collapsing block needs; styles.content's overflow/position/fade rules are\n // collapse-only and would clip content (a focus ring, an absolutely-positioned child) that isn't\n // meant to be clipped. contentRef sits directly under styles.root rather than under a styles.content\n // box, so measureScope (its parent) is styles.root in this branch and styles.content in the\n // overflowing one below - both carry the same inherited font-size, since textStyle now lives on\n // root and cascades down, so collapsedHeight's em/var(...) units resolve the same way in either\n // branch. disabled/ids/collapsedWidth/onExitComplete/lazyMount/unmountOnExit/hideMode\n // are zag/Ark machine props with no meaning on plain markup, so they're destructured out above and\n // only forwarded to Collapsible.Root below - otherwise they'd reach the DOM as unknown attributes.\n //\n // isOverflowing starts true, so every mount (even of content that turns out to fit) renders through\n // this Collapsible.Root tree first and flips to the plain tree below once measured - a real\n // remount of children, since the two trees don't share a component type at that position. Same\n // going the other way on a runtime resize. Accepted tradeoff: measuring requires a real layout\n // pass, and we don't have the content's size before that first render.\n if (!isOverflowing) {\n return (\n <Box ref={ref} css={[styles.root, css]} {...rest}>\n {label && <BitkitLabel {...labelProps}>{label}</BitkitLabel>}\n <Box ref={contentRef}>{children}</Box>\n </Box>\n );\n }\n\n return (\n <Collapsible.Root\n ref={ref}\n collapsedHeight={collapsedHeight}\n collapsedWidth={collapsedWidth}\n css={[styles.root, css]}\n defaultOpen={defaultOpen}\n disabled={disabled}\n hideMode={hideMode}\n ids={ids}\n lazyMount={lazyMount}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n unmountOnExit={unmountOnExit}\n {...rest}\n >\n {label && <BitkitLabel {...labelProps}>{label}</BitkitLabel>}\n <Collapsible.Content css={styles.content}>\n <Box ref={contentRef}>{children}</Box>\n </Collapsible.Content>\n <Collapsible.Trigger css={styles.trigger}>\n <Collapsible.Context>\n {(api) => (\n <>\n {api.open ? closedLabel : openLabel}\n {api.open ? <IconChevronUp size=\"16\" /> : <IconChevronDown size=\"16\" />}\n </>\n )}\n </Collapsible.Context>\n </Collapsible.Trigger>\n </Collapsible.Root>\n );\n});\n\nBitkitCollapsible.displayName = 'BitkitCollapsible';\n\nexport default BitkitCollapsible;\n"],"mappings":";;;;;;;;;;AA2CA,IAAM,2BAA2B,oBAA4B;CAC3D,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,CAAC,eAAe,oBAAoB,SAAS,IAAI;CAEvD,0BAA0B;EACxB,MAAM,YAAY,WAAW;EAC7B,MAAM,eAAe,WAAW;EAChC,IAAI,CAAC,aAAa,CAAC,cACjB;EAMF,MAAM,QAAQ,SAAS,cAAc,KAAK;EAC1C,MAAM,MAAM,UAAU,yEAAyE,gBAAgB;EAC/G,aAAa,YAAY,KAAK;EAC9B,MAAM,oBAAoB,MAAM,sBAAsB,CAAC,CAAC;EACxD,aAAa,YAAY,KAAK;EAE9B,MAAM,sBAAsB,iBAAiB,UAAU,eAAe,iBAAiB;EACvF,cAAc;EAEd,IAAI,OAAO,mBAAmB,aAC5B;EAGF,MAAM,iBAAiB,IAAI,eAAe,aAAa;EACvD,eAAe,QAAQ,SAAS;EAChC,aAAa,eAAe,WAAW;CACzC,GAAG,CAAC,iBAAiB,aAAa,CAAC;CAEnC,OAAO;EAAE;EAAY;CAAc;AACrC;AAEA,IAAM,oBAAoB,YAAoD,OAAO,QAAQ;CAC3F,MAAM,EACJ,UACA,cAAc,aACd,kBAAkB,QAClB,gBACA,KACA,aACA,UACA,UACA,KACA,OACA,YACA,WACA,gBACA,cACA,MACA,YAAY,aACZ,eACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,cAAc,CACnC,CAAA,CAAO;CAEtB,MAAM,EAAE,YAAY,kBAAkB,wBAAwB,eAAe;CAE7E,MAAM,mBAAmB,gBAAgB,YAA+B,aAAa,QAAQ,IAAI,IAAI,KAAA;CAuBrG,IAAI,CAAC,eACH,OACE,qBAAC,KAAD;EAAU;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,GAAI;EAA5C,UAAA,CACG,SAAS,oBAAC,aAAD;GAAa,GAAI;GAAa,UAAA;EAAmB,CAAA,GAC3D,oBAAC,KAAD;GAAK,KAAK;GAAa;EAAc,CAAA,CAClC;;CAIT,OACE,qBAAC,YAAY,MAAb;EACO;EACY;EACD;EAChB,KAAK,CAAC,OAAO,MAAM,GAAG;EACT;EACH;EACA;EACL;EACM;EACK;EAChB,cAAc;EACR;EACS;EACf,GAAI;EAdN,UAAA;GAgBG,SAAS,oBAAC,aAAD;IAAa,GAAI;IAAa,UAAA;GAAmB,CAAA;GAC3D,oBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAC/B,UAAA,oBAAC,KAAD;KAAK,KAAK;KAAa;IAAc,CAAA;GAClB,CAAA;GACrB,oBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAC/B,UAAA,oBAAC,YAAY,SAAb,EAAA,WACI,QACA,qBAAAA,YAAA,EAAA,UAAA,CACG,IAAI,OAAO,cAAc,WACzB,IAAI,OAAO,oBAAC,eAAD,EAAe,MAAK,KAAM,CAAA,IAAI,oBAAC,iBAAD,EAAiB,MAAK,KAAM,CAAA,CACtE,EAAA,CAAA,EAEe,CAAA;GACF,CAAA;EACL;;AAEtB,CAAC;AAED,kBAAkB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitColorButton.js","names":[],"sources":["../../../lib/components/BitkitColorButton/BitkitColorButton.tsx"],"sourcesContent":["import { Spinner } from '@chakra-ui/react/spinner';\nimport { createRecipeContext, type HTMLChakraProps, type RecipeProps } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type KeyboardEvent, type MouseEvent, type Ref } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport colorButtonRecipe from '../../theme/recipes/ColorButton.recipe';\n\ntype ColorButtonOmitted = 'as' | 'colorPalette' | 'size' | 'type';\n\ntype StyledButtonProps = Omit<HTMLChakraProps<'button'>, 'colorPalette' | 'size'> & RecipeProps<'colorButton'>;\ntype StyledAnchorProps = Omit<HTMLChakraProps<'a'>, 'colorPalette' | 'size'> & RecipeProps<'colorButton'>;\n\ninterface BitkitColorButtonCommonProps extends RecipeProps<'colorButton'> {\n /**\n * Disabled or loading state of the control. Both are honoured in anchor mode too.\n *\n * Note that `'loading'` behaves differently here than on `BitkitButton`, which delegates to\n * Chakra's `Button loading` and therefore also *disables* and dims the control. This one stays\n * focusable and undimmed: the label keeps its width, a spinner is overlaid on top of it, and\n * activation is blocked by a click guard — so a keyboard or screen reader user doesn't lose the\n * element they were on the moment they press it.\n */\n state?: 'disabled' | 'loading';\n suffixIcon?: BitkitIconComponent;\n}\n\nexport interface BitkitColorButtonAsButtonProps\n extends BitkitColorButtonCommonProps, Omit<HTMLChakraProps<'button'>, ColorButtonOmitted | 'disabled'> {\n href?: undefined;\n isExternal?: undefined;\n}\n\nexport interface BitkitColorButtonAsAnchorProps\n extends BitkitColorButtonCommonProps, Omit<HTMLChakraProps<'a'>, ColorButtonOmitted> {\n href: string;\n isExternal?: boolean;\n}\n\nexport type BitkitColorButtonProps = BitkitColorButtonAsButtonProps | BitkitColorButtonAsAnchorProps;\n\nconst { withContext } = createRecipeContext({ recipe: colorButtonRecipe });\n\nconst StyledButton = withContext<HTMLButtonElement, StyledButtonProps>('button');\n\nconst StyledAnchor = withContext<HTMLAnchorElement, StyledAnchorProps>('a');\n\nconst BitkitColorButton = forwardRef<HTMLButtonElement | HTMLAnchorElement, BitkitColorButtonProps>((props, ref) => {\n const { children, size, state, suffixIcon: SuffixIcon } = props;\n const isDisabled = state === 'disabled';\n const isLoading = state === 'loading';\n const isInactive = isDisabled || isLoading;\n const spinnerSize = size === 'lg' ? '20' : '16';\n // Keep the fallback equal to `defaultVariants.size` in ColorButton.recipe.ts.\n const iconSize = (size ?? 'sm') === 'lg' ? '24' : '16';\n\n const content = (\n <>\n {isLoading ? (\n // `opacity: 0` rather than `visibility: hidden`: both reserve the label's width so the\n // button doesn't collapse, but `visibility: hidden` also drops it from the accessibility\n // tree — leaving a focusable control with no accessible name.\n <Text as=\"span\" opacity=\"0\" userSelect=\"none\">\n {children}\n </Text>\n ) : (\n children\n )}\n {SuffixIcon && (\n <SuffixIcon marginInlineEnd=\"-4\" marginInlineStart=\"8\" opacity={isLoading ? 0 : undefined} size={iconSize} />\n )}\n {isLoading && (\n <Spinner\n position=\"absolute\"\n insetBlock=\"0\"\n insetInline=\"0\"\n margin=\"auto\"\n height={spinnerSize}\n width={spinnerSize}\n />\n )}\n </>\n );\n\n // --- Anchor mode (href) ---\n if (props.href !== undefined) {\n const {\n children: _children,\n href,\n isExternal,\n onClick,\n onKeyDown,\n rel,\n state: _state,\n suffixIcon: _suffixIcon,\n target,\n ...anchorRest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = isInactive\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n // What actually blocks keyboard activation in both states is `handleClick`: neither state\n // removes the anchor from the tab order (`loading` never sets `disabled`, and a disabled anchor\n // is only `aria-disabled`), and Enter/Space dispatch a click, which the guard above swallows.\n // The keydown guard is the extra layer an anchor needs, since it never gets the native\n // `disabled` treatment a button does.\n const handleKeyDown = isInactive\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n\n return (\n <StyledAnchor\n ref={ref as Ref<HTMLAnchorElement>}\n {...anchorRest}\n aria-disabled={isDisabled || undefined}\n data-disabled={isDisabled || undefined}\n // `data-loading` (not `aria-busy`) — it's the styling hook the recipe's `_loading` condition\n // reads, without claiming ARIA semantics that aren't announced anyway. Announcing the state\n // change to assistive tech needs a live region inside the component; that's its own change.\n data-loading={isLoading || undefined}\n // The `href` is kept while loading — so the link stays focusable and keeps its accessible\n // name, with activation still blocked by the guards above — and dropped only when disabled,\n // to take the anchor out of the tab order and make it fully inert.\n href={isDisabled ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n rel={effectiveRel}\n target={effectiveTarget}\n >\n {content}\n </StyledAnchor>\n );\n }\n\n // --- Button mode (default) ---\n const { children: _children, onClick, state: _state, suffixIcon: _suffixIcon, ...buttonRest } = props;\n const handleClick = isInactive\n ? (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n\n return (\n <StyledButton\n ref={ref as Ref<HTMLButtonElement>}\n {...buttonRest}\n data-loading={isLoading || undefined}\n disabled={isDisabled}\n onClick={handleClick}\n type=\"button\"\n >\n {content}\n </StyledButton>\n );\n});\n\nBitkitColorButton.displayName = 'BitkitColorButton';\n\nexport default BitkitColorButton;\n"],"mappings":";;;;;;;AAyCA,IAAM,EAAE,gBAAgB,oBAAoB,EAAE,QAAQ,kBAAkB,CAAC;AAEzE,IAAM,eAAe,YAAkD,QAAQ;AAE/E,IAAM,eAAe,YAAkD,GAAG;AAE1E,IAAM,oBAAoB,YAA2E,OAAO,QAAQ;CAClH,MAAM,EAAE,UAAU,MAAM,OAAO,YAAY,eAAe;CAC1D,MAAM,aAAa,UAAU;CAC7B,MAAM,YAAY,UAAU;CAC5B,MAAM,aAAa,cAAc;CACjC,MAAM,cAAc,SAAS,OAAO,OAAO;CAI3C,MAAM,UACJ,
|
|
1
|
+
{"version":3,"file":"BitkitColorButton.js","names":["_Fragment"],"sources":["../../../lib/components/BitkitColorButton/BitkitColorButton.tsx"],"sourcesContent":["import { Spinner } from '@chakra-ui/react/spinner';\nimport { createRecipeContext, type HTMLChakraProps, type RecipeProps } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type KeyboardEvent, type MouseEvent, type Ref } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport colorButtonRecipe from '../../theme/recipes/ColorButton.recipe';\n\ntype ColorButtonOmitted = 'as' | 'colorPalette' | 'size' | 'type';\n\ntype StyledButtonProps = Omit<HTMLChakraProps<'button'>, 'colorPalette' | 'size'> & RecipeProps<'colorButton'>;\ntype StyledAnchorProps = Omit<HTMLChakraProps<'a'>, 'colorPalette' | 'size'> & RecipeProps<'colorButton'>;\n\ninterface BitkitColorButtonCommonProps extends RecipeProps<'colorButton'> {\n /**\n * Disabled or loading state of the control. Both are honoured in anchor mode too.\n *\n * Note that `'loading'` behaves differently here than on `BitkitButton`, which delegates to\n * Chakra's `Button loading` and therefore also *disables* and dims the control. This one stays\n * focusable and undimmed: the label keeps its width, a spinner is overlaid on top of it, and\n * activation is blocked by a click guard — so a keyboard or screen reader user doesn't lose the\n * element they were on the moment they press it.\n */\n state?: 'disabled' | 'loading';\n suffixIcon?: BitkitIconComponent;\n}\n\nexport interface BitkitColorButtonAsButtonProps\n extends BitkitColorButtonCommonProps, Omit<HTMLChakraProps<'button'>, ColorButtonOmitted | 'disabled'> {\n href?: undefined;\n isExternal?: undefined;\n}\n\nexport interface BitkitColorButtonAsAnchorProps\n extends BitkitColorButtonCommonProps, Omit<HTMLChakraProps<'a'>, ColorButtonOmitted> {\n href: string;\n isExternal?: boolean;\n}\n\nexport type BitkitColorButtonProps = BitkitColorButtonAsButtonProps | BitkitColorButtonAsAnchorProps;\n\nconst { withContext } = createRecipeContext({ recipe: colorButtonRecipe });\n\nconst StyledButton = withContext<HTMLButtonElement, StyledButtonProps>('button');\n\nconst StyledAnchor = withContext<HTMLAnchorElement, StyledAnchorProps>('a');\n\nconst BitkitColorButton = forwardRef<HTMLButtonElement | HTMLAnchorElement, BitkitColorButtonProps>((props, ref) => {\n const { children, size, state, suffixIcon: SuffixIcon } = props;\n const isDisabled = state === 'disabled';\n const isLoading = state === 'loading';\n const isInactive = isDisabled || isLoading;\n const spinnerSize = size === 'lg' ? '20' : '16';\n // Keep the fallback equal to `defaultVariants.size` in ColorButton.recipe.ts.\n const iconSize = (size ?? 'sm') === 'lg' ? '24' : '16';\n\n const content = (\n <>\n {isLoading ? (\n // `opacity: 0` rather than `visibility: hidden`: both reserve the label's width so the\n // button doesn't collapse, but `visibility: hidden` also drops it from the accessibility\n // tree — leaving a focusable control with no accessible name.\n <Text as=\"span\" opacity=\"0\" userSelect=\"none\">\n {children}\n </Text>\n ) : (\n children\n )}\n {SuffixIcon && (\n <SuffixIcon marginInlineEnd=\"-4\" marginInlineStart=\"8\" opacity={isLoading ? 0 : undefined} size={iconSize} />\n )}\n {isLoading && (\n <Spinner\n position=\"absolute\"\n insetBlock=\"0\"\n insetInline=\"0\"\n margin=\"auto\"\n height={spinnerSize}\n width={spinnerSize}\n />\n )}\n </>\n );\n\n // --- Anchor mode (href) ---\n if (props.href !== undefined) {\n const {\n children: _children,\n href,\n isExternal,\n onClick,\n onKeyDown,\n rel,\n state: _state,\n suffixIcon: _suffixIcon,\n target,\n ...anchorRest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = isInactive\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n // What actually blocks keyboard activation in both states is `handleClick`: neither state\n // removes the anchor from the tab order (`loading` never sets `disabled`, and a disabled anchor\n // is only `aria-disabled`), and Enter/Space dispatch a click, which the guard above swallows.\n // The keydown guard is the extra layer an anchor needs, since it never gets the native\n // `disabled` treatment a button does.\n const handleKeyDown = isInactive\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n\n return (\n <StyledAnchor\n ref={ref as Ref<HTMLAnchorElement>}\n {...anchorRest}\n aria-disabled={isDisabled || undefined}\n data-disabled={isDisabled || undefined}\n // `data-loading` (not `aria-busy`) — it's the styling hook the recipe's `_loading` condition\n // reads, without claiming ARIA semantics that aren't announced anyway. Announcing the state\n // change to assistive tech needs a live region inside the component; that's its own change.\n data-loading={isLoading || undefined}\n // The `href` is kept while loading — so the link stays focusable and keeps its accessible\n // name, with activation still blocked by the guards above — and dropped only when disabled,\n // to take the anchor out of the tab order and make it fully inert.\n href={isDisabled ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n rel={effectiveRel}\n target={effectiveTarget}\n >\n {content}\n </StyledAnchor>\n );\n }\n\n // --- Button mode (default) ---\n const { children: _children, onClick, state: _state, suffixIcon: _suffixIcon, ...buttonRest } = props;\n const handleClick = isInactive\n ? (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n\n return (\n <StyledButton\n ref={ref as Ref<HTMLButtonElement>}\n {...buttonRest}\n data-loading={isLoading || undefined}\n disabled={isDisabled}\n onClick={handleClick}\n type=\"button\"\n >\n {content}\n </StyledButton>\n );\n});\n\nBitkitColorButton.displayName = 'BitkitColorButton';\n\nexport default BitkitColorButton;\n"],"mappings":";;;;;;;AAyCA,IAAM,EAAE,gBAAgB,oBAAoB,EAAE,QAAQ,kBAAkB,CAAC;AAEzE,IAAM,eAAe,YAAkD,QAAQ;AAE/E,IAAM,eAAe,YAAkD,GAAG;AAE1E,IAAM,oBAAoB,YAA2E,OAAO,QAAQ;CAClH,MAAM,EAAE,UAAU,MAAM,OAAO,YAAY,eAAe;CAC1D,MAAM,aAAa,UAAU;CAC7B,MAAM,YAAY,UAAU;CAC5B,MAAM,aAAa,cAAc;CACjC,MAAM,cAAc,SAAS,OAAO,OAAO;CAI3C,MAAM,UACJ,qBAAAA,YAAA,EAAA,UAAA;EACG,YAIC,oBAAC,MAAD;GAAM,IAAG;GAAO,SAAQ;GAAI,YAAW;GACpC;EACG,CAAA,IAEN;EAED,cACC,oBAAC,YAAD;GAAY,iBAAgB;GAAK,mBAAkB;GAAI,SAAS,YAAY,IAAI,KAAA;GAAW,OAf/E,QAAQ,UAAU,OAAO,OAAO;EAegE,CAAA;EAE7G,aACC,oBAAC,SAAD;GACE,UAAS;GACT,YAAW;GACX,aAAY;GACZ,QAAO;GACP,QAAQ;GACR,OAAO;EACR,CAAA;CAEH,EAAA,CAAA;CAIJ,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,UAAU,WACV,MACA,YACA,SACA,WACA,KACA,OAAO,QACP,YAAY,aACZ,QACA,GAAG,eACD;EACJ,MAAM,kBAAkB,aAAa,WAAW;EAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;EACjG,MAAM,cAAc,cACf,MAAqC;GACpC,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB,IACA;EAMJ,MAAM,gBAAgB,cACjB,MAAwC;GACvC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtC,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;EACF,IACA;EAEJ,OACE,oBAAC,cAAD;GACO;GACL,GAAI;GACJ,iBAAe,cAAc,KAAA;GAC7B,iBAAe,cAAc,KAAA;GAI7B,gBAAc,aAAa,KAAA;GAI3B,MAAM,aAAa,KAAA,IAAY;GAC/B,SAAS;GACT,WAAW;GACX,KAAK;GACL,QAAQ;GAEP,UAAA;EACW,CAAA;CAElB;CAGA,MAAM,EAAE,UAAU,WAAW,SAAS,OAAO,QAAQ,YAAY,aAAa,GAAG,eAAe;CAChG,MAAM,cAAc,cACf,MAAqC;EACpC,EAAE,eAAe;EACjB,EAAE,gBAAgB;CACpB,IACA;CAEJ,OACE,oBAAC,cAAD;EACO;EACL,GAAI;EACJ,gBAAc,aAAa,KAAA;EAC3B,UAAU;EACV,SAAS;EACT,MAAK;EAEJ,UAAA;CACW,CAAA;AAElB,CAAC;AAED,kBAAkB,cAAc"}
|
|
@@ -3,8 +3,6 @@ import { BitkitFieldProps } from '../BitkitField/BitkitField';
|
|
|
3
3
|
export type BitkitDatePickerControlProps = BoxProps;
|
|
4
4
|
export interface BitkitDatePickerProps extends Omit<BitkitFieldProps, 'children' | 'defaultValue' | 'state' | 'value'> {
|
|
5
5
|
controlProps?: BitkitDatePickerControlProps;
|
|
6
|
-
/** Text for a day's tooltip, e.g. why it can't be picked. Return `undefined` for no tooltip. */
|
|
7
|
-
dayTooltip?: (date: Date) => string | undefined;
|
|
8
6
|
defaultValue?: Date | null;
|
|
9
7
|
disablePortal?: boolean;
|
|
10
8
|
max?: Date;
|
|
@@ -46,7 +46,7 @@ var DatePickerInput = ({ css }) => {
|
|
|
46
46
|
});
|
|
47
47
|
};
|
|
48
48
|
var BitkitDatePicker = forwardRef((props, ref) => {
|
|
49
|
-
const { controlProps,
|
|
49
|
+
const { controlProps, defaultValue, disablePortal, max, min, onValueChange, placeholder, showOutsideDays, size = "lg", state, value, ...fieldProps } = props;
|
|
50
50
|
const styles = useSlotRecipe({ key: "textInput" })({ size });
|
|
51
51
|
const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);
|
|
52
52
|
const minCalendarDate = useMemo(() => min ? dateToCalendarDate(min) : void 0, [min]);
|
|
@@ -115,7 +115,6 @@ var BitkitDatePicker = forwardRef((props, ref) => {
|
|
|
115
115
|
}), /* @__PURE__ */ jsx(Portal, {
|
|
116
116
|
disabled: disablePortal || disablePortalFromContext,
|
|
117
117
|
children: /* @__PURE__ */ jsx(DatePicker.Positioner, { children: /* @__PURE__ */ jsx(CalendarContent, {
|
|
118
|
-
dayTooltip,
|
|
119
118
|
layout: "1-month",
|
|
120
119
|
max: maxCalendarDate,
|
|
121
120
|
min: minCalendarDate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitDatePicker.js","names":[],"sources":["../../../lib/components/BitkitDatePicker/BitkitDatePicker.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { useFieldContext } from '@chakra-ui/react/field';\nimport { useSafeLayoutEffect } from '@chakra-ui/react/hooks';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { type SystemStyleObject, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useContext, useMemo, useRef } from 'react';\n\nimport { DatePicker, type DatePickerValueChangeDetails, useDatePickerContext } from '../../atoms/DatePicker/DatePicker';\nimport IconCalendar from '../../icons/IconCalendar';\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport { calendarDateToDate, dateToCalendarDate } from '../BitkitCalendar/Calendar.utils';\nimport CalendarContent from '../BitkitCalendar/components/CalendarContent';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport type BitkitDatePickerControlProps = BoxProps;\n\nexport interface BitkitDatePickerProps extends Omit<BitkitFieldProps, 'children' | 'defaultValue' | 'state' | 'value'> {\n controlProps?: BitkitDatePickerControlProps;\n /** Text for a day's tooltip, e.g. why it can't be picked. Return `undefined` for no tooltip. */\n dayTooltip?: (date: Date) => string | undefined;\n defaultValue?: Date | null;\n disablePortal?: boolean;\n max?: Date;\n min?: Date;\n onValueChange?: (value: Date | null) => void;\n placeholder?: string;\n showOutsideDays?: boolean;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n value?: Date | null;\n}\n\n/**\n * Ark offers `openOnClick` but nothing for focus, so the calendar is opened from the input's own\n * focus event — that covers tabbing in as well as clicking.\n */\nconst DatePickerInput = ({ css }: { css: SystemStyleObject }) => {\n const { disabled, open, readOnly, setOpen } = useDatePickerContext();\n // Ark's DatePicker.Input has no notion of Chakra's Field — without this, `errorText`/`helperText`\n // render visually but are never announced, since nothing points the input's aria-describedby at them.\n const ariaDescribedby = useFieldContext()?.ariaDescribedby;\n const reopenBlockedRef = useRef(false);\n const wasOpenRef = useRef(false);\n\n // Zag's `focusInputElement` puts focus back on the input a frame after the calendar closes on\n // selection, which would bounce it straight back open. Ignore focus that lands right after a\n // close — this has to be a layout effect so the flag is set before Zag's rAF runs. Isomorphic\n // layout effect: avoids the SSR \"useLayoutEffect does nothing on the server\" warning.\n useSafeLayoutEffect(() => {\n const justClosed = wasOpenRef.current && !open;\n wasOpenRef.current = open;\n\n // Only a real close can trigger Zag's refocus, so mount (never-opened) must not arm the block\n // — otherwise an autoFocus or a programmatic focus right after mount gets swallowed.\n if (!justClosed) {\n return undefined;\n }\n\n reopenBlockedRef.current = true;\n const timeout = setTimeout(() => {\n reopenBlockedRef.current = false;\n }, 100);\n\n return () => clearTimeout(timeout);\n }, [open]);\n\n // Ark gates its own trigger handlers on the machine's interactive state, but `setOpen` is not —\n // it would happily open the calendar on a read-only or disabled field. A disabled input still\n // needs the check: Chrome fires focus events for a programmatic `.focus()` on one, even though\n // focus never actually lands there.\n const handleFocus = () => {\n if (!reopenBlockedRef.current && !readOnly && !disabled) {\n setOpen(true);\n }\n };\n\n return <DatePicker.Input aria-describedby={ariaDescribedby} css={css} index={0} onFocus={handleFocus} unstyled />;\n};\n\nconst BitkitDatePicker = forwardRef<HTMLDivElement, BitkitDatePickerProps>((props, ref) => {\n const {\n controlProps,\n dayTooltip,\n defaultValue,\n disablePortal,\n max,\n min,\n onValueChange,\n placeholder,\n showOutsideDays,\n size = 'lg',\n state,\n value,\n ...fieldProps\n } = props;\n\n const recipe = useSlotRecipe({ key: 'textInput' });\n const styles = recipe({ size });\n\n const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\n\n const minCalendarDate = useMemo(() => (min ? dateToCalendarDate(min) : undefined), [min]);\n const maxCalendarDate = useMemo(() => (max ? dateToCalendarDate(max) : undefined), [max]);\n\n const iconSize = size === 'md' ? '16' : '24';\n const hasWarning = state === 'warning' || !!fieldProps.warningText;\n const isInvalid = state === 'error' || !!fieldProps.errorText;\n\n let statusIcon: ReactNode = null;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled color=\"icon/negative\" size={iconSize} />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n const stateAttrs = {\n 'data-disabled': state === 'disabled' ? '' : undefined,\n 'data-invalid': isInvalid ? '' : undefined,\n 'data-readonly': state === 'readOnly' ? '' : undefined,\n };\n\n const isInteractive = state !== 'disabled' && state !== 'readOnly';\n\n const calendarButton = (\n <BitkitControlButton\n icon={IconCalendar}\n label=\"Open calendar\"\n // Pulled out by its own padding so the glyph lands where a plain end icon would sit in\n // BitkitTextInput — 16px (lg) / 12px (md) from the field's outer edge.\n marginInlineEnd={size === 'md' ? '-8' : '-4'}\n size={size === 'md' ? 'xs' : 'sm'}\n state={isInteractive ? undefined : 'disabled'}\n />\n );\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <DatePicker.Root\n defaultValue={defaultValue ? [dateToCalendarDate(defaultValue)] : undefined}\n device=\"desktop\"\n disabled={state === 'disabled'}\n invalid={isInvalid}\n layout=\"1-month\"\n max={maxCalendarDate}\n min={minCalendarDate}\n numOfMonths={1}\n onValueChange={\n onValueChange\n ? (details: DatePickerValueChangeDetails) =>\n onValueChange(details.value?.[0] ? calendarDateToDate(details.value[0]) : null)\n : undefined\n }\n placeholder={state === 'readOnly' ? '(not set)' : placeholder}\n positioning={{ placement: 'bottom-start' }}\n readOnly={state === 'readOnly'}\n selectionMode=\"single\"\n showOutsideDays={showOutsideDays ?? true}\n startOfWeek={1}\n // Stay controlled whenever `value` is provided — even for `null` (\"nothing selected\").\n // Passing `undefined` would flip Root to uncontrolled. See BitkitCombobox.\n value={value === undefined ? undefined : value ? [dateToCalendarDate(value)] : []}\n >\n <DatePicker.Control asChild>\n <Box {...controlProps} css={[styles.field, controlProps?.css]} {...stateAttrs}>\n <DatePickerInput css={styles.input} />\n {statusIcon != null && (\n <Box css={styles.element} {...stateAttrs}>\n {statusIcon}\n </Box>\n )}\n {/* Ark keeps the trigger interactive in read-only mode and forces `disabled={false}`\n onto whatever it wraps, so the button is left unwrapped there to stay inert. */}\n {state === 'readOnly' ? calendarButton : <DatePicker.Trigger asChild>{calendarButton}</DatePicker.Trigger>}\n </Box>\n </DatePicker.Control>\n <Portal disabled={disablePortal || disablePortalFromContext}>\n <DatePicker.Positioner>\n <CalendarContent\n dayTooltip={dayTooltip}\n layout=\"1-month\"\n max={maxCalendarDate}\n min={minCalendarDate}\n selectionMode=\"day\"\n />\n </DatePicker.Positioner>\n </Portal>\n </DatePicker.Root>\n </BitkitField>\n );\n});\n\nBitkitDatePicker.displayName = 'BitkitDatePicker';\n\nexport default BitkitDatePicker;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BitkitDatePicker.js","names":[],"sources":["../../../lib/components/BitkitDatePicker/BitkitDatePicker.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { useFieldContext } from '@chakra-ui/react/field';\nimport { useSafeLayoutEffect } from '@chakra-ui/react/hooks';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { type SystemStyleObject, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useContext, useMemo, useRef } from 'react';\n\nimport { DatePicker, type DatePickerValueChangeDetails, useDatePickerContext } from '../../atoms/DatePicker/DatePicker';\nimport IconCalendar from '../../icons/IconCalendar';\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport { calendarDateToDate, dateToCalendarDate } from '../BitkitCalendar/Calendar.utils';\nimport CalendarContent from '../BitkitCalendar/components/CalendarContent';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport type BitkitDatePickerControlProps = BoxProps;\n\nexport interface BitkitDatePickerProps extends Omit<BitkitFieldProps, 'children' | 'defaultValue' | 'state' | 'value'> {\n controlProps?: BitkitDatePickerControlProps;\n defaultValue?: Date | null;\n disablePortal?: boolean;\n max?: Date;\n min?: Date;\n onValueChange?: (value: Date | null) => void;\n placeholder?: string;\n showOutsideDays?: boolean;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n value?: Date | null;\n}\n\n/**\n * Ark offers `openOnClick` but nothing for focus, so the calendar is opened from the input's own\n * focus event — that covers tabbing in as well as clicking.\n */\nconst DatePickerInput = ({ css }: { css: SystemStyleObject }) => {\n const { disabled, open, readOnly, setOpen } = useDatePickerContext();\n // Ark's DatePicker.Input has no notion of Chakra's Field — without this, `errorText`/`helperText`\n // render visually but are never announced, since nothing points the input's aria-describedby at them.\n const ariaDescribedby = useFieldContext()?.ariaDescribedby;\n const reopenBlockedRef = useRef(false);\n const wasOpenRef = useRef(false);\n\n // Zag's `focusInputElement` puts focus back on the input a frame after the calendar closes on\n // selection, which would bounce it straight back open. Ignore focus that lands right after a\n // close — this has to be a layout effect so the flag is set before Zag's rAF runs. Isomorphic\n // layout effect: avoids the SSR \"useLayoutEffect does nothing on the server\" warning.\n useSafeLayoutEffect(() => {\n const justClosed = wasOpenRef.current && !open;\n wasOpenRef.current = open;\n\n // Only a real close can trigger Zag's refocus, so mount (never-opened) must not arm the block\n // — otherwise an autoFocus or a programmatic focus right after mount gets swallowed.\n if (!justClosed) {\n return undefined;\n }\n\n reopenBlockedRef.current = true;\n const timeout = setTimeout(() => {\n reopenBlockedRef.current = false;\n }, 100);\n\n return () => clearTimeout(timeout);\n }, [open]);\n\n // Ark gates its own trigger handlers on the machine's interactive state, but `setOpen` is not —\n // it would happily open the calendar on a read-only or disabled field. A disabled input still\n // needs the check: Chrome fires focus events for a programmatic `.focus()` on one, even though\n // focus never actually lands there.\n const handleFocus = () => {\n if (!reopenBlockedRef.current && !readOnly && !disabled) {\n setOpen(true);\n }\n };\n\n return <DatePicker.Input aria-describedby={ariaDescribedby} css={css} index={0} onFocus={handleFocus} unstyled />;\n};\n\nconst BitkitDatePicker = forwardRef<HTMLDivElement, BitkitDatePickerProps>((props, ref) => {\n const {\n controlProps,\n defaultValue,\n disablePortal,\n max,\n min,\n onValueChange,\n placeholder,\n showOutsideDays,\n size = 'lg',\n state,\n value,\n ...fieldProps\n } = props;\n\n const recipe = useSlotRecipe({ key: 'textInput' });\n const styles = recipe({ size });\n\n const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\n\n const minCalendarDate = useMemo(() => (min ? dateToCalendarDate(min) : undefined), [min]);\n const maxCalendarDate = useMemo(() => (max ? dateToCalendarDate(max) : undefined), [max]);\n\n const iconSize = size === 'md' ? '16' : '24';\n const hasWarning = state === 'warning' || !!fieldProps.warningText;\n const isInvalid = state === 'error' || !!fieldProps.errorText;\n\n let statusIcon: ReactNode = null;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled color=\"icon/negative\" size={iconSize} />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n const stateAttrs = {\n 'data-disabled': state === 'disabled' ? '' : undefined,\n 'data-invalid': isInvalid ? '' : undefined,\n 'data-readonly': state === 'readOnly' ? '' : undefined,\n };\n\n const isInteractive = state !== 'disabled' && state !== 'readOnly';\n\n const calendarButton = (\n <BitkitControlButton\n icon={IconCalendar}\n label=\"Open calendar\"\n // Pulled out by its own padding so the glyph lands where a plain end icon would sit in\n // BitkitTextInput — 16px (lg) / 12px (md) from the field's outer edge.\n marginInlineEnd={size === 'md' ? '-8' : '-4'}\n size={size === 'md' ? 'xs' : 'sm'}\n state={isInteractive ? undefined : 'disabled'}\n />\n );\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <DatePicker.Root\n defaultValue={defaultValue ? [dateToCalendarDate(defaultValue)] : undefined}\n device=\"desktop\"\n disabled={state === 'disabled'}\n invalid={isInvalid}\n layout=\"1-month\"\n max={maxCalendarDate}\n min={minCalendarDate}\n numOfMonths={1}\n onValueChange={\n onValueChange\n ? (details: DatePickerValueChangeDetails) =>\n onValueChange(details.value?.[0] ? calendarDateToDate(details.value[0]) : null)\n : undefined\n }\n placeholder={state === 'readOnly' ? '(not set)' : placeholder}\n positioning={{ placement: 'bottom-start' }}\n readOnly={state === 'readOnly'}\n selectionMode=\"single\"\n showOutsideDays={showOutsideDays ?? true}\n startOfWeek={1}\n // Stay controlled whenever `value` is provided — even for `null` (\"nothing selected\").\n // Passing `undefined` would flip Root to uncontrolled. See BitkitCombobox.\n value={value === undefined ? undefined : value ? [dateToCalendarDate(value)] : []}\n >\n <DatePicker.Control asChild>\n <Box {...controlProps} css={[styles.field, controlProps?.css]} {...stateAttrs}>\n <DatePickerInput css={styles.input} />\n {statusIcon != null && (\n <Box css={styles.element} {...stateAttrs}>\n {statusIcon}\n </Box>\n )}\n {/* Ark keeps the trigger interactive in read-only mode and forces `disabled={false}`\n onto whatever it wraps, so the button is left unwrapped there to stay inert. */}\n {state === 'readOnly' ? calendarButton : <DatePicker.Trigger asChild>{calendarButton}</DatePicker.Trigger>}\n </Box>\n </DatePicker.Control>\n <Portal disabled={disablePortal || disablePortalFromContext}>\n <DatePicker.Positioner>\n <CalendarContent layout=\"1-month\" max={maxCalendarDate} min={minCalendarDate} selectionMode=\"day\" />\n </DatePicker.Positioner>\n </Portal>\n </DatePicker.Root>\n </BitkitField>\n );\n});\n\nBitkitDatePicker.displayName = 'BitkitDatePicker';\n\nexport default BitkitDatePicker;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitStepsDialog.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitStepsDialog.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactElement, type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { type BitkitDataAttributes } from '../../utilities/dataAttributes';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitSteps from '../BitkitSteps/BitkitSteps';\nimport BitkitStepsDialogStep, { type BitkitStepsDialogStepProps } from './BitkitStepsDialogStep';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogShellProps } from './DialogShell';\nimport { StepsDialogProvider } from './StepsDialogContext';\n\nexport { useStepsDialog } from './StepsDialogContext';\n\nexport type BitkitStepsDialogProps = {\n /** `BitkitStepsDialog.Step` children, one per step. */\n children: ReactNode;\n /** Initial step when uncontrolled. Resets to this when the dialog closes. */\n defaultStep?: number;\n /** Set to `false` to remove every dismiss route that skips a decision: no close button, no ESC. */\n dismissible?: boolean;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n /**\n * The step navigation, built with `useStepsDialog()`. Pass the buttons themselves: the dialog lays\n * them out the way the design asks for, leading action on the left, the step navigation opposite.\n * A footer with no leading action passes a single group, which stays on the right.\n */\n footerButtons?: ReactNode;\n /** Arbitrary content rendered raw inside the footer, above `footerButtons` (e.g. a `BitkitAlert`). */\n footerContent?: ReactNode;\n headerLabel?: string;\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n /** Called whenever the active step changes (controlled or uncontrolled). */\n onStepChange?: (step: number) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n /**\n * `loading` locks the dialog while a background action runs: the close button stays in place but\n * disabled, and ESC is blocked. Use it alongside the footer button's own `state=\"loading\"`.\n */\n state?: 'loading';\n /** Controlled active step. Omit for uncontrolled (see `defaultStep`). */\n step?: number;\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n // Data attributes are forwarded to the element carrying `role=\"dialog\"`, and nothing else is —\n // style props, `className` and `id` don't pass through.\n} & BitkitDataAttributes;\n\n/**\n * A dialog that walks through a sequence of `BitkitStepsDialog.Step` children. It owns the step\n * state, auto-renders the steps header, and shows only the active step's body. The consumer builds\n * the step navigation with the `useStepsDialog()` hook and passes it in as `footerButtons`.\n */\nconst BitkitStepsDialog = ({\n children,\n defaultStep = 0,\n dismissible = true,\n initialFocusEl,\n footerButtons,\n footerContent,\n headerLabel,\n maxHeight,\n onExitComplete,\n onOpenChange,\n onStepChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n state,\n step: stepProp,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitStepsDialogProps) => {\n const [internalStep, setInternalStep] = useState(defaultStep);\n const isControlled = stepProp !== undefined;\n const rawStep = (isControlled ? stepProp : internalStep) ?? 0;\n const steps = flattenChildren(children).filter(\n (child): child is ReactElement<BitkitStepsDialogStepProps> => child.type === BitkitStepsDialogStep,\n );\n const totalSteps = steps.length;\n const step = Math.max(0, Math.min(rawStep, Math.max(0, totalSteps - 1)));\n\n const setStep = useCallback(\n (next: number) => {\n const clamped = Math.max(0, Math.min(next, totalSteps - 1));\n if (!isControlled) setInternalStep(clamped);\n onStepChange?.(clamped);\n },\n [isControlled, onStepChange, totalSteps],\n );\n\n const ctx = useMemo(\n () => ({\n goTo: setStep,\n isFirst: step === 0,\n isLast: step === totalSteps - 1,\n next: () => setStep(step + 1),\n prev: () => setStep(step - 1),\n setStep,\n step,\n totalSteps,\n }),\n [setStep, step, totalSteps],\n );\n\n const handleOpenChange = (details: { open: boolean }) => {\n if (!details.open && !isControlled) setInternalStep(defaultStep);\n onOpenChange?.(details);\n };\n\n // The design splits this row: the leading action sits opposite the step navigation. Laying it out\n // here rather than in `DialogInner` keeps the shared action block right-aligned for every other\n // dialog, and keeps the split off every call site. A footer with no leading action passes a single\n // group, which `space-between` would park at the start, so that case is pushed back to the end. It\n // has to be a selector rather than a prop: `footerButtons` is one element rendering a fragment, so\n // the component cannot count what it will produce.\n const footerNav = footerButtons && (\n <Box\n css={{ '& > :only-child': { marginInlineStart: 'auto' } }}\n display=\"flex\"\n justifyContent=\"space-between\"\n width=\"100%\"\n >\n {footerButtons}\n </Box>\n );\n\n const stepsHeader = (\n <BitkitSteps step={step}>\n {steps.map((child, index) => (\n <BitkitSteps.Item key={index} label={child.props.label} />\n ))}\n </BitkitSteps>\n );\n\n return (\n <StepsDialogProvider value={ctx}>\n <DialogShell\n dismissible={dismissible}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n state={state}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content aria-busy={state === 'loading' || undefined} maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n dismissible={dismissible}\n footerButtons={footerNav}\n footerContent={footerContent}\n headerExtra={stepsHeader}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n state={state}\n title={title}\n variant={variant}\n >\n {steps[step]}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n </StepsDialogProvider>\n );\n};\n\nBitkitStepsDialog.displayName = 'BitkitStepsDialog';\n\nexport default withSubComponents(BitkitStepsDialog, {\n ActionTrigger: Dialog.ActionTrigger,\n Step: BitkitStepsDialogStep,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;AA8DA,IAAM,qBAAqB,EACzB,UACA,cAAc,GACd,cAAc,MACd,gBACA,eACA,eACA,aACA,WACA,gBACA,cACA,cACA,MACA,eACA,gBACA,oBACA,MACA,OACA,MAAM,UACN,OACA,SACA,SACA,GAAG,qBACyB;CAC5B,MAAM,CAAC,cAAc,mBAAmB,SAAS,WAAW;CAC5D,MAAM,eAAe,aAAa,KAAA;CAClC,MAAM,WAAW,eAAe,WAAW,iBAAiB;CAC5D,MAAM,QAAQ,gBAAgB,QAAQ,CAAC,CAAC,QACrC,UAA6D,MAAM,SAAS,qBAC/E;CACA,MAAM,aAAa,MAAM;CACzB,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;CAEvE,MAAM,UAAU,aACb,SAAiB;EAChB,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,CAAC,CAAC;EAC1D,IAAI,CAAC,cAAc,gBAAgB,OAAO;EAC1C,eAAe,OAAO;CACxB,GACA;EAAC;EAAc;EAAc;CAAU,CACzC;CAEA,MAAM,MAAM,eACH;EACL,MAAM;EACN,SAAS,SAAS;EAClB,QAAQ,SAAS,aAAa;EAC9B,YAAY,QAAQ,OAAO,CAAC;EAC5B,YAAY,QAAQ,OAAO,CAAC;EAC5B;EACA;EACA;CACF,IACA;EAAC;EAAS;EAAM;CAAU,CAC5B;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,CAAC,QAAQ,QAAQ,CAAC,cAAc,gBAAgB,WAAW;EAC/D,eAAe,OAAO;CACxB;CAQA,MAAM,YAAY,iBAChB,oBAAC,KAAD;EACE,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,OAAO,EAAE;EACxD,SAAQ;EACR,gBAAe;EACf,OAAM;EAEL,UAAA;CACE,CAAA;CAGP,MAAM,cACJ,
|
|
1
|
+
{"version":3,"file":"BitkitStepsDialog.js","names":["BitkitSteps"],"sources":["../../../lib/components/BitkitDialog/BitkitStepsDialog.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactElement, type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { type BitkitDataAttributes } from '../../utilities/dataAttributes';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitSteps from '../BitkitSteps/BitkitSteps';\nimport BitkitStepsDialogStep, { type BitkitStepsDialogStepProps } from './BitkitStepsDialogStep';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogShellProps } from './DialogShell';\nimport { StepsDialogProvider } from './StepsDialogContext';\n\nexport { useStepsDialog } from './StepsDialogContext';\n\nexport type BitkitStepsDialogProps = {\n /** `BitkitStepsDialog.Step` children, one per step. */\n children: ReactNode;\n /** Initial step when uncontrolled. Resets to this when the dialog closes. */\n defaultStep?: number;\n /** Set to `false` to remove every dismiss route that skips a decision: no close button, no ESC. */\n dismissible?: boolean;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n /**\n * The step navigation, built with `useStepsDialog()`. Pass the buttons themselves: the dialog lays\n * them out the way the design asks for, leading action on the left, the step navigation opposite.\n * A footer with no leading action passes a single group, which stays on the right.\n */\n footerButtons?: ReactNode;\n /** Arbitrary content rendered raw inside the footer, above `footerButtons` (e.g. a `BitkitAlert`). */\n footerContent?: ReactNode;\n headerLabel?: string;\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n /** Called whenever the active step changes (controlled or uncontrolled). */\n onStepChange?: (step: number) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n /**\n * `loading` locks the dialog while a background action runs: the close button stays in place but\n * disabled, and ESC is blocked. Use it alongside the footer button's own `state=\"loading\"`.\n */\n state?: 'loading';\n /** Controlled active step. Omit for uncontrolled (see `defaultStep`). */\n step?: number;\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n // Data attributes are forwarded to the element carrying `role=\"dialog\"`, and nothing else is —\n // style props, `className` and `id` don't pass through.\n} & BitkitDataAttributes;\n\n/**\n * A dialog that walks through a sequence of `BitkitStepsDialog.Step` children. It owns the step\n * state, auto-renders the steps header, and shows only the active step's body. The consumer builds\n * the step navigation with the `useStepsDialog()` hook and passes it in as `footerButtons`.\n */\nconst BitkitStepsDialog = ({\n children,\n defaultStep = 0,\n dismissible = true,\n initialFocusEl,\n footerButtons,\n footerContent,\n headerLabel,\n maxHeight,\n onExitComplete,\n onOpenChange,\n onStepChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n state,\n step: stepProp,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitStepsDialogProps) => {\n const [internalStep, setInternalStep] = useState(defaultStep);\n const isControlled = stepProp !== undefined;\n const rawStep = (isControlled ? stepProp : internalStep) ?? 0;\n const steps = flattenChildren(children).filter(\n (child): child is ReactElement<BitkitStepsDialogStepProps> => child.type === BitkitStepsDialogStep,\n );\n const totalSteps = steps.length;\n const step = Math.max(0, Math.min(rawStep, Math.max(0, totalSteps - 1)));\n\n const setStep = useCallback(\n (next: number) => {\n const clamped = Math.max(0, Math.min(next, totalSteps - 1));\n if (!isControlled) setInternalStep(clamped);\n onStepChange?.(clamped);\n },\n [isControlled, onStepChange, totalSteps],\n );\n\n const ctx = useMemo(\n () => ({\n goTo: setStep,\n isFirst: step === 0,\n isLast: step === totalSteps - 1,\n next: () => setStep(step + 1),\n prev: () => setStep(step - 1),\n setStep,\n step,\n totalSteps,\n }),\n [setStep, step, totalSteps],\n );\n\n const handleOpenChange = (details: { open: boolean }) => {\n if (!details.open && !isControlled) setInternalStep(defaultStep);\n onOpenChange?.(details);\n };\n\n // The design splits this row: the leading action sits opposite the step navigation. Laying it out\n // here rather than in `DialogInner` keeps the shared action block right-aligned for every other\n // dialog, and keeps the split off every call site. A footer with no leading action passes a single\n // group, which `space-between` would park at the start, so that case is pushed back to the end. It\n // has to be a selector rather than a prop: `footerButtons` is one element rendering a fragment, so\n // the component cannot count what it will produce.\n const footerNav = footerButtons && (\n <Box\n css={{ '& > :only-child': { marginInlineStart: 'auto' } }}\n display=\"flex\"\n justifyContent=\"space-between\"\n width=\"100%\"\n >\n {footerButtons}\n </Box>\n );\n\n const stepsHeader = (\n <BitkitSteps step={step}>\n {steps.map((child, index) => (\n <BitkitSteps.Item key={index} label={child.props.label} />\n ))}\n </BitkitSteps>\n );\n\n return (\n <StepsDialogProvider value={ctx}>\n <DialogShell\n dismissible={dismissible}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n state={state}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content aria-busy={state === 'loading' || undefined} maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n dismissible={dismissible}\n footerButtons={footerNav}\n footerContent={footerContent}\n headerExtra={stepsHeader}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n state={state}\n title={title}\n variant={variant}\n >\n {steps[step]}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n </StepsDialogProvider>\n );\n};\n\nBitkitStepsDialog.displayName = 'BitkitStepsDialog';\n\nexport default withSubComponents(BitkitStepsDialog, {\n ActionTrigger: Dialog.ActionTrigger,\n Step: BitkitStepsDialogStep,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;AA8DA,IAAM,qBAAqB,EACzB,UACA,cAAc,GACd,cAAc,MACd,gBACA,eACA,eACA,aACA,WACA,gBACA,cACA,cACA,MACA,eACA,gBACA,oBACA,MACA,OACA,MAAM,UACN,OACA,SACA,SACA,GAAG,qBACyB;CAC5B,MAAM,CAAC,cAAc,mBAAmB,SAAS,WAAW;CAC5D,MAAM,eAAe,aAAa,KAAA;CAClC,MAAM,WAAW,eAAe,WAAW,iBAAiB;CAC5D,MAAM,QAAQ,gBAAgB,QAAQ,CAAC,CAAC,QACrC,UAA6D,MAAM,SAAS,qBAC/E;CACA,MAAM,aAAa,MAAM;CACzB,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;CAEvE,MAAM,UAAU,aACb,SAAiB;EAChB,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,CAAC,CAAC;EAC1D,IAAI,CAAC,cAAc,gBAAgB,OAAO;EAC1C,eAAe,OAAO;CACxB,GACA;EAAC;EAAc;EAAc;CAAU,CACzC;CAEA,MAAM,MAAM,eACH;EACL,MAAM;EACN,SAAS,SAAS;EAClB,QAAQ,SAAS,aAAa;EAC9B,YAAY,QAAQ,OAAO,CAAC;EAC5B,YAAY,QAAQ,OAAO,CAAC;EAC5B;EACA;EACA;CACF,IACA;EAAC;EAAS;EAAM;CAAU,CAC5B;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,CAAC,QAAQ,QAAQ,CAAC,cAAc,gBAAgB,WAAW;EAC/D,eAAe,OAAO;CACxB;CAQA,MAAM,YAAY,iBAChB,oBAAC,KAAD;EACE,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,OAAO,EAAE;EACxD,SAAQ;EACR,gBAAe;EACf,OAAM;EAEL,UAAA;CACE,CAAA;CAGP,MAAM,cACJ,oBAACA,qBAAD;EAAmB;EAChB,UAAA,MAAM,KAAK,OAAO,UACjB,oBAACA,oBAAY,MAAb,EAA8B,OAAO,MAAM,MAAM,MAAQ,GAAlC,KAAkC,CAC1D;CACU,CAAA;CAGf,OACE,oBAAC,qBAAD;EAAqB,OAAO;EAC1B,UAAA,oBAAC,aAAD;GACe;GACG;GACA;GAChB,cAAc;GACR;GACS;GACC;GACV;GACC;GACE;GACA;GAET,UAAA,oBAAC,OAAO,SAAR;IAAgB,aAAW,UAAU,aAAa,KAAA;IAAsB;IAAW,GAAI;IACrF,UAAA,oBAAC,aAAD;KACe;KACb,eAAe;KACA;KACf,aAAa;KACA;KACG;KACI;KACb;KACA;KACE;KAER,UAAA,MAAM;IACI,CAAA;GACC,CAAA;EACL,CAAA;CACM,CAAA;AAEzB;AAEA,kBAAkB,cAAc;AAEhC,IAAA,4BAAe,kBAAkB,mBAAmB;CAClD,eAAe,OAAO;CACtB,MAAM;AACR,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitStepsDialogStep.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitStepsDialogStep.tsx"],"sourcesContent":["import { useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { type ReactNode } from 'react';\n\nexport interface BitkitStepsDialogStepProps {\n /** Body content for this step. */\n children?: ReactNode;\n /** Optional subtitle shown under the step's body title. */\n description?: string;\n /** Short label shown in the steps header. */\n label: string;\n /** Heading shown at the top of the step's body. */\n title: string;\n}\n\n/**\n * A single step of a {@link BitkitStepsDialog}. Renders its `title`/`description` typography\n * followed by `children`. The parent only mounts the active step, so this never self-gates.\n */\nconst BitkitStepsDialogStep = ({ children, description, title }: BitkitStepsDialogStepProps) => {\n const styles = useDialogStyles();\n\n return (\n <>\n <chakra.div css={styles.stepTitleGroup}>\n <chakra.p css={styles.stepTitle}>{title}</chakra.p>\n {description && <chakra.p css={styles.stepDescription}>{description}</chakra.p>}\n </chakra.div>\n {children}\n </>\n );\n};\n\nBitkitStepsDialogStep.displayName = 'BitkitStepsDialogStep';\n\nexport default BitkitStepsDialogStep;\n"],"mappings":";;;;;;;;AAmBA,IAAM,yBAAyB,EAAE,UAAU,aAAa,YAAwC;CAC9F,MAAM,SAAS,gBAAgB;CAE/B,OACE,
|
|
1
|
+
{"version":3,"file":"BitkitStepsDialogStep.js","names":["_Fragment"],"sources":["../../../lib/components/BitkitDialog/BitkitStepsDialogStep.tsx"],"sourcesContent":["import { useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { type ReactNode } from 'react';\n\nexport interface BitkitStepsDialogStepProps {\n /** Body content for this step. */\n children?: ReactNode;\n /** Optional subtitle shown under the step's body title. */\n description?: string;\n /** Short label shown in the steps header. */\n label: string;\n /** Heading shown at the top of the step's body. */\n title: string;\n}\n\n/**\n * A single step of a {@link BitkitStepsDialog}. Renders its `title`/`description` typography\n * followed by `children`. The parent only mounts the active step, so this never self-gates.\n */\nconst BitkitStepsDialogStep = ({ children, description, title }: BitkitStepsDialogStepProps) => {\n const styles = useDialogStyles();\n\n return (\n <>\n <chakra.div css={styles.stepTitleGroup}>\n <chakra.p css={styles.stepTitle}>{title}</chakra.p>\n {description && <chakra.p css={styles.stepDescription}>{description}</chakra.p>}\n </chakra.div>\n {children}\n </>\n );\n};\n\nBitkitStepsDialogStep.displayName = 'BitkitStepsDialogStep';\n\nexport default BitkitStepsDialogStep;\n"],"mappings":";;;;;;;;AAmBA,IAAM,yBAAyB,EAAE,UAAU,aAAa,YAAwC;CAC9F,MAAM,SAAS,gBAAgB;CAE/B,OACE,qBAAAA,UAAA,EAAA,UAAA,CACE,qBAAC,OAAO,KAAR;EAAY,KAAK,OAAO;EAAxB,UAAA,CACE,oBAAC,OAAO,GAAR;GAAU,KAAK,OAAO;GAAY,UAAA;EAAgB,CAAA,GACjD,eAAe,oBAAC,OAAO,GAAR;GAAU,KAAK,OAAO;GAAkB,UAAA;EAAsB,CAAA,CACpE;CACX,CAAA,GAAA,QACD,EAAA,CAAA;AAEN;AAEA,sBAAsB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogBodyContext.js","names":[],"sources":["../../../lib/components/BitkitDialog/DialogBodyContext.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog, useDialogContext, useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';\n\nimport { IconArrowDown } from '../../icons';\n\ninterface DialogBodyContextValue {\n scrollBehavior: 'inside' | 'outside';\n showScrollGradient: boolean;\n}\n\nexport const DialogBodyContext = createContext<DialogBodyContextValue>({\n scrollBehavior: 'outside',\n showScrollGradient: true,\n});\n\nexport const resolveScrollBehavior = (\n variant: 'overflowContent' | undefined,\n scrollBehavior: 'inside' | 'outside' | undefined,\n): 'inside' | 'outside' | undefined => (variant === 'overflowContent' ? 'inside' : scrollBehavior);\n\nconst ScrollableDialogBody = ({ children, ...props }: Dialog.BodyProps) => {\n const { showScrollGradient } = useContext(DialogBodyContext);\n const styles = useDialogStyles();\n const { open } = useDialogContext();\n const contentRef = useRef<HTMLDivElement>(null);\n const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false);\n\n const updateScrollButtonVisibility = useCallback(() => {\n const content = contentRef.current;\n if (!content) {\n setIsScrollButtonVisible(false);\n return;\n }\n const didScrollToBottom = content.scrollTop >= content.scrollHeight - content.offsetHeight - 1;\n setIsScrollButtonVisible(!didScrollToBottom);\n }, []);\n\n useEffect(() => {\n const content = contentRef.current;\n if (!open || !content) return;\n\n content.addEventListener('scroll', updateScrollButtonVisibility);\n const resizeObserver = new ResizeObserver(updateScrollButtonVisibility);\n resizeObserver.observe(content);\n\n return () => {\n content.removeEventListener('scroll', updateScrollButtonVisibility);\n resizeObserver.disconnect();\n };\n }, [open, updateScrollButtonVisibility]);\n\n return (\n <Box css={styles.scrollBody}>\n <Box css={styles.scrollArea}>\n <Dialog.Body ref={contentRef} {...props}>\n {children}\n </Dialog.Body>\n {isScrollButtonVisible && (\n <>\n {showScrollGradient && <Box css={styles.scrollGradient} />}\n <chakra.button\n aria-label=\"Scroll to bottom\"\n css={styles.scrollButton}\n type=\"button\"\n onClick={() => {\n contentRef.current?.scrollTo({ top: contentRef.current.scrollHeight, behavior: 'smooth' });\n }}\n >\n <IconArrowDown color=\"icon/tertiary\" size=\"16\" />\n </chakra.button>\n </>\n )}\n </Box>\n </Box>\n );\n};\n\n/**\n * Scroll-aware dialog body. Reads {@link DialogBodyContext} to decide whether the body scrolls\n * internally (`inside` → scroll button + optional gradient) or the whole dialog scrolls (`outside`).\n */\nconst DialogBody = ({ children, ...rest }: Dialog.BodyProps) => {\n const { scrollBehavior } = useContext(DialogBodyContext);\n\n if (scrollBehavior === 'inside') {\n return <ScrollableDialogBody {...rest}>{children}</ScrollableDialogBody>;\n }\n return <Dialog.Body {...rest}>{children}</Dialog.Body>;\n};\n\nexport default DialogBody;\n"],"mappings":";;;;;;;AAYA,IAAa,oBAAoB,cAAsC;CACrE,gBAAgB;CAChB,oBAAoB;AACtB,CAAC;AAED,IAAa,yBACX,SACA,mBACsC,YAAY,oBAAoB,WAAW;AAEnF,IAAM,wBAAwB,EAAE,UAAU,GAAG,YAA8B;CACzE,MAAM,EAAE,uBAAuB,WAAW,iBAAiB;CAC3D,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,iBAAiB;CAClC,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,CAAC,uBAAuB,4BAA4B,SAAS,KAAK;CAExE,MAAM,+BAA+B,kBAAkB;EACrD,MAAM,UAAU,WAAW;EAC3B,IAAI,CAAC,SAAS;GACZ,yBAAyB,KAAK;GAC9B;EACF;EACA,MAAM,oBAAoB,QAAQ,aAAa,QAAQ,eAAe,QAAQ,eAAe;EAC7F,yBAAyB,CAAC,iBAAiB;CAC7C,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,UAAU,WAAW;EAC3B,IAAI,CAAC,QAAQ,CAAC,SAAS;EAEvB,QAAQ,iBAAiB,UAAU,4BAA4B;EAC/D,MAAM,iBAAiB,IAAI,eAAe,4BAA4B;EACtE,eAAe,QAAQ,OAAO;EAE9B,aAAa;GACX,QAAQ,oBAAoB,UAAU,4BAA4B;GAClE,eAAe,WAAW;EAC5B;CACF,GAAG,CAAC,MAAM,4BAA4B,CAAC;CAEvC,OACE,oBAAC,KAAD;EAAK,KAAK,OAAO;EACf,UAAA,qBAAC,KAAD;GAAK,KAAK,OAAO;GAAjB,UAAA,CACE,oBAAC,OAAO,MAAR;IAAa,KAAK;IAAY,GAAI;IAC/B;GACU,CAAA,GACZ,yBACC,
|
|
1
|
+
{"version":3,"file":"DialogBodyContext.js","names":["_Fragment"],"sources":["../../../lib/components/BitkitDialog/DialogBodyContext.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog, useDialogContext, useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';\n\nimport { IconArrowDown } from '../../icons';\n\ninterface DialogBodyContextValue {\n scrollBehavior: 'inside' | 'outside';\n showScrollGradient: boolean;\n}\n\nexport const DialogBodyContext = createContext<DialogBodyContextValue>({\n scrollBehavior: 'outside',\n showScrollGradient: true,\n});\n\nexport const resolveScrollBehavior = (\n variant: 'overflowContent' | undefined,\n scrollBehavior: 'inside' | 'outside' | undefined,\n): 'inside' | 'outside' | undefined => (variant === 'overflowContent' ? 'inside' : scrollBehavior);\n\nconst ScrollableDialogBody = ({ children, ...props }: Dialog.BodyProps) => {\n const { showScrollGradient } = useContext(DialogBodyContext);\n const styles = useDialogStyles();\n const { open } = useDialogContext();\n const contentRef = useRef<HTMLDivElement>(null);\n const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false);\n\n const updateScrollButtonVisibility = useCallback(() => {\n const content = contentRef.current;\n if (!content) {\n setIsScrollButtonVisible(false);\n return;\n }\n const didScrollToBottom = content.scrollTop >= content.scrollHeight - content.offsetHeight - 1;\n setIsScrollButtonVisible(!didScrollToBottom);\n }, []);\n\n useEffect(() => {\n const content = contentRef.current;\n if (!open || !content) return;\n\n content.addEventListener('scroll', updateScrollButtonVisibility);\n const resizeObserver = new ResizeObserver(updateScrollButtonVisibility);\n resizeObserver.observe(content);\n\n return () => {\n content.removeEventListener('scroll', updateScrollButtonVisibility);\n resizeObserver.disconnect();\n };\n }, [open, updateScrollButtonVisibility]);\n\n return (\n <Box css={styles.scrollBody}>\n <Box css={styles.scrollArea}>\n <Dialog.Body ref={contentRef} {...props}>\n {children}\n </Dialog.Body>\n {isScrollButtonVisible && (\n <>\n {showScrollGradient && <Box css={styles.scrollGradient} />}\n <chakra.button\n aria-label=\"Scroll to bottom\"\n css={styles.scrollButton}\n type=\"button\"\n onClick={() => {\n contentRef.current?.scrollTo({ top: contentRef.current.scrollHeight, behavior: 'smooth' });\n }}\n >\n <IconArrowDown color=\"icon/tertiary\" size=\"16\" />\n </chakra.button>\n </>\n )}\n </Box>\n </Box>\n );\n};\n\n/**\n * Scroll-aware dialog body. Reads {@link DialogBodyContext} to decide whether the body scrolls\n * internally (`inside` → scroll button + optional gradient) or the whole dialog scrolls (`outside`).\n */\nconst DialogBody = ({ children, ...rest }: Dialog.BodyProps) => {\n const { scrollBehavior } = useContext(DialogBodyContext);\n\n if (scrollBehavior === 'inside') {\n return <ScrollableDialogBody {...rest}>{children}</ScrollableDialogBody>;\n }\n return <Dialog.Body {...rest}>{children}</Dialog.Body>;\n};\n\nexport default DialogBody;\n"],"mappings":";;;;;;;AAYA,IAAa,oBAAoB,cAAsC;CACrE,gBAAgB;CAChB,oBAAoB;AACtB,CAAC;AAED,IAAa,yBACX,SACA,mBACsC,YAAY,oBAAoB,WAAW;AAEnF,IAAM,wBAAwB,EAAE,UAAU,GAAG,YAA8B;CACzE,MAAM,EAAE,uBAAuB,WAAW,iBAAiB;CAC3D,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,iBAAiB;CAClC,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,CAAC,uBAAuB,4BAA4B,SAAS,KAAK;CAExE,MAAM,+BAA+B,kBAAkB;EACrD,MAAM,UAAU,WAAW;EAC3B,IAAI,CAAC,SAAS;GACZ,yBAAyB,KAAK;GAC9B;EACF;EACA,MAAM,oBAAoB,QAAQ,aAAa,QAAQ,eAAe,QAAQ,eAAe;EAC7F,yBAAyB,CAAC,iBAAiB;CAC7C,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,UAAU,WAAW;EAC3B,IAAI,CAAC,QAAQ,CAAC,SAAS;EAEvB,QAAQ,iBAAiB,UAAU,4BAA4B;EAC/D,MAAM,iBAAiB,IAAI,eAAe,4BAA4B;EACtE,eAAe,QAAQ,OAAO;EAE9B,aAAa;GACX,QAAQ,oBAAoB,UAAU,4BAA4B;GAClE,eAAe,WAAW;EAC5B;CACF,GAAG,CAAC,MAAM,4BAA4B,CAAC;CAEvC,OACE,oBAAC,KAAD;EAAK,KAAK,OAAO;EACf,UAAA,qBAAC,KAAD;GAAK,KAAK,OAAO;GAAjB,UAAA,CACE,oBAAC,OAAO,MAAR;IAAa,KAAK;IAAY,GAAI;IAC/B;GACU,CAAA,GACZ,yBACC,qBAAAA,YAAA,EAAA,UAAA,CACG,sBAAsB,oBAAC,KAAD,EAAK,KAAK,OAAO,eAAiB,CAAA,GACzD,oBAAC,OAAO,QAAR;IACE,cAAW;IACX,KAAK,OAAO;IACZ,MAAK;IACL,eAAe;KACb,WAAW,SAAS,SAAS;MAAE,KAAK,WAAW,QAAQ;MAAc,UAAU;KAAS,CAAC;IAC3F;IAEA,UAAA,oBAAC,eAAD;KAAe,OAAM;KAAgB,MAAK;IAAM,CAAA;GACnC,CAAA,CACf,EAAA,CAAA,CAED;;CACF,CAAA;AAET;;;;;AAMA,IAAM,cAAc,EAAE,UAAU,GAAG,WAA6B;CAC9D,MAAM,EAAE,mBAAmB,WAAW,iBAAiB;CAEvD,IAAI,mBAAmB,UACrB,OAAO,oBAAC,sBAAD;EAAsB,GAAI;EAAO;CAA+B,CAAA;CAEzE,OAAO,oBAAC,OAAO,MAAR;EAAa,GAAI;EAAO;CAAsB,CAAA;AACvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitExpandableCard.js","names":[],"sources":["../../../lib/components/BitkitExpandableCard/BitkitExpandableCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Card } from '@chakra-ui/react/card';\nimport { Collapsible, type CollapsibleRootProps } from '@chakra-ui/react/collapsible';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { cloneElement, forwardRef, isValidElement, type ReactElement, type ReactNode } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport { type BitkitAvatarProps } from '../BitkitAvatar/BitkitAvatar';\nimport BitkitBadge, { type BitkitBadgeProps } from '../BitkitBadge/BitkitBadge';\n\ntype UncontrolledProps = {\n defaultExpanded?: boolean;\n expanded?: never;\n onChange?: never;\n};\n\ntype ControlledProps = {\n defaultExpanded?: never;\n expanded: boolean;\n onChange: (expanded: boolean) => void;\n};\n\n/**\n * Zag/Ark machine props. They drive the inner `Collapsible.Root` and mean nothing on the card\n * element, so they're forwarded by name rather than left in `...rest` — which belongs to the\n * rendered root (`Card.Root`) so consumer style props reach the card itself.\n */\ntype CollapsibleMachineProps = Pick<\n CollapsibleRootProps,\n | 'collapsedHeight'\n | 'collapsedWidth'\n | 'disabled'\n | 'hideMode'\n | 'ids'\n | 'lazyMount'\n | 'onExitComplete'\n | 'unmountOnExit'\n>;\n\nexport type BitkitExpandableCardProps = Omit<BoxProps, 'asChild' | 'children' | 'onChange' | 'title'> &\n CollapsibleMachineProps & {\n children: ReactNode;\n elevation?: boolean;\n footer?: ReactNode;\n icon?: BitkitIconComponent | ReactElement<BitkitAvatarProps>;\n iconColor?: string;\n noPadding?: boolean;\n size?: 'md' | 'lg';\n subtitle?: ReactNode;\n suffix?: ReactNode;\n title: ReactNode;\n } & (UncontrolledProps | ControlledProps);\n\nconst BitkitExpandableCard = forwardRef<HTMLDivElement, BitkitExpandableCardProps>((props, ref) => {\n const {\n children,\n collapsedHeight,\n collapsedWidth,\n css,\n defaultExpanded,\n disabled,\n elevation = true,\n expanded,\n footer,\n hideMode,\n icon,\n iconColor,\n ids,\n lazyMount,\n noPadding = false,\n onChange,\n onExitComplete,\n size = 'lg',\n subtitle,\n suffix,\n title,\n unmountOnExit,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'expandableCard' });\n const styles = recipe({ noPadding, size });\n\n const handleOpenChange = onChange ? (details: { open: boolean }) => onChange(details.open) : undefined;\n\n // `md` is the tested branch so the default size ('lg') stays on the fallback.\n const iconSize = size === 'md' ? '16' : '24';\n\n // Figma sizes the header badge with the card: xs on md, sm (the badge default) on lg.\n let renderedSuffix: ReactNode = suffix;\n if (isValidElement<BitkitBadgeProps>(suffix) && suffix.type === BitkitBadge) {\n renderedSuffix = cloneElement(suffix, { size: size === 'md' ? 'xs' : 'sm' });\n }\n\n let renderedIcon: ReactNode = null;\n if (isValidElement<BitkitAvatarProps>(icon)) {\n // BitkitAvatar has no '16' size, so avatars stay at '24' even on the md card.\n renderedIcon = cloneElement(icon, { size: '24' });\n } else if (icon) {\n const Icon = icon;\n renderedIcon = <Icon color={iconColor} size={iconSize} />;\n }\n\n return (\n <Card.Root ref={ref} elevation={elevation} paddingSize=\"sm\" css={[styles.root, css]} {...rest}>\n <Collapsible.Root\n collapsedHeight={collapsedHeight}\n collapsedWidth={collapsedWidth}\n defaultOpen={defaultExpanded}\n disabled={disabled}\n hideMode={hideMode}\n ids={ids}\n lazyMount={lazyMount}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={expanded}\n unmountOnExit={unmountOnExit}\n >\n <Collapsible.Trigger css={styles.header}>\n <Box display=\"flex\" alignItems=\"center\" flex=\"1\" gap=\"8\" minWidth=\"0\">\n {!!renderedIcon && <Box css={styles.icon}>{renderedIcon}</Box>}\n <Box css={styles.title}>\n {title}\n {!!subtitle && (\n <Text as=\"span\" css={styles.subtitle}>\n {subtitle}\n </Text>\n )}\n </Box>\n </Box>\n <Box display=\"flex\" alignItems=\"center\" flexShrink=\"0\">\n {!!renderedSuffix && (\n <Text as=\"span\" css={styles.suffix}>\n {renderedSuffix}\n </Text>\n )}\n <Collapsible.Indicator asChild>\n <AssetSelectChevron />\n </Collapsible.Indicator>\n </Box>\n </Collapsible.Trigger>\n <Collapsible.Content css={styles.collapsible}>\n <Card.Body css={styles.body}>{children}</Card.Body>\n {!!footer && <Card.Footer css={styles.footer}>{footer}</Card.Footer>}\n </Collapsible.Content>\n </Collapsible.Root>\n </Card.Root>\n );\n});\n\nBitkitExpandableCard.displayName = 'BitkitExpandableCard';\n\nexport default BitkitExpandableCard;\n"],"mappings":";;;;;;;;;;AAuDA,IAAM,uBAAuB,YAAuD,OAAO,QAAQ;CACjG,MAAM,EACJ,UACA,iBACA,gBACA,KACA,iBACA,UACA,YAAY,MACZ,UACA,QACA,UACA,MACA,WACA,KACA,WACA,YAAY,OACZ,UACA,gBACA,OAAO,MACP,UACA,QACA,OACA,eACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,iBAAiB,CACtC,CAAA,CAAO;EAAE;EAAW;CAAK,CAAC;CAEzC,MAAM,mBAAmB,YAAY,YAA+B,SAAS,QAAQ,IAAI,IAAI,KAAA;CAG7F,MAAM,WAAW,SAAS,OAAO,OAAO;CAGxC,IAAI,iBAA4B;CAChC,IAAI,eAAiC,MAAM,KAAK,OAAO,SAAS,aAC9D,iBAAiB,aAAa,QAAQ,EAAE,MAAM,SAAS,OAAO,OAAO,KAAK,CAAC;CAG7E,IAAI,eAA0B;CAC9B,IAAI,eAAkC,IAAI,GAExC,eAAe,aAAa,MAAM,EAAE,MAAM,KAAK,CAAC;MAC3C,IAAI,MAET,eAAe,
|
|
1
|
+
{"version":3,"file":"BitkitExpandableCard.js","names":["Icon"],"sources":["../../../lib/components/BitkitExpandableCard/BitkitExpandableCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Card } from '@chakra-ui/react/card';\nimport { Collapsible, type CollapsibleRootProps } from '@chakra-ui/react/collapsible';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { cloneElement, forwardRef, isValidElement, type ReactElement, type ReactNode } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport { type BitkitAvatarProps } from '../BitkitAvatar/BitkitAvatar';\nimport BitkitBadge, { type BitkitBadgeProps } from '../BitkitBadge/BitkitBadge';\n\ntype UncontrolledProps = {\n defaultExpanded?: boolean;\n expanded?: never;\n onChange?: never;\n};\n\ntype ControlledProps = {\n defaultExpanded?: never;\n expanded: boolean;\n onChange: (expanded: boolean) => void;\n};\n\n/**\n * Zag/Ark machine props. They drive the inner `Collapsible.Root` and mean nothing on the card\n * element, so they're forwarded by name rather than left in `...rest` — which belongs to the\n * rendered root (`Card.Root`) so consumer style props reach the card itself.\n */\ntype CollapsibleMachineProps = Pick<\n CollapsibleRootProps,\n | 'collapsedHeight'\n | 'collapsedWidth'\n | 'disabled'\n | 'hideMode'\n | 'ids'\n | 'lazyMount'\n | 'onExitComplete'\n | 'unmountOnExit'\n>;\n\nexport type BitkitExpandableCardProps = Omit<BoxProps, 'asChild' | 'children' | 'onChange' | 'title'> &\n CollapsibleMachineProps & {\n children: ReactNode;\n elevation?: boolean;\n footer?: ReactNode;\n icon?: BitkitIconComponent | ReactElement<BitkitAvatarProps>;\n iconColor?: string;\n noPadding?: boolean;\n size?: 'md' | 'lg';\n subtitle?: ReactNode;\n suffix?: ReactNode;\n title: ReactNode;\n } & (UncontrolledProps | ControlledProps);\n\nconst BitkitExpandableCard = forwardRef<HTMLDivElement, BitkitExpandableCardProps>((props, ref) => {\n const {\n children,\n collapsedHeight,\n collapsedWidth,\n css,\n defaultExpanded,\n disabled,\n elevation = true,\n expanded,\n footer,\n hideMode,\n icon,\n iconColor,\n ids,\n lazyMount,\n noPadding = false,\n onChange,\n onExitComplete,\n size = 'lg',\n subtitle,\n suffix,\n title,\n unmountOnExit,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'expandableCard' });\n const styles = recipe({ noPadding, size });\n\n const handleOpenChange = onChange ? (details: { open: boolean }) => onChange(details.open) : undefined;\n\n // `md` is the tested branch so the default size ('lg') stays on the fallback.\n const iconSize = size === 'md' ? '16' : '24';\n\n // Figma sizes the header badge with the card: xs on md, sm (the badge default) on lg.\n let renderedSuffix: ReactNode = suffix;\n if (isValidElement<BitkitBadgeProps>(suffix) && suffix.type === BitkitBadge) {\n renderedSuffix = cloneElement(suffix, { size: size === 'md' ? 'xs' : 'sm' });\n }\n\n let renderedIcon: ReactNode = null;\n if (isValidElement<BitkitAvatarProps>(icon)) {\n // BitkitAvatar has no '16' size, so avatars stay at '24' even on the md card.\n renderedIcon = cloneElement(icon, { size: '24' });\n } else if (icon) {\n const Icon = icon;\n renderedIcon = <Icon color={iconColor} size={iconSize} />;\n }\n\n return (\n <Card.Root ref={ref} elevation={elevation} paddingSize=\"sm\" css={[styles.root, css]} {...rest}>\n <Collapsible.Root\n collapsedHeight={collapsedHeight}\n collapsedWidth={collapsedWidth}\n defaultOpen={defaultExpanded}\n disabled={disabled}\n hideMode={hideMode}\n ids={ids}\n lazyMount={lazyMount}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={expanded}\n unmountOnExit={unmountOnExit}\n >\n <Collapsible.Trigger css={styles.header}>\n <Box display=\"flex\" alignItems=\"center\" flex=\"1\" gap=\"8\" minWidth=\"0\">\n {!!renderedIcon && <Box css={styles.icon}>{renderedIcon}</Box>}\n <Box css={styles.title}>\n {title}\n {!!subtitle && (\n <Text as=\"span\" css={styles.subtitle}>\n {subtitle}\n </Text>\n )}\n </Box>\n </Box>\n <Box display=\"flex\" alignItems=\"center\" flexShrink=\"0\">\n {!!renderedSuffix && (\n <Text as=\"span\" css={styles.suffix}>\n {renderedSuffix}\n </Text>\n )}\n <Collapsible.Indicator asChild>\n <AssetSelectChevron />\n </Collapsible.Indicator>\n </Box>\n </Collapsible.Trigger>\n <Collapsible.Content css={styles.collapsible}>\n <Card.Body css={styles.body}>{children}</Card.Body>\n {!!footer && <Card.Footer css={styles.footer}>{footer}</Card.Footer>}\n </Collapsible.Content>\n </Collapsible.Root>\n </Card.Root>\n );\n});\n\nBitkitExpandableCard.displayName = 'BitkitExpandableCard';\n\nexport default BitkitExpandableCard;\n"],"mappings":";;;;;;;;;;AAuDA,IAAM,uBAAuB,YAAuD,OAAO,QAAQ;CACjG,MAAM,EACJ,UACA,iBACA,gBACA,KACA,iBACA,UACA,YAAY,MACZ,UACA,QACA,UACA,MACA,WACA,KACA,WACA,YAAY,OACZ,UACA,gBACA,OAAO,MACP,UACA,QACA,OACA,eACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,iBAAiB,CACtC,CAAA,CAAO;EAAE;EAAW;CAAK,CAAC;CAEzC,MAAM,mBAAmB,YAAY,YAA+B,SAAS,QAAQ,IAAI,IAAI,KAAA;CAG7F,MAAM,WAAW,SAAS,OAAO,OAAO;CAGxC,IAAI,iBAA4B;CAChC,IAAI,eAAiC,MAAM,KAAK,OAAO,SAAS,aAC9D,iBAAiB,aAAa,QAAQ,EAAE,MAAM,SAAS,OAAO,OAAO,KAAK,CAAC;CAG7E,IAAI,eAA0B;CAC9B,IAAI,eAAkC,IAAI,GAExC,eAAe,aAAa,MAAM,EAAE,MAAM,KAAK,CAAC;MAC3C,IAAI,MAET,eAAe,oBAACA,MAAD;EAAM,OAAO;EAAW,MAAM;CAAW,CAAA;CAG1D,OACE,oBAAC,KAAK,MAAN;EAAgB;EAAgB;EAAW,aAAY;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,GAAI;EACvF,UAAA,qBAAC,YAAY,MAAb;GACmB;GACD;GAChB,aAAa;GACH;GACA;GACL;GACM;GACK;GAChB,cAAc;GACd,MAAM;GACS;GAXjB,UAAA,CAaE,qBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAAjC,UAAA,CACE,qBAAC,KAAD;KAAK,SAAQ;KAAO,YAAW;KAAS,MAAK;KAAI,KAAI;KAAI,UAAS;KAAlE,UAAA,CACG,CAAC,CAAC,gBAAgB,oBAAC,KAAD;MAAK,KAAK,OAAO;MAAO,UAAA;KAAkB,CAAA,GAC7D,qBAAC,KAAD;MAAK,KAAK,OAAO;MAAjB,UAAA,CACG,OACA,CAAC,CAAC,YACD,oBAAC,MAAD;OAAM,IAAG;OAAO,KAAK,OAAO;OACzB,UAAA;MACG,CAAA,CAEL;KACF,CAAA,CAAA;IACL,CAAA,GAAA,qBAAC,KAAD;KAAK,SAAQ;KAAO,YAAW;KAAS,YAAW;KAAnD,UAAA,CACG,CAAC,CAAC,kBACD,oBAAC,MAAD;MAAM,IAAG;MAAO,KAAK,OAAO;MACzB,UAAA;KACG,CAAA,GAER,oBAAC,YAAY,WAAb;MAAuB,SAAA;MACrB,UAAA,oBAAC,oBAAD,CAAqB,CAAA;KACA,CAAA,CACpB;IACc,CAAA,CAAA;GACrB,CAAA,GAAA,qBAAC,YAAY,SAAb;IAAqB,KAAK,OAAO;IAAjC,UAAA,CACE,oBAAC,KAAK,MAAN;KAAW,KAAK,OAAO;KAAO;IAAoB,CAAA,GACjD,CAAC,CAAC,UAAU,oBAAC,KAAK,QAAN;KAAa,KAAK,OAAO;KAAS,UAAA;IAAoB,CAAA,CAChD;GACL,CAAA,CAAA;;CACT,CAAA;AAEf,CAAC;AAED,qBAAqB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitFileInput.js","names":[],"sources":["../../../lib/components/BitkitFileInput/BitkitFileInput.tsx"],"sourcesContent":["import { Card } from '@chakra-ui/react/card';\nimport { useFieldContext } from '@chakra-ui/react/field';\nimport {\n FileUpload,\n type FileUploadFileAcceptDetails,\n type FileUploadRootProps,\n useFileUploadContext,\n} from '@chakra-ui/react/file-upload';\nimport { VStack } from '@chakra-ui/react/stack';\nimport { Text } from '@chakra-ui/react/text';\nimport { splitProps as splitFileUploadProps } from '@zag-js/file-upload';\nimport { forwardRef, useEffect, useId, useMemo } from 'react';\n\nimport ImageCropper, { useImageCropperContext } from '../../atoms/ImageCropper/ImageCropper';\nimport { IconMinusCircle, IconUpload } from '../../icons';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport type BitkitFileInputProps = Omit<BitkitFieldProps, 'children' | 'state'> &\n Omit<FileUploadRootProps, 'disabled' | 'invalid'> & {\n aspectRatio?: number;\n /**\n * Max width/height (px) of the cropped output. The Ark cropper emits at the\n * selection's natural resolution with no size cap, so a large source image\n * can produce an oversized file; set this to downscale the output to fit.\n */\n maxCroppedSize?: number;\n onCropChange?: (file: File) => void;\n /**\n * Called when a file is accepted. Only ever fires with a file — clearing the\n * selection calls `onFileRemoved` instead.\n */\n onFileAccepted?: (file: File) => void;\n /**\n * Called when the accepted file is cleared — via the \"Remove\" button or a\n * programmatic `clearFiles()`.\n */\n onFileRemoved?: () => void;\n state?: 'error' | 'disabled';\n };\n\n// Ark's getCroppedImage() emits at the selection's natural resolution and only\n// controls format/quality (no size cap), so downscale here when a max is set —\n// this keeps a large source image from producing an oversized upload. Preserves\n// the blob's MIME type; falls back to the original blob if it can't be decoded.\nconst downscaleBlob = (blob: Blob, maxSize: number): Promise<Blob> => {\n // A non-positive or non-finite max would produce a 0×0 / NaN canvas and corrupt\n // the output, so treat it as \"no cap\" and pass the blob through untouched.\n if (!Number.isFinite(maxSize) || maxSize <= 0) {\n return Promise.resolve(blob);\n }\n\n return new Promise((resolve) => {\n const url = URL.createObjectURL(blob);\n const image = new Image();\n\n image.onload = () => {\n URL.revokeObjectURL(url);\n const largestSide = Math.max(image.naturalWidth, image.naturalHeight);\n if (largestSide <= maxSize) {\n resolve(blob);\n return;\n }\n const scale = maxSize / largestSide;\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(image.naturalWidth * scale);\n canvas.height = Math.round(image.naturalHeight * scale);\n const context = canvas.getContext('2d');\n if (!context) {\n resolve(blob);\n return;\n }\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n canvas.toBlob((result) => resolve(result ?? blob), blob.type);\n };\n\n image.onerror = () => {\n URL.revokeObjectURL(url);\n resolve(blob);\n };\n\n image.src = url;\n });\n};\n\nconst Dropzone = (props: Pick<BitkitFileInputProps, 'label'>) => {\n const { label } = props;\n const { disabled } = useFileUploadContext();\n const field = useFieldContext();\n const instructionId = useId();\n const dropzoneLabel = disabled ? 'Cannot upload file' : 'Drag and drop file here or click to select';\n const fieldControlProps = field?.getInputProps();\n const fieldLabelId = label ? field?.ids.label : undefined;\n\n return (\n <FileUpload.Dropzone\n aria-describedby={fieldControlProps?.['aria-describedby']}\n aria-errormessage={fieldControlProps?.['aria-errormessage']}\n aria-invalid={fieldControlProps?.['aria-invalid']}\n aria-labelledby={fieldLabelId ? `${fieldLabelId} ${instructionId}` : instructionId}\n >\n <FileUpload.DropzoneContent>\n <IconUpload />\n <Text as=\"span\" id={instructionId}>\n {dropzoneLabel}\n </Text>\n </FileUpload.DropzoneContent>\n </FileUpload.Dropzone>\n );\n};\n\nconst ImagePreviewContent = (props: Pick<BitkitFileInputProps, 'onCropChange' | 'maxCroppedSize'>) => {\n const { onCropChange, maxCroppedSize } = props;\n\n const { acceptedFiles } = useFileUploadContext();\n const { dragging, getCroppedImage } = useImageCropperContext();\n\n const acceptedFile = acceptedFiles[0];\n const objectUrl = useMemo(() => (acceptedFile ? URL.createObjectURL(acceptedFile) : undefined), [acceptedFile]);\n\n useEffect(() => {\n return () => {\n if (objectUrl) {\n URL.revokeObjectURL(objectUrl);\n }\n };\n }, [objectUrl]);\n\n useEffect(() => {\n if (!onCropChange || dragging) {\n return;\n }\n\n if (!acceptedFile) {\n return;\n }\n\n let cancelled = false;\n // Preserve the source MIME type — the Ark cropper defaults to image/png, which\n // would mismatch a .jpg name and bloat the file.\n getCroppedImage({ type: acceptedFile.type || undefined })\n .then((result) => {\n if (!(result instanceof Blob)) {\n return result;\n }\n return maxCroppedSize ? downscaleBlob(result, maxCroppedSize) : result;\n })\n .then((result) => {\n if (!cancelled && result instanceof Blob) {\n onCropChange(new File([result], acceptedFile.name, { type: result.type }));\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [getCroppedImage, acceptedFile, onCropChange, dragging, maxCroppedSize]);\n\n return (\n <ImageCropper.Viewport>\n <ImageCropper.Image src={objectUrl} />\n <ImageCropper.Selection>\n {ImageCropper.handles.map((position) => (\n <ImageCropper.Handle key={position} position={position}>\n <div />\n </ImageCropper.Handle>\n ))}\n </ImageCropper.Selection>\n </ImageCropper.Viewport>\n );\n};\n\nconst ImagePreview = (props: Pick<BitkitFileInputProps, 'aspectRatio' | 'onCropChange' | 'maxCroppedSize'>) => {\n const { aspectRatio, onCropChange, maxCroppedSize } = props;\n\n return (\n <ImageCropper.Root aspectRatio={aspectRatio} height=\"100%\">\n <ImagePreviewContent onCropChange={onCropChange} maxCroppedSize={maxCroppedSize} />\n </ImageCropper.Root>\n );\n};\n\nconst NonImagePreview = () => {\n const fileUpload = useFileUploadContext();\n const acceptedFile = fileUpload.acceptedFiles[0];\n\n return (\n <Card.Root asChild elevation={false}>\n <Card.Body display=\"flex\" paddingBlock=\"20\" paddingInline=\"24\" alignItems=\"center\" flex=\"1\">\n <VStack gap=\"4\" alignItems=\"flex-start\" flex=\"1\" minWidth=\"0\">\n <Text textStyle=\"comp/input/label\">Selected file</Text>\n <Text whiteSpace=\"nowrap\" textOverflow=\"ellipsis\" overflow=\"hidden\" maxWidth=\"100%\">\n {acceptedFile.name}\n </Text>\n </VStack>\n <BitkitButton icon={IconMinusCircle} variant=\"secondary\" size=\"md\" onClick={fileUpload.clearFiles}>\n Remove\n </BitkitButton>\n </Card.Body>\n </Card.Root>\n );\n};\n\nconst BitkitFileInputContent = (\n props: Pick<BitkitFileInputProps, 'variant' | 'aspectRatio' | 'label' | 'onCropChange' | 'maxCroppedSize'>,\n) => {\n const { variant, aspectRatio, label, onCropChange, maxCroppedSize } = props;\n const acceptedFile = useFileUploadContext().acceptedFiles[0];\n\n return (\n <>\n {!acceptedFile && <Dropzone label={label} />}\n {acceptedFile && variant === 'image' && (\n <ImagePreview aspectRatio={aspectRatio} onCropChange={onCropChange} maxCroppedSize={maxCroppedSize} />\n )}\n {acceptedFile && variant !== 'image' && <NonImagePreview />}\n </>\n );\n};\n\nconst BitkitFileInput = forwardRef<HTMLDivElement, BitkitFileInputProps>((props, ref) => {\n const {\n aspectRatio,\n maxCroppedSize,\n onCropChange,\n onFileAccept,\n onFileAccepted,\n onFileRemoved,\n state,\n variant,\n ...rest\n } = props;\n const [fileUploadProps, fieldProps] = splitFileUploadProps(rest as never);\n\n const handleFileAccept = (details: FileUploadFileAcceptDetails) => {\n onFileAccept?.(details);\n\n const acceptedFile = details.files[0];\n if (acceptedFile) {\n onFileAccepted?.(acceptedFile);\n } else {\n onFileRemoved?.();\n }\n };\n\n const contentProps = {\n aspectRatio,\n label: props.label,\n maxCroppedSize,\n onCropChange,\n variant,\n };\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <FileUpload.Root variant={variant} onFileAccept={handleFileAccept} {...fileUploadProps}>\n <FileUpload.HiddenInput />\n <BitkitFileInputContent {...contentProps} />\n </FileUpload.Root>\n </BitkitField>\n );\n});\n\nBitkitFileInput.displayName = 'BitkitFileInput';\n\nexport default BitkitFileInput;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BitkitFileInput.js","names":["ImageCropper","_Fragment","splitFileUploadProps"],"sources":["../../../lib/components/BitkitFileInput/BitkitFileInput.tsx"],"sourcesContent":["import { Card } from '@chakra-ui/react/card';\nimport { useFieldContext } from '@chakra-ui/react/field';\nimport {\n FileUpload,\n type FileUploadFileAcceptDetails,\n type FileUploadRootProps,\n useFileUploadContext,\n} from '@chakra-ui/react/file-upload';\nimport { VStack } from '@chakra-ui/react/stack';\nimport { Text } from '@chakra-ui/react/text';\nimport { splitProps as splitFileUploadProps } from '@zag-js/file-upload';\nimport { forwardRef, useEffect, useId, useMemo } from 'react';\n\nimport ImageCropper, { useImageCropperContext } from '../../atoms/ImageCropper/ImageCropper';\nimport { IconMinusCircle, IconUpload } from '../../icons';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport type BitkitFileInputProps = Omit<BitkitFieldProps, 'children' | 'state'> &\n Omit<FileUploadRootProps, 'disabled' | 'invalid'> & {\n aspectRatio?: number;\n /**\n * Max width/height (px) of the cropped output. The Ark cropper emits at the\n * selection's natural resolution with no size cap, so a large source image\n * can produce an oversized file; set this to downscale the output to fit.\n */\n maxCroppedSize?: number;\n onCropChange?: (file: File) => void;\n /**\n * Called when a file is accepted. Only ever fires with a file — clearing the\n * selection calls `onFileRemoved` instead.\n */\n onFileAccepted?: (file: File) => void;\n /**\n * Called when the accepted file is cleared — via the \"Remove\" button or a\n * programmatic `clearFiles()`.\n */\n onFileRemoved?: () => void;\n state?: 'error' | 'disabled';\n };\n\n// Ark's getCroppedImage() emits at the selection's natural resolution and only\n// controls format/quality (no size cap), so downscale here when a max is set —\n// this keeps a large source image from producing an oversized upload. Preserves\n// the blob's MIME type; falls back to the original blob if it can't be decoded.\nconst downscaleBlob = (blob: Blob, maxSize: number): Promise<Blob> => {\n // A non-positive or non-finite max would produce a 0×0 / NaN canvas and corrupt\n // the output, so treat it as \"no cap\" and pass the blob through untouched.\n if (!Number.isFinite(maxSize) || maxSize <= 0) {\n return Promise.resolve(blob);\n }\n\n return new Promise((resolve) => {\n const url = URL.createObjectURL(blob);\n const image = new Image();\n\n image.onload = () => {\n URL.revokeObjectURL(url);\n const largestSide = Math.max(image.naturalWidth, image.naturalHeight);\n if (largestSide <= maxSize) {\n resolve(blob);\n return;\n }\n const scale = maxSize / largestSide;\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(image.naturalWidth * scale);\n canvas.height = Math.round(image.naturalHeight * scale);\n const context = canvas.getContext('2d');\n if (!context) {\n resolve(blob);\n return;\n }\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n canvas.toBlob((result) => resolve(result ?? blob), blob.type);\n };\n\n image.onerror = () => {\n URL.revokeObjectURL(url);\n resolve(blob);\n };\n\n image.src = url;\n });\n};\n\nconst Dropzone = (props: Pick<BitkitFileInputProps, 'label'>) => {\n const { label } = props;\n const { disabled } = useFileUploadContext();\n const field = useFieldContext();\n const instructionId = useId();\n const dropzoneLabel = disabled ? 'Cannot upload file' : 'Drag and drop file here or click to select';\n const fieldControlProps = field?.getInputProps();\n const fieldLabelId = label ? field?.ids.label : undefined;\n\n return (\n <FileUpload.Dropzone\n aria-describedby={fieldControlProps?.['aria-describedby']}\n aria-errormessage={fieldControlProps?.['aria-errormessage']}\n aria-invalid={fieldControlProps?.['aria-invalid']}\n aria-labelledby={fieldLabelId ? `${fieldLabelId} ${instructionId}` : instructionId}\n >\n <FileUpload.DropzoneContent>\n <IconUpload />\n <Text as=\"span\" id={instructionId}>\n {dropzoneLabel}\n </Text>\n </FileUpload.DropzoneContent>\n </FileUpload.Dropzone>\n );\n};\n\nconst ImagePreviewContent = (props: Pick<BitkitFileInputProps, 'onCropChange' | 'maxCroppedSize'>) => {\n const { onCropChange, maxCroppedSize } = props;\n\n const { acceptedFiles } = useFileUploadContext();\n const { dragging, getCroppedImage } = useImageCropperContext();\n\n const acceptedFile = acceptedFiles[0];\n const objectUrl = useMemo(() => (acceptedFile ? URL.createObjectURL(acceptedFile) : undefined), [acceptedFile]);\n\n useEffect(() => {\n return () => {\n if (objectUrl) {\n URL.revokeObjectURL(objectUrl);\n }\n };\n }, [objectUrl]);\n\n useEffect(() => {\n if (!onCropChange || dragging) {\n return;\n }\n\n if (!acceptedFile) {\n return;\n }\n\n let cancelled = false;\n // Preserve the source MIME type — the Ark cropper defaults to image/png, which\n // would mismatch a .jpg name and bloat the file.\n getCroppedImage({ type: acceptedFile.type || undefined })\n .then((result) => {\n if (!(result instanceof Blob)) {\n return result;\n }\n return maxCroppedSize ? downscaleBlob(result, maxCroppedSize) : result;\n })\n .then((result) => {\n if (!cancelled && result instanceof Blob) {\n onCropChange(new File([result], acceptedFile.name, { type: result.type }));\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [getCroppedImage, acceptedFile, onCropChange, dragging, maxCroppedSize]);\n\n return (\n <ImageCropper.Viewport>\n <ImageCropper.Image src={objectUrl} />\n <ImageCropper.Selection>\n {ImageCropper.handles.map((position) => (\n <ImageCropper.Handle key={position} position={position}>\n <div />\n </ImageCropper.Handle>\n ))}\n </ImageCropper.Selection>\n </ImageCropper.Viewport>\n );\n};\n\nconst ImagePreview = (props: Pick<BitkitFileInputProps, 'aspectRatio' | 'onCropChange' | 'maxCroppedSize'>) => {\n const { aspectRatio, onCropChange, maxCroppedSize } = props;\n\n return (\n <ImageCropper.Root aspectRatio={aspectRatio} height=\"100%\">\n <ImagePreviewContent onCropChange={onCropChange} maxCroppedSize={maxCroppedSize} />\n </ImageCropper.Root>\n );\n};\n\nconst NonImagePreview = () => {\n const fileUpload = useFileUploadContext();\n const acceptedFile = fileUpload.acceptedFiles[0];\n\n return (\n <Card.Root asChild elevation={false}>\n <Card.Body display=\"flex\" paddingBlock=\"20\" paddingInline=\"24\" alignItems=\"center\" flex=\"1\">\n <VStack gap=\"4\" alignItems=\"flex-start\" flex=\"1\" minWidth=\"0\">\n <Text textStyle=\"comp/input/label\">Selected file</Text>\n <Text whiteSpace=\"nowrap\" textOverflow=\"ellipsis\" overflow=\"hidden\" maxWidth=\"100%\">\n {acceptedFile.name}\n </Text>\n </VStack>\n <BitkitButton icon={IconMinusCircle} variant=\"secondary\" size=\"md\" onClick={fileUpload.clearFiles}>\n Remove\n </BitkitButton>\n </Card.Body>\n </Card.Root>\n );\n};\n\nconst BitkitFileInputContent = (\n props: Pick<BitkitFileInputProps, 'variant' | 'aspectRatio' | 'label' | 'onCropChange' | 'maxCroppedSize'>,\n) => {\n const { variant, aspectRatio, label, onCropChange, maxCroppedSize } = props;\n const acceptedFile = useFileUploadContext().acceptedFiles[0];\n\n return (\n <>\n {!acceptedFile && <Dropzone label={label} />}\n {acceptedFile && variant === 'image' && (\n <ImagePreview aspectRatio={aspectRatio} onCropChange={onCropChange} maxCroppedSize={maxCroppedSize} />\n )}\n {acceptedFile && variant !== 'image' && <NonImagePreview />}\n </>\n );\n};\n\nconst BitkitFileInput = forwardRef<HTMLDivElement, BitkitFileInputProps>((props, ref) => {\n const {\n aspectRatio,\n maxCroppedSize,\n onCropChange,\n onFileAccept,\n onFileAccepted,\n onFileRemoved,\n state,\n variant,\n ...rest\n } = props;\n const [fileUploadProps, fieldProps] = splitFileUploadProps(rest as never);\n\n const handleFileAccept = (details: FileUploadFileAcceptDetails) => {\n onFileAccept?.(details);\n\n const acceptedFile = details.files[0];\n if (acceptedFile) {\n onFileAccepted?.(acceptedFile);\n } else {\n onFileRemoved?.();\n }\n };\n\n const contentProps = {\n aspectRatio,\n label: props.label,\n maxCroppedSize,\n onCropChange,\n variant,\n };\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <FileUpload.Root variant={variant} onFileAccept={handleFileAccept} {...fileUploadProps}>\n <FileUpload.HiddenInput />\n <BitkitFileInputContent {...contentProps} />\n </FileUpload.Root>\n </BitkitField>\n );\n});\n\nBitkitFileInput.displayName = 'BitkitFileInput';\n\nexport default BitkitFileInput;\n"],"mappings":"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"}
|