@openreachtech/furo-vue 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.ja.md +334 -0
- package/README.md +333 -0
- package/index.js +11 -0
- package/lib/assets/css/furo/0010.variables-palette-color-scale.css +298 -0
- package/lib/assets/css/furo/0020.variables-z-index.css +10 -0
- package/lib/assets/css/furo/0030.variables-semantic-color.css +178 -0
- package/lib/assets/css/furo/0035.variables-semantic-dimension.css +104 -0
- package/lib/assets/css/furo/0040.variables-component-furo.css +28 -0
- package/lib/assets/css/furo/0050.furo-editor-content.css +22 -0
- package/lib/assets/css/furo.css +15 -0
- package/lib/components/atoms/FuroAvatar/FuroAvatar.vue +135 -0
- package/lib/components/atoms/FuroAvatar/FuroAvatarContext.js +147 -0
- package/lib/components/atoms/FuroBadge/FuroBadge.vue +240 -0
- package/lib/components/atoms/FuroBadge/FuroBadgeContext.js +298 -0
- package/lib/components/atoms/FuroButton/ButtonEmitPayload.js +44 -0
- package/lib/components/atoms/FuroButton/FuroButton.vue +301 -0
- package/lib/components/atoms/FuroButton/FuroButtonContext.js +328 -0
- package/lib/components/atoms/FuroCheckbox/CheckboxEmitPayload.js +106 -0
- package/lib/components/atoms/FuroCheckbox/FuroCheckbox.vue +173 -0
- package/lib/components/atoms/FuroCheckbox/FuroCheckboxContext.js +682 -0
- package/lib/components/atoms/FuroEmailField/EmailFieldEmitPayload.js +74 -0
- package/lib/components/atoms/FuroEmailField/FuroEmailField.vue +119 -0
- package/lib/components/atoms/FuroEmailField/FuroEmailFieldContext.js +311 -0
- package/lib/components/atoms/FuroFileField/FileFieldEmitPayload.js +80 -0
- package/lib/components/atoms/FuroFileField/FuroFileField.vue +128 -0
- package/lib/components/atoms/FuroFileField/FuroFileFieldContext.js +195 -0
- package/lib/components/atoms/FuroIcon/FuroIcon.vue +74 -0
- package/lib/components/atoms/FuroIcon/FuroIconContext.js +293 -0
- package/lib/components/atoms/FuroIcon/FuroIconRegistry.js +617 -0
- package/lib/components/atoms/FuroIcon/FuroIconifyRendererContext.js +101 -0
- package/lib/components/atoms/FuroIcon/furoIconData.js +164 -0
- package/lib/components/atoms/FuroIcon/iconRenderers.js +62 -0
- package/lib/components/atoms/FuroIcon/icons.js +7 -0
- package/lib/components/atoms/FuroNumberField/FuroNumberField.vue +213 -0
- package/lib/components/atoms/FuroNumberField/FuroNumberFieldContext.js +442 -0
- package/lib/components/atoms/FuroNumberField/NumberFieldEmitPayload.js +162 -0
- package/lib/components/atoms/FuroPasswordField/FuroPasswordField.vue +119 -0
- package/lib/components/atoms/FuroPasswordField/FuroPasswordFieldContext.js +311 -0
- package/lib/components/atoms/FuroPasswordField/PasswordFieldEmitPayload.js +74 -0
- package/lib/components/atoms/FuroRadio/FuroRadio.vue +193 -0
- package/lib/components/atoms/FuroRadio/FuroRadioContext.js +557 -0
- package/lib/components/atoms/FuroRadio/RadioEmitPayload.js +72 -0
- package/lib/components/atoms/FuroSwitch/FuroSwitch.vue +165 -0
- package/lib/components/atoms/FuroSwitch/FuroSwitchContext.js +440 -0
- package/lib/components/atoms/FuroSwitch/SwitchEmitPayload.js +86 -0
- package/lib/components/atoms/FuroTextField/FuroTextField.vue +119 -0
- package/lib/components/atoms/FuroTextField/FuroTextFieldContext.js +311 -0
- package/lib/components/atoms/FuroTextField/TextFieldEmitPayload.js +83 -0
- package/lib/components/atoms/FuroTextarea/FuroTextarea.vue +121 -0
- package/lib/components/atoms/FuroTextarea/FuroTextareaContext.js +322 -0
- package/lib/components/atoms/FuroTextarea/TextareaEmitPayload.js +83 -0
- package/lib/components/atoms/FuroToggle/FuroToggle.vue +172 -0
- package/lib/components/atoms/FuroToggle/FuroToggleContext.js +410 -0
- package/lib/components/atoms/FuroToggle/ToggleEmitPayload.js +86 -0
- package/lib/components/molecules/FuroAccordion/AccordionEmitPayload.js +80 -0
- package/lib/components/molecules/FuroAccordion/FuroAccordion.vue +219 -0
- package/lib/components/molecules/FuroAccordion/FuroAccordionContext.js +547 -0
- package/lib/components/molecules/FuroAttachment/FuroAttachment.vue +376 -0
- package/lib/components/molecules/FuroAttachment/FuroAttachmentContext.js +628 -0
- package/lib/components/molecules/FuroAutocompleteField/AutocompleteEmitPayload.js +225 -0
- package/lib/components/molecules/FuroAutocompleteField/FuroAutocompleteField.vue +669 -0
- package/lib/components/molecules/FuroAutocompleteField/FuroAutocompleteFieldContext.js +1525 -0
- package/lib/components/molecules/FuroAvatarGroup/FuroAvatarGroup.vue +126 -0
- package/lib/components/molecules/FuroAvatarGroup/FuroAvatarGroupContext.js +245 -0
- package/lib/components/molecules/FuroBreadcrumb/FuroBreadcrumb.vue +219 -0
- package/lib/components/molecules/FuroBreadcrumb/FuroBreadcrumbContext.js +257 -0
- package/lib/components/molecules/FuroCollapsible/CollapsibleEmitPayload.js +69 -0
- package/lib/components/molecules/FuroCollapsible/FuroCollapsible.vue +177 -0
- package/lib/components/molecules/FuroCollapsible/FuroCollapsibleContext.js +389 -0
- package/lib/components/molecules/FuroControlBlock/FuroControlBlock.vue +149 -0
- package/lib/components/molecules/FuroControlBlock/FuroControlBlockContext.js +81 -0
- package/lib/components/molecules/FuroDatePicker/DatePickerEmitPayload.js +74 -0
- package/lib/components/molecules/FuroDatePicker/FuroDatePicker.vue +661 -0
- package/lib/components/molecules/FuroDatePicker/FuroDatePickerContext.js +1038 -0
- package/lib/components/molecules/FuroDateTimePicker/DateTimePickerEmitPayload.js +96 -0
- package/lib/components/molecules/FuroDateTimePicker/FuroDateTimePicker.vue +153 -0
- package/lib/components/molecules/FuroDateTimePicker/FuroDateTimePickerContext.js +840 -0
- package/lib/components/molecules/FuroDropdownMenu/DropdownMenuOptionSelectEmitPayload.js +100 -0
- package/lib/components/molecules/FuroDropdownMenu/FuroDropdownMenu.vue +348 -0
- package/lib/components/molecules/FuroDropdownMenu/FuroDropdownMenuContext.js +714 -0
- package/lib/components/molecules/FuroDropdownMenu/FuroDropdownMenuOptionRows.vue +222 -0
- package/lib/components/molecules/FuroEditableField/EditableEmitPayload.js +89 -0
- package/lib/components/molecules/FuroEditableField/FuroEditableField.vue +314 -0
- package/lib/components/molecules/FuroEditableField/FuroEditableFieldContext.js +1018 -0
- package/lib/components/molecules/FuroEditableField/processors/EditorCollisionProcessor.js +236 -0
- package/lib/components/molecules/FuroEditableField/processors/ObjectProcessor.js +101 -0
- package/lib/components/molecules/FuroEmptyState/FuroEmptyState.vue +124 -0
- package/lib/components/molecules/FuroEmptyState/FuroEmptyStateContext.js +42 -0
- package/lib/components/molecules/FuroErrorState/FuroErrorState.vue +125 -0
- package/lib/components/molecules/FuroErrorState/FuroErrorStateContext.js +42 -0
- package/lib/components/molecules/FuroPagination/FuroPagination.vue +246 -0
- package/lib/components/molecules/FuroPagination/FuroPaginationContext.js +489 -0
- package/lib/components/molecules/FuroPopover/FuroPopover.vue +171 -0
- package/lib/components/molecules/FuroPopover/FuroPopoverContext.js +279 -0
- package/lib/components/molecules/FuroScrollArea/FuroScrollArea.vue +181 -0
- package/lib/components/molecules/FuroScrollArea/FuroScrollAreaContext.js +149 -0
- package/lib/components/molecules/FuroSearchField/FuroSearchField.vue +155 -0
- package/lib/components/molecules/FuroSearchField/FuroSearchFieldContext.js +231 -0
- package/lib/components/molecules/FuroSectionHeader/FuroSectionHeader.vue +140 -0
- package/lib/components/molecules/FuroSectionHeader/FuroSectionHeaderContext.js +204 -0
- package/lib/components/molecules/FuroSelect/FuroSelect.vue +474 -0
- package/lib/components/molecules/FuroSelect/FuroSelectContext.js +743 -0
- package/lib/components/molecules/FuroSelect/SelectEmitPayload.js +181 -0
- package/lib/components/molecules/FuroSeparator/FuroSeparator.vue +88 -0
- package/lib/components/molecules/FuroSeparator/FuroSeparatorContext.js +40 -0
- package/lib/components/molecules/FuroSkeleton/FuroSkeleton.vue +101 -0
- package/lib/components/molecules/FuroSkeleton/FuroSkeletonContext.js +82 -0
- package/lib/components/molecules/FuroSplitter/FuroSplitter.vue +237 -0
- package/lib/components/molecules/FuroSplitter/FuroSplitterContext.js +429 -0
- package/lib/components/molecules/FuroSplitter/SplitterEmitPayload.js +69 -0
- package/lib/components/molecules/FuroTimeField/FuroTimeField.vue +251 -0
- package/lib/components/molecules/FuroTimeField/FuroTimeFieldContext.js +1138 -0
- package/lib/components/molecules/FuroTimeField/TimeFieldEmitPayload.js +74 -0
- package/lib/components/molecules/FuroToggleGroup/FuroToggleGroup.vue +211 -0
- package/lib/components/molecules/FuroToggleGroup/FuroToggleGroupContext.js +551 -0
- package/lib/components/molecules/FuroToggleGroup/ToggleGroupEmitPayload.js +80 -0
- package/lib/components/molecules/FuroToolBar/FuroToolBar.vue +91 -0
- package/lib/components/molecules/FuroToolBar/FuroToolBarContext.js +75 -0
- package/lib/components/molecules/FuroTooltip/FuroTooltip.vue +183 -0
- package/lib/components/molecules/FuroTooltip/FuroTooltipContext.js +290 -0
- package/lib/components/organisms/FuroAlertDialog/FuroAlertDialog.vue +324 -0
- package/lib/components/organisms/FuroAlertDialog/FuroAlertDialogContext.js +608 -0
- package/lib/components/organisms/FuroDialog/FuroDialog.vue +362 -0
- package/lib/components/organisms/FuroDialog/FuroDialogContext.js +535 -0
- package/lib/components/organisms/FuroDrawer/FuroDrawer.vue +618 -0
- package/lib/components/organisms/FuroDrawer/FuroDrawerContext.js +676 -0
- package/lib/components/organisms/FuroEditor/FuroEditor.vue +613 -0
- package/lib/components/organisms/FuroEditor/FuroEditorCommandContext.js +420 -0
- package/lib/components/organisms/FuroEditor/FuroEditorContext.js +2048 -0
- package/lib/components/organisms/FuroEditor/FuroEditorMentionMenu.vue +120 -0
- package/lib/components/organisms/FuroEditor/FuroEditorMentionMenuContext.js +261 -0
- package/lib/components/organisms/FuroEditor/PreserveNewlinesPasteExtension.js +267 -0
- package/lib/components/organisms/FuroEditor/build-editor-extensions.js +97 -0
- package/lib/components/organisms/FuroEditor/mention-suggestion.js +320 -0
- package/lib/components/organisms/FuroEditor/paste-link-segments.js +124 -0
- package/lib/components/organisms/FuroSidebar/FuroSidebar.vue +473 -0
- package/lib/components/organisms/FuroSidebar/FuroSidebarContext.js +1014 -0
- package/lib/components/organisms/FuroStepper/FuroStepper.vue +345 -0
- package/lib/components/organisms/FuroStepper/FuroStepperContext.js +481 -0
- package/lib/components/organisms/FuroTable/FuroTable.vue +707 -0
- package/lib/components/organisms/FuroTable/FuroTableContext.js +1965 -0
- package/lib/components/organisms/FuroTable/FuroTableRowItemContext.js +111 -0
- package/lib/components/organisms/FuroTabs/FuroTabs.vue +403 -0
- package/lib/components/organisms/FuroTabs/FuroTabsContext.js +846 -0
- package/lib/components/organisms/FuroToast/FuroToast.vue +624 -0
- package/lib/components/organisms/FuroToast/FuroToastContext.js +1089 -0
- package/lib/components/organisms/FuroToast/FuroToaster.vue +44 -0
- package/lib/components/organisms/FuroToast/FuroToasterContext.js +113 -0
- package/lib/components/organisms/FuroToast/ToastQueue.js +325 -0
- package/lib/components/organisms/FuroToast/toast.js +64 -0
- package/lib/contexts/BaseFuroContext.js +318 -0
- package/lib/contexts/BaseFuroContextAccessor.js +47 -0
- package/lib/emit-payload/BaseEmitPayload.js +91 -0
- package/lib/index.components.js +61 -0
- package/lib/index.core.js +18 -0
- package/lib/tools/TimerClerk.js +75 -0
- package/nuxt/index.js +109 -0
- package/nuxt/runtime/furo-icon-renderer.js +24 -0
- package/package.json +137 -0
- package/public/furo-vue/components.json +4619 -0
- package/public/furo-vue/llms.txt +66 -0
- package/types/furo-nuxt.d.ts +48 -0
- package/types/generated/components/atoms/FuroAvatar/FuroAvatar.vue.d.ts +74 -0
- package/types/generated/components/atoms/FuroAvatar/FuroAvatarContext.d.ts +82 -0
- package/types/generated/components/atoms/FuroBadge/FuroBadge.vue.d.ts +12 -0
- package/types/generated/components/atoms/FuroBadge/FuroBadgeContext.d.ts +160 -0
- package/types/generated/components/atoms/FuroButton/ButtonEmitPayload.d.ts +19 -0
- package/types/generated/components/atoms/FuroButton/FuroButton.vue.d.ts +53 -0
- package/types/generated/components/atoms/FuroButton/FuroButtonContext.d.ts +156 -0
- package/types/generated/components/atoms/FuroCheckbox/CheckboxEmitPayload.d.ts +55 -0
- package/types/generated/components/atoms/FuroCheckbox/FuroCheckbox.vue.d.ts +87 -0
- package/types/generated/components/atoms/FuroCheckbox/FuroCheckboxContext.d.ts +342 -0
- package/types/generated/components/atoms/FuroEmailField/EmailFieldEmitPayload.d.ts +46 -0
- package/types/generated/components/atoms/FuroEmailField/FuroEmailField.vue.d.ts +458 -0
- package/types/generated/components/atoms/FuroEmailField/FuroEmailFieldContext.d.ts +161 -0
- package/types/generated/components/atoms/FuroFileField/FileFieldEmitPayload.d.ts +46 -0
- package/types/generated/components/atoms/FuroFileField/FuroFileField.vue.d.ts +454 -0
- package/types/generated/components/atoms/FuroFileField/FuroFileFieldContext.d.ts +109 -0
- package/types/generated/components/atoms/FuroIcon/FuroIcon.vue.d.ts +14 -0
- package/types/generated/components/atoms/FuroIcon/FuroIconContext.d.ts +152 -0
- package/types/generated/components/atoms/FuroIcon/FuroIconRegistry.d.ts +457 -0
- package/types/generated/components/atoms/FuroIcon/FuroIconifyRendererContext.d.ts +65 -0
- package/types/generated/components/atoms/FuroIcon/furoIconData.d.ts +154 -0
- package/types/generated/components/atoms/FuroIcon/iconRenderers.d.ts +6 -0
- package/types/generated/components/atoms/FuroIcon/icons.d.ts +6 -0
- package/types/generated/components/atoms/FuroNumberField/FuroNumberField.vue.d.ts +500 -0
- package/types/generated/components/atoms/FuroNumberField/FuroNumberFieldContext.d.ts +243 -0
- package/types/generated/components/atoms/FuroNumberField/NumberFieldEmitPayload.d.ts +74 -0
- package/types/generated/components/atoms/FuroPasswordField/FuroPasswordField.vue.d.ts +458 -0
- package/types/generated/components/atoms/FuroPasswordField/FuroPasswordFieldContext.d.ts +161 -0
- package/types/generated/components/atoms/FuroPasswordField/PasswordFieldEmitPayload.d.ts +46 -0
- package/types/generated/components/atoms/FuroRadio/FuroRadio.vue.d.ts +96 -0
- package/types/generated/components/atoms/FuroRadio/FuroRadioContext.d.ts +290 -0
- package/types/generated/components/atoms/FuroRadio/RadioEmitPayload.d.ts +39 -0
- package/types/generated/components/atoms/FuroSwitch/FuroSwitch.vue.d.ts +74 -0
- package/types/generated/components/atoms/FuroSwitch/FuroSwitchContext.d.ts +218 -0
- package/types/generated/components/atoms/FuroSwitch/SwitchEmitPayload.d.ts +42 -0
- package/types/generated/components/atoms/FuroTextField/FuroTextField.vue.d.ts +458 -0
- package/types/generated/components/atoms/FuroTextField/FuroTextFieldContext.d.ts +161 -0
- package/types/generated/components/atoms/FuroTextField/TextFieldEmitPayload.d.ts +52 -0
- package/types/generated/components/atoms/FuroTextarea/FuroTextarea.vue.d.ts +422 -0
- package/types/generated/components/atoms/FuroTextarea/FuroTextareaContext.d.ts +161 -0
- package/types/generated/components/atoms/FuroTextarea/TextareaEmitPayload.d.ts +52 -0
- package/types/generated/components/atoms/FuroToggle/FuroToggle.vue.d.ts +51 -0
- package/types/generated/components/atoms/FuroToggle/FuroToggleContext.d.ts +191 -0
- package/types/generated/components/atoms/FuroToggle/ToggleEmitPayload.d.ts +42 -0
- package/types/generated/components/molecules/FuroAccordion/AccordionEmitPayload.d.ts +41 -0
- package/types/generated/components/molecules/FuroAccordion/FuroAccordion.vue.d.ts +133 -0
- package/types/generated/components/molecules/FuroAccordion/FuroAccordionContext.d.ts +279 -0
- package/types/generated/components/molecules/FuroAttachment/FuroAttachment.vue.d.ts +79 -0
- package/types/generated/components/molecules/FuroAttachment/FuroAttachmentContext.d.ts +363 -0
- package/types/generated/components/molecules/FuroAutocompleteField/AutocompleteEmitPayload.d.ts +129 -0
- package/types/generated/components/molecules/FuroAutocompleteField/FuroAutocompleteField.vue.d.ts +751 -0
- package/types/generated/components/molecules/FuroAutocompleteField/FuroAutocompleteFieldContext.d.ts +722 -0
- package/types/generated/components/molecules/FuroAvatarGroup/FuroAvatarGroup.vue.d.ts +84 -0
- package/types/generated/components/molecules/FuroAvatarGroup/FuroAvatarGroupContext.d.ts +150 -0
- package/types/generated/components/molecules/FuroBreadcrumb/FuroBreadcrumb.vue.d.ts +24 -0
- package/types/generated/components/molecules/FuroBreadcrumb/FuroBreadcrumbContext.d.ts +152 -0
- package/types/generated/components/molecules/FuroCollapsible/CollapsibleEmitPayload.d.ts +36 -0
- package/types/generated/components/molecules/FuroCollapsible/FuroCollapsible.vue.d.ts +98 -0
- package/types/generated/components/molecules/FuroCollapsible/FuroCollapsibleContext.d.ts +191 -0
- package/types/generated/components/molecules/FuroControlBlock/FuroControlBlock.vue.d.ts +30 -0
- package/types/generated/components/molecules/FuroControlBlock/FuroControlBlockContext.d.ts +57 -0
- package/types/generated/components/molecules/FuroDatePicker/DatePickerEmitPayload.d.ts +41 -0
- package/types/generated/components/molecules/FuroDatePicker/FuroDatePicker.vue.d.ts +456 -0
- package/types/generated/components/molecules/FuroDatePicker/FuroDatePickerContext.d.ts +516 -0
- package/types/generated/components/molecules/FuroDateTimePicker/DateTimePickerEmitPayload.d.ts +55 -0
- package/types/generated/components/molecules/FuroDateTimePicker/FuroDateTimePicker.vue.d.ts +1365 -0
- package/types/generated/components/molecules/FuroDateTimePicker/FuroDateTimePickerContext.d.ts +435 -0
- package/types/generated/components/molecules/FuroDropdownMenu/DropdownMenuOptionSelectEmitPayload.d.ts +48 -0
- package/types/generated/components/molecules/FuroDropdownMenu/FuroDropdownMenu.vue.d.ts +773 -0
- package/types/generated/components/molecules/FuroDropdownMenu/FuroDropdownMenuContext.d.ts +380 -0
- package/types/generated/components/molecules/FuroDropdownMenu/FuroDropdownMenuOptionRows.vue.d.ts +261 -0
- package/types/generated/components/molecules/FuroEditableField/EditableEmitPayload.d.ts +39 -0
- package/types/generated/components/molecules/FuroEditableField/FuroEditableField.vue.d.ts +646 -0
- package/types/generated/components/molecules/FuroEditableField/FuroEditableFieldContext.d.ts +477 -0
- package/types/generated/components/molecules/FuroEditableField/processors/EditorCollisionProcessor.d.ts +121 -0
- package/types/generated/components/molecules/FuroEditableField/processors/ObjectProcessor.d.ts +45 -0
- package/types/generated/components/molecules/FuroEmptyState/FuroEmptyState.vue.d.ts +21 -0
- package/types/generated/components/molecules/FuroEmptyState/FuroEmptyStateContext.d.ts +32 -0
- package/types/generated/components/molecules/FuroErrorState/FuroErrorState.vue.d.ts +21 -0
- package/types/generated/components/molecules/FuroErrorState/FuroErrorStateContext.d.ts +32 -0
- package/types/generated/components/molecules/FuroPagination/FuroPagination.vue.d.ts +534 -0
- package/types/generated/components/molecules/FuroPagination/FuroPaginationContext.d.ts +271 -0
- package/types/generated/components/molecules/FuroPopover/FuroPopover.vue.d.ts +513 -0
- package/types/generated/components/molecules/FuroPopover/FuroPopoverContext.d.ts +160 -0
- package/types/generated/components/molecules/FuroScrollArea/FuroScrollArea.vue.d.ts +124 -0
- package/types/generated/components/molecules/FuroScrollArea/FuroScrollAreaContext.d.ts +86 -0
- package/types/generated/components/molecules/FuroSearchField/FuroSearchField.vue.d.ts +487 -0
- package/types/generated/components/molecules/FuroSearchField/FuroSearchFieldContext.d.ts +137 -0
- package/types/generated/components/molecules/FuroSectionHeader/FuroSectionHeader.vue.d.ts +49 -0
- package/types/generated/components/molecules/FuroSectionHeader/FuroSectionHeaderContext.d.ts +121 -0
- package/types/generated/components/molecules/FuroSelect/FuroSelect.vue.d.ts +719 -0
- package/types/generated/components/molecules/FuroSelect/FuroSelectContext.d.ts +402 -0
- package/types/generated/components/molecules/FuroSelect/SelectEmitPayload.d.ts +102 -0
- package/types/generated/components/molecules/FuroSeparator/FuroSeparator.vue.d.ts +39 -0
- package/types/generated/components/molecules/FuroSeparator/FuroSeparatorContext.d.ts +31 -0
- package/types/generated/components/molecules/FuroSkeleton/FuroSkeleton.vue.d.ts +27 -0
- package/types/generated/components/molecules/FuroSkeleton/FuroSkeletonContext.d.ts +61 -0
- package/types/generated/components/molecules/FuroSplitter/FuroSplitter.vue.d.ts +139 -0
- package/types/generated/components/molecules/FuroSplitter/FuroSplitterContext.d.ts +226 -0
- package/types/generated/components/molecules/FuroSplitter/SplitterEmitPayload.d.ts +41 -0
- package/types/generated/components/molecules/FuroTimeField/FuroTimeField.vue.d.ts +498 -0
- package/types/generated/components/molecules/FuroTimeField/FuroTimeFieldContext.d.ts +555 -0
- package/types/generated/components/molecules/FuroTimeField/TimeFieldEmitPayload.d.ts +41 -0
- package/types/generated/components/molecules/FuroToggleGroup/FuroToggleGroup.vue.d.ts +70 -0
- package/types/generated/components/molecules/FuroToggleGroup/FuroToggleGroupContext.d.ts +270 -0
- package/types/generated/components/molecules/FuroToggleGroup/ToggleGroupEmitPayload.d.ts +41 -0
- package/types/generated/components/molecules/FuroToolBar/FuroToolBar.vue.d.ts +30 -0
- package/types/generated/components/molecules/FuroToolBar/FuroToolBarContext.d.ts +48 -0
- package/types/generated/components/molecules/FuroTooltip/FuroTooltip.vue.d.ts +524 -0
- package/types/generated/components/molecules/FuroTooltip/FuroTooltipContext.d.ts +166 -0
- package/types/generated/components/organisms/FuroAlertDialog/FuroAlertDialog.vue.d.ts +651 -0
- package/types/generated/components/organisms/FuroAlertDialog/FuroAlertDialogContext.d.ts +299 -0
- package/types/generated/components/organisms/FuroDialog/FuroDialog.vue.d.ts +583 -0
- package/types/generated/components/organisms/FuroDialog/FuroDialogContext.d.ts +264 -0
- package/types/generated/components/organisms/FuroDrawer/FuroDrawer.vue.d.ts +635 -0
- package/types/generated/components/organisms/FuroDrawer/FuroDrawerContext.d.ts +347 -0
- package/types/generated/components/organisms/FuroEditor/FuroEditor.vue.d.ts +2487 -0
- package/types/generated/components/organisms/FuroEditor/FuroEditorCommandContext.d.ts +192 -0
- package/types/generated/components/organisms/FuroEditor/FuroEditorContext.d.ts +904 -0
- package/types/generated/components/organisms/FuroEditor/FuroEditorMentionMenu.vue.d.ts +43 -0
- package/types/generated/components/organisms/FuroEditor/FuroEditorMentionMenuContext.d.ts +159 -0
- package/types/generated/components/organisms/FuroEditor/PreserveNewlinesPasteExtension.d.ts +43 -0
- package/types/generated/components/organisms/FuroEditor/build-editor-extensions.d.ts +22 -0
- package/types/generated/components/organisms/FuroEditor/mention-suggestion.d.ts +25 -0
- package/types/generated/components/organisms/FuroEditor/paste-link-segments.d.ts +31 -0
- package/types/generated/components/organisms/FuroSidebar/FuroSidebar.vue.d.ts +898 -0
- package/types/generated/components/organisms/FuroSidebar/FuroSidebarContext.d.ts +596 -0
- package/types/generated/components/organisms/FuroStepper/FuroStepper.vue.d.ts +589 -0
- package/types/generated/components/organisms/FuroStepper/FuroStepperContext.d.ts +266 -0
- package/types/generated/components/organisms/FuroTable/FuroTable.vue.d.ts +528 -0
- package/types/generated/components/organisms/FuroTable/FuroTableContext.d.ts +1035 -0
- package/types/generated/components/organisms/FuroTable/FuroTableRowItemContext.d.ts +62 -0
- package/types/generated/components/organisms/FuroTabs/FuroTabs.vue.d.ts +515 -0
- package/types/generated/components/organisms/FuroTabs/FuroTabsContext.d.ts +438 -0
- package/types/generated/components/organisms/FuroToast/FuroToast.vue.d.ts +725 -0
- package/types/generated/components/organisms/FuroToast/FuroToastContext.d.ts +543 -0
- package/types/generated/components/organisms/FuroToast/FuroToaster.vue.d.ts +729 -0
- package/types/generated/components/organisms/FuroToast/FuroToasterContext.d.ts +62 -0
- package/types/generated/components/organisms/FuroToast/ToastQueue.d.ts +201 -0
- package/types/generated/components/organisms/FuroToast/toast.d.ts +23 -0
- package/types/generated/contexts/BaseFuroContext.d.ts +207 -0
- package/types/generated/contexts/BaseFuroContextAccessor.d.ts +28 -0
- package/types/generated/emit-payload/BaseEmitPayload.d.ts +62 -0
- package/types/generated/index.components.d.ts +50 -0
- package/types/generated/index.core.d.ts +6 -0
- package/types/generated/tools/TimerClerk.d.ts +50 -0
- package/types/index.d.ts +12 -0
|
@@ -0,0 +1,1138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ref,
|
|
3
|
+
} from 'vue'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Time,
|
|
7
|
+
parseTime,
|
|
8
|
+
} from '@internationalized/date'
|
|
9
|
+
|
|
10
|
+
import BaseFuroContext from '../../../contexts/BaseFuroContext.js'
|
|
11
|
+
|
|
12
|
+
import TimeFieldEmitPayload from './TimeFieldEmitPayload.js'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Furo-only parcel keys that are not forwarded to Reka `TimeFieldRoot`.
|
|
16
|
+
* These are stripped from the Reka v-bind spread.
|
|
17
|
+
*/
|
|
18
|
+
export const FURO_TIME_FIELD_PARCEL_KEYS = new Set([
|
|
19
|
+
'invalid',
|
|
20
|
+
'placeholder',
|
|
21
|
+
'disabled',
|
|
22
|
+
'readonly',
|
|
23
|
+
'minValue',
|
|
24
|
+
'maxValue',
|
|
25
|
+
'timeFormat',
|
|
26
|
+
'granularity',
|
|
27
|
+
'timezone',
|
|
28
|
+
'step',
|
|
29
|
+
'stepSnapping',
|
|
30
|
+
'decrementLabel',
|
|
31
|
+
'incrementLabel',
|
|
32
|
+
])
|
|
33
|
+
|
|
34
|
+
const DEFAULT_DECREMENT_LABEL = 'Decrement time'
|
|
35
|
+
const DEFAULT_INCREMENT_LABEL = 'Increment time'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Context class for managing FuroTimeField atom.
|
|
39
|
+
*
|
|
40
|
+
* @extends {BaseFuroContext<null, Props, EmitEventName>}
|
|
41
|
+
*/
|
|
42
|
+
export default class FuroTimeFieldContext extends BaseFuroContext {
|
|
43
|
+
/**
|
|
44
|
+
* Constructor.
|
|
45
|
+
*
|
|
46
|
+
* @param {FuroTimeFieldContextParams} params - Parameters of this constructor.
|
|
47
|
+
*/
|
|
48
|
+
constructor ({
|
|
49
|
+
props,
|
|
50
|
+
componentContext,
|
|
51
|
+
refHash,
|
|
52
|
+
}) {
|
|
53
|
+
super({
|
|
54
|
+
props,
|
|
55
|
+
componentContext,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
this.refHash = refHash
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Factory method.
|
|
63
|
+
*
|
|
64
|
+
* @template {X extends typeof FuroTimeFieldContext ? X : never} T, X
|
|
65
|
+
* @override
|
|
66
|
+
* @param {FuroTimeFieldContextFactoryParams} params - Parameters of this factory method.
|
|
67
|
+
* @returns {InstanceType<T>} An instance of this class.
|
|
68
|
+
* @this {T}
|
|
69
|
+
*/
|
|
70
|
+
static create ({
|
|
71
|
+
props,
|
|
72
|
+
componentContext,
|
|
73
|
+
refHash = this.buildRefHash(),
|
|
74
|
+
}) {
|
|
75
|
+
return /** @type {InstanceType<T>} */ (
|
|
76
|
+
new this({
|
|
77
|
+
props,
|
|
78
|
+
componentContext,
|
|
79
|
+
refHash,
|
|
80
|
+
})
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Build ref hash.
|
|
86
|
+
*
|
|
87
|
+
* @override
|
|
88
|
+
* @returns {FuroTimeFieldContextParams['refHash']}
|
|
89
|
+
*/
|
|
90
|
+
static buildRefHash () {
|
|
91
|
+
return {
|
|
92
|
+
rootElementRef: ref(null),
|
|
93
|
+
internalValueRef: ref(null),
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Build a zero `Time` (`00:00:00`) used as a fallback start for stepper edits.
|
|
99
|
+
*
|
|
100
|
+
* @returns {import('@internationalized/date').Time}
|
|
101
|
+
*/
|
|
102
|
+
static buildZeroTime () {
|
|
103
|
+
return new Time(0, 0, 0)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get emit event names.
|
|
108
|
+
*
|
|
109
|
+
* @override
|
|
110
|
+
* @returns {Readonly<{
|
|
111
|
+
* CHANGE_VALUE: 'change-value'
|
|
112
|
+
* COMMIT_VALUE: 'commit-value'
|
|
113
|
+
* UPDATE_VALUE: 'update:value'
|
|
114
|
+
* }>}
|
|
115
|
+
*/
|
|
116
|
+
static get EMIT_EVENT_NAME () {
|
|
117
|
+
return {
|
|
118
|
+
CHANGE_VALUE: 'change-value',
|
|
119
|
+
COMMIT_VALUE: 'commit-value',
|
|
120
|
+
UPDATE_VALUE: 'update:value',
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get emit event hash.
|
|
126
|
+
*
|
|
127
|
+
* @returns {{
|
|
128
|
+
* 'change-value': (payload: import('./TimeFieldEmitPayload.js').default) => void
|
|
129
|
+
* 'commit-value': (payload: import('./TimeFieldEmitPayload.js').default) => void
|
|
130
|
+
* 'update:value': (value: string | null) => void
|
|
131
|
+
* }}
|
|
132
|
+
*/
|
|
133
|
+
static get EMIT_EVENT_HASH () {
|
|
134
|
+
return {
|
|
135
|
+
[this.EMIT_EVENT_NAME.CHANGE_VALUE]: payload => {},
|
|
136
|
+
[this.EMIT_EVENT_NAME.COMMIT_VALUE]: payload => {},
|
|
137
|
+
[this.EMIT_EVENT_NAME.UPDATE_VALUE]: value => {},
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get the EmitPayload constructor.
|
|
143
|
+
*
|
|
144
|
+
* @returns {typeof TimeFieldEmitPayload}
|
|
145
|
+
*/
|
|
146
|
+
static get EmitPayloadCtor () {
|
|
147
|
+
return TimeFieldEmitPayload
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Map a time segment part (`hour` | `minute` | `second`) to the `Time.add` /
|
|
152
|
+
* `Time.subtract` duration unit key. Shared by focused-segment and granularity stepping.
|
|
153
|
+
*
|
|
154
|
+
* @returns {Readonly<{
|
|
155
|
+
* hour: 'hours'
|
|
156
|
+
* minute: 'minutes'
|
|
157
|
+
* second: 'seconds'
|
|
158
|
+
* }>}
|
|
159
|
+
*/
|
|
160
|
+
static get SEGMENT_UNIT_HASH () {
|
|
161
|
+
return {
|
|
162
|
+
hour: 'hours',
|
|
163
|
+
minute: 'minutes',
|
|
164
|
+
second: 'seconds',
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get the constructor of this class.
|
|
170
|
+
*
|
|
171
|
+
* @override
|
|
172
|
+
* @returns {typeof FuroTimeFieldContext}
|
|
173
|
+
*/
|
|
174
|
+
get Ctor () {
|
|
175
|
+
return /** @type {typeof FuroTimeFieldContext} */ (this.constructor)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get root element ref.
|
|
180
|
+
*
|
|
181
|
+
* @returns {import('vue').Ref<HTMLElement | null>}
|
|
182
|
+
*/
|
|
183
|
+
get rootElementRef () {
|
|
184
|
+
return this.refHash.rootElementRef
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get internal Time value ref.
|
|
189
|
+
*
|
|
190
|
+
* @returns {import('vue').Ref<import('@internationalized/date').Time | null>}
|
|
191
|
+
*/
|
|
192
|
+
get internalValueRef () {
|
|
193
|
+
return this.refHash.internalValueRef
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Parcel passed from parent via props.
|
|
198
|
+
*
|
|
199
|
+
* @override
|
|
200
|
+
* @returns {Props['parcel']}
|
|
201
|
+
*/
|
|
202
|
+
get parcel () {
|
|
203
|
+
return this.props.parcel
|
|
204
|
+
?? null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Whether the time field is in an externally-flagged invalid state.
|
|
209
|
+
*
|
|
210
|
+
* @returns {boolean}
|
|
211
|
+
*/
|
|
212
|
+
get isInvalid () {
|
|
213
|
+
return this.parcel?.invalid
|
|
214
|
+
?? false
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Whether the time field is disabled.
|
|
219
|
+
*
|
|
220
|
+
* @returns {boolean}
|
|
221
|
+
*/
|
|
222
|
+
isDisabled () {
|
|
223
|
+
return Boolean(this.parcel?.disabled)
|
|
224
|
+
|| this.hasBooleanAttribute({ name: 'disabled' })
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Whether the time field is read-only.
|
|
229
|
+
*
|
|
230
|
+
* @returns {boolean}
|
|
231
|
+
*/
|
|
232
|
+
isReadonly () {
|
|
233
|
+
return Boolean(this.parcel?.readonly)
|
|
234
|
+
|| this.hasBooleanAttribute({ name: 'readonly' })
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Placeholder text.
|
|
239
|
+
*
|
|
240
|
+
* @returns {string}
|
|
241
|
+
*/
|
|
242
|
+
get placeholder () {
|
|
243
|
+
return this.parcel?.placeholder
|
|
244
|
+
?? ''
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Time format (12 or 24). `null` when unset (locale default applies).
|
|
249
|
+
*
|
|
250
|
+
* @returns {number | null}
|
|
251
|
+
*/
|
|
252
|
+
get timeFormat () {
|
|
253
|
+
return this.parcel?.timeFormat
|
|
254
|
+
?? null
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Segment granularity (`hour` | `minute` | `second`). `null` when unset (Reka defaults to `minute`).
|
|
259
|
+
*
|
|
260
|
+
* @returns {string | null}
|
|
261
|
+
*/
|
|
262
|
+
get granularity () {
|
|
263
|
+
return this.parcel?.granularity
|
|
264
|
+
?? null
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* IANA timezone identifier for `Date` object normalization (e.g. `'Asia/Tokyo'`).
|
|
269
|
+
* When `null`, normalization falls back to local time parts (timezone-naive).
|
|
270
|
+
* Furo-only — never forwarded to Reka.
|
|
271
|
+
*
|
|
272
|
+
* @returns {string | null}
|
|
273
|
+
*/
|
|
274
|
+
get timezone () {
|
|
275
|
+
return this.parcel?.timezone
|
|
276
|
+
?? null
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Accessible name of the decrement button.
|
|
281
|
+
*
|
|
282
|
+
* @returns {string}
|
|
283
|
+
*/
|
|
284
|
+
get decrementLabel () {
|
|
285
|
+
return this.parcel?.decrementLabel
|
|
286
|
+
?? DEFAULT_DECREMENT_LABEL
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Accessible name of the increment button.
|
|
291
|
+
*
|
|
292
|
+
* @returns {string}
|
|
293
|
+
*/
|
|
294
|
+
get incrementLabel () {
|
|
295
|
+
return this.parcel?.incrementLabel
|
|
296
|
+
?? DEFAULT_INCREMENT_LABEL
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Whether the increment button can step the value up.
|
|
301
|
+
* `false` when disabled/readonly, or when the next step would exceed `maxValue`.
|
|
302
|
+
* When no value has been entered yet, returns `true` — the first press seeds a
|
|
303
|
+
* starting value (see `extractIncrementSeed()`).
|
|
304
|
+
*
|
|
305
|
+
* @returns {boolean}
|
|
306
|
+
*/
|
|
307
|
+
canIncrement () {
|
|
308
|
+
if (
|
|
309
|
+
this.isDisabled()
|
|
310
|
+
|| this.isReadonly()
|
|
311
|
+
) {
|
|
312
|
+
return false
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const current = this.internalValueRef.value
|
|
316
|
+
|
|
317
|
+
if (current === null) {
|
|
318
|
+
return true
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const maxValue = this.normalizeMaxValue()
|
|
322
|
+
|
|
323
|
+
if (maxValue === null) {
|
|
324
|
+
return true
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return current.compare(maxValue) < 0
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Whether the decrement button can step the value down.
|
|
332
|
+
* `false` when disabled/readonly, or when the previous step would fall below `minValue`.
|
|
333
|
+
* When no value has been entered yet, returns `true` — the first press seeds a
|
|
334
|
+
* starting value (see `extractDecrementSeed()`).
|
|
335
|
+
*
|
|
336
|
+
* @returns {boolean}
|
|
337
|
+
*/
|
|
338
|
+
canDecrement () {
|
|
339
|
+
if (
|
|
340
|
+
this.isDisabled()
|
|
341
|
+
|| this.isReadonly()
|
|
342
|
+
) {
|
|
343
|
+
return false
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const current = this.internalValueRef.value
|
|
347
|
+
|
|
348
|
+
if (current === null) {
|
|
349
|
+
return true
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const minValue = this.normalizeMinValue()
|
|
353
|
+
|
|
354
|
+
if (minValue === null) {
|
|
355
|
+
return true
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return current.compare(minValue) > 0
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Setup component — sync external value into internal Time ref.
|
|
363
|
+
*
|
|
364
|
+
* @template {X extends FuroTimeFieldContext ? X : never} T, X
|
|
365
|
+
* @override
|
|
366
|
+
* @returns {T} - For method chaining.
|
|
367
|
+
* @this {T}
|
|
368
|
+
*/
|
|
369
|
+
setupComponent () {
|
|
370
|
+
this.watch(
|
|
371
|
+
[
|
|
372
|
+
() => this.parcel?.value,
|
|
373
|
+
() => this.attrs?.value ?? null,
|
|
374
|
+
],
|
|
375
|
+
([parcelValue, attrsValue]) => {
|
|
376
|
+
const raw = /** @type {string | null} */ (parcelValue ?? attrsValue ?? null)
|
|
377
|
+
|
|
378
|
+
this.internalValueRef.value = this.normalizeToTime({ raw })
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
immediate: true,
|
|
382
|
+
}
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
return this
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Normalize an external value to `Time | null`.
|
|
390
|
+
* Accepts `HH:MM` / `HH:MM:SS` strings, `Date` objects, `Time` instances, or `null`.
|
|
391
|
+
*
|
|
392
|
+
* @param {{
|
|
393
|
+
* raw: string | Date | import('reka-ui').TimeValue | null
|
|
394
|
+
* }} params - Parameters of this method.
|
|
395
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
396
|
+
*/
|
|
397
|
+
normalizeToTime ({
|
|
398
|
+
raw,
|
|
399
|
+
}) {
|
|
400
|
+
if (!raw) {
|
|
401
|
+
return null
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (typeof raw === 'string') {
|
|
405
|
+
return this.normalizeStringToTime({ raw })
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (raw instanceof Date) {
|
|
409
|
+
return this.normalizeDateToTime({ raw })
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Already a Time-like object
|
|
413
|
+
return /** @type {import('@internationalized/date').Time} */ (raw)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Parse an `HH:MM` or `HH:MM:SS` string into a `Time`.
|
|
418
|
+
*
|
|
419
|
+
* @param {{
|
|
420
|
+
* raw: string
|
|
421
|
+
* }} params - Parameters of this method.
|
|
422
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
423
|
+
*/
|
|
424
|
+
normalizeStringToTime ({
|
|
425
|
+
raw,
|
|
426
|
+
}) {
|
|
427
|
+
if (!raw) {
|
|
428
|
+
return null
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
try {
|
|
432
|
+
return parseTime(raw)
|
|
433
|
+
} catch {
|
|
434
|
+
return null
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Convert a `Date` object to `Time`.
|
|
440
|
+
* When `parcel.timezone` is set, time parts are extracted in that IANA timezone.
|
|
441
|
+
* Otherwise falls back to local wall-clock parts (timezone-naive).
|
|
442
|
+
*
|
|
443
|
+
* @param {{
|
|
444
|
+
* raw: Date
|
|
445
|
+
* }} params - Parameters of this method.
|
|
446
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
447
|
+
*/
|
|
448
|
+
normalizeDateToTime ({
|
|
449
|
+
raw,
|
|
450
|
+
}) {
|
|
451
|
+
if (
|
|
452
|
+
!raw
|
|
453
|
+
|| isNaN(raw.getTime())
|
|
454
|
+
) {
|
|
455
|
+
return null
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const { timezone } = this
|
|
459
|
+
|
|
460
|
+
if (timezone) {
|
|
461
|
+
return this.normalizeDateToTimeInTimezone({ raw, timezone })
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return new Time(
|
|
465
|
+
raw.getHours(),
|
|
466
|
+
raw.getMinutes(),
|
|
467
|
+
raw.getSeconds()
|
|
468
|
+
)
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Convert a `Date` object to `Time` using a specific IANA timezone.
|
|
473
|
+
* Returns `null` when the timezone identifier is invalid.
|
|
474
|
+
*
|
|
475
|
+
* @param {{
|
|
476
|
+
* raw: Date
|
|
477
|
+
* timezone: string
|
|
478
|
+
* }} params - Parameters of this method.
|
|
479
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
480
|
+
*/
|
|
481
|
+
normalizeDateToTimeInTimezone ({
|
|
482
|
+
raw,
|
|
483
|
+
timezone,
|
|
484
|
+
}) {
|
|
485
|
+
try {
|
|
486
|
+
const { hour, minute, second } = this.Ctor.extractTimePartsInTimezone({ raw, timezone })
|
|
487
|
+
|
|
488
|
+
if (
|
|
489
|
+
hour === null
|
|
490
|
+
|| minute === null
|
|
491
|
+
|| second === null
|
|
492
|
+
) {
|
|
493
|
+
return null
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const isoString = [
|
|
497
|
+
hour,
|
|
498
|
+
minute,
|
|
499
|
+
second,
|
|
500
|
+
].join(':')
|
|
501
|
+
|
|
502
|
+
return this.normalizeStringToTime({ raw: isoString })
|
|
503
|
+
} catch {
|
|
504
|
+
return null
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Extract hour / minute / second string parts from a `Date` object in a specific IANA
|
|
510
|
+
* timezone via `Intl.DateTimeFormat`. Each part is zero-padded to 2 digits so the
|
|
511
|
+
* assembled `HH:MM:SS` string parses cleanly (generalizes the year-pad lesson).
|
|
512
|
+
*
|
|
513
|
+
* @param {{
|
|
514
|
+
* raw: Date
|
|
515
|
+
* timezone: string
|
|
516
|
+
* }} params - Parameters of this method.
|
|
517
|
+
* @returns {{ hour: string | null, minute: string | null, second: string | null }}
|
|
518
|
+
*/
|
|
519
|
+
static extractTimePartsInTimezone ({
|
|
520
|
+
raw,
|
|
521
|
+
timezone,
|
|
522
|
+
}) {
|
|
523
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
524
|
+
timeZone: timezone,
|
|
525
|
+
hour: '2-digit',
|
|
526
|
+
minute: '2-digit',
|
|
527
|
+
second: '2-digit',
|
|
528
|
+
hourCycle: 'h23',
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
const parts = formatter.formatToParts(raw)
|
|
532
|
+
|
|
533
|
+
const hour = this.extractPaddedTimePart({ parts, type: 'hour' })
|
|
534
|
+
const minute = this.extractPaddedTimePart({ parts, type: 'minute' })
|
|
535
|
+
const second = this.extractPaddedTimePart({ parts, type: 'second' })
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
hour,
|
|
539
|
+
minute,
|
|
540
|
+
second,
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Extract the DOM element that currently has focus, or `null` when the document is
|
|
546
|
+
* unavailable (e.g. SSR). Isolated as a static hook so tests can stub the active element.
|
|
547
|
+
*
|
|
548
|
+
* @returns {Element | null}
|
|
549
|
+
*/
|
|
550
|
+
static extractActiveElement () {
|
|
551
|
+
if (!globalThis.document) {
|
|
552
|
+
return null
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return document.activeElement
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Find a single formatted time part by type and zero-pad it to 2 digits.
|
|
560
|
+
*
|
|
561
|
+
* @param {{
|
|
562
|
+
* parts: Array<Intl.DateTimeFormatPart>
|
|
563
|
+
* type: string
|
|
564
|
+
* }} params - Parameters of this method.
|
|
565
|
+
* @returns {string | null}
|
|
566
|
+
*/
|
|
567
|
+
static extractPaddedTimePart ({
|
|
568
|
+
parts,
|
|
569
|
+
type,
|
|
570
|
+
}) {
|
|
571
|
+
return parts.find(part => part.type === type)
|
|
572
|
+
?.value
|
|
573
|
+
?.padStart(2, '0')
|
|
574
|
+
?? null
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Normalize a `Time` to an `HH:MM:SS` string or `null`.
|
|
579
|
+
* Always serializes via `time.toString()` (zero-pads), never manual segment assembly.
|
|
580
|
+
*
|
|
581
|
+
* @param {{
|
|
582
|
+
* time: import('@internationalized/date').Time | null
|
|
583
|
+
* }} params - Parameters of this method.
|
|
584
|
+
* @returns {string | null}
|
|
585
|
+
*/
|
|
586
|
+
normalizeToIsoString ({
|
|
587
|
+
time,
|
|
588
|
+
}) {
|
|
589
|
+
return time?.toString() ?? null
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Normalize the parcel `minValue` to a `Time`.
|
|
594
|
+
*
|
|
595
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
596
|
+
*/
|
|
597
|
+
normalizeMinValue () {
|
|
598
|
+
const raw = this.parcel?.minValue ?? null
|
|
599
|
+
|
|
600
|
+
return this.normalizeToTime({ raw })
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Normalize the parcel `maxValue` to a `Time`.
|
|
605
|
+
*
|
|
606
|
+
* @returns {import('@internationalized/date').Time | null}
|
|
607
|
+
*/
|
|
608
|
+
normalizeMaxValue () {
|
|
609
|
+
const raw = this.parcel?.maxValue ?? null
|
|
610
|
+
|
|
611
|
+
return this.normalizeToTime({ raw })
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Normalize the parcel `step` amount applied to the smallest visible segment (per
|
|
616
|
+
* `granularity`) for the increment/decrement buttons. A non-positive or non-numeric
|
|
617
|
+
* step falls back to `1`.
|
|
618
|
+
*
|
|
619
|
+
* @returns {number}
|
|
620
|
+
*/
|
|
621
|
+
normalizeStep () {
|
|
622
|
+
const rawStep = this.parcel?.step
|
|
623
|
+
?? null
|
|
624
|
+
|
|
625
|
+
if (
|
|
626
|
+
typeof rawStep !== 'number'
|
|
627
|
+
|| rawStep <= 0
|
|
628
|
+
) {
|
|
629
|
+
return 1
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
return rawStep
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Extract attributes for Reka `TimeFieldRoot`.
|
|
637
|
+
* Strips all Furo-only keys and re-applies normalized Reka props.
|
|
638
|
+
*
|
|
639
|
+
* @returns {Record<string, unknown>}
|
|
640
|
+
*/
|
|
641
|
+
extractRootAttributes () {
|
|
642
|
+
const strippedParcel = this.stripFuroParcelKeys()
|
|
643
|
+
|
|
644
|
+
const optionalAttributes = this.buildOptionalRootAttributes()
|
|
645
|
+
|
|
646
|
+
const {
|
|
647
|
+
value,
|
|
648
|
+
...passthroughAttrs
|
|
649
|
+
} = this.attrs ?? {}
|
|
650
|
+
|
|
651
|
+
return {
|
|
652
|
+
...passthroughAttrs,
|
|
653
|
+
...strippedParcel,
|
|
654
|
+
modelValue: this.internalValueRef.value,
|
|
655
|
+
disabled: this.isDisabled(),
|
|
656
|
+
readonly: this.isReadonly(),
|
|
657
|
+
step: this.normalizeStep(),
|
|
658
|
+
...optionalAttributes,
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Build the optional Reka root attributes that are only included when present.
|
|
664
|
+
*
|
|
665
|
+
* @returns {Record<string, unknown>}
|
|
666
|
+
*/
|
|
667
|
+
buildOptionalRootAttributes () {
|
|
668
|
+
const entries = [
|
|
669
|
+
['stepSnapping', this.parcel?.stepSnapping ?? null],
|
|
670
|
+
['hourCycle', this.timeFormat],
|
|
671
|
+
['granularity', this.granularity],
|
|
672
|
+
['minValue', this.normalizeMinValue()],
|
|
673
|
+
['maxValue', this.normalizeMaxValue()],
|
|
674
|
+
]
|
|
675
|
+
.filter(([, attributeValue]) => attributeValue !== null)
|
|
676
|
+
|
|
677
|
+
return Object.fromEntries(entries)
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Strip Furo-only parcel keys from the parcel object.
|
|
682
|
+
*
|
|
683
|
+
* @returns {Record<string, unknown>}
|
|
684
|
+
*/
|
|
685
|
+
stripFuroParcelKeys () {
|
|
686
|
+
const { parcel } = this
|
|
687
|
+
|
|
688
|
+
if (!parcel) {
|
|
689
|
+
return {}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const entries = Object.entries(parcel)
|
|
693
|
+
.filter(([key]) => !FURO_TIME_FIELD_PARCEL_KEYS.has(key))
|
|
694
|
+
|
|
695
|
+
return Object.fromEntries(entries)
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Build a custom event for the emit payload.
|
|
700
|
+
*
|
|
701
|
+
* @param {{
|
|
702
|
+
* name: string
|
|
703
|
+
* value: string | null
|
|
704
|
+
* }} params - Parameters of this method.
|
|
705
|
+
* @returns {CustomEvent<{
|
|
706
|
+
* target: HTMLElement | null
|
|
707
|
+
* value: string | null
|
|
708
|
+
* }>}
|
|
709
|
+
*/
|
|
710
|
+
buildCustomEvent ({
|
|
711
|
+
name,
|
|
712
|
+
value,
|
|
713
|
+
}) {
|
|
714
|
+
return new CustomEvent(
|
|
715
|
+
name,
|
|
716
|
+
{
|
|
717
|
+
detail: {
|
|
718
|
+
target: this.rootElementRef.value,
|
|
719
|
+
value,
|
|
720
|
+
},
|
|
721
|
+
}
|
|
722
|
+
)
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Respond to `update:modelValue` from Reka `TimeFieldRoot`.
|
|
727
|
+
* Emits `change-value`, `update:value`, and `commit-value`.
|
|
728
|
+
*
|
|
729
|
+
* @param {{
|
|
730
|
+
* time?: import('reka-ui').TimeValue | null
|
|
731
|
+
* }} params - Parameters of this method.
|
|
732
|
+
*/
|
|
733
|
+
onChangeValue ({
|
|
734
|
+
time = null,
|
|
735
|
+
}) {
|
|
736
|
+
const normalized = this.normalizeToTime({
|
|
737
|
+
raw: time,
|
|
738
|
+
})
|
|
739
|
+
|
|
740
|
+
this.internalValueRef.value = normalized
|
|
741
|
+
|
|
742
|
+
const value = this.normalizeToIsoString({ time: normalized })
|
|
743
|
+
|
|
744
|
+
const customEvent = this.buildCustomEvent({
|
|
745
|
+
name: this.EMIT_EVENT_NAME.CHANGE_VALUE,
|
|
746
|
+
value,
|
|
747
|
+
})
|
|
748
|
+
|
|
749
|
+
const payload = this.Ctor.EmitPayloadCtor.create({
|
|
750
|
+
rawEvent: customEvent,
|
|
751
|
+
})
|
|
752
|
+
|
|
753
|
+
this.emit(
|
|
754
|
+
this.EMIT_EVENT_NAME.CHANGE_VALUE,
|
|
755
|
+
payload
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
this.emit(
|
|
759
|
+
this.EMIT_EVENT_NAME.UPDATE_VALUE,
|
|
760
|
+
value
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
this.emit(
|
|
764
|
+
this.EMIT_EVENT_NAME.COMMIT_VALUE,
|
|
765
|
+
payload
|
|
766
|
+
)
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* Step the value up by `step` of the smallest visible segment, clamped to
|
|
771
|
+
* `[minValue, maxValue]`, then route through the same emit path as segment edits.
|
|
772
|
+
* When no value has been entered yet, the first press seeds the increment start
|
|
773
|
+
* value (`minValue ?? 00:00`) instead of stepping.
|
|
774
|
+
*/
|
|
775
|
+
onIncrementValue () {
|
|
776
|
+
if (!this.canIncrement()) {
|
|
777
|
+
return
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const current = this.internalValueRef.value
|
|
781
|
+
|
|
782
|
+
if (current === null) {
|
|
783
|
+
this.onChangeValue({ time: this.extractIncrementSeed() })
|
|
784
|
+
|
|
785
|
+
return
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const next = current.add(this.extractStepDuration())
|
|
789
|
+
|
|
790
|
+
if (next.compare(current) < 0) {
|
|
791
|
+
this.onIncrementWrap({ next })
|
|
792
|
+
|
|
793
|
+
return
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
const clamped = this.clampTime({ time: next })
|
|
797
|
+
|
|
798
|
+
this.onChangeValue({ time: clamped })
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Handle a forward step that wrapped past midnight (`23:58 + 5 → 00:03`).
|
|
803
|
+
* Pins to `maxValue` when set; otherwise loops the wrapped value around (cyclic,
|
|
804
|
+
* since the field is unbounded above).
|
|
805
|
+
*
|
|
806
|
+
* @param {{
|
|
807
|
+
* next: import('@internationalized/date').Time
|
|
808
|
+
* }} params - Parameters of this method.
|
|
809
|
+
*/
|
|
810
|
+
onIncrementWrap ({
|
|
811
|
+
next,
|
|
812
|
+
}) {
|
|
813
|
+
const maxValue = this.normalizeMaxValue()
|
|
814
|
+
|
|
815
|
+
if (maxValue === null) {
|
|
816
|
+
this.onChangeValue({ time: next })
|
|
817
|
+
|
|
818
|
+
return
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
this.onChangeValue({ time: maxValue })
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Step the value down by `step` of the smallest visible segment, clamped to
|
|
826
|
+
* `[minValue, maxValue]`, then route through the same emit path as segment edits.
|
|
827
|
+
* When no value has been entered yet, the first press seeds the decrement start
|
|
828
|
+
* value (`maxValue ?? 00:00`) instead of stepping.
|
|
829
|
+
*/
|
|
830
|
+
onDecrementValue () {
|
|
831
|
+
if (!this.canDecrement()) {
|
|
832
|
+
return
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
const current = this.internalValueRef.value
|
|
836
|
+
|
|
837
|
+
if (current === null) {
|
|
838
|
+
this.onChangeValue({ time: this.extractDecrementSeed() })
|
|
839
|
+
|
|
840
|
+
return
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const next = current.subtract(this.extractStepDuration())
|
|
844
|
+
|
|
845
|
+
if (next.compare(current) > 0) {
|
|
846
|
+
this.onDecrementWrap({ next })
|
|
847
|
+
|
|
848
|
+
return
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
const clamped = this.clampTime({ time: next })
|
|
852
|
+
|
|
853
|
+
this.onChangeValue({ time: clamped })
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Handle a backward step that wrapped past midnight (`00:02 - 5 → 23:57`).
|
|
858
|
+
* Pins to `minValue` when set; otherwise loops the wrapped value around (cyclic,
|
|
859
|
+
* since the field is unbounded below).
|
|
860
|
+
*
|
|
861
|
+
* @param {{
|
|
862
|
+
* next: import('@internationalized/date').Time
|
|
863
|
+
* }} params - Parameters of this method.
|
|
864
|
+
*/
|
|
865
|
+
onDecrementWrap ({
|
|
866
|
+
next,
|
|
867
|
+
}) {
|
|
868
|
+
const minValue = this.normalizeMinValue()
|
|
869
|
+
|
|
870
|
+
if (minValue === null) {
|
|
871
|
+
this.onChangeValue({ time: next })
|
|
872
|
+
|
|
873
|
+
return
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
this.onChangeValue({ time: minValue })
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Build the starting value for the first increment press on an empty field.
|
|
881
|
+
* Begins at `minValue` when set, otherwise `00:00`, clamped into `[minValue, maxValue]`.
|
|
882
|
+
*
|
|
883
|
+
* @returns {import('@internationalized/date').Time}
|
|
884
|
+
*/
|
|
885
|
+
extractIncrementSeed () {
|
|
886
|
+
const seed = this.normalizeMinValue()
|
|
887
|
+
?? this.Ctor.buildZeroTime()
|
|
888
|
+
|
|
889
|
+
return this.clampTime({ time: seed })
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Build the starting value for the first decrement press on an empty field.
|
|
894
|
+
* Begins at `maxValue` when set, otherwise the end of the day (per `granularity`,
|
|
895
|
+
* e.g. `23:59`) so subsequent decrements keep stepping down instead of landing on
|
|
896
|
+
* `00:00` where they cannot cross midnight. Clamped into `[minValue, maxValue]`.
|
|
897
|
+
*
|
|
898
|
+
* @returns {import('@internationalized/date').Time}
|
|
899
|
+
*/
|
|
900
|
+
extractDecrementSeed () {
|
|
901
|
+
const seed = this.normalizeMaxValue()
|
|
902
|
+
?? this.buildEndOfDayTime()
|
|
903
|
+
|
|
904
|
+
return this.clampTime({ time: seed })
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Build the end-of-day `Time` for the current `granularity`: `23:00` for hours,
|
|
909
|
+
* `23:59:59` for seconds, otherwise `23:59`. Used as the unbounded decrement seed.
|
|
910
|
+
*
|
|
911
|
+
* @returns {import('@internationalized/date').Time}
|
|
912
|
+
*/
|
|
913
|
+
buildEndOfDayTime () {
|
|
914
|
+
const partsHash = {
|
|
915
|
+
hours: [23, 0, 0],
|
|
916
|
+
minutes: [23, 59, 0],
|
|
917
|
+
seconds: [23, 59, 59],
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
const [hour, minute, second] = partsHash[this.extractGranularityUnit()]
|
|
921
|
+
|
|
922
|
+
return new Time(hour, minute, second)
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Build the duration object passed to `Time.add` / `Time.subtract` for one stepper press.
|
|
927
|
+
* The unit prioritizes the currently focused segment (`hour` / `minute` / `second`); when no
|
|
928
|
+
* segment is focused it falls back to `granularity` (the smallest visible segment), defaulting
|
|
929
|
+
* to minutes. The amount is always `step`.
|
|
930
|
+
*
|
|
931
|
+
* @returns {{
|
|
932
|
+
* hours?: number
|
|
933
|
+
* minutes?: number
|
|
934
|
+
* seconds?: number
|
|
935
|
+
* }}
|
|
936
|
+
*/
|
|
937
|
+
extractStepDuration () {
|
|
938
|
+
const unit = this.extractFocusedSegmentUnit()
|
|
939
|
+
?? this.extractGranularityUnit()
|
|
940
|
+
|
|
941
|
+
return {
|
|
942
|
+
[unit]: this.normalizeStep(),
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Map the currently focused time segment to a duration unit key, or `null` when no
|
|
948
|
+
* steppable segment (`hour` / `minute` / `second`) is focused.
|
|
949
|
+
*
|
|
950
|
+
* @returns {'hours' | 'minutes' | 'seconds' | null}
|
|
951
|
+
*/
|
|
952
|
+
extractFocusedSegmentUnit () {
|
|
953
|
+
const part = this.extractFocusedSegmentPart()
|
|
954
|
+
|
|
955
|
+
return this.Ctor.SEGMENT_UNIT_HASH[/** @type {keyof typeof FuroTimeFieldContext.SEGMENT_UNIT_HASH} */ (part)]
|
|
956
|
+
?? null
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Map the `granularity` (smallest visible segment) to a duration unit key.
|
|
961
|
+
* Defaults to minutes when granularity is unset or unrecognized.
|
|
962
|
+
*
|
|
963
|
+
* @returns {'hours' | 'minutes' | 'seconds'}
|
|
964
|
+
*/
|
|
965
|
+
extractGranularityUnit () {
|
|
966
|
+
return this.Ctor.SEGMENT_UNIT_HASH[/** @type {keyof typeof FuroTimeFieldContext.SEGMENT_UNIT_HASH} */ (this.granularity)]
|
|
967
|
+
?? 'minutes'
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Extract the currently focused time segment part (`hour` | `minute` | `second` | `dayPeriod`)
|
|
972
|
+
* from the active element, or `null` when no time segment is focused. Reads the
|
|
973
|
+
* `data-reka-time-field-segment` attribute the underlying primitive stamps on each segment.
|
|
974
|
+
*
|
|
975
|
+
* @returns {string | null}
|
|
976
|
+
*/
|
|
977
|
+
extractFocusedSegmentPart () {
|
|
978
|
+
const activeElement = this.Ctor.extractActiveElement()
|
|
979
|
+
|
|
980
|
+
return activeElement?.getAttribute('data-reka-time-field-segment')
|
|
981
|
+
?? null
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Clamp a `Time` into the `[minValue, maxValue]` window.
|
|
986
|
+
* Returns the bound when out of range, otherwise the original time.
|
|
987
|
+
*
|
|
988
|
+
* @param {{
|
|
989
|
+
* time: import('@internationalized/date').Time
|
|
990
|
+
* }} params - Parameters of this method.
|
|
991
|
+
* @returns {import('@internationalized/date').Time}
|
|
992
|
+
*/
|
|
993
|
+
clampTime ({
|
|
994
|
+
time,
|
|
995
|
+
}) {
|
|
996
|
+
const minValue = this.normalizeMinValue()
|
|
997
|
+
const maxValue = this.normalizeMaxValue()
|
|
998
|
+
|
|
999
|
+
if (
|
|
1000
|
+
minValue !== null
|
|
1001
|
+
&& time.compare(minValue) < 0
|
|
1002
|
+
) {
|
|
1003
|
+
return minValue
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (
|
|
1007
|
+
maxValue !== null
|
|
1008
|
+
&& time.compare(maxValue) > 0
|
|
1009
|
+
) {
|
|
1010
|
+
return maxValue
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
return time
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Whether the segment part is a literal separator (e.g. `:` between segments).
|
|
1018
|
+
*
|
|
1019
|
+
* @param {{ part: import('reka-ui').SegmentPart }} params - Parameters of this method.
|
|
1020
|
+
* @returns {boolean}
|
|
1021
|
+
*/
|
|
1022
|
+
isLiteralPart ({
|
|
1023
|
+
part,
|
|
1024
|
+
}) {
|
|
1025
|
+
return part === 'literal'
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* Format a time segment value for display. Hour, minute, and second segments are zero-padded
|
|
1030
|
+
* to two digits (e.g. `9` → `09`) so the field width stays constant as the value changes;
|
|
1031
|
+
* the day period (AM/PM) and literals pass through unchanged. The underlying primitive
|
|
1032
|
+
* renders filled segments with single-digit (`numeric`) formatting, so this — together with
|
|
1033
|
+
* `tabular-nums` — keeps the trigger from resizing and shifting the popover.
|
|
1034
|
+
*
|
|
1035
|
+
* @param {{
|
|
1036
|
+
* part: import('reka-ui').SegmentPart
|
|
1037
|
+
* value: string
|
|
1038
|
+
* }} params - Parameters of this method.
|
|
1039
|
+
* @returns {string}
|
|
1040
|
+
*/
|
|
1041
|
+
formatSegmentValue ({
|
|
1042
|
+
part,
|
|
1043
|
+
value,
|
|
1044
|
+
}) {
|
|
1045
|
+
if (!this.isTwoDigitSegmentPart({ part })) {
|
|
1046
|
+
return value
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
if (!/^\d{1,2}$/u.test(value)) {
|
|
1050
|
+
return value
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
return value.padStart(2, '0')
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Whether a segment part should display zero-padded to two digits (hour, minute, second).
|
|
1058
|
+
*
|
|
1059
|
+
* @param {{ part: import('reka-ui').SegmentPart }} params - Parameters of this method.
|
|
1060
|
+
* @returns {boolean}
|
|
1061
|
+
*/
|
|
1062
|
+
isTwoDigitSegmentPart ({
|
|
1063
|
+
part,
|
|
1064
|
+
}) {
|
|
1065
|
+
return [
|
|
1066
|
+
'hour',
|
|
1067
|
+
'minute',
|
|
1068
|
+
'second',
|
|
1069
|
+
]
|
|
1070
|
+
.includes(part)
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* @typedef {import('../../../contexts/BaseFuroContext.js').BaseFuroContextParams & {
|
|
1076
|
+
* props: Props
|
|
1077
|
+
* componentContext: ComponentContext
|
|
1078
|
+
* refHash: {
|
|
1079
|
+
* rootElementRef: import('vue').Ref<HTMLElement | null>
|
|
1080
|
+
* internalValueRef: import('vue').Ref<import('@internationalized/date').Time | null>
|
|
1081
|
+
* }
|
|
1082
|
+
* }} FuroTimeFieldContextParams
|
|
1083
|
+
*/
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* @typedef {Omit<FuroTimeFieldContextParams, 'refHash'> & {
|
|
1087
|
+
* refHash?: {
|
|
1088
|
+
* rootElementRef: import('vue').Ref<HTMLElement | null>
|
|
1089
|
+
* internalValueRef: import('vue').Ref<import('@internationalized/date').Time | null>
|
|
1090
|
+
* }
|
|
1091
|
+
* }} FuroTimeFieldContextFactoryParams
|
|
1092
|
+
*/
|
|
1093
|
+
|
|
1094
|
+
/**
|
|
1095
|
+
* @typedef {keyof typeof FuroTimeFieldContext.EMIT_EVENT_NAME} EmitEventName
|
|
1096
|
+
*/
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* @typedef {import('vue').HTMLAttributes & {
|
|
1100
|
+
* parcel?: TimeFieldParcel | null
|
|
1101
|
+
* }} Props
|
|
1102
|
+
*/
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* @typedef {Record<string, unknown> & {
|
|
1106
|
+
* value?: string | null
|
|
1107
|
+
* invalid?: boolean
|
|
1108
|
+
* placeholder?: string | null
|
|
1109
|
+
* disabled?: boolean
|
|
1110
|
+
* readonly?: boolean
|
|
1111
|
+
* minValue?: string | null
|
|
1112
|
+
* maxValue?: string | null
|
|
1113
|
+
* timeFormat?: number | null
|
|
1114
|
+
* granularity?: 'hour' | 'minute' | 'second' | null
|
|
1115
|
+
* step?: number | null
|
|
1116
|
+
* stepSnapping?: boolean | null
|
|
1117
|
+
* timezone?: string | null
|
|
1118
|
+
* decrementLabel?: string
|
|
1119
|
+
* incrementLabel?: string
|
|
1120
|
+
* }} TimeFieldParcel
|
|
1121
|
+
*/
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* @typedef {import('vue').SetupContext<FuroTimeFieldEmitHash>} ComponentContext
|
|
1125
|
+
*/
|
|
1126
|
+
|
|
1127
|
+
/**
|
|
1128
|
+
* @typedef {typeof FuroTimeFieldContext.EMIT_EVENT_HASH} FuroTimeFieldEmitHash
|
|
1129
|
+
*/
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* @typedef {(
|
|
1133
|
+
* props: Props,
|
|
1134
|
+
* componentContext: ComponentContext
|
|
1135
|
+
* ) => {
|
|
1136
|
+
* context: FuroTimeFieldContext
|
|
1137
|
+
* }} FuroTimeFieldSetup
|
|
1138
|
+
*/
|